Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
2 changes: 1 addition & 1 deletion instrumentation/external-annotations/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,6 @@ common vendor annotations by default, and additional annotations can be targeted
configuration property "otel.instrumentation.external-annotations.include".

| System property | Type | Default | Description |
| ----------------------------------------------------------- | ------ | ------------------- | --------------------------------------------------------------------------------------------------------- |
|-------------------------------------------------------------|--------|---------------------|-----------------------------------------------------------------------------------------------------------|
| `otel.instrumentation.external-annotations.include` | String | Default annotations | Configuration for trace annotations, in the form of a pattern that matches `'package.Annotation$Name;*'`. |
| `otel.instrumentation.external-annotations.exclude-methods` | String | | All methods to be excluded from auto-instrumentation by annotation-based advices. |
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@
import io.opentelemetry.context.Scope;
import io.opentelemetry.instrumentation.api.incubator.config.internal.InstrumentationConfig;
import io.opentelemetry.instrumentation.api.incubator.semconv.util.ClassAndMethod;
import io.opentelemetry.javaagent.bootstrap.Java8BytecodeBridge;
import io.opentelemetry.javaagent.bootstrap.internal.AgentInstrumentationConfig;
import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation;
import io.opentelemetry.javaagent.extension.instrumentation.TypeTransformer;
Expand All @@ -32,6 +31,7 @@
import java.util.Map;
import java.util.Set;
import java.util.logging.Logger;
import javax.annotation.Nullable;
import net.bytebuddy.asm.Advice;
import net.bytebuddy.description.ByteCodeElement;
import net.bytebuddy.description.NamedElement;
Expand Down Expand Up @@ -168,36 +168,48 @@ private static ElementMatcher.Junction<MethodDescription> configureExcludedMetho
@SuppressWarnings("unused")
public static class ExternalAnnotationAdvice {

@Advice.OnMethodEnter(suppress = Throwable.class)
public static void onEnter(
@Advice.Origin("#t") Class<?> declaringClass,
@Advice.Origin("#m") String methodName,
@Advice.Local("otelRequest") ClassAndMethod request,
@Advice.Local("otelContext") Context context,
@Advice.Local("otelScope") Scope scope) {

Context parentContext = Java8BytecodeBridge.currentContext();
request = ClassAndMethod.create(declaringClass, methodName);
if (!instrumenter().shouldStart(parentContext, request)) {
return;
public static class AdviceScope {
private final ClassAndMethod classAndMethod;
private final Context context;
private final Scope scope;

private AdviceScope(ClassAndMethod classAndMethod, Context context, Scope scope) {
this.classAndMethod = classAndMethod;
this.context = context;
this.scope = scope;
}

@Nullable
public static AdviceScope start(Class<?> declaringClass, String methodName) {
Context parentContext = Context.current();
ClassAndMethod classAndMethod = ClassAndMethod.create(declaringClass, methodName);
if (!instrumenter().shouldStart(parentContext, classAndMethod)) {
return null;
}

Context context = instrumenter().start(parentContext, classAndMethod);
return new AdviceScope(classAndMethod, context, context.makeCurrent());
}

context = instrumenter().start(parentContext, request);
scope = context.makeCurrent();
public void end(@Nullable Throwable throwable) {
scope.close();
instrumenter().end(context, classAndMethod, null, throwable);
}
}

@Advice.OnMethodEnter(suppress = Throwable.class)
public static AdviceScope onEnter(
@Advice.Origin("#t") Class<?> declaringClass, @Advice.Origin("#m") String methodName) {
return AdviceScope.start(declaringClass, methodName);
}

@Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class)
public static void stopSpan(
@Advice.Local("otelRequest") ClassAndMethod request,
@Advice.Local("otelContext") Context context,
@Advice.Local("otelScope") Scope scope,
@Advice.Thrown Throwable throwable) {

if (scope == null) {
return;
@Advice.Thrown @Nullable Throwable throwable,
@Advice.Enter @Nullable AdviceScope adviceScope) {
if (adviceScope != null) {
adviceScope.end(throwable);
}
scope.close();
instrumenter().end(context, request, null, throwable);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,12 @@
import com.google.auto.service.AutoService;
import io.opentelemetry.javaagent.extension.instrumentation.InstrumentationModule;
import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation;
import io.opentelemetry.javaagent.extension.instrumentation.internal.ExperimentalInstrumentationModule;
import java.util.List;

@AutoService(InstrumentationModule.class)
public class ExternalAnnotationInstrumentationModule extends InstrumentationModule {
public class ExternalAnnotationInstrumentationModule extends InstrumentationModule
implements ExperimentalInstrumentationModule {

public ExternalAnnotationInstrumentationModule() {
super("external-annotations");
Expand All @@ -23,4 +25,9 @@ public ExternalAnnotationInstrumentationModule() {
public List<TypeInstrumentation> typeInstrumentations() {
return singletonList(new ExternalAnnotationInstrumentation());
}

@Override
public boolean isIndyReady() {
return true;
}
}
Loading