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

.NET 6中如何注入ILogger<Startup>及日志配置问题

问题分析与解决方案

为什么Foo.Bar.Startup的日志级别配置不生效?

WebApplication.Logger对应的日志类别是Microsoft.AspNetCore.Hosting.WebApplication,并非你的Foo.Bar.Startup类。Serilog的MinimumLevel.Override配置是精确匹配日志类别的,所以你针对Foo.Bar.Startup的级别覆盖不会作用在app.Logger上,自然无法输出Information级别的日志。而配置Foo.Bar时能生效,大概率是配置联动导致的意外结果,但这并非精准的解决方式。

两种获取ILogger<Startup>的方法

方法一:构造函数注入

修改Startup类,通过构造函数注入ILogger<Startup>:

namespace Foo.Bar
{
    public class Startup
    {
        private IConfiguration Configuration { get; }
        private IWebHostEnvironment Environment { get; }
        private ILogger<Startup> Logger { get; }

        public Startup(IConfiguration configuration, IWebHostEnvironment environment, ILogger<Startup> logger)
        {
            Configuration = configuration;
            Environment = environment;
            Logger = logger;
        }
      
        public void ConfigureServices(IServiceCollection services)
        {
            
        }
        
        public void Configure(WebApplication app)
        {
            var appLifetime = app.Lifetime;            

            Logger.LogInformation("Started Configure Method.");

            appLifetime.ApplicationStarted.Register(() =>
            {
                Logger.LogInformation("Application started. {0}", DateTime.UtcNow);
            });
            
            appLifetime.ApplicationStopped.Register(() =>
            {
                Logger.LogInformation("Application stopped. {0}", DateTime.UtcNow);
            });      
        }
    }
}

然后在Program.cs中创建Startup实例时,先从临时服务容器解析日志实例:

Log.Logger = new LoggerConfiguration()
    .WriteTo.Console()
    .WriteTo.File("logs/log.txt", rollingInterval: RollingInterval.Day)
    .CreateBootstrapLogger();
Log.Information("Starting up!");

try
{
    var builder = WebApplication.CreateBuilder(args);
    builder.Host.UseSerilog((context, services, configuration) => configuration
                .ReadFrom.Configuration(context.Configuration)
                .Enrich.FromLogContext());
    
    // 构建临时服务提供者解析ILogger<Startup>
    using var tempServiceProvider = builder.Services.BuildServiceProvider();
    var startupLogger = tempServiceProvider.GetRequiredService<ILogger<Startup>>();
    var startup = new Startup(builder.Configuration, builder.Environment, startupLogger);
    
    startup.ConfigureServices(builder.Services);
    var app = builder.Build();
    startup.Configure(app);
    app.Run();    
}
catch (Exception ex)
{
    Log.Fatal(ex, "An unhandled exception occurred during bootstrapping");
}
finally
{
    Log.CloseAndFlush();
}

方法二:在Configure方法中直接获取

无需修改构造函数,直接从WebApplication的服务容器中获取ILogger<Startup>:

public void Configure(WebApplication app)
{
    var logger = app.Services.GetRequiredService<ILogger<Startup>>();
    var appLifetime = app.Lifetime;            

    logger.LogInformation("Started Configure Method.");

    appLifetime.ApplicationStarted.Register(() =>
    {
        logger.LogInformation("Application started. {0}", DateTime.UtcNow);
    });
    
    appLifetime.ApplicationStopped.Register(() =>
    {
        logger.LogInformation("Application stopped. {0}", DateTime.UtcNow);
    });      
}

使用以上任意一种方法后,你在appsettings.json中配置的"Foo.Bar.Startup": "Information"就会精准作用于ILogger<Startup>实例,对应的Information日志就能正常输出了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 15:35:20