Skip to content

Commit fdacd21

Browse files
otelbot[bot]trask
andauthored
Review fixes for jetty-8.0:javaagent (open-telemetry#18093)
Co-authored-by: otelbot <197425009+otelbot@users.noreply.github.com> Co-authored-by: Trask Stalnaker <trask.stalnaker@gmail.com>
1 parent f36be55 commit fdacd21

5 files changed

Lines changed: 80 additions & 84 deletions

File tree

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

Lines changed: 0 additions & 80 deletions
This file was deleted.

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

Lines changed: 73 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,22 @@
66
package io.opentelemetry.javaagent.instrumentation.jetty.v8_0;
77

88
import static io.opentelemetry.javaagent.extension.matcher.AgentElementMatchers.hasClassesNamed;
9+
import static io.opentelemetry.javaagent.instrumentation.jetty.v8_0.Jetty8Singletons.helper;
910
import static java.util.Arrays.asList;
1011

1112
import com.google.auto.service.AutoService;
13+
import io.opentelemetry.context.Context;
14+
import io.opentelemetry.context.Scope;
15+
import io.opentelemetry.instrumentation.servlet.internal.ServletRequestContext;
16+
import io.opentelemetry.javaagent.bootstrap.http.HttpServerResponseCustomizerHolder;
1217
import io.opentelemetry.javaagent.extension.instrumentation.InstrumentationModule;
1318
import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation;
1419
import io.opentelemetry.javaagent.instrumentation.jetty.common.JettyHandlerInstrumentation;
1520
import java.util.List;
21+
import javax.annotation.Nullable;
22+
import javax.servlet.http.HttpServletRequest;
23+
import javax.servlet.http.HttpServletResponse;
24+
import net.bytebuddy.asm.Advice;
1625
import net.bytebuddy.matcher.ElementMatcher;
1726

1827
@AutoService(InstrumentationModule.class)
@@ -32,8 +41,70 @@ public ElementMatcher.Junction<ClassLoader> classLoaderMatcher() {
3241
public List<TypeInstrumentation> typeInstrumentations() {
3342
return asList(
3443
new JettyHandlerInstrumentation(
35-
"javax.servlet",
36-
Jetty8InstrumentationModule.class.getPackage().getName() + ".Jetty8HandlerAdvice"),
44+
"javax.servlet", getClass().getName() + "$Jetty8HandlerAdvice"),
3745
new JettyQueuedThreadPoolInstrumentation());
3846
}
47+
48+
@SuppressWarnings("unused")
49+
public static class Jetty8HandlerAdvice {
50+
51+
public static class AdviceScope {
52+
private final ServletRequestContext<HttpServletRequest> requestContext;
53+
private final Context context;
54+
private final Scope scope;
55+
56+
private AdviceScope(
57+
ServletRequestContext<HttpServletRequest> requestContext, Context context, Scope scope) {
58+
this.requestContext = requestContext;
59+
this.context = context;
60+
this.scope = scope;
61+
}
62+
63+
@Nullable
64+
public static AdviceScope start(HttpServletRequest request, HttpServletResponse response) {
65+
Context attachedContext = helper().getServerContext(request);
66+
if (attachedContext != null) {
67+
// We are inside nested handler, don't create new span
68+
return null;
69+
}
70+
Context parentContext = Context.current();
71+
ServletRequestContext<HttpServletRequest> requestContext =
72+
new ServletRequestContext<>(request);
73+
if (!helper().shouldStart(parentContext, requestContext)) {
74+
return null;
75+
}
76+
Context context = helper().start(parentContext, requestContext);
77+
Scope scope = context.makeCurrent();
78+
// Must be set here since Jetty handlers can use startAsync outside of servlet scope.
79+
helper().setAsyncListenerResponse(context, response);
80+
HttpServerResponseCustomizerHolder.getCustomizer()
81+
.customize(context, response, new Jetty8ResponseMutator());
82+
return new AdviceScope(requestContext, context, scope);
83+
}
84+
85+
public void end(
86+
@Nullable Throwable throwable, HttpServletRequest request, HttpServletResponse response) {
87+
helper().end(requestContext, request, response, throwable, context, scope);
88+
}
89+
}
90+
91+
@Advice.OnMethodEnter(suppress = Throwable.class, inline = false)
92+
@Nullable
93+
public static AdviceScope onEnter(
94+
@Advice.Argument(2) HttpServletRequest request,
95+
@Advice.Argument(3) HttpServletResponse response) {
96+
return AdviceScope.start(request, response);
97+
}
98+
99+
@Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class, inline = false)
100+
public static void stopSpan(
101+
@Advice.Argument(2) HttpServletRequest request,
102+
@Advice.Argument(3) HttpServletResponse response,
103+
@Advice.Thrown @Nullable Throwable throwable,
104+
@Advice.Enter @Nullable AdviceScope adviceScope) {
105+
if (adviceScope != null) {
106+
adviceScope.end(throwable, request, response);
107+
}
108+
}
109+
}
39110
}

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
import io.opentelemetry.javaagent.bootstrap.executors.PropagatedContext;
1717
import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation;
1818
import io.opentelemetry.javaagent.extension.instrumentation.TypeTransformer;
19+
import javax.annotation.Nullable;
1920
import net.bytebuddy.asm.Advice;
2021
import net.bytebuddy.description.type.TypeDescription;
2122
import net.bytebuddy.matcher.ElementMatcher;
@@ -50,7 +51,7 @@ public static PropagatedContext enterJobSubmit(@Advice.Argument(0) Runnable task
5051
public static void exitJobSubmit(
5152
@Advice.Argument(0) Runnable task,
5253
@Advice.Enter PropagatedContext propagatedContext,
53-
@Advice.Thrown Throwable throwable) {
54+
@Advice.Thrown @Nullable Throwable throwable) {
5455
ExecutorAdviceHelper.cleanUpAfterSubmit(
5556
propagatedContext, throwable, PROPAGATED_CONTEXT, task);
5657
}

instrumentation/jetty/jetty-8.0/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/jetty/v8_0/QueuedThreadPoolTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ void dispatchPropagatesLambda() throws Exception {
8686

8787
testing.waitAndAssertTraces(
8888
trace ->
89-
trace.hasSpansSatisfyingExactlyInAnyOrder(
89+
trace.hasSpansSatisfyingExactly(
9090
span -> span.hasName("parent").hasKind(SpanKind.INTERNAL).hasNoParent(),
9191
span ->
9292
span.hasName("asyncChild")

instrumentation/jetty/jetty-8.0/metadata.yaml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,20 +8,24 @@ features:
88
library_link: https://eclipse.dev/jetty/
99
configurations:
1010
- name: otel.instrumentation.http.known-methods
11+
declarative_name: java.common.http.known_methods
1112
description: >
1213
Configures the instrumentation to recognize an alternative set of HTTP request methods. All
1314
other methods will be treated as `_OTHER`.
1415
type: list
1516
default: "CONNECT,DELETE,GET,HEAD,OPTIONS,PATCH,POST,PUT,TRACE"
1617
- name: otel.instrumentation.http.server.capture-request-headers
18+
declarative_name: general.http.server.request_captured_headers
1719
description: List of HTTP request headers to capture in HTTP server telemetry.
1820
type: list
1921
default: ""
2022
- name: otel.instrumentation.http.server.capture-response-headers
23+
declarative_name: general.http.server.response_captured_headers
2124
description: List of HTTP response headers to capture in HTTP server telemetry.
2225
type: list
2326
default: ""
2427
- name: otel.instrumentation.http.server.emit-experimental-telemetry
28+
declarative_name: java.common.http.server.emit_experimental_telemetry/development
2529
description: >
2630
Enable the capture of experimental HTTP server telemetry. Adds the `http.request.body.size`
2731
and `http.response.body.size` attributes to spans, and records `http.server.request.size` and

0 commit comments

Comments
 (0)