chore: update APM metrics to use v4 query range (#4638)

This commit is contained in:
Srikanth Chekuri 2024-03-04 10:15:43 +05:30 committed by GitHub
parent 0870030d1c
commit b3b7522250
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
35 changed files with 221 additions and 110 deletions

View File

@ -1,6 +1,7 @@
import { ApiV3Instance, ApiV4Instance } from 'api'; import { ApiV3Instance, ApiV4Instance } from 'api';
import { ErrorResponseHandler } from 'api/ErrorResponseHandler'; import { ErrorResponseHandler } from 'api/ErrorResponseHandler';
import { AxiosError } from 'axios'; import { AxiosError } from 'axios';
import { ENTITY_VERSION_V4 } from 'constants/app';
import { ErrorResponse, SuccessResponse } from 'types/api'; import { ErrorResponse, SuccessResponse } from 'types/api';
import { import {
MetricRangePayloadV3, MetricRangePayloadV3,
@ -13,7 +14,7 @@ export const getMetricsQueryRange = async (
signal: AbortSignal, signal: AbortSignal,
): Promise<SuccessResponse<MetricRangePayloadV3> | ErrorResponse> => { ): Promise<SuccessResponse<MetricRangePayloadV3> | ErrorResponse> => {
try { try {
if (version && version === 'v4') { if (version && version === ENTITY_VERSION_V4) {
const response = await ApiV4Instance.post('/query_range', props, { signal }); const response = await ApiV4Instance.post('/query_range', props, { signal });
return { return {

View File

@ -15,3 +15,4 @@ export const SIGNOZ_UPGRADE_PLAN_URL =
export const DASHBOARD_TIME_IN_DURATION = 'refreshInterval'; export const DASHBOARD_TIME_IN_DURATION = 'refreshInterval';
export const DEFAULT_ENTITY_VERSION = 'v3'; export const DEFAULT_ENTITY_VERSION = 'v3';
export const ENTITY_VERSION_V4 = 'v4';

View File

@ -1,3 +1,4 @@
import { ENTITY_VERSION_V4 } from 'constants/app';
import { import {
initialQueryBuilderFormValuesMap, initialQueryBuilderFormValuesMap,
initialQueryPromQLData, initialQueryPromQLData,
@ -24,7 +25,7 @@ const defaultAnnotations = {
export const alertDefaults: AlertDef = { export const alertDefaults: AlertDef = {
alertType: AlertTypes.METRICS_BASED_ALERT, alertType: AlertTypes.METRICS_BASED_ALERT,
version: 'v4', version: ENTITY_VERSION_V4,
condition: { condition: {
compositeQuery: { compositeQuery: {
builderQueries: { builderQueries: {

View File

@ -1,4 +1,5 @@
import { Form, Row } from 'antd'; import { Form, Row } from 'antd';
import { ENTITY_VERSION_V4 } from 'constants/app';
import FormAlertRules from 'container/FormAlertRules'; import FormAlertRules from 'container/FormAlertRules';
import { useGetCompositeQueryParam } from 'hooks/queryBuilder/useGetCompositeQueryParam'; import { useGetCompositeQueryParam } from 'hooks/queryBuilder/useGetCompositeQueryParam';
import { useEffect, useState } from 'react'; import { useEffect, useState } from 'react';
@ -44,7 +45,7 @@ function CreateRules(): JSX.Element {
default: default:
setInitValues({ setInitValues({
...alertDefaults, ...alertDefaults,
version: version || 'v4', version: version || ENTITY_VERSION_V4,
}); });
} }
}; };

View File

@ -2,6 +2,7 @@ import './QuerySection.styles.scss';
import { Button, Tabs, Tooltip } from 'antd'; import { Button, Tabs, Tooltip } from 'antd';
import { ALERTS_DATA_SOURCE_MAP } from 'constants/alerts'; import { ALERTS_DATA_SOURCE_MAP } from 'constants/alerts';
import { ENTITY_VERSION_V4 } from 'constants/app';
import { PANEL_TYPES } from 'constants/queryBuilder'; import { PANEL_TYPES } from 'constants/queryBuilder';
import { QBShortcuts } from 'constants/shortcuts/QBShortcuts'; import { QBShortcuts } from 'constants/shortcuts/QBShortcuts';
import { QueryBuilder } from 'container/QueryBuilder'; import { QueryBuilder } from 'container/QueryBuilder';
@ -55,7 +56,8 @@ function QuerySection({
initialDataSource: ALERTS_DATA_SOURCE_MAP[alertType], initialDataSource: ALERTS_DATA_SOURCE_MAP[alertType],
}} }}
showFunctions={ showFunctions={
alertType === AlertTypes.METRICS_BASED_ALERT && alertDef.version === 'v4' alertType === AlertTypes.METRICS_BASED_ALERT &&
alertDef.version === ENTITY_VERSION_V4
} }
version={alertDef.version || 'v3'} version={alertDef.version || 'v3'}
/> />

View File

@ -40,6 +40,7 @@ function FullView({
fullViewOptions = true, fullViewOptions = true,
onClickHandler, onClickHandler,
name, name,
version,
originalName, originalName,
yAxisUnit, yAxisUnit,
options, options,
@ -97,7 +98,7 @@ function FullView({
globalSelectedInterval: globalSelectedTime, globalSelectedInterval: globalSelectedTime,
variables: getDashboardVariables(selectedDashboard?.data.variables), variables: getDashboardVariables(selectedDashboard?.data.variables),
}, },
selectedDashboard?.data?.version || DEFAULT_ENTITY_VERSION, selectedDashboard?.data?.version || version || DEFAULT_ENTITY_VERSION,
{ {
queryKey: `FullViewGetMetricsQueryRange-${selectedTime.enum}-${globalSelectedTime}-${widget.id}`, queryKey: `FullViewGetMetricsQueryRange-${selectedTime.enum}-${globalSelectedTime}-${widget.id}`,
enabled: !isDependedDataLoaded && widget.panelTypes !== PANEL_TYPES.LIST, // Internally both the list view panel has it's own query range api call, so we don't need to call it again enabled: !isDependedDataLoaded && widget.panelTypes !== PANEL_TYPES.LIST, // Internally both the list view panel has it's own query range api call, so we don't need to call it again

View File

@ -50,6 +50,7 @@ export interface FullViewProps {
fullViewOptions?: boolean; fullViewOptions?: boolean;
onClickHandler?: OnClickPluginOpts['onClick']; onClickHandler?: OnClickPluginOpts['onClick'];
name: string; name: string;
version?: string;
originalName: string; originalName: string;
options: uPlot.Options; options: uPlot.Options;
yAxisUnit?: string; yAxisUnit?: string;

View File

@ -39,6 +39,7 @@ function WidgetGraphComponent({
queryResponse, queryResponse,
errorMessage, errorMessage,
name, name,
version,
threshold, threshold,
headerMenuList, headerMenuList,
isWarning, isWarning,
@ -283,6 +284,7 @@ function WidgetGraphComponent({
> >
<FullView <FullView
name={`${name}expanded`} name={`${name}expanded`}
version={version}
originalName={name} originalName={name}
widget={widget} widget={widget}
yAxisUnit={widget.yAxisUnit} yAxisUnit={widget.yAxisUnit}

View File

@ -237,6 +237,7 @@ function GridCardGraph({
errorMessage={errorMessage} errorMessage={errorMessage}
isWarning={false} isWarning={false}
name={name} name={name}
version={version}
onDragSelect={onDragSelect} onDragSelect={onDragSelect}
threshold={threshold} threshold={threshold}
headerMenuList={menuList} headerMenuList={menuList}

View File

@ -23,6 +23,7 @@ export interface WidgetGraphComponentProps extends UplotProps {
>; >;
errorMessage: string | undefined; errorMessage: string | undefined;
name: string; name: string;
version?: string;
onDragSelect: (start: number, end: number) => void; onDragSelect: (start: number, end: number) => void;
onClickHandler?: OnClickPluginOpts['onClick']; onClickHandler?: OnClickPluginOpts['onClick'];
threshold?: ReactNode; threshold?: ReactNode;

View File

@ -10,6 +10,7 @@ import {
import DynamicColumnTable from 'components/ResizeTable/DynamicColumnTable'; import DynamicColumnTable from 'components/ResizeTable/DynamicColumnTable';
import LabelColumn from 'components/TableRenderer/LabelColumn'; import LabelColumn from 'components/TableRenderer/LabelColumn';
import TextToolTip from 'components/TextToolTip'; import TextToolTip from 'components/TextToolTip';
import { ENTITY_VERSION_V4 } from 'constants/app';
import ROUTES from 'constants/routes'; import ROUTES from 'constants/routes';
import { useGetAllDashboard } from 'hooks/dashboard/useGetAllDashboard'; import { useGetAllDashboard } from 'hooks/dashboard/useGetAllDashboard';
import useComponentPermission from 'hooks/useComponentPermission'; import useComponentPermission from 'hooks/useComponentPermission';
@ -210,7 +211,7 @@ function DashboardsList(): JSX.Element {
ns: 'dashboard', ns: 'dashboard',
}), }),
uploadedGrafana: false, uploadedGrafana: false,
version: 'v4', version: ENTITY_VERSION_V4,
}); });
if (response.statusCode === 200) { if (response.statusCode === 200) {

View File

@ -113,9 +113,13 @@ export const databaseCallsAvgDuration = ({
const disabled = [true, true]; const disabled = [true, true];
const legendFormulas = ['Average Duration']; const legendFormulas = ['Average Duration'];
const expressions = [FORMULA.DATABASE_CALLS_AVG_DURATION]; const expressions = [FORMULA.DATABASE_CALLS_AVG_DURATION];
const aggregateOperators = [ const timeAggregateOperators = [
MetricAggregateOperator.SUM_RATE, MetricAggregateOperator.RATE,
MetricAggregateOperator.SUM_RATE, MetricAggregateOperator.RATE,
];
const spaceAggregateOperators = [
MetricAggregateOperator.SUM,
MetricAggregateOperator.SUM,
]; ];
const dataSource = DataSource.METRICS; const dataSource = DataSource.METRICS;
@ -126,7 +130,8 @@ export const databaseCallsAvgDuration = ({
disabled, disabled,
expressions, expressions,
legendFormulas, legendFormulas,
aggregateOperators, timeAggregateOperators,
spaceAggregateOperators,
dataSource, dataSource,
}); });
}; };

View File

@ -93,9 +93,13 @@ export const externalCallErrorPercent = ({
const additionalItems = [additionalItemsA, additionalItemsB]; const additionalItems = [additionalItemsA, additionalItemsB];
const aggregateOperators = [ const timeAggregateOperators = [
MetricAggregateOperator.SUM_RATE, MetricAggregateOperator.RATE,
MetricAggregateOperator.SUM_RATE, MetricAggregateOperator.RATE,
];
const spaceAggregateOperators = [
MetricAggregateOperator.SUM,
MetricAggregateOperator.SUM,
]; ];
const legends = [legend, legend]; const legends = [legend, legend];
const dataSource = DataSource.METRICS; const dataSource = DataSource.METRICS;
@ -108,7 +112,8 @@ export const externalCallErrorPercent = ({
disabled, disabled,
expressions, expressions,
legendFormulas, legendFormulas,
aggregateOperators, timeAggregateOperators,
spaceAggregateOperators,
dataSource, dataSource,
}); });
}; };
@ -152,9 +157,13 @@ export const externalCallDuration = ({
const additionalItems = [additionalItemsA, additionalItemsA]; const additionalItems = [additionalItemsA, additionalItemsA];
const legends = [legend, legend]; const legends = [legend, legend];
const aggregateOperators = [ const timeAggregateOperators = [
MetricAggregateOperator.SUM_RATE, MetricAggregateOperator.RATE,
MetricAggregateOperator.SUM_RATE, MetricAggregateOperator.RATE,
];
const spaceAggregateOperators = [
MetricAggregateOperator.SUM,
MetricAggregateOperator.SUM,
]; ];
const dataSource = DataSource.METRICS; const dataSource = DataSource.METRICS;
@ -165,7 +174,8 @@ export const externalCallDuration = ({
disabled, disabled,
expressions, expressions,
legendFormulas, legendFormulas,
aggregateOperators, timeAggregateOperators,
spaceAggregateOperators,
dataSource, dataSource,
}); });
}; };
@ -250,9 +260,13 @@ export const externalCallDurationByAddress = ({
const autocompleteData = [autocompleteDataA, autocompleteDataB]; const autocompleteData = [autocompleteDataA, autocompleteDataB];
const additionalItems = [additionalItemsA, additionalItemsA]; const additionalItems = [additionalItemsA, additionalItemsA];
const legends = [legend, legend]; const legends = [legend, legend];
const aggregateOperators = [ const timeAggregateOperators = [
MetricAggregateOperator.SUM_RATE, MetricAggregateOperator.RATE,
MetricAggregateOperator.SUM_RATE, MetricAggregateOperator.RATE,
];
const spaceAggregateOperators = [
MetricAggregateOperator.SUM,
MetricAggregateOperator.SUM,
]; ];
const dataSource = DataSource.METRICS; const dataSource = DataSource.METRICS;
@ -264,7 +278,8 @@ export const externalCallDurationByAddress = ({
disabled, disabled,
expressions, expressions,
legendFormulas, legendFormulas,
aggregateOperators, timeAggregateOperators,
spaceAggregateOperators,
dataSource, dataSource,
}); });
}; };

View File

@ -9,6 +9,7 @@ import { IBuilderQuery } from 'types/api/queryBuilder/queryBuilderData';
import { import {
MetricAggregateOperator, MetricAggregateOperator,
QueryBuilderData, QueryBuilderData,
Temporality,
} from 'types/common/queryBuilder'; } from 'types/common/queryBuilder';
import { import {
@ -69,7 +70,8 @@ export const getQueryBuilderQuerieswithFormula = ({
disabled, disabled,
expressions, expressions,
legendFormulas, legendFormulas,
aggregateOperators, timeAggregateOperators,
spaceAggregateOperators,
dataSource, dataSource,
}: BuilderQuerieswithFormulaProps): QueryBuilderData => ({ }: BuilderQuerieswithFormulaProps): QueryBuilderData => ({
queryFormulas: expressions.map((expression, index) => ({ queryFormulas: expressions.map((expression, index) => ({
@ -79,7 +81,9 @@ export const getQueryBuilderQuerieswithFormula = ({
})), })),
queryData: autocompleteData.map((_, index) => ({ queryData: autocompleteData.map((_, index) => ({
...initialQueryBuilderFormValuesMap.metrics, ...initialQueryBuilderFormValuesMap.metrics,
aggregateOperator: aggregateOperators[index], timeAggregation: timeAggregateOperators[index],
spaceAggregation: spaceAggregateOperators[index],
temporality: Temporality.Delta,
disabled: disabled[index], disabled: disabled[index],
groupBy, groupBy,
legend: legends[index], legend: legends[index],

View File

@ -250,11 +250,16 @@ export const apDexTracesQueryBuilderQueries = ({
const disabled = Array(3).fill(true); const disabled = Array(3).fill(true);
const expressions = [FORMULA.APDEX_TRACES]; const expressions = [FORMULA.APDEX_TRACES];
const legendFormulas = [GraphTitle.APDEX]; const legendFormulas = [GraphTitle.APDEX];
const aggregateOperators = [ const timeAggregateOperators = [
MetricAggregateOperator.COUNT, MetricAggregateOperator.COUNT,
MetricAggregateOperator.COUNT, MetricAggregateOperator.COUNT,
MetricAggregateOperator.COUNT, MetricAggregateOperator.COUNT,
]; ];
const spaceAggregateOperators = [
MetricAggregateOperator.EMPTY,
MetricAggregateOperator.EMPTY,
MetricAggregateOperator.EMPTY,
];
const dataSource = DataSource.TRACES; const dataSource = DataSource.TRACES;
return getQueryBuilderQuerieswithFormula({ return getQueryBuilderQuerieswithFormula({
@ -264,7 +269,8 @@ export const apDexTracesQueryBuilderQueries = ({
disabled, disabled,
expressions, expressions,
legendFormulas, legendFormulas,
aggregateOperators, timeAggregateOperators,
spaceAggregateOperators,
dataSource, dataSource,
}); });
}; };
@ -433,10 +439,16 @@ export const apDexMetricsQueryBuilderQueries = ({
? [FORMULA.APDEX_DELTA_SPAN_METRICS] ? [FORMULA.APDEX_DELTA_SPAN_METRICS]
: [FORMULA.APDEX_CUMULATIVE_SPAN_METRICS]; : [FORMULA.APDEX_CUMULATIVE_SPAN_METRICS];
const legendFormulas = [GraphTitle.APDEX]; const legendFormulas = [GraphTitle.APDEX];
const aggregateOperators = [ const timeAggregateOperators = [
MetricAggregateOperator.SUM_RATE, MetricAggregateOperator.RATE,
MetricAggregateOperator.SUM_RATE, MetricAggregateOperator.RATE,
MetricAggregateOperator.SUM_RATE, MetricAggregateOperator.RATE,
];
const spaceAggregateOperators = [
MetricAggregateOperator.SUM,
MetricAggregateOperator.SUM,
MetricAggregateOperator.SUM,
]; ];
const dataSource = DataSource.METRICS; const dataSource = DataSource.METRICS;
@ -447,7 +459,8 @@ export const apDexMetricsQueryBuilderQueries = ({
disabled, disabled,
expressions, expressions,
legendFormulas, legendFormulas,
aggregateOperators, timeAggregateOperators,
spaceAggregateOperators,
dataSource, dataSource,
}); });
}; };
@ -593,9 +606,13 @@ export const errorPercentage = ({
const disabled = [true, true]; const disabled = [true, true];
const expressions = [FORMULA.ERROR_PERCENTAGE]; const expressions = [FORMULA.ERROR_PERCENTAGE];
const legendFormulas = [GraphTitle.ERROR_PERCENTAGE]; const legendFormulas = [GraphTitle.ERROR_PERCENTAGE];
const aggregateOperators = [ const timeAggregateOperators = [
MetricAggregateOperator.SUM_RATE, MetricAggregateOperator.RATE,
MetricAggregateOperator.SUM_RATE, MetricAggregateOperator.RATE,
];
const spaceAggregateOperators = [
MetricAggregateOperator.SUM,
MetricAggregateOperator.SUM,
]; ];
const dataSource = DataSource.METRICS; const dataSource = DataSource.METRICS;
@ -606,7 +623,8 @@ export const errorPercentage = ({
disabled, disabled,
expressions, expressions,
legendFormulas, legendFormulas,
aggregateOperators, timeAggregateOperators,
spaceAggregateOperators,
dataSource, dataSource,
}); });
}; };

View File

@ -118,13 +118,21 @@ export const topOperationQueries = ({
KeyOperationTableHeader.ERROR_RATE, KeyOperationTableHeader.ERROR_RATE,
KeyOperationTableHeader.NUM_OF_CALLS, KeyOperationTableHeader.NUM_OF_CALLS,
]; ];
const aggregateOperators = [ const timeAggregateOperators = [
MetricAggregateOperator.HIST_QUANTILE_50, MetricAggregateOperator.EMPTY,
MetricAggregateOperator.HIST_QUANTILE_90, MetricAggregateOperator.EMPTY,
MetricAggregateOperator.HIST_QUANTILE_99, MetricAggregateOperator.EMPTY,
MetricAggregateOperator.SUM_RATE, MetricAggregateOperator.RATE,
MetricAggregateOperator.SUM_RATE, MetricAggregateOperator.RATE,
MetricAggregateOperator.SUM_RATE, MetricAggregateOperator.RATE,
];
const spaceAggregateOperators = [
MetricAggregateOperator.P50,
MetricAggregateOperator.P90,
MetricAggregateOperator.P99,
MetricAggregateOperator.SUM,
MetricAggregateOperator.SUM,
MetricAggregateOperator.SUM,
]; ];
const expressions = ['D*100/E']; const expressions = ['D*100/E'];
const legendFormulas = [GraphTitle.ERROR_PERCENTAGE]; const legendFormulas = [GraphTitle.ERROR_PERCENTAGE];
@ -135,7 +143,8 @@ export const topOperationQueries = ({
additionalItems, additionalItems,
disabled, disabled,
legends, legends,
aggregateOperators, timeAggregateOperators,
spaceAggregateOperators,
expressions, expressions,
legendFormulas, legendFormulas,
dataSource, dataSource,

View File

@ -1,4 +1,5 @@
import { Col } from 'antd'; import { Col } from 'antd';
import { ENTITY_VERSION_V4 } from 'constants/app';
import { PANEL_TYPES } from 'constants/queryBuilder'; import { PANEL_TYPES } from 'constants/queryBuilder';
import Graph from 'container/GridCardLayout/GridCard'; import Graph from 'container/GridCardLayout/GridCard';
import { import {
@ -121,6 +122,7 @@ function DBCall(): JSX.Element {
'database_call_rps', 'database_call_rps',
); );
}} }}
version={ENTITY_VERSION_V4}
/> />
</GraphContainer> </GraphContainer>
</Card> </Card>
@ -156,6 +158,7 @@ function DBCall(): JSX.Element {
'database_call_avg_duration', 'database_call_avg_duration',
); );
}} }}
version={ENTITY_VERSION_V4}
/> />
</GraphContainer> </GraphContainer>
</Card> </Card>

View File

@ -1,4 +1,5 @@
import { Col } from 'antd'; import { Col } from 'antd';
import { ENTITY_VERSION_V4 } from 'constants/app';
import { PANEL_TYPES } from 'constants/queryBuilder'; import { PANEL_TYPES } from 'constants/queryBuilder';
import Graph from 'container/GridCardLayout/GridCard'; import Graph from 'container/GridCardLayout/GridCard';
import { import {
@ -165,6 +166,7 @@ function External(): JSX.Element {
'external_call_error_percentage', 'external_call_error_percentage',
); );
}} }}
version={ENTITY_VERSION_V4}
/> />
</GraphContainer> </GraphContainer>
</Card> </Card>
@ -201,6 +203,7 @@ function External(): JSX.Element {
'external_call_duration', 'external_call_duration',
); );
}} }}
version={ENTITY_VERSION_V4}
/> />
</GraphContainer> </GraphContainer>
</Card> </Card>
@ -238,6 +241,7 @@ function External(): JSX.Element {
'external_call_rps_by_address', 'external_call_rps_by_address',
) )
} }
version={ENTITY_VERSION_V4}
/> />
</GraphContainer> </GraphContainer>
</Card> </Card>
@ -274,6 +278,7 @@ function External(): JSX.Element {
'external_call_duration_by_address', 'external_call_duration_by_address',
); );
}} }}
version={ENTITY_VERSION_V4}
/> />
</GraphContainer> </GraphContainer>
</Card> </Card>

View File

@ -5,6 +5,7 @@ import {
apDexToolTipUrl, apDexToolTipUrl,
apDexToolTipUrlText, apDexToolTipUrlText,
} from 'constants/apDex'; } from 'constants/apDex';
import { ENTITY_VERSION_V4 } from 'constants/app';
import { PANEL_TYPES } from 'constants/queryBuilder'; import { PANEL_TYPES } from 'constants/queryBuilder';
import Graph from 'container/GridCardLayout/GridCard'; import Graph from 'container/GridCardLayout/GridCard';
import DisplayThreshold from 'container/GridCardLayout/WidgetHeader/DisplayThreshold'; import DisplayThreshold from 'container/GridCardLayout/WidgetHeader/DisplayThreshold';
@ -94,6 +95,7 @@ function ApDexMetrics({
onClickHandler={handleGraphClick('ApDex')} onClickHandler={handleGraphClick('ApDex')}
threshold={threshold} threshold={threshold}
isQueryEnabled={isQueryEnabled} isQueryEnabled={isQueryEnabled}
version={ENTITY_VERSION_V4}
/> />
); );
} }

View File

@ -1,5 +1,6 @@
// This component is not been used in the application as we support only metrics for ApDex as of now. // This component is not been used in the application as we support only metrics for ApDex as of now.
// This component is been kept for future reference. // This component is been kept for future reference.
import { ENTITY_VERSION_V4 } from 'constants/app';
import { PANEL_TYPES } from 'constants/queryBuilder'; import { PANEL_TYPES } from 'constants/queryBuilder';
import Graph from 'container/GridCardLayout/GridCard'; import Graph from 'container/GridCardLayout/GridCard';
import { GraphTitle } from 'container/MetricsApplication/constant'; import { GraphTitle } from 'container/MetricsApplication/constant';
@ -54,6 +55,7 @@ function ApDexTraces({
onClickHandler={handleGraphClick('ApDex')} onClickHandler={handleGraphClick('ApDex')}
threshold={thresholdValue} threshold={thresholdValue}
isQueryEnabled={isQueryEnabled} isQueryEnabled={isQueryEnabled}
version={ENTITY_VERSION_V4}
/> />
); );
} }

View File

@ -1,3 +1,4 @@
import { ENTITY_VERSION_V4 } from 'constants/app';
import { FeatureKeys } from 'constants/features'; import { FeatureKeys } from 'constants/features';
import { PANEL_TYPES } from 'constants/queryBuilder'; import { PANEL_TYPES } from 'constants/queryBuilder';
import Graph from 'container/GridCardLayout/GridCard'; import Graph from 'container/GridCardLayout/GridCard';
@ -93,6 +94,7 @@ function ServiceOverview({
onClickHandler={handleGraphClick('Service')} onClickHandler={handleGraphClick('Service')}
isQueryEnabled={isQueryEnabled} isQueryEnabled={isQueryEnabled}
fillSpans={false} fillSpans={false}
version={ENTITY_VERSION_V4}
/> />
</GraphContainer> </GraphContainer>
</Card> </Card>

View File

@ -1,6 +1,7 @@
import { Typography } from 'antd'; import { Typography } from 'antd';
import axios from 'axios'; import axios from 'axios';
import { SOMETHING_WENT_WRONG } from 'constants/api'; import { SOMETHING_WENT_WRONG } from 'constants/api';
import { ENTITY_VERSION_V4 } from 'constants/app';
import Graph from 'container/GridCardLayout/GridCard'; import Graph from 'container/GridCardLayout/GridCard';
import { Card, GraphContainer } from 'container/MetricsApplication/styles'; import { Card, GraphContainer } from 'container/MetricsApplication/styles';
import { OnClickPluginOpts } from 'lib/uPlotLib/plugins/onClickPlugin'; import { OnClickPluginOpts } from 'lib/uPlotLib/plugins/onClickPlugin';
@ -33,6 +34,7 @@ function TopLevelOperation({
onClickHandler={handleGraphClick(opName)} onClickHandler={handleGraphClick(opName)}
onDragSelect={onDragSelect} onDragSelect={onDragSelect}
isQueryEnabled={!topLevelOperationsIsLoading} isQueryEnabled={!topLevelOperationsIsLoading}
version={ENTITY_VERSION_V4}
/> />
</GraphContainer> </GraphContainer>
)} )}

