Exemple #1
0
def test_zipkin_span_trace_with_0_sample_rate(
    logging_context_cls_mock,
    logger_handler_cls_mock,
    create_endpoint_mock,
    create_attrs_for_span_mock,
    push_zipkin_attrs_mock,
    pop_zipkin_attrs_mock,
):
    create_attrs_for_span_mock.return_value = ZipkinAttrs(
        trace_id=generate_random_64bit_string(),
        span_id=generate_random_64bit_string(),
        parent_span_id=None,
        flags='0',
        is_sampled=False,
    )
    with zipkin.zipkin_span(
        service_name='some_service_name',
        span_name='span_name',
        transport_handler=mock.Mock(),
        sample_rate=0.0,
    ) as zipkin_context:
        assert zipkin_context.port == 0
        pass
    create_attrs_for_span_mock.assert_called_once_with(
        sample_rate=0.0,
        use_128bit_trace_id=False,
    )
    push_zipkin_attrs_mock.assert_called_once_with(
        create_attrs_for_span_mock.return_value)
    assert create_endpoint_mock.call_count == 0
    assert logger_handler_cls_mock.call_count == 0
    assert logging_context_cls_mock.call_count == 0
    pop_zipkin_attrs_mock.assert_called_once_with()
Exemple #2
0
def create_attrs_for_span(sample_rate=100.0, trace_id=None, span_id=None):
    """Creates a set of zipkin attributes for a span.

    :param sample_rate: Float between 0.0 and 100.0 to determine sampling rate
    :type sample_rate: float
    :param trace_id: Optional 16-character hex string representing a trace_id.
                    If this is None, a random trace_id will be generated.
    :type trace_id: str
    :param span_id: Optional 16-character hex string representing a span_id.
                    If this is None, a random span_id will be generated.
    :type span_id: str
    """
    # Calculate if this trace is sampled based on the sample rate
    if trace_id is None:
        trace_id = generate_random_64bit_string()
    if span_id is None:
        span_id = generate_random_64bit_string()
    if sample_rate == 0.0:
        is_sampled = False
    else:
        is_sampled = (random.random() * 100) < sample_rate

    return ZipkinAttrs(
        trace_id=trace_id,
        span_id=span_id,
        parent_span_id=None,
        flags='0',
        is_sampled=is_sampled,
    )
Exemple #3
0
    def test_get_current_context_root_sample_rate_override_not_sampled(
        self,
        mock_create_attr,
    ):
        # Root span, with custom zipkin_attrs, not sampled and sample_rate
        zipkin_attrs = ZipkinAttrs(
            trace_id=generate_random_64bit_string(),
            span_id=generate_random_64bit_string(),
            parent_span_id=generate_random_64bit_string(),
            flags=None,
            is_sampled=False,
        )
        context = zipkin.zipkin_span(
            service_name='test_service',
            span_name='test_span',
            transport_handler=MockTransportHandler(),
            zipkin_attrs=zipkin_attrs,
            sample_rate=100.0,
        )

        report_root, _ = context._get_current_context()

        assert mock_create_attr.call_args == mock.call(
            sample_rate=100.0,
            trace_id=zipkin_attrs.trace_id,
        )
        # It wasn't sampled before and now it is, so this is the trace root
        assert report_root is True
Exemple #4
0
    def test_get_current_context_root_sample_rate_override_sampled(
            self,
            mock_create_attr,
    ):
        # Root span, with custom zipkin_attrs, sampled
        # Just return the custom zipkin_attrs.
        zipkin_attrs = ZipkinAttrs(
            trace_id=generate_random_64bit_string(),
            span_id=generate_random_64bit_string(),
            parent_span_id=generate_random_64bit_string(),
            flags=None,
            is_sampled=True,
        )
        context = zipkin.zipkin_span(
            service_name='test_service',
            span_name='test_span',
            transport_handler=MockTransportHandler(),
            zipkin_attrs=zipkin_attrs,
            sample_rate=100.0,
        )

        report_root, current_attrs = context._get_current_context()

        assert mock_create_attr.call_count == 0
        assert current_attrs == zipkin_attrs
        # The override was set and was already sampled, so this is probably
        # not the trace root.
        assert report_root is False
