import os import platform import sys from datetime import datetime, timedelta from typing import List, Any import psutil from config import get_settings from entity.dto.monitor_dto import CpuInfo, MemoryInfo, SystemInfo, DiskInfo, PythonEnvInfo from utils.ip_utils import IpUtil def get_attr(obj: Any, attr: str, default: Any = None) -> Any: return getattr(obj, attr, default) class ServerInfoUtils: """服务器相关信息""" datetime_fmt = get_settings().datetime_fmt @staticmethod def get_size(data, suffix='B') -> str: """ 按照正确的格式缩放字节 eg: 1253656 => '1.20MB' 1253656678 => '1.17GB' """ factor = 1024 for unit in ['', 'K', 'M', 'G', 'T', 'P']: if data < factor: return f'{data:.2f}{unit}{suffix}' data /= factor @staticmethod def fmt_timedelta(td: timedelta) -> str: """格式化显示timedelta eg: timedelta => xx天xx小时xx分钟 """ rem = td.seconds days, rem = rem // 86400, rem % 86400 hours, rem = rem // 3600, rem % 3600 minutes = rem // 60 res = f'{minutes}分钟' if hours > 0: res = f'{hours}小时{res}' if days > 0: res = f'{days}天{res}' return res @staticmethod def get_cpu_info() -> CpuInfo: """获取CPU信息""" res = {'cpu_num': psutil.cpu_count(logical=True)} cpu_times = psutil.cpu_times() total = cpu_times.user + cpu_times.nice + cpu_times.system + cpu_times.idle \ + get_attr(cpu_times, 'iowait', 0.0) + get_attr(cpu_times, 'irq', 0.0) \ + get_attr(cpu_times, 'softirq', 0.0) + get_attr(cpu_times, 'steal', 0.0) res['total'] = round(total, 2) res['sys'] = round(cpu_times.system / total, 2) res['used'] = round(cpu_times.user / total, 2) res['wait'] = round(get_attr(cpu_times, 'iowait', 0.0) / total, 2) res['free'] = round(cpu_times.idle / total, 2) return CpuInfo(**res) @staticmethod def get_mem_info() -> MemoryInfo: """获取内存信息""" number = 1024 ** 3 return MemoryInfo(**{ 'total': round(psutil.virtual_memory().total / number, 2), 'used': round(psutil.virtual_memory().used / number, 2), 'free': round(psutil.virtual_memory().available / number, 2), 'usage': round(psutil.virtual_memory().percent, 2)}) @staticmethod def get_sys_info() -> SystemInfo: """获取服务器信息""" return SystemInfo(**{ 'computerName': IpUtil.get_host_name(), 'computerIp': IpUtil.get_host_ip(), 'userDir': os.path.dirname(os.path.abspath(os.path.join(__file__, '../..'))), 'osName': platform.system(), 'osArch': platform.machine()}) @staticmethod def get_disk_info() -> List[DiskInfo]: """获取磁盘信息""" disk_info = [] for disk in psutil.disk_partitions(): usage = psutil.disk_usage(disk.mountpoint) disk_info.append(DiskInfo(**{ 'dirName': disk.mountpoint, 'sysTypeName': disk.fstype, 'typeName': disk.device, 'total': ServerInfoUtils.get_size(usage.total), 'free': ServerInfoUtils.get_size(usage.free), 'used': ServerInfoUtils.get_size(usage.used), 'usage': round(usage.percent, 2), })) return disk_info @staticmethod def get_py_info(): """获取Python环境及服务信息""" number = 1024 ** 2 cur_proc = psutil.Process(os.getpid()) mem_info = cur_proc.memory_info() start_dt = datetime.fromtimestamp(cur_proc.create_time()) return PythonEnvInfo(**{ 'name': 'Python', 'version': platform.python_version(), 'home': sys.executable, 'inputArgs': '[{}]'.format(', '.join(sys.argv[1:])), 'total': round(mem_info.vms / number, 2), 'max': round(mem_info.vms / number, 2), 'free': round((mem_info.vms - mem_info.rss) / number, 2), 'usage': round(mem_info.rss / number, 2), 'runTime': ServerInfoUtils.fmt_timedelta(datetime.now() - start_dt), 'startTime': start_dt.strftime(ServerInfoUtils.datetime_fmt), })