Skip to content

feat(agent-data-plane): emit liveness signals - #2213

Open
thieman wants to merge 6 commits into
mainfrom
thieman/dadp-157-liveness-signals
Open

feat(agent-data-plane): emit liveness signals#2213
thieman wants to merge 6 commits into
mainfrom
thieman/dadp-157-liveness-signals

Conversation

@thieman

@thieman thieman commented Jul 27, 2026

Copy link
Copy Markdown
Contributor

Tracking

Summary

  • Add a periodic Agent Data Plane liveness source that emits datadog.agent_data_plane.running and datadog.agent_data_plane.up through the existing Datadog encoders and forwarder.
  • Attach the ADP hostname to both signals and an ADP version tag to the running gauge. The running gauge uses the existing metrics_enrich path, so common host-tag enrichment applies exactly as it does to other metrics.
  • Keep liveness emission simple: it has no source-specific Core Agent IPC, host-tag cache, or retry logic; prebuild the two payloads once and clone them for each emission.
  • Provision the metrics and service-check output paths for connected topologies with an active data pipeline, including connected OTLP proxy-only topologies, while preserving standalone proxy no-DNS behavior and the established no-data-pipelines exit behavior.

Validation

  • cargo nextest run -p agent-data-plane --bin agent-data-plane (160 passed)
  • cargo check -p agent-data-plane --tests
  • make fmt
  • Independent post-fix review of origin/main...HEAD (no blockers or important issues)
  • make test-integration-macos-run CASE=adp-no-pipelines-exit — requires provisioned Core Agent plus release ADP and Panoramic binaries, unavailable locally; the exact CI regression is fixed by the restored no-pipeline exit condition and will rerun in CI.
  • make check-all — local FIPS feature checks require cmake, which is unavailable in this environment.

thieman added 2 commits July 27, 2026 12:39
Add a periodic liveness source that emits Core Agent-compatible running metrics and service checks through the existing metric and service-check pipelines.\n\nKeep the liveness baseline pipelines available whenever ADP is enabled, and fetch/cache Core Agent system host tags without suppressing signals when tag retrieval fails.
Defer liveness IPC client construction until the source tick so host tag failures cannot block topology startup. Bound and cancel tag lookups and dispatches, cache successful system tags, and skip missed ticks.\n\nRoute liveness metrics directly to the Datadog metrics encoder so optional host-tag enrichment cannot suppress liveness signals.
@datadog-prod-us1-5

This comment has been minimized.

Keep liveness tied to a running topology rather than allowing it to create a liveness-only topology. Require the metric and service-check baselines whenever a data pipeline runs so proxy-only OTLP topologies can emit liveness, while no-pipeline configurations retain the established early exit.
@thieman

thieman commented Jul 27, 2026

Copy link
Copy Markdown
Contributor Author

[GPT-5.6 Terra (OpenAI)] Investigated the automated CI summaries. adp-no-pipelines-exit exposed a real regression: liveness incorrectly kept ADP alive with no enabled data pipelines. That was fixed in cd938ee460.

The subsequent adp-ipc-no-dns failure exposed a second issue: standalone OTLP proxy mode intentionally avoids normal forwarding/DNS, but liveness had forced those output paths. The simplified revision in 41c9389e9a scopes liveness to connected topologies, removes liveness-specific Core Agent IPC and host-tag logic, and routes the running metric through the common metrics_enrich path. Standalone proxy retains its existing no-DNS behavior. The updated commits are pushed and CI will rerun.

@pr-commenter

pr-commenter Bot commented Jul 27, 2026

Copy link
Copy Markdown

Binary Size Analysis (Agent Data Plane)

Baseline: 49ff2f8 · Comparison: d94bbb2 · diff
Analysis Configuration: stripped binaries · Pass/Fail Threshold: +5%
Sizes: 40.91 MiB (baseline) vs 40.82 MiB (comparison)
Size Change: -88.92 KiB (-0.21%)

✅ Binary size difference within threshold

Changes by Module
Module File Size Symbols
tokio -17.08 KiB 382
anon.2e413e04bd8c3b9df12e29b0b9db0106.602.llvm.13353585689389608272 +16.92 KiB 1
anon.90ffda7748c861fe2f6f03211060ab76.488.llvm.2966725881188392761 -16.92 KiB 1
[sections] -16.45 KiB 9
agent_data_plane::components::liveness +14.52 KiB 17
anon.90ffda7748c861fe2f6f03211060ab76.639.llvm.2966725881188392761 -12.02 KiB 1
anon.2e413e04bd8c3b9df12e29b0b9db0106.609.llvm.13353585689389608272 +12.02 KiB 1
figment -11.39 KiB 163
anon.90ffda7748c861fe2f6f03211060ab76.96.llvm.2966725881188392761 -9.80 KiB 1
anon.2e413e04bd8c3b9df12e29b0b9db0106.606.llvm.13353585689389608272 +9.72 KiB 1
anon.90ffda7748c861fe2f6f03211060ab76.361.llvm.2966725881188392761 -9.16 KiB 1
anon.2e413e04bd8c3b9df12e29b0b9db0106.364.llvm.13353585689389608272 +9.07 KiB 1
anon.90ffda7748c861fe2f6f03211060ab76.1.llvm.2966725881188392761 -8.49 KiB 1
std +8.46 KiB 72
anon.9c495e45b57b5eb105f4b933431ecb7c.8.llvm.15048504531932446446 +8.40 KiB 1
serde_core -8.11 KiB 56
core -7.68 KiB 1322
http_body_util +7.44 KiB 43
anon.45288ec21d0b197332c371a800b48124.12.llvm.11840851408775994717 -6.94 KiB 1
anon.1cace928b9235e2bb9ca999f9e8bfbe2.104.llvm.11528837137455035160 +6.94 KiB 1
Detailed Symbol Changes
    FILE SIZE        VM SIZE    
 --------------  -------------- 
  [NEW] +32.9Ki  [NEW] +32.7Ki    agent_data_plane::internal::env::workload::RemoteAgentWorkloadProvider::from_configuration::_{{closure}}::h438e15b1c6f48c53
  [NEW] +16.9Ki  [NEW]     +76    anon.2e413e04bd8c3b9df12e29b0b9db0106.602.llvm.13353585689389608272
  [NEW] +12.0Ki  [NEW]     +81    anon.2e413e04bd8c3b9df12e29b0b9db0106.609.llvm.13353585689389608272
  [NEW] +9.72Ki  [NEW]     +79    anon.2e413e04bd8c3b9df12e29b0b9db0106.606.llvm.13353585689389608272
  [NEW] +9.07Ki  [NEW]     +91    anon.2e413e04bd8c3b9df12e29b0b9db0106.364.llvm.13353585689389608272
 +11e2% +8.62Ki +13e2% +8.62Ki    std::sys::backtrace::__rust_begin_short_backtrace::h9c087ec96f088179
  [NEW] +8.40Ki  [NEW]     +81    anon.9c495e45b57b5eb105f4b933431ecb7c.8.llvm.15048504531932446446
  [NEW] +6.94Ki  [NEW]     +77    anon.1cace928b9235e2bb9ca999f9e8bfbe2.104.llvm.11528837137455035160
  [DEL] -6.18Ki  [DEL]     -79    anon.90ffda7748c861fe2f6f03211060ab76.479.llvm.2966725881188392761
 -19.3% -6.27Ki -19.4% -6.27Ki    datadog_agent_commons::ipc::client::RemoteAgentClient::from_client_configuration::_{{closure}}::_{{closure}}::_{{closure}}::h97868b07fa692b3b
  [DEL] -6.94Ki  [DEL]     -77    anon.45288ec21d0b197332c371a800b48124.12.llvm.11840851408775994717
  [DEL] -8.42Ki  [DEL] -8.33Ki    tokio::runtime::runtime::Runtime::block_on::hb9e167ed76612262
  [DEL] -8.49Ki  [DEL]     -81    anon.90ffda7748c861fe2f6f03211060ab76.1.llvm.2966725881188392761
  [DEL] -9.16Ki  [DEL]     -91    anon.90ffda7748c861fe2f6f03211060ab76.361.llvm.2966725881188392761
  [DEL] -9.80Ki  [DEL]     -79    anon.90ffda7748c861fe2f6f03211060ab76.96.llvm.2966725881188392761
  [DEL] -12.0Ki  [DEL]     -81    anon.90ffda7748c861fe2f6f03211060ab76.639.llvm.2966725881188392761
  -1.1% -13.1Ki  -1.1% -13.1Ki    [section .gcc_except_table]
  [DEL] -16.9Ki  [DEL]     -76    anon.90ffda7748c861fe2f6f03211060ab76.488.llvm.2966725881188392761
  [DEL] -19.8Ki  [DEL] -19.7Ki    agent_data_plane::internal::env::workload::build_collector::_{{closure}}::h2f3a47ff8d1c568c
  [DEL] -21.2Ki  [DEL] -21.0Ki    agent_data_plane::internal::env::ADPEnvironmentProvider::from_configuration::_{{closure}}::h2d1251391c27a303
  -0.6% -55.2Ki  -0.6% -48.8Ki    [7994 Others]
  -0.2% -88.9Ki  -0.2% -75.9Ki    TOTAL

