import {useTheme} from '@emotion/react'; import styled from '@emotion/styled'; import ExternalLink from 'sentry/components/links/externalLink'; import {IconSpan} from 'sentry/icons'; import {t, tct} from 'sentry/locale'; import {space} from 'sentry/styles/space'; import getDuration from 'sentry/utils/duration/getDuration'; import {generateProfileFlamechartRouteWithQuery} from 'sentry/utils/profiling/routes'; import useProjects from 'sentry/utils/useProjects'; import {ProfileGroupProvider} from 'sentry/views/profiling/profileGroupProvider'; import {ProfileContext, ProfilesProvider} from 'sentry/views/profiling/profilesProvider'; import {getCustomInstrumentationLink} from '../../traceConfigurations'; import {ProfilePreview} from '../../traceDrawer/details/profiling/profilePreview'; import type {TraceTreeNodeDetailsProps} from '../../traceDrawer/tabs/traceTreeNodeDetails'; import type {MissingInstrumentationNode} from '../../traceModels/missingInstrumentationNode'; import {TraceTree} from '../../traceModels/traceTree'; import {makeTraceNodeBarColor} from '../../traceRow/traceBar'; import {getTraceTabTitle} from '../../traceState/traceTabs'; import {useHasTraceNewUi} from '../../useHasTraceNewUi'; import {type SectionCardKeyValueList, TraceDrawerComponents} from './styles'; export function MissingInstrumentationNodeDetails( props: TraceTreeNodeDetailsProps ) { const {projects} = useProjects(); const hasTraceNewUi = useHasTraceNewUi(); if (!hasTraceNewUi) { return ; } const {node, organization, onTabScrollToNode} = props; const event = node.previous.event ?? node.next.event ?? null; const project = projects.find(proj => proj.slug === event?.projectSlug); const profileId = event?.contexts?.profile?.profile_id ?? null; return ( {t('No Instrumentation')} {tct( 'It looks like there’s more than 100ms unaccounted for. This might be a missing service or just idle time. If you know there’s something going on, you can [customInstrumentationLink: add more spans using custom instrumentation].', { customInstrumentationLink: ( ), } )} {event?.projectSlug ? ( {profiles => ( )} ) : null} {t( "You can turn off the 'No Instrumentation' feature using the settings dropdown above." )} ); } const TextBlock = styled('div')` font-size: ${p => p.theme.fontSizeLarge}; line-height: 1.5; margin-bottom: ${space(2)}; `; function LegacyMissingInstrumentationNodeDetails({ node, onParentClick, onTabScrollToNode, organization, }: TraceTreeNodeDetailsProps) { const theme = useTheme(); const {projects} = useProjects(); const parentTransaction = TraceTree.ParentTransaction(node); const event = node.previous.event ?? node.next.event ?? null; const project = projects.find(proj => proj.slug === event?.projectSlug); const profileId = event?.contexts?.profile?.profile_id ?? null; const items: SectionCardKeyValueList = [ { key: 'duration', subject: t('Duration'), value: getDuration(node.value.timestamp - node.value.start_timestamp, 2, true), }, { key: 'previous_span', subject: t('Previous Span'), value: `${node.previous.value.op} - ${node.previous.value.description}`, }, { key: 'next_span', subject: t('Next Span'), value: `${node.next.value.op} - ${node.next.value.description}`, }, ]; if (profileId && project?.slug) { items.push({ key: 'profile_id', subject: 'Profile ID', value: ( ), }); } if (parentTransaction) { items.push({ key: 'parent_transaction', subject: t('Parent Transaction'), value: ( onParentClick(parentTransaction)}> {getTraceTabTitle(parentTransaction)} ), }); } return (
{t('Missing Instrumentation')}
{node.event?.projectSlug ? ( {profiles => ( )} ) : null}
); }