Browse Source

feat(perf): Add analytics to transaction summary and subpages (#35581)

Ash Anand 2 years ago
parent
commit
038dc1b8f8

+ 24 - 0
static/app/utils/analytics/performanceAnalyticsEvents.tsx

@@ -10,6 +10,7 @@ type PerformanceTourParams = {
 };
 };
 
 
 export type PerformanceEventParameters = {
 export type PerformanceEventParameters = {
+  'performance_views.all_events.open_in_discover': {};
   'performance_views.create_sample_transaction': SampleTransactionParam;
   'performance_views.create_sample_transaction': SampleTransactionParam;
   'performance_views.landingv2.transactions.sort': {
   'performance_views.landingv2.transactions.sort': {
     direction?: string;
     direction?: string;
@@ -52,6 +53,12 @@ export type PerformanceEventParameters = {
   'performance_views.spans.change_sort': {
   'performance_views.spans.change_sort': {
     sort_column?: string;
     sort_column?: string;
   };
   };
+  'performance_views.tags.change_tag': {
+    from_tag: string;
+    is_other_tag: boolean;
+    to_tag: string;
+  };
+  'performance_views.tags.jump_to_release': {};
   'performance_views.team_key_transaction.set': {
   'performance_views.team_key_transaction.set': {
     action: string;
     action: string;
   };
   };
@@ -59,6 +66,13 @@ export type PerformanceEventParameters = {
   'performance_views.tour.close': PerformanceTourParams;
   'performance_views.tour.close': PerformanceTourParams;
   'performance_views.tour.start': {};
   'performance_views.tour.start': {};
   'performance_views.trace_view.view': {};
   'performance_views.trace_view.view': {};
+  'performance_views.transaction_summary.change_chart_display': {
+    from_chart: string;
+    to_chart: string;
+  };
+  'performance_views.transaction_summary.status_breakdown_click': {
+    status: string;
+  };
   'performance_views.trends.change_duration': {
   'performance_views.trends.change_duration': {
     value: string;
     value: string;
     widget_type: string;
     widget_type: string;
@@ -102,6 +116,16 @@ export const performanceEventMap: Record<PerformanceEventKey, string | null> = {
   'performance_views.overview.search': 'Performance Views: Transaction overview search',
   'performance_views.overview.search': 'Performance Views: Transaction overview search',
   'performance_views.vital_detail.view': 'Performance Views: Vital Detail viewed',
   'performance_views.vital_detail.view': 'Performance Views: Vital Detail viewed',
   'performance_views.trace_view.view': 'Performance Views: Trace View viewed',
   'performance_views.trace_view.view': 'Performance Views: Trace View viewed',
+  'performance_views.transaction_summary.change_chart_display':
+    'Performance Views: Transaction Summary chart display changed',
+  'performance_views.transaction_summary.status_breakdown_click':
+    'Performance Views: Transaction Summary status breakdown option clicked',
+  'performance_views.all_events.open_in_discover':
+    'Performance Views: All Events page open in Discover button clicked',
+  'performance_views.tags.change_tag':
+    'Performance Views: Tags Page changed selected tag',
+  'performance_views.tags.jump_to_release':
+    'Performance Views: Tags Page link to release in table clicked',
   'performance_views.team_key_transaction.set':
   'performance_views.team_key_transaction.set':
     'Performance Views: Set Team Key Transaction',
     'Performance Views: Set Team Key Transaction',
   'performance_views.trends.widget_interaction':
   'performance_views.trends.widget_interaction':

+ 11 - 1
static/app/views/performance/transactionSummary/transactionEvents/content.tsx

@@ -14,6 +14,7 @@ import {normalizeDateTimeParams} from 'sentry/components/organizations/pageFilte
 import {t} from 'sentry/locale';
 import {t} from 'sentry/locale';
 import space from 'sentry/styles/space';
 import space from 'sentry/styles/space';
 import {Organization} from 'sentry/types';
 import {Organization} from 'sentry/types';
+import trackAdvancedAnalyticsEvent from 'sentry/utils/analytics/trackAdvancedAnalyticsEvent';
 import EventView from 'sentry/utils/discover/eventView';
 import EventView from 'sentry/utils/discover/eventView';
 import {WebVital} from 'sentry/utils/discover/fields';
 import {WebVital} from 'sentry/utils/discover/fields';
 import {decodeScalar} from 'sentry/utils/queryString';
 import {decodeScalar} from 'sentry/utils/queryString';
@@ -127,6 +128,12 @@ function Search(props: Props) {
     percentileValues
     percentileValues
   );
   );
 
 
+  const handleDiscoverButtonClick = () => {
+    trackAdvancedAnalyticsEvent('performance_views.all_events.open_in_discover', {
+      organization,
+    });
+  };
+
   return (
   return (
     <FilterActions>
     <FilterActions>
       <Filter
       <Filter
@@ -163,7 +170,10 @@ function Search(props: Props) {
           );
           );
         })}
         })}
       </DropdownControl>
       </DropdownControl>
-      <Button to={eventView.getResultsViewUrlTarget(organization.slug)}>
+      <Button
+        to={eventView.getResultsViewUrlTarget(organization.slug)}
+        onClick={handleDiscoverButtonClick}
+      >
         {t('Open in Discover')}
         {t('Open in Discover')}
       </Button>
       </Button>
     </FilterActions>
     </FilterActions>

+ 13 - 2
static/app/views/performance/transactionSummary/transactionOverview/charts.tsx

@@ -12,7 +12,8 @@ import {
 import {Panel} from 'sentry/components/panels';
 import {Panel} from 'sentry/components/panels';
 import Placeholder from 'sentry/components/placeholder';
 import Placeholder from 'sentry/components/placeholder';
 import {t} from 'sentry/locale';
 import {t} from 'sentry/locale';
-import {OrganizationSummary, SelectValue} from 'sentry/types';
+import {Organization, SelectValue} from 'sentry/types';
+import trackAdvancedAnalyticsEvent from 'sentry/utils/analytics/trackAdvancedAnalyticsEvent';
 import EventView from 'sentry/utils/discover/eventView';
 import EventView from 'sentry/utils/discover/eventView';
 import {removeHistogramQueryStrings} from 'sentry/utils/performance/histogram';
 import {removeHistogramQueryStrings} from 'sentry/utils/performance/histogram';
 import {decodeScalar} from 'sentry/utils/queryString';
 import {decodeScalar} from 'sentry/utils/queryString';
@@ -73,7 +74,7 @@ type Props = {
   currentFilter: SpanOperationBreakdownFilter;
   currentFilter: SpanOperationBreakdownFilter;
   eventView: EventView;
   eventView: EventView;
   location: Location;
   location: Location;
-  organization: OrganizationSummary;
+  organization: Organization;
   totalValues: number | null;
   totalValues: number | null;
   withoutZerofill: boolean;
   withoutZerofill: boolean;
 };
 };
@@ -87,6 +88,16 @@ function TransactionSummaryCharts({
   withoutZerofill,
   withoutZerofill,
 }: Props) {
 }: Props) {
   function handleDisplayChange(value: string) {
   function handleDisplayChange(value: string) {
+    const display = decodeScalar(location.query.display, DisplayModes.DURATION);
+    trackAdvancedAnalyticsEvent(
+      'performance_views.transaction_summary.change_chart_display',
+      {
+        organization,
+        from_chart: display,
+        to_chart: value,
+      }
+    );
+
     browserHistory.push({
     browserHistory.push({
       pathname: location.pathname,
       pathname: location.pathname,
       query: {
       query: {

+ 9 - 0
static/app/views/performance/transactionSummary/transactionOverview/statusBreakdown.tsx

@@ -12,6 +12,7 @@ import QuestionTooltip from 'sentry/components/questionTooltip';
 import {IconWarning} from 'sentry/icons';
 import {IconWarning} from 'sentry/icons';
 import {t} from 'sentry/locale';
 import {t} from 'sentry/locale';
 import {Organization} from 'sentry/types';
 import {Organization} from 'sentry/types';
+import trackAdvancedAnalyticsEvent from 'sentry/utils/analytics/trackAdvancedAnalyticsEvent';
 import DiscoverQuery from 'sentry/utils/discover/discoverQuery';
 import DiscoverQuery from 'sentry/utils/discover/discoverQuery';
 import EventView from 'sentry/utils/discover/eventView';
 import EventView from 'sentry/utils/discover/eventView';
 import {MutableSearch} from 'sentry/utils/tokenizeSearch';
 import {MutableSearch} from 'sentry/utils/tokenizeSearch';
@@ -85,6 +86,14 @@ function StatusBreakdown({eventView, location, organization}: Props) {
                   query: query.formatString(),
                   query: query.formatString(),
                 },
                 },
               });
               });
+
+              trackAdvancedAnalyticsEvent(
+                'performance_views.transaction_summary.status_breakdown_click',
+                {
+                  organization,
+                  status: row['transaction.status'] as string,
+                }
+              );
             },
             },
           }));
           }));
           return <BreakdownBars data={points} />;
           return <BreakdownBars data={points} />;

