Core/Logging: Extend logging system to allow inheritance of loggers

- Changed default loggers and appenders
- '.' determines the relation between loggers ("type.subtype" inherits "type" logger setting if logger "type.subtype" is not defined)
- When core logs a message it search for the correct logger (root is the default one)
  ie: a message logged with "type.subtype"
  * Core will try to find a logger with name "type.subtype", if its not found then will search for "type", again if its not found it will return the default one "root"
This commit is contained in:
Spp
2013-11-07 16:34:44 +01:00
parent d26bb8517c
commit 8aa9745c4c
12 changed files with 243 additions and 394 deletions

View File

@@ -219,6 +219,11 @@ LoginDatabase.WorkerThreads = 1
Appender.Console=1,2,0
Appender.Auth=2,2,0,Auth.log,w
# Logger config values: Given a logger "name"
# Logger.name
# Description: Defines 'What to log'
# Format: LogLevel,AppenderList
#
# LogLevel
# 0 - (Disabled)
# 1 - (Trace)
@@ -231,23 +236,6 @@ Appender.Auth=2,2,0,Auth.log,w
# AppenderList: List of appenders linked to logger
# (Using spaces as separator).
#
# Appenders
# Description: List of Appenders to read from config
# (Using spaces as separator).
# Default: "Console Server"
Appenders=Console Auth
# Logger config values: Given a logger "name"
# Logger.name
# Description: Defines 'What to log'
# Format: Type,LogLevel,AppenderList
# Type
# 0 - Default. Each type that has no config will
# rely on this one. Core will create this logger
# (disabled) if it's not configured
# 7 - Network input/output,
# 30 - Authserver
Logger.Root=0,3,Console Auth

View File

@@ -117,3 +117,35 @@ std::string const& ConfigMgr::GetFilename()
GuardType guard(_configLock);
return _filename;
}
std::list<std::string> ConfigMgr::GetKeysByString(std::string const& name)
{
GuardType guard(_configLock);
std::list<std::string> keys;
if (_config.get() == 0)
return keys;
ACE_TString section_name;
ACE_Configuration_Section_Key section_key;
const ACE_Configuration_Section_Key &root_key = _config->root_section();
int i = 0;
while (_config->enumerate_sections(root_key, i++, section_name) == 0)
{
_config->open_section(root_key, section_name.c_str(), 0, section_key);
ACE_TString key_name;
ACE_Configuration::VALUETYPE type;
int j = 0;
while (_config->enumerate_values(section_key, j++, key_name, type) == 0)
{
std::string temp = key_name.c_str();
if (!temp.find(name))
keys.push_back(temp);
}
}
return keys;
}

View File

@@ -20,7 +20,7 @@
#define CONFIG_H
#include <string>
#include <map>
#include <list>
#include <ace/Singleton.h>
#include <ace/Configuration_Import_Export.h>
#include <ace/Thread_Mutex.h>
@@ -56,6 +56,7 @@ public:
float GetFloatDefault(const char* name, float def);
std::string const& GetFilename();
std::list<std::string> GetKeysByString(std::string const& name);
private:
bool GetValueHelper(const char* name, ACE_TString &result);

View File

