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<
SuccessResponse<MetricRangePayloadProps> | ErrorResponse
>(
`FullViewGetMetricsQueryRange-${selectedTime.enum}-${globalSelectedTime}`,
`FullViewGetMetricsQueryRange-${selectedTime.enum}-${globalSelectedTime}-${widget.id}`,
() =>
GetMetricQueryRange({
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 FullView from 'container/GridGraphLayout/Graph/FullView';
import React from 'react';
import FullView from 'container/GridGraphLayout/Graph/FullView/index.metricsBuilder';
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 { useParams } from 'react-router-dom';
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 { Card, GraphContainer, GraphTitle, Row } from '../styles';
function External({ getWidget }: ExternalProps): JSX.Element {
function External({ getWidgetQueryBuilder }: ExternalProps): JSX.Element {
const { servicename } = useParams<{ servicename?: string }>();
const { resourceAttributePromQLQuery } = useSelector<AppState, MetricReducer>(
const { resourceAttributeQueries } = useSelector<AppState, MetricReducer>(
(state) => state.metrics,
);
const tagFilterItems = useMemo(
() => resourceAttributesToTagFilterItems(resourceAttributeQueries) || [],
[resourceAttributeQueries],
);
const legend = '{{address}}';
return (
@ -26,12 +39,16 @@ function External({ getWidget }: ExternalProps): JSX.Element {
<FullView
name="external_call_error_percentage"
fullViewOptions={false}
widget={getWidget([
{
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)`,
legend: 'External Call Error Percentage',
},
])}
widget={getWidgetQueryBuilder({
queryType: 1,
promQL: [],
metricsBuilder: externalCallErrorPercent({
servicename,
legend,
tagFilterItems,
}),
clickHouse: [],
})}
yAxisUnit="%"
/>
</GraphContainer>
@ -45,12 +62,12 @@ function External({ getWidget }: ExternalProps): JSX.Element {
<FullView
name="external_call_duration"
fullViewOptions={false}
widget={getWidget([
{
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]))`,
legend: 'Average Duration',
},
])}
widget={getWidgetQueryBuilder({
queryType: 1,
promQL: [],
metricsBuilder: externalCallDuration({ servicename, tagFilterItems }),
clickHouse: [],
})}
yAxisUnit="ms"
/>
</GraphContainer>
@ -66,12 +83,16 @@ function External({ getWidget }: ExternalProps): JSX.Element {
<FullView
name="external_call_rps_by_address"
fullViewOptions={false}
widget={getWidget([
{
query: `sum(rate(signoz_external_call_latency_count{service_name="${servicename}"${resourceAttributePromQLQuery}}[5m])) by (address)`,
widget={getWidgetQueryBuilder({
queryType: 1,
promQL: [],
metricsBuilder: externalCallRpsByAddress({
servicename,
legend,
},
])}
tagFilterItems,
}),
clickHouse: [],
})}
yAxisUnit="reqps"
/>
</GraphContainer>
@ -85,12 +106,16 @@ function External({ getWidget }: ExternalProps): JSX.Element {
<FullView
name="external_call_duration_by_address"
fullViewOptions={false}
widget={getWidget([
{
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))`,
widget={getWidgetQueryBuilder({
queryType: 1,
promQL: [],
metricsBuilder: externalCallDurationByAddress({
servicename,
legend,
},
])}
tagFilterItems,
}),
clickHouse: [],
})}
yAxisUnit="ms"
/>
</GraphContainer>
@ -102,7 +127,7 @@ function External({ getWidget }: ExternalProps): JSX.Element {
}
interface ExternalProps {
getWidget: (query: PromQLWidgets['query']) => PromQLWidgets;
getWidgetQueryBuilder: (query: Widgets['query']) => Widgets;
}
export default External;

View File

@ -3,7 +3,8 @@ import ROUTES from 'constants/routes';
import React from 'react';
import { generatePath, useParams } from 'react-router-dom';
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 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 {
return <Overview getWidget={getWidget} />;
}
@ -40,7 +62,7 @@ function DbCallTab(): JSX.Element {
}
function ExternalTab(): JSX.Element {
return <External getWidget={getWidget} />;
return <External getWidgetQueryBuilder={getWidgetQueryBuilder} />;
}
function ServiceMetrics(): JSX.Element {

View File

@ -1,5 +1,6 @@
import { OperatorConversions } from 'constants/resourceAttributes';
import { IResourceAttributeQuery } from 'container/MetricsApplication/ResourceAttributesFilter/types';
import { IQueryBuilderTagFilterItems } from 'types/api/dashboard/getAll';
import { OperatorValues, Tags, TagsAPI } from 'types/reducer/trace';
/**
@ -69,3 +70,15 @@ export const resourceAttributesQueryToPromQL = (
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 {
op: string;
items:
| {
id: string;
key: string;
op: string;
value: string[];
}[]
| [];
items: IQueryBuilderTagFilterItems[] | [];
}
export interface IClickHouseQuery {
@ -134,3 +127,10 @@ export interface IPromQLQuery {
disabled: boolean;
name: string;
}
export interface IQueryBuilderTagFilterItems {
id: string;
key: string;
op: string;
value: string[];
}