LogWrite() - The Basics

Tutorials on setting up a server, configuring your client, and connecting to an EQ2Emulator server.
Only moderators can start new topics here
Forum rules
Most information about EQ2Emulator and Tutorials can be found at the Project Wiki. Look there for the most current information.
Locked
User avatar
John Adams
Retired
Posts: 9684
Joined: Thu Jul 26, 2007 6:27 am
EQ2Emu Server: EQ2Emulator Test Center
Characters: John
Location: Arizona
Contact:

LogWrite() - The Basics

Post by John Adams » 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:

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")
A LOG_TYPE is further broken down into it's own parts, and are in LogTypes.h as "default logging options".
  • 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
These hard-coded definitions mean Logging will still work even if you do not have a log_config.xml file. The log_config.xml file is used as an "override" to change logging levels/displays without having to recompile the code. A typical log_config.xml entry would be as follows:

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>
You can see the format is slightly different, but basically does the same thing (in simpler terms):
  • 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
An example log entry would be like this:

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 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.

Locked

Who is online

Users browsing this forum: No registered users and 0 guests