@@ -74,7 +74,7 @@ void Appender::write(LogMessage& message)
message.prefix.clear();
if (flags & APPENDER_FLAGS_PREFIX_TIMESTAMP)
message.prefix.append(message.getTimeStr().c_str());
message.prefix.append(message.getTimeStr());
if (flags & APPENDER_FLAGS_PREFIX_LOGLEVEL)
{
@@ -91,9 +91,9 @@ void Appender::write(LogMessage& message)
if (!message.prefix.empty())
message.prefix.push_back(' ');
char text[MAX_QUERY_LEN];
snprintf(text, MAX_QUERY_LEN, "[%s]", Appender::getLogFilterTypeString(message.type));
message.prefix.append(text);
message.prefix.push_back('[');
message.prefix.append(message.type);
message.prefix.push_back(']');
}
if (!message.prefix.empty())
@@ -122,104 +122,3 @@ const char* Appender::getLogLevelString(LogLevel level)
return "DISABLED";
}
}
char const* Appender::getLogFilterTypeString(LogFilterType type)
{
switch (type)
{
case LOG_FILTER_GENERAL:
return "GENERAL";
case LOG_FILTER_UNITS:
return "UNITS";
case LOG_FILTER_PETS:
return "PETS";
case LOG_FILTER_VEHICLES:
return "VEHICLES";
case LOG_FILTER_TSCR:
return "TSCR";
case LOG_FILTER_DATABASE_AI:
return "DATABASE_AI";
case LOG_FILTER_MAPSCRIPTS:
return "MAPSCRIPTS";
case LOG_FILTER_NETWORKIO:
return "NETWORKIO";
case LOG_FILTER_SPELLS_AURAS:
return "SPELLS_AURAS";
case LOG_FILTER_ACHIEVEMENTSYS:
return "ACHIEVEMENTSYS";
case LOG_FILTER_CONDITIONSYS:
return "CONDITIONSYS";
case LOG_FILTER_POOLSYS:
return "POOLSYS";
case LOG_FILTER_AUCTIONHOUSE:
return "AUCTIONHOUSE";
case LOG_FILTER_BATTLEGROUND:
return "BATTLEGROUND";
case LOG_FILTER_OUTDOORPVP:
return "OUTDOORPVP";
case LOG_FILTER_CHATSYS:
return "CHATSYS";
case LOG_FILTER_LFG:
return "LFG";
case LOG_FILTER_MAPS:
return "MAPS";
case LOG_FILTER_PLAYER:
return "PLAYER";
case LOG_FILTER_PLAYER_LOADING:
return "PLAYER LOADING";
case LOG_FILTER_PLAYER_ITEMS:
return "PLAYER ITEMS";
case LOG_FILTER_PLAYER_SKILLS:
return "PLAYER SKILLS";
case LOG_FILTER_PLAYER_CHATLOG:
return "PLAYER CHATLOG";
case LOG_FILTER_LOOT:
return "LOOT";
case LOG_FILTER_GUILD:
return "GUILD";
case LOG_FILTER_TRANSPORTS:
return "TRANSPORTS";
case LOG_FILTER_SQL:
return "SQL";
case LOG_FILTER_GMCOMMAND:
return "GMCOMMAND";
case LOG_FILTER_REMOTECOMMAND:
return "REMOTECOMMAND";
case LOG_FILTER_WARDEN:
return "WARDEN";
case LOG_FILTER_AUTHSERVER:
return "AUTHSERVER";
case LOG_FILTER_WORLDSERVER:
return "WORLDSERVER";
case LOG_FILTER_GAMEEVENTS:
return "GAMEEVENTS";
case LOG_FILTER_CALENDAR:
return "CALENDAR";
case LOG_FILTER_CHARACTER:
return "CHARACTER";
case LOG_FILTER_ARENAS:
return "ARENAS";
case LOG_FILTER_SQL_DRIVER:
return "SQL DRIVER";
case LOG_FILTER_SQL_DEV:
return "SQL DEV";
case LOG_FILTER_PLAYER_DUMP:
return "PLAYER DUMP";
case LOG_FILTER_BATTLEFIELD:
return "BATTLEFIELD";
case LOG_FILTER_SERVER_LOADING:
return "SERVER LOADING";
case LOG_FILTER_OPCODES:
return "OPCODE";
case LOG_FILTER_SOAP:
return "SOAP";
case LOG_FILTER_RBAC:
return "RBAC";
case LOG_FILTER_CHEAT:
return "CHEAT";
default:
break;
}
return "???";
}

View File

