【Unity】通用的Debugger日志模塊


模塊代碼整理自 http://gad.qq.com/lore/catalog/10007

Debugger類。提供打印日志的靜態方法。

using System;
using System.IO;

namespace UnityEngine
{
    /// <summary>
    /// 系統日志模塊
    /// </summary>
    public class Debugger
    {
        public static bool EnableLog;           // 是否啟用日志,僅可控制普通級別的日志的啟用與關閉,LogError和LogWarn都是始終啟用的。
        public static bool EnableTime = true;
        public static bool EnableSave = false;  // 是否允許保存日志,即把日志寫入到文件中
        public static bool EnableStack = false;
        public static string LogFileDir = Application.persistentDataPath + "/DebuggerLog/";
        public static string LogFileName = "";
        public static string Prefix = "> ";     // 用於與Unity默認的系統日志做區分。本日志系統輸出的日志頭部都會帶上這個標記。
        public static StreamWriter LogFileWriter = null;
        public static bool UseUnityEngine;

        private static string GetLogText(string tag, string message)
        {
            string str = "";
            if (EnableTime)
            {
                str = DateTime.Now.ToString("HH:mm:ss.fff") + " ";
            }
            return (str + tag + "::" + message);
        }

        private static string GetLogTime()
        {
            string str = "";
            if (EnableTime)
            {
                str = DateTime.Now.ToString("HH:mm:ss.fff") + " ";
            }
            return str;
        }

        public static void Log(object message)
        {
            if (!Debugger.EnableLog)
                return;

            string str = GetLogTime() + message;
            Debug.Log(Prefix + str, null);
            LogToFile("[I]" + str, false);
        }

        public static void Log(object message, Object context)
        {
            if (!Debugger.EnableLog)
                return;

            string str = GetLogTime() + message;
            Debug.Log(Prefix + str, context);
            LogToFile("[I]" + str, false);
        }

        public static void Log(string tag, string message)
        {
            if (!Debugger.EnableLog)
                return;

            message = GetLogText(tag, message);
            Debug.Log(Prefix + message, null);
            LogToFile("[I]" + message, false);
        }

        public static void Log(string tag, string format, params object[] args)
        {
            if (!Debugger.EnableLog)
                return;

            string logText = GetLogText(tag, string.Format(format, args));
            Debug.Log(Prefix + logText, null);
            LogToFile("[I]" + logText, false);
        }

        public static void LogError(object message)
        {
            string str = GetLogTime() + message;
            Debug.Log(Prefix + str, null);
            LogToFile("[E]" + str, true);
        }

        public static void LogError(object message, Object context)
        {
            string str = GetLogTime() + message;
            Debug.Log(Prefix + str, context);
            LogToFile("[E]" + str, true);
        }

        public static void LogError(string tag, string message)
        {
            message = GetLogText(tag, message);
            Debug.Log(Prefix + message, null);
            LogToFile("[E]" + message, true);
        }

        public static void LogError(string tag, string format, params object[] args)
        {
            string logText = GetLogText(tag, string.Format(format, args));
            Debug.Log(Prefix + logText, null);
            LogToFile("[E]" + logText, true);
        }

        /// <summary>
        /// 將日志寫入到文件中
        /// </summary>
        /// <param name="message"></param>
        /// <param name="EnableStack"></param>
        private static void LogToFile(string message, bool EnableStack = false)
        {
            if (!Debugger.EnableSave)
                return;

            if (LogFileWriter == null)
            {
                LogFileName = DateTime.Now.GetDateTimeFormats('s')[0].ToString();
                LogFileName = LogFileName.Replace("-", "_");
                LogFileName = LogFileName.Replace(":", "_");
                LogFileName = LogFileName.Replace(" ", "");
                LogFileName = LogFileName + ".log";
                if (string.IsNullOrEmpty(LogFileDir))
                {
                    try
                    {
                        if (UseUnityEngine)
                        {
                            LogFileDir = Application.persistentDataPath + "/DebuggerLog/";
                        }
                        else
                        {
                            LogFileDir = AppDomain.CurrentDomain.BaseDirectory + "/DebuggerLog/";
                        }
                    }
                    catch (Exception exception)
                    {
                        Debug.Log(Prefix + "獲取 Application.persistentDataPath 報錯!" + exception.Message, null);
                        return;
                    }
                }
                string path = LogFileDir + LogFileName;
                try
                {
                    if (!Directory.Exists(LogFileDir))
                    {
                        Directory.CreateDirectory(LogFileDir);
                    }
                    LogFileWriter = File.AppendText(path);
                    LogFileWriter.AutoFlush = true;
                }
                catch (Exception exception2)
                {
                    LogFileWriter = null;
                    Debug.Log("LogToCache() " + exception2.Message + exception2.StackTrace, null);
                    return;
                }
            }
            if (LogFileWriter != null)
            {
                try
                {
                    LogFileWriter.WriteLine(message);
                    if ((EnableStack || Debugger.EnableStack) && UseUnityEngine)
                    {
                        LogFileWriter.WriteLine(StackTraceUtility.ExtractStackTrace());
                    }
                }
                catch (Exception)
                {
                }
            }
        }

