ASP.NET Core日志API是否有类似Serilog ForContext的独立日志器创建方法
针对独立隔离日志器的实现方案
首先纠正一个常见误解:BeginScope并不会向全局日志器添加属性,默认实现是基于AsyncLocal的异步上下文隔离,不同异步上下文的Scope互不影响,只是在你用到的Rx.NET无上下文调度场景下,异步上下文容易丢失,所以不适用。
你可以选择两种方案实现完全隔离、不受线程上下文影响的带属性日志器:
- 方案1:基于微软
ILogger抽象封装自定义实现
通过装饰器模式即可实现需求,不需要修改现有日志框架配置:- 定义实现
ILogger接口的FixedPropertyLogger类,内部持有原始ILogger实例,同时存储需要附加的固定属性字典 - 在
Log方法的实现中,用using块包裹BeginScope调用传入固定属性,再执行原始日志写入逻辑,属性会自动附加到本次日志中 - 给
ILogger写扩展方法ForContext,直接返回封装好的FixedPropertyLogger实例,调用方式和Serilog原生API完全一致
这种方式完全基于微软日志抽象,不需要依赖特定日志框架实现,所有属性仅在当前封装的日志器实例生效,和其他日志器完全隔离,也不会受线程上下文、异步调度的影响。
- 定义实现
- 方案2:直接复用Serilog底层能力
如果你当前已经用Serilog作为微软日志抽象的底层实现,可以直接将Microsoft.Extensions.Logging.ILogger实例转换为Serilog原生的Serilog.ILogger,直接调用原生ForContext方法即可得到完全隔离的子日志器,不需要额外开发。
关于是否直接使用Serilog.ILogger的建议
是否替换取决于你的项目定位:
- 如果你的项目是业务应用,没有对外输出通用类库的需求,且未来不会更换日志框架,完全可以直接使用
Serilog.ILogger,原生API对结构化日志、上下文属性的支持更完善,没有抽象层的额外适配成本,用起来更灵活。 - 如果你的项目是通用类库,或者未来有更换日志框架的可能,保留微软
ILogger抽象即可,用上面提到的扩展封装方案就能满足你的需求。
内容的提问来源于stack exchange,提问作者ArXen42
相关产品推荐
相关产品推荐

