Browse Source

feat(perf): Add avg to Txn Duration Breakdown widget (#53174)

We've had a number of requests internally and externally to add `avg()`
to the Transaction Summary page's Duration Breakdown widget, alongside
the existing percentile options. Add `avg()` as an option, but make it
unselected by default.

Unlike the percentile functions, `avg()` doesn't have
`transaction.duration` as its default argument: it must be passed
explicitly. Updated the widget to pass this argument by default, but
strip it back out before the results are displayed to avoid cluttering
the widget.
Matt Quinn 1 year ago
parent
commit
4bd6934f1b

+ 9 - 9
static/app/components/events/interfaces/performance/spanEvidenceKeyValueList.spec.tsx

@@ -60,7 +60,7 @@ describe('SpanEvidenceKeyValueList', () => {
         screen.getByTestId('span-evidence-key-value-list.transaction').querySelector('a')
       ).toHaveAttribute(
         'href',
-        `/organizations/org-slug/performance/summary/?project=123&referrer=performance-transaction-summary&transaction=%2F&unselectedSeries=p100%28%29`
+        `/organizations/org-slug/performance/summary/?project=123&referrer=performance-transaction-summary&transaction=%2F&unselectedSeries=p100%28%29&unselectedSeries=avg%28%29`
       );
       expect(
         screen.getByRole('button', {
@@ -132,7 +132,7 @@ describe('SpanEvidenceKeyValueList', () => {
         screen.getByTestId('span-evidence-key-value-list.transaction').querySelector('a')
       ).toHaveAttribute(
         'href',
-        `/organizations/org-slug/performance/summary/?project=123&referrer=performance-transaction-summary&transaction=%2F&unselectedSeries=p100%28%29`
+        `/organizations/org-slug/performance/summary/?project=123&referrer=performance-transaction-summary&transaction=%2F&unselectedSeries=p100%28%29&unselectedSeries=avg%28%29`
       );
       expect(
         screen.getByRole('button', {
@@ -204,7 +204,7 @@ describe('SpanEvidenceKeyValueList', () => {
         screen.getByTestId('span-evidence-key-value-list.transaction').querySelector('a')
       ).toHaveAttribute(
         'href',
-        `/organizations/org-slug/performance/summary/?project=123&referrer=performance-transaction-summary&transaction=%2F&unselectedSeries=p100%28%29`
+        `/organizations/org-slug/performance/summary/?project=123&referrer=performance-transaction-summary&transaction=%2F&unselectedSeries=p100%28%29&unselectedSeries=avg%28%29`
       );
       expect(
         screen.getByRole('button', {
@@ -286,7 +286,7 @@ describe('SpanEvidenceKeyValueList', () => {
         screen.getByTestId('span-evidence-key-value-list.transaction').querySelector('a')
       ).toHaveAttribute(
         'href',
-        `/organizations/org-slug/performance/summary/?project=123&referrer=performance-transaction-summary&transaction=%2F&unselectedSeries=p100%28%29`
+        `/organizations/org-slug/performance/summary/?project=123&referrer=performance-transaction-summary&transaction=%2F&unselectedSeries=p100%28%29&unselectedSeries=avg%28%29`
       );
       expect(
         screen.getByRole('button', {
@@ -428,7 +428,7 @@ describe('SpanEvidenceKeyValueList', () => {
         screen.getByTestId('span-evidence-key-value-list.transaction').querySelector('a')
       ).toHaveAttribute(
         'href',
-        `/organizations/org-slug/performance/summary/?project=123&referrer=performance-transaction-summary&transaction=%2F&unselectedSeries=p100%28%29`
+        `/organizations/org-slug/performance/summary/?project=123&referrer=performance-transaction-summary&transaction=%2F&unselectedSeries=p100%28%29&unselectedSeries=avg%28%29`
       );
       expect(
         screen.getByRole('button', {
@@ -579,7 +579,7 @@ describe('SpanEvidenceKeyValueList', () => {
         screen.getByTestId('span-evidence-key-value-list.transaction').querySelector('a')
       ).toHaveAttribute(
         'href',
-        `/organizations/org-slug/performance/summary/?project=123&referrer=performance-transaction-summary&transaction=%2F&unselectedSeries=p100%28%29`
+        `/organizations/org-slug/performance/summary/?project=123&referrer=performance-transaction-summary&transaction=%2F&unselectedSeries=p100%28%29&unselectedSeries=avg%28%29`
       );
       expect(
         screen.getByRole('button', {
@@ -630,7 +630,7 @@ describe('SpanEvidenceKeyValueList', () => {
         screen.getByTestId('span-evidence-key-value-list.transaction').querySelector('a')
       ).toHaveAttribute(
         'href',
-        `/organizations/org-slug/performance/summary/?project=123&referrer=performance-transaction-summary&transaction=%2F&unselectedSeries=p100%28%29`
+        `/organizations/org-slug/performance/summary/?project=123&referrer=performance-transaction-summary&transaction=%2F&unselectedSeries=p100%28%29&unselectedSeries=avg%28%29`
       );
       expect(
         screen.getByRole('button', {
@@ -692,7 +692,7 @@ describe('SpanEvidenceKeyValueList', () => {
         screen.getByTestId('span-evidence-key-value-list.transaction').querySelector('a')
       ).toHaveAttribute(
         'href',
-        `/organizations/org-slug/performance/summary/?project=123&referrer=performance-transaction-summary&transaction=%2F&unselectedSeries=p100%28%29`
+        `/organizations/org-slug/performance/summary/?project=123&referrer=performance-transaction-summary&transaction=%2F&unselectedSeries=p100%28%29&unselectedSeries=avg%28%29`
       );
       expect(
         screen.getByRole('button', {
@@ -790,7 +790,7 @@ describe('SpanEvidenceKeyValueList', () => {
         screen.getByTestId('span-evidence-key-value-list.transaction').querySelector('a')
       ).toHaveAttribute(
         'href',
-        `/organizations/org-slug/performance/summary/?project=123&referrer=performance-transaction-summary&transaction=%2F&unselectedSeries=p100%28%29`
+        `/organizations/org-slug/performance/summary/?project=123&referrer=performance-transaction-summary&transaction=%2F&unselectedSeries=p100%28%29&unselectedSeries=avg%28%29`
       );
       expect(
         screen.getByRole('button', {

+ 1 - 1
static/app/views/performance/table.spec.tsx

@@ -210,7 +210,7 @@ describe('Performance > Table', function () {
       const link = within(transactionCell).getByRole('link', {name: '/apple/cart'});
       expect(link).toHaveAttribute(
         'href',
-        '/organizations/org-slug/performance/summary/?end=2019-10-02T00%3A00%3A00&project=2&query=&referrer=performance-transaction-summary&start=2019-10-01T00%3A00%3A00&statsPeriod=14d&transaction=%2Fapple%2Fcart&unselectedSeries=p100%28%29'
+        '/organizations/org-slug/performance/summary/?end=2019-10-02T00%3A00%3A00&project=2&query=&referrer=performance-transaction-summary&start=2019-10-01T00%3A00%3A00&statsPeriod=14d&transaction=%2Fapple%2Fcart&unselectedSeries=p100%28%29&unselectedSeries=avg%28%29'
       );
 
       const cellActionContainers = screen.getAllByTestId('cell-action-container');

+ 21 - 12
static/app/views/performance/transactionSummary/transactionOverview/durationChart/index.tsx

@@ -11,6 +11,7 @@ import QuestionTooltip from 'sentry/components/questionTooltip';
 import {t, tct} from 'sentry/locale';
 import {OrganizationSummary} from 'sentry/types';
 import {getUtcToLocalDateObject} from 'sentry/utils/dates';
+import {parseFunction} from 'sentry/utils/discover/fields';
 import useApi from 'sentry/utils/useApi';
 import {useLocation} from 'sentry/utils/useLocation';
 import useRouter from 'sentry/utils/useRouter';
@@ -31,7 +32,7 @@ type Props = ViewProps & {
   queryExtras?: Record<string, string>;
 };
 
-const yAxisValues = ['p50', 'p75', 'p95', 'p99', 'p100'];
+const yAxisValues = ['p50', 'p75', 'p95', 'p99', 'p100', 'avg'];
 
 /**
  * Fetch and render a stacked area chart that shows duration percentiles over
@@ -107,7 +108,8 @@ function DurationChart({
     interval: getInterval(datetimeSelection, 'high'),
   };
 
-  const parameter = SPAN_OPERATION_BREAKDOWN_FILTER_TO_FIELD[currentFilter] ?? '';
+  const parameter =
+    SPAN_OPERATION_BREAKDOWN_FILTER_TO_FIELD[currentFilter] ?? 'transaction.duration';
 
   const header = (
     <HeaderTitleLegend>
@@ -142,16 +144,23 @@ function DurationChart({
         referrer="api.performance.transaction-summary.duration-chart"
         queryExtras={queryExtras}
       >
-        {({results, errored, loading, reloading, timeframe: timeFrame}) => (
-          <Content
-            series={results}
-            errored={errored}
-            loading={loading}
-            reloading={reloading}
-            timeFrame={timeFrame}
-            {...contentCommonProps}
-          />
-        )}
+        {({results, errored, loading, reloading, timeframe: timeFrame}) => {
+          const stripParamsForLegend = seriesResults =>
+            seriesResults?.map(series => ({
+              ...series,
+              seriesName: `${parseFunction(series.seriesName)?.name}()`,
+            }));
+          return (
+            <Content
+              series={stripParamsForLegend(results)}
+              errored={errored}
+              loading={loading}
+              reloading={reloading}
+              timeFrame={timeFrame}
+              {...contentCommonProps}
+            />
+          );
+        }}
       </EventsRequest>
     </Fragment>
   );

+ 8 - 1
static/app/views/performance/transactionSummary/transactionOverview/index.spec.tsx

@@ -1089,7 +1089,14 @@ describe('Performance > TransactionSummary', function () {
               'transaction.op:pageload event.type:transaction transaction:/performance',
             referrer: 'api.performance.transaction-summary.duration-chart',
             statsPeriod: '14d',
-            yAxis: ['p50()', 'p75()', 'p95()', 'p99()', 'p100()'],
+            yAxis: [
+              'p50(transaction.duration)',
+              'p75(transaction.duration)',
+              'p95(transaction.duration)',
+              'p99(transaction.duration)',
+              'p100(transaction.duration)',
+              'avg(transaction.duration)',
+            ],
           }),
         })
       );

+ 1 - 1
static/app/views/performance/transactionSummary/utils.tsx

@@ -67,7 +67,7 @@ export function transactionSummaryRouteWithQuery({
   transaction,
   projectID,
   query,
-  unselectedSeries = 'p100()',
+  unselectedSeries = ['p100()', 'avg()'],
   display,
   trendFunction,
   trendColumn,

+ 1 - 1
static/app/views/performance/trends/index.spec.tsx

@@ -338,7 +338,7 @@ describe('Performance > Trends', function () {
 
     expect(summaryLink.closest('a')).toHaveAttribute(
       'href',
-      '/organizations/org-slug/performance/summary/?display=trend&project=1&query=tpm%28%29%3A%3E0.01%20transaction.duration%3A%3E0%20transaction.duration%3A%3C15min%20count_percentage%28%29%3A%3E0.25%20count_percentage%28%29%3A%3C4%20trend_percentage%28%29%3A%3E0%25%20confidence%28%29%3A%3E6&referrer=performance-transaction-summary&statsPeriod=14d&transaction=%2Forganizations%2F%3AorgId%2Fperformance%2F&trendFunction=p50&unselectedSeries=p100%28%29'
+      '/organizations/org-slug/performance/summary/?display=trend&project=1&query=tpm%28%29%3A%3E0.01%20transaction.duration%3A%3E0%20transaction.duration%3A%3C15min%20count_percentage%28%29%3A%3E0.25%20count_percentage%28%29%3A%3C4%20trend_percentage%28%29%3A%3E0%25%20confidence%28%29%3A%3E6&referrer=performance-transaction-summary&statsPeriod=14d&transaction=%2Forganizations%2F%3AorgId%2Fperformance%2F&trendFunction=p50&unselectedSeries=p100%28%29&unselectedSeries=avg%28%29'
     );
   });
 

+ 2 - 2
static/app/views/performance/vitalDetail/index.spec.tsx

@@ -310,7 +310,7 @@ describe('Performance > VitalDetail', function () {
         end: undefined,
         query: 'sometag:value has:measurements.lcp',
         referrer: 'performance-transaction-summary',
-        unselectedSeries: 'p100()',
+        unselectedSeries: ['p100()', 'avg()'],
         showTransactions: 'recent',
         display: 'vitals',
         trendFunction: undefined,
@@ -362,7 +362,7 @@ describe('Performance > VitalDetail', function () {
         end: undefined,
         query: 'anothertag:value has:measurements.cls',
         referrer: 'performance-transaction-summary',
-        unselectedSeries: 'p100()',
+        unselectedSeries: ['p100()', 'avg()'],
         showTransactions: 'recent',
         display: 'vitals',
         trendFunction: undefined,