Files
WGDashboard/src/modules/SystemStatus.py

204 lines
6.8 KiB
Python
Raw Normal View History

2025-09-13 08:23:54 +08:00
import shutil, subprocess, time, threading, psutil
from flask import current_app
2025-01-24 00:01:29 +08:00
class SystemStatus:
def __init__(self):
self.CPU = CPU()
self.MemoryVirtual = Memory('virtual')
self.MemorySwap = Memory('swap')
self.Disks = Disks()
self.NetworkInterfaces = NetworkInterfaces()
self.Processes = Processes()
def toJson(self):
process = [
threading.Thread(target=self.CPU.getCPUPercent),
threading.Thread(target=self.CPU.getPerCPUPercent),
threading.Thread(target=self.NetworkInterfaces.getData)
]
for p in process:
p.start()
for p in process:
p.join()
return {
"CPU": self.CPU,
"Memory": {
"VirtualMemory": self.MemoryVirtual,
"SwapMemory": self.MemorySwap
},
"Disks": self.Disks,
"NetworkInterfaces": self.NetworkInterfaces,
2025-08-27 17:48:28 +08:00
"NetworkInterfacesPriority": self.NetworkInterfaces.getInterfacePriorities(),
"Processes": self.Processes
}
2025-01-24 00:01:29 +08:00
class CPU:
def __init__(self):
self.cpu_percent: float = 0
self.cpu_percent_per_cpu: list[float] = []
2025-09-13 08:23:54 +08:00
def getCPUPercent(self):
try:
self.cpu_percent = psutil.cpu_percent(interval=1)
except Exception as e:
2025-09-13 08:23:54 +08:00
current_app.logger.error("Get CPU Percent error", e)
def getPerCPUPercent(self):
2025-01-24 00:01:29 +08:00
try:
self.cpu_percent_per_cpu = psutil.cpu_percent(interval=1, percpu=True)
2025-01-24 00:01:29 +08:00
except Exception as e:
2025-09-13 08:23:54 +08:00
current_app.logger.error("Get Per CPU Percent error", e)
2025-01-24 00:01:29 +08:00
def toJson(self):
return self.__dict__
class Memory:
def __init__(self, memoryType: str):
self.__memoryType__ = memoryType
2025-01-24 00:01:29 +08:00
self.total = 0
self.available = 0
self.percent = 0
def getData(self):
try:
if self.__memoryType__ == "virtual":
memory = psutil.virtual_memory()
2025-09-13 19:05:32 +08:00
self.available = memory.available
else:
memory = psutil.swap_memory()
2025-09-13 19:05:32 +08:00
self.available = memory.free
self.total = memory.total
2025-09-13 19:05:32 +08:00
self.percent = memory.percent
except Exception as e:
2025-09-13 08:23:54 +08:00
current_app.logger.error("Get Memory percent error", e)
2025-01-24 00:01:29 +08:00
def toJson(self):
self.getData()
return self.__dict__
class Disks:
def __init__(self):
self.disks : list[Disk] = []
def getData(self):
try:
self.disks = list(map(lambda x : Disk(x.mountpoint), psutil.disk_partitions()))
except Exception as e:
2025-09-13 08:23:54 +08:00
current_app.logger.error("Get Disk percent error", e)
def toJson(self):
self.getData()
return self.disks
2025-01-24 00:01:29 +08:00
class Disk:
def __init__(self, mountPoint: str):
self.total = 0
self.used = 0
self.free = 0
self.percent = 0
self.mountPoint = mountPoint
def getData(self):
try:
disk = psutil.disk_usage(self.mountPoint)
self.total = disk.total
self.free = disk.free
self.used = disk.used
self.percent = disk.percent
except Exception as e:
2025-09-13 08:23:54 +08:00
current_app.logger.error("Get Disk percent error", e)
2025-01-24 00:01:29 +08:00
def toJson(self):
self.getData()
return self.__dict__
class NetworkInterfaces:
def __init__(self):
self.interfaces = {}
2025-08-27 17:48:28 +08:00
def getInterfacePriorities(self):
if shutil.which("ip"):
result = subprocess.check_output(["ip", "route", "show"]).decode()
priorities = {}
for line in result.splitlines():
if "metric" in line and "dev" in line:
parts = line.split()
dev = parts[parts.index("dev")+1]
metric = int(parts[parts.index("metric")+1])
if dev not in priorities:
priorities[dev] = metric
return priorities
return {}
2025-01-24 00:01:29 +08:00
def getData(self):
2025-08-27 17:48:28 +08:00
self.interfaces.clear()
try:
network = psutil.net_io_counters(pernic=True, nowrap=True)
for i in network.keys():
self.interfaces[i] = network[i]._asdict()
time.sleep(1)
network = psutil.net_io_counters(pernic=True, nowrap=True)
for i in network.keys():
self.interfaces[i]['realtime'] = {
'sent': round((network[i].bytes_sent - self.interfaces[i]['bytes_sent']) / 1024 / 1024, 4),
'recv': round((network[i].bytes_recv - self.interfaces[i]['bytes_recv']) / 1024 / 1024, 4)
}
except Exception as e:
2025-09-13 08:23:54 +08:00
current_app.logger.error("Get network error", e)
2025-01-24 00:01:29 +08:00
def toJson(self):
return self.interfaces
2025-04-20 02:52:22 +08:00
class Process:
def __init__(self, name, command, pid, percent):
self.name = name
self.command = command
self.pid = pid
self.percent = percent
def toJson(self):
return self.__dict__
2025-01-24 00:01:29 +08:00
class Processes:
def __init__(self):
2025-04-21 17:25:12 +08:00
self.CPU_Top_10_Processes: list[Process] = []
self.Memory_Top_10_Processes: list[Process] = []
2025-01-24 00:01:29 +08:00
def getData(self):
try:
processes = list(psutil.process_iter())
cpu_processes = []
memory_processes = []
for proc in processes:
try:
name = proc.name()
cmdline = " ".join(proc.cmdline())
pid = proc.pid
cpu_percent = proc.cpu_percent()
mem_percent = proc.memory_percent()
# Create Process object for CPU and memory tracking
cpu_process = Process(name, cmdline, pid, cpu_percent)
mem_process = Process(name, cmdline, pid, mem_percent)
cpu_processes.append(cpu_process)
memory_processes.append(mem_process)
except (psutil.NoSuchProcess, psutil.AccessDenied, psutil.ZombieProcess):
# Skip processes we cant access or that no longer exist
continue
# Sort by CPU and memory usage (descending order)
cpu_sorted = sorted(cpu_processes, key=lambda p: p.percent, reverse=True)
mem_sorted = sorted(memory_processes, key=lambda p: p.percent, reverse=True)
# Get top 20 processes for each
self.CPU_Top_10_Processes = cpu_sorted[:20]
self.Memory_Top_10_Processes = mem_sorted[:20]
except Exception as e:
current_app.logger.error("Get processes error", e)
2025-09-13 08:23:54 +08:00
2025-01-24 00:01:29 +08:00
def toJson(self):
self.getData()
return {
"cpu_top_10": self.CPU_Top_10_Processes,
"memory_top_10": self.Memory_Top_10_Processes
}