You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.17 13:01:42