forked from instana/python-sensor
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtracer.py
121 lines (98 loc) · 3.41 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
from __future__ import absolute_import
import time
import opentracing as ot
from basictracer import BasicTracer
from basictracer.context import SpanContext
from . import sensor
from . import options as o
from . import recorder as r
from .http_propagator import HTTPPropagator
from .span import InstanaSpan
from .text_propagator import TextPropagator
from .util import generate_id
class InstanaTracer(BasicTracer):
sensor = None
cur_ctx = None
def __init__(self, options=o.Options()):
self.sensor = sensor.get_sensor()
super(InstanaTracer, self).__init__(
r.InstanaRecorder(self.sensor), r.InstanaSampler())
self._propagators[ot.Format.HTTP_HEADERS] = HTTPPropagator()
self._propagators[ot.Format.TEXT_MAP] = TextPropagator()
def start_span(
self,
operation_name=None,
child_of=None,
references=None,
tags=None,
start_time=None):
"Taken from BasicTracer so we can override generate_id calls to ours"
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, ot.SpanContext)
else child_of.context)
elif references is not None and len(references) > 0:
# TODO only the first reference is currently used
parent_ctx = references[0].referenced_context
# Assemble the child ctx
instana_id = generate_id()
ctx = SpanContext(span_id=instana_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 = instana_id
ctx.sampled = self.sampler.sampled(ctx.trace_id)
# Tie it all together
span = InstanaSpan(
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)
self.cur_ctx = span.context
return span
def current_context(self):
context = None
if self.cur_ctx is not None:
context = self.cur_ctx
return context
def inject(self, span_context, format, carrier):
if format in self._propagators:
self._propagators[format].inject(span_context, carrier)
else:
raise ot.UnsupportedFormatException()
def extract(self, format, carrier):
if format in self._propagators:
return self._propagators[format].extract(carrier)
else:
raise ot.UnsupportedFormatException()
def handle_fork(self):
self.sensor.handle_fork()
self.recorder = r.InstanaRecorder(self.sensor)
def init(options):
"""
Deprecated.
No longer in use.
To be removed in next major release.
"""
return internal_tracer
def get_tracer():
return internal_tracer
# The global OpenTracing compatible tracer used internally by
# this package.
#
# Usage example:
#
# import instana
# instana.internal_tracer.start_span(...)
#
internal_tracer = InstanaTracer()
# Set ourselves as the tracer.
ot.tracer = internal_tracer