Exemple #5
0
    def test_get_current_context_non_root_existing(
            self,
            mock_create_attr,
    ):
        # Non root, zipkin_attrs in context stack.
        # Return existing zipkin_attrs with the current one as parent
        zipkin_attrs = ZipkinAttrs(
            trace_id=generate_random_64bit_string(),
            span_id=generate_random_64bit_string(),
            parent_span_id=generate_random_64bit_string(),
            flags=None,
            is_sampled=True,
        )
        tracer = MockTracer()
        context = tracer.zipkin_span(
            service_name='test_service',
            span_name='test_span',
        )
        tracer._context_stack.push(zipkin_attrs)

        _, current_attrs = context._get_current_context()

        assert mock_create_attr.call_count == 0
        assert current_attrs == ZipkinAttrs(
            trace_id=zipkin_attrs.trace_id,
            span_id=mock.ANY,
            parent_span_id=zipkin_attrs.span_id,
            flags=zipkin_attrs.flags,
            is_sampled=zipkin_attrs.is_sampled,
        )
Exemple #6
0
def trace(span_name, tracer, span_id=None, service_name=None):
    span_id = span_id or generate_random_64bit_string()
    service_name = service_name or settings.ZIPKIN_SERVICE_NAME
    if len(span_id) > 16:
        logger.warning('Span id %s for %s should be max 16 chars.' %
                       (span_id, span_name))
    trace_id = (tracer.get('trace_id') or generate_random_64bit_string())
    parent_span_id = (tracer.get('span_id') or generate_random_64bit_string())
    flags = tracer.get('flags') or ''
    is_sampled = (True if tracer.get('is_tracing') else False)
    transport_handler = import_string(
        getattr(settings, 'ZIPKIN_TRANSPORT_HANDLER',
                'django_py_zipkin.transport.zipkin_transport'))

    span = zipkin_span(service_name=service_name,
                       span_name=span_name,
                       transport_handler=transport_handler,
                       zipkin_attrs=ZipkinAttrs(trace_id=trace_id,
                                                span_id=span_id,
                                                parent_span_id=parent_span_id,
                                                flags=flags,
                                                is_sampled=is_sampled))
    with span as zipkin_context:
        dict_context = {}
        yield dict_context
        zipkin_context.update_binary_annotations(dict_context)
Exemple #7
0
def make_new_attrs(sample_rate=1.0):
    return ZipkinAttrs(
        generate_random_64bit_string(),
        generate_random_64bit_string(),
        None,
        '0',
        sample_rate and random.random() < sample_rate or False,
    )
Exemple #8
0
def test_encoding(encoding, validate_fn):
    zipkin_attrs = ZipkinAttrs(
        trace_id=generate_random_64bit_string(),
        span_id=generate_random_64bit_string(),
        parent_span_id=generate_random_64bit_string(),
        is_sampled=True,
        flags=None,
    )
    inner_span_id = generate_random_64bit_string()
    mock_transport_handler = MockTransportHandler(10000)
    # Let's hardcode the timestamp rather than call time.time() every time.
    # The issue with time.time() is that the convertion to int of the
    # returned float value * 1000000 is not precise and in the same test
    # sometimes returns N and sometimes N+1. This ts value doesn't have that
    # issue afaict, probably since it ends in zeros.
    ts = 1538544126.115900
    with mock.patch("time.time", autospec=True) as mock_time:
        # zipkin.py start, logging_helper.start, 3 x logging_helper.stop
        # I don't understand why logging_helper.stop would run 3 times, but
        # that's what I'm seeing in the test
        mock_time.side_effect = iter(
            [ts, ts, ts + 10, ts + 10, ts + 10, ts + 10, ts + 10]
        )
        with zipkin.zipkin_span(
            service_name="test_service_name",
            span_name="test_span_name",
            transport_handler=mock_transport_handler,
            binary_annotations={"some_key": "some_value"},
            encoding=encoding,
            zipkin_attrs=zipkin_attrs,
            host="10.0.0.0",
            port=8080,
            kind=Kind.CLIENT,
        ) as span:
            with mock.patch.object(
                zipkin, "generate_random_64bit_string", return_value=inner_span_id,
            ):
                with zipkin.zipkin_span(
                    service_name="test_service_name",
                    span_name="inner_span",
                    timestamp=ts,
                    duration=5,
                    annotations={"ws": ts},
                ):
                    span.add_sa_binary_annotation(
                        8888, "sa_service", "2001:0db8:85a3:0000:0000:8a2e:0370:7334",
                    )
                with zipkin.zipkin_span(
                    service_name="test_service_name",
                    span_name="producer_span",
                    timestamp=ts,
                    duration=10,
                    kind=Kind.PRODUCER,
                ):
                    pass

    output = mock_transport_handler.get_payloads()[0]
    validate_fn(output, zipkin_attrs, inner_span_id, ts)
