001package io.prometheus.metrics.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.metrics.tracer.common.SpanContext; 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 OpenTelemetryAgentSpanContext implements SpanContext { 014 015 public static boolean isAvailable() { 016 try { 017 OpenTelemetryAgentSpanContext test = new OpenTelemetryAgentSpanContext(); 018 test.getCurrentSpanId(); 019 test.getCurrentTraceId(); 020 test.isCurrentSpanSampled(); 021 return true; 022 } catch (LinkageError ignored) { 023 // NoClassDefFoundError: 024 // Either OpenTelemetry is not present, or it is version 0.9.1 or older when io.opentelemetry.api.trace.Span did not exist. 025 // IncompatibleClassChangeError: 026 // The application uses an OpenTelemetry version between 0.10.0 and 0.15.0 when SpanContext was a class, and not an interface. 027 return false; 028 } 029 } 030 031 @Override 032 public String getCurrentTraceId() { 033 String traceId = Span.current().getSpanContext().getTraceId(); 034 return TraceId.isValid(traceId) ? traceId : null; 035 } 036 037 @Override 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}