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 marek 1.37 /** Get trace facility currently in use
166 @return TRACE_FACILITY_FILE - if trace facility is file
167 TRACE_FACILITY_LOG - if trace facility is the log
168 */
169 static Uint32 getTraceFacility();
170
|
171 karl 1.25 /** Traces method entry.
|
172 kumpf 1.27 @param token TracerToken
173 @param fileName filename of the trace originator
174 @param lineNum line number of the trace originator
175 @param traceComponent component being traced
176 @param methodName method being traced
|
177 mike 1.2 */
|
178 karl 1.25 static void traceEnter(
|
179 kumpf 1.27 TracerToken& token,
180 const char* file,
181 size_t line,
182 Uint32 component,
183 const char* method);
|
184 r.kieninger 1.20
185 /** Traces method exit.
|
186 kumpf 1.27 @param token TracerToken containing component and method
187 @param fileName filename of the trace originator
188 @param lineNum line number of the trace originator
|
189 mike 1.2 */
|
190 karl 1.25 static void traceExit(
|
191 kumpf 1.27 TracerToken& token,
192 const char* file,
193 size_t line);
|
194 mike 1.2
195 /** Validates the File Path for the trace File
|
196 kumpf 1.27 @param filePath full path of the file
197 @return 1 if the file path is valid
198 0 if the file path is invalid
|
199 mike 1.2 */
|
200 kumpf 1.7 static Boolean isValidFileName(const char* filePath);
201
202 /** Validates the trace components
|
203 kumpf 1.27 @param traceComponents comma separated list of trace components
204 @return 1 if the components are valid
205 0 if one or more components are invalid
|
206 kumpf 1.7 */
|
207 kumpf 1.15 static Boolean isValidComponents(const String& traceComponents);
|
208 mike 1.2
209 /** Validates the trace components
|
210 kumpf 1.27 @param traceComponents comma separated list of trace components
211 @param invalidComponents comma separated list of invalid components
212 @return 1 if the components are valid
213 0 if one or more components are invalid
|
214 mike 1.2 */
|
215 kumpf 1.7 static Boolean isValidComponents(
|
216 kumpf 1.15 const String& traceComponents,
|
217 kumpf 1.7 String& invalidComponents);
|
218 mike 1.2
|
219 r.kieninger 1.35 /** Validates the trace facility string value
220 @param traceFacility The trace facility as string
221 @return 1 if the trace facility is valid
222 0 if the trace facility is invalid
223 */
224 static Boolean isValidTraceFacility( const String& traceFacility );
225
|
226 kumpf 1.15 /** Specify the name of the module being traced. If non-empty, this
227 value is used as an extension to the name of the trace file.
|
228 kumpf 1.27 @param moduleName Name of the module being traced.
|
229 kumpf 1.15 */
230 static void setModuleName(const String& moduleName);
231
|
232 karl 1.25 /**
233 */
|
234 david.dillard 1.23 static Boolean isTraceOn() { return _traceOn; }
|
235 mike 1.21
|
236 marek 1.31 // Checks if trace is enabled for the given component and trace level
237 // @param traceComponent component being traced
238 // @param level level of the trace message
239 // @return 0 if the component and level are not enabled
240 // 1 if the component and level are enabled
241 static Boolean isTraceEnabled(
242 const Uint32 traceComponent,
243 const Uint32 level);
244
|
245 mike 1.2 private:
246
|
247 r.kieninger 1.20 /** A static single indicator if tracing is turned on allowing to
248 determine the state of trace quickly without many instructions.
249 Used to wrap the public static trace interface methods to avoid
250 obsolete calls when tracing is turned off.
251 */
|
252 david.dillard 1.23 static Boolean _traceOn;
|
253 r.kieninger 1.20
|
254 marek 1.34 /** Internal only Levels of trace
255 These cannot be used in any of the trace calls directly, but are set
256 by methods of the Tracer class for specific purposes, such as trace
257 Enter and traceExit.
258 LEVEL0 - Trace is switched off
259 LEVEL5 - used for method enter & exit
260 */
261 static const Uint32 LEVEL0;
262 static const Uint32 LEVEL5;
263
|
264 mike 1.2 static const char _COMPONENT_SEPARATOR;
265 static const Uint32 _NUM_COMPONENTS;
266 static const Uint32 _STRLEN_MAX_UNSIGNED_INT;
|
267 kumpf 1.4 static const Uint32 _STRLEN_MAX_PID_TID;
|
268 kumpf 1.15 AutoArrayPtr<Boolean> _traceComponentMask;
|
269 r.kieninger 1.35 Uint32 _traceFacility;
|
270 marek 1.34 //Is true if any components are set at the component mask
271 Boolean _componentsAreSet;
272 Uint32 _traceLevelMask;
|
273 r.kieninger 1.35 AutoPtr<TraceHandler> _traceHandler;
|
274 kumpf 1.15 String _moduleName;
|
275 mike 1.2 static Tracer* _tracerInstance;
276
|
277 kumpf 1.10 // Message Strings for function Entry and Exit
|
278 r.kieninger 1.20 static const char _METHOD_ENTER_MSG[];
279 static const char _METHOD_EXIT_MSG[];
|
280 mike 1.2
|
281 r.kieninger 1.35 // Factory function to create an instance of the matching trace handler
282 // for the given type of traceFacility.
283 // @param traceFacility type of trace handler to create
284 // @return an instance of a trace handler class. For invalid trace
285 // facilities always creates a traceFileHandler.
286 TraceHandler* getTraceHandler( Uint32 traceFacility );
287
|
288 mike 1.2 // Traces the given message. Overloaded to include the file name and the
289 // line number as one of the parameters.
290 // @param traceComponent component being traced
291 // @param message message header (file name:line number)
292 // @param *fmt printf style format string
293 // @param argList variable argument list
294 static void _trace(
|
295 kumpf 1.27 const char* fileName,
296 const Uint32 lineNum,
297 const Uint32 traceComponent,
298 const char* fmt,
299 va_list argList);
|
300 mike 1.2
|
301 kumpf 1.6 // Traces the message in the given CIMException object. The message
|
302 r.kieninger 1.20 // to be written to the trace file will include the source filename and
|
303 kumpf 1.6 // line number of the CIMException originator.
304 // @param traceComponent component being traced
305 // @param CIMException the CIMException to be traced.
306 //
307 static void _traceCIMException(
|
308 kumpf 1.27 const Uint32 traceComponent,
309 const CIMException& cimException);
|
310 r.kieninger 1.20
|
311 marek 1.28 // Called by all the trace interfaces to log message
312 // consisting of a single character string to the trace file
313 // @param traceComponent component being traced
314 // @param cstring the string to be traced
315 static void _traceCString(
316 const Uint32 traceComponent,
317 const char* message,
318 const char* cstring);
319
320 // Called by all the trace interfaces to log message
321 // with variable number of arguments to the trace file
|
322 mike 1.2 // @param traceComponent component being traced
323 // @param *fmt printf style format string
324 // @param argList variable argument list
325 static void _trace(
|
326 kumpf 1.27 const Uint32 traceComponent,
327 const char* message,
328 const char* fmt,
329 va_list argList);
|
330 mike 1.2
|
331 marek 1.28 // Traces method enter/exit
|
332 mike 1.2 // @param fileName filename of the trace originator
333 // @param lineNum line number of the trace originator
334 // @param traceComponent component being traced
|
335 marek 1.28 // @param method name of the method
336 static void _traceMethod(
|
337 kumpf 1.27 const char* fileName,
338 const Uint32 lineNum,
339 const Uint32 traceComponent,
|
340 marek 1.28 const char* methodEntryExit,
341 const char* method);
|
342 mike 1.2
343 // Tracer constructor
344 // Constructor is private to prevent construction of Tracer objects
345 // Single Instance of Tracer is maintained for each process.
346 Tracer();
347
348 // Tracer destructor
349 ~Tracer();
350
351 // Returns the Singleton instance of the Tracer
|
352 r.kieninger 1.20 // @return Tracer* Instance of Tracer
|
353 mike 1.2 static Tracer* _getInstance();
|
354 marek 1.31
355 friend class TraceCallFrame;
|
356 marek 1.34 friend class TracePropertyOwner;
|
357 mike 1.2 };
358
|
359 karl 1.25 //==============================================================================
360 //
361 // PEGASUS_REMOVE_TRACE defines the compile time inclusion of the Trace
362 // interfaces. If defined the interfaces map to empty functions.
363 //
364 //==============================================================================
365
|
366 mike 1.2 #ifdef PEGASUS_REMOVE_TRACE
|
367 karl 1.25
|
368 marek 1.28 inline void Tracer::traceCString(
369 const char* fileName,
370 const Uint32 lineNum,
|
371 kumpf 1.27 const Uint32 traceComponent,
|
372 marek 1.28 const char* cstring)
|
373 karl 1.25 {
374 // empty function
375 }
376
377 inline void Tracer::traceCIMException(
|
378 kumpf 1.27 const Uint32 traceComponent,
379 const Uint32 level,
380 const CIMException& cimException)
|
381 karl 1.25 {
382 // empty function
383 }
384
|
385 sushma.fernandes 1.30 static SharedArrayPtr<char> getHTTPRequestMessage(
386 const Buffer& requestMessage)
387 {
388 //empty function
389 return SharedArrayPtr<char>();
390 }
391
|
392 karl 1.25 inline Uint32 Tracer::setTraceFile(const char* traceFile)
393 {
394 // empty function
395 return 0;
396 }
397
|
398 kumpf 1.26 inline Uint32 Tracer::setTraceLevel(const Uint32 level)
399 {
400 // empty function
401 return 0;
402 }
403
404 inline void Tracer::setTraceComponents(const String& traceComponents)
405 {
406 // empty function
407 }
408
|
409 r.kieninger 1.35 inline Uint32 Tracer::setTraceFacility(const String& traceComponents)
410 {
411 // empty function
|
412 marek 1.37 return 0;
413 }
414
415 inline Uint32 Tracer::getTraceFacility()
416 {
417 // empty function
418 return 0;
|
419 r.kieninger 1.35 }
420
|
421 karl 1.25 #endif /* PEGASUS_REMOVE_TRACE */
422
423 //==============================================================================
424 //
425 // Tracing macros
426 //
427 //==============================================================================
428
429 // Defines a variable that bypasses inclusion of line and filename in output.
430 // #define PEGASUS_NO_FILE_LINE_TRACE=1 to exclude file names and line numbers
431 #ifdef PEGASUS_NO_FILE_LINE_TRACE
432 # define PEGASUS_COMMA_FILE_LINE /* empty */
433 # define PEGASUS_FILE_LINE_COMMA /* empty */
|
434 mike 1.2 #else
|
435 karl 1.25 # define PEGASUS_COMMA_FILE_LINE ,__FILE__,__LINE__
436 # define PEGASUS_FILE_LINE_COMMA __FILE__,__LINE__,
437 #endif
438
439 #ifdef PEGASUS_REMOVE_TRACE
440
441 # define PEG_METHOD_ENTER(comp,meth)
442 # define PEG_METHOD_EXIT()
443 # define PEG_TRACE_STRING(comp,level,string)
444 # define PEG_TRACE(VAR_ARGS)
|
445 marek 1.28 # define PEG_TRACE_CSTRING(comp,level,chars)
|
446 karl 1.25
447 #else /* PEGASUS_REMOVE_TRACE */
448
|
449 marek 1.36 // remover trace code for method enter/exit
450 # ifdef PEGASUS_REMOVE_METHODTRACE
451 # define PEG_METHOD_ENTER(comp,meth)
452 # define PEG_METHOD_EXIT()
453 # else
454 # define PEG_METHOD_ENTER(comp, meth) \
|
455 karl 1.25 TracerToken __tracerToken; \
|
456 dave.sudlik 1.32 __tracerToken.method = 0; \
|
457 marek 1.28 do \
458 { \
459 if (Tracer::isTraceOn()) \
|
460 kumpf 1.29 Tracer::traceEnter( \
461 __tracerToken PEGASUS_COMMA_FILE_LINE, comp, meth); \
|
462 marek 1.28 } \
463 while (0)
|
464 karl 1.25
465 # define PEG_METHOD_EXIT() \
|
466 marek 1.28 do \
467 { \
468 if (Tracer::isTraceOn()) \
469 Tracer::traceExit(__tracerToken PEGASUS_COMMA_FILE_LINE); \
470 } \
471 while (0)
|
472 marek 1.36 # endif
|
473 karl 1.25
474 // Macro for Trace String. the do construct allows this to appear
475 // as a single statement.
476 # define PEG_TRACE_STRING(comp, level, string) \
477 do \
478 { \
|
479 marek 1.28 if (Tracer::isTraceOn()) \
|
480 marek 1.31 { \
481 if (Tracer::isTraceEnabled(comp, level)) \
482 { \
483 Tracer::traceCString(PEGASUS_FILE_LINE_COMMA \
484 comp, \
485 (const char*) (string).getCString()); \
486 } \
487 } \
|
488 marek 1.28 } \
489 while (0)
490
491 // Macro to trace character lists. the do construct allows this to appear
492 // as a single statement.
493 # define PEG_TRACE_CSTRING(comp, level, chars) \
494 do \
495 { \
496 if (Tracer::isTraceOn()) \
|
497 marek 1.31 { \
498 if (Tracer::isTraceEnabled(comp, level)) \
499 { \
500 Tracer::traceCString(PEGASUS_FILE_LINE_COMMA comp, chars); \
501 } \
502 } \
|
503 karl 1.25 } \
504 while (0)
505
|
506 marek 1.31 //
507 // This class is constructed with the same arguments passed to PEG_TRACE().
508 // The constructor saves all the fixed arguments and calls va_start() on
509 // the varying arguments (wherein the va_list argument is the ap member of
510 // this class). The PEG_TRACE() macro eventually calls invoke() with the
511 // file and line macros in order to write the trace entry. For more details,
512 // see the comments below on the PEG_TRACE() macro.
513 //
514 class TraceCallFrame
515 {
516 public:
517
518 const char* file;
519 Uint32 line;
520
521 TraceCallFrame(const char* file_, Uint32 line_) : file(file_), line(line_)
522 {
523 }
524
525 PEGASUS_FORMAT(4, 5)
526 inline void invoke(
527 marek 1.31 const Uint32 component,
528 const Uint32 level,
529 const char* format,
530 ...)
531 {
532 if (Tracer::isTraceEnabled(component, level))
533 {
534 va_list ap;
535 va_start(ap, format);
536 Tracer::_trace(file, line, component, format, ap);
537 va_end(ap);
538 }
539 }
540
541 ~TraceCallFrame()
542 {
543 }
544 };
545 //
546 // This macro is a wrapper for calling the printf-style form of the
547 // Tracer::trace() function. Since macros cannot have a varying number of
548 marek 1.31 // arguments, PEG_TRACE() must be invoked with double parentheses. For
549 // example:
550 //
551 // PEG_TRACE((TRC_HTTP, Tracer::LEVEL1, "Oops: %d", 999));
552 //
553 // This macro offers two advantages over the calling trace() directly.
554 //
555 // 1. It eliminates the call to trace() if isTraceOn() returns false.
556 // This has proven to reduce the expense of servicing a request
557 // (when tracing is off) by as much as 3%.
558 //
559 // 2. It implicitly injects the __FILE__ and __LINE__ macros, relieving
560 // the caller of this burden.
561 //
|
562 karl 1.25 # define PEG_TRACE(VAR_ARGS) \
563 do \
564 { \
|
565 kumpf 1.27 if (Tracer::isTraceOn()) \
|
566 marek 1.31 { \
567 TraceCallFrame frame(__FILE__, __LINE__); \
568 frame.invoke VAR_ARGS; \
569 } \
|
570 karl 1.25 } \
571 while (0)
|
572 mike 1.22
|
573 karl 1.25 #endif /* !PEGASUS_REMOVE_TRACE */
|
574 mike 1.2
575 PEGASUS_NAMESPACE_END
576
577 #endif /* Pegasus_Tracer_h */
|