Search Unity

  1. Unity 2019.1 is now released.
    Dismiss Notice

Debug.Log and needless spam :]

Discussion in 'Wish List' started by Nightmaare, Jan 11, 2010.

  1. Nightmaare

    Nightmaare

    Joined:
    Nov 11, 2009
    Posts:
    7
    Please take a look at the following picture:



    I think that you'll all agree that the UnityEngine.Debug:Log(Object) is appended under every log statement, is not needed - doesn't make the programmer's life easier, doesn't help with finding bugs or telling anything important. It's making the log show twice less info than it could and increases visual clutter.

    Having used UE3, which has the simplest logger ever - `log("statement"); just prints the 'statement', without any line number, time&date info or anything else, I'm pretty disappointed by Unity's logger.

    If there's a need to distinguish between different log messages types, it's enough to change the icon (like it's already done) and if there's really a need to show UnityEngine.Debug:Log(Object) then it can be done in the small place below console, where you see the full text of message (and it's already shown there too).That's a good place for it.

    But please remove it from the main log (or at least give the option of disabling it)! I think it shouldn't be hard :] rather quick and easy change, that will improve the usability of console and whole unity platform a lot.


    Thank you.
     
    Xblade-Imperium42 likes this.
  2. Michael-Ryan

    Michael-Ryan

    Joined:
    Apr 10, 2009
    Posts:
    140
    You could override Unity's Debug class with your own. I've done this in the past.

    Code (csharp):
    1. using UnityEngine;
    2.  
    3. class Debug : UnityEngine.Debug
    4. {
    5.     private static string hr = "\n\n-------------------------------------------------------------------------------";
    6.  
    7.     public static new void Log(object message)
    8.     {
    9.         UnityEngine.Debug.Log(message.ToString() + hr);
    10.     }
    11.  
    12.     public static new void Log(object message, Object context)
    13.     {
    14.         UnityEngine.Debug.Log(message.ToString() + hr, context);
    15.     }
    16.  
    17.     public static new void LogError(object message)
    18.     {
    19.         UnityEngine.Debug.LogError(message.ToString() + hr);
    20.     }
    21.  
    22.     public static new void LogError(object message, Object context)
    23.     {
    24.         UnityEngine.Debug.LogError(message.ToString() + hr, context);
    25.     }
    26.  
    27.     public static new void LogWarning(object message)
    28.     {
    29.         UnityEngine.Debug.LogWarning(message.ToString() + hr);
    30.     }
    31.  
    32.     public static new void LogWarning(object message, Object context)
    33.     {
    34.         UnityEngine.Debug.LogWarning(message.ToString() + hr, context);
    35.     }
    36. }
    37.  
    Does the Unity Debug class get removed on release builds?

    When Unity iPhone apps are built for release on the AppStore, are the Debug messages usually present, or does Xcode remove them automatically?
     
    ocimum likes this.
  3. Nightmaare

    Nightmaare

    Joined:
    Nov 11, 2009
    Posts:
    7
    Erm, why would I do that?

    Instead of getting ie.

    "WALKING ON SURFACE blablabla
    UnityEngine.Debug:Log(Object)"

    in your implementation I would be getting:

    "WALKING ON SURFACE blablabla

    ----------------------------------------
    UnityEngine.Debug:Log(Object)"


    That would add even more to the unwanted spam. I don't need any more whitespaces or anything else... I just want to get rid of "UnityEngine.Debug:Log(Object)" ... or is there sth that I'm missing here?
     
  4. Michael-Ryan

    Michael-Ryan

    Joined:
    Apr 10, 2009
    Posts:
    140
    I'm not sure if you're aware of this, but every Unity Console message that is generated using Debug.Log includes stacktrace information that follows immediately after any custom message you specify.

    The Console just happens to show the first two lines of each message. Therefore, if you have a short message that takes up only one line, you will always see "UnityEngine.Debug:Log(Object)" directly beneath it.

    To get around that, you can manually append a newline character ("\n") after your message. Then you'll just see your custom message in the Console, because everything else will be cut off. Regardless, if you click on one of the Console items, you will see the full message in the area below.

    The code I provided earlier automatically adds the newline character, as well as a separator so it's easier to see where your portion of the log message ends, and the stacktrace begins.
     
  5. monark

    monark

    Joined:
    May 2, 2008
    Posts:
    1,464
    Does turning on the collapse option help?
     
  6. Nightmaare

    Nightmaare

    Joined:
    Nov 11, 2009
    Posts:
    7
    mryan: oh I see now what you meant. But I suspect that this approach makes the "UnityEngine.Debug:Log(Object)" text just pushed line below, so that it disappears from log, yet single element still has the same height and the whole list looks the same (minus the text, which makes it easier on the eyes which is good, but still not what I originally asked for).

    I don't know by myself, since I couldn't get it to work :/ ehhh noobish problem (I'm still new to unity): alongside other scripts, I made a new C# script file MyDebug, where I copied your code, renamed the class to MyDebug, and then tried using it in my
    javascript files:

    MyDebug.Log("WALKING ON SURFACE g: " + timeGrounded + " a: " + timeInAir );

    Unforunately I get "Unknown identifier: 'MyDebug'. " What's the way of "including" C# files in javascript and/or how to use this class ie do I have to define a static instance?


    monark: unfortunately collapse doesn't help
     
  7. Michael-Ryan

    Michael-Ryan

    Joined:
    Apr 10, 2009
    Posts:
    140
    See this page for information on mixing C# and Javascript:

    LINK: Overview: Script compilation (Advanced)

    I always use C#, but I just tried to duplicate what you were doing, and also received the error. Placing the C# script in the "Standard Assets" folder corrected the issue. The link above provides details on exactly how the engine compiles scripts.
     
  8. Orion

    Orion

    Joined:
    Mar 31, 2008
    Posts:
    205
    Hmm.. doesn't seem to work (anymore). I always get a
    Code (csharp):
    1. cannot derive from sealed type `UnityEngine.Debug'
    Although my concern is that I want to get rid of the stacktrace, unless specifically asked for. When testing performance for iPhone, one single Debug line takes about 50 times as long to compute as the rest of the frame, so I have to remove all debug output every time I want to test performance.
     
    Marzoa likes this.
  9. samizzo

    samizzo

    Joined:
    Sep 7, 2011
    Posts:
    456
    Bump. I'd like to get rid of the stacktrace too, as it is needless spam in the xcode debug log which is getting in the way of the real info that I want to see. Is there any way to do this?
     
    MattijsKneppers likes this.
  10. justinlloyd

    justinlloyd

    Joined:
    Aug 5, 2010
    Posts:
    1,679
    None that I know of if you are sending to the standard Unity Debug log window, but you can implement your own logging framework or use one of the many fine ones available. Implemented your own logging window and you're good to go.

    I use LoggingFramework which was a doddle to port to Unity. Gives me everything I need and I can turn logging on and off to the console as I desire.
     
  11. Ntero

    Ntero

    Joined:
    Apr 29, 2010
    Posts:
    1,436
    I kinda wish you could provide it with a Stack Trace. Or at least something useful so that when I double click the links I don't go to my define wrapped Asserts, but to the callee of those asserts.
     
  12. samizzo

    samizzo

    Joined:
    Sep 7, 2011
    Posts:
    456
    Thanks. How would one implement their own logging window? The only way to get debug output from Unity is via Debug.Log, right? So no matter what, your output is going to go via there in the end right? What does LoggingFramework do for you? Does it write to a file?
     
  13. 3Duaun

    3Duaun

    Joined:
    Dec 29, 2009
    Posts:
    600
    firstly, @JustinLloyd, pretty impressive you got LoggingFramework into Unity. Any possibility you'd be willing to share ;-)

    has anyone found a solution to strip all debug calls from an XCODE build, or preferably BEFORE Unity Builds the app itself, so they're stripped before the project goes into xcode? perhaps an asset in the asset store ;-).

    we're aware of the "Debug.isDebugBuild" approach, but would like to avoid it if possible.

    We've been searching for a solution that strips(thus sliences) ALL debug.log and debug.warning calls in our solution(we'd still like to be able to see logErrors, but would be willing to lose to too if the fix called for it). We haven't found any solutions. On and iPhone every cpu cycle is so precious, we'd love to have these debug.log/warning call's we've placed in our solution appear in the unity editor, but not be called at in the compiled app/ipa. That being said, we would happily lose ALL log messages if it would just prevent them from running when the app is on the (mobile) device. Its wild how much CPU time some log calls can take; yes we can manually silence them, but with a large solution, if we miss one or 2, its a timesink to have to go in and out and enable/disable them manually all the time :-(

    We'd greatly appreciate any help anyone can lend, as we started to think we were the only ones looking for such a solution(especially for mobiles).

    Thanks much for any help anyone can offer :)
     
    Last edited: Sep 17, 2011
  14. justinlloyd

    justinlloyd

    Joined:
    Aug 5, 2010
    Posts:
    1,679
    How to port LoggingFramework to Unity:

    Purchase LoggingFramework for $5 http://www.theobjectguy.com/dotnetlog/Overview.aspx
    Create logger class in BitFactory.Logging namespace that wraps Debug.Log in a DoLog override function
    Compile to .NET DLL
    Copy .NET DLL to Unity project plugins directory
    Add using LoggingFramework to required .CS files
    Instantiate logger in game startup code
    Run

    I'm having a hard time thinking of any other steps I might have missed. :)
     
  15. 3Duaun

    3Duaun

    Joined:
    Dec 29, 2009
    Posts:
    600
    thanks for taking the time walkthrough on installing LogginFramework, I was weary of the setup process, but no longer :)

    also, found this GREAT solution to strip all debug call by stripping out the out with an override that responds to the isDebugBuild setting, soooo useful.

    http://answers.unity3d.com/questions/126315/debuglog-in-build.html
     
  16. 3Duaun

    3Duaun

    Joined:
    Dec 29, 2009
    Posts:
    600
    thanks for taking the time walkthrough on installing LogginFramework, I was weary of the setup process, but no longer :)

    also, found this GREAT solution to strip all debug call by stripping out the out with an static overrid that responds to the isDebugBuild setting, soooo useful.

    http://answers.unity3d.com/questions/126315/debuglog-in-build.html
     
    Last edited: Sep 17, 2011
  17. samizzo

    samizzo

    Joined:
    Sep 7, 2011
    Posts:
    456
    Right, but you're still going through Debug.Log though, so you'll still get the callstack in the xcode debug output window..

    I guess the only way to do it is to write your own native logging function and call into that.
     
  18. 3Duaun

    3Duaun

    Joined:
    Dec 29, 2009
    Posts:
    600
    this method TOTALLY works for me, does exactly what I wanted, muting debug messages completely on a platform-specific basis. I have it check to see if the game is being played in any platform other than the unityeditor, if so, I have an if statement on all debug low/warning/errors that only process the deug.log/warning/error if the isDebugBuild variable (on my custom Debug Override Class) is true or false. I opened xcode, used the device console and tested on multiple devices, no debug prints or processing of any debug calls(when I have the ovveride class enabled). its awesome(for us anyway!)

    first I do this on launch of application:
    Code (csharp):
    1. [SIZE="3"]if (iPhoneSettings.model != "UnityEditor"){
    2.                  Debug.isDebugBuild = false; // ENABLE debug log messages in the Unity editor. if this is FALSE, which it is by default, NO debug messages would be displayed in the console or logged on the mobile(or desktop) device
    3.             }[/SIZE]
    then I create a new static Debug class to override the default unity debug class/processor. so AFAIK, and have been able to test, no more callstack logging(good for mobile devices, bad for unity editor ;-)).

    Code (csharp):
    1.  
    2. using UnityEngine;
    3. using System.Collections;
    4. using System;
    5. using System.IO;
    6. using System.Text.RegularExpressions;
    7. using UnityEngineInternal;
    8.  
    9. public static class Debug{
    10.     public static bool isDebugBuild = true;
    11.     //private static string hr = "\n\n-------------------------------------------------------------------------------";
    12.    
    13.    
    14.     public static new void Log (object message)
    15.     {   if (isDebugBuild)
    16.         UnityEngine.Debug.Log (message);
    17.         //UnityEngine.Debug.Log (message.ToString ());
    18.     }
    19.  
    20.     public static new void Log (object message, UnityEngine.Object context)
    21.     {   if (isDebugBuild)
    22.         UnityEngine.Debug.Log (message, context);
    23.         //UnityEngine.Debug.Log (message.ToString (), context);
    24.     }
    25.    
    26.    
    27.     public static new void LogError (object message)
    28.     {   if (isDebugBuild)
    29.         UnityEngine.Debug.LogError (message);
    30.         //UnityEngine.Debug.LogError (message.ToString ());
    31.     }
    32.  
    33.     public static new void LogError (object message, UnityEngine.Object context)
    34.     {   if (isDebugBuild)
    35.         UnityEngine.Debug.LogError (message, context);
    36.         //UnityEngine.Debug.LogError (message.ToString (), context);
    37.     }
    38.  
    39.     public static new void LogWarning (object message)
    40.     {   if (isDebugBuild)
    41.         UnityEngine.Debug.LogWarning (message.ToString ());
    42.     }
    43.  
    44.     public static new void LogWarning (object message, UnityEngine.Object context)
    45.     {   if (isDebugBuild)
    46.         UnityEngine.Debug.LogWarning (message.ToString (), context);
    47.     }
    48. }
    49.  
    again, this works perfectly for us, no debug printing or processing of log calls of any sort from our app, no callstack processing(that we've been able to see like we used to), nothing. and actually we've gained a noticeable amount of cpu on iOS devices after this remedy.
     
    Last edited: Sep 19, 2011
  19. samizzo

    samizzo

    Joined:
    Sep 7, 2011
    Posts:
    456
    Doesn't do what I want, but thanks anyway (I wanted debug output without stack trace logging). I'll call into my own native log function.
     
  20. imtrobin

    imtrobin

    Joined:
    Nov 30, 2009
    Posts:
    1,545
    this is annoying, I like to remove the stack trace as I look at the log file for debugging
     
  21. Ntero

    Ntero

    Joined:
    Apr 29, 2010
    Posts:
    1,436
    You can strip them out entirely using the System.Debug.ConditionalAttribute: http://msdn.microsoft.com/en-us/library/system.diagnostics.conditionalattribute.aspx


    It'll strip them out at compile time, which sounds like what you want samizzo
    Code (csharp):
    1.  
    2. [System.Debug.Conditional("UNITY_ENGINE")]
    3. public static new void LogError (object message)
    4. {
    5.     UnityEngine.Debug.LogError (message);
    6. }
    7.  
    It works off of defines, and the easiest way to create combinatory of inverted defines that I found is at the top of your Debugs class file do something like this:
    Code (csharp):
    1.  
    2. #if !UNITY_EDITOR || UNITY_IPHONE
    3. #Define NEWDEFINE
    4. #endif
    5.  
    Then use newdefine in your conditionals
     
  22. kolmich

    kolmich

    Joined:
    Apr 27, 2009
    Posts:
    147
    Hi check out this log- solution: KGFDebug

    You can define a log level, a stacktrace level, log categories, log to file, and you can extend this debugger/logger by your logging code simply by implementing the KGFIDebug interface...
     
  23. Dad

    Dad

    Joined:
    Sep 29, 2010
    Posts:
    10
    It would be great if this got reported as a feature request to Unity3d dev team. Totally agree that a log message *without* the stack trace is needed.
     
    Last edited: Jul 12, 2012
  24. bwilder

    bwilder

    Joined:
    Feb 1, 2012
    Posts:
    8
  25. superpig

    superpig

    Quis aedificabit ipsos aedificatores? Unity Technologies

    Joined:
    Jan 16, 2011
    Posts:
    4,131
    Have you tried just using System.Console.WriteLine() instead? I think someone said it writes to the editor log file without any stacktrace.
     
    Unity910 and fschneider like this.
  26. AlexHogan

    AlexHogan

    Joined:
    Oct 8, 2010
    Posts:
    5
    I do a lot of this stuff with a small extension method for the monobehaviour class:

    Code (csharp):
    1.  
    2. using UnityEngine;
    3. using System.Collections;
    4.  
    5. public static class GameObjectExtensions
    6. {
    7.     public static string tagString( this MonoBehaviour mb, string messageString  )
    8.     {
    9.         return string.Format( "[{0}] {1}.{2} : {3}\n\n",
    10.             Time.time.ToString(),
    11.             mb.name,
    12.             mb.GetType().ToString(),
    13.             messageString );
    14.     }
    15. }
    16.  
    It gets rid of the stacktrace in the editor (but not in log files, alas) and you still retain the ability to jump to your code from Unity's console.

    I use it from within other scripts like so:

    Code (csharp):
    1.  
    2.     void Start ()
    3.     {
    4.         Debug.Log( this.tagString( "I just started up!" ) );
    5.     }
    6.  
    And prints console messages like this:

    [0] MyGameObject.MonobehaviourScript : I just started up!
     
  27. AlexHogan

    AlexHogan

    Joined:
    Oct 8, 2010
    Posts:
    5
    I wanted to post a new little set of extension methods I use.

    I simply call this.spew() or this.spew( "Message" ) from any monobehavior and I get a timestamped message, labeled with the gameobject name, monobehavior component name, and the calling methodname.

    There's another one in there that lets a monobehavior tag a string you send it and return it to you, if you have to use it somewhere other than Debug.Log()

    Code (csharp):
    1.  
    2. using UnityEngine;
    3. using System.Collections;
    4. using System.Diagnostics;
    5.  
    6. public static class GameObjectExtensions
    7. {
    8.     public static void spew( this MonoBehaviour mb )
    9.     {
    10.         // get call stack
    11.         StackTrace stackTrace = new StackTrace();
    12.  
    13.         // get calling method name
    14.         string methodName = stackTrace.GetFrame(1).GetMethod().Name;
    15.        
    16.         string output = string.Format( "[{0}] {1}.{2} : {3}\n\n",
    17.             Time.time.ToString(),
    18.             mb.name,
    19.             mb.GetType().ToString(),
    20.             methodName);
    21.        
    22.         UnityEngine.Debug.Log (output);
    23.     }
    24.    
    25.     public static void spew( this MonoBehaviour mb, string messageString )
    26.     {
    27.         // get call stack
    28.         StackTrace stackTrace = new StackTrace();
    29.  
    30.         // get calling method name, jump up one because this is an extension method and it counts
    31.         string methodName = stackTrace.GetFrame(1).GetMethod().Name;
    32.        
    33.         string output = string.Format( "[{0}] {1}.{2} {4}() : {3}\n\n",
    34.             Time.time.ToString(),
    35.             mb.name,
    36.             mb.GetType().ToString(),
    37.             messageString,
    38.             methodName);
    39.        
    40.         UnityEngine.Debug.Log(output);
    41.     }
    42.    
    43.     public static string tagString( this MonoBehaviour mb, string messageString  )
    44.     {  
    45.         return string.Format( "[{0}] {1}.{2} : {3}\n\n",
    46.             Time.time.ToString(),
    47.             mb.name,
    48.             mb.GetType().ToString(),
    49.             messageString);    
    50.     }
    51. }
    52.  
     
  28. kimsama

    kimsama

    Joined:
    Jan 2, 2009
    Posts:
    166
    Tested and seems to work fine.

    Note:
    Using other preprocessor directives than UNITY_EDITOR does not correctly work which means using 'DEBUG' preprocessor with Conditional attribute, no log messages are put on the console even it runs on Unity editor.

    Code (csharp):
    1.  
    2. //#if UNITY_EDITOR
    3. //#define DEBUG
    4. //#endif
    5.  
    6. using UnityEngine;
    7. using System.Collections;
    8. using System;
    9. using System.IO;
    10. using System.Text.RegularExpressions;
    11. using UnityEngineInternal;
    12.  
    13.  
    14. ///
    15. /// It overrides UnityEngine.Debug to mute debug messages completely on a platform-specific basis.
    16. ///
    17. /// Putting this inside of 'Plugins' foloder is ok.
    18. ///
    19. /// Important:
    20. ///     Other preprocessor directives than 'UNITY_EDITOR' does not correctly work.
    21. ///
    22. /// Note:
    23. ///     [Conditional] attribute indicates to compilers that a method call or attribute should be
    24. ///     ignored unless a specified conditional compilation symbol is defined.
    25. ///
    26. /// See Also:
    27. ///     http://msdn.microsoft.com/en-us/library/system.diagnostics.conditionalattribute.aspx
    28. ///
    29. /// 2012.11. @kimsama
    30. ///
    31. public static class Debug
    32. {
    33.     public static bool isDebugBuild
    34.     {
    35.     get { return UnityEngine.Debug.isDebugBuild; }
    36.     }
    37.  
    38.     [System.Diagnostics.Conditional("UNITY_EDITOR")]
    39.     public static void Log (object message)
    40.     {  
    41.         UnityEngine.Debug.Log (message);
    42.     }
    43.  
    44.     [System.Diagnostics.Conditional("UNITY_EDITOR")]
    45.     public static void Log (object message, UnityEngine.Object context)
    46.     {  
    47.         UnityEngine.Debug.Log (message, context);
    48.     }
    49.        
    50.     [System.Diagnostics.Conditional("UNITY_EDITOR")]
    51.     public static void LogError (object message)
    52.     {  
    53.         UnityEngine.Debug.LogError (message);
    54.     }
    55.  
    56.     [System.Diagnostics.Conditional("UNITY_EDITOR")]   
    57.     public static void LogError (object message, UnityEngine.Object context)
    58.     {  
    59.         UnityEngine.Debug.LogError (message, context);
    60.     }
    61.  
    62.     [System.Diagnostics.Conditional("UNITY_EDITOR")]
    63.     public static void LogWarning (object message)
    64.     {  
    65.         UnityEngine.Debug.LogWarning (message.ToString ());
    66.     }
    67.  
    68.     [System.Diagnostics.Conditional("UNITY_EDITOR")]
    69.     public static void LogWarning (object message, UnityEngine.Object context)
    70.     {  
    71.         UnityEngine.Debug.LogWarning (message.ToString (), context);
    72.     }
    73.  
    74.     [System.Diagnostics.Conditional("UNITY_EDITOR")]
    75.     public static void DrawLine(Vector3 start, Vector3 end, Color color = default(Color), float duration = 0.0f, bool depthTest = true)
    76.     {
    77.     UnityEngine.Debug.DrawLine(start, end, color, duration, depthTest);
    78.     }
    79.    
    80.     [System.Diagnostics.Conditional("UNITY_EDITOR")]
    81.     public static void DrawRay(Vector3 start, Vector3 dir, Color color = default(Color), float duration = 0.0f, bool depthTest = true)
    82.     {
    83.     UnityEngine.Debug.DrawRay(start, dir, color, duration, depthTest);
    84.     }
    85.    
    86.     [System.Diagnostics.Conditional("UNITY_EDITOR")]
    87.     public static void Assert(bool condition)
    88.     {
    89.     if (!condition) throw new Exception();
    90.     }
    91. }
    92.  
    Thank you.

    [EDIT} Added isDebugBuild property.


    -kimsama
     
    Last edited: Nov 21, 2012