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