Skip to content

Commit

Permalink
feat(new-trace): Replacing trace duration with root Duration in trace… (
Browse files Browse the repository at this point in the history
#81974)

<img width="1287" alt="Screenshot 2024-12-11 at 2 03 36 PM"
src="https://github.com/user-attachments/assets/154cefa1-f748-4671-afc5-e451ba019cfc"
/>

---------

Co-authored-by: Abdullah Khan <[email protected]>
  • Loading branch information
Abdkhan14 and Abdullah Khan authored Dec 11, 2024
1 parent af37b33 commit ec05e95
Show file tree
Hide file tree
Showing 4 changed files with 93 additions and 75 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,10 @@ import {useModuleURLBuilder} from 'sentry/views/insights/common/utils/useModuleU
import {useDomainViewFilters} from 'sentry/views/insights/pages/useFilters';
import {useTraceStateDispatch} from 'sentry/views/performance/newTraceDetails/traceState/traceStateProvider';

import {isRootTransaction} from '../../traceDetails/utils';
import type {TraceMetaQueryResults} from '../traceApi/useTraceMeta';
import TraceConfigurations from '../traceConfigurations';
import {isTraceNode} from '../traceGuards';
import type {TraceTree} from '../traceModels/traceTree';
import {useHasTraceNewUi} from '../useHasTraceNewUi';

Expand Down Expand Up @@ -102,6 +104,49 @@ const StyledPlaceholder = styled(Placeholder)<{_height: number; _width: number}>
width: ${p => p._width}px;
`;

const CANDIDATE_TRACE_TITLE_OPS = ['pageload', 'navigation'];

export const getRepresentativeTransaction = (
tree: TraceTree
): TraceTree.Transaction | null => {
const traceNode = tree.root.children[0];

if (!traceNode) {
return null;
}

if (!isTraceNode(traceNode)) {
throw new TypeError('Not trace node');
}

let firstRootTransaction: TraceTree.Transaction | null = null;
let candidateTransaction: TraceTree.Transaction | null = null;
let firstTransaction: TraceTree.Transaction | null = null;

for (const transaction of traceNode.value.transactions || []) {
// If we find a root transaction, we can stop looking and use it for the title.
if (!firstRootTransaction && isRootTransaction(transaction)) {
firstRootTransaction = transaction;
break;
} else if (
// If we haven't found a root transaction, but we found a candidate transaction
// with an op that we care about, we can use it for the title. We keep looking for
// a root.
!candidateTransaction &&
CANDIDATE_TRACE_TITLE_OPS.includes(transaction['transaction.op'])
) {
candidateTransaction = transaction;
continue;
} else if (!firstTransaction) {
// If we haven't found a root or candidate transaction, we can use the first transaction
// in the trace for the title.
firstTransaction = transaction;
}
}

return firstRootTransaction ?? candidateTransaction ?? firstTransaction;
};

function LegacyTraceMetadataHeader(props: TraceMetadataHeaderProps) {
const location = useLocation();
const {view} = useDomainViewFilters();
Expand Down Expand Up @@ -181,6 +226,8 @@ export function TraceMetaDataHeader(props: TraceMetadataHeaderProps) {
return <PlaceHolder organization={props.organization} />;
}

const representativeTransaction = getRepresentativeTransaction(props.tree);

return (
<HeaderLayout>
<HeaderContent>
Expand All @@ -195,12 +242,16 @@ export function TraceMetaDataHeader(props: TraceMetadataHeaderProps) {
/>
</HeaderRow>
<HeaderRow>
<Title traceSlug={props.traceSlug} tree={props.tree} />
<Title
traceSlug={props.traceSlug}
representativeTransaction={representativeTransaction}
/>
<Meta
organization={props.organization}
rootEventResults={props.rootEventResults}
tree={props.tree}
meta={props.metaResults.data}
representativeTransaction={representativeTransaction}
/>
</HeaderRow>
<StyledBreak />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ const SectionBody = styled('div')<{rightAlign?: boolean}>`
interface MetaProps {
meta: TraceMeta | undefined;
organization: Organization;
representativeTransaction: TraceTree.Transaction | null;
rootEventResults: UseApiQueryResult<EventTransaction, RequestError>;
tree: TraceTree;
}
Expand Down Expand Up @@ -134,11 +135,16 @@ export function Meta(props: MetaProps) {
) : null}
{traceNode ? (
<MetaSection
headingText={t('Trace Duration')}
headingText={t('Root Duration')}
rightAlignBody
bodyText={
traceNode.space[1] > 0
? getDuration(traceNode.space[1] / 1e3, 2, true)
props.representativeTransaction
? getDuration(
props.representativeTransaction.timestamp -
props.representativeTransaction.start_timestamp,
2,
true
)
: '\u2014'
}
/>
Expand Down
62 changes: 8 additions & 54 deletions static/app/views/performance/newTraceDetails/traceHeader/title.tsx
Original file line number Diff line number Diff line change
@@ -1,71 +1,25 @@
import {Fragment, useMemo} from 'react';
import {Fragment} from 'react';
import styled from '@emotion/styled';

import {CopyToClipboardButton} from 'sentry/components/copyToClipboardButton';
import ExternalLink from 'sentry/components/links/externalLink';
import {Tooltip} from 'sentry/components/tooltip';
import {t, tct} from 'sentry/locale';

import {isRootTransaction} from '../../traceDetails/utils';
import {isTraceNode} from '../traceGuards';
import type {TraceTree} from '../traceModels/traceTree';

const CANDIDATE_TRACE_TITLE_OPS = ['pageload', 'navigation'];

type TraceTitle = {
op: string;
transaction?: string;
} | null;

interface TitleProps {
representativeTransaction: TraceTree.Transaction | null;
traceSlug: string;
tree: TraceTree;
}

export function Title({traceSlug, tree}: TitleProps) {
const traceTitle: TraceTitle = useMemo(() => {
const trace = tree.root.children[0];

if (!trace) {
return null;
}

if (!isTraceNode(trace)) {
throw new TypeError('Not trace node');
}

let firstRootTransaction: TraceTitle = null;
let candidateTransaction: TraceTitle = null;
let firstTransaction: TraceTitle = null;

for (const transaction of trace.value.transactions || []) {
const title = {
op: transaction['transaction.op'],
transaction: transaction.transaction,
};

// If we find a root transaction, we can stop looking and use it for the title.
if (!firstRootTransaction && isRootTransaction(transaction)) {
firstRootTransaction = title;
break;
} else if (
// If we haven't found a root transaction, but we found a candidate transaction
// with an op that we care about, we can use it for the title. We keep looking for
// a root.
!candidateTransaction &&
CANDIDATE_TRACE_TITLE_OPS.includes(transaction['transaction.op'])
) {
candidateTransaction = title;
continue;
} else if (!firstTransaction) {
// If we haven't found a root or candidate transaction, we can use the first transaction
// in the trace for the title.
firstTransaction = title;
export function Title({traceSlug, representativeTransaction}: TitleProps) {
const traceTitle = representativeTransaction
? {
op: representativeTransaction['transaction.op'],
transaction: representativeTransaction.transaction,
}
}

return firstRootTransaction ?? candidateTransaction ?? firstTransaction;
}, [tree.root.children]);
: null;

return (
<div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,15 @@ import {
TraceRowConnectors,
type TraceRowProps,
} from '../traceRow/traceRow';
import {useHasTraceNewUi} from '../useHasTraceNewUi';

const NO_ERRORS = new Set<TraceTree.TraceError>();
const NO_PERFORMANCE_ISSUES = new Set<TraceTree.TracePerformanceIssue>();
const NO_PROFILES = [];

export function TraceRootRow(props: TraceRowProps<TraceTreeNode<TraceTree.Trace>>) {
const hasTraceNewUi = useHasTraceNewUi();

if (!isTraceNode(props.node)) {
throw new Error('Trace row rendered called on row that is not root');
}
Expand Down Expand Up @@ -77,23 +80,27 @@ export function TraceRootRow(props: TraceRowProps<TraceTreeNode<TraceTree.Trace>
className={props.spanColumnClassName}
onDoubleClick={props.onRowDoubleClick}
>
<TraceBar
node={props.node}
virtualized_index={props.virtualized_index}
manager={props.manager}
color={makeTraceNodeBarColor(props.theme, props.node)}
node_space={props.node.space}
errors={NO_ERRORS}
performance_issues={NO_PERFORMANCE_ISSUES}
profiles={NO_PROFILES}
/>
<button
ref={props.registerSpanArrowRef}
className="TraceArrow"
onClick={props.onSpanArrowClick}
>
<TraceIcons.Chevron direction="left" />
</button>
{!hasTraceNewUi && (
<Fragment>
<TraceBar
node={props.node}
virtualized_index={props.virtualized_index}
manager={props.manager}
color={makeTraceNodeBarColor(props.theme, props.node)}
node_space={props.node.space}
errors={NO_ERRORS}
performance_issues={NO_PERFORMANCE_ISSUES}
profiles={NO_PROFILES}
/>
<button
ref={props.registerSpanArrowRef}
className="TraceArrow"
onClick={props.onSpanArrowClick}
>
<TraceIcons.Chevron direction="left" />
</button>
</Fragment>
)}
</div>
</div>
);
Expand Down

0 comments on commit ec05e95

Please sign in to comment.