ultimatepp/bazaar/SystemLog/SystemLog.cpp
mdelfede d2b54f7989 changed svn layout
git-svn-id: svn://ultimatepp.org/upp/trunk@281 f0d560ea-af0d-0410-9eb7-867de7ffcac7
2008-06-07 22:31:27 +00:00

300 lines
7.5 KiB
C++

#include "SystemLog.h"
NAMESPACE_UPP
////////////////////////////////////////////////////////////////////////////////////////////////
// Global log object
SystemLog SysLog;
// gets platfor-dependent log level
#ifdef PLATFORM_POSIX
int SystemLog::platform(Levels level)
#elif defined(PLATFORM_WIN32)
dword SystemLog::platform(Levels level)
#endif
{
#ifdef PLATFORM_POSIX
if(level & LEMERGENCY) return LOG_EMERG;
if(level & LALERT) return LOG_ALERT;
if(level & LCRITICAL) return LOG_CRIT;
if(level & LERROR) return LOG_ERR;
if(level & LWARNING) return LOG_WARNING;
if(level & LNOTICE) return LOG_NOTICE;
if(level & LINFO) return LOG_INFO;
if(level & LDEBUG) return LOG_DEBUG;
#elif defined(PLATFORM_WIN32)
if(level & LEMERGENCY) return EVENTLOG_ERROR_TYPE;
if(level & LALERT) return EVENTLOG_ERROR_TYPE;
if(level & LCRITICAL) return EVENTLOG_ERROR_TYPE;
if(level & LERROR) return EVENTLOG_ERROR_TYPE;
if(level & LWARNING) return EVENTLOG_WARNING_TYPE;
if(level & LNOTICE) return EVENTLOG_INFORMATION_TYPE;
if(level & LINFO) return EVENTLOG_INFORMATION_TYPE;
if(level & LDEBUG) return EVENTLOG_INFORMATION_TYPE;
#endif
// should not happen....
return 0;
} // END SystemLog::platform()
////////////////////////////////////////////////////////////////////////////////////////////////
// constructor
SystemLog::SystemLog()
{
// log not opened upon creation
FOpened = false;
// disables syslog, disables console, enables CErr() and enables Upp log output
FCoutEnabled = false;
FCerrEnabled = true;
FSysLogEnabled = false;
FUppLogEnabled = true;
// initializes log buffer
FBuffer = "";
// initializes starting log level
FLastLevel = LERROR;
} // END Constructor class SystemLog
////////////////////////////////////////////////////////////////////////////////////////////////
// destructor
SystemLog::~SystemLog()
{
// closes the active log
Close();
} // END Destructor class SystemLog
////////////////////////////////////////////////////////////////////////////////////////////////
// closes the active log
void SystemLog::Close()
{
if (FOpened)
{
// flushes log buffer
Flush();
#ifdef PLATFORM_POSIX
closelog();
#elif defined(PLATFORM_WIN32)
DeregisterEventSource(log);
#endif
FOpened = false;
}
}
////////////////////////////////////////////////////////////////////////////////////////////////
// opens and initializes log stream
SystemLog &SystemLog::Open(String const &name, String const &dllPath)
{
// closes, if already opened
Close();
// stores the user log name
FLogName = name;
#ifdef PLATFORM_POSIX
openlog(FLogName, LOG_PID, LOG_USER);
#elif defined(PLATFORM_WIN32)
String path;
dword eventTypes = EVENTLOG_ERROR_TYPE | EVENTLOG_WARNING_TYPE | EVENTLOG_INFORMATION_TYPE;
dword categoryCount = 0;
log = NULL;
path << "SYSTEM\\CurrentControlSet\\Services\\EventLog\\Application\\" << FLogName;
if (GetWinRegString("EventMessageFile", path, HKEY_LOCAL_MACHINE) != dllPath)
{
if (!SetWinRegExpandString(dllPath, "EventMessageFile", path, HKEY_LOCAL_MACHINE))
return *this;
if (!SetWinRegInt(eventTypes, "TypesSupported", path, HKEY_LOCAL_MACHINE))
return *this;
}
log = RegisterEventSource(NULL, FLogName);
if (log == NULL)
return *this;
#endif
// marks log stream as opened
FOpened = true;
return *this;
}
////////////////////////////////////////////////////////////////////////////////////////////////
// flushes log buffer
void SystemLog::Flush()
{
// if no log opened, or buffer empty, does nothing
if (!FOpened || FBuffer == "" || !(FEnabledLevels & FLastLevel))
{
FBuffer = "";
return;
}
// Inserts log level name on buffer's head
String msg = LevelName(FLastLevel) + FBuffer;
// wipes buffer
FBuffer = "";
// outputs buffer to enabled log streams
// if upp log enabled, log on upp app log file
if(FUppLogEnabled)
LOG(msg);
// if CErr is enabled and message is an error one, logs to CErr()
if(FCerrEnabled && (FLastLevel & LALLERR))
// Cerr() << FLogName << " : " << msg << "\n";
fprintf(stderr, "%s : %s\n", (const char *)FLogName, (const char *)msg);
else if(FCoutEnabled)
fprintf(stdout, "%s : %s\n", (const char *)FLogName, (const char *)msg);
// Cout() << FLogName << " : " << msg << "\n";
// if syslog enabled, logs on syslog
if(FSysLogEnabled)
{
#ifdef PLATFORM_POSIX
syslog(platform(FLastLevel), msg);
#elif defined(PLATFORM_WIN32)
const char *array[2];
array[0] = (const char *)msg;
if (log == NULL)
return;
if (!ReportEvent(log, (WORD)platform(FLastLevel), 0, 0x00000001L, NULL, 1, 0, &array[0], NULL))
return;
#endif
}
}
////////////////////////////////////////////////////////////////////////////////////////////////
// enable specified level(s)
SystemLog &SystemLog::EnableLevels(byte Levels)
{
// flushes log buffer if needed
Flush();
FEnabledLevels |= Levels;
return *this;
} // END SystemLog::EnableLevels()
////////////////////////////////////////////////////////////////////////////////////////////////
// disable specified level(s)
SystemLog &SystemLog::DisableLevels(byte Levels)
{
// flushes log buffer if needed
Flush();
FEnabledLevels &= ~Levels;
return *this;
} // END SystemLog::DisableLevels()
////////////////////////////////////////////////////////////////////////////////////////////////
// sets enabled lebels to 'Levels'
SystemLog &SystemLog::SetLevels(byte Levels)
{
// flushes log buffer if needed
Flush();
FEnabledLevels = Levels;
return *this;
} // END SystemLog::SetLevels()
////////////////////////////////////////////////////////////////////////////////////////////////
// gets level name from level
String SystemLog::LevelName(Levels level)
{
switch(level)
{
case LEMERGENCY :
return "EMERGENCY:: ";
case LALERT :
return "ALERT :: ";
case LCRITICAL :
return "CRITICAL :: ";
case LERROR :
return "ERROR :: ";
case LWARNING :
return "WARNING :: ";
case LNOTICE :
return "NOTICE :: ";
case LINFO :
return "INFO :: ";
case LDEBUG :
return "DEBUG :: ";
default:
return "UNKNOWN :: ";
}
} // END SystemLog::LevelName()
////////////////////////////////////////////////////////////////////////////////////////////////
// sets current use level
SystemLog &SystemLog::SetLevel(Levels level)
{
if(FLastLevel != level)
{
Flush();
FLastLevel = level;
}
return *this;
} // END SystemLog::SetLevel()
SystemLog &SystemLog::operator()(Levels level)
{
if(FLastLevel != level)
{
Flush();
FLastLevel = level;
}
return *this;
} // END SystemLog::operator()
////////////////////////////////////////////////////////////////////////////////////////////////
// writes log message at required level
SystemLog &SystemLog::WriteLog(Levels level, String const &message)
{
// nothing to do if log is not opened
if(!FOpened)
return *this;
// checks if level is enabled
if(!(FEnabledLevels & level))
return *this;
// if changing log level, flushes previous buffer
if(FLastLevel != level)
Flush();
// sets last level as current
FLastLevel = level;
// appends current message to buffer
int start = 0;
int nl = 0;
while( nl < message.GetCount() && (nl = message.Find('\n', start)) >= 0)
{
FBuffer += message.Mid(start, nl-start);
Flush();
start = nl+1;
}
if(start < message.GetCount())
FBuffer += message.Mid(start);
return *this;
}
END_UPP_NAMESPACE