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查看下载:























