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

  1 martin 1.66 //%LICENSE////////////////////////////////////////////////////////////////
  2 martin 1.67 //
  3 martin 1.66 // 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.67 //
 10 martin 1.66 // 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.67 //
 17 martin 1.66 // The above copyright notice and this permission notice shall be included
 18             // in all copies or substantial portions of the Software.
 19 martin 1.67 //
 20 martin 1.66 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 21 martin 1.67 // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 22 martin 1.66 // 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.67 //
 28 martin 1.66 //////////////////////////////////////////////////////////////////////////
 29 mike   1.13 //
 30             //%/////////////////////////////////////////////////////////////////////////////
 31             
 32             #include <iostream>
 33             #include <fstream>
 34 kumpf  1.23 #include <cstring>
 35 mreddy 1.55 #include <Pegasus/Common/Logger.h>
 36 marek  1.59 #include <Pegasus/Common/Tracer.h>
 37 mreddy 1.55 #include <Pegasus/Common/System.h>
 38             #include <Pegasus/Common/FileSystem.h>
 39 kumpf  1.48 #include <Pegasus/Common/MessageLoader.h>
 40 kumpf  1.54 #include <Pegasus/Common/Executor.h>
 41 mreddy 1.55 #include <Pegasus/Common/Mutex.h>
 42 kumpf  1.16 
 43 marek  1.47 #if defined(PEGASUS_USE_SYSLOGS)
 44             # include <syslog.h>
 45             #endif
 46             
 47 mike   1.13 PEGASUS_USING_STD;
 48             
 49             PEGASUS_NAMESPACE_BEGIN
 50             
 51 mreddy 1.55 
 52 mike   1.13 const Uint32 Logger::TRACE = (1 << 0);
 53             const Uint32 Logger::INFORMATION = (1 << 1);
 54             const Uint32 Logger::WARNING = (1 << 2);
 55             const Uint32 Logger::SEVERE = (1 << 3);
 56             const Uint32 Logger::FATAL = (1 << 4);
 57             
 58 david  1.26 static char const* LOGLEVEL_LIST[] =
 59             {
 60                 "TRACE",
 61                 "INFORMATION",
 62                 "WARNING",
 63                 "SEVERE",
 64                 "FATAL"
 65             };
 66             
 67 mike   1.13 LoggerRep* Logger::_rep = 0;
 68             String Logger::_homeDirectory = ".";
 69 kumpf  1.16 
 70 david  1.26 const Uint32 Logger::_NUM_LOGLEVEL = 5;
 71             
 72 kumpf  1.57 Uint32 Logger::_severityMask;
 73 david  1.26 
 74 mreddy 1.65 
 75 kumpf  1.57 ///////////////////////////////////////////////////////////////////////////////
 76             //
 77             // LoggerRep
 78             //
 79             ///////////////////////////////////////////////////////////////////////////////
 80 kumpf  1.16 
 81 kumpf  1.57 #if defined(PEGASUS_USE_SYSLOGS)
 82 mike   1.13 
 83 kumpf  1.57 class LoggerRep
 84             {
 85             public:
 86 david  1.26 
 87 kumpf  1.57     LoggerRep(const String& homeDirectory)
 88 mike   1.13     {
 89 kumpf  1.57 # ifdef PEGASUS_OS_ZOS
 90                     logIdentity = strdup(System::CIMSERVER.getCString());
 91                     // If System Log is used open it
 92                     System::openlog(logIdentity, LOG_PID, LOG_DAEMON);
 93             # endif
 94                 }
 95 mike   1.13 
 96 kumpf  1.57     ~LoggerRep()
 97                 {
 98             # ifdef PEGASUS_OS_ZOS
 99                     System::closelog();
100                     free(logIdentity);
101             # endif
102                 }
103 mike   1.13 
104 kumpf  1.57     // Actual logging is done in this routine
105                 void log(Logger::LogFileType logFileType,
106                     const String& systemId,
107                     Uint32 logLevel,
108                     const String localizedMsg)
109                 {
110                     // Log the message
111                     System::syslog(systemId, logLevel, localizedMsg.getCString());
112                 }
113             
114             private:
115             
116             # ifdef PEGASUS_OS_ZOS
117                 char* logIdentity;
118             # endif
119             };
120             
121             #else    // !defined(PEGASUS_USE_SYSLOGS)
122             
123             static const char* fileNames[] =
124             {
125 kumpf  1.57     "PegasusTrace.log",
126                 "PegasusStandard.log",
127                 "PegasusAudit.log",
128 ouyang.jian 1.60     "PegasusError.log"
129 kumpf       1.57 };
130                  static const char* lockFileName = "PegasusLog.lock";
131                  
132                  /*
133                      _constructFileName builds the absolute file name from homeDirectory
134 mreddy      1.55     and fileName.
135                  */
136                  static CString _constructFileName(
137                      const String& homeDirectory,
138                      const char * fileName)
139                  {
140 mike        1.13     String result;
141 kumpf       1.57     result.reserveCapacity(
142                          (Uint32)(homeDirectory.size() + 1 + strlen(fileName)));
143 kumpf       1.20     result.append(homeDirectory);
144                      result.append('/');
145 mreddy      1.55     result.append(fileName);
146 kumpf       1.22     return result.getCString();
147 mike        1.13 }
148                  
149                  class LoggerRep
150                  {
151                  public:
152                  
153                      LoggerRep(const String& homeDirectory)
154                      {
155 kumpf       1.40         // Add test for home directory set.
156 mike        1.13 
157 kumpf       1.40         // If home directory does not exist, create it.
158                          CString lgDir = homeDirectory.getCString();
159 mike        1.13 
160 kumpf       1.40         if (!System::isDirectory(lgDir))
161                              System::makeDirectory(lgDir);
162 mike        1.13 
163 kumpf       1.40         // KS: I put the second test in just in case some trys to create
164                          // a completly erronous directory.  At least we will get a message
165 kumpf       1.48         if (!System::isDirectory(lgDir))
166                          {
167                              MessageLoaderParms parms("Common.Logger.LOGGING_DISABLED",
168                                  "Logging Disabled");
169 kumpf       1.40 
170 kumpf       1.48             cerr << MessageLoader::getMessage(parms);
171 kumpf       1.40         }
172                  
173 mreddy      1.55        //Filelocks are not used for VMS
174 kumpf       1.57 # if !defined(PEGASUS_OS_VMS)
175 mreddy      1.55         _loggerLockFileName = _constructFileName(homeDirectory, lockFileName);
176                  
177                          // Open and close a file to make sure that the file exists, on which
178                          // file lock is requested
179                          FILE *fileLockFilePointer;
180                          fileLockFilePointer = fopen(_loggerLockFileName, "a+");
181                          if(fileLockFilePointer)
182                          {
183                              fclose(fileLockFilePointer);
184                          }
185 kumpf       1.57 # endif
186 mreddy      1.55 
187                          _logFileNames[Logger::TRACE_LOG] = _constructFileName(homeDirectory,
188                                                                 fileNames[Logger::TRACE_LOG]);
189 kumpf       1.40 
190 mreddy      1.55         _logFileNames[Logger::STANDARD_LOG] = _constructFileName(homeDirectory,
191                                                                 fileNames[Logger::STANDARD_LOG]);
192 kumpf       1.40 
193 kumpf       1.57 # ifdef PEGASUS_ENABLE_AUDIT_LOGGER
194 mreddy      1.55         _logFileNames[Logger::AUDIT_LOG] = _constructFileName(homeDirectory,
195                                                                 fileNames[Logger::AUDIT_LOG]);
196 kumpf       1.57 # endif
197 thilo.boehm 1.46 
198 mreddy      1.55         _logFileNames[Logger::ERROR_LOG] = _constructFileName(homeDirectory,
199                                                                 fileNames[Logger::ERROR_LOG]);
200 marek       1.47     }
201                  
202                      ~LoggerRep()
203                      {
204 mreddy      1.55     }
205                  
206                      // Actual logging is done in this routine
207                      void log(Logger::LogFileType logFileType,
208                          const String& systemId,
209                          Uint32 logLevel,
210                          const String localizedMsg)
211                      {
212                          // Prepend the systemId to the incoming message
213                          String messageString(systemId);
214                          messageString.append(": ");
215                          messageString.append(localizedMsg);  // l10n
216 marek       1.47 
217 mreddy      1.55         // Get the logLevel String
218                          // This converts bitmap to string based on highest order
219                          // bit set
220                          // ATTN: KS Fix this more efficiently.
221                          const char* tmp = "";
222                          if (logLevel & Logger::TRACE) tmp =       "TRACE   ";
223                          if (logLevel & Logger::INFORMATION) tmp = "INFO    ";
224                          if (logLevel & Logger::WARNING) tmp =     "WARNING ";
225                          if (logLevel & Logger::SEVERE) tmp =      "SEVERE  ";
226                          if (logLevel & Logger::FATAL) tmp =       "FATAL   ";
227 mike        1.13 
228 mreddy      1.55 # ifndef PEGASUS_OS_VMS
229 kumpf       1.68         // Acquire AutoMutex (for thread sync)
230 mreddy      1.55         // and AutoFileLock (for Process Sync).
231                          AutoMutex am(_mutex);
232                          AutoFileLock fileLock(_loggerLockFileName);
233                  
234                          Uint32  logFileSize = 0;
235                  
236                          // Read logFileSize to check if the logfile needs to be pruned.
237 kumpf       1.68         FileSystem::getFileSize(String(_logFileNames[logFileType]),
238 mreddy      1.55                                        logFileSize);
239                  
240 mreddy      1.65         // Check if the size of the logfile is exceeding _maxLogFileSizeBytes.
241                          if ( logFileSize > _maxLogFileSizeBytes)
242 kumpf       1.57         {
243 mreddy      1.55             // Prepare appropriate file name based on the logFileType.
244                              // Eg: if Logfile name is PegasusStandard.log, pruned logfile name
245                              // will be PegasusStandard-062607-122302.log,where 062607-122302
246                              // is the time stamp.
247                              String prunedLogfile(_logFileNames[logFileType],
248                                                  (Uint32)strlen(_logFileNames[logFileType]) - 4);
249                              prunedLogfile.append('-');
250                  
251                              // Get timestamp,remove illegal chars in file name'/' and ':'
252                              // (: is illegal Open VMS) from the time stamp. Append the time
253                              // info to the file name.
254 mike        1.13 
255 mreddy      1.55             String timeStamp = System::getCurrentASCIITime();
256                              for (unsigned int i=0; i<=timeStamp.size(); i++)
257                              {
258                                  if(timeStamp[i] == '/' || timeStamp[i] == ':')
259                                  {
260                                      timeStamp.remove(i, 1);
261                                  }
262                              }
263                              prunedLogfile.append(timeStamp);
264 mike        1.13 
265 mreddy      1.55             // Append '.log' to the file
266                              prunedLogfile.append( ".log");
267 mike        1.13 
268 mreddy      1.55             // Rename the logfile
269                              FileSystem::renameFile(String(_logFileNames[logFileType]),
270                                                     prunedLogfile);
271                  
272                          } // Check if the logfile needs to be pruned.
273                  # endif  // ifndef PEGASUS_OS_VMS
274                  
275                          // Open Logfile. Based on the value of logFileType, one of the five
276                          // Logfiles will be opened.
277                          ofstream logFileStream;
278                          logFileStream.open(_logFileNames[logFileType], ios::app);
279                          logFileStream << System::getCurrentASCIITime()
280                             << " " << tmp << (const char *)messageString.getCString() << endl;
281                          logFileStream.close();
282 mike        1.13     }
283                  
284 mreddy      1.65     static void setMaxLogFileSize(Uint32 maxLogFileSizeBytes)
285                      {
286                          _maxLogFileSizeBytes = maxLogFileSizeBytes;
287                      }
288 mike        1.13 private:
289                  
290 mreddy      1.55     CString _logFileNames[int(Logger::NUM_LOGS)];
291 kumpf       1.57 
292 mreddy      1.65     static Uint32 _maxLogFileSizeBytes;
293 kumpf       1.57 # ifndef PEGASUS_OS_VMS
294 mreddy      1.55     CString _loggerLockFileName;
295                      Mutex _mutex;
296 kumpf       1.57 # endif
297 mike        1.13 };
298                  
299 mreddy      1.65 Uint32 LoggerRep::_maxLogFileSizeBytes;
300                  
301 kumpf       1.57 #endif    // !defined(PEGASUS_USE_SYSLOGS)
302                  
303                  
304                  ///////////////////////////////////////////////////////////////////////////////
305                  //
306                  // Logger
307                  //
308                  ///////////////////////////////////////////////////////////////////////////////
309                  
310 david       1.26 void Logger::_putInternal(
311 mike        1.13     LogFileType logFileType,
312                      const String& systemId,
313 kumpf       1.48     const Uint32 logComponent, // FUTURE: Support logComponent mask
314 david       1.26     Uint32 logLevel,
315 kumpf       1.63     const String& message)
316 mike        1.13 {
317 kumpf       1.63     if (!_rep)
318                         _rep = new LoggerRep(_homeDirectory);
319 chuck       1.29 
320 kumpf       1.63     // Call the actual logging routine is in LoggerRep.
321                      _rep->log(logFileType, systemId, logLevel, message);
322 kumpf       1.68 
323 thilo.boehm 1.64     // PEP 315
324                      // The trace can be routed into the log. The logged trace messages are
325 kumpf       1.68     // logged with logFileType of Logger::TRACE_LOG.
326 thilo.boehm 1.64     // To avoid a cirular writing of these messages, log messages with
327                      // logFileType of Logger::TRACE_LOG are never send to the trace.
328 kumpf       1.63     if (Logger::TRACE_LOG != logFileType)
329                      {
330 thilo.boehm 1.64         // For all other logFileType's send the log messages to the trace.
331                          // But do not write log messages to trace when the trace facility is
332                          // set to log. This avoids double messages.
333 kumpf       1.63         if (Tracer::TRACE_FACILITY_LOG != Tracer::getTraceFacility())
334                          {
335                              PEG_TRACE_CSTRING(
336                                  TRC_LOGMSG,
337                                  Tracer::LEVEL1,
338                                  (const char*) message.getCString());
339 kumpf       1.40         }
340 david       1.26     }
341                  }
342 mike        1.13 
343 mike        1.42 ////////////////////////////////////////////////////////////////////////////////
344                  //
345                  // Public methods start here:
346                  //
347                  ////////////////////////////////////////////////////////////////////////////////
348                  
349 david       1.26 void Logger::put(
350 kumpf       1.40     LogFileType logFileType,
351                      const String& systemId,
352                      Uint32 logLevel,
353                      const String& formatString,
354                      const Formatter::Arg& arg0,
355                      const Formatter::Arg& arg1,
356                      const Formatter::Arg& arg2,
357                      const Formatter::Arg& arg3,
358                      const Formatter::Arg& arg4,
359                      const Formatter::Arg& arg5,
360                      const Formatter::Arg& arg6,
361                      const Formatter::Arg& arg7,
362                      const Formatter::Arg& arg8,
363                      const Formatter::Arg& arg9)
364 chuck       1.29 {
365 mike        1.42     if (wouldLog(logLevel))
366                      {
367                          Logger::_putInternal(logFileType, systemId, 0, logLevel,
368 kumpf       1.63             Formatter::format(formatString, arg0, arg1, arg2, arg3,
369                                  arg4, arg5, arg6, arg7, arg8, arg9));
370 mike        1.42     }
371 karl        1.37 }
372                  
373                  void Logger::put(
374 kumpf       1.40     LogFileType logFileType,
375                      const String& systemId,
376                      Uint32 logLevel,
377                      const String& formatString)
378 karl        1.37 {
379 mike        1.42     if (wouldLog(logLevel))
380                      {
381 kumpf       1.63         Logger::_putInternal(logFileType, systemId, 0, logLevel, formatString);
382 mike        1.42     }
383                  }
384 karl        1.37 
385 mike        1.42 void Logger::put(
386                      LogFileType logFileType,
387                      const String& systemId,
388                      Uint32 logLevel,
389                      const String& formatString,
390                      const Formatter::Arg& arg0)
391                  {
392                      if (wouldLog(logLevel))
393                      {
394                          Logger::_putInternal(logFileType, systemId, 0, logLevel,
395 kumpf       1.63             Formatter::format(formatString, arg0));
396 mike        1.42     }
397 karl        1.37 }
398                  
399                  void Logger::put(
400 kumpf       1.40     LogFileType logFileType,
401                      const String& systemId,
402                      Uint32 logLevel,
403                      const String& formatString,
404 mike        1.42     const Formatter::Arg& arg0,
405                      const Formatter::Arg& arg1)
406 karl        1.37 {
407 mike        1.42     if (wouldLog(logLevel))
408                      {
409                          Logger::_putInternal(logFileType, systemId, 0, logLevel,
410 kumpf       1.63             Formatter::format(formatString, arg0, arg1));
411 mike        1.42     }
412                  }
413 karl        1.37 
414 mike        1.42 void Logger::put(
415                      LogFileType logFileType,
416                      const String& systemId,
417                      Uint32 logLevel,
418                      const String& formatString,
419                      const Formatter::Arg& arg0,
420                      const Formatter::Arg& arg1,
421                      const Formatter::Arg& arg2)
422                  {
423                      if (wouldLog(logLevel))
424                      {
425                          Logger::_putInternal(logFileType, systemId, 0, logLevel,
426 kumpf       1.63             Formatter::format(formatString, arg0, arg1, arg2));
427 mike        1.42     }
428 chuck       1.29 }
429                  
430                  void Logger::put_l(
431 kumpf       1.40     LogFileType logFileType,
432                      const String& systemId,
433                      Uint32 logLevel,
434 kumpf       1.63     const MessageLoaderParms& msgParms)
435 mike        1.42 {
436                      if (wouldLog(logLevel))
437                      {
438 kumpf       1.63         MessageLoaderParms parms = msgParms;
439                          parms.useProcessLocale = true;
440 mike        1.42         Logger::_putInternal(logFileType, systemId, 0, logLevel,
441 kumpf       1.63             MessageLoader::getMessage(parms));
442 mike        1.42     }
443 david       1.26 }
444                  
445                  void Logger::trace(
446 kumpf       1.40     LogFileType logFileType,
447                      const String& systemId,
448                      const Uint32 logComponent,
449 kumpf       1.62     const String& message)
450 chuck       1.29 {
451 mike        1.42     if (wouldLog(Logger::TRACE))
452                      {
453                          Logger::_putInternal(logFileType, systemId, logComponent, Logger::TRACE,
454 kumpf       1.63             message);
455 mike        1.42     }
456 mike        1.13 }
457                  
458                  void Logger::setHomeDirectory(const String& homeDirectory)
459                  {
460                      _homeDirectory = homeDirectory;
461                  }
462 david       1.26 
463                  void Logger::setlogLevelMask( const String logLevelList )
464                  {
465 karl        1.37     Uint32 logLevelType = 0;
466 david       1.26     String logLevelName      = logLevelList;
467                  
468                      // Check if logLevel has been specified
469                      if (logLevelName != String::EMPTY)
470                      {
471                          // initialise _severityMask
472                          _severityMask = 0;
473                  
474 kumpf       1.40         // Set logLevelType to indicate the level of logging
475 david       1.26         // required by the user.
476 kumpf       1.40         if (String::equalNoCase(logLevelName,"TRACE"))
477                          {
478                              logLevelType =  Logger::TRACE;
479                          }
480                          else if (String::equalNoCase(logLevelName,"INFORMATION"))
481                          {
482                              logLevelType =  Logger::INFORMATION;
483                          }
484                          else if (String::equalNoCase(logLevelName,"WARNING"))
485                          {
486                              logLevelType = Logger::WARNING;
487                          }
488                          else if (String::equalNoCase(logLevelName,"SEVERE"))
489                          {
490                              logLevelType = Logger::SEVERE;
491                          }
492                          else if (String::equalNoCase(logLevelName,"FATAL"))
493                          {
494                              logLevelType = Logger::FATAL;
495                          }
496                          // Setting _severityMask.  NOTE:  When adding new logLevels
497 david       1.26         // it is essential that they are adding in ascending order
498                          // based on priority.  Once a case statement is true we will
499                          // continue to set all following log levels with a higher
500                          // priority.
501 kumpf       1.40         switch(logLevelType)
502                          {
503                              case Logger::TRACE:
504                                    _severityMask |= Logger::TRACE;
505                              case Logger::INFORMATION:
506                                    _severityMask |= Logger::INFORMATION;
507                              case Logger::WARNING:
508                                    _severityMask |= Logger::WARNING;
509                              case Logger::SEVERE:
510                                    _severityMask |= Logger::SEVERE;
511                              case Logger::FATAL:
512                                    _severityMask |= Logger::FATAL;
513                          }
514 kumpf       1.54 
515                          Executor::updateLogLevel(logLevelName.getCString());
516 david       1.26     }
517                      else
518                      {
519 kumpf       1.40         // Property logLevel not specified, set default value.
520                          _severityMask = ~Logger::TRACE;
521 kumpf       1.54         Executor::updateLogLevel("INFORMATION");
522 david       1.26     }
523                  }
524                  
525 mike        1.42 Boolean Logger::isValidlogLevel(const String logLevel)
526 david       1.26 {
527                      // Validate the logLevel and modify the logLevel argument
528                      // to reflect the invalid logLevel
529                  
530                      Uint32    index=0;
531                      String    logLevelName = String::EMPTY;
532                      Boolean   validlogLevel=false;
533                  
534                      logLevelName = logLevel;
535                  
536                      if (logLevelName != String::EMPTY)
537                      {
538 kumpf       1.40         // Lookup the index for logLevel name in _logLevel_LIST
539                          index = 0;
540                          validlogLevel = false;
541                  
542                          while (index < _NUM_LOGLEVEL)
543                          {
544                              if (String::equalNoCase(logLevelName, LOGLEVEL_LIST[index]))
545                              {
546                                  // Found logLevel, break from the loop
547                                  validlogLevel = true;
548                                  break;
549                              }
550                              else
551                              {
552                                  index++;
553                              }
554                          }
555 david       1.26     }
556                      else
557                      {
558 kumpf       1.40         // logLevels is empty, it is a valid value so return true
559 kumpf       1.57         return true;
560 david       1.26     }
561                  
562                      return validlogLevel;
563                  }
564                  
565 mreddy      1.65 #if !defined (PEGASUS_USE_SYSLOGS)
566                  void Logger::setMaxLogFileSize(Uint32 maxLogFileSizeBytes)
567                  {
568                       LoggerRep::setMaxLogFileSize(maxLogFileSizeBytes);
569                  }
570                  #endif
571                  
572 mike        1.13 PEGASUS_NAMESPACE_END

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2