From 4afc902e7df0f2a75df89cb008c038a148579446 Mon Sep 17 00:00:00 2001 From: adamleantech <65166709+adamleantech@users.noreply.github.com> Date: Thu, 16 Mar 2023 12:03:46 +0000 Subject: [PATCH 1/3] add baggage span processor --- .../tooling/AddBaggageSpanProcessor.java | 18 +++++++++++ .../AddThreadDetailsSpanProcessor.java | 28 +---------------- .../javaagent/tooling/AgentInstaller.java | 22 -------------- .../AgentTracerProviderConfigurer.java | 6 ++++ .../tooling/OnStartSpanProcessor.java | 30 +++++++++++++++++++ .../tooling/AddBaggageSpanProcessorTest.java | 26 ++++++++++++++++ 6 files changed, 81 insertions(+), 49 deletions(-) create mode 100644 javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/AddBaggageSpanProcessor.java create mode 100644 javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/OnStartSpanProcessor.java create mode 100644 javaagent-tooling/src/test/java/io/opentelemetry/javaagent/tooling/AddBaggageSpanProcessorTest.java 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/AgentInstaller.java b/javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/AgentInstaller.java index 149143c8d27e..dbb6734b95bc 100644 --- a/javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/AgentInstaller.java +++ b/javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/AgentInstaller.java @@ -22,9 +22,6 @@ import io.opentelemetry.javaagent.bootstrap.ClassFileTransformerHolder; import io.opentelemetry.javaagent.bootstrap.DefineClassHelper; import io.opentelemetry.javaagent.bootstrap.InstrumentedTaskClasses; -import io.opentelemetry.javaagent.bootstrap.http.HttpServerResponseCustomizer; -import io.opentelemetry.javaagent.bootstrap.http.HttpServerResponseCustomizerHolder; -import io.opentelemetry.javaagent.bootstrap.http.HttpServerResponseMutator; import io.opentelemetry.javaagent.bootstrap.internal.InstrumentationConfig; import io.opentelemetry.javaagent.extension.AgentListener; import io.opentelemetry.javaagent.extension.ignore.IgnoredTypesConfigurer; @@ -185,8 +182,6 @@ private static void installBytebuddyAgent( ResettableClassFileTransformer resettableClassFileTransformer = agentBuilder.installOn(inst); ClassFileTransformerHolder.setClassFileTransformer(resettableClassFileTransformer); - addHttpServerResponseCustomizers(extensionClassLoader); - runAfterAgentListeners(agentListeners, autoConfiguredSdk); } @@ -239,23 +234,6 @@ private static AgentBuilder configureIgnoredTypes( }); } - private static void addHttpServerResponseCustomizers(ClassLoader extensionClassLoader) { - List customizers = - load(HttpServerResponseCustomizer.class, extensionClassLoader); - - HttpServerResponseCustomizerHolder.setCustomizer( - new HttpServerResponseCustomizer() { - @Override - public void customize( - Context serverContext, T response, HttpServerResponseMutator responseMutator) { - - for (HttpServerResponseCustomizer modifier : customizers) { - modifier.customize(serverContext, response, responseMutator); - } - } - }); - } - private static void runAfterAgentListeners( Iterable agentListeners, AutoConfiguredOpenTelemetrySdk autoConfiguredSdk) { // java.util.logging.LogManager maintains a final static LogManager, which is created during 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"); + } +} From 7c61b0479909fb201a43c1c68e1a86354f0101fd Mon Sep 17 00:00:00 2001 From: adamleantech <65166709+adamleantech@users.noreply.github.com> Date: Thu, 16 Mar 2023 12:06:08 +0000 Subject: [PATCH 2/3] revert accidental changes --- .../javaagent/tooling/AgentInstaller.java | 28 +++++++++++++++++-- 1 file changed, 25 insertions(+), 3 deletions(-) diff --git a/javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/AgentInstaller.java b/javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/AgentInstaller.java index dbb6734b95bc..8375cb4219d3 100644 --- a/javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/AgentInstaller.java +++ b/javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/AgentInstaller.java @@ -22,6 +22,9 @@ import io.opentelemetry.javaagent.bootstrap.ClassFileTransformerHolder; import io.opentelemetry.javaagent.bootstrap.DefineClassHelper; import io.opentelemetry.javaagent.bootstrap.InstrumentedTaskClasses; +import io.opentelemetry.javaagent.bootstrap.http.HttpServerResponseCustomizer; +import io.opentelemetry.javaagent.bootstrap.http.HttpServerResponseCustomizerHolder; +import io.opentelemetry.javaagent.bootstrap.http.HttpServerResponseMutator; import io.opentelemetry.javaagent.bootstrap.internal.InstrumentationConfig; import io.opentelemetry.javaagent.extension.AgentListener; import io.opentelemetry.javaagent.extension.ignore.IgnoredTypesConfigurer; @@ -126,9 +129,9 @@ private static void installBytebuddyAgent( AgentBuilder agentBuilder = new AgentBuilder.Default( - // default method graph compiler inspects the class hierarchy, we don't need it, so - // we use a simpler and faster strategy instead - new ByteBuddy().with(MethodGraph.Compiler.ForDeclaredMethods.INSTANCE)) + // default method graph compiler inspects the class hierarchy, we don't need it, so + // we use a simpler and faster strategy instead + new ByteBuddy().with(MethodGraph.Compiler.ForDeclaredMethods.INSTANCE)) .disableClassFormatChanges() // disableClassFormatChanges sets type strategy to TypeStrategy.Default.REDEFINE_FROZEN // we'll wrap it with our own strategy @@ -182,6 +185,8 @@ private static void installBytebuddyAgent( ResettableClassFileTransformer resettableClassFileTransformer = agentBuilder.installOn(inst); ClassFileTransformerHolder.setClassFileTransformer(resettableClassFileTransformer); + addHttpServerResponseCustomizers(extensionClassLoader); + runAfterAgentListeners(agentListeners, autoConfiguredSdk); } @@ -234,6 +239,23 @@ private static AgentBuilder configureIgnoredTypes( }); } + private static void addHttpServerResponseCustomizers(ClassLoader extensionClassLoader) { + List customizers = + load(HttpServerResponseCustomizer.class, extensionClassLoader); + + HttpServerResponseCustomizerHolder.setCustomizer( + new HttpServerResponseCustomizer() { + @Override + public void customize( + Context serverContext, T response, HttpServerResponseMutator responseMutator) { + + for (HttpServerResponseCustomizer modifier : customizers) { + modifier.customize(serverContext, response, responseMutator); + } + } + }); + } + private static void runAfterAgentListeners( Iterable agentListeners, AutoConfiguredOpenTelemetrySdk autoConfiguredSdk) { // java.util.logging.LogManager maintains a final static LogManager, which is created during From e637d1a1dd505a4bcbae2eae9308ef1faadd2d18 Mon Sep 17 00:00:00 2001 From: adamleantech <65166709+adamleantech@users.noreply.github.com> Date: Thu, 16 Mar 2023 12:07:52 +0000 Subject: [PATCH 3/3] revert accidental changes --- .../io/opentelemetry/javaagent/tooling/AgentInstaller.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/AgentInstaller.java b/javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/AgentInstaller.java index 8375cb4219d3..149143c8d27e 100644 --- a/javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/AgentInstaller.java +++ b/javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/AgentInstaller.java @@ -129,9 +129,9 @@ private static void installBytebuddyAgent( AgentBuilder agentBuilder = new AgentBuilder.Default( - // default method graph compiler inspects the class hierarchy, we don't need it, so - // we use a simpler and faster strategy instead - new ByteBuddy().with(MethodGraph.Compiler.ForDeclaredMethods.INSTANCE)) + // default method graph compiler inspects the class hierarchy, we don't need it, so + // we use a simpler and faster strategy instead + new ByteBuddy().with(MethodGraph.Compiler.ForDeclaredMethods.INSTANCE)) .disableClassFormatChanges() // disableClassFormatChanges sets type strategy to TypeStrategy.Default.REDEFINE_FROZEN // we'll wrap it with our own strategy