(file) Return to Tracer.cpp CVS log (file) (dir) Up to [Pegasus] / pegasus / src / Pegasus / Common

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

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2