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