Skip to content

Commit 788a163

Browse files
committed
Added trace response headers to Tornado
1 parent 370952f commit 788a163

File tree

4 files changed

+48
-1
lines changed

4 files changed

+48
-1
lines changed

.github/workflows/test.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ on:
66
- 'release/*'
77
pull_request:
88
env:
9-
CORE_REPO_SHA: cad261e5dae1fe986c87e6965664b45cc9ab73c3
9+
CORE_REPO_SHA: f6b04c483f6c416e1927f010c07e71a17a5d79d0
1010

1111
jobs:
1212
build:

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
2121
([#299](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/299))
2222
- `opentelemetry-instrumenation-django` now supports request and response hooks.
2323
([#407](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/407))
24+
- `opentelemetry-instrumenation-tornado` now supports trace response headers.
25+
([#433](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/433))
2426

2527
### Removed
2628
- Remove `http.status_text` from span attributes

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

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,10 @@ def get(self):
4646

4747
from opentelemetry import context, trace
4848
from opentelemetry.instrumentation.instrumentor import BaseInstrumentor
49+
from opentelemetry.instrumentation.propagators import (
50+
FuncSetter,
51+
get_global_back_propagator,
52+
)
4953
from opentelemetry.instrumentation.tornado.version import __version__
5054
from opentelemetry.instrumentation.utils import (
5155
extract_attributes_from_object,
@@ -68,6 +72,8 @@ def get(self):
6872
_excluded_urls = get_excluded_urls("TORNADO")
6973
_traced_request_attrs = get_traced_request_attrs("TORNADO")
7074

75+
back_propagation_setter = FuncSetter(tornado.web.RequestHandler.add_header)
76+
7177

7278
class TornadoInstrumentor(BaseInstrumentor):
7379
patched_handlers = []
@@ -211,6 +217,14 @@ def _start_span(tracer, handler, start_time) -> _TraceContext:
211217
activation.__enter__() # pylint: disable=E1101
212218
ctx = _TraceContext(activation, span, token)
213219
setattr(handler, _HANDLER_CONTEXT_KEY, ctx)
220+
221+
# finish handler is called after the response is sent back to
222+
# the client so it is too late to inject trace response headers
223+
# there.
224+
propagator = get_global_back_propagator()
225+
if propagator:
226+
propagator.inject(handler, setter=back_propagation_setter)
227+
214228
return ctx
215229

216230

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

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,11 @@
1818
from tornado.testing import AsyncHTTPTestCase
1919

2020
from opentelemetry import trace
21+
from opentelemetry.instrumentation.propagators import (
22+
TraceResponsePropagator,
23+
get_global_back_propagator,
24+
set_global_back_propagator,
25+
)
2126
from opentelemetry.instrumentation.tornado import (
2227
TornadoInstrumentor,
2328
patch_handler_class,
@@ -366,6 +371,32 @@ def test_traced_attrs(self):
366371
)
367372
self.memory_exporter.clear()
368373

374+
def test_response_headers(self):
375+
orig = get_global_back_propagator()
376+
set_global_back_propagator(TraceResponsePropagator())
377+
378+
response = self.fetch("/")
379+
headers = response.headers
380+
381+
spans = self.sorted_spans(self.memory_exporter.get_finished_spans())
382+
self.assertEqual(len(spans), 3)
383+
server_span = spans[1]
384+
385+
self.assertIn("traceresponse", headers)
386+
self.assertEqual(
387+
headers["access-control-expose-headers"], "traceresponse",
388+
)
389+
self.assertEqual(
390+
headers["traceresponse"],
391+
"00-{0}-{1}-01".format(
392+
trace.format_trace_id(server_span.get_span_context().trace_id),
393+
trace.format_span_id(server_span.get_span_context().span_id),
394+
),
395+
)
396+
397+
self.memory_exporter.clear()
398+
set_global_back_propagator(orig)
399+
369400

370401
class TestTornadoUninstrument(TornadoTest):
371402
def test_uninstrument(self):

0 commit comments

Comments
 (0)