diff --git a/static/app/utils/analytics/monitorsAnalyticsEvents.tsx b/static/app/utils/analytics/monitorsAnalyticsEvents.tsx index cb16961358bd38..15b1ebc5ad7088 100644 --- a/static/app/utils/analytics/monitorsAnalyticsEvents.tsx +++ b/static/app/utils/analytics/monitorsAnalyticsEvents.tsx @@ -1,5 +1,8 @@ import type {Organization} from 'sentry/types/organization'; -import {getAutomationAnalyticsPayload} from 'sentry/views/automations/components/forms/common/getAutomationAnalyticsPayload'; +import type {getAutomationAnalyticsPayload} from 'sentry/views/automations/components/forms/common/getAutomationAnalyticsPayload'; +import type {getDetectorAnalyticsPayload} from 'sentry/views/detectors/components/forms/common/getDetectorAnalyticsPayload'; + +type DetectorAnalyticsEventPayload = ReturnType; type AutomationAnalyticsEventPayload = ReturnType; @@ -14,12 +17,16 @@ export type MonitorsEventParameters = { guide: string; platform: string; }; + 'monitor.created': DetectorAnalyticsEventPayload; + 'monitor.updated': DetectorAnalyticsEventPayload; }; type MonitorsAnalyticsKey = keyof MonitorsEventParameters; export const monitorsEventMap: Record = { 'landing_page.platform_guide.viewed': 'Crons Landing Page: Viewed Platform Guide', + 'monitor.created': 'Detectors: Created', + 'monitor.updated': 'Detectors: Updated', 'automation.created': 'Automations: Created', 'automation.updated': 'Automations: Updated', }; diff --git a/static/app/views/detectors/components/forms/common/getDetectorAnalyticsPayload.ts b/static/app/views/detectors/components/forms/common/getDetectorAnalyticsPayload.ts new file mode 100644 index 00000000000000..36feb6b4ac48ee --- /dev/null +++ b/static/app/views/detectors/components/forms/common/getDetectorAnalyticsPayload.ts @@ -0,0 +1,63 @@ +import type { + CronDetector, + Detector, + MetricDetector, + SnubaQuery, + UptimeDetector, +} from 'sentry/types/workflowEngine/detectors'; +import type {MonitorConfig} from 'sentry/views/insights/crons/types'; + +type MetricDetectorAnalytics = { + detector_type: MetricDetector['type']; + aggregate?: SnubaQuery['aggregate']; + dataset?: SnubaQuery['dataset']; +}; + +type UptimeDetectorAnalytics = { + detector_type: UptimeDetector['type']; + uptime_mode: UptimeDetector['config']['mode']; +}; + +type MonitorDetectorAnalytics = { + cron_schedule_type: MonitorConfig['schedule_type'] | undefined; + detector_type: CronDetector['type']; +}; + +type ErrorDetectorAnalytics = { + detector_type: Extract; +}; + +type DetectorAnalyticsPayload = + | MetricDetectorAnalytics + | UptimeDetectorAnalytics + | MonitorDetectorAnalytics + | ErrorDetectorAnalytics; + +export function getDetectorAnalyticsPayload( + detector: Detector +): DetectorAnalyticsPayload { + switch (detector.type) { + case 'metric_issue': { + const snubaQuery = detector.dataSources[0]?.queryObj?.snubaQuery; + return { + detector_type: detector.type, + aggregate: snubaQuery?.aggregate, + dataset: snubaQuery?.dataset, + }; + } + case 'uptime_domain_failure': + return { + detector_type: detector.type, + uptime_mode: detector.config.mode, + }; + case 'monitor_check_in_failure': { + const monitorConfig = detector.dataSources[0]?.queryObj?.config; + return { + cron_schedule_type: monitorConfig?.schedule_type, + detector_type: detector.type, + }; + } + default: + return {detector_type: detector.type}; + } +} diff --git a/static/app/views/detectors/hooks/useCreateDetectorFormSubmit.tsx b/static/app/views/detectors/hooks/useCreateDetectorFormSubmit.tsx index c8110fd571991a..b335ca7459937a 100644 --- a/static/app/views/detectors/hooks/useCreateDetectorFormSubmit.tsx +++ b/static/app/views/detectors/hooks/useCreateDetectorFormSubmit.tsx @@ -7,8 +7,10 @@ import type { BaseDetectorUpdatePayload, Detector, } from 'sentry/types/workflowEngine/detectors'; +import {trackAnalytics} from 'sentry/utils/analytics'; import {useNavigate} from 'sentry/utils/useNavigate'; import useOrganization from 'sentry/utils/useOrganization'; +import {getDetectorAnalyticsPayload} from 'sentry/views/detectors/components/forms/common/getDetectorAnalyticsPayload'; import {useCreateDetector} from 'sentry/views/detectors/hooks'; import {makeMonitorDetailsPathname} from 'sentry/views/detectors/pathnames'; @@ -44,6 +46,11 @@ export function useCreateDetectorFormSubmit< const payload = formDataToEndpointPayload(data as TFormData); const resultDetector = await createDetector(payload); + trackAnalytics('monitor.created', { + organization, + ...getDetectorAnalyticsPayload(resultDetector), + }); + addSuccessMessage(t('Monitor created successfully')); if (onSuccess) { @@ -66,7 +73,7 @@ export function useCreateDetectorFormSubmit< [ formDataToEndpointPayload, createDetector, - organization.slug, + organization, navigate, onSuccess, onError, diff --git a/static/app/views/detectors/hooks/useEditDetectorFormSubmit.tsx b/static/app/views/detectors/hooks/useEditDetectorFormSubmit.tsx index 42131fed22edef..c91cd4a54d5839 100644 --- a/static/app/views/detectors/hooks/useEditDetectorFormSubmit.tsx +++ b/static/app/views/detectors/hooks/useEditDetectorFormSubmit.tsx @@ -7,8 +7,10 @@ import type { BaseDetectorUpdatePayload, Detector, } from 'sentry/types/workflowEngine/detectors'; +import {trackAnalytics} from 'sentry/utils/analytics'; import {useNavigate} from 'sentry/utils/useNavigate'; import useOrganization from 'sentry/utils/useOrganization'; +import {getDetectorAnalyticsPayload} from 'sentry/views/detectors/components/forms/common/getDetectorAnalyticsPayload'; import {useUpdateDetector} from 'sentry/views/detectors/hooks'; import {makeMonitorDetailsPathname} from 'sentry/views/detectors/pathnames'; @@ -52,6 +54,11 @@ export function useEditDetectorFormSubmit< const resultDetector = await updateDetector(updatedData); + trackAnalytics('monitor.updated', { + organization, + ...getDetectorAnalyticsPayload(resultDetector), + }); + addSuccessMessage(t('Monitor updated successfully')); if (onSuccess) { @@ -75,7 +82,7 @@ export function useEditDetectorFormSubmit< detector, formDataToEndpointPayload, updateDetector, - organization.slug, + organization, navigate, onSuccess, onError,