在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
相关产品推荐
相关产品推荐

