mirror of
https://git.mirrors.martin98.com/https://github.com/SigNoz/signoz
synced 2025-09-20 07:23:14 +08:00
Key Operation to Metrics using USE_SPAN_METRIC feature flag (#3188)
* refactor: generic querybuilderWithFormula * refactor: added generic datasource * refactor: dynamic disabled in getQueryBuilderQueriesWithFormula * refactor: generic legend for building query with formulas * feat: added new TopOperationMetrics component for key operation * refactor: added feature flag for key operation * refactor: shifted types and fixed typos * refactor: separated types and renamed file * refactor: one on one mapping * refactor: added clickable link for navigating to traces * chore: separated types * chore: removed unnecessary comments * refactor: one on one mapping for DBCallQueries * refactor: seperated types and one on one mapping for externalQueries * refactor: separate type from metricsPagesQueriesFactory * refactor: separated types and one on one mapping for overviewQueries * refactor: remove the type inforcement from TopOperationQueries.ts * refactor: one on one mapping in TopOperationQueries.ts * refactor: one on one mapping and remove the unwanted code * refactor: shifted logic of navigating to traces to utils * refactor: separated renderColumnCell from the TopOperationMetric component * refactor: generic tableRenderer * refactor: made getTableColumnRenderer more generic * chore: title is updated --------- Co-authored-by: Palash Gupta <palashgdev@gmail.com>
This commit is contained in:
parent
5c83d133a2
commit
bc4a4edc7f
@ -1,17 +1,19 @@
|
||||
import { PANEL_TYPES } from 'constants/queryBuilder';
|
||||
import { Widgets } from 'types/api/dashboard/getAll';
|
||||
import { v4 } from 'uuid';
|
||||
|
||||
export const getWidgetQueryBuilder = (
|
||||
query: Widgets['query'],
|
||||
import { GetWidgetQueryBuilderProps } from './types';
|
||||
|
||||
export const getWidgetQueryBuilder = ({
|
||||
query,
|
||||
title = '',
|
||||
): Widgets => ({
|
||||
panelTypes,
|
||||
}: GetWidgetQueryBuilderProps): Widgets => ({
|
||||
description: '',
|
||||
id: v4(),
|
||||
isStacked: false,
|
||||
nullZeroValues: '',
|
||||
opacity: '0',
|
||||
panelTypes: PANEL_TYPES.TIME_SERIES,
|
||||
panelTypes,
|
||||
query,
|
||||
timePreferance: 'GLOBAL_TIME',
|
||||
title,
|
||||
|
@ -1,7 +1,11 @@
|
||||
import { OPERATORS } from 'constants/queryBuilder';
|
||||
import { BaseAutocompleteData } from 'types/api/queryBuilder/queryAutocompleteResponse';
|
||||
import { TagFilterItem } from 'types/api/queryBuilder/queryBuilderData';
|
||||
import { DataSource, QueryBuilderData } from 'types/common/queryBuilder';
|
||||
import {
|
||||
DataSource,
|
||||
MetricAggregateOperator,
|
||||
QueryBuilderData,
|
||||
} from 'types/common/queryBuilder';
|
||||
|
||||
import { DataType, FORMULA, MetricsType, WidgetKeys } from '../constant';
|
||||
import { IServiceName } from '../Tabs/types';
|
||||
@ -44,13 +48,14 @@ export const databaseCallsRPS = ({
|
||||
];
|
||||
|
||||
const legends = [legend];
|
||||
const dataSource = DataSource.METRICS;
|
||||
|
||||
return getQueryBuilderQueries({
|
||||
autocompleteData,
|
||||
groupBy,
|
||||
legends,
|
||||
filterItems,
|
||||
dataSource: DataSource.METRICS,
|
||||
dataSource,
|
||||
});
|
||||
};
|
||||
|
||||
@ -85,17 +90,36 @@ export const databaseCallsAvgDuration = ({
|
||||
},
|
||||
...tagFilterItems,
|
||||
];
|
||||
const additionalItemsB = additionalItemsA;
|
||||
|
||||
return getQueryBuilderQuerieswithFormula({
|
||||
const autocompleteData: BaseAutocompleteData[] = [
|
||||
autocompleteDataA,
|
||||
autocompleteDataB,
|
||||
];
|
||||
|
||||
const additionalItems: TagFilterItem[][] = [
|
||||
additionalItemsA,
|
||||
additionalItemsB,
|
||||
legend: '',
|
||||
disabled: true,
|
||||
expression: FORMULA.DATABASE_CALLS_AVG_DURATION,
|
||||
legendFormula: 'Average Duration',
|
||||
additionalItemsA,
|
||||
];
|
||||
|
||||
const legends = ['', ''];
|
||||
const disabled = [true, true];
|
||||
const legendFormula = 'Average Duration';
|
||||
const expression = FORMULA.DATABASE_CALLS_AVG_DURATION;
|
||||
const aggregateOperators = [
|
||||
MetricAggregateOperator.SUM,
|
||||
MetricAggregateOperator.SUM,
|
||||
];
|
||||
const dataSource = DataSource.METRICS;
|
||||
|
||||
return getQueryBuilderQuerieswithFormula({
|
||||
autocompleteData,
|
||||
additionalItems,
|
||||
legends,
|
||||
disabled,
|
||||
expression,
|
||||
legendFormula,
|
||||
aggregateOperators,
|
||||
dataSource,
|
||||
});
|
||||
};
|
||||
|
||||
|
@ -1,10 +1,17 @@
|
||||
import { OPERATORS } from 'constants/queryBuilder';
|
||||
import { BaseAutocompleteData } from 'types/api/queryBuilder/queryAutocompleteResponse';
|
||||
import { TagFilterItem } from 'types/api/queryBuilder/queryBuilderData';
|
||||
import { DataSource, QueryBuilderData } from 'types/common/queryBuilder';
|
||||
import {
|
||||
DataSource,
|
||||
MetricAggregateOperator,
|
||||
QueryBuilderData,
|
||||
} from 'types/common/queryBuilder';
|
||||
|
||||
import { DataType, FORMULA, MetricsType, WidgetKeys } from '../constant';
|
||||
import { IServiceName } from '../Tabs/types';
|
||||
import {
|
||||
ExternalCallDurationByAddressProps,
|
||||
ExternalCallProps,
|
||||
} from '../Tabs/types';
|
||||
import {
|
||||
getQueryBuilderQueries,
|
||||
getQueryBuilderQuerieswithFormula,
|
||||
@ -36,6 +43,7 @@ export const externalCallErrorPercent = ({
|
||||
isColumn: true,
|
||||
type: null,
|
||||
};
|
||||
|
||||
const additionalItemsA: TagFilterItem[] = [
|
||||
{
|
||||
id: '',
|
||||
@ -71,23 +79,38 @@ export const externalCallErrorPercent = ({
|
||||
type: MetricsType.Resource,
|
||||
},
|
||||
op: OPERATORS.IN,
|
||||
value: [`${servicename}`],
|
||||
value: [servicename],
|
||||
},
|
||||
...tagFilterItems,
|
||||
];
|
||||
|
||||
const legendFormula = legend;
|
||||
const expression = FORMULA.ERROR_PERCENTAGE;
|
||||
const disabled = true;
|
||||
return getQueryBuilderQuerieswithFormula({
|
||||
const autocompleteData: BaseAutocompleteData[] = [
|
||||
autocompleteDataA,
|
||||
autocompleteDataB,
|
||||
];
|
||||
|
||||
const additionalItems: TagFilterItem[][] = [
|
||||
additionalItemsA,
|
||||
additionalItemsB,
|
||||
legend,
|
||||
];
|
||||
|
||||
const legends = Array(2).fill(legend);
|
||||
const aggregateOperators = Array(2).fill(MetricAggregateOperator.SUM);
|
||||
const disabled = Array(2).fill(true);
|
||||
const dataSource = DataSource.METRICS;
|
||||
|
||||
return getQueryBuilderQuerieswithFormula({
|
||||
autocompleteData,
|
||||
additionalItems,
|
||||
legends,
|
||||
groupBy,
|
||||
disabled,
|
||||
expression,
|
||||
legendFormula,
|
||||
aggregateOperators,
|
||||
dataSource,
|
||||
});
|
||||
};
|
||||
|
||||
@ -107,10 +130,11 @@ export const externalCallDuration = ({
|
||||
key: WidgetKeys.SignozExternalCallLatencyCount,
|
||||
type: null,
|
||||
};
|
||||
|
||||
const expression = FORMULA.DATABASE_CALLS_AVG_DURATION;
|
||||
const legendFormula = 'Average Duration';
|
||||
const legend = '';
|
||||
const disabled = true;
|
||||
const disabled = Array(2).fill(true);
|
||||
const additionalItemsA: TagFilterItem[] = [
|
||||
{
|
||||
id: '',
|
||||
@ -125,17 +149,29 @@ export const externalCallDuration = ({
|
||||
},
|
||||
...tagFilterItems,
|
||||
];
|
||||
const additionalItemsB = additionalItemsA;
|
||||
|
||||
return getQueryBuilderQuerieswithFormula({
|
||||
const autocompleteData: BaseAutocompleteData[] = [
|
||||
autocompleteDataA,
|
||||
autocompleteDataB,
|
||||
];
|
||||
|
||||
const additionalItems: TagFilterItem[][] = [
|
||||
additionalItemsA,
|
||||
additionalItemsB,
|
||||
legend,
|
||||
additionalItemsA,
|
||||
];
|
||||
|
||||
const legends = Array(2).fill(legend);
|
||||
const aggregateOperators = Array(2).fill(MetricAggregateOperator.SUM);
|
||||
|
||||
return getQueryBuilderQuerieswithFormula({
|
||||
autocompleteData,
|
||||
additionalItems,
|
||||
legends,
|
||||
disabled,
|
||||
expression,
|
||||
legendFormula,
|
||||
aggregateOperators,
|
||||
dataSource: DataSource.METRICS,
|
||||
});
|
||||
};
|
||||
|
||||
@ -169,13 +205,15 @@ export const externalCallRpsByAddress = ({
|
||||
],
|
||||
];
|
||||
|
||||
const legends: string[] = [legend];
|
||||
const legends = [legend];
|
||||
const dataSource = DataSource.METRICS;
|
||||
|
||||
return getQueryBuilderQueries({
|
||||
autocompleteData,
|
||||
groupBy,
|
||||
legends,
|
||||
filterItems,
|
||||
dataSource: DataSource.METRICS,
|
||||
dataSource,
|
||||
});
|
||||
};
|
||||
|
||||
@ -198,7 +236,7 @@ export const externalCallDurationByAddress = ({
|
||||
};
|
||||
const expression = FORMULA.DATABASE_CALLS_AVG_DURATION;
|
||||
const legendFormula = legend;
|
||||
const disabled = true;
|
||||
const disabled = [true, true];
|
||||
const additionalItemsA: TagFilterItem[] = [
|
||||
{
|
||||
id: '',
|
||||
@ -213,26 +251,30 @@ export const externalCallDurationByAddress = ({
|
||||
},
|
||||
...tagFilterItems,
|
||||
];
|
||||
const additionalItemsB = additionalItemsA;
|
||||
|
||||
return getQueryBuilderQuerieswithFormula({
|
||||
const autocompleteData: BaseAutocompleteData[] = [
|
||||
autocompleteDataA,
|
||||
autocompleteDataB,
|
||||
];
|
||||
|
||||
const additionalItems: TagFilterItem[][] = [
|
||||
additionalItemsA,
|
||||
additionalItemsB,
|
||||
legend,
|
||||
additionalItemsA,
|
||||
];
|
||||
|
||||
const legends = Array(2).fill(legend);
|
||||
const aggregateOperators = Array(2).fill(MetricAggregateOperator.SUM_RATE);
|
||||
const dataSource = DataSource.METRICS;
|
||||
|
||||
return getQueryBuilderQuerieswithFormula({
|
||||
autocompleteData,
|
||||
additionalItems,
|
||||
legends,
|
||||
groupBy,
|
||||
disabled,
|
||||
expression,
|
||||
legendFormula,
|
||||
aggregateOperators,
|
||||
dataSource,
|
||||
});
|
||||
};
|
||||
|
||||
interface ExternalCallDurationByAddressProps extends ExternalCallProps {
|
||||
legend: string;
|
||||
}
|
||||
|
||||
export interface ExternalCallProps {
|
||||
servicename: IServiceName['servicename'];
|
||||
tagFilterItems: TagFilterItem[];
|
||||
}
|
||||
|
@ -1,20 +1,21 @@
|
||||
import {
|
||||
alphabet,
|
||||
initialFormulaBuilderFormValues,
|
||||
initialQueryBuilderFormValuesMap,
|
||||
} from 'constants/queryBuilder';
|
||||
import getStep from 'lib/getStep';
|
||||
import store from 'store';
|
||||
import { BaseAutocompleteData } from 'types/api/queryBuilder/queryAutocompleteResponse';
|
||||
import { IBuilderQuery } from 'types/api/queryBuilder/queryBuilderData';
|
||||
import {
|
||||
IBuilderQuery,
|
||||
TagFilterItem,
|
||||
} from 'types/api/queryBuilder/queryBuilderData';
|
||||
import {
|
||||
DataSource,
|
||||
MetricAggregateOperator,
|
||||
QueryBuilderData,
|
||||
} from 'types/common/queryBuilder';
|
||||
|
||||
import {
|
||||
BuilderQueriesProps,
|
||||
BuilderQuerieswithFormulaProps,
|
||||
} from '../Tabs/types';
|
||||
|
||||
export const getQueryBuilderQueries = ({
|
||||
autocompleteData,
|
||||
groupBy = [],
|
||||
@ -61,15 +62,15 @@ export const getQueryBuilderQueries = ({
|
||||
});
|
||||
|
||||
export const getQueryBuilderQuerieswithFormula = ({
|
||||
autocompleteDataA,
|
||||
autocompleteDataB,
|
||||
additionalItemsA,
|
||||
additionalItemsB,
|
||||
legend,
|
||||
autocompleteData,
|
||||
additionalItems,
|
||||
legends,
|
||||
groupBy = [],
|
||||
disabled,
|
||||
expression,
|
||||
legendFormula,
|
||||
aggregateOperators,
|
||||
dataSource,
|
||||
}: BuilderQuerieswithFormulaProps): QueryBuilderData => ({
|
||||
queryFormulas: [
|
||||
{
|
||||
@ -78,66 +79,25 @@ export const getQueryBuilderQuerieswithFormula = ({
|
||||
legend: legendFormula,
|
||||
},
|
||||
],
|
||||
queryData: [
|
||||
{
|
||||
...initialQueryBuilderFormValuesMap.metrics,
|
||||
aggregateOperator: MetricAggregateOperator.SUM_RATE,
|
||||
disabled,
|
||||
groupBy,
|
||||
legend,
|
||||
aggregateAttribute: autocompleteDataA,
|
||||
reduceTo: 'sum',
|
||||
filters: {
|
||||
items: additionalItemsA,
|
||||
op: 'AND',
|
||||
},
|
||||
stepInterval: getStep({
|
||||
end: store.getState().globalTime.maxTime,
|
||||
inputFormat: 'ns',
|
||||
start: store.getState().globalTime.minTime,
|
||||
}),
|
||||
queryData: autocompleteData.map((_, index) => ({
|
||||
...initialQueryBuilderFormValuesMap.metrics,
|
||||
aggregateOperator: aggregateOperators[index],
|
||||
disabled: disabled[index],
|
||||
groupBy,
|
||||
legend: legends[index],
|
||||
aggregateAttribute: autocompleteData[index],
|
||||
queryName: alphabet[index],
|
||||
expression: alphabet[index],
|
||||
reduceTo: 'sum',
|
||||
filters: {
|
||||
items: additionalItems[index],
|
||||
op: 'AND',
|
||||
},
|
||||
{
|
||||
...initialQueryBuilderFormValuesMap.metrics,
|
||||
aggregateOperator: MetricAggregateOperator.SUM_RATE,
|
||||
disabled,
|
||||
groupBy,
|
||||
legend,
|
||||
aggregateAttribute: autocompleteDataB,
|
||||
queryName: 'B',
|
||||
expression: 'B',
|
||||
reduceTo: 'sum',
|
||||
filters: {
|
||||
items: additionalItemsB,
|
||||
op: 'AND',
|
||||
},
|
||||
stepInterval: getStep({
|
||||
end: store.getState().globalTime.maxTime,
|
||||
inputFormat: 'ns',
|
||||
start: store.getState().globalTime.minTime,
|
||||
}),
|
||||
},
|
||||
],
|
||||
stepInterval: getStep({
|
||||
end: store.getState().globalTime.maxTime,
|
||||
inputFormat: 'ns',
|
||||
start: store.getState().globalTime.minTime,
|
||||
}),
|
||||
dataSource,
|
||||
})),
|
||||
});
|
||||
|
||||
interface BuilderQueriesProps {
|
||||
autocompleteData: BaseAutocompleteData[];
|
||||
groupBy?: BaseAutocompleteData[];
|
||||
legends: string[];
|
||||
filterItems: TagFilterItem[][];
|
||||
aggregateOperator?: string[];
|
||||
dataSource: DataSource;
|
||||
queryNameAndExpression?: string[];
|
||||
}
|
||||
|
||||
interface BuilderQuerieswithFormulaProps {
|
||||
autocompleteDataA: BaseAutocompleteData;
|
||||
autocompleteDataB: BaseAutocompleteData;
|
||||
legend: string;
|
||||
disabled: boolean;
|
||||
groupBy?: BaseAutocompleteData[];
|
||||
expression: string;
|
||||
legendFormula: string;
|
||||
additionalItemsA: TagFilterItem[];
|
||||
additionalItemsB: TagFilterItem[];
|
||||
}
|
||||
|
@ -1,7 +1,11 @@
|
||||
import { OPERATORS } from 'constants/queryBuilder';
|
||||
import { BaseAutocompleteData } from 'types/api/queryBuilder/queryAutocompleteResponse';
|
||||
import { TagFilterItem } from 'types/api/queryBuilder/queryBuilderData';
|
||||
import { DataSource, QueryBuilderData } from 'types/common/queryBuilder';
|
||||
import {
|
||||
DataSource,
|
||||
MetricAggregateOperator,
|
||||
QueryBuilderData,
|
||||
} from 'types/common/queryBuilder';
|
||||
|
||||
import {
|
||||
DataType,
|
||||
@ -14,7 +18,7 @@ import {
|
||||
QUERYNAME_AND_EXPRESSION,
|
||||
WidgetKeys,
|
||||
} from '../constant';
|
||||
import { IServiceName } from '../Tabs/types';
|
||||
import { LatencyProps, OperationPerSecProps } from '../Tabs/types';
|
||||
import {
|
||||
getQueryBuilderQueries,
|
||||
getQueryBuilderQuerieswithFormula,
|
||||
@ -35,9 +39,7 @@ export const latency = ({
|
||||
type: isSpanMetricEnable ? null : MetricsType.Tag,
|
||||
};
|
||||
|
||||
const autocompleteData: BaseAutocompleteData[] = Array(3).fill(
|
||||
newAutoCompleteData,
|
||||
);
|
||||
const autocompleteData = Array(3).fill(newAutoCompleteData);
|
||||
|
||||
const filterItem: TagFilterItem[] = [
|
||||
{
|
||||
@ -65,17 +67,21 @@ export const latency = ({
|
||||
...tagFilterItems,
|
||||
];
|
||||
|
||||
const filterItems: TagFilterItem[][] = Array(3).fill([...filterItem]);
|
||||
const filterItems = Array(3).fill([...filterItem]);
|
||||
const legends = LATENCY_AGGREGATEOPERATOR;
|
||||
const aggregateOperator = isSpanMetricEnable
|
||||
? LATENCY_AGGREGATEOPERATOR_SPAN_METRICS
|
||||
: LATENCY_AGGREGATEOPERATOR;
|
||||
const dataSource = isSpanMetricEnable ? DataSource.METRICS : DataSource.TRACES;
|
||||
const queryNameAndExpression = QUERYNAME_AND_EXPRESSION;
|
||||
|
||||
return getQueryBuilderQueries({
|
||||
autocompleteData,
|
||||
legends: LATENCY_AGGREGATEOPERATOR,
|
||||
legends,
|
||||
filterItems,
|
||||
aggregateOperator: isSpanMetricEnable
|
||||
? LATENCY_AGGREGATEOPERATOR_SPAN_METRICS
|
||||
: LATENCY_AGGREGATEOPERATOR,
|
||||
dataSource: isSpanMetricEnable ? DataSource.METRICS : DataSource.TRACES,
|
||||
queryNameAndExpression: QUERYNAME_AND_EXPRESSION,
|
||||
aggregateOperator,
|
||||
dataSource,
|
||||
queryNameAndExpression,
|
||||
});
|
||||
};
|
||||
|
||||
@ -121,11 +127,14 @@ export const operationPerSec = ({
|
||||
],
|
||||
];
|
||||
|
||||
const legends = OPERATION_LEGENDS;
|
||||
const dataSource = DataSource.METRICS;
|
||||
|
||||
return getQueryBuilderQueries({
|
||||
autocompleteData,
|
||||
legends: OPERATION_LEGENDS,
|
||||
legends,
|
||||
filterItems,
|
||||
dataSource: DataSource.METRICS,
|
||||
dataSource,
|
||||
});
|
||||
};
|
||||
|
||||
@ -146,6 +155,9 @@ export const errorPercentage = ({
|
||||
isColumn: true,
|
||||
type: null,
|
||||
};
|
||||
|
||||
const autocompleteData = [autocompleteDataA, autocompleteDataB];
|
||||
|
||||
const additionalItemsA: TagFilterItem[] = [
|
||||
{
|
||||
id: '',
|
||||
@ -209,27 +221,25 @@ export const errorPercentage = ({
|
||||
...tagFilterItems,
|
||||
];
|
||||
|
||||
const additionalItems = [additionalItemsA, additionalItemsB];
|
||||
const legends = [GraphTitle.ERROR_PERCENTAGE];
|
||||
const disabled = [true, true];
|
||||
const expression = FORMULA.ERROR_PERCENTAGE;
|
||||
const legendFormula = GraphTitle.ERROR_PERCENTAGE;
|
||||
const aggregateOperators = [
|
||||
MetricAggregateOperator.SUM_RATE,
|
||||
MetricAggregateOperator.SUM_RATE,
|
||||
];
|
||||
const dataSource = DataSource.METRICS;
|
||||
|
||||
return getQueryBuilderQuerieswithFormula({
|
||||
autocompleteDataA,
|
||||
autocompleteDataB,
|
||||
additionalItemsA,
|
||||
additionalItemsB,
|
||||
legend: GraphTitle.ERROR_PERCENTAGE,
|
||||
disabled: true,
|
||||
expression: FORMULA.ERROR_PERCENTAGE,
|
||||
legendFormula: GraphTitle.ERROR_PERCENTAGE,
|
||||
autocompleteData,
|
||||
additionalItems,
|
||||
legends,
|
||||
disabled,
|
||||
expression,
|
||||
legendFormula,
|
||||
aggregateOperators,
|
||||
dataSource,
|
||||
});
|
||||
};
|
||||
|
||||
export interface OperationPerSecProps {
|
||||
servicename: IServiceName['servicename'];
|
||||
tagFilterItems: TagFilterItem[];
|
||||
topLevelOperations: string[];
|
||||
}
|
||||
|
||||
export interface LatencyProps {
|
||||
servicename: IServiceName['servicename'];
|
||||
tagFilterItems: TagFilterItem[];
|
||||
isSpanMetricEnable?: boolean;
|
||||
topLevelOperationsRoute: string[];
|
||||
}
|
||||
|
@ -0,0 +1,142 @@
|
||||
import { OPERATORS } from 'constants/queryBuilder';
|
||||
import { BaseAutocompleteData } from 'types/api/queryBuilder/queryAutocompleteResponse';
|
||||
import { TagFilterItem } from 'types/api/queryBuilder/queryBuilderData';
|
||||
import {
|
||||
DataSource,
|
||||
MetricAggregateOperator,
|
||||
QueryBuilderData,
|
||||
} from 'types/common/queryBuilder';
|
||||
|
||||
import {
|
||||
DataType,
|
||||
GraphTitle,
|
||||
KeyOperationTableHeader,
|
||||
MetricsType,
|
||||
WidgetKeys,
|
||||
} from '../constant';
|
||||
import { TopOperationQueryFactoryProps } from '../Tabs/types';
|
||||
import { getQueryBuilderQuerieswithFormula } from './MetricsPageQueriesFactory';
|
||||
|
||||
export const topOperationQueries = ({
|
||||
servicename,
|
||||
}: TopOperationQueryFactoryProps): QueryBuilderData => {
|
||||
const latencyAutoCompleteData: BaseAutocompleteData = {
|
||||
key: WidgetKeys.Signoz_latency_bucket,
|
||||
dataType: DataType.FLOAT64,
|
||||
isColumn: true,
|
||||
type: null,
|
||||
};
|
||||
|
||||
const errorRateAutoCompleteData: BaseAutocompleteData = {
|
||||
key: WidgetKeys.SignozCallsTotal,
|
||||
dataType: DataType.FLOAT64,
|
||||
isColumn: true,
|
||||
type: null,
|
||||
};
|
||||
|
||||
const numOfCallAutoCompleteData: BaseAutocompleteData = {
|
||||
key: WidgetKeys.SignozLatencyCount,
|
||||
dataType: DataType.FLOAT64,
|
||||
isColumn: true,
|
||||
type: null,
|
||||
};
|
||||
|
||||
const latencyAndNumberOfCallAdditionalItems: TagFilterItem[] = [
|
||||
{
|
||||
id: '',
|
||||
key: {
|
||||
key: WidgetKeys.Service_name,
|
||||
dataType: DataType.STRING,
|
||||
isColumn: false,
|
||||
type: MetricsType.Resource,
|
||||
},
|
||||
value: [servicename],
|
||||
op: OPERATORS.IN,
|
||||
},
|
||||
];
|
||||
|
||||
const errorRateAdditionalItemsA: TagFilterItem[] = [
|
||||
{
|
||||
id: '',
|
||||
key: {
|
||||
dataType: DataType.STRING,
|
||||
isColumn: false,
|
||||
key: WidgetKeys.Service_name,
|
||||
type: MetricsType.Resource,
|
||||
},
|
||||
op: OPERATORS.IN,
|
||||
value: [servicename],
|
||||
},
|
||||
{
|
||||
id: '',
|
||||
key: {
|
||||
dataType: DataType.INT64,
|
||||
isColumn: false,
|
||||
key: WidgetKeys.StatusCode,
|
||||
type: MetricsType.Tag,
|
||||
},
|
||||
op: OPERATORS.IN,
|
||||
value: ['STATUS_CODE_ERROR'],
|
||||
},
|
||||
];
|
||||
|
||||
const errorRateAdditionalItemsB = latencyAndNumberOfCallAdditionalItems;
|
||||
|
||||
const groupBy: BaseAutocompleteData[] = [
|
||||
{
|
||||
dataType: DataType.STRING,
|
||||
isColumn: false,
|
||||
key: WidgetKeys.Operation,
|
||||
type: MetricsType.Tag,
|
||||
},
|
||||
];
|
||||
|
||||
const autocompleteData = [
|
||||
latencyAutoCompleteData,
|
||||
latencyAutoCompleteData,
|
||||
latencyAutoCompleteData,
|
||||
errorRateAutoCompleteData,
|
||||
errorRateAutoCompleteData,
|
||||
numOfCallAutoCompleteData,
|
||||
];
|
||||
const additionalItems = [
|
||||
latencyAndNumberOfCallAdditionalItems,
|
||||
latencyAndNumberOfCallAdditionalItems,
|
||||
latencyAndNumberOfCallAdditionalItems,
|
||||
errorRateAdditionalItemsA,
|
||||
errorRateAdditionalItemsB,
|
||||
latencyAndNumberOfCallAdditionalItems,
|
||||
];
|
||||
const disabled = [false, false, false, true, true, false];
|
||||
const legends = [
|
||||
KeyOperationTableHeader.P50,
|
||||
KeyOperationTableHeader.P90,
|
||||
KeyOperationTableHeader.P99,
|
||||
KeyOperationTableHeader.ERROR_RATE,
|
||||
KeyOperationTableHeader.ERROR_RATE,
|
||||
KeyOperationTableHeader.NUM_OF_CALLS,
|
||||
];
|
||||
const aggregateOperators = [
|
||||
MetricAggregateOperator.HIST_QUANTILE_50,
|
||||
MetricAggregateOperator.HIST_QUANTILE_90,
|
||||
MetricAggregateOperator.HIST_QUANTILE_99,
|
||||
MetricAggregateOperator.SUM_RATE,
|
||||
MetricAggregateOperator.SUM_RATE,
|
||||
MetricAggregateOperator.SUM_RATE,
|
||||
];
|
||||
const expression = 'D*100/E';
|
||||
const legendFormula = GraphTitle.ERROR_PERCENTAGE;
|
||||
const dataSource = DataSource.METRICS;
|
||||
|
||||
return getQueryBuilderQuerieswithFormula({
|
||||
autocompleteData,
|
||||
additionalItems,
|
||||
disabled,
|
||||
legends,
|
||||
aggregateOperators,
|
||||
expression,
|
||||
legendFormula,
|
||||
dataSource,
|
||||
groupBy,
|
||||
});
|
||||
};
|
@ -1,4 +1,5 @@
|
||||
import { Col } from 'antd';
|
||||
import { PANEL_TYPES } from 'constants/queryBuilder';
|
||||
import Graph from 'container/GridGraphLayout/Graph/';
|
||||
import {
|
||||
databaseCallsAvgDuration,
|
||||
@ -50,8 +51,8 @@ function DBCall(): JSX.Element {
|
||||
|
||||
const databaseCallsRPSWidget = useMemo(
|
||||
() =>
|
||||
getWidgetQueryBuilder(
|
||||
{
|
||||
getWidgetQueryBuilder({
|
||||
query: {
|
||||
queryType: EQueryType.QUERY_BUILDER,
|
||||
promql: [],
|
||||
builder: databaseCallsRPS({
|
||||
@ -62,14 +63,15 @@ function DBCall(): JSX.Element {
|
||||
clickhouse_sql: [],
|
||||
id: uuid(),
|
||||
},
|
||||
GraphTitle.DATABASE_CALLS_RPS,
|
||||
),
|
||||
title: GraphTitle.DATABASE_CALLS_RPS,
|
||||
panelTypes: PANEL_TYPES.TIME_SERIES,
|
||||
}),
|
||||
[servicename, tagFilterItems],
|
||||
);
|
||||
const databaseCallsAverageDurationWidget = useMemo(
|
||||
() =>
|
||||
getWidgetQueryBuilder(
|
||||
{
|
||||
getWidgetQueryBuilder({
|
||||
query: {
|
||||
queryType: EQueryType.QUERY_BUILDER,
|
||||
promql: [],
|
||||
builder: databaseCallsAvgDuration({
|
||||
@ -79,8 +81,9 @@ function DBCall(): JSX.Element {
|
||||
clickhouse_sql: [],
|
||||
id: uuid(),
|
||||
},
|
||||
GraphTitle.DATABASE_CALLS_AVG_DURATION,
|
||||
),
|
||||
title: GraphTitle.DATABASE_CALLS_AVG_DURATION,
|
||||
panelTypes: PANEL_TYPES.TIME_SERIES,
|
||||
}),
|
||||
[servicename, tagFilterItems],
|
||||
);
|
||||
|
||||
|
@ -1,4 +1,5 @@
|
||||
import { Col } from 'antd';
|
||||
import { PANEL_TYPES } from 'constants/queryBuilder';
|
||||
import Graph from 'container/GridGraphLayout/Graph/';
|
||||
import {
|
||||
externalCallDuration,
|
||||
@ -41,8 +42,8 @@ function External(): JSX.Element {
|
||||
|
||||
const externalCallErrorWidget = useMemo(
|
||||
() =>
|
||||
getWidgetQueryBuilder(
|
||||
{
|
||||
getWidgetQueryBuilder({
|
||||
query: {
|
||||
queryType: EQueryType.QUERY_BUILDER,
|
||||
promql: [],
|
||||
builder: externalCallErrorPercent({
|
||||
@ -53,8 +54,9 @@ function External(): JSX.Element {
|
||||
clickhouse_sql: [],
|
||||
id: uuid(),
|
||||
},
|
||||
GraphTitle.EXTERNAL_CALL_ERROR_PERCENTAGE,
|
||||
),
|
||||
title: GraphTitle.EXTERNAL_CALL_ERROR_PERCENTAGE,
|
||||
panelTypes: PANEL_TYPES.TIME_SERIES,
|
||||
}),
|
||||
[servicename, tagFilterItems],
|
||||
);
|
||||
|
||||
@ -65,8 +67,8 @@ function External(): JSX.Element {
|
||||
|
||||
const externalCallDurationWidget = useMemo(
|
||||
() =>
|
||||
getWidgetQueryBuilder(
|
||||
{
|
||||
getWidgetQueryBuilder({
|
||||
query: {
|
||||
queryType: EQueryType.QUERY_BUILDER,
|
||||
promql: [],
|
||||
builder: externalCallDuration({
|
||||
@ -76,15 +78,16 @@ function External(): JSX.Element {
|
||||
clickhouse_sql: [],
|
||||
id: uuid(),
|
||||
},
|
||||
GraphTitle.EXTERNAL_CALL_DURATION,
|
||||
),
|
||||
title: GraphTitle.EXTERNAL_CALL_DURATION,
|
||||
panelTypes: PANEL_TYPES.TIME_SERIES,
|
||||
}),
|
||||
[servicename, tagFilterItems],
|
||||
);
|
||||
|
||||
const externalCallRPSWidget = useMemo(
|
||||
() =>
|
||||
getWidgetQueryBuilder(
|
||||
{
|
||||
getWidgetQueryBuilder({
|
||||
query: {
|
||||
queryType: EQueryType.QUERY_BUILDER,
|
||||
promql: [],
|
||||
builder: externalCallRpsByAddress({
|
||||
@ -95,15 +98,16 @@ function External(): JSX.Element {
|
||||
clickhouse_sql: [],
|
||||
id: uuid(),
|
||||
},
|
||||
GraphTitle.EXTERNAL_CALL_RPS_BY_ADDRESS,
|
||||
),
|
||||
title: GraphTitle.EXTERNAL_CALL_RPS_BY_ADDRESS,
|
||||
panelTypes: PANEL_TYPES.TIME_SERIES,
|
||||
}),
|
||||
[servicename, tagFilterItems],
|
||||
);
|
||||
|
||||
const externalCallDurationAddressWidget = useMemo(
|
||||
() =>
|
||||
getWidgetQueryBuilder(
|
||||
{
|
||||
getWidgetQueryBuilder({
|
||||
query: {
|
||||
queryType: EQueryType.QUERY_BUILDER,
|
||||
promql: [],
|
||||
builder: externalCallDurationByAddress({
|
||||
@ -114,8 +118,9 @@ function External(): JSX.Element {
|
||||
clickhouse_sql: [],
|
||||
id: uuid(),
|
||||
},
|
||||
GraphTitle.EXTERNAL_CALL_DURATION_BY_ADDRESS,
|
||||
),
|
||||
title: GraphTitle.EXTERNAL_CALL_DURATION_BY_ADDRESS,
|
||||
panelTypes: PANEL_TYPES.TIME_SERIES,
|
||||
}),
|
||||
[servicename, tagFilterItems],
|
||||
);
|
||||
|
||||
|
@ -2,10 +2,13 @@ import getTopLevelOperations, {
|
||||
ServiceDataProps,
|
||||
} from 'api/metrics/getTopLevelOperations';
|
||||
import { ActiveElement, Chart, ChartData, ChartEvent } from 'chart.js';
|
||||
import { FeatureKeys } from 'constants/features';
|
||||
import { QueryParams } from 'constants/query';
|
||||
import { PANEL_TYPES } from 'constants/queryBuilder';
|
||||
import ROUTES from 'constants/routes';
|
||||
import { routeConfig } from 'container/SideNav/config';
|
||||
import { getQueryString } from 'container/SideNav/helper';
|
||||
import useFeatureFlag from 'hooks/useFeatureFlag';
|
||||
import useResourceAttribute from 'hooks/useResourceAttribute';
|
||||
import {
|
||||
convertRawQueriesToTraceSelectedTags,
|
||||
@ -29,10 +32,11 @@ import {
|
||||
errorPercentage,
|
||||
operationPerSec,
|
||||
} from '../MetricsPageQueries/OverviewQueries';
|
||||
import { Col, Row } from '../styles';
|
||||
import { Card, Col, Row } from '../styles';
|
||||
import ServiceOverview from './Overview/ServiceOverview';
|
||||
import TopLevelOperation from './Overview/TopLevelOperations';
|
||||
import TopOperation from './Overview/TopOperation';
|
||||
import TopOperationMetrics from './Overview/TopOperationMetrics';
|
||||
import { Button } from './styles';
|
||||
import { IServiceName } from './types';
|
||||
import {
|
||||
@ -53,6 +57,8 @@ function Application(): JSX.Element {
|
||||
() => (convertRawQueriesToTraceSelectedTags(queries) as Tags[]) || [],
|
||||
[queries],
|
||||
);
|
||||
const isSpanMetricEnabled = useFeatureFlag(FeatureKeys.USE_SPAN_METRICS)
|
||||
?.active;
|
||||
|
||||
const handleSetTimeStamp = useCallback((selectTime: number) => {
|
||||
setSelectedTimeStamp(selectTime);
|
||||
@ -104,8 +110,8 @@ function Application(): JSX.Element {
|
||||
|
||||
const operationPerSecWidget = useMemo(
|
||||
() =>
|
||||
getWidgetQueryBuilder(
|
||||
{
|
||||
getWidgetQueryBuilder({
|
||||
query: {
|
||||
queryType: EQueryType.QUERY_BUILDER,
|
||||
promql: [],
|
||||
builder: operationPerSec({
|
||||
@ -116,15 +122,16 @@ function Application(): JSX.Element {
|
||||
clickhouse_sql: [],
|
||||
id: uuid(),
|
||||
},
|
||||
GraphTitle.RATE_PER_OPS,
|
||||
),
|
||||
title: GraphTitle.RATE_PER_OPS,
|
||||
panelTypes: PANEL_TYPES.TIME_SERIES,
|
||||
}),
|
||||
[servicename, tagFilterItems, topLevelOperationsRoute],
|
||||
);
|
||||
|
||||
const errorPercentageWidget = useMemo(
|
||||
() =>
|
||||
getWidgetQueryBuilder(
|
||||
{
|
||||
getWidgetQueryBuilder({
|
||||
query: {
|
||||
queryType: EQueryType.QUERY_BUILDER,
|
||||
promql: [],
|
||||
builder: errorPercentage({
|
||||
@ -135,8 +142,9 @@ function Application(): JSX.Element {
|
||||
clickhouse_sql: [],
|
||||
id: uuid(),
|
||||
},
|
||||
GraphTitle.ERROR_PERCENTAGE,
|
||||
),
|
||||
title: GraphTitle.ERROR_PERCENTAGE,
|
||||
panelTypes: PANEL_TYPES.TIME_SERIES,
|
||||
}),
|
||||
[servicename, tagFilterItems, topLevelOperationsRoute],
|
||||
);
|
||||
|
||||
@ -239,7 +247,9 @@ function Application(): JSX.Element {
|
||||
</Col>
|
||||
|
||||
<Col span={12}>
|
||||
<TopOperation />
|
||||
<Card>
|
||||
{isSpanMetricEnabled ? <TopOperationMetrics /> : <TopOperation />}
|
||||
</Card>
|
||||
</Col>
|
||||
</Row>
|
||||
</>
|
||||
|
@ -1,4 +1,5 @@
|
||||
import { FeatureKeys } from 'constants/features';
|
||||
import { PANEL_TYPES } from 'constants/queryBuilder';
|
||||
import Graph from 'container/GridGraphLayout/Graph/';
|
||||
import { GraphTitle } from 'container/MetricsApplication/constant';
|
||||
import { getWidgetQueryBuilder } from 'container/MetricsApplication/MetricsApplication.factory';
|
||||
@ -31,8 +32,8 @@ function ServiceOverview({
|
||||
|
||||
const latencyWidget = useMemo(
|
||||
() =>
|
||||
getWidgetQueryBuilder(
|
||||
{
|
||||
getWidgetQueryBuilder({
|
||||
query: {
|
||||
queryType: EQueryType.QUERY_BUILDER,
|
||||
promql: [],
|
||||
builder: latency({
|
||||
@ -44,8 +45,9 @@ function ServiceOverview({
|
||||
clickhouse_sql: [],
|
||||
id: uuid(),
|
||||
},
|
||||
GraphTitle.LATENCY,
|
||||
),
|
||||
title: GraphTitle.LATENCY,
|
||||
panelTypes: PANEL_TYPES.TIME_SERIES,
|
||||
}),
|
||||
[servicename, tagFilterItems, isSpanMetricEnable, topLevelOperationsRoute],
|
||||
);
|
||||
|
||||
|
@ -0,0 +1,39 @@
|
||||
import { Tooltip, Typography } from 'antd';
|
||||
import { navigateToTrace } from 'container/MetricsApplication/utils';
|
||||
import { RowData } from 'lib/query/createTableColumnsFromQuery';
|
||||
|
||||
function ColumnWithLink({
|
||||
servicename,
|
||||
minTime,
|
||||
maxTime,
|
||||
selectedTraceTags,
|
||||
record,
|
||||
}: LinkColumnProps): JSX.Element {
|
||||
const text = record.toString();
|
||||
|
||||
const handleOnClick = (operation: string) => (): void => {
|
||||
navigateToTrace({
|
||||
servicename,
|
||||
operation,
|
||||
minTime,
|
||||
maxTime,
|
||||
selectedTraceTags,
|
||||
});
|
||||
};
|
||||
|
||||
return (
|
||||
<Tooltip placement="topLeft" title={text}>
|
||||
<Typography.Link onClick={handleOnClick(text)}>{text}</Typography.Link>
|
||||
</Tooltip>
|
||||
);
|
||||
}
|
||||
|
||||
interface LinkColumnProps {
|
||||
servicename: string;
|
||||
minTime: number;
|
||||
maxTime: number;
|
||||
selectedTraceTags: string;
|
||||
record: RowData;
|
||||
}
|
||||
|
||||
export default ColumnWithLink;
|
@ -0,0 +1,11 @@
|
||||
import { RowData } from 'lib/query/createTableColumnsFromQuery';
|
||||
import { ReactNode } from 'react';
|
||||
|
||||
import { TableRendererProps } from '../../types';
|
||||
|
||||
export const getTableColumnRenderer = ({
|
||||
columnName,
|
||||
renderFunction,
|
||||
}: TableRendererProps): Record<string, (record: RowData) => ReactNode> => ({
|
||||
[columnName]: renderFunction,
|
||||
});
|
@ -1,6 +1,5 @@
|
||||
import getTopOperations from 'api/metrics/getTopOperations';
|
||||
import Spinner from 'components/Spinner';
|
||||
import { Card } from 'container/MetricsApplication/styles';
|
||||
import TopOperationsTable from 'container/MetricsApplication/TopOperationsTable';
|
||||
import useResourceAttribute from 'hooks/useResourceAttribute';
|
||||
import { convertRawQueriesToTraceSelectedTags } from 'hooks/useResourceAttribute/utils';
|
||||
@ -35,11 +34,13 @@ function TopOperation(): JSX.Element {
|
||||
}),
|
||||
});
|
||||
|
||||
const topOperationData = data || [];
|
||||
|
||||
return (
|
||||
<Card>
|
||||
<>
|
||||
{isLoading && <Spinner size="large" tip="Loading..." height="40vh" />}
|
||||
{!isLoading && <TopOperationsTable data={data || []} />}
|
||||
</Card>
|
||||
{!isLoading && <TopOperationsTable data={topOperationData} />}
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,122 @@
|
||||
import { PANEL_TYPES } from 'constants/queryBuilder';
|
||||
import { getWidgetQueryBuilder } from 'container/MetricsApplication/MetricsApplication.factory';
|
||||
import { topOperationQueries } from 'container/MetricsApplication/MetricsPageQueries/TopOperationQueries';
|
||||
import { QueryTable } from 'container/QueryTable';
|
||||
import { useGetQueryRange } from 'hooks/queryBuilder/useGetQueryRange';
|
||||
import { useStepInterval } from 'hooks/queryBuilder/useStepInterval';
|
||||
import useResourceAttribute from 'hooks/useResourceAttribute';
|
||||
import { convertRawQueriesToTraceSelectedTags } from 'hooks/useResourceAttribute/utils';
|
||||
import { getDashboardVariables } from 'lib/dashbaordVariables/getDashboardVariables';
|
||||
import { RowData } from 'lib/query/createTableColumnsFromQuery';
|
||||
import { isEmpty } from 'lodash-es';
|
||||
import { ReactNode, useMemo, useState } from 'react';
|
||||
import { useSelector } from 'react-redux';
|
||||
import { useParams } from 'react-router-dom';
|
||||
import { AppState } from 'store/reducers';
|
||||
import { EQueryType } from 'types/common/dashboard';
|
||||
import { GlobalReducer } from 'types/reducer/globalTime';
|
||||
import { v4 as uuid } from 'uuid';
|
||||
|
||||
import { IServiceName } from '../types';
|
||||
import { title } from './config';
|
||||
import ColumnWithLink from './TableRenderer/ColumnWithLink';
|
||||
import { getTableColumnRenderer } from './TableRenderer/TableColumnRenderer';
|
||||
|
||||
function TopOperationMetrics(): JSX.Element {
|
||||
const { servicename } = useParams<IServiceName>();
|
||||
|
||||
const [errorMessage, setErrorMessage] = useState<string | undefined>('');
|
||||
const { minTime, maxTime, selectedTime: globalSelectedInterval } = useSelector<
|
||||
AppState,
|
||||
GlobalReducer
|
||||
>((state) => state.globalTime);
|
||||
const { queries } = useResourceAttribute();
|
||||
|
||||
const selectedTraceTags = JSON.stringify(
|
||||
convertRawQueriesToTraceSelectedTags(queries) || [],
|
||||
);
|
||||
|
||||
const keyOperationWidget = useMemo(
|
||||
() =>
|
||||
getWidgetQueryBuilder({
|
||||
query: {
|
||||
queryType: EQueryType.QUERY_BUILDER,
|
||||
promql: [],
|
||||
builder: topOperationQueries({
|
||||
servicename,
|
||||
}),
|
||||
clickhouse_sql: [],
|
||||
id: uuid(),
|
||||
},
|
||||
panelTypes: PANEL_TYPES.TABLE,
|
||||
}),
|
||||
[servicename],
|
||||
);
|
||||
|
||||
const updatedQuery = useStepInterval(keyOperationWidget.query);
|
||||
|
||||
const isEmptyWidget = useMemo(
|
||||
() => keyOperationWidget.id === 'empty' || isEmpty(keyOperationWidget),
|
||||
[keyOperationWidget],
|
||||
);
|
||||
|
||||
const { data, isLoading } = useGetQueryRange(
|
||||
{
|
||||
selectedTime: keyOperationWidget?.timePreferance,
|
||||
graphType: keyOperationWidget?.panelTypes,
|
||||
query: updatedQuery,
|
||||
globalSelectedInterval,
|
||||
variables: getDashboardVariables(),
|
||||
},
|
||||
{
|
||||
queryKey: [
|
||||
`GetMetricsQueryRange-${keyOperationWidget?.timePreferance}-${globalSelectedInterval}-${keyOperationWidget?.id}`,
|
||||
keyOperationWidget,
|
||||
maxTime,
|
||||
minTime,
|
||||
globalSelectedInterval,
|
||||
],
|
||||
keepPreviousData: true,
|
||||
enabled: !isEmptyWidget,
|
||||
refetchOnMount: false,
|
||||
onError: (error) => {
|
||||
setErrorMessage(error.message);
|
||||
},
|
||||
},
|
||||
);
|
||||
|
||||
const queryTableData = data?.payload.data.newResult.data.result || [];
|
||||
|
||||
const renderColumnCell = useMemo(
|
||||
() =>
|
||||
getTableColumnRenderer({
|
||||
columnName: 'operation',
|
||||
renderFunction: (record: RowData): ReactNode => (
|
||||
<ColumnWithLink
|
||||
servicename={servicename}
|
||||
minTime={minTime}
|
||||
maxTime={maxTime}
|
||||
selectedTraceTags={selectedTraceTags}
|
||||
record={record}
|
||||
/>
|
||||
),
|
||||
}),
|
||||
[servicename, minTime, maxTime, selectedTraceTags],
|
||||
);
|
||||
|
||||
if (errorMessage) {
|
||||
return <div>{errorMessage}</div>;
|
||||
}
|
||||
|
||||
return (
|
||||
<QueryTable
|
||||
title={title}
|
||||
query={updatedQuery}
|
||||
queryTableData={queryTableData}
|
||||
loading={isLoading}
|
||||
renderColumnCell={renderColumnCell}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
export default TopOperationMetrics;
|
@ -0,0 +1 @@
|
||||
export const title = (): string => 'Key Operations';
|
@ -1,3 +1,62 @@
|
||||
import { RowData } from 'lib/query/createTableColumnsFromQuery';
|
||||
import { ReactNode } from 'react';
|
||||
import { BaseAutocompleteData } from 'types/api/queryBuilder/queryAutocompleteResponse';
|
||||
import { TagFilterItem } from 'types/api/queryBuilder/queryBuilderData';
|
||||
import { DataSource, MetricAggregateOperator } from 'types/common/queryBuilder';
|
||||
|
||||
export interface IServiceName {
|
||||
servicename: string;
|
||||
}
|
||||
|
||||
export interface TopOperationQueryFactoryProps {
|
||||
servicename: IServiceName['servicename'];
|
||||
}
|
||||
|
||||
export interface ExternalCallDurationByAddressProps extends ExternalCallProps {
|
||||
legend: string;
|
||||
}
|
||||
|
||||
export interface ExternalCallProps {
|
||||
servicename: IServiceName['servicename'];
|
||||
tagFilterItems: TagFilterItem[];
|
||||
}
|
||||
|
||||
export interface BuilderQueriesProps {
|
||||
autocompleteData: BaseAutocompleteData[];
|
||||
groupBy?: BaseAutocompleteData[];
|
||||
legends: string[];
|
||||
filterItems: TagFilterItem[][];
|
||||
aggregateOperator?: string[];
|
||||
dataSource: DataSource;
|
||||
queryNameAndExpression?: string[];
|
||||
}
|
||||
|
||||
export interface BuilderQuerieswithFormulaProps {
|
||||
autocompleteData: BaseAutocompleteData[];
|
||||
legends: string[];
|
||||
disabled: boolean[];
|
||||
groupBy?: BaseAutocompleteData[];
|
||||
expression: string;
|
||||
legendFormula: string;
|
||||
additionalItems: TagFilterItem[][];
|
||||
aggregateOperators: MetricAggregateOperator[];
|
||||
dataSource: DataSource;
|
||||
}
|
||||
|
||||
export interface OperationPerSecProps {
|
||||
servicename: IServiceName['servicename'];
|
||||
tagFilterItems: TagFilterItem[];
|
||||
topLevelOperations: string[];
|
||||
}
|
||||
|
||||
export interface LatencyProps {
|
||||
servicename: IServiceName['servicename'];
|
||||
tagFilterItems: TagFilterItem[];
|
||||
isSpanMetricEnable?: boolean;
|
||||
topLevelOperationsRoute: string[];
|
||||
}
|
||||
|
||||
export interface TableRendererProps {
|
||||
columnName: string;
|
||||
renderFunction: (record: RowData) => ReactNode;
|
||||
}
|
||||
|
@ -1,17 +1,14 @@
|
||||
import { Tooltip, Typography } from 'antd';
|
||||
import { ColumnsType } from 'antd/lib/table';
|
||||
import { ResizeTable } from 'components/ResizeTable';
|
||||
import { QueryParams } from 'constants/query';
|
||||
import ROUTES from 'constants/routes';
|
||||
import useResourceAttribute from 'hooks/useResourceAttribute';
|
||||
import { convertRawQueriesToTraceSelectedTags } from 'hooks/useResourceAttribute/utils';
|
||||
import history from 'lib/history';
|
||||
import { useSelector } from 'react-redux';
|
||||
import { useParams } from 'react-router-dom';
|
||||
import { AppState } from 'store/reducers';
|
||||
import { GlobalReducer } from 'types/reducer/globalTime';
|
||||
|
||||
import { getErrorRate } from './utils';
|
||||
import { getErrorRate, navigateToTrace } from './utils';
|
||||
|
||||
function TopOperationsTable(props: TopOperationsTableProps): JSX.Element {
|
||||
const { minTime, maxTime } = useSelector<AppState, GlobalReducer>(
|
||||
@ -28,16 +25,15 @@ function TopOperationsTable(props: TopOperationsTableProps): JSX.Element {
|
||||
const params = useParams<{ servicename: string }>();
|
||||
|
||||
const handleOnClick = (operation: string): void => {
|
||||
const urlParams = new URLSearchParams();
|
||||
const { servicename } = params;
|
||||
urlParams.set(QueryParams.startTime, (minTime / 1000000).toString());
|
||||
urlParams.set(QueryParams.endTime, (maxTime / 1000000).toString());
|
||||
|
||||
history.push(
|
||||
`${
|
||||
ROUTES.TRACE
|
||||
}?${urlParams.toString()}&selected={"serviceName":["${servicename}"],"operation":["${operation}"]}&filterToFetchData=["duration","status","serviceName","operation"]&spanAggregateCurrentPage=1&selectedTags=${selectedTraceTags}&&isFilterExclude={"serviceName":false,"operation":false}&userSelectedFilter={"status":["error","ok"],"serviceName":["${servicename}"],"operation":["${operation}"]}&spanAggregateCurrentPage=1`,
|
||||
);
|
||||
navigateToTrace({
|
||||
servicename,
|
||||
operation,
|
||||
minTime,
|
||||
maxTime,
|
||||
selectedTraceTags,
|
||||
});
|
||||
};
|
||||
|
||||
const columns: ColumnsType<TopOperationList> = [
|
||||
|
@ -28,6 +28,14 @@ export enum GraphTitle {
|
||||
EXTERNAL_CALL_DURATION_BY_ADDRESS = 'External Call duration(by Address)',
|
||||
}
|
||||
|
||||
export enum KeyOperationTableHeader {
|
||||
P50 = 'P50',
|
||||
P90 = 'P90',
|
||||
P99 = 'P99',
|
||||
NUM_OF_CALLS = 'Number of Calls',
|
||||
ERROR_RATE = 'Error Rate',
|
||||
}
|
||||
|
||||
export enum DataType {
|
||||
STRING = 'string',
|
||||
FLOAT64 = 'float64',
|
||||
|
15
frontend/src/container/MetricsApplication/types.ts
Normal file
15
frontend/src/container/MetricsApplication/types.ts
Normal file
@ -0,0 +1,15 @@
|
||||
import { Widgets } from 'types/api/dashboard/getAll';
|
||||
|
||||
export interface GetWidgetQueryBuilderProps {
|
||||
query: Widgets['query'];
|
||||
title?: string;
|
||||
panelTypes: Widgets['panelTypes'];
|
||||
}
|
||||
|
||||
export interface NavigateToTraceProps {
|
||||
servicename: string;
|
||||
operation: string;
|
||||
minTime: number;
|
||||
maxTime: number;
|
||||
selectedTraceTags: string;
|
||||
}
|
@ -1,4 +1,26 @@
|
||||
import { QueryParams } from 'constants/query';
|
||||
import ROUTES from 'constants/routes';
|
||||
import history from 'lib/history';
|
||||
|
||||
import { TopOperationList } from './TopOperationsTable';
|
||||
import { NavigateToTraceProps } from './types';
|
||||
|
||||
export const getErrorRate = (list: TopOperationList): number =>
|
||||
(list.errorCount / list.numCalls) * 100;
|
||||
|
||||
export const navigateToTrace = ({
|
||||
servicename,
|
||||
operation,
|
||||
minTime,
|
||||
maxTime,
|
||||
selectedTraceTags,
|
||||
}: NavigateToTraceProps): void => {
|
||||
const urlParams = new URLSearchParams();
|
||||
urlParams.set(QueryParams.startTime, (minTime / 1000000).toString());
|
||||
urlParams.set(QueryParams.endTime, (maxTime / 1000000).toString());
|
||||
history.push(
|
||||
`${
|
||||
ROUTES.TRACE
|
||||
}?${urlParams.toString()}&selected={"serviceName":["${servicename}"],"operation":["${operation}"]}&filterToFetchData=["duration","status","serviceName","operation"]&spanAggregateCurrentPage=1&selectedTags=${selectedTraceTags}&&isFilterExclude={"serviceName":false,"operation":false}&userSelectedFilter={"status":["error","ok"],"serviceName":["${servicename}"],"operation":["${operation}"]}&spanAggregateCurrentPage=1`,
|
||||
);
|
||||
};
|
||||
|
Loading…
x
Reference in New Issue
Block a user