Class OpenTelemetryTracer

java.lang.Object
com.azure.core.tracing.opentelemetry.OpenTelemetryTracer
All Implemented Interfaces:
Tracer

public class OpenTelemetryTracer extends Object implements Tracer
Basic tracing implementation class for use with REST and AMQP Service Clients to create Span and in-process context propagation. Singleton OpenTelemetry tracer capable of starting and exporting spans.

This helper class supports W3C distributed tracing protocol and injects SpanContext into the outgoing HTTP and AMQP requests.

  • Constructor Details

    • OpenTelemetryTracer

      public OpenTelemetryTracer()
      Creates new OpenTelemetryTracer using default global tracer - GlobalOpenTelemetry.getTracer(String)
  • Method Details

    • start

      public Context start(String spanName, Context context)
      Creates a new tracing span.

      The context will be checked for information about a parent span. If a parent span is found, the new span will be added as a child. Otherwise, the parent span will be created and added to the context and any downstream start() calls will use the created span as the parent.

      Code samples

      Starts a tracing span with provided method name and explicit parent span

       // start a new tracing span with given name and parent context implicitly propagated
       // in io.opentelemetry.context.Context.current()
      
       Throwable throwable = null;
       Context span = tracer.start("keyvault.setsecret", Context.NONE);
       try {
           doWork();
       } catch (Throwable ex) {
           throwable = ex;
       } finally {
           tracer.end(null, throwable, span);
       }
       
      Specified by:
      start in interface Tracer
      Parameters:
      spanName - Name of the method triggering the span creation.
      context - Additional metadata that is passed through the call stack.
      Returns:
      The updated Context object containing the returned span.
    • start

      public Context start(String spanName, StartSpanOptions options, Context context)
      Creates a new tracing span.

      The context will be checked for information about a parent span. If a parent span is found, the new span will be added as a child. Otherwise, the parent span will be created and added to the context and any downstream start() calls will use the created span as the parent.

      Code samples

      Starts a tracing span with provided method name and explicit parent span

       // start a new CLIENT tracing span with the given start options and explicit parent context
       StartSpanOptions options = new StartSpanOptions(SpanKind.CLIENT)
           .setAttribute("key", "value");
       Context spanFromOptions = tracer.start("keyvault.setsecret", options, Context.NONE);
       try {
           doWork();
       } catch (Throwable ex) {
           throwable = ex;
       } finally {
           tracer.end(null, throwable, spanFromOptions);
       }
       
      Specified by:
      start in interface Tracer
      Parameters:
      spanName - Name of the method triggering the span creation.
      options - span creation options.
      context - Additional metadata that is passed through the call stack.
      Returns:
      The updated Context object containing the returned span.
    • injectContext

      public void injectContext(BiConsumer<String,String> headerSetter, Context context)
      Description copied from interface: com.azure.core.util.tracing.Tracer
      Injects tracing context.
       Context httpSpan = tracer.start("HTTP GET", new StartSpanOptions(SpanKind.CLIENT), methodSpan);
       tracer.injectContext((headerName, headerValue) -> request.setHeader(headerName, headerValue), httpSpan);
      
       try (AutoCloseable scope = tracer.makeSpanCurrent(httpSpan)) {
           HttpResponse response = getResponse(request);
           httpResponseCode = response.getStatusCode();
       } catch (Throwable ex) {
           throwable = ex;
       } finally {
           tracer.end(httpResponseCode, throwable, httpSpan);
       }
       
      Specified by:
      injectContext in interface Tracer
      Parameters:
      headerSetter - callback to set context with.
      context - trace context instance
    • setAttribute

      public void setAttribute(String key, long value, Context context)
      Description copied from interface: com.azure.core.util.tracing.Tracer
      Sets long attribute.
       Context span = tracer.start("EventHubs.process", Context.NONE);
       tracer.setAttribute("foo", 42, span);
       
      Specified by:
      setAttribute in interface Tracer
      Parameters:
      key - attribute name
      value - atteribute value
      context - tracing context
    • setAttribute

      public void setAttribute(String key, String value, Context context)
      Adds metadata to the current span. If no span information is found in the context, then no metadata is added.
       span = tracer.start("EventHubs.process", Context.NONE);
       tracer.setAttribute("bar", "baz", span);
       
      Specified by:
      setAttribute in interface Tracer
      Parameters:
      key - Name of the metadata.
      value - Value of the metadata.
      context - Additional metadata that is passed through the call stack.
    • end

      public void end(String errorMessage, Throwable throwable, Context context)
      Completes span on the context.

      Code samples

      Completes the tracing span with unset status

       Context messageSpan = tracer.start("ServiceBus.message", new StartSpanOptions(SpanKind.PRODUCER), Context.NONE);
       tracer.end(null, null, messageSpan);
       

      Completes the tracing span with provided error message

       Context span = tracer.start("ServiceBus.send", new StartSpanOptions(SpanKind.CLIENT), Context.NONE);
       tracer.end("amqp:not-found", null, span);
       

      Completes the tracing span with provided exception

       Context sendSpan = tracer.start("ServiceBus.send", new StartSpanOptions(SpanKind.CLIENT), Context.NONE);
       try (AutoCloseable scope = tracer.makeSpanCurrent(sendSpan)) {
           doWork();
       } catch (Throwable ex) {
           throwable = ex;
       } finally {
           tracer.end(null, throwable, sendSpan);
       }
       
      Specified by:
      end in interface Tracer
      Parameters:
      errorMessage - The error message that occurred during the call, or null if no error. occurred. Any other non-null string indicates an error with description provided in errorMessage.
      throwable - Throwable that happened during the span or null if no exception occurred.
      context - Additional metadata that is passed through the call stack.
    • extractContext

      public Context extractContext(Function<String,String> headerGetter)
      Extracts the span's context as Context from upstream.

      Code samples

      Extracts the corresponding span context information from a valid diagnostic id

       Context parentContext = tracer.extractContext(name -> {
           Object value = messageProperties.get(name);
           return value instanceof String ? (String) value : null;
       });
      
       StartSpanOptions remoteParentOptions = new StartSpanOptions(SpanKind.CONSUMER)
           .setRemoteParent(parentContext);
      
       Context spanWithRemoteParent = tracer.start("EventHubs.process", remoteParentOptions, Context.NONE);
      
       try (AutoCloseable scope = tracer.makeSpanCurrent(spanWithRemoteParent)) {
           doWork();
       } catch (Throwable ex) {
           throwable = ex;
       } finally {
           tracer.end(null, throwable, spanWithRemoteParent);
       }
       
      Specified by:
      extractContext in interface Tracer
      Parameters:
      headerGetter - Unique identifier for the trace information of the span and todo.
      Returns:
      The updated Context object containing the span context.
    • makeSpanCurrent

      public AutoCloseable makeSpanCurrent(Context context)
      Makes span current. Implementations may put it on ThreadLocal. Make sure to always use try-with-resource statement with makeSpanCurrent
      Specified by:
      makeSpanCurrent in interface Tracer
      Parameters:
      context - Context with span.
       Context span = tracer.start("EventHubs.process", new StartSpanOptions(SpanKind.CONSUMER), Context.NONE);
       try (AutoCloseable scope = tracer.makeSpanCurrent(span)) {
           doWork();
       } catch (Throwable ex) {
           throwable = ex;
       } finally {
           tracer.end(null, throwable, span);
       }
       
      Returns:
      Closeable that should be closed in the same thread with try-with-resource statement.
    • addEvent

      public void addEvent(String eventName, Map<String,Object> traceEventAttributes, OffsetDateTime timestamp, Context context)
      Adds an event to the span present in the Context with the provided timestamp and attributes.

      This API does not provide any normalization if provided timestamps are out of range of the current span timeline

      Supported attribute values include String, double, boolean, long, String [], double [], long []. Any other Object value type and null values will be silently ignored.

       Context span = tracer.start("Cosmos.getItem", Context.NONE);
       tracer.addEvent("trying another endpoint", Collections.singletonMap("endpoint", "westus3"), OffsetDateTime.now(), span);
       
      Specified by:
      addEvent in interface Tracer
      Parameters:
      eventName - the name of the event.
      traceEventAttributes - the additional attributes to be set for the event.
      timestamp - The instant, in UTC, at which the event will be associated to the span.
      context - the call metadata containing information of the span to which the event should be associated with.
    • isEnabled

      public boolean isEnabled()
      Description copied from interface: com.azure.core.util.tracing.Tracer
      Checks if tracer is enabled.
       if (!tracer.isEnabled()) {
           doWork();
       } else {
           Context span = tracer.start("span", Context.NONE);
           try {
               doWork();
           } catch (Throwable ex) {
               throwable = ex;
           } finally {
               tracer.end(null, throwable, span);
           }
       }
       
      Specified by:
      isEnabled in interface Tracer
      Returns:
      true if tracer is enabled, false otherwise.