UnityLog.cs 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256
  1. using System;
  2. using System.IO;
  3. using System.Text;
  4. using UnityEngine;
  5. namespace XRTool.Util
  6. {
  7. /// <summary>
  8. /// 日志输出,请勿使用Debug或者Print等自带的日志
  9. /// 日志分级,普通日志,错误日志,异常日志
  10. /// debug模式可以输出普通日志,其他日志必输出
  11. /// 通过配置参数实现不同的日志等级
  12. /// 为了避免大量日志输出,采用优化方案写入日志
  13. /// </summary>
  14. public class UnityLog : Singleton<UnityLog>
  15. {
  16. private string logBuilder;
  17. private FileStream logStream;
  18. private FileStream errorStream;
  19. private FileStream exceptStream;
  20. public event Action<string> MessageReceived;
  21. /// <summary>
  22. /// 在编辑器中是否输出日志文件
  23. /// </summary>
  24. public bool isOutLogEditor = true;
  25. /// <summary>
  26. /// 日志等级,默认为1,正式发布版本为0
  27. /// 等级越高代表可输出的日志越多
  28. /// </summary>
  29. public int logLevel = 1;
  30. public const string NULL = "null";
  31. private bool isFristLog = true;
  32. private bool isFristLogError = true;
  33. private bool isFristLogExcept = true;
  34. public static string LogPath = "LogData";
  35. public UnityLog()
  36. {
  37. InitLog();
  38. }
  39. /// <summary>
  40. /// 接受系统级别的日志信息
  41. /// </summary>
  42. public void InitLog(FileMode mode = FileMode.Append)
  43. {
  44. if (logStream == null)
  45. {
  46. string appPath = Application.persistentDataPath + "/" + LogPath;
  47. if (!Directory.Exists(appPath))
  48. {
  49. Directory.CreateDirectory(appPath);
  50. }
  51. string logPath = Path.Combine(appPath, "log.txt");
  52. string errorPath = Path.Combine(appPath, "error.txt");
  53. string exceptPath = Path.Combine(appPath, "except.txt");
  54. //Log(appPath);
  55. logStream = new FileStream(logPath, mode);
  56. errorStream = new FileStream(errorPath, mode);
  57. exceptStream = new FileStream(exceptPath, mode);
  58. Application.logMessageReceived += LogMessageReceived;
  59. }
  60. }
  61. /// <summary>
  62. /// 接受系统日志
  63. /// </summary>
  64. /// <param name="condition"></param>
  65. /// <param name="stackTrace"></param>
  66. /// <param name="type"></param>
  67. private void LogMessageReceived(string condition, string stackTrace, LogType type)
  68. {
  69. if (!isOutLogEditor)
  70. {
  71. return;
  72. }
  73. logBuilder = null;
  74. FileStream fileStream = null;
  75. if (string.IsNullOrEmpty(condition) && string.IsNullOrEmpty(stackTrace))
  76. {
  77. return;
  78. }
  79. bool isWriteFrist = false;
  80. #if UNITY_EDITOR || !BUILDTYPE_RELEASE //Release
  81. if (type == LogType.Log)
  82. {
  83. ///日志等级大于0时才会开启日志
  84. if (logLevel >= 1)
  85. {
  86. fileStream = logStream;
  87. }
  88. if (isFristLog)
  89. {
  90. isWriteFrist = true;
  91. isFristLog = false;
  92. }
  93. }
  94. #endif
  95. if (type == LogType.Exception)
  96. {
  97. fileStream = exceptStream;
  98. if (isFristLogExcept)
  99. {
  100. isWriteFrist = true;
  101. isFristLogExcept = false;
  102. }
  103. }
  104. else if (type == LogType.Error)
  105. {
  106. fileStream = errorStream;
  107. if (isFristLogError)
  108. {
  109. isWriteFrist = true;
  110. isFristLogError = false;
  111. }
  112. }
  113. if (fileStream != null)
  114. {
  115. DateTime time = DateTime.Now;
  116. logBuilder = time + ": " + condition + stackTrace + "\n";
  117. MessageReceived?.Invoke(logBuilder);
  118. if (isWriteFrist)
  119. {
  120. if (BuildConfigMgr.Instance.IsInit)
  121. {
  122. ReleaseLog("\n----------Version Log------------\n" +
  123. Application.productName + "_" + Application.version + "_" + BuildConfig.Instance.buildTime + "\n",
  124. fileStream);
  125. }
  126. }
  127. ReleaseLog(logBuilder, fileStream);
  128. fileStream.Flush();
  129. }
  130. fileStream = null;
  131. logBuilder = null;
  132. }
  133. /// <summary>
  134. /// 释放资源
  135. /// </summary>
  136. public void ReleaseLog()
  137. {
  138. Application.logMessageReceived -= LogMessageReceived;
  139. if (logStream != null)
  140. {
  141. logStream.Close();
  142. }
  143. if (errorStream != null)
  144. {
  145. errorStream.Close();
  146. }
  147. if (exceptStream != null)
  148. {
  149. exceptStream.Close();
  150. }
  151. logStream = null;
  152. errorStream = null;
  153. exceptStream = null;
  154. }
  155. public void Log(object log, int logLevel = 1)
  156. {
  157. //Log(log != null ? log.ToString() : "null", logLevel);
  158. ///如果是编辑器模式或者非商用APP版本,可以打日志文件
  159. #if UNITY_EDITOR || !BuildType_RELEASE //Release
  160. bool isForce = false;
  161. #if UNITY_EDITOR
  162. isForce = this.logLevel >= 4;
  163. #endif
  164. if (isForce || logLevel <= this.logLevel)
  165. {
  166. Debug.Log(log != null ? log.ToString() : NULL);
  167. }
  168. #endif
  169. }
  170. /// <summary>
  171. /// 正常的日志输出
  172. /// </summary>
  173. public void Log(string log, int logLevel = 1)
  174. {
  175. ///如果是编辑器模式或者非商用APP版本,可以打日志文件
  176. #if UNITY_EDITOR || !BuildType_RELEASE //Release
  177. bool isForce = false;
  178. #if UNITY_EDITOR
  179. isForce = this.logLevel >= 4;
  180. #endif
  181. if (isForce || logLevel <= this.logLevel)
  182. {
  183. Debug.Log(log);
  184. }
  185. #endif
  186. }
  187. /// <summary>
  188. /// 错误日志输出
  189. /// </summary>
  190. public void LogError(string log, int logLevel = 1)
  191. {
  192. ///错误日志任何模式都会输出
  193. Debug.LogError(log);
  194. }
  195. /// <summary>
  196. /// 错误日志输出
  197. /// </summary>
  198. public void LogException(Exception ex, int logLevel = 1)
  199. {
  200. ///异常日志由系统自动输出
  201. Debug.LogException(ex);
  202. }
  203. /// <summary>
  204. /// 日志输出,替换对应的日志文件
  205. /// </summary>
  206. public void Log(string log, LogType logType, int logLevel = 1)
  207. {
  208. if (logType == LogType.Log)
  209. {
  210. Log(log, logLevel);
  211. }
  212. else if (logType == LogType.Error)
  213. {
  214. LogError(log, logLevel);
  215. }
  216. }
  217. /// <summary>
  218. /// 释放资源
  219. /// </summary>
  220. public void ReleaseLog(string msg, FileStream stream)
  221. {
  222. if (!string.IsNullOrEmpty(msg))
  223. {
  224. WriteLogToFile(msg, stream);
  225. }
  226. }
  227. /// <summary>
  228. /// 将日志写入到文件中
  229. /// </summary>
  230. /// <param name="log"></param>
  231. /// <param name="logType"></param>
  232. public void WriteLogToFile(string log, FileStream stream)
  233. {
  234. if (stream != null)
  235. {
  236. ///UTF8的编码格式转化成byte字节流
  237. byte[] buttf = Encoding.Default.GetBytes(log);
  238. stream.Write(buttf, 0, log.Length);
  239. }
  240. }
  241. public void ClearAllLog()
  242. {
  243. ReleaseLog();
  244. InitLog(FileMode.Create);
  245. }
  246. }
  247. }