Skip to content

Commit

Permalink
[Stack Monitoring] Adding alerts to react app (#114029)
Browse files Browse the repository at this point in the history
* [Stack Monitoring] Adding alerts to react app

* Fixing global state context path

* adding alerts to pages; adding alerts model to cluster_overview; removing loadAlerts from page template

* Fixing request for enable alerts

* remove loadAlerts from page template

* Adding request error handlers

* removing redundent error handling

* Changing useRequestErrorHandler function to be async due to error.response.json call

* removing old comment

* Fixing contexts paths

* Converting ajaxRequestErrorHandler to useRequestErrorHandler

* Refactoring error handler for page template and setup mode

* Removing unnecessary async/await

* Removing unnecessary async/await in useClusters

* adding alertTypeIds to each page

* fixing instance count

* Adding alertTypeIds to index page

* Adding alert filters for specific pages

* Adding alerts to Logstash nodes

Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
  • Loading branch information
simianhacker and kibanamachine authored Oct 11, 2021
1 parent b03237a commit c8a0108
Show file tree
Hide file tree
Showing 47 changed files with 990 additions and 517 deletions.
1 change: 1 addition & 0 deletions x-pack/plugins/monitoring/common/types/alerts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ export interface CommonAlertState {
export interface CommonAlertFilter {
nodeUuid?: string;
shardId?: string;
shardIndex?: string;
}

export interface CommonAlertParamDetail {
Expand Down
5 changes: 2 additions & 3 deletions x-pack/plugins/monitoring/public/alerts/alerts_dropdown.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,12 @@ import {
import { i18n } from '@kbn/i18n';
import React, { useState } from 'react';
import { FormattedMessage } from '@kbn/i18n/react';
import { Legacy } from '../legacy_shims';
import { useKibana } from '../../../../../src/plugins/kibana_react/public';
import { MonitoringStartPluginDependencies } from '../types';
import { useAlertsModal } from '../application/hooks/use_alerts_modal';

export const AlertsDropdown: React.FC<{}> = () => {
const $injector = Legacy.shims.getAngularInjector();
const alertsEnableModalProvider: any = $injector.get('enableAlertsModal');
const alertsEnableModalProvider = useAlertsModal();
const { navigateToApp } =
useKibana<MonitoringStartPluginDependencies['core']>().services.application;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@
* 2.0.
*/
import React, { createContext } from 'react';
import { GlobalState } from '../url_state';
import { MonitoringStartPluginDependencies } from '../types';
import { TimeRange, RefreshInterval } from '../../../../../src/plugins/data/public';
import { Legacy } from '../legacy_shims';
import { GlobalState } from '../../url_state';
import { MonitoringStartPluginDependencies } from '../../types';
import { TimeRange, RefreshInterval } from '../../../../../../src/plugins/data/public';
import { Legacy } from '../../legacy_shims';

interface GlobalStateProviderProps {
query: MonitoringStartPluginDependencies['data']['query'];
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/

import React from 'react';
import { AppMountParameters } from 'kibana/public';

interface ContextProps {
setHeaderActionMenu?: AppMountParameters['setHeaderActionMenu'];
}

export const HeaderActionMenuContext = React.createContext<ContextProps>({});
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,11 @@
*/
import { useKibana } from '../../../../../../src/plugins/kibana_react/public';
import { showAlertsToast } from '../../alerts/lib/alerts_toast';
import { ajaxErrorHandlersProvider } from '../../lib/ajax_error_handler';
import { useRequestErrorHandler } from './use_request_error_handler';

export const useAlertsModal = () => {
const { services } = useKibana();
const handleRequestError = useRequestErrorHandler();

function shouldShowAlertsModal(alerts: {}) {
const modalHasBeenShown =
Expand All @@ -28,12 +29,11 @@ export const useAlertsModal = () => {

async function enableAlerts() {
try {
const { data } = await services.http?.post('../api/monitoring/v1/alerts/enable', {});
const response = await services.http?.post('../api/monitoring/v1/alerts/enable', {});
window.localStorage.setItem('ALERTS_MODAL_DECISION_MADE', 'true');
showAlertsToast(data);
showAlertsToast(response);
} catch (err) {
const ajaxErrorHandlers = ajaxErrorHandlersProvider();
return ajaxErrorHandlers(err);
await handleRequestError(err);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import { useState, useEffect } from 'react';
import { useKibana } from '../../../../../../src/plugins/kibana_react/public';
import { fetchClusters } from '../../lib/fetch_clusters';
import { useRequestErrorHandler } from './use_request_error_handler';

export function useClusters(clusterUuid?: string | null, ccs?: any, codePaths?: string[]) {
const { services } = useKibana<{ data: any }>();
Expand All @@ -17,6 +18,7 @@ export function useClusters(clusterUuid?: string | null, ccs?: any, codePaths?:

const [clusters, setClusters] = useState([] as any);
const [loaded, setLoaded] = useState<boolean | null>(false);
const handleRequestError = useRequestErrorHandler();

useEffect(() => {
async function makeRequest() {
Expand All @@ -34,13 +36,13 @@ export function useClusters(clusterUuid?: string | null, ccs?: any, codePaths?:
setClusters(response);
}
} catch (e) {
// TODO: Handle errors
handleRequestError(e);
} finally {
setLoaded(true);
}
}
makeRequest();
}, [clusterUuid, ccs, services.http, codePaths, min, max]);
}, [handleRequestError, clusterUuid, ccs, services.http, codePaths, min, max]);

return { clusters, loaded };
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { useCallback, useState, useContext, useEffect } from 'react';
import createContainer from 'constate';
import { useKibana } from '../../../../../../src/plugins/kibana_react/public';
import { Legacy } from '../../legacy_shims';
import { GlobalStateContext } from '../../application/global_state_context';
import { GlobalStateContext } from '../contexts/global_state_context';

interface TimeOptions {
from: string;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
import React, { useCallback } from 'react';
import { includes } from 'lodash';
import { IHttpFetchError } from 'kibana/public';
import { FormattedMessage } from '@kbn/i18n/react';
import { EuiButton, EuiSpacer, EuiText } from '@elastic/eui';
import { formatMsg } from '../../../../../../src/plugins/kibana_legacy/public';
import { toMountPoint, useKibana } from '../../../../../../src/plugins/kibana_react/public';
import { MonitoringStartPluginDependencies } from '../../types';

export function formatMonitoringError(err: IHttpFetchError) {
if (err.response?.status && err.response?.status !== -1) {
return (
<EuiText>
<p>{err.body?.message}</p>
<EuiText size="xs">
<FormattedMessage
id="xpack.monitoring.ajaxErrorHandler.httpErrorMessage"
defaultMessage="HTTP {errStatus}"
values={{ errStatus: err.response?.status }}
/>
</EuiText>
</EuiText>
);
}

return formatMsg(err);
}

export const useRequestErrorHandler = () => {
const { services } = useKibana<MonitoringStartPluginDependencies>();
return useCallback(
(err: IHttpFetchError) => {
if (err.response?.status === 403) {
// redirect to error message view
history.replaceState(null, '', '#/access-denied');
} else if (err.response?.status === 404 && !includes(window.location.hash, 'no-data')) {
// pass through if this is a 404 and we're already on the no-data page
const formattedError = formatMonitoringError(err);
services.notifications?.toasts.addDanger({
title: toMountPoint(
<FormattedMessage
id="xpack.monitoring.ajaxErrorHandler.requestFailedNotificationTitle"
defaultMessage="Monitoring Request Failed"
/>
),
text: toMountPoint(
<div>
{formattedError}
<EuiSpacer />
<EuiButton size="s" color="danger" onClick={() => window.location.reload()}>
<FormattedMessage
id="xpack.monitoring.ajaxErrorHandler.requestFailedNotification.retryButtonLabel"
defaultMessage="Retry"
/>
</EuiButton>
</div>
),
});
} else {
services.notifications?.toasts.addDanger({
title: toMountPoint(
<FormattedMessage
id="xpack.monitoring.ajaxErrorHandler.requestErrorNotificationTitle"
defaultMessage="Monitoring Request Error"
/>
),
text: toMountPoint(formatMonitoringError(err)),
});
}
},
[services.notifications]
);
};
Loading

0 comments on commit c8a0108

Please sign in to comment.