|
@@ -33,7 +33,7 @@ import tornado.websocket
|
|
|
from tornado.gen import sleep
|
|
|
import asyncio
|
|
|
|
|
|
-VERSION = '0.9.9'
|
|
|
+VERSION = '0.9.11'
|
|
|
|
|
|
konfig_file = 'config.cfg'
|
|
|
s_certfile = 'server.crt'
|
|
@@ -41,6 +41,9 @@ s_keyfile = 'server.key'
|
|
|
ws_method = 'ws'
|
|
|
host_dict = dict()
|
|
|
failed_pingc = dict()
|
|
|
+g_since = dict()
|
|
|
+y_since = dict()
|
|
|
+r_since = dict()
|
|
|
loop_interval = 3
|
|
|
listen_port = 8888
|
|
|
listen_addr = '0.0.0.0'
|
|
@@ -137,6 +140,13 @@ def file_exists(file):
|
|
|
return True
|
|
|
return False
|
|
|
|
|
|
+def set_since(host,now,set,unset1,unset2):
|
|
|
+ unset1[host]=None
|
|
|
+ unset2[host]=None
|
|
|
+ if set.get(host):
|
|
|
+ pass
|
|
|
+ else:
|
|
|
+ set[host] = now
|
|
|
|
|
|
def create_fpingparam():
|
|
|
global fping_parameter
|
|
@@ -170,7 +180,6 @@ def ping(ip, packets=1, timeout=2):
|
|
|
return res.returncode == 0
|
|
|
|
|
|
def fping(ips):
|
|
|
- #comd = ['fping', '--quiet', '--interval=2', '--vcount=3', '--period=100'] + ips
|
|
|
comd = fping_parameter + ips
|
|
|
|
|
|
res = subprocess.run(comd, stdin=subprocess.DEVNULL, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) #, universal_newlines = True)
|
|
@@ -237,11 +246,16 @@ async def FpingLoop():
|
|
|
await asyncio.sleep(3)
|
|
|
continue
|
|
|
|
|
|
- ac_time = datetime.now().strftime("%H:%M:%S")
|
|
|
+ ac_now = datetime.now()
|
|
|
+ ac_time = ac_now.strftime("%H:%M:%S")
|
|
|
+ ac_timed = ac_now.strftime("%a %d %H:%M:%S")
|
|
|
if args.v: print("call fping: " + ac_time)
|
|
|
ret = fping(ip_list)
|
|
|
rl = ret.splitlines()
|
|
|
json_bc = []
|
|
|
+ cnt_ok = 0
|
|
|
+ cnt_halb = 0
|
|
|
+ cnt_fail = 0
|
|
|
for line in rl:
|
|
|
host,rtims = line.split(' : ')
|
|
|
if ( re.search(r"duplicate", rtims, flags=re.I) ):
|
|
@@ -249,45 +263,58 @@ async def FpingLoop():
|
|
|
continue
|
|
|
host = host.strip()
|
|
|
rtims = rtims.strip()
|
|
|
+ #print(host+": "+rtims)
|
|
|
ux_sect = 'ux_' + host_dict[host]
|
|
|
|
|
|
if re.search(r"[\d\.]+ [\d\.]+ [\d\.]+", rtims):
|
|
|
#print(host+" OK")
|
|
|
+ cnt_ok += 1
|
|
|
+ set_since(host, ac_timed, set=g_since,unset1=y_since,unset2=r_since)
|
|
|
json_bc.append({
|
|
|
- "host": host, "status": "OK", "rtt": rtims, "actime": ac_time, "sect": ux_sect
|
|
|
+ "host": host, "status": "OK", "rtt": rtims, "actime": ac_time, "sect": ux_sect, "since": g_since[host]
|
|
|
})
|
|
|
failed_pingc[host] = 0
|
|
|
#BroadcastHandler.broadcast(line)
|
|
|
elif re.search(r"[\d\.]+ [\d\.]+ -", rtims) or re.search(r"[\d\.]+ - [\d\.]+", rtims) or re.search(r"- [\d\.]+ [\d\.]+", rtims):
|
|
|
#print(host+" OK")
|
|
|
+ cnt_ok += 1
|
|
|
+ set_since(host, ac_timed, set=g_since,unset1=y_since,unset2=r_since)
|
|
|
json_bc.append({
|
|
|
- "host": host, "status": "OK", "rtt": rtims, "actime": ac_time, "sect": ux_sect
|
|
|
+ "host": host, "status": "OK", "rtt": rtims, "actime": ac_time, "sect": ux_sect, "since": g_since[host]
|
|
|
})
|
|
|
failed_pingc[host] = 0
|
|
|
#BroadcastHandler.broadcast(line)
|
|
|
elif re.search(r"- - -", rtims):
|
|
|
#print(host+" FAILED")
|
|
|
+ cnt_fail += 1
|
|
|
+ set_since(host, ac_timed, set=r_since,unset1=y_since,unset2=g_since)
|
|
|
if failed_pingc[host] < int(config["Main"]["FlashThreshold"]):
|
|
|
json_bc.append({
|
|
|
- "host": host, "status": "NEWFAIL", "rtt": rtims, "actime": ac_time, "sect": ux_sect
|
|
|
+ "host": host, "status": "NEWFAIL", "rtt": rtims, "actime": ac_time, "sect": ux_sect, "since": r_since[host]
|
|
|
})
|
|
|
failed_pingc[host] += 1
|
|
|
else:
|
|
|
json_bc.append({
|
|
|
- "host": host, "status": "FAILED", "rtt": rtims, "actime": ac_time, "sect": ux_sect
|
|
|
+ "host": host, "status": "FAILED", "rtt": rtims, "actime": ac_time, "sect": ux_sect, "since": r_since[host]
|
|
|
})
|
|
|
failed_pingc[host] = int(config["Main"]["FlashThreshold"]) + 1
|
|
|
#BroadcastHandler.broadcast(line)
|
|
|
elif re.search(r"[\d\.]+", rtims):
|
|
|
#print(host+" HALB")
|
|
|
+ cnt_halb += 1
|
|
|
+ set_since(host, ac_timed, set=y_since,unset1=r_since,unset2=g_since)
|
|
|
json_bc.append({
|
|
|
- "host": host, "status": "HALB", "rtt": rtims, "actime": ac_time, "sect": ux_sect
|
|
|
+ "host": host, "status": "HALB", "rtt": rtims, "actime": ac_time, "sect": ux_sect, "since": y_since[host]
|
|
|
})
|
|
|
failed_pingc[host] = 0
|
|
|
#BroadcastHandler.broadcast(line)
|
|
|
else:
|
|
|
print(host+" ???????????????????")
|
|
|
-
|
|
|
+
|
|
|
+ if args.v: print("STAT(%d hosts, interval:%s ms, period:%s ms): green=%d / yellow=%d / red=%d / ping-round: %d sec" % (anz_hosts, config["Main"]["Fping-interval"], config["Main"]["Fping-period"], cnt_ok, cnt_halb, cnt_fail, int(datetime.now().timestamp()) - int(ac_now.timestamp())) )
|
|
|
+ #print(g_since)
|
|
|
+ #print(y_since)
|
|
|
+ #print(r_since)
|
|
|
#print(json.dumps(json_bc, separators=(',', ':'), ensure_ascii=False))
|
|
|
BroadcastHandler.broadcast(json_bc)
|
|
|
|
|
@@ -482,6 +509,7 @@ html_html = '''
|
|
|
var cur_status = data_obj.status;
|
|
|
var cur_sect_ux = data_obj.sect;
|
|
|
var cur_rtt = data_obj.rtt;
|
|
|
+ var cur_since = data_obj.since;
|
|
|
cur_rtt = cur_rtt.replace(/ /g,' \/ ');
|
|
|
var uc_cur_host = cur_host.replace(/\./g,'_');
|
|
|
document.getElementById(uc_cur_host).textContent = cur_host;
|
|
@@ -490,24 +518,33 @@ html_html = '''
|
|
|
if (cur_status == 'OK') {
|
|
|
M_green.set(cur_sect_ux, M_green.get(cur_sect_ux) + 1);
|
|
|
document.getElementById(stat_id).innerHTML = '<img src="/img/green_on.gif">';
|
|
|
- document.getElementById(ttip_id).innerHTML = '<b>RTT</b>: '+cur_rtt;
|
|
|
+ document.getElementById(ttip_id).innerHTML = '<b>RTT</b>: '+cur_rtt+'<br><span style="color:#0f0;">since </span>: '+cur_since;
|
|
|
} else if (cur_status == 'FAILED') {
|
|
|
M_red.set(cur_sect_ux, M_red.get(cur_sect_ux) + 1);
|
|
|
document.getElementById(stat_id).innerHTML = '<img src="/img/red_on.gif">';
|
|
|
- document.getElementById(ttip_id).innerHTML = '<b>RTT</b>: '+cur_rtt;
|
|
|
+ document.getElementById(ttip_id).innerHTML = '<b>RTT</b>: '+cur_rtt+'<br><span style="color:red;">since </span>: '+cur_since;
|
|
|
} else if (cur_status == 'NEWFAIL') {
|
|
|
M_red.set(cur_sect_ux, M_red.get(cur_sect_ux) + 1);
|
|
|
document.getElementById(stat_id).innerHTML = '<img src="/img/red_anim.gif">';
|
|
|
- document.getElementById(ttip_id).innerHTML = '<b>RTT</b>: '+cur_rtt;
|
|
|
+ document.getElementById(ttip_id).innerHTML = '<b>RTT</b>: '+cur_rtt+'<br><span style="color:red;">since </span>: '+cur_since;
|
|
|
} else {
|
|
|
M_yellow.set(cur_sect_ux, M_yellow.get(cur_sect_ux) + 1);
|
|
|
document.getElementById(stat_id).innerHTML = '<img src="/img/yellow_on.gif">';
|
|
|
- document.getElementById(ttip_id).innerHTML = '<b>RTT</b>: '+cur_rtt;
|
|
|
+ document.getElementById(ttip_id).innerHTML = '<b>RTT</b>: '+cur_rtt+'<br><span style="color:yellow;">since </span>: '+cur_since;
|
|
|
}
|
|
|
} // End for
|
|
|
document.getElementById('cur_actime').innerHTML = cur_actime;
|
|
|
+
|
|
|
for (let [sect, val] of M_red) {
|
|
|
- document.getElementById(sect).innerHTML = '<span class="unreach_r"><span class="red_r">'+M_red.get(sect).toString().padStart(3, " ")+'</span> | <span class="yellow_r">'+M_yellow.get(sect).toString().padStart(3, " ")+'</span> | <span class="green_r">'+M_green.get(sect).toString().padStart(3, " ")+'</span></span>';
|
|
|
+ let tmp_r = '<span class="unreach_r">';
|
|
|
+ tmp_r += (M_red.get(sect) == 0) ? '<span class="red_r opaq_r">'+M_red.get(sect).toString().padStart(3, " ")+'</span> | '
|
|
|
+ : '<span class="red_r">'+M_red.get(sect).toString().padStart(3, " ")+'</span> | ';
|
|
|
+ tmp_r += (M_yellow.get(sect) == 0) ? '<span class="yellow_r opaq_r">'+M_yellow.get(sect).toString().padStart(3, " ")+'</span> | '
|
|
|
+ : '<span class="yellow_r">'+M_yellow.get(sect).toString().padStart(3, " ")+'</span> | ';
|
|
|
+ tmp_r += (M_green.get(sect) == 0) ? '<span class="green_r opaq_r">'+M_green.get(sect).toString().padStart(3, " ")+'</span>'
|
|
|
+ : '<span class="green_r">'+M_green.get(sect).toString().padStart(3, " ")+'</span>';
|
|
|
+ tmp_r += '</span>';
|
|
|
+ document.getElementById(sect).innerHTML = tmp_r;
|
|
|
}
|
|
|
};
|
|
|
|
|
@@ -530,7 +567,7 @@ html_html = '''
|
|
|
};
|
|
|
|
|
|
function Accordion(id) {
|
|
|
- var x = document.getElementById(id); //alert(x); //.previousSibling.getElementsByTagName("*").item(0).innerHTML);
|
|
|
+ var x = document.getElementById(id);
|
|
|
if (x.className.indexOf("w3-show") == -1) {
|
|
|
x.className = "w3-show";
|
|
|
} else {
|
|
@@ -581,10 +618,11 @@ body {
|
|
|
.red { color: red; }
|
|
|
.green { color: #0f0; }
|
|
|
.yellow { color: yellow; }
|
|
|
-.red_r { color: red; white-space: pre; text-align: right; font-family: monospace;text-shadow: 0px -0px 0px #f44;}
|
|
|
-.green_r { color: #0f0; white-space: pre; text-align: right;; font-family: monospace;}
|
|
|
-.yellow_r { color: yellow; white-space: pre; text-align: right;; font-family: monospace;}
|
|
|
+.red_r { color: red; white-space: pre; text-align: right; font-family: monospace; width: 2em; display: inline-block;}
|
|
|
+.green_r { color: #0f0; white-space: pre; text-align: right;; font-family: monospace; width: 2em; display: inline-block;}
|
|
|
+.yellow_r { color: yellow; white-space: pre; text-align: right;; font-family: monospace; width: 2em; display: inline-block;}
|
|
|
.ip_num { font-size: 80%; }
|
|
|
+.opaq_r { opacity: 0.2; }
|
|
|
|
|
|
.si3-dark-grey{color:#fff!important;background-color:#626262!important;text-shadow: 0 0 0px #fff, 0 0 1px #000;}
|
|
|
|