diff --git a/x-pack/plugins/apm/public/components/app/service_node_overview/index.tsx b/x-pack/plugins/apm/public/components/app/service_node_overview/index.tsx index f2f1e983471b9..1158a671bfe0a 100644 --- a/x-pack/plugins/apm/public/components/app/service_node_overview/index.tsx +++ b/x-pack/plugins/apm/public/components/app/service_node_overview/index.tsx @@ -4,7 +4,7 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ -import { EuiToolTip } from '@elastic/eui'; +import { EuiToolTip, EuiIcon } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import React from 'react'; import { euiStyled } from '../../../../../../../src/plugins/kibana_react/common'; @@ -78,6 +78,12 @@ function ServiceNodeOverview() { {i18n.translate('xpack.apm.jvmsTable.nameColumnLabel', { defaultMessage: 'Name', })} + ), @@ -110,11 +116,20 @@ function ServiceNodeOverview() { ); }, }, + { + name: i18n.translate('xpack.apm.jvmsTable.hostName', { + defaultMessage: 'Host name', + }), + field: 'hostName', + sortable: true, + render: (_, { hostName }) => hostName ?? '', + }, { name: i18n.translate('xpack.apm.jvmsTable.cpuColumnLabel', { defaultMessage: 'CPU avg', }), field: 'cpu', + dataType: 'number', sortable: true, render: (_, { cpu }) => asPercent(cpu, 1), }, @@ -123,6 +138,7 @@ function ServiceNodeOverview() { defaultMessage: 'Heap memory avg', }), field: 'heapMemory', + dataType: 'number', sortable: true, render: asDynamicBytes, }, @@ -131,6 +147,7 @@ function ServiceNodeOverview() { defaultMessage: 'Non-heap memory avg', }), field: 'nonHeapMemory', + dataType: 'number', sortable: true, render: asDynamicBytes, }, @@ -139,6 +156,7 @@ function ServiceNodeOverview() { defaultMessage: 'Thread count max', }), field: 'threadCount', + dataType: 'number', sortable: true, render: asInteger, }, diff --git a/x-pack/plugins/apm/server/lib/service_nodes/__snapshots__/queries.test.ts.snap b/x-pack/plugins/apm/server/lib/service_nodes/__snapshots__/queries.test.ts.snap index 8e47b7298cc33..3550b9a602eda 100644 --- a/x-pack/plugins/apm/server/lib/service_nodes/__snapshots__/queries.test.ts.snap +++ b/x-pack/plugins/apm/server/lib/service_nodes/__snapshots__/queries.test.ts.snap @@ -141,6 +141,18 @@ Object { "field": "jvm.memory.heap.used", }, }, + "latest": Object { + "top_metrics": Object { + "metrics": Array [ + Object { + "field": "host.hostname", + }, + ], + "sort": Object { + "@timestamp": "desc", + }, + }, + }, "nonHeapMemory": Object { "avg": Object { "field": "jvm.memory.non_heap.used", diff --git a/x-pack/plugins/apm/server/lib/service_nodes/index.ts b/x-pack/plugins/apm/server/lib/service_nodes/index.ts index 4eb6abddd81a6..77bd646f4da60 100644 --- a/x-pack/plugins/apm/server/lib/service_nodes/index.ts +++ b/x-pack/plugins/apm/server/lib/service_nodes/index.ts @@ -10,8 +10,10 @@ import { METRIC_JAVA_NON_HEAP_MEMORY_USED, METRIC_JAVA_THREAD_COUNT, METRIC_PROCESS_CPU_PERCENT, + HOST_NAME, } from '../../../common/elasticsearch_fieldnames'; import { SERVICE_NODE_NAME_MISSING } from '../../../common/service_nodes'; +import { asMutableArray } from '../../../common/utils/as_mutable_array'; import { getServiceNodesProjection } from '../../projections/service_nodes'; import { mergeProjection } from '../../projections/util/merge_projection'; import { Setup, SetupTimeRange } from '../helpers/setup_request'; @@ -46,6 +48,14 @@ const getServiceNodes = async ({ missing: SERVICE_NODE_NAME_MISSING, }, aggs: { + latest: { + top_metrics: { + metrics: asMutableArray([{ field: HOST_NAME }] as const), + sort: { + '@timestamp': 'desc', + }, + }, + }, cpu: { avg: { field: METRIC_PROCESS_CPU_PERCENT, @@ -83,6 +93,10 @@ const getServiceNodes = async ({ name: bucket.key as string, cpu: bucket.cpu.value, heapMemory: bucket.heapMemory.value, + hostName: bucket.latest.top?.[0]?.metrics?.['host.hostname'] as + | string + | null + | undefined, nonHeapMemory: bucket.nonHeapMemory.value, threadCount: bucket.threadCount.value, }))