diff --git a/javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/AddBaggageSpanProcessor.java b/javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/AddBaggageSpanProcessor.java new file mode 100644 index 000000000000..dd4088449e6e --- /dev/null +++ b/javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/AddBaggageSpanProcessor.java @@ -0,0 +1,18 @@ +package io.opentelemetry.javaagent.tooling; + +import io.opentelemetry.api.baggage.Baggage; +import io.opentelemetry.context.Context; +import io.opentelemetry.sdk.trace.ReadWriteSpan; + +public class AddBaggageSpanProcessor implements OnStartSpanProcessor { + @Override + public void onStart(Context context, ReadWriteSpan span) { + Baggage baggage = Baggage.fromContext(context); + baggage.forEach( + (key, value) -> + span.setAttribute( + // add prefix to key to not override existing attributes + "baggage." + key, + value.getValue())); + } +} diff --git a/javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/AddThreadDetailsSpanProcessor.java b/javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/AddThreadDetailsSpanProcessor.java index 426098256504..0a4646f5ef54 100644 --- a/javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/AddThreadDetailsSpanProcessor.java +++ b/javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/AddThreadDetailsSpanProcessor.java @@ -6,13 +6,10 @@ package io.opentelemetry.javaagent.tooling; import io.opentelemetry.context.Context; -import io.opentelemetry.sdk.common.CompletableResultCode; import io.opentelemetry.sdk.trace.ReadWriteSpan; -import io.opentelemetry.sdk.trace.ReadableSpan; -import io.opentelemetry.sdk.trace.SpanProcessor; import io.opentelemetry.semconv.trace.attributes.SemanticAttributes; -public class AddThreadDetailsSpanProcessor implements SpanProcessor { +public class AddThreadDetailsSpanProcessor implements OnStartSpanProcessor { @Override public void onStart(Context context, ReadWriteSpan span) { @@ -20,27 +17,4 @@ public void onStart(Context context, ReadWriteSpan span) { span.setAttribute(SemanticAttributes.THREAD_ID, currentThread.getId()); span.setAttribute(SemanticAttributes.THREAD_NAME, currentThread.getName()); } - - @Override - public boolean isStartRequired() { - return true; - } - - @Override - public void onEnd(ReadableSpan span) {} - - @Override - public boolean isEndRequired() { - return false; - } - - @Override - public CompletableResultCode shutdown() { - return CompletableResultCode.ofSuccess(); - } - - @Override - public CompletableResultCode forceFlush() { - return CompletableResultCode.ofSuccess(); - } } diff --git a/javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/AgentTracerProviderConfigurer.java b/javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/AgentTracerProviderConfigurer.java index c1a2f032cdc4..b51bbce8f233 100644 --- a/javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/AgentTracerProviderConfigurer.java +++ b/javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/AgentTracerProviderConfigurer.java @@ -20,6 +20,7 @@ @AutoService(AutoConfigurationCustomizerProvider.class) public class AgentTracerProviderConfigurer implements AutoConfigurationCustomizerProvider { private static final String ADD_THREAD_DETAILS = "otel.javaagent.add-thread-details"; + private static final String ADD_BAGGAGE = "otel.javaagent.span.add-baggage"; @Override public void customize(AutoConfigurationCustomizer autoConfigurationCustomizer) { @@ -38,6 +39,11 @@ private static SdkTracerProviderBuilder configure( sdkTracerProviderBuilder.addSpanProcessor(new AddThreadDetailsSpanProcessor()); } + // Register baggage adding span processor if config value is set + if (config.getBoolean(ADD_BAGGAGE, false)) { + sdkTracerProviderBuilder.addSpanProcessor(new AddBaggageSpanProcessor()); + } + maybeEnableLoggingExporter(sdkTracerProviderBuilder, config); return sdkTracerProviderBuilder; diff --git a/javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/OnStartSpanProcessor.java b/javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/OnStartSpanProcessor.java new file mode 100644 index 000000000000..fce238a9793e --- /dev/null +++ b/javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/OnStartSpanProcessor.java @@ -0,0 +1,30 @@ +package io.opentelemetry.javaagent.tooling; + +import io.opentelemetry.sdk.common.CompletableResultCode; +import io.opentelemetry.sdk.trace.ReadableSpan; +import io.opentelemetry.sdk.trace.SpanProcessor; + +public interface OnStartSpanProcessor extends SpanProcessor { + @Override + default boolean isStartRequired() { + return true; + } + + @Override + default void onEnd(ReadableSpan span) {} + + @Override + default boolean isEndRequired() { + return false; + } + + @Override + default CompletableResultCode shutdown() { + return CompletableResultCode.ofSuccess(); + } + + @Override + default CompletableResultCode forceFlush() { + return CompletableResultCode.ofSuccess(); + } +} diff --git a/javaagent-tooling/src/test/java/io/opentelemetry/javaagent/tooling/AddBaggageSpanProcessorTest.java b/javaagent-tooling/src/test/java/io/opentelemetry/javaagent/tooling/AddBaggageSpanProcessorTest.java new file mode 100644 index 000000000000..1b7ed6931dde --- /dev/null +++ b/javaagent-tooling/src/test/java/io/opentelemetry/javaagent/tooling/AddBaggageSpanProcessorTest.java @@ -0,0 +1,26 @@ +package io.opentelemetry.javaagent.tooling; + +import static org.mockito.Mockito.verify; + +import io.opentelemetry.api.baggage.Baggage; +import io.opentelemetry.context.Context; +import io.opentelemetry.context.Scope; +import io.opentelemetry.sdk.trace.ReadWriteSpan; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; + +@ExtendWith(MockitoExtension.class) +class AddBaggageSpanProcessorTest { + @Mock ReadWriteSpan readWriteSpan; + + @Test + void shouldAddBaggageToSpanWithPrefixedKeysWhenBaggageIsPopulated() { + try (Scope unused = Baggage.builder().put("someKey", "someValue").build().makeCurrent()) { + new AddBaggageSpanProcessor().onStart(Context.current(), readWriteSpan); + } + + verify(readWriteSpan).setAttribute("baggage.someKey", "someValue"); + } +}