Revize 74bd1e40
Přidáno uživatelem Pultak před více než 2 roky(ů)
ld_client/LDClient/Program.cs | ||
---|---|---|
1 |
using LDClient; |
|
2 |
using System;
|
|
1 |
using LDClient.utils;
|
|
2 |
using LDClient.utils.loggers;
|
|
3 | 3 |
|
4 |
namespace LDClient; |
|
4 | 5 |
|
5 |
class Program { |
|
6 |
internal class Program {
|
|
6 | 7 |
|
7 |
public static LDClient.ConfigLoader Config { get; set; }
|
|
8 |
public static ConfigLoader Config { get; set; } = null!;
|
|
8 | 9 |
|
9 | 10 |
// Main Method |
10 |
static public void Main() {
|
|
11 |
Config = new LDClient.ConfigLoader();
|
|
11 |
public static void Main() {
|
|
12 |
Config = new ConfigLoader(); |
|
12 | 13 |
|
13 | 14 |
while (true) { |
14 |
Logger.Current.Info("Ok"); |
|
15 |
Logger.Current.Debug("Debug"); |
|
16 |
Logger.Current.Error("Error"); |
|
15 |
ALogger.Current.Info("Ok");
|
|
16 |
ALogger.Current.Debug("Debug");
|
|
17 |
ALogger.Current.Error("Error");
|
|
17 | 18 |
} |
18 | 19 |
} |
19 | 20 |
} |
ld_client/LDClient/appsettings.json | ||
---|---|---|
7 | 7 |
"Error": "Red" |
8 | 8 |
} |
9 | 9 |
}, |
10 |
"LogChunkSize": 1000,
|
|
11 |
"LogChunkMaxCount": 1,
|
|
12 |
"LogArchiveMaxCount": 1, |
|
13 |
"LogCleanupPeriod": 1000,
|
|
10 |
"LogChunkSize": 2097152,
|
|
11 |
"LogChunkMaxCount": 2,
|
|
12 |
"LogArchiveMaxCount": 10,
|
|
13 |
"LogCleanupPeriod": 10, |
|
14 | 14 |
"LogVerbosityType": 2, |
15 | 15 |
"LogFlowType": 1 |
16 | 16 |
} |
ld_client/LDClient/utils/ConfigLoader.cs | ||
---|---|---|
1 |
using System; |
|
2 |
using System.Collections.Generic; |
|
3 |
using System.Configuration; |
|
4 |
using System.Linq; |
|
5 |
using System.Text; |
|
6 |
using System.Threading.Tasks; |
|
1 |
using LDClient.utils.loggers; |
|
7 | 2 |
using Microsoft.Extensions.Configuration; |
8 |
using Microsoft.Extensions.Configuration.Json; |
|
9 | 3 |
|
10 |
namespace LDClient { |
|
11 |
internal class ConfigurationLoader { |
|
12 |
|
|
13 |
private readonly string LOGGING_SECTION = "Logging"; |
|
4 |
namespace LDClient.utils { |
|
5 |
internal class ConfigLoader { |
|
6 |
private const string LoggingSection = "Logging"; |
|
14 | 7 |
|
15 | 8 |
|
16 | 9 |
public int LogChunkSize { get; set; } |
... | ... | |
19 | 12 |
|
20 | 13 |
public int LogCleanupPeriod { get; set; } |
21 | 14 |
|
22 |
private LogVerbosity _logVerbosity = LogVerbosity.Full; |
|
23 |
public LogVerbosity LogVerbosityType { |
|
24 |
get { |
|
25 |
return _logVerbosity; |
|
26 |
} |
|
27 |
set |
|
28 |
{ _logVerbosity = value; |
|
29 |
} |
|
30 |
} |
|
15 |
public LogVerbosity LogVerbosityType { get; set; } = LogVerbosity.Full; |
|
31 | 16 |
|
32 |
private LogFlow _logFlowType = LogFlow.Console; |
|
33 |
public LogFlow LogFlowType { |
|
34 |
get { |
|
35 |
return _logFlowType; |
|
36 |
} |
|
37 |
set { |
|
38 |
_logFlowType = value; |
|
39 |
} |
|
40 |
} |
|
17 |
public LogFlow LogFlowType { get; set; } = LogFlow.Console; |
|
41 | 18 |
|
42 |
public ConfigurationLoader() {
|
|
19 |
public ConfigLoader() { |
|
43 | 20 |
var configuration = new ConfigurationBuilder() |
44 | 21 |
.AddJsonFile("appsettings.json") |
45 | 22 |
.Build(); |
46 | 23 |
ReadAllSettings(configuration); |
47 | 24 |
} |
48 | 25 |
|
49 |
void ReadAllSettings(IConfigurationRoot configuration) { |
|
26 |
private void ReadAllSettings(IConfigurationRoot configuration) {
|
|
50 | 27 |
|
51 | 28 |
try { |
52 |
var logging = configuration.GetSection(LOGGING_SECTION);
|
|
29 |
var logging = configuration.GetSection(LoggingSection);
|
|
53 | 30 |
//TODO: Exception handling |
54 |
LogChunkSize = Int32.Parse(logging["LogChunkSize"]);
|
|
55 |
LogChunkMaxCount = Int32.Parse(logging["LogChunkMaxCount"]);
|
|
56 |
LogArchiveMaxCount = Int32.Parse(logging["LogArchiveMaxCount"]);
|
|
57 |
LogCleanupPeriod = Int32.Parse(logging["LogCleanupPeriod"]);
|
|
58 |
LogFlowType = (LogFlow)Int32.Parse(logging["LogFlowType"]);
|
|
59 |
LogVerbosityType = (LogVerbosity)Int32.Parse(logging["LogVerbosityType"]);
|
|
31 |
LogChunkSize = int.Parse(logging["LogChunkSize"]);
|
|
32 |
LogChunkMaxCount = int.Parse(logging["LogChunkMaxCount"]);
|
|
33 |
LogArchiveMaxCount = int.Parse(logging["LogArchiveMaxCount"]);
|
|
34 |
LogCleanupPeriod = int.Parse(logging["LogCleanupPeriod"]);
|
|
35 |
LogFlowType = (LogFlow)int.Parse(logging["LogFlowType"]);
|
|
36 |
LogVerbosityType = (LogVerbosity)int.Parse(logging["LogVerbosityType"]);
|
|
60 | 37 |
|
61 | 38 |
|
62 | 39 |
Console.WriteLine("Configuration successfully loaded!"); |
63 | 40 |
} catch (FormatException e) { |
64 | 41 |
//Console.WriteLine("Error reading app settings"); |
65 | 42 |
//TODO: remove stacktrace print in production |
66 |
Console.WriteLine("Error during reading of configuration occured!" + e); |
|
43 |
Console.WriteLine("Error during reading of configuration occurred!" + e);
|
|
67 | 44 |
throw new IOException("Reading of configuration file failed! " + e); |
68 | 45 |
} |
69 | 46 |
} |
ld_client/LDClient/utils/Logger.cs | ||
---|---|---|
1 |
using System; |
|
2 |
using System.Collections.Generic; |
|
3 |
using System.Globalization; |
|
4 |
using System.IO.Compression; |
|
5 |
using System.Linq; |
|
6 |
using System.Text; |
|
7 |
using System.Threading.Tasks; |
|
8 |
|
|
9 |
namespace LDClient { |
|
10 |
enum LogVerbosity { |
|
11 |
None = 0, |
|
12 |
Exceptions, |
|
13 |
Full |
|
14 |
} |
|
15 |
|
|
16 |
public enum LogType { |
|
17 |
Info = 0, |
|
18 |
Debug, |
|
19 |
Error |
|
20 |
} |
|
21 |
|
|
22 |
enum LogFlow { |
|
23 |
Console = 0, |
|
24 |
File |
|
25 |
} |
|
26 |
|
|
27 |
|
|
28 |
public abstract class Logger : IDisposable { |
|
29 |
|
|
30 |
private LogVerbosity _verbosity; |
|
31 |
private LogFlow _logFlow; |
|
32 |
|
|
33 |
private Queue<Action> _queue = new Queue<Action>(); |
|
34 |
private ManualResetEvent _hasNewItems = new ManualResetEvent(false); |
|
35 |
private ManualResetEvent _terminate = new ManualResetEvent(false); |
|
36 |
private ManualResetEvent _waiting = new ManualResetEvent(false); |
|
37 |
private Thread _loggingThread; |
|
38 |
|
|
39 |
private static readonly Lazy<Logger> _lazyLog = new Lazy<Logger>(() |
|
40 |
=> { |
|
41 |
switch (Program.Config.LogFlowType) { |
|
42 |
case LogFlow.File: |
|
43 |
return new FileLogger(); |
|
44 |
case LogFlow.Console: |
|
45 |
default: |
|
46 |
return new ConsoleLogger(); |
|
47 |
|
|
48 |
} |
|
49 |
} |
|
50 |
); |
|
51 |
|
|
52 |
public static Logger Current => _lazyLog.Value; |
|
53 |
|
|
54 |
protected Logger() { |
|
55 |
_verbosity = (LogVerbosity)Program.Config.LogVerbosityType; |
|
56 |
_logFlow = (LogFlow)Program.Config.LogFlowType; |
|
57 |
_loggingThread = new Thread(new ThreadStart(ProcessQueue)) { IsBackground = true }; |
|
58 |
_loggingThread.Start(); |
|
59 |
} |
|
60 |
|
|
61 |
public void Info(string message) { |
|
62 |
Log(message, LogType.Info); |
|
63 |
} |
|
64 |
|
|
65 |
public void Debug(string message) { |
|
66 |
Log(message, LogType.Debug); |
|
67 |
} |
|
68 |
|
|
69 |
public void Error(string message) { |
|
70 |
Log(message, LogType.Error); |
|
71 |
} |
|
72 |
|
|
73 |
public void Error(Exception e) { |
|
74 |
if (_verbosity != LogVerbosity.None) { |
|
75 |
Log(UnwrapExceptionMessages(e), LogType.Error); |
|
76 |
} |
|
77 |
} |
|
78 |
|
|
79 |
public override string ToString() => $"Logger settings: [Type: {this.GetType().Name}, Verbosity: {_verbosity}, "; |
|
80 |
|
|
81 |
protected abstract void CreateLog(string message); |
|
82 |
|
|
83 |
public void Flush() => _waiting.WaitOne(); |
|
84 |
|
|
85 |
public void Dispose() { |
|
86 |
_terminate.Set(); |
|
87 |
_loggingThread.Join(); |
|
88 |
} |
|
89 |
|
|
90 |
protected virtual string ComposeLogRow(string message, LogType logType) => |
|
91 |
$"[{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss,fff", CultureInfo.InvariantCulture)} - {logType}] - {message}"; |
|
92 |
|
|
93 |
protected virtual string UnwrapExceptionMessages(Exception ex) { |
|
94 |
if (ex == null) |
|
95 |
return string.Empty; |
|
96 |
|
|
97 |
return $"{ex}, Inner exception: {UnwrapExceptionMessages(ex.InnerException)} "; |
|
98 |
} |
|
99 |
|
|
100 |
private void ProcessQueue() { |
|
101 |
while (true) { |
|
102 |
_waiting.Set(); |
|
103 |
int i = WaitHandle.WaitAny(new WaitHandle[] { _hasNewItems, _terminate }); |
|
104 |
if (i == 1) return; |
|
105 |
_hasNewItems.Reset(); |
|
106 |
_waiting.Reset(); |
|
107 |
|
|
108 |
Queue<Action> queueCopy; |
|
109 |
lock (_queue) { |
|
110 |
queueCopy = new Queue<Action>(_queue); |
|
111 |
_queue.Clear(); |
|
112 |
} |
|
113 |
|
|
114 |
foreach (var log in queueCopy) { |
|
115 |
log(); |
|
116 |
} |
|
117 |
} |
|
118 |
} |
|
119 |
|
|
120 |
private void Log(string message, LogType logType) { |
|
121 |
if (string.IsNullOrEmpty(message)) |
|
122 |
return; |
|
123 |
|
|
124 |
var logRow = ComposeLogRow(message, logType); |
|
125 |
System.Diagnostics.Debug.WriteLine(logRow); |
|
126 |
|
|
127 |
if (_verbosity == LogVerbosity.Full) { |
|
128 |
lock (_queue) |
|
129 |
_queue.Enqueue(() => CreateLog(logRow)); |
|
130 |
|
|
131 |
_hasNewItems.Set(); |
|
132 |
} |
|
133 |
} |
|
134 |
} |
|
135 |
|
|
136 |
class ConsoleLogger : Logger { |
|
137 |
protected override void CreateLog(string message) { |
|
138 |
Console.WriteLine(message); |
|
139 |
} |
|
140 |
} |
|
141 |
|
|
142 |
|
|
143 |
class FileLogger : Logger { |
|
144 |
|
|
145 |
private const string LogFolderName = "logs"; |
|
146 |
private const string LogFileName = "app_info.log"; |
|
147 |
private readonly int _logChunkSize = Program.Config.LogChunkSize; |
|
148 |
private readonly int _logChunkMaxCount = Program.Config.LogChunkMaxCount; |
|
149 |
private readonly int _logArchiveMaxCount = Program.Config.LogArchiveMaxCount; |
|
150 |
private readonly int _logCleanupPeriod = Program.Config.LogCleanupPeriod; |
|
151 |
|
|
152 |
private readonly string logFolderPath = Path.Combine(Path.GetTempPath(), $"ldClient\\{LogFolderName}"); |
|
153 |
|
|
154 |
private bool _logDirExists = false; |
|
155 |
|
|
156 |
protected override void CreateLog(string message) { |
|
157 |
|
|
158 |
if (!_logDirExists) { |
|
159 |
_logDirExists = Directory.Exists(logFolderPath); |
|
160 |
if (!_logDirExists) { |
|
161 |
Directory.CreateDirectory(logFolderPath); |
|
162 |
_logDirExists = true; |
|
163 |
} |
|
164 |
} |
|
165 |
|
|
166 |
var logFilePath = Path.Combine(logFolderPath, LogFileName); |
|
167 |
|
|
168 |
Rotate(logFilePath); |
|
169 |
|
|
170 |
using (var sw = File.AppendText(logFilePath)) { |
|
171 |
sw.WriteLine(message); |
|
172 |
} |
|
173 |
} |
|
174 |
|
|
175 |
private void Rotate(string filePath) { |
|
176 |
if (!File.Exists(filePath)) |
|
177 |
return; |
|
178 |
|
|
179 |
var fileInfo = new FileInfo(filePath); |
|
180 |
if (fileInfo.Length < _logChunkSize) |
|
181 |
return; |
|
182 |
|
|
183 |
var fileTime = DateTime.Now.ToString("dd-MM-yyyy,hh-mm-ss,fff"); |
|
184 |
var rotatedPath = filePath.Replace(".log", $".{fileTime}"); |
|
185 |
File.Move(filePath, rotatedPath); |
|
186 |
|
|
187 |
var folderPath = Path.GetDirectoryName(rotatedPath); |
|
188 |
var logFolderContent = new DirectoryInfo(folderPath).GetFileSystemInfos(); |
|
189 |
|
|
190 |
var chunks = logFolderContent.Where(x => !x.Extension.Equals(".zip", StringComparison.OrdinalIgnoreCase)); |
|
191 |
|
|
192 |
if (chunks.Count() <= _logChunkMaxCount) |
|
193 |
return; |
|
194 |
|
|
195 |
var archiveFolderInfo = Directory.CreateDirectory(Path.Combine(Path.GetDirectoryName(rotatedPath), $"{LogFolderName}_{fileTime}")); |
|
196 |
|
|
197 |
foreach (var chunk in chunks) { |
|
198 |
var destination = Path.Combine(archiveFolderInfo.FullName, chunk.Name); |
|
199 |
Directory.Move(chunk.FullName, destination); |
|
200 |
} |
|
201 |
|
|
202 |
ZipFile.CreateFromDirectory(archiveFolderInfo.FullName, Path.Combine(folderPath, $"{LogFolderName}_{fileTime}.zip")); |
|
203 |
Directory.Delete(archiveFolderInfo.FullName, true); |
|
204 |
|
|
205 |
var archives = logFolderContent.Where(x => x.Extension.Equals(".zip", StringComparison.OrdinalIgnoreCase)).ToArray(); |
|
206 |
|
|
207 |
if (archives.Count() <= _logArchiveMaxCount) |
|
208 |
return; |
|
209 |
|
|
210 |
var oldestArchive = archives.OrderBy(x => x.CreationTime).First(); |
|
211 |
var cleanupDate = oldestArchive.CreationTime.AddDays(_logCleanupPeriod); |
|
212 |
if (DateTime.Compare(cleanupDate, DateTime.Now) <= 0) { |
|
213 |
foreach (var file in logFolderContent) { |
|
214 |
file.Delete(); |
|
215 |
} |
|
216 |
} else |
|
217 |
File.Delete(oldestArchive.FullName); |
|
218 |
|
|
219 |
} |
|
220 |
|
|
221 |
public override string ToString() => $"{base.ToString()}, Chunk Size: {_logChunkSize}, Max chunk count: {_logChunkMaxCount}, Max log archive count: {_logArchiveMaxCount}, Cleanup period: {_logCleanupPeriod} days]"; |
|
222 |
} |
|
223 |
|
|
224 |
|
|
225 |
} |
ld_client/LDClient/utils/loggers/ALogger.cs | ||
---|---|---|
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 |
} |
ld_client/LDClient/utils/loggers/ConsoleLogger.cs | ||
---|---|---|
1 |
namespace LDClient.utils.loggers { |
|
2 |
public class ConsoleLogger : ALogger { |
|
3 |
protected override void CreateLog(string message) { |
|
4 |
Console.WriteLine(message); |
|
5 |
} |
|
6 |
} |
|
7 |
} |
ld_client/LDClient/utils/loggers/FileLogger.cs | ||
---|---|---|
1 |
using System.IO.Compression; |
|
2 |
|
|
3 |
namespace LDClient.utils.loggers; |
|
4 |
|
|
5 |
public class FileLogger : ALogger { |
|
6 |
|
|
7 |
private const string LogFolderName = "logs"; |
|
8 |
private const string LogFileName = "app_info.log"; |
|
9 |
private readonly int _logChunkSize = Program.Config.LogChunkSize; |
|
10 |
private readonly int _logChunkMaxCount = Program.Config.LogChunkMaxCount; |
|
11 |
private readonly int _logArchiveMaxCount = Program.Config.LogArchiveMaxCount; |
|
12 |
private readonly int _logCleanupPeriod = Program.Config.LogCleanupPeriod; |
|
13 |
|
|
14 |
private const string LogFolderPath = $"ldClient\\{LogFolderName}"; |
|
15 |
|
|
16 |
private bool _logDirExists; |
|
17 |
|
|
18 |
protected override void CreateLog(string message) { |
|
19 |
|
|
20 |
if (!_logDirExists) { |
|
21 |
_logDirExists = Directory.Exists(LogFolderPath); |
|
22 |
if (!_logDirExists) { |
|
23 |
Directory.CreateDirectory(LogFolderPath); |
|
24 |
_logDirExists = true; |
|
25 |
} |
|
26 |
} |
|
27 |
|
|
28 |
var logFilePath = Path.Combine(LogFolderPath, LogFileName); |
|
29 |
|
|
30 |
Rotate(logFilePath); |
|
31 |
|
|
32 |
using var sw = File.AppendText(logFilePath); |
|
33 |
sw.WriteLine(message); |
|
34 |
} |
|
35 |
|
|
36 |
private void Rotate(string filePath) { |
|
37 |
if (!File.Exists(filePath)) { |
|
38 |
return; |
|
39 |
} |
|
40 |
|
|
41 |
var fileInfo = new FileInfo(filePath); |
|
42 |
if (fileInfo.Length < _logChunkSize) { |
|
43 |
return; |
|
44 |
} |
|
45 |
var fileTime = DateTime.Now.ToString("dd-MM-yyyy,hh-mm-ss,fff"); |
|
46 |
var rotatedPath = filePath.Replace(".log", $".{fileTime}"); |
|
47 |
File.Move(filePath, rotatedPath); |
|
48 |
|
|
49 |
var folderPath = Path.GetDirectoryName(rotatedPath); |
|
50 |
var logFolderContent = new DirectoryInfo(folderPath ?? string.Empty).GetFileSystemInfos(); |
|
51 |
|
|
52 |
var chunks = logFolderContent.Where(x => |
|
53 |
!x.Extension.Equals(".zip", StringComparison.OrdinalIgnoreCase)); |
|
54 |
|
|
55 |
if (chunks.Count() <= _logChunkMaxCount) { |
|
56 |
return; |
|
57 |
} |
|
58 |
|
|
59 |
Archive(chunks, rotatedPath, fileTime, folderPath); |
|
60 |
DeleteOldArchives(logFolderContent); |
|
61 |
} |
|
62 |
|
|
63 |
private void Archive(IEnumerable<FileSystemInfo> chunks, string rotatedPath, string fileTime, string? folderPath) { |
|
64 |
|
|
65 |
var archiveFolderInfo = Directory.CreateDirectory(Path.Combine(Path.GetDirectoryName(rotatedPath) ?? LogFolderPath, $"{LogFolderName}_{fileTime}")); |
|
66 |
|
|
67 |
foreach (var chunk in chunks) { |
|
68 |
var destination = Path.Combine(archiveFolderInfo.FullName, chunk.Name); |
|
69 |
Directory.Move(chunk.FullName, destination); |
|
70 |
} |
|
71 |
|
|
72 |
ZipFile.CreateFromDirectory(archiveFolderInfo.FullName, Path.Combine(folderPath ?? LogFolderPath, $"{LogFolderName}_{fileTime}.zip")); |
|
73 |
Directory.Delete(archiveFolderInfo.FullName, true); |
|
74 |
} |
|
75 |
|
|
76 |
private void DeleteOldArchives(FileSystemInfo[] logFolderContent) { |
|
77 |
|
|
78 |
var archives = logFolderContent.Where(x => x.Extension.Equals(".zip", StringComparison.OrdinalIgnoreCase)).ToArray(); |
|
79 |
|
|
80 |
if (archives.Length <= _logArchiveMaxCount) |
|
81 |
return; |
|
82 |
|
|
83 |
var oldestArchive = archives.OrderBy(x => x.CreationTime).First(); |
|
84 |
var cleanupDate = oldestArchive.CreationTime.AddDays(_logCleanupPeriod); |
|
85 |
if (DateTime.Compare(cleanupDate, DateTime.Now) <= 0) { |
|
86 |
foreach (var file in logFolderContent) { |
|
87 |
file.Delete(); |
|
88 |
} |
|
89 |
} else { |
|
90 |
File.Delete(oldestArchive.FullName); |
|
91 |
} |
|
92 |
} |
|
93 |
|
|
94 |
public override string ToString() => $"{base.ToString()}, Chunk Size: {_logChunkSize}, Max chunk count: {_logChunkMaxCount}, Max log archive count: {_logArchiveMaxCount}, Cleanup period: {_logCleanupPeriod} days]"; |
|
95 |
} |
ld_client/LDClient/utils/loggers/LogFlow.cs | ||
---|---|---|
1 |
namespace LDClient.utils.loggers { |
|
2 |
public enum LogFlow { |
|
3 |
Console = 0, |
|
4 |
File |
|
5 |
} |
|
6 |
} |
ld_client/LDClient/utils/loggers/LogType.cs | ||
---|---|---|
1 |
namespace LDClient.utils.loggers { |
|
2 |
public enum LogType { |
|
3 |
Info = 0, |
|
4 |
Debug, |
|
5 |
Error |
|
6 |
} |
|
7 |
} |
ld_client/LDClient/utils/loggers/LogVerbosity.cs | ||
---|---|---|
1 |
namespace LDClient.utils.loggers { |
|
2 |
public enum LogVerbosity { |
|
3 |
None = 0, |
|
4 |
Exceptions, |
|
5 |
Full |
|
6 |
} |
|
7 |
} |
Také k dispozici: Unified diff
re #9439 logger code refactoring