def test_sampler_effects(tracer): tracer.sampler = ConstSampler(True) span = tracer.start_span("test") assert span.is_sampled(), "Must be sampled" tracer.sampler = ConstSampler(False) span = tracer.start_span("test") assert not span.is_sampled(), "Must not be sampled" tracer.close()
def test_context_from_readable_headers(self): # provide headers all the way through Config object config = Config(service_name='test', config={ 'trace_id_header': 'Trace_ID', 'baggage_header_prefix': 'Trace-Attr-', }) tracer = config.create_tracer( reporter=InMemoryReporter(), sampler=ConstSampler(True), ) for url_encoding in [False, True]: if url_encoding: codec = tracer.codecs[Format.HTTP_HEADERS] headers = { 'Trace-ID': '100%3A7f:0:1', 'trace-attr-Kiff': 'Amy%20Wang', 'trace-atTR-HERMES': 'LaBarbara%20Hermes' } else: codec = tracer.codecs[Format.HTTP_HEADERS] headers = { 'Trace-ID': '100:7f:0:1', 'trace-attr-Kiff': 'Amy Wang', 'trace-atTR-HERMES': 'LaBarbara Hermes' } ctx = codec.extract(headers) assert ctx.trace_id == 256 assert ctx.span_id == 127 assert ctx.parent_id is None assert ctx.flags == 1 assert ctx.baggage == { 'kiff': 'Amy Wang', 'hermes': 'LaBarbara Hermes', }
def test_baggage_as_unicode_strings_with_httplib(httpserver): if six.PY2: import urllib2 urllib_under_test = urllib2 else: import urllib.request urllib_under_test = urllib.request # httpserver is provided by pytest-localserver httpserver.serve_content(content='Hello', code=200, headers=None) tracer = Tracer( service_name='test', reporter=InMemoryReporter(), # don't sample to avoid logging baggage to the span sampler=ConstSampler(False), ) tracer.codecs[Format.TEXT_MAP] = TextCodec(url_encoding=True) baggage = [(b'key1', b'value'), (u'key2', b'value'), ('key3', u'value'), (b'key4', bytes(chr(255)) if six.PY2 else bytes([255])), (u'key5', u'\U0001F47E')] for b in baggage: span = tracer.start_span('test') span.set_baggage_item(b[0], b[1]) headers = {} tracer.inject(span_context=span.context, format=Format.TEXT_MAP, carrier=headers) # make sure httplib doesn't blow up request = urllib_under_test.Request(httpserver.url, None, headers) response = urllib_under_test.urlopen(request) assert response.read() == b'Hello' response.close()
def test_child_span(tracer): span = tracer.start_span("test") child = tracer.start_span("child", references=child_of(span.context)) child.set_tag(ext_tags.SPAN_KIND, ext_tags.SPAN_KIND_RPC_CLIENT) child.set_tag('bender', 'is great') child.log_event('kiss-my-shiny-metal-...') child.finish() span.finish() tracer.reporter.report_span.assert_called_once() assert len(span.logs) == 0, 'Parent span is Local, must not have events' assert len(child.logs) == 1, 'Child must have one events' add_zipkin_annotations(span=span, endpoint=None) add_zipkin_annotations(span=child, endpoint=None) assert len([t for t in span.tags if t.key == g.LOCAL_COMPONENT]) == 1 assert len(child.logs) == 3, 'Child must have three events' assert log_exists(child, g.CLIENT_SEND), 'Must have cs event' assert log_exists(child, g.CLIENT_RECV), 'Must have cr event' tracer.sampler = ConstSampler(False) span = tracer.start_span("test") child = tracer.start_span("child", references=child_of(span.context)) child.set_tag('bender', 'is great') child.log_event('kiss-my-shiny-metal-...') child.finish() span.finish() assert len(child.logs) == 0, "Must have no events, not sampled" assert len(child.tags) == 0, "Must have no attributes, not sampled" tracer.close()
def test_tracer_tags_hostname(): reporter = mock.MagicMock() sampler = ConstSampler(True) with mock.patch('socket.gethostname', return_value='dream-host.com'): t = Tracer(service_name='x', reporter=reporter, sampler=sampler) assert t.tags.get(c.JAEGER_HOSTNAME_TAG_KEY) == 'dream-host.com'
def test_tracer_tags_on_root_span(span_type, expected_tags): reporter = mock.MagicMock() sampler = ConstSampler(True) with mock.patch('socket.gethostname', return_value='dream-host.com'): tracer = Tracer(service_name='x', reporter=reporter, sampler=sampler, tags={'global-tag': 'global-tag'}) span = tracer.start_span(operation_name='root') if span_type == 'child': span = tracer.start_span('child', child_of=span) if span_type == 'rpc-server': span = tracer.start_span( 'child', child_of=span.context, tags={ext_tags.SPAN_KIND: ext_tags.SPAN_KIND_RPC_SERVER}) for key, value in six.iteritems(expected_tags): found_tag = None for tag in span.tags: if tag.key == key: found_tag = tag if value is None: assert found_tag is None, 'test (%s)' % span_type continue assert found_tag is not None, 'test (%s): expecting tag %s' % ( span_type, key) assert found_tag.value == value, \ 'test (%s): expecting tag %s=%s' % (span_type, key, value)
def test_non_ascii_baggage_with_httplib(httpserver): # httpserver is provided by pytest-localserver httpserver.serve_content(content='Hello', code=200, headers=None) tracer = Tracer( service_name='test', reporter=InMemoryReporter(), # don't sample to avoid logging baggage to the span sampler=ConstSampler(False), ) tracer.codecs[Format.TEXT_MAP] = TextCodec(url_encoding=True) baggage = [ (b'key', b'value'), (u'key', b'value'), (b'key', bytes(chr(255))), (u'caf\xe9', 'caf\xc3\xa9'), ('caf\xc3\xa9', 'value'), ] for b in baggage: span = tracer.start_span('test') span.set_baggage_item(b[0], b[1]) headers = {} tracer.inject(span_context=span.context, format=Format.TEXT_MAP, carrier=headers) # make sure httplib doesn't blow up request = urllib2.Request(httpserver.url, None, headers) response = urllib2.urlopen(request) assert response.read() == 'Hello' response.close()
def test_tracer_tags(): reporter = mock.MagicMock() sampler = ConstSampler(True) with mock.patch('socket.gethostname', return_value='dream-host.com'): t = Tracer(service_name='x', reporter=reporter, sampler=sampler) assert t.tags.get('hostname') == 'dream-host.com' assert 'ip' in t.tags assert 'jaeger.version' in t.tags
def tracer(): tracer = Tracer(service_name='test-tracer', sampler=ConstSampler(True), reporter=InMemoryReporter(), scope_manager=scope_manager() if scope_manager else None) try: yield tracer finally: tracer.close()
def test_sampling_priority(tracer): tracer.sampler = ConstSampler(False) span = tracer.start_span(operation_name='x') assert span.is_sampled() is False span.set_tag(ext_tags.SAMPLING_PRIORITY, 1) assert span.is_sampled() assert span.is_debug() span.set_tag(ext_tags.SAMPLING_PRIORITY, 0) assert span.is_sampled() is False
def test_max_tag_value_length(self): c = Config({}, service_name='x') assert c.max_tag_value_length == constants.MAX_TAG_VALUE_LENGTH c = Config({'max_tag_value_length': 333}, service_name='x') assert c.max_tag_value_length == 333 t = c.create_tracer(NullReporter(), ConstSampler(True)) assert t.max_tag_value_length == 333
def test_tracer_tags_no_hostname(): reporter = mock.MagicMock() sampler = ConstSampler(True) from jaeger_client.tracer import logger with mock.patch.object(logger, 'exception') as mock_log: with mock.patch('socket.gethostname', side_effect=['host', ValueError()]): Tracer(service_name='x', reporter=reporter, sampler=sampler) assert mock_log.call_count == 1
def tracer(): tracer = Tracer( service_name='test-tracer', sampler=ConstSampler(True), reporter=InMemoryReporter(), ) try: yield tracer finally: tracer.close()
def test_tracer_tags_passed_to_reporter(): reporter = mock.MagicMock() reporter.set_process = mock.MagicMock() sampler = ConstSampler(True) tracer = Tracer( service_name='x', reporter=reporter, sampler=sampler, max_tag_value_length=123, ) reporter.set_process.assert_called_once_with( service_name='x', tags=tracer.tags, max_length=123, )
def test_tracer_ip_tag(): reporter = mock.MagicMock() sampler = ConstSampler(True) tracer = Tracer( service_name='x', tags={c.JAEGER_IP_TAG_KEY: '192.0.2.3'}, reporter=reporter, sampler=sampler, ) assert tracer.tags[c.JAEGER_IP_TAG_KEY] == '192.0.2.3'
def test_tracer_hostname_tag(): reporter = mock.MagicMock() sampler = ConstSampler(True) tracer = Tracer( service_name='x', tags={c.JAEGER_HOSTNAME_TAG_KEY: 'jaeger-client-app.local'}, reporter=reporter, sampler=sampler, ) assert tracer.tags[c.JAEGER_HOSTNAME_TAG_KEY] == 'jaeger-client-app.local'
def tracer(): tracer = Tracer(service_name='test-tracer', sampler=ConstSampler(True), reporter=InMemoryReporter(), scope_manager=TornadoScopeManager()) opentracing.set_global_tracer(tracer) try: yield tracer finally: opentracing._reset_global_tracer() tracer.close()
def test_round_trip(tracer, fmt, carrier): tracer_128bit = Tracer(service_name='test', reporter=InMemoryReporter(), sampler=ConstSampler(True), generate_128bit_trace_id=True) for tracer1, tracer2 in product([tracer, tracer_128bit], repeat=2): span = tracer1.start_span('test-%s' % fmt) tracer1.inject(span, fmt, carrier) context = tracer2.extract(fmt, carrier) span2 = tracer2.start_span('test-%s' % fmt, child_of=context) assert span.trace_id == span2.trace_id
def test_span_finish(tracer): tracer.sampler = ConstSampler(decision=True) span = tracer.start_span(operation_name='x') assert span.is_sampled() finish_time = time.time() span.finish(finish_time) assert span.finished is True # test double finish warning span.finish(finish_time + 10) assert span.end_time == finish_time
def init(): config = Config(service_name='test', config={ 'trace_id_header': 'Trace_ID', 'baggage_header_prefix': 'Trace-Attr-', }) reporter = InMemoryReporter() tracer = config.create_tracer( reporter=reporter, sampler=ConstSampler(True), ) tracing = FlaskTracing(tracer, True, app)
class APITest(unittest.TestCase, APICompatibilityCheckMixin): reporter = NullReporter() sampler = ConstSampler(True) _tracer = Tracer(service_name='test_service_1', reporter=reporter, sampler=sampler) def tracer(self): return APITest._tracer def test_binary_propagation(self): # TODO binary codecs are not implemented at the moment pass
def sampler(self): sampler_config = self.config.get('sampler', {}) sampler_type = sampler_config.get('type', None) sampler_param = sampler_config.get('param', None) if not sampler_type: return None elif sampler_type == SAMPLER_TYPE_CONST: return ConstSampler(decision=get_boolean(sampler_param, False)) elif sampler_type == SAMPLER_TYPE_PROBABILISTIC: return ProbabilisticSampler(rate=float(sampler_param)) elif sampler_type in [SAMPLER_TYPE_RATE_LIMITING, 'rate_limiting']: return RateLimitingSampler( max_traces_per_second=float(sampler_param)) raise ValueError('Unknown sampler type %s' % sampler_type)
def test_tracer_override_codecs(): reporter = mock.MagicMock() sampler = ConstSampler(True) codecs = { 'extra_codec': "codec_placeholder", Format.BINARY: "overridden_binary_codec" } with mock.patch('socket.gethostname', return_value='dream-host.com'): tracer = Tracer(service_name='x', reporter=reporter, sampler=sampler, extra_codecs=codecs) assert tracer.codecs['extra_codec'] == "codec_placeholder",\ "Extra codec not found" assert tracer.codecs[Format.BINARY] == "overridden_binary_codec",\ "Binary format codec not overridden"
def _init_tracer(self): service_name = '' try: value = getattr(settings, 'SERVICE_CONF', '') if value: service_name = value.get('NAME', '') except Exception as e: logger.error('SERVICE_CONF:NAME is not set in settings. {}'.format(str(e))) # create a global tracer first tracer = Tracer( one_span_per_rpc=True, service_name=service_name, reporter=NullReporter(), sampler=ConstSampler(decision=True), extra_codecs={Format.HTTP_HEADERS: B3Codec()} ) opentracing.set_global_tracer(tracer)
def tracer(): reporter = InMemoryReporter() report_func = reporter.report_span def log_and_report(span): print 'Reporting span %s' % span report_func(span) reporter.report_span = log_and_report tracer = Tracer( service_name='test-tracer', sampler=ConstSampler(True), reporter=reporter, ) try: yield tracer finally: tracer.close()
def serve(): """main entry point""" logging.getLogger().setLevel(logging.DEBUG) logging.info('Python Tornado Crossdock Server Starting ...') tracer = Tracer(service_name='python', reporter=NullReporter(), sampler=ConstSampler(decision=True)) opentracing.tracer = tracer tchannel = TChannel(name='python', hostport=':%d' % DEFAULT_SERVER_PORT, trace=True) register_tchannel_handlers(tchannel=tchannel) tchannel.listen() app = tornado.web.Application(debug=True) register_http_handlers(app) app.listen(DEFAULT_CLIENT_PORT) tornado.ioloop.IOLoop.current().start()
def test_non_ascii_baggage_with_httplib(httpserver): # TODO this test requires `futurize`. Unfortunately, that also changes # how the test works under Py2. # Some observation: # - In Py2, the httplib does not like unicode strings, maybe we need to convert everything to bytes. # - Not sure yet what's the story with httplib in Py3, it seems not to like raw bytes. if six.PY3: raise ValueError('this test does not work with Py3') # httpserver is provided by pytest-localserver httpserver.serve_content(content='Hello', code=200, headers=None) tracer = Tracer( service_name='test', reporter=InMemoryReporter(), # don't sample to avoid logging baggage to the span sampler=ConstSampler(False), ) tracer.codecs[Format.TEXT_MAP] = TextCodec(url_encoding=True) baggage = [ (b'key', b'value'), (u'key', b'value'), (b'key', byte255), (u'caf\xe9', 'caf\xc3\xa9'), ('caf\xc3\xa9', 'value'), ] for b in baggage: span = tracer.start_span('test') span.set_baggage_item(b[0], b[1]) headers = {} tracer.inject(span_context=span.context, format=Format.TEXT_MAP, carrier=headers) # make sure httplib doesn't blow up import urllib2 request = urllib2.Request(httpserver.url, None, headers) response = urllib2.urlopen(request) assert response.read() == b'Hello' response.close()
def initialize_tracer(self, transport_handler=None, io_loop=None): # pragma: nocover """ Initialize Jaeger Tracer based on the passed `jaeger_client.Config`. Save it to `opentracing.tracer` global variable. Only the first call to this method has any effect. """ with Config._initialized_lock: if Config._initialized: logger.warn('Jaeger tracer already initialized, skipping') return opentracing.tracer sampler = self.sampler if sampler is None: sampler = ConstSampler(True) logger.info('Using sampler %s', sampler) reporter = ZipkinReporter( transport_handler=transport_handler, io_loop=io_loop, queue_capacity=self.reporter_queue_size, batch_size=self.reporter_batch_size, flush_interval=self.reporter_flush_interval, logger=logger, metrics_factory=self._metrics_factory, error_reporter=self.error_reporter) if self.logging: reporter = CompositeReporter(reporter, LoggingReporter(logger)) tracer = self.create_tracer( reporter=reporter, sampler=sampler, ) self._initialize_global_tracer(tracer=tracer) Config._initialized = True return tracer
def test_child_span(tracer): span = tracer.start_span("test") child = tracer.start_span("child", references=child_of(span.context)) child.set_tag(ext_tags.SPAN_KIND, ext_tags.SPAN_KIND_RPC_CLIENT) child.set_tag('bender', 'is great') child.log_event('kiss-my-shiny-metal-...') child.finish() span.finish() tracer.reporter.report_span.assert_called_once() assert len(span.logs) == 0, 'Parent span is Local, must not have events' assert len(child.logs) == 1, 'Child must have one events' tracer.sampler = ConstSampler(False) span = tracer.start_span("test") child = tracer.start_span("child", references=child_of(span.context)) child.set_tag('bender', 'is great') child.log_event('kiss-my-shiny-metal-...') child.finish() span.finish() assert len(child.logs) == 0, "Must have no events, not sampled" assert len(child.tags) == 0, "Must have no attributes, not sampled" tracer.close()
def test_debug_id(): debug_header = 'correlation-id' tracer = Tracer( service_name='test', reporter=InMemoryReporter(), sampler=ConstSampler(True), debug_id_header=debug_header, ) tracer.codecs[Format.TEXT_MAP] = TextCodec( url_encoding=False, debug_id_header=debug_header, ) carrier = {debug_header: 'Coraline'} context = tracer.extract(Format.TEXT_MAP, carrier) assert context.is_debug_id_container_only assert context.debug_id == 'Coraline' span = tracer.start_span('test', child_of=context) assert span.is_debug() assert span.is_sampled() tags = [t for t in span.tags if t.key == debug_header] assert len(tags) == 1 assert tags[0].vStr == 'Coraline'