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}