Skip to content
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

[Metrics Alerts] Handle invalid KQL in filterQuery #119557

Merged
merged 8 commits into from
Nov 30, 2021

Conversation

Zacqary
Copy link
Contributor

@Zacqary Zacqary commented Nov 23, 2021

Summary

Closes #119416

This PR will:

  • Add filterQuery validation to Metric Threshold and Inventory alerts on the frontend. If the KQL query bar is invalid, the alert cannot be saved.

Screen Shot 2021-11-23 at 5 40 01 PM

  • Handle any invalid filterQuery that makes it to the backend, for backwards compatibility. The frontend previously sent an empty filterQuery to the backend, but because the alert executor can also access the filterQueryText, it will validate the filterQueryText before evaluating anything and send an error alert if the query is invalid.

Checklist

@Zacqary Zacqary added release_note:fix Feature:Metrics UI Metrics UI feature v8.0.0 auto-backport Deprecated - use backport:version if exact versions are needed v8.1.0 Team: Actionable Observability - DEPRECATED For Observability Alerting and SLOs use "Team:obs-ux-management", for AIops "Team:obs-knowledge" v7.16.1 labels Nov 23, 2021
@Zacqary Zacqary marked this pull request as ready for review November 24, 2021 16:55
@Zacqary Zacqary requested a review from a team as a code owner November 24, 2021 16:55
@Zacqary
Copy link
Contributor Author

Zacqary commented Nov 24, 2021

Reverting a change where I imported some esKuery logic from @kbn/es-query instead of from the data plugin. Importing from the data plugin is deprecated and we're supposed to remove it by 8.1, but changing this ballooned the infra plugin bundle size to the point where it wouldn't pass CI.

We can avoid this by using async imports, but converting all the uses of convertKueryToElasticSearchQuery to async is kind of an invasive project, so I'm punting on this for now.

@Zacqary Zacqary enabled auto-merge (squash) November 24, 2021 21:48
@Zacqary
Copy link
Contributor Author

Zacqary commented Nov 24, 2021

@elasticmachine merge upstream

@Zacqary
Copy link
Contributor Author

Zacqary commented Nov 24, 2021

I have no idea why the page load bundle size is ballooning. I moved all new imports to async and it's still doing this. Very confused. If someone else can help figure this out I'd appreciate it.

@miltonhultgren
Copy link
Contributor

@elastic/kibana-operations Can you see anything in this PR that would cause the bundle to blow up?

Copy link
Contributor

@miltonhultgren miltonhultgren left a comment

Choose a reason for hiding this comment

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

LGTM, just a few code clarity questions 👍🏼

@@ -70,6 +70,7 @@ import { useKibanaContextForPlugin } from '../../../hooks/use_kibana';

import { ExpressionChart } from './expression_chart';
const FILTER_TYPING_DEBOUNCE_MS = 500;
export const QUERY_INVALID = Symbol('QUERY_INVALID');
Copy link
Contributor

Choose a reason for hiding this comment

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

Nit: For me a name like INVALID_QUERY_MARKER would be more clear.

Copy link
Contributor

Choose a reason for hiding this comment

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

Would it make sense to use unique symbol type and export that type to the other places where this is the value being passed in? So it's not "any symbol"?

@@ -10,7 +10,8 @@ import { esKuery } from '../../../../../src/plugins/data/public';

export const convertKueryToElasticSearchQuery = (
kueryExpression: string,
indexPattern: DataViewBase
indexPattern: DataViewBase,
swallowErrors: boolean = true
Copy link
Contributor

@miltonhultgren miltonhultgren Nov 25, 2021

Choose a reason for hiding this comment

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

Maybe we can convert this to a small helper instead and use composition for the same effect?
I think it's more clear at call site to read something like this instead:
tryOrFallback(convertKueryToElasticSearchQuery(kuery, indexPatterns), '')
This leaves the places that should throw more clear also by not sending the magic boolean into them.

@@ -34,9 +37,17 @@ export function validateMetricThreshold({
};
metric: string[];
};
} = {};
} & { filterQuery?: string[] } = {};
Copy link
Contributor

Choose a reason for hiding this comment

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

NIt: Can this type live as part of the ValidationResult type?

@@ -42,6 +42,7 @@ import { ExpressionChart } from './expression_chart';
import { useKibanaContextForPlugin } from '../../../hooks/use_kibana';

const FILTER_TYPING_DEBOUNCE_MS = 500;
export const QUERY_INVALID = Symbol('QUERY_INVALID');
Copy link
Contributor

