From 6bc2f9125cca5eaefee2950ab11d2b9a4c9b8295 Mon Sep 17 00:00:00 2001 From: rahulkeswani101 Date: Mon, 2 Sep 2024 09:54:49 +0530 Subject: [PATCH 1/7] feat: added view logs button for error and latency chart --- .../MetricsApplication/Tabs/Overview.tsx | 86 +++++++++++++------ .../GraphControlsPanel.styles.scss | 26 ++++++ .../GraphControlsPanel/GraphControlsPanel.tsx | 42 +++++++++ .../Tabs/Overview/ServiceOverview.tsx | 22 +++-- .../container/MetricsApplication/Tabs/util.ts | 53 ++++++++++-- 5 files changed, 187 insertions(+), 42 deletions(-) create mode 100644 frontend/src/container/MetricsApplication/Tabs/Overview/GraphControlsPanel/GraphControlsPanel.styles.scss create mode 100644 frontend/src/container/MetricsApplication/Tabs/Overview/GraphControlsPanel/GraphControlsPanel.tsx diff --git a/frontend/src/container/MetricsApplication/Tabs/Overview.tsx b/frontend/src/container/MetricsApplication/Tabs/Overview.tsx index 241395b23a..25f6f72a55 100644 --- a/frontend/src/container/MetricsApplication/Tabs/Overview.tsx +++ b/frontend/src/container/MetricsApplication/Tabs/Overview.tsx @@ -38,6 +38,7 @@ import { } from '../MetricsPageQueries/OverviewQueries'; import { Col, ColApDexContainer, ColErrorContainer, Row } from '../styles'; import ApDex from './Overview/ApDex'; +import GraphControlsPanel from './Overview/GraphControlsPanel/GraphControlsPanel'; import ServiceOverview from './Overview/ServiceOverview'; import TopLevelOperation from './Overview/TopLevelOperations'; import TopOperation from './Overview/TopOperation'; @@ -48,6 +49,7 @@ import { handleNonInQueryRange, onGraphClickHandler, onViewTracePopupClick, + useGetAPMToLogsQueries, useGetAPMToTracesQueries, } from './util'; @@ -194,33 +196,57 @@ function Application(): JSX.Element { [dispatch, pathname, urlQuery], ); - const onErrorTrackHandler = ( - timestamp: number, - apmToTraceQuery: Query, - ): (() => void) => (): void => { - const currentTime = timestamp; - const tPlusOne = timestamp + 60 * 1000; + const onErrorTrackHandler = useCallback( + ( + timestamp: number, + apmToTraceQuery: Query, + isViewLogsClicked?: boolean, + ): (() => void) => (): void => { + const currentTime = timestamp; + const tPlusOne = timestamp + 60 * 1000; - const urlParams = new URLSearchParams(search); - urlParams.set(QueryParams.startTime, currentTime.toString()); - urlParams.set(QueryParams.endTime, tPlusOne.toString()); + const urlParams = new URLSearchParams(search); + urlParams.set(QueryParams.startTime, currentTime.toString()); + urlParams.set(QueryParams.endTime, tPlusOne.toString()); - const avialableParams = routeConfig[ROUTES.TRACE]; - const queryString = getQueryString(avialableParams, urlParams); + const avialableParams = routeConfig[ROUTES.TRACE]; + const queryString = getQueryString(avialableParams, urlParams); - const JSONCompositeQuery = encodeURIComponent( - JSON.stringify(apmToTraceQuery), - ); + const JSONCompositeQuery = encodeURIComponent( + JSON.stringify(apmToTraceQuery), + ); - const newTraceExplorerPath = `${ - ROUTES.TRACES_EXPLORER - }?${urlParams.toString()}&selected={"serviceName":["${servicename}"]}&filterToFetchData=["duration","status","serviceName"]&spanAggregateCurrentPage=1&selectedTags=${selectedTraceTags}&${ - QueryParams.compositeQuery - }=${JSONCompositeQuery}&${queryString.join('&')}`; + const basePath = isViewLogsClicked + ? ROUTES.LOGS_EXPLORER + : ROUTES.TRACES_EXPLORER; + const newPath = `${basePath}?${urlParams.toString()}&selected={"serviceName":["${servicename}"]}&filterToFetchData=["duration","status","serviceName"]&spanAggregateCurrentPage=1&selectedTags=${selectedTraceTags}&${ + QueryParams.compositeQuery + }=${JSONCompositeQuery}&${queryString.join('&')}`; - history.push(newTraceExplorerPath); - }; + history.push(newPath); + }, + // eslint-disable-next-line react-hooks/exhaustive-deps + [], + ); + const logErrorQuery = useGetAPMToLogsQueries({ + servicename, + filters: [ + { + id: uuid().slice(0, 8), + key: { + key: 'hasError', + dataType: DataTypes.bool, + type: 'tag', + isColumn: true, + isJSON: false, + id: 'hasError--bool--tag--true', + }, + op: '=', + value: ['true'], + }, + ], + }); const errorTrackQuery = useGetAPMToTracesQueries({ servicename, filters: [ @@ -304,14 +330,18 @@ function Application(): JSX.Element { /> - + onViewLogsClick={onErrorTrackHandler( + selectedTimeStamp, + logErrorQuery, + true, + )} + onViewTracesClick={onErrorTrackHandler( + selectedTimeStamp, + errorTrackQuery, + )} + /> void; + onViewTracesClick: () => void; +} + +function GraphControlsPanel({ + id, + onViewLogsClick, + onViewTracesClick, +}: GraphControlsPanelProps): JSX.Element { + return ( +
+ + +
+ ); +} + +export default GraphControlsPanel; diff --git a/frontend/src/container/MetricsApplication/Tabs/Overview/ServiceOverview.tsx b/frontend/src/container/MetricsApplication/Tabs/Overview/ServiceOverview.tsx index 9651e16d3a..0b7d86d660 100644 --- a/frontend/src/container/MetricsApplication/Tabs/Overview/ServiceOverview.tsx +++ b/frontend/src/container/MetricsApplication/Tabs/Overview/ServiceOverview.tsx @@ -19,13 +19,14 @@ import { useParams } from 'react-router-dom'; import { EQueryType } from 'types/common/dashboard'; import { v4 as uuid } from 'uuid'; -import { Button } from '../styles'; import { IServiceName } from '../types'; import { handleNonInQueryRange, onViewTracePopupClick, + useGetAPMToLogsQueries, useGetAPMToTracesQueries, } from '../util'; +import GraphControlsPanel from './GraphControlsPanel/GraphControlsPanel'; function ServiceOverview({ onDragSelect, @@ -75,21 +76,26 @@ function ServiceOverview({ const apmToTraceQuery = useGetAPMToTracesQueries({ servicename }); + const apmToLogQuery = useGetAPMToLogsQueries({ servicename }); + return ( <> - + /> {topLevelOperationsIsLoading && ( diff --git a/frontend/src/container/MetricsApplication/Tabs/util.ts b/frontend/src/container/MetricsApplication/Tabs/util.ts index 6832fe9d02..a9d04d361d 100644 --- a/frontend/src/container/MetricsApplication/Tabs/util.ts +++ b/frontend/src/container/MetricsApplication/Tabs/util.ts @@ -5,6 +5,7 @@ import { routeConfig } from 'container/SideNav/config'; import { getQueryString } from 'container/SideNav/helper'; import { useQueryBuilder } from 'hooks/queryBuilder/useQueryBuilder'; import history from 'lib/history'; +import { prepareQueryWithDefaultTimestamp } from 'pages/LogsExplorer/utils'; import { traceFilterKeys } from 'pages/TracesExplorer/Filter/filterUtils'; import { Dispatch, SetStateAction, useMemo } from 'react'; import { @@ -31,12 +32,14 @@ interface OnViewTracePopupClickProps { selectedTraceTags: string; timestamp: number; apmToTraceQuery: Query; + isViewLogsClicked?: boolean; } export function onViewTracePopupClick({ selectedTraceTags, servicename, timestamp, apmToTraceQuery, + isViewLogsClicked, }: OnViewTracePopupClickProps): VoidFunction { return (): void => { const currentTime = timestamp; @@ -53,13 +56,14 @@ export function onViewTracePopupClick({ JSON.stringify(apmToTraceQuery), ); - const newTraceExplorerPath = `${ - ROUTES.TRACES_EXPLORER - }?${urlParams.toString()}&selected={"serviceName":["${servicename}"]}&filterToFetchData=["duration","status","serviceName"]&spanAggregateCurrentPage=1&selectedTags=${selectedTraceTags}&${ + const basePath = isViewLogsClicked + ? ROUTES.LOGS_EXPLORER + : ROUTES.TRACES_EXPLORER; + const newPath = `${basePath}?${urlParams.toString()}&selected={"serviceName":["${servicename}"]}&filterToFetchData=["duration","status","serviceName"]&spanAggregateCurrentPage=1&selectedTags=${selectedTraceTags}&${ QueryParams.compositeQuery }=${JSONCompositeQuery}&${queryString.join('&')}`; - history.push(newTraceExplorerPath); + history.push(newPath); }; } @@ -79,7 +83,7 @@ export function onGraphClickHandler( if (xValue) { if (buttonElement) { - buttonElement.style.display = 'block'; + buttonElement.style.display = 'flex'; buttonElement.style.left = `${mouseX}px`; buttonElement.style.top = `${mouseY}px`; setSelectedTimeStamp(xValue); @@ -106,12 +110,13 @@ export function handleQueryChange( attributeKeys: BaseAutocompleteData, serviceAttribute: string, filters?: TagFilterItem[], + logs?: boolean, ): Query { const filterItem: TagFilterItem[] = [ { id: uuid().slice(0, 8), key: attributeKeys, - op: 'in', + op: logs ? '=' : 'in', value: serviceAttribute, }, ]; @@ -130,6 +135,42 @@ export function handleQueryChange( }; } +export function useGetAPMToLogsQueries({ + servicename, + filters, +}: { + servicename: string; + filters?: TagFilterItem[]; +}): Query { + const finalFilters: TagFilterItem[] = []; + const { updateAllQueriesOperators } = useQueryBuilder(); + let updatedQuery = updateAllQueriesOperators( + initialQueriesMap.logs, + PANEL_TYPES.LIST, + DataSource.LOGS, + ); + const serviceName = { + id: 'service.name--string--resource--true', + dataType: DataTypes.String, + isColumn: true, + key: 'service.name', + type: 'resource', + isJSON: false, + }; + + if (filters?.length) { + finalFilters.push(...filters); + } + updatedQuery = prepareQueryWithDefaultTimestamp(updatedQuery); + return handleQueryChange( + updatedQuery, + serviceName, + servicename, + finalFilters, + true, + ); +} + export function useGetAPMToTracesQueries({ servicename, isExternalCall, From 6c06fea1aa3736d4634f903ef4db3d575733ac7e Mon Sep 17 00:00:00 2001 From: rahulkeswani101 Date: Mon, 2 Sep 2024 13:43:54 +0530 Subject: [PATCH 2/7] style: remove unused CSS --- .../Overview/GraphControlsPanel/GraphControlsPanel.styles.scss | 1 - frontend/src/container/MetricsApplication/Tabs/util.ts | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/frontend/src/container/MetricsApplication/Tabs/Overview/GraphControlsPanel/GraphControlsPanel.styles.scss b/frontend/src/container/MetricsApplication/Tabs/Overview/GraphControlsPanel/GraphControlsPanel.styles.scss index 9ace0dc0dd..c42014485d 100644 --- a/frontend/src/container/MetricsApplication/Tabs/Overview/GraphControlsPanel/GraphControlsPanel.styles.scss +++ b/frontend/src/container/MetricsApplication/Tabs/Overview/GraphControlsPanel/GraphControlsPanel.styles.scss @@ -2,7 +2,6 @@ position: absolute; z-index: 999; display: none; - flex-direction: column; width: 110px; padding: 5px; border-radius: 5px; diff --git a/frontend/src/container/MetricsApplication/Tabs/util.ts b/frontend/src/container/MetricsApplication/Tabs/util.ts index a9d04d361d..cb771581cd 100644 --- a/frontend/src/container/MetricsApplication/Tabs/util.ts +++ b/frontend/src/container/MetricsApplication/Tabs/util.ts @@ -83,7 +83,7 @@ export function onGraphClickHandler( if (xValue) { if (buttonElement) { - buttonElement.style.display = 'flex'; + buttonElement.style.display = 'block'; buttonElement.style.left = `${mouseX}px`; buttonElement.style.top = `${mouseY}px`; setSelectedTimeStamp(xValue); From ed4613cb1b9c36359a3d557f5f7f61ca7390c43b Mon Sep 17 00:00:00 2001 From: rahulkeswani101 Date: Wed, 4 Sep 2024 15:35:01 +0530 Subject: [PATCH 3/7] feat: added severity text as a filter and removed relative time param from url --- .../container/MetricsApplication/Tabs/Overview.tsx | 12 ++++++------ .../src/container/MetricsApplication/Tabs/util.ts | 1 + 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/frontend/src/container/MetricsApplication/Tabs/Overview.tsx b/frontend/src/container/MetricsApplication/Tabs/Overview.tsx index 25f6f72a55..32a819e375 100644 --- a/frontend/src/container/MetricsApplication/Tabs/Overview.tsx +++ b/frontend/src/container/MetricsApplication/Tabs/Overview.tsx @@ -208,7 +208,7 @@ function Application(): JSX.Element { const urlParams = new URLSearchParams(search); urlParams.set(QueryParams.startTime, currentTime.toString()); urlParams.set(QueryParams.endTime, tPlusOne.toString()); - + urlParams.delete('relativeTime'); const avialableParams = routeConfig[ROUTES.TRACE]; const queryString = getQueryString(avialableParams, urlParams); @@ -235,15 +235,15 @@ function Application(): JSX.Element { { id: uuid().slice(0, 8), key: { - key: 'hasError', - dataType: DataTypes.bool, - type: 'tag', + key: 'severity_text', + dataType: DataTypes.String, + type: '', isColumn: true, isJSON: false, - id: 'hasError--bool--tag--true', + id: 'severity_text--string----true', }, op: '=', - value: ['true'], + value: 'ERROR', }, ], }); diff --git a/frontend/src/container/MetricsApplication/Tabs/util.ts b/frontend/src/container/MetricsApplication/Tabs/util.ts index cb771581cd..6835080349 100644 --- a/frontend/src/container/MetricsApplication/Tabs/util.ts +++ b/frontend/src/container/MetricsApplication/Tabs/util.ts @@ -49,6 +49,7 @@ export function onViewTracePopupClick({ const urlParams = new URLSearchParams(window.location.search); urlParams.set(QueryParams.startTime, currentTime.toString()); urlParams.set(QueryParams.endTime, tPlusOne.toString()); + urlParams.delete('relativeTime'); const avialableParams = routeConfig[ROUTES.TRACE]; const queryString = getQueryString(avialableParams, urlParams); From bfb63ca8c420ac027b3848276a5039bcc2bb227e Mon Sep 17 00:00:00 2001 From: rahulkeswani101 Date: Sun, 8 Sep 2024 22:22:39 +0530 Subject: [PATCH 4/7] fix: custom end time issue while navigating to a different page --- frontend/src/container/MetricsApplication/Tabs/Overview.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/frontend/src/container/MetricsApplication/Tabs/Overview.tsx b/frontend/src/container/MetricsApplication/Tabs/Overview.tsx index 32a819e375..f94d5fc865 100644 --- a/frontend/src/container/MetricsApplication/Tabs/Overview.tsx +++ b/frontend/src/container/MetricsApplication/Tabs/Overview.tsx @@ -203,7 +203,7 @@ function Application(): JSX.Element { isViewLogsClicked?: boolean, ): (() => void) => (): void => { const currentTime = timestamp; - const tPlusOne = timestamp + 60 * 1000; + const tPlusOne = timestamp + 60; const urlParams = new URLSearchParams(search); urlParams.set(QueryParams.startTime, currentTime.toString()); @@ -242,8 +242,8 @@ function Application(): JSX.Element { isJSON: false, id: 'severity_text--string----true', }, - op: '=', - value: 'ERROR', + op: 'in', + value: ['ERROR', 'FATAL'], }, ], }); From 540a2c6712e18cef0cd429d5b4713f33ef94e261 Mon Sep 17 00:00:00 2001 From: rahulkeswani101 Date: Mon, 16 Sep 2024 15:49:55 +0530 Subject: [PATCH 5/7] feat: added all values for severity text when we are navigating from error panel to logs --- frontend/src/container/MetricsApplication/Tabs/Overview.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/src/container/MetricsApplication/Tabs/Overview.tsx b/frontend/src/container/MetricsApplication/Tabs/Overview.tsx index f94d5fc865..5fb101deac 100644 --- a/frontend/src/container/MetricsApplication/Tabs/Overview.tsx +++ b/frontend/src/container/MetricsApplication/Tabs/Overview.tsx @@ -243,7 +243,7 @@ function Application(): JSX.Element { id: 'severity_text--string----true', }, op: 'in', - value: ['ERROR', 'FATAL'], + value: ['ERROR', 'FATAL', 'error', 'fatal'], }, ], }); From f4fbe62169e549b503100c5251580a32e3a9af3e Mon Sep 17 00:00:00 2001 From: rahulkeswani101 Date: Thu, 26 Sep 2024 17:26:14 +0530 Subject: [PATCH 6/7] feat: added new function to decide new path based on button clicked --- .../MetricsApplication/Tabs/Overview.tsx | 17 ++++++---- .../container/MetricsApplication/Tabs/util.ts | 34 +++++++++++++++---- 2 files changed, 37 insertions(+), 14 deletions(-) diff --git a/frontend/src/container/MetricsApplication/Tabs/Overview.tsx b/frontend/src/container/MetricsApplication/Tabs/Overview.tsx index 5fb101deac..a8d40f3dd9 100644 --- a/frontend/src/container/MetricsApplication/Tabs/Overview.tsx +++ b/frontend/src/container/MetricsApplication/Tabs/Overview.tsx @@ -46,6 +46,7 @@ import TopOperationMetrics from './Overview/TopOperationMetrics'; import { Button, Card } from './styles'; import { IServiceName } from './types'; import { + generateExplorerPath, handleNonInQueryRange, onGraphClickHandler, onViewTracePopupClick, @@ -208,7 +209,7 @@ function Application(): JSX.Element { const urlParams = new URLSearchParams(search); urlParams.set(QueryParams.startTime, currentTime.toString()); urlParams.set(QueryParams.endTime, tPlusOne.toString()); - urlParams.delete('relativeTime'); + urlParams.delete(QueryParams.relativeTime); const avialableParams = routeConfig[ROUTES.TRACE]; const queryString = getQueryString(avialableParams, urlParams); @@ -216,12 +217,14 @@ function Application(): JSX.Element { JSON.stringify(apmToTraceQuery), ); - const basePath = isViewLogsClicked - ? ROUTES.LOGS_EXPLORER - : ROUTES.TRACES_EXPLORER; - const newPath = `${basePath}?${urlParams.toString()}&selected={"serviceName":["${servicename}"]}&filterToFetchData=["duration","status","serviceName"]&spanAggregateCurrentPage=1&selectedTags=${selectedTraceTags}&${ - QueryParams.compositeQuery - }=${JSONCompositeQuery}&${queryString.join('&')}`; + const newPath = generateExplorerPath( + isViewLogsClicked, + urlParams, + servicename, + selectedTraceTags, + JSONCompositeQuery, + queryString, + ); history.push(newPath); }, diff --git a/frontend/src/container/MetricsApplication/Tabs/util.ts b/frontend/src/container/MetricsApplication/Tabs/util.ts index d58554e2d7..c13c0857e5 100644 --- a/frontend/src/container/MetricsApplication/Tabs/util.ts +++ b/frontend/src/container/MetricsApplication/Tabs/util.ts @@ -36,6 +36,24 @@ interface OnViewTracePopupClickProps { apmToTraceQuery: Query; isViewLogsClicked?: boolean; } + +export function generateExplorerPath( + isViewLogsClicked: boolean | undefined, + urlParams: URLSearchParams, + servicename: string | undefined, + selectedTraceTags: string, + JSONCompositeQuery: string, + queryString: string[], +): string { + const basePath = isViewLogsClicked + ? ROUTES.LOGS_EXPLORER + : ROUTES.TRACES_EXPLORER; + + return `${basePath}?${urlParams.toString()}&selected={"serviceName":["${servicename}"]}&filterToFetchData=["duration","status","serviceName"]&spanAggregateCurrentPage=1&selectedTags=${selectedTraceTags}&${ + QueryParams.compositeQuery + }=${JSONCompositeQuery}&${queryString.join('&')}`; +} + export function onViewTracePopupClick({ selectedTraceTags, servicename, @@ -51,7 +69,7 @@ export function onViewTracePopupClick({ const urlParams = new URLSearchParams(window.location.search); urlParams.set(QueryParams.startTime, currentTime.toString()); urlParams.set(QueryParams.endTime, tPlusOne.toString()); - urlParams.delete('relativeTime'); + urlParams.delete(QueryParams.relativeTime); const avialableParams = routeConfig[ROUTES.TRACE]; const queryString = getQueryString(avialableParams, urlParams); @@ -59,12 +77,14 @@ export function onViewTracePopupClick({ JSON.stringify(apmToTraceQuery), ); - const basePath = isViewLogsClicked - ? ROUTES.LOGS_EXPLORER - : ROUTES.TRACES_EXPLORER; - const newPath = `${basePath}?${urlParams.toString()}&selected={"serviceName":["${servicename}"]}&filterToFetchData=["duration","status","serviceName"]&spanAggregateCurrentPage=1&selectedTags=${selectedTraceTags}&${ - QueryParams.compositeQuery - }=${JSONCompositeQuery}&${queryString.join('&')}`; + const newPath = generateExplorerPath( + isViewLogsClicked, + urlParams, + servicename, + selectedTraceTags, + JSONCompositeQuery, + queryString, + ); history.push(newPath); }; From 6a4643558caa1e32f62b5f07ccd2efac8c67c7f0 Mon Sep 17 00:00:00 2001 From: rahulkeswani101 Date: Thu, 3 Oct 2024 15:36:17 +0530 Subject: [PATCH 7/7] feat: added step interval instead of tplusone --- .../MetricsApplication/Tabs/DBCall.tsx | 14 +++++++++++++ .../MetricsApplication/Tabs/External.tsx | 15 +++++++++++++ .../MetricsApplication/Tabs/Overview.tsx | 21 ++++++++++++++++--- .../Tabs/Overview/ServiceOverview.tsx | 5 ++++- .../container/MetricsApplication/Tabs/util.ts | 10 +++++---- 5 files changed, 57 insertions(+), 8 deletions(-) diff --git a/frontend/src/container/MetricsApplication/Tabs/DBCall.tsx b/frontend/src/container/MetricsApplication/Tabs/DBCall.tsx index da7bbbfc60..9ce242582b 100644 --- a/frontend/src/container/MetricsApplication/Tabs/DBCall.tsx +++ b/frontend/src/container/MetricsApplication/Tabs/DBCall.tsx @@ -14,10 +14,12 @@ import { resourceAttributesToTagFilterItems, } from 'hooks/useResourceAttribute/utils'; import useUrlQuery from 'hooks/useUrlQuery'; +import getStep from 'lib/getStep'; import history from 'lib/history'; import { useCallback, useEffect, useMemo, useRef, useState } from 'react'; import { useDispatch } from 'react-redux'; import { useLocation, useParams } from 'react-router-dom'; +import store from 'store'; import { UpdateTimeInterval } from 'store/actions'; import { TagFilterItem } from 'types/api/queryBuilder/queryBuilderData'; import { EQueryType } from 'types/common/dashboard'; @@ -123,6 +125,16 @@ function DBCall(): JSX.Element { [servicename, tagFilterItems], ); + const stepInterval = useMemo( + () => + getStep({ + end: store.getState().globalTime.maxTime, + inputFormat: 'ns', + start: store.getState().globalTime.minTime, + }), + [], + ); + const logEventCalledRef = useRef(false); useEffect(() => { @@ -158,6 +170,7 @@ function DBCall(): JSX.Element { selectedTraceTags, timestamp: selectedTimeStamp, apmToTraceQuery, + stepInterval, })} > View Traces @@ -192,6 +205,7 @@ function DBCall(): JSX.Element { selectedTraceTags, timestamp: selectedTimeStamp, apmToTraceQuery, + stepInterval, })} > View Traces diff --git a/frontend/src/container/MetricsApplication/Tabs/External.tsx b/frontend/src/container/MetricsApplication/Tabs/External.tsx index 5ba3d3df6c..328a544472 100644 --- a/frontend/src/container/MetricsApplication/Tabs/External.tsx +++ b/frontend/src/container/MetricsApplication/Tabs/External.tsx @@ -16,10 +16,12 @@ import { resourceAttributesToTagFilterItems, } from 'hooks/useResourceAttribute/utils'; import useUrlQuery from 'hooks/useUrlQuery'; +import getStep from 'lib/getStep'; import history from 'lib/history'; import { useCallback, useEffect, useMemo, useRef, useState } from 'react'; import { useDispatch } from 'react-redux'; import { useLocation, useParams } from 'react-router-dom'; +import store from 'store'; import { UpdateTimeInterval } from 'store/actions'; import { DataTypes } from 'types/api/queryBuilder/queryAutocompleteResponse'; import { EQueryType } from 'types/common/dashboard'; @@ -141,6 +143,15 @@ function External(): JSX.Element { ], }); + const stepInterval = useMemo( + () => + getStep({ + end: store.getState().globalTime.maxTime, + inputFormat: 'ns', + start: store.getState().globalTime.minTime, + }), + [], + ); const logEventCalledRef = useRef(false); useEffect(() => { if (!logEventCalledRef.current) { @@ -222,6 +233,7 @@ function External(): JSX.Element { selectedTraceTags, timestamp: selectedTimeStamp, apmToTraceQuery: errorApmToTraceQuery, + stepInterval, })} > View Traces @@ -257,6 +269,7 @@ function External(): JSX.Element { selectedTraceTags, timestamp: selectedTimeStamp, apmToTraceQuery, + stepInterval, })} > View Traces @@ -295,6 +308,7 @@ function External(): JSX.Element { selectedTraceTags, timestamp: selectedTimeStamp, apmToTraceQuery, + stepInterval, })} > View Traces @@ -330,6 +344,7 @@ function External(): JSX.Element { selectedTraceTags, timestamp: selectedTimeStamp, apmToTraceQuery, + stepInterval, })} > View Traces diff --git a/frontend/src/container/MetricsApplication/Tabs/Overview.tsx b/frontend/src/container/MetricsApplication/Tabs/Overview.tsx index a8d40f3dd9..77bf86b80f 100644 --- a/frontend/src/container/MetricsApplication/Tabs/Overview.tsx +++ b/frontend/src/container/MetricsApplication/Tabs/Overview.tsx @@ -15,6 +15,7 @@ import { resourceAttributesToTagFilterItems, } from 'hooks/useResourceAttribute/utils'; import useUrlQuery from 'hooks/useUrlQuery'; +import getStep from 'lib/getStep'; import history from 'lib/history'; import { OnClickPluginOpts } from 'lib/uPlotLib/plugins/onClickPlugin'; import { defaultTo } from 'lodash-es'; @@ -180,6 +181,16 @@ function Application(): JSX.Element { id: SERVICE_CHART_ID.errorPercentage, }); + const stepInterval = useMemo( + () => + getStep({ + end: maxTime, + inputFormat: 'ns', + start: minTime, + }), + [maxTime, minTime], + ); + const onDragSelect = useCallback( (start: number, end: number) => { const startTimestamp = Math.trunc(start); @@ -204,11 +215,12 @@ function Application(): JSX.Element { isViewLogsClicked?: boolean, ): (() => void) => (): void => { const currentTime = timestamp; - const tPlusOne = timestamp + 60; + const endTime = timestamp + stepInterval; + console.log(endTime, stepInterval); const urlParams = new URLSearchParams(search); urlParams.set(QueryParams.startTime, currentTime.toString()); - urlParams.set(QueryParams.endTime, tPlusOne.toString()); + urlParams.set(QueryParams.endTime, endTime.toString()); urlParams.delete(QueryParams.relativeTime); const avialableParams = routeConfig[ROUTES.TRACE]; const queryString = getQueryString(avialableParams, urlParams); @@ -229,7 +241,7 @@ function Application(): JSX.Element { history.push(newPath); }, // eslint-disable-next-line react-hooks/exhaustive-deps - [], + [stepInterval], ); const logErrorQuery = useGetAPMToLogsQueries({ @@ -280,6 +292,7 @@ function Application(): JSX.Element { selectedTraceTags={selectedTraceTags} topLevelOperationsRoute={topLevelOperationsRoute} topLevelOperationsIsLoading={topLevelOperationsIsLoading} + stepInterval={stepInterval} /> @@ -293,6 +306,7 @@ function Application(): JSX.Element { selectedTraceTags, timestamp: selectedTimeStamp, apmToTraceQuery, + stepInterval, })} > View Traces @@ -321,6 +335,7 @@ function Application(): JSX.Element { selectedTraceTags, timestamp: selectedTimeStamp, apmToTraceQuery, + stepInterval, })} > View Traces diff --git a/frontend/src/container/MetricsApplication/Tabs/Overview/ServiceOverview.tsx b/frontend/src/container/MetricsApplication/Tabs/Overview/ServiceOverview.tsx index 0b7d86d660..24e2233244 100644 --- a/frontend/src/container/MetricsApplication/Tabs/Overview/ServiceOverview.tsx +++ b/frontend/src/container/MetricsApplication/Tabs/Overview/ServiceOverview.tsx @@ -35,6 +35,7 @@ function ServiceOverview({ selectedTimeStamp, topLevelOperationsRoute, topLevelOperationsIsLoading, + stepInterval, }: ServiceOverviewProps): JSX.Element { const { servicename: encodedServiceName } = useParams(); const servicename = decodeURIComponent(encodedServiceName); @@ -88,12 +89,14 @@ function ServiceOverview({ timestamp: selectedTimeStamp, apmToTraceQuery: apmToLogQuery, isViewLogsClicked: true, + stepInterval, })} onViewTracesClick={onViewTracePopupClick({ servicename, selectedTraceTags, timestamp: selectedTimeStamp, apmToTraceQuery, + stepInterval, })} /> @@ -120,8 +123,8 @@ function ServiceOverview({ ); } - interface ServiceOverviewProps { + stepInterval: number; selectedTimeStamp: number; selectedTraceTags: string; onDragSelect: (start: number, end: number) => void; diff --git a/frontend/src/container/MetricsApplication/Tabs/util.ts b/frontend/src/container/MetricsApplication/Tabs/util.ts index c13c0857e5..e6d58831a0 100644 --- a/frontend/src/container/MetricsApplication/Tabs/util.ts +++ b/frontend/src/container/MetricsApplication/Tabs/util.ts @@ -35,6 +35,7 @@ interface OnViewTracePopupClickProps { timestamp: number; apmToTraceQuery: Query; isViewLogsClicked?: boolean; + stepInterval?: number; } export function generateExplorerPath( @@ -54,21 +55,22 @@ export function generateExplorerPath( }=${JSONCompositeQuery}&${queryString.join('&')}`; } +// TODO(@rahul-signoz): update the name of this function once we have view logs button in every panel export function onViewTracePopupClick({ selectedTraceTags, servicename, timestamp, apmToTraceQuery, isViewLogsClicked, + stepInterval, }: OnViewTracePopupClickProps): VoidFunction { return (): void => { const currentTime = timestamp; - - const tPlusOne = timestamp + 60; + const endTime = timestamp + (stepInterval || 60); const urlParams = new URLSearchParams(window.location.search); urlParams.set(QueryParams.startTime, currentTime.toString()); - urlParams.set(QueryParams.endTime, tPlusOne.toString()); + urlParams.set(QueryParams.endTime, endTime.toString()); urlParams.delete(QueryParams.relativeTime); const avialableParams = routeConfig[ROUTES.TRACE]; const queryString = getQueryString(avialableParams, urlParams); @@ -175,7 +177,7 @@ export function useGetAPMToLogsQueries({ const serviceName = { id: 'service.name--string--resource--true', dataType: DataTypes.String, - isColumn: true, + isColumn: false, key: 'service.name', type: 'resource', isJSON: false,