手动实现文件日志记录器(.NET 示例代码)
显示原文'%20fill-opacity='.8'%20d='M3.256%203.913a3.083%203.083%200%200%200-.003%204.397L8%2012.998l4.743-4.684a3.085%203.085%200%200%200%20.001-4.4c-.6-.593-1.4-.914-2.233-.914a3.17%203.17%200%200%200-1.91.635L8%204.087l-.601-.452A3.17%203.17%200%200%200%205.489%203c-.834%200-1.634.321-2.233.913m10.19%205.111-4.748%204.69a.996.996%200%200%201-1.397%200L2.549%209.02a4.083%204.083%200%200%201%20.004-5.82A4.17%204.17%200%200%201%205.488%202c.907%200%201.787.29%202.512.835A4.17%204.17%200%200%201%2010.51%202c1.093%200%202.146.422%202.936%201.202a4.085%204.085%200%200%201%200%205.822'%20/%3e%3c/svg%3e)

| // 在原生的 Microsoft.Extensions.Logging 中没有内置的文件日志提供程序,但可以自定义实现: | |
| // Soccer.Infrastructure/Logging/FileLoggerProvider.cs | |
| public sealed class FileLoggerProvider : ILoggerProvider | |
| { | |
| private readonly StreamWriter _writer; | |
| private readonly object _lock = new(); | |
| public FileLoggerProvider(string path) | |
| { | |
| Directory.CreateDirectory(Path.GetDirectoryName(path)!); | |
| _writer = new StreamWriter(path, append: true) { AutoFlush = true }; | |
| } | |
| public ILogger CreateLogger(string categoryName) => | |
| new FileLogger(categoryName, _writer, _lock); | |
| public void Dispose() => _writer.Dispose(); | |
| } | |
| public sealed class FileLogger : ILogger | |
| { | |
| private readonly string _category; | |
| private readonly StreamWriter _writer; | |
| private readonly object _lock; | |
| public FileLogger(string category, StreamWriter writer, object @lock) | |
| { | |
| _category = category; | |
| _writer = writer; | |
| _lock = @lock; | |
| } | |
| public IDisposable? BeginScope(TState state) where TState : notnull => null; | |
| public bool IsEnabled(LogLevel logLevel) => logLevel >= LogLevel.Information; | |
| public void Log( | |
| LogLevel logLevel, EventId eventId, TState state, | |
| Exception? exception, Func formatter) | |
| { | |
| if (!IsEnabled(logLevel)) return; | |
| var line = $"{DateTime.UtcNow:O} [{logLevel}] {_category}: {formatter(state, exception)}"; | |
| if (exception != null) line += Environment.NewLine + exception; | |
| lock (_lock) _writer.WriteLine(line); | |
| } | |
| } | |
| // 然后在 Program.cs 中进行注册: | |
| // builder.Logging.AddProvider(new FileLoggerProvider("logs/app.log")); |
参与讨论