# Elastic APM and openTracing

**URL:** <https://discuss.elastic.co/t/elastic-apm-and-opentracing/171357>\
**Category:** APM\
**Created:** [March 7, 2019, 4:51pm UTC](https://discuss.elastic.co/t/elastic-apm-and-opentracing/171357 "2019-03-07T16:51:21Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![afrozl](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/afrozl/32/26197_2.png) [@afrozl](https://discuss.elastic.co/u/afrozl)\
**Post date:** [March 7, 2019, 4:51pm UTC](https://discuss.elastic.co/t/elastic-apm-and-opentracing/171357/1 "2019-03-07T16:51:21Z")

</div>

Am I right in assuming that one of the primary objectives of openTracing is to make instrumentation of traces within application code agnostic to the specific tracer being used? In other words, I should be able to swap out Jaeger or Zipkin for Elastic APM without any required code changes (other than imports).

I was looking at some openTracing tutorials at [https://github.com/yurishkuro/opentracing-tutorial/tree/master/java](https://github.com/yurishkuro/opentracing-tutorial/tree/master/java) and I can't see how this could possibly work without code changes. Here is the Java example:

```
package lesson01.solution;

import com.google.common.collect.ImmutableMap;
import io.jaegertracing.internal.JaegerTracer;
import io.opentracing.Span;
import io.opentracing.Tracer;
import lib.Tracing;

public class Hello {

private final Tracer tracer;

private Hello(Tracer tracer) {
    this.tracer = tracer;
}

private void sayHello(String helloTo) {
    Span span = tracer.buildSpan("say-hello").start();
    span.setTag("hello-to", helloTo);

    String helloStr = String.format("Hello, %s!", helloTo);
    span.log(ImmutableMap.of("event", "string-format", "value", helloStr));

    System.out.println(helloStr);
    span.log(ImmutableMap.of("event", "println"));

    span.finish();
}

public static void main(String[] args) {
    if (args.length != 1) {
        throw new IllegalArgumentException("Expecting one argument");
    }

    String helloTo = args[0];
    try (JaegerTracer tracer = Tracing.init("hello-world")) {
        new Hello(tracer).sayHello(helloTo);
    }
 }

```

Unless I'm missing something, I can't see how this could be switched to elastic APM without code changes?

---

<div class="post-metadata">

**Author:** ![axw](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/axw/32/28197_2.png) [@axw](https://discuss.elastic.co/u/axw)\
**Post date:** [March 8, 2019, 2:39am UTC](https://discuss.elastic.co/t/elastic-apm-and-opentracing/171357/2 "2019-03-08T02:39:50Z")

</div>

> [@afrozl](#):
>
> Am I right in assuming that one of the primary objectives of openTracing is to make instrumentation of traces within application code agnostic to the specific tracer being used? In other words, I should be able to swap out Jaeger or Zipkin for Elastic APM without any required code changes (other than imports).

Yes, that's the idea behind the API. There is one part that you'll need to change in your application: constructing the `Tracer` object. In this example, that would be the tracer value that's passed into `new Hello(tracer)`. More concretely:

- remove `import io.jaegertracing.internal.JaegerTracer;` (it's not needed anyway)
- add `import co.elastic.apm.opentracing.ElasticApmTracer;`
- pass a Tracer constructed using `new ElasticApmTracer()` into `new Hello(...)`

Other than that, follow [OpenTracing bridge | APM Java Agent Reference [1.x] | Elastic](https://www.elastic.co/guide/en/apm/agent/java/current/opentracing-bridge.html) and [Set up the Agent | APM Java Agent Reference [1.x] | Elastic](https://www.elastic.co/guide/en/apm/agent/java/current/setup.html) to add the build and runtime dependencies.

So there are some changes required, but note that it's restricted to initialising the Tracer. After that, the instrumentation code is all the same: i.e. the calls to tracer inside `Hello.sayHello` in the example.

---

<div class="post-metadata">

**Author:** ![afrozl](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/afrozl/32/26197_2.png) [@afrozl](https://discuss.elastic.co/u/afrozl)\
**Post date:** [March 9, 2019, 2:23pm UTC](https://discuss.elastic.co/t/elastic-apm-and-opentracing/171357/3 "2019-03-09T14:23:06Z")

</div>

Thanks! that worked well for the example above. However, how would I convert to elastic APM this piece of code that's specific to Jaeger:

```
@Path("/publish")
@Produces(MediaType.TEXT_PLAIN)
public class PublisherResource {

    @GET
    public String format(@QueryParam("helloStr") String helloStr, @Context HttpHeaders httpHeaders) {
        try (Scope scope = Tracing.startServerSpan(tracer, httpHeaders, "publish")) {
            System.out.println(helloStr);
            scope.span().log(ImmutableMap.of("event", "println", "value", helloStr));
            return "published";
        }
    }
}
```

---

<div class="post-metadata">

**Author:** ![Eyal\_Koren](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/eyal_koren/32/36830_2.png) [@Eyal\_Koren](https://discuss.elastic.co/u/Eyal_Koren)\
**Post date:** [March 10, 2019, 2:48pm UTC](https://discuss.elastic.co/t/elastic-apm-and-opentracing/171357/4 "2019-03-10T14:48:06Z")

</div>

Is `Tracing.startServerSpan` an OpenTracing API?  
In any case, your imports are not included in this code snippet, but assuming the tracer here is of type `io.opentracing.Tracer`, you wouldn't need to change anything in this specific code, as long as you make sure that `tracer` you are using here is an instance of `co.elastic.apm.opentracing.ElasticApmTracer`, as @axw instructed above.

---

<div class="post-metadata">

**Author:** ![afrozl](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/afrozl/32/26197_2.png) [@afrozl](https://discuss.elastic.co/u/afrozl)\
**Post date:** [March 11, 2019, 2:41pm UTC](https://discuss.elastic.co/t/elastic-apm-and-opentracing/171357/5 "2019-03-11T14:41:12Z")

</div>

I guess I am not clear on how to pass context to the openTracing API using the elastic APM bridge. Jaeger imports a tracing package:

```
    try (Scope scope = Tracing.startServerSpan(tracer, httpHeaders, "publish")) {
        System.out.println(helloStr);
        scope.span().log(ImmutableMap.of("event", "println", "value", helloStr));
        return "published";
    }

```

In this case, I can't just replace the Jaeger tracing package with the elastic APM tracer, or can I?

---

<div class="post-metadata">

**Author:** ![felixbarny](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/felixbarny/32/27341_2.png) [@felixbarny](https://discuss.elastic.co/u/felixbarny)\
**Post date:** [March 11, 2019, 3:15pm UTC](https://discuss.elastic.co/t/elastic-apm-and-opentracing/171357/6 "2019-03-11T15:15:59Z")

</div>

The `Tracing` class is just a utility class in the same project: [https://github.com/yurishkuro/opentracing-tutorial/blob/c3b5f28cbbc1bc40d90cc84758b3229426825869/java/src/main/java/lib/Tracing.java#L42](https://github.com/yurishkuro/opentracing-tutorial/blob/c3b5f28cbbc1bc40d90cc84758b3229426825869/java/src/main/java/lib/Tracing.java#L42). This method does not depend on Jaeger internals (in contrast to other methods in this class).

---

<div class="post-metadata">

**Author:** ![afrozl](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/afrozl/32/26197_2.png) [@afrozl](https://discuss.elastic.co/u/afrozl)\
**Post date:** [March 12, 2019, 3:30pm UTC](https://discuss.elastic.co/t/elastic-apm-and-opentracing/171357/7 "2019-03-12T15:30:47Z")

</div>

Thanks! Adding the tracing class (minus the init method) allows the code to remain as is.

---

<div class="post-metadata">

**Author:** ![system](https://us1.discourse-cdn.com/elastic/original/3X/1/a/1ac57faf039f6b580b3f104ef42a2a89e41014de.png) [@system](https://discuss.elastic.co/u/system)\
**Post date:** [April 2, 2019, 11:30am UTC](https://discuss.elastic.co/t/elastic-apm-and-opentracing/171357/8 "2019-04-02T11:30:47Z")

</div>

This topic was automatically closed 20 days after the last reply. New replies are no longer allowed.
