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

Spring Boot中扩展Micrometer Observation上下文的推荐方式咨询

扩展Spring Boot现有Observation上下文的最佳实践

你的实现并非官方推荐的方式,原因及替代方案如下:

不推荐直接操作ObservationContext的原因

  1. 属性无法被观测导出器识别:直接调用currentObservation.getContext().put()添加的属性,不会被自动转换为观测的标准标签(Tags),Zipkin、Prometheus这类主流监控工具只会读取通过官方API添加的键值对,自定义put的内容大概率不会出现在监控数据里。
  2. 没有区分属性基数:Micrometer设计中,属性分为低基数(如枚举类型的状态值)和高基数(如用户ID、订单号),不同基数的属性需要用不同方法添加来避免监控系统性能问题,直接put无法做这个区分。
  3. API兼容性风险:ObservationContext的内部存储属于Micrometer的实现细节,后续版本可能变更,直接操作会导致代码依赖内部实现,升级时容易出问题。

推荐的替代方案

方案1:直接在现有观测中添加标准键值对

使用Micrometer提供的lowCardinalityKeyValue(低基数属性)或highCardinalityKeyValue(高基数属性)方法,这是官方推荐的扩展观测上下文的方式:

@Autowired
private ObservationRegistry observationRegistry;

public void myBusinessMethod(String userId) {
    // 其他业务代码
    Observation currentObservation = observationRegistry.getCurrentObservation();
    if (currentObservation != null) {
        // 用户ID属于高基数属性,用highCardinalityKeyValue
        currentObservation.highCardinalityKeyValue("userId", userId);
    }
    // 其他业务代码
}

方案2:全局统一添加属性(适合跨方法的通用属性)

如果需要在所有自动观测中统一添加某个属性(比如当前登录用户ID),可以自定义ObservationFilter,拦截观测创建过程自动注入属性:

@Component
public class GlobalUserIdObservationFilter implements ObservationFilter {
    @Override
    public Observation.Context map(Observation.Context context) {
        // 从上下文获取当前用户ID,示例用Spring Security的方式
        String userId = SecurityContextHolder.getContext()
                .getAuthentication()
                .getName();
                
        if (userId != null) {
            context.highCardinalityKeyValue("userId", userId);
        }
        return context;
    }
}

方案3:启动子观测(如果业务需要独立的观测节点)

如果你的业务方法需要生成独立的观测链路节点,同时继承父观测的上下文,可以创建子观测并添加属性:

@Autowired
private ObservationRegistry observationRegistry;

public void myBusinessMethod(String userId) {
    // 其他业务代码
    // 基于当前观测创建子观测,自动继承上下文
    try (Observation.Scope scope = Observation.createNotStarted("my.business.operation", observationRegistry)
            .highCardinalityKeyValue("userId", userId)
            .start()
            .openScope()) {
        // 子观测覆盖的业务代码
    }
    // 其他业务代码
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 13:14:53