001package io.prometheus.client.exemplars.tracer.otel_agent;
002
003import io.opentelemetry.api.trace.Span;
004import io.opentelemetry.api.trace.SpanId;
005import io.opentelemetry.api.trace.TraceId;
006import io.prometheus.client.exemplars.tracer.common.SpanContextSupplier;
007
008/**
009 * This is exactly the same as the {@code OpenTelemetrySpanContextSupplier}.
010 * However, the {@code io.opentelemetry.api} package is relocated to
011 * {@code io.opentelemetry.javaagent.shaded.io.opentelemetry.api} in the OpenTelemetry agent.
012 */
013public class OpenTelemetryAgentSpanContextSupplier implements SpanContextSupplier {
014
015  public static boolean isAvailable() {
016    try {
017      if ("inactive".equalsIgnoreCase(System.getProperties().getProperty("io.prometheus.otelExemplars"))) {
018        return false;
019      }
020      OpenTelemetryAgentSpanContextSupplier test = new OpenTelemetryAgentSpanContextSupplier();
021      test.getSpanId();
022      test.getTraceId();
023      test.isSampled();
024      return true;
025    } catch (LinkageError ignored) {
026      // NoClassDefFoundError:
027      //   Either OpenTelemetry is not present, or it is version 0.9.1 or older when io.opentelemetry.api.trace.Span did not exist.
028      // IncompatibleClassChangeError:
029      //   The application uses an OpenTelemetry version between 0.10.0 and 0.15.0 when SpanContext was a class, and not an interface.
030      return false;
031    }
032  }
033
034  @Override
035  public String getTraceId() {
036    String traceId = Span.current().getSpanContext().getTraceId();
037    return TraceId.isValid(traceId) ? traceId : null;
038  }
039
040  @Override
041  public String getSpanId() {
042    String spanId = Span.current().getSpanContext().getSpanId();
043    return SpanId.isValid(spanId) ? spanId : null;
044  }
045
046  @Override
047  public boolean isSampled() {
048    return Span.current().getSpanContext().isSampled();
049  }
050}