feat: Agent Health page with progressive filtering and GroupCard component
Add URL-driven Agent Health page (/agents, /agents/:appId, /agents/:appId/:instanceId) that progressively narrows from all applications to a single instance with trend charts. Create generic GroupCard composite for grouping instances by application. Expand mock data to 8 instances across 4 apps with varied states. Split sidebar Agents header into navigable link + collapse chevron. Update agent tree paths to /agents/:appId/:instanceId. Add EventFeed with lifecycle events. Change SidebarAgent.tps from string to number. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
55
src/mocks/agentEvents.ts
Normal file
55
src/mocks/agentEvents.ts
Normal file
@@ -0,0 +1,55 @@
|
||||
import type { FeedEvent } from '../design-system/composites/EventFeed/EventFeed'
|
||||
|
||||
const MINUTE = 60_000
|
||||
const HOUR = 3_600_000
|
||||
|
||||
export const agentEvents: FeedEvent[] = [
|
||||
{
|
||||
id: 'evt-1',
|
||||
severity: 'error',
|
||||
message: '[notification-hub] notif-1 status changed to DEAD — no heartbeat for 47m',
|
||||
timestamp: new Date(Date.now() - 47 * MINUTE),
|
||||
},
|
||||
{
|
||||
id: 'evt-2',
|
||||
severity: 'warning',
|
||||
message: '[payment-svc] pay-2 status changed to STALE — missed 3 consecutive heartbeats',
|
||||
timestamp: new Date(Date.now() - 3 * MINUTE),
|
||||
},
|
||||
{
|
||||
id: 'evt-3',
|
||||
severity: 'success',
|
||||
message: '[order-service] ord-3 started — instance joined cluster (v3.2.1)',
|
||||
timestamp: new Date(Date.now() - 2 * HOUR - 15 * MINUTE),
|
||||
},
|
||||
{
|
||||
id: 'evt-4',
|
||||
severity: 'warning',
|
||||
message: '[payment-svc] pay-2 error rate elevated: 12 err/h (threshold: 10 err/h)',
|
||||
timestamp: new Date(Date.now() - 5 * MINUTE),
|
||||
},
|
||||
{
|
||||
id: 'evt-5',
|
||||
severity: 'running',
|
||||
message: '[order-service] Route "order-validation" added to ord-1, ord-2, ord-3',
|
||||
timestamp: new Date(Date.now() - 1 * HOUR - 30 * MINUTE),
|
||||
},
|
||||
{
|
||||
id: 'evt-6',
|
||||
severity: 'running',
|
||||
message: '[shipment-svc] Configuration updated — retry policy changed to 3 attempts with exponential backoff',
|
||||
timestamp: new Date(Date.now() - 4 * HOUR),
|
||||
},
|
||||
{
|
||||
id: 'evt-7',
|
||||
severity: 'success',
|
||||
message: '[shipment-svc] ship-1 and ship-2 upgraded to v3.2.0 — rolling restart complete',
|
||||
timestamp: new Date(Date.now() - 7 * 24 * HOUR),
|
||||
},
|
||||
{
|
||||
id: 'evt-8',
|
||||
severity: 'error',
|
||||
message: '[notification-hub] notif-1 failed health check — memory allocation error',
|
||||
timestamp: new Date(Date.now() - 48 * MINUTE),
|
||||
},
|
||||
]
|
||||
@@ -1,9 +1,10 @@
|
||||
export interface AgentHealth {
|
||||
id: string
|
||||
name: string
|
||||
appId: string
|
||||
service: string
|
||||
version: string
|
||||
tps: string
|
||||
tps: number
|
||||
lastSeen: string
|
||||
status: 'live' | 'stale' | 'dead'
|
||||
errorRate?: string
|
||||
@@ -15,61 +16,48 @@ export interface AgentHealth {
|
||||
}
|
||||
|
||||
export const agents: AgentHealth[] = [
|
||||
// order-service: 3 instances, all live
|
||||
{
|
||||
id: 'prod-1',
|
||||
name: 'prod-1',
|
||||
service: 'order-service',
|
||||
version: 'v3.2.1',
|
||||
tps: '14.2/s',
|
||||
lastSeen: '12s ago',
|
||||
status: 'live',
|
||||
uptime: '14d 6h',
|
||||
memoryUsagePct: 62,
|
||||
cpuUsagePct: 24,
|
||||
activeRoutes: 3,
|
||||
totalRoutes: 3,
|
||||
id: 'ord-1', name: 'ord-1', appId: 'order-service', service: 'order-service', version: 'v3.2.1',
|
||||
tps: 14.2, lastSeen: '12s ago', status: 'live', uptime: '14d 6h',
|
||||
memoryUsagePct: 62, cpuUsagePct: 24, activeRoutes: 3, totalRoutes: 3,
|
||||
},
|
||||
{
|
||||
id: 'prod-2',
|
||||
name: 'prod-2',
|
||||
service: 'payment-svc',
|
||||
version: 'v3.2.1',
|
||||
tps: '11.8/s',
|
||||
lastSeen: '8s ago',
|
||||
status: 'live',
|
||||
errorRate: '3 err/h',
|
||||
uptime: '14d 6h',
|
||||
memoryUsagePct: 71,
|
||||
cpuUsagePct: 31,
|
||||
activeRoutes: 2,
|
||||
totalRoutes: 2,
|
||||
id: 'ord-2', name: 'ord-2', appId: 'order-service', service: 'order-service', version: 'v3.2.1',
|
||||
tps: 11.8, lastSeen: '8s ago', status: 'live', errorRate: '3 err/h', uptime: '14d 6h',
|
||||
memoryUsagePct: 71, cpuUsagePct: 31, activeRoutes: 3, totalRoutes: 3,
|
||||
},
|
||||
{
|
||||
id: 'prod-3',
|
||||
name: 'prod-3',
|
||||
service: 'shipment-svc',
|
||||
version: 'v3.2.0',
|
||||
tps: '12.1/s',
|
||||
lastSeen: '5s ago',
|
||||
status: 'live',
|
||||
uptime: '7d 14h',
|
||||
memoryUsagePct: 55,
|
||||
cpuUsagePct: 19,
|
||||
activeRoutes: 2,
|
||||
totalRoutes: 2,
|
||||
id: 'ord-3', name: 'ord-3', appId: 'order-service', service: 'order-service', version: 'v3.2.1',
|
||||
tps: 8.4, lastSeen: '4s ago', status: 'live', uptime: '2h 15m',
|
||||
memoryUsagePct: 38, cpuUsagePct: 12, activeRoutes: 3, totalRoutes: 3,
|
||||
},
|
||||
// payment-svc: 2 instances, one stale
|
||||
{
|
||||
id: 'pay-1', name: 'pay-1', appId: 'payment-svc', service: 'payment-svc', version: 'v3.2.1',
|
||||
tps: 9.7, lastSeen: '6s ago', status: 'live', uptime: '14d 6h',
|
||||
memoryUsagePct: 58, cpuUsagePct: 22, activeRoutes: 2, totalRoutes: 2,
|
||||
},
|
||||
{
|
||||
id: 'prod-4',
|
||||
name: 'prod-4',
|
||||
service: 'shipment-svc',
|
||||
version: 'v3.2.0',
|
||||
tps: '9.1/s',
|
||||
lastSeen: '3s ago',
|
||||
status: 'live',
|
||||
uptime: '7d 14h',
|
||||
memoryUsagePct: 48,
|
||||
cpuUsagePct: 15,
|
||||
activeRoutes: 2,
|
||||
totalRoutes: 2,
|
||||
id: 'pay-2', name: 'pay-2', appId: 'payment-svc', service: 'payment-svc', version: 'v3.2.1',
|
||||
tps: 0.3, lastSeen: '3m ago', status: 'stale', errorRate: '12 err/h', uptime: '14d 6h',
|
||||
memoryUsagePct: 82, cpuUsagePct: 67, activeRoutes: 1, totalRoutes: 2,
|
||||
},
|
||||
// shipment-svc: 2 instances, both live
|
||||
{
|
||||
id: 'ship-1', name: 'ship-1', appId: 'shipment-svc', service: 'shipment-svc', version: 'v3.2.0',
|
||||
tps: 12.1, lastSeen: '5s ago', status: 'live', uptime: '7d 14h',
|
||||
memoryUsagePct: 55, cpuUsagePct: 19, activeRoutes: 2, totalRoutes: 2,
|
||||
},
|
||||
{
|
||||
id: 'ship-2', name: 'ship-2', appId: 'shipment-svc', service: 'shipment-svc', version: 'v3.2.0',
|
||||
tps: 9.1, lastSeen: '3s ago', status: 'live', uptime: '7d 14h',
|
||||
memoryUsagePct: 48, cpuUsagePct: 15, activeRoutes: 2, totalRoutes: 2,
|
||||
},
|
||||
// notification-hub: 1 instance, DEAD
|
||||
{
|
||||
id: 'notif-1', name: 'notif-1', appId: 'notification-hub', service: 'notification-hub', version: 'v3.1.9',
|
||||
tps: 0, lastSeen: '47m ago', status: 'dead', errorRate: '0 err/h', uptime: '0',
|
||||
memoryUsagePct: 0, cpuUsagePct: 0, activeRoutes: 0, totalRoutes: 1,
|
||||
},
|
||||
]
|
||||
|
||||
@@ -8,7 +8,7 @@ export interface SidebarAgent {
|
||||
id: string
|
||||
name: string
|
||||
status: 'live' | 'stale' | 'dead'
|
||||
tps: string
|
||||
tps: number
|
||||
}
|
||||
|
||||
export interface SidebarApp {
|
||||
@@ -31,8 +31,9 @@ export const SIDEBAR_APPS: SidebarApp[] = [
|
||||
{ id: 'order-enrichment', name: 'order-enrichment', exchangeCount: 541 },
|
||||
],
|
||||
agents: [
|
||||
{ id: 'prod-1', name: 'prod-1', status: 'live', tps: '14.2/s' },
|
||||
{ id: 'prod-2', name: 'prod-2', status: 'live', tps: '11.8/s' },
|
||||
{ id: 'ord-1', name: 'ord-1', status: 'live', tps: 14.2 },
|
||||
{ id: 'ord-2', name: 'ord-2', status: 'live', tps: 11.8 },
|
||||
{ id: 'ord-3', name: 'ord-3', status: 'live', tps: 8.4 },
|
||||
],
|
||||
},
|
||||
{
|
||||
@@ -45,7 +46,8 @@ export const SIDEBAR_APPS: SidebarApp[] = [
|
||||
{ id: 'payment-validate', name: 'payment-validate', exchangeCount: 498 },
|
||||
],
|
||||
agents: [
|
||||
{ id: 'prod-2', name: 'prod-2', status: 'live', tps: '11.8/s' },
|
||||
{ id: 'pay-1', name: 'pay-1', status: 'live', tps: 9.7 },
|
||||
{ id: 'pay-2', name: 'pay-2', status: 'stale', tps: 0.3 },
|
||||
],
|
||||
},
|
||||
{
|
||||
@@ -58,8 +60,8 @@ export const SIDEBAR_APPS: SidebarApp[] = [
|
||||
{ id: 'shipment-track', name: 'shipment-track', exchangeCount: 923 },
|
||||
],
|
||||
agents: [
|
||||
{ id: 'prod-3', name: 'prod-3', status: 'live', tps: '12.1/s' },
|
||||
{ id: 'prod-4', name: 'prod-4', status: 'live', tps: '9.1/s' },
|
||||
{ id: 'ship-1', name: 'ship-1', status: 'live', tps: 12.1 },
|
||||
{ id: 'ship-2', name: 'ship-2', status: 'live', tps: 9.1 },
|
||||
],
|
||||
},
|
||||
{
|
||||
@@ -70,6 +72,8 @@ export const SIDEBAR_APPS: SidebarApp[] = [
|
||||
routes: [
|
||||
{ id: 'notification-dispatch', name: 'notification-dispatch', exchangeCount: 471 },
|
||||
],
|
||||
agents: [],
|
||||
agents: [
|
||||
{ id: 'notif-1', name: 'notif-1', status: 'dead', tps: 0 },
|
||||
],
|
||||
},
|
||||
]
|
||||
|
||||
Reference in New Issue
Block a user