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

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

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2