Update methods-javaagent to Instrumenter API (#3070)
* Update methods-javaagent to Instrumenter API Signed-off-by: dengliming <liming.d.pro@gmail.com> * introduce SpanNames Signed-off-by: dengliming <liming.d.pro@gmail.com> * Add test for SpanNames Signed-off-by: dengliming <liming.d.pro@gmail.com> * Fix merge * Codenarc * Remove unused dep Co-authored-by: Trask Stalnaker <trask.stalnaker@gmail.com>
This commit is contained in:
parent
b5f949afb2
commit
ca5b792f95
|
@ -181,43 +181,45 @@ public abstract class BaseTracer {
|
|||
/**
|
||||
* This method is used to generate an acceptable span (operation) name based on a given method
|
||||
* reference. Anonymous classes are named based on their parent.
|
||||
*
|
||||
* @deprecated Use {@link SpanNames#spanNameForMethod(Method)}.
|
||||
*/
|
||||
@Deprecated
|
||||
public static String spanNameForMethod(Method method) {
|
||||
return spanNameForMethod(method.getDeclaringClass(), method.getName());
|
||||
return SpanNames.spanNameForMethod(method);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is used to generate an acceptable span (operation) name based on a given method
|
||||
* reference. Anonymous classes are named based on their parent.
|
||||
*
|
||||
* @deprecated Use {@link SpanNames#spanNameForMethod(Class, Method)}.
|
||||
*/
|
||||
@Deprecated
|
||||
public static String spanNameForMethod(Class<?> clazz, @Nullable Method method) {
|
||||
return spanNameForMethod(clazz, method == null ? "<unknown>" : method.getName());
|
||||
return SpanNames.spanNameForMethod(clazz, method);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is used to generate an acceptable span (operation) name based on a given method
|
||||
* reference. Anonymous classes are named based on their parent.
|
||||
*
|
||||
* @deprecated Use {@link SpanNames#spanNameForMethod(Class, String)}.
|
||||
*/
|
||||
@Deprecated
|
||||
public static String spanNameForMethod(Class<?> cl, String methodName) {
|
||||
return spanNameForClass(cl) + "." + methodName;
|
||||
return SpanNames.spanNameForMethod(cl, methodName);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is used to generate an acceptable span (operation) name based on a given class
|
||||
* reference. Anonymous classes are named based on their parent.
|
||||
*
|
||||
* @deprecated Use {@link SpanNames#spanNameForClass(Class)}.
|
||||
*/
|
||||
@Deprecated
|
||||
public static String spanNameForClass(Class<?> clazz) {
|
||||
if (!clazz.isAnonymousClass()) {
|
||||
return clazz.getSimpleName();
|
||||
}
|
||||
String className = clazz.getName();
|
||||
if (clazz.getPackage() != null) {
|
||||
String pkgName = clazz.getPackage().getName();
|
||||
if (!pkgName.isEmpty()) {
|
||||
className = className.substring(pkgName.length() + 1);
|
||||
}
|
||||
}
|
||||
return className;
|
||||
return SpanNames.spanNameForClass(clazz);
|
||||
}
|
||||
|
||||
/** Ends the execution of a span stored in the passed {@code context}. */
|
||||
|
|
|
@ -0,0 +1,55 @@
|
|||
/*
|
||||
* Copyright The OpenTelemetry Authors
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package io.opentelemetry.instrumentation.api.tracer;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
|
||||
public final class SpanNames {
|
||||
/**
|
||||
* This method is used to generate an acceptable span (operation) name based on a given method
|
||||
* reference. Anonymous classes are named based on their parent.
|
||||
*/
|
||||
public static String spanNameForMethod(Method method) {
|
||||
return spanNameForMethod(method.getDeclaringClass(), method.getName());
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is used to generate an acceptable span (operation) name based on a given method
|
||||
* reference. Anonymous classes are named based on their parent.
|
||||
*/
|
||||
public static String spanNameForMethod(Class<?> clazz, @Nullable Method method) {
|
||||
return spanNameForMethod(clazz, method == null ? "<unknown>" : method.getName());
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is used to generate an acceptable span (operation) name based on a given method
|
||||
* reference. Anonymous classes are named based on their parent.
|
||||
*/
|
||||
public static String spanNameForMethod(Class<?> cl, String methodName) {
|
||||
return spanNameForClass(cl) + "." + methodName;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is used to generate an acceptable span (operation) name based on a given class
|
||||
* reference. Anonymous classes are named based on their parent.
|
||||
*/
|
||||
public static String spanNameForClass(Class<?> clazz) {
|
||||
if (!clazz.isAnonymousClass()) {
|
||||
return clazz.getSimpleName();
|
||||
}
|
||||
String className = clazz.getName();
|
||||
if (clazz.getPackage() != null) {
|
||||
String pkgName = clazz.getPackage().getName();
|
||||
if (!pkgName.isEmpty()) {
|
||||
className = className.substring(pkgName.length() + 1);
|
||||
}
|
||||
}
|
||||
return className;
|
||||
}
|
||||
|
||||
private SpanNames() {}
|
||||
}
|
|
@ -0,0 +1,51 @@
|
|||
/*
|
||||
* Copyright The OpenTelemetry Authors
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package io.opentelemetry.instrumentation.api.tracer
|
||||
|
||||
import org.spockframework.util.ReflectionUtil
|
||||
import spock.lang.Specification
|
||||
|
||||
class SpanNamesTest extends Specification {
|
||||
|
||||
def "test spanNameForClass"() {
|
||||
when:
|
||||
String result = SpanNames.spanNameForClass(clazz)
|
||||
|
||||
then:
|
||||
result == expected
|
||||
|
||||
where:
|
||||
clazz | expected
|
||||
SpanNamesTest | "SpanNamesTest"
|
||||
SpanNames | "SpanNames"
|
||||
}
|
||||
|
||||
def "test spanNameForMethod"() {
|
||||
when:
|
||||
String result = SpanNames.spanNameForMethod(method)
|
||||
|
||||
then:
|
||||
result == expected
|
||||
|
||||
where:
|
||||
method | expected
|
||||
ReflectionUtil.getMethodByName(SpanNames, "spanNameForClass") | "SpanNames.spanNameForClass"
|
||||
ReflectionUtil.getMethodByName(String, "length") | "String.length"
|
||||
}
|
||||
|
||||
def "test spanNameForMethod with class"() {
|
||||
when:
|
||||
String result = SpanNames.spanNameForMethod(clazz, method)
|
||||
|
||||
then:
|
||||
result == expected
|
||||
|
||||
where:
|
||||
clazz | method | expected
|
||||
SpanNames | ReflectionUtil.getMethodByName(SpanNames, "spanNameForClass") | "SpanNames.spanNameForClass"
|
||||
SpanNames | "test" | "SpanNames.test"
|
||||
}
|
||||
}
|
|
@ -7,7 +7,8 @@ package io.opentelemetry.javaagent.instrumentation.methods;
|
|||
|
||||
import static io.opentelemetry.javaagent.extension.matcher.AgentElementMatchers.safeHasSuperType;
|
||||
import static io.opentelemetry.javaagent.extension.matcher.ClassLoaderMatcher.hasClassesNamed;
|
||||
import static io.opentelemetry.javaagent.instrumentation.methods.MethodTracer.tracer;
|
||||
import static io.opentelemetry.javaagent.instrumentation.api.Java8BytecodeBridge.currentContext;
|
||||
import static io.opentelemetry.javaagent.instrumentation.methods.MethodInstrumenters.instrumenter;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.named;
|
||||
|
||||
import io.opentelemetry.context.Context;
|
||||
|
@ -62,21 +63,23 @@ public class MethodInstrumentation implements TypeInstrumentation {
|
|||
@Advice.Origin Method method,
|
||||
@Advice.Local("otelContext") Context context,
|
||||
@Advice.Local("otelScope") Scope scope) {
|
||||
context = tracer().startSpan(method);
|
||||
Context parentContext = currentContext();
|
||||
if (!instrumenter().shouldStart(parentContext, method)) {
|
||||
return;
|
||||
}
|
||||
|
||||
context = instrumenter().start(parentContext, method);
|
||||
scope = context.makeCurrent();
|
||||
}
|
||||
|
||||
@Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class)
|
||||
public static void stopSpan(
|
||||
@Advice.Origin Method method,
|
||||
@Advice.Local("otelContext") Context context,
|
||||
@Advice.Local("otelScope") Scope scope,
|
||||
@Advice.Thrown Throwable throwable) {
|
||||
scope.close();
|
||||
if (throwable != null) {
|
||||
tracer().endExceptionally(context, throwable);
|
||||
} else {
|
||||
tracer().end(context);
|
||||
}
|
||||
instrumenter().end(context, method, null, throwable);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -53,7 +53,7 @@ public class MethodInstrumentationModule extends InstrumentationModule {
|
|||
public List<String> getMuzzleHelperClassNames() {
|
||||
return typeInstrumentations.isEmpty()
|
||||
? emptyList()
|
||||
: singletonList("io.opentelemetry.javaagent.instrumentation.methods.MethodTracer");
|
||||
: singletonList("io.opentelemetry.javaagent.instrumentation.methods.MethodInstrumenters");
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -0,0 +1,35 @@
|
|||
/*
|
||||
* Copyright The OpenTelemetry Authors
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package io.opentelemetry.javaagent.instrumentation.methods;
|
||||
|
||||
import io.opentelemetry.api.GlobalOpenTelemetry;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.SpanKindExtractor;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.SpanNameExtractor;
|
||||
import io.opentelemetry.instrumentation.api.tracer.SpanNames;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
public final class MethodInstrumenters {
|
||||
private static final String INSTRUMENTATION_NAME =
|
||||
"io.opentelemetry.javaagent.external-annotations";
|
||||
|
||||
private static final Instrumenter<Method, Void> INSTRUMENTER;
|
||||
|
||||
static {
|
||||
SpanNameExtractor<Method> spanName = SpanNames::spanNameForMethod;
|
||||
|
||||
INSTRUMENTER =
|
||||
Instrumenter.<Method, Void>newBuilder(
|
||||
GlobalOpenTelemetry.get(), INSTRUMENTATION_NAME, spanName)
|
||||
.newInstrumenter(SpanKindExtractor.alwaysInternal());
|
||||
}
|
||||
|
||||
public static Instrumenter<Method, Void> instrumenter() {
|
||||
return INSTRUMENTER;
|
||||
}
|
||||
|
||||
private MethodInstrumenters() {}
|
||||
}
|
|
@ -1,27 +0,0 @@
|
|||
/*
|
||||
* Copyright The OpenTelemetry Authors
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package io.opentelemetry.javaagent.instrumentation.methods;
|
||||
|
||||
import io.opentelemetry.context.Context;
|
||||
import io.opentelemetry.instrumentation.api.tracer.BaseTracer;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
public class MethodTracer extends BaseTracer {
|
||||
private static final MethodTracer TRACER = new MethodTracer();
|
||||
|
||||
public static MethodTracer tracer() {
|
||||
return TRACER;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getInstrumentationName() {
|
||||
return "io.opentelemetry.javaagent.external-annotations";
|
||||
}
|
||||
|
||||
public Context startSpan(Method method) {
|
||||
return startSpan(spanNameForMethod(method));
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue