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,