Skip to content

chore(config): migrate OTTL filter to typed configuration - #2262

Merged
webern merged 1 commit into
mainfrom
m/confra-ofilt
Aug 10, 2026
Merged

chore(config): migrate OTTL filter to typed configuration#2262
webern merged 1 commit into
mainfrom
m/confra-ofilt

Conversation

@webern

@webern webern commented Aug 5, 2026

Copy link
Copy Markdown
Contributor

Summary

Migrate the OTTL span filter processor to the typed traces configuration. The processor now receives typed error-mode and span-condition values, and its raw configuration adapter is removed.

Change Type

  • Non-functional (chore, refactoring, docs)

How did you test this PR?

  • make fmt
  • make check-docs
  • make check-clippy
  • make check-all
  • OTTL filter tests: 13 passed
  • cargo check -p agent-data-plane --tests

References

@pr-commenter

pr-commenter Bot commented Aug 5, 2026

Copy link
Copy Markdown

Binary Size Analysis (Agent Data Plane)

Baseline: be50909 · Comparison: 5e2ad06 · diff
Analysis Configuration: stripped binaries · Pass/Fail Threshold: +5%
Sizes: 41.69 MiB (baseline) vs 41.31 MiB (comparison)
Size Change: -393.90 KiB (-0.92%)

✅ Binary size difference within threshold

Changes by Module
Module File Size Symbols
core -165.54 KiB 1774
figment -79.82 KiB 176
agent_data_plane_config_system::saluki_env_overlay::PathRecorder -56.46 KiB 20
agent_data_plane_config_system::saluki_only::_ +44.01 KiB 9
tokio -37.15 KiB 711
[sections] -26.79 KiB 8
serde_json -25.75 KiB 155
agent_data_plane::dogstatsd_contexts::artifact +24.32 KiB 9
saluki_common::resource_tracking::groups -23.85 KiB 8
saluki_common::task::instrument +22.92 KiB 11
h2 -20.54 KiB 81
hyper +19.68 KiB 159
anon.4d7b2df5eb1b3946a70196cadfabc2c4.518.llvm.1716889922181735544 -17.71 KiB 1
anon.5267a291e5f08ab9d80458cdfc1a9218.14.llvm.16802303590854200399 +17.53 KiB 1
anon.4d7b2df5eb1b3946a70196cadfabc2c4.590.llvm.1716889922181735544 -12.37 KiB 1
anon.1f80ce2ea163219c91306f97a3cc048a.579.llvm.14847804023011234010 +12.28 KiB 1
agent_data_plane_config::shared::_ +12.04 KiB 16
anyhow -11.84 KiB 270
saluki_common::cache::CacheBuilder<K,V,W,H> -11.01 KiB 3
agent_data_plane_config::domains::dogstatsd -10.49 KiB 13
Detailed Symbol Changes
    FILE SIZE        VM SIZE    
 --------------  -------------- 
  [NEW] +35.0Ki  [NEW] +34.7Ki    _<agent_data_plane_config_system::saluki_only::_::<impl serde_core::de::Deserialize for agent_data_plane_config_system::saluki_only::SalukiOnly>::deserialize::__Visitor as serde_core::de::Visitor>::visit_map::h9cec17db56ba97fb
  +313% +22.3Ki  +320% +22.3Ki    _<figment::value::de::ConfiguredValueDe<I> as serde_core::de::Deserializer>::deserialize_struct::h58b266ff3a7eeafe
  +266% +20.8Ki  +272% +20.8Ki    _<figment::value::de::ConfiguredValueDe<I> as serde_core::de::Deserializer>::deserialize_struct::ha4ed5ea72e5ab5f4
  [NEW] +20.8Ki  [NEW] +20.6Ki    agent_data_plane::internal::env::workload::build_collector::_{{closure}}::h11f056b0e952ff1d
  [NEW] +19.9Ki  [NEW] +19.8Ki    agent_data_plane::internal::env::ADPEnvironmentProvider::from_configuration::_{{closure}}::hbf519b844eb69f03
  [NEW] +17.5Ki  [NEW]     +76    anon.5267a291e5f08ab9d80458cdfc1a9218.14.llvm.16802303590854200399
 +12e2% +15.1Ki +16e2% +15.1Ki    _<agent_data_plane::internal::remote_agent::RemoteAgentImpl as datadog_protos::agent_include::datadog::remoteagent::flare::v1::flare_provider_server::FlareProvider>::get_flare_files::_{{closure}}::h1e40160ed77ede56
  [NEW] +14.8Ki  [NEW] +14.7Ki    agent_data_plane::state::metrics::rules::get_compat_remappings::hecb92936be43ea62
  +224% +14.6Ki  +229% +14.6Ki    _<figment::value::de::ConfiguredValueDe<I> as serde_core::de::Deserializer>::deserialize_struct::h6c5e847551d5f92c
  [NEW] +12.7Ki  [NEW] +12.6Ki    agent_data_plane::dogstatsd_contexts::artifact::decode_records::h14dabe22dc89b463
  [DEL] -12.6Ki  [DEL] -12.4Ki    _<serde_json::de::StreamDeserializer<R,T> as core::iter::traits::iterator::Iterator>::next::h6054a357390c9fb4
 -48.7% -13.9Ki -48.9% -13.8Ki    core::ptr::drop_in_place<agent_data_plane::cli::run::handle_run_command::{{closure}}>::h89ae9ab35e94ec3f
  [DEL] -14.3Ki  [DEL] -14.1Ki    agent_data_plane::state::metrics::rules::compat::get_compat_remappings::h5bb445b7815c4600
  [DEL] -14.9Ki  [DEL] -14.8Ki    _<h2::client::Connection<T,B> as core::future::future::Future>::poll::h4886d448713196ce
  [DEL] -15.6Ki  [DEL] -15.5Ki    _<agent_data_plane_config_system::saluki_env_overlay::PathRecorder as serde_core::de::Deserializer>::deserialize_struct::hb4aae3736c21710c
  [DEL] -16.6Ki  [DEL] -16.5Ki    _<h2::client::Connection<T,B> as core::future::future::Future>::poll::h41a8072f644cb4e7
  [DEL] -17.4Ki  [DEL] -17.2Ki    agent_data_plane::internal::remote_agent::RemoteAgentImpl::session_id_middleware::_{{closure}}::hac3e2bcce0c21cc5
  [DEL] -17.7Ki  [DEL]     -76    anon.4d7b2df5eb1b3946a70196cadfabc2c4.518.llvm.1716889922181735544
  -1.9% -22.8Ki  -1.9% -22.8Ki    [section .gcc_except_table]
  [DEL] -32.9Ki  [DEL] -32.7Ki    agent_data_plane::internal::env::workload::RemoteAgentWorkloadProvider::from_configuration::_{{closure}}::hb9276a11f915d291
  -3.8%  -408Ki  -3.9%  -335Ki    [10116 Others]
  -0.9%  -393Ki  -0.9%  -320Ki    TOTAL