Exemple #9
0
def _make_new_attrs(sample_rate=1.0):
    from py_zipkin.zipkin import ZipkinAttrs  # pylint: disable=E0401
    from py_zipkin.util import generate_random_64bit_string  # pylint: disable=E0401

    return ZipkinAttrs(
        generate_random_64bit_string(),
        generate_random_64bit_string(),
        None,
        '0',
        sample_rate and random.random() < sample_rate or False,
    )
Exemple #10
0
def _read_zipkin_attrs(worker_ctx):
    if TRACE_ID_HEADER not in worker_ctx.data:
        trace_id = generate_random_64bit_string()
        logger.info('No {} header in context, created trace ID: {}'.format(TRACE_ID_HEADER, trace_id))
    else:
        trace_id = worker_ctx.data[TRACE_ID_HEADER]
    return zipkin.ZipkinAttrs(trace_id=trace_id,
                              span_id=generate_random_64bit_string(),
                              parent_span_id=worker_ctx.data.get(PARENT_SPAN_ID_HEADER),
                              flags=worker_ctx.data.get(FLAGS_HEADER),
                              is_sampled=worker_ctx.data.get(SAMPLED_HEADER) == '1')
Exemple #11
0
def test_create_span_with_bad_kind():
    with pytest.raises(ZipkinError) as e:
        Span(
            trace_id=generate_random_64bit_string(),
            name="test span",
            parent_id=generate_random_64bit_string(),
            span_id=generate_random_64bit_string(),
            kind="client",
            timestamp=26.0,
            duration=4.0,
        )

    assert "Invalid kind value client. Must be of type Kind." in str(e.value)
Exemple #12
0
def generate_list_of_spans(encoding):
    zipkin_attrs = ZipkinAttrs(
        trace_id=generate_random_64bit_string(),
        span_id=generate_random_64bit_string(),
        parent_span_id=generate_random_64bit_string(),
        is_sampled=True,
        flags=None,
    )
    inner_span_id = generate_random_64bit_string()
    transport_handler = MockTransportHandler()
    # Let's hardcode the timestamp rather than call time.time() every time.
    # The issue with time.time() is that the convertion to int of the
    # returned float value * 1000000 is not precise and in the same test
    # sometimes returns N and sometimes N+1. This ts value doesn't have that
    # issue afaict, probably since it ends in zeros.
    ts = 1538544126.115900
    with mock.patch('time.time', autospec=True) as mock_time:
        # zipkin.py start, logging_helper.start, 3 x logging_helper.stop
        # I don't understand why logging_helper.stop would run 3 times, but
        # that's what I'm seeing in the test
        mock_time.side_effect = iter([ts, ts, ts + 10, ts + 10, ts + 10])
        with zipkin.zipkin_span(
                service_name='test_service_name',
                span_name='test_span_name',
                transport_handler=transport_handler,
                binary_annotations={'some_key': 'some_value'},
                encoding=encoding,
                zipkin_attrs=zipkin_attrs,
                host='10.0.0.0',
                port=8080,
                kind=Kind.CLIENT,
        ) as span:
            with mock.patch.object(
                    zipkin,
                    'generate_random_64bit_string',
                    return_value=inner_span_id,
            ):
                with zipkin.zipkin_span(
                        service_name='test_service_name',
                        span_name='inner_span',
                        timestamp=ts,
                        duration=5,
                        annotations={'ws': ts},
                ):
                    span.add_sa_binary_annotation(
                        8888,
                        'sa_service',
                        '2001:0db8:85a3:0000:0000:8a2e:0370:7334',
                    )

    return transport_handler.get_payloads()[0], zipkin_attrs, inner_span_id, ts
