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 kumpf 1.14 trace( traceComponent, Tracer::LEVEL4, "%s", _LOG_MSG );
|
117 mike 1.2 }
118 else
119 {
120 if (_isTraceEnabled(traceComponent,traceLevel))
121 {
122 _trace(traceComponent,"",fmt,argList);
123 }
124 }
125 }
126
127 ////////////////////////////////////////////////////////////////////////////////
128 //Traces the given message - Overloaded for including FileName and Line number
129 ////////////////////////////////////////////////////////////////////////////////
130 void Tracer::_trace(
131 const char* fileName,
132 const Uint32 lineNum,
133 const Uint32 traceComponent,
134 const Uint32 traceLevel,
135 const char* fmt,
136 va_list argList)
137 {
138 mike 1.2 char* message;
139
140 if ( traceLevel == LEVEL1 )
141 {
|
142 kumpf 1.14 trace( traceComponent, Tracer::LEVEL4, "%s", _LOG_MSG );
|
143 mike 1.2 }
144 else
145 {
146 if (_isTraceEnabled(traceComponent,traceLevel))
147 {
|
148 kumpf 1.3 //
149 // Allocate memory for the message string
150 // Needs to be updated if additional info is added
151 //
|
152 mike 1.2 message = new char[ strlen(fileName) +
|
153 kumpf 1.3 _STRLEN_MAX_UNSIGNED_INT + _STRLEN_MAX_PID_TID ];
154 sprintf(
155 message,
|
156 kumpf 1.9 "[%d:%u:%s:%u]: ",
|
157 kumpf 1.3 System::getPID(),
|
158 kumpf 1.9 Uint32(pegasus_thread_self()),
|
159 kumpf 1.3 fileName,
160 lineNum);
|
161 mike 1.2
162 _trace(traceComponent,message,fmt,argList);
163 delete []message;
164 }
165 }
166 }
167
168 ////////////////////////////////////////////////////////////////////////////////
169 //Traces the given buffer
170 ////////////////////////////////////////////////////////////////////////////////
171 void Tracer::_traceBuffer(
172 const Uint32 traceComponent,
173 const Uint32 traceLevel,
174 const char* data,
175 const Uint32 size)
176 {
177 if ( traceLevel == LEVEL1 )
178 {
|
179 kumpf 1.14 trace( traceComponent, Tracer::LEVEL4, "%s", _LOG_MSG );
|
180 mike 1.2 }
181 else
182 {
183 if (_isTraceEnabled(traceComponent,traceLevel))
184 {
185 char* tmpBuf = new char[size+1];
186
187 strncpy( tmpBuf, data, size );
188 tmpBuf[size] = '\0';
189 trace(traceComponent,traceLevel,"%s",tmpBuf);
190
191 delete []tmpBuf;
192 }
193 }
194 }
195 ////////////////////////////////////////////////////////////////////////////////
196 //Traces the given buffer - Overloaded for including FileName and Line number
197 ////////////////////////////////////////////////////////////////////////////////
198 void Tracer::_traceBuffer(
199 const char* fileName,
200 const Uint32 lineNum,
201 mike 1.2 const Uint32 traceComponent,
202 const Uint32 traceLevel,
203 const char* data,
204 const Uint32 size)
205 {
206 if ( traceLevel == LEVEL1 )
207 {
|
208 kumpf 1.14 trace( traceComponent, Tracer::LEVEL4, "%s", _LOG_MSG );
|
209 mike 1.2 }
210 else
211 {
212 if ( _isTraceEnabled( traceComponent, traceLevel ) )
213 {
214 char* tmpBuf = new char[size+1];
215
216 strncpy( tmpBuf, data, size );
217 tmpBuf[size] = '\0';
218 trace(fileName,lineNum,traceComponent,traceLevel,"%s",tmpBuf);
219
220 delete []tmpBuf;
|
221 kumpf 1.5 }
222 }
223 }
224
225 ////////////////////////////////////////////////////////////////////////////////
226 //Traces the given string
227 ////////////////////////////////////////////////////////////////////////////////
228 void Tracer::_traceString(
229 const Uint32 traceComponent,
230 const Uint32 traceLevel,
231 const String& traceString)
232 {
233 if ( traceLevel == LEVEL1 )
234 {
|
235 kumpf 1.14 trace( traceComponent, Tracer::LEVEL4, "%s", _LOG_MSG );
|
236 kumpf 1.5 }
237 else
238 {
239 if (_isTraceEnabled(traceComponent,traceLevel))
240 {
|
241 kumpf 1.18 trace(traceComponent,traceLevel,"%s",
242 (const char *)traceString.getCString());
|
243 kumpf 1.5 }
244 }
245 }
246
247 ////////////////////////////////////////////////////////////////////////////////
248 //Traces the given string - Overloaded to include the fileName and line number
249 //of trace origin.
250 ////////////////////////////////////////////////////////////////////////////////
251 void Tracer::_traceString(
252 const char* fileName,
253 const Uint32 lineNum,
254 const Uint32 traceComponent,
255 const Uint32 traceLevel,
256 const String& traceString)
257 {
258 if ( traceLevel == LEVEL1 )
259 {
|
260 kumpf 1.14 trace( traceComponent, Tracer::LEVEL4, "%s", _LOG_MSG );
|
261 kumpf 1.5 }
262 else
263 {
264 if ( _isTraceEnabled( traceComponent, traceLevel ) )
265 {
|
266 kumpf 1.18 trace(fileName,lineNum,traceComponent,traceLevel,"%s",
267 (const char *)traceString.getCString());
|
268 kumpf 1.5 }
269 }
270 }
271
272 ////////////////////////////////////////////////////////////////////////////////
273 //Traces the message in the given CIMException object.
274 ////////////////////////////////////////////////////////////////////////////////
275 void Tracer::_traceCIMException(
276 const Uint32 traceComponent,
277 const Uint32 traceLevel,
278 CIMException cimException)
279 {
280 if ( traceLevel == LEVEL1 )
281 {
|
282 kumpf 1.14 trace( traceComponent, Tracer::LEVEL4, "%s", _LOG_MSG );
|
283 kumpf 1.5 }
284 else
285 {
286 if ( _isTraceEnabled( traceComponent, traceLevel ) )
287 {
288 // get the CIMException trace message string
|
289 kumpf 1.15 String traceMsg =
290 TraceableCIMException(cimException).getTraceDescription();
|
291 kumpf 1.5
292 // trace the string
293 _traceString(traceComponent, traceLevel, traceMsg);
|
294 mike 1.2 }
295 }
296 }
297
298 ////////////////////////////////////////////////////////////////////////////////
299 //Traces method entry
300 ////////////////////////////////////////////////////////////////////////////////
301 void Tracer::_traceEnter(
302 const char* fileName,
303 const Uint32 lineNum,
304 const Uint32 traceComponent,
305 const char* fmt,
306 ...)
307 {
308 va_list argList;
309 char* message;
310
311 if (_isTraceEnabled(traceComponent,LEVEL1))
312 {
|
313 kumpf 1.3
|
314 mike 1.2 va_start(argList,fmt);
315
|
316 kumpf 1.3 //
317 // Allocate memory for the message string
318 // Needs to be updated if additional info is added
319 //
|
320 mike 1.2 message = new char[ strlen(fileName) +
|
321 kumpf 1.3 _STRLEN_MAX_UNSIGNED_INT + _STRLEN_MAX_PID_TID ];
322 sprintf(
323 message,
|
324 kumpf 1.9 "[%d:%u:%s:%u]: ",
|
325 kumpf 1.3 System::getPID(),
|
326 kumpf 1.9 Uint32(pegasus_thread_self()),
|
327 kumpf 1.3 fileName,
328 lineNum);
|
329 mike 1.2 _trace(traceComponent,message,fmt,argList);
330
331 va_end(argList);
332 delete []message;
333 }
334 }
335
336 ////////////////////////////////////////////////////////////////////////////////
337 //Traces method exit
338 ////////////////////////////////////////////////////////////////////////////////
339 void Tracer::_traceExit(
340 const char* fileName,
341 const Uint32 lineNum,
342 const Uint32 traceComponent,
343 const char* fmt
344 ...)
345 {
346 va_list argList;
347 char* message;
348
349 if (_isTraceEnabled(traceComponent,LEVEL1))
350 mike 1.2 {
351 va_start(argList,fmt);
352
|
353 kumpf 1.3 //
354 // Allocate memory for the message string
355 // Needs to be updated if additional info is added
356 //
|
357 mike 1.2 message = new char[ strlen(fileName) +
|
358 kumpf 1.3 _STRLEN_MAX_UNSIGNED_INT + _STRLEN_MAX_PID_TID ];
359 sprintf(
360 message,
|
361 kumpf 1.9 "[%d:%u:%s:%u]: ",
|
362 kumpf 1.3 System::getPID(),
|
363 kumpf 1.9 Uint32(pegasus_thread_self()),
|
364 kumpf 1.3 fileName,
365 lineNum);
|
366 mike 1.2 _trace(traceComponent,message,fmt,argList);
367 va_end(argList);
368
369 delete []message;
370 }
371 }
372
373 ////////////////////////////////////////////////////////////////////////////////
374 //Checks if trace is enabled for the given component and level
375 ////////////////////////////////////////////////////////////////////////////////
376 Boolean Tracer::_isTraceEnabled(const Uint32 traceComponent,
377 const Uint32 traceLevel)
378 {
379 Tracer* instance = _getInstance();
380 if (traceComponent >= _NUM_COMPONENTS)
381 {
382 return false;
383 }
384 return ((instance->_traceComponentMask[traceComponent]) &&
385 (traceLevel & instance->_traceLevelMask));
386 }
387 mike 1.2
388 ////////////////////////////////////////////////////////////////////////////////
389 //Called by all trace interfaces to log message to trace file
390 ////////////////////////////////////////////////////////////////////////////////
391 void Tracer::_trace(
392 const Uint32 traceComponent,
393 const char* message,
394 const char* fmt,
395 va_list argList)
396 {
397 char* msgHeader;
398
399 // Get the current system time and prepend to message
400 String currentTime = System::getCurrentASCIITime();
|
401 kumpf 1.17 CString timeStamp = currentTime.getCString();
|
402 mike 1.2
|
403 kumpf 1.3 //
|
404 mike 1.2 // Allocate messageHeader.
|
405 kumpf 1.3 // Needs to be updated if additional info is added
406 //
|
407 mike 1.2 msgHeader = new char [strlen(message)
408 + strlen(TRACE_COMPONENT_LIST[traceComponent])
|
409 kumpf 1.17 + strlen(timeStamp) + _STRLEN_MAX_PID_TID];
|
410 mike 1.2
411 // Construct the message header
412 // The message header is in the following format
413 // timestamp: <component name> [file name:line number]
414 if (strcmp(message,"") != 0)
415 {
|
416 kumpf 1.17 sprintf(msgHeader,"%s: %s %s",(const char*)timeStamp,
|
417 mike 1.2 TRACE_COMPONENT_LIST[traceComponent] ,message);
418 }
419 else
420 {
|
421 kumpf 1.3 //
422 // Since the message is blank form a string using the pid and tid
423 //
424 char* tmpBuffer;
425
426 //
427 // Allocate messageHeader.
428 // Needs to be updated if additional info is added
429 //
430 tmpBuffer = new char[_STRLEN_MAX_PID_TID];
|
431 kumpf 1.9 sprintf(tmpBuffer, "[%u:%u]: ", System::getPID(),
432 Uint32(pegasus_thread_self()));
|
433 kumpf 1.3
|
434 kumpf 1.17 sprintf(msgHeader,"%s: %s %s ",(const char*)timeStamp,
|
435 kumpf 1.3 TRACE_COMPONENT_LIST[traceComponent] ,tmpBuffer );
436 delete []tmpBuffer;
|
437 mike 1.2 }
438
439 // Call trace file handler to write message
440 _getInstance()->_traceHandler->handleMessage(msgHeader,fmt,argList);
441 delete []msgHeader;
442 }
443
444 ////////////////////////////////////////////////////////////////////////////////
445 //Validate the trace file
446 ////////////////////////////////////////////////////////////////////////////////
|
447 kumpf 1.10 Boolean Tracer::isValidFileName(const char* filePath)
|
448 mike 1.2 {
449 return (_getInstance()->_traceHandler->isValidFilePath(filePath));
450 }
451
452 ////////////////////////////////////////////////////////////////////////////////
453 //Validate the trace components
454 ////////////////////////////////////////////////////////////////////////////////
|
455 kumpf 1.10 Boolean Tracer::isValidComponents(const String traceComponents)
456 {
457 String invalidComponents;
458 return isValidComponents(traceComponents, invalidComponents);
459 }
460
461 Boolean Tracer::isValidComponents(
462 const String traceComponents, String& invalidComponents)
|
463 mike 1.2 {
464 // Validate the trace components and modify the traceComponents argument
465 // to reflect the invalid components
466
467 Uint32 position=0;
468 Uint32 index=0;
469 String componentName = String::EMPTY;
470 String componentStr = String::EMPTY;
471 Boolean validComponent=false;
472 Boolean retCode=true;
473
474 componentStr = traceComponents;
475 invalidComponents = String::EMPTY;
476
477 if (componentStr != String::EMPTY)
478 {
479 // Check if ALL is specified
480 if (String::equalNoCase(componentStr,"ALL"))
481 {
482 return _SUCCESS;
483 }
484 mike 1.2
485 // Append _COMPONENT_SEPARATOR to the end of the traceComponents
|
486 kumpf 1.16 componentStr.append(_COMPONENT_SEPARATOR);
|
487 mike 1.2
488 while (componentStr != String::EMPTY)
489 {
490 //
491 // Get the Component name from traceComponents.
492 // Components are separated by _COMPONENT_SEPARATOR
493 //
494 position = componentStr.find(_COMPONENT_SEPARATOR);
495 componentName = componentStr.subString(0,(position));
496
497 // Lookup the index for Component name in TRACE_COMPONENT_LIST
498 index = 0;
499 validComponent = false;
500
501 while (index < _NUM_COMPONENTS)
502 {
503 if (String::equalNoCase(
504 componentName, TRACE_COMPONENT_LIST[index]))
505 {
506 // Found component, break from the loop
507 validComponent = true;
508 mike 1.2 break;
509 }
510 else
511 {
512 index++;
513 }
514 }
515
516 // Remove the searched componentname from the traceComponents
517 componentStr.remove(0,position+1);
518
519 if ( !validComponent )
520 {
|
521 kumpf 1.16 invalidComponents.append(componentName);
522 invalidComponents.append(_COMPONENT_SEPARATOR);
|
523 mike 1.2 }
524 }
525 }
526 else
527 {
528 // trace components is empty, it is a valid value so return true
529 return _SUCCESS;
530 }
531 if ( invalidComponents != String::EMPTY )
532 {
533 retCode = false;
534 //
535 // Remove the extra ',' at the end
536 //
537 invalidComponents.remove(
538 invalidComponents.reverseFind(_COMPONENT_SEPARATOR));
539 }
540 return retCode;
541 }
542
543 ////////////////////////////////////////////////////////////////////////////////
544 mike 1.2 //Returns the Singleton instance of the Tracer
545 ////////////////////////////////////////////////////////////////////////////////
546 Tracer* Tracer::_getInstance()
547 {
548 if (_tracerInstance == 0)
549 {
550 _tracerInstance = new Tracer();
551 }
552 return _tracerInstance;
553 }
554
555 // PEGASUS_REMOVE_TRACE defines the compile time inclusion of the Trace
556 // interfaces. If defined the interfaces map to empty functions
557
558 #ifndef PEGASUS_REMOVE_TRACE
559
560 ////////////////////////////////////////////////////////////////////////////////
561 //Set the trace file
562 ////////////////////////////////////////////////////////////////////////////////
563 Uint32 Tracer::setTraceFile(const char* traceFile)
564 {
565 mike 1.2 return (_getInstance()->_traceHandler->setFileName (traceFile));
566 }
567
568 ////////////////////////////////////////////////////////////////////////////////
569 //Set the trace level
570 ////////////////////////////////////////////////////////////////////////////////
571 Uint32 Tracer::setTraceLevel(const Uint32 traceLevel)
572 {
573 Uint32 retCode = 0;
574
575 switch (traceLevel)
576 {
577 case LEVEL1:
578 _getInstance()->_traceLevelMask = 0x01;
579 break;
580
581 case LEVEL2:
582 _getInstance()->_traceLevelMask = 0x03;
583 break;
584
585 case LEVEL3:
586 mike 1.2 _getInstance()->_traceLevelMask = 0x07;
587 break;
588
589 case LEVEL4:
590 _getInstance()->_traceLevelMask = 0x0F;
591 break;
592
593 default:
594 _getInstance()->_traceLevelMask = 0;
595 retCode = 1;
596 }
597 return retCode;
598 }
599
600 ////////////////////////////////////////////////////////////////////////////////
601 // Set components to be traced.
602 ////////////////////////////////////////////////////////////////////////////////
603 void Tracer::setTraceComponents( const String traceComponents )
604 {
605 Uint32 position = 0;
606 Uint32 index = 0;
607 mike 1.2 String componentName = String::EMPTY;
608 String componentStr = traceComponents;
609 String invalidComponents = String::EMPTY;
610
611 if (componentStr != String::EMPTY)
612 {
613 // Check if ALL is specified
614 if (String::equalNoCase(componentStr,"ALL"))
615 {
616 for (index=0; index < _NUM_COMPONENTS;
617 _getInstance()->_traceComponentMask[index++] = true);
618 return ;
619 }
620
621 // initialise ComponentMask array to False
622 for (index = 0;index < _NUM_COMPONENTS;
623 _getInstance()->_traceComponentMask[index++] = false);
624
625 // Append _COMPONENT_SEPARATOR to the end of the traceComponents
|
626 kumpf 1.16 componentStr.append(_COMPONENT_SEPARATOR);
|
627 mike 1.2
628 while (componentStr != String::EMPTY)
629 {
630 // Get the Component name from traceComponents.
631 // Components are separated by _COMPONENT_SEPARATOR
632 position = componentStr.find(_COMPONENT_SEPARATOR);
633 componentName = componentStr.subString(0,(position));
634
635 // Lookup the index for Component name in TRACE_COMPONENT_LIST
636 index = 0;
637 while (index < _NUM_COMPONENTS)
638 {
639 if (String::equalNoCase(
640 componentName,TRACE_COMPONENT_LIST[index]))
641 {
642 _getInstance()->_traceComponentMask[index]=true;
643
644 // Found component, break from the loop
645 break;
646 }
647 else
648 mike 1.2 {
649 index++;
650 }
651 }
652
653 // Remove the searched componentname from the traceComponents
654 componentStr.remove(0,position+1);
655 }
656 }
657 else
658 {
659 // initialise ComponentMask array to False
660 for (Uint32 index = 0;index < _NUM_COMPONENTS;
661 _getInstance()->_traceComponentMask[index++] = false);
662 }
663 return ;
664 }
665
666 #endif
667
668 PEGASUS_NAMESPACE_END
|