Projekt

Obecné

Profil

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