Browse Source

feat(perf): Add response code class rate columns to HTTP module landing page (#66753)

NOTE: The _typing_ for this is a little awkward, since the field types
don't know how to handle a function with parameters. For now I added
types for all the arguments that I know are in use. I'll come back and
clean this up once it gets a notch more complicated.
George Gritsouk 1 year ago
parent
commit
4274beecaf

+ 1 - 1
static/app/utils/discover/fields.tsx

@@ -1103,7 +1103,7 @@ export function aggregateFunctionOutputType(
     return STARFISH_FIELDS[firstArg].outputType;
   }
 
-  if (!firstArg && STARFISH_AGGREGATION_FIELDS[funcName]) {
+  if (STARFISH_AGGREGATION_FIELDS[funcName]) {
     return STARFISH_AGGREGATION_FIELDS[funcName].defaultOutputType;
   }
 

+ 28 - 1
static/app/views/performance/http/domainsTable.tsx

@@ -25,13 +25,22 @@ type Row = Pick<
   | 'project.id'
   | 'span.domain'
   | 'spm()'
+  | 'http_response_rate(2)'
+  | 'http_response_rate(4)'
+  | 'http_response_rate(5)'
   | 'avg(span.self_time)'
   | 'sum(span.self_time)'
   | 'time_spent_percentage()'
 >;
 
 type Column = GridColumnHeader<
-  'span.domain' | 'spm()' | 'avg(span.self_time)' | 'time_spent_percentage()'
+  | 'span.domain'
+  | 'spm()'
+  | 'http_response_rate(2)'
+  | 'http_response_rate(4)'
+  | 'http_response_rate(5)'
+  | 'avg(span.self_time)'
+  | 'time_spent_percentage()'
 >;
 
 const COLUMN_ORDER: Column[] = [
@@ -45,6 +54,21 @@ const COLUMN_ORDER: Column[] = [
     name: `${t('Requests')} ${RATE_UNIT_TITLE[RateUnit.PER_MINUTE]}`,
     width: COL_WIDTH_UNDEFINED,
   },
+  {
+    key: `http_response_rate(2)`,
+    name: t('2XXs'),
+    width: 50,
+  },
+  {
+    key: `http_response_rate(4)`,
+    name: t('4XXs'),
+    width: 50,
+  },
+  {
+    key: `http_response_rate(5)`,
+    name: t('5XXs'),
+    width: 50,
+  },
   {
     key: `avg(span.self_time)`,
     name: DataTitles.avg,
@@ -60,6 +84,9 @@ const COLUMN_ORDER: Column[] = [
 const SORTABLE_FIELDS = [
   'avg(span.self_time)',
   'spm()',
+  'http_response_rate(2)',
+  'http_response_rate(4)',
+  'http_response_rate(5)',
   'time_spent_percentage()',
 ] as const;
 

+ 3 - 0
static/app/views/performance/http/httpLandingPage.spec.tsx

@@ -148,6 +148,9 @@ describe('HTTPLandingPage', function () {
             'project.id',
             'span.domain',
             'spm()',
+            'http_response_rate(2)',
+            'http_response_rate(4)',
+            'http_response_rate(5)',
             'avg(span.self_time)',
             'sum(span.self_time)',
             'time_spent_percentage()',

+ 3 - 0
static/app/views/performance/http/httpLandingPage.tsx

@@ -73,6 +73,9 @@ export function HTTPLandingPage() {
       'project.id',
       'span.domain',
       'spm()',
+      'http_response_rate(2)',
+      'http_response_rate(4)',
+      'http_response_rate(5)',
       'avg(span.self_time)',
       'sum(span.self_time)',
       'time_spent_percentage()',

+ 5 - 1
static/app/views/starfish/components/tableCells/renderHeadCell.tsx

@@ -26,7 +26,8 @@ type Options = {
 const DEFAULT_SORT_PARAMETER_NAME = 'sort';
 
 const {SPAN_SELF_TIME, HTTP_RESPONSE_CONTENT_LENGTH} = SpanMetricsField;
-const {TIME_SPENT_PERCENTAGE, SPS, SPM, HTTP_ERROR_COUNT} = SpanFunction;
+const {TIME_SPENT_PERCENTAGE, SPS, SPM, HTTP_ERROR_COUNT, HTTP_RESPONSE_RATE} =
+  SpanFunction;
 
 export const SORTABLE_FIELDS = new Set([
   `avg(${SPAN_SELF_TIME})`,
@@ -39,6 +40,9 @@ export const SORTABLE_FIELDS = new Set([
   `${SPM}()`,
   `${TIME_SPENT_PERCENTAGE}()`,
   `${HTTP_ERROR_COUNT}()`,
+  `${HTTP_RESPONSE_RATE}(2)`,
+  `${HTTP_RESPONSE_RATE}(4)`,
+  `${HTTP_RESPONSE_RATE}(5)`,
   `avg(${HTTP_RESPONSE_CONTENT_LENGTH})`,
 ]);
 

+ 14 - 0
static/app/views/starfish/types.tsx

@@ -78,6 +78,7 @@ export const SPAN_FUNCTIONS = [
   'spm',
   'count',
   'time_spent_percentage',
+  'http_response_rate',
   'http_error_count',
 ] as const;
 
@@ -91,6 +92,12 @@ export type MetricsResponse = {
   [Property in SpanStringFields as `${Property}`]: string;
 } & {
   [Property in SpanStringArrayFields as `${Property}`]: string[];
+} & {
+  // TODO: This should include all valid HTTP codes or just all integers
+  'http_response_rate(2)': number;
+  'http_response_rate(3)': number;
+  'http_response_rate(4)': number;
+  'http_response_rate(5)': number;
 } & {
   ['project.id']: number;
 };
@@ -166,6 +173,7 @@ export enum SpanFunction {
   SPM = 'spm',
   TIME_SPENT_PERCENTAGE = 'time_spent_percentage',
   HTTP_ERROR_COUNT = 'http_error_count',
+  HTTP_RESPONSE_RATE = 'http_response_rate',
 }
 
 export const StarfishDatasetFields = {
@@ -201,4 +209,10 @@ export const STARFISH_AGGREGATION_FIELDS: Record<
     kind: FieldKind.FUNCTION,
     valueType: FieldValueType.NUMBER,
   },
+  [SpanFunction.HTTP_RESPONSE_RATE]: {
+    desc: t('Percentage of HTTP responses by code'),
+    defaultOutputType: 'percentage',
+    kind: FieldKind.FUNCTION,
+    valueType: FieldValueType.NUMBER,
+  },
 };