210 Commits
1.0.0 ... 1.1.0

Author SHA1 Message Date
cppla
d242c6cea1 1.1.0
修复一些bug.
2023-10-09 14:24:17 +08:00
windows11
d7614ab168 width css bt3 2023-10-09 14:08:47 +08:00
windows11
ff06df8263 修复告警信息和URL特殊字符冲突的问题 2023-10-09 13:05:59 +08:00
cppla
9ee1516f72 Update README.md
up theme
2023-10-05 15:29:32 +08:00
cppla
7603ce37af add light theme
add light theme link and demo .
2023-10-05 15:19:02 +08:00
cppla
5cfd533daf flush dns , every time 2023-05-31 11:06:28 +08:00
cppla
9077f1058a add layui theme. 2023-05-04 15:59:37 +08:00
cppla
e34ed05901 make -j,多核心编译docker image 2023-04-12 11:10:10 +08:00
cppla
4ab545f646 fix bug about tupt 2023-04-12 10:17:51 +08:00
cppla
a6b4248967 jquery 3.5.0 to 3.5.1 2023-04-04 19:06:35 +08:00
cppla
8ad927d88d jquery v3.3.1 to v3.5.0 2023-04-03 15:22:59 +08:00
cppla
4b1ec57c6d 增加一个月出口流量示例 2023-04-03 15:12:33 +08:00
cppla
979a9b5d87 加一个ddcc告警示例 2023-03-13 07:23:44 +00:00
cppla
52d62afa59 优化curl 2023-02-28 17:19:49 +08:00
cppla
806b60bd6b get macos infomation build 2022-11-30 11:17:12 +08:00
cppla
d5af5445df disk io not in win 2022-11-30 11:09:21 +08:00
cppla
c77e00476c get macos tudp 2022-11-30 11:02:09 +08:00
cppla
b551998eb8 get macos load 2022-11-30 10:31:04 +08:00
cppla
1c606cc79e update 2022-11-08 12:52:16 +08:00
cppla
d602791b11 macos disk info 2022-11-03 16:38:22 +08:00
cppla
a695ef8b3a update for macos 2022-11-03 16:33:16 +08:00
cppla
9f60b7962b beta macos disk info 2022-11-03 16:25:23 +08:00
cppla
34b1bca5b1 The io_counters is not available on OS X, 兼容处理 2022-11-03 14:49:47 +08:00
cppla
25917f0883 update readme 2022-11-01 13:47:36 +08:00
cppla
333bc29c88 rename old tg to plugin 2022-11-01 13:38:14 +08:00
cppla
c116067c39 get to post 2022-10-31 18:36:33 +08:00
cppla
14db7ec943 update config template 2022-10-31 16:48:54 +08:00
cppla
af8244f1d7 int memory expand 2022-10-31 14:53:12 +08:00
cppla
1004c9a6bd update 2022-10-31 14:25:36 +08:00
cppla
7f78af03f0 100 ping lost 2022-10-31 14:15:37 +08:00
cppla
02bbdb18de update lost style 2022-10-31 14:01:42 +08:00
cppla
6d813f932d Merge pull request #191 from zqcccc/master
展开栏添加丢包信息
2022-10-31 13:43:34 +08:00
c9cu
19d6a5ea8b 展开栏添加丢包信息 2022-10-29 19:07:33 +08:00
cppla
35de279e89 Update README.md 2022-08-26 14:53:47 +08:00
cppla
d5a047c781 Update README.md 2022-08-25 16:23:02 +08:00
cppla
10872059c5 build 1.0.9
build 1.0.9
2022-08-25 16:14:46 +08:00
cppla
44656e565f 更改watchdog callback说明
更改watchdog callback说明
2022-08-25 16:13:24 +08:00
cppla
78c7da7361 经测试邮箱 和wechat不能稳定发送
经测试邮箱 和wechat不能稳定发送
2022-08-25 16:03:46 +08:00
cppla
b5edeea057 Update README.md
添加一个邮箱服务
2022-08-25 14:40:56 +08:00
cppla
c2259f347d Update README.md 2022-08-23 19:39:54 +08:00
cppla
bb5f03047d Update README.md 2022-08-23 19:39:10 +08:00
cppla
6ab6e16d0f 1080 to 1200 2022-08-01 19:37:26 +08:00
cppla
615cec88c2 300s 2022-07-21 10:53:08 +08:00
cppla
94896bac80 change docker to beijing time 2022-07-18 10:36:36 +08:00
cppla
a788b5da90 . 2022-07-17 10:11:11 +08:00
cppla
de0bc9dd74 Update README.md 2022-07-17 10:08:04 +08:00
cppla
ec16fc1fac Update README.md 2022-07-16 19:47:33 +08:00
cppla
cbd803b686 Create README.md
update tips
2022-07-16 19:46:59 +08:00
cppla
3eddb27d51 update 2022-07-16 19:30:29 +08:00
cppla
522809483e Compatible with older versions config.json 2022-07-16 19:11:29 +08:00
cppla
9d706f4da8 Update README.md
update watchdog 说明
2022-07-16 18:44:09 +08:00
cppla
a0fe8ee33c Update README.md
callback说明
2022-07-16 18:35:08 +08:00
cppla
c5eed8e4fa Update README.md
加入watchdog 说明
2022-07-16 18:00:10 +08:00
cppla
32d302580e update 2022-07-16 17:53:17 +08:00
cppla
b03d090a5c update readme 2022-07-16 17:47:57 +08:00
cppla
6151806141 c++ eval build use c++11 2022-07-16 14:42:32 +08:00
cppla
2703993272 add timeout for libcurl 2022-07-16 13:45:37 +08:00
cppla
022e5edb28 formate 2022-07-16 00:41:25 +08:00
cppla
135eb180c8 escape 2022-07-16 00:32:33 +08:00
cppla
2ead43a0d8 update 2022-07-15 23:14:53 +08:00
cppla
baae11de3b tg sms 2022-07-15 22:34:44 +08:00
cppla
2e62ffa593 link libcurl static lib 2022-07-15 21:14:39 +08:00
cppla
f70705d872 next add callback 2022-07-13 17:11:22 +08:00
cppla
7316dbdddb update 2022-07-13 16:55:38 +08:00
cppla
a1689acbf0 trigger msg for watchdog 2022-07-12 16:58:30 +08:00
cppla
e2a59a5465 eval 2022-07-12 15:59:24 +08:00
cppla
962d564c80 copy msg 2022-07-12 13:50:57 +08:00
cppla
77973a5309 0 and 1 2022-07-11 19:03:29 +08:00
cppla
a9128b137d read config. 2022-07-07 18:30:31 +08:00
cppla
0a2a007e24 support for python 3.10 2022-05-30 13:08:34 +08:00
cppla
ab5d6f7d2d Update serverstatus.js
change style for io speed
2022-05-10 15:20:58 +08:00
cppla
dae7c07772 1.0.8 build 2022-05-10 11:56:38 +08:00
cppla
14447399a0 Update README.md 2022-05-06 10:26:46 +08:00
cppla
3327c5fd25 修复增删节点月流量匹配的问题 2022-05-05 10:15:06 +08:00
cppla
217b14bf55 old style 2022-04-29 16:07:56 +08:00
cppla
d7b8f27082 IO Speed as Tips 2022-04-29 13:58:38 +08:00
cppla
8f3736e4fc 增加开源的支持
just do it .
2022-04-13 15:40:46 +08:00
windows11
22c1905acb style 2022-04-02 15:55:58 +08:00
cppla
f73970262b test 2022-04-02 15:39:41 +08:00
cppla
f45d9be9fc ui 2022-04-02 15:34:01 +08:00
cppla
cb1313f5b5 test 2022-04-02 15:25:10 +08:00
cppla
b3f7ab45c5 blue 2022-04-02 14:47:23 +08:00
cppla
54451cab85 no float for IO 2022-04-02 11:39:37 +08:00
cppla
0f26eb502a 1080p change 2022-04-01 18:55:41 +08:00
cppla
472196d1ea 1.0.8 beta 2022-04-01 17:42:43 +08:00
cppla
7e84c230e6 Merge branch 'dev' 2022-04-01 17:36:22 +08:00
cppla
76cc15e84f css 2022-04-01 17:35:58 +08:00
cppla
4c0f4b94e8 Merge pull request #149 from cppla/dev
新增实时IO统计
2022-04-01 16:29:53 +08:00
cppla
36040be11e add 2022-04-01 16:28:22 +08:00
cppla
776ad68392 io css style 2022-04-01 16:24:52 +08:00
cppla
39c92f4788 bug 2022-04-01 16:07:30 +08:00
cppla
6a15832966 bug test 2022-04-01 16:04:08 +08:00
cppla
654ecd7a3e update disk io style 2022-04-01 15:50:09 +08:00
cppla
47cf7a1818 持续获取io 2022-04-01 15:37:43 +08:00
cppla
5176cb0340 table control 2022-04-01 15:19:06 +08:00
cppla
1f47bcdb6f beta 2022-04-01 14:55:19 +08:00
cppla
7698ce0e4b 开源让编程更加美好 2022-03-31 19:53:17 +08:00
cppla
2d457c66ad push disk io for client-linux.py 2022-03-31 19:48:26 +08:00
cppla
d8c8d8fd3f add todo 2022-03-24 17:24:01 +08:00
cppla
d64beb7ba8 psutil add io total 2022-03-23 11:45:16 +08:00
cppla
30f9999fc6 rename 2022-03-23 11:13:18 +08:00
cppla
c46d0c06cd Merge pull request #139 from cppla/revert-135-master
Revert "修改丢包率分隔符💻为 |"
2022-03-02 18:51:29 +08:00
cppla
589c8812de Revert "修改丢包率分隔符💻为 |" 2022-03-02 18:48:07 +08:00
cppla
110a2d97d8 Merge pull request #135 from jwstaceyOvO/master
修改丢包率分隔符💻为 |
2022-03-02 11:02:02 +08:00
windows11
0914175200 load tofixed 2 2022-02-24 19:31:35 +08:00
windows11
830ea094a3 some change css for view 2022-02-24 19:17:20 +08:00
jwstaceyOvO
2f4611bdd8 修改丢包率分隔符💻为 |
💻太占空间,导致当丢包率位数较多时,无法正常显示全部数字
2022-02-24 12:33:31 +08:00
cppla
0b9e747cc9 Merge pull request #132 from jwstaceyOvO/master
ServerStatus一键安装脚本
2022-02-23 15:42:29 +08:00
cppla
22847aa590 Update status.sh
auto install bash.
2022-02-23 15:41:08 +08:00
jwstaceyOvO
e8482bf8ac Add files via upload 2022-02-22 17:39:14 +08:00
jwstaceyOvO
be95052d8f Update status-server.service 2022-02-22 17:38:41 +08:00
jwstaceyOvO
4c8006d183 Add files via upload 2022-02-22 17:01:04 +08:00
jwstaceyOvO
f1559bfb55 Update status-server.service 2022-02-22 17:00:13 +08:00
jwstaceyOvO
cab0f8bc91 Update status.sh 2022-02-16 19:49:16 +08:00
jwstaceyOvO
4e1e92e406 Update status.sh 2022-02-16 15:47:27 +08:00
jwstaceyOvO
fcb4b3cdfe Update status.sh 2022-02-15 18:47:44 +08:00
jwstaceyOvO
260b7b3a21 Update status-server.service 2022-02-15 18:31:39 +08:00
jwstaceyOvO
64c028f9ce Update status.sh 2022-02-14 16:57:08 +08:00
jwstaceyOvO
ec4218f1b0 Update status.sh 2022-02-14 16:41:56 +08:00
jwstaceyOvO
00bc87c2c2 Add files via upload 2022-02-14 16:37:05 +08:00
jwstaceyOvO
f36b4e66d2 Delete status.sh 2022-02-14 16:32:02 +08:00
jwstaceyOvO
3871c2c3d9 Update status.sh 2022-02-14 16:29:32 +08:00
jwstaceyOvO
4a0b15b61d Update status-client.service 2022-02-14 15:37:58 +08:00
jwstaceyOvO
e4fdacb2b5 Update status-client.service 2022-02-14 15:34:54 +08:00
jwstaceyOvO
d1bdec5e30 Update status-client.service 2022-02-14 15:33:39 +08:00
jwstaceyOvO
d0f3507add Update status-client.service 2022-02-14 15:31:31 +08:00
jwstaceyOvO
a3dab0dc0f Update status-client.service 2022-02-14 15:30:08 +08:00
jwstaceyOvO
050a6f78dc Update status-server.service 2022-02-14 13:23:25 +08:00
jwstaceyOvO
0219d21ad5 Add files via upload 2022-02-14 12:39:10 +08:00
jwstaceyOvO
fc977367ba Add files via upload 2022-02-14 12:30:17 +08:00
jwstaceyOvO
7d02f16fff Create status-client.service 2022-02-14 12:30:04 +08:00
oc
4792821e8e docker compose for X86 and ARM, good luck 2022-01-27 17:49:35 +08:00
oc
6c926209bd docker compose support for X86 or ARM64 2022-01-27 17:10:07 +08:00
windows11
e274b09c0f 修复增删节点月流量错误适配,置0, todo:等待全适配 2022-01-21 15:48:49 +08:00
windows11
5078381215 copy dark theme color from jk.sunpma.com 2022-01-19 19:29:15 +08:00
oc
4e175d0a81 change max client 128 to 256 2022-01-07 18:45:17 +08:00
cppla
0dc82096f5 update 1.0.7 readme
update 1.0.7 readme
2021-12-21 19:37:44 +08:00
oc
43c1c1279f 主题默认跟随系统,直至你手动选择了模式 2021-12-21 17:51:12 +08:00
oc
ef0229b2d7 Unified style 2021-12-20 15:09:19 +08:00
aws
77443663d6 command 2021-12-17 11:21:40 +08:00
cppla
4c2bcfbe20 Update README.md 2021-12-17 11:07:57 +08:00
aws
8e06385152 docker install and docker-compose install 2021-12-17 11:02:07 +08:00
aws
cc5aec11ba update README 2021-12-17 10:51:37 +08:00
cppla
7bf4a22457 Update bot-telegram.py 2021-12-16 19:25:15 +08:00
root
f68d3a8963 telegram for serverstatus 2021-12-16 19:00:48 +08:00
windows11
0834ff138d emoji to computer 2021-11-24 11:17:27 +08:00
windows11
cbbd71d037 update 2021-11-12 15:49:25 +08:00
cppla
614c6d323c Update README.md 2021-11-12 15:27:09 +08:00
windows11
e6d9edee2d Merge branch 'dev' 2021-11-12 15:09:21 +08:00
windows11
e00a374f03 update readme 2021-11-12 15:07:11 +08:00
windows11
feef07a6d8 Merge branch 'dev' 2021-11-11 18:06:20 +08:00
windows11
a83a2ff5a3 update 2021-11-11 18:05:51 +08:00
windows11
8925de8fc9 Merge branch 'dev' 2021-11-10 18:28:40 +08:00
windows11
700287125a default light 2021-11-10 18:28:20 +08:00
windows11
ec86ae7ed8 Merge branch 'dev' 2021-11-03 18:47:53 +08:00
windows11
0254971ec7 css 2021-11-03 18:47:32 +08:00
windows11
4966fe7daa Merge branch 'dev' 2021-11-03 18:02:49 +08:00
windows11
e5d22ad2db css 2021-11-03 18:02:31 +08:00
windows11
b348032855 Merge branch 'dev' 2021-11-03 15:00:59 +08:00
windows11
3cb0ea4777 css防止挤兑 2021-11-03 14:48:12 +08:00
windows11
f6cfdc9e6b fix 2021-11-03 14:45:00 +08:00
windows11
47a9ba60cb fix a bug 2021-11-03 13:39:55 +08:00
windows11
37dc23ee45 Merge branch 'dev' 2021-11-03 11:37:11 +08:00
windows11
ff51c48c93 update css 2021-11-03 11:36:50 +08:00
windows11
3edefd45ce Merge branch 'dev' 2021-11-03 11:34:56 +08:00
windows11
bde340a7e8 720px with 10px font 2021-11-03 11:34:27 +08:00
windows11
5323b28304 Merge branch 'dev' 2021-11-03 11:15:09 +08:00
windows11
28f61460c3 version beta 1.0.5 2021-11-03 11:13:57 +08:00
windows11
fd382957ca some change for css 2021-11-02 20:00:36 +08:00
windows11
c0ea66171a reduce month traffic diff 2021-11-02 16:35:42 +08:00
windows11
ab0a19b244 test bug for negative monthtraffic 2021-11-02 15:56:33 +08:00
cppla
d6878854b1 Update README.md 2021-10-22 11:53:39 +08:00
windows11
3aac3ccd0d 避免歧义 2021-10-22 11:51:43 +08:00
cppla
87824ce25a update to beta 1.0.4
update to beta 1.0.4
2021-10-18 17:05:36 +08:00
windows11
9d2a2e1c94 fix some bug for month traffic 2021-10-18 17:04:04 +08:00
windows11
6ee766df87 not remove json file 2021-10-18 15:42:23 +08:00
cppla
5afdb61e88 Update README.md 2021-10-14 20:41:24 +08:00
cppla
9592ba7b1d Update README.md 2021-10-14 20:30:25 +08:00
windows11
ecf19ae3c0 change length for css 2021-10-14 20:28:43 +08:00
windows11
c512ede1f7 add length for network 2021-10-14 19:54:16 +08:00
windows11
45a0723bea testing 2021-10-14 19:33:17 +08:00
windows11
b8a717a374 add info for change 2021-10-14 11:42:15 +08:00
windows11
3f0790db81 fix bug , no testing 2021-10-13 19:33:23 +08:00
windows11
8acb6ec0df 提交一个bug 2021-10-13 19:08:58 +08:00
windows11
7486919dbe 修复重启服务端,月流量统计丢失的问题 2021-10-13 18:45:34 +08:00
cppla
6188192951 Update README.md 2021-10-10 20:02:06 +08:00
cppla
e50ca41061 Bug说明,todo说明
Bug说明,todo说明
2021-10-10 19:01:11 +08:00
windows11
dc06c90e94 update kb 2 to 1 2021-10-10 14:14:04 +08:00
cppla
dcb2246d94 Update README.md 2021-10-10 12:46:49 +08:00
cppla
20d938401c Merge pull request #110 from cppla/dev
css show month_traffic
2021-10-10 11:40:05 +08:00
windows11
87895de2cf change css show month_traffic 2021-10-10 11:33:00 +08:00
cppla
427303d9ae Update README.md 2021-10-09 23:03:30 +08:00
cppla
e2f4714641 1.0.2 版本,beta
1.0.2 版本,beta
2021-10-09 22:46:07 +08:00
windows11
34236b4c5f update readme 2021-10-09 22:22:24 +08:00
windows11
474e7addc9 update 2021-10-09 22:13:53 +08:00
windows11
4c042a3fc7 兼容旧版本,删除ip_status旧版本显示MH370 2021-10-09 22:13:13 +08:00
windows11
a0842a020b version beta 1.0.2 2021-10-09 22:07:07 +08:00
windows11
c98dc92256 去除ip_status检测,和丢包率检测重复。默认为python3, python2已经 end of life 2021-10-09 21:28:05 +08:00
windows11
60264204cb test web ui 0.7 2021-10-09 20:06:26 +08:00
windows11
e145feb1cd test web ui 0.6 2021-10-09 19:36:53 +08:00
windows11
2359890ca0 test web ui 0.5 2021-10-09 19:24:18 +08:00
windows11
430bf2d2e0 test web ui 0.4 2021-10-09 17:54:04 +08:00
windows11
cfd472357f test web ui 0.3 2021-10-09 17:35:39 +08:00
windows11
895206baa4 test web ui 0.2 2021-10-09 16:59:50 +08:00
windows11
1828a476f7 test web ui 0.1 2021-10-09 16:37:35 +08:00
windows98
7cf9d969bc dev: add month traffic , no completed 2021-10-09 14:27:31 +08:00
root
55ee9ca6fb emoji location 2021-08-09 13:00:07 +08:00
windows98
9601ef1655 update ssview.py for view ServerStatus in console when attacked 2021-07-14 12:02:35 +08:00
cppla
a77f94c8d6 Merge pull request #103 from paulzzh/patch-1
fix #102
2021-07-13 21:15:05 +08:00
paulzzh
ab65e0fc26 fix #102
修正依赖
2021-07-13 18:42:06 +08:00
30 changed files with 42918 additions and 536 deletions

29
Dockerfile Normal file
View File

@@ -0,0 +1,29 @@
# The Dockerfile for build localhost source, not git repo
FROM debian:buster as builder
MAINTAINER cppla https://cpp.la
RUN apt-get update -y && apt-get -y install gcc g++ make libcurl4-openssl-dev
COPY . .
WORKDIR /server
RUN make -j
RUN pwd && ls -a
# glibc env run
FROM nginx:latest
RUN mkdir -p /ServerStatus/server/
COPY --from=builder server /ServerStatus/server/
COPY --from=builder web /usr/share/nginx/html/
# china time
ENV TZ=Asia/Shanghai
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
EXPOSE 80 35601
CMD nohup sh -c '/etc/init.d/nginx start && /ServerStatus/server/sergate --config=/ServerStatus/server/config.json --web-dir=/usr/share/nginx/html'

191
README.md
View File

@@ -3,138 +3,179 @@
* ServerStatus中文版是一个酷炫高逼格的云探针、云监控、服务器云监控、多服务器探针~。
* 在线演示https://tz.cloudcpp.com
[![Python Support](https://img.shields.io/badge/python-2.7%2B%20-blue.svg)](https://github.com/cppla/ServerStatus)
[![Python Support](https://img.shields.io/badge/python-3.6%2B%20-blue.svg)](https://github.com/cppla/ServerStatus)
[![C++ Compiler](http://img.shields.io/badge/C++-GNU-blue.svg?style=flat&logo=cplusplus)](https://github.com/cppla/ServerStatus)
[![License](https://img.shields.io/badge/license-MIT-4EB1BA.svg?style=flat-square)](https://github.com/cppla/ServerStatus)
[![Version](https://img.shields.io/badge/Version-Build%201.1.0-red)](https://github.com/cppla/ServerStatus)
![Latest Version](http://dl.cpp.la/Archive/serverstatus.png)
![Latest Version](http://dl.cpp.la/Archive/serverstatus_1.0.9.png)
# 目录介绍:
`Watchdog🐶已经加入触发式告警。 interval只是为了防止频繁收到报警信息造成骚扰并不是探测间隔。`
* autodeploy 自动部署.
* clients 客户端文件
* server 服务端文件
* web 网站文件      
# 目录:
# 自动部署:
* clients 客户端文件
* server 服务端文件
* web 网站文件
* server/config.json 探针配置文件      
* web/json 探针月流量
# 部署:
【服务端】:
```bash
`x86_64`: docker pull cppla/serverstatus:latest
`arm64`: docker pull cppla/serverstatus:arm
`Docker`:
wget https://raw.githubusercontent.com/cppla/ServerStatus/master/autodeploy/config.json
docker run -d --restart=always --name=serverstatus -v {$path}/config.json:/ServerStatus/server/config.json -p {$port}:80 -p {$port}:35601 cppla/serverstatus:latest
wget --no-check-certificate -qO ~/serverstatus-config.json https://raw.githubusercontent.com/cppla/ServerStatus/master/server/config.json && mkdir ~/serverstatus-monthtraffic
docker run -d --restart=always --name=serverstatus -v ~/serverstatus-config.json:/ServerStatus/server/config.json -v ~/serverstatus-monthtraffic:/usr/share/nginx/html/json -p 80:80 -p 35601:35601 cppla/serverstatus:latest
eg:
docker run -d --restart=always --name=serverstatus -v ~/config.json:/ServerStatus/server/config.json -p 80:80 -p 35601:35601 cppla/serverstatus:latest
`Docker-compose(推荐)`: docker-compose up -d
```
【客户端】:
```bash
wget --no-check-certificate -qO client-linux.py 'https://raw.githubusercontent.com/cppla/ServerStatus/master/clients/client-linux.py' && nohup python client-linux.py SERVER={$SERVER} USER={$USER} PASSWORD={$PASSWORD} >/dev/null 2>&1 &
wget --no-check-certificate -qO client-linux.py 'https://raw.githubusercontent.com/cppla/ServerStatus/master/clients/client-linux.py' && nohup python3 client-linux.py SERVER={$SERVER} USER={$USER} PASSWORD={$PASSWORD} >/dev/null 2>&1 &
eg:
wget --no-check-certificate -qO client-linux.py 'https://raw.githubusercontent.com/cppla/ServerStatus/master/clients/client-linux.py' && nohup python client-linux.py SERVER=45.79.67.132 USER=s04 >/dev/null 2>&1 &
wget --no-check-certificate -qO client-linux.py 'https://raw.githubusercontent.com/cppla/ServerStatus/master/clients/client-linux.py' && nohup python3 client-linux.py SERVER=45.79.67.132 USER=s04 >/dev/null 2>&1 &
```
# 主题:
* layuihttps://github.com/zeyudada/StatusServerLayui 预览https://sslt.8zyw.cn
<img src=https://dl.cpp.la/Archive/serverstatus_layui.png width=200 height=100 />
* lighthttps://github.com/orilights/ServerStatus-Theme-Light 预览https://tz.cloudcpp.com/index3.html
<img src=https://github.com/orilights/ServerStatus-Theme-Light/blob/main/docs/screenshot.png width=200 height=100 />
# 手动安装教程:
【克隆代码】:
```
git clone https://github.com/cppla/ServerStatus.git
```
【服务端配置】服务端程序在ServerStatus/web下:
**【服务端配置】**
一、生成服务端程序
#### 一、生成服务端程序
```
cd ServerStatus/server
make
`Debian/Ubuntu`: apt-get -y install gcc g++ make libcurl4-openssl-dev
`Centos/Redhat`: yum -y install gcc gcc-c++ make libcurl-devel
cd ServerStatus/server && make
./sergate
```
如果没错误提示OKctrl+c关闭如果有错误提示检查35601端口是否被占用
二、修改配置文件
修改config.json文件注意username, password的值需要和客户端对应一致    
#### 二、修改配置文件
```diff
! watchdog rule 可以为任何已知字段的表达式。
! watchdog interval 最小通知间隔。
! watchdog callback 可自定义为Post方法的URL告警内容将拼接其后并发起回调。
! watchdog callback Telegram: https://api.telegram.org/bot你自己的密钥/sendMessage?parse_mode=HTML&disable_web_page_preview=true&chat_id=你自己的标识&text=
! watchdog callback Server酱: https://sctapi.ftqq.com/你自己的密钥.send?title=ServerStatus&desp=
! watchdog callback PushDeer: https://api2.pushdeer.com/message/push?pushkey=你自己的密钥&text=
! watchdog callback BasicAuth: https://用户名:密码@你自己的域名/api/push?message=
```
{"servers":
```
{
"servers":
[
{
"username": "s01",
"name": "Mainserver 1",
"type": "Dedicated Server",
"host": "GenericServerHost123",
"location": "Austria",
"password": "some-hard-to-guess-copy-paste-password"
"name": "vps-1",
"type": "kvm",
"host": "chengdu",
"location": "🇨🇳",
"password": "USER_DEFAULT_PASSWORD",
"monthstart": 1
},
],
"watchdog":
[
{
"name": "服务器负载高监控",
"rule": "cpu>90&load_5>3",
"interval": 600,
"callback": "https://yourSMSurl"
},
{
"name": "服务器内存使用率过高监控",
"rule": "(memory_used/memory_total)*100>90",
"interval": 600,
"callback": "https://yourSMSurl"
},
{
"name": "服务器宕机告警,排除经常掉线的",
"rule": "online4=0&online6=0&username!=s21",
"interval": 600,
"callback": "https://yourSMSurl"
},
{
"name": "DDOS和CC攻击监控",
"rule": "tcp_count>600",
"interval": 300,
"callback": "https://yourSMSurl"
},
{
"name": "服务器月出口流量999GB告警",
"rule": "(network_out-last_network_out)/1024/1024/1024>999",
"interval": 3600,
"callback": "https://yourSMSurl"
},
{
"name": "你可以组合任何已知字段的表达式",
"rule": "(hdd_used/hdd_total)*100>95",
"interval": 1800,
"callback": "https://yourSMSurl"
}
]
}
```
三、拷贝ServerStatus/status到你的网站目录
#### 三、拷贝ServerStatus/status到你的网站目录
例如:
```
sudo cp -r ServerStatus/web/* /home/wwwroot/default
```
四、运行服务端:
#### 四、运行服务端:
web-dir参数为上一步设置的网站根目录务必修改成自己网站的路径
```
./sergate --config=config.json --web-dir=/home/wwwroot/default
```
【客户端配置】客户端程序在ServerStatus/clients下
**【客户端配置】**
客户端有两个版本client-linux为普通linuxclient-psutil为跨平台版普通版不成功换成跨平台版即可。
一、client-linux版配置
#### 一、client-linux版配置
1、vim client-linux.py, 修改SERVER地址username帐号 password密码
2、python client-linux.py 运行即可。
2、python3 client-linux.py 运行即可。
二、client-psutil版配置:
1、安装psutil跨平台依赖库
#### 二、client-psutil版配置:
1、安装psutil跨平台依赖库
```
`Debian/Ubuntu`: apt -y install python3-pip && pip3 install psutil
`Centos/Redhat`: yum -y install python3-pip gcc python3-devel && pip3 install psutil
`Windows`: https://pypi.org/project/psutil/
```
2、vim client-psutil.py, 修改SERVER地址username帐号 password密码
3、python client-psutil.py 运行即可。
```
### for Centos
sudo yum -y install epel-release
sudo yum -y install python-pip
sudo yum clean all
sudo yum -y install gcc
sudo yum -y install python-devel
sudo pip install psutil
### for Ubuntu/Debian:
sudo root
apt-get -y install python-setuptools python-dev build-essential
apt-get -y install python-pip
pip install psutil
### for Windows:
打开网址https://pypi.python.org/pypi?:action=display&name=psutil#downloads
下载psutil for windows程序包
安装即可
```
3、python3 client-psutil.py 运行即可。
打开云探针页面,就可以正常的监控。接下来把服务器和客户端脚本自行加入开机启动,或进程守护,或后台方式运行即可!例如: nohup python client-linux.py &
服务器和客户端自行加入开机启动,或进程守护,或后台方式运行例如: nohup python3 client-linux.py &
### 如何快速跟随系统启动呢?其实好多人都搞复杂化了
1、chmod 755 /root/client-linux.py
2、vim /etc/crontab尾部追加
```diff
@reboot root /root/client-linux.py SERVER=$server USER=$user
```
`extra scene (run web/ssview.py)`
![Shell View](https://dl.cpp.la/Archive/serverstatus-shell.png?version=2023)
# 为什么会有ServerStatus中文版
* 有些功能确实没用
* 原版本部署,英文说明复杂
* 不符合中文版的习惯
* 没有一次又一次的轮子,哪来如此优秀的云探针
# Make Better
# 相关开源项目,感谢:
* ServerStatushttps://github.com/BotoX/ServerStatus
* BotoXhttps://github.com/BotoX/ServerStatus
* mojeda: https://github.com/mojeda
* mojeda's ServerStatus: https://github.com/mojeda/ServerStatus
* BlueVM's project: http://www.lowendtalk.com/discussion/comment/169690#Comment_169690
# Jetbrains
<a href="https://www.jetbrains.com/?from=ServerStatus"><img src="https://resources.jetbrains.com/storage/products/company/brand/logos/jb_square.png" width="100px"></a>

View File

@@ -1,24 +0,0 @@
FROM debian:latest as builder
MAINTAINER cppla https://cpp.la
RUN apt-get update
RUN apt-get -y install gcc g++ make git
RUN git clone https://github.com/cppla/ServerStatus
WORKDIR /ServerStatus/server
RUN make
RUN pwd && ls -a
# glibc env run
FROM nginx:latest
RUN mkdir -p /ServerStatus/server/
COPY --from=builder /ServerStatus/server /ServerStatus/server/
COPY --from=builder /ServerStatus/web /usr/share/nginx/html/
EXPOSE 80 35601
CMD nohup sh -c '/etc/init.d/nginx start && /ServerStatus/server/sergate --config=/ServerStatus/server/config.json --web-dir=/usr/share/nginx/html'

View File

@@ -1,37 +0,0 @@
{"servers":
[
{
"username": "s01",
"name": "node1",
"type": "xen",
"host": "host1",
"location": "cn",
"password": "USER_DEFAULT_PASSWORD"
},
{
"username": "s02",
"name": "node2",
"type": "vmware",
"host": "host2",
"location": "jp",
"password": "USER_DEFAULT_PASSWORD"
},
{
"disabled": true,
"username": "s03",
"name": "node3",
"type": "Nothing",
"host": "host3",
"location": "fr",
"password": "USER_DEFAULT_PASSWORD"
},
{
"username": "s04",
"name": "ssss",
"type": "ssss",
"host": "ssss",
"location": "ssss",
"password": "USER_DEFAULT_PASSWORD"
}
]
}

View File

@@ -1,15 +0,0 @@
服务端:
docker build -f Dockerfile -t sss .
docker run -d --restart=always --name=sss -v {$path}/config.json:/ServerStatus/server/config.json -p {$port}:80 -p {$port}:35601 sss
客户端:
wget --no-check-certificate -qO client-linux.py 'https://raw.githubusercontent.com/cppla/ServerStatus/master/clients/client-linux.py' && nohup python client-linux.py SERVER={$SERVER} USER={$USER} PASSWORD={$PASSWORD} >/dev/null 2>&1 &
附: docker安装
curl -sSL https://get.docker.com/ | sh

View File

@@ -1,25 +1,23 @@
#!/usr/bin/env python
#!/usr/bin/env python3
# coding: utf-8
# Update by : https://github.com/cppla/ServerStatus
# 支持Python版本2.7 to 3.7
# Update by : https://github.com/cppla/ServerStatus, Update date: 20220530
# 版本1.0.3, 支持Python版本2.7 to 3.10
# 支持操作系统: Linux, OSX, FreeBSD, OpenBSD and NetBSD, both 32-bit and 64-bit architectures
# 时间: 20200407
# 说明: 默认情况下修改server和user就可以了。丢包率监测方向可以自定义例如CU = "www.facebook.com"。
SERVER = "127.0.0.1"
USER = "s01"
PORT = 35601
PASSWORD = "USER_DEFAULT_PASSWORD"
INTERVAL = 1
PROBEPORT = 80
PROBE_PROTOCOL_PREFER = "ipv4" # ipv4, ipv6
PING_PACKET_HISTORY_LEN = 100
PORT = 35601
CU = "cu.tz.cloudcpp.com"
CT = "ct.tz.cloudcpp.com"
CM = "cm.tz.cloudcpp.com"
PROBEPORT = 80
PROBE_PROTOCOL_PREFER = "ipv4" # ipv4, ipv6
PING_PACKET_HISTORY_LEN = 100
INTERVAL = 1
import socket
import time
@@ -119,18 +117,6 @@ def tupd():
d = int(s[:-1])-2
return t,u,p,d
def ip_status():
ip_check = 0
for i in [CU, CT, CM]:
try:
socket.create_connection((i, PROBEPORT), timeout=1).close()
except:
ip_check += 1
if ip_check >= 2:
return False
else:
return True
def get_network(ip_version):
if(ip_version == 4):
HOST = "ipv4.google.com"
@@ -160,22 +146,27 @@ netSpeed = {
'avgrx': 0,
'avgtx': 0
}
diskIO = {
'read': 0,
'write': 0
}
def _ping_thread(host, mark, port):
lostPacket = 0
packet_queue = Queue(maxsize=PING_PACKET_HISTORY_LEN)
IP = host
if host.count(':') < 1: # if not plain ipv6 address, means ipv4 address or hostname
try:
if PROBE_PROTOCOL_PREFER == 'ipv4':
IP = socket.getaddrinfo(host, None, socket.AF_INET)[0][4][0]
else:
IP = socket.getaddrinfo(host, None, socket.AF_INET6)[0][4][0]
except Exception:
while True:
# flush dns , every time.
IP = host
if host.count(':') < 1: # if not plain ipv6 address, means ipv4 address or hostname
try:
if PROBE_PROTOCOL_PREFER == 'ipv4':
IP = socket.getaddrinfo(host, None, socket.AF_INET)[0][4][0]
else:
IP = socket.getaddrinfo(host, None, socket.AF_INET6)[0][4][0]
except Exception:
pass
while True:
if packet_queue.full():
if packet_queue.get() == 0:
lostPacket -= 1
@@ -223,7 +214,72 @@ def _net_speed():
netSpeed["avgtx"] = avgtx
time.sleep(INTERVAL)
def get_realtime_date():
def _disk_io():
'''
good luck for opensource! by: cpp.la
磁盘IO因为IOPS原因SSD和HDD、包括RAID卡ZFS等阵列技术。IO对性能的影响还需要结合自身服务器情况来判断。
比如我这里是机械硬盘,大量做随机小文件读写,那么很低的读写也就能造成硬盘长时间的等待。
如果这里做连续性IO那么普通机械硬盘写入到100Mb/s那么也能造成硬盘长时间的等待。
磁盘读写有误差4k8k https://stackoverflow.com/questions/34413926/psutil-vs-dd-monitoring-disk-i-o
:return:
'''
while True:
# pre pid snapshot
snapshot_first = {}
# next pid snapshot
snapshot_second = {}
# read count snapshot
snapshot_read = 0
# write count snapshot
snapshot_write = 0
# process snapshot
pid_snapshot = [str(i) for i in os.listdir("/proc") if i.isdigit() is True]
for pid in pid_snapshot:
try:
with open("/proc/{}/io".format(pid)) as f:
pid_io = {}
for line in f.readlines():
if "read_bytes" in line:
pid_io["read"] = int(line.split("read_bytes:")[-1].strip())
elif "write_bytes" in line and "cancelled_write_bytes" not in line:
pid_io["write"] = int(line.split("write_bytes:")[-1].strip())
pid_io["name"] = open("/proc/{}/comm".format(pid), "r").read().strip()
snapshot_first[pid] = pid_io
except:
if pid in snapshot_first:
snapshot_first.pop(pid)
time.sleep(INTERVAL)
for pid in pid_snapshot:
try:
with open("/proc/{}/io".format(pid)) as f:
pid_io = {}
for line in f.readlines():
if "read_bytes" in line:
pid_io["read"] = int(line.split("read_bytes:")[-1].strip())
elif "write_bytes" in line and "cancelled_write_bytes" not in line:
pid_io["write"] = int(line.split("write_bytes:")[-1].strip())
pid_io["name"] = open("/proc/{}/comm".format(pid), "r").read().strip()
snapshot_second[pid] = pid_io
except:
if pid in snapshot_first:
snapshot_first.pop(pid)
if pid in snapshot_second:
snapshot_second.pop(pid)
for k, v in snapshot_first.items():
if snapshot_first[k]["name"] == snapshot_second[k]["name"] and snapshot_first[k]["name"] != "bash":
snapshot_read += (snapshot_second[k]["read"] - snapshot_first[k]["read"])
snapshot_write += (snapshot_second[k]["write"] - snapshot_first[k]["write"])
diskIO["read"] = snapshot_read
diskIO["write"] = snapshot_write
def get_realtime_data():
'''
real time get system data
:return:
'''
t1 = threading.Thread(
target=_ping_thread,
kwargs={
@@ -251,14 +307,12 @@ def get_realtime_date():
t4 = threading.Thread(
target=_net_speed,
)
t1.setDaemon(True)
t2.setDaemon(True)
t3.setDaemon(True)
t4.setDaemon(True)
t1.start()
t2.start()
t3.start()
t4.start()
t5 = threading.Thread(
target=_disk_io,
)
for ti in [t1, t2, t3, t4, t5]:
ti.daemon = True
ti.start()
def byte_str(object):
'''
@@ -286,7 +340,7 @@ if __name__ == '__main__':
elif 'INTERVAL' in argc:
INTERVAL = int(argc.split('INTERVAL=')[-1])
socket.setdefaulttimeout(30)
get_realtime_date()
get_realtime_data()
while True:
try:
print("Connecting...")
@@ -324,7 +378,6 @@ if __name__ == '__main__':
Load_1, Load_5, Load_15 = os.getloadavg()
MemoryTotal, MemoryUsed, SwapTotal, SwapFree = get_memory()
HDDTotal, HDDUsed = get_hdd()
IP_STATUS = ip_status()
array = {}
if not timer:
@@ -348,7 +401,8 @@ if __name__ == '__main__':
array['network_tx'] = netSpeed.get("nettx")
array['network_in'] = NET_IN
array['network_out'] = NET_OUT
array['ip_status'] = IP_STATUS
# todo兼容旧版本下个版本删除ip_status
array['ip_status'] = True
array['ping_10010'] = lostRate.get('10010') * 100
array['ping_189'] = lostRate.get('189') * 100
array['ping_10086'] = lostRate.get('10086') * 100
@@ -356,6 +410,8 @@ if __name__ == '__main__':
array['time_189'] = pingTime.get('189')
array['time_10086'] = pingTime.get('10086')
array['tcp'], array['udp'], array['process'], array['thread'] = tupd()
array['io_read'] = diskIO.get("read")
array['io_write'] = diskIO.get("write")
s.send(byte_str("update " + json.dumps(array) + "\n"))
except KeyboardInterrupt:

View File

@@ -1,35 +1,33 @@
#!/usr/bin/env python
#!/usr/bin/env python3
# coding: utf-8
# Update by : https://github.com/cppla/ServerStatus
# Update by : https://github.com/cppla/ServerStatus, Update date: 20220530
# 依赖于psutil跨平台库
# 支持Python版本2.7 to 3.7
# 版本1.0.3, 支持Python版本2.7 to 3.10
# 支持操作系统: Linux, Windows, OSX, Sun Solaris, FreeBSD, OpenBSD and NetBSD, both 32-bit and 64-bit architectures
# 时间: 20200407
# 说明: 默认情况下修改server和user就可以了。丢包率监测方向可以自定义例如CU = "www.facebook.com"。
SERVER = "127.0.0.1"
USER = "s01"
PORT = 35601
PASSWORD = "USER_DEFAULT_PASSWORD"
INTERVAL = 1
PROBEPORT = 80
PROBE_PROTOCOL_PREFER = "ipv4" # ipv4, ipv6
PING_PACKET_HISTORY_LEN = 100
PORT = 35601
CU = "cu.tz.cloudcpp.com"
CT = "ct.tz.cloudcpp.com"
CM = "cm.tz.cloudcpp.com"
PROBEPORT = 80
PROBE_PROTOCOL_PREFER = "ipv4" # ipv4, ipv6
PING_PACKET_HISTORY_LEN = 100
INTERVAL = 1
import socket
import time
import timeit
import os
import json
import psutil
import sys
import threading
import json
import errno
import psutil
import threading
try:
from queue import Queue # python3
@@ -48,18 +46,22 @@ def get_swap():
return int(Mem.total/1024.0), int(Mem.used/1024.0)
def get_hdd():
valid_fs = [ "ext4", "ext3", "ext2", "reiserfs", "jfs", "btrfs", "fuseblk", "zfs", "simfs", "ntfs", "fat32", "exfat", "xfs" ]
disks = dict()
size = 0
used = 0
for disk in psutil.disk_partitions():
if not disk.device in disks and disk.fstype.lower() in valid_fs:
disks[disk.device] = disk.mountpoint
for disk in disks.values():
usage = psutil.disk_usage(disk)
size += usage.total
used += usage.used
return int(size/1024.0/1024.0), int(used/1024.0/1024.0)
if "darwin" in sys.platform:
return int(psutil.disk_usage("/").total/1024.0/1024.0), int((psutil.disk_usage("/").total-psutil.disk_usage("/").free)/1024.0/1024.0)
else:
valid_fs = ["ext4", "ext3", "ext2", "reiserfs", "jfs", "btrfs", "fuseblk", "zfs", "simfs", "ntfs", "fat32",
"exfat", "xfs"]
disks = dict()
size = 0
used = 0
for disk in psutil.disk_partitions():
if not disk.device in disks and disk.fstype.lower() in valid_fs:
disks[disk.device] = disk.mountpoint
for disk in disks.values():
usage = psutil.disk_usage(disk)
size += usage.total
used += usage.used
return int(size/1024.0/1024.0), int(used/1024.0/1024.0)
def get_cpu():
return psutil.cpu_percent(interval=INTERVAL)
@@ -90,31 +92,29 @@ def tupd():
u = int(os.popen('ss -u|wc -l').read()[:-1])-1
p = int(os.popen('ps -ef|wc -l').read()[:-1])-2
d = int(os.popen('ps -eLf|wc -l').read()[:-1])-2
elif sys.platform.startswith("darwin") is True:
t = int(os.popen('lsof -nP -iTCP | wc -l').read()[:-1]) - 1
u = int(os.popen('lsof -nP -iUDP | wc -l').read()[:-1]) - 1
p = len(psutil.pids())
d = 0
for k in psutil.pids():
try:
d += psutil.Process(k).num_threads()
except:
pass
elif sys.platform.startswith("win") is True:
t = int(os.popen('netstat -an|find "TCP" /c').read()[:-1])-1
u = int(os.popen('netstat -an|find "UDP" /c').read()[:-1])-1
p = len(psutil.pids())
d = 0
# cpu is high, default: 0
# d = sum([psutil.Process(k).num_threads() for k in [x for x in psutil.pids()]])
# if you find cpu is high, please set d=0
d = sum([psutil.Process(k).num_threads() for k in psutil.pids()])
else:
t,u,p,d = 0,0,0,0
return t,u,p,d
except:
return 0,0,0,0
def ip_status():
ip_check = 0
for i in [CU, CT, CM]:
try:
socket.create_connection((i, PROBEPORT), timeout=1).close()
except:
ip_check += 1
if ip_check >= 2:
return False
else:
return True
def get_network(ip_version):
if(ip_version == 4):
HOST = "ipv4.google.com"
@@ -144,22 +144,27 @@ netSpeed = {
'avgrx': 0,
'avgtx': 0
}
diskIO = {
'read': 0,
'write': 0
}
def _ping_thread(host, mark, port):
lostPacket = 0
packet_queue = Queue(maxsize=PING_PACKET_HISTORY_LEN)
IP = host
if host.count(':') < 1: # if not plain ipv6 address, means ipv4 address or hostname
try:
if PROBE_PROTOCOL_PREFER == 'ipv4':
IP = socket.getaddrinfo(host, None, socket.AF_INET)[0][4][0]
else:
IP = socket.getaddrinfo(host, None, socket.AF_INET6)[0][4][0]
except Exception:
while True:
# flush dns, every time.
IP = host
if host.count(':') < 1: # if not plain ipv6 address, means ipv4 address or hostname
try:
if PROBE_PROTOCOL_PREFER == 'ipv4':
IP = socket.getaddrinfo(host, None, socket.AF_INET)[0][4][0]
else:
IP = socket.getaddrinfo(host, None, socket.AF_INET6)[0][4][0]
except Exception:
pass
while True:
if packet_queue.full():
if packet_queue.get() == 0:
lostPacket -= 1
@@ -203,7 +208,67 @@ def _net_speed():
netSpeed["avgtx"] = avgtx
time.sleep(INTERVAL)
def get_realtime_date():
def _disk_io():
"""
the code is by: https://github.com/giampaolo/psutil/blob/master/scripts/iotop.py
good luck for opensource! modify: cpp.la
Calculate IO usage by comparing IO statics before and
after the interval.
Return a tuple including all currently running processes
sorted by IO activity and total disks I/O activity.
磁盘IO因为IOPS原因SSD和HDD、包括RAID卡ZFS等。IO对性能的影响还需要结合自身服务器情况来判断。
比如我这里是机械硬盘,大量做随机小文件读写,那么很低的读写也就能造成硬盘长时间的等待。
如果这里做连续性IO那么普通机械硬盘写入到100Mb/s那么也能造成硬盘长时间的等待。
磁盘读写有误差4k8k https://stackoverflow.com/questions/34413926/psutil-vs-dd-monitoring-disk-i-o
macos/win暂不处理。
"""
if "darwin" in sys.platform or "win" in sys.platform:
diskIO["read"] = 0
diskIO["write"] = 0
else:
while True:
# first get a list of all processes and disk io counters
procs = [p for p in psutil.process_iter()]
for p in procs[:]:
try:
p._before = p.io_counters()
except psutil.Error:
procs.remove(p)
continue
disks_before = psutil.disk_io_counters()
# sleep some time, only when INTERVAL==1 , io read/write per_sec.
# when INTERVAL > 1, io read/write per_INTERVAL
time.sleep(INTERVAL)
# then retrieve the same info again
for p in procs[:]:
with p.oneshot():
try:
p._after = p.io_counters()
p._cmdline = ' '.join(p.cmdline())
if not p._cmdline:
p._cmdline = p.name()
p._username = p.username()
except (psutil.NoSuchProcess, psutil.ZombieProcess):
procs.remove(p)
disks_after = psutil.disk_io_counters()
# finally calculate results by comparing data before and
# after the interval
for p in procs:
p._read_per_sec = p._after.read_bytes - p._before.read_bytes
p._write_per_sec = p._after.write_bytes - p._before.write_bytes
p._total = p._read_per_sec + p._write_per_sec
diskIO["read"] = disks_after.read_bytes - disks_before.read_bytes
diskIO["write"] = disks_after.write_bytes - disks_before.write_bytes
def get_realtime_data():
'''
real time get system data
:return:
'''
t1 = threading.Thread(
target=_ping_thread,
kwargs={
@@ -231,14 +296,12 @@ def get_realtime_date():
t4 = threading.Thread(
target=_net_speed,
)
t1.setDaemon(True)
t2.setDaemon(True)
t3.setDaemon(True)
t4.setDaemon(True)
t1.start()
t2.start()
t3.start()
t4.start()
t5 = threading.Thread(
target=_disk_io,
)
for ti in [t1, t2, t3, t4, t5]:
ti.daemon = True
ti.start()
def byte_str(object):
'''
@@ -266,7 +329,7 @@ if __name__ == '__main__':
elif 'INTERVAL' in argc:
INTERVAL = int(argc.split('INTERVAL=')[-1])
socket.setdefaulttimeout(30)
get_realtime_date()
get_realtime_data()
while 1:
try:
print("Connecting...")
@@ -301,11 +364,10 @@ if __name__ == '__main__':
CPU = get_cpu()
NET_IN, NET_OUT = liuliang()
Uptime = get_uptime()
Load_1, Load_5, Load_15 = os.getloadavg() if 'linux' in sys.platform else (0.0, 0.0, 0.0)
Load_1, Load_5, Load_15 = os.getloadavg() if 'linux' in sys.platform or 'darwin' in sys.platform else (0.0, 0.0, 0.0)
MemoryTotal, MemoryUsed = get_memory()
SwapTotal, SwapUsed = get_swap()
HDDTotal, HDDUsed = get_hdd()
IP_STATUS = ip_status()
array = {}
if not timer:
@@ -329,7 +391,8 @@ if __name__ == '__main__':
array['network_tx'] = netSpeed.get("nettx")
array['network_in'] = NET_IN
array['network_out'] = NET_OUT
array['ip_status'] = IP_STATUS
# todo兼容旧版本下个版本删除ip_status
array['ip_status'] = True
array['ping_10010'] = lostRate.get('10010') * 100
array['ping_189'] = lostRate.get('189') * 100
array['ping_10086'] = lostRate.get('10086') * 100
@@ -337,6 +400,8 @@ if __name__ == '__main__':
array['time_189'] = pingTime.get('189')
array['time_10086'] = pingTime.get('10086')
array['tcp'], array['udp'], array['process'], array['thread'] = tupd()
array['io_read'] = diskIO.get("read")
array['io_write'] = diskIO.get("write")
s.send(byte_str("update " + json.dumps(array) + "\n"))
except KeyboardInterrupt:

25
docker-compose.yml Normal file
View File

@@ -0,0 +1,25 @@
version: "3"
services:
serverstatus:
build:
context: .
dockerfile: Dockerfile
image: serverstatus_server
container_name: serverstatus
restart: unless-stopped
networks:
serverstatus-network:
ipv4_address: 172.23.0.2
volumes:
- ./server/config.json:/ServerStatus/server/config.json
- ./web/json:/usr/share/nginx/html/json
ports:
- 35601:35601
- 8080:80
networks:
serverstatus-network:
name: serverstatus-network
ipam:
config:
- subnet: 172.23.0.0/24

View File

@@ -0,0 +1,10 @@
FROM python:alpine
LABEL maintainer="lidalao"
LABEL version="0.0.1"
LABEL description="Telegram Bot for ServerStatus"
WORKDIR /app
RUN pip install requests
COPY ./bot-telegram.py .
CMD [ "python", "./bot-telegram.py" ]

73
plugin/bot-telegram.py Normal file
View File

@@ -0,0 +1,73 @@
#!/usr/bin/env python3
# coding: utf-8
# Create by : https://github.com/lidalao/ServerStatus
# 版本0.0.1, 支持Python版本2.7 to 3.9
# 支持操作系统: Linux, OSX, FreeBSD, OpenBSD and NetBSD, both 32-bit and 64-bit architectures
import os
import sys
import requests
import time
import traceback
NODE_STATUS_URL = 'http://serverstatus/json/stats.json'
offs = []
counterOff = {}
counterOn = {}
def _send(text):
chat_id = os.getenv('TG_CHAT_ID')
bot_token = os.environ.get('TG_BOT_TOKEN')
url = f"https://api.telegram.org/bot{bot_token}/sendMessage?parse_mode=HTML&disable_web_page_preview=true&chat_id=" + chat_id + "&text=" + text
try:
requests.get(url)
except Exception as e:
print("catch exception: ", traceback.format_exc())
def send2tg(srv, flag):
if srv not in counterOff:
counterOff[srv] = 0
if srv not in counterOn:
counterOn[srv] = 0
if flag == 1 : # online
if srv in offs:
if counterOn[srv] < 10:
counterOn[srv] += 1
return
#1. Remove srv from offs; 2. Send to tg: I am online
offs.remove(srv)
counterOn[srv] = 0
text = '<b>Server Status</b>' + '\n主机上线: ' + srv
_send(text)
else: #offline
if srv not in offs:
if counterOff[srv] < 10:
counterOff[srv] += 1
return
#1. Append srv to offs; 2. Send to tg: I am offline
offs.append(srv)
counterOff[srv] = 0
text = '<b>Server Status</b>' + '\n主机下线: ' + srv
_send(text)
def sscmd(address):
while True:
r = requests.get(url=address, headers={"User-Agent": "ServerStatus/20211116"})
try:
jsonR = r.json()
except Exception as e:
print('未发现任何节点')
continue
for i in jsonR["servers"]:
if i["online4"] is False and i["online6"] is False:
send2tg(i["name"], 0)
else:
send2tg(i["name"], 1)
time.sleep(3)
if __name__ == '__main__':
sscmd(NODE_STATUS_URL)

View File

@@ -0,0 +1,38 @@
version: "3"
services:
serverstatus:
build:
context: ..
dockerfile: Dockerfile
image: serverstatus_server
container_name: serverstatus
restart: unless-stopped
networks:
serverstatus-network:
ipv4_address: 172.23.0.2
volumes:
- ../server/config.json:/ServerStatus/server/config.json
- ../web/json:/usr/share/nginx/html/json
ports:
- 35601:35601
- 8080:80
bot:
build:
context: .
dockerfile: Dockerfile-telegram
image: serverstatus_bot
container_name: bot4sss
restart: unless-stopped
networks:
serverstatus-network:
ipv4_address: 172.23.0.3
environment:
- TG_CHAT_ID=${TG_CHAT_ID}
- TG_BOT_TOKEN=${TG_BOT_TOKEN}
networks:
serverstatus-network:
name: serverstatus-network
ipam:
config:
- subnet: 172.23.0.0/24

View File

@@ -6,7 +6,7 @@ CFLAGS = -Wall -O2
#CXX = clang++
CXX = g++
CXXFLAGS = -Wall -O2
CXXFLAGS = -Wall -O2 -std=c++11
ODIR = obj
SDIR = src
@@ -26,7 +26,7 @@ $(ODIR)/%.o: $(SDIR)/%.cpp
$(CXX) -c $(INC) $(CXXFLAGS) $< -o $@
$(OUT): $(OBJS)
$(CXX) $(LIBS) $^ -o $(OUT)
$(CXX) $(LIBS) $^ -o $(OUT) -lcurl
.PHONY: clean

View File

@@ -1,37 +1,79 @@
{"servers":
[
{
"servers": [
{
"username": "s01",
"name": "node1",
"type": "xen",
"host": "host1",
"location": "cn",
"password": "USER_DEFAULT_PASSWORD"
"location": "🇨🇳",
"password": "USER_DEFAULT_PASSWORD",
"monthstart": 1
},
{
"username": "s02",
"name": "node2",
"type": "vmware",
"host": "host2",
"location": "jp",
"password": "USER_DEFAULT_PASSWORD"
"location": "🇯🇵",
"password": "USER_DEFAULT_PASSWORD",
"monthstart": 1
},
{
"disabled": true,
"username": "s03",
"name": "node3",
"type": "Nothing",
"type": "hyper",
"host": "host3",
"location": "fr",
"password": "USER_DEFAULT_PASSWORD"
"location": "🇫🇷",
"password": "USER_DEFAULT_PASSWORD",
"monthstart": 1
},
{
"username": "s04",
"name": "node4",
"type": "kvm",
"host": "host4",
"location": "kr",
"password": "USER_DEFAULT_PASSWORD"
"location": "🇰🇷",
"password": "USER_DEFAULT_PASSWORD",
"monthstart": 1
}
],
"watchdog": [
{
"name": "cpu high warning",
"rule": "cpu>90&load_1>3",
"interval": 600,
"callback": "https://yourSMSurl"
},
{
"name": "memory high warning",
"rule": "(memory_used/memory_total)*100>90",
"interval": 300,
"callback": "https://yourSMSurl"
},
{
"name": "offline warning",
"rule": "online4=0&online6=0",
"interval": 600,
"callback": "https://yourSMSurl"
},
{
"name": "ddcc attack",
"rule": "tcp_count>500",
"interval": 300,
"callback": "https://yourSMSurl"
},
{
"name": "month traffic warning",
"rule": "(network_out-last_network_out)/1024/1024/1024>999",
"interval": 3600,
"callback": "https://yourSMSurl"
},
{
"name": "you can parse an expression combining any known field",
"rule": "load_5>3",
"interval": 900,
"callback": "https://yourSMSurl"
}
]
}
}

40746
server/src/exprtk.hpp Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -7,6 +7,8 @@
#include <json.h>
#include "server.h"
#include "main.h"
#include "exprtk.hpp"
#include "curl/curl.h"
#if defined(CONF_FAMILY_UNIX)
#include <signal.h>
@@ -96,6 +98,13 @@ void CMain::OnDelClient(int ClientNetID)
{
int ClientID = ClientNetToClient(ClientNetID);
dbg_msg("main", "OnDelClient(ncid=%d, cid=%d)", ClientNetID, ClientID);
//copy offline message for watchdog
WatchdogMessage(ClientNetID,
0, 0, 0, 0, 0, 0,
0, 0, 0,0, 0, 0,
0, 0, 0, 0, 0, 0,
0, 0, 0,0, 0, 0,
0, 0, 0, 0);
if(ClientID >= 0 && ClientID < NET_MAX_CLIENTS)
{
Client(ClientID)->m_Connected = false;
@@ -178,36 +187,48 @@ int CMain::HandleMessage(int ClientNetID, char *pMessage)
pClient->m_Stats.m_HDDTotal = rStart["hdd_total"].u.integer;
if(rStart["hdd_used"].type)
pClient->m_Stats.m_HDDUsed = rStart["hdd_used"].u.integer;
if(rStart["io_read"].type)
pClient->m_Stats.m_IORead = rStart["io_read"].u.integer;
if(rStart["io_write"].type)
pClient->m_Stats.m_IOWrite = rStart["io_write"].u.integer;
if(rStart["cpu"].type)
pClient->m_Stats.m_CPU = rStart["cpu"].u.dbl;
if(rStart["online4"].type && pClient->m_ClientNetType == NETTYPE_IPV6)
pClient->m_Stats.m_Online4 = rStart["online4"].u.boolean;
if(rStart["online6"].type && pClient->m_ClientNetType == NETTYPE_IPV4)
pClient->m_Stats.m_Online6 = rStart["online6"].u.boolean;
if(rStart["ip_status"].type)
pClient->m_Stats.m_IpStatus = rStart["ip_status"].u.boolean;
if(rStart["custom"].type == json_string)
str_copy(pClient->m_Stats.m_aCustom, rStart["custom"].u.string.ptr, sizeof(pClient->m_Stats.m_aCustom));
//copy message for watchdog to analysis
WatchdogMessage(ClientNetID,
pClient->m_Stats.m_Load_1, pClient->m_Stats.m_Load_5, pClient->m_Stats.m_Load_15,
pClient->m_Stats.m_ping_10010, pClient->m_Stats.m_ping_189, pClient->m_Stats.m_ping_10086,
pClient->m_Stats.m_time_10010, pClient->m_Stats.m_time_189, pClient->m_Stats.m_time_10086,
pClient->m_Stats.m_tcpCount, pClient->m_Stats.m_udpCount, pClient->m_Stats.m_processCount,
pClient->m_Stats.m_threadCount, pClient->m_Stats.m_NetworkRx, pClient->m_Stats.m_NetworkTx,
pClient->m_Stats.m_NetworkIN, pClient->m_Stats.m_NetworkOUT,pClient->m_Stats.m_MemTotal,
pClient->m_Stats.m_MemUsed, pClient->m_Stats.m_SwapTotal, pClient->m_Stats.m_SwapUsed,
pClient->m_Stats.m_HDDTotal, pClient->m_Stats.m_HDDUsed, pClient->m_Stats.m_IORead,
pClient->m_Stats.m_IOWrite, pClient->m_Stats.m_CPU, pClient->m_Stats.m_Online4,
pClient->m_Stats.m_Online6);
if(m_Config.m_Verbose)
{
if(rStart["online4"].type)
dbg_msg("main", "Online4: %s\nUptime: %" PRId64 "\nIpStatus: %s\nLoad_1: %f\nLoad_5: %f\nLoad_15: %f\nPing_10010: %f\nPing_189: %f\nPing_10086: %f\nTime_10010: %" PRId64 "\nTime_189: %" PRId64 "\nTime_10086: %" PRId64 "\nTcp_count: %" PRId64 "\nUdp_count: %" PRId64 "\nprocess_count: %" PRId64 "\nthread_count: %" PRId64 "\nNetworkRx: %" PRId64 "\nNetworkTx: %" PRId64 "\nNetworkIN: %" PRId64 "\nNetworkOUT: %" PRId64 "\nMemTotal: %" PRId64 "\nMemUsed: %" PRId64 "\nSwapTotal: %" PRId64 "\nSwapUsed: %" PRId64 "\nHDDTotal: %" PRId64 "\nHDDUsed: %" PRId64 "\nCPU: %f\n",
dbg_msg("main", "Online4: %s\nUptime: %" PRId64 "\nLoad_1: %f\nLoad_5: %f\nLoad_15: %f\nPing_10010: %f\nPing_189: %f\nPing_10086: %f\nTime_10010: %" PRId64 "\nTime_189: %" PRId64 "\nTime_10086: %" PRId64 "\nTcp_count: %" PRId64 "\nUdp_count: %" PRId64 "\nprocess_count: %" PRId64 "\nthread_count: %" PRId64 "\nNetworkRx: %" PRId64 "\nNetworkTx: %" PRId64 "\nNetworkIN: %" PRId64 "\nNetworkOUT: %" PRId64 "\nMemTotal: %" PRId64 "\nMemUsed: %" PRId64 "\nSwapTotal: %" PRId64 "\nSwapUsed: %" PRId64 "\nHDDTotal: %" PRId64 "\nHDDUsed: %" PRId64 "\nCPU: %f\nIORead: %" PRId64 "\nIOWrite: %" PRId64 "\n",
rStart["online4"].u.boolean ? "true" : "false",
pClient->m_Stats.m_Uptime,
pClient->m_Stats.m_IpStatus ? "true" : "false",
pClient->m_Stats.m_Load_1, pClient->m_Stats.m_Load_5, pClient->m_Stats.m_Load_15, pClient->m_Stats.m_ping_10010, pClient->m_Stats.m_ping_189, pClient->m_Stats.m_ping_10086, pClient->m_Stats.m_time_10010, pClient->m_Stats.m_time_189, pClient->m_Stats.m_time_10086,pClient->m_Stats.m_tcpCount,pClient->m_Stats.m_udpCount,pClient->m_Stats.m_processCount,pClient->m_Stats.m_threadCount,pClient->m_Stats.m_NetworkRx, pClient->m_Stats.m_NetworkTx, pClient->m_Stats.m_NetworkIN, pClient->m_Stats.m_NetworkOUT, pClient->m_Stats.m_MemTotal, pClient->m_Stats.m_MemUsed, pClient->m_Stats.m_SwapTotal, pClient->m_Stats.m_SwapUsed, pClient->m_Stats.m_HDDTotal, pClient->m_Stats.m_HDDUsed, pClient->m_Stats.m_CPU);
pClient->m_Stats.m_Load_1, pClient->m_Stats.m_Load_5, pClient->m_Stats.m_Load_15, pClient->m_Stats.m_ping_10010, pClient->m_Stats.m_ping_189, pClient->m_Stats.m_ping_10086, pClient->m_Stats.m_time_10010, pClient->m_Stats.m_time_189, pClient->m_Stats.m_time_10086,pClient->m_Stats.m_tcpCount,pClient->m_Stats.m_udpCount,pClient->m_Stats.m_processCount,pClient->m_Stats.m_threadCount,pClient->m_Stats.m_NetworkRx, pClient->m_Stats.m_NetworkTx, pClient->m_Stats.m_NetworkIN, pClient->m_Stats.m_NetworkOUT, pClient->m_Stats.m_MemTotal, pClient->m_Stats.m_MemUsed, pClient->m_Stats.m_SwapTotal, pClient->m_Stats.m_SwapUsed, pClient->m_Stats.m_HDDTotal, pClient->m_Stats.m_HDDUsed, pClient->m_Stats.m_CPU, pClient->m_Stats.m_IORead, pClient->m_Stats.m_IOWrite);
else if(rStart["online6"].type)
dbg_msg("main", "Online6: %s\nUptime: %" PRId64 "\nIpStatus: %s\nLoad_1: %f\nLoad_5: %f\nLoad_15: %f\nPing_10010: %f\nPing_189: %f\nPing_10086: %f\nTime_10010: %" PRId64 "\nTime_189: %" PRId64 "\nTime_10086: %" PRId64 "\nTcp_count: %" PRId64 "\nUdp_count: %" PRId64 "\nprocess_count: %" PRId64 "\nthread_count: %" PRId64 "\nNetworkRx: %" PRId64 "\nNetworkTx: %" PRId64 "\nNetworkIN: %" PRId64 "\nNetworkOUT: %" PRId64 "\nMemTotal: %" PRId64 "\nMemUsed: %" PRId64 "\nSwapTotal: %" PRId64 "\nSwapUsed: %" PRId64 "\nHDDTotal: %" PRId64 "\nHDDUsed: %" PRId64 "\nCPU: %f\n",
dbg_msg("main", "Online6: %s\nUptime: %" PRId64 "\nLoad_1: %f\nLoad_5: %f\nLoad_15: %f\nPing_10010: %f\nPing_189: %f\nPing_10086: %f\nTime_10010: %" PRId64 "\nTime_189: %" PRId64 "\nTime_10086: %" PRId64 "\nTcp_count: %" PRId64 "\nUdp_count: %" PRId64 "\nprocess_count: %" PRId64 "\nthread_count: %" PRId64 "\nNetworkRx: %" PRId64 "\nNetworkTx: %" PRId64 "\nNetworkIN: %" PRId64 "\nNetworkOUT: %" PRId64 "\nMemTotal: %" PRId64 "\nMemUsed: %" PRId64 "\nSwapTotal: %" PRId64 "\nSwapUsed: %" PRId64 "\nHDDTotal: %" PRId64 "\nHDDUsed: %" PRId64 "\nCPU: %f\nIORead: %" PRId64 "\nIOWrite: %" PRId64 "\n",
rStart["online6"].u.boolean ? "true" : "false",
pClient->m_Stats.m_Uptime,
pClient->m_Stats.m_IpStatus ? "true" : "false",
pClient->m_Stats.m_Load_1, pClient->m_Stats.m_Load_5, pClient->m_Stats.m_Load_15, pClient->m_Stats.m_ping_10010, pClient->m_Stats.m_ping_189, pClient->m_Stats.m_ping_10086, pClient->m_Stats.m_time_10010, pClient->m_Stats.m_time_189, pClient->m_Stats.m_time_10086,pClient->m_Stats.m_tcpCount,pClient->m_Stats.m_udpCount,pClient->m_Stats.m_processCount,pClient->m_Stats.m_threadCount,pClient->m_Stats.m_NetworkRx, pClient->m_Stats.m_NetworkTx, pClient->m_Stats.m_NetworkIN, pClient->m_Stats.m_NetworkOUT, pClient->m_Stats.m_MemTotal, pClient->m_Stats.m_MemUsed, pClient->m_Stats.m_SwapTotal, pClient->m_Stats.m_SwapUsed, pClient->m_Stats.m_HDDTotal, pClient->m_Stats.m_HDDUsed, pClient->m_Stats.m_CPU);
pClient->m_Stats.m_Load_1, pClient->m_Stats.m_Load_5, pClient->m_Stats.m_Load_15, pClient->m_Stats.m_ping_10010, pClient->m_Stats.m_ping_189, pClient->m_Stats.m_ping_10086, pClient->m_Stats.m_time_10010, pClient->m_Stats.m_time_189, pClient->m_Stats.m_time_10086,pClient->m_Stats.m_tcpCount,pClient->m_Stats.m_udpCount,pClient->m_Stats.m_processCount,pClient->m_Stats.m_threadCount,pClient->m_Stats.m_NetworkRx, pClient->m_Stats.m_NetworkTx, pClient->m_Stats.m_NetworkIN, pClient->m_Stats.m_NetworkOUT, pClient->m_Stats.m_MemTotal, pClient->m_Stats.m_MemUsed, pClient->m_Stats.m_SwapTotal, pClient->m_Stats.m_SwapUsed, pClient->m_Stats.m_HDDTotal, pClient->m_Stats.m_HDDUsed, pClient->m_Stats.m_CPU, pClient->m_Stats.m_IORead, pClient->m_Stats.m_IOWrite);
else
dbg_msg("main", "Uptime: %" PRId64 "\nIpStatus: %s\nLoad_1: %f\nLoad_5: %f\nLoad_15: %f\nPing_10010: %f\nPing_189: %f\nPing_10086: %f\nTime_10010: %" PRId64 "\nTime_189: %" PRId64 "\nTime_10086: %" PRId64 "\nTcp_count: %" PRId64 "\nUdp_count: %" PRId64 "\nprocess_count: %" PRId64 "\nthread_count: %" PRId64 "\nNetworkRx: %" PRId64 "\nNetworkTx: %" PRId64 "\nNetworkIN: %" PRId64 "\nNetworkOUT: %" PRId64 "\nMemTotal: %" PRId64 "\nMemUsed: %" PRId64 "\nSwapTotal: %" PRId64 "\nSwapUsed: %" PRId64 "\nHDDTotal: %" PRId64 "\nHDDUsed: %" PRId64 "\nCPU: %f\n",
dbg_msg("main", "Uptime: %" PRId64 "\nLoad_1: %f\nLoad_5: %f\nLoad_15: %f\nPing_10010: %f\nPing_189: %f\nPing_10086: %f\nTime_10010: %" PRId64 "\nTime_189: %" PRId64 "\nTime_10086: %" PRId64 "\nTcp_count: %" PRId64 "\nUdp_count: %" PRId64 "\nprocess_count: %" PRId64 "\nthread_count: %" PRId64 "\nNetworkRx: %" PRId64 "\nNetworkTx: %" PRId64 "\nNetworkIN: %" PRId64 "\nNetworkOUT: %" PRId64 "\nMemTotal: %" PRId64 "\nMemUsed: %" PRId64 "\nSwapTotal: %" PRId64 "\nSwapUsed: %" PRId64 "\nHDDTotal: %" PRId64 "\nHDDUsed: %" PRId64 "\nCPU: %f\nIORead: %" PRId64 "\nIOWrite: %" PRId64 "\n",
pClient->m_Stats.m_Uptime,
pClient->m_Stats.m_IpStatus ? "true" : "false",
pClient->m_Stats.m_Load_1, pClient->m_Stats.m_Load_5, pClient->m_Stats.m_Load_15, pClient->m_Stats.m_ping_10010, pClient->m_Stats.m_ping_189, pClient->m_Stats.m_ping_10086, pClient->m_Stats.m_time_10010, pClient->m_Stats.m_time_189, pClient->m_Stats.m_time_10086,pClient->m_Stats.m_tcpCount,pClient->m_Stats.m_udpCount,pClient->m_Stats.m_processCount,pClient->m_Stats.m_threadCount,pClient->m_Stats.m_NetworkRx, pClient->m_Stats.m_NetworkTx, pClient->m_Stats.m_NetworkIN, pClient->m_Stats.m_NetworkOUT, pClient->m_Stats.m_MemTotal, pClient->m_Stats.m_MemUsed, pClient->m_Stats.m_SwapTotal, pClient->m_Stats.m_SwapUsed, pClient->m_Stats.m_HDDTotal, pClient->m_Stats.m_HDDUsed, pClient->m_Stats.m_CPU);
pClient->m_Stats.m_Load_1, pClient->m_Stats.m_Load_5, pClient->m_Stats.m_Load_15, pClient->m_Stats.m_ping_10010, pClient->m_Stats.m_ping_189, pClient->m_Stats.m_ping_10086, pClient->m_Stats.m_time_10010, pClient->m_Stats.m_time_189, pClient->m_Stats.m_time_10086,pClient->m_Stats.m_tcpCount,pClient->m_Stats.m_udpCount,pClient->m_Stats.m_processCount,pClient->m_Stats.m_threadCount,pClient->m_Stats.m_NetworkRx, pClient->m_Stats.m_NetworkTx, pClient->m_Stats.m_NetworkIN, pClient->m_Stats.m_NetworkOUT, pClient->m_Stats.m_MemTotal, pClient->m_Stats.m_MemUsed, pClient->m_Stats.m_SwapTotal, pClient->m_Stats.m_SwapUsed, pClient->m_Stats.m_HDDTotal, pClient->m_Stats.m_HDDUsed, pClient->m_Stats.m_CPU, pClient->m_Stats.m_IORead, pClient->m_Stats.m_IOWrite);
}
// clean up
@@ -235,6 +256,113 @@ int CMain::HandleMessage(int ClientNetID, char *pMessage)
return 1;
}
void CMain::WatchdogMessage(int ClientNetID, double load_1, double load_5, double load_15, double ping_10010, double ping_189, double ping_10086,
double time_10010, double time_189, double time_10086, double tcp_count, double udp_count, double process_count, double thread_count,
double network_rx, double network_tx, double network_in, double network_out, double memory_total, double memory_used,
double swap_total, double swap_used, double hdd_total, double hdd_used, double io_read, double io_write, double cpu,
double online4, double online6)
{
int ID = 0;
while (strcmp(Watchdog(ID)->m_aName, "NULL"))
{
typedef exprtk::symbol_table<double> symbol_table_t;
typedef exprtk::expression<double> expression_t;
typedef exprtk::parser<double> parser_t;
const std::string expression_string = Watchdog(ID)->m_aRule;
symbol_table_t symbol_table;
symbol_table.add_variable("load_1",load_1);
symbol_table.add_variable("load_5",load_5);
symbol_table.add_variable("load_15",load_15);
symbol_table.add_variable("ping_10010",ping_10010);
symbol_table.add_variable("ping_189",ping_189);
symbol_table.add_variable("ping_10086",ping_10086);
symbol_table.add_variable("time_10010",time_10010);
symbol_table.add_variable("time_189",time_189);
symbol_table.add_variable("time_10086",time_10086);
symbol_table.add_variable("tcp_count",tcp_count);
symbol_table.add_variable("udp_count",udp_count);
symbol_table.add_variable("process_count",process_count);
symbol_table.add_variable("thread_count",thread_count);
symbol_table.add_variable("network_rx",network_rx);
symbol_table.add_variable("network_tx",network_tx);
symbol_table.add_variable("network_in",network_in);
symbol_table.add_variable("network_out",network_out);
symbol_table.add_variable("memory_total",memory_total);
symbol_table.add_variable("memory_used",memory_used);
symbol_table.add_variable("swap_total",swap_total);
symbol_table.add_variable("swap_used",swap_used);
symbol_table.add_variable("hdd_total",hdd_total);
symbol_table.add_variable("hdd_used",hdd_used);
symbol_table.add_variable("io_read",io_read);
symbol_table.add_variable("io_write",io_write);
symbol_table.add_variable("cpu",cpu);
symbol_table.add_variable("online4",online4);
symbol_table.add_variable("online6",online6);
symbol_table.add_constants();
expression_t expression;
expression.register_symbol_table(symbol_table);
parser_t parser;
parser.compile(expression_string,expression);
if (expression.value() > 0)
{
int ClientID = ClientNetToClient(ClientNetID);
time_t currentStamp = (long long)time(/*ago*/0);
if ((currentStamp-Client(ClientID)->m_AlarmLastTime) > Watchdog(ID)->m_aInterval)
{
Client(ClientID)->m_AlarmLastTime = currentStamp;
CURL *curl;
CURLcode res;
curl_global_init(CURL_GLOBAL_ALL);
curl = curl_easy_init();
if(curl) {
//standard time
char standardTime[32]= { 0 };
strftime(standardTime, sizeof(standardTime), "%Y-%m-%d %H:%M:%S",localtime(&currentStamp));
//url encode, Rules conflict with url special characterseg&, del rules, by https://cpp.la, 2023-10-09
char encodeBuffer[2048] = { 0 };
sprintf(encodeBuffer, "【告警名称】 %s \n\n【告警时间】 %s \n\n【用户名】 %s \n\n【节点名】 %s \n\n【虚拟化】 %s \n\n【主机名】 %s \n\n【位 置】 %s",
Watchdog(ID)->m_aName,
standardTime,
Client(ClientID)->m_aUsername,
Client(ClientID)->m_aName,
Client(ClientID)->m_aType,
Client(ClientID)->m_aHost,
Client(ClientID)->m_aLocation);
char *encodeUrl = curl_easy_escape(curl, encodeBuffer, strlen(encodeBuffer));
//standard url
char urlBuffer[2048] = { 0 };
sprintf(urlBuffer, "%s%s",Watchdog(ID)->m_aCallback, encodeUrl);
curl_easy_setopt(curl, CURLOPT_POST, 1L);
curl_easy_setopt(curl, CURLOPT_URL, urlBuffer);
curl_easy_setopt(curl, CURLOPT_POSTFIELDS,"signature=ServerStatus");
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0);
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0);
curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 3L);
curl_easy_setopt(curl, CURLOPT_TIMEOUT, 6L);
res = curl_easy_perform(curl);
if(res != CURLE_OK)
fprintf(stderr, "watchdog failed: %s\n", curl_easy_strerror(res));
if(encodeUrl)
curl_free(encodeUrl);
curl_easy_cleanup(curl);
}
curl_global_cleanup();
}
}
ID++;
}
}
void CMain::JSONUpdateThread(void *pUser)
{
CJSONUpdateThreadData *m_pJSONUpdateThreadData = (CJSONUpdateThreadData *)pUser;
@@ -269,17 +397,35 @@ void CMain::JSONUpdateThread(void *pUser)
else
str_format(aUptime, sizeof(aUptime), "%02d:%02d:%02d", (int)(pClients[i].m_Stats.m_Uptime/60.0/60.0), (int)((pClients[i].m_Stats.m_Uptime/60)%60), (int)((pClients[i].m_Stats.m_Uptime)%60));
// track month network traffic, diff: 2021-10-01 00:05, 5minutes
// last_network_in/out is last record flag.
time_t currentStamp = (long long)time(/*ago*/0);
if(0 == pClients[i].m_LastNetworkIN || (0 != pClients[i].m_Stats.m_NetworkIN && pClients[i].m_LastNetworkIN > pClients[i].m_Stats.m_NetworkIN) || (localtime(&currentStamp)->tm_mday == pClients[i].m_aMonthStart && localtime(&currentStamp)->tm_hour == 0 && localtime(&currentStamp)->tm_min < 5))
{
pClients[i].m_LastNetworkIN = pClients[i].m_Stats.m_NetworkIN;
pClients[i].m_LastNetworkOUT = pClients[i].m_Stats.m_NetworkOUT;
}
str_format(pBuf, sizeof(aFileBuf) - (pBuf - aFileBuf),
"{ \"name\": \"%s\",\"type\": \"%s\",\"host\": \"%s\",\"location\": \"%s\",\"online4\": %s, \"online6\": %s,\"ip_status\": %s,\"uptime\": \"%s\",\"load_1\": %.2f, \"load_5\": %.2f, \"load_15\": %.2f,\"ping_10010\": %.2f, \"ping_189\": %.2f, \"ping_10086\": %.2f,\"time_10010\": %" PRId64 ", \"time_189\": %" PRId64 ", \"time_10086\": %" PRId64 ", \"tcp_count\": %" PRId64 ", \"udp_count\": %" PRId64 ", \"process_count\": %" PRId64 ", \"thread_count\": %" PRId64 ", \"network_rx\": %" PRId64 ", \"network_tx\": %" PRId64 ", \"network_in\": %" PRId64 ", \"network_out\": %" PRId64 ", \"cpu\": %d, \"memory_total\": %" PRId64 ", \"memory_used\": %" PRId64 ", \"swap_total\": %" PRId64 ", \"swap_used\": %" PRId64 ", \"hdd_total\": %" PRId64 ", \"hdd_used\": %" PRId64 ", \"custom\": \"%s\" },\n",
"{ \"name\": \"%s\",\"type\": \"%s\",\"host\": \"%s\",\"location\": \"%s\",\"online4\": %s, \"online6\": %s, \"uptime\": \"%s\",\"load_1\": %.2f, \"load_5\": %.2f, \"load_15\": %.2f,\"ping_10010\": %.2f, \"ping_189\": %.2f, \"ping_10086\": %.2f,\"time_10010\": %" PRId64 ", \"time_189\": %" PRId64 ", \"time_10086\": %" PRId64 ", \"tcp_count\": %" PRId64 ", \"udp_count\": %" PRId64 ", \"process_count\": %" PRId64 ", \"thread_count\": %" PRId64 ", \"network_rx\": %" PRId64 ", \"network_tx\": %" PRId64 ", \"network_in\": %" PRId64 ", \"network_out\": %" PRId64 ", \"cpu\": %d, \"memory_total\": %" PRId64 ", \"memory_used\": %" PRId64 ", \"swap_total\": %" PRId64 ", \"swap_used\": %" PRId64 ", \"hdd_total\": %" PRId64 ", \"hdd_used\": %" PRId64 ", \"last_network_in\": %" PRId64 ", \"last_network_out\": %" PRId64 ",\"io_read\": %" PRId64 ", \"io_write\": %" PRId64 ",\"custom\": \"%s\" },\n",
pClients[i].m_aName,pClients[i].m_aType,pClients[i].m_aHost,pClients[i].m_aLocation,
pClients[i].m_Stats.m_Online4 ? "true" : "false",pClients[i].m_Stats.m_Online6 ? "true" : "false",pClients[i].m_Stats.m_IpStatus ? "true": "false",
aUptime, pClients[i].m_Stats.m_Load_1, pClients[i].m_Stats.m_Load_5, pClients[i].m_Stats.m_Load_15, pClients[i].m_Stats.m_ping_10010, pClients[i].m_Stats.m_ping_189, pClients[i].m_Stats.m_ping_10086, pClients[i].m_Stats.m_time_10010, pClients[i].m_Stats.m_time_189, pClients[i].m_Stats.m_time_10086,pClients[i].m_Stats.m_tcpCount,pClients[i].m_Stats.m_udpCount,pClients[i].m_Stats.m_processCount,pClients[i].m_Stats.m_threadCount,pClients[i].m_Stats.m_NetworkRx, pClients[i].m_Stats.m_NetworkTx, pClients[i].m_Stats.m_NetworkIN, pClients[i].m_Stats.m_NetworkOUT, (int)pClients[i].m_Stats.m_CPU, pClients[i].m_Stats.m_MemTotal, pClients[i].m_Stats.m_MemUsed, pClients[i].m_Stats.m_SwapTotal, pClients[i].m_Stats.m_SwapUsed, pClients[i].m_Stats.m_HDDTotal, pClients[i].m_Stats.m_HDDUsed, pClients[i].m_Stats.m_aCustom);
pClients[i].m_Stats.m_Online4 ? "true" : "false",pClients[i].m_Stats.m_Online6 ? "true" : "false",
aUptime, pClients[i].m_Stats.m_Load_1, pClients[i].m_Stats.m_Load_5, pClients[i].m_Stats.m_Load_15, pClients[i].m_Stats.m_ping_10010, pClients[i].m_Stats.m_ping_189, pClients[i].m_Stats.m_ping_10086,
pClients[i].m_Stats.m_time_10010, pClients[i].m_Stats.m_time_189, pClients[i].m_Stats.m_time_10086,pClients[i].m_Stats.m_tcpCount,pClients[i].m_Stats.m_udpCount,pClients[i].m_Stats.m_processCount,pClients[i].m_Stats.m_threadCount,
pClients[i].m_Stats.m_NetworkRx, pClients[i].m_Stats.m_NetworkTx, pClients[i].m_Stats.m_NetworkIN, pClients[i].m_Stats.m_NetworkOUT, (int)pClients[i].m_Stats.m_CPU, pClients[i].m_Stats.m_MemTotal, pClients[i].m_Stats.m_MemUsed,
pClients[i].m_Stats.m_SwapTotal, pClients[i].m_Stats.m_SwapUsed, pClients[i].m_Stats.m_HDDTotal, pClients[i].m_Stats.m_HDDUsed,
pClients[i].m_Stats.m_NetworkIN == 0 || pClients[i].m_LastNetworkIN == 0 ? pClients[i].m_Stats.m_NetworkIN : pClients[i].m_LastNetworkIN,
pClients[i].m_Stats.m_NetworkOUT == 0 || pClients[i].m_LastNetworkOUT == 0 ? pClients[i].m_Stats.m_NetworkOUT : pClients[i].m_LastNetworkOUT,
pClients[i].m_Stats.m_IORead, pClients[i].m_Stats.m_IOWrite,
pClients[i].m_Stats.m_aCustom);
pBuf += strlen(pBuf);
}
else
{
str_format(pBuf, sizeof(aFileBuf) - (pBuf - aFileBuf), "{ \"name\": \"%s\", \"type\": \"%s\", \"host\": \"%s\", \"location\": \"%s\", \"online4\": false, \"online6\": false },\n",
pClients[i].m_aName, pClients[i].m_aType, pClients[i].m_aHost, pClients[i].m_aLocation);
// sava network traffic record to json when close client
// last_network_in == last network in record, last_network_out == last network out record
str_format(pBuf, sizeof(aFileBuf) - (pBuf - aFileBuf), "{ \"name\": \"%s\", \"type\": \"%s\", \"host\": \"%s\", \"location\": \"%s\", \"online4\": false, \"online6\": false, \"last_network_in\": %" PRId64 ", \"last_network_out\": %" PRId64 " },\n",
pClients[i].m_aName, pClients[i].m_aType, pClients[i].m_aHost, pClients[i].m_aLocation, pClients[i].m_LastNetworkIN, pClients[i].m_LastNetworkOUT);
pBuf += strlen(pBuf);
}
}
@@ -306,7 +452,11 @@ void CMain::JSONUpdateThread(void *pUser)
fs_rename(aJSONFileTmp, pConfig->m_aJSONFile);
thread_sleep(1000);
}
fs_remove(pConfig->m_aJSONFile);
// support by: https://cpp.la. don't remove month traffic record, storage as "stats.json~", remark: 2021-10-18
// fs_remove(pConfig->m_aJSONFile);
char aJSONFileTmp[1024];
str_format(aJSONFileTmp, sizeof(aJSONFileTmp), "%s~", pConfig->m_aJSONFile);
fs_rename(pConfig->m_aJSONFile, aJSONFileTmp);
}
int CMain::ReadConfig()
@@ -367,21 +517,102 @@ int CMain::ReadConfig()
str_copy(Client(ID)->m_aHost, rStart[i]["host"].u.string.ptr, sizeof(Client(ID)->m_aHost));
str_copy(Client(ID)->m_aLocation, rStart[i]["location"].u.string.ptr, sizeof(Client(ID)->m_aLocation));
str_copy(Client(ID)->m_aPassword, rStart[i]["password"].u.string.ptr, sizeof(Client(ID)->m_aPassword));
//if month start day > 28, diff: 3days(29,30,31)
Client(ID)->m_aMonthStart = rStart[i]["monthstart"].u.integer;
if(Client(ID)->m_aMonthStart > 28)
{
Client(ID)->m_aMonthStart = 28;
}
Client(ID)->m_LastNetworkIN = 0;
Client(ID)->m_LastNetworkOUT = 0;
if(m_Config.m_Verbose)
{
if(Client(ID)->m_Disabled)
dbg_msg("main", "[#%d: Name: \"%s\", Username: \"%s\", Type: \"%s\", Host: \"%s\", Location: \"%s\", Password: \"%s\"]",
ID, Client(ID)->m_aName, Client(ID)->m_aUsername, Client(ID)->m_aType, Client(ID)->m_aHost, Client(ID)->m_aLocation, Client(ID)->m_aPassword);
dbg_msg("main", "[#%d: Name: \"%s\", Username: \"%s\", Type: \"%s\", Host: \"%s\", Location: \"%s\", Password: \"%s\", MonthStart: %\" PRId64 \"]",
ID, Client(ID)->m_aName, Client(ID)->m_aUsername, Client(ID)->m_aType, Client(ID)->m_aHost, Client(ID)->m_aLocation, Client(ID)->m_aPassword, Client(ID)->m_aMonthStart);
else
dbg_msg("main", "#%d: Name: \"%s\", Username: \"%s\", Type: \"%s\", Host: \"%s\", Location: \"%s\", Password: \"%s\"",
ID, Client(ID)->m_aName, Client(ID)->m_aUsername, Client(ID)->m_aType, Client(ID)->m_aHost, Client(ID)->m_aLocation, Client(ID)->m_aPassword);
dbg_msg("main", "#%d: Name: \"%s\", Username: \"%s\", Type: \"%s\", Host: \"%s\", Location: \"%s\", Password: \"%s\", MonthStart: %\" PRId64 \"",
ID, Client(ID)->m_aName, Client(ID)->m_aUsername, Client(ID)->m_aType, Client(ID)->m_aHost, Client(ID)->m_aLocation, Client(ID)->m_aPassword, Client(ID)->m_aMonthStart);
}
ID++;
}
}
// watch dog
// support by: https://cpp.la
ID = 0;
const json_value &jStart = (*pJsonData)["watchdog"];
if(jStart.type == json_array)
{
for(unsigned i = 0; i < jStart.u.array.length; i++)
{
if(ID < 0 || ID >= NET_MAX_CLIENTS)
continue;
str_copy(Watchdog(ID)->m_aName, jStart[i]["name"].u.string.ptr, sizeof(Watchdog(ID)->m_aName));
str_copy(Watchdog(ID)->m_aRule, jStart[i]["rule"].u.string.ptr, sizeof(Watchdog(ID)->m_aRule));
Watchdog(ID)->m_aInterval = jStart[i]["interval"].u.integer;
str_copy(Watchdog(ID)->m_aCallback, jStart[i]["callback"].u.string.ptr, sizeof(Watchdog(ID)->m_aCallback));
ID++;
}
str_copy(Watchdog(ID)->m_aName, "NULL", sizeof(Watchdog(ID)->m_aName));
} else
str_copy(Watchdog(ID)->m_aName, "NULL", sizeof(Watchdog(ID)->m_aName));
// if file exists, read last network traffic recordreset m_LastNetworkIN and m_LastNetworkOUT
// support by: https://cpp.la
IOHANDLE nFile = io_open(m_Config.m_aJSONFile, IOFLAG_READ);
if(!nFile)
{
char aJSONFileTmp[1024];
str_format(aJSONFileTmp, sizeof(aJSONFileTmp), "%s~", m_Config.m_aJSONFile);
nFile = io_open(aJSONFileTmp, IOFLAG_READ);
}
if(nFile)
{
int nFileSize = (int)io_length(nFile);
char *pNFileData = (char *)mem_alloc(nFileSize + 1, 1);
io_read(nFile, pNFileData, nFileSize);
pNFileData[nFileSize] = 0;
io_close(nFile);
json_settings nJsonSettings;
mem_zero(&nJsonSettings, sizeof(nJsonSettings));
json_value *pNJsonData = json_parse_ex(&nJsonSettings, pNFileData, strlen(pNFileData), aError);
if(pNJsonData)
{
const json_value &cStart = (*pNJsonData)["servers"];
if(rStart.type == json_array)
{
int ID = 0;
for(unsigned i = 0; i < rStart.u.array.length; i++)
{
if(ID < 0 || ID >= NET_MAX_CLIENTS)
continue;
for(unsigned j = 0; j < cStart.u.array.length; j++)
{
if(strcmp(Client(ID)->m_aName, cStart[j]["name"].u.string.ptr)==0 &&
strcmp(Client(ID)->m_aType, cStart[j]["type"].u.string.ptr)==0 &&
strcmp(Client(ID)->m_aHost, cStart[j]["host"].u.string.ptr)==0 &&
strcmp(Client(ID)->m_aLocation, cStart[j]["location"].u.string.ptr)==0)
{
Client(ID)->m_LastNetworkIN = cStart[j]["last_network_in"].u.integer;
Client(ID)->m_LastNetworkOUT = cStart[j]["last_network_out"].u.integer;
break;
}
}
ID++;
}
}
json_value_free(pNJsonData);
}
mem_free(pNFileData);
}
// clean up
json_value_free(pJsonData);
mem_free(pFileData);
@@ -486,3 +717,4 @@ int main(int argc, const char *argv[])
return RetVal;
}

View File

@@ -36,15 +36,20 @@ class CMain
char m_aHost[128];
char m_aLocation[128];
char m_aPassword[128];
int m_aMonthStart; //track month network traffic. by: https://cpp.la
int64 m_TimeConnected;
int64 m_LastUpdate;
int64_t m_LastNetworkIN; //restore month traffic info.
int64_t m_LastNetworkOUT; //restore month traffic info.
int64_t m_TimeConnected;
int64_t m_LastUpdate;
int64_t m_AlarmLastTime; //record last alarm time.
struct CStats
{
bool m_Online4;
bool m_Online6;
bool m_IpStatus; //mh361 or mh370, mourn mh370, 2014-03-08 01:20 lost from all over the world. by:cpp.la
// bool m_IpStatus delete ip_status check, Duplicate packet loss rate detection
// mh361 or mh370, mourn mh370, 2014-03-08 01:20 lost from all over the world. by:https://cpp.la
int64_t m_Uptime;
double m_Load_1;
double m_Load_5;
@@ -69,6 +74,8 @@ class CMain
int64_t m_udpCount;
int64_t m_processCount;
int64_t m_threadCount;
int64_t m_IORead;
int64_t m_IOWrite;
double m_CPU;
char m_aCustom[512];
// Options
@@ -76,6 +83,13 @@ class CMain
} m_Stats;
} m_aClients[NET_MAX_CLIENTS];
struct CWatchDog{
char m_aName[128];
char m_aRule[128];
int m_aInterval;
char m_aCallback[1024];
} m_aCWatchDogs[NET_MAX_CLIENTS];
struct CJSONUpdateThreadData
{
CClient *pClients;
@@ -93,6 +107,14 @@ public:
int ReadConfig();
int Run();
CWatchDog *Watchdog(int ruleID) { return &m_aCWatchDogs[ruleID]; }
void WatchdogMessage(int ClientNetID,
double load_1, double load_5, double load_15, double ping_10010, double ping_189, double ping_10086,
double time_10010, double time_189, double time_10086, double tcp_count, double udp_count, double process_count, double thread_count,
double network_rx, double network_tx, double network_in, double network_out,double memory_total,
double memory_used,double swap_total, double swap_used, double hdd_total,
double hdd_used, double io_read, double io_write, double cpu,double online4, double online6);
CClient *Client(int ClientID) { return &m_aClients[ClientID]; }
CClient *ClientNet(int ClientNetID);
const CConfig *Config() const { return &m_Config; }

View File

@@ -10,7 +10,7 @@ enum
NET_CONNSTATE_ERROR=4,
NET_MAX_PACKETSIZE = 1400,
NET_MAX_CLIENTS = 128
NET_MAX_CLIENTS = 256
};
typedef int (*NETFUNC_DELCLIENT)(int ClientID, const char* pReason, void *pUser);

View File

@@ -0,0 +1,9 @@
[Unit]
Description=ServerStatus-Client
After=network.target
[Service]
ExecStart=/usr/bin/python3 /usr/local/ServerStatus/clients/client-linux.py
ExecReload=/bin/kill -HUP $MAINPID
Restart=on-failure
[Install]
WantedBy=multi-user.target

View File

@@ -0,0 +1,9 @@
[Unit]
Description=ServerStatus-Server
After=network.target
[Service]
ExecStart=/usr/local/ServerStatus/server/sergate --config=/usr/local/ServerStatus/server/config.json --web-dir=/usr/local/ServerStatus/web
ExecReload=/bin/kill -HUP $MAINPID
Restart=on-failure
[Install]
WantedBy=multi-user.target

1041
status.sh Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -1,54 +1,71 @@
body { background: #222 url('../img/dark.png'); color: #fff; }
body { background: #212e36 url('../img/dark.png'); color: #dcdcdc; }
.navbar { min-height: 40px; }
.navbar-brand { color: #FFF !important; padding: 10px; font-size: 20px; }
.dropdown .dropdown-toggle { padding-bottom: 10px; padding-top: 10px; }
.dropdown-menu > li > a { color: #FFF !important; background-color: #222222 !important; }
.dropdown-menu > li > a:hover { color: #FFF !important; background: #000 !important; }
.dropdown-menu { background: #222 !important; background-color: #222222 !important; }
.navbar-inverse .navbar-inner { background-color:#1B1B1B; background-image:-moz-linear-gradient(top, #222222, #111111); background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#222222), to(#111111)); background-image:-webkit-linear-gradient(top, #222222, #111111); background-image:-o-linear-gradient(top, #222222, #111111); background-image:linear-gradient(to bottom, #222222, #111111); background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff222222', endColorstr='#ff111111', GradientType=0); border-color: #252525; }
.content { background: #222; padding: 20px; border-radius: 5px; border: 1px #000 solid; -webkit-box-shadow: 0 1px 10px rgba(0, 0, 0, .1); -moz-box-shadow: 0 1px 10px rgba(0, 0, 0, .1); box-shadow: 0 1px 10px rgba(0, 0, 0, .1); margin-bottom: 20px; }
.table { background: #000; margin-bottom: 0; border-collapse: collapse; border-radius: 3px; }
.navbar-inverse .navbar-inner { background-color:#1B1B1B; background-image:-moz-linear-gradient(top, #222222, #111111); background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#222222), to(#111111)); background-image:-webkit-linear-gradient(top, #222222, #111111); background-image:-o-linear-gradient(top, #222222, #111111); background-image:linear-gradient(to bottom, #212e36, #212e36); background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff222222', endColorstr='#ff111111', GradientType=0); border-color: #252525; }
.container { width: 1280px; }
.content { background: #212e36; padding: 20px; border-radius: 5px; border: 1px #212e36 solid; -webkit-box-shadow: 0 0px 0px rgba(0, 0, 0, 0); -moz-box-shadow: 0 0px 0px rgba(0, 0, 0, 0); box-shadow: 0 0px 0px rgba(0, 0, 0, 0); margin-bottom: 20px; }
.table { background: #363b40; margin-bottom: 0; border-collapse: collapse; border-radius: 3px; }
.table th { text-align: center; }
.table-striped tbody > tr.even > td, .table-striped tbody > tr.even > th { background-color: #2F2F2F; }
.table-striped tbody > tr.odd > td, .table-striped tbody > tr.odd > th { background-color: #000; }
.table-striped tbody > tr.even > td, .table-striped tbody > tr.even > th { background-color: #212e36; }
.table-striped tbody > tr.odd > td, .table-striped tbody > tr.odd > th { background-color: #212e36; }
.table td { text-align: center; border-color: #2F2F2F; }
.progress { margin-bottom: 0; background: #222; }
.progress { margin-bottom: 0; background: #363b40; }
.table-hover > tbody > tr:hover > td { background: #414141; }
tr.even.expandRow > :hover { background: #2F2F2F !important; }
tr.odd.expandRow > :hover { background: #000 !important; }
tr.even.expandRow > :hover { background: #212e36 !important; }
tr.odd.expandRow > :hover { background: #212e36 !important; }
.expandRow > td { padding: 0 !important; border-top: 0px !important; }
#cpu, #ram, #hdd, #network { min-width: 55px; max-width: 100px; }
#ping { min-width: 55px; max-width: 130px; }
#month_traffic { min-width: 85px; max-width: 95px;}
#network { min-width: 110px; }
#cpu, #ram, #hdd { min-width: 45px; max-width: 90px; }
#ping { max-width: 110px; }
@media only screen and (max-width: 992px) {
#location, tr td:nth-child(5) { display:none; visibility:hidden; }
@media only screen and (max-width: 1200px) {
#type, tr td:nth-child(4) { display:none; visibility:hidden; }
#location, tr td:nth-child(5) { display:none; visibility:hidden; }
#uptime, tr td:nth-child(6) { display:none; visibility:hidden; }
#ping, tr td:nth-child(13) { display:none; visibility:hidden; }
}
@media only screen and (max-width: 720px) {
#type, tr td:nth-child(4) { display:none; visibility:hidden; }
#location, tr td:nth-child(5) { display:none; visibility:hidden; }
#ping, tr td:nth-child(13) { display:none; visibility:hidden; }
body { font-size: 10px; }
.content { padding: 0; }
#type, tr td:nth-child(4) { display:none; visibility:hidden; }
#location, tr td:nth-child(5) { display:none; visibility:hidden; }
#uptime, tr td:nth-child(6) { display:none; visibility:hidden; }
#ping, tr td:nth-child(13) { display:none; visibility:hidden; }
}
@media only screen and (max-width: 600px) {
#type, tr td:nth-child(4) { display:none; visibility:hidden; }
#location, tr td:nth-child(5) { display:none; visibility:hidden; }
#uptime, tr td:nth-child(6) { display:none; visibility:hidden; }
#ping, tr td:nth-child(13) { display:none; visibility:hidden; }
@media only screen and (max-width: 620px) {
body { font-size: 10px; }
.content { padding: 0; }
#month_traffic, tr td:nth-child(2) { display:none; visibility:hidden; }
#type, tr td:nth-child(4) { display:none; visibility:hidden; }
#location, tr td:nth-child(5) { display:none; visibility:hidden; }
#uptime, tr td:nth-child(6) { display:none; visibility:hidden; }
#traffic, tr td:nth-child(9) { display:none; visibility:hidden; }
#ping, tr td:nth-child(13) { display:none; visibility:hidden; }
}
@media only screen and (max-width: 533px) {
#type, tr td:nth-child(4) { display:none; visibility:hidden; }
#location, tr td:nth-child(5) { display:none; visibility:hidden; }
#uptime, tr td:nth-child(6) { display:none; visibility:hidden; }
#network, tr td:nth-child(8) { display:none; visibility:hidden; }
#ping, tr td:nth-child(13) { display:none; visibility:hidden; }
body { font-size: 10px; }
.content { padding: 0; }
#month_traffic, tr td:nth-child(2) { display:none; visibility:hidden; }
#type, tr td:nth-child(4) { display:none; visibility:hidden; }
#location, tr td:nth-child(5) { display:none; visibility:hidden; }
#uptime, tr td:nth-child(6) { display:none; visibility:hidden; }
#traffic, tr td:nth-child(9) { display:none; visibility:hidden; }
#ping, tr td:nth-child(13) { display:none; visibility:hidden; }
}
@media only screen and (max-width: 450px) {
body { font-size: 10px; }
.content { padding: 0; }
#name, tr td:nth-child(3) { min-width: 55px; max-width: 85px; text-overflow: ellipsis; white-space: nowrap; overflow: hidden; }
#type, tr td:nth-child(4) { display:none; visibility:hidden; }
#location, tr td:nth-child(5) { display:none; visibility:hidden; }
#uptime, tr td:nth-child(6) { display:none; visibility:hidden; }
#network, tr td:nth-child(8) { display:none; visibility:hidden; }
#cpu, #ram, #hdd { min-width: 25px; max-width: 50px; }
#ping, tr td:nth-child(13) { display:none; visibility:hidden; }
}
body { font-size: 10px; }
.content { padding: 0; }
#month_traffic, tr td:nth-child(2) { display:none; visibility:hidden; }
#name, tr td:nth-child(3) { min-width: 55px; max-width: 85px; text-overflow: ellipsis; white-space: nowrap; overflow: hidden; }
#type, tr td:nth-child(4) { display:none; visibility:hidden; }
#location, tr td:nth-child(5) { display:none; visibility:hidden; }
#uptime, tr td:nth-child(6) { display:none; visibility:hidden; }
#traffic, tr td:nth-child(9) { display:none; visibility:hidden; }
#cpu, #ram, #hdd { min-width: 25px; max-width: 50px; }
#ping, tr td:nth-child(13) { display:none; visibility:hidden; }
}

View File

@@ -3,6 +3,7 @@ body { background: #ebebeb url('../img/light.png'); }
.navbar-brand { color: #fff; padding: 10px; font-size: 20px; }
.dropdown .dropdown-toggle { padding-bottom: 10px; padding-top: 10px; }
.navbar-inverse .navbar-brand { color: #fff; padding: 10px; font-size: 20px; }
.container { width: 1280px; }
.content { background: #ffffff; padding: 20px; border-radius: 5px; border: 1px #cecece solid; -webkit-box-shadow: 0 1px 10px rgba(0, 0, 0, .1); -moz-box-shadow: 0 1px 10px rgba(0, 0, 0, .1); box-shadow: 0 1px 10px rgba(0, 0, 0, .1); margin-bottom: 20px; }
.table { background: #ffffff; margin-bottom: 0; border-collapse: collapse; border-radius: 3px; }
.table th, .table td { text-align: center; }
@@ -14,38 +15,54 @@ body { background: #ebebeb url('../img/light.png'); }
tr.even.expandRow > :hover { background: #F9F9F9 !important; }
tr.odd.expandRow > :hover { background: #FFF !important; }
.expandRow > td { padding: 0 !important; border-top: 0px !important; }
#cpu, #ram, #hdd, #network { min-width: 55px; max-width: 100px; }
#ping { min-width: 55px; max-width: 130px; }
#month_traffic { min-width: 85px; max-width: 95px;}
#network { min-width: 110px; }
#cpu, #ram, #hdd { min-width: 45px; max-width: 90px; }
#ping { max-width: 110px; }
@media only screen and (max-width: 992px) {
#location, tr td:nth-child(5) { display:none; visibility:hidden; }
@media only screen and (max-width: 1200px) {
#type, tr td:nth-child(4) { display:none; visibility:hidden; }
#location, tr td:nth-child(5) { display:none; visibility:hidden; }
#uptime, tr td:nth-child(6) { display:none; visibility:hidden; }
#ping, tr td:nth-child(13) { display:none; visibility:hidden; }
}
@media only screen and (max-width: 720px) {
#type, tr td:nth-child(4) { display:none; visibility:hidden; }
#location, tr td:nth-child(5) { display:none; visibility:hidden; }
#ping, tr td:nth-child(13) { display:none; visibility:hidden; }
body { font-size: 10px; }
.content { padding: 0; }
#type, tr td:nth-child(4) { display:none; visibility:hidden; }
#location, tr td:nth-child(5) { display:none; visibility:hidden; }
#uptime, tr td:nth-child(6) { display:none; visibility:hidden; }
#ping, tr td:nth-child(13) { display:none; visibility:hidden; }
}
@media only screen and (max-width: 600px) {
#type, tr td:nth-child(4) { display:none; visibility:hidden; }
#location, tr td:nth-child(5) { display:none; visibility:hidden; }
#uptime, tr td:nth-child(6) { display:none; visibility:hidden; }
#ping, tr td:nth-child(13) { display:none; visibility:hidden; }
@media only screen and (max-width: 620px) {
body { font-size: 10px; }
.content { padding: 0; }
#month_traffic, tr td:nth-child(2) { display:none; visibility:hidden; }
#type, tr td:nth-child(4) { display:none; visibility:hidden; }
#location, tr td:nth-child(5) { display:none; visibility:hidden; }
#uptime, tr td:nth-child(6) { display:none; visibility:hidden; }
#traffic, tr td:nth-child(9) { display:none; visibility:hidden; }
#ping, tr td:nth-child(13) { display:none; visibility:hidden; }
}
@media only screen and (max-width: 533px) {
#type, tr td:nth-child(4) { display:none; visibility:hidden; }
#location, tr td:nth-child(5) { display:none; visibility:hidden; }
#uptime, tr td:nth-child(6) { display:none; visibility:hidden; }
#network, tr td:nth-child(8) { display:none; visibility:hidden; }
#ping, tr td:nth-child(13) { display:none; visibility:hidden; }
body { font-size: 10px; }
.content { padding: 0; }
#month_traffic, tr td:nth-child(2) { display:none; visibility:hidden; }
#type, tr td:nth-child(4) { display:none; visibility:hidden; }
#location, tr td:nth-child(5) { display:none; visibility:hidden; }
#uptime, tr td:nth-child(6) { display:none; visibility:hidden; }
#traffic, tr td:nth-child(9) { display:none; visibility:hidden; }
#ping, tr td:nth-child(13) { display:none; visibility:hidden; }
}
@media only screen and (max-width: 450px) {
body { font-size: 10px; }
.content { padding: 0; }
#name, tr td:nth-child(3) { min-width: 55px; max-width: 85px; text-overflow: ellipsis; white-space: nowrap; overflow: hidden; }
#type, tr td:nth-child(4) { display:none; visibility:hidden; }
#location, tr td:nth-child(5) { display:none; visibility:hidden; }
#uptime, tr td:nth-child(6) { display:none; visibility:hidden; }
#network, tr td:nth-child(8) { display:none; visibility:hidden; }
#cpu, #ram, #hdd { min-width: 25px; max-width: 50px; }
#ping, tr td:nth-child(13) { display:none; visibility:hidden; }
}
body { font-size: 10px; }
.content { padding: 0; }
#month_traffic, tr td:nth-child(2) { display:none; visibility:hidden; }
#name, tr td:nth-child(3) { min-width: 55px; max-width: 85px; text-overflow: ellipsis; white-space: nowrap; overflow: hidden; }
#type, tr td:nth-child(4) { display:none; visibility:hidden; }
#location, tr td:nth-child(5) { display:none; visibility:hidden; }
#uptime, tr td:nth-child(6) { display:none; visibility:hidden; }
#traffic, tr td:nth-child(9) { display:none; visibility:hidden; }
#cpu, #ram, #hdd { min-width: 25px; max-width: 50px; }
#ping, tr td:nth-child(13) { display:none; visibility:hidden; }
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 600 B

After

Width:  |  Height:  |  Size: 1.9 KiB

View File

@@ -1,13 +1,12 @@
<!DOCTYPE html>
<!--
json字段保持完整, 后期更新会向下兼容
可以自定义前端展示
json字段保持完整, 自行自定义前端展示
ლ(•̀ _ •́ ლ)
ლ(•̀ _ •́ ლ)ლ(•̀ _ •́ ლ)
ლ(•̀ _ •́ ლ)ლ(•̀ _ •́ ლ)ლ(•̀ _ •́ ლ)
ლ(•̀ _ •́ ლ)ლ(•̀ _ •́ ლ)
ლ(•̀ _ •́ ლ)
by:https://www.cpp.la
follow me, better solution for you. by:https://cpp.la
-->
<html>
<head>
@@ -19,8 +18,8 @@
<meta name="author" content="BotoX">
<link rel="stylesheet" href="css/bootstrap.min.css">
<link rel="stylesheet" href="css/bootstrap-theme.min.css">
<link rel="stylesheet" href="css/dark.css" title="dark">
<link rel="stylesheet" href="css/light.css" title="light">
<link rel="stylesheet" href="css/dark.css" title="dark">
<style>
body {
padding-top: 70px;
@@ -51,8 +50,8 @@
<li class="dropdown">
<a data-toggle="dropdown" class="dropdown-toggle" href="#">风格<b class="caret"></b></a>
<ul class="dropdown-menu">
<li><a href="#" onclick="setActiveStyleSheet('dark')">黑夜</a></li>
<li><a href="#" onclick="setActiveStyleSheet('light')">白天</a></li>
<li><a href="#" onclick="setActiveStyleSheet('dark', true)">黑夜</a></li>
<li><a href="#" onclick="setActiveStyleSheet('light', true)">白天</a></li>
</ul>
</li>
</ul>
@@ -76,19 +75,19 @@
<table class="table table-striped table-condensed table-hover">
<thead>
<tr>
<th id="status4" style="text-align: center;">协议</th>
<th id="ipstatus" style="text-align: center;">Flight</th>
<th id="name">节点</th>
<th id="type">虚拟化</th>
<th id="location">位置</th>
<th id="uptime">在线时间</th>
<th id="online_status" style="text-align: center;">🔗协议</th>
<th id="month_traffic" style="text-align: center;">📊月流量↓|↑</th>
<th id="name">📌节点</th>
<th id="type">🗂️虚拟化</th>
<th id="location">🌍位置</th>
<th id="uptime">⏱️在线</th>
<th id="load">负载</th>
<th id="network">网络 ↓|↑</th>
<th id="traffic">流量 ↓|↑</th>
<th id="cpu">处理器</th>
<th id="ram">内存</th>
<th id="hdd">硬盘</th>
<th id="ping">丢包率(CU|CT|CM)</th>
<th id="network">🚦网络↓|↑</th>
<th id="traffic">📋总流量↓|↑</th>
<th id="cpu">🎯核芯</th>
<th id="ram">⚡️内存</th>
<th id="hdd">💾硬盘</th>
<th id="ping">🌐CU|CT|CM</th>
</tr>
</thead>
<tbody id="servers">

File diff suppressed because one or more lines are too long

View File

@@ -1,4 +1,4 @@
// serverstatus.js
// serverstatus.js. big data boom today.
var error = 0;
var d = 0;
var server_status = new Array();
@@ -8,24 +8,9 @@ function timeSince(date) {
return "从未.";
var seconds = Math.floor((new Date() - date) / 1000);
var interval = Math.floor(seconds / 31536000);
if (interval > 1)
return interval + " 年前.";
interval = Math.floor(seconds / 2592000);
if (interval > 1)
return interval + " 月前.";
interval = Math.floor(seconds / 86400);
if (interval > 1)
return interval + " 日前.";
interval = Math.floor(seconds / 3600);
if (interval > 1)
return interval + " 小时前.";
interval = Math.floor(seconds / 60);
var interval = Math.floor(seconds / 60);
if (interval > 1)
return interval + " 分钟前.";
/*if(Math.floor(seconds) >= 5)
return Math.floor(seconds) + " seconds";*/
else
return "几秒前.";
}
@@ -35,24 +20,16 @@ function bytesToSize(bytes, precision, si)
var ret;
si = typeof si !== 'undefined' ? si : 0;
if(si != 0) {
var kilobyte = 1000;
var megabyte = kilobyte * 1000;
var megabyte = 1000 * 1000;
var gigabyte = megabyte * 1000;
var terabyte = gigabyte * 1000;
} else {
var kilobyte = 1024;
var megabyte = kilobyte * 1024;
var megabyte = 1024 * 1024;
var gigabyte = megabyte * 1024;
var terabyte = gigabyte * 1024;
}
if ((bytes >= 0) && (bytes < kilobyte)) {
return bytes + ' B';
} else if ((bytes >= kilobyte) && (bytes < megabyte)) {
ret = (bytes / kilobyte).toFixed(precision) + ' K';
} else if ((bytes >= megabyte) && (bytes < gigabyte)) {
if ((bytes >= megabyte) && (bytes < gigabyte)) {
ret = (bytes / megabyte).toFixed(precision) + ' M';
} else if ((bytes >= gigabyte) && (bytes < terabyte)) {
@@ -64,18 +41,19 @@ function bytesToSize(bytes, precision, si)
} else {
return bytes + ' B';
}
if(si != 0) {
return ret;
/*if(si != 0) {
return ret + 'B';
} else {
return ret + 'iB';
}
}*/
}
function uptime() {
$.getJSON("json/stats.json", function(result) {
$("#loading-notice").remove();
if(result.reload)
setTimeout(function() { location.reload(true) }, 1000);
setTimeout(function() { location.reload() }, 1000);
for (var i = 0, rlen=result.servers.length; i < rlen; i++) {
var TableRow = $("#servers tr#r" + i);
@@ -85,8 +63,8 @@ function uptime() {
if (!TableRow.length) {
$("#servers").append(
"<tr id=\"r" + i + "\" data-toggle=\"collapse\" data-target=\"#rt" + i + "\" class=\"accordion-toggle " + hack + "\">" +
"<td id=\"online4\"><div class=\"progress\"><div style=\"width: 100%;\" class=\"progress-bar progress-bar-warning\"><small>加载中</small></div></div></td>" +
"<td id=\"ip_status\"><div class=\"progress\"><div style=\"width: 100%;\" class=\"progress-bar progress-bar-warning\"><small>加载中</small></div></div></td>" +
"<td id=\"online_status\"><div class=\"progress\"><div style=\"width: 100%;\" class=\"progress-bar progress-bar-warning\"><small>加载中</small></div></div></td>" +
"<td id=\"month_traffic\"><div class=\"progress\"><div style=\"width: 100%;\" class=\"progress-bar progress-bar-warning\"><small>加载中</small></div></div></td>" +
"<td id=\"name\">加载中</td>" +
"<td id=\"type\">加载中</td>" +
"<td id=\"location\">加载中</td>" +
@@ -101,10 +79,10 @@ function uptime() {
"</tr>" +
"<tr class=\"expandRow " + hack + "\"><td colspan=\"16\"><div class=\"accordian-body collapse\" id=\"rt" + i + "\">" +
"<div id=\"expand_mem\">加载中</div>" +
"<div id=\"expand_swap\">加载中</div>" +
"<div id=\"expand_hdd\">加载中</div>" +
"<div id=\"expand_tupd\">加载中</div>" +
"<div id=\"expand_ping\">加载中</div>" +
"<div id=\"expand_lost\">加载中</div>" +
"<div id=\"expand_custom\">加载中</div>" +
"</div></td></tr>"
);
@@ -118,38 +96,19 @@ function uptime() {
server_status[i] = true;
}
// Online4
// online_status
if (result.servers[i].online4 && !result.servers[i].online6) {
TableRow.children["online4"].children[0].children[0].className = "progress-bar progress-bar-success";
TableRow.children["online4"].children[0].children[0].innerHTML = "<small>IPv4</small>";
TableRow.children["online_status"].children[0].children[0].className = "progress-bar progress-bar-success";
TableRow.children["online_status"].children[0].children[0].innerHTML = "<small>IPv4</small>";
} else if (result.servers[i].online4 && result.servers[i].online6) {
TableRow.children["online4"].children[0].children[0].className = "progress-bar progress-bar-success";
TableRow.children["online4"].children[0].children[0].innerHTML = "<small>双栈</small>";
TableRow.children["online_status"].children[0].children[0].className = "progress-bar progress-bar-success";
TableRow.children["online_status"].children[0].children[0].innerHTML = "<small>双栈</small>";
} else if (!result.servers[i].online4 && result.servers[i].online6) {
TableRow.children["online4"].children[0].children[0].className = "progress-bar progress-bar-success";
TableRow.children["online4"].children[0].children[0].innerHTML = "<small>IPv6</small>";
TableRow.children["online_status"].children[0].children[0].className = "progress-bar progress-bar-success";
TableRow.children["online_status"].children[0].children[0].innerHTML = "<small>IPv6</small>";
} else {
TableRow.children["online4"].children[0].children[0].className = "progress-bar progress-bar-danger";
TableRow.children["online4"].children[0].children[0].innerHTML = "<small>关闭</small>";
}
// Online6
//if (result.servers[i].online6) {
// TableRow.children["online6"].children[0].children[0].className = "progress-bar progress-bar-success";
// TableRow.children["online6"].children[0].children[0].innerHTML = "<small>开启</small>";
//} else {
// TableRow.children["online6"].children[0].children[0].className = "progress-bar progress-bar-danger";
// TableRow.children["online6"].children[0].children[0].innerHTML = "<small>关闭</small>";
//}
// Ipstatus
// mh361 or mh370, mourn mh370, 2014-03-08 01:20 lost from all over the world.
if (result.servers[i].ip_status) {
TableRow.children["ip_status"].children[0].children[0].className = "progress-bar progress-bar-success";
TableRow.children["ip_status"].children[0].children[0].innerHTML = "<small>MH361</small>";
} else {
TableRow.children["ip_status"].children[0].children[0].className = "progress-bar progress-bar-danger";
TableRow.children["ip_status"].children[0].children[0].innerHTML = "<small>MH370</small>";
TableRow.children["online_status"].children[0].children[0].className = "progress-bar progress-bar-danger";
TableRow.children["online_status"].children[0].children[0].innerHTML = "<small>关闭</small>";
}
// Name
@@ -166,6 +125,8 @@ function uptime() {
TableRow.children["load"].innerHTML = "";
TableRow.children["network"].innerHTML = "";
TableRow.children["traffic"].innerHTML = "";
TableRow.children["month_traffic"].children[0].children[0].className = "progress-bar progress-bar-warning";
TableRow.children["month_traffic"].children[0].children[0].innerHTML = "<small>关闭</small>";
TableRow.children["cpu"].children[0].children[0].className = "progress-bar progress-bar-danger";
TableRow.children["cpu"].children[0].children[0].style.width = "100%";
TableRow.children["cpu"].children[0].children[0].innerHTML = "<small>关闭</small>";
@@ -190,6 +151,22 @@ function uptime() {
server_status[i] = true;
}
// month traffic
var monthtraffic = "";
var trafficdiff_in = result.servers[i].network_in - result.servers[i].last_network_in;
var trafficdiff_out = result.servers[i].network_out - result.servers[i].last_network_out;
if(trafficdiff_in < 1024*1024*1024*1024)
monthtraffic += (trafficdiff_in/1024/1024/1024).toFixed(1) + "G";
else
monthtraffic += (trafficdiff_in/1024/1024/1024/1024).toFixed(1) + "T";
monthtraffic += " | "
if(trafficdiff_out < 1024*1024*1024*1024)
monthtraffic += (trafficdiff_out/1024/1024/1024).toFixed(1) + "G";
else
monthtraffic += (trafficdiff_out/1024/1024/1024/1024).toFixed(1) + "T";
TableRow.children["month_traffic"].children[0].children[0].className = "progress-bar progress-bar-success";
TableRow.children["month_traffic"].children[0].children[0].innerHTML = "<small>"+monthtraffic+"</small>";
// Uptime
TableRow.children["uptime"].innerHTML = result.servers[i].uptime;
@@ -202,44 +179,28 @@ function uptime() {
// Network
var netstr = "";
if(result.servers[i].network_rx < 1024)
netstr += result.servers[i].network_rx.toFixed(0) + "B";
else if(result.servers[i].network_rx < 1024*1024)
netstr += (result.servers[i].network_rx/1024).toFixed(0) + "K";
if(result.servers[i].network_rx < 1024*1024)
netstr += (result.servers[i].network_rx/1024).toFixed(1) + "K";
else
netstr += (result.servers[i].network_rx/1024/1024).toFixed(1) + "M";
netstr += " | "
if(result.servers[i].network_tx < 1024)
netstr += result.servers[i].network_tx.toFixed(0) + "B";
else if(result.servers[i].network_tx < 1024*1024)
netstr += (result.servers[i].network_tx/1024).toFixed(0) + "K";
if(result.servers[i].network_tx < 1024*1024)
netstr += (result.servers[i].network_tx/1024).toFixed(1) + "K";
else
netstr += (result.servers[i].network_tx/1024/1024).toFixed(1) + "M";
TableRow.children["network"].innerHTML = netstr;
//Traffic
var trafficstr = "";
if(result.servers[i].network_in < 1024)
trafficstr += result.servers[i].network_in.toFixed(0) + "B";
else if(result.servers[i].network_in < 1024*1024)
trafficstr += (result.servers[i].network_in/1024).toFixed(0) + "K";
else if(result.servers[i].network_in < 1024*1024*1024)
trafficstr += (result.servers[i].network_in/1024/1024).toFixed(1) + "M";
else if(result.servers[i].network_in < 1024*1024*1024*1024)
trafficstr += (result.servers[i].network_in/1024/1024/1024).toFixed(2) + "G";
if(result.servers[i].network_in < 1024*1024*1024*1024)
trafficstr += (result.servers[i].network_in/1024/1024/1024).toFixed(1) + "G";
else
trafficstr += (result.servers[i].network_in/1024/1024/1024/1024).toFixed(2) + "T";
trafficstr += (result.servers[i].network_in/1024/1024/1024/1024).toFixed(1) + "T";
trafficstr += " | "
if(result.servers[i].network_out < 1024)
trafficstr += result.servers[i].network_out.toFixed(0) + "B";
else if(result.servers[i].network_out < 1024*1024)
trafficstr += (result.servers[i].network_out/1024).toFixed(0) + "K";
else if(result.servers[i].network_out < 1024*1024*1024)
trafficstr += (result.servers[i].network_out/1024/1024).toFixed(1) + "M";
else if(result.servers[i].network_out < 1024*1024*1024*1024)
trafficstr += (result.servers[i].network_out/1024/1024/1024).toFixed(2) + "G";
if(result.servers[i].network_out < 1024*1024*1024*1024)
trafficstr += (result.servers[i].network_out/1024/1024/1024).toFixed(1) + "G";
else
trafficstr += (result.servers[i].network_out/1024/1024/1024/1024).toFixed(2) + "T";
trafficstr += (result.servers[i].network_out/1024/1024/1024/1024).toFixed(1) + "T";
TableRow.children["traffic"].innerHTML = trafficstr;
// CPU
@@ -262,9 +223,8 @@ function uptime() {
TableRow.children["memory"].children[0].children[0].className = "progress-bar progress-bar-success";
TableRow.children["memory"].children[0].children[0].style.width = Mem + "%";
TableRow.children["memory"].children[0].children[0].innerHTML = Mem + "%";
ExpandRow[0].children["expand_mem"].innerHTML = "内存: " + bytesToSize(result.servers[i].memory_used*1024, 2) + " / " + bytesToSize(result.servers[i].memory_total*1024, 2);
// Swap
ExpandRow[0].children["expand_swap"].innerHTML = "交换分区: " + bytesToSize(result.servers[i].swap_used*1024, 2) + " / " + bytesToSize(result.servers[i].swap_total*1024, 2);
// 内存|swap
ExpandRow[0].children["expand_mem"].innerHTML = "内存|虚存: " + bytesToSize(result.servers[i].memory_used*1024, 1) + " / " + bytesToSize(result.servers[i].memory_total*1024, 1) + " | " + bytesToSize(result.servers[i].swap_used*1024, 0) + " / " + bytesToSize(result.servers[i].swap_total*1024, 0);
// HDD
var HDD = ((result.servers[i].hdd_used/result.servers[i].hdd_total)*100.0).toFixed(0);
@@ -276,7 +236,20 @@ function uptime() {
TableRow.children["hdd"].children[0].children[0].className = "progress-bar progress-bar-success";
TableRow.children["hdd"].children[0].children[0].style.width = HDD + "%";
TableRow.children["hdd"].children[0].children[0].innerHTML = HDD + "%";
ExpandRow[0].children["expand_hdd"].innerHTML = "硬盘: " + bytesToSize(result.servers[i].hdd_used*1024*1024, 2) + " / " + bytesToSize(result.servers[i].hdd_total*1024*1024, 2);
// IO Speed for HDD.
// IO 过小的B字节单位没有意义
var io = "";
if(result.servers[i].io_read < 1024*1024)
io += parseInt(result.servers[i].io_read/1024) + "K";
else
io += parseInt(result.servers[i].io_read/1024/1024) + "M";
io += " / "
if(result.servers[i].io_write < 1024*1024)
io += parseInt(result.servers[i].io_write/1024) + "K";
else
io += parseInt(result.servers[i].io_write/1024/1024) + "M";
// Expand for HDD.
ExpandRow[0].children["expand_hdd"].innerHTML = "硬盘|读写: " + bytesToSize(result.servers[i].hdd_used*1024*1024, 2) + " / " + bytesToSize(result.servers[i].hdd_total*1024*1024, 2) + " | " + io;
// delay time
@@ -288,8 +261,12 @@ function uptime() {
var PING_10010 = result.servers[i].ping_10010.toFixed(0);
var PING_189 = result.servers[i].ping_189.toFixed(0);
var PING_10086 = result.servers[i].ping_10086.toFixed(0);
ExpandRow[0].children["expand_lost"].innerHTML = "丢包:联通/电信/移动: " + PING_10010 + "% / " + PING_189 + "% / " + PING_10086 + "%"
if (PING_10010 >= 20 || PING_189 >= 20 || PING_10086 >= 20)
TableRow.children["ping"].children[0].children[0].className = "progress-bar progress-bar-danger";
else if (PING_10010 >= 10 || PING_189 >= 10 || PING_10086 >= 10)
TableRow.children["ping"].children[0].children[0].className = "progress-bar progress-bar-warning";
else
TableRow.children["ping"].children[0].children[0].className = "progress-bar progress-bar-success";
TableRow.children["ping"].children[0].children[0].innerHTML = PING_10010 + "%💻" + PING_189 + "%💻" + PING_10086 + "%";
@@ -310,12 +287,10 @@ function uptime() {
$("#servers > tr.accordion-toggle").each(function(i) {
var TableRow = $("#servers tr#r" + i)[0];
var ExpandRow = $("#servers #rt" + i);
TableRow.children["online4"].children[0].children[0].className = "progress-bar progress-bar-error";
TableRow.children["online4"].children[0].children[0].innerHTML = "<small>错误</small>";
//TableRow.children["online6"].children[0].children[0].className = "progress-bar progress-bar-error";
//TableRow.children["online6"].children[0].children[0].innerHTML = "<small>错误</small>";
TableRow.children["ip_status"].children[0].children[0].className = "progress-bar progress-bar-error";
TableRow.children["ip_status"].children[0].children[0].innerHTML = "<small>错误</small>";
TableRow.children["online_status"].children[0].children[0].className = "progress-bar progress-bar-error";
TableRow.children["online_status"].children[0].children[0].innerHTML = "<small>错误</small>";
TableRow.children["month_traffic"].children[0].children[0].className = "progress-bar progress-bar-error";
TableRow.children["month_traffic"].children[0].children[0].innerHTML = "<small>错误</small>";
TableRow.children["uptime"].children[0].children[0].className = "progress-bar progress-bar-error";
TableRow.children["uptime"].children[0].children[0].innerHTML = "<small>错误</small>";
TableRow.children["load"].children[0].children[0].className = "progress-bar progress-bar-error";
@@ -360,14 +335,17 @@ setInterval(updateTime, 2000);
// styleswitcher.js
function setActiveStyleSheet(title) {
var i, a, main;
for(i=0; (a = document.getElementsByTagName("link")[i]); i++) {
if(a.getAttribute("rel").indexOf("style") != -1 && a.getAttribute("title")) {
a.disabled = true;
if(a.getAttribute("title") == title) a.disabled = false;
}
}
function setActiveStyleSheet(title, cookie=false) {
var i, a, main;
for(i=0; (a = document.getElementsByTagName("link")[i]); i++) {
if(a.getAttribute("rel").indexOf("style") != -1 && a.getAttribute("title")) {
a.disabled = true;
if(a.getAttribute("title") == title) a.disabled = false;
}
}
if (true==cookie) {
createCookie("style", title, 365);
}
}
function getActiveStyleSheet() {
@@ -379,15 +357,6 @@ function getActiveStyleSheet() {
return null;
}
function getPreferredStyleSheet() {
var i, a;
for(i=0; (a = document.getElementsByTagName("link")[i]); i++) {
if(a.getAttribute("rel").indexOf("style") != -1 && a.getAttribute("rel").indexOf("alt") == -1 && a.getAttribute("title"))
return a.getAttribute("title");
}
return null;
}
function createCookie(name,value,days) {
if (days) {
var date = new Date();
@@ -412,16 +381,19 @@ function readCookie(name) {
}
window.onload = function(e) {
var cookie = readCookie("style");
var title = cookie ? cookie : getPreferredStyleSheet();
setActiveStyleSheet(title);
var cookie = readCookie("style");
if (cookie && cookie != 'null' ) {
setActiveStyleSheet(cookie);
} else {
function handleChange (mediaQueryListEvent) {
if (mediaQueryListEvent.matches) {
setActiveStyleSheet('dark');
} else {
setActiveStyleSheet('light');
}
}
const mediaQueryListDark = window.matchMedia('(prefers-color-scheme: dark)');
setActiveStyleSheet(mediaQueryListDark.matches ? 'dark' : 'light');
mediaQueryListDark.addEventListener("change",handleChange);
}
}
window.onunload = function(e) {
var title = getActiveStyleSheet();
createCookie("style", title, 365);
}
var cookie = readCookie("style");
var title = cookie ? cookie : getPreferredStyleSheet();
setActiveStyleSheet(title);

View File

@@ -1,11 +1,8 @@
#!/usr/bin/env python
#!/usr/bin/env python3
# coding: utf-8
# Update by : https://github.com/cppla/ServerStatus
# 支持Python版本2.7 to 3.5; requirements.txt: requests, PrettyTable
# 时间: 20180828
'''
maybe better by youself
'''
# Update by : https://github.com/cppla/ServerStatus, Update date: 20211009
# 支持Python版本2.7 to 3.9; requirements.txt: requests, PrettyTable
# 主要是为了受到CC attack时候方便查看机器状态
import os
import sys
@@ -13,9 +10,9 @@ import requests
import time
from prettytable import PrettyTable
# todo: 程序在非gui环境下目前有闪屏的bug
scroll = True
clear = lambda: os.system('clear' if 'linux' in sys.platform else 'cls')
clear = lambda: os.system('clear' if 'linux' in sys.platform or 'darwin' in sys.platform else 'cls')
def sscmd(address):
while True:
@@ -29,42 +26,58 @@ def sscmd(address):
ss = PrettyTable(
[
"Flight",
"月流量 ↓|↑",
"节点名",
# "虚拟化",
"位置",
"在线时间",
"负载",
"网络",
"流量",
"网络 ↓|↑",
"流量 ↓|↑",
"处理器",
"内存",
"硬盘"
],
)
for i in jsonR["servers"]:
ss.add_row(
[
"%s" % 'MH361' if i["ip_status"] is True else 'MH370',
"%s" % i["name"],
# "%s" % i["type"],
"%s" % i["location"],
"%s" % i["uptime"],
"%s" % (i["load_1"]),
"%.2fM|%.2fM" % (float(i["network_rx"]) / 1000 / 1000, float(i["network_tx"]) / 1000 / 1000),
"%.2fG|%.2fG" % (
float(i["network_in"]) / 1024 / 1024 / 1024, float(i["network_out"]) / 1024 / 1024 / 1024),
"%d%%" % (i["cpu"]),
"%d%%" % (float(i["memory_used"]) / i["memory_total"] * 100),
"%d%%" % (float(i["hdd_used"]) / i["hdd_total"] * 100),
]
)
if i["online4"] is False and i["online6"] is False:
ss.add_row(
[
'0.00G',
"%s" % i["name"],
"%s" % i["location"],
'-',
'-',
'-',
'-',
'-',
'-',
'-',
]
)
else:
ss.add_row(
[
"%.2fG|%.2fG" % (float(i["last_network_in"]) / 1024 / 1024 / 1024, float(i["last_network_out"]) / 1024 / 1024 / 1024),
"%s" % i["name"],
# "%s" % i["type"],
"%s" % i["location"],
"%s" % i["uptime"],
"%s" % (i["load_1"]),
"%.2fM|%.2fM" % (float(i["network_rx"]) / 1000 / 1000, float(i["network_tx"]) / 1000 / 1000),
"%.2fG|%.2fG" % (
float(i["network_in"]) / 1024 / 1024 / 1024, float(i["network_out"]) / 1024 / 1024 / 1024),
"%d%%" % (i["cpu"]),
"%d%%" % (float(i["memory_used"]) / i["memory_total"] * 100),
"%d%%" % (float(i["hdd_used"]) / i["hdd_total"] * 100),
]
)
if scroll is True:
clear()
print(ss)
time.sleep(1)
if __name__ == '__main__':
default = 'https://tz.cloudcpp.com/json/stats.json'
ads = sys.argv[1] if len(sys.argv)==2 else default
ads = sys.argv[1] if len(sys.argv) == 2 else default
sscmd(ads)