mirror of
https://github.com//cppla/ServerStatus
synced 2026-08-09 22:03:59 +08:00
Compare commits
35
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d5e59453f1 | ||
|
|
d242c6cea1 | ||
|
|
d7614ab168 | ||
|
|
ff06df8263 | ||
|
|
9ee1516f72 | ||
|
|
7603ce37af | ||
|
|
5cfd533daf | ||
|
|
9077f1058a | ||
|
|
e34ed05901 | ||
|
|
4ab545f646 | ||
|
|
a6b4248967 | ||
|
|
8ad927d88d | ||
|
|
4b1ec57c6d | ||
|
|
979a9b5d87 | ||
|
|
52d62afa59 | ||
|
|
806b60bd6b | ||
|
|
d5af5445df | ||
|
|
c77e00476c | ||
|
|
b551998eb8 | ||
|
|
1c606cc79e | ||
|
|
d602791b11 | ||
|
|
a695ef8b3a | ||
|
|
9f60b7962b | ||
|
|
34b1bca5b1 | ||
|
|
25917f0883 | ||
|
|
333bc29c88 | ||
|
|
c116067c39 | ||
|
|
14db7ec943 | ||
|
|
af8244f1d7 | ||
|
|
1004c9a6bd | ||
|
|
7f78af03f0 | ||
|
|
02bbdb18de | ||
|
|
6d813f932d | ||
|
|
19d6a5ea8b | ||
|
|
35de279e89 |
+1
-1
@@ -9,7 +9,7 @@ COPY . .
|
|||||||
|
|
||||||
WORKDIR /server
|
WORKDIR /server
|
||||||
|
|
||||||
RUN make
|
RUN make -j
|
||||||
RUN pwd && ls -a
|
RUN pwd && ls -a
|
||||||
|
|
||||||
# glibc env run
|
# glibc env run
|
||||||
|
|||||||
@@ -6,13 +6,13 @@
|
|||||||
[](https://github.com/cppla/ServerStatus)
|
[](https://github.com/cppla/ServerStatus)
|
||||||
[](https://github.com/cppla/ServerStatus)
|
[](https://github.com/cppla/ServerStatus)
|
||||||
[](https://github.com/cppla/ServerStatus)
|
[](https://github.com/cppla/ServerStatus)
|
||||||
[](https://github.com/cppla/ServerStatus)
|
[](https://github.com/cppla/ServerStatus)
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
`Watchdog🐶已经加入,触发式告警。 interval只是为了防止频繁收到报警信息造成骚扰,并不是探测间隔。`
|
`Watchdog🐶已经加入,触发式告警。 interval只是为了防止频繁收到报警信息造成骚扰,并不是探测间隔。`
|
||||||
|
|
||||||
# 目录介绍:
|
# 目录:
|
||||||
|
|
||||||
* clients 客户端文件
|
* clients 客户端文件
|
||||||
* server 服务端文件
|
* server 服务端文件
|
||||||
@@ -21,7 +21,7 @@
|
|||||||
* server/config.json 探针配置文件
|
* server/config.json 探针配置文件
|
||||||
* web/json 探针月流量
|
* web/json 探针月流量
|
||||||
|
|
||||||
# 自动部署:
|
# 部署:
|
||||||
|
|
||||||
【服务端】:
|
【服务端】:
|
||||||
```bash
|
```bash
|
||||||
@@ -31,7 +31,7 @@
|
|||||||
wget --no-check-certificate -qO ~/serverstatus-config.json https://raw.githubusercontent.com/cppla/ServerStatus/master/server/config.json && mkdir ~/serverstatus-monthtraffic
|
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
|
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
|
||||||
|
|
||||||
`Docker-compose`: docker-compose up -d
|
`Docker-compose(推荐)`: docker-compose up -d
|
||||||
```
|
```
|
||||||
|
|
||||||
【客户端】:
|
【客户端】:
|
||||||
@@ -42,6 +42,15 @@ eg:
|
|||||||
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 &
|
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 &
|
||||||
```
|
```
|
||||||
|
|
||||||
|
# 主题:
|
||||||
|
|
||||||
|
* layui:https://github.com/zeyudada/StatusServerLayui ,预览:https://sslt.8zyw.cn
|
||||||
|
<img src=https://dl.cpp.la/Archive/serverstatus_layui.png width=200 height=100 />
|
||||||
|
|
||||||
|
* light:https://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 />
|
||||||
|
|
||||||
|
|
||||||
# 手动安装教程:
|
# 手动安装教程:
|
||||||
|
|
||||||
**【服务端配置】**
|
**【服务端配置】**
|
||||||
@@ -60,16 +69,17 @@ cd ServerStatus/server && make
|
|||||||
```diff
|
```diff
|
||||||
! watchdog rule 可以为任何已知字段的表达式。
|
! watchdog rule 可以为任何已知字段的表达式。
|
||||||
! watchdog interval 最小通知间隔。
|
! watchdog interval 最小通知间隔。
|
||||||
! watchdog callback 可自定义为Get方法的URL,告警内容将拼接其后并发起回调。
|
! 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 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 Server酱: https://sctapi.ftqq.com/你自己的密钥.send?title=ServerStatus&desp=
|
||||||
! watchdog callback PushDeer: https://api2.pushdeer.com/message/push?pushkey=你自己的密钥&text=
|
! watchdog callback PushDeer: https://api2.pushdeer.com/message/push?pushkey=你自己的密钥&text=
|
||||||
|
! watchdog callback BasicAuth: https://用户名:密码@你自己的域名/api/push?message=
|
||||||
```
|
```
|
||||||
|
|
||||||
```
|
```
|
||||||
{
|
{
|
||||||
"servers":
|
"servers":
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
"username": "s01",
|
"username": "s01",
|
||||||
@@ -89,6 +99,30 @@ cd ServerStatus/server && make
|
|||||||
"interval": 600,
|
"interval": 600,
|
||||||
"callback": "https://yourSMSurl"
|
"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": "你可以组合任何已知字段的表达式",
|
"name": "你可以组合任何已知字段的表达式",
|
||||||
"rule": "(hdd_used/hdd_total)*100>95",
|
"rule": "(hdd_used/hdd_total)*100>95",
|
||||||
@@ -132,7 +166,7 @@ web-dir参数为上一步设置的网站根目录,务必修改成自己网站
|
|||||||
服务器和客户端自行加入开机启动,或进程守护,或后台方式运行。 例如: nohup python3 client-linux.py &
|
服务器和客户端自行加入开机启动,或进程守护,或后台方式运行。 例如: nohup python3 client-linux.py &
|
||||||
|
|
||||||
`extra scene (run web/ssview.py)`
|
`extra scene (run web/ssview.py)`
|
||||||

|

|
||||||
|
|
||||||
|
|
||||||
# Make Better
|
# Make Better
|
||||||
|
|||||||
+10
-9
@@ -155,17 +155,18 @@ def _ping_thread(host, mark, port):
|
|||||||
lostPacket = 0
|
lostPacket = 0
|
||||||
packet_queue = Queue(maxsize=PING_PACKET_HISTORY_LEN)
|
packet_queue = Queue(maxsize=PING_PACKET_HISTORY_LEN)
|
||||||
|
|
||||||
IP = host
|
while True:
|
||||||
if host.count(':') < 1: # if not plain ipv6 address, means ipv4 address or hostname
|
# flush dns , every time.
|
||||||
try:
|
IP = host
|
||||||
if PROBE_PROTOCOL_PREFER == 'ipv4':
|
if host.count(':') < 1: # if not plain ipv6 address, means ipv4 address or hostname
|
||||||
IP = socket.getaddrinfo(host, None, socket.AF_INET)[0][4][0]
|
try:
|
||||||
else:
|
if PROBE_PROTOCOL_PREFER == 'ipv4':
|
||||||
IP = socket.getaddrinfo(host, None, socket.AF_INET6)[0][4][0]
|
IP = socket.getaddrinfo(host, None, socket.AF_INET)[0][4][0]
|
||||||
except Exception:
|
else:
|
||||||
|
IP = socket.getaddrinfo(host, None, socket.AF_INET6)[0][4][0]
|
||||||
|
except Exception:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
while True:
|
|
||||||
if packet_queue.full():
|
if packet_queue.full():
|
||||||
if packet_queue.get() == 0:
|
if packet_queue.get() == 0:
|
||||||
lostPacket -= 1
|
lostPacket -= 1
|
||||||
|
|||||||
+78
-58
@@ -46,18 +46,22 @@ def get_swap():
|
|||||||
return int(Mem.total/1024.0), int(Mem.used/1024.0)
|
return int(Mem.total/1024.0), int(Mem.used/1024.0)
|
||||||
|
|
||||||
def get_hdd():
|
def get_hdd():
|
||||||
valid_fs = [ "ext4", "ext3", "ext2", "reiserfs", "jfs", "btrfs", "fuseblk", "zfs", "simfs", "ntfs", "fat32", "exfat", "xfs" ]
|
if "darwin" in sys.platform:
|
||||||
disks = dict()
|
return int(psutil.disk_usage("/").total/1024.0/1024.0), int((psutil.disk_usage("/").total-psutil.disk_usage("/").free)/1024.0/1024.0)
|
||||||
size = 0
|
else:
|
||||||
used = 0
|
valid_fs = ["ext4", "ext3", "ext2", "reiserfs", "jfs", "btrfs", "fuseblk", "zfs", "simfs", "ntfs", "fat32",
|
||||||
for disk in psutil.disk_partitions():
|
"exfat", "xfs"]
|
||||||
if not disk.device in disks and disk.fstype.lower() in valid_fs:
|
disks = dict()
|
||||||
disks[disk.device] = disk.mountpoint
|
size = 0
|
||||||
for disk in disks.values():
|
used = 0
|
||||||
usage = psutil.disk_usage(disk)
|
for disk in psutil.disk_partitions():
|
||||||
size += usage.total
|
if not disk.device in disks and disk.fstype.lower() in valid_fs:
|
||||||
used += usage.used
|
disks[disk.device] = disk.mountpoint
|
||||||
return int(size/1024.0/1024.0), int(used/1024.0/1024.0)
|
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():
|
def get_cpu():
|
||||||
return psutil.cpu_percent(interval=INTERVAL)
|
return psutil.cpu_percent(interval=INTERVAL)
|
||||||
@@ -88,13 +92,23 @@ def tupd():
|
|||||||
u = int(os.popen('ss -u|wc -l').read()[:-1])-1
|
u = int(os.popen('ss -u|wc -l').read()[:-1])-1
|
||||||
p = int(os.popen('ps -ef|wc -l').read()[:-1])-2
|
p = int(os.popen('ps -ef|wc -l').read()[:-1])-2
|
||||||
d = int(os.popen('ps -eLf|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:
|
elif sys.platform.startswith("win") is True:
|
||||||
t = int(os.popen('netstat -an|find "TCP" /c').read()[:-1])-1
|
t = int(os.popen('netstat -an|find "TCP" /c').read()[:-1])-1
|
||||||
u = int(os.popen('netstat -an|find "UDP" /c').read()[:-1])-1
|
u = int(os.popen('netstat -an|find "UDP" /c').read()[:-1])-1
|
||||||
p = len(psutil.pids())
|
p = len(psutil.pids())
|
||||||
d = 0
|
# if you find cpu is high, please set d=0
|
||||||
# cpu is high, default: 0
|
d = sum([psutil.Process(k).num_threads() for k in psutil.pids()])
|
||||||
# d = sum([psutil.Process(k).num_threads() for k in [x for x in psutil.pids()]])
|
|
||||||
else:
|
else:
|
||||||
t,u,p,d = 0,0,0,0
|
t,u,p,d = 0,0,0,0
|
||||||
return t,u,p,d
|
return t,u,p,d
|
||||||
@@ -139,17 +153,18 @@ def _ping_thread(host, mark, port):
|
|||||||
lostPacket = 0
|
lostPacket = 0
|
||||||
packet_queue = Queue(maxsize=PING_PACKET_HISTORY_LEN)
|
packet_queue = Queue(maxsize=PING_PACKET_HISTORY_LEN)
|
||||||
|
|
||||||
IP = host
|
while True:
|
||||||
if host.count(':') < 1: # if not plain ipv6 address, means ipv4 address or hostname
|
# flush dns, every time.
|
||||||
try:
|
IP = host
|
||||||
if PROBE_PROTOCOL_PREFER == 'ipv4':
|
if host.count(':') < 1: # if not plain ipv6 address, means ipv4 address or hostname
|
||||||
IP = socket.getaddrinfo(host, None, socket.AF_INET)[0][4][0]
|
try:
|
||||||
else:
|
if PROBE_PROTOCOL_PREFER == 'ipv4':
|
||||||
IP = socket.getaddrinfo(host, None, socket.AF_INET6)[0][4][0]
|
IP = socket.getaddrinfo(host, None, socket.AF_INET)[0][4][0]
|
||||||
except Exception:
|
else:
|
||||||
|
IP = socket.getaddrinfo(host, None, socket.AF_INET6)[0][4][0]
|
||||||
|
except Exception:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
while True:
|
|
||||||
if packet_queue.full():
|
if packet_queue.full():
|
||||||
if packet_queue.get() == 0:
|
if packet_queue.get() == 0:
|
||||||
lostPacket -= 1
|
lostPacket -= 1
|
||||||
@@ -205,44 +220,49 @@ def _disk_io():
|
|||||||
比如我这里是机械硬盘,大量做随机小文件读写,那么很低的读写也就能造成硬盘长时间的等待。
|
比如我这里是机械硬盘,大量做随机小文件读写,那么很低的读写也就能造成硬盘长时间的等待。
|
||||||
如果这里做连续性IO,那么普通机械硬盘写入到100Mb/s,那么也能造成硬盘长时间的等待。
|
如果这里做连续性IO,那么普通机械硬盘写入到100Mb/s,那么也能造成硬盘长时间的等待。
|
||||||
磁盘读写有误差:4k,8k ,https://stackoverflow.com/questions/34413926/psutil-vs-dd-monitoring-disk-i-o
|
磁盘读写有误差:4k,8k ,https://stackoverflow.com/questions/34413926/psutil-vs-dd-monitoring-disk-i-o
|
||||||
|
macos/win,暂不处理。
|
||||||
"""
|
"""
|
||||||
while True:
|
if "darwin" in sys.platform or "win" in sys.platform:
|
||||||
# first get a list of all processes and disk io counters
|
diskIO["read"] = 0
|
||||||
procs = [p for p in psutil.process_iter()]
|
diskIO["write"] = 0
|
||||||
for p in procs[:]:
|
else:
|
||||||
try:
|
while True:
|
||||||
p._before = p.io_counters()
|
# first get a list of all processes and disk io counters
|
||||||
except psutil.Error:
|
procs = [p for p in psutil.process_iter()]
|
||||||
procs.remove(p)
|
for p in procs[:]:
|
||||||
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:
|
try:
|
||||||
p._after = p.io_counters()
|
p._before = p.io_counters()
|
||||||
p._cmdline = ' '.join(p.cmdline())
|
except psutil.Error:
|
||||||
if not p._cmdline:
|
|
||||||
p._cmdline = p.name()
|
|
||||||
p._username = p.username()
|
|
||||||
except (psutil.NoSuchProcess, psutil.ZombieProcess):
|
|
||||||
procs.remove(p)
|
procs.remove(p)
|
||||||
disks_after = psutil.disk_io_counters()
|
continue
|
||||||
|
disks_before = psutil.disk_io_counters()
|
||||||
|
|
||||||
# finally calculate results by comparing data before and
|
# sleep some time, only when INTERVAL==1 , io read/write per_sec.
|
||||||
# after the interval
|
# when INTERVAL > 1, io read/write per_INTERVAL
|
||||||
for p in procs:
|
time.sleep(INTERVAL)
|
||||||
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
|
# then retrieve the same info again
|
||||||
diskIO["write"] = disks_after.write_bytes - disks_before.write_bytes
|
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():
|
def get_realtime_data():
|
||||||
'''
|
'''
|
||||||
@@ -344,7 +364,7 @@ if __name__ == '__main__':
|
|||||||
CPU = get_cpu()
|
CPU = get_cpu()
|
||||||
NET_IN, NET_OUT = liuliang()
|
NET_IN, NET_OUT = liuliang()
|
||||||
Uptime = get_uptime()
|
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()
|
MemoryTotal, MemoryUsed = get_memory()
|
||||||
SwapTotal, SwapUsed = get_swap()
|
SwapTotal, SwapUsed = get_swap()
|
||||||
HDDTotal, HDDUsed = get_hdd()
|
HDDTotal, HDDUsed = get_hdd()
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ version: "3"
|
|||||||
services:
|
services:
|
||||||
serverstatus:
|
serverstatus:
|
||||||
build:
|
build:
|
||||||
context: .
|
context: ..
|
||||||
dockerfile: Dockerfile
|
dockerfile: Dockerfile
|
||||||
image: serverstatus_server
|
image: serverstatus_server
|
||||||
container_name: serverstatus
|
container_name: serverstatus
|
||||||
@@ -11,14 +11,14 @@ services:
|
|||||||
serverstatus-network:
|
serverstatus-network:
|
||||||
ipv4_address: 172.23.0.2
|
ipv4_address: 172.23.0.2
|
||||||
volumes:
|
volumes:
|
||||||
- ./server/config.json:/ServerStatus/server/config.json
|
- ../server/config.json:/ServerStatus/server/config.json
|
||||||
- ./web/json:/usr/share/nginx/html/json
|
- ../web/json:/usr/share/nginx/html/json
|
||||||
ports:
|
ports:
|
||||||
- 35601:35601
|
- 35601:35601
|
||||||
- 8080:80
|
- 8080:80
|
||||||
bot:
|
bot:
|
||||||
build:
|
build:
|
||||||
context: ./plugin
|
context: .
|
||||||
dockerfile: Dockerfile-telegram
|
dockerfile: Dockerfile-telegram
|
||||||
image: serverstatus_bot
|
image: serverstatus_bot
|
||||||
container_name: bot4sss
|
container_name: bot4sss
|
||||||
+18
-6
@@ -22,7 +22,7 @@
|
|||||||
"disabled": true,
|
"disabled": true,
|
||||||
"username": "s03",
|
"username": "s03",
|
||||||
"name": "node3",
|
"name": "node3",
|
||||||
"type": "Nothing",
|
"type": "hyper",
|
||||||
"host": "host3",
|
"host": "host3",
|
||||||
"location": "🇫🇷",
|
"location": "🇫🇷",
|
||||||
"password": "USER_DEFAULT_PASSWORD",
|
"password": "USER_DEFAULT_PASSWORD",
|
||||||
@@ -41,26 +41,38 @@
|
|||||||
"watchdog": [
|
"watchdog": [
|
||||||
{
|
{
|
||||||
"name": "cpu high warning",
|
"name": "cpu high warning",
|
||||||
"rule": "cpu>98",
|
"rule": "cpu>90&load_1>3",
|
||||||
"interval": 600,
|
"interval": 600,
|
||||||
"callback": "https://yourSMSurl"
|
"callback": "https://yourSMSurl"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "memory high warning",
|
"name": "memory high warning",
|
||||||
"rule": "(memory_used/memory_total)*100>90",
|
"rule": "(memory_used/memory_total)*100>90",
|
||||||
"interval": 600,
|
"interval": 300,
|
||||||
"callback": "https://yourSMSurl"
|
"callback": "https://yourSMSurl"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "offline warning",
|
"name": "offline warning",
|
||||||
"rule": "online4=0&online6=0",
|
"rule": "online4=0&online6=0",
|
||||||
"interval": 300,
|
"interval": 600,
|
||||||
"callback": "https://yourSMSurl"
|
"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",
|
"name": "you can parse an expression combining any known field",
|
||||||
"rule": "load_5>10",
|
"rule": "load_5>3",
|
||||||
"interval": 1800,
|
"interval": 900,
|
||||||
"callback": "https://yourSMSurl"
|
"callback": "https://yourSMSurl"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|||||||
+11
-9
@@ -258,7 +258,7 @@ int CMain::HandleMessage(int ClientNetID, char *pMessage)
|
|||||||
|
|
||||||
|
|
||||||
void CMain::WatchdogMessage(int ClientNetID, double load_1, double load_5, double load_15, double ping_10010, double ping_189, double ping_10086,
|
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, double udp, double process, double thread,
|
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 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 swap_total, double swap_used, double hdd_total, double hdd_used, double io_read, double io_write, double cpu,
|
||||||
double online4, double online6)
|
double online4, double online6)
|
||||||
@@ -281,10 +281,10 @@ void CMain::WatchdogMessage(int ClientNetID, double load_1, double load_5, doubl
|
|||||||
symbol_table.add_variable("time_10010",time_10010);
|
symbol_table.add_variable("time_10010",time_10010);
|
||||||
symbol_table.add_variable("time_189",time_189);
|
symbol_table.add_variable("time_189",time_189);
|
||||||
symbol_table.add_variable("time_10086",time_10086);
|
symbol_table.add_variable("time_10086",time_10086);
|
||||||
symbol_table.add_variable("tcp",tcp);
|
symbol_table.add_variable("tcp_count",tcp_count);
|
||||||
symbol_table.add_variable("udp",udp);
|
symbol_table.add_variable("udp_count",udp_count);
|
||||||
symbol_table.add_variable("process",process);
|
symbol_table.add_variable("process_count",process_count);
|
||||||
symbol_table.add_variable("thread",thread);
|
symbol_table.add_variable("thread_count",thread_count);
|
||||||
symbol_table.add_variable("network_rx",network_rx);
|
symbol_table.add_variable("network_rx",network_rx);
|
||||||
symbol_table.add_variable("network_tx",network_tx);
|
symbol_table.add_variable("network_tx",network_tx);
|
||||||
symbol_table.add_variable("network_in",network_in);
|
symbol_table.add_variable("network_in",network_in);
|
||||||
@@ -314,7 +314,6 @@ void CMain::WatchdogMessage(int ClientNetID, double load_1, double load_5, doubl
|
|||||||
time_t currentStamp = (long long)time(/*ago*/0);
|
time_t currentStamp = (long long)time(/*ago*/0);
|
||||||
if ((currentStamp-Client(ClientID)->m_AlarmLastTime) > Watchdog(ID)->m_aInterval)
|
if ((currentStamp-Client(ClientID)->m_AlarmLastTime) > Watchdog(ID)->m_aInterval)
|
||||||
{
|
{
|
||||||
//todo 这里需要换成线程
|
|
||||||
Client(ClientID)->m_AlarmLastTime = currentStamp;
|
Client(ClientID)->m_AlarmLastTime = currentStamp;
|
||||||
CURL *curl;
|
CURL *curl;
|
||||||
CURLcode res;
|
CURLcode res;
|
||||||
@@ -326,11 +325,10 @@ void CMain::WatchdogMessage(int ClientNetID, double load_1, double load_5, doubl
|
|||||||
char standardTime[32]= { 0 };
|
char standardTime[32]= { 0 };
|
||||||
strftime(standardTime, sizeof(standardTime), "%Y-%m-%d %H:%M:%S",localtime(¤tStamp));
|
strftime(standardTime, sizeof(standardTime), "%Y-%m-%d %H:%M:%S",localtime(¤tStamp));
|
||||||
|
|
||||||
//url encode
|
//url encode, Rules conflict with url special characters,eg:&, del rules, by https://cpp.la, 2023-10-09
|
||||||
char encodeBuffer[2048] = { 0 };
|
char encodeBuffer[2048] = { 0 };
|
||||||
sprintf(encodeBuffer, " \n\n【告警名称】 %s \n\n【告警规则】 %s \n\n【告警时间】 %s \n\n ---------------- \n\n【用户名】 %s \n\n【节点名】 %s \n\n【虚拟化】 %s \n\n【主机名】 %s \n\n【位 置】 %s",
|
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,
|
Watchdog(ID)->m_aName,
|
||||||
Watchdog(ID)->m_aRule,
|
|
||||||
standardTime,
|
standardTime,
|
||||||
Client(ClientID)->m_aUsername,
|
Client(ClientID)->m_aUsername,
|
||||||
Client(ClientID)->m_aName,
|
Client(ClientID)->m_aName,
|
||||||
@@ -344,7 +342,11 @@ void CMain::WatchdogMessage(int ClientNetID, double load_1, double load_5, doubl
|
|||||||
sprintf(urlBuffer, "%s%s",Watchdog(ID)->m_aCallback, encodeUrl);
|
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_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_CONNECTTIMEOUT, 3L);
|
||||||
curl_easy_setopt(curl, CURLOPT_TIMEOUT, 6L);
|
curl_easy_setopt(curl, CURLOPT_TIMEOUT, 6L);
|
||||||
res = curl_easy_perform(curl);
|
res = curl_easy_perform(curl);
|
||||||
|
|||||||
+1
-1
@@ -110,7 +110,7 @@ public:
|
|||||||
CWatchDog *Watchdog(int ruleID) { return &m_aCWatchDogs[ruleID]; }
|
CWatchDog *Watchdog(int ruleID) { return &m_aCWatchDogs[ruleID]; }
|
||||||
void WatchdogMessage(int ClientNetID,
|
void WatchdogMessage(int ClientNetID,
|
||||||
double load_1, double load_5, double load_15, double ping_10010, double ping_189, double ping_10086,
|
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, double udp, double process, double thread,
|
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 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 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);
|
double hdd_used, double io_read, double io_write, double cpu,double online4, double online6);
|
||||||
|
|||||||
Vendored
+1
-1
File diff suppressed because one or more lines are too long
+2
-2
@@ -18,9 +18,9 @@ tr.even.expandRow > :hover { background: #212e36 !important; }
|
|||||||
tr.odd.expandRow > :hover { background: #212e36 !important; }
|
tr.odd.expandRow > :hover { background: #212e36 !important; }
|
||||||
.expandRow > td { padding: 0 !important; border-top: 0px !important; }
|
.expandRow > td { padding: 0 !important; border-top: 0px !important; }
|
||||||
#month_traffic { min-width: 85px; max-width: 95px;}
|
#month_traffic { min-width: 85px; max-width: 95px;}
|
||||||
#network { min-width: 115px; }
|
#network { min-width: 110px; }
|
||||||
#cpu, #ram, #hdd { min-width: 45px; max-width: 90px; }
|
#cpu, #ram, #hdd { min-width: 45px; max-width: 90px; }
|
||||||
#ping { max-width: 95px; }
|
#ping { max-width: 110px; }
|
||||||
|
|
||||||
@media only screen and (max-width: 1200px) {
|
@media only screen and (max-width: 1200px) {
|
||||||
#type, tr td:nth-child(4) { display:none; visibility:hidden; }
|
#type, tr td:nth-child(4) { display:none; visibility:hidden; }
|
||||||
|
|||||||
+3
-2
@@ -3,6 +3,7 @@ body { background: #ebebeb url('../img/light.png'); }
|
|||||||
.navbar-brand { color: #fff; padding: 10px; font-size: 20px; }
|
.navbar-brand { color: #fff; padding: 10px; font-size: 20px; }
|
||||||
.dropdown .dropdown-toggle { padding-bottom: 10px; padding-top: 10px; }
|
.dropdown .dropdown-toggle { padding-bottom: 10px; padding-top: 10px; }
|
||||||
.navbar-inverse .navbar-brand { color: #fff; padding: 10px; font-size: 20px; }
|
.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; }
|
.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 { background: #ffffff; margin-bottom: 0; border-collapse: collapse; border-radius: 3px; }
|
||||||
.table th, .table td { text-align: center; }
|
.table th, .table td { text-align: center; }
|
||||||
@@ -15,9 +16,9 @@ tr.even.expandRow > :hover { background: #F9F9F9 !important; }
|
|||||||
tr.odd.expandRow > :hover { background: #FFF !important; }
|
tr.odd.expandRow > :hover { background: #FFF !important; }
|
||||||
.expandRow > td { padding: 0 !important; border-top: 0px !important; }
|
.expandRow > td { padding: 0 !important; border-top: 0px !important; }
|
||||||
#month_traffic { min-width: 85px; max-width: 95px;}
|
#month_traffic { min-width: 85px; max-width: 95px;}
|
||||||
#network { min-width: 115px; }
|
#network { min-width: 110px; }
|
||||||
#cpu, #ram, #hdd { min-width: 45px; max-width: 90px; }
|
#cpu, #ram, #hdd { min-width: 45px; max-width: 90px; }
|
||||||
#ping { max-width: 95px; }
|
#ping { max-width: 110px; }
|
||||||
|
|
||||||
@media only screen and (max-width: 1200px) {
|
@media only screen and (max-width: 1200px) {
|
||||||
#type, tr td:nth-child(4) { display:none; visibility:hidden; }
|
#type, tr td:nth-child(4) { display:none; visibility:hidden; }
|
||||||
|
|||||||
Vendored
+2
-2
File diff suppressed because one or more lines are too long
@@ -79,10 +79,10 @@ function uptime() {
|
|||||||
"</tr>" +
|
"</tr>" +
|
||||||
"<tr class=\"expandRow " + hack + "\"><td colspan=\"16\"><div class=\"accordian-body collapse\" id=\"rt" + i + "\">" +
|
"<tr class=\"expandRow " + hack + "\"><td colspan=\"16\"><div class=\"accordian-body collapse\" id=\"rt" + i + "\">" +
|
||||||
"<div id=\"expand_mem\">加载中</div>" +
|
"<div id=\"expand_mem\">加载中</div>" +
|
||||||
"<div id=\"expand_swap\">加载中</div>" +
|
|
||||||
"<div id=\"expand_hdd\">加载中</div>" +
|
"<div id=\"expand_hdd\">加载中</div>" +
|
||||||
"<div id=\"expand_tupd\">加载中</div>" +
|
"<div id=\"expand_tupd\">加载中</div>" +
|
||||||
"<div id=\"expand_ping\">加载中</div>" +
|
"<div id=\"expand_ping\">加载中</div>" +
|
||||||
|
"<div id=\"expand_lost\">加载中</div>" +
|
||||||
"<div id=\"expand_custom\">加载中</div>" +
|
"<div id=\"expand_custom\">加载中</div>" +
|
||||||
"</div></td></tr>"
|
"</div></td></tr>"
|
||||||
);
|
);
|
||||||
@@ -223,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].className = "progress-bar progress-bar-success";
|
||||||
TableRow.children["memory"].children[0].children[0].style.width = Mem + "%";
|
TableRow.children["memory"].children[0].children[0].style.width = Mem + "%";
|
||||||
TableRow.children["memory"].children[0].children[0].innerHTML = 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
|
||||||
// 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);
|
||||||
ExpandRow[0].children["expand_swap"].innerHTML = "交换分区: " + bytesToSize(result.servers[i].swap_used*1024, 2) + " / " + bytesToSize(result.servers[i].swap_total*1024, 2);
|
|
||||||
|
|
||||||
// HDD
|
// HDD
|
||||||
var HDD = ((result.servers[i].hdd_used/result.servers[i].hdd_total)*100.0).toFixed(0);
|
var HDD = ((result.servers[i].hdd_used/result.servers[i].hdd_total)*100.0).toFixed(0);
|
||||||
@@ -262,8 +261,12 @@ function uptime() {
|
|||||||
var PING_10010 = result.servers[i].ping_10010.toFixed(0);
|
var PING_10010 = result.servers[i].ping_10010.toFixed(0);
|
||||||
var PING_189 = result.servers[i].ping_189.toFixed(0);
|
var PING_189 = result.servers[i].ping_189.toFixed(0);
|
||||||
var PING_10086 = result.servers[i].ping_10086.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)
|
if (PING_10010 >= 20 || PING_189 >= 20 || PING_10086 >= 20)
|
||||||
TableRow.children["ping"].children[0].children[0].className = "progress-bar progress-bar-warning";
|
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
|
else
|
||||||
TableRow.children["ping"].children[0].children[0].className = "progress-bar progress-bar-success";
|
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 + "%";
|
TableRow.children["ping"].children[0].children[0].innerHTML = PING_10010 + "%💻" + PING_189 + "%💻" + PING_10086 + "%";
|
||||||
|
|||||||
Reference in New Issue
Block a user