123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732 |
- import {Moment, unix} from 'moment';
- import {EventTransaction, NewQuery} from 'sentry/types';
- import {
- DiscoverQueryComponentProps,
- DiscoverQueryPropsWithThresholds,
- useDiscoverQuery,
- } from 'sentry/utils/discover/discoverQuery';
- import EventView from 'sentry/utils/discover/eventView';
- import {useGenericDiscoverQuery} from 'sentry/utils/discover/genericDiscoverQuery';
- import {DiscoverDatasets} from 'sentry/utils/discover/types';
- import {DefinedUseQueryResult, useQuery} from 'sentry/utils/queryClient';
- import {useLocation} from 'sentry/utils/useLocation';
- import useOrganization from 'sentry/utils/useOrganization';
- import usePageFilters from 'sentry/utils/usePageFilters';
- import {DataRow} from 'sentry/views/starfish/components/databaseTableView';
- 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';
- import {
- UseSpansQueryReturnType,
- useWrappedDiscoverTimeseriesQuery,
- } from 'sentry/views/starfish/utils/useSpansQuery';
- export type TransactionListDataRow = {
- count: number;
- example: string;
- frequency: number;
- group_id: string;
- p75: number;
- transaction: string;
- uniqueEvents: number;
- };
- export const DEFAULT_WHERE = `
- startsWith(span_operation, 'db') and
- span_operation != 'db.redis' and
- module = 'db' and
- action != ''
- `;
- const SPM =
- 'if(duration > 0, divide(count(), (max(start_timestamp) - min(start_timestamp) as duration)/60), 0)';
- const ORDERBY = `
- -sum(exclusive_time), -count()
- `;
- const getActionSubquery = (date_filters: string) => {
- return `
- select action
- from default.spans_experimental_starfish
- where
- ${DEFAULT_WHERE}
- ${date_filters}
- group by action
- order by ${ORDERBY}
- limit 5
- `;
- };
- const getDomainSubquery = (date_filters: string) => {
- return `
- select domain
- from default.spans_experimental_starfish
- where
- ${DEFAULT_WHERE}
- ${date_filters} and
- domain != ''
- group by domain
- having
- ${SPM} > 0.05
- order by ${ORDERBY}
- limit 5
- `;
- };
- const getTransactionsFromTableSubquery = (tableNames: string[], dateFilters: string) => {
- const tableFilter = `domain IN ('${tableNames.join(`', '`)}')`;
- const filters = [DEFAULT_WHERE, tableFilter];
- return `
- SELECT
- transaction
- FROM default.spans_experimental_starfish
- WHERE
- ${filters.join(' AND ')}
- ${dateFilters}
- GROUP BY transaction
- ORDER BY ${ORDERBY}
- LIMIT 5
- `;
- };
- const SEVEN_DAYS = 7 * 24 * 60 * 60;
- const getNewColumn = (duration: number, startTime: Moment, endTime: Moment) => {
- const {start_timestamp, end_timestamp} = datetimeToClickhouseFilterTimestamps({
- start: unix(startTime.unix() + duration / 10).format('YYYY-MM-DD HH:mm:ss'),
- end: unix(endTime.unix() - duration / 10).format('YYYY-MM-DD HH:mm:ss'),
- });
- return duration > SEVEN_DAYS
- ? `(
- greater(min(start_timestamp), '${start_timestamp}') and
- greater(max(start_timestamp), '${end_timestamp}')
- ) as newish`
- : '0 as newish';
- };
- const getRetiredColumn = (duration: number, startTime: Moment, endTime: Moment) => {
- const {start_timestamp, end_timestamp} = datetimeToClickhouseFilterTimestamps({
- start: unix(startTime.unix() + duration / 10).format('YYYY-MM-DD HH:mm:ss'),
- end: unix(endTime.unix() - duration / 10).format('YYYY-MM-DD HH:mm:ss'),
- });
- return duration > SEVEN_DAYS
- ? `(
- less(max(start_timestamp), '${end_timestamp}') and
- less(min(start_timestamp), '${start_timestamp}')
- ) as retired`
- : '0 as retired';
- };
- export const useQueryDbTables = (): DefinedUseQueryResult<
- {key: string; value: string}[]
- > => {
- const pageFilter = usePageFilters();
- const {startTime, endTime} = getDateFilters(pageFilter);
- const dateFilters = getDateQueryFilter(startTime, endTime);
- const query = `
- select
- domain as key,
- quantile(0.75)(exclusive_time) as value
- from default.spans_experimental_starfish
- where
- ${DEFAULT_WHERE}
- ${dateFilters}
- group by domain
- order by ${ORDERBY}
- `;
- return useQuery({
- queryKey: ['table', pageFilter.selection.datetime],
- queryFn: () => fetch(`${HOST}/?query=${query}`).then(res => res.json()),
- retry: false,
- initialData: [],
- });
- };
- export const useQueryTopDbOperationsChart = (
- interval: number
- ): DefinedUseQueryResult<
- {action: string; count: number; interval: string; p50: number}[]
- > => {
- const pageFilter = usePageFilters();
- const {startTime, endTime} = getDateFilters(pageFilter);
- const dateFilters = getDateQueryFilter(startTime, endTime);
- const query = `
- select
- floor(quantile(0.50)(exclusive_time), 5) as p50,
- action,
- count() as count,
- toStartOfInterval(start_timestamp, INTERVAL ${interval} hour) as interval
- from default.spans_experimental_starfish
- where
- ${DEFAULT_WHERE}
- ${dateFilters} and
- action in (${getActionSubquery(dateFilters)})
- group by action, interval
- order by action, interval
- `;
- return useQuery({
- queryKey: ['topGraph', pageFilter.selection.datetime],
- queryFn: () => fetch(`${HOST}/?query=${query}`).then(res => res.json()),
- retry: false,
- initialData: [],
- });
- };
- type TopTransactionData = {
- interval: string;
- transaction: string;
- epm?: number;
- p75?: number;
- };
- export const useGetTransactionsForTables = (
- tableNames: string[],
- interval: number
- ): DefinedUseQueryResult<TopTransactionData[]> => {
- const pageFilter = usePageFilters();
- const location = useLocation();
- const {startTime, endTime} = getDateFilters(pageFilter);
- const dateFilters = getDateQueryFilter(startTime, endTime);
- const transactionNameQuery = getTransactionsFromTableSubquery(tableNames, dateFilters);
- const {start, end, period} = pageFilter.selection.datetime;
- const result1 = useQuery<{transaction: string}[]>({
- enabled: !!tableNames?.length,
- queryKey: ['topTransactionNames', tableNames.join(','), start, end],
- queryFn: () =>
- fetch(`${HOST}/?query=${transactionNameQuery}`).then(res => res.json()),
- retry: false,
- initialData: [],
- });
- const query: NewQuery = {
- id: undefined,
- name: 'Db module - epm/p75 for top transactions',
- query: `transaction:[${result1.data?.map(d => d.transaction).join(',')}]`,
- projects: [1],
- fields: ['transaction', 'epm()', 'p75(transaction.duration)'],
- version: 1,
- topEvents: '5',
- start: start?.toString(),
- end: end?.toString(),
- dataset: DiscoverDatasets.METRICS_ENHANCED,
- interval: `${interval}h`,
- yAxis: ['epm()', 'p75(transaction.duration)'],
- };
- const eventView = EventView.fromNewQueryWithLocation(query, location);
- eventView.statsPeriod = period ?? undefined;
- const result2 = useDiscoverEventsStatsQuery({
- eventView,
- referrer: 'api.starfish.database.charts',
- location,
- orgSlug: 'sentry',
- queryExtras: {
- interval: `${interval}h`, // This interval isn't being propogated from eventView
- yAxis: ['epm()', 'p75(transaction.duration)'], // workaround - eventView actually doesn't support multiple yAxis
- excludeOther: '1',
- topEvents: '5',
- per_page: undefined,
- },
- });
- const data: TopTransactionData[] = [];
- if (!result2.isLoading && result2.data) {
- Object.entries(result2.data).forEach(([transactionName, result]: [string, any]) => {
- result['epm()'].data.forEach(entry => {
- data.push({
- transaction: transactionName,
- interval: unix(entry[0]).format('YYYY-MM-DDTHH:mm:ss'),
- epm: entry[1][0].count,
- });
- });
- result['p75(transaction.duration)'].data.forEach(entry => {
- data.push({
- transaction: transactionName,
- interval: unix(entry[0]).format('YYYY-MM-DDTHH:mm:ss'),
- p75: entry[1][0].count,
- });
- });
- });
- }
- return {...result2, data} as DefinedUseQueryResult<TopTransactionData[]>;
- };
- type TopTableQuery = {
- count: number;
- domain: string;
- interval: string;
- p50: number;
- }[];
- export const useQueryTopTablesChart = (
- interval: number
- ): DefinedUseQueryResult<TopTableQuery> => {
- const pageFilter = usePageFilters();
- const {startTime, endTime} = getDateFilters(pageFilter);
- const dateFilters = getDateQueryFilter(startTime, endTime);
- const query = `
- select
- floor(quantile(0.50)(exclusive_time), 5) as p50,
- domain,
- divide(count(), multiply(${interval}, 60)) as count,
- toStartOfInterval(start_timestamp, INTERVAL ${interval} hour) as interval
- from default.spans_experimental_starfish
- where
- ${DEFAULT_WHERE}
- ${dateFilters} and
- domain in (${getDomainSubquery(dateFilters)})
- group by interval, domain
- order by interval, domain
- `;
- const result1 = useQuery<TopTableQuery>({
- queryKey: ['topTable', pageFilter.selection.datetime],
- queryFn: () => fetch(`${HOST}/?query=${query}`).then(res => res.json()),
- retry: false,
- initialData: [],
- });
- const tables = [...new Set(result1.data.map(d => d.domain))];
- const query2 = `
- select
- floor(quantile(0.50)(exclusive_time), 5) as p50,
- divide(count(), multiply(${interval}, 60)) as count,
- toStartOfInterval(start_timestamp, INTERVAL ${interval} hour) as interval
- from default.spans_experimental_starfish
- where
- domain not in ('${tables.join(`', '`)}')
- AND ${DEFAULT_WHERE}
- ${dateFilters}
- group by interval
- order by interval
- `;
- const result2 = useQuery<TopTableQuery>({
- enabled: !result1.isLoading && !!result1.data?.length,
- queryKey: ['topTableOther', pageFilter.selection.datetime],
- queryFn: () => fetch(`${HOST}/?query=${query2}`).then(res => res.json()),
- retry: false,
- initialData: [],
- });
- result2.data.forEach(d => (d.domain = 'other'));
- const joinedData = [...result1.data, ...result2.data];
- return {...result2, data: joinedData};
- };
- export const useQueryPanelTable = (
- row: DataRow,
- sortKey: string | undefined,
- sortDirection: string | undefined,
- transaction: string | undefined
- ): DefinedUseQueryResult<
- Pick<TransactionListDataRow, 'transaction' | 'count' | 'p75'>[]
- > => {
- const pageFilter = usePageFilters();
- const {startTime, endTime} = getDateFilters(pageFilter);
- const dateFilters = getDateQueryFilter(startTime, endTime);
- const orderBy = getOrderByFromKey(sortKey, sortDirection) ?? ORDERBY;
- const transactionFilter = transaction ? `and transaction='${transaction}'` : '';
- const query = `
- SELECT
- transaction,
- count() AS count,
- quantile(0.75)(exclusive_time) as p75,
- any(transaction_id) as example
- FROM spans_experimental_starfish
- WHERE
- ${DEFAULT_WHERE}
- ${dateFilters} AND
- group_id = '${row.group_id}'
- ${transactionFilter}
- GROUP BY transaction
- ORDER BY ${orderBy}
- LIMIT 5
- `;
- return useQuery({
- queryKey: [
- 'dbQueryDetailsTable',
- row.group_id,
- pageFilter.selection.datetime,
- sortKey,
- sortDirection,
- ],
- queryFn: () => fetch(`${HOST}/?query=${query}`).then(res => res.json()),
- retry: true,
- initialData: [],
- });
- };
- export const useQueryExampleTransaction = (
- row: DataRow
- ): DefinedUseQueryResult<{first: string; latest: string}[]> => {
- const pageFilter = usePageFilters();
- const {startTime, endTime} = getDateFilters(pageFilter);
- const dateFilters = getDateQueryFilter(startTime, endTime);
- const query = `
- SELECT
- minIf(transaction_id, equals(timestamp, '${row.lastSeen}')) as latest,
- minIf(transaction_id, equals(timestamp, '${row.firstSeen}')) as first
- FROM spans_experimental_starfish
- WHERE
- ${DEFAULT_WHERE}
- ${dateFilters} AND
- group_id = '${row.group_id}'
- HAVING latest > 0 and first > 0
- LIMIT 10
- `;
- return useQuery({
- queryKey: ['getExampleTransaction', row.group_id],
- queryFn: () => fetch(`${HOST}/?query=${query}`).then(res => res.json()),
- retry: true,
- initialData: [],
- });
- };
- export const useQueryPanelSparklines = (
- row: DataRow,
- sortKey: string | undefined,
- sortDirection: string | undefined,
- interval: number,
- transaction: string | undefined
- ): DefinedUseQueryResult<{interval: string; spm: number; transaction: string}[]> => {
- const pageFilter = usePageFilters();
- const {startTime, endTime} = getDateFilters(pageFilter);
- const dateFilters = getDateQueryFilter(startTime, endTime);
- const orderBy = getOrderByFromKey(sortKey, sortDirection) ?? ORDERBY;
- const transactionFilter = transaction ? `and transaction='${transaction}'` : '';
- const query = `
- SELECT
- transaction,
- toStartOfInterval(start_timestamp, INTERVAL ${interval} hour) as interval,
- quantile(0.50)(exclusive_time) AS p50,
- divide(count(), multiply(${interval}, 60)) as spm
- FROM spans_experimental_starfish
- WHERE
- transaction in (
- SELECT
- transaction
- FROM spans_experimental_starfish
- WHERE
- ${DEFAULT_WHERE}
- ${dateFilters} AND
- group_id = '${row.group_id}'
- ${transactionFilter}
- GROUP BY transaction
- ORDER BY ${orderBy}
- LIMIT 5
- ) and
- ${DEFAULT_WHERE}
- ${dateFilters} AND
- group_id = '${row.group_id}'
- GROUP BY transaction, interval
- ORDER BY transaction, interval, ${orderBy}
- `;
- return useQuery({
- queryKey: [
- 'dbQueryDetailsSparklines',
- row.group_id,
- pageFilter.selection.datetime,
- sortKey,
- sortDirection,
- ],
- queryFn: () => fetch(`${HOST}/?query=${query}`).then(res => res.json()),
- retry: true,
- initialData: [],
- });
- };
- export const useQueryPanelGraph = (row: DataRow, interval: number) => {
- const pageFilter = usePageFilters();
- const {startTime, endTime} = getDateFilters(pageFilter);
- const dateFilters = getDateQueryFilter(startTime, endTime);
- const query = `
- SELECT
- toStartOfInterval(start_timestamp, INTERVAL ${interval} HOUR) as interval,
- quantile(0.95)(exclusive_time) as p95,
- quantile(0.50)(exclusive_time) as p50,
- divide(count(), multiply(${interval}, 60)) as count
- FROM spans_experimental_starfish
- WHERE
- ${DEFAULT_WHERE}
- ${dateFilters} AND
- group_id = '${row.group_id}'
- GROUP BY interval
- ORDER BY interval
- `;
- return useQuery({
- queryKey: ['dbQueryDetailsGraph', row.group_id, pageFilter.selection.datetime],
- queryFn: () => fetch(`${HOST}/?query=${query}&format=sql`).then(res => res.json()),
- retry: false,
- initialData: [],
- });
- };
- export const useQueryPanelEventCount = (
- row: DataRow
- ): DefinedUseQueryResult<Pick<TransactionListDataRow, 'uniqueEvents' | 'count'>[]> => {
- const pageFilter = usePageFilters();
- const {startTime, endTime} = getDateFilters(pageFilter);
- const dateFilters = getDateQueryFilter(startTime, endTime);
- const query = `
- SELECT
- transaction,
- count(DISTINCT transaction_id) as uniqueEvents
- FROM spans_experimental_starfish
- WHERE
- ${DEFAULT_WHERE}
- ${dateFilters} AND
- group_id = '${row.group_id}'
- GROUP BY transaction
- ORDER BY ${ORDERBY}
- `;
- return useQuery({
- queryKey: ['dbQueryDetailsEventCount', row.group_id, pageFilter.selection.datetime],
- queryFn: () => fetch(`${HOST}/?query=${query}`).then(res => res.json()),
- retry: true,
- initialData: [],
- });
- };
- export const useQueryMainTable = (options: {
- action?: string;
- filterNew?: boolean;
- filterOld?: boolean;
- filterOutlier?: boolean;
- limit?: number;
- sortDirection?: string;
- sortKey?: string;
- table?: string;
- transaction?: string;
- }): DefinedUseQueryResult<DataRow[]> => {
- const {
- action,
- filterNew,
- filterOld,
- filterOutlier,
- sortDirection,
- sortKey,
- table,
- transaction,
- limit,
- } = options;
- const pageFilter = usePageFilters();
- const {startTime, endTime} = getDateFilters(pageFilter);
- const dateFilters = getDateQueryFilter(startTime, endTime);
- const transactionFilter = transaction ? `transaction='${transaction}'` : null;
- const tableFilter = table && table !== 'ALL' ? `domain = '${table}'` : undefined;
- const actionFilter = action && action !== 'ALL' ? `action = '${action}'` : undefined;
- const newFilter: string | undefined = filterNew ? 'newish = 1' : undefined;
- const oldFilter: string | undefined = filterOld ? 'retired = 1' : undefined;
- const outlierFilter: string | undefined = filterOutlier ? `${SPM} > 0.02` : undefined;
- const filters = [DEFAULT_WHERE, transactionFilter, tableFilter, actionFilter].filter(
- fil => !!fil
- );
- const duration = endTime.unix() - startTime.unix();
- const newColumn = getNewColumn(duration, startTime, endTime);
- const retiredColumn = getRetiredColumn(duration, startTime, endTime);
- const havingFilters = [newFilter, oldFilter, outlierFilter].filter(fil => !!fil);
- const orderBy = getOrderByFromKey(sortKey, sortDirection) ?? ORDERBY;
- const query = `
- select
- description,
- group_id, count() as count,
- ${SPM} as epm,
- quantile(0.75)(exclusive_time) as p75,
- quantile(0.50)(exclusive_time) as p50,
- quantile(0.95)(exclusive_time) as p95,
- uniq(transaction) as transactions,
- sum(exclusive_time) as total_time,
- domain,
- action,
- data_keys,
- data_values,
- min(start_timestamp) as firstSeen,
- max(start_timestamp) as lastSeen,
- ${newColumn},
- ${retiredColumn}
- from default.spans_experimental_starfish
- where
- ${filters.join(' AND ')}
- ${dateFilters}
- group by
- action,
- description,
- group_id,
- domain,
- data_keys,
- data_values
- ${havingFilters.length > 0 ? 'having' : ''}
- ${havingFilters.join(' and ')}
- order by ${orderBy}
- limit ${limit ?? 50}
- `;
- return useQuery<DataRow[]>({
- queryKey: [
- 'endpoints',
- transaction,
- table,
- pageFilter.selection.datetime,
- sortKey,
- sortDirection,
- newFilter,
- oldFilter,
- outlierFilter,
- ],
- cacheTime: 10000,
- queryFn: () => fetch(`${HOST}/?query=${query}&format=sql`).then(res => res.json()),
- retry: false,
- initialData: [],
- });
- };
- type QueryTransactionByTPMAndP75ReturnType = {
- count: number;
- 'count()': number;
- interval: string;
- 'p50(transaction.duration)': number;
- 'p95(transaction.duration)': number;
- transaction: string;
- }[];
- export const useQueryTransactionByTPMAndDuration = (
- transactionNames: string[],
- interval: number
- ): UseSpansQueryReturnType<QueryTransactionByTPMAndP75ReturnType> => {
- const {
- selection: {datetime},
- } = usePageFilters();
- return useWrappedDiscoverTimeseriesQuery({
- eventView: EventView.fromSavedQuery({
- name: '',
- fields: [
- 'transaction',
- 'epm()',
- 'p50(transaction.duration)',
- 'p95(transaction.duration)',
- ],
- yAxis: ['epm()', 'p50(transaction.duration)', 'p95(transaction.duration)'],
- orderby: '-count',
- query: `transaction:["${transactionNames.join('","')}"]`,
- topEvents: '5',
- start: datetime.start as string,
- end: datetime.end as string,
- range: datetime.period as string,
- dataset: DiscoverDatasets.METRICS,
- interval: `${interval}h`,
- projects: [1],
- version: 2,
- }),
- initialData: [],
- });
- };
- export const useQueryGetProfileIds = (transactionNames: string[]) => {
- const location = useLocation();
- const {slug: orgSlug} = useOrganization();
- const eventView = EventView.fromNewQueryWithLocation(
- {
- fields: ['transaction'],
- name: 'Db module - profile',
- query: `transaction:[${transactionNames.join(',')}] has:profile.id`,
- projects: [1],
- version: 1,
- orderby: 'id',
- },
- location
- );
- return useDiscoverQuery({eventView, location, orgSlug, queryExtras: {per_page: '10'}});
- };
- export const useQueryGetEvent = (
- transactionEventId?: string
- ): DefinedUseQueryResult<EventTransaction> => {
- const path = `/api/0/projects/sentry/sentry/events/${transactionEventId?.replaceAll(
- '-',
- ''
- )}/`;
- return useQuery({
- enabled: !!transactionEventId,
- queryKey: ['event', transactionEventId],
- queryFn: () => fetch(path).then(res => res.json()),
- retry: false,
- initialData: {},
- });
- };
- const getOrderByFromKey = (
- sortKey: string | undefined,
- sortDirection: string | undefined
- ) => {
- if (!sortDirection || !sortKey) {
- return undefined;
- }
- sortDirection ??= '';
- return `${sortKey} ${sortDirection}`;
- };
- const shouldRefetchData = (
- prevProps: DiscoverQueryPropsWithThresholds,
- nextProps: DiscoverQueryPropsWithThresholds
- ) => {
- return (
- prevProps.transactionName !== nextProps.transactionName ||
- prevProps.transactionThreshold !== nextProps.transactionThreshold ||
- prevProps.transactionThresholdMetric !== nextProps.transactionThresholdMetric
- );
- };
- // We should find a way to use this in discover
- export function useDiscoverEventsStatsQuery<T>(
- props: Omit<DiscoverQueryComponentProps, 'children'>
- ) {
- const afterFetch = (data, _) => {
- const {fields, ...otherMeta} = data.meta ?? {};
- return {
- ...data,
- meta: {...fields, ...otherMeta},
- };
- };
- return useGenericDiscoverQuery<T, unknown>({
- route: 'events-stats',
- shouldRefetchData,
- afterFetch,
- ...props,
- });
- }
- export const getDbAggregatesQuery = ({datetime, transaction}) => {
- const {start_timestamp, end_timestamp} = datetimeToClickhouseFilterTimestamps(datetime);
- return `
- SELECT
- description,
- toStartOfInterval(start_timestamp, INTERVAL 12 HOUR) as interval,
- divide(count(), multiply(12, 60)) as count,
- quantile(0.50)(exclusive_time) as p50,
- quantile(0.95)(exclusive_time) as p95
- FROM spans_experimental_starfish
- WHERE module = 'db'
- ${transaction ? `AND transaction = '${transaction}'` : ''}
- ${start_timestamp ? `AND greaterOrEquals(start_timestamp, '${start_timestamp}')` : ''}
- ${end_timestamp ? `AND lessOrEquals(start_timestamp, '${end_timestamp}')` : ''}
- GROUP BY description, interval
- ORDER BY interval asc
- `;
- };
|