diff options
author | Spp <spp@jorge.gr> | 2012-08-15 19:58:02 +0200 |
---|---|---|
committer | Spp <spp@jorge.gr> | 2012-08-15 19:58:02 +0200 |
commit | 52a5991c1258073d561e8b74ef99a7b940808d92 (patch) | |
tree | bfe7b789ed8f98297666257c116a17af697aa2d4 | |
parent | b77d88ec51e734a65f3d2ce3c69991980ac23ffd (diff) |
Core/Logging: Added documentation about this system
- Restored old CharDump (LOG_FILTER_PLAYER_DUMP) but disabled by default.
- "%s" is now used to set dynamic file names, only used by GM commands and Player dump
-rw-r--r-- | doc/LoggingHOWTO.txt | 276 | ||||
-rw-r--r-- | src/server/authserver/authserver.conf.dist | 2 | ||||
-rw-r--r-- | src/server/game/Handlers/CharacterHandler.cpp | 8 | ||||
-rw-r--r-- | src/server/shared/Logging/Appender.h | 9 | ||||
-rw-r--r-- | src/server/shared/Logging/AppenderFile.cpp | 4 | ||||
-rwxr-xr-x | src/server/shared/Logging/Log.cpp | 22 | ||||
-rwxr-xr-x | src/server/shared/Logging/Log.h | 1 | ||||
-rw-r--r-- | src/server/worldserver/worldserver.conf.dist | 21 |
8 files changed, 325 insertions, 18 deletions
diff --git a/doc/LoggingHOWTO.txt b/doc/LoggingHOWTO.txt new file mode 100644 index 00000000000..12850eb06cf --- /dev/null +++ b/doc/LoggingHOWTO.txt @@ -0,0 +1,276 @@ +Logging system "log4j-like" + +--- LOGGERS AND APPENDERS --- + +Logging system has two components: loggers and appenders. These types of +components enable users to log messages according to message type and level and +control at runtime where they are reported. + +LOGGERS + +The first and foremost advantage of this system resided in the ability to +disable certain log statements while allowing others to print unhindered. +This capability assumes that the loggers are categorized according to some +developer-chosen criteria. + +Loggers follow hierarchy, if a logger is not defined a root logger will be used + +Loggers may be assigned levels. The set of possible levels are TRACE, DEBUG, +INFO, WARN, ERROR AND FATAL, or be disabled using level DISABLED. + +By definition the printing method determines the level of a logging request. +For example, sLog->outInfo(...) is a logging request of level INFO. + +A logging request is said to be enabled if its level is higher than or equal to +the level of its logger. Otherwise, the request is said to be disabled. A logger +without an assigned level will inherit one from the hierarchy + +Example +Logger Name Assigned Level Inherited Level +root Proot Proot +Network None Proot + +As Network is not defined, it uses the root logger and it's log level. +TRACE < DEBUG < INFO < WARN < ERROR < FATAL. + + +APPENDERS + +The ability to selectively enable of dissable logging request based on their +loggers is only part of the picture. This system allows logging requests to +print to multiple destinations. An output destination is called an appender. +Current system defines appenders for Console, files and Database, but can be +easily extended to remote socket server, NT event loggers, syslog daemons or +any other system. + +More than one appender can be attached to one logger. Each enabled logging +request for a given logger will be forwarded to all the appenders in that +logger + + +CONFIGURATION + +System will read "Loggers" and "Appenders" to know the list of loggers and +appenders to read from config file. Both are a list of elements separated +by space. + +Once we have the list of appenders to read, system will try to configure a new +appender from its config line. Appender config line follows the format: + + Type,LogLevel,Flags,optional1,optional2 + +Its a list of elements separated by comma where each element has its own meaning + Type: Type of the appender + 1 - (Console) + 2 - (File) + 3 - (DB) + LogLevel: Log level + 0 - (Disabled) + 1 - (Trace) + 2 - (Debug) + 3 - (Info) + 4 - (Warn) + 5 - (Error) + 6 - (Fatal) + Flags: Define some extra modifications to do to logging message + 1 - Prefix Timestamp to the text + 2 - Prefix Log Level to the text + 4 - Prefix Log Filter type to the text + 8 - Append timestamp to the log file name. Format: YYYY-MM-DD_HH-MM-SS + (Only used with Type = 2) + 16 - Make a backup of existing file before overwrite + (Only used with Mode = w) + +Depending on the type, elements optional1 and optional2 will take different + + Colors (read as optional1 if Type = Console) + Format: "fatal error warn info debug trace" + 0 - BLACK + 1 - RED + 2 - GREEN + 3 - BROWN + 4 - BLUE + 5 - MAGENTA + 6 - CYAN + 7 - GREY + 8 - YELLOW + 9 - LRED + 10 - LGREEN + 11 - LBLUE + 12 - LMAGENTA + 13 - LCYAN + 14 - WHITE + Example: "13 11 9 5 3 1" + + File: Name of the file (read as optional1 if Type = File) + Allows to use one "%u" to create dynamic files + + Mode: Mode to open the file (read as optional2 if Type = File) + a - (Append) + w - (Overwrite) + +Example: + Appender.Console1=1,2,6 + + Creates new appender to log to console any message with log level DEBUG + or higher and prefixes log type and level to the message. + + Appender.Console2=1,5,1,13 11 9 5 3 1 + + Creates new appender to log to console any message with log level ERROR + or higher and prefixes timestamp to the message using colored text. + + Appender.File=2,2,7,Auth.log,w + + Creates new appender to log to file "Auth.log" any message with log level + DEBUG or higher and prefixes timestamp, type and level to message + +In the example, having two different loggers to log to console is perfectly +legal but redundant. + +Once we have the list of loggers to read, system will try to configure a new +logger from its config line. Logger config line follows the format: + + Type,LogLevel,AppenderList + +Its a list of elements separated by comma where each element has its own meaning + Type: Type of the logger ( + 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 login, logout, create, rename and delete) + 35 - Arenas + 36 - SQL Driver + 37 - SQL Dev + LogLevel + 0 - (Disabled) + 1 - (Trace) + 2 - (Debug) + 3 - (Info) + 4 - (Warn) + 5 - (Error) + 6 - (Fatal) + AppenderList: List of appenders linked to logger + (Using spaces as separator). + +--- EXAMPLES --- + +EXAMPLE 1 + +Log errors to console and a file called server.log that only contain +logs for this server run. File should prefix timestamp, type and log level to +the messages. Console should prefix type and log level. + + Appenders=Console Server + Loggers=Root + Appender.Console=1,5,6 + Appender.Server=2,5,7,Server.log,w + Logger.Root=0,5,Console Server + +Lets trace how system will log two different messages: + 1) sLog->outError(LOG_FILTER_GUILD, "Guild 1 created"); + System will try to find logger of type GUILD, as no logger is configured + for GUILD it will use Root logger. As message Log Level is equal or higher + than the Log level of logger the message is sent to the Appenders + configured in the Logger. "Console" and "Server". + Console will write: "ERROR [GUILD ] Guild 1 created" + Server will write to file "2012-08-15 ERROR [GUILD ] Guild 1 created" + + 2) sLog->outInfo(LOG_FILTER_CHARACTER, "Player Name Logged in"); + System will try to find logger of type CHARACTER, as no logger is + configured for CHARACTER it will use Root logger. As message Log Level is + not equal or higher than the Log level of logger the message its discarted. + +EXAMPLE 2 + +Same example that above, but now i want to see all messages of level INFO on +file and server file should add timestamp on creation. + + Appenders=Console Server + Loggers=Root + Appender.Console=1,5,6 + Appender.Server=2,4,15,Server.log + Logger.Root=0,4,Console Server + +Lets trace how system will log two different messages: + 1) sLog->outError(LOG_FILTER_GUILD, "Guild 1 created"); + Performs exactly as example 1. + 2) sLog->outInfo(LOG_FILTER_CHARACTER, "Player Name Logged in"); + System will try to find logger of type CHARACTER, as no logger is + configured for CHARACTER it will use Root logger. As message Log Level is + equal or higher than the Log level of logger the message is sent to the + Appenders configured in the Logger. "Console" and "Server". + Console will discard msg as Log Level is not higher or equal to this + appender + Server will write to file + "2012-08-15 INFO [CHARACTER ] Guild 1 Player Name Logged in" + +EXAMPLE 3 +As a dev, i may be interested in logging just a particular part of the core +while i'm trying to fix something. So... i want to debug GUILDS to maximum +and also some CHARACTER events to some point. Also im checking some Waypoints +so i want SQLDEV to be logged to file without prefixes. All other messages +should only be logged to console, GUILD to TRACE and CHARACTER to INFO + + Appenders=Console SQLDev + Loggers=Guild Characters SQLDev + Appender.Console=1,1 + Appender.SQLDev=2,2,0,SQLDev.log + Logger.Guild=24,1,Console + Logger.Characters=34,3,Console + Logger.SQLDev=37,3,SQLDev + +With this config, any message logger with a Log type different to GUILD, +CHARACTER or SQLDEV will be ignored, as we didn't define a logger Root and +system created a default Root disabled. Appender Console, log level should be +defined to allow all possible messages of its loggers, in this case GUILD uses +TRACE (1), so Appender should allow it. Logger Characters will limit it's own +messages to INFO (3) + +--- SOME EXTRA COMMENTS --- +why this system is better than previous one? +- Can be extended: Anyone can easily create new appenders to log to new + systems as syslog or IRC, having all code related to that system in particular + files +- It's asyncronous: Uses threads to write messages, so core performance wont be + affected by IO operations +- Lets us select "What to log" and "Where to log" on the fly. You can log to a + dozen of files without having to change a single line of code + +
\ No newline at end of file diff --git a/src/server/authserver/authserver.conf.dist b/src/server/authserver/authserver.conf.dist index d1c92dcf1d0..15dd02d9052 100644 --- a/src/server/authserver/authserver.conf.dist +++ b/src/server/authserver/authserver.conf.dist @@ -170,7 +170,7 @@ LoginDatabase.WorkerThreads = 1 # 5 - (Error) # 6 - (Fatal) # -# Flags: Default Console = 6, File = 7, DB = 0 +# Flags: # 0 - None # 1 - Prefix Timestamp to the text # 2 - Prefix Log Level to the text diff --git a/src/server/game/Handlers/CharacterHandler.cpp b/src/server/game/Handlers/CharacterHandler.cpp index 7451bd2dc2a..8544266840f 100644 --- a/src/server/game/Handlers/CharacterHandler.cpp +++ b/src/server/game/Handlers/CharacterHandler.cpp @@ -719,11 +719,15 @@ void WorldSession::HandleCharDeleteOpcode(WorldPacket & recv_data) sScriptMgr->OnPlayerDelete(guid); sWorld->DeleteCharaceterNameData(GUID_LOPART(guid)); - if (sLog->ShouldLog(LOG_FILTER_CHARACTER, LOG_LEVEL_DEBUG)) // optimize GetPlayerDump call + if (sLog->ShouldLog(LOG_FILTER_PLAYER_DUMP, LOG_LEVEL_INFO)) // optimize GetPlayerDump call { std::string dump; if (PlayerDumpWriter().GetDump(GUID_LOPART(guid), dump)) - sLog->outDebug(LOG_FILTER_CHARACTER, dump.c_str(), GetAccountId(), GUID_LOPART(guid), name.c_str()); + { + std::ostringstream ss; + ss << GetAccountId() << '_' << name.c_str(); + sLog->outCharDump(ss.str().c_str(), dump.c_str(), GetAccountId(), GUID_LOPART(guid), name.c_str()); + } } Player::DeleteFromDB(guid, GetAccountId()); diff --git a/src/server/shared/Logging/Appender.h b/src/server/shared/Logging/Appender.h index 332edbf170c..ebe7408d400 100644 --- a/src/server/shared/Logging/Appender.h +++ b/src/server/shared/Logging/Appender.h @@ -62,10 +62,12 @@ enum LogFilterType LOG_FILTER_CHARACTER, LOG_FILTER_ARENAS, LOG_FILTER_SQL_DRIVER, - LOG_FILTER_SQL_DEV + LOG_FILTER_SQL_DEV, + LOG_FILTER_PLAYER_DUMP, + LOG_FILTER_BATTLEFIELD }; -const uint8 MaxLogFilter = uint8(LOG_FILTER_SQL_DEV) + 1; +const uint8 MaxLogFilter = uint8(LOG_FILTER_BATTLEFIELD) + 1; // Values assigned have their equivalent in enum ACE_Log_Priority enum LogLevel @@ -105,7 +107,6 @@ struct LogMessage : level(_level) , type(_type) , text(_text) - , param1(0) { mtime = time(NULL); } @@ -117,7 +118,7 @@ struct LogMessage LogFilterType type; std::string text; std::string prefix; - uint32 param1; + std::string param1; time_t mtime; }; diff --git a/src/server/shared/Logging/AppenderFile.cpp b/src/server/shared/Logging/AppenderFile.cpp index 01a2f34baa7..67adff39aae 100644 --- a/src/server/shared/Logging/AppenderFile.cpp +++ b/src/server/shared/Logging/AppenderFile.cpp @@ -24,7 +24,7 @@ AppenderFile::AppenderFile(uint8 id, std::string const& name, LogLevel level, co , logDir(_logDir) , mode(_mode) { - dynamicName = std::string::npos != filename.find("%u"); + dynamicName = std::string::npos != filename.find("%s"); backup = _flags & APPENDER_FLAGS_MAKE_FILE_BACKUP; logfile = !dynamicName ? OpenFile(_filename, _mode, backup) : NULL; @@ -44,7 +44,7 @@ void AppenderFile::_write(LogMessage& message) if (dynamicName) { char namebuf[TRINITY_PATH_MAX]; - snprintf(namebuf, TRINITY_PATH_MAX, filename.c_str(), message.param1); + snprintf(namebuf, TRINITY_PATH_MAX, filename.c_str(), message.param1.c_str()); logfile = OpenFile(namebuf, mode, backup); } diff --git a/src/server/shared/Logging/Log.cpp b/src/server/shared/Logging/Log.cpp index 27f33754da9..64f7e697f1f 100755 --- a/src/server/shared/Logging/Log.cpp +++ b/src/server/shared/Logging/Log.cpp @@ -449,6 +449,23 @@ void Log::outFatal(LogFilterType filter, const char * str, ...) va_end(ap); } +void Log::outCharDump(const char* param, const char * str, ...) +{ + if (!str || !ShouldLog(LOG_FILTER_PLAYER_DUMP, LOG_LEVEL_INFO)) + return; + + va_list ap; + va_start(ap, str); + char text[MAX_QUERY_LEN]; + vsnprintf(text, MAX_QUERY_LEN, str, ap); + va_end(ap); + + LogMessage* msg = new LogMessage(LOG_LEVEL_INFO, LOG_FILTER_PLAYER_DUMP, text); + msg->param1 = param; + + write(msg); +} + void Log::outCommand(uint32 account, const char * str, ...) { if (!str || !ShouldLog(LOG_FILTER_GMCOMMAND, LOG_LEVEL_INFO)) @@ -461,7 +478,10 @@ void Log::outCommand(uint32 account, const char * str, ...) va_end(ap); LogMessage* msg = new LogMessage(LOG_LEVEL_INFO, LOG_FILTER_GMCOMMAND, text); - msg->param1 = account; + + std::ostringstream ss; + ss << account; + msg->param1 = ss.str(); write(msg); } diff --git a/src/server/shared/Logging/Log.h b/src/server/shared/Logging/Log.h index 7b0e8cd381b..cd1e9dc80df 100755 --- a/src/server/shared/Logging/Log.h +++ b/src/server/shared/Logging/Log.h @@ -56,6 +56,7 @@ class Log void EnableDBAppenders(); void outCommand(uint32 account, const char * str, ...) ATTR_PRINTF(3, 4); + void outCharDump(const char* param, const char* str, ...) ATTR_PRINTF(3, 4); static std::string GetTimestampStr(); void SetRealmID(uint32 id); diff --git a/src/server/worldserver/worldserver.conf.dist b/src/server/worldserver/worldserver.conf.dist index be5a452c7b4..789af4e371b 100644 --- a/src/server/worldserver/worldserver.conf.dist +++ b/src/server/worldserver/worldserver.conf.dist @@ -2592,7 +2592,7 @@ PlayerDump.DisallowOverwrite = 1 # 5 - (Error) # 6 - (Fatal) # -# Flags: Default Console = 6, File = 7, DB = 0 +# Flags: # 0 - None # 1 - Prefix Timestamp to the text # 2 - Prefix Log Level to the text @@ -2629,13 +2629,14 @@ PlayerDump.DisallowOverwrite = 1 Appender.Console=1,2,6 Appender.Server=2,2,7,Server.log,w -Appender.GM=2,2,7,GM.log +Appender.GM=2,2,7,GM_%s.log Appender.SQL=2,2,7,SQL.log Appender.DBErrors=2,2,7,DBErrors.log Appender.Char=2,2,7,Char.log,w +Appender.CharDump=2,2,0,chardumps/%s.log Appender.RA=2,2,7,RA.log Appender.Arenas=2,2,7,Arena.log -Appender.SQLDev=2,2,7,SQLDev.log +Appender.SQLDev=2,2,0,SQLDev.log Appender.SQLDriver=2,2,7,SQLDriver.log Appender.Warden=2,2,7,Warden.log Appender.Chat=2,2,7,Chat.log @@ -2684,12 +2685,14 @@ Appender.Chat=2,2,7,Chat.log # 31 - Worldserver # 32 - Game Events # 33 - Calendar -# 34 - Character (Exclusive to log login, logout, create, rename, delete actions) +# 34 - Character (Exclusive to log login, logout, create, rename) # 35 - Arenas # 36 - SQL Driver # 37 - SQL Dev +# 38 - Player Dump +# 39 - Battlefield -Logger.Root=0,5,Console Server +Logger.Root=0,3,Console Server Logger.Units=1,3,Console Server Logger.Pets=2,3,Console Server Logger.Vehicles=3,3,Console Server @@ -2715,7 +2718,7 @@ Logger.PlayerChat=22,3,Chat Logger.Loot=23,3,Console Server Logger.Guilds=24,3,Console Server Logger.Transports=25,3,Console Server -Logger.SQL=26,2,Console Server SQL +Logger.SQL=26,2,Console Server DBErrors Logger.GM=27,3,Console Server GM Logger.RA=28,3,RA Logger.Warden=29,3,Warden @@ -2727,6 +2730,8 @@ Logger.Character=34,3,Char Logger.Arenas=35,3,Arenas Logger.SQLDriver=36,5,SQLDriver Logger.SQLDev=37,3,SQLDev +Logger.CharDump=38,5,CharDump +Logger.Battlefield=39,3,Console Server # LogLevel # 0 - (Disabled) @@ -2745,7 +2750,7 @@ Logger.SQLDev=37,3,SQLDev # (Using spaces as separator). # Default: "Console Server" -Appenders=Console Server +Appenders=Console Server GM Char Arenas Warden DBErrors CharDump # # Loggers @@ -2753,4 +2758,4 @@ Appenders=Console Server # (Using spaces as separator). # Default: "root" -Loggers=Root +Loggers=Root GM Character Arenas Warden SQL |