Skip to content

Commit 7cbd938

Browse files
fix(tornado) ensure error status codes mark the span as an error (#2984) (#2989)
* fix(tornado) ensure error status codes mark the span as an error We were only marking the tornado spans as an error if the request raised an exception. While this is the typical way users will return an error we were not looking to see if users were manually set the status code to 500 <= x < 600 and setting span.error. This change has tornado use `set_http_meta` to ensure a consistent experience across web server integrations. * remove unused import (cherry picked from commit 9f8b827) Co-authored-by: Brett Langdon <[email protected]>
1 parent 4e2d633 commit 7cbd938

File tree

4 files changed

+42
-6
lines changed

4 files changed

+42
-6
lines changed

ddtrace/contrib/tornado/handlers.py

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,9 @@
66
from ...constants import ANALYTICS_SAMPLE_RATE_KEY
77
from ...constants import SPAN_MEASURED_KEY
88
from ...ext import SpanTypes
9-
from ...ext import http
109
from ...utils import ArgumentError
1110
from ...utils import get_argument_value
11+
from ..trace_utils import set_http_meta
1212
from .constants import CONFIG_KEY
1313
from .constants import REQUEST_SPAN_KEY
1414
from .stack_context import TracerStackContext
@@ -63,11 +63,14 @@ def on_finish(func, handler, args, kwargs):
6363
# space here
6464
klass = handler.__class__
6565
request_span.resource = "{}.{}".format(klass.__module__, klass.__name__)
66-
request_span.set_tag("http.method", request.method)
67-
request_span.set_tag("http.status_code", handler.get_status())
68-
request_span.set_tag(http.URL, request.full_url().rsplit("?", 1)[0])
69-
if config.tornado.trace_query_string:
70-
request_span.set_tag(http.QUERY_STRING, request.query)
66+
set_http_meta(
67+
request_span,
68+
config.tornado,
69+
method=request.method,
70+
url=request.full_url().rsplit("?", 1)[0],
71+
status_code=handler.get_status(),
72+
query=request.query,
73+
)
7174
request_span.finish()
7275

7376
return func(*args, **kwargs)
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
---
2+
fixes:
3+
- |
4+
Ensure tornado spans are marked as an error if the response status code is 500 <= x < 600.

tests/contrib/tornado/test_tornado_web.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,27 @@ def test_success_handler_query_string_trace(self):
5555
with self.override_http_config("tornado", dict(trace_query_string=True)):
5656
self.test_success_handler("foo=bar")
5757

58+
def test_status_code_500_handler(self):
59+
"""
60+
Test an endpoint which sets the status code to 500 but doesn't raise an exception
61+
62+
We expect the resulting span to be marked as an error
63+
"""
64+
response = self.fetch("/status_code/500")
65+
assert 500 == response.code
66+
67+
traces = self.pop_traces()
68+
assert 1 == len(traces)
69+
assert 1 == len(traces[0])
70+
71+
request_span = traces[0][0]
72+
assert_is_measured(request_span)
73+
assert "tests.contrib.tornado.web.app.ResponseStatusHandler" == request_span.resource
74+
assert "GET" == request_span.get_tag("http.method")
75+
assert_span_http_status_code(request_span, 500)
76+
assert self.get_url("/status_code/500") == request_span.get_tag(http.URL)
77+
assert 1 == request_span.error
78+
5879
def test_nested_handler(self):
5980
# it should trace a handler that calls the tracer.trace() method
6081
# using the automatic Context retrieval

tests/contrib/tornado/web/app.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,13 @@ def get(self):
1919
self.write("OK")
2020

2121

22+
class ResponseStatusHandler(tornado.web.RequestHandler):
23+
@tornado.gen.coroutine
24+
def get(self, status_code):
25+
self.set_status(int(status_code))
26+
self.write("status_code: {}".format(status_code))
27+
28+
2229
class NestedHandler(tornado.web.RequestHandler):
2330
@tornado.gen.coroutine
2431
def get(self):
@@ -307,6 +314,7 @@ def make_app(settings={}):
307314
[
308315
# custom handlers
309316
(r"/success/", SuccessHandler),
317+
(r"/status_code/([0-9]+)", ResponseStatusHandler),
310318
(r"/nested/", NestedHandler),
311319
(r"/nested_wrap/", NestedWrapHandler),
312320
(r"/nested_exception_wrap/", NestedExceptionWrapHandler),

0 commit comments

Comments
 (0)