mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 01:38:56 -04:00
Fix the charts and group by section on the Log Threshold alert detail page (#155327)
## Summary This PR fixes #155083 with the following changes: - Create a new field to store the action context for an alert under `ALERT_CONTEXT` (`kibana.alert.context`) for Log Threshold Rule. - Change the alert detail page to reference the `groupByKeys` under `ALERT_CONTEXT` for the group by section - Change the history chart to only display `12h` buckets I plan to do a follow up PR to add the ALERT_CONTEXT to the other Observability Rules which we will also need for our alert details pages. ### How to test 1. Index data using: https://github.com/elastic/high-cardinality-cluster/tree/main/high_cardinality_indexer by running the following command: ``` DATASET="fake_stack" EVENTS_PER_CYCLE=1 INDEX_INTERVAL=60000 ELASTICSEARCH_HOSTS=http://localhost:9200 node src/run.js ``` 2. Create a DataView for named "Admin Console" with the index pattern of `high-cardinality-data-fake_stack.admin-console-*` and the timestamp field set to `@timestamp` 3. Go to the Log Stream in Observability and change the index pattern to "Admin Console" 4. Create a rule that looks like: <img width="600" alt="image" src="https://user-images.githubusercontent.com/41702/232578891-e65a3f1a-457c-459a-8d7f-cadc85e7067c.png"> 5. Create a rule WITHOUT a group by that will trigger and check the alert detail page 6. Create a rule with a ratio WITHOUT a group by that will trigger and check the alert detail page 7. Create a rule with a ratio WITH a group by that will trigger and check the alert detail page --------- Co-authored-by: Kevin Delemme <kdelemme@gmail.com> Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
parent
937912b056
commit
78671f113c
6 changed files with 30 additions and 7 deletions
|
@ -7,6 +7,7 @@
|
|||
*/
|
||||
|
||||
import {
|
||||
ALERT_CONTEXT,
|
||||
ALERT_EVALUATION_THRESHOLD,
|
||||
ALERT_EVALUATION_VALUE,
|
||||
ALERT_EVALUATION_VALUES,
|
||||
|
@ -19,6 +20,7 @@ export const legacyExperimentalFieldMap = {
|
|||
required: false,
|
||||
},
|
||||
[ALERT_EVALUATION_VALUE]: { type: 'scaled_float', scaling_factor: 100, required: false },
|
||||
[ALERT_CONTEXT]: { type: 'object', array: false, required: false },
|
||||
[ALERT_EVALUATION_VALUES]: {
|
||||
type: 'scaled_float',
|
||||
scaling_factor: 100,
|
||||
|
|
|
@ -85,6 +85,7 @@ const EVENT_MODULE = 'event.module' as const;
|
|||
const ALERT_BUILDING_BLOCK_TYPE = `${ALERT_NAMESPACE}.building_block_type` as const;
|
||||
const ALERT_EVALUATION_THRESHOLD = `${ALERT_NAMESPACE}.evaluation.threshold` as const;
|
||||
const ALERT_EVALUATION_VALUE = `${ALERT_NAMESPACE}.evaluation.value` as const;
|
||||
const ALERT_CONTEXT = `${ALERT_NAMESPACE}.context` as const;
|
||||
const ALERT_EVALUATION_VALUES = `${ALERT_NAMESPACE}.evaluation.values` as const;
|
||||
|
||||
// Fields pertaining to the rule associated with the alert
|
||||
|
@ -133,6 +134,7 @@ const fields = {
|
|||
ALERT_RULE_CONSUMER,
|
||||
ALERT_RULE_PRODUCER,
|
||||
ALERT_REASON,
|
||||
ALERT_CONTEXT,
|
||||
ALERT_RISK_SCORE,
|
||||
ALERT_CASE_IDS,
|
||||
ALERT_RULE_AUTHOR,
|
||||
|
@ -194,6 +196,7 @@ export {
|
|||
ALERT_BUILDING_BLOCK_TYPE,
|
||||
ALERT_EVALUATION_THRESHOLD,
|
||||
ALERT_EVALUATION_VALUE,
|
||||
ALERT_CONTEXT,
|
||||
ALERT_EVALUATION_VALUES,
|
||||
ALERT_RULE_EXCEPTIONS_LIST,
|
||||
ALERT_RULE_NAMESPACE_FIELD,
|
||||
|
|
|
@ -131,6 +131,7 @@ const LogsRatioChart: React.FC<ChartProps> = ({
|
|||
const barSeries = useMemo(() => {
|
||||
return series.flatMap(({ points, id }) => points.map((point) => ({ ...point, groupBy: id })));
|
||||
}, [series]);
|
||||
|
||||
if (isLoading) {
|
||||
return <LoadingState />;
|
||||
} else if (hasError) {
|
||||
|
|
|
@ -8,7 +8,12 @@ import React, { useEffect, useState } from 'react';
|
|||
import { EuiFlexGroup, EuiFlexItem, EuiSpacer } from '@elastic/eui';
|
||||
import { LIGHT_THEME } from '@elastic/charts';
|
||||
import { EuiPanel } from '@elastic/eui';
|
||||
import { ALERT_END, ALERT_EVALUATION_VALUE, ALERT_START } from '@kbn/rule-data-utils';
|
||||
import {
|
||||
ALERT_CONTEXT,
|
||||
ALERT_END,
|
||||
ALERT_EVALUATION_VALUE,
|
||||
ALERT_START,
|
||||
} from '@kbn/rule-data-utils';
|
||||
import moment from 'moment';
|
||||
import { useTheme } from '@emotion/react';
|
||||
import { EuiTitle } from '@elastic/eui';
|
||||
|
@ -20,6 +25,7 @@ import {
|
|||
} from '@kbn/observability-alert-details';
|
||||
import { useEuiTheme } from '@elastic/eui';
|
||||
import { UI_SETTINGS } from '@kbn/data-plugin/public';
|
||||
import { get } from 'lodash';
|
||||
import { useKibanaContextForPlugin } from '../../../../hooks/use_kibana';
|
||||
import { getChartGroupNames } from '../../../../../common/utils/get_chart_group_names';
|
||||
import {
|
||||
|
@ -61,7 +67,9 @@ const AlertDetailsAppSection = ({
|
|||
rule.params.groupBy?.reduce(
|
||||
(selectedFields: Record<string, any>, field) => ({
|
||||
...selectedFields,
|
||||
...{ [field]: alert.fields[field] },
|
||||
...{
|
||||
[field]: get(alert.fields[ALERT_CONTEXT], ['groupByKeys', ...field.split('.')], null),
|
||||
},
|
||||
}),
|
||||
{}
|
||||
) || {};
|
||||
|
@ -232,7 +240,9 @@ const AlertDetailsAppSection = ({
|
|||
rule &&
|
||||
rule.params.criteria.length === 1 && (
|
||||
<EuiFlexItem>
|
||||
<LogsHistoryChart rule={rule} />
|
||||
<LogsHistoryChart
|
||||
rule={{ ...rule, params: { ...rule.params, timeSize: 12, timeUnit: 'h' } }}
|
||||
/>
|
||||
</EuiFlexItem>
|
||||
)
|
||||
);
|
||||
|
|
|
@ -68,7 +68,7 @@ export const useChartPreviewData = ({
|
|||
let seriesQueryB = ratio[1].data.series[0].points;
|
||||
let seriesId = 'ratio';
|
||||
// When groupBy and a filter is applied, return the ratio only for the filtered grouped-by
|
||||
if (ruleParams.groupBy.length && filterSeriesByGroupName) {
|
||||
if (ruleParams.groupBy?.length && filterSeriesByGroupName) {
|
||||
seriesId = filterSeriesByGroupName;
|
||||
seriesQueryA =
|
||||
ratio[0].data.series.find((series) => series.id === filterSeriesByGroupName)
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
import type * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import {
|
||||
ALERT_CONTEXT,
|
||||
ALERT_EVALUATION_THRESHOLD,
|
||||
ALERT_EVALUATION_VALUE,
|
||||
ALERT_REASON,
|
||||
|
@ -86,7 +87,7 @@ export type LogThresholdAlertFactory = (
|
|||
value: number,
|
||||
threshold: number,
|
||||
actions?: Array<{ actionGroup: LogThresholdActionGroups; context: AlertContext }>,
|
||||
additionalContext?: AdditionalContext
|
||||
rootLevelContext?: AdditionalContext
|
||||
) => LogThresholdAlert;
|
||||
export type LogThresholdAlertLimit = RuleExecutorServices<
|
||||
LogThresholdAlertState,
|
||||
|
@ -134,15 +135,21 @@ export const createLogThresholdExecutor = (libs: InfraBackendLibs) =>
|
|||
value,
|
||||
threshold,
|
||||
actions,
|
||||
additionalContext
|
||||
rootLevelContext
|
||||
) => {
|
||||
const alertContext =
|
||||
actions != null
|
||||
? actions.reduce((next, action) => ({ ...next, ...action.context }), {})
|
||||
: {};
|
||||
|
||||
const alert = alertWithLifecycle({
|
||||
id,
|
||||
fields: {
|
||||
[ALERT_EVALUATION_THRESHOLD]: threshold,
|
||||
[ALERT_EVALUATION_VALUE]: value,
|
||||
[ALERT_REASON]: reason,
|
||||
...flattenAdditionalContext(additionalContext),
|
||||
[ALERT_CONTEXT]: alertContext,
|
||||
...flattenAdditionalContext(rootLevelContext),
|
||||
},
|
||||
});
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue