Files
users/app/monitoring/page.tsx
v0 b17b488f8e refactor: restructure navigation and module layout
Reorganize navigation and module structure based on new requirements.

Co-authored-by: null <4804959+fnvtk@users.noreply.github.com>
2026-01-31 04:32:36 +00:00

382 lines
18 KiB
TypeScript

"use client"
import { useState, useEffect } from "react"
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"
import { Button } from "@/components/ui/button"
import { Badge } from "@/components/ui/badge"
import { Progress } from "@/components/ui/progress"
import {
Activity,
Server,
Cpu,
HardDrive,
Wifi,
AlertTriangle,
CheckCircle2,
Bell,
RefreshCw,
ArrowRight,
TrendingUp,
} from "lucide-react"
import Link from "next/link"
import { XAxis, YAxis, CartesianGrid, Tooltip, ResponsiveContainer, AreaChart, Area } from "recharts"
// 模拟系统资源数据
const systemMetrics = [
{ time: "00:00", cpu: 45, memory: 62, disk: 78, network: 120 },
{ time: "04:00", cpu: 32, memory: 58, disk: 78, network: 80 },
{ time: "08:00", cpu: 58, memory: 65, disk: 79, network: 180 },
{ time: "12:00", cpu: 72, memory: 71, disk: 79, network: 320 },
{ time: "16:00", cpu: 68, memory: 69, disk: 80, network: 280 },
{ time: "20:00", cpu: 55, memory: 64, disk: 80, network: 200 },
]
const recentAlerts = [
{ id: 1, type: "warning", message: "数据同步任务延迟超过阈值", time: "10分钟前", status: "active" },
{ id: 2, type: "info", message: "模型训练任务已完成", time: "30分钟前", status: "resolved" },
{ id: 3, type: "error", message: "API网关响应超时", time: "1小时前", status: "resolved" },
{ id: 4, type: "warning", message: "磁盘使用率超过80%", time: "2小时前", status: "active" },
]
const serviceStatus = [
{ name: "数据接入服务", status: "healthy", uptime: "99.99%", latency: "12ms" },
{ name: "标签计算引擎", status: "healthy", uptime: "99.95%", latency: "45ms" },
{ name: "AI推理服务", status: "healthy", uptime: "99.90%", latency: "120ms" },
{ name: "API网关", status: "degraded", uptime: "99.85%", latency: "85ms" },
{ name: "数据库集群", status: "healthy", uptime: "99.99%", latency: "8ms" },
{ name: "缓存服务", status: "healthy", uptime: "99.99%", latency: "2ms" },
]
export default function MonitoringPage() {
const [cpuUsage, setCpuUsage] = useState(65)
const [memoryUsage, setMemoryUsage] = useState(68)
const [diskUsage, setDiskUsage] = useState(80)
const [networkIO, setNetworkIO] = useState(256)
useEffect(() => {
const interval = setInterval(() => {
setCpuUsage((prev) => Math.min(95, Math.max(30, prev + (Math.random() - 0.5) * 10)))
setMemoryUsage((prev) => Math.min(90, Math.max(50, prev + (Math.random() - 0.5) * 5)))
setNetworkIO((prev) => Math.min(500, Math.max(100, prev + (Math.random() - 0.5) * 50)))
}, 3000)
return () => clearInterval(interval)
}, [])
return (
<div className="min-h-screen bg-gradient-to-br from-slate-50 via-white to-emerald-50/30 p-6">
<div className="max-w-7xl mx-auto space-y-6">
{/* 页面标题 */}
<div className="flex items-center justify-between">
<div>
<h1 className="text-2xl font-bold text-slate-800"></h1>
<p className="text-slate-500 mt-1"></p>
</div>
<div className="flex items-center gap-2">
<Button variant="outline">
<Bell className="w-4 h-4 mr-2" />
</Button>
<Button variant="outline">
<RefreshCw className="w-4 h-4 mr-2" />
</Button>
<Link href="/monitoring/alerts">
<Button className="bg-gradient-to-r from-emerald-500 to-teal-600 hover:from-emerald-600 hover:to-teal-700">
<Activity className="w-4 h-4 mr-2" />
</Button>
</Link>
</div>
</div>
{/* 系统资源概览 */}
<div className="grid grid-cols-1 md:grid-cols-4 gap-4">
<Card className="bg-white/70 backdrop-blur border-slate-200/60">
<CardContent className="p-4">
<div className="flex items-center justify-between mb-3">
<div className="flex items-center gap-2">
<div className="w-8 h-8 rounded-lg bg-gradient-to-br from-blue-500 to-cyan-600 flex items-center justify-center">
<Cpu className="w-4 h-4 text-white" />
</div>
<span className="text-sm font-medium text-slate-700">CPU使用率</span>
</div>
<span
className={`text-xl font-bold ${cpuUsage > 80 ? "text-red-600" : cpuUsage > 60 ? "text-amber-600" : "text-emerald-600"}`}
>
{cpuUsage.toFixed(1)}%
</span>
</div>
<Progress value={cpuUsage} className="h-2" />
<p className="text-xs text-slate-500 mt-2">8 / 16线</p>
</CardContent>
</Card>
<Card className="bg-white/70 backdrop-blur border-slate-200/60">
<CardContent className="p-4">
<div className="flex items-center justify-between mb-3">
<div className="flex items-center gap-2">
<div className="w-8 h-8 rounded-lg bg-gradient-to-br from-violet-500 to-purple-600 flex items-center justify-center">
<Server className="w-4 h-4 text-white" />
</div>
<span className="text-sm font-medium text-slate-700">使</span>
</div>
<span
className={`text-xl font-bold ${memoryUsage > 85 ? "text-red-600" : memoryUsage > 70 ? "text-amber-600" : "text-emerald-600"}`}
>
{memoryUsage.toFixed(1)}%
</span>
</div>
<Progress value={memoryUsage} className="h-2" />
<p className="text-xs text-slate-500 mt-2">54.4GB / 80GB</p>
</CardContent>
</Card>
<Card className="bg-white/70 backdrop-blur border-slate-200/60">
<CardContent className="p-4">
<div className="flex items-center justify-between mb-3">
<div className="flex items-center gap-2">
<div className="w-8 h-8 rounded-lg bg-gradient-to-br from-amber-500 to-orange-600 flex items-center justify-center">
<HardDrive className="w-4 h-4 text-white" />
</div>
<span className="text-sm font-medium text-slate-700">使</span>
</div>
<span className={`text-xl font-bold ${diskUsage > 85 ? "text-red-600" : "text-amber-600"}`}>
{diskUsage}%
</span>
</div>
<Progress value={diskUsage} className="h-2" />
<p className="text-xs text-slate-500 mt-2">1.6TB / 2TB</p>
</CardContent>
</Card>
<Card className="bg-white/70 backdrop-blur border-slate-200/60">
<CardContent className="p-4">
<div className="flex items-center justify-between mb-3">
<div className="flex items-center gap-2">
<div className="w-8 h-8 rounded-lg bg-gradient-to-br from-emerald-500 to-teal-600 flex items-center justify-center">
<Wifi className="w-4 h-4 text-white" />
</div>
<span className="text-sm font-medium text-slate-700">IO</span>
</div>
<span className="text-xl font-bold text-emerald-600">{networkIO} MB/s</span>
</div>
<Progress value={(networkIO / 500) * 100} className="h-2" />
<p className="text-xs text-slate-500 mt-2">入站: 180MB/s | 出站: 76MB/s</p>
</CardContent>
</Card>
</div>
{/* 功能入口 */}
<div className="grid grid-cols-1 md:grid-cols-3 gap-4">
<Link href="/monitoring/health">
<Card className="bg-white/70 backdrop-blur border-slate-200/60 hover:shadow-lg hover:border-slate-300 transition-all cursor-pointer group h-full">
<CardContent className="p-5">
<div className="flex items-center justify-between">
<div className="flex items-center gap-3">
<div className="w-12 h-12 rounded-xl bg-gradient-to-br from-emerald-500 to-teal-600 flex items-center justify-center">
<Activity className="w-6 h-6 text-white" />
</div>
<div>
<h3 className="font-semibold text-slate-800"></h3>
<p className="text-sm text-slate-500"></p>
</div>
</div>
<ArrowRight className="w-5 h-5 text-slate-400 group-hover:text-slate-600 group-hover:translate-x-1 transition-all" />
</div>
</CardContent>
</Card>
</Link>
<Link href="/monitoring/alerts">
<Card className="bg-white/70 backdrop-blur border-slate-200/60 hover:shadow-lg hover:border-slate-300 transition-all cursor-pointer group h-full">
<CardContent className="p-5">
<div className="flex items-center justify-between">
<div className="flex items-center gap-3">
<div className="w-12 h-12 rounded-xl bg-gradient-to-br from-red-500 to-orange-600 flex items-center justify-center">
<Bell className="w-6 h-6 text-white" />
</div>
<div>
<h3 className="font-semibold text-slate-800"></h3>
<p className="text-sm text-slate-500"></p>
</div>
</div>
<div className="flex items-center gap-2">
<Badge className="bg-red-100 text-red-700">2</Badge>
<ArrowRight className="w-5 h-5 text-slate-400 group-hover:text-slate-600 group-hover:translate-x-1 transition-all" />
</div>
</div>
</CardContent>
</Card>
</Link>
<Link href="/monitoring/business">
<Card className="bg-white/70 backdrop-blur border-slate-200/60 hover:shadow-lg hover:border-slate-300 transition-all cursor-pointer group h-full">
<CardContent className="p-5">
<div className="flex items-center justify-between">
<div className="flex items-center gap-3">
<div className="w-12 h-12 rounded-xl bg-gradient-to-br from-blue-500 to-indigo-600 flex items-center justify-center">
<TrendingUp className="w-6 h-6 text-white" />
</div>
<div>
<h3 className="font-semibold text-slate-800"></h3>
<p className="text-sm text-slate-500">KPI监控</p>
</div>
</div>
<ArrowRight className="w-5 h-5 text-slate-400 group-hover:text-slate-600 group-hover:translate-x-1 transition-all" />
</div>
</CardContent>
</Card>
</Link>
</div>
<div className="grid grid-cols-1 lg:grid-cols-3 gap-6">
{/* 系统资源趋势 */}
<Card className="lg:col-span-2 bg-white/70 backdrop-blur border-slate-200/60">
<CardHeader className="pb-2">
<CardTitle className="text-base"> (24)</CardTitle>
</CardHeader>
<CardContent>
<div className="h-64">
<ResponsiveContainer width="100%" height="100%">
<AreaChart data={systemMetrics}>
<CartesianGrid strokeDasharray="3 3" stroke="#e2e8f0" />
<XAxis dataKey="time" tick={{ fontSize: 12 }} stroke="#94a3b8" />
<YAxis tick={{ fontSize: 12 }} stroke="#94a3b8" />
<Tooltip
contentStyle={{
backgroundColor: "white",
border: "1px solid #e2e8f0",
borderRadius: "8px",
}}
/>
<defs>
<linearGradient id="colorCpu" x1="0" y1="0" x2="0" y2="1">
<stop offset="5%" stopColor="#3b82f6" stopOpacity={0.3} />
<stop offset="95%" stopColor="#3b82f6" stopOpacity={0} />
</linearGradient>
<linearGradient id="colorMemory" x1="0" y1="0" x2="0" y2="1">
<stop offset="5%" stopColor="#8b5cf6" stopOpacity={0.3} />
<stop offset="95%" stopColor="#8b5cf6" stopOpacity={0} />
</linearGradient>
</defs>
<Area type="monotone" dataKey="cpu" stroke="#3b82f6" strokeWidth={2} fill="url(#colorCpu)" />
<Area type="monotone" dataKey="memory" stroke="#8b5cf6" strokeWidth={2} fill="url(#colorMemory)" />
</AreaChart>
</ResponsiveContainer>
</div>
<div className="flex items-center justify-center gap-6 mt-4">
<div className="flex items-center gap-2">
<div className="w-3 h-3 rounded-full bg-blue-500" />
<span className="text-xs text-slate-600">CPU</span>
</div>
<div className="flex items-center gap-2">
<div className="w-3 h-3 rounded-full bg-violet-500" />
<span className="text-xs text-slate-600"></span>
</div>
</div>
</CardContent>
</Card>
{/* 最近告警 */}
<Card className="bg-white/70 backdrop-blur border-slate-200/60">
<CardHeader className="pb-3">
<div className="flex items-center justify-between">
<CardTitle className="text-base flex items-center gap-2">
<Bell className="w-4 h-4 text-red-500" />
</CardTitle>
<Link href="/monitoring/alerts">
<Button variant="ghost" size="sm">
</Button>
</Link>
</div>
</CardHeader>
<CardContent>
<div className="space-y-3">
{recentAlerts.map((alert) => (
<div key={alert.id} className="flex items-start gap-3 p-3 bg-slate-50/80 rounded-lg">
{alert.type === "error" ? (
<AlertTriangle className="w-5 h-5 text-red-500 mt-0.5" />
) : alert.type === "warning" ? (
<AlertTriangle className="w-5 h-5 text-amber-500 mt-0.5" />
) : (
<CheckCircle2 className="w-5 h-5 text-blue-500 mt-0.5" />
)}
<div className="flex-1">
<p className="text-sm text-slate-700">{alert.message}</p>
<div className="flex items-center gap-2 mt-1">
<span className="text-xs text-slate-500">{alert.time}</span>
{alert.status === "active" ? (
<Badge className="bg-red-100 text-red-700 text-xs"></Badge>
) : (
<Badge className="bg-emerald-100 text-emerald-700 text-xs"></Badge>
)}
</div>
</div>
</div>
))}
</div>
</CardContent>
</Card>
</div>
{/* 服务状态 */}
<Card className="bg-white/70 backdrop-blur border-slate-200/60">
<CardHeader className="pb-3">
<CardTitle className="text-base flex items-center gap-2">
<Server className="w-4 h-4 text-slate-500" />
</CardTitle>
</CardHeader>
<CardContent>
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
{serviceStatus.map((service, i) => (
<div
key={i}
className={`flex items-center justify-between p-4 rounded-lg border ${
service.status === "healthy"
? "bg-emerald-50/50 border-emerald-200"
: service.status === "degraded"
? "bg-amber-50/50 border-amber-200"
: "bg-red-50/50 border-red-200"
}`}
>
<div className="flex items-center gap-3">
<div
className={`w-3 h-3 rounded-full ${
service.status === "healthy"
? "bg-emerald-500"
: service.status === "degraded"
? "bg-amber-500 animate-pulse"
: "bg-red-500 animate-pulse"
}`}
/>
<div>
<p className="text-sm font-medium text-slate-800">{service.name}</p>
<p className="text-xs text-slate-500">
: {service.uptime} | : {service.latency}
</p>
</div>
</div>
<Badge
className={
service.status === "healthy"
? "bg-emerald-100 text-emerald-700"
: service.status === "degraded"
? "bg-amber-100 text-amber-700"
: "bg-red-100 text-red-700"
}
>
{service.status === "healthy" ? "正常" : service.status === "degraded" ? "降级" : "故障"}
</Badge>
</div>
))}
</div>
</CardContent>
</Card>
</div>
</div>
)
}