Skip to content

fix(id): reset DogStatsD and exporter state on refresh - #10323

Draft
litianningdatadog wants to merge 1 commit into
masterfrom
tianning.li/1-dogstatsd-exporter-refresh-resets
Draft

litianningdatadog wants to merge 1 commit into
masterfrom
tianning.li/1-dogstatsd-exporter-refresh-resets

Conversation

@litianningdatadog

@litianningdatadog litianningdatadog commented Sep 14, 2026 •

Copy link
Copy Markdown
Contributor

Stacked PRs

  • #10323 tianning.li/1-dogstatsd-exporter-refresh-resets — current PR
  • #10324 tianning.li/2-otel-runtime-refresh-resets
  • #10325 tianning.li/3-exporter-otel-identity-gaps
  • #10326 tianning.li/4-runtime-datastream-identity-gaps
  • #10327 tianning.li/5-exporter-buffer-state
  • #10328 tianning.li/6-otel-datastream-counter-state
  • #10329 tianning.li/7-spanstats-otel-retry-state
  • #10330 tianning.li/8-agent-otel-counter-baselines
  • #10331 tianning.li/9-datastream-dogstatsd-exporter-requests

Origin

This change set was split from the monolithic PR #9814 to keep the identity-refresh fixes smaller and easier to review.

What does this PR do?

Reset inherited DogStatsD buffers and exporter batches when a MicroVM identity refresh occurs.

Motivation

A clone can inherit pre-snapshot DogStatsD and exporter state. Discarding that state prevents duplicate or stale telemetry from being reported under the refreshed runtime identity.

Logical change

This is the 1-dogstatsd-exporter-refresh-resets layer of the stacked MicroVM identity-refresh fix. It is based on master and keeps the subsystem-specific reset behavior isolated for review.

Jira

SVLS-9768

Tests

./node_modules/.bin/mocha packages/dd-trace/test/dogstatsd.spec.js packages/dd-trace/test/exporters/agent/exporter.spec.js packages/dd-trace/test/exporters/agentless/exporter.spec.js packages/dd-trace/test/exporters/common/writer.spec.js packages/dd-trace/test/exporters/span-stats/writer.spec.js

Additional Notes

This PR is intentionally opened as a draft and is part of a linear stack.

@dd-octo-sts

dd-octo-sts Bot commented Sep 14, 2026

Copy link
Copy Markdown
Contributor

Overall package size

Self size: 8.96 MB
Deduped: 9.69 MB
No deduping: 9.69 MB

Dependency sizes | name | version | self size | total size | |------|---------|-----------|------------| | import-in-the-middle | 3.5.1 | 127.66 kB | 513.61 kB | | opentracing | 0.14.7 | 194.81 kB | 194.81 kB | | dc-polyfill | 0.1.11 | 25.74 kB | 25.74 kB |

🤖 This report was automatically generated by heaviest-objects-in-the-universe

@codecov

codecov Bot commented Sep 14, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 98.71%. Comparing base (3dcb352) to head (6533cee).
⚠️ Report is 1 commits behind head on master.

Additional details and impacted files
@@           Coverage Diff           @@
##           master   #10323   +/-   ##
=======================================
  Coverage   98.71%   98.71%           
=======================================
  Files        1025     1025           
  Lines      160626   160673   +47     
  Branches       74       74           
=======================================
+ Hits       158563   158610   +47     
  Misses       2063     2063           
