Projekt

Obecné

Profil

Stáhnout (3.42 KB) Statistiky
| Větev: | Tag: | Revize:
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
}