Skip to content

Commit

Permalink
Support client dynamic registration
Browse files Browse the repository at this point in the history
  • Loading branch information
zdz committed May 24, 2022
1 parent 3763423 commit bd23ccc
Show file tree
Hide file tree
Showing 20 changed files with 899 additions and 310 deletions.
88 changes: 54 additions & 34 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,17 @@
<img width="1215" alt="image" src="https://user-images.githubusercontent.com/152173/165957689-d35714a9-f7f8-49f7-9573-97d4cf3c2f79.png">
<img width="1436" alt="image" src="https://user-images.githubusercontent.com/152173/165958225-25fc8fda-5798-42f8-bac5-72d778c0bab5.png">

<h2>Table of Contents</h2>

- [✨ Rust 版 ServerStatus 云探针](#-rust-版-serverstatus-云探针)
- [1. 介绍](#1-介绍)
- [🍀 主题](#-主题)
- [2. 安装部署](#2-安装部署)
- [2.1 快速体验](#21-快速体验)
- [2.2 服务管理脚本部署,感谢 @Colsro 提供](#22-服务管理脚本部署感谢-colsro-提供)
- [2.3 Railway 部署](#23-railway-部署)
- [2.4 前后端分离部署](#24-前后端分离部署)
- [2.2 快速部署](#22-快速部署)
- [2.3 服务管理脚本部署,感谢 @Colsro 提供](#23-服务管理脚本部署感谢-colsro-提供)
- [2.4 Railway 部署](#24-railway-部署)
- [2.5 前后端分离部署](#25-前后端分离部署)
- [3. 服务端说明](#3-服务端说明)
- [3.1 配置文件 `config.toml`](#31-配置文件-configtoml)
- [3.2 服务端运行](#32-服务端运行)
Expand All @@ -38,15 +41,17 @@
- 支持 `systemd` 开机自启
- 其它功能,如 🗺️ 见 [wiki](https://github.com/zdz/ServerStatus-Rust/wiki)

演示:[tz-rust.vercel.app](https://tz-rust.vercel.app)
演示:[ssr.rs](https://d.ssr.rs) | [vercel.app](https://tz-rust.vercel.app)
|
下载:[Releases](https://github.com/zdz/ServerStatus-Rust/releases)
|
反馈:[Discussions](https://github.com/zdz/ServerStatus-Rust/discussions)

📕 完整文档迁移至 [doc.ssr.rs](https://doc.ssr.rs)

### 🍀 主题

如果你觉得你修改的主题还不错,欢迎分享/PR,前端单独部署方法参见 [#37](https://github.com/zdz/ServerStatus-Rust/discussions/37)
如果你觉得你创造/修改的主题还不错,欢迎分享/PR,前端单独部署方法参见 [#37](https://github.com/zdz/ServerStatus-Rust/discussions/37)

<details>
<summary>Hotaru 主题</summary>
Expand All @@ -70,7 +75,11 @@ bash -ex one-touch.sh
# 自定义部署可参照 one-touch.sh 脚本
```

### 2.2 服务管理脚本部署,感谢 [@Colsro](https://github.com/Colsro) 提供
### 2.2 快速部署

参见 [快速部署](https://doc.ssr.rs/rapid_deploy)

### 2.3 服务管理脚本部署,感谢 [@Colsro](https://github.com/Colsro) 提供
<details>
<summary>管理脚本使用说明</summary>

Expand Down Expand Up @@ -115,14 +124,14 @@ help:
</details>


### 2.3 Railway 部署
### 2.4 Railway 部署

懒得配置 `Nginx``SSL` 证书?试试
[在 Railway 部署 Server 教程](https://github.com/zdz/ServerStatus-Rust/wiki/Railway)

[![Deploy on Railway](https://railway.app/button.svg)](https://railway.app/new/template/kzT46l?referralCode=pJYbdU)

### 2.4 前后端分离部署
### 2.5 前后端分离部署

<details>
<summary>前后端分离部署</summary>
Expand Down Expand Up @@ -195,15 +204,26 @@ admin_pass = ""
# name 主机唯一标识,不可重复,alias 为展示名
# 使用 ansible 批量部署时可以用主机 hostname 作为 name,统一密码
# notify = false 单独禁止单台机器的告警,一般针对网络差,频繁上下线
# monthstart = 1 没启用 vnstat 时,表示月流量从每月哪天开始统计
# monthstart = 1 没启用vnstat时,表示月流量从每月哪天开始统计
# disabled = true 单机禁用,跟删除这条配置的效果一样
hosts = [
{name = "h1", password = "p1", alias = "n1", location = "🏠", type = "kvm"},
{name = "h2", password = "p2", alias = "n2", location = "🏢", type = "kvm", notify = true},
{name = "h3", password = "p3", alias = "n3", location = "🏝️", type = "kvm", monthstart = 1},
{name = "h4", password = "p4", alias = "n4", location = "🏢", type = "kvm", disabled = false},
{name = "h1", password = "p1", alias = "n1", location = "🏠", type = "kvm", notify = true},
{name = "h2", password = "p2", alias = "n2", location = "🏢", type = "kvm", disabled = false},
{name = "h3", password = "p3", alias = "n3", location = "🏡", type = "kvm", monthstart = 1},
]

# 动态注册模式,不再需要针对每一个主机做单独配置
# gid 为模板组id, 动态注册唯一标识,不可重复
hosts_group = [
# 可以按国家地区或用途来做分组
{gid = "g1", password = "pp", location = "🏠", type = "kvm", notify = true},
{gid = "g2", password = "pp", location = "🏢", type = "kvm", notify = true},
# 例如不发送通知可以单独做一组
{gid = "silent", password = "pp", location = "🏡", type = "kvm", notify = false},
]
# 动态注册模式下,无效数据清理间隔,默认 30s
group_gc = 30

# 不开启告警,可忽略后面配置,或者删除不需要的通知方式
# 告警间隔默认为30s
notify_interval = 30
Expand Down Expand Up @@ -277,27 +297,31 @@ docker-compose up -d
# rust client 可用参数
./stat_client -h
OPTIONS:
-6, --ipv6 ipv6 only, default:false
-a, --addr <ADDR> [default: http://127.0.0.1:8080/report]
--cm <CM_ADDR> China Mobile probe addr [default: cm.tz.cloudcpp.com:80]
--ct <CT_ADDR> China Telecom probe addr [default: ct.tz.cloudcpp.com:80]
--cu <CU_ADDR> China Unicom probe addr [default: cu.tz.cloudcpp.com:80]
--disable-extra disable extra info report, default:false
--disable-ping disable ping, default:false
--disable-tupd disable t/u/p/d, default:false
-h, --help Print help information
--ip-info show ip info, default:false
--json use json protocol, default:false
-n, --vnstat enable vnstat, default:false
-p, --pass <PASS> password [default: p1]
-u, --user <USER> username [default: h1]
-V, --version Print version information
-6, --ipv6 ipv6 only, default:false
-a, --addr <ADDR> [default: http://127.0.0.1:8080/report]
--alias <ALIAS> alias for host [default: unknown]
--cm <CM_ADDR> China Mobile probe addr [default: cm.tz.cloudcpp.com:80]
--ct <CT_ADDR> China Telecom probe addr [default: ct.tz.cloudcpp.com:80]
--cu <CU_ADDR> China Unicom probe addr [default: cu.tz.cloudcpp.com:80]
--disable-extra disable extra info report, default:false
--disable-ping disable ping, default:false
--disable-tupd disable t/u/p/d, default:false
-g, --gid <GID> group id [default: ]
-h, --help Print help information
--ip-info show ip info, default:false
--json use json protocol, default:false
-n, --vnstat enable vnstat, default:false
-p, --pass <PASS> password [default: p1]
-u, --user <USER> username [default: h1]
-V, --version Print version information
-w, --weight <WEIGHT> weight for rank [default: 0]

# 一些参数说明
--ip-info # 显示本机ip信息后立即退出,目前使用 ip-api.com 数据
--disable-extra # 不上报系统信息和IP信息
--disable-ping # 停用三网延时和丢包率探测
--disable-tupd # 不上报 tcp/udp/进程数/线程数,减少CPU占用
-w, --weight # 排序加分,微调让主机靠前显示,无强迫症可忽略
```

### 4.2 跨平台版本 (`Window`, `Linux`, `...`)
Expand Down Expand Up @@ -361,10 +385,6 @@ vnstat --version
vnstat -m
vnstat --json m

# server config.toml 开启 vnstat
# 从 v1.3.6 不再需要在 server 配置开启,client 自由选择启用与否,client 可部分打开,部分关闭
vnstat = true

# client 使用 -n 参数开启 vnstat 统计
./stat_client -a "grpc://127.0.0.1:9394" -u h1 -p p1 -n
#
Expand Down Expand Up @@ -449,8 +469,8 @@ OPTIONS:
<details>
<summary>关于这个轮子</summary>

之前一直在使用 `Prometheus` + `Grafana` + `Alertmanager` + `node_exporter` 做VPS监控,这也是业界比较成熟的监控方案,用过一段时间后,发现非生产环境的话,很多监控指标都用不上,反而显得有些重。
`ServerStatus` 很好,足够简单和轻量,一眼可以看尽大好山河,只是 `c++` 版本很久没迭代过,自己的一些需求在原版上不是很好修改,如自带 `tcp` 上报对跨区机器不是很友好,也不方便对上报的链路优化 等等。过年的时候正值疫情闲来无事,学习 `Rust` 正好需要个小项目练手,于是撸了个 `ServerStatus` 来练手,项目后面会继续维护但不会增加复杂的功能,保持小而美,简单部署,配合 [Uptime Kuma](https://github.com/louislam/uptime-kuma) 基本上可以满足个人大部分监控需求。
之前一直在使用 `Prometheus` + `Grafana` + `Alertmanager` + `node_exporter` 做VPS监控,这也是业界比较成熟的监控方案,用过一段时间后,发现非生产环境,很多监控指标都用不上,反而显得有些重。
`ServerStatus` 很好,足够简单和轻量,一眼可以看尽所有小机机,只是 `c++` 版本很久没迭代过,自己的一些需求在原版上不是很好修改,如自带 `tcp` 上报对跨区机器不是很友好,也不方便对上报的链路做优化 等等。过年的时候正值疫情闲来无事,学习 `Rust` 正好需要个小项目练手,于是撸了个 `ServerStatus` 来练手,项目后面会继续维护但不会增加复杂的功能,保持小而美,简单部署,配合 [Uptime Kuma](https://github.com/louislam/uptime-kuma) 基本上可以满足个人大部分监控需求。

</details>

Expand Down
3 changes: 2 additions & 1 deletion client/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[package]
edition = "2021"
name = "stat_client"
version = "1.4.2"
version = "1.5.0"

rust-version = "1.60"

Expand Down Expand Up @@ -35,6 +35,7 @@ sysinfo = "0.23"
tokio = {version = "1", features = ["full"]}
tonic = {version = "0.7", features = ["tokio-rustls"]}
tower = { version = "0.4" }
md5 = "0.7.0"

[features]
default = ["native"]
Expand Down
14 changes: 13 additions & 1 deletion client/src/grpc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,16 @@ pub async fn report(args: &Args, stat_base: &mut StatRequest) -> anyhow::Result<
);
}

let token = MetadataValue::try_from(format!("{}@_@{}", args.user, args.pass))?;
let auth_user: String;
let ssr_auth: &[u8];
if args.gid.is_empty() {
auth_user = args.user.to_string();
ssr_auth = b"single";
} else {
auth_user = args.gid.to_string();
ssr_auth = b"group";
}
let token = MetadataValue::try_from(format!("{}@_@{}", auth_user, args.pass))?;

let channel = Channel::from_shared(args.addr.to_string())?
.connect()
Expand All @@ -43,6 +52,9 @@ pub async fn report(args: &Args, stat_base: &mut StatRequest) -> anyhow::Result<
let grpc_client =
ServerStatusClient::with_interceptor(timeout_channel, move |mut req: Request<()>| {
req.metadata_mut().insert("authorization", token.clone());
req.metadata_mut()
.insert("ssr-auth", MetadataValue::try_from(ssr_auth).unwrap());

Ok(req)
});

Expand Down
48 changes: 41 additions & 7 deletions client/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,15 @@ pub struct Args {
json: bool,
#[clap(short = '6', long = "ipv6", help = "ipv6 only, default:false")]
ipv6: bool,
// #[clap(long = "debug", help = "debug mode, default:false")]
// debug: bool,
// for group
#[clap(short, long, default_value = "", help = "group id")]
gid: String,
#[clap(long = "alias", default_value = "unknown", help = "alias for host")]
alias: String,
#[clap(short, long, default_value = "0", help = "weight for rank")]
weight: u64,
}

fn sample_all(args: &Args, stat_base: &StatRequest) -> StatRequest {
Expand Down Expand Up @@ -145,8 +154,16 @@ fn http_report(args: &Args, stat_base: &mut StatRequest) -> Result<()> {

let client = http_client.clone();
let url = args.addr.to_string();
let auth_user = args.user.to_string();
let auth_pass = args.pass.to_string();
let auth_user: String;
let ssr_auth: &str;
if args.gid.is_empty() {
auth_user = args.user.to_string();
ssr_auth = "single";
} else {
auth_user = args.gid.to_string();
ssr_auth = "group";
}

// http
tokio::spawn(async move {
Expand All @@ -155,6 +172,7 @@ fn http_report(args: &Args, stat_base: &mut StatRequest) -> Result<()> {
.basic_auth(auth_user, Some(auth_pass))
.timeout(Duration::from_secs(3))
.header(header::CONTENT_TYPE, content_type)
.header("ssr-auth", ssr_auth)
.body(body_data.unwrap())
.send()
.await
Expand Down Expand Up @@ -196,7 +214,7 @@ async fn refresh_ip_info(args: &Args) {
#[tokio::main]
async fn main() -> Result<()> {
pretty_env_logger::init();
let args = Args::parse();
let mut args = Args::parse();
dbg!(&args);

if args.ip_info {
Expand All @@ -205,19 +223,21 @@ async fn main() -> Result<()> {
process::exit(0);
}

// support check
if !System::IS_SUPPORTED {
panic!("当前系统不支持,请切换到Python跨平台版本!");
}

let sys_info = sys_info::collect_sys_info(&args);
let sys_info_json = serde_json::to_string(&sys_info)?;
let sys_id = sys_info::gen_sys_id(&sys_info);
eprintln!("sys id: {}", sys_id);
eprintln!("sys info: {}", sys_info_json);

if let Ok(mut o) = G_CONFIG.lock() {
o.sys_info = Some(sys_info);
}

// support check
if !System::IS_SUPPORTED {
panic!("当前系统不支持,请切换到Python跨平台版本!");
}

// use native
#[cfg(all(feature = "native", not(feature = "sysinfo")))]
{
Expand Down Expand Up @@ -250,8 +270,22 @@ async fn main() -> Result<()> {
online4: ipv4,
online6: ipv6,
vnstat: args.vnstat,
weight: args.weight,
version: env!("CARGO_PKG_VERSION").to_string(),
..Default::default()
};
if !args.gid.is_empty() {
stat_base.gid = args.gid.to_owned();
if stat_base.name.eq("h1") {
stat_base.name = sys_id;
}
if args.alias.eq("unknown") {
args.alias = stat_base.name.to_owned();
} else {
stat_base.alias = args.alias.to_owned();
}
}
// dbg!(&stat_base);

if args.addr.starts_with("http") {
let result = http_report(&args, &mut stat_base);
Expand Down
17 changes: 17 additions & 0 deletions client/src/sys_info.rs
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ pub fn start_net_speed_collect_t() {
});
}

// TODO
pub fn sample(args: &Args, stat: &mut StatRequest) {
stat.version = env!("CARGO_PKG_VERSION").to_string();
stat.vnstat = args.vnstat;
Expand Down Expand Up @@ -211,3 +212,19 @@ pub fn collect_sys_info(args: &Args) -> SysInfo {

info_pb
}

pub fn gen_sys_id(sys_info: &SysInfo) -> String {
format!(
"{:x}",
md5::compute(format!(
"{}/{}/{}/{}/{}/{}/{}",
sys_info.host_name,
sys_info.os_name,
sys_info.os_arch,
sys_info.os_family,
sys_info.os_release,
sys_info.kernel_version,
sys_info.cpu_brand,
))
)
}
2 changes: 1 addition & 1 deletion common/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[package]
edition = "2021"
name = "stat_common"
version = "1.0.0"
version = "1.1.0"

authors = ["doge <[email protected]>"]
categories = ["monitoring-tools"]
Expand Down
9 changes: 6 additions & 3 deletions common/proto/server_status.proto
Original file line number Diff line number Diff line change
Expand Up @@ -89,13 +89,16 @@ message StatRequest {

optional SysInfo sys_info = 37;
optional IpInfo ip_info = 38;

// group
string gid = 39;
string alias = 40;
uint64 weight = 41;
}

message Response {
int32 code = 1;
string message = 2;
}

service ServerStatus {
rpc Report(StatRequest) returns (Response);
}
service ServerStatus { rpc Report(StatRequest) returns (Response); }
Loading

0 comments on commit bd23ccc

Please sign in to comment.