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

.NET 8中Serilog DI变更引发DiagnosticContext注入问题咨询

问题

在ASP.NET Core 8.0 Web API中,遇到Serilog与DiagnosticContext相关的运行时问题。此前正常运行的配置代码如下:

public static WebApplicationBuilder AddLogging(this WebApplicationBuilder builder, params ILogEventSink[] extraLogEventSinks)
{
    builder.Host
        .UseSerilog((context, services, configuration) =>
        {
            configuration
                .ReadFrom.Configuration(context.Configuration)
                .Enrich.WithMachineName()
                .Enrich.WithEnvironmentName()
                .Enrich.FromLogContext()
                .Enrich.With<OperationIdEnricher>()
                .Enrich.With<VersionNumberEnricher>()
                .Enrich.With(new ServiceNameEnricher(builder.Configuration))
                .Enrich.WithExceptionDetails()
                .Enrich.WithSensitiveDataMasking(options =>
                {
                    options.MaskProperties = ["Authorization"];
                    options.MaskingOperators.Clear();
                })
                .Filter.With(new HealthEndpointFilter())
                .WriteTo.ApplicationInsights(services.GetRequiredService<TelemetryConfiguration>(),
                    new OperationTelemetryConverter());

            foreach (var extraLogEventSink in extraLogEventSinks)
            {
                configuration.WriteTo.Sink(extraLogEventSink);
            }

            var minimumLoglevel = builder.Environment.IsDevelopment() ? LogEventLevel.Verbose : LogEventLevel.Error;
            if (builder.Environment.IsProduction())
            {
                configuration.WriteTo.Console(new CompactJsonFormatter(),
                    restrictedToMinimumLevel: minimumLoglevel);
            }
            else
            {
                configuration.WriteTo.Console(restrictedToMinimumLevel: minimumLoglevel);
            }
        });

    return builder;
}

现在API无法启动,抛出运行时错误:

System.InvalidOperationException: Unable to resolve service for type 'Serilog.Extensions.Hosting.DiagnosticContext' while attempting to activate 'Serilog.AspNetCore.RequestLoggingMiddleware'

尝试添加.Services.AddSingleton<DiagnosticContext>()到WebApplicationBuilder,又引发新错误:

Some services are not able to be constructed (Error while validating the service descriptor 'ServiceType:
Serilog.Extensions.Hosting.DiagnosticContext Lifetime: Singleton ImplementationType: Serilog.Extensions.Hosting.DiagnosticContext':
Unable to resolve service for type 'Serilog.ILogger' while attempting to activate 'Serilog.Extensions.Hosting.DiagnosticContext'.)

添加.Services.AddSingleton<DiagnosticContext>().AddSingleton(Log.Logger)后问题暂时解决,但有以下疑问:

  1. .NET 8的ASP.NET Core Web API包与Serilog有哪些变更导致此问题?
  2. 添加该Singleton Logger是否会破坏其他ILogger或ILogger依赖?
  3. 是否需要添加文档中的Logger创建代码?当前配置是否正确?using Serilog是否会引发Serilog.Log与Microsoft.Extensions.Logging的冲突?

解答

1. 问题根源:.NET 8与Serilog的适配变更

.NET 8调整了ASP.NET Core中间件的激活逻辑,而适配.NET 8的Serilog.AspNetCore版本,对DiagnosticContext等服务的注册方式做了修改。旧版本中UseSerilog可能会自动注册这些服务,但如果你的Serilog版本未及时升级,或者配置方式未触发自动注册逻辑(比如仅在委托内配置Logger,未让Serilog完全接管日志系统),就会导致DI容器无法解析DiagnosticContext,进而引发RequestLoggingMiddleware的激活失败。

2. 添加Singleton Logger的影响

不会破坏其他ILogger或ILogger<T>依赖。Serilog.AspNetCore已经将Microsoft.Extensions.Logging.ILogger<T>的实现替换为Serilog适配器,你添加的Serilog.ILogger单例是Serilog自身的核心日志实例,与.NET框架的日志接口属于不同类型,DI容器会正确区分两者,不会出现冲突或覆盖。

3. 配置正确性与命名空间冲突

  • 是否需要手动创建Logger:不需要。正确的做法是升级到适配.NET 8的最新Serilog.AspNetCore版本,此时调用builder.Host.UseSerilog(...)会自动注册DiagnosticContext、Serilog.ILogger等必要服务,无需手动添加单例。
  • 当前配置的问题:配置逻辑本身没问题,但缺少Serilog服务的自动注册环节。升级Serilog.AspNetCore版本后,移除手动添加的AddSingleton<DiagnosticContext>()和AddSingleton(Log.Logger)代码,即可正常启动。
  • 命名空间冲突问题:不会冲突。Serilog.Log是Serilog的静态日志类,Microsoft.Extensions.Logging下的是日志接口及实现,两者命名空间不同。若代码中出现歧义,可使用完全限定名(如Serilog.Log.Information(...)或Microsoft.Extensions.Logging.ILogger)明确区分。

内容的提问来源于stack exchange,提问作者Chaos

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 07:42:19