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.

169 lines
5.1 KiB

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