【Unity】本地化日志


方法一

通过Application.logMessageReceived事件,控制log的输出及方法

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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
using Sirenix.OdinInspector;
using System;
using System.IO;
using System.Text;
using UnityEngine;

public class Logger : MonoBehaviour
{
// 使用StringBuilder来优化字符串的重复构造
StringBuilder m_logStr = new StringBuilder();
// 日志文件存储位置
string m_logFileSavePath;

void Awake()
{
// 当前时间
var t = System.DateTime.Now.ToString("yyyyMMddHHmmss");
m_logFileSavePath = string.Format("{0}/output_{1}.log", Application.persistentDataPath, t);
Debug.Log(m_logFileSavePath);
Application.logMessageReceived += OnLogCallBack;
Debug.Log("日志存储测试");
}

/// <summary>
/// 打印日志回调
/// </summary>
/// <param name="condition">日志文本</param>
/// <param name="stackTrace">调用堆栈</param>
/// <param name="type">日志类型</param>
private void OnLogCallBack(string condition, string stackTrace, LogType type)
{
m_logStr.Append($"[{Customize.ShowDateSeconds(DateTime.Now)}]");
m_logStr.Append("\n");
m_logStr.Append(condition);
m_logStr.Append("\n");
m_logStr.Append(stackTrace);
m_logStr.Append("\n");

if (m_logStr.Length <= 0) return;
if (!File.Exists(m_logFileSavePath))
{
var fs = File.Create(m_logFileSavePath);
fs.Close();
}
using (var sw = File.AppendText(m_logFileSavePath))
{
sw.WriteLine(m_logStr.ToString());
}
m_logStr.Remove(0, m_logStr.Length);
}
}

方法二

自定义log类,通过自定义类的方法输出并本地化日志

该方法自定义自定义性更强,可以过滤命名空间

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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using UnityEngine;

namespace Controller
{
public class LogManager : MonoBehaviour
{
private static string logFilePath;

// 自定义的日志输出方法
public static void Log(string message)
{
if (logFilePath == null)
{
InitializeLogFile();
}
// 在编辑器中输出日志
UnityEngine.Debug.Log(message);

StackTrace stackTrace = new StackTrace(true);

string filteredStackTrace = FilterStackTrace(stackTrace);

// 将日志写入文件
File.AppendAllText(logFilePath, $"[{Customize.ShowDateSeconds(DateTime.Now)}]\n{message}\n{filteredStackTrace}\n\n");
}

// 自定义的日志输出方法
public static void LogError(string message)
{
if (logFilePath == null)
{
InitializeLogFile();
}
// 在编辑器中输出日志
UnityEngine.Debug.LogError(message);

StackTrace stackTrace = new StackTrace(true);

string filteredStackTrace = FilterStackTrace(stackTrace);

// 将日志写入文件
File.AppendAllText(logFilePath, $"[{Customize.ShowDateSeconds(DateTime.Now)}]\n{message}\n{filteredStackTrace}\n\n");
}

private static void InitializeLogFile()
{
var t = System.DateTime.Now.ToString("yyyyMMddHHmmss");
logFilePath = Path.Combine(Application.persistentDataPath, $"Controller_{t}.txt");
UnityEngine.Debug.Log(logFilePath);
}

// 过滤堆栈信息,仅保留指定脚本的部分
private static string FilterStackTrace(StackTrace stackTrace)
{
// 这里假设你的脚本在命名空间 "Controller" 中,替换为实际的命名空间
string targetNamespace = "Controller";

// 过滤堆栈信息,仅保留与指定命名空间相关的部分
StackFrame[] frames = stackTrace.GetFrames();
StringWriter writer = new StringWriter();

foreach (var frame in frames)
{
if (frame.GetMethod().DeclaringType.Namespace == targetNamespace)
{
writer.WriteLine(frame.ToString());
}
}

return writer.ToString();
}


}
}