From df9779c02b2714ce92fdcd96ed785dfce632963b Mon Sep 17 00:00:00 2001 From: Tony Xiao Date: Mon, 29 Jul 2024 14:41:16 -0400 Subject: [PATCH 1/2] feat(profiling): Make transactions table continuous profiling compatible This allows the transactions table to be populated with transasactions that have continuous profiles. --- .../profilingTransactionHovercard.tsx | 80 ++++++++++++------- .../analytics/profilingAnalyticsEvents.tsx | 1 + .../profiling/hooks/useProfileEvents.tsx | 4 +- static/app/views/profiling/content.tsx | 4 + 4 files changed, 60 insertions(+), 29 deletions(-) diff --git a/static/app/components/profiling/profilingTransactionHovercard.tsx b/static/app/components/profiling/profilingTransactionHovercard.tsx index 0d3c3461ebc4b8..b71fed6f22a6cf 100644 --- a/static/app/components/profiling/profilingTransactionHovercard.tsx +++ b/static/app/components/profiling/profilingTransactionHovercard.tsx @@ -21,6 +21,7 @@ import { generateProfileSummaryRouteWithQuery, } from 'sentry/utils/profiling/routes'; import {useLocation} from 'sentry/utils/useLocation'; +import {profilesRouteWithQuery} from 'sentry/views/performance/transactionSummary/transactionProfiles/utils'; import {Button} from '../button'; import Link from '../links/link'; @@ -37,50 +38,73 @@ export function ProfilingTransactionHovercard(props: ProfilingTransactionHoverca const {project, transaction, organization} = props; const {query} = useLocation(); - const linkToSummary = generateProfileSummaryRouteWithQuery({ + if (!organization.features.includes('continuous-profiling-compat')) { + const linkToSummary = generateProfileSummaryRouteWithQuery({ + query, + orgSlug: organization.slug, + projectSlug: project.slug, + transaction, + }); + + const triggerLink = ( + + trackAnalytics('profiling_views.go_to_transaction', { + organization, + source: 'transaction_hovercard.trigger', + }) + } + > + {transaction} + + ); + + return ( + + {transaction} + + + } + body={ + + } + showUnderline + > + {triggerLink} + + ); + } + + const linkToSummary = profilesRouteWithQuery({ query, orgSlug: organization.slug, - projectSlug: project.slug, + projectID: project.id, transaction, }); - const triggerLink = ( + return ( trackAnalytics('profiling_views.go_to_transaction', { organization, - source: 'transaction_hovercard.trigger', + source: 'profiling.landing.transaction_table', }) } > {transaction} ); - - return ( - - {transaction} - - - } - body={ - - } - showUnderline - > - {triggerLink} - - ); } export function ProfilingTransactionHovercardBody({ diff --git a/static/app/utils/analytics/profilingAnalyticsEvents.tsx b/static/app/utils/analytics/profilingAnalyticsEvents.tsx index e86e4f7158311b..639299e83224ee 100644 --- a/static/app/utils/analytics/profilingAnalyticsEvents.tsx +++ b/static/app/utils/analytics/profilingAnalyticsEvents.tsx @@ -13,6 +13,7 @@ type ProfilingEventSource = | 'profiling.global_suspect_functions' | 'profiling.issue.function_regression.list' | 'profiling.issue.function_regression.transactions' + | 'profiling.landing.transaction_table' | 'profiling_transaction.suspect_functions_table' | 'profiling_transaction.slowest_functions_table' | 'profiling_transaction.regressed_functions_table' diff --git a/static/app/utils/profiling/hooks/useProfileEvents.tsx b/static/app/utils/profiling/hooks/useProfileEvents.tsx index 217a62dd2d83ec..d65f59a689e6e6 100644 --- a/static/app/utils/profiling/hooks/useProfileEvents.tsx +++ b/static/app/utils/profiling/hooks/useProfileEvents.tsx @@ -14,6 +14,7 @@ export interface UseProfileEventsOptions fields: readonly F[]; referrer: string; sort: Sort; + baseQuery?: string; cursor?: string; datetime?: PageFilters['datetime']; enabled?: boolean; @@ -34,11 +35,12 @@ export function useProfileEvents({ refetchOnMount = true, datetime, projects, + baseQuery = 'has:profile.id', }: UseProfileEventsOptions) { const organization = useOrganization(); const {selection} = usePageFilters(); - query = `has:profile.id ${query ? `(${query})` : ''}`; + query = `${baseQuery} ${query ? `(${query})` : ''}`; const path = `/organizations/${organization.slug}/events/`; const endpointOptions = { diff --git a/static/app/views/profiling/content.tsx b/static/app/views/profiling/content.tsx index fbf2ca516c0330..dd7e98981c3f9a 100644 --- a/static/app/views/profiling/content.tsx +++ b/static/app/views/profiling/content.tsx @@ -297,6 +297,10 @@ function ProfilingContent({location}: ProfilingContentProps) { query, sort, referrer: 'api.profiling.landing-table', + // TODO: this should move into the hook at some point + baseQuery: organization.features.includes('continuous-profiling-compat') + ? '(has:profile.id OR (has:profiler.id has:thread.id))' + : 'has:profile.id', }); const transactionsError = From ed612154ffebd84b08871dfd93362ec61d8d85be Mon Sep 17 00:00:00 2001 From: Tony Xiao Date: Mon, 29 Jul 2024 15:29:44 -0400 Subject: [PATCH 2/2] move conditions into hook --- static/app/utils/profiling/hooks/useProfileEvents.tsx | 10 +++++++--- static/app/views/profiling/content.tsx | 7 +++---- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/static/app/utils/profiling/hooks/useProfileEvents.tsx b/static/app/utils/profiling/hooks/useProfileEvents.tsx index d65f59a689e6e6..151b27584b2b20 100644 --- a/static/app/utils/profiling/hooks/useProfileEvents.tsx +++ b/static/app/utils/profiling/hooks/useProfileEvents.tsx @@ -14,7 +14,7 @@ export interface UseProfileEventsOptions fields: readonly F[]; referrer: string; sort: Sort; - baseQuery?: string; + continuousProfilingCompat?: boolean; cursor?: string; datetime?: PageFilters['datetime']; enabled?: boolean; @@ -30,17 +30,21 @@ export function useProfileEvents({ referrer, query, sort, + continuousProfilingCompat, cursor, enabled = true, refetchOnMount = true, datetime, projects, - baseQuery = 'has:profile.id', }: UseProfileEventsOptions) { const organization = useOrganization(); const {selection} = usePageFilters(); - query = `${baseQuery} ${query ? `(${query})` : ''}`; + if (continuousProfilingCompat) { + query = `(has:profile.id OR (has:profiler.id has:thread.id)) ${query ? `(${query})` : ''}`; + } else { + query = `has:profile.id ${query ? `(${query})` : ''}`; + } const path = `/organizations/${organization.slug}/events/`; const endpointOptions = { diff --git a/static/app/views/profiling/content.tsx b/static/app/views/profiling/content.tsx index dd7e98981c3f9a..d97dad89d5ed96 100644 --- a/static/app/views/profiling/content.tsx +++ b/static/app/views/profiling/content.tsx @@ -297,10 +297,9 @@ function ProfilingContent({location}: ProfilingContentProps) { query, sort, referrer: 'api.profiling.landing-table', - // TODO: this should move into the hook at some point - baseQuery: organization.features.includes('continuous-profiling-compat') - ? '(has:profile.id OR (has:profiler.id has:thread.id))' - : 'has:profile.id', + continuousProfilingCompat: organization.features.includes( + 'continuous-profiling-compat' + ), }); const transactionsError =