66package io .opentelemetry .javaagent .instrumentation .jetty .v8_0 ;
77
88import static io .opentelemetry .javaagent .extension .matcher .AgentElementMatchers .hasClassesNamed ;
9+ import static io .opentelemetry .javaagent .instrumentation .jetty .v8_0 .Jetty8Singletons .helper ;
910import static java .util .Arrays .asList ;
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 ;
1520import 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 ;
1625import 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}
0 commit comments