Skip to content
Merged
Show file tree
Hide file tree
Changes from 23 commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
d95f01b
make async-http-client indy ready
SylvainJuge May 21, 2025
098a622
make google-http-client indy ready + cleanup
SylvainJuge May 21, 2025
b2eb052
spotless
SylvainJuge May 21, 2025
2469bbb
fix issue with virtual field
SylvainJuge May 22, 2025
d1a18e1
fix another virtual field
SylvainJuge May 22, 2025
04b3353
java-http-client
SylvainJuge May 22, 2025
f01093a
jetty-httpclient
SylvainJuge May 22, 2025
2466290
fix few other virtualfield mis-usages
SylvainJuge May 22, 2025
238681b
cleanup and rename locals to scope
SylvainJuge May 22, 2025
330cf7a
Merge branch 'main' of github.com:open-telemetry/opentelemetry-java-i…
SylvainJuge May 22, 2025
d0ef024
Merge branch 'main' of github.com:open-telemetry/opentelemetry-java-i…
SylvainJuge May 23, 2025
a52fb8e
Merge branch 'main' of github.com:open-telemetry/opentelemetry-java-i…
SylvainJuge May 23, 2025
033e584
remove invalid virtual field usages
SylvainJuge May 23, 2025
08fd20b
post-review changes in async-http-client 1.9
SylvainJuge May 26, 2025
efbc87b
post-review changes
SylvainJuge May 26, 2025
8957f7a
post-review changes
SylvainJuge May 26, 2025
eee5c47
post-review changes
SylvainJuge May 26, 2025
4ad77f0
Merge branch 'main' of github.com:open-telemetry/opentelemetry-java-i…
SylvainJuge May 26, 2025
c50fcb3
reformat
SylvainJuge May 26, 2025
a416134
Apply suggestions from code review
SylvainJuge May 27, 2025
60e52d7
cleanup import
SylvainJuge May 27, 2025
873e072
Apply suggestions from code review
SylvainJuge May 27, 2025
059461f
Merge branch 'main' of github.com:open-telemetry/opentelemetry-java-i…
SylvainJuge May 27, 2025
80a806c
Update instrumentation/jetty-httpclient/jetty-httpclient-12.0/javaage…
SylvainJuge May 27, 2025
01f7e0b
Update instrumentation/jetty-httpclient/jetty-httpclient-12.0/javaage…
SylvainJuge May 27, 2025
9114941
Update instrumentation/jetty-httpclient/jetty-httpclient-12.0/javaage…
SylvainJuge May 27, 2025
601d194
split sync/async advices
SylvainJuge May 27, 2025
b5298eb
wip still broken
SylvainJuge May 28, 2025
ceed0fe
fix argument order
SylvainJuge May 28, 2025
c75c9eb
Merge branch 'main' of github.com:open-telemetry/opentelemetry-java-i…
SylvainJuge May 28, 2025
dc8ed24
spotless
SylvainJuge May 28, 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
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 AsyncHttpClientInstrumentationModule extends InstrumentationModule {
public class AsyncHttpClientInstrumentationModule extends InstrumentationModule
implements ExperimentalInstrumentationModule {
public AsyncHttpClientInstrumentationModule() {
super("async-http-client", "async-http-client-1.9");
}
Expand All @@ -22,4 +24,9 @@ public AsyncHttpClientInstrumentationModule() {
public List<TypeInstrumentation> typeInstrumentations() {
return asList(new RequestInstrumentation(), new ResponseInstrumentation());
}

@Override
public boolean isIndyReady() {
return true;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,22 +5,28 @@

package io.opentelemetry.javaagent.instrumentation.asynchttpclient.v1_9;

import com.ning.http.client.AsyncHandler;
import com.ning.http.client.Request;
import com.ning.http.client.Response;
import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter;
import io.opentelemetry.instrumentation.api.util.VirtualField;
import io.opentelemetry.javaagent.bootstrap.internal.JavaagentHttpClientInstrumenters;

public final class AsyncHttpClientSingletons {
private static final String INSTRUMENTATION_NAME = "io.opentelemetry.async-http-client-1.9";

private static final Instrumenter<Request, Response> INSTRUMENTER;

public static final VirtualField<AsyncHandler<?>, AsyncHandlerData> ASYNC_HANDLER_DATA;

static {
INSTRUMENTER =
JavaagentHttpClientInstrumenters.create(
INSTRUMENTATION_NAME,
new AsyncHttpClientHttpAttributesGetter(),
HttpHeaderSetter.INSTANCE);

ASYNC_HANDLER_DATA = VirtualField.find(AsyncHandler.class, AsyncHandlerData.class);
}

public static Instrumenter<Request, Response> instrumenter() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
package io.opentelemetry.javaagent.instrumentation.asynchttpclient.v1_9;

import static io.opentelemetry.javaagent.bootstrap.Java8BytecodeBridge.currentContext;
import static io.opentelemetry.javaagent.instrumentation.asynchttpclient.v1_9.AsyncHttpClientSingletons.ASYNC_HANDLER_DATA;
import static io.opentelemetry.javaagent.instrumentation.asynchttpclient.v1_9.AsyncHttpClientSingletons.instrumenter;
import static net.bytebuddy.matcher.ElementMatchers.isPublic;
import static net.bytebuddy.matcher.ElementMatchers.named;
Expand All @@ -15,9 +16,9 @@
import com.ning.http.client.Request;
import io.opentelemetry.context.Context;
import io.opentelemetry.context.Scope;
import io.opentelemetry.instrumentation.api.util.VirtualField;
import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation;
import io.opentelemetry.javaagent.extension.instrumentation.TypeTransformer;
import javax.annotation.Nullable;
import net.bytebuddy.asm.Advice;
import net.bytebuddy.description.type.TypeDescription;
import net.bytebuddy.matcher.ElementMatcher;
Expand All @@ -42,24 +43,22 @@ public void transform(TypeTransformer transformer) {
@SuppressWarnings("unused")
public static class ExecuteAdvice {

@Nullable
@Advice.OnMethodEnter(suppress = Throwable.class)
public static void onEnter(
@Advice.Argument(0) Request request,
@Advice.Argument(1) AsyncHandler<?> handler,
@Advice.Local("otelScope") Scope scope) {
public static Scope onEnter(
@Advice.Argument(0) Request request, @Advice.Argument(1) AsyncHandler<?> handler) {
Context parentContext = currentContext();
if (!instrumenter().shouldStart(parentContext, request)) {
return;
return null;
}

Context context = instrumenter().start(parentContext, request);
VirtualField.find(AsyncHandler.class, AsyncHandlerData.class)
.set(handler, AsyncHandlerData.create(parentContext, context, request));
scope = context.makeCurrent();
ASYNC_HANDLER_DATA.set(handler, AsyncHandlerData.create(parentContext, context, request));
return context.makeCurrent();
}

@Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class)
public static void onExit(@Advice.Local("otelScope") Scope scope) {
public static void onExit(@Advice.Enter @Nullable Scope scope) {
if (scope != null) {
scope.close();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,16 @@
package io.opentelemetry.javaagent.instrumentation.asynchttpclient.v1_9;

import static io.opentelemetry.javaagent.extension.matcher.AgentElementMatchers.hasClassesNamed;
import static io.opentelemetry.javaagent.instrumentation.asynchttpclient.v1_9.AsyncHttpClientSingletons.ASYNC_HANDLER_DATA;
import static io.opentelemetry.javaagent.instrumentation.asynchttpclient.v1_9.AsyncHttpClientSingletons.instrumenter;
import static net.bytebuddy.matcher.ElementMatchers.hasSuperClass;
import static net.bytebuddy.matcher.ElementMatchers.isPublic;
import static net.bytebuddy.matcher.ElementMatchers.named;
import static net.bytebuddy.matcher.ElementMatchers.takesArgument;

import com.ning.http.client.AsyncCompletionHandler;
import com.ning.http.client.AsyncHandler;
import com.ning.http.client.Response;
import io.opentelemetry.context.Scope;
import io.opentelemetry.instrumentation.api.util.VirtualField;
import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation;
import io.opentelemetry.javaagent.extension.instrumentation.TypeTransformer;
import net.bytebuddy.asm.Advice;
Expand Down Expand Up @@ -54,13 +53,11 @@ public static class OnCompletedAdvice {
public static Scope onEnter(
@Advice.This AsyncCompletionHandler<?> handler, @Advice.Argument(0) Response response) {

VirtualField<AsyncHandler<?>, AsyncHandlerData> virtualField =
VirtualField.find(AsyncHandler.class, AsyncHandlerData.class);
AsyncHandlerData data = virtualField.get(handler);
AsyncHandlerData data = ASYNC_HANDLER_DATA.get(handler);
if (data == null) {
return null;
}
virtualField.set(handler, null);
ASYNC_HANDLER_DATA.set(handler, null);
instrumenter().end(data.getContext(), data.getRequest(), response, null);
return data.getParentContext().makeCurrent();
}
Expand All @@ -80,13 +77,11 @@ public static class OnThrowableAdvice {
public static Scope onEnter(
@Advice.This AsyncCompletionHandler<?> handler, @Advice.Argument(0) Throwable throwable) {

VirtualField<AsyncHandler<?>, AsyncHandlerData> virtualField =
VirtualField.find(AsyncHandler.class, AsyncHandlerData.class);
AsyncHandlerData data = virtualField.get(handler);
AsyncHandlerData data = ASYNC_HANDLER_DATA.get(handler);
if (data == null) {
return null;
}
virtualField.set(handler, null);
ASYNC_HANDLER_DATA.set(handler, null);
instrumenter().end(data.getContext(), data.getRequest(), null, throwable);
return data.getParentContext().makeCurrent();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,21 +6,20 @@
package io.opentelemetry.javaagent.instrumentation.asynchttpclient.v2_0;

import static io.opentelemetry.javaagent.extension.matcher.AgentElementMatchers.hasClassesNamed;
import static io.opentelemetry.javaagent.instrumentation.asynchttpclient.v2_0.AsyncHttpClientSingletons.ASYNC_HANDLER_REQUEST_CONTEXT;
import static io.opentelemetry.javaagent.instrumentation.asynchttpclient.v2_0.AsyncHttpClientSingletons.instrumenter;
import static net.bytebuddy.matcher.ElementMatchers.hasSuperClass;
import static net.bytebuddy.matcher.ElementMatchers.isPublic;
import static net.bytebuddy.matcher.ElementMatchers.named;
import static net.bytebuddy.matcher.ElementMatchers.takesArgument;

import io.opentelemetry.context.Scope;
import io.opentelemetry.instrumentation.api.util.VirtualField;
import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation;
import io.opentelemetry.javaagent.extension.instrumentation.TypeTransformer;
import net.bytebuddy.asm.Advice;
import net.bytebuddy.description.type.TypeDescription;
import net.bytebuddy.matcher.ElementMatcher;
import org.asynchttpclient.AsyncCompletionHandler;
import org.asynchttpclient.AsyncHandler;
import org.asynchttpclient.Response;

public class AsyncCompletionHandlerInstrumentation implements TypeInstrumentation {
Expand Down Expand Up @@ -54,13 +53,11 @@ public static class OnCompletedAdvice {
public static Scope onEnter(
@Advice.This AsyncCompletionHandler<?> handler, @Advice.Argument(0) Response response) {

VirtualField<AsyncHandler<?>, RequestContext> virtualField =
VirtualField.find(AsyncHandler.class, RequestContext.class);
RequestContext requestContext = virtualField.get(handler);
RequestContext requestContext = ASYNC_HANDLER_REQUEST_CONTEXT.get(handler);
if (requestContext == null) {
return null;
}
virtualField.set(handler, null);
ASYNC_HANDLER_REQUEST_CONTEXT.set(handler, null);
instrumenter().end(requestContext.getContext(), requestContext, response, null);
return requestContext.getParentContext().makeCurrent();
}
Expand All @@ -80,13 +77,11 @@ public static class OnThrowableAdvice {
public static Scope onEnter(
@Advice.This AsyncCompletionHandler<?> handler, @Advice.Argument(0) Throwable throwable) {

VirtualField<AsyncHandler<?>, RequestContext> virtualField =
VirtualField.find(AsyncHandler.class, RequestContext.class);
RequestContext requestContext = virtualField.get(handler);
RequestContext requestContext = ASYNC_HANDLER_REQUEST_CONTEXT.get(handler);
if (requestContext == null) {
return null;
}
virtualField.set(handler, null);
ASYNC_HANDLER_REQUEST_CONTEXT.set(handler, null);
instrumenter().end(requestContext.getContext(), requestContext, null, throwable);
return requestContext.getParentContext().makeCurrent();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,17 @@

import static io.opentelemetry.javaagent.bootstrap.Java8BytecodeBridge.currentContext;
import static io.opentelemetry.javaagent.extension.matcher.AgentElementMatchers.implementsInterface;
import static io.opentelemetry.javaagent.instrumentation.asynchttpclient.v2_0.AsyncHttpClientSingletons.ASYNC_HANDLER_REQUEST_CONTEXT;
import static io.opentelemetry.javaagent.instrumentation.asynchttpclient.v2_0.AsyncHttpClientSingletons.instrumenter;
import static net.bytebuddy.matcher.ElementMatchers.isPublic;
import static net.bytebuddy.matcher.ElementMatchers.named;
import static net.bytebuddy.matcher.ElementMatchers.takesArgument;

import io.opentelemetry.context.Context;
import io.opentelemetry.context.Scope;
import io.opentelemetry.instrumentation.api.util.VirtualField;
import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation;
import io.opentelemetry.javaagent.extension.instrumentation.TypeTransformer;
import javax.annotation.Nullable;
import net.bytebuddy.asm.Advice;
import net.bytebuddy.description.type.TypeDescription;
import net.bytebuddy.matcher.ElementMatcher;
Expand All @@ -43,15 +44,14 @@ public void transform(TypeTransformer transformer) {
@SuppressWarnings("unused")
public static class ExecuteRequestAdvice {

@Nullable
@Advice.OnMethodEnter(suppress = Throwable.class)
public static void onEnter(
@Advice.Argument(0) Request request,
@Advice.Argument(1) AsyncHandler<?> handler,
@Advice.Local("otelScope") Scope scope) {
public static Scope onEnter(
@Advice.Argument(0) Request request, @Advice.Argument(1) AsyncHandler<?> handler) {
Context parentContext = currentContext();
RequestContext requestContext = new RequestContext(parentContext, request);
if (!instrumenter().shouldStart(parentContext, requestContext)) {
return;
return null;
}

Context context = instrumenter().start(parentContext, requestContext);
Expand All @@ -70,12 +70,12 @@ public static void onEnter(
// 2.1, so the instrumentation module will need to be essentially duplicated (or a common
// module introduced)

VirtualField.find(AsyncHandler.class, RequestContext.class).set(handler, requestContext);
scope = context.makeCurrent();
ASYNC_HANDLER_REQUEST_CONTEXT.set(handler, requestContext);
return context.makeCurrent();
}

@Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class)
public static void onExit(@Advice.Local("otelScope") Scope scope) {
public static void onExit(@Advice.Enter @Nullable Scope scope) {
if (scope != null) {
scope.close();
}
Expand Down
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 AsyncHttpClientInstrumentationModule extends InstrumentationModule {
public class AsyncHttpClientInstrumentationModule extends InstrumentationModule
implements ExperimentalInstrumentationModule {
public AsyncHttpClientInstrumentationModule() {
super("async-http-client", "async-http-client-2.0");
}
Expand All @@ -26,4 +28,9 @@ public List<TypeInstrumentation> typeInstrumentations() {
new NettyRequestSenderInstrumentation(),
new NettyResponseFutureInstrumentation());
}

@Override
public boolean isIndyReady() {
return true;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,21 +5,30 @@

package io.opentelemetry.javaagent.instrumentation.asynchttpclient.v2_0;

import io.opentelemetry.context.Context;
import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter;
import io.opentelemetry.instrumentation.api.util.VirtualField;
import io.opentelemetry.javaagent.bootstrap.internal.JavaagentHttpClientInstrumenters;
import org.asynchttpclient.AsyncHandler;
import org.asynchttpclient.Request;
import org.asynchttpclient.Response;

public final class AsyncHttpClientSingletons {
private static final String INSTRUMENTATION_NAME = "io.opentelemetry.async-http-client-2.0";

private static final Instrumenter<RequestContext, Response> INSTRUMENTER;
public static final VirtualField<AsyncHandler<?>, RequestContext> ASYNC_HANDLER_REQUEST_CONTEXT;
public static final VirtualField<Request, Context> REQUEST_CONTEXT;

static {
INSTRUMENTER =
JavaagentHttpClientInstrumenters.create(
INSTRUMENTATION_NAME,
new AsyncHttpClientHttpAttributesGetter(),
HttpHeaderSetter.INSTANCE);

ASYNC_HANDLER_REQUEST_CONTEXT = VirtualField.find(AsyncHandler.class, RequestContext.class);
REQUEST_CONTEXT = VirtualField.find(Request.class, Context.class);
}

public static Instrumenter<RequestContext, Response> instrumenter() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,21 +5,21 @@

package io.opentelemetry.javaagent.instrumentation.asynchttpclient.v2_0;

import static io.opentelemetry.javaagent.instrumentation.asynchttpclient.v2_0.AsyncHttpClientSingletons.ASYNC_HANDLER_REQUEST_CONTEXT;
import static io.opentelemetry.javaagent.instrumentation.asynchttpclient.v2_0.AsyncHttpClientSingletons.REQUEST_CONTEXT;
import static net.bytebuddy.matcher.ElementMatchers.isPublic;
import static net.bytebuddy.matcher.ElementMatchers.named;
import static net.bytebuddy.matcher.ElementMatchers.returns;
import static net.bytebuddy.matcher.ElementMatchers.takesArgument;

import io.opentelemetry.context.Context;
import io.opentelemetry.context.Scope;
import io.opentelemetry.instrumentation.api.util.VirtualField;
import io.opentelemetry.javaagent.bootstrap.Java8BytecodeBridge;
import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation;
import io.opentelemetry.javaagent.extension.instrumentation.TypeTransformer;
import net.bytebuddy.asm.Advice;
import net.bytebuddy.description.type.TypeDescription;
import net.bytebuddy.matcher.ElementMatcher;
import org.asynchttpclient.AsyncHandler;
import org.asynchttpclient.Request;
import org.asynchttpclient.netty.NettyResponseFuture;

Expand Down Expand Up @@ -59,8 +59,7 @@ public static class AttachContextAdvice {

@Advice.OnMethodEnter
public static void attachContext(@Advice.Argument(0) Request request) {
VirtualField.find(Request.class, Context.class)
.set(request, Java8BytecodeBridge.currentContext());
REQUEST_CONTEXT.set(request, Java8BytecodeBridge.currentContext());
}
}

Expand All @@ -70,7 +69,7 @@ public static class MountContextAdvice {
@Advice.OnMethodEnter
public static Scope mountContext(@Advice.Argument(0) NettyResponseFuture<?> responseFuture) {
Request request = responseFuture.getCurrentRequest();
Context context = VirtualField.find(Request.class, Context.class).get(request);
Context context = REQUEST_CONTEXT.get(request);
return context == null ? null : context.makeCurrent();
}

Expand All @@ -88,8 +87,7 @@ public static class RememberNettyRequestAdvice {
@Advice.OnMethodExit
public static void rememberNettyRequest(@Advice.Return NettyResponseFuture<?> responseFuture) {
RequestContext requestContext =
VirtualField.find(AsyncHandler.class, RequestContext.class)
.get(responseFuture.getAsyncHandler());
ASYNC_HANDLER_REQUEST_CONTEXT.get(responseFuture.getAsyncHandler());
if (requestContext != null) {
requestContext.setNettyRequest(responseFuture.getNettyRequest());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
import io.opentelemetry.javaagent.extension.instrumentation.TypeTransformer;
import java.util.concurrent.CompletableFuture;
import net.bytebuddy.asm.Advice;
import net.bytebuddy.asm.Advice.AssignReturned;
import net.bytebuddy.description.type.TypeDescription;
import net.bytebuddy.matcher.ElementMatcher;

Expand All @@ -34,9 +35,10 @@ public void transform(TypeTransformer transformer) {
@SuppressWarnings("unused")
public static class WrapFutureAdvice {

@AssignReturned.ToReturned
@Advice.OnMethodExit(suppress = Throwable.class)
public static void onExit(@Advice.Return(readOnly = false) CompletableFuture<?> result) {
result = CompletableFutureWrapper.wrap(result, Java8BytecodeBridge.currentContext());
public static CompletableFuture<?> onExit(@Advice.Return CompletableFuture<?> result) {
return CompletableFutureWrapper.wrap(result, Java8BytecodeBridge.currentContext());
}
}
}
Loading
Loading