Unity日志添加时间戳:含第三方DLL输出的解决方案咨询
解决Unity项目中第三方DLL日志添加时间戳的问题
方案1:自定义Console输出包装类
如果第三方DLL是通过Console.WriteLine输出日志,你可以自定义一个TextWriter子类,在输出时自动添加时间戳,再替换默认的Console.Out。所有通过Console输出的内容都会被拦截并修改格式。
示例代码:
using System; using System.IO; using UnityEngine; public class TimedConsoleWriter : TextWriter { private readonly TextWriter _originalOut; public TimedConsoleWriter(TextWriter original) { _originalOut = original; } public override Encoding Encoding => _originalOut.Encoding; public override void WriteLine(string value) { // 自定义时间戳格式,可按需调整 string timestampedLine = $"[{DateTime.Now:yyyy-MM-dd HH:mm:ss.fff}] {value}"; _originalOut.WriteLine(timestampedLine); // 同时转发到Unity Debug系统,实现日志统一管理 Debug.Log(timestampedLine); } public override void Write(string value) { // 处理非换行输出,按需实现 _originalOut.Write(value); } } // 项目初始化时完成日志配置 public class LogSetup : MonoBehaviour { void Awake() { // 避免重复替换Console输出 if (!(Console.Out is TimedConsoleWriter)) { Console.SetOut(new TimedConsoleWriter(Console.Out)); } // 保留Unity自身日志的时间戳处理 Application.logMessageReceivedThreaded += HandleUnityLog; } void HandleUnityLog(string message, string stackTrace, LogType type) { string timestampedMessage = $"[{DateTime.Now:yyyy-MM-dd HH:mm:ss.fff}] [{type}] {message}"; // 将处理后的日志写入自定义文件 WriteToLogFile(timestampedMessage); } void WriteToLogFile(string content) { string logPath = Path.Combine(Application.persistentDataPath, "game_log.txt"); // 加锁避免多线程写入冲突 lock (this) { File.AppendAllText(logPath, content + Environment.NewLine); } } void OnDestroy() { Application.logMessageReceivedThreaded -= HandleUnityLog; // 可选:恢复原始Console输出 if (Console.Out is TimedConsoleWriter timedWriter) { Console.SetOut(timedWriter._originalOut); } } }
方案2:过滤Unity自带时间戳的线程ID
如果想用Unity官方日志时间戳功能,但编辑器输出的线程ID多余,可以在日志回调中用正则过滤掉线程ID部分。
示例代码:
using System.Text.RegularExpressions; void HandleUnityLog(string message, string stackTrace, LogType type) { // 匹配并移除开头的[Thread 数字]格式线程ID string cleanedMessage = Regex.Replace(message, @"^\[Thread \d+\] ", ""); string timestampedMessage = $"[{DateTime.Now:yyyy-MM-dd HH:mm:ss.fff}] [{type}] {cleanedMessage}"; WriteToLogFile(timestampedMessage); }
关于Reflection Emit的说明
Reflection Emit确实能动态修改第三方DLL的方法实现,但复杂度极高,需要熟悉IL指令,且容易因DLL更新、IL结构变化失效,完全不是最优方案,优先用前面两种简单稳定的方法。
特殊情况处理
如果第三方DLL用私有日志类输出(而非Console),可以尝试用反射定位它的日志方法,替换为自定义实现:
// 示例:假设DLL中有个Logger类,有WriteLog静态方法 Type loggerType = Type.GetType("ThirdParty.Logger, ThirdPartyDll"); MethodInfo originalMethod = loggerType.GetMethod("WriteLog", BindingFlags.Public | BindingFlags.Static); // 创建自定义委托替换原方法 Action<string> customLog = (msg) => Debug.Log($"[{DateTime.Now:yyyy-MM-dd HH:mm:ss.fff}] {msg}"); Delegate.CreateDelegate(originalMethod.GetType(), customLog.Target, customLog.Method);
内容的提问来源于stack exchange,提问作者nkazz
相关产品推荐
相关产品推荐

