You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何确定Serilog配置中的可用Enrichers并实现动态值注入

Serilog 动态Enricher实现相关问题解答

已注册Enrichers枚举需求实现方案

Serilog 公开API没有直接提供枚举已注册Enrichers的方法,配置完成后的Enricher默认封装在ILogger实现类的内部处理链路中,不对外暴露。你可以通过两种方式实现需求:

  • 配置阶段自行维护自定义Enricher的注册列表:新增一个CustomEnricherRegistry静态类,每次调用Enrich.With()添加你自定义的Enricher实例时,同步将实例存入该静态类的集合中,后续需要赋值时直接从集合中取出对应实例即可,该方案无兼容性风险,是最稳妥的实现方式。
  • 反射读取内部字段(不推荐):Serilog.Core.Logger类包含私有字段_messageTemplateProcessors,该字段存储了所有注册的日志事件处理器,其中就包含所有Enricher实例,你可以通过反射读取该字段后筛选出你自定义的Enricher类型即可,该方案依赖Serilog内部实现,版本升级可能会失效。

更简化的动态值注入Enricher实现方案

不需要通过枚举全量Enrichers的方式实现动态赋值,直接调整自定义Enricher的结构即可,参考实现如下:

public class DynamicValueEnricher : ILogEventEnricher
{
    // 全局共享动态值用静态容器,需要实例隔离则改为实例属性
    public static ConcurrentDictionary<string, object> RuntimeValues { get; } = new();

    public void Enrich(LogEvent logEvent, ILogEventPropertyFactory propertyFactory)
    {
        foreach (var (key, value) in RuntimeValues)
        {
            logEvent.AddPropertyIfAbsent(propertyFactory.CreateProperty(key, value));
        }
    }

    // 对外暴露操作动态值的入口
    public static void SetValue(string key, object value) => RuntimeValues[key] = value;
    public static void RemoveValue(string key) => RuntimeValues.TryRemove(key, out _);
}

配置时注册该Enricher后,后续需要动态赋值时直接调用DynamicValueEnricher.SetValue("属性名", 属性值)即可,完全不需要枚举已注册的Enricher,实现逻辑更简单。

其他补充方案

如果你要注入的动态值是和作用域/请求绑定的,LogContext本身是Serilog官方推荐的实现方式,如果你觉得调用繁琐,可以自己封装一层辅助语法糖,比如封装成using (LogScope.SetUserId(123))的形式,用起来和自定义Enricher一样简洁,不需要额外开发自定义Enricher。

内容的提问来源于stack exchange,提问作者user4266661

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.06 20:39:03