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 结语

运行状况:

1468668339

用起来挺方便的,倒是丢包率与阀值比较那里不是太理想。我想要不要将丢包率的平均值与阀值比较,而不是最大值。

这脚本的运行环境是Mac OS X,如果你想在Linux 下运行,可能需要做些修改。

完整的脚本可以点击下面的链接跳转到Github查看下载:

website_status_monitor