From 3e8fa7cba7e53b1664a0e837dc43133498c5514d Mon Sep 17 00:00:00 2001 From: MacRimi Date: Sat, 11 Oct 2025 12:06:59 +0200 Subject: [PATCH] Update system-logs.tsx --- AppImage/components/system-logs.tsx | 280 +++++++++++++++++++++++++--- 1 file changed, 257 insertions(+), 23 deletions(-) diff --git a/AppImage/components/system-logs.tsx b/AppImage/components/system-logs.tsx index fb0a3b4..972cd59 100644 --- a/AppImage/components/system-logs.tsx +++ b/AppImage/components/system-logs.tsx @@ -7,6 +7,7 @@ import { Input } from "./ui/input" import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "./ui/select" import { ScrollArea } from "./ui/scroll-area" import { Tabs, TabsContent, TabsList, TabsTrigger } from "./ui/tabs" +import { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle } from "./ui/dialog" import { FileText, Search, @@ -22,6 +23,7 @@ import { RefreshCw, Bell, Mail, + Eye, } from "lucide-react" import { useState, useEffect } from "react" @@ -90,6 +92,13 @@ export function SystemLogs() { const [serviceFilter, setServiceFilter] = useState("all") const [activeTab, setActiveTab] = useState("logs") + const [selectedLog, setSelectedLog] = useState(null) + const [selectedEvent, setSelectedEvent] = useState(null) + const [selectedBackup, setSelectedBackup] = useState(null) + const [isLogModalOpen, setIsLogModalOpen] = useState(false) + const [isEventModalOpen, setIsEventModalOpen] = useState(false) + const [isBackupModalOpen, setIsBackupModalOpen] = useState(false) + const getApiUrl = (endpoint: string) => { if (typeof window !== "undefined") { return `${window.location.protocol}//${window.location.hostname}:8008${endpoint}` @@ -97,12 +106,8 @@ export function SystemLogs() { return `http://localhost:8008${endpoint}` } - // Fetch data useEffect(() => { fetchAllData() - // Refresh every 30 seconds - const interval = setInterval(fetchAllData, 30000) - return () => clearInterval(interval) }, []) const fetchAllData = async () => { @@ -259,12 +264,38 @@ export function SystemLogs() { const uniqueServices = [...new Set(logs.map((log) => log.service))] - // Calculate backup statistics + const getBackupStorageType = (volid: string): "pbs" | "pve" => { + // PBS backups have format: storage:backup/type/vmid/timestamp + // PVE backups have format: storage:backup/vzdump-type-vmid-timestamp.vma.zst + if (volid.includes(":backup/vm/") || volid.includes(":backup/ct/")) { + return "pbs" + } + return "pve" + } + + const getBackupStorageColor = (volid: string) => { + const type = getBackupStorageType(volid) + return type === "pbs" + ? "bg-purple-500/10 text-purple-500 border-purple-500/20" + : "bg-blue-500/10 text-blue-500 border-blue-500/20" + } + + const getBackupStorageLabel = (volid: string) => { + const type = getBackupStorageType(volid) + return type === "pbs" ? "PBS" : "PVE" + } + const backupStats = { total: backups.length, totalSize: backups.reduce((sum, b) => sum + b.size, 0), - qemu: backups.filter((b) => b.type === "qemu").length, - lxc: backups.filter((b) => b.type === "lxc").length, + qemu: backups.filter((b) => { + // Check if volid contains /vm/ for QEMU or vzdump-qemu for PVE + return b.volid.includes("/vm/") || b.volid.includes("vzdump-qemu") + }).length, + lxc: backups.filter((b) => { + // Check if volid contains /ct/ for LXC or vzdump-lxc for PVE + return b.volid.includes("/ct/") || b.volid.includes("vzdump-lxc") + }).length, } const formatBytes = (bytes: number) => { @@ -411,7 +442,11 @@ export function SystemLogs() { {filteredLogs.map((log, index) => (
{ + setSelectedLog(log) + setIsLogModalOpen(true) + }} >
@@ -423,9 +458,12 @@ export function SystemLogs() {
{log.service}
-
{log.timestamp}
+
+ +
{log.timestamp}
+
-
{log.message}
+
{log.message}
Source: {log.source} {log.pid && ` • PID: ${log.pid}`} @@ -452,7 +490,11 @@ export function SystemLogs() { {events.map((event, index) => (
{ + setSelectedEvent(event) + setIsEventModalOpen(true) + }} >
@@ -467,14 +509,15 @@ export function SystemLogs() { {event.type} {event.vmid && ` (VM/CT ${event.vmid})`}
-
{event.duration}
+
+ +
{event.duration}
+
Node: {event.node} • User: {event.user}
-
- Started: {event.starttime} • Ended: {event.endtime} -
+
Started: {event.starttime}
))} @@ -517,7 +560,11 @@ export function SystemLogs() { {backups.map((backup, index) => (
{ + setSelectedBackup(backup) + setIsBackupModalOpen(true) + }} >
@@ -525,19 +572,27 @@ export function SystemLogs() {
-
- {backup.type?.toUpperCase()} {backup.vmid && `VM ${backup.vmid}`} +
+
+ {backup.volid.includes("/vm/") || backup.volid.includes("vzdump-qemu") ? "QEMU" : "LXC"} + {backup.vmid && ` VM ${backup.vmid}`} +
+ + {getBackupStorageLabel(backup.volid)} + +
+
+ + + {backup.size_human} +
- - {backup.size_human} -
Storage: {backup.storage}
{backup.created}
-
{backup.volid}
))} @@ -552,6 +607,7 @@ export function SystemLogs() { + {/* Notifications Tab */}
@@ -564,7 +620,9 @@ export function SystemLogs() {
-
{notification.type}
+
+ {notification.type} +
{notification.timestamp}
{notification.message}
@@ -587,6 +645,182 @@ export function SystemLogs() { + + + + + + + Log Details + + Complete information about this log entry + + {selectedLog && ( +
+
+
+
Level
+ + {getLevelIcon(selectedLog.level)} + {selectedLog.level.toUpperCase()} + +
+
+
Service
+
{selectedLog.service}
+
+
+
Timestamp
+
{selectedLog.timestamp}
+
+
+
Source
+
{selectedLog.source}
+
+ {selectedLog.pid && ( +
+
Process ID
+
{selectedLog.pid}
+
+ )} + {selectedLog.hostname && ( +
+
Hostname
+
{selectedLog.hostname}
+
+ )} +
+
+
Message
+
+
{selectedLog.message}
+
+
+
+ )} +
+
+ + + + + + + Event Details + + Complete information about this event + + {selectedEvent && ( +
+
+
+
Status
+ + {getLevelIcon(selectedEvent.level)} + {selectedEvent.status} + +
+
+
Type
+
{selectedEvent.type}
+
+
+
Node
+
{selectedEvent.node}
+
+
+
User
+
{selectedEvent.user}
+
+ {selectedEvent.vmid && ( +
+
VM/CT ID
+
{selectedEvent.vmid}
+
+ )} +
+
Duration
+
{selectedEvent.duration}
+
+
+
Start Time
+
{selectedEvent.starttime}
+
+
+
End Time
+
{selectedEvent.endtime}
+
+
+
+
UPID
+
+
+                    {selectedEvent.upid}
+                  
+
+
+
+ )} +
+
+ + + + + + + Backup Details + + Complete information about this backup + + {selectedBackup && ( +
+
+
+
Type
+ + {selectedBackup.volid.includes("/vm/") || selectedBackup.volid.includes("vzdump-qemu") + ? "QEMU" + : "LXC"} + +
+
+
Storage Type
+ + {getBackupStorageLabel(selectedBackup.volid)} + +
+
+
Storage
+
{selectedBackup.storage}
+
+ {selectedBackup.vmid && ( +
+
VM/CT ID
+
{selectedBackup.vmid}
+
+ )} +
+
Size
+
{selectedBackup.size_human}
+
+
+
Created
+
{selectedBackup.created}
+
+
+
+
Volume ID
+
+
+                    {selectedBackup.volid}
+                  
+
+
+
+ )} +
+
) }