Exemple #1
0
    def start(self):
        """Enter the new span context. All annotations logged inside this
        context will be attributed to this span. All new spans generated
        inside this context will have this span as their parent.

        In the unsampled case, this context still generates new span IDs and
        pushes them onto the threadlocal stack, so downstream services calls
        made will pass the correct headers. However, the logging handler is
        never attached in the unsampled case, so the spans are never logged.
        """
        self.do_pop_attrs = False
        # If zipkin_attrs are passed in or this span is doing its own sampling,
        # it will need to actually log spans at __exit__.
        self.perform_logging = self.zipkin_attrs or self.sample_rate is not None

        if self.sample_rate is not None:
            # This clause allows for sampling this service independently
            # of the passed-in zipkin_attrs.
            if self.zipkin_attrs and not self.zipkin_attrs.is_sampled:
                self.zipkin_attrs = create_attrs_for_span(
                    sample_rate=self.sample_rate,
                    trace_id=self.zipkin_attrs.trace_id,
                )
            elif not self.zipkin_attrs:
                self.zipkin_attrs = create_attrs_for_span(
                    sample_rate=self.sample_rate, )

        if not self.zipkin_attrs:
            # This span is inside the context of an existing trace
            existing_zipkin_attrs = get_zipkin_attrs()
            if existing_zipkin_attrs:
                self.zipkin_attrs = ZipkinAttrs(
                    trace_id=existing_zipkin_attrs.trace_id,
                    span_id=generate_random_64bit_string(),
                    parent_span_id=existing_zipkin_attrs.span_id,
                    flags=existing_zipkin_attrs.flags,
                    is_sampled=existing_zipkin_attrs.is_sampled,
                )

        # If zipkin_attrs are not set up by now, that means this span is not
        # configured to perform logging itself, and it's not in an existing
        # Zipkin trace. That means there's nothing else to do and it can exit
        # early.
        if not self.zipkin_attrs:
            return self

        push_zipkin_attrs(self.zipkin_attrs)
        self.do_pop_attrs = True

        self.start_timestamp = time.time()

        # Set up logging if this is the root span
        if self.perform_logging:
            # Don't set up any logging if we're not sampling
            if not self.zipkin_attrs.is_sampled:
                return self

            endpoint = create_endpoint(self.port, self.service_name)
            self.log_handler = ZipkinLoggerHandler(self.zipkin_attrs)
            self.logging_context = ZipkinLoggingContext(
                self.zipkin_attrs,
                endpoint,
                self.log_handler,
                self.span_name,
                self.transport_handler,
                self.binary_annotations,
                add_logging_annotation=self.add_logging_annotation,
            )
            self.logging_context.start()
            return self
        else:
            # In the sampled case, patch the ZipkinLoggerHandler.
            if self.zipkin_attrs.is_sampled:
                # Be defensive about logging setup. Since ZipkinAttrs are local to
                # the thread, multithreaded frameworks can get in strange states.
                # The logging is not going to be correct in these cases, so we set
                # a flag that turns off logging on __exit__.
                if len(zipkin_logger.handlers) > 0:
                    # Put span ID on logging handler. Assume there's only a single
                    # handler, since all logging should be set up in this package.
                    self.log_handler = zipkin_logger.handlers[0]
                    # Store the old parent_span_id, probably None, in case we have
                    # nested zipkin_spans
                    self.old_parent_span_id = self.log_handler.parent_span_id
                    self.log_handler.parent_span_id = self.zipkin_attrs.span_id

            return self
Exemple #2
0
def test_push_zipkin_attrs_adds_new_zipkin_attrs_to_list():
    tracer = storage.get_default_tracer()
    with mock.patch.object(tracer._context_stack, "_storage", ["foo"]):
        assert "foo" == thread_local.get_zipkin_attrs()
        thread_local.push_zipkin_attrs("bar")
        assert "bar" == thread_local.get_zipkin_attrs()
def test_push_zipkin_attrs_adds_new_zipkin_attrs_to_list():
    assert 'foo' == thread_local.get_zipkin_attrs()
    thread_local.push_zipkin_attrs('bar')
    assert 'bar' == thread_local.get_zipkin_attrs()
Exemple #4
0
def test_push_zipkin_attrs_adds_new_zipkin_attrs_to_list():
    tracer = storage.get_default_tracer()
    with mock.patch.object(tracer._context_stack, '_storage', ['foo']):
        assert 'foo' == thread_local.get_zipkin_attrs()
        thread_local.push_zipkin_attrs('bar')
        assert 'bar' == thread_local.get_zipkin_attrs()