From 99ed314fc9b7fa4b8ce5406c85bdef30cfbed0ae Mon Sep 17 00:00:00 2001 From: Palash Gupta Date: Wed, 29 Mar 2023 14:45:58 +0530 Subject: [PATCH] feat: resource attribute is added in the exception (#2491) * feat: resource attribute is added in the exception * fix: build is fixed * chore: methods is updated to post * fix: build is fixed * fix: listErrors, countErrors API request body * chore: type of the function is updated * chore: convertRawQueriesToTraceSelectedTags is updated * fix: resource attribute is updated * chore: selected tags is updated * feat: key is updated --------- Co-authored-by: Vishal Sharma --- frontend/src/AppRoutes/index.tsx | 45 ++-- frontend/src/api/errors/getAll.ts | 17 +- frontend/src/api/errors/getErrorCounts.ts | 13 +- frontend/src/api/trace/getSpans.ts | 2 +- frontend/src/api/trace/getSpansAggregate.ts | 2 +- frontend/src/container/AllError/index.tsx | 9 +- .../ResourceAttributesFilter/QueryChip.tsx | 32 --- .../ResourceAttributesFilter.Machine.ts | 61 ----- ...esourceAttributesFilter.Machine.typegen.ts | 32 --- .../ResourceAttributesFilter/index.tsx | 219 ------------------ .../ResourceAttributesFilter/types.ts | 11 - .../ResourceAttributesFilter/utils.ts | 64 ----- .../MetricsApplication/Tabs/DBCall.tsx | 21 +- .../MetricsApplication/Tabs/External.tsx | 21 +- .../MetricsApplication/Tabs/Overview.tsx | 27 +-- .../MetricsApplication/TopOperationsTable.tsx | 10 +- .../container/MetricsApplication/index.tsx | 2 +- .../MetricTagKey.machine.typegen.ts | 30 +-- .../ResourceAttributesFilter.tsx | 77 ++++++ .../components/QueryChip/QueryChip.tsx | 23 ++ .../components/QueryChip/index.ts | 3 + .../components/QueryChip/types.ts | 6 + .../ResourceAttributesFilter/index.ts | 3 + .../ResourceAttributesFilter/styles.ts | 6 +- frontend/src/container/SideNav/index.tsx | 9 +- .../useResourceAttribute/ResourceProvider.tsx | 181 +++++++++++++++ .../src/hooks/useResourceAttribute/context.ts | 7 + .../src/hooks/useResourceAttribute/index.ts | 7 + .../src/hooks/useResourceAttribute/machine.ts | 61 +++++ .../useResourceAttribute/machine.typegen.ts | 37 +++ .../src/hooks/useResourceAttribute/types.ts | 32 +++ .../useResourceAttribute.tsx | 9 + .../src/hooks/useResourceAttribute/utils.ts | 161 +++++++++++++ frontend/src/lib/resourceAttributes.ts | 76 ------ frontend/src/pages/AllErrors/index.tsx | 28 ++- .../src/pages/MetricApplication/index.tsx | 14 +- frontend/src/pages/Metrics/index.tsx | 23 +- .../metrics/setResourceAttributeQueries.ts | 55 ----- frontend/src/store/reducers/metric.ts | 16 -- frontend/src/types/actions/metrics.ts | 17 +- frontend/src/types/api/errors/getAll.ts | 2 + .../src/types/api/errors/getErrorCounts.ts | 2 + frontend/src/types/reducer/metrics.ts | 3 - 43 files changed, 754 insertions(+), 722 deletions(-) delete mode 100644 frontend/src/container/MetricsApplication/ResourceAttributesFilter/QueryChip.tsx delete mode 100644 frontend/src/container/MetricsApplication/ResourceAttributesFilter/ResourceAttributesFilter.Machine.ts delete mode 100644 frontend/src/container/MetricsApplication/ResourceAttributesFilter/ResourceAttributesFilter.Machine.typegen.ts delete mode 100644 frontend/src/container/MetricsApplication/ResourceAttributesFilter/index.tsx delete mode 100644 frontend/src/container/MetricsApplication/ResourceAttributesFilter/types.ts delete mode 100644 frontend/src/container/MetricsApplication/ResourceAttributesFilter/utils.ts create mode 100644 frontend/src/container/ResourceAttributesFilter/ResourceAttributesFilter.tsx create mode 100644 frontend/src/container/ResourceAttributesFilter/components/QueryChip/QueryChip.tsx create mode 100644 frontend/src/container/ResourceAttributesFilter/components/QueryChip/index.ts create mode 100644 frontend/src/container/ResourceAttributesFilter/components/QueryChip/types.ts create mode 100644 frontend/src/container/ResourceAttributesFilter/index.ts rename frontend/src/container/{MetricsApplication => }/ResourceAttributesFilter/styles.ts (77%) create mode 100644 frontend/src/hooks/useResourceAttribute/ResourceProvider.tsx create mode 100644 frontend/src/hooks/useResourceAttribute/context.ts create mode 100644 frontend/src/hooks/useResourceAttribute/index.ts create mode 100644 frontend/src/hooks/useResourceAttribute/machine.ts create mode 100644 frontend/src/hooks/useResourceAttribute/machine.typegen.ts create mode 100644 frontend/src/hooks/useResourceAttribute/types.ts create mode 100644 frontend/src/hooks/useResourceAttribute/useResourceAttribute.tsx create mode 100644 frontend/src/hooks/useResourceAttribute/utils.ts delete mode 100644 frontend/src/lib/resourceAttributes.ts delete mode 100644 frontend/src/store/actions/metrics/setResourceAttributeQueries.ts diff --git a/frontend/src/AppRoutes/index.tsx b/frontend/src/AppRoutes/index.tsx index 832e557e49..edfe843882 100644 --- a/frontend/src/AppRoutes/index.tsx +++ b/frontend/src/AppRoutes/index.tsx @@ -4,6 +4,7 @@ import Spinner from 'components/Spinner'; import AppLayout from 'container/AppLayout'; import { useThemeConfig } from 'hooks/useDarkMode'; import { NotificationProvider } from 'hooks/useNotifications'; +import { ResourceProvider } from 'hooks/useResourceAttribute'; import history from 'lib/history'; import { QueryBuilderProvider } from 'providers/QueryBuilder'; import React, { Suspense } from 'react'; @@ -17,30 +18,32 @@ function App(): JSX.Element { return ( - - + + - - - }> - - {routes.map(({ path, component, exact }) => ( - - ))} + + + + }> + + {routes.map(({ path, component, exact }) => ( + + ))} - - - - - + + + + + + - - + + ); } diff --git a/frontend/src/api/errors/getAll.ts b/frontend/src/api/errors/getAll.ts index 7014e52a56..8d6793ee87 100644 --- a/frontend/src/api/errors/getAll.ts +++ b/frontend/src/api/errors/getAll.ts @@ -1,7 +1,6 @@ import axios from 'api'; import { ErrorResponseHandler } from 'api/ErrorResponseHandler'; import { AxiosError } from 'axios'; -import createQueryParams from 'lib/createQueryParams'; import { ErrorResponse, SuccessResponse } from 'types/api'; import { PayloadProps, Props } from 'types/api/errors/getAll'; @@ -9,11 +8,17 @@ const getAll = async ( props: Props, ): Promise | ErrorResponse> => { try { - const response = await axios.get( - `/listErrors?${createQueryParams({ - ...props, - })}`, - ); + const response = await axios.post(`/listErrors`, { + start: `${props.start}`, + end: `${props.end}`, + order: props.order, + orderParam: props.orderParam, + limit: props.limit, + offset: props.offset, + exceptionType: props.exceptionType, + serviceName: props.serviceName, + tags: props.tags, + }); return { statusCode: 200, diff --git a/frontend/src/api/errors/getErrorCounts.ts b/frontend/src/api/errors/getErrorCounts.ts index 4992a6d391..977eeb226f 100644 --- a/frontend/src/api/errors/getErrorCounts.ts +++ b/frontend/src/api/errors/getErrorCounts.ts @@ -1,7 +1,6 @@ import axios from 'api'; import { ErrorResponseHandler } from 'api/ErrorResponseHandler'; import { AxiosError } from 'axios'; -import createQueryParams from 'lib/createQueryParams'; import { ErrorResponse, SuccessResponse } from 'types/api'; import { PayloadProps, Props } from 'types/api/errors/getErrorCounts'; @@ -9,11 +8,13 @@ const getErrorCounts = async ( props: Props, ): Promise | ErrorResponse> => { try { - const response = await axios.get( - `/countErrors?${createQueryParams({ - ...props, - })}`, - ); + const response = await axios.post(`/countErrors`, { + start: `${props.start}`, + end: `${props.end}`, + exceptionType: props.exceptionType, + serviceName: props.serviceName, + tags: props.tags, + }); return { statusCode: 200, diff --git a/frontend/src/api/trace/getSpans.ts b/frontend/src/api/trace/getSpans.ts index 8b56caa46d..261b2652c6 100644 --- a/frontend/src/api/trace/getSpans.ts +++ b/frontend/src/api/trace/getSpans.ts @@ -10,7 +10,7 @@ const getSpans = async ( ): Promise | ErrorResponse> => { try { const updatedSelectedTags = props.selectedTags.map((e) => ({ - Key: e.Key, + Key: `${e.Key}.(string)`, Operator: e.Operator, StringValues: e.StringValues, NumberValues: e.NumberValues, diff --git a/frontend/src/api/trace/getSpansAggregate.ts b/frontend/src/api/trace/getSpansAggregate.ts index cfa1f7e31f..7f245605fc 100644 --- a/frontend/src/api/trace/getSpansAggregate.ts +++ b/frontend/src/api/trace/getSpansAggregate.ts @@ -28,7 +28,7 @@ const getSpanAggregate = async ( }); const updatedSelectedTags = props.selectedTags.map((e) => ({ - Key: e.Key, + Key: `${e.Key}.(string)`, Operator: e.Operator, StringValues: e.StringValues, NumberValues: e.NumberValues, diff --git a/frontend/src/container/AllError/index.tsx b/frontend/src/container/AllError/index.tsx index 64d83e70ec..c3b0580f44 100644 --- a/frontend/src/container/AllError/index.tsx +++ b/frontend/src/container/AllError/index.tsx @@ -18,6 +18,8 @@ import { ResizeTable } from 'components/ResizeTable'; import ROUTES from 'constants/routes'; import dayjs from 'dayjs'; import { useNotifications } from 'hooks/useNotifications'; +import useResourceAttribute from 'hooks/useResourceAttribute'; +import { convertRawQueriesToTraceSelectedTags } from 'hooks/useResourceAttribute/utils'; import useUrlQuery from 'hooks/useUrlQuery'; import createQueryParams from 'lib/createQueryParams'; import history from 'lib/history'; @@ -93,9 +95,11 @@ function AllErrors(): JSX.Element { ], ); + const { queries } = useResourceAttribute(); + const [{ isLoading, data }, errorCountResponse] = useQueries([ { - queryKey: ['getAllErrors', updatedPath, maxTime, minTime], + queryKey: ['getAllErrors', updatedPath, maxTime, minTime, queries], queryFn: (): Promise | ErrorResponse> => getAll({ end: maxTime, @@ -106,6 +110,7 @@ function AllErrors(): JSX.Element { orderParam: getUpdatedParams, exceptionType: getUpdatedExceptionType, serviceName: getUpdatedServiceName, + tags: convertRawQueriesToTraceSelectedTags(queries), }), enabled: !loading, }, @@ -116,6 +121,7 @@ function AllErrors(): JSX.Element { minTime, getUpdatedExceptionType, getUpdatedServiceName, + queries, ], queryFn: (): Promise> => getErrorCounts({ @@ -123,6 +129,7 @@ function AllErrors(): JSX.Element { start: minTime, exceptionType: getUpdatedExceptionType, serviceName: getUpdatedServiceName, + tags: convertRawQueriesToTraceSelectedTags(queries), }), enabled: !loading, }, diff --git a/frontend/src/container/MetricsApplication/ResourceAttributesFilter/QueryChip.tsx b/frontend/src/container/MetricsApplication/ResourceAttributesFilter/QueryChip.tsx deleted file mode 100644 index 09c5d27471..0000000000 --- a/frontend/src/container/MetricsApplication/ResourceAttributesFilter/QueryChip.tsx +++ /dev/null @@ -1,32 +0,0 @@ -import { convertMetricKeyToTrace } from 'lib/resourceAttributes'; -import React from 'react'; - -import { QueryChipContainer, QueryChipItem } from './styles'; -import { IResourceAttributeQuery } from './types'; - -interface IQueryChipProps { - queryData: IResourceAttributeQuery; - onClose: (id: string) => void; - disabled: boolean; -} - -export default function QueryChip({ - queryData, - onClose, - disabled, -}: IQueryChipProps): JSX.Element { - return ( - - {convertMetricKeyToTrace(queryData.tagKey)} - {queryData.operator} - { - if (!disabled) onClose(queryData.id); - }} - > - {queryData.tagValue.join(', ')} - - - ); -} diff --git a/frontend/src/container/MetricsApplication/ResourceAttributesFilter/ResourceAttributesFilter.Machine.ts b/frontend/src/container/MetricsApplication/ResourceAttributesFilter/ResourceAttributesFilter.Machine.ts deleted file mode 100644 index 3b9078f76b..0000000000 --- a/frontend/src/container/MetricsApplication/ResourceAttributesFilter/ResourceAttributesFilter.Machine.ts +++ /dev/null @@ -1,61 +0,0 @@ -import { createMachine } from 'xstate'; - -export const ResourceAttributesFilterMachine = - /** @xstate-layout N4IgpgJg5mDOIC5QBECGsAWAjA9qgThAAQDKYBAxhkQIIB2xAYgJYA2ALmPgHQAqqUANJgAngGIAcgFEAGr0SgADjljN2zHHQUgAHogAcAFgAM3AOz6ATAEYAzJdsA2Y4cOWAnABoQIxAFpDR2tuQ319AFYTcKdbFycAX3jvNExcAmIySmp6JjZOHn4hUTFNACFWAFd8bWVVdU1tPQQzY1MXY2tDdzNHM3dHd0NvXwR7biMTa313S0i+63DE5PRsPEJScnwqWgYiFg4uPgFhcQAlKRIpeSQQWrUNLRumx3Czbg8TR0sbS31jfUcw38fW47gBHmm4XCVms3SWIBSq3SGyyO1yBx4AHlFFxUOwcPhJLJrkoVPcGk9ENYFuF3i5YR0wtEHECEAEgiEmV8zH1DLYzHZ4Yi0utMltsrt9vluNjcfjCWVKtUbnd6o9QE1rMYBtxbGFvsZ3NrZj1WdYOfotUZLX0XEFHEKViKMpttjk9nlDrL8HiCWJzpcSbcyWrGoh3NCQj0zK53P1ph1WeFLLqnJZ2s5vmZLA6kginWsXaj3VLDoUAGqoSpgEp0cpVGohh5hhDWDy0sz8zruakzamWVm-Qyg362V5-AZOayO1KFlHitEejFHKCV6v+i5XRt1ZuU1s52zjNOOaZfdOWIY+RDZ0Hc6ZmKEXqyLPPCudit2Sz08ACSEFYNbSHI27kuquiIOEjiONwjJgrM3RWJYZisgEIJgnYPTmuEdi2OaiR5nQOAQHA2hvsiH4Sui0qFCcIGhnuLSmP0YJuJ2xjJsmKELG8XZTK0tjdHG06vgW5GupRS7St6vrKqSO4UhqVL8TBWp8o4eqdl0A5Xmy3G6gK56-B4uERDOSKiuJi6lgUAhrhUYB0buimtrEKZBDYrxaS0OZca8+ltheybOI4hivGZzrzp+VGHH+AGOQp4EIHy+ghNYnawtG4TsbYvk8QKfHGAJfQ9uF76WSW37xWBTSGJ0qXpd0vRZdEKGPqC2YeO2-zfO4+HxEAA */ - createMachine({ - tsTypes: {} as import('./ResourceAttributesFilter.Machine.typegen').Typegen0, - initial: 'Idle', - states: { - TagKey: { - on: { - NEXT: { - actions: 'onSelectOperator', - target: 'Operator', - }, - onBlur: { - actions: 'onBlurPurge', - target: 'Idle', - }, - RESET: { - target: 'Idle', - }, - }, - }, - Operator: { - on: { - NEXT: { - actions: 'onSelectTagValue', - target: 'TagValue', - }, - onBlur: { - actions: 'onBlurPurge', - target: 'Idle', - }, - RESET: { - target: 'Idle', - }, - }, - }, - TagValue: { - on: { - onBlur: { - actions: ['onValidateQuery', 'onBlurPurge'], - target: 'Idle', - }, - RESET: { - target: 'Idle', - }, - }, - }, - Idle: { - on: { - NEXT: { - actions: 'onSelectTagKey', - description: 'Select Category', - target: 'TagKey', - }, - }, - }, - }, - id: 'Dashboard Search And Filter', - }); diff --git a/frontend/src/container/MetricsApplication/ResourceAttributesFilter/ResourceAttributesFilter.Machine.typegen.ts b/frontend/src/container/MetricsApplication/ResourceAttributesFilter/ResourceAttributesFilter.Machine.typegen.ts deleted file mode 100644 index e7f7ee3de7..0000000000 --- a/frontend/src/container/MetricsApplication/ResourceAttributesFilter/ResourceAttributesFilter.Machine.typegen.ts +++ /dev/null @@ -1,32 +0,0 @@ -// This file was automatically generated. Edits will be overwritten - -export interface Typegen0 { - '@@xstate/typegen': true; - eventsCausingActions: { - onSelectOperator: 'NEXT'; - onBlurPurge: 'onBlur'; - onSelectTagValue: 'NEXT'; - onValidateQuery: 'onBlur'; - onSelectTagKey: 'NEXT'; - }; - internalEvents: { - 'xstate.init': { type: 'xstate.init' }; - }; - invokeSrcNameMap: {}; - missingImplementations: { - actions: - | 'onSelectOperator' - | 'onBlurPurge' - | 'onSelectTagValue' - | 'onValidateQuery' - | 'onSelectTagKey'; - services: never; - guards: never; - delays: never; - }; - eventsCausingServices: {}; - eventsCausingGuards: {}; - eventsCausingDelays: {}; - matchesStates: 'TagKey' | 'Operator' | 'TagValue' | 'Idle'; - tags: never; -} diff --git a/frontend/src/container/MetricsApplication/ResourceAttributesFilter/index.tsx b/frontend/src/container/MetricsApplication/ResourceAttributesFilter/index.tsx deleted file mode 100644 index b8bed255f7..0000000000 --- a/frontend/src/container/MetricsApplication/ResourceAttributesFilter/index.tsx +++ /dev/null @@ -1,219 +0,0 @@ -import { CloseCircleFilled } from '@ant-design/icons'; -import { useMachine } from '@xstate/react'; -import { Button, Select, Spin } from 'antd'; -import ROUTES from 'constants/routes'; -import history from 'lib/history'; -import { convertMetricKeyToTrace } from 'lib/resourceAttributes'; -import { map } from 'lodash-es'; -import React, { useEffect, useState } from 'react'; -import { useDispatch, useSelector } from 'react-redux'; -import { ResetInitialData } from 'store/actions/metrics/resetInitialData'; -import { SetResourceAttributeQueries } from 'store/actions/metrics/setResourceAttributeQueries'; -import { AppState } from 'store/reducers'; -import MetricReducer from 'types/reducer/metrics'; -import { v4 as uuid } from 'uuid'; - -import QueryChip from './QueryChip'; -import { ResourceAttributesFilterMachine } from './ResourceAttributesFilter.Machine'; -import { QueryChipItem, SearchContainer } from './styles'; -import { IOption, IResourceAttributeQuery } from './types'; -import { createQuery, GetTagKeys, GetTagValues, OperatorSchema } from './utils'; - -function ResourceAttributesFilter(): JSX.Element | null { - const dispatch = useDispatch(); - const [disabled, setDisabled] = useState( - !(history.location.pathname === ROUTES.APPLICATION), - ); - - useEffect(() => { - const unListen = history.listen(({ pathname }) => { - setDisabled(!(pathname === ROUTES.APPLICATION)); - }); - return (): void => { - if (!history.location.pathname.startsWith(`${ROUTES.APPLICATION}/`)) { - dispatch(ResetInitialData()); - } - unListen(); - }; - }, [dispatch]); - - const { resourceAttributeQueries } = useSelector( - (state) => state.metrics, - ); - const [loading, setLoading] = useState(true); - const [selectedValues, setSelectedValues] = useState([]); - const [staging, setStaging] = useState([]); - const [queries, setQueries] = useState([]); - const [optionsData, setOptionsData] = useState<{ - mode: undefined | 'tags' | 'multiple'; - options: IOption[]; - }>({ - mode: undefined, - options: [], - }); - - const dispatchQueries = (updatedQueries: IResourceAttributeQuery[]): void => { - dispatch(SetResourceAttributeQueries(updatedQueries)); - }; - const handleLoading = (isLoading: boolean): void => { - setLoading(isLoading); - if (isLoading) { - setOptionsData({ mode: undefined, options: [] }); - } - }; - const [state, send] = useMachine(ResourceAttributesFilterMachine, { - actions: { - onSelectTagKey: () => { - handleLoading(true); - GetTagKeys() - .then((tagKeys) => setOptionsData({ options: tagKeys, mode: undefined })) - .finally(() => { - handleLoading(false); - }); - }, - onSelectOperator: () => { - setOptionsData({ options: OperatorSchema, mode: undefined }); - }, - onSelectTagValue: () => { - handleLoading(true); - - GetTagValues(staging[0]) - .then((tagValuesOptions) => - setOptionsData({ options: tagValuesOptions, mode: 'multiple' }), - ) - .finally(() => { - handleLoading(false); - }); - }, - onBlurPurge: () => { - setSelectedValues([]); - setStaging([]); - }, - onValidateQuery: (): void => { - if (staging.length < 2 || selectedValues.length === 0) { - return; - } - - const generatedQuery = createQuery([...staging, selectedValues]); - if (generatedQuery) { - dispatchQueries([...queries, generatedQuery]); - } - }, - }, - }); - - useEffect(() => { - setQueries(resourceAttributeQueries); - }, [resourceAttributeQueries]); - - const handleFocus = (): void => { - if (state.value === 'Idle') { - send('NEXT'); - } - }; - - const handleBlur = (): void => { - send('onBlur'); - }; - const handleChange = (value: never): void => { - if (!optionsData.mode) { - setStaging((prevStaging) => [...prevStaging, value]); - setSelectedValues([]); - send('NEXT'); - return; - } - - setSelectedValues([...value]); - }; - - const handleClose = (id: string): void => { - dispatchQueries(queries.filter((queryData) => queryData.id !== id)); - }; - - const handleClearAll = (): void => { - send('RESET'); - dispatchQueries([]); - setStaging([]); - setSelectedValues([]); - }; - const disabledAndEmpty = !!( - !queries.length && - !staging.length && - !selectedValues.length && - disabled - ); - const disabledOrEmpty = !!( - queries.length || - staging.length || - selectedValues.length || - disabled - ); - - if (disabledAndEmpty) { - return null; - } - - return ( - -
- {map( - queries, - (query): JSX.Element => ( - - ), - )} - {map(staging, (item, idx) => ( - - {idx === 0 ? convertMetricKeyToTrace(item) : item} - - ))} -
- {!disabled && ( - + Loading...{' '} + + ) : ( + + No resource attributes available to filter. Please refer docs to send + attributes. + + ) + } + /> + + {queries.length || staging.length || selectedQuery.length ? ( +