2025-01-21 21:57:32 +05:30
|
|
|
import './entityTraces.styles.scss';
|
2025-01-08 16:13:54 +05:30
|
|
|
|
2025-03-24 14:21:51 +05:30
|
|
|
import logEvent from 'api/common/logEvent';
|
2025-01-08 16:13:54 +05:30
|
|
|
import { getListColumns } from 'components/HostMetricsDetail/HostMetricTraces/utils';
|
|
|
|
|
import { ResizeTable } from 'components/ResizeTable';
|
|
|
|
|
import { DEFAULT_ENTITY_VERSION } from 'constants/app';
|
2025-03-24 14:21:51 +05:30
|
|
|
import { InfraMonitoringEvents } from 'constants/events';
|
2025-01-08 16:13:54 +05:30
|
|
|
import { QueryParams } from 'constants/query';
|
|
|
|
|
import EmptyLogsSearch from 'container/EmptyLogsSearch/EmptyLogsSearch';
|
|
|
|
|
import NoLogs from 'container/NoLogs/NoLogs';
|
|
|
|
|
import QueryBuilderSearch from 'container/QueryBuilder/filters/QueryBuilderSearch';
|
|
|
|
|
import { ErrorText } from 'container/TimeSeriesView/styles';
|
|
|
|
|
import DateTimeSelectionV2 from 'container/TopNav/DateTimeSelectionV2';
|
|
|
|
|
import {
|
|
|
|
|
CustomTimeType,
|
|
|
|
|
Time,
|
|
|
|
|
} from 'container/TopNav/DateTimeSelectionV2/config';
|
|
|
|
|
import TraceExplorerControls from 'container/TracesExplorer/Controls';
|
|
|
|
|
import { PER_PAGE_OPTIONS } from 'container/TracesExplorer/ListView/configs';
|
|
|
|
|
import { TracesLoading } from 'container/TracesExplorer/TraceLoading/TraceLoading';
|
|
|
|
|
import { useQueryBuilder } from 'hooks/queryBuilder/useQueryBuilder';
|
|
|
|
|
import { Pagination } from 'hooks/queryPagination';
|
|
|
|
|
import useUrlQueryData from 'hooks/useUrlQueryData';
|
|
|
|
|
import { GetMetricQueryRange } from 'lib/dashboard/getQueryResults';
|
2025-03-24 14:21:51 +05:30
|
|
|
import { useCallback, useEffect, useMemo, useState } from 'react';
|
2025-01-08 16:13:54 +05:30
|
|
|
import { useQuery } from 'react-query';
|
|
|
|
|
import { IBuilderQuery } from 'types/api/queryBuilder/queryBuilderData';
|
|
|
|
|
import { DataSource } from 'types/common/queryBuilder';
|
|
|
|
|
|
2025-01-21 21:57:32 +05:30
|
|
|
import {
|
2025-02-05 18:18:35 +05:30
|
|
|
filterOutPrimaryFilters,
|
2025-01-21 21:57:32 +05:30
|
|
|
getEntityTracesQueryPayload,
|
|
|
|
|
selectedEntityTracesColumns,
|
|
|
|
|
} from '../utils';
|
2025-01-08 16:13:54 +05:30
|
|
|
|
|
|
|
|
interface Props {
|
|
|
|
|
timeRange: {
|
|
|
|
|
startTime: number;
|
|
|
|
|
endTime: number;
|
|
|
|
|
};
|
|
|
|
|
isModalTimeSelection: boolean;
|
|
|
|
|
handleTimeChange: (
|
|
|
|
|
interval: Time | CustomTimeType,
|
|
|
|
|
dateTimeRange?: [number, number],
|
|
|
|
|
) => void;
|
|
|
|
|
handleChangeTracesFilters: (value: IBuilderQuery['filters']) => void;
|
|
|
|
|
tracesFilters: IBuilderQuery['filters'];
|
|
|
|
|
selectedInterval: Time;
|
2025-01-21 21:57:32 +05:30
|
|
|
queryKey: string;
|
2025-03-24 14:21:51 +05:30
|
|
|
category: string;
|
2025-02-05 18:18:35 +05:30
|
|
|
queryKeyFilters: string[];
|
2025-01-08 16:13:54 +05:30
|
|
|
}
|
|
|
|
|
|
2025-01-21 21:57:32 +05:30
|
|
|
function EntityTraces({
|
2025-01-08 16:13:54 +05:30
|
|
|
timeRange,
|
|
|
|
|
isModalTimeSelection,
|
|
|
|
|
handleTimeChange,
|
|
|
|
|
handleChangeTracesFilters,
|
|
|
|
|
tracesFilters,
|
|
|
|
|
selectedInterval,
|
2025-01-21 21:57:32 +05:30
|
|
|
queryKey,
|
2025-03-24 14:21:51 +05:30
|
|
|
category,
|
2025-02-05 18:18:35 +05:30
|
|
|
queryKeyFilters,
|
2025-01-08 16:13:54 +05:30
|
|
|
}: Props): JSX.Element {
|
|
|
|
|
const [traces, setTraces] = useState<any[]>([]);
|
|
|
|
|
const [offset] = useState<number>(0);
|
|
|
|
|
|
|
|
|
|
const { currentQuery } = useQueryBuilder();
|
|
|
|
|
const updatedCurrentQuery = useMemo(
|
|
|
|
|
() => ({
|
|
|
|
|
...currentQuery,
|
|
|
|
|
builder: {
|
|
|
|
|
...currentQuery.builder,
|
|
|
|
|
queryData: [
|
|
|
|
|
{
|
|
|
|
|
...currentQuery.builder.queryData[0],
|
|
|
|
|
dataSource: DataSource.TRACES,
|
|
|
|
|
aggregateOperator: 'noop',
|
|
|
|
|
aggregateAttribute: {
|
|
|
|
|
...currentQuery.builder.queryData[0].aggregateAttribute,
|
|
|
|
|
},
|
|
|
|
|
filters: {
|
2025-02-05 18:18:35 +05:30
|
|
|
items: filterOutPrimaryFilters(tracesFilters.items, queryKeyFilters),
|
2025-01-08 16:13:54 +05:30
|
|
|
op: 'AND',
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
],
|
|
|
|
|
},
|
|
|
|
|
}),
|
2025-02-05 18:18:35 +05:30
|
|
|
[currentQuery, queryKeyFilters, tracesFilters.items],
|
2025-01-08 16:13:54 +05:30
|
|
|
);
|
|
|
|
|
|
|
|
|
|
const query = updatedCurrentQuery?.builder?.queryData[0] || null;
|
|
|
|
|
|
|
|
|
|
const { queryData: paginationQueryData } = useUrlQueryData<Pagination>(
|
|
|
|
|
QueryParams.pagination,
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
const queryPayload = useMemo(
|
|
|
|
|
() =>
|
2025-01-21 21:57:32 +05:30
|
|
|
getEntityTracesQueryPayload(
|
2025-01-08 16:13:54 +05:30
|
|
|
timeRange.startTime,
|
|
|
|
|
timeRange.endTime,
|
|
|
|
|
paginationQueryData?.offset || offset,
|
|
|
|
|
tracesFilters,
|
|
|
|
|
),
|
|
|
|
|
[
|
|
|
|
|
timeRange.startTime,
|
|
|
|
|
timeRange.endTime,
|
|
|
|
|
offset,
|
|
|
|
|
tracesFilters,
|
|
|
|
|
paginationQueryData,
|
|
|
|
|
],
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
const { data, isLoading, isFetching, isError } = useQuery({
|
|
|
|
|
queryKey: [
|
2025-01-21 21:57:32 +05:30
|
|
|
queryKey,
|
2025-01-08 16:13:54 +05:30
|
|
|
timeRange.startTime,
|
|
|
|
|
timeRange.endTime,
|
|
|
|
|
offset,
|
|
|
|
|
tracesFilters,
|
|
|
|
|
DEFAULT_ENTITY_VERSION,
|
|
|
|
|
paginationQueryData,
|
|
|
|
|
],
|
|
|
|
|
queryFn: () => GetMetricQueryRange(queryPayload, DEFAULT_ENTITY_VERSION),
|
|
|
|
|
enabled: !!queryPayload,
|
|
|
|
|
});
|
|
|
|
|
|
2025-01-21 21:57:32 +05:30
|
|
|
const traceListColumns = getListColumns(selectedEntityTracesColumns);
|
2025-01-08 16:13:54 +05:30
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
if (data?.payload?.data?.newResult?.data?.result) {
|
|
|
|
|
const currentData = data.payload.data.newResult.data.result;
|
|
|
|
|
if (currentData.length > 0 && currentData[0].list) {
|
|
|
|
|
if (offset === 0) {
|
|
|
|
|
setTraces(currentData[0].list ?? []);
|
|
|
|
|
} else {
|
|
|
|
|
setTraces((prev) => [...prev, ...(currentData[0].list ?? [])]);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}, [data, offset]);
|
|
|
|
|
|
|
|
|
|
const isDataEmpty =
|
|
|
|
|
!isLoading && !isFetching && !isError && traces.length === 0;
|
|
|
|
|
const hasAdditionalFilters = tracesFilters.items.length > 1;
|
|
|
|
|
|
|
|
|
|
const totalCount =
|
|
|
|
|
data?.payload?.data?.newResult?.data?.result?.[0]?.list?.length || 0;
|
|
|
|
|
|
2025-03-24 14:21:51 +05:30
|
|
|
const handleRowClick = useCallback(() => {
|
|
|
|
|
logEvent(InfraMonitoringEvents.ItemClicked, {
|
|
|
|
|
entity: InfraMonitoringEvents.K8sEntity,
|
|
|
|
|
category,
|
|
|
|
|
view: InfraMonitoringEvents.TracesView,
|
|
|
|
|
});
|
|
|
|
|
}, [category]);
|
|
|
|
|
|
2025-01-08 16:13:54 +05:30
|
|
|
return (
|
2025-01-21 21:57:32 +05:30
|
|
|
<div className="entity-metric-traces">
|
|
|
|
|
<div className="entity-metric-traces-header">
|
2025-01-08 16:13:54 +05:30
|
|
|
<div className="filter-section">
|
|
|
|
|
{query && (
|
|
|
|
|
<QueryBuilderSearch
|
|
|
|
|
query={query}
|
|
|
|
|
onChange={handleChangeTracesFilters}
|
|
|
|
|
disableNavigationShortcuts
|
|
|
|
|
/>
|
|
|
|
|
)}
|
|
|
|
|
</div>
|
|
|
|
|
<div className="datetime-section">
|
|
|
|
|
<DateTimeSelectionV2
|
|
|
|
|
showAutoRefresh={false}
|
|
|
|
|
showRefreshText={false}
|
|
|
|
|
hideShareModal
|
|
|
|
|
isModalTimeSelection={isModalTimeSelection}
|
|
|
|
|
onTimeChange={handleTimeChange}
|
|
|
|
|
defaultRelativeTime="5m"
|
|
|
|
|
modalSelectedInterval={selectedInterval}
|
|
|
|
|
/>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
{isError && <ErrorText>{data?.error || 'Something went wrong'}</ErrorText>}
|
|
|
|
|
|
|
|
|
|
{isLoading && traces.length === 0 && <TracesLoading />}
|
|
|
|
|
|
|
|
|
|
{isDataEmpty && !hasAdditionalFilters && (
|
|
|
|
|
<NoLogs dataSource={DataSource.TRACES} />
|
|
|
|
|
)}
|
|
|
|
|
|
|
|
|
|
{isDataEmpty && hasAdditionalFilters && (
|
|
|
|
|
<EmptyLogsSearch dataSource={DataSource.TRACES} panelType="LIST" />
|
|
|
|
|
)}
|
|
|
|
|
|
|
|
|
|
{!isError && traces.length > 0 && (
|
2025-01-21 21:57:32 +05:30
|
|
|
<div className="entity-traces-table">
|
2025-01-08 16:13:54 +05:30
|
|
|
<TraceExplorerControls
|
|
|
|
|
isLoading={isFetching}
|
|
|
|
|
totalCount={totalCount}
|
|
|
|
|
perPageOptions={PER_PAGE_OPTIONS}
|
|
|
|
|
showSizeChanger={false}
|
|
|
|
|
/>
|
|
|
|
|
<ResizeTable
|
|
|
|
|
tableLayout="fixed"
|
|
|
|
|
pagination={false}
|
|
|
|
|
scroll={{ x: true }}
|
|
|
|
|
loading={isFetching}
|
|
|
|
|
dataSource={traces}
|
|
|
|
|
columns={traceListColumns}
|
2025-03-24 14:21:51 +05:30
|
|
|
onRow={(): Record<string, unknown> => ({
|
|
|
|
|
onClick: (): void => handleRowClick(),
|
|
|
|
|
})}
|
2025-01-08 16:13:54 +05:30
|
|
|
/>
|
|
|
|
|
</div>
|
|
|
|
|
)}
|
|
|
|
|
</div>
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
2025-01-21 21:57:32 +05:30
|
|
|
export default EntityTraces;
|