@@ -27,6 +27,7 @@ class B3Format(HTTPTextFormat):
27
27
SINGLE_HEADER_KEY = "b3"
28
28
TRACE_ID_KEY = "x-b3-traceid"
29
29
SPAN_ID_KEY = "x-b3-spanid"
30
+ PARENT_SPAN_ID_KEY = "x-b3-parentspanid"
30
31
SAMPLED_KEY = "x-b3-sampled"
31
32
FLAGS_KEY = "x-b3-flags"
32
33
_SAMPLE_PROPAGATE_VALUES = set (["1" , "True" , "true" , "d" ])
@@ -35,6 +36,7 @@ class B3Format(HTTPTextFormat):
35
36
def extract (cls , get_from_carrier , carrier ):
36
37
trace_id = format_trace_id (trace .INVALID_TRACE_ID )
37
38
span_id = format_span_id (trace .INVALID_SPAN_ID )
39
+ parent_span_id = format_span_id (trace .INVALID_SPAN_ID )
38
40
sampled = "0"
39
41
flags = None
40
42
@@ -55,7 +57,7 @@ def extract(cls, get_from_carrier, carrier):
55
57
elif len (fields ) == 3 :
56
58
trace_id , span_id , sampled = fields
57
59
elif len (fields ) == 4 :
58
- trace_id , span_id , sampled , _parent_span_id = fields
60
+ trace_id , span_id , sampled , parent_span_id = fields
59
61
else :
60
62
return trace .INVALID_SPAN_CONTEXT
61
63
else :
@@ -71,6 +73,12 @@ def extract(cls, get_from_carrier, carrier):
71
73
)
72
74
or span_id
73
75
)
76
+ parent_span_id = (
77
+ _extract_first_element (
78
+ get_from_carrier (carrier , cls .PARENT_SPAN_ID_KEY )
79
+ )
80
+ or parent_span_id
81
+ )
74
82
sampled = (
75
83
_extract_first_element (
76
84
get_from_carrier (carrier , cls .SAMPLED_KEY )
@@ -91,12 +99,22 @@ def extract(cls, get_from_carrier, carrier):
91
99
# header is set to allow.
92
100
if sampled in cls ._SAMPLE_PROPAGATE_VALUES or flags == "1" :
93
101
options |= trace .TraceOptions .SAMPLED
102
+
103
+ trace_state = trace .TraceState ()
104
+
105
+ if parent_span_id != trace .INVALID_SPAN_ID :
106
+ # FIXME This is a workaround for the error specified below being
107
+ # raised because of a pylint issue. Remove this when the issue is
108
+ # fixed in pylint.
109
+ # pylint: disable=E1137
110
+ trace_state [cls .PARENT_SPAN_ID_KEY ] = int (parent_span_id , 16 )
111
+
94
112
return trace .SpanContext (
95
113
# trace an span ids are encoded in hex, so must be converted
96
114
trace_id = int (trace_id , 16 ),
97
115
span_id = int (span_id , 16 ),
98
116
trace_options = trace .TraceOptions (options ),
99
- trace_state = trace . TraceState () ,
117
+ trace_state = trace_state ,
100
118
)
101
119
102
120
@classmethod
@@ -108,6 +126,11 @@ def inject(cls, context, set_in_carrier, carrier):
108
126
set_in_carrier (
109
127
carrier , cls .SPAN_ID_KEY , format_span_id (context .span_id )
110
128
)
129
+ set_in_carrier (
130
+ carrier ,
131
+ cls .PARENT_SPAN_ID_KEY ,
132
+ format_span_id (context .trace_state [cls .PARENT_SPAN_ID_KEY ]),
133
+ )
111
134
set_in_carrier (carrier , cls .SAMPLED_KEY , "1" if sampled else "0" )
112
135
113
136
0 commit comments