version 1.47, 2006/11/08 20:38:30
|
version 1.55.2.1, 2007/09/11 16:32:42
|
|
|
#include <iostream> | #include <iostream> |
#include <fstream> | #include <fstream> |
#include <cstring> | #include <cstring> |
#include "Logger.h" |
#include <Pegasus/Common/Logger.h> |
#include "System.h" |
#include <Pegasus/Common/System.h> |
#include <Pegasus/Common/MessageLoader.h> //l10n |
#include <Pegasus/Common/FileSystem.h> |
|
#include <Pegasus/Common/MessageLoader.h> |
|
#include <Pegasus/Common/Executor.h> |
|
#include <Pegasus/Common/Mutex.h> |
| |
#if defined(PEGASUS_USE_SYSLOGS) | #if defined(PEGASUS_USE_SYSLOGS) |
# include <syslog.h> | # include <syslog.h> |
|
|
| |
PEGASUS_NAMESPACE_BEGIN | PEGASUS_NAMESPACE_BEGIN |
| |
|
// Maximum logfile size is defined as 32 MB = 32 * 1024 * 1024 |
|
# define PEGASUS_MAX_LOGFILE_SIZE 0X2000000 |
|
|
const Uint32 Logger::TRACE = (1 << 0); | const Uint32 Logger::TRACE = (1 << 0); |
const Uint32 Logger::INFORMATION = (1 << 1); | const Uint32 Logger::INFORMATION = (1 << 1); |
const Uint32 Logger::WARNING = (1 << 2); | const Uint32 Logger::WARNING = (1 << 2); |
|
|
const Boolean Logger::_SUCCESS = 1; | const Boolean Logger::_SUCCESS = 1; |
const Boolean Logger::_FAILURE = 0; | const Boolean Logger::_FAILURE = 0; |
| |
/* _allocLogFileName. Allocates the name from a name set. |
|
Today this is static. However, it should be completely |
|
configerable and driven from the config file so that |
|
Log organization and names are open. |
|
ATTN: rewrite this so that names, choice to do logs and |
|
mask for level of severity are all driven from configuration |
|
input. |
|
*/ |
|
static CString _allocLogFileName( |
|
const String& homeDirectory, |
|
Logger::LogFileType logFileType) |
|
{ |
|
static const char* fileNames[] = | static const char* fileNames[] = |
{ | { |
"PegasusTrace.log", | "PegasusTrace.log", |
|
|
"PegasusError.log", | "PegasusError.log", |
"PegasusDebug.log" | "PegasusDebug.log" |
}; | }; |
|
static const char* lockFileName = "PegasusLog.lock"; |
| |
int index = int(logFileType); |
#if defined(PEGASUS_OS_VXWORKS) && defined(log) |
|
# undef log |
if (index > Logger::NUM_LOGS) |
#endif |
index = Logger::ERROR_LOG; |
|
| |
const char* logFileName = fileNames[index]; |
/* _constructFileName prepares the absolute file name from homeDirectory |
|
and fileName. |
| |
|
Today this is static. However, it should be completely |
|
configerable and driven from the config file so that |
|
Log organization and names are open. |
|
ATTN: rewrite this so that names, choice to do logs and |
|
mask for level of severity are all driven from configuration |
|
input. |
|
*/ |
|
static CString _constructFileName( |
|
const String& homeDirectory, |
|
const char * fileName) |
|
{ |
String result; | String result; |
result.reserveCapacity(homeDirectory.size() + 1 + strlen(logFileName)); |
result.reserveCapacity((Uint32)(homeDirectory.size() + 1 + |
|
strlen(fileName))); |
result.append(homeDirectory); | result.append(homeDirectory); |
result.append('/'); | result.append('/'); |
result.append(logFileName); |
result.append(fileName); |
return result.getCString(); | return result.getCString(); |
} | } |
| |
|
|
| |
// KS: I put the second test in just in case some trys to create | // KS: I put the second test in just in case some trys to create |
// a completly erronous directory. At least we will get a message | // a completly erronous directory. At least we will get a message |
if (!System::isDirectory(lgDir)){ |
if (!System::isDirectory(lgDir)) |
//l10n |
{ |
//cerr << "Logging Disabled"; |
|
MessageLoaderParms parms("Common.Logger.LOGGING_DISABLED", | MessageLoaderParms parms("Common.Logger.LOGGING_DISABLED", |
"Logging Disabled"); | "Logging Disabled"); |
| |
cerr << MessageLoader::getMessage(parms); | cerr << MessageLoader::getMessage(parms); |
} | } |
| |
CString fileName = _allocLogFileName(homeDirectory, Logger::TRACE_LOG); |
//Filelocks are not used for VMS |
_logs[Logger::TRACE_LOG].open(fileName, ios::app); |
#if !defined(PEGASUS_OS_VMS) |
|
_loggerLockFileName = _constructFileName(homeDirectory, lockFileName); |
|
|
|
// Open and close a file to make sure that the file exists, on which |
|
// file lock is requested |
|
FILE *fileLockFilePointer; |
|
fileLockFilePointer = fopen(_loggerLockFileName, "a+"); |
|
if(fileLockFilePointer) |
|
{ |
|
fclose(fileLockFilePointer); |
|
} |
|
#endif |
| |
fileName = _allocLogFileName(homeDirectory, Logger::STANDARD_LOG); |
|
_logs[Logger::STANDARD_LOG].open(fileName, ios::app); |
_logFileNames[Logger::TRACE_LOG] = _constructFileName(homeDirectory, |
|
fileNames[Logger::TRACE_LOG]); |
|
|
|
_logFileNames[Logger::STANDARD_LOG] = _constructFileName(homeDirectory, |
|
fileNames[Logger::STANDARD_LOG]); |
| |
#ifndef PEGASUS_DISABLE_AUDIT_LOGGER | #ifndef PEGASUS_DISABLE_AUDIT_LOGGER |
fileName = _allocLogFileName(homeDirectory, Logger::AUDIT_LOG); |
_logFileNames[Logger::AUDIT_LOG] = _constructFileName(homeDirectory, |
_logs[Logger::AUDIT_LOG].open(fileName, ios::app); |
fileNames[Logger::AUDIT_LOG]); |
#endif | #endif |
| |
fileName = _allocLogFileName(homeDirectory, Logger::ERROR_LOG); |
_logFileNames[Logger::ERROR_LOG] = _constructFileName(homeDirectory, |
_logs[Logger::ERROR_LOG].open(fileName, ios::app); |
fileNames[Logger::ERROR_LOG]); |
| |
fileName = _allocLogFileName(homeDirectory, Logger::DEBUG_LOG); |
_logFileNames[Logger::DEBUG_LOG] = _constructFileName(homeDirectory, |
_logs[Logger::DEBUG_LOG].open(fileName, ios::app); |
fileNames[Logger::DEBUG_LOG]); |
#else | #else |
| |
#ifdef PEGASUS_OS_ZOS | #ifdef PEGASUS_OS_ZOS |
logIdendity = System::CIMSERVER.getCString(); |
logIdentity = strdup(System::CIMSERVER.getCString()); |
// If System Log is used open it | // If System Log is used open it |
System::openlog(logIdendity, LOG_PID, LOG_DAEMON); |
System::openlog(logIdentity, LOG_PID, LOG_DAEMON); |
#endif | #endif |
| |
#endif | #endif |
|
|
| |
~LoggerRep() | ~LoggerRep() |
{ | { |
#if !defined(PEGASUS_USE_SYSLOGS) |
|
_logs[Logger::TRACE_LOG].close(); |
|
_logs[Logger::STANDARD_LOG].close(); |
|
| |
#ifndef PEGASUS_DISABLE_AUDIT_LOGGER |
#ifdef PEGASUS_OS_ZOS |
_logs[Logger::AUDIT_LOG].close(); |
System::closelog(); |
|
free(logIdentity); |
#endif | #endif |
|
} |
| |
_logs[Logger::ERROR_LOG].close(); |
// Actual logging is done in this routine |
_logs[Logger::DEBUG_LOG].close(); |
void log(Logger::LogFileType logFileType, |
|
const String& systemId, |
|
Uint32 logLevel, |
|
const String localizedMsg) |
|
{ |
|
#if defined(PEGASUS_USE_SYSLOGS) |
|
|
|
// Log the message |
|
System::syslog(systemId, logLevel, localizedMsg.getCString()); |
| |
#else | #else |
|
// Prepend the systemId to the incoming message |
|
String messageString(systemId); |
|
messageString.append(": "); |
|
messageString.append(localizedMsg); // l10n |
| |
#ifdef PEGASUS_OS_ZOS |
// Get the logLevel String |
System::closelog(); |
// This converts bitmap to string based on highest order |
|
// bit set |
|
// ATTN: KS Fix this more efficiently. |
|
const char* tmp = ""; |
|
if (logLevel & Logger::TRACE) tmp = "TRACE "; |
|
if (logLevel & Logger::INFORMATION) tmp = "INFO "; |
|
if (logLevel & Logger::WARNING) tmp = "WARNING "; |
|
if (logLevel & Logger::SEVERE) tmp = "SEVERE "; |
|
if (logLevel & Logger::FATAL) tmp = "FATAL "; |
| |
#endif |
# ifndef PEGASUS_OS_VMS |
|
// Acquire AutoMutex (for thread sync) |
|
// and AutoFileLock (for Process Sync). |
|
AutoMutex am(_mutex); |
|
AutoFileLock fileLock(_loggerLockFileName); |
| |
#endif |
Uint32 logFileSize = 0; |
| |
} |
// Read logFileSize to check if the logfile needs to be pruned. |
|
FileSystem::getFileSize(String(_logFileNames[logFileType]), |
|
logFileSize); |
|
|
|
// Check if the size of the logfile is exceeding 32MB. |
|
if ( logFileSize > PEGASUS_MAX_LOGFILE_SIZE) |
|
{ |
|
// Prepare appropriate file name based on the logFileType. |
|
// Eg: if Logfile name is PegasusStandard.log, pruned logfile name |
|
// will be PegasusStandard-062607-122302.log,where 062607-122302 |
|
// is the time stamp. |
|
String prunedLogfile(_logFileNames[logFileType], |
|
(Uint32)strlen(_logFileNames[logFileType]) - 4); |
|
prunedLogfile.append('-'); |
| |
ostream& logOf(Logger::LogFileType logFileType) |
// Get timestamp,remove illegal chars in file name'/' and ':' |
|
// (: is illegal Open VMS) from the time stamp. Append the time |
|
// info to the file name. |
|
|
|
String timeStamp = System::getCurrentASCIITime(); |
|
for (unsigned int i=0; i<=timeStamp.size(); i++) |
|
{ |
|
if(timeStamp[i] == '/' || timeStamp[i] == ':') |
{ | { |
int index = int(logFileType); |
timeStamp.remove(i, 1); |
|
} |
|
} |
|
prunedLogfile.append(timeStamp); |
|
|
|
// Append '.log' to the file |
|
prunedLogfile.append( ".log"); |
| |
if (index > int(Logger::NUM_LOGS)) |
// Rename the logfile |
index = Logger::ERROR_LOG; |
FileSystem::renameFile(String(_logFileNames[logFileType]), |
|
prunedLogfile); |
| |
return _logs[index]; |
} // Check if the logfile needs to be pruned. |
|
# endif // ifndef PEGASUS_OS_VMS |
|
|
|
// Open Logfile. Based on the value of logFileType, one of the five |
|
// Logfiles will be opened. |
|
ofstream logFileStream; |
|
logFileStream.open(_logFileNames[logFileType], ios::app); |
|
logFileStream << System::getCurrentASCIITime() |
|
<< " " << tmp << (const char *)messageString.getCString() << endl; |
|
logFileStream.close(); |
|
#endif // ifndef PEGASUS_USE_SYSLOGS |
} | } |
| |
private: | private: |
| |
#ifdef PEGASUS_OS_ZOS | #ifdef PEGASUS_OS_ZOS |
CString logIdendity; |
char* logIdentity; |
|
#endif |
|
CString _logFileNames[int(Logger::NUM_LOGS)]; |
|
#ifndef PEGASUS_OS_VMS |
|
CString _loggerLockFileName; |
|
Mutex _mutex; |
#endif | #endif |
ofstream _logs[int(Logger::NUM_LOGS)]; |
|
}; | }; |
| |
void Logger::_putInternal( | void Logger::_putInternal( |
LogFileType logFileType, | LogFileType logFileType, |
const String& systemId, | const String& systemId, |
const Uint32 logComponent, // TODO: Support logComponent mask in future release |
const Uint32 logComponent, // FUTURE: Support logComponent mask |
Uint32 logLevel, | Uint32 logLevel, |
const String& formatString, | const String& formatString, |
const String& messageId, // l10n |
const String& messageId, |
const Formatter::Arg& arg0, | const Formatter::Arg& arg0, |
const Formatter::Arg& arg1, | const Formatter::Arg& arg1, |
const Formatter::Arg& arg2, | const Formatter::Arg& arg2, |
|
|
if (!_rep) | if (!_rep) |
_rep = new LoggerRep(_homeDirectory); | _rep = new LoggerRep(_homeDirectory); |
| |
// Get the logLevel String |
|
// This converts bitmap to string based on highest order |
|
// bit set |
|
// ATTN: KS Fix this more efficiently. |
|
static const char* svNames[] = |
|
{ |
|
"TRACE ", |
|
"INFO ", |
|
"WARNING ", |
|
"SEVERE ", |
|
"FATAL " |
|
}; |
|
// NUM_LEVELS = 5 |
|
int sizeSvNames = sizeof(svNames) / sizeof(svNames[0]) - 1; |
|
| |
// l10n start | // l10n start |
// The localized message to be sent to the system log. | // The localized message to be sent to the system log. |
|
|
} | } |
// l10n end | // l10n end |
| |
#if defined(PEGASUS_USE_SYSLOGS) |
|
|
|
// Log the message |
|
System::syslog(systemId, logLevel, localizedMsg.getCString()); |
|
| |
#else |
// Call the actual logging routine is in LoggerRep. |
|
_rep->log(logFileType, systemId, logLevel, localizedMsg); |
// Prepend the systemId to the incoming message |
|
String messageString(systemId); |
|
messageString.append(": "); |
|
messageString.append(localizedMsg); // l10n |
|
|
|
const char* tmp = ""; |
|
if (logLevel & Logger::TRACE) tmp = "TRACE "; |
|
if (logLevel & Logger::INFORMATION) tmp = "INFO "; |
|
if (logLevel & Logger::WARNING) tmp = "WARNING "; |
|
if (logLevel & Logger::SEVERE) tmp = "SEVERE "; |
|
if (logLevel & Logger::FATAL) tmp = "FATAL "; |
|
|
|
_rep->logOf(logFileType) << System::getCurrentASCIITime() |
|
<< " " << tmp << (const char *)messageString.getCString() << endl; |
|
|
|
#endif |
|
} | } |
} | } |
| |
|
|
| |
void Logger::setlogLevelMask( const String logLevelList ) | void Logger::setlogLevelMask( const String logLevelList ) |
{ | { |
Uint32 position = 0; |
|
Uint32 logLevelType = 0; | Uint32 logLevelType = 0; |
String logLevelName = logLevelList; | String logLevelName = logLevelList; |
| |
|
|
case Logger::FATAL: | case Logger::FATAL: |
_severityMask |= Logger::FATAL; | _severityMask |= Logger::FATAL; |
} | } |
|
|
|
Executor::updateLogLevel(logLevelName.getCString()); |
} | } |
else | else |
{ | { |
// Property logLevel not specified, set default value. | // Property logLevel not specified, set default value. |
_severityMask = ~Logger::TRACE; | _severityMask = ~Logger::TRACE; |
|
Executor::updateLogLevel("INFORMATION"); |
} | } |
return ; |
|
} | } |
| |
Boolean Logger::isValidlogLevel(const String logLevel) | Boolean Logger::isValidlogLevel(const String logLevel) |
|
|
// Validate the logLevel and modify the logLevel argument | // Validate the logLevel and modify the logLevel argument |
// to reflect the invalid logLevel | // to reflect the invalid logLevel |
| |
Uint32 position=0; |
|
Uint32 index=0; | Uint32 index=0; |
String logLevelName = String::EMPTY; | String logLevelName = String::EMPTY; |
Boolean validlogLevel=false; | Boolean validlogLevel=false; |
Boolean retCode=true; |
|
| |
logLevelName = logLevel; | logLevelName = logLevel; |
| |