Skip to content

Commit 1bdf8cf

Browse files
fix(log_filter_logic.tsx): fix searching for end user logs, globally
ensures filters work outside of initial loaded page
1 parent 6745e9f commit 1bdf8cf

File tree

1 file changed

+48
-28
lines changed

1 file changed

+48
-28
lines changed

ui/litellm-dashboard/src/components/view_logs/log_filter_logic.tsx

Lines changed: 48 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,13 @@ export function useLogFilterLogic({
5555
}), []);
5656

5757
const [filters, setFilters] = useState<LogFilterState>(defaultFilters);
58-
const [filteredLogs, setFilteredLogs] = useState<PaginatedResponse>(logs);
58+
const [backendFilteredLogs, setBackendFilteredLogs] = useState<PaginatedResponse>({
59+
data: [],
60+
total: 0,
61+
page: 1,
62+
page_size: 50,
63+
total_pages: 0
64+
});
5965
const lastSearchTimestamp = useRef(0);
6066
const performSearch = useCallback(async (filters: LogFilterState, page = 1) => {
6167
if (!accessToken) return;
@@ -87,7 +93,7 @@ export function useLogFilterLogic({
8793
);
8894

8995
if (currentTimestamp === lastSearchTimestamp.current && response.data) {
90-
setFilteredLogs(response);
96+
setBackendFilteredLogs(response);
9197
}
9298
} catch (error) {
9399
console.error("Error searching users:", error);
@@ -113,34 +119,36 @@ export function useLogFilterLogic({
113119
});
114120
const allKeyAliases = queryAllKeysQuery.data || []
115121

116-
// Apply filters to keys whenever logs or filters change
117-
useEffect(() => {
122+
// Determine when backend filters are active (server-side filtering)
123+
const hasBackendFilters = useMemo(() => (
124+
!!(
125+
filters[FILTER_KEYS.KEY_ALIAS] ||
126+
filters[FILTER_KEYS.KEY_HASH] ||
127+
filters[FILTER_KEYS.REQUEST_ID] ||
128+
filters[FILTER_KEYS.USER_ID] ||
129+
filters[FILTER_KEYS.END_USER]
130+
)
131+
), [filters]);
132+
133+
// Compute client-side filtered logs directly from incoming logs and filters
134+
const clientDerivedFilteredLogs: PaginatedResponse = useMemo(() => {
118135
if (!logs || !logs.data) {
119-
setFilteredLogs({
136+
return {
120137
data: [],
121138
total: 0,
122139
page: 1,
123140
page_size: 50,
124141
total_pages: 0
125-
});
126-
return;
142+
};
127143
}
128144

129-
// Only do client-side filtering if no backend filters are active
130-
const hasBackendFilters =
131-
filters[FILTER_KEYS.KEY_ALIAS] ||
132-
filters[FILTER_KEYS.KEY_HASH] ||
133-
filters[FILTER_KEYS.REQUEST_ID] ||
134-
filters[FILTER_KEYS.USER_ID] ||
135-
filters[FILTER_KEYS.END_USER];
136-
145+
// If backend filters are on, don't perform client-side filtering here
137146
if (hasBackendFilters) {
138-
// Backend is handling filtering, don't override the results
139-
return;
147+
return logs;
140148
}
141-
149+
142150
let filteredData = [...logs.data];
143-
151+
144152
if (filters[FILTER_KEYS.TEAM_ID]) {
145153
filteredData = filteredData.filter(
146154
log => log.team_id === filters[FILTER_KEYS.TEAM_ID]
@@ -163,7 +171,7 @@ export function useLogFilterLogic({
163171
log => log.model === filters[FILTER_KEYS.MODEL]
164172
);
165173
}
166-
174+
167175
if (filters[FILTER_KEYS.KEY_HASH]) {
168176
filteredData = filteredData.filter(
169177
log => log.api_key === filters[FILTER_KEYS.KEY_HASH]
@@ -175,21 +183,33 @@ export function useLogFilterLogic({
175183
log => log.end_user === filters[FILTER_KEYS.END_USER]
176184
);
177185
}
178-
179-
const newFilteredLogs: PaginatedResponse = {
186+
187+
return {
180188
data: filteredData,
181189
total: logs.total,
182190
page: logs.page,
183191
page_size: logs.page_size,
184192
total_pages: logs.total_pages,
185193
};
186-
187-
if (JSON.stringify(newFilteredLogs) !== JSON.stringify(filteredLogs)) {
188-
setFilteredLogs(newFilteredLogs);
189-
}
190-
}, [logs, filters, filteredLogs, accessToken]);
194+
}, [logs, filters, hasBackendFilters]);
191195

192-
196+
// Choose which filtered logs to expose: backend result when active, otherwise client-derived
197+
const filteredLogs: PaginatedResponse = useMemo(() => {
198+
if (hasBackendFilters) {
199+
// Prefer backend result if present; otherwise fall back to latest logs
200+
if (backendFilteredLogs && backendFilteredLogs.data && backendFilteredLogs.data.length > 0) {
201+
return backendFilteredLogs;
202+
}
203+
return logs || {
204+
data: [],
205+
total: 0,
206+
page: 1,
207+
page_size: 50,
208+
total_pages: 0
209+
};
210+
}
211+
return clientDerivedFilteredLogs;
212+
}, [hasBackendFilters, backendFilteredLogs, clientDerivedFilteredLogs, logs]);
193213

194214
// Fetch all teams and users for potential filter dropdowns (optional, can be adapted)
195215
const { data: allTeams } = useQuery<Team[], Error>({

0 commit comments

Comments
 (0)