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