Пример #1
0
def tracer():
    tracer = Tracer(
        service_name='test-tracer',
        sampler=ConstSampler(True),
        reporter=InMemoryReporter(),
    )
    try:
        yield tracer
    finally:
        tracer.close()
Пример #2
0
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
Пример #3
0
def test_default_tracer():
    class Sender(object):
        def __init__(self):
            self._channel = mock.MagicMock()
            self.io_loop = mock.MagicMock()

    channel = Sender()
    sampler = ConstSampler(False)
    tracer = Tracer.default_tracer(channel=channel, service_name='service')
    assert tracer.reporter._channel == channel

    reporter = 'reporter'
    tracer = Tracer.default_tracer(channel=channel, service_name='service',
                                   reporter=reporter)
    assert tracer.reporter == reporter

    tracer = Tracer.default_tracer(channel=channel, service_name='service',
                                   sampler=sampler)
    assert tracer.sampler == sampler
Пример #4
0
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 build_started_scope(tracer: Tracer, parent_span: SpanContext, verb: str, message: any,
                            span_setup: 'Callable[[Span, any], None]') -> None:
        message_type = type(message).__name__
        scope = tracer.start_active_span(f'{verb} {message_type}', child_of=parent_span)
        scope.span.set_tag('proto.messagetype', message_type)

        if span_setup is not None:
            span_setup(scope.span, message)

        return scope
Пример #6
0
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()
Пример #7
0
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
Пример #8
0
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'
Пример #9
0
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,
    )
Пример #10
0
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'
Пример #11
0
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
Пример #12
0
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()
Пример #13
0
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'
Пример #14
0
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()
Пример #15
0
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'
Пример #16
0
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
Пример #17
0
def tracer():
    reporter = InMemoryReporter()
    report_func = reporter.report_span

    def log_and_report(span):
        print(('Reporting span %s' % span))
        print(('Span type %s' % type(span)))
        print(('SpanContext type %s' % type(span.context)))
        report_func(span)

    reporter.report_span = log_and_report

    tracer = Tracer(
        service_name='test-tracer',
        sampler=ConstSampler(True),
        reporter=reporter,
        scope_manager=TornadoScopeManager()
    )
    opentracing.set_global_tracer(tracer)
    try:
        yield tracer
    finally:
        opentracing._reset_global_tracer()
        tracer.close()
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 = find_tag(span, key, type(value).__name__)
            if value is None:
                assert found_tag is None, 'test (%s)' % span_type
                continue

            assert found_tag == value, \
                'test (%s): expecting tag %s=%s' % (span_type, key, value)
Пример #19
0
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"
Пример #20
0
 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 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()
Пример #22
0
def test_inject_with_128bit_trace_id(tracer, fmt, carrier, get_trace_id):
    tracer_128bit = Tracer(service_name='test',
                           reporter=InMemoryReporter(),
                           sampler=ConstSampler(True),
                           generate_128bit_trace_id=True)

    for tracer in [tracer, tracer_128bit]:
        length = tracer.max_trace_id_bits / 4
        trace_id = (1 << 64) - 1 if length == 16 else (1 << 128) - 1
        ctx = SpanContext(trace_id=trace_id,
                          span_id=127,
                          parent_id=None,
                          flags=1)
        span = Span(ctx,
                    operation_name='test-%s' % fmt,
                    tracer=None,
                    start_time=1)
        tracer.inject(span, fmt, carrier)
        assert len(get_trace_id(carrier)) == length

        # test if the trace_id arrived on wire remains same even if
        # the tracer is configured for 64bit ids or 128bit ids
        ctx = SpanContext(trace_id=(1 << 128) - 1,
                          span_id=127,
                          parent_id=None,
                          flags=0)
        span = tracer.start_span('test-%s' % fmt, child_of=ctx)
        carrier = dict()
        tracer.inject(span, fmt, carrier)
        assert len(get_trace_id(carrier)) == 32

        ctx = SpanContext(trace_id=(1 << 64) - 1,
                          span_id=127,
                          parent_id=None,
                          flags=0)
        span = tracer.start_span('test-%s' % fmt, child_of=ctx)
        carrier = dict()
        tracer.inject(span, fmt, carrier)
        assert len(get_trace_id(carrier)) == 16
Пример #23
0
def tracer():
    reporter = mock.MagicMock()
    sampler = ConstSampler(True)
    return Tracer(service_name='test_service_1',
                  reporter=reporter,
                  sampler=sampler)
Пример #24
0
# x-b3-flags
#
# This example code uses OpenTracing (http://opentracing.io/) to propagate
# the 'b3' (zipkin) headers. Using OpenTracing for this is not a requirement.
# Using OpenTracing allows you to add application-specific tracing later on,
# but you can just manually forward the headers if you prefer.
#
# The OpenTracing example here is very basic. It only forwards headers. It is
# intended as a reference to help people get started, eg how to create spans,
# extract/inject context, etc.

