mirror of
https://git.mirrors.martin98.com/https://github.com/SigNoz/signoz
synced 2025-08-12 10:09:02 +08:00
feat: added domain level and endpoint level stats
This commit is contained in:
parent
1123a9a93d
commit
552b103e8b
@ -13,10 +13,11 @@ import QueryBuilderSearchV2 from 'container/QueryBuilder/filters/QueryBuilderSea
|
|||||||
// Time,
|
// Time,
|
||||||
// } from 'container/TopNav/DateTimeSelectionV2/config';
|
// } from 'container/TopNav/DateTimeSelectionV2/config';
|
||||||
import { GetMetricQueryRange } from 'lib/dashboard/getQueryResults';
|
import { GetMetricQueryRange } from 'lib/dashboard/getQueryResults';
|
||||||
import { useMemo, useState } from 'react';
|
import { useCallback, useEffect, useMemo, useState } from 'react';
|
||||||
import { useQueries } from 'react-query';
|
import { useQueries } from 'react-query';
|
||||||
import { SuccessResponse } from 'types/api';
|
import { SuccessResponse } from 'types/api';
|
||||||
import { MetricRangePayloadProps } from 'types/api/metrics/getQueryRange';
|
import { MetricRangePayloadProps } from 'types/api/metrics/getQueryRange';
|
||||||
|
import { DataTypes } from 'types/api/queryBuilder/queryAutocompleteResponse';
|
||||||
import { IBuilderQuery } from 'types/api/queryBuilder/queryBuilderData';
|
import { IBuilderQuery } from 'types/api/queryBuilder/queryBuilderData';
|
||||||
import { DataSource } from 'types/common/queryBuilder';
|
import { DataSource } from 'types/common/queryBuilder';
|
||||||
|
|
||||||
@ -27,6 +28,15 @@ import MetricOverTimeGraph from './components/MetricOverTimeGraph';
|
|||||||
import StatusCodeBarCharts from './components/StatusCodeBarCharts';
|
import StatusCodeBarCharts from './components/StatusCodeBarCharts';
|
||||||
import StatusCodeTable from './components/StatusCodeTable';
|
import StatusCodeTable from './components/StatusCodeTable';
|
||||||
|
|
||||||
|
const httpUrlKey = {
|
||||||
|
dataType: DataTypes.String,
|
||||||
|
id: 'http.url--string--tag--false',
|
||||||
|
isColumn: false,
|
||||||
|
isJSON: false,
|
||||||
|
key: 'http.url',
|
||||||
|
type: 'tag',
|
||||||
|
};
|
||||||
|
|
||||||
function EndPointDetails({
|
function EndPointDetails({
|
||||||
domainName,
|
domainName,
|
||||||
endPointName,
|
endPointName,
|
||||||
@ -52,16 +62,72 @@ function EndPointDetails({
|
|||||||
|
|
||||||
const currentQuery = initialQueriesMap[DataSource.TRACES];
|
const currentQuery = initialQueriesMap[DataSource.TRACES];
|
||||||
|
|
||||||
const [filters, setFilters] = useState<IBuilderQuery['filters']>({
|
// Local state for filters, combining endpoint filter and search filters
|
||||||
op: 'AND',
|
const [filters, setFilters] = useState<IBuilderQuery['filters']>(() => {
|
||||||
items: [],
|
// Initialize filters based on the initial endPointName prop
|
||||||
|
const initialItems = [];
|
||||||
|
if (endPointName) {
|
||||||
|
initialItems.push({
|
||||||
|
id: '92b8a1c1',
|
||||||
|
key: httpUrlKey,
|
||||||
|
op: '=',
|
||||||
|
value: endPointName,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return { op: 'AND', items: initialItems };
|
||||||
});
|
});
|
||||||
// [TODO] if endPointName is there then add it to the filters under http.url key
|
|
||||||
|
|
||||||
// Manually update the query to include the filters
|
// Effect to synchronize local filters when the endPointName prop changes (e.g., from dropdown)
|
||||||
// Because using the hook is causing the global domain
|
useEffect(() => {
|
||||||
// query to be updated and causing main domain list to
|
setFilters((currentFilters) => {
|
||||||
// refetch with the filters of endpoints
|
const existingHttpUrlFilter = currentFilters.items.find(
|
||||||
|
(item) => item.key?.key === httpUrlKey.key,
|
||||||
|
);
|
||||||
|
const existingHttpUrlValue = (existingHttpUrlFilter?.value as string) || '';
|
||||||
|
|
||||||
|
// Only update filters if the prop value is different from what's already in filters
|
||||||
|
if (endPointName === existingHttpUrlValue) {
|
||||||
|
return currentFilters; // No change needed, prevents loop
|
||||||
|
}
|
||||||
|
|
||||||
|
// Rebuild filters: Keep non-http.url filters and add/update http.url filter based on prop
|
||||||
|
const otherFilters = currentFilters.items.filter(
|
||||||
|
(item) => item.key?.key !== httpUrlKey.key,
|
||||||
|
);
|
||||||
|
const newItems = [...otherFilters];
|
||||||
|
if (endPointName) {
|
||||||
|
newItems.push({
|
||||||
|
id: '92b8a1c1',
|
||||||
|
key: httpUrlKey,
|
||||||
|
op: '=',
|
||||||
|
value: endPointName,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return { op: 'AND', items: newItems };
|
||||||
|
});
|
||||||
|
}, [endPointName]);
|
||||||
|
|
||||||
|
// Handler for changes from the QueryBuilderSearchV2 component
|
||||||
|
const handleFilterChange = useCallback(
|
||||||
|
(newFilters: IBuilderQuery['filters']): void => {
|
||||||
|
// 1. Update local filters state immediately
|
||||||
|
setFilters(newFilters);
|
||||||
|
|
||||||
|
// 2. Derive the endpoint name from the *new* filters state
|
||||||
|
const httpUrlFilter = newFilters.items.find(
|
||||||
|
(item) => item.key?.key === httpUrlKey.key,
|
||||||
|
);
|
||||||
|
const derivedEndPointName = (httpUrlFilter?.value as string) || '';
|
||||||
|
|
||||||
|
// 3. If the derived endpoint name is different from the current prop,
|
||||||
|
// it means the search change modified the effective endpoint.
|
||||||
|
// Notify the parent component.
|
||||||
|
if (derivedEndPointName !== endPointName) {
|
||||||
|
setSelectedEndPointName(derivedEndPointName);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
[endPointName, setSelectedEndPointName], // Dependencies for the callback
|
||||||
|
);
|
||||||
|
|
||||||
const updatedCurrentQuery = useMemo(
|
const updatedCurrentQuery = useMemo(
|
||||||
() => ({
|
() => ({
|
||||||
@ -72,7 +138,7 @@ function EndPointDetails({
|
|||||||
{
|
{
|
||||||
...currentQuery.builder.queryData[0],
|
...currentQuery.builder.queryData[0],
|
||||||
dataSource: DataSource.TRACES,
|
dataSource: DataSource.TRACES,
|
||||||
filters,
|
filters, // Use the local filters state
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
@ -97,7 +163,7 @@ function EndPointDetails({
|
|||||||
queryKey: [
|
queryKey: [
|
||||||
END_POINT_DETAILS_QUERY_KEYS_ARRAY[index],
|
END_POINT_DETAILS_QUERY_KEYS_ARRAY[index],
|
||||||
payload,
|
payload,
|
||||||
filters.items,
|
filters.items, // Include filters.items in queryKey for better caching
|
||||||
ENTITY_VERSION_V4,
|
ENTITY_VERSION_V4,
|
||||||
],
|
],
|
||||||
queryFn: (): Promise<SuccessResponse<MetricRangePayloadProps>> =>
|
queryFn: (): Promise<SuccessResponse<MetricRangePayloadProps>> =>
|
||||||
@ -126,22 +192,25 @@ function EndPointDetails({
|
|||||||
);
|
);
|
||||||
|
|
||||||
const { endpoint, port } = useMemo(
|
const { endpoint, port } = useMemo(
|
||||||
() => extractPortAndEndpoint(endPointName),
|
() => extractPortAndEndpoint(endPointName), // Derive display info from the prop
|
||||||
[endPointName],
|
[endPointName],
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// Combine domainListFilters (from parent) and local filters for graph/chart queries
|
||||||
|
const combinedFilters = useMemo(
|
||||||
|
() => ({
|
||||||
|
op: 'AND', // Assuming AND logic for combining filter sets
|
||||||
|
items: [...domainListFilters.items, ...filters.items],
|
||||||
|
}),
|
||||||
|
[domainListFilters, filters],
|
||||||
|
);
|
||||||
|
|
||||||
const [rateOverTimeWidget, latencyOverTimeWidget] = useMemo(
|
const [rateOverTimeWidget, latencyOverTimeWidget] = useMemo(
|
||||||
() => [
|
() => [
|
||||||
getRateOverTimeWidgetData(domainName, endPointName, {
|
getRateOverTimeWidgetData(domainName, endPointName, combinedFilters),
|
||||||
items: [...domainListFilters.items, ...filters.items],
|
getLatencyOverTimeWidgetData(domainName, endPointName, combinedFilters),
|
||||||
op: filters.op,
|
|
||||||
}),
|
|
||||||
getLatencyOverTimeWidgetData(domainName, endPointName, {
|
|
||||||
items: [...domainListFilters.items, ...filters.items],
|
|
||||||
op: filters.op,
|
|
||||||
}),
|
|
||||||
],
|
],
|
||||||
[domainName, endPointName, filters, domainListFilters],
|
[domainName, endPointName, combinedFilters], // Use combinedFilters
|
||||||
);
|
);
|
||||||
|
|
||||||
// // [TODO] Fix this later
|
// // [TODO] Fix this later
|
||||||
@ -173,9 +242,7 @@ function EndPointDetails({
|
|||||||
<div className="endpoint-details-filters-container-search">
|
<div className="endpoint-details-filters-container-search">
|
||||||
<QueryBuilderSearchV2
|
<QueryBuilderSearchV2
|
||||||
query={query}
|
query={query}
|
||||||
onChange={(searchFilters): void => {
|
onChange={handleFilterChange}
|
||||||
setFilters(searchFilters);
|
|
||||||
}}
|
|
||||||
placeholder="Search for filters..."
|
placeholder="Search for filters..."
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user