Skip to content

Commit 6ad4124

Browse files
chore: add debug logs to sampling rules (#14549)
Add logs to sampling rules to more easily debug sampling mechanism and sampling rate, especially in cases where the sampling rules may get reset / recreated. ## Checklist - [x] PR author has checked that all the criteria below are met - The PR description includes an overview of the change - The PR description articulates the motivation for the change - The change includes tests OR the PR description describes a testing strategy - The PR description notes risks associated with the change, if any - Newly-added code is easy to change - The change follows the [library release note guidelines](https://ddtrace.readthedocs.io/en/stable/releasenotes.html) - The change includes or references documentation updates if necessary - Backport labels are set (if [applicable](https://ddtrace.readthedocs.io/en/latest/contributing.html#backporting)) ## Reviewer Checklist - [ ] Reviewer has checked that all the criteria below are met - Title is accurate - All changes are related to the pull request's stated goal - Avoids breaking [API](https://ddtrace.readthedocs.io/en/stable/versioning.html#interfaces) changes - Testing strategy adequately addresses listed risks - Newly-added code is easy to change - Release note makes sense to a user of the library - If necessary, author has acknowledged and discussed the performance implications of this PR as reported in the benchmarks PR comment - Backport labels are set in a manner that is consistent with the [release branch maintenance policy](https://ddtrace.readthedocs.io/en/latest/contributing.html#backporting) --------- Co-authored-by: Brett Langdon <brett.langdon@datadoghq.com>
1 parent 9f9fde0 commit 6ad4124

File tree

6 files changed

+33
-7
lines changed

6 files changed

+33
-7
lines changed

ddtrace/_trace/processor/__init__.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
from ddtrace.internal.constants import HIGHER_ORDER_TRACE_ID_BITS
2020
from ddtrace.internal.constants import LAST_DD_PARENT_ID_KEY
2121
from ddtrace.internal.constants import MAX_UINT_64BITS
22+
from ddtrace.internal.constants import SAMPLING_DECISION_TRACE_TAG_KEY
2223
from ddtrace.internal.constants import SamplingMechanism
2324
from ddtrace.internal.logger import get_logger
2425
from ddtrace.internal.rate_limiter import RateLimiter
@@ -280,7 +281,7 @@ class SpanAggregator(SpanProcessor):
280281
SPAN_FINISH_DEBUG_MESSAGE = (
281282
"Encoding %d spans. Spans processed: %d. Spans dropped by trace processors: %d. Unfinished "
282283
"spans remaining in the span aggregator: %d. (trace_id: %d) (top level span: name=%s) "
283-
"(partial flush triggered: %s)"
284+
"(sampling_priority: %s) (sampling_mechanism: %s) (partial flush triggered: %s)"
284285
)
285286

286287
SPAN_START_DEBUG_MESSAGE = "Starting span: %s, trace has %d spans in the span aggregator"
@@ -390,6 +391,11 @@ def on_span_finish(self, span: Span) -> None:
390391
log.error("error applying processor %r to trace %d", tp, span.trace_id, exc_info=True)
391392

392393
if spans:
394+
# Get sampling information from the root span
395+
root_span = spans[0]._local_root
396+
sampling_priority = root_span.context.sampling_priority
397+
sampling_mechanism = root_span.context._meta.get(SAMPLING_DECISION_TRACE_TAG_KEY, "None")
398+
393399
log.debug(
394400
self.SPAN_FINISH_DEBUG_MESSAGE,
395401
len(spans),
@@ -398,6 +404,8 @@ def on_span_finish(self, span: Span) -> None:
398404
num_buffered - num_finished,
399405
spans[0].trace_id,
400406
spans[0].name,
407+
sampling_priority,
408+
sampling_mechanism,
401409
should_partial_flush,
402410
)
403411
self.writer.write(spans)

ddtrace/_trace/product.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -182,7 +182,12 @@ def _apply_config_change(config_name, config_value, dd_config):
182182

183183
if config_name == "_trace_sampling_rules":
184184
tracer._sampler.set_sampling_rules(config_value)
185-
log.debug("Updated tracer sampling rules via remote_config: %s", config_value)
185+
log.debug(
186+
"Updated tracer sampler (id: %s, rules: %s) sampling rules via remote_config: %s.",
187+
id(tracer._sampler),
188+
tracer._sampler.rules,
189+
config_value,
190+
)
186191
elif config_name == "tags":
187192
tracer._tags = (config_value or {}).copy()
188193
log.debug("Updated tracer tags via remote_config: %s", tracer._tags)

ddtrace/_trace/sampler.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ class DatadogSampler:
8282

8383
SAMPLE_DEBUG_MESSAGE = (
8484
"Sampling decision applied to %s: sampled=%s sample_rate=%s sampling_mechanism=%s "
85-
"matched_trace_sampling_rule=%s agent_sampled=%s"
85+
"matched_trace_sampling_rule=%s agent_sampled=%s rules=%s sampler_id=%s"
8686
)
8787

8888
def __init__(
@@ -197,7 +197,9 @@ def sample(self, span: Span) -> bool:
197197
sample_rate,
198198
sampling_mechanism,
199199
matched_rule,
200-
agent_sampler is not None,
200+
str(agent_sampler) if agent_sampler is not None else "None",
201+
str(self.rules) if self.rules is not None else "None",
202+
id(self),
201203
)
202204
return sampled
203205

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
---
2+
other:
3+
- |
4+
sampling: Add more debug logs to help debug sampling issues.

tests/integration/test_integration.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -775,13 +775,15 @@ def test_partial_flush_log():
775775
mock.call(
776776
"Encoding %d spans. Spans processed: %d. Spans dropped by trace processors: %d. Unfinished "
777777
"spans remaining in the span aggregator: %d. (trace_id: %d) (top level span: name=%s) "
778-
"(partial flush triggered: %s)",
778+
"(sampling_priority: %s) (sampling_mechanism: %s) (partial flush triggered: %s)",
779779
2,
780780
3,
781781
0,
782782
1,
783783
t_id,
784784
"2",
785+
1,
786+
"-0",
785787
True,
786788
),
787789
]

tests/internal/test_settings.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -647,7 +647,7 @@ def test_remoteconfig_debug_logging():
647647
}
648648

649649
for _ in range(3):
650-
# Attempt to set the same RC Configurations multiple times. This mimicks the behavior
650+
# Attempt to set the same RC Configurations multiple times. This mimics the behavior
651651
# of the agent where all the current RC configurations are returned periodically.
652652
call_apm_tracing_rc(
653653
_base_rc_config(rc_configs),
@@ -656,7 +656,12 @@ def test_remoteconfig_debug_logging():
656656
# Ensure APM Tracing Remote Config debug logs are generated
657657
expected_logs = [
658658
# Tracer configurations are only updated once (calls with duplicate values should be ignored)
659-
mock.call("Updated tracer sampling rules via remote_config: %s", '[{"sample_rate": 0.3}]'),
659+
mock.call(
660+
"Updated tracer sampler (id: %s, rules: %s) sampling rules via remote_config: %s.",
661+
mock.ANY,
662+
mock.ANY,
663+
'[{"sample_rate": 0.3}]',
664+
),
660665
mock.call("Updated tracer tags via remote_config: %s", {"team": "onboarding"}),
661666
mock.call("Tracing disabled via remote_config. Config: %s Value: %s", "_tracing_enabled", False),
662667
mock.call(

0 commit comments

Comments
 (0)