0x01 前言
在平常的工作中,我们都很注重服务器的在线率。在最近的时间里我用python 写了一个脚本,也能借此机会学习python 。
代码可能比较长,而我的程序也分成两部分,所以我将分开两篇文章来写,你可以在文章底部找到另一篇文章的地址与完整的python 文件。
0x02 思路
我想通过定时ping 服务器的IP 地址来确认网络是否有丢包或延迟过高的情况。如果丢包率与延迟都超过了我设置的阀值,将调用Mac OS X 的音乐播放器,播放一首音乐或者警告音来提醒我。
如果我有很多服务器或有很多IP 地址,那么修改、使用岂不是很麻烦?要是我想将脚本分享给大家参考,要是脚本里含有我服务器的地址,岂不是不安全?因此我将脚本写成可通过参数传递的模式。而第二篇文章就是一个调用这篇文章里所说的脚本的一个说明。
我这脚本的使用方式如下:
python3 website_status_monitor.py [-h help] [-i server_ipaddr] [-n server_name]
0x03 源代码
0x03.1 导入模块 & 设定变量
import getopt import os import sys # ping包数,整数 ping_packet_count = 10 # 丢包率(%),请勿添加单位,浮点数 packetloss_percentage = 10.0 # 延迟(ms),请勿添加单位,浮点数 latency_max = 40.0
0x03.2 获取传入的参数
#定义main 函数 def main(argv): #将server_ipaddr 设为全局变量 global server_ipaddr #将server_name 设为全局变量 global server_name #初始化server_ipaddr server_ipaddr = '' #初始化server_ipaddr server_name = '' #使用try 捕捉异常 try: #args: 要解析的命令行参数列表。 # #options: 以字符串的格式定义,options后的冒号(:)表示该选项必须有附加的参数, ##不带冒号表示该选项不附加参数。 # #long_options: 以列表的格式定义,long_options 后的等号(=)表示如果设置该选项, ##必须有附加的参数,否则就不附加参数。 # #该方法返回值由两个元素组成: 第一个是 (option, value) 元组的列表。 ##第二个是参数列表,包含那些没有'-'或'--'的参数。 opts, args = getopt.getopt(argv, "hi:n:", ["iipaddr=", "nname="]) #在没有找到参数列表,或选项的需要的参数为空时会触发该异常。 except getopt.GetoptError: #输出错误 print('test.py -i <ipaddr> -n <name>') #通过命令行返还错误 sys.exit(2) #使用历遍获取参数 for opt, arg in opts: if opt == '-h': print('test.py -i <ipaddr> -n <name>') sys.exit() elif opt in ("-i", "--ipaddr"): server_ipaddr = arg elif opt in ("-n", "--name"): server_name = arg #调用main 函数 if __name__ == "__main__": main(sys.argv[1:])
0x03.3 获取ping 结果
#使用popen 调用系统shell #通过readlines 获取shell 以列表形式返还的内容 ping_result = os.popen( 'ping -c ' + str(ping_packet_count) + ' -t ' + str(ping_packet_count) + ' ' + server_ipaddr).readlines()
0x03.4 预处理
#获取元素数量,如果全丢包,元素数为4,否则大于4 result_list_count = len(ping_result) #获取数值并以空格为分隔符重新构建列表 ping_packetloss_output_list = ping_result[-2].split(' ') #获取丢包率并将百分号%去除 ping_packetloss_percentage = ping_packetloss_output_list[-3].strip('%') #构造丢包输出字符串 ping_packetloss_percentage_output = 'packetloss = ' + str(ping_packetloss_percentage) + '%' #获取延迟最小、平均、最大和方差值并以空格为分隔符重新构建列表 round_trip_list = ping_result[-1].split(' ') #将上面构建的列表取出第4个元素,并以/为分隔符重新构建列表 round_trip_values = round_trip_list[3].split('/') #将最大值设为浮点数,以便后面进行比较操作 ping_max_value = float(round_trip_values[2])
0x3.5 内容输出函数
#定义函数,名为ping_result_output且不需要输入参数 def ping_result_output(): #延迟最小值 ping_min = 'ping_min = ' + str(round_trip_values[0]) #延迟平均值 ping_avg = 'ping_avg = ' + str(round_trip_values[1]) #延迟最大值 ping_max = 'ping_max = ' + str(round_trip_values[2]) #延迟标准差 ping_stddev = 'ping_stddev = ' + str(round_trip_values[3]) #获取现在的时间 date_now = str(os.popen('date').readline()) #打印上面的内容 print( '-' * 25 + server_name + '-' * 25 + ' ' + date_now + ping_min + ' ' + ping_avg + ' ' + ping_max + ' ' + ping_stddev + ' ' + ping_packetloss_percentage_output) return ping_result_output
0x03.6 判断与打印结果
#如果全丢包,则result_list_count 为4,若符合则打印错误并通过shell 启动afplay 播放音乐 if result_list_count <= 4: ping_result_output() print('server ' + server_name + ' is down!') os.popen('afplay /Users/terence/Music/QQ音乐/Austin\ Mahone\,Pitbull-Mmm\ Yeah.mp3') #如果ping_packetloss_percentage 超过阀值则打印错误并通过shell 启动afplay 播放音乐 elif float(ping_packetloss_percentage) >= float(packetloss_percentage): ping_result_output() print('The ' + server_name + ' network packet lossis is more then ' + str(packetloss_percentage) + '%! packetloss!') os.popen('afplay /Users/terence/Music/QQ音乐/Austin\ Mahone\,Pitbull-Mmm\ Yeah.mp3') #若ping_max_value 超过阀值则打印错误并通过shell 启动afplay 播放音乐 elif ping_max_value >= float(latency_max): ping_result_output() print('The ' + server_name + ' network latency is more then ' + str(latency_max) + 'ms! High network latency!') os.popen('afplay /Users/terence/Music/QQ音乐/Austin\ Mahone\,Pitbull-Mmm\ Yeah.mp3') #正常则近打印信息 else: ping_result_output()
0x04 结语
运行状况:
用起来挺方便的,倒是丢包率与阀值比较那里不是太理想。我想要不要将丢包率的平均值与阀值比较,而不是最大值。
这脚本的运行环境是Mac OS X,如果你想在Linux 下运行,可能需要做些修改。
完整的脚本可以点击下面的链接跳转到Github查看下载: