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

在Vertx Verticle中创建OpenTelemetry追踪及获取实例的方法

在Vert.x Verticle中获取OpenTelemetry实例并手动埋点的最佳实践

问题背景

已完成Vertx与OpenTelemetry的基础配置,但官方示例仅覆盖初始化步骤,未说明在Verticle中如何获取OpenTelemetry实例进行手动埋点,无法实现自定义Span的创建与管理。

配置代码参考:

SdkTracerProvider sdkTracerProvider = SdkTracerProvider.builder().build();
OpenTelemetry openTelemetry = OpenTelemetrySdk.builder()
    .setTracerProvider(sdkTracerProvider)
    .setPropagators(ContextPropagators.create(W3CTraceContextPropagator.getInstance()))
    .buildAndRegisterGlobal();

VertxOptions vertxOptions = new VertxOptions();
vertxOptions.setTracingOptions(new OpenTelemetryOptions(openTelemetry));

Vertx vertx = Vertx.vertx(vertxOptions);

需求是在路由处理器中手动创建Span:

router.route(HttpMethod.GET, "/stats/system/time").handler(ctx -> {
    Tracer tracer = ... // 需要获取Tracer实例
    SpanBuilder spanBuilder = tracer.spanBuilder("testSpan").setAttribute("task", "json-generation");
    Span span = spanBuilder.startSpan();
    ctx.json(new JsonObject().put("systemTime", LocalDateTime.now()));
    span.end();
});

最佳实现方式

1. 从Vertx实例获取(推荐)

Vertx的Tracing组件已绑定配置好的OpenTelemetry实例,可直接从Vertx上下文提取:

// 在Verticle的start方法中或路由处理器内
OpenTelemetryTracer otelTracer = (OpenTelemetryTracer) vertx.tracing();
OpenTelemetry openTelemetry = otelTracer.getOpenTelemetry();
Tracer tracer = openTelemetry.getTracer("Test");

// 完善的手动埋点示例(关联请求上下文)
router.route(HttpMethod.GET, "/stats/system/time").handler(ctx -> {
    // 将当前请求的Span作为父Span,保证链路连续性
    Span parentSpan = otelTracer.getSpan(ctx);
    Span span = tracer.spanBuilder("testSpan")
        .setAttribute("task", "json-generation")
        .setParent(Context.current().with(parentSpan))
        .startSpan();
    
    // 使用try-with-resources自动管理Scope,确保上下文传递
    try (Scope scope = span.makeCurrent()) {
        ctx.json(new JsonObject().put("systemTime", LocalDateTime.now()));
    } finally {
        span.end();
    }
});

优势:与Vertx上下文强绑定,支持多Vertx实例不同配置的场景,避免全局实例的耦合问题。

2. 使用全局注册的OpenTelemetry实例

如果初始化时调用了buildAndRegisterGlobal(),可直接通过全局静态方法获取:

Tracer tracer = OpenTelemetry.getGlobal().getTracer("Test");

注意:仅适用于单Vertx实例、统一OpenTelemetry配置的场景,多实例环境下会导致配置冲突,不推荐在复杂系统中使用。

3. 上下文传递实例(自定义扩展)

若需在多个Verticle间共享实例,可将OpenTelemetry实例存入Vertx Context:

// 启动Verticle时存入上下文
DeploymentOptions options = new DeploymentOptions();
options.setConfig(new JsonObject().put("otelInstance", openTelemetry));
vertx.deployVerticle(new MyVerticle(), options);

// 在Verticle中获取
@Override
public void start(Promise<Void> startPromise) {
    OpenTelemetry openTelemetry = (OpenTelemetry) config().getValue("otelInstance");
    Tracer tracer = openTelemetry.getTracer("Test");
    // 后续埋点逻辑...
}

有效使用的核心要点

  • 关联请求上下文:手动创建Span时必须关联当前请求的父Span,避免链路追踪断裂
  • 自动管理Scope:使用try-with-resources包裹Scope,确保Span上下文在代码块内正确传递
  • 合理设置Span属性:添加业务相关的标签(如接口名称、参数、状态码),提升链路的可观测性
  • 控制Span粒度:避免创建过多细粒度Span,仅对关键业务步骤埋点,保持链路清晰

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 22:05:25