fix: enable custom aggregate interval for all data sources across application (#5074)

* fix: step interval not working for logs alerts

* fix: build issues

* fix: do not auto update the step interval when user enters some value

* feat: remove initial default 60 from step interval

* feat: revert last change

* fix: step interval mapping

* fix: remove initial default 60 from step interval

* Revert "fix: remove initial default 60 from step interval"

This reverts commit d23ce5e7e2860f37d433070d16793ceab85ed614.

* chore: fix backend

* chore: remove backend changes

* feat: enable the aggregate every interval across product

* fix: handle full view and landing view changes

---------

Co-authored-by: Srikanth Chekuri <srikanth.chekuri92@gmail.com>
This commit is contained in:
Vikrant Gupta 2024-06-12 17:38:05 +05:30 committed by GitHub
parent af8907d4f8
commit dc294ff6d5
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
11 changed files with 53 additions and 54 deletions

View File

@ -174,8 +174,8 @@ export const initialQueryBuilderFormValues: IBuilderQuery = {
sourceNames: alphabet, sourceNames: alphabet,
}), }),
disabled: false, disabled: false,
having: [],
stepInterval: 60, stepInterval: 60,
having: [],
limit: null, limit: null,
orderBy: [], orderBy: [],
groupBy: [], groupBy: [],

View File

