#include "precompiled.h" #include "CLogger.h" #include "ConfigDB.h" #include "lib.h" #include "CConsole.h" extern CConsole* g_Console; using namespace std; const char* html_header0 = "\n\n\n" "\n\n

\n" "

"; const char* html_header1 = "

\n"; const char* html_footer = "\n\n"; #define MEMORY_BUFFER_SIZE 35 CLogger * CLogger::GetInstance() { static CLogger m_Instance; return &m_Instance; } CLogger::CLogger() { m_NumberOfMessages = 0; m_NumberOfErrors = 0; m_NumberOfWarnings = 0; m_MemoryLogBuffer = (char *) malloc(MEMORY_BUFFER_SIZE); m_CurrentPosition = m_MemoryLogBuffer; memset(m_MemoryLog,0,MEMORY_BUFFER_SIZE); // current directory is $install_dir/data, we want $install_dir/logs. // TODO: make sure we are called after file_rel_chdir, // or else cur dir may be anywhere m_MainLog.open ("../logs/mainlog.html", ofstream::out | ofstream::trunc); m_InterestingLog.open ("../logs/interestinglog.html", ofstream::out | ofstream::trunc); m_MemoryLog.open ("../logs/memorylog.html", ofstream::out | ofstream::trunc); //Write Headers for the HTML documents m_MainLog << html_header0 << "Main log" << html_header1; //Write Headers for the HTML documents m_InterestingLog << html_header0 << "Main log (interesting items only, as specified in system.cfg)" << html_header1; } CLogger::~CLogger () { char buffer[60]; sprintf(buffer," with %d message(s), %d error(s) and %d warning(s).", \ m_NumberOfMessages,m_NumberOfErrors,m_NumberOfWarnings); //Write closing text m_MainLog << "

Engine exited successfully on " << __DATE__; m_MainLog << " at " << __TIME__ << buffer << "

\n"; m_MainLog << html_footer; m_MainLog.close (); m_InterestingLog << "

Engine exited successfully on " << __DATE__; m_InterestingLog << " at " << __TIME__ << buffer << "

\n"; m_InterestingLog << html_footer; m_InterestingLog.close (); //Add end marker to logs in memory m_CurrentPosition = '\0'; m_MemoryLog << html_header0 << "Memory log" << html_header1; m_MemoryLog << "

Memory Log started with capacity of " << \ MEMORY_BUFFER_SIZE << " characters.

\n"; m_MemoryLog << m_MemoryLogBuffer; m_MemoryLog << html_footer; m_MemoryLog.close (); free(m_MemoryLogBuffer); } void CLogger::WriteMessage(const char *message, int interestedness) { m_NumberOfMessages++; if (interestedness >= 2) { if (g_Console) g_Console->InsertMessage(L"LOG: %hs", message); m_InterestingLog << "

" << message << "

\n"; m_InterestingLog.flush(); } m_MainLog << "

" << message << "

\n"; m_MainLog.flush(); } void CLogger::WriteError(const char *message, int interestedness) { m_NumberOfErrors++; debug_out("ERROR: %s\n", message); if (interestedness >= 1) { if (g_Console) g_Console->InsertMessage(L"ERROR: %hs", message); m_InterestingLog << "

ERROR: "<< message << "

\n"; m_InterestingLog.flush(); } m_MainLog << "

ERROR: "<< message << "

\n"; m_MainLog.flush(); } void CLogger::WriteWarning(const char *message, int interestedness) { m_NumberOfWarnings++; if (interestedness >= 1) { if (g_Console) g_Console->InsertMessage(L"WARNING: %hs", message); m_InterestingLog << "

WARNING: "<< message << "

\n"; m_InterestingLog.flush(); } m_MainLog << "

WARNING: "<< message << "

\n"; m_MainLog.flush(); } void CLogger::Log(ELogMethod method, const char* category, const char *fmt, ...) { va_list argp; char buffer[512]; memset(buffer,0,sizeof(buffer)); va_start(argp, fmt); vsnprintf2(buffer, sizeof(buffer), fmt, argp); va_end(argp); if(method == NORMAL) WriteMessage(buffer, Interestedness(category)); else if(method == ERROR) WriteError(buffer, Interestedness(category)); else if(method == WARNING) WriteWarning(buffer, Interestedness(category)); else WriteMessage(buffer, Interestedness(category)); } void CLogger::QuickLog(const char *fmt, ...) { va_list argp; char buffer[512]; int count = 0; //Start a new paragraph in HTML strcpy(buffer,"

"); va_start(argp, fmt); vsnprintf(strchr(buffer, 0), sizeof(buffer), fmt, argp); va_end(argp); //add some html formatting strcat(buffer,"

"); if((m_CurrentPosition - m_MemoryLogBuffer + strlen(buffer) + 1) >= MEMORY_BUFFER_SIZE) { //not enough room in the buffer so don't log. return; } while(buffer[count] != '\0') { *m_CurrentPosition = buffer[count]; *m_CurrentPosition++; count++; } *m_CurrentPosition = '\n'; *m_CurrentPosition++; free(buffer); } int CLogger::Interestedness(const char* category) { // This could be cached, but reading from the config DB every time allows // easy run-time alteration of interest levels (and shouldn't be particularly // slow) // Category unspecified: use a high interest level to encourage // people to categorise their errors if (category == NULL) return 2; // If the config DB hasn't been loaded, assume the default if (! g_ConfigDB.IsInitialised()) return 1; CConfigValue* v = g_ConfigDB.GetValue(CFG_SYSTEM, CStr("loginterest.")+category); // If the value is unspecified, also use the default if (!v) return 1; int level; // Something failed, so the default value might be a good alternative if (! v->GetInt(level)) return 1; return level; }