前段时间,为了实现自动化巡检,我开发了自动化巡检工具,由于我的系统设备版本比较多,所以我是分别开发的客户端程序,服务端使用dll文件与客户端通信,服务端的dll在与python通信,通过Python丰富的第三方库,实现绘图入库等,该方式比较繁琐,我们管理的设备还有一些网络设备,这些设备无法通过开发程序来实现监控,为了实现全平台全设备监控,我决定使用SNMP实现监控任务。
首先需要在系统中安装SNMP客户端,对于Linux平台来说只需要执行如下配置过程即可.
[root@localhost~]#yuminstall-ynet-snmp [root@localhost~]#cat/etc/snmp/snmpd.conf|grep-vE"^#|^$" com2secnotConfigUserdefaultpublic groupnotConfigGroupv1notConfigUser groupnotConfigGroupv2cnotConfigUser viewsystemviewincluded.1 viewsystemviewincluded.1 accessnotConfigGroup""anynoauthexactsystemviewnonenone [root@localhost~]#systemctlrestartsnmpd [root@localhost~]#systemctlenablesnmpd
如果是Windows系统则需要在客户机服务列表,开启SNMP支持,并设置好一个团体名称,如下图。

当我们配置好客户端后,服务端就客户获取数据了,我们以一个OID序号为例,我们查询特定序号对应的名称,然后将其记录下来,例如下面这样。

