Browse Source

feat(starfish): improve span sample panel (#51482)

Dominik Buszowiecki 1 year ago
parent
commit
ca28a2add7

+ 2 - 8
static/app/views/starfish/components/samplesTable/spanSamplesTable.tsx

@@ -3,8 +3,8 @@ import {Link} from 'react-router';
 import DateTime from 'sentry/components/dateTime';
 import GridEditable, {GridColumnHeader} from 'sentry/components/gridEditable';
 import {useLocation} from 'sentry/utils/useLocation';
-import {SpanDurationBar} from 'sentry/views/performance/transactionSummary/transactionSpans/spanDetails/spanDetailsTable';
 import {DurationComparisonCell} from 'sentry/views/starfish/components/samplesTable/common';
+import DurationCell from 'sentry/views/starfish/components/tableCells/durationCell';
 import {
   OverflowEllipsisTextContainer,
   TextAlignRight,
@@ -78,13 +78,7 @@ export function SpanSamplesTable({isLoading, data, p95}: Props) {
     }
 
     if (column.key === 'duration') {
-      return (
-        <SpanDurationBar
-          spanOp={row.op}
-          spanDuration={row['span.self_time']}
-          transactionDuration={row.transaction?.['transaction.duration']}
-        />
-      );
+      return <DurationCell milliseconds={row['span.self_time']} />;
     }
 
     if (column.key === 'p95_comparison') {

+ 8 - 4
static/app/views/starfish/queries/useSpanSamples.tsx

@@ -55,10 +55,14 @@ export const useSpanSamples = (options: Options) => {
           query: query.formatString(),
         })}`
       );
-      return data?.map((d: SpanSample) => ({
-        ...d,
-        timestamp: moment(d.timestamp).format(DATE_FORMAT),
-      }));
+      return data
+        ?.map((d: SpanSample) => ({
+          ...d,
+          timestamp: moment(d.timestamp).format(DATE_FORMAT),
+        }))
+        .sort(
+          (a: SpanSample, b: SpanSample) => b['span.self_time'] - a['span.self_time']
+        );
     },
     refetchOnWindowFocus: false,
     enabled: Boolean(groupId && transactionName),

+ 46 - 6
static/app/views/starfish/views/spanSummaryPage/sampleList/durationChart/index.tsx

@@ -4,12 +4,13 @@ import {useTheme} from '@emotion/react';
 import {Series} from 'sentry/types/echarts';
 import {P95_COLOR} from 'sentry/views/starfish/colours';
 import Chart from 'sentry/views/starfish/components/chart';
+import {useSpanMetrics} from 'sentry/views/starfish/queries/useSpanMetrics';
 import {useSpanMetricsSeries} from 'sentry/views/starfish/queries/useSpanMetricsSeries';
 import {useSpanSamples} from 'sentry/views/starfish/queries/useSpanSamples';
 import {SpanMetricsFields} from 'sentry/views/starfish/types';
 import {DataTitles} from 'sentry/views/starfish/views/spans/types';
 
-const {SPAN_SELF_TIME} = SpanMetricsFields;
+const {SPAN_SELF_TIME, SPAN_OP} = SpanMetricsFields;
 
 type Props = {
   groupId: string;
@@ -20,6 +21,18 @@ type Props = {
 function DurationChart({groupId, transactionName}: Props) {
   const theme = useTheme();
 
+  const getSampleSymbol = (duration: number, p95: number) => {
+    return duration > p95
+      ? {
+          symbol: 'path://M 5 4 L 0 -4 L -5 4 L 5 4',
+          color: theme.red300,
+        }
+      : {
+          symbol: 'path://M -5 -4 L 0 4 L 5 -4 L -5 -4',
+          color: theme.green300,
+        };
+  };
+
   const {isLoading, data: spanMetricsSeriesData} = useSpanMetricsSeries(
     {group: groupId},
     {transactionName},
@@ -27,6 +40,15 @@ function DurationChart({groupId, transactionName}: Props) {
     'sidebar-span-metrics'
   );
 
+  const {data: spanMetrics} = useSpanMetrics(
+    {group: groupId},
+    {transactionName},
+    [`p95(${SPAN_SELF_TIME})`, SPAN_OP],
+    'span-summary-panel-samples-table-p95'
+  );
+
+  const p95 = spanMetrics?.[`p95(${SPAN_SELF_TIME})`] || 0;
+
   const {
     data: spans,
     isLoading: areSpanSamplesLoading,
@@ -36,6 +58,24 @@ function DurationChart({groupId, transactionName}: Props) {
     transactionName,
   });
 
+  const baselineP95Series: Series = {
+    seriesName: 'Baseline P95',
+    data: [],
+    markLine: {
+      data: [{valueDim: 'x', yAxis: p95}],
+      symbol: ['none', 'none'],
+      lineStyle: {
+        color: theme.gray400,
+      },
+      emphasis: {disabled: true},
+      label: {
+        fontSize: 11,
+        position: 'insideEndBottom',
+        formatter: () => 'Baseline P95',
+      },
+    },
+  };
+
   const sampledSpanDataSeries: Series[] = spans.map(
     ({timestamp, 'span.self_time': duration, 'transaction.id': transaction_id}) => ({
       data: [
@@ -44,9 +84,9 @@ function DurationChart({groupId, transactionName}: Props) {
           value: duration,
         },
       ],
-      symbol: 'path://M -1 -1 V -5 H 0 V -1 H 4 V 0 H 0 V 4 H -1 V 0 H -5 V -1 H -1',
-      color: theme.gray400,
-      symbolSize: 15,
+      symbol: getSampleSymbol(duration, p95).symbol,
+      color: getSampleSymbol(duration, p95).color,
+      symbolSize: 10,
       seriesName: transaction_id,
     })
   );
@@ -57,7 +97,7 @@ function DurationChart({groupId, transactionName}: Props) {
       <Chart
         statsPeriod="24h"
         height={140}
-        data={[spanMetricsSeriesData?.[`p95(${SPAN_SELF_TIME})`]]}
+        data={[spanMetricsSeriesData?.[`p95(${SPAN_SELF_TIME})`], baselineP95Series]}
         start=""
         end=""
         loading={isLoading}
@@ -67,7 +107,7 @@ function DurationChart({groupId, transactionName}: Props) {
             : sampledSpanDataSeries
         }
         utc={false}
-        chartColors={[P95_COLOR]}
+        chartColors={[P95_COLOR, 'black']}
         isLineChart
         definedAxisTicks={4}
       />