destinationSummaryPage.tsx 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  1. import {Fragment} from 'react';
  2. import styled from '@emotion/styled';
  3. import {Breadcrumbs} from 'sentry/components/breadcrumbs';
  4. import ButtonBar from 'sentry/components/buttonBar';
  5. import FeedbackWidgetButton from 'sentry/components/feedback/widget/feedbackWidgetButton';
  6. import * as Layout from 'sentry/components/layouts/thirds';
  7. import {DatePageFilter} from 'sentry/components/organizations/datePageFilter';
  8. import {EnvironmentPageFilter} from 'sentry/components/organizations/environmentPageFilter';
  9. import PageFilterBar from 'sentry/components/organizations/pageFilterBar';
  10. import {ProjectPageFilter} from 'sentry/components/organizations/projectPageFilter';
  11. import {t} from 'sentry/locale';
  12. import {space} from 'sentry/styles/space';
  13. import {DurationUnit} from 'sentry/utils/discover/fields';
  14. import {decodeScalar} from 'sentry/utils/queryString';
  15. import {useLocation} from 'sentry/utils/useLocation';
  16. import useOrganization from 'sentry/utils/useOrganization';
  17. import {useOnboardingProject} from 'sentry/views/performance/browser/webVitals/utils/useOnboardingProject';
  18. import {MetricReadout} from 'sentry/views/performance/metricReadout';
  19. import * as ModuleLayout from 'sentry/views/performance/moduleLayout';
  20. import {ModulePageProviders} from 'sentry/views/performance/modulePageProviders';
  21. import Onboarding from 'sentry/views/performance/onboarding';
  22. import {LatencyChart} from 'sentry/views/performance/queues/charts/latencyChart';
  23. import {ThroughputChart} from 'sentry/views/performance/queues/charts/throughputChart';
  24. import {MessageSpanSamplesPanel} from 'sentry/views/performance/queues/destinationSummary/messageSpanSamplesPanel';
  25. import {TransactionsTable} from 'sentry/views/performance/queues/destinationSummary/transactionsTable';
  26. import {useQueuesMetricsQuery} from 'sentry/views/performance/queues/queries/useQueuesMetricsQuery';
  27. import {Referrer} from 'sentry/views/performance/queues/referrers';
  28. import {DESTINATION_TITLE} from 'sentry/views/performance/queues/settings';
  29. import {useModuleBreadcrumbs} from 'sentry/views/performance/utils/useModuleBreadcrumbs';
  30. import {getTimeSpentExplanation} from 'sentry/views/starfish/components/tableCells/timeSpentCell';
  31. function DestinationSummaryPage() {
  32. const organization = useOrganization();
  33. const onboardingProject = useOnboardingProject();
  34. const {query} = useLocation();
  35. const destination = decodeScalar(query.destination);
  36. const {data, isLoading} = useQueuesMetricsQuery({
  37. destination,
  38. referrer: Referrer.QUEUES_SUMMARY,
  39. });
  40. const errorRate = 1 - (data[0]?.['trace_status_rate(ok)'] ?? 0);
  41. const crumbs = useModuleBreadcrumbs('queue');
  42. return (
  43. <Fragment>
  44. <Layout.Header>
  45. <Layout.HeaderContent>
  46. <Breadcrumbs
  47. crumbs={[
  48. ...crumbs,
  49. {
  50. label: DESTINATION_TITLE,
  51. },
  52. ]}
  53. />
  54. <Layout.Title>{destination}</Layout.Title>
  55. </Layout.HeaderContent>
  56. <Layout.HeaderActions>
  57. <ButtonBar gap={1}>
  58. <FeedbackWidgetButton />
  59. </ButtonBar>
  60. </Layout.HeaderActions>
  61. </Layout.Header>
  62. <Layout.Body>
  63. <Layout.Main fullWidth>
  64. <ModuleLayout.Layout>
  65. <ModuleLayout.Full>
  66. <HeaderContainer>
  67. <PageFilterBar condensed>
  68. <ProjectPageFilter />
  69. <EnvironmentPageFilter />
  70. <DatePageFilter />
  71. </PageFilterBar>
  72. {!onboardingProject && (
  73. <MetricsRibbon>
  74. <MetricReadout
  75. title={t('Avg Time In Queue')}
  76. value={data[0]?.['avg(messaging.message.receive.latency)']}
  77. unit={DurationUnit.MILLISECOND}
  78. isLoading={isLoading}
  79. />
  80. <MetricReadout
  81. title={t('Avg Processing Time')}
  82. value={data[0]?.['avg_if(span.duration,span.op,queue.process)']}
  83. unit={DurationUnit.MILLISECOND}
  84. isLoading={isLoading}
  85. />
  86. <MetricReadout
  87. title={t('Error Rate')}
  88. value={errorRate}
  89. unit={'percentage'}
  90. isLoading={isLoading}
  91. />
  92. <MetricReadout
  93. title={t('Published')}
  94. value={data[0]?.['count_op(queue.publish)']}
  95. unit={'count'}
  96. isLoading={isLoading}
  97. />
  98. <MetricReadout
  99. title={t('Processed')}
  100. value={data[0]?.['count_op(queue.process)']}
  101. unit={'count'}
  102. isLoading={isLoading}
  103. />
  104. <MetricReadout
  105. title={t('Time Spent')}
  106. value={data[0]?.['sum(span.duration)']}
  107. unit={DurationUnit.MILLISECOND}
  108. tooltip={getTimeSpentExplanation(
  109. data[0]?.['time_spent_percentage(app,span.duration)']
  110. )}
  111. isLoading={isLoading}
  112. />
  113. </MetricsRibbon>
  114. )}
  115. </HeaderContainer>
  116. </ModuleLayout.Full>
  117. {onboardingProject && (
  118. <Onboarding organization={organization} project={onboardingProject} />
  119. )}
  120. {!onboardingProject && (
  121. <Fragment>
  122. <ModuleLayout.Half>
  123. <LatencyChart
  124. destination={destination}
  125. referrer={Referrer.QUEUES_SUMMARY_CHARTS}
  126. />
  127. </ModuleLayout.Half>
  128. <ModuleLayout.Half>
  129. <ThroughputChart
  130. destination={destination}
  131. referrer={Referrer.QUEUES_SUMMARY_CHARTS}
  132. />
  133. </ModuleLayout.Half>
  134. <ModuleLayout.Full>
  135. <Flex>
  136. <TransactionsTable />
  137. </Flex>
  138. </ModuleLayout.Full>
  139. </Fragment>
  140. )}
  141. </ModuleLayout.Layout>
  142. </Layout.Main>
  143. </Layout.Body>
  144. <MessageSpanSamplesPanel />
  145. </Fragment>
  146. );
  147. }
  148. function PageWithProviders() {
  149. return (
  150. <ModulePageProviders
  151. moduleName="queue"
  152. pageTitle={t('Destination Summary')}
  153. features={['insights-addon-modules', 'performance-queues-view']}
  154. >
  155. <DestinationSummaryPage />
  156. </ModulePageProviders>
  157. );
  158. }
  159. export default PageWithProviders;
  160. const Flex = styled('div')`
  161. display: flex;
  162. flex-direction: column;
  163. gap: ${space(2)};
  164. `;
  165. const MetricsRibbon = styled('div')`
  166. display: flex;
  167. flex-wrap: wrap;
  168. gap: ${space(4)};
  169. `;
  170. const HeaderContainer = styled('div')`
  171. display: flex;
  172. justify-content: space-between;
  173. `;