import {RouteComponentProps} from 'react-router'; import styled from '@emotion/styled'; import {Location} from 'history'; import Breadcrumbs from 'sentry/components/breadcrumbs'; import DatePageFilter from 'sentry/components/datePageFilter'; import FeatureBadge from 'sentry/components/featureBadge'; import * as Layout from 'sentry/components/layouts/thirds'; import PageFilterBar from 'sentry/components/organizations/pageFilterBar'; import {t} from 'sentry/locale'; import {space} from 'sentry/styles/space'; import type {Sort} from 'sentry/utils/discover/fields'; import {RateUnits} from 'sentry/utils/discover/fields'; import {formatRate} from 'sentry/utils/formatters'; import {useLocation} from 'sentry/utils/useLocation'; import useOrganization from 'sentry/utils/useOrganization'; import {normalizeUrl} from 'sentry/utils/withDomainRequired'; import {ModulePageProviders} from 'sentry/views/performance/database/modulePageProviders'; import {AVG_COLOR, THROUGHPUT_COLOR} from 'sentry/views/starfish/colours'; import Chart, {useSynchronizeCharts} from 'sentry/views/starfish/components/chart'; import ChartPanel from 'sentry/views/starfish/components/chartPanel'; import {SpanDescription} from 'sentry/views/starfish/components/spanDescription'; import {useFullSpanFromTrace} from 'sentry/views/starfish/queries/useFullSpanFromTrace'; import { SpanSummaryQueryFilters, useSpanMetrics, } from 'sentry/views/starfish/queries/useSpanMetrics'; import {useSpanMetricsSeries} from 'sentry/views/starfish/queries/useSpanMetricsSeries'; import {SpanFunction, SpanMetricsField} from 'sentry/views/starfish/types'; import {QueryParameterNames} from 'sentry/views/starfish/views/queryParameters'; import { getDurationChartTitle, getThroughputChartTitle, } from 'sentry/views/starfish/views/spans/types'; import {useModuleSort} from 'sentry/views/starfish/views/spans/useModuleSort'; import {Block, BlockContainer} from 'sentry/views/starfish/views/spanSummaryPage/block'; import {SampleList} from 'sentry/views/starfish/views/spanSummaryPage/sampleList'; import {SpanMetricsRibbon} from 'sentry/views/starfish/views/spanSummaryPage/spanMetricsRibbon'; import {SpanTransactionsTable} from 'sentry/views/starfish/views/spanSummaryPage/spanTransactionsTable'; type Query = { endpoint: string; endpointMethod: string; transaction: string; transactionMethod: string; [QueryParameterNames.SPANS_SORT]: string; }; type Props = { location: Location; } & RouteComponentProps; function SpanSummaryPage({params}: Props) { const organization = useOrganization(); const location = useLocation(); const {groupId} = params; const {transaction, transactionMethod, endpoint, endpointMethod} = location.query; const queryFilter: SpanSummaryQueryFilters = endpoint ? {transactionName: endpoint, 'transaction.method': endpointMethod} : {}; const sort = useModuleSort(QueryParameterNames.ENDPOINTS_SORT, DEFAULT_SORT); const {data: fullSpan} = useFullSpanFromTrace(groupId); const {data: spanMetrics} = useSpanMetrics( groupId, queryFilter, [ SpanMetricsField.SPAN_OP, SpanMetricsField.SPAN_DESCRIPTION, SpanMetricsField.SPAN_ACTION, SpanMetricsField.SPAN_DOMAIN, 'count()', `${SpanFunction.SPM}()`, `sum(${SpanMetricsField.SPAN_SELF_TIME})`, `avg(${SpanMetricsField.SPAN_SELF_TIME})`, `${SpanFunction.TIME_SPENT_PERCENTAGE}()`, `${SpanFunction.HTTP_ERROR_COUNT}()`, ], 'api.starfish.span-summary-page-metrics' ); const span = { ...spanMetrics, [SpanMetricsField.SPAN_GROUP]: groupId, } as { [SpanMetricsField.SPAN_OP]: string; [SpanMetricsField.SPAN_DESCRIPTION]: string; [SpanMetricsField.SPAN_ACTION]: string; [SpanMetricsField.SPAN_DOMAIN]: string; [SpanMetricsField.SPAN_GROUP]: string; }; const {isLoading: areSpanMetricsSeriesLoading, data: spanMetricsSeriesData} = useSpanMetricsSeries( groupId, queryFilter, [`avg(${SpanMetricsField.SPAN_SELF_TIME})`, 'spm()', 'http_error_count()'], 'api.starfish.span-summary-page-metrics-chart' ); useSynchronizeCharts([!areSpanMetricsSeriesLoading]); const spanMetricsThroughputSeries = { seriesName: span?.[SpanMetricsField.SPAN_OP]?.startsWith('db') ? 'Queries' : 'Requests', data: spanMetricsSeriesData?.['spm()'].data, }; return ( {t('Query Summary')} {span?.[SpanMetricsField.SPAN_DESCRIPTION] && ( )} formatRate(value, RateUnits.PER_MINUTE), }} /> {span && ( )} ); } const CHART_HEIGHT = 160; const DEFAULT_SORT: Sort = { kind: 'desc', field: 'time_spent_percentage(local)', }; const PaddedContainer = styled('div')` margin-bottom: ${space(2)}; `; const HeaderContainer = styled('div')` display: flex; justify-content: space-between; flex-wrap: wrap; `; const DescriptionContainer = styled('div')` width: 100%; margin-bottom: ${space(2)}; font-size: 1rem; line-height: 1.2; `; export default SpanSummaryPage;