-
Notifications
You must be signed in to change notification settings - Fork 8.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[RAM] Add shareable rule tag filter #130710
Conversation
@JiaweiWu LGTM so far! For the tags filter to work, I expect one change in this function call https://github.com/elastic/kibana/blob/main/x-pack/plugins/triggers_actions_ui/public/application/lib/rule_api/rules.ts#L40 where we need to pass the new tagsFilter along with the rest filters that are currently being passed. This means that this file https://github.com/elastic/kibana/blob/main/x-pack/plugins/triggers_actions_ui/public/application/lib/rule_api/map_filters_to_kql.ts needs to be changed as well. |
@elasticmachine merge upstream |
@mgiota I added changes to the |
@elasticmachine merge upstream |
Pinging @elastic/response-ops (Team:ResponseOps) |
@JiaweiWu I gave it a try and yep it works! I will have a look again a bit later and approve the PR. |
@@ -930,6 +942,13 @@ export const RulesList: React.FunctionComponent = () => { | |||
); | |||
}; | |||
|
|||
const getRuleTagFilter = () => { | |||
if (isRuleTagFilterEnabled) { | |||
return [<RuleTagFilter tags={tags} selectedTags={tagsFilter} onChange={setTagsFilter} />]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@JiaweiWu Since I had to do the loadRuleAggregations
logic on our side same way you did above in order to setTags
, I was wondering if it would make sense to make the tags
prop optional and have this logic implemented within the RuleTagFilter, if you know what I mean. The code I had to add is similar to what you have on your side, that's why I am wondering if we could avoid this repetition.
I don't mind merging current PR and have a follow up PR when there's more time. I just wanted to hear your opinion, regarding moving the aggregations on the tags field within the RuleTagFilter, so that consumer doesn't have to write this logic. What do you think?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We had a chat and I brought up the issue that the rules_list aggregations require filter parameters from other filters as well (actionTypes, ruleStatuses, etc.) which makes it outside of the responsibility of the tag filter component.
I'm currently working on refactoring and making the rules list shareable, which will involves moving the fetching logic into hooks. So I think that will indirectly solve this problem.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I approve this PR! Later on we could refactor so that the server requests the tags and the consumer doesn't have to pass any tags prop.
It would be great if we could get this PR merged soon, so that I can working on #127013 |
@@ -990,6 +1000,9 @@ export class RulesClient { | |||
snoozed: snoozedBuckets.reduce((acc, bucket) => acc + bucket.doc_count, 0), | |||
}; | |||
|
|||
const tagsBuckets = resp.aggregations.tags.buckets; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are we confident the buckets
are always there?
ES has a tendency to drop keys in aggs when there are no hits (such as a cluster with no rules in it or when a filter is applied).
Worth treading with caution and checking for undefined keys.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I tested it with rules that have no tags, but I'll add a fall back just in case
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Always build these things defensively, otherwise the UI breaks and we have no idea unless someone files an SDH.
Thanks 🙏
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looking great so far, had a couple of thoughts/questions in my first pass
@@ -226,6 +232,7 @@ export const RulesList: React.FunctionComponent = () => { | |||
JSON.stringify(typesFilter), | |||
JSON.stringify(actionTypesFilter), | |||
JSON.stringify(ruleStatusesFilter), | |||
JSON.stringify(tagsFilter), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think you need to worry about this in this PR but this code should be improved. It looks like we're doing multiple JSON.stringify
calls every render - we should redo this a bit to be more performant. WDYT?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@JiaweiWu In case it is useful, here's what I used https://github.com/elastic/kibana/blob/main/x-pack/plugins/observability/public/hooks/use_fetch_rules.ts#L36 when I moved this code under observability in a use_fetch_rules
hook. I got rid of JSON.stringify and used useCallback
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yep, this is getting improved in my rules_list refactor
...plugins/triggers_actions_ui/public/application/sections/rules_list/components/rules_list.tsx
Show resolved
Hide resolved
...ns/triggers_actions_ui/public/application/sections/rules_list/components/rule_tag_filter.tsx
Outdated
Show resolved
Hide resolved
@elasticmachine merge upstream |
@@ -345,6 +356,24 @@ export const RulesList: React.FunctionComponent = () => { | |||
} | |||
} | |||
|
|||
async function loadRuleTags() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I want to give more context to this function here. So there's an awkward behaviour when I added the tag filters to the aggregation, because we use 1 aggregation function to get a list of tags and all of the rule execution status values, if we started filtering down the aggregation with tag filters, the list of tags would also get filtered, and thus it would replace the list of available tags with a smaller subset of tags (which is incorrect).
To fix this, i considered only calling setState
on the tags list if the tagsFilter is empty. But this is also incorrect because we miss the edge case where the user adds new tags or a new rule while the tag filter is applied.
From there, I decided to add this function, which calls the aggregation with empty params, as a part of the data fetch. I think the downside here is we're doing the aggregation twice now, which has performance implications.
But aside from doing something client side like merging in new tags in react, we might eventually want to have a separate aggregation just to get a list of tags. Let me know if we want to do that in this PR or I could do it in another PR.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it possible to understand this more? How can I simulate this? Or can I see this happening on an older version of this PR?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I didn't have the tag filters passed into the aggregation for the previous commit, you can simulate it by checking out the previous commit and passing the tag filters:
rules_list.tsx:
async function loadRuleAggs() {
try {
const rulesAggs = await loadRuleAggregations({
http,
searchText,
typesFilter,
actionTypesFilter,
ruleExecutionStatusesFilter,
ruleStatusesFilter,
tagsFilter,
});
...
}
aggregate.ts:
export async function loadRuleAggregations({
const filters = mapFiltersToKql({
typesFilter,
actionTypesFilter,
ruleExecutionStatusesFilter,
ruleStatusesFilter,
tagsFilter,
});
...
}
Switching the experiment on and filter by tags using the dropdown, you'll notice the entire list of available tags gets filtered as well
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm
What about something like:
async function loadRuleAggs() {
try {
const rulesAggs = await loadRuleAggregations({
http,
searchText,
typesFilter,
actionTypesFilter,
ruleStatusesFilter,
tagsFilter,
});
if (rulesAggs?.ruleExecutionStatus) {
setRulesStatusesTotal(rulesAggs.ruleExecutionStatus);
}
if (rulesAggs?.ruleTags && rulesAggs?.ruleTags.length > tags.length) {
setTags(rulesAggs.ruleTags);
}
}
I guess this doesn't work if we delete a rule and a tag is only associated with that rule though
I think we should separate these two things out into separate "things" - api that is called that is assumed to return filtered data and a separate api call that is expected to return total data. We might need to add something to the lib/rule_api
layer too but it's too confusing to keep this logic as-is - definitely recommend some delineation here to make it clear in the future.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yea thought so, ok I'll add a new endpoint to expose tags
💔 Build FailedFailed CI StepsMetrics [docs]Module Count
Public APIs missing comments
Async chunks
Public APIs missing exports
Page load bundle
Unknown metric groupsAPI count
async chunk count
ESLint disabled line counts
Total ESLint disabled count
History
To update your PR or re-run it, just comment with: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM! Great work here
@elasticmachine merge upstream |
Hey there! It seems like I have to slightly bump the bundle size for |
@elasticmachine merge upstream |
💚 Build SucceededMetrics [docs]Module Count
Public APIs missing comments
Async chunks
Public APIs missing exports
Page load bundle
Unknown metric groupsAPI count
async chunk count
ESLint disabled line counts
Total ESLint disabled count
History
To update your PR or re-run it, just comment with: |
…hromium-to-print-pdf-part-1 * 'main' of github.com:elastic/kibana: (59 commits) [Cloud Posture] Enabled findings group by feature (elastic#131780) [EBT] Fix `userId` generation (elastic#131701) [RAM] Add shareable rule tag filter (elastic#130710) Optimize package installation performance, phase 2 (elastic#131627) [Screenshotting] instrument for benchmark tests using new EventLogger class (elastic#130356) [Connector] Adding internal route for requesting ad-hoc ServiceNow access token (elastic#131171) [ci] bump kibana-buildkite-library (elastic#131754) [Synthetics] UI clean up (elastic#131598) [RsponseOps] Fix flaky rules list test (elastic#131567) [Cases] Add severity field to create case (elastic#131626) [Discover] Monospace font in Document Explorer (elastic#131513) Sessions tab improvements (elastic#131583) Add cloud icon "ess-icon" at the end of the config keys in "alerting" documentation (elastic#131735) [DOCS] Updates deprecation text for legacy APIs (elastic#131741) [ci] break out skip patterns so they can change without triggering CI (elastic#131726) Adjust search session management page font size (elastic#131291) [Unified search] Fix uptime css problem (elastic#131730) [Actionable Observability] Link to filtered rules page (elastic#131629) Add openAPI specifications for cases endpoint (elastic#131275) Display rule API key owner to users who can manage API keys (elastic#131662) ... # Conflicts: # x-pack/plugins/screenshotting/server/formats/pdf/index.ts # x-pack/plugins/screenshotting/server/screenshots/observable.ts
* rule tag filter * lower case test subj * [CI] Auto-commit changed files from 'node scripts/eslint --no-cache --fix' * Tag filter and aggregation APIs * [CI] Auto-commit changed files from 'node scripts/eslint --no-cache --fix' * Fix and add more tests * Fix test * Fix test and add new function test * Addressed comments * Lint * Create new load tags function * bump bundle size Co-authored-by: kibanamachine <[email protected]>
Summary
Resolves: #130158
Adds a shareable rule tags filter, this is a new component that does not exist as a part of the rule list currently. Therefore, it is not being used, except as a shareable component (hidden behind a feature flag).
This change also required new aggregations on the tags field since we need a list of all tags that the user can filter on. So the alerting aggregation function was modified. API and E2E tests were written to cover this.