aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/LoggingHOWTO.txt276
-rw-r--r--src/server/authserver/authserver.conf.dist2
-rw-r--r--src/server/game/Handlers/CharacterHandler.cpp8
-rw-r--r--src/server/shared/Logging/Appender.h9
-rw-r--r--src/server/shared/Logging/AppenderFile.cpp4
-rwxr-xr-xsrc/server/shared/Logging/Log.cpp22
-rwxr-xr-xsrc/server/shared/Logging/Log.h1
-rw-r--r--src/server/worldserver/worldserver.conf.dist21
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