def test_span_environment_limits(self):
        reload(trace)
        tracer = new_tracer()
        id_generator = RandomIdGenerator()
        some_links = [
            trace_api.Link(
                trace_api.SpanContext(
                    trace_id=id_generator.generate_trace_id(),
                    span_id=id_generator.generate_span_id(),
                    is_remote=False,
                )
            )
            for _ in range(100)
        ]
        with pytest.raises(ValueError):
            with tracer.start_as_current_span("root", links=some_links):
                pass

        with tracer.start_as_current_span("root") as root:
            for idx in range(100):
                root.set_attribute("my_attribute_{}".format(idx), 0)
                root.add_event("my_event_{}".format(idx))

            self.assertEqual(len(root.attributes), 10)
            self.assertEqual(len(root.events), 20)
 def setUpClass(cls):
     id_generator = RandomIdGenerator()
     cls.serialized_trace_id = propagator.format_trace_id(
         id_generator.generate_trace_id())
     cls.serialized_parent_id = propagator.format_span_id(
         id_generator.generate_span_id())
     cls.serialized_origin = "origin-service"
Exemple #3
0
    async def test_trace_parent(self):
        id_generator = RandomIdGenerator()
        trace_id = format_trace_id(id_generator.generate_trace_id())
        span_id = format_span_id(id_generator.generate_span_id())
        traceparent_value = f"00-{trace_id}-{span_id}-01"

        await self.async_client.get(
            "/span_name/1234/",
            traceparent=traceparent_value,
        )
        span = self.memory_exporter.get_finished_spans()[0]

        self.assertEqual(
            trace_id,
            format_trace_id(span.get_span_context().trace_id),
        )
        self.assertIsNotNone(span.parent)
        self.assertEqual(
            trace_id,
            format_trace_id(span.parent.trace_id),
        )
        self.assertEqual(
            span_id,
            format_span_id(span.parent.span_id),
        )
        self.memory_exporter.clear()
    def __init__(
        self,
        sampler: sampling.Sampler = _TRACE_SAMPLER,
        resource: Resource = Resource.create({}),
        shutdown_on_exit: bool = True,
        active_span_processor: Union[
            SynchronousMultiSpanProcessor, ConcurrentMultiSpanProcessor
        ] = None,
        id_generator: IdGenerator = None,
        span_limits: SpanLimits = None,
    ):
        self._active_span_processor = (
            active_span_processor or SynchronousMultiSpanProcessor()
        )
        if id_generator is None:
            self.id_generator = RandomIdGenerator()
        else:
            self.id_generator = id_generator
        self._resource = resource
        self.sampler = sampler
        self._span_limits = span_limits or SpanLimits()
        self._atexit_handler = None

        if shutdown_on_exit:
            self._atexit_handler = atexit.register(self.shutdown)
    def test_sampling_priority_auto_reject(self):
        """Test sampling priority rejected."""
        parent_span_context = get_current_span(
            FORMAT.extract(
                {
                    FORMAT.TRACE_ID_KEY: self.serialized_trace_id,
                    FORMAT.PARENT_ID_KEY: self.serialized_parent_id,
                    FORMAT.SAMPLING_PRIORITY_KEY: str(constants.AUTO_REJECT),
                }, )).get_span_context()

        self.assertEqual(parent_span_context.trace_flags,
                         constants.AUTO_REJECT)

        child = trace._Span(
            "child",
            trace_api.SpanContext(
                parent_span_context.trace_id,
                RandomIdGenerator().generate_span_id(),
                is_remote=False,
                trace_flags=parent_span_context.trace_flags,
                trace_state=parent_span_context.trace_state,
            ),
            parent=parent_span_context,
        )

        child_carrier = {}
        child_context = set_span_in_context(child)
        FORMAT.inject(child_carrier, context=child_context)

        self.assertEqual(
            child_carrier[FORMAT.SAMPLING_PRIORITY_KEY],
            str(constants.AUTO_REJECT),
        )
    def test_links(self):
        id_generator = RandomIdGenerator()
        other_context1 = trace_api.SpanContext(
            trace_id=id_generator.generate_trace_id(),
            span_id=id_generator.generate_span_id(),
            is_remote=False,
        )
        other_context2 = trace_api.SpanContext(
            trace_id=id_generator.generate_trace_id(),
            span_id=id_generator.generate_span_id(),
            is_remote=False,
        )

        links = (
            trace_api.Link(other_context1),
            trace_api.Link(other_context2, {"name": "neighbor"}),
        )
        with self.tracer.start_as_current_span("root", links=links) as root:

            self.assertEqual(len(root.links), 2)
            self.assertEqual(
                root.links[0].context.trace_id, other_context1.trace_id
            )
            self.assertEqual(
                root.links[0].context.span_id, other_context1.span_id
            )
            self.assertEqual(root.links[0].attributes, None)
            self.assertEqual(
                root.links[1].context.trace_id, other_context2.trace_id
            )
            self.assertEqual(
                root.links[1].context.span_id, other_context2.span_id
            )
            self.assertEqual(root.links[1].attributes, {"name": "neighbor"})
