Python通过SNMP监控网络设备

前段时间,为了实现自动化巡检,我开发了自动化巡检工具,由于我的系统设备版本比较多,所以我是分别开发的客户端程序,服务端使用dll文件与客户端通信,服务端的dll在与python通信,通过Python丰富的第三方库,实现绘图入库等,该方式比较繁琐,我们管理的设备还有一些网络设备,这些设备无法通过开发程序来实现监控,为了实现全平台全设备监控,我决定使用SNMP实现监控任务。

SNMP是简单的网络管理协议,该协议非常古老但至今仍然被广泛应用在数据采集上,目前SNMP协议被所有的网络设备和网络管理应用广泛支持,完全做到的全平台兼容,使用它我们可以收集任何设备的任何数据。

以前我喜欢直接调用snmpwalk命令来实现数据的采集,这种方式效率太低了,所以我放弃了,代码先发出来留档,后面我们使用pysnmp来做。

通过SNMP收集主机CPU利用率 通过SNMP协议,收集目标主机的CPU利用率(百分比),并返回JSON字符串.

import os,re,time

def Get_CPU_Info(addr):
    try:
        Head = ["HostName","CoreLoad","CpuUser","CpuSystem","CpuIdle"]
        CPU = []
        ret = os.popen("snmpwalk -v 2c -c nmap " + addr + " .1.3.6.1.2.1.1.5")
        CPU.append(ret.read().split(":")[3].strip())
        ret = os.popen("snmpwalk -v 2c -c nmap " + addr + " .1.3.6.1.2.1.25.3.3.1.2")
        CPU.append(ret.read().split(":")[3].strip())

        for i in [9,10,11]:
            ret = os.popen("snmpwalk -v 2c -c nmap " + addr + " 1.3.6.1.4.1.2021.11.{}.0".format(i))
            ret = ret.read()
            Info = ret.split(":")[3].strip()
            CPU.append(Info)
        return dict(zip(Head,CPU))
    except Exception:
        return 0

if __name__ == '__main__':
    for i in range(100):
        dic = Get_CPU_Info("192.168.1.20")
        print(dic)
        time.sleep(1)

通过SNMP获取系统CPU负载信息 分别获取到系统的1,5,15分钟的负载信息,并返回JSON格式.

import os,re,time

def Get_Load_Info(addr):
    try:
        Head = ["HostName","Load1","Load5","Load15"]
        SysLoad = []
        ret = os.popen("snmpwalk -v 2c -c nmap " + addr + " .1.3.6.1.2.1.1.5")
        SysLoad.append(ret.read().split(":")[3].strip())

        ret = os.popen("snmpwalk -v 2c -c nmap " + addr + " .1.3.6.1.4.1.2021.10.1.3")
        load = list(re.sub(".*STRING: ", "", ret.read()).split("\n"))
        SysLoad.append(load[0])
        SysLoad.append(load[1])
        SysLoad.append(load[2])
        return dict(zip(Head,SysLoad))
    except Exception:
        return 0

if __name__ == '__main__':
    dic = Get_Load_Info("192.168.1.20")
    print(dic)

通过SNMP获取系统内存占用 内存利用率,获取到之后,将其转化为字典格式保存。

import os,re,time

def Get_Mem_Info(addr):
    try:
        Head = ["HostName","memTotalSwap","memAvailSwap","memTotalReal","memTotalFree"]
        SysMem = []
        ret = os.popen("snmpwalk -v 2c -c nmap " + addr + " .1.3.6.1.2.1.1.5")
        SysMem.append(ret.read().split(":")[3].strip())
        ret = os.popen("snmpwalk -v 2c -c nmap " + addr + " .1.3.6.1.4.1.2021.4")
        mem = ret.read().split("\n")
        for i in [2,3,4,6]:
            SysMem.append(re.sub(".*INTEGER: ","",mem[i]).split(" ")[0])
        return dict(zip(Head,SysMem))
    except Exception:
        return 0

if __name__ == '__main__':
    dic = Get_Mem_Info("192.168.1.20")
    print(dic)

通过SNMP获取系统磁盘数据 这个案例并不完整,我只写了一点,后面有个问题一直没有解决.

import os,re,time

def Get_Disk_Info(addr):
    try:
        dic = {}
        list = []
        ret = os.popen("snmpwalk -v 2c -c nmap " + addr + " HOST-RESOURCES-MIB::hrStorageDescr")
        DiskName = ret.read().split("\n")
        ret =os.popen("snmpwalk -v 2c -c nmap " + addr + " HOST-RESOURCES-MIB::hrStorageUsed")
        DiskUsed = ret.read().split("\n")
        ret = os.popen("snmpwalk -v 2c -c nmap " + addr + " HOST-RESOURCES-MIB::hrStorageSize")
        DiskSize = ret.read().split("\n")

        for i in range(1,len(DiskName) - 7):
            dic["Name"]= DiskName[i + 5].split(":")[3]
            dic["Used"]= DiskUsed[i + 5].split(":")[3]
            dic["Size"]= DiskSize[i + 5].split(":")[3]
            list.append(dic)
        return list
    except Exception:
        return 0

if __name__ == '__main__':
     list = Get_Disk_Info("192.168.1.20")
     print(list)

接下来,我们使用pysnmp模块来做,安装pysnmp很简单,执行命令pip install pysnmp即可,安装后,使用以下代码执行即可获取到目标数据,网上的那些转载的都是坑,没一个能用的,这个案例是官方案例,可以使用。

