From 86f020182a796f39f308a63c0e02a4dc4e4459cd Mon Sep 17 00:00:00 2001 From: gahusb Date: Thu, 28 May 2026 02:48:56 +0900 Subject: [PATCH] =?UTF-8?q?feat(agent-office/LogTab):=20source=20=EB=B1=83?= =?UTF-8?q?=EC=A7=80=20+=20access=20=EB=A9=94=ED=83=80=EB=8D=B0=EC=9D=B4?= =?UTF-8?q?=ED=84=B0=20=ED=91=9C=EC=8B=9C=20+=205=EC=B4=88=20=ED=8F=B4?= =?UTF-8?q?=EB=A7=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pages/agent-office/AgentOffice.css | 12 +++++ src/pages/agent-office/components/LogTab.jsx | 46 ++++++++++++++++---- 2 files changed, 49 insertions(+), 9 deletions(-) diff --git a/src/pages/agent-office/AgentOffice.css b/src/pages/agent-office/AgentOffice.css index ab40f58..8cfa59a 100644 --- a/src/pages/agent-office/AgentOffice.css +++ b/src/pages/agent-office/AgentOffice.css @@ -371,6 +371,18 @@ .ao-log-level { min-width: 48px; font-weight: bold; } .ao-log-msg { color: #ccc; word-break: break-all; } +.ao-log-source { + margin-left: 6px; + font-size: 0.75em; + font-weight: 600; + letter-spacing: 0.5px; +} + +.ao-log-meta { + color: #6b7280; + font-size: 0.85em; +} + /* ===== Common ===== */ .ao-empty { color: #94a3b8; diff --git a/src/pages/agent-office/components/LogTab.jsx b/src/pages/agent-office/components/LogTab.jsx index 91c8b4e..5cf9562 100644 --- a/src/pages/agent-office/components/LogTab.jsx +++ b/src/pages/agent-office/components/LogTab.jsx @@ -5,19 +5,37 @@ import { getAgentLogs } from '../../../api'; const LEVEL_STYLE = { info: { color: '#60a5fa' }, warning: { color: '#fbbf24' }, - error: { color: '#ef4444' } + error: { color: '#ef4444' }, }; +const SOURCE_STYLE = { + agent: { color: '#9ca3af', label: 'AGENT' }, + access: { color: '#5eead4', label: 'ACCESS' }, + log: { color: '#a78bfa', label: 'LOG' }, +}; + +function formatTime(iso) { + if (!iso) return ''; + return new Date(iso).toLocaleTimeString('ko-KR', { + hour: '2-digit', minute: '2-digit', second: '2-digit', + }); +} + export default function LogTab({ agentId, refreshTrigger }) { const [logs, setLogs] = useState([]); const scrollRef = useRef(null); useEffect(() => { let cancelled = false; - getAgentLogs(agentId, 50).then(data => { - if (!cancelled) setLogs(Array.isArray(data) ? data : (data?.logs || [])); - }); - return () => { cancelled = true; }; + const fetchLogs = () => { + getAgentLogs(agentId, 100).then(data => { + if (cancelled) return; + setLogs(Array.isArray(data) ? data : (data?.logs || [])); + }).catch(() => {}); + }; + fetchLogs(); + const interval = setInterval(fetchLogs, 5000); // 5초 폴링 + return () => { cancelled = true; clearInterval(interval); }; }, [agentId, refreshTrigger]); useEffect(() => { @@ -30,13 +48,23 @@ export default function LogTab({ agentId, refreshTrigger }) {
{logs.length === 0 &&
No logs yet
} {logs.map((log, i) => { - const style = LEVEL_STYLE[log.level] || LEVEL_STYLE.info; - const time = new Date(log.created_at).toLocaleTimeString('ko-KR', { hour: '2-digit', minute: '2-digit', second: '2-digit' }); + const source = log.source || 'agent'; + const sourceMeta = SOURCE_STYLE[source] || SOURCE_STYLE.agent; + const levelStyle = LEVEL_STYLE[log.level] || LEVEL_STYLE.info; + const time = formatTime(log.ts || log.created_at); return ( -
+
{time} - [{log.level}] + + [{sourceMeta.label}] + + [{log.level}] {log.message} + {source === 'access' && ( + + {' '}({log.status} · {log.ms}ms) + + )}
); })}