From 98443682671d0c39b19f86098f7bc900b7529b72 Mon Sep 17 00:00:00 2001 From: Tycho Date: Tue, 12 Aug 2014 16:05:04 +0100 Subject: [PATCH] Renamed Loggers --- Tools/MCADefrag/CMakeLists.txt | 4 +- Tools/MCADefrag/MCADefrag.cpp | 18 +-- Tools/ProtoProxy/CMakeLists.txt | 4 +- src/Bindings/ManualBindings.cpp | 10 +- src/CMakeLists.txt | 7 +- src/CompositeChat.cpp | 24 ++-- src/CompositeChat.h | 2 +- src/Globals.h | 2 +- src/Listeners.cpp | 236 ------------------------------- src/Listeners.h | 21 --- src/LogDispacher.cpp | 114 --------------- src/Logger.cpp | 109 ++++++++++++++ src/{LogDispacher.h => Logger.h} | 42 +++--- src/LoggerListeners.cpp | 231 ++++++++++++++++++++++++++++++ src/LoggerListeners.h | 17 +++ src/Root.cpp | 14 +- src/main.cpp | 2 +- 17 files changed, 418 insertions(+), 439 deletions(-) delete mode 100644 src/Listeners.cpp delete mode 100644 src/Listeners.h delete mode 100644 src/LogDispacher.cpp create mode 100644 src/Logger.cpp rename src/{LogDispacher.h => Logger.h} (51%) create mode 100644 src/LoggerListeners.cpp create mode 100644 src/LoggerListeners.h diff --git a/Tools/MCADefrag/CMakeLists.txt b/Tools/MCADefrag/CMakeLists.txt index e237b6429..42b42018b 100644 --- a/Tools/MCADefrag/CMakeLists.txt +++ b/Tools/MCADefrag/CMakeLists.txt @@ -39,8 +39,8 @@ set_exe_flags() set(SHARED_SRC ../../src/StringCompression.cpp ../../src/StringUtils.cpp - ../../src/Listeners.cpp - ../../src/LogDispacher.cpp + ../../src/LoggerListeners.cpp + ../../src/Logger.cpp ) set(SHARED_HDR ../../src/ByteBuffer.h diff --git a/Tools/MCADefrag/MCADefrag.cpp b/Tools/MCADefrag/MCADefrag.cpp index 702b04ebf..d5d233fd2 100644 --- a/Tools/MCADefrag/MCADefrag.cpp +++ b/Tools/MCADefrag/MCADefrag.cpp @@ -5,8 +5,8 @@ #include "Globals.h" #include "MCADefrag.h" -#include "LogDispacher.h" -#include "Listeners.h" +#include "Logger.h" +#include "LoggerListeners.h" #include "zlib/zlib.h" @@ -22,12 +22,12 @@ static const Byte g_Zeroes[4096] = {0}; int main(int argc, char ** argv) { - Logger::cLoggerListener * consoleLogListener = Logger::MakeConsoleListener(); - Logger::cLoggerListener * fileLogListener = new Logger::cFileListener(); - Logger::GetInstance().AttachListener(consoleLogListener); - Logger::GetInstance().AttachListener(fileLogListener); + cLogger::cListener * consoleLogListener = MakeConsoleListener(); + cLogger::cListener * fileLogListener = new cFileListener(); + cLogger::GetInstance().AttachListener(consoleLogListener); + cLogger::GetInstance().AttachListener(fileLogListener); - Logger::InitiateMultithreading(); + cLogger::InitiateMultithreading(); cMCADefrag Defrag; if (!Defrag.Init(argc, argv)) @@ -37,9 +37,9 @@ int main(int argc, char ** argv) Defrag.Run(); - Logger::GetInstance().DetachListener(consoleLogListener); + cLogger::GetInstance().DetachListener(consoleLogListener); delete consoleLogListener; - Logger::GetInstance().DetachListener(fileLogListener); + cLogger::GetInstance().DetachListener(fileLogListener); delete fileLogListener; return 0; diff --git a/Tools/ProtoProxy/CMakeLists.txt b/Tools/ProtoProxy/CMakeLists.txt index 16c59bb43..bc3923d90 100644 --- a/Tools/ProtoProxy/CMakeLists.txt +++ b/Tools/ProtoProxy/CMakeLists.txt @@ -40,8 +40,8 @@ set(SHARED_SRC ../../src/PolarSSL++/CtrDrbgContext.cpp ../../src/PolarSSL++/EntropyContext.cpp ../../src/PolarSSL++/RsaPrivateKey.cpp - ../../src/Listeners.cpp - ../../src/LogDispacher.cpp + ../../src/LoggerListeners.cpp + ../../src/Logger.cpp ) set(SHARED_HDR ../../src/ByteBuffer.h diff --git a/src/Bindings/ManualBindings.cpp b/src/Bindings/ManualBindings.cpp index d792cd0ee..e1e6585f0 100644 --- a/src/Bindings/ManualBindings.cpp +++ b/src/Bindings/ManualBindings.cpp @@ -168,7 +168,7 @@ static AString GetLogMessage(lua_State * tolua_S) static int tolua_LOG(lua_State * tolua_S) { // If the param is a cCompositeChat, read the log level from it: - Logger::eLogLevel LogLevel = Logger::llRegular; + cLogger::eLogLevel LogLevel = cLogger::llRegular; tolua_Error err; if (tolua_isusertype(tolua_S, 1, "cCompositeChat", false, &err)) { @@ -176,7 +176,7 @@ static int tolua_LOG(lua_State * tolua_S) } // Log the message: - Logger::GetInstance().LogSimple(GetLogMessage(tolua_S).c_str(), LogLevel); + cLogger::GetInstance().LogSimple(GetLogMessage(tolua_S).c_str(), LogLevel); return 0; } @@ -186,7 +186,7 @@ static int tolua_LOG(lua_State * tolua_S) static int tolua_LOGINFO(lua_State * tolua_S) { - Logger::GetInstance().LogSimple(GetLogMessage(tolua_S).c_str(), Logger::llInfo); + cLogger::GetInstance().LogSimple(GetLogMessage(tolua_S).c_str(), cLogger::llInfo); return 0; } @@ -196,7 +196,7 @@ static int tolua_LOGINFO(lua_State * tolua_S) static int tolua_LOGWARN(lua_State * tolua_S) { - Logger::GetInstance().LogSimple(GetLogMessage(tolua_S).c_str(), Logger::llWarning); + cLogger::GetInstance().LogSimple(GetLogMessage(tolua_S).c_str(), cLogger::llWarning); return 0; } @@ -206,7 +206,7 @@ static int tolua_LOGWARN(lua_State * tolua_S) static int tolua_LOGERROR(lua_State * tolua_S) { - Logger::GetInstance().LogSimple(GetLogMessage(tolua_S).c_str(), Logger::llError); + cLogger::GetInstance().LogSimple(GetLogMessage(tolua_S).c_str(), cLogger::llError); return 0; } diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index bca6a2eb0..8925c9be8 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -42,8 +42,8 @@ SET (SRCS LightingThread.cpp LineBlockTracer.cpp LinearInterpolation.cpp - Listeners.cpp - LogDispacher.cpp + LoggerListeners.cpp + Logger.cpp Map.cpp MapManager.cpp MobCensus.cpp @@ -108,7 +108,8 @@ SET (HDRS LineBlockTracer.h LinearInterpolation.h LinearUpscale.h - LogDispacher.h + Logger.h + LoggerListeners.h Map.h MapManager.h Matrix4.h diff --git a/src/CompositeChat.cpp b/src/CompositeChat.cpp index b702447be..0d339021e 100644 --- a/src/CompositeChat.cpp +++ b/src/CompositeChat.cpp @@ -353,23 +353,23 @@ AString cCompositeChat::ExtractText(void) const -Logger::eLogLevel cCompositeChat::MessageTypeToLogLevel(eMessageType a_MessageType) +cLogger::eLogLevel cCompositeChat::MessageTypeToLogLevel(eMessageType a_MessageType) { switch (a_MessageType) { - case mtCustom: return Logger::llRegular; - case mtFailure: return Logger::llWarning; - case mtInformation: return Logger::llInfo; - case mtSuccess: return Logger::llRegular; - case mtWarning: return Logger::llWarning; - case mtFatal: return Logger::llError; - case mtDeath: return Logger::llRegular; - case mtPrivateMessage: return Logger::llRegular; - case mtJoin: return Logger::llRegular; - case mtLeave: return Logger::llRegular; + case mtCustom: return cLogger::llRegular; + case mtFailure: return cLogger::llWarning; + case mtInformation: return cLogger::llInfo; + case mtSuccess: return cLogger::llRegular; + case mtWarning: return cLogger::llWarning; + case mtFatal: return cLogger::llError; + case mtDeath: return cLogger::llRegular; + case mtPrivateMessage: return cLogger::llRegular; + case mtJoin: return cLogger::llRegular; + case mtLeave: return cLogger::llRegular; } ASSERT(!"Unhandled MessageType"); - return Logger::llError; + return cLogger::llError; } diff --git a/src/CompositeChat.h b/src/CompositeChat.h index cc7c446c3..2dc21b98f 100644 --- a/src/CompositeChat.h +++ b/src/CompositeChat.h @@ -196,7 +196,7 @@ public: /** Converts the MessageType to a LogLevel value. Used by the logging bindings when logging a cCompositeChat object. */ - static Logger::eLogLevel MessageTypeToLogLevel(eMessageType a_MessageType); + static cLogger::eLogLevel MessageTypeToLogLevel(eMessageType a_MessageType); protected: /** All the parts that */ diff --git a/src/Globals.h b/src/Globals.h index ae7a68e7f..de1024010 100644 --- a/src/Globals.h +++ b/src/Globals.h @@ -249,7 +249,7 @@ template class SizeChecker; #include "OSSupport/Event.h" #include "OSSupport/Thread.h" #include "OSSupport/File.h" - #include "LogDispacher.h" + #include "Logger.h" #else // Logging functions void inline LOGERROR(const char* a_Format, ...) FORMATSTRING(1, 2); diff --git a/src/Listeners.cpp b/src/Listeners.cpp deleted file mode 100644 index 384dcaf91..000000000 --- a/src/Listeners.cpp +++ /dev/null @@ -1,236 +0,0 @@ - -#include "Globals.h" - -#include "Listeners.h" - -#if defined(_WIN32) - #include // Needed for _isatty(), not available on Linux -#elif defined(__linux) && !defined(ANDROID_NDK) - #include // Needed for isatty() on Linux -#elif defined(ANDROID_NDK) - #include -#endif - - -namespace Logger -{ - - #if defined(_WIN32) || (defined (__linux) && !defined(ANDROID_NDK)) - class cColouredConsoleListener - : public cLoggerListener - { - - virtual void SetLogColour(eLogLevel a_LogLevel) = 0; - virtual void SetDefaultLogColour() = 0; - - virtual void Log(AString a_Message, eLogLevel a_LogLevel) override - { - SetLogColour(a_LogLevel); - puts(a_Message.c_str()); - SetDefaultLogColour(); - } - }; - #endif - - #ifdef _WIN32 - class cWindowsConsoleListener - : public cColouredConsoleListener - { - public: - cWindowsConsoleListener(HANDLE a_Console, WORD a_DefaultConsoleAttrib) : - m_Console(a_Console), - m_DefaultConsoleAttrib(a_DefaultConsoleAttrib) - { - } - - #ifdef DEBUG - virtual void Log(AString a_Message, eLogLevel a_LogLevel) override - { - cColouredConsoleListener::Log(a_Message, a_LogLevel); - // In a Windows Debug build, output the log to debug console as well: - OutputDebugStringA(a_Message.c_str()); - } - #endif // _WIN32 - - - virtual void SetLogColour(eLogLevel a_LogLevel) override - { - // by default, gray on black - WORD Attrib = FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED; - switch (a_LogLevel) - { - case llRegular: - // Gray on black - Attrib = FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED; - break; - case llInfo: - // Yellow on black - Attrib = FOREGROUND_GREEN | ; - break; - case llWarning: - // Red on black - Attrib = FOREGROUND_RED | FOREGROUND_INTENSITY; - break; - case llError: - // Black on red - Attrib = BACKGROUND_RED | BACKGROUND_INTENSITY; - break; - } - SetConsoleTextAttribute(m_Console, Attrib); - } - virtual void SetDefaultLogColour() override - { - SetConsoleTextAttribute(m_Console, m_DefaultConsoleAttrib); - } - private: - HANDLE m_Console; - WORD m_DefaultConsoleAttrib; - }; - #elif defined (__linux) && !defined(ANDROID_NDK) - class cLinuxConsoleListener - : public cColouredConsoleListener - { - public: - virtual void SetLogColour(eLogLevel a_LogLevel) override - { - switch (a_LogLevel) - { - case llRegular: - // Whatever the console default is - printf("\x1b[0m"); - break; - case llInfo: - // Yellow on black - printf("\x1b[33;1m"); - break; - case llWarning: - // Red on black - printf("\x1b[31;1m"); - break; - case llError: - // Yellow on red - printf("\x1b[1;33;41;1m"); - break; - } - } - virtual void SetDefaultLogColour() override - { - // Whatever the console default is - printf("\x1b[0m"); - } - }; - #elif defined(ANDROID_NDK) - class cAndroidConsoleListener - : public cLoggerListener - { - public: - virtual void Log(AString a_Message, eLogLevel a_LogLevel) override - { - android_LogPriority AndroidLogLevel; - switch (a_LogLevel) - { - case llRegular: - AndroidLogLevel = ANDROID_LOG_VERBOSE; - break; - case llInfo: - AndroidLogLevel = ANDROID_LOG_INFO; - break; - case llWarning: - AndroidLogLevel = ANDROID_LOG_WARNING; - break; - case llError: - AndroidLogLevel = ANDROID_LOG_ERROR; - break; - } - __android_log_print(AndroidLogLevel, "MCServer", "%s", a_Message.c_str()); - } - }; - #endif - - class cVanillaCPPConsoleListener - : public cLoggerListener - { - public: - virtual void Log(AString a_Message, eLogLevel a_LogLevel) override - { - AString LogLevelString; - switch (a_LogLevel) - { - case llRegular: - LogLevelString = "Log"; - break; - case llInfo: - LogLevelString = "Info"; - break; - case llWarning: - LogLevelString = "Warning"; - break; - case llError: - LogLevelString = "Error"; - break; - } - printf("%s: %s", LogLevelString.c_str(), a_Message.c_str()); - } - }; - - - - cLoggerListener * MakeConsoleListener() - { - #ifdef _WIN32 - // See whether we are writing to a console the default console attrib: - bool ShouldColorOutput = (_isatty(_fileno(stdin)) != 0); - if (ShouldColorOutput) - { - CONSOLE_SCREEN_BUFFER_INFO sbi; - HANDLE Console = getStdHandle(STD_OUTPUT_HANDLE); - GetConsoleScreenBufferInfo(Console, &sbi); - WORD DefaultConsoleAttrib = sbi.wAttributes; - return new cWindowsConsoleListener(Console, DefaultConsoleAttrib); - } else { - return new cVanillaCPPConsoleListener(); - } - - #elif defined (__linux) && !defined(ANDROID_NDK) - // TODO: lookup terminal in terminfo - if (isatty(fileno(stdout))) - { - return new cLinuxConsoleListener(); - } else { - return new cVanillaCPPConsoleListener(); - } - #else - return new cVanillaCPPConsoleListener(); - #endif - } - - cFileListener::cFileListener() - { - cFile::CreateFolder(FILE_IO_PREFIX + AString("logs")); - AString FileName; - FileName = Printf("%s%sLOG_%d.txt", FILE_IO_PREFIX, "logs/", (int)time(NULL)); - m_File.Open(FileName, cFile::fmAppend); - } - - void cFileListener::Log(AString a_Message, eLogLevel a_LogLevel) - { - AString LogLevelString; - switch (a_LogLevel) - { - case llRegular: - LogLevelString = "Log"; - break; - case llInfo: - LogLevelString = "Info"; - break; - case llWarning: - LogLevelString = "Warning"; - break; - case llError: - LogLevelString = "Error"; - break; - } - m_File.Printf("%s: %s", LogLevelString.c_str(), a_Message.c_str()); - } - -} diff --git a/src/Listeners.h b/src/Listeners.h deleted file mode 100644 index bc29d0c06..000000000 --- a/src/Listeners.h +++ /dev/null @@ -1,21 +0,0 @@ - -#include "LogDispacher.h" - -namespace Logger -{ - - class cFileListener - : public cLoggerListener - { - public: - - cFileListener(); - cFileListener(AString a_Filename); - - virtual void Log(AString a_Message, eLogLevel a_LogLevel) override; - private: - cFile m_File; - }; - - cLoggerListener * MakeConsoleListener(); -} diff --git a/src/LogDispacher.cpp b/src/LogDispacher.cpp deleted file mode 100644 index abca6a898..000000000 --- a/src/LogDispacher.cpp +++ /dev/null @@ -1,114 +0,0 @@ - -#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules - -#include "OSSupport/IsThread.h" - - - -namespace Logger -{ - - cLogDispacher & GetInstance(void) - { - static cLogDispacher Instance; - return Instance; - } - - void InitiateMultithreading() - { - GetInstance(); - } - - void cLogDispacher::LogSimple(AString a_Message, eLogLevel a_LogLevel) - { - time_t rawtime; - time ( &rawtime); - - struct tm* timeinfo; - #ifdef _MSC_VER - struct tm timeinforeal; - timeinfo = &timeinforeal; - localtime_s(timeinfo, &rawtime); - #else - timeinfo = localtime( &rawtime); - #endif - - AString Line; - #ifdef _DEBUG - Printf(Line, "[%04lx|%02d:%02d:%02d] %s\n", cIsThread::GetCurrentID(), timeinfo->tm_hour, timeinfo->tm_min, timeinfo->tm_sec, a_Message.c_str()); - #else - Printf(Line, "[%02d:%02d:%02d] %s\n", timeinfo->tm_hour, timeinfo->tm_min, timeinfo->tm_sec, a_Message.c_str()); - #endif - - - cCSLock Lock(m_CriticalSection); - for(size_t i = 0; i < m_LogListeners.size(); i++) - { - m_LogListeners[i]->Log(a_Message, a_LogLevel); - } - } - - - - - - void cLogDispacher::Log(const char * a_Format, eLogLevel a_LogLevel, va_list a_ArgList) - { - AString Message; - AppendVPrintf(Message, a_Format, a_ArgList); - LogSimple(Message, a_LogLevel); - } - - void cLogDispacher::AttachListener(Logger::cLoggerListener * a_Listener) - { - cCSLock Lock(m_CriticalSection); - m_LogListeners.push_back(a_Listener); - } - - void cLogDispacher::DetachListener(Logger::cLoggerListener * a_Listener) - { - cCSLock Lock(m_CriticalSection); - m_LogListeners.erase(std::remove(m_LogListeners.begin(), m_LogListeners.end(), a_Listener)); - } -}; - - - -//////////////////////////////////////////////////////////////////////////////// -// Global functions - -void LOG(const char* a_Format, ...) -{ - va_list argList; - va_start(argList, a_Format); - Logger::GetInstance().Log(a_Format, Logger::llRegular, argList); - va_end(argList); -} - -void LOGINFO(const char* a_Format, ...) -{ - va_list argList; - va_start(argList, a_Format); - Logger::GetInstance().Log( a_Format, Logger::llInfo, argList); - va_end(argList); -} - -void LOGWARN(const char* a_Format, ...) -{ - va_list argList; - va_start(argList, a_Format); - Logger::GetInstance().Log( a_Format, Logger::llWarning, argList); - va_end(argList); -} - -void LOGERROR(const char* a_Format, ...) -{ - va_list argList; - va_start(argList, a_Format); - Logger::GetInstance().Log( a_Format, Logger::llError, argList); - va_end(argList); -} - - - - diff --git a/src/Logger.cpp b/src/Logger.cpp new file mode 100644 index 000000000..e0ea973f8 --- /dev/null +++ b/src/Logger.cpp @@ -0,0 +1,109 @@ + +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "OSSupport/IsThread.h" + + +cLogger & cLogger::GetInstance(void) +{ + static cLogger Instance; + return Instance; +} + +void cLogger::InitiateMultithreading() +{ + GetInstance(); +} + +void cLogger::LogSimple(AString a_Message, eLogLevel a_LogLevel) +{ + time_t rawtime; + time ( &rawtime); + + struct tm* timeinfo; + #ifdef _MSC_VER + struct tm timeinforeal; + timeinfo = &timeinforeal; + localtime_s(timeinfo, &rawtime); + #else + timeinfo = localtime( &rawtime); + #endif + + AString Line; + #ifdef _DEBUG + Printf(Line, "[%04lx|%02d:%02d:%02d] %s\n", cIsThread::GetCurrentID(), timeinfo->tm_hour, timeinfo->tm_min, timeinfo->tm_sec, a_Message.c_str()); + #else + Printf(Line, "[%02d:%02d:%02d] %s\n", timeinfo->tm_hour, timeinfo->tm_min, timeinfo->tm_sec, a_Message.c_str()); + #endif + + + cCSLock Lock(m_CriticalSection); + for(size_t i = 0; i < m_LogListeners.size(); i++) + { + m_LogListeners[i]->Log(a_Message, a_LogLevel); + } +} + + + + + +void cLogger::Log(const char * a_Format, eLogLevel a_LogLevel, va_list a_ArgList) +{ + AString Message; + AppendVPrintf(Message, a_Format, a_ArgList); + LogSimple(Message, a_LogLevel); +} + +void cLogger::AttachListener(cListener * a_Listener) +{ + cCSLock Lock(m_CriticalSection); + m_LogListeners.push_back(a_Listener); +} + +void cLogger::DetachListener(cListener * a_Listener) +{ + cCSLock Lock(m_CriticalSection); + m_LogListeners.erase(std::remove(m_LogListeners.begin(), m_LogListeners.end(), a_Listener)); +} + + + +//////////////////////////////////////////////////////////////////////////////// +// Global functions + +void LOG(const char* a_Format, ...) +{ + va_list argList; + va_start(argList, a_Format); + cLogger::GetInstance().Log(a_Format, cLogger::llRegular, argList); + va_end(argList); +} + +void LOGINFO(const char* a_Format, ...) +{ + va_list argList; + va_start(argList, a_Format); + cLogger::GetInstance().Log( a_Format, cLogger::llInfo, argList); + va_end(argList); +} + +void LOGWARN(const char* a_Format, ...) +{ + va_list argList; + va_start(argList, a_Format); + cLogger::GetInstance().Log( a_Format, cLogger::llWarning, argList); + va_end(argList); +} + +void LOGERROR(const char* a_Format, ...) +{ + va_list argList; + va_start(argList, a_Format); + cLogger::GetInstance().Log( a_Format, cLogger::llError, argList); + va_end(argList); +} + + + + diff --git a/src/LogDispacher.h b/src/Logger.h similarity index 51% rename from src/LogDispacher.h rename to src/Logger.h index 1472b392a..5e65de8a8 100644 --- a/src/LogDispacher.h +++ b/src/Logger.h @@ -2,8 +2,9 @@ #pragma once -namespace Logger +class cLogger { +public: enum eLogLevel { @@ -13,41 +14,32 @@ namespace Logger llError, }; - class cLogDispacher; - // Must be called before calling GetInstance in a multithreaded context - void InitiateMultithreading(); - - cLogDispacher & GetInstance(void); - - class cLoggerListener + class cListener { public: virtual void Log(AString a_Message, eLogLevel a_LogLevel) = 0; - - virtual ~cLoggerListener(){} + + virtual ~cListener(){} }; - class cLogDispacher - { - public: + void Log (const char * a_Format, eLogLevel a_LogLevel, va_list a_ArgList) FORMATSTRING(2, 0); - void Log (const char * a_Format, Logger::eLogLevel a_LogLevel, va_list a_ArgList) FORMATSTRING(2, 0); + /** Logs the simple text message at the specified log level. */ + void LogSimple(AString a_Message, eLogLevel a_LogLevel = llRegular); - /** Logs the simple text message at the specified log level. */ - void LogSimple(AString a_Message, Logger::eLogLevel a_LogLevel = Logger::llRegular); + void AttachListener(cListener * a_Listener); + void DetachListener(cListener * a_Listener); - void AttachListener(Logger::cLoggerListener * a_Listener); - void DetachListener(Logger::cLoggerListener * a_Listener); + static cLogger & GetInstance(void); + // Must be called before calling GetInstance in a multithreaded context + static void InitiateMultithreading(); +private: - private: - - cCriticalSection m_CriticalSection; - std::vector m_LogListeners; - - }; + cCriticalSection m_CriticalSection; + std::vector m_LogListeners; -} +}; diff --git a/src/LoggerListeners.cpp b/src/LoggerListeners.cpp new file mode 100644 index 000000000..d6567abe0 --- /dev/null +++ b/src/LoggerListeners.cpp @@ -0,0 +1,231 @@ + +#include "Globals.h" + +#include "LoggerListeners.h" + +#if defined(_WIN32) + #include // Needed for _isatty(), not available on Linux +#elif defined(__linux) && !defined(ANDROID_NDK) + #include // Needed for isatty() on Linux +#elif defined(ANDROID_NDK) + #include +#endif + + +#if defined(_WIN32) || (defined (__linux) && !defined(ANDROID_NDK)) + class cColouredConsoleListener + : public cLogger::cListener + { + + virtual void SetLogColour(cLogger::eLogLevel a_LogLevel) = 0; + virtual void SetDefaultLogColour() = 0; + + virtual void Log(AString a_Message, cLogger::eLogLevel a_LogLevel) override + { + SetLogColour(a_LogLevel); + puts(a_Message.c_str()); + SetDefaultLogColour(); + } + }; +#endif + +#ifdef _WIN32 + class cWindowsConsoleListener + : public cColouredConsoleListener + { + public: + cWindowsConsoleListener(HANDLE a_Console, WORD a_DefaultConsoleAttrib) : + m_Console(a_Console), + m_DefaultConsoleAttrib(a_DefaultConsoleAttrib) + { + } + + #ifdef DEBUG + virtual void Log(AString a_Message, cLogger::eLogLevel a_LogLevel) override + { + cColouredConsoleListener::Log(a_Message, a_LogLevel); + // In a Windows Debug build, output the log to debug console as well: + OutputDebugStringA(a_Message.c_str()); + } + #endif + + + virtual void SetLogColour(cLogger::eLogLevel a_LogLevel) override + { + // by default, gray on black + WORD Attrib = FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED; + switch (a_LogLevel) + { + case cLogger::llRegular: + // Gray on black + Attrib = FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED; + break; + case cLogger::llInfo: + // Yellow on black + Attrib = FOREGROUND_GREEN | ; + break; + case cLogger::llWarning: + // Red on black + Attrib = FOREGROUND_RED | FOREGROUND_INTENSITY; + break; + case cLogger::llError: + // Black on red + Attrib = BACKGROUND_RED | BACKGROUND_INTENSITY; + break; + } + SetConsoleTextAttribute(m_Console, Attrib); + } + virtual void SetDefaultLogColour() override + { + SetConsoleTextAttribute(m_Console, m_DefaultConsoleAttrib); + } + private: + HANDLE m_Console; + WORD m_DefaultConsoleAttrib; + }; +#elif defined (__linux) && !defined(ANDROID_NDK) + class cLinuxConsoleListener + : public cColouredConsoleListener + { + public: + virtual void SetLogColour(cLogger::eLogLevel a_LogLevel) override + { + switch (a_LogLevel) + { + case cLogger::llRegular: + // Whatever the console default is + printf("\x1b[0m"); + break; + case cLogger::llInfo: + // Yellow on black + printf("\x1b[33;1m"); + break; + case cLogger::llWarning: + // Red on black + printf("\x1b[31;1m"); + break; + case cLogger::llError: + // Yellow on red + printf("\x1b[1;33;41;1m"); + break; + } + } + virtual void SetDefaultLogColour() override + { + // Whatever the console default is + printf("\x1b[0m"); + } + }; +#elif defined(ANDROID_NDK) + class cAndroidConsoleListener + : public cLogger::cListener + { + public: + virtual void Log(AString a_Message, cLogger::eLogLevel a_LogLevel) override + { + android_LogPriority AndroidLogLevel; + switch (a_LogLevel) + { + case cLogger::llRegular: + AndroidLogLevel = ANDROID_LOG_VERBOSE; + break; + case cLogger::llInfo: + AndroidLogLevel = ANDROID_LOG_INFO; + break; + case cLogger::llWarning: + AndroidLogLevel = ANDROID_LOG_WARNING; + break; + case cLogger::llError: + AndroidLogLevel = ANDROID_LOG_ERROR; + break; + } + __android_log_print(AndroidLogLevel, "MCServer", "%s", a_Message.c_str()); + } + }; +#endif + +class cVanillaCPPConsoleListener + : public cLogger::cListener +{ +public: + virtual void Log(AString a_Message, cLogger::eLogLevel a_LogLevel) override + { + AString LogLevelString; + switch (a_LogLevel) + { + case cLogger::llRegular: + LogLevelString = "Log"; + break; + case cLogger::llInfo: + LogLevelString = "Info"; + break; + case cLogger::llWarning: + LogLevelString = "Warning"; + break; + case cLogger::llError: + LogLevelString = "Error"; + break; + } + printf("%s: %s", LogLevelString.c_str(), a_Message.c_str()); + } +}; + + + +cLogger::cListener * MakeConsoleListener() +{ + #ifdef _WIN32 + // See whether we are writing to a console the default console attrib: + bool ShouldColorOutput = (_isatty(_fileno(stdin)) != 0); + if (ShouldColorOutput) + { + CONSOLE_SCREEN_BUFFER_INFO sbi; + HANDLE Console = getStdHandle(STD_OUTPUT_HANDLE); + GetConsoleScreenBufferInfo(Console, &sbi); + WORD DefaultConsoleAttrib = sbi.wAttributes; + return new cWindowsConsoleListener(Console, DefaultConsoleAttrib); + } else { + return new cVanillaCPPConsoleListener(); + } + + #elif defined (__linux) && !defined(ANDROID_NDK) + // TODO: lookup terminal in terminfo + if (isatty(fileno(stdout))) + { + return new cLinuxConsoleListener(); + } else { + return new cVanillaCPPConsoleListener(); + } + #else + return new cVanillaCPPConsoleListener(); + #endif +} + +cFileListener::cFileListener() +{ + cFile::CreateFolder(FILE_IO_PREFIX + AString("logs")); + AString FileName; + FileName = Printf("%s%sLOG_%d.txt", FILE_IO_PREFIX, "logs/", (int)time(NULL)); + m_File.Open(FileName, cFile::fmAppend); +} + +void cFileListener::Log(AString a_Message, cLogger::eLogLevel a_LogLevel) +{ + AString LogLevelString; + switch (a_LogLevel) + { + case cLogger::llRegular: + LogLevelString = "Log"; + break; + case cLogger::llInfo: + LogLevelString = "Info"; + break; + case cLogger::llWarning: + LogLevelString = "Warning"; + break; + case cLogger::llError: + LogLevelString = "Error"; + break; + } + m_File.Printf("%s: %s", LogLevelString.c_str(), a_Message.c_str()); +} diff --git a/src/LoggerListeners.h b/src/LoggerListeners.h new file mode 100644 index 000000000..4d2889a93 --- /dev/null +++ b/src/LoggerListeners.h @@ -0,0 +1,17 @@ + +#include "Logger.h" + +class cFileListener + : public cLogger::cListener +{ + public: + + cFileListener(); + cFileListener(AString a_Filename); + + virtual void Log(AString a_Message, cLogger::eLogLevel a_LogLevel) override; + private: + cFile m_File; +}; + +cLogger::cListener * MakeConsoleListener(); diff --git a/src/Root.cpp b/src/Root.cpp index 72048b631..ee0d9b835 100644 --- a/src/Root.cpp +++ b/src/Root.cpp @@ -18,7 +18,7 @@ #include "CommandOutput.h" #include "DeadlockDetect.h" #include "OSSupport/Timer.h" -#include "Listeners.h" +#include "LoggerListeners.h" #include "inifile/iniFile.h" @@ -106,10 +106,10 @@ void cRoot::Start(void) EnableMenuItem(hmenu, SC_CLOSE, MF_GRAYED); // Disable close button when starting up; it causes problems with our CTRL-CLOSE handling #endif - Logger::cLoggerListener * consoleLogListener = Logger::MakeConsoleListener(); - Logger::cLoggerListener * fileLogListener = new Logger::cFileListener(); - Logger::GetInstance().AttachListener(consoleLogListener); - Logger::GetInstance().AttachListener(fileLogListener); + cLogger::cListener * consoleLogListener = MakeConsoleListener(); + cLogger::cListener * fileLogListener = new cFileListener(); + cLogger::GetInstance().AttachListener(consoleLogListener); + cLogger::GetInstance().AttachListener(fileLogListener); LOG("--- Started Log ---\n"); @@ -257,9 +257,9 @@ void cRoot::Start(void) LOG("--- Stopped Log ---"); - Logger::GetInstance().DetachListener(consoleLogListener); + cLogger::GetInstance().DetachListener(consoleLogListener); delete consoleLogListener; - Logger::GetInstance().DetachListener(fileLogListener); + cLogger::GetInstance().DetachListener(fileLogListener); delete fileLogListener; } diff --git a/src/main.cpp b/src/main.cpp index e40035538..86ecd4000 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -273,7 +273,7 @@ int main( int argc, char **argv) } } // for i - argv[] - Logger::InitiateMultithreading(); + cLogger::InitiateMultithreading(); #if !defined(ANDROID_NDK) try