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输出日志:
- 修改类的构造函数注入和成员变量:
// 添加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); } } }
- 确保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
相关产品推荐
相关产品推荐

