diff --git a/frontend/src/modules/agent/api/agent.api.service.ts b/frontend/src/modules/agent/api/agent.api.service.ts index 14aacd2..db258e8 100644 --- a/frontend/src/modules/agent/api/agent.api.service.ts +++ b/frontend/src/modules/agent/api/agent.api.service.ts @@ -45,20 +45,17 @@ class AgentApiService { } async searchLogs(filters?: LogFilters): Promise { - const response = await apiClient.get( - `${this.logsBasePath}/mock`, - { - params: { - level: filters?.level, - service: filters?.service, - agent: filters?.agent, - date_from: filters?.date_from, - date_to: filters?.date_to, - limit: filters?.limit ?? 100, - offset: filters?.offset ?? 0, - }, + const response = await apiClient.get(this.logsBasePath, { + params: { + level: filters?.level, + service: filters?.service, + agent: filters?.agent, + date_from: filters?.date_from, + date_to: filters?.date_to, + limit: filters?.limit ?? 100, + offset: filters?.offset ?? 0, }, - ); + }); return response.data; } diff --git a/frontend/src/pages/logs.page.tsx b/frontend/src/pages/logs.page.tsx index 6b2b824..0ec9256 100644 --- a/frontend/src/pages/logs.page.tsx +++ b/frontend/src/pages/logs.page.tsx @@ -63,12 +63,20 @@ export const LogsPage: React.FC = () => { try { const filters = getFilters(); const data = await agentApiService.searchLogs(filters); + if (!Array.isArray(data)) { + console.error("[Logs] Expected array, got:", typeof data); + setLogs([]); + setTotalLogs(0); + return; + } setLogs(data); setTotalLogs(data.length); } catch (err) { setError( err instanceof Error ? err.message : "Ошибка при загрузке логов", ); + setLogs([]); + setTotalLogs(0); } finally { setIsLoading(false); } @@ -76,14 +84,44 @@ export const LogsPage: React.FC = () => { const fetchDistinctData = useCallback(async () => { try { - const [services, agents] = await Promise.all([ + const [servicesResult, agentsResult] = await Promise.allSettled([ agentApiService.getDistinctServices(), agentApiService.getDistinctAgents(), ]); - setAvailableServices(services); - setAvailableAgents(agents); + + if ( + servicesResult.status === "fulfilled" && + Array.isArray(servicesResult.value) + ) { + setAvailableServices(servicesResult.value); + } else { + console.error( + "[Logs] Failed to fetch services:", + servicesResult.status === "rejected" + ? servicesResult.reason + : "non-array response", + ); + setAvailableServices([]); + } + + if ( + agentsResult.status === "fulfilled" && + Array.isArray(agentsResult.value) + ) { + setAvailableAgents(agentsResult.value); + } else { + console.error( + "[Logs] Failed to fetch agents:", + agentsResult.status === "rejected" + ? agentsResult.reason + : "non-array response", + ); + setAvailableAgents([]); + } } catch (err) { - console.error("Failed to fetch distinct data:", err); + console.error("[Logs] Failed to fetch distinct data:", err); + setAvailableServices([]); + setAvailableAgents([]); } }, []); @@ -108,8 +146,10 @@ export const LogsPage: React.FC = () => { setOffset(Math.max(0, offset - limit)); }; - const formatTimestamp = (timestamp: string) => { + const formatTimestamp = (timestamp: string | undefined | null) => { + if (!timestamp) return "—"; const date = new Date(timestamp); + if (isNaN(date.getTime())) return "—"; return date.toLocaleString("ru-RU", { year: "numeric", month: "2-digit", @@ -266,8 +306,9 @@ export const LogsPage: React.FC = () => { {logs.map((log, index) => { + const level = log.level || "INFO"; const colors = - logLevelColors[log.level] || logLevelColors.INFO; + logLevelColors[level] || logLevelColors.INFO; return ( { borderColor: colors.border, }} > - {logLevelIcons[log.level]} - {log.level} + {logLevelIcons[level]} + {level} - {log.service} + {log.service || "—"} - {log.agent} + {log.agent || "—"} - {log.message} + {log.message || "—"} );