1 mike 1.2 //%/////////////////////////////////////////////////////////////////////////////
2 //
|
3 kumpf 1.12 // Copyright (c) 2000, 2001, 2002 BMC Software, Hewlett-Packard Company, IBM,
|
4 mike 1.2 // The Open Group, Tivoli Systems
5 //
6 // Permission is hereby granted, free of charge, to any person obtaining a copy
7 // of this software and associated documentation files (the "Software"), to
8 // deal in the Software without restriction, including without limitation the
9 // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
10 // sell copies of the Software, and to permit persons to whom the Software is
11 // furnished to do so, subject to the following conditions:
|
12 kumpf 1.12 //
|
13 mike 1.2 // THE ABOVE COPYRIGHT NOTICE AND THIS PERMISSION NOTICE SHALL BE INCLUDED IN
14 // ALL COPIES OR SUBSTANTIAL PORTIONS OF THE SOFTWARE. THE SOFTWARE IS PROVIDED
15 // "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
16 // LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
17 // PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
18 // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
19 // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 //
22 //==============================================================================
23 //
24 // Author: Sushma Fernandes, Hewlett-Packard Company (sushma_fernandes@hp.com)
25 //
|
26 kumpf 1.5 // Modified By: Jenny Yu, Hewlett-Packard Company (jenny_yu@hp.com)
|
27 mike 1.2 //
28 //%/////////////////////////////////////////////////////////////////////////////
29
|
30 sage 1.4 #include <Pegasus/Common/Config.h>
|
31 mike 1.2 #include <Pegasus/Common/Tracer.h>
32 #include <Pegasus/Common/Destroyer.h>
|
33 kumpf 1.3 #include <Pegasus/Common/Thread.h>
34 #include <Pegasus/Common/IPC.h>
35 #include <Pegasus/Common/System.h>
|
36 mike 1.2
37 PEGASUS_USING_STD;
38
39 PEGASUS_NAMESPACE_BEGIN
40
41 // Set the trace levels
42 // These levels will be compared against a trace level mask to determine
43 // if a specific trace level is enabled
44
45 const Uint32 Tracer::LEVEL1 = (1 << 0);
46 const Uint32 Tracer::LEVEL2 = (1 << 1);
47 const Uint32 Tracer::LEVEL3 = (1 << 2);
48 const Uint32 Tracer::LEVEL4 = (1 << 3);
49
50 // Set the return codes
51 const Boolean Tracer::_SUCCESS = 1;
52 const Boolean Tracer::_FAILURE = 0;
53
54 // Set the Enter and Exit messages
|
55 kumpf 1.13 const char Tracer::_METHOD_ENTER_MSG[] = "Entering method";
56 const char Tracer::_METHOD_EXIT_MSG[] = "Exiting method";
|
57 mike 1.2
58 // Set Log messages
|
59 kumpf 1.13 const char Tracer::_LOG_MSG[] = "LEVEL1 may only be used with trace macros PEG_METHOD_ENTER/PEG_METHOD_EXIT.";
|
60 mike 1.2
61 // Initialize singleton instance of Tracer
62 Tracer* Tracer::_tracerInstance = 0;
63
64 // Set component separator
65 const char Tracer::_COMPONENT_SEPARATOR = ',';
66
67 // Set the number of defined components
68 const Uint32 Tracer::_NUM_COMPONENTS =
69 sizeof(TRACE_COMPONENT_LIST)/sizeof(TRACE_COMPONENT_LIST[0]);
70
71 // Set the line maximum
72 const Uint32 Tracer::_STRLEN_MAX_UNSIGNED_INT = 21;
73
|
74 kumpf 1.3 // Set the max PID and Thread ID Length
75 const Uint32 Tracer::_STRLEN_MAX_PID_TID = 20;
76
|
77 mike 1.2 ////////////////////////////////////////////////////////////////////////////////
78 // Tracer constructor
79 // Constructor is private to preclude construction of Tracer objects
80 // Single Instance of Tracer is maintained for each process.
81 ////////////////////////////////////////////////////////////////////////////////
82 Tracer::Tracer()
83 {
84 // Initialize Trace File Handler
85 _traceHandler=new TraceFileHandler();
86 _traceLevelMask=0;
87 _traceComponentMask=new Boolean[_NUM_COMPONENTS];
88
89 // Initialize ComponentMask array to false
90 for (Uint32 index=0;index < _NUM_COMPONENTS;
91 _traceComponentMask[index++]=false);
92 }
93
94 ////////////////////////////////////////////////////////////////////////////////
95 //Tracer destructor
96 ////////////////////////////////////////////////////////////////////////////////
97 Tracer::~Tracer()
98 mike 1.2 {
99 delete []_traceComponentMask;
100 delete _traceHandler;
101 delete _tracerInstance;
102 }
103
104
105 ////////////////////////////////////////////////////////////////////////////////
106 //Traces the given message
107 ////////////////////////////////////////////////////////////////////////////////
108 void Tracer::_trace(
109 const Uint32 traceComponent,
110 const Uint32 traceLevel,
111 const char* fmt,
112 va_list argList)
113 {
114 if ( traceLevel == LEVEL1 )
115 {
116 // ATTN: Setting the Log file type to DEBUG_LOG
117 // May need to change to an appropriate log file type
|
118 kumpf 1.5 Logger::put(Logger::DEBUG_LOG,"Tracer",Logger::WARNING,"$0", _LOG_MSG);
|
119 mike 1.2 }
120 else
121 {
122 if (_isTraceEnabled(traceComponent,traceLevel))
123 {
124 _trace(traceComponent,"",fmt,argList);
125 }
126 }
127 }
128
129 ////////////////////////////////////////////////////////////////////////////////
130 //Traces the given message - Overloaded for including FileName and Line number
131 ////////////////////////////////////////////////////////////////////////////////
132 void Tracer::_trace(
133 const char* fileName,
134 const Uint32 lineNum,
135 const Uint32 traceComponent,
136 const Uint32 traceLevel,
137 const char* fmt,
138 va_list argList)
139 {
140 mike 1.2 char* message;
141
142 if ( traceLevel == LEVEL1 )
143 {
|
144 kumpf 1.5 Logger::put(Logger::DEBUG_LOG,"Tracer",Logger::WARNING,"$0", _LOG_MSG);
|
145 mike 1.2 }
146 else
147 {
148 if (_isTraceEnabled(traceComponent,traceLevel))
149 {
|
150 kumpf 1.3 //
151 // Allocate memory for the message string
152 // Needs to be updated if additional info is added
153 //
|
154 mike 1.2 message = new char[ strlen(fileName) +
|
155 kumpf 1.3 _STRLEN_MAX_UNSIGNED_INT + _STRLEN_MAX_PID_TID ];
156 sprintf(
157 message,
|
158 kumpf 1.9 "[%d:%u:%s:%u]: ",
|
159 kumpf 1.3 System::getPID(),
|
160 kumpf 1.9 Uint32(pegasus_thread_self()),
|
161 kumpf 1.3 fileName,
162 lineNum);
|
163 mike 1.2
164 _trace(traceComponent,message,fmt,argList);
165 delete []message;
166 }
167 }
168 }
169
170 ////////////////////////////////////////////////////////////////////////////////
171 //Traces the given buffer
172 ////////////////////////////////////////////////////////////////////////////////
173 void Tracer::_traceBuffer(
174 const Uint32 traceComponent,
175 const Uint32 traceLevel,
176 const char* data,
177 const Uint32 size)
178 {
179 if ( traceLevel == LEVEL1 )
180 {
|
181 kumpf 1.5 Logger::put(Logger::DEBUG_LOG,"Tracer",Logger::WARNING,"$0", _LOG_MSG);
|
182 mike 1.2 }
183 else
184 {
185 if (_isTraceEnabled(traceComponent,traceLevel))
186 {
187 char* tmpBuf = new char[size+1];
188
189 strncpy( tmpBuf, data, size );
190 tmpBuf[size] = '\0';
191 trace(traceComponent,traceLevel,"%s",tmpBuf);
192
193 delete []tmpBuf;
194 }
195 }
196 }
197 ////////////////////////////////////////////////////////////////////////////////
198 //Traces the given buffer - Overloaded for including FileName and Line number
199 ////////////////////////////////////////////////////////////////////////////////
200 void Tracer::_traceBuffer(
201 const char* fileName,
202 const Uint32 lineNum,
203 mike 1.2 const Uint32 traceComponent,
204 const Uint32 traceLevel,
205 const char* data,
206 const Uint32 size)
207 {
208 if ( traceLevel == LEVEL1 )
209 {
|
210 kumpf 1.5 Logger::put(Logger::DEBUG_LOG,"Tracer",Logger::WARNING,"$0", _LOG_MSG);
|
211 mike 1.2 }
212 else
213 {
214 if ( _isTraceEnabled( traceComponent, traceLevel ) )
215 {
216 char* tmpBuf = new char[size+1];
217
218 strncpy( tmpBuf, data, size );
219 tmpBuf[size] = '\0';
220 trace(fileName,lineNum,traceComponent,traceLevel,"%s",tmpBuf);
221
222 delete []tmpBuf;
|
223 kumpf 1.5 }
224 }
225 }
226
227 ////////////////////////////////////////////////////////////////////////////////
228 //Traces the given string
229 ////////////////////////////////////////////////////////////////////////////////
230 void Tracer::_traceString(
231 const Uint32 traceComponent,
232 const Uint32 traceLevel,
233 const String& traceString)
234 {
235 if ( traceLevel == LEVEL1 )
236 {
237 Logger::put(Logger::DEBUG_LOG,"Tracer",Logger::WARNING,"$0", _LOG_MSG);
238 }
239 else
240 {
241 if (_isTraceEnabled(traceComponent,traceLevel))
242 {
|
243 kumpf 1.7 ArrayDestroyer<char> traceMsg(traceString.allocateCString());
244 trace(traceComponent,traceLevel,"%s",traceMsg.getPointer());
|
245 kumpf 1.5 }
246 }
247 }
248
249 ////////////////////////////////////////////////////////////////////////////////
250 //Traces the given string - Overloaded to include the fileName and line number
251 //of trace origin.
252 ////////////////////////////////////////////////////////////////////////////////
253 void Tracer::_traceString(
254 const char* fileName,
255 const Uint32 lineNum,
256 const Uint32 traceComponent,
257 const Uint32 traceLevel,
258 const String& traceString)
259 {
260 if ( traceLevel == LEVEL1 )
261 {
262 Logger::put(Logger::DEBUG_LOG,"Tracer",Logger::WARNING,"$0", _LOG_MSG);
263 }
264 else
265 {
266 kumpf 1.5 if ( _isTraceEnabled( traceComponent, traceLevel ) )
267 {
|
268 kumpf 1.7 ArrayDestroyer<char> traceMsg(traceString.allocateCString());
269 trace(fileName,lineNum,traceComponent,traceLevel,"%s",traceMsg.getPointer());
|
270 kumpf 1.5 }
271 }
272 }
273
274 ////////////////////////////////////////////////////////////////////////////////
275 //Traces the message in the given CIMException object.
276 ////////////////////////////////////////////////////////////////////////////////
277 void Tracer::_traceCIMException(
278 const Uint32 traceComponent,
279 const Uint32 traceLevel,
280 CIMException cimException)
281 {
282 if ( traceLevel == LEVEL1 )
283 {
284 Logger::put(Logger::DEBUG_LOG,"Tracer",Logger::WARNING,"$0", _LOG_MSG);
285 }
286 else
287 {
288 if ( _isTraceEnabled( traceComponent, traceLevel ) )
289 {
290 // get the CIMException trace message string
|
291 kumpf 1.11 String traceMsg = cimException.getTraceDescription();
|
292 kumpf 1.5
293 // trace the string
294 _traceString(traceComponent, traceLevel, traceMsg);
|
295 mike 1.2 }
296 }
297 }
298
299 ////////////////////////////////////////////////////////////////////////////////
300 //Traces method entry
301 ////////////////////////////////////////////////////////////////////////////////
302 void Tracer::_traceEnter(
303 const char* fileName,
304 const Uint32 lineNum,
305 const Uint32 traceComponent,
306 const char* fmt,
307 ...)
308 {
309 va_list argList;
310 char* message;
311
312 if (_isTraceEnabled(traceComponent,LEVEL1))
313 {
|
314 kumpf 1.3
|
315 mike 1.2 va_start(argList,fmt);
316
|
317 kumpf 1.3 //
318 // Allocate memory for the message string
319 // Needs to be updated if additional info is added
320 //
|
321 mike 1.2 message = new char[ strlen(fileName) +
|
322 kumpf 1.3 _STRLEN_MAX_UNSIGNED_INT + _STRLEN_MAX_PID_TID ];
323 sprintf(
324 message,
|
325 kumpf 1.9 "[%d:%u:%s:%u]: ",
|
326 kumpf 1.3 System::getPID(),
|
327 kumpf 1.9 Uint32(pegasus_thread_self()),
|
328 kumpf 1.3 fileName,
329 lineNum);
|
330 mike 1.2 _trace(traceComponent,message,fmt,argList);
331
332 va_end(argList);
333 delete []message;
334 }
335 }
336
337 ////////////////////////////////////////////////////////////////////////////////
338 //Traces method exit
339 ////////////////////////////////////////////////////////////////////////////////
340 void Tracer::_traceExit(
341 const char* fileName,
342 const Uint32 lineNum,
343 const Uint32 traceComponent,
344 const char* fmt
345 ...)
346 {
347 va_list argList;
348 char* message;
349
350 if (_isTraceEnabled(traceComponent,LEVEL1))
351 mike 1.2 {
352 va_start(argList,fmt);
353
|
354 kumpf 1.3 //
355 // Allocate memory for the message string
356 // Needs to be updated if additional info is added
357 //
|
358 mike 1.2 message = new char[ strlen(fileName) +
|
359 kumpf 1.3 _STRLEN_MAX_UNSIGNED_INT + _STRLEN_MAX_PID_TID ];
360 sprintf(
361 message,
|
362 kumpf 1.9 "[%d:%u:%s:%u]: ",
|
363 kumpf 1.3 System::getPID(),
|
364 kumpf 1.9 Uint32(pegasus_thread_self()),
|
365 kumpf 1.3 fileName,
366 lineNum);
|
367 mike 1.2 _trace(traceComponent,message,fmt,argList);
368 va_end(argList);
369
370 delete []message;
371 }
372 }
373
374 ////////////////////////////////////////////////////////////////////////////////
375 //Checks if trace is enabled for the given component and level
376 ////////////////////////////////////////////////////////////////////////////////
377 Boolean Tracer::_isTraceEnabled(const Uint32 traceComponent,
378 const Uint32 traceLevel)
379 {
380 Tracer* instance = _getInstance();
381 if (traceComponent >= _NUM_COMPONENTS)
382 {
383 return false;
384 }
385 return ((instance->_traceComponentMask[traceComponent]) &&
386 (traceLevel & instance->_traceLevelMask));
387 }
388 mike 1.2
389 ////////////////////////////////////////////////////////////////////////////////
390 //Called by all trace interfaces to log message to trace file
391 ////////////////////////////////////////////////////////////////////////////////
392 void Tracer::_trace(
393 const Uint32 traceComponent,
394 const char* message,
395 const char* fmt,
396 va_list argList)
397 {
398 char* msgHeader;
399
400 // Get the current system time and prepend to message
401 String currentTime = System::getCurrentASCIITime();
402 ArrayDestroyer<char> timeStamp(currentTime.allocateCString());
403
|
404 kumpf 1.3 //
|
405 mike 1.2 // Allocate messageHeader.
|
406 kumpf 1.3 // Needs to be updated if additional info is added
407 //
|
408 mike 1.2 msgHeader = new char [strlen(message)
409 + strlen(TRACE_COMPONENT_LIST[traceComponent])
|
410 kumpf 1.3 + strlen(timeStamp.getPointer()) + _STRLEN_MAX_PID_TID];
|
411 mike 1.2
412 // Construct the message header
413 // The message header is in the following format
414 // timestamp: <component name> [file name:line number]
415 if (strcmp(message,"") != 0)
416 {
417 sprintf(msgHeader,"%s: %s %s",timeStamp.getPointer(),
418 TRACE_COMPONENT_LIST[traceComponent] ,message);
419 }
420 else
421 {
|
422 kumpf 1.3 //
423 // Since the message is blank form a string using the pid and tid
424 //
425 char* tmpBuffer;
426
427 //
428 // Allocate messageHeader.
429 // Needs to be updated if additional info is added
430 //
431 tmpBuffer = new char[_STRLEN_MAX_PID_TID];
|
432 kumpf 1.9 sprintf(tmpBuffer, "[%u:%u]: ", System::getPID(),
433 Uint32(pegasus_thread_self()));
|
434 kumpf 1.3
435 sprintf(msgHeader,"%s: %s %s ",timeStamp.getPointer(),
436 TRACE_COMPONENT_LIST[traceComponent] ,tmpBuffer );
437 delete []tmpBuffer;
|
438 mike 1.2 }
439
440 // Call trace file handler to write message
441 _getInstance()->_traceHandler->handleMessage(msgHeader,fmt,argList);
442 delete []msgHeader;
443 }
444
445 ////////////////////////////////////////////////////////////////////////////////
446 //Validate the trace file
447 ////////////////////////////////////////////////////////////////////////////////
|
448 kumpf 1.10 Boolean Tracer::isValidFileName(const char* filePath)
|
449 mike 1.2 {
450 return (_getInstance()->_traceHandler->isValidFilePath(filePath));
451 }
452
453 ////////////////////////////////////////////////////////////////////////////////
454 //Validate the trace components
455 ////////////////////////////////////////////////////////////////////////////////
|
456 kumpf 1.10 Boolean Tracer::isValidComponents(const String traceComponents)
457 {
458 String invalidComponents;
459 return isValidComponents(traceComponents, invalidComponents);
460 }
461
462 Boolean Tracer::isValidComponents(
463 const String traceComponents, String& invalidComponents)
|
464 mike 1.2 {
465 // Validate the trace components and modify the traceComponents argument
466 // to reflect the invalid components
467
468 Uint32 position=0;
469 Uint32 index=0;
470 String componentName = String::EMPTY;
471 String componentStr = String::EMPTY;
472 Boolean validComponent=false;
473 Boolean retCode=true;
474
475 componentStr = traceComponents;
476 invalidComponents = String::EMPTY;
477
478 if (componentStr != String::EMPTY)
479 {
480 // Check if ALL is specified
481 if (String::equalNoCase(componentStr,"ALL"))
482 {
483 return _SUCCESS;
484 }
485 mike 1.2
486 // Append _COMPONENT_SEPARATOR to the end of the traceComponents
487 componentStr += _COMPONENT_SEPARATOR;
488
489 while (componentStr != String::EMPTY)
490 {
491 //
492 // Get the Component name from traceComponents.
493 // Components are separated by _COMPONENT_SEPARATOR
494 //
495 position = componentStr.find(_COMPONENT_SEPARATOR);
496 componentName = componentStr.subString(0,(position));
497
498 // Lookup the index for Component name in TRACE_COMPONENT_LIST
499 index = 0;
500 validComponent = false;
501
502 while (index < _NUM_COMPONENTS)
503 {
504 if (String::equalNoCase(
505 componentName, TRACE_COMPONENT_LIST[index]))
506 mike 1.2 {
507 // Found component, break from the loop
508 validComponent = true;
509 break;
510 }
511 else
512 {
513 index++;
514 }
515 }
516
517 // Remove the searched componentname from the traceComponents
518 componentStr.remove(0,position+1);
519
520 if ( !validComponent )
521 {
522 invalidComponents += componentName;
523 invalidComponents += _COMPONENT_SEPARATOR;
524 }
525 }
526 }
527 mike 1.2 else
528 {
529 // trace components is empty, it is a valid value so return true
530 return _SUCCESS;
531 }
532 if ( invalidComponents != String::EMPTY )
533 {
534 retCode = false;
535 //
536 // Remove the extra ',' at the end
537 //
538 invalidComponents.remove(
539 invalidComponents.reverseFind(_COMPONENT_SEPARATOR));
540 }
541 return retCode;
542 }
543
544 ////////////////////////////////////////////////////////////////////////////////
545 //Returns the Singleton instance of the Tracer
546 ////////////////////////////////////////////////////////////////////////////////
547 Tracer* Tracer::_getInstance()
548 mike 1.2 {
549 if (_tracerInstance == 0)
550 {
551 _tracerInstance = new Tracer();
552 }
553 return _tracerInstance;
554 }
555
556 // PEGASUS_REMOVE_TRACE defines the compile time inclusion of the Trace
557 // interfaces. If defined the interfaces map to empty functions
558
559 #ifndef PEGASUS_REMOVE_TRACE
560
561 ////////////////////////////////////////////////////////////////////////////////
562 //Set the trace file
563 ////////////////////////////////////////////////////////////////////////////////
564 Uint32 Tracer::setTraceFile(const char* traceFile)
565 {
566 return (_getInstance()->_traceHandler->setFileName (traceFile));
567 }
568
569 mike 1.2 ////////////////////////////////////////////////////////////////////////////////
570 //Set the trace level
571 ////////////////////////////////////////////////////////////////////////////////
572 Uint32 Tracer::setTraceLevel(const Uint32 traceLevel)
573 {
574 Uint32 retCode = 0;
575
576 switch (traceLevel)
577 {
578 case LEVEL1:
579 _getInstance()->_traceLevelMask = 0x01;
580 break;
581
582 case LEVEL2:
583 _getInstance()->_traceLevelMask = 0x03;
584 break;
585
586 case LEVEL3:
587 _getInstance()->_traceLevelMask = 0x07;
588 break;
589
590 mike 1.2 case LEVEL4:
591 _getInstance()->_traceLevelMask = 0x0F;
592 break;
593
594 default:
595 _getInstance()->_traceLevelMask = 0;
596 retCode = 1;
597 }
598 return retCode;
599 }
600
601 ////////////////////////////////////////////////////////////////////////////////
602 // Set components to be traced.
603 ////////////////////////////////////////////////////////////////////////////////
604 void Tracer::setTraceComponents( const String traceComponents )
605 {
606 Uint32 position = 0;
607 Uint32 index = 0;
608 String componentName = String::EMPTY;
609 String componentStr = traceComponents;
610 String invalidComponents = String::EMPTY;
611 mike 1.2
612 if (componentStr != String::EMPTY)
613 {
614 // Check if ALL is specified
615 if (String::equalNoCase(componentStr,"ALL"))
616 {
617 for (index=0; index < _NUM_COMPONENTS;
618 _getInstance()->_traceComponentMask[index++] = true);
619 return ;
620 }
621
622 // initialise ComponentMask array to False
623 for (index = 0;index < _NUM_COMPONENTS;
624 _getInstance()->_traceComponentMask[index++] = false);
625
626 // Append _COMPONENT_SEPARATOR to the end of the traceComponents
627 componentStr += _COMPONENT_SEPARATOR;
628
629 while (componentStr != String::EMPTY)
630 {
631 // Get the Component name from traceComponents.
632 mike 1.2 // Components are separated by _COMPONENT_SEPARATOR
633 position = componentStr.find(_COMPONENT_SEPARATOR);
634 componentName = componentStr.subString(0,(position));
635
636 // Lookup the index for Component name in TRACE_COMPONENT_LIST
637 index = 0;
638 while (index < _NUM_COMPONENTS)
639 {
640 if (String::equalNoCase(
641 componentName,TRACE_COMPONENT_LIST[index]))
642 {
643 _getInstance()->_traceComponentMask[index]=true;
644
645 // Found component, break from the loop
646 break;
647 }
648 else
649 {
650 index++;
651 }
652 }
653 mike 1.2
654 // Remove the searched componentname from the traceComponents
655 componentStr.remove(0,position+1);
656 }
657 }
658 else
659 {
660 // initialise ComponentMask array to False
661 for (Uint32 index = 0;index < _NUM_COMPONENTS;
662 _getInstance()->_traceComponentMask[index++] = false);
663 }
664 return ;
665 }
666
667 #endif
668
669 PEGASUS_NAMESPACE_END
|