Browse Source

feat(ddm): analytics tracking (#59775)

Ogi 1 year ago
parent
commit
5c878bc643

+ 3 - 0
static/app/utils/analytics.tsx

@@ -3,6 +3,7 @@ import {Transaction} from '@sentry/types';
 
 import HookStore from 'sentry/stores/hookStore';
 import {Hooks} from 'sentry/types/hooks';
+import {ddmEventMap, DDMEventParameters} from 'sentry/utils/analytics/ddmAnalyticsEvents';
 
 import {
   aiSuggestedSolutionEventMap,
@@ -77,6 +78,7 @@ interface EventParameters
   extends GrowthEventParameters,
     CoreUIEventParameters,
     DashboardsEventParameters,
+    DDMEventParameters,
     DiscoverEventParameters,
     IssueEventParameters,
     MonitorsEventParameters,
@@ -100,6 +102,7 @@ interface EventParameters
 const allEventMap: Record<string, string | null> = {
   ...coreUIEventMap,
   ...dashboardsEventMap,
+  ...ddmEventMap,
   ...discoverEventMap,
   ...growthEventMap,
   ...issueEventMap,

+ 31 - 0
static/app/utils/analytics/ddmAnalyticsEvents.tsx

@@ -0,0 +1,31 @@
+export type DDMEventParameters = {
+  'ddm.page-view': {
+    organization: string;
+  };
+  'ddm.scratchpad.remove': {
+    organization: string;
+  };
+  'ddm.scratchpad.save': {
+    organization: string;
+  };
+  'ddm.scratchpad.set-default': {
+    organization: string;
+  };
+  'ddm.widget.add': {
+    organization: string;
+  };
+  'ddm.widget.sort': {
+    by: string;
+    order: string;
+    organization: string;
+  };
+};
+
+export const ddmEventMap: Record<keyof DDMEventParameters, string> = {
+  'ddm.page-view': 'DDM: Page View',
+  'ddm.scratchpad.remove': 'DDM: Scratchpad Removed',
+  'ddm.scratchpad.save': 'DDM: Scratchpad Saved',
+  'ddm.scratchpad.set-default': 'DDM: Scratchpad Set as Default',
+  'ddm.widget.add': 'DDM: Widget Added',
+  'ddm.widget.sort': 'DDM: Group By Sort Changed',
+};

+ 9 - 0
static/app/views/ddm/ddm.tsx

@@ -1,3 +1,4 @@
+import {useEffect} from 'react';
 import styled from '@emotion/styled';
 
 import FeatureBadge from 'sentry/components/featureBadge';
@@ -12,6 +13,7 @@ import {PageHeadingQuestionTooltip} from 'sentry/components/pageHeadingQuestionT
 import SentryDocumentTitle from 'sentry/components/sentryDocumentTitle';
 import {t} from 'sentry/locale';
 import {space} from 'sentry/styles/space';
+import {trackAnalytics} from 'sentry/utils/analytics';
 import useOrganization from 'sentry/utils/useOrganization';
 import {MetricScratchpad} from 'sentry/views/ddm/scratchpad';
 import {ScratchpadSelector} from 'sentry/views/ddm/scratchpadSelector';
@@ -20,6 +22,13 @@ import {TraceTable} from 'sentry/views/ddm/traceTable';
 function DDM() {
   const organization = useOrganization();
 
+  useEffect(() => {
+    trackAnalytics('ddm.page-view', {
+      organization: organization.slug,
+    });
+    // eslint-disable-next-line react-hooks/exhaustive-deps
+  }, []);
+
   return (
     <SentryDocumentTitle title={t('DDM')} orgSlug={organization.slug}>
       <PageFiltersContainer disablePersistence>

+ 12 - 1
static/app/views/ddm/scratchpad.tsx

@@ -5,6 +5,8 @@ import {Button} from 'sentry/components/button';
 import Panel from 'sentry/components/panels/panel';
 import {IconAdd} from 'sentry/icons';
 import {space} from 'sentry/styles/space';
+import {trackAnalytics} from 'sentry/utils/analytics';
+import useOrganization from 'sentry/utils/useOrganization';
 import usePageFilters from 'sentry/utils/usePageFilters';
 import {DDM_CHART_GROUP, MIN_WIDGET_WIDTH} from 'sentry/views/ddm/constants';
 
@@ -13,6 +15,7 @@ import {MetricWidget, useMetricWidgets} from './widget';
 export function MetricScratchpad() {
   const {widgets, onChange, addWidget} = useMetricWidgets();
   const {selection} = usePageFilters();
+  const organization = useOrganization();
 
   const Wrapper =
     widgets.length === 1 ? StyledSingleWidgetWrapper : StyledMetricDashboard;
@@ -35,7 +38,15 @@ export function MetricScratchpad() {
           environments={selection.environments}
         />
       ))}
-      <AddWidgetPanel onClick={addWidget}>
+      <AddWidgetPanel
+        onClick={() => {
+          trackAnalytics('ddm.widget.add', {
+            organization: organization.slug,
+          });
+
+          addWidget();
+        }}
+      >
         <Button icon={<IconAdd isCircled />}>Add widget</Button>
       </AddWidgetPanel>
     </Wrapper>

+ 21 - 3
static/app/views/ddm/scratchpadSelector.tsx

@@ -15,6 +15,7 @@ import {Tooltip} from 'sentry/components/tooltip';
 import {IconBookmark, IconDelete, IconStar} from 'sentry/icons';
 import {t} from 'sentry/locale';
 import {space} from 'sentry/styles/space';
+import {trackAnalytics} from 'sentry/utils/analytics';
 import {clearQuery, updateQuery} from 'sentry/utils/metrics';
 import useKeyPress from 'sentry/utils/useKeyPress';
 import {useLocalStorageState} from 'sentry/utils/useLocalStorageState';
@@ -158,6 +159,7 @@ export function useScratchpads() {
 
 export function ScratchpadSelector() {
   const scratchpads = useScratchpads();
+  const organization = useOrganization();
 
   const isDefault = useCallback(
     scratchpad => scratchpads.default === scratchpad.id,
@@ -183,6 +185,10 @@ export function ScratchpadSelector() {
                 borderless
                 onPointerDown={e => e.stopPropagation()}
                 onClick={() => {
+                  trackAnalytics('ddm.scratchpad.set-default', {
+                    organization: organization.slug,
+                  });
+
                   if (isDefault(s)) {
                     scratchpads.setDefault(null);
                   } else {
@@ -202,7 +208,13 @@ export function ScratchpadSelector() {
                 onPointerDown={e => e.stopPropagation()}
                 onClick={() => {
                   openConfirmModal({
-                    onConfirm: () => scratchpads.remove(s.id),
+                    onConfirm: () => {
+                      trackAnalytics('ddm.scratchpad.remove', {
+                        organization: organization.slug,
+                      });
+
+                      return scratchpads.remove(s.id);
+                    },
                     message: t('Are you sure you want to delete this scratchpad?'),
                     confirmText: t('Delete'),
                   });
@@ -216,7 +228,7 @@ export function ScratchpadSelector() {
           </Fragment>
         ),
       })),
-    [scratchpads, isDefault]
+    [scratchpads, isDefault, organization.slug]
   );
 
   return (
@@ -260,11 +272,17 @@ function SaveAsDropdown({
   const theme = useTheme();
   const [name, setName] = useState('');
 
+  const organization = useOrganization();
+
   const save = useCallback(() => {
+    trackAnalytics('ddm.scratchpad.save', {
+      organization: organization.slug,
+    });
+
     onSave(name);
     setOpen(false);
     setName('');
-  }, [name, onSave, setOpen]);
+  }, [name, onSave, setOpen, organization]);
 
   const enterKeyPressed = useKeyPress('Enter');
 

+ 7 - 1
static/app/views/ddm/summaryTable.tsx

@@ -8,6 +8,7 @@ import {Tooltip} from 'sentry/components/tooltip';
 import {IconArrow, IconLightning, IconReleases} from 'sentry/icons';
 import {t} from 'sentry/locale';
 import {space} from 'sentry/styles/space';
+import {trackAnalytics} from 'sentry/utils/analytics';
 import {getUtcDateString} from 'sentry/utils/dates';
 import {formatMetricsUsingUnitAndOp, parseMRI} from 'sentry/utils/metrics';
 import useOrganization from 'sentry/utils/useOrganization';
@@ -46,6 +47,11 @@ export function SummaryTable({
 
   const changeSort = useCallback(
     (name: SortState['name']) => {
+      trackAnalytics('ddm.widget.sort', {
+        organization: slug,
+        by: name,
+        order: sort.order,
+      });
       if (sort.name === name) {
         if (sort.order === 'desc') {
           onSortChange(DEFAULT_SORT_STATE as SortState);
@@ -67,7 +73,7 @@ export function SummaryTable({
         });
       }
     },
-    [sort, onSortChange]
+    [sort, onSortChange, slug]
   );
 
   const releaseTo = (release: string) => {