Migrate opentelemetry-api testing module to Instrumenter API (#4580)
This commit is contained in:
parent
a9ed1ae030
commit
f3cbf25a89
|
@ -11,7 +11,6 @@ import io.opentelemetry.context.ContextKey
|
||||||
import io.opentelemetry.extension.annotations.WithSpan
|
import io.opentelemetry.extension.annotations.WithSpan
|
||||||
import io.opentelemetry.instrumentation.api.instrumenter.SpanKey
|
import io.opentelemetry.instrumentation.api.instrumenter.SpanKey
|
||||||
import io.opentelemetry.instrumentation.api.tracer.ClientSpan
|
import io.opentelemetry.instrumentation.api.tracer.ClientSpan
|
||||||
import io.opentelemetry.instrumentation.api.tracer.ConsumerSpan
|
|
||||||
import io.opentelemetry.instrumentation.api.tracer.ServerSpan
|
import io.opentelemetry.instrumentation.api.tracer.ServerSpan
|
||||||
import io.opentelemetry.instrumentation.test.AgentInstrumentationSpecification
|
import io.opentelemetry.instrumentation.test.AgentInstrumentationSpecification
|
||||||
|
|
||||||
|
@ -161,17 +160,6 @@ class ContextBridgeTest extends AgentInstrumentationSpecification {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
def "test consumer span bridge"() {
|
|
||||||
expect:
|
|
||||||
AgentSpanTesting.runWithConsumerSpan("consumer") {
|
|
||||||
assert Span.current() != null
|
|
||||||
assert ConsumerSpan.fromContextOrNull(Context.current()) != null
|
|
||||||
runWithSpan("internal") {
|
|
||||||
assert ConsumerSpan.fromContextOrNull(Context.current()) != null
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
def "test client span bridge"() {
|
def "test client span bridge"() {
|
||||||
expect:
|
expect:
|
||||||
AgentSpanTesting.runWithClientSpan("client") {
|
AgentSpanTesting.runWithClientSpan("client") {
|
||||||
|
|
|
@ -13,14 +13,6 @@ public class AgentSpanTesting {
|
||||||
runnable.run();
|
runnable.run();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Runs the provided {@code runnable} inside the scope of an CONSUMER span with name {@code
|
|
||||||
* spanName}.
|
|
||||||
*/
|
|
||||||
public static void runWithConsumerSpan(String spanName, Runnable runnable) {
|
|
||||||
runnable.run();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Runs the provided {@code runnable} inside the scope of an CLIENT span with name {@code
|
* Runs the provided {@code runnable} inside the scope of an CLIENT span with name {@code
|
||||||
* spanName}.
|
* spanName}.
|
||||||
|
|
|
@ -24,8 +24,6 @@ public class AgentSpanTestingInstrumentation implements TypeInstrumentation {
|
||||||
public void transform(TypeTransformer transformer) {
|
public void transform(TypeTransformer transformer) {
|
||||||
transformer.applyAdviceToMethod(
|
transformer.applyAdviceToMethod(
|
||||||
named("runWithServerSpan"), this.getClass().getName() + "$RunWithServerSpanAdvice");
|
named("runWithServerSpan"), this.getClass().getName() + "$RunWithServerSpanAdvice");
|
||||||
transformer.applyAdviceToMethod(
|
|
||||||
named("runWithConsumerSpan"), this.getClass().getName() + "$RunWithConsumerSpanAdvice");
|
|
||||||
transformer.applyAdviceToMethod(
|
transformer.applyAdviceToMethod(
|
||||||
named("runWithClientSpan"), this.getClass().getName() + "$RunWithClientSpanAdvice");
|
named("runWithClientSpan"), this.getClass().getName() + "$RunWithClientSpanAdvice");
|
||||||
transformer.applyAdviceToMethod(
|
transformer.applyAdviceToMethod(
|
||||||
|
@ -40,7 +38,7 @@ public class AgentSpanTestingInstrumentation implements TypeInstrumentation {
|
||||||
@Advice.Argument(0) String spanName,
|
@Advice.Argument(0) String spanName,
|
||||||
@Advice.Local("otelContext") Context context,
|
@Advice.Local("otelContext") Context context,
|
||||||
@Advice.Local("otelScope") Scope scope) {
|
@Advice.Local("otelScope") Scope scope) {
|
||||||
context = AgentSpanTestingTracer.tracer().startServerSpan(spanName);
|
context = AgentSpanTestingInstrumenter.startServerSpan(spanName);
|
||||||
scope = context.makeCurrent();
|
scope = context.makeCurrent();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -50,37 +48,7 @@ public class AgentSpanTestingInstrumentation implements TypeInstrumentation {
|
||||||
@Advice.Local("otelContext") Context context,
|
@Advice.Local("otelContext") Context context,
|
||||||
@Advice.Local("otelScope") Scope scope) {
|
@Advice.Local("otelScope") Scope scope) {
|
||||||
scope.close();
|
scope.close();
|
||||||
if (throwable != null) {
|
AgentSpanTestingInstrumenter.end(context, throwable);
|
||||||
AgentSpanTestingTracer.tracer().endExceptionally(context, throwable);
|
|
||||||
} else {
|
|
||||||
AgentSpanTestingTracer.tracer().end(context);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("unused")
|
|
||||||
public static class RunWithConsumerSpanAdvice {
|
|
||||||
|
|
||||||
@Advice.OnMethodEnter(suppress = Throwable.class)
|
|
||||||
public static void onEnter(
|
|
||||||
@Advice.Argument(0) String spanName,
|
|
||||||
@Advice.Local("otelContext") Context context,
|
|
||||||
@Advice.Local("otelScope") Scope scope) {
|
|
||||||
context = AgentSpanTestingTracer.tracer().startConsumerSpan(spanName);
|
|
||||||
scope = context.makeCurrent();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class)
|
|
||||||
public static void onExit(
|
|
||||||
@Advice.Thrown Throwable throwable,
|
|
||||||
@Advice.Local("otelContext") Context context,
|
|
||||||
@Advice.Local("otelScope") Scope scope) {
|
|
||||||
scope.close();
|
|
||||||
if (throwable != null) {
|
|
||||||
AgentSpanTestingTracer.tracer().endExceptionally(context, throwable);
|
|
||||||
} else {
|
|
||||||
AgentSpanTestingTracer.tracer().end(context);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -92,7 +60,7 @@ public class AgentSpanTestingInstrumentation implements TypeInstrumentation {
|
||||||
@Advice.Argument(0) String spanName,
|
@Advice.Argument(0) String spanName,
|
||||||
@Advice.Local("otelContext") Context context,
|
@Advice.Local("otelContext") Context context,
|
||||||
@Advice.Local("otelScope") Scope scope) {
|
@Advice.Local("otelScope") Scope scope) {
|
||||||
context = AgentSpanTestingTracer.tracer().startClientSpan(spanName);
|
context = AgentSpanTestingInstrumenter.startClientSpan(spanName);
|
||||||
scope = context.makeCurrent();
|
scope = context.makeCurrent();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -102,11 +70,7 @@ public class AgentSpanTestingInstrumentation implements TypeInstrumentation {
|
||||||
@Advice.Local("otelContext") Context context,
|
@Advice.Local("otelContext") Context context,
|
||||||
@Advice.Local("otelScope") Scope scope) {
|
@Advice.Local("otelScope") Scope scope) {
|
||||||
scope.close();
|
scope.close();
|
||||||
if (throwable != null) {
|
AgentSpanTestingInstrumenter.end(context, throwable);
|
||||||
AgentSpanTestingTracer.tracer().endExceptionally(context, throwable);
|
|
||||||
} else {
|
|
||||||
AgentSpanTestingTracer.tracer().end(context);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -118,7 +82,7 @@ public class AgentSpanTestingInstrumentation implements TypeInstrumentation {
|
||||||
@Advice.Argument(0) String spanName,
|
@Advice.Argument(0) String spanName,
|
||||||
@Advice.Local("otelContext") Context context,
|
@Advice.Local("otelContext") Context context,
|
||||||
@Advice.Local("otelScope") Scope scope) {
|
@Advice.Local("otelScope") Scope scope) {
|
||||||
context = AgentSpanTestingTracer.tracer().startSpanWithAllKeys(spanName);
|
context = AgentSpanTestingInstrumenter.startSpanWithAllKeys(spanName);
|
||||||
scope = context.makeCurrent();
|
scope = context.makeCurrent();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -128,11 +92,7 @@ public class AgentSpanTestingInstrumentation implements TypeInstrumentation {
|
||||||
@Advice.Local("otelContext") Context context,
|
@Advice.Local("otelContext") Context context,
|
||||||
@Advice.Local("otelScope") Scope scope) {
|
@Advice.Local("otelScope") Scope scope) {
|
||||||
scope.close();
|
scope.close();
|
||||||
if (throwable != null) {
|
AgentSpanTestingInstrumenter.end(context, throwable);
|
||||||
AgentSpanTestingTracer.tracer().endExceptionally(context, throwable);
|
|
||||||
} else {
|
|
||||||
AgentSpanTestingTracer.tracer().end(context);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,7 +18,7 @@ public class AgentSpanTestingInstrumentationModule extends InstrumentationModule
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isHelperClass(String className) {
|
public boolean isHelperClass(String className) {
|
||||||
return className.startsWith("AgentSpanTestingTracer");
|
return className.startsWith("AgentSpanTestingInstrumenter");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -0,0 +1,89 @@
|
||||||
|
/*
|
||||||
|
* Copyright The OpenTelemetry Authors
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
import io.opentelemetry.api.GlobalOpenTelemetry;
|
||||||
|
import io.opentelemetry.api.trace.Span;
|
||||||
|
import io.opentelemetry.api.trace.SpanKind;
|
||||||
|
import io.opentelemetry.context.Context;
|
||||||
|
import io.opentelemetry.context.ContextKey;
|
||||||
|
import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter;
|
||||||
|
import io.opentelemetry.instrumentation.api.instrumenter.SpanKey;
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
|
||||||
|
public final class AgentSpanTestingInstrumenter {
|
||||||
|
|
||||||
|
private static final ContextKey<Request> REQUEST_CONTEXT_KEY =
|
||||||
|
ContextKey.named("test-request-key");
|
||||||
|
|
||||||
|
private static final Instrumenter<Request, Void> INSTRUMENTER =
|
||||||
|
Instrumenter.<Request, Void>builder(
|
||||||
|
GlobalOpenTelemetry.get(), "test", request -> request.name)
|
||||||
|
.addContextCustomizer(
|
||||||
|
(context, request, startAttributes) -> context.with(REQUEST_CONTEXT_KEY, request))
|
||||||
|
.newInstrumenter(request -> request.kind);
|
||||||
|
|
||||||
|
public static Context startServerSpan(String name) {
|
||||||
|
return start(name, SpanKind.SERVER);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Context startClientSpan(String name) {
|
||||||
|
return start(name, SpanKind.CLIENT);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Context startSpanWithAllKeys(String name) {
|
||||||
|
Context context = start(name, SpanKind.INTERNAL);
|
||||||
|
Span span = Span.fromContext(context);
|
||||||
|
for (SpanKey spanKey : SpanKeyAccess.getSpanKeys()) {
|
||||||
|
context = spanKey.storeInContext(context, span);
|
||||||
|
}
|
||||||
|
return context;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Context start(String name, SpanKind kind) {
|
||||||
|
return INSTRUMENTER.start(Context.current(), new Request(name, kind));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void end(Context context, Throwable error) {
|
||||||
|
INSTRUMENTER.end(context, context.get(REQUEST_CONTEXT_KEY), null, error);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final class Request {
|
||||||
|
private final String name;
|
||||||
|
private final SpanKind kind;
|
||||||
|
|
||||||
|
public Request(String name, SpanKind kind) {
|
||||||
|
this.name = name;
|
||||||
|
this.kind = kind;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final class SpanKeyAccess {
|
||||||
|
|
||||||
|
public static SpanKey[] getSpanKeys() {
|
||||||
|
return new SpanKey[] {
|
||||||
|
SpanKey.SERVER,
|
||||||
|
getSpanKeyByName("HTTP_CLIENT"),
|
||||||
|
getSpanKeyByName("RPC_CLIENT"),
|
||||||
|
getSpanKeyByName("DB_CLIENT"),
|
||||||
|
SpanKey.ALL_CLIENTS,
|
||||||
|
getSpanKeyByName("PRODUCER"),
|
||||||
|
getSpanKeyByName("CONSUMER_RECEIVE"),
|
||||||
|
getSpanKeyByName("CONSUMER_PROCESS")
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private static SpanKey getSpanKeyByName(String name) {
|
||||||
|
try {
|
||||||
|
Field field = SpanKey.class.getDeclaredField(name);
|
||||||
|
field.setAccessible(true);
|
||||||
|
return (SpanKey) field.get(name);
|
||||||
|
} catch (NoSuchFieldException | IllegalAccessException exception) {
|
||||||
|
throw new IllegalStateException("Failed to find span key named " + name, exception);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private AgentSpanTestingInstrumenter() {}
|
||||||
|
}
|
|
@ -1,85 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright The OpenTelemetry Authors
|
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
|
||||||
*/
|
|
||||||
|
|
||||||
import io.opentelemetry.api.GlobalOpenTelemetry;
|
|
||||||
import io.opentelemetry.api.trace.Span;
|
|
||||||
import io.opentelemetry.api.trace.SpanBuilder;
|
|
||||||
import io.opentelemetry.api.trace.SpanKind;
|
|
||||||
import io.opentelemetry.context.Context;
|
|
||||||
import io.opentelemetry.instrumentation.api.instrumenter.SpanKey;
|
|
||||||
import io.opentelemetry.instrumentation.api.tracer.BaseTracer;
|
|
||||||
import java.lang.reflect.Field;
|
|
||||||
|
|
||||||
public class AgentSpanTestingTracer extends BaseTracer {
|
|
||||||
private static final AgentSpanTestingTracer TRACER = new AgentSpanTestingTracer();
|
|
||||||
|
|
||||||
private AgentSpanTestingTracer() {
|
|
||||||
super(GlobalOpenTelemetry.get());
|
|
||||||
}
|
|
||||||
|
|
||||||
public static AgentSpanTestingTracer tracer() {
|
|
||||||
return TRACER;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Context startServerSpan(String name) {
|
|
||||||
Context parentContext = Context.current();
|
|
||||||
SpanBuilder spanBuilder = spanBuilder(parentContext, name, SpanKind.SERVER);
|
|
||||||
return withServerSpan(parentContext, spanBuilder.startSpan());
|
|
||||||
}
|
|
||||||
|
|
||||||
public Context startConsumerSpan(String name) {
|
|
||||||
Context parentContext = Context.current();
|
|
||||||
SpanBuilder spanBuilder = spanBuilder(parentContext, name, SpanKind.CONSUMER);
|
|
||||||
return withConsumerSpan(parentContext, spanBuilder.startSpan());
|
|
||||||
}
|
|
||||||
|
|
||||||
public Context startClientSpan(String name) {
|
|
||||||
Context parentContext = Context.current();
|
|
||||||
SpanBuilder spanBuilder = spanBuilder(parentContext, name, SpanKind.CLIENT);
|
|
||||||
return withClientSpan(parentContext, spanBuilder.startSpan());
|
|
||||||
}
|
|
||||||
|
|
||||||
public Context startSpanWithAllKeys(String name) {
|
|
||||||
Context parentContext = Context.current();
|
|
||||||
SpanBuilder spanBuilder = spanBuilder(parentContext, name, SpanKind.INTERNAL);
|
|
||||||
Span span = spanBuilder.startSpan();
|
|
||||||
Context newContext = parentContext.with(span);
|
|
||||||
for (SpanKey spanKey : SpanKeyAccess.getSpanKeys()) {
|
|
||||||
newContext = spanKey.storeInContext(newContext, span);
|
|
||||||
}
|
|
||||||
return newContext;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected String getInstrumentationName() {
|
|
||||||
return "agent-span-test-instrumentation";
|
|
||||||
}
|
|
||||||
|
|
||||||
private static class SpanKeyAccess {
|
|
||||||
|
|
||||||
public static SpanKey[] getSpanKeys() {
|
|
||||||
return new SpanKey[] {
|
|
||||||
SpanKey.SERVER,
|
|
||||||
getSpanKeyByName("HTTP_CLIENT"),
|
|
||||||
getSpanKeyByName("RPC_CLIENT"),
|
|
||||||
getSpanKeyByName("DB_CLIENT"),
|
|
||||||
SpanKey.ALL_CLIENTS,
|
|
||||||
getSpanKeyByName("PRODUCER"),
|
|
||||||
getSpanKeyByName("CONSUMER_RECEIVE"),
|
|
||||||
getSpanKeyByName("CONSUMER_PROCESS")
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
private static SpanKey getSpanKeyByName(String name) {
|
|
||||||
try {
|
|
||||||
Field field = SpanKey.class.getDeclaredField(name);
|
|
||||||
field.setAccessible(true);
|
|
||||||
return (SpanKey) field.get(name);
|
|
||||||
} catch (NoSuchFieldException | IllegalAccessException exception) {
|
|
||||||
throw new IllegalStateException("Failed to find span key named " + name, exception);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Reference in New Issue