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
|
from collections import defaultdict
import enum
import opentracing
@enum.unique
class SpanRelationship(enum.Enum):
NONE = 0
FOLLOWS_FROM = 1
CHILD_OF = 2
class _SpanContext(opentracing.SpanContext):
def __init__(self, identity):
self.identity = identity
class _Span(opentracing.Span):
def __init__(self, tracer, identity, tags=None):
super(_Span, self).__init__(tracer, _SpanContext(identity))
self._identity = identity
if tags is None:
tags = {}
self._tags = tags
def set_tag(self, key, value):
self._tags[key] = value
def get_tag(self, key):
return self._tags.get(key, None)
class Tracer(opentracing.Tracer):
def __init__(self):
super(Tracer, self).__init__()
self._counter = 0
self._spans = {}
self._relationships = defaultdict(lambda: None)
def start_span(self,
operation_name=None,
child_of=None,
references=None,
tags=None,
start_time=None):
identity = self._counter
self._counter += 1
if child_of is not None:
self._relationships[(child_of.identity,
identity)] = opentracing.ReferenceType.CHILD_OF
if references is not None:
assert child_of is None and len(
references) == 1, 'Only a single reference is supported'
reference_type, span_context = references[0]
self._relationships[(span_context.identity,
identity)] = reference_type
span = _Span(self, identity, tags)
self._spans[identity] = span
return span
def inject(self, span_context, format, carrier):
if format != opentracing.Format.HTTP_HEADERS and isinstance(carrier,
dict):
raise opentracing.UnsupportedFormatException(format)
carrier['span-identity'] = str(span_context.identity)
def extract(self, format, carrier):
if format != opentracing.Format.HTTP_HEADERS and isinstance(carrier,
dict):
raise opentracing.UnsupportedFormatException(format)
if 'span-identity' not in carrier:
raise opentracing.SpanContextCorruptedException
return _SpanContext(int(carrier['span-identity']))
def get_relationship(self, identity1, identity2):
return self._relationships[(identity1, identity2)]
def get_span(self, identity):
return self._spans.get(identity, None)
|