Exemple #7
0
    def test_context_propagation(self):
        """Test the propagation of Datadog headers."""
        parent_span_context = get_current_span(
            FORMAT.extract(
                carrier_getter,
                {
                    FORMAT.TRACE_ID_KEY: self.serialized_trace_id,
                    FORMAT.PARENT_ID_KEY: self.serialized_parent_id,
                    FORMAT.SAMPLING_PRIORITY_KEY: str(constants.AUTO_KEEP),
                    FORMAT.ORIGIN_KEY: self.serialized_origin,
                },
            )).get_span_context()

        self.assertEqual(parent_span_context.trace_id,
                         int(self.serialized_trace_id))
        self.assertEqual(parent_span_context.span_id,
                         int(self.serialized_parent_id))
        self.assertEqual(parent_span_context.trace_flags, constants.AUTO_KEEP)
        self.assertEqual(
            parent_span_context.trace_state.get(constants.DD_ORIGIN),
            self.serialized_origin,
        )
        self.assertTrue(parent_span_context.is_remote)

        child = trace._Span(
            "child",
            trace_api.SpanContext(
                parent_span_context.trace_id,
                RandomIdGenerator().generate_span_id(),
                is_remote=False,
                trace_flags=parent_span_context.trace_flags,
                trace_state=parent_span_context.trace_state,
            ),
            parent=parent_span_context,
        )

        child_carrier = {}
        child_context = set_span_in_context(child)
        FORMAT.inject(dict.__setitem__, child_carrier, context=child_context)

        self.assertEqual(child_carrier[FORMAT.TRACE_ID_KEY],
                         self.serialized_trace_id)
        self.assertEqual(child_carrier[FORMAT.PARENT_ID_KEY],
                         str(child.context.span_id))
        self.assertEqual(
            child_carrier[FORMAT.SAMPLING_PRIORITY_KEY],
            str(constants.AUTO_KEEP),
        )
        self.assertEqual(child_carrier.get(FORMAT.ORIGIN_KEY),
                         self.serialized_origin)
class AwsXRayIdGenerator(IdGenerator):
    """Generates tracing IDs compatible with the AWS X-Ray tracing service. In
    the X-Ray system, the first 32 bits of the `TraceId` are the Unix epoch time
    in seconds. Since spans (AWS calls them segments) with an embedded timestamp
    more than 30 days ago are rejected, a purely random `TraceId` risks being
    rejected by the service.

    See: https://docs.aws.amazon.com/xray/latest/devguide/xray-api-sendingdata.html#xray-api-traceids
    """

    random_id_generator = RandomIdGenerator()

    def generate_span_id(self) -> int:
        return self.random_id_generator.generate_span_id()

    @staticmethod
    def generate_trace_id() -> int:
        trace_time = int(time.time())
        trace_identifier = random.getrandbits(96)
        return (trace_time << 96) + trace_identifier