1 |
74bd1e40
|
Pultak
|
using System.Globalization;
|
2 |
|
|
|
3 |
|
|
namespace LDClient.utils.loggers {
|
4 |
|
|
|
5 |
|
|
public abstract class ALogger : IDisposable {
|
6 |
|
|
|
7 |
|
|
private readonly LogVerbosity _verbosity;
|
8 |
|
|
private readonly LogFlow _logFlow;
|
9 |
|
|
|
10 |
|
|
private readonly Queue<Action> _queue = new();
|
11 |
|
|
private readonly ManualResetEvent _hasNewItems = new(false);
|
12 |
|
|
private readonly ManualResetEvent _terminate = new(false);
|
13 |
|
|
private readonly ManualResetEvent _waiting = new(false);
|
14 |
|
|
private readonly Thread _loggingThread;
|
15 |
|
|
|
16 |
|
|
private static readonly Lazy<ALogger> LazyLog = new(()
|
17 |
|
|
=> {
|
18 |
|
|
switch (Program.Config.LogFlowType) {
|
19 |
|
|
case LogFlow.File:
|
20 |
|
|
return new FileLogger();
|
21 |
|
|
case LogFlow.Console:
|
22 |
|
|
default:
|
23 |
|
|
return new ConsoleLogger();
|
24 |
|
|
|
25 |
|
|
}
|
26 |
|
|
}
|
27 |
|
|
);
|
28 |
|
|
|
29 |
|
|
public static ALogger Current => LazyLog.Value;
|
30 |
|
|
|
31 |
|
|
protected ALogger() {
|
32 |
|
|
_verbosity = Program.Config.LogVerbosityType;
|
33 |
|
|
_logFlow = Program.Config.LogFlowType;
|
34 |
|
|
_loggingThread = new Thread(ProcessQueue) { IsBackground = true };
|
35 |
|
|
_loggingThread.Start();
|
36 |
|
|
}
|
37 |
|
|
|
38 |
|
|
public void Info(string message) {
|
39 |
|
|
Log(message, LogType.Info);
|
40 |
|
|
}
|
41 |
|
|
|
42 |
|
|
public void Debug(string message) {
|
43 |
|
|
Log(message, LogType.Debug);
|
44 |
|
|
}
|
45 |
|
|
|
46 |
|
|
public void Error(string message) {
|
47 |
|
|
Log(message, LogType.Error);
|
48 |
|
|
}
|
49 |
|
|
|
50 |
|
|
public void Error(Exception e) {
|
51 |
|
|
if (_verbosity != LogVerbosity.None) {
|
52 |
|
|
Log(UnwrapExceptionMessages(e), LogType.Error);
|
53 |
|
|
}
|
54 |
|
|
}
|
55 |
|
|
|
56 |
|
|
public override string ToString() => $"Logger settings: [Type: {this.GetType().Name}, Verbosity: {_verbosity}, ";
|
57 |
|
|
|
58 |
|
|
protected abstract void CreateLog(string message);
|
59 |
|
|
|
60 |
|
|
public void Flush() => _waiting.WaitOne();
|
61 |
|
|
|
62 |
|
|
public void Dispose() {
|
63 |
|
|
_terminate.Set();
|
64 |
|
|
_loggingThread.Join();
|
65 |
|
|
}
|
66 |
|
|
|
67 |
|
|
protected virtual string ComposeLogRow(string message, LogType logType) =>
|
68 |
|
|
$"[{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss,fff", CultureInfo.InvariantCulture)} - {logType}] - {message}";
|
69 |
|
|
|
70 |
|
|
protected virtual string UnwrapExceptionMessages(Exception? ex) =>
|
71 |
|
|
ex == null ? string.Empty : $"{ex}, Inner exception: {UnwrapExceptionMessages(ex.InnerException)} ";
|
72 |
|
|
|
73 |
|
|
|
74 |
|
|
private void ProcessQueue() {
|
75 |
|
|
while (true) {
|
76 |
|
|
_waiting.Set();
|
77 |
|
|
var i = WaitHandle.WaitAny(new WaitHandle[] { _hasNewItems, _terminate });
|
78 |
|
|
if (i == 1) return;
|
79 |
|
|
_hasNewItems.Reset();
|
80 |
|
|
_waiting.Reset();
|
81 |
|
|
|
82 |
|
|
Queue<Action> queueCopy;
|
83 |
|
|
lock (_queue) {
|
84 |
|
|
queueCopy = new Queue<Action>(_queue);
|
85 |
|
|
_queue.Clear();
|
86 |
|
|
}
|
87 |
|
|
|
88 |
|
|
foreach (var log in queueCopy) {
|
89 |
|
|
log();
|
90 |
|
|
}
|
91 |
|
|
}
|
92 |
|
|
}
|
93 |
|
|
|
94 |
|
|
private void Log(string message, LogType logType) {
|
95 |
|
|
if (string.IsNullOrEmpty(message))
|
96 |
|
|
return;
|
97 |
|
|
|
98 |
|
|
var logRow = ComposeLogRow(message, logType);
|
99 |
|
|
System.Diagnostics.Debug.WriteLine(logRow);
|
100 |
|
|
|
101 |
|
|
if (_verbosity == LogVerbosity.Full) {
|
102 |
|
|
lock (_queue)
|
103 |
|
|
_queue.Enqueue(() => CreateLog(logRow));
|
104 |
|
|
|
105 |
|
|
_hasNewItems.Set();
|
106 |
|
|
}
|
107 |
|
|
}
|
108 |
|
|
}
|
109 |
|
|
}
|