Example #1
0
def test_datadog_sampler_init():
    # No args
    sampler = DatadogSampler()
    assert sampler.rules == []
    assert isinstance(sampler.limiter, RateLimiter)
    assert sampler.limiter.rate_limit == DatadogSampler.DEFAULT_RATE_LIMIT

    # With rules
    rule = SamplingRule(sample_rate=1)
    sampler = DatadogSampler(rules=[rule])
    assert sampler.rules == [rule]
    assert sampler.limiter.rate_limit == DatadogSampler.DEFAULT_RATE_LIMIT

    # With rate limit
    sampler = DatadogSampler(rate_limit=10)
    assert sampler.limiter.rate_limit == 10

    # Invalid rules
    for val in (None, True, False, object(), 1, Exception()):
        with pytest.raises(TypeError):
            DatadogSampler(rules=[val])

    # Ensure rule order
    rule_1 = SamplingRule(sample_rate=1)
    rule_2 = SamplingRule(sample_rate=0.5, service='test')
    rule_3 = SamplingRule(sample_rate=0.25, name='flask.request')
    sampler = DatadogSampler(rules=[rule_1, rule_2, rule_3])
    assert sampler.rules == [rule_1, rule_2, rule_3]
Example #2
0
def test_sampling_rule_init_sample_rate(sample_rate, allowed):
    if allowed:
        rule = SamplingRule(sample_rate=sample_rate)
        assert rule.sample_rate == sample_rate
    else:
        with pytest.raises(ValueError):
            SamplingRule(sample_rate=sample_rate)
Example #3
0
def test_sampling_rule_sample_rate_1():
    tracer = DummyTracer()
    rule = SamplingRule(sample_rate=1)

    iterations = int(1e4)
    assert all(
        rule.sample(Span(tracer=tracer, name=i)) for i in range(iterations))
Example #4
0
def test_sampling_rule_sample_rate_0():
    tracer = get_dummy_tracer()
    rule = SamplingRule(sample_rate=0)

    iterations = int(1e4)
    assert sum(
        rule.sample(Span(tracer=tracer, name=i))
        for i in range(iterations)) == 0
Example #5
0
def test_datadog_sampler_init():
    # No args
    sampler = DatadogSampler()
    assert sampler.rules == []
    assert isinstance(sampler.limiter, RateLimiter)
    assert sampler.limiter.rate_limit == DatadogSampler.DEFAULT_RATE_LIMIT
    assert isinstance(sampler.default_sampler, RateByServiceSampler)

    # With rules
    rule = SamplingRule(sample_rate=1)
    sampler = DatadogSampler(rules=[rule])
    assert sampler.rules == [rule]
    assert sampler.limiter.rate_limit == DatadogSampler.DEFAULT_RATE_LIMIT
    assert isinstance(sampler.default_sampler, RateByServiceSampler)

    # With rate limit
    sampler = DatadogSampler(rate_limit=10)
    assert sampler.limiter.rate_limit == 10
    assert isinstance(sampler.default_sampler, RateByServiceSampler)

    # With default_sample_rate
    sampler = DatadogSampler(default_sample_rate=0.5)
    assert sampler.limiter.rate_limit == DatadogSampler.DEFAULT_RATE_LIMIT
    assert isinstance(sampler.default_sampler, SamplingRule)
    assert sampler.default_sampler.sample_rate == 0.5

    # From env variables
    with override_env(
            dict(DD_TRACE_SAMPLE_RATE="0.5", DD_TRACE_RATE_LIMIT="10")):
        sampler = DatadogSampler()
        assert sampler.limiter.rate_limit == 10
        assert isinstance(sampler.default_sampler, SamplingRule)
        assert sampler.default_sampler.sample_rate == 0.5

    # Invalid env vars
    with override_env(dict(DD_TRACE_SAMPLE_RATE="asdf")):
        with pytest.raises(ValueError):
            DatadogSampler()

    # Invalid env vars
    with override_env(dict(DD_TRACE_RATE_LIMIT="asdf")):
        with pytest.raises(ValueError):
            DatadogSampler()

    # Invalid rules
    for val in (None, True, False, object(), 1, Exception()):
        with pytest.raises(TypeError):
            DatadogSampler(rules=[val])

    # Ensure rule order
    rule_1 = SamplingRule(sample_rate=1)
    rule_2 = SamplingRule(sample_rate=0.5, service="test")
    rule_3 = SamplingRule(sample_rate=0.25, name="flask.request")
    sampler = DatadogSampler(rules=[rule_1, rule_2, rule_3])
    assert sampler.rules == [rule_1, rule_2, rule_3]
