mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 09:19:04 -04:00
# Backport This will backport the following commits from `main` to `8.x`: - [[Cloud Security] Collecting telemetry of graph visualization usage (#207154)](https://github.com/elastic/kibana/pull/207154) <!--- Backport version: 9.4.3 --> ### Questions ? Please refer to the [Backport tool documentation](https://github.com/sqren/backport) <!--BACKPORT [{"author":{"name":"Kfir Peled","email":"61654899+kfirpeled@users.noreply.github.com"},"sourceCommit":{"committedDate":"2025-01-29T17:31:20Z","message":"[Cloud Security] Collecting telemetry of graph visualization usage (#207154)\n\n## Summary\r\n\r\nCollects two events of graph visualization usage\r\n\r\n1. When graph preview is shown - allows to determine how many users\r\ningested data that is graph compliant\r\n2. When graph investigation component is visible - allows to determine\r\nhow many users entered the investigation user flow\r\n\r\n**How to test:**\r\n\r\n- Enable the feature flag \r\n\r\n`kibana.dev.yml`:\r\n\r\n```yaml\r\nuiSettings.overrides.securitySolution:enableVisualizationsInFlyout: true\r\nuiSettings.overrides.securitySolution:enableGraphVisualization: true\r\n```\r\n\r\n- Load mocked data:\r\n\r\n```bash\r\nnode scripts/es_archiver load x-pack/test/cloud_security_posture_functional/es_archives/logs_gcp_audit \\ \r\n --es-url http://elastic:changeme@localhost:9200 \\\r\n --kibana-url http://elastic:changeme@localhost:5601\r\n\r\nnode scripts/es_archiver load x-pack/test/cloud_security_posture_functional/es_archives/security_alerts \\\r\n --es-url http://elastic:changeme@localhost:9200 \\\r\n --kibana-url http://elastic:changeme@localhost:5601\r\n```\r\n\r\n- Make sure you include data from Oct 13 2024. (in the video I use Last\r\nyear)\r\n- Run in dev tools:\r\n```\r\nPOST kbn:/internal/telemetry/clusters/_stats?pretty=true&apiVersion=2\r\n{\r\n \"unencrypted\": true,\r\n \"refreshCache\": true\r\n}\r\n```\r\n- Check if the ui_counters were reported\r\n\r\n","sha":"7ac553ce89e987cb08128afff4f9fdcefc48e0c1","branchLabelMapping":{"^v9.0.0$":"main","^v8.18.0$":"8.x","^v(\\d+).(\\d+).\\d+$":"$1.$2"}},"sourcePullRequest":{"labels":["release_note:skip","v9.0.0","Team:Cloud Security","backport:prev-minor"],"title":"[Cloud Security] Collecting telemetry of graph visualization usage","number":207154,"url":"https://github.com/elastic/kibana/pull/207154","mergeCommit":{"message":"[Cloud Security] Collecting telemetry of graph visualization usage (#207154)\n\n## Summary\r\n\r\nCollects two events of graph visualization usage\r\n\r\n1. When graph preview is shown - allows to determine how many users\r\ningested data that is graph compliant\r\n2. When graph investigation component is visible - allows to determine\r\nhow many users entered the investigation user flow\r\n\r\n**How to test:**\r\n\r\n- Enable the feature flag \r\n\r\n`kibana.dev.yml`:\r\n\r\n```yaml\r\nuiSettings.overrides.securitySolution:enableVisualizationsInFlyout: true\r\nuiSettings.overrides.securitySolution:enableGraphVisualization: true\r\n```\r\n\r\n- Load mocked data:\r\n\r\n```bash\r\nnode scripts/es_archiver load x-pack/test/cloud_security_posture_functional/es_archives/logs_gcp_audit \\ \r\n --es-url http://elastic:changeme@localhost:9200 \\\r\n --kibana-url http://elastic:changeme@localhost:5601\r\n\r\nnode scripts/es_archiver load x-pack/test/cloud_security_posture_functional/es_archives/security_alerts \\\r\n --es-url http://elastic:changeme@localhost:9200 \\\r\n --kibana-url http://elastic:changeme@localhost:5601\r\n```\r\n\r\n- Make sure you include data from Oct 13 2024. (in the video I use Last\r\nyear)\r\n- Run in dev tools:\r\n```\r\nPOST kbn:/internal/telemetry/clusters/_stats?pretty=true&apiVersion=2\r\n{\r\n \"unencrypted\": true,\r\n \"refreshCache\": true\r\n}\r\n```\r\n- Check if the ui_counters were reported\r\n\r\n","sha":"7ac553ce89e987cb08128afff4f9fdcefc48e0c1"}},"sourceBranch":"main","suggestedTargetBranches":[],"targetPullRequestStates":[{"branch":"main","label":"v9.0.0","branchLabelMappingKey":"^v9.0.0$","isSourceBranch":true,"state":"MERGED","url":"https://github.com/elastic/kibana/pull/207154","number":207154,"mergeCommit":{"message":"[Cloud Security] Collecting telemetry of graph visualization usage (#207154)\n\n## Summary\r\n\r\nCollects two events of graph visualization usage\r\n\r\n1. When graph preview is shown - allows to determine how many users\r\ningested data that is graph compliant\r\n2. When graph investigation component is visible - allows to determine\r\nhow many users entered the investigation user flow\r\n\r\n**How to test:**\r\n\r\n- Enable the feature flag \r\n\r\n`kibana.dev.yml`:\r\n\r\n```yaml\r\nuiSettings.overrides.securitySolution:enableVisualizationsInFlyout: true\r\nuiSettings.overrides.securitySolution:enableGraphVisualization: true\r\n```\r\n\r\n- Load mocked data:\r\n\r\n```bash\r\nnode scripts/es_archiver load x-pack/test/cloud_security_posture_functional/es_archives/logs_gcp_audit \\ \r\n --es-url http://elastic:changeme@localhost:9200 \\\r\n --kibana-url http://elastic:changeme@localhost:5601\r\n\r\nnode scripts/es_archiver load x-pack/test/cloud_security_posture_functional/es_archives/security_alerts \\\r\n --es-url http://elastic:changeme@localhost:9200 \\\r\n --kibana-url http://elastic:changeme@localhost:5601\r\n```\r\n\r\n- Make sure you include data from Oct 13 2024. (in the video I use Last\r\nyear)\r\n- Run in dev tools:\r\n```\r\nPOST kbn:/internal/telemetry/clusters/_stats?pretty=true&apiVersion=2\r\n{\r\n \"unencrypted\": true,\r\n \"refreshCache\": true\r\n}\r\n```\r\n- Check if the ui_counters were reported\r\n\r\n","sha":"7ac553ce89e987cb08128afff4f9fdcefc48e0c1"}}]}] BACKPORT--> Co-authored-by: Kfir Peled <61654899+kfirpeled@users.noreply.github.com>
This commit is contained in:
parent
273630d3a7
commit
89fe701d70
15 changed files with 171 additions and 63 deletions
|
@ -10,35 +10,45 @@ 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 MISCONFIGURATION_INSIGHT = 'misconfiguration-insight' as const;
|
||||
export const VULNERABILITIES_INSIGHT = 'vulnerabilities-insight' as const;
|
||||
export const MISCONFIGURATION_INSIGHT_HOST_DETAILS =
|
||||
`${MISCONFIGURATION_INSIGHT}-host-details` as const;
|
||||
export const MISCONFIGURATION_INSIGHT_USER_DETAILS =
|
||||
`${MISCONFIGURATION_INSIGHT}-user-details` as const;
|
||||
export const MISCONFIGURATION_INSIGHT_HOST_ENTITY_OVERVIEW =
|
||||
`${MISCONFIGURATION_INSIGHT}-host-entity-overview` as const;
|
||||
export const MISCONFIGURATION_INSIGHT_USER_ENTITY_OVERVIEW =
|
||||
`${MISCONFIGURATION_INSIGHT}-user-entity-overview` as const;
|
||||
export const VULNERABILITIES_INSIGHT_HOST_DETAILS =
|
||||
`${VULNERABILITIES_INSIGHT}-host-details` as const;
|
||||
export const VULNERABILITIES_INSIGHT_HOST_ENTITY_OVERVIEW =
|
||||
`${VULNERABILITIES_INSIGHT}-host-entity-overview` as const;
|
||||
|
||||
export const ENTITY_FLYOUT_WITH_MISCONFIGURATION_VISIT =
|
||||
'entity-flyout-with-misconfiguration-visits';
|
||||
'entity-flyout-with-misconfiguration-visits' as const;
|
||||
export const ENTITY_FLYOUT_WITH_VULNERABILITY_PREVIEW =
|
||||
'entity-flyout-with-vulnerability-preview-visits';
|
||||
'entity-flyout-with-vulnerability-preview-visits' as const;
|
||||
export const ENTITY_FLYOUT_EXPAND_MISCONFIGURATION_VIEW_VISITS =
|
||||
'entity-flyout-expand-misconfiguration-view-visits';
|
||||
'entity-flyout-expand-misconfiguration-view-visits' as const;
|
||||
export const ENTITY_FLYOUT_EXPAND_VULNERABILITY_VIEW_VISITS =
|
||||
'entity-flyout-expand-vulnerability-view-visits';
|
||||
'entity-flyout-expand-vulnerability-view-visits' as const;
|
||||
export const NAV_TO_FINDINGS_BY_HOST_NAME_FRPOM_ENTITY_FLYOUT =
|
||||
'nav-to-findings-by-host-name-from-entity-flyout';
|
||||
'nav-to-findings-by-host-name-from-entity-flyout' as const;
|
||||
export const NAV_TO_FINDINGS_BY_RULE_NAME_FRPOM_ENTITY_FLYOUT =
|
||||
'nav-to-findings-by-rule-name-from-entity-flyout';
|
||||
export const CREATE_DETECTION_RULE_FROM_FLYOUT = 'create-detection-rule-from-flyout';
|
||||
export const CREATE_DETECTION_FROM_TABLE_ROW_ACTION = 'create-detection-from-table-row-action';
|
||||
export const VULNERABILITIES_FLYOUT_VISITS = 'vulnerabilities-flyout-visits';
|
||||
export const OPEN_FINDINGS_FLYOUT = 'open-findings-flyout';
|
||||
export const GROUP_BY_CLICK = 'group-by-click';
|
||||
export const CHANGE_RULE_STATE = 'change-rule-state';
|
||||
'nav-to-findings-by-rule-name-from-entity-flyout' as const;
|
||||
export const CREATE_DETECTION_RULE_FROM_FLYOUT = 'create-detection-rule-from-flyout' as const;
|
||||
export const CREATE_DETECTION_FROM_TABLE_ROW_ACTION =
|
||||
'create-detection-from-table-row-action' as const;
|
||||
export const VULNERABILITIES_FLYOUT_VISITS = 'vulnerabilities-flyout-visits' as const;
|
||||
export const OPEN_FINDINGS_FLYOUT = 'open-findings-flyout' as const;
|
||||
export const GROUP_BY_CLICK = 'group-by-click' as const;
|
||||
export const CHANGE_RULE_STATE = 'change-rule-state' as const;
|
||||
|
||||
type CloudSecurityUiCounters =
|
||||
export const GRAPH_PREVIEW = 'graph-preview' as const;
|
||||
export const GRAPH_INVESTIGATION = 'graph-investigation' as const;
|
||||
|
||||
export type CloudSecurityUiCounters =
|
||||
| typeof ENTITY_FLYOUT_WITH_MISCONFIGURATION_VISIT
|
||||
| typeof ENTITY_FLYOUT_WITH_VULNERABILITY_PREVIEW
|
||||
| typeof ENTITY_FLYOUT_EXPAND_MISCONFIGURATION_VIEW_VISITS
|
||||
|
@ -56,7 +66,9 @@ type CloudSecurityUiCounters =
|
|||
| typeof MISCONFIGURATION_INSIGHT_HOST_ENTITY_OVERVIEW
|
||||
| typeof MISCONFIGURATION_INSIGHT_USER_ENTITY_OVERVIEW
|
||||
| typeof VULNERABILITIES_INSIGHT_HOST_DETAILS
|
||||
| typeof VULNERABILITIES_INSIGHT_HOST_ENTITY_OVERVIEW;
|
||||
| typeof VULNERABILITIES_INSIGHT_HOST_ENTITY_OVERVIEW
|
||||
| typeof GRAPH_PREVIEW
|
||||
| typeof GRAPH_INVESTIGATION;
|
||||
|
||||
export class UiMetricService {
|
||||
private usageCollection: UsageCollectionSetup | undefined;
|
||||
|
|
|
@ -25,6 +25,10 @@ import type { EuiBasicTableColumn } from '@elastic/eui';
|
|||
import { FormattedMessage } from '@kbn/i18n-react';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { useExpandableFlyoutApi } from '@kbn/expandable-flyout';
|
||||
import {
|
||||
MISCONFIGURATION_INSIGHT_HOST_DETAILS,
|
||||
VULNERABILITIES_INSIGHT_HOST_DETAILS,
|
||||
} from '@kbn/cloud-security-posture-common/utils/ui_metrics';
|
||||
import { ExpandablePanel } from '../../../shared/components/expandable_panel';
|
||||
import type { RelatedUser } from '../../../../../common/search_strategy/security_solution/related_entities/related_users';
|
||||
import type { RiskSeverity } from '../../../../../common/search_strategy';
|
||||
|
@ -346,13 +350,13 @@ export const HostDetails: React.FC<HostDetailsProps> = ({ hostName, timestamp, s
|
|||
name={hostName}
|
||||
direction="column"
|
||||
data-test-subj={HOST_DETAILS_MISCONFIGURATIONS_TEST_ID}
|
||||
telemetrySuffix={'host-details'}
|
||||
telemetryKey={MISCONFIGURATION_INSIGHT_HOST_DETAILS}
|
||||
/>
|
||||
<VulnerabilitiesInsight
|
||||
hostName={hostName}
|
||||
direction="column"
|
||||
data-test-subj={HOST_DETAILS_VULNERABILITIES_TEST_ID}
|
||||
telemetrySuffix={'host-details'}
|
||||
telemetryKey={VULNERABILITIES_INSIGHT_HOST_DETAILS}
|
||||
/>
|
||||
</EuiFlexGrid>
|
||||
<EuiSpacer size="l" />
|
||||
|
|
|
@ -25,6 +25,7 @@ import type { EuiBasicTableColumn } from '@elastic/eui';
|
|||
import { FormattedMessage } from '@kbn/i18n-react';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { useExpandableFlyoutApi } from '@kbn/expandable-flyout';
|
||||
import { MISCONFIGURATION_INSIGHT_USER_DETAILS } from '@kbn/cloud-security-posture-common/utils/ui_metrics';
|
||||
import { ExpandablePanel } from '../../../shared/components/expandable_panel';
|
||||
import type { RelatedHost } from '../../../../../common/search_strategy/security_solution/related_entities/related_hosts';
|
||||
import type { RiskSeverity } from '../../../../../common/search_strategy';
|
||||
|
@ -346,7 +347,7 @@ export const UserDetails: React.FC<UserDetailsProps> = ({ userName, timestamp, s
|
|||
name={userName}
|
||||
direction="column"
|
||||
data-test-subj={USER_DETAILS_MISCONFIGURATIONS_TEST_ID}
|
||||
telemetrySuffix={'user-details'}
|
||||
telemetryKey={MISCONFIGURATION_INSIGHT_USER_DETAILS}
|
||||
/>
|
||||
</EuiFlexGrid>
|
||||
<EuiSpacer size="l" />
|
||||
|
|
|
@ -11,6 +11,10 @@ import type { EuiButtonGroupOptionProps } from '@elastic/eui/src/components/butt
|
|||
import { useExpandableFlyoutApi, useExpandableFlyoutState } from '@kbn/expandable-flyout';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { FormattedMessage } from '@kbn/i18n-react';
|
||||
import {
|
||||
uiMetricService,
|
||||
GRAPH_INVESTIGATION,
|
||||
} from '@kbn/cloud-security-posture-common/utils/ui_metrics';
|
||||
import { useUiSetting$ } from '@kbn/kibana-react-plugin/public';
|
||||
import { useDocumentDetailsContext } from '../../shared/context';
|
||||
import { useWhichFlyout } from '../../shared/hooks/use_which_flyout';
|
||||
|
@ -31,6 +35,7 @@ import { ALERTS_ACTIONS } from '../../../../common/lib/apm/user_actions';
|
|||
import { useStartTransaction } from '../../../../common/lib/apm/use_start_transaction';
|
||||
import { GRAPH_ID, GraphVisualization } from '../components/graph_visualization';
|
||||
import { useGraphPreview } from '../../shared/hooks/use_graph_preview';
|
||||
import { METRIC_TYPE } from '../../../../common/lib/telemetry';
|
||||
import { ENABLE_GRAPH_VISUALIZATION_SETTING } from '../../../../../common/constants';
|
||||
|
||||
const visualizeButtons: EuiButtonGroupOptionProps[] = [
|
||||
|
@ -109,6 +114,8 @@ export const VisualizeTab = memo(() => {
|
|||
banner: ANALYZER_PREVIEW_BANNER,
|
||||
},
|
||||
});
|
||||
} else if (optionId === GRAPH_ID) {
|
||||
uiMetricService.trackUiMetric(METRIC_TYPE.CLICK, GRAPH_INVESTIGATION);
|
||||
}
|
||||
},
|
||||
[startTransaction, openPreviewPanel, key, scopeId]
|
||||
|
@ -117,6 +124,10 @@ export const VisualizeTab = memo(() => {
|
|||
useEffect(() => {
|
||||
if (panels.left?.path?.subTab) {
|
||||
setActiveVisualizationId(panels.left?.path?.subTab);
|
||||
|
||||
if (panels.left?.path?.subTab === GRAPH_ID) {
|
||||
uiMetricService.trackUiMetric(METRIC_TYPE.CLICK, GRAPH_INVESTIGATION);
|
||||
}
|
||||
}
|
||||
}, [panels.left?.path?.subTab]);
|
||||
|
||||
|
|
|
@ -5,10 +5,15 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import { render } from '@testing-library/react';
|
||||
import { useFetchGraphData } from '@kbn/cloud-security-posture-graph/src/hooks';
|
||||
import {
|
||||
uiMetricService,
|
||||
GRAPH_PREVIEW,
|
||||
} from '@kbn/cloud-security-posture-common/utils/ui_metrics';
|
||||
import { METRIC_TYPE } from '@kbn/analytics';
|
||||
import { TestProviders } from '../../../../common/mock';
|
||||
import React from 'react';
|
||||
import { DocumentDetailsContext } from '../../shared/context';
|
||||
import { mockContextValue } from '../../shared/mocks/mock_context';
|
||||
import { GraphPreviewContainer } from './graph_preview_container';
|
||||
|
@ -23,6 +28,14 @@ import {
|
|||
} from '../../../shared/components/test_ids';
|
||||
import { useIsExperimentalFeatureEnabled } from '../../../../common/hooks/use_experimental_features';
|
||||
|
||||
jest.mock('@kbn/cloud-security-posture-common/utils/ui_metrics', () => ({
|
||||
uiMetricService: {
|
||||
trackUiMetric: jest.fn(),
|
||||
},
|
||||
}));
|
||||
|
||||
const uiMetricServiceMock = uiMetricService as jest.Mocked<typeof uiMetricService>;
|
||||
|
||||
const mockUseUiSetting = jest.fn().mockReturnValue([true]);
|
||||
jest.mock('@kbn/kibana-react-plugin/public', () => {
|
||||
const original = jest.requireActual('@kbn/kibana-react-plugin/public');
|
||||
|
@ -173,6 +186,10 @@ describe('<GraphPreviewContainer />', () => {
|
|||
refetchOnWindowFocus: false,
|
||||
},
|
||||
});
|
||||
expect(uiMetricServiceMock.trackUiMetric).toHaveBeenCalledWith(
|
||||
METRIC_TYPE.LOADED,
|
||||
GRAPH_PREVIEW
|
||||
);
|
||||
});
|
||||
|
||||
it('should render component for event', async () => {
|
||||
|
@ -224,6 +241,10 @@ describe('<GraphPreviewContainer />', () => {
|
|||
refetchOnWindowFocus: false,
|
||||
},
|
||||
});
|
||||
expect(uiMetricServiceMock.trackUiMetric).toHaveBeenCalledWith(
|
||||
METRIC_TYPE.LOADED,
|
||||
GRAPH_PREVIEW
|
||||
);
|
||||
});
|
||||
|
||||
it('should render component and without link in header in preview panel', async () => {
|
||||
|
@ -437,5 +458,7 @@ describe('<GraphPreviewContainer />', () => {
|
|||
refetchOnWindowFocus: false,
|
||||
},
|
||||
});
|
||||
|
||||
expect(uiMetricServiceMock.trackUiMetric).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
|
|
@ -5,12 +5,17 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import React, { useEffect } from 'react';
|
||||
import { FormattedMessage } from '@kbn/i18n-react';
|
||||
import { useUiSetting$ } from '@kbn/kibana-react-plugin/public';
|
||||
import { EuiBetaBadge } from '@elastic/eui';
|
||||
import { EuiBetaBadge, useGeneratedHtmlId } from '@elastic/eui';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { useFetchGraphData } from '@kbn/cloud-security-posture-graph/src/hooks';
|
||||
import {
|
||||
uiMetricService,
|
||||
GRAPH_PREVIEW,
|
||||
} from '@kbn/cloud-security-posture-common/utils/ui_metrics';
|
||||
import { METRIC_TYPE } from '@kbn/analytics';
|
||||
import { ENABLE_VISUALIZATIONS_IN_FLYOUT_SETTING } from '../../../../../common/constants';
|
||||
import { useDocumentDetailsContext } from '../../shared/context';
|
||||
import { GRAPH_PREVIEW_TEST_ID } from './test_ids';
|
||||
|
@ -23,6 +28,7 @@ import { ExpandablePanel } from '../../../shared/components/expandable_panel';
|
|||
* Graph preview under Overview, Visualizations. It shows a graph representation of entities.
|
||||
*/
|
||||
export const GraphPreviewContainer: React.FC = () => {
|
||||
const renderingId = useGeneratedHtmlId();
|
||||
const {
|
||||
dataAsNestedObject,
|
||||
getFieldsData,
|
||||
|
@ -72,6 +78,12 @@ export const GraphPreviewContainer: React.FC = () => {
|
|||
},
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
if (hasGraphRepresentation) {
|
||||
uiMetricService.trackUiMetric(METRIC_TYPE.LOADED, GRAPH_PREVIEW);
|
||||
}
|
||||
}, [hasGraphRepresentation, renderingId]);
|
||||
|
||||
return (
|
||||
<ExpandablePanel
|
||||
header={{
|
||||
|
|
|
@ -18,6 +18,10 @@ import {
|
|||
import { css } from '@emotion/react';
|
||||
import { getOr } from 'lodash/fp';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import {
|
||||
MISCONFIGURATION_INSIGHT_HOST_ENTITY_OVERVIEW,
|
||||
VULNERABILITIES_INSIGHT_HOST_ENTITY_OVERVIEW,
|
||||
} from '@kbn/cloud-security-posture-common/utils/ui_metrics';
|
||||
import { buildHostNamesFilter } from '../../../../../common/search_strategy';
|
||||
import { HOST_NAME_FIELD_NAME } from '../../../../timelines/components/timeline/body/renderers/constants';
|
||||
import { useRiskScore } from '../../../../entity_analytics/api/hooks/use_risk_score';
|
||||
|
@ -253,12 +257,12 @@ export const HostEntityOverview: React.FC<HostEntityOverviewProps> = ({ hostName
|
|||
fieldName={'host.name'}
|
||||
name={hostName}
|
||||
data-test-subj={ENTITIES_HOST_OVERVIEW_MISCONFIGURATIONS_TEST_ID}
|
||||
telemetrySuffix={'host-entity-overview'}
|
||||
telemetryKey={MISCONFIGURATION_INSIGHT_HOST_ENTITY_OVERVIEW}
|
||||
/>
|
||||
<VulnerabilitiesInsight
|
||||
hostName={hostName}
|
||||
data-test-subj={ENTITIES_HOST_OVERVIEW_VULNERABILITIES_TEST_ID}
|
||||
telemetrySuffix={'host-entity-overview'}
|
||||
telemetryKey={VULNERABILITIES_INSIGHT_HOST_ENTITY_OVERVIEW}
|
||||
/>
|
||||
</EuiFlexGroup>
|
||||
);
|
||||
|
|
|
@ -18,6 +18,7 @@ import {
|
|||
import { css } from '@emotion/react';
|
||||
import { getOr } from 'lodash/fp';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { MISCONFIGURATION_INSIGHT_USER_ENTITY_OVERVIEW } from '@kbn/cloud-security-posture-common/utils/ui_metrics';
|
||||
import { buildUserNamesFilter } from '../../../../../common/search_strategy';
|
||||
import { useDocumentDetailsContext } from '../../shared/context';
|
||||
import type { DescriptionList } from '../../../../../common/utility_types';
|
||||
|
@ -250,7 +251,7 @@ export const UserEntityOverview: React.FC<UserEntityOverviewProps> = ({ userName
|
|||
fieldName={'user.name'}
|
||||
name={userName}
|
||||
data-test-subj={ENTITIES_USER_OVERVIEW_MISCONFIGURATIONS_TEST_ID}
|
||||
telemetrySuffix={'user-entity-overview'}
|
||||
telemetryKey={MISCONFIGURATION_INSIGHT_USER_ENTITY_OVERVIEW}
|
||||
/>
|
||||
</EuiFlexGroup>
|
||||
);
|
||||
|
|
|
@ -9,6 +9,11 @@ import React from 'react';
|
|||
import { __IntlProvider as IntlProvider } from '@kbn/i18n-react';
|
||||
import { render } from '@testing-library/react';
|
||||
import { useFetchGraphData } from '@kbn/cloud-security-posture-graph/src/hooks';
|
||||
import {
|
||||
uiMetricService,
|
||||
GRAPH_PREVIEW,
|
||||
} from '@kbn/cloud-security-posture-common/utils/ui_metrics';
|
||||
import { METRIC_TYPE } from '@kbn/analytics';
|
||||
import {
|
||||
ANALYZER_PREVIEW_TEST_ID,
|
||||
SESSION_PREVIEW_TEST_ID,
|
||||
|
@ -84,6 +89,14 @@ jest.mock('@kbn/cloud-security-posture-graph/src/hooks', () => ({
|
|||
|
||||
const mockUseFetchGraphData = useFetchGraphData as jest.Mock;
|
||||
|
||||
jest.mock('@kbn/cloud-security-posture-common/utils/ui_metrics', () => ({
|
||||
uiMetricService: {
|
||||
trackUiMetric: jest.fn(),
|
||||
},
|
||||
}));
|
||||
|
||||
const uiMetricServiceMock = uiMetricService as jest.Mocked<typeof uiMetricService>;
|
||||
|
||||
const panelContextValue = {
|
||||
...mockContextValue,
|
||||
dataFormattedForFieldBrowser: mockDataFormattedForFieldBrowser,
|
||||
|
@ -182,6 +195,10 @@ describe('<VisualizationsSection />', () => {
|
|||
const { getByTestId } = renderVisualizationsSection();
|
||||
|
||||
expect(getByTestId(`${GRAPH_PREVIEW_TEST_ID}LeftSection`)).toBeInTheDocument();
|
||||
expect(uiMetricServiceMock.trackUiMetric).toHaveBeenCalledWith(
|
||||
METRIC_TYPE.LOADED,
|
||||
GRAPH_PREVIEW
|
||||
);
|
||||
});
|
||||
|
||||
it('should not render the graph preview component if the graph feature is disabled', () => {
|
||||
|
|
|
@ -6,14 +6,14 @@
|
|||
*/
|
||||
|
||||
import React, { useEffect, useMemo } from 'react';
|
||||
import { EuiFlexItem, type EuiFlexGroupProps, useEuiTheme } from '@elastic/eui';
|
||||
import { EuiFlexItem, type EuiFlexGroupProps, useEuiTheme, useGeneratedHtmlId } from '@elastic/eui';
|
||||
import { FormattedMessage } from '@kbn/i18n-react';
|
||||
import { css } from '@emotion/react';
|
||||
import { useMisconfigurationPreview } from '@kbn/cloud-security-posture/src/hooks/use_misconfiguration_preview';
|
||||
import { buildGenericEntityFlyoutPreviewQuery } from '@kbn/cloud-security-posture-common';
|
||||
import {
|
||||
MISCONFIGURATION_INSIGHT,
|
||||
uiMetricService,
|
||||
type CloudSecurityUiCounters,
|
||||
} from '@kbn/cloud-security-posture-common/utils/ui_metrics';
|
||||
import { METRIC_TYPE } from '@kbn/analytics';
|
||||
import { InsightDistributionBar } from './insight_distribution_bar';
|
||||
|
@ -42,7 +42,7 @@ interface MisconfigurationsInsightProps {
|
|||
/**
|
||||
* used to track the instance of this component, prefer kebab-case
|
||||
*/
|
||||
telemetrySuffix?: string;
|
||||
telemetryKey?: CloudSecurityUiCounters;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -53,8 +53,9 @@ export const MisconfigurationsInsight: React.FC<MisconfigurationsInsightProps> =
|
|||
fieldName,
|
||||
direction,
|
||||
'data-test-subj': dataTestSubj,
|
||||
telemetrySuffix,
|
||||
telemetryKey,
|
||||
}) => {
|
||||
const renderingId = useGeneratedHtmlId();
|
||||
const { scopeId, isPreview } = useDocumentDetailsContext();
|
||||
const { euiTheme } = useEuiTheme();
|
||||
const { data } = useMisconfigurationPreview({
|
||||
|
@ -65,12 +66,10 @@ export const MisconfigurationsInsight: React.FC<MisconfigurationsInsightProps> =
|
|||
});
|
||||
|
||||
useEffect(() => {
|
||||
uiMetricService.trackUiMetric(
|
||||
METRIC_TYPE.COUNT,
|
||||
`${MISCONFIGURATION_INSIGHT}-${telemetrySuffix}`
|
||||
);
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, []);
|
||||
if (telemetryKey) {
|
||||
uiMetricService.trackUiMetric(METRIC_TYPE.COUNT, telemetryKey);
|
||||
}
|
||||
}, [telemetryKey, renderingId]);
|
||||
|
||||
const passedFindings = data?.count.passed || 0;
|
||||
const failedFindings = data?.count.failed || 0;
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
*/
|
||||
|
||||
import React, { useEffect, useMemo } from 'react';
|
||||
import { EuiFlexItem, type EuiFlexGroupProps, useEuiTheme } from '@elastic/eui';
|
||||
import { EuiFlexItem, type EuiFlexGroupProps, useEuiTheme, useGeneratedHtmlId } from '@elastic/eui';
|
||||
import { FormattedMessage } from '@kbn/i18n-react';
|
||||
import { css } from '@emotion/react';
|
||||
import { useVulnerabilitiesPreview } from '@kbn/cloud-security-posture/src/hooks/use_vulnerabilities_preview';
|
||||
|
@ -14,7 +14,7 @@ import { buildGenericEntityFlyoutPreviewQuery } from '@kbn/cloud-security-postur
|
|||
import { getVulnerabilityStats, hasVulnerabilitiesData } from '@kbn/cloud-security-posture';
|
||||
import {
|
||||
uiMetricService,
|
||||
VULNERABILITIES_INSIGHT,
|
||||
type CloudSecurityUiCounters,
|
||||
} from '@kbn/cloud-security-posture-common/utils/ui_metrics';
|
||||
import { METRIC_TYPE } from '@kbn/analytics';
|
||||
import { InsightDistributionBar } from './insight_distribution_bar';
|
||||
|
@ -38,7 +38,7 @@ interface VulnerabilitiesInsightProps {
|
|||
/**
|
||||
* used to track the instance of this component, prefer kebab-case
|
||||
*/
|
||||
telemetrySuffix?: string;
|
||||
telemetryKey?: CloudSecurityUiCounters;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -48,8 +48,9 @@ export const VulnerabilitiesInsight: React.FC<VulnerabilitiesInsightProps> = ({
|
|||
hostName,
|
||||
direction,
|
||||
'data-test-subj': dataTestSubj,
|
||||
telemetrySuffix,
|
||||
telemetryKey,
|
||||
}) => {
|
||||
const renderingId = useGeneratedHtmlId();
|
||||
const { scopeId, isPreview } = useDocumentDetailsContext();
|
||||
const { euiTheme } = useEuiTheme();
|
||||
const { data } = useVulnerabilitiesPreview({
|
||||
|
@ -60,12 +61,10 @@ export const VulnerabilitiesInsight: React.FC<VulnerabilitiesInsightProps> = ({
|
|||
});
|
||||
|
||||
useEffect(() => {
|
||||
uiMetricService.trackUiMetric(
|
||||
METRIC_TYPE.COUNT,
|
||||
`${VULNERABILITIES_INSIGHT}-${telemetrySuffix}`
|
||||
);
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, []);
|
||||
if (telemetryKey) {
|
||||
uiMetricService.trackUiMetric(METRIC_TYPE.COUNT, telemetryKey);
|
||||
}
|
||||
}, [telemetryKey, renderingId]);
|
||||
|
||||
const { CRITICAL = 0, HIGH = 0, MEDIUM = 0, LOW = 0, NONE = 0 } = data?.count || {};
|
||||
const totalVulnerabilities = useMemo(
|
||||
|
|
|
@ -6,10 +6,25 @@
|
|||
*/
|
||||
|
||||
import { resolve } from 'path';
|
||||
import type { FtrConfigProviderContext } from '@kbn/test';
|
||||
import type { FtrConfigProviderContext, GenericFtrProviderContext } from '@kbn/test';
|
||||
import { CLOUD_SECURITY_PLUGIN_VERSION } from '@kbn/cloud-security-posture-plugin/common/constants';
|
||||
import {
|
||||
KibanaEBTServerProvider,
|
||||
KibanaEBTUIProvider,
|
||||
} from '@kbn/test-suites-src/analytics/services/kibana_ebt';
|
||||
import { pageObjects } from './page_objects';
|
||||
import { services } from './services';
|
||||
import type { services as inheritedServices } from '../functional/services';
|
||||
|
||||
type SecurityTelemetryServices = typeof inheritedServices &
|
||||
typeof services & {
|
||||
kibana_ebt_ui: typeof KibanaEBTUIProvider;
|
||||
};
|
||||
|
||||
export type SecurityTelemetryFtrProviderContext = GenericFtrProviderContext<
|
||||
SecurityTelemetryServices,
|
||||
typeof pageObjects
|
||||
>;
|
||||
|
||||
export default async function ({ readConfigFile }: FtrConfigProviderContext) {
|
||||
const xpackFunctionalConfig = await readConfigFile(
|
||||
|
@ -21,6 +36,8 @@ export default async function ({ readConfigFile }: FtrConfigProviderContext) {
|
|||
services: {
|
||||
...xpackFunctionalConfig.get('services'),
|
||||
...services,
|
||||
kibana_ebt_server: KibanaEBTServerProvider,
|
||||
kibana_ebt_ui: KibanaEBTUIProvider,
|
||||
},
|
||||
pageObjects,
|
||||
testFiles: [resolve(__dirname, './pages')],
|
||||
|
@ -50,6 +67,11 @@ export default async function ({ readConfigFile }: FtrConfigProviderContext) {
|
|||
// `--xpack.fleet.registryUrl=https://localhost:8080`,
|
||||
`--xpack.fleet.agents.fleet_server.hosts=["https://ftr.kibana:8220"]`,
|
||||
`--xpack.fleet.internal.fleetServerStandalone=true`,
|
||||
// Required for telemetry e2e tests
|
||||
`--plugin-path=${resolve(
|
||||
__dirname,
|
||||
'../../../test/analytics/plugins/analytics_ftr_helpers'
|
||||
)}`,
|
||||
],
|
||||
},
|
||||
};
|
||||
|
|
|
@ -6,10 +6,11 @@
|
|||
*/
|
||||
|
||||
import expect from '@kbn/expect';
|
||||
import { GenericFtrService } from '@kbn/test';
|
||||
import type { WebElementWrapper } from '@kbn/ftr-common-functional-ui-services';
|
||||
import type { FilterBarService } from '@kbn/test-suites-src/functional/services/filter_bar';
|
||||
import { FtrService } from '../../functional/ftr_provider_context';
|
||||
import type { QueryBarProvider } from '../services/query_bar_provider';
|
||||
import type { SecurityTelemetryFtrProviderContext } from '../config';
|
||||
|
||||
const GRAPH_PREVIEW_TITLE_LINK_TEST_ID = 'securitySolutionFlyoutGraphPreviewTitleLink';
|
||||
const NODE_EXPAND_BUTTON_TEST_ID = 'cloudSecurityGraphNodeExpandButton';
|
||||
|
@ -24,7 +25,7 @@ const GRAPH_ACTIONS_TOGGLE_SEARCH_ID = `${GRAPH_INVESTIGATION_TEST_ID}ToggleSear
|
|||
const GRAPH_ACTIONS_INVESTIGATE_IN_TIMELINE_ID = `${GRAPH_INVESTIGATION_TEST_ID}InvestigateInTimeline`;
|
||||
type Filter = Parameters<FilterBarService['addFilter']>[0];
|
||||
|
||||
export class ExpandedFlyoutGraph extends FtrService {
|
||||
export class ExpandedFlyoutGraph extends GenericFtrService<SecurityTelemetryFtrProviderContext> {
|
||||
private readonly pageObjects = this.ctx.getPageObjects(['common', 'header']);
|
||||
private readonly testSubjects = this.ctx.getService('testSubjects');
|
||||
private readonly filterBar = this.ctx.getService('filterBar');
|
||||
|
@ -154,7 +155,6 @@ export class ExpandedFlyoutGraph extends FtrService {
|
|||
}
|
||||
|
||||
async setKqlQuery(kql: string): Promise<void> {
|
||||
// @ts-expect-error queryBarProvider is not a public service
|
||||
const queryBarProvider: QueryBarProvider = this.ctx.getService('queryBarProvider');
|
||||
|
||||
const queryBar = queryBarProvider.getQueryBar(GRAPH_INVESTIGATION_TEST_ID);
|
||||
|
|
|
@ -6,14 +6,15 @@
|
|||
*/
|
||||
|
||||
import { waitForPluginInitialized } from '../../cloud_security_posture_api/utils';
|
||||
import type { FtrProviderContext } from '../ftr_provider_context';
|
||||
import type { SecurityTelemetryFtrProviderContext } from '../config';
|
||||
|
||||
// eslint-disable-next-line import/no-default-export
|
||||
export default function ({ getPageObjects, getService }: FtrProviderContext) {
|
||||
export default function ({ getPageObjects, getService }: SecurityTelemetryFtrProviderContext) {
|
||||
const retry = getService('retry');
|
||||
const logger = getService('log');
|
||||
const supertest = getService('supertest');
|
||||
const esArchiver = getService('esArchiver');
|
||||
const ebtUIHelper = getService('kibana_ebt_ui');
|
||||
const pageObjects = getPageObjects([
|
||||
'common',
|
||||
'header',
|
||||
|
@ -49,8 +50,7 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) {
|
|||
);
|
||||
|
||||
await alertsPage.waitForListToHaveAlerts();
|
||||
|
||||
await alertsPage.flyout.expandVisualizations();
|
||||
await ebtUIHelper.setOptIn(true); // starts the recording of events from this moment
|
||||
});
|
||||
|
||||
after(async () => {
|
||||
|
@ -63,6 +63,8 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) {
|
|||
});
|
||||
|
||||
it('expanded flyout - filter by node', async () => {
|
||||
await alertsPage.flyout.expandVisualizations();
|
||||
|
||||
await alertsPage.flyout.assertGraphPreviewVisible();
|
||||
await alertsPage.flyout.assertGraphNodesNumber(3);
|
||||
|
||||
|
|
|
@ -6,14 +6,15 @@
|
|||
*/
|
||||
|
||||
import { waitForPluginInitialized } from '../../cloud_security_posture_api/utils';
|
||||
import type { FtrProviderContext } from '../ftr_provider_context';
|
||||
import type { SecurityTelemetryFtrProviderContext } from '../config';
|
||||
|
||||
// eslint-disable-next-line import/no-default-export
|
||||
export default function ({ getPageObjects, getService }: FtrProviderContext) {
|
||||
export default function ({ getPageObjects, getService }: SecurityTelemetryFtrProviderContext) {
|
||||
const retry = getService('retry');
|
||||
const logger = getService('log');
|
||||
const supertest = getService('supertest');
|
||||
const esArchiver = getService('esArchiver');
|
||||
const ebtUIHelper = getService('kibana_ebt_ui');
|
||||
const pageObjects = getPageObjects([
|
||||
'common',
|
||||
'header',
|
||||
|
@ -44,8 +45,7 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) {
|
|||
);
|
||||
|
||||
await networkEventsPage.waitForListToHaveEvents();
|
||||
|
||||
await networkEventsPage.flyout.expandVisualizations();
|
||||
await ebtUIHelper.setOptIn(true); // starts the recording of events from this moment
|
||||
});
|
||||
|
||||
after(async () => {
|
||||
|
@ -55,6 +55,7 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) {
|
|||
});
|
||||
|
||||
it('expanded flyout - filter by node', async () => {
|
||||
await networkEventsPage.flyout.expandVisualizations();
|
||||
await networkEventsPage.flyout.assertGraphPreviewVisible();
|
||||
await networkEventsPage.flyout.assertGraphNodesNumber(3);
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue