python实现,通过ping监控主机状态

简单用python实现了一段监控主机状态的代码,有两个线程,一个线程负责执行ping,将ping的结果保存在主进程的LIST中,另一线程负责检查该结果,并在检测到主机状态变化时执行其它操作,比如发送邮件报警等。有两种情况会认为主机down了,一是当连续5个ping包都timeout时;二是在20次ping 中有10个timeout时,后者主要目的在于当主机线路出现抖动(时通时断)时也认为主机不可用了;在主机处于down状态时,连继5次ping包都正常,则将主机状态恢复为up。

目前该脚本还有些不足,threading创建多个线程后,发送给主进程的SIGINT信号都被阻塞了,所以ctrl+c不能中止程序,要直接kill掉才行,正在想法解决。
以上问题已经解决,将子线程设置为Daemon,主进程不再被子线程阻塞,可以正常接收信号。为保证主进程不退出,使用一个判断子线程是否存活的循环,子线程中增加判断全局的一个标记,如果标记为True则结束并退出,主进程收到ctrl+c的信号后,将全局的标记设置为True,子线程退出,主进程检测到线程没有存活也就退出。

在我们实际应用中,主机状态发生变化执行操作是邮件通知和修改三层交换机默认网关,两个功能也是通过python来实现的,目前代码很不整洁,待整理后放出。

脚本执行需要ping模块,到这里下载,将ping.py和以下脚本文件放到同一目录即可。

#!/usr/bin/env python
 
import time,threading,sys
from ping import *
import signal
 
ping_timeout=2
status_last=True
status_list=[ 1 for i in range(0,20) ]
dest_ip=''
tread_exit=False

def thread_exit(a,b):
    global tread_exit
    tread_exit=True

    

def ping_check(dest_addr):
    global status_list
    global dest_ip
    global tread_exit
    dest_ip=dest_addr
    while not tread_exit:
        print "ping %s with ..." % dest_addr ,
        try:
            delay  =  do_one(dest_addr, ping_timeout, 64)
        except Exception,err:
            print err
            print "Network error" 
            time.sleep(1)
            continue
        if delay  ==  None:
            status_list.insert(0,0)
            status_list.pop()
            print "failed. (timeout within %ssec.)" % ping_timeout
        else:
            delay  =  delay * 1000
            status_list.insert(0,1)
            status_list.pop()
            print "get ping in %0.4fms" % delay
            time.sleep(1)
 
def check_status():
    global status_list
    global status_last
    global dest_ip
    global tread_exit
    status_changed=False
    status_list_copy=status_list
    while not tread_exit:
        if status_list_copy[:5].count(1)==5:
            status_now=True
        elif status_list_copy[:5].count(0)==5 or status_list_copy.count(0)==10:
            status_now=False
        if status_now!=status_last:
            status_changed=True
        else:
            status_changed=False
        status_last=status_now
        if status_changed==True:
            if status_now==False:
                print dest_ip,"status to Down"
            elif status_now==True:
                print dest_ip,"status to Up"
        #print 'now status is: ', status_now
        time.sleep(0.3)
 
if __name__ == '__main__':
    signal.signal(signal.SIGINT,thread_exit)
    th_ping=threading.Thread(target=ping_check,args=("10.0.0.1",))
    th_status=threading.Thread(target=check_status)
    th_ping.setDaemon(True)
    th_status.setDaemon(True)
    th_ping.start()
    th_status.start()
    while th_ping.isAlive() or th_status.isAlive():
        time.sleep(1)

python实现,通过ping监控主机状态》有5个想法

  1. 林刚

    我需要使用python实现ping功能,好像这个ping使用了socket.SOCK_RAW需要root权限的,不知道你那里是不是有这个问题?

    回复

发表评论

您的电子邮箱地址不会被公开。 必填项已用*标注

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据