You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 14:21:21