def test_span_environment_limits(self): reload(trace) tracer = new_tracer() ids_generator = RandomIdsGenerator() some_links = [ trace_api.Link( trace_api.SpanContext( trace_id=ids_generator.generate_trace_id(), span_id=ids_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): ids_generator = RandomIdsGenerator() cls.serialized_trace_id = propagator.format_trace_id( ids_generator.generate_trace_id()) cls.serialized_parent_id = propagator.format_span_id( ids_generator.generate_span_id()) cls.serialized_origin = "origin-service"
def test_sampling_priority_auto_reject(self): """Test sampling priority rejected.""" 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_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, RandomIdsGenerator().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.SAMPLING_PRIORITY_KEY], str(constants.AUTO_REJECT), )
def test_links(self): ids_generator = RandomIdsGenerator() other_context1 = trace_api.SpanContext( trace_id=ids_generator.generate_trace_id(), span_id=ids_generator.generate_span_id(), is_remote=False, ) other_context2 = trace_api.SpanContext( trace_id=ids_generator.generate_trace_id(), span_id=ids_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"})
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, RandomIdsGenerator().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)
def __init__( self, sampler: sampling.Sampler = TRACE_SAMPLER, resource: Resource = Resource.create({}), shutdown_on_exit: bool = True, active_span_processor: Union[SynchronousMultiSpanProcessor, ConcurrentMultiSpanProcessor] = None, ids_generator: IdsGenerator = None, ): self._active_span_processor = (active_span_processor or SynchronousMultiSpanProcessor()) if ids_generator is None: self.ids_generator = RandomIdsGenerator() else: self.ids_generator = ids_generator self.resource = resource self.sampler = sampler self._atexit_handler = None if shutdown_on_exit: self._atexit_handler = atexit.register(self.shutdown)
class AwsXRayIdsGenerator(IdsGenerator): """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_ids_generator = RandomIdsGenerator() def generate_span_id(self) -> int: return self.random_ids_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