spanEvidence.tsx 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  1. import styled from '@emotion/styled';
  2. import {LinkButton} from 'sentry/components/button';
  3. import {EventDataSection} from 'sentry/components/events/eventDataSection';
  4. import {getProblemSpansForSpanTree} from 'sentry/components/events/interfaces/performance/utils';
  5. import {IconSettings} from 'sentry/icons';
  6. import {t} from 'sentry/locale';
  7. import {space} from 'sentry/styles/space';
  8. import {
  9. EventTransaction,
  10. getIssueTypeFromOccurenceType,
  11. IssueType,
  12. Organization,
  13. } from 'sentry/types';
  14. import {ProfileGroupProvider} from 'sentry/views/profiling/profileGroupProvider';
  15. import {ProfileContext, ProfilesProvider} from 'sentry/views/profiling/profilesProvider';
  16. import {projectDetectorSettingsId} from 'sentry/views/settings/projectPerformance/projectPerformance';
  17. import TraceView from '../spans/traceView';
  18. import {TraceContextType} from '../spans/types';
  19. import WaterfallModel from '../spans/waterfallModel';
  20. import {SpanEvidenceKeyValueList} from './spanEvidenceKeyValueList';
  21. interface Props {
  22. event: EventTransaction;
  23. organization: Organization;
  24. projectSlug: string;
  25. }
  26. export type TraceContextSpanProxy = Omit<TraceContextType, 'span_id'> & {
  27. span_id: string; // TODO: Remove this temporary type.
  28. };
  29. export function SpanEvidenceSection({event, organization, projectSlug}: Props) {
  30. if (!event) {
  31. return null;
  32. }
  33. const {affectedSpanIds, focusedSpanIds} = getProblemSpansForSpanTree(event);
  34. const profileId = event.contexts?.profile?.profile_id ?? null;
  35. const hasProfilingFeature = organization.features.includes('profiling');
  36. const issueType = getIssueTypeFromOccurenceType(event.occurrence?.type);
  37. const hasConfigurableThresholds =
  38. organization.features.includes('project-performance-settings-admin') &&
  39. issueType &&
  40. ![
  41. IssueType.PERFORMANCE_N_PLUS_ONE_API_CALLS, // TODO Abdullah Khan: Remove check when thresholds for these two issues are configurable.
  42. IssueType.PERFORMANCE_CONSECUTIVE_HTTP,
  43. ].includes(issueType);
  44. return (
  45. <EventDataSection
  46. title={t('Span Evidence')}
  47. type="span-evidence"
  48. help={t(
  49. 'Span Evidence identifies the root cause of this issue, found in other similar events within the same issue.'
  50. )}
  51. actions={
  52. hasConfigurableThresholds && (
  53. <LinkButton
  54. data-test-id="span-evidence-settings-btn"
  55. to={`/settings/projects/${projectSlug}/performance/#${projectDetectorSettingsId}`}
  56. size="xs"
  57. >
  58. <StyledSettingsIcon size="xs" />
  59. Threshold Settings
  60. </LinkButton>
  61. )
  62. }
  63. >
  64. <SpanEvidenceKeyValueList event={event} projectSlug={projectSlug} />
  65. {hasProfilingFeature ? (
  66. <ProfilesProvider
  67. orgSlug={organization.slug}
  68. projectSlug={projectSlug}
  69. profileId={profileId || ''}
  70. >
  71. <ProfileContext.Consumer>
  72. {profiles => (
  73. <ProfileGroupProvider
  74. type="flamechart"
  75. input={profiles?.type === 'resolved' ? profiles.data : null}
  76. traceID={profileId || ''}
  77. >
  78. <TraceViewWrapper>
  79. <TraceView
  80. organization={organization}
  81. waterfallModel={
  82. new WaterfallModel(
  83. event as EventTransaction,
  84. affectedSpanIds,
  85. focusedSpanIds
  86. )
  87. }
  88. isEmbedded
  89. />
  90. </TraceViewWrapper>
  91. </ProfileGroupProvider>
  92. )}
  93. </ProfileContext.Consumer>
  94. </ProfilesProvider>
  95. ) : (
  96. <TraceViewWrapper>
  97. <TraceView
  98. organization={organization}
  99. waterfallModel={
  100. new WaterfallModel(
  101. event as EventTransaction,
  102. affectedSpanIds,
  103. focusedSpanIds
  104. )
  105. }
  106. isEmbedded
  107. />
  108. </TraceViewWrapper>
  109. )}
  110. </EventDataSection>
  111. );
  112. }
  113. const TraceViewWrapper = styled('div')`
  114. border: 1px solid ${p => p.theme.innerBorder};
  115. border-radius: ${p => p.theme.borderRadius};
  116. `;
  117. const StyledSettingsIcon = styled(IconSettings)`
  118. margin-right: ${space(0.5)};
  119. `;