Browse Source

feat(insights): Adds alerts to insights webvitals module charts. (#77268)

Adds alerts to insights webvitals module charts
Also fix pageoverview chart not receiving geo and browser filters
edwardgou-sentry 6 months ago
parent
commit
5fe7729750

+ 6 - 0
static/app/views/alerts/rules/metric/utils/isInsightsMetricAlert.tsx

@@ -59,6 +59,12 @@ export const INSIGHTS_METRICS = [
   'g:spans/mobile.slow_frames@none',
   'c:spans/ai.total_tokens.used@none',
   'c:spans/ai.total_cost@usd',
+  'd:transactions/measurements.score.lcp@ratio',
+  'd:transactions/measurements.score.fcp@ratio',
+  'd:transactions/measurements.score.cls@ratio',
+  'd:transactions/measurements.score.ttfb@ratio',
+  'd:transactions/measurements.score.inp@ratio',
+  'd:transactions/measurements.score.total@ratio',
 ];
 
 export const isInsightsMetricAlert = (aggregate: string) => {

+ 34 - 0
static/app/views/insights/browser/webVitals/alerts.ts

@@ -0,0 +1,34 @@
+import type {AlertConfig} from 'sentry/views/insights/common/components/chartPanel';
+
+export const ALERTS: Record<string, AlertConfig> = {
+  lcp: {
+    aggregate: 'performance_score(d:transactions/measurements.score.lcp@ratio)',
+    query: 'has:measurements.score.total',
+    name: 'Create LCP Score Alert',
+  },
+  fcp: {
+    aggregate: 'performance_score(measurements.score.fcp)',
+    query: 'has:measurements.score.total',
+    name: 'Create FCP Score Alert',
+  },
+  cls: {
+    aggregate: 'performance_score(measurements.score.cls)',
+    query: 'has:measurements.score.total',
+    name: 'Create CLS Score Alert',
+  },
+  ttfb: {
+    aggregate: 'performance_score(measurements.score.ttfb)',
+    query: 'has:measurements.score.total',
+    name: 'Create TTFB Score Alert',
+  },
+  inp: {
+    aggregate: 'performance_score(measurements.score.inp)',
+    query: 'has:measurements.score.total',
+    name: 'Create INP Score Alert',
+  },
+  total: {
+    aggregate: 'performance_score(measurements.score.total)',
+    query: 'has:measurements.score.total',
+    name: 'Create Total Score Alert',
+  },
+};

+ 24 - 17
static/app/views/insights/browser/webVitals/components/charts/performanceScoreBreakdownChart.tsx

@@ -5,17 +5,21 @@ import {DEFAULT_RELATIVE_PERIODS} from 'sentry/constants';
 import {t} from 'sentry/locale';
 import {space} from 'sentry/styles/space';
 import type {Series} from 'sentry/types/echarts';
+import {MutableSearch} from 'sentry/utils/tokenizeSearch';
 import usePageFilters from 'sentry/utils/usePageFilters';
+import {ALERTS} from 'sentry/views/insights/browser/webVitals/alerts';
 import {ORDER} from 'sentry/views/insights/browser/webVitals/components/charts/performanceScoreChart';
 import {
   useProjectWebVitalsScoresTimeseriesQuery,
   type WebVitalsScoreBreakdown,
 } from 'sentry/views/insights/browser/webVitals/queries/storedScoreQueries/useProjectWebVitalsScoresTimeseriesQuery';
+import {DEFAULT_QUERY_FILTER} from 'sentry/views/insights/browser/webVitals/settings';
 import {applyStaticWeightsToTimeseries} from 'sentry/views/insights/browser/webVitals/utils/applyStaticWeightsToTimeseries';
 import type {BrowserType} from 'sentry/views/insights/browser/webVitals/utils/queryParameterDecoders/browserType';
 import {PERFORMANCE_SCORE_WEIGHTS} from 'sentry/views/insights/browser/webVitals/utils/scoreThresholds';
 import Chart, {ChartType} from 'sentry/views/insights/common/components/chart';
-import type {SubregionCode} from 'sentry/views/insights/types';
+import ChartPanel from 'sentry/views/insights/common/components/chartPanel';
+import {SpanMetricsField, type SubregionCode} from 'sentry/views/insights/types';
 
 type Props = {
   browserTypes?: BrowserType[];
@@ -90,9 +94,24 @@ export function PerformanceScoreBreakdownChart({
     return {name, value};
   });
 
+  // We need to reproduce the same query filters that were used to fetch the timeseries data so that they can be propagated to the alerts
+  const search = new MutableSearch(ALERTS.total.query ?? '');
+  if (transaction) {
+    search.addFilterValue('transaction', transaction);
+  }
+  if (subregions) {
+    search.addDisjunctionFilterValues(SpanMetricsField.USER_GEO_SUBREGION, subregions);
+  }
+  if (browserTypes) {
+    search.addDisjunctionFilterValues(SpanMetricsField.BROWSER_NAME, browserTypes);
+  }
+  const query = [DEFAULT_QUERY_FILTER, search.formatString()].join(' ').trim();
+
   return (
-    <ChartContainer>
-      <PerformanceScoreLabel>{t('Score Breakdown')}</PerformanceScoreLabel>
+    <StyledChartPanel
+      title={t('Score Breakdown')}
+      alertConfigs={Object.values(ALERTS).map(alertConfig => ({...alertConfig, query}))}
+    >
       <PerformanceScoreSubtext>{performanceScoreSubtext}</PerformanceScoreSubtext>
       <Chart
         stacked
@@ -135,24 +154,12 @@ export function PerformanceScoreBreakdownChart({
           },
         }}
       />
-    </ChartContainer>
+    </StyledChartPanel>
   );
 }
 
-const ChartContainer = styled('div')`
-  padding: ${space(2)} ${space(2)} ${space(1)} ${space(2)};
+const StyledChartPanel = styled(ChartPanel)`
   flex: 1;
-  border: 1px solid ${p => p.theme.gray200};
-  border-radius: ${p => p.theme.borderRadius};
-  position: relative;
-  min-width: 320px;
-`;
-
-const PerformanceScoreLabel = styled('div')`
-  width: 100%;
-  font-size: ${p => p.theme.fontSizeLarge};
-  color: ${p => p.theme.textColor};
-  font-weight: ${p => p.theme.fontWeightBold};
 `;
 
 const PerformanceScoreSubtext = styled('div')`

+ 5 - 1
static/app/views/insights/browser/webVitals/views/pageOverview.tsx

@@ -200,7 +200,11 @@ export function PageOverview() {
                 <SubregionSelector />
               </TopMenuContainer>
               <Flex>
-                <PerformanceScoreBreakdownChart transaction={transaction} />
+                <PerformanceScoreBreakdownChart
+                  transaction={transaction}
+                  browserTypes={browserTypes}
+                  subregions={subregions}
+                />
               </Flex>
               <WebVitalMetersContainer>
                 <WebVitalMeters