在Visual Studio 2022的Program.cs中配置Serilog作用域遇阻求助
ASP.NET Core + Angular 中 Serilog 日志配置及作用域问题解决
从你提供的代码来看,日志未生成、作用域无法正常工作主要是因为Serilog初始化流程错误、静态日志类未关联主机配置,以及作用域使用方式不对。以下是具体的修复步骤:
1. 确保安装必要的Serilog包
确认项目已安装以下NuGet包:
Serilog.AspNetCoreSerilog.Sinks.File
可以通过NuGet包管理器或命令行安装:
Install-Package Serilog.AspNetCore Install-Package Serilog.Sinks.File
2. 修正Serilog初始化流程
你的代码中没有将Serilog正确注册到ASP.NET Core主机,导致静态Log类无法使用配置好的接收器。需要在构建主机时就集成Serilog:
var builder = WebApplication.CreateBuilder(args); // 配置Serilog Log.Logger = new LoggerConfiguration() .Enrich.WithProperty("Application", "CMS_CORE_NG") .Enrich.WithProperty("MachineName", Environment.MachineName) .Enrich.WithProperty("CurrentManagedThreadId", Environment.CurrentManagedThreadId) .Enrich.WithProperty("OSVersion", Environment.OSVersion) .Enrich.WithProperty("Version", Environment.Version) .Enrich.WithProperty("UserName", Environment.UserName) .Enrich.WithProperty("ProcessId", Process.GetCurrentProcess().Id) .Enrich.WithProperty("ProcessName", Process.GetCurrentProcess().ProcessName) // 使用Serilog内置的滚动文件名模板,避免启动时固定文件名 .WriteTo.File( formatter: new CustomTextFormatter(), path: Path.Combine(builder.Environment.ContentRootPath, "Logs", "cms_core_ng_.txt"), rollingInterval: RollingInterval.Day, retainedFileCountLimit: 30) .ReadFrom.Configuration(builder.Configuration) .CreateLogger(); // 将Serilog设置为主机的日志提供器 builder.Host.UseSerilog(); // 其他服务配置(比如添加Controllers、Angular相关服务等) builder.Services.AddControllersWithViews(); var app = builder.Build(); // 作用域内的日志操作(修正后的方式) using (var scope = app.Services.CreateScope()) { var logger = scope.ServiceProvider.GetRequiredService<ILogger<Program>>(); try { int zero = 0; int result = 100 / zero; } catch (Exception ex) { // 使用依赖注入的ILogger,自动继承作用域上下文 logger.LogError(ex, "数据库初始化时发生错误"); } } // 中间件配置 if (!app.Environment.IsDevelopment()) { app.UseExceptionHandler("/Home/Error"); app.UseHsts(); } app.UseHttpsRedirection(); app.UseStaticFiles(); app.UseRouting(); app.UseAuthorization(); app.MapControllerRoute( name: "default", pattern: "{controller=Home}/{action=Index}/{id?}"); app.Run(); // 应用关闭时释放Serilog AppDomain.CurrentDomain.ProcessExit += (s, e) => Log.CloseAndFlush();
3. 修复作用域失效问题
你之前使用静态Log类无法正确关联作用域,原因是静态类不依赖于注入容器的作用域。正确的做法是通过依赖注入获取ILogger<T>实例,它会自动继承当前作用域的上下文信息。
如果需要手动添加作用域属性,可以使用BeginScope方法:
using (var scope = app.Services.CreateScope()) { var logger = scope.ServiceProvider.GetRequiredService<ILogger<Program>>(); // 手动添加作用域属性 using (logger.BeginScope(new Dictionary<string, object> { ["OperationId"] = Guid.NewGuid(), ["ScopeName"] = "DatabaseSeeding" })) { try { int zero = 0; int result = 100 / zero; } catch (Exception ex) { logger.LogError(ex, "数据库初始化时发生错误"); } } }
4. 其他注意事项
- 文件路径权限:确保应用程序对
Logs目录有写入权限,否则日志文件无法生成。 - 自定义格式化器:检查
CustomTextFormatter是否正确实现了ITextFormatter接口,避免因格式化器错误导致日志无法写入。 - 配置优先级:
ReadFrom.Configuration会覆盖代码中的配置,如果appsettings.json中有Serilog配置,需要确保配置正确。
内容的提问来源于stack exchange,提问作者Prasad
相关产品推荐
相关产品推荐

