Skip to content

[SLO] Fix dashboard filters not applied to SLO embeddable for grouping fields#255746

Merged
fkanout merged 8 commits intoelastic:mainfrom
fkanout:fix/slo-dashboard-cluster-filter-rewriting
Mar 25, 2026
Merged

[SLO] Fix dashboard filters not applied to SLO embeddable for grouping fields#255746
fkanout merged 8 commits intoelastic:mainfrom
fkanout:fix/slo-dashboard-cluster-filter-rewriting

Conversation

@fkanout
Copy link
Copy Markdown
Contributor

@fkanout fkanout commented Mar 3, 2026

Summary

Closes #198289

Dashboard-level filters (e.g. orchestrator.cluster.name, k8s.cluster.name) were silently dropped when applied to SLO embeddables in global dashboards. Two root causes:

  1. The SLO overview embeddable never subscribed to parent dashboard filters — it only used its own internal groupFilters, ignoring any filters set via the dashboard's KQL bar or control panels.
  2. The SLO summary index stores user-defined grouping values under a flattened slo.groupings.* field, but buildQueryFromFilters was called with ignoreFilterIfFieldNotInIndex: true, which silently discarded any filter whose field name didn't exist in the summary mapping (e.g. orchestrator.cluster.name is not a native summary field).

What changed

  • Embeddable filter propagation: The SLO overview embeddable now merges parent dashboard filters (via useFetchContext) with its own local filters before passing them downstream.
  • Client-side filter rewriting: A new shared utility (common/rewrite_slo_filters.ts) rewrites Kibana Filter objects whose field is not a native summary field — prefixing the field name with slo.groupings. in both meta.key and the query payload. This happens before buildQueryFromFilters, which now runs with ignoreFilterIfFieldNotInIndex: false.
  • Shared mapping properties: The summary index mapping properties are extracted into common/summary_mapping_properties.ts, imported by both the server-side component template and the client-side rewrite logic. This avoids duplication and ensures native-field detection stays in sync with the actual mapping.

How it works

When a dashboard filter like orchestrator.cluster.name: "prod" reaches the SLO hooks:

  1. rewriteFiltersForSloSummary checks the field against the summary mapping properties.
  2. orchestrator is not a top-level mapping key → the filter is rewritten to slo.groupings.orchestrator.cluster.name: "prod".
  3. buildQueryFromFilters now generates a valid ES query against the summary index.

Native summary fields (e.g. status, slo.tags, service.name) pass through untouched.

Screen.Recording.2026-03-03.at.10.55.59.mov

Files changed

Area Files What
Common common/summary_mapping_properties.ts Extracted mapping properties (single source of truth)
Common common/rewrite_slo_filters.ts Client-side filter field rewriting
Embeddable public/embeddable/slo/overview/slo_embeddable_factory.tsx Subscribe to dashboard filters via useFetchContext
Hooks use_fetch_slo_list.ts, use_fetch_slo_groups.ts, use_fetch_slos_overview.ts Apply rewriteFiltersForSloSummary before buildQueryFromFilters
Server summary_mappings_template.ts Import properties from common
Tests common/rewrite_slo_filters.test.ts 14 unit tests for the rewrite logic
Tests transform_generators/common.test.ts Updated server-side tests
Tests find_slo_with_cluster_filter.ts E2E integration test for cluster filtering

Test plan

  • Unit tests for rewriteFilterForSloSummary covering term, match_phrase, exists, bool, native fields, leaf-field subpaths, and edge cases (14 tests)
  • Server-side parseStringFilters tests updated
  • E2E integration test: create SLO with orchestrator.cluster.name grouping, query overview endpoint with cluster filter, verify results
  • Manual: create an SLO grouped by orchestrator.cluster.name, add SLO overview panel to a dashboard, add a dashboard control for orchestrator.cluster.name, verify filtering works

Made with Cursor

…g fields

Dashboard-level filters using fields like `orchestrator.cluster.name` were
silently dropped by the SLO embeddable because:

1. The SLO overview embeddable did not subscribe to parent dashboard filters
   via `useFetchContext`, so global filters were never forwarded.
2. The SLO summary index stores grouping values under a flattened
   `slo.groupings.*` namespace, but `buildQueryFromFilters` with
   `ignoreFilterIfFieldNotInIndex: true` discarded filters whose field
   names didn't match the summary index mapping.

