From 138658aaf733bc7b2d610ebee620bcca8a3bf28e Mon Sep 17 00:00:00 2001 From: Carlos Crespo Date: Wed, 6 Sep 2023 13:04:20 +0200 Subject: [PATCH] Make infra plugin optional in APM server; Hide links to Infra in the UI --- .../instance_actions_menu/index.tsx | 7 +- .../instance_actions_menu/menu_sections.ts | 122 ++++----- .../transaction_action_menu/sections.ts | 247 ++++++++++-------- .../transaction_action_menu.tsx | 8 +- .../lib/helpers/get_infra_metric_indices.ts | 3 + .../apm/server/routes/infrastructure/route.ts | 6 +- .../apm/server/routes/services/route.ts | 11 +- x-pack/plugins/apm/server/types.ts | 2 +- x-pack/plugins/ux/kibana.jsonc | 1 - 9 files changed, 215 insertions(+), 192 deletions(-) diff --git a/x-pack/plugins/apm/public/components/app/service_overview/service_overview_instances_table/instance_actions_menu/index.tsx b/x-pack/plugins/apm/public/components/app/service_overview/service_overview_instances_table/instance_actions_menu/index.tsx index 4b2f8bb39579e..d2e8034cab32f 100644 --- a/x-pack/plugins/apm/public/components/app/service_overview/service_overview_instances_table/instance_actions_menu/index.tsx +++ b/x-pack/plugins/apm/public/components/app/service_overview/service_overview_instances_table/instance_actions_menu/index.tsx @@ -40,10 +40,7 @@ export function InstanceActionsMenu({ kuery, onClose, }: Props) { - const { - core, - infra: { locators }, - } = useApmPluginContext(); + const { core, infra } = useApmPluginContext(); const { data, status } = useInstanceDetailsFetcher({ serviceName, serviceNodeName, @@ -92,7 +89,7 @@ export function InstanceActionsMenu({ basePath: core.http.basePath, onFilterByInstanceClick: handleFilterByInstanceClick, metricsHref, - infraLocators: locators, + infraLocators: infra?.locators, }); return ( diff --git a/x-pack/plugins/apm/public/components/app/service_overview/service_overview_instances_table/instance_actions_menu/menu_sections.ts b/x-pack/plugins/apm/public/components/app/service_overview/service_overview_instances_table/instance_actions_menu/menu_sections.ts index e3398258b5fed..284e3ca6d4964 100644 --- a/x-pack/plugins/apm/public/components/app/service_overview/service_overview_instances_table/instance_actions_menu/menu_sections.ts +++ b/x-pack/plugins/apm/public/components/app/service_overview/service_overview_instances_table/instance_actions_menu/menu_sections.ts @@ -52,67 +52,71 @@ export function getMenuSections({ ? new Date(instanceDetails['@timestamp']).valueOf() : undefined; const infraMetricsQuery = getInfraMetricsQuery(instanceDetails['@timestamp']); - const infraNodeLocator = infraLocators.nodeLogsLocator; + const infraNodeLocator = infraLocators?.nodeLogsLocator; - const podActions: Action[] = [ - { - key: 'podLogs', - label: i18n.translate( - 'xpack.apm.serviceOverview.instancesTable.actionMenus.podLogs', - { defaultMessage: 'Pod logs' } - ), - href: infraNodeLocator.getRedirectUrl({ - nodeId: podId!, - nodeType: 'pod', - time, - }), - condition: !!podId, - }, - { - key: 'podMetrics', - label: i18n.translate( - 'xpack.apm.serviceOverview.instancesTable.actionMenus.podMetrics', - { defaultMessage: 'Pod metrics' } - ), - href: getInfraHref({ - app: 'metrics', - basePath, - path: `/link-to/pod-detail/${podId}`, - query: infraMetricsQuery, - }), - condition: !!podId, - }, - ]; + const podActions: Action[] = infraNodeLocator + ? [ + { + key: 'podLogs', + label: i18n.translate( + 'xpack.apm.serviceOverview.instancesTable.actionMenus.podLogs', + { defaultMessage: 'Pod logs' } + ), + href: infraNodeLocator?.getRedirectUrl({ + nodeId: podId!, + nodeType: 'pod', + time, + }), + condition: !!podId, + }, + { + key: 'podMetrics', + label: i18n.translate( + 'xpack.apm.serviceOverview.instancesTable.actionMenus.podMetrics', + { defaultMessage: 'Pod metrics' } + ), + href: getInfraHref({ + app: 'metrics', + basePath, + path: `/link-to/pod-detail/${podId}`, + query: infraMetricsQuery, + }), + condition: !!podId, + }, + ] + : []; - const containerActions: Action[] = [ - { - key: 'containerLogs', - label: i18n.translate( - 'xpack.apm.serviceOverview.instancesTable.actionMenus.containerLogs', - { defaultMessage: 'Container logs' } - ), - href: infraNodeLocator.getRedirectUrl({ - nodeId: containerId!, - nodeType: 'container', - time, - }), - condition: !!containerId, - }, - { - key: 'containerMetrics', - label: i18n.translate( - 'xpack.apm.serviceOverview.instancesTable.actionMenus.containerMetrics', - { defaultMessage: 'Container metrics' } - ), - href: getInfraHref({ - app: 'metrics', - basePath, - path: `/link-to/container-detail/${containerId}`, - query: infraMetricsQuery, - }), - condition: !!containerId, - }, - ]; + const containerActions: Action[] = infraNodeLocator + ? [ + { + key: 'containerLogs', + label: i18n.translate( + 'xpack.apm.serviceOverview.instancesTable.actionMenus.containerLogs', + { defaultMessage: 'Container logs' } + ), + href: infraNodeLocator?.getRedirectUrl({ + nodeId: containerId!, + nodeType: 'container', + time, + }), + condition: !!containerId, + }, + { + key: 'containerMetrics', + label: i18n.translate( + 'xpack.apm.serviceOverview.instancesTable.actionMenus.containerMetrics', + { defaultMessage: 'Container metrics' } + ), + href: getInfraHref({ + app: 'metrics', + basePath, + path: `/link-to/container-detail/${containerId}`, + query: infraMetricsQuery, + }), + condition: !!containerId, + }, + ] + : []; const apmActions: Action[] = [ { diff --git a/x-pack/plugins/apm/public/components/shared/transaction_action_menu/sections.ts b/x-pack/plugins/apm/public/components/shared/transaction_action_menu/sections.ts index 9b50bdd350a3f..8f230ba94abe8 100644 --- a/x-pack/plugins/apm/public/components/shared/transaction_action_menu/sections.ts +++ b/x-pack/plugins/apm/public/components/shared/transaction_action_menu/sections.ts @@ -49,7 +49,7 @@ export const getSections = ({ basePath: IBasePath; location: Location; apmRouter: ApmRouter; - infraLocators: InfraLocators; + infraLocators?: InfraLocators; infraLinksAvailable: boolean; profilingLocators?: ProfilingLocators; rangeFrom: string; @@ -60,7 +60,7 @@ export const getSections = ({ const hostName = transaction.host?.hostname; const podId = transaction.kubernetes?.pod?.uid; const containerId = transaction.container?.id; - const { nodeLogsLocator, logsLocator } = infraLocators; + const { nodeLogsLocator, logsLocator } = infraLocators ?? {}; const time = Math.round(transaction.timestamp.us / 1000); const infraMetricsQuery = getInfraMetricsQuery(transaction); @@ -79,94 +79,102 @@ export const getSections = ({ )}`, }); - const podActions: Action[] = [ - { - key: 'podLogs', - label: i18n.translate( - 'xpack.apm.transactionActionMenu.showPodLogsLinkLabel', - { defaultMessage: 'Pod logs' } - ), - href: nodeLogsLocator.getRedirectUrl({ - nodeId: podId!, - nodeType: 'pod', - time, - }), - condition: !!podId, - }, - { - key: 'podMetrics', - label: i18n.translate( - 'xpack.apm.transactionActionMenu.showPodMetricsLinkLabel', - { defaultMessage: 'Pod metrics' } - ), - href: getInfraHref({ - app: 'metrics', - basePath, - path: `/link-to/pod-detail/${podId}`, - query: infraMetricsQuery, - }), - condition: !!podId, - }, - ]; + const podActions: Action[] = nodeLogsLocator + ? [ + { + key: 'podLogs', + label: i18n.translate( + 'xpack.apm.transactionActionMenu.showPodLogsLinkLabel', + { defaultMessage: 'Pod logs' } + ), + href: nodeLogsLocator.getRedirectUrl({ + nodeId: podId!, + nodeType: 'pod', + time, + }), + condition: !!podId, + }, + { + key: 'podMetrics', + label: i18n.translate( + 'xpack.apm.transactionActionMenu.showPodMetricsLinkLabel', + { defaultMessage: 'Pod metrics' } + ), + href: getInfraHref({ + app: 'metrics', + basePath, + path: `/link-to/pod-detail/${podId}`, + query: infraMetricsQuery, + }), + condition: !!podId, + }, + ] + : []; - const containerActions: Action[] = [ - { - key: 'containerLogs', - label: i18n.translate( - 'xpack.apm.transactionActionMenu.showContainerLogsLinkLabel', - { defaultMessage: 'Container logs' } - ), - href: nodeLogsLocator.getRedirectUrl({ - nodeId: containerId!, - nodeType: 'container', - time, - }), - condition: !!containerId, - }, - { - key: 'containerMetrics', - label: i18n.translate( - 'xpack.apm.transactionActionMenu.showContainerMetricsLinkLabel', - { defaultMessage: 'Container metrics' } - ), - href: getInfraHref({ - app: 'metrics', - basePath, - path: `/link-to/container-detail/${containerId}`, - query: infraMetricsQuery, - }), - condition: !!containerId, - }, - ]; + const containerActions: Action[] = nodeLogsLocator + ? [ + { + key: 'containerLogs', + label: i18n.translate( + 'xpack.apm.transactionActionMenu.showContainerLogsLinkLabel', + { defaultMessage: 'Container logs' } + ), + href: nodeLogsLocator.getRedirectUrl({ + nodeId: containerId!, + nodeType: 'container', + time, + }), + condition: !!containerId, + }, + { + key: 'containerMetrics', + label: i18n.translate( + 'xpack.apm.transactionActionMenu.showContainerMetricsLinkLabel', + { defaultMessage: 'Container metrics' } + ), + href: getInfraHref({ + app: 'metrics', + basePath, + path: `/link-to/container-detail/${containerId}`, + query: infraMetricsQuery, + }), + condition: !!containerId, + }, + ] + : []; const hostActions: Action[] = [ - { - key: 'hostLogs', - label: i18n.translate( - 'xpack.apm.transactionActionMenu.showHostLogsLinkLabel', - { defaultMessage: 'Host logs' } - ), - href: nodeLogsLocator.getRedirectUrl({ - nodeId: hostName!, - nodeType: 'host', - time, - }), - condition: !!hostName, - }, - { - key: 'hostMetrics', - label: i18n.translate( - 'xpack.apm.transactionActionMenu.showHostMetricsLinkLabel', - { defaultMessage: 'Host metrics' } - ), - href: getInfraHref({ - app: 'metrics', - basePath, - path: `/link-to/host-detail/${hostName}`, - query: infraMetricsQuery, - }), - condition: !!hostName, - }, + ...(nodeLogsLocator + ? [ + { + key: 'hostLogs', + label: i18n.translate( + 'xpack.apm.transactionActionMenu.showHostLogsLinkLabel', + { defaultMessage: 'Host logs' } + ), + href: nodeLogsLocator.getRedirectUrl({ + nodeId: hostName!, + nodeType: 'host', + time, + }), + condition: !!hostName, + }, + { + key: 'hostMetrics', + label: i18n.translate( + 'xpack.apm.transactionActionMenu.showHostMetricsLinkLabel', + { defaultMessage: 'Host metrics' } + ), + href: getInfraHref({ + app: 'metrics', + basePath, + path: `/link-to/host-detail/${hostName}`, + query: infraMetricsQuery, + }), + condition: !!hostName, + }, + ] + : []), { key: 'hostProfilingFlamegraph', label: i18n.translate( @@ -205,20 +213,22 @@ export const getSections = ({ }, ]; - const logActions: Action[] = [ - { - key: 'traceLogs', - label: i18n.translate( - 'xpack.apm.transactionActionMenu.showTraceLogsLinkLabel', - { defaultMessage: 'Trace logs' } - ), - href: logsLocator.getRedirectUrl({ - filter: `trace.id:"${transaction.trace.id}" OR (not trace.id:* AND "${transaction.trace.id}")`, - time, - }), - condition: true, - }, - ]; + const logActions: Action[] = logsLocator + ? [ + { + key: 'traceLogs', + label: i18n.translate( + 'xpack.apm.transactionActionMenu.showTraceLogsLinkLabel', + { defaultMessage: 'Trace logs' } + ), + href: logsLocator.getRedirectUrl({ + filter: `trace.id:"${transaction.trace.id}" OR (not trace.id:* AND "${transaction.trace.id}")`, + time, + }), + condition: true, + }, + ] + : []; const uptimeActions: Action[] = [ { @@ -273,7 +283,7 @@ export const getSections = ({ const sectionRecord: SectionRecord = { observability: [ - ...(infraLinksAvailable + ...(infraLinksAvailable && infraLocators ? [ { key: 'podDetails', @@ -329,19 +339,26 @@ export const getSections = ({ ] : []), - { - key: 'traceDetails', - title: i18n.translate('xpack.apm.transactionActionMenu.trace.title', { - defaultMessage: 'Trace details', - }), - subtitle: i18n.translate( - 'xpack.apm.transactionActionMenu.trace.subtitle', - { - defaultMessage: 'View trace logs to get further details.', - } - ), - actions: logActions, - }, + ...(infraLocators + ? [ + { + key: 'traceDetails', + title: i18n.translate( + 'xpack.apm.transactionActionMenu.trace.title', + { + defaultMessage: 'Trace details', + } + ), + subtitle: i18n.translate( + 'xpack.apm.transactionActionMenu.trace.subtitle', + { + defaultMessage: 'View trace logs to get further details.', + } + ), + actions: logActions, + }, + ] + : []), { key: 'statusDetails', title: i18n.translate('xpack.apm.transactionActionMenu.status.title', { diff --git a/x-pack/plugins/apm/public/components/shared/transaction_action_menu/transaction_action_menu.tsx b/x-pack/plugins/apm/public/components/shared/transaction_action_menu/transaction_action_menu.tsx index e888cec54f11a..14cae53ba28cf 100644 --- a/x-pack/plugins/apm/public/components/shared/transaction_action_menu/transaction_action_menu.tsx +++ b/x-pack/plugins/apm/public/components/shared/transaction_action_menu/transaction_action_menu.tsx @@ -125,11 +125,7 @@ function ActionMenuSections({ transaction?: Transaction; profilingLocators?: ProfilingLocators; }) { - const { - core, - uiActions, - infra: { locators }, - } = useApmPluginContext(); + const { core, uiActions, infra } = useApmPluginContext(); const location = useLocation(); const apmRouter = useApmRouter(); @@ -151,7 +147,7 @@ function ActionMenuSections({ basePath: core.http.basePath, location, apmRouter, - infraLocators: locators, + infraLocators: infra?.locators, infraLinksAvailable, profilingLocators, rangeFrom, diff --git a/x-pack/plugins/apm/server/lib/helpers/get_infra_metric_indices.ts b/x-pack/plugins/apm/server/lib/helpers/get_infra_metric_indices.ts index aec76a75fb944..24b76edb4d887 100644 --- a/x-pack/plugins/apm/server/lib/helpers/get_infra_metric_indices.ts +++ b/x-pack/plugins/apm/server/lib/helpers/get_infra_metric_indices.ts @@ -15,6 +15,9 @@ export async function getInfraMetricIndices({ infraPlugin: Required; savedObjectsClient: SavedObjectsClientContract; }): Promise { + if (!infraPlugin) { + throw new Error('Infra Plugin needs to be setup'); + } const infra = await infraPlugin.start(); const infraMetricIndices = await infra.getMetricIndices(savedObjectsClient); diff --git a/x-pack/plugins/apm/server/routes/infrastructure/route.ts b/x-pack/plugins/apm/server/routes/infrastructure/route.ts index 151ed589396ce..4117a43ce1e3f 100644 --- a/x-pack/plugins/apm/server/routes/infrastructure/route.ts +++ b/x-pack/plugins/apm/server/routes/infrastructure/route.ts @@ -5,6 +5,7 @@ * 2.0. */ import * as t from 'io-ts'; +import Boom from '@hapi/boom'; import { createApmServerRoute } from '../apm_routes/create_apm_server_route'; import { getApmEventClient } from '../../lib/helpers/get_apm_event_client'; import { environmentRt, kueryRt, rangeRt } from '../default_api_types'; @@ -29,9 +30,12 @@ const infrastructureRoute = createApmServerRoute({ hostNames: string[]; podNames: string[]; }> => { + if (!resources.plugins.infra) { + throw Boom.notFound(); + } + const apmEventClient = await getApmEventClient(resources); const infraMetricsClient = createInfraMetricsClient(resources); - const { params } = resources; const { diff --git a/x-pack/plugins/apm/server/routes/services/route.ts b/x-pack/plugins/apm/server/routes/services/route.ts index e13c7564a3fff..4ac0a37b3d10d 100644 --- a/x-pack/plugins/apm/server/routes/services/route.ts +++ b/x-pack/plugins/apm/server/routes/services/route.ts @@ -239,7 +239,6 @@ const serviceMetadataDetailsRoute = createApmServerRoute({ options: { tags: ['access:apm'] }, handler: async (resources): Promise => { const apmEventClient = await getApmEventClient(resources); - const infraMetricsClient = createInfraMetricsClient(resources); const { params } = resources; const { serviceName } = params.path; const { start, end } = params.query; @@ -251,7 +250,8 @@ const serviceMetadataDetailsRoute = createApmServerRoute({ end, }); - if (serviceMetadataDetails?.container?.ids) { + if (serviceMetadataDetails?.container?.ids && resources.plugins.infra) { + const infraMetricsClient = createInfraMetricsClient(resources); const containerMetadata = await getServiceOverviewContainerMetadata({ infraMetricsClient, containerIds: serviceMetadataDetails.container.ids, @@ -748,7 +748,6 @@ export const serviceInstancesMetadataDetails = createApmServerRoute({ (ServiceInstanceContainerMetadataDetails | {}) > => { const apmEventClient = await getApmEventClient(resources); - const infraMetricsClient = createInfraMetricsClient(resources); const { params } = resources; const { serviceName, serviceNodeName } = params.path; const { start, end } = params.query; @@ -762,7 +761,11 @@ export const serviceInstancesMetadataDetails = createApmServerRoute({ end, }); - if (serviceInstanceMetadataDetails?.container?.id) { + if ( + serviceInstanceMetadataDetails?.container?.id && + resources.plugins.infra + ) { + const infraMetricsClient = createInfraMetricsClient(resources); const containerMetadata = await getServiceInstanceContainerMetadata({ infraMetricsClient, containerId: serviceInstanceMetadataDetails.container.id, diff --git a/x-pack/plugins/apm/server/types.ts b/x-pack/plugins/apm/server/types.ts index 054861a082b44..ec3fb5b80e130 100644 --- a/x-pack/plugins/apm/server/types.ts +++ b/x-pack/plugins/apm/server/types.ts @@ -75,7 +75,7 @@ export interface APMPluginSetupDependencies { licensing: LicensingPluginSetup; observability: ObservabilityPluginSetup; ruleRegistry: RuleRegistryPluginSetupContract; - infra: InfraPluginSetup; + infra?: InfraPluginSetup; dataViews: {}; share: SharePluginSetup; diff --git a/x-pack/plugins/ux/kibana.jsonc b/x-pack/plugins/ux/kibana.jsonc index 26a2ab78a926a..22d912cbe4ab3 100644 --- a/x-pack/plugins/ux/kibana.jsonc +++ b/x-pack/plugins/ux/kibana.jsonc @@ -17,7 +17,6 @@ "observabilityShared", "observabilityAIAssistant", "embeddable", - "infra", "inspector", "apm" ],