来自于:Zero_LJ

前言

之前unity5.x在代码中写了debug.log..等等,打包之后在当前程序文件夹下会有个对应的”outlog.txt”,2017之后这个文件被移到C盘用户Appdata/LocalLow/公司名 文件夹下面。觉得不方便就自己写了个

代码

  1. using UnityEngine;
  2. using System.IO;
  3. using System;
  4. using System.Diagnostics;
  5. using Debug = UnityEngine.Debug;
  6. public class DebugTrace
  7. {
  8. private FileStream fileStream;
  9. private StreamWriter streamWriter;
  10. private bool isEditorCreate = false;//是否在编辑器中也产生日志文件
  11. private int showFrames = 1000; //打印所有
  12. #region instance
  13. private static readonly object obj = new object();
  14. private static DebugTrace m_instance;
  15. public static DebugTrace Instance
  16. {
  17. get
  18. {
  19. if (m_instance == null)
  20. {
  21. lock (obj)
  22. {
  23. if (m_instance == null)
  24. m_instance = new DebugTrace();
  25. }
  26. }
  27. return m_instance;
  28. }
  29. }
  30. #endregion
  31. private DebugTrace()
  32. {
  33. }
  34. /// <summary>
  35. /// 开启跟踪日志信息
  36. /// </summary>
  37. public void StartTrace()
  38. {
  39. if (Debug.unityLogger.logEnabled)
  40. {
  41. if (Application.isEditor)
  42. {
  43. //在编辑器中设置isEditorCreate==true时候产生日志
  44. if (isEditorCreate)
  45. {
  46. CreateOutlog();
  47. }
  48. }
  49. //不在编辑器中 是否产生日志由 Debug.unityLogger.logEnabled 控制
  50. else
  51. {
  52. CreateOutlog();
  53. }
  54. }
  55. }
  56. private void Application_logMessageReceivedThreaded(string logString, string stackTrace, LogType type)
  57. {
  58. // Debug.Log(stackTrace); //打包后staackTrace为空 所以要自己实现
  59. if (type != LogType.Warning)
  60. {
  61. // StackTrace stack = new StackTrace(1,true); //跳过第二?(1)帧
  62. StackTrace stack = new StackTrace(true); //捕获所有帧
  63. string stackStr = string.Empty;
  64. int frameCount = stack.FrameCount; //帧数
  65. if (this.showFrames > frameCount) this.showFrames = frameCount; //如果帧数大于总帧速 设置一下
  66. //自定义输出帧数,可以自行试试查看效果
  67. for (int i = stack.FrameCount - this.showFrames; i < stack.FrameCount; i++)
  68. {
  69. StackFrame sf = stack.GetFrame(i); //获取当前帧信息
  70. // 1:第一种 ps:GetFileLineNumber 在发布打包后获取不到
  71. stackStr += "at [" + sf.GetMethod().DeclaringType.FullName +
  72. "." + sf.GetMethod().Name +
  73. ".Line:" + sf.GetFileLineNumber() + "]\n ";
  74. //或者直接调用tostring 显示数据过多 且打包后有些数据获取不到
  75. // stackStr += sf.ToString();
  76. }
  77. //或者 stackStr = stack.ToString();
  78. string content = string.Format("time: {0} logType: {1} logString: {2} \nstackTrace: {3} {4} ",
  79. DateTime.Now.ToString("HH:mm:ss"), type, logString, stackStr, "\r\n");
  80. streamWriter.WriteLine(content);
  81. streamWriter.Flush();
  82. }
  83. }
  84. private void CreateOutlog()
  85. {
  86. if (!Directory.Exists(Application.dataPath + "/../" + "OutLog"))
  87. Directory.CreateDirectory(Application.dataPath + "/../" + "OutLog");
  88. string path = Application.dataPath + "/../OutLog" + "/" + DateTime.Now.ToString("yyyyMMddHHmmss") + "_log.txt";
  89. fileStream = new FileStream(path, FileMode.OpenOrCreate, FileAccess.ReadWrite);
  90. streamWriter = new StreamWriter(fileStream);
  91. Application.logMessageReceivedThreaded += Application_logMessageReceivedThreaded;
  92. }
  93. /// <summary>
  94. /// 关闭跟踪日志信息
  95. /// </summary>
  96. public void CloseTrace()
  97. {
  98. Application.logMessageReceivedThreaded -= Application_logMessageReceivedThreaded;
  99. streamWriter.Dispose();
  100. streamWriter.Close();
  101. fileStream.Dispose();
  102. fileStream.Close();
  103. }
  104. /// <summary>
  105. /// 设置选项
  106. /// </summary>
  107. /// <param name="logEnable">是否记录日志</param>
  108. /// <param name="showFrams">是否显示所有堆栈帧 默认只显示当前帧 如果设为0 则显示所有帧</param>
  109. /// <param name="filterLogType">过滤 默认log级别以上</param>
  110. /// <param name="editorCreate">是否在编辑器中产生日志记录 默认不需要</param>
  111. public void SetLogOptions(bool logEnable, int showFrams = 1, LogType filterLogType = LogType.Log, bool editorCreate = false)
  112. {
  113. Debug.unityLogger.logEnabled = logEnable;
  114. Debug.unityLogger.filterLogType = filterLogType;
  115. isEditorCreate = editorCreate;
  116. this.showFrames = showFrams == 0 ? 1000 : showFrams;
  117. }
  118. }

关于 filterLogType
filterLogType默认设置是Log,会显示所有类型的Log。
Warning:会显示Warning,Assert,Error,Exception
Assert:会显示Assert,Error,Exception
Error:显示Error和Exception
Exception:只会显示Exception

  1. using UnityEngine;
  2. public class Test : MonoBehaviour
  3. {
  4. private BoxCollider boxCollider;
  5. void Start()
  6. {
  7. DebugTrace.Instance.SetLogOptions(true, 2, editorCreate: true); //设置日志打开 显示2帧 并且编辑器下产生日志
  8. DebugTrace.Instance.StartTrace();
  9. Debug.Log("log");
  10. Debug.Log("log", this);
  11. Debug.LogError("LogError");
  12. Debug.LogAssertion("LogAssertion");
  13. boxCollider.enabled = false; //报错 发布后捕捉不到帧
  14. }
  15. private void OnApplicationQuit()
  16. {
  17. DebugTrace.Instance.CloseTrace();
  18. }
  19. }

如果在编辑器中也设置产生日志,日志文件在当前项目路径下,打包后在exe同级目录下
在打包发布后某些数据会获取不到 例如行号

StackFrame参考

image.png
最后看下效果:
image.png

不足

发布版本 出现异常捕捉不到 行号获取不到
debug版本可以勾选DevelopMend build 捕捉到更多信息
image.png