mirror of
https://git.mirrors.martin98.com/https://github.com/SigNoz/signoz
synced 2025-08-12 01:59:04 +08:00
1375 overview querybuilder (#1983)
This commit is contained in:
parent
a405307c96
commit
f1c7d72fc5
@ -0,0 +1,20 @@
|
||||
import { Widgets } from 'types/api/dashboard/getAll';
|
||||
import { v4 } from 'uuid';
|
||||
|
||||
export const getWidgetQueryBuilder = (query: Widgets['query']): Widgets => ({
|
||||
description: '',
|
||||
id: v4(),
|
||||
isStacked: false,
|
||||
nullZeroValues: '',
|
||||
opacity: '0',
|
||||
panelTypes: 'TIME_SERIES',
|
||||
query,
|
||||
queryData: {
|
||||
data: { queryData: [] },
|
||||
error: false,
|
||||
errorMessage: '',
|
||||
loading: false,
|
||||
},
|
||||
timePreferance: 'GLOBAL_TIME',
|
||||
title: '',
|
||||
});
|
@ -0,0 +1,112 @@
|
||||
import {
|
||||
IMetricsBuilderFormula,
|
||||
IMetricsBuilderQuery,
|
||||
IQueryBuilderTagFilterItems,
|
||||
} from 'types/api/dashboard/getAll';
|
||||
|
||||
import {
|
||||
getQueryBuilderQueries,
|
||||
getQueryBuilderQuerieswithFormula,
|
||||
} from './MetricsPageQueriesFactory';
|
||||
|
||||
export const operationPerSec = ({
|
||||
servicename,
|
||||
tagFilterItems,
|
||||
topLevelOperations,
|
||||
}: OperationPerSecProps): IOverviewQueries => {
|
||||
const metricName = 'signoz_latency_count';
|
||||
const legend = 'Operations';
|
||||
const itemsA = [
|
||||
{
|
||||
id: '',
|
||||
key: 'service_name',
|
||||
op: 'IN',
|
||||
value: [`${servicename}`],
|
||||
},
|
||||
{
|
||||
id: '',
|
||||
key: 'operation',
|
||||
op: 'MATCH',
|
||||
value: topLevelOperations,
|
||||
},
|
||||
...tagFilterItems,
|
||||
];
|
||||
|
||||
return getQueryBuilderQueries({
|
||||
metricName,
|
||||
legend,
|
||||
itemsA,
|
||||
});
|
||||
};
|
||||
|
||||
export const errorPercentage = ({
|
||||
servicename,
|
||||
tagFilterItems,
|
||||
topLevelOperations,
|
||||
}: OperationPerSecProps): IOverviewQueries => {
|
||||
const metricNameA = 'signoz_calls_total';
|
||||
const metricNameB = 'signoz_calls_total';
|
||||
const additionalItemsA = [
|
||||
{
|
||||
id: '',
|
||||
key: 'service_name',
|
||||
op: 'IN',
|
||||
value: [`${servicename}`],
|
||||
},
|
||||
{
|
||||
id: '',
|
||||
key: 'operation',
|
||||
op: 'MATCH',
|
||||
value: topLevelOperations,
|
||||
},
|
||||
{
|
||||
id: '',
|
||||
key: 'status_code',
|
||||
op: 'IN',
|
||||
value: ['STATUS_CODE_ERROR'],
|
||||
},
|
||||
...tagFilterItems,
|
||||
];
|
||||
|
||||
const additionalItemsB = [
|
||||
{
|
||||
id: '',
|
||||
key: 'service_name',
|
||||
op: 'IN',
|
||||
value: [`${servicename}`],
|
||||
},
|
||||
{
|
||||
id: '',
|
||||
key: 'operation',
|
||||
op: 'MATCH',
|
||||
value: topLevelOperations,
|
||||
},
|
||||
...tagFilterItems,
|
||||
];
|
||||
|
||||
const legendFormula = 'Error Percentage';
|
||||
const legend = legendFormula;
|
||||
const expression = 'A*100/B';
|
||||
const disabled = true;
|
||||
return getQueryBuilderQuerieswithFormula({
|
||||
metricNameA,
|
||||
metricNameB,
|
||||
additionalItemsA,
|
||||
additionalItemsB,
|
||||
legend,
|
||||
disabled,
|
||||
expression,
|
||||
legendFormula,
|
||||
});
|
||||
};
|
||||
|
||||
export interface OperationPerSecProps {
|
||||
servicename: string | undefined;
|
||||
tagFilterItems: IQueryBuilderTagFilterItems[];
|
||||
topLevelOperations: string[];
|
||||
}
|
||||
|
||||
interface IOverviewQueries {
|
||||
formulas: IMetricsBuilderFormula[];
|
||||
queryBuilder: IMetricsBuilderQuery[];
|
||||
}
|
@ -2,25 +2,31 @@ import { ActiveElement, Chart, ChartData, ChartEvent } from 'chart.js';
|
||||
import Graph from 'components/Graph';
|
||||
import { METRICS_PAGE_QUERY_PARAM } from 'constants/query';
|
||||
import ROUTES from 'constants/routes';
|
||||
import FullView from 'container/GridGraphLayout/Graph/FullView';
|
||||
import FullView from 'container/GridGraphLayout/Graph/FullView/index.metricsBuilder';
|
||||
import convertToNanoSecondsToSecond from 'lib/convertToNanoSecondsToSecond';
|
||||
import { colors } from 'lib/getRandomColor';
|
||||
import history from 'lib/history';
|
||||
import { convertRawQueriesToTraceSelectedTags } from 'lib/resourceAttributes';
|
||||
import { escapeRegExp } from 'lodash-es';
|
||||
import {
|
||||
convertRawQueriesToTraceSelectedTags,
|
||||
resourceAttributesToTagFilterItems,
|
||||
} from 'lib/resourceAttributes';
|
||||
import React, { useCallback, useMemo, useRef } from 'react';
|
||||
import { useDispatch, useSelector } from 'react-redux';
|
||||
import { useParams } from 'react-router-dom';
|
||||
import { UpdateTimeInterval } from 'store/actions';
|
||||
import { AppState } from 'store/reducers';
|
||||
import { PromQLWidgets } from 'types/api/dashboard/getAll';
|
||||
import { Widgets } from 'types/api/dashboard/getAll';
|
||||
import MetricReducer from 'types/reducer/metrics';
|
||||
|
||||
import {
|
||||
errorPercentage,
|
||||
operationPerSec,
|
||||
} from '../MetricsPageQueries/OverviewQueries';
|
||||
import { Card, Col, GraphContainer, GraphTitle, Row } from '../styles';
|
||||
import TopOperationsTable from '../TopOperationsTable';
|
||||
import { Button } from './styles';
|
||||
|
||||
function Application({ getWidget }: DashboardProps): JSX.Element {
|
||||
function Application({ getWidgetQueryBuilder }: DashboardProps): JSX.Element {
|
||||
const { servicename } = useParams<{ servicename?: string }>();
|
||||
const selectedTimeStamp = useRef(0);
|
||||
const dispatch = useDispatch();
|
||||
@ -28,20 +34,49 @@ function Application({ getWidget }: DashboardProps): JSX.Element {
|
||||
const {
|
||||
topOperations,
|
||||
serviceOverview,
|
||||
resourceAttributePromQLQuery,
|
||||
resourceAttributeQueries,
|
||||
topLevelOperations,
|
||||
} = useSelector<AppState, MetricReducer>((state) => state.metrics);
|
||||
const operationsRegex = useMemo(() => {
|
||||
return encodeURIComponent(
|
||||
topLevelOperations.map((e) => escapeRegExp(e)).join('|'),
|
||||
);
|
||||
}, [topLevelOperations]);
|
||||
|
||||
const selectedTraceTags: string = JSON.stringify(
|
||||
convertRawQueriesToTraceSelectedTags(resourceAttributeQueries, 'array') || [],
|
||||
);
|
||||
|
||||
const tagFilterItems = useMemo(
|
||||
() => resourceAttributesToTagFilterItems(resourceAttributeQueries) || [],
|
||||
[resourceAttributeQueries],
|
||||
);
|
||||
|
||||
const operationPerSecWidget = useMemo(
|
||||
() =>
|
||||
getWidgetQueryBuilder({
|
||||
queryType: 1,
|
||||
promQL: [],
|
||||
metricsBuilder: operationPerSec({
|
||||
servicename,
|
||||
tagFilterItems,
|
||||
topLevelOperations,
|
||||
}),
|
||||
clickHouse: [],
|
||||
}),
|
||||
[getWidgetQueryBuilder, servicename, topLevelOperations, tagFilterItems],
|
||||
);
|
||||
|
||||
const errorPercentageWidget = useMemo(
|
||||
() =>
|
||||
getWidgetQueryBuilder({
|
||||
queryType: 1,
|
||||
promQL: [],
|
||||
metricsBuilder: errorPercentage({
|
||||
servicename,
|
||||
tagFilterItems,
|
||||
topLevelOperations,
|
||||
}),
|
||||
clickHouse: [],
|
||||
}),
|
||||
[servicename, topLevelOperations, tagFilterItems, getWidgetQueryBuilder],
|
||||
);
|
||||
|
||||
const onTracePopupClick = (timestamp: number): void => {
|
||||
const currentTime = timestamp;
|
||||
const tPlusOne = timestamp + 1 * 60 * 1000;
|
||||
@ -211,12 +246,7 @@ function Application({ getWidget }: DashboardProps): JSX.Element {
|
||||
onClickHandler={(event, element, chart, data): void => {
|
||||
onClickHandler(event, element, chart, data, 'Rate');
|
||||
}}
|
||||
widget={getWidget([
|
||||
{
|
||||
query: `sum(rate(signoz_latency_count{service_name="${servicename}", operation=~\`${operationsRegex}\`${resourceAttributePromQLQuery}}[5m]))`,
|
||||
legend: 'Operations',
|
||||
},
|
||||
])}
|
||||
widget={operationPerSecWidget}
|
||||
yAxisUnit="ops"
|
||||
onDragSelect={onDragSelect}
|
||||
/>
|
||||
@ -246,12 +276,7 @@ function Application({ getWidget }: DashboardProps): JSX.Element {
|
||||
onClickHandler={(ChartEvent, activeElements, chart, data): void => {
|
||||
onClickHandler(ChartEvent, activeElements, chart, data, 'Error');
|
||||
}}
|
||||
widget={getWidget([
|
||||
{
|
||||
query: `max(sum(rate(signoz_calls_total{service_name="${servicename}", operation=~\`${operationsRegex}\`, status_code="STATUS_CODE_ERROR"${resourceAttributePromQLQuery}}[5m]) OR rate(signoz_calls_total{service_name="${servicename}", operation=~\`${operationsRegex}\`, http_status_code=~"5.."${resourceAttributePromQLQuery}}[5m]))*100/sum(rate(signoz_calls_total{service_name="${servicename}", operation=~\`${operationsRegex}\`${resourceAttributePromQLQuery}}[5m]))) < 1000 OR vector(0)`,
|
||||
legend: 'Error Percentage',
|
||||
},
|
||||
])}
|
||||
widget={errorPercentageWidget}
|
||||
yAxisUnit="%"
|
||||
onDragSelect={onDragSelect}
|
||||
/>
|
||||
@ -270,7 +295,7 @@ function Application({ getWidget }: DashboardProps): JSX.Element {
|
||||
}
|
||||
|
||||
interface DashboardProps {
|
||||
getWidget: (query: PromQLWidgets['query']) => PromQLWidgets;
|
||||
getWidgetQueryBuilder: (query: Widgets['query']) => Widgets;
|
||||
}
|
||||
|
||||
export default Application;
|
||||
|
@ -3,58 +3,15 @@ import ROUTES from 'constants/routes';
|
||||
import React from 'react';
|
||||
import { generatePath, useParams } from 'react-router-dom';
|
||||
import { useLocation } from 'react-use';
|
||||
import { PromQLWidgets, Widgets } from 'types/api/dashboard/getAll';
|
||||
import { v4 } from 'uuid';
|
||||
|
||||
import { getWidgetQueryBuilder } from './MetricsApplication.factory';
|
||||
import ResourceAttributesFilter from './ResourceAttributesFilter';
|
||||
import DBCall from './Tabs/DBCall';
|
||||
import External from './Tabs/External';
|
||||
import Overview from './Tabs/Overview';
|
||||
|
||||
const getWidget = (query: PromQLWidgets['query']): PromQLWidgets => {
|
||||
return {
|
||||
description: '',
|
||||
id: '',
|
||||
isStacked: false,
|
||||
nullZeroValues: '',
|
||||
opacity: '0',
|
||||
panelTypes: 'TIME_SERIES',
|
||||
query,
|
||||
queryData: {
|
||||
data: { queryData: [] },
|
||||
error: false,
|
||||
errorMessage: '',
|
||||
loading: false,
|
||||
},
|
||||
timePreferance: 'GLOBAL_TIME',
|
||||
title: '',
|
||||
stepSize: 60,
|
||||
};
|
||||
};
|
||||
|
||||
const getWidgetQueryBuilder = (query: Widgets['query']): Widgets => {
|
||||
return {
|
||||
description: '',
|
||||
id: v4(),
|
||||
isStacked: false,
|
||||
nullZeroValues: '',
|
||||
opacity: '0',
|
||||
panelTypes: 'TIME_SERIES',
|
||||
query,
|
||||
queryData: {
|
||||
data: { queryData: [] },
|
||||
error: false,
|
||||
errorMessage: '',
|
||||
loading: false,
|
||||
},
|
||||
timePreferance: 'GLOBAL_TIME',
|
||||
title: '',
|
||||
stepSize: 60,
|
||||
};
|
||||
};
|
||||
|
||||
function OverViewTab(): JSX.Element {
|
||||
return <Overview getWidget={getWidget} />;
|
||||
return <Overview getWidgetQueryBuilder={getWidgetQueryBuilder} />;
|
||||
}
|
||||
|
||||
function DbCallTab(): JSX.Element {
|
||||
|
Loading…
x
Reference in New Issue
Block a user