66package io .opentelemetry .javaagent .instrumentation .jetty .v11_0 ;
77
88import static io .opentelemetry .javaagent .extension .matcher .AgentElementMatchers .hasClassesNamed ;
9+ import static io .opentelemetry .javaagent .instrumentation .jetty .v11_0 .Jetty11Singletons .helper ;
910import static java .util .Collections .singletonList ;
1011
1112import 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 ;
1217import io .opentelemetry .javaagent .extension .instrumentation .InstrumentationModule ;
1318import io .opentelemetry .javaagent .extension .instrumentation .TypeInstrumentation ;
1419import io .opentelemetry .javaagent .instrumentation .jetty .common .JettyHandlerInstrumentation ;
20+ import jakarta .servlet .http .HttpServletRequest ;
21+ import jakarta .servlet .http .HttpServletResponse ;
1522import java .util .List ;
23+ import javax .annotation .Nullable ;
24+ import net .bytebuddy .asm .Advice ;
1625import net .bytebuddy .matcher .ElementMatcher ;
1726
1827@ AutoService (InstrumentationModule .class )
@@ -32,7 +41,69 @@ public ElementMatcher.Junction<ClassLoader> classLoaderMatcher() {
3241 public List <TypeInstrumentation > typeInstrumentations () {
3342 return singletonList (
3443 new JettyHandlerInstrumentation (
35- "jakarta.servlet" ,
36- Jetty11InstrumentationModule .class .getPackage ().getName () + ".Jetty11HandlerAdvice" ));
44+ "jakarta.servlet" , getClass ().getName () + "$Jetty11HandlerAdvice" ));
45+ }
46+
47+ @ SuppressWarnings ("unused" )
48+ public static class Jetty11HandlerAdvice {
49+
50+ public static class AdviceScope {
51+ private final ServletRequestContext <HttpServletRequest > requestContext ;
52+ private final Context context ;
53+ private final Scope scope ;
54+
55+ private AdviceScope (
56+ ServletRequestContext <HttpServletRequest > requestContext , Context context , Scope scope ) {
57+ this .requestContext = requestContext ;
58+ this .context = context ;
59+ this .scope = scope ;
60+ }
61+
62+ @ Nullable
63+ public static AdviceScope start (HttpServletRequest request , HttpServletResponse response ) {
64+ Context attachedContext = helper ().getServerContext (request );
65+ if (attachedContext != null ) {
66+ // We are inside nested handler, don't create new span
67+ return null ;
68+ }
69+ Context parentContext = Context .current ();
70+ ServletRequestContext <HttpServletRequest > requestContext =
71+ new ServletRequestContext <>(request );
72+ if (!helper ().shouldStart (parentContext , requestContext )) {
73+ return null ;
74+ }
75+ Context context = helper ().start (parentContext , requestContext );
76+ Scope scope = context .makeCurrent ();
77+ // Must be set here since Jetty handlers can use startAsync outside of servlet scope.
78+ helper ().setAsyncListenerResponse (context , response );
79+ HttpServerResponseCustomizerHolder .getCustomizer ()
80+ .customize (context , response , new Jetty11ResponseMutator ());
81+ return new AdviceScope (requestContext , context , scope );
82+ }
83+
84+ public void end (
85+ @ Nullable Throwable throwable , HttpServletRequest request , HttpServletResponse response ) {
86+ helper ().end (requestContext , request , response , throwable , context , scope );
87+ }
88+ }
89+
90+ @ Nullable
91+ @ Advice .OnMethodEnter (suppress = Throwable .class , inline = false )
92+ public static AdviceScope onEnter (
93+ @ Advice .Argument (2 ) HttpServletRequest request ,
94+ @ Advice .Argument (3 ) HttpServletResponse response ) {
95+ return AdviceScope .start (request , response );
96+ }
97+
98+ @ Advice .OnMethodExit (onThrowable = Throwable .class , suppress = Throwable .class , inline = false )
99+ public static void stopSpan (
100+ @ Advice .Argument (2 ) HttpServletRequest request ,
101+ @ Advice .Argument (3 ) HttpServletResponse response ,
102+ @ Advice .Thrown @ Nullable Throwable throwable ,
103+ @ Advice .Enter @ Nullable AdviceScope adviceScope ) {
104+ if (adviceScope != null ) {
105+ adviceScope .end (throwable , request , response );
106+ }
107+ }
37108 }
38109}
0 commit comments