工作之余,为了方便,继续完善了网络监测程序(:

1、监测端:c#开发,目前实现了设备维护,监测,比如ping,snmp特性监测,模拟telnet等, 发现设备故障时可以二次验证,可以自由拓展,监测速度快,结果进日志及统计,同时第一时间短信及邮件通知维护人员。

2、订阅者:第一次用python增加了监控中心 订阅者,可以实时监视各 监测软件运行情况。

整体思路及效果,python订阅者代码分享

python Telemetry 网络设备监控指标采集_机器人 监测 巡检 c# python

python Telemetry 网络设备监控指标采集_数据_02

#!/usr/bin/env python3
# -*- coding:utf-8 -*-

"""
网络巡检程序消息订阅程序
ver:3.0
"""

__author__ = 'wyw308'
__date__ = '2018.11.18'

import socket,winsound
import sys,os,time
import configparser
from threading import Timer
import threading

s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)  # 定义全局订阅通道s,ipv4  SOCK_DGRAM指定了这个Socket的类型是UDP
s_cmd = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)  # cmd通道
orderMode = 'err'  # 输出显现类型,all全部,err只显示告警信息


def send_msg(ip, port, msg):
    """发送数据到对应的ip和端口,在订阅通道接收返回数据"""
    s.sendto(msg.encode(), (ip, int(port)))
    return s.recv(1024).decode()


def send_cmd(ip, port, msg):
    """发送命令到对应的ip和端口,在随机通道(非订阅通道)接收返回数据"""
    s_cmd.sendto(msg.encode(), (ip, int(port)))
    return s_cmd.recv(1024).decode()


def talk_serv(pra):
    """ 根据配置文件,自动从远端服务器注册,订阅消息 """
    config = configparser.ConfigParser()
    config.read('order.conf', encoding='UTF-8')
    order_from = config.get('db', 'orderFrom')

    data = order_from.split(',')
    for d in data:
        if pra == 'hello-connect':
            print('--> '+check_data(send_msg(d.split(':')[0], d.split(':')[1], pra)), flush=True)
        else:
            print('--> '+check_data(send_cmd(d.split(':')[0], d.split(':')[1], pra)), flush=True)


def get_host_ip():
    """ 查询返回本机ip地址 """
    try:
        s_ip = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        s_ip.connect(('8.8.8.8', 80))
        ip = s_ip.getsockname()[0]
    finally:
        s_ip.close()
    return ip


def check_data(d):
    """格式化各服务端的返回数据"""
    if d.find('新发现故障') >= 0 or d.find('错误') >= 0:
        winsound.PlaySound('err.wav', winsound.SND_FILENAME)
        d = '\033[1;31;40m{0} \033[0m'.format(d)
    elif d.find('故障持续') >= 0:
        winsound.PlaySound('err.wav', winsound.SND_FILENAME)
        d = '\033[1;33;40m{0} \033[0m'.format(d)
    elif d.find('网络已恢复') >= 0:
        winsound.PlaySound('shake.wav', winsound.SND_FILENAME)
        d = '\033[1;32;40m{0} \033[0m'.format(d)
    elif d.find('共') >= 0:
        d = '\033[1;37;42m{0} \033[0m'.format(d)
    else:
        d = '\033[0;37m{0} \033[0m'.format(d)
    return d


def init_server():
    """ 初始化软件,一些初始设置及与服务器交互约定 """
    global orderMode
    while True:
        data = input('Enter reg:')
        if data == 'quit':
            print('\r\n\033[0;31m开始接收数据.... \033[0m', flush=True)
            break
        elif data == 'orderMode=all':
            orderMode = 'all'
            print('订阅模式orderMode={0}'.format(orderMode), flush=True)
        elif data == 'orderMode=err':
            orderMode = 'err'
            print('订阅模式orderMode={0}'.format(orderMode), flush=True)
        elif len(data.split(':')) == 3:
            data = data.split(':')
            print(data[0], data[1], data[2])
            print(send_msg(data[0], data[1], data[2]), flush=True)
        else:
            print('命令[{0}]错误,请检查。'.format(data), flush=True)


def run_order():
    """ 开始执行订阅主功能 """
    print('--> {0}:线程启动:开始执行订阅主功能,orderMode={1}'.format(time.strftime("%H:%M:%S"), orderMode), flush=True)
    min_num = 0
    max_num = 99999999
    bar = ProgressBar(count=min_num, total=max_num, width=40)
    animation = ['-', '\\', '|', '/']
    count = 0
    while True:
        count += 1
        data, address = s.recvfrom(1024)  # 返回数据和客户端的地址与端口
        d = check_data(data.decode())
        if orderMode == 'err':  # 只输出错误模式
            if d.find('新发现故障') >= 0 or d.find('错误') >= 0 or d.find('异常') >= 0 or d.find('故障持续') >= 0 \
                    or d.find('网络已恢复') >= 0 or d.find('共:') >= 0 or d.find('- - -') >= 0:
                bar.move()
                bar.log('--> {0}'.format(d))
            else:
                print('\r{0}'.format(' '*100), end='')  # 首先在当前行输出100个空格,清空内容,'\r'表示不换行回到最左边
                print('\r{0}--> {1}'.format(animation[count % 4], d), end='')  # 不换行
                print('\r', end='', flush=True)  # 将光标移动到左端,不换行,刷新输入
        else:
            bar.move()
            bar.log('--> {0}'.format(d))
    s.close()


def loop_check_heart(pra):
    """ 定时检查服务是否正常 """
    print('--> {0}:线程启动:定时任务自启动循环检查服务是否正常'.format(time.strftime("%H:%M:%S")), flush=True)
    talk_serv(pra)
    Timer(480, loop_check_heart, ('hello-heart',)).start()


def print_help():
    welcome = '''欢迎使用网络监测程序订阅端,作者:wyw308 by/2018.11.18
    
    python app.py --run app
    Enter reg: remoteIp:port:hello-connect --order msg from remoteServer
    Enter reg: remoteIp:port:hello-close   --undo order from remoteServer
    Enter reg: quit                        --run at recive msg mode
    Enter reg: orderMode=all  or err       --recive mode,defalt is err mode
    
    '''
    print(welcome)


class ProgressBar:
    # 进度条类
    def __init__(self, count=0, total=0, width=50):
        self.count = count
        self.total = total
        self.width = width

    def move(self):
        self.count += 1

    def log(self, s):
        sys.stdout.write(' ' * (self.width + 9) + '\r')
        sys.stdout.flush()
        sys.stdout.write(s + '\r\n')
        progress = self.width * self.count / self.total
        sys.stdout.write('+消息订阅[{0}]:{1:3}/{2:3}:'.format(time.strftime("%H:%M:%S"),self.count, self.total))
        sys.stdout.write('#' * int(progress) + '-' * int((self.width - progress))+ '\r')
        if progress == self.width:
            sys.stdout.write('\n')
        sys.stdout.flush()


def main():
    os.system('')  # 在执行完system()之后,win10转移序列都会生效,原因未知
    print_help()

    ip = get_host_ip()  # 本机IP
    # ip='10.17.90.79'
    port = 6283       # 监听端口

    s.bind((ip, port))  # 绑定 客户端口和地址
    print('\033[0;32m Bind UDP on {0}:{1}...\033[0m'.format(ip, port), flush=True)
    
    init_server() 
    talk_serv('hello-connect')
    loop_check_heart('hello-heart')

    t2 = threading.Thread(target=run_order)
    t2.start()
    t2.join()


if __name__ == '__main__':
    main()