Core/Logging: Minor internal refactor

* Avoid formatting to output with fprintf
* Use vector instead of unordered_map to store appenders in Logger
This commit is contained in:
Shauren
2024-07-16 16:31:40 +02:00
parent 14f7c0984f
commit 81bec6954f
13 changed files with 82 additions and 67 deletions

View File

@@ -18,12 +18,11 @@
#include "Appender.h"
#include "LogMessage.h"
#include "StringFormat.h"
#include <sstream>
Appender::Appender(uint8 _id, std::string const& _name, LogLevel _level /* = LOG_LEVEL_DISABLED */, AppenderFlags _flags /* = APPENDER_FLAGS_NONE */):
id(_id), name(_name), level(_level), flags(_flags) { }
Appender::Appender(uint8 _id, std::string _name, LogLevel _level /* = LOG_LEVEL_DISABLED */, AppenderFlags _flags /* = APPENDER_FLAGS_NONE */):
id(_id), name(std::move(_name)), level(_level), flags(_flags) { }
Appender::~Appender() { }
Appender::~Appender() = default;
uint8 Appender::getId() const
{
@@ -55,18 +54,28 @@ void Appender::write(LogMessage* message)
if (!level || level > message->level)
return;
std::ostringstream ss;
if (flags & (APPENDER_FLAGS_PREFIX_TIMESTAMP | APPENDER_FLAGS_PREFIX_LOGLEVEL | APPENDER_FLAGS_PREFIX_LOGFILTERTYPE))
{
message->prefix.reserve(100);
message->prefix.clear();
if (flags & APPENDER_FLAGS_PREFIX_TIMESTAMP)
ss << message->getTimeStr() << ' ';
if (flags & APPENDER_FLAGS_PREFIX_TIMESTAMP)
{
message->prefix.append(message->getTimeStr());
message->prefix.append(1, ' ');
}
if (flags & APPENDER_FLAGS_PREFIX_LOGLEVEL)
ss << Trinity::StringFormat("{:<5} ", Appender::getLogLevelString(message->level));
if (flags & APPENDER_FLAGS_PREFIX_LOGLEVEL)
Trinity::StringFormatTo(std::back_inserter(message->prefix), "{:<5} ", getLogLevelString(message->level));
if (flags & APPENDER_FLAGS_PREFIX_LOGFILTERTYPE)
ss << '[' << message->type << "] ";
if (flags & APPENDER_FLAGS_PREFIX_LOGFILTERTYPE)
{
message->prefix.append(1, '[');
message->prefix.append(message->type);
message->prefix.append("] ", 2);
}
}
message->prefix = ss.str();
_write(message);
}

View File

