LogWrite() - The Basics
Posted: Fri Oct 21, 2011 1:03 pm
This tutorial will help you understand the EQ2Emu custom Logging system and give examples of it's use (and expandability).
Why Log?
Logging is needed for any application to show current functionality and/or debugging information. We have always had logging in EQ2Emulator, but now it is enhanced and easier to understand and implement. Our logging system is made up of the following components, and (imo) are fairly easy to understand and implement.
First, all "loggers" must be pre-defined in LogTypes.h, Here is an example of our Items loggers:
A LOG_TYPE is further broken down into it's own parts, and are in LogTypes.h as "default logging options".
You can see the format is slightly different, but basically does the same thing (in simpler terms):
Log entries are made up of a few pieces of data:
The first LogWrite example shows a simple int32 value passed to the logger.
The second is a little more complex, with some calculations in-line being sent to the logger.
So where do you put log entries?
Wherever you think they will have value.
For example, you want to offer INFO that ITEMS are loading, so you write an ITEM__INFO logger before the function LoadItems(); Inside the LoadItem() function.
If you want to place some DEBUG loggers to show statistics of the different Item Types loading, so you would build ITEM__DEBUG loggers between Armor, Bag, Bauble....Weapon Item load routines.
If you want extreme DETAIL of each item loaded during the loading process, you would insert a ITEM__DETAIL logger inside the while() or for() loops that are iterating through the values.
You would generally put a ITEM__ERROR or ITEM__WARNING logger if something goes wrong with loading, where ERROR is fatal, and WARNING means the data/code is not critical, but something went wrong loading it.
And as mentioned before, if there is not a Logger pre-defined for something you feel should be a unique scenario, you can always add a logger to the definitions (LogTypes.h), the log_config.xml, and your code.
Next topic will be more advanced logging information.
Why Log?
Logging is needed for any application to show current functionality and/or debugging information. We have always had logging in EQ2Emulator, but now it is enhanced and easier to understand and implement. Our logging system is made up of the following components, and (imo) are fairly easy to understand and implement.
First, all "loggers" must be pre-defined in LogTypes.h, Here is an example of our Items loggers:
Code: Select all
LOG_CATEGORY(ITEM)
LOG_TYPE(ITEM, INFO, FOREGROUND_WHITE_BOLD, ENABLED, ENABLED, ENABLED, "I")
LOG_TYPE(ITEM, WARNING, FOREGROUND_YELLOW_BOLD, ENABLED, ENABLED, ENABLED, "W")
LOG_TYPE(ITEM, ERROR, FOREGROUND_RED_BOLD, ENABLED, ENABLED, ENABLED, "E")
LOG_TYPE(ITEM, DEBUG, FOREGROUND_GREEN_BOLD, ENABLED, ENABLED, ENABLED, "D")
LOG_TYPE(ITEM, PACKET, FOREGROUND_CYAN_BOLD, DISABLED, DISABLED, DISABLED, "P")
LOG_TYPE(ITEM, DETAIL, FOREGROUND_GREEN, DISABLED, DISABLED, DISABLED, "T")- ITEM - the LOG_CATEGORY this configuration belongs to
[TYPE] - Custom, can be anything you need for your log entry, but must be PRE-DEFINED HERE
COLOR - Any of our pre-configured colors - again, more can be added following the rules of ANSI console colors
ENABLE - Tells if the log entry is enabled at all
ENABLE - Tells if the log entry is enabled to write to a log text file
ENABLE - Tells if the log entry is enabled to write to the console dialog (colors)
STR - This 1-character string will identify what type of log entry is being displayed
eg., I = Information, D = Debug
Code: Select all
<LogConfig Category="ITEM">
<ConfigType Type="INFO" Color="WhiteBold" Enabled="True" Logs="3" />
<ConfigType Type="WARNING" Color="YellowBold" Enabled="True" Logs="3" />
<ConfigType Type="ERROR" Color="RedBold" Enabled="True" Logs="3" />
<ConfigType Type="DEBUG" Color="GreenBold" Enabled="False" Logs="3" />
<ConfigType Type="PACKET" Color="Yellow" Enabled="False" Logs="3" />
<ConfigType Type="DETAIL" Color="Green" Enabled="False" Logs="3" />
</LogConfig>- Category = ITEM
ConfigType = INFO, with a bold-white text output, the entry is Enabled, and is told to output to File and Console
"Logs" is a bitwise value, where 1 = File, 2 = Console and 4 = Client. Therefore, 1+2 = 3.
Log entries are made up of a few pieces of data:
Code: Select all
LOG_CATEGORY, LOG_TYPE, CAT_TEXT, LOG_TEXT{, Parameters})- LOG_CATEGORY will usually be the the system it is meant for. Ie., Spawns, Spells, Items, Quests... etc.
LOG_TYPE will be the type of entry it is, Info, Warning, Error, Debug...
CAT_TEXT is a custom text field to display on the log entry
LOG_TEXT is the body of the log message itself (using normal string formatting like %s, %i, %.2f)...
{Parameters} is optional, and only needed if you are passing values into the LOG_TEXT
Code: Select all
LogWrite(ITEM__ERROR, "Item", "Unknown item broker stat type %u", btype);
LogWrite(ITEM__INFO, "Items", "Loaded %u Total Items (took %u seconds)", total, Timer::GetUnixTimeStamp() - t_now);
The second is a little more complex, with some calculations in-line being sent to the logger.
So where do you put log entries?
Wherever you think they will have value.
For example, you want to offer INFO that ITEMS are loading, so you write an ITEM__INFO logger before the function LoadItems(); Inside the LoadItem() function.
If you want to place some DEBUG loggers to show statistics of the different Item Types loading, so you would build ITEM__DEBUG loggers between Armor, Bag, Bauble....Weapon Item load routines.
If you want extreme DETAIL of each item loaded during the loading process, you would insert a ITEM__DETAIL logger inside the while() or for() loops that are iterating through the values.
You would generally put a ITEM__ERROR or ITEM__WARNING logger if something goes wrong with loading, where ERROR is fatal, and WARNING means the data/code is not critical, but something went wrong loading it.
And as mentioned before, if there is not a Logger pre-defined for something you feel should be a unique scenario, you can always add a logger to the definitions (LogTypes.h), the log_config.xml, and your code.
Next topic will be more advanced logging information.