@webern
webern marked this pull request as ready for review August 5, 2026 13:30
@webern
webern requested a review from a team as a code owner August 5, 2026 13:30

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

A typo or unknown field in ottl_filter_config used to fail configuration loading, but this migration routes it through a parser that silently falls back to propagate; the agent can therefore start while unexpectedly dropping spans. The focused Rust scenarios could not execute because the sandbox lacks the pinned toolchain/dependency, so this regression is reported from the diff and translator behavior.

Open Bits AI session

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

config: filter_config.unwrap_or_default(),
})
/// Creates configuration from the resolved typed traces configuration.
pub fn from_configuration(config: &TypedOttlFilter) -> Self {

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 Invalid filter configuration no longer fails startup

A malformed production configuration can silently discard spans and hide the operator's typo rather than preventing startup with an actionable error.

Assertion details
  • Input: A deployment sets ottl_filter_config.error_mode to an unsupported value such as explode, or includes an unknown field under ottl_filter_config.
  • Expected: Configuration loading rejects the invalid filter configuration before the agent starts, matching the removed adapter's enum parsing and deny_unknown_fields behavior.
  • Actual: The new adapter accepts an already-resolved TypedOttlFilter without validation, while the typed source translator maps any unrecognized error mode to OttlErrorMode::Propagate and permits unknown fields. The agent starts and treats the typo as propagate, causing evaluation errors to drop spans instead of surfacing a configuration error.

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

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.

I opened an issue at #2278 to follow up on where these configs are coming from. But for now fixed (see below)

Sonnet:

Fixed by strengthening the typed config layer instead of the component: ottl_filter_config.error_mode / ottl_transform_config.error_mode now deserialize through a dedicated OttlErrorModeSource enum (in saluki_only.rs) rather than Option<String>, so an unrecognized value (e.g. ignroe) is a deserialization error instead of a silent fallback to Propagate. OttlFilterConfig, OttlFilterTraces, and OttlTransformConfig also gained deny_unknown_fields, restoring the old adapter's rejection of unknown keys (e.g. a stray traces.spanevent block). Startup translation is strict, so either failure mode now fails config load before the agent starts, matching the removed adapter's behavior. Added regression tests covering both cases plus an environment-variable round-trip for the new enum leaf.

@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: 82bacaec81

ℹ️ 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 trace_obfuscation_config =
TraceObfuscationConfiguration::from_configuration(&config.domains.traces.obfuscation);

let ottl_filter_config = OttlFilterConfiguration::from_configuration(&config.domains.traces.ottl_filter);

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 OTTL filter config validation

With this call now consuming config.domains.traces.ottl_filter, invalid filter config no longer goes through the old serde type that had deny_unknown_fields and an enum for error_mode; the typed Saluki-only model stores error_mode as Option<String> and maps anything else to Propagate. In configs with a typo such as error_mode: ignroe or an unsupported traces.spanevent block, ADP now boots with the default/no-op typed value instead of failing fast, and evaluation errors can start dropping spans unexpectedly. Keep the previous validation at the typed boundary before handing the value to the component.

Useful? React with 👍 / 👎.

@webern webern Aug 6, 2026

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.

I opened an issue at #2278 to follow up on where these configs are coming from. But for now fixed (see below)

Sonnet:

Fixed by strengthening the typed config layer instead of the component: ottl_filter_config.error_mode / ottl_transform_config.error_mode now deserialize through a dedicated OttlErrorModeSource enum (in saluki_only.rs) rather than Option<String>, so an unrecognized value (e.g. ignroe) is a deserialization error instead of a silent fallback to Propagate. OttlFilterConfig, OttlFilterTraces, and OttlTransformConfig also gained deny_unknown_fields, restoring the old adapter's rejection of unknown keys (e.g. a stray traces.spanevent block). Startup translation is strict, so either failure mode now fails config load before the agent starts, matching the removed adapter's behavior. Added regression tests covering both cases plus an environment-variable round-trip for the new enum leaf.

@pr-commenter

pr-commenter Bot commented Aug 5, 2026

Copy link
Copy Markdown

Regression Detector (Agent Data Plane)

Run ID: ddae51af-f99b-40d2-820c-248918c4f1e0
Baseline: be50909a · Comparison: 5e2ad06e · diff

Optimization Goals: ✅ No significant changes detected

Fine details of change detection per experiment (5)

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_dsd_medium memory ⚪ +0.09 metrics profiles logs
quality_gates_rss_dsd_heavy memory ⚪ -0.31 metrics profiles logs
quality_gates_rss_idle memory ⚪ -0.36 metrics profiles logs
quality_gates_rss_dsd_ultraheavy memory ⚪ -0.44 metrics profiles logs
quality_gates_rss_dsd_low memory ⚪ -0.88 metrics profiles logs
Bounds Checks: ✅ Passed (5)
experiment check replicates observed links
quality_gates_rss_dsd_heavy memory_usage 10/10 ✅ 230 MiB ≤ 250 MiB metrics profiles logs
quality_gates_rss_dsd_low memory_usage 10/10 ✅ 50.8 MiB ≤ 60 MiB metrics profiles logs
quality_gates_rss_dsd_medium memory_usage 10/10 ✅ 90.4 MiB ≤ 100 MiB metrics profiles logs
quality_gates_rss_dsd_ultraheavy memory_usage 10/10 ✅ 383 MiB ≤ 420 MiB metrics profiles logs
quality_gates_rss_idle memory_usage 10/10 ✅ 31.6 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.

@webern
webern force-pushed the m/confra-ofilt branch 3 times, most recently from 1005c62 to fedf507 Compare August 6, 2026 12:13
@webern
webern force-pushed the m/confra-tobfs branch 2 times, most recently from 9b18bd0 to e7805fa Compare August 6, 2026 12:31
Base automatically changed from m/confra-tobfs to main August 6, 2026 13:06

@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 typed boundary retains the valid OTTL filter modes and conditions used by the existing correctness and SMP configurations, while enum discovery makes DD_OTTL_FILTER_CONFIG_ERROR_MODE reachable. No additional tests recommended: production inputs were unavailable and execution was blocked by unavailable toolchain/dependency downloads.

Was this helpful? React 👍 or 👎

Open Bits AI session

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

@webern
webern merged commit 2ce0908 into main Aug 10, 2026
93 checks passed
@webern
webern deleted the m/confra-ofilt branch August 10, 2026 16:36
dd-octo-sts Bot pushed a commit that referenced this pull request Aug 10, 2026
## Summary

Migrate the OTTL span filter processor to the typed traces
configuration. The processor now receives typed error-mode and
span-condition values, and its raw configuration adapter is removed.

## Change Type
- [x] Non-functional (chore, refactoring, docs)

## How did you test this PR?

- `make fmt`
- `make check-docs`
- `make check-clippy`
- `make check-all`
- OTTL filter tests: 13 passed
- `cargo check -p agent-data-plane --tests`

## References

- Progresses #2169
- Progresses #2193 2ce0908
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.

2 participants