(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 marek  1.70     LoggerRep(const String&)
 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 marek  1.70     void log(Logger::LogFileType,
106 kumpf  1.57         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                 "PegasusTrace.log",
126                 "PegasusStandard.log",
127 kumpf  1.57     "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 dl.meetei   1.71         const String &localizedMsg)
211 mreddy      1.55     {
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 ajay.rao    1.69             for ( unsigned int i = 0; i < timeStamp.size(); i++ )
257 mreddy      1.55             {
258 ajay.rao    1.69                 if( timeStamp[i] == '/' || timeStamp[i] == ':')
259 mreddy      1.55                 {
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 david       1.26     Uint32 logLevel,
314 kumpf       1.63     const String& message)
315 mike        1.13 {
316 kumpf       1.63     if (!_rep)
317                         _rep = new LoggerRep(_homeDirectory);
318 chuck       1.29 
319 kumpf       1.63     // Call the actual logging routine is in LoggerRep.
320                      _rep->log(logFileType, systemId, logLevel, message);
321 kumpf       1.68 
322 thilo.boehm 1.64     // PEP 315
323                      // The trace can be routed into the log. The logged trace messages are
324 kumpf       1.68     // logged with logFileType of Logger::TRACE_LOG.
325 thilo.boehm 1.64     // To avoid a cirular writing of these messages, log messages with
326                      // logFileType of Logger::TRACE_LOG are never send to the trace.
327 kumpf       1.63     if (Logger::TRACE_LOG != logFileType)
328                      {
329 thilo.boehm 1.64         // For all other logFileType's send the log messages to the trace.
330                          // But do not write log messages to trace when the trace facility is
331                          // set to log. This avoids double messages.
332 kumpf       1.63         if (Tracer::TRACE_FACILITY_LOG != Tracer::getTraceFacility())
333                          {
334                              PEG_TRACE_CSTRING(
335                                  TRC_LOGMSG,
336                                  Tracer::LEVEL1,
337                                  (const char*) message.getCString());
338 kumpf       1.40         }
339 david       1.26     }
340                  }
341 mike        1.13 
342 mike        1.42 ////////////////////////////////////////////////////////////////////////////////
343                  //
344                  // Public methods start here:
345                  //
346                  ////////////////////////////////////////////////////////////////////////////////
347                  
348 david       1.26 void Logger::put(
349 kumpf       1.40     LogFileType logFileType,
350                      const String& systemId,
351                      Uint32 logLevel,
352                      const String& formatString,
353                      const Formatter::Arg& arg0,
354                      const Formatter::Arg& arg1,
355                      const Formatter::Arg& arg2,
356                      const Formatter::Arg& arg3,
357                      const Formatter::Arg& arg4,
358                      const Formatter::Arg& arg5,
359                      const Formatter::Arg& arg6,
360                      const Formatter::Arg& arg7,
361                      const Formatter::Arg& arg8,
362                      const Formatter::Arg& arg9)
363 chuck       1.29 {
364 mike        1.42     if (wouldLog(logLevel))
365                      {
366 marek       1.70         Logger::_putInternal(logFileType, systemId, logLevel,
367 kumpf       1.63             Formatter::format(formatString, arg0, arg1, arg2, arg3,
368                                  arg4, arg5, arg6, arg7, arg8, arg9));
369 mike        1.42     }
370 karl        1.37 }
371                  
372                  void Logger::put(
373 kumpf       1.40     LogFileType logFileType,
374                      const String& systemId,
375                      Uint32 logLevel,
376                      const String& formatString)
377 karl        1.37 {
378 mike        1.42     if (wouldLog(logLevel))
379                      {
380 marek       1.70         Logger::_putInternal(logFileType, systemId, logLevel, formatString);
381 mike        1.42     }
382                  }
383 karl        1.37 
384 mike        1.42 void Logger::put(
385                      LogFileType logFileType,
386                      const String& systemId,
387                      Uint32 logLevel,
388                      const String& formatString,
389                      const Formatter::Arg& arg0)
390                  {
391                      if (wouldLog(logLevel))
392                      {
393 marek       1.70         Logger::_putInternal(logFileType, systemId, logLevel,
394 kumpf       1.63             Formatter::format(formatString, arg0));
395 mike        1.42     }
396 karl        1.37 }
397                  
398                  void Logger::put(
399 kumpf       1.40     LogFileType logFileType,
400                      const String& systemId,
401                      Uint32 logLevel,
402                      const String& formatString,
403 mike        1.42     const Formatter::Arg& arg0,
404                      const Formatter::Arg& arg1)
405 karl        1.37 {
406 mike        1.42     if (wouldLog(logLevel))
407                      {
408 marek       1.70         Logger::_putInternal(logFileType, systemId, logLevel,
409 kumpf       1.63             Formatter::format(formatString, arg0, arg1));
410 mike        1.42     }
411                  }
412 karl        1.37 
413 mike        1.42 void Logger::put(
414                      LogFileType logFileType,
415                      const String& systemId,
416                      Uint32 logLevel,
417                      const String& formatString,
418                      const Formatter::Arg& arg0,
419                      const Formatter::Arg& arg1,
420                      const Formatter::Arg& arg2)
421                  {
422                      if (wouldLog(logLevel))
423                      {
424 marek       1.70         Logger::_putInternal(logFileType, systemId, logLevel,
425 kumpf       1.63             Formatter::format(formatString, arg0, arg1, arg2));
426 mike        1.42     }
427 chuck       1.29 }
428                  
429                  void Logger::put_l(
430 kumpf       1.40     LogFileType logFileType,
431                      const String& systemId,
432                      Uint32 logLevel,
433 kumpf       1.63     const MessageLoaderParms& msgParms)
434 mike        1.42 {
435                      if (wouldLog(logLevel))
436                      {
437 kumpf       1.63         MessageLoaderParms parms = msgParms;
438                          parms.useProcessLocale = true;
439 marek       1.70         Logger::_putInternal(logFileType, systemId, logLevel,
440 kumpf       1.63             MessageLoader::getMessage(parms));
441 mike        1.42     }
442 david       1.26 }
443                  
444                  void Logger::trace(
445 kumpf       1.40     LogFileType logFileType,
446                      const String& systemId,
447 kumpf       1.62     const String& message)
448 chuck       1.29 {
449 mike        1.42     if (wouldLog(Logger::TRACE))
450                      {
451 marek       1.70         Logger::_putInternal(logFileType, systemId, Logger::TRACE,
452 kumpf       1.63             message);
453 mike        1.42     }
454 mike        1.13 }
455                  
456                  void Logger::setHomeDirectory(const String& homeDirectory)
457                  {
458                      _homeDirectory = homeDirectory;
459                  }
460 david       1.26 
461 dl.meetei   1.71 void Logger::setlogLevelMask( const String &logLevelList )
462 david       1.26 {
463 karl        1.37     Uint32 logLevelType = 0;
464 david       1.26     String logLevelName      = logLevelList;
465                  
466                      // Check if logLevel has been specified
467                      if (logLevelName != String::EMPTY)
468                      {
469                          // initialise _severityMask
470                          _severityMask = 0;
471                  
472 kumpf       1.40         // Set logLevelType to indicate the level of logging
473 david       1.26         // required by the user.
474 kumpf       1.40         if (String::equalNoCase(logLevelName,"TRACE"))
475                          {
476                              logLevelType =  Logger::TRACE;
477                          }
478                          else if (String::equalNoCase(logLevelName,"INFORMATION"))
479                          {
480                              logLevelType =  Logger::INFORMATION;
481                          }
482                          else if (String::equalNoCase(logLevelName,"WARNING"))
483                          {
484                              logLevelType = Logger::WARNING;
485                          }
486                          else if (String::equalNoCase(logLevelName,"SEVERE"))
487                          {
488                              logLevelType = Logger::SEVERE;
489                          }
490                          else if (String::equalNoCase(logLevelName,"FATAL"))
491                          {
492                              logLevelType = Logger::FATAL;
493                          }
494                          // Setting _severityMask.  NOTE:  When adding new logLevels
495 david       1.26         // it is essential that they are adding in ascending order
496                          // based on priority.  Once a case statement is true we will
497                          // continue to set all following log levels with a higher
498                          // priority.
499 kumpf       1.40         switch(logLevelType)
500                          {
501                              case Logger::TRACE:
502                                    _severityMask |= Logger::TRACE;
503                              case Logger::INFORMATION:
504                                    _severityMask |= Logger::INFORMATION;
505                              case Logger::WARNING:
506                                    _severityMask |= Logger::WARNING;
507                              case Logger::SEVERE:
508                                    _severityMask |= Logger::SEVERE;
509                              case Logger::FATAL:
510                                    _severityMask |= Logger::FATAL;
511                          }
512 kumpf       1.54 
513                          Executor::updateLogLevel(logLevelName.getCString());
514 david       1.26     }
515                      else
516                      {
517 kumpf       1.40         // Property logLevel not specified, set default value.
518                          _severityMask = ~Logger::TRACE;
519 kumpf       1.54         Executor::updateLogLevel("INFORMATION");
520 david       1.26     }
521                  }
522                  
523 dl.meetei   1.71 Boolean Logger::isValidlogLevel(const String &logLevel)
524 david       1.26 {
525                      // Validate the logLevel and modify the logLevel argument
526                      // to reflect the invalid logLevel
527                  
528                      Uint32    index=0;
529                      String    logLevelName = String::EMPTY;
530                      Boolean   validlogLevel=false;
531                  
532                      logLevelName = logLevel;
533                  
534                      if (logLevelName != String::EMPTY)
535                      {
536 kumpf       1.40         // Lookup the index for logLevel name in _logLevel_LIST
537                          index = 0;
538                          validlogLevel = false;
539                  
540                          while (index < _NUM_LOGLEVEL)
541                          {
542                              if (String::equalNoCase(logLevelName, LOGLEVEL_LIST[index]))
543                              {
544                                  // Found logLevel, break from the loop
545                                  validlogLevel = true;
546                                  break;
547                              }
548                              else
549                              {
550                                  index++;
551                              }
552                          }
553 david       1.26     }
554                      else
555                      {
556 kumpf       1.40         // logLevels is empty, it is a valid value so return true
557 kumpf       1.57         return true;
558 david       1.26     }
559                  
560                      return validlogLevel;
561                  }
562                  
563 mreddy      1.65 #if !defined (PEGASUS_USE_SYSLOGS)
564                  void Logger::setMaxLogFileSize(Uint32 maxLogFileSizeBytes)
565                  {
566                       LoggerRep::setMaxLogFileSize(maxLogFileSizeBytes);
567                  }
568                  #endif
569                  
570 mike        1.13 PEGASUS_NAMESPACE_END

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2