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; 007 008/** 009 * This is exactly the same as the {@code OpenTelemetrySpanContextSupplier}. However, the {@code 010 * io.opentelemetry.api} package is relocated to {@code 011 * 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 025 // io.opentelemetry.api.trace.Span did not exist. 026 // IncompatibleClassChangeError: 027 // The application uses an OpenTelemetry version between 0.10.0 and 0.15.0 when SpanContext 028 // was a class, and not an interface. 029 return false; 030 } 031 } 032 033 @Override 034 public String getCurrentTraceId() { 035 String traceId = Span.current().getSpanContext().getTraceId(); 036 return TraceId.isValid(traceId) ? traceId : null; 037 } 038 039 @Override 040 public String getCurrentSpanId() { 041 String spanId = Span.current().getSpanContext().getSpanId(); 042 return SpanId.isValid(spanId) ? spanId : null; 043 } 044 045 @Override 046 public boolean isCurrentSpanSampled() { 047 return Span.current().getSpanContext().isSampled(); 048 } 049 050 @Override 051 public void markCurrentSpanAsExemplar() { 052 Span.current().setAttribute(EXEMPLAR_ATTRIBUTE_NAME, EXEMPLAR_ATTRIBUTE_VALUE); 053 } 054}