From 71cadcfebe05d97fb609b2b380ff82213f01faa0 Mon Sep 17 00:00:00 2001
From: cppla
Date: Sun, 21 Jan 2024 21:09:37 +0800
Subject: [PATCH] =?UTF-8?q?=E6=B5=8B=E8=AF=95=E7=9B=91=E6=8E=A7=E9=87=8D?=
=?UTF-8?q?=E8=A6=81=E6=9C=8D=E5=8A=A1?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
clients/client-linux.py | 118 +++++++++++++++++++++++++++++++++++++--
clients/client-psutil.py | 118 +++++++++++++++++++++++++++++++++++++--
server/config.json | 40 +++++++++----
server/src/main.cpp | 34 +++++++++++
server/src/main.h | 11 +++-
web/css/dark.css | 66 +++++++++-------------
web/css/light.css | 66 +++++++++-------------
web/index.html | 73 ++++++++++++++++--------
web/js/serverstatus.js | 42 +++++++++++---
9 files changed, 434 insertions(+), 134 deletions(-)
diff --git a/clients/client-linux.py b/clients/client-linux.py
index 00e59d5..0574453 100755
--- a/clients/client-linux.py
+++ b/clients/client-linux.py
@@ -20,6 +20,7 @@ PING_PACKET_HISTORY_LEN = 100
INTERVAL = 1
import socket
+import ssl
import time
import timeit
import re
@@ -29,10 +30,10 @@ import json
import errno
import subprocess
import threading
-try:
- from queue import Queue # python3
-except ImportError:
- from Queue import Queue # python2
+if sys.version_info.major == 3:
+ from queue import Queue
+elif sys.version_info.major == 2:
+ from Queue import Queue
def get_uptime():
with open('/proc/uptime', 'r') as f:
@@ -150,6 +151,7 @@ diskIO = {
'read': 0,
'write': 0
}
+monitorServer = {}
def _ping_thread(host, mark, port):
lostPacket = 0
@@ -314,6 +316,97 @@ def get_realtime_data():
ti.daemon = True
ti.start()
+
+def _monitor_thread(name, host, interval, type):
+ lostPacket = 0
+ packet_queue = Queue(maxsize=PING_PACKET_HISTORY_LEN)
+ while True:
+ if name not in monitorServer.keys():
+ monitorServer[name] = {
+ "type": type,
+ "dns_time": 0,
+ "connect_time": 0,
+ "download_time": 0,
+ "online_rate": 1
+ }
+ if packet_queue.full():
+ if packet_queue.get() == 0:
+ lostPacket -= 1
+ try:
+ if type == "http":
+ address = host.replace("http://", "")
+ m = timeit.default_timer()
+ if PROBE_PROTOCOL_PREFER == 'ipv4':
+ IP = socket.getaddrinfo(address, None, socket.AF_INET)[0][4][0]
+ else:
+ IP = socket.getaddrinfo(address, None, socket.AF_INET6)[0][4][0]
+ monitorServer[name]["dns_time"] = int((timeit.default_timer() - m) * 1000)
+ m = timeit.default_timer()
+ k = socket.create_connection((IP, 80), timeout=6)
+ monitorServer[name]["connect_time"] = int((timeit.default_timer() - m) * 1000)
+ m = timeit.default_timer()
+ k.sendall("GET / HTTP/1.2\r\nHost:{}\r\nConnection:close\r\n\r\n".format(address).encode('utf-8'))
+ response = b""
+ while True:
+ data = k.recv(4096)
+ if not data:
+ break
+ response += data
+ http_code = response.decode('utf-8').split('\r\n')[0].split()[1]
+ monitorServer[name]["download_time"] = int((timeit.default_timer() - m) * 1000)
+ k.close()
+ if http_code not in ['200', '204', '301', '302', '401']:
+ raise Exception("http code not in 200, 204, 301, 302, 401")
+ elif type == "https":
+ context = ssl._create_unverified_context()
+ address = host.replace("https://", "")
+ m = timeit.default_timer()
+ if PROBE_PROTOCOL_PREFER == 'ipv4':
+ IP = socket.getaddrinfo(address, None, socket.AF_INET)[0][4][0]
+ else:
+ IP = socket.getaddrinfo(address, None, socket.AF_INET6)[0][4][0]
+ monitorServer[name]["dns_time"] = int((timeit.default_timer() - m) * 1000)
+ m = timeit.default_timer()
+ k = socket.create_connection((IP, 443), timeout=6)
+ monitorServer[name]["connect_time"] = int((timeit.default_timer() - m) * 1000)
+ m = timeit.default_timer()
+ kk = context.wrap_socket(k, server_hostname=address)
+ kk.sendall("GET / HTTP/1.2\r\nHost:{}\r\nConnection:close\r\n\r\n".format(address).encode('utf-8'))
+ response = b""
+ while True:
+ data = kk.recv(4096)
+ if not data:
+ break
+ response += data
+ http_code = response.decode('utf-8').split('\r\n')[0].split()[1]
+ monitorServer[name]["download_time"] = int((timeit.default_timer() - m) * 1000)
+ kk.close()
+ k.close()
+ if http_code not in ['200', '204', '301', '302', '401']:
+ raise Exception("http code not in 200, 204, 301, 302, 401")
+ elif type == "tcp":
+ m = timeit.default_timer()
+ if PROBE_PROTOCOL_PREFER == 'ipv4':
+ IP = socket.getaddrinfo(host.split(":")[0], None, socket.AF_INET)[0][4][0]
+ else:
+ IP = socket.getaddrinfo(host.split(":")[0], None, socket.AF_INET6)[0][4][0]
+ monitorServer[name]["dns_time"] = int((timeit.default_timer() - m) * 1000)
+ m = timeit.default_timer()
+ k = socket.create_connection((IP, int(host.split(":")[1])), timeout=6)
+ monitorServer[name]["connect_time"] = int((timeit.default_timer() - m) * 1000)
+ m = timeit.default_timer()
+ k.send(b"GET / HTTP/1.2\r\n\r\n")
+ k.recv(1024)
+ monitorServer[name]["download_time"] = int((timeit.default_timer() - m) * 1000)
+ k.close()
+ packet_queue.put(1)
+ except Exception as e:
+ lostPacket += 1
+ packet_queue.put(0)
+ if packet_queue.qsize() > 5:
+ monitorServer[name]["online_rate"] = 1 - float(lostPacket) / packet_queue.qsize()
+ time.sleep(interval)
+
def byte_str(object):
'''
bytes to str, str to bytes
@@ -360,6 +453,20 @@ if __name__ == '__main__':
if data.find("You are connecting via") < 0:
data = byte_str(s.recv(1024))
print(data)
+ for i in data.split('\n'):
+ if "monitor" in i and "type" in i and "{" in i and "}" in i:
+ jdata = json.loads(i[i.find("{"):i.find("}")+1])
+ t = threading.Thread(
+ target=_monitor_thread,
+ kwargs={
+ 'name': jdata.get("name"),
+ 'host': jdata.get("host"),
+ 'interval': jdata.get("interval"),
+ 'type': jdata.get("type")
+ }
+ )
+ t.daemon = True
+ t.start()
timer = 0
check_ip = 0
@@ -378,7 +485,6 @@ if __name__ == '__main__':
Load_1, Load_5, Load_15 = os.getloadavg()
MemoryTotal, MemoryUsed, SwapTotal, SwapFree = get_memory()
HDDTotal, HDDUsed = get_hdd()
-
array = {}
if not timer:
array['online' + str(check_ip)] = get_network(check_ip)
@@ -412,7 +518,7 @@ if __name__ == '__main__':
array['tcp'], array['udp'], array['process'], array['thread'] = tupd()
array['io_read'] = diskIO.get("read")
array['io_write'] = diskIO.get("write")
-
+ array['custom'] = "
".join(f"{k}
\\t解析: {v['dns_time']}\\t连接: {v['connect_time']}\\t下载: {v['download_time']}\\t在线率: {v['online_rate']*100}%
" for k, v in monitorServer.items())
s.send(byte_str("update " + json.dumps(array) + "\n"))
except KeyboardInterrupt:
raise
diff --git a/clients/client-psutil.py b/clients/client-psutil.py
index ceac788..c2b3928 100755
--- a/clients/client-psutil.py
+++ b/clients/client-psutil.py
@@ -21,6 +21,7 @@ PING_PACKET_HISTORY_LEN = 100
INTERVAL = 1
import socket
+import ssl
import time
import timeit
import os
@@ -29,10 +30,10 @@ import json
import errno
import psutil
import threading
-try:
- from queue import Queue # python3
-except ImportError:
- from Queue import Queue # python2
+if sys.version_info.major == 3:
+ from queue import Queue
+elif sys.version_info.major == 2:
+ from Queue import Queue
def get_uptime():
return int(time.time() - psutil.boot_time())
@@ -148,6 +149,7 @@ diskIO = {
'read': 0,
'write': 0
}
+monitorServer = {}
def _ping_thread(host, mark, port):
lostPacket = 0
@@ -303,6 +305,97 @@ def get_realtime_data():
ti.daemon = True
ti.start()
+def _monitor_thread(name, host, interval, type):
+ lostPacket = 0
+ packet_queue = Queue(maxsize=PING_PACKET_HISTORY_LEN)
+ while True:
+ if name not in monitorServer.keys():
+ monitorServer[name] = {
+ "type": type,
+ "dns_time": 0,
+ "connect_time": 0,
+ "download_time": 0,
+ "online_rate": 1
+ }
+ if packet_queue.full():
+ if packet_queue.get() == 0:
+ lostPacket -= 1
+ try:
+ if type == "http":
+ address = host.replace("http://", "")
+ m = timeit.default_timer()
+ if PROBE_PROTOCOL_PREFER == 'ipv4':
+ IP = socket.getaddrinfo(address, None, socket.AF_INET)[0][4][0]
+ else:
+ IP = socket.getaddrinfo(address, None, socket.AF_INET6)[0][4][0]
+ monitorServer[name]["dns_time"] = int((timeit.default_timer() - m) * 1000)
+ m = timeit.default_timer()
+ k = socket.create_connection((IP, 80), timeout=6)
+ monitorServer[name]["connect_time"] = int((timeit.default_timer() - m) * 1000)
+ m = timeit.default_timer()
+ k.sendall("GET / HTTP/1.2\r\nHost:{}\r\nConnection:close\r\n\r\n".format(address).encode('utf-8'))
+ response = b""
+ while True:
+ data = k.recv(4096)
+ if not data:
+ break
+ response += data
+ http_code = response.decode('utf-8').split('\r\n')[0].split()[1]
+ monitorServer[name]["download_time"] = int((timeit.default_timer() - m) * 1000)
+ k.close()
+ if http_code not in ['200', '204', '301', '302', '401']:
+ raise Exception("http code not in 200, 204, 301, 302, 401")
+ elif type == "https":
+ context = ssl._create_unverified_context()
+ address = host.replace("https://", "")
+ m = timeit.default_timer()
+ if PROBE_PROTOCOL_PREFER == 'ipv4':
+ IP = socket.getaddrinfo(address, None, socket.AF_INET)[0][4][0]
+ else:
+ IP = socket.getaddrinfo(address, None, socket.AF_INET6)[0][4][0]
+ monitorServer[name]["dns_time"] = int((timeit.default_timer() - m) * 1000)
+ m = timeit.default_timer()
+ k = socket.create_connection((IP, 443), timeout=6)
+ monitorServer[name]["connect_time"] = int((timeit.default_timer() - m) * 1000)
+ m = timeit.default_timer()
+ kk = context.wrap_socket(k, server_hostname=address)
+ kk.sendall("GET / HTTP/1.2\r\nHost:{}\r\nConnection:close\r\n\r\n".format(address).encode('utf-8'))
+ response = b""
+ while True:
+ data = kk.recv(4096)
+ if not data:
+ break
+ response += data
+ http_code = response.decode('utf-8').split('\r\n')[0].split()[1]
+ monitorServer[name]["download_time"] = int((timeit.default_timer() - m) * 1000)
+ kk.close()
+ k.close()
+ if http_code not in ['200', '204', '301', '302', '401']:
+ raise Exception("http code not in 200, 204, 301, 302, 401")
+ elif type == "tcp":
+ m = timeit.default_timer()
+ if PROBE_PROTOCOL_PREFER == 'ipv4':
+ IP = socket.getaddrinfo(host.split(":")[0], None, socket.AF_INET)[0][4][0]
+ else:
+ IP = socket.getaddrinfo(host.split(":")[0], None, socket.AF_INET6)[0][4][0]
+ monitorServer[name]["dns_time"] = int((timeit.default_timer() - m) * 1000)
+ m = timeit.default_timer()
+ k = socket.create_connection((IP, int(host.split(":")[1])), timeout=6)
+ monitorServer[name]["connect_time"] = int((timeit.default_timer() - m) * 1000)
+ m = timeit.default_timer()
+ k.send(b"GET / HTTP/1.2\r\n\r\n")
+ k.recv(1024)
+ monitorServer[name]["download_time"] = int((timeit.default_timer() - m) * 1000)
+ k.close()
+ packet_queue.put(1)
+ except Exception as e:
+ lostPacket += 1
+ packet_queue.put(0)
+ if packet_queue.qsize() > 5:
+ monitorServer[name]["online_rate"] = 1 - float(lostPacket) / packet_queue.qsize()
+ time.sleep(interval)
+
+
def byte_str(object):
'''
bytes to str, str to bytes
@@ -349,6 +442,20 @@ if __name__ == '__main__':
if data.find("You are connecting via") < 0:
data = byte_str(s.recv(1024))
print(data)
+ for i in data.split('\n'):
+ if "monitor" in i and "type" in i and "{" in i and "}" in i:
+ jdata = json.loads(i[i.find("{"):i.find("}")+1])
+ t = threading.Thread(
+ target=_monitor_thread,
+ kwargs={
+ 'name': jdata.get("name"),
+ 'host': jdata.get("host"),
+ 'interval': jdata.get("interval"),
+ 'type': jdata.get("type")
+ }
+ )
+ t.daemon = True
+ t.start()
timer = 0
check_ip = 0
@@ -368,7 +475,6 @@ if __name__ == '__main__':
MemoryTotal, MemoryUsed = get_memory()
SwapTotal, SwapUsed = get_swap()
HDDTotal, HDDUsed = get_hdd()
-
array = {}
if not timer:
array['online' + str(check_ip)] = get_network(check_ip)
@@ -402,7 +508,7 @@ if __name__ == '__main__':
array['tcp'], array['udp'], array['process'], array['thread'] = tupd()
array['io_read'] = diskIO.get("read")
array['io_write'] = diskIO.get("write")
-
+ array['custom'] = "
".join(f"{k}
\\t解析: {v['dns_time']}\\t连接: {v['connect_time']}\\t下载: {v['download_time']}\\t在线率: {v['online_rate']*100}%
" for k, v in monitorServer.items())
s.send(byte_str("update " + json.dumps(array) + "\n"))
except KeyboardInterrupt:
raise
diff --git a/server/config.json b/server/config.json
index c60018f..29a4df4 100644
--- a/server/config.json
+++ b/server/config.json
@@ -38,6 +38,26 @@
"monthstart": 1
}
],
+ "monitors": [
+ {
+ "name": "百度一下",
+ "host": "https://www.baidu.com",
+ "interval": 60,
+ "type": "https"
+ },
+ {
+ "name": "主机交流",
+ "host": "https://www.hostloc.com",
+ "interval": 60,
+ "type": "https"
+ },
+ {
+ "name": "DNS服务",
+ "host": "114.114.114.114:53",
+ "interval": 60,
+ "type": "tcp"
+ }
+ ],
"watchdog": [
{
"name": "cpu high warning,exclude username s01",
@@ -58,17 +78,17 @@
"callback": "https://yourSMSurl"
},
{
- "name": "ddcc attack,limit type Oracle",
- "rule": "tcp_count>600&type='Oracle'",
- "interval": 300,
- "callback": "https://yourSMSurl"
- },
+ "name": "ddcc attack,limit type Oracle",
+ "rule": "tcp_count>600&type='Oracle'",
+ "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": "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",
diff --git a/server/src/main.cpp b/server/src/main.cpp
index d24d605..2dc5c43 100644
--- a/server/src/main.cpp
+++ b/server/src/main.cpp
@@ -92,6 +92,18 @@ void CMain::OnNewClient(int ClientNetID, int ClientID)
Client(ClientID)->m_Stats.m_Online4 = true;
else if(Client(ClientID)->m_ClientNetType == NETTYPE_IPV6)
Client(ClientID)->m_Stats.m_Online6 = true;
+
+ // Send monitor to client
+ // support by cpp.la
+ int ID = 0;
+ char monitorBuffer[2048];
+ while (strcmp(Monitors(ID)->m_aName, "NULL"))
+ {
+ memset(monitorBuffer, 0, sizeof(monitorBuffer));
+ sprintf(monitorBuffer, "{\"name\":\"%s\",\"host\":\"%s\",\"interval\":%d,\"type\":\"%s\",\"monitor\":%d}", Monitors(ID)->m_aName, Monitors(ID)->m_aHost, Monitors(ID)->m_aInterval, Monitors(ID)->m_aType, ID);
+ m_Server.Network()->Send(ClientNetID, monitorBuffer);
+ ID++;
+ }
}
void CMain::OnDelClient(int ClientNetID)
@@ -572,6 +584,28 @@ int CMain::ReadConfig()
} else
str_copy(Watchdog(ID)->m_aName, "NULL", sizeof(Watchdog(ID)->m_aName));
+ // monitor
+ // support by: https://cpp.la
+ ID = 0;
+ const json_value &mStart = (*pJsonData)["monitors"];
+ if(mStart.type == json_array)
+ {
+ for(unsigned i = 0; i < mStart.u.array.length; i++)
+ {
+ if(ID < 0 || ID >= NET_MAX_CLIENTS)
+ continue;
+
+ str_copy(Monitors(ID)->m_aName, mStart[i]["name"].u.string.ptr, sizeof(Monitors(ID)->m_aName));
+ str_copy(Monitors(ID)->m_aHost, mStart[i]["host"].u.string.ptr, sizeof(Monitors(ID)->m_aHost));
+ Monitors(ID)->m_aInterval = mStart[i]["interval"].u.integer;
+ str_copy(Monitors(ID)->m_aType, mStart[i]["type"].u.string.ptr, sizeof(Monitors(ID)->m_aType));
+
+ ID++;
+ }
+ str_copy(Monitors(ID)->m_aName, "NULL", sizeof(Monitors(ID)->m_aName));
+ } else
+ str_copy(Monitors(ID)->m_aName, "NULL", sizeof(Monitors(ID)->m_aName));
+
// if file exists, read last network traffic record,reset m_LastNetworkIN and m_LastNetworkOUT
// support by: https://cpp.la
IOHANDLE nFile = io_open(m_Config.m_aJSONFile, IOFLAG_READ);
diff --git a/server/src/main.h b/server/src/main.h
index eb3fb3e..848d246 100644
--- a/server/src/main.h
+++ b/server/src/main.h
@@ -77,7 +77,7 @@ class CMain
int64_t m_IORead;
int64_t m_IOWrite;
double m_CPU;
- char m_aCustom[512];
+ char m_aCustom[1024];
// Options
bool m_Pong;
} m_Stats;
@@ -90,6 +90,13 @@ class CMain
char m_aCallback[1024];
} m_aCWatchDogs[NET_MAX_CLIENTS];
+ struct CMonitors{
+ char m_aName[128];
+ char m_aHost[128];
+ int m_aInterval;
+ char m_aType[128];
+ } m_aCMonitors[NET_MAX_CLIENTS];
+
struct CJSONUpdateThreadData
{
CClient *pClients;
@@ -108,6 +115,8 @@ public:
int Run();
CWatchDog *Watchdog(int ruleID) { return &m_aCWatchDogs[ruleID]; }
+ CMonitors *Monitors(int ruleID) { return &m_aCMonitors[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,
diff --git a/web/css/dark.css b/web/css/dark.css
index 5bfb949..eea98f3 100644
--- a/web/css/dark.css
+++ b/web/css/dark.css
@@ -23,48 +23,32 @@ tr.odd.expandRow > :hover { background: #212e36 !important; }
#ping { max-width: 110px; }
@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; }
+ #server {
+ #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) {
- 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; }
+ #server {
+ 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: 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) {
- 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; }
- #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; }
-}
+ #server {
+ 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; }
+ }
+}
\ No newline at end of file
diff --git a/web/css/light.css b/web/css/light.css
index e881dcb..37e7f77 100644
--- a/web/css/light.css
+++ b/web/css/light.css
@@ -20,48 +20,32 @@ tr.odd.expandRow > :hover { background: #FFF !important; }
#ping { max-width: 110px; }
@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; }
+ #server {
+ #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) {
- 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; }
+ #server {
+ 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: 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) {
- 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; }
- #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; }
-}
+ #server {
+ 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; }
+ }
+}
\ No newline at end of file
diff --git a/web/index.html b/web/index.html
index ed68d63..5fa6175 100644
--- a/web/index.html
+++ b/web/index.html
@@ -47,6 +47,12 @@
-
-
-
- 🔗协议 |
- 📊月流量↓|↑ |
- 📌节点 |
- 🗂️虚拟化 |
- 🌍位置 |
- ⏱️在线 |
- 负载 |
- 🚦网络↓|↑ |
- 📋总流量↓|↑ |
- 🎯核芯 |
- ⚡️内存 |
- 💾硬盘 |
- 🌐CU|CT|CM |
-
-
-
-
-
-
+
+
+
+
+
+
+
+ 🔗协议 |
+ 📊月流量↓|↑ |
+ 📌节点 |
+ 🗂️虚拟化 |
+ 🌍位置 |
+ ⏱️在线 |
+ 负载 |
+ 🚦网络↓|↑ |
+ 📋总流量↓|↑ |
+ 🎯核芯 |
+ ⚡️内存 |
+ 💾硬盘 |
+ 🌐CU|CT|CM |
+
+
+
+
+
+
+
+
+
+
+
+
+ 🔗协议 |
+ 📌监测节点 |
+ 🌍监测位置 |
+ 📋监测内容 |
+
+
+
+
+
+
+
+
+
Updating...
diff --git a/web/js/serverstatus.js b/web/js/serverstatus.js
index 43c1237..529456c 100644
--- a/web/js/serverstatus.js
+++ b/web/js/serverstatus.js
@@ -57,6 +57,7 @@ function uptime() {
for (var i = 0, rlen=result.servers.length; i < rlen; i++) {
var TableRow = $("#servers tr#r" + i);
+ var MableRow = $("#monitors tr#r" + i);
var ExpandRow = $("#servers #rt" + i);
var hack; // fuck CSS for making me do this
if(i%2) hack="odd"; else hack="even";
@@ -82,16 +83,28 @@ function uptime() {
"加载中
" +
"加载中
" +
"加载中
" +
- "加载中
" +
""
);
TableRow = $("#servers tr#r" + i);
ExpandRow = $("#servers #rt" + i);
server_status[i] = true;
}
+ if (!MableRow.length) {
+ $("#monitors").append(
+ "" +
+ " | " +
+ "加载中 | " +
+ "加载中 | " +
+ "加载中 | " +
+ "
"
+ );
+ MableRow = $("#monitors tr#r" + i);
+ }
TableRow = TableRow[0];
+ MableRow = MableRow[0];
if(error) {
TableRow.setAttribute("data-target", "#rt" + i);
+ MableRow.setAttribute("data-target", "#rt" + i);
server_status[i] = true;
}
@@ -99,25 +112,35 @@ function uptime() {
if (result.servers[i].online4 && !result.servers[i].online6) {
TableRow.children["online_status"].children[0].children[0].className = "progress-bar progress-bar-success";
TableRow.children["online_status"].children[0].children[0].innerHTML = "IPv4";
+ MableRow.children["monitor_status"].children[0].children[0].className = "progress-bar progress-bar-success";
+ MableRow.children["monitor_status"].children[0].children[0].innerHTML = "IPv4";
} else if (result.servers[i].online4 && result.servers[i].online6) {
TableRow.children["online_status"].children[0].children[0].className = "progress-bar progress-bar-success";
TableRow.children["online_status"].children[0].children[0].innerHTML = "双栈";
+ MableRow.children["monitor_status"].children[0].children[0].className = "progress-bar progress-bar-success";
+ MableRow.children["monitor_status"].children[0].children[0].innerHTML = "双栈";
} else if (!result.servers[i].online4 && result.servers[i].online6) {
TableRow.children["online_status"].children[0].children[0].className = "progress-bar progress-bar-success";
TableRow.children["online_status"].children[0].children[0].innerHTML = "IPv6";
+ MableRow.children["monitor_status"].children[0].children[0].className = "progress-bar progress-bar-success";
+ MableRow.children["monitor_status"].children[0].children[0].innerHTML = "IPv6";
} else {
TableRow.children["online_status"].children[0].children[0].className = "progress-bar progress-bar-danger";
TableRow.children["online_status"].children[0].children[0].innerHTML = "关闭";
+ MableRow.children["monitor_status"].children[0].children[0].className = "progress-bar progress-bar-danger";
+ MableRow.children["monitor_status"].children[0].children[0].innerHTML = "关闭";
}
// Name
TableRow.children["name"].innerHTML = result.servers[i].name;
+ MableRow.children["monitor_node"].innerHTML = result.servers[i].name;
// Type
TableRow.children["type"].innerHTML = result.servers[i].type;
// Location
TableRow.children["location"].innerHTML = result.servers[i].location;
+ MableRow.children["monitor_location"].innerHTML = result.servers[i].location;
if (!result.servers[i].online4 && !result.servers[i].online6) {
if (server_status[i]) {
TableRow.children["uptime"].innerHTML = "–";
@@ -138,15 +161,18 @@ function uptime() {
TableRow.children["ping"].children[0].children[0].className = "progress-bar progress-bar-danger";
TableRow.children["ping"].children[0].children[0].style.width = "100%";
TableRow.children["ping"].children[0].children[0].innerHTML = "关闭";
+ MableRow.children["monitor_text"].innerHTML = "-";
if(ExpandRow.hasClass("in")) {
ExpandRow.collapse("hide");
}
TableRow.setAttribute("data-target", "");
+ MableRow.setAttribute("data-target", "");
server_status[i] = false;
}
} else {
if (!server_status[i]) {
TableRow.setAttribute("data-target", "#rt" + i);
+ MableRow.setAttribute("data-target", "#rt" + i);
server_status[i] = true;
}
@@ -271,12 +297,8 @@ function uptime() {
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 + "%";
- // Custom
- if (result.servers[i].custom) {
- ExpandRow[0].children["expand_custom"].innerHTML = result.servers[i].custom
- } else {
- ExpandRow[0].children["expand_custom"].innerHTML = ""
- }
+ // monitor
+ MableRow.children["monitor_text"].innerHTML = result.servers[i].custom;
}
};
@@ -286,9 +308,12 @@ function uptime() {
if (!error) {
$("#servers > tr.accordion-toggle").each(function(i) {
var TableRow = $("#servers tr#r" + i)[0];
+ var MableRow = $("#monitors tr#r" + i)[0];
var ExpandRow = $("#servers #rt" + i);
TableRow.children["online_status"].children[0].children[0].className = "progress-bar progress-bar-error";
TableRow.children["online_status"].children[0].children[0].innerHTML = "错误";
+ MableRow.children["monitor_status"].children[0].children[0].className = "progress-bar progress-bar-error";
+ MableRow.children["monitor_status"].children[0].children[0].innerHTML = "错误";
TableRow.children["month_traffic"].children[0].children[0].className = "progress-bar progress-bar-error";
TableRow.children["month_traffic"].children[0].children[0].innerHTML = "错误";
TableRow.children["uptime"].children[0].children[0].className = "progress-bar progress-bar-error";
@@ -311,10 +336,13 @@ function uptime() {
TableRow.children["ping"].children[0].children[0].className = "progress-bar progress-bar-error";
TableRow.children["ping"].children[0].children[0].style.width = "100%";
TableRow.children["ping"].children[0].children[0].innerHTML = "错误";
+ MableRow.children["monitor_text"].children[0].children[0].className = "progress-bar progress-bar-error";
+ MableRow.children["monitor_text"].children[0].children[0].innerHTML = "错误";
if(ExpandRow.hasClass("in")) {
ExpandRow.collapse("hide");
}
TableRow.setAttribute("data-target", "");
+ MableRow.setAttribute("data-target", "");
server_status[i] = false;
});
}