feat(FE): span Kind is added in the trace filter page (#2281)

This commit is contained in:
palashgdev 2023-02-20 19:12:54 +05:30 committed by GitHub
parent 3d5134b43c
commit 2624ce4007
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
34 changed files with 263 additions and 33 deletions

View File

@ -32,6 +32,7 @@ const getFilters = async (
maxDuration: String((duration.duration || [])[0] || ''), maxDuration: String((duration.duration || [])[0] || ''),
minDuration: String((duration.duration || [])[1] || ''), minDuration: String((duration.duration || [])[1] || ''),
exclude, exclude,
spanKind: props.spanKind,
}); });
return { return {

View File

@ -44,6 +44,7 @@ const getSpans = async (
maxDuration: String((duration.duration || [])[0] || ''), maxDuration: String((duration.duration || [])[0] || ''),
minDuration: String((duration.duration || [])[1] || ''), minDuration: String((duration.duration || [])[1] || ''),
exclude, exclude,
spanKind: props.spanKind,
}, },
); );

View File

@ -48,6 +48,7 @@ const getSpanAggregate = async (
maxDuration: String((duration.duration || [])[0] || ''), maxDuration: String((duration.duration || [])[0] || ''),
minDuration: String((duration.duration || [])[1] || ''), minDuration: String((duration.duration || [])[1] || ''),
exclude, exclude,
spanKind: props.spanKind,
}); });
return { return {

View File

@ -32,6 +32,7 @@ const getTagFilters = async (
maxDuration: String((duration.duration || [])[0] || ''), maxDuration: String((duration.duration || [])[0] || ''),
minDuration: String((duration.duration || [])[1] || ''), minDuration: String((duration.duration || [])[1] || ''),
exclude, exclude,
spanKind: props.spanKind,
}); });
return { return {

View File

@ -15,6 +15,7 @@ const getTagValue = async (
Key: props.tagKey.Key, Key: props.tagKey.Key,
Type: props.tagKey.Type, Type: props.tagKey.Type,
}, },
spanKind: props.spanKind,
}); });
return { return {
statusCode: 200, statusCode: 200,

View File

@ -161,7 +161,7 @@ export const externalCallDurationByAddress = ({
}; };
interface ExternalCallDurationByAddressProps extends ExternalCallProps { interface ExternalCallDurationByAddressProps extends ExternalCallProps {
legend: '{{address}}'; legend: string;
} }
export interface ExternalCallProps { export interface ExternalCallProps {

View File

@ -79,11 +79,11 @@ function DBCall({ getWidgetQueryBuilder }: DBCallProps): JSX.Element {
type="default" type="default"
size="small" size="small"
id="database_call_rps_button" id="database_call_rps_button"
onClick={onViewTracePopupClick( onClick={onViewTracePopupClick({
servicename, servicename,
selectedTraceTags, selectedTraceTags,
selectedTimeStamp, timestamp: selectedTimeStamp,
)} })}
> >
View Traces View Traces
</Button> </Button>
@ -114,11 +114,11 @@ function DBCall({ getWidgetQueryBuilder }: DBCallProps): JSX.Element {
type="default" type="default"
size="small" size="small"
id="database_call_avg_duration_button" id="database_call_avg_duration_button"
onClick={onViewTracePopupClick( onClick={onViewTracePopupClick({
servicename, servicename,
selectedTraceTags, selectedTraceTags,
selectedTimeStamp, timestamp: selectedTimeStamp,
)} })}
> >
View Traces View Traces
</Button> </Button>

View File

@ -6,8 +6,11 @@ import {
externalCallErrorPercent, externalCallErrorPercent,
externalCallRpsByAddress, externalCallRpsByAddress,
} from 'container/MetricsApplication/MetricsPageQueries/ExternalQueries'; } from 'container/MetricsApplication/MetricsPageQueries/ExternalQueries';
import { resourceAttributesToTagFilterItems } from 'lib/resourceAttributes'; import {
import React, { useMemo } from 'react'; convertRawQueriesToTraceSelectedTags,
resourceAttributesToTagFilterItems,
} from 'lib/resourceAttributes';
import React, { useMemo, useState } from 'react';
import { useSelector } from 'react-redux'; import { useSelector } from 'react-redux';
import { useParams } from 'react-router-dom'; import { useParams } from 'react-router-dom';
import { AppState } from 'store/reducers'; import { AppState } from 'store/reducers';
@ -15,8 +18,13 @@ import { Widgets } from 'types/api/dashboard/getAll';
import MetricReducer from 'types/reducer/metrics'; import MetricReducer from 'types/reducer/metrics';
import { Card, GraphContainer, GraphTitle, Row } from '../styles'; import { Card, GraphContainer, GraphTitle, Row } from '../styles';
import { legend } from './constant';
import { Button } from './styles';
import { onGraphClickHandler, onViewTracePopupClick } from './util';
function External({ getWidgetQueryBuilder }: ExternalProps): JSX.Element { function External({ getWidgetQueryBuilder }: ExternalProps): JSX.Element {
const [selectedTimeStamp, setSelectedTimeStamp] = useState<number>(0);
const { servicename } = useParams<{ servicename?: string }>(); const { servicename } = useParams<{ servicename?: string }>();
const { resourceAttributeQueries } = useSelector<AppState, MetricReducer>( const { resourceAttributeQueries } = useSelector<AppState, MetricReducer>(
(state) => state.metrics, (state) => state.metrics,
@ -27,8 +35,6 @@ function External({ getWidgetQueryBuilder }: ExternalProps): JSX.Element {
[resourceAttributeQueries], [resourceAttributeQueries],
); );
const legend = '{{address}}';
const externalCallErrorWidget = useMemo( const externalCallErrorWidget = useMemo(
() => () =>
getWidgetQueryBuilder({ getWidgetQueryBuilder({
@ -36,7 +42,7 @@ function External({ getWidgetQueryBuilder }: ExternalProps): JSX.Element {
promQL: [], promQL: [],
metricsBuilder: externalCallErrorPercent({ metricsBuilder: externalCallErrorPercent({
servicename, servicename,
legend, legend: legend.address,
tagFilterItems, tagFilterItems,
}), }),
clickHouse: [], clickHouse: [],
@ -44,6 +50,14 @@ function External({ getWidgetQueryBuilder }: ExternalProps): JSX.Element {
[getWidgetQueryBuilder, servicename, tagFilterItems], [getWidgetQueryBuilder, servicename, tagFilterItems],
); );
const selectedTraceTags = useMemo(
() =>
JSON.stringify(
convertRawQueriesToTraceSelectedTags(resourceAttributeQueries) || [],
),
[resourceAttributeQueries],
);
const externalCallDurationWidget = useMemo( const externalCallDurationWidget = useMemo(
() => () =>
getWidgetQueryBuilder({ getWidgetQueryBuilder({
@ -65,7 +79,7 @@ function External({ getWidgetQueryBuilder }: ExternalProps): JSX.Element {
promQL: [], promQL: [],
metricsBuilder: externalCallRpsByAddress({ metricsBuilder: externalCallRpsByAddress({
servicename, servicename,
legend, legend: legend.address,
tagFilterItems, tagFilterItems,
}), }),
clickHouse: [], clickHouse: [],
@ -80,7 +94,7 @@ function External({ getWidgetQueryBuilder }: ExternalProps): JSX.Element {
promQL: [], promQL: [],
metricsBuilder: externalCallDurationByAddress({ metricsBuilder: externalCallDurationByAddress({
servicename, servicename,
legend, legend: legend.address,
tagFilterItems, tagFilterItems,
}), }),
clickHouse: [], clickHouse: [],
@ -92,6 +106,19 @@ function External({ getWidgetQueryBuilder }: ExternalProps): JSX.Element {
<> <>
<Row gutter={24}> <Row gutter={24}>
<Col span={12}> <Col span={12}>
<Button
type="default"
size="small"
id="external_call_error_percentage_button"
onClick={onViewTracePopupClick({
servicename,
selectedTraceTags,
timestamp: selectedTimeStamp,
isExternalCall: true,
})}
>
View Traces
</Button>
<Card> <Card>
<GraphTitle>External Call Error Percentage</GraphTitle> <GraphTitle>External Call Error Percentage</GraphTitle>
<GraphContainer> <GraphContainer>
@ -100,12 +127,35 @@ function External({ getWidgetQueryBuilder }: ExternalProps): JSX.Element {
fullViewOptions={false} fullViewOptions={false}
widget={externalCallErrorWidget} widget={externalCallErrorWidget}
yAxisUnit="%" yAxisUnit="%"
onClickHandler={(ChartEvent, activeElements, chart, data): void => {
onGraphClickHandler(setSelectedTimeStamp)(
ChartEvent,
activeElements,
chart,
data,
'external_call_error_percentage',
);
}}
/> />
</GraphContainer> </GraphContainer>
</Card> </Card>
</Col> </Col>
<Col span={12}> <Col span={12}>
<Button
type="default"
size="small"
id="external_call_duration_button"
onClick={onViewTracePopupClick({
servicename,
selectedTraceTags,
timestamp: selectedTimeStamp,
isExternalCall: true,
})}
>
View Traces
</Button>
<Card> <Card>
<GraphTitle>External Call duration</GraphTitle> <GraphTitle>External Call duration</GraphTitle>
<GraphContainer> <GraphContainer>
@ -114,6 +164,15 @@ function External({ getWidgetQueryBuilder }: ExternalProps): JSX.Element {
fullViewOptions={false} fullViewOptions={false}
widget={externalCallDurationWidget} widget={externalCallDurationWidget}
yAxisUnit="ms" yAxisUnit="ms"
onClickHandler={(ChartEvent, activeElements, chart, data): void => {
onGraphClickHandler(setSelectedTimeStamp)(
ChartEvent,
activeElements,
chart,
data,
'external_call_duration',
);
}}
/> />
</GraphContainer> </GraphContainer>
</Card> </Card>
@ -122,6 +181,19 @@ function External({ getWidgetQueryBuilder }: ExternalProps): JSX.Element {
<Row gutter={24}> <Row gutter={24}>
<Col span={12}> <Col span={12}>
<Button
type="default"
size="small"
id="external_call_rps_by_address_button"
onClick={onViewTracePopupClick({
servicename,
selectedTraceTags,
timestamp: selectedTimeStamp,
isExternalCall: true,
})}
>
View Traces
</Button>
<Card> <Card>
<GraphTitle>External Call RPS(by Address)</GraphTitle> <GraphTitle>External Call RPS(by Address)</GraphTitle>
<GraphContainer> <GraphContainer>
@ -130,12 +202,35 @@ function External({ getWidgetQueryBuilder }: ExternalProps): JSX.Element {
fullViewOptions={false} fullViewOptions={false}
widget={externalCallRPSWidget} widget={externalCallRPSWidget}
yAxisUnit="reqps" yAxisUnit="reqps"
onClickHandler={(ChartEvent, activeElements, chart, data): void => {
onGraphClickHandler(setSelectedTimeStamp)(
ChartEvent,
activeElements,
chart,
data,
'external_call_rps_by_address',
);
}}
/> />
</GraphContainer> </GraphContainer>
</Card> </Card>
</Col> </Col>
<Col span={12}> <Col span={12}>
<Button
type="default"
size="small"
id="external_call_duration_by_address_button"
onClick={onViewTracePopupClick({
servicename,
selectedTraceTags,
timestamp: selectedTimeStamp,
isExternalCall: true,
})}
>
View Traces
</Button>
<Card> <Card>
<GraphTitle>External Call duration(by Address)</GraphTitle> <GraphTitle>External Call duration(by Address)</GraphTitle>
<GraphContainer> <GraphContainer>
@ -144,6 +239,15 @@ function External({ getWidgetQueryBuilder }: ExternalProps): JSX.Element {
fullViewOptions={false} fullViewOptions={false}
widget={externalCallDurationAddressWidget} widget={externalCallDurationAddressWidget}
yAxisUnit="ms" yAxisUnit="ms"
onClickHandler={(ChartEvent, activeElements, chart, data): void => {
onGraphClickHandler(setSelectedTimeStamp)(
ChartEvent,
activeElements,
chart,
data,
'external_call_duration_by_address',
);
}}
/> />
</GraphContainer> </GraphContainer>
</Card> </Card>

View File

@ -181,11 +181,11 @@ function Application({ getWidgetQueryBuilder }: DashboardProps): JSX.Element {
type="default" type="default"
size="small" size="small"
id="Service_button" id="Service_button"
onClick={onViewTracePopupClick( onClick={onViewTracePopupClick({
servicename, servicename,
selectedTraceTags, selectedTraceTags,
selectedTimeStamp, timestamp: selectedTimeStamp,
)} })}
> >
View Traces View Traces
</Button> </Button>
@ -210,11 +210,11 @@ function Application({ getWidgetQueryBuilder }: DashboardProps): JSX.Element {
type="default" type="default"
size="small" size="small"
id="Rate_button" id="Rate_button"
onClick={onViewTracePopupClick( onClick={onViewTracePopupClick({
servicename, servicename,
selectedTraceTags, selectedTraceTags,
selectedTimeStamp, timestamp: selectedTimeStamp,
)} })}
> >
View Traces View Traces
</Button> </Button>

View File

@ -0,0 +1,3 @@
export const legend = {
address: '{{address}}',
};

View File

@ -14,11 +14,18 @@ export const dbSystemTags: Tags[] = [
}, },
]; ];
export function onViewTracePopupClick( interface OnViewTracePopupClickProps {
servicename: string | undefined, servicename: string | undefined;
selectedTraceTags: string, selectedTraceTags: string;
timestamp: number, timestamp: number;
): VoidFunction { isExternalCall?: boolean;
}
export function onViewTracePopupClick({
selectedTraceTags,
servicename,
timestamp,
isExternalCall,
}: OnViewTracePopupClickProps): VoidFunction {
return (): void => { return (): void => {
const currentTime = timestamp; const currentTime = timestamp;
const tPlusOne = timestamp + 60 * 1000; const tPlusOne = timestamp + 60 * 1000;
@ -30,7 +37,9 @@ export function onViewTracePopupClick(
history.replace( history.replace(
`${ `${
ROUTES.TRACE ROUTES.TRACE
}?${urlParams.toString()}&selected={"serviceName":["${servicename}"]}&filterToFetchData=["duration","status","serviceName"]&spanAggregateCurrentPage=1&selectedTags=${selectedTraceTags}&&isFilterExclude={"serviceName":false}&userSelectedFilter={"status":["error","ok"],"serviceName":["${servicename}"]}&spanAggregateCurrentPage=1`, }?${urlParams.toString()}&selected={"serviceName":["${servicename}"]}&filterToFetchData=["duration","status","serviceName"]&spanAggregateCurrentPage=1&selectedTags=${selectedTraceTags}&&isFilterExclude={"serviceName":false}&userSelectedFilter={"status":["error","ok"],"serviceName":["${servicename}"]}&spanAggregateCurrentPage=1${
isExternalCall ? '&spanKind=3' : ''
}`,
); );
}; };
} }

View File

@ -24,6 +24,7 @@ function CheckBoxComponent(props: CheckBoxProps): JSX.Element {
filter, filter,
userSelectedFilter, userSelectedFilter,
isFilterExclude, isFilterExclude,
spanKind,
} = useSelector<AppState, TraceReducer>((state) => state.traces); } = useSelector<AppState, TraceReducer>((state) => state.traces);
const globalTime = useSelector<AppState, GlobalReducer>( const globalTime = useSelector<AppState, GlobalReducer>(
@ -91,6 +92,7 @@ function CheckBoxComponent(props: CheckBoxProps): JSX.Element {
start: String(globalTime.minTime), start: String(globalTime.minTime),
getFilters: filterToFetchData.filter((e) => e !== name), getFilters: filterToFetchData.filter((e) => e !== name),
isFilterExclude: preIsFilterExclude, isFilterExclude: preIsFilterExclude,
spanKind,
}); });
if (response.statusCode === 200) { if (response.statusCode === 200) {
@ -125,6 +127,7 @@ function CheckBoxComponent(props: CheckBoxProps): JSX.Element {
order: spansAggregate.order, order: spansAggregate.order,
orderParam: spansAggregate.orderParam, orderParam: spansAggregate.orderParam,
pageSize: spansAggregate.pageSize, pageSize: spansAggregate.pageSize,
spanKind,
}, },
}); });

View File

@ -30,6 +30,7 @@ function Duration(): JSX.Element {
selectedTags, selectedTags,
userSelectedFilter, userSelectedFilter,
isFilterExclude, isFilterExclude,
spanKind,
} = useSelector<AppState, TraceReducer>((state) => state.traces); } = useSelector<AppState, TraceReducer>((state) => state.traces);
const dispatch = useDispatch<Dispatch<AppActions>>(); const dispatch = useDispatch<Dispatch<AppActions>>();
@ -88,6 +89,7 @@ function Duration(): JSX.Element {
other: Object.fromEntries(preSelectedFilter), other: Object.fromEntries(preSelectedFilter),
start: String(globalTime.minTime), start: String(globalTime.minTime),
isFilterExclude, isFilterExclude,
spanKind,
}); });
if (response.statusCode === 200) { if (response.statusCode === 200) {
@ -113,6 +115,7 @@ function Duration(): JSX.Element {
order: spansAggregate.order, order: spansAggregate.order,
pageSize: spansAggregate.pageSize, pageSize: spansAggregate.pageSize,
orderParam: spansAggregate.orderParam, orderParam: spansAggregate.orderParam,
spanKind,
}, },
}); });

View File

@ -22,6 +22,7 @@ function TraceID(): JSX.Element {
selectedTags, selectedTags,
userSelectedFilter, userSelectedFilter,
isFilterExclude, isFilterExclude,
spanKind,
} = useSelector<AppState, TraceReducer>((state) => state.traces); } = useSelector<AppState, TraceReducer>((state) => state.traces);
const dispatch = useDispatch<Dispatch<AppActions>>(); const dispatch = useDispatch<Dispatch<AppActions>>();
const globalTime = useSelector<AppState, GlobalReducer>( const globalTime = useSelector<AppState, GlobalReducer>(
@ -52,6 +53,7 @@ function TraceID(): JSX.Element {
start: String(globalTime.minTime), start: String(globalTime.minTime),
getFilters: filterToFetchData, getFilters: filterToFetchData,
isFilterExclude, isFilterExclude,
spanKind,
}); });
if (response.statusCode === 200) { if (response.statusCode === 200) {
@ -77,6 +79,7 @@ function TraceID(): JSX.Element {
order: spansAggregate.order, order: spansAggregate.order,
pageSize: spansAggregate.pageSize, pageSize: spansAggregate.pageSize,
orderParam: spansAggregate.orderParam, orderParam: spansAggregate.orderParam,
spanKind,
}, },
}); });

View File

@ -37,6 +37,7 @@ function PanelHeading(props: PanelHeadingProps): JSX.Element {
filter, filter,
isFilterExclude, isFilterExclude,
userSelectedFilter, userSelectedFilter,
spanKind,
} = useSelector<AppState, TraceReducer>((state) => state.traces); } = useSelector<AppState, TraceReducer>((state) => state.traces);
const { name: PanelName, isOpen: IsPanelOpen } = props; const { name: PanelName, isOpen: IsPanelOpen } = props;
@ -75,6 +76,7 @@ function PanelHeading(props: PanelHeadingProps): JSX.Element {
getFilters: updatedFilterData, getFilters: updatedFilterData,
other: Object.fromEntries(getprepdatedSelectedFilter), other: Object.fromEntries(getprepdatedSelectedFilter),
isFilterExclude, isFilterExclude,
spanKind,
}); });
if (response.statusCode === 200) { if (response.statusCode === 200) {
@ -107,6 +109,7 @@ function PanelHeading(props: PanelHeadingProps): JSX.Element {
order: spansAggregate.order, order: spansAggregate.order,
pageSize: spansAggregate.pageSize, pageSize: spansAggregate.pageSize,
orderParam: spansAggregate.orderParam, orderParam: spansAggregate.orderParam,
spanKind,
}, },
}); });
@ -160,6 +163,7 @@ function PanelHeading(props: PanelHeadingProps): JSX.Element {
order: spansAggregate.order, order: spansAggregate.order,
pageSize: spansAggregate.pageSize, pageSize: spansAggregate.pageSize,
orderParam: spansAggregate.orderParam, orderParam: spansAggregate.orderParam,
spanKind,
}, },
}); });
@ -195,6 +199,7 @@ function PanelHeading(props: PanelHeadingProps): JSX.Element {
getFilters: filterToFetchData, getFilters: filterToFetchData,
other: Object.fromEntries(updatedFilter), other: Object.fromEntries(updatedFilter),
isFilterExclude: postIsFilterExclude, isFilterExclude: postIsFilterExclude,
spanKind,
}); });
if (response.statusCode === 200 && response.payload) { if (response.statusCode === 200 && response.payload) {
@ -213,6 +218,7 @@ function PanelHeading(props: PanelHeadingProps): JSX.Element {
order: spansAggregate.order, order: spansAggregate.order,
pageSize: spansAggregate.pageSize, pageSize: spansAggregate.pageSize,
orderParam: spansAggregate.orderParam, orderParam: spansAggregate.orderParam,
spanKind,
}, },
}); });

View File

@ -27,6 +27,7 @@ function TagsKey(props: TagsKeysProps): JSX.Element {
globalTime.maxTime, globalTime.maxTime,
traces.selectedFilter, traces.selectedFilter,
traces.isFilterExclude, traces.isFilterExclude,
traces.spanKind,
], ],
{ {
queryFn: () => queryFn: () =>
@ -35,6 +36,7 @@ function TagsKey(props: TagsKeysProps): JSX.Element {
end: globalTime.maxTime, end: globalTime.maxTime,
other: Object.fromEntries(traces.selectedFilter), other: Object.fromEntries(traces.selectedFilter),
isFilterExclude: traces.isFilterExclude, isFilterExclude: traces.isFilterExclude,
spanKind: traces.spanKind,
}), }),
cacheTime: 120000, cacheTime: 120000,
}, },

View File

@ -30,6 +30,8 @@ function TagValue(props: TagValueProps): JSX.Element {
BoolValues: selectedBoolValues, BoolValues: selectedBoolValues,
} = tag; } = tag;
const traces = useSelector<AppState, TraceReducer>((state) => state.traces);
const [localTagValue, setLocalTagValue] = useState<TagValueTypes[]>( const [localTagValue, setLocalTagValue] = useState<TagValueTypes[]>(
getInitialLocalValue( getInitialLocalValue(
selectedNumberValues, selectedNumberValues,
@ -45,7 +47,14 @@ function TagValue(props: TagValueProps): JSX.Element {
const tagType = useMemo(() => extractTagType(tagKey), [tagKey]); const tagType = useMemo(() => extractTagType(tagKey), [tagKey]);
const { isLoading, data } = useQuery( const { isLoading, data } = useQuery(
['tagKey', globalReducer.minTime, globalReducer.maxTime, tagKey, tagType], [
'tagKey',
globalReducer.minTime,
globalReducer.maxTime,
tagKey,
tagType,
traces.spanKind,
],
{ {
queryFn: () => queryFn: () =>
getTagValue({ getTagValue({
@ -55,6 +64,7 @@ function TagValue(props: TagValueProps): JSX.Element {
Key: extractTagKey(tagKey), Key: extractTagKey(tagKey),
Type: tagType, Type: tagType,
}, },
spanKind: traces.spanKind,
}), }),
}, },
); );

View File

@ -67,6 +67,7 @@ function Search({
order: traces.spansAggregate.order, order: traces.spansAggregate.order,
pageSize: traces.spansAggregate.pageSize, pageSize: traces.spansAggregate.pageSize,
orderParam: traces.spansAggregate.orderParam, orderParam: traces.spansAggregate.orderParam,
spanKind: traces.spanKind,
}, },
}); });

View File

@ -40,6 +40,7 @@ function TraceGraphFilter(): JSX.Element {
globalTime.maxTime, globalTime.maxTime,
traces.selectedFilter, traces.selectedFilter,
traces.isFilterExclude, traces.isFilterExclude,
traces.spanKind,
], ],
{ {
queryFn: () => queryFn: () =>
@ -48,8 +49,10 @@ function TraceGraphFilter(): JSX.Element {
end: globalTime.maxTime, end: globalTime.maxTime,
other: Object.fromEntries(traces.selectedFilter), other: Object.fromEntries(traces.selectedFilter),
isFilterExclude: traces.isFilterExclude, isFilterExclude: traces.isFilterExclude,
spanKind: traces.spanKind,
}), }),
cacheTime: 120000, cacheTime: 120000,
enabled: traces.filter.size > 0,
}, },
); );

View File

@ -52,6 +52,7 @@ function Trace({
selectedFunction, selectedFunction,
selectedGroupBy, selectedGroupBy,
isFilterExclude, isFilterExclude,
spanKind,
} = useSelector<AppState, TraceReducer>((state) => state.traces); } = useSelector<AppState, TraceReducer>((state) => state.traces);
const { notifications } = useNotifications(); const { notifications } = useNotifications();
@ -71,6 +72,7 @@ function Trace({
selectedTags, selectedTags,
order: spansAggregate.order, order: spansAggregate.order,
orderParam: spansAggregate.orderParam, orderParam: spansAggregate.orderParam,
spanKind,
}, },
notifications, notifications,
); );
@ -85,6 +87,7 @@ function Trace({
spansAggregate.order, spansAggregate.order,
spansAggregate.orderParam, spansAggregate.orderParam,
notifications, notifications,
spanKind,
]); ]);
useEffect(() => { useEffect(() => {
@ -98,6 +101,7 @@ function Trace({
start: minTime, start: minTime,
step: getStep({ start: minTime, end: maxTime, inputFormat: 'ns' }), step: getStep({ start: minTime, end: maxTime, inputFormat: 'ns' }),
isFilterExclude, isFilterExclude,
spanKind,
}, },
notifications, notifications,
); );
@ -111,6 +115,7 @@ function Trace({
getSpans, getSpans,
isFilterExclude, isFilterExclude,
notifications, notifications,
spanKind,
]); ]);
useEffect( useEffect(

View File

@ -12,6 +12,7 @@ import {
import { GlobalReducer } from 'types/reducer/globalTime'; import { GlobalReducer } from 'types/reducer/globalTime';
import { TraceFilterEnum, TraceReducer } from 'types/reducer/trace'; import { TraceFilterEnum, TraceReducer } from 'types/reducer/trace';
import { parseQueryIntoSpanKind } from './parseFilter/parseSpanKind';
import { import {
isTraceFilterEnum, isTraceFilterEnum,
parseAggregateOrderParams, parseAggregateOrderParams,
@ -55,6 +56,8 @@ export const GetInitialTraceFilter = (
traces.filterToFetchData, traces.filterToFetchData,
); );
const parsedSpanKind = parseQueryIntoSpanKind(query, traces.spanKind);
const getUserSelected = parseSelectedFilter(query, traces.userSelectedFilter); const getUserSelected = parseSelectedFilter(query, traces.userSelectedFilter);
const getIsFilterExcluded = parseFilterExclude(query, traces.isFilterExclude); const getIsFilterExcluded = parseFilterExclude(query, traces.isFilterExclude);
@ -102,6 +105,7 @@ export const GetInitialTraceFilter = (
start: String(minTime), start: String(minTime),
other: Object.fromEntries(getSelectedFilter.currentValue), other: Object.fromEntries(getSelectedFilter.currentValue),
isFilterExclude: getIsFilterExcluded.currentValue, isFilterExclude: getIsFilterExcluded.currentValue,
spanKind: parsedSpanKind.currentValue,
}); });
const preSelectedFilter: Map<TraceFilterEnum, string[]> = new Map( const preSelectedFilter: Map<TraceFilterEnum, string[]> = new Map(
@ -164,6 +168,7 @@ export const GetInitialTraceFilter = (
order: parsedQueryOrder.currentValue, order: parsedQueryOrder.currentValue,
pageSize: parsedPageSize.currentValue, pageSize: parsedPageSize.currentValue,
orderParam: parsedOrderParams.currentValue, orderParam: parsedOrderParams.currentValue,
spanKind: parsedSpanKind.currentValue,
}, },
}); });
} else { } else {

View File

@ -61,6 +61,7 @@ export const GetSpansAggregate = (
isFilterExclude: traces.isFilterExclude, isFilterExclude: traces.isFilterExclude,
order, order,
orderParam: props.orderParam, orderParam: props.orderParam,
spanKind: props.spanKind,
}); });
if (response.statusCode === 200) { if (response.statusCode === 200) {
@ -140,4 +141,5 @@ export interface GetSpansAggregateProps {
selectedTags: TraceReducer['selectedTags']; selectedTags: TraceReducer['selectedTags'];
order: GetSpanAggregateProps['order']; order: GetSpanAggregateProps['order'];
orderParam: GetSpanAggregateProps['orderParam']; orderParam: GetSpanAggregateProps['orderParam'];
spanKind: TraceReducer['spanKind'];
} }

View File

@ -63,6 +63,7 @@ export const GetSpans = (
start, start,
step: props.step, step: props.step,
isFilterExclude: props.isFilterExclude, isFilterExclude: props.isFilterExclude,
spanKind: props.spanKind,
}); });
if (response.statusCode === 200) { if (response.statusCode === 200) {

View File

@ -0,0 +1,39 @@
import { TraceReducer } from 'types/reducer/trace';
import { ParsedUrl } from '../util';
export const parseQueryIntoSpanKind = (
query: string,
stateCurrent: TraceReducer['spanKind'],
): ParsedUrl<TraceReducer['spanKind']> => {
const url = new URLSearchParams(query);
let current = '';
const selected = url.get('spanKind');
if (selected) {
try {
const parsedValue = selected;
if (parsedValue && typeof parsedValue === 'string') {
current = parsedValue;
}
} catch (error) {
console.log(error);
console.log('error while parsing json');
}
}
if (selected) {
return {
currentValue: current,
urlValue: current,
};
}
return {
currentValue: stateCurrent,
urlValue: current,
};
};

View File

@ -70,6 +70,7 @@ const initialValue: TraceReducer = {
['status', INITIAL_FILTER_VALUE], ['status', INITIAL_FILTER_VALUE],
['traceID', INITIAL_FILTER_VALUE], ['traceID', INITIAL_FILTER_VALUE],
]), ]),
spanKind: undefined,
}; };
const traceReducer = ( const traceReducer = (
@ -97,6 +98,7 @@ const traceReducer = (
order, order,
pageSize, pageSize,
orderParam, orderParam,
spanKind,
} = payload; } = payload;
return { return {
@ -114,6 +116,7 @@ const traceReducer = (
order, order,
orderParam, orderParam,
}, },
spanKind,
}; };
} }

View File

@ -82,6 +82,7 @@ export interface UpdateAllFilters {
order: TraceReducer['spansAggregate']['order']; order: TraceReducer['spansAggregate']['order'];
pageSize: TraceReducer['spansAggregate']['pageSize']; pageSize: TraceReducer['spansAggregate']['pageSize'];
orderParam: TraceReducer['spansAggregate']['orderParam']; orderParam: TraceReducer['spansAggregate']['orderParam'];
spanKind?: TraceReducer['spanKind'];
}; };
} }

View File

@ -8,6 +8,7 @@ export interface Props {
[k: string]: string[]; [k: string]: string[];
}; };
isFilterExclude: TraceReducer['isFilterExclude']; isFilterExclude: TraceReducer['isFilterExclude'];
spanKind?: TraceReducer['spanKind'];
} }
export interface PayloadProps { export interface PayloadProps {

View File

@ -10,6 +10,7 @@ export interface Props {
order?: TraceReducer['spansAggregate']['order']; order?: TraceReducer['spansAggregate']['order'];
isFilterExclude: TraceReducer['isFilterExclude']; isFilterExclude: TraceReducer['isFilterExclude'];
orderParam: TraceReducer['spansAggregate']['orderParam']; orderParam: TraceReducer['spansAggregate']['orderParam'];
spanKind?: TraceReducer['spanKind'];
} }
export type PayloadProps = { export type PayloadProps = {

View File

@ -9,6 +9,7 @@ export interface Props {
selectedFilter: TraceReducer['selectedFilter']; selectedFilter: TraceReducer['selectedFilter'];
selectedTags: TraceReducer['selectedTags']; selectedTags: TraceReducer['selectedTags'];
isFilterExclude: TraceReducer['isFilterExclude']; isFilterExclude: TraceReducer['isFilterExclude'];
spanKind?: TraceReducer['spanKind'];
} }
export interface PayloadProps { export interface PayloadProps {

View File

@ -7,6 +7,7 @@ export interface Props {
[k: string]: string[]; [k: string]: string[];
}; };
isFilterExclude: TraceReducer['isFilterExclude']; isFilterExclude: TraceReducer['isFilterExclude'];
spanKind?: TraceReducer['spanKind'];
} }
export interface PayloadProps { export interface PayloadProps {

View File

@ -1,4 +1,5 @@
import { GlobalReducer } from 'types/reducer/globalTime'; import { GlobalReducer } from 'types/reducer/globalTime';
import { TraceReducer } from 'types/reducer/trace';
export interface Props { export interface Props {
start: GlobalReducer['minTime']; start: GlobalReducer['minTime'];
@ -7,6 +8,7 @@ export interface Props {
Key: string; Key: string;
Type: string; Type: string;
}; };
spanKind?: TraceReducer['spanKind'];
} }
export interface PayloadProps { export interface PayloadProps {

View File

@ -33,6 +33,7 @@ export interface TraceReducer {
}; };
yAxisUnit: string | undefined; yAxisUnit: string | undefined;
filterDisplayValue: Map<TraceFilterEnum, number>; filterDisplayValue: Map<TraceFilterEnum, number>;
spanKind?: string;
} }
interface SpansAggregateData { interface SpansAggregateData {

View File

@ -1001,6 +1001,11 @@ func (r *ClickHouseReader) GetSpanFilters(ctx context.Context, queryParams *mode
args = append(args, clickhouse.Named("durationNanoMax", queryParams.MaxDuration)) args = append(args, clickhouse.Named("durationNanoMax", queryParams.MaxDuration))
} }
if len(queryParams.SpanKind) != 0 {
query = query + " AND kind = @kind"
args = append(args, clickhouse.Named("kind", queryParams.SpanKind))
}
query = getStatusFilters(query, queryParams.Status, excludeMap) query = getStatusFilters(query, queryParams.Status, excludeMap)
traceFilterReponse := model.SpanFiltersResponse{ traceFilterReponse := model.SpanFiltersResponse{
@ -1364,9 +1369,9 @@ func (r *ClickHouseReader) GetFilteredSpans(ctx context.Context, queryParams *mo
} }
query = getStatusFilters(query, queryParams.Status, excludeMap) query = getStatusFilters(query, queryParams.Status, excludeMap)
if len(queryParams.Kind) != 0 { if len(queryParams.SpanKind) != 0 {
query = query + " AND kind = @kind" query = query + " AND kind = @kind"
args = append(args, clickhouse.Named("kind", queryParams.Kind)) args = append(args, clickhouse.Named("kind", queryParams.SpanKind))
} }
// create TagQuery from TagQueryParams // create TagQuery from TagQueryParams
@ -1666,6 +1671,10 @@ func (r *ClickHouseReader) GetTagFilters(ctx context.Context, queryParams *model
query = query + " AND durationNano <= @durationNanoMax" query = query + " AND durationNano <= @durationNanoMax"
args = append(args, clickhouse.Named("durationNanoMax", queryParams.MaxDuration)) args = append(args, clickhouse.Named("durationNanoMax", queryParams.MaxDuration))
} }
if len(queryParams.SpanKind) != 0 {
query = query + " AND kind = @kind"
args = append(args, clickhouse.Named("kind", queryParams.SpanKind))
}
query = getStatusFilters(query, queryParams.Status, excludeMap) query = getStatusFilters(query, queryParams.Status, excludeMap)
@ -1781,6 +1790,10 @@ func (r *ClickHouseReader) GetTagValues(ctx context.Context, queryParams *model.
query = query + " AND durationNano <= @durationNanoMax" query = query + " AND durationNano <= @durationNanoMax"
args = append(args, clickhouse.Named("durationNanoMax", queryParams.MaxDuration)) args = append(args, clickhouse.Named("durationNanoMax", queryParams.MaxDuration))
} }
if len(queryParams.SpanKind) != 0 {
query = query + " AND kind = @kind"
args = append(args, clickhouse.Named("kind", queryParams.SpanKind))
}
query = getStatusFilters(query, queryParams.Status, excludeMap) query = getStatusFilters(query, queryParams.Status, excludeMap)
@ -2113,9 +2126,9 @@ func (r *ClickHouseReader) GetFilteredSpansAggregates(ctx context.Context, query
} }
query = getStatusFilters(query, queryParams.Status, excludeMap) query = getStatusFilters(query, queryParams.Status, excludeMap)
if len(queryParams.Kind) != 0 { if len(queryParams.SpanKind) != 0 {
query = query + " AND kind = @kind" query = query + " AND kind = @kind"
args = append(args, clickhouse.Named("kind", queryParams.Kind)) args = append(args, clickhouse.Named("kind", queryParams.SpanKind))
} }
// create TagQuery from TagQueryParams // create TagQuery from TagQueryParams
tags := createTagQueryFromTagQueryParams(queryParams.Tags) tags := createTagQueryFromTagQueryParams(queryParams.Tags)

View File

@ -312,7 +312,7 @@ type GetFilteredSpansParams struct {
TraceID []string `json:"traceID"` TraceID []string `json:"traceID"`
ServiceName []string `json:"serviceName"` ServiceName []string `json:"serviceName"`
Operation []string `json:"operation"` Operation []string `json:"operation"`
Kind string `json:"kind"` SpanKind string `json:"spanKind"`
Status []string `json:"status"` Status []string `json:"status"`
HttpRoute []string `json:"httpRoute"` HttpRoute []string `json:"httpRoute"`
HttpCode []string `json:"httpCode"` HttpCode []string `json:"httpCode"`
@ -340,7 +340,7 @@ type GetFilteredSpanAggregatesParams struct {
TraceID []string `json:"traceID"` TraceID []string `json:"traceID"`
ServiceName []string `json:"serviceName"` ServiceName []string `json:"serviceName"`
Operation []string `json:"operation"` Operation []string `json:"operation"`
Kind string `json:"kind"` SpanKind string `json:"spanKind"`
Status []string `json:"status"` Status []string `json:"status"`
HttpRoute []string `json:"httpRoute"` HttpRoute []string `json:"httpRoute"`
HttpCode []string `json:"httpCode"` HttpCode []string `json:"httpCode"`
@ -369,6 +369,7 @@ type SpanFilterParams struct {
TraceID []string `json:"traceID"` TraceID []string `json:"traceID"`
Status []string `json:"status"` Status []string `json:"status"`
ServiceName []string `json:"serviceName"` ServiceName []string `json:"serviceName"`
SpanKind string `json:"spanKind"`
HttpRoute []string `json:"httpRoute"` HttpRoute []string `json:"httpRoute"`
HttpCode []string `json:"httpCode"` HttpCode []string `json:"httpCode"`
HttpUrl []string `json:"httpUrl"` HttpUrl []string `json:"httpUrl"`
@ -394,6 +395,7 @@ type TagFilterParams struct {
ServiceName []string `json:"serviceName"` ServiceName []string `json:"serviceName"`
HttpRoute []string `json:"httpRoute"` HttpRoute []string `json:"httpRoute"`
HttpCode []string `json:"httpCode"` HttpCode []string `json:"httpCode"`
SpanKind string `json:"spanKind"`
HttpUrl []string `json:"httpUrl"` HttpUrl []string `json:"httpUrl"`
HttpHost []string `json:"httpHost"` HttpHost []string `json:"httpHost"`
HttpMethod []string `json:"httpMethod"` HttpMethod []string `json:"httpMethod"`