diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index e20a10f4..2c7fef5a 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -3,7 +3,7 @@ name: Release
on:
push:
tags:
- - "*"
+ - "v*"
workflow_dispatch:
@@ -14,64 +14,118 @@ jobs:
release:
name: Cross build for ${{ matrix.target }}
runs-on: ${{ matrix.os }}
+ permissions:
+ contents: write
strategy:
matrix:
include:
- os: ubuntu-latest
target: x86_64-unknown-linux-musl
suffix: ""
+ use-cross: true
+ cargo-flags: "--no-default-features --features stat_client/native"
- os: ubuntu-latest
target: aarch64-unknown-linux-musl
suffix: ""
+ use-cross: true
+ cargo-flags: "--no-default-features --features stat_client/native"
- # - os: macos-latest
- # target: x86_64-apple-darwin
- # suffix: ""
- # - os: macos-latest
- # target: aarch64-apple-darwin
- # suffix: ""
+ - os: ubuntu-latest
+ target: aarch64-linux-android
+ suffix: ""
+ use-cross: true
+ cargo-flags: ""
+ # 32bit
+ - os: ubuntu-latest
+ target: armv7-linux-androideabi
+ suffix: ""
+ use-cross: true
+ cargo-flags: ""
+
+ - os: ubuntu-latest
+ target: armv7-unknown-linux-musleabihf
+ suffix: ""
+ use-cross: true
+ cargo-flags: ""
+
+ - os: macos-latest
+ target: x86_64-apple-darwin
+ suffix: ""
+ use-cross: false
+ cargo-flags: ""
+ - os: macos-latest
+ target: aarch64-apple-darwin
+ suffix: ""
+ use-cross: true
+ cargo-flags: ""
+
+ - os: windows-latest
+ target: x86_64-pc-windows-msvc
+ suffix: .exe
+ use-cross: false
+ cargo-flags: ""
# - os: windows-latest
- # target: x86_64-pc-windows-msvc
+ # target: x86_64-pc-windows-gnu
# suffix: .exe
+ # use-cross: false
+ # cargo-flags: ""
+
steps:
- uses: actions/checkout@v3
- uses: actions-rs/toolchain@v1
with:
+ override: true
profile: minimal
toolchain: stable
- - name: Install cross
- run: cargo install cross
- - name: Run tests
- run: cross test --release --target ${{ matrix.target }} --verbose
+ target: ${{ matrix.target }}
+
+ - name: Install Protoc
+ if: matrix.os == 'windows-latest'
+ uses: arduino/setup-protoc@v1
+ with:
+ version: '3.x'
+ repo-token: ${{ secrets.GITHUB_TOKEN }}
+
- name: Build release
- run: cross build --release --target ${{ matrix.target }}
+ uses: actions-rs/cargo@v1
+ with:
+ command: build
+ use-cross: ${{ matrix.use-cross }}
+ args: --locked --release --target=${{ matrix.target }} ${{ matrix.cargo-flags }}
- - name: Install LLVM Strip
- if: matrix.os == 'ubuntu-latest'
- run: sudo apt-get install -y llvm
+ - name: Strip (MacOS/Window)
+ if: matrix.os != 'ubuntu-latest'
+ continue-on-error: true
+ run: |
+ strip target/${{ matrix.target }}/release/stat_server${{matrix.suffix}}
+ strip target/${{ matrix.target }}/release/stat_client${{matrix.suffix}}
+ cp config.toml target/${{ matrix.target }}/release/
+ cp systemd/stat_server.service target/${{ matrix.target }}/release/
+ cp systemd/stat_client.service target/${{ matrix.target }}/release/
- - name: LLVM Strip
+ - name: LLVM Strip (Linux)
if: matrix.os == 'ubuntu-latest'
continue-on-error: true
run: |
+ sudo apt-get install -y llvm
llvm-strip target/${{ matrix.target }}/release/stat_server${{matrix.suffix}}
llvm-strip target/${{ matrix.target }}/release/stat_client${{matrix.suffix}}
cp config.toml target/${{ matrix.target }}/release/
cp systemd/stat_server.service target/${{ matrix.target }}/release/
cp systemd/stat_client.service target/${{ matrix.target }}/release/
- - name: Run UPX
+ - name: Compress binaries
# Upx may not support some platforms. Ignore the errors
continue-on-error: true
# Disable upx for mips. See https://github.com/upx/upx/issues/387
- if: matrix.os == 'ubuntu-latest' && !contains(matrix.target, 'mips')
- uses: crazy-max/ghaction-upx@v2
+ if: true && !contains(matrix.target, 'mips')
+ uses: svenstaro/upx-action@v2
with:
- version: latest
+ strip: false
+ args: -q --best --lzma
files: |
target/${{ matrix.target }}/release/stat_server${{matrix.suffix}}
target/${{ matrix.target }}/release/stat_client${{matrix.suffix}}
- args: -q --best --lzma
- uses: actions/upload-artifact@v3
with:
@@ -83,8 +137,8 @@ jobs:
target/${{ matrix.target }}/release/stat_server.service
target/${{ matrix.target }}/release/stat_client.service
- - name: Zip Release For Server
- if: matrix.os == 'ubuntu-latest'
+ - name: Zip Release For Server (Linux)
+ if: matrix.os == 'ubuntu-latest' && contains(matrix.target, 'linux')
uses: TheDoctor0/zip-release@0.7.1
with:
type: zip
@@ -95,8 +149,8 @@ jobs:
stat_server.service
config.toml
- - name: Zip Release For Client
- if: matrix.os == 'ubuntu-latest'
+ - name: Zip Release For Client (Linux)
+ if: matrix.os == 'ubuntu-latest' && contains(matrix.target, 'linux')
uses: TheDoctor0/zip-release@0.7.1
with:
type: zip
@@ -106,20 +160,32 @@ jobs:
stat_client${{matrix.suffix}}
stat_client.service
- # - name: Zip Release For MacOS/Win
- # if: matrix.os != 'ubuntu-latest'
- # uses: TheDoctor0/zip-release@0.6.2
- # with:
- # type: zip
- # filename: ServerStatus-${{ matrix.target }}.zip
- # directory: target/${{ matrix.target }}/release/
- # path: |
- # stat_server${{matrix.suffix}}
- # stat_client${{matrix.suffix}}
+ - name: Zip Release For Server (MacOS/Window)
+ if: true && !contains(matrix.target, 'linux')
+ uses: TheDoctor0/zip-release@0.7.1
+ with:
+ type: zip
+ filename: server-${{ matrix.target }}.zip
+ directory: target/${{ matrix.target }}/release/
+ path: |
+ stat_server${{matrix.suffix}}
+ config.toml
+
+ - name: Zip Release For Client (MacOS/Window)
+ if: true && !contains(matrix.target, 'linux')
+ uses: TheDoctor0/zip-release@0.7.1
+ with:
+ type: zip
+ filename: client-${{ matrix.target }}.zip
+ directory: target/${{ matrix.target }}/release/
+ path: |
+ stat_client${{matrix.suffix}}
- name: Publish
uses: softprops/action-gh-release@v1
if: startsWith(github.ref, 'refs/tags/')
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
files: |
target/${{ matrix.target }}/release/server-${{ matrix.target }}.zip
diff --git a/README.md b/README.md
index 290e667c..826e1e8d 100644
--- a/README.md
+++ b/README.md
@@ -60,7 +60,8 @@
`ServerStatus` 威力加强版,保持轻量和简单部署,增加以下主要特性:
- 使用 `rust` 完全重写 `server`、`client`,单个执行文件部署
-- 支持上下线和简单自定义规则告警 (`telegram`、 `wechat`、 `email`、 `webhook`)
+- 多系统支持 `Linux`、`MacOS`、`Windows`、`Android`、`Raspberry Pi`
+- 支持上下线和简单自定义规则告警 (`telegram`、`wechat`、`email`、`webhook`)
- 支持 `http` 协议上报,方便部署到各免费容器服务和配合 `cf` 等优化上报链路
- 支持 `vnstat` 统计月流量,重启不丢流量数据
- 支持 `railway` 快速部署
@@ -77,6 +78,17 @@
📕 完整文档迁移至 [doc.ssr.rs](https://doc.ssr.rs)
+| OS | Release |
+| ---- | ---- |
+| Linux x86_64 | x86_64-unknown-linux-musl |
+| Linux arm64 | aarch64-unknown-linux-musl |
+| MacOS x86_64 | x86_64-apple-darwin |
+| MacOS arm64 | aarch64-apple-darwin |
+| Windows x86_64 | x86_64-pc-windows-msvc |
+| Raspberry Pi | armv7-unknown-linux-musleabihf |
+| Android 64bit | aarch64-linux-android |
+| Android 32bit | armv7-linux-androideabi |
+
### 🍀 主题
如果你觉得你创造/修改的主题还不错,欢迎分享/PR,前端单独部署方法参考 [#37](https://github.com/zdz/ServerStatus-Rust/discussions/37)
@@ -95,15 +107,15 @@ Hotaru 主题由 [@HinataKato](https://github.com/HinataKato) 修改提供,[
ServerStatus-web 主题由 [@mjjrock](https://github.com/mjjrock) 修改提供,[主题地址](https://github.com/mjjrock/ServerStatus-web)
-演示:[Demo](https://ssr-web.vercel.app)
-
- v1.5.7版本主题
+ v1.5.7 版本主题
+
+[演示:Demo](https://tz-rust.vercel.app)
@@ -123,7 +135,7 @@ bash -ex one-touch.sh
### 2.2 快速部署
-参见 [快速部署](https://doc.ssr.rs/rapid_deploy)
+👉 [快速部署](https://doc.ssr.rs/rapid_deploy)
### 2.3 服务管理脚本部署,感谢 [@Colsro](https://github.com/Colsro) 提供
@@ -309,6 +321,7 @@ OPTIONS:
-g, --gid group id [default: ]
-h, --help Print help information
--ip-info show ip info, default:false
+ --sys-info show sys info, default:false
--json use json protocol, default:false
--location location [default: ]
-n, --vnstat enable vnstat, default:false
@@ -321,6 +334,7 @@ OPTIONS:
# 一些参数说明
--ip-info # 显示本机ip信息后立即退出,目前使用 ip-api.com 数据
+--sys-info # 显示本机系统信息后立即退出
--disable-extra # 不上报系统信息和IP信息
--disable-ping # 停用三网延时和丢包率探测
--disable-tupd # 不上报 tcp/udp/进程数/线程数,减少CPU占用
@@ -406,7 +420,7 @@ python3 stat_client.py -a "http://127.0.0.1:8080/report" -u h1 -p p1 -n
如何使用自定义主题
-更灵活的方式见 [#37](https://github.com/zdz/ServerStatus-Rust/discussions/37)
+更简单的方式 👉 [#37](https://github.com/zdz/ServerStatus-Rust/discussions/37)
```nginx
server {
@@ -478,7 +492,7 @@ OPTIONS:
关于这个轮子
- 之前一直在使用 `Prometheus` + `Grafana` + `Alertmanager` + `node_exporter` 做VPS监控,这也是业界比较成熟的监控方案,用过一段时间后,发现非生产环境,很多监控指标都用不上,反而显得有些重。
+ 之前一直在使用 `Prometheus` + `Grafana` + `Alertmanager` + `node_exporter` 做VPS监控,这也是业界比较成熟的监控方案,用过一段时间后,发现非生产环境,很多监控指标都用不上,运维成本有点大。
而 `ServerStatus` 很好,足够简单和轻量,一眼可以看尽所有小机机,只是 `c++` 版本很久没迭代过,自己的一些需求在原版上不是很好修改,如自带 `tcp` 上报对跨区机器不是很友好,也不方便对上报的链路做优化 等等。这是学习 `Rust` 练手的小项目,所以不会增加复杂功能,保持小而美,简单部署,配合 [Uptime Kuma](https://github.com/louislam/uptime-kuma) 基本上可以满足个人大部分监控需求。
diff --git a/client/Cargo.toml b/client/Cargo.toml
index ecb5006b..5ecb645d 100644
--- a/client/Cargo.toml
+++ b/client/Cargo.toml
@@ -34,13 +34,13 @@ reqwest = {version = "0.11", features = ["json", "rustls-tls", "brotli", "gzip",
serde = {version = "1.0", default-features = false, features = ["derive", "alloc"]}
serde_json = {version = "1.0", default-features = false, features = ["alloc"]}
stat_common = {path = "../common"}
-sysinfo = "0.26"
+sysinfo = "0.27.7"
tokio = {version = "1", features = ["full"]}
tonic = {version = "0.8", features = ["tokio-rustls"]}
tower = { version = "0.4" }
md5 = "0.7.0"
[features]
-default = ["native"]
+default = ["sysinfo"]
native = []
sysinfo = []
diff --git a/client/src/main.rs b/client/src/main.rs
index 058bda25..4c5c52a2 100644
--- a/client/src/main.rs
+++ b/client/src/main.rs
@@ -86,6 +86,8 @@ pub struct Args {
cm_addr: String,
#[arg(long = "cu", env = "SSR_CU_ADDR", default_value = CU, help = "China Unicom probe addr")]
cu_addr: String,
+ #[arg(long = "sys-info", help = "show sys info, default:false")]
+ sys_info: bool,
#[arg(long = "ip-info", help = "show ip info, default:false")]
ip_info: bool,
#[arg(long = "json", help = "use json protocol, default:false")]
@@ -155,7 +157,7 @@ fn sample_all(args: &Args, stat_base: &StatRequest) -> StatRequest {
// dbg!(&stat_base);
let mut stat_rt = stat_base.clone();
- #[cfg(all(feature = "native", not(feature = "sysinfo")))]
+ #[cfg(all(feature = "native", not(feature = "sysinfo"), target_os = "linux"))]
status::sample(args, &mut stat_rt);
#[cfg(all(feature = "sysinfo", not(feature = "native")))]
sys_info::sample(args, &mut stat_rt);
@@ -303,14 +305,19 @@ async fn main() -> Result<()> {
eprintln!("sys id: {sys_id}");
eprintln!("sys info: {sys_info_json}");
+ if args.sys_info {
+ sys_info::print_sysinfo();
+ process::exit(0);
+ }
+
if let Ok(mut o) = G_CONFIG.lock() {
o.sys_info = Some(sys_info);
}
// use native
- #[cfg(all(feature = "native", not(feature = "sysinfo")))]
+ #[cfg(all(feature = "native", not(feature = "sysinfo"), target_os = "linux"))]
{
- eprintln!("enable feature native");
+ eprintln!("feature native enabled");
status::start_cpu_percent_collect_t();
status::start_net_speed_collect_t(&args);
}
@@ -318,9 +325,9 @@ async fn main() -> Result<()> {
// use sysinfo
#[cfg(all(feature = "sysinfo", not(feature = "native")))]
{
- eprintln!("enable feature sysinfo");
+ eprintln!("feature sysinfo enabled");
sys_info::start_cpu_percent_collect_t();
- sys_info::start_net_speed_collect_t();
+ sys_info::start_net_speed_collect_t(&args);
}
status::start_all_ping_collect_t(&args);
diff --git a/client/src/status.rs b/client/src/status.rs
index 58a98315..a0fce2fa 100644
--- a/client/src/status.rs
+++ b/client/src/status.rs
@@ -1,4 +1,4 @@
-// #![allow(unused)]
+#![allow(unused)]
use lazy_static::lazy_static;
use once_cell::sync::OnceCell;
use regex::Regex;
diff --git a/client/src/sys_info.rs b/client/src/sys_info.rs
index 463d6b9b..17d8c4d4 100644
--- a/client/src/sys_info.rs
+++ b/client/src/sys_info.rs
@@ -1,11 +1,13 @@
#![deny(warnings)]
#![allow(unused)]
use lazy_static::lazy_static;
+use std::collections::HashSet;
use std::fs;
use std::sync::Arc;
use std::sync::Mutex;
use std::thread;
use std::time::Duration;
+use sysinfo::CpuRefreshKind;
use sysinfo::{CpuExt, DiskExt, NetworkExt, RefreshKind, System, SystemExt};
use crate::status;
@@ -18,6 +20,7 @@ const SAMPLE_PERIOD: u64 = 1000; //ms
lazy_static! {
pub static ref G_EXPECT_FS: Vec<&'static str> = [
"apfs",
+ "hfs",
"ext4",
"ext3",
"ext2",
@@ -38,15 +41,15 @@ lazy_static! {
pub static ref G_CPU_PERCENT: Arc> = Arc::new(Default::default());
}
pub fn start_cpu_percent_collect_t() {
- let mut sys = System::new_all();
- sys.refresh_cpu();
+ let mut sys = System::new_with_specifics(RefreshKind::new().with_cpu(CpuRefreshKind::new().with_cpu_usage()));
thread::spawn(move || loop {
+ sys.refresh_cpu();
+
let global_cpu = sys.global_cpu_info();
if let Ok(mut cpu_percent) = G_CPU_PERCENT.lock() {
*cpu_percent = global_cpu.cpu_usage().round() as f64;
}
- sys.refresh_cpu();
thread::sleep(Duration::from_millis(SAMPLE_PERIOD));
});
}
@@ -62,8 +65,8 @@ lazy_static! {
}
pub fn start_net_speed_collect_t(args: &Args) {
- let mut sys = System::new_all();
- sys.refresh_all();
+ let mut sys = System::new_with_specifics(RefreshKind::new().with_networks().with_networks_list());
+ sys.refresh_networks();
let args_1 = args.clone();
thread::spawn(move || loop {
let (mut net_rx, mut net_tx) = (0_u64, 0_u64);
@@ -85,19 +88,28 @@ pub fn start_net_speed_collect_t(args: &Args) {
});
}
-// TODO
pub fn sample(args: &Args, stat: &mut StatRequest) {
stat.version = env!("CARGO_PKG_VERSION").to_string();
stat.vnstat = args.vnstat;
// 注意:sysinfo 统一使用 KB, 非KiB,需要转换一下
- let mut sys = System::new_with_specifics(RefreshKind::new().with_disks_list().with_memory());
+ let mut unit: u64 = 1024;
+
+ // mac系统 下面使用 KB 展示
+ #[cfg(target_os = "macos")]
+ {
+ stat.si = true;
+ unit = 1000;
+ }
- sys.refresh_system();
- // sys.refresh_processes();
- // sys.refresh_memory();
- // sys.refresh_disks();
- sys.refresh_disks_list();
+ let mut sys = System::new_with_specifics(
+ RefreshKind::new()
+ .with_memory()
+ .with_disks()
+ .with_disks_list()
+ .with_networks()
+ .with_networks_list(),
+ );
// uptime
stat.uptime = sys.uptime();
@@ -107,36 +119,45 @@ pub fn sample(args: &Args, stat: &mut StatRequest) {
stat.load_5 = load_avg.five;
stat.load_15 = load_avg.fifteen;
- // mem KB -> KiB
- let (mem_total, mem_used, swap_total, swap_free) = (
- sys.total_memory() * 1000 / 1024,
- sys.used_memory() * 1000 / 1024,
- sys.total_swap() * 1000 / 1024,
- sys.free_swap() * 1000 / 1024,
- );
- stat.memory_total = mem_total;
- stat.memory_used = mem_used;
- stat.swap_total = swap_total;
- stat.swap_used = swap_total - swap_free;
+ // mem 不用转。。。(KB -> KiB)
+ stat.memory_total = sys.total_memory() / 1024;
+ #[cfg(any(target_os = "macos"))]
+ {
+ stat.memory_used = (sys.total_memory() - sys.available_memory()) / 1024;
+ }
+ #[cfg(not(target_os = "macos"))]
+ {
+ stat.memory_used = sys.used_memory() / 1024;
+ }
+ stat.swap_total = sys.total_swap() / 1024;
+ stat.swap_used = (sys.total_swap() - sys.free_swap()) / 1024;
- // hdd KB -> KiB
+ // hdd KB -> KiB
let (mut hdd_total, mut hdd_avail) = (0_u64, 0_u64);
+ let mut uniq_disk_set = HashSet::new();
for disk in sys.disks() {
let fs = String::from_utf8_lossy(disk.file_system()).to_lowercase();
if G_EXPECT_FS.iter().any(|&k| fs.contains(k)) {
+ if uniq_disk_set.contains(disk.name()) {
+ continue;
+ }
+ uniq_disk_set.insert(disk.name());
+
hdd_total += disk.total_space();
hdd_avail += disk.available_space();
}
}
- stat.hdd_total = hdd_total / 1024 / 1024;
- stat.hdd_used = (hdd_total - hdd_avail) / 1024 / 1024;
- // t/u/p/d TODO
+ stat.hdd_total = hdd_total / unit.pow(2);
+ stat.hdd_used = (hdd_total - hdd_avail) / unit.pow(2);
+
+ // t/u/p/d
let (t, u, p, d) = if args.disable_tupd {
(0, 0, 0, 0)
} else if "linux".eq(std::env::consts::OS) {
status::tupd()
} else {
+ // sys.processes()
(0, 0, 0, 0)
};
stat.tcp = t;
@@ -146,13 +167,15 @@ pub fn sample(args: &Args, stat: &mut StatRequest) {
// traffic
if args.vnstat {
- let (network_in, network_out, m_network_in, m_network_out) = vnstat::get_traffic(args).unwrap();
- stat.network_in = network_in;
- stat.network_out = network_out;
- stat.last_network_in = network_in - m_network_in;
- stat.last_network_out = network_out - m_network_out;
+ #[cfg(any(target_os = "linux"))]
+ {
+ let (network_in, network_out, m_network_in, m_network_out) = vnstat::get_traffic(args).unwrap();
+ stat.network_in = network_in;
+ stat.network_out = network_out;
+ stat.last_network_in = network_in - m_network_in;
+ stat.last_network_out = network_out - m_network_out;
+ }
} else {
- sys.refresh_networks();
let (mut network_in, mut network_out) = (0_u64, 0_u64);
for (name, data) in sys.networks() {
// spec iface
@@ -193,8 +216,8 @@ pub fn sample(args: &Args, stat: &mut StatRequest) {
pub fn collect_sys_info(args: &Args) -> SysInfo {
let mut info_pb = SysInfo::default();
- let mut sys = System::new_all();
- sys.refresh_all();
+ let mut sys = System::new();
+ sys.refresh_cpu();
info_pb.name = args.user.to_owned();
info_pb.version = env!("CARGO_PKG_VERSION").to_string();
@@ -222,7 +245,7 @@ pub fn gen_sys_id(sys_info: &SysInfo) -> String {
match fs::read_to_string(SYS_ID_FILE) {
Ok(content) => {
- if (content.len() > 0) {
+ if (!content.is_empty()) {
info!("{}", format!("read sys_id from {SYS_ID_FILE}"));
return content.trim().to_string();
}
@@ -232,7 +255,7 @@ pub fn gen_sys_id(sys_info: &SysInfo) -> String {
}
}
- let mut sys = System::new_all();
+ let mut sys = System::new();
let bt = sys.boot_time();
let sys_id = format!(
@@ -262,6 +285,67 @@ pub fn gen_sys_id(sys_info: &SysInfo) -> String {
sys_id
}
-// pub fn get_sys_id(sys_info: &SysInfo) -> String {
-// return ''.to_string();
-// }
+pub fn print_sysinfo() {
+ use sysinfo::{NetworkExt, NetworksExt, ProcessExt, System, SystemExt};
+ let mut sys = System::new_all();
+ sys.refresh_all();
+
+ println!("=> disks:");
+ for disk in sys.disks() {
+ println!(
+ "\t{}\t{}\t{}/{} B\tremovable:{}\tmounted on:{}",
+ disk.name().to_str().unwrap_or_default(),
+ String::from_utf8(disk.file_system().into()).unwrap_or_default(),
+ disk.available_space(),
+ disk.total_space(),
+ disk.is_removable(),
+ disk.mount_point().to_str().unwrap_or_default(),
+ );
+ // println!("\t{:?}", disk);
+ }
+
+ // Network interfaces name, data received and data transmitted:
+ println!("=> networks:");
+ for (interface_name, data) in sys.networks() {
+ println!("\t{}: \t{}/{} B", interface_name, data.received(), data.transmitted());
+ }
+
+ // Components temperature:
+ println!("=> components:");
+ for component in sys.components() {
+ println!("\t{component:?}");
+ }
+
+ println!("=> system:");
+ // RAM and swap information:
+ println!("\ttotal memory: {} bytes", sys.total_memory());
+ println!("\tused memory : {} bytes", sys.used_memory());
+ println!("\tavai memory : {} bytes", sys.available_memory());
+ println!("\tfree memory : {} bytes", sys.free_memory());
+ println!("\ttotal swap : {} bytes", sys.total_swap());
+ println!("\tused swap : {} bytes", sys.used_swap());
+
+ // Display system information:
+ println!("\tSystem name: {:?}", sys.name());
+ println!("\tSystem kernel version: {:?}", sys.kernel_version());
+ println!("\tSystem OS version: {:?}", sys.os_version());
+ println!("\tSystem host name: {:?}", sys.host_name());
+
+ let load_avg = sys.load_average();
+ println!(
+ "\tone minute: {:.2}, five minutes: {:.2}, fifteen minutes: {:.2}",
+ load_avg.one, load_avg.five, load_avg.fifteen,
+ );
+
+ // Number of CPUs:
+ let global_cpu = sys.global_cpu_info();
+ println!("\tCPU Num: {}", sys.cpus().len());
+ println!("\tCPU Brand: {}", global_cpu.brand());
+ println!("\tCPU VerderId: {}", global_cpu.vendor_id());
+ // println!("\tCPU Frequency: {}", global_cpu.frequency());
+
+ // Display processes ID, name na disk usage:
+ // for (pid, process) in sys.processes() {
+ // println!("[{}] {} {:?}", pid, process.name(), process.disk_usage());
+ // }
+}
diff --git a/common/Cargo.toml b/common/Cargo.toml
index dfa2473c..969b1a0a 100644
--- a/common/Cargo.toml
+++ b/common/Cargo.toml
@@ -1,7 +1,7 @@
[package]
edition = "2021"
name = "stat_common"
-version = "1.1.1"
+version = "1.1.2"
authors = ["doge "]
categories = ["monitoring-tools"]
@@ -19,7 +19,11 @@ prost = "0.11"
serde = {version = "1.0", default-features = false, features = ["derive", "alloc"]}
tonic = {version = "0.8", features = ["tokio-rustls"]}
-[build-dependencies]
+[target.'cfg(not(target_env = "msvc"))'.build-dependencies]
chrono = "0.4"
protobuf-src = "1"
tonic-build = "0.8"
+
+[build-dependencies]
+chrono = "0.4"
+tonic-build = "0.8"
diff --git a/common/build.rs b/common/build.rs
index 5b958af6..5b6f643b 100644
--- a/common/build.rs
+++ b/common/build.rs
@@ -22,7 +22,9 @@ fn main() {
}
println!("cargo:rustc-env=APP_VERSION={app_version}");
+ #[cfg(not(target_env = "msvc"))]
std::env::set_var("PROTOC", protobuf_src::protoc());
+
tonic_build::configure()
.type_attribute(".", "#[derive(serde::Serialize, serde::Deserialize)]")
.compile(&["proto/server_status.proto"], &["proto"])
diff --git a/common/proto/server_status.proto b/common/proto/server_status.proto
index fb8a60f0..d60767c1 100644
--- a/common/proto/server_status.proto
+++ b/common/proto/server_status.proto
@@ -98,6 +98,8 @@ message StatRequest {
string type = 42;
string location = 43;
bool notify = 44;
+ // false: KiB (1024), true: KB (1000)
+ bool si = 45;
}
message Response {
diff --git a/config.toml b/config.toml
index ada61928..312568dc 100644
--- a/config.toml
+++ b/config.toml
@@ -5,6 +5,7 @@ http_addr = "0.0.0.0:8080"
offline_threshold = 30
# 管理员账号,不设置默认随机生成,用于查看 /detail, /map
+jwt_secret = "" # 修改这个, 使用 openssl rand -base64 16 生成 secret
admin_user = ""
admin_pass = ""
@@ -17,12 +18,18 @@ admin_pass = ""
# 或国家缩写,如 cn us 等等,所有国家见目录 web/static/flags
# 自定义标签 labels = "os=centos;ndd=2022/11/25;spec=2C/4G/60G;"
# os 标签可选,不填则使用上报数据,ndd(next due date) 下次续费时间, spec 为主机规格
-# os 可用值 centos debian ubuntu alpine pi arch windows linux
+# os 可用值 centos debian ubuntu alpine pi arch windows linux macos android
hosts = [
{name = "h1", password = "p1", alias = "n1", location = "🏠", type = "kvm", labels = "os=arch;ndd=2022/11/25;spec=2C/4G/60G;"},
{name = "h2", password = "p2", alias = "n2", location = "🏢", type = "kvm", disabled = false},
{name = "h3", password = "p3", alias = "n3", location = "🏡", type = "kvm", monthstart = 1},
{name = "h4", password = "p4", alias = "n4", location = "cn", type = "kvm", notify = true, labels = "ndd=2022/11/25;spec=2C/4G/60G;"},
+
+ # 最小化配置
+ {name = "mac", password = "pp", alias = "macos"},
+ {name = "pi", password = "pp", alias = "pi", labels = "os=pi"},
+ {name = "win", password = "pp", alias = "windows"},
+ {name = "android", password = "pp", alias = "android", labels = "os=android"},
]
# 动态注册模式,不再需要针对每一个主机做单独配置
diff --git a/server/Cargo.toml b/server/Cargo.toml
index c2253246..2cec4325 100644
--- a/server/Cargo.toml
+++ b/server/Cargo.toml
@@ -20,13 +20,13 @@ chrono = "0.4"
[dependencies]
anyhow = "1"
+axum = {version = "0.6.4", features = ["headers"]}
bytes = {version = "1", features = ["serde"]}
chrono = "0.4"
clap = {version = "4.1", features = ["derive", "unicode"]}
-futures = "0.3"
futures-util = {version = "0.3", default-features = false}
-http-auth-basic = "0.3"
hyper = {version = "0.14", features = ["full"]}
+jsonwebtoken = "8.0"
lazy_static = "1.4"
lettre = {version = "0.10", default-features = false, features = ["smtp-transport", "pool", "hostname", "builder", "rustls-tls", "tokio1-rustls-tls"]}
log = "0.4"
diff --git a/server/src/stats.rs b/server/src/stats.rs
index 89dec6ef..53f309bd 100644
--- a/server/src/stats.rs
+++ b/server/src/stats.rs
@@ -250,7 +250,9 @@ impl StatsMgr {
}
// labels
- const OS_LIST: [&str; 7] = ["centos", "debian", "ubuntu", "pi", "arch", "windows", "linux"];
+ const OS_LIST: [&str; 9] = [
+ "centos", "debian", "ubuntu", "arch", "windows", "macos", "pi", "android", "linux",
+ ];
if !o.labels.contains("os=") {
if let Some(sys_info) = &o.sys_info {
let os_r = sys_info.os_release.to_lowercase();