# A very basic OpenTracing tracer (with null reporter)
tracer = Tracer(
    one_span_per_rpc=True,
    service_name='productpage',
    reporter=NullReporter(),
    sampler=ConstSampler(decision=True),
    extra_codecs={Format.HTTP_HEADERS: B3Codec()}
)


def trace():
    '''
    Function decorator that creates opentracing span from incoming b3 headers
    '''
    def decorator(f):
        def wrapper(*args, **kwargs):
            request = stack.top.request
            try:
                # Create a new span context, reading in values (traceid,
                # spanid, etc) from the incoming x-b3-*** headers.
Пример #25
0
 def __init__(self, sname):
     self.tracer = Tracer(one_span_per_rpc=True,
                          service_name=sname,
                          reporter=NullReporter(),
                          sampler=ConstSampler(decision=True),
                          extra_codecs={Format.HTTP_HEADERS: B3Codec()})
from opentracing_instrumentation import http_client, http_server, get_current_span, request_context
from opentracing_instrumentation.client_hooks import tornado_http
import opentracing.ext.tags as ext_tags
from crossdock.thrift_gen.tracetest.ttypes import ObservedSpan, TraceResponse, Transport, \
    JoinTraceRequest

from tchannel import TChannel, thrift
from crossdock.server.thriftrw_serializer import trace_response_to_thriftrw, \
    join_trace_request_to_thriftrw

DefaultClientPortHTTP = 8080
DefaultServerPortHTTP = 8081
DefaultServerPortTChannel = 8082

tracer = Tracer(service_name='python',
                reporter=NullReporter(),
                sampler=ConstSampler(decision=True),
                scope_manager=TornadoScopeManager())
opentracing.set_global_tracer(tracer)

idl_path = 'idl/thrift/crossdock/tracetest.thrift'
thrift_services = {}


def get_thrift_service(service_name):
    if service_name in thrift_services:
        return thrift_services[service_name]
    thrift_service = thrift.load(path=idl_path, service=service_name)
    thrift_services[service_name] = thrift_service
    return thrift_service

Пример #27
0
__name__ = "fastapi_opentracing"
from jaeger_client import Tracer, ConstSampler
from jaeger_client.reporter import NullReporter
from jaeger_client.codecs import B3Codec
from opentracing.scope_managers.contextvars import ContextVarsScopeManager
from opentracing.propagation import Format

tracer = Tracer(
    one_span_per_rpc=True,
    service_name='wk_api_gateway',
    reporter=NullReporter(),
    sampler=ConstSampler(decision=True),
    extra_codecs={Format.HTTP_HEADERS: B3Codec()},
    scope_manager=ContextVarsScopeManager(),
)


async def get_opentracing_span_headers():
    scope = tracer.scope_manager.active
    carrier = {}
    if scope is not None:
        span = scope.span
        tracer.inject(span_context=span,
                      format=Format.HTTP_HEADERS,
                      carrier=carrier)
        for k, v in getattr(span, 'extra_headers', {}).items():
            carrier[k] = v
    return carrier
