NamedPipeLogger.cs 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228
  1. using System.Diagnostics;
  2. using System.Diagnostics.CodeAnalysis;
  3. using System.Text;
  4. using H.Formatters;
  5. using H.Pipes;
  6. using InABox.Core;
  7. using InABox.Formatters;
  8. namespace InABox.Logging
  9. {
  10. public abstract class LoggerBase
  11. {
  12. public LogType[] LogTypes = { LogType.Information, LogType.Query, LogType.Update, LogType.Error, LogType.Important };
  13. protected abstract void DoSend(string message);
  14. public virtual void Send(LogType logType, string user, string message, Guid transaction)
  15. {
  16. if (!LogTypes.Any(x => x == logType))
  17. return;
  18. var type = logType switch
  19. {
  20. LogType.Information => "INFO",
  21. LogType.Query => "READ",
  22. LogType.Update => "UPDATE",
  23. LogType.Error => "ERROR",
  24. LogType.Important => "IMPTNT",
  25. _ => "ERROR"
  26. };
  27. var msg = string.Format("{0:HH:mm:ss.fff} {1} {2} {3} {4}",
  28. DateTime.Now,
  29. transaction,
  30. type?.PadRight(6),
  31. (user ?? "").PadRight(12),
  32. message
  33. );
  34. DoSend(msg);
  35. }
  36. public virtual void Stop() { }
  37. }
  38. public class EventLogger : LoggerBase
  39. {
  40. public Action<string>? OnLog;
  41. public EventLogger(Action<string>? onLog = null)
  42. {
  43. OnLog = onLog;
  44. }
  45. protected override void DoSend(string message)
  46. {
  47. OnLog?.Invoke(message);
  48. }
  49. }
  50. public class ConsoleLogger : LoggerBase
  51. {
  52. public ConsoleLogger()
  53. {
  54. LogTypes = new LogType[] { LogType.Information, LogType.Error };
  55. }
  56. protected override void DoSend(string message)
  57. {
  58. Console.WriteLine(message);
  59. }
  60. }
  61. public class LogFileLogger : LoggerBase
  62. {
  63. private static readonly object logfileLock = new();
  64. private string TmpFolder;
  65. private string _folder;
  66. public string Folder
  67. {
  68. get => _folder;
  69. [MemberNotNull(nameof(_folder), nameof(TmpFolder))]
  70. set
  71. {
  72. _folder = value;
  73. TmpFolder = Path.Combine(Folder, "Temp");
  74. if (Directory.Exists(TmpFolder))
  75. {
  76. Directory.CreateDirectory(TmpFolder);
  77. var files = Directory.GetFiles(TmpFolder);
  78. foreach (var file in files)
  79. File.Delete(file);
  80. }
  81. }
  82. }
  83. public LogFileLogger(string folder)
  84. {
  85. Folder = folder;
  86. }
  87. public override void Send(LogType logtype, string user, string message, Guid transaction)
  88. {
  89. if (logtype == LogType.Update)
  90. UpdateJournal(message);
  91. else
  92. base.Send(logtype, user, message, transaction);
  93. }
  94. protected override void DoSend(string message)
  95. {
  96. if (!string.IsNullOrEmpty(Folder))
  97. {
  98. UpdateLogFile(message);
  99. }
  100. }
  101. private void UpdateLogFile(string msg)
  102. {
  103. if (!Directory.Exists(Folder)) Directory.CreateDirectory(Folder);
  104. var filename = Path.Combine(Folder, string.Format("{0:yyyy-MM-dd}.log", DateTime.Today));
  105. try
  106. {
  107. lock (logfileLock)
  108. {
  109. using (var sw = new StreamWriter(filename, true, Encoding.UTF8, 65536))
  110. {
  111. sw.WriteLine(msg);
  112. sw.Close();
  113. }
  114. }
  115. }
  116. catch (Exception e)
  117. {
  118. Console.WriteLine("*** Failed to Update Log: " + e.Message);
  119. Console.WriteLine("*** Message: " + msg);
  120. }
  121. }
  122. private void UpdateJournal(string sql)
  123. {
  124. var filename = Path.Combine(Folder, string.Format("{0:yyyy-MM-dd}.sql", DateTime.Today));
  125. try
  126. {
  127. lock (logfileLock)
  128. {
  129. using (var sw = new StreamWriter(filename, true, Encoding.UTF8, 65536))
  130. {
  131. sw.WriteLine(sql);
  132. sw.Close();
  133. }
  134. }
  135. }
  136. catch (Exception e)
  137. {
  138. Console.WriteLine("*** Failed to Update SQL Journal: " + e.Message);
  139. Console.WriteLine("*** Message: " + sql);
  140. }
  141. }
  142. }
  143. public class NamedPipeLogger : LoggerBase
  144. {
  145. private PipeServer<string> _pipe;
  146. private string _name = "";
  147. public NamedPipeLogger(string name = "")
  148. {
  149. _name = string.IsNullOrWhiteSpace(name) ? Process.GetCurrentProcess().ProcessName : name;
  150. _pipe = new PipeServer<string>(_name, new MemoryPackFormatter<string>());
  151. _pipe.ClientConnected += _pipe_ClientConnected;
  152. _pipe.StartAsync();
  153. }
  154. private void _pipe_ClientConnected(object? sender, H.Pipes.Args.ConnectionEventArgs<string> e)
  155. {
  156. _pipe.WriteAsync("Connected to " + _name);
  157. }
  158. public override void Stop()
  159. {
  160. _pipe.StopAsync().Wait();
  161. }
  162. protected override void DoSend(string message)
  163. {
  164. if (_pipe != null)
  165. _pipe.WriteAsync(message);
  166. }
  167. }
  168. public static class MainLogger
  169. {
  170. private static List<LoggerBase> Loggers = new();
  171. public static void AddLogger(LoggerBase logger)
  172. {
  173. Loggers.Add(logger);
  174. }
  175. public static void RemoveLogger(LoggerBase logger)
  176. {
  177. Loggers.Remove(logger);
  178. }
  179. public static void Send(LogType logType, string user, string message, Guid transaction)
  180. {
  181. foreach(var logger in Loggers)
  182. {
  183. try
  184. {
  185. logger.Send(logType, user, message, transaction);
  186. }
  187. catch (Exception e)
  188. {
  189. Logger.Send(LogType.Error, "LOGERROR",
  190. $"Exception in Logger.Send ({e.Message}) Message=[{message}]");
  191. }
  192. }
  193. }
  194. public static void Stop()
  195. {
  196. foreach (var logger in Loggers)
  197. {
  198. logger.Stop();
  199. }
  200. }
  201. }
  202. }