Exemple #13
0
def test_create_span_with_bad_remote_endpoint():
    with pytest.raises(ZipkinError) as e:
        Span(
            trace_id=generate_random_64bit_string(),
            name='test span',
            parent_id=generate_random_64bit_string(),
            span_id=generate_random_64bit_string(),
            kind=Kind.CLIENT,
            timestamp=26.0,
            duration=4.0,
            remote_endpoint='my_service',
        )

    assert 'Invalid remote_endpoint value. Must be of type Endpoint.' in str(e)
Exemple #14
0
 def test__convert_unsigned_long_to_lower_hex(self):
     decoder = _V1ThriftDecoder()
     span_id = generate_random_64bit_string()
     span = thrift.create_span(
         span_id,
         None,
         generate_random_64bit_string(),
         'test_span',
         [],
         [],
         None,
         None,
     )
     assert decoder._convert_unsigned_long_to_lower_hex(span.id) == span_id
Exemple #15
0
    def test_v1_span(self, kind, annotations):
        endpoint = create_endpoint(port=8080, service_name="foo", host="80")
        span = Span(
            trace_id=generate_random_64bit_string(),
            name="test span",
            parent_id=generate_random_64bit_string(),
            span_id=generate_random_64bit_string(),
            kind=kind,
            timestamp=26.0,
            duration=4.0,
            local_endpoint=endpoint,
        )
        v1_span = span.build_v1_span()

        assert v1_span.annotations == annotations
Exemple #16
0
def test_create_span_with_bad_local_endpoint():
    with pytest.raises(ZipkinError) as e:
        Span(
            trace_id=generate_random_64bit_string(),
            name="test span",
            parent_id=generate_random_64bit_string(),
            span_id=generate_random_64bit_string(),
            kind=Kind.CLIENT,
            timestamp=26.0,
            duration=4.0,
            local_endpoint="my_service",
        )

    assert "Invalid local_endpoint value. Must be of type Endpoint." in str(
        e.value)
def construct_zipkin_attrs(data):
    parsed = json.loads(data)
    return ZipkinAttrs(trace_id=parsed.get('trace_id'),
                       parent_span_id=parsed.get('parent_span_id'),
                       span_id=generate_random_64bit_string(),
                       is_sampled=parsed.get('is_sampled'),
                       flags='0')
    def add_zipkin_to_request(self, request):
        if not (self.enable_tracing and self.is_tracing(request)):
            setattr(request, 'zipkin_is_tracing', False)
            setattr(request, 'zipkin_trace_id', None)
            setattr(request, 'zipkin_span_id', None)
            setattr(request, 'zipkin_parent_span_id', None)
            setattr(request, 'zipkin_flags', None)
            setattr(request, 'zipkin_tracer', {
                'is_tracing': request.zipkin_is_tracing,
            })
            return

        span_id = request.META.get('HTTP_X_B3_SPANID',
                                   generate_random_64bit_string())
        parent_span_id = request.META.get('HTTP_X_B3_PARENTSPANID', None)
        flags = request.META.get('HTTP_X_B3_FLAGS', '0')

        setattr(request, 'zipkin_is_tracing', True)
        setattr(request, 'zipkin_trace_id', get_trace_id(request))
        setattr(request, 'zipkin_span_id', span_id)
        setattr(request, 'zipkin_parent_span_id', parent_span_id)
        setattr(request, 'zipkin_flags', flags)
        setattr(
            request, 'zipkin_tracer', {
                'is_tracing': request.zipkin_is_tracing,
                'trace_id': request.zipkin_trace_id,
                'span_id': request.zipkin_span_id,
                'parent_span_id': request.zipkin_parent_span_id,
                'flags': request.zipkin_flags
            })