@@ -22,14 +22,17 @@
#include "LogCommon.h"
#include <stdexcept>
#include <string>
#include <vector>
struct LogMessage;
class TC_COMMON_API Appender
{
public:
Appender(uint8 _id, std::string const& name, LogLevel level = LOG_LEVEL_DISABLED, AppenderFlags flags = APPENDER_FLAGS_NONE);
Appender(uint8 _id, std::string name, LogLevel level = LOG_LEVEL_DISABLED, AppenderFlags flags = APPENDER_FLAGS_NONE);
Appender(Appender const&) = delete;
Appender(Appender&&) = delete;
Appender& operator=(Appender const&) = delete;
Appender& operator=(Appender&&) = delete;
virtual ~Appender();
uint8 getId() const;

View File

@@ -18,22 +18,21 @@
#include "AppenderConsole.h"
#include "LogMessage.h"
#include "SmartEnum.h"
#include "StringFormat.h"
#include "StringConvert.h"
#include "StringFormat.h"
#include "Util.h"
#if TRINITY_PLATFORM == TRINITY_PLATFORM_WINDOWS
#include <Windows.h>
#endif
AppenderConsole::AppenderConsole(uint8 id, std::string const& name, LogLevel level, AppenderFlags flags, std::vector<std::string_view> const& args)
: Appender(id, name, level, flags), _colored(false)
AppenderConsole::AppenderConsole(uint8 id, std::string name, LogLevel level, AppenderFlags flags, std::vector<std::string_view> const& args)
: Appender(id, std::move(name), level, flags), _colored(false)
{
for (uint8 i = 0; i < NUM_ENABLED_LOG_LEVELS; ++i)
_colors[i] = ColorTypes(NUM_COLOR_TYPES);
std::ranges::fill(_colors, NUM_COLOR_TYPES);
if (3 < args.size())
InitColors(name, args[3]);
if (args.size() > 3)
InitColors(getName(), args[3]);
}
void AppenderConsole::InitColors(std::string const& name, std::string_view str)
@@ -154,20 +153,23 @@ void AppenderConsole::SetColor(bool stdout_stream, ColorTypes color)
void AppenderConsole::ResetColor(bool stdout_stream)
{
#if TRINITY_PLATFORM == TRINITY_PLATFORM_WINDOWS
#if TRINITY_PLATFORM == TRINITY_PLATFORM_WINDOWS
HANDLE hConsole = GetStdHandle(stdout_stream ? STD_OUTPUT_HANDLE : STD_ERROR_HANDLE);
SetConsoleTextAttribute(hConsole, FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED);
#else
fprintf((stdout_stream ? stdout : stderr), "\x1b[0m");
#endif
#else
fputs("\x1b[0m", stdout_stream ? stdout : stderr);
#endif
}
void AppenderConsole::Print(std::string const& str, bool error)
void AppenderConsole::Print(std::string const& prefix, std::string const& text, bool error)
{
#if TRINITY_PLATFORM == TRINITY_PLATFORM_WINDOWS
WriteWinConsole(str + "\n", error);
WriteWinConsole(prefix + text + "\n", error);
#else
utf8printf(error ? stderr : stdout, "%s\n", str.c_str());
FILE* out = error ? stderr : stdout;
fwrite(prefix.c_str(), 1, prefix.length(), out);
fwrite(text.c_str(), 1, text.length(), out);
fwrite("\n", 1, 1, out);
#endif
}
@@ -203,9 +205,9 @@ void AppenderConsole::_write(LogMessage const* message)
}
SetColor(stdout_stream, _colors[index]);
Print(message->prefix + message->text, !stdout_stream);
Print(message->prefix, message->text, !stdout_stream);
ResetColor(stdout_stream);
}
else
Print(message->prefix + message->text, !stdout_stream);
Print(message->prefix, message->text, !stdout_stream);
}

View File

@@ -19,6 +19,7 @@
#define APPENDERCONSOLE_H
#include "Appender.h"
#include <vector>
// EnumUtils: DESCRIBE THIS
enum ColorTypes
@@ -46,14 +47,14 @@ class TC_COMMON_API AppenderConsole : public Appender
public:
static constexpr AppenderType type = APPENDER_CONSOLE;
AppenderConsole(uint8 _id, std::string const& name, LogLevel level, AppenderFlags flags, std::vector<std::string_view> const& args);
AppenderConsole(uint8 _id, std::string name, LogLevel level, AppenderFlags flags, std::vector<std::string_view> const& args);
void InitColors(std::string const& name, std::string_view init_str);
AppenderType getType() const override { return type; }
private:
void SetColor(bool stdout_stream, ColorTypes color);
void ResetColor(bool stdout_stream);
void Print(std::string const& str, bool error);
void Print(std::string const& prefix, std::string const& text, bool error);
void _write(LogMessage const* message) override;
bool _colored;
ColorTypes _colors[NUM_ENABLED_LOG_LEVELS];

View File

@@ -21,8 +21,8 @@
#include "StringConvert.h"
#include <algorithm>
AppenderFile::AppenderFile(uint8 id, std::string const& name, LogLevel level, AppenderFlags flags, std::vector<std::string_view> const& args) :
Appender(id, name, level, flags),
AppenderFile::AppenderFile(uint8 id, std::string name, LogLevel level, AppenderFlags flags, std::vector<std::string_view> const& args) :
Appender(id, std::move(name), level, flags),
logfile(nullptr),
_logDir(sLog->GetLogsDir()),
_maxFileSize(0),
@@ -78,7 +78,9 @@ void AppenderFile::_write(LogMessage const* message)
FILE* file = OpenFile(namebuf, "a", _backup || exceedMaxSize);
if (!file)
return;
fprintf(file, "%s%s\n", message->prefix.c_str(), message->text.c_str());
fwrite(message->prefix.c_str(), 1, message->prefix.length(), file);
fwrite(message->text.c_str(), 1, message->text.length(), file);
fwrite("\n", 1, 1, file);
fflush(file);
_fileSize += uint64(message->Size());
fclose(file);
@@ -90,7 +92,9 @@ void AppenderFile::_write(LogMessage const* message)
if (!logfile)
return;
fprintf(logfile, "%s%s\n", message->prefix.c_str(), message->text.c_str());
fwrite(message->prefix.c_str(), 1, message->prefix.length(), logfile);
fwrite(message->text.c_str(), 1, message->text.length(), logfile);
fwrite("\n", 1, 1, logfile);
fflush(logfile);
_fileSize += uint64(message->Size());
}

