Browse Source

feat(starfish): remove sparklines, replace with the value (#50440)

1. Remove sparklines
2. Replace sparklines with corresponding value for the time period
3. Use throughput per second instead of per minute (i'm seeing a lot of
0's here, so depending on how this looks with prod data we might wanna
change it back)

<img width="1234" alt="image"
src="https://github.com/getsentry/sentry/assets/44422760/ced80b3a-8fea-4b0f-b11b-04aac67b41e8">
Dominik Buszowiecki 1 year ago
parent
commit
4bbc9864e5

+ 9 - 0
static/app/views/starfish/components/tableCells/durationCell.tsx

@@ -0,0 +1,9 @@
+import Duration from 'sentry/components/duration';
+
+type Props = {
+  seconds: number;
+};
+
+export default function DurationCell({seconds}: Props) {
+  return <Duration seconds={seconds} fixedDigits={2} abbreviation />;
+}

+ 10 - 0
static/app/views/starfish/components/tableCells/throughputCell.tsx

@@ -0,0 +1,10 @@
+import {t} from 'sentry/locale';
+
+type Props = {
+  throughputPerSecond?: number;
+};
+
+export default function ThroughputCell({throughputPerSecond}: Props) {
+  const throughput = throughputPerSecond ? throughputPerSecond.toFixed(2) : '--';
+  return <span>{`${throughput}/${t('sec')}`}</span>;
+}

+ 19 - 0
static/app/views/starfish/components/tableCells/timeSpentCell.tsx

@@ -0,0 +1,19 @@
+import {Tooltip} from 'sentry/components/tooltip';
+import {getTooltip} from 'sentry/views/starfish/views/spans/types';
+
+export function TimeSpentCell({
+  formattedTimeSpent,
+  totalSpanTime,
+  totalAppTime,
+}: {
+  formattedTimeSpent: string;
+  totalAppTime: number;
+  totalSpanTime: number;
+}) {
+  const toolTip = getTooltip('timeSpent', totalSpanTime, totalAppTime);
+  return (
+    <span>
+      <Tooltip title={toolTip}>{formattedTimeSpent}</Tooltip>
+    </span>
+  );
+}

+ 6 - 4
static/app/views/starfish/queries/useSpanMetrics.tsx

@@ -1,3 +1,5 @@
+import moment from 'moment';
+
 import {useQuery} from 'sentry/utils/queryClient';
 import usePageFilters from 'sentry/utils/usePageFilters';
 import type {Span} from 'sentry/views/starfish/queries/types';
@@ -5,15 +7,13 @@ import {HOST} from 'sentry/views/starfish/utils/constants';
 import {getDateFilters} from 'sentry/views/starfish/utils/dates';
 import {getDateQueryFilter} from 'sentry/views/starfish/utils/getDateQueryFilter';
 
-const INTERVAL = 12;
-
 export type SpanMetrics = {
   count: number;
   first_seen: string;
   last_seen: string;
   p50: number;
   p95: number;
-  spm: number;
+  spans_per_second: number;
   total_time: number;
 };
 
@@ -39,7 +39,9 @@ export const useSpanMetrics = (
   sum(exclusive_time) as total_time,
   quantile(0.5)(exclusive_time) as p50,
   quantile(0.5)(exclusive_time) as p95,
-  divide(count, multiply(${INTERVAL}, 60)) as spm
+  divide(count(), ${
+    moment(endTime ?? undefined).unix() - moment(startTime).unix()
+  }) as spans_per_second
   FROM spans_experimental_starfish
   WHERE group_id = '${span.group_id}'
   ${dateFilters}

+ 5 - 4
static/app/views/starfish/queries/useSpanTransactionMetrics.tsx

@@ -1,4 +1,5 @@
 import keyBy from 'lodash/keyBy';
+import moment from 'moment';
 
 import {useQuery} from 'sentry/utils/queryClient';
 import usePageFilters from 'sentry/utils/usePageFilters';
@@ -7,12 +8,10 @@ import {HOST} from 'sentry/views/starfish/utils/constants';
 import {getDateFilters} from 'sentry/views/starfish/utils/dates';
 import {getDateQueryFilter} from 'sentry/views/starfish/utils/getDateQueryFilter';
 
-const INTERVAL = 12;
-
 export type SpanTransactionMetrics = {
   p50: number;
   p95: number;
-  spm: number;
+  spans_per_second: number;
   'sum(span.self_time)': number;
   total_time: number;
   transaction: string;
@@ -36,7 +35,9 @@ export const useSpanTransactionMetrics = (
       quantile(0.5)(exclusive_time) as p95,
       sum(exclusive_time) as "sum(span.self_time)",
       sum(exclusive_time) as total_time,
-      divide(count(), multiply(${INTERVAL}, 60)) as spm
+      divide(count(), ${
+        moment(endTime ?? undefined).unix() - moment(startTime).unix()
+      }) as spans_per_second
     FROM spans_experimental_starfish
     WHERE group_id = '${span.group_id}'
     ${dateFilters}

+ 5 - 2
static/app/views/starfish/views/spanSummaryPage/sampleList/sampleInfo/index.tsx

@@ -1,6 +1,7 @@
 import {Tooltip} from 'sentry/components/tooltip';
 import {t} from 'sentry/locale';
 import {formatPercentage} from 'sentry/utils/formatters';
+import ThroughputCell from 'sentry/views/starfish/components/tableCells/throughputCell';
 import {useApplicationMetrics} from 'sentry/views/starfish/queries/useApplicationMetrics';
 import {useSpanTransactionMetrics} from 'sentry/views/starfish/queries/useSpanTransactionMetrics';
 import {DataTitles, getTooltip} from 'sentry/views/starfish/views/spans/types';
@@ -18,7 +19,7 @@ function SampleInfo(props: Props) {
     transactionName,
   ]);
   const {data: applicationMetrics} = useApplicationMetrics();
-  const spm = spanMetrics[transactionName]?.spm;
+  const spansPerSecond = spanMetrics[transactionName]?.spans_per_second;
   const p95 = spanMetrics[transactionName]?.p95;
   const span_total_time = spanMetrics[transactionName]?.total_time;
   const application_total_time = applicationMetrics['sum(span.duration)'];
@@ -27,7 +28,9 @@ function SampleInfo(props: Props) {
 
   return (
     <BlockContainer>
-      <Block title={t('Throughput')}>{spm?.toFixed(2)} / min</Block>
+      <Block title={t('Throughput')}>
+        <ThroughputCell throughputPerSecond={spansPerSecond} />
+      </Block>
       <Block title={DataTitles.p95}>{p95?.toFixed(2)} ms</Block>
       <Block title={DataTitles.timeSpent}>
         <Tooltip title={tooltip}>

+ 14 - 90
static/app/views/starfish/views/spanSummaryPage/spanBaselineTable.tsx

@@ -1,19 +1,14 @@
-import {Fragment} from 'react';
-import {useTheme} from '@emotion/react';
-
 import GridEditable, {
   COL_WIDTH_UNDEFINED,
   GridColumnHeader,
 } from 'sentry/components/gridEditable';
-import {Tooltip} from 'sentry/components/tooltip';
 import {Series} from 'sentry/types/echarts';
 import {formatPercentage} from 'sentry/utils/formatters';
 import {useLocation} from 'sentry/utils/useLocation';
-import {P95_COLOR, THROUGHPUT_COLOR} from 'sentry/views/starfish/colours';
 import {SpanDescription} from 'sentry/views/starfish/components/spanDescription';
-import Sparkline, {
-  generateHorizontalLine,
-} from 'sentry/views/starfish/components/sparkline';
+import DurationCell from 'sentry/views/starfish/components/tableCells/durationCell';
+import ThroughputCell from 'sentry/views/starfish/components/tableCells/throughputCell';
+import {TimeSpentCell} from 'sentry/views/starfish/components/tableCells/timeSpentCell';
 import type {Span} from 'sentry/views/starfish/queries/types';
 import {
   ApplicationMetrics,
@@ -21,7 +16,7 @@ import {
 } from 'sentry/views/starfish/queries/useApplicationMetrics';
 import {SpanMetrics, useSpanMetrics} from 'sentry/views/starfish/queries/useSpanMetrics';
 import {useSpanMetricSeries} from 'sentry/views/starfish/queries/useSpanMetricSeries';
-import {DataTitles, getTooltip} from 'sentry/views/starfish/views/spans/types';
+import {DataTitles} from 'sentry/views/starfish/views/spans/types';
 
 type Props = {
   span: Span;
@@ -34,7 +29,11 @@ type Row = {
   timeSpent: string;
 };
 
-export type Keys = 'description' | 'epm()' | 'p95(span.self_time)' | 'timeSpent';
+export type Keys =
+  | 'description'
+  | 'spans_per_second'
+  | 'p95(span.self_time)'
+  | 'timeSpent';
 export type TableColumnHeader = GridColumnHeader<Keys>;
 
 export function SpanBaselineTable({span}: Props) {
@@ -100,17 +99,11 @@ function BodyCell({
   }
 
   if (column.key === 'p95(span.self_time)') {
-    return (
-      <DurationTrendCell
-        duration={row.metrics?.p95}
-        durationSeries={row.metricSeries?.p95}
-        color={P95_COLOR}
-      />
-    );
+    return <DurationCell seconds={row.metrics.p95} />;
   }
 
-  if (column.key === 'epm()') {
-    return <EPMCell span={span} row={row} column={column} />;
+  if (column.key === 'spans_per_second') {
+    return <ThroughputCell throughputPerSecond={row.metrics.spans_per_second} />;
   }
 
   if (column.key === 'timeSpent') {
@@ -130,75 +123,6 @@ function DescriptionCell({span}: CellProps) {
   return <SpanDescription span={span} />;
 }
 
-export function DurationTrendCell({
-  duration,
-  durationSeries,
-  color,
-}: {
-  color: string;
-  duration: number;
-  durationSeries?: Series;
-}) {
-  const theme = useTheme();
-
-  return (
-    <Fragment>
-      {durationSeries ? (
-        <Sparkline
-          color={color}
-          series={durationSeries}
-          markLine={
-            duration
-              ? generateHorizontalLine(
-                  `${(duration / 1000).toFixed(2)} s`,
-                  duration,
-                  theme
-                )
-              : undefined
-          }
-        />
-      ) : null}
-    </Fragment>
-  );
-}
-
-function EPMCell({row}: CellProps) {
-  const theme = useTheme();
-  const epm = row.metrics?.spm;
-  const epmSeries = row.metricSeries?.spm;
-
-  return (
-    <Fragment>
-      {epmSeries ? (
-        <Sparkline
-          color={THROUGHPUT_COLOR}
-          series={epmSeries}
-          markLine={
-            epm ? generateHorizontalLine(`${epm.toFixed(2)}`, epm, theme) : undefined
-          }
-        />
-      ) : null}
-    </Fragment>
-  );
-}
-
-export function TimeSpentCell({
-  formattedTimeSpent,
-  totalSpanTime,
-  totalAppTime,
-}: {
-  formattedTimeSpent: string;
-  totalAppTime: number;
-  totalSpanTime: number;
-}) {
-  const toolTip = getTooltip('timeSpent', totalSpanTime, totalAppTime);
-  return (
-    <span>
-      <Tooltip title={toolTip}>{formattedTimeSpent}</Tooltip>
-    </span>
-  );
-}
-
 const COLUMN_ORDER: TableColumnHeader[] = [
   {
     key: 'description',
@@ -206,8 +130,8 @@ const COLUMN_ORDER: TableColumnHeader[] = [
     width: 500,
   },
   {
-    key: 'epm()',
-    name: 'Throughput (TPM)',
+    key: 'spans_per_second',
+    name: DataTitles.throughput,
     width: COL_WIDTH_UNDEFINED,
   },
   {

+ 13 - 41
static/app/views/starfish/views/spanSummaryPage/spanTransactionsTable.tsx

@@ -1,5 +1,4 @@
 import {Fragment} from 'react';
-import {useTheme} from '@emotion/react';
 import * as qs from 'query-string';
 
 import GridEditable, {
@@ -11,10 +10,9 @@ import Truncate from 'sentry/components/truncate';
 import {Series} from 'sentry/types/echarts';
 import {formatPercentage} from 'sentry/utils/formatters';
 import {useLocation} from 'sentry/utils/useLocation';
-import {P95_COLOR, THROUGHPUT_COLOR} from 'sentry/views/starfish/colours';
-import Sparkline, {
-  generateHorizontalLine,
-} from 'sentry/views/starfish/components/sparkline';
+import DurationCell from 'sentry/views/starfish/components/tableCells/durationCell';
+import ThroughputCell from 'sentry/views/starfish/components/tableCells/throughputCell';
+import {TimeSpentCell} from 'sentry/views/starfish/components/tableCells/timeSpentCell';
 import type {Span} from 'sentry/views/starfish/queries/types';
 import {
   ApplicationMetrics,
@@ -27,10 +25,6 @@ import {
 import {useSpanTransactionMetricSeries} from 'sentry/views/starfish/queries/useSpanTransactionMetricSeries';
 import {useSpanTransactions} from 'sentry/views/starfish/queries/useSpanTransactions';
 import {DataTitles} from 'sentry/views/starfish/views/spans/types';
-import {
-  DurationTrendCell,
-  TimeSpentCell,
-} from 'sentry/views/starfish/views/spanSummaryPage/spanBaselineTable';
 
 type Row = {
   count: number;
@@ -45,7 +39,11 @@ type Props = {
   openSidebar?: boolean;
 };
 
-export type Keys = 'transaction' | 'epm()' | 'p95(transaction.duration)' | 'timeSpent';
+export type Keys =
+  | 'transaction'
+  | 'p95(transaction.duration)'
+  | 'timeSpent'
+  | 'spans_per_second';
 export type TableColumnHeader = GridColumnHeader<Keys>;
 
 export function SpanTransactionsTable({span, openSidebar, onClickTransaction}: Props) {
@@ -135,17 +133,11 @@ function BodyCell({
   }
 
   if (column.key === 'p95(transaction.duration)') {
-    return (
-      <DurationTrendCell
-        duration={row.metrics?.p50}
-        color={P95_COLOR}
-        durationSeries={row.metricSeries?.p50}
-      />
-    );
+    return <DurationCell seconds={row.metrics?.p95} />;
   }
 
-  if (column.key === 'epm()') {
-    return <EPMCell span={span} row={row} column={column} />;
+  if (column.key === 'spans_per_second') {
+    return <ThroughputCell throughputPerSecond={row.metrics?.spans_per_second} />;
   }
 
   if (column.key === 'timeSpent') {
@@ -175,26 +167,6 @@ function TransactionCell({span, column, row}: CellProps) {
   );
 }
 
-function EPMCell({row}: CellProps) {
-  const theme = useTheme();
-  const epm = row.metrics?.spm;
-  const epmSeries = row.metricSeries?.spm;
-
-  return (
-    <Fragment>
-      {epmSeries ? (
-        <Sparkline
-          color={THROUGHPUT_COLOR}
-          series={epmSeries}
-          markLine={
-            epm ? generateHorizontalLine(`${epm.toFixed(2)}`, epm, theme) : undefined
-          }
-        />
-      ) : null}
-    </Fragment>
-  );
-}
-
 const COLUMN_ORDER: TableColumnHeader[] = [
   {
     key: 'transaction',
@@ -202,8 +174,8 @@ const COLUMN_ORDER: TableColumnHeader[] = [
     width: 500,
   },
   {
-    key: 'epm()',
-    name: 'Throughput (TPM)',
+    key: 'spans_per_second',
+    name: DataTitles.throughput,
     width: COL_WIDTH_UNDEFINED,
   },
   {

+ 2 - 2
static/app/views/starfish/views/spans/queries.tsx

@@ -50,8 +50,8 @@ export const getSpanListQuery = (
     quantile(0.50)(exclusive_time) as p50,
     count() as count,
     (divide(count, ${
-      (moment(end_timestamp ?? undefined).unix() - moment(start_timestamp).unix()) / 60
-    }) AS epm)
+      moment(end_timestamp ?? undefined).unix() - moment(start_timestamp).unix()
+    }) AS spans_per_second)
     FROM spans_experimental_starfish
     WHERE greaterOrEquals(start_timestamp, '${start_timestamp}')
     ${validConditions.length > 0 ? 'AND' : ''}

+ 3 - 3
static/app/views/starfish/views/spans/spanTimeCharts.tsx

@@ -65,7 +65,7 @@ export function SpanTimeCharts({moduleName, appliedFilters}: Props) {
     {Comp: (props: ChartProps) => JSX.Element; title: string}[]
   > = {
     [ModuleName.ALL]: [
-      {title: t('Throughput'), Comp: ThroughputChart},
+      {title: DataTitles.throughput, Comp: ThroughputChart},
       {title: DataTitles.p95, Comp: DurationChart},
     ],
     [ModuleName.DB]: [],
@@ -111,7 +111,7 @@ function ThroughputChart({moduleName, filters}: ChartProps): JSX.Element {
       {
         seriesName: label ?? 'Throughput',
         data: groupData.map(datum => ({
-          value: datum['spm()'],
+          value: datum['spm()'] / 60,
           name: datum.interval,
         })),
       },
@@ -141,7 +141,7 @@ function ThroughputChart({moduleName, filters}: ChartProps): JSX.Element {
       isLineChart
       chartColors={[THROUGHPUT_COLOR]}
       tooltipFormatterOptions={{
-        valueFormatter: value => `${value.toFixed(3)} / ${t('min')}`,
+        valueFormatter: value => `${value.toFixed(3)} / ${t('sec')}`,
       }}
     />
   );

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