Exemple #19
0
def create_zipkin_attr(request):
    """Create ZipkinAttrs object from a request with sampled flag as True.
    Attaches lazy attribute `zipkin_trace_id` with request which is then used
    throughout the tween.

    Consumes custom is_tracing function to determine if the request is traced
    if one is set in the pyramid registry.

    :param request: pyramid request object
    :rtype: :class:`pyramid_zipkin.request_helper.ZipkinAttrs`
    """
    request.set_property(get_trace_id, 'zipkin_trace_id', reify=True)

    trace_id = request.zipkin_trace_id

    settings = request.registry.settings
    if 'zipkin.is_tracing' in settings:
        is_sampled = settings['zipkin.is_tracing'](request)
    else:
        is_sampled = is_tracing(request)

    span_id = request.headers.get('X-B3-SpanId',
                                  generate_random_64bit_string())
    parent_span_id = request.headers.get('X-B3-ParentSpanId', None)
    flags = request.headers.get('X-B3-Flags', '0')
    return ZipkinAttrs(
        trace_id=trace_id,
        span_id=span_id,
        parent_span_id=parent_span_id,
        flags=flags,
        is_sampled=is_sampled,
    )
Exemple #20
0
def test_generate_random_64bit_string(rand):
    rand.return_value = b'17133d482ba4f605'
    random_string = util.generate_random_64bit_string()
    assert random_string == '17133d482ba4f605'
    # This acts as a contract test of sorts. This should return a str
    # in both py2 and py3. IOW, no unicode objects.
    assert isinstance(random_string, str)
Exemple #21
0
def generate_single_thrift_span():
    trace_id = generate_random_128bit_string()
    span_id = generate_random_64bit_string()
    timestamp_s = round(time.time(), 3)
    duration_s = 2.0
    host = thrift.create_endpoint(port=8000, service_name='host')
    host.ipv4 = 2130706433
    span = thrift.create_span(
        span_id=span_id,
        parent_span_id=None,
        trace_id=trace_id,
        span_name='foo',
        annotations=[
            thrift.create_annotation(1472470996199000, "cs", host),
        ],
        binary_annotations=[
            thrift.create_binary_annotation(
                "key",
                "value",
                zipkin_core.AnnotationType.STRING,
                host,
            ),
        ],
        timestamp_s=timestamp_s,
        duration_s=duration_s,
    )

    return thrift.span_to_bytes(span)
def enrich_with_zipkin_data(data):
    zipkin_attr = get_zipkin_attrs()
    data[0]['trace_id'] = zipkin_attr.trace_id
    data[0]['parent_span_id'] = zipkin_attr.span_id
    data[0]['span_id'] = generate_random_64bit_string()
    data[0]['is_sampled'] = True if zipkin_attr.is_sampled else False
    return data
Exemple #23
0
def generate_zipkin_headers(zipkin_context):
    return {
        "X-B3-TraceId": zipkin_context.zipkin_attrs.trace_id,
        "X-B3-ParentSpanId": zipkin_context.zipkin_attrs.span_id,
        "X-B3-SpanId": generate_random_64bit_string(),
        "X-B3-Sampled": '1'
    }
Exemple #24
0
def create_zipkin_attr(request):
    """Create ZipkinAttrs object from a request with sampled flag as True.
    Attaches lazy attribute `zipkin_trace_id` with request which is then used
    throughout the tween.

    Consumes custom is_tracing function to determine if the request is traced
    if one is set in the pyramid registry.

    :param request: pyramid request object
    :rtype: :class:`pyramid_zipkin.request_helper.ZipkinAttrs`
    """
    request.set_property(get_trace_id, 'zipkin_trace_id', reify=True)

    trace_id = request.zipkin_trace_id

    settings = request.registry.settings
    if 'zipkin.is_tracing' in settings:
        is_sampled = settings['zipkin.is_tracing'](request)
    else:
        is_sampled = is_tracing(request)

    span_id = request.headers.get(
        'X-B3-SpanId', generate_random_64bit_string())
    parent_span_id = request.headers.get('X-B3-ParentSpanId', None)
    flags = request.headers.get('X-B3-Flags', '0')
    return ZipkinAttrs(
        trace_id=trace_id,
        span_id=span_id,
        parent_span_id=parent_span_id,
        flags=flags,
        is_sampled=is_sampled,
    )
