aboutsummaryrefslogtreecommitdiff
path: root/src/server/shared/Logging/Log.cpp
diff options
context:
space:
mode:
authorSubv <s.v.h21@hotmail.com>2012-08-07 13:44:22 -0500
committerSubv <s.v.h21@hotmail.com>2012-08-07 13:44:22 -0500
commitd82266bc0ef31df82dc67c1023d6208df6ac247b (patch)
treea0c5970a82e568ca54a25809555b7abad52e1bc1 /src/server/shared/Logging/Log.cpp
parent224cf663e2af8b355b4bdca4069080636321b0ba (diff)
parentf8cd39b2ed1056f409c2690ac8bb661fbcb68e18 (diff)
Merge branch 'master' of github.com:TrinityCore/TrinityCore into 4.3.4
Conflicts: src/server/authserver/Server/AuthSocket.cpp src/server/game/Achievements/AchievementMgr.cpp src/server/game/Chat/Chat.h src/server/game/Chat/Commands/Level1.cpp src/server/game/Chat/Commands/Level2.cpp src/server/game/Chat/Commands/Level3.cpp src/server/game/DataStores/DBCStores.cpp src/server/game/DataStores/DBCStructure.h src/server/game/Entities/Object/Object.cpp src/server/game/Entities/Object/Updates/UpdateData.cpp src/server/game/Entities/Player/Player.cpp src/server/game/Globals/ObjectMgr.cpp src/server/game/Guilds/Guild.cpp src/server/game/Guilds/GuildMgr.cpp src/server/game/Handlers/AuctionHouseHandler.cpp src/server/game/Handlers/CharacterHandler.cpp src/server/game/Handlers/ChatHandler.cpp src/server/game/Handlers/GroupHandler.cpp src/server/game/Handlers/ItemHandler.cpp src/server/game/Handlers/MailHandler.cpp src/server/game/Handlers/MiscHandler.cpp src/server/game/Handlers/MovementHandler.cpp src/server/game/Handlers/PetHandler.cpp src/server/game/Handlers/QuestHandler.cpp src/server/game/Handlers/VehicleHandler.cpp src/server/game/Server/WorldSession.cpp src/server/game/Server/WorldSocket.cpp src/server/game/Spells/Auras/SpellAuraEffects.cpp src/server/game/Spells/SpellEffects.cpp src/server/game/Spells/SpellMgr.cpp src/server/game/World/World.cpp src/server/scripts/Commands/cs_debug.cpp src/server/scripts/Commands/cs_modify.cpp src/server/scripts/Commands/cs_reload.cpp src/server/scripts/Kalimdor/azuremyst_isle.cpp src/server/shared/Logging/Log.cpp src/server/shared/Logging/Log.h src/server/worldserver/worldserver.conf.dist
Diffstat (limited to 'src/server/shared/Logging/Log.cpp')
-rw-r--r--[-rwxr-xr-x]src/server/shared/Logging/Log.cpp1188
1 files changed, 301 insertions, 887 deletions
diff --git a/src/server/shared/Logging/Log.cpp b/src/server/shared/Logging/Log.cpp
index 493e30d36c0..14234dfb155 100755..100644
--- a/src/server/shared/Logging/Log.cpp
+++ b/src/server/shared/Logging/Log.cpp
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2008-2012 TrinityCore <http://www.trinitycore.org/>
- * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
+ * Copyright (C) 2005-2008 MaNGOS <http://getmangos.com/>
*
* 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
@@ -16,1071 +16,485 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#include "Common.h"
#include "Log.h"
-#include "Configuration/Config.h"
+#include "Common.h"
+#include "Config.h"
#include "Util.h"
+#include "AppenderConsole.h"
+#include "AppenderFile.h"
+#include "AppenderDB.h"
+#include "LogOperation.h"
-#include "Implementation/LoginDatabase.h" // For logging
-extern LoginDatabaseWorkerPool LoginDatabase;
-
-#include <stdarg.h>
-#include <stdio.h>
+#include <cstdarg>
+#include <cstdio>
+#include <sstream>
-Log::Log() :
- raLogfile(NULL), logfile(NULL), gmLogfile(NULL), charLogfile(NULL),
- dberLogfile(NULL), chatLogfile(NULL), arenaLogFile(NULL), sqlLogFile(NULL), sqlDevLogFile(NULL), wardenLogFile(NULL),
- m_gmlog_per_account(false), m_enableLogDBLater(false),
- m_enableLogDB(false), m_colored(false)
+Log::Log() : worker(NULL)
{
- Initialize();
+ SetRealmID(0);
+ m_logsTimestamp = "_" + GetTimestampStr();
+ LoadFromConfig();
}
Log::~Log()
{
- if (logfile != NULL)
- fclose(logfile);
- logfile = NULL;
-
- if (gmLogfile != NULL)
- fclose(gmLogfile);
- gmLogfile = NULL;
-
- if (charLogfile != NULL)
- fclose(charLogfile);
- charLogfile = NULL;
-
- if (dberLogfile != NULL)
- fclose(dberLogfile);
- dberLogfile = NULL;
-
- if (raLogfile != NULL)
- fclose(raLogfile);
- raLogfile = NULL;
-
- if (chatLogfile != NULL)
- fclose(chatLogfile);
- chatLogfile = NULL;
-
- if (arenaLogFile != NULL)
- fclose(arenaLogFile);
- arenaLogFile = NULL;
-
- if (sqlLogFile != NULL)
- fclose(sqlLogFile);
- sqlLogFile = NULL;
-
- if (sqlDevLogFile != NULL)
- fclose(sqlDevLogFile);
- sqlDevLogFile = NULL;
-
- if (wardenLogFile != NULL)
- fclose(wardenLogFile);
- wardenLogFile = NULL;
+ Close();
}
-void Log::SetLogLevel(char *Level)
+uint8 Log::NextAppenderId()
{
- int32 NewLevel = atoi((char*)Level);
- if (NewLevel < 0)
- NewLevel = 0;
- m_logLevel = NewLevel;
-
- outString("LogLevel is %u", m_logLevel);
+ return AppenderId++;
}
-void Log::SetLogFileLevel(char *Level)
+int32 GetConfigIntDefault(std::string base, const char* name, int32 value)
{
- int32 NewLevel = atoi((char*)Level);
- if (NewLevel < 0)
- NewLevel = 0;
- m_logFileLevel = NewLevel;
-
- outString("LogFileLevel is %u", m_logFileLevel);
+ base.append(name);
+ return ConfigMgr::GetIntDefault(base.c_str(), value);
}
-void Log::SetDBLogLevel(char *Level)
+std::string GetConfigStringDefault(std::string base, const char* name, const char* value)
{
- int32 NewLevel = atoi((char*)Level);
- if (NewLevel < 0)
- NewLevel = 0;
- m_dbLogLevel = NewLevel;
-
- outString("DBLogLevel is %u", m_dbLogLevel);
+ base.append(name);
+ return ConfigMgr::GetStringDefault(base.c_str(), value);
}
-void Log::Initialize()
+// Returns default logger if the requested logger is not found
+Logger* Log::GetLoggerByType(LogFilterType filter)
{
- /// Check whether we'll log GM commands/RA events/character outputs/chat stuffs
- m_dbChar = ConfigMgr::GetBoolDefault("LogDB.Char", false);
- m_dbRA = ConfigMgr::GetBoolDefault("LogDB.RA", false);
- m_dbGM = ConfigMgr::GetBoolDefault("LogDB.GM", false);
- m_dbChat = ConfigMgr::GetBoolDefault("LogDB.Chat", false);
-
- /// Realm must be 0 by default
- SetRealmID(0);
-
- /// Common log files data
- m_logsDir = ConfigMgr::GetStringDefault("LogsDir", "");
- if (!m_logsDir.empty())
- if ((m_logsDir.at(m_logsDir.length() - 1) != '/') && (m_logsDir.at(m_logsDir.length() - 1) != '\\'))
- m_logsDir.push_back('/');
-
- m_logsTimestamp = "_" + GetTimestampStr();
-
- /// Open specific log files
- logfile = openLogFile("LogFile", "LogTimestamp", "w");
- InitColors(ConfigMgr::GetStringDefault("LogColors", ""));
-
- m_gmlog_per_account = ConfigMgr::GetBoolDefault("GmLogPerAccount", false);
- if (!m_gmlog_per_account)
- gmLogfile = openLogFile("GMLogFile", "GmLogTimestamp", "a");
- else
- {
- // GM log settings for per account case
- m_gmlog_filename_format = ConfigMgr::GetStringDefault("GMLogFile", "");
- if (!m_gmlog_filename_format.empty())
- {
- bool m_gmlog_timestamp = ConfigMgr::GetBoolDefault("GmLogTimestamp", false);
-
- size_t dot_pos = m_gmlog_filename_format.find_last_of('.');
- if (dot_pos!=m_gmlog_filename_format.npos)
- {
- if (m_gmlog_timestamp)
- m_gmlog_filename_format.insert(dot_pos, m_logsTimestamp);
-
- m_gmlog_filename_format.insert(dot_pos, "_#%u");
- }
- else
- {
- m_gmlog_filename_format += "_#%u";
-
- if (m_gmlog_timestamp)
- m_gmlog_filename_format += m_logsTimestamp;
- }
+ LoggerMap::iterator it = loggers.begin();
+ while (it != loggers.end() && it->second.getType() != filter)
+ ++it;
- m_gmlog_filename_format = m_logsDir + m_gmlog_filename_format;
- }
- }
-
- charLogfile = openLogFile("CharLogFile", "CharLogTimestamp", "a");
- dberLogfile = openLogFile("DBErrorLogFile", NULL, "a");
- raLogfile = openLogFile("RaLogFile", NULL, "a");
- chatLogfile = openLogFile("ChatLogFile", "ChatLogTimestamp", "a");
- arenaLogFile = openLogFile("ArenaLogFile", NULL, "a");
- sqlLogFile = openLogFile("SQLDriverLogFile", NULL, "a");
- sqlDevLogFile = openLogFile("SQLDeveloperLogFile", NULL, "a");
- wardenLogFile = openLogFile("Warden.LogFile",NULL,"a");
-
- // Main log file settings
- m_logLevel = ConfigMgr::GetIntDefault("LogLevel", LOGL_NORMAL);
- m_logFileLevel = ConfigMgr::GetIntDefault("LogFileLevel", LOGL_NORMAL);
- m_dbLogLevel = ConfigMgr::GetIntDefault("DBLogLevel", LOGL_NORMAL);
- m_sqlDriverQueryLogging = ConfigMgr::GetBoolDefault("SQLDriverQueryLogging", false);
-
- m_DebugLogMask = DebugLogFilters(ConfigMgr::GetIntDefault("DebugLogMask", LOG_FILTER_NONE));
-
- // Char log settings
- m_charLog_Dump = ConfigMgr::GetBoolDefault("CharLogDump", false);
- m_charLog_Dump_Separate = ConfigMgr::GetBoolDefault("CharLogDump.Separate", false);
- if (m_charLog_Dump_Separate)
- {
- m_dumpsDir = ConfigMgr::GetStringDefault("CharLogDump.SeparateDir", "");
- if (!m_dumpsDir.empty())
- if ((m_dumpsDir.at(m_dumpsDir.length() - 1) != '/') && (m_dumpsDir.at(m_dumpsDir.length() - 1) != '\\'))
- m_dumpsDir.push_back('/');
- }
-}
-
-void Log::ReloadConfig()
-{
- m_logLevel = ConfigMgr::GetIntDefault("LogLevel", LOGL_NORMAL);
- m_logFileLevel = ConfigMgr::GetIntDefault("LogFileLevel", LOGL_NORMAL);
- m_dbLogLevel = ConfigMgr::GetIntDefault("DBLogLevel", LOGL_NORMAL);
-
- m_DebugLogMask = DebugLogFilters(ConfigMgr::GetIntDefault("DebugLogMask", LOG_FILTER_NONE));
+ return it == loggers.end() ? &(loggers[0]) : &(it->second);
}
-FILE* Log::openLogFile(char const* configFileName, char const* configTimeStampFlag, char const* mode)
+Appender* Log::GetAppenderByName(std::string const& name)
{
- std::string logfn=ConfigMgr::GetStringDefault(configFileName, "");
- if (logfn.empty())
- return NULL;
-
- if (configTimeStampFlag && ConfigMgr::GetBoolDefault(configTimeStampFlag, false))
- {
- size_t dot_pos = logfn.find_last_of(".");
- if (dot_pos!=logfn.npos)
- logfn.insert(dot_pos, m_logsTimestamp);
- else
- logfn += m_logsTimestamp;
- }
+ AppenderMap::iterator it = appenders.begin();
+ while (it != appenders.end() && it->second && it->second->getName() != name)
+ ++it;
- return fopen((m_logsDir+logfn).c_str(), mode);
+ return it == appenders.end() ? NULL : it->second;
}
-FILE* Log::openGmlogPerAccount(uint32 account)
+void Log::CreateAppenderFromConfig(const char* name)
{
- if (m_gmlog_filename_format.empty())
- return NULL;
+ if (!name || *name == '\0')
+ return;
- char namebuf[TRINITY_PATH_MAX];
- snprintf(namebuf, TRINITY_PATH_MAX, m_gmlog_filename_format.c_str(), account);
- return fopen(namebuf, "a");
-}
+ // Format=type,level,flags,optional1,optional2
+ // if type = File. optional1 = file and option2 = mode
+ // if type = Console. optional1 = Color
+ std::string options = "Appender.";
+ options.append(name);
+ options = ConfigMgr::GetStringDefault(options.c_str(), "");
+ Tokens tokens(options, ',');
+ Tokens::iterator iter = tokens.begin();
-void Log::outTimestamp(FILE* file)
-{
- time_t t = time(NULL);
- tm* aTm = localtime(&t);
- // YYYY year
- // MM month (2 digits 01-12)
- // DD day (2 digits 01-31)
- // HH hour (2 digits 00-23)
- // MM minutes (2 digits 00-59)
- // SS seconds (2 digits 00-59)
- fprintf(file, "%-4d-%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);
-}
-
-void Log::InitColors(const std::string& str)
-{
- if (str.empty())
+ if (tokens.size() < 2)
{
- m_colored = false;
+ fprintf(stderr, "Log::CreateAppenderFromConfig: Wrong configuration for appender %s. Config line: %s\n", name, options.c_str());
return;
}
- int color[4];
-
- std::istringstream ss(str);
-
- for (uint8 i = 0; i < LogLevels; ++i)
+ AppenderFlags flags = APPENDER_FLAGS_NONE;
+ AppenderType type = AppenderType(atoi(*iter));
+ ++iter;
+ LogLevel level = LogLevel(atoi(*iter));
+ if (level > LOG_LEVEL_FATAL)
{
- ss >> color[i];
-
- if (!ss)
- return;
-
- if (color[i] < 0 || color[i] >= Colors)
- return;
+ fprintf(stderr, "Log::CreateAppenderFromConfig: Wrong Log Level %u for appender %s\n", level, name);
+ return;
}
- for (uint8 i = 0; i < LogLevels; ++i)
- m_colors[i] = ColorTypes(color[i]);
-
- m_colored = true;
-}
-
-void Log::SetColor(bool stdout_stream, ColorTypes color)
-{
- #if PLATFORM == PLATFORM_WINDOWS
- static WORD WinColorFG[Colors] =
- {
- 0, // BLACK
- FOREGROUND_RED, // RED
- FOREGROUND_GREEN, // GREEN
- FOREGROUND_RED | FOREGROUND_GREEN, // BROWN
- FOREGROUND_BLUE, // BLUE
- FOREGROUND_RED | FOREGROUND_BLUE, // MAGENTA
- FOREGROUND_GREEN | FOREGROUND_BLUE, // CYAN
- FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE, // WHITE
- // YELLOW
- FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_INTENSITY,
- // RED_BOLD
- FOREGROUND_RED | FOREGROUND_INTENSITY,
- // GREEN_BOLD
- FOREGROUND_GREEN | FOREGROUND_INTENSITY,
- FOREGROUND_BLUE | FOREGROUND_INTENSITY, // BLUE_BOLD
- // MAGENTA_BOLD
- FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_INTENSITY,
- // CYAN_BOLD
- FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_INTENSITY,
- // WHITE_BOLD
- FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_INTENSITY
- };
-
- HANDLE hConsole = GetStdHandle(stdout_stream ? STD_OUTPUT_HANDLE : STD_ERROR_HANDLE );
- SetConsoleTextAttribute(hConsole, WinColorFG[color]);
- #else
- enum ANSITextAttr
- {
- TA_NORMAL=0,
- TA_BOLD=1,
- TA_BLINK=5,
- TA_REVERSE=7
- };
-
- enum ANSIFgTextAttr
- {
- FG_BLACK=30, FG_RED, FG_GREEN, FG_BROWN, FG_BLUE,
- FG_MAGENTA, FG_CYAN, FG_WHITE, FG_YELLOW
- };
-
- enum ANSIBgTextAttr
+ if (++iter != tokens.end())
+ flags = AppenderFlags(atoi(*iter));
+
+ switch (type)
{
- BG_BLACK=40, BG_RED, BG_GREEN, BG_BROWN, BG_BLUE,
- BG_MAGENTA, BG_CYAN, BG_WHITE
- };
-
- static uint8 UnixColorFG[Colors] =
- {
- FG_BLACK, // BLACK
- FG_RED, // RED
- FG_GREEN, // GREEN
- FG_BROWN, // BROWN
- FG_BLUE, // BLUE
- FG_MAGENTA, // MAGENTA
- FG_CYAN, // CYAN
- FG_WHITE, // WHITE
- FG_YELLOW, // YELLOW
- FG_RED, // LRED
- FG_GREEN, // LGREEN
- FG_BLUE, // LBLUE
- FG_MAGENTA, // LMAGENTA
- FG_CYAN, // LCYAN
- FG_WHITE // LWHITE
- };
-
- fprintf((stdout_stream? stdout : stderr), "\x1b[%d%sm", UnixColorFG[color], (color >= YELLOW && color < Colors ? ";1" : ""));
- #endif
-}
-
-void Log::ResetColor(bool stdout_stream)
-{
- #if PLATFORM == 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
-}
+ case APPENDER_CONSOLE:
+ {
+ if (flags == APPENDER_FLAGS_NONE)
+ flags = AppenderFlags(APPENDER_FLAGS_PREFIX_LOGLEVEL | APPENDER_FLAGS_PREFIX_LOGFILTERTYPE);
+
+ AppenderConsole* appender = new AppenderConsole(NextAppenderId(), name, level, flags);
+ appenders[appender->getId()] = appender;
+ if (++iter != tokens.end())
+ appender->InitColors(*iter);
+ //fprintf(stdout, "Log::CreateAppenderFromConfig: Created Appender %s (%u), Type CONSOLE, Mask %u\n", appender->getName().c_str(), appender->getId(), appender->getLogLevel()); // DEBUG - RemoveMe
+ break;
+ }
+ case APPENDER_FILE:
+ {
+ std::string filename;
+ std::string mode = "a";
-std::string Log::GetTimestampStr()
-{
- time_t t = time(NULL);
- tm* aTm = localtime(&t);
- // YYYY year
- // MM month (2 digits 01-12)
- // DD day (2 digits 01-31)
- // HH hour (2 digits 00-23)
- // MM minutes (2 digits 00-59)
- // SS seconds (2 digits 00-59)
- 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);
-}
+ if (++iter == tokens.end())
+ {
+ fprintf(stderr, "Log::CreateAppenderFromConfig: Missing file name for appender %s\n", name);
+ return;
+ }
-void Log::outDB(LogTypes type, const char * str)
-{
- if (!str || type >= MAX_LOG_TYPES)
- return;
+ if (flags == APPENDER_FLAGS_NONE)
+ flags = AppenderFlags(APPENDER_FLAGS_PREFIX_LOGLEVEL | APPENDER_FLAGS_PREFIX_LOGFILTERTYPE | APPENDER_FLAGS_PREFIX_TIMESTAMP);
- std::string logStr(str);
- if (logStr.empty())
- return;
+ filename = *iter;
- PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_INS_LOG);
+ if (++iter != tokens.end())
+ mode = *iter;
- stmt->setInt32(0, realm);
- stmt->setUInt8(1, uint8(type));
- stmt->setString(2, logStr);
+ 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;
+ }
- LoginDatabase.Execute(stmt);
+ uint8 id = NextAppenderId();
+ appenders[id] = new AppenderFile(id, name, level, filename.c_str(), m_logsDir.c_str(), mode.c_str(), flags);
+ //fprintf(stdout, "Log::CreateAppenderFromConfig: Created Appender %s (%u), Type FILE, Mask %u, File %s, Mode %s\n", name, id, level, filename.c_str(), mode.c_str()); // DEBUG - RemoveMe
+ break;
+ }
+ case APPENDER_DB:
+ {
+ uint8 id = NextAppenderId();
+ appenders[id] = new AppenderDB(id, name, level, realm);
+ break;
+ }
+ default:
+ fprintf(stderr, "Log::CreateAppenderFromConfig: Unknown type %u for appender %s\n", type, name);
+ break;
+ }
}
-void Log::outString(const char * str, ...)
+void Log::CreateLoggerFromConfig(const char* name)
{
- if (!str)
+ if (!name || *name == '\0')
return;
- if (m_enableLogDB)
- {
- // we don't want empty strings in the DB
- std::string s(str);
- if (s.empty() || s == " ")
- return;
-
- va_list ap2;
- va_start(ap2, str);
- char nnew_str[MAX_QUERY_LEN];
- vsnprintf(nnew_str, MAX_QUERY_LEN, str, ap2);
- outDB(LOG_TYPE_STRING, nnew_str);
- va_end(ap2);
- }
-
- if (m_colored)
- SetColor(true, m_colors[LOGL_NORMAL]);
-
- va_list ap;
+ LogLevel level = LOG_LEVEL_DISABLED;
+ int32 type = -1;
- va_start(ap, str);
- vutf8printf(stdout, str, &ap);
- va_end(ap);
+ std::string options = "Logger.";
+ options.append(name);
+ options = ConfigMgr::GetStringDefault(options.c_str(), "");
- if (m_colored)
- ResetColor(true);
+ Tokens tokens(options, ',');
+ Tokens::iterator iter = tokens.begin();
- printf("\n");
- if (logfile)
+ if (tokens.size() != 3)
{
- outTimestamp(logfile);
- va_start(ap, str);
- vfprintf(logfile, str, ap);
- fprintf(logfile, "\n");
- va_end(ap);
-
- fflush(logfile);
+ fprintf(stderr, "Log::CreateLoggerFromConfig: Wrong configuration for logger %s. Config line: %s\n", name, options.c_str());
+ return;
}
- fflush(stdout);
-}
-void Log::outString()
-{
- printf("\n");
- if (logfile)
+ type = atoi(*iter);
+ if (type > MaxLogFilter)
{
- outTimestamp(logfile);
- fprintf(logfile, "\n");
- fflush(logfile);
+ fprintf(stderr, "Log::CreateLoggerFromConfig: Wrong type %u for logger %s\n", type, name);
+ return;
}
- fflush(stdout);
-}
-void Log::outCrash(const char * err, ...)
-{
- if (!err)
+ Logger& logger = loggers[type];
+ if (!logger.getName().empty())
+ {
+ fprintf(stderr, "Error while configuring Logger %s. Already defined\n", name);
return;
+ }
- if (m_enableLogDB)
+ ++iter;
+ level = LogLevel(atoi(*iter));
+ if (level > LOG_LEVEL_FATAL)
{
- va_list ap2;
- va_start(ap2, err);
- char nnew_str[MAX_QUERY_LEN];
- vsnprintf(nnew_str, MAX_QUERY_LEN, err, ap2);
- outDB(LOG_TYPE_CRASH, nnew_str);
- va_end(ap2);
+ fprintf(stderr, "Log::CreateLoggerFromConfig: Wrong Log Level %u for logger %s\n", type, name);
+ return;
}
- if (m_colored)
- SetColor(false, LRED);
+ logger.Create(name, LogFilterType(type), level);
+ //fprintf(stdout, "Log::CreateLoggerFromConfig: Created Logger %s, Type %u, mask %u\n", name, LogFilterType(type), level); // DEBUG - RemoveMe
- va_list ap;
-
- va_start(ap, err);
- vutf8printf(stderr, err, &ap);
- va_end(ap);
+ ++iter;
+ std::istringstream ss(*iter);
+ std::string str;
- if (m_colored)
- ResetColor(false);
-
- fprintf(stderr, "\n");
- if (logfile)
+ ss >> str;
+ while (ss)
{
- outTimestamp(logfile);
- fprintf(logfile, "CRASH ALERT: ");
-
- va_start(ap, err);
- vfprintf(logfile, err, ap);
- va_end(ap);
-
- fprintf(logfile, "\n");
- fflush(logfile);
+ if (Appender* appender = GetAppenderByName(str))
+ {
+ logger.addAppender(appender->getId(), appender);
+ //fprintf(stdout, "Log::CreateLoggerFromConfig: Added Appender %s to Logger %s\n", appender->getName().c_str(), name); // DEBUG - RemoveMe
+ }
+ else
+ fprintf(stderr, "Error while configuring Appender %s in Logger %s. Appender does not exist", str.c_str(), name);
+ ss >> str;
}
- fflush(stderr);
}
-void Log::outError(const char * err, ...)
+void Log::ReadAppendersFromConfig()
{
- if (!err)
- return;
+ std::istringstream ss(ConfigMgr::GetStringDefault("Appenders", ""));
+ std::string name;
- if (m_enableLogDB)
+ do
{
- va_list ap2;
- va_start(ap2, err);
- char nnew_str[MAX_QUERY_LEN];
- vsnprintf(nnew_str, MAX_QUERY_LEN, err, ap2);
- outDB(LOG_TYPE_ERROR, nnew_str);
- va_end(ap2);
+ ss >> name;
+ CreateAppenderFromConfig(name.c_str());
+ name = "";
}
+ while (ss);
+}
- if (m_colored)
- SetColor(false, LRED);
-
- va_list ap;
-
- va_start(ap, err);
- vutf8printf(stderr, err, &ap);
- va_end(ap);
-
- if (m_colored)
- ResetColor(false);
+void Log::ReadLoggersFromConfig()
+{
+ std::istringstream ss(ConfigMgr::GetStringDefault("Loggers", ""));
+ std::string name;
- fprintf( stderr, "\n");
- if (logfile)
+ do
{
- outTimestamp(logfile);
- fprintf(logfile, "ERROR: ");
+ ss >> name;
+ CreateLoggerFromConfig(name.c_str());
+ name = "";
+ }
+ while (ss);
- va_start(ap, err);
- vfprintf(logfile, err, ap);
- va_end(ap);
+ LoggerMap::const_iterator it = loggers.begin();
- fprintf(logfile, "\n");
- fflush(logfile);
- }
- fflush(stderr);
+ while (it != loggers.end() && it->first)
+ ++it;
+
+ // root logger must exist. Marking as disabled as its not configured
+ if (it == loggers.end())
+ loggers[0].Create("root", LOG_FILTER_GENERAL, LOG_LEVEL_DISABLED);
}
-void Log::outArena(const char * str, ...)
+void Log::EnableDBAppenders()
{
- if (!str)
- return;
-
- if (arenaLogFile)
- {
- va_list ap;
- outTimestamp(arenaLogFile);
- va_start(ap, str);
- vfprintf(arenaLogFile, str, ap);
- fprintf(arenaLogFile, "\n");
- va_end(ap);
- fflush(arenaLogFile);
- }
+ for (AppenderMap::iterator it = appenders.begin(); it != appenders.end(); ++it)
+ if (it->second && it->second->getType() == APPENDER_DB)
+ ((AppenderDB *)it->second)->setEnable(true);
}
-void Log::outSQLDriver(const char* str, ...)
+void Log::log(LogFilterType filter, LogLevel level, char const* str, ...)
{
- if (!str)
+ if (!str || !ShouldLog(filter, level))
return;
va_list ap;
va_start(ap, str);
- vutf8printf(stdout, str, &ap);
- va_end(ap);
-
- printf("\n");
-
- if (sqlLogFile)
- {
- outTimestamp(sqlLogFile);
-
- va_list apSQL;
- va_start(apSQL, str);
- vfprintf(sqlLogFile, str, apSQL);
- va_end(apSQL);
- fprintf(sqlLogFile, "\n");
- fflush(sqlLogFile);
- }
+ vlog(filter, level, str, ap);
- fflush(stdout);
+ va_end(ap);
}
-void Log::outErrorDb(const char * err, ...)
+void Log::vlog(LogFilterType filter, LogLevel level, char const* str, va_list argptr)
{
- if (!err)
- return;
-
- if (m_colored)
- SetColor(false, LRED);
-
- va_list ap;
+ char text[MAX_QUERY_LEN];
+ vsnprintf(text, MAX_QUERY_LEN, str, argptr);
+ write(new LogMessage(level, filter, text));
+}
- va_start(ap, err);
- vutf8printf(stderr, err, &ap);
- va_end(ap);
+void Log::write(LogMessage* msg)
+{
+ msg->text.append("\n");
+ Logger* logger = GetLoggerByType(msg->type);
+ worker->enqueue(new LogOperation(logger, msg));
+}
- if (m_colored)
- ResetColor(false);
+std::string Log::GetTimestampStr()
+{
+ time_t t = time(NULL);
+ tm* aTm = localtime(&t);
+ // YYYY year
+ // MM month (2 digits 01-12)
+ // DD day (2 digits 01-31)
+ // HH hour (2 digits 00-23)
+ // MM minutes (2 digits 00-59)
+ // SS seconds (2 digits 00-59)
+ 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);
+}
- fprintf( stderr, "\n" );
+bool Log::SetLogLevel(std::string const& name, const char* newLevelc, bool isLogger /* = true */)
+{
+ LogLevel newLevel = LogLevel(atoi(newLevelc));
+ if (newLevel < 0)
+ return false;
- if (logfile)
+ if (isLogger)
{
- outTimestamp(logfile);
- fprintf(logfile, "ERROR: " );
+ LoggerMap::iterator it = loggers.begin();
+ while (it != loggers.end() && it->second.getName() != name)
+ ++it;
- va_start(ap, err);
- vfprintf(logfile, err, ap);
- va_end(ap);
+ if (it == loggers.end())
+ return false;
- fprintf(logfile, "\n" );
- fflush(logfile);
+ it->second.setLogLevel(newLevel);
}
-
- if (dberLogfile)
+ else
{
- outTimestamp(dberLogfile);
- va_start(ap, err);
- vfprintf(dberLogfile, err, ap);
- va_end(ap);
+ Appender* appender = GetAppenderByName(name);
+ if (!appender)
+ return false;
- fprintf(dberLogfile, "\n" );
- fflush(dberLogfile);
+ appender->setLogLevel(newLevel);
}
- fflush(stderr);
+ return true;
}
-void Log::outBasic(const char * str, ...)
+bool Log::ShouldLog(LogFilterType type, LogLevel level) const
{
- if (!str)
- return;
+ LoggerMap::const_iterator it = loggers.begin();
+ while (it != loggers.end() && it->second.getType() != type)
+ ++it;
- if (m_enableLogDB && m_dbLogLevel > LOGL_NORMAL)
+ if (it != loggers.end())
{
- va_list ap2;
- va_start(ap2, str);
- char nnew_str[MAX_QUERY_LEN];
- vsnprintf(nnew_str, MAX_QUERY_LEN, str, ap2);
- outDB(LOG_TYPE_BASIC, nnew_str);
- va_end(ap2);
+ LogLevel loggerLevel = it->second.getLogLevel();
+ return loggerLevel && loggerLevel <= level;
}
- if (m_logLevel > LOGL_NORMAL)
- {
- if (m_colored)
- SetColor(true, m_colors[LOGL_BASIC]);
-
- va_list ap;
- va_start(ap, str);
- vutf8printf(stdout, str, &ap);
- va_end(ap);
+ if (type != LOG_FILTER_GENERAL)
+ return ShouldLog(LOG_FILTER_GENERAL, level);
- if (m_colored)
- ResetColor(true);
-
- printf("\n");
-
- if (logfile)
- {
- outTimestamp(logfile);
- va_list ap2;
- va_start(ap2, str);
- vfprintf(logfile, str, ap2);
- fprintf(logfile, "\n" );
- va_end(ap2);
- fflush(logfile);
- }
- }
- fflush(stdout);
+ return false;
}
-void Log::outDetail(const char * str, ...)
+void Log::outTrace(LogFilterType filter, const char * str, ...)
{
- if (!str)
+ if (!str || !ShouldLog(filter, LOG_LEVEL_TRACE))
return;
- if (m_enableLogDB && m_dbLogLevel > LOGL_BASIC)
- {
- va_list ap2;
- va_start(ap2, str);
- char nnew_str[MAX_QUERY_LEN];
- vsnprintf(nnew_str, MAX_QUERY_LEN, str, ap2);
- outDB(LOG_TYPE_DETAIL, nnew_str);
- va_end(ap2);
- }
-
- if (m_logLevel > LOGL_BASIC)
- {
- if (m_colored)
- SetColor(true, m_colors[LOGL_DETAIL]);
-
- va_list ap;
- va_start(ap, str);
- vutf8printf(stdout, str, &ap);
- va_end(ap);
-
- if (m_colored)
- ResetColor(true);
-
- printf("\n");
+ va_list ap;
+ va_start(ap, str);
- if (logfile)
- {
- outTimestamp(logfile);
- va_list ap2;
- va_start(ap2, str);
- vfprintf(logfile, str, ap2);
- va_end(ap2);
-
- fprintf(logfile, "\n");
- fflush(logfile);
- }
- }
+ vlog(filter, LOG_LEVEL_TRACE, str, ap);
- fflush(stdout);
+ va_end(ap);
}
-void Log::outDebugInLine(const char * str, ...)
+void Log::outDebug(LogFilterType filter, const char * str, ...)
{
- if (!str)
+ if (!str || !ShouldLog(filter, LOG_LEVEL_DEBUG))
return;
- if (m_logLevel > LOGL_DETAIL)
- {
- va_list ap;
- va_start(ap, str);
- vutf8printf(stdout, str, &ap);
- va_end(ap);
+ va_list ap;
+ va_start(ap, str);
- //if (m_colored)
- // ResetColor(true);
+ vlog(filter, LOG_LEVEL_DEBUG, str, ap);
- if (logfile)
- {
- va_list ap2;
- va_start(ap2, str);
- vfprintf(logfile, str, ap2);
- va_end(ap2);
- }
- }
+ va_end(ap);
}
-void Log::outSQLDev(const char* str, ...)
+void Log::outInfo(LogFilterType filter, const char * str, ...)
{
- if (!str)
+ if (!str || !ShouldLog(filter, LOG_LEVEL_INFO))
return;
va_list ap;
va_start(ap, str);
- vutf8printf(stdout, str, &ap);
- va_end(ap);
-
- printf("\n");
- if (sqlDevLogFile)
- {
- va_list ap2;
- va_start(ap2, str);
- vfprintf(sqlDevLogFile, str, ap2);
- va_end(ap2);
-
- fprintf(sqlDevLogFile, "\n");
- fflush(sqlDevLogFile);
- }
+ vlog(filter, LOG_LEVEL_INFO, str, ap);
- fflush(stdout);
+ va_end(ap);
}
-void Log::outDebug(DebugLogFilters f, const char * str, ...)
+void Log::outWarn(LogFilterType filter, const char * str, ...)
{
- if (!(m_DebugLogMask & f))
- return;
-
- if (!str)
+ if (!str || !ShouldLog(filter, LOG_LEVEL_WARN))
return;
- if (m_enableLogDB && m_dbLogLevel > LOGL_DETAIL)
- {
- va_list ap2;
- va_start(ap2, str);
- char nnew_str[MAX_QUERY_LEN];
- vsnprintf(nnew_str, MAX_QUERY_LEN, str, ap2);
- outDB(LOG_TYPE_DEBUG, nnew_str);
- va_end(ap2);
- }
-
- if ( m_logLevel > LOGL_DETAIL )
- {
- if (m_colored)
- SetColor(true, m_colors[LOGL_DEBUG]);
-
- va_list ap;
- va_start(ap, str);
- vutf8printf(stdout, str, &ap);
- va_end(ap);
-
- if (m_colored)
- ResetColor(true);
+ va_list ap;
+ va_start(ap, str);
- printf( "\n" );
+ vlog(filter, LOG_LEVEL_WARN, str, ap);
- if (logfile)
- {
- outTimestamp(logfile);
- va_list ap2;
- va_start(ap2, str);
- vfprintf(logfile, str, ap2);
- va_end(ap2);
-
- fprintf(logfile, "\n" );
- fflush(logfile);
- }
- }
- fflush(stdout);
+ va_end(ap);
}
-void Log::outStaticDebug(const char * str, ...)
+void Log::outError(LogFilterType filter, const char * str, ...)
{
- if (!str)
+ if (!str || !ShouldLog(filter, LOG_LEVEL_ERROR))
return;
- if (m_enableLogDB && m_dbLogLevel > LOGL_DETAIL)
- {
- va_list ap2;
- va_start(ap2, str);
- char nnew_str[MAX_QUERY_LEN];
- vsnprintf(nnew_str, MAX_QUERY_LEN, str, ap2);
- outDB(LOG_TYPE_DEBUG, nnew_str);
- va_end(ap2);
- }
-
- if ( m_logLevel > LOGL_DETAIL )
- {
- if (m_colored)
- SetColor(true, m_colors[LOGL_DEBUG]);
-
- va_list ap;
- va_start(ap, str);
- vutf8printf(stdout, str, &ap);
- va_end(ap);
-
- if (m_colored)
- ResetColor(true);
+ va_list ap;
+ va_start(ap, str);
- printf( "\n" );
+ vlog(filter, LOG_LEVEL_ERROR, str, ap);
- if (logfile)
- {
- outTimestamp(logfile);
- va_list ap2;
- va_start(ap2, str);
- vfprintf(logfile, str, ap2);
- va_end(ap2);
-
- fprintf(logfile, "\n" );
- fflush(logfile);
- }
- }
- fflush(stdout);
+ va_end(ap);
}
-void Log::outStringInLine(const char * str, ...)
+void Log::outFatal(LogFilterType filter, const char * str, ...)
{
- if (!str)
+ if (!str || !ShouldLog(filter, LOG_LEVEL_FATAL))
return;
va_list ap;
-
va_start(ap, str);
- vutf8printf(stdout, str, &ap);
- va_end(ap);
-
- if (logfile)
- {
- va_start(ap, str);
- vfprintf(logfile, str, ap);
- va_end(ap);
- }
-}
-
-void Log::outCommand(uint32 account, const char * str, ...)
-{
- if (!str)
- return;
-
- // TODO: support accountid
- if (m_enableLogDB && m_dbGM)
- {
- va_list ap2;
- va_start(ap2, str);
- char nnew_str[MAX_QUERY_LEN];
- vsnprintf(nnew_str, MAX_QUERY_LEN, str, ap2);
- outDB(LOG_TYPE_GM, nnew_str);
- va_end(ap2);
- }
-
- if (m_logLevel > LOGL_NORMAL)
- {
- if (m_colored)
- SetColor(true, m_colors[LOGL_BASIC]);
-
- va_list ap;
- va_start(ap, str);
- vutf8printf(stdout, str, &ap);
- va_end(ap);
-
- if (m_colored)
- ResetColor(true);
-
- printf("\n");
-
- if (logfile)
- {
- outTimestamp(logfile);
- va_list ap2;
- va_start(ap2, str);
- vfprintf(logfile, str, ap2);
- fprintf(logfile, "\n" );
- va_end(ap2);
- fflush(logfile);
- }
- }
- if (m_gmlog_per_account)
- {
- if (FILE* per_file = openGmlogPerAccount (account))
- {
- outTimestamp(per_file);
- va_list ap;
- va_start(ap, str);
- vfprintf(per_file, str, ap);
- fprintf(per_file, "\n" );
- va_end(ap);
- fclose(per_file);
- }
- }
- else if (gmLogfile)
- {
- outTimestamp(gmLogfile);
- va_list ap;
- va_start(ap, str);
- vfprintf(gmLogfile, str, ap);
- fprintf(gmLogfile, "\n" );
- va_end(ap);
- fflush(gmLogfile);
- }
+ vlog(filter, LOG_LEVEL_FATAL, str, ap);
- fflush(stdout);
+ va_end(ap);
}
-void Log::outChar(const char * str, ...)
+void Log::outCommand(uint32 account, const char * str, ...)
{
- if (!str)
+ if (!str || !ShouldLog(LOG_FILTER_GMCOMMAND, LOG_LEVEL_INFO))
return;
- if (m_enableLogDB && m_dbChar)
- {
- va_list ap2;
- va_start(ap2, str);
- char nnew_str[MAX_QUERY_LEN];
- vsnprintf(nnew_str, MAX_QUERY_LEN, str, ap2);
- outDB(LOG_TYPE_CHAR, nnew_str);
- va_end(ap2);
- }
+ va_list ap;
+ va_start(ap, str);
+ char text[MAX_QUERY_LEN];
+ vsnprintf(text, MAX_QUERY_LEN, str, ap);
+ va_end(ap);
- if (charLogfile)
- {
- outTimestamp(charLogfile);
- va_list ap;
- va_start(ap, str);
- vfprintf(charLogfile, str, ap);
- fprintf(charLogfile, "\n" );
- va_end(ap);
- fflush(charLogfile);
- }
-}
+ LogMessage* msg = new LogMessage(LOG_LEVEL_INFO, LOG_FILTER_GMCOMMAND, text);
+ msg->param1 = account;
-void Log::outCharDump(const char * str, uint32 account_id, uint32 guid, const char * name)
-{
- FILE* file = NULL;
- if (m_charLog_Dump_Separate)
- {
- char fileName[29]; // Max length: name(12) + guid(11) + _.log (5) + \0
- snprintf(fileName, 29, "%d_%s.log", guid, name);
- std::string sFileName(m_dumpsDir);
- sFileName.append(fileName);
- file = fopen((m_logsDir + sFileName).c_str(), "w");
- }
- else
- file = charLogfile;
- if (file)
- {
- fprintf(file, "== START DUMP == (account: %u guid: %u name: %s )\n%s\n== END DUMP ==\n",
- account_id, guid, name, str);
- fflush(file);
- if (m_charLog_Dump_Separate)
- fclose(file);
- }
+ write(msg);
}
-void Log::outOpCode(uint32 op, const char * name, bool smsg)
+void Log::outOpCode(uint32 op, const char* name, bool smsg)
{
- if (!(m_DebugLogMask & LOG_FILTER_OPCODES))
+ if (!ShouldLog(LOG_FILTER_OPCODES, LOG_LEVEL_DEBUG))
return;
- outString("%s: %s 0x%.4X (%u)", smsg ? "S->C" : "C->S", name, op, op);
+
+ outInfo(LOG_FILTER_OPCODES, "%s: %s 0x%.4X (%u)", smsg ? "S->C" : "C->S", name, op, op);
}
-void Log::outRemote(const char * str, ...)
+void Log::SetRealmID(uint32 id)
{
- if (!str)
- return;
-
- if (m_enableLogDB && m_dbRA)
- {
- va_list ap2;
- va_start(ap2, str);
- char nnew_str[MAX_QUERY_LEN];
- vsnprintf(nnew_str, MAX_QUERY_LEN, str, ap2);
- outDB(LOG_TYPE_RA, nnew_str);
- va_end(ap2);
- }
-
- if (raLogfile)
- {
- outTimestamp(raLogfile);
- va_list ap;
- va_start(ap, str);
- vfprintf(raLogfile, str, ap);
- fprintf(raLogfile, "\n" );
- va_end(ap);
- fflush(raLogfile);
- }
+ realm = id;
}
-void Log::outChat(const char * str, ...)
+void Log::Close()
{
- if (!str)
- return;
-
- if (m_enableLogDB && m_dbChat)
+ for (AppenderMap::iterator it = appenders.begin(); it != appenders.end(); ++it)
{
- va_list ap2;
- va_start(ap2, str);
- char nnew_str[MAX_QUERY_LEN];
- vsnprintf(nnew_str, MAX_QUERY_LEN, str, ap2);
- outDB(LOG_TYPE_CHAT, nnew_str);
- va_end(ap2);
- }
-
- if (chatLogfile)
- {
- outTimestamp(chatLogfile);
- va_list ap;
- va_start(ap, str);
- vfprintf(chatLogfile, str, ap);
- fprintf(chatLogfile, "\n" );
- fflush(chatLogfile);
- va_end(ap);
+ delete it->second;
+ it->second = NULL;
}
+ appenders.clear();
+ loggers.clear();
+ delete worker;
+ worker = NULL;
}
-void Log::outErrorST(const char * str, ...)
+void Log::LoadFromConfig()
{
- va_list ap;
- va_start(ap, str);
- char nnew_str[MAX_QUERY_LEN];
- vsnprintf(nnew_str, MAX_QUERY_LEN, str, ap);
- va_end(ap);
-
- ACE_Stack_Trace st;
- outError("%s [Stacktrace: %s]", nnew_str, st.c_str());
-}
-
-void Log::outWarden(const char * str, ...)
-{
- if (!str)
- return;
-
- if (wardenLogFile)
- {
- outTimestamp(wardenLogFile);
- va_list ap;
- va_start(ap, str);
- vfprintf(wardenLogFile, str, ap);
- fprintf(wardenLogFile, "\n" );
- fflush(wardenLogFile);
- va_end(ap);
- }
+ Close();
+ AppenderId = 0;
+ m_logsDir = ConfigMgr::GetStringDefault("LogsDir", "");
+ if (!m_logsDir.empty())
+ if ((m_logsDir.at(m_logsDir.length() - 1) != '/') && (m_logsDir.at(m_logsDir.length() - 1) != '\\'))
+ m_logsDir.push_back('/');
+ ReadAppendersFromConfig();
+ ReadLoggersFromConfig();
+ worker = new LogWorker();
}