from pysnmp.hlapi import *

iterator = getCmd(SnmpEngine(),
                  CommunityData('public'),
                  UdpTransportTarget(('192.168.1.113', 161)),
                  ContextData(),
                  ObjectType(ObjectIdentity('SNMPv2-MIB', 'sysDescr', 0)))

errorIndication, errorStatus, errorIndex, varBinds = next(iterator)

if errorIndication:
    print(errorIndication)
else:
    if errorStatus:
        print('%s at %s' % (errorStatus.prettyPrint(), varBinds[int(errorIndex)-1] if errorIndex else '?'))
    else:
        for varBind in varBinds:
            print(' = '.join([x.prettyPrint() for x in varBind]))

首先我们以一个OID序号为例,我们查询特定序号对应的名称,然后将其记录下来,例如下面这样。

在客户机上面,需要在服务列,开启SNMP支持,并设置好一个团体名称,如下图。

然后我们简单的封装一个类,先来测试一下是否能通。

# snmpwalk -v 2c -c public 192.168.1.113 .1.3.6.1.2.1.1.5
from pysnmp.hlapi import *

class NetSNMP():
    def __init__(self,address,region):
        self.region = region
        self.address = address

    # 获取指定数据的方法
    def GetNumber(self,oid,sub_oid,sub_id):
        iterator = getCmd(SnmpEngine(),
                          CommunityData(self.region),
                          UdpTransportTarget((self.address, 161)),
                          ContextData(),
                          ObjectType(ObjectIdentity(oid, sub_oid, sub_id)))
        errorIndication, errorStatus, errorIndex, varBinds = next(iterator)

        if errorIndication:
            return False
        else:
            if errorStatus:
                return False
            else:
                for varBind in varBinds:
                    return [x.prettyPrint() for x in varBind]

if __name__ == "__main__":

    # 初始化
    ptr = NetSNMP("192.168.1.101","public")

    # 设置OID数据集
    ret = ptr.GetNumber("HOST-RESOURCES-MIB","hrMemorySize",0)
    print("类型: {} --> 返回结果: {} --> 解析: {}".format(type(ret),ret,ret[1]))

运行后,即可读取到内存数据,如下。

未完待续

(0)

相关推荐

  • 你可能也会遇到:低级bug耗费12小时Fix

    调试某程序非常简单的程序,简单到认为不可能存在缺陷,但该BUG处理时间超过12小时:程序属于后台进程,监控系统每隔15秒检查外设IO状态,IO异常后发出报警或复位外设,外设都在linux下有/sys/ ...

  • SNMP监控OID总结

    https://www.cnblogs.com/tianxiafeiyu/p/13597010.html 系统信息 iso(1) identified-organization(3) dod(6) i ...

  • 用 Python 监控 NASA TV 直播画面

    演示地址: https://replit.com/@PaoloAmoroso/spacestills 在Replit上运行的Spacestills主窗口 这是一个具有GUI的简单系统,它访问feed流 ...

  • 用Python做了一个 ''盯盘机器人'',股票价格实时监控,还能邮件通知你!

    Python凭借其开发效率高和功能强大的特性,在众多编程语言中脱颖而出,成为大数据时代的分析利器. 据我多年的领悟,编程语言只是一种按照人的意图去实现特定功能的高效工具而已,程序化所实现的核心决策功能 ...

  • 神器推荐!一个能监控文件变化的Python神器—看门狗

    Python爱好者社区 2021-08-07 以下文章来源于Python实用宝典 ,作者Ckend 来源于Python实用宝典 作者Ckend 假设现在有一个应用场景,需要对文件系统进行监控,发生变化 ...

  • Python对系统数据进行采集监控——psutil

    大家好,我是辰哥- 今天给大家介绍一个可以获取当前系统信息的库--psutil 利用psutil库可以获取系统的一些信息,如cpu,内存等使用率,从而可以查看当前系统的使用情况,实时采集这些信息可以达 ...

  • 2022年起,AMSA将为船只提供24小时HF监控服务

    从2022年1月1日起,AMSA将在澳大利亚提供24小时全国范围的高频(HF)无线电话船只遇险.紧急情况和安全通信监控. HF无线电话是VHF岸站范围以外的船只与其他船只和岸站发送和接收遇险和海上安全 ...

  • 13岁男孩被困电梯自救失败坠亡!监控记录心痛一幕…

    5月3日,福建福州一小区电梯故障,一13岁男孩在自救过程中坠落身亡.当地社区主任称,通过监控发现该男孩曾按求助按钮,因按钮失效没有接通物业处.目前,警方介入调查. 5月3日,福建福州,一名13岁男孩带 ...

  • 大华网络视频监控图像卡顿分析思路和案例总结

    一.理清楚视频卡顿分析思路 1.IPC设备跟电脑直连都卡顿(排除网线和电脑问题)用VLC和WEB,SDK测试DEMO都验证过卡顿.那后续就不用排查其它问题,直接联系研发进行问题处理. 2.直连测试正常 ...

  • Python|二叉树叶子结点问题解决方法

    问题描述键盘输入一颗二叉树,求解其叶子结点个数.示例: 输入:4,2,6,1,3,5输出:3解决方案一棵树当中没有子结点(即度为0)的结点称为叶子结点,简称"叶子".当二叉树为空时 ...