一、日志工具功能
封裝Debug類,需要實現功能:
1.控制所有日志是否打印;
2.除了Log,Warning,Error外,給更多日志種類(不同顏色);
3.格式化打印日志;
4.不定參數,自動拼接成字符串;
5.上傳日志到服務器;
二、Logger類
1.控制日志打印
封裝Debug中關於Log的方法;
使用靜態方法,聲明靜態字段,控制log,warning,error是否打印;
Debug源碼中Log方法有兩個重載;
第二個參數context可以傳參GameObject,Hierarchy或者Project窗口中的預制體,雙擊Console日志會直接跳轉選中傳入的游戲物體;
我們可以將這個方法合並,第二個參數默認空;
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");
}