Logger.cs 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Drawing;
  4. using System.IO;
  5. using System.Linq;
  6. using System.Text;
  7. using System.Threading;
  8. namespace Island.StandardLib
  9. {
  10. /// <summary>
  11. /// 表示输出内容的等级
  12. /// </summary>
  13. public enum LogLevel
  14. {
  15. /// <summary>
  16. /// 提示
  17. /// </summary>
  18. Info,
  19. /// <summary>
  20. /// 正常
  21. /// </summary>
  22. Default,
  23. /// <summary>
  24. /// 警告
  25. /// </summary>
  26. Warning,
  27. /// <summary>
  28. /// 错误
  29. /// </summary>
  30. Error
  31. }
  32. internal class LogLine
  33. {
  34. internal string str;
  35. internal LogLevel lvl;
  36. }
  37. public interface ILogger
  38. {
  39. void Write(string data);
  40. void WriteLine(string data);
  41. void SetForegroundColor(Color color);
  42. void GetForegroundColor(ref Color color);
  43. void ReadLine(ref string str);
  44. }
  45. public static class Logger
  46. {
  47. public static bool ShowInfo = true;
  48. public static ILogger __Logger__;
  49. public static bool ShowDefault = true;
  50. public static bool ShowWarning = true;
  51. static bool mainThread = false;
  52. public static bool RunInMainThread
  53. {
  54. get
  55. {
  56. return mainThread;
  57. }
  58. set
  59. {
  60. mainThread = value;
  61. if (value)
  62. WriteLine(LogLevel.Warning, "已强制Logger使用单线程,这将影响服务器执行效率。");
  63. else WriteLine(LogLevel.Warning, "已关闭强制Logger使用单线程。");
  64. }
  65. }
  66. static StreamWriter writer;
  67. static ConsoleColor srcColor;
  68. static Color srcColor2;
  69. static List<LogLine> lines;
  70. public static void InitLoggerOnce(bool saveToFile = true, string fileName = null)
  71. {
  72. if (lines != null) return;
  73. if (saveToFile)
  74. {
  75. if (writer != null) return;
  76. string file = fileName ?? "log.txt";
  77. writer = new StreamWriter(file, true, Encoding.UTF8);
  78. }
  79. if (__Logger__ == null)
  80. srcColor = Console.ForegroundColor;
  81. else __Logger__.GetForegroundColor(ref srcColor2);
  82. lines = new List<LogLine>();
  83. Thread thread = new Thread(Loop);
  84. thread.IsBackground = true;
  85. thread.Start();
  86. }
  87. static bool flushd;
  88. public static void Flush()
  89. {
  90. flushd = false;
  91. while (!flushd) { }
  92. }
  93. static void Loop()
  94. {
  95. while (true)
  96. {
  97. lock (lines)
  98. {
  99. for (int i = 0; i < lines.Count; i++)
  100. {
  101. if (i < 0) continue;
  102. if (lines[i] != null)
  103. writeInternal(lines[i].lvl, lines[i].str);
  104. lines.RemoveAt(i);
  105. i--;
  106. }
  107. }
  108. flushd = true;
  109. Thread.Sleep(1);
  110. }
  111. }
  112. static void writeInternal(LogLevel level, string str)
  113. {
  114. string[] tline = str.Split('\n');
  115. foreach (string t in tline)
  116. {
  117. string timeStr = "[" + DateTime.Now.ToString() + "] ";
  118. string logStr = timeStr;
  119. switch (level)
  120. {
  121. case LogLevel.Default:
  122. logStr += "[Default] ";
  123. break;
  124. case LogLevel.Error:
  125. logStr += "[Error] ";
  126. break;
  127. case LogLevel.Info:
  128. logStr += "[Info] ";
  129. break;
  130. case LogLevel.Warning:
  131. logStr += "[Warning] ";
  132. break;
  133. }
  134. logStr += t;
  135. if (level != LogLevel.Info)
  136. {
  137. writer?.WriteLine(logStr);
  138. writer?.Flush();
  139. }
  140. if (__Logger__ == null)
  141. {
  142. Console.ForegroundColor = ConsoleColor.DarkGray;
  143. Console.Write(timeStr);
  144. }
  145. else
  146. {
  147. __Logger__.SetForegroundColor(Color.DarkGray);
  148. __Logger__.Write(timeStr);
  149. }
  150. string writeStr = t;
  151. switch (level)
  152. {
  153. case LogLevel.Default:
  154. if (!ShowDefault) return;
  155. if (__Logger__ == null)
  156. Console.ForegroundColor = ConsoleColor.White;
  157. else
  158. __Logger__.SetForegroundColor(Color.White);
  159. break;
  160. case LogLevel.Error:
  161. if (__Logger__ == null)
  162. Console.ForegroundColor = ConsoleColor.Red;
  163. else
  164. __Logger__.SetForegroundColor(Color.Red);
  165. break;
  166. case LogLevel.Info:
  167. if (!ShowInfo) return;
  168. if (__Logger__ == null)
  169. Console.ForegroundColor = ConsoleColor.DarkGray;
  170. else
  171. __Logger__.SetForegroundColor(Color.DarkGray);
  172. break;
  173. case LogLevel.Warning:
  174. if (!ShowWarning) return;
  175. if (__Logger__ == null)
  176. Console.ForegroundColor = ConsoleColor.Yellow;
  177. else
  178. __Logger__.SetForegroundColor(Color.Yellow);
  179. break;
  180. }
  181. if (__Logger__ == null)
  182. {
  183. Console.WriteLine(writeStr);
  184. Console.ForegroundColor = srcColor;
  185. }
  186. else
  187. {
  188. __Logger__.WriteLine(writeStr);
  189. __Logger__.SetForegroundColor(srcColor2);
  190. }
  191. }
  192. }
  193. public static void Log(LogLevel level, string str)
  194. {
  195. WriteLine(level, str);
  196. }
  197. public static void Log(string str)
  198. {
  199. WriteLine(str);
  200. }
  201. public static void Log(string str, params object[] cs)
  202. {
  203. WriteLine(str, cs);
  204. }
  205. public static void Log(LogLevel level, string str, params object[] cs)
  206. {
  207. WriteLine(level, str, cs);
  208. }
  209. public static void WriteLine(LogLevel level, string str)
  210. {
  211. if (mainThread)
  212. {
  213. writeInternal(level, str);
  214. }
  215. else
  216. {
  217. LogLine ll = new LogLine();
  218. ll.lvl = level;
  219. ll.str = str;
  220. lock (lines)
  221. lines.Add(ll);
  222. }
  223. }
  224. public static void WriteLine(string str)
  225. {
  226. WriteLine(LogLevel.Default, str);
  227. }
  228. public static void WriteLine(string str, params object[] cs)
  229. {
  230. string c = str;
  231. for (int i = 0; i < cs.Length; i++)
  232. c = c.Replace("{" + i + "}", cs[i].ToString());
  233. WriteLine(c);
  234. }
  235. public static void WriteLine(LogLevel level, string str, params object[] cs)
  236. {
  237. string c = str;
  238. for (int i = 0; i < cs.Length; i++)
  239. c = c.Replace("{" + i + "}", cs[i].ToString());
  240. WriteLine(level, c);
  241. }
  242. public static void LogError(Exception e)
  243. {
  244. WriteLine(LogLevel.Error, e.ToString());
  245. }
  246. public static string ReadLine()
  247. {
  248. string cmd = null;
  249. if (__Logger__ == null)
  250. cmd = Console.ReadLine();
  251. else __Logger__.ReadLine(ref cmd);
  252. return cmd;
  253. }
  254. public static string ReadData(string helpText, string defValue = null)
  255. {
  256. string txt = helpText + (defValue == null ? "" : $"({defValue})") + "> ";
  257. if (__Logger__ == null)
  258. Console.Write(txt);
  259. else __Logger__.Write(txt);
  260. string dat = ReadLine();
  261. return dat == "" ? defValue : dat;
  262. }
  263. public static T ReadData<T>(string helpText, Func<string, T> parseFunc)
  264. {
  265. while (true)
  266. {
  267. string data = ReadData(helpText);
  268. try
  269. {
  270. return parseFunc(data);
  271. }
  272. catch
  273. {
  274. if (__Logger__ == null)
  275. Console.WriteLine("Parse Error, Retry.");
  276. else __Logger__.WriteLine("Parse Error, Retry.");
  277. }
  278. }
  279. }
  280. public static T ReadData<T>(string helpText, Func<string, T> parseFunc, string defValue)
  281. {
  282. while (true)
  283. {
  284. string data = ReadData(helpText, defValue);
  285. try
  286. {
  287. return parseFunc(data);
  288. }
  289. catch
  290. {
  291. if (__Logger__ == null)
  292. Console.WriteLine("Parse Error, Retry.");
  293. else __Logger__.WriteLine("Parse Error, Retry.");
  294. }
  295. }
  296. }
  297. }
  298. }