Migrate opentelemetry-api testing module to Instrumenter API (#4580)

This commit is contained in:
Mateusz Rzeszutek 2021-11-04 18:23:51 +01:00 committed by GitHub
parent a9ed1ae030
commit f3cbf25a89
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 96 additions and 152 deletions

View File

@ -11,7 +11,6 @@ import io.opentelemetry.context.ContextKey
import io.opentelemetry.extension.annotations.WithSpan
import io.opentelemetry.instrumentation.api.instrumenter.SpanKey
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.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"() {
expect:
AgentSpanTesting.runWithClientSpan("client") {

View File

@ -13,14 +13,6 @@ public class AgentSpanTesting {
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
* spanName}.

View File

@ -24,8 +24,6 @@ public class AgentSpanTestingInstrumentation implements TypeInstrumentation {
public void transform(TypeTransformer transformer) {
transformer.applyAdviceToMethod(
named("runWithServerSpan"), this.getClass().getName() + "$RunWithServerSpanAdvice");
transformer.applyAdviceToMethod(
named("runWithConsumerSpan"), this.getClass().getName() + "$RunWithConsumerSpanAdvice");
transformer.applyAdviceToMethod(
named("runWithClientSpan"), this.getClass().getName() + "$RunWithClientSpanAdvice");
transformer.applyAdviceToMethod(
@ -40,7 +38,7 @@ public class AgentSpanTestingInstrumentation implements TypeInstrumentation {
@Advice.Argument(0) String spanName,
@Advice.Local("otelContext") Context context,
@Advice.Local("otelScope") Scope scope) {
context = AgentSpanTestingTracer.tracer().startServerSpan(spanName);
context = AgentSpanTestingInstrumenter.startServerSpan(spanName);
scope = context.makeCurrent();
}
@ -50,37 +48,7 @@ public class AgentSpanTestingInstrumentation implements TypeInstrumentation {
@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);
}
}
}
@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);
}
AgentSpanTestingInstrumenter.end(context, throwable);
}
}
@ -92,7 +60,7 @@ public class AgentSpanTestingInstrumentation implements TypeInstrumentation {
@Advice.Argument(0) String spanName,
@Advice.Local("otelContext") Context context,
@Advice.Local("otelScope") Scope scope) {
context = AgentSpanTestingTracer.tracer().startClientSpan(spanName);
context = AgentSpanTestingInstrumenter.startClientSpan(spanName);
scope = context.makeCurrent();
}
@ -102,11 +70,7 @@ public class AgentSpanTestingInstrumentation implements TypeInstrumentation {
@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);
}
AgentSpanTestingInstrumenter.end(context, throwable);
}
}
@ -118,7 +82,7 @@ public class AgentSpanTestingInstrumentation implements TypeInstrumentation {
@Advice.Argument(0) String spanName,
@Advice.Local("otelContext") Context context,
@Advice.Local("otelScope") Scope scope) {
context = AgentSpanTestingTracer.tracer().startSpanWithAllKeys(spanName);
context = AgentSpanTestingInstrumenter.startSpanWithAllKeys(spanName);
scope = context.makeCurrent();
}
@ -128,11 +92,7 @@ public class AgentSpanTestingInstrumentation implements TypeInstrumentation {
@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);
}
AgentSpanTestingInstrumenter.end(context, throwable);
}
}
}

View File

@ -18,7 +18,7 @@ public class AgentSpanTestingInstrumentationModule extends InstrumentationModule
@Override
public boolean isHelperClass(String className) {
return className.startsWith("AgentSpanTestingTracer");
return className.startsWith("AgentSpanTestingInstrumenter");
}
@Override

View File

@ -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() {}
}

View File

@ -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);
}
}
}
}