37
37
from elasticapm import async_capture_span
38
38
from elasticapm .conf import constants
39
39
from elasticapm .contrib .tornado import ElasticAPM
40
+ from elasticapm .utils .disttracing import TraceParent
41
+
42
+ pytestmark = pytest .mark .tornado
40
43
41
44
42
45
@pytest .fixture
@@ -49,7 +52,7 @@ def get(self):
49
52
50
53
class BoomHandler (tornado .web .RequestHandler ):
51
54
def get (self ):
52
- raise ValueError ()
55
+ raise tornado . web . HTTPError ()
53
56
54
57
app = tornado .web .Application ([(r"/" , HelloHandler ), (r"/boom" , BoomHandler )])
55
58
apm = ElasticAPM (app , elasticapm_client )
@@ -77,3 +80,49 @@ async def test_get(app, base_url, http_client):
77
80
request ["socket" ] == {"remote_address" : "127.0.0.1" , "encrypted" : False }
78
81
79
82
assert span ["name" ] == "test"
83
+
84
+
85
+ @pytest .mark .gen_test
86
+ async def test_exception (app , base_url , http_client ):
87
+ elasticapm_client = app .elasticapm_client
88
+ with pytest .raises (tornado .httpclient .HTTPClientError ):
89
+ response = await http_client .fetch (base_url + "/boom" )
90
+
91
+ assert len (elasticapm_client .events [constants .TRANSACTION ]) == 1
92
+ transaction = elasticapm_client .events [constants .TRANSACTION ][0 ]
93
+ spans = elasticapm_client .spans_for_transaction (transaction )
94
+ assert len (spans ) == 0
95
+
96
+ assert transaction ["name" ] == "GET BoomHandler"
97
+ assert transaction ["result" ] == "HTTP 5xx"
98
+ assert transaction ["type" ] == "request"
99
+ request = transaction ["context" ]["request" ]
100
+ assert request ["method" ] == "GET"
101
+ assert request ["socket" ] == {"remote_address" : "127.0.0.1" , "encrypted" : False }
102
+ assert transaction ["context" ]["response" ]["status_code" ] == 500
103
+
104
+ assert len (elasticapm_client .events [constants .ERROR ]) == 1
105
+ error = elasticapm_client .events [constants .ERROR ][0 ]
106
+ assert error ["transaction_id" ] == transaction ["id" ]
107
+ assert error ["exception" ]["type" ] == "HTTPError"
108
+ assert error ["context" ]["request" ] == transaction ["context" ]["request" ]
109
+
110
+
111
+ @pytest .mark .gen_test
112
+ async def test_traceparent_handling (app , base_url , http_client ):
113
+ elasticapm_client = app .elasticapm_client
114
+ with mock .patch (
115
+ "elasticapm.instrumentation.packages.tornado.TraceParent.from_headers" , wraps = TraceParent .from_headers
116
+ ) as wrapped_from_string :
117
+ headers = tornado .httputil .HTTPHeaders ()
118
+ headers .add (constants .TRACEPARENT_HEADER_NAME , "00-0af7651916cd43dd8448eb211c80319c-b7ad6b7169203331-03" )
119
+ headers .add (constants .TRACESTATE_HEADER_NAME , "foo=bar,bar=baz" )
120
+ headers .add (constants .TRACESTATE_HEADER_NAME , "baz=bazzinga" )
121
+ request = tornado .httpclient .HTTPRequest (url = base_url , headers = headers )
122
+ resp = await http_client .fetch (request )
123
+
124
+ transaction = elasticapm_client .events [constants .TRANSACTION ][0 ]
125
+
126
+ assert transaction ["trace_id" ] == "0af7651916cd43dd8448eb211c80319c"
127
+ assert transaction ["parent_id" ] == "b7ad6b7169203331"
128
+ assert "foo=bar,bar=baz,baz=bazzinga" == wrapped_from_string .call_args [0 ][0 ]["TraceState" ]
0 commit comments