123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405 |
- import {DateTimeObject} from 'sentry/components/charts/utils';
- import {DefinedUseQueryResult, useQueries, useQuery} from 'sentry/utils/queryClient';
- import usePageFilters from 'sentry/utils/usePageFilters';
- import {getEndpointDetailSeriesQuery} from 'sentry/views/starfish/modules/APIModule/queries';
- import {HOST} from 'sentry/views/starfish/utils/constants';
- import {
- datetimeToClickhouseFilterTimestamps,
- getDateFilters,
- } from 'sentry/views/starfish/utils/dates';
- import {getDateQueryFilter} from 'sentry/views/starfish/utils/getDateQueryFilter';
- export enum SamplePopulationType {
- FASTEST = 'fastest',
- MEDIAN = 'median',
- SLOWEST = 'slowest',
- }
- export const useQueryGetSpanSamples = (options: {
- groupId: string;
- transactionName: string;
- p50?: number;
- user?: string;
- }) => {
- const {groupId, transactionName, user, p50} = options;
- const pageFilter = usePageFilters();
- const commonQueryOptions = {
- queryKey: [
- groupId,
- transactionName,
- user,
- pageFilter.selection.datetime,
- 'spanSamples',
- ],
- retry: false,
- initialData: [],
- enabled: Boolean(groupId && transactionName && p50),
- };
- const commonSamplesQueryOptions: GetSamplesQueryOptions = {
- groupId,
- transactionName,
- user,
- datetime: pageFilter.selection.datetime,
- p50,
- };
- const results = useQueries({
- queries: [
- {
- ...commonQueryOptions,
- queryKey: [...commonQueryOptions.queryKey, 'spanSamplesSlowest'],
- queryFn: () =>
- fetch(
- `${HOST}/?query=${getSpanSamplesQuery({
- ...commonSamplesQueryOptions,
- populationType: SamplePopulationType.SLOWEST,
- })}`
- ).then(res => res.json()),
- },
- {
- ...commonQueryOptions,
- queryKey: [...commonQueryOptions.queryKey, 'spanSamplesMedian'],
- queryFn: () =>
- fetch(
- `${HOST}/?query=${getSpanSamplesQuery({
- ...commonSamplesQueryOptions,
- populationType: SamplePopulationType.MEDIAN,
- })}`
- ).then(res => res.json()),
- },
- {
- ...commonQueryOptions,
- queryKey: [...commonQueryOptions.queryKey, 'spanSamplesFastest'],
- queryFn: () =>
- fetch(
- `${HOST}/?query=${getSpanSamplesQuery({
- ...commonSamplesQueryOptions,
- populationType: SamplePopulationType.FASTEST,
- })}`
- ).then(res => res.json()),
- },
- ],
- });
- return results;
- };
- export const useQueryGetFacetsBreakdown = (options: {
- groupId: string;
- transactionName: string;
- }): DefinedUseQueryResult<{domain: string; user: string}[]> => {
- const {groupId, transactionName} = options;
- const pageFilter = usePageFilters();
- const {startTime, endTime} = getDateFilters(pageFilter);
- const dateFilters = getDateQueryFilter(startTime, endTime);
- const query = `
- SELECT
- user, domain
- FROM spans_experimental_starfish
- WHERE
- group_id = '${groupId}'
- AND transaction = '${transactionName}'
- ${dateFilters}
- `;
- return useQuery({
- queryKey: ['facetBreakdown', groupId, transactionName],
- queryFn: () => fetch(`${HOST}/?query=${query}`).then(res => res.json()),
- retry: false,
- initialData: [],
- });
- };
- export const useQuerySpansInTransaction = (options: {
- groupId: string;
- }): DefinedUseQueryResult<
- {
- action: string;
- count: number;
- description: string;
- formatted_desc: string;
- module: 'http' | 'db' | 'cache' | 'none';
- p50: number;
- p95: number;
- span_operation: string;
- }[]
- > => {
- const {groupId} = options;
- const pageFilter = usePageFilters();
- const {startTime, endTime} = getDateFilters(pageFilter);
- const dateFilters = getDateQueryFilter(startTime, endTime);
- const query = `
- SELECT
- count() AS count,
- quantile(0.5)(exclusive_time) as p50,
- quantile(0.95)(exclusive_time) as p95,
- span_operation,
- action,
- module,
- description
- FROM
- spans_experimental_starfish
- WHERE
- group_id = '${groupId}'
- ${dateFilters}
- GROUP BY
- span_operation,
- description,
- action,
- module
- `;
- return useQuery({
- queryKey: ['spansInTransaction', groupId, dateFilters],
- queryFn: () => fetch(`${HOST}/?query=${query}&format=sql`).then(res => res.json()),
- retry: false,
- initialData: [],
- });
- };
- export const useQueryGetSpanAggregatesQuery = (options: {
- groupId: string;
- transactionName: string;
- description?: string;
- module?: string;
- }): DefinedUseQueryResult<
- {
- count: number;
- count_unique_transaction: number;
- count_unique_transaction_id: number;
- failure_rate: number;
- faiure_count: number;
- first_seen: string;
- last_seen: string;
- p50: number;
- p95: number;
- total_exclusive_time: number;
- }[]
- > => {
- const {description, groupId, transactionName, module} = options;
- const pageFilter = usePageFilters();
- const aggregatesQuery = getSidebarAggregatesQuery({
- description,
- transactionName,
- datetime: pageFilter.selection.datetime,
- groupId,
- module,
- });
- return useQuery({
- queryKey: ['span-aggregates', transactionName, groupId, description],
- queryFn: () =>
- fetch(`${HOST}/?query=${aggregatesQuery}&referrer=sidebar-aggregates`).then(res =>
- res.json()
- ),
- retry: false,
- initialData: [],
- });
- };
- export const useQueryGetSpanSeriesData = (options: {
- groupId: string;
- spanGroupOperation: string;
- transactionName: string;
- description?: string;
- module?: string;
- }): DefinedUseQueryResult<
- {
- count: number;
- failure_count: number;
- failure_rate: number;
- interval: string;
- p50: number;
- p95: number;
- spm: number;
- }[]
- > => {
- const {description, groupId, spanGroupOperation, transactionName, module} = options;
- const pageFilter = usePageFilters();
- const {getSeriesQuery} = getQueries(spanGroupOperation);
- const aggregatesQuery = getSeriesQuery({
- datetime: pageFilter.selection.datetime,
- groupId,
- module,
- description,
- interval: 12,
- transactionName,
- });
- return useQuery({
- queryKey: [
- 'seriesdata',
- transactionName,
- module,
- pageFilter.selection.datetime,
- groupId,
- ],
- queryFn: () =>
- fetch(`${HOST}/?query=${aggregatesQuery}&referrer=sidebar-aggregates`).then(res =>
- res.json()
- ),
- retry: false,
- initialData: [],
- });
- };
- type GetSamplesQueryOptions = {
- groupId: string;
- transactionName: string;
- datetime?: DateTimeObject;
- p50?: number;
- populationType?: SamplePopulationType;
- user?: string;
- };
- const getSpanSamplesQuery = ({
- groupId,
- transactionName,
- user,
- populationType,
- datetime,
- p50,
- }: GetSamplesQueryOptions) => {
- const {start_timestamp, end_timestamp} = datetimeToClickhouseFilterTimestamps(datetime);
- return `
- SELECT transaction_id, transaction, description, user, domain, span_id, sum(exclusive_time) as exclusive_time, abs(minus(exclusive_time, ${p50})) as diff
- FROM spans_experimental_starfish
- WHERE group_id = '${groupId}'
- ${transactionName ? `AND transaction = '${transactionName}'` : ''}
- ${user ? `AND user = '${user}'` : ''}
- ${start_timestamp ? `AND greaterOrEquals(start_timestamp, '${start_timestamp}')` : ''}
- ${end_timestamp ? `AND lessOrEquals(start_timestamp, '${end_timestamp}')` : ''}
- GROUP BY transaction_id, transaction, description, user, domain, span_id
- ORDER BY ${
- populationType === SamplePopulationType.SLOWEST || !populationType
- ? 'exclusive_time desc'
- : populationType === SamplePopulationType.FASTEST
- ? 'exclusive_time asc'
- : 'diff asc'
- }
- LIMIT 3
- `;
- };
- // Metrics request to get total count of events for a transaction
- export const useQueryGetUniqueTransactionCount = (options: {transactionName: string}) => {
- const {transactionName} = options;
- const {
- selection: {datetime},
- } = usePageFilters();
- const query = `?field=count%28%29&query=transaction%3A${encodeURIComponent(
- transactionName
- )}${
- datetime
- ? datetime.period
- ? `&statsPeriod=${datetime.period}`
- : datetime.start && datetime.end
- ? `&start=${encodeURIComponent(
- (datetime.start as Date).toISOString()
- )}&end=${encodeURIComponent((datetime.end as Date).toISOString())}`
- : null
- : null
- }&dataset=metricsEnhanced&project=1`;
- return useQuery({
- queryKey: ['uniqueTransactionCount', transactionName],
- queryFn: () =>
- fetch(`/api/0/organizations/sentry/events/${query}`).then(res => res.json()),
- retry: false,
- initialData: [],
- });
- };
- const getSidebarSeriesQuery = ({
- description,
- transactionName,
- datetime,
- groupId,
- module,
- interval,
- }) => {
- const {start_timestamp, end_timestamp} = datetimeToClickhouseFilterTimestamps(datetime);
- return `SELECT
- toStartOfInterval(start_timestamp, INTERVAL 12 HOUR) as interval,
- quantile(0.5)(exclusive_time) as p50,
- quantile(0.95)(exclusive_time) as p95,
- count() as count,
- divide(count(), multiply(${interval}, 60)) as spm,
- countIf(greaterOrEquals(status, 400) AND lessOrEquals(status, 599)) as failure_count,
- failure_count / count as failure_rate
- FROM spans_experimental_starfish
- WHERE module = '${module}'
- ${description ? `AND description = '${description}'` : ''}
- ${groupId ? `AND group_id = '${groupId}'` : ''}
- ${transactionName ? `AND transaction = '${transactionName}'` : ''}
- ${
- start_timestamp ? `AND greaterOrEquals(start_timestamp, '${start_timestamp}')` : ''
- }
- ${end_timestamp ? `AND lessOrEquals(start_timestamp, '${end_timestamp}')` : ''}
- GROUP BY interval
- ORDER BY interval asc
- `;
- };
- const getSidebarAggregatesQuery = ({
- description,
- transactionName,
- datetime,
- groupId,
- module,
- }) => {
- const {start_timestamp, end_timestamp} = datetimeToClickhouseFilterTimestamps(datetime);
- return `
- SELECT
- count() AS count,
- quantile(0.5)(exclusive_time) as p50,
- quantile(0.95)(exclusive_time) as p95,
- countIf(greaterOrEquals(status, 400) AND lessOrEquals(status, 599)) as failure_count,
- failure_count / count() as failure_rate,
- sum(exclusive_time) as total_exclusive_time,
- count(DISTINCT transaction_id) as count_unique_transaction_id,
- count(DISTINCT transaction) as count_unique_transaction,
- min(timestamp) as first_seen,
- max(timestamp) as last_seen
- FROM spans_experimental_starfish
- WHERE 1 == 1
- ${module ? `AND module = '${module}'` : ''}
- ${description ? `AND description = '${description}'` : ''}
- ${groupId ? `AND group_id = '${groupId}'` : ''}
- ${transactionName ? `AND transaction = '${transactionName}'` : ''}
- ${start_timestamp ? `AND greaterOrEquals(start_timestamp, '${start_timestamp}')` : ''}
- ${end_timestamp ? `AND lessOrEquals(start_timestamp, '${end_timestamp}')` : ''}
- ORDER BY count DESC
- LIMIT 5
- `;
- };
- function getQueries(spanGroupOperation: string) {
- switch (spanGroupOperation) {
- case 'db':
- case 'cache':
- return {
- getSeriesQuery: getSidebarSeriesQuery,
- getAggregatesQuery: getSidebarAggregatesQuery,
- };
- case 'http.client':
- return {
- getSeriesQuery: getEndpointDetailSeriesQuery,
- getAggregatesQuery: getSidebarAggregatesQuery,
- };
- default:
- return {
- getSeriesQuery: getSidebarSeriesQuery,
- getAggregatesQuery: getSidebarAggregatesQuery,
- };
- }
- }
|