Skip to content

Commit 8f8aa12

Browse files
Abdkhan14Abdullah Khan
andauthored
feat(issues-trace): Using trace endpoints correctly in anr root cause… (#95075)
… section - Assigns /events-trace/ (old) and /trace-endpoint/ (new) based on the trace-spans-format flag. - Without this change we default to the old events-trace endpoint, which should only be called for `am1` right now. The flag enforces this. --------- Co-authored-by: Abdullah Khan <abdullahkhan@PG9Y57YDXQ.local>
1 parent 9366d48 commit 8f8aa12

File tree

6 files changed

+86
-42
lines changed

6 files changed

+86
-42
lines changed

static/app/components/events/interfaces/performance/anrRootCause.spec.tsx

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,25 @@ import {textWithMarkupMatcher} from 'sentry-test/utils';
55
import {AnrRootCause} from 'sentry/components/events/interfaces/performance/anrRootCause';
66
import type {Event, Thread} from 'sentry/types/event';
77
import {EntryType, EventOrGroupType, LockType} from 'sentry/types/event';
8+
import {DEFAULT_TRACE_VIEW_PREFERENCES} from 'sentry/views/performance/newTraceDetails/traceState/tracePreferences';
9+
import {TraceStateProvider} from 'sentry/views/performance/newTraceDetails/traceState/traceStateProvider';
10+
11+
jest.mock('sentry/views/performance/newTraceDetails/traceApi/useTrace', () => {
12+
return {
13+
useTrace: jest.fn(() => ({
14+
data: {
15+
transactions: [],
16+
orphan_errors: [],
17+
},
18+
})),
19+
};
20+
});
21+
22+
const wrapper = ({children}: {children: React.ReactNode}) => (
23+
<TraceStateProvider initialPreferences={DEFAULT_TRACE_VIEW_PREFERENCES}>
24+
{children}
25+
</TraceStateProvider>
26+
);
827

928
const makeEventWithThreads = (threads: Thread[]): Event => {
1029
const event: Event = {
@@ -13,6 +32,7 @@ const makeEventWithThreads = (threads: Thread[]): Event => {
1332
eventID: '020eb33f6ce64ed6adc60f8993535816',
1433
projectID: '2',
1534
size: 3481,
35+
1636
entries: [
1737
{
1838
data: {
@@ -215,7 +235,7 @@ describe('anrRootCause', function () {
215235
]);
216236
const {organization} = initializeOrg();
217237
const org = {...organization, features: ['anr-analyze-frames']};
218-
render(<AnrRootCause event={event} organization={org} />);
238+
render(<AnrRootCause event={event} organization={org} />, {wrapper});
219239

220240
expect(
221241
screen.getByText(

static/app/components/events/interfaces/performance/anrRootCause.tsx

Lines changed: 42 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,15 @@
1-
import {Fragment, useContext, useEffect} from 'react';
1+
import {Fragment, useEffect} from 'react';
22
import styled from '@emotion/styled';
33

44
import {analyzeFramesForRootCause} from 'sentry/components/events/interfaces/analyzeFrames';
55
import {StackTraceContent} from 'sentry/components/events/interfaces/crashContent/stackTrace';
66
import NoStackTraceMessage from 'sentry/components/events/interfaces/noStackTraceMessage';
77
import getThreadStacktrace from 'sentry/components/events/interfaces/threads/threadSelector/getThreadStacktrace';
8-
import {getThreadById, inferPlatform} from 'sentry/components/events/interfaces/utils';
8+
import {
9+
getEventTimestampInSeconds,
10+
getThreadById,
11+
inferPlatform,
12+
} from 'sentry/components/events/interfaces/utils';
913
import GlobalSelectionLink from 'sentry/components/globalSelectionLink';
1014
import ShortId from 'sentry/components/group/inboxBadges/shortId';
1115
import ProjectBadge from 'sentry/components/idBadge/projectBadge';
@@ -16,10 +20,12 @@ import type {Organization} from 'sentry/types/organization';
1620
import {StackView} from 'sentry/types/stacktrace';
1721
import {defined} from 'sentry/utils';
1822
import {trackAnalytics} from 'sentry/utils/analytics';
19-
import {QuickTraceContext} from 'sentry/utils/performance/quickTrace/quickTraceContext';
2023
import useProjects from 'sentry/utils/useProjects';
2124
import {SectionKey} from 'sentry/views/issueDetails/streamline/context';
2225
import {InterimSection} from 'sentry/views/issueDetails/streamline/interimSection';
26+
import {useIssuesTraceTree} from 'sentry/views/performance/newTraceDetails/traceApi/useIssuesTraceTree';
27+
import {useTrace} from 'sentry/views/performance/newTraceDetails/traceApi/useTrace';
28+
import {isEAPTraceOccurrence} from 'sentry/views/performance/newTraceDetails/traceGuards';
2329

2430
enum AnrRootCauseAllowlist {
2531
PERFORMANCE_FILE_IO_MAIN_THREAD_GROUP_TYPE = 1008,
@@ -32,7 +38,16 @@ interface Props {
3238
}
3339

3440
export function AnrRootCause({event, organization}: Props) {
35-
const quickTrace = useContext(QuickTraceContext);
41+
const traceSlug = event.contexts.trace?.trace_id ?? '';
42+
43+
const trace = useTrace({
44+
timestamp: getEventTimestampInSeconds(event),
45+
traceSlug,
46+
limit: 10000,
47+
});
48+
const tree = useIssuesTraceTree({trace, replay: null});
49+
const traceNode = tree.root.children[0];
50+
3651
const {projects} = useProjects();
3752

3853
const anrCulprit = analyzeFramesForRootCause(event);
@@ -49,20 +64,19 @@ export function AnrRootCause({event, organization}: Props) {
4964
});
5065
}, [anrCulprit, organization, event?.groupID]);
5166

52-
const noPerfIssueOnTrace =
53-
!quickTrace ||
54-
quickTrace.error ||
55-
quickTrace.trace === null ||
56-
quickTrace.trace.length === 0 ||
57-
quickTrace.trace[0]?.performance_issues?.length === 0;
67+
if (tree.type === 'loading' || tree.type === 'error') {
68+
return null;
69+
}
70+
71+
const occurrences = Array.from(traceNode?.occurrences ?? []);
72+
const noPerfIssueOnTrace = occurrences.length === 0;
5873

5974
if (noPerfIssueOnTrace && !anrCulprit) {
6075
return null;
6176
}
6277

63-
const potentialAnrRootCause = quickTrace?.trace?.[0]?.performance_issues?.filter(
64-
issue =>
65-
Object.values(AnrRootCauseAllowlist).includes(issue.type as AnrRootCauseAllowlist)
78+
const potentialAnrRootCause = occurrences.filter(issue =>
79+
Object.values(AnrRootCauseAllowlist).includes(issue.type as AnrRootCauseAllowlist)
6680
);
6781

6882
const helpText =
@@ -119,28 +133,34 @@ export function AnrRootCause({event, organization}: Props) {
119133
type={SectionKey.SUSPECT_ROOT_CAUSE}
120134
help={helpText}
121135
>
122-
{potentialAnrRootCause?.map(issue => {
123-
const project = projects.find(p => p.id === issue.project_id.toString());
136+
{potentialAnrRootCause?.map(occurence => {
137+
const project = projects.find(p => p.id === occurence.project_id.toString());
138+
const title = isEAPTraceOccurrence(occurence)
139+
? occurence.description
140+
: occurence.title;
141+
const shortId = isEAPTraceOccurrence(occurence)
142+
? occurence.short_id
143+
: occurence.issue_short_id;
124144
return (
125-
<IssueSummary key={issue.issue_id}>
145+
<IssueSummary key={occurence.issue_id}>
126146
<Title>
127147
<TitleWithLink
128148
to={{
129-
pathname: `/organizations/${organization.id}/issues/${issue.issue_id}/${
130-
issue.event_id ? `events/${issue.event_id}/` : ''
149+
pathname: `/organizations/${organization.id}/issues/${occurence.issue_id}/${
150+
occurence.event_id ? `events/${occurence.event_id}/` : ''
131151
}`,
132152
}}
133153
>
134-
{issue.title}
154+
{title}
135155
<Fragment>
136156
<Spacer />
137-
<Subtitle title={issue.culprit}>{issue.culprit}</Subtitle>
157+
<Subtitle title={occurence.culprit}>{occurence.culprit}</Subtitle>
138158
</Fragment>
139159
</TitleWithLink>
140160
</Title>
141-
{issue.issue_short_id && (
161+
{shortId && (
142162
<ShortId
143-
shortId={issue.issue_short_id}
163+
shortId={shortId}
144164
avatar={
145165
project && <ProjectBadge project={project} hideName avatarSize={12} />
146166
}

static/app/views/issueDetails/groupEventDetails/groupEventDetailsContent.tsx

Lines changed: 8 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ import {Message} from 'sentry/components/events/interfaces/message';
4444
import {AnrRootCause} from 'sentry/components/events/interfaces/performance/anrRootCause';
4545
import {EventTraceView} from 'sentry/components/events/interfaces/performance/eventTraceView';
4646
import {SpanEvidenceSection} from 'sentry/components/events/interfaces/performance/spanEvidence';
47+
import {TRACE_WATERFALL_PREFERENCES_KEY} from 'sentry/components/events/interfaces/performance/utils';
4748
import {Request} from 'sentry/components/events/interfaces/request';
4849
import {StackTrace} from 'sentry/components/events/interfaces/stackTrace';
4950
import {Template} from 'sentry/components/events/interfaces/template';
@@ -66,11 +67,8 @@ import {IssueType} from 'sentry/types/group';
6667
import type {Project} from 'sentry/types/project';
6768
import {defined} from 'sentry/utils';
6869
import {getConfigForIssueType} from 'sentry/utils/issueTypeConfig';
69-
import {QuickTraceContext} from 'sentry/utils/performance/quickTrace/quickTraceContext';
70-
import QuickTraceQuery from 'sentry/utils/performance/quickTrace/quickTraceQuery';
7170
import {isJavascriptPlatform} from 'sentry/utils/platform';
7271
import {getReplayIdFromEvent} from 'sentry/utils/replays/getReplayIdFromEvent';
73-
import {useLocation} from 'sentry/utils/useLocation';
7472
import useOrganization from 'sentry/utils/useOrganization';
7573
import {MetricIssuesSection} from 'sentry/views/issueDetails/metricIssues/metricIssuesSection';
7674
import {SectionKey} from 'sentry/views/issueDetails/streamline/context';
@@ -79,6 +77,8 @@ import {useCopyIssueDetails} from 'sentry/views/issueDetails/streamline/hooks/us
7977
import {InterimSection} from 'sentry/views/issueDetails/streamline/interimSection';
8078
import {TraceDataSection} from 'sentry/views/issueDetails/traceDataSection';
8179
import {useHasStreamlinedUI} from 'sentry/views/issueDetails/utils';
80+
import {DEFAULT_TRACE_VIEW_PREFERENCES} from 'sentry/views/performance/newTraceDetails/traceState/tracePreferences';
81+
import {TraceStateProvider} from 'sentry/views/performance/newTraceDetails/traceState/traceStateProvider';
8282

8383
export interface EventDetailsContentProps {
8484
group: Group;
@@ -92,7 +92,6 @@ export function EventDetailsContent({
9292
project,
9393
}: Required<Pick<EventDetailsContentProps, 'group' | 'event' | 'project'>>) {
9494
const organization = useOrganization();
95-
const location = useLocation();
9695
const hasStreamlinedUI = useHasStreamlinedUI();
9796
const tagsRef = useRef<HTMLDivElement>(null);
9897
const eventEntries = useMemo(() => {
@@ -278,21 +277,12 @@ export function EventDetailsContent({
278277
<ScreenshotDataSection event={event} projectSlug={project.slug} />
279278
)}
280279
{isANR && (
281-
<QuickTraceQuery
282-
event={event}
283-
location={location}
284-
orgSlug={organization.slug}
285-
type={'spans'}
286-
skipLight
280+
<TraceStateProvider
281+
initialPreferences={DEFAULT_TRACE_VIEW_PREFERENCES}
282+
preferencesStorageKey={TRACE_WATERFALL_PREFERENCES_KEY}
287283
>
288-
{results => {
289-
return (
290-
<QuickTraceContext value={results}>
291-
<AnrRootCause event={event} organization={organization} />
292-
</QuickTraceContext>
293-
);
294-
}}
295-
</QuickTraceQuery>
284+
<AnrRootCause event={event} organization={organization} />
285+
</TraceStateProvider>
296286
)}
297287
{issueTypeConfig.spanEvidence.enabled && (
298288
<SpanEvidenceSection

static/app/views/performance/newTraceDetails/traceGuards.tsx

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,14 @@ export function isTraceOccurence(
231231
return 'issue_id' in issue && issue.event_type !== 'error';
232232
}
233233

234+
export function isEAPTraceOccurrence(
235+
issue: TraceTree.TraceIssue
236+
): issue is TraceTree.EAPOccurrence {
237+
return (
238+
isTraceOccurence(issue) && 'event_type' in issue && issue.event_type === 'occurrence'
239+
);
240+
}
241+
234242
export function isEAPMeasurementValue(
235243
value: number | Measurement | undefined
236244
): value is number {

static/app/views/performance/newTraceDetails/traceModels/traceTree.tsx

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,8 @@ export declare namespace TraceTree {
144144
};
145145

146146
type EAPOccurrence = {
147+
culprit: string;
148+
description: string;
147149
event_id: string;
148150
event_type: 'occurrence';
149151
issue_id: number;
@@ -152,7 +154,8 @@ export declare namespace TraceTree {
152154
project_slug: string;
153155
start_timestamp: number;
154156
transaction: string;
155-
description?: string;
157+
type: number;
158+
short_id?: string;
156159
};
157160

158161
type EAPSpan = {

static/app/views/performance/newTraceDetails/traceModels/traceTreeTestUtils.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,9 @@ export function makeEAPOccurrence(
122122
event_type: 'occurrence',
123123
issue_id: 1,
124124
level: 'info',
125+
culprit: 'code',
126+
short_id: 'short_id',
127+
type: 0,
125128
...overrides,
126129
};
127130
}

0 commit comments

Comments
 (0)