|
|
@ -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) |
|
|
|