11import datadog.trace.agent.test.AgentTestRunner
22import datadog.trace.agent.test.TestUtils
33import datadog.trace.agent.test.utils.OkHttpUtils
4- import datadog.trace.api.Config
54import datadog.trace.api.DDSpanTypes
65import okhttp3.OkHttpClient
76import org.eclipse.jetty.continuation.Continuation
@@ -11,9 +10,11 @@ import org.eclipse.jetty.server.Request
1110import org.eclipse.jetty.server.Server
1211import org.eclipse.jetty.server.handler.AbstractHandler
1312
13+ import javax.servlet.DispatcherType
1414import javax.servlet.ServletException
1515import javax.servlet.http.HttpServletRequest
1616import javax.servlet.http.HttpServletResponse
17+ import java.util.concurrent.atomic.AtomicBoolean
1718
1819class JettyHandlerTest extends AgentTestRunner {
1920
@@ -55,29 +56,29 @@ class JettyHandlerTest extends AgentTestRunner {
5556
5657 expect :
5758 response. body(). string(). trim() == " Hello World"
58- TEST_WRITER . waitForTraces( 1 )
59- TEST_WRITER . size() == 1
60- def trace = TEST_WRITER . firstTrace()
61- trace . size() == 1
62- def context = trace[ 0 ] . context()
63- context . serviceName == " unnamed-java-app "
64- context . operationName == " jetty.request "
65- context . resourceName == " GET ${ handler.class.name } "
66- context . spanType == DDSpanTypes . HTTP_SERVER
67- ! context . getErrorFlag ()
68- context . parentId == " 0 "
69- def tags = context . tags
70- tags[ " http.url " ] == " http://localhost: $p ort / "
71- tags[ " http.method " ] == " GET "
72- tags[ " span.kind " ] == " server "
73- tags[ " span.type" ] == DDSpanTypes . HTTP_SERVER
74- tags[ " component " ] == " jetty-handler "
75- tags[ " http.status_code" ] == 200
76- tags[ " thread.name " ] != null
77- tags[ " thread.id " ] != null
78- tags[ Config . RUNTIME_ID_TAG ] == Config . get() . runtimeId
79- tags[ " span.origin.type " ] == handler . class . name
80- tags . size() == 10
59+
60+ assertTraces( 1 ) {
61+ trace( 0 , 1 ) {
62+ span( 0 ) {
63+ serviceName " unnamed-java-app "
64+ operationName " jetty.request "
65+ resourceName " GET ${ handler.class.name } "
66+ spanType DDSpanTypes . HTTP_SERVER
67+ errored false
68+ parent ()
69+ tags {
70+ " http.url " " http://localhost: $p ort / "
71+ " http.method " " GET "
72+ " span.kind " " server "
73+ " component " " jetty-handler "
74+ " span.origin. type" handler . class . name
75+ " span.type " DDSpanTypes . HTTP_SERVER
76+ " http.status_code" 200
77+ defaultTags()
78+ }
79+ }
80+ }
81+ }
8182 }
8283
8384 def " handler instrumentation clears state after async request" () {
@@ -127,10 +128,16 @@ class JettyHandlerTest extends AgentTestRunner {
127128
128129 def " call to jetty with error creates a trace" () {
129130 setup :
131+ def errorHandlerCalled = new AtomicBoolean (false )
130132 Handler handler = new AbstractHandler () {
131133 @Override
132134 void handle (String target , Request baseRequest , HttpServletRequest request , HttpServletResponse response ) throws IOException , ServletException {
133- throw new RuntimeException ()
135+ if (baseRequest. dispatcherType == DispatcherType . ERROR ) {
136+ errorHandlerCalled. set(true )
137+ baseRequest. setHandled(true )
138+ } else {
139+ throw new RuntimeException ()
140+ }
134141 }
135142 }
136143 server. setHandler(handler)
@@ -143,31 +150,52 @@ class JettyHandlerTest extends AgentTestRunner {
143150
144151 expect :
145152 response. body(). string(). trim() == " "
146- TEST_WRITER . waitForTraces(1 )
147- TEST_WRITER . size() == 1
148- def trace = TEST_WRITER . firstTrace()
149- trace. size() == 1
150- def context = trace[0 ]. context()
151- context. serviceName == " unnamed-java-app"
152- context. operationName == " jetty.request"
153- context. resourceName == " GET ${ handler.class.name} "
154- context. spanType == DDSpanTypes . HTTP_SERVER
155- context. getErrorFlag()
156- context. parentId == " 0"
157- def tags = context. tags
158- tags[" http.url" ] == " http://localhost:$port /"
159- tags[" http.method" ] == " GET"
160- tags[" span.kind" ] == " server"
161- tags[" span.type" ] == DDSpanTypes . HTTP_SERVER
162- tags[" component" ] == " jetty-handler"
163- tags[" http.status_code" ] == 500
164- tags[" thread.name" ] != null
165- tags[" thread.id" ] != null
166- tags[Config . RUNTIME_ID_TAG ] == Config . get(). runtimeId
167- tags[" span.origin.type" ] == handler. class. name
168- tags[" error" ] == true
169- tags[" error.type" ] == RuntimeException . name
170- tags[" error.stack" ] != null
171- tags. size() == 13
153+
154+ assertTraces(errorHandlerCalled. get() ? 2 : 1 ) {
155+ trace(0 , 1 ) {
156+ span(0 ) {
157+ serviceName " unnamed-java-app"
158+ operationName " jetty.request"
159+ resourceName " GET ${ handler.class.name} "
160+ spanType DDSpanTypes . HTTP_SERVER
161+ errored true
162+ parent()
163+ tags {
164+ " http.url" " http://localhost:$port /"
165+ " http.method" " GET"
166+ " span.kind" " server"
167+ " component" " jetty-handler"
168+ " span.origin.type" handler. class. name
169+ " span.type" DDSpanTypes . HTTP_SERVER
170+ " http.status_code" 500
171+ errorTags RuntimeException
172+ defaultTags()
173+ }
174+ }
175+ }
176+ if (errorHandlerCalled. get()) {
177+ trace(1 , 1 ) {
178+ span(0 ) {
179+ serviceName " unnamed-java-app"
180+ operationName " jetty.request"
181+ resourceName " GET ${ handler.class.name} "
182+ spanType DDSpanTypes . HTTP_SERVER
183+ errored true
184+ parent()
185+ tags {
186+ " http.url" " http://localhost:$port /"
187+ " http.method" " GET"
188+ " span.kind" " server"
189+ " component" " jetty-handler"
190+ " span.origin.type" handler. class. name
191+ " span.type" DDSpanTypes . HTTP_SERVER
192+ " http.status_code" 500
193+ " error" true
194+ defaultTags()
195+ }
196+ }
197+ }
198+ }
199+ }
172200 }
173201}
0 commit comments