Exemple #25
0
def create_http_headers_for_new_span(context_stack=None, tracer=None):
    """
    Generate the headers for a new zipkin span.

    .. note::

        If the method is not called from within a zipkin_trace context,
        empty dict will be returned back.

    :returns: dict containing (X-B3-TraceId, X-B3-SpanId, X-B3-ParentSpanId,
                X-B3-Flags and X-B3-Sampled) keys OR an empty dict.
    """
    if tracer:
        zipkin_attrs = tracer.get_zipkin_attrs()
    elif context_stack:
        zipkin_attrs = context_stack.get()
    else:
        zipkin_attrs = get_default_tracer().get_zipkin_attrs()

    if not zipkin_attrs:
        return {}

    return {
        'X-B3-TraceId': zipkin_attrs.trace_id,
        'X-B3-SpanId': generate_random_64bit_string(),
        'X-B3-ParentSpanId': zipkin_attrs.span_id,
        'X-B3-Flags': '0',
        'X-B3-Sampled': '1' if zipkin_attrs.is_sampled else '0',
    }
Exemple #26
0
def make_child_attrs(attrs):
    return ZipkinAttrs(
        attrs.trace_id,
        generate_random_64bit_string(),
        attrs.span_id,
        attrs.flags,
        attrs.is_sampled,
    )
Exemple #27
0
    def start_workunit(self, workunit):
        """Implementation of Reporter callback."""
        if workunit.has_label(WorkUnitLabel.GOAL):
            service_name = "pants goal"
        elif workunit.has_label(WorkUnitLabel.TASK):
            service_name = "pants task"
        else:
            service_name = "pants workunit"

        # Check if it is the first workunit
        first_span = not self._workunits_to_spans
        if first_span:
            # If trace_id and parent_id are given as flags create zipkin_attrs
            if self.trace_id is not None and self.parent_id is not None:
                zipkin_attrs = ZipkinAttrs(
                    # trace_id and parent_id are passed to Pants by another process that collects
                    # Zipkin trace
                    trace_id=self.trace_id,
                    span_id=generate_random_64bit_string(),
                    parent_span_id=self.parent_id,
                    flags='0',  # flags: stores flags header. Currently unused
                    is_sampled=True,
                )
            else:
                zipkin_attrs = create_attrs_for_span(
                    # trace_id is the same as run_uuid that is created in run_tracker and is the part of
                    # pants_run id
                    trace_id=self.trace_id,
                    sample_rate=self.
                    sample_rate,  # Value between 0.0 and 100.0
                )
                self.trace_id = zipkin_attrs.trace_id
                # TODO delete this line when parent_id will be passed in v2 engine:
                #  - with ExecutionRequest when Nodes from v2 engine are called by a workunit;
                #  - when a v2 engine Node is called by another v2 engine Node.
                self.parent_id = zipkin_attrs.span_id

            span = zipkin_span(
                service_name=service_name,
                span_name=workunit.name,
                transport_handler=self.handler,
                encoding=Encoding.V1_THRIFT,
                zipkin_attrs=zipkin_attrs,
                span_storage=self.span_storage,
            )
        else:
            span = zipkin_span(
                service_name=service_name,
                span_name=workunit.name,
                span_storage=self.span_storage,
            )
        self._workunits_to_spans[workunit] = span
        span.start()
        # Goals and tasks save their start time at the beginning of their run.
        # This start time is passed to workunit, because the workunit may be created much later.
        span.start_timestamp = workunit.start_time
        if first_span and span.zipkin_attrs.is_sampled:
            span.logging_context.start_timestamp = workunit.start_time
  def start_workunit(self, workunit):
    """Implementation of Reporter callback."""
    if workunit.has_label(WorkUnitLabel.GOAL):
      service_name = "pants goal"
    elif workunit.has_label(WorkUnitLabel.TASK):
      service_name = "pants task"
    else:
      service_name = "pants workunit"

    # Check if it is the first workunit
    first_span = not self._workunits_to_spans
    if first_span:
      # If trace_id and parent_id are given as flags create zipkin_attrs
      if self.trace_id is not None and self.parent_id is not None:
        zipkin_attrs = ZipkinAttrs(
          # trace_id and parent_id are passed to Pants by another process that collects
          # Zipkin trace
          trace_id=self.trace_id,
          span_id=generate_random_64bit_string(),
          parent_span_id=self.parent_id,
          flags='0', # flags: stores flags header. Currently unused
          is_sampled=True,
        )
      else:
        zipkin_attrs =  create_attrs_for_span(
          # trace_id is the same as run_uuid that is created in run_tracker and is the part of
          # pants_run id
          trace_id=self.trace_id,
          sample_rate=self.sample_rate, # Value between 0.0 and 100.0
        )
        self.trace_id = zipkin_attrs.trace_id
        # TODO delete this line when parent_id will be passed in v2 engine:
        #  - with ExecutionRequest when Nodes from v2 engine are called by a workunit;
        #  - when a v2 engine Node is called by another v2 engine Node.
        self.parent_id = zipkin_attrs.span_id

      span = zipkin_span(
        service_name=service_name,
        span_name=workunit.name,
        transport_handler=self.handler,
        encoding=Encoding.V1_THRIFT,
        zipkin_attrs=zipkin_attrs,
        span_storage=self.span_storage,
      )
    else:
      span = zipkin_span(
        service_name=service_name,
        span_name=workunit.name,
        span_storage=self.span_storage,
      )
    self._workunits_to_spans[workunit] = span
    span.start()
    # Goals and tasks save their start time at the beginning of their run.
    # This start time is passed to workunit, because the workunit may be created much later.
    span.start_timestamp = workunit.start_time
    if first_span and span.zipkin_attrs.is_sampled:
      span.logging_context.start_timestamp = workunit.start_time
Exemple #29
0
def extract_zipkin_attrs(headers):
    logger.debug(f"headers:{headers}")
    return ZipkinAttrs(
        headers['X-B3-TraceId'],
        generate_random_64bit_string(),
        headers['X-B3-SpanId'],
        headers.get('X-B3-Flags', ''),
        headers['X-B3-Sampled'],
    )
Exemple #30
0
def _read_zipkin_attrs(worker_ctx):
    if TRACE_ID_HEADER not in worker_ctx.data:
        return None
    return zipkin.ZipkinAttrs(
        trace_id=worker_ctx.data[TRACE_ID_HEADER],
        span_id=generate_random_64bit_string(),
        parent_span_id=worker_ctx.data[PARENT_SPAN_ID_HEADER],
        flags=worker_ctx.data[FLAGS_HEADER],
        is_sampled=worker_ctx.data[SAMPLED_HEADER] == '1')
Exemple #31
0
def _make_child_attrs(attrs):
    from py_zipkin.zipkin import ZipkinAttrs  # pylint: disable=E0401
    from py_zipkin.util import generate_random_64bit_string  # pylint: disable=E0401

    return ZipkinAttrs(
        attrs.trace_id,
        generate_random_64bit_string(),
        attrs.span_id,
        attrs.flags,
        attrs.is_sampled,
    )
    def __get_span_attrs(self, use_128bit_trace_id=False):
        parent_span_id = self.__get_parent_span_id()
        trace_id = self.__get_trace_id()

        if trace_id is None:
            if use_128bit_trace_id:
                trace_id = generate_random_128bit_string()
            else:
                trace_id = generate_random_64bit_string()

        is_sampled = self.__is_sampled()
        span_id = generate_random_64bit_string()

        return ZipkinAttrs(
                trace_id=trace_id,
                span_id=span_id,
                parent_span_id=parent_span_id,
                flags=self.__get_flags(),
                is_sampled=is_sampled,
        )
