def from_headers(self, headers):
        """Generate a SpanContext object from B3 propagation headers.

        :type headers: dict
        :param headers: HTTP request headers.

        :rtype: :class:`~opencensus.trace.span_context.SpanContext`
        :returns: SpanContext generated from B3 propagation headers.
        """
        if headers is None:
            return SpanContext(from_header=False)

        trace_id, span_id, sampled = None, None, None

        state = headers.get(_STATE_HEADER_KEY)
        if state:
            fields = state.split('-', 4)

            if len(fields) == 1:
                sampled = fields[0]
            elif len(fields) == 2:
                trace_id, span_id = fields
            elif len(fields) == 3:
                trace_id, span_id, sampled = fields
            elif len(fields) == 4:
                trace_id, span_id, sampled, _parent_span_id = fields
            else:
                return SpanContext(from_header=False)
        else:
            trace_id = headers.get(_TRACE_ID_KEY)
            span_id = headers.get(_SPAN_ID_KEY)
            sampled = headers.get(_SAMPLED_KEY)

        if sampled is not None:
            # The specification encodes an enabled tracing decision as "1".
            # In the wild pre-standard implementations might still send "true".
            # "d" is set in the single header case when debugging is enabled.
            sampled = sampled.lower() in ('1', 'd', 'true')
        else:
            # If there's no incoming sampling decision, it was deferred to us.
            # Even though we set it to False here, we might still sample
            # depending on the tracer configuration.
            sampled = False

        trace_options = TraceOptions()
        trace_options.set_enabled(sampled)

        # TraceId and SpanId headers both have to exist
        if not trace_id or not span_id:
            return SpanContext(trace_options=trace_options)

        # Convert 64-bit trace ids to 128-bit
        if len(trace_id) == 16:
            trace_id = '0' * 16 + trace_id

        span_context = SpanContext(trace_id=trace_id,
                                   span_id=span_id,
                                   trace_options=trace_options,
                                   from_header=True)

        return span_context
示例#2
0
 def nope(*args, **kwargs):
     trace_options = TraceOptions()
     trace_options.set_enabled(False)
     return SpanContext(trace_options=trace_options)