mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 17:59:23 -04:00
[Monitoring] "Internal Monitoring" deprecation warning (#72020)
* Internal Monitoring deprecation * Fixed type * Added if cloud logic * Fixed i18n test * Addressed code review feedback * Fixed types * Changed query * Added delay to fix a test * Fixed tests * Fixed text Co-authored-by: Elastic Machine <elasticmachine@users.noreply.github.com>
This commit is contained in:
parent
02e3fca772
commit
9aa5e1772d
6 changed files with 245 additions and 6 deletions
|
@ -0,0 +1,123 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License;
|
||||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { FormattedMessage } from '@kbn/i18n/react';
|
||||
import { EuiSpacer, EuiLink } from '@elastic/eui';
|
||||
import { Legacy } from '../legacy_shims';
|
||||
import { toMountPoint } from '../../../../../src/plugins/kibana_react/public';
|
||||
import { isInSetupMode, toggleSetupMode } from './setup_mode';
|
||||
|
||||
export interface MonitoringIndicesTypes {
|
||||
legacyIndices: number;
|
||||
metricbeatIndices: number;
|
||||
}
|
||||
|
||||
const enterSetupModeLabel = () =>
|
||||
i18n.translate('xpack.monitoring.internalMonitoringToast.enterSetupMode', {
|
||||
defaultMessage: 'Enter setup mode',
|
||||
});
|
||||
|
||||
const learnMoreLabel = () =>
|
||||
i18n.translate('xpack.monitoring.internalMonitoringToast.learnMoreAction', {
|
||||
defaultMessage: 'Learn more',
|
||||
});
|
||||
|
||||
const showIfLegacyOnlyIndices = () => {
|
||||
const { ELASTIC_WEBSITE_URL } = Legacy.shims.docLinks;
|
||||
const toast = Legacy.shims.toastNotifications.addWarning({
|
||||
title: toMountPoint(
|
||||
<FormattedMessage
|
||||
id="xpack.monitoring.internalMonitoringToast.title"
|
||||
defaultMessage="Internal Monitoring Detected"
|
||||
/>
|
||||
),
|
||||
text: toMountPoint(
|
||||
<div>
|
||||
<p>
|
||||
{i18n.translate('xpack.monitoring.internalMonitoringToast.description', {
|
||||
defaultMessage: `It appears you are using "Legacy Collection" for Stack Monitoring.
|
||||
This method of monitoring will no longer be supported in the next major release (8.0.0).
|
||||
Please follow the steps in setup mode to start monitoring with Metricbeat.`,
|
||||
})}
|
||||
</p>
|
||||
<EuiLink
|
||||
onClick={() => {
|
||||
Legacy.shims.toastNotifications.remove(toast);
|
||||
toggleSetupMode(true);
|
||||
}}
|
||||
>
|
||||
{enterSetupModeLabel()}
|
||||
</EuiLink>
|
||||
|
||||
<EuiSpacer />
|
||||
<EuiLink
|
||||
href={`${ELASTIC_WEBSITE_URL}blog/external-collection-for-elastic-stack-monitoring-is-now-available-via-metricbeat`}
|
||||
external
|
||||
target="_blank"
|
||||
>
|
||||
{learnMoreLabel()}
|
||||
</EuiLink>
|
||||
</div>
|
||||
),
|
||||
});
|
||||
};
|
||||
|
||||
const showIfLegacyAndMetricbeatIndices = () => {
|
||||
const { ELASTIC_WEBSITE_URL } = Legacy.shims.docLinks;
|
||||
const toast = Legacy.shims.toastNotifications.addWarning({
|
||||
title: toMountPoint(
|
||||
<FormattedMessage
|
||||
id="xpack.monitoring.internalAndMetricbeatMonitoringToast.title"
|
||||
defaultMessage="Partial Legacy Monitoring Detected"
|
||||
/>
|
||||
),
|
||||
text: toMountPoint(
|
||||
<div>
|
||||
<p>
|
||||
{i18n.translate('xpack.monitoring.internalAndMetricbeatMonitoringToast.description', {
|
||||
defaultMessage: `It appears you are using both Metricbeat and "Legacy Collection" for Stack Monitoring.
|
||||
In 8.0.0, you must use Metricbeat to collect monitoring data.
|
||||
Please follow the steps in setup mode to migrate the rest of the monitoring to Metricbeat.`,
|
||||
})}
|
||||
</p>
|
||||
<EuiLink
|
||||
onClick={() => {
|
||||
Legacy.shims.toastNotifications.remove(toast);
|
||||
toggleSetupMode(true);
|
||||
}}
|
||||
>
|
||||
{enterSetupModeLabel()}
|
||||
</EuiLink>
|
||||
|
||||
<EuiSpacer />
|
||||
<EuiLink
|
||||
href={`${ELASTIC_WEBSITE_URL}blog/external-collection-for-elastic-stack-monitoring-is-now-available-via-metricbeat`}
|
||||
external
|
||||
target="_blank"
|
||||
>
|
||||
{learnMoreLabel()}
|
||||
</EuiLink>
|
||||
</div>
|
||||
),
|
||||
});
|
||||
};
|
||||
|
||||
export const showInternalMonitoringToast = ({
|
||||
legacyIndices,
|
||||
metricbeatIndices,
|
||||
}: MonitoringIndicesTypes) => {
|
||||
if (isInSetupMode()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (legacyIndices && !metricbeatIndices) {
|
||||
showIfLegacyOnlyIndices();
|
||||
} else if (legacyIndices && metricbeatIndices) {
|
||||
showIfLegacyAndMetricbeatIndices();
|
||||
}
|
||||
};
|
|
@ -7,6 +7,7 @@
|
|||
import { ajaxErrorHandlersProvider } from '../lib/ajax_error_handler';
|
||||
import { Legacy } from '../legacy_shims';
|
||||
import { STANDALONE_CLUSTER_CLUSTER_UUID } from '../../common/constants';
|
||||
import { showInternalMonitoringToast } from '../lib/internal_monitoring_toasts';
|
||||
import { showSecurityToast } from '../alerts/lib/security_toasts';
|
||||
|
||||
function formatClusters(clusters) {
|
||||
|
@ -21,6 +22,7 @@ function formatCluster(cluster) {
|
|||
}
|
||||
|
||||
let once = false;
|
||||
let inTransit = false;
|
||||
|
||||
export function monitoringClustersProvider($injector) {
|
||||
return (clusterUuid, ccs, codePaths) => {
|
||||
|
@ -63,19 +65,39 @@ export function monitoringClustersProvider($injector) {
|
|||
});
|
||||
}
|
||||
|
||||
if (!once) {
|
||||
function ensureMetricbeatEnabled() {
|
||||
if (Legacy.shims.isCloud) {
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
return $http
|
||||
.get('../api/monitoring/v1/elasticsearch_settings/check/internal_monitoring')
|
||||
.then(({ data }) => {
|
||||
showInternalMonitoringToast({
|
||||
legacyIndices: data.legacy_indices,
|
||||
metricbeatIndices: data.mb_indices,
|
||||
});
|
||||
})
|
||||
.catch((err) => {
|
||||
const Private = $injector.get('Private');
|
||||
const ajaxErrorHandlers = Private(ajaxErrorHandlersProvider);
|
||||
return ajaxErrorHandlers(err);
|
||||
});
|
||||
}
|
||||
|
||||
if (!once && !inTransit) {
|
||||
inTransit = true;
|
||||
return getClusters().then((clusters) => {
|
||||
if (clusters.length) {
|
||||
return ensureAlertsEnabled()
|
||||
.then(({ data }) => {
|
||||
Promise.all([ensureAlertsEnabled(), ensureMetricbeatEnabled()])
|
||||
.then(([{ data }]) => {
|
||||
showSecurityToast(data);
|
||||
once = true;
|
||||
return clusters;
|
||||
})
|
||||
.catch(() => {
|
||||
// Intentionally swallow the error as this will retry the next page load
|
||||
return clusters;
|
||||
});
|
||||
})
|
||||
.finally(() => (inTransit = false));
|
||||
}
|
||||
return clusters;
|
||||
});
|
||||
|
|
|
@ -0,0 +1,85 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License;
|
||||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import { RequestHandlerContext } from 'kibana/server';
|
||||
// @ts-ignore
|
||||
import { getIndexPatterns } from '../../../../../lib/cluster/get_index_patterns';
|
||||
// @ts-ignore
|
||||
import { handleError } from '../../../../../lib/errors';
|
||||
import { RouteDependencies } from '../../../../../types';
|
||||
|
||||
const queryBody = {
|
||||
size: 0,
|
||||
aggs: {
|
||||
types: {
|
||||
terms: {
|
||||
field: '_index',
|
||||
size: 10,
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const checkLatestMonitoringIsLegacy = async (context: RequestHandlerContext, index: string) => {
|
||||
const { client: esClient } = context.core.elasticsearch.legacy;
|
||||
const result = await esClient.callAsCurrentUser('search', {
|
||||
index,
|
||||
body: queryBody,
|
||||
});
|
||||
|
||||
const { aggregations } = result;
|
||||
const counts = {
|
||||
legacyIndicesCount: 0,
|
||||
mbIndicesCount: 0,
|
||||
};
|
||||
|
||||
if (!aggregations) {
|
||||
return counts;
|
||||
}
|
||||
|
||||
const {
|
||||
types: { buckets },
|
||||
} = aggregations;
|
||||
counts.mbIndicesCount = buckets.filter(({ key }: { key: string }) => key.includes('-mb-')).length;
|
||||
|
||||
counts.legacyIndicesCount = buckets.length - counts.mbIndicesCount;
|
||||
return counts;
|
||||
};
|
||||
|
||||
export function internalMonitoringCheckRoute(server: unknown, npRoute: RouteDependencies) {
|
||||
npRoute.router.get(
|
||||
{
|
||||
path: '/api/monitoring/v1/elasticsearch_settings/check/internal_monitoring',
|
||||
validate: false,
|
||||
},
|
||||
async (context, _request, response) => {
|
||||
try {
|
||||
const typeCount = {
|
||||
legacy_indices: 0,
|
||||
mb_indices: 0,
|
||||
};
|
||||
|
||||
const { esIndexPattern, kbnIndexPattern, lsIndexPattern } = getIndexPatterns(server);
|
||||
const indexCounts = await Promise.all([
|
||||
checkLatestMonitoringIsLegacy(context, esIndexPattern),
|
||||
checkLatestMonitoringIsLegacy(context, kbnIndexPattern),
|
||||
checkLatestMonitoringIsLegacy(context, lsIndexPattern),
|
||||
]);
|
||||
|
||||
indexCounts.forEach((counts) => {
|
||||
typeCount.legacy_indices += counts.legacyIndicesCount;
|
||||
typeCount.mb_indices += counts.mbIndicesCount;
|
||||
});
|
||||
|
||||
return response.ok({
|
||||
body: typeCount,
|
||||
});
|
||||
} catch (err) {
|
||||
throw handleError(err);
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
|
@ -4,6 +4,7 @@
|
|||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
export { internalMonitoringCheckRoute } from './check/internal_monitoring';
|
||||
export { clusterSettingsCheckRoute } from './check/cluster';
|
||||
export { nodesSettingsCheckRoute } from './check/nodes';
|
||||
export { setCollectionEnabledRoute } from './set/collection_enabled';
|
||||
|
|
|
@ -20,6 +20,7 @@ export {
|
|||
ccrShardRoute,
|
||||
} from './elasticsearch';
|
||||
export {
|
||||
internalMonitoringCheckRoute,
|
||||
clusterSettingsCheckRoute,
|
||||
nodesSettingsCheckRoute,
|
||||
setCollectionEnabledRoute,
|
||||
|
|
|
@ -7,6 +7,8 @@
|
|||
import expect from '@kbn/expect';
|
||||
import { getLifecycleMethods } from './_get_lifecycle_methods';
|
||||
|
||||
const delay = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
|
||||
|
||||
export default function ({ getService, getPageObjects }) {
|
||||
const PageObjects = getPageObjects(['header', 'timePicker']);
|
||||
const testSubjects = getService('testSubjects');
|
||||
|
@ -35,6 +37,11 @@ export default function ({ getService, getPageObjects }) {
|
|||
});
|
||||
|
||||
it('should send another request when changing the time picker', async () => {
|
||||
/**
|
||||
* TODO: The value should either be removed or lowered after:
|
||||
* https://github.com/elastic/kibana/issues/72997 is resolved
|
||||
*/
|
||||
await delay(3000);
|
||||
await PageObjects.timePicker.setAbsoluteRange(
|
||||
'Aug 15, 2016 @ 21:00:00.000',
|
||||
'Aug 16, 2016 @ 00:00:00.000'
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue