# -*- coding: utf-8 -*- # @Author : YY from datetime import datetime import json import time import os import platform import sys from flask import current_app import psutil from typing import Dict, List from typing_extensions import Annotated from pydantic import BaseModel, Field from ruoyi_common.base.model import strict_base_config from ruoyi_common.utils import IpUtil class Cpu(BaseModel): model_config = strict_base_config # 核心数 cpu_num: int # CPU总的使用率 total: float # CPU系统使用率 sys: float # CPU用户使用率 used: float # CPU当前等待率 wait: float # CPU当前空闲率 free: float @classmethod def from_module(cls) -> "Cpu": """ 获取CPU信息 Returns: Cpu: CPU信息 """ scputimes = psutil.cpu_times_percent(1) nice = getattr(scputimes, 'nice', 0) irq = getattr(scputimes, 'irq', 0) softirq = getattr(scputimes, 'softirq', 0) steal = getattr(scputimes, 'steal', 0) used = getattr(scputimes, 'user', 0) sys = getattr(scputimes,'system', 0) wait = getattr(scputimes, 'iowait', 0) free = getattr(scputimes, 'idle', 0) total = used + sys + wait + free + nice + irq + softirq + steal return cls( cpu_num=psutil.cpu_count(), total=total, sys=sys, used=used, wait=wait, free=free ) class Memory(BaseModel): model_config = strict_base_config # 内存总量 total: str # 已用内存 used: str # 剩余内存 free: str @classmethod def from_module(cls) -> "Memory": """ 获取内存信息 Returns: Memory: 内存信息 """ memory = psutil.virtual_memory() total = cls.bytes_to_gb(memory.total) used = cls.bytes_to_gb(memory.used) free = cls.bytes_to_gb(memory.free) return cls(total=total, used=used, free=free) @classmethod def bytes_to_gb(cls, val:int) -> str: return "{:.2f}".format(val / 1024 / 1024 / 1024) class Jvm(BaseModel): model_config = strict_base_config # 当前JVM占用的内存总数(M) total: float = 0 # JVM最大可用内存总数(M) max: float = 0 # JVM空闲内存(M) free: float = 0 # JDK版本 version: str = "" # JDK路径 home: str = "" name: str = "[java示例,非python示例] 请执行 bash patch.sh upgrade", usage: float = 75.76, used: float = 1015.63, start_time: str = "2024-11-11 12:00:50", input_args: str = "[java示例,非python示例] 请执行 bash patch.sh upgrade" run_time: str = "2小时12分钟" class SystemFile(BaseModel): model_config = strict_base_config # 盘符路径 dir_name: str # 盘符类型 sys_type_name: str # 文件类型 type_name: str # 总大小 total: str # 剩余大小 free: str # 已经使用量 used: str # 资源的使用率 usage: float class System(BaseModel): model_config = strict_base_config # 服务器名称 computer_name: str # 服务器IP地址 computer_ip: str # 项目路径 user_dir: str # 操作系统 os_name:str # 系统架构 os_arch:str @classmethod def from_module(cls) -> "System": """ 获取服务器系统信息 Returns: System: 服务器系统信息 """ computer_name = platform.node() computer_ip = IpUtil.get_local_ips()[0] user_dir = current_app.extensions['flaskowl'].proot os_name = platform.system() os_arch = platform.machine() return cls( computer_name=computer_name, computer_ip=computer_ip, user_dir=user_dir, os_name=os_name, os_arch=os_arch ) class PyImplementation(BaseModel): model_config = strict_base_config # 当前Python占用的内存总数(MB) ##### 虚拟数据 ##### total: str # Python最大可用内存总数(MB) ##### 虚拟数据 ##### max: str # Python空闲内存(MB) ##### 虚拟数据 ##### free: str # Python解释器名称 name: str = "CPython" # Python内存使用率 ##### 虚拟数据 ##### usage: str # Python占用的内存总数 ##### 虚拟数据 ##### used: str # 启动时间 start_time: str = "", # 启动参数 input_args: str = "" # 运行时间 run_time: str = "" # Python版本 version: str # Python路径 home: str @classmethod def from_module(cls) -> "PyImplementation": """ 获取当前Python进程信息 Returns: PyImplementation: Python进程信息 """ proc = psutil.Process(os.getpid()) memory = proc.memory_info() total = memory.rss used = total usage = "30" name = platform.python_implementation() if hasattr(proc, 'rlimit'): max = proc.rlimit(psutil.RLIMIT_AS) else: max = 0 version = platform.python_version() home = sys.executable start_time = proc.create_time() run_time = time.time() - start_time input_args = json.dumps(proc.cmdline()) return cls( total = cls.bytes_to_mb(total), max = cls.bytes_to_mb(max), used = cls.bytes_to_mb(used), usage = usage, name = name, free = cls.bytes_to_mb(total) if max == 0 else cls.bytes_to_mb(max - total), version=version, home=home, start_time=datetime.fromtimestamp(start_time).strftime('%Y-%m-%d %H:%M:%S'), run_time=datetime.fromtimestamp(run_time).strftime('%H小时 %M分钟 %S秒'), input_args=input_args ) @classmethod def bytes_to_mb(cls, val:int) -> str: """ 字节转换为MB Args: val (int): 输入 Returns: str: 输出字符串 """ return "{:.2f}".format(val / 1024 / 1024) class Server(BaseModel): model_config = strict_base_config cpu: Cpu mem: Memory sys: System sys_files: List[SystemFile] = [] pyimp: PyImplementation = None jvm: Jvm = None @classmethod def from_module(cls) -> "Server": """ 获取服务器信息 Returns: Server: 服务器信息 """ cpu = Cpu.from_module() mem = Memory.from_module() sys = System.from_module() pyimp = PyImplementation.from_module() jvm = Jvm( total=1340.5, max=3579, free=324.87, version="[java示例,非python示例] 请执行 bash patch.sh upgrade", home="[java示例,非python示例 请执行 bash patch.sh upgrade", name="[java示例,非python示例 请执行 bash patch.sh upgrade", usage=75.76, used=1015.63, start_time="[java示例,非python示例 请执行 bash patch.sh upgrade", input_args="[java示例,非python示例 请执行 bash patch.sh upgrade", run_time="[java示例,非python示例 请执行 bash patch.sh upgrade" ) sys_files = [] for part in psutil.disk_partitions(): if os.name == 'nt': if 'cdrom' in part.opts or part.fstype == '': continue usage = psutil.disk_usage(part.mountpoint) sys_file = SystemFile( dirName=part.mountpoint, sysTypeName=part.fstype, typeName=part.device, total=cls.bytes_to_gb(usage.total), free=cls.bytes_to_gb(usage.free), used=cls.bytes_to_gb(usage.used), usage=usage.percent ) sys_files.append(sys_file) return cls(cpu=cpu, mem=mem, sys=sys, sys_files=sys_files, pyimp=pyimp, jvm=jvm) @classmethod def bytes_to_gb(cls, val:int) -> str: """ 字节转换为GB Args: val (int): 输入 Returns: str: 输出字符串 """ return "{:.2f}".format(val / 1024 / 1024 / 1024) + " GB" class RedisCommandStatsOption(BaseModel): name: str value: Annotated[str, Field(coerce_numbers_to_str=True)] class RedisCache(BaseModel): model_config = strict_base_config info: Dict = {} db_size: int command_stats: List[RedisCommandStatsOption] @classmethod def from_connection(cls, connection) -> "RedisCache": """ 获取Redis缓存信息 Args: connection (redis.Redis): Redis连接 Returns: RedisCache: Redis缓存信息 """ info = connection.info() db_size = connection.dbsize() _command_stats = connection.info('commandstats') command_stats = [] for key,value in _command_stats.items(): key = key.replace('cmdstat_', '') value = value["calls"] command_stats.append(RedisCommandStatsOption(name=key, value=value)) return cls(info=info, db_size=db_size, command_stats=command_stats)