This commit fixes both issues:

- Merge dashboard filters with embeddable-local filters in the SLO overview
  factory using `useFetchContext`.
- Rewrite non-native filter field names to their `slo.groupings.*` equivalents
  on the client side before calling `buildQueryFromFilters`, and flip
  `ignoreFilterIfFieldNotInIndex` to `false` so rewritten filters are always
  included in the ES query.
- Extract summary mapping properties into a shared `common/` module so the
  rewrite logic derives native fields from the actual mapping definition rather
  than a hardcoded list.
- Remove the now-unnecessary server-side query DSL rewriting from
  `parseStringFilters`.
- Add unit tests for filter rewriting and integration test for the overview
  endpoint with cluster filters.

Closes elastic#198289

Made-with: Cursor
@fkanout fkanout requested a review from a team as a code owner March 3, 2026 11:24
@github-actions github-actions Bot added the author:actionable-obs PRs authored by the actionable obs team label Mar 3, 2026
@fkanout fkanout self-assigned this Mar 3, 2026
@fkanout fkanout added release_note:fix Team:actionable-obs Formerly "obs-ux-management", responsible for SLO, o11y alerting, significant events, & synthetics. backport:version Backport to applied version labels v9.3.0 v9.4.0 labels Mar 3, 2026
@elasticmachine
Copy link
Copy Markdown
Contributor

Pinging @elastic/actionable-obs-team (Team:actionable-obs)


