aboutsummaryrefslogtreecommitdiff
path: root/src/common/Logging
diff options
context:
space:
mode:
authorariel- <ariel-@users.noreply.github.com>2017-06-19 23:20:06 -0300
committerariel- <ariel-@users.noreply.github.com>2017-06-19 23:20:06 -0300
commit85a7d5ce9ac68b30da2277cc91d4b70358f1880d (patch)
treedf3d2084ee2e35008903c03178039b9c986e2d08 /src/common/Logging
parent052fc24315ace866ea1cf610e85df119b68100c9 (diff)
Core: ported headers cleanup from master branch
Diffstat (limited to 'src/common/Logging')
-rw-r--r--src/common/Logging/Appender.cpp20
-rw-r--r--src/common/Logging/Appender.h79
-rw-r--r--src/common/Logging/AppenderConsole.cpp15
-rw-r--r--src/common/Logging/AppenderConsole.h5
-rw-r--r--src/common/Logging/AppenderFile.cpp18
-rw-r--r--src/common/Logging/AppenderFile.h4
-rw-r--r--src/common/Logging/Log.cpp150
-rw-r--r--src/common/Logging/Log.h100
-rw-r--r--src/common/Logging/LogCommon.h52
-rw-r--r--src/common/Logging/LogMessage.cpp43
-rw-r--r--src/common/Logging/LogMessage.h51
-rw-r--r--src/common/Logging/LogOperation.cpp9
-rw-r--r--src/common/Logging/LogOperation.h8
-rw-r--r--src/common/Logging/Logger.cpp12
-rw-r--r--src/common/Logging/Logger.h15
15 files changed, 326 insertions, 255 deletions
diff --git a/src/common/Logging/Appender.cpp b/src/common/Logging/Appender.cpp
index ec88d5fd4c1..616e3a2137f 100644
--- a/src/common/Logging/Appender.cpp
+++ b/src/common/Logging/Appender.cpp
@@ -16,27 +16,11 @@
*/
#include "Appender.h"
-#include "Common.h"
-#include "Util.h"
+#include "LogMessage.h"
#include "StringFormat.h"
-#include <utility>
#include <sstream>
-std::string LogMessage::getTimeStr(time_t time)
-{
- tm aTm;
- localtime_r(&time, &aTm);
- char buf[20];
- snprintf(buf, 20, "%04d-%02d-%02d_%02d:%02d:%02d", aTm.tm_year+1900, aTm.tm_mon+1, aTm.tm_mday, aTm.tm_hour, aTm.tm_min, aTm.tm_sec);
- return std::string(buf);
-}
-
-std::string LogMessage::getTimeStr()
-{
- return getTimeStr(mtime);
-}
-
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) { }
@@ -87,7 +71,7 @@ void Appender::write(LogMessage* message)
_write(message);
}
-const char* Appender::getLogLevelString(LogLevel level)
+char const* Appender::getLogLevelString(LogLevel level)
{
switch (level)
{
diff --git a/src/common/Logging/Appender.h b/src/common/Logging/Appender.h
index 6a9932b7935..fd17ad71fdd 100644
--- a/src/common/Logging/Appender.h
+++ b/src/common/Logging/Appender.h
@@ -18,72 +18,13 @@
#ifndef APPENDER_H
#define APPENDER_H
-#include <unordered_map>
+#include "Define.h"
+#include "LogCommon.h"
#include <stdexcept>
#include <string>
-#include <time.h>
-#include <type_traits>
#include <vector>
-#include <utility>
-#include "Define.h"
-
-// Values assigned have their equivalent in enum ACE_Log_Priority
-enum LogLevel
-{
- LOG_LEVEL_DISABLED = 0,
- LOG_LEVEL_TRACE = 1,
- LOG_LEVEL_DEBUG = 2,
- LOG_LEVEL_INFO = 3,
- LOG_LEVEL_WARN = 4,
- LOG_LEVEL_ERROR = 5,
- LOG_LEVEL_FATAL = 6
-};
-
-const uint8 MaxLogLevels = 6;
-
-enum AppenderType : uint8
-{
- APPENDER_NONE,
- APPENDER_CONSOLE,
- APPENDER_FILE,
- APPENDER_DB
-};
-
-enum AppenderFlags
-{
- APPENDER_FLAGS_NONE = 0x00,
- APPENDER_FLAGS_PREFIX_TIMESTAMP = 0x01,
- APPENDER_FLAGS_PREFIX_LOGLEVEL = 0x02,
- APPENDER_FLAGS_PREFIX_LOGFILTERTYPE = 0x04,
- APPENDER_FLAGS_USE_TIMESTAMP = 0x08, // only used by FileAppender
- APPENDER_FLAGS_MAKE_FILE_BACKUP = 0x10 // only used by FileAppender
-};
-
-struct TC_COMMON_API LogMessage
-{
- LogMessage(LogLevel _level, std::string const& _type, std::string&& _text)
- : level(_level), type(_type), text(std::forward<std::string>(_text)), mtime(time(NULL))
- { }
- LogMessage(LogMessage const& /*other*/) = delete;
- LogMessage& operator=(LogMessage const& /*other*/) = delete;
-
- static std::string getTimeStr(time_t time);
- std::string getTimeStr();
-
- LogLevel const level;
- std::string const type;
- std::string const text;
- std::string prefix;
- std::string param1;
- time_t mtime;
-
- ///@ Returns size of the log message content in bytes
- uint32 Size() const
- {
- return static_cast<uint32>(prefix.size() + text.size());
- }
-};
+struct LogMessage;
class TC_COMMON_API Appender
{
@@ -99,7 +40,7 @@ class TC_COMMON_API Appender
void setLogLevel(LogLevel);
void write(LogMessage* message);
- static const char* getLogLevelString(LogLevel level);
+ static char const* getLogLevelString(LogLevel level);
virtual void setRealmId(uint32 /*realmId*/) { }
private:
@@ -111,18 +52,6 @@ class TC_COMMON_API Appender
AppenderFlags flags;
};
-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 TC_COMMON_API InvalidAppenderArgsException : public std::length_error
{
public:
diff --git a/src/common/Logging/AppenderConsole.cpp b/src/common/Logging/AppenderConsole.cpp
index 3378c185cc5..7ae1987162e 100644
--- a/src/common/Logging/AppenderConsole.cpp
+++ b/src/common/Logging/AppenderConsole.cpp
@@ -15,20 +15,19 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#include <sstream>
-
#include "AppenderConsole.h"
-#include "Config.h"
+#include "LogMessage.h"
#include "Util.h"
+#include <sstream>
#if TRINITY_PLATFORM == TRINITY_PLATFORM_WINDOWS
#include <Windows.h>
#endif
-AppenderConsole::AppenderConsole(uint8 id, std::string const& name, LogLevel level, AppenderFlags flags, ExtraAppenderArgs extraArgs)
+AppenderConsole::AppenderConsole(uint8 id, std::string const& name, LogLevel level, AppenderFlags flags, std::vector<char const*> extraArgs)
: Appender(id, name, level, flags), _colored(false)
{
- for (uint8 i = 0; i < MaxLogLevels; ++i)
+ for (uint8 i = 0; i < NUM_ENABLED_LOG_LEVELS; ++i)
_colors[i] = ColorTypes(MaxColors);
if (!extraArgs.empty())
@@ -43,11 +42,11 @@ void AppenderConsole::InitColors(std::string const& str)
return;
}
- int color[MaxLogLevels];
+ int color[NUM_ENABLED_LOG_LEVELS];
std::istringstream ss(str);
- for (uint8 i = 0; i < MaxLogLevels; ++i)
+ for (uint8 i = 0; i < NUM_ENABLED_LOG_LEVELS; ++i)
{
ss >> color[i];
@@ -58,7 +57,7 @@ void AppenderConsole::InitColors(std::string const& str)
return;
}
- for (uint8 i = 0; i < MaxLogLevels; ++i)
+ for (uint8 i = 0; i < NUM_ENABLED_LOG_LEVELS; ++i)
_colors[i] = ColorTypes(color[i]);
_colored = true;
diff --git a/src/common/Logging/AppenderConsole.h b/src/common/Logging/AppenderConsole.h
index c56a745bfba..9fd57c99f8a 100644
--- a/src/common/Logging/AppenderConsole.h
+++ b/src/common/Logging/AppenderConsole.h
@@ -18,7 +18,6 @@
#ifndef APPENDERCONSOLE_H
#define APPENDERCONSOLE_H
-#include <string>
#include "Appender.h"
enum ColorTypes
@@ -47,7 +46,7 @@ class TC_COMMON_API AppenderConsole : public Appender
public:
typedef std::integral_constant<AppenderType, APPENDER_CONSOLE>::type TypeIndex;
- AppenderConsole(uint8 _id, std::string const& name, LogLevel level, AppenderFlags flags, ExtraAppenderArgs extraArgs);
+ AppenderConsole(uint8 _id, std::string const& name, LogLevel level, AppenderFlags flags, std::vector<char const*> extraArgs);
void InitColors(const std::string& init_str);
AppenderType getType() const override { return TypeIndex::value; }
@@ -56,7 +55,7 @@ class TC_COMMON_API AppenderConsole : public Appender
void ResetColor(bool stdout_stream);
void _write(LogMessage const* message) override;
bool _colored;
- ColorTypes _colors[MaxLogLevels];
+ ColorTypes _colors[NUM_ENABLED_LOG_LEVELS];
};
#endif
diff --git a/src/common/Logging/AppenderFile.cpp b/src/common/Logging/AppenderFile.cpp
index 6c68406667d..d2109936e65 100644
--- a/src/common/Logging/AppenderFile.cpp
+++ b/src/common/Logging/AppenderFile.cpp
@@ -16,17 +16,13 @@
*/
#include "AppenderFile.h"
-#include "Common.h"
-#include "StringFormat.h"
#include "Log.h"
+#include "LogMessage.h"
+#include <algorithm>
-#if TRINITY_PLATFORM == TRINITY_PLATFORM_WINDOWS
-# include <Windows.h>
-#endif
-
-AppenderFile::AppenderFile(uint8 id, std::string const& name, LogLevel level, AppenderFlags flags, ExtraAppenderArgs extraArgs) :
+AppenderFile::AppenderFile(uint8 id, std::string const& name, LogLevel level, AppenderFlags flags, std::vector<char const*> extraArgs) :
Appender(id, name, level, flags),
- logfile(NULL),
+ logfile(nullptr),
_logDir(sLog->GetLogsDir()),
_maxFileSize(0),
_fileSize(0)
@@ -101,7 +97,7 @@ FILE* AppenderFile::OpenFile(std::string const& filename, std::string const& mod
CloseFile();
std::string newName(fullName);
newName.push_back('.');
- newName.append(LogMessage::getTimeStr(time(NULL)));
+ newName.append(LogMessage::getTimeStr(time(nullptr)));
std::replace(newName.begin(), newName.end(), ':', '-');
rename(fullName.c_str(), newName.c_str()); // no error handling... if we couldn't make a backup, just ignore
}
@@ -112,7 +108,7 @@ FILE* AppenderFile::OpenFile(std::string const& filename, std::string const& mod
return ret;
}
- return NULL;
+ return nullptr;
}
void AppenderFile::CloseFile()
@@ -120,6 +116,6 @@ void AppenderFile::CloseFile()
if (logfile)
{
fclose(logfile);
- logfile = NULL;
+ logfile = nullptr;
}
}
diff --git a/src/common/Logging/AppenderFile.h b/src/common/Logging/AppenderFile.h
index aeb1c2d8001..8e728cbdf4d 100644
--- a/src/common/Logging/AppenderFile.h
+++ b/src/common/Logging/AppenderFile.h
@@ -18,15 +18,15 @@
#ifndef APPENDERFILE_H
#define APPENDERFILE_H
-#include <atomic>
#include "Appender.h"
+#include <atomic>
class TC_COMMON_API AppenderFile : public Appender
{
public:
typedef std::integral_constant<AppenderType, APPENDER_FILE>::type TypeIndex;
- AppenderFile(uint8 id, std::string const& name, LogLevel level, AppenderFlags flags, ExtraAppenderArgs extraArgs);
+ AppenderFile(uint8 id, std::string const& name, LogLevel level, AppenderFlags flags, std::vector<char const*> extraArgs);
~AppenderFile();
FILE* OpenFile(std::string const& name, std::string const& mode, bool backup);
AppenderType getType() const override { return TypeIndex::value; }
diff --git a/src/common/Logging/Log.cpp b/src/common/Logging/Log.cpp
index a2e3ee99471..d0ba17b52a7 100644
--- a/src/common/Logging/Log.cpp
+++ b/src/common/Logging/Log.cpp
@@ -17,14 +17,17 @@
*/
#include "Log.h"
-#include "Common.h"
-#include "Config.h"
-#include "Util.h"
#include "AppenderConsole.h"
#include "AppenderFile.h"
+#include "AsioHacksImpl.h"
+#include "Common.h"
+#include "Config.h"
+#include "Errors.h"
+#include "Logger.h"
+#include "LogMessage.h"
#include "LogOperation.h"
-
-#include <cstdio>
+#include "Util.h"
+#include <chrono>
#include <sstream>
Log::Log() : AppenderId(0), lowestLogLevel(LOG_LEVEL_FATAL), _ioService(nullptr), _strand(nullptr)
@@ -45,25 +48,13 @@ uint8 Log::NextAppenderId()
return AppenderId++;
}
-int32 GetConfigIntDefault(std::string base, const char* name, int32 value)
-{
- base.append(name);
- return sConfigMgr->GetIntDefault(base.c_str(), value);
-}
-
-std::string GetConfigStringDefault(std::string base, const char* name, const char* value)
-{
- base.append(name);
- return sConfigMgr->GetStringDefault(base.c_str(), value);
-}
-
Appender* Log::GetAppenderByName(std::string const& name)
{
- AppenderMap::iterator it = appenders.begin();
+ auto it = appenders.begin();
while (it != appenders.end() && it->second && it->second->getName() != name)
++it;
- return it == appenders.end() ? NULL : it->second;
+ return it == appenders.end() ? nullptr : it->second.get();
}
void Log::CreateAppenderFromConfig(std::string const& appenderName)
@@ -71,13 +62,13 @@ void Log::CreateAppenderFromConfig(std::string const& appenderName)
if (appenderName.empty())
return;
- // Format=type, level, flags, optional1, optional2
+ // Format = type, level, flags, optional1, optional2
// if type = File. optional1 = file and option2 = mode
// if type = Console. optional1 = Color
std::string options = sConfigMgr->GetStringDefault(appenderName.c_str(), "");
Tokenizer tokens(options, ',');
- Tokenizer::const_iterator iter = tokens.begin();
+ auto iter = tokens.begin();
size_t size = tokens.size();
std::string name = appenderName.substr(9);
@@ -110,8 +101,8 @@ void Log::CreateAppenderFromConfig(std::string const& appenderName)
try
{
- Appender* appender = factoryFunction->second(NextAppenderId(), name, level, flags, ExtraAppenderArgs(iter, tokens.end()));
- appenders[appender->getId()] = appender;
+ Appender* appender = factoryFunction->second(NextAppenderId(), name, level, flags, std::vector<char const*>(iter, tokens.end()));
+ appenders[appender->getId()].reset(appender);
}
catch (InvalidAppenderArgsException const& iaae)
{
@@ -145,8 +136,8 @@ void Log::CreateLoggerFromConfig(std::string const& appenderName)
return;
}
- Logger& logger = loggers[name];
- if (!logger.getName().empty())
+ std::unique_ptr<Logger>& logger = loggers[name];
+ if (logger)
{
fprintf(stderr, "Error while configuring Logger %s. Already defined\n", name.c_str());
return;
@@ -162,7 +153,7 @@ void Log::CreateLoggerFromConfig(std::string const& appenderName)
if (level < lowestLogLevel)
lowestLogLevel = level;
- logger.Create(name, level);
+ logger = Trinity::make_unique<Logger>(name, level);
//fprintf(stdout, "Log::CreateLoggerFromConfig: Created Logger %s, Level %u\n", name.c_str(), level);
std::istringstream ss(*iter);
@@ -173,7 +164,7 @@ void Log::CreateLoggerFromConfig(std::string const& appenderName)
{
if (Appender* appender = GetAppenderByName(str))
{
- logger.addAppender(appender->getId(), appender);
+ logger->addAppender(appender->getId(), appender);
//fprintf(stdout, "Log::CreateLoggerFromConfig: Added Appender %s to Logger %s\n", appender->getName().c_str(), name.c_str());
}
else
@@ -184,24 +175,16 @@ void Log::CreateLoggerFromConfig(std::string const& appenderName)
void Log::ReadAppendersFromConfig()
{
- std::list<std::string> keys = sConfigMgr->GetKeysByString("Appender.");
-
- while (!keys.empty())
- {
- CreateAppenderFromConfig(keys.front());
- keys.pop_front();
- }
+ std::vector<std::string> keys = sConfigMgr->GetKeysByString("Appender.");
+ for (std::string const& appenderName : keys)
+ CreateAppenderFromConfig(appenderName);
}
void Log::ReadLoggersFromConfig()
{
- std::list<std::string> keys = sConfigMgr->GetKeysByString("Logger.");
-
- while (!keys.empty())
- {
- CreateLoggerFromConfig(keys.front());
- keys.pop_front();
- }
+ std::vector<std::string> keys = sConfigMgr->GetKeysByString("Logger.");
+ for (std::string const& loggerName : keys)
+ CreateLoggerFromConfig(loggerName);
// Bad config configuration, creating default config
if (loggers.find(LOGGER_ROOT) == loggers.end())
@@ -211,26 +194,43 @@ void Log::ReadLoggersFromConfig()
Close(); // Clean any Logger or Appender created
- AppenderConsole* appender = new AppenderConsole(NextAppenderId(), "Console", LOG_LEVEL_DEBUG, APPENDER_FLAGS_NONE, ExtraAppenderArgs());
- appenders[appender->getId()] = appender;
+ AppenderConsole* appender = new AppenderConsole(NextAppenderId(), "Console", LOG_LEVEL_DEBUG, APPENDER_FLAGS_NONE, std::vector<char const*>());
+ appenders[appender->getId()].reset(appender);
- Logger& rootLogger = loggers[LOGGER_ROOT];
- rootLogger.Create(LOGGER_ROOT, LOG_LEVEL_ERROR);
- rootLogger.addAppender(appender->getId(), appender);
+ Logger* rootLogger = new Logger(LOGGER_ROOT, LOG_LEVEL_ERROR);
+ rootLogger->addAppender(appender->getId(), appender);
+ loggers[LOGGER_ROOT].reset(rootLogger);
- Logger& serverLogger = loggers["server"];
- serverLogger.Create("server", LOG_LEVEL_INFO);
- serverLogger.addAppender(appender->getId(), appender);
+ Logger* serverLogger = new Logger("server", LOG_LEVEL_INFO);
+ serverLogger->addAppender(appender->getId(), appender);
+ loggers["server"].reset(serverLogger);
}
}
+void Log::RegisterAppender(uint8 index, AppenderCreatorFn appenderCreateFn)
+{
+ auto itr = appenderFactory.find(index);
+ ASSERT(itr == appenderFactory.end());
+ appenderFactory[index] = appenderCreateFn;
+}
+
+void Log::outMessage(std::string const& filter, LogLevel level, std::string&& message)
+{
+ write(Trinity::make_unique<LogMessage>(level, filter, std::move(message)));
+}
+
+void Log::outCommand(std::string&& message, std::string&& param1)
+{
+ write(Trinity::make_unique<LogMessage>(LOG_LEVEL_INFO, "commands.gm", std::move(message), std::move(param1)));
+}
+
void Log::write(std::unique_ptr<LogMessage>&& msg) const
{
Logger const* logger = GetLoggerByType(msg->type);
if (_ioService)
{
- auto logOperation = std::shared_ptr<LogOperation>(new LogOperation(logger, std::move(msg)));
+ auto logOperation = std::make_shared<LogOperation>(logger, std::move(msg));
_ioService->post(_strand->wrap([logOperation](){ logOperation->call(); }));
}
@@ -238,6 +238,23 @@ void Log::write(std::unique_ptr<LogMessage>&& msg) const
logger->write(msg.get());
}
+Logger const* Log::GetLoggerByType(std::string const& type) const
+{
+ auto it = loggers.find(type);
+ if (it != loggers.end())
+ return it->second.get();
+
+ if (type == LOGGER_ROOT)
+ return nullptr;
+
+ std::string parentLogger = LOGGER_ROOT;
+ size_t found = type.find_last_of('.');
+ if (found != std::string::npos)
+ parentLogger = type.substr(0, found);
+
+ return GetLoggerByType(parentLogger);
+}
+
std::string Log::GetTimestampStr()
{
time_t tt = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now());
@@ -255,7 +272,7 @@ std::string Log::GetTimestampStr()
aTm.tm_year + 1900, aTm.tm_mon + 1, aTm.tm_mday, aTm.tm_hour, aTm.tm_min, aTm.tm_sec);
}
-bool Log::SetLogLevel(std::string const& name, const char* newLevelc, bool isLogger /* = true */)
+bool Log::SetLogLevel(std::string const& name, char const* newLevelc, bool isLogger /* = true */)
{
LogLevel newLevel = LogLevel(atoi(newLevelc));
if (newLevel < 0)
@@ -263,14 +280,14 @@ bool Log::SetLogLevel(std::string const& name, const char* newLevelc, bool isLog
if (isLogger)
{
- LoggerMap::iterator it = loggers.begin();
- while (it != loggers.end() && it->second.getName() != name)
+ auto it = loggers.begin();
+ while (it != loggers.end() && it->second->getName() != name)
++it;
if (it == loggers.end())
return false;
- it->second.setLogLevel(newLevel);
+ it->second->setLogLevel(newLevel);
if (newLevel != LOG_LEVEL_DISABLED && newLevel < lowestLogLevel)
lowestLogLevel = newLevel;
@@ -307,19 +324,34 @@ 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)
+ for (auto it = appenders.begin(); it != appenders.end(); ++it)
it->second->setRealmId(id);
}
void Log::Close()
{
loggers.clear();
- for (AppenderMap::iterator it = appenders.begin(); it != appenders.end(); ++it)
- delete it->second;
-
appenders.clear();
}
+bool Log::ShouldLog(std::string const& type, LogLevel level) const
+{
+ // TODO: Use cache to store "Type.sub1.sub2": "Type" equivalence, should
+ // Speed up in cases where requesting "Type.sub1.sub2" but only configured
+ // Logger "Type"
+
+ // Don't even look for a logger if the LogLevel is lower than lowest log levels across all loggers
+ if (level < lowestLogLevel)
+ return false;
+
+ Logger const* logger = GetLoggerByType(type);
+ if (!logger)
+ return false;
+
+ LogLevel logLevel = logger->getLogLevel();
+ return logLevel != LOG_LEVEL_DISABLED && logLevel <= level;
+}
+
Log* Log::instance()
{
static Log instance;
@@ -331,7 +363,7 @@ void Log::Initialize(boost::asio::io_service* ioService)
if (ioService)
{
_ioService = ioService;
- _strand = new boost::asio::strand(*ioService);
+ _strand = new Trinity::AsioStrand(*ioService);
}
LoadFromConfig();
diff --git a/src/common/Logging/Log.h b/src/common/Logging/Log.h
index fa67a8ea648..5065d8bb5b8 100644
--- a/src/common/Logging/Log.h
+++ b/src/common/Logging/Log.h
@@ -20,20 +20,36 @@
#define TRINITYCORE_LOG_H
#include "Define.h"
-#include "Appender.h"
-#include "Logger.h"
+#include "AsioHacksFwd.h"
+#include "LogCommon.h"
#include "StringFormat.h"
-#include "Common.h"
-#include <boost/asio/io_service.hpp>
-#include <boost/asio/strand.hpp>
-#include <stdarg.h>
-#include <unordered_map>
-#include <string>
#include <memory>
+#include <unordered_map>
+#include <vector>
+
+class Appender;
+class Logger;
+struct LogMessage;
+
+namespace boost
+{
+ namespace asio
+ {
+ class io_service;
+ }
+}
#define LOGGER_ROOT "root"
+typedef Appender*(*AppenderCreatorFn)(uint8 id, std::string const& name, LogLevel level, AppenderFlags flags, std::vector<char const*>&& extraArgs);
+
+template <class AppenderImpl>
+Appender* CreateAppender(uint8 id, std::string const& name, LogLevel level, AppenderFlags flags, std::vector<char const*>&& extraArgs)
+{
+ return new AppenderImpl(id, name, level, flags, std::forward<std::vector<char const*>>(extraArgs));
+}
+
class TC_COMMON_API Log
{
typedef std::unordered_map<std::string, Logger> LoggerMap;
@@ -41,9 +57,12 @@ class TC_COMMON_API Log
private:
Log();
~Log();
+ Log(Log const&) = delete;
+ Log(Log&&) = delete;
+ Log& operator=(Log const&) = delete;
+ Log& operator=(Log&&) = delete;
public:
-
static Log* instance();
void Initialize(boost::asio::io_service* ioService);
@@ -56,8 +75,7 @@ class TC_COMMON_API Log
template<typename Format, typename... Args>
inline void outMessage(std::string const& filter, LogLevel const level, Format&& fmt, Args&&... args)
{
- write(Trinity::make_unique<LogMessage>(level, filter,
- Trinity::StringFormat(std::forward<Format>(fmt), std::forward<Args>(args)...)));
+ outMessage(filter, level, Trinity::StringFormat(std::forward<Format>(fmt), std::forward<Args>(args)...));
}
template<typename Format, typename... Args>
@@ -66,13 +84,7 @@ class TC_COMMON_API Log
if (!ShouldLog("commands.gm", LOG_LEVEL_INFO))
return;
- std::unique_ptr<LogMessage> msg =
- Trinity::make_unique<LogMessage>(LOG_LEVEL_INFO, "commands.gm",
- Trinity::StringFormat(std::forward<Format>(fmt), std::forward<Args>(args)...));
-
- msg->param1 = std::to_string(account);
-
- write(std::move(msg));
+ outCommand(Trinity::StringFormat(std::forward<Format>(fmt), std::forward<Args>(args)...), std::to_string(account));
}
void outCharDump(char const* str, uint32 account_id, uint64 guid, char const* name);
@@ -83,9 +95,7 @@ class TC_COMMON_API Log
void RegisterAppender()
{
using Index = typename AppenderImpl::TypeIndex;
- auto itr = appenderFactory.find(Index::value);
- ASSERT(itr == appenderFactory.end());
- appenderFactory[Index::value] = &CreateAppender<AppenderImpl>;
+ RegisterAppender(Index::value, &CreateAppender<AppenderImpl>);
}
std::string const& GetLogsDir() const { return m_logsDir; }
@@ -102,10 +112,13 @@ class TC_COMMON_API Log
void CreateLoggerFromConfig(std::string const& name);
void ReadAppendersFromConfig();
void ReadLoggersFromConfig();
+ void RegisterAppender(uint8 index, AppenderCreatorFn appenderCreateFn);
+ void outMessage(std::string const& filter, LogLevel level, std::string&& message);
+ void outCommand(std::string&& message, std::string&& param1);
- AppenderCreatorMap appenderFactory;
- AppenderMap appenders;
- LoggerMap loggers;
+ std::unordered_map<uint8, AppenderCreatorFn> appenderFactory;
+ std::unordered_map<uint8, std::unique_ptr<Appender>> appenders;
+ std::unordered_map<std::string, std::unique_ptr<Logger>> loggers;
uint8 AppenderId;
LogLevel lowestLogLevel;
@@ -113,44 +126,9 @@ class TC_COMMON_API Log
std::string m_logsTimestamp;
boost::asio::io_service* _ioService;
- boost::asio::strand* _strand;
+ Trinity::AsioStrand* _strand;
};
-inline Logger const* Log::GetLoggerByType(std::string const& type) const
-{
- LoggerMap::const_iterator it = loggers.find(type);
- if (it != loggers.end())
- return &(it->second);
-
- if (type == LOGGER_ROOT)
- return NULL;
-
- std::string parentLogger = LOGGER_ROOT;
- size_t found = type.find_last_of('.');
- if (found != std::string::npos)
- parentLogger = type.substr(0,found);
-
- return GetLoggerByType(parentLogger);
-}
-
-inline bool Log::ShouldLog(std::string const& type, LogLevel level) const
-{
- // TODO: Use cache to store "Type.sub1.sub2": "Type" equivalence, should
- // Speed up in cases where requesting "Type.sub1.sub2" but only configured
- // Logger "Type"
-
- // Don't even look for a logger if the LogLevel is lower than lowest log levels across all loggers
- if (level < lowestLogLevel)
- return false;
-
- Logger const* logger = GetLoggerByType(type);
- if (!logger)
- return false;
-
- LogLevel logLevel = logger->getLogLevel();
- return logLevel != LOG_LEVEL_DISABLED && logLevel <= level;
-}
-
#define sLog Log::instance()
#define LOG_EXCEPTION_FREE(filterType__, level__, ...) \
@@ -167,7 +145,7 @@ inline bool Log::ShouldLog(std::string const& type, LogLevel level) const
}
#if TRINITY_PLATFORM != TRINITY_PLATFORM_WINDOWS
-void check_args(const char*, ...) ATTR_PRINTF(1, 2);
+void check_args(char const*, ...) ATTR_PRINTF(1, 2);
void check_args(std::string const&, ...);
// This will catch format errors on build time
diff --git a/src/common/Logging/LogCommon.h b/src/common/Logging/LogCommon.h
new file mode 100644
index 00000000000..50ab6131a73
--- /dev/null
+++ b/src/common/Logging/LogCommon.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2008-2017 TrinityCore <http://www.trinitycore.org/>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef LogCommon_h__
+#define LogCommon_h__
+
+enum LogLevel
+{
+ LOG_LEVEL_DISABLED = 0,
+ LOG_LEVEL_TRACE = 1,
+ LOG_LEVEL_DEBUG = 2,
+ LOG_LEVEL_INFO = 3,
+ LOG_LEVEL_WARN = 4,
+ LOG_LEVEL_ERROR = 5,
+ LOG_LEVEL_FATAL = 6,
+
+ NUM_ENABLED_LOG_LEVELS = 6
+};
+
+enum AppenderType : uint8
+{
+ APPENDER_NONE,
+ APPENDER_CONSOLE,
+ APPENDER_FILE,
+ APPENDER_DB
+};
+
+enum AppenderFlags
+{
+ APPENDER_FLAGS_NONE = 0x00,
+ APPENDER_FLAGS_PREFIX_TIMESTAMP = 0x01,
+ APPENDER_FLAGS_PREFIX_LOGLEVEL = 0x02,
+ APPENDER_FLAGS_PREFIX_LOGFILTERTYPE = 0x04,
+ APPENDER_FLAGS_USE_TIMESTAMP = 0x08,
+ APPENDER_FLAGS_MAKE_FILE_BACKUP = 0x10
+};
+
+#endif // LogCommon_h__
diff --git a/src/common/Logging/LogMessage.cpp b/src/common/Logging/LogMessage.cpp
new file mode 100644
index 00000000000..d907fbc12a2
--- /dev/null
+++ b/src/common/Logging/LogMessage.cpp
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2008-2017 TrinityCore <http://www.trinitycore.org/>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "LogMessage.h"
+#include "Util.h"
+
+LogMessage::LogMessage(LogLevel _level, std::string const& _type, std::string&& _text)
+ : level(_level), type(_type), text(std::forward<std::string>(_text)), mtime(time(nullptr))
+{
+}
+
+LogMessage::LogMessage(LogLevel _level, std::string const& _type, std::string&& _text, std::string&& _param1)
+ : level(_level), type(_type), text(std::forward<std::string>(_text)), param1(std::forward<std::string>(_param1)), mtime(time(nullptr))
+{
+}
+
+std::string LogMessage::getTimeStr(time_t time)
+{
+ tm aTm;
+ localtime_r(&time, &aTm);
+ char buf[20];
+ snprintf(buf, 20, "%04d-%02d-%02d_%02d:%02d:%02d", aTm.tm_year + 1900, aTm.tm_mon + 1, aTm.tm_mday, aTm.tm_hour, aTm.tm_min, aTm.tm_sec);
+ return std::string(buf);
+}
+
+std::string LogMessage::getTimeStr() const
+{
+ return getTimeStr(mtime);
+}
diff --git a/src/common/Logging/LogMessage.h b/src/common/Logging/LogMessage.h
new file mode 100644
index 00000000000..ed9c51cec2f
--- /dev/null
+++ b/src/common/Logging/LogMessage.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2008-2017 TrinityCore <http://www.trinitycore.org/>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef LogMessage_h__
+#define LogMessage_h__
+
+#include "Define.h"
+#include "LogCommon.h"
+#include <string>
+#include <ctime>
+
+struct TC_COMMON_API LogMessage
+{
+ LogMessage(LogLevel _level, std::string const& _type, std::string&& _text);
+ LogMessage(LogLevel _level, std::string const& _type, std::string&& _text, std::string&& _param1);
+
+ LogMessage(LogMessage const& /*other*/) = delete;
+ LogMessage& operator=(LogMessage const& /*other*/) = delete;
+
+ static std::string getTimeStr(time_t time);
+ std::string getTimeStr() const;
+
+ LogLevel const level;
+ std::string const type;
+ std::string const text;
+ std::string prefix;
+ std::string param1;
+ time_t mtime;
+
+ ///@ Returns size of the log message content in bytes
+ uint32 Size() const
+ {
+ return static_cast<uint32>(prefix.size() + text.size());
+ }
+};
+
+#endif // LogMessage_h__
diff --git a/src/common/Logging/LogOperation.cpp b/src/common/Logging/LogOperation.cpp
index 81bb98b9cce..c3a3711cc49 100644
--- a/src/common/Logging/LogOperation.cpp
+++ b/src/common/Logging/LogOperation.cpp
@@ -17,6 +17,15 @@
#include "LogOperation.h"
#include "Logger.h"
+#include "LogMessage.h"
+
+LogOperation::LogOperation(Logger const* _logger, std::unique_ptr<LogMessage>&& _msg) : logger(_logger), msg(std::forward<std::unique_ptr<LogMessage>>(_msg))
+{
+}
+
+LogOperation::~LogOperation()
+{
+}
int LogOperation::call()
{
diff --git a/src/common/Logging/LogOperation.h b/src/common/Logging/LogOperation.h
index a7230d1749d..ddf5ef1debc 100644
--- a/src/common/Logging/LogOperation.h
+++ b/src/common/Logging/LogOperation.h
@@ -18,8 +18,8 @@
#ifndef LOGOPERATION_H
#define LOGOPERATION_H
-#include <memory>
#include "Define.h"
+#include <memory>
class Logger;
struct LogMessage;
@@ -27,11 +27,9 @@ struct LogMessage;
class TC_COMMON_API LogOperation
{
public:
- LogOperation(Logger const* _logger, std::unique_ptr<LogMessage>&& _msg)
- : logger(_logger), msg(std::forward<std::unique_ptr<LogMessage>>(_msg))
- { }
+ LogOperation(Logger const* _logger, std::unique_ptr<LogMessage>&& _msg);
- ~LogOperation() { }
+ ~LogOperation();
int call();
diff --git a/src/common/Logging/Logger.cpp b/src/common/Logging/Logger.cpp
index 8e1f9c7ef9d..a3a72f15642 100644
--- a/src/common/Logging/Logger.cpp
+++ b/src/common/Logging/Logger.cpp
@@ -16,14 +16,10 @@
*/
#include "Logger.h"
+#include "Appender.h"
+#include "LogMessage.h"
-Logger::Logger(): name(""), level(LOG_LEVEL_DISABLED) { }
-
-void Logger::Create(std::string const& _name, LogLevel _level)
-{
- name = _name;
- level = _level;
-}
+Logger::Logger(std::string const& _name, LogLevel _level): name(_name), level(_level) { }
std::string const& Logger::getName() const
{
@@ -58,7 +54,7 @@ void Logger::write(LogMessage* message) const
return;
}
- for (AppenderMap::const_iterator it = appenders.begin(); it != appenders.end(); ++it)
+ for (auto it = appenders.begin(); it != appenders.end(); ++it)
if (it->second)
it->second->write(message);
}
diff --git a/src/common/Logging/Logger.h b/src/common/Logging/Logger.h
index 1446062c22b..7aac15396f3 100644
--- a/src/common/Logging/Logger.h
+++ b/src/common/Logging/Logger.h
@@ -18,15 +18,20 @@
#ifndef LOGGER_H
#define LOGGER_H
-#include "Appender.h"
+#include "Define.h"
+#include "LogCommon.h"
+#include <unordered_map>
+#include <string>
+
+class Appender;
+struct LogMessage;
class TC_COMMON_API Logger
{
public:
- Logger();
+ Logger(std::string const& name, LogLevel level);
- void Create(std::string const& name, LogLevel level);
- void addAppender(uint8 type, Appender *);
+ void addAppender(uint8 type, Appender* appender);
void delAppender(uint8 type);
std::string const& getName() const;
@@ -37,7 +42,7 @@ class TC_COMMON_API Logger
private:
std::string name;
LogLevel level;
- AppenderMap appenders;
+ std::unordered_map<uint8, Appender*> appenders;
};
#endif