.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
相关产品推荐
相关产品推荐

