Loading...   

[Show Table of Contents]


§EQEmuLogSys

  • 1/22/2015 EQEmu saw an overhaul of the logging system that was badly needed for many reasons.
    • The need to eliminate 10+ cpp.h files containing dozens of different logging systems of varying complexity, overall 2k+ lines removed
      • A logging system managed through log.ini with many categories that most don't know enough about
      • Clients logs, mob logs, zone logs that I personally haven't used in my 8 years being around and no one else uses
      • Many different subscription hooks and very bloated different systems, many duplicative functions with much needed in desire for simplicity, scalability and flexibility

§The Code (In the Source)

  • First I will start by explaining the number one used function in all of the source, Log.Out:
void Out(Logs::DebugLevel debug_level, uint16 log_category, std::string message, ...)

/* 
		The one and only Logging function that uses a debug level as a parameter, as well as a log_category
		log_category - defined in Logs::LogCategory::[]
		log_category name resolution works by passing the enum int ID to Logs::LogCategoryName[category_id]

		Example: EQEmuLogSys::Out(Logs::General, Logs::Guilds, "This guild has no leader present");
			- This would pipe the same category and debug level to all output formats, but the internal memory reference of log_settings would 
				be checked against to see if that piped output is set to actually process it for the category and debug level
	*/
  • In each project (world/zone/ucs/etc.), EQEmuLogSys:: class is referenced via Log.
    • ​Usage Examples: (Zone bootup)
Log.Out(Logs::General, Logs::Zone_Server, "Loading guilds");
guild_mgr.LoadGuilds();
	
Log.Out(Logs::General, Logs::Zone_Server, "Loading factions");
database.LoadFactionData();
	
Log.Out(Logs::General, Logs::Zone_Server, "Loading titles");
title_manager.LoadTitles();
	
Log.Out(Logs::General, Logs::Zone_Server, "Loading AA effects");
database.LoadAAEffects();
  • It also supports the use of parameters just like the old system which is printf-like:
Log.Out(Logs::General, Logs::Zone_Server, "Starting EQ Network server on port %d", Config->ZonePort);
  • Ultimately, this function is the end-all for everything, if there is a new category that needs to be created for debugging purposes

§Defining Categories

  • Categories are defined in 3 places and are very simple to add to
    • Logs::LogCategory (common/eqemu_logsys.h)
      • Defines enumeration number for the category MAKE SURE YOU ONLY ADD NEW CATEGORIES AT THE BOTTOM
    • Logs::LogCategoryName[category_id] (common/eqemu_logsys.h)
      • Name resolution for various functions
    • Database Table `logsys_catgories`
      • Where ALL log settings get loaded from for the server and all processes
      • The log_category_id must line up with the enum in Logs::LogCategory, if you simply added to the end of the list of all three of the places just mentioned in this section, you have done it sir.
      • Note, as of deployment of this system, 1/22/2015, these are the current default settings.
+-----------------+------------------------------------+----------------+-------------+--------------+
| log_category_id | log_category_description           | log_to_console | log_to_file | log_to_gmsay |
+-----------------+------------------------------------+----------------+-------------+--------------+
|               1 | AA                                 |              0 |           0 |            0 |
|               2 | AI                                 |              0 |           0 |            0 |
|               3 | Aggro                              |              0 |           0 |            0 |
|               4 | Attack                             |              0 |           0 |            0 |
|               5 | Packet: Client -> Server           |              0 |           0 |            0 |
|               6 | Combat                             |              0 |           0 |            0 |
|               7 | Commands                           |              0 |           0 |            0 |
|               8 | Crash                              |              1 |           1 |            0 |
|               9 | Debug                              |              0 |           0 |            0 |
|              10 | Doors                              |              0 |           0 |            0 |
|              11 | Error                              |              1 |           1 |            0 |
|              12 | Guilds                             |              0 |           0 |            0 |
|              13 | Inventory                          |              0 |           0 |            0 |
|              14 | Launcher                           |              1 |           1 |            0 |
|              15 | Netcode                            |              0 |           0 |            0 |
|              16 | Normal                             |              1 |           1 |            0 |
|              17 | Object                             |              0 |           0 |            0 |
|              18 | Pathing                            |              0 |           0 |            0 |
|              19 | QS_Server                          |              0 |           0 |            0 |
|              20 | Quests                             |              0 |           0 |            0 |
|              21 | Rules                              |              0 |           0 |            0 |
|              22 | Skills                             |              0 |           0 |            0 |
|              23 | Spawns                             |              0 |           0 |            0 |
|              24 | Spells                             |              0 |           0 |            0 |
|              25 | Status                             |              1 |           1 |            0 |
|              26 | TCP_Connection                     |              0 |           0 |            0 |
|              27 | Tasks                              |              0 |           0 |            0 |
|              28 | Tradeskills                        |              0 |           0 |            0 |
|              29 | Trading                            |              0 |           0 |            0 |
|              30 | Tribute                            |              0 |           0 |            0 |
|              31 | UCS_Server                         |              1 |           1 |            0 |
|              32 | WebInterface_Server                |              1 |           1 |            0 |
|              33 | World_Server                       |              1 |           1 |            0 |
|              34 | Zone Server                        |              1 |           1 |            0 |
|              35 | MySQL Error                        |              1 |           1 |            1 |
|              36 | MySQL Queries                      |              0 |           0 |            0 |
|              37 | Mercenaries                        |              0 |           0 |            0 |
|              38 | Quest Debug                        |              0 |           0 |            1 |
|              39 | Packet: Server -> Client           |              0 |           0 |            0 |
|              40 | Packet: Client -> Server Unhandled |              0 |           0 |            0 |
|              41 | Packet: Server -> Client With Dump |              0 |           0 |            0 |
|              42 | Packet: Server -> Client With Dump |              0 |           0 |            0 |
+-----------------+------------------------------------+----------------+-------------+--------------+

