Skip to content

Commit 45832be

Browse files
authored
Merge pull request #29 from instana/better_http_propagator
Propagators should support all forms of Instana Headers
2 parents 6f25a5f + 210be14 commit 45832be

File tree

2 files changed

+68
-13
lines changed

2 files changed

+68
-13
lines changed

instana/http_propagator.py

+35-13
Original file line numberDiff line numberDiff line change
@@ -3,27 +3,43 @@
33
from basictracer.context import SpanContext
44
from instana import util, log
55

6-
prefix_tracer_state = 'X-Instana-'
7-
field_name_trace_id = prefix_tracer_state + 'T'
8-
field_name_span_id = prefix_tracer_state + 'S'
9-
field_count = 2
6+
7+
# The carrier can be a dict or a list.
8+
# Using the trace header as an example, it can be in the following forms
9+
# for extraction:
10+
# X-Instana-T
11+
# HTTP_X_INSTANA_T
12+
#
13+
# The second form above is found in places like Django middleware for
14+
# incoming requests.
15+
#
16+
# For injection, we only support the standard format:
17+
# X-Instana-T
1018

1119

1220
class HTTPPropagator():
1321
"""A Propagator for Format.HTTP_HEADERS. """
1422

23+
HEADER_KEY_T = 'X-Instana-T'
24+
HEADER_KEY_S = 'X-Instana-S'
25+
HEADER_KEY_L = 'X-Instana-L'
26+
ALT_HEADER_KEY_T = 'HTTP_X_INSTANA_T'
27+
ALT_HEADER_KEY_S = 'HTTP_X_INSTANA_S'
28+
ALT_HEADER_KEY_L = 'HTTP_X_INSTANA_L'
29+
1530
def inject(self, span_context, carrier):
1631
try:
1732
trace_id = util.id_to_header(span_context.trace_id)
1833
span_id = util.id_to_header(span_context.span_id)
34+
1935
if type(carrier) is dict or hasattr(carrier, "__dict__"):
20-
carrier[field_name_trace_id] = trace_id
21-
carrier[field_name_span_id] = span_id
36+
carrier[self.HEADER_KEY_T] = trace_id
37+
carrier[self.HEADER_KEY_S] = span_id
38+
carrier[self.HEADER_KEY_L] = "1"
2239
elif type(carrier) is list:
23-
trace_header = (field_name_trace_id, trace_id)
24-
carrier.append(trace_header)
25-
span_header = (field_name_span_id, span_id)
26-
carrier.append(span_header)
40+
carrier.append((self.HEADER_KEY_T, trace_id))
41+
carrier.append((self.HEADER_KEY_S, span_id))
42+
carrier.append((self.HEADER_KEY_L, "1"))
2743
else:
2844
raise Exception("Unsupported carrier type", type(carrier))
2945

@@ -39,9 +55,15 @@ def extract(self, carrier): # noqa
3955
else:
4056
raise ot.SpanContextCorruptedException()
4157

42-
if field_name_trace_id in dc and field_name_span_id in dc:
43-
trace_id = util.header_to_id(dc[field_name_trace_id])
44-
span_id = util.header_to_id(dc[field_name_span_id])
58+
# Look for standard X-Instana-T/S format
59+
if self.HEADER_KEY_T in dc and self.header_key_s in dc:
60+
trace_id = util.header_to_id(dc[self.HEADER_KEY_T])
61+
span_id = util.header_to_id(dc[self.HEADER_KEY_S])
62+
63+
# Alternatively check for alternate HTTP_X_INSTANA_T/S style
64+
elif self.ALT_HEADER_KEY_T in dc and self.ALT_HEADER_KEY_S in dc:
65+
trace_id = util.header_to_id(dc[self.ALT_HEADER_KEY_T])
66+
span_id = util.header_to_id(dc[self.ALT_HEADER_KEY_S])
4567

4668
return SpanContext(span_id=span_id,
4769
trace_id=trace_id,

tests/test_ot_propagators.py

+33
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import instana.http_propagator as ihp
2+
import opentracing as ot
3+
from instana import tracer, options, util
4+
from nose.tools import assert_equals
5+
import inspect
6+
7+
8+
def test_basics():
9+
inspect.isclass(ihp.HTTPPropagator)
10+
11+
inject_func = getattr(ihp.HTTPPropagator, "inject", None)
12+
assert inject_func
13+
assert callable(inject_func)
14+
15+
extract_func = getattr(ihp.HTTPPropagator, "extract", None)
16+
assert extract_func
17+
assert callable(extract_func)
18+
19+
20+
def test_inject():
21+
opts = options.Options()
22+
ot.global_tracer = tracer.InstanaTracer(opts)
23+
24+
carrier = {}
25+
span = ot.global_tracer.start_span("nosetests")
26+
ot.global_tracer.inject(span.context, ot.Format.HTTP_HEADERS, carrier)
27+
28+
assert 'X-Instana-T' in carrier
29+
assert_equals(carrier['X-Instana-T'], util.id_to_header(span.context.trace_id))
30+
assert 'X-Instana-S' in carrier
31+
assert_equals(carrier['X-Instana-S'], util.id_to_header(span.context.span_id))
32+
assert 'X-Instana-L' in carrier
33+
assert_equals(carrier['X-Instana-L'], "1")

0 commit comments

Comments
 (0)