Search code examples
javatracejaegerapmopen-telemetry

How to create multiple services using opentelemetry java sdk?


I have an application which is made up of multiple services built in proprietary language. I want to collect traces and ingest into Jaeger or APM solution. There is no instrumentation library. However, these services produce traces in a proprietary format. I want to convert these traces to OpenTelemetry traces and ingest into Jaeger or APM solution.

I started using 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();
}

Configured appropriate exporter. I can see the traces in Jeager as expected. enter image description here

BUT it shows only one service. enter image description here

Whereas I want to depict two different services. Is that possible using OpenTelemetry?

enter image description here


Solution

  • Based on some of the hints provided by Opentelemetry Java community, created two providers which indeed creates two services. Reusing same exporter, so that multiple connections to the backend can be avoided. I will learn more about reusing exporter to create two or more provides in the same application in coming days.

    OpenTelemetry openTelemetryParent = ExampleConfiguration.initOpenTelemetry(jaegerHostName, jaegerPort,
            "FirstService");
        Tracer tracerParent = openTelemetryParent.getTracer("FirstServiceInstrumentation");
    
        OpenTelemetry openTelemetryChild = ExampleConfiguration.initOpenTelemetry(jaegerHostName, jaegerPort,
            "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();
      }
    

    Thank you to amazing Opentelemetry java community - @John Watson (jkwatson), Bogdan Drutu, Rupinder Singh, Anuraag Agrawal.