Skip to content

Commit 3541d6d

Browse files
authored
make jetty indy-ready (#14806)
1 parent 0e2c685 commit 3541d6d

File tree

8 files changed

+167
-96
lines changed

8 files changed

+167
-96
lines changed

instrumentation/jetty/jetty-11.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/jetty/v11_0/Jetty11HandlerAdvice.java

Lines changed: 48 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -9,57 +9,74 @@
99

1010
import io.opentelemetry.context.Context;
1111
import io.opentelemetry.context.Scope;
12-
import io.opentelemetry.javaagent.bootstrap.Java8BytecodeBridge;
1312
import io.opentelemetry.javaagent.bootstrap.http.HttpServerResponseCustomizerHolder;
1413
import io.opentelemetry.javaagent.instrumentation.servlet.ServletRequestContext;
1514
import jakarta.servlet.http.HttpServletRequest;
1615
import jakarta.servlet.http.HttpServletResponse;
16+
import javax.annotation.Nullable;
1717
import net.bytebuddy.asm.Advice;
1818

1919
@SuppressWarnings("unused")
2020
public class Jetty11HandlerAdvice {
2121

22-
@Advice.OnMethodEnter(suppress = Throwable.class)
23-
public static void onEnter(
24-
@Advice.This Object source,
25-
@Advice.Argument(2) HttpServletRequest request,
26-
@Advice.Argument(3) HttpServletResponse response,
27-
@Advice.Local("otelRequest") ServletRequestContext<HttpServletRequest> requestContext,
28-
@Advice.Local("otelContext") Context context,
29-
@Advice.Local("otelScope") Scope scope) {
22+
public static class AdviceScope {
23+
private final ServletRequestContext<HttpServletRequest> requestContext;
24+
private final Context context;
25+
private final Scope scope;
3026

31-
Context attachedContext = helper().getServerContext(request);
32-
if (attachedContext != null) {
33-
// We are inside nested handler, don't create new span
34-
return;
27+
private AdviceScope(
28+
ServletRequestContext<HttpServletRequest> requestContext, Context context, Scope scope) {
29+
this.requestContext = requestContext;
30+
this.context = context;
31+
this.scope = scope;
3532
}
3633

37-
Context parentContext = Java8BytecodeBridge.currentContext();
38-
requestContext = new ServletRequestContext<>(request);
39-
40-
if (!helper().shouldStart(parentContext, requestContext)) {
41-
return;
34+
@Nullable
35+
public static AdviceScope start(
36+
Object source, HttpServletRequest request, HttpServletResponse response) {
37+
Context attachedContext = helper().getServerContext(request);
38+
if (attachedContext != null) {
39+
// We are inside nested handler, don't create new span
40+
return null;
41+
}
42+
Context parentContext = Context.current();
43+
ServletRequestContext<HttpServletRequest> requestContext =
44+
new ServletRequestContext<>(request);
45+
if (!helper().shouldStart(parentContext, requestContext)) {
46+
return null;
47+
}
48+
Context context = helper().start(parentContext, requestContext);
49+
Scope scope = context.makeCurrent();
50+
// Must be set here since Jetty handlers can use startAsync outside of servlet scope.
51+
helper().setAsyncListenerResponse(context, response);
52+
HttpServerResponseCustomizerHolder.getCustomizer()
53+
.customize(context, response, Jetty11ResponseMutator.INSTANCE);
54+
return new AdviceScope(requestContext, context, scope);
4255
}
4356

44-
context = helper().start(parentContext, requestContext);
45-
scope = context.makeCurrent();
46-
47-
// Must be set here since Jetty handlers can use startAsync outside of servlet scope.
48-
helper().setAsyncListenerResponse(context, response);
57+
public void end(
58+
@Nullable Throwable throwable, HttpServletRequest request, HttpServletResponse response) {
59+
helper().end(requestContext, request, response, throwable, context, scope);
60+
}
61+
}
4962

50-
HttpServerResponseCustomizerHolder.getCustomizer()
51-
.customize(context, response, Jetty11ResponseMutator.INSTANCE);
63+
@Nullable
64+
@Advice.OnMethodEnter(suppress = Throwable.class)
65+
public static AdviceScope onEnter(
66+
@Advice.This Object source,
67+
@Advice.Argument(2) HttpServletRequest request,
68+
@Advice.Argument(3) HttpServletResponse response) {
69+
return AdviceScope.start(source, request, response);
5270
}
5371

5472
@Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class)
5573
public static void stopSpan(
5674
@Advice.Argument(2) HttpServletRequest request,
5775
@Advice.Argument(3) HttpServletResponse response,
58-
@Advice.Thrown Throwable throwable,
59-
@Advice.Local("otelRequest") ServletRequestContext<HttpServletRequest> requestContext,
60-
@Advice.Local("otelContext") Context context,
61-
@Advice.Local("otelScope") Scope scope) {
62-
63-
helper().end(requestContext, request, response, throwable, context, scope);
76+
@Advice.Thrown @Nullable Throwable throwable,
77+
@Advice.Enter @Nullable AdviceScope adviceScope) {
78+
if (adviceScope != null) {
79+
adviceScope.end(throwable, request, response);
80+
}
6481
}
6582
}

instrumentation/jetty/jetty-11.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/jetty/v11_0/Jetty11InstrumentationModule.java

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,15 @@
1010
import com.google.auto.service.AutoService;
1111
import io.opentelemetry.javaagent.extension.instrumentation.InstrumentationModule;
1212
import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation;
13+
import io.opentelemetry.javaagent.extension.instrumentation.internal.ExperimentalInstrumentationModule;
1314
import io.opentelemetry.javaagent.instrumentation.jetty.common.JettyHandlerInstrumentation;
1415
import java.util.Collections;
1516
import java.util.List;
1617
import net.bytebuddy.matcher.ElementMatcher;
1718

1819
@AutoService(InstrumentationModule.class)
19-
public class Jetty11InstrumentationModule extends InstrumentationModule {
20+
public class Jetty11InstrumentationModule extends InstrumentationModule
21+
implements ExperimentalInstrumentationModule {
2022

2123
public Jetty11InstrumentationModule() {
2224
super("jetty", "jetty-11.0");
@@ -34,4 +36,9 @@ public List<TypeInstrumentation> typeInstrumentations() {
3436
"jakarta.servlet",
3537
Jetty11InstrumentationModule.class.getPackage().getName() + ".Jetty11HandlerAdvice"));
3638
}
39+
40+
@Override
41+
public boolean isIndyReady() {
42+
return true;
43+
}
3744
}

instrumentation/jetty/jetty-12.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/jetty/v12_0/Jetty12InstrumentationModule.java

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,13 @@
1111
import com.google.auto.service.AutoService;
1212
import io.opentelemetry.javaagent.extension.instrumentation.InstrumentationModule;
1313
import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation;
14+
import io.opentelemetry.javaagent.extension.instrumentation.internal.ExperimentalInstrumentationModule;
1415
import java.util.List;
1516
import net.bytebuddy.matcher.ElementMatcher;
1617

1718
@AutoService(InstrumentationModule.class)
18-
public class Jetty12InstrumentationModule extends InstrumentationModule {
19+
public class Jetty12InstrumentationModule extends InstrumentationModule
20+
implements ExperimentalInstrumentationModule {
1921

2022
public Jetty12InstrumentationModule() {
2123
super("jetty", "jetty-12.0");
@@ -30,4 +32,9 @@ public ElementMatcher.Junction<ClassLoader> classLoaderMatcher() {
3032
public List<TypeInstrumentation> typeInstrumentations() {
3133
return singletonList(new Jetty12ServerInstrumentation());
3234
}
35+
36+
@Override
37+
public boolean isIndyReady() {
38+
return true;
39+
}
3340
}

instrumentation/jetty/jetty-12.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/jetty/v12_0/Jetty12ServerInstrumentation.java

Lines changed: 38 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,10 @@
1212

1313
import io.opentelemetry.context.Context;
1414
import io.opentelemetry.context.Scope;
15-
import io.opentelemetry.javaagent.bootstrap.Java8BytecodeBridge;
1615
import io.opentelemetry.javaagent.bootstrap.http.HttpServerResponseCustomizerHolder;
1716
import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation;
1817
import io.opentelemetry.javaagent.extension.instrumentation.TypeTransformer;
18+
import javax.annotation.Nullable;
1919
import net.bytebuddy.asm.Advice;
2020
import net.bytebuddy.description.type.TypeDescription;
2121
import net.bytebuddy.matcher.ElementMatcher;
@@ -43,39 +43,53 @@ public void transform(TypeTransformer transformer) {
4343
@SuppressWarnings("unused")
4444
public static class HandlerAdvice {
4545

46-
@Advice.OnMethodEnter(suppress = Throwable.class)
47-
public static void onEnter(
48-
@Advice.This Object source,
49-
@Advice.Argument(0) Request request,
50-
@Advice.Argument(1) Response response,
51-
@Advice.Local("otelContext") Context context,
52-
@Advice.Local("otelScope") Scope scope) {
46+
public static class AdviceScope {
47+
private final Context context;
48+
private final Scope scope;
49+
50+
private AdviceScope(Context context, Scope scope) {
51+
this.context = context;
52+
this.scope = scope;
53+
}
5354

54-
Context parentContext = Java8BytecodeBridge.currentContext();
55-
if (!helper().shouldStart(parentContext, request)) {
56-
return;
55+
@Nullable
56+
public static AdviceScope start(Object source, Request request, Response response) {
57+
Context parentContext = Context.current();
58+
if (!helper().shouldStart(parentContext, request)) {
59+
return null;
60+
}
61+
Context context = helper().start(parentContext, request, response);
62+
Scope scope = context.makeCurrent();
63+
HttpServerResponseCustomizerHolder.getCustomizer()
64+
.customize(context, response, Jetty12ResponseMutator.INSTANCE);
65+
return new AdviceScope(context, scope);
5766
}
5867

59-
context = helper().start(parentContext, request, response);
60-
scope = context.makeCurrent();
68+
public void end(Request request, Response response, @Nullable Throwable throwable) {
69+
scope.close();
70+
if (throwable != null) {
71+
helper().end(context, request, response, throwable);
72+
}
73+
}
74+
}
6175

62-
HttpServerResponseCustomizerHolder.getCustomizer()
63-
.customize(context, response, Jetty12ResponseMutator.INSTANCE);
76+
@Nullable
77+
@Advice.OnMethodEnter(suppress = Throwable.class)
78+
public static AdviceScope onEnter(
79+
@Advice.This Object source,
80+
@Advice.Argument(0) Request request,
81+
@Advice.Argument(1) Response response) {
82+
return AdviceScope.start(source, request, response);
6483
}
6584

6685
@Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class)
6786
public static void stopSpan(
6887
@Advice.Argument(0) Request request,
6988
@Advice.Argument(1) Response response,
70-
@Advice.Thrown Throwable throwable,
71-
@Advice.Local("otelContext") Context context,
72-
@Advice.Local("otelScope") Scope scope) {
73-
if (scope == null) {
74-
return;
75-
}
76-
scope.close();
77-
if (throwable != null) {
78-
helper().end(context, request, response, throwable);
89+
@Advice.Thrown @Nullable Throwable throwable,
90+
@Advice.Enter @Nullable AdviceScope adviceScope) {
91+
if (adviceScope != null) {
92+
adviceScope.end(request, response, throwable);
7993
}
8094
}
8195
}

instrumentation/jetty/jetty-8.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/jetty/v8_0/Jetty8HandlerAdvice.java

Lines changed: 48 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -9,57 +9,74 @@
99

1010
import io.opentelemetry.context.Context;
1111
import io.opentelemetry.context.Scope;
12-
import io.opentelemetry.javaagent.bootstrap.Java8BytecodeBridge;
1312
import io.opentelemetry.javaagent.bootstrap.http.HttpServerResponseCustomizerHolder;
1413
import io.opentelemetry.javaagent.instrumentation.servlet.ServletRequestContext;
14+
import javax.annotation.Nullable;
1515
import javax.servlet.http.HttpServletRequest;
1616
import javax.servlet.http.HttpServletResponse;
1717
import net.bytebuddy.asm.Advice;
1818

1919
@SuppressWarnings("unused")
2020
public class Jetty8HandlerAdvice {
2121

22-
@Advice.OnMethodEnter(suppress = Throwable.class)
23-
public static void onEnter(
24-
@Advice.This Object source,
25-
@Advice.Argument(2) HttpServletRequest request,
26-
@Advice.Argument(3) HttpServletResponse response,
27-
@Advice.Local("otelRequest") ServletRequestContext<HttpServletRequest> requestContext,
28-
@Advice.Local("otelContext") Context context,
29-
@Advice.Local("otelScope") Scope scope) {
22+
public static class AdviceScope {
23+
private final ServletRequestContext<HttpServletRequest> requestContext;
24+
private final Context context;
25+
private final Scope scope;
3026

31-
Context attachedContext = helper().getServerContext(request);
32-
if (attachedContext != null) {
33-
// We are inside nested handler, don't create new span
34-
return;
27+
private AdviceScope(
28+
ServletRequestContext<HttpServletRequest> requestContext, Context context, Scope scope) {
29+
this.requestContext = requestContext;
30+
this.context = context;
31+
this.scope = scope;
3532
}
3633

37-
Context parentContext = Java8BytecodeBridge.currentContext();
38-
requestContext = new ServletRequestContext<>(request);
39-
40-
if (!helper().shouldStart(parentContext, requestContext)) {
41-
return;
34+
@Nullable
35+
public static AdviceScope start(
36+
Object source, HttpServletRequest request, HttpServletResponse response) {
37+
Context attachedContext = helper().getServerContext(request);
38+
if (attachedContext != null) {
39+
// We are inside nested handler, don't create new span
40+
return null;
41+
}
42+
Context parentContext = Context.current();
43+
ServletRequestContext<HttpServletRequest> requestContext =
44+
new ServletRequestContext<>(request);
45+
if (!helper().shouldStart(parentContext, requestContext)) {
46+
return null;
47+
}
48+
Context context = helper().start(parentContext, requestContext);
49+
Scope scope = context.makeCurrent();
50+
// Must be set here since Jetty handlers can use startAsync outside of servlet scope.
51+
helper().setAsyncListenerResponse(context, response);
52+
HttpServerResponseCustomizerHolder.getCustomizer()
53+
.customize(context, response, Jetty8ResponseMutator.INSTANCE);
54+
return new AdviceScope(requestContext, context, scope);
4255
}
4356

44-
context = helper().start(parentContext, requestContext);
45-
scope = context.makeCurrent();
46-
47-
// Must be set here since Jetty handlers can use startAsync outside of servlet scope.
48-
helper().setAsyncListenerResponse(context, response);
57+
public void end(
58+
@Nullable Throwable throwable, HttpServletRequest request, HttpServletResponse response) {
59+
helper().end(requestContext, request, response, throwable, context, scope);
60+
}
61+
}
4962

50-
HttpServerResponseCustomizerHolder.getCustomizer()
51-
.customize(context, response, Jetty8ResponseMutator.INSTANCE);
63+
@Advice.OnMethodEnter(suppress = Throwable.class)
64+
@Nullable
65+
public static AdviceScope onEnter(
66+
@Advice.This Object source,
67+
@Advice.Argument(2) HttpServletRequest request,
68+
@Advice.Argument(3) HttpServletResponse response) {
69+
return AdviceScope.start(source, request, response);
5270
}
5371

5472
@Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class)
5573
public static void stopSpan(
5674
@Advice.Argument(2) HttpServletRequest request,
5775
@Advice.Argument(3) HttpServletResponse response,
58-
@Advice.Thrown Throwable throwable,
59-
@Advice.Local("otelRequest") ServletRequestContext<HttpServletRequest> requestContext,
60-
@Advice.Local("otelContext") Context context,
61-
@Advice.Local("otelScope") Scope scope) {
62-
63-
helper().end(requestContext, request, response, throwable, context, scope);
76+
@Advice.Thrown @Nullable Throwable throwable,
77+
@Advice.Enter @Nullable AdviceScope adviceScope) {
78+
if (adviceScope != null) {
79+
adviceScope.end(throwable, request, response);
80+
}
6481
}
6582
}

instrumentation/jetty/jetty-8.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/jetty/v8_0/Jetty8InstrumentationModule.java

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,15 @@
1010
import com.google.auto.service.AutoService;
1111
import io.opentelemetry.javaagent.extension.instrumentation.InstrumentationModule;
1212
import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation;
13+
import io.opentelemetry.javaagent.extension.instrumentation.internal.ExperimentalInstrumentationModule;
1314
import io.opentelemetry.javaagent.instrumentation.jetty.common.JettyHandlerInstrumentation;
1415
import java.util.Arrays;
1516
import java.util.List;
1617
import net.bytebuddy.matcher.ElementMatcher;
1718

1819
@AutoService(InstrumentationModule.class)
19-
public class Jetty8InstrumentationModule extends InstrumentationModule {
20+
public class Jetty8InstrumentationModule extends InstrumentationModule
21+
implements ExperimentalInstrumentationModule {
2022

2123
public Jetty8InstrumentationModule() {
2224
super("jetty", "jetty-8.0");
@@ -35,4 +37,9 @@ public List<TypeInstrumentation> typeInstrumentations() {
3537
Jetty8InstrumentationModule.class.getPackage().getName() + ".Jetty8HandlerAdvice"),
3638
new JettyQueuedThreadPoolInstrumentation());
3739
}
40+
41+
@Override
42+
public boolean isIndyReady() {
43+
return true;
44+
}
3845
}

instrumentation/jetty/jetty-8.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/jetty/v8_0/Jetty8Singletons.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
package io.opentelemetry.javaagent.instrumentation.jetty.v8_0;
77

88
import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter;
9+
import io.opentelemetry.instrumentation.api.util.VirtualField;
10+
import io.opentelemetry.javaagent.bootstrap.executors.PropagatedContext;
911
import io.opentelemetry.javaagent.bootstrap.servlet.AppServerBridge;
1012
import io.opentelemetry.javaagent.instrumentation.jetty.common.JettyHelper;
1113
import io.opentelemetry.javaagent.instrumentation.servlet.ServletInstrumenterBuilder;
@@ -18,6 +20,9 @@
1820
public final class Jetty8Singletons {
1921
private static final String INSTRUMENTATION_NAME = "io.opentelemetry.jetty-8.0";
2022

23+
public static final VirtualField<Runnable, PropagatedContext> PROPAGATED_CONTEXT =
24+
VirtualField.find(Runnable.class, PropagatedContext.class);
25+
2126
private static final Instrumenter<
2227
ServletRequestContext<HttpServletRequest>, ServletResponseContext<HttpServletResponse>>
2328
INSTRUMENTER =

0 commit comments

Comments
 (0)