diff --git a/AppImage/components/proxmox-dashboard.tsx b/AppImage/components/proxmox-dashboard.tsx index f2e1d1d..b480f7f 100644 --- a/AppImage/components/proxmox-dashboard.tsx +++ b/AppImage/components/proxmox-dashboard.tsx @@ -63,9 +63,14 @@ export function ProxmoxDashboard() { const [lastScrollY, setLastScrollY] = useState(0) const fetchSystemData = useCallback(async () => { + console.log("[v0] Fetching system data from Flask server...") + console.log("[v0] Current window location:", window.location.href) + const baseUrl = typeof window !== "undefined" ? `${window.location.protocol}//${window.location.hostname}:8008` : "" const apiUrl = `${baseUrl}/api/system` + console.log("[v0] API URL:", apiUrl) + try { const response = await fetch(apiUrl, { method: "GET", @@ -74,12 +79,14 @@ export function ProxmoxDashboard() { }, cache: "no-store", }) + console.log("[v0] Response status:", response.status) if (!response.ok) { throw new Error(`Server responded with status: ${response.status}`) } const data: FlaskSystemData = await response.json() + console.log("[v0] System data received:", data) let status: "healthy" | "warning" | "critical" = "healthy" if (data.cpu_usage > 90 || data.memory_usage > 90) { @@ -97,6 +104,13 @@ export function ProxmoxDashboard() { }) setIsServerConnected(true) } catch (error) { + console.error("[v0] Failed to fetch system data from Flask server:", error) + console.error("[v0] Error details:", { + message: error instanceof Error ? error.message : "Unknown error", + apiUrl, + windowLocation: window.location.href, + }) + setIsServerConnected(false) setSystemStatus((prev) => ({ ...prev, @@ -234,7 +248,9 @@ export function ProxmoxDashboard() {
+ {/* Logo and Title */}
+ {/* Logo and Title */}
{ + console.log("[v0] Logo failed to load, using fallback icon") const target = e.target as HTMLImageElement target.style.display = "none" const fallback = target.parentElement?.querySelector(".fallback-icon") @@ -265,6 +282,7 @@ export function ProxmoxDashboard() {
+ {/* Desktop Actions */}
@@ -294,6 +312,7 @@ export function ProxmoxDashboard() {
+ {/* Mobile Actions */}
{statusIcon} @@ -308,6 +327,7 @@ export function ProxmoxDashboard() {
+ {/* Mobile Server Info */}
Uptime: {systemStatus.uptime}
diff --git a/AppImage/components/system-overview.tsx b/AppImage/components/system-overview.tsx index ba7a1f8..ce08a9f 100644 --- a/AppImage/components/system-overview.tsx +++ b/AppImage/components/system-overview.tsx @@ -109,12 +109,13 @@ const fetchSystemData = async (): Promise => { }) if (!response.ok) { - throw new Error(`HTTP error! status: ${response.status}`) + throw new Error(`Flask server responded with status: ${response.status}`) } const data = await response.json() return data } catch (error) { + console.error("[v0] Failed to fetch system data:", error) return null } } @@ -133,12 +134,13 @@ const fetchVMData = async (): Promise => { }) if (!response.ok) { - throw new Error(`HTTP error! status: ${response.status}`) + throw new Error(`Flask server responded with status: ${response.status}`) } const data = await response.json() - return data.vms || [] + return Array.isArray(data) ? data : data.vms || [] } catch (error) { + console.error("[v0] Failed to fetch VM data:", error) return [] } } @@ -157,12 +159,40 @@ const fetchStorageData = async (): Promise => { }) if (!response.ok) { - throw new Error(`HTTP error! status: ${response.status}`) + console.log("[v0] Storage API not available (this is normal if not configured)") + return null } const data = await response.json() return data } catch (error) { + console.log("[v0] Storage data unavailable:", error instanceof Error ? error.message : "Unknown error") + return null + } +} + +const fetchNetworkData = async (): Promise => { + try { + const baseUrl = typeof window !== "undefined" ? `${window.location.protocol}//${window.location.hostname}:8008` : "" + const apiUrl = `${baseUrl}/api/network` + + const response = await fetch(apiUrl, { + method: "GET", + headers: { + "Content-Type": "application/json", + }, + cache: "no-store", + }) + + if (!response.ok) { + console.log("[v0] Network API not available (this is normal if not configured)") + return null + } + + const data = await response.json() + return data + } catch (error) { + console.log("[v0] Network data unavailable:", error instanceof Error ? error.message : "Unknown error") return null } } @@ -193,30 +223,6 @@ const fetchProxmoxStorageData = async (): Promise => } } -const fetchNetworkData = async (): Promise => { - try { - const baseUrl = typeof window !== "undefined" ? `${window.location.protocol}//${window.location.hostname}:8008` : "" - const apiUrl = `${baseUrl}/api/network` - - const response = await fetch(apiUrl, { - method: "GET", - headers: { - "Content-Type": "application/json", - }, - cache: "no-store", - }) - - if (!response.ok) { - throw new Error(`HTTP error! status: ${response.status}`) - } - - const data = await response.json() - return data - } catch (error) { - return null - } -} - export function SystemOverview() { const [systemData, setSystemData] = useState(null) const [vmData, setVmData] = useState([]) diff --git a/AppImage/scripts/flask_server.py b/AppImage/scripts/flask_server.py index faab885..2428869 100644 --- a/AppImage/scripts/flask_server.py +++ b/AppImage/scripts/flask_server.py @@ -1087,7 +1087,7 @@ def get_smart_data(disk_name): smart_data['media_wearout_indicator'] = wear_used smart_data['ssd_life_left'] = max(0, 100 - wear_used) - print(f"[v0] Media Wearout Indicator (ID 230): {smart_data['media_wearout_indicator']}% used, {smart_data['ssd_life_left']}% life left") + print(f"[v0] Media Wearout Indicator (ID 230): {wear_used}% used, {smart_data['ssd_life_left']}% life left") except Exception as e: print(f"[v0] Error parsing Media_Wearout_Indicator (ID 230): {e}") elif attr_id == '233': # Media_Wearout_Indicator (Intel/Samsung SSD) @@ -2806,6 +2806,26 @@ def get_detailed_gpu_info(gpu): detailed_info['utilization_memory'] = round(mem_util, 1) print(f"[v0] Memory Utilization: {detailed_info['utilization_memory']}%", flush=True) + # Parse GRBM (Graphics Register Bus Manager) for engine utilization + if 'GRBM' in device: + grbm = device['GRBM'] + + # Graphics Pipe (similar to Render/3D) + if 'Graphics Pipe' in grbm: + gfx_pipe = grbm['Graphics Pipe'] + if 'value' in gfx_pipe: + detailed_info['engine_render'] = f"{gfx_pipe['value']:.1f}%" + + # Parse GRBM2 for additional engine info + if 'GRBM2' in device: + grbm2 = device['GRBM2'] + + # Texture Cache (similar to Blitter) + if 'Texture Cache' in grbm2: + tex_cache = grbm2['Texture Cache'] + if 'value' in tex_cache: + detailed_info['engine_blitter'] = f"{tex_cache['value']:.1f}%" + # Parse processes (fdinfo) if 'fdinfo' in device: fdinfo = device['fdinfo'] @@ -3871,11 +3891,14 @@ def api_network_interface_metrics(interface_name): print(f"[v0] ===== NETWORK INTERFACE METRICS REQUEST EXCEPTION =====") return jsonify({'error': str(e)}), 500 +# ... existing code ... + @app.route('/api/vms', methods=['GET']) def api_vms(): """Get virtual machine information""" return jsonify(get_proxmox_vms()) +# Add the new api_vm_metrics endpoint here @app.route('/api/vms//metrics', methods=['GET']) def api_vm_metrics(vmid): """Get historical metrics (RRD data) for a specific VM/LXC"""