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.
  2. Dismiss Notice

Question Can I format log entries?

Discussion in 'Scripting' started by Ozgekocaoglu, Feb 6, 2023.

  1. Ozgekocaoglu

    Ozgekocaoglu

    Joined:
    Feb 13, 2019
    Posts:
    38
    Hello everyone,
    I'm coding a custom console.
    Log Handler was not catches syntax error so i coded a class that uses reflection to wrap LogEntries class at Unity sources. I've simply copied the Unity console.

    Code (CSharp):
    1.   // -------------------------------------------------------------------------
    2.   public static CustomLog getEntryInternal(int row)
    3.   {
    4.     var logEntryType = Assembly.GetAssembly(typeof(SceneView)).GetType("UnityEditor.LogEntry");
    5.     var logEntryTemp = Activator.CreateInstance(logEntryType);
    6.  
    7.     object[] parameters = new object[] {row, logEntryTemp};
    8.     var getEntries = logEntries.GetMethod("GetEntryInternal");
    9.     getEntries.Invoke(null, parameters);
    10.  
    11.     FieldInfo messageField = logEntryType.GetField("message", BindingFlags.Instance | BindingFlags.Public);
    12.     string message = (string) messageField.GetValue(logEntryTemp);
    13.  
    14.     FieldInfo fileField = logEntryType.GetField("file", BindingFlags.Instance | BindingFlags.Public);
    15.     string file = (string) fileField.GetValue(logEntryTemp);
    16.  
    17.     FieldInfo modeField = logEntryType.GetField("mode", BindingFlags.Instance | BindingFlags.Public);
    18.     int mode = (int) modeField.GetValue(logEntryTemp);
    19.  
    20.     FieldInfo instanceIDField = logEntryType.GetField("instanceID", BindingFlags.Instance | BindingFlags.Public);
    21.     int instanceID = (int) instanceIDField.GetValue(logEntryTemp);
    22.    
    23.     FieldInfo globalLineIndexField = logEntryType.GetField("globalLineIndex", BindingFlags.Instance | BindingFlags.Public);
    24.     int globalLineIndex = (int) globalLineIndexField.GetValue(logEntryTemp);
    25.  
    26.     CustomLog log = new CustomLog(message, file, mode, instanceID, globalLineIndex, DateTime.Now.ToLongTimeString());
    27.  
    28.     return log;
    29.   }
    But i have a problem. I wanna manipulate logs and send to unity logger because i dont wanna keep additional log file and i wanna format my log files as json. Could it possible to do that?

    I've saw this method at the LogEntries class but i'm not sure how it works.

    Code (CSharp):
    1. [ThreadSafe]
    2.         public extern static unsafe void AddMessagesImpl(void* messagesBuffer, int messagesBufferLength);
    Do you have any ideas?
     
  2. Bunny83

    Bunny83

    Joined:
    Oct 18, 2010
    Posts:
    3,524
    I'm not sure what exactly you want to achieve, however you may want to have a look at the ILogHandler example.
    I'm not sure if internally raised log messages actually go through it or not. Though I would assume they do.
     
  3. Ozgekocaoglu

    Ozgekocaoglu

    Joined:
    Feb 13, 2019
    Posts:
    38
    Hi don't want to keep extra log file, I've already checked this class but not that i want it.
     
  4. SF_FrankvHoof

    SF_FrankvHoof

    Joined:
    Apr 1, 2022
    Posts:
    780
    A custom ILogHandler should override the Unity ILogHandler. You can then print, write, etc. to wherever you want.
     
  5. Bunny83

    Bunny83

    Joined:
    Oct 18, 2010
    Posts:
    3,524
    Exactly.
    Haven't you seen this line in the code:
    Code (CSharp):
    1. m_DefaultLogHandler.LogFormat(logType, context, format, args);
    Here they just funnel the message unaltered to the default handler. That's where you can most likely change whatever should be logged. It seems you focused too much on that "extra log file". You should understand what that interface allows you to do.
     
  6. Ozgekocaoglu

    Ozgekocaoglu

    Joined:
    Feb 13, 2019
    Posts:
    38
    Guys alright don't come on me.
    I've tried for you again, probably i could not explain what i want to.

    This is my logger class:

    Code (CSharp):
    1. // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    2. public class Logger : ILogHandler
    3. {
    4.     public static Logger instance = null;
    5.     ILogHandler defaultLogHandler = Debug.unityLogger.logHandler;
    6.     FileStream fileStream;
    7.     StreamWriter streamWriter;
    8.     static string filePath = Application.persistentDataPath + "/PlayerLogs.txt";
    9.  
    10.   // -------------------------------------------------------------------------
    11.   public Logger()
    12.   {
    13.     fileStream = new FileStream(filePath, FileMode.OpenOrCreate, FileAccess.ReadWrite);
    14.     streamWriter = new StreamWriter(fileStream);
    15.     Debug.unityLogger.logHandler = this;
    16.   }
    17.  
    18.   // -------------------------------------------------------------------------
    19.   public void LogFormat(LogType logType, UnityEngine.Object context, string format, params object[] args)
    20.   {
    21.     streamWriter.WriteLine(String.Format(format, args));
    22.     streamWriter.Flush();
    23.     defaultLogHandler.LogFormat(logType, context, format, args);
    24.   }
    25.  
    26.   // -------------------------------------------------------------------------
    27.   public void LogException(Exception exception, UnityEngine.Object context)
    28.   {
    29.     defaultLogHandler.LogException(exception, context);
    30.   }
    31.  
    32.   // -------------------------------------------------------------------------
    33.   /// <summary>
    34.   /// Init function.
    35.   /// </summary>
    36.   [EditorUtils.OnEditorLaunchBeforeInitialized]
    37.   static void init()
    38.   {
    39.     if (instance.isNull()) {
    40.       instance = new Logger();
    41.     }
    42.   }
    43.  
    44.  
    45. }
    And my test class:

    Code (CSharp):
    1. // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    2. public class ConsoleLogTest : MonoBehaviour
    3. {
    4.  
    5.   // -------------------------------------------------------------------------
    6.   void Awake()
    7.   {
    8.     Debug.unityLogger.LogFormat(LogType.Log, "Test");
    9.   }
    10. }
    Logger creates file and print the logs inside my console window as you can see.

    upload_2023-2-8_12-12-8.png

    But my ''PlayerLogs.txt'' file is empty. Do you have any idea, why would it be?
     

    Attached Files:

  7. SF_FrankvHoof

    SF_FrankvHoof

    Joined:
    Apr 1, 2022
    Posts:
    780
    My first guess would be the call to
    Debug.unityLogger.LogFormat()
    instead of the normal
    Debug.LogFormat()
    .
    Second guess would be that your ILogger is somehow not initializing?
    Have you tried replacing
    defaultLogHandler.LogFormat(logType, context, format, args);
    with a simple output of "Hey this is working" to see if it actually goes through that method?
     
    Ozgekocaoglu likes this.
  8. tleylan

    tleylan

    Joined:
    Jun 17, 2020
    Posts:
    523
    I'm not going to be of help with your issue but I figured I would add my 2 cents...

    This seems like a lot of typing for little gain.
    Code (CSharp):
    1. Debug.unityLogger.LogFormat(LogType.Log, "Test");
    I've written a level-based logger that I am very happy with. It formats the output (with colors) and it can log to special locations i.e. a rest client so log messages can be gathered during multiplayer testing.

    An event handler log for instance would look as follows:
    Code (CSharp):
    1. Logger.Debug($"event={photonEvent.Code}");
    This would only output if the setting was Debug or higher. It has a .Any method which logs regardless of the level set. The level can be changed dynamically and there is a .Assert method which only logs if a condition is met.

    It doesn't write to the Unity log but I assume I could add that as an option. Personally I would avoid using Reflection but that's me.
     
  9. Ozgekocaoglu

    Ozgekocaoglu

    Joined:
    Feb 13, 2019
    Posts:
    38
    I've figure out what happened. Now my logs are json. Thank you guys.