001package io.prometheus.metrics.tracer.otel;
002
003import io.opentelemetry.api.trace.Span;
004import io.opentelemetry.api.trace.SpanId;
005import io.opentelemetry.api.trace.TraceId;
006import io.prometheus.metrics.tracer.common.SpanContext;
007
008public class OpenTelemetrySpanContext implements SpanContext {
009
010  public static boolean isAvailable() {
011    try {
012      OpenTelemetrySpanContext test = new OpenTelemetrySpanContext();
013      test.getCurrentSpanId();
014      test.getCurrentTraceId();
015      test.isCurrentSpanSampled();
016      return true;
017    } catch (LinkageError ignored) {
018      // NoClassDefFoundError:
019      //   Either OpenTelemetry is not present, or it is version 0.9.1 or older when
020      // io.opentelemetry.api.trace.Span did not exist.
021      // IncompatibleClassChangeError:
022      //   The application uses an OpenTelemetry version between 0.10.0 and 0.15.0 when SpanContext
023      // was a class, and not an interface.
024      return false;
025    }
026  }
027
028  @Override
029  public String getCurrentTraceId() {
030    String traceId = Span.current().getSpanContext().getTraceId();
031    return TraceId.isValid(traceId) ? traceId : null;
032  }
033
034  @Override
035  public String getCurrentSpanId() {
036    String spanId = Span.current().getSpanContext().getSpanId();
037    return SpanId.isValid(spanId) ? spanId : null;
038  }
039
040  @Override
041  public boolean isCurrentSpanSampled() {
042    return Span.current().getSpanContext().isSampled();
043  }
044
045  @Override
046  public void markCurrentSpanAsExemplar() {
047    Span.current().setAttribute(EXEMPLAR_ATTRIBUTE_NAME, EXEMPLAR_ATTRIBUTE_VALUE);
048  }
049}