Browse Source

feat(starfish): Adds an operation breakdown column to endpoint overview sampled event table (#49961)

Adds an operation breakdown column to endpoint overview sampled event
table
edwardgou-sentry 1 year ago
parent
commit
7430d2ec5a

+ 54 - 1
static/app/views/starfish/components/samplesTable/transactionSamplesTable.tsx

@@ -1,12 +1,20 @@
+import {Fragment} from 'react';
+import styled from '@emotion/styled';
+
 import DateTime from 'sentry/components/dateTime';
 import Duration from 'sentry/components/duration';
 import GridEditable, {GridColumnHeader} from 'sentry/components/gridEditable';
 import Link from 'sentry/components/links/link';
+import QuestionTooltip from 'sentry/components/questionTooltip';
+import {t} from 'sentry/locale';
 import {NewQuery} from 'sentry/types';
 import EventView from 'sentry/utils/discover/eventView';
+import {getFieldRenderer} from 'sentry/utils/discover/fieldRenderers';
+import {SPAN_OP_RELATIVE_BREAKDOWN_FIELD} from 'sentry/utils/discover/fields';
 import {DiscoverDatasets} from 'sentry/utils/discover/types';
 import {MutableSearch} from 'sentry/utils/tokenizeSearch';
 import {useLocation} from 'sentry/utils/useLocation';
+import useOrganization from 'sentry/utils/useOrganization';
 import {DurationComparisonCell} from 'sentry/views/starfish/components/samplesTable/common';
 import useSlowMedianFastSamplesQuery from 'sentry/views/starfish/components/samplesTable/useSlowMedianFastSamplesQuery';
 import {
@@ -15,7 +23,13 @@ import {
   TextAlignRight,
 } from 'sentry/views/starfish/components/textAlign';
 
-type Keys = 'id' | 'profile_id' | 'timestamp' | 'transaction.duration' | 'p95_comparison';
+type Keys =
+  | 'id'
+  | 'profile_id'
+  | 'timestamp'
+  | 'transaction.duration'
+  | 'p95_comparison'
+  | 'span_ops_breakdown.relative';
 type TableColumnHeader = GridColumnHeader<Keys>;
 
 const COLUMN_ORDER: TableColumnHeader[] = [
@@ -29,6 +43,11 @@ const COLUMN_ORDER: TableColumnHeader[] = [
     name: 'Profile ID',
     width: 140,
   },
+  {
+    key: SPAN_OP_RELATIVE_BREAKDOWN_FIELD,
+    name: 'Operation Duration',
+    width: 200,
+  },
   {
     key: 'timestamp',
     name: 'Timestamp',
@@ -53,12 +72,18 @@ type Props = {
 type DataRow = {
   id: string;
   profile_id: string;
+  'spans.browser': number;
+  'spans.db': number;
+  'spans.http': number;
+  'spans.resource': number;
+  'spans.ui': number;
   timestamp: string;
   'transaction.duration': number;
 };
 
 export function TransactionSamplesTable({queryConditions}: Props) {
   const location = useLocation();
+  const organization = useOrganization();
   const query = new MutableSearch(queryConditions);
 
   const savedQuery: NewQuery = {
@@ -83,6 +108,21 @@ export function TransactionSamplesTable({queryConditions}: Props) {
       );
     }
 
+    if (column.key === SPAN_OP_RELATIVE_BREAKDOWN_FIELD) {
+      return (
+        <Fragment>
+          {column.name}
+          <StyledIconQuestion
+            size="xs"
+            position="top"
+            title={t(
+              `Span durations are summed over the course of an entire transaction. Any overlapping spans are only counted once.`
+            )}
+          />
+        </Fragment>
+      );
+    }
+
     return <OverflowEllipsisTextContainer>{column.name}</OverflowEllipsisTextContainer>;
   }
 
@@ -130,6 +170,14 @@ export function TransactionSamplesTable({queryConditions}: Props) {
       );
     }
 
+    if (column.key === SPAN_OP_RELATIVE_BREAKDOWN_FIELD) {
+      return getFieldRenderer(column.key, {})(row, {
+        location,
+        organization,
+        eventView,
+      });
+    }
+
     return <TextAlignLeft>{row[column.key]}</TextAlignLeft>;
   }
 
@@ -147,3 +195,8 @@ export function TransactionSamplesTable({queryConditions}: Props) {
     />
   );
 }
+
+const StyledIconQuestion = styled(QuestionTooltip)`
+  position: relative;
+  left: 4px;
+`;

+ 20 - 0
static/app/views/starfish/components/samplesTable/useSlowMedianFastSamplesQuery.tsx

@@ -35,6 +35,26 @@ export default function useSlowMedianFastSamplesQuery(eventView: EventView) {
       field: 'timestamp',
       kind: 'field',
     },
+    {
+      field: 'spans.browser',
+      kind: 'field',
+    },
+    {
+      field: 'spans.db',
+      kind: 'field',
+    },
+    {
+      field: 'spans.http',
+      kind: 'field',
+    },
+    {
+      field: 'spans.resource',
+      kind: 'field',
+    },
+    {
+      field: 'spans.ui',
+      kind: 'field',
+    },
   ];
 
   const eventViewAggregates = eventView.clone().withColumns([