You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

151 lines
4.5 KiB

  1. using IllusionInjector.Logging.Printers;
  2. using IllusionPlugin.Logging;
  3. using IllusionPlugin.Logging.Printers;
  4. using System;
  5. using System.Collections.Concurrent;
  6. using System.Collections.Generic;
  7. using System.Linq;
  8. using System.Text;
  9. using System.Threading;
  10. using System.Threading.Tasks;
  11. using LoggerBase = IllusionPlugin.Logging.Logger;
  12. namespace IllusionInjector.Logging
  13. {
  14. internal static class Logger
  15. {
  16. private static LoggerBase _log;
  17. internal static LoggerBase log
  18. {
  19. get
  20. {
  21. if (_log == null)
  22. _log = new StandardLogger("IllusionInjector");
  23. return _log;
  24. }
  25. }
  26. }
  27. public class StandardLogger : LoggerBase
  28. {
  29. private static readonly IReadOnlyList<LogPrinter> defaultPrinters = new List<LogPrinter>()
  30. {
  31. new ColoredConsolePrinter()
  32. {
  33. Filter = LogLevel.DebugOnly,
  34. Color = ConsoleColor.Green,
  35. },
  36. new ColoredConsolePrinter()
  37. {
  38. Filter = LogLevel.InfoOnly,
  39. Color = ConsoleColor.White,
  40. },
  41. new ColoredConsolePrinter()
  42. {
  43. Filter = LogLevel.WarningOnly,
  44. Color = ConsoleColor.Yellow,
  45. },
  46. new ColoredConsolePrinter()
  47. {
  48. Filter = LogLevel.ErrorOnly,
  49. Color = ConsoleColor.Red,
  50. },
  51. new ColoredConsolePrinter()
  52. {
  53. Filter = LogLevel.CriticalOnly,
  54. Color = ConsoleColor.Magenta,
  55. },
  56. new GlobalLogFilePrinter()
  57. };
  58. private string logName;
  59. private static LogLevel showFilter = LogLevel.InfoUp;
  60. public static LogLevel Filter { get => showFilter; set => showFilter = value; }
  61. private List<LogPrinter> printers = new List<LogPrinter>(defaultPrinters);
  62. internal StandardLogger(string name)
  63. {
  64. logName = name;
  65. printers.Add(new PluginLogFilePrinter(name));
  66. if (_logThread == null || !_logThread.IsAlive)
  67. {
  68. _logThread = new Thread(LogThread);
  69. _logThread.Start();
  70. }
  71. }
  72. public override void Log(Level level, string message)
  73. {
  74. _logQueue.Add(new LogMessage
  75. {
  76. level = level,
  77. message = message,
  78. logger = this,
  79. time = DateTime.Now
  80. });
  81. }
  82. internal struct LogMessage
  83. {
  84. public Level level;
  85. public StandardLogger logger;
  86. public string message;
  87. public DateTime time;
  88. }
  89. private static BlockingCollection<LogMessage> _logQueue = new BlockingCollection<LogMessage>();
  90. private static Thread _logThread;
  91. private static void LogThread()
  92. {
  93. HashSet<LogPrinter> started = new HashSet<LogPrinter>();
  94. while (_logQueue.TryTake(out LogMessage msg, Timeout.Infinite)) {
  95. foreach (var printer in msg.logger.printers)
  96. {
  97. try
  98. {
  99. if (((byte)msg.level & (byte)printer.Filter) != 0)
  100. {
  101. if (!started.Contains(printer))
  102. {
  103. printer.StartPrint();
  104. started.Add(printer);
  105. }
  106. printer.Print(msg.level, msg.time, msg.logger.logName, msg.message);
  107. }
  108. }
  109. catch (Exception e)
  110. {
  111. Console.WriteLine($"printer errored {e}");
  112. }
  113. }
  114. if (_logQueue.Count == 0)
  115. {
  116. foreach (var printer in started)
  117. {
  118. try
  119. {
  120. printer.EndPrint();
  121. }
  122. catch (Exception e)
  123. {
  124. Console.WriteLine($"printer errored {e}");
  125. }
  126. }
  127. started.Clear();
  128. }
  129. }
  130. }
  131. public static void StopLogThread()
  132. {
  133. _logQueue.CompleteAdding();
  134. _logThread.Join();
  135. }
  136. }
  137. }