Example #6
0
def test_sampling_rule_sample(sample_rate):
    rule = SamplingRule(sample_rate=sample_rate)

    iterations = int(1e4 / sample_rate)
    sampled = sum(rule.sample(Span(name=str(i))) for i in range(iterations))

    # Less than 5% deviation when 'enough' iterations (arbitrary, just check if it converges)
    deviation = abs(sampled -
                    (iterations * sample_rate)) / (iterations * sample_rate)
    assert deviation < 0.05, "Deviation {!r} too high with sample_rate {!r} for {} sampled".format(
        deviation, sample_rate, sampled)
Example #7
0
    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()
Example #8
0
def test_datadog_sampler_tracer_rate_limited(dummy_tracer):
    rule = SamplingRule(sample_rate=1.0, name='test.span')
    rule_spy = mock.Mock(spec=rule, wraps=rule)
    rule_spy.sample_rate = rule.sample_rate

    sampler = DatadogSampler(rules=[rule_spy])
    limiter_spy = mock.Mock(spec=sampler.limiter, wraps=sampler.limiter)
    limiter_spy.is_allowed.return_value = False  # Have the limiter deny the span
    sampler.limiter = limiter_spy
    sampler_spy = mock.Mock(spec=sampler, wraps=sampler)

    dummy_tracer.configure(sampler=sampler_spy)

    assert dummy_tracer.sampler is sampler_spy

    with dummy_tracer.trace('test.span') as span:
        # Assert all of our expected functions were called
        sampler_spy.sample.assert_called_once_with(span)
        rule_spy.matches.assert_called_once_with(span)
        rule_spy.sample.assert_called_once_with(span)
        limiter_spy.is_allowed.assert_called_once_with()

        # We know it was not sampled because of our limiter
        assert span.sampled is False
        assert span._context.sampling_priority is AUTO_REJECT
        assert_sampling_decision_tags(span, rule=1.0, limit=None)
Example #9
0
def test_datadog_sampler_tracer(dummy_tracer):
    rule = SamplingRule(sample_rate=1.0, name='test.span')
    rule_spy = mock.Mock(spec=rule, wraps=rule)
    rule_spy.sample_rate = rule.sample_rate

    sampler = DatadogSampler(rules=[rule_spy])
    limiter_spy = mock.Mock(spec=sampler.limiter, wraps=sampler.limiter)
    sampler.limiter = limiter_spy
    sampler_spy = mock.Mock(spec=sampler, wraps=sampler)

    dummy_tracer.configure(sampler=sampler_spy)

    assert dummy_tracer.sampler is sampler_spy

    with dummy_tracer.trace('test.span') as span:
        # Assert all of our expected functions were called
        sampler_spy.sample.assert_called_once_with(span)
        rule_spy.matches.assert_called_once_with(span)
        rule_spy.sample.assert_called_once_with(span)
        limiter_spy.is_allowed.assert_called_once_with()

        # We know it was sampled because we have a sample rate of 1.0
        assert span.sampled is True
        assert span._context.sampling_priority is AUTO_KEEP
        assert_sampling_decision_tags(span, rule=1.0)
Example #10
0
    def run(self):
        # Generate random service and operation names for the counts we requested
        services = [rands() for _ in range(self.num_services)]
        operation_names = [rands() for _ in range(self.num_operations)]

        # Generate all possible permutations of service and operation names
        spans = [
            Span(tracer=None, service=service, name=name)
            for service, name in itertools.product(services, operation_names)
        ]

        # Create a single rule to use for all matches
        # Pick a random service/operation name
        rule = SamplingRule(
            service=random.choice(services),
            name=random.choice(operation_names),
            sample_rate=1.0,
        )

        def _(loops):
            for _ in range(loops):
                for span in iter_n(spans, n=self.num_iterations):
                    rule.matches(span)

        yield _
Example #11
0
def test_datadog_sampler_tracer_rate_0(dummy_tracer):
    rule = SamplingRule(
        sample_rate=0, name='test.span')  # Sample rate of 0 means never sample
    rule_spy = mock.Mock(spec=rule, wraps=rule)
    rule_spy.sample_rate = rule.sample_rate

    sampler = DatadogSampler(rules=[rule_spy])
    limiter_spy = mock.Mock(spec=sampler.limiter, wraps=sampler.limiter)
    sampler.limiter = limiter_spy
    sampler_spy = mock.Mock(spec=sampler, wraps=sampler)

    # TODO: Remove `priority_sampling=False` when we remove fallback
    dummy_tracer.configure(sampler=sampler_spy, priority_sampling=False)

    assert dummy_tracer.sampler is sampler_spy

    with dummy_tracer.trace('test.span') as span:
        # Assert all of our expected functions were called
        sampler_spy.sample.assert_called_once_with(span)
        rule_spy.matches.assert_called_once_with(span)
        rule_spy.sample.assert_called_once_with(span)
        limiter_spy.is_allowed.assert_not_called()

        # We know it was not sampled because we have a sample rate of 0.0
        assert span.sampled is False
        assert span._context.sampling_priority is AUTO_REJECT
        assert_sampling_decision_tags(span, rule=0)
Example #12
0
def test_datadog_sampler_tracer_child(dummy_tracer):
    rule = SamplingRule(
        sample_rate=1.0)  # No rules means it gets applied to every span
    rule_spy = mock.Mock(spec=rule, wraps=rule)
    rule_spy.sample_rate = rule.sample_rate

    sampler = DatadogSampler(rules=[rule_spy])
    limiter_spy = mock.Mock(spec=sampler.limiter, wraps=sampler.limiter)
    sampler.limiter = limiter_spy
    sampler_spy = mock.Mock(spec=sampler, wraps=sampler)

    # TODO: Remove `priority_sampling=False` when we remove fallback
    dummy_tracer.configure(sampler=sampler_spy, priority_sampling=False)

    assert dummy_tracer.sampler is sampler_spy

    with dummy_tracer.trace('parent.span') as parent:
        with dummy_tracer.trace('child.span') as child:
            # Assert all of our expected functions were called
            # DEV: `assert_called_once_with` ensures we didn't also call with the child span
            sampler_spy.sample.assert_called_once_with(parent)
            rule_spy.matches.assert_called_once_with(parent)
            rule_spy.sample.assert_called_once_with(parent)
            limiter_spy.is_allowed.assert_called_once_with()

            # We know it was sampled because we have a sample rate of 1.0
            assert parent.sampled is True
            assert parent._context.sampling_priority is AUTO_KEEP
            assert_sampling_decision_tags(parent, rule=1.0)

            assert child.sampled is True
            assert child._parent is parent
            assert child._context.sampling_priority is AUTO_KEEP
Example #13
0
def test_datadog_sampler_tracer_start_span(dummy_tracer):
    rule = SamplingRule(
        sample_rate=1.0)  # No rules means it gets applied to every span
    rule_spy = mock.Mock(spec=rule, wraps=rule)
    rule_spy.sample_rate = rule.sample_rate

    sampler = DatadogSampler(rules=[rule_spy])
    limiter_spy = mock.Mock(spec=sampler.limiter, wraps=sampler.limiter)
    sampler.limiter = limiter_spy
    sampler_spy = mock.Mock(spec=sampler, wraps=sampler)

    # TODO: Remove `priority_sampling=False` when we remove fallback
    dummy_tracer.configure(sampler=sampler_spy, priority_sampling=False)

    assert dummy_tracer.sampler is sampler_spy

    span = dummy_tracer.start_span('test.span')

    # Assert all of our expected functions were called
    sampler_spy.sample.assert_called_once_with(span)
    rule_spy.matches.assert_called_once_with(span)
    rule_spy.sample.assert_called_once_with(span)
    limiter_spy.is_allowed.assert_called_once_with()

    # We know it was sampled because we have a sample rate of 1.0
    assert span.sampled is True
    assert span._context.sampling_priority is AUTO_KEEP
    assert_sampling_decision_tags(span, rule=1.0)
