Better Debug Logging in Unity

Debug logging for me, and I’m sure I’m not alone, has always been a love-hate relationship. I love getting my valuable information but hate the slow-downs associated with it. With these things in mind I took it upon myself to improve the experience.

It was important to me to be able to set filters for the types of messages that I wanted to show, so I created a small static wrapper for the built-in debug logger. Using these filters I can determine what messages I want to see by setting a few flags when initializing the wrapper. Since the wrapper contains flag checks for each filter type it would also be easy to leave these filters turned on in release and gather assert information as telemetry. Keep in mind that this isn’t the most optimized version of this script, and it can in fact be extended quite a bit. This is, more than anything, a concept for debug logging that I wanted to share.

Using the wrapper is easy, but I’ll demonstrate how to use it. First create a c# script named CDebugLogger and just copy over this text into the script.

/*********************************************************************
 *	File : 		CDebugLogger.cs
 * 
 * 	Author :	Chase Cobb
 * 
 * 	Purpose : 	To wrap the functionality of the Unity Debugger to allow
 * 				control over what messages should be shown
 */

using UnityEngine;
using System.Collections;
using System;


public static class CDebugLogger
{
    private static string WARN_MESSAGE =            "Warning : ";
    private static string ERROR_MESSAGE =           "Error : ";
    private static string CRITICAL_MESSAGE =        "Critical : ";
    private static string INFO_MESSAGE =            "Information : ";
	
	//Each enumerated value should be a power of two
    [Flags]
    public enum EDebugLevel
    {
        DEBUG_WARN = 0x1,
        DEBUG_ERROR = 0x2,
        DEBUG_CRITICAL = 0x4,
        DEBUG_INFO = 0x8
    }

    /// 
    /// This property determines which debug messages are seen int the output
    /// to set this property use SetDebugLoggingLevel
    /// 
    public static int DebugLevel
    {
        get;set;
    }

    /// 
    /// Sets which debug messages should be shown
    /// 
    /// flags to determine which levels are shown
    public static void SetDebugLoggingLevel(int nDebugLevel)
    {
        DebugLevel = nDebugLevel;
    }

    /// 
    /// Function responsible for writing to the debug log
    /// 
    /// Debug level of this message, from enum EDebugLevel
    /// The message to write
    public static void WriteToLog(EDebugLevel eLevel, object cMessage)
    {
        if ((eLevel & EDebugLevel.DEBUG_WARN) != 0 && (DebugLevel & (int)EDebugLevel.DEBUG_WARN) != 0)
        {
            Debug.Log(WARN_MESSAGE + cMessage);
        }
        else if ((eLevel & EDebugLevel.DEBUG_ERROR) != 0 && (DebugLevel & (int)EDebugLevel.DEBUG_ERROR) != 0)
        {
            Debug.Log(ERROR_MESSAGE + cMessage);
        }
        else if ((eLevel & EDebugLevel.DEBUG_CRITICAL) != 0 && (DebugLevel & (int)EDebugLevel.DEBUG_CRITICAL) != 0)
        {
            Debug.Log(CRITICAL_MESSAGE + cMessage);
        }
        else if ((eLevel & EDebugLevel.DEBUG_INFO) != 0 && (DebugLevel & (int)EDebugLevel.DEBUG_INFO) != 0)
        {
            Debug.Log(INFO_MESSAGE + cMessage);
        }
    }
}

After that, be sure to initialize the script and set the desired flags using the OR bitwise operator. This needs to be done in a script that will be guaranteed to load at the beginning of the scene. I use a persistent game manager class to initialize mine.

The only messages that will show are the ones that you set here!

//Set the debug levels to show in the debug log
CDebugLogger.SetDebugLoggingLevel((int)CDebugLogger.EDebugLevel.DEBUG_WARN |
                                  (int)CDebugLogger.EDebugLevel.DEBUG_ERROR |
                                  (int)CDebugLogger.EDebugLevel.DEBUG_CRITICAL |
                                  (int)CDebugLogger.EDebugLevel.DEBUG_INFO);

All that remains now is to use the wrapper for logging. Include your flag to determine the level of debugging that you desire for this message. Then include the message you wish to see as the second parameter( the second parameter is used exactly like the normal debug.log() function).

CDebugLogger.WriteToLog(CDebugLogger.EDebugLevel.DEBUG_INFO, "m_rSpawnRect.xMax = " + m_rSpawnRect.xMax);

Once that is done just run your game and enjoy your new easily controlled debug logging!

CDebugLogger

4 thoughts on “Better Debug Logging in Unity

    • While this is true of the current implementation, unfortunately, all hope is not lost. With a custom console log window you can grab the stack trace of the double-clicked log and use that to navigate to the correct line. Maybe I’ll show how to do that in an update. Thanks for commenting! 🙂

        • I don’t disagree with this method at all. My only reasoning for not doing it this way is to remove overhead of upkeep of external dlls, if it were something that would change frequently (which mine will). This is a pretty solid example you have though! Here I was thinking I was the only person who thought Unity’s debugging needed some TLC.:P

Leave a Reply

Your email address will not be published.