Пример #28
0
class SimpleTracer:
    '''A very basic OpenTracing tracer, with null reporter'''
    def __init__(self, sname):
        self.tracer = Tracer(one_span_per_rpc=True,
                             service_name=sname,
                             reporter=NullReporter(),
                             sampler=ConstSampler(decision=True),
                             extra_codecs={Format.HTTP_HEADERS: B3Codec()})

    def trace(self):
        '''
        Decorator that creates opentracing span from incoming b3 headers
        '''
        def decorator(f):
            def wrapper(*args, **kwargs):
                global stack
                request = stack.top.request
                try:
                    # Create a new span context, reading in values (traceid,
                    # spanid, etc) from the incoming x-b3-*** headers.
                    span_ctx = self.tracer.extract(Format.HTTP_HEADERS,
                                                   dict(request.headers))
                    # Note: this tag means that the span will *not* be
                    # a child span. It will use the incoming traceid and
                    # spanid. We do this to propagate the headers verbatim.
                    rpc_tag = {tags.SPAN_KIND: tags.SPAN_KIND_RPC_SERVER}
                    span = self.tracer.start_span(operation_name='op',
                                                  child_of=span_ctx,
                                                  tags=rpc_tag)
                except Exception as e:
                    # We failed to create a context, possibly due to no
                    # incoming x-b3-*** headers. Start a fresh span.
                    # Note: This is a fallback only, and will create fresh
                    # headers, not propagate headers.
                    span = self.tracer.start_span('op')
                with span_in_context(span):
                    r = f(*args, **kwargs)
                    return r

            wrapper.__name__ = f.__name__
            return wrapper

        return decorator

    def getForwardHeaders(self, request):
        '''
        Return the headers that should be forwarded to subservices.

        This function currently forwards instances of tracing headers
        for a much wider range of tracing tools than are used in
        this course. If those headers are not present, nothing
        happens other than a bit of wasted computation here.

        At some point, we should pare down the list to only those
        headers needed by the tools used in class.

        The final block, "Application-specific", includes headers
        not needed for tracing but that our application requires to
        be forwarded.
        '''
        headers = {}

        # x-b3-*** headers can be populated using the opentracing span
        span = get_current_span()
        carrier = {}
        self.tracer.inject(span_context=span.context,
                           format=Format.HTTP_HEADERS,
                           carrier=carrier)

        headers.update(carrier)

        # CMPT 756 --- COMMENTED OUT FROM bookinfo
        # We handle other (non x-b3-***) headers manually
        #if 'user' in session:
        #    headers['end-user'] = session['user']

        # Keep this in sync with the headers in details and reviews.
        incoming_headers = [
            # All applications should propagate x-request-id. This header is
            # included in access log statements and is used for consistent trace
            # sampling and log sampling decisions in Istio.
            'x-request-id',

            # Lightstep tracing header. Propagate this if you use lightstep tracing
            # in Istio (see
            # https://istio.io/latest/docs/tasks/observability/distributed-tracing/lightstep/)
            # Note: this should probably be changed to use B3 or W3C TRACE_CONTEXT.
            # Lightstep recommends using B3 or TRACE_CONTEXT and most application
            # libraries from lightstep do not support x-ot-span-context.
            'x-ot-span-context',

            # Datadog tracing header. Propagate these headers if you use Datadog
            # tracing.
            'x-datadog-trace-id',
            'x-datadog-parent-id',
            'x-datadog-sampling-priority',

            # W3C Trace Context. Compatible with OpenCensusAgent and Stackdriver Istio
            # configurations.
            'traceparent',
            'tracestate',

            # Cloud trace context. Compatible with OpenCensusAgent and Stackdriver Istio
            # configurations.
            'x-cloud-trace-context',

            # Grpc binary trace context. Compatible with OpenCensusAgent nad
            # Stackdriver Istio configurations.
            'grpc-trace-bin',

            # b3 trace headers. Compatible with Zipkin, OpenCensusAgent, and
            # Stackdriver Istio configurations. Commented out since they are
            # propagated by the OpenTracing tracer above.
            # 'x-b3-traceid',
            # 'x-b3-spanid',
            # 'x-b3-parentspanid',
            # 'x-b3-sampled',
            # 'x-b3-flags',

            # Application-specific headers to forward.
            'user-agent',
            'Authorization',  # CMPT 756
        ]
        # For Zipkin, always propagate b3 headers.
        # For Lightstep, always propagate the x-ot-span-context header.
        # For Datadog, propagate the corresponding datadog headers.
        # For OpenCensusAgent and Stackdriver configurations, you can choose any
        # set of compatible headers to propagate within your application. For
        # example, you can propagate b3 headers or W3C trace context headers with
        # the same result. This can also allow you to translate between context
        # propagation mechanisms between different applications.

        for ihdr in incoming_headers:
            val = request.headers.get(ihdr)
            if val is not None:
                headers[ihdr] = val

        return headers
Пример #29
0
def tracer():
    reporter = mock.MagicMock()
    sampler = ConstSampler(True)
    return Tracer.default_tracer(None, 'test_service_1', reporter, sampler)
Пример #30
0
from opentracing_instrumentation.client_hooks import tornado_http
import opentracing.ext.tags as ext_tags
from crossdock.thrift_gen.tracetest.ttypes import ObservedSpan, TraceResponse, Transport, \
    JoinTraceRequest

from tchannel import TChannel, thrift
from crossdock.server.thriftrw_serializer import trace_response_to_thriftrw, \
    join_trace_request_to_thriftrw

DefaultClientPortHTTP = 8080
DefaultServerPortHTTP = 8081
DefaultServerPortTChannel = 8082


tracer = Tracer(
    service_name='python',
    reporter=NullReporter(),
    sampler=ConstSampler(decision=True))
opentracing.tracer = tracer


idl_path = 'idl/thrift/crossdock/tracetest.thrift'
thrift_services = {}


def get_thrift_service(service_name):
    if service_name in thrift_services:
        return thrift_services[service_name]
    thrift_service = thrift.load(path=idl_path, service=service_name)
    thrift_services[service_name] = thrift_service
    return thrift_service