@@ -24,57 +24,6 @@
#include <string>
enum LogFilterType
{
LOG_FILTER_GENERAL = 0, // This one should only be used inside Log.cpp
LOG_FILTER_UNITS = 1, // Anything related to units that doesn't fit in other categories. ie. creature formations
LOG_FILTER_PETS = 2,
LOG_FILTER_VEHICLES = 3,
LOG_FILTER_TSCR = 4, // C++ AI, instance scripts, etc.
LOG_FILTER_DATABASE_AI = 5, // SmartAI, EventAI, Creature* * AI
LOG_FILTER_MAPSCRIPTS = 6,
LOG_FILTER_NETWORKIO = 7,
LOG_FILTER_SPELLS_AURAS = 8,
LOG_FILTER_ACHIEVEMENTSYS = 9,
LOG_FILTER_CONDITIONSYS = 10,
LOG_FILTER_POOLSYS = 11,
LOG_FILTER_AUCTIONHOUSE = 12,
LOG_FILTER_BATTLEGROUND = 13,
LOG_FILTER_OUTDOORPVP = 14,
LOG_FILTER_CHATSYS = 15,
LOG_FILTER_LFG = 16,
LOG_FILTER_MAPS = 17,
LOG_FILTER_PLAYER = 18, // Any player log that does not fit in other player filters
LOG_FILTER_PLAYER_LOADING = 19, // Debug output from Player::_Load functions
LOG_FILTER_PLAYER_ITEMS = 20,
LOG_FILTER_PLAYER_SKILLS = 21,
LOG_FILTER_PLAYER_CHATLOG = 22,
LOG_FILTER_LOOT = 23,
LOG_FILTER_GUILD = 24,
LOG_FILTER_TRANSPORTS = 25,
LOG_FILTER_SQL = 26,
LOG_FILTER_GMCOMMAND = 27,
LOG_FILTER_REMOTECOMMAND = 28,
LOG_FILTER_WARDEN = 29,
LOG_FILTER_AUTHSERVER = 30,
LOG_FILTER_WORLDSERVER = 31,
LOG_FILTER_GAMEEVENTS = 32,
LOG_FILTER_CALENDAR = 33,
LOG_FILTER_CHARACTER = 34,
LOG_FILTER_ARENAS = 35,
LOG_FILTER_SQL_DRIVER = 36,
LOG_FILTER_SQL_DEV = 37,
LOG_FILTER_PLAYER_DUMP = 38,
LOG_FILTER_BATTLEFIELD = 39,
LOG_FILTER_SERVER_LOADING = 40,
LOG_FILTER_OPCODES = 41,
LOG_FILTER_SOAP = 42,
LOG_FILTER_RBAC = 43,
LOG_FILTER_CHEAT = 44
};
const uint8 MaxLogFilter = 45;
// Values assigned have their equivalent in enum ACE_Log_Priority
enum LogLevel
{
@@ -109,7 +58,7 @@ enum AppenderFlags
struct LogMessage
{
LogMessage(LogLevel _level, LogFilterType _type, std::string _text)
LogMessage(LogLevel _level, std::string const& _type, std::string const& _text)
: level(_level), type(_type), text(_text), mtime(time(NULL))
{ }
@@ -117,7 +66,7 @@ struct LogMessage
std::string getTimeStr();
LogLevel level;
LogFilterType type;
std::string type;
std::string text;
std::string prefix;
std::string param1;
@@ -145,7 +94,6 @@ class Appender
void setLogLevel(LogLevel);
void write(LogMessage& message);
static const char* getLogLevelString(LogLevel level);
static const char* getLogFilterTypeString(LogFilterType type);
private:
virtual void _write(LogMessage const& /*message*/) = 0;

View File

@@ -25,25 +25,17 @@ AppenderDB::~AppenderDB() { }
void AppenderDB::_write(LogMessage const& message)
{
if (!enabled)
// Avoid infinite loop, PExecute triggers Logging with LOG_FILTER_SQL type
if (!enabled || !message.type.find("sql"))
return;
switch (message.type)
{
case LOG_FILTER_SQL:
case LOG_FILTER_SQL_DRIVER:
case LOG_FILTER_SQL_DEV:
break; // Avoid infinite loop, PExecute triggers Logging with LOG_FILTER_SQL type
default:
PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_INS_LOG);
stmt->setUInt64(0, message.mtime);
stmt->setUInt32(1, realmId);
stmt->setUInt8(2, uint8(message.type));
stmt->setUInt8(3, uint8(message.level));
stmt->setString(4, message.text);
LoginDatabase.Execute(stmt);
break;
}
PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_INS_LOG);
stmt->setUInt64(0, message.mtime);
stmt->setUInt32(1, realmId);
stmt->setString(2, message.type);
stmt->setUInt8(3, uint8(message.level));
stmt->setString(4, message.text);
LoginDatabase.Execute(stmt);
}
void AppenderDB::setRealmId(uint32 _realmId)

View File

