Skip to content

Commit e7ed8a4

Browse files
authored
Asynqp: Update and use the TEXT_MAP propagator (#144)
* Update and use the TEXT_MAP propagator * Update tests to follow changes.
1 parent 1c316a2 commit e7ed8a4

File tree

4 files changed

+139
-32
lines changed

4 files changed

+139
-32
lines changed

instana/instrumentation/asynqp.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ def publish_with_instana(wrapped, instance, argv, kwargs):
2424
msg = argv[0]
2525
if msg.headers is None:
2626
msg.headers = {}
27-
async_tracer.inject(scope.span.context, opentracing.Format.HTTP_HEADERS, msg.headers)
27+
async_tracer.inject(scope.span.context, opentracing.Format.TEXT_MAP, msg.headers)
2828

2929
try:
3030
scope.span.set_tag("exchange", instance.name)
@@ -77,7 +77,7 @@ def callback_with_instana(*argv, **kwargs):
7777
ctx = None
7878
msg = argv[0]
7979
if msg.headers is not None:
80-
ctx = async_tracer.extract(opentracing.Format.HTTP_HEADERS, dict(msg.headers))
80+
ctx = async_tracer.extract(opentracing.Format.TEXT_MAP, dict(msg.headers))
8181

8282
with async_tracer.start_active_span("rabbitmq", child_of=ctx) as scope:
8383
host, port = msg.sender.protocol.transport._sock.getsockname()

instana/text_propagator.py

Lines changed: 43 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -6,45 +6,66 @@
66
from .log import logger
77
from .util import header_to_id
88

9-
prefix_tracer_state = 'X-INSTANA-'
10-
prefix_baggage = 'X-INSTANA-BAGGAGE-'
11-
field_name_trace_id = prefix_tracer_state + 'T'
12-
field_name_span_id = prefix_tracer_state + 'S'
13-
149

1510
class TextPropagator():
1611
"""
1712
A Propagator for TEXT_MAP.
1813
"""
1914

15+
HEADER_KEY_T = 'X-INSTANA-T'
16+
HEADER_KEY_S = 'X-INSTANA-S'
17+
HEADER_KEY_L = 'X-INSTANA-L'
18+
2019
def inject(self, span_context, carrier):
2120
try:
22-
carrier[field_name_trace_id] = span_context.trace_id
23-
carrier[field_name_span_id] = span_context.span_id
24-
if span_context.baggage is not None:
25-
for k in span_context.baggage:
26-
carrier[prefix_baggage+k] = span_context.baggage[k]
27-
except Exception as e:
28-
logger.debug("inject error: ", str(e))
21+
trace_id = span_context.trace_id
22+
span_id = span_context.span_id
23+
24+
if type(carrier) is dict or hasattr(carrier, "__dict__"):
25+
carrier[self.HEADER_KEY_T] = trace_id
26+
carrier[self.HEADER_KEY_S] = span_id
27+
carrier[self.HEADER_KEY_L] = "1"
28+
elif type(carrier) is list:
29+
carrier.append((self.HEADER_KEY_T, trace_id))
30+
carrier.append((self.HEADER_KEY_S, span_id))
31+
carrier.append((self.HEADER_KEY_L, "1"))
32+
elif hasattr(carrier, '__setitem__'):
33+
carrier.__setitem__(self.HEADER_KEY_T, trace_id)
34+
carrier.__setitem__(self.HEADER_KEY_S, span_id)
35+
carrier.__setitem__(self.HEADER_KEY_L, "1")
36+
else:
37+
raise Exception("Unsupported carrier type", type(carrier))
38+
39+
except:
40+
logger.debug("inject error:", exc_info=True)
2941

3042
def extract(self, carrier): # noqa
43+
trace_id = None
44+
span_id = None
45+
3146
try:
32-
if type(carrier) is dict or hasattr(carrier, "__dict__"):
47+
if type(carrier) is dict or hasattr(carrier, "__getitem__"):
3348
dc = carrier
49+
elif hasattr(carrier, "__dict__"):
50+
dc = carrier.__dict__
3451
elif type(carrier) is list:
3552
dc = dict(carrier)
3653
else:
3754
raise ot.SpanContextCorruptedException()
3855

39-
if field_name_trace_id in dc and field_name_span_id in dc:
40-
trace_id = header_to_id(dc[field_name_trace_id])
41-
span_id = header_to_id(dc[field_name_span_id])
56+
for key in dc.keys():
57+
if self.HEADER_KEY_T == key:
58+
trace_id = header_to_id(dc[key])
59+
elif self.HEADER_KEY_S == key:
60+
span_id = header_to_id(dc[key])
4261

43-
return SpanContext(span_id=span_id,
44-
trace_id=trace_id,
45-
baggage={},
46-
sampled=True)
62+
ctx = None
63+
if trace_id is not None and span_id is not None:
64+
ctx = SpanContext(span_id=span_id,
65+
trace_id=trace_id,
66+
baggage={},
67+
sampled=True)
68+
return ctx
4769

4870
except Exception as e:
49-
logger.debug("extract error: ", str(e))
50-
return SpanContext()
71+
logger.debug("extract error:", exc_info=True)

tests/test_asynqp.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -367,7 +367,7 @@ def handle_message(msg):
367367
# print("")
368368
# print("handle_message active scope: %s" % async_tracer.scope_manager.active)
369369
# print("")
370-
async_tracer.inject(async_tracer.active_span.context, opentracing.Format.HTTP_HEADERS, msg.headers)
370+
async_tracer.inject(async_tracer.active_span.context, opentracing.Format.TEXT_MAP, msg.headers)
371371
asyncio.ensure_future(run_later(msg))
372372
msg.ack()
373373

tests/test_ot_propagators.py

Lines changed: 93 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,12 @@
55
from nose.tools import assert_equals
66

77
import instana.http_propagator as ihp
8+
import instana.text_propagator as itp
89
from instana import options, util
910
from instana.tracer import InstanaTracer
1011

1112

12-
def test_basics():
13+
def test_http_basics():
1314
inspect.isclass(ihp.HTTPPropagator)
1415

1516
inject_func = getattr(ihp.HTTPPropagator, "inject", None)
@@ -21,7 +22,7 @@ def test_basics():
2122
assert callable(extract_func)
2223

2324

24-
def test_inject_with_dict():
25+
def test_http_inject_with_dict():
2526
opts = options.Options()
2627
ot.tracer = InstanaTracer(opts)
2728

@@ -37,7 +38,7 @@ def test_inject_with_dict():
3738
assert_equals(carrier['X-Instana-L'], "1")
3839

3940

40-
def test_inject_with_list():
41+
def test_http_inject_with_list():
4142
opts = options.Options()
4243
ot.tracer = InstanaTracer(opts)
4344

@@ -50,7 +51,7 @@ def test_inject_with_list():
5051
assert ('X-Instana-L', "1") in carrier
5152

5253

53-
def test_basic_extract():
54+
def test_http_basic_extract():
5455
opts = options.Options()
5556
ot.tracer = InstanaTracer(opts)
5657

@@ -62,7 +63,7 @@ def test_basic_extract():
6263
assert_equals('0000000000000001', ctx.span_id)
6364

6465

65-
def test_mixed_case_extract():
66+
def test_http_mixed_case_extract():
6667
opts = options.Options()
6768
ot.tracer = InstanaTracer(opts)
6869

@@ -74,7 +75,7 @@ def test_mixed_case_extract():
7475
assert_equals('0000000000000001', ctx.span_id)
7576

7677

77-
def test_no_context_extract():
78+
def test_http_no_context_extract():
7879
opts = options.Options()
7980
ot.tracer = InstanaTracer(opts)
8081

@@ -84,7 +85,7 @@ def test_no_context_extract():
8485
assert ctx is None
8586

8687

87-
def test_128bit_headers():
88+
def test_http_128bit_headers():
8889
opts = options.Options()
8990
ot.tracer = InstanaTracer(opts)
9091

@@ -96,3 +97,88 @@ def test_128bit_headers():
9697
assert_equals('b0789916ff8f319f', ctx.trace_id)
9798
assert_equals('b0789916ff8f319f', ctx.span_id)
9899

100+
101+
def test_text_basics():
102+
inspect.isclass(itp.TextPropagator)
103+
104+
inject_func = getattr(itp.TextPropagator, "inject", None)
105+
assert inject_func
106+
assert callable(inject_func)
107+
108+
extract_func = getattr(itp.TextPropagator, "extract", None)
109+
assert extract_func
110+
assert callable(extract_func)
111+
112+
113+
def test_text_inject_with_dict():
114+
opts = options.Options()
115+
ot.tracer = InstanaTracer(opts)
116+
117+
carrier = {}
118+
span = ot.tracer.start_span("nosetests")
119+
ot.tracer.inject(span.context, ot.Format.TEXT_MAP, carrier)
120+
121+
assert 'X-INSTANA-T' in carrier
122+
assert_equals(carrier['X-INSTANA-T'], span.context.trace_id)
123+
assert 'X-INSTANA-S' in carrier
124+
assert_equals(carrier['X-INSTANA-S'], span.context.span_id)
125+
assert 'X-INSTANA-L' in carrier
126+
assert_equals(carrier['X-INSTANA-L'], "1")
127+
128+
129+
def test_text_inject_with_list():
130+
opts = options.Options()
131+
ot.tracer = InstanaTracer(opts)
132+
133+
carrier = []
134+
span = ot.tracer.start_span("nosetests")
135+
ot.tracer.inject(span.context, ot.Format.TEXT_MAP, carrier)
136+
137+
assert ('X-INSTANA-T', span.context.trace_id) in carrier
138+
assert ('X-INSTANA-S', span.context.span_id) in carrier
139+
assert ('X-INSTANA-L', "1") in carrier
140+
141+
142+
def test_text_basic_extract():
143+
opts = options.Options()
144+
ot.tracer = InstanaTracer(opts)
145+
146+
carrier = {'X-INSTANA-T': '1', 'X-INSTANA-S': '1', 'X-INSTANA-L': '1'}
147+
ctx = ot.tracer.extract(ot.Format.TEXT_MAP, carrier)
148+
149+
assert type(ctx) is basictracer.context.SpanContext
150+
assert_equals('0000000000000001', ctx.trace_id)
151+
assert_equals('0000000000000001', ctx.span_id)
152+
153+
154+
def test_text_mixed_case_extract():
155+
opts = options.Options()
156+
ot.tracer = InstanaTracer(opts)
157+
158+
carrier = {'x-insTana-T': '1', 'X-inSTANa-S': '1', 'X-INstana-l': '1'}
159+
ctx = ot.tracer.extract(ot.Format.TEXT_MAP, carrier)
160+
161+
assert(ctx is None)
162+
163+
164+
def test_text_no_context_extract():
165+
opts = options.Options()
166+
ot.tracer = InstanaTracer(opts)
167+
168+
carrier = {}
169+
ctx = ot.tracer.extract(ot.Format.TEXT_MAP, carrier)
170+
171+
assert ctx is None
172+
173+
174+
def test_text_128bit_headers():
175+
opts = options.Options()
176+
ot.tracer = InstanaTracer(opts)
177+
178+
carrier = {'X-INSTANA-T': '0000000000000000b0789916ff8f319f',
179+
'X-INSTANA-S': ' 0000000000000000b0789916ff8f319f', 'X-INSTANA-L': '1'}
180+
ctx = ot.tracer.extract(ot.Format.TEXT_MAP, carrier)
181+
182+
assert type(ctx) is basictracer.context.SpanContext
183+
assert_equals('b0789916ff8f319f', ctx.trace_id)
184+
assert_equals('b0789916ff8f319f', ctx.span_id)

0 commit comments

Comments
 (0)