[Unity] 自定义日志系统 解决Unity Log的痛点

编程入门 行业动态 更新时间:2024-10-24 05:24:16

[Unity] <a href=https://www.elefans.com/category/jswz/34/1771438.html style=自定义日志系统 解决Unity Log的痛点"/>

[Unity] 自定义日志系统 解决Unity Log的痛点

当前Unity日志存在的问题:

1.日志打印没有时间

2.日志文件中Log、Warning、和Error区分度不大

3.长时间没有清理容易产生动辄几十MB,几十万行的日志文件

本日志系统区别于Unity原生Log主要有以下几点:

1.日志打印添加时间戳

2.普通打印可忽略堆栈信息

3.每次启动生成一份日志文件

4.日志文件包含设备信息

5.关闭Log可自定义关闭内容,关闭Log默认情况下仅屏蔽普通打印,不屏蔽Warning和Error

6.关闭Log情况下出现Error自动打印前20条Log方便跟踪报错

效果展示:

使用方式:

需要在程序初始化时调用初始化日志系统,以便日志系统捕获系统报错

Editor:

日志文件:

源码:

using System;
using System.Collections.Generic;
using System.IO;
using UnityEngine;namespace AuthorZhidai
{public class Log{private const int LOG_COUNT = 20;// 最多临时保存LOG_COUNT条日志private const int LOG_FILE_COUNT = 10;// 最多保存的日志文件数public static bool EnableLog = true;// 是否启用日志,仅可控制普通级别的日志的启用与关闭,LogError和LogWarn都是始终启用的。public static bool EnableSave = true;// 是否允许保存日志,即把日志写入到文件中public static string LogFileDir = Application.dataPath.Replace("Assets", "") + "Log";// 日志存放目录:和Assets同级目录下的Logpublic static string LogFileName = "";public static string Prefix = "> ";// 用于与Unity默认的系统日志做区分。本日志系统输出的日志头部都会带上这个标记。public static StreamWriter LogFileWriter = null;//日志列表,忽略Info时报错回溯使用public static List<string> ListLogs = new List<string>();//第一次执行打印logprivate static bool FirstLogTag = true;public static void Init(){Application.logMessageReceived += OnLogByUnity;}#region 日志public static void Info(object message, bool recordStackTrace = false){string str = "[I]" + GetLogTime() + message;AddListLogs(str);if (!EnableLog)return;Debug.Log(Prefix + str, null);LogToFile(str, recordStackTrace);}public static void Warning(object message){string str = "[W]" + GetLogTime() + message;AddListLogs(str);Debug.LogWarning(Prefix + str, null);LogToFile(str, true);}public static void Error(object message){string str = "[E]" + GetLogTime() + message;Debug.LogError(Prefix + str, null);if (!EnableLog){OutputListLogs(LogFileWriter);// 忽略Info时报错,自动将日志记录到文件中方便回溯}else{AddListLogs(str);}LogToFile(str, true);}/// <summary>/// 输出列表中所有日志/// 可能会造成卡顿,谨慎使用。/// </summary>/// <param name="sw"></param>public static void OutputListLogs(StreamWriter sw){if (sw == null || ListLogs.Count < 1)return;sw.WriteLine($"---------------- Log History Start [以下是报错前{ListLogs.Count}条日志]---------------- ");foreach (var i in ListLogs){sw.WriteLine(i);}sw.WriteLine($"---------------- Log History  End  [以上是报错前{ListLogs.Count}条日志]---------------- ");ListLogs.Clear();}#endregionpublic static void CloseLog(){if (LogFileWriter != null){try{LogFileWriter.Flush();LogFileWriter.Close();LogFileWriter.Dispose();LogFileWriter = null;}catch (Exception){}}}public static void CheckClearLog(){if (!Directory.Exists(LogFileDir)){return;}DirectoryInfo direction = new DirectoryInfo(LogFileDir);var files = direction.GetFiles("*");if (files.Length >= LOG_FILE_COUNT){var oldfile = files[0];var lastestTime = files[0].CreationTime;foreach (var file in files){if (lastestTime > file.CreationTime){oldfile = file;lastestTime = file.CreationTime;}}oldfile.Delete();}}private static void OnLogByUnity(string condition, string stackTrace, LogType type){// 过滤自己的输出if (type == LogType.Log || condition.StartsWith(Prefix)){return;}var str = type == LogType.Warning ? "[W]" : "[E]" + GetLogTime() + condition + "\n" + stackTrace;if (!EnableLog && type != LogType.Warning)OutputListLogs(LogFileWriter);// 忽略Info时报错,自动将日志记录到文件中方便回溯elseAddListLogs(str);LogToFile(str);}private static void AddListLogs(string str){if (ListLogs.Count > LOG_COUNT){ListLogs.RemoveAt(0);}ListLogs.Add(str);}private static string GetLogTime(){string str = "";str = DateTime.Now.ToString("HH:mm:ss.fff") + " ";return str;}/// <summary>/// 将日志写入到文件中/// </summary>/// <param name="message"></param>/// <param name="EnableStack"></param>private static void LogToFile(string message, bool EnableStack = false){if (!EnableSave)return;if (LogFileWriter == null){CheckClearLog();LogFileName = DateTime.Now.GetDateTimeFormats('s')[0].ToString();LogFileName = LogFileName.Replace("-", "_");LogFileName = LogFileName.Replace(":", "_");LogFileName = LogFileName.Replace(" ", "");LogFileName = LogFileName.Replace("T", "_");LogFileName = LogFileName + ".log";if (string.IsNullOrEmpty(LogFileDir)){try{if (!Directory.Exists(LogFileDir)){Directory.CreateDirectory(LogFileDir);}}catch (Exception exception){Debug.Log(Prefix + "获取 Application.streamingAssetsPath 报错!" + exception.Message, null);return;}}string path = LogFileDir + "/" + LogFileName;Debug.Log("Log Path :" + LogFileDir + "\nLog Name :" + 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{if (FirstLogTag){FirstLogTag = false;PhoneSystemInfo(LogFileWriter);}LogFileWriter.WriteLine(message);if (EnableStack){//把无关的log去掉var st = StackTraceUtility.ExtractStackTrace();
#if UNITY_EDITORfor (int i = 0; i < 3; i++)
#elsefor (int i = 0; i < 2; i++)
#endif{st = st.Remove(0, st.IndexOf('\n') + 1);}LogFileWriter.WriteLine(st);}}catch (Exception){}}}private static void PhoneSystemInfo(StreamWriter sw){sw.WriteLine("*********************************************************************************************************start");sw.WriteLine("By " + SystemInfo.deviceName);DateTime now = DateTime.Now;sw.WriteLine(string.Concat(new object[] { now.Year.ToString(), "年", now.Month.ToString(), "月", now.Day, "日  ", now.Hour.ToString(), ":", now.Minute.ToString(), ":", now.Second.ToString() }));sw.WriteLine();sw.WriteLine("操作系统:  " + SystemInfo.operatingSystem);sw.WriteLine("系统内存大小:  " + SystemInfo.systemMemorySize);sw.WriteLine("设备模型:  " + SystemInfo.deviceModel);sw.WriteLine("设备唯一标识符:  " + SystemInfo.deviceUniqueIdentifier);sw.WriteLine("处理器数量:  " + SystemInfo.processorCount);sw.WriteLine("处理器类型:  " + SystemInfo.processorType);sw.WriteLine("显卡标识符:  " + SystemInfo.graphicsDeviceID);sw.WriteLine("显卡名称:  " + SystemInfo.graphicsDeviceName);sw.WriteLine("显卡标识符:  " + SystemInfo.graphicsDeviceVendorID);sw.WriteLine("显卡厂商:  " + SystemInfo.graphicsDeviceVendor);sw.WriteLine("显卡版本:  " + SystemInfo.graphicsDeviceVersion);sw.WriteLine("显存大小:  " + SystemInfo.graphicsMemorySize);sw.WriteLine("显卡着色器级别:  " + SystemInfo.graphicsShaderLevel);sw.WriteLine("是否图像效果:  " + SystemInfo.supportsImageEffects);sw.WriteLine("是否支持内置阴影:  " + SystemInfo.supportsShadows);sw.WriteLine("*********************************************************************************************************end");sw.WriteLine("LogInfo:");sw.WriteLine();}}}

更多推荐

[Unity] 自定义日志系统 解决Unity Log的痛点

本文发布于:2023-07-01 07:34:29,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/972690.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:自定义   系统   日志   Unity   Log

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!