@@ -57,13 +57,6 @@ std::string GetConfigStringDefault(std::string base, const char* name, const cha
return sConfigMgr->GetStringDefault(base.c_str(), value);
}
// Returns default logger if the requested logger is not found
Logger* Log::GetLoggerByType(LogFilterType filterType)
{
LoggerMap::iterator it = loggers.find(static_cast<uint8>(filterType));
return it == loggers.end() ? &loggers[0] : &it->second;
}
Appender* Log::GetAppenderByName(std::string const& name)
{
AppenderMap::iterator it = appenders.begin();
@@ -73,24 +66,23 @@ Appender* Log::GetAppenderByName(std::string const& name)
return it == appenders.end() ? NULL : it->second;
}
void Log::CreateAppenderFromConfig(const char* name)
void Log::CreateAppenderFromConfig(std::string const& appenderName)
{
if (!name || *name == '\0')
if (appenderName.empty())
return;
// 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 = sConfigMgr->GetStringDefault(options.c_str(), "");
std::string options = sConfigMgr->GetStringDefault(appenderName.c_str(), "");
Tokenizer tokens(options, ',');
Tokenizer::const_iterator iter = tokens.begin();
uint8 size = tokens.size();
std::string name = appenderName.substr(9);
if (size < 2)
{
fprintf(stderr, "Log::CreateAppenderFromConfig: Wrong configuration for appender %s. Config line: %s\n", name, options.c_str());
fprintf(stderr, "Log::CreateAppenderFromConfig: Wrong configuration for appender %s. Config line: %s\n", name.c_str(), options.c_str());
return;
}
@@ -99,7 +91,7 @@ void Log::CreateAppenderFromConfig(const char* name)
LogLevel level = LogLevel(atoi(*(++iter)));
if (level > LOG_LEVEL_FATAL)
{
fprintf(stderr, "Log::CreateAppenderFromConfig: Wrong Log Level %d for appender %s\n", level, name);
fprintf(stderr, "Log::CreateAppenderFromConfig: Wrong Log Level %d for appender %s\n", level, name.c_str());
return;
}
@@ -114,7 +106,7 @@ void Log::CreateAppenderFromConfig(const char* name)
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()); // DEBUG - RemoveMe
//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:
@@ -124,7 +116,7 @@ void Log::CreateAppenderFromConfig(const char* name)
if (size < 4)
{
fprintf(stderr, "Log::CreateAppenderFromConfig: Missing file name for appender %s\n", name);
fprintf(stderr, "Log::CreateAppenderFromConfig: Missing file name for appender %s\n", name.c_str());
return;
}
@@ -148,7 +140,7 @@ void Log::CreateAppenderFromConfig(const char* name)
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, id, level, filename.c_str(), mode.c_str()); // DEBUG - RemoveMe
//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:
@@ -158,62 +150,53 @@ void Log::CreateAppenderFromConfig(const char* name)
break;
}
default:
fprintf(stderr, "Log::CreateAppenderFromConfig: Unknown type %d for appender %s\n", type, name);
fprintf(stderr, "Log::CreateAppenderFromConfig: Unknown type %d for appender %s\n", type, name.c_str());
break;
}
}
void Log::CreateLoggerFromConfig(const char* name)
void Log::CreateLoggerFromConfig(std::string const& appenderName)
{
if (!name || *name == '\0')
if (appenderName.empty())
return;
LogLevel level = LOG_LEVEL_DISABLED;
uint8 type = uint8(-1);
std::string options = "Logger.";
options.append(name);
options = sConfigMgr->GetStringDefault(options.c_str(), "");
std::string options = sConfigMgr->GetStringDefault(appenderName.c_str(), "");
std::string name = appenderName.substr(7);
if (options.empty())
{
fprintf(stderr, "Log::CreateLoggerFromConfig: Missing config option Logger.%s\n", name);
fprintf(stderr, "Log::CreateLoggerFromConfig: Missing config option Logger.%s\n", name.c_str());
return;
}
Tokenizer tokens(options, ',');
Tokenizer::const_iterator iter = tokens.begin();
if (tokens.size() != 3)
if (tokens.size() != 2)
{
fprintf(stderr, "Log::CreateLoggerFromConfig: Wrong config option Logger.%s=%s\n", name, options.c_str());
fprintf(stderr, "Log::CreateLoggerFromConfig: Wrong config option Logger.%s=%s\n", name.c_str(), options.c_str());
return;
}
type = uint8(atoi(*iter));
if (type > MaxLogFilter)
{
fprintf(stderr, "Log::CreateLoggerFromConfig: Wrong type %u for logger %s\n", type, name);
return;
}
Logger& logger = loggers[type];
Logger& logger = loggers[name];
if (!logger.getName().empty())
{
fprintf(stderr, "Error while configuring Logger %s. Already defined\n", name);
fprintf(stderr, "Error while configuring Logger %s. Already defined\n", name.c_str());
return;
}
++iter;
level = LogLevel(atoi(*iter));
if (level > LOG_LEVEL_FATAL)
{
fprintf(stderr, "Log::CreateLoggerFromConfig: Wrong Log Level %u for logger %s\n", type, name);
fprintf(stderr, "Log::CreateLoggerFromConfig: Wrong Log Level %u for logger %s\n", type, name.c_str());
return;
}
logger.Create(name, LogFilterType(type), level);
//fprintf(stdout, "Log::CreateLoggerFromConfig: Created Logger %s, Type %u, mask %u\n", name, LogFilterType(type), level); // DEBUG - RemoveMe
logger.Create(name, level);
//fprintf(stdout, "Log::CreateLoggerFromConfig: Created Logger %s, Level %u\n", name.c_str(), level);
++iter;
std::istringstream ss(*iter);
@@ -225,63 +208,54 @@ void Log::CreateLoggerFromConfig(const char* name)
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
//fprintf(stdout, "Log::CreateLoggerFromConfig: Added Appender %s to Logger %s\n", appender->getName().c_str(), name.c_str());
}
else
fprintf(stderr, "Error while configuring Appender %s in Logger %s. Appender does not exist", str.c_str(), name);
fprintf(stderr, "Error while configuring Appender %s in Logger %s. Appender does not exist", str.c_str(), name.c_str());
ss >> str;
}
}
void Log::ReadAppendersFromConfig()
{
std::istringstream ss(sConfigMgr->GetStringDefault("Appenders", ""));
std::string name;
std::list<std::string> keys = sConfigMgr->GetKeysByString("Appender.");
do
while (!keys.empty())
{
ss >> name;
CreateAppenderFromConfig(name.c_str());
name = "";
CreateAppenderFromConfig(keys.front());
keys.pop_front();
}
while (ss);
}
void Log::ReadLoggersFromConfig()
{
std::istringstream ss(sConfigMgr->GetStringDefault("Loggers", ""));
std::string name;
std::list<std::string> keys = sConfigMgr->GetKeysByString("Logger.");
do
while (!keys.empty())
{
ss >> name;
CreateLoggerFromConfig(name.c_str());
name = "";
CreateLoggerFromConfig(keys.front());
keys.pop_front();
}
while (ss);
// root logger must exist. Marking as disabled as its not configured
if (loggers.find(LOG_FILTER_GENERAL) == loggers.end())
loggers[LOG_FILTER_GENERAL].Create("root", LOG_FILTER_GENERAL, LOG_LEVEL_DISABLED);
if (loggers.find(LOGGER_ROOT) == loggers.end())
{
fprintf(stdout, "Wrong Loggers configuration, Logger.root needs to exist, nothing will be logged.\n");
loggers[LOGGER_ROOT].Create(LOGGER_ROOT, LOG_LEVEL_DISABLED);
}
}
void Log::vlog(LogFilterType filter, LogLevel level, char const* str, va_list argptr)
void Log::vlog(std::string const& filter, LogLevel level, char const* str, va_list argptr)
{
char text[MAX_QUERY_LEN];
vsnprintf(text, MAX_QUERY_LEN, str, argptr);
write(new LogMessage(level, filter, text));
}
void Log::write(LogMessage* msg)
void Log::write(LogMessage* msg) const
{
if (loggers.empty())
{
delete msg;
return;
}
Logger const* logger = GetLoggerByType(msg->type);
msg->text.append("\n");
Logger* logger = GetLoggerByType(msg->type);
if (worker)
worker->enqueue(new LogOperation(logger, msg));
@@ -336,7 +310,7 @@ bool Log::SetLogLevel(std::string const& name, const char* newLevelc, bool isLog
return true;
}
void Log::outTrace(LogFilterType filter, const char * str, ...)
void Log::outTrace(std::string const& filter, const char * str, ...)
{
va_list ap;
va_start(ap, str);
@@ -346,7 +320,7 @@ void Log::outTrace(LogFilterType filter, const char * str, ...)
va_end(ap);
}
void Log::outDebug(LogFilterType filter, const char * str, ...)
void Log::outDebug(std::string const& filter, const char * str, ...)
{
va_list ap;
va_start(ap, str);
@@ -356,7 +330,7 @@ void Log::outDebug(LogFilterType filter, const char * str, ...)
va_end(ap);
}
void Log::outInfo(LogFilterType filter, const char * str, ...)
void Log::outInfo(std::string const& filter, const char * str, ...)
{
va_list ap;
va_start(ap, str);
@@ -366,7 +340,7 @@ void Log::outInfo(LogFilterType filter, const char * str, ...)
va_end(ap);
}
void Log::outWarn(LogFilterType filter, const char * str, ...)
void Log::outWarn(std::string const& filter, const char * str, ...)
{
va_list ap;
va_start(ap, str);
@@ -376,7 +350,7 @@ void Log::outWarn(LogFilterType filter, const char * str, ...)
va_end(ap);
}
void Log::outError(LogFilterType filter, const char * str, ...)
void Log::outError(std::string const& filter, const char * str, ...)
{
va_list ap;
va_start(ap, str);
@@ -386,7 +360,7 @@ void Log::outError(LogFilterType filter, const char * str, ...)
va_end(ap);
}
void Log::outFatal(LogFilterType filter, const char * str, ...)
void Log::outFatal(std::string const& filter, const char * str, ...)
{
va_list ap;
va_start(ap, str);

View File

@@ -28,11 +28,60 @@
#include <string>
#include <ace/Singleton.h>
// TODO: Replace all defines in core
#define LOG_FILTER_ACHIEVEMENTSYS "achievement"
#define LOG_FILTER_AUCTIONHOUSE "auctionHouse"
#define LOG_FILTER_ARENAS "bg.arena"
#define LOG_FILTER_BATTLEFIELD "bg.battlefield"
#define LOG_FILTER_BATTLEGROUND "bg.battleground"
#define LOG_FILTER_PLAYER_CHATLOG "chat.log"
#define LOG_FILTER_CALENDAR "calendar"
#define LOG_FILTER_CHATSYS "chat.system"
#define LOG_FILTER_CHEAT "cheat"
#define LOG_FILTER_REMOTECOMMAND "commands.ra"
#define LOG_FILTER_GMCOMMAND "commands.gm"
#define LOG_FILTER_CONDITIONSYS "condition"
#define LOG_FILTER_PETS "entities.pet"
#define LOG_FILTER_CHARACTER "entities.player.character"
#define LOG_FILTER_PLAYER_DUMP "entities.player.dump"
#define LOG_FILTER_PLAYER "entities.player"
#define LOG_FILTER_PLAYER_ITEMS "entities.player.items"
#define LOG_FILTER_PLAYER_LOADING "entities.player.loading"
#define LOG_FILTER_PLAYER_SKILLS "entities.player.skills"
#define LOG_FILTER_TRANSPORTS "entities.transport"
#define LOG_FILTER_UNITS "entities.unit"
#define LOG_FILTER_VEHICLES "entities.vehicle"
#define LOG_FILTER_GAMEEVENTS "gameevent"
#define LOG_FILTER_GUILD "guild"
#define LOG_FILTER_LFG "lfg"
#define LOG_FILTER_LOOT "loot"
#define LOG_FILTER_MAPSCRIPTS "maps.script"
#define LOG_FILTER_MAPS "maps"
#define LOG_FILTER_GENERAL "misc"
#define LOG_FILTER_NETWORKIO "network"
#define LOG_FILTER_OPCODES "network.opcode"
#define LOG_FILTER_SOAP "network.soap"
#define LOG_FILTER_OUTDOORPVP "outdoorpvp"
#define LOG_FILTER_POOLSYS "pool"
#define LOG_FILTER_RBAC "rbac"
#define LOG_FILTER_TSCR "scripts"
#define LOG_FILTER_DATABASE_AI "scripts.ai"
#define LOG_FILTER_SERVER_LOADING "server.loading"
#define LOG_FILTER_AUTHSERVER "server.authserver"
#define LOG_FILTER_WORLDSERVER "server.worldserver"
#define LOG_FILTER_SPELLS_AURAS "spells"
#define LOG_FILTER_SQL_DEV "sql.dev"
#define LOG_FILTER_SQL_DRIVER "sql.driver"
#define LOG_FILTER_SQL "sql.sql"
#define LOG_FILTER_WARDEN "warden"
#define LOGGER_ROOT "root"
class Log
{
friend class ACE_Singleton<Log, ACE_Thread_Mutex>;
typedef UNORDERED_MAP<uint8, Logger> LoggerMap;
typedef UNORDERED_MAP<std::string, Logger> LoggerMap;
private:
Log();
@@ -41,15 +90,15 @@ class Log
public:
void LoadFromConfig();
void Close();
bool ShouldLog(LogFilterType type, LogLevel level) const;
bool ShouldLog(std::string const& type, LogLevel level) const;
bool SetLogLevel(std::string const& name, char const* level, bool isLogger = true);
void outTrace(LogFilterType f, char const* str, ...) ATTR_PRINTF(3, 4);
void outDebug(LogFilterType f, char const* str, ...) ATTR_PRINTF(3, 4);
void outInfo(LogFilterType f, char const* str, ...) ATTR_PRINTF(3, 4);
void outWarn(LogFilterType f, char const* str, ...) ATTR_PRINTF(3, 4);
void outError(LogFilterType f, char const* str, ...) ATTR_PRINTF(3, 4);
void outFatal(LogFilterType f, char const* str, ...) ATTR_PRINTF(3, 4);
void outTrace(std::string const& f, char const* str, ...) ATTR_PRINTF(3, 4);
void outDebug(std::string const& f, char const* str, ...) ATTR_PRINTF(3, 4);
void outInfo(std::string const& f, char const* str, ...) ATTR_PRINTF(3, 4);
void outWarn(std::string const& f, char const* str, ...) ATTR_PRINTF(3, 4);
void outError(std::string const& f, char const* str, ...) ATTR_PRINTF(3, 4);
void outFatal(std::string const& f, char const* str, ...) ATTR_PRINTF(3, 4);
void outCommand(uint32 account, const char * str, ...) ATTR_PRINTF(3, 4);
void outCharDump(char const* str, uint32 account_id, uint32 guid, char const* name);
@@ -58,14 +107,14 @@ class Log
void SetRealmId(uint32 id);
private:
void vlog(LogFilterType f, LogLevel level, char const* str, va_list argptr);
void write(LogMessage* msg);
void vlog(std::string const& f, LogLevel level, char const* str, va_list argptr);
void write(LogMessage* msg) const;
Logger* GetLoggerByType(LogFilterType filter);
Logger const* GetLoggerByType(std::string const& type) const;
Appender* GetAppenderByName(std::string const& name);
uint8 NextAppenderId();
void CreateAppenderFromConfig(const char* name);
void CreateLoggerFromConfig(const char* name);
void CreateAppenderFromConfig(std::string const& name);
void CreateLoggerFromConfig(std::string const& name);
void ReadAppendersFromConfig();
void ReadLoggersFromConfig();
@@ -79,19 +128,35 @@ class Log
LogWorker* worker;
};
inline bool Log::ShouldLog(LogFilterType type, LogLevel level) const
inline Logger const* Log::GetLoggerByType(std::string const& type) const
{
LoggerMap::const_iterator it = loggers.find(uint8(type));
LoggerMap::const_iterator it = loggers.find(type);
if (it != loggers.end())
{
LogLevel logLevel = it->second.getLogLevel();
return logLevel != LOG_LEVEL_DISABLED && logLevel <= level;
}
return &(it->second);
if (type != LOG_FILTER_GENERAL)
return ShouldLog(LOG_FILTER_GENERAL, level);
else
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"
Logger const* logger = GetLoggerByType(type);
if (!logger)
return false;
LogLevel logLevel = logger->getLogLevel();
return logLevel != LOG_LEVEL_DISABLED && logLevel <= level;
}
#define sLog ACE_Singleton<Log, ACE_Thread_Mutex>::instance()

View File

@@ -24,7 +24,7 @@ struct LogMessage;
class LogOperation
{
public:
LogOperation(Logger* _logger, LogMessage* _msg)
LogOperation(Logger const* _logger, LogMessage* _msg)
: logger(_logger), msg(_msg)
{ }
@@ -33,8 +33,8 @@ class LogOperation
int call();
protected:
Logger *logger;
LogMessage *msg;
Logger const* logger;
LogMessage* msg;
};
#endif

View File

@@ -17,12 +17,11 @@
#include "Logger.h"
Logger::Logger(): name(""), type(LOG_FILTER_GENERAL), level(LOG_LEVEL_DISABLED) { }
Logger::Logger(): name(""), level(LOG_LEVEL_DISABLED) { }
void Logger::Create(std::string const& _name, LogFilterType _type, LogLevel _level)
void Logger::Create(std::string const& _name, LogLevel _level)
{
name = _name;
type = _type;
level = _level;
}
@@ -38,11 +37,6 @@ std::string const& Logger::getName() const
return name;
}
LogFilterType Logger::getType() const
{
return type;
}
LogLevel Logger::getLogLevel() const
{
return level;
@@ -68,7 +62,7 @@ void Logger::setLogLevel(LogLevel _level)
level = _level;
}
void Logger::write(LogMessage& message)
void Logger::write(LogMessage& message) const
{
if (!level || level > message.level || message.text.empty())
{
@@ -76,7 +70,7 @@ void Logger::write(LogMessage& message)
return;
}
for (AppenderMap::iterator it = appenders.begin(); it != appenders.end(); ++it)
for (AppenderMap::const_iterator it = appenders.begin(); it != appenders.end(); ++it)
if (it->second)
it->second->write(message);
}

View File

@@ -26,19 +26,17 @@ class Logger
Logger();
~Logger();
void Create(std::string const& name, LogFilterType type, LogLevel level);
void Create(std::string const& name, LogLevel level);
void addAppender(uint8 type, Appender *);
void delAppender(uint8 type);
std::string const& getName() const;
LogFilterType getType() const;
LogLevel getLogLevel() const;
void setLogLevel(LogLevel level);
void write(LogMessage& message);
void write(LogMessage& message) const;
private:
std::string name;
LogFilterType type;
LogLevel level;
AppenderMap appenders;
};

