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

ASP.NET Core 8迁移Serilog时ILogger无BeginScope定义的问题求助

解决Serilog适配BeginScope的报错问题

问题根源

你的代码里_logger是Serilog的ILogger接口,而BeginScope是Microsoft.Extensions.Logging(MS Logger)提供的扩展方法,两个接口分属不同库,自然找不到对应方法。


两种解决方案

方案1:继续使用MS Logger接口(推荐,保持原有编码习惯)

Serilog完全兼容MS Logger生态,直接注入MS Logger的ILogger<T>,既能用BeginScope,也能通过Serilog输出日志:

  1. 修改类的构造函数注入和成员变量:
// 添加MS Logger的命名空间
using Microsoft.Extensions.Logging;

internal class GlobalExceptionHandler(ILogger<GlobalExceptionHandler> logger, IWebHostEnvironment env) : IExceptionHandler
{
    private readonly ILogger<GlobalExceptionHandler> _logger = logger;
    private readonly IWebHostEnvironment _env = env.IsNotNull();

    // 其他代码不变

    private void LogErrorMessage1(LogEventLevel errorLogLevel, Exception exception, ExceptionDetails details)
    {
        var properties = new Dictionary<string, object>
        {
            { "TraceId", details.TraceId }
        };

        if (details.Errors != null)
        {
            properties.Add("Errors", details.Errors);
        }

        if (_env.IsDevelopment())
        {
            properties.Add("StackTrace", exception.StackTrace!.Trim());
        }

        // 此时BeginScope可正常使用,因为_logger是MS Logger接口
        using (_logger.BeginScope(properties))
        {
            // 两种日志输出方式选其一:
            // 方式1:用MS Logger的Log方法(自动适配Serilog输出)
            _logger.Log((LogLevel)errorLogLevel, "{title} | {details} | {traceId}", details.Title, details.Detail, details.TraceId);
            // 方式2:直接调用Serilog API
            // Serilog.Log.ForContext<GlobalExceptionHandler>().Write(errorLogLevel, "{title} | {details} | {traceId}", details.Title, details.Detail, details.TraceId);
        }
    }
}
  1. 确保Program.cs中已配置Serilog作为MS Logger的提供方:
var builder = WebApplication.CreateBuilder(args);

// 配置Serilog
builder.Host.UseSerilog((context, config) =>
{
    config.ReadFrom.Configuration(context.Configuration);
    // 其他Serilog自定义配置
});

// 后续代码不变

方案2:纯Serilog实现(抛弃MS Logger的BeginScope)

如果想完全使用Serilog原生API,用LogContext.PushProperty实现上下文属性注入(Serilog无BeginScope,对应功能由该方法实现):

修改LogErrorMessage1方法:

private void LogErrorMessage1(LogEventLevel errorLogLevel, Exception exception, ExceptionDetails details)
{
    // 批量注入上下文属性
    using var propertyScope = LogContext.Push(new PropertyEnricher("TraceId", details.TraceId));
    
    if (details.Errors != null)
    {
        LogContext.PushProperty("Errors", details.Errors);
    }

    if (_env.IsDevelopment())
    {
        LogContext.PushProperty("StackTrace", exception.StackTrace!.Trim());
    }

    // 直接用Serilog API输出日志
    _logger.Write(errorLogLevel, "{title} | {details} | {traceId}", details.Title, details.Detail, details.TraceId);
}

注意:使用LogContext必须在Serilog配置中启用上下文 enrichment:

builder.Host.UseSerilog((context, config) =>
{
    config.ReadFrom.Configuration(context.Configuration)
          .Enrich.FromLogContext(); // 必须添加此行,否则上下文属性不会被输出
});

内容的提问来源于stack exchange,提问作者santosh kumar patro

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 22:35:10