diff --git a/x-pack/packages/kbn-cloud-security-posture/common/utils/ui_metrics.ts b/x-pack/packages/kbn-cloud-security-posture/common/utils/ui_metrics.ts index 252252b08e976..c7baeb47bc214 100644 --- a/x-pack/packages/kbn-cloud-security-posture/common/utils/ui_metrics.ts +++ b/x-pack/packages/kbn-cloud-security-posture/common/utils/ui_metrics.ts @@ -10,6 +10,15 @@ import type { UsageCollectionSetup } from '@kbn/usage-collection-plugin/public'; export const APP_NAME = 'cloud-security'; +export const MISCONFIGURATION_INSIGHT = 'misconfiguration-insight'; +export const VULNERABILITIES_INSIGHT = 'vulnerabilities-insight'; +export const MISCONFIGURATION_INSIGHT_HOST_DETAILS = `${MISCONFIGURATION_INSIGHT}-host-details`; +export const MISCONFIGURATION_INSIGHT_USER_DETAILS = `${MISCONFIGURATION_INSIGHT}-user-details`; +export const MISCONFIGURATION_INSIGHT_HOST_ENTITY_OVERVIEW = `${MISCONFIGURATION_INSIGHT}-host-entity-overview`; +export const MISCONFIGURATION_INSIGHT_USER_ENTITY_OVERVIEW = `${MISCONFIGURATION_INSIGHT}-user-entity-overview`; +export const VULNERABILITIES_INSIGHT_HOST_DETAILS = `${VULNERABILITIES_INSIGHT}-host-details`; +export const VULNERABILITIES_INSIGHT_HOST_ENTITY_OVERVIEW = `${VULNERABILITIES_INSIGHT}-host-entity-overview`; + export const ENTITY_FLYOUT_WITH_MISCONFIGURATION_VISIT = 'entity-flyout-with-misconfiguration-visits'; export const ENTITY_FLYOUT_WITH_VULNERABILITY_PREVIEW = @@ -41,7 +50,13 @@ type CloudSecurityUiCounters = | typeof CREATE_DETECTION_RULE_FROM_FLYOUT | typeof CREATE_DETECTION_FROM_TABLE_ROW_ACTION | typeof GROUP_BY_CLICK - | typeof CHANGE_RULE_STATE; + | typeof CHANGE_RULE_STATE + | typeof MISCONFIGURATION_INSIGHT_HOST_DETAILS + | typeof MISCONFIGURATION_INSIGHT_USER_DETAILS + | typeof MISCONFIGURATION_INSIGHT_HOST_ENTITY_OVERVIEW + | typeof MISCONFIGURATION_INSIGHT_USER_ENTITY_OVERVIEW + | typeof VULNERABILITIES_INSIGHT_HOST_DETAILS + | typeof VULNERABILITIES_INSIGHT_HOST_ENTITY_OVERVIEW; export class UiMetricService { private usageCollection: UsageCollectionSetup | undefined; diff --git a/x-pack/plugins/cloud_security_posture/public/components/empty_states_illustration_container.tsx b/x-pack/plugins/cloud_security_posture/public/components/empty_states_illustration_container.tsx new file mode 100644 index 0000000000000..3ae4b64b1c848 --- /dev/null +++ b/x-pack/plugins/cloud_security_posture/public/components/empty_states_illustration_container.tsx @@ -0,0 +1,21 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; + +// dimensions of the SVGs used in the empty states illustrations +// e.g. x-pack/plugins/cloud_security_posture/public/assets/illustrations/clouds.svg +const SVG_HEIGHT = 209; +const SVG_WIDTH = 376; + +/** + * A container component that maintains a fixed size for child elements. + * used for displaying the empty state illustrations and prevent flickering while the SVGs are loading. + */ +export const EmptyStatesIllustrationContainer: React.FC<{ children: React.ReactNode }> = ({ + children, +}) =>
{children}
; diff --git a/x-pack/plugins/cloud_security_posture/public/components/no_findings_states/no_findings_states.tsx b/x-pack/plugins/cloud_security_posture/public/components/no_findings_states/no_findings_states.tsx index 5a8db618d5495..a475d35cd6885 100644 --- a/x-pack/plugins/cloud_security_posture/public/components/no_findings_states/no_findings_states.tsx +++ b/x-pack/plugins/cloud_security_posture/public/components/no_findings_states/no_findings_states.tsx @@ -26,6 +26,7 @@ import type { IndexDetails, CspStatusCode } from '@kbn/cloud-security-posture-co import { useCspSetupStatusApi } from '@kbn/cloud-security-posture/src/hooks/use_csp_setup_status_api'; import { useLocation } from 'react-router-dom'; import { findingsNavigation } from '@kbn/cloud-security-posture'; +import { EmptyStatesIllustrationContainer } from '../empty_states_illustration_container'; import { useAdd3PIntegrationRoute } from '../../common/api/use_wiz_integration_route'; import { FullSizeCenteredPage } from '../full_size_centered_page'; import { useCISIntegrationPoliciesLink } from '../../common/navigation/use_navigate_to_cis_integration_policies'; @@ -191,7 +192,11 @@ const EmptySecurityFindingsPrompt = () => { } + icon={ + + + + } title={

{ style={{ padding: euiTheme.size.l }} data-test-subj={THIRD_PARTY_INTEGRATIONS_NO_MISCONFIGURATIONS_FINDINGS_PROMPT} icon={ - + + + } title={

diff --git a/x-pack/plugins/cloud_security_posture/public/components/no_vulnerabilities_states.tsx b/x-pack/plugins/cloud_security_posture/public/components/no_vulnerabilities_states.tsx index 20438aa341ad6..4e6b487f73cbc 100644 --- a/x-pack/plugins/cloud_security_posture/public/components/no_vulnerabilities_states.tsx +++ b/x-pack/plugins/cloud_security_posture/public/components/no_vulnerabilities_states.tsx @@ -25,6 +25,7 @@ import type { IndexDetails } from '@kbn/cloud-security-posture-common'; import { useCspSetupStatusApi } from '@kbn/cloud-security-posture/src/hooks/use_csp_setup_status_api'; import { useLocation } from 'react-router-dom'; import { findingsNavigation } from '@kbn/cloud-security-posture'; +import { EmptyStatesIllustrationContainer } from './empty_states_illustration_container'; import { VULN_MGMT_POLICY_TEMPLATE } from '../../common/constants'; import { FullSizeCenteredPage } from './full_size_centered_page'; import { CloudPosturePage } from './cloud_posture_page'; @@ -84,7 +85,11 @@ const CnvmIntegrationNotInstalledEmptyPrompt = ({ } + icon={ + + + + } title={

+ + + } title={

diff --git a/x-pack/plugins/security_solution/public/flyout/document_details/left/components/host_details.tsx b/x-pack/plugins/security_solution/public/flyout/document_details/left/components/host_details.tsx index 122caa657b039..c04c8e4212c64 100644 --- a/x-pack/plugins/security_solution/public/flyout/document_details/left/components/host_details.tsx +++ b/x-pack/plugins/security_solution/public/flyout/document_details/left/components/host_details.tsx @@ -359,11 +359,13 @@ export const HostDetails: React.FC = ({ hostName, timestamp, s name={hostName} direction="column" data-test-subj={HOST_DETAILS_MISCONFIGURATIONS_TEST_ID} + telemetrySuffix={'host-details'} /> diff --git a/x-pack/plugins/security_solution/public/flyout/document_details/left/components/user_details.tsx b/x-pack/plugins/security_solution/public/flyout/document_details/left/components/user_details.tsx index c90d11f4b8bc2..40e58195bf1e9 100644 --- a/x-pack/plugins/security_solution/public/flyout/document_details/left/components/user_details.tsx +++ b/x-pack/plugins/security_solution/public/flyout/document_details/left/components/user_details.tsx @@ -359,6 +359,7 @@ export const UserDetails: React.FC = ({ userName, timestamp, s name={userName} direction="column" data-test-subj={USER_DETAILS_MISCONFIGURATIONS_TEST_ID} + telemetrySuffix={'user-details'} /> diff --git a/x-pack/plugins/security_solution/public/flyout/document_details/right/components/host_entity_overview.tsx b/x-pack/plugins/security_solution/public/flyout/document_details/right/components/host_entity_overview.tsx index 90405286b004c..9b60eefbb5f61 100644 --- a/x-pack/plugins/security_solution/public/flyout/document_details/right/components/host_entity_overview.tsx +++ b/x-pack/plugins/security_solution/public/flyout/document_details/right/components/host_entity_overview.tsx @@ -285,10 +285,12 @@ export const HostEntityOverview: React.FC = ({ hostName fieldName={'host.name'} name={hostName} data-test-subj={ENTITIES_HOST_OVERVIEW_MISCONFIGURATIONS_TEST_ID} + telemetrySuffix={'host-entity-overview'} /> ); diff --git a/x-pack/plugins/security_solution/public/flyout/document_details/right/components/user_entity_overview.tsx b/x-pack/plugins/security_solution/public/flyout/document_details/right/components/user_entity_overview.tsx index 0019228d656cd..1008f6139cd67 100644 --- a/x-pack/plugins/security_solution/public/flyout/document_details/right/components/user_entity_overview.tsx +++ b/x-pack/plugins/security_solution/public/flyout/document_details/right/components/user_entity_overview.tsx @@ -283,6 +283,7 @@ export const UserEntityOverview: React.FC = ({ userName fieldName={'user.name'} name={userName} data-test-subj={ENTITIES_USER_OVERVIEW_MISCONFIGURATIONS_TEST_ID} + telemetrySuffix={'user-entity-overview'} /> ); diff --git a/x-pack/plugins/security_solution/public/flyout/document_details/shared/components/misconfiguration_insight.tsx b/x-pack/plugins/security_solution/public/flyout/document_details/shared/components/misconfiguration_insight.tsx index 961fa1d5f3a45..e7ebb371fb020 100644 --- a/x-pack/plugins/security_solution/public/flyout/document_details/shared/components/misconfiguration_insight.tsx +++ b/x-pack/plugins/security_solution/public/flyout/document_details/shared/components/misconfiguration_insight.tsx @@ -5,12 +5,17 @@ * 2.0. */ -import React, { useMemo } from 'react'; +import React, { useEffect, useMemo } from 'react'; import { EuiFlexItem, type EuiFlexGroupProps, useEuiTheme } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n-react'; import { css } from '@emotion/css'; import { useMisconfigurationPreview } from '@kbn/cloud-security-posture/src/hooks/use_misconfiguration_preview'; import { buildEntityFlyoutPreviewQuery } from '@kbn/cloud-security-posture-common'; +import { + MISCONFIGURATION_INSIGHT, + uiMetricService, +} from '@kbn/cloud-security-posture-common/utils/ui_metrics'; +import { METRIC_TYPE } from '@kbn/analytics'; import { InsightDistributionBar } from './insight_distribution_bar'; import { getFindingsStats } from '../../../../cloud_security_posture/components/misconfiguration/misconfiguration_preview'; import { FormattedCount } from '../../../../common/components/formatted_number'; @@ -34,6 +39,10 @@ interface MisconfigurationsInsightProps { * The data-test-subj to use for the component */ ['data-test-subj']?: string; + /** + * used to track the instance of this component, prefer kebab-case + */ + telemetrySuffix?: string; } /* @@ -44,6 +53,7 @@ export const MisconfigurationsInsight: React.FC = fieldName, direction, 'data-test-subj': dataTestSubj, + telemetrySuffix, }) => { const { scopeId, isPreview } = useDocumentDetailsContext(); const { euiTheme } = useEuiTheme(); @@ -54,6 +64,14 @@ export const MisconfigurationsInsight: React.FC = pageSize: 1, }); + useEffect(() => { + uiMetricService.trackUiMetric( + METRIC_TYPE.COUNT, + `${MISCONFIGURATION_INSIGHT}-${telemetrySuffix}` + ); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []); + const passedFindings = data?.count.passed || 0; const failedFindings = data?.count.failed || 0; const totalFindings = useMemo( diff --git a/x-pack/plugins/security_solution/public/flyout/document_details/shared/components/vulnerabilities_insight.tsx b/x-pack/plugins/security_solution/public/flyout/document_details/shared/components/vulnerabilities_insight.tsx index c675c0a0e079b..1dab4660194b9 100644 --- a/x-pack/plugins/security_solution/public/flyout/document_details/shared/components/vulnerabilities_insight.tsx +++ b/x-pack/plugins/security_solution/public/flyout/document_details/shared/components/vulnerabilities_insight.tsx @@ -5,13 +5,18 @@ * 2.0. */ -import React, { useMemo } from 'react'; +import React, { useEffect, useMemo } from 'react'; import { EuiFlexItem, type EuiFlexGroupProps, useEuiTheme } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n-react'; import { css } from '@emotion/css'; import { useVulnerabilitiesPreview } from '@kbn/cloud-security-posture/src/hooks/use_vulnerabilities_preview'; import { buildEntityFlyoutPreviewQuery } from '@kbn/cloud-security-posture-common'; import { getVulnerabilityStats, hasVulnerabilitiesData } from '@kbn/cloud-security-posture'; +import { + uiMetricService, + VULNERABILITIES_INSIGHT, +} from '@kbn/cloud-security-posture-common/utils/ui_metrics'; +import { METRIC_TYPE } from '@kbn/analytics'; import { InsightDistributionBar } from './insight_distribution_bar'; import { FormattedCount } from '../../../../common/components/formatted_number'; import { PreviewLink } from '../../../shared/components/preview_link'; @@ -30,6 +35,10 @@ interface VulnerabilitiesInsightProps { * The data-test-subj to use for the component */ ['data-test-subj']?: string; + /** + * used to track the instance of this component, prefer kebab-case + */ + telemetrySuffix?: string; } /* @@ -39,6 +48,7 @@ export const VulnerabilitiesInsight: React.FC = ({ hostName, direction, 'data-test-subj': dataTestSubj, + telemetrySuffix, }) => { const { scopeId, isPreview } = useDocumentDetailsContext(); const { euiTheme } = useEuiTheme(); @@ -49,6 +59,14 @@ export const VulnerabilitiesInsight: React.FC = ({ pageSize: 1, }); + useEffect(() => { + uiMetricService.trackUiMetric( + METRIC_TYPE.COUNT, + `${VULNERABILITIES_INSIGHT}-${telemetrySuffix}` + ); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []); + const { CRITICAL = 0, HIGH = 0, MEDIUM = 0, LOW = 0, NONE = 0 } = data?.count || {}; const totalVulnerabilities = useMemo( () => CRITICAL + HIGH + MEDIUM + LOW + NONE,