一、日誌工具功能
封裝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");
}