1 karl 1.24 //%2006////////////////////////////////////////////////////////////////////////
|
2 mike 1.2 //
|
3 karl 1.16 // Copyright (c) 2000, 2001, 2002 BMC Software; Hewlett-Packard Development
4 // Company, L.P.; IBM Corp.; The Open Group; Tivoli Systems.
5 // Copyright (c) 2003 BMC Software; Hewlett-Packard Development Company, L.P.;
|
6 karl 1.13 // IBM Corp.; EMC Corporation, The Open Group.
|
7 karl 1.16 // Copyright (c) 2004 BMC Software; Hewlett-Packard Development Company, L.P.;
8 // IBM Corp.; EMC Corporation; VERITAS Software Corporation; The Open Group.
|
9 karl 1.18 // Copyright (c) 2005 Hewlett-Packard Development Company, L.P.; IBM Corp.;
10 // EMC Corporation; VERITAS Software Corporation; The Open Group.
|
11 karl 1.24 // Copyright (c) 2006 Hewlett-Packard Development Company, L.P.; IBM Corp.;
12 // EMC Corporation; Symantec Corporation; The Open Group.
|
13 mike 1.2 //
14 // Permission is hereby granted, free of charge, to any person obtaining a copy
15 // of this software and associated documentation files (the "Software"), to
16 // deal in the Software without restriction, including without limitation the
17 // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
18 // sell copies of the Software, and to permit persons to whom the Software is
19 // furnished to do so, subject to the following conditions:
|
20 karl 1.24 //
|
21 mike 1.2 // THE ABOVE COPYRIGHT NOTICE AND THIS PERMISSION NOTICE SHALL BE INCLUDED IN
22 // ALL COPIES OR SUBSTANTIAL PORTIONS OF THE SOFTWARE. THE SOFTWARE IS PROVIDED
23 // "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
24 // LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
25 // PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
26 // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
27 // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
28 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29 //
30 //==============================================================================
31 //
32 //%/////////////////////////////////////////////////////////////////////////////
33
34 #ifndef Pegasus_Tracer_h
35 #define Pegasus_Tracer_h
36
|
37 marek 1.31 #include <cstdarg>
|
38 mike 1.2 #include <Pegasus/Common/String.h>
39 #include <Pegasus/Common/System.h>
40 #include <Pegasus/Common/Logger.h>
|
41 kumpf 1.12 #include <Pegasus/Common/InternalException.h>
|
42 mike 1.2 #include <Pegasus/Common/TraceComponents.h>
|
43 r.kieninger 1.35 #include <Pegasus/Common/TraceHandler.h>
|
44 kumpf 1.11 #include <Pegasus/Common/Linkage.h>
|
45 sushma.fernandes 1.30 #include <Pegasus/Common/SharedPtr.h>
|
46 mike 1.2
47 PEGASUS_NAMESPACE_BEGIN
48
|
49 karl 1.25 /** Token used for tracing functions.
50 */
51 struct TracerToken
52 {
53 Uint32 component;
54 const char* method;
55 };
56
|
57 mike 1.2 /** Tracer implements tracing of messages to a defined file
58 */
59 class PEGASUS_COMMON_LINKAGE Tracer
60 {
61 public:
62
|
63 r.kieninger 1.35
64 /** Trace facilities
65 File - tracing occurs to the trace file
66 Log - tracing occurs through the Pegasus Logger class
67 Keep the TRACE_FACILITY_LIST in sync with the TRACE_FACILITY_INDEX,
68 so that the index matches the according string in the list.
69 */
70 static char const* TRACE_FACILITY_LIST[];
71
72 enum TRACE_FACILITY_INDEX
73 {
74 TRACE_FACILITY_FILE = 0,
75 TRACE_FACILITY_LOG = 1
76 };
77
78
|
79 mike 1.2 /** Levels of trace
80 Trace messages are written to the trace file only if they are at or
81 above a given trace level
|
82 marek 1.34 LEVEL1 - Severe and log messages
|
83 mike 1.2 LEVEL2 - Basic flow trace messages, low data detail
84 LEVEL3 - Inter-function logic flow, medium data detail
85 LEVEL4 - High data detail
86 */
87 static const Uint32 LEVEL1;
88 static const Uint32 LEVEL2;
89 static const Uint32 LEVEL3;
90 static const Uint32 LEVEL4;
|
91 r.kieninger 1.20
|
92 marek 1.28 /** Traces the given character string.
93 Overloaded to include the filename
94 and line number of trace origin.
|
95 kumpf 1.27 @param fileName filename of the trace originator
96 @param lineNum line number of the trace originator
97 @param traceComponent component being traced
|
98 marek 1.28 @param cstring the character string to be traced
|
99 karl 1.25 */
|
100 marek 1.28 static void traceCString(
101 const char* fileName,
102 const Uint32 lineNum,
|
103 kumpf 1.27 const Uint32 traceComponent,
|
104 marek 1.28 const char* cstring);
|
105 karl 1.25
106 /** Traces the message in the given CIMException object. The message
|
107 kumpf 1.27 written to the trace file will include the source filename and
108 line number of the CIMException originator.
109 @param traceComponent component being traced
110 @param level trace level of the trace message
|
111 kumpf 1.33 @param cimException the CIMException to be traced.
|
112 karl 1.25 */
113 static void traceCIMException(
|
114 kumpf 1.27 const Uint32 traceComponent,
115 const Uint32 level,
116 const CIMException& cimException);
|
117 karl 1.25
|
118 sushma.fernandes 1.30 /** Gets an HTTP request message.
119
120 Given an HTTP request message, this method checks if the
121 message contains a "Basic" authorization header.
122
123 If true, the username/passwd is suppressed and returned.
124 Otherwise the request message is returned without any changes.
125
126 @param requestMessage requestMessage to be checked
127
128 @return request message
129
130 */
131 static SharedArrayPtr<char> getHTTPRequestMessage(
132 const Buffer& requestMessage);
133
|
134 karl 1.25 /** Set the trace file to the given file
|
135 kumpf 1.27 @param traceFile full path of the trace file
136 @return 0 if the filepath is valid
137 1 if the traceFile is an empty string or
138 if an error occurs while opening the file
139 in append mode
|
140 karl 1.25 */
141 static Uint32 setTraceFile(const char* traceFile);
142
143 /** Set the trace level to the given level
|
144 kumpf 1.27 @param level trace level to be set
145 @return 0 if trace level is valid
146 1 if trace level is invalid
|
147 karl 1.25 */
148 static Uint32 setTraceLevel(const Uint32 level);
149
150 /** Set components to be traced
|
151 kumpf 1.27 @param traceComponents list of components to be traced,
152 components should be separated by ','
|
153 karl 1.25 */
154 static void setTraceComponents(
155 const String& traceComponents);
|
156 r.kieninger 1.20
|
157 r.kieninger 1.35 /** Set trace facility to be used
158 @param traceFacility facility to be used for tracing,
159 for example Log or File.
160 @return 0 if trace facility is valid
161 1 if trace facility is invalid
162 */
163 static Uint32 setTraceFacility(const String& traceFacility);
164
|
165 karl 1.25 /** Traces method entry.
|
166 kumpf 1.27 @param token TracerToken
167 @param fileName filename of the trace originator
168 @param lineNum line number of the trace originator
169 @param traceComponent component being traced
170 @param methodName method being traced
|
171 mike 1.2 */
|
172 karl 1.25 static void traceEnter(
|
173 kumpf 1.27 TracerToken& token,
174 const char* file,
175 size_t line,
176 Uint32 component,
177 const char* method);
|
178 r.kieninger 1.20
179 /** Traces method exit.
|
180 kumpf 1.27 @param token TracerToken containing component and method
181 @param fileName filename of the trace originator
182 @param lineNum line number of the trace originator
|
183 mike 1.2 */
|
184 karl 1.25 static void traceExit(
|
185 kumpf 1.27 TracerToken& token,
186 const char* file,
187 size_t line);
|
188 mike 1.2
189 /** Validates the File Path for the trace File
|
190 kumpf 1.27 @param filePath full path of the file
191 @return 1 if the file path is valid
192 0 if the file path is invalid
|
193 mike 1.2 */
|
194 kumpf 1.7 static Boolean isValidFileName(const char* filePath);
195
196 /** Validates the trace components
|
197 kumpf 1.27 @param traceComponents comma separated list of trace components
198 @return 1 if the components are valid
199 0 if one or more components are invalid
|
200 kumpf 1.7 */
|
201 kumpf 1.15 static Boolean isValidComponents(const String& traceComponents);
|
202 mike 1.2
203 /** Validates the trace components
|
204 kumpf 1.27 @param traceComponents comma separated list of trace components
205 @param invalidComponents comma separated list of invalid components
206 @return 1 if the components are valid
207 0 if one or more components are invalid
|
208 mike 1.2 */
|
209 kumpf 1.7 static Boolean isValidComponents(
|
210 kumpf 1.15 const String& traceComponents,
|
211 kumpf 1.7 String& invalidComponents);
|
212 mike 1.2
|
213 r.kieninger 1.35 /** Validates the trace facility string value
214 @param traceFacility The trace facility as string
215 @return 1 if the trace facility is valid
216 0 if the trace facility is invalid
217 */
218 static Boolean isValidTraceFacility( const String& traceFacility );
219
|
220 kumpf 1.15 /** Specify the name of the module being traced. If non-empty, this
221 value is used as an extension to the name of the trace file.
|
222 kumpf 1.27 @param moduleName Name of the module being traced.
|
223 kumpf 1.15 */
224 static void setModuleName(const String& moduleName);
225
|
226 karl 1.25 /**
227 */
|
228 david.dillard 1.23 static Boolean isTraceOn() { return _traceOn; }
|
229 mike 1.21
|
230 marek 1.31 // Checks if trace is enabled for the given component and trace level
231 // @param traceComponent component being traced
232 // @param level level of the trace message
233 // @return 0 if the component and level are not enabled
234 // 1 if the component and level are enabled
235 static Boolean isTraceEnabled(
236 const Uint32 traceComponent,
237 const Uint32 level);
238
|
239 mike 1.2 private:
240
|
241 r.kieninger 1.20 /** A static single indicator if tracing is turned on allowing to
242 determine the state of trace quickly without many instructions.
243 Used to wrap the public static trace interface methods to avoid
244 obsolete calls when tracing is turned off.
245 */
|
246 david.dillard 1.23 static Boolean _traceOn;
|
247 r.kieninger 1.20
|
248 marek 1.34 /** Internal only Levels of trace
249 These cannot be used in any of the trace calls directly, but are set
250 by methods of the Tracer class for specific purposes, such as trace
251 Enter and traceExit.
252 LEVEL0 - Trace is switched off
253 LEVEL5 - used for method enter & exit
254 */
255 static const Uint32 LEVEL0;
256 static const Uint32 LEVEL5;
257
|
258 mike 1.2 static const char _COMPONENT_SEPARATOR;
259 static const Uint32 _NUM_COMPONENTS;
260 static const Uint32 _STRLEN_MAX_UNSIGNED_INT;
|
261 kumpf 1.4 static const Uint32 _STRLEN_MAX_PID_TID;
|
262 kumpf 1.15 AutoArrayPtr<Boolean> _traceComponentMask;
|
263 r.kieninger 1.35 Uint32 _traceFacility;
|
264 marek 1.34 //Is true if any components are set at the component mask
265 Boolean _componentsAreSet;
266 Uint32 _traceLevelMask;
|
267 r.kieninger 1.35 AutoPtr<TraceHandler> _traceHandler;
|
268 kumpf 1.15 String _moduleName;
|
269 mike 1.2 static Tracer* _tracerInstance;
270
|
271 kumpf 1.10 // Message Strings for function Entry and Exit
|
272 r.kieninger 1.20 static const char _METHOD_ENTER_MSG[];
273 static const char _METHOD_EXIT_MSG[];
|
274 mike 1.2
|
275 r.kieninger 1.35 // Factory function to create an instance of the matching trace handler
276 // for the given type of traceFacility.
277 // @param traceFacility type of trace handler to create
278 // @return an instance of a trace handler class. For invalid trace
279 // facilities always creates a traceFileHandler.
280 TraceHandler* getTraceHandler( Uint32 traceFacility );
281
|
282 mike 1.2 // Traces the given message. Overloaded to include the file name and the
283 // line number as one of the parameters.
284 // @param traceComponent component being traced
285 // @param message message header (file name:line number)
286 // @param *fmt printf style format string
287 // @param argList variable argument list
288 static void _trace(
|
289 kumpf 1.27 const char* fileName,
290 const Uint32 lineNum,
291 const Uint32 traceComponent,
292 const char* fmt,
293 va_list argList);
|
294 mike 1.2
|
295 kumpf 1.6 // Traces the message in the given CIMException object. The message
|
296 r.kieninger 1.20 // to be written to the trace file will include the source filename and
|
297 kumpf 1.6 // line number of the CIMException originator.
298 // @param traceComponent component being traced
299 // @param CIMException the CIMException to be traced.
300 //
301 static void _traceCIMException(
|
302 kumpf 1.27 const Uint32 traceComponent,
303 const CIMException& cimException);
|
304 r.kieninger 1.20
|
305 marek 1.28 // Called by all the trace interfaces to log message
306 // consisting of a single character string to the trace file
307 // @param traceComponent component being traced
308 // @param cstring the string to be traced
309 static void _traceCString(
310 const Uint32 traceComponent,
311 const char* message,
312 const char* cstring);
313
314 // Called by all the trace interfaces to log message
315 // with variable number of arguments to the trace file
|
316 mike 1.2 // @param traceComponent component being traced
317 // @param *fmt printf style format string
318 // @param argList variable argument list
319 static void _trace(
|
320 kumpf 1.27 const Uint32 traceComponent,
321 const char* message,
322 const char* fmt,
323 va_list argList);
|
324 mike 1.2
|
325 marek 1.28 // Traces method enter/exit
|
326 mike 1.2 // @param fileName filename of the trace originator
327 // @param lineNum line number of the trace originator
328 // @param traceComponent component being traced
|
329 marek 1.28 // @param method name of the method
330 static void _traceMethod(
|
331 kumpf 1.27 const char* fileName,
332 const Uint32 lineNum,
333 const Uint32 traceComponent,
|
334 marek 1.28 const char* methodEntryExit,
335 const char* method);
|
336 mike 1.2
337 // Tracer constructor
338 // Constructor is private to prevent construction of Tracer objects
339 // Single Instance of Tracer is maintained for each process.
340 Tracer();
341
342 // Tracer destructor
343 ~Tracer();
344
345 // Returns the Singleton instance of the Tracer
|
346 r.kieninger 1.20 // @return Tracer* Instance of Tracer
|
347 mike 1.2 static Tracer* _getInstance();
|
348 marek 1.31
349 friend class TraceCallFrame;
|
350 marek 1.34 friend class TracePropertyOwner;
|
351 mike 1.2 };
352
|
353 karl 1.25 //==============================================================================
354 //
355 // PEGASUS_REMOVE_TRACE defines the compile time inclusion of the Trace
356 // interfaces. If defined the interfaces map to empty functions.
357 //
358 //==============================================================================
359
|
360 mike 1.2 #ifdef PEGASUS_REMOVE_TRACE
|
361 karl 1.25
|
362 marek 1.28 inline void Tracer::traceCString(
363 const char* fileName,
364 const Uint32 lineNum,
|
365 kumpf 1.27 const Uint32 traceComponent,
|
366 marek 1.28 const char* cstring)
|
367 karl 1.25 {
368 // empty function
369 }
370
371 inline void Tracer::traceCIMException(
|
372 kumpf 1.27 const Uint32 traceComponent,
373 const Uint32 level,
374 const CIMException& cimException)
|
375 karl 1.25 {
376 // empty function
377 }
378
|
379 sushma.fernandes 1.30 static SharedArrayPtr<char> getHTTPRequestMessage(
380 const Buffer& requestMessage)
381 {
382 //empty function
383 return SharedArrayPtr<char>();
384 }
385
|
386 karl 1.25 inline Uint32 Tracer::setTraceFile(const char* traceFile)
387 {
388 // empty function
389 return 0;
390 }
391
|
392 kumpf 1.26 inline Uint32 Tracer::setTraceLevel(const Uint32 level)
393 {
394 // empty function
395 return 0;
396 }
397
398 inline void Tracer::setTraceComponents(const String& traceComponents)
399 {
400 // empty function
401 }
402
|
403 r.kieninger 1.35 inline Uint32 Tracer::setTraceFacility(const String& traceComponents)
404 {
405 // empty function
406 }
407
|
408 karl 1.25 #endif /* PEGASUS_REMOVE_TRACE */
409
410 //==============================================================================
411 //
412 // Tracing macros
413 //
414 //==============================================================================
415
416 // Defines a variable that bypasses inclusion of line and filename in output.
417 // #define PEGASUS_NO_FILE_LINE_TRACE=1 to exclude file names and line numbers
418 #ifdef PEGASUS_NO_FILE_LINE_TRACE
419 # define PEGASUS_COMMA_FILE_LINE /* empty */
420 # define PEGASUS_FILE_LINE_COMMA /* empty */
|
421 mike 1.2 #else
|
422 karl 1.25 # define PEGASUS_COMMA_FILE_LINE ,__FILE__,__LINE__
423 # define PEGASUS_FILE_LINE_COMMA __FILE__,__LINE__,
424 #endif
425
426 #ifdef PEGASUS_REMOVE_TRACE
427
428 # define PEG_METHOD_ENTER(comp,meth)
429 # define PEG_METHOD_EXIT()
430 # define PEG_TRACE_STRING(comp,level,string)
431 # define PEG_TRACE(VAR_ARGS)
|
432 marek 1.28 # define PEG_TRACE_CSTRING(comp,level,chars)
|
433 karl 1.25
434 #else /* PEGASUS_REMOVE_TRACE */
435
|
436 marek 1.36 // remover trace code for method enter/exit
437 # ifdef PEGASUS_REMOVE_METHODTRACE
438 # define PEG_METHOD_ENTER(comp,meth)
439 # define PEG_METHOD_EXIT()
440 # else
441 # define PEG_METHOD_ENTER(comp, meth) \
|
442 karl 1.25 TracerToken __tracerToken; \
|
443 dave.sudlik 1.32 __tracerToken.method = 0; \
|
444 marek 1.28 do \
445 { \
446 if (Tracer::isTraceOn()) \
|
447 kumpf 1.29 Tracer::traceEnter( \
448 __tracerToken PEGASUS_COMMA_FILE_LINE, comp, meth); \
|
449 marek 1.28 } \
450 while (0)
|
451 karl 1.25
452 # define PEG_METHOD_EXIT() \
|
453 marek 1.28 do \
454 { \
455 if (Tracer::isTraceOn()) \
456 Tracer::traceExit(__tracerToken PEGASUS_COMMA_FILE_LINE); \
457 } \
458 while (0)
|
459 marek 1.36 # endif
|
460 karl 1.25
461 // Macro for Trace String. the do construct allows this to appear
462 // as a single statement.
463 # define PEG_TRACE_STRING(comp, level, string) \
464 do \
465 { \
|
466 marek 1.28 if (Tracer::isTraceOn()) \
|
467 marek 1.31 { \
468 if (Tracer::isTraceEnabled(comp, level)) \
469 { \
470 Tracer::traceCString(PEGASUS_FILE_LINE_COMMA \
471 comp, \
472 (const char*) (string).getCString()); \
473 } \
474 } \
|
475 marek 1.28 } \
476 while (0)
477
478 // Macro to trace character lists. the do construct allows this to appear
479 // as a single statement.
480 # define PEG_TRACE_CSTRING(comp, level, chars) \
481 do \
482 { \
483 if (Tracer::isTraceOn()) \
|
484 marek 1.31 { \
485 if (Tracer::isTraceEnabled(comp, level)) \
486 { \
487 Tracer::traceCString(PEGASUS_FILE_LINE_COMMA comp, chars); \
488 } \
489 } \
|
490 karl 1.25 } \
491 while (0)
492
|
493 marek 1.31 //
494 // This class is constructed with the same arguments passed to PEG_TRACE().
495 // The constructor saves all the fixed arguments and calls va_start() on
496 // the varying arguments (wherein the va_list argument is the ap member of
497 // this class). The PEG_TRACE() macro eventually calls invoke() with the
498 // file and line macros in order to write the trace entry. For more details,
499 // see the comments below on the PEG_TRACE() macro.
500 //
501 class TraceCallFrame
502 {
503 public:
504
505 const char* file;
506 Uint32 line;
507
508 TraceCallFrame(const char* file_, Uint32 line_) : file(file_), line(line_)
509 {
510 }
511
512 PEGASUS_FORMAT(4, 5)
513 inline void invoke(
514 marek 1.31 const Uint32 component,
515 const Uint32 level,
516 const char* format,
517 ...)
518 {
519 if (Tracer::isTraceEnabled(component, level))
520 {
521 va_list ap;
522 va_start(ap, format);
523 Tracer::_trace(file, line, component, format, ap);
524 va_end(ap);
525 }
526 }
527
528 ~TraceCallFrame()
529 {
530 }
531 };
532 //
533 // This macro is a wrapper for calling the printf-style form of the
534 // Tracer::trace() function. Since macros cannot have a varying number of
535 marek 1.31 // arguments, PEG_TRACE() must be invoked with double parentheses. For
536 // example:
537 //
538 // PEG_TRACE((TRC_HTTP, Tracer::LEVEL1, "Oops: %d", 999));
539 //
540 // This macro offers two advantages over the calling trace() directly.
541 //
542 // 1. It eliminates the call to trace() if isTraceOn() returns false.
543 // This has proven to reduce the expense of servicing a request
544 // (when tracing is off) by as much as 3%.
545 //
546 // 2. It implicitly injects the __FILE__ and __LINE__ macros, relieving
547 // the caller of this burden.
548 //
|
549 karl 1.25 # define PEG_TRACE(VAR_ARGS) \
550 do \
551 { \
|
552 kumpf 1.27 if (Tracer::isTraceOn()) \
|
553 marek 1.31 { \
554 TraceCallFrame frame(__FILE__, __LINE__); \
555 frame.invoke VAR_ARGS; \
556 } \
|
557 karl 1.25 } \
558 while (0)
|
559 mike 1.22
|
560 karl 1.25 #endif /* !PEGASUS_REMOVE_TRACE */
|
561 mike 1.2
562 PEGASUS_NAMESPACE_END
563
564 #endif /* Pegasus_Tracer_h */
|