mirror of
https://github.com/ultimatepp/ultimatepp.git
synced 2026-05-15 22:02:49 -06:00
300 lines
7.5 KiB
C++
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
|