コード例 #1
0
    def extract(cls, get_from_carrier, carrier):
        trace_id = format_trace_id(trace.INVALID_TRACE_ID)
        span_id = format_span_id(trace.INVALID_SPAN_ID)
        sampled = "0"
        flags = None

        single_header = _extract_first_element(
            get_from_carrier(carrier, cls.SINGLE_HEADER_KEY))
        if single_header:
            # The b3 spec calls for the sampling state to be
            # "deferred", which is unspecified. This concept does not
            # translate to SpanContext, so we set it as recorded.
            sampled = "1"
            fields = single_header.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 trace.INVALID_SPAN_CONTEXT
        else:
            trace_id = (_extract_first_element(
                get_from_carrier(carrier, cls.TRACE_ID_KEY)) or trace_id)
            span_id = (_extract_first_element(
                get_from_carrier(carrier, cls.SPAN_ID_KEY)) or span_id)
            sampled = (_extract_first_element(
                get_from_carrier(carrier, cls.SAMPLED_KEY)) or sampled)
            flags = (_extract_first_element(
                get_from_carrier(carrier, cls.FLAGS_KEY)) or flags)

        options = 0
        # The b3 spec provides no defined behavior for both sample and
        # flag values set. Since the setting of at least one implies
        # the desire for some form of sampling, propagate if either
        # header is set to allow.
        if sampled in cls._SAMPLE_PROPAGATE_VALUES or flags == "1":
            options |= trace.TraceOptions.SAMPLED
        return trace.SpanContext(
            # trace an span ids are encoded in hex, so must be converted
            trace_id=int(trace_id, 16),
            span_id=int(span_id, 16),
            trace_options=trace.TraceOptions(options),
            trace_state=trace.TraceState(),
        )
コード例 #2
0
    def extract(cls, get_from_carrier: httptextformat.Getter[_T],
                carrier: _T) -> trace.SpanContext:
        """Extracts a valid SpanContext from the carrier.
        """
        header = get_from_carrier(carrier, cls._TRACEPARENT_HEADER_NAME)

        if not header:
            return trace.INVALID_SPAN_CONTEXT

        match = re.search(cls._TRACEPARENT_HEADER_FORMAT_RE, header[0])
        if not match:
            return trace.INVALID_SPAN_CONTEXT

        version = match.group(1)
        trace_id = match.group(2)
        span_id = match.group(3)
        trace_options = match.group(4)

        if trace_id == "0" * 32 or span_id == "0" * 16:
            return trace.INVALID_SPAN_CONTEXT

        if version == "00":
            if match.group(5):
                return trace.INVALID_SPAN_CONTEXT
        if version == "ff":
            return trace.INVALID_SPAN_CONTEXT

        tracestate_headers = get_from_carrier(carrier,
                                              cls._TRACESTATE_HEADER_NAME)
        tracestate = _parse_tracestate(tracestate_headers)

        span_context = trace.SpanContext(
            trace_id=int(trace_id, 16),
            span_id=int(span_id, 16),
            trace_options=trace.TraceOptions(trace_options),
            trace_state=tracestate,
        )

        return span_context
コード例 #3
0
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

import unittest

from opentelemetry import trace
from opentelemetry.trace import sampling

TO_DEFAULT = trace.TraceOptions(trace.TraceOptions.DEFAULT)
TO_SAMPLED = trace.TraceOptions(trace.TraceOptions.SAMPLED)


class TestSampler(unittest.TestCase):
    def test_always_on(self):
        no_record_always_on = sampling.ALWAYS_ON.should_sample(
            trace.SpanContext(0xDEADBEEF, 0xDEADBEF0,
                              trace_options=TO_DEFAULT),
            0xDEADBEF1,
            0xDEADBEF2,
            "unsampled parent, sampling on",
        )
        self.assertTrue(no_record_always_on.sampled)
        self.assertEqual(no_record_always_on.attributes, {})