Skip to content

Commit 312f073

Browse files
[Monitoring] Fix issues displaying alerts (#72891) (#72989)
* Fix issues displaying alerts * Fix type issues * More support for multiple alerts Co-authored-by: Elastic Machine <elasticmachine@users.noreply.github.com> Co-authored-by: Elastic Machine <elasticmachine@users.noreply.github.com>
1 parent aeacef5 commit 312f073

File tree

9 files changed

+313
-81
lines changed

9 files changed

+313
-81
lines changed

x-pack/plugins/monitoring/public/alerts/badge.tsx

Lines changed: 24 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -23,18 +23,25 @@ import { AlertPanel } from './panel';
2323
import { Legacy } from '../legacy_shims';
2424
import { isInSetupMode } from '../lib/setup_mode';
2525

26-
function getDateFromState(states: CommonAlertState[]) {
27-
const timestamp = states[0].state.ui.triggeredMS;
26+
function getDateFromState(state: CommonAlertState) {
27+
const timestamp = state.state.ui.triggeredMS;
2828
const tz = Legacy.shims.uiSettings.get('dateFormat:tz');
2929
return formatDateTimeLocal(timestamp, false, tz === 'Browser' ? null : tz);
3030
}
3131

3232
export const numberOfAlertsLabel = (count: number) => `${count} alert${count > 1 ? 's' : ''}`;
3333

34+
interface AlertInPanel {
35+
alert: CommonAlertStatus;
36+
alertState: CommonAlertState;
37+
}
38+
3439
interface Props {
3540
alerts: { [alertTypeId: string]: CommonAlertStatus };
41+
stateFilter: (state: AlertState) => boolean;
3642
}
3743
export const AlertsBadge: React.FC<Props> = (props: Props) => {
44+
const { stateFilter = () => true } = props;
3845
const [showPopover, setShowPopover] = React.useState<AlertSeverity | boolean | null>(null);
3946
const inSetupMode = isInSetupMode();
4047
const alerts = Object.values(props.alerts).filter(Boolean);
@@ -93,15 +100,20 @@ export const AlertsBadge: React.FC<Props> = (props: Props) => {
93100
);
94101
} else {
95102
const byType = {
96-
[AlertSeverity.Danger]: [] as CommonAlertStatus[],
97-
[AlertSeverity.Warning]: [] as CommonAlertStatus[],
98-
[AlertSeverity.Success]: [] as CommonAlertStatus[],
103+
[AlertSeverity.Danger]: [] as AlertInPanel[],
104+
[AlertSeverity.Warning]: [] as AlertInPanel[],
105+
[AlertSeverity.Success]: [] as AlertInPanel[],
99106
};
100107

101108
for (const alert of alerts) {
102109
for (const alertState of alert.states) {
103-
const state = alertState.state as AlertState;
104-
byType[state.ui.severity].push(alert);
110+
if (alertState.firing && stateFilter(alertState.state)) {
111+
const state = alertState.state as AlertState;
112+
byType[state.ui.severity].push({
113+
alertState,
114+
alert,
115+
});
116+
}
105117
}
106118
}
107119

@@ -127,14 +139,14 @@ export const AlertsBadge: React.FC<Props> = (props: Props) => {
127139
{
128140
id: 0,
129141
title: `Alerts`,
130-
items: list.map(({ alert, states }, index) => {
142+
items: list.map(({ alert, alertState }, index) => {
131143
return {
132144
name: (
133145
<Fragment>
134146
<EuiText size="s">
135-
<h4>{getDateFromState(states)}</h4>
147+
<h4>{getDateFromState(alertState)}</h4>
136148
</EuiText>
137-
<EuiText>{alert.label}</EuiText>
149+
<EuiText>{alert.alert.label}</EuiText>
138150
</Fragment>
139151
),
140152
panel: index + 1,
@@ -144,9 +156,9 @@ export const AlertsBadge: React.FC<Props> = (props: Props) => {
144156
...list.map((alertStatus, index) => {
145157
return {
146158
id: index + 1,
147-
title: getDateFromState(alertStatus.states),
159+
title: getDateFromState(alertStatus.alertState),
148160
width: 400,
149-
content: <AlertPanel alert={alertStatus} />,
161+
content: <AlertPanel alert={alertStatus.alert} alertState={alertStatus.alertState} />,
150162
};
151163
}),
152164
];

x-pack/plugins/monitoring/public/alerts/callout.tsx

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import { EuiCallOut, EuiSpacer } from '@elastic/eui';
1010
import { CommonAlertStatus } from '../../common/types';
1111
import { AlertSeverity } from '../../common/enums';
1212
import { replaceTokens } from './lib/replace_tokens';
13-
import { AlertMessage } from '../../server/alerts/types';
13+
import { AlertMessage, AlertState } from '../../server/alerts/types';
1414

1515
const TYPES = [
1616
{
@@ -31,16 +31,17 @@ const TYPES = [
3131

3232
interface Props {
3333
alerts: { [alertTypeId: string]: CommonAlertStatus };
34+
stateFilter: (state: AlertState) => boolean;
3435
}
3536
export const AlertsCallout: React.FC<Props> = (props: Props) => {
36-
const { alerts } = props;
37+
const { alerts, stateFilter = () => true } = props;
3738

3839
const callouts = TYPES.map((type) => {
3940
const list = [];
4041
for (const alertTypeId of Object.keys(alerts)) {
4142
const alertInstance = alerts[alertTypeId];
42-
for (const { state } of alertInstance.states) {
43-
if (state.ui.severity === type.severity) {
43+
for (const { firing, state } of alertInstance.states) {
44+
if (firing && stateFilter(state) && state.ui.severity === type.severity) {
4445
list.push(state);
4546
}
4647
}

x-pack/plugins/monitoring/public/alerts/panel.tsx

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ import {
1818
EuiListGroupItem,
1919
} from '@elastic/eui';
2020

21-
import { CommonAlertStatus } from '../../common/types';
21+
import { CommonAlertStatus, CommonAlertState } from '../../common/types';
2222
import { AlertMessage } from '../../server/alerts/types';
2323
import { Legacy } from '../legacy_shims';
2424
import { replaceTokens } from './lib/replace_tokens';
@@ -30,10 +30,12 @@ import { BASE_ALERT_API_PATH } from '../../../alerts/common';
3030

3131
interface Props {
3232
alert: CommonAlertStatus;
33+
alertState?: CommonAlertState;
3334
}
3435
export const AlertPanel: React.FC<Props> = (props: Props) => {
3536
const {
36-
alert: { states, alert },
37+
alert: { alert },
38+
alertState,
3739
} = props;
3840
const [showFlyout, setShowFlyout] = React.useState(false);
3941
const [isEnabled, setIsEnabled] = React.useState(alert.rawAlert.enabled);
@@ -190,20 +192,14 @@ export const AlertPanel: React.FC<Props> = (props: Props) => {
190192
</Fragment>
191193
);
192194

193-
if (inSetupMode) {
195+
if (inSetupMode || !alertState) {
194196
return <div style={{ padding: '1rem' }}>{configurationUi}</div>;
195197
}
196198

197-
const firingStates = states.filter((state) => state.firing);
198-
if (!firingStates.length) {
199-
return <div style={{ padding: '1rem' }}>{configurationUi}</div>;
200-
}
201-
202-
const firingState = firingStates[0];
203199
const nextStepsUi =
204-
firingState.state.ui.message.nextSteps && firingState.state.ui.message.nextSteps.length ? (
200+
alertState.state.ui.message.nextSteps && alertState.state.ui.message.nextSteps.length ? (
205201
<EuiListGroup>
206-
{firingState.state.ui.message.nextSteps.map((step: AlertMessage, index: number) => (
202+
{alertState.state.ui.message.nextSteps.map((step: AlertMessage, index: number) => (
207203
<EuiListGroupItem size="s" key={index} label={replaceTokens(step)} />
208204
))}
209205
</EuiListGroup>
@@ -213,7 +209,7 @@ export const AlertPanel: React.FC<Props> = (props: Props) => {
213209
<Fragment>
214210
<div style={{ padding: '1rem' }}>
215211
<EuiTitle size="xs">
216-
<h5>{replaceTokens(firingState.state.ui.message)}</h5>
212+
<h5>{replaceTokens(alertState.state.ui.message)}</h5>
217213
</EuiTitle>
218214
{nextStepsUi ? <EuiSpacer size="s" /> : null}
219215
{nextStepsUi}

x-pack/plugins/monitoring/public/alerts/status.tsx

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,36 +11,44 @@ import { CommonAlertStatus } from '../../common/types';
1111
import { AlertSeverity } from '../../common/enums';
1212
import { AlertState } from '../../server/alerts/types';
1313
import { AlertsBadge } from './badge';
14+
import { isInSetupMode } from '../lib/setup_mode';
1415

1516
interface Props {
1617
alerts: { [alertTypeId: string]: CommonAlertStatus };
1718
showBadge: boolean;
1819
showOnlyCount: boolean;
20+
stateFilter: (state: AlertState) => boolean;
1921
}
2022
export const AlertsStatus: React.FC<Props> = (props: Props) => {
21-
const { alerts, showBadge = false, showOnlyCount = false } = props;
23+
const { alerts, showBadge = false, showOnlyCount = false, stateFilter = () => true } = props;
24+
const inSetupMode = isInSetupMode();
2225

2326
if (!alerts) {
2427
return null;
2528
}
2629

2730
let atLeastOneDanger = false;
2831
const count = Object.values(alerts).reduce((cnt, alertStatus) => {
29-
if (alertStatus.states.length) {
32+
const firingStates = alertStatus.states.filter((state) => state.firing);
33+
const firingAndFilterStates = firingStates.filter((state) => stateFilter(state.state));
34+
cnt += firingAndFilterStates.length;
35+
if (firingStates.length) {
3036
if (!atLeastOneDanger) {
3137
for (const state of alertStatus.states) {
32-
if ((state.state as AlertState).ui.severity === AlertSeverity.Danger) {
38+
if (
39+
stateFilter(state.state) &&
40+
(state.state as AlertState).ui.severity === AlertSeverity.Danger
41+
) {
3342
atLeastOneDanger = true;
3443
break;
3544
}
3645
}
3746
}
38-
cnt++;
3947
}
4048
return cnt;
4149
}, 0);
4250

43-
if (count === 0) {
51+
if (count === 0 && (!inSetupMode || showOnlyCount)) {
4452
return (
4553
<EuiToolTip
4654
content={i18n.translate('xpack.monitoring.alerts.status.clearToolip', {
@@ -62,8 +70,8 @@ export const AlertsStatus: React.FC<Props> = (props: Props) => {
6270
);
6371
}
6472

65-
if (showBadge) {
66-
return <AlertsBadge alerts={alerts} />;
73+
if (showBadge || inSetupMode) {
74+
return <AlertsBadge alerts={alerts} stateFilter={stateFilter} />;
6775
}
6876

6977
const severity = atLeastOneDanger ? AlertSeverity.Danger : AlertSeverity.Warning;

x-pack/plugins/monitoring/public/components/elasticsearch/node/node.js

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,10 +60,14 @@ export const Node = ({
6060
<EuiPage>
6161
<EuiPageBody>
6262
<EuiPanel>
63-
<NodeDetailStatus stats={nodeSummary} alerts={alerts} />
63+
<NodeDetailStatus
64+
stats={nodeSummary}
65+
alerts={alerts}
66+
alertsStateFilter={(state) => state.nodeId === nodeId}
67+
/>
6468
</EuiPanel>
6569
<EuiSpacer size="m" />
66-
<AlertsCallout alerts={alerts} />
70+
<AlertsCallout alerts={alerts} stateFilter={(state) => state.nodeId === nodeId} />
6771
<EuiPageContent>
6872
<EuiFlexGrid columns={2} gutterSize="s">
6973
{metricsToShow.map((metric, index) => (

x-pack/plugins/monitoring/public/components/elasticsearch/node_detail_status/index.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import { formatMetric } from '../../../lib/format_number';
1111
import { i18n } from '@kbn/i18n';
1212
import { AlertsStatus } from '../../../alerts/status';
1313

14-
export function NodeDetailStatus({ stats, alerts = {} }) {
14+
export function NodeDetailStatus({ stats, alerts = {}, alertsStateFilter = () => true }) {
1515
const {
1616
transport_address: transportAddress,
1717
usedHeap,
@@ -33,7 +33,7 @@ export function NodeDetailStatus({ stats, alerts = {} }) {
3333
label: i18n.translate('xpack.monitoring.elasticsearch.nodeDetailStatus.alerts', {
3434
defaultMessage: 'Alerts',
3535
}),
36-
value: <AlertsStatus alerts={alerts} showOnlyCount={true} />,
36+
value: <AlertsStatus alerts={alerts} showOnlyCount={true} stateFilter={alertsStateFilter} />,
3737
},
3838
{
3939
label: i18n.translate('xpack.monitoring.elasticsearch.nodeDetailStatus.transportAddress', {

x-pack/plugins/monitoring/public/components/elasticsearch/nodes/nodes.js

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -129,8 +129,14 @@ const getColumns = (showCgroupMetricsElasticsearch, setupMode, clusterUuid, aler
129129
field: 'alerts',
130130
width: '175px',
131131
sortable: true,
132-
render: () => {
133-
return <AlertsStatus showBadge={true} alerts={alerts} />;
132+
render: (_field, node) => {
133+
return (
134+
<AlertsStatus
135+
showBadge={true}
136+
alerts={alerts}
137+
stateFilter={(state) => state.nodeId === node.resolver}
138+
/>
139+
);
134140
},
135141
});
136142

0 commit comments

Comments
 (0)