.NET应用中使用Microsoft.Extensions.Logging如何统计错误日志数量?
在.NET中用Microsoft.Extensions.Logging获取错误日志计数的方案
默认的Microsoft.Extensions.Logging组件本身没有开箱即用的错误日志计数功能,官方并未提供内置的计数器来跟踪不同日志级别的条目数量。
不过你可以通过以下几种方案实现需求,比完全自定义ILogger更便捷:
1. 使用兼容的第三方日志提供程序
如果愿意切换到与Microsoft.Extensions.Logging兼容的成熟日志库(比如Serilog、NLog),这些库通常自带或有扩展支持日志计数功能。以Serilog为例,你可以通过自定义Sink或使用现成的扩展包,轻松统计Error/Critical级别的日志数量,同时保留原有日志框架的使用方式。
2. 轻量包装现有Logger实现
不需要从零实现完整的ILogger,只需包装现有LoggerProvider,在日志写入时统计错误级别即可:
步骤1:定义计数服务
public interface ILogCounter { int ErrorCount { get; } void IncrementErrorCount(); } public class LogCounter : ILogCounter { private int _errorCount; // 使用Interlocked保证线程安全 public int ErrorCount => Interlocked.CompareExchange(ref _errorCount, 0, 0); public void IncrementErrorCount() { Interlocked.Increment(ref _errorCount); } }
步骤2:实现计数Logger和Provider
public class CountingLogger : ILogger { private readonly ILogger _innerLogger; private readonly ILogCounter _logCounter; public CountingLogger(ILogger innerLogger, ILogCounter logCounter) { _innerLogger = innerLogger; _logCounter = logCounter; } public IDisposable BeginScope<TState>(TState state) => _innerLogger.BeginScope(state); public bool IsEnabled(LogLevel logLevel) => _innerLogger.IsEnabled(logLevel); public void Log<TState>(LogLevel logLevel, EventId eventId, TState state, Exception exception, Func<TState, Exception, string> formatter) { // 统计Error和Critical级别的日志 if (logLevel is LogLevel.Error or LogLevel.Critical) { _logCounter.IncrementErrorCount(); } // 转发日志到原Logger _innerLogger.Log(logLevel, eventId, state, exception, formatter); } } public class CountingLoggerProvider : ILoggerProvider { private readonly ILoggerProvider _innerProvider; private readonly ILogCounter _logCounter; public CountingLoggerProvider(ILoggerProvider innerProvider, ILogCounter logCounter) { _innerProvider = innerProvider; _logCounter = logCounter; } public ILogger CreateLogger(string categoryName) { var innerLogger = _innerProvider.CreateLogger(categoryName); return new CountingLogger(innerLogger, _logCounter); } public void Dispose() => _innerProvider.Dispose(); }
步骤3:注册服务
在Program.cs中添加注册代码:
// 注册计数服务 builder.Services.AddSingleton<ILogCounter, LogCounter>(); // 包装原有日志提供程序(这里以ConsoleLogger为例) var consoleProvider = new ConsoleLoggerProvider(new ConsoleLoggerSettings()); builder.Services.AddSingleton<ILoggerProvider>(sp => new CountingLoggerProvider(consoleProvider, sp.GetRequiredService<ILogCounter>()));
之后你就可以通过注入ILogCounter来获取当前的错误日志计数了。
3. 结合监控Metrics(如OpenTelemetry)
如果你的应用已经接入监控系统,可以通过OpenTelemetry来收集日志相关的指标。配置OpenTelemetry日志导出的同时,添加自定义计数器,每次错误日志写入时更新指标值。这种方案适合需要统一监控日志、指标的场景。
内容的提问来源于stack exchange,提问作者Sigurd Garshol
相关产品推荐
相关产品推荐

