Log.cs 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238
  1. //************************************************************************
  2. // https://github.com/yuzhengyang
  3. // author: yuzhengyang
  4. // date: 2017.3.29 - 2017.7.6
  5. // desc: 日志功能
  6. // Copyright (c) yuzhengyang. All rights reserved.
  7. //************************************************************************
  8. //R.Log.IsWriteFile = true;
  9. //R.Log.LogLevel = LogLevel.Warning | LogLevel.Debug;
  10. //Log.AllocConsole();
  11. //R.Log.v("this is v 啰嗦");
  12. //R.Log.d("this is d 调试");
  13. //R.Log.i("this is i 重要");
  14. //R.Log.w("this is w 警告");
  15. //R.Log.e("this is e 错误");
  16. using Azylee.Core.DataUtils.CollectionUtils;
  17. using Azylee.Core.IOUtils.DirUtils;
  18. using Azylee.Core.IOUtils.TxtUtils;
  19. using System;
  20. using System.Collections.Concurrent;
  21. using System.Collections.Generic;
  22. using System.Linq;
  23. using System.Runtime.InteropServices;
  24. using System.Threading;
  25. using System.Threading.Tasks;
  26. namespace Azylee.Core.LogUtils
  27. {
  28. /// <summary>
  29. /// Log 输出工具
  30. ///
  31. /// 说明:
  32. /// 1、Log.AllocConsole();开启控制台
  33. /// 2、Log.FreeConsole();关闭控制台
  34. /// 3、Log.i("information");输出消息
  35. /// </summary>
  36. public class Log
  37. {
  38. //输出的 Log 格式
  39. const string LOG_FORMAT = "{0} {1} {2}";
  40. const string TIME_FORMAT = "HH:mm:ss.fff";
  41. const string LOG_PATH = "Log";
  42. private object LogFileLock = new object();//写日志文件锁
  43. private bool IsWriteFile = false;//是否写日志文件
  44. public string LogPath = LOG_PATH;
  45. public LogLevel LogLevel = LogLevel.All;//日志输出等级
  46. bool IsStart = false;
  47. ConcurrentQueue<LogModel> Queue = new ConcurrentQueue<LogModel>();
  48. public Log()
  49. { }
  50. public Log(bool isWrite, string logPath = LOG_PATH, LogLevel level = LogLevel.All)
  51. {
  52. if (isWrite && !string.IsNullOrWhiteSpace(logPath))
  53. {
  54. LogPath = logPath.Trim();
  55. IsWriteFile = true;
  56. LogLevel = level;
  57. }
  58. }
  59. public void Start()
  60. {
  61. if (!IsStart)
  62. {
  63. IsStart = true;
  64. Task.Factory.StartNew(() =>
  65. {
  66. while (IsStart)
  67. {
  68. Thread.Sleep(500);
  69. if (Queue.Any())
  70. {
  71. List<LogModel> list = new List<LogModel>();
  72. for (int i = 0; i < Queue.Count; i++)
  73. {
  74. LogModel model = null;
  75. if (Queue.TryDequeue(out model)) list.Add(model);
  76. }
  77. if (ListTool.HasElements(list)) WriteFile(list);
  78. }
  79. }
  80. });
  81. }
  82. }
  83. void Stop()
  84. {
  85. if (IsStart)
  86. IsStart = false;
  87. }
  88. public bool SetWriteFile(bool isWrite, string logPath)
  89. {
  90. if (isWrite && !string.IsNullOrWhiteSpace(logPath))
  91. {
  92. LogPath = logPath.Trim();
  93. IsWriteFile = true;
  94. return true;
  95. }
  96. IsWriteFile = false;
  97. return false;
  98. }
  99. #region Console 开启/关闭 API
  100. [DllImport("kernel32.dll")]
  101. public static extern Boolean AllocConsole();
  102. [DllImport("kernel32.dll")]
  103. public static extern Boolean FreeConsole();
  104. #endregion
  105. /// <summary>
  106. /// 获取输出颜色
  107. /// </summary>
  108. /// <param name="type">输出类型</param>
  109. /// <returns></returns>
  110. private ConsoleColor GetColor(LogType type)
  111. {
  112. switch (type)
  113. {
  114. case LogType.v: return ConsoleColor.Gray;
  115. case LogType.d: return ConsoleColor.Blue;
  116. case LogType.i: return ConsoleColor.Green;
  117. case LogType.w: return ConsoleColor.Yellow;
  118. case LogType.e: return ConsoleColor.Red;
  119. default: return ConsoleColor.Gray;
  120. }
  121. }
  122. /// <summary>
  123. /// 写出到控制台
  124. /// </summary>
  125. /// <param name="type">类型</param>
  126. /// <param name="tag">标记</param>
  127. /// <param name="message">消息</param>
  128. private void Write(LogType type, string message)
  129. {
  130. Console.ForegroundColor = GetColor(type);
  131. Console.WriteLine(LOG_FORMAT, DateTime.Now.ToString(TIME_FORMAT), type.ToString(), message);
  132. if (IsWriteFile) Queue.Enqueue(new LogModel() { Type = type, Message = message, CreateTime = DateTime.Now });
  133. }
  134. private void WriteFile(LogModel log)
  135. {
  136. if (IsWriteFile)
  137. {
  138. lock (LogFileLock)
  139. {
  140. //设置日志目录
  141. string logPath = AppDomain.CurrentDomain.BaseDirectory + LogPath;
  142. string file = string.Format(@"{0}\{1}.txt", logPath, DateTime.Now.ToString("yyyy-MM-dd"));
  143. //创建日志目录
  144. DirTool.Create(logPath);
  145. //写出日志
  146. TxtTool.Append(file, string.Format(LOG_FORMAT, log.CreateTime.ToString(TIME_FORMAT), log.Type.ToString(), log.Message));
  147. }
  148. }
  149. }
  150. private void WriteFile(List<LogModel> list)
  151. {
  152. if (IsWriteFile)
  153. {
  154. lock (LogFileLock)
  155. {
  156. //设置日志目录
  157. string logPath = AppDomain.CurrentDomain.BaseDirectory + LogPath;
  158. string file = string.Format(@"{0}\{1}.txt", logPath, DateTime.Now.ToString("yyyy-MM-dd"));
  159. //创建日志目录
  160. DirTool.Create(logPath);
  161. //整理要输出的内容
  162. List<string> txts = new List<string>();
  163. foreach (var item in list)
  164. {
  165. txts.Add(string.Format(LOG_FORMAT, item.CreateTime.ToString(TIME_FORMAT), item.Type.ToString(), item.Message));
  166. }
  167. //写出日志
  168. TxtTool.Append(file, txts);
  169. }
  170. }
  171. }
  172. #region 分类详细输出
  173. /// <summary>
  174. /// 输出 verbose (啰嗦信息)
  175. /// </summary>
  176. /// <param name="message">消息</param>
  177. /// <param name="tag">可选:标记</param>
  178. public void v<T>(T msg)
  179. {
  180. if ((LogLevel & LogLevel.Verbose) == LogLevel.Verbose)
  181. Write(LogType.v, msg.ToString());
  182. }
  183. /// <summary>
  184. /// 输出 Debug (调试信息)
  185. /// </summary>
  186. /// <param name="message">消息</param>
  187. /// <param name="tag">可选:标记</param>
  188. public void d<T>(T msg)
  189. {
  190. if ((LogLevel & LogLevel.Debug) == LogLevel.Debug)
  191. Write(LogType.d, msg.ToString());
  192. }
  193. /// <summary>
  194. /// 输出 Information (重要信息)
  195. /// </summary>
  196. /// <param name="message">消息</param>
  197. /// <param name="tag">可选:标记</param>
  198. public void i<T>(T msg)
  199. {
  200. if ((LogLevel & LogLevel.Information) == LogLevel.Information)
  201. Write(LogType.i, msg.ToString());
  202. }
  203. /// <summary>
  204. /// 输出 Warning (警告信息)
  205. /// </summary>
  206. /// <param name="message">消息</param>
  207. /// <param name="tag">可选:标记</param>
  208. public void w<T>(T msg)
  209. {
  210. if ((LogLevel & LogLevel.Warning) == LogLevel.Warning)
  211. Write(LogType.w, msg.ToString());
  212. }
  213. /// <summary>
  214. /// 输出 Error (错误信息)
  215. /// </summary>
  216. /// <param name="message">消息</param>
  217. /// <param name="tag">可选:标记</param>
  218. public void e<T>(T msg)
  219. {
  220. if ((LogLevel & LogLevel.Error) == LogLevel.Error)
  221. Write(LogType.e, msg.ToString());
  222. }
  223. #endregion
  224. }
  225. }