mirror of
https://github.com/TrinityCore/TrinityCore.git
synced 2026-01-20 09:17:36 +01:00
Core/Logging: Refactored appender creation to allow using logging without mysql dependency in tools (future task)
This commit is contained in:
@@ -31,6 +31,7 @@
|
||||
#include "Config.h"
|
||||
#include "DatabaseEnv.h"
|
||||
#include "Log.h"
|
||||
#include "AppenderDB.h"
|
||||
#include "ProcessPriority.h"
|
||||
#include "RealmList.h"
|
||||
#include "SystemConfig.h"
|
||||
@@ -104,6 +105,9 @@ int main(int argc, char** argv)
|
||||
return 1;
|
||||
}
|
||||
|
||||
sLog->RegisterAppender<AppenderDB>();
|
||||
sLog->Initialize(nullptr);
|
||||
|
||||
TC_LOG_INFO("server.bnetserver", "%s (bnetserver)", _FULLVERSION);
|
||||
TC_LOG_INFO("server.bnetserver", "<Ctrl-C> to stop.\n");
|
||||
TC_LOG_INFO("server.bnetserver", "Using configuration file %s.", configFile.c_str());
|
||||
|
||||
@@ -37,8 +37,8 @@ std::string LogMessage::getTimeStr()
|
||||
return getTimeStr(mtime);
|
||||
}
|
||||
|
||||
Appender::Appender(uint8 _id, std::string const& _name, AppenderType _type /* = APPENDER_NONE*/, LogLevel _level /* = LOG_LEVEL_DISABLED */, AppenderFlags _flags /* = APPENDER_FLAGS_NONE */):
|
||||
id(_id), name(_name), type(_type), level(_level), flags(_flags) { }
|
||||
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() { }
|
||||
|
||||
@@ -52,11 +52,6 @@ std::string const& Appender::getName() const
|
||||
return name;
|
||||
}
|
||||
|
||||
AppenderType Appender::getType() const
|
||||
{
|
||||
return type;
|
||||
}
|
||||
|
||||
LogLevel Appender::getLogLevel() const
|
||||
{
|
||||
return level;
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
#include <string>
|
||||
#include <time.h>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
#include "Define.h"
|
||||
|
||||
// Values assigned have their equivalent in enum ACE_Log_Priority
|
||||
@@ -85,18 +86,19 @@ struct LogMessage
|
||||
class Appender
|
||||
{
|
||||
public:
|
||||
Appender(uint8 _id, std::string const& name, AppenderType type = APPENDER_NONE, LogLevel level = LOG_LEVEL_DISABLED, AppenderFlags flags = APPENDER_FLAGS_NONE);
|
||||
Appender(uint8 _id, std::string const& name, LogLevel level = LOG_LEVEL_DISABLED, AppenderFlags flags = APPENDER_FLAGS_NONE);
|
||||
virtual ~Appender();
|
||||
|
||||
uint8 getId() const;
|
||||
std::string const& getName() const;
|
||||
AppenderType getType() const;
|
||||
virtual AppenderType getType() const = 0;
|
||||
LogLevel getLogLevel() const;
|
||||
AppenderFlags getFlags() const;
|
||||
|
||||
void setLogLevel(LogLevel);
|
||||
void write(LogMessage* message);
|
||||
static const char* getLogLevelString(LogLevel level);
|
||||
virtual void setRealmId(uint32 /*realmId*/) { }
|
||||
|
||||
private:
|
||||
virtual void _write(LogMessage const* /*message*/) = 0;
|
||||
@@ -110,4 +112,20 @@ class Appender
|
||||
|
||||
typedef std::unordered_map<uint8, Appender*> AppenderMap;
|
||||
|
||||
typedef std::vector<char const*> ExtraAppenderArgs;
|
||||
typedef Appender*(*AppenderCreatorFn)(uint8 id, std::string const& name, LogLevel level, AppenderFlags flags, ExtraAppenderArgs extraArgs);
|
||||
typedef std::unordered_map<uint8, AppenderCreatorFn> AppenderCreatorMap;
|
||||
|
||||
template<class AppenderImpl>
|
||||
Appender* CreateAppender(uint8 id, std::string const& name, LogLevel level, AppenderFlags flags, ExtraAppenderArgs extraArgs)
|
||||
{
|
||||
return new AppenderImpl(id, name, level, flags, std::forward<ExtraAppenderArgs>(extraArgs));
|
||||
}
|
||||
|
||||
class InvalidAppenderArgsException : public std::length_error
|
||||
{
|
||||
public:
|
||||
using std::length_error::length_error;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -25,11 +25,14 @@
|
||||
#include <Windows.h>
|
||||
#endif
|
||||
|
||||
AppenderConsole::AppenderConsole(uint8 id, std::string const& name, LogLevel level, AppenderFlags flags):
|
||||
Appender(id, name, APPENDER_CONSOLE, level, flags), _colored(false)
|
||||
AppenderConsole::AppenderConsole(uint8 id, std::string const& name, LogLevel level, AppenderFlags flags, ExtraAppenderArgs extraArgs)
|
||||
: Appender(id, name, level, flags), _colored(false)
|
||||
{
|
||||
for (uint8 i = 0; i < MaxLogLevels; ++i)
|
||||
_colors[i] = ColorTypes(MaxColors);
|
||||
|
||||
if (!extraArgs.empty())
|
||||
InitColors(extraArgs[0]);
|
||||
}
|
||||
|
||||
void AppenderConsole::InitColors(std::string const& str)
|
||||
|
||||
@@ -42,11 +42,14 @@ enum ColorTypes
|
||||
|
||||
const uint8 MaxColors = uint8(WHITE) + 1;
|
||||
|
||||
class AppenderConsole: public Appender
|
||||
class AppenderConsole : public Appender
|
||||
{
|
||||
public:
|
||||
AppenderConsole(uint8 _id, std::string const& name, LogLevel level, AppenderFlags flags);
|
||||
typedef std::integral_constant<AppenderType, APPENDER_CONSOLE>::type TypeIndex;
|
||||
|
||||
AppenderConsole(uint8 _id, std::string const& name, LogLevel level, AppenderFlags flags, ExtraAppenderArgs extraArgs);
|
||||
void InitColors(const std::string& init_str);
|
||||
AppenderType getType() const override { return TypeIndex::value; }
|
||||
|
||||
private:
|
||||
void SetColor(bool stdout_stream, ColorTypes color);
|
||||
|
||||
@@ -18,8 +18,8 @@
|
||||
#include "AppenderDB.h"
|
||||
#include "Database/DatabaseEnv.h"
|
||||
|
||||
AppenderDB::AppenderDB(uint8 id, std::string const& name, LogLevel level)
|
||||
: Appender(id, name, APPENDER_DB, level), realmId(0), enabled(false) { }
|
||||
AppenderDB::AppenderDB(uint8 id, std::string const& name, LogLevel level, AppenderFlags /*flags*/, ExtraAppenderArgs /*extraArgs*/)
|
||||
: Appender(id, name, level), realmId(0), enabled(false) { }
|
||||
|
||||
AppenderDB::~AppenderDB() { }
|
||||
|
||||
|
||||
@@ -23,10 +23,13 @@
|
||||
class AppenderDB: public Appender
|
||||
{
|
||||
public:
|
||||
AppenderDB(uint8 _id, std::string const& _name, LogLevel level);
|
||||
typedef std::integral_constant<AppenderType, APPENDER_DB>::type TypeIndex;
|
||||
|
||||
AppenderDB(uint8 id, std::string const& name, LogLevel level, AppenderFlags flags, ExtraAppenderArgs extraArgs);
|
||||
~AppenderDB();
|
||||
|
||||
void setRealmId(uint32 realmId);
|
||||
void setRealmId(uint32 realmId) override;
|
||||
AppenderType getType() const override { return TypeIndex::value; }
|
||||
|
||||
private:
|
||||
uint32 realmId;
|
||||
|
||||
@@ -17,24 +17,45 @@
|
||||
|
||||
#include "AppenderFile.h"
|
||||
#include "Common.h"
|
||||
#include "StringFormat.h"
|
||||
#include "Log.h"
|
||||
|
||||
#if PLATFORM == PLATFORM_WINDOWS
|
||||
# include <Windows.h>
|
||||
#endif
|
||||
|
||||
AppenderFile::AppenderFile(uint8 id, std::string const& name, LogLevel level, const char* filename, const char* logDir, const char* mode, AppenderFlags flags, uint64 fileSize):
|
||||
Appender(id, name, APPENDER_FILE, level, flags),
|
||||
AppenderFile::AppenderFile(uint8 id, std::string const& name, LogLevel level, AppenderFlags flags, ExtraAppenderArgs extraArgs) :
|
||||
Appender(id, name, level, flags),
|
||||
logfile(NULL),
|
||||
_fileName(filename),
|
||||
_logDir(logDir),
|
||||
_maxFileSize(fileSize),
|
||||
_logDir(sLog->GetLogsDir()),
|
||||
_fileSize(0)
|
||||
{
|
||||
if (extraArgs.empty())
|
||||
throw InvalidAppenderArgsException(Trinity::StringFormat("Log::CreateAppenderFromConfig: Missing file name for appender %s\n", name.c_str()));
|
||||
|
||||
_fileName = extraArgs[0];
|
||||
|
||||
char const* mode = "a";
|
||||
if (extraArgs.size() > 1)
|
||||
mode = extraArgs[1];
|
||||
|
||||
if (flags & APPENDER_FLAGS_USE_TIMESTAMP)
|
||||
{
|
||||
size_t dot_pos = _fileName.find_last_of(".");
|
||||
if (dot_pos != std::string::npos)
|
||||
_fileName.insert(dot_pos, sLog->GetLogsTimestamp());
|
||||
else
|
||||
_fileName += sLog->GetLogsTimestamp();
|
||||
}
|
||||
|
||||
if (extraArgs.size() > 2)
|
||||
_maxFileSize = atoi(extraArgs[2]);
|
||||
|
||||
_dynamicName = std::string::npos != _fileName.find("%s");
|
||||
_backup = (flags & APPENDER_FLAGS_MAKE_FILE_BACKUP) != 0;
|
||||
|
||||
if (!_dynamicName)
|
||||
logfile = OpenFile(filename, mode, !strcmp(mode, "w") && _backup);
|
||||
logfile = OpenFile(_fileName, mode, !strcmp(mode, "w") && _backup);
|
||||
}
|
||||
|
||||
AppenderFile::~AppenderFile()
|
||||
|
||||
@@ -21,12 +21,15 @@
|
||||
#include <atomic>
|
||||
#include "Appender.h"
|
||||
|
||||
class AppenderFile: public Appender
|
||||
class AppenderFile : public Appender
|
||||
{
|
||||
public:
|
||||
AppenderFile(uint8 id, std::string const& name, LogLevel level, const char* filename, const char* logDir, const char* mode, AppenderFlags flags, uint64 maxSize);
|
||||
typedef std::integral_constant<AppenderType, APPENDER_FILE>::type TypeIndex;
|
||||
|
||||
AppenderFile(uint8 id, std::string const& name, LogLevel level, AppenderFlags flags, ExtraAppenderArgs extraArgs);
|
||||
~AppenderFile();
|
||||
FILE* OpenFile(std::string const& name, std::string const& mode, bool backup);
|
||||
AppenderType getType() const override { return TypeIndex::value; }
|
||||
|
||||
private:
|
||||
void CloseFile();
|
||||
|
||||
@@ -32,7 +32,8 @@
|
||||
Log::Log() : _ioService(nullptr), _strand(nullptr)
|
||||
{
|
||||
m_logsTimestamp = "_" + GetTimestampStr();
|
||||
LoadFromConfig();
|
||||
RegisterAppender<AppenderConsole>();
|
||||
RegisterAppender<AppenderFile>();
|
||||
}
|
||||
|
||||
Log::~Log()
|
||||
@@ -102,60 +103,21 @@ void Log::CreateAppenderFromConfig(std::string const& appenderName)
|
||||
if (size > 2)
|
||||
flags = AppenderFlags(atoi(*iter++));
|
||||
|
||||
switch (type)
|
||||
auto factoryFunction = appenderFactory.find(type);
|
||||
if (factoryFunction == appenderFactory.end())
|
||||
{
|
||||
case APPENDER_CONSOLE:
|
||||
{
|
||||
AppenderConsole* appender = new AppenderConsole(NextAppenderId(), name, level, flags);
|
||||
appenders[appender->getId()] = appender;
|
||||
if (size > 3)
|
||||
appender->InitColors(*iter++);
|
||||
//fprintf(stdout, "Log::CreateAppenderFromConfig: Created Appender %s (%u), Type CONSOLE, Mask %u\n", appender->getName().c_str(), appender->getId(), appender->getLogLevel());
|
||||
break;
|
||||
}
|
||||
case APPENDER_FILE:
|
||||
{
|
||||
std::string filename;
|
||||
std::string mode = "a";
|
||||
fprintf(stderr, "Log::CreateAppenderFromConfig: Unknown type %d for appender %s\n", type, name.c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
if (size < 4)
|
||||
{
|
||||
fprintf(stderr, "Log::CreateAppenderFromConfig: Missing file name for appender %s\n", name.c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
filename = *iter++;
|
||||
|
||||
if (size > 4)
|
||||
mode = *iter++;
|
||||
|
||||
if (flags & APPENDER_FLAGS_USE_TIMESTAMP)
|
||||
{
|
||||
size_t dot_pos = filename.find_last_of(".");
|
||||
if (dot_pos != filename.npos)
|
||||
filename.insert(dot_pos, m_logsTimestamp);
|
||||
else
|
||||
filename += m_logsTimestamp;
|
||||
}
|
||||
|
||||
uint64 maxFileSize = 0;
|
||||
if (size > 5)
|
||||
maxFileSize = atoi(*iter++);
|
||||
|
||||
uint8 id = NextAppenderId();
|
||||
appenders[id] = new AppenderFile(id, name, level, filename.c_str(), m_logsDir.c_str(), mode.c_str(), flags, maxFileSize);
|
||||
//fprintf(stdout, "Log::CreateAppenderFromConfig: Created Appender %s (%u), Type FILE, Mask %u, File %s, Mode %s\n", name.c_str(), id, level, filename.c_str(), mode.c_str());
|
||||
break;
|
||||
}
|
||||
case APPENDER_DB:
|
||||
{
|
||||
uint8 id = NextAppenderId();
|
||||
appenders[id] = new AppenderDB(id, name, level);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
fprintf(stderr, "Log::CreateAppenderFromConfig: Unknown type %d for appender %s\n", type, name.c_str());
|
||||
break;
|
||||
try
|
||||
{
|
||||
Appender* appender = factoryFunction->second(NextAppenderId(), name, level, flags, ExtraAppenderArgs(iter, tokens.end()));
|
||||
appenders[appender->getId()] = appender;
|
||||
}
|
||||
catch (InvalidAppenderArgsException const& iaae)
|
||||
{
|
||||
fprintf(stderr, iaae.what());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -251,7 +213,7 @@ void Log::ReadLoggersFromConfig()
|
||||
|
||||
Close(); // Clean any Logger or Appender created
|
||||
|
||||
AppenderConsole* appender = new AppenderConsole(NextAppenderId(), "Console", LOG_LEVEL_DEBUG, APPENDER_FLAGS_NONE);
|
||||
AppenderConsole* appender = new AppenderConsole(NextAppenderId(), "Console", LOG_LEVEL_DEBUG, APPENDER_FLAGS_NONE, ExtraAppenderArgs());
|
||||
appenders[appender->getId()] = appender;
|
||||
|
||||
Logger& logger = loggers[LOGGER_ROOT];
|
||||
@@ -348,21 +310,29 @@ void Log::outCharDump(char const* str, uint32 accountId, uint64 guid, char const
|
||||
void Log::SetRealmId(uint32 id)
|
||||
{
|
||||
for (AppenderMap::iterator it = appenders.begin(); it != appenders.end(); ++it)
|
||||
if (it->second && it->second->getType() == APPENDER_DB)
|
||||
static_cast<AppenderDB*>(it->second)->setRealmId(id);
|
||||
it->second->setRealmId(id);
|
||||
}
|
||||
|
||||
void Log::Close()
|
||||
{
|
||||
loggers.clear();
|
||||
for (AppenderMap::iterator it = appenders.begin(); it != appenders.end(); ++it)
|
||||
{
|
||||
delete it->second;
|
||||
it->second = NULL;
|
||||
}
|
||||
|
||||
appenders.clear();
|
||||
}
|
||||
|
||||
void Log::Initialize(boost::asio::io_service* ioService)
|
||||
{
|
||||
if (ioService)
|
||||
{
|
||||
_ioService = ioService;
|
||||
_strand = new boost::asio::strand(*ioService);
|
||||
}
|
||||
|
||||
LoadFromConfig();
|
||||
}
|
||||
|
||||
void Log::LoadFromConfig()
|
||||
{
|
||||
Close();
|
||||
|
||||
@@ -44,19 +44,13 @@ class Log
|
||||
|
||||
public:
|
||||
|
||||
static Log* instance(boost::asio::io_service* ioService = nullptr)
|
||||
static Log* instance()
|
||||
{
|
||||
static Log instance;
|
||||
|
||||
if (ioService != nullptr)
|
||||
{
|
||||
instance._ioService = ioService;
|
||||
instance._strand = new boost::asio::strand(*ioService);
|
||||
}
|
||||
|
||||
return &instance;
|
||||
}
|
||||
|
||||
void Initialize(boost::asio::io_service* ioService);
|
||||
void LoadFromConfig();
|
||||
void Close();
|
||||
bool ShouldLog(std::string const& type, LogLevel level) const;
|
||||
@@ -88,6 +82,18 @@ class Log
|
||||
|
||||
void SetRealmId(uint32 id);
|
||||
|
||||
template<class AppenderImpl>
|
||||
void RegisterAppender()
|
||||
{
|
||||
using Index = typename AppenderImpl::TypeIndex;
|
||||
auto itr = appenderFactory.find(Index::value);
|
||||
ASSERT(itr == appenderFactory.end());
|
||||
appenderFactory[Index::value] = &CreateAppender<AppenderImpl>;
|
||||
}
|
||||
|
||||
std::string const& GetLogsDir() const { return m_logsDir; }
|
||||
std::string const& GetLogsTimestamp() const { return m_logsTimestamp; }
|
||||
|
||||
private:
|
||||
static std::string GetTimestampStr();
|
||||
void write(std::unique_ptr<LogMessage>&& msg) const;
|
||||
@@ -100,6 +106,7 @@ class Log
|
||||
void ReadAppendersFromConfig();
|
||||
void ReadLoggersFromConfig();
|
||||
|
||||
AppenderCreatorMap appenderFactory;
|
||||
AppenderMap appenders;
|
||||
LoggerMap loggers;
|
||||
uint8 AppenderId;
|
||||
|
||||
@@ -45,6 +45,7 @@
|
||||
#include "BattlenetServerManager.h"
|
||||
#include "Realm/Realm.h"
|
||||
#include "DatabaseLoader.h"
|
||||
#include "AppenderDB.h"
|
||||
#include <openssl/opensslv.h>
|
||||
#include <openssl/crypto.h>
|
||||
#include <boost/asio/io_service.hpp>
|
||||
@@ -125,11 +126,9 @@ extern int main(int argc, char** argv)
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (sConfigMgr->GetBoolDefault("Log.Async.Enable", false))
|
||||
{
|
||||
// If logs are supposed to be handled async then we need to pass the io_service into the Log singleton
|
||||
Log::instance(&_ioService);
|
||||
}
|
||||
sLog->RegisterAppender<AppenderDB>();
|
||||
// If logs are supposed to be handled async then we need to pass the io_service into the Log singleton
|
||||
sLog->Initialize(sConfigMgr->GetBoolDefault("Log.Async.Enable", false) ? &_ioService : nullptr);
|
||||
|
||||
TC_LOG_INFO("server.worldserver", "%s (worldserver-daemon)", _FULLVERSION);
|
||||
TC_LOG_INFO("server.worldserver", "<Ctrl-C> to stop.\n");
|
||||
|
||||
Reference in New Issue
Block a user