1
0
mirror of https://github.com/VCMP-SqMod/SqMod.git synced 2024-11-08 08:47:17 +01:00
SqMod/source/Logger.cpp
Sandu Liviu Catalin 6ed02d0fd4 Initial commit.
2015-09-30 03:56:11 +03:00

382 lines
11 KiB
C++

#include "Logger.hpp"
// ------------------------------------------------------------------------------------------------
#include <ctime>
#include <cstdio>
#include <cstdarg>
// ------------------------------------------------------------------------------------------------
namespace {
#ifdef SQMOD_OS_WINDOWS
#include <Windows.h>
enum
{
LOG_COLOR_NORMAL = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE,
LOG_COLOR_WHITE = FOREGROUND_INTENSITY | FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE,
LOG_COLOR_GRAY = FOREGROUND_INTENSITY,
LOG_COLOR_LIGHT_BLUE = FOREGROUND_INTENSITY | FOREGROUND_BLUE,
LOG_COLOR_DARK_BLUE = FOREGROUND_BLUE,
LOG_COLOR_LIGHT_GREEN = FOREGROUND_INTENSITY | FOREGROUND_GREEN,
LOG_COLOR_DARK_GREEN = FOREGROUND_GREEN,
LOG_COLOR_LIGHT_CYAN = FOREGROUND_INTENSITY | FOREGROUND_GREEN | FOREGROUND_BLUE,
LOG_COLOR_DARK_CYAN = FOREGROUND_GREEN | FOREGROUND_BLUE,
LOG_COLOR_LIGHT_YELLOW = FOREGROUND_INTENSITY | FOREGROUND_RED | FOREGROUND_GREEN,
LOG_COLOR_DARK_YELLOW = FOREGROUND_RED | FOREGROUND_GREEN,
LOG_COLOR_LIGHT_RED = FOREGROUND_INTENSITY | FOREGROUND_RED,
LOG_COLOR_DARK_RED = FOREGROUND_RED,
LOG_COLOR_LIGHT_MAGENTA = FOREGROUND_INTENSITY | FOREGROUND_RED | FOREGROUND_BLUE,
LOG_COLOR_DARK_MAGENTA = FOREGROUND_RED | FOREGROUND_BLUE
};
enum
{
LOG_COLOR_DBG = LOG_COLOR_LIGHT_BLUE,
LOG_COLOR_MSG = LOG_COLOR_GRAY,
LOG_COLOR_SCS = LOG_COLOR_LIGHT_GREEN,
LOG_COLOR_INF = LOG_COLOR_LIGHT_CYAN,
LOG_COLOR_WRN = LOG_COLOR_LIGHT_YELLOW,
LOG_COLOR_ERR = LOG_COLOR_LIGHT_MAGENTA,
LOG_COLOR_FTL = LOG_COLOR_LIGHT_RED
};
#endif // SQMOD_OS_WINDOWS
} // Namespace::
// ------------------------------------------------------------------------------------------------
namespace SqMod {
// ------------------------------------------------------------------------------------------------
const Logger::Pointer _Log = Logger::Inst();
// ------------------------------------------------------------------------------------------------
inline const char * GetLevelTag(Uint8 type) noexcept
{
switch (type)
{
case Logger::LEVEL_DBG: return "[DBG]";
case Logger::LEVEL_MSG: return "[MSG]";
case Logger::LEVEL_SCS: return "[SCS]";
case Logger::LEVEL_INF: return "[INF]";
case Logger::LEVEL_WRN: return "[WRN]";
case Logger::LEVEL_ERR: return "[ERR]";
case Logger::LEVEL_FTL: return "[FTL]";
default: return "[UNK]";
}
}
#ifdef SQMOD_OS_WINDOWS
// ------------------------------------------------------------------------------------------------
inline Uint16 GetLevelColor(Uint8 type) noexcept
{
switch (type)
{
case Logger::LEVEL_DBG: return LOG_COLOR_DBG;
case Logger::LEVEL_MSG: return LOG_COLOR_MSG;
case Logger::LEVEL_SCS: return LOG_COLOR_SCS;
case Logger::LEVEL_INF: return LOG_COLOR_INF;
case Logger::LEVEL_WRN: return LOG_COLOR_WRN;
case Logger::LEVEL_ERR: return LOG_COLOR_ERR;
case Logger::LEVEL_FTL: return LOG_COLOR_FTL;
default: return LOG_COLOR_NORMAL;
}
}
#else
// ------------------------------------------------------------------------------------------------
inline const char * GetLevelColor(Uint8 type) noexcept
{
return "";
}
#endif // SQMOD_OS_WINDOWS
// ------------------------------------------------------------------------------------------------
Logger::Logger() noexcept
: m_ConsoleTime(false), m_FileTime(true)
, m_ConsoleLevels(Logger::LEVEL_ANY), m_FileLevels(Logger::LEVEL_ANY)
, m_LogPath("./logs/"), m_DebugLevel(SQMOD_DEBUG_LEVEL), m_Verbosity(0)
{
}
// ------------------------------------------------------------------------------------------------
Logger::~Logger()
{
}
// ------------------------------------------------------------------------------------------------
void Logger::_Finalizer(Logger * ptr) noexcept
{
if (ptr) delete ptr;
}
// ------------------------------------------------------------------------------------------------
Logger::Pointer Logger::Inst() noexcept
{
if (!_Log) return Pointer(new Logger(), &Logger::_Finalizer);
return Pointer(nullptr, &Logger::_Finalizer);
}
// ------------------------------------------------------------------------------------------------
bool Logger::Init()
{
return true;
}
bool Logger::Load()
{
return true;
}
// ------------------------------------------------------------------------------------------------
void Logger::Deinit()
{
}
void Logger::Unload()
{
}
// ------------------------------------------------------------------------------------------------
void Logger::Terminate()
{
}
// ------------------------------------------------------------------------------------------------
void Logger::ToggleConsoleTime(bool enabled) noexcept
{
m_ConsoleTime = enabled;
}
void Logger::ToggleFileTime(bool enabled) noexcept
{
m_FileTime = enabled;
}
// ------------------------------------------------------------------------------------------------
bool Logger::HasConsoleTime() const noexcept
{
return m_ConsoleTime;
}
bool Logger::HasFileTime()const noexcept
{
return m_FileTime;
}
// ------------------------------------------------------------------------------------------------
void Logger::SetConsoleLevels(Uint8 levels) noexcept
{
m_ConsoleLevels = levels;
}
void Logger::SetFileLevels(Uint8 levels) noexcept
{
m_FileLevels = levels;
}
// ------------------------------------------------------------------------------------------------
Uint8 Logger::GetConsoleLevels() const noexcept
{
return m_ConsoleLevels;
}
Uint8 Logger::GetFileLevels() const noexcept
{
return m_FileLevels;
}
// ------------------------------------------------------------------------------------------------
void Logger::EnableConsoleLevel(Uint8 level) noexcept
{
m_ConsoleLevels |= level;
}
void Logger::EnableFileLevel(Uint8 level) noexcept
{
m_FileLevels |= level;
}
// ------------------------------------------------------------------------------------------------
void Logger::DisableConsoleLevel(Uint8 level) noexcept
{
if (m_ConsoleLevels & level) m_ConsoleLevels ^= level;
}
void Logger::DisableFileLevel(Uint8 level) noexcept
{
if (m_FileLevels & level) m_FileLevels ^= level;
}
// ------------------------------------------------------------------------------------------------
Uint8 Logger::GetDebugLevel() const noexcept
{
return m_DebugLevel;
}
void Logger::SetDebugLevel(Uint8 level) noexcept
{
m_DebugLevel = level;
}
// ------------------------------------------------------------------------------------------------
SQInt32 Logger::GetVerbosity() const noexcept
{
return m_Verbosity;
}
void Logger::SetVerbosity(SQInt32 level) noexcept
{
m_Verbosity = level;
}
// ------------------------------------------------------------------------------------------------
void Logger::Send(Uint8 type, bool sub, const char * fmt, va_list args) noexcept
{
// Verify that this level is allowed to be streamed
if (!(m_ConsoleLevels & type) && !(m_FileLevels & type)) return;
// Allocate space for the time stamp string
char timebuff[80];
// Grab the local time into a string if required
if (m_ConsoleTime || m_FileTime)
{
// Create the variables required to retrieve the time.
time_t rawtime;
struct tm * timeinfo;
// Retrieve the local time.
time(&rawtime);
timeinfo = localtime(&rawtime);
// Format the retrieved time.
strftime(timebuff, 80, "%Y-%m-%d %H:%M:%S", timeinfo);
}
// Output to console if streaming to console is enabled
if (m_ConsoleLevels & type)
{
#ifdef SQMOD_OS_WINDOWS
// Get the handle to the output stream
HANDLE hstdout = GetStdHandle(STD_OUTPUT_HANDLE);
// Save the current state of the console screen buffer
CONSOLE_SCREEN_BUFFER_INFO csb_state;
GetConsoleScreenBufferInfo(hstdout, &csb_state);
// Set the attributes for the message information
SetConsoleTextAttribute(hstdout, GetLevelColor(type));
// Output the message information
if (m_ConsoleTime)
{
printf("%s %s ", GetLevelTag(type), timebuff);
}
else
{
printf("%s ", GetLevelTag(type));
}
// Set the attributes for the message content
SetConsoleTextAttribute(hstdout, sub ? LOG_COLOR_NORMAL : LOG_COLOR_WHITE);
// Print the specified message
vprintf(fmt, args);
// Restore the state of the console screen buffer
SetConsoleTextAttribute(hstdout, csb_state.wAttributes);
#else
// Output the message information
if (m_ConsoleTime)
{
printf("%s %s ", GetLevelTag(type), timebuff);
}
else
{
printf("%s ", GetLevelTag(type));
}
// Print the specified message
vprintf(fmt, args);
#endif // SQMOD_OS_WINDOWS
// Terminate the line
puts("");
}
}
// ------------------------------------------------------------------------------------------------
#define SQMOD_LOG(N_, L_, S_) /*
*/ void Logger::N_(const char * fmt, ...) noexcept /*
*/ { /*
*/ va_list args; /*
*/ va_start(args, fmt); /*
*/ Send(L_, S_, fmt, args); /*
*/ va_end(args); /*
*/ } /*
*/
// ------------------------------------------------------------------------------------------------
SQMOD_LOG(Dbg, LEVEL_DBG, false)
SQMOD_LOG(Msg, LEVEL_MSG, false)
SQMOD_LOG(Scs, LEVEL_SCS, false)
SQMOD_LOG(Inf, LEVEL_INF, false)
SQMOD_LOG(Wrn, LEVEL_WRN, false)
SQMOD_LOG(Err, LEVEL_ERR, false)
SQMOD_LOG(Ftl, LEVEL_FTL, false)
// ------------------------------------------------------------------------------------------------
SQMOD_LOG(SDbg, LEVEL_DBG, true)
SQMOD_LOG(SMsg, LEVEL_MSG, true)
SQMOD_LOG(SScs, LEVEL_SCS, true)
SQMOD_LOG(SInf, LEVEL_INF, true)
SQMOD_LOG(SWrn, LEVEL_WRN, true)
SQMOD_LOG(SErr, LEVEL_ERR, true)
SQMOD_LOG(SFtl, LEVEL_FTL, true)
// ------------------------------------------------------------------------------------------------
#define SQMOD_CLOG(N_, L_, S_) /*
*/bool Logger::N_(bool c, const char * fmt, ...) noexcept /*
*/ { /*
*/ if (c) /*
*/ { /*
*/ va_list args; /*
*/ va_start(args, fmt); /*
*/ Send(L_, S_, fmt, args); /*
*/ va_end(args); /*
*/ } /*
*/ return c; /*
*/ } /*
*/
// ------------------------------------------------------------------------------------------------
SQMOD_CLOG(cDbg, LEVEL_DBG, false)
SQMOD_CLOG(cMsg, LEVEL_MSG, false)
SQMOD_CLOG(cScs, LEVEL_SCS, false)
SQMOD_CLOG(cInf, LEVEL_INF, false)
SQMOD_CLOG(cWrn, LEVEL_WRN, false)
SQMOD_CLOG(cErr, LEVEL_ERR, false)
SQMOD_CLOG(cFtl, LEVEL_FTL, false)
// ------------------------------------------------------------------------------------------------
SQMOD_CLOG(cSDbg, LEVEL_DBG, true)
SQMOD_CLOG(cSMsg, LEVEL_MSG, true)
SQMOD_CLOG(cSScs, LEVEL_SCS, true)
SQMOD_CLOG(cSInf, LEVEL_INF, true)
SQMOD_CLOG(cSWrn, LEVEL_WRN, true)
SQMOD_CLOG(cSErr, LEVEL_ERR, true)
SQMOD_CLOG(cSFtl, LEVEL_FTL, true)
} // Namespace:: SqMod