Choose a reason for hiding this comment

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

I'm wondering if there is any benefit to having two symbols for this?

@@ -281,15 +286,16 @@ export const Expressions: React.FC<Props> = (props) => {
}, [alertParams.groupBy]);

const redundantFilterGroupBy = useMemo(() => {
if (!alertParams.filterQuery || !groupByFilterTestPatterns) return [];
const { filterQuery } = alertParams;
if (typeof filterQuery !== 'string' || !groupByFilterTestPatterns) return [];
Copy link
Contributor

Choose a reason for hiding this comment

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

Nit: I'd expect to compare filterQuery to QUERY_INVALID here instead (TypeScript should ensure it's a string in any other case)

@@ -74,6 +75,25 @@ export const createInventoryMetricThresholdExecutor = (libs: InfraBackendLibs) =
},
});

if (!params.filterQuery && params.filterQueryText) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Might be worth wrapping this in a function that calls out it's handling old alerts that didn't have the new guard

@mgiota
Copy link
Contributor

mgiota commented Nov 29, 2021

@elasticmachine merge upstream

@Zacqary Zacqary merged commit 611da24 into elastic:main Nov 30, 2021
@kibana-ci
Copy link
Collaborator

💚 Build Succeeded

Metrics [docs]

Async chunks

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

id before after diff
infra 928.7KB 991.0KB +62.3KB

Page load bundle

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

id before after diff
infra 88.3KB 62.2KB -26.1KB
Unknown metric groups

async chunk count

id before after diff
infra 13 14 +1

History

To update your PR or re-run it, just comment with:
@elasticmachine merge upstream

kibanamachine pushed a commit to kibanamachine/kibana that referenced this pull request Nov 30, 2021
* [Metrics Alerts] Handle invalid KQL in filterQuery

* Add test for malformed KQL, fix existing KQL tests

* Revert @kbn/es-query imports
kibanamachine pushed a commit to kibanamachine/kibana that referenced this pull request Nov 30, 2021
* [Metrics Alerts] Handle invalid KQL in filterQuery

* Add test for malformed KQL, fix existing KQL tests

* Revert @kbn/es-query imports
@kibanamachine
Copy link
Contributor

💚 Backport successful

Status Branch Result
8.0
7.16

The backport PRs will be merged automatically after passing CI.

kibanamachine added a commit that referenced this pull request Nov 30, 2021
* [Metrics Alerts] Handle invalid KQL in filterQuery

* Add test for malformed KQL, fix existing KQL tests

* Revert @kbn/es-query imports

Co-authored-by: Zacqary Adam Xeper <[email protected]>
kibanamachine added a commit that referenced this pull request Nov 30, 2021
* [Metrics Alerts] Handle invalid KQL in filterQuery

* Add test for malformed KQL, fix existing KQL tests

* Revert @kbn/es-query imports

Co-authored-by: Zacqary Adam Xeper <[email protected]>
@mgiota
Copy link
Contributor

mgiota commented Dec 1, 2021

@Zacqary I was looking into this PR and I need a few clarifications.

  • In the first bullet of the PR description you say If the KQL query bar is invalid, the alert cannot be saved.. Do you refer to the rule instead? I guess you mean that if the KQL query is not valid, when user clicks the Create rule button, then user gets a validation error and so the Rule can not be saved, right? Let's clarify this
  • Your screenshot shows two generated alerts, so this screenshot is an example of the second bullet, where an invalid filterQuery made it to the backend, for backwards compatibility, right? The message that appears in the reason column says Alert is using a malformed KQL query... I guess it should be Rule instead. Am I right?

Let's clarify the correct terminology here, because it gets a bit confusing. @jasonrhodes What are your thoughts?

TinLe pushed a commit to TinLe/kibana that referenced this pull request Dec 22, 2021
* [Metrics Alerts] Handle invalid KQL in filterQuery

* Add test for malformed KQL, fix existing KQL tests

* Revert @kbn/es-query imports
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
auto-backport Deprecated - use backport:version if exact versions are needed Feature:Metrics UI Metrics UI feature release_note:fix Team: Actionable Observability - DEPRECATED For Observability Alerting and SLOs use "Team:obs-ux-management", for AIops "Team:obs-knowledge" v7.16.1 v8.0.0 v8.1.0
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[Metrics UI] Metrics threshold stores malformed KQL as an empty filter
5 participants