Browse Source

feat(aggregate-waterfall): Add links to events containing span samples (#57920)

Ash Anand 1 year ago
parent
commit
ae3e34ba3c

+ 26 - 3
static/app/components/events/interfaces/spans/aggregateSpanDetail.tsx

@@ -1,14 +1,17 @@
 import styled from '@emotion/styled';
 
+import Link from 'sentry/components/links/link';
 import {t} from 'sentry/locale';
 import {space} from 'sentry/styles/space';
-import {Organization} from 'sentry/types';
+import {Organization, Project} from 'sentry/types';
 import {AggregateEventTransaction} from 'sentry/types/event';
 import {formatPercentage, getDuration} from 'sentry/utils/formatters';
 import {
   QuickTraceEvent,
   TraceErrorOrIssue,
 } from 'sentry/utils/performance/quickTrace/types';
+import {useLocation} from 'sentry/utils/useLocation';
+import useProjects from 'sentry/utils/useProjects';
 
 import {AggregateSpanType, ParsedTraceType} from './types';
 
@@ -24,9 +27,28 @@ type Props = {
   trace: Readonly<ParsedTraceType>;
 };
 
+function renderSpanSamples(span: AggregateSpanType, project: Project | undefined) {
+  if (!project) {
+    return null;
+  }
+
+  return span.samples.map(([transactionId, spanId], index) => (
+    <Link
+      key={`${transactionId}-${spanId}`}
+      to={`/performance/${project.slug}:${transactionId}#span-${spanId}`}
+    >{`${spanId}${index < span.samples.length - 1 ? ', ' : ''}`}</Link>
+  ));
+}
+
 function AggregateSpanDetail({span}: Props) {
+  const location = useLocation();
+  const {projects} = useProjects();
+
+  const project = projects.find(p => p.id === location.query.project);
+
   const frequency = span?.frequency;
   const avgDuration = span?.timestamp - span?.start_timestamp;
+
   return (
     <SpanDetailContainer
       data-component="span-detail"
@@ -38,8 +60,9 @@ function AggregateSpanDetail({span}: Props) {
       <SpanDetails>
         <table className="table key-value">
           <tbody>
-            <Row title={t('avg(duration)')}>{getDuration(avgDuration)}</Row>
-            <Row title={t('frequency')}>{frequency && formatPercentage(frequency)}</Row>
+            <Row title={t('Avg Duration')}>{getDuration(avgDuration)}</Row>
+            <Row title={t('Frequency')}>{frequency && formatPercentage(frequency)}</Row>
+            <Row title={t('Span Samples')}>{renderSpanSamples(span, project)}</Row>
           </tbody>
         </table>
       </SpanDetails>

+ 5 - 0
static/app/components/events/interfaces/spans/aggregateSpans.tsx

@@ -19,6 +19,8 @@ import {useLocalStorageState} from 'sentry/utils/useLocalStorageState';
 import useOrganization from 'sentry/utils/useOrganization';
 import usePageFilters from 'sentry/utils/usePageFilters';
 
+type SpanSamples = Array<[string, string]>;
+
 type AggregateSpanRow = {
   'avg(absolute_offset)': number;
   'avg(duration)': number;
@@ -29,6 +31,7 @@ type AggregateSpanRow = {
   is_segment: number;
   node_fingerprint: string;
   parent_node_fingerprint: string;
+  samples: SpanSamples;
   start_ms: number;
 };
 
@@ -84,6 +87,7 @@ export function AggregateSpans({transaction}: Props) {
       'avg(absolute_offset)': start_timestamp,
       'count()': count,
       'avg(duration)': duration,
+      samples,
       ...rest
     } = span;
     return {
@@ -98,6 +102,7 @@ export function AggregateSpans({transaction}: Props) {
       count,
       total,
       duration,
+      samples,
       frequency: count / total,
       type: 'aggregate',
     };

+ 1 - 0
static/app/components/events/interfaces/spans/types.tsx

@@ -35,6 +35,7 @@ export type RawSpanType = {
 export type AggregateSpanType = RawSpanType & {
   count: number;
   frequency: number;
+  samples: Array<[string, string]>;
   total: number;
   type: 'aggregate';
 };