Debug Wrapper Class

I’d like to create a class that wraps Debug.Log so I can enhance logging. To start, I created something very simple:

public static class Log  
  public static void Format(string format, params object[] args)  
    Debug.Log(string.Format(format, args));  

The problem is, when the log message appears in the console, double clicking it will bring you to this classes Debug.Log statement rather than the actual code where Log.Format was called.

Anyone found a way around this? That is, a way to wrap Debug.Log such that when clicked in the console you’re taken to the source line that called the wrapper, and not to the wrapper itself.

You can move your logging code to a separate assembly. In this case double click will ignore all stack frames on the top not from the current assembly so you’ll be navigated to a proper file/line.

public static void Log(object format, params object paramList)
System.Diagnostics.StackFrame f = stackTrace.GetFrame(2);

    string log = string.Format("[{3}.{4}] == ",
        f.GetFileLineNumber(),      // always reports 0
        f.GetFileColumnNumber(),    // always reports 0

    // if the last parameter is a unity object, lets feed it in as the context 
    UnityEngine.Object newContext = null;
    if(paramList.Length > 0 && paramList[paramList.Length - 1] is UnityEngine.Object)
         newContext = paramList[paramList.Length - 1] as UnityEngine.Object;
    //UnityEngine.Object context = f.GetMethod().ReflectedType;
    if (format is string)
        log += format as string;
        Debug.Log(string.Format(log, paramList), newContext);
        log += format.ToString();
        UnityEngine.Debug.Log(log, newContext);

This is the closest i’ve come to doing that exact thing. It when double clicking, it still takes you to the debug proxy but when you select them in the editor, it will flash the object that signaled the log statement.

I think you should be able to use this: StackTrace Class (System.Diagnostics) | Microsoft Learn

This is an old thread, but came up as I was searching for a solution.

Unity now supports this internally via a logging event, for which you can designate handlers.

So try:

Application.logMessageReceived += HandlerMethodName;

The handler signature must be:
HandlerMethodName(string logString, string stackTrace, LogType type)

I created a console replacement for Unity. My console lets you open any row of the callstack with a double-click. The free version is limited in that it only lets you open the top couple rows of the callstack. For some projects this is enough.

The pro version also lets you mark methods as “wrappers”. The console knows to automatically ignore your wrapper functions. When you click on an entry, it walks the callstack, skipping past wrappers, opening the first non-wrapper row. It works well, and it also works with externally built DLLs as long as you include your .mdb file with your .dll file.

Check it out:

I found a very cool solution using andy_t’s answer and IC_ assembly definition (asmdef) suggestion…

This is definitely not the perfect solution and it probably has some drawbacks - but for personal use it’s the easiest way I found.

  1. Put the desired code (eg. assert wrapper) into a separate folder and add an assembly definition asset to it.
  2. Uncheck the assembly definitions Auto Referenced option.
  3. Switch to Visual Studio, find the assembly and build it.
  4. Copy the generated DLL to anywhere inside your Assets folder, except the asmdef folder. The DLL location is shown in the Output View (typically ProjectFolder/Temp/bin/Debug/AssemblyName.dll).
  5. Go back to the asmdef asset and check all Exclude Platforms options. (Unchecking everything does not work as of 2019.10f2.)