§Debug Levels

  • There are currently three debug levels:
    1. Logs::General - 1 - Low-Level general debugging, useful info on single line
    2. Logs::Moderate -  2 - Informational based, used in functions, when particular things load
    3. Logs::Detail - 3 - Use this for extreme detail in logging, usually in extreme debugging in the stack or interprocess communication
  • Debug levels are PER category, so if you wanted to set for example, level 3 debugging enabled to gmsay (In Game) but only 1 to your console, you put respectively 1 in your console field and 3 in gmsay for whatever category it is your enable

§Settings

  • All settings are managed in logsys_categories database table as mentioned above.
  • When a process boots up, such as zone/world/ucs/queryserv/etc. - These settings will load and whatever applies to the server category wise is what it will use as 'rules' to understand where to send output, as well as what level of information (high or low) to display
    • Please note that log_to_gmsay is only available for Zone level debugging.

§Enabling Settings In-Game

  • So what if I have world and zone up, and I want to make changes to my logging?
    • Before this change, you'd have to recompile your binaries in order to change the level of logging or the categories that you see. Now everything is done at runtime and can be easily reloaded at runtime

§Command #logs

  • #logs - Will display usage menu
    • #logs reload_all - Reload all settings in world and all zone processes with what is defined in the database
    • #logs list_settings - Shows current log settings and categories loaded into the current process' memory
    • #logs set [console|file|gmsay] - Sets log settings during the lifetime of the zone

#logs list settings

§#logs set gmsay example, enabling MySQL Query debugging to gmsay

§File Logs

  • Not a lot has changed about how we do logging, but here are some distinct changes:
    • All zone logs go underneath a respective logs/zone/
      • All zones, once booted up, will have a name that actually means something to a server administrator:
      • Examples:
        • nexus_version_0_inst_id_0_port_7000_20084.log
        • nexus_version_0_inst_id_0_port_7000_24356.log
        • zone_20084.log - A zone that has been booted up as a dynamic, but not assigned to any logical zone yet
    • All crash logs will make their way underneath logs/crash
    • All other process logs go to the top level of logs, this may change
  • Naming Convention:
    • ​Unless a zone is using zone properties for the file name, most processes will look like the following convention:
      • ​process_name_processid.log

§Example Output Screenshots

An example of GMSay output of several different categories being displayed
Windows Console of Zone, initial bootup

Linux Console

(ANSI Color support)

§Packet Logging

  • Useful for developers, its nice to see what activitiy is happening realtime, and now we have the ability to sink it to any output format simultaneously.
  • Here are some examples:

§Server -> Client

§Client -> Server 

§Unhandled Packets

§Packet Logging Levels

  • The main differentiator when deciding how much information you want to see with each packet, you use two different but very smiliar categories for each type. It all comes down to whether or not you want to see the packet dump data with the packet or not. As of this time, Packet: Client -> Server Unhandled always dumps the packet because they are far less frequent.
    • Packet: Client -> Server
    • Packet: Server -> Client
    • Packet: Server -> Client With Dump
    • Packet: Server -> Client With Dump

Here is the difference:

§Packet: Client -> Server & Packet: Server -> Client