@pr-commenter

pr-commenter Bot commented Jul 27, 2026

Copy link
Copy Markdown

Regression Detector (Agent Data Plane)

Run ID: a58ac662-1059-45e3-ab73-b5eb4b1f7930
Baseline: 49ff2f81 · Comparison: d94bbb26 · diff

Optimization Goals: ✅ No significant changes detected

Fine details of change detection per experiment (3)

Experiments configured erratic: true are tagged (ignored) and skipped when determining which experiments regressed or improved. Experiments which are detected as erratic at runtime are tagged (erratic) to flag that the run's sample dispersion was high, but their regression / improvement signal still counts.

experiment goal Δ mean % links
quality_gates_rss_idle memory ⚪ -0.16 metrics profiles logs
quality_gates_rss_dsd_low memory ⚪ -0.18 metrics profiles logs
quality_gates_rss_dsd_medium memory ⚪ -0.58 metrics profiles logs
Bounds Checks: ✅ Passed (3)
experiment check replicates observed links
quality_gates_rss_dsd_low memory_usage 10/10 ✅ 45.5 MiB ≤ 50 MiB metrics profiles logs
quality_gates_rss_dsd_medium memory_usage 10/10 ✅ 67.1 MiB ≤ 75 MiB metrics profiles logs
quality_gates_rss_idle memory_usage 10/10 ✅ 31.1 MiB ≤ 40 MiB metrics profiles logs
Explanation

A change is flagged as a regression when |Δ mean %| > 5.00% in the regressing direction for its optimization goal AND SMP marks the experiment as a regression (is_regression: true). Improvements use the matching criteria for the improving direction. Experiments configured erratic: true (tagged (ignored)) are skipped outright; experiments detected as erratic at runtime (tagged (erratic)) still count, since that flag describes sample dispersion rather than directional certainty. The Δ mean % cell is colored accordingly: 🟢 = improvement, 🔴 = regression, ⚪ = neutral. Reduction in CPU or memory is an improvement; reduction in ingress throughput is a regression.

Comment thread bin/agent-data-plane/src/cli/run.rs Outdated

// If no data pipelines are enabled, then there's nothing for us to do.
// Without a data pipeline, there is no useful topology to run. In particular, liveness alone must not keep ADP
// alive.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

This comment was fine before, revert it

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

[GPT-5.6 Terra (OpenAI)] Restored the original no-data-pipelines comment in c90a1a2c7b.

Comment thread bin/agent-data-plane/src/cli/run.rs Outdated
// Notably, we _don't_ need either of these if all we're doing is running the OTLP pipeline in proxy mode, which
// is the only reason we're differentiating here.
// Liveness requires the metrics and service-check baseline pipelines for every running topology, including an
// OTLP proxy-only topology.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Again, this comment was fine, revert it

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

[GPT-5.6 Terra (OpenAI)] Restored the original baseline explanation in c90a1a2c7b and retained a concise connected-liveness exception. Reverting the proxy-mode sentence verbatim would be inaccurate because connected OTLP proxy-only topologies now deliberately provision metric and service-check output paths for liveness.

