From eb62c80daf904c81c5337bc06f19a1a05419dc22 Mon Sep 17 00:00:00 2001 From: hsiegeln <37154749+hsiegeln@users.noreply.github.com> Date: Tue, 24 Mar 2026 15:22:41 +0100 Subject: [PATCH] refactor: use LogViewer in AgentInstance page Replace custom log entry rendering (MonoText, Badge, per-entry HTML) with the LogViewer composite component. Map mock data to LogEntry interface, remove formatLogTime helper, and clean up unused CSS classes and imports (Card, CodeBlock, ProgressBar, sectionHeaderRow, sectionTitle, fdRow). Co-Authored-By: Claude Opus 4.6 (1M context) --- .../AgentInstance/AgentInstance.module.css | 67 +------------------ src/pages/AgentInstance/AgentInstance.tsx | 50 +++++--------- 2 files changed, 16 insertions(+), 101 deletions(-) diff --git a/src/pages/AgentInstance/AgentInstance.module.css b/src/pages/AgentInstance/AgentInstance.module.css index 2028ac8..1048005 100644 --- a/src/pages/AgentInstance/AgentInstance.module.css +++ b/src/pages/AgentInstance/AgentInstance.module.css @@ -51,20 +51,6 @@ font-family: var(--font-mono); } -/* Section header — matches /agents */ -.sectionHeaderRow { - display: flex; - align-items: center; - gap: 8px; - margin-bottom: 12px; -} - -.sectionTitle { - font-size: 13px; - font-weight: 600; - color: var(--text-primary); -} - /* Charts 3x2 grid */ .chartsGrid { display: grid; @@ -125,12 +111,6 @@ font-weight: 500; } -.fdRow { - display: flex; - align-items: center; - gap: 8px; -} - /* Log + Timeline side by side */ .bottomRow { display: grid; @@ -155,52 +135,7 @@ border-bottom: 1px solid var(--border-subtle); } -.logEntries { - max-height: 360px; - overflow-y: auto; - font-size: 11px; -} - -.logEntry { - display: flex; - align-items: flex-start; - gap: 8px; - padding: 5px 16px; - border-bottom: 1px solid var(--border-subtle); - font-family: var(--font-mono); - transition: background 0.1s; -} - -.logEntry:hover { - background: var(--bg-hover); -} - -.logEntry:last-child { - border-bottom: none; -} - -.logTime { - flex-shrink: 0; - color: var(--text-muted); - min-width: 60px; -} - -.logLogger { - flex-shrink: 0; - color: var(--text-faint); - max-width: 220px; - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; -} - -.logMsg { - color: var(--text-primary); - font-family: var(--font-mono); - font-size: 11px; - word-break: break-word; -} - +/* Empty state (shared) */ .logEmpty { padding: 24px; text-align: center; diff --git a/src/pages/AgentInstance/AgentInstance.tsx b/src/pages/AgentInstance/AgentInstance.tsx index 2c4f19b..bdcd538 100644 --- a/src/pages/AgentInstance/AgentInstance.tsx +++ b/src/pages/AgentInstance/AgentInstance.tsx @@ -12,16 +12,15 @@ import { LineChart } from '../../design-system/composites/LineChart/LineChart' import { AreaChart } from '../../design-system/composites/AreaChart/AreaChart' import { EventFeed } from '../../design-system/composites/EventFeed/EventFeed' import { Tabs } from '../../design-system/composites/Tabs/Tabs' +import { LogViewer } from '../../design-system/composites/LogViewer/LogViewer' +import type { LogEntry } from '../../design-system/composites/LogViewer/LogViewer' // Primitives import { StatusDot } from '../../design-system/primitives/StatusDot/StatusDot' import { MonoText } from '../../design-system/primitives/MonoText/MonoText' import { Badge } from '../../design-system/primitives/Badge/Badge' import { StatCard } from '../../design-system/primitives/StatCard/StatCard' -import { ProgressBar } from '../../design-system/primitives/ProgressBar/ProgressBar' import { SectionHeader } from '../../design-system/primitives/SectionHeader/SectionHeader' -import { Card } from '../../design-system/primitives/Card/Card' -import { CodeBlock } from '../../design-system/primitives/CodeBlock/CodeBlock' // Global filters import { useGlobalFilters } from '../../design-system/providers/GlobalFilterProvider' @@ -53,27 +52,23 @@ function buildMemoryHistory(currentPct: number) { // ── Mock log entries ───────────────────────────────────────────────────────── -function buildLogEntries(agentName: string) { +function buildLogEntries(agentName: string): LogEntry[] { const now = Date.now() const MIN = 60_000 return [ - { ts: new Date(now - 1 * MIN).toISOString(), level: 'INFO', logger: 'o.a.c.impl.DefaultCamelContext', msg: `Route order-validation started and consuming from: direct:validate` }, - { ts: new Date(now - 2 * MIN).toISOString(), level: 'INFO', logger: 'o.a.c.impl.DefaultCamelContext', msg: `Total 3 routes, of which 3 are started` }, - { ts: new Date(now - 5 * MIN).toISOString(), level: 'WARN', logger: 'o.a.c.processor.errorhandler', msg: `Failed delivery for exchangeId: ID-${agentName}-1710847200000-0-1. Exhausted after 3 attempts.` }, - { ts: new Date(now - 8 * MIN).toISOString(), level: 'INFO', logger: 'o.a.c.health.HealthCheckHelper', msg: `Health check [routes] is UP` }, - { ts: new Date(now - 12 * MIN).toISOString(), level: 'INFO', logger: 'o.a.c.health.HealthCheckHelper', msg: `Health check [consumers] is UP` }, - { ts: new Date(now - 15 * MIN).toISOString(), level: 'DEBUG', logger: 'o.a.c.component.kafka', msg: `KafkaConsumer[order-events] poll returned 42 records in 18ms` }, - { ts: new Date(now - 18 * MIN).toISOString(), level: 'INFO', logger: 'o.a.c.impl.engine.InternalRouteStartup', msg: `Route order-enrichment started and consuming from: kafka:order-events` }, - { ts: new Date(now - 25 * MIN).toISOString(), level: 'WARN', logger: 'o.a.c.component.http', msg: `HTTP endpoint https://payment-api.internal/verify returned 503 — will retry` }, - { ts: new Date(now - 30 * MIN).toISOString(), level: 'INFO', logger: 'o.a.c.impl.DefaultCamelContext', msg: `Apache Camel ${agentName} (CamelContext) is starting` }, - { ts: new Date(now - 32 * MIN).toISOString(), level: 'INFO', logger: 'org.springframework.boot', msg: `Started ${agentName} in 4.231 seconds (process running for 4.892)` }, + { timestamp: new Date(now - 1 * MIN).toISOString(), level: 'info', message: `[o.a.c.impl.DefaultCamelContext] Route order-validation started and consuming from: direct:validate` }, + { timestamp: new Date(now - 2 * MIN).toISOString(), level: 'info', message: `[o.a.c.impl.DefaultCamelContext] Total 3 routes, of which 3 are started` }, + { timestamp: new Date(now - 5 * MIN).toISOString(), level: 'warn', message: `[o.a.c.processor.errorhandler] Failed delivery for exchangeId: ID-${agentName}-1710847200000-0-1. Exhausted after 3 attempts.` }, + { timestamp: new Date(now - 8 * MIN).toISOString(), level: 'info', message: `[o.a.c.health.HealthCheckHelper] Health check [routes] is UP` }, + { timestamp: new Date(now - 12 * MIN).toISOString(), level: 'info', message: `[o.a.c.health.HealthCheckHelper] Health check [consumers] is UP` }, + { timestamp: new Date(now - 15 * MIN).toISOString(), level: 'debug', message: `[o.a.c.component.kafka] KafkaConsumer[order-events] poll returned 42 records in 18ms` }, + { timestamp: new Date(now - 18 * MIN).toISOString(), level: 'info', message: `[o.a.c.impl.engine.InternalRouteStartup] Route order-enrichment started and consuming from: kafka:order-events` }, + { timestamp: new Date(now - 25 * MIN).toISOString(), level: 'warn', message: `[o.a.c.component.http] HTTP endpoint https://payment-api.internal/verify returned 503 — will retry` }, + { timestamp: new Date(now - 30 * MIN).toISOString(), level: 'info', message: `[o.a.c.impl.DefaultCamelContext] Apache Camel ${agentName} (CamelContext) is starting` }, + { timestamp: new Date(now - 32 * MIN).toISOString(), level: 'info', message: `[org.springframework.boot] Started ${agentName} in 4.231 seconds (process running for 4.892)` }, ] } -function formatLogTime(iso: string): string { - return new Date(iso).toLocaleTimeString('en-GB', { hour: '2-digit', minute: '2-digit', second: '2-digit', hour12: false }) -} - // ── Mock JVM / process info ────────────────────────────────────────────────── function buildProcessInfo(agent: typeof agents[0]) { @@ -144,7 +139,7 @@ export function AgentInstance() { const logEntries = buildLogEntries(agent.name) const filteredLogs = logFilter === 'all' ? logEntries - : logEntries.filter((l) => l.level === logFilter.toUpperCase()) + : logEntries.filter((l) => l.level === logFilter) const cpuData = buildTimeSeries(agent.cpuUsagePct, 15) const memSeries = buildMemoryHistory(agent.memoryUsagePct) @@ -289,22 +284,7 @@ export function AgentInstance() { Application Log -
- {filteredLogs.map((entry, i) => ( -
- {formatLogTime(entry.ts)} - - {entry.logger} - {entry.msg} -
- ))} - {filteredLogs.length === 0 && ( -
No log entries match the selected filter.
- )} -
+ {/* Timeline */}