123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193 |
- import {useMemo} from 'react';
- import type {PageFilters} from 'sentry/types/core';
- import {parsePeriodToHours} from 'sentry/utils/dates';
- import {getDateTimeParams, getMetricsInterval} from 'sentry/utils/metrics';
- import {getUseCaseFromMRI, MRIToField} from 'sentry/utils/metrics/mri';
- import {useApiQuery} from 'sentry/utils/queryClient';
- import useOrganization from 'sentry/utils/useOrganization';
- import type {
- MetricsDataIntervalLadder,
- MetricsQueryApiResponse,
- MRI,
- } from '../../types/metrics';
- export function createMqlQuery({
- field,
- query,
- groupBy = [],
- }: {
- field: string;
- groupBy?: string[];
- query?: string;
- }) {
- let mql = field;
- if (query) {
- mql = `${mql}{${query}}`;
- }
- if (groupBy.length) {
- mql = `${mql} by (${groupBy.join(',')})`;
- }
- return mql;
- }
- export interface MetricsQueryApiRequestQuery {
- mri: MRI;
- name: string;
- op: string;
- alias?: string;
- groupBy?: string[];
- isQueryOnly?: boolean;
- limit?: number;
- orderBy?: 'asc' | 'desc';
- query?: string;
- }
- export interface MetricsQueryApiRequestFormula {
- formula: string;
- name: string;
- alias?: string;
- limit?: number;
- orderBy?: 'asc' | 'desc';
- }
- export type MetricsQueryApiQueryParams =
- | MetricsQueryApiRequestQuery
- | MetricsQueryApiRequestFormula;
- const getQueryInterval = (
- query: MetricsQueryApiRequestQuery,
- datetime: PageFilters['datetime'],
- intervalLadder?: MetricsDataIntervalLadder
- ) => {
- const useCase = getUseCaseFromMRI(query.mri) ?? 'custom';
- return getMetricsInterval(datetime, useCase, intervalLadder);
- };
- export function isMetricFormula(
- queryEntry: MetricsQueryApiQueryParams
- ): queryEntry is MetricsQueryApiRequestFormula {
- return 'formula' in queryEntry;
- }
- export function getMetricsQueryApiRequestPayload(
- queries: (MetricsQueryApiRequestQuery | MetricsQueryApiRequestFormula)[],
- {projects, environments, datetime}: PageFilters,
- {
- intervalLadder,
- interval: intervalParam,
- }: {
- autoOrder?: boolean;
- interval?: string;
- intervalLadder?: MetricsDataIntervalLadder;
- } = {}
- ) {
-
-
- const interval =
- intervalParam ??
- queries
- .map(query =>
- !isMetricFormula(query) ? getQueryInterval(query, datetime, intervalLadder) : '1m'
- )
- .reduce(
- (acc, curr) => (parsePeriodToHours(curr) > parsePeriodToHours(acc) ? curr : acc),
- '1m'
- );
- const requestQueries: {mql: string; name: string}[] = [];
- const requestFormulas: {
- mql: string;
- limit?: number;
- name?: string;
- order?: 'asc' | 'desc';
- }[] = [];
- queries.forEach((query, index) => {
- if (isMetricFormula(query)) {
- requestFormulas.push({
- mql: query.formula,
- limit: query.limit,
- order: query.orderBy,
- });
- return;
- }
- const {
- mri,
- op,
- groupBy,
- limit,
- orderBy,
- query: queryParam,
- name: nameParam,
- isQueryOnly,
- } = query;
- const name = nameParam || `query_${index + 1}`;
- const hasGroupBy = groupBy && groupBy.length > 0;
- requestQueries.push({
- name,
- mql: createMqlQuery({
- field: MRIToField(mri, op),
- query: queryParam,
- groupBy,
- }),
- });
- if (!isQueryOnly) {
- requestFormulas.push({
- mql: `$${name}`,
- limit,
- order: hasGroupBy ? orderBy : undefined,
- });
- }
- });
- return {
- query: {
- ...getDateTimeParams(datetime),
- project: projects,
- environment: environments,
- interval,
- },
- body: {
- queries: requestQueries,
- formulas: requestFormulas,
- },
- };
- }
- export function useMetricsQuery(
- queries: MetricsQueryApiQueryParams[],
- {projects, environments, datetime}: PageFilters,
- overrides: {interval?: string; intervalLadder?: MetricsDataIntervalLadder} = {},
- enableRefetch = true
- ) {
- const organization = useOrganization();
- const {query: queryToSend, body} = useMemo(
- () =>
- getMetricsQueryApiRequestPayload(
- queries,
- {datetime, projects, environments},
- {...overrides}
- ),
- [queries, datetime, projects, environments, overrides]
- );
- return useApiQuery<MetricsQueryApiResponse>(
- [
- `/organizations/${organization.slug}/metrics/query/`,
- {query: queryToSend, data: body, method: 'POST'},
- ],
- {
- retry: 0,
- staleTime: 0,
- refetchOnReconnect: enableRefetch,
- refetchOnWindowFocus: enableRefetch,
- refetchInterval: false,
- }
- );
- }
|