+ 13 - 4
static/app/views/performance/transactionSummary/transactionTags/content.tsx

@@ -16,6 +16,7 @@ import Radio from 'sentry/components/radio';
 import {t} from 'sentry/locale';
 import {t} from 'sentry/locale';
 import space from 'sentry/styles/space';
 import space from 'sentry/styles/space';
 import {Organization, Project} from 'sentry/types';
 import {Organization, Project} from 'sentry/types';
+import trackAdvancedAnalyticsEvent from 'sentry/utils/analytics/trackAdvancedAnalyticsEvent';
 import EventView from 'sentry/utils/discover/eventView';
 import EventView from 'sentry/utils/discover/eventView';
 import SegmentExplorerQuery, {
 import SegmentExplorerQuery, {
   TableData,
   TableData,
@@ -122,6 +123,7 @@ const InnerContent = (
     if (initialTag) {
     if (initialTag) {
       changeTagSelected(initialTag);
       changeTagSelected(initialTag);
     }
     }
+    // eslint-disable-next-line react-hooks/exhaustive-deps
   }, [initialTag]);
   }, [initialTag]);
 
 
   const handleSearch = (query: string) => {
   const handleSearch = (query: string) => {
@@ -136,7 +138,14 @@ const InnerContent = (
     });
     });
   };
   };
 
 
