From 17d5ea2b06044d1b4b60b4fda102934ca361cdde Mon Sep 17 00:00:00 2001 From: Peter Giacomo Lombardo Date: Tue, 10 Oct 2017 21:41:46 +0200 Subject: [PATCH 1/4] Improved HTTP propagator: Also support HTTP_ style headers --- instana/http_propagator.py | 44 +++++++++++++++++++++++++++----------- 1 file changed, 31 insertions(+), 13 deletions(-) diff --git a/instana/http_propagator.py b/instana/http_propagator.py index 48f20ce3..4b601dac 100644 --- a/instana/http_propagator.py +++ b/instana/http_propagator.py @@ -3,27 +3,39 @@ from basictracer.context import SpanContext from instana import util, log -prefix_tracer_state = 'X-Instana-' -field_name_trace_id = prefix_tracer_state + 'T' -field_name_span_id = prefix_tracer_state + 'S' -field_count = 2 + +# The carrier can be a dict or a list. +# Using the trace header as an example, it can be in the following forms +# for extraction: +# X-Instana-T +# HTTP_X_INSTANA_T +# +# The second form above is found in places like Django middleware for +# incoming requests. +# +# For injection, we only support the standard format: +# X-Instana-T class HTTPPropagator(): """A Propagator for Format.HTTP_HEADERS. """ + HEADER_KEY_T = 'X-Instana-T' + HEADER_KEY_S = 'X-Instana-S' + ALT_HEADER_KEY_T = 'HTTP_X_INSTANA_T' + ALT_HEADER_KEY_S = 'HTTP_X_INSTANA_S' + def inject(self, span_context, carrier): try: trace_id = util.id_to_header(span_context.trace_id) span_id = util.id_to_header(span_context.span_id) + if type(carrier) is dict or hasattr(carrier, "__dict__"): - carrier[field_name_trace_id] = trace_id - carrier[field_name_span_id] = span_id + carrier[self.HEADER_KEY_T] = trace_id + carrier[self.HEADER_KEY_S] = span_id elif type(carrier) is list: - trace_header = (field_name_trace_id, trace_id) - carrier.append(trace_header) - span_header = (field_name_span_id, span_id) - carrier.append(span_header) + carrier.append((self.HEADER_KEY_T, trace_id)) + carrier.append((self.HEADER_KEY_S, span_id)) else: raise Exception("Unsupported carrier type", type(carrier)) @@ -39,9 +51,15 @@ def extract(self, carrier): # noqa else: raise ot.SpanContextCorruptedException() - if field_name_trace_id in dc and field_name_span_id in dc: - trace_id = util.header_to_id(dc[field_name_trace_id]) - span_id = util.header_to_id(dc[field_name_span_id]) + # Look for standard X-Instana-T/S format + if self.HEADER_KEY_T in dc and self.header_key_s in dc: + trace_id = util.header_to_id(dc[self.HEADER_KEY_T]) + span_id = util.header_to_id(dc[self.header_key_s]) + + # Alternatively check for HTTP_X_INSTANA_T/S style + elif self.ALT_HEADER_KEY_T in dc and self.ALT_HEADER_KEY_S in dc: + trace_id = util.header_to_id(dc[self.ALT_HEADER_KEY_T]) + span_id = util.header_to_id(dc[self.ALT_HEADER_KEY_S]) return SpanContext(span_id=span_id, trace_id=trace_id, From 4c25c9159e29d2634d78b8e053e41b436d42c64a Mon Sep 17 00:00:00 2001 From: Peter Giacomo Lombardo Date: Fri, 13 Oct 2017 17:51:29 +0200 Subject: [PATCH 2/4] Add X-Instana-L header support for inject. --- instana/http_propagator.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/instana/http_propagator.py b/instana/http_propagator.py index 4b601dac..15a6a77a 100644 --- a/instana/http_propagator.py +++ b/instana/http_propagator.py @@ -22,8 +22,10 @@ class HTTPPropagator(): HEADER_KEY_T = 'X-Instana-T' HEADER_KEY_S = 'X-Instana-S' + HEADER_KEY_L = 'X-Instana-L' ALT_HEADER_KEY_T = 'HTTP_X_INSTANA_T' ALT_HEADER_KEY_S = 'HTTP_X_INSTANA_S' + ALT_HEADER_KEY_L = 'HTTP_X_INSTANA_L' def inject(self, span_context, carrier): try: @@ -33,9 +35,11 @@ def inject(self, span_context, carrier): if type(carrier) is dict or hasattr(carrier, "__dict__"): carrier[self.HEADER_KEY_T] = trace_id carrier[self.HEADER_KEY_S] = span_id + carrier[self.HEADER_KEY_L] = "1" elif type(carrier) is list: carrier.append((self.HEADER_KEY_T, trace_id)) carrier.append((self.HEADER_KEY_S, span_id)) + carrier.append((self.HEADER_KEY_L, "1")) else: raise Exception("Unsupported carrier type", type(carrier)) @@ -54,9 +58,9 @@ def extract(self, carrier): # noqa # Look for standard X-Instana-T/S format if self.HEADER_KEY_T in dc and self.header_key_s in dc: trace_id = util.header_to_id(dc[self.HEADER_KEY_T]) - span_id = util.header_to_id(dc[self.header_key_s]) + span_id = util.header_to_id(dc[self.HEADER_KEY_S]) - # Alternatively check for HTTP_X_INSTANA_T/S style + # Alternatively check for alternate HTTP_X_INSTANA_T/S style elif self.ALT_HEADER_KEY_T in dc and self.ALT_HEADER_KEY_S in dc: trace_id = util.header_to_id(dc[self.ALT_HEADER_KEY_T]) span_id = util.header_to_id(dc[self.ALT_HEADER_KEY_S]) From 8a7f5ea15bc94dea5e74e1c390701aa036cd66c2 Mon Sep 17 00:00:00 2001 From: Peter Giacomo Lombardo Date: Fri, 13 Oct 2017 18:14:46 +0200 Subject: [PATCH 3/4] Starter propagator tests. --- tests/test_ot_propagators.py | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 tests/test_ot_propagators.py diff --git a/tests/test_ot_propagators.py b/tests/test_ot_propagators.py new file mode 100644 index 00000000..2eab849b --- /dev/null +++ b/tests/test_ot_propagators.py @@ -0,0 +1,33 @@ +import instana.http_propagator as ihp +import opentracing as ot +from instana import tracer, options, util +from nose.tools import assert_equals +import inspect + + +def test_basics(): + inspect.isclass(ihp.HTTPPropagator) + + inject_func = getattr(ihp.HTTPPropagator, "inject", None) + assert inject_func + assert inspect.ismethod(inject_func) + + extract_func = getattr(ihp.HTTPPropagator, "extract", None) + assert extract_func + assert inspect.ismethod(extract_func) + + +def test_inject(): + opts = options.Options() + ot.global_tracer = tracer.InstanaTracer(opts) + + carrier = {} + span = ot.global_tracer.start_span("nosetests") + ot.global_tracer.inject(span.context, ot.Format.HTTP_HEADERS, carrier) + + assert 'X-Instana-T' in carrier + assert_equals(carrier['X-Instana-T'], util.id_to_header(span.context.trace_id)) + assert 'X-Instana-S' in carrier + assert_equals(carrier['X-Instana-S'], util.id_to_header(span.context.span_id)) + assert 'X-Instana-L' in carrier + assert_equals(carrier['X-Instana-L'], "1") From 210be14772b403e8fb5938e4e2cd391d43275ab1 Mon Sep 17 00:00:00 2001 From: Peter Giacomo Lombardo Date: Fri, 13 Oct 2017 18:21:27 +0200 Subject: [PATCH 4/4] Fix function test to work on both Py 2 + 3 --- tests/test_ot_propagators.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/test_ot_propagators.py b/tests/test_ot_propagators.py index 2eab849b..e3996fa9 100644 --- a/tests/test_ot_propagators.py +++ b/tests/test_ot_propagators.py @@ -10,11 +10,11 @@ def test_basics(): inject_func = getattr(ihp.HTTPPropagator, "inject", None) assert inject_func - assert inspect.ismethod(inject_func) + assert callable(inject_func) extract_func = getattr(ihp.HTTPPropagator, "extract", None) assert extract_func - assert inspect.ismethod(extract_func) + assert callable(extract_func) def test_inject():