mirror of
https://github.com/snowykami/server-status-client.git
synced 2026-01-25 05:01:50 +00:00
Compare commits
25 Commits
c271378c71
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| 7ee3eb377e | |||
| 90b4952ea9 | |||
| 0559212d03 | |||
| e74324e21b | |||
| 48ac46bbb3 | |||
| b5ba568a66 | |||
| b30b3429ad | |||
| 7cbca85a60 | |||
| ce3a07e350 | |||
| 9160e7c4b4 | |||
| 8e2c5c24b8 | |||
| c63d84106b | |||
| 0d7b7700de | |||
| b5bf2c1de6 | |||
| 87418edeea | |||
| 5c089873ca | |||
| 79242f9dd6 | |||
| 22feee38ee | |||
| e0aa6adbeb | |||
| 87859a58f8 | |||
| d1098cf735 | |||
| 62096e5f4d | |||
| 26db6fe7d0 | |||
| 3b09c0650d | |||
| fb7e3144d3 |
21
LICENSE
Normal file
21
LICENSE
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2024 Snowykami
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
78
README.md
78
README.md
@@ -19,37 +19,46 @@ _✨ 服务器状态 - 客户端 ✨_
|
|||||||
|
|
||||||
服务器状态的客户端命令行工具
|
服务器状态的客户端命令行工具
|
||||||
|
|
||||||
|
- 跨平台支持
|
||||||
|
- 自动上报服务器状态
|
||||||
|
- 支持自定义标签、地域、链接等信息
|
||||||
|
|
||||||
## 💿 安装
|
## 💿 安装
|
||||||
|
- 先决条件:`curl` `python3` `pip` `venv` `git`
|
||||||
|
|
||||||
- Linux 可使用脚本安装,带自动部署和自启动
|
- Linux 可使用脚本安装,带自动部署和自启动
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
curl -sSL https://raw.githubusercontent.com/snowykami/server-status-client/refs/heads/main/deploy.sh | sudo bash
|
sudo bash -c "$(curl -sSL https://raw.githubusercontent.com/snowykami/server-status-client/refs/heads/main/deploy.sh)"
|
||||||
```
|
```
|
||||||
|
如果位于中国大陆无法访问GitHub,可使用中国版脚本
|
||||||
|
```shell
|
||||||
|
sudo bash -c "$(curl -sSL https://git.liteyuki.icu/snowykami/server-status-client/raw/branch/main/deploy-cn.sh)"
|
||||||
|
```
|
||||||
|
|
||||||
- 或手动部署
|
- 或手动部署
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
# 克隆仓库
|
# 克隆仓库
|
||||||
git clone https://github.com/snowykami/server-status-client
|
git clone https://github.com/snowykami/server-status-client
|
||||||
cd server-status-client
|
cd server-status-client
|
||||||
|
|
||||||
# 配置环境
|
# 配置环境
|
||||||
python3 -m venv venv
|
python3 -m venv venv
|
||||||
source venv/bin/activate
|
source venv/bin/activate
|
||||||
# 安装依赖
|
# 安装依赖
|
||||||
pip install pdm
|
pip install pdm
|
||||||
pdm install
|
pdm install
|
||||||
|
|
||||||
# 如需自启动请自行添加到系统服务
|
# 如需自启动请自行添加到系统服务
|
||||||
```
|
```
|
||||||
|
|
||||||
## 🎉 使用
|
## 🎉 使用
|
||||||
|
|
||||||
### 命令
|
### 命令
|
||||||
|
|
||||||
- `server-status <server> <token> <id> run` - 运行客户端
|
- `python main.py <server> <token> <id> run` - 运行客户端
|
||||||
- `server-status <server> <token> <id> rm` - 从服务端移除主机
|
- `python.main.py <server> <token> <id> rm` - 从服务端移除主机
|
||||||
|
|
||||||
#### 可选项
|
#### 可选项
|
||||||
|
|
||||||
@@ -62,47 +71,20 @@ pdm install
|
|||||||
#### 示例
|
#### 示例
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
server_status https://status.liteyuki.icu 114514 myhost run -n "MyHost" --labels "标签1,标签2" --interval 5 --location "Chongqing" --link "https://example.com"
|
python main.py https://status.liteyuki.icu 114514 myhost run -n "MyHost" --labels "标签1,标签2" --interval 5 --location "Chongqing" --link "https://example.com"
|
||||||
```
|
```
|
||||||
|
|
||||||
## 📝 其他
|
## 📝 其他
|
||||||
|
|
||||||
### 开机启动
|
### 开机启动
|
||||||
|
|
||||||
执行以下命令
|
- 安装脚本已自动添加到系统服务
|
||||||
|
|
||||||
```shell
|
|
||||||
sudo pipx ensurepath # 确保pipx路径在环境变量下
|
|
||||||
|
|
||||||
sudo touch /etc/systemd/system/server-status-client.service
|
|
||||||
|
|
||||||
sudo bash -c 'cat <<EOF > /etc/systemd/system/server-status-client.service
|
|
||||||
[Unit]
|
|
||||||
Description=Server Status Client
|
|
||||||
After=network-online.target
|
|
||||||
|
|
||||||
[Service]
|
|
||||||
Type=simple
|
|
||||||
ExecStart=server-status <server> <token> <id> run # 请替换为实际参数
|
|
||||||
Restart=on-failure
|
|
||||||
RestartSec=10
|
|
||||||
|
|
||||||
[Install]
|
|
||||||
WantedBy=multi-user.target
|
|
||||||
EOF'
|
|
||||||
|
|
||||||
sudo systemctl enable server-status-client
|
|
||||||
sudo systemctl start server-status-client
|
|
||||||
```
|
|
||||||
|
|
||||||
### 更新
|
### 更新
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
git pull
|
git pull
|
||||||
sudo systemctl restart server-status-client
|
sudo systemctl restart server-status-client
|
||||||
#
|
|
||||||
git pull
|
|
||||||
systemctl restart server-status-client
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### 服务端
|
### 服务端
|
||||||
|
|||||||
96
deploy-cn.sh
Executable file
96
deploy-cn.sh
Executable file
@@ -0,0 +1,96 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# 部署脚本中国大陆可用版本
|
||||||
|
|
||||||
|
# check if sudo is used
|
||||||
|
if [ "$EUID" -ne 0 ]; then
|
||||||
|
echo "Please run as root"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# check install dir
|
||||||
|
install_dir="/opt"
|
||||||
|
echo -n "安装目录? (默认: $install_dir/server-status-client): " && read -r install_dir_input
|
||||||
|
if [ -n "$install_dir_input" ]; then
|
||||||
|
install_dir="$install_dir_input"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# check server
|
||||||
|
echo -n "服务端地址? (必须): " && read -r server
|
||||||
|
if [ -z "$server" ]; then
|
||||||
|
echo "服务端地址是必须的"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# check token
|
||||||
|
echo -n "令牌? (必须或留空): " && read -r token
|
||||||
|
|
||||||
|
# check hostname
|
||||||
|
hostname=$(hostname)
|
||||||
|
echo -n "此主机名? (默认: $hostname): " && read -r hostname_input
|
||||||
|
if [ -n "$hostname_input" ]; then
|
||||||
|
hostname="$hostname_input"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# labels
|
||||||
|
echo -n "标签们? (空格分隔): " && read -r labels_input
|
||||||
|
if [ -n "$labels_input" ]; then
|
||||||
|
labels="$labels_input"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# location
|
||||||
|
echo -n "地理位置? (可选|自定义): " && read -r location_input
|
||||||
|
if [ -n "$location_input" ]; then
|
||||||
|
location="$location_input"
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
repo2="https://git.liteyuki.icu/snowykami/server-status-client"
|
||||||
|
# try 1 if failed try 2
|
||||||
|
git clone "$repo2" "$install_dir/server-status-client"
|
||||||
|
cd "$install_dir/server-status-client" || { echo "克隆失败"; exit 1; }
|
||||||
|
|
||||||
|
# create venv
|
||||||
|
python3 -m venv venv
|
||||||
|
python_exe="./venv/bin/python"
|
||||||
|
|
||||||
|
# check if venv is created
|
||||||
|
if [ ! -f "$python_exe" ]; then
|
||||||
|
echo "创建虚拟环境失败"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
echo "虚拟环境创建成功"
|
||||||
|
|
||||||
|
# install the required packages
|
||||||
|
echo "正在安装依赖包..."
|
||||||
|
$python_exe -m pip install pdm -i https://mirrors.tuna.tsinghua.edu.cn/pypi/web/simple
|
||||||
|
$python_exe -m pdm install
|
||||||
|
|
||||||
|
# create the systemd service
|
||||||
|
echo "正在创建服务..."
|
||||||
|
|
||||||
|
# generate random id
|
||||||
|
# shellcheck disable=SC2002
|
||||||
|
id=$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 8 | head -n 1)
|
||||||
|
|
||||||
|
bash -c "cat <<EOF > /etc/systemd/system/server-status-client.service
|
||||||
|
[Unit]
|
||||||
|
Description=Server Status Client
|
||||||
|
After=network-online.target
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=simple
|
||||||
|
ExecStart=$install_dir/server-status-client/venv/bin/python main.py $server $token $id run -n $hostname --labels $labels --location $location
|
||||||
|
WorkingDirectory=$install_dir/server-status-client
|
||||||
|
Restart=on-failure
|
||||||
|
RestartSec=10
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
|
EOF"
|
||||||
|
|
||||||
|
# enable and start the service
|
||||||
|
systemctl enable server-status-client
|
||||||
|
systemctl start server-status-client
|
||||||
|
|
||||||
|
echo "安装完成,服务已启动"
|
||||||
37
deploy.sh
37
deploy.sh
@@ -64,9 +64,6 @@ if [ ! -f "$python_exe" ]; then
|
|||||||
fi
|
fi
|
||||||
echo "venv created successfully"
|
echo "venv created successfully"
|
||||||
|
|
||||||
# activate the virtual environment
|
|
||||||
|
|
||||||
|
|
||||||
# install the required packages
|
# install the required packages
|
||||||
echo "Installing the required packages"
|
echo "Installing the required packages"
|
||||||
$python_exe -m pip install pdm
|
$python_exe -m pip install pdm
|
||||||
@@ -77,26 +74,26 @@ echo "Creating the systemd service"
|
|||||||
|
|
||||||
# generate random id
|
# generate random id
|
||||||
# shellcheck disable=SC2002
|
# shellcheck disable=SC2002
|
||||||
id=$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 32 | head -n 1)
|
id=$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 8 | head -n 1)
|
||||||
|
|
||||||
#bash -c "cat <<EOF > /etc/systemd/system/server-status-client.service
|
bash -c "cat <<EOF > /etc/systemd/system/server-status-client.service
|
||||||
#[Unit]
|
[Unit]
|
||||||
#Description=Server Status Client
|
Description=Server Status Client
|
||||||
#After=network-online.target
|
After=network-online.target
|
||||||
#
|
|
||||||
#[Service]
|
[Service]
|
||||||
#Type=simple
|
Type=simple
|
||||||
#ExecStart=$install_dir/server-status-client/venv/bin/python main.py $server $token $id run -n $hostname --labels $labels --location $location
|
ExecStart=$install_dir/server-status-client/venv/bin/python main.py $server $token $id run -n $hostname --labels $labels --location $location
|
||||||
#WorkingDirectory=$install_dir/server-status-client
|
WorkingDirectory=$install_dir/server-status-client
|
||||||
#Restart=on-failure
|
Restart=on-failure
|
||||||
#RestartSec=10
|
RestartSec=10
|
||||||
#
|
|
||||||
#[Install]
|
[Install]
|
||||||
#WantedBy=multi-user.target
|
WantedBy=multi-user.target
|
||||||
#EOF"
|
EOF"
|
||||||
|
|
||||||
# enable and start the service
|
# enable and start the service
|
||||||
systemctl enable server-status-client
|
systemctl enable server-status-client
|
||||||
systemctl start server-status-client
|
systemctl start server-status-client
|
||||||
|
|
||||||
echo "server-status-client installed successfully"
|
echo "server-status-client installed successfully"
|
||||||
@@ -31,5 +31,5 @@ tag_filter = "v*"
|
|||||||
tag_regex = '^v(?:\D*)?(?P<version>([1-9][0-9]*!)?(0|[1-9][0-9]*)(\.(0|[1-9][0-9]*))*((a|b|c|rc)(0|[1-9][0-9]*))?(\.post(0|[1-9][0-9]*))?(\.dev(0|[1-9][0-9]*))?$)$'
|
tag_regex = '^v(?:\D*)?(?P<version>([1-9][0-9]*!)?(0|[1-9][0-9]*)(\.(0|[1-9][0-9]*))*((a|b|c|rc)(0|[1-9][0-9]*))?(\.post(0|[1-9][0-9]*))?(\.dev(0|[1-9][0-9]*))?$)$'
|
||||||
|
|
||||||
[[tool.pdm.source]]
|
[[tool.pdm.source]]
|
||||||
name = "tuna"
|
name = "pypi"
|
||||||
url = "https://mirrors.tuna.tsinghua.edu.cn/pypi/web/simple"
|
url = "https://mirrors.tuna.tsinghua.edu.cn/pypi/web/simple"
|
||||||
@@ -8,7 +8,41 @@ import requests
|
|||||||
|
|
||||||
from server_status.timezone import get_timezone
|
from server_status.timezone import get_timezone
|
||||||
|
|
||||||
excluded_partition_prefix = ("/var", "/boot", "/run", "/proc", "/sys", "/dev", "/tmp", "/snap")
|
excluded_partition_prefix = (
|
||||||
|
"/var",
|
||||||
|
"/boot",
|
||||||
|
"/run",
|
||||||
|
"/proc",
|
||||||
|
"/sys",
|
||||||
|
"/dev",
|
||||||
|
"/tmp",
|
||||||
|
"/snap",
|
||||||
|
|
||||||
|
"/System",
|
||||||
|
"/Applications",
|
||||||
|
"/private",
|
||||||
|
"/Library",
|
||||||
|
)
|
||||||
|
|
||||||
|
include_partition_prefix_mac = ("/Volumes")
|
||||||
|
|
||||||
|
os_name = "" # linux下为发行版名称,windows下为Windows, macOS下为Darwin
|
||||||
|
os_version = "" # linux下为发行版版本,windows下为Windows版本
|
||||||
|
try:
|
||||||
|
# read /etc/os-release
|
||||||
|
with open("/etc/os-release") as f:
|
||||||
|
os_release = f.read()
|
||||||
|
# 找到NAME=和VERSION=的行
|
||||||
|
for line in os_release.split("\n"):
|
||||||
|
if line.startswith("NAME="):
|
||||||
|
os_name = line.split("=")[1].replace('"', "")
|
||||||
|
elif line.startswith("VERSION_ID="):
|
||||||
|
os_version = line.split("=")[1].replace('"', "")
|
||||||
|
except FileNotFoundError:
|
||||||
|
os_name = platform.system()
|
||||||
|
os_version = platform.release()
|
||||||
|
|
||||||
|
print("Current OS:", os_name, os_version)
|
||||||
|
|
||||||
|
|
||||||
def log(*args):
|
def log(*args):
|
||||||
@@ -29,6 +63,7 @@ def get_network_speed(interval) -> tuple[int, int]:
|
|||||||
|
|
||||||
|
|
||||||
class Hardware:
|
class Hardware:
|
||||||
|
os_release: str = ""
|
||||||
mem_total: int = psutil.virtual_memory().total
|
mem_total: int = psutil.virtual_memory().total
|
||||||
mem_used: int = psutil.virtual_memory().used
|
mem_used: int = psutil.virtual_memory().used
|
||||||
|
|
||||||
@@ -112,7 +147,9 @@ class Api:
|
|||||||
"""
|
"""
|
||||||
self.headers.update(self.format(headers))
|
self.headers.update(self.format(headers))
|
||||||
|
|
||||||
def format(self, obj: str | list[str] | dict[str, Any]) -> str | list[str] | dict[str, Any]:
|
def format(
|
||||||
|
self, obj: str | list[str] | dict[str, Any]
|
||||||
|
) -> str | list[str] | dict[str, Any]:
|
||||||
if isinstance(obj, str):
|
if isinstance(obj, str):
|
||||||
obj = obj.format(**self.variables)
|
obj = obj.format(**self.variables)
|
||||||
elif isinstance(obj, dict):
|
elif isinstance(obj, dict):
|
||||||
@@ -125,8 +162,17 @@ class Api:
|
|||||||
|
|
||||||
|
|
||||||
class Client:
|
class Client:
|
||||||
def __init__(self, addr: str, token: str, client_id: str, name: str = "", location: str = "", labels: list[str] = [], link: str = "",
|
def __init__(
|
||||||
interval: int = 2):
|
self,
|
||||||
|
addr: str,
|
||||||
|
token: str,
|
||||||
|
client_id: str,
|
||||||
|
name: str = "",
|
||||||
|
location: str = "",
|
||||||
|
labels: list[str] = [],
|
||||||
|
link: str = "",
|
||||||
|
interval: int = 2,
|
||||||
|
):
|
||||||
self.api = Api(addr, {"token": token, "id": client_id})
|
self.api = Api(addr, {"token": token, "id": client_id})
|
||||||
self.api = self.api.group("/client")
|
self.api = self.api.group("/client")
|
||||||
self.api.add_headers(Authorization="{token}")
|
self.api.add_headers(Authorization="{token}")
|
||||||
@@ -140,15 +186,66 @@ class Client:
|
|||||||
self.link = link
|
self.link = link
|
||||||
self.interval = interval
|
self.interval = interval
|
||||||
|
|
||||||
self.start_time = psutil.boot_time()
|
self.start_time: float = psutil.boot_time()
|
||||||
|
|
||||||
self.hardware = Hardware()
|
self.hardware = Hardware()
|
||||||
|
|
||||||
log("Client initialized",
|
log(
|
||||||
f"Name: {self.name}({self.client_id}), Location: {self.location}, Labels: {self.labels}")
|
"Client initialized",
|
||||||
|
f"Name: {self.name}({self.client_id}), Location: {self.location}, Labels: {self.labels}",
|
||||||
|
)
|
||||||
|
|
||||||
def start(self):
|
def start(self):
|
||||||
self.observe()
|
log("Starting client")
|
||||||
|
threading.Thread(target=self._start_obs, daemon=True).start()
|
||||||
|
threading.Thread(target=self._start_post, daemon=True).start()
|
||||||
|
|
||||||
|
while True:
|
||||||
|
time.sleep(1)
|
||||||
|
|
||||||
|
def _start_obs(self):
|
||||||
|
"""启动监控记录线程"""
|
||||||
|
while True:
|
||||||
|
try:
|
||||||
|
self.hardware.mem_total = psutil.virtual_memory().total
|
||||||
|
self.hardware.mem_used = psutil.virtual_memory().used
|
||||||
|
self.hardware.swap_total = psutil.swap_memory().total
|
||||||
|
self.hardware.swap_used = psutil.swap_memory().used
|
||||||
|
self.hardware.cpu_cores = psutil.cpu_count(logical=False)
|
||||||
|
self.hardware.cpu_logics = psutil.cpu_count(logical=True)
|
||||||
|
for part in psutil.disk_partitions():
|
||||||
|
try:
|
||||||
|
usage = psutil.disk_usage(part.mountpoint)
|
||||||
|
|
||||||
|
if (
|
||||||
|
(
|
||||||
|
platform.system() in ("Linux", "Darwin")
|
||||||
|
and (
|
||||||
|
part.mountpoint.startswith(
|
||||||
|
excluded_partition_prefix
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
):
|
||||||
|
continue
|
||||||
|
|
||||||
|
self.hardware.disks[part.device] = {
|
||||||
|
"mountpoint": part.mountpoint,
|
||||||
|
"device": part.device,
|
||||||
|
"fstype": part.fstype,
|
||||||
|
"total": usage.total,
|
||||||
|
"used": usage.used,
|
||||||
|
}
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
self.hardware.cpu_percent = psutil.cpu_percent(1)
|
||||||
|
self.hardware.net_up, self.hardware.net_down = get_network_speed(1)
|
||||||
|
log("Observed")
|
||||||
|
except Exception as e:
|
||||||
|
log(f"Failed to observe: {e}")
|
||||||
|
|
||||||
|
def _start_post(self):
|
||||||
|
"""启动上报进程"""
|
||||||
while True:
|
while True:
|
||||||
try:
|
try:
|
||||||
resp = self.get_ping()
|
resp = self.get_ping()
|
||||||
@@ -156,9 +253,13 @@ class Client:
|
|||||||
log(f"Connected to server {self.addr}")
|
log(f"Connected to server {self.addr}")
|
||||||
break
|
break
|
||||||
else:
|
else:
|
||||||
log(f"Failed to connect to server {self.addr}, retrying in 5 seconds: {resp.text}")
|
log(
|
||||||
|
f"Failed to connect to server {self.addr}, retrying in 5 seconds: {resp.text}"
|
||||||
|
)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
log(f"Failed to connect to server {self.addr}, retrying in 5 seconds: {e}")
|
log(
|
||||||
|
f"Failed to connect to server {self.addr}, retrying in 5 seconds: {e}"
|
||||||
|
)
|
||||||
time.sleep(5)
|
time.sleep(5)
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
@@ -185,10 +286,11 @@ class Client:
|
|||||||
"id": self.client_id,
|
"id": self.client_id,
|
||||||
"name": self.name,
|
"name": self.name,
|
||||||
"os": {
|
"os": {
|
||||||
"name": platform.system(),
|
"name": platform.system(), # 系统类型 linux|windows|darwin
|
||||||
"version": platform.version(),
|
"version": os_name + os_version,
|
||||||
"machine": platform.machine(),
|
# 系统版本复杂描述 #1 SMP PREEMPT_DYNAMIC Fri Sep 13 10:42:50 UTC 2024 (5c05eeb)
|
||||||
"release": platform.release(),
|
"machine": platform.machine(), # 机器类型 x86_64
|
||||||
|
"release": os_version, # 系统版本
|
||||||
},
|
},
|
||||||
"labels": self.labels,
|
"labels": self.labels,
|
||||||
"location": self.location,
|
"location": self.location,
|
||||||
@@ -221,42 +323,5 @@ class Client:
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
def observe(self):
|
|
||||||
"""
|
|
||||||
观察硬件状态并更新
|
|
||||||
Returns:
|
|
||||||
|
|
||||||
"""
|
|
||||||
|
|
||||||
def _observe():
|
|
||||||
while True:
|
|
||||||
self.hardware.mem_total = psutil.virtual_memory().total
|
|
||||||
self.hardware.mem_used = psutil.virtual_memory().used
|
|
||||||
self.hardware.swap_total = psutil.swap_memory().total
|
|
||||||
self.hardware.swap_used = psutil.swap_memory().used
|
|
||||||
self.hardware.cpu_cores = psutil.cpu_count(logical=False)
|
|
||||||
self.hardware.cpu_logics = psutil.cpu_count(logical=True)
|
|
||||||
for part in psutil.disk_partitions():
|
|
||||||
try:
|
|
||||||
usage = psutil.disk_usage(part.mountpoint)
|
|
||||||
|
|
||||||
if part.mountpoint.startswith(excluded_partition_prefix) or usage.total == 0:
|
|
||||||
continue
|
|
||||||
|
|
||||||
self.hardware.disks[part.device] = {
|
|
||||||
"mountpoint": part.mountpoint,
|
|
||||||
"device": part.device,
|
|
||||||
"fstype": part.fstype,
|
|
||||||
"total": usage.total,
|
|
||||||
"used": usage.used,
|
|
||||||
}
|
|
||||||
except:
|
|
||||||
pass
|
|
||||||
self.hardware.cpu_percent = psutil.cpu_percent(1)
|
|
||||||
self.hardware.net_up, self.hardware.net_down = get_network_speed(1)
|
|
||||||
log("Observed")
|
|
||||||
|
|
||||||
threading.Thread(target=_observe, daemon=True).start()
|
|
||||||
|
|
||||||
def remove(self, client_id) -> requests.Response:
|
def remove(self, client_id) -> requests.Response:
|
||||||
return self.api.delete("/host", data={"id": client_id})
|
return self.api.delete("/host", data={"id": client_id})
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import socket
|
|||||||
|
|
||||||
from arclet.alconna import Alconna, Subcommand, Option, Args, MultiVar
|
from arclet.alconna import Alconna, Subcommand, Option, Args, MultiVar
|
||||||
|
|
||||||
server_status_alc = Alconna(
|
server_status_alc = Alconna( # type: ignore
|
||||||
"server_status",
|
"server_status",
|
||||||
Args["server", str]["token", str]["id", str],
|
Args["server", str]["token", str]["id", str],
|
||||||
Subcommand(
|
Subcommand(
|
||||||
|
|||||||
Reference in New Issue
Block a user