diff --git a/x-pack/plugins/observability_solution/infra/public/components/asset_details/tabs/overview/alerts/alerts.tsx b/x-pack/plugins/observability_solution/infra/public/components/asset_details/tabs/overview/alerts/alerts.tsx index dc4d78baeb5a1..304e67a0debde 100644 --- a/x-pack/plugins/observability_solution/infra/public/components/asset_details/tabs/overview/alerts/alerts.tsx +++ b/x-pack/plugins/observability_solution/infra/public/components/asset_details/tabs/overview/alerts/alerts.tsx @@ -75,7 +75,7 @@ export const AlertsSummaryContent = ({ )} diff --git a/x-pack/plugins/observability_solution/infra/public/pages/metrics/hosts/components/tabs/alerts/alerts_tab_content.tsx b/x-pack/plugins/observability_solution/infra/public/pages/metrics/hosts/components/tabs/alerts/alerts_tab_content.tsx index 7b0ec7ed2d2f1..34726a68ab2dd 100644 --- a/x-pack/plugins/observability_solution/infra/public/pages/metrics/hosts/components/tabs/alerts/alerts_tab_content.tsx +++ b/x-pack/plugins/observability_solution/infra/public/pages/metrics/hosts/components/tabs/alerts/alerts_tab_content.tsx @@ -6,11 +6,7 @@ */ import React from 'react'; import { EuiFlexGroup, EuiFlexItem } from '@elastic/eui'; -import { - AlertConsumers, - INFRA_RULE_TYPE_IDS, - OBSERVABILITY_RULE_TYPE_IDS, -} from '@kbn/rule-data-utils'; +import { AlertConsumers, OBSERVABILITY_RULE_TYPE_IDS } from '@kbn/rule-data-utils'; import { BrushEndListener, type XYBrushEvent } from '@elastic/charts'; import { useSummaryTimeRange } from '@kbn/observability-plugin/public'; import { useBoolean } from '@kbn/react-hooks'; @@ -47,11 +43,7 @@ export const AlertsTabContent = () => { const { alertsTableConfigurationRegistry, getAlertsStateTable: AlertsStateTable } = triggersActionsUi; - - const hostsWithAlertsKuery = hostNodes - .filter((host) => host.alertsCount) - .map((host) => `"${host.name}"`) - .join(' OR '); + const hostNamesKuery = hostNodes.map((host) => `host.name: "${host.name}"`).join(' OR '); return ( @@ -73,7 +65,7 @@ export const AlertsTabContent = () => { @@ -146,7 +138,7 @@ const MemoAlertSummaryWidget = React.memo( return ( { const { alertsEsQuery } = useAlertsQuery(); const { alertsCount, loading, error } = useAlertsCount({ - ruleTypeIds: INFRA_RULE_TYPE_IDS, + ruleTypeIds: OBSERVABILITY_RULE_TYPE_IDS, consumers: INFRA_ALERT_CONSUMERS, query: alertsEsQuery, }); diff --git a/x-pack/plugins/observability_solution/inventory/public/components/alerts_badge/alerts_badge.test.tsx b/x-pack/plugins/observability_solution/inventory/public/components/alerts_badge/alerts_badge.test.tsx index 1892dd0109490..0957fa4da8aea 100644 --- a/x-pack/plugins/observability_solution/inventory/public/components/alerts_badge/alerts_badge.test.tsx +++ b/x-pack/plugins/observability_solution/inventory/public/components/alerts_badge/alerts_badge.test.tsx @@ -15,10 +15,12 @@ const useKibanaMock = useKibana as jest.Mock; const commonEntityFields: Partial = { entityLastSeenTimestamp: 'foo', - entityId: 'entity1', + entityId: '1', }; describe('AlertsBadge', () => { + const mockAsKqlFilter = jest.fn(); + beforeEach(() => { jest.clearAllMocks(); @@ -29,6 +31,11 @@ describe('AlertsBadge', () => { prepend: (path: string) => path, }, }, + entityManager: { + entityClient: { + asKqlFilter: mockAsKqlFilter, + }, + }, }, }); }); @@ -52,10 +59,11 @@ describe('AlertsBadge', () => { provider: null, }, }; + mockAsKqlFilter.mockReturnValue('host.name: "foo"'); render(); expect(screen.queryByTestId('inventoryAlertsBadgeLink')?.getAttribute('href')).toEqual( - `/app/observability/alerts?_a=(kuery:\"entity1\",status:active)` + `/app/observability/alerts?_a=(kuery:'host.name: "foo"',status:active)` ); expect(screen.queryByTestId('inventoryAlertsBadgeLink')?.textContent).toEqual('1'); }); @@ -78,11 +86,40 @@ describe('AlertsBadge', () => { alertsCount: 5, }; + mockAsKqlFilter.mockReturnValue('service.name: "bar"'); render(); expect(screen.queryByTestId('inventoryAlertsBadgeLink')?.getAttribute('href')).toEqual( - `/app/observability/alerts?_a=(kuery:\"entity1\",status:active)` + `/app/observability/alerts?_a=(kuery:'service.name: "bar"',status:active)` ); expect(screen.queryByTestId('inventoryAlertsBadgeLink')?.textContent).toEqual('5'); }); + it('render alerts badge for a service entity with multiple identity fields', () => { + const entity: InventoryEntity = { + ...(commonEntityFields as InventoryEntity), + entityType: 'service', + entityDisplayName: 'foo', + entityIdentityFields: ['service.name', 'service.environment'], + entityDefinitionId: 'service', + service: { + name: 'bar', + environment: 'prod', + }, + agent: { + name: 'node', + }, + cloud: { + provider: null, + }, + alertsCount: 2, + }; + + mockAsKqlFilter.mockReturnValue('service.name: "bar" AND service.environment: "prod"'); + + render(); + expect(screen.queryByTestId('inventoryAlertsBadgeLink')?.getAttribute('href')).toEqual( + `/app/observability/alerts?_a=(kuery:'service.name: "bar" AND service.environment: "prod"',status:active)` + ); + expect(screen.queryByTestId('inventoryAlertsBadgeLink')?.textContent).toEqual('2'); + }); }); diff --git a/x-pack/plugins/observability_solution/inventory/public/components/alerts_badge/alerts_badge.tsx b/x-pack/plugins/observability_solution/inventory/public/components/alerts_badge/alerts_badge.tsx index 228cd3d8bbfd8..301dcb63d1a17 100644 --- a/x-pack/plugins/observability_solution/inventory/public/components/alerts_badge/alerts_badge.tsx +++ b/x-pack/plugins/observability_solution/inventory/public/components/alerts_badge/alerts_badge.tsx @@ -15,12 +15,18 @@ export function AlertsBadge({ entity }: { entity: InventoryEntity }) { const { services: { http: { basePath }, + entityManager, }, } = useKibana(); const activeAlertsHref = basePath.prepend( `/app/observability/alerts?_a=${rison.encode({ - kuery: `"${entity.entityId}"`, + kuery: entityManager.entityClient.asKqlFilter({ + entity: { + identity_fields: entity.entityIdentityFields, + }, + ...entity, + }), status: 'active', })}` );