diff --git a/x-pack/plugins/monitoring/public/components/apm/apm_metrics.tsx b/x-pack/plugins/monitoring/public/components/apm/apm_metrics.tsx index 2f09b20efd8a1..dcfd3adf72168 100644 --- a/x-pack/plugins/monitoring/public/components/apm/apm_metrics.tsx +++ b/x-pack/plugins/monitoring/public/components/apm/apm_metrics.tsx @@ -24,13 +24,19 @@ import { FormattedMessage } from '@kbn/i18n/react'; import { MonitoringTimeseriesContainer } from '../chart'; // @ts-ignore could not find declaration file import { Status } from './instance/status'; +import { checkAgentTypeMetric } from '../../lib/apm_agent'; +interface TitleType { + title?: string; + heading?: unknown; +} interface Props { - stats: unknown; + stats: { versions: string[]; [key: string]: unknown }; metrics: { [key: string]: unknown }; seriesToShow: unknown[]; title: string; summary: { + version: string; config: { container: boolean; }; @@ -47,10 +53,37 @@ const createCharts = (series: unknown[], props: Partial) => { }); }; +const getHeading = (isFleetTypeMetric: boolean) => { + const titles: TitleType = {}; + if (isFleetTypeMetric) { + titles.title = i18n.translate('xpack.monitoring.apm.metrics.topCharts.agentTitle', { + defaultMessage: 'APM & Fleet Server - Resource Usage', + }); + titles.heading = ( + + ); + } + titles.title = i18n.translate('xpack.monitoring.apm.metrics.topCharts.title', { + defaultMessage: 'APM Server - Resource Usage', + }); + titles.heading = ( + + ); + return titles; +}; + export const ApmMetrics = ({ stats, metrics, seriesToShow, title, summary, ...props }: Props) => { if (!metrics) { return null; } + + const versions = summary?.version ? [summary?.version] : stats.versions; + const isFleetTypeMetric = checkAgentTypeMetric(versions); + const titles = getHeading(isFleetTypeMetric); + const topSeries = [metrics.apm_cpu, metrics.apm_os_load]; const { config } = summary || stats; topSeries.push(config.container ? metrics.apm_memory_cgroup : metrics.apm_memory); @@ -59,12 +92,7 @@ export const ApmMetrics = ({ stats, metrics, seriesToShow, title, summary, ...pr -

- -

+

{titles.heading as FormattedMessage}

