-
Notifications
You must be signed in to change notification settings - Fork 21
/
Copy pathtracer.py
146 lines (120 loc) · 5.17 KB
/
tracer.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
import time
import opentracing
from opentracing import Format, Tracer
from opentracing import UnsupportedFormatException
from opentracing.scope_managers import ThreadLocalScopeManager
from .context import SpanContext
from .recorder import SpanRecorder, DefaultSampler
from .span import BasicSpan
from .util import generate_id
class BasicTracer(Tracer):
def __init__(self, recorder=None, sampler=None, scope_manager=None):
"""Initialize a BasicTracer instance.
Note that the returned BasicTracer has *no* propagators registered. The
user should either call register_propagator() for each needed
inject/extract format and/or the user can simply call
register_required_propagators().
The required formats are opt-in because of protobuf version conflicts
with the binary carrier.
"""
scope_manager = ThreadLocalScopeManager() \
if scope_manager is None else scope_manager
super(BasicTracer, self).__init__(scope_manager)
self.recorder = NoopRecorder() if recorder is None else recorder
self.sampler = DefaultSampler(1) if sampler is None else sampler
self._propagators = {}
def register_propagator(self, format, propagator):
"""Register a propagator with this BasicTracer.
:param string format: a Format identifier like Format.TEXT_MAP
:param Propagator propagator: a Propagator instance to handle
inject/extract calls involving `format`
"""
self._propagators[format] = propagator
def register_required_propagators(self):
from .text_propagator import TextPropagator
from .binary_propagator import BinaryPropagator
self.register_propagator(Format.TEXT_MAP, TextPropagator())
self.register_propagator(Format.HTTP_HEADERS, TextPropagator())
self.register_propagator(Format.BINARY, BinaryPropagator())
def start_active_span(self,
operation_name,
child_of=None,
references=None,
tags=None,
start_time=None,
ignore_active_span=False,
finish_on_close=True):
# create a new Span
span = self.start_span(
operation_name=operation_name,
child_of=child_of,
references=references,
tags=tags,
start_time=start_time,
ignore_active_span=ignore_active_span,
)
return self.scope_manager.activate(span, finish_on_close)
def start_span(self,
operation_name=None,
child_of=None,
references=None,
tags=None,
start_time=None,
ignore_active_span=False):
if isinstance(references, opentracing.Reference):
references = [references]
start_time = time.time() if start_time is None else start_time
# See if we have a parent_ctx in `references`
parent_ctx = None
if child_of is not None:
parent_ctx = (
child_of if isinstance(child_of, opentracing.SpanContext)
else child_of.context)
elif references is not None and len(references) > 0:
# TODO only the first reference is currently used
first_ref = references[0]
if not isinstance(first_ref, opentracing.Reference):
msg = (
'references[0] should be a opentracing.Reference '
'objects, got %r instead'
)
raise TypeError(msg % first_ref)
parent_ctx = first_ref.referenced_context
# retrieve the active SpanContext
if not ignore_active_span and parent_ctx is None:
scope = self.scope_manager.active
if scope is not None:
parent_ctx = scope.span.context
# Assemble the child ctx
ctx = SpanContext(span_id=generate_id())
if parent_ctx is not None:
if parent_ctx._baggage is not None:
ctx._baggage = parent_ctx._baggage.copy()
ctx.trace_id = parent_ctx.trace_id
ctx.sampled = parent_ctx.sampled
else:
ctx.trace_id = generate_id()
ctx.sampled = self.sampler.sampled(ctx.trace_id)
# Tie it all together
return BasicSpan(
self,
operation_name=operation_name,
context=ctx,
parent_id=(None if parent_ctx is None else parent_ctx.span_id),
tags=tags,
start_time=start_time)
def inject(self, span_context, format, carrier):
if format in self._propagators:
self._propagators[format].inject(span_context, carrier)
else:
raise UnsupportedFormatException()
def extract(self, format, carrier):
if format in self._propagators:
return self._propagators[format].extract(carrier)
else:
raise UnsupportedFormatException()
def record(self, span):
self.recorder.record_span(span)
class NoopRecorder(SpanRecorder):
def record_span(self, span):
pass