Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ muzzle {
module.set("azure-core")
versions.set("[1.53.0,)")
assertInverse.set(true)
// our advice helper bridges an explicitly supplied application parent context to the agent
// context, so it references io.opentelemetry.context.{Context,Scope}
extraDependency("io.opentelemetry:opentelemetry-api:1.27.0")
}
}

Expand All @@ -24,6 +27,10 @@ sourceSets {
dependencies {
compileOnly(project(":instrumentation:azure-core:azure-core-1.53:library-instrumentation-shaded", configuration = "shadow"))

// needed to bridge an explicitly supplied application parent context (the unshaded
// "application.io.opentelemetry.*" types) to the agent context inside our advice
compileOnly(project(":opentelemetry-api-shaded-for-instrumenting", configuration = "shadow"))

library("com.azure:azure-core:1.53.0")

// Ensure no cross interference
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/

package io.opentelemetry.javaagent.instrumentation.azurecore.v1_53;

import static net.bytebuddy.matcher.ElementMatchers.named;
import static net.bytebuddy.matcher.ElementMatchers.takesArguments;

import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation;
import io.opentelemetry.javaagent.extension.instrumentation.TypeTransformer;
import java.util.Optional;
import net.bytebuddy.asm.Advice;
import net.bytebuddy.asm.Advice.AssignReturned;
import net.bytebuddy.description.type.TypeDescription;
import net.bytebuddy.matcher.ElementMatcher;

/**
* Bridges an explicitly supplied parent context for {@code azure-core-tracing-opentelemetry}.
*
* <p>When a user passes a parent context to an Azure SDK call, the value is stored on the {@link
* com.azure.core.util.Context} under the {@code "trace-context"} key as the application's (unshaded)
* {@code io.opentelemetry.context.Context}. The bundled {@code OpenTelemetryTracer} reads that value
* back and expects it to be the agent's (shaded) context. Convert it here so the tracer does not
* need to reach into agent internals reflectively.
*/
class AzureContextInstrumentation implements TypeInstrumentation {

@Override
public ElementMatcher<TypeDescription> typeMatcher() {
return named("com.azure.core.util.Context");
}

@Override
public void transform(TypeTransformer transformer) {
transformer.applyAdviceToMethod(
named("getData").and(takesArguments(1)),
getClass().getName() + "$GetDataAdvice");
}

@SuppressWarnings("unused")
public static class GetDataAdvice {
@AssignReturned.ToReturned
@Advice.OnMethodExit(suppress = Throwable.class, inline = false)
public static Optional<Object> onExit(
@Advice.Argument(0) Object key, @Advice.Return Optional<Object> data) {
return AzureExplicitParentContextHelper.bridgeApplicationContext(key, data);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/

package io.opentelemetry.javaagent.instrumentation.azurecore.v1_53;

import io.opentelemetry.context.Context;
import java.util.Optional;

/**
* Converts an explicitly supplied application parent context into the agent context.
*
* <p>In the agent the application's {@code io.opentelemetry.context.Context} (referenced here as
* {@code application.io.opentelemetry.context.Context}) is bridged to the agent context by the
* opentelemetry-api instrumentation. Making the application context current and reading back the
* agent context performs that conversion using only public API, so this works in both inline and
* indy mode without reaching into agent-internal helper classes.
*/
public final class AzureExplicitParentContextHelper {

// azure-core-tracing-opentelemetry stores the explicit parent context under this key
private static final String PARENT_TRACE_CONTEXT_KEY = "trace-context";
Comment thread
trask marked this conversation as resolved.
Outdated

public static Optional<Object> bridgeApplicationContext(Object key, Optional<Object> data) {
if (!PARENT_TRACE_CONTEXT_KEY.equals(key) || data == null || !data.isPresent()) {
return data;
}
Object value = data.get();
if (!(value instanceof application.io.opentelemetry.context.Context)) {
return data;
}
application.io.opentelemetry.context.Context applicationContext =
(application.io.opentelemetry.context.Context) value;
Context agentContext;
try (application.io.opentelemetry.context.Scope ignored = applicationContext.makeCurrent()) {
agentContext = Context.current();
}
return Optional.of(agentContext);
}

private AzureExplicitParentContextHelper() {}
}
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,10 @@ public ElementMatcher.Junction<ClassLoader> classLoaderMatcher() {

@Override
public List<TypeInstrumentation> typeInstrumentations() {
return asList(new EmptyTypeInstrumentation(), new AzureHttpClientInstrumentation());
return asList(
new EmptyTypeInstrumentation(),
new AzureContextInstrumentation(),
new AzureHttpClientInstrumentation());
Comment thread
trask marked this conversation as resolved.
}

private static class EmptyTypeInstrumentation implements TypeInstrumentation {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@
import com.azure.core.util.TracingOptions;
import com.azure.core.util.tracing.Tracer;
import com.azure.core.util.tracing.TracerProvider;
import io.opentelemetry.api.GlobalOpenTelemetry;
import io.opentelemetry.api.trace.Span;
import io.opentelemetry.api.trace.SpanKind;
import io.opentelemetry.instrumentation.api.internal.SpanKey;
import io.opentelemetry.instrumentation.testing.junit.AgentInstrumentationExtension;
Expand Down Expand Up @@ -78,6 +80,34 @@ void testSpan() {
equalTo(stringKey("az.namespace"), "otel.tests"))));
}

@Test
void testExplicitParentContextBridge() {
// Azure's bundled OpenTelemetryTracer reflectively calls
// io.opentelemetry.javaagent.instrumentation.opentelemetryapi.context.AgentContextStorage
// #getAgentContext(application io.opentelemetry.context.Context)
// to convert an explicitly-supplied application context into the agent (shaded) context.
// This test exercises that path: the parent span is supplied only via the Azure context bag
// under PARENT_TRACE_CONTEXT_KEY and is never made current, so the only way the child can be
// linked to it is through the reflective bridge.
Comment thread
trask marked this conversation as resolved.
Outdated
Tracer azTracer = createAzTracer();

Span parentSpan = GlobalOpenTelemetry.getTracer("test").spanBuilder("parent").startSpan();
// application (unshaded) context carrying the parent span, NOT made current
io.opentelemetry.context.Context parentContext =
io.opentelemetry.context.Context.root().with(parentSpan);

Context azContext = new Context(Tracer.PARENT_TRACE_CONTEXT_KEY, parentContext);
Context child = azTracer.start("child", azContext);
azTracer.end(null, null, child);
parentSpan.end();

testing.waitAndAssertTracesWithoutScopeVersionVerification(
trace ->
trace.hasSpansSatisfyingExactly(
span -> span.hasName("parent").hasNoParent(),
span -> span.hasName("child").hasParent(trace.getSpan(0))));
}

@Test
void testPipelineAndSuppression() {
AtomicBoolean hasClientAndHttpKeys = new AtomicBoolean(false);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,12 @@
* SPDX-License-Identifier: Apache-2.0
*/

package io.opentelemetry.javaagent.instrumentation.opentelemetryapi;
package io.opentelemetry.javaagent.instrumentation.opentelemetryapi.v1_0;

import io.opentelemetry.api.GlobalOpenTelemetry;
import io.opentelemetry.api.OpenTelemetry;
import io.opentelemetry.javaagent.instrumentation.opentelemetryapi.context.propagation.ApplicationContextPropagators;
import io.opentelemetry.javaagent.instrumentation.opentelemetryapi.trace.ApplicationTracerProvider;
import io.opentelemetry.javaagent.instrumentation.opentelemetryapi.v1_0.context.propagation.ApplicationContextPropagators;
import io.opentelemetry.javaagent.instrumentation.opentelemetryapi.v1_0.trace.ApplicationTracerProvider;
import javax.annotation.Nullable;

public class ApplicationOpenTelemetry implements application.io.opentelemetry.api.OpenTelemetry {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,14 @@
* SPDX-License-Identifier: Apache-2.0
*/

package io.opentelemetry.javaagent.instrumentation.opentelemetryapi;
package io.opentelemetry.javaagent.instrumentation.opentelemetryapi.v1_0;

import static net.bytebuddy.matcher.ElementMatchers.isStatic;
import static net.bytebuddy.matcher.ElementMatchers.named;

import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation;
import io.opentelemetry.javaagent.extension.instrumentation.TypeTransformer;
import io.opentelemetry.javaagent.instrumentation.opentelemetryapi.context.AgentContextStorage;
import io.opentelemetry.javaagent.instrumentation.opentelemetryapi.v1_0.context.AgentContextStorage;
import net.bytebuddy.asm.Advice;
import net.bytebuddy.asm.Advice.AssignReturned;
import net.bytebuddy.description.type.TypeDescription;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,13 @@
* SPDX-License-Identifier: Apache-2.0
*/

package io.opentelemetry.javaagent.instrumentation.opentelemetryapi;
package io.opentelemetry.javaagent.instrumentation.opentelemetryapi.v1_0;

import static net.bytebuddy.matcher.ElementMatchers.named;

import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation;
import io.opentelemetry.javaagent.extension.instrumentation.TypeTransformer;
import io.opentelemetry.javaagent.instrumentation.opentelemetryapi.context.AgentContextStorage;
import io.opentelemetry.javaagent.instrumentation.opentelemetryapi.v1_0.context.AgentContextStorage;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Function;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
* SPDX-License-Identifier: Apache-2.0
*/

package io.opentelemetry.javaagent.instrumentation.opentelemetryapi;
package io.opentelemetry.javaagent.instrumentation.opentelemetryapi.v1_0;

import static net.bytebuddy.matcher.ElementMatchers.named;
import static net.bytebuddy.matcher.ElementMatchers.returns;
Expand All @@ -12,7 +12,7 @@
import io.opentelemetry.api.internal.InstrumentationUtil;
import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation;
import io.opentelemetry.javaagent.extension.instrumentation.TypeTransformer;
import io.opentelemetry.javaagent.instrumentation.opentelemetryapi.context.AgentContextStorage;
import io.opentelemetry.javaagent.instrumentation.opentelemetryapi.v1_0.context.AgentContextStorage;
import net.bytebuddy.asm.Advice;
import net.bytebuddy.asm.Advice.AssignReturned;
import net.bytebuddy.description.type.TypeDescription;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
* SPDX-License-Identifier: Apache-2.0
*/

package io.opentelemetry.javaagent.instrumentation.opentelemetryapi;
package io.opentelemetry.javaagent.instrumentation.opentelemetryapi.v1_0;

import static java.util.Arrays.asList;
import static java.util.Collections.singletonList;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
* SPDX-License-Identifier: Apache-2.0
*/

package io.opentelemetry.javaagent.instrumentation.opentelemetryapi;
package io.opentelemetry.javaagent.instrumentation.opentelemetryapi.v1_0;

import static java.util.logging.Level.WARNING;
import static net.bytebuddy.matcher.ElementMatchers.isStatic;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,15 @@
* SPDX-License-Identifier: Apache-2.0
*/

package io.opentelemetry.javaagent.instrumentation.opentelemetryapi;
package io.opentelemetry.javaagent.instrumentation.opentelemetryapi.v1_0;

import static net.bytebuddy.matcher.ElementMatchers.isStatic;
import static net.bytebuddy.matcher.ElementMatchers.named;

import io.opentelemetry.api.trace.Span;
import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation;
import io.opentelemetry.javaagent.extension.instrumentation.TypeTransformer;
import io.opentelemetry.javaagent.instrumentation.opentelemetryapi.trace.Bridging;
import io.opentelemetry.javaagent.instrumentation.opentelemetryapi.v1_0.trace.Bridging;
import net.bytebuddy.asm.Advice;
import net.bytebuddy.asm.Advice.AssignReturned;
import net.bytebuddy.description.type.TypeDescription;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
* SPDX-License-Identifier: Apache-2.0
*/

package io.opentelemetry.javaagent.instrumentation.opentelemetryapi;
package io.opentelemetry.javaagent.instrumentation.opentelemetryapi.v1_0;

import java.util.function.Function;
import javax.annotation.Nullable;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
* SPDX-License-Identifier: Apache-2.0
*/

package io.opentelemetry.javaagent.instrumentation.opentelemetryapi.baggage;
package io.opentelemetry.javaagent.instrumentation.opentelemetryapi.v1_0.baggage;

import io.opentelemetry.api.baggage.Baggage;
import io.opentelemetry.api.baggage.BaggageBuilder;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
* SPDX-License-Identifier: Apache-2.0
*/

package io.opentelemetry.javaagent.instrumentation.opentelemetryapi.context;
package io.opentelemetry.javaagent.instrumentation.opentelemetryapi.v1_0.context;

import static java.util.logging.Level.FINE;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,12 @@
* SPDX-License-Identifier: Apache-2.0
*/

package io.opentelemetry.javaagent.instrumentation.opentelemetryapi.context;
package io.opentelemetry.javaagent.instrumentation.opentelemetryapi.v1_0.context;

import io.opentelemetry.api.trace.Span;
import io.opentelemetry.context.Context;
import io.opentelemetry.javaagent.instrumentation.opentelemetryapi.baggage.BaggageBridging;
import io.opentelemetry.javaagent.instrumentation.opentelemetryapi.trace.Bridging;
import io.opentelemetry.javaagent.instrumentation.opentelemetryapi.v1_0.baggage.BaggageBridging;
import io.opentelemetry.javaagent.instrumentation.opentelemetryapi.v1_0.trace.Bridging;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
* SPDX-License-Identifier: Apache-2.0
*/

package io.opentelemetry.javaagent.instrumentation.opentelemetryapi.context;
package io.opentelemetry.javaagent.instrumentation.opentelemetryapi.v1_0.context;

import io.opentelemetry.context.ContextKey;
import java.lang.reflect.Field;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@
* SPDX-License-Identifier: Apache-2.0
*/

package io.opentelemetry.javaagent.instrumentation.opentelemetryapi.context;
package io.opentelemetry.javaagent.instrumentation.opentelemetryapi.v1_0.context;

import io.opentelemetry.api.trace.Span;
import io.opentelemetry.javaagent.instrumentation.opentelemetryapi.trace.Bridging;
import io.opentelemetry.javaagent.instrumentation.opentelemetryapi.v1_0.trace.Bridging;
import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodType;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
* SPDX-License-Identifier: Apache-2.0
*/

package io.opentelemetry.javaagent.instrumentation.opentelemetryapi.context.propagation;
package io.opentelemetry.javaagent.instrumentation.opentelemetryapi.v1_0.context.propagation;

import io.opentelemetry.context.propagation.ContextPropagators;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,13 @@
* SPDX-License-Identifier: Apache-2.0
*/

package io.opentelemetry.javaagent.instrumentation.opentelemetryapi.context.propagation;
package io.opentelemetry.javaagent.instrumentation.opentelemetryapi.v1_0.context.propagation;

import io.opentelemetry.context.Context;
import io.opentelemetry.context.propagation.TextMapGetter;
import io.opentelemetry.context.propagation.TextMapPropagator;
import io.opentelemetry.context.propagation.TextMapSetter;
import io.opentelemetry.javaagent.instrumentation.opentelemetryapi.context.AgentContextStorage;
import io.opentelemetry.javaagent.instrumentation.opentelemetryapi.v1_0.context.AgentContextStorage;
import java.util.Collection;
import javax.annotation.Nullable;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,12 @@
* SPDX-License-Identifier: Apache-2.0
*/

package io.opentelemetry.javaagent.instrumentation.opentelemetryapi.trace;
package io.opentelemetry.javaagent.instrumentation.opentelemetryapi.v1_0.trace;

import com.google.errorprone.annotations.CanIgnoreReturnValue;
import io.opentelemetry.api.common.AttributeKey;
import io.opentelemetry.api.trace.Span;
import io.opentelemetry.javaagent.instrumentation.opentelemetryapi.ValueBridging;
import io.opentelemetry.javaagent.instrumentation.opentelemetryapi.v1_0.ValueBridging;
import java.util.concurrent.TimeUnit;
import javax.annotation.Nullable;

Expand Down
Loading
Loading