#include "precompiled.h"
#include "CLogger.h"
#include "ConfigDB.h"
#include "lib/lib.h"
#include "lib/path_util.h"
#include "lib/res/file/file.h"
#include ";
const char* html_header1 = "
Engine exited successfully on " << currentDate; m_MainLog << " at " << currentTime << buffer << "
\n"; m_MainLog << html_footer; m_MainLog.close (); m_InterestingLog << "Engine exited successfully on " << currentDate; m_InterestingLog << " at " << currentTime << 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_printf("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(); } // Sends the message to the appropriate piece of code void CLogger::LogUsingMethod(ELogMethod method, const char* category, const char* message) { if(method == NORMAL) WriteMessage(message, Interestedness(category)); else if(method == ERROR) WriteError(message, Interestedness(category)); else if(method == WARNING) WriteWarning(message, Interestedness(category)); else WriteMessage(message, Interestedness(category)); } 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); if (vsnprintf2(buffer, sizeof(buffer)-1, fmt, argp) == -1) { // Buffer too small - ensure the string is nicely terminated strcpy(buffer+sizeof(buffer)-4, "..."); // safe } va_end(argp); LogUsingMethod(method, category, buffer); } void CLogger::LogOnce(ELogMethod method, const char* category, const char *fmt, ...) { va_list argp; char buffer[512]; memset(buffer,0,sizeof(buffer)); va_start(argp, fmt); if (vsnprintf2(buffer, sizeof(buffer), fmt, argp) == -1) { // Buffer too small - ensure the string is nicely terminated strcpy(buffer+sizeof(buffer)-4, "..."); // safe } va_end(argp); std::string message (buffer); // If this message has already been logged, ignore it if (m_LoggedOnce.find(message) != m_LoggedOnce.end()) return; // If not, mark it as having been logged and then log it m_LoggedOnce.insert(message); LogUsingMethod(method, category, buffer); } void CLogger::QuickLog(const char *fmt, ...) { va_list argp; char buffer[512]; int count = 0; //Start a new paragraph in HTML strcpy(buffer,""); // safe va_start(argp, fmt); char *bufend=strchr(buffer, 0); vsnprintf(bufend, buffer+sizeof(buffer)-bufend, fmt, argp); va_end(argp); //add some html formatting, making sure not to overrun the buffer bufend=strchr(buffer, 0); strncpy(bufend, "
", buffer+sizeof(buffer)-bufend); 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]; count++; } *m_CurrentPosition++ = '\n'; 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 (! CConfigDB::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; // Try to retrieve the value as an integer if (! v->GetInt(level)) return 1; // something failed, so the default value might be a good alternative return level; }