export const SUMMARY_MAPPINGS_TEMPLATE: ClusterPutComponentTemplateRequest = {
name: SUMMARY_COMPONENT_TEMPLATE_MAPPINGS_NAME,
template: {
mappings: {
properties: {
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.

The runtime values of the original inline properties object and SUMMARY_MAPPING_PROPERTIES produce the exact same JSON

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.

not ideal to move this out the server. kind of scared someone will update the summary_mapping_properties.ts later on. Do we need to export this to common? On what fields do we expect to do filtering on?

Comment on lines +9 to +18
import { SUMMARY_MAPPING_PROPERTIES } from './summary_mapping_properties';

const SLO_GROUPINGS_PREFIX = 'slo.groupings.';

const SUMMARY_TOP_LEVEL_KEYS = Object.keys(SUMMARY_MAPPING_PROPERTIES);
const SUMMARY_NATIVE_FIELDS = new Set(SUMMARY_TOP_LEVEL_KEYS);
const SUMMARY_NATIVE_PREFIXES = SUMMARY_TOP_LEVEL_KEYS.filter((key) => {
const val = (SUMMARY_MAPPING_PROPERTIES as Record<string, unknown>)[key];
return val != null && typeof val === 'object' && 'properties' in val;
}).map((key) => `${key}.`);
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.

I think we should not move the mappings definition.

Can we introduce an allow list of fields that we consider useful, e.g. slo.id, slo.tags, slo.groupings.*, service.*, transaction.*, monitor.*, observer.* ?

I don't think others fields are that useful to filter upon

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.

done

@kdelemme
Copy link
Copy Markdown
Contributor

kdelemme commented Mar 3, 2026

I'll try to review and test this properly this week

const mergedFilters = useMemo(
() => [...(groupFilters?.filters ?? []), ...(fetchContext.filters ?? [])],
[groupFilters?.filters, fetchContext.filters]
);
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.

Do you think we could have a rewrite_filter here that transforms the fetchContext.filters by adding the slo.grouping. prefix to every fields? We wouldn't need to make any change in the existing hooks by doing that?

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.

Done

@fkanout fkanout requested a review from kdelemme March 4, 2026 11:04
fkanout added 4 commits March 4, 2026 12:30
…luster-filter-rewriting

Made-with: Cursor

# Conflicts:
#	x-pack/solutions/observability/plugins/slo/public/embeddable/slo/overview/slo_embeddable_factory.tsx
const mergedFilters = useMemo(
() => [
...(toStoredFilters(groupFilters?.filters) ?? []),
...rewriteFiltersForSloSummary(fetchContext.filters ?? []),
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.

Thanks for making this change, it feels much better to handle this only here and leak the transformation inside the hooks used in other places than the embeddable 👍🏻

Comment on lines +37 to +39
if (!field || field.startsWith(SLO_GROUPINGS_PREFIX) || isSummaryNativeField(field)) {
return filter;
}
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.

I guess SLO_GROUPINGS_PREFIX can be part of SUMMARY_NATIVE_PREFIXES and checked by isSummaryNativeField?

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.

Done b2dc97d

@elasticmachine
Copy link
Copy Markdown
Contributor

💛 Build succeeded, but was flaky

Failed CI Steps

Test Failures

  • [job] [logs] Jest Integration Tests #8 / unrecognized task types should be no workload aggregator errors when there are removed task types

Metrics [docs]

Module Count

Fewer modules leads to a faster build time

id before after diff
slo 1469 1470 +1

Async chunks

Total size of all lazy-loaded chunks that will be downloaded as the user navigates the app

id before after diff
slo 1.1MB 1.1MB +697.0B

Page load bundle

Size of the bundles that are downloaded on every page load. Target size is below 100kb

id before after diff
slo 36.0KB 36.0KB -1.0B

History

cc @fkanout

.set(adminRoleAuthc.apiKeyHeader)
.set(internalHeaders)
.send()
.expect(200);
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.

Interesting that we are testing this API, did the LLM hallucinate the API used behind the overview embeddable? overview embeddable -> /overview API? 😅

I mean it's not bad to test this API (it is used for the stats shown on the listing page), but it's unrelated to your change :)

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.

“LLM hallucination”? Maybe 😆 My guess is it came from my prompt about tests, since I usually ask for broad coverage, starting with edge cases.

expect(result.query).toEqual({ term: { 'service.name': 'my-svc' } });
});

it('leaves native prefixed fields unchanged', () => {
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.

👍🏻

Copy link
Copy Markdown
Contributor

@kdelemme kdelemme left a comment

Choose a reason for hiding this comment

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

Looking good, thanks for the changes. One more thing about adding slo.groupings into the SUMMARY_NATIVE_PREFIXES so we can use only isSummaryNativeField...

And the integration test is somewhat irrelevant to the codepath changed but still we can keep it :)

I'm going to test it locally now

@kdelemme
Copy link
Copy Markdown
Contributor

kdelemme commented Mar 6, 2026

Tested locally, works fine
image

Copy link
Copy Markdown
Contributor

@kdelemme kdelemme left a comment

Choose a reason for hiding this comment

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

Approving to not block you further

…luster-filter-rewriting

Made-with: Cursor

# Conflicts:
#	x-pack/solutions/observability/plugins/slo/public/embeddable/slo/overview/slo_embeddable_factory.tsx
@fkanout fkanout enabled auto-merge (squash) March 25, 2026 11:39
…mary

slo.groupings.* is already covered by the 'slo.' entry in
SUMMARY_NATIVE_PREFIXES, making the explicit startsWith check
unnecessary.

Made-with: Cursor
@macroscopeapp
Copy link
Copy Markdown
Contributor

macroscopeapp Bot commented Mar 25, 2026

Approvability

Verdict: Needs human review

This bug fix changes runtime query behavior by modifying ignoreFilterIfFieldNotInIndex from true to false in multiple hooks and introduces filter rewriting logic for SLO embeddables. While the author owns all changed files and the changes include comprehensive tests, the behavioral impact on SLO filtering warrants human review.

You can customize Macroscope's approvability policy. Learn more.

@fkanout fkanout merged commit a201390 into elastic:main Mar 25, 2026
20 checks passed
@kibanamachine
Copy link
Copy Markdown
Contributor

Starting backport for target branches: 9.3

https://github.com/elastic/kibana/actions/runs/23543293966

@kibanamachine
Copy link
Copy Markdown
Contributor

💔 All backports failed

Status Branch Result
9.3 Backport failed because of merge conflicts

You might need to backport the following PRs to 9.3:
- feat(slo): introduce SLO templates API (#246778)

Manual backport

To create the backport manually run:

node scripts/backport --pr 255746

Questions ?

Please refer to the Backport tool documentation

jeramysoucy pushed a commit to jeramysoucy/kibana that referenced this pull request Mar 26, 2026
…g fields (elastic#255746)

## Summary
Closes elastic#198289

Dashboard-level filters (e.g. `orchestrator.cluster.name`,
`k8s.cluster.name`) were silently dropped when applied to SLO
embeddables in global dashboards. Two root causes:

1. The SLO overview embeddable never subscribed to parent dashboard
filters — it only used its own internal `groupFilters`, ignoring any
filters set via the dashboard's KQL bar or control panels.
2. The SLO summary index stores user-defined grouping values under a
flattened `slo.groupings.*` field, but `buildQueryFromFilters` was
called with `ignoreFilterIfFieldNotInIndex: true`, which silently
discarded any filter whose field name didn't exist in the summary
mapping (e.g. `orchestrator.cluster.name` is not a native summary
field).

### What changed

- **Embeddable filter propagation**: The SLO overview embeddable now
merges parent dashboard filters (via `useFetchContext`) with its own
local filters before passing them downstream.
- **Client-side filter rewriting**: A new shared utility
(`common/rewrite_slo_filters.ts`) rewrites Kibana `Filter` objects whose
field is not a native summary field — prefixing the field name with
`slo.groupings.` in both `meta.key` and the query payload. This happens
before `buildQueryFromFilters`, which now runs with
`ignoreFilterIfFieldNotInIndex: false`.
- **Shared mapping properties**: The summary index mapping properties
are extracted into `common/summary_mapping_properties.ts`, imported by
both the server-side component template and the client-side rewrite
logic. This avoids duplication and ensures native-field detection stays
in sync with the actual mapping.

### How it works

When a dashboard filter like `orchestrator.cluster.name: "prod"` reaches
the SLO hooks:

1. `rewriteFiltersForSloSummary` checks the field against the summary
mapping properties.
2. `orchestrator` is not a top-level mapping key → the filter is
rewritten to `slo.groupings.orchestrator.cluster.name: "prod"`.
3. `buildQueryFromFilters` now generates a valid ES query against the
summary index.

Native summary fields (e.g. `status`, `slo.tags`, `service.name`) pass
through untouched.



https://github.com/user-attachments/assets/9e086fa4-7f66-4461-aa60-1a7a0afc9faf


### Files changed

| Area | Files | What |
|------|-------|------|
| Common | `common/summary_mapping_properties.ts` | Extracted mapping
properties (single source of truth) |
| Common | `common/rewrite_slo_filters.ts` | Client-side filter field
rewriting |
| Embeddable |
`public/embeddable/slo/overview/slo_embeddable_factory.tsx` | Subscribe
to dashboard filters via `useFetchContext` |
| Hooks | `use_fetch_slo_list.ts`, `use_fetch_slo_groups.ts`,
`use_fetch_slos_overview.ts` | Apply `rewriteFiltersForSloSummary`
before `buildQueryFromFilters` |
| Server | `summary_mappings_template.ts` | Import properties from
common |
| Tests | `common/rewrite_slo_filters.test.ts` | 14 unit tests for the
rewrite logic |
| Tests | `transform_generators/common.test.ts` | Updated server-side
tests |
| Tests | `find_slo_with_cluster_filter.ts` | E2E integration test for
cluster filtering |

## Test plan

- [x] Unit tests for `rewriteFilterForSloSummary` covering term,
match_phrase, exists, bool, native fields, leaf-field subpaths, and edge
cases (14 tests)
- [x] Server-side `parseStringFilters` tests updated
- [x] E2E integration test: create SLO with `orchestrator.cluster.name`
grouping, query overview endpoint with cluster filter, verify results
- [ ] Manual: create an SLO grouped by `orchestrator.cluster.name`, add
SLO overview panel to a dashboard, add a dashboard control for
`orchestrator.cluster.name`, verify filtering works


Made with [Cursor](https://cursor.com)
@kibanamachine kibanamachine added the backport missing Added to PRs automatically when the are determined to be missing a backport. label Mar 27, 2026
@kibanamachine
Copy link
Copy Markdown
Contributor

Friendly reminder: Looks like this PR hasn’t been backported yet.
To create automatically backports add a backport:* label or prevent reminders by adding the backport:skip label.
You can also create backports manually by running node scripts/backport --pr 255746 locally
cc: @fkanout

1 similar comment
@kibanamachine
Copy link
Copy Markdown
Contributor

Friendly reminder: Looks like this PR hasn’t been backported yet.
To create automatically backports add a backport:* label or prevent reminders by adding the backport:skip label.
You can also create backports manually by running node scripts/backport --pr 255746 locally
cc: @fkanout

@fkanout fkanout removed the v9.3.0 label Mar 30, 2026
@kibanamachine
Copy link
Copy Markdown
Contributor

Friendly reminder: Looks like this PR hasn’t been backported yet.
To create automatically backports add a backport:* label or prevent reminders by adding the backport:skip label.
You can also create backports manually by running node scripts/backport --pr 255746 locally
cc: @fkanout

jeramysoucy pushed a commit to jeramysoucy/kibana that referenced this pull request Apr 1, 2026
…g fields (elastic#255746)

## Summary
Closes elastic#198289

Dashboard-level filters (e.g. `orchestrator.cluster.name`,
`k8s.cluster.name`) were silently dropped when applied to SLO
embeddables in global dashboards. Two root causes:

1. The SLO overview embeddable never subscribed to parent dashboard
filters — it only used its own internal `groupFilters`, ignoring any
filters set via the dashboard's KQL bar or control panels.
2. The SLO summary index stores user-defined grouping values under a
flattened `slo.groupings.*` field, but `buildQueryFromFilters` was
called with `ignoreFilterIfFieldNotInIndex: true`, which silently
discarded any filter whose field name didn't exist in the summary
mapping (e.g. `orchestrator.cluster.name` is not a native summary
field).

### What changed

- **Embeddable filter propagation**: The SLO overview embeddable now
merges parent dashboard filters (via `useFetchContext`) with its own
local filters before passing them downstream.
- **Client-side filter rewriting**: A new shared utility
(`common/rewrite_slo_filters.ts`) rewrites Kibana `Filter` objects whose
field is not a native summary field — prefixing the field name with
`slo.groupings.` in both `meta.key` and the query payload. This happens
before `buildQueryFromFilters`, which now runs with
`ignoreFilterIfFieldNotInIndex: false`.
- **Shared mapping properties**: The summary index mapping properties
are extracted into `common/summary_mapping_properties.ts`, imported by
both the server-side component template and the client-side rewrite
logic. This avoids duplication and ensures native-field detection stays
in sync with the actual mapping.

### How it works

When a dashboard filter like `orchestrator.cluster.name: "prod"` reaches
the SLO hooks:

1. `rewriteFiltersForSloSummary` checks the field against the summary
mapping properties.
2. `orchestrator` is not a top-level mapping key → the filter is
rewritten to `slo.groupings.orchestrator.cluster.name: "prod"`.
3. `buildQueryFromFilters` now generates a valid ES query against the
summary index.

Native summary fields (e.g. `status`, `slo.tags`, `service.name`) pass
through untouched.



https://github.com/user-attachments/assets/9e086fa4-7f66-4461-aa60-1a7a0afc9faf


### Files changed

| Area | Files | What |
|------|-------|------|
| Common | `common/summary_mapping_properties.ts` | Extracted mapping
properties (single source of truth) |
| Common | `common/rewrite_slo_filters.ts` | Client-side filter field
rewriting |
| Embeddable |
`public/embeddable/slo/overview/slo_embeddable_factory.tsx` | Subscribe
to dashboard filters via `useFetchContext` |
| Hooks | `use_fetch_slo_list.ts`, `use_fetch_slo_groups.ts`,
`use_fetch_slos_overview.ts` | Apply `rewriteFiltersForSloSummary`
before `buildQueryFromFilters` |
| Server | `summary_mappings_template.ts` | Import properties from
common |
| Tests | `common/rewrite_slo_filters.test.ts` | 14 unit tests for the
rewrite logic |
| Tests | `transform_generators/common.test.ts` | Updated server-side
tests |
| Tests | `find_slo_with_cluster_filter.ts` | E2E integration test for
cluster filtering |

## Test plan

- [x] Unit tests for `rewriteFilterForSloSummary` covering term,
match_phrase, exists, bool, native fields, leaf-field subpaths, and edge
cases (14 tests)
- [x] Server-side `parseStringFilters` tests updated
- [x] E2E integration test: create SLO with `orchestrator.cluster.name`
grouping, query overview endpoint with cluster filter, verify results
- [ ] Manual: create an SLO grouped by `orchestrator.cluster.name`, add
SLO overview panel to a dashboard, add a dashboard control for
`orchestrator.cluster.name`, verify filtering works


Made with [Cursor](https://cursor.com)
@kibanamachine
Copy link
Copy Markdown
Contributor

Friendly reminder: Looks like this PR hasn’t been backported yet.
To create automatically backports add a backport:* label or prevent reminders by adding the backport:skip label.
You can also create backports manually by running node scripts/backport --pr 255746 locally
cc: @fkanout

paulinashakirova pushed a commit to paulinashakirova/kibana that referenced this pull request Apr 2, 2026
…g fields (elastic#255746)

## Summary
Closes elastic#198289

Dashboard-level filters (e.g. `orchestrator.cluster.name`,
`k8s.cluster.name`) were silently dropped when applied to SLO
embeddables in global dashboards. Two root causes:

1. The SLO overview embeddable never subscribed to parent dashboard
filters — it only used its own internal `groupFilters`, ignoring any
filters set via the dashboard's KQL bar or control panels.
2. The SLO summary index stores user-defined grouping values under a
flattened `slo.groupings.*` field, but `buildQueryFromFilters` was
called with `ignoreFilterIfFieldNotInIndex: true`, which silently
discarded any filter whose field name didn't exist in the summary
mapping (e.g. `orchestrator.cluster.name` is not a native summary
field).

### What changed

- **Embeddable filter propagation**: The SLO overview embeddable now
merges parent dashboard filters (via `useFetchContext`) with its own
local filters before passing them downstream.
- **Client-side filter rewriting**: A new shared utility
(`common/rewrite_slo_filters.ts`) rewrites Kibana `Filter` objects whose
field is not a native summary field — prefixing the field name with
`slo.groupings.` in both `meta.key` and the query payload. This happens
before `buildQueryFromFilters`, which now runs with
`ignoreFilterIfFieldNotInIndex: false`.
- **Shared mapping properties**: The summary index mapping properties
are extracted into `common/summary_mapping_properties.ts`, imported by
both the server-side component template and the client-side rewrite
logic. This avoids duplication and ensures native-field detection stays
in sync with the actual mapping.

### How it works

When a dashboard filter like `orchestrator.cluster.name: "prod"` reaches
the SLO hooks:

1. `rewriteFiltersForSloSummary` checks the field against the summary
mapping properties.
2. `orchestrator` is not a top-level mapping key → the filter is
rewritten to `slo.groupings.orchestrator.cluster.name: "prod"`.
3. `buildQueryFromFilters` now generates a valid ES query against the
summary index.

Native summary fields (e.g. `status`, `slo.tags`, `service.name`) pass
through untouched.



https://github.com/user-attachments/assets/9e086fa4-7f66-4461-aa60-1a7a0afc9faf


### Files changed

| Area | Files | What |
|------|-------|------|
| Common | `common/summary_mapping_properties.ts` | Extracted mapping
properties (single source of truth) |
| Common | `common/rewrite_slo_filters.ts` | Client-side filter field
rewriting |
| Embeddable |
`public/embeddable/slo/overview/slo_embeddable_factory.tsx` | Subscribe
to dashboard filters via `useFetchContext` |
| Hooks | `use_fetch_slo_list.ts`, `use_fetch_slo_groups.ts`,
`use_fetch_slos_overview.ts` | Apply `rewriteFiltersForSloSummary`
before `buildQueryFromFilters` |
| Server | `summary_mappings_template.ts` | Import properties from
common |
| Tests | `common/rewrite_slo_filters.test.ts` | 14 unit tests for the
rewrite logic |
| Tests | `transform_generators/common.test.ts` | Updated server-side
tests |
| Tests | `find_slo_with_cluster_filter.ts` | E2E integration test for
cluster filtering |

## Test plan

- [x] Unit tests for `rewriteFilterForSloSummary` covering term,
match_phrase, exists, bool, native fields, leaf-field subpaths, and edge
cases (14 tests)
- [x] Server-side `parseStringFilters` tests updated
- [x] E2E integration test: create SLO with `orchestrator.cluster.name`
grouping, query overview endpoint with cluster filter, verify results
- [ ] Manual: create an SLO grouped by `orchestrator.cluster.name`, add
SLO overview panel to a dashboard, add a dashboard control for
`orchestrator.cluster.name`, verify filtering works


Made with [Cursor](https://cursor.com)
@kibanamachine
Copy link
Copy Markdown
Contributor

Friendly reminder: Looks like this PR hasn’t been backported yet.
To create automatically backports add a backport:* label or prevent reminders by adding the backport:skip label.
You can also create backports manually by running node scripts/backport --pr 255746 locally
cc: @fkanout

11 similar comments
@kibanamachine
Copy link
Copy Markdown
Contributor

Friendly reminder: Looks like this PR hasn’t been backported yet.
To create automatically backports add a backport:* label or prevent reminders by adding the backport:skip label.
You can also create backports manually by running node scripts/backport --pr 255746 locally
cc: @fkanout

@kibanamachine
Copy link
Copy Markdown
Contributor

Friendly reminder: Looks like this PR hasn’t been backported yet.
To create automatically backports add a backport:* label or prevent reminders by adding the backport:skip label.
You can also create backports manually by running node scripts/backport --pr 255746 locally
cc: @fkanout

@kibanamachine
Copy link
Copy Markdown
Contributor

Friendly reminder: Looks like this PR hasn’t been backported yet.
To create automatically backports add a backport:* label or prevent reminders by adding the backport:skip label.
You can also create backports manually by running node scripts/backport --pr 255746 locally
cc: @fkanout

@kibanamachine
Copy link
Copy Markdown
Contributor

Friendly reminder: Looks like this PR hasn’t been backported yet.
To create automatically backports add a backport:* label or prevent reminders by adding the backport:skip label.
You can also create backports manually by running node scripts/backport --pr 255746 locally
cc: @fkanout

@kibanamachine
Copy link
Copy Markdown
Contributor

Friendly reminder: Looks like this PR hasn’t been backported yet.
To create automatically backports add a backport:* label or prevent reminders by adding the backport:skip label.
You can also create backports manually by running node scripts/backport --pr 255746 locally
cc: @fkanout

@kibanamachine
Copy link
Copy Markdown
Contributor

Friendly reminder: Looks like this PR hasn’t been backported yet.
To create automatically backports add a backport:* label or prevent reminders by adding the backport:skip label.
You can also create backports manually by running node scripts/backport --pr 255746 locally
cc: @fkanout

@kibanamachine
Copy link
Copy Markdown
Contributor

Friendly reminder: Looks like this PR hasn’t been backported yet.
To create automatically backports add a backport:* label or prevent reminders by adding the backport:skip label.
You can also create backports manually by running node scripts/backport --pr 255746 locally
cc: @fkanout

@kibanamachine
Copy link
Copy Markdown
Contributor

Friendly reminder: Looks like this PR hasn’t been backported yet.
To create automatically backports add a backport:* label or prevent reminders by adding the backport:skip label.
You can also create backports manually by running node scripts/backport --pr 255746 locally
cc: @fkanout

@kibanamachine
Copy link
Copy Markdown
Contributor

Friendly reminder: Looks like this PR hasn’t been backported yet.
To create automatically backports add a backport:* label or prevent reminders by adding the backport:skip label.
You can also create backports manually by running node scripts/backport --pr 255746 locally
cc: @fkanout

@kibanamachine
Copy link
Copy Markdown
Contributor

Friendly reminder: Looks like this PR hasn’t been backported yet.
To create automatically backports add a backport:* label or prevent reminders by adding the backport:skip label.
You can also create backports manually by running node scripts/backport --pr 255746 locally
cc: @fkanout

@kibanamachine
Copy link
Copy Markdown
Contributor

Friendly reminder: Looks like this PR hasn’t been backported yet.
To create automatically backports add a backport:* label or prevent reminders by adding the backport:skip label.
You can also create backports manually by running node scripts/backport --pr 255746 locally
cc: @fkanout

@fkanout fkanout added the backport:skip This PR does not require backporting label Apr 14, 2026
@kibanamachine kibanamachine removed the backport missing Added to PRs automatically when the are determined to be missing a backport. label Apr 14, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

author:actionable-obs PRs authored by the actionable obs team backport:skip This PR does not require backporting backport:version Backport to applied version labels release_note:fix Team:actionable-obs Formerly "obs-ux-management", responsible for SLO, o11y alerting, significant events, & synthetics. v9.4.0

4 participants