首先我们不适用PySNMP模块直接开线程调用看看,该代码如下所示.
importos,re,time #通过SNMP收集主机CPU利用率:通过SNMP协议,收集目标主机的CPU利用率(百分比),并返回JSON字符串. defGet_CPU_Info(addr): try: Head=["HostName","CoreLoad","CpuUser","CpuSystem","CpuIdle"] CPU=[] ret=os.popen("snmpwalk-v2c-cnmap"+addr+".1.3.6.1.2.1.1.5") CPU.append(ret.read().split(":")[3].strip()) ret=os.popen("snmpwalk-v2c-cnmap"+addr+".1.3.6.1.2.1.25.3.3.1.2") CPU.append(ret.read().split(":")[3].strip()) foriin[9,10,11]: ret=os.popen("snmpwalk-v2c-cnmap"+addr+"1.3.6.1.4.1.2021.11.{}.0".format(i)) ret=ret.read() Info=ret.split(":")[3].strip() CPU.append(Info) returndict(zip(Head,CPU)) exceptException: return0 #通过SNMP获取系统CPU负载信息:分别获取到系统的1,5,15分钟的负载信息,并返回JSON格式. defGet_Load_Info(addr): try: Head=["HostName","Load1","Load5","Load15"] SysLoad=[] ret=os.popen("snmpwalk-v2c-cnmap"+addr+".1.3.6.1.2.1.1.5") SysLoad.append(ret.read().split(":")[3].strip()) ret=os.popen("snmpwalk-v2c-cnmap"+addr+".1.3.6.1.4.1.2021.10.1.3") load=list(re.sub(".*STRING:","",ret.read()).split(" ")) SysLoad.append(load[0]) SysLoad.append(load[1]) SysLoad.append(load[2]) returndict(zip(Head,SysLoad)) exceptException: return0 #通过SNMP获取系统内存占用:内存利用率,获取到之后,将其转化为字典格式保存。 defGet_Mem_Info(addr): try: Head=["HostName","memTotalSwap","memAvailSwap","memTotalReal","memTotalFree"] SysMem=[] ret=os.popen("snmpwalk-v2c-cnmap"+addr+".1.3.6.1.2.1.1.5") SysMem.append(ret.read().split(":")[3].strip()) ret=os.popen("snmpwalk-v2c-cnmap"+addr+".1.3.6.1.4.1.2021.4") mem=ret.read().split(" ") foriin[2,3,4,6]: SysMem.append(re.sub(".*INTEGER:","",mem[i]).split("")[0]) returndict(zip(Head,SysMem)) exceptException: return0 #通过SNMP获取系统磁盘数据:这个案例并不完整,我只写了一点,后面有个问题一直没有解决. defGet_Disk_Info(addr): try: dic={} list=[] ret=os.popen("snmpwalk-v2c-cnmap"+addr+"HOST-RESOURCES-MIB::hrStorageDescr") DiskName=ret.read().split(" ") ret=os.popen("snmpwalk-v2c-cnmap"+addr+"HOST-RESOURCES-MIB::hrStorageUsed") DiskUsed=ret.read().split(" ") ret=os.popen("snmpwalk-v2c-cnmap"+addr+"HOST-RESOURCES-MIB::hrStorageSize") DiskSize=ret.read().split(" ") foriinrange(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) returnlist exceptException: return0 if__name__=='__main__': foriinrange(100): dic=Get_CPU_Info("192.168.1.20") print(dic) time.sleep(1)
通过SNMP收集主机CPU利用率 通过SNMP协议,收集目标主机的CPU利用率(百分比),并返回JSON字符串.
importos,re,time
defGet_CPU_Info(addr):
try:
Head=["HostName","CoreLoad","CpuUser","CpuSystem","CpuIdle"]
CPU=[]
ret=os.popen("snmpwalk-v2c-cnmap"+addr+".1.3.6.1.2.1.1.5")
CPU.append(ret.read().split(":")[3].strip())
ret=os.popen("snmpwalk-v2c-cnmap"+addr+".1.3.6.1.2.1.25.3.3.1.2")
CPU.append(ret.read().split(":")[3].strip())
foriin[9,10,11]:
ret=os.popen("snmpwalk-v2c-cnmap"+addr+"1.3.6.1.4.1.2021.11.{}.0".format(i))
ret=ret.read()
Info=ret.split(":")[3].strip()
CPU.append(Info)
returndict(zip(Head,CPU))
exceptException:
return0
if__name__=='__main__':
foriinrange(100):
dic=Get_CPU_Info("192.168.1.20")
print(dic)
time.sleep(1)
通过SNMP获取系统CPU负载信息 分别获取到系统的1,5,15分钟的负载信息,并返回JSON格式.
importos,re,time
defGet_Load_Info(addr):
try:
Head=["HostName","Load1","Load5","Load15"]
SysLoad=[]
ret=os.popen("snmpwalk-v2c-cnmap"+addr+".1.3.6.1.2.1.1.5")
SysLoad.append(ret.read().split(":")[3].strip())
ret=os.popen("snmpwalk-v2c-cnmap"+addr+".1.3.6.1.4.1.2021.10.1.3")
load=list(re.sub(".*STRING:","",ret.read()).split("
"))
SysLoad.append(load[0])
SysLoad.append(load[1])
SysLoad.append(load[2])
returndict(zip(Head,SysLoad))
exceptException:
return0
if__name__=='__main__':
dic=Get_Load_Info("192.168.1.20")
print(dic)
通过SNMP获取系统内存占用 内存利用率,获取到之后,将其转化为字典格式保存。
importos,re,time
defGet_Mem_Info(addr):
try:
Head=["HostName","memTotalSwap","memAvailSwap","memTotalReal","memTotalFree"]
SysMem=[]
ret=os.popen("snmpwalk-v2c-cnmap"+addr+".1.3.6.1.2.1.1.5")
SysMem.append(ret.read().split(":")[3].strip())
ret=os.popen("snmpwalk-v2c-cnmap"+addr+".1.3.6.1.4.1.2021.4")
mem=ret.read().split("
")
foriin[2,3,4,6]:
SysMem.append(re.sub(".*INTEGER:","",mem[i]).split("")[0])
returndict(zip(Head,SysMem))
exceptException:
return0
if__name__=='__main__':
dic=Get_Mem_Info("192.168.1.20")
print(dic)
通过SNMP获取系统磁盘数据 这个案例并不完整,我只写了一点,后面有个问题一直没有解决.
importos,re,time
defGet_Disk_Info(addr):
try:
dic={}
list=[]
ret=os.popen("snmpwalk-v2c-cnmap"+addr+"HOST-RESOURCES-MIB::hrStorageDescr")
DiskName=ret.read().split("
")
ret=os.popen("snmpwalk-v2c-cnmap"+addr+"HOST-RESOURCES-MIB::hrStorageUsed")
DiskUsed=ret.read().split("
")
ret=os.popen("snmpwalk-v2c-cnmap"+addr+"HOST-RESOURCES-MIB::hrStorageSize")
DiskSize=ret.read().split("
")
foriinrange(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)
returnlist
exceptException:
return0
if__name__=='__main__':
list=Get_Disk_Info("192.168.1.20")
print(list)
接下来,我们使用pysnmp模块来做,安装pysnmp很简单,执行命令pip install pysnmp即可,安装后,使用以下代码执行即可获取到目标数据,网上的那些转载的都是坑,没一个能用的,这个案例是官方案例,可以使用。
frompysnmp.hlapiimport* iterator=getCmd(SnmpEngine(), CommunityData('public'), UdpTransportTarget(('192.168.1.113',161)), ContextData(), ObjectType(ObjectIdentity('SNMPv2-MIB','sysDescr',0))) errorIndication,errorStatus,errorIndex,varBinds=next(iterator) iferrorIndication: print(errorIndication) else: iferrorStatus: print('%sat%s'%(errorStatus.prettyPrint(),varBinds[int(errorIndex)-1]iferrorIndexelse'?')) else: forvarBindinvarBinds: print('='.join([x.prettyPrint()forxinvarBind]))
首先我们以一个OID序号为例,我们查询特定序号对应的名称,然后将其记录下来,例如下面这样。

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

然后我们简单的封装一个类,先来测试一下是否能通。
#snmpwalk-v2c-cpublic192.168.1.113.1.3.6.1.2.1.1.5
frompysnmp.hlapiimport*
classNetSNMP():
def__init__(self,address,region):
self.region=region
self.address=address
#获取指定数据的方法
defGetNumber(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)
iferrorIndication:
returnFalse
else:
iferrorStatus:
returnFalse
else:
forvarBindinvarBinds:
return[x.prettyPrint()forxinvarBind]
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]))
运行后,即可读取到内存数据,如下。

-
Linux
+关注
关注
88文章
11627浏览量
217895 -
SNMP
+关注
关注
0文章
93浏览量
30573 -
网络设备
+关注
关注
0文章
337浏览量
30751 -
python
+关注
关注
57文章
4856浏览量
89550
原文标题:如何使用Python通过SNMP监控网络设备?
文章出处:【微信号:网络技术干货圈,微信公众号:网络技术干货圈】欢迎添加关注!文章转载请注明出处。
发布评论请先 登录
基于SNMP的网络拓扑结构自动发现研究
Labview监控带有snmp网卡设备有没有问题?
用LWIP的SNMP监控嵌入式设备
AN_基于FreeRTOS+LwIP的SNMP实现方案
基于SNMP的网络监控系统
基于SNMP的网络监控系统开发平台与架构的设计与实现

如何使用Python通过SNMP监控网络设备?
评论