Skip to content

Commit

Permalink
Fix up stateFilter usage
Browse files Browse the repository at this point in the history
  • Loading branch information
chrisronline committed Dec 11, 2020
1 parent a33cf5e commit e4f7d04
Show file tree
Hide file tree
Showing 9 changed files with 81 additions and 31 deletions.
13 changes: 9 additions & 4 deletions x-pack/plugins/monitoring/public/alerts/badge.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
import React from 'react';
import { i18n } from '@kbn/i18n';
import { EuiContextMenu, EuiPopover, EuiBadge, EuiSwitch } from '@elastic/eui';
import { CommonAlertStatus } from '../../common/types/alerts';
import { AlertState, CommonAlertStatus } from '../../common/types/alerts';
import { AlertSeverity } from '../../common/enums';
// @ts-ignore
import { formatDateTimeLocal } from '../../common/formatting';
Expand Down Expand Up @@ -45,16 +45,21 @@ const GROUP_BY_TYPE = i18n.translate('xpack.monitoring.alerts.badge.groupByType'

interface Props {
alerts: CommonAlertStatus[];
stateFilter: (state: AlertState) => boolean;
}
export const AlertsBadge: React.FC<Props> = (props: Props) => {
// We do not always have the alerts that each consumer wants due to licensing
const { stateFilter = () => true } = props;
const alerts = props.alerts.filter(Boolean);
const [showPopover, setShowPopover] = React.useState<AlertSeverity | boolean | null>(null);
const inSetupMode = isInSetupMode(React.useContext(SetupModeContext));
const alertsContext = React.useContext(AlertsContext);
const alertCount = inSetupMode
? alerts.length
: alerts.reduce((sum, { states }) => sum + states.length, 0);
: alerts.reduce(
(sum, { states }) => sum + states.filter(({ state }) => stateFilter(state)).length,
0
);
const [showByNode, setShowByNode] = React.useState(
!inSetupMode && alertCount > MAX_TO_SHOW_BY_CATEGORY
);
Expand Down Expand Up @@ -86,8 +91,8 @@ export const AlertsBadge: React.FC<Props> = (props: Props) => {
}

const panels = showByNode
? getAlertPanelsByNode(PANEL_TITLE, alerts)
: getAlertPanelsByCategory(PANEL_TITLE, inSetupMode, alerts, alertsContext);
? getAlertPanelsByNode(PANEL_TITLE, alerts, stateFilter)
: getAlertPanelsByCategory(PANEL_TITLE, inSetupMode, alerts, alertsContext, stateFilter);

if (panels.length && !inSetupMode && panels[0].items) {
panels[0].items.push(
Expand Down
7 changes: 4 additions & 3 deletions x-pack/plugins/monitoring/public/alerts/callout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,17 +17,18 @@ import {
EuiIcon,
} from '@elastic/eui';
import { replaceTokens } from './lib/replace_tokens';
import { AlertMessage } from '../../common/types/alerts';
import { AlertMessage, AlertState } from '../../common/types/alerts';
import { AlertsByName } from './types';
import { isInSetupMode } from '../lib/setup_mode';
import { SetupModeContext } from '../components/setup_mode/setup_mode_context';
import { AlertConfiguration } from './configuration';

interface Props {
alerts: AlertsByName;
stateFilter: (state: AlertState) => boolean;
}
export const AlertsCallout: React.FC<Props> = (props: Props) => {
const { alerts } = props;
const { alerts, stateFilter = () => true } = props;
const inSetupMode = isInSetupMode(React.useContext(SetupModeContext));

if (inSetupMode) {
Expand All @@ -37,7 +38,7 @@ export const AlertsCallout: React.FC<Props> = (props: Props) => {
const list = [];
for (const alertTypeId of Object.keys(alerts)) {
const alertInstance = alerts[alertTypeId];
for (const state of alertInstance.states) {
for (const state of alertInstance.states.filter(({ state: _state }) => stateFilter(_state))) {
list.push({
alert: alertInstance,
state,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import {
} from '../../../common/constants';
import { AlertsByName } from '../types';
import { AlertExecutionStatusValues } from '../../../../alerts/common';
import { AlertState } from '../../../common/types/alerts';

jest.mock('../../legacy_shims', () => ({
Legacy: {
Expand Down Expand Up @@ -133,6 +134,7 @@ describe('getAlertPanelsByCategory', () => {
allAlerts: getAllAlerts(),
};

const stateFilter = (state: AlertState) => true;
const panelTitle = 'Alerts';

describe('non setup mode', () => {
Expand All @@ -142,13 +144,25 @@ describe('getAlertPanelsByCategory', () => {
getAlert(ALERT_DISK_USAGE, 1),
getAlert(ALERT_LICENSE_EXPIRATION, 2),
];
const result = getAlertPanelsByCategory(panelTitle, false, alerts, alertsContext);
const result = getAlertPanelsByCategory(
panelTitle,
false,
alerts,
alertsContext,
stateFilter
);
expect(result).toMatchSnapshot();
});

it('should properly group for alerts in a single category', () => {
const alerts = [getAlert(ALERT_MEMORY_USAGE, 2)];
const result = getAlertPanelsByCategory(panelTitle, false, alerts, alertsContext);
const result = getAlertPanelsByCategory(
panelTitle,
false,
alerts,
alertsContext,
stateFilter
);
expect(result).toMatchSnapshot();
});

Expand All @@ -158,7 +172,13 @@ describe('getAlertPanelsByCategory', () => {
getAlert(ALERT_CPU_USAGE, 0),
getAlert(ALERT_THREAD_POOL_WRITE_REJECTIONS, 0),
];
const result = getAlertPanelsByCategory(panelTitle, false, alerts, alertsContext);
const result = getAlertPanelsByCategory(
panelTitle,
false,
alerts,
alertsContext,
stateFilter
);
expect(result).toMatchSnapshot();
});
});
Expand All @@ -170,13 +190,13 @@ describe('getAlertPanelsByCategory', () => {
getAlert(ALERT_DISK_USAGE, 1),
getAlert(ALERT_LICENSE_EXPIRATION, 2),
];
const result = getAlertPanelsByCategory(panelTitle, true, alerts, alertsContext);
const result = getAlertPanelsByCategory(panelTitle, true, alerts, alertsContext, stateFilter);
expect(result).toMatchSnapshot();
});

it('should properly group for alerts in a single category', () => {
const alerts = [getAlert(ALERT_MEMORY_USAGE, 2)];
const result = getAlertPanelsByCategory(panelTitle, true, alerts, alertsContext);
const result = getAlertPanelsByCategory(panelTitle, true, alerts, alertsContext, stateFilter);
expect(result).toMatchSnapshot();
});

Expand All @@ -186,7 +206,7 @@ describe('getAlertPanelsByCategory', () => {
getAlert(ALERT_CPU_USAGE, 0),
getAlert(ALERT_THREAD_POOL_WRITE_REJECTIONS, 0),
];
const result = getAlertPanelsByCategory(panelTitle, true, alerts, alertsContext);
const result = getAlertPanelsByCategory(panelTitle, true, alerts, alertsContext, stateFilter);
expect(result).toMatchSnapshot();
});
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { AlertPanel } from '../panel';
import { ALERT_PANEL_MENU } from '../../../common/constants';
import { getDateFromNow, getCalendar } from '../../../common/formatting';
import { IAlertsContext } from '../context';
import { CommonAlertStatus } from '../../../common/types/alerts';
import { AlertState, CommonAlertStatus } from '../../../common/types/alerts';
import { PanelItem } from '../types';
import { sortByNewestAlert } from './sort_by_newest_alert';
import { Legacy } from '../../legacy_shims';
Expand All @@ -18,7 +18,8 @@ export function getAlertPanelsByCategory(
panelTitle: string,
inSetupMode: boolean,
alerts: CommonAlertStatus[],
alertsContext: IAlertsContext
alertsContext: IAlertsContext,
stateFilter: (state: AlertState) => boolean
) {
const menu = [];
for (const category of ALERT_PANEL_MENU) {
Expand Down Expand Up @@ -53,7 +54,8 @@ export function getAlertPanelsByCategory(
({ rawAlert: { alertTypeId } }) => alertName === alertTypeId
);
if (foundAlert && foundAlert.states.length > 0) {
if (foundAlert.states.length > 0) {
const states = foundAlert.states.filter(({ state }) => stateFilter(state));
if (states.length > 0) {
firingAlertsInCategory.push({
alert: foundAlert.rawAlert,
states: foundAlert.states,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import {
ALERT_MEMORY_USAGE,
} from '../../../common/constants';
import { AlertExecutionStatusValues } from '../../../../alerts/common';
import { AlertState } from '../../../common/types/alerts';

jest.mock('../../legacy_shims', () => ({
Legacy: {
Expand Down Expand Up @@ -92,20 +93,21 @@ describe('getAlertPanelsByNode', () => {
}

const panelTitle = 'Alerts';
const stateFilter = (state: AlertState) => true;

it('should properly group for alerts in each category', () => {
const alerts = [
getAlert(ALERT_NODES_CHANGED, 2),
getAlert(ALERT_DISK_USAGE, 1),
getAlert(ALERT_LICENSE_EXPIRATION, 2),
];
const result = getAlertPanelsByNode(panelTitle, alerts);
const result = getAlertPanelsByNode(panelTitle, alerts, stateFilter);
expect(result).toMatchSnapshot();
});

it('should properly group for alerts in a single category', () => {
const alerts = [getAlert(ALERT_MEMORY_USAGE, 2)];
const result = getAlertPanelsByNode(panelTitle, alerts);
const result = getAlertPanelsByNode(panelTitle, alerts, stateFilter);
expect(result).toMatchSnapshot();
});

Expand All @@ -115,7 +117,7 @@ describe('getAlertPanelsByNode', () => {
getAlert(ALERT_CPU_USAGE, 0),
getAlert(ALERT_THREAD_POOL_WRITE_REJECTIONS, 0),
];
const result = getAlertPanelsByNode(panelTitle, alerts);
const result = getAlertPanelsByNode(panelTitle, alerts, stateFilter);
expect(result).toMatchSnapshot();
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,22 @@
import React, { Fragment } from 'react';
import { EuiText, EuiToolTip } from '@elastic/eui';
import { AlertPanel } from '../panel';
import { CommonAlertStatus, CommonAlertState, CommonAlert } from '../../../common/types/alerts';
import {
CommonAlertStatus,
CommonAlertState,
CommonAlert,
AlertState,
} from '../../../common/types/alerts';
import { getDateFromNow, getCalendar } from '../../../common/formatting';
import { PanelItem } from '../types';
import { sortByNewestAlert } from './sort_by_newest_alert';
import { Legacy } from '../../legacy_shims';

export function getAlertPanelsByNode(panelTitle: string, alerts: CommonAlertStatus[]) {
export function getAlertPanelsByNode(
panelTitle: string,
alerts: CommonAlertStatus[],
stateFilter: (state: AlertState) => boolean
) {
const alertsByNodes: {
[uuid: string]: {
[alertName: string]: {
Expand All @@ -28,7 +37,7 @@ export function getAlertPanelsByNode(panelTitle: string, alerts: CommonAlertStat

for (const { states, rawAlert } of alerts) {
const { alertTypeId } = rawAlert;
for (const alertState of states) {
for (const alertState of states.filter(({ state: _state }) => stateFilter(_state))) {
const { state } = alertState;
statesByNodes[state.nodeId] = statesByNodes[state.nodeId] || [];
statesByNodes[state.nodeId].push(alertState);
Expand Down Expand Up @@ -57,7 +66,9 @@ export function getAlertPanelsByNode(panelTitle: string, alerts: CommonAlertStat
title: panelTitle,
items: [
...Object.keys(statesByNodes).map((nodeUuid, index) => {
const states = statesByNodes[nodeUuid] as CommonAlertState[];
const states = (statesByNodes[nodeUuid] as CommonAlertState[]).filter(({ state }) =>
stateFilter(state)
);
return {
name: (
<EuiText>
Expand Down
13 changes: 9 additions & 4 deletions x-pack/plugins/monitoring/public/alerts/status.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,10 @@ interface Props {
alerts: { [alertTypeId: string]: CommonAlertStatus };
showBadge: boolean;
showOnlyCount: boolean;
stateFilter: (state: AlertState) => boolean;
}
export const AlertsStatus: React.FC<Props> = (props: Props) => {
const { alerts, showBadge = false, showOnlyCount = false } = props;
const { alerts, showBadge = false, showOnlyCount = false, stateFilter = () => true } = props;
const inSetupMode = isInSetupMode(React.useContext(SetupModeContext));

if (!alerts) {
Expand All @@ -29,11 +30,15 @@ export const AlertsStatus: React.FC<Props> = (props: Props) => {
let atLeastOneDanger = false;
const count = Object.values(alerts).reduce((cnt, alertStatus) => {
const firingStates = alertStatus.states.filter((state) => state.firing);
cnt += firingStates.length;
const firingAndFilterStates = firingStates.filter((state) => stateFilter(state.state));
cnt += firingAndFilterStates.length;
if (firingStates.length) {
if (!atLeastOneDanger) {
for (const state of alertStatus.states) {
if ((state.state as AlertState).ui.severity === AlertSeverity.Danger) {
if (
stateFilter(state.state) &&
(state.state as AlertState).ui.severity === AlertSeverity.Danger
) {
atLeastOneDanger = true;
break;
}
Expand Down Expand Up @@ -66,7 +71,7 @@ export const AlertsStatus: React.FC<Props> = (props: Props) => {
}

if (showBadge || inSetupMode) {
return <AlertsBadge alerts={Object.values(alerts)} />;
return <AlertsBadge alerts={Object.values(alerts)} stateFilter={stateFilter} />;
}

const severity = atLeastOneDanger ? AlertSeverity.Danger : AlertSeverity.Warning;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -131,8 +131,14 @@ const getColumns = (showCgroupMetricsElasticsearch, setupMode, clusterUuid, aler
}),
field: 'alerts',
sortable: true,
render: () => {
return <AlertsStatus showBadge={true} alerts={alerts} />;
render: (_field, node) => {
return (
<AlertsStatus
showBadge={true}
alerts={alerts}
stateFilter={(state) => state.nodeId === node.resolver}
/>
);
},
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ import {
ALERT_MISSING_MONITORING_DATA,
ALERT_DISK_USAGE,
ALERT_MEMORY_USAGE,
ALERT_ELASTICSEARCH_VERSION_MISMATCH,
} from '../../../../common/constants';
import { SetupModeContext } from '../../../components/setup_mode/setup_mode_context';

Expand Down Expand Up @@ -100,7 +99,6 @@ uiRoutes.when('/elasticsearch/nodes', {
ALERT_THREAD_POOL_WRITE_REJECTIONS,
ALERT_MEMORY_USAGE,
ALERT_MISSING_MONITORING_DATA,
ALERT_ELASTICSEARCH_VERSION_MISMATCH,
],
},
},
Expand Down

0 comments on commit e4f7d04

Please sign in to comment.