Flag Coverage Δ
ai-guard 65.26% <55.00%> (-0.03%) ⬇️
apm-capabilities 63.69% <100.00%> (+0.01%) ⬆️
apm-integrations 81.57% <55.00%> (-0.02%) ⬇️
appsec 58.94% <55.00%> (-0.01%) ⬇️
debugger 70.21% <55.00%> (-0.04%) ⬇️
instrumentation 54.46% <55.00%> (-0.01%) ⬇️
llmobs 79.08% <55.00%> (-0.03%) ⬇️
master-coverage 98.71% <100.00%> (?)
openfeature 66.51% <55.00%> (-0.03%) ⬇️
platform 69.38% <73.52%> (-0.03%) ⬇️
profiling 66.86% <55.00%> (-0.03%) ⬇️
serverless 65.99% <55.00%> (-0.02%) ⬇️
test-optimization 82.54% <55.00%> (+0.03%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@litianningdatadog
litianningdatadog marked this pull request as ready for review September 14, 2026 20:20
@litianningdatadog
litianningdatadog requested review from a team as code owners September 14, 2026 20:20
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Sep 14, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-09-14T20:35:37.525537Z 6533cee Draft marked ready
🔒 Security Review ✅ Completed 2026-09-14T20:34:47.464458Z 6533cee Draft marked ready
ℹ️ About Codex in GitHub

Your team has set up Codex to 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" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟡 Changes recommended

Three moderate issues remain around telemetry accumulators, AgentExporter reset wiring, and OTLP trace-root preservation.

Get a fresh assessment by requesting another Copilot review.

Pull request overview

This PR resets stale DogStatsD, span-statistics, and exporter state when a MicroVM identity refresh occurs.

Changes:

  • Clears buffered telemetry and exporter batches on refresh.
  • Resets span-statistics buckets.
  • Adds regression tests for refresh behavior.
File summaries
File Summary
packages/dd-trace/test/span_stats.spec.js Tests span-statistics reset behavior.
packages/dd-trace/test/exporters/common/writer.spec.js Tests pending writer-batch resets.
packages/dd-trace/test/exporters/agentless/exporter.spec.js Tests agentless refresh subscriptions.
packages/dd-trace/test/dogstatsd.spec.js Tests DogStatsD refresh handling.
packages/dd-trace/src/span_stats.js Resets span-stat buckets; OTLP root-span configuration must be preserved.
packages/dd-trace/src/exporters/common/writer.js Adds pending-batch reset support; normal AgentExporter wiring remains incomplete.
packages/dd-trace/src/exporters/agentless/index.js Resets agentless batches on identity refresh.
packages/dd-trace/src/dogstatsd.js Resets aggregation maps, but telemetry accumulators also require clearing.
Review details

Suppressed comments (2)

packages/dd-trace/src/dogstatsd.js:610

  • On a tag-changing refresh, this call resets only the aggregation maps. A telemetry-enabled client still retains metricsByType, aggregatedContextsByType, and sent/dropped counters in DogStatsDClient.telemetry; if those values were collected before the snapshot, the next telemetry flush emits them with the refreshed tags. Clear the client telemetry accumulators as part of the same identity-boundary reset.
    if (this._client.updateTags(tags)) {
      this.reset()
    }

packages/dd-trace/src/exporters/common/writer.js:109

  • Although the new reset API is on the shared Writer, the identity-refresh listener is only installed by AgentlessExporter. The default AgentExporter (used by exporter.js for normal tracing) also buffers spans in a common Writer when flushInterval > 0, so a clone can still flush pre-snapshot traces after refresh. Wire the reset into AgentExporter as well, or centralize it in the shared exporter lifecycle.
  resetPendingBatch () {
    this._encoder.reset()
  • Files reviewed: 8/8 changed files
  • Comments generated: 1
  • Review effort level: Lite

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

// A clone resume shouldn't export buckets accumulated before the snapshot under its own identity.
unsubscribeBucketReset?.()
const onIdentityRefresh = () => {
this.buckets = new TimeBuckets()
@litianningdatadog litianningdatadog added the aws-microvm AWS MicroVM related features label Sep 14, 2026
@datadog-prod-us1-4

Copy link
Copy Markdown

Tests

✅ All CI checks and tests passed.

🎉 All green!

🧪 All tests passed
❄️ No new flaky tests detected

🎯 Code Coverage (details)
• Patch Coverage: 100.00%
• Overall Coverage: 98.21% (+0.01%)

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

@litianningdatadog
litianningdatadog marked this pull request as draft September 14, 2026 20:25

@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

With the default DogStatsD setting, an identity refresh does not remove inherited aggregate data. The span statistics reset removes OTLP trace-root grouping after the first refresh.

Open Bits AI session

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

*/
updateTags (tags) {
this._client.updateTags(tags)
if (this._client.updateTags(tags)) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Reset aggregates on each identity refresh

MicroVM clones can send duplicate aggregate metrics from the snapshot.

Assertion details
  • Input: A MicroVM identity refresh with the default runtimeMetricsRuntimeId setting and pending aggregate metrics.
  • Expected: Each identity refresh must remove aggregate data that the clone inherits from the snapshot.
  • Actual: The new condition resets aggregate data only when the serialized tag prefix changes. The default setting omits the runtime ID, so a clone refresh can leave the prefix unchanged and preserve inherited counters, gauges, and histograms.

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

// A clone resume shouldn't export buckets accumulated before the snapshot under its own identity.
unsubscribeBucketReset?.()
const onIdentityRefresh = () => {
this.buckets = new TimeBuckets()

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 Keep OTLP trace-root grouping after refresh

OTLP span metrics become incorrect after the first identity refresh.

Assertion details
  • Input: An identity refresh while OTLP span metrics are active, followed by root and child spans with the same dimensions.
  • Expected: The new bucket set must keep trace-root grouping when the OTLP exporter is active.
  • Actual: The refresh handler replaces OTLP TimeBuckets with the default mode. This mode merges trace roots with other spans and removes the datadog.is_trace_root attribute.
Suggested change
this.buckets = new TimeBuckets()
this.buckets = new TimeBuckets(Boolean(this.otlpExporter))

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

@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: 6533ceed93

ℹ️ About Codex in GitHub

Your team has set up Codex to 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 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

// A clone resume shouldn't export buckets accumulated before the snapshot under its own identity.
unsubscribeBucketReset?.()
const onIdentityRefresh = () => {
this.buckets = new TimeBuckets()

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Preserve OTLP trace-root bucketing after refresh

When OTLP span statistics are enabled and the MicroVM identity-refresh channel fires, this replaces the original TimeBuckets(true) with the default non-OTLP configuration. All subsequently recorded root and child spans are therefore merged under the same aggregation key and exported without the datadog.is_trace_root attribute; recreate the buckets with Boolean(this.otlpExporter) so the constructor's OTLP behavior survives the reset.

AGENTS.md reference: AGENTS.md:L79-L80

Useful? React with 👍 / 👎.

Comment on lines +608 to +610
if (this._client.updateTags(tags)) {
this.reset()
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Reset aggregates even when identity tags are unchanged

When runtimeMetricsRuntimeId has its default value of false, generateClientConfig() excludes the refreshed runtime ID, so the DogStatsD tag prefix remains unchanged on every MicroVM identity refresh. This condition then preserves counters, gauges, and histograms captured before the snapshot, allowing every clone to flush the same inherited aggregate; the identity-refresh path must reset pending aggregation independently of whether the serialized tags changed.

Useful? React with 👍 / 👎.

@litianningdatadog
litianningdatadog marked this pull request as ready for review September 14, 2026 20:29
@pr-commenter

pr-commenter Bot commented Sep 14, 2026

Copy link
Copy Markdown

Benchmarks

Benchmark execution time: 2026-09-14 20:34:03

Comparing candidate commit 6533cee in PR branch tianning.li/1-dogstatsd-exporter-refresh-resets with baseline commit 3dcb352 in branch master.

📊 Benchmarking dashboard

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

Explanation

This is an A/B test comparing a candidate commit's performance against that of a baseline commit. Performance changes are noted in the tables below as:

  • 🟩 = significantly better candidate vs. baseline
  • 🟥 = significantly worse candidate vs. baseline

We compute a confidence interval (CI) over the relative difference of means between metrics from the candidate and baseline commits, considering the baseline as the reference.

If the CI is entirely outside the configured SIGNIFICANT_IMPACT_THRESHOLD (or the deprecated UNCONFIDENCE_THRESHOLD), the change is considered significant.

Feel free to reach out to #apm-benchmarking-platform on Slack if you have any questions.

More details about the CI and significant changes

You can imagine this CI as a range of values that is likely to contain the true difference of means between the candidate and baseline commits.

CIs of the difference of means are often centered around 0%, because often changes are not that big:

---------------------------------(------|---^--------)-------------------------------->
                              -0.6%    0%  0.3%     +1.2%
                                 |          |        |
         lower bound of the CI --'          |        |
sample mean (center of the CI) -------------'        |
         upper bound of the CI ----------------------'

As described above, a change is considered significant if the CI is entirely outside the configured SIGNIFICANT_IMPACT_THRESHOLD (or the deprecated UNCONFIDENCE_THRESHOLD).

For instance, for an execution time metric, this confidence interval indicates a significantly worse performance:

----------------------------------------|---------|---(---------^---------)---------->
                                       0%        1%  1.3%      2.2%      3.1%
                                                  |   |         |         |
       significant impact threshold --------------'   |         |         |
                      lower bound of CI --------------'         |         |
       sample mean (center of the CI) --------------------------'         |
                      upper bound of CI ----------------------------------'

Unstable benchmarks

These benchmarks have a confidence interval too wide to call a change; treat them as noise rather than signal.

scenario:appsec-iast-no-vulnerability-iast-enabled-default-config-20

  • unstable max_rss_usage [-22.671MB; +11.113MB] or [-9.829%; +4.818%]

scenario:encoders-0.4-immediate-flush-20

  • unstable max_rss_usage [-5.550MB; +10.957MB] or [-7.025%; +13.870%]

scenario:llmobs-encode-unicode-mixed-20

  • unstable max_rss_usage [-4.703MB; +11.277MB] or [-6.157%; +14.764%]

scenario:plugin-cassandra-driver-long-query-24

  • unstable execution_time [-150.851ms; +232.279ms] or [-4.126%; +6.354%]

scenario:plugin-graphql-long-with-depth-and-collapse-off-24

  • unstable cpu_user_time [-656.850ms; +568.061ms] or [-5.882%; +5.087%]
  • unstable execution_time [-664.658ms; +569.708ms] or [-5.870%; +5.032%]
  • unstable throughput [-2.019op/s; +2.363op/s] or [-5.045%; +5.904%]

scenario:plugin-graphql-long-with-depth-off-26

  • unstable max_rss_usage [-21.304MB; +36.901MB] or [-9.186%; +15.912%]
  • unstable throughput [-21.113op/s; +12.608op/s] or [-6.380%; +3.810%]

@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: 6533ceed93

ℹ️ About Codex in GitHub

Your team has set up Codex to 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 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".


// A clone resume shouldn't flush spans buffered before the snapshot under its own identity.
unsubscribeBatchReset?.()
const onIdentityRefresh = () => this._writer.resetPendingBatch()

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Reset batches for the agent exporter too

When a MicroVM uses the normal Agent exporter—for example through a local Agent or Lambda extension—packages/dd-trace/src/exporters/agent/index.js:23-31 constructs the same common writer but never subscribes to the identity-refresh channel. Traces buffered before the image snapshot therefore remain in its AgentEncoder, and every clone can flush the inherited traces when its timer fires; wire resetPendingBatch() into AgentExporter as well.

AGENTS.md reference: AGENTS.md:L79-L79

Useful? React with 👍 / 👎.

payload.offset = 0
}

return true

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 Clear DogStatsD self-telemetry accumulators on refresh

When the refreshed tags do change, this method drops the encoded telemetry payload but leaves telemetry.metricsByType, aggregatedContextsByType, bytesSent/bytesDropped, and packetsSent/packetsDropped untouched. If the image is snapshotted before the telemetry interval flushes, every clone later reports those inherited pre-snapshot counts under the refreshed prefix, duplicating DogStatsD client telemetry even though the application metric buffers were reset; clear these interval accumulators at the same identity boundary.

AGENTS.md reference: AGENTS.md:L79-L79

Useful? React with 👍 / 👎.

@litianningdatadog
litianningdatadog marked this pull request as draft September 14, 2026 21:41

This branch has not been deployed

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

Labels

aws-microvm AWS MicroVM related features semver-patch

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants