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