diff --git a/frontend/src/container/GridGraphLayout/Graph/FullView/index.metricsBuilder.tsx b/frontend/src/container/GridGraphLayout/Graph/FullView/index.metricsBuilder.tsx index 113049a295..df8ea6c22d 100644 --- a/frontend/src/container/GridGraphLayout/Graph/FullView/index.metricsBuilder.tsx +++ b/frontend/src/container/GridGraphLayout/Graph/FullView/index.metricsBuilder.tsx @@ -46,7 +46,7 @@ function FullView({ const response = useQuery< SuccessResponse | ErrorResponse >( - `FullViewGetMetricsQueryRange-${selectedTime.enum}-${globalSelectedTime}`, + `FullViewGetMetricsQueryRange-${selectedTime.enum}-${globalSelectedTime}-${widget.id}`, () => GetMetricQueryRange({ selectedTime: selectedTime.enum, diff --git a/frontend/src/container/MetricsApplication/MetricsPageQueries/ExternalQueries.tsx b/frontend/src/container/MetricsApplication/MetricsPageQueries/ExternalQueries.tsx new file mode 100644 index 0000000000..f355004b84 --- /dev/null +++ b/frontend/src/container/MetricsApplication/MetricsPageQueries/ExternalQueries.tsx @@ -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[] | []; +} diff --git a/frontend/src/container/MetricsApplication/Tabs/External.tsx b/frontend/src/container/MetricsApplication/Tabs/External.tsx index 4fd039e979..b10dc13f25 100644 --- a/frontend/src/container/MetricsApplication/Tabs/External.tsx +++ b/frontend/src/container/MetricsApplication/Tabs/External.tsx @@ -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( + const { resourceAttributeQueries } = useSelector( (state) => state.metrics, ); + + const tagFilterItems = useMemo( + () => resourceAttributesToTagFilterItems(resourceAttributeQueries) || [], + [resourceAttributeQueries], + ); + const legend = '{{address}}'; return ( @@ -26,12 +39,16 @@ function External({ getWidget }: ExternalProps): JSX.Element { @@ -45,12 +62,12 @@ function External({ getWidget }: ExternalProps): JSX.Element { @@ -66,12 +83,16 @@ function External({ getWidget }: ExternalProps): JSX.Element { @@ -85,12 +106,16 @@ function External({ getWidget }: ExternalProps): JSX.Element { @@ -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; diff --git a/frontend/src/container/MetricsApplication/index.tsx b/frontend/src/container/MetricsApplication/index.tsx index f6305358b3..49ec6f7b26 100644 --- a/frontend/src/container/MetricsApplication/index.tsx +++ b/frontend/src/container/MetricsApplication/index.tsx @@ -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 ; } @@ -40,7 +62,7 @@ function DbCallTab(): JSX.Element { } function ExternalTab(): JSX.Element { - return ; + return ; } function ServiceMetrics(): JSX.Element { diff --git a/frontend/src/lib/resourceAttributes.ts b/frontend/src/lib/resourceAttributes.ts index 5a1596efda..d00d1b6c19 100644 --- a/frontend/src/lib/resourceAttributes.ts +++ b/frontend/src/lib/resourceAttributes.ts @@ -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(','), + })); +}; diff --git a/frontend/src/types/api/dashboard/getAll.ts b/frontend/src/types/api/dashboard/getAll.ts index 2a2617bb99..8de0978fb0 100644 --- a/frontend/src/types/api/dashboard/getAll.ts +++ b/frontend/src/types/api/dashboard/getAll.ts @@ -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[]; +}