日志工具功能 封装Debug类,需要实现功能:
1.控制所有日志是否打印;
2.除了Log,Warning,Error外,给更多日志种类(不同颜色);
3.格式化打印日志;
4.不定参数,自动拼接成字符串;
5.上传日志到服务器;
Logger类 控制日志打印 封装Debug中关于Log的方法;
使用静态方法,声明静态字段,控制log,warning,error是否打印;
Debug源码中Log方法有两个重载;
第二个参数context可以传参GameObject,Hierarchy或者Project窗口中的预制体,双击Console日志会直接跳转选中传入的游戏物体;
我们可以将这个方法合并,第二个参数默认空;
色彩打印 打印不同颜色使用富文本 ;
1 string .Format("<color={0}>{1}</color>" ,color,obj);
多参数拼接 之前使用Go语言的fmt.Println有个功能很好用,连续传多个参数自动拼接;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 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);
格式化打印 格式化打印封装原本Debug.LogFormat方法;
1 2 3 4 5 public static void LogFormat (string format, params object [] args ){ if (!s_debugLogEnable) return ; Debug.LogFormat(format, args); }
LoggerMgr类 继承MonoBehavior的单例;
初始化Logger中的三个控制打印的字段;
Application类中有收到日志消息触发的事件LogMessageReceived;
监听这个事件;如果日志开关为关闭状态return;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 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开始调用;
1 2 3 4 5 6 7 8 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方法中将日志和栈信息存储成文件,等待上传;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 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类
开启协程上传日志文件;
1 2 3 4 5 6 7 8 9 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打印;
1 2 3 4 public static void UploadLog (string desc ){ LogUploader.StartUploadLog(s_logFileSavePath, desc); }
日志双击溯源问题 以上的代码有个很大的问题,现在我们双击不会回到调用Logger的地方,只会跳转到Logger类中调用Debug.Log的地方;
有个很简单的办法解决,将上面代码编译成dll;
另外查找源码也可以自己决定掉转位置;
具体方法,通过反射获日志取栈信息,根据Logger类返回的栈信息路径,筛选出要跳转的位置;
通过官方提供的方法跳转到相应位置;
1 UnityEditorInternal.InternalEditorUtility.OpenFileAtLineExternal(string filename, int line);
调用 1 2 3 4 5 6 7 8 9 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" ); }
工具类下载