-
-
Notifications
You must be signed in to change notification settings - Fork 330
/
config.toml
328 lines (302 loc) · 13.2 KB
/
config.toml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
# 侦听地址, ipv6 使用 [::]:9394
grpc_addr = "0.0.0.0:9394"
http_addr = "0.0.0.0:8080"
# 默认30s无上报判定下线
offline_threshold = 30
# 开启 grpc TLS, 0:关闭 1: TLS 2: mTLS
grpc_tls = 0
# 证书最终路径 ${workspace}/${tls_dir}, 包含 server.pem, server.key 文件
tls_dir = "tls"
# 管理员账号,不设置默认随机生成,用于查看 /detail, /map
jwt_secret = "" # 修改这个, 使用 openssl rand -base64 16 生成 secret
admin_user = ""
admin_pass = ""
# hosts 跟 hosts_group 两种配置模式任挑一种配置即可
# name 主机唯一标识,不可重复,alias 为展示名
# notify = false 单独禁止单台机器的告警,一般针对网络差,频繁上下线
# monthstart = 1 没启用vnstat时,表示月流量从每月哪天开始统计
# disabled = true 单机禁用
# location 支持国旗 emoji https://emojixd.com/group/flags
# 或国家缩写,如 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 macos android freebsd
hosts = [
{name = "h1", password = "p1", alias = "n1", location = "🏠", type = "kvm", labels = "os=freebsd;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"},
]
# 动态注册模式,不再需要针对每一个主机做单独配置
# gid 为模板组id, 自动注册唯一标识,不可重复
# eg. ./stat_client -a "http://127.0.0.1:8080/report" -g g1 -p pp
hosts_group = [
# 可以按国家地区或用途来做分组
{gid = "g1", password = "pp", location = "🏠", type = "kvm", labels = "os=centos;ndd=2022/11/25;spec=2C/4G/60G;"},
{gid = "g2", password = "pp", location = "🏢", type = "kvm", notify = true},
# 例如不发送通知可以单独做一组
{gid = "silent", password = "pp", location = "🏡", type = "kvm", notify = false},
]
# 动态注册模式下,无效数据清理间隔,默认 30s
# 这个设置要比较通知间隔 notify_interval 大,不然收不到告警通知
group_gc = 30
# !!! 一键部署如果没问题则不需要动,Server 会自行根据你的域名生成 server_url
# 修正一键部署,请自行替换 ssr.rs 为你的域名,
# server_url = "https://ssr.rs/report"
# stat_client 默认安装的路径
workspace = "/opt/ServerStatus"
# 不开启告警,可忽略后面配置,或者删除不需的通知方式
# 告警间隔默认为30s
notify_interval = 30
# https://core.telegram.org/bots/api
# https://jinja.palletsprojects.com/en/3.0.x/templates/#if
[tgbot]
# 开关 true 打开
enabled = false
bot_token = "<tg bot token>"
chat_id = "<chat id>"
# host 可用字段见 payload.rs 文件 HostStat 结构, {{host.xxx}} 为占位变量
# 例如 host.name 可替换为 host.alias,大家根据自己的喜好来编写通知消息
# {{ip_info.query}} 主机 ip, {{sys_info.host_name}} 主机 hostname,见 server_status.proto
title = "❗<b>Server Status</b>"
online_tpl = "{{config.title}} \n😆 {{host.location}} {{host.name}} 主机恢复上线啦"
offline_tpl = "{{config.title}} \n😱 {{host.location}} {{host.name}} 主机已经掉线啦"
# custom 模板置空则停用自定义告警,只保留上下线通知
custom_tpl = """
{% if host.memory_used / host.memory_total > 0.5 %}
<pre>😲 {{host.name}} 主机内存使用率超50%, 当前{{ (100 * host.memory_used / host.memory_total) | round }}% </pre>
{% endif %}
{% if host.hdd_used / host.hdd_total > 0.5 %}
<pre>😲 {{host.name}} 主机硬盘使用率超50%, 当前{{ (100 * host.hdd_used / host.hdd_total) | round }}% </pre>
{% endif %}
"""
###################### tgbot end ##########################
## 可选 单纯记录 event 到日志文件,调试自定义告警使用
[log]
enabled = false
log_dir = "/opt/ServerStatus/logs"
tpl = """{% set obj = dict(event=event, host=host, ip_info=ip_info, sys_info=sys_info) %} {{ obj | tojson}}"""
###################### log end ##########################
## 可选 微信通知
[wechat]
enabled = false
corp_id = "<corp id>"
corp_secret = "<corp secret>"
agent_id = "<agent id>"
title = "❗Server Status"
online_tpl = "{{config.title}} \n😆 {{host.location}} 的 {{host.name}} 主机恢复上线啦"
offline_tpl = "{{config.title}} \n😱 {{host.location}} 的 {{host.name}} 主机已经掉线啦"
custom_tpl = """
{% if host.memory_used / host.memory_total > 0.8 %}
😲 {{host.name}} 主机内存使用率超80%
{% endif %}
{% if host.hdd_used / host.hdd_total > 0.8 %}
😲 {{host.name}} 主机硬盘使用率超80%
{% endif %}
"""
###################### wechat end ##########################
## 可选 邮件通知
[email]
enabled = false
server = "smtp.gmail.com"
username = "user@email.com"
password = "***"
to = "user1@email.com;user2@email.com"
subject = "ServerStatus Notification"
title = "❗<b>Server Status</b><br/>"
online_tpl = "{{config.title}} 😆 {{host.location}} 的 {{host.name}} 主机恢复上线啦"
offline_tpl = "{{config.title}} 😱 {{host.location}} 的 {{host.name}} 主机已经掉线啦"
custom_tpl = """
{% if host.memory_used / host.memory_total > 0.8 %}
<pre>😲 {{host.name}} 主机内存使用率超80%, 当前{{ (100 * host.memory_used / host.memory_total) | round }}% </pre>
{% endif %}
{% if host.hdd_used / host.hdd_total > 0.8 %}
<pre>😲 {{host.name}} 主机硬盘使用率超80%, 当前{{ (100 * host.hdd_used / host.hdd_total) | round }}% </pre>
{% endif %}
"""
###################### email end ##########################
## 可选 webhook
# 理论上支持所有支持 webhook 的软件,如 Discord、 Slack、 飞书、 企业版微信(WorkWechat)、 钉钉(DingTalk)等。
# webhook 调用基本上都差不多,差异只在最后返回的 json 结构,根据各自的 api 文档自行构建相应的 json 结构即可。
# script 使用脚本引擎 https://rhai.rs/book/
[webhook]
# 总开关
enabled = false
# 可多个 webhook.receiver
[[webhook.receiver]] # 通用型 webhook
# 局部开关
enabled = false
# https://webhook.site/#!/2b1ad731-45fe-49a8-ae91-614167019db2
url = "https://webhook.site/2b1ad731-45fe-49a8-ae91-614167019db2"
headers = { content-type = "application/json", x-data = "y-data" }
# headers = { content-type = "text/plain" }
# 可选 HTTP Basic Auth
username = "u"
password = "p"
timeout = 5 #s
# 简单发送一个 json 对象,#{} 为 Object 对象, [] 为数组
# 最终结果, 固定结构 [是否发送通知,结果对象]
script = """[true, #{config: config, event: event, host: host, ip_info: ip_info, sys_info:sys_info} ]"""
[[webhook.receiver]] # Discord
enabled = false
# https://discord.com/developers/docs/resources/webhook
url = "https://discord.com/api/webhooks/xxxxxxxxxxxxxxxxxxxxxxx"
headers = { content-type = "application/json" }
timeout = 5 #s
script = """
let message = "";
switch event {
"Custom" => { // 自定义事件
let threshold = 10;
let msgs = [];
let memory_usage = round(host.memory_used * 100.0 / host.memory_total);
if memory_usage > threshold {
msgs.push(`😲 ${host.location} ${host.name} 主机内存使用率超${threshold}%, 当前 ${memory_usage}%`);
}
let hdd_usage = round(host.hdd_used * 100.0 / host.hdd_total);
if hdd_usage > threshold {
msgs.push(`😲 ${host.location} ${host.name} 主机硬盘使用率超${threshold}%, 当前 ${hdd_usage}%`);
}
message = join(msgs, "\\n");
},
"NodeDown" => { // 掉线
message = `😱 ${host.location} ${host.name} 主机已经掉线啦`;
},
"NodeUp" => { // 上线
message = `😆 ${host.location} ${host.name} 主机恢复上线啦`;
}
}
// 返回的 json 结构,#{} 为 Object 对象, [] 为数组
// 最终结果, 固定结构 [是否发送通知,结果对象]
[message.len() > 0, #{ embeds: [ #{
title: ":bell: ServerStatus-Rust :bell:",
fields: [
#{ name: "Event", value: event, },
#{ name: "Datetime", value: now_str(), },
#{ name: "Message", value: message, },
]
}]}]
"""
[[webhook.receiver]] # Slack
enabled = false
# https://api.slack.com/messaging/webhooks
url = "https://hooks.slack.com/services/xxxxxxxxxxxxxxxxxxxxxxx"
headers = { content-type = "application/json" }
timeout = 5 #s
script = """
let message = "";
switch event {
"Custom" => { // 自定义事件
let threshold = 80;
let msgs = [];
let memory_usage = round(host.memory_used * 100.0 / host.memory_total);
if memory_usage > threshold {
msgs.push(`😲 ${host.location} ${host.name} 主机内存使用率超${threshold}%, 当前 ${memory_usage}%`);
}
let hdd_usage = round(host.hdd_used * 100.0 / host.hdd_total);
if hdd_usage > threshold {
msgs.push(`😲 ${host.location} ${host.name} 主机硬盘使用率超${threshold}%, 当前 ${hdd_usage}%`);
}
message = join(msgs, "\\n");
},
"NodeDown" => { // 掉线
message = `😱 ${host.location} ${host.name} 主机已经掉线啦`;
},
"NodeUp" => { // 上线
message = `😆 ${host.location} ${host.name} 主机恢复上线啦`;
}
}
// 最终结果, 固定结构 [是否发送通知,结果对象]
[message.len() > 0, #{text: message}]
"""
[[webhook.receiver]] # WorkWechat
enabled = false
# https://developer.work.weixin.qq.com/document/path/91770
url = "https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=xxxxxxxxxxxxxxxxxxxxxxx"
headers = { content-type = "application/json" }
timeout = 5 #s
script = """
let message = "";
switch event {
"Custom" => { // 自定义事件
let threshold = 80;
let msgs = [];
let memory_usage = round(host.memory_used * 100.0 / host.memory_total);
if memory_usage > threshold {
msgs.push(`😲 ${host.location} ${host.name} 主机内存使用率超${threshold}%, 当前 ${memory_usage}%`);
}
let hdd_usage = round(host.hdd_used * 100.0 / host.hdd_total);
if hdd_usage > threshold {
msgs.push(`😲 ${host.location} ${host.name} 主机硬盘使用率超${threshold}%, 当前 ${hdd_usage}%`);
}
message = join(msgs, "\\n");
},
"NodeDown" => { // 掉线
message = `😱 ${host.location} ${host.name} 主机已经掉线啦`;
},
"NodeUp" => { // 上线
message = `😆 ${host.location} ${host.name} 主机恢复上线啦`;
}
}
// 最终结果, 固定结构 [是否发送通知,结果对象]
[message.len() > 0, #{
msgtype: "text",
text: #{
content: message
}
}]
"""
[[webhook.receiver]] # Bark
enabled = false
# https://github.com/Finb/Bark
# https://day.app/2021/06/barkfaq/
url = "https://api.day.app/push"
headers = { content-type = "application/json; charset=utf-8" }
timeout = 5 #s
script = """
let message = "";
switch event {
"Custom" => { // 自定义事件
// 使用率阈值,这里是磁盘 超 70% 告警
let threshold = 70;
let msgs = [];
let memory_usage = round(host.memory_used * 100.0 / host.memory_total);
if memory_usage > threshold {
msgs.push(`😲 ${host.location} ${host.name} 主机内存使用率超${threshold}%, 当前 ${memory_usage}%`);
}
let hdd_usage = round(host.hdd_used * 100.0 / host.hdd_total);
if hdd_usage > threshold {
msgs.push(`😲 ${host.location} ${host.name} 主机硬盘使用率超${threshold}%, 当前 ${hdd_usage}%`);
}
message = join(msgs, "\\n");
},
"NodeDown" => { // 掉线
message = `😱 ${host.location} ${host.name} 主机已经掉线啦`;
},
"NodeUp" => { // 上线
message = `😆 ${host.location} ${host.name} 主机恢复上线啦`;
}
}
// 最终结果, 固定结构 [是否发送通知,结果对象]
[message.len() > 0, #{
// 标题
title: "ServerStatusRust",
// 告警内容
body: message,
// 修改成你的设备 key, app 内获取
device_key: "fLLBrV****kM5H",
// 后面为可选字段参考 https://github.com/Finb/bark-server/blob/master/docs/API_V2.md
// 其它角标, 铃声, icon, 参考 app 里面的说明即可
badge: 1,
sound: "minuet.caf",
icon: "https://day.app/assets/images/avatar.jpg",
group: "SSR",
url: "https://github.com/zdz/ServerStatus-Rust"
}]
"""
###################### webhook end ##########################