Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

indy instrumentation - leftovers migration #13074

Merged
merged 26 commits into from
Jan 31, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
c911faa
lambda
SylvainJuge Jan 20, 2025
26e79f9
inject proxies for indy
SylvainJuge Jan 20, 2025
7f3ae3b
kotlinx + integration tests
SylvainJuge Jan 21, 2025
9183992
Merge branch 'main' of github.com:open-telemetry/opentelemetry-java-i…
SylvainJuge Jan 21, 2025
29c99dd
inject missing classes for indy
SylvainJuge Jan 21, 2025
45ead47
do not inject proxies for lambda
SylvainJuge Jan 21, 2025
ba30ba8
move back comment in the expected location
SylvainJuge Jan 21, 2025
eb945b8
remove duplication
SylvainJuge Jan 22, 2025
eba7e20
add jpms compatible class file transformer
SylvainJuge Jan 22, 2025
7a1cbc7
remove lambda java9 module
SylvainJuge Jan 22, 2025
590f86e
fix pebkc
SylvainJuge Jan 22, 2025
a8cbb24
fix lambda instrumentation, must not redefine them
SylvainJuge Jan 22, 2025
403caaa
fix javadoc
SylvainJuge Jan 22, 2025
506cc62
fix things again
SylvainJuge Jan 22, 2025
da1c13d
fix it again
SylvainJuge Jan 22, 2025
c4350d0
make the comments a bit better
SylvainJuge Jan 23, 2025
1d54a14
fix typo
SylvainJuge Jan 23, 2025
03aa810
avoid injecting classes for kotlinxcoroutines
SylvainJuge Jan 24, 2025
2ed4e96
remove commented code
SylvainJuge Jan 24, 2025
77a4f00
Merge branch 'main' of github.com:open-telemetry/opentelemetry-java-i…
SylvainJuge Jan 27, 2025
d9cd13f
Merge branch 'main' of github.com:open-telemetry/opentelemetry-java-i…
SylvainJuge Jan 29, 2025
5e2ef89
Merge branch 'main' of github.com:open-telemetry/opentelemetry-java-i…
SylvainJuge Jan 30, 2025
20856e3
Merge branch 'main' of github.com:open-telemetry/opentelemetry-java-i…
SylvainJuge Jan 31, 2025
a38763f
revert commented code that was there for a reason
SylvainJuge Jan 31, 2025
b77428c
add LambdaTransformer interface + rename things
SylvainJuge Jan 31, 2025
bc785b9
fix typos and comments
SylvainJuge Jan 31, 2025
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

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ plugins {

dependencies {
compileOnly(project(":javaagent-bootstrap"))
implementation(project(":instrumentation:internal:internal-lambda-java9:javaagent"))

testImplementation(project(":javaagent-bootstrap"))
}
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ public void visitMethodInsn(
Opcodes.GETFIELD, slashClassName, "targetClass", "Ljava/lang/Class;");
mv.visitMethodInsn(
Opcodes.INVOKESTATIC,
Type.getInternalName(LambdaTransformer.class),
Type.getInternalName(LambdaTransformerHelper.class),
"transform",
"([BLjava/lang/String;Ljava/lang/Class;)[B",
false);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,14 @@
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 io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import net.bytebuddy.utility.JavaModule;

@AutoService(InstrumentationModule.class)
public class LambdaInstrumentationModule extends InstrumentationModule {
public class LambdaInstrumentationModule extends InstrumentationModule
implements ExperimentalInstrumentationModule {
public LambdaInstrumentationModule() {
super("internal-lambda");
}
Expand All @@ -28,21 +29,16 @@ public boolean defaultEnabled(ConfigProperties config) {
}

@Override
public boolean isIndyModule() {
return false;
public List<String> injectedClassNames() {
return Collections.singletonList(
"io.opentelemetry.javaagent.instrumentation.internal.lambda.LambdaTransformerHelper");
}

@Override
public List<String> getAdditionalHelperClassNames() {
// this instrumentation uses ASM not ByteBuddy so muzzle doesn't automatically add helper
// classes
List<String> classNames = new ArrayList<>();
classNames.add("io.opentelemetry.javaagent.instrumentation.internal.lambda.LambdaTransformer");
if (JavaModule.isSupported()) {
classNames.add(
"io.opentelemetry.javaagent.instrumentation.internal.lambda.Java9LambdaTransformer");
}
return classNames;
return injectedClassNames();
}

@Override
Expand Down

This file was deleted.

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.internal.lambda;

import io.opentelemetry.javaagent.bootstrap.InjectedClassHelper;
import io.opentelemetry.javaagent.bootstrap.LambdaTransformer;
import io.opentelemetry.javaagent.bootstrap.LambdaTransformerHolder;

/** Helper class for transforming lambda class bytes. */
public final class LambdaTransformerHelper {

private LambdaTransformerHelper() {}

/**
* Called from {@code java.lang.invoke.InnerClassLambdaMetafactory} to transform lambda class
* bytes.
*/
@SuppressWarnings("unused")
public static byte[] transform(byte[] classBytes, String slashClassName, Class<?> targetClass) {
// Skip transforming lambdas of injected helper classes.
if (InjectedClassHelper.isHelperClass(targetClass)) {
return classBytes;
}
LambdaTransformer transformer = LambdaTransformerHolder.getLambdaTransformer();
if (transformer == null) {
return classBytes;
}

try {
byte[] result = transformer.transform(slashClassName, targetClass, classBytes);
if (result != null) {
classBytes = result;
}
} catch (Throwable throwable) {
// sun.instrument.TransformerManager catches Throwable from ClassFileTransformer and ignores
// it, we do the same.
}
return classBytes;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,20 @@
import kotlin.coroutines.Continuation;
import kotlin.coroutines.intrinsics.IntrinsicsKt;

/**
* Instrumentation helper that is called through bytecode instrumentation. When using invokedynamic
* instrumentation this class is called through an injected proxy, and thus it should not pull any
* other class references than the ones that are already present in the target classloader or the
* bootstrap classloader. This is why the {@link MethodRequest} class is here passed as an {@link
* Object} as it allows to avoid having to inject extra classes in the target classloader
*/
@SuppressWarnings("unused") // methods calls injected through bytecode instrumentation
public final class AnnotationInstrumentationHelper {

private static final VirtualField<Continuation<?>, Context> contextField =
VirtualField.find(Continuation.class, Context.class);

public static MethodRequest createMethodRequest(
public static Object createMethodRequest(
Class<?> declaringClass, String methodName, String withSpanValue, String spanKindString) {
SpanKind spanKind = SpanKind.INTERNAL;
if (spanKindString != null) {
Expand All @@ -34,11 +42,10 @@ public static MethodRequest createMethodRequest(
return MethodRequest.create(declaringClass, methodName, withSpanValue, spanKind);
}

public static Context enterCoroutine(
int label, Continuation<?> continuation, MethodRequest request) {
public static Context enterCoroutine(int label, Continuation<?> continuation, Object request) {
// label 0 means that coroutine is started, any other label means that coroutine is resumed
if (label == 0) {
Context context = instrumenter().start(Context.current(), request);
Context context = instrumenter().start(Context.current(), (MethodRequest) request);
// null continuation means that this method is not going to be resumed, and we don't need to
// store the context
if (continuation != null) {
Expand All @@ -55,18 +62,14 @@ public static Scope openScope(Context context) {
}

public static void exitCoroutine(
Object result,
MethodRequest request,
Continuation<?> continuation,
Context context,
Scope scope) {
Object result, Object request, Continuation<?> continuation, Context context, Scope scope) {
exitCoroutine(null, result, request, continuation, context, scope);
}

public static void exitCoroutine(
Throwable error,
Object result,
MethodRequest request,
Object request,
Continuation<?> continuation,
Context context,
Scope scope) {
Expand All @@ -78,7 +81,7 @@ public static void exitCoroutine(
// end the span when this method can not be resumed (coroutine is null) or if it has reached
// final state (returns anything else besides COROUTINE_SUSPENDED)
if (continuation == null || result != IntrinsicsKt.getCOROUTINE_SUSPENDED()) {
instrumenter().end(context, request, null, error);
instrumenter().end(context, (MethodRequest) request, null, error);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,16 @@
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 io.opentelemetry.javaagent.extension.instrumentation.internal.injection.ClassInjector;
import io.opentelemetry.javaagent.extension.instrumentation.internal.injection.InjectionMode;
import java.util.List;
import net.bytebuddy.matcher.ElementMatcher;

/** Instrumentation for methods annotated with {@code WithSpan} annotation. */
@AutoService(InstrumentationModule.class)
public class AnnotationInstrumentationModule extends InstrumentationModule {
public class AnnotationInstrumentationModule extends InstrumentationModule
implements ExperimentalInstrumentationModule {

public AnnotationInstrumentationModule() {
super(
Expand All @@ -26,12 +30,6 @@ public AnnotationInstrumentationModule() {
"opentelemetry-instrumentation-annotations");
}

@Override
public boolean isIndyModule() {
// needs helper classes in the same class loader
return false;
}

@Override
public int order() {
// Run first to ensure other automatic instrumentation is added after and therefore is executed
Expand All @@ -50,4 +48,17 @@ public ElementMatcher.Junction<ClassLoader> classLoaderMatcher() {
public List<TypeInstrumentation> typeInstrumentations() {
return singletonList(new WithSpanInstrumentation());
}

@Override
public void injectClasses(ClassInjector injector) {
// AnnotationInstrumentationHelper is called directly in the instrumented bytecode.
//
// With invokedynamic instrumentation a proxy class can be used as long as it does not pull
// extra types in the method signatures (which would require those types to also be available
// in the instrumented code).
injector
.proxyBuilder(
"io.opentelemetry.javaagent.instrumentation.kotlinxcoroutines.instrumentationannotations.AnnotationInstrumentationHelper")
.inject(InjectionMode.CLASS_ONLY);
}
}
Loading