aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/server/bnetserver/Main.cpp4
-rw-r--r--src/server/shared/Logging/Appender.cpp9
-rw-r--r--src/server/shared/Logging/Appender.h22
-rw-r--r--src/server/shared/Logging/AppenderConsole.cpp7
-rw-r--r--src/server/shared/Logging/AppenderConsole.h7
-rw-r--r--src/server/shared/Logging/AppenderDB.cpp4
-rw-r--r--src/server/shared/Logging/AppenderDB.h7
-rw-r--r--src/server/shared/Logging/AppenderFile.cpp33
-rw-r--r--src/server/shared/Logging/AppenderFile.h7
-rw-r--r--src/server/shared/Logging/Log.cpp90
-rw-r--r--src/server/shared/Logging/Log.h23
-rw-r--r--src/server/worldserver/Main.cpp9
12 files changed, 124 insertions, 98 deletions
diff --git a/src/server/bnetserver/Main.cpp b/src/server/bnetserver/Main.cpp
index 68e647d8b15..d7d9951f233 100644
--- a/src/server/bnetserver/Main.cpp
+++ b/src/server/bnetserver/Main.cpp
@@ -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());
diff --git a/src/server/shared/Logging/Appender.cpp b/src/server/shared/Logging/Appender.cpp
index 31db3ae1b86..d19ef8cf96f 100644
--- a/src/server/shared/Logging/Appender.cpp
+++ b/src/server/shared/Logging/Appender.cpp
@@ -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;
diff --git a/src/server/shared/Logging/Appender.h b/src/server/shared/Logging/Appender.h
index 73af351e41d..09ee6070050 100644
--- a/src/server/shared/Logging/Appender.h
+++ b/src/server/shared/Logging/Appender.h
@@ -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
diff --git a/src/server/shared/Logging/AppenderConsole.cpp b/src/server/shared/Logging/AppenderConsole.cpp
index 2efa4db4d2e..531df266aa1 100644
--- a/src/server/shared/Logging/AppenderConsole.cpp
+++ b/src/server/shared/Logging/AppenderConsole.cpp
@@ -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)
diff --git a/src/server/shared/Logging/AppenderConsole.h b/src/server/shared/Logging/AppenderConsole.h
index 0acf7636e35..6b30505c6bd 100644
--- a/src/server/shared/Logging/AppenderConsole.h
+++ b/src/server/shared/Logging/AppenderConsole.h
@@ -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);
diff --git a/src/server/shared/Logging/AppenderDB.cpp b/src/server/shared/Logging/AppenderDB.cpp
index 8a329ea3a0f..9e6ab1a057c 100644
--- a/src/server/shared/Logging/AppenderDB.cpp
+++ b/src/server/shared/Logging/AppenderDB.cpp
@@ -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() { }
diff --git a/src/server/shared/Logging/AppenderDB.h b/src/server/shared/Logging/AppenderDB.h
index 09affdb46f1..50607fd8136 100644
--- a/src/server/shared/Logging/AppenderDB.h
+++ b/src/server/shared/Logging/AppenderDB.h
@@ -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;
diff --git a/src/server/shared/Logging/AppenderFile.cpp b/src/server/shared/Logging/AppenderFile.cpp
index c9cc1935c7a..d33818626fe 100644
--- a/src/server/shared/Logging/AppenderFile.cpp
+++ b/src/server/shared/Logging/AppenderFile.cpp
@@ -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()
diff --git a/src/server/shared/Logging/AppenderFile.h b/src/server/shared/Logging/AppenderFile.h
index 4082b34a2b4..c2781eb1ee9 100644
--- a/src/server/shared/Logging/AppenderFile.h
+++ b/src/server/shared/Logging/AppenderFile.h
@@ -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();
diff --git a/src/server/shared/Logging/Log.cpp b/src/server/shared/Logging/Log.cpp
index f9f96c3da75..286816f4c2c 100644
--- a/src/server/shared/Logging/Log.cpp
+++ b/src/server/shared/Logging/Log.cpp
@@ -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";
-
- 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;
+ fprintf(stderr, "Log::CreateAppenderFromConfig: Unknown type %d for appender %s\n", type, name.c_str());
+ return;
+ }
+
+ 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();
diff --git a/src/server/shared/Logging/Log.h b/src/server/shared/Logging/Log.h
index ab7b2169ed2..a15bb4ad485 100644
--- a/src/server/shared/Logging/Log.h
+++ b/src/server/shared/Logging/Log.h
@@ -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;
diff --git a/src/server/worldserver/Main.cpp b/src/server/worldserver/Main.cpp
index e09f28d416f..d0acfa279f6 100644
--- a/src/server/worldserver/Main.cpp
+++ b/src/server/worldserver/Main.cpp
@@ -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");