feat(emit): inject attributes/keep upstream of each sketch processor (B3) - #278
Merged
Merged
Conversation
…g crate (B7.5, schema-retirement #5 step 4) After #273 (modern execute() handles sketches via instances_matching) and #277 (saturating_sub for time=0 + dangling-callers cleanup), the legacy `handle_query` / `handle_query_promql` family no longer has features the modern `QueryEngine::execute()` trait can't handle. This PR deletes the whole legacy tree and the orphan `crates/promql_utilities/src/ast_matching/` module that only the legacy path consumed. Deleted: * `ASAPQueryEngine::handle_query`, `ASAPQueryEngine::handle_query_promql`, `ASAPQueryEngine::try_handle_query_promql_via_timeline` (instant-query entry points) * `ASAPQueryEngine::handle_range_query_promql`, `build_range_query_execution_context_promql`, `execute_range_query_pipeline`, `handle_binary_expr_range_promql`, `build_arm_range_context`, `apply_range_binary_op` (range-query entry point + helpers) * `execute_context`, `execute_query_pipeline`, `execute_store_query`, `execute_and_merge_store_queries` (legacy dispatcher chain) * `build_query_execution_context_promql*`, `build_promql_execution_context_tail`, `parse_and_match_promql`, `resolve_agg_info_promql`, `agg_info_from_forced_id`, `find_compatible_aggregation_with_miss_notify`, `resolve_metric_labels`, `calculate_query_timestamps_promql`, `calculate_start_timestamp_promql`, `validate_and_align_end_timestamp`, `extract_quantile_param_promql`, `extract_topk_param`, `build_query_kwargs_promql`, `create_keys_query_params`, `create_store_query_plan`, `collect_all_results`, `merge_precomputed_outputs`, `merge_accumulators`, `collect_results_separate_keys`, `collect_results_same_aggregation`, `limit_keys_for_topk`, `validate_range_query_params`, `format_final_results`, `build_query_requirements_promql`, `query_precompute_for_statistic` (legacy helpers) * `QueryExecutionContext`, `QueryMetadata`, `QueryTimestamps`, `StoreQueryParams`, `StoreQueryPlan`, `RangeQueryParams`, `RangeQueryExecutionContext` (legacy types) * `control_plane_patterns` field, the `PromQLPatternBuilder` setup in `new_with_hot_reload`, `QueryPatternType` enum * `crates/promql_utilities/src/ast_matching/` (4 files; only consumer was the legacy path) * `crates/promql_utilities/src/query_logics/parsing.rs` helpers (`get_metric_and_spatial_filter`, `get_statistics_to_compute`, `get_spatial_aggregation_output_labels`) * Test modules tied to the deleted surface: `range_query_tests`, `sketch_query_tests`, `e2e_feedback_loop_tests`, `forced_agg_id_tests`, `hll_count_query_tests`, `kll_quantile_query_tests`, `cms_rate_capability_tests`, `analyzer_parity_tests`, `calculate_start_timestamp_promql_tests`, `aux_pushdown_tests`, the whole `capability_matching_tests.rs` file and `tests/test_utilities/comparison.rs` Updated: * `data_plane/src/drivers/query/servers/http.rs::process_via_simple_engine` now calls modern `execute()` only. The capability-miss notify side-effect that used to live in `find_compatible_aggregation_with_miss_notify` is moved to the modern path's sid-resolution error branches AND to the "no-sketch-index attached" branch (HttpServer attaches its own `SketchStore` but the `ASAPQueryEngine` builder it hands off does not `.with_sketch_index(...)` — the e2e test `http_capability_miss_feedback_loop_closes_over_http` pins exactly that wiring). * `handle_range_query` now calls modern `execute_range_promql_modern` only — no legacy fallback. * `handle_precompute_job` routes through modern `execute()`. * `tests/schema_timeline_dispatch_tests.rs::single_schema_query_falls_through_to_default_path` moved to `#[ignore]` — its premise no longer has a callsite. Modern-path coverage lives in `asap_tier_classify_tests` and `e2e_modified_otlp_sketch_path`. Test plan: * `cargo test -p data_plane --lib`: 707 pass, 0 failed, 5 ignored (down from 754 — 47 tests deleted with the legacy code they exercised). * `cargo test -p data_plane --lib capability_miss_http_e2e`: 1 pass, 1 ignored — the feedback-loop test that pins the notify side-effect still passes. * `cargo test -p control_plane --lib`: 699 pass, 0 failed. The `try_handle_query_promql_via_timeline` cross-reconfigure dispatch path is gone too. Its functionality (per-segment dispatch across schema boundaries) was scheduled for a sid-level rewrite in the schema-retirement #5 follow-up; deferred to a separate PR since no current test exercises a multi-segment reconfigure boundary (the two `#[ignore]`d tests in `tests/schema_timeline_dispatch_tests.rs` documented as needing a sid-level rewrite anyway). Closes step 4 of #272. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This was referenced May 18, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
transform/keep_for_<sanitized_metric>OTTL processor in front of every sketch processor the controller emits, so the agent reduces wire attrs tostreaming_config.grouping_labelsbefore sketching.EdgeStageConfig::metric_to_grouping_labelsfield carries the per-metric allowlist; populated fromQueryWorkload::group_by_labelsby the main bootstrap, typed-stage-split, and replanner paths.Why
Today the controller emits sketch processors with no preceding attribute-reduction step. Real producers emit metrics with a wide attribute set (e.g.
{zone, rack, node, pod, endpoint, service.name, telemetry.sdk.*}= 9 keys), so the sketch processor mints one sid per unique attr tuple — 51 sids forhttp_requests_total_latency_msin the smoke test. With B3, sids are keyed on the streaming-config'sgrouping_labels(e.g. one per zone).Pairs with PR #273 (sid-resolution side fix): #273 makes the query path find UNREDUCED sids via subset-matching; this PR removes the need for the subset walk by ensuring the agent emits REDUCED sids in the first place. Both stay landed — the subset walk is the fallback for non-controller-managed sketches.
Implementation notes
transformoverattributes/keep: the attributes processor has no native allowlist action (only insert/update/delete/hash). OTTL'skeep_keys(datapoint.attributes, [...])is the right primitive and the transform processor is already in the asap-otel builder-config alongside attributes, filter, and groupbyattrs.transform/keep_for_<sanitized_metric>where the sanitiser replaces every non-[A-Za-z0-9_]byte with_(OTel component-id grammar rejects dots/dashes/slashes).where metric.name == "<metric>"guard: makes each statement a no-op on non-matching metrics — important because per-family pipelines see ALL metrics routed to that family by the connector, not just the controller's currently-planned one.[memory_limiter, gorillas3?, transform/keep_for_<metric>*, <family>processor, batch]. gorillas3 writes the cold tier on RAW samples (full wire attrs preserved in MinIO for drill-down) BEFORE the keep-processor strips attrs for the sketch's benefit.grouping_labelssupported — emitskeep_keys(datapoint.attributes, [])(planner's signal for one global sid per metric).Test plan
cargo test -p control_plane --lib— 699/699 pass (691 baseline + 8 new B3 tests).cargo build -p control_plane --lib— clean (only pre-existing warnings).http_requests_total_latency_msto drop from 51 to the cardinality of uniquezonevalues.New tests in
control_plane/src/emit/stage_config.rs::tests:b3_emits_transform_keep_processor_per_metric_with_grouping_labelsb3_transform_block_uses_keep_keys_ottl_with_correct_labelsb3_per_family_pipeline_prepends_keep_before_sketchb3_keep_lives_after_gorillas3_so_cold_tier_keeps_full_attrsb3_processor_name_sanitises_metric_special_charsb3_no_transform_processor_when_grouping_labels_absentb3_empty_grouping_label_list_emits_empty_keep_keysb3_legacy_emit_edge_yaml_injects_keep_for_source_metric🤖 Generated with Claude Code