From 2e5954b6f162086c53770b1f4e1d5179661c96aa Mon Sep 17 00:00:00 2001 From: Phillip Burch Date: Fri, 27 Nov 2020 10:51:49 -0600 Subject: [PATCH 01/15] Add properties tab to flyout --- .../infra/common/http_api/metadata_api.ts | 19 +++ .../components/node_details/overlay.tsx | 2 +- .../node_details/tabs/properties.tsx | 21 ---- .../tabs/properties/build_fields.ts | 105 ++++++++++++++++ .../node_details/tabs/properties/index.tsx | 119 ++++++++++++++++++ .../node_details/tabs/properties/table.tsx | 88 +++++++++++++ .../routes/metadata/lib/get_node_info.ts | 2 +- 7 files changed, 333 insertions(+), 23 deletions(-) delete mode 100644 x-pack/plugins/infra/public/pages/metrics/inventory_view/components/node_details/tabs/properties.tsx create mode 100644 x-pack/plugins/infra/public/pages/metrics/inventory_view/components/node_details/tabs/properties/build_fields.ts create mode 100644 x-pack/plugins/infra/public/pages/metrics/inventory_view/components/node_details/tabs/properties/index.tsx create mode 100644 x-pack/plugins/infra/public/pages/metrics/inventory_view/components/node_details/tabs/properties/table.tsx diff --git a/x-pack/plugins/infra/common/http_api/metadata_api.ts b/x-pack/plugins/infra/common/http_api/metadata_api.ts index 5ee96b479be8e..957413b6db4cc 100644 --- a/x-pack/plugins/infra/common/http_api/metadata_api.ts +++ b/x-pack/plugins/infra/common/http_api/metadata_api.ts @@ -29,10 +29,14 @@ export const InfraMetadataOSRT = rt.partial({ name: rt.string, platform: rt.string, version: rt.string, + build: rt.string, }); export const InfraMetadataHostRT = rt.partial({ name: rt.string, + hostname: rt.string, + id: rt.string, + mac: rt.array(rt.string), os: InfraMetadataOSRT, architecture: rt.string, containerized: rt.boolean, @@ -43,25 +47,40 @@ export const InfraMetadataInstanceRT = rt.partial({ name: rt.string, }); +export const InfraMetadataAccountRT = rt.partial({ + id: rt.string, + name: rt.string, +}); + export const InfraMetadataProjectRT = rt.partial({ id: rt.string, }); export const InfraMetadataMachineRT = rt.partial({ interface: rt.string, + type: rt.string, }); export const InfraMetadataCloudRT = rt.partial({ instance: InfraMetadataInstanceRT, provider: rt.string, + account: InfraMetadataAccountRT, availability_zone: rt.string, project: InfraMetadataProjectRT, machine: InfraMetadataMachineRT, + region: rt.string, +}); + +export const InfraMetadataAgentRT = rt.partial({ + id: rt.string, + version: rt.string, + policy: rt.string, }); export const InfraMetadataInfoRT = rt.partial({ cloud: InfraMetadataCloudRT, host: InfraMetadataHostRT, + agent: InfraMetadataAgentRT, }); const InfraMetadataRequiredRT = rt.type({ diff --git a/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/node_details/overlay.tsx b/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/node_details/overlay.tsx index 0943ced5e5be0..f1760595ab8ca 100644 --- a/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/node_details/overlay.tsx +++ b/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/node_details/overlay.tsx @@ -14,7 +14,7 @@ import { InventoryItemType } from '../../../../../../common/inventory_models/typ import { MetricsTab } from './tabs/metrics/metrics'; import { LogsTab } from './tabs/logs'; import { ProcessesTab } from './tabs/processes'; -import { PropertiesTab } from './tabs/properties'; +import { PropertiesTab } from './tabs/properties/index'; import { OVERLAY_Y_START, OVERLAY_BOTTOM_MARGIN, OVERLAY_HEADER_SIZE } from './tabs/shared'; interface Props { diff --git a/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/node_details/tabs/properties.tsx b/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/node_details/tabs/properties.tsx deleted file mode 100644 index 8157aca9b1410..0000000000000 --- a/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/node_details/tabs/properties.tsx +++ /dev/null @@ -1,21 +0,0 @@ -/* - * 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 { TabContent, TabProps } from './shared'; - -const TabComponent = (props: TabProps) => { - return Properties Placeholder; -}; - -export const PropertiesTab = { - id: 'properties', - name: i18n.translate('xpack.infra.nodeDetails.tabs.properties', { - defaultMessage: 'Properties', - }), - content: TabComponent, -}; diff --git a/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/node_details/tabs/properties/build_fields.ts b/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/node_details/tabs/properties/build_fields.ts new file mode 100644 index 0000000000000..2ee4265a4d778 --- /dev/null +++ b/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/node_details/tabs/properties/build_fields.ts @@ -0,0 +1,105 @@ +/* + * 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 { InfraMetadata } from '../../../../../../../../common/http_api'; + +export const getFields = (metadata: InfraMetadata, group: 'cloud' | 'host' | 'agent') => { + switch (group) { + case 'host': + return [ + { + name: 'host.architecture', + value: metadata.info?.host?.architecture, + }, + { + name: 'host.hostname', + value: metadata.info?.host?.name, + }, + { + name: 'host.id', + value: metadata.info?.host?.id, + }, + { + name: 'host.mac', + value: metadata.info?.host?.mac ? metadata.info?.host?.mac.join(',') : '', + }, + { + name: 'host.name', + value: metadata.info?.host?.name, + }, + { + name: 'host.os.build', + value: metadata.info?.host?.os?.build, + }, + { + name: 'host.os.family', + value: metadata.info?.host?.os?.family, + }, + { + name: 'host.os.name', + value: metadata.info?.host?.os?.name, + }, + { + name: 'host.os.kernel', + value: metadata.info?.host?.os?.kernel, + }, + { + name: 'host.os.platform', + value: metadata.info?.host?.os?.platform, + }, + ]; + case 'cloud': + return [ + { + name: 'cloud.account.id', + value: metadata.info?.cloud?.account?.id, + }, + { + name: 'cloud.account.name', + value: metadata.info?.cloud?.account?.name, + }, + { + name: 'cloud.availability_zone', + value: metadata.info?.cloud?.availability_zone, + }, + { + name: 'cloud.instance.id', + value: metadata.info?.cloud?.instance?.id, + }, + { + name: 'cloud.instance.name', + value: metadata.info?.cloud?.instance?.name, + }, + { + name: 'cloud.machine.type', + value: metadata.info?.cloud?.machine?.type, + }, + { + name: 'cloud.provider', + value: metadata.info?.cloud?.provider, + }, + { + name: 'cloud.region', + value: metadata.info?.cloud?.region, + }, + ]; + case 'agent': + return [ + { + name: 'agent.id', + value: metadata.info?.agent?.id, + }, + { + name: 'agent.version', + value: metadata.info?.agent?.version, + }, + { + name: 'agent.policy', + value: metadata.info?.agent?.policy, + }, + ]; + } +}; diff --git a/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/node_details/tabs/properties/index.tsx b/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/node_details/tabs/properties/index.tsx new file mode 100644 index 0000000000000..e6682df25ee1f --- /dev/null +++ b/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/node_details/tabs/properties/index.tsx @@ -0,0 +1,119 @@ +/* + * 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, { useCallback, useContext, useMemo } from 'react'; +import { i18n } from '@kbn/i18n'; +import { EuiLoadingSpinner } from '@elastic/eui'; +import { TabContent, TabProps } from '../shared'; +import { Source } from '../../../../../../../containers/source'; +import { findInventoryModel } from '../../../../../../../../common/inventory_models'; +import { InventoryItemType } from '../../../../../../../../common/inventory_models/types'; +import { useMetadata } from '../../../../../metric_detail/hooks/use_metadata'; +import { getFields } from './build_fields'; +import { useWaffleTimeContext } from '../../../../hooks/use_waffle_time'; +import { Table } from './table'; +import { euiStyled } from '../../../../../../../../../observability/public'; +import { useWaffleFiltersContext } from '../../../../hooks/use_waffle_filters'; + +const TabComponent = (props: TabProps) => { + const nodeId = props.node.id; + const nodeType = props.nodeType as InventoryItemType; + const inventoryModel = findInventoryModel(nodeType); + const { sourceId } = useContext(Source.Context); + const { currentTimeRange } = useWaffleTimeContext(); + const { applyFilterQuery } = useWaffleFiltersContext(); + const { loading: metadataLoading, metadata } = useMetadata( + nodeId, + nodeType, + inventoryModel.requiredMetrics, + sourceId, + currentTimeRange + ); + + const hostFields = useMemo(() => { + if (!metadata) return null; + return getFields(metadata, 'host'); + }, [metadata]); + + const cloudFields = useMemo(() => { + if (!metadata) return null; + return getFields(metadata, 'cloud'); + }, [metadata]); + + const agentFields = useMemo(() => { + if (!metadata) return null; + return getFields(metadata, 'agent'); + }, [metadata]); + + const onFilter = useCallback( + (item: { name: string; value: string }) => { + applyFilterQuery({ + kind: 'kuery', + expression: `${item.name}: "${item.value}"`, + }); + }, + [applyFilterQuery] + ); + + if (metadataLoading) { + return ; + } + + return ( + + {hostFields && ( + + + + )} + {cloudFields && ( + +
+ + )} + {agentFields && ( + +
+ + )} + + ); +}; + +const TableWrapper = euiStyled.div` + margin-bottom: 20px +`; + +const LoadingSpinner = euiStyled(EuiLoadingSpinner).attrs({ size: 'm' })` + margin-top: 2px; + margin-bottom: 3px; +`; + +export const PropertiesTab = { + id: 'properties', + name: i18n.translate('xpack.infra.nodeDetails.tabs.metadata', { + defaultMessage: 'Metadata', + }), + content: TabComponent, +}; diff --git a/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/node_details/tabs/properties/table.tsx b/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/node_details/tabs/properties/table.tsx new file mode 100644 index 0000000000000..b952d749dad52 --- /dev/null +++ b/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/node_details/tabs/properties/table.tsx @@ -0,0 +1,88 @@ +/* + * 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 { EuiText } from '@elastic/eui'; +import { EuiToolTip } from '@elastic/eui'; +import { EuiButtonIcon } from '@elastic/eui'; +import { EuiBasicTable } from '@elastic/eui'; +import { i18n } from '@kbn/i18n'; +import React, { useMemo } from 'react'; +import { euiStyled } from '../../../../../../../../../observability/public'; + +interface Row { + name: string; + value: string | undefined; +} + +interface Props { + rows: Row[]; + title: string; + onClick(item: Row): void; +} + +export const Table = (props: Props) => { + const { rows, title, onClick } = props; + const columns = useMemo( + () => [ + { + field: 'name', + name: '', + sortable: false, + render: (name: string, item: Row) => ( + + {item.name} + + ), + }, + { + field: 'value', + name: '', + sortable: false, + render: (_name: string, item: Row) => ( + + + onClick(item)} + /> + + {item.value} + + ), + }, + ], + [onClick] + ); + + return ( + <> + + +

{title}

+
+
+ + + ); +}; + +const TitleWrapper = euiStyled.div` + margin-bottom: 10px +`; + +class TableWithoutHeader extends EuiBasicTable { + renderTableHead() { + return <>; + } +} diff --git a/x-pack/plugins/infra/server/routes/metadata/lib/get_node_info.ts b/x-pack/plugins/infra/server/routes/metadata/lib/get_node_info.ts index f1341c7ec8101..b378b42e2ff59 100644 --- a/x-pack/plugins/infra/server/routes/metadata/lib/get_node_info.ts +++ b/x-pack/plugins/infra/server/routes/metadata/lib/get_node_info.ts @@ -58,7 +58,7 @@ export const getNodeInfo = async ( index: sourceConfiguration.metricAlias, body: { size: 1, - _source: ['host.*', 'cloud.*'], + _source: ['host.*', 'cloud.*', 'agent.*'], sort: [{ [timestampField]: 'desc' }], query: { bool: { From 05c7a3b5460b01a20e7f01f2a1dde8d67aa8d8de Mon Sep 17 00:00:00 2001 From: Phillip Burch Date: Fri, 27 Nov 2020 11:08:26 -0600 Subject: [PATCH 02/15] Better id for i18n title --- .../components/node_details/tabs/properties/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/node_details/tabs/properties/index.tsx b/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/node_details/tabs/properties/index.tsx index e6682df25ee1f..92c8b497c1bff 100644 --- a/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/node_details/tabs/properties/index.tsx +++ b/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/node_details/tabs/properties/index.tsx @@ -112,7 +112,7 @@ const LoadingSpinner = euiStyled(EuiLoadingSpinner).attrs({ size: 'm' })` export const PropertiesTab = { id: 'properties', - name: i18n.translate('xpack.infra.nodeDetails.tabs.metadata', { + name: i18n.translate('xpack.infra.nodeDetails.tabs.metadata.title', { defaultMessage: 'Metadata', }), content: TabComponent, From 2fbd2b253e119c8c4ddf4d503c7eb86b95b4bec1 Mon Sep 17 00:00:00 2001 From: Phillip Burch Date: Fri, 27 Nov 2020 11:11:40 -0600 Subject: [PATCH 03/15] Update i18n ids --- .../components/node_details/tabs/properties/table.tsx | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/node_details/tabs/properties/table.tsx b/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/node_details/tabs/properties/table.tsx index b952d749dad52..4b5b87645a701 100644 --- a/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/node_details/tabs/properties/table.tsx +++ b/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/node_details/tabs/properties/table.tsx @@ -44,16 +44,19 @@ export const Table = (props: Props) => { render: (_name: string, item: Row) => ( onClick(item)} /> From b09a77855aeb6c5bf4f11c35d56473dff89b89ff Mon Sep 17 00:00:00 2001 From: Phillip Burch Date: Mon, 30 Nov 2020 08:18:32 -0600 Subject: [PATCH 04/15] Fix test and styling --- .../components/node_details/tabs/properties/table.tsx | 2 +- x-pack/test/api_integration/apis/metrics_ui/metadata.ts | 7 +++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/node_details/tabs/properties/table.tsx b/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/node_details/tabs/properties/table.tsx index 4b5b87645a701..7a4cb6018bae2 100644 --- a/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/node_details/tabs/properties/table.tsx +++ b/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/node_details/tabs/properties/table.tsx @@ -75,7 +75,7 @@ export const Table = (props: Props) => {

{title}

- + ); }; diff --git a/x-pack/test/api_integration/apis/metrics_ui/metadata.ts b/x-pack/test/api_integration/apis/metrics_ui/metadata.ts index 349b0dcbd9cfe..bbd54d691eede 100644 --- a/x-pack/test/api_integration/apis/metrics_ui/metadata.ts +++ b/x-pack/test/api_integration/apis/metrics_ui/metadata.ts @@ -109,6 +109,13 @@ export default function ({ getService }: FtrProviderContext) { machine: { type: 'n1-standard-4' }, project: { id: 'elastic-observability' }, }, + agent: { + hostname: 'gke-observability-8--observability-8--bc1afd95-f0zc', + id: 'c91c0d2b-6483-46bb-9731-f06afd32bb59', + ephemeral_id: '7cb259b1-795c-4c76-beaf-2eb8f18f5b02', + type: 'metricbeat', + version: '8.0.0', + }, host: { hostname: 'gke-observability-8--observability-8--bc1afd95-f0zc', os: { From 3bf817202260e438d3bbd278e7865c4739bb9c3b Mon Sep 17 00:00:00 2001 From: Phillip Burch Date: Mon, 30 Nov 2020 09:32:02 -0600 Subject: [PATCH 05/15] Style changes, add support for collapsing array fields --- .../infra/common/http_api/metadata_api.ts | 1 + .../tabs/properties/build_fields.ts | 10 +- .../node_details/tabs/properties/table.tsx | 116 ++++++++++++++---- 3 files changed, 101 insertions(+), 26 deletions(-) diff --git a/x-pack/plugins/infra/common/http_api/metadata_api.ts b/x-pack/plugins/infra/common/http_api/metadata_api.ts index 957413b6db4cc..41b599c310419 100644 --- a/x-pack/plugins/infra/common/http_api/metadata_api.ts +++ b/x-pack/plugins/infra/common/http_api/metadata_api.ts @@ -36,6 +36,7 @@ export const InfraMetadataHostRT = rt.partial({ name: rt.string, hostname: rt.string, id: rt.string, + ip: rt.array(rt.string), mac: rt.array(rt.string), os: InfraMetadataOSRT, architecture: rt.string, diff --git a/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/node_details/tabs/properties/build_fields.ts b/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/node_details/tabs/properties/build_fields.ts index 2ee4265a4d778..98609a2cd8fa4 100644 --- a/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/node_details/tabs/properties/build_fields.ts +++ b/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/node_details/tabs/properties/build_fields.ts @@ -22,9 +22,13 @@ export const getFields = (metadata: InfraMetadata, group: 'cloud' | 'host' | 'ag name: 'host.id', value: metadata.info?.host?.id, }, + { + name: 'host.ip', + value: metadata.info?.host?.ip, + }, { name: 'host.mac', - value: metadata.info?.host?.mac ? metadata.info?.host?.mac.join(',') : '', + value: metadata.info?.host?.mac, }, { name: 'host.name', @@ -50,6 +54,10 @@ export const getFields = (metadata: InfraMetadata, group: 'cloud' | 'host' | 'ag name: 'host.os.platform', value: metadata.info?.host?.os?.platform, }, + { + name: 'host.os.version', + value: metadata.info?.host?.os?.version, + }, ]; case 'cloud': return [ diff --git a/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/node_details/tabs/properties/table.tsx b/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/node_details/tabs/properties/table.tsx index 7a4cb6018bae2..b632a0f1a8f9b 100644 --- a/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/node_details/tabs/properties/table.tsx +++ b/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/node_details/tabs/properties/table.tsx @@ -7,14 +7,18 @@ import { EuiText } from '@elastic/eui'; import { EuiToolTip } from '@elastic/eui'; import { EuiButtonIcon } from '@elastic/eui'; +import { EuiFlexGroup } from '@elastic/eui'; +import { EuiFlexItem } from '@elastic/eui'; +import { EuiLink } from '@elastic/eui'; import { EuiBasicTable } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; -import React, { useMemo } from 'react'; +import React, { useCallback, useMemo, useState } from 'react'; +import { FormattedMessage } from 'react-intl'; import { euiStyled } from '../../../../../../../../../observability/public'; interface Row { name: string; - value: string | undefined; + value: string | string[] | undefined; } interface Props { @@ -30,6 +34,7 @@ export const Table = (props: Props) => { { field: 'name', name: '', + width: '35%', sortable: false, render: (name: string, item: Row) => ( @@ -40,29 +45,39 @@ export const Table = (props: Props) => { { field: 'value', name: '', + width: '65%', sortable: false, - render: (_name: string, item: Row) => ( - - - onClick(item)} - /> - - {item.value} - - ), + render: (_name: string, item: Row) => { + return ( + + + + + onClick(item)} + /> + + + {!Array.isArray(item.value) && item.value} + {Array.isArray(item.value) && } + + + + + ); + }, }, ], [onClick] @@ -75,7 +90,7 @@ export const Table = (props: Props) => {

{title}

- + ); }; @@ -89,3 +104,54 @@ class TableWithoutHeader extends EuiBasicTable { return <>; } } + +interface MoreProps { + values: string[]; +} +const ArrayValue = (props: MoreProps) => { + const { values } = props; + const [isExpanded, setIsExpanded] = useState(false); + const expand = useCallback(() => { + setIsExpanded(true); + }, []); + + const collapse = useCallback(() => { + setIsExpanded(false); + }, []); + + return ( + <> + {!isExpanded && ( + + + {values[0]} + {' ... '} + + + + + + + + )} + {isExpanded && ( +
+ {values.map((v) => ( +
{v}
+ ))} + + {i18n.translate('xpack.infra.nodeDetails.tabs.metadata.seeLess', { + defaultMessage: 'See less', + })} + +
+ )} + + ); +}; From 2a6b58bb6669eea80fd94d0bda55c063c60000c1 Mon Sep 17 00:00:00 2001 From: Phillip Burch Date: Mon, 30 Nov 2020 09:53:36 -0600 Subject: [PATCH 06/15] Add loading indicators --- .../node_details/tabs/metrics/metrics.tsx | 20 +++++++++++++++- .../node_details/tabs/properties/index.tsx | 23 +++++++++++++++---- 2 files changed, 37 insertions(+), 6 deletions(-) diff --git a/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/node_details/tabs/metrics/metrics.tsx b/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/node_details/tabs/metrics/metrics.tsx index b5628b0a7c9b4..87d76855acba2 100644 --- a/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/node_details/tabs/metrics/metrics.tsx +++ b/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/node_details/tabs/metrics/metrics.tsx @@ -17,6 +17,7 @@ import { PointerEvent, } from '@elastic/charts'; import moment from 'moment'; +import { EuiLoadingChart } from '@elastic/eui'; import { TabContent, TabProps } from '../shared'; import { useSnapshot } from '../../../../hooks/use_snaphot'; import { useWaffleOptionsContext } from '../../../../hooks/use_waffle_options'; @@ -239,7 +240,7 @@ const TabComponent = (props: TabProps) => { !usedMemoryMetricsTs || !freeMemoryMetricsTs ) { - return
; + return ; } const cpuChartMetrics = buildChartMetricLabels([SYSTEM_METRIC_NAME, USER_METRIC_NAME], 'avg'); @@ -467,6 +468,23 @@ const ChartContainer: React.FC = ({ children }) => (
); +const LoadingPlaceholder = () => { + return ( +
+ +
+ ); +}; + export const MetricsTab = { id: 'metrics', name: i18n.translate('xpack.infra.nodeDetails.tabs.metrics', { diff --git a/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/node_details/tabs/properties/index.tsx b/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/node_details/tabs/properties/index.tsx index 92c8b497c1bff..fa30b3411d15a 100644 --- a/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/node_details/tabs/properties/index.tsx +++ b/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/node_details/tabs/properties/index.tsx @@ -7,6 +7,7 @@ import React, { useCallback, useContext, useMemo } from 'react'; import { i18n } from '@kbn/i18n'; import { EuiLoadingSpinner } from '@elastic/eui'; +import { EuiLoadingChart } from '@elastic/eui'; import { TabContent, TabProps } from '../shared'; import { Source } from '../../../../../../../containers/source'; import { findInventoryModel } from '../../../../../../../../common/inventory_models'; @@ -59,7 +60,7 @@ const TabComponent = (props: TabProps) => { ); if (metadataLoading) { - return ; + return ; } return ( @@ -105,10 +106,22 @@ const TableWrapper = euiStyled.div` margin-bottom: 20px `; -const LoadingSpinner = euiStyled(EuiLoadingSpinner).attrs({ size: 'm' })` - margin-top: 2px; - margin-bottom: 3px; -`; +const LoadingPlaceholder = () => { + return ( +
+ +
+ ); +}; export const PropertiesTab = { id: 'properties', From d55787e8d5eb73e9be1af1910edaacbd889f99d7 Mon Sep 17 00:00:00 2001 From: Phillip Burch Date: Mon, 30 Nov 2020 10:14:53 -0600 Subject: [PATCH 07/15] Fix type check --- .../components/node_details/tabs/properties/index.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/node_details/tabs/properties/index.tsx b/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/node_details/tabs/properties/index.tsx index fa30b3411d15a..9fadc6eb6f214 100644 --- a/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/node_details/tabs/properties/index.tsx +++ b/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/node_details/tabs/properties/index.tsx @@ -6,7 +6,6 @@ import React, { useCallback, useContext, useMemo } from 'react'; import { i18n } from '@kbn/i18n'; -import { EuiLoadingSpinner } from '@elastic/eui'; import { EuiLoadingChart } from '@elastic/eui'; import { TabContent, TabProps } from '../shared'; import { Source } from '../../../../../../../containers/source'; From c6e1d99699298009c0fb3f8dd0888e2181639399 Mon Sep 17 00:00:00 2001 From: Phillip Burch Date: Mon, 30 Nov 2020 18:30:22 -0600 Subject: [PATCH 08/15] Fix another test --- x-pack/test/api_integration/apis/metrics_ui/metadata.ts | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/x-pack/test/api_integration/apis/metrics_ui/metadata.ts b/x-pack/test/api_integration/apis/metrics_ui/metadata.ts index bbd54d691eede..423fa345ac2b6 100644 --- a/x-pack/test/api_integration/apis/metrics_ui/metadata.ts +++ b/x-pack/test/api_integration/apis/metrics_ui/metadata.ts @@ -157,6 +157,13 @@ export default function ({ getService }: FtrProviderContext) { region: 'us-east-2', account: { id: '015351775590' }, }, + agent: { + hostname: 'ip-172-31-47-9.us-east-2.compute.internal', + id: 'd0943b36-d0d3-426d-892b-7d79c071b44b', + ephemeral_id: '64c94244-88b8-4a37-adc0-30428fefaf53', + type: 'metricbeat', + version: '8.0.0', + }, host: { hostname: 'ip-172-31-47-9.us-east-2.compute.internal', os: { From 84e95ae98807da735e748b8ce5a0cb83d982013d Mon Sep 17 00:00:00 2001 From: Phillip Burch Date: Tue, 1 Dec 2020 07:30:51 -0600 Subject: [PATCH 09/15] Fix tests for pods --- x-pack/test/api_integration/apis/metrics_ui/metadata.ts | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/x-pack/test/api_integration/apis/metrics_ui/metadata.ts b/x-pack/test/api_integration/apis/metrics_ui/metadata.ts index 423fa345ac2b6..4c310b878d3f2 100644 --- a/x-pack/test/api_integration/apis/metrics_ui/metadata.ts +++ b/x-pack/test/api_integration/apis/metrics_ui/metadata.ts @@ -202,6 +202,13 @@ export default function ({ getService }: FtrProviderContext) { id: '6613144177892233360', name: 'gke-observability-8--observability-8--bc1afd95-ngmh', }, + agent: { + hostname: 'gke-observability-8--observability-8--bc1afd95-ngmh', + id: '66dc19e6-da36-49d2-9471-2c9475503178', + ephemeral_id: 'a0c3a9ff-470a-41a0-bf43-d1af6b7a3b5b', + type: 'metricbeat', + version: '8.0.0', + }, provider: 'gcp', availability_zone: 'europe-west1-c', machine: { From ceaac8c0150ee70e804de41b1f11e554306d5b0b Mon Sep 17 00:00:00 2001 From: Phillip Burch Date: Tue, 1 Dec 2020 08:25:18 -0600 Subject: [PATCH 10/15] Add link to node details page --- .../components/node_details/overlay.tsx | 39 +++++++++++++++++-- .../apis/metrics_ui/metadata.ts | 14 +++---- 2 files changed, 43 insertions(+), 10 deletions(-) diff --git a/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/node_details/overlay.tsx b/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/node_details/overlay.tsx index f1760595ab8ca..be953ded70d79 100644 --- a/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/node_details/overlay.tsx +++ b/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/node_details/overlay.tsx @@ -16,6 +16,9 @@ import { LogsTab } from './tabs/logs'; import { ProcessesTab } from './tabs/processes'; import { PropertiesTab } from './tabs/properties/index'; import { OVERLAY_Y_START, OVERLAY_BOTTOM_MARGIN, OVERLAY_HEADER_SIZE } from './tabs/shared'; +import { useLinkProps } from '../../../../../hooks/use_link_props'; +import { getNodeDetailUrl } from '../../../../link_to'; +import { findInventoryModel } from '../../../../../../common/inventory_models'; interface Props { isOpen: boolean; @@ -35,6 +38,8 @@ export const NodeContextPopover = ({ }: Props) => { // eslint-disable-next-line react-hooks/exhaustive-deps const tabConfigs = [MetricsTab, LogsTab, ProcessesTab, PropertiesTab]; + const inventoryModel = findInventoryModel(nodeType); + const nodeDetailFrom = currentTime - inventoryModel.metrics.defaultTimeRangeInSeconds * 1000; const tabs = useMemo(() => { return tabConfigs.map((m) => { @@ -50,6 +55,15 @@ export const NodeContextPopover = ({ const [selectedTab, setSelectedTab] = useState(0); + const nodeDetailMenuItemLinkProps = useLinkProps({ + ...getNodeDetailUrl({ + nodeType, + nodeId: node.id, + from: nodeDetailFrom, + to: currentTime, + }), + }); + if (!isOpen) { return null; } @@ -65,9 +79,28 @@ export const NodeContextPopover = ({ - - - + + + + + + + + + + + + diff --git a/x-pack/test/api_integration/apis/metrics_ui/metadata.ts b/x-pack/test/api_integration/apis/metrics_ui/metadata.ts index 4c310b878d3f2..279a155f9567b 100644 --- a/x-pack/test/api_integration/apis/metrics_ui/metadata.ts +++ b/x-pack/test/api_integration/apis/metrics_ui/metadata.ts @@ -202,13 +202,6 @@ export default function ({ getService }: FtrProviderContext) { id: '6613144177892233360', name: 'gke-observability-8--observability-8--bc1afd95-ngmh', }, - agent: { - hostname: 'gke-observability-8--observability-8--bc1afd95-ngmh', - id: '66dc19e6-da36-49d2-9471-2c9475503178', - ephemeral_id: 'a0c3a9ff-470a-41a0-bf43-d1af6b7a3b5b', - type: 'metricbeat', - version: '8.0.0', - }, provider: 'gcp', availability_zone: 'europe-west1-c', machine: { @@ -218,6 +211,13 @@ export default function ({ getService }: FtrProviderContext) { id: 'elastic-observability', }, }, + agent: { + hostname: 'gke-observability-8--observability-8--bc1afd95-ngmh', + id: '66dc19e6-da36-49d2-9471-2c9475503178', + ephemeral_id: 'a0c3a9ff-470a-41a0-bf43-d1af6b7a3b5b', + type: 'metricbeat', + version: '8.0.0', + }, host: { hostname: 'gke-observability-8--observability-8--bc1afd95-ngmh', name: 'gke-observability-8--observability-8--bc1afd95-ngmh', From 25e23ed7a149cf9b9b2be4027588dac4ff2d29f3 Mon Sep 17 00:00:00 2001 From: Phillip Burch Date: Tue, 1 Dec 2020 09:55:24 -0600 Subject: [PATCH 11/15] Only show the overlay when viewing hosts --- .../metrics/inventory_view/components/waffle/node.tsx | 8 +++++++- .../components/waffle/node_context_menu.tsx | 9 --------- x-pack/test/api_integration/apis/metrics_ui/metadata.ts | 7 +++++++ 3 files changed, 14 insertions(+), 10 deletions(-) diff --git a/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/waffle/node.tsx b/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/waffle/node.tsx index f2d9da960df81..03fb53898e316 100644 --- a/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/waffle/node.tsx +++ b/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/waffle/node.tsx @@ -54,6 +54,7 @@ export const Node = class extends React.PureComponent { defaultMessage: '{nodeName}, click to open menu', values: { nodeName: node.name }, }); + return ( <> { } private togglePopover = () => { - this.setState((prevState) => ({ isPopoverOpen: !prevState.isPopoverOpen })); + const { nodeType } = this.props; + if (nodeType === 'host') { + this.toggleNewOverlay(); + } else { + this.setState((prevState) => ({ isPopoverOpen: !prevState.isPopoverOpen })); + } }; private toggleNewOverlay = () => { diff --git a/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/waffle/node_context_menu.tsx b/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/waffle/node_context_menu.tsx index 91c6ad801000a..3179d4aa05268 100644 --- a/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/waffle/node_context_menu.tsx +++ b/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/waffle/node_context_menu.tsx @@ -161,14 +161,6 @@ export const NodeContextMenu: React.FC = withTheme }, }; - const openNewOverlayMenuItem: SectionLinkProps = { - label: i18n.translate('xpack.infra.nodeContextMenu.openNewOverlay', { - defaultMessage: '**** [NEW] Overlay ***', - }), - style: { color: theme?.eui.euiLinkColor || '#006BB4', fontWeight: 500, padding: 0 }, - onClick: openNewOverlay, - }; - return ( <> = withTheme - diff --git a/x-pack/test/api_integration/apis/metrics_ui/metadata.ts b/x-pack/test/api_integration/apis/metrics_ui/metadata.ts index 279a155f9567b..e319e59045d26 100644 --- a/x-pack/test/api_integration/apis/metrics_ui/metadata.ts +++ b/x-pack/test/api_integration/apis/metrics_ui/metadata.ts @@ -265,6 +265,13 @@ export default function ({ getService }: FtrProviderContext) { id: 'elastic-observability', }, }, + agent: { + hostname: 'gke-observability-8--observability-8--bc1afd95-nhhw', + id: 'c58a514c-e971-4590-8206-385400e184dd', + ephemeral_id: 'e9d46cb0-2e89-469d-bd3b-6f32d7c96cc0', + type: 'metricbeat', + version: '8.0.0', + }, host: { hostname: 'gke-observability-8--observability-8--bc1afd95-nhhw', name: 'gke-observability-8--observability-8--bc1afd95-nhhw', From 161a80e6c4b5bc20a6254bc2ebd549dd9bd0a5f7 Mon Sep 17 00:00:00 2001 From: Phillip Burch Date: Tue, 1 Dec 2020 17:32:01 -0600 Subject: [PATCH 12/15] Take into account cores when showing cpu --- .../node_details/tabs/metrics/metrics.tsx | 25 ++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/node_details/tabs/metrics/metrics.tsx b/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/node_details/tabs/metrics/metrics.tsx index 87d76855acba2..a12df113e5488 100644 --- a/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/node_details/tabs/metrics/metrics.tsx +++ b/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/node_details/tabs/metrics/metrics.tsx @@ -83,9 +83,9 @@ const TabComponent = (props: TabProps) => { } const buildCustomMetric = useCallback( - (field: string, id: string) => ({ + (field: string, id: string, aggregation: string = 'avg') => ({ type: 'custom' as SnapshotMetricType, - aggregation: 'avg', + aggregation, field, id, }), @@ -111,6 +111,7 @@ const TabComponent = (props: TabProps) => { buildCustomMetric('system.load.15', 'load15m'), buildCustomMetric('system.memory.actual.used.bytes', 'usedMemory'), buildCustomMetric('system.memory.actual.free', 'freeMemory'), + buildCustomMetric('system.cpu.cores', 'cores', 'max'), ], [], nodeType, @@ -166,7 +167,7 @@ const TabComponent = (props: TabProps) => { base.rows = base.rows.map((b, rowIdx) => { const newRow = { ...b }; otherSeries.forEach((o, idx) => { - newRow[`metric_${idx + 1}`] = o.rows[rowIdx].metric_0; + newRow[`metric_${idx + 1}`] = o.rows[rowIdx].metric_0 as number; }); return newRow; }); @@ -224,6 +225,7 @@ const TabComponent = (props: TabProps) => { const load15mMetricsTs = useMemo(() => getTimeseries('load15m'), [getTimeseries]); const usedMemoryMetricsTs = useMemo(() => getTimeseries('usedMemory'), [getTimeseries]); const freeMemoryMetricsTs = useMemo(() => getTimeseries('freeMemory'), [getTimeseries]); + const coresMetricsTs = useMemo(() => getTimeseries('cores'), [getTimeseries]); useEffect(() => { reload(); @@ -254,6 +256,23 @@ const TabComponent = (props: TabProps) => { 'rate' ); + systemMetricsTs.rows = systemMetricsTs.rows.slice().map((r, idx) => { + if (r.metric_0 && coresMetricsTs?.rows[idx].metric_0) { + const metric0: number = r.metric_0! as number; + const cores: number = coresMetricsTs!.rows[idx].metric_0! as number; + r.metric_0 = metric0 / cores; + } + return r; + }); + + userMetricsTs.rows = userMetricsTs.rows.slice().map((r, idx) => { + if (r.metric_0 && coresMetricsTs?.rows[idx].metric_0) { + const metric0: number = r.metric_0! as number; + const cores: number = coresMetricsTs!.rows[idx].metric_0! as number; + r.metric_0 = metric0 / cores; + } + return r; + }); const cpuTimeseries = mergeTimeseries(systemMetricsTs, userMetricsTs); const networkTimeseries = mergeTimeseries(rxMetricsTs, txMetricsTs); const loadTimeseries = mergeTimeseries(load1mMetricsTs, load5mMetricsTs, load15mMetricsTs); From a7a7f1342d240a96efbccb691581f7841f395971 Mon Sep 17 00:00:00 2001 From: Phillip Burch Date: Tue, 1 Dec 2020 17:49:50 -0600 Subject: [PATCH 13/15] Make it easier to read --- .../node_details/tabs/metrics/metrics.tsx | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/node_details/tabs/metrics/metrics.tsx b/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/node_details/tabs/metrics/metrics.tsx index a12df113e5488..5be44d410abe1 100644 --- a/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/node_details/tabs/metrics/metrics.tsx +++ b/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/node_details/tabs/metrics/metrics.tsx @@ -257,19 +257,19 @@ const TabComponent = (props: TabProps) => { ); systemMetricsTs.rows = systemMetricsTs.rows.slice().map((r, idx) => { - if (r.metric_0 && coresMetricsTs?.rows[idx].metric_0) { - const metric0: number = r.metric_0! as number; - const cores: number = coresMetricsTs!.rows[idx].metric_0! as number; - r.metric_0 = metric0 / cores; + const metric = r.metric_0 as number | undefined; + const cores = coresMetricsTs!.rows[idx].metric_0 as number | undefined; + if (metric && cores) { + r.metric_0 = metric / cores; } return r; }); userMetricsTs.rows = userMetricsTs.rows.slice().map((r, idx) => { - if (r.metric_0 && coresMetricsTs?.rows[idx].metric_0) { - const metric0: number = r.metric_0! as number; - const cores: number = coresMetricsTs!.rows[idx].metric_0! as number; - r.metric_0 = metric0 / cores; + const metric = r.metric_0 as number | undefined; + const cores = coresMetricsTs!.rows[idx].metric_0 as number | undefined; + if (metric && cores) { + r.metric_0 = metric / cores; } return r; }); From c2da6f5b66ea2f69f1227e1da0a459ea3fe3fcdd Mon Sep 17 00:00:00 2001 From: Phillip Burch Date: Tue, 1 Dec 2020 18:04:32 -0600 Subject: [PATCH 14/15] Remove unnecessary cast --- .../components/node_details/tabs/metrics/metrics.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/node_details/tabs/metrics/metrics.tsx b/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/node_details/tabs/metrics/metrics.tsx index 5be44d410abe1..789658c060403 100644 --- a/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/node_details/tabs/metrics/metrics.tsx +++ b/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/node_details/tabs/metrics/metrics.tsx @@ -167,7 +167,7 @@ const TabComponent = (props: TabProps) => { base.rows = base.rows.map((b, rowIdx) => { const newRow = { ...b }; otherSeries.forEach((o, idx) => { - newRow[`metric_${idx + 1}`] = o.rows[rowIdx].metric_0 as number; + newRow[`metric_${idx + 1}`] = o.rows[rowIdx].metric_0; }); return newRow; }); From 4f6b8db44779ba5e964368b085138e858cdc1391 Mon Sep 17 00:00:00 2001 From: Phillip Burch Date: Thu, 3 Dec 2020 07:05:53 -0600 Subject: [PATCH 15/15] Fix PR feedback --- .../node_details/tabs/properties/build_fields.ts | 15 +++++++++------ .../node_details/tabs/properties/index.tsx | 6 +++--- .../node_details/tabs/properties/table.tsx | 3 ++- 3 files changed, 14 insertions(+), 10 deletions(-) diff --git a/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/node_details/tabs/properties/build_fields.ts b/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/node_details/tabs/properties/build_fields.ts index 98609a2cd8fa4..79610ba3eef0a 100644 --- a/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/node_details/tabs/properties/build_fields.ts +++ b/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/node_details/tabs/properties/build_fields.ts @@ -9,7 +9,7 @@ import { InfraMetadata } from '../../../../../../../../common/http_api'; export const getFields = (metadata: InfraMetadata, group: 'cloud' | 'host' | 'agent') => { switch (group) { case 'host': - return [ + return prune([ { name: 'host.architecture', value: metadata.info?.host?.architecture, @@ -58,9 +58,9 @@ export const getFields = (metadata: InfraMetadata, group: 'cloud' | 'host' | 'ag name: 'host.os.version', value: metadata.info?.host?.os?.version, }, - ]; + ]); case 'cloud': - return [ + return prune([ { name: 'cloud.account.id', value: metadata.info?.cloud?.account?.id, @@ -93,9 +93,9 @@ export const getFields = (metadata: InfraMetadata, group: 'cloud' | 'host' | 'ag name: 'cloud.region', value: metadata.info?.cloud?.region, }, - ]; + ]); case 'agent': - return [ + return prune([ { name: 'agent.id', value: metadata.info?.agent?.id, @@ -108,6 +108,9 @@ export const getFields = (metadata: InfraMetadata, group: 'cloud' | 'host' | 'ag name: 'agent.policy', value: metadata.info?.agent?.policy, }, - ]; + ]); } }; + +const prune = (fields: Array<{ name: string; value: string | string[] | undefined }>) => + fields.filter((f) => !!f.value); diff --git a/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/node_details/tabs/properties/index.tsx b/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/node_details/tabs/properties/index.tsx index 9fadc6eb6f214..b901c37484381 100644 --- a/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/node_details/tabs/properties/index.tsx +++ b/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/node_details/tabs/properties/index.tsx @@ -64,7 +64,7 @@ const TabComponent = (props: TabProps) => { return ( - {hostFields && ( + {hostFields && hostFields.length > 0 && (
{ /> )} - {cloudFields && ( + {cloudFields && cloudFields.length > 0 && (
{ /> )} - {agentFields && ( + {agentFields && agentFields.length > 0 && (
{ {!isExpanded && ( - {values[0]} + {first(values)} {' ... '}