diff options
Diffstat (limited to 'src/Agent.App/Logging/RollingFileWriter.cs')
| -rw-r--r-- | src/Agent.App/Logging/RollingFileWriter.cs | 50 |
1 files changed, 50 insertions, 0 deletions
diff --git a/src/Agent.App/Logging/RollingFileWriter.cs b/src/Agent.App/Logging/RollingFileWriter.cs new file mode 100644 index 0000000..e155858 --- /dev/null +++ b/src/Agent.App/Logging/RollingFileWriter.cs @@ -0,0 +1,50 @@ +using System.Text; + +namespace Agent.App.Logging; + +internal sealed class RollingFileWriter : IDisposable +{ + private readonly object _sync = new(); + private readonly string _path; + private readonly long _maxBytes; + private readonly int _retainedFiles; + private StreamWriter _writer; + + public RollingFileWriter(string path, long maxBytes, int retainedFiles) + { + _path = path; + _maxBytes = maxBytes; + _retainedFiles = retainedFiles; + Directory.CreateDirectory(Path.GetDirectoryName(path)!); + _writer = Open(); + } + + public void WriteLine(string line) + { + lock (_sync) + { + if (_writer.BaseStream.Length >= _maxBytes) Rotate(); + _writer.WriteLine(line); + _writer.Flush(); + } + } + + private StreamWriter Open() => new(new FileStream(_path, FileMode.Append, FileAccess.Write, FileShare.Read), new UTF8Encoding(false)); + + private void Rotate() + { + _writer.Dispose(); + for (int index = _retainedFiles - 1; index >= 1; index--) + { + string source = $"{_path}.{index}"; + if (File.Exists(source)) File.Move(source, $"{_path}.{index + 1}", true); + } + if (File.Exists(_path)) File.Move(_path, $"{_path}.1", true); + _writer = Open(); + } + + public void Dispose() + { + lock (_sync) _writer.Dispose(); + } +} |
