PySNMP 是一个纯粹用Python实现的SNMP,用PySNMP的最抽象的API为One-line Applications,其中有两类API:同步的和非同步的,都在模块pysnmp.entity.rfc3413.oneliner.cmdgen 中实现,如下是Get方式与Walk方式的基本实现.
首先需要在系统中安装SNMP客户端,对于Linux平台来说只需要执行如下配置过程即可.
[root@localhost ~]# yum install -y net-snmp
[root@localhost ~]# cat /etc/snmp/snmpd.conf |grep -vE \"^#|^$\"
com2sec notConfigUser default public
group notConfigGroup v1 notConfigUser
group notConfigGroup v2c notConfigUser
view systemview included .1
view systemview included .1
access notConfigGroup \"\" any noauth exact systemview none none
[root@localhost ~]# systemctl restart snmpd
[root@localhost ~]# systemctl enable snmpd
如果是Windows系统则需要在客户机服务列表,开启SNMP支持,并设置好一个团体名称,如下图。
当我们配置好客户端后,服务端就客户获取数据了,我们以一个OID序号为例,我们查询特定序号对应的名称,然后将其记录下来,例如下面这样。
C:\\Users\\admin> snmpwalk -v 2c -c public 192.168.1.101 .1.3.6.1.2.1.25.2.2
HOST-RESOURCES-MIB::hrMemorySize.0 = INTEGER: 2096632 KBytes
首先我们不使用PySNMP模块直接开线程调用看看,该代码如下所示.
import os,re,time
# 通过SNMP收集主机CPU利用率: 通过SNMP协议,收集目标主机的CPU利用率(百分比),并返回JSON字符串.
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
# 通过SNMP获取系统CPU负载信息: 分别获取到系统的1,5,15分钟的负载信息,并返回JSON格式.
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
# 通过SNMP获取系统内存占用: 内存利用率,获取到之后,将其转化为字典格式保存。
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
# 通过SNMP获取系统磁盘数据: 这个案例并不完整,我只写了一点,后面有个问题一直没有解决.
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__\':
for i in range(100):
dic = Get_CPU_Info(\"192.168.1.20\")
print(dic)
time.sleep(1)
我们使用pysnmp模块来做,安装pysnmp很简单,执行命令pip install pysnmp
即可,安装后使用以下代码执行即可获取到目标数据,获取方式分为两种一种为Get另一种为Walk.
from pysnmp.hlapi import *
import os,sys
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]
# 使用Walk拉取数据
def WalkNumber(self, oid):
res = []
for (errorIndication, errorStatus, errorIndex, varBinds) in nextCmd(SnmpEngine(),
CommunityData(self.region),UdpTransportTarget((self.address, 161)),ContextData(),
ObjectType(ObjectIdentity(oid)).addMibSource(
\'./site-packages/pysnmp/smi/mibs\',\'pysnmp_mibs\'),lexicographicMode=False):
if errorIndication:
print(errorIndication, file=sys.stderr)
break
elif errorStatus:
print(\'%s at %s\' % (errorStatus.prettyPrint(),
errorIndex and varBinds[int(errorIndex) - 1][0] or \'?\'),
file=sys.stderr)
break
else:
for varBind in varBinds:
res.append(str(varBind))
return res
if __name__ == \"__main__\":
# 初始化
ptr = NetSNMP(\"192.168.81.130\",\"public\")
# 使用GET方式获取OID数据
ret = ptr.GetNumber(\"HOST-RESOURCES-MIB\",\"hrMemorySize\",0)
print(\"类型: {} --> 返回结果: {} --> 解析: {}\".format(type(ret),ret,ret[1]))
# 使用Walk方式获取OID数据
ret = ptr.WalkNumber(\".1.3.6.1.2.1.2.2.1.6\")
for each in ret:
mac = each.split(\"=\")[1]
if len(mac) > 1:
print(\"网卡接口: {}\".format(mac))
文章出处:https://www.cnblogs.com/LyShark/p/16512846.html
版权声明:本博客文章与代码均为学习时整理的笔记,文章 [均为原创] 作品,转载请 [添加出处] ,您添加出处是我创作的动力!
来源:https://www.cnblogs.com/LyShark/p/16512846.html
本站部分图文来源于网络,如有侵权请联系删除。