Example #14
0
def test_datadog_sampler_tracer_rate_0(dummy_tracer):
    rule = SamplingRule(
        sample_rate=0, name="test.span")  # Sample rate of 0 means never sample
    rule_spy = mock.Mock(spec=rule, wraps=rule)
    rule_spy.sample_rate = rule.sample_rate

    sampler = DatadogSampler(rules=[rule_spy])
    limiter_spy = mock.Mock(spec=sampler.limiter, wraps=sampler.limiter)
    sampler.limiter = limiter_spy
    sampler_spy = mock.Mock(spec=sampler, wraps=sampler)

    dummy_tracer.configure(sampler=sampler_spy)

    assert dummy_tracer.sampler is sampler_spy

    with dummy_tracer.trace("test.span") as span:
        # Assert all of our expected functions were called
        sampler_spy.sample.assert_called_once_with(span)
        rule_spy.matches.assert_called_once_with(span)
        rule_spy.sample.assert_called_once_with(span)
        limiter_spy.is_allowed.assert_not_called()

    spans = dummy_tracer.pop()
    assert len(spans) == 1, "Span should have been sampled and written"
    assert spans[0].get_metric(SAMPLING_PRIORITY_KEY) is AUTO_REJECT
    assert spans[0].get_metric(SAMPLING_RULE_DECISION) == 0
Example #15
0
def test_datadog_sampler_tracer_child(dummy_tracer):
    rule = SamplingRule(
        sample_rate=1.0)  # No rules means it gets applied to every span
    rule_spy = mock.Mock(spec=rule, wraps=rule)
    rule_spy.sample_rate = rule.sample_rate

    sampler = DatadogSampler(rules=[rule_spy])
    limiter_spy = mock.Mock(spec=sampler.limiter, wraps=sampler.limiter)
    sampler.limiter = limiter_spy
    sampler_spy = mock.Mock(spec=sampler, wraps=sampler)

    dummy_tracer.configure(sampler=sampler_spy)

    assert dummy_tracer.sampler is sampler_spy

    with dummy_tracer.trace("parent.span") as parent:
        with dummy_tracer.trace("child.span"):
            # Assert all of our expected functions were called
            # DEV: `assert_called_once_with` ensures we didn't also call with the child span
            sampler_spy.sample.assert_called_once_with(parent)
            rule_spy.matches.assert_called_once_with(parent)
            rule_spy.sample.assert_called_once_with(parent)
            limiter_spy.is_allowed.assert_called_once_with()

    spans = dummy_tracer.pop()
    assert len(spans) == 2, "Trace should have been sampled and written"
    assert spans[0].get_metric(SAMPLING_PRIORITY_KEY) is AUTO_KEEP
    assert spans[0].get_metric(SAMPLING_RULE_DECISION) == 1.0
Example #16
0
def test_datadog_sampler_tracer_start_span(dummy_tracer):
    rule = SamplingRule(
        sample_rate=1.0)  # No rules means it gets applied to every span
    rule_spy = mock.Mock(spec=rule, wraps=rule)
    rule_spy.sample_rate = rule.sample_rate

    sampler = DatadogSampler(rules=[rule_spy])
    limiter_spy = mock.Mock(spec=sampler.limiter, wraps=sampler.limiter)
    sampler.limiter = limiter_spy
    sampler_spy = mock.Mock(spec=sampler, wraps=sampler)

    dummy_tracer.configure(sampler=sampler_spy)

    assert dummy_tracer.sampler is sampler_spy

    span = dummy_tracer.start_span("test.span")
    span.finish()

    # Assert all of our expected functions were called
    sampler_spy.sample.assert_called_once_with(span)
    rule_spy.matches.assert_called_once_with(span)
    rule_spy.sample.assert_called_once_with(span)
    limiter_spy.is_allowed.assert_called_once_with()

    spans = dummy_tracer.pop()
    assert len(spans) == 1, "Span should have been sampled and written"
    assert spans[0].get_metric(SAMPLING_PRIORITY_KEY) is AUTO_KEEP
    assert spans[0].get_metric(SAMPLING_RULE_DECISION) == 1.0
Example #17
0
def test_sampling_rule_matches_exception():
    e = Exception("an error occurred")

    def pattern(prop):
        raise e

    rule = SamplingRule(sample_rate=1.0, name=pattern)
    span = create_span(name="test.span")

    with mock.patch("ddtrace.sampler.log") as mock_log:
        assert rule.matches(span) is False
        mock_log.warning.assert_called_once_with(
            "%r pattern %r failed with %r",
            rule,
            pattern,
            "test.span",
            exc_info=True,
        )
Example #18
0
def test_sampling_rule_matches_exception():
    e = Exception('an error occurred')

    def pattern(prop):
        raise e

    rule = SamplingRule(sample_rate=1.0, name=pattern)
    span = create_span(name='test.span')

    with mock.patch('ddtrace.sampler.log') as mock_log:
        assert rule.matches(span) is False
        mock_log.warning.assert_called_once_with(
            '%r pattern %r failed with %r: %s',
            rule,
            pattern,
            'test.span',
            e,
        )
Example #19
0
        def reset():
            mock_is_allowed.reset_mock()
            for rule in rules:
                rule.reset_mock()
                rule.sample_rate = 0.5

            default_rule = SamplingRule(sample_rate=1.0)
            sampler.default_sampler = mock.Mock(spec=SamplingRule, wraps=default_rule)
            # Mock has lots of problems with mocking/wrapping over class properties
            sampler.default_sampler.sample_rate = default_rule.sample_rate
Example #20
0
def test_datadog_sampler_tracer_rate_limited(dummy_tracer):
    rule = SamplingRule(sample_rate=1.0, name="test.span")
    sampler = DatadogSampler(rules=[rule], rate_limit=0)
    dummy_tracer.configure(sampler=sampler)

    with dummy_tracer.trace("test.span"):
        pass

    spans = dummy_tracer.pop()
    assert len(spans) == 1, "Span should have been sampled and written"
    assert spans[0].get_metric(SAMPLING_PRIORITY_KEY) is USER_REJECT
    assert_sampling_decision_tags(spans[0], rule=1.0, limit=0.0)
Example #21
0
def test_datadog_sampler_tracer_start_span(dummy_tracer):
    # No rules means it gets applied to every span
    rule = SamplingRule(sample_rate=1.0)
    sampler = DatadogSampler(rules=[rule])
    dummy_tracer.configure(sampler=sampler)

    span = dummy_tracer.start_span("test.span")
    span.finish()

    spans = dummy_tracer.pop()
    assert len(spans) == 1, "Span should have been sampled and written"
    assert spans[0].get_metric(SAMPLING_PRIORITY_KEY) is USER_KEEP
    assert_sampling_decision_tags(spans[0], rule=1.0, limit=None)
Example #22
0
def test_sampling_rule_init():
    name_regex = re.compile(r"\.request$")

    rule = SamplingRule(
        sample_rate=0.0,
        # Value
        service="my-service",
        # Regex
        name=name_regex,
    )

    assert rule.sample_rate == 0.0
    assert rule.service == "my-service"
    assert rule.name == name_regex
Example #23
0
def test_datadog_sampler_tracer_child(dummy_tracer):
    # No rules means it gets applied to every span
    rule = SamplingRule(sample_rate=1.0)
    sampler = DatadogSampler(rules=[rule])
    dummy_tracer.configure(sampler=sampler)

    with dummy_tracer.trace("parent.span"):
        with dummy_tracer.trace("child.span"):
            pass

    spans = dummy_tracer.pop()
    assert len(spans) == 2, "Trace should have been sampled and written"
    assert spans[0].get_metric(SAMPLING_PRIORITY_KEY) is USER_KEEP
    assert_sampling_decision_tags(spans[0], rule=1.0, limit=None)
    assert_sampling_decision_tags(spans[1], agent=None, rule=None, limit=None)
Example #24
0
def test_sampling_rule_init():
    name_regex = re.compile(r'\.request$')

    def resource_check(resource):
        return 'healthcheck' in resource

    rule = SamplingRule(
        sample_rate=0.0,
        # Value
        service='my-service',
        # Regex
        name=name_regex,
    )

    assert rule.sample_rate == 0.0
    assert rule.service == 'my-service'
    assert rule.name == name_regex
Example #25
0
        # Value
        service='my-service',
        # Regex
        name=name_regex,
    )

    assert rule.sample_rate == 0.0
    assert rule.service == 'my-service'
    assert rule.name == name_regex


