Unity—日志打印工具


一、日志工具功能

封裝Debug類,需要實現功能:

1.控制所有日志是否打印;

2.除了Log,Warning,Error外,給更多日志種類(不同顏色);

3.格式化打印日志;

4.不定參數,自動拼接成字符串;

5.上傳日志到服務器;

二、Logger類

1.控制日志打印

封裝Debug中關於Log的方法;

使用靜態方法,聲明靜態字段,控制log,warning,error是否打印;

image-20220128214145257

Debug源碼中Log方法有兩個重載;

image-20220128212705287

第二個參數context可以傳參GameObject,Hierarchy或者Project窗口中的預制體,雙擊Console日志會直接跳轉選中傳入的游戲物體;

我們可以將這個方法合並,第二個參數默認空;

image-20220128214208934

2.色彩打印

打印不同顏色使用富文本

string.Format("<color={0}>{1}</color>",color,obj);
3.多參數拼接

之前使用Go語言的fmt.Println有個功能很好用,連續傳多個參數自動拼接;

public static void Log(params object[] messags)
{
    if (!s_debugLogEnable) return;

    string message = string.Empty;
    foreach (var it in messags)
    {
        message += it.ToString();
    }

    Debug.Log(message, null);
}

//調用
Logger.Log("Net error:",error,"msgId:",msgId);
4.格式化打印

格式化打印封裝原本Debug.LogFormat方法;

public static void LogFormat(string format, params object[] args)
{
    if (!s_debugLogEnable) return;
    Debug.LogFormat(format, args);
}

三、LoggerMgr類

繼承MonoBehavior的單例;

初始化Logger中的三個控制打印的字段;

Application類中有收到日志消息觸發的事件LogMessageReceived;

監聽這個事件;如果日志開關為關閉狀態return;

if (isOpenLog)
{
    Logger.s_debugLogEnable = true;
    Logger.s_warningLogEnable = true;
    Logger.s_errorLogEnable = true;          
}

Application.logMessageReceived += (string condition, string stackTrace, LogType type) =>
{
    switch (type)
    {
        case LogType.Log:
            {
                if (!Logger.s_debugLogEnable) return;
            }
            break;
        case LogType.Warning:
            {
                if (!Logger.s_warningLogEnable) return;
            }
            break;
        case LogType.Error:
            {
                if (!Logger.s_errorLogEnable) return;
            }
            break;
    }
};

四、上傳日志

LoggerMgr中初始化上傳日志信息;

方法寫在logger中,在LoggerMgr開始調用;

public static void Init(string url)
{
    LogUploader.SetUploadUrl(url);
    // 日期
    var t = System.DateTime.Now.ToString("yyyyMMddhhmmss");
    s_logFileSavePath = string.Format("{0}/output_{1}.log", Application.persistentDataPath, t);
    Application.logMessageReceived += OnLogCallBack;
}

OnLogCallBack方法中將日志和棧信息存儲成文件,等待上傳;

private static void OnLogCallBack(string condition, string stackTrace, LogType type)
{
    s_logStr.Append(condition);
    s_logStr.Append("\n");
    s_logStr.Append(stackTrace);
    s_logStr.Append("\n");

    if (s_logStr.Length <= 0) return;
    if (!File.Exists(s_logFileSavePath))
    {
        var fs = File.Create(s_logFileSavePath);
        fs.Close();
    }
    using (var sw = File.AppendText(s_logFileSavePath))
    {
        sw.WriteLine(s_logStr.ToString());
    }
    s_logStr.Remove(0, s_logStr.Length);
}

LogUploader類

開啟協程上傳日志文件;

public static void StartUploadLog(string logFilePath, string desc)
{
    if (LOG_UPLOAD_URL == string.Empty)
        return;

    var go = new GameObject("LogUploader");
    var bhv = go.AddComponent<LogUploader>();
    bhv.StartCoroutine(bhv.UploadLog(logFilePath, LOG_UPLOAD_URL, desc));
}

在Logger類中同樣封裝上面的方法,所有的日志都通過Logger打印;

public static void UploadLog(string desc)
{
    LogUploader.StartUploadLog(s_logFileSavePath, desc);
}

五、日志雙擊溯源問題

以上的代碼有個很大的問題,現在我們雙擊不會回到調用Logger的地方,只會跳轉到Logger類中調用Debug.Log的地方;

有個很簡單的辦法解決,將上面代碼編譯成dll;

另外查找源碼也可以自己決定掉轉位置;

具體方法,通過反射獲日志取棧信息,根據Logger類返回的棧信息路徑,篩選出要跳轉的位置;

通過官方提供的方法跳轉到相應位置;

UnityEditorInternal.InternalEditorUtility.OpenFileAtLineExternal(string filename, int line);

六、調用

void Start()
{
    Logger.Log("aaaa");
    Logger.LogFormat("{0}===={1}",111,0.232);
    Logger.LogGreen("bbbb");
    Logger.LogError("log error");
    Logger.Log("aa", 13, "fff",16,"sfddf",64654);
    Logger.UploadLog("NetWork LogTest");
}

image-20220128223127707

工具類下載


免責聲明!

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



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