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