@@ -72,11 +100,7 @@ export const ApmMetrics = ({ stats, metrics, seriesToShow, title, summary, ...pr -

- {i18n.translate('xpack.monitoring.apm.metrics.topCharts.nonAgentTitle', { - defaultMessage: 'APM Server - Resource Usage', - })} -

+

{titles.title}

{createCharts(topSeries, props)} diff --git a/x-pack/plugins/monitoring/public/components/cluster/overview/apm_panel.js b/x-pack/plugins/monitoring/public/components/cluster/overview/apm_panel.js index a8b71bbfb234d..64afe8988e8bf 100644 --- a/x-pack/plugins/monitoring/public/components/cluster/overview/apm_panel.js +++ b/x-pack/plugins/monitoring/public/components/cluster/overview/apm_panel.js @@ -30,15 +30,78 @@ import { SetupModeTooltip } from '../../setup_mode/tooltip'; import { getSafeForExternalLink } from '../../../lib/get_safe_for_external_link'; import { isSetupModeFeatureEnabled } from '../../../lib/setup_mode'; import { SetupModeFeature } from '../../../../common/enums'; +import { checkAgentTypeMetric } from '../../../lib/apm_agent'; + +const getServerTitle = (isFleetTypeMetric, total) => { + const apmsTotal = {total}; + const linkLabel = {}; + if (isFleetTypeMetric) { + linkLabel.link = ( + + ); + linkLabel.aria = i18n.translate( + 'xpack.monitoring.cluster.overview.apmPanel.instancesAndFleetsTotalLinkAriaLabel', + { + defaultMessage: 'APM and Fleet server instances: {apmsTotal}', + values: { apmsTotal }, + } + ); + } + linkLabel.link = ( + + ); + linkLabel.aria = i18n.translate( + 'xpack.monitoring.cluster.overview.apmPanel.instancesTotalLinkAriaLabel', + { + defaultMessage: 'APM server instances: {apmsTotal}', + values: { apmsTotal }, + } + ); + + return linkLabel; +}; + +const getOverviewTitle = (isFleetTypeMetric) => { + if (isFleetTypeMetric) { + return i18n.translate('xpack.monitoring.cluster.overview.apmPanel.overviewFleetLinkLabel', { + defaultMessage: 'APM & Fleet server overview', + }); + } + return i18n.translate('xpack.monitoring.cluster.overview.apmPanel.overviewLinkLabel', { + defaultMessage: 'APM server overview', + }); +}; + +const getHeadingTitle = (isFleetTypeMetric) => { + if (isFleetTypeMetric) { + return i18n.translate('xpack.monitoring.cluster.overview.apmPanel.apmFleetTitle', { + defaultMessage: 'APM & Fleet server', + }); + } + return i18n.translate('xpack.monitoring.cluster.overview.apmPanel.apmTitle', { + defaultMessage: 'APM server', + }); +}; export function ApmPanel(props) { - const { setupMode } = props; + const { setupMode, versions } = props; const apmsTotal = get(props, 'apms.total') || 0; // Do not show if we are not in setup mode if (apmsTotal === 0 && !setupMode.enabled) { return null; } + const isFleetTypeMetric = checkAgentTypeMetric(versions); + const { link, aria } = getServerTitle(isFleetTypeMetric, apmsTotal); + const overviewTitle = getOverviewTitle(isFleetTypeMetric); const goToInstances = () => getSafeForExternalLink('#/apm/instances'); const setupModeData = get(setupMode.data, 'apm'); const setupModeMetricbeatMigrationTooltip = isSetupModeFeatureEnabled( @@ -52,13 +115,7 @@ export function ApmPanel(props) { ) : null; return ( - + @@ -68,18 +125,10 @@ export function ApmPanel(props) { setupModeEnabled={setupMode.enabled} setupModeData={setupModeData} href={getSafeForExternalLink('#/apm')} - aria-label={i18n.translate( - 'xpack.monitoring.cluster.overview.apmPanel.overviewLinkAriaLabel', - { - defaultMessage: 'APM server overview', - } - )} + aria-label={overviewTitle} data-test-subj="apmOverview" > - + {overviewTitle} @@ -121,22 +170,8 @@ export function ApmPanel(props) {

- - + + {link}

diff --git a/x-pack/plugins/monitoring/public/lib/apm_agent.ts b/x-pack/plugins/monitoring/public/lib/apm_agent.ts new file mode 100644 index 0000000000000..8884557782126 --- /dev/null +++ b/x-pack/plugins/monitoring/public/lib/apm_agent.ts @@ -0,0 +1,26 @@ +/* + * 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 { Legacy } from '../legacy_shims'; + +/** + * Possible temporary work arround to establish if APM might also be monitoring fleet: + * https://github.com/elastic/kibana/pull/95129/files#r604815886 + */ +export const checkAgentTypeMetric = (versions?: string[]) => { + if (!Legacy.shims.isCloud || !versions) { + return false; + } + versions.forEach((version) => { + const [major, minor] = version.split('.'); + const majorInt = Number(major); + if (majorInt > 7 || (majorInt === 7 && Number(minor) >= 13)) { + return true; + } + }); + return false; +}; diff --git a/x-pack/plugins/monitoring/server/lib/apm/_apm_stats.js b/x-pack/plugins/monitoring/server/lib/apm/_apm_stats.js index bdcd4d07f2c67..0dfcbfff834d8 100644 --- a/x-pack/plugins/monitoring/server/lib/apm/_apm_stats.js +++ b/x-pack/plugins/monitoring/server/lib/apm/_apm_stats.js @@ -24,6 +24,7 @@ export const apmAggFilterPath = [ 'aggregations.min_mem_rss_total.value', 'aggregations.max_mem_rss_total.value', 'aggregations.max_mem_total_total.value', + 'aggregations.versions.buckets', ]; export const apmUuidsAgg = (maxBucketSize) => ({ @@ -33,6 +34,11 @@ export const apmUuidsAgg = (maxBucketSize) => ({ precision_threshold: 10000, }, }, + versions: { + terms: { + field: 'beats_stats.beat.version', + }, + }, ephemeral_ids: { terms: { field: 'beats_stats.metrics.beat.info.ephemeral_id', @@ -101,11 +107,13 @@ export const apmAggResponseHandler = (response) => { const memRssMax = get(response, 'aggregations.max_mem_rss_total.value', 0); const memRssMin = get(response, 'aggregations.min_mem_rss_total.value', 0); const memTotal = get(response, 'aggregations.max_mem_total_total.value', 0); + const versions = get(response, 'aggregations.versions.buckets', []).map(({ key }) => key); return { apmTotal, totalEvents: getDiffCalculation(eventsTotalMax, eventsTotalMin), memRss: getDiffCalculation(memRssMax, memRssMin), memTotal, + versions, }; }; diff --git a/x-pack/plugins/monitoring/server/lib/apm/get_apms_for_clusters.js b/x-pack/plugins/monitoring/server/lib/apm/get_apms_for_clusters.js index ce40c52cdde25..3ece0af0369fd 100644 --- a/x-pack/plugins/monitoring/server/lib/apm/get_apms_for_clusters.js +++ b/x-pack/plugins/monitoring/server/lib/apm/get_apms_for_clusters.js @@ -13,7 +13,7 @@ import { apmAggResponseHandler, apmUuidsAgg, apmAggFilterPath } from './_apm_sta import { getTimeOfLastEvent } from './_get_time_of_last_event'; export function handleResponse(clusterUuid, response) { - const { apmTotal, totalEvents, memRss, memTotal } = apmAggResponseHandler(response); + const { apmTotal, totalEvents, memRss, memTotal, versions } = apmAggResponseHandler(response); // combine stats const stats = { @@ -23,6 +23,7 @@ export function handleResponse(clusterUuid, response) { apms: { total: apmTotal, }, + versions, }; return { diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json index b66fa50ae168a..42a9857462965 100644 --- a/x-pack/plugins/translations/translations/ja-JP.json +++ b/x-pack/plugins/translations/translations/ja-JP.json @@ -15247,7 +15247,6 @@ "xpack.monitoring.cluster.overview.apmPanel.lastEventDescription": "{timeOfLastEvent} 前", "xpack.monitoring.cluster.overview.apmPanel.lastEventLabel": "最後のイベント", "xpack.monitoring.cluster.overview.apmPanel.memoryUsageLabel": "メモリー使用状況", - "xpack.monitoring.cluster.overview.apmPanel.overviewLinkAriaLabel": "APM Server 概要", "xpack.monitoring.cluster.overview.apmPanel.overviewLinkLabel": "APM Server 概要", "xpack.monitoring.cluster.overview.apmPanel.processedEventsLabel": "処理済みのイベント", "xpack.monitoring.cluster.overview.apmPanel.serversTotalLinkLabel": "APM Server:{apmsTotal}", diff --git a/x-pack/plugins/translations/translations/zh-CN.json b/x-pack/plugins/translations/translations/zh-CN.json index 5fc97e9792083..08fef4ad34888 100644 --- a/x-pack/plugins/translations/translations/zh-CN.json +++ b/x-pack/plugins/translations/translations/zh-CN.json @@ -15472,7 +15472,6 @@ "xpack.monitoring.cluster.overview.apmPanel.lastEventDescription": "{timeOfLastEvent}前", "xpack.monitoring.cluster.overview.apmPanel.lastEventLabel": "最后事件", "xpack.monitoring.cluster.overview.apmPanel.memoryUsageLabel": "内存利用率", - "xpack.monitoring.cluster.overview.apmPanel.overviewLinkAriaLabel": "APM 服务器概览", "xpack.monitoring.cluster.overview.apmPanel.overviewLinkLabel": "APM 服务器概览", "xpack.monitoring.cluster.overview.apmPanel.processedEventsLabel": "已处理事件", "xpack.monitoring.cluster.overview.apmPanel.serversTotalLinkLabel": "APM 服务器:{apmsTotal}", diff --git a/x-pack/test/api_integration/apis/monitoring/apm/fixtures/cluster.json b/x-pack/test/api_integration/apis/monitoring/apm/fixtures/cluster.json index 197d8f8fe6c2c..1b89349785f26 100644 --- a/x-pack/test/api_integration/apis/monitoring/apm/fixtures/cluster.json +++ b/x-pack/test/api_integration/apis/monitoring/apm/fixtures/cluster.json @@ -9,7 +9,10 @@ "config": { "container": false }, - "timeOfLastEvent": "2018-08-31T13:59:21.199Z" + "timeOfLastEvent": "2018-08-31T13:59:21.199Z", + "versions": [ + "7.0.0-alpha1" + ] }, "metrics": { "apm_cpu": [ diff --git a/x-pack/test/api_integration/apis/monitoring/cluster/fixtures/multicluster.json b/x-pack/test/api_integration/apis/monitoring/cluster/fixtures/multicluster.json index 2bbd9029e6982..6abd3a8ecff9d 100644 --- a/x-pack/test/api_integration/apis/monitoring/cluster/fixtures/multicluster.json +++ b/x-pack/test/api_integration/apis/monitoring/cluster/fixtures/multicluster.json @@ -82,7 +82,8 @@ }, "config": { "container": false - } + }, + "versions": [ ] }, "alerts": { "alertsMeta": { @@ -178,7 +179,8 @@ }, "config": { "container": false - } + }, + "versions": [ ] }, "alerts": { "alertsMeta": { @@ -274,7 +276,8 @@ }, "config": { "container": false - } + }, + "versions": [ ] }, "alerts": { "alertsMeta": { diff --git a/x-pack/test/api_integration/apis/monitoring/cluster/fixtures/overview.json b/x-pack/test/api_integration/apis/monitoring/cluster/fixtures/overview.json index 7eaf2bbee289f..4f1024f2c94b0 100644 --- a/x-pack/test/api_integration/apis/monitoring/cluster/fixtures/overview.json +++ b/x-pack/test/api_integration/apis/monitoring/cluster/fixtures/overview.json @@ -96,7 +96,8 @@ }, "config": { "container": false - } + }, + "versions": [ ] }, "isCcrEnabled": true, "isPrimary": true, diff --git a/x-pack/test/api_integration/apis/monitoring/standalone_cluster/fixtures/cluster.json b/x-pack/test/api_integration/apis/monitoring/standalone_cluster/fixtures/cluster.json index e3ed40b197cc1..3e590656753f1 100644 --- a/x-pack/test/api_integration/apis/monitoring/standalone_cluster/fixtures/cluster.json +++ b/x-pack/test/api_integration/apis/monitoring/standalone_cluster/fixtures/cluster.json @@ -55,7 +55,8 @@ }, "config": { "container": false - } + }, + "versions": [] }, "isPrimary": false }] diff --git a/x-pack/test/api_integration/apis/monitoring/standalone_cluster/fixtures/clusters.json b/x-pack/test/api_integration/apis/monitoring/standalone_cluster/fixtures/clusters.json index 0034199325e5c..8f20dce44ee8a 100644 --- a/x-pack/test/api_integration/apis/monitoring/standalone_cluster/fixtures/clusters.json +++ b/x-pack/test/api_integration/apis/monitoring/standalone_cluster/fixtures/clusters.json @@ -82,7 +82,8 @@ }, "config": { "container": false - } + }, + "versions": [] }, "alerts": { "alertsMeta": { @@ -158,7 +159,8 @@ }, "config": { "container": false - } + }, + "versions": [] }, "alerts": { "alertsMeta": {