diff --git a/active_connector.py b/active_connector.py index 75beaae..f5477d2 100644 --- a/active_connector.py +++ b/active_connector.py @@ -3,6 +3,7 @@ import threading import paramiko import time import json +import re class Connector: def __init__(self, data_dict : dict, server_cfg : dict, lock : threading.Lock, connect_check_interval : float, reconnect_interval : float, multiple_of_timeout : float = 2): @@ -58,7 +59,8 @@ class Connector: error_info_dict = dict() # 网络 信息 network_info = self.__get_network_info(client, interval*self.multiple_of_timeout, server.get('network_interface_name', None), error_info_dict) - # TODO CPU 信息 + # CPU 信息 + cpu_info = self.__get_cpu_info(client, interval*self.multiple_of_timeout, error_info_dict) # 内存 信息 memory_info = self.__get_memory_info(client, interval*self.multiple_of_timeout, error_info_dict) # 存储空间 信息 @@ -73,6 +75,8 @@ class Connector: shared_data_list[server_title]['title'] = server_title shared_data_list[server_title]['version'] = version shared_data_list[server_title]['update_time_stamp'] = int(time.time()) + if cpu_info is not None: + shared_data_list[server_title]['cpu'] = cpu_info if memory_info is not None: shared_data_list[server_title]['gpu_list'] = gpu_info if memory_info is not None: @@ -106,6 +110,7 @@ class Connector: time.sleep(re_connect_time) re_try_count += 1 + # 持续的将主动获取的服务器信息同步到最终信息中 def __transmit_data(self, interval): # 等待一点时间再开始 time.sleep(interval * 0.5) @@ -119,6 +124,89 @@ class Connector: #region 获取信息的方法 + def __get_cpu_info(self, client, timeout, info_dict:dict=None): + def get_cpu_temp_via_sysfs(client): + try: + command = r''' + for zone in /sys/class/thermal/thermal_zone*; do + if [ -f "$zone/type" ] && [ -f "$zone/temp" ]; then + type=$(cat "$zone/type") + temp=$(cat "$zone/temp") + echo "$type:$temp" + fi + done + ''' + stdin, stdout, stderr = client.exec_command(command) + output = stdout.read().decode().strip() + temperatures = [] + for line in output.splitlines(): + if ':' in line: + type_str, temp_str = line.split(':', 1) + if 'cpu' in type_str.lower() or 'pkg' in type_str.lower(): + try: + temp = int(temp_str.strip()) + temperatures.append(round(temp / 1000, 1)) # 转为摄氏度 + except ValueError: + continue + return temperatures + except Exception as e: + return [] + + def get_cpu_avg_usage_via_procstat(client, interval_sec=0.3): + def read_cpu_stat_line(): + stdin, stdout, _ = client.exec_command("grep '^cpu ' /proc/stat") + line = stdout.read().decode().strip() + parts = list(map(int, line.split()[1:])) + idle = parts[3] + parts[4] # idle + iowait + total = sum(parts) + return idle, total + try: + idle1, total1 = read_cpu_stat_line() + time.sleep(interval_sec) + idle2, total2 = read_cpu_stat_line() + + total_delta = total2 - total1 + idle_delta = idle2 - idle1 + + if total_delta == 0: + return 0.0 + usage = 100.0 * (1.0 - idle_delta / total_delta) + return round(usage, 1) + except Exception as e: + return None + + try: + result = dict() + # 1. 获取 CPU 型号 + stdin, stdout, stderr = client.exec_command("lscpu") + lscpu_output = stdout.read().decode() + model_match = re.search(r"Model name\s*:\s*(.+)", lscpu_output) + if model_match: + result["name"] = model_match.group(1).strip() + else: + # 如果没有找到“Model name”,则尝试匹配“型号名称” + model_name_match_cn = re.search(r'型号名称\s*:\s*(.+)', lscpu_output) + if model_name_match_cn: + result["name"] = model_name_match_cn.group(1).strip() + else: + result["name"] = "未知CPU" + + # 2. 获取 CPU 温度 + result["temperature_list"] = get_cpu_temp_via_sysfs(client) + + # 3. 获取 CPU 占用率 + result["core_avg_occupy"] = get_cpu_avg_usage_via_procstat(client) + result["core_occupy_list"] = [-1] # TODO 用现在这种方法去查询所有核心的消耗比较大,也没什么用处,暂时不查了 + + return result + except paramiko.ssh_exception.SSHException as e: + # ssh 的异常仍然抛出 + raise + except Exception as e: + if info_dict is not None: + info_dict['cpu'] = f'{e}' + return None + def __get_memory_info(self, client, timeout, info_dict:dict=None): try: stdin, stdout, stderr = client.exec_command('free', timeout=timeout) diff --git a/version.py b/version.py index 626d9d5..4e5e697 100644 --- a/version.py +++ b/version.py @@ -1 +1 @@ -version = "0.2.0.20250626_beta" \ No newline at end of file +version = "0.2.1.20250626_beta" \ No newline at end of file