diff --git a/static/app/views/performance/newTraceDetails/traceAnalytics.tsx b/static/app/views/performance/newTraceDetails/traceAnalytics.tsx
index fc423cb5bf46d7..bd0a6390a93b9d 100644
--- a/static/app/views/performance/newTraceDetails/traceAnalytics.tsx
+++ b/static/app/views/performance/newTraceDetails/traceAnalytics.tsx
@@ -71,6 +71,10 @@ const trackViewContinuousProfile = (organization: Organization) =>
trackAnalytics('trace.trace_layout.view_continuous_profile', {
organization,
});
+const trackViewTransactionProfile = (organization: Organization) =>
+ trackAnalytics('trace.trace_layout.view_transaction_profile', {
+ organization,
+ });
const trackTabPin = (organization: Organization) =>
trackAnalytics('trace.trace_layout.tab_pin', {
@@ -209,6 +213,7 @@ const traceAnalytics = {
trackShowInView,
trackViewEventJSON,
trackViewContinuousProfile,
+ trackViewTransactionProfile,
// Layout actions
trackLayoutChange,
trackDrawerMinimize,
diff --git a/static/app/views/performance/newTraceDetails/traceDrawer/details/styles.tsx b/static/app/views/performance/newTraceDetails/traceDrawer/details/styles.tsx
index 5761397441829b..429f8914fdd7f7 100644
--- a/static/app/views/performance/newTraceDetails/traceDrawer/details/styles.tsx
+++ b/static/app/views/performance/newTraceDetails/traceDrawer/details/styles.tsx
@@ -52,7 +52,10 @@ import {useParams} from 'sentry/utils/useParams';
import {traceAnalytics} from '../../traceAnalytics';
import {useTransaction} from '../../traceApi/useTransaction';
import {useDrawerContainerRef} from '../../traceDrawer/details/drawerContainerRefContext';
-import {makeTraceContinuousProfilingLink} from '../../traceDrawer/traceProfilingLink';
+import {
+ makeTraceContinuousProfilingLink,
+ makeTransactionProfilingLink,
+} from '../../traceDrawer/traceProfilingLink';
import {
isAutogroupedNode,
isMissingInstrumentationNode,
@@ -798,30 +801,44 @@ function NodeActions(props: {
organization,
});
- const profilerId: string = useMemo(() => {
- if (isTransactionNode(props.node)) {
- return props.node.value.profiler_id;
+ const transactionProfileTarget = useMemo(() => {
+ const profileId = isTransactionNode(props.node)
+ ? props.node.value.profile_id
+ : isSpanNode(props.node)
+ ? props.node.event?.contexts?.profile?.profile_id ?? ''
+ : '';
+ if (!profileId) {
+ return null;
}
- if (isSpanNode(props.node)) {
- return props.node.value.sentry_tags?.profiler_id ?? '';
+ return makeTransactionProfilingLink(profileId, {
+ orgSlug: props.organization.slug,
+ projectSlug: props.node.metadata.project_slug ?? '',
+ });
+ }, [props.node, props.organization]);
+
+ const continuousProfileTarget = useMemo(() => {
+ const profilerId = isTransactionNode(props.node)
+ ? props.node.value.profiler_id
+ : isSpanNode(props.node)
+ ? props.node.value.sentry_tags?.profiler_id ?? null
+ : null;
+ if (!profilerId) {
+ return null;
}
- return '';
- }, [props]);
-
- const profileLink = makeTraceContinuousProfilingLink(props.node, profilerId, {
- orgSlug: props.organization.slug,
- projectSlug: props.node.metadata.project_slug ?? '',
- traceId: params.traceSlug ?? '',
- threadId: getThreadIdFromNode(props.node, transaction),
- });
+ return makeTraceContinuousProfilingLink(props.node, profilerId, {
+ orgSlug: props.organization.slug,
+ projectSlug: props.node.metadata.project_slug ?? '',
+ traceId: params.traceSlug ?? '',
+ threadId: getThreadIdFromNode(props.node, transaction),
+ });
+ }, [params.traceSlug, props.node, props.organization, transaction]);
if (!hasNewTraceUi) {
return (
);
}
@@ -850,11 +867,23 @@ function NodeActions(props: {
/>
) : null}
- {profileLink ? (
-
+ {continuousProfileTarget ? (
+
+ traceAnalytics.trackViewContinuousProfile(props.organization)}
+ to={continuousProfileTarget}
+ size="xs"
+ aria-label={t('Profile')}
+ icon={}
+ />
+
+ ) : transactionProfileTarget ? (
+
traceAnalytics.trackViewTransactionProfile(props.organization)}
+ to={transactionProfileTarget}
size="xs"
- aria-label={t('Continuous Profile')}
+ aria-label={t('Profile')}
icon={}
/>
@@ -888,6 +917,7 @@ const ActionWrapper = styled('div')`
`;
function LegacyNodeActions(props: {
+ continuousProfileTarget: LocationDescriptor | null;
node: TraceTreeNode;
onTabScrollToNode: (
node:
@@ -896,20 +926,18 @@ function LegacyNodeActions(props: {
| SiblingAutogroupNode
| MissingInstrumentationNode
) => void;
- profileLink: LocationDescriptor | null;
- profilerId: string;
- transaction: EventTransaction | undefined;
+ organization: Organization;
+ transactionProfileTarget: LocationDescriptor | null;
eventSize?: number | undefined;
}) {
const navigate = useNavigate();
- const organization = useOrganization();
const items = useMemo((): MenuItemProps[] => {
const showInView: MenuItemProps = {
key: 'show-in-view',
label: t('Show in View'),
onAction: () => {
- traceAnalytics.trackShowInView(organization);
+ traceAnalytics.trackShowInView(props.organization);
props.onTabScrollToNode(props.node);
},
};
@@ -925,9 +953,9 @@ function LegacyNodeActions(props: {
const jsonDetails: MenuItemProps = {
key: 'json-details',
onAction: () => {
- traceAnalytics.trackViewEventJSON(organization);
+ traceAnalytics.trackViewEventJSON(props.organization);
window.open(
- `/api/0/projects/${organization.slug}/${projectSlug}/events/${eventId}/json/`,
+ `/api/0/projects/${props.organization.slug}/${projectSlug}/events/${eventId}/json/`,
'_blank'
);
},
@@ -936,28 +964,37 @@ function LegacyNodeActions(props: {
(typeof eventSize === 'number' ? ` (${formatBytesBase10(eventSize, 0)})` : ''),
};
- const continuousProfileLink: MenuItemProps | null = props.profileLink
+ const profileLink: MenuItemProps | null = props.continuousProfileTarget
? {
- key: 'continuous-profile',
+ key: 'profile',
onAction: () => {
- traceAnalytics.trackViewContinuousProfile(organization);
- navigate(props.profileLink!);
+ traceAnalytics.trackViewContinuousProfile(props.organization);
+ navigate(props.continuousProfileTarget!);
},
- label: t('Continuous Profile'),
+ label: t('View Profile'),
}
- : null;
+ : props.transactionProfileTarget
+ ? {
+ key: 'profile',
+ onAction: () => {
+ traceAnalytics.trackViewTransactionProfile(props.organization);
+ navigate(props.transactionProfileTarget!);
+ },
+ label: t('View Profile'),
+ }
+ : null;
if (isTransactionNode(props.node)) {
- return [showInView, jsonDetails, continuousProfileLink].filter(TypeSafeBoolean);
+ return [showInView, jsonDetails, profileLink].filter(TypeSafeBoolean);
}
if (isSpanNode(props.node)) {
- return [showInView, continuousProfileLink].filter(TypeSafeBoolean);
+ return [showInView, profileLink].filter(TypeSafeBoolean);
}
if (isMissingInstrumentationNode(props.node)) {
- return [showInView, continuousProfileLink].filter(TypeSafeBoolean);
+ return [showInView, profileLink].filter(TypeSafeBoolean);
}
if (isTraceErrorNode(props.node)) {
- return [showInView, continuousProfileLink].filter(TypeSafeBoolean);
+ return [showInView, profileLink].filter(TypeSafeBoolean);
}
if (isRootNode(props.node)) {
return [showInView];
@@ -967,20 +1004,24 @@ function LegacyNodeActions(props: {
}
return [showInView];
- }, [props, navigate, organization]);
+ }, [props, navigate]);
return (
- {props.profileLink ? (
-
- {t('Continuous Profile')}
+ {props.continuousProfileTarget ? (
+
+ {t('View Profile')}
+
+ ) : props.transactionProfileTarget ? (
+
+ {t('View Profile')}
) : null}