From b533b7718785b40bc2cc7d0602bb2ad09f67304b Mon Sep 17 00:00:00 2001 From: Jenny Date: Thu, 22 Aug 2024 13:50:06 +0200 Subject: [PATCH 1/9] Add troubleshooting link to apm services empty message --- .../asset_details/tabs/overview/services.tsx | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/x-pack/plugins/observability_solution/infra/public/components/asset_details/tabs/overview/services.tsx b/x-pack/plugins/observability_solution/infra/public/components/asset_details/tabs/overview/services.tsx index ec633420ce1a7..9ba1728ef604f 100644 --- a/x-pack/plugins/observability_solution/infra/public/components/asset_details/tabs/overview/services.tsx +++ b/x-pack/plugins/observability_solution/infra/public/components/asset_details/tabs/overview/services.tsx @@ -119,7 +119,7 @@ export const ServicesContent = ({ values={{ apmTutorialLink: ( + + +

)} From 7613e0923e941fcb57c69be216d26984eb8e08c0 Mon Sep 17 00:00:00 2001 From: Jenny Date: Thu, 22 Aug 2024 17:35:49 +0200 Subject: [PATCH 2/9] Add troubleshooting message and link for hosts with/without system metrics --- .../infra/common/http_api/metadata_api.ts | 1 + .../asset_details/tabs/overview/services.tsx | 25 +++++++++++++++--- .../infra/server/routes/metadata/index.ts | 2 ++ .../metadata/lib/get_metric_metadata.ts | 26 ++++++++++++++++++- 4 files changed, 50 insertions(+), 4 deletions(-) diff --git a/x-pack/plugins/observability_solution/infra/common/http_api/metadata_api.ts b/x-pack/plugins/observability_solution/infra/common/http_api/metadata_api.ts index f2f5bc2c07dbe..9afb527a9120c 100644 --- a/x-pack/plugins/observability_solution/infra/common/http_api/metadata_api.ts +++ b/x-pack/plugins/observability_solution/infra/common/http_api/metadata_api.ts @@ -106,6 +106,7 @@ export const InfraMetadataInfoResponseRT = rt.partial({ const InfraMetadataRequiredRT = rt.type({ id: rt.string, name: rt.string, + hasSystemIntegration: rt.boolean, features: rt.array(InfraMetadataFeatureRT), }); diff --git a/x-pack/plugins/observability_solution/infra/public/components/asset_details/tabs/overview/services.tsx b/x-pack/plugins/observability_solution/infra/public/components/asset_details/tabs/overview/services.tsx index 9ba1728ef604f..fc58afbdaf596 100644 --- a/x-pack/plugins/observability_solution/infra/public/components/asset_details/tabs/overview/services.tsx +++ b/x-pack/plugins/observability_solution/infra/public/components/asset_details/tabs/overview/services.tsx @@ -22,6 +22,7 @@ import { LinkToApmService } from '../../links/link_to_apm_service'; import { useKibanaEnvironmentContext } from '../../../../hooks/use_kibana'; import { useRequestObservable } from '../../hooks/use_request_observable'; import { useTabSwitcherContext } from '../../hooks/use_tab_switcher'; +import { useMetadataStateContext } from '../../hooks/use_metadata_state'; export const ServicesContent = ({ hostName, @@ -33,6 +34,7 @@ export const ServicesContent = ({ const { isServerlessEnv } = useKibanaEnvironmentContext(); const { request$ } = useRequestObservable(); const { isActiveTab } = useTabSwitcherContext(); + const { metadata, loading: metadataLoading } = useMetadataStateContext(); const linkProps = useLinkProps({ app: 'home', @@ -92,7 +94,7 @@ export const ServicesContent = ({ defaultMessage: 'An error occurred while fetching services.', })} - ) : isPending(status) ? ( + ) : isPending(status) || metadataLoading ? ( ) : hasServices ? ( ))} - ) : ( + ) : metadata?.hasSystemIntegration ? (

), }} - /> + />{' '} + + + +

+ ) : ( +

+ {' '} { timeRange ); const metricFeatures = pickFeatureName(metricsMetadata.buckets).map(nameToFeature('metrics')); + const hasSystemIntegration = metricsMetadata.hasSystemIntegration; const info = await getNodeInfo( framework, @@ -82,6 +83,7 @@ export const initMetadataRoute = (libs: InfraBackendLibs) => { body: InfraMetadataRT.encode({ id, name, + hasSystemIntegration, features: [...metricFeatures, ...cloudMetricsFeatures], info: { ...info, diff --git a/x-pack/plugins/observability_solution/infra/server/routes/metadata/lib/get_metric_metadata.ts b/x-pack/plugins/observability_solution/infra/server/routes/metadata/lib/get_metric_metadata.ts index f12cce92e60b5..30f000d4c235c 100644 --- a/x-pack/plugins/observability_solution/infra/server/routes/metadata/lib/get_metric_metadata.ts +++ b/x-pack/plugins/observability_solution/infra/server/routes/metadata/lib/get_metric_metadata.ts @@ -15,12 +15,14 @@ import { } from '../../../lib/adapters/framework'; import { KibanaFramework } from '../../../lib/adapters/framework/kibana_framework_adapter'; import { InfraSourceConfiguration } from '../../../lib/sources'; -import { TIMESTAMP_FIELD } from '../../../../common/constants'; +import { HOST_NAME_FIELD, SYSTEM_INTEGRATION, TIMESTAMP_FIELD } from '../../../../common/constants'; +import { getFilterByIntegration } from '../../infra/lib/helpers/query'; export interface InfraMetricsAdapterResponse { id: string; name?: string; buckets: InfraMetadataAggregationBucket[]; + hasSystemIntegration: boolean; } export const getMetricMetadata = async ( @@ -70,6 +72,20 @@ export const getMetricMetadata = async ( size: 1000, }, }, + monitoredHost: { + filter: getFilterByIntegration(SYSTEM_INTEGRATION), + aggs: { + name: { + terms: { + field: HOST_NAME_FIELD, + size: 1, + order: { + _key: 'asc', + }, + }, + }, + }, + }, }, }, }; @@ -79,6 +95,7 @@ export const getMetricMetadata = async ( { metrics?: InfraMetadataAggregationResponse; nodeName?: InfraMetadataAggregationResponse; + monitoredHost?: { name: InfraMetadataAggregationResponse }; } >(requestContext, 'search', metricQuery); @@ -86,10 +103,17 @@ export const getMetricMetadata = async ( response.aggregations && response.aggregations.metrics ? response.aggregations.metrics.buckets : []; + const hostWithSystemIntegration = + response.aggregations && (response.aggregations?.monitoredHost?.name?.buckets ?? []).length > 0 + ? response.aggregations?.monitoredHost?.name.buckets[0]?.key + : null; + + const hasSystemIntegration = hostWithSystemIntegration === nodeId; return { id: nodeId, name: get(response, ['aggregations', 'nodeName', 'buckets', 0, 'key'], nodeId), + hasSystemIntegration, buckets, }; }; From cdfb4f65be74c9d6667cc057fa19950945856720 Mon Sep 17 00:00:00 2001 From: Jenny Date: Thu, 22 Aug 2024 18:15:33 +0200 Subject: [PATCH 3/9] Extract the documentation link to a constant --- .../infra/public/components/asset_details/constants.ts | 2 ++ .../components/asset_details/tabs/overview/services.tsx | 8 ++++---- .../public/pages/metrics/hosts/hooks/use_hosts_table.tsx | 3 ++- 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/x-pack/plugins/observability_solution/infra/public/components/asset_details/constants.ts b/x-pack/plugins/observability_solution/infra/public/components/asset_details/constants.ts index 3b3db1b21bd09..79f05157af92d 100644 --- a/x-pack/plugins/observability_solution/infra/public/components/asset_details/constants.ts +++ b/x-pack/plugins/observability_solution/infra/public/components/asset_details/constants.ts @@ -30,3 +30,5 @@ export const INTEGRATIONS = { export const DOCKER_METRIC_TYPES: DockerContainerMetrics[] = ['cpu', 'memory', 'network', 'disk']; export const KUBERNETES_METRIC_TYPES: KubernetesContainerMetrics[] = ['cpu', 'memory']; + +export const APM_HOST_TROUBLESHOOTING_LINK = 'https://ela.st/host-troubleshooting'; diff --git a/x-pack/plugins/observability_solution/infra/public/components/asset_details/tabs/overview/services.tsx b/x-pack/plugins/observability_solution/infra/public/components/asset_details/tabs/overview/services.tsx index fc58afbdaf596..0e504413abbcf 100644 --- a/x-pack/plugins/observability_solution/infra/public/components/asset_details/tabs/overview/services.tsx +++ b/x-pack/plugins/observability_solution/infra/public/components/asset_details/tabs/overview/services.tsx @@ -17,7 +17,7 @@ import { Section } from '../../components/section'; import { ServicesSectionTitle } from './section_titles'; import { HOST_NAME_FIELD } from '../../../../../common/constants'; import { LinkToApmServices } from '../../links'; -import { APM_HOST_FILTER_FIELD } from '../../constants'; +import { APM_HOST_FILTER_FIELD, APM_HOST_TROUBLESHOOTING_LINK } from '../../constants'; import { LinkToApmService } from '../../links/link_to_apm_service'; import { useKibanaEnvironmentContext } from '../../../../hooks/use_kibana'; import { useRequestObservable } from '../../hooks/use_request_observable'; @@ -134,7 +134,7 @@ export const ServicesContent = ({ />{' '} {' '} {

Date: Fri, 23 Aug 2024 12:59:29 +0200 Subject: [PATCH 4/9] Fix the test type --- .../components/asset_details/tabs/metadata/utils.test.ts | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/x-pack/plugins/observability_solution/infra/public/components/asset_details/tabs/metadata/utils.test.ts b/x-pack/plugins/observability_solution/infra/public/components/asset_details/tabs/metadata/utils.test.ts index 04bfdf9945ff3..74a53685973b5 100644 --- a/x-pack/plugins/observability_solution/infra/public/components/asset_details/tabs/metadata/utils.test.ts +++ b/x-pack/plugins/observability_solution/infra/public/components/asset_details/tabs/metadata/utils.test.ts @@ -13,6 +13,7 @@ describe('#getAllFields', () => { architecture: 'x86_64', containerized: false, hostname: 'host1', + hasSystemIntegration: true, ip: [ '10.10.10.10', '10.10.10.10', @@ -63,6 +64,7 @@ describe('#getAllFields', () => { const result: InfraMetadata = { id: 'host1', name: 'host1', + hasSystemIntegration: true, features: [ { name: 'system.core', @@ -77,6 +79,7 @@ describe('#getAllFields', () => { const result: InfraMetadata = { id: 'host1', name: 'host1', + hasSystemIntegration: true, features: [ { name: 'system.core', @@ -96,6 +99,7 @@ describe('#getAllFields', () => { const result: InfraMetadata = { id: 'host1', name: 'host1', + hasSystemIntegration: true, features: [ { name: 'system.core', @@ -117,6 +121,7 @@ describe('#getAllFields', () => { const result = { id: 'host1', name: 'host1', + hasSystemIntegration: true, features: [ { name: 'system.core', @@ -163,6 +168,7 @@ describe('#getAllFields', () => { const result: InfraMetadata = { id: 'host1', name: 'host1', + hasSystemIntegration: true, features: [ { name: 'system.core', @@ -266,6 +272,7 @@ describe('#getAllFields', () => { const result: InfraMetadata = { id: 'host1', name: 'host1', + hasSystemIntegration: true, features: [ { name: 'system.core', @@ -349,6 +356,7 @@ describe('#getAllFields', () => { const result: InfraMetadata = { id: 'host1', name: 'host1', + hasSystemIntegration: true, features: [ { name: 'system.core', From a56bc7fe38c68d78972f7898f39d7ca91529820a Mon Sep 17 00:00:00 2001 From: Jenny Date: Fri, 23 Aug 2024 13:00:14 +0200 Subject: [PATCH 5/9] Add missing title popover --- .../asset_details/header/flyout_header.tsx | 16 ++++- .../header/page_title_with_popover.tsx | 66 +++++++++++++++++++ .../asset_details/template/flyout.tsx | 11 +++- .../asset_details/template/page.tsx | 10 ++- 4 files changed, 97 insertions(+), 6 deletions(-) create mode 100644 x-pack/plugins/observability_solution/infra/public/components/asset_details/header/page_title_with_popover.tsx diff --git a/x-pack/plugins/observability_solution/infra/public/components/asset_details/header/flyout_header.tsx b/x-pack/plugins/observability_solution/infra/public/components/asset_details/header/flyout_header.tsx index 05f96a331a07c..ac4fe36aecb81 100644 --- a/x-pack/plugins/observability_solution/infra/public/components/asset_details/header/flyout_header.tsx +++ b/x-pack/plugins/observability_solution/infra/public/components/asset_details/header/flyout_header.tsx @@ -18,9 +18,17 @@ import { type EuiPageHeaderProps, } from '@elastic/eui'; import { css } from '@emotion/react'; -type Props = Pick; +import { PageTitleWithPopover } from './page_title_with_popover'; +type Props = Pick & { + hasSystemIntegration: boolean; +}; -export const FlyoutHeader = ({ title, tabs = [], rightSideItems = [] }: Props) => { +export const FlyoutHeader = ({ + title, + tabs = [], + rightSideItems = [], + hasSystemIntegration, +}: Props) => { const { euiTheme } = useEuiTheme(); return ( @@ -39,7 +47,9 @@ export const FlyoutHeader = ({ title, tabs = [], rightSideItems = [] }: Props) = `} > -

{title}

+

+ +

{ + return !hasSystemMetrics ? ( + + {name} + + + +

+ + + + ), + }} + /> +

+

+ + + +

+
+
+
+
+ ) : ( + <>{name} + ); +}; diff --git a/x-pack/plugins/observability_solution/infra/public/components/asset_details/template/flyout.tsx b/x-pack/plugins/observability_solution/infra/public/components/asset_details/template/flyout.tsx index 898ce873e49ec..33e6127d52e26 100644 --- a/x-pack/plugins/observability_solution/infra/public/components/asset_details/template/flyout.tsx +++ b/x-pack/plugins/observability_solution/infra/public/components/asset_details/template/flyout.tsx @@ -19,6 +19,7 @@ import { useAssetDetailsUrlState } from '../hooks/use_asset_details_url_state'; import { usePageHeader } from '../hooks/use_page_header'; import { useTabSwitcherContext } from '../hooks/use_tab_switcher'; import type { ContentTemplateProps } from '../types'; +import { useMetadataStateContext } from '../hooks/use_metadata_state'; export const Flyout = ({ tabs = [], @@ -32,6 +33,7 @@ export const Flyout = ({ const { services: { telemetry }, } = useKibanaContextForPlugin(); + const { metadata, loading: metadataLoading } = useMetadataStateContext(); useEffectOnce(() => { telemetry.reportAssetDetailsFlyoutViewed({ @@ -53,7 +55,7 @@ export const Flyout = ({ data-component-name={ASSET_DETAILS_FLYOUT_COMPONENT_NAME} data-asset-type={asset.type} > - {loading ? ( + {loading || metadataLoading ? ( - + diff --git a/x-pack/plugins/observability_solution/infra/public/components/asset_details/template/page.tsx b/x-pack/plugins/observability_solution/infra/public/components/asset_details/template/page.tsx index 346acb6d8a164..4153d84a2e03b 100644 --- a/x-pack/plugins/observability_solution/infra/public/components/asset_details/template/page.tsx +++ b/x-pack/plugins/observability_solution/infra/public/components/asset_details/template/page.tsx @@ -22,6 +22,7 @@ import { ContentTemplateProps } from '../types'; import { getIntegrationsAvailable } from '../utils'; import { InfraPageTemplate } from '../../shared/templates/infra_page_template'; import { OnboardingFlow } from '../../shared/templates/no_data_config'; +import { PageTitleWithPopover } from '../header/page_title_with_popover'; const DATA_AVAILABILITY_PER_TYPE: Partial> = { host: [SYSTEM_INTEGRATION], @@ -83,7 +84,14 @@ export const Page = ({ tabs = [], links = [] }: ContentTemplateProps) => { onboardingFlow={asset.type === 'host' ? OnboardingFlow.Hosts : OnboardingFlow.Infra} dataAvailabilityModules={DATA_AVAILABILITY_PER_TYPE[asset.type] || undefined} pageHeader={{ - pageTitle: loading ? : asset.name, + pageTitle: loading ? ( + + ) : ( + + ), tabs: tabEntries, rightSideItems, breadcrumbs: headerBreadcrumbs, From e7b829e4d127fc0c269ac9c5caff578b7c248664 Mon Sep 17 00:00:00 2001 From: Jenny Date: Fri, 23 Aug 2024 13:33:54 +0200 Subject: [PATCH 6/9] Add hasSystemIntegration only for hosts --- .../infra/common/http_api/metadata_api.ts | 2 +- .../asset_details/header/flyout_header.tsx | 9 ++- .../asset_details/template/flyout.tsx | 1 + .../asset_details/template/page.tsx | 4 +- .../infra/server/routes/metadata/index.ts | 27 +++++---- .../metadata/lib/get_metric_metadata.ts | 58 ++++++++++++------- 6 files changed, 64 insertions(+), 37 deletions(-) diff --git a/x-pack/plugins/observability_solution/infra/common/http_api/metadata_api.ts b/x-pack/plugins/observability_solution/infra/common/http_api/metadata_api.ts index 9afb527a9120c..ce2bfdfa25dcb 100644 --- a/x-pack/plugins/observability_solution/infra/common/http_api/metadata_api.ts +++ b/x-pack/plugins/observability_solution/infra/common/http_api/metadata_api.ts @@ -106,12 +106,12 @@ export const InfraMetadataInfoResponseRT = rt.partial({ const InfraMetadataRequiredRT = rt.type({ id: rt.string, name: rt.string, - hasSystemIntegration: rt.boolean, features: rt.array(InfraMetadataFeatureRT), }); const InfraMetadataOptionalRT = rt.partial({ info: InfraMetadataInfoResponseRT, + hasSystemIntegration: rt.boolean, }); export const InfraMetadataRT = rt.intersection([InfraMetadataRequiredRT, InfraMetadataOptionalRT]); diff --git a/x-pack/plugins/observability_solution/infra/public/components/asset_details/header/flyout_header.tsx b/x-pack/plugins/observability_solution/infra/public/components/asset_details/header/flyout_header.tsx index ac4fe36aecb81..800101dc12973 100644 --- a/x-pack/plugins/observability_solution/infra/public/components/asset_details/header/flyout_header.tsx +++ b/x-pack/plugins/observability_solution/infra/public/components/asset_details/header/flyout_header.tsx @@ -18,9 +18,11 @@ import { type EuiPageHeaderProps, } from '@elastic/eui'; import { css } from '@emotion/react'; +import type { InventoryItemType } from '@kbn/metrics-data-access-plugin/common/inventory_models/types'; import { PageTitleWithPopover } from './page_title_with_popover'; type Props = Pick & { hasSystemIntegration: boolean; + assetType: InventoryItemType; }; export const FlyoutHeader = ({ @@ -28,6 +30,7 @@ export const FlyoutHeader = ({ tabs = [], rightSideItems = [], hasSystemIntegration, + assetType, }: Props) => { const { euiTheme } = useEuiTheme(); @@ -48,7 +51,11 @@ export const FlyoutHeader = ({ >

- + {assetType === 'host' ? ( + + ) : ( + title + )}

diff --git a/x-pack/plugins/observability_solution/infra/public/components/asset_details/template/flyout.tsx b/x-pack/plugins/observability_solution/infra/public/components/asset_details/template/flyout.tsx index 33e6127d52e26..cb8dfaf0e0d1b 100644 --- a/x-pack/plugins/observability_solution/infra/public/components/asset_details/template/flyout.tsx +++ b/x-pack/plugins/observability_solution/infra/public/components/asset_details/template/flyout.tsx @@ -71,6 +71,7 @@ export const Flyout = ({ tabs={tabEntries} rightSideItems={rightSideItems} hasSystemIntegration={!!metadata?.hasSystemIntegration} + assetType={asset.type} /> diff --git a/x-pack/plugins/observability_solution/infra/public/components/asset_details/template/page.tsx b/x-pack/plugins/observability_solution/infra/public/components/asset_details/template/page.tsx index 4153d84a2e03b..3c43984e2ecb4 100644 --- a/x-pack/plugins/observability_solution/infra/public/components/asset_details/template/page.tsx +++ b/x-pack/plugins/observability_solution/infra/public/components/asset_details/template/page.tsx @@ -86,11 +86,13 @@ export const Page = ({ tabs = [], links = [] }: ContentTemplateProps) => { pageHeader={{ pageTitle: loading ? ( - ) : ( + ) : asset.type === 'host' ? ( + ) : ( + asset.name ), tabs: tabEntries, rightSideItems, diff --git a/x-pack/plugins/observability_solution/infra/server/routes/metadata/index.ts b/x-pack/plugins/observability_solution/infra/server/routes/metadata/index.ts index 162c10e5629ec..d8096695e3501 100644 --- a/x-pack/plugins/observability_solution/infra/server/routes/metadata/index.ts +++ b/x-pack/plugins/observability_solution/infra/server/routes/metadata/index.ts @@ -53,7 +53,6 @@ export const initMetadataRoute = (libs: InfraBackendLibs) => { timeRange ); const metricFeatures = pickFeatureName(metricsMetadata.buckets).map(nameToFeature('metrics')); - const hasSystemIntegration = metricsMetadata.hasSystemIntegration; const info = await getNodeInfo( framework, @@ -79,18 +78,22 @@ export const initMetadataRoute = (libs: InfraBackendLibs) => { ); const id = metricsMetadata.id; const name = metricsMetadata.name || id; - return response.ok({ - body: InfraMetadataRT.encode({ - id, - name, - hasSystemIntegration, - features: [...metricFeatures, ...cloudMetricsFeatures], - info: { - ...info, - timestamp: info['@timestamp'], - }, - }), + + const responseBody = InfraMetadataRT.encode({ + id, + name, + features: [...metricFeatures, ...cloudMetricsFeatures], + info: { + ...info, + timestamp: info['@timestamp'], + }, }); + if (nodeType === 'host') { + const hasSystemIntegration = metricsMetadata?.hasSystemIntegration; + return response.ok({ body: { ...responseBody, hasSystemIntegration } }); + } + + return response.ok({ body: responseBody }); } ); }; diff --git a/x-pack/plugins/observability_solution/infra/server/routes/metadata/lib/get_metric_metadata.ts b/x-pack/plugins/observability_solution/infra/server/routes/metadata/lib/get_metric_metadata.ts index 30f000d4c235c..54187d14c8ba9 100644 --- a/x-pack/plugins/observability_solution/infra/server/routes/metadata/lib/get_metric_metadata.ts +++ b/x-pack/plugins/observability_solution/infra/server/routes/metadata/lib/get_metric_metadata.ts @@ -4,7 +4,7 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ - +import { set } from '@kbn/safer-lodash-set'; import { get } from 'lodash'; import { findInventoryFields } from '@kbn/metrics-data-access-plugin/common'; import { InventoryItemType } from '@kbn/metrics-data-access-plugin/common'; @@ -22,7 +22,7 @@ export interface InfraMetricsAdapterResponse { id: string; name?: string; buckets: InfraMetadataAggregationBucket[]; - hasSystemIntegration: boolean; + hasSystemIntegration?: boolean; } export const getMetricMetadata = async ( @@ -72,23 +72,28 @@ export const getMetricMetadata = async ( size: 1000, }, }, - monitoredHost: { - filter: getFilterByIntegration(SYSTEM_INTEGRATION), - aggs: { - name: { - terms: { - field: HOST_NAME_FIELD, - size: 1, - order: { - _key: 'asc', - }, + }, + }, + }; + + if (nodeType === 'host') { + set(metricQuery, 'body.aggs', { + monitoredHost: { + filter: getFilterByIntegration(SYSTEM_INTEGRATION), + aggs: { + name: { + terms: { + field: HOST_NAME_FIELD, + size: 1, + order: { + _key: 'asc', }, }, }, }, }, - }, - }; + }); + } const response = await framework.callWithRequest< {}, @@ -103,17 +108,26 @@ export const getMetricMetadata = async ( response.aggregations && response.aggregations.metrics ? response.aggregations.metrics.buckets : []; - const hostWithSystemIntegration = - response.aggregations && (response.aggregations?.monitoredHost?.name?.buckets ?? []).length > 0 - ? response.aggregations?.monitoredHost?.name.buckets[0]?.key - : null; - - const hasSystemIntegration = hostWithSystemIntegration === nodeId; - return { + const res = { id: nodeId, name: get(response, ['aggregations', 'nodeName', 'buckets', 0, 'key'], nodeId), - hasSystemIntegration, buckets, }; + + if (nodeType === 'host') { + const hostWithSystemIntegration = + response.aggregations && + (response.aggregations?.monitoredHost?.name?.buckets ?? []).length > 0 + ? response.aggregations?.monitoredHost?.name.buckets[0]?.key + : null; + + const hasSystemIntegration = hostWithSystemIntegration === nodeId; + return { + hasSystemIntegration, + ...res, + }; + } + + return res; }; From 429f136750e55b35600875442a14d1e3fce7efaa Mon Sep 17 00:00:00 2001 From: Jenny Date: Fri, 23 Aug 2024 16:44:01 +0200 Subject: [PATCH 7/9] CR changes --- .../asset_details/header/flyout_header.tsx | 26 ++++++++--- .../asset_details/template/flyout.tsx | 42 +++++++----------- .../infra/lib/host/get_filtered_hosts.ts | 14 ++++-- .../infra/server/routes/metadata/index.ts | 9 +++- .../metadata/lib/get_metric_metadata.ts | 43 ++++++------------- 5 files changed, 67 insertions(+), 67 deletions(-) diff --git a/x-pack/plugins/observability_solution/infra/public/components/asset_details/header/flyout_header.tsx b/x-pack/plugins/observability_solution/infra/public/components/asset_details/header/flyout_header.tsx index 800101dc12973..8a410d4518352 100644 --- a/x-pack/plugins/observability_solution/infra/public/components/asset_details/header/flyout_header.tsx +++ b/x-pack/plugins/observability_solution/infra/public/components/asset_details/header/flyout_header.tsx @@ -16,6 +16,7 @@ import { useEuiTheme, useEuiMinBreakpoint, type EuiPageHeaderProps, + EuiLoadingSpinner, } from '@elastic/eui'; import { css } from '@emotion/react'; import type { InventoryItemType } from '@kbn/metrics-data-access-plugin/common/inventory_models/types'; @@ -23,6 +24,8 @@ import { PageTitleWithPopover } from './page_title_with_popover'; type Props = Pick & { hasSystemIntegration: boolean; assetType: InventoryItemType; + metadataLoading: boolean; + loading: boolean; }; export const FlyoutHeader = ({ @@ -31,6 +34,8 @@ export const FlyoutHeader = ({ rightSideItems = [], hasSystemIntegration, assetType, + metadataLoading, + loading, }: Props) => { const { euiTheme } = useEuiTheme(); @@ -50,13 +55,20 @@ export const FlyoutHeader = ({ `} > -

- {assetType === 'host' ? ( - - ) : ( - title - )} -

+ {metadataLoading || loading ? ( + + ) : ( +

+ {assetType === 'host' ? ( + + ) : ( + title + )} +

+ )}
- {loading || metadataLoading ? ( - - ) : ( - <> - - - - - - - - )} + <> + + + + + + + ); }; diff --git a/x-pack/plugins/observability_solution/infra/server/routes/infra/lib/host/get_filtered_hosts.ts b/x-pack/plugins/observability_solution/infra/server/routes/infra/lib/host/get_filtered_hosts.ts index c943206853821..ef6e6a2c2a040 100644 --- a/x-pack/plugins/observability_solution/infra/server/routes/infra/lib/host/get_filtered_hosts.ts +++ b/x-pack/plugins/observability_solution/infra/server/routes/infra/lib/host/get_filtered_hosts.ts @@ -8,7 +8,7 @@ import { rangeQuery } from '@kbn/observability-plugin/server'; import { estypes } from '@elastic/elasticsearch'; import { castArray } from 'lodash'; -import { HOST_NAME_FIELD } from '../../../../../common/constants'; +import { HOST_NAME_FIELD, SYSTEM_INTEGRATION } from '../../../../../common/constants'; import { GetHostParameters } from '../types'; import { getFilterByIntegration } from '../helpers/query'; @@ -28,7 +28,11 @@ export const getFilteredHostNames = async ({ track_total_hits: false, query: { bool: { - filter: [...castArray(query), ...rangeQuery(from, to), getFilterByIntegration('system')], + filter: [ + ...castArray(query), + ...rangeQuery(from, to), + getFilterByIntegration(SYSTEM_INTEGRATION), + ], }, }, aggs: { @@ -66,7 +70,11 @@ export const getHasDataFromSystemIntegration = async ({ track_total_hits: true, query: { bool: { - filter: [...castArray(query), ...rangeQuery(from, to), getFilterByIntegration('system')], + filter: [ + ...castArray(query), + ...rangeQuery(from, to), + getFilterByIntegration(SYSTEM_INTEGRATION), + ], }, }, }, diff --git a/x-pack/plugins/observability_solution/infra/server/routes/metadata/index.ts b/x-pack/plugins/observability_solution/infra/server/routes/metadata/index.ts index d8096695e3501..10b0fe8932a30 100644 --- a/x-pack/plugins/observability_solution/infra/server/routes/metadata/index.ts +++ b/x-pack/plugins/observability_solution/infra/server/routes/metadata/index.ts @@ -22,6 +22,7 @@ import { getMetricMetadata } from './lib/get_metric_metadata'; import { pickFeatureName } from './lib/pick_feature_name'; import { getCloudMetricsMetadata } from './lib/get_cloud_metric_metadata'; import { getNodeInfo } from './lib/get_node_info'; +import { getInfraMetricsClient } from '../../lib/helpers/get_infra_metrics_client'; const escapeHatch = schema.object({}, { unknowns: 'allow' }); @@ -44,13 +45,19 @@ export const initMetadataRoute = (libs: InfraBackendLibs) => { const soClient = (await requestContext.core).savedObjects.client; const { configuration } = await libs.sources.getSourceConfiguration(soClient, sourceId); + const infraMetricsClient = await getInfraMetricsClient({ + request, + libs, + context: requestContext, + }); const metricsMetadata = await getMetricMetadata( framework, requestContext, configuration, nodeId, nodeType, - timeRange + timeRange, + infraMetricsClient ); const metricFeatures = pickFeatureName(metricsMetadata.buckets).map(nameToFeature('metrics')); diff --git a/x-pack/plugins/observability_solution/infra/server/routes/metadata/lib/get_metric_metadata.ts b/x-pack/plugins/observability_solution/infra/server/routes/metadata/lib/get_metric_metadata.ts index 54187d14c8ba9..ef5afc9f5b20a 100644 --- a/x-pack/plugins/observability_solution/infra/server/routes/metadata/lib/get_metric_metadata.ts +++ b/x-pack/plugins/observability_solution/infra/server/routes/metadata/lib/get_metric_metadata.ts @@ -4,10 +4,10 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ -import { set } from '@kbn/safer-lodash-set'; import { get } from 'lodash'; import { findInventoryFields } from '@kbn/metrics-data-access-plugin/common'; import { InventoryItemType } from '@kbn/metrics-data-access-plugin/common'; +import type { InfraMetricsClient } from '../../../lib/helpers/get_infra_metrics_client'; import type { InfraPluginRequestHandlerContext } from '../../../types'; import { InfraMetadataAggregationBucket, @@ -15,8 +15,8 @@ import { } from '../../../lib/adapters/framework'; import { KibanaFramework } from '../../../lib/adapters/framework/kibana_framework_adapter'; import { InfraSourceConfiguration } from '../../../lib/sources'; -import { HOST_NAME_FIELD, SYSTEM_INTEGRATION, TIMESTAMP_FIELD } from '../../../../common/constants'; -import { getFilterByIntegration } from '../../infra/lib/helpers/query'; +import { TIMESTAMP_FIELD } from '../../../../common/constants'; +import { getHasDataFromSystemIntegration } from '../../infra/lib/host/get_filtered_hosts'; export interface InfraMetricsAdapterResponse { id: string; @@ -31,7 +31,8 @@ export const getMetricMetadata = async ( sourceConfiguration: InfraSourceConfiguration, nodeId: string, nodeType: InventoryItemType, - timeRange: { from: number; to: number } + timeRange: { from: number; to: number }, + infraMetricsClient: InfraMetricsClient ): Promise => { const fields = findInventoryFields(nodeType); const metricQuery = { @@ -76,31 +77,11 @@ export const getMetricMetadata = async ( }, }; - if (nodeType === 'host') { - set(metricQuery, 'body.aggs', { - monitoredHost: { - filter: getFilterByIntegration(SYSTEM_INTEGRATION), - aggs: { - name: { - terms: { - field: HOST_NAME_FIELD, - size: 1, - order: { - _key: 'asc', - }, - }, - }, - }, - }, - }); - } - const response = await framework.callWithRequest< {}, { metrics?: InfraMetadataAggregationResponse; nodeName?: InfraMetadataAggregationResponse; - monitoredHost?: { name: InfraMetadataAggregationResponse }; } >(requestContext, 'search', metricQuery); @@ -116,13 +97,15 @@ export const getMetricMetadata = async ( }; if (nodeType === 'host') { - const hostWithSystemIntegration = - response.aggregations && - (response.aggregations?.monitoredHost?.name?.buckets ?? []).length > 0 - ? response.aggregations?.monitoredHost?.name.buckets[0]?.key - : null; + const hasSystemIntegration = await getHasDataFromSystemIntegration({ + infraMetricsClient, + from: timeRange.from, + to: timeRange.to, + query: { + match: { [fields.id]: nodeId }, + }, + }); - const hasSystemIntegration = hostWithSystemIntegration === nodeId; return { hasSystemIntegration, ...res, From ab69314e8ddda5787c72d5e27c569144f7efd599 Mon Sep 17 00:00:00 2001 From: Jenny Date: Fri, 23 Aug 2024 17:33:16 +0200 Subject: [PATCH 8/9] Fix unit test --- .../components/asset_details/tabs/metadata/utils.test.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/x-pack/plugins/observability_solution/infra/public/components/asset_details/tabs/metadata/utils.test.ts b/x-pack/plugins/observability_solution/infra/public/components/asset_details/tabs/metadata/utils.test.ts index 74a53685973b5..b586a0909ce03 100644 --- a/x-pack/plugins/observability_solution/infra/public/components/asset_details/tabs/metadata/utils.test.ts +++ b/x-pack/plugins/observability_solution/infra/public/components/asset_details/tabs/metadata/utils.test.ts @@ -237,6 +237,7 @@ describe('#getAllFields', () => { { name: 'host.architecture', value: 'x86_64' }, { name: 'host.containerized', value: 'false' }, { name: 'host.hostname', value: 'host1' }, + { name: 'host.hasSystemIntegration', value: 'true' }, { name: 'host.ip', value: [ @@ -289,6 +290,7 @@ describe('#getAllFields', () => { { name: 'host.architecture', value: 'x86_64' }, { name: 'host.containerized', value: 'false' }, { name: 'host.hostname', value: 'host1' }, + { name: 'host.hasSystemIntegration', value: 'true' }, { name: 'host.ip', value: [ @@ -373,6 +375,7 @@ describe('#getAllFields', () => { { name: 'host.architecture', value: 'x86_64' }, { name: 'host.containerized', value: 'false' }, { name: 'host.hostname', value: 'host1' }, + { name: 'host.hasSystemIntegration', value: 'true' }, { name: 'host.ip', value: [ From 5a7ac87dec4f57732ccc27bd9b417eca09c24ec2 Mon Sep 17 00:00:00 2001 From: Jenny Date: Fri, 23 Aug 2024 17:38:05 +0200 Subject: [PATCH 9/9] Add check in the integration test --- .../api_integration/test_suites/observability/infra/metadata.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/x-pack/test_serverless/api_integration/test_suites/observability/infra/metadata.ts b/x-pack/test_serverless/api_integration/test_suites/observability/infra/metadata.ts index c38b89b32017d..c50fe1bcb4928 100644 --- a/x-pack/test_serverless/api_integration/test_suites/observability/infra/metadata.ts +++ b/x-pack/test_serverless/api_integration/test_suites/observability/infra/metadata.ts @@ -65,6 +65,7 @@ export default function ({ getService }: FtrProviderContext) { if (metadata) { expect(metadata.features.length).to.be(4); expect(metadata.name).to.equal('serverless-host'); + expect(metadata.hasSystemIntegration).to.equal(true); expect(new Date(metadata.info?.timestamp ?? '')?.getTime()).to.be.above(timeRange.from); expect(new Date(metadata.info?.timestamp ?? '')?.getTime()).to.be.below(timeRange.to); expect(metadata.info?.agent).to.eql({