Remove liveness-specific IPC host-tag retrieval, caching, retries, and dispatch timeouts. Route its metric through the common enrichment pipeline so host tags remain a pipeline concern, while service checks continue through the standard encoder path.\n\nKeep connected topologies provisioned for liveness, including OTLP proxy-only, but leave standalone OTLP proxy mode free of liveness and otherwise-unneeded output paths.

/// Periodically emits Agent Data Plane liveness signals.
pub struct LivenessConfiguration {
hostname: MetaString,

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Is hostname here necessary? I would have thought this would be added by the downstream metrics/service_checks components

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

[GPT-5.6 Terra (OpenAI)] Kept the hostname. metrics_enrich intentionally does not add metric hosts, and this service check routes directly to dd_service_checks_encode without a host-enrichment transform. Removing it would leave the metric without a host dimension and omit host_name from the service-check payload.

let service_check =
Event::ServiceCheck(ServiceCheck::new(UP_SERVICE_CHECK_NAME, CheckStatus::Ok).with_hostname(hostname));

(metric, service_check)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

These are going to be around for the lifetime of the process, can we just make them once and then have them be static or something? It's not a lot, but we should minimize allocations here

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

[GPT-5.6 Terra (OpenAI)] Fixed in c90a1a2c7b: Liveness::new constructs both payloads once, and each timer tick only clones the prebuilt events for dispatch.

}

#[test]
fn emits_liveness_events_without_direct_system_host_tags() {

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Yes this component should not put any host tags on, but that should be happening downstream. Think we want to remove this test.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

[GPT-5.6 Terra (OpenAI)] Replaced the implementation-specific assertion about absent source tags in c90a1a2c7b with payload-contract tests for metric name/value/host/version and service-check name/status/hostname.

Construct the liveness metric and service check with the source, then clone them for each dispatch tick. Preserve explicit hostnames because the shared metric path and direct service-check encoder do not add them.\n\nRestore the original topology comments while documenting the connected liveness exception for proxy-only OTLP deployments, and replace source-tag implementation assertions with payload contract coverage.
Comment thread bin/agent-data-plane/src/cli/run.rs Outdated
}

#[cfg(test)]
mod liveness_topology_tests {

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Extraneous test, remove

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

[GPT-5.6 Terra (OpenAI)] Removed the constant-only test in d94bbb262d.

Remove the constant-only liveness topology test module after review feedback.\n\nLiveness routing remains covered by the production topology configuration and existing component tests.
@thieman
thieman marked this pull request as ready for review July 28, 2026 19:55
@thieman
thieman requested a review from a team as a code owner July 28, 2026 19:55

@datadog-prod-us1-5 datadog-prod-us1-5 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: PASS

More details

The new liveness source is wired only after the required metric and service-check baselines are selected, so connected OTLP proxy-only topologies can emit both signals while standalone proxy mode and the no-pipeline exit path remain unchanged. Payload inspection covered hostname, version tagging, status encoding, and downstream encoder contracts; local compilation was unavailable because the uncached hyper-http-proxy git dependency could not be fetched.

Was this helpful? React 👍 or 👎

Open Bits AI session

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

@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: d94bbb262d

ℹ️ 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".

let metric_context = Context::from_static_name(RUNNING_METRIC_NAME)
.with_host(hostname.clone())
.with_tags(TagSet::from_iter([Tag::from(format!("version:{version}"))]));
let metric = Event::Metric(Metric::gauge(metric_context, 1.0));

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 Stamp each liveness metric at emission time

Metric::gauge(metric_context, 1.0) creates a point without a timestamp, and prebuilding then cloning it preserves that state for every 15-second tick. Because this source connects directly through metrics_enrich rather than the aggregation transform that timestamps non-timestamped values, the Datadog metrics encoders serialize the point timestamp as 0, so the running gauge is reported at the Unix epoch instead of indicating current liveness. Construct the metric with the current Unix timestamp on each emission.

Useful? React with 👍 / 👎.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant