feat: wire up application logs from OpenSearch, fix event autoscroll
Add GET /api/v1/logs endpoint to query application logs stored in OpenSearch with filters for application, agent, level, time range, and text search. Wire up the AgentInstance LogViewer with real data and an EventFeed-style toolbar (search input + level filter pills). Fix agent events timeline autoscroll by reversing the DESC-ordered events so newest entries appear at the bottom where EventFeed autoscrolls to. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
46
ui/src/api/queries/logs.ts
Normal file
46
ui/src/api/queries/logs.ts
Normal file
@@ -0,0 +1,46 @@
|
||||
import { useQuery } from '@tanstack/react-query';
|
||||
import { config } from '../../config';
|
||||
import { useAuthStore } from '../../auth/auth-store';
|
||||
import { useRefreshInterval } from './use-refresh-interval';
|
||||
import { useGlobalFilters } from '@cameleer/design-system';
|
||||
|
||||
export interface LogEntryResponse {
|
||||
timestamp: string;
|
||||
level: string;
|
||||
loggerName: string | null;
|
||||
message: string;
|
||||
threadName: string | null;
|
||||
stackTrace: string | null;
|
||||
}
|
||||
|
||||
export function useApplicationLogs(
|
||||
application?: string,
|
||||
agentId?: string,
|
||||
options?: { limit?: number },
|
||||
) {
|
||||
const refetchInterval = useRefreshInterval(15_000);
|
||||
const { timeRange } = useGlobalFilters();
|
||||
|
||||
return useQuery({
|
||||
queryKey: ['logs', application, agentId, timeRange.start.toISOString(), timeRange.end.toISOString(), options?.limit],
|
||||
queryFn: async () => {
|
||||
const token = useAuthStore.getState().accessToken;
|
||||
const params = new URLSearchParams();
|
||||
params.set('application', application!);
|
||||
if (agentId) params.set('agentId', agentId);
|
||||
params.set('from', timeRange.start.toISOString());
|
||||
params.set('to', timeRange.end.toISOString());
|
||||
if (options?.limit) params.set('limit', String(options.limit));
|
||||
const res = await fetch(`${config.apiBaseUrl}/logs?${params}`, {
|
||||
headers: {
|
||||
Authorization: `Bearer ${token}`,
|
||||
'X-Cameleer-Protocol-Version': '1',
|
||||
},
|
||||
});
|
||||
if (!res.ok) throw new Error('Failed to load application logs');
|
||||
return res.json() as Promise<LogEntryResponse[]>;
|
||||
},
|
||||
enabled: !!application,
|
||||
refetchInterval,
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user