Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.

Debug.Log Extensions

Discussion in 'Assets and Asset Store' started by SisusCo, Mar 17, 2020.

  1. SisusCo

    SisusCo

    Joined:
    Jan 29, 2019
    Posts:
    886
    Hi @yenmoc !

    Do you mean having Debug.Log Extensions get installed under the Packages folder instead of the Assets folder?

    This isn't supported yet by Unity for asset store packages unfortunately - although I did just now find this experimental repo that seems to make it possible...now I am interested in trying it out!
     
  2. yenmoc

    yenmoc

    Joined:
    Sep 21, 2019
    Posts:
    5
    Hi @SisusCo Well, I will try it hope it works, if not sure I will try refactoring
     
  3. LuiBroDood

    LuiBroDood

    Joined:
    Mar 13, 2019
    Posts:
    63
    #1 can i add to Channel.cs the Sisus.Debugging namespace ? without any problems?

    Channel in global namespace interferes with FishNet
    ... hmm even tho fishnet's Channel is in a namespace... weird... idk whats going on lol
    but adding Channel.cs to the Sisus.Debugging makes it have no console reported errors and allows it to Play lol

    #2 also, i can put the whole folder in any folder? i put it in Plugins/1_Docu/Debug.Log Extensions

    is this okay or will something break?

    best console plugin
    thanks
     
  4. SisusCo

    SisusCo

    Joined:
    Jan 29, 2019
    Posts:
    886
    Hey @LuiBroDood !

    You don't actually have to modify the class manually; the Channel.cs is auto-generated based on the list of channels defined in Project Settings > Debug.Log Extensions.

    In the Project Settings you can uncheck the Replace Default Debug Class option, and then hit the Rebuild Channel Class button and the Channel class will get moved under the Sisus.Debugging namespace.

    Rebuild Channel Class.png

    Yep, this should work without any issues! I gave it a quick test as well and everything looks to be good:

    moved under plugins.png

    Thank you, I'm very glad to hear this! :)
     
  5. Hakim59

    Hakim59

    Joined:
    Nov 14, 2020
    Posts:
    1
    Hello SisusCo

    Very great console, love it.
    Unfortunately I did not find how to resize font size, is there a way? and is it possible to Debug.Watch a variable? like display just 1 message iven if the variable is modificate?

    if you plan to spend time on it can you add the display of class in class with the command Debug.LogState(target)

    Have a good day
     
  6. SisusCo

    SisusCo

    Joined:
    Jan 29, 2019
    Posts:
    886
    @Hakim59 Awesome to hear you like it, thanks! :)

    Changing font size is not a feature that is currently supported. There is Compact Mode that helps more content fit on screen at the same time, but that's all that can be done at the moment.

    compact-mode.png

    Are you interested in increasing or lowering the font size? I could add in support for customizing it in a future version.


    Debug.LogChanges can be used to log a message to the console every time that the value of a variable changes, and Debug.DisplayOnScreen can be used to pin a variable on screen. There's no functionality to log a message only a single time when the value of a variable changes next. Do you have a use case in mind where logging a message only once would be especially useful?

    Printing out all nested member variables with Debug.LogState is an interested idea! I'll consider adding this in.
     
  7. Thygrrr

    Thygrrr

    Joined:
    Sep 23, 2013
    Posts:
    489
    Just bought the package, looked promising.

    Unfortunately...
    upload_2023-3-6_11-23-35.png

    ...the global namespace hack (how does that even work? sounds super useful!) doesn't play well with various official packages I am using in unity 2022.2 :)

    Interestingly, only a few of the packages are affected; URP itself, for instance, isn't, just ShaderGraph and Burst.

    Also, log messages in systems like this one don't get any stack traces, it would be great if they would:

    Code (CSharp):
    1. using Sisus.Debugging;
    2. using Unity.Collections;
    3. using Unity.Entities;
    4. using UnityEngine;
    5.  
    6. namespace Jovian.Systems
    7. {
    8.     [WorldSystemFilter(WorldSystemFilterFlags.BakingSystem)]
    9.     [UpdateInGroup(typeof(BakingSystemGroup), OrderLast = true)]
    10.     public partial class DebugBakingSystem : SystemBase
    11.     {
    12.         private EntityQuery _noSectionQuery;
    13.         protected override void OnCreate()
    14.         {
    15.             base.OnCreate();
    16.  
    17.             _noSectionQuery = GetEntityQuery(
    18.                 new EntityQueryDesc
    19.                 {
    20.                     None = new[] {ComponentType.ReadWrite<SceneSection>()},
    21.                     Options = EntityQueryOptions.IncludePrefab | EntityQueryOptions.IncludeDisabledEntities
    22.                 }
    23.             );
    24.  
    25.             RequireForUpdate(_noSectionQuery);
    26.         }
    27.         protected override void OnUpdate()
    28.         {
    29.             if (_noSectionQuery.IsEmpty)
    30.             {
    31.                 return;
    32.             }
    33.             var entities = _noSectionQuery.ToEntityArray(Allocator.TempJob);
    34.             foreach (var entity in entities)
    35.             {
    36.                 Dev.LogWarning($"{EntityManager.GetName(entity)} has no SceneSection!");
    37.             }
    38.             entities.Dispose();
    39.         }
    40.     }
    41. }

    There are also a couple of bugs with the Channel class, it can get out of sync with the list despite the rebuild having been triggered. This is particularly true if you remove your user channel.

    upload_2023-3-6_11-47-15.png

    If you come back later, chances are the settings menu has broken entirely, requiring a reinstall. I have a subtle suspicion this may or may not have something to do with Enter PlayMode Options.

    Edit: no, it seems to be an issue with asset naming during serialization:
    Code (csharp):
    1.  
    2. Main Object Name '' does not match filename 'DebugLogExtensionsProjectSettings'
    3. UnityEngine.StackTraceUtility:ExtractStackTrace ()
    4. Sisus.Debugging.DebugLogExtensionsProjectSettingsProvider:OnSettingChanged () (at Assets/Sisus/Debug.Log Extensions/Scripts/Editor/DebugLogExtensionsProjectSettingsProvider.cs:678)
    5. Sisus.Debugging.DebugLogExtensionsProjectSettingsProvider:DrawChannelsElement (UnityEngine.Rect,int,bool,bool) (at Assets/Sisus/Debug.Log Extensions/Scripts/Editor/DebugLogExtensionsProjectSettingsProvider.cs:520)
    6. UnityEditorInternal.ReorderableList:DoListElements (UnityEngine.Rect,UnityEngine.Rect)
    7. UnityEditorInternal.ReorderableList:DoLayoutList ()
    8. Sisus.Debugging.DebugLogExtensionsProjectSettingsProvider:DrawSettingsGUI () (at Assets/Sisus/Debug.Log Extensions/Scripts/Editor/DebugLogExtensionsProjectSettingsProvider.cs:292)
    9. Sisus.Debugging.DebugLogExtensionsProjectSettingsProvider:DrawSettingsGUI (string) (at Assets/Sisus/Debug.Log Extensions/Scripts/Editor/DebugLogExtensionsProjectSettingsProvider.cs:243)
    10. UnityEngine.GUIUtility:ProcessEvent (int,intptr,bool&)
    11.  
    Deleting your user channel will trigger this. I don't want the user channel, and I don't want my windows username to be serialized and committed to version cotnrol with ProjectSettings. (this section should go into UserSettings, and even there, I would like a choice to not have the per-user channel)

    There's also a bug with the names going out of sync; (meaning your channels will log as the wrong channels) I suggest using string.GetHashCode() to use a hashtable of unique channel numbers, instead of using indices from 0, and writing these hashcodes into the Channels class.
     
    Last edited: Mar 6, 2023
  8. SisusCo

    SisusCo

    Joined:
    Jan 29, 2019
    Posts:
    886
    The way it works is really simple: it relies on the fact that if there's a reference to a class named X, and there are multiple classes with the name X, then the compiler will prioritize options found within the same namespace chain with the class containing the reference.
    Code (CSharp):
    1. using UnityEngine; // Priority 3
    2.  
    3. namespace MyNamespace
    4. {
    5.     public class MyClass
    6.     {
    7.         public void MyMethod() => Debug.Log("It works ");
    8.     }
    9.  
    10.     public static class Debug // Priority 1
    11.     {
    12.         public static void Log(string message) => UnityEngine.Debug.Log(message + "like this.");
    13.     }
    14. }
    15.  
    16. public static class Debug // Priority 2
    17. {
    18.     public static void Log(string message) => UnityEngine.Debug.Log(message + "like this.");
    19. }
    20.  
    Since the global namespace is considered the topmost namespace in the namespace chain, all classes in all namespaces will prioritize a Debug class found in the global namespace over the one in the UnityEngine namespace - except for other classes in the UnityEngine namespace.

    Unfortunately:
    1. System.Diagnostics happens to also contain a class named Debug, which has lead to some adding the using alias
    using Debug = UnityEngine.Debug
    to their classes, to help the compiler understand that their Debug class references refer to the one in the UnityEngine namespace in particular.
    2. That particular using alias creates a conflict with a Debug class found in the global namespace.
    3. Since Debug.Log Extensions was initially released, more and more unity packages have been introduced that contain that using alias.

    The end result is that automatically redirecting all Debug.Log calls globally to Debug.Log Extensions' enhanced variants won't be a viable option in most projects today. Not unless you go to the lengths of copying the conflicting packages under the Assets folder, doing a search and replace to remove all the "using Debug = UnityEngine.Debug" references, and then removing the packages from the package manager :confused:

    I'll take a look at this - thanks for letting me know!

    You should be able to turn off the automatic dev personal channel blacklisting in the Project Settings > Debug.Log Extensions.
    Dev.ChannelName.png

    The idea behind the feature is that when working as part of a small team, it could be useful to be able to do some logging that will be very helpful for you to see, but would be probably too spammy for your other team members. By tagging your logging with your personal channel name, the logged messages would only be visible for you by default.
    Code (CSharp):
    1. Dev.Log(Channel.AudioGuy89, Channel.Audio, $"Playing {audioId} in {delay} seconds.", this);
    Code (CSharp):
    1. Dev.Log(Channel.LeetProgrammerGal, Channel.AI, $"AI switching from state {currentState} to {newState}.", this);
    I'll investigate the issues you ran into while trying to delete your dev channel. It looks like something went wrong there when trying to save your Project Settings to disk.

    Your string.GetHashCode suggestion is an interesting idea, but unfortunately GetHashCode results are not guaranteed to be unique, so I couldn't use it as a simple plug-in replacement :( I could use a HashSet<string>, but that would mostly defeat the purpose of the Channel class: avoiding having to perform any string comparisons.
     
    Last edited: Mar 7, 2023
  9. Thygrrr

    Thygrrr

    Joined:
    Sep 23, 2013
    Posts:
    489
    Thank you for the detailed reply.

    Regarding hashes - just roll your own. :)

    Code (CSharp):
    1.  public static int GetStableHashCode(this string str)
    2.         {
    3.             unchecked
    4.             {
    5.                 var hash1 = 5381;
    6.                 var hash2 = hash1;
    7.  
    8.                 for (var i = 0; i < str.Length && str[i] != '\0'; i += 2)
    9.                 {
    10.                     hash1 = ((hash1 << 5) + hash1) ^ str[i];
    11.                     if (i == str.Length - 1 || str[i + 1] == '\0')
    12.                         break;
    13.                     hash2 = ((hash2 << 5) + hash2) ^ str[i + 1];
    14.                 }
    15.  
    16.                 return hash1 + (hash2 * 1566083941);
    17.             }
    18.         }
     
  10. SisusCo

    SisusCo

    Joined:
    Jan 29, 2019
    Posts:
    886
    Even if a hash code is stable it does not guarantee it to be unique for all possible values a string can have.

    For example, only 31 flags can be encoded into an integer bit field before hitting int.MaxValue, and in this case each flag can only have two different values. In a string each character can have ~60 000 different values, so hash collisions are unavoidable.
     
  11. sampenguin

    sampenguin

    Joined:
    Feb 1, 2011
    Posts:
    28
    Love this asset, been using it for some time now. However I'm currently having a problem on iOS and Android devices with Debug.LogIf(), where if the condition is true it still doesn't output to the console. Debug.Log() works fine however.

    Any ideas what could be causing that? I can verify the condition I'm testing against is definitely true on the device.

    UPDATE: same problem on Android.

    I should probably also add that I'm displaying the console in my game via the very nice SRDebugger from the Unity asset store.

    UPDATE 2: Looking at the decompiled code, it looks like there is a
    [Conditional("DEBUG")]
    attribute just above the LogIf methods, which is NOT there on the normal Log calls.

    My "strip log calls from builds" is set to false.

    Up to now, I've been using Dev.* when it's output I don't want to leave the dev environment or for development builds, but I still want the ability to branch on more detailed Debug output in release builds if a problem is encountered, e.g. bugs which can only repro on device.
     
    Last edited: Mar 15, 2023
  12. SisusCo

    SisusCo

    Joined:
    Jan 29, 2019
    Posts:
    886
    @sampenguin Thank you for reporting this!

    Yeah, it looks like those conditional Conditional attributes are indeed the culprit. They should only be on methods in the Dev class unless strip log calls from builds is enabled. I'll fix this in the next update.
     
  13. SisusCo

    SisusCo

    Joined:
    Jan 29, 2019
    Posts:
    886
    @sampenguin I've submitted a fix for the LogIf issue to the asset store - and also sent you the fixed package in a PM.
     
  14. sampenguin

    sampenguin

    Joined:
    Feb 1, 2011
    Posts:
    28
    Thanks so much!! I just tried it out and good news, bad news (results from Android only so far):

    Bad news: Still shows same behavior in release builds on device. (Debug.LogIf does NOT output)
    Good news: Development builds now work. (Debug.LogIf DOES output)

    Ideally, Debug.LogIf would still work in release builds, but at least for now I have a way to see more extended output.

    Side note: As a thanks for the speedy reply, I just bought all your other assets. :)
    Thanks for all the good stuff you've put out!
     
  15. SisusCo

    SisusCo

    Joined:
    Jan 29, 2019
    Posts:
    886
    Hmm, okay I'll take investigate what could be the reason for this.

    And just to make sure: you still don't have the 'Strip Log Calls From Builds' option enabled, right?

    You rock - thanks a bunch :) I hope you find them very useful!
     
  16. SisusCo

    SisusCo

    Joined:
    Jan 29, 2019
    Posts:
    886
    @sampenguin I found the issue: there was a second set of preprocessor directives that had to be updated, in addition to the ConditionalAttribute, for the code to be executed in release builds. This should be fixed in the new version.
     
    sampenguin likes this.
  17. SisusCo

    SisusCo

    Joined:
    Jan 29, 2019
    Posts:
    886
    I've now figured out a way to make it possible to reroute all classes to use my enhanced Debug class, but only on specifically hand-picked assemblies.

    In the latest version, I'm tweaking the DLL structure so that the DLLs for different platforms all share the same name.

    Then I've went ahead and disabled the Auto Reference option for the DLLs in the global namespace. This will prevent compile errors from occurring from within package manager packages.

    auto-reference-disabled.png


    Now to change all classes in a particular assembly to use the enhanced Debug class, one just needs to:
    1. Create an Assembly Definition Asset at the folder root, if one doesn't exist already.
    2. Check Override References.
    3. Add Debug-Log-Extensions.dll to the Assembly References list.
    override-references.png


    With this, all classes in the assembly should switch to using the enhanced Debug class without there being any need to manually specify using Debug = Sisus.Debugging.Debug.

    result.png

    I've changed the Channel class from using const fields to static readonly fields in the latest version. Using constants was likely the reason for the channel members mapping to incorrect values when referenced from external assemblies.

    In my testing Console+ was able to properly parse and display stack traces from systems. Could you maybe share the stack trace that wasn't being displayed from the built-in Console?
     
  18. Thygrrr

    Thygrrr

    Joined:
    Sep 23, 2013
    Posts:
    489
    What was the literal message and its entire (nonexistent?) stack trace.
     
  19. SisusCo

    SisusCo

    Joined:
    Jan 29, 2019
    Posts:
    886
    @Thygrrr Right, I get what you mean now; they are missing stack traces when using UnityEngine.Debug.Log as well when the logging takes place in a background thread. I can do some investigating to see if it's something I could remedy. Would you be most interested in getting this information in the editor or in builds?
     
    Last edited: Mar 18, 2023 at 6:40 AM
  20. Thygrrr

    Thygrrr

    Joined:
    Sep 23, 2013
    Posts:
    489
    Editor, always Editor. :)
    But don't prioritize it, I'd rather see the basic logging stuff a little more stabilized (and the Context Object feature added to as many of the log overloads as feasible)
     
    SisusCo likes this.