content.tsx 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. import {Fragment} from 'react';
  2. import type {Location} from 'history';
  3. import IdBadge from 'sentry/components/idBadge';
  4. import * as Layout from 'sentry/components/layouts/thirds';
  5. import type {Organization} from 'sentry/types/organization';
  6. import type {Project} from 'sentry/types/project';
  7. import type {SpanSlug} from 'sentry/utils/performance/suspectSpans/types';
  8. import useRouteAnalyticsEventNames from 'sentry/utils/routeAnalytics/useRouteAnalyticsEventNames';
  9. import useRouteAnalyticsParams from 'sentry/utils/routeAnalytics/useRouteAnalyticsParams';
  10. import {MutableSearch} from 'sentry/utils/tokenizeSearch';
  11. import {useLocation} from 'sentry/utils/useLocation';
  12. import {useParams} from 'sentry/utils/useParams';
  13. import Breadcrumb from 'sentry/views/performance/breadcrumb';
  14. import {SpanSummaryReferrer} from 'sentry/views/performance/transactionSummary/transactionSpans/spanSummary/referrers';
  15. import SpanSummaryCharts from 'sentry/views/performance/transactionSummary/transactionSpans/spanSummary/spanSummaryCharts';
  16. import SpanSummaryTable from 'sentry/views/performance/transactionSummary/transactionSpans/spanSummary/spanSummaryTable';
  17. import {getSelectedProjectPlatforms} from 'sentry/views/performance/utils';
  18. import {useSpanMetrics} from 'sentry/views/starfish/queries/useDiscover';
  19. import type {SpanMetricsQueryFilters} from 'sentry/views/starfish/types';
  20. import Tab from '../../tabs';
  21. import SpanSummaryControls from './spanSummaryControls';
  22. import SpanSummaryHeader from './spanSummaryHeader';
  23. type Props = {
  24. organization: Organization;
  25. project: Project | undefined;
  26. spanSlug: SpanSlug;
  27. transactionName: string;
  28. };
  29. export default function SpanSummary(props: Props) {
  30. const {organization, project, transactionName, spanSlug} = props;
  31. const location = useLocation();
  32. // customize the route analytics event we send
  33. useRouteAnalyticsEventNames(
  34. 'performance_views.span_summary.view',
  35. 'Performance Views: Span Summary page viewed'
  36. );
  37. useRouteAnalyticsParams({
  38. project_platforms: project ? getSelectedProjectPlatforms(location, [project]) : '',
  39. });
  40. return (
  41. <Fragment>
  42. <Layout.Header>
  43. <Layout.HeaderContent>
  44. <Breadcrumb
  45. organization={organization}
  46. location={location}
  47. transaction={{
  48. project: project?.id ?? '',
  49. name: transactionName,
  50. }}
  51. tab={Tab.SPANS}
  52. spanSlug={spanSlug}
  53. />
  54. <Layout.Title>
  55. {project && (
  56. <IdBadge
  57. project={project}
  58. avatarSize={28}
  59. hideName
  60. avatarProps={{hasTooltip: true, tooltip: project.slug}}
  61. />
  62. )}
  63. {transactionName}
  64. </Layout.Title>
  65. </Layout.HeaderContent>
  66. </Layout.Header>
  67. <Layout.Body>
  68. <Layout.Main fullWidth>
  69. <SpanSummaryContent
  70. location={location}
  71. organization={organization}
  72. project={project}
  73. transactionName={transactionName}
  74. />
  75. </Layout.Main>
  76. </Layout.Body>
  77. </Fragment>
  78. );
  79. }
  80. type ContentProps = {
  81. location: Location;
  82. organization: Organization;
  83. project: Project | undefined;
  84. transactionName: string;
  85. };
  86. function SpanSummaryContent(props: ContentProps) {
  87. const {transactionName, project} = props;
  88. const {spanSlug: spanParam} = useParams();
  89. const [spanOp, groupId] = spanParam.split(':');
  90. const filters: SpanMetricsQueryFilters = {
  91. 'span.group': groupId,
  92. 'span.op': spanOp,
  93. transaction: transactionName,
  94. };
  95. const {data: spanHeaderData} = useSpanMetrics(
  96. {
  97. search: MutableSearch.fromQueryObject(filters),
  98. fields: [
  99. 'span.description',
  100. 'avg(span.duration)',
  101. 'sum(span.self_time)',
  102. 'count()',
  103. ],
  104. },
  105. SpanSummaryReferrer.SPAN_SUMMARY_HEADER_DATA
  106. );
  107. const description = spanHeaderData[0]?.['span.description'];
  108. const timeSpent = spanHeaderData[0]?.['sum(span.self_time)'];
  109. const avgDuration = spanHeaderData[0]?.['avg(span.duration)'];
  110. const spanCount = spanHeaderData[0]?.['count()'];
  111. return (
  112. <Fragment>
  113. <SpanSummaryControls />
  114. <SpanSummaryHeader
  115. spanOp={spanOp}
  116. spanDescription={description}
  117. avgDuration={avgDuration}
  118. timeSpent={timeSpent}
  119. spanCount={spanCount}
  120. />
  121. <SpanSummaryCharts />
  122. <SpanSummaryTable project={project} />
  123. </Fragment>
  124. );
  125. }