如何在ASP.NET Core自定义中间件中获取LogContext属性集合?
获取ASP.NET Core中Serilog LogContext的全部属性集合
要获取Serilog LogContext中的所有属性,由于其本身未提供公开的直接获取方法,你可以通过编写扩展方法遍历LogContext的scope链来实现,具体如下:
编写扩展方法
创建一个静态扩展类,遍历LogContext的当前scope链,收集所有属性:
using Serilog.Context; using Serilog.Core; using Serilog.Events; using System.Collections.Generic; using System.Linq; public static class LogContextExtensions { public static IReadOnlyDictionary<string, LogEventPropertyValue> GetAllProperties() { var propertyDict = new Dictionary<string, LogEventPropertyValue>(); var currentScope = LogContext.CurrentScope; // 遍历整个scope链,收集属性(后面的scope会覆盖前面同名属性) while (currentScope != null) { if (currentScope is ILogEventEnricher enricher) { var tempEvent = new LogEvent( timestamp: DateTimeOffset.Now, level: LogEventLevel.Information, exception: null, messageTemplate: MessageTemplate.Empty, properties: Enumerable.Empty<LogEventProperty>()); enricher.Enrich(tempEvent, new DefaultLogEventPropertyFactory()); foreach (var prop in tempEvent.Properties) { // 保留最新的属性值(后续scope的属性覆盖前面的) propertyDict[prop.Key] = prop.Value; } } currentScope = currentScope.Next; } return propertyDict; } }
使用扩展方法
在你的中间件或任意需要获取属性的代码位置,直接调用该扩展方法即可:
// 示例:在中间件中获取LogContext属性 var allLogProps = LogContextExtensions.GetAllProperties(); // 遍历输出属性 foreach (var prop in allLogProps) { // 这里可以根据需求处理属性,比如打印、存入变量等 Console.WriteLine($"Log属性:{prop.Key} = {prop.Value}"); }
说明
- LogContext的属性是通过链式scope维护的,每次
PushProperty都会创建一个新的scope节点,遍历链可以收集所有层级的属性。 - 若存在同名属性,后续scope中的属性值会覆盖前面的,这和Serilog LogContext的属性优先级逻辑一致。
- 该方法基于Serilog的公开接口实现,兼容Serilog 2.x及3.x版本,无需依赖内部未公开API。
内容的提问来源于stack exchange,提问作者likquietly
相关产品推荐
相关产品推荐

