1 karl 1.34 //%2006////////////////////////////////////////////////////////////////////////
|
2 mike 1.2 //
|
3 karl 1.24 // 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.21 // IBM Corp.; EMC Corporation, The Open Group.
|
7 karl 1.24 // 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.27 // Copyright (c) 2005 Hewlett-Packard Development Company, L.P.; IBM Corp.;
10 // EMC Corporation; VERITAS Software Corporation; The Open Group.
|
11 karl 1.34 // 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.34 //
|
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 sage 1.4 #include <Pegasus/Common/Config.h>
|
35 thilo.boehm 1.54 #include <Pegasus/Common/Constants.h>
|
36 mike 1.2 #include <Pegasus/Common/Tracer.h>
|
37 r.kieninger 1.49 #include <Pegasus/Common/TraceFileHandler.h>
38 #include <Pegasus/Common/TraceLogHandler.h>
|
39 thilo.boehm 1.52 #include <Pegasus/Common/TraceMemoryHandler.h>
|
40 kumpf 1.3 #include <Pegasus/Common/Thread.h>
41 #include <Pegasus/Common/System.h>
|
42 sushma.fernandes 1.45 #include <Pegasus/Common/HTTPMessage.h>
|
43 thilo.boehm 1.52 #include <Pegasus/Common/StringConversion.h>
|
44 thilo.boehm 1.54 #include <Pegasus/Common/FileSystem.h>
|
45 r.kieninger 1.49
|
46 mike 1.2 PEGASUS_USING_STD;
47
48 PEGASUS_NAMESPACE_BEGIN
49
|
50 kumpf 1.53 /**
51 String constants for naming the various Trace components.
52 These strings will used when turning on tracing for the respective
53 components. The component list must be kept in sync with the
54 TraceComponentId enumeration.
55
|
56 thilo.boehm 1.56 The tracer uses the _traceComponentMask in form of a 64bit field to mask
57 the user configured components.
58 Please ensure that no more than 64 components are specified in the
59 TRACE_COMPONENT_LIST.
60
|
61 kumpf 1.53 The following example shows the usage of trace component names.
62 The setTraceComponents method is used to turn on tracing for the
63 components: Config and Repository. The component names are passed as a
64 comma separated list.
65
66 Tracer::setTraceComponents("Config,Repository");
67 */
68 static char const* TRACE_COMPONENT_LIST[] =
69 {
70 "XmlParser",
71 "XmlWriter",
72 "XmlReader",
73 "XmlIO",
74 "Http",
75 "CimData",
76 "Repository",
77 "Dispatcher",
78 "OsAbstraction",
79 "Config",
80 "IndHandler",
81 "Authentication",
82 kumpf 1.53 "Authorization",
83 "UserManager",
84 "Registration",
85 "Shutdown",
86 "Server",
87 "IndicationService",
88 "IndicationServiceInternal",
89 "MessageQueueService",
90 "ProviderManager",
91 "ObjectResolution",
92 "WQL",
93 "CQL",
94 "Thread",
95 "IPC",
96 "IndicationHandlerService",
97 "CIMExportRequestDispatcher",
98 "SSL",
99 "ControlProvider",
100 "CIMOMHandle",
101 "BinaryMessageHandler",
102 "L10N",
103 kumpf 1.53 "ExportClient",
104 "Listener",
105 "DiscardedData",
106 "ProviderAgent",
107 "IndicationFormatter",
108 "StatisticalData",
109 "CMPIProvider",
110 "IndicationGeneration",
111 "IndicationReceipt",
112 "CMPIProviderInterface",
113 "WsmServer",
114 "LogMessages"
115 };
116
|
117 r.kieninger 1.49
118 // Defines the value values for trace facilities
119 // Keep the TRACE_FACILITY_LIST in sync with the TRACE_FACILITY_INDEX,
120 // so that the index matches the according string in the list.
121 char const* Tracer::TRACE_FACILITY_LIST[] =
122 {
123 "File",
124 "Log",
|
125 thilo.boehm 1.52 "Memory",
|
126 r.kieninger 1.49 0
127 };
128
129
|
130 mike 1.2 // Set the trace levels
131 // These levels will be compared against a trace level mask to determine
|
132 chip 1.20 // if a specific trace level is enabled
|
133 mike 1.2
|
134 marek 1.48 const Uint32 Tracer::LEVEL0 = 0;
|
135 mike 1.2 const Uint32 Tracer::LEVEL1 = (1 << 0);
136 const Uint32 Tracer::LEVEL2 = (1 << 1);
137 const Uint32 Tracer::LEVEL3 = (1 << 2);
138 const Uint32 Tracer::LEVEL4 = (1 << 3);
|
139 marek 1.48 const Uint32 Tracer::LEVEL5 = (1 << 4);
|
140 mike 1.2
141 // Set the Enter and Exit messages
|
142 kumpf 1.13 const char Tracer::_METHOD_ENTER_MSG[] = "Entering method";
143 const char Tracer::_METHOD_EXIT_MSG[] = "Exiting method";
|
144 mike 1.2
145 // Initialize singleton instance of Tracer
146 Tracer* Tracer::_tracerInstance = 0;
|
147 chip 1.20
|
148 mike 1.2 // Set component separator
149 const char Tracer::_COMPONENT_SEPARATOR = ',';
150
151 // Set the number of defined components
|
152 chip 1.20 const Uint32 Tracer::_NUM_COMPONENTS =
|
153 mike 1.2 sizeof(TRACE_COMPONENT_LIST)/sizeof(TRACE_COMPONENT_LIST[0]);
154
155 // Set the line maximum
156 const Uint32 Tracer::_STRLEN_MAX_UNSIGNED_INT = 21;
157
|
158 kumpf 1.3 // Set the max PID and Thread ID Length
|
159 mike 1.39 const Uint32 Tracer::_STRLEN_MAX_PID_TID = 21;
|
160 kumpf 1.3
|
161 r.kieninger 1.30 // Initialize public indicator of trace state
|
162 thilo.boehm 1.56 Boolean Tracer::_traceOn=false;
163 Uint32 Tracer::_traceLevelMask=0;
164 Uint64 Tracer::_traceComponentMask=(Uint64)0;
|
165 r.kieninger 1.30
|
166 mike 1.2 ////////////////////////////////////////////////////////////////////////////////
167 // Tracer constructor
168 // Constructor is private to preclude construction of Tracer objects
169 // Single Instance of Tracer is maintained for each process.
170 ////////////////////////////////////////////////////////////////////////////////
171 Tracer::Tracer()
|
172 thilo.boehm 1.56 : _traceMemoryBufferSize(PEGASUS_TRC_DEFAULT_BUFFER_SIZE_KB),
|
173 r.kieninger 1.49 _traceFacility(TRACE_FACILITY_FILE),
|
174 thilo.boehm 1.54 _runningOOP(false),
|
175 r.kieninger 1.49 _traceHandler(0)
|
176 mike 1.2 {
|
177 thilo.boehm 1.56
178 // The tracer uses a 64bit field to mask the user configured components.
179 // This assert ensures that no more than 64 components are specified in the
180 // TRACE_COMPONENT_LIST.
181 PEGASUS_ASSERT(_NUM_COMPONENTS <= 64);
182
|
183 r.kieninger 1.49 // Instantiate trace handler according to configured facility
|
184 thilo.boehm 1.52 _setTraceHandler(_traceFacility);
|
185 mike 1.2 }
|
186 chip 1.20
|
187 mike 1.2 ////////////////////////////////////////////////////////////////////////////////
188 //Tracer destructor
189 ////////////////////////////////////////////////////////////////////////////////
190 Tracer::~Tracer()
191 {
|
192 thilo.boehm 1.52 delete _traceHandler;
|
193 mike 1.2 delete _tracerInstance;
194 }
195
196
197 ////////////////////////////////////////////////////////////////////////////////
|
198 r.kieninger 1.49 //Factory function for the trace handler instances.
199 ////////////////////////////////////////////////////////////////////////////////
|
200 thilo.boehm 1.52 void Tracer::_setTraceHandler( Uint32 traceFacility )
|
201 r.kieninger 1.49 {
|
202 thilo.boehm 1.52 TraceHandler * oldTrcHandler = _traceHandler;
203
|
204 r.kieninger 1.49 switch(traceFacility)
205 {
206 case TRACE_FACILITY_LOG:
|
207 thilo.boehm 1.52 _traceFacility = TRACE_FACILITY_LOG;
208 _traceHandler = new TraceLogHandler();
209 break;
210
211 case TRACE_FACILITY_MEMORY:
212 _traceFacility = TRACE_FACILITY_MEMORY;
|
213 thilo.boehm 1.54 _traceHandler = new TraceMemoryHandler();
|
214 r.kieninger 1.49 break;
215
216 case TRACE_FACILITY_FILE:
217 default:
|
218 thilo.boehm 1.52 _traceFacility = TRACE_FACILITY_FILE;
219 _traceHandler = new TraceFileHandler();
|
220 r.kieninger 1.49 }
|
221 thilo.boehm 1.54 delete oldTrcHandler;
222 }
223
224 ////////////////////////////////////////////////////////////////////////////////
225 // Validates if a given file path if it is eligible for writing traces.
226 ////////////////////////////////////////////////////////////////////////////////
227 Boolean Tracer::_isValidTraceFile(String fileName)
228 {
229 // Check if the file path is a directory
230 FileSystem::translateSlashes(fileName);
231 if (FileSystem::isDirectory(fileName))
232 {
233 return false;
234 }
235
236 // Check if the file exists and is writable
237 if (FileSystem::exists(fileName))
238 {
239 return FileSystem::canWrite(fileName);
240 }
241
242 thilo.boehm 1.54 // Check if directory is writable
243 Uint32 index = fileName.reverseFind('/');
|
244 r.kieninger 1.49
|
245 thilo.boehm 1.54 if (index != PEG_NOT_FOUND)
246 {
247 String dirName = fileName.subString(0,index);
248
249 if (dirName.size() == 0)
250 {
251 dirName = "/";
252 }
253
254 if (!FileSystem::isDirectory(dirName))
255 {
256 return false;
257 }
258
259 return FileSystem::canWrite(dirName);
260 }
261
262 String currentDir;
263
264 // Check if there is permission to write in the
265 // current working directory
266 thilo.boehm 1.54 FileSystem::getCurrentDirectory(currentDir);
267
268 return FileSystem::canWrite(currentDir);
|
269 r.kieninger 1.49 }
270
271 ////////////////////////////////////////////////////////////////////////////////
|
272 mike 1.2 //Traces the given message - Overloaded for including FileName and Line number
273 ////////////////////////////////////////////////////////////////////////////////
274 void Tracer::_trace(
275 const char* fileName,
276 const Uint32 lineNum,
|
277 kumpf 1.53 const TraceComponentId traceComponent,
|
278 mike 1.2 const char* fmt,
279 va_list argList)
280 {
281 char* message;
|
282 marek 1.42 //
283 // Allocate memory for the message string
284 // Needs to be updated if additional info is added
285 //
286 message = new char[strlen(fileName) +
287 _STRLEN_MAX_UNSIGNED_INT + (_STRLEN_MAX_PID_TID * 2) + 8];
288 sprintf(
289 message,
|
290 kumpf 1.51 "[%u:%s:%s:%u]: ",
|
291 marek 1.42 System::getPID(),
292 Threads::id().buffer,
293 fileName,
294 lineNum);
|
295 mike 1.2
|
296 marek 1.42 _trace(traceComponent, message, fmt, argList);
297 delete [] message;
|
298 mike 1.2 }
299
300 ////////////////////////////////////////////////////////////////////////////////
|
301 kumpf 1.5 //Traces the message in the given CIMException object.
302 ////////////////////////////////////////////////////////////////////////////////
303 void Tracer::_traceCIMException(
|
304 kumpf 1.53 const TraceComponentId traceComponent,
|
305 kumpf 1.40 const CIMException& cimException)
|
306 thilo.boehm 1.56 {
|
307 kumpf 1.43 // get the CIMException trace message string
308 CString traceMsg =
309 TraceableCIMException(cimException).getTraceDescription().getCString();
310 // trace the string
311 _traceCString(traceComponent, "", (const char*) traceMsg);
|
312 mike 1.2 }
313
|
314 sushma.fernandes 1.45 SharedArrayPtr<char> Tracer::getHTTPRequestMessage(
315 const Buffer& requestMessage)
316 {
317 const Uint32 requestSize = requestMessage.size();
318
319 // Make a copy of the request message.
320 SharedArrayPtr<char>
321 requestBuf(new char [requestSize + 1]);
322 strncpy(requestBuf.get(), requestMessage.getData(), requestSize);
323 requestBuf.get()[requestSize] = 0;
324
325 //
326 // Check if requestBuffer contains a Basic authorization header.
327 // If true, suppress the user/passwd info in the request buffer.
328 //
329 char* sep;
330 const char* line = requestBuf.get();
331
332 while ((sep = HTTPMessage::findSeparator(
333 line, (Uint32)(requestSize - (line - requestBuf.get())))) &&
334 (line != sep))
335 sushma.fernandes 1.45 {
336 if (HTTPMessage::expectHeaderToken(line, "Authorization") &&
337 HTTPMessage::expectHeaderToken(line, ":") &&
338 HTTPMessage::expectHeaderToken(line, "Basic"))
339 {
340 // Suppress the user/passwd info
341 HTTPMessage::skipHeaderWhitespace(line);
|
342 thilo.boehm 1.56 for ( char* userpass = (char*)line ;
343 userpass < sep;
|
344 sushma.fernandes 1.45 *userpass = 'X', userpass++);
345
346 break;
347 }
348
349 line = sep + ((*sep == '\r') ? 2 : 1);
350 }
351
352 return requestBuf;
353 }
354
|
355 mike 1.2 ////////////////////////////////////////////////////////////////////////////////
|
356 marek 1.42 //Traces method entry and exit
|
357 mike 1.2 ////////////////////////////////////////////////////////////////////////////////
|
358 marek 1.42 void Tracer::_traceMethod(
|
359 mike 1.2 const char* fileName,
360 const Uint32 lineNum,
|
361 kumpf 1.53 const TraceComponentId traceComponent,
|
362 marek 1.42 const char* methodEntryExit,
363 const char* method)
|
364 mike 1.2 {
365 char* message;
366
|
367 marek 1.42 //
368 // Allocate memory for the message string
369 // Needs to be updated if additional info is added
370 //
371 // assume Method entry/exit string 15 characters long
372 // +1 space character
373 message = new char[ strlen(fileName) +
|
374 thilo.boehm 1.56 _STRLEN_MAX_UNSIGNED_INT + (_STRLEN_MAX_PID_TID * 2) + 8
|
375 marek 1.42 + 16];
376
377 sprintf(
378 message,
|
379 kumpf 1.51 "[%u:%s:%s:%u]: %s ",
|
380 marek 1.42 System::getPID(),
381 Threads::id().buffer,
382 fileName,
383 lineNum,
384 methodEntryExit);
385
386 _traceCString(traceComponent, message, method);
|
387 carson.hovey 1.37
|
388 marek 1.42 delete [] message;
|
389 mike 1.2 }
390
391 ////////////////////////////////////////////////////////////////////////////////
|
392 marek 1.42 //Called by all trace interfaces with variable arguments
393 //to log message to trace file
|
394 mike 1.2 ////////////////////////////////////////////////////////////////////////////////
395 void Tracer::_trace(
|
396 kumpf 1.53 const TraceComponentId traceComponent,
|
397 mike 1.2 const char* message,
398 const char* fmt,
399 va_list argList)
400 {
401 char* msgHeader;
|
402 thilo.boehm 1.52 Uint32 msgLen;
403 Uint32 usec,sec;
|
404 mike 1.2
405 // Get the current system time and prepend to message
|
406 thilo.boehm 1.52 System::getCurrentTimeUsec(sec,usec);
|
407 mike 1.2
|
408 kumpf 1.3 //
|
409 chip 1.20 // Allocate messageHeader.
|
410 kumpf 1.3 // Needs to be updated if additional info is added
411 //
|
412 mday 1.19
|
413 mike 1.2 // Construct the message header
|
414 chip 1.20 // The message header is in the following format
|
415 mike 1.2 // timestamp: <component name> [file name:line number]
|
416 thilo.boehm 1.52 //
417 // Format string length calculation:
418 // 11(sec)+ 2('s-')+11(usec)+4('us: ')+1(' ')+1(\0) = 30
|
419 joyce.j 1.26 if (*message != '\0')
|
420 mike 1.2 {
|
421 kumpf 1.40 msgHeader = new char [strlen(message) +
|
422 thilo.boehm 1.52 strlen(TRACE_COMPONENT_LIST[traceComponent]) + 30];
|
423 kumpf 1.40
|
424 thilo.boehm 1.52 msgLen = sprintf(msgHeader, "%us-%uus: %s %s", sec, usec,
|
425 kumpf 1.40 TRACE_COMPONENT_LIST[traceComponent], message);
|
426 mike 1.2 }
427 else
428 {
|
429 kumpf 1.3 //
|
430 chip 1.20 // Allocate messageHeader.
|
431 kumpf 1.3 // Needs to be updated if additional info is added
432 //
|
433 thilo.boehm 1.56 // Format string length calculation:
|
434 thilo.boehm 1.52 // 11(sec)+2('s-')+11(usec)+4('us: ')+
435 // +2(' [')+1(':')+3(']: ')+1(\0) = 35
|
436 thilo.boehm 1.56 msgHeader = new char[2 * _STRLEN_MAX_PID_TID +
|
437 thilo.boehm 1.52 strlen(TRACE_COMPONENT_LIST[traceComponent]) + 35];
438
439 msgLen = sprintf(msgHeader, "%us-%uus: %s [%u:%s]: ", sec, usec,
440 TRACE_COMPONENT_LIST[traceComponent],
|
441 kumpf 1.40 System::getPID(), Threads::id().buffer);
|
442 mike 1.2 }
443
444 // Call trace file handler to write message
|
445 thilo.boehm 1.52 _getInstance()->_traceHandler->handleMessage(msgHeader,msgLen,fmt,argList);
|
446 chip 1.20
447 delete [] msgHeader;
|
448 mike 1.2 }
449
450 ////////////////////////////////////////////////////////////////////////////////
|
451 marek 1.42 //Called by all trace interfaces using a character string without format string
452 //to log message to trace file
453 ////////////////////////////////////////////////////////////////////////////////
454 void Tracer::_traceCString(
|
455 kumpf 1.53 const TraceComponentId traceComponent,
|
456 marek 1.42 const char* message,
457 const char* cstring)
458 {
459 char* completeMessage;
|
460 thilo.boehm 1.52 Uint32 msgLen;
461 Uint32 usec,sec;
|
462 marek 1.42
463 // Get the current system time and prepend to message
|
464 thilo.boehm 1.52 System::getCurrentTimeUsec(sec,usec);
465
|
466 marek 1.42 //
467 // Allocate completeMessage.
468 // Needs to be updated if additional info is added
469 //
470
471 // Construct the message header
472 // The message header is in the following format
473 // timestamp: <component name> [file name:line number]
|
474 thilo.boehm 1.52 //
|
475 thilo.boehm 1.56 // Format string length calculation:
|
476 thilo.boehm 1.52 // 11(sec)+ 2('s-')+11(usec)+4('us: ')+1(' ')+1(\0) = 30
|
477 marek 1.42 if (*message != '\0')
478 {
479 completeMessage = new char [strlen(message) +
480 strlen(TRACE_COMPONENT_LIST[traceComponent]) +
|
481 thilo.boehm 1.52 strlen(cstring) + 30];
|
482 marek 1.42
|
483 thilo.boehm 1.52 msgLen = sprintf(completeMessage, "%us-%uus: %s %s%s", sec, usec,
|
484 marek 1.42 TRACE_COMPONENT_LIST[traceComponent], message, cstring);
485 }
486 else
487 {
488 //
489 // Since the message is blank, form a string using the pid and tid
490 //
491 char* tmpBuffer;
492
493 //
494 // Allocate messageHeader.
495 // Needs to be updated if additional info is added
496 //
|
497 thilo.boehm 1.52 // Format string length calculation:
498 // 11(sec)+2('s-')+11(usec)+4('us: ')+
499 // +2(' [')+1(':')+3(']: ')+1(\0) = 35
500 completeMessage = new char[2 * _STRLEN_MAX_PID_TID +
|
501 marek 1.42 strlen(TRACE_COMPONENT_LIST[traceComponent]) +
|
502 thilo.boehm 1.52 strlen(cstring) +35];
|
503 marek 1.42
|
504 thilo.boehm 1.52 msgLen = sprintf(completeMessage, "%us-%uus: %s [%u:%s] %s", sec, usec,
|
505 thilo.boehm 1.56 TRACE_COMPONENT_LIST[traceComponent],
506 System::getPID(), Threads::id().buffer,
|
507 thilo.boehm 1.52 cstring);
|
508 marek 1.42 }
509
510 // Call trace file handler to write message
|
511 thilo.boehm 1.52 _getInstance()->_traceHandler->handleMessage(completeMessage,msgLen);
|
512 marek 1.42
513 delete [] completeMessage;
514 }
515
516
517 ////////////////////////////////////////////////////////////////////////////////
|
518 mike 1.2 //Validate the trace file
519 ////////////////////////////////////////////////////////////////////////////////
|
520 kumpf 1.10 Boolean Tracer::isValidFileName(const char* filePath)
|
521 mike 1.2 {
|
522 thilo.boehm 1.54 Tracer* instance = _getInstance();
523 String testTraceFile(filePath);
524
525 if (instance->_runningOOP)
|
526 kumpf 1.23 {
|
527 thilo.boehm 1.54 testTraceFile.append(".");
528 testTraceFile.append(instance->_oopTraceFileExtension);
|
529 kumpf 1.23 }
|
530 thilo.boehm 1.54
531 return _isValidTraceFile(testTraceFile);
|
532 mike 1.2 }
533
534 ////////////////////////////////////////////////////////////////////////////////
535 //Validate the trace components
536 ////////////////////////////////////////////////////////////////////////////////
|
537 kumpf 1.23 Boolean Tracer::isValidComponents(const String& traceComponents)
|
538 kumpf 1.10 {
539 String invalidComponents;
540 return isValidComponents(traceComponents, invalidComponents);
541 }
542
543 Boolean Tracer::isValidComponents(
|
544 kumpf 1.40 const String& traceComponents,
545 String& invalidComponents)
|
546 mike 1.2 {
547 // Validate the trace components and modify the traceComponents argument
548 // to reflect the invalid components
549
550 Uint32 position=0;
551 Uint32 index=0;
|
552 kumpf 1.44 String componentName;
553 String componentStr;
|
554 mike 1.2 Boolean validComponent=false;
555 Boolean retCode=true;
556
557 componentStr = traceComponents;
558 invalidComponents = String::EMPTY;
559
560 if (componentStr != String::EMPTY)
561 {
562 // Check if ALL is specified
563 if (String::equalNoCase(componentStr,"ALL"))
564 {
|
565 marek 1.48 return true;
|
566 mike 1.2 }
567
568 // Append _COMPONENT_SEPARATOR to the end of the traceComponents
|
569 kumpf 1.16 componentStr.append(_COMPONENT_SEPARATOR);
|
570 mike 1.2
571 while (componentStr != String::EMPTY)
572 {
|
573 david.dillard 1.32 //
|
574 mike 1.2 // Get the Component name from traceComponents.
575 // Components are separated by _COMPONENT_SEPARATOR
|
576 david.dillard 1.32 //
|
577 mike 1.2 position = componentStr.find(_COMPONENT_SEPARATOR);
578 componentName = componentStr.subString(0,(position));
579
580 // Lookup the index for Component name in TRACE_COMPONENT_LIST
581 index = 0;
582 validComponent = false;
583
584 while (index < _NUM_COMPONENTS)
585 {
|
586 chip 1.20 if (String::equalNoCase(
|
587 david.dillard 1.32 componentName, TRACE_COMPONENT_LIST[index]))
|
588 mike 1.2 {
589 // Found component, break from the loop
|
590 david.dillard 1.32 validComponent = true;
|
591 mike 1.2 break;
592 }
593 else
594 {
595 index++;
596 }
597 }
598
599 // Remove the searched componentname from the traceComponents
600 componentStr.remove(0,position+1);
601
|
602 kumpf 1.40 if (!validComponent)
|
603 david.dillard 1.32 {
604 invalidComponents.append(componentName);
605 invalidComponents.append(_COMPONENT_SEPARATOR);
|
606 mike 1.2 }
607 }
608 }
609 else
610 {
|
611 david.dillard 1.32 // trace components is empty, it is a valid value so return true
|
612 marek 1.48 return true;
|
613 mike 1.2 }
|
614 kumpf 1.40
615 if (invalidComponents != String::EMPTY)
|
616 mike 1.2 {
|
617 david.dillard 1.32 retCode = false;
618 //
619 // Remove the extra ',' at the end
620 //
621 invalidComponents.remove(
622 invalidComponents.reverseFind(_COMPONENT_SEPARATOR));
|
623 mike 1.2 }
624 return retCode;
625 }
|
626 chip 1.20
|
627 mike 1.2 ////////////////////////////////////////////////////////////////////////////////
|
628 r.kieninger 1.49 //Validate the trace facility
629 ////////////////////////////////////////////////////////////////////////////////
630 Boolean Tracer::isValidTraceFacility(const String& traceFacility)
631 {
632 Boolean retCode = false;
633
634 if (traceFacility.size() != 0)
635 {
636 Uint32 index = 0;
637 while (TRACE_FACILITY_LIST[index] != 0 )
638 {
|
639 thilo.boehm 1.52 if (String::equalNoCase(traceFacility,TRACE_FACILITY_LIST[index]))
|
640 r.kieninger 1.49 {
641 retCode = true;
642 break;
643 }
644 index++;
645 }
646 }
647
648 return retCode;
649 }
650
651 ////////////////////////////////////////////////////////////////////////////////
|
652 thilo.boehm 1.54 // Notify the trare running out of process and provide the trace file extension
653 // for the out of process trace file.
|
654 kumpf 1.23 ////////////////////////////////////////////////////////////////////////////////
|
655 thilo.boehm 1.54 void Tracer::setOOPTraceFileExtension(const String& oopTraceFileExtension)
|
656 kumpf 1.23 {
|
657 thilo.boehm 1.54 Tracer* instance = _getInstance();
658 instance->_oopTraceFileExtension = oopTraceFileExtension;
659 instance->_runningOOP=true;
660 instance->_traceMemoryBufferSize /= PEGASUS_TRC_BUFFER_OOP_SIZE_DEVISOR;
661
|
662 kumpf 1.23 }
663
664 ////////////////////////////////////////////////////////////////////////////////
|
665 mike 1.2 //Returns the Singleton instance of the Tracer
666 ////////////////////////////////////////////////////////////////////////////////
667 Tracer* Tracer::_getInstance()
668 {
669 if (_tracerInstance == 0)
670 {
671 _tracerInstance = new Tracer();
672 }
673 return _tracerInstance;
674 }
675
|
676 chip 1.20 // PEGASUS_REMOVE_TRACE defines the compile time inclusion of the Trace
|
677 karl 1.35 // interfaces. This section defines the trace functions IF the remove
678 // trace flag is NOT set. If it is set, they are defined as empty functions
679 // in the header file.
|
680 mike 1.2
681 #ifndef PEGASUS_REMOVE_TRACE
682
683 ////////////////////////////////////////////////////////////////////////////////
684 //Set the trace file
685 ////////////////////////////////////////////////////////////////////////////////
686 Uint32 Tracer::setTraceFile(const char* traceFile)
687 {
|
688 kumpf 1.25 if (*traceFile == 0)
689 {
690 return 1;
691 }
692
|
693 thilo.boehm 1.54 Tracer* instance = _getInstance();
694 String newTraceFile(traceFile);
695
696 if (instance->_runningOOP)
697 {
698 newTraceFile.append(".");
699 newTraceFile.append(instance->_oopTraceFileExtension);
700 }
701
702 if (_isValidTraceFile(newTraceFile))
|
703 kumpf 1.23 {
|
704 thilo.boehm 1.54 instance->_traceFile = newTraceFile;
705 instance->_traceHandler->configurationUpdated();
|
706 kumpf 1.23 }
707 else
708 {
|
709 thilo.boehm 1.55 return 1;
|
710 kumpf 1.23 }
|
711 thilo.boehm 1.54
712
|
713 thilo.boehm 1.55 return 0;
|
714 thilo.boehm 1.54
|
715 chip 1.20 }
|
716 mike 1.2
717 ////////////////////////////////////////////////////////////////////////////////
718 //Set the trace level
719 ////////////////////////////////////////////////////////////////////////////////
720 Uint32 Tracer::setTraceLevel(const Uint32 traceLevel)
721 {
722 Uint32 retCode = 0;
723
724 switch (traceLevel)
725 {
|
726 marek 1.48 case LEVEL0:
|
727 thilo.boehm 1.56 _traceLevelMask = 0x00;
|
728 marek 1.48 break;
729
|
730 david.dillard 1.32 case LEVEL1:
|
731 thilo.boehm 1.56 _traceLevelMask = 0x01;
|
732 david.dillard 1.32 break;
|
733 chip 1.20
|
734 mike 1.2 case LEVEL2:
|
735 thilo.boehm 1.56 _traceLevelMask = 0x03;
|
736 david.dillard 1.32 break;
|
737 mike 1.2
738 case LEVEL3:
|
739 thilo.boehm 1.56 _traceLevelMask = 0x07;
|
740 david.dillard 1.32 break;
|
741 mike 1.2
742 case LEVEL4:
|
743 thilo.boehm 1.56 _traceLevelMask = 0x0F;
|
744 david.dillard 1.32 break;
|
745 mike 1.2
|
746 marek 1.48 case LEVEL5:
|
747 thilo.boehm 1.56 _traceLevelMask = 0x1F;
|
748 marek 1.48 break;
749
|
750 mike 1.2 default:
|
751 thilo.boehm 1.56 _traceLevelMask = 0x00;
|
752 mike 1.2 retCode = 1;
753 }
|
754 marek 1.48
|
755 thilo.boehm 1.56 // If one of the components was set for tracing and the traceLevel
756 // is not zero, then turn on tracing.
757 _traceOn=((_traceComponentMask!=(Uint64)0)&&(_traceLevelMask!=LEVEL0));
|
758 marek 1.48
|
759 mike 1.2 return retCode;
760 }
761
762 ////////////////////////////////////////////////////////////////////////////////
|
763 chip 1.20 // Set components to be traced.
|
764 mike 1.2 ////////////////////////////////////////////////////////////////////////////////
|
765 kumpf 1.23 void Tracer::setTraceComponents(const String& traceComponents)
|
766 mike 1.2 {
|
767 marek 1.48 // Check if ALL is specified
768 if (String::equalNoCase(traceComponents,"ALL"))
|
769 mike 1.2 {
|
770 thilo.boehm 1.56 // initialize ComponentMask bit array to true
771 _traceComponentMask = (Uint64)-1;
772
|
773 marek 1.48 // If tracing isn't turned off by a traceLevel of zero, let's
774 // turn on the flag that activates tracing.
|
775 thilo.boehm 1.56 _traceOn = (_traceLevelMask != LEVEL0);
|
776 marek 1.48
777 return;
778 }
779
|
780 thilo.boehm 1.56 // initialize ComponentMask bit array to false
781 _traceComponentMask = (Uint64)0;
|
782 marek 1.48 _traceOn = false;
|
783 thilo.boehm 1.56
|
784 marek 1.48 if (traceComponents != String::EMPTY)
785 {
786 Uint32 index = 0;
787 Uint32 position = 0;
788 String componentName;
789 String componentStr = traceComponents;
|
790 mike 1.2
|
791 marek 1.48
|
792 r.kieninger 1.30 // Append _COMPONENT_SEPARATOR to the end of the traceComponents
|
793 kumpf 1.16 componentStr.append(_COMPONENT_SEPARATOR);
|
794 mike 1.2
795 while (componentStr != String::EMPTY)
796 {
|
797 chip 1.20 // Get the Component name from traceComponents.
|
798 r.kieninger 1.30 // Components are separated by _COMPONENT_SEPARATOR
|
799 mike 1.2 position = componentStr.find(_COMPONENT_SEPARATOR);
|
800 r.kieninger 1.30 componentName = componentStr.subString(0,(position));
|
801 mike 1.2
|
802 r.kieninger 1.30 // Lookup the index for Component name in TRACE_COMPONENT_LIST
|
803 mike 1.2 index = 0;
|
804 r.kieninger 1.30 while (index < _NUM_COMPONENTS)
805 {
806 if (String::equalNoCase(
807 componentName,TRACE_COMPONENT_LIST[index]))
808 {
|
809 thilo.boehm 1.56 _traceComponentMask=_traceComponentMask|((Uint64)1<<index);
|
810 mike 1.2 // Found component, break from the loop
811 break;
|
812 r.kieninger 1.30 }
813 else
814 {
815 index++;
|
816 mike 1.2 }
|
817 chip 1.20 }
|
818 mike 1.2 // Remove the searched componentname from the traceComponents
819 componentStr.remove(0,position+1);
820 }
|
821 marek 1.48 // If one of the components was set for tracing and the traceLevel
822 // is not zero, then turn on tracing.
|
823 thilo.boehm 1.56 _traceOn=((_traceComponentMask!=(Uint64)0)&&(_traceLevelMask!=LEVEL0));
|
824 mike 1.2 }
|
825 marek 1.48
|
826 mike 1.2 return ;
827 }
828
|
829 r.kieninger 1.49 ////////////////////////////////////////////////////////////////////////////////
830 // Set the trace facility to be used
831 ////////////////////////////////////////////////////////////////////////////////
832 Uint32 Tracer::setTraceFacility(const String& traceFacility)
833 {
834 Uint32 retCode = 0;
835 Tracer* instance = _getInstance();
|
836 thilo.boehm 1.54
|
837 r.kieninger 1.49 if (traceFacility.size() != 0)
838 {
839 Uint32 index = 0;
840 while (TRACE_FACILITY_LIST[index] != 0 )
841 {
842 if (String::equalNoCase( traceFacility,TRACE_FACILITY_LIST[index]))
843 {
844 if (index != instance->_traceFacility)
845 {
|
846 thilo.boehm 1.52 instance->_setTraceHandler(index);
|
847 r.kieninger 1.49 }
848 retCode = 1;
849 break;
850 }
851 index++;
852 }
853 }
854
855 return retCode;
856 }
857
|
858 marek 1.50 ////////////////////////////////////////////////////////////////////////////////
859 // Get the trace facility in use
860 ////////////////////////////////////////////////////////////////////////////////
861 Uint32 Tracer::getTraceFacility()
862 {
863 return _getInstance()->_traceFacility;
864 }
|
865 r.kieninger 1.49
|
866 thilo.boehm 1.52 ////////////////////////////////////////////////////////////////////////////////
867 // Set the size of the memory trace buffer
868 ////////////////////////////////////////////////////////////////////////////////
869 Boolean Tracer::setTraceMemoryBufferSize(Uint32 bufferSize)
870 {
871 Tracer* instance = _getInstance();
|
872 thilo.boehm 1.54 if (instance->_runningOOP)
873 {
874 // in OOP we reduce the trace memory buffer by factor
875 // PEGASUS_TRC_BUFFER_OOP_SIZE_DEVISOR
876 instance->_traceMemoryBufferSize =
877 bufferSize / PEGASUS_TRC_BUFFER_OOP_SIZE_DEVISOR;
878 }
879 else
880 {
881 instance->_traceMemoryBufferSize = bufferSize;
882 }
883
|
884 thilo.boehm 1.52 // If we decide to dynamically change the trace buffer size,
885 // this is where it needs to be implemented.
886 return true;
887 }
888
889 ////////////////////////////////////////////////////////////////////////////////
890 // Flushes the trace buffer to traceFilePath. This method will only
891 // have an effect when traceFacility=Memory.
892 ////////////////////////////////////////////////////////////////////////////////
893 void Tracer::flushTrace()
894 {
895 _getInstance()->_traceHandler->flushTrace();
896 return;
897 }
898
899
|
900 kumpf 1.40 void Tracer::traceEnter(
901 TracerToken& token,
|
902 karl 1.35 const char* file,
903 size_t line,
|
904 kumpf 1.53 TraceComponentId traceComponent,
|
905 karl 1.35 const char* method)
906 {
|
907 marek 1.42 token.component = traceComponent;
908 token.method = method;
909
|
910 marek 1.48 if (isTraceEnabled(traceComponent, LEVEL5))
|
911 karl 1.35 {
|
912 marek 1.42 _traceMethod(
913 file, (Uint32)line, traceComponent,
|
914 a.dunfey 1.41 _METHOD_ENTER_MSG, method);
|
915 karl 1.35 }
916 }
917
918 void Tracer::traceExit(
919 TracerToken& token,
920 const char* file,
921 size_t line)
922 {
|
923 marek 1.48 if (isTraceEnabled(token.component, LEVEL5) && token.method)
|
924 marek 1.42 _traceMethod(
925 file, (Uint32)line, token.component,
|
926 kumpf 1.40 _METHOD_EXIT_MSG, token.method);
|
927 karl 1.35 }
928
|
929 marek 1.46 ////////////////////////////////////////////////////////////////////////////////
930 //Traces the given string - Overloaded to include the fileName and line number
931 //of trace origin.
932 ////////////////////////////////////////////////////////////////////////////////
933 void Tracer::traceCString(
|
934 karl 1.35 const char* fileName,
935 const Uint32 lineNum,
|
936 kumpf 1.53 const TraceComponentId traceComponent,
|
937 marek 1.46 const char* cstring)
|
938 karl 1.35 {
|
939 marek 1.46 char* message;
|
940 karl 1.35
|
941 thilo.boehm 1.52 Uint32 msgLen;
942 Uint32 usec,sec;
943
944 // Get the current system time
945 System::getCurrentTimeUsec(sec,usec);
946
|
947 marek 1.46 //
948 // Allocate memory for the message string
949 // Needs to be updated if additional info is added
950 //
|
951 thilo.boehm 1.52 message = new char [strlen(fileName) +
952 _STRLEN_MAX_UNSIGNED_INT + (_STRLEN_MAX_PID_TID * 2) + 8 +
|
953 thilo.boehm 1.56 strlen(TRACE_COMPONENT_LIST[traceComponent]) +
|
954 thilo.boehm 1.52 strlen(cstring) + 30];
955
956 msgLen = sprintf(message, "%us-%uus: %s [%u:%s:%s:%u]: %s",
957 sec,
958 usec,
|
959 thilo.boehm 1.56 TRACE_COMPONENT_LIST[traceComponent],
|
960 r.kieninger 1.49 System::getPID(),
961 Threads::id().buffer,
962 fileName,
|
963 thilo.boehm 1.52 lineNum,
964 cstring);
965
966 // Call trace file handler to write message
967 _getInstance()->_traceHandler->handleMessage(message,msgLen);
|
968 karl 1.35
|
969 marek 1.46 delete [] message;
|
970 karl 1.35 }
971
|
972 marek 1.42 void Tracer::traceCIMException(
|
973 kumpf 1.53 const TraceComponentId traceComponent,
|
974 marek 1.42 const Uint32 traceLevel,
975 const CIMException& cimException)
|
976 karl 1.35 {
|
977 marek 1.46 if (isTraceEnabled(traceComponent, traceLevel))
|
978 marek 1.42 {
979 _traceCIMException(traceComponent, cimException);
980 }
|
981 karl 1.35 }
982
983 #endif /* !PEGASUS_REMOVE_TRACE */
|
984 mike 1.2
985 PEGASUS_NAMESPACE_END
|