View File

@@ -2703,79 +2703,13 @@ UI.ShowQuestLevelsInDialogs = 0
Appender.Console=1,3,0
Appender.Server=2,2,0,Server.log,w
Appender.GM=2,2,0,GM.log
Appender.GM=2,2,15,gm/gm_%s.log
Appender.DBErrors=2,2,0,DBErrors.log
Appender.Char=2,2,0,Char.log,w
Appender.RA=2,2,0,RA.log
Appender.Warden=2,4,0,Warden.log
Appender.Chat=2,2,0,Chat.log
Appender.CharDump=2,2,0,%s.log
Appender.Arenas=2,2,0,Arena.log
Appender.SQLDev=2,2,0,SQLDev.log
Appender.SQLDriver=2,2,0,SQLDriver.log
# Appenders
# Description: List of Appenders to read from config
# (Using spaces as separator).
# Default: "Console Server GM DBErrors Char RA Warden Chat"
Appenders=Console Server GM DBErrors Char RA Warden Chat
# Logger config values: Given a logger "name"
# Logger.name
# Description: Defines 'What to log'
# Format: Type,LogLevel,AppenderList
# Type
# 0 - Default. Each type that has no config will
# rely on this one. Core will create this logger
# (disabled) if it's not configured
# 1 - Units that doesn't fit in other categories
# 2 - Pets
# 3 - Vehicles
# 4 - C++ AI, instance scripts, etc.
# 5 - DB AI, such as SAI, EAI, CreatureAI
# 6 - DB map scripts
# 7 - Network input/output,
# such as packet handlers and netcode logs
# 8 - Spellsystem and aurasystem
# 9 - Achievement system
# 10 - Condition system
# 11 - Pool system
# 12 - Auction house
# 13 - Arena's and battlegrounds
# 14 - Outdoor PVP
# 15 - Chat system
# 16 - LFG system
# 17 - Maps, instances (not scripts),
# grids, cells, visibility, etc.
# 18 - Player that doesn't fit in other categories.
# 19 - Player loading from DB
# (Player::_LoadXXX functions)
# 20 - Items
# 21 - Player skills (do not confuse with spells)
# 22 - Player chat logs
# 23 - loot
# 24 - guilds
# 25 - transports
# 26 - SQL. DB errors
# 27 - GM Commands
# 28 - Remote Access Commands
# 29 - Warden
# 30 - Authserver
# 31 - Worldserver
# 32 - Game Events
# 33 - Calendar
# 34 - Character (Exclusive to log login, logout, create, rename)
# 35 - Arenas
# 36 - SQL Driver
# 37 - SQL Dev
# 38 - Player Dump
# 39 - Battlefield
# 40 - Server Loading
# 41 - Opcodes (just id and name sent / received)
# 42 - SOAP
# 43 - RBAC (Role Based Access Control)
# 44 - Cheat (used to log cheat attempts)
# Format: LogLevel,AppenderList
#
# LogLevel
# 0 - (Disabled)
@@ -2790,28 +2724,52 @@ Appenders=Console Server GM DBErrors Char RA Warden Chat
# (Using spaces as separator).
#
Logger.Root=0,5,Console Server
Logger.Chat=22,2,Chat
Logger.DBErrors=26,5,Console Server DBErrors
Logger.GM=27,3,Console Server GM
Logger.RA=28,3,RA
Logger.Warden=29,4,Warden
Logger.WorldServer=31,3,Console Server
Logger.Character=34,3,Char
Logger.Arenas=35,3,Arenas
Logger.SQLDriver=36,5,SQLDriver
Logger.SQLDev=37,3,SQLDev
Logger.CharDump=38,3,CharDump
Logger.Load=40,3,Console Server
Logger.Opcodes=41,6,Console Server
Logger.root=5,Console Server
Logger.server=3,Console Server
Logger.commands.gm=3,Console GM
Logger.sql.sql=5,Console DBErrors
#
# Loggers
# Description: List of Loggers to read from config
# (Using spaces as separator).
# Default: "Root Chat DBErrors GM RA Warden Character Load"
Loggers=Root Chat DBErrors GM RA Warden Character Load WorldServer Opcodes
#Logger.achievement=3,Console Server
#Logger.auctionHouse=3,Console Server
#Logger.bg.arena=3,Console Server
#Logger.bg.battlefield=3,Console Server
#Logger.bg.battleground=3,Console Server
#Logger.chat.log=3,Console Server
#Logger.calendar=3,Console Server
#Logger.chat.system=3,Console Server
#Logger.cheat=3,Console Server
#Logger.commands.ra=3,Console Server
#Logger.condition=3,Console Server
#Logger.entities.pet=3,Console Server
#Logger.entities.player.character=3,Console Server
#Logger.entities.player.dump=3,Console Server
#Logger.entities.player=3,Console Server
#Logger.entities.player.items=3,Console Server
#Logger.entities.player.loading=3,Console Server
#Logger.entities.player.skills=3,Console Server
#Logger.entities.transport=3,Console Server
#Logger.entities.unit=3,Console Server
#Logger.entities.vehicle=3,Console Server
#Logger.gameevent=3,Console Server
#Logger.guild=3,Console Server
#Logger.lfg=3,Console Server
#Logger.loot=3,Console Server
#Logger.maps.script=3,Console Server
#Logger.maps=3,Console Server
#Logger.misc=3,Console Server
#Logger.network=3,Console Server
#Logger.network.opcode=3,Console Server
#Logger.network.soap=3,Console Server
#Logger.outdoorpvp=3,Console Server
#Logger.pool=3,Console Server
#Logger.rbac=3,Console Server
#Logger.scripts=3,Console Server
#Logger.scripts.ai=3,Console Server
#Logger.server.authserver=3,Console Server
#Logger.spells=3,Console Server
#Logger.sql.dev=3,Console Server
#Logger.sql.driver=3,Console Server
#Logger.warden=3,Console Server
#
# Log.Async.Enable