Skip to content

Commit 4169123

Browse files
Lead generation telemetry changes
1 parent c5d134c commit 4169123

8 files changed

Lines changed: 79 additions & 5 deletions

File tree

x-pack/solutions/security/plugins/security_solution/public/common/lib/telemetry/events/entity_analytics/index.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -423,6 +423,16 @@ const anomaliesCountClickedEvent: EntityAnalyticsTelemetryEvent = {
423423
},
424424
};
425425

426+
export const leadGenerationGenerateClickedEvent: EntityAnalyticsTelemetryEvent = {
427+
eventType: EntityEventTypes.LeadGenerationGenerateClicked,
428+
schema: {},
429+
};
430+
431+
export const leadGenerationLeadClickedEvent: EntityAnalyticsTelemetryEvent = {
432+
eventType: EntityEventTypes.LeadGenerationLeadClicked,
433+
schema: {},
434+
};
435+
426436
export const entityTelemetryEvents = [
427437
entityClickedEvent,
428438
entityAlertsClickedEvent,
@@ -440,4 +450,6 @@ export const entityTelemetryEvents = [
440450
addRiskInputToTimelineClickedEvent,
441451
mlJobUpdateEvent,
442452
anomaliesCountClickedEvent,
453+
leadGenerationGenerateClickedEvent,
454+
leadGenerationLeadClickedEvent,
443455
];

x-pack/solutions/security/plugins/security_solution/public/common/lib/telemetry/events/entity_analytics/types.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ export enum EntityEventTypes {
2626
PrivilegedUserMonitoringCsvImported = 'Privileged User Monitoring CSV Imported',
2727
AnomaliesCountClicked = 'Anomalies Count Clicked',
2828
MLJobUpdate = 'ML Job Update',
29+
LeadGenerationGenerateClicked = 'Lead Generation Generate Clicked',
30+
LeadGenerationLeadClicked = 'Lead Generation Lead Clicked',
2931
}
3032

3133
export enum ML_JOB_TELEMETRY_STATUS {
@@ -110,6 +112,11 @@ interface ReportMLJobUpdateParams {
110112
errorMessage?: string;
111113
}
112114

115+
// eslint-disable-next-line @typescript-eslint/no-empty-interface
116+
interface ReportLeadGenerationGenerateClickedParams {}
117+
// eslint-disable-next-line @typescript-eslint/no-empty-interface
118+
interface ReportLeadGenerationLeadClickedParams {}
119+
113120
export interface EntityAnalyticsTelemetryEventsMap {
114121
[EntityEventTypes.EntityDetailsClicked]: ReportEntityDetailsClickedParams;
115122
[EntityEventTypes.EntityAlertsClicked]: ReportEntityAlertsClickedParams;
@@ -128,6 +135,8 @@ export interface EntityAnalyticsTelemetryEventsMap {
128135
[EntityEventTypes.PrivilegedUserMonitoringCsvImported]: ReportAssetCriticalityCsvImportedParams;
129136
[EntityEventTypes.AnomaliesCountClicked]: ReportAnomaliesCountClickedParams;
130137
[EntityEventTypes.MLJobUpdate]: ReportMLJobUpdateParams;
138+
[EntityEventTypes.LeadGenerationGenerateClicked]: ReportLeadGenerationGenerateClickedParams;
139+
[EntityEventTypes.LeadGenerationLeadClicked]: ReportLeadGenerationLeadClickedParams;
131140
}
132141

133142
export interface EntityAnalyticsTelemetryEvent {

x-pack/solutions/security/plugins/security_solution/public/entity_analytics/components/threat_hunting/top_threat_hunting_leads/use_hunting_leads.ts

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,11 @@
55
* 2.0.
66
*/
77

8-
import { useRef, useEffect, useState } from 'react';
8+
import { useRef, useEffect, useState, useCallback } from 'react';
99
import { useQuery, useMutation, useQueryClient } from '@kbn/react-query';
1010
import { useAppToasts } from '../../../../common/hooks/use_app_toasts';
11+
import { useKibana } from '../../../../common/lib/kibana';
12+
import { EntityEventTypes } from '../../../../common/lib/telemetry';
1113
import { useEntityAnalyticsRoutes } from '../../../api/api';
1214
import { fromApiLead } from './types';
1315
import * as i18n from './translations';
@@ -39,6 +41,7 @@ export const useHuntingLeads = (isEnabled: boolean = true) => {
3941
} = useEntityAnalyticsRoutes();
4042
const queryClient = useQueryClient();
4143
const { addSuccess, addError } = useAppToasts();
44+
const { telemetry } = useKibana().services;
4245
const abortCtrl = useRef(new AbortController());
4346
const [hasGenerated, setHasGenerated] = useState(false);
4447

@@ -64,6 +67,7 @@ export const useHuntingLeads = (isEnabled: boolean = true) => {
6467
abortCtrl.current = new AbortController();
6568
const { signal } = abortCtrl.current;
6669

70+
telemetry.reportEvent(EntityEventTypes.LeadGenerationGenerateClicked, {});
6771
await generateLeadsApi({ params: {}, signal });
6872

6973
if (signal.aborted) return;
@@ -97,6 +101,10 @@ export const useHuntingLeads = (isEnabled: boolean = true) => {
97101

98102
const isLoading = isLeadsLoading || isStatusLoading;
99103

104+
const reportLeadClicked = useCallback(() => {
105+
telemetry.reportEvent(EntityEventTypes.LeadGenerationLeadClicked, {});
106+
}, [telemetry]);
107+
100108
return {
101109
leads: data?.leads?.map(fromApiLead) ?? [],
102110
totalCount: data?.total ?? 0,
@@ -108,5 +116,6 @@ export const useHuntingLeads = (isEnabled: boolean = true) => {
108116
refetch,
109117
isScheduled: statusData?.isEnabled ?? false,
110118
toggleSchedule,
119+
reportLeadClicked,
111120
};
112121
};

x-pack/solutions/security/plugins/security_solution/public/entity_analytics/pages/entity_analytics_home_page.tsx

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ export const EntityAnalyticsHomePage = () => {
7878
generate,
7979
isScheduled,
8080
toggleSchedule,
81+
reportLeadClicked,
8182
} = useHuntingLeads(leadGenerationEnabled);
8283
const openAgentBuilderWithLead = useLeadAttachment();
8384

@@ -131,8 +132,11 @@ export const EntityAnalyticsHomePage = () => {
131132
const handleCloseFlyout = useCallback(() => setIsFlyoutOpen(false), []);
132133

133134
const handleOpenLeadInChat = useCallback(
134-
(lead: HuntingLead) => openAgentBuilderWithLead(lead),
135-
[openAgentBuilderWithLead]
135+
(lead: HuntingLead) => {
136+
reportLeadClicked();
137+
openAgentBuilderWithLead(lead);
138+
},
139+
[openAgentBuilderWithLead, reportLeadClicked]
136140
);
137141

138142
const handleHuntInChat = useCallback(() => {

x-pack/solutions/security/plugins/security_solution/server/lib/entity_analytics/lead_generation/routes/generate_leads.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ export const generateLeadsRoute = (
5656
const executionUuid = uuidv4();
5757
const riskScoreDataClient = secSol.getRiskScoreDataClient();
5858

59-
const [, startPlugins] = await getStartServices();
59+
const [coreStart, startPlugins] = await getStartServices();
6060
const crudClient = startPlugins.entityStore.createCRUDClient(esClient, spaceId);
6161

6262
void (async () => {
@@ -69,6 +69,7 @@ export const generateLeadsRoute = (
6969
riskScoreDataClient,
7070
executionId: executionUuid,
7171
sourceType: 'adhoc',
72+
analytics: coreStart.analytics,
7273
});
7374
logger.info(
7475
`[LeadGeneration] Background generation completed (executionUuid=${executionUuid})`

x-pack/solutions/security/plugins/security_solution/server/lib/entity_analytics/lead_generation/run_pipeline.ts

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,10 @@
66
*/
77

88
import { v4 as uuidv4 } from 'uuid';
9-
import type { ElasticsearchClient, Logger } from '@kbn/core/server';
9+
import type { AnalyticsServiceStart, ElasticsearchClient, Logger } from '@kbn/core/server';
1010

1111
import type { LeadGenerationMode } from '../../../../common/entity_analytics/lead_generation/constants';
12+
import { LEAD_GENERATION_EXECUTION_EVENT } from '../../telemetry/event_based/events';
1213
import { getAlertsIndex } from '../../../../common/entity_analytics/utils';
1314
import { createLeadGenerationEngine } from './engine/lead_generation_engine';
1415
import { createRiskScoreModule } from './observation_modules/risk_score_module';
@@ -26,6 +27,7 @@ export interface RunPipelineParams {
2627
readonly riskScoreDataClient: RiskScoreDataClient;
2728
readonly executionId?: string;
2829
readonly sourceType: LeadGenerationMode;
30+
readonly analytics?: AnalyticsServiceStart;
2931
}
3032

3133
export interface RunPipelineResult {
@@ -44,6 +46,7 @@ export const runLeadGenerationPipeline = async ({
4446
riskScoreDataClient,
4547
executionId: providedExecutionId,
4648
sourceType,
49+
analytics,
4750
}: RunPipelineParams): Promise<RunPipelineResult> => {
4851
const executionId = providedExecutionId ?? uuidv4();
4952
const pipelineStart = Date.now();
@@ -109,5 +112,11 @@ export const runLeadGenerationPipeline = async ({
109112
}ms (executionId=${executionId})`
110113
);
111114

115+
analytics?.reportEvent(LEAD_GENERATION_EXECUTION_EVENT.eventType, {
116+
spaceId,
117+
leadsGenerated: leads.length,
118+
sourceType,
119+
});
120+
112121
return { total: leads.length };
113122
};

x-pack/solutions/security/plugins/security_solution/server/lib/entity_analytics/lead_generation/tasks/lead_generation_task.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,7 @@ const runLeadGenerationTask = async ({
185185
spaceId: state.namespace,
186186
riskScoreDataClient,
187187
sourceType: 'scheduled',
188+
analytics: core.analytics,
188189
});
189190
} catch (e) {
190191
logger.error(`[LeadGeneration] Error running scheduled lead generation task: ${e.message}`);

x-pack/solutions/security/plugins/security_solution/server/lib/telemetry/event_based/events.ts

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1859,6 +1859,34 @@ export const GAP_DETECTED_EVENT: EventTypeOpts<{
18591859
},
18601860
};
18611861

1862+
export const LEAD_GENERATION_EXECUTION_EVENT: EventTypeOpts<{
1863+
spaceId: string;
1864+
leadsGenerated: number;
1865+
sourceType: string;
1866+
}> = {
1867+
eventType: 'lead_generation_execution',
1868+
schema: {
1869+
spaceId: {
1870+
type: 'keyword',
1871+
_meta: {
1872+
description: 'Space ID where lead generation was run',
1873+
},
1874+
},
1875+
leadsGenerated: {
1876+
type: 'long',
1877+
_meta: {
1878+
description: 'Number of leads successfully generated',
1879+
},
1880+
},
1881+
sourceType: {
1882+
type: 'keyword',
1883+
_meta: {
1884+
description: 'How lead generation was triggered: "adhoc" or "scheduled"',
1885+
},
1886+
},
1887+
},
1888+
};
1889+
18621890
export const events = [
18631891
DETECTION_RULE_UPGRADE_EVENT,
18641892
DETECTION_RULE_BULK_UPGRADE_EVENT,
@@ -1896,4 +1924,5 @@ export const events = [
18961924
...SIEM_MIGRATIONS_EVENTS,
18971925
GAP_DETECTED_EVENT,
18981926
...TRIAL_COMPANION_EVENTS,
1927+
LEAD_GENERATION_EXECUTION_EVENT,
18991928
];

0 commit comments

Comments
 (0)