Parcourir la source

v0.9.11 / 28.4.25, si:
- New: - improved debug (-v) output to fiddle better with timing parameters
- Consolidated status information on sections more readable
- Host specific tooltip now has a "since" time info
- Corr: - anim_red image loop now infinite

sigi il y a 1 semaine
Parent
commit
2e4ff6160e
3 fichiers modifiés avec 66 ajouts et 23 suppressions
  1. 56 18
      PingPanel.py
  2. 2 2
      README.md
  3. 8 3
      changelog

+ 56 - 18
PingPanel.py

@@ -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;}
 

+ 2 - 2
README.md

@@ -12,8 +12,8 @@ Instead, it merely provides an overview of the current availability of the devic
 [https://pingpanel.zweiernet.ch/](https://pingpanel.zweiernet.ch/)
 	
 **_Download_**:   
-\- tar-archive: [https://pingpanel.zweiernet.ch/pingpanel_0.9.9.tar.gz](https://pingpanel.zweiernet.ch/pingpanel_0.9.9.tar.gz)   
-\- Debian installer: [https://pingpanel.zweiernet.ch/pingpanel_0.9.9_all.deb](https://pingpanel.zweiernet.ch/pingpanel_0.9.9_all.deb)
+\- tar-archive: [https://pingpanel.zweiernet.ch/pingpanel_latest.tar.gz](https://pingpanel.zweiernet.ch/pingpanel_latest.tar.gz)   
+\- Debian installer: [https://pingpanel.zweiernet.ch/pingpanel_latest_all.deb](https://pingpanel.zweiernet.ch/pingpanel_latest_all.deb)
 
 
 **_Requirements_**:

+ 8 - 3
changelog

@@ -8,11 +8,16 @@ v0.9.7 / 30.7.24, sigi:
 	
 v0.9.8 / 12.8.24, sigi:
 	- implementing secure HTTPS connections on both, webserver and websocket.
-	- Added HTTPS params in config.cfg.
+	- New HTTPS params in config.cfg.
 	- Changed: 'Title' param renamed to 'TitleAdd' in config.cfg as it is now an addendum to the title.
 	
 v0.9.9 / 1.4.25, sigi:
 	- Corr: configfile handling.
-	- Added: fping parameter --size can now be set in PingPanel's config.cfg.
-
+	- New: fping parameter --size can now be set in PingPanel's config.cfg.
 
+v0.9.11 / 17.4.25, si:
+	- New:	- improved debug (-v) output to fiddle better with timing parameters
+			- Consolidated status information on sections more readable
+			- Host specific tooltip now has a "since" time info
+	- Corr:	- anim_red image loop now infinite
+