如何使用 opentelemetry java sdk 创建多个服务?

问题描述

我有一个应用程序,它由多个以专有语言构建的服务组成。我想收集痕迹并摄取到 Jaeger 或 APM 解决方案中。没有仪器库。但是,这些服务会以专有格式生成跟踪。我想将这些跟踪信息转换为 OpenTelemetry 跟踪信息并摄取到 Jaeger 或 APM 解决方案中。

我开始使用 OpenTelemetry-Java SDK。

// This is a just converter service,trying to convert proprietary traces to OLTP
// Not interested in instrumenting this converter service. Following code does not show the proprietary trace reading and conversion for brevity.

// Converter service - reading first service 
private static void convert() {
   OpenTelemetry openTelemetry = ExampleConfiguration.initOpenTelemetry();
   Tracer tracer = openTelemetry.getTracer("io.opentelemetry.example");
   Span exampleSpan = tracer.spanBuilder("exampleSpan").startSpan();
   childOne(exampleSpan,openTelemetry);
   ...
}

// Converter service - reading second service
private static void childOne(Span parentSpan,OpenTelemetry openTelemetry) {
  Tracer tracer = openTelemetry.getTracer("service2");
  Span childSpan = tracer.spanBuilder("child").setParent(Context.current().with(parentSpan)).startSpan();
  try {
    Thread.sleep(4000);
  } catch (InterruptedException e) {
    // Todo Auto-generated catch block
    e.printstacktrace();
  }
  childSpan.end();
}

配置合适的导出器。我可以在 Jeager 中看到预期的痕迹。

enter image description here

但它只显示一项服务。

enter image description here

而我想描述两种不同的服务。使用 OpenTelemetry 可以吗?

enter image description here

解决方法

您可以在代码中设置服务名称如下:

Resource serviceNameResource = Resource.create(Attributes.of(ResourceAttributes.SERVICE_NAME,serviceName));

// Set to process the spans by the Jaeger Exporter
SdkTracerProvider tracerProvider =
    SdkTracerProvider.builder()
        .addSpanProcessor(SimpleSpanProcessor.create(jaegerExporter))
        .setResource(Resource.getDefault().merge(serviceNameResource))
        .build();

OpenTelemetrySdk openTelemetry =
    OpenTelemetrySdk.builder().setTracerProvider(tracerProvider).build();
,

基于 Opentelemetry Java 社区提供的一些提示,创建了两个提供者,它们确实创建了两个服务。重用相同的导出器,这样可以避免与后端的多个连接。在接下来的几天里,我将详细了解如何重用 exporter 在同一个应用程序中创建两个或多个提供。

OpenTelemetry openTelemetryParent = ExampleConfiguration.initOpenTelemetry(jaegerHostName,jaegerPort,"FirstService");
    Tracer tracerParent = openTelemetryParent.getTracer("FirstServiceInstrumentation");

    OpenTelemetry openTelemetryChild = ExampleConfiguration.initOpenTelemetry(jaegerHostName,"SecondService");
    Tracer tracerChild = openTelemetryChild.getTracer("SecondServiceInstrumentation");

    Random randomNum = new Random();

    for (int i = 0; i < 10; i++) {
      Span parentSpan = tracerParent.spanBuilder("MyService1Span").startSpan();
      try (Scope scope = parentSpan.makeCurrent()) {
        Thread.sleep(1 + randomNum.nextInt(100));
        secondService(parentSpan,tracerChild,randomNum.nextInt(300));
        Thread.sleep(1 + randomNum.nextInt(100));
      } catch (InterruptedException e) {
        e.printStackTrace();
      } finally {
        parentSpan.end();
      }
    }
  }

  private static void secondService(Span parentSpan,Tracer tracer,int delay) {
    Span childSpan = tracer.spanBuilder("MyService2Span").setParent(Context.current().with(parentSpan)).startSpan();
    try {
      Thread.sleep(delay);
    } catch (InterruptedException e) {
      e.printStackTrace();
    }
    childSpan.end();
  }

感谢令人惊叹的 Opentelemetry Java 社区 - @John Watson (jkwatson)、Bogdan Drutu、Rupinder Singh、Anuraag Agrawal。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...