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

如何在OpenTelemetry自动配置中限制Span深度?

控制OpenTelemetry自动配置模式下的Span追踪深度

在自动配置的OpenTelemetry中,要实现Span深度控制并支持按需展示全部Span,可以通过自定义Span Processor结合动态配置来实现,具体方案如下:

一、核心思路

通过自定义Span Processor拦截Span的创建和结束过程,计算每个Span的层级,根据预设的最大深度阈值决定是否导出该Span;同时提供动态修改阈值的能力,实现按需切换是否展示全部Span。

二、实现步骤

1. 自定义深度限制Span Processor

实现SpanProcessor接口,在Span启动时计算层级,结束时过滤超过阈值的Span:

public class DepthLimitingSpanProcessor implements SpanProcessor {
    // 默认允许根Span(深度0)+第一层子Span(深度1)
    private volatile int maxAllowedDepth = 1;

    @Override
    public void onStart(Context parentContext, ReadWriteSpan span) {
        // 从父Span获取层级,根Span层级为0
        Integer parentDepth = parentContext.get(Span.class) != null 
            ? parentContext.get(Span.class).getAttribute("custom.span.trace.depth") 
            : null;
        int currentDepth = parentDepth != null ? parentDepth + 1 : 0;
        // 将层级作为Span属性存储
        span.setAttribute("custom.span.trace.depth", currentDepth);
    }

    @Override
    public boolean isStartRequired() {
        return true;
    }

    @Override
    public void onEnd(ReadableSpan span) {
        int currentDepth = span.getAttribute("custom.span.trace.depth", 0);
        // 超过阈值的Span标记为不导出(通过设置状态为UNSET,后续Exporter可过滤)
        if (currentDepth > maxAllowedDepth) {
            span.setStatus(StatusCode.UNSET);
        }
    }

    @Override
    public boolean isEndRequired() {
        return true;
    }

    // 动态修改最大允许深度的方法
    public void setMaxAllowedDepth(int maxAllowedDepth) {
        this.maxAllowedDepth = maxAllowedDepth;
    }
}

2. 注册自定义Span Processor

在Spring Boot自动配置环境中,通过@Bean将自定义Processor注册到OpenTelemetry SDK:

@Configuration
public class OpenTelemetryConfig {
    @Bean
    public SpanProcessor depthLimitingSpanProcessor() {
        return new DepthLimitingSpanProcessor();
    }
}

OpenTelemetry自动配置会自动将该Processor加入Span处理链。

3. 动态控制Span深度阈值

提供接口或配置中心集成,实现不重启服务修改阈值:

@RestController
@RequestMapping("/otel/control")
public class OtelTraceController {
    private final DepthLimitingSpanProcessor spanProcessor;

    public OtelTraceController(DepthLimitingSpanProcessor spanProcessor) {
        this.spanProcessor = spanProcessor;
    }

    // 设置最大允许的Span深度,比如设为100即可导出所有嵌套Span
    @PostMapping("/set-max-depth")
    public ResponseEntity<Void> setMaxTraceDepth(@RequestParam int maxDepth) {
        spanProcessor.setMaxAllowedDepth(maxDepth);
        return ResponseEntity.ok().build();
    }
}

三、使用说明

  • 仅记录根Span:调用接口设置maxDepth=0,此时只有最外层的父Span会被导出。
  • 记录根Span+第一层子Span:保持默认的maxDepth=1。
  • 展示全部Span:调用接口设置maxDepth为一个足够大的值(如100),所有嵌套Span都会被导出。

四、补充优化

  • 可以结合配置中心(如Nacos、Spring Cloud Config),将maxAllowedDepth作为配置项,实现更灵活的动态调整。
  • 如果使用OTLP Exporter,可在Exporter配置中添加过滤规则,直接过滤状态为UNSET的Span,进一步减少不必要的导出:
    otel.exporter.otlp.traces.filter=status.code != "UNSET"
    

内容的提问来源于stack exchange,提问作者Valeriy K.

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 17:16:29