w3c.py (2747B)
1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\packages\beeline\propagation\w3c.py 2 import beeline 3 from beeline.propagation import PropagationContext 4 import re 5 _TRACEPARENT_HEADER_FORMAT = '^[ \t]*([0-9a-f]{2})-([0-9a-f]{32})-([0-9a-f]{16})-([0-9a-f]{2})' + '(-.*)?[ \t]*$' 6 _TRACEPARENT_HEADER_FORMAT_RE = re.compile(_TRACEPARENT_HEADER_FORMAT) 7 _EMPTY_TRACE_ID = '0' * 32 8 _EMPTY_PARENT_ID = '0000000000000000' 9 10 def http_trace_parser_hook(request): 11 traceparent_header = request.header('traceparent') 12 if not traceparent_header: 13 return 14 tracestate_header = request.header('tracestate') 15 trace_id = None 16 parent_id = None 17 try: 18 trace_id, parent_id, trace_flags = unmarshal_traceparent(traceparent_header) 19 tracestate = unmarshal_tracestate(tracestate_header) 20 trace_fields = {} 21 trace_fields['traceflags'] = trace_flags 22 trace_fields['tracestate'] = tracestate 23 return PropagationContext(trace_id, parent_id, trace_fields) 24 except Exception as e: 25 beeline.internal.log('error attempting to extract w3c trace: %s', beeline.internal.stringify_exception(e)) 26 27 28 def http_trace_propagation_hook(propagation_context): 29 if not propagation_context: 30 return None 31 traceparent_header = marshal_traceparent(propagation_context) 32 if not traceparent_header: 33 return {} 34 headers = {} 35 headers['traceparent'] = traceparent_header 36 tracestate_header = marshal_tracestate(propagation_context) 37 if tracestate_header: 38 headers['tracestate'] = tracestate_header 39 return headers 40 41 42 def marshal_traceparent(propagation_context): 43 if not propagation_context: 44 return None 45 trace_flags = propagation_context.trace_fields.get('traceflags') 46 if not trace_flags: 47 trace_flags = '01' 48 traceparent_header = '00-{}-{}-{}'.format(propagation_context.trace_id, propagation_context.parent_id, trace_flags) 49 return traceparent_header 50 51 52 def marshal_tracestate(propagation_context): 53 if not propagation_context: 54 return None 55 tracestate_header = propagation_context.trace_fields.get('tracestate') 56 return tracestate_header 57 58 59 def unmarshal_traceparent(header): 60 match = re.search(_TRACEPARENT_HEADER_FORMAT_RE, header) 61 if not match: 62 return None 63 version = match.group(1) 64 trace_id = match.group(2) 65 parent_id = match.group(3) 66 trace_flags = match.group(4) 67 if trace_id == _EMPTY_TRACE_ID or parent_id == _EMPTY_PARENT_ID: 68 return None 69 if version == '00': 70 if match.group(5): 71 return None 72 if version == 'ff': 73 return None 74 return (trace_id, parent_id, trace_flags) 75 76 77 def unmarshal_tracestate(header): 78 return header