def get_trace_id(request):
    """Gets the trace id based on a request. If not present with the request,
    create a custom (depending on config: `zipkin.trace_id_generator`) or a
    completely random trace id.

    :param: current active pyramid request
    :returns: a 64-bit hex string
    """
    if 'X-B3-TraceId' in request.headers:
        trace_id = request.headers['X-B3-TraceId']
    elif 'zipkin.trace_id_generator' in request.registry.settings:
        trace_id = request.registry.settings[
            'zipkin.trace_id_generator'](request)
    else:
        trace_id = generate_random_64bit_string()

    return trace_id
Exemple #34
0
def get_trace_id(request):
    """Gets the trace id based on a request. If not present with the request,
    create a custom (depending on config: `zipkin.trace_id_generator`) or a
    completely random trace id.

    :param: current active pyramid request
    :returns: a 64-bit hex string
    """
    if 'X-B3-TraceId' in request.headers:
        trace_id = _convert_signed_hex(request.headers['X-B3-TraceId'])
        # Tolerates 128 bit X-B3-TraceId by reading the right-most 16 hex
        # characters (as opposed to overflowing a U64 and starting a new trace).
        trace_id = trace_id[-16:]
    elif 'zipkin.trace_id_generator' in request.registry.settings:
        trace_id = _convert_signed_hex(request.registry.settings[
            'zipkin.trace_id_generator'](request))
    else:
        trace_id = generate_random_64bit_string()

    return trace_id
def create_zipkin_attr(request):
    """Create ZipkinAttrs object from a request with sampled flag as True.
    Attaches lazy attribute `zipkin_trace_id` with request which is then used
    throughout the tween.

    Consumes custom is_tracing function to determine if the request is traced
    if one is set in the pyramid registry.

    :param request: pyramid request object
    :rtype: :class:`pyramid_zipkin.request_helper.ZipkinAttrs`
    """
    settings = request.registry.settings

    if 'zipkin.is_tracing' in settings:
        is_sampled = settings['zipkin.is_tracing'](request)
    else:
        is_sampled = is_tracing(request)

    # If zipkin.always_emit_zipkin_headers is set to false, don't propagate
    # zipkin headers if we're not tracing.
    # This saves about 0.3ms since request.set_property is quite slow
    if is_sampled or settings.get('zipkin.always_emit_zipkin_headers', True):
        request.set_property(get_trace_id, 'zipkin_trace_id', reify=True)

        trace_id = request.zipkin_trace_id

        span_id = request.headers.get(
            'X-B3-SpanId', generate_random_64bit_string())
        parent_span_id = request.headers.get('X-B3-ParentSpanId', None)
        flags = request.headers.get('X-B3-Flags', '0')
        return ZipkinAttrs(
            trace_id=trace_id,
            span_id=span_id,
            parent_span_id=parent_span_id,
            flags=flags,
            is_sampled=is_sampled,
        )

    return ZipkinAttrs('', '', '', '0', False)
def create_zipkin_attr(request):
    """Create ZipkinAttrs object from a request with sampled flag as True.
    Attaches lazy attribute `zipkin_trace_id` with request which is then used
    throughout the tween.

    :param request: pyramid request object
    :rtype: :class:`pyramid_zipkin.request_helper.ZipkinAttrs`
    """
    request.set_property(get_trace_id, 'zipkin_trace_id', reify=True)

    trace_id = request.zipkin_trace_id
    is_sampled = is_tracing(request)
    span_id = request.headers.get(
        'X-B3-SpanId', generate_random_64bit_string())
    parent_span_id = request.headers.get('X-B3-ParentSpanId', None)
    flags = request.headers.get('X-B3-Flags', '0')
    return ZipkinAttrs(
        trace_id=trace_id,
        span_id=span_id,
        parent_span_id=parent_span_id,
        flags=flags,
        is_sampled=is_sampled,
    )