mirror of
https://git.mirrors.martin98.com/https://github.com/SigNoz/signoz
synced 2025-07-28 05:01:57 +08:00
Merge pull request #5826 from SigNoz/SIG-5729
feat: added view logs button for error and latency chart
This commit is contained in:
commit
69aab87d72
@ -14,10 +14,12 @@ import {
|
|||||||
resourceAttributesToTagFilterItems,
|
resourceAttributesToTagFilterItems,
|
||||||
} from 'hooks/useResourceAttribute/utils';
|
} from 'hooks/useResourceAttribute/utils';
|
||||||
import useUrlQuery from 'hooks/useUrlQuery';
|
import useUrlQuery from 'hooks/useUrlQuery';
|
||||||
|
import getStep from 'lib/getStep';
|
||||||
import history from 'lib/history';
|
import history from 'lib/history';
|
||||||
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
||||||
import { useDispatch } from 'react-redux';
|
import { useDispatch } from 'react-redux';
|
||||||
import { useLocation, useParams } from 'react-router-dom';
|
import { useLocation, useParams } from 'react-router-dom';
|
||||||
|
import store from 'store';
|
||||||
import { UpdateTimeInterval } from 'store/actions';
|
import { UpdateTimeInterval } from 'store/actions';
|
||||||
import { TagFilterItem } from 'types/api/queryBuilder/queryBuilderData';
|
import { TagFilterItem } from 'types/api/queryBuilder/queryBuilderData';
|
||||||
import { EQueryType } from 'types/common/dashboard';
|
import { EQueryType } from 'types/common/dashboard';
|
||||||
@ -123,6 +125,16 @@ function DBCall(): JSX.Element {
|
|||||||
[servicename, tagFilterItems],
|
[servicename, tagFilterItems],
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const stepInterval = useMemo(
|
||||||
|
() =>
|
||||||
|
getStep({
|
||||||
|
end: store.getState().globalTime.maxTime,
|
||||||
|
inputFormat: 'ns',
|
||||||
|
start: store.getState().globalTime.minTime,
|
||||||
|
}),
|
||||||
|
[],
|
||||||
|
);
|
||||||
|
|
||||||
const logEventCalledRef = useRef(false);
|
const logEventCalledRef = useRef(false);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@ -158,6 +170,7 @@ function DBCall(): JSX.Element {
|
|||||||
selectedTraceTags,
|
selectedTraceTags,
|
||||||
timestamp: selectedTimeStamp,
|
timestamp: selectedTimeStamp,
|
||||||
apmToTraceQuery,
|
apmToTraceQuery,
|
||||||
|
stepInterval,
|
||||||
})}
|
})}
|
||||||
>
|
>
|
||||||
View Traces
|
View Traces
|
||||||
@ -192,6 +205,7 @@ function DBCall(): JSX.Element {
|
|||||||
selectedTraceTags,
|
selectedTraceTags,
|
||||||
timestamp: selectedTimeStamp,
|
timestamp: selectedTimeStamp,
|
||||||
apmToTraceQuery,
|
apmToTraceQuery,
|
||||||
|
stepInterval,
|
||||||
})}
|
})}
|
||||||
>
|
>
|
||||||
View Traces
|
View Traces
|
||||||
|
@ -16,10 +16,12 @@ import {
|
|||||||
resourceAttributesToTagFilterItems,
|
resourceAttributesToTagFilterItems,
|
||||||
} from 'hooks/useResourceAttribute/utils';
|
} from 'hooks/useResourceAttribute/utils';
|
||||||
import useUrlQuery from 'hooks/useUrlQuery';
|
import useUrlQuery from 'hooks/useUrlQuery';
|
||||||
|
import getStep from 'lib/getStep';
|
||||||
import history from 'lib/history';
|
import history from 'lib/history';
|
||||||
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
||||||
import { useDispatch } from 'react-redux';
|
import { useDispatch } from 'react-redux';
|
||||||
import { useLocation, useParams } from 'react-router-dom';
|
import { useLocation, useParams } from 'react-router-dom';
|
||||||
|
import store from 'store';
|
||||||
import { UpdateTimeInterval } from 'store/actions';
|
import { UpdateTimeInterval } from 'store/actions';
|
||||||
import { DataTypes } from 'types/api/queryBuilder/queryAutocompleteResponse';
|
import { DataTypes } from 'types/api/queryBuilder/queryAutocompleteResponse';
|
||||||
import { EQueryType } from 'types/common/dashboard';
|
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);
|
const logEventCalledRef = useRef(false);
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!logEventCalledRef.current) {
|
if (!logEventCalledRef.current) {
|
||||||
@ -222,6 +233,7 @@ function External(): JSX.Element {
|
|||||||
selectedTraceTags,
|
selectedTraceTags,
|
||||||
timestamp: selectedTimeStamp,
|
timestamp: selectedTimeStamp,
|
||||||
apmToTraceQuery: errorApmToTraceQuery,
|
apmToTraceQuery: errorApmToTraceQuery,
|
||||||
|
stepInterval,
|
||||||
})}
|
})}
|
||||||
>
|
>
|
||||||
View Traces
|
View Traces
|
||||||
@ -257,6 +269,7 @@ function External(): JSX.Element {
|
|||||||
selectedTraceTags,
|
selectedTraceTags,
|
||||||
timestamp: selectedTimeStamp,
|
timestamp: selectedTimeStamp,
|
||||||
apmToTraceQuery,
|
apmToTraceQuery,
|
||||||
|
stepInterval,
|
||||||
})}
|
})}
|
||||||
>
|
>
|
||||||
View Traces
|
View Traces
|
||||||
@ -295,6 +308,7 @@ function External(): JSX.Element {
|
|||||||
selectedTraceTags,
|
selectedTraceTags,
|
||||||
timestamp: selectedTimeStamp,
|
timestamp: selectedTimeStamp,
|
||||||
apmToTraceQuery,
|
apmToTraceQuery,
|
||||||
|
stepInterval,
|
||||||
})}
|
})}
|
||||||
>
|
>
|
||||||
View Traces
|
View Traces
|
||||||
@ -330,6 +344,7 @@ function External(): JSX.Element {
|
|||||||
selectedTraceTags,
|
selectedTraceTags,
|
||||||
timestamp: selectedTimeStamp,
|
timestamp: selectedTimeStamp,
|
||||||
apmToTraceQuery,
|
apmToTraceQuery,
|
||||||
|
stepInterval,
|
||||||
})}
|
})}
|
||||||
>
|
>
|
||||||
View Traces
|
View Traces
|
||||||
|
@ -15,6 +15,7 @@ import {
|
|||||||
resourceAttributesToTagFilterItems,
|
resourceAttributesToTagFilterItems,
|
||||||
} from 'hooks/useResourceAttribute/utils';
|
} from 'hooks/useResourceAttribute/utils';
|
||||||
import useUrlQuery from 'hooks/useUrlQuery';
|
import useUrlQuery from 'hooks/useUrlQuery';
|
||||||
|
import getStep from 'lib/getStep';
|
||||||
import history from 'lib/history';
|
import history from 'lib/history';
|
||||||
import { OnClickPluginOpts } from 'lib/uPlotLib/plugins/onClickPlugin';
|
import { OnClickPluginOpts } from 'lib/uPlotLib/plugins/onClickPlugin';
|
||||||
import { defaultTo } from 'lodash-es';
|
import { defaultTo } from 'lodash-es';
|
||||||
@ -38,6 +39,7 @@ import {
|
|||||||
} from '../MetricsPageQueries/OverviewQueries';
|
} from '../MetricsPageQueries/OverviewQueries';
|
||||||
import { Col, ColApDexContainer, ColErrorContainer, Row } from '../styles';
|
import { Col, ColApDexContainer, ColErrorContainer, Row } from '../styles';
|
||||||
import ApDex from './Overview/ApDex';
|
import ApDex from './Overview/ApDex';
|
||||||
|
import GraphControlsPanel from './Overview/GraphControlsPanel/GraphControlsPanel';
|
||||||
import ServiceOverview from './Overview/ServiceOverview';
|
import ServiceOverview from './Overview/ServiceOverview';
|
||||||
import TopLevelOperation from './Overview/TopLevelOperations';
|
import TopLevelOperation from './Overview/TopLevelOperations';
|
||||||
import TopOperation from './Overview/TopOperation';
|
import TopOperation from './Overview/TopOperation';
|
||||||
@ -45,9 +47,11 @@ import TopOperationMetrics from './Overview/TopOperationMetrics';
|
|||||||
import { Button, Card } from './styles';
|
import { Button, Card } from './styles';
|
||||||
import { IServiceName } from './types';
|
import { IServiceName } from './types';
|
||||||
import {
|
import {
|
||||||
|
generateExplorerPath,
|
||||||
handleNonInQueryRange,
|
handleNonInQueryRange,
|
||||||
onGraphClickHandler,
|
onGraphClickHandler,
|
||||||
onViewTracePopupClick,
|
onViewTracePopupClick,
|
||||||
|
useGetAPMToLogsQueries,
|
||||||
useGetAPMToTracesQueries,
|
useGetAPMToTracesQueries,
|
||||||
} from './util';
|
} from './util';
|
||||||
|
|
||||||
@ -177,6 +181,16 @@ function Application(): JSX.Element {
|
|||||||
id: SERVICE_CHART_ID.errorPercentage,
|
id: SERVICE_CHART_ID.errorPercentage,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const stepInterval = useMemo(
|
||||||
|
() =>
|
||||||
|
getStep({
|
||||||
|
end: maxTime,
|
||||||
|
inputFormat: 'ns',
|
||||||
|
start: minTime,
|
||||||
|
}),
|
||||||
|
[maxTime, minTime],
|
||||||
|
);
|
||||||
|
|
||||||
const onDragSelect = useCallback(
|
const onDragSelect = useCallback(
|
||||||
(start: number, end: number) => {
|
(start: number, end: number) => {
|
||||||
const startTimestamp = Math.trunc(start);
|
const startTimestamp = Math.trunc(start);
|
||||||
@ -194,33 +208,60 @@ function Application(): JSX.Element {
|
|||||||
[dispatch, pathname, urlQuery],
|
[dispatch, pathname, urlQuery],
|
||||||
);
|
);
|
||||||
|
|
||||||
const onErrorTrackHandler = (
|
const onErrorTrackHandler = useCallback(
|
||||||
timestamp: number,
|
(
|
||||||
apmToTraceQuery: Query,
|
timestamp: number,
|
||||||
): (() => void) => (): void => {
|
apmToTraceQuery: Query,
|
||||||
const currentTime = timestamp;
|
isViewLogsClicked?: boolean,
|
||||||
const tPlusOne = timestamp + 60 * 1000;
|
): (() => void) => (): void => {
|
||||||
|
const currentTime = timestamp;
|
||||||
|
const endTime = timestamp + stepInterval;
|
||||||
|
console.log(endTime, stepInterval);
|
||||||
|
|
||||||
const urlParams = new URLSearchParams(search);
|
const urlParams = new URLSearchParams(search);
|
||||||
urlParams.set(QueryParams.startTime, currentTime.toString());
|
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);
|
||||||
|
|
||||||
const avialableParams = routeConfig[ROUTES.TRACE];
|
const JSONCompositeQuery = encodeURIComponent(
|
||||||
const queryString = getQueryString(avialableParams, urlParams);
|
JSON.stringify(apmToTraceQuery),
|
||||||
|
);
|
||||||
|
|
||||||
const JSONCompositeQuery = encodeURIComponent(
|
const newPath = generateExplorerPath(
|
||||||
JSON.stringify(apmToTraceQuery),
|
isViewLogsClicked,
|
||||||
);
|
urlParams,
|
||||||
|
servicename,
|
||||||
|
selectedTraceTags,
|
||||||
|
JSONCompositeQuery,
|
||||||
|
queryString,
|
||||||
|
);
|
||||||
|
|
||||||
const newTraceExplorerPath = `${
|
history.push(newPath);
|
||||||
ROUTES.TRACES_EXPLORER
|
},
|
||||||
}?${urlParams.toString()}&selected={"serviceName":["${servicename}"]}&filterToFetchData=["duration","status","serviceName"]&spanAggregateCurrentPage=1&selectedTags=${selectedTraceTags}&${
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
QueryParams.compositeQuery
|
[stepInterval],
|
||||||
}=${JSONCompositeQuery}&${queryString.join('&')}`;
|
);
|
||||||
|
|
||||||
history.push(newTraceExplorerPath);
|
|
||||||
};
|
|
||||||
|
|
||||||
|
const logErrorQuery = useGetAPMToLogsQueries({
|
||||||
|
servicename,
|
||||||
|
filters: [
|
||||||
|
{
|
||||||
|
id: uuid().slice(0, 8),
|
||||||
|
key: {
|
||||||
|
key: 'severity_text',
|
||||||
|
dataType: DataTypes.String,
|
||||||
|
type: '',
|
||||||
|
isColumn: true,
|
||||||
|
isJSON: false,
|
||||||
|
id: 'severity_text--string----true',
|
||||||
|
},
|
||||||
|
op: 'in',
|
||||||
|
value: ['ERROR', 'FATAL', 'error', 'fatal'],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
const errorTrackQuery = useGetAPMToTracesQueries({
|
const errorTrackQuery = useGetAPMToTracesQueries({
|
||||||
servicename,
|
servicename,
|
||||||
filters: [
|
filters: [
|
||||||
@ -251,6 +292,7 @@ function Application(): JSX.Element {
|
|||||||
selectedTraceTags={selectedTraceTags}
|
selectedTraceTags={selectedTraceTags}
|
||||||
topLevelOperationsRoute={topLevelOperationsRoute}
|
topLevelOperationsRoute={topLevelOperationsRoute}
|
||||||
topLevelOperationsIsLoading={topLevelOperationsIsLoading}
|
topLevelOperationsIsLoading={topLevelOperationsIsLoading}
|
||||||
|
stepInterval={stepInterval}
|
||||||
/>
|
/>
|
||||||
</Col>
|
</Col>
|
||||||
|
|
||||||
@ -264,6 +306,7 @@ function Application(): JSX.Element {
|
|||||||
selectedTraceTags,
|
selectedTraceTags,
|
||||||
timestamp: selectedTimeStamp,
|
timestamp: selectedTimeStamp,
|
||||||
apmToTraceQuery,
|
apmToTraceQuery,
|
||||||
|
stepInterval,
|
||||||
})}
|
})}
|
||||||
>
|
>
|
||||||
View Traces
|
View Traces
|
||||||
@ -292,6 +335,7 @@ function Application(): JSX.Element {
|
|||||||
selectedTraceTags,
|
selectedTraceTags,
|
||||||
timestamp: selectedTimeStamp,
|
timestamp: selectedTimeStamp,
|
||||||
apmToTraceQuery,
|
apmToTraceQuery,
|
||||||
|
stepInterval,
|
||||||
})}
|
})}
|
||||||
>
|
>
|
||||||
View Traces
|
View Traces
|
||||||
@ -304,14 +348,18 @@ function Application(): JSX.Element {
|
|||||||
/>
|
/>
|
||||||
</ColApDexContainer>
|
</ColApDexContainer>
|
||||||
<ColErrorContainer>
|
<ColErrorContainer>
|
||||||
<Button
|
<GraphControlsPanel
|
||||||
type="default"
|
|
||||||
size="small"
|
|
||||||
id="Error_button"
|
id="Error_button"
|
||||||
onClick={onErrorTrackHandler(selectedTimeStamp, errorTrackQuery)}
|
onViewLogsClick={onErrorTrackHandler(
|
||||||
>
|
selectedTimeStamp,
|
||||||
View Traces
|
logErrorQuery,
|
||||||
</Button>
|
true,
|
||||||
|
)}
|
||||||
|
onViewTracesClick={onErrorTrackHandler(
|
||||||
|
selectedTimeStamp,
|
||||||
|
errorTrackQuery,
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
|
||||||
<TopLevelOperation
|
<TopLevelOperation
|
||||||
handleGraphClick={handleGraphClick}
|
handleGraphClick={handleGraphClick}
|
||||||
|
@ -0,0 +1,25 @@
|
|||||||
|
.graph-controls-panel {
|
||||||
|
position: absolute;
|
||||||
|
z-index: 999;
|
||||||
|
display: none;
|
||||||
|
width: 110px;
|
||||||
|
padding: 5px;
|
||||||
|
border-radius: 5px;
|
||||||
|
background: var(--bg-slate-400);
|
||||||
|
|
||||||
|
.ant-btn-link {
|
||||||
|
padding: 0;
|
||||||
|
margin: 0;
|
||||||
|
text-decoration: none;
|
||||||
|
color: var(--bg-vanilla-100);
|
||||||
|
cursor: pointer;
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 2px;
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ant-btn-link:hover {
|
||||||
|
color: var(--bg-vanilla-100);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,42 @@
|
|||||||
|
import './GraphControlsPanel.styles.scss';
|
||||||
|
|
||||||
|
import { Color } from '@signozhq/design-tokens';
|
||||||
|
import { Button } from 'antd';
|
||||||
|
import { DraftingCompass, ScrollText } from 'lucide-react';
|
||||||
|
|
||||||
|
interface GraphControlsPanelProps {
|
||||||
|
id: string;
|
||||||
|
onViewLogsClick: () => void;
|
||||||
|
onViewTracesClick: () => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
function GraphControlsPanel({
|
||||||
|
id,
|
||||||
|
onViewLogsClick,
|
||||||
|
onViewTracesClick,
|
||||||
|
}: GraphControlsPanelProps): JSX.Element {
|
||||||
|
return (
|
||||||
|
<div id={id} className="graph-controls-panel">
|
||||||
|
<Button
|
||||||
|
type="link"
|
||||||
|
icon={<DraftingCompass size={14} />}
|
||||||
|
size="small"
|
||||||
|
onClick={onViewTracesClick}
|
||||||
|
style={{ color: Color.BG_VANILLA_100 }}
|
||||||
|
>
|
||||||
|
View traces
|
||||||
|
</Button>
|
||||||
|
<Button
|
||||||
|
type="link"
|
||||||
|
icon={<ScrollText size={14} />}
|
||||||
|
size="small"
|
||||||
|
onClick={onViewLogsClick}
|
||||||
|
style={{ color: Color.BG_VANILLA_100 }}
|
||||||
|
>
|
||||||
|
View logs
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default GraphControlsPanel;
|
@ -19,13 +19,14 @@ import { useParams } from 'react-router-dom';
|
|||||||
import { EQueryType } from 'types/common/dashboard';
|
import { EQueryType } from 'types/common/dashboard';
|
||||||
import { v4 as uuid } from 'uuid';
|
import { v4 as uuid } from 'uuid';
|
||||||
|
|
||||||
import { Button } from '../styles';
|
|
||||||
import { IServiceName } from '../types';
|
import { IServiceName } from '../types';
|
||||||
import {
|
import {
|
||||||
handleNonInQueryRange,
|
handleNonInQueryRange,
|
||||||
onViewTracePopupClick,
|
onViewTracePopupClick,
|
||||||
|
useGetAPMToLogsQueries,
|
||||||
useGetAPMToTracesQueries,
|
useGetAPMToTracesQueries,
|
||||||
} from '../util';
|
} from '../util';
|
||||||
|
import GraphControlsPanel from './GraphControlsPanel/GraphControlsPanel';
|
||||||
|
|
||||||
function ServiceOverview({
|
function ServiceOverview({
|
||||||
onDragSelect,
|
onDragSelect,
|
||||||
@ -34,6 +35,7 @@ function ServiceOverview({
|
|||||||
selectedTimeStamp,
|
selectedTimeStamp,
|
||||||
topLevelOperationsRoute,
|
topLevelOperationsRoute,
|
||||||
topLevelOperationsIsLoading,
|
topLevelOperationsIsLoading,
|
||||||
|
stepInterval,
|
||||||
}: ServiceOverviewProps): JSX.Element {
|
}: ServiceOverviewProps): JSX.Element {
|
||||||
const { servicename: encodedServiceName } = useParams<IServiceName>();
|
const { servicename: encodedServiceName } = useParams<IServiceName>();
|
||||||
const servicename = decodeURIComponent(encodedServiceName);
|
const servicename = decodeURIComponent(encodedServiceName);
|
||||||
@ -75,21 +77,28 @@ function ServiceOverview({
|
|||||||
|
|
||||||
const apmToTraceQuery = useGetAPMToTracesQueries({ servicename });
|
const apmToTraceQuery = useGetAPMToTracesQueries({ servicename });
|
||||||
|
|
||||||
|
const apmToLogQuery = useGetAPMToLogsQueries({ servicename });
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Button
|
<GraphControlsPanel
|
||||||
type="default"
|
|
||||||
size="small"
|
|
||||||
id="Service_button"
|
id="Service_button"
|
||||||
onClick={onViewTracePopupClick({
|
onViewLogsClick={onViewTracePopupClick({
|
||||||
|
servicename,
|
||||||
|
selectedTraceTags,
|
||||||
|
timestamp: selectedTimeStamp,
|
||||||
|
apmToTraceQuery: apmToLogQuery,
|
||||||
|
isViewLogsClicked: true,
|
||||||
|
stepInterval,
|
||||||
|
})}
|
||||||
|
onViewTracesClick={onViewTracePopupClick({
|
||||||
servicename,
|
servicename,
|
||||||
selectedTraceTags,
|
selectedTraceTags,
|
||||||
timestamp: selectedTimeStamp,
|
timestamp: selectedTimeStamp,
|
||||||
apmToTraceQuery,
|
apmToTraceQuery,
|
||||||
|
stepInterval,
|
||||||
})}
|
})}
|
||||||
>
|
/>
|
||||||
View Traces
|
|
||||||
</Button>
|
|
||||||
<Card data-testid="service_latency">
|
<Card data-testid="service_latency">
|
||||||
<GraphContainer>
|
<GraphContainer>
|
||||||
{topLevelOperationsIsLoading && (
|
{topLevelOperationsIsLoading && (
|
||||||
@ -114,8 +123,8 @@ function ServiceOverview({
|
|||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
interface ServiceOverviewProps {
|
interface ServiceOverviewProps {
|
||||||
|
stepInterval: number;
|
||||||
selectedTimeStamp: number;
|
selectedTimeStamp: number;
|
||||||
selectedTraceTags: string;
|
selectedTraceTags: string;
|
||||||
onDragSelect: (start: number, end: number) => void;
|
onDragSelect: (start: number, end: number) => void;
|
||||||
|
@ -7,6 +7,7 @@ import { useQueryBuilder } from 'hooks/queryBuilder/useQueryBuilder';
|
|||||||
import useResourceAttribute from 'hooks/useResourceAttribute';
|
import useResourceAttribute from 'hooks/useResourceAttribute';
|
||||||
import { resourceAttributesToTracesFilterItems } from 'hooks/useResourceAttribute/utils';
|
import { resourceAttributesToTracesFilterItems } from 'hooks/useResourceAttribute/utils';
|
||||||
import history from 'lib/history';
|
import history from 'lib/history';
|
||||||
|
import { prepareQueryWithDefaultTimestamp } from 'pages/LogsExplorer/utils';
|
||||||
import { traceFilterKeys } from 'pages/TracesExplorer/Filter/filterUtils';
|
import { traceFilterKeys } from 'pages/TracesExplorer/Filter/filterUtils';
|
||||||
import { Dispatch, SetStateAction, useMemo } from 'react';
|
import { Dispatch, SetStateAction, useMemo } from 'react';
|
||||||
import {
|
import {
|
||||||
@ -33,21 +34,44 @@ interface OnViewTracePopupClickProps {
|
|||||||
selectedTraceTags: string;
|
selectedTraceTags: string;
|
||||||
timestamp: number;
|
timestamp: number;
|
||||||
apmToTraceQuery: Query;
|
apmToTraceQuery: Query;
|
||||||
|
isViewLogsClicked?: boolean;
|
||||||
|
stepInterval?: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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('&')}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO(@rahul-signoz): update the name of this function once we have view logs button in every panel
|
||||||
export function onViewTracePopupClick({
|
export function onViewTracePopupClick({
|
||||||
selectedTraceTags,
|
selectedTraceTags,
|
||||||
servicename,
|
servicename,
|
||||||
timestamp,
|
timestamp,
|
||||||
apmToTraceQuery,
|
apmToTraceQuery,
|
||||||
|
isViewLogsClicked,
|
||||||
|
stepInterval,
|
||||||
}: OnViewTracePopupClickProps): VoidFunction {
|
}: OnViewTracePopupClickProps): VoidFunction {
|
||||||
return (): void => {
|
return (): void => {
|
||||||
const currentTime = timestamp;
|
const currentTime = timestamp;
|
||||||
|
const endTime = timestamp + (stepInterval || 60);
|
||||||
const tPlusOne = timestamp + 60;
|
|
||||||
|
|
||||||
const urlParams = new URLSearchParams(window.location.search);
|
const urlParams = new URLSearchParams(window.location.search);
|
||||||
urlParams.set(QueryParams.startTime, currentTime.toString());
|
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 avialableParams = routeConfig[ROUTES.TRACE];
|
||||||
const queryString = getQueryString(avialableParams, urlParams);
|
const queryString = getQueryString(avialableParams, urlParams);
|
||||||
|
|
||||||
@ -55,13 +79,16 @@ export function onViewTracePopupClick({
|
|||||||
JSON.stringify(apmToTraceQuery),
|
JSON.stringify(apmToTraceQuery),
|
||||||
);
|
);
|
||||||
|
|
||||||
const newTraceExplorerPath = `${
|
const newPath = generateExplorerPath(
|
||||||
ROUTES.TRACES_EXPLORER
|
isViewLogsClicked,
|
||||||
}?${urlParams.toString()}&selected={"serviceName":["${servicename}"]}&filterToFetchData=["duration","status","serviceName"]&spanAggregateCurrentPage=1&selectedTags=${selectedTraceTags}&${
|
urlParams,
|
||||||
QueryParams.compositeQuery
|
servicename,
|
||||||
}=${JSONCompositeQuery}&${queryString.join('&')}`;
|
selectedTraceTags,
|
||||||
|
JSONCompositeQuery,
|
||||||
|
queryString,
|
||||||
|
);
|
||||||
|
|
||||||
history.push(newTraceExplorerPath);
|
history.push(newPath);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -108,12 +135,13 @@ export function handleQueryChange(
|
|||||||
attributeKeys: BaseAutocompleteData,
|
attributeKeys: BaseAutocompleteData,
|
||||||
serviceAttribute: string,
|
serviceAttribute: string,
|
||||||
filters?: TagFilterItem[],
|
filters?: TagFilterItem[],
|
||||||
|
logs?: boolean,
|
||||||
): Query {
|
): Query {
|
||||||
const filterItem: TagFilterItem[] = [
|
const filterItem: TagFilterItem[] = [
|
||||||
{
|
{
|
||||||
id: uuid().slice(0, 8),
|
id: uuid().slice(0, 8),
|
||||||
key: attributeKeys,
|
key: attributeKeys,
|
||||||
op: 'in',
|
op: logs ? '=' : 'in',
|
||||||
value: serviceAttribute,
|
value: serviceAttribute,
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
@ -132,6 +160,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: false,
|
||||||
|
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({
|
export function useGetAPMToTracesQueries({
|
||||||
servicename,
|
servicename,
|
||||||
isExternalCall,
|
isExternalCall,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user