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.

I've got the same issue - Anyone ?

–

Same here. Anything?

–

I did something similar on a project, but ended up creating my own log window to take the place of the Unity console, and handling double-click myself.

–

I did all this actions but my error didn't solved... any error don't display in console just a error image .... I restarted Unity and tried to Build it but did't worked.... and I should say I did these on sample project .... I really get confused please help me...

–

6 Answers

6

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.

That worked brilliantly! Thanks much andy_t.

–

How did you move it to a "separate assembly?" I am looking to do the same thing.

–

You can set up a Visual Studio project outside of the Unity Assets folder and build your code as a standalone C# project, with a reference to the UnityEngine assembly. This will create a separate assembly (DLL file) that you can copy into the Unity Assets folder (or make it build there in the first place). See http://docs.unity3d.com/Manual/UsingDLL.html for details.

–

Awesome - thank you very much @yoyo!

–

I have a sub project in its own asmdef but I still navigating to the logger sources instead of my main project. Generating dll manually every single change looks like hell

–

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

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

    // 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);
    }
    else
    {
        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

Close. That does get me the file and line number. Still can't double click it in the console window and be taken directly to the line though.

–

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)

Interesting. But here you can't change the log message that's output or change the logging signatures - which is key.

–

Ah, you're right. I missed the crux of the question. This lets you tack additional enhancements on to logging, but doesn't let you change the log message which is sent to the console. Presumably, there's a way to do so if you have access to the source itself.

–

Still helped me do exactly what i needed, never even knew such an awesome thing existed :)

–

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:
http://unityconsole.com

Had Econsole for a while, was delighted to see It had support for wrapper functions!

–

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