View File

@ -1,4 +1,4 @@
import { DEFAULT_ENTITY_VERSION } from 'constants/app'; import { ENTITY_VERSION_V4 } from 'constants/app';
import { PANEL_TYPES } from 'constants/queryBuilder'; import { PANEL_TYPES } from 'constants/queryBuilder';
import { topOperationMetricsDownloadOptions } from 'container/MetricsApplication/constant'; import { topOperationMetricsDownloadOptions } from 'container/MetricsApplication/constant';
import { getWidgetQueryBuilder } from 'container/MetricsApplication/MetricsApplication.factory'; import { getWidgetQueryBuilder } from 'container/MetricsApplication/MetricsApplication.factory';
@ -68,7 +68,7 @@ function TopOperationMetrics(): JSX.Element {
globalSelectedInterval, globalSelectedInterval,
variables: {}, variables: {},
}, },
DEFAULT_ENTITY_VERSION, ENTITY_VERSION_V4,
{ {
queryKey: [ queryKey: [
`GetMetricsQueryRange-${keyOperationWidget?.timePreferance}-${globalSelectedInterval}-${keyOperationWidget?.id}`, `GetMetricsQueryRange-${keyOperationWidget?.timePreferance}-${globalSelectedInterval}-${keyOperationWidget?.id}`,

View File

@ -39,7 +39,8 @@ export interface BuilderQuerieswithFormulaProps {
expressions: string[]; expressions: string[];
legendFormulas: string[]; legendFormulas: string[];
additionalItems: TagFilterItem[][]; additionalItems: TagFilterItem[][];
aggregateOperators: MetricAggregateOperator[]; timeAggregateOperators: MetricAggregateOperator[];
spaceAggregateOperators: MetricAggregateOperator[];
dataSource: DataSource; dataSource: DataSource;
} }

View File

@ -2,6 +2,7 @@
import './Query.styles.scss'; import './Query.styles.scss';
import { Col, Input, Row } from 'antd'; import { Col, Input, Row } from 'antd';
import { ENTITY_VERSION_V4 } from 'constants/app';
// ** Constants // ** Constants
import { ATTRIBUTE_TYPES, PANEL_TYPES } from 'constants/queryBuilder'; import { ATTRIBUTE_TYPES, PANEL_TYPES } from 'constants/queryBuilder';
import ROUTES from 'constants/routes'; import ROUTES from 'constants/routes';
@ -316,13 +317,15 @@ export const Query = memo(function Query({
const disableOperatorSelector = const disableOperatorSelector =
!query?.aggregateAttribute.key || query?.aggregateAttribute.key === ''; !query?.aggregateAttribute.key || query?.aggregateAttribute.key === '';
const isVersionV4 = version && version === 'v4'; const isVersionV4 = version && version === ENTITY_VERSION_V4;
return ( return (
<Row gutter={[0, 12]}> <Row gutter={[0, 12]}>
<QBEntityOptions <QBEntityOptions
isMetricsDataSource={isMetricsDataSource} isMetricsDataSource={isMetricsDataSource}
showFunctions={(version && version === 'v4') || showFunctions || false} showFunctions={
(version && version === ENTITY_VERSION_V4) || showFunctions || false
}
isCollapsed={isCollapse} isCollapsed={isCollapse}
entityType="query" entityType="query"
entityData={query} entityData={query}
@ -375,7 +378,7 @@ export const Query = memo(function Query({
</Col> </Col>
{version && {version &&
version === 'v4' && version === ENTITY_VERSION_V4 &&
operators && operators &&
Array.isArray(operators) && Array.isArray(operators) &&
operators.length > 0 && ( operators.length > 0 && (

View File

@ -1,4 +1,5 @@
import { Select } from 'antd'; import { Select } from 'antd';
import { ENTITY_VERSION_V4 } from 'constants/app';
// ** Constants // ** Constants
import { HAVING_OPERATORS, initialHavingValues } from 'constants/queryBuilder'; import { HAVING_OPERATORS, initialHavingValues } from 'constants/queryBuilder';
import { HavingFilterTag } from 'container/QueryBuilder/components'; import { HavingFilterTag } from 'container/QueryBuilder/components';
@ -54,7 +55,7 @@ export function HavingFilter({
query && query &&
query.dataSource === DataSource.METRICS && query.dataSource === DataSource.METRICS &&
query.spaceAggregation && query.spaceAggregation &&
entityVersion === 'v4' entityVersion === ENTITY_VERSION_V4
) { ) {
return `${query.spaceAggregation.toUpperCase()}(${aggregatorAttribute})`; return `${query.spaceAggregation.toUpperCase()}(${aggregatorAttribute})`;
} }

View File

@ -1,7 +1,7 @@
import { WarningFilled } from '@ant-design/icons'; import { WarningFilled } from '@ant-design/icons';
import { Flex, Typography } from 'antd'; import { Flex, Typography } from 'antd';
import { ResizeTable } from 'components/ResizeTable'; import { ResizeTable } from 'components/ResizeTable';
import { DEFAULT_ENTITY_VERSION } from 'constants/app'; import { ENTITY_VERSION_V4 } from 'constants/app';
import { MAX_RPS_LIMIT } from 'constants/global'; import { MAX_RPS_LIMIT } from 'constants/global';
import ResourceAttributesFilter from 'container/ResourceAttributesFilter'; import ResourceAttributesFilter from 'container/ResourceAttributesFilter';
import { useGetQueriesRange } from 'hooks/queryBuilder/useGetQueriesRange'; import { useGetQueriesRange } from 'hooks/queryBuilder/useGetQueriesRange';
@ -36,10 +36,7 @@ function ServiceMetricTable({
const { data: licenseData, isFetching } = useLicense(); const { data: licenseData, isFetching } = useLicense();
const isCloudUserVal = isCloudUser(); const isCloudUserVal = isCloudUser();
const queries = useGetQueriesRange( const queries = useGetQueriesRange(queryRangeRequestData, ENTITY_VERSION_V4, {
queryRangeRequestData,
DEFAULT_ENTITY_VERSION,
{
queryKey: [ queryKey: [
`GetMetricsQueryRange-${queryRangeRequestData[0].selectedTime}-${globalSelectedInterval}`, `GetMetricsQueryRange-${queryRangeRequestData[0].selectedTime}-${globalSelectedInterval}`,
maxTime, maxTime,
@ -54,8 +51,7 @@ function ServiceMetricTable({
message: error.message, message: error.message,
}); });
}, },
}, });
);
const isLoading = queries.some((query) => query.isLoading); const isLoading = queries.some((query) => query.isLoading);
const services: ServicesList[] = useMemo( const services: ServicesList[] = useMemo(

View File

@ -166,11 +166,17 @@ export const serviceMetricsQuery = (
operationPrSecondAdditionalItems, operationPrSecondAdditionalItems,
]; ];
const aggregateOperators = [ const timeAggregateOperators = [
MetricAggregateOperator.HIST_QUANTILE_99, MetricAggregateOperator.EMPTY,
MetricAggregateOperator.SUM_RATE, MetricAggregateOperator.RATE,
MetricAggregateOperator.SUM_RATE, MetricAggregateOperator.RATE,
MetricAggregateOperator.SUM_RATE, MetricAggregateOperator.RATE,
];
const spaceAggregateOperators = [
MetricAggregateOperator.P99,
MetricAggregateOperator.SUM,
MetricAggregateOperator.SUM,
MetricAggregateOperator.SUM,
]; ];
const disabled = [false, true, true, false]; const disabled = [false, true, true, false];
@ -201,7 +207,8 @@ export const serviceMetricsQuery = (
additionalItems, additionalItems,
disabled, disabled,
legends, legends,
aggregateOperators, timeAggregateOperators,
spaceAggregateOperators,
expressions, expressions,
legendFormulas, legendFormulas,
groupBy, groupBy,

View File

@ -1,3 +1,4 @@
import { ENTITY_VERSION_V4 } from 'constants/app';
import { LEGEND } from 'constants/global'; import { LEGEND } from 'constants/global';
import { import {
ATTRIBUTE_TYPES, ATTRIBUTE_TYPES,
@ -183,7 +184,10 @@ export const useQueryOperations: UseQueryOperations = ({
having: [], having: [],
}; };
if (newQuery.dataSource === DataSource.METRICS && entityVersion === 'v4') { if (
newQuery.dataSource === DataSource.METRICS &&
entityVersion === ENTITY_VERSION_V4
) {
handleMetricAggregateAtributeTypes(newQuery.aggregateAttribute); handleMetricAggregateAtributeTypes(newQuery.aggregateAttribute);
if (newQuery.aggregateAttribute.type === ATTRIBUTE_TYPES.SUM) { if (newQuery.aggregateAttribute.type === ATTRIBUTE_TYPES.SUM) {
@ -310,7 +314,7 @@ export const useQueryOperations: UseQueryOperations = ({
dataSource === DataSource.METRICS && dataSource === DataSource.METRICS &&
query && query &&
query.aggregateAttribute && query.aggregateAttribute &&
entityVersion === 'v4' entityVersion === ENTITY_VERSION_V4
) { ) {
handleMetricAggregateAtributeTypes(query.aggregateAttribute); handleMetricAggregateAtributeTypes(query.aggregateAttribute);
} else { } else {

View File

@ -11,6 +11,10 @@ export const handlers = [
res(ctx.status(200), ctx.json(queryRangeSuccessResponse)), res(ctx.status(200), ctx.json(queryRangeSuccessResponse)),
), ),
rest.post('http://localhost/api/v4/query_range', (req, res, ctx) =>
res(ctx.status(200), ctx.json(queryRangeSuccessResponse)),
),
rest.post('http://localhost/api/v1/services', (req, res, ctx) => rest.post('http://localhost/api/v1/services', (req, res, ctx) =>
res(ctx.status(200), ctx.json(serviceSuccessResponse)), res(ctx.status(200), ctx.json(serviceSuccessResponse)),
), ),

View File

@ -60,6 +60,7 @@ export type IBuilderQuery = {
aggregateAttribute: BaseAutocompleteData; aggregateAttribute: BaseAutocompleteData;
timeAggregation: string; timeAggregation: string;
spaceAggregation?: string; spaceAggregation?: string;
temporality?: string;
functions: QueryFunctionProps[]; functions: QueryFunctionProps[];
filters: TagFilter; filters: TagFilter;
groupBy: BaseAutocompleteData[]; groupBy: BaseAutocompleteData[];

View File

@ -61,7 +61,14 @@ export enum BoolOperators {
COUNT_DISTINCT = 'count_distinct', COUNT_DISTINCT = 'count_distinct',
} }
export enum Temporality {
Unspecified = 'Unspecified',
Delta = 'Delta',
Cumulative = 'Cumulative',
}
export enum MetricAggregateOperator { export enum MetricAggregateOperator {
EMPTY = '', // used as time aggregator for histograms
NOOP = 'noop', NOOP = 'noop',
COUNT = 'count', COUNT = 'count',
COUNT_DISTINCT = 'count_distinct', COUNT_DISTINCT = 'count_distinct',

View File

@ -120,6 +120,13 @@ func joinAndCalculate(results []*v3.Result, uniqueLabelSet map[string]string, ex
for queryName, series := range seriesMap { for queryName, series := range seriesMap {
values[queryName] = series[timestamp] values[queryName] = series[timestamp]
} }
// If the value is not present in the values map, set it to 0
for _, v := range expression.Vars() {
if _, ok := values[v]; !ok {
values[v] = 0
}
}
newValue, err := expression.Evaluate(values) newValue, err := expression.Evaluate(values)
if err != nil { if err != nil {
return nil, err return nil, err

View File

@ -492,23 +492,23 @@ func TestParseQueryRangeParamsCompositeQuery(t *testing.T) {
expectErr: true, expectErr: true,
errMsg: "data source is invalid", errMsg: "data source is invalid",
}, },
{ // {
desc: "invalid aggregate operator for builder query", // desc: "invalid aggregate operator for builder query",
compositeQuery: v3.CompositeQuery{ // compositeQuery: v3.CompositeQuery{
PanelType: v3.PanelTypeGraph, // PanelType: v3.PanelTypeGraph,
QueryType: v3.QueryTypeBuilder, // QueryType: v3.QueryTypeBuilder,
BuilderQueries: map[string]*v3.BuilderQuery{ // BuilderQueries: map[string]*v3.BuilderQuery{
"A": { // "A": {
QueryName: "A", // QueryName: "A",
DataSource: "metrics", // DataSource: "metrics",
AggregateOperator: "invalid", // AggregateOperator: "invalid",
Expression: "A", // Expression: "A",
}, // },
}, // },
}, // },
expectErr: true, // expectErr: true,
errMsg: "aggregate operator is invalid", // errMsg: "aggregate operator is invalid",
}, // },
{ {
desc: "invalid aggregate attribute for builder query", desc: "invalid aggregate attribute for builder query",
compositeQuery: v3.CompositeQuery{ compositeQuery: v3.CompositeQuery{

View File

@ -654,22 +654,22 @@ func (b *BuilderQuery) Validate() error {
} }
if b.DataSource == DataSourceMetrics { if b.DataSource == DataSourceMetrics {
// if AggregateOperator is specified, then the request is using v3 payload // if AggregateOperator is specified, then the request is using v3 payload
if b.AggregateOperator != "" && b.SpaceAggregation == SpaceAggregationUnspecified { // if b.AggregateOperator != "" && b.SpaceAggregation == SpaceAggregationUnspecified {
if err := b.AggregateOperator.Validate(); err != nil { // if err := b.AggregateOperator.Validate(); err != nil {
return fmt.Errorf("aggregate operator is invalid: %w", err) // return fmt.Errorf("aggregate operator is invalid: %w", err)
} // }
} else { // } else {
// the time aggregation is not needed for percentile operators // // the time aggregation is not needed for percentile operators
if !IsPercentileOperator(b.SpaceAggregation) { // if !IsPercentileOperator(b.SpaceAggregation) {
if err := b.TimeAggregation.Validate(); err != nil { // if err := b.TimeAggregation.Validate(); err != nil {
return fmt.Errorf("time aggregation is invalid: %w", err) // return fmt.Errorf("time aggregation is invalid: %w", err)
} // }
} // }
if err := b.SpaceAggregation.Validate(); err != nil { // if err := b.SpaceAggregation.Validate(); err != nil {
return fmt.Errorf("space aggregation is invalid: %w", err) // return fmt.Errorf("space aggregation is invalid: %w", err)
} // }
} // }
} else { } else {
if err := b.AggregateOperator.Validate(); err != nil { if err := b.AggregateOperator.Validate(); err != nil {
return fmt.Errorf("aggregate operator is invalid: %w", err) return fmt.Errorf("aggregate operator is invalid: %w", err)