-  const changeTag = (tag: string) => {
+  const changeTag = (tag: string, isOtherTag: boolean) => {
+    trackAdvancedAnalyticsEvent('performance_views.tags.change_tag', {
+      organization,
+      from_tag: tagSelected!,
+      to_tag: tag,
+      is_other_tag: isOtherTag,
+    });
+
     return changeTagSelected(tag);
     return changeTagSelected(tag);
   };
   };
   if (tagSelected) {
   if (tagSelected) {
@@ -175,7 +184,7 @@ const InnerContent = (
 };
 };
 
 
 const TagsSideBar = (props: {
 const TagsSideBar = (props: {
-  changeTag: (tag: string) => void;
+  changeTag: (tag: string, isOtherTag: boolean) => void;
   otherTags: TagOption[];
   otherTags: TagOption[];
   suspectTags: TagOption[];
   suspectTags: TagOption[];
   isLoading?: boolean;
   isLoading?: boolean;
@@ -202,7 +211,7 @@ const TagsSideBar = (props: {
             <Radio
             <Radio
               aria-label={tag}
               aria-label={tag}
               checked={tagSelected === tag}
               checked={tagSelected === tag}
-              onChange={() => changeTag(tag)}
+              onChange={() => changeTag(tag, false)}
             />
             />
             <SidebarTagValue className="truncate">{tag}</SidebarTagValue>
             <SidebarTagValue className="truncate">{tag}</SidebarTagValue>
           </RadioLabel>
           </RadioLabel>
@@ -231,7 +240,7 @@ const TagsSideBar = (props: {
             <Radio
             <Radio
               aria-label={tag}
               aria-label={tag}
               checked={tagSelected === tag}
               checked={tagSelected === tag}
-              onChange={() => changeTag(tag)}
+              onChange={() => changeTag(tag, true)}
             />
             />
             <SidebarTagValue className="truncate">{tag}</SidebarTagValue>
             <SidebarTagValue className="truncate">{tag}</SidebarTagValue>
           </RadioLabel>
           </RadioLabel>

+ 12 - 1
static/app/views/performance/transactionSummary/transactionTags/tagValueTable.tsx

@@ -15,6 +15,7 @@ import {IconAdd} from 'sentry/icons/iconAdd';
 import {t} from 'sentry/locale';
 import {t} from 'sentry/locale';
 import space from 'sentry/styles/space';
 import space from 'sentry/styles/space';
 import {Organization, Project} from 'sentry/types';
 import {Organization, Project} from 'sentry/types';
+import trackAdvancedAnalyticsEvent from 'sentry/utils/analytics/trackAdvancedAnalyticsEvent';
 import EventView from 'sentry/utils/discover/eventView';
 import EventView from 'sentry/utils/discover/eventView';
 import {fieldAlignment} from 'sentry/utils/discover/fields';
 import {fieldAlignment} from 'sentry/utils/discover/fields';
 import {formatPercentage} from 'sentry/utils/formatters';
 import {formatPercentage} from 'sentry/utils/formatters';
@@ -160,6 +161,13 @@ export class TagValueTable extends Component<Props, State> {
     };
     };
   };
   };
 
 
+  handleReleaseLinkClicked = () => {
+    const {organization} = this.props;
+    trackAdvancedAnalyticsEvent('performance_views.tags.jump_to_release', {
+      organization,
+    });
+  };
+
   renderBodyCell = (
   renderBodyCell = (
     parentProps: Props,
     parentProps: Props,
     column: TableColumn<TagsTableColumnKeys>,
     column: TableColumn<TagsTableColumnKeys>,
@@ -185,7 +193,10 @@ export class TagValueTable extends Component<Props, State> {
           allowActions={allowActions}
           allowActions={allowActions}
         >
         >
           {column.name === 'release' ? (
           {column.name === 'release' ? (
-            <Link to={this.generateReleaseLocation(dataRow.tags_value)}>
+            <Link
+              to={this.generateReleaseLocation(dataRow.tags_value)}
+              onClick={this.handleReleaseLinkClicked}
+            >
               <TagValue row={dataRow} />
               <TagValue row={dataRow} />
             </Link>
             </Link>
           ) : (
           ) : (