-
-
Notifications
You must be signed in to change notification settings - Fork 4.2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(new-trace): Adding trace header information to drawer. (#70717)
Before: <img width="1512" alt="Screenshot 2024-05-12 at 11 20 05 PM" src="https://github.com/getsentry/sentry/assets/60121741/721ed8fd-87db-4e17-9769-1ae5215a1c19"> After: <img width="1510" alt="Screenshot 2024-05-12 at 11 19 50 PM" src="https://github.com/getsentry/sentry/assets/60121741/3162dba2-0437-4093-8978-54f265b024f2"> --------- Co-authored-by: Abdullah Khan <[email protected]>
- Loading branch information
Showing
9 changed files
with
450 additions
and
51 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
229 changes: 229 additions & 0 deletions
229
static/app/views/performance/newTraceDetails/traceDrawer/tabs/trace/generalInfo.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,229 @@ | ||
import {Fragment, useMemo} from 'react'; | ||
|
||
import Link from 'sentry/components/links/link'; | ||
import LoadingIndicator from 'sentry/components/loadingIndicator'; | ||
import {Tooltip} from 'sentry/components/tooltip'; | ||
import {t, tn} from 'sentry/locale'; | ||
import type {Organization} from 'sentry/types'; | ||
import type {EventTransaction} from 'sentry/types/event'; | ||
import getDuration from 'sentry/utils/duration/getDuration'; | ||
import {getShortEventId} from 'sentry/utils/events'; | ||
import type { | ||
TraceErrorOrIssue, | ||
TraceFullDetailed, | ||
TraceMeta, | ||
TraceSplitResults, | ||
} from 'sentry/utils/performance/quickTrace/types'; | ||
import type {UseApiQueryResult} from 'sentry/utils/queryClient'; | ||
import type RequestError from 'sentry/utils/requestError/requestError'; | ||
import {useParams} from 'sentry/utils/useParams'; | ||
import {normalizeUrl} from 'sentry/utils/withDomainRequired'; | ||
import {SpanTimeRenderer} from 'sentry/views/performance/traces/fieldRenderers'; | ||
|
||
import {isTraceNode} from '../../../guards'; | ||
import type {TraceTree, TraceTreeNode} from '../../../traceModels/traceTree'; | ||
import {type SectionCardKeyValueList, TraceDrawerComponents} from '../../details/styles'; | ||
|
||
type GeneralInfoProps = { | ||
metaResults: UseApiQueryResult<TraceMeta | null, any>; | ||
node: TraceTreeNode<TraceTree.NodeValue> | null; | ||
organization: Organization; | ||
rootEventResults: UseApiQueryResult<EventTransaction, RequestError>; | ||
traces: TraceSplitResults<TraceFullDetailed> | null; | ||
tree: TraceTree; | ||
}; | ||
|
||
export function GeneralInfo(props: GeneralInfoProps) { | ||
const params = useParams<{traceSlug?: string}>(); | ||
|
||
const traceNode = props.tree.root.children[0]; | ||
|
||
const uniqueErrorIssues = useMemo(() => { | ||
if (!traceNode) { | ||
return []; | ||
} | ||
|
||
const unique: TraceErrorOrIssue[] = []; | ||
|
||
const seenIssues: Set<number> = new Set(); | ||
|
||
for (const issue of traceNode.errors) { | ||
if (seenIssues.has(issue.issue_id)) { | ||
continue; | ||
} | ||
seenIssues.add(issue.issue_id); | ||
unique.push(issue); | ||
} | ||
|
||
return unique; | ||
}, [traceNode]); | ||
|
||
const uniquePerformanceIssues = useMemo(() => { | ||
if (!traceNode) { | ||
return []; | ||
} | ||
|
||
const unique: TraceErrorOrIssue[] = []; | ||
const seenIssues: Set<number> = new Set(); | ||
|
||
for (const issue of traceNode.performance_issues) { | ||
if (seenIssues.has(issue.issue_id)) { | ||
continue; | ||
} | ||
seenIssues.add(issue.issue_id); | ||
unique.push(issue); | ||
} | ||
|
||
return unique; | ||
}, [traceNode]); | ||
|
||
const uniqueIssuesCount = uniqueErrorIssues.length + uniquePerformanceIssues.length; | ||
|
||
const traceSlug = useMemo(() => { | ||
return params.traceSlug?.trim() ?? ''; | ||
}, [params.traceSlug]); | ||
|
||
const isLoading = useMemo(() => { | ||
return ( | ||
props.metaResults.isLoading || | ||
(props.rootEventResults.isLoading && props.rootEventResults.fetchStatus !== 'idle') | ||
); | ||
}, [ | ||
props.metaResults.isLoading, | ||
props.rootEventResults.isLoading, | ||
props.rootEventResults.fetchStatus, | ||
]); | ||
|
||
if (isLoading) { | ||
return ( | ||
<TraceDrawerComponents.SectionCard | ||
items={[ | ||
{ | ||
key: 'trace_general_loading', | ||
subject: null, | ||
value: <LoadingIndicator size={30} />, | ||
}, | ||
]} | ||
title={t('General')} | ||
/> | ||
); | ||
} | ||
|
||
if (!(traceNode && isTraceNode(traceNode))) { | ||
throw new Error('Expected a trace node'); | ||
} | ||
|
||
if ( | ||
props.traces?.transactions.length === 0 && | ||
props.traces.orphan_errors.length === 0 | ||
) { | ||
return null; | ||
} | ||
|
||
const replay_id = props.rootEventResults?.data?.contexts?.replay?.replay_id; | ||
const browser = props.rootEventResults?.data?.contexts?.browser; | ||
|
||
const items: SectionCardKeyValueList = [ | ||
{ | ||
key: 'trace_id', | ||
subject: t('Trace ID'), | ||
value: <TraceDrawerComponents.CardValueWithCopy value={traceSlug} />, | ||
}, | ||
{ | ||
key: 'events', | ||
subject: t('Events'), | ||
value: props.metaResults.data | ||
? props.metaResults.data.transactions + props.metaResults.data.errors | ||
: '\u2014', | ||
}, | ||
{ | ||
key: 'issues', | ||
subject: t('Issues'), | ||
value: ( | ||
<Tooltip | ||
title={ | ||
uniqueIssuesCount > 0 ? ( | ||
<Fragment> | ||
<div> | ||
{tn('%s error issue', '%s error issues', uniqueErrorIssues.length)} | ||
</div> | ||
<div> | ||
{tn( | ||
'%s performance issue', | ||
'%s performance issues', | ||
uniquePerformanceIssues.length | ||
)} | ||
</div> | ||
</Fragment> | ||
) : null | ||
} | ||
showUnderline | ||
position="bottom" | ||
> | ||
{uniqueIssuesCount > 0 ? ( | ||
<TraceDrawerComponents.IssuesLink> | ||
{uniqueIssuesCount} | ||
</TraceDrawerComponents.IssuesLink> | ||
) : uniqueIssuesCount === 0 ? ( | ||
0 | ||
) : ( | ||
'\u2014' | ||
)} | ||
</Tooltip> | ||
), | ||
}, | ||
{ | ||
key: 'start_timestamp', | ||
subject: t('Start Timestamp'), | ||
value: traceNode.space?.[1] ? ( | ||
<SpanTimeRenderer timestamp={traceNode.space?.[0]} tooltipShowSeconds /> | ||
) : ( | ||
'\u2014' | ||
), | ||
}, | ||
{ | ||
key: 'total_duration', | ||
subject: t('Total Duration'), | ||
value: traceNode.space?.[1] | ||
? getDuration(traceNode.space[1] / 1000, 2, true) | ||
: '\u2014', | ||
}, | ||
{ | ||
key: 'user', | ||
subject: t('User'), | ||
value: | ||
props.rootEventResults?.data?.user?.email ?? | ||
props.rootEventResults?.data?.user?.name ?? | ||
'\u2014', | ||
}, | ||
{ | ||
key: 'browser', | ||
subject: t('Browser'), | ||
value: browser ? browser.name + ' ' + browser.version : '\u2014', | ||
}, | ||
]; | ||
|
||
if (replay_id) { | ||
items.push({ | ||
key: 'replay_id', | ||
subject: t('Replay ID'), | ||
value: ( | ||
<Link | ||
to={normalizeUrl( | ||
`/organizations/${props.organization.slug}/replays/${replay_id}/` | ||
)} | ||
> | ||
{getShortEventId(replay_id)} | ||
</Link> | ||
), | ||
}); | ||
} | ||
|
||
return ( | ||
<TraceDrawerComponents.SectionCard | ||
items={items} | ||
title={t('General')} | ||
disableTruncate | ||
/> | ||
); | ||
} |
Oops, something went wrong.