1363 externalcall querybuilder (#1550)

* externaltab-promql-to-querybuilder
* refactored the queries into separate file
* added logic for resourceattribute to tagFilter items conversion
* refactor: use useMemo

Co-authored-by: Palash Gupta <palashgdev@gmail.com>
This commit is contained in:
Priyanka Chakraborty 2022-10-03 08:51:08 +05:30 committed by GitHub
parent 1b1fb2f13b
commit 3bbe2f4f58
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 337 additions and 39 deletions

View File

@ -46,7 +46,7 @@ function FullView({
const response = useQuery< const response = useQuery<
SuccessResponse<MetricRangePayloadProps> | ErrorResponse SuccessResponse<MetricRangePayloadProps> | ErrorResponse
>( >(
`FullViewGetMetricsQueryRange-${selectedTime.enum}-${globalSelectedTime}`, `FullViewGetMetricsQueryRange-${selectedTime.enum}-${globalSelectedTime}-${widget.id}`,
() => () =>
GetMetricQueryRange({ GetMetricQueryRange({
selectedTime: selectedTime.enum, selectedTime: selectedTime.enum,

View File

@ -0,0 +1,238 @@
import {
IMetricsBuilderFormula,
IMetricsBuilderQuery,
IQueryBuilderTagFilterItems,
} from 'types/api/dashboard/getAll';
export const externalCallErrorPercent = ({
servicename,
legend,
tagFilterItems,
}: ExternalCallDurationByAddressProps): {
formulas: IMetricsBuilderFormula[];
queryBuilder: IMetricsBuilderQuery[];
} => ({
formulas: [
{
name: 'F1',
expression: 'A*100/B',
disabled: false,
legend: 'External Call Error Percentage',
},
],
queryBuilder: [
{
name: 'A',
aggregateOperator: 18,
metricName: 'signoz_external_call_latency_count',
tagFilters: {
items: [
{
id: '',
key: 'service_name',
op: 'IN',
value: [`${servicename}`],
},
{
id: '',
key: 'status_code',
op: 'IN',
value: ['STATUS_CODE_ERROR'],
},
...tagFilterItems,
],
op: 'AND',
},
groupBy: ['address'],
legend,
disabled: false,
},
{
name: 'B',
aggregateOperator: 18,
metricName: 'signoz_external_call_latency_count',
tagFilters: {
items: [
{
id: '',
key: 'service_name',
op: 'IN',
value: [`${servicename}`],
},
...tagFilterItems,
],
op: 'AND',
},
groupBy: ['address'],
legend,
disabled: false,
},
],
});
export const externalCallDuration = ({
servicename,
tagFilterItems,
}: ExternalCallProps): {
formulas: IMetricsBuilderFormula[];
queryBuilder: IMetricsBuilderQuery[];
} => ({
formulas: [
{
disabled: false,
expression: 'A/B',
name: 'F1',
legend: 'Average Duration',
},
],
queryBuilder: [
{
aggregateOperator: 18,
disabled: true,
groupBy: [],
legend: '',
metricName: 'signoz_external_call_latency_sum',
name: 'A',
reduceTo: 1,
tagFilters: {
items: [
{
id: '',
key: 'service_name',
op: 'IN',
value: [`${servicename}`],
},
...tagFilterItems,
],
op: 'AND',
},
},
{
aggregateOperator: 18,
disabled: true,
groupBy: [],
legend: '',
metricName: 'signoz_external_call_latency_count',
name: 'B',
reduceTo: 1,
tagFilters: {
items: [
{
id: '',
key: 'service_name',
op: 'IN',
value: [`${servicename}`],
},
...tagFilterItems,
],
op: 'AND',
},
},
],
});
export const externalCallRpsByAddress = ({
servicename,
legend,
tagFilterItems,
}: ExternalCallDurationByAddressProps): {
formulas: IMetricsBuilderFormula[];
queryBuilder: IMetricsBuilderQuery[];
} => ({
formulas: [],
queryBuilder: [
{
aggregateOperator: 18,
disabled: false,
groupBy: ['address'],
legend,
metricName: 'signoz_external_call_latency_count',
name: 'A',
reduceTo: 1,
tagFilters: {
items: [
{
id: '',
key: 'service_name',
op: 'IN',
value: [`${servicename}`],
},
...tagFilterItems,
],
op: 'AND',
},
},
],
});
export const externalCallDurationByAddress = ({
servicename,
legend,
tagFilterItems,
}: ExternalCallDurationByAddressProps): {
formulas: IMetricsBuilderFormula[];
queryBuilder: IMetricsBuilderQuery[];
} => ({
formulas: [
{
disabled: false,
expression: 'A/B',
name: 'F1',
legend,
},
],
queryBuilder: [
{
aggregateOperator: 18,
disabled: false,
groupBy: ['address'],
legend,
metricName: 'signoz_external_call_latency_sum',
name: 'A',
reduceTo: 1,
tagFilters: {
items: [
{
id: '',
key: 'service_name',
op: 'IN',
value: [`${servicename}`],
},
...tagFilterItems,
],
op: 'AND',
},
},
{
aggregateOperator: 18,
disabled: false,
groupBy: ['address'],
legend,
metricName: 'signoz_external_call_latency_count',
name: 'B',
reduceTo: 1,
tagFilters: {
items: [
{
id: '',
key: 'service_name',
op: 'IN',
value: [`${servicename}`],
},
...tagFilterItems,
],
op: 'AND',
},
},
],
});
interface ExternalCallDurationByAddressProps extends ExternalCallProps {
legend: '{{address}}';
}
interface ExternalCallProps {
servicename: string | undefined;
tagFilterItems: IQueryBuilderTagFilterItems[] | [];
}

View File

@ -1,19 +1,32 @@
import { Col } from 'antd'; import { Col } from 'antd';
import FullView from 'container/GridGraphLayout/Graph/FullView'; import FullView from 'container/GridGraphLayout/Graph/FullView/index.metricsBuilder';
import React from 'react'; import {
externalCallDuration,
externalCallDurationByAddress,
externalCallErrorPercent,
externalCallRpsByAddress,
} from 'container/MetricsApplication/MetricsPageQueries/ExternalQueries';
import { resourceAttributesToTagFilterItems } from 'lib/resourceAttributes';
import React, { useMemo } from 'react';
import { useSelector } from 'react-redux'; import { useSelector } from 'react-redux';
import { useParams } from 'react-router-dom'; import { useParams } from 'react-router-dom';
import { AppState } from 'store/reducers'; 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 MetricReducer from 'types/reducer/metrics';
import { Card, GraphContainer, GraphTitle, Row } from '../styles'; import { Card, GraphContainer, GraphTitle, Row } from '../styles';
function External({ getWidget }: ExternalProps): JSX.Element { function External({ getWidgetQueryBuilder }: ExternalProps): JSX.Element {
const { servicename } = useParams<{ servicename?: string }>(); const { servicename } = useParams<{ servicename?: string }>();
const { resourceAttributePromQLQuery } = useSelector<AppState, MetricReducer>( const { resourceAttributeQueries } = useSelector<AppState, MetricReducer>(
(state) => state.metrics, (state) => state.metrics,
); );
const tagFilterItems = useMemo(
() => resourceAttributesToTagFilterItems(resourceAttributeQueries) || [],
[resourceAttributeQueries],
);
const legend = '{{address}}'; const legend = '{{address}}';
return ( return (
@ -26,12 +39,16 @@ function External({ getWidget }: ExternalProps): JSX.Element {
<FullView <FullView
name="external_call_error_percentage" name="external_call_error_percentage"
fullViewOptions={false} fullViewOptions={false}
widget={getWidget([ widget={getWidgetQueryBuilder({
{ queryType: 1,
query: `max((sum(rate(signoz_external_call_latency_count{service_name="${servicename}", status_code="STATUS_CODE_ERROR"${resourceAttributePromQLQuery}}[5m]) OR vector(0)) by (address))*100/sum(rate(signoz_external_call_latency_count{service_name="${servicename}"${resourceAttributePromQLQuery}}[5m])) by (address)) < 1000 OR vector(0)`, promQL: [],
legend: 'External Call Error Percentage', metricsBuilder: externalCallErrorPercent({
}, servicename,
])} legend,
tagFilterItems,
}),
clickHouse: [],
})}
yAxisUnit="%" yAxisUnit="%"
/> />
</GraphContainer> </GraphContainer>
@ -45,12 +62,12 @@ function External({ getWidget }: ExternalProps): JSX.Element {
<FullView <FullView
name="external_call_duration" name="external_call_duration"
fullViewOptions={false} fullViewOptions={false}
widget={getWidget([ widget={getWidgetQueryBuilder({
{ queryType: 1,
query: `sum(rate(signoz_external_call_latency_sum{service_name="${servicename}"${resourceAttributePromQLQuery}}[5m]))/sum(rate(signoz_external_call_latency_count{service_name="${servicename}"${resourceAttributePromQLQuery}}[5m]))`, promQL: [],
legend: 'Average Duration', metricsBuilder: externalCallDuration({ servicename, tagFilterItems }),
}, clickHouse: [],
])} })}
yAxisUnit="ms" yAxisUnit="ms"
/> />
</GraphContainer> </GraphContainer>
@ -66,12 +83,16 @@ function External({ getWidget }: ExternalProps): JSX.Element {
<FullView <FullView
name="external_call_rps_by_address" name="external_call_rps_by_address"
fullViewOptions={false} fullViewOptions={false}
widget={getWidget([ widget={getWidgetQueryBuilder({
{ queryType: 1,
query: `sum(rate(signoz_external_call_latency_count{service_name="${servicename}"${resourceAttributePromQLQuery}}[5m])) by (address)`, promQL: [],
metricsBuilder: externalCallRpsByAddress({
servicename,
legend, legend,
}, tagFilterItems,
])} }),
clickHouse: [],
})}
yAxisUnit="reqps" yAxisUnit="reqps"
/> />
</GraphContainer> </GraphContainer>
@ -85,12 +106,16 @@ function External({ getWidget }: ExternalProps): JSX.Element {
<FullView <FullView
name="external_call_duration_by_address" name="external_call_duration_by_address"
fullViewOptions={false} fullViewOptions={false}
widget={getWidget([ widget={getWidgetQueryBuilder({
{ queryType: 1,
query: `(sum(rate(signoz_external_call_latency_sum{service_name="${servicename}"${resourceAttributePromQLQuery}}[5m])) by (address))/(sum(rate(signoz_external_call_latency_count{service_name="${servicename}"${resourceAttributePromQLQuery}}[5m])) by (address))`, promQL: [],
metricsBuilder: externalCallDurationByAddress({
servicename,
legend, legend,
}, tagFilterItems,
])} }),
clickHouse: [],
})}
yAxisUnit="ms" yAxisUnit="ms"
/> />
</GraphContainer> </GraphContainer>
@ -102,7 +127,7 @@ function External({ getWidget }: ExternalProps): JSX.Element {
} }
interface ExternalProps { interface ExternalProps {
getWidget: (query: PromQLWidgets['query']) => PromQLWidgets; getWidgetQueryBuilder: (query: Widgets['query']) => Widgets;
} }
export default External; export default External;

View File

@ -3,7 +3,8 @@ import ROUTES from 'constants/routes';
import React from 'react'; import React from 'react';
import { generatePath, useParams } from 'react-router-dom'; import { generatePath, useParams } from 'react-router-dom';
import { useLocation } from 'react-use'; import { useLocation } from 'react-use';
import { PromQLWidgets } from 'types/api/dashboard/getAll'; import { PromQLWidgets, Widgets } from 'types/api/dashboard/getAll';
import { v4 } from 'uuid';
import ResourceAttributesFilter from './ResourceAttributesFilter'; import ResourceAttributesFilter from './ResourceAttributesFilter';
import DBCall from './Tabs/DBCall'; import DBCall from './Tabs/DBCall';
@ -31,6 +32,27 @@ const getWidget = (query: PromQLWidgets['query']): PromQLWidgets => {
}; };
}; };
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 { function OverViewTab(): JSX.Element {
return <Overview getWidget={getWidget} />; return <Overview getWidget={getWidget} />;
} }
@ -40,7 +62,7 @@ function DbCallTab(): JSX.Element {
} }
function ExternalTab(): JSX.Element { function ExternalTab(): JSX.Element {
return <External getWidget={getWidget} />; return <External getWidgetQueryBuilder={getWidgetQueryBuilder} />;
} }
function ServiceMetrics(): JSX.Element { function ServiceMetrics(): JSX.Element {

View File

@ -1,5 +1,6 @@
import { OperatorConversions } from 'constants/resourceAttributes'; import { OperatorConversions } from 'constants/resourceAttributes';
import { IResourceAttributeQuery } from 'container/MetricsApplication/ResourceAttributesFilter/types'; import { IResourceAttributeQuery } from 'container/MetricsApplication/ResourceAttributesFilter/types';
import { IQueryBuilderTagFilterItems } from 'types/api/dashboard/getAll';
import { OperatorValues, Tags, TagsAPI } from 'types/reducer/trace'; import { OperatorValues, Tags, TagsAPI } from 'types/reducer/trace';
/** /**
@ -69,3 +70,15 @@ export const resourceAttributesQueryToPromQL = (
return parsedQueryString; return parsedQueryString;
}; };
/* Convert resource attributes to tagFilter items for queryBuilder */
export const resourceAttributesToTagFilterItems = (
queries: IResourceAttributeQuery[],
): IQueryBuilderTagFilterItems[] => {
return queries.map((res) => ({
id: `${res.id}`,
key: `${res.tagKey}`,
op: `${res.operator}`,
value: `${res.tagValue}`.split(','),
}));
};

View File

@ -112,14 +112,7 @@ export interface IMetricsBuilderQuery {
export interface IQueryBuilderTagFilters { export interface IQueryBuilderTagFilters {
op: string; op: string;
items: items: IQueryBuilderTagFilterItems[] | [];
| {
id: string;
key: string;
op: string;
value: string[];
}[]
| [];
} }
export interface IClickHouseQuery { export interface IClickHouseQuery {
@ -134,3 +127,10 @@ export interface IPromQLQuery {
disabled: boolean; disabled: boolean;
name: string; name: string;
} }
export interface IQueryBuilderTagFilterItems {
id: string;
key: string;
op: string;
value: string[];
}