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

  1 mike  1.13 //%/////////////////////////////////////////////////////////////////////////////
  2            //
  3 kumpf 1.18 // Copyright (c) 2000, 2001, 2002 BMC Software, Hewlett-Packard Company, IBM,
  4            // The Open Group, Tivoli Systems
  5 mike  1.13 //
  6            // Permission is hereby granted, free of charge, to any person obtaining a copy
  7 kumpf 1.18 // of this software and associated documentation files (the "Software"), to
  8            // deal in the Software without restriction, including without limitation the
  9            // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
 10 mike  1.13 // sell copies of the Software, and to permit persons to whom the Software is
 11            // furnished to do so, subject to the following conditions:
 12            // 
 13 kumpf 1.18 // THE ABOVE COPYRIGHT NOTICE AND THIS PERMISSION NOTICE SHALL BE INCLUDED IN
 14 mike  1.13 // ALL COPIES OR SUBSTANTIAL PORTIONS OF THE SOFTWARE. THE SOFTWARE IS PROVIDED
 15            // "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
 16 kumpf 1.18 // LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
 17            // PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
 18            // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
 19 mike  1.13 // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 20            // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 21            //
 22            //==============================================================================
 23            //
 24            // Author: Mike Brasher (mbrasher@bmc.com)
 25            //
 26 kumpf 1.16 // Modified By: Sushma Fernandes (Hewlett-Packard Company)
 27            //              sushma_fernandes@hp.com
 28 david 1.25 // Modified By: Dave Rosckes (IBM)
 29            //              rosckes@us.ibm.com
 30 mike  1.13 //
 31            //%/////////////////////////////////////////////////////////////////////////////
 32            
 33            #include <iostream>
 34            #include <fstream>
 35 kumpf 1.23 #include <cstring>
 36 mike  1.13 #include "Logger.h"
 37            #include "System.h"
 38 kumpf 1.16 #include "Destroyer.h"
 39 mday  1.28.6.2 #include <Pegasus/Common/MessageLoader.h> //l10n
 40 kumpf 1.16     
 41 mike  1.13     PEGASUS_USING_STD;
 42                
 43                PEGASUS_NAMESPACE_BEGIN
 44                
 45                const Uint32 Logger::TRACE = (1 << 0);
 46                const Uint32 Logger::INFORMATION = (1 << 1);
 47                const Uint32 Logger::WARNING = (1 << 2);
 48                const Uint32 Logger::SEVERE = (1 << 3);
 49                const Uint32 Logger::FATAL = (1 << 4);
 50                
 51 david 1.26     static char const* LOGLEVEL_LIST[] =
 52                {
 53                    "TRACE",
 54                    "INFORMATION",
 55                    "WARNING",
 56                    "SEVERE",
 57                    "FATAL"
 58                };
 59                
 60                
 61 mike  1.13     LoggerRep* Logger::_rep = 0;
 62                String Logger::_homeDirectory = ".";
 63 kumpf 1.16     
 64 david 1.26     const Uint32 Logger::_NUM_LOGLEVEL = 5;
 65                
 66                // Set separator
 67                const char Logger::_SEPARATOR = '@';
 68                
 69                Uint32 Logger::_severityMask; 
 70 kumpf 1.16     
 71 mike  1.13     Uint32 Logger::_writeControlMask = 0xF;   // Set all on by default
 72                
 73 david 1.26     // Set the return codes
 74                const Boolean Logger::_SUCCESS = 1;
 75                const Boolean Logger::_FAILURE = 0;
 76                
 77 mike  1.13     /* _allocLogFileName. Allocates the name from a name set.
 78                    Today this is static.  However, it should be completely
 79                    configerable and driven from the config file so that
 80                    Log organization and names are open.
 81                    ATTN: rewrite this so that names, choice to do logs and
 82                    mask for level of severity are all driven from configuration
 83                    input.
 84                */
 85 kumpf 1.22     static CString _allocLogFileName(
 86 mike  1.13         const String& homeDirectory,
 87                    Logger::LogFileType logFileType)
 88                {
 89 mike  1.15         static const char* fileNames[] = 
 90 mike  1.13         {
 91                	"PegasusTrace.log",
 92                	"PegasusStandard.log",
 93                	"PegasusError.log",
 94                	"PegasusDebug.log"
 95                    };
 96                
 97                    int index = int(logFileType);
 98                
 99                    if (index > Logger::NUM_LOGS)
100                	index = Logger::ERROR_LOG;
101                
102                    const char* logFileName = fileNames[index];
103                
104                    String result;
105 kumpf 1.19         result.reserveCapacity(homeDirectory.size() + 1 + strlen(logFileName));
106 kumpf 1.20         result.append(homeDirectory);
107                    result.append('/');
108                    result.append(logFileName);
109 kumpf 1.22         return result.getCString();
110 mike  1.13     }
111                
112                class LoggerRep
113                {
114                public:
115                
116                    LoggerRep(const String& homeDirectory)
117                    {
118 david 1.27     #if !defined(PEGASUS_USE_SYSLOGS)    
119 mike  1.13     	// Add test for home directory set.
120                
121                	// If home directory does not exist, create it.
122 kumpf 1.22     	CString lgDir = homeDirectory.getCString();
123 mike  1.13     
124                	if (!System::isDirectory(lgDir))
125                	    System::makeDirectory(lgDir);
126                
127 karl  1.14     	// KS: I put the second test in just in case some trys to create
128 mike  1.13     	// a completly erronous directory.  At least we will get a message
129 mday  1.28.6.2 	if (!System::isDirectory(lgDir)){
130                		//l10n
131                	   //cerr << "Logging Disabled";
132                	   MessageLoaderParms parms("Common.Logger.LOGGING_DISABLED",
133                	   							"Logging Disabled");
134                	   			
135                	   cerr << MessageLoader::getMessage(parms);
136                	}
137 mike  1.13     
138 kumpf 1.22     	CString fileName = _allocLogFileName(homeDirectory, Logger::TRACE_LOG);
139 mike  1.13     	_logs[Logger::TRACE_LOG].open(fileName, ios::app);
140                
141                	fileName = _allocLogFileName(homeDirectory, Logger::STANDARD_LOG);
142                	_logs[Logger::STANDARD_LOG].open(fileName, ios::app);
143                
144                	fileName = _allocLogFileName(homeDirectory, Logger::ERROR_LOG);
145                	_logs[Logger::ERROR_LOG].open(fileName, ios::app);
146                
147                	fileName = _allocLogFileName(homeDirectory, Logger::DEBUG_LOG);
148                	_logs[Logger::DEBUG_LOG].open(fileName, ios::app);
149 kumpf 1.17     #endif 
150 mike  1.13     
151                    }
152                
153                    ostream& logOf(Logger::LogFileType logFileType)
154                    {
155                	int index = int(logFileType);
156                
157                	if (index > int(Logger::ERROR_LOG))
158                	    index = Logger::ERROR_LOG;
159                
160                	return _logs[index];
161                    }
162                
163                private:
164                
165                    ofstream _logs[int(Logger::NUM_LOGS)];
166                };
167                
168 david 1.26     void Logger::_putInternal(
169 mike  1.13         LogFileType logFileType,
170                    const String& systemId,
171 david 1.26         const Uint32 logComponent, // TODO: Support logComponent mask in future release 
172                    Uint32 logLevel,
173 mike  1.13         const String& formatString,
174 mday  1.28.6.1     const String& messageId,  // l10n
175 mike  1.13         const Formatter::Arg& arg0,
176                    const Formatter::Arg& arg1,
177                    const Formatter::Arg& arg2,
178                    const Formatter::Arg& arg3,
179                    const Formatter::Arg& arg4,
180                    const Formatter::Arg& arg5,
181                    const Formatter::Arg& arg6,
182                    const Formatter::Arg& arg7,
183                    const Formatter::Arg& arg8,
184                    const Formatter::Arg& arg9)
185                {
186 david 1.26         // Test for logLevel against severity mask to determine
187 mike  1.13         // if we write this log.
188 david 1.26         if ((_severityMask & logLevel) != 0) 
189 mike  1.13         {
190                	if (!_rep)
191                	   _rep = new LoggerRep(_homeDirectory);
192                
193 mday  1.28.6.1 		// Get the logLevel String
194                		// This converts bitmap to string based on highest order
195                		// bit set
196                		// ATTN: KS Fix this more efficiently.
197                		static const char* svNames[] = 
198                		{
199 mike  1.13     	    "TRACE   ",
200                	    "INFO    ",
201                	    "WARNING ",
202                	    "SEVERE  ",
203                	    "FATAL   "
204 mday  1.28.6.1 		};
205                		// NUM_LEVELS = 5
206                		int sizeSvNames = sizeof(svNames) / sizeof(svNames[0]) - 1;
207                
208                // l10n start
209                        // The localized message to be sent to the system log.
210                		String localizedMsg;
211                         
212                		// If the caller specified a messageId, then load the localized
213                		// message in the locale of the server process.                		
214                		if (messageId != String::EMPTY)
215                		{
216                			// A message ID was specified.  Use the MessageLoader.			
217                			MessageLoaderParms msgParms(messageId, formatString);
218                			msgParms.useProcessLocale = true;
219                			msgParms.arg0 = arg0;
220                			msgParms.arg1 = arg1;
221                			msgParms.arg2 = arg2;
222                			msgParms.arg3 = arg3;
223                			msgParms.arg4 = arg4;
224                			msgParms.arg5 = arg5;
225 mday  1.28.6.1 			msgParms.arg6 = arg6;
226                			msgParms.arg7 = arg7;
227                			msgParms.arg8 = arg8;
228                			msgParms.arg9 = arg9;
229                																		
230                			localizedMsg = MessageLoader::getMessage(msgParms);				
231                		}
232                		else
233                		{  // No message ID.  Use the Pegasus formatter  
234                		  	localizedMsg = Formatter::format(formatString,
235                                arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9);			
236                		}
237                // l10n end		
238                	
239 david 1.26     #if defined(PEGASUS_USE_SYSLOGS)
240                           
241 kumpf 1.16                 // Open the syslog.
242                            // Ignore the systemId and open the log as cimserver
243 david 1.26     	    System::openlog(systemId);
244 kumpf 1.16     
245                            // Log the message
246 mday  1.28.6.2 	    System::syslog(logLevel,(const char*)localizedMsg.getCStringUTF8());	    
247 mday  1.28.6.1 	    
248 kumpf 1.16                 // Close the syslog.
249 david 1.26     	    System::closelog();
250 david 1.25     
251 david 1.26            #else
252 david 1.25     
253 david 1.26     	    // Prepend the systemId to the incoming message
254                	    String messageString(systemId);
255                	    messageString.append(": ");
256 mday  1.28.6.2 	    messageString.append(localizedMsg);  // l10n 
257 david 1.25     
258 kumpf 1.16     	    const char* tmp = "";
259 david 1.26     	    if (logLevel & Logger::TRACE) tmp =       "TRACE   ";
260                	    if (logLevel & Logger::INFORMATION) tmp = "INFO    ";
261                            if (logLevel & Logger::WARNING) tmp =     "WARNING ";
262                	    if (logLevel & Logger::SEVERE) tmp =      "SEVERE  ";
263                	    if (logLevel & Logger::FATAL) tmp =       "FATAL   ";
264 mday  1.28.6.1                 _rep->logOf(logFileType) << System::getCurrentASCIITime()
265 mday  1.28.6.2                << " " << tmp << messageString.getCStringUTF8() << endl;
266 david 1.26     
267 kumpf 1.16            #endif
268 david 1.26         }
269                }
270 mike  1.13     
271 david 1.26     void Logger::put(
272                		 LogFileType logFileType,
273                		 const String& systemId,
274                		 Uint32 logLevel,
275                		 const String& formatString,
276                		 const Formatter::Arg& arg0,
277                		 const Formatter::Arg& arg1,
278                		 const Formatter::Arg& arg2,
279                		 const Formatter::Arg& arg3,
280                		 const Formatter::Arg& arg4,
281                		 const Formatter::Arg& arg5,
282                		 const Formatter::Arg& arg6,
283                		 const Formatter::Arg& arg7,
284                		 const Formatter::Arg& arg8,
285 mday  1.28.6.1 		 const Formatter::Arg& arg9)	
286                {
287                    Uint32 logComponent = 0;
288                
289                    Logger::_putInternal(
290                			logFileType,
291                			systemId,
292                			logComponent,
293                			logLevel,
294 mday  1.28.6.3 			formatString,
295                //l10n
296 mday  1.28.6.1 			String::EMPTY,
297                			arg0,
298                			arg1,
299                			arg2,
300                			arg3,
301                			arg4,
302                			arg5,
303                			arg6,
304                			arg7,
305                			arg8,
306                			arg9);		
307                }
308                
309                // l10n
310                void Logger::put_l(
311                		 LogFileType logFileType,
312                		 const String& systemId,
313                		 Uint32 logLevel,
314                		 const String& messageId,  // l10n		 
315                		 const String& formatString,
316                		 const Formatter::Arg& arg0,
317 mday  1.28.6.1 		 const Formatter::Arg& arg1,
318                		 const Formatter::Arg& arg2,
319                		 const Formatter::Arg& arg3,
320                		 const Formatter::Arg& arg4,
321                		 const Formatter::Arg& arg5,
322                		 const Formatter::Arg& arg6,
323                		 const Formatter::Arg& arg7,
324                		 const Formatter::Arg& arg8,
325                		 const Formatter::Arg& arg9)			
326 david 1.26     {
327                    Uint32 logComponent = 0;
328                
329                    Logger::_putInternal(
330                			logFileType,
331                			systemId,
332                			logComponent,
333                			logLevel,
334                			formatString,
335 mday  1.28.6.1 			messageId,
336 david 1.26     			arg0,
337                			arg1,
338                			arg2,
339                			arg3,
340                			arg4,
341                			arg5,
342                			arg6,
343                			arg7,
344                			arg8,
345 mday  1.28.6.1 			arg9);		
346 david 1.26     }
347                
348                void Logger::trace(
349                		   LogFileType logFileType,
350                		   const String& systemId,
351                		   const Uint32 logComponent,
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 mday  1.28.6.1 		   const Formatter::Arg& arg9)	
363                {
364                    Uint32 logLevel = Logger::TRACE;
365                
366                    Logger::_putInternal(
367                			logFileType,
368                			systemId,
369                			logComponent,
370                			logLevel,
371                			formatString,
372                // l10n
373                			String::EMPTY,
374                			arg0,
375                			arg1,
376                			arg2,
377                			arg3,
378                			arg4,
379                			arg5,
380                			arg6,
381                			arg7,
382                			arg8,
383 mday  1.28.6.1 			arg9);			
384                }
385                
386                // l10n
387                void Logger::trace_l(
388                		   LogFileType logFileType,
389                		   const String& systemId,
390                		   const Uint32 logComponent,
391                		   const String& messageId,		   
392                		   const String& formatString,
393                		   const Formatter::Arg& arg0,
394                		   const Formatter::Arg& arg1,
395                		   const Formatter::Arg& arg2,
396                		   const Formatter::Arg& arg3,
397                		   const Formatter::Arg& arg4,
398                		   const Formatter::Arg& arg5,
399                		   const Formatter::Arg& arg6,
400                		   const Formatter::Arg& arg7,
401                		   const Formatter::Arg& arg8,
402                		   const Formatter::Arg& arg9)	
403 david 1.26     {
404                    Uint32 logLevel = Logger::TRACE;
405                
406                    Logger::_putInternal(
407                			logFileType,
408                			systemId,
409                			logComponent,
410                			logLevel,
411                			formatString,
412 mday  1.28.6.1 			messageId,
413 david 1.26     			arg0,
414                			arg1,
415                			arg2,
416                			arg3,
417                			arg4,
418                			arg5,
419                			arg6,
420                			arg7,
421                			arg8,
422 mday  1.28.6.1 			arg9);			
423 mike  1.13     }
424                
425                void Logger::setHomeDirectory(const String& homeDirectory)
426                {
427                    _homeDirectory = homeDirectory;
428                }
429 david 1.26     
430                ////////////////////////////////////////////////////////////////////////////////
431                // Set logLevel. 
432                ////////////////////////////////////////////////////////////////////////////////
433                void Logger::setlogLevelMask( const String logLevelList )
434                {
435                    Uint32 position          = 0;
436                    Uint32 logLevelType;
437                    String logLevelName      = logLevelList;
438                
439                    // Check if logLevel has been specified
440                    if (logLevelName != String::EMPTY)
441                    {
442                        // initialise _severityMask
443                        _severityMask = 0;
444                
445                 	// Set logLevelType to indicate the level of logging
446                        // required by the user.
447                	if (String::equalNoCase(logLevelName,"TRACE"))
448                	{
449                	    logLevelType =  Logger::TRACE;
450 david 1.26     	}
451                	else if (String::equalNoCase(logLevelName,"INFORMATION"))
452                	{
453                	    logLevelType =  Logger::INFORMATION;
454                	}
455                	else if (String::equalNoCase(logLevelName,"WARNING"))
456                	{
457                	    logLevelType = Logger::WARNING;
458                	}
459                	else if (String::equalNoCase(logLevelName,"SEVERE"))
460                	{
461                	    logLevelType = Logger::SEVERE;
462                	}
463                	else if (String::equalNoCase(logLevelName,"FATAL"))
464                	{
465                	    logLevelType = Logger::FATAL;
466                	}
467                	// Setting _severityMask.  NOTE:  When adding new logLevels
468                        // it is essential that they are adding in ascending order
469                        // based on priority.  Once a case statement is true we will
470                        // continue to set all following log levels with a higher
471 david 1.26             // priority.
472                	switch(logLevelType)
473                	{
474                	    case Logger::TRACE:
475                		  _severityMask |= Logger::TRACE;
476                	    case Logger::INFORMATION:
477                		  _severityMask |= Logger::INFORMATION;
478                	    case Logger::WARNING:
479                		  _severityMask |= Logger::WARNING;
480                	    case Logger::SEVERE:
481                		  _severityMask |= Logger::SEVERE;
482                	    case Logger::FATAL:
483                		  _severityMask |= Logger::FATAL;
484                	}
485                    }
486                    else
487                    {
488                	// Property logLevel not specified, set default value.
489                	_severityMask = ~Logger::TRACE;
490                    }
491                    return ;
492 david 1.26     }
493                
494                Boolean Logger::isValidlogLevel(
495                    const String logLevel)
496                {
497                    // Validate the logLevel and modify the logLevel argument
498                    // to reflect the invalid logLevel
499                
500                    Uint32    position=0;
501                    Uint32    index=0;
502                    String    logLevelName = String::EMPTY;
503                    Boolean   validlogLevel=false;
504                    Boolean   retCode=true;
505                
506                    logLevelName = logLevel;
507                
508                    if (logLevelName != String::EMPTY)
509                    {
510                	// Lookup the index for logLevel name in _logLevel_LIST
511                	index = 0;
512                	validlogLevel = false;
513 david 1.26     
514                	while (index < _NUM_LOGLEVEL)
515                	{
516                	    if (String::equalNoCase(logLevelName, LOGLEVEL_LIST[index]))
517                	    {
518                		// Found logLevel, break from the loop
519                		validlogLevel = true;
520                		break;
521                	    }
522                	    else
523                	    {
524                		index++;
525                	    }
526                	}
527                    }
528                    else
529                    {
530                	// logLevels is empty, it is a valid value so return true
531                	return _SUCCESS;
532                    }
533                
534 david 1.26         return validlogLevel;
535                }
536                
537 mike  1.13     
538                PEGASUS_NAMESPACE_END

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2