async def test_distributed_tracing_sub_span(app_tracer, aiohttp_client): app, tracer = app_tracer client = await aiohttp_client(app) tracer.priority_sampler = RateSampler(1.0) # activate distributed tracing tracing_headers = { "x-datadog-trace-id": "100", "x-datadog-parent-id": "42", "x-datadog-sampling-priority": "0", } request = await client.request("GET", "/sub_span", headers=tracing_headers) assert 200 == request.status text = await request.text() assert "OK" == text # the trace is created traces = tracer.pop_traces() assert 1 == len(traces) assert 2 == len(traces[0]) span, sub_span = traces[0][0], traces[0][1] # with the right trace_id and parent_id assert 100 == span.trace_id assert 42 == span.parent_id assert 0 == span.get_metric(SAMPLING_PRIORITY_KEY) # check parenting is OK with custom sub-span created within server code assert 100 == sub_span.trace_id assert span.span_id == sub_span.parent_id assert sub_span.get_metric(SAMPLING_PRIORITY_KEY) is None
def test_distributed_tracing_sub_span(self): self.tracer.priority_sampler = RateSampler(1.0) # activate distributed tracing tracing_headers = { 'x-datadog-trace-id': '100', 'x-datadog-parent-id': '42', 'x-datadog-sampling-priority': '0', } request = yield from self.client.request('GET', '/sub_span', headers=tracing_headers) assert 200 == request.status text = yield from request.text() assert 'OK' == text # the trace is created traces = self.tracer.writer.pop_traces() assert 1 == len(traces) assert 2 == len(traces[0]) span, sub_span = traces[0][0], traces[0][1] # with the right trace_id and parent_id assert 100 == span.trace_id assert 42 == span.parent_id assert 0 == span.get_metric(SAMPLING_PRIORITY_KEY) # check parenting is OK with custom sub-span created within server code assert 100 == sub_span.trace_id assert span.span_id == sub_span.parent_id assert sub_span.get_metric(SAMPLING_PRIORITY_KEY) is None
async def test_distributed_tracing_with_sampling_false(app_tracer, aiohttp_client): app, tracer = app_tracer client = await aiohttp_client(app) tracer.priority_sampler = RateSampler(0.9) tracing_headers = { "x-datadog-trace-id": "100", "x-datadog-parent-id": "42", "x-datadog-sampling-priority": "0", } request = await client.request("GET", "/", headers=tracing_headers) assert 200 == request.status text = await request.text() assert "What's tracing?" == text # the trace is created traces = tracer.pop_traces() assert 1 == len(traces) assert 1 == len(traces[0]) span = traces[0][0] # with the right trace_id and parent_id assert 100 == span.trace_id assert 42 == span.parent_id assert 0 == span.get_metric(SAMPLING_PRIORITY_KEY)
def test_distributed_tracing_sub_span(self): self.tracer.priority_sampler = RateSampler(1.0) # activate distributed tracing tracing_headers = { 'x-datadog-trace-id': '100', 'x-datadog-parent-id': '42', 'x-datadog-sampling-priority': '0', } request = yield from self.client.request('GET', '/sub_span', headers=tracing_headers) eq_(200, request.status) text = yield from request.text() eq_("OK", text) # the trace is created traces = self.tracer.writer.pop_traces() eq_(1, len(traces)) eq_(2, len(traces[0])) span, sub_span = traces[0][0], traces[0][1] # with the right trace_id and parent_id eq_(100, span.trace_id) eq_(42, span.parent_id) eq_(0, span.get_metric(SAMPLING_PRIORITY_KEY)) # check parenting is OK with custom sub-span created within server code eq_(100, sub_span.trace_id) eq_(span.span_id, sub_span.parent_id) eq_(None, sub_span.get_metric(SAMPLING_PRIORITY_KEY))
def test_distributed_tracing_with_sampling_false(self): self.tracer.priority_sampler = RateSampler(0.9) # activate distributed tracing self.app['datadog_trace']['distributed_tracing_enabled'] = True tracing_headers = { 'x-datadog-trace-id': '100', 'x-datadog-parent-id': '42', 'x-datadog-sampling-priority': '0', } request = yield from self.client.request('GET', '/', headers=tracing_headers) eq_(200, request.status) text = yield from request.text() eq_("What's tracing?", text) # the trace is created traces = self.tracer.writer.pop_traces() eq_(1, len(traces)) eq_(1, len(traces[0])) span = traces[0][0] # with the right trace_id and parent_id eq_(100, span.trace_id) eq_(42, span.parent_id) eq_(0, span.get_metric(SAMPLING_PRIORITY_KEY))
def test_sample_rate_deviation(self): for sample_rate in [0.1, 0.25, 0.5, 1]: tracer = get_dummy_tracer() writer = tracer.writer tracer.sampler = RateSampler(sample_rate) random.seed(1234) iterations = int(1e4 / sample_rate) for i in range(iterations): span = tracer.trace(i) span.finish() samples = writer.pop() # We must have at least 1 sample, check that it has its sample rate properly assigned assert samples[0].get_metric(SAMPLE_RATE_METRIC_KEY) == sample_rate # Less than 2% deviation when "enough" iterations (arbitrary, just check if it converges) deviation = abs(len(samples) - (iterations * sample_rate)) / (iterations * sample_rate) assert deviation < 0.02, "Deviation too high %f with sample_rate %f" % ( deviation, sample_rate)
def test_sampling(self, tracer): with tracer.trace("trace1"): with tracer.trace("child"): pass sampler = DatadogSampler(default_sample_rate=1.0) tracer.configure(sampler=sampler, writer=tracer.writer) with tracer.trace("trace2"): with tracer.trace("child"): pass sampler = DatadogSampler(default_sample_rate=0.000001) tracer.configure(sampler=sampler, writer=tracer.writer) with tracer.trace("trace3"): with tracer.trace("child"): pass sampler = DatadogSampler(default_sample_rate=1, rules=[SamplingRule(1.0)]) tracer.configure(sampler=sampler, writer=tracer.writer) with tracer.trace("trace4"): with tracer.trace("child"): pass sampler = DatadogSampler(default_sample_rate=1, rules=[SamplingRule(0)]) tracer.configure(sampler=sampler, writer=tracer.writer) with tracer.trace("trace5"): with tracer.trace("child"): pass sampler = DatadogSampler(default_sample_rate=1) tracer.configure(sampler=sampler, writer=tracer.writer) with tracer.trace("trace6"): with tracer.trace("child") as span: span.set_tag(MANUAL_DROP_KEY) sampler = DatadogSampler(default_sample_rate=1) tracer.configure(sampler=sampler, writer=tracer.writer) with tracer.trace("trace7"): with tracer.trace("child") as span: span.set_tag(MANUAL_KEEP_KEY) sampler = RateSampler(0.0000000001) tracer.configure(sampler=sampler, writer=tracer.writer) # This trace should not appear in the snapshot with tracer.trace("trace8"): with tracer.trace("child"): pass tracer.shutdown()
def test_set_sample_rate(self): sampler = RateSampler() assert sampler.sample_rate == 1.0 for rate in [0.001, 0.01, 0.1, 0.25, 0.5, 0.75, 0.99999999, 1.0, 1]: sampler.set_sample_rate(rate) assert sampler.sample_rate == float(rate) sampler.set_sample_rate(str(rate)) assert sampler.sample_rate == float(rate)
def test_deterministic_behavior(self): """ Test that for a given trace ID, the result is always the same """ tracer = DummyTracer() tracer.sampler = RateSampler(0.5) for i in range(10): span = tracer.trace(i) span.finish() samples = tracer.pop() assert len(samples) <= 1, "there should be 0 or 1 spans" sampled = 1 == len(samples) for j in range(10): other_span = Span(tracer, i, trace_id=span.trace_id) assert sampled == tracer.sampler.sample( other_span ), "sampling should give the same result for a given trace_id"
def test_deterministic_behavior(self): """ Test that for a given trace ID, the result is always the same """ tracer = get_dummy_tracer() writer = tracer.writer tracer.sampler = RateSampler(0.5) for i in range(10): span = tracer.trace(i) span.finish() samples = writer.pop() assert len(samples) <= 1, 'there should be 0 or 1 spans' sampled = (1 == len(samples)) for j in range(10): other_span = Span(tracer, i, trace_id=span.trace_id) assert ( sampled == tracer.sampler.sample(other_span) ), 'sampling should give the same result for a given trace_id'
def test_distributed_tracing_with_sampling_false(self): self.tracer.priority_sampler = RateSampler(0.9) tracing_headers = { 'x-datadog-trace-id': '100', 'x-datadog-parent-id': '42', 'x-datadog-sampling-priority': '0', } request = yield from self.client.request('GET', '/', headers=tracing_headers) assert 200 == request.status text = yield from request.text() assert "What's tracing?" == text # the trace is created traces = self.tracer.writer.pop_traces() assert 1 == len(traces) assert 1 == len(traces[0]) span = traces[0][0] # with the right trace_id and parent_id assert 100 == span.trace_id assert 42 == span.parent_id assert 0 == span.get_metric(SAMPLING_PRIORITY_KEY)
def test_distributed_tracing_with_sampling_true(self): self.tracer.priority_sampler = RateSampler(0.1) tracing_headers = { "x-datadog-trace-id": "100", "x-datadog-parent-id": "42", "x-datadog-sampling-priority": "1", } request = yield from self.client.request("GET", "/", headers=tracing_headers) assert 200 == request.status text = yield from request.text() assert "What's tracing?" == text # the trace is created traces = self.pop_traces() assert 1 == len(traces) assert 1 == len(traces[0]) span = traces[0][0] # with the right trace_id and parent_id assert 100 == span.trace_id assert 42 == span.parent_id assert 1 == span.get_metric(SAMPLING_PRIORITY_KEY)
def test_set_sample_rate_str(self): sampler = RateSampler() sampler.set_sample_rate("0.5") assert sampler.sample_rate == 0.5
def test_sample_rate_0_does_not_reset_to_1(self): # Regression test for case where a sample rate of 0 caused the sample rate to be reset to 1 tracer = DummyTracer() tracer.sampler = RateSampler(sample_rate=0) assert tracer.sampler.sample_rate == 0
def test_negative_sample_rate_raises_error(self): tracer = DummyTracer() with pytest.raises(ValueError, match="sample_rate of -0.5 is negative"): tracer.sampler = RateSampler(sample_rate=-0.5)
def test_sampling(writer, tracer): if writer == "sync": writer = AgentWriter( tracer.writer.agent_url, priority_sampler=tracer.priority_sampler, sync_mode=True, ) # Need to copy the headers which contain the test token to associate # traces with this test case. writer._headers = tracer.writer._headers else: writer = tracer.writer tracer.configure(writer=writer) with tracer.trace("trace1"): with tracer.trace("child"): pass sampler = DatadogSampler(default_sample_rate=1.0) tracer.configure(sampler=sampler, writer=writer) with tracer.trace("trace2"): with tracer.trace("child"): pass sampler = DatadogSampler(default_sample_rate=0.000001) tracer.configure(sampler=sampler, writer=writer) with tracer.trace("trace3"): with tracer.trace("child"): pass sampler = DatadogSampler(default_sample_rate=1, rules=[SamplingRule(1.0)]) tracer.configure(sampler=sampler, writer=writer) with tracer.trace("trace4"): with tracer.trace("child"): pass sampler = DatadogSampler(default_sample_rate=1, rules=[SamplingRule(0)]) tracer.configure(sampler=sampler, writer=writer) with tracer.trace("trace5"): with tracer.trace("child"): pass sampler = DatadogSampler(default_sample_rate=1) tracer.configure(sampler=sampler, writer=writer) with tracer.trace("trace6"): with tracer.trace("child") as span: span.set_tag(MANUAL_DROP_KEY) sampler = DatadogSampler(default_sample_rate=1) tracer.configure(sampler=sampler, writer=writer) with tracer.trace("trace7"): with tracer.trace("child") as span: span.set_tag(MANUAL_KEEP_KEY) sampler = RateSampler(0.0000000001) tracer.configure(sampler=sampler, writer=writer) # This trace should not appear in the snapshot with tracer.trace("trace8"): with tracer.trace("child"): pass tracer.shutdown()