Skip to content

Commit fe4e2d4

Browse files
pitabwirealrex
and
alrex
authored
Reorder on_finish call order to correctly instrument all tornado work done during a request (#499)
Co-authored-by: alrex <[email protected]>
1 parent 5b125b1 commit fe4e2d4

File tree

4 files changed

+64
-1
lines changed

4 files changed

+64
-1
lines changed

CHANGELOG.md

+2
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
66

77
## [Unreleased](https://github.com/open-telemetry/opentelemetry-python/compare/v1.3.0-0.22b0...HEAD)
88

9+
- `opentelemetry-instrumentation-tornado` properly instrument work done in tornado on_finish method.
10+
([#499](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/499))
911
- `opentelemetry-instrumentation` Fixed cases where trying to use an instrumentation package without the
1012
target library was crashing auto instrumentation agent.
1113
([#530](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/530))

instrumentation/opentelemetry-instrumentation-tornado/src/opentelemetry/instrumentation/tornado/__init__.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -213,8 +213,9 @@ def _prepare(tracer, request_hook, func, handler, args, kwargs):
213213

214214

215215
def _on_finish(tracer, func, handler, args, kwargs):
216+
response = func(*args, **kwargs)
216217
_finish_span(tracer, handler)
217-
return func(*args, **kwargs)
218+
return response
218219

219220

220221
def _log_exception(tracer, func, handler, args, kwargs):

instrumentation/opentelemetry-instrumentation-tornado/tests/test_instrumentation.py

+48
Original file line numberDiff line numberDiff line change
@@ -347,6 +347,54 @@ def test_dynamic_handler(self):
347347
},
348348
)
349349

350+
def test_handler_on_finish(self):
351+
352+
response = self.fetch("/on_finish")
353+
self.assertEqual(response.code, 200)
354+
355+
spans = self.sorted_spans(self.memory_exporter.get_finished_spans())
356+
self.assertEqual(len(spans), 3)
357+
auditor, server, client = spans
358+
359+
self.assertEqual(server.name, "FinishedHandler.get")
360+
self.assertTrue(server.parent.is_remote)
361+
self.assertNotEqual(server.parent, client.context)
362+
self.assertEqual(server.parent.span_id, client.context.span_id)
363+
self.assertEqual(server.context.trace_id, client.context.trace_id)
364+
self.assertEqual(server.kind, SpanKind.SERVER)
365+
self.assert_span_has_attributes(
366+
server,
367+
{
368+
SpanAttributes.HTTP_METHOD: "GET",
369+
SpanAttributes.HTTP_SCHEME: "http",
370+
SpanAttributes.HTTP_HOST: "127.0.0.1:"
371+
+ str(self.get_http_port()),
372+
SpanAttributes.HTTP_TARGET: "/on_finish",
373+
SpanAttributes.NET_PEER_IP: "127.0.0.1",
374+
SpanAttributes.HTTP_STATUS_CODE: 200,
375+
},
376+
)
377+
378+
self.assertEqual(client.name, "GET")
379+
self.assertFalse(client.context.is_remote)
380+
self.assertIsNone(client.parent)
381+
self.assertEqual(client.kind, SpanKind.CLIENT)
382+
self.assert_span_has_attributes(
383+
client,
384+
{
385+
SpanAttributes.HTTP_URL: self.get_url("/on_finish"),
386+
SpanAttributes.HTTP_METHOD: "GET",
387+
SpanAttributes.HTTP_STATUS_CODE: 200,
388+
},
389+
)
390+
391+
self.assertEqual(auditor.name, "audit_task")
392+
self.assertFalse(auditor.context.is_remote)
393+
self.assertEqual(auditor.parent.span_id, server.context.span_id)
394+
self.assertEqual(auditor.context.trace_id, client.context.trace_id)
395+
396+
self.assertEqual(auditor.kind, SpanKind.INTERNAL)
397+
350398
def test_exclude_lists(self):
351399
def test_excluded(path):
352400
self.fetch(path)

instrumentation/opentelemetry-instrumentation-tornado/tests/tornado_test_app.py

+12
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
# pylint: disable=W0223,R0201
2+
import time
23

34
import tornado.web
45
from tornado import gen
@@ -79,6 +80,16 @@ def get(self):
7980
self.set_status(202)
8081

8182

83+
class FinishedHandler(tornado.web.RequestHandler):
84+
def on_finish(self):
85+
with self.application.tracer.start_as_current_span("audit_task"):
86+
time.sleep(0.05)
87+
88+
def get(self):
89+
self.write("Test can finish")
90+
self.set_status(200)
91+
92+
8293
class HealthCheckHandler(tornado.web.RequestHandler):
8394
def get(self):
8495
self.set_status(200)
@@ -91,6 +102,7 @@ def make_app(tracer):
91102
(r"/error", BadHandler),
92103
(r"/cor", CoroutineHandler),
93104
(r"/async", AsyncHandler),
105+
(r"/on_finish", FinishedHandler),
94106
(r"/healthz", HealthCheckHandler),
95107
(r"/ping", HealthCheckHandler),
96108
]

0 commit comments

Comments
 (0)