View File

@@ -20,13 +20,14 @@
#include "Appender.h"
#include <atomic>
#include <vector>
class TC_COMMON_API AppenderFile : public Appender
{
public:
static constexpr AppenderType type = APPENDER_FILE;
AppenderFile(uint8 id, std::string const& name, LogLevel level, AppenderFlags flags, std::vector<std::string_view> const& args);
AppenderFile(uint8 id, std::string name, LogLevel level, AppenderFlags flags, std::vector<std::string_view> const& args);
~AppenderFile();
FILE* OpenFile(std::string const& name, std::string const& mode, bool backup);
AppenderType getType() const override { return type; }

View File

@@ -83,13 +83,13 @@ void Log::CreateAppenderFromConfigLine(std::string const& appenderName, std::str
auto factoryFunction = appenderFactory.find(type);
if (factoryFunction == appenderFactory.end())
{
fprintf(stderr, "Log::CreateAppenderFromConfig: Unknown type '%s' for appender %s\n", std::string(tokens[0]).c_str(), name.c_str());
fprintf(stderr, "Log::CreateAppenderFromConfig: Unknown type '" STRING_VIEW_FMT "' for appender %s\n", STRING_VIEW_FMT_ARG(tokens[0]), name.c_str());
return;
}
if (level > NUM_ENABLED_LOG_LEVELS)
{
fprintf(stderr, "Log::CreateAppenderFromConfig: Wrong Log Level '%s' for appender %s\n", std::string(tokens[1]).c_str(), name.c_str());
fprintf(stderr, "Log::CreateAppenderFromConfig: Wrong Log Level '" STRING_VIEW_FMT "' for appender %s\n", STRING_VIEW_FMT_ARG(tokens[1]), name.c_str());
return;
}
@@ -99,14 +99,14 @@ void Log::CreateAppenderFromConfigLine(std::string const& appenderName, std::str
flags = AppenderFlags(*flagsVal);
else
{
fprintf(stderr, "Log::CreateAppenderFromConfig: Unknown flags '%s' for appender %s\n", std::string(tokens[2]).c_str(), name.c_str());
fprintf(stderr, "Log::CreateAppenderFromConfig: Unknown flags '" STRING_VIEW_FMT "' for appender %s\n", STRING_VIEW_FMT_ARG(tokens[2]), name.c_str());
return;
}
}
try
{
Appender* appender = factoryFunction->second(NextAppenderId(), name, level, flags, tokens);
Appender* appender = factoryFunction->second(NextAppenderId(), std::move(name), level, flags, tokens);
appenders[appender->getId()].reset(appender);
}
catch (InvalidAppenderArgsException const& iaae)
@@ -152,7 +152,7 @@ void Log::CreateLoggerFromConfigLine(std::string const& loggerName, std::string
level = LogLevel(Trinity::StringTo<uint8>(tokens[0]).value_or(LOG_LEVEL_INVALID));
if (level > NUM_ENABLED_LOG_LEVELS)
{
fprintf(stderr, "Log::CreateLoggerFromConfig: Wrong Log Level '%s' for logger %s\n", std::string(tokens[0]).c_str(), name.c_str());
fprintf(stderr, "Log::CreateLoggerFromConfig: Wrong Log Level '" STRING_VIEW_FMT "' for logger %s\n", STRING_VIEW_FMT_ARG(tokens[0]), name.c_str());
return;
}
@@ -167,11 +167,11 @@ void Log::CreateLoggerFromConfigLine(std::string const& loggerName, std::string
{
if (Appender* appender = GetAppenderByName(appenderName))
{
logger->addAppender(appender->getId(), appender);
logger->addAppender(appender);
//fprintf(stdout, "Log::CreateLoggerFromConfig: Added Appender %s to Logger %s\n", appender->getName().c_str(), name.c_str());
}
else
fprintf(stderr, "Error while configuring Appender %s in Logger %s. Appender does not exist\n", std::string(appenderName).c_str(), name.c_str());
fprintf(stderr, "Error while configuring Appender " STRING_VIEW_FMT " in Logger %s. Appender does not exist\n", STRING_VIEW_FMT_ARG(appenderName), name.c_str());
}
}
@@ -205,11 +205,11 @@ void Log::ReadLoggersFromConfig()
appenders[appender->getId()].reset(appender);
Logger* rootLogger = new Logger(LOGGER_ROOT, LOG_LEVEL_ERROR);
rootLogger->addAppender(appender->getId(), appender);
rootLogger->addAppender(appender);
loggers[rootLogger->getName()].reset(rootLogger);
Logger* serverLogger = new Logger("server", LOG_LEVEL_INFO);
serverLogger->addAppender(appender->getId(), appender);
serverLogger->addAppender(appender);
loggers[serverLogger->getName()].reset(serverLogger);
}
}

View File

@@ -40,12 +40,12 @@ namespace Trinity
#define LOGGER_ROOT "root"
typedef Appender*(*AppenderCreatorFn)(uint8 id, std::string const& name, LogLevel level, AppenderFlags flags, std::vector<std::string_view> const& extraArgs);
typedef Appender*(*AppenderCreatorFn)(uint8 id, std::string name, LogLevel level, AppenderFlags flags, std::vector<std::string_view> const& extraArgs);
template <class AppenderImpl>
Appender* CreateAppender(uint8 id, std::string const& name, LogLevel level, AppenderFlags flags, std::vector<std::string_view> const& extraArgs)
Appender* CreateAppender(uint8 id, std::string name, LogLevel level, AppenderFlags flags, std::vector<std::string_view> const& extraArgs)
{
return new AppenderImpl(id, name, level, flags, extraArgs);
return new AppenderImpl(id, std::move(name), level, flags, extraArgs);
}
class TC_COMMON_API Log

View File

@@ -31,14 +31,9 @@ LogLevel Logger::getLogLevel() const
return level;
}
void Logger::addAppender(uint8 id, Appender* appender)
void Logger::addAppender(Appender* appender)
{
appenders[id] = appender;
}
void Logger::delAppender(uint8 id)
{
appenders.erase(id);
appenders.push_back(appender);
}
void Logger::setLogLevel(LogLevel _level)
@@ -54,7 +49,6 @@ void Logger::write(LogMessage* message) const
return;
}
for (std::pair<uint8 const, Appender*> const& appender : appenders)
if (appender.second)
appender.second->write(message);
for (Appender* appender : appenders)
appender->write(message);
}

View File

@@ -20,8 +20,8 @@
#include "Define.h"
#include "LogCommon.h"
#include <unordered_map>
#include <string>
#include <vector>
class Appender;
struct LogMessage;
@@ -31,8 +31,7 @@ class TC_COMMON_API Logger
public:
Logger(std::string const& name, LogLevel level);
void addAppender(uint8 type, Appender* appender);
void delAppender(uint8 type);
void addAppender(Appender* appender);
std::string const& getName() const;
LogLevel getLogLevel() const;
@@ -42,7 +41,7 @@ class TC_COMMON_API Logger
private:
std::string name;
LogLevel level;
std::unordered_map<uint8, Appender*> appenders;
std::vector<Appender*> appenders;
};
#endif

View File

@@ -826,6 +826,7 @@ bool ReadWinConsole(std::string& str, size_t size /*= 256*/)
bool WriteWinConsole(std::string_view str, bool error /*= false*/)
{
std::wstring wstr;
wstr.reserve(str.length());
if (!Utf8toWStr(str, wstr))
return false;

View File

@@ -20,10 +20,10 @@
#include "LogMessage.h"
#include "PreparedStatement.h"
AppenderDB::AppenderDB(uint8 id, std::string const& name, LogLevel level, AppenderFlags /*flags*/, std::vector<std::string_view> const& /*args*/)
: Appender(id, name, level), realmId(0), enabled(false) { }
AppenderDB::AppenderDB(uint8 id, std::string name, LogLevel level, AppenderFlags /*flags*/, std::vector<std::string_view> const& /*args*/)
: Appender(id, std::move(name), level), realmId(0), enabled(false) { }
AppenderDB::~AppenderDB() { }
AppenderDB::~AppenderDB() = default;
void AppenderDB::_write(LogMessage const* message)
{

View File

@@ -19,13 +19,14 @@
#define APPENDERDB_H
#include "Appender.h"
#include <vector>
class TC_DATABASE_API AppenderDB: public Appender
{
public:
static constexpr AppenderType type = APPENDER_DB;
AppenderDB(uint8 id, std::string const& name, LogLevel level, AppenderFlags flags, std::vector<std::string_view> const& args);
AppenderDB(uint8 id, std::string name, LogLevel level, AppenderFlags flags, std::vector<std::string_view> const& args);
~AppenderDB();
void setRealmId(uint32 realmId) override;