import React, { useState, useEffect, useCallback } from "react"; import { agentApiService } from "@/modules/agent"; import type { LogEntry } from "@/modules/agent"; import { LogFilters } from "@/modules/agent/ui/LogFilters"; import { useLogFilterStore } from "@/modules/agent/store/logFilter.store"; import { FiFileText, FiRefreshCw, FiChevronLeft, FiChevronRight, FiInfo, FiAlertTriangle, FiAlertCircle, FiXOctagon, } from "react-icons/fi"; const logLevelIcons: Record = { INFO: , WARNING: , ERROR: , FATAL: , }; const logLevelColors: Record< string, { bg: string; text: string; border: string } > = { INFO: { bg: "var(--info-bg)", text: "var(--info-text)", border: "var(--info-border)", }, WARNING: { bg: "var(--warning-bg)", text: "var(--warning-text)", border: "var(--warning-border)", }, ERROR: { bg: "var(--error-bg)", text: "var(--error-text)", border: "var(--error-border)", }, FATAL: { bg: "var(--fatal-bg)", text: "var(--fatal-text)", border: "var(--fatal-border)", }, }; export const LogsPage: React.FC = () => { const [logs, setLogs] = useState([]); const [isLoading, setIsLoading] = useState(false); const [error, setError] = useState(null); const [availableServices, setAvailableServices] = useState([]); const [availableAgents, setAvailableAgents] = useState([]); const [totalLogs, setTotalLogs] = useState(0); const { getFilters, limit, offset, setOffset } = useLogFilterStore(); const fetchLogs = useCallback(async () => { setIsLoading(true); setError(null); try { const filters = getFilters(); const data = await agentApiService.searchLogs(filters); setLogs(data); setTotalLogs(data.length); } catch (err) { setError( err instanceof Error ? err.message : "Ошибка при загрузке логов", ); } finally { setIsLoading(false); } }, [getFilters]); const fetchDistinctData = useCallback(async () => { try { const [services, agents] = await Promise.all([ agentApiService.getDistinctServices(), agentApiService.getDistinctAgents(), ]); setAvailableServices(services); setAvailableAgents(agents); } catch (err) { console.error("Failed to fetch distinct data:", err); } }, []); useEffect(() => { fetchDistinctData(); }, [fetchDistinctData]); useEffect(() => { fetchLogs(); }, [fetchLogs, offset, limit]); const handleFilterApply = () => { setOffset(0); fetchLogs(); }; const handleNextPage = () => { setOffset(offset + limit); }; const handlePrevPage = () => { setOffset(Math.max(0, offset - limit)); }; const formatTimestamp = (timestamp: string) => { const date = new Date(timestamp); return date.toLocaleString("ru-RU", { year: "numeric", month: "2-digit", day: "2-digit", hour: "2-digit", minute: "2-digit", second: "2-digit", }); }; return (
{/* Header */}

Поиск логов

Фильтрация и анализ логов системы

{/* Filters */}
{/* Error Message */} {error && (
{error}
)} {/* Logs Table */}
{/* Table Header */}
Найдено: {totalLogs} записей
{isLoading ? (
Загрузка логов...
) : logs.length === 0 ? (
Логи не найдены
) : ( <>
{logs.map((log, index) => { const colors = logLevelColors[log.level] || logLevelColors.INFO; return ( ); })}
Время Уровень Сервис Агент Сообщение
{formatTimestamp(log.timestamp)} {logLevelIcons[log.level]} {log.level} {log.service} {log.agent} {log.message}
{/* Pagination */}
Показано {logs.length} записей (смещение: {offset})
)}
); };