|
- import random
-
- from eventlet import wsgi
- from eventlet.zipkin import api
- from eventlet.zipkin._thrift.zipkinCore.constants import \
- SERVER_RECV, SERVER_SEND
- from eventlet.zipkin.http import \
- HDR_TRACE_ID, HDR_SPAN_ID, HDR_PARENT_SPAN_ID, HDR_SAMPLED
-
-
- _sampler = None
- __original_handle_one_response__ = wsgi.HttpProtocol.handle_one_response
-
-
- def _patched_handle_one_response(self):
- api.init_trace_data()
- trace_id = int_or_none(self.headers.getheader(HDR_TRACE_ID))
- span_id = int_or_none(self.headers.getheader(HDR_SPAN_ID))
- parent_id = int_or_none(self.headers.getheader(HDR_PARENT_SPAN_ID))
- sampled = bool_or_none(self.headers.getheader(HDR_SAMPLED))
- if trace_id is None: # front-end server
- trace_id = span_id = api.generate_trace_id()
- parent_id = None
- sampled = _sampler.sampling()
- ip, port = self.request.getsockname()[:2]
- ep = api.ZipkinDataBuilder.build_endpoint(ip, port)
- trace_data = api.TraceData(name=self.command,
- trace_id=trace_id,
- span_id=span_id,
- parent_id=parent_id,
- sampled=sampled,
- endpoint=ep)
- api.set_trace_data(trace_data)
- api.put_annotation(SERVER_RECV)
- api.put_key_value('http.uri', self.path)
-
- __original_handle_one_response__(self)
-
- if api.is_sample():
- api.put_annotation(SERVER_SEND)
-
-
- class Sampler(object):
- def __init__(self, sampling_rate):
- self.sampling_rate = sampling_rate
-
- def sampling(self):
- # avoid generating unneeded random numbers
- if self.sampling_rate == 1.0:
- return True
- r = random.random()
- if r < self.sampling_rate:
- return True
- return False
-
-
- def int_or_none(val):
- if val is None:
- return None
- return int(val, 16)
-
-
- def bool_or_none(val):
- if val == '1':
- return True
- if val == '0':
- return False
- return None
-
-
- def patch(sampling_rate):
- global _sampler
- _sampler = Sampler(sampling_rate)
- wsgi.HttpProtocol.handle_one_response = _patched_handle_one_response
-
-
- def unpatch():
- wsgi.HttpProtocol.handle_one_response = __original_handle_one_response__
|