Browse Source

feat(discover): Add referrers to the events-stats endpoint (#28848)

* feat(discover): Add referrers to the events-stats endpoint

- This adds an allow list of referrers to the events-stats endpoint so
  we can differentiate the performance between the different parts of
  the sentry product
William Mak 3 years ago
parent
commit
97dec91237

+ 28 - 1
src/sentry/api/endpoints/organization_events_stats.py

@@ -6,6 +6,26 @@ from sentry.api.bases import OrganizationEventsV2EndpointBase
 from sentry.constants import MAX_TOP_EVENTS
 from sentry.snuba import discover
 
+ALLOWED_EVENTS_STATS_REFERRERS = {
+    "api.alerts.alert-rule-chart",
+    "api.dashboards.widget.area-chart",
+    "api.dashboards.widget.bar-chart",
+    "api.dashboards.widget.line-chart",
+    "api.dashboards.top-events",
+    "api.discover.prebuilt-chart",
+    "api.discover.previous-chart",
+    "api.discover.default-chart",
+    "api.discover.daily-chart",
+    "api.discover.top5-chart",
+    "api.discover.dailytop5-chart",
+    "api.performance.homepage.duration-chart",
+    "api.performance.transaction-summary.sidebar-chart",
+    "api.performance.transaction-summary.vitals-chart",
+    "api.performance.transaction-summary.trends-chart",
+    "api.performance.transaction-summary.duration",
+    "api.releases.release-details-chart",
+}
+
 
 class OrganizationEventsStatsEndpoint(OrganizationEventsV2EndpointBase):
     def has_chart_interpolation(self, organization, request):
@@ -45,6 +65,13 @@ class OrganizationEventsStatsEndpoint(OrganizationEventsV2EndpointBase):
             # the start of the bucket does not align with the rollup.
             allow_partial_buckets = request.GET.get("partial") == "1"
 
+            referrer = request.GET.get("referrer")
+            referrer = (
+                referrer
+                if referrer in ALLOWED_EVENTS_STATS_REFERRERS
+                else "api.organization-event-stats"
+            )
+
         def get_event_stats(query_columns, query, params, rollup, zerofill_results):
             if top_events > 0:
                 return discover.top_events_timeseries(
@@ -57,7 +84,7 @@ class OrganizationEventsStatsEndpoint(OrganizationEventsV2EndpointBase):
                     rollup=rollup,
                     limit=top_events,
                     organization=organization,
-                    referrer="api.organization-event-stats.find-topn",
+                    referrer=referrer + ".find-topn",
                     allow_empty=False,
                     zerofill_results=zerofill_results,
                     include_other=self.has_top_events(organization, request),

+ 3 - 0
static/app/actionCreators/events.tsx

@@ -31,6 +31,7 @@ type Options = {
   orderby?: string;
   partial: boolean;
   withoutZerofill?: boolean;
+  referrer?: string;
 };
 
 /**
@@ -67,6 +68,7 @@ export const doEventsRequest = (
     orderby,
     partial,
     withoutZerofill,
+    referrer,
   }: Options
 ): Promise<EventsStats | MultiSeriesEventsStats> => {
   const shouldDoublePeriod = canIncludePreviousPeriod(includePrevious, period);
@@ -83,6 +85,7 @@ export const doEventsRequest = (
       orderby,
       partial: partial ? '1' : undefined,
       withoutZerofill: withoutZerofill ? '1' : undefined,
+      referrer: referrer ? referrer : 'api.organization-event-stats',
     }).filter(([, value]) => typeof value !== 'undefined')
   );
 

+ 5 - 0
static/app/components/charts/eventsChart.tsx

@@ -66,6 +66,7 @@ type ChartProps = {
   height?: number;
   timeframe?: {start: number; end: number};
   topEvents?: number;
+  referrer?: string;
 };
 
 type State = {
@@ -371,6 +372,10 @@ export type EventsChartProps = {
    * Name of the previous series
    */
   previousSeriesName?: string;
+  /**
+   * A unique name for what's triggering this request, see organization_events_stats for an allowlist
+   */
+  referrer?: string;
 } & Pick<
   ChartProps,
   | 'seriesTransformer'

+ 4 - 0
static/app/components/charts/eventsRequest.tsx

@@ -163,6 +163,10 @@ type EventsRequestPartialProps = {
    * Whether or not to zerofill results
    */
   withoutZerofill?: boolean;
+  /**
+   * A unique name for what's triggering this request, see organization_events_stats for an allowlist
+   */
+  referrer?: string;
 };
 
 type TimeAggregationProps =

+ 1 - 0
static/app/views/alerts/rules/details/metricChart.tsx

@@ -450,6 +450,7 @@ class MetricChart extends React.PureComponent<Props, State> {
         includePrevious={false}
         currentSeriesName={rule.aggregate}
         partial={false}
+        referrer="api.alerts.alert-rule-chart"
       >
         {({loading, timeseriesData}) => {
           if (loading || !timeseriesData) {

+ 5 - 5
static/app/views/dashboardsV2/widgetQueries.tsx

@@ -26,7 +26,7 @@ import {
 } from 'app/utils/discover/genericDiscoverQuery';
 import {TOP_N} from 'app/utils/discover/types';
 
-import {Widget, WidgetQuery} from './types';
+import {DisplayType, Widget, WidgetQuery} from './types';
 import {eventViewFromWidget} from './utils';
 
 // Don't fetch more than 4000 bins as we're plotting on a small area.
@@ -274,7 +274,7 @@ class WidgetQueries extends React.Component<Props, State> {
     });
   }
 
-  fetchTimeseriesData(queryFetchID: symbol) {
+  fetchTimeseriesData(queryFetchID: symbol, displayType: DisplayType) {
     const {selection, api, organization, widget} = this.props;
     this.setState({timeseriesResults: [], rawResults: []});
 
@@ -299,7 +299,7 @@ class WidgetQueries extends React.Component<Props, State> {
           query: query.conditions,
           yAxis: getAggregateFields(query.fields)[0],
           includePrevious: false,
-          referrer: 'api.dashboards.top_5',
+          referrer: `api.dashboards.widget.${displayType}-chart`,
           partial: true,
           topEvents: TOP_N,
           field: query.fields,
@@ -320,7 +320,7 @@ class WidgetQueries extends React.Component<Props, State> {
           yAxis: query.fields,
           orderby: query.orderby,
           includePrevious: false,
-          referrer: 'api.dashboards.timeserieswidget',
+          referrer: `api.dashboards.widget.${displayType}-chart`,
           partial: true,
         };
       }
@@ -376,7 +376,7 @@ class WidgetQueries extends React.Component<Props, State> {
     if (['table', 'world_map', 'big_number'].includes(widget.displayType)) {
       this.fetchEventData(queryFetchID);
     } else {
-      this.fetchTimeseriesData(queryFetchID);
+      this.fetchTimeseriesData(queryFetchID, widget.displayType);
     }
   }
 

+ 3 - 1
static/app/views/eventsV2/miniGraph.tsx

@@ -30,6 +30,7 @@ type Props = {
   eventView: EventView;
   api: Client;
   location: Location;
+  referrer?: string;
 };
 
 class MiniGraph extends React.Component<Props> {
@@ -124,7 +125,7 @@ class MiniGraph extends React.Component<Props> {
   }
 
   render() {
-    const {theme, api} = this.props;
+    const {theme, api, referrer} = this.props;
     const {
       query,
       start,
@@ -161,6 +162,7 @@ class MiniGraph extends React.Component<Props> {
         orderby={orderby}
         expired={expired}
         name={name}
+        referrer={referrer}
         partial
       >
         {({loading, timeseriesData, results, errored}) => {

+ 3 - 0
static/app/views/eventsV2/queryList.tsx

@@ -169,6 +169,7 @@ class QueryList extends React.Component<Props> {
               location={location}
               eventView={eventView}
               organization={organization}
+              referrer="api.discover.homepage.prebuilt"
             />
           )}
           onEventClick={() => {
@@ -224,6 +225,7 @@ class QueryList extends React.Component<Props> {
 
       const to = eventView.getResultsViewShortUrlTarget(organization.slug);
       const dateStatus = <TimeSince date={savedQuery.dateUpdated} />;
+      const referrer = `api.discover.${eventView.getDisplayMode()}-chart`;
 
       return (
         <QueryCard
@@ -246,6 +248,7 @@ class QueryList extends React.Component<Props> {
               location={location}
               eventView={eventView}
               organization={organization}
+              referrer={referrer}
             />
           )}
           renderContextMenu={() => (

+ 2 - 0
static/app/views/eventsV2/resultsChart.tsx

@@ -71,6 +71,7 @@ class ResultsChart extends Component<ResultsChartProps> {
     const isPeriod = display === DisplayModes.DEFAULT || display === DisplayModes.TOP5;
     const isDaily = display === DisplayModes.DAILYTOP5 || display === DisplayModes.DAILY;
     const isPrevious = display === DisplayModes.PREVIOUS;
+    const referrer = `api.discover.${display}-chart`;
 
     return (
       <Fragment>
@@ -101,6 +102,7 @@ class ResultsChart extends Component<ResultsChartProps> {
               chartComponent={
                 hasConnectDiscoverAndDashboards && !isDaily ? AreaChart : undefined
               }
+              referrer={referrer}
             />
           ),
           fixed: <Placeholder height="200px" testId="skeleton-ui" />,

+ 1 - 0
static/app/views/performance/landing/chart/durationChart.tsx

@@ -87,6 +87,7 @@ function DurationChart(props: Props) {
       yAxis={[field, ..._backupField]}
       partial
       hideError
+      referrer="api.performance.homepage.duration-chart"
     >
       {({
         loading,

Some files were not shown because too many files changed in this diff