First commit
This commit is contained in:
123
Logger/FileLogger.cs
Normal file
123
Logger/FileLogger.cs
Normal file
@@ -0,0 +1,123 @@
|
||||
namespace Logger;
|
||||
|
||||
/// <summary>
|
||||
/// Logger implementation that writes to file with rotation support
|
||||
/// </summary>
|
||||
public class FileLogger : ILogger
|
||||
{
|
||||
private readonly FileLoggerOptions _options;
|
||||
private readonly object _lockObject = new();
|
||||
|
||||
public FileLogger(FileLoggerOptions options)
|
||||
{
|
||||
_options = options ?? throw new ArgumentNullException(nameof(options));
|
||||
EnsureLogDirectory();
|
||||
}
|
||||
|
||||
public void Trace(string message) => Log(LogLevel.Trace, message);
|
||||
public void Debug(string message) => Log(LogLevel.Debug, message);
|
||||
public void Info(string message) => Log(LogLevel.Info, message);
|
||||
public void Warning(string message) => Log(LogLevel.Warning, message);
|
||||
public void Error(string message) => Log(LogLevel.Error, message);
|
||||
public void Fatal(string message) => Log(LogLevel.Fatal, message);
|
||||
|
||||
public void Log(LogLevel level, string message)
|
||||
{
|
||||
if (level < _options.MinimumLevel)
|
||||
return;
|
||||
|
||||
var timestamp = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff");
|
||||
var formattedMessage = $"[{timestamp}] [{level}] {message}";
|
||||
|
||||
lock (_lockObject)
|
||||
{
|
||||
try
|
||||
{
|
||||
RotateFileIfNeeded();
|
||||
var logPath = GetLogFilePath();
|
||||
File.AppendAllText(logPath, formattedMessage + Environment.NewLine);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.Error.WriteLine($"Error writing to log file: {ex.Message}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void EnsureLogDirectory()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (!Directory.Exists(_options.LogDirectory))
|
||||
{
|
||||
Directory.CreateDirectory(_options.LogDirectory);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.Error.WriteLine($"Error creating log directory: {ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
private void RotateFileIfNeeded()
|
||||
{
|
||||
var logPath = GetLogFilePath();
|
||||
|
||||
if (!File.Exists(logPath))
|
||||
return;
|
||||
|
||||
var fileInfo = new FileInfo(logPath);
|
||||
if (fileInfo.Length >= _options.MaxFileSizeBytes)
|
||||
{
|
||||
ArchiveCurrentLog(logPath);
|
||||
}
|
||||
}
|
||||
|
||||
private void ArchiveCurrentLog(string currentLogPath)
|
||||
{
|
||||
try
|
||||
{
|
||||
var fileNameWithoutExtension = Path.GetFileNameWithoutExtension(_options.FileName);
|
||||
var fileExtension = Path.GetExtension(_options.FileName);
|
||||
var timestamp = DateTime.Now.ToString("yyyy-MM-dd_HH-mm-ss");
|
||||
var archivePath = Path.Combine(_options.LogDirectory,
|
||||
$"{fileNameWithoutExtension}_{timestamp}{fileExtension}");
|
||||
|
||||
File.Move(currentLogPath, archivePath, overwrite: true);
|
||||
|
||||
CleanupOldBackups();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.Error.WriteLine($"Error archiving log file: {ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
private void CleanupOldBackups()
|
||||
{
|
||||
try
|
||||
{
|
||||
var directory = new DirectoryInfo(_options.LogDirectory);
|
||||
var pattern = $"{Path.GetFileNameWithoutExtension(_options.FileName)}_*";
|
||||
|
||||
var backupFiles = directory.GetFiles(pattern)
|
||||
.OrderByDescending(f => f.CreationTime)
|
||||
.Skip(_options.MaxBackupFiles)
|
||||
.ToList();
|
||||
|
||||
foreach (var file in backupFiles)
|
||||
{
|
||||
file.Delete();
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.Error.WriteLine($"Error cleaning up old backup files: {ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
private string GetLogFilePath()
|
||||
{
|
||||
return Path.Combine(_options.LogDirectory, _options.FileName);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user