@ -22,7 +22,6 @@ import PlotTag from 'container/NewWidget/LeftContainer/WidgetGraph/PlotTag';
import { BuilderUnitsFilter } from 'container/QueryBuilder/filters'; import { BuilderUnitsFilter } from 'container/QueryBuilder/filters';
import { useQueryBuilder } from 'hooks/queryBuilder/useQueryBuilder'; import { useQueryBuilder } from 'hooks/queryBuilder/useQueryBuilder';
import { useShareBuilderUrl } from 'hooks/queryBuilder/useShareBuilderUrl'; import { useShareBuilderUrl } from 'hooks/queryBuilder/useShareBuilderUrl';
import { updateStepInterval } from 'hooks/queryBuilder/useStepInterval';
import { MESSAGE, useIsFeatureDisabled } from 'hooks/useFeatureFlag'; import { MESSAGE, useIsFeatureDisabled } from 'hooks/useFeatureFlag';
import { useNotifications } from 'hooks/useNotifications'; import { useNotifications } from 'hooks/useNotifications';
import useUrlQuery from 'hooks/useUrlQuery'; import useUrlQuery from 'hooks/useUrlQuery';
@ -70,7 +69,7 @@ function FormAlertRules({
// init namespace for translations // init namespace for translations
const { t } = useTranslation('alerts'); const { t } = useTranslation('alerts');
const { minTime, maxTime, selectedTime: globalSelectedInterval } = useSelector< const { selectedTime: globalSelectedInterval } = useSelector<
AppState, AppState,
GlobalReducer GlobalReducer
>((state) => state.globalTime); >((state) => state.globalTime);
@ -191,7 +190,9 @@ function FormAlertRules({
} }
const query: Query = { ...currentQuery, queryType: val }; const query: Query = { ...currentQuery, queryType: val };
redirectWithQueryBuilderData(updateStepInterval(query, maxTime, minTime)); // update step interval is removed from here as if the user enters
// any value we will use that rather than auto update
redirectWithQueryBuilderData(query);
}; };
const { notifications } = useNotifications(); const { notifications } = useNotifications();
@ -540,7 +541,7 @@ function FormAlertRules({
queryCategory={currentQuery.queryType} queryCategory={currentQuery.queryType}
setQueryCategory={onQueryCategoryChange} setQueryCategory={onQueryCategoryChange}
alertType={alertType || AlertTypes.METRICS_BASED_ALERT} alertType={alertType || AlertTypes.METRICS_BASED_ALERT}
runQuery={handleRunQuery} runQuery={(): void => handleRunQuery(true)}
alertDef={alertDef} alertDef={alertDef}
panelType={panelType || PANEL_TYPES.TIME_SERIES} panelType={panelType || PANEL_TYPES.TIME_SERIES}
key={currentQuery.queryType} key={currentQuery.queryType}

View File

@ -15,7 +15,6 @@ import {
} from 'container/NewWidget/RightContainer/timeItems'; } from 'container/NewWidget/RightContainer/timeItems';
import PanelWrapper from 'container/PanelWrapper/PanelWrapper'; import PanelWrapper from 'container/PanelWrapper/PanelWrapper';
import { useGetQueryRange } from 'hooks/queryBuilder/useGetQueryRange'; import { useGetQueryRange } from 'hooks/queryBuilder/useGetQueryRange';
import { useStepInterval } from 'hooks/queryBuilder/useStepInterval';
import { useChartMutable } from 'hooks/useChartMutable'; import { useChartMutable } from 'hooks/useChartMutable';
import useUrlQuery from 'hooks/useUrlQuery'; import useUrlQuery from 'hooks/useUrlQuery';
import { getDashboardVariables } from 'lib/dashbaordVariables/getDashboardVariables'; import { getDashboardVariables } from 'lib/dashbaordVariables/getDashboardVariables';
@ -71,7 +70,7 @@ function FullView({
enum: widget?.timePreferance || 'GLOBAL_TIME', enum: widget?.timePreferance || 'GLOBAL_TIME',
}); });
const updatedQuery = useStepInterval(widget?.query); const updatedQuery = widget?.query;
const [requestData, setRequestData] = useState<GetQueryResultsProps>(() => { const [requestData, setRequestData] = useState<GetQueryResultsProps>(() => {
if (widget.panelTypes !== PANEL_TYPES.LIST) { if (widget.panelTypes !== PANEL_TYPES.LIST) {

View File

@ -3,7 +3,6 @@ import { QueryParams } from 'constants/query';
import { PANEL_TYPES } from 'constants/queryBuilder'; import { PANEL_TYPES } from 'constants/queryBuilder';
import { CustomTimeType } from 'container/TopNav/DateTimeSelectionV2/config'; import { CustomTimeType } from 'container/TopNav/DateTimeSelectionV2/config';
import { useGetQueryRange } from 'hooks/queryBuilder/useGetQueryRange'; import { useGetQueryRange } from 'hooks/queryBuilder/useGetQueryRange';
import { useStepInterval } from 'hooks/queryBuilder/useStepInterval';
import { useIntersectionObserver } from 'hooks/useIntersectionObserver'; import { useIntersectionObserver } from 'hooks/useIntersectionObserver';
import { getDashboardVariables } from 'lib/dashbaordVariables/getDashboardVariables'; import { getDashboardVariables } from 'lib/dashbaordVariables/getDashboardVariables';
import { GetQueryResultsProps } from 'lib/dashboard/getQueryResults'; import { GetQueryResultsProps } from 'lib/dashboard/getQueryResults';
@ -90,7 +89,7 @@ function GridCardGraph({
} }
}, [toScrollWidgetId, setToScrollWidgetId, widget.id]); }, [toScrollWidgetId, setToScrollWidgetId, widget.id]);
const updatedQuery = useStepInterval(widget?.query); const updatedQuery = widget?.query;
const isEmptyWidget = const isEmptyWidget =
widget?.id === PANEL_TYPES.EMPTY_WIDGET || isEmpty(widget); widget?.id === PANEL_TYPES.EMPTY_WIDGET || isEmpty(widget);

View File

@ -47,7 +47,7 @@ function LogExplorerQuerySection({
const isTable = panelTypes === PANEL_TYPES.TABLE; const isTable = panelTypes === PANEL_TYPES.TABLE;
const isList = panelTypes === PANEL_TYPES.LIST; const isList = panelTypes === PANEL_TYPES.LIST;
const config: QueryBuilderProps['filterConfigs'] = { const config: QueryBuilderProps['filterConfigs'] = {
stepInterval: { isHidden: isTable, isDisabled: true }, stepInterval: { isHidden: isTable, isDisabled: false },
having: { isHidden: isList, isDisabled: true }, having: { isHidden: isList, isDisabled: true },
filters: { filters: {
customKey: 'body', customKey: 'body',

View File

@ -12,7 +12,6 @@ import { QueryBuilderProps } from 'container/QueryBuilder/QueryBuilder.interface
import { useKeyboardHotkeys } from 'hooks/hotkeys/useKeyboardHotkeys'; import { useKeyboardHotkeys } from 'hooks/hotkeys/useKeyboardHotkeys';
import { useQueryBuilder } from 'hooks/queryBuilder/useQueryBuilder'; import { useQueryBuilder } from 'hooks/queryBuilder/useQueryBuilder';
import { useShareBuilderUrl } from 'hooks/queryBuilder/useShareBuilderUrl'; import { useShareBuilderUrl } from 'hooks/queryBuilder/useShareBuilderUrl';
import { updateStepInterval } from 'hooks/queryBuilder/useStepInterval';
import { useIsDarkMode } from 'hooks/useDarkMode'; import { useIsDarkMode } from 'hooks/useDarkMode';
import useUrlQuery from 'hooks/useUrlQuery'; import useUrlQuery from 'hooks/useUrlQuery';
import { defaultTo } from 'lodash-es'; import { defaultTo } from 'lodash-es';
@ -33,7 +32,6 @@ import { MetricRangePayloadProps } from 'types/api/metrics/getQueryRange';
import { Query } from 'types/api/queryBuilder/queryBuilderData'; import { Query } from 'types/api/queryBuilder/queryBuilderData';
import { EQueryType } from 'types/common/dashboard'; import { EQueryType } from 'types/common/dashboard';
import AppReducer from 'types/reducer/app'; import AppReducer from 'types/reducer/app';
import { GlobalReducer } from 'types/reducer/globalTime';
import ClickHouseQueryContainer from './QueryBuilder/clickHouse'; import ClickHouseQueryContainer from './QueryBuilder/clickHouse';
import PromQLQueryContainer from './QueryBuilder/promQL'; import PromQLQueryContainer from './QueryBuilder/promQL';
@ -46,10 +44,6 @@ function QuerySection({
const urlQuery = useUrlQuery(); const urlQuery = useUrlQuery();
const { registerShortcut, deregisterShortcut } = useKeyboardHotkeys(); const { registerShortcut, deregisterShortcut } = useKeyboardHotkeys();
const { minTime, maxTime } = useSelector<AppState, GlobalReducer>(
(state) => state.globalTime,
);
const { featureResponse } = useSelector<AppState, AppReducer>( const { featureResponse } = useSelector<AppState, AppReducer>(
(state) => state.app, (state) => state.app,
); );
@ -80,8 +74,6 @@ function QuerySection({
return; return;
} }
const updatedQuery = updateStepInterval(query, maxTime, minTime);
const selectedWidgetIndex = getSelectedWidgetIndex( const selectedWidgetIndex = getSelectedWidgetIndex(
selectedDashboard, selectedDashboard,
selectedWidget.id, selectedWidget.id,
@ -102,18 +94,16 @@ function QuerySection({
...previousWidgets, ...previousWidgets,
{ {
...selectedWidget, ...selectedWidget,
query: updatedQuery, query,
}, },
...nextWidgets, ...nextWidgets,
], ],
}, },
}); });
redirectWithQueryBuilderData(updatedQuery); redirectWithQueryBuilderData(query);
}, },
[ [
selectedDashboard, selectedDashboard,
maxTime,
minTime,
selectedWidget, selectedWidget,
setSelectedDashboard, setSelectedDashboard,
redirectWithQueryBuilderData, redirectWithQueryBuilderData,
@ -137,7 +127,7 @@ function QuerySection({
const filterConfigs: QueryBuilderProps['filterConfigs'] = useMemo(() => { const filterConfigs: QueryBuilderProps['filterConfigs'] = useMemo(() => {
const config: QueryBuilderProps['filterConfigs'] = { const config: QueryBuilderProps['filterConfigs'] = {
stepInterval: { isHidden: false, isDisabled: true }, stepInterval: { isHidden: false, isDisabled: false },
}; };
return config; return config;

View File

@ -22,7 +22,6 @@ import { QueryHistoryState } from 'container/LiveLogs/types';
import NewExplorerCTA from 'container/NewExplorerCTA'; import NewExplorerCTA from 'container/NewExplorerCTA';
import dayjs, { Dayjs } from 'dayjs'; import dayjs, { Dayjs } from 'dayjs';
import { useQueryBuilder } from 'hooks/queryBuilder/useQueryBuilder'; import { useQueryBuilder } from 'hooks/queryBuilder/useQueryBuilder';
import { updateStepInterval } from 'hooks/queryBuilder/useStepInterval';
import useUrlQuery from 'hooks/useUrlQuery'; import useUrlQuery from 'hooks/useUrlQuery';
import GetMinMax from 'lib/getMinMax'; import GetMinMax from 'lib/getMinMax';
import getTimeString from 'lib/getTimeString'; import getTimeString from 'lib/getTimeString';
@ -315,8 +314,6 @@ function DateTimeSelection({
return; return;
} }
const { maxTime, minTime } = GetMinMax(value, getTime());
if (!isLogsExplorerPage) { if (!isLogsExplorerPage) {
urlQuery.delete('startTime'); urlQuery.delete('startTime');
urlQuery.delete('endTime'); urlQuery.delete('endTime');
@ -333,7 +330,8 @@ function DateTimeSelection({
return; return;
} }
// the second boolean param directs the qb about the time change so to merge the query and retain the current state // the second boolean param directs the qb about the time change so to merge the query and retain the current state
initQueryBuilderData(updateStepInterval(stagedQuery, maxTime, minTime), true); // we removed update step interval to stop auto updating the value on time change
initQueryBuilderData(stagedQuery, true);
}; };
const onRefreshHandler = (): void => { const onRefreshHandler = (): void => {
@ -383,8 +381,6 @@ function DateTimeSelection({
setIsValidteRelativeTime(true); setIsValidteRelativeTime(true);
const { maxTime, minTime } = GetMinMax(dateTimeStr, getTime());
if (!isLogsExplorerPage) { if (!isLogsExplorerPage) {
urlQuery.delete('startTime'); urlQuery.delete('startTime');
urlQuery.delete('endTime'); urlQuery.delete('endTime');
@ -400,7 +396,8 @@ function DateTimeSelection({
} }
// the second boolean param directs the qb about the time change so to merge the query and retain the current state // the second boolean param directs the qb about the time change so to merge the query and retain the current state
initQueryBuilderData(updateStepInterval(stagedQuery, maxTime, minTime), true); // we removed update step interval to stop auto updating the value on time change
initQueryBuilderData(stagedQuery, true);
}; };
const getCustomOrIntervalTime = ( const getCustomOrIntervalTime = (

View File

@ -19,7 +19,7 @@ function QuerySection(): JSX.Element {
const filterConfigs: QueryBuilderProps['filterConfigs'] = useMemo(() => { const filterConfigs: QueryBuilderProps['filterConfigs'] = useMemo(() => {
const isList = panelTypes === PANEL_TYPES.LIST; const isList = panelTypes === PANEL_TYPES.LIST;
const config: QueryBuilderProps['filterConfigs'] = { const config: QueryBuilderProps['filterConfigs'] = {
stepInterval: { isHidden: false, isDisabled: true }, stepInterval: { isHidden: false, isDisabled: false },
limit: { isHidden: isList, isDisabled: true }, limit: { isHidden: isList, isDisabled: true },
having: { isHidden: isList, isDisabled: true }, having: { isHidden: isList, isDisabled: true },
}; };
@ -56,7 +56,7 @@ function QuerySection(): JSX.Element {
version="v3" // setting this to v3 as we this is rendered in logs explorer version="v3" // setting this to v3 as we this is rendered in logs explorer
actions={ actions={
<ButtonWrapper> <ButtonWrapper>
<Button onClick={handleRunQuery} type="primary"> <Button onClick={(): void => handleRunQuery()} type="primary">
Run Query Run Query
</Button> </Button>
</ButtonWrapper> </ButtonWrapper>

View File

@ -8,6 +8,7 @@ export const updateStepInterval = (
query: Widgets['query'], query: Widgets['query'],
maxTime: number, maxTime: number,
minTime: number, minTime: number,
shallUpdateStepInterval?: boolean,
): Widgets['query'] => { ): Widgets['query'] => {
const stepInterval = getStep({ const stepInterval = getStep({
start: minTime, start: minTime,
@ -15,6 +16,14 @@ export const updateStepInterval = (
inputFormat: 'ns', inputFormat: 'ns',
}); });
function getStepInterval(customInterval: number): number {
// if user enters some value then auto update should never come
if (shallUpdateStepInterval) {
return customInterval;
}
return stepInterval;
}
return { return {
...query, ...query,
builder: { builder: {
@ -22,7 +31,7 @@ export const updateStepInterval = (
queryData: queryData:
query?.builder?.queryData?.map((item) => ({ query?.builder?.queryData?.map((item) => ({
...item, ...item,
stepInterval, stepInterval: getStepInterval(item.stepInterval),
})) || [], })) || [],
}, },
}; };

View File

@ -752,26 +752,30 @@ export function QueryBuilderProvider({
[], [],
); );
const handleRunQuery = useCallback(() => { const handleRunQuery = useCallback(
redirectWithQueryBuilderData({ (shallUpdateStepInterval?: boolean) => {
...{ redirectWithQueryBuilderData({
...currentQuery, ...{
...updateStepInterval( ...currentQuery,
{ ...updateStepInterval(
builder: currentQuery.builder, {
clickhouse_sql: currentQuery.clickhouse_sql, builder: currentQuery.builder,
promql: currentQuery.promql, clickhouse_sql: currentQuery.clickhouse_sql,
id: currentQuery.id, promql: currentQuery.promql,
queryType, id: currentQuery.id,
unit: currentQuery.unit, queryType,
}, unit: currentQuery.unit,
maxTime, },
minTime, maxTime,
), minTime,
}, !!shallUpdateStepInterval,
queryType, ),
}); },
}, [currentQuery, queryType, maxTime, minTime, redirectWithQueryBuilderData]); queryType,
});
},
[currentQuery, queryType, maxTime, minTime, redirectWithQueryBuilderData],
);
useEffect(() => { useEffect(() => {
if (!compositeQueryParam) return; if (!compositeQueryParam) return;

View File

@ -222,7 +222,7 @@ export type QueryBuilderContextType = {
redirectToUrl?: typeof ROUTES[keyof typeof ROUTES], redirectToUrl?: typeof ROUTES[keyof typeof ROUTES],
shallStringify?: boolean, shallStringify?: boolean,
) => void; ) => void;
handleRunQuery: () => void; handleRunQuery: (shallUpdateStepInterval?: boolean) => void;
resetQuery: (newCurrentQuery?: QueryState) => void; resetQuery: (newCurrentQuery?: QueryState) => void;
handleOnUnitsChange: (units: Format['id']) => void; handleOnUnitsChange: (units: Format['id']) => void;
updateAllQueriesOperators: ( updateAllQueriesOperators: (