Skip to content

Commit

Permalink
feat(new-trace): Adding direct-routing to trace view from transaction…
Browse files Browse the repository at this point in the history
… summary and span details (#68696)

Last of directly routing to trace view from performance, covers:
- transaction summary
- transaction summary > span details
- Aggregate span samples

---------

Co-authored-by: Abdullah Khan <abdullahkhan@PG9Y57YDXQ.local>
  • Loading branch information
Abdkhan14 and Abdullah Khan committed Apr 15, 2024
1 parent 90b4364 commit 74b54e4
Show file tree
Hide file tree
Showing 16 changed files with 119 additions and 58 deletions.
4 changes: 2 additions & 2 deletions static/app/components/discover/transactionsList.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -72,10 +72,10 @@ describe('TransactionsList', function () {
},
];
generateLink = {
transaction: (org, row, query) => ({
transaction: (org, row) => ({
pathname: `/${org.slug}`,
query: {
...query,
...location.query,
transaction: row.transaction,
count: row.count,
'count()': row['count()'],
Expand Down
4 changes: 2 additions & 2 deletions static/app/components/discover/transactionsList.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import {Component, Fragment, useContext, useEffect} from 'react';
import {browserHistory} from 'react-router';
import styled from '@emotion/styled';
import type {Location, LocationDescriptor, Query} from 'history';
import type {Location, LocationDescriptor} from 'history';

import GuideAnchor from 'sentry/components/assistant/guideAnchor';
import {Button} from 'sentry/components/button';
Expand Down Expand Up @@ -100,7 +100,7 @@ type Props = {
(
organization: Organization,
tableRow: TableDataRow,
query: Query
location: Location
) => LocationDescriptor
>;
generatePerformanceTransactionEventsView?: () => EventView;
Expand Down
6 changes: 3 additions & 3 deletions static/app/components/discover/transactionsTable.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import {Fragment, PureComponent} from 'react';
import styled from '@emotion/styled';
import type {Location, LocationDescriptor, Query} from 'history';
import type {Location, LocationDescriptor} from 'history';

import SortLink from 'sentry/components/gridEditable/sortLink';
import Link from 'sentry/components/links/link';
Expand Down Expand Up @@ -39,7 +39,7 @@ type Props = {
(
organization: Organization,
tableRow: TableDataRow,
query: Query
location: Location
) => LocationDescriptor
>;
handleCellAction?: (
Expand Down Expand Up @@ -143,7 +143,7 @@ class TransactionsTable extends PureComponent<Props> {
const fieldRenderer = getFieldRenderer(field, tableMeta, useAggregateAlias);
let rendered = fieldRenderer(row, {organization, location});

const target = generateLink?.[field]?.(organization, row, location.query);
const target = generateLink?.[field]?.(organization, row, location);

if (target && !objectIsEmpty(target)) {
if (fields[index] === 'replayId') {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
import styled from '@emotion/styled';
import type {Location} from 'history';

import Link from 'sentry/components/links/link';
import {t} from 'sentry/locale';
import {space} from 'sentry/styles/space';
import type {Organization, Project} from 'sentry/types';
import type {AggregateEventTransaction} from 'sentry/types/event';
import EventView from 'sentry/utils/discover/eventView';
import {generateLinkToEventInTraceView} from 'sentry/utils/discover/urls';
import {formatPercentage, getDuration} from 'sentry/utils/formatters';
import type {
QuickTraceEvent,
Expand All @@ -27,20 +30,32 @@ type Props = {
trace: Readonly<ParsedTraceType>;
};

function renderSpanSamples(span: AggregateSpanType, project: Project | undefined) {
function renderSpanSamples(
aggSpan: AggregateSpanType,
project: Project | undefined,
location: Location,
organization: Organization
) {
if (!project) {
return null;
}

return span.samples?.map(([transactionId, spanId], index) => (
return aggSpan.samples?.map(({transaction, span, trace, timestamp}, index) => (
<Link
key={`${transactionId}-${spanId}`}
to={`/performance/${project.slug}:${transactionId}#span-${spanId}`}
>{`${spanId}${index < span.samples.length - 1 ? ', ' : ''}`}</Link>
key={`${transaction}-${span}`}
to={generateLinkToEventInTraceView({
organization,
eventSlug: `${project.slug}:${transaction}`,
dataRow: {id: transaction, trace, timestamp},
location,
eventView: EventView.fromLocation(location),
spanId: span,
})}
>{`${span}${index < aggSpan.samples.length - 1 ? ', ' : ''}`}</Link>
));
}

function AggregateSpanDetail({span}: Props) {
function AggregateSpanDetail({span, organization}: Props) {
const location = useLocation();
const {projects} = useProjects();

Expand All @@ -62,7 +77,9 @@ function AggregateSpanDetail({span}: Props) {
<tbody>
<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>
<Row title={t('Span Samples')}>
{renderSpanSamples(span, project, location, organization)}
</Row>
</tbody>
</table>
</SpanDetails>
Expand Down
7 changes: 6 additions & 1 deletion static/app/components/events/interfaces/spans/types.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,12 @@ export type RawSpanType = {
export type AggregateSpanType = RawSpanType & {
count: number;
frequency: number;
samples: Array<[string, string]>;
samples: Array<{
span: string;
timestamp: number;
trace: string;
transaction: string;
}>;
total: number;
type: 'aggregate';
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@ export function useSpanWaterfallModelFromTransaction(
'avg(absolute_offset)': start_timestamp,
'count()': count,
'avg(duration)': duration,
samples,
sample_spans,
trace,
...rest
} = span;
return {
Expand All @@ -33,11 +34,11 @@ export function useSpanWaterfallModelFromTransaction(
exclusive_time,
timestamp: (start_timestamp + duration) / 1000,
start_timestamp: start_timestamp / 1000,
trace_id: '1', // not actually trace_id just a placeholder
trace,
count,
total,
duration,
samples,
samples: sample_spans,
frequency: count / total,
type: 'aggregate',
};
Expand Down
4 changes: 3 additions & 1 deletion static/app/utils/discover/urls.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ export function generateLinkToEventInTraceView({
location,
spanId,
eventSlug,
transactionName,
type = 'performance',
}: {
dataRow: TableDataRow;
Expand All @@ -57,6 +58,7 @@ export function generateLinkToEventInTraceView({
organization: Organization;
isHomepage?: boolean;
spanId?: string;
transactionName?: string;
type?: 'performance' | 'discover';
}) {
const dateSelection = eventView.normalizeDateSelection(location);
Expand All @@ -78,7 +80,7 @@ export function generateLinkToEventInTraceView({
return getTransactionDetailsUrl(
organization.slug,
eventSlug,
undefined,
transactionName,
location.query,
spanId
);
Expand Down
1 change: 1 addition & 0 deletions static/app/utils/performance/suspectSpans/types.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ export type ExampleSpan = {
finishTimestamp: number;
id: string;
startTimestamp: number;
trace: string;
};

export type ExampleTransaction = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,18 @@ import type {IssueAttachment, Organization} from 'sentry/types';
import {trackAnalytics} from 'sentry/utils/analytics';
import type {TableData, TableDataRow} from 'sentry/utils/discover/discoverQuery';
import DiscoverQuery from 'sentry/utils/discover/discoverQuery';
import type EventView from 'sentry/utils/discover/eventView';
import {isFieldSortable} from 'sentry/utils/discover/eventView';
import EventView, {isFieldSortable} from 'sentry/utils/discover/eventView';
import {getFieldRenderer} from 'sentry/utils/discover/fieldRenderers';
import {
fieldAlignment,
getAggregateAlias,
isSpanOperationBreakdownField,
SPAN_OP_RELATIVE_BREAKDOWN_FIELD,
} from 'sentry/utils/discover/fields';
import {
generateEventSlug,
generateLinkToEventInTraceView,
} from 'sentry/utils/discover/urls';
import ViewReplayLink from 'sentry/utils/discover/viewReplayLink';
import parseLinkHeader from 'sentry/utils/parseLinkHeader';
import {VisuallyCompleteWithData} from 'sentry/utils/performanceForSentry';
Expand All @@ -38,7 +41,6 @@ import {
generateProfileLink,
generateReplayLink,
generateTraceLink,
generateTransactionLink,
normalizeSearchConditions,
} from '../utils';

Expand Down Expand Up @@ -164,8 +166,18 @@ class EventsTable extends Component<Props, State> {
if (isIssue && !isRegressionIssue && field === 'id') {
target.pathname = `/organizations/${organization.slug}/issues/${issueId}/events/${dataRow.id}/`;
} else {
const generateLink = field === 'id' ? generateTransactionLink : generateTraceLink;
target = generateLink(transactionName)(organization, dataRow, location.query);
if (field === 'id') {
target = generateLinkToEventInTraceView({
eventSlug: generateEventSlug(dataRow),
dataRow: dataRow,
eventView: EventView.fromLocation(location),
location,
organization,
transactionName: transactionName,
});
} else {
target = generateTraceLink(transactionName)(organization, dataRow, location);
}
}

return (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ import {
generateProfileLink,
generateReplayLink,
generateTraceLink,
generateTransactionLink,
generateTransactionIdLink,
normalizeSearchConditions,
SidebarSpacer,
TransactionFilterOptions,
Expand Down Expand Up @@ -391,7 +391,7 @@ function SummaryContent({
titles={transactionsListTitles}
handleDropdownChange={handleTransactionsListSortChange}
generateLink={{
id: generateTransactionLink(transactionName),
id: generateTransactionIdLink(transactionName),
trace: generateTraceLink(eventView.normalizeDateSelection(location)),
replayId: generateReplayLink(routes),
'profile.id': generateProfileLink(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,14 @@ import {t, tct} from 'sentry/locale';
import {space} from 'sentry/styles/space';
import type {Organization, Project} from 'sentry/types';
import {defined} from 'sentry/utils';
import EventView from 'sentry/utils/discover/eventView';
import {getFieldRenderer} from 'sentry/utils/discover/fieldRenderers';
import type {ColumnType} from 'sentry/utils/discover/fields';
import {fieldAlignment} from 'sentry/utils/discover/fields';
import {
generateEventSlug,
generateLinkToEventInTraceView,
} from 'sentry/utils/discover/urls';
import {formatPercentage} from 'sentry/utils/formatters';
import toPercent from 'sentry/utils/number/toPercent';
import type {
Expand All @@ -26,8 +31,6 @@ import type {
} from 'sentry/utils/performance/suspectSpans/types';
import {VisuallyCompleteWithData} from 'sentry/utils/performanceForSentry';

import {generateTransactionLink} from '../../utils';

type TableColumnKeys =
| 'id'
| 'timestamp'
Expand Down Expand Up @@ -59,9 +62,9 @@ export default function SpanTable(props: Props) {
project,
examples,
suspectSpan,
transactionName,
isLoading,
pageLinks,
transactionName,
} = props;

if (!defined(examples)) {
Expand Down Expand Up @@ -152,17 +155,22 @@ function renderBodyCellWithMeta(
let rendered = fieldRenderer(dataRow, {location, organization});

if (column.key === 'id') {
const traceSlug = dataRow.spans[0] ? dataRow.spans[0].trace : '';
const worstSpan = dataRow.spans.length
? dataRow.spans.reduce((worst, span) =>
worst.exclusiveTime >= span.exclusiveTime ? worst : span
)
: null;
const target = generateTransactionLink(transactionName)(

const target = generateLinkToEventInTraceView({
eventSlug: generateEventSlug(dataRow),
dataRow: {...dataRow, trace: traceSlug},
eventView: EventView.fromLocation(location),
location,
organization,
dataRow,
location.query,
worstSpan.id
);
spanId: worstSpan.id,
transactionName: transactionName,
});

rendered = <Link to={target}>{rendered}</Link>;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,11 @@ export function generateSpansEventView({
id: undefined,
version: 2,
name: transactionName,
fields: [...Object.values(SpanSortOthers), ...Object.values(SpanSortPercentiles)],
fields: [
...Object.values(SpanSortOthers),
...Object.values(SpanSortPercentiles),
'trace',
],
query: conditions.formatString(),
projects: [],
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,11 @@ import {space} from 'sentry/styles/space';
import type {Organization, Project} from 'sentry/types';
import type {ReactEchartsRef, Series} from 'sentry/types/echarts';
import {axisLabelFormatter} from 'sentry/utils/discover/charts';
import type EventView from 'sentry/utils/discover/eventView';
import EventView from 'sentry/utils/discover/eventView';
import {
generateEventSlug,
generateLinkToEventInTraceView,
} from 'sentry/utils/discover/urls';
import {formatAbbreviatedNumber} from 'sentry/utils/formatters';
import getDynamicText from 'sentry/utils/getDynamicText';
import type {
Expand All @@ -39,7 +43,6 @@ import {decodeScalar} from 'sentry/utils/queryString';
import {getPerformanceDuration} from 'sentry/views/performance/utils/getPerformanceDuration';

import {eventsRouteWithQuery} from '../transactionEvents/utils';
import {generateTransactionLink} from '../utils';

import {parseHistogramBucketInfo, trackTagPageInteraction} from './utils';

Expand Down Expand Up @@ -348,11 +351,14 @@ function TagsHeatMap(
<div>
{!transactionTableData?.data.length ? <Placeholder /> : null}
{[...(transactionTableData?.data ?? [])].slice(0, 3).map(row => {
const target = generateTransactionLink(transactionName)(
const target = generateLinkToEventInTraceView({
eventSlug: generateEventSlug(row),
dataRow: row,
eventView: EventView.fromLocation(location),
location,
organization,
row,
location.query
);
transactionName,
});

return (
<DropdownItem width="small" key={row.id} to={target}>
Expand Down
Loading

0 comments on commit 74b54e4

Please sign in to comment.