Skip to content

Add coordinated sampling for snapshot probes - #12452

Open
jpbempel wants to merge 1 commit into
masterfrom
jpbempel/logpoint-sync
Open

Add coordinated sampling for snapshot probes#12452
jpbempel wants to merge 1 commit into
masterfrom
jpbempel/logpoint-sync

Conversation

@jpbempel

@jpbempel jpbempel commented Sep 10, 2026

Copy link
Copy Markdown
Member

What Does This Do

Adds coordinated sampling for full debugger snapshots using the active Datadog context, using Context API.
State of Coordinated Sampling is stored into a Context attached to the root local span.
The first probe’s sampling decision controls related probes, avoiding fragmented snapshot sets.
Ensures each probe emits at most once per coordinated context. Log-only probes remain independent.
Encapsulates ProbeDefinition.probeId, updating callers to use getProbeId().

Motivation

Additional Notes

Contributor Checklist

Jira ticket: DEBUG-5829

Adds coordinated sampling for full debugger snapshots using the active
Datadog context, using Context API.
State of Coordinated Sampling is stored into a Context attached to
the root local span.
The first probe’s sampling decision controls related probes, avoiding
fragmented snapshot sets.
Ensures each probe emits at most once per coordinated context.
Log-only probes remain independent.
Encapsulates ProbeDefinition.probeId, updating callers to use
getProbeId().
@jpbempel
jpbempel requested a review from a team as a code owner September 10, 2026 15:44
@jpbempel
jpbempel requested review from evanchooly and removed request for a team September 10, 2026 15:44
@jpbempel jpbempel added comp: debugger Dynamic Instrumentation type: feature Enhancements and improvements labels Sep 10, 2026

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: f56387e2e7

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

boolean sampled =
!logStatus.getDebugSessionStatus().isDisabled()
&& ProbeRateLimiter.tryProbe(localSampler, isFullSnapshot());
boolean sampled = !logStatus.getDebugSessionStatus().isDisabled() && trySample(localSampler);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Exclude active debug-session probes from shared sampling

When a full-snapshot probe tagged for an active debug session reaches this path, such as a conditioned probe, trySample can cache DROP even though LogStatus.shouldSend() later emits that probe unconditionally because the trigger already sampled the session. Every ordinary snapshot probe later in the same local trace then observes DROP and is suppressed, producing the fragmented snapshot set this coordination is meant to prevent; conversely, an active probe still emits after an ordinary probe cached DROP. Bypass or update the coordinated state for active-session probes rather than recording a decision that shouldSend() ignores.

Useful? React with 👍 / 👎.

boolean sampled =
!logStatus.getDebugSessionStatus().isDisabled()
&& ProbeRateLimiter.tryProbe(localSampler, isFullSnapshot());
boolean sampled = !logStatus.getDebugSessionStatus().isDisabled() && trySample(localSampler);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Exclude active debug-session probes from the shared decision

When a full-snapshot probe tagged for an active debug session reaches this path (for example, a conditioned probe), trySample can cache DROP even though LogStatus.shouldSend() later emits that probe unconditionally because the trigger already sampled the session. Every ordinary snapshot probe later in the same local trace then observes DROP and is suppressed, producing exactly the fragmented snapshot set this coordination is meant to prevent; if an ordinary probe cached DROP first, the active probe still emits with the same inconsistency. Bypass or update the coordinated state for active-session probes rather than recording a decision that shouldSend() ignores.

Useful? React with 👍 / 👎.

}
}
}
return state.tryEmit(getProbeId().getEncodedId());

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Preserve snapshot rate caps for coordinated followers

When an EMIT trace reaches two or more full-snapshot probes, only the first probe invokes ProbeRateLimiter.tryProbe; every later probe returns true here without consulting either its own sampler or GLOBAL_SNAPSHOT_SAMPLER. This lets followers exceed their documented snapshotsPerSecond maximum when probes have different rates, and it lets the configured global snapshot cap be exceeded by up to the number of matching probes per trace. Use a coordinated group decision that still enforces the applicable per-probe and global caps rather than bypassing both samplers for followers.

Useful? React with 👍 / 👎.

@datadog-prod-us1-4

datadog-prod-us1-4 Bot commented Sep 10, 2026

Copy link
Copy Markdown

🎯 Code Coverage (details)
Patch Coverage: 93.75%
Overall Coverage: 59.11% (+0.00%)

This comment will be updated automatically if new data arrives.
🔗 Commit SHA: f56387e | Docs | View more details | Give us feedback!

@pr-commenter

pr-commenter Bot commented Sep 10, 2026

Copy link
Copy Markdown

Debugger benchmarks

Parameters

Baseline Candidate
baseline_or_candidate baseline candidate
ci_job_date 1789055605 1789055932
end_time 2026-09-10T15:54:55 2026-09-10T16:00:23
git_branch master jpbempel/logpoint-sync
git_commit_sha 2df9ed5 f56387e
start_time 2026-09-10T15:53:26 2026-09-10T15:58:53
See matching parameters
Baseline Candidate
ci_job_id 2032729208 2032729208
ci_pipeline_id 136668803 136668803
cpu_model Intel(R) Xeon(R) Platinum 8175M CPU @ 2.50GHz Intel(R) Xeon(R) Platinum 8175M CPU @ 2.50GHz
git_commit_date 1789054911 1789054911

Summary

Found 0 performance improvements and 0 performance regressions! Performance is the same for 11 metrics, 4 unstable metrics.

See unchanged results
scenario Δ mean agg_http_req_duration_min Δ mean agg_http_req_duration_p50 Δ mean agg_http_req_duration_p75 Δ mean agg_http_req_duration_p99 Δ mean throughput
scenario:noprobe same unstable
[-11.444µs; +38.470µs] or [-3.210%; +10.792%]
unstable
[-16.092µs; +50.803µs] or [-4.351%; +13.735%]
unstable
[-172.756µs; +14.407µs] or [-13.554%; +1.130%]
same
scenario:basic same same same unstable
[+30.470µs; +278.682µs] or [+2.790%; +25.516%]
same
scenario:loop same same same same same
Request duration reports for reports
gantt
    title reports - request duration [CI 0.99] : candidate=None, baseline=None
    dateFormat X
    axisFormat %s
section baseline
noprobe (356.461 µs) : 333, 380
.   : milestone, 356,
basic (336.266 µs) : 329, 343
.   : milestone, 336,
loop (8.118 ms) : 8055, 8181
.   : milestone, 8118,
section candidate
noprobe (369.974 µs) : 346, 394
.   : milestone, 370,
basic (341.009 µs) : 336, 346
.   : milestone, 341,
loop (8.117 ms) : 8053, 8181
.   : milestone, 8117,
Loading
  • baseline results
Scenario Request median duration [CI 0.99]
noprobe 356.461 µs [332.701 µs, 380.221 µs]
basic 336.266 µs [329.292 µs, 343.239 µs]
loop 8.118 ms [8.055 ms, 8.181 ms]
  • candidate results
Scenario Request median duration [CI 0.99]
noprobe 369.974 µs [346.34 µs, 393.609 µs]
basic 341.009 µs [335.595 µs, 346.423 µs]
loop 8.117 ms [8.053 ms, 8.181 ms]

@dd-octo-sts

dd-octo-sts Bot commented Sep 10, 2026

Copy link
Copy Markdown
Contributor

🟢 Java Benchmark SLOs — All performance SLOs passed

Suite Status
Startup 🟢 pass

SLO thresholds are defined here based on automatically generated metrics. A warning is raised when results are within 5% of the threshold.

PR vs. master results
Scenario Candidate master Δ (95% CI of mean)
startup:insecure-bank:iast:Agent 14.81 s 14.59 s [+0.6%; +2.4%] (maybe worse)
startup:insecure-bank:tracing:Agent 13.59 s 13.75 s [-2.0%; -0.3%] (maybe better)
startup:petclinic:appsec:Agent 17.08 s 16.97 s [-0.1%; +1.4%] (no difference)
startup:petclinic:iast:Agent 16.95 s 16.95 s [-0.8%; +0.9%] (no difference)
startup:petclinic:profiling:Agent 16.84 s 16.80 s [-0.8%; +1.4%] (no difference)
startup:petclinic:sca:Agent 16.99 s 16.91 s [-0.7%; +1.6%] (no difference)
startup:petclinic:tracing:Agent 16.07 s 16.16 s [-1.7%; +0.5%] (no difference)

Commit: f56387e2 · CI Pipeline · Benchmarking Platform UI


Load and DaCapo benchmarks can be triggered manually in the GitLab pipeline. Results will appear in the Benchmarking Platform UI after completion.

@datadog-prod-us1-4 datadog-prod-us1-4 Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Datadog Autotest: FAIL

An ordinary snapshot probe and an exception probe now share one root-span sampling state. The first probe can stop the other probe or let it emit without its own sampling decision.

Open Bits AI session

🤖 Datadog Autotest · Commit f56387e · What is Autotest? · @DataDog review to ask questions · Any feedback? Reach out in #autotest

}

private boolean trySample(Sampler sampler) {
if (!isFullSnapshot()) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Exclude exception probes from shared sampling

One feature can stop the other feature or let it emit without its own sampling decision.

Assertion details
  • Input: Enable exception debugging and an ordinary snapshot probe on the same local root span.
  • Expected: Exception probes must use their exception sampling flow. They must not share the coordinated state of ordinary snapshot probes.
  • Actual: The first full-snapshot probe stores its decision on the local root span. An ExceptionProbe uses the same state because it extends LogProbe and is a full-snapshot probe.

Was this helpful? React 👍 or 👎
🤖 Datadog Autotest · What is Autotest? · @DataDog review to ask questions · Any feedback? Reach out in #autotest · Open Bits AI session

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp: debugger Dynamic Instrumentation type: feature Enhancements and improvements

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants