Skip to content

Commit

Permalink
[8.x] [SecuritySolution] Generic reportEvents for EBT Telemetry (#197079
Browse files Browse the repository at this point in the history
) (#199697)

# Backport

This will backport the following commits from `main` to `8.x`:
- [[SecuritySolution] Generic reportEvents for EBT Telemetry
(#197079)](#197079)

<!--- Backport version: 9.4.3 -->

### Questions ?
Please refer to the [Backport tool
documentation](https://github.com/sqren/backport)

<!--BACKPORT [{"author":{"name":"Angela
Chuang","email":"[email protected]"},"sourceCommit":{"committedDate":"2024-11-11T19:08:27Z","message":"[SecuritySolution]
Generic reportEvents for EBT Telemetry (#197079)\n\n## Summary\r\n\r\n1.
Removing the custom EBT
events:\r\nhttps://github.com//pull/197079/files#diff-7beaf4f2d7c25c8913607b5dbc6e1ad0027f6ffacddafe4c675c775c3e7ae903L55\r\n2.
Use `reportEvent` for all the Security Solution EBT events.\r\n\r\n###
Checklist\r\n\r\nDelete any items that are not applicable to this
PR.\r\n\r\n\r\n- [x] [Unit or
functional\r\ntests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)\r\nwere
updated or added to match the most common
scenarios","sha":"3b0c3808ef34db432c4e879a029e67188a01539b","branchLabelMapping":{"^v9.0.0$":"main","^v8.17.0$":"8.x","^v(\\d+).(\\d+).\\d+$":"$1.$2"}},"sourcePullRequest":{"labels":["backport","release_note:skip","v9.0.0","Team:Threat
Hunting:Explore","v8.17.0"],"title":"[SecuritySolution] Generic
reportEvents for EBT
Telemetry","number":197079,"url":"https://github.com/elastic/kibana/pull/197079","mergeCommit":{"message":"[SecuritySolution]
Generic reportEvents for EBT Telemetry (#197079)\n\n## Summary\r\n\r\n1.
Removing the custom EBT
events:\r\nhttps://github.com//pull/197079/files#diff-7beaf4f2d7c25c8913607b5dbc6e1ad0027f6ffacddafe4c675c775c3e7ae903L55\r\n2.
Use `reportEvent` for all the Security Solution EBT events.\r\n\r\n###
Checklist\r\n\r\nDelete any items that are not applicable to this
PR.\r\n\r\n\r\n- [x] [Unit or
functional\r\ntests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)\r\nwere
updated or added to match the most common
scenarios","sha":"3b0c3808ef34db432c4e879a029e67188a01539b"}},"sourceBranch":"main","suggestedTargetBranches":["8.x"],"targetPullRequestStates":[{"branch":"main","label":"v9.0.0","branchLabelMappingKey":"^v9.0.0$","isSourceBranch":true,"state":"MERGED","url":"https://github.com/elastic/kibana/pull/197079","number":197079,"mergeCommit":{"message":"[SecuritySolution]
Generic reportEvents for EBT Telemetry (#197079)\n\n## Summary\r\n\r\n1.
Removing the custom EBT
events:\r\nhttps://github.com//pull/197079/files#diff-7beaf4f2d7c25c8913607b5dbc6e1ad0027f6ffacddafe4c675c775c3e7ae903L55\r\n2.
Use `reportEvent` for all the Security Solution EBT events.\r\n\r\n###
Checklist\r\n\r\nDelete any items that are not applicable to this
PR.\r\n\r\n\r\n- [x] [Unit or
functional\r\ntests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)\r\nwere
updated or added to match the most common
scenarios","sha":"3b0c3808ef34db432c4e879a029e67188a01539b"}},{"branch":"8.x","label":"v8.17.0","branchLabelMappingKey":"^v8.17.0$","isSourceBranch":false,"state":"NOT_CREATED"}]}]
BACKPORT-->

Co-authored-by: Angela Chuang <[email protected]>
  • Loading branch information
kibanamachine and angorayc authored Nov 12, 2024
1 parent bb3e3c7 commit ee0934b
Show file tree
Hide file tree
Showing 97 changed files with 883 additions and 1,223 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import type { StartServices } from '../../types';
import { enhanceActionWithTelemetry } from './telemetry';
import { createAction } from '@kbn/ui-actions-plugin/public';
import type { CellActionExecutionContext } from '@kbn/cell-actions';
import { AppEventTypes } from '../../common/lib/telemetry';

const actionId = 'test_action_id';
const displayName = 'test-actions';
Expand All @@ -29,13 +30,13 @@ const context = {

describe('enhanceActionWithTelemetry', () => {
it('calls telemetry report when the action is executed', () => {
const telemetry = { reportCellActionClicked: jest.fn() };
const telemetry = { reportEvent: jest.fn() };
const services = { telemetry } as unknown as StartServices;

const enhancedAction = enhanceActionWithTelemetry(action, services);
enhancedAction.execute(context);

expect(telemetry.reportCellActionClicked).toHaveBeenCalledWith({
expect(telemetry.reportEvent).toHaveBeenCalledWith(AppEventTypes.CellActionClicked, {
displayName,
actionId,
fieldName,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import type { CellAction, CellActionExecutionContext } from '@kbn/cell-actions';
import type { ActionExecutionContext } from '@kbn/ui-actions-plugin/public';
import type { StartServices } from '../../types';
import type { SecurityCellActionExecutionContext } from './types';
import { AppEventTypes } from '../../common/lib/telemetry';

export const enhanceActionWithTelemetry = (
action: CellAction<CellActionExecutionContext>,
Expand All @@ -19,7 +20,7 @@ export const enhanceActionWithTelemetry = (
const enhancedExecute = (
context: ActionExecutionContext<SecurityCellActionExecutionContext>
): Promise<void> => {
telemetry.reportCellActionClicked({
telemetry.reportEvent(AppEventTypes.CellActionClicked, {
actionId: rest.id,
displayName: rest.getDisplayName(context),
fieldName: context.data.map(({ field }) => field.name).join(', '),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { renderHook } from '@testing-library/react-hooks';
import { useAssistantTelemetry } from '.';
import { BASE_SECURITY_CONVERSATIONS } from '../content/conversations';
import { createTelemetryServiceMock } from '../../common/lib/telemetry/telemetry_service.mock';
import { AssistantEventTypes } from '../../common/lib/telemetry';

const customId = `My Convo`;
const mockedConversations = {
Expand All @@ -20,15 +21,9 @@ const mockedConversations = {
messages: [],
},
};
const reportAssistantInvoked = jest.fn();
const reportAssistantMessageSent = jest.fn();
const reportAssistantQuickPrompt = jest.fn();

const mockedTelemetry = {
...createTelemetryServiceMock(),
reportAssistantInvoked,
reportAssistantMessageSent,
reportAssistantQuickPrompt,
reportAssistantSettingToggled: () => {},
};

jest.mock('../../common/lib/kibana', () => {
Expand All @@ -55,9 +50,9 @@ jest.mock('@kbn/elastic-assistant', () => ({
}));

const trackingFns = [
'reportAssistantInvoked',
'reportAssistantMessageSent',
'reportAssistantQuickPrompt',
{ name: 'reportAssistantInvoked', eventType: AssistantEventTypes.AssistantInvoked },
{ name: 'reportAssistantMessageSent', eventType: AssistantEventTypes.AssistantMessageSent },
{ name: 'reportAssistantQuickPrompt', eventType: AssistantEventTypes.AssistantQuickPrompt },
];

describe('useAssistantTelemetry', () => {
Expand All @@ -67,7 +62,7 @@ describe('useAssistantTelemetry', () => {
it('should return the expected telemetry object with tracking functions', () => {
const { result } = renderHook(() => useAssistantTelemetry());
trackingFns.forEach((fn) => {
expect(result.current).toHaveProperty(fn);
expect(result.current).toHaveProperty(fn.name);
});
});

Expand All @@ -76,11 +71,11 @@ describe('useAssistantTelemetry', () => {
const { result } = renderHook(() => useAssistantTelemetry());
const validId = Object.keys(mockedConversations)[0];
// @ts-ignore
const trackingFn = result.current[fn];
const trackingFn = result.current[fn.name];
await trackingFn({ conversationId: validId, invokedBy: 'shortcut' });
// @ts-ignore
const trackingMockedFn = mockedTelemetry[fn];
expect(trackingMockedFn).toHaveBeenCalledWith({
const trackingMockedFn = mockedTelemetry.reportEvent;
expect(trackingMockedFn).toHaveBeenCalledWith(fn.eventType, {
conversationId: validId,
invokedBy: 'shortcut',
});
Expand All @@ -89,11 +84,11 @@ describe('useAssistantTelemetry', () => {
it('Should call tracking with "Custom" id when tracking is called with an isDefault=false conversation id', async () => {
const { result } = renderHook(() => useAssistantTelemetry());
// @ts-ignore
const trackingFn = result.current[fn];
const trackingFn = result.current[fn.name];
await trackingFn({ conversationId: customId, invokedBy: 'shortcut' });
// @ts-ignore
const trackingMockedFn = mockedTelemetry[fn];
expect(trackingMockedFn).toHaveBeenCalledWith({
const trackingMockedFn = mockedTelemetry.reportEvent;
expect(trackingMockedFn).toHaveBeenCalledWith(fn.eventType, {
conversationId: 'Custom',
invokedBy: 'shortcut',
});
Expand All @@ -102,11 +97,11 @@ describe('useAssistantTelemetry', () => {
it('Should call tracking with "Custom" id when tracking is called with an unknown conversation id', async () => {
const { result } = renderHook(() => useAssistantTelemetry());
// @ts-ignore
const trackingFn = result.current[fn];
const trackingFn = result.current[fn.name];
await trackingFn({ conversationId: '123', invokedBy: 'shortcut' });
// @ts-ignore
const trackingMockedFn = mockedTelemetry[fn];
expect(trackingMockedFn).toHaveBeenCalledWith({
const trackingMockedFn = mockedTelemetry.reportEvent;
expect(trackingMockedFn).toHaveBeenCalledWith(fn.eventType, {
conversationId: 'Custom',
invokedBy: 'shortcut',
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,13 @@ import { type AssistantTelemetry } from '@kbn/elastic-assistant';
import { useCallback } from 'react';
import { useKibana } from '../../common/lib/kibana';
import { useBaseConversations } from '../use_conversation_store';

import type {
ReportAssistantInvokedParams,
ReportAssistantMessageSentParams,
ReportAssistantQuickPromptParams,
ReportAssistantSettingToggledParams,
} from '../../common/lib/telemetry';
import { AssistantEventTypes } from '../../common/lib/telemetry';
export const useAssistantTelemetry = (): AssistantTelemetry => {
const {
services: { telemetry },
Expand All @@ -27,27 +33,30 @@ export const useAssistantTelemetry = (): AssistantTelemetry => {

const reportTelemetry = useCallback(
async ({
fn,
eventType,
params: { conversationId, ...rest },
}: // eslint-disable-next-line @typescript-eslint/no-explicit-any
any): Promise<{
fn: keyof AssistantTelemetry;
params: AssistantTelemetry[keyof AssistantTelemetry];
}> =>
fn({
}: {
eventType: AssistantEventTypes;
params:
| ReportAssistantInvokedParams
| ReportAssistantMessageSentParams
| ReportAssistantQuickPromptParams;
}) =>
telemetry.reportEvent(eventType, {
...rest,
conversationId: await getAnonymizedConversationTitle(conversationId),
}),
[getAnonymizedConversationTitle]
[getAnonymizedConversationTitle, telemetry]
);

return {
reportAssistantInvoked: (params) =>
reportTelemetry({ fn: telemetry.reportAssistantInvoked, params }),
reportAssistantMessageSent: (params) =>
reportTelemetry({ fn: telemetry.reportAssistantMessageSent, params }),
reportAssistantQuickPrompt: (params) =>
reportTelemetry({ fn: telemetry.reportAssistantQuickPrompt, params }),
reportAssistantSettingToggled: (params) => telemetry.reportAssistantSettingToggled(params),
reportAssistantInvoked: (params: ReportAssistantInvokedParams) =>
reportTelemetry({ eventType: AssistantEventTypes.AssistantInvoked, params }),
reportAssistantMessageSent: (params: ReportAssistantMessageSentParams) =>
reportTelemetry({ eventType: AssistantEventTypes.AssistantMessageSent, params }),
reportAssistantQuickPrompt: (params: ReportAssistantQuickPromptParams) =>
reportTelemetry({ eventType: AssistantEventTypes.AssistantQuickPrompt, params }),
reportAssistantSettingToggled: (params: ReportAssistantSettingToggledParams) =>
telemetry.reportEvent(AssistantEventTypes.AssistantSettingToggled, params),
};
};
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import * as timelineMarkdownPlugin from '../../common/components/markdown_editor
import { useFetchAlertData } from './use_fetch_alert_data';
import { useUpsellingMessage } from '../../common/hooks/use_upselling';
import { useFetchNotes } from '../../notes/hooks/use_fetch_notes';
import { DocumentEventTypes } from '../../common/lib/telemetry';

const CaseContainerComponent: React.FC = () => {
const { cases, telemetry } = useKibana().services;
Expand All @@ -47,7 +48,7 @@ const CaseContainerComponent: React.FC = () => {
},
},
});
telemetry.reportDetailsFlyoutOpened({
telemetry.reportEvent(DocumentEventTypes.DetailsFlyoutOpened, {
location: TimelineId.casePage,
panel: 'right',
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import type { ColumnHeaderOptions, OnRowSelected } from '../../../../../common/t
import { useIsExperimentalFeatureEnabled } from '../../../hooks/use_experimental_features';
import { useTourContext } from '../../guided_onboarding_tour';
import { AlertsCasesTourSteps, SecurityStepId } from '../../guided_onboarding_tour/tour_config';
import { NotesEventTypes, DocumentEventTypes } from '../../../lib/telemetry';
import { getMappedNonEcsValue } from '../../../utils/get_mapped_non_ecs_value';

export type RowActionProps = EuiDataGridCellValueElementProps & {
Expand Down Expand Up @@ -109,7 +110,7 @@ const RowActionComponent = ({
},
},
});
telemetry.reportDetailsFlyoutOpened({
telemetry.reportEvent(DocumentEventTypes.DetailsFlyoutOpened, {
location: tableId,
panel: 'right',
});
Expand Down Expand Up @@ -137,10 +138,10 @@ const RowActionComponent = ({
},
},
});
telemetry.reportOpenNoteInExpandableFlyoutClicked({
telemetry.reportEvent(NotesEventTypes.OpenNoteInExpandableFlyoutClicked, {
location: tableId,
});
telemetry.reportDetailsFlyoutOpened({
telemetry.reportEvent(DocumentEventTypes.DetailsFlyoutOpened, {
location: tableId,
panel: 'left',
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ import {
import type { HostsTableType } from '../../../explore/hosts/store/model';
import type { UsersTableType } from '../../../explore/users/store/model';
import { useGetSecuritySolutionLinkProps, withSecuritySolutionLink } from './link_props';
import { EntityEventTypes } from '../../lib/telemetry';

export { useSecuritySolutionLinkProps, type GetSecuritySolutionLinkProps } from './link_props';
export { LinkButton, LinkAnchor } from './helpers';
Expand Down Expand Up @@ -94,7 +95,7 @@ const UserDetailsLinkComponent: React.FC<{

const onClick = useCallback(
(e: SyntheticEvent) => {
telemetry.reportEntityDetailsClicked({ entity: 'user' });
telemetry.reportEvent(EntityEventTypes.EntityDetailsClicked, { entity: 'user' });
const callback = onClickParam ?? goToUsersDetails;
callback(e);
},
Expand Down Expand Up @@ -171,7 +172,7 @@ const HostDetailsLinkComponent: React.FC<HostDetailsLinkProps> = ({

const onClick = useCallback(
(e: SyntheticEvent) => {
telemetry.reportEntityDetailsClicked({ entity: 'host' });
telemetry.reportEvent(EntityEventTypes.EntityDetailsClicked, { entity: 'host' });

const callback = onClickParam ?? goToHostDetails;
callback(e);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import { TestProviders } from '../../../mock';

import type { SecurityJob } from '../types';
import { createTelemetryServiceMock } from '../../../lib/telemetry/telemetry_service.mock';
import { ML_JOB_TELEMETRY_STATUS } from '../../../lib/telemetry';
import { ML_JOB_TELEMETRY_STATUS, EntityEventTypes } from '../../../lib/telemetry';

const wrapper = ({ children }: { children: React.ReactNode }) => (
<TestProviders>{children}</TestProviders>
Expand Down Expand Up @@ -188,14 +188,14 @@ describe('useSecurityJobsHelpers', () => {
await result.current.enableDatafeed(JOB, TIMESTAMP);
});

expect(mockedTelemetry.reportMLJobUpdate).toHaveBeenCalledWith({
expect(mockedTelemetry.reportEvent).toHaveBeenCalledWith(EntityEventTypes.MLJobUpdate, {
status: ML_JOB_TELEMETRY_STATUS.moduleInstalled,
isElasticJob: true,
jobId,
moduleId,
});

expect(mockedTelemetry.reportMLJobUpdate).toHaveBeenCalledWith({
expect(mockedTelemetry.reportEvent).toHaveBeenCalledWith(EntityEventTypes.MLJobUpdate, {
status: ML_JOB_TELEMETRY_STATUS.started,
isElasticJob: true,
jobId,
Expand All @@ -211,7 +211,7 @@ describe('useSecurityJobsHelpers', () => {
await result.current.enableDatafeed({ ...JOB, isInstalled: true }, TIMESTAMP);
});

expect(mockedTelemetry.reportMLJobUpdate).toHaveBeenCalledWith({
expect(mockedTelemetry.reportEvent).toHaveBeenCalledWith(EntityEventTypes.MLJobUpdate, {
status: ML_JOB_TELEMETRY_STATUS.startError,
errorMessage: 'Start job failure - test_error',
isElasticJob: true,
Expand All @@ -228,7 +228,7 @@ describe('useSecurityJobsHelpers', () => {
await result.current.enableDatafeed(JOB, TIMESTAMP);
});

expect(mockedTelemetry.reportMLJobUpdate).toHaveBeenCalledWith({
expect(mockedTelemetry.reportEvent).toHaveBeenCalledWith(EntityEventTypes.MLJobUpdate, {
status: ML_JOB_TELEMETRY_STATUS.installationError,
errorMessage: 'Create job failure - test_error',
isElasticJob: true,
Expand Down Expand Up @@ -295,7 +295,7 @@ describe('useSecurityJobsHelpers', () => {
await result.current.disableDatafeed({ ...JOB, isInstalled: true });
});

expect(mockedTelemetry.reportMLJobUpdate).toHaveBeenCalledWith({
expect(mockedTelemetry.reportEvent).toHaveBeenCalledWith(EntityEventTypes.MLJobUpdate, {
status: ML_JOB_TELEMETRY_STATUS.stopped,
isElasticJob: true,
jobId,
Expand All @@ -311,7 +311,7 @@ describe('useSecurityJobsHelpers', () => {
await result.current.disableDatafeed({ ...JOB, isInstalled: true });
});

expect(mockedTelemetry.reportMLJobUpdate).toHaveBeenCalledWith({
expect(mockedTelemetry.reportEvent).toHaveBeenCalledWith(EntityEventTypes.MLJobUpdate, {
status: ML_JOB_TELEMETRY_STATUS.stopError,
errorMessage: 'Stop job failure - test_error',
isElasticJob: true,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {
METRIC_TYPE,
ML_JOB_TELEMETRY_STATUS,
TELEMETRY_EVENT,
EntityEventTypes,
track,
} from '../../../lib/telemetry';

Expand Down Expand Up @@ -43,7 +44,7 @@ export const useEnableDataFeed = () => {
jobIdErrorFilter: [job.id],
groups: job.groups,
});
telemetry.reportMLJobUpdate({
telemetry.reportEvent(EntityEventTypes.MLJobUpdate, {
jobId: job.id,
isElasticJob: job.isElasticJob,
moduleId: job.moduleId,
Expand All @@ -52,7 +53,7 @@ export const useEnableDataFeed = () => {
} catch (error) {
setIsLoading(false);
addError(error, { title: i18n.CREATE_JOB_FAILURE });
telemetry.reportMLJobUpdate({
telemetry.reportEvent(EntityEventTypes.MLJobUpdate, {
jobId: job.id,
isElasticJob: job.isElasticJob,
moduleId: job.moduleId,
Expand Down Expand Up @@ -82,7 +83,7 @@ export const useEnableDataFeed = () => {
throw new Error(response[datafeedId].error);
}

telemetry.reportMLJobUpdate({
telemetry.reportEvent(EntityEventTypes.MLJobUpdate, {
jobId: job.id,
isElasticJob: job.isElasticJob,
status: ML_JOB_TELEMETRY_STATUS.started,
Expand All @@ -92,7 +93,7 @@ export const useEnableDataFeed = () => {
} catch (error) {
track(METRIC_TYPE.COUNT, TELEMETRY_EVENT.JOB_ENABLE_FAILURE);
addError(error, { title: i18n.START_JOB_FAILURE });
telemetry.reportMLJobUpdate({
telemetry.reportEvent(EntityEventTypes.MLJobUpdate, {
jobId: job.id,
isElasticJob: job.isElasticJob,
status: ML_JOB_TELEMETRY_STATUS.startError,
Expand Down Expand Up @@ -124,7 +125,7 @@ export const useEnableDataFeed = () => {
throw new Error(response.error);
}

telemetry.reportMLJobUpdate({
telemetry.reportEvent(EntityEventTypes.MLJobUpdate, {
jobId: job.id,
isElasticJob: job.isElasticJob,
status: ML_JOB_TELEMETRY_STATUS.stopped,
Expand All @@ -134,7 +135,7 @@ export const useEnableDataFeed = () => {
} catch (error) {
track(METRIC_TYPE.COUNT, TELEMETRY_EVENT.JOB_DISABLE_FAILURE);
addError(error, { title: i18n.STOP_JOB_FAILURE });
telemetry.reportMLJobUpdate({
telemetry.reportEvent(EntityEventTypes.MLJobUpdate, {
jobId: job.id,
isElasticJob: job.isElasticJob,
status: ML_JOB_TELEMETRY_STATUS.stopError,
Expand Down
Loading

0 comments on commit ee0934b

Please sign in to comment.