2020INTERVAL = 1
2121
2222import socket
23+ import ssl
2324import time
2425import timeit
2526import re
2930import errno
3031import subprocess
3132import threading
32- try :
33- from queue import Queue # python3
34- except ImportError :
35- from Queue import Queue # python2
33+ if sys . version_info . major == 3 :
34+ from queue import Queue
35+ elif sys . version_info . major == 2 :
36+ from Queue import Queue
3637
3738def get_uptime ():
3839 with open ('/proc/uptime' , 'r' ) as f :
@@ -150,6 +151,7 @@ def get_network(ip_version):
150151 'read' : 0 ,
151152 'write' : 0
152153}
154+ monitorServer = {}
153155
154156def _ping_thread (host , mark , port ):
155157 lostPacket = 0
@@ -314,6 +316,97 @@ def get_realtime_data():
314316 ti .daemon = True
315317 ti .start ()
316318
319+
320+ def _monitor_thread (name , host , interval , type ):
321+ lostPacket = 0
322+ packet_queue = Queue (maxsize = PING_PACKET_HISTORY_LEN )
323+ while True :
324+ if name not in monitorServer .keys ():
325+ monitorServer [name ] = {
326+ "type" : type ,
327+ "dns_time" : 0 ,
328+ "connect_time" : 0 ,
329+ "download_time" : 0 ,
330+ "online_rate" : 1
331+ }
332+ if packet_queue .full ():
333+ if packet_queue .get () == 0 :
334+ lostPacket -= 1
335+ try :
336+ if type == "http" :
337+ address = host .replace ("http://" , "" )
338+ m = timeit .default_timer ()
339+ if PROBE_PROTOCOL_PREFER == 'ipv4' :
340+ IP = socket .getaddrinfo (address , None , socket .AF_INET )[0 ][4 ][0 ]
341+ else :
342+ IP = socket .getaddrinfo (address , None , socket .AF_INET6 )[0 ][4 ][0 ]
343+ monitorServer [name ]["dns_time" ] = int ((timeit .default_timer () - m ) * 1000 )
344+ m = timeit .default_timer ()
345+ k = socket .create_connection ((IP , 80 ), timeout = 6 )
346+ monitorServer [name ]["connect_time" ] = int ((timeit .default_timer () - m ) * 1000 )
347+ m = timeit .default_timer ()
348+ k .sendall ("GET / HTTP/1.2\r \n Host:{}\r \n Connection:close\r \n \r \n " .format (address ).encode ('utf-8' ))
349+ response = b""
350+ while True :
351+ data = k .recv (4096 )
352+ if not data :
353+ break
354+ response += data
355+ http_code = response .decode ('utf-8' ).split ('\r \n ' )[0 ].split ()[1 ]
356+ monitorServer [name ]["download_time" ] = int ((timeit .default_timer () - m ) * 1000 )
357+ k .close ()
358+ if http_code not in ['200' , '204' , '301' , '302' , '401' ]:
359+ raise Exception ("http code not in 200, 204, 301, 302, 401" )
360+ elif type == "https" :
361+ context = ssl ._create_unverified_context ()
362+ address = host .replace ("https://" , "" )
363+ m = timeit .default_timer ()
364+ if PROBE_PROTOCOL_PREFER == 'ipv4' :
365+ IP = socket .getaddrinfo (address , None , socket .AF_INET )[0 ][4 ][0 ]
366+ else :
367+ IP = socket .getaddrinfo (address , None , socket .AF_INET6 )[0 ][4 ][0 ]
368+ monitorServer [name ]["dns_time" ] = int ((timeit .default_timer () - m ) * 1000 )
369+ m = timeit .default_timer ()
370+ k = socket .create_connection ((IP , 443 ), timeout = 6 )
371+ monitorServer [name ]["connect_time" ] = int ((timeit .default_timer () - m ) * 1000 )
372+ m = timeit .default_timer ()
373+ kk = context .wrap_socket (k , server_hostname = address )
374+ kk .sendall ("GET / HTTP/1.2\r \n Host:{}\r \n Connection:close\r \n \r \n " .format (address ).encode ('utf-8' ))
375+ response = b""
376+ while True :
377+ data = kk .recv (4096 )
378+ if not data :
379+ break
380+ response += data
381+ http_code = response .decode ('utf-8' ).split ('\r \n ' )[0 ].split ()[1 ]
382+ monitorServer [name ]["download_time" ] = int ((timeit .default_timer () - m ) * 1000 )
383+ kk .close ()
384+ k .close ()
385+ if http_code not in ['200' , '204' , '301' , '302' , '401' ]:
386+ raise Exception ("http code not in 200, 204, 301, 302, 401" )
387+ elif type == "tcp" :
388+ m = timeit .default_timer ()
389+ if PROBE_PROTOCOL_PREFER == 'ipv4' :
390+ IP = socket .getaddrinfo (host .split (":" )[0 ], None , socket .AF_INET )[0 ][4 ][0 ]
391+ else :
392+ IP = socket .getaddrinfo (host .split (":" )[0 ], None , socket .AF_INET6 )[0 ][4 ][0 ]
393+ monitorServer [name ]["dns_time" ] = int ((timeit .default_timer () - m ) * 1000 )
394+ m = timeit .default_timer ()
395+ k = socket .create_connection ((IP , int (host .split (":" )[1 ])), timeout = 6 )
396+ monitorServer [name ]["connect_time" ] = int ((timeit .default_timer () - m ) * 1000 )
397+ m = timeit .default_timer ()
398+ k .send (b"GET / HTTP/1.2\r \n \r \n " )
399+ k .recv (1024 )
400+ monitorServer [name ]["download_time" ] = int ((timeit .default_timer () - m ) * 1000 )
401+ k .close ()
402+ packet_queue .put (1 )
403+ except Exception as e :
404+ lostPacket += 1
405+ packet_queue .put (0 )
406+ if packet_queue .qsize () > 5 :
407+ monitorServer [name ]["online_rate" ] = 1 - float (lostPacket ) / packet_queue .qsize ()
408+ time .sleep (interval )
409+
317410def byte_str (object ):
318411 '''
319412 bytes to str, str to bytes
@@ -360,6 +453,20 @@ def byte_str(object):
360453 if data .find ("You are connecting via" ) < 0 :
361454 data = byte_str (s .recv (1024 ))
362455 print (data )
456+ for i in data .split ('\n ' ):
457+ if "monitor" in i and "type" in i and "{" in i and "}" in i :
458+ jdata = json .loads (i [i .find ("{" ):i .find ("}" )+ 1 ])
459+ t = threading .Thread (
460+ target = _monitor_thread ,
461+ kwargs = {
462+ 'name' : jdata .get ("name" ),
463+ 'host' : jdata .get ("host" ),
464+ 'interval' : jdata .get ("interval" ),
465+ 'type' : jdata .get ("type" )
466+ }
467+ )
468+ t .daemon = True
469+ t .start ()
363470
364471 timer = 0
365472 check_ip = 0
@@ -378,7 +485,6 @@ def byte_str(object):
378485 Load_1 , Load_5 , Load_15 = os .getloadavg ()
379486 MemoryTotal , MemoryUsed , SwapTotal , SwapFree = get_memory ()
380487 HDDTotal , HDDUsed = get_hdd ()
381-
382488 array = {}
383489 if not timer :
384490 array ['online' + str (check_ip )] = get_network (check_ip )
@@ -412,7 +518,7 @@ def byte_str(object):
412518 array ['tcp' ], array ['udp' ], array ['process' ], array ['thread' ] = tupd ()
413519 array ['io_read' ] = diskIO .get ("read" )
414520 array ['io_write' ] = diskIO .get ("write" )
415-
521+ array [ 'custom' ] = "<br>" . join ( f"<code> { k } </code> \\ t解析: { v [ 'dns_time' ] } \\ t连接: { v [ 'connect_time' ] } \\ t下载: { v [ 'download_time' ] } \\ t在线率: <code> { v [ 'online_rate' ] * 100 } %</code>" for k , v in monitorServer . items ())
416522 s .send (byte_str ("update " + json .dumps (array ) + "\n " ))
417523 except KeyboardInterrupt :
418524 raise
0 commit comments