@pytest.mark.parametrize(
    'span,rule,expected',
    [
        # DEV: Use sample_rate=1 to ensure SamplingRule._sample always returns True
        (create_span(name=name), SamplingRule(sample_rate=1,
                                              name=pattern), expected)
        for name, pattern, expected in [
            ('test.span', SamplingRule.NO_RULE, True),
            # DEV: `span.name` cannot be `None`
            ('test.span', None, False),
            ('test.span', 'test.span', True),
            ('test.span', 'test_span', False),
            ('test.span', re.compile(r'^test\.span$'), True),
            ('test_span', re.compile(r'^test.span$'), True),
            ('test.span', re.compile(r'^test_span$'), False),
            ('test.span', re.compile(r'test'), True),
            ('test.span', re.compile(r'test\.span|another\.span'), True),
            ('another.span', re.compile(r'test\.span|another\.span'), True),
            ('test.span', lambda name: 'span' in name, True),
            ('test.span', lambda name: 'span' not in name, False),
            ('test.span', lambda name: 1 / 0, False),
Example #26
0
def test_sampling_rule_sample_rate_0():
    rule = SamplingRule(sample_rate=0)

    iterations = int(1e4)
    assert sum(rule.sample(Span(name=str(i))) for i in range(iterations)) == 0
Example #27
0
        # Value
        service="my-service",
        # Regex
        name=name_regex,
    )

    assert rule.sample_rate == 0.0
    assert rule.service == "my-service"
    assert rule.name == name_regex


@pytest.mark.parametrize(
    "rule_1,rule_2,expected",
    [
        # Sample rate only
        (SamplingRule(sample_rate=1.0), SamplingRule(sample_rate=1.0), True),
        (SamplingRule(sample_rate=0.5), SamplingRule(sample_rate=0.5), True),
        (SamplingRule(sample_rate=0.0), SamplingRule(sample_rate=0.0), True),
        (SamplingRule(sample_rate=0.5), SamplingRule(sample_rate=1.0), False),
        # Sample rate, and service name
        (SamplingRule(sample_rate=1.0, service="my-svc"),
         SamplingRule(sample_rate=1.0, service="my-svc"), True),
        (
            SamplingRule(sample_rate=1.0, service=re.compile("my-svc")),
            SamplingRule(sample_rate=1.0, service=re.compile("my-svc")),
            True,
        ),
        (SamplingRule(sample_rate=1.0, service="my-svc"),
         SamplingRule(sample_rate=1.0, service="other-svc"), False),
        (SamplingRule(sample_rate=1.0, service="my-svc"),
         SamplingRule(sample_rate=0.5, service="my-svc"), False),
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()
Example #29
0
def test_sampling_rule_init_defaults():
    rule = SamplingRule(sample_rate=1.0)
    assert rule.sample_rate == 1.0
    assert rule.service == SamplingRule.NO_RULE
    assert rule.name == SamplingRule.NO_RULE
Example #30
0
        # Value
        service="my-service",
        # Regex
        name=name_regex,
    )

    assert rule.sample_rate == 0.0
    assert rule.service == "my-service"
    assert rule.name == name_regex


@pytest.mark.parametrize(
    "span,rule,expected",
    [
        # DEV: Use sample_rate=1 to ensure SamplingRule._sample always returns True
        (create_span(name=name), SamplingRule(sample_rate=1,
                                              name=pattern), expected)
        for name, pattern, expected in [
            ("test.span", SamplingRule.NO_RULE, True),
            # DEV: `span.name` cannot be `None`
            ("test.span", None, False),
            ("test.span", "test.span", True),
            ("test.span", "test_span", False),
            ("test.span", re.compile(r"^test\.span$"), True),
            ("test_span", re.compile(r"^test.span$"), True),
            ("test.span", re.compile(r"^test_span$"), False),
            ("test.span", re.compile(r"test"), True),
            ("test.span", re.compile(r"test\.span|another\.span"), True),
            ("another.span", re.compile(r"test\.span|another\.span"), True),
            ("test.span", lambda name: "span" in name, True),
            ("test.span", lambda name: "span" not in name, False),
            ("test.span", lambda name: 1 / 0, False),