        public static void LogWarning(object message)
        {
            string str = GetLogTime() + message;
            Debug.Log(Prefix + str, null);
            LogToFile("[W]" + str, false);
        }

        public static void LogWarning(object message, Object context)
        {
            string str = GetLogTime() + message;
            Debug.Log(Prefix + str, context);
            LogToFile("[W]" + str, false);
        }

        public static void LogWarning(string tag, string message)
        {
            message = GetLogText(tag, message);
            Debug.Log(Prefix + message, null);
            LogToFile("[W]" + message, false);
        }

        public static void LogWarning(string tag, string format, params object[] args)
        {
            string logText = GetLogText(tag, string.Format(format, args));
            Debug.Log(Prefix + logText, null);
            LogToFile("[W]" + logText, false);
        }

    }
}

DebuggerExtension類。采用C#的擴展方法特性,使所有System.Object子類獲得了打印日志的函數功能。

using System.Diagnostics;
using System.Reflection;
using UnityEngine;

namespace UnityEngine
{
    /// <summary>
    /// 日志模塊的擴展類
    /// </summary>
    public static class DebuggerExtension
    {
        /// <summary>
        /// LogTag是調用打印日志的類中自定義的常量字符串,通常情況下LogTag是類名。
        /// 用LogTag可以直觀地看出這條日志是哪個類輸出的。
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        private static string GetLogTag(object obj)
        {
            FieldInfo field = obj.GetType().GetField("LOG_TAG");
            if (field != null)
            {
                return (string)field.GetValue(obj);
            }
            return obj.GetType().Name;
        }

        [Conditional("EnableLog")]
        public static void Log(this object obj, string message)
        {
            if (Debugger.EnableLog)
            {
                Debugger.Log(GetLogTag(obj), message);
            }
        }

        [Conditional("EnableLog")]
        public static void Log(this object obj, string format, params object[] args)
        {
            if (Debugger.EnableLog)
            {
                string message = string.Format(format, args);
                Debugger.Log(GetLogTag(obj), message);
            }
        }

        public static void LogError(this object obj, string message)
        {
            Debugger.LogError(GetLogTag(obj), message);
        }

        public static void LogError(this object obj, string format, params object[] args)
        {
            string message = string.Format(format, args);
            Debugger.LogError(GetLogTag(obj), message);
        }

        public static void LogWarning(this object obj, string message)
        {
            Debugger.LogWarning(GetLogTag(obj), message);
        }

        public static void LogWarning(this object obj, string format, params object[] args)
        {
            string message = string.Format(format, args);
            Debugger.LogWarning(GetLogTag(obj), message);
        }

    }
}

Example測試日志模塊。

using UnityEngine;

public class Example_Debugger : MonoBehaviour
{
    void Start()
    {
        Debug.Log("這是Unity默認的日志!");

        Debugger.EnableLog = true;
        Debugger.EnableTime = true;

        Debugger.Log("Debugger.Log");
        Debugger.LogWarning("Debugger.LogWarning");
        Debugger.LogError("Debugger.LogError");

        Debugger.Log("Example_Debugger", "格式化日志: {0}", 123456);
        Debugger.Log("日志保存路徑:", Debugger.LogFileDir);

        this.Log("日志擴展類中的方法。該方法需要在Unity編輯器中添加宏命令EnableLog才能被編譯!");
    }

}

運行效果:

注意,DebuggerExtension類采用了[Conditional]特性條件編譯,被[Conditional]標記的函數需要在Unity編輯器中開啟命令宏才能被編譯,參考這里

建議將Debugger類和DebuggerExtension類都編譯到Debugger.dll中,再放入Unity工程Asset目錄下使用。因為如果將Debuger類放到主工程里,在Unity的日志輸出窗口Console中點擊日志,會跳轉到Debuger類中的代碼,而我們真正想要跳轉到的是調用了Debuger的地方。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM