PySNMP获取设备信息
只要你在你的计算机上下载并安装了 PySNMP 库,你就可以解决非常基本的 SNMP 问题, 如通过 Python 命令行获取某个远程 SNMP Agent 的数据 (你至少需要 4.3.0 以上版本,才可以执行后面的示例代码)。
复制和粘贴下列代码到 Python 命令提示符上,代码将会执行 SNMP GET 操作获取sysDescr.0
对象,这是一个公开可用的 SNMP Command Responder,
"""
SNMPv1
++++++
Send SNMP GET request using the following options:
* with SNMPv1, community 'public'
* over IPv4/UDP
* to an Agent at demo.snmplabs.com:161
* for two instances of SNMPv2-MIB::sysDescr.0 MIB object,
Functionally similar to:
| $ snmpget -v1 -c public demo.snmplabs.com SNMPv2-MIB::sysDescr.0
"""#
from pysnmp.hlapi import *
errorIndication, errorStatus, errorIndex, varBinds = next(
getCmd(SnmpEngine(),
CommunityData('public', mpModel=0),
UdpTransportTarget(('demo.snmplabs.com', 161)),
ContextData(),
ObjectType(ObjectIdentity('SNMPv2-MIB', 'sysDescr', 0)))
)
if errorIndication:
print(errorIndication)
elif errorStatus:
print('%s at %s' % (errorStatus.prettyPrint(),
errorIndex and varBinds[int(errorIndex) - 1][0] or '?'))
else:
for varBind in varBinds:
print(' = '.join([x.prettyPrint() for x in varBind]))
如果一切执行正常,那么将会在你的终端打印:
...
SNMPv2-MIB::sysDescr."0" = SunOS zeus.snmplabs.com 4.1.3_U1 1 sun4m
>>>
想给 """
SNMPv1 TRAP with defaults
+++++++++++++++++++++++++
Send SNMPv1 TRAP through unified SNMPv3 message processing framework
using the following options:
* SNMPv1
* with community name 'public'
* over IPv4/UDP
* send TRAP notification
* with Generic Trap #1 (warmStart) and Specific Trap 0
* with default Uptime
* with default Agent Address
* with Enterprise OID 1.3.6.1.4.1.20408.4.1.1.2
* include managed object information '1.3.6.1.2.1.1.1.0' = 'my system'
Functionally similar to:
| $ snmptrap -v1 -c public demo.snmplabs.com 1.3.6.1.4.1.20408.4.1.1.2 0.0.0.0 1 0 0 1.3.6.1.2.1.1.1.0 s "my system"
"""#
from pysnmp.hlapi import *
errorIndication, errorStatus, errorIndex, varBinds = next(
sendNotification(
SnmpEngine(),
CommunityData('public', mpModel=0),
UdpTransportTarget(('demo.snmplabs.com', 162)),
ContextData(),
'trap',
NotificationType(
ObjectIdentity('1.3.6.1.6.3.1.1.5.2')
).addVarBinds(
('1.3.6.1.6.3.1.1.4.3.0', '1.3.6.1.4.1.20408.4.1.1.2'),
('1.3.6.1.2.1.1.1.0', OctetString('my system'))
)
)
)
if errorIndication:
print(errorIndication)
PySNMP 获取设备信息示例
2.1. cpu 信息 ¶
根据 UCD-SNMP-MIB 文件,可以获取的 cpu 参数共有 33 条,这里我们主要关注的是 cpu 的使用率,ssCpuIdle
获取的是 cpu 的空闲率,所以 100 - ssCpuIdle 既可以求得 cpu 的使用率。
def getCpuUsage(targetHost, targetPort, cmd, community): errIndication, errStatus, errIndex, varBindTable = cmd.nextCmd( cmdgen.CommunityData(community, mpModel=1), # mpModel=1,表示使用v2协议 cmdgen.UdpTransportTarget((targetHost,targetPort)), # 设备ip及端口 cmdgen.MibVariable('UCD-SNMP-MIB','ssCpuIdle'), # 需要访问信息的MIB库及子节点,也可以用形如'1.3.6.1.4'(OID标识符)的方式来定义 #lookupValues=True ) if errIndication: print errIndication else: if errStatus: print '%s at %s' % ( errStatus.prettyPrint(), errIndex and varBindTable[-1][int(errIndex)-1] or '?' ) else: return 100.0 - float(varBindTable[0][0][1].prettyPrint())
这是运行结果:
[[ObjectType(ObjectIdentity(ObjectName('1.3.6.1.4.1.2021.11.11.0')), Integer32(92))]] CPU使用率:8.0
2.2. 内存信息 ¶
可以获取的完整内存对象信息也在http://mibs.snmplabs.com/asn1/UCD-SNMP-MIB
上,包括 memTotalFree,memShared,memBuffer 等。
def getMemUsage(targetHost, targetPort, cmd, community): errIndication, errStatus, errIndex, varBindTable = cmd.nextCmd( cmdgen.CommunityData(community, mpModel=1), cmdgen.UdpTransportTarget((targetHost,targetPort)), cmdgen.MibVariable('UCD-SNMP-MIB','memTotalReal'), #'1.3.6.1.4.1.2021.4.5', cmdgen.MibVariable('UCD-SNMP-MIB','memAvailReal'), #'1.3.6.1.4.1.2021.4.6', cmdgen.MibVariable('UCD-SNMP-MIB','memBuffer'), #'1.3.6.1.4.1.2021.4.14', cmdgen.MibVariable('UCD-SNMP-MIB','memCached'), # '1.3.6.1.4.1.2021.4.15', #cmdgen.MibVariable('UCD-SNMP-MIB', 'memTotalSwap'), #lookupValues=True #lookupNames=True ) #print varBindTable if errIndication: print errIndication else: if errStatus: print '%s at %s' % ( errStatus.prettyPrint(), errIndex and varBindTable[-1][int(errIndex)-1] or '?' ) else: mysum = 0.0 totalAvailReal = float(varBindTable[0][0][1].prettyPrint()) for var in varBindTable: for name , val in var: mysum += float(val.prettyPrint()) return totalAvailReal, (2*totalAvailReal - mysum) / totalAvailReal * 100.0
其中,比较重要的内存信息有:内存总量,缓冲区大小,cache 区大小,swap 区大小等。据此,可以计算出内存的使用率。
2.3. disk 信息 ¶
disk 的相关信息也定义在 mib 文件 UCD-SNMP-MIB 中,根据该文件,可以获取以下 disk 信息:
DskEntry ::= SEQUENCE { dskIndex Integer32, dskPath DisplayString, dskDevice DisplayString, dskMinimum Integer32, dskMinPercent Integer32, dskTotal Integer32, dskAvail Integer32, dskUsed Integer32, dskPercent Integer32, dskPercentNode Integer32, dskErrorFlag UCDErrorFlag, dskErrorMsg DisplayString, dskTotalLow Unsigned32, dskTotalHigh Unsigned32, dskAvailLow Unsigned32, dskAvailHigh Unsigned32, dskUsedLow Unsigned32, dskUsedHigh Unsigned32 }
根据 oid name,可以很容易看出其意思,下面的代码可以用来获取 disk 的使用信息:
def getDiskUsage(targetHost, targetPort, cmd, community): errIndication, errStatus, errIndex, varBindTable = cmd.nextCmd( cmdgen.CommunityData(community, mpModel=1), cmdgen.UdpTransportTarget((targetHost,targetPort)), cmdgen.MibVariable('UCD-SNMP-MIB', 'dskPath'), # '1.3.6.1.4.1.2021.9.1.2' cmdgen.MibVariable('UCD-SNMP-MIB', 'dskTotal'), # '1.3.6.1.4.1.2021.9.1.6' cmdgen.MibVariable('UCD-SNMP-MIB', 'dskPercent'), #'1.3.6.1.4.1.2021.9.1.9' cmdgen.MibVariable('UCD-SNMP-MIB', 'dskDevice'), #'1.3.6.1.4.1.2021.9.1.3' #lookupValues=True, #lookupNames=True ) if errIndication: print errIndication else: if errStatus: print '%s at %s' % (errStatus.prettyPrint(), errIndex \ and varBindTable[-1][int(errIndex)-1] or '?') else: result = [] for var in varBindTable: tempResult = {} for name , val in var: tempResult[name.getLabel()[len(name.getLabel())-1]] = val.prettyPrint() result.append(tempResult) return result
测试时,我们获取到 waf 设备 10.11.113.150 的 disk 信息为空,其他设备可以正常获取。
2.4. 流量信息 ¶
也网卡或者流量相关的对象定义定义在 IF-MIB 中,可以获取的具体信息包括:
IfEntry ::= SEQUENCE { ifIndex InterfaceIndex, ifDescr DisplayString, ifType IANAifType, ifMtu Integer32, ifSpeed Gauge32, ifPhysAddress PhysAddress, ifAdminStatus INTEGER, ifOperStatus INTEGER, ifLastChange TimeTicks, ifInOctets Counter32, ifInUcastPkts Counter32, ifInNUcastPkts Counter32, -- deprecated ifInDiscards Counter32, ifInErrors Counter32, ifInUnknownProtos Counter32, ifOutOctets Counter32, ifOutUcastPkts Counter32, ifOutNUcastPkts Counter32, -- deprecated ifOutDiscards Counter32, ifOutErrors Counter32, ifOutQLen Gauge32, -- deprecated ifSpecific OBJECT IDENTIFIER -- deprecated }
以下是获取网卡流量相关信息的示例代码:
def getIfaceTraffic(targetHost, targetPort, cmd, community, period): def getNowTraffic(): errIndication, errStatus, errIndex, varBindTable = cmd.nextCmd( cmdgen.CommunityData(community, mpModel=1), cmdgen.UdpTransportTarget((targetHost,targetPort)), cmdgen.MibVariable('IF-MIB', 'ifDescr'), # '1.3.6.1.2.1.2.2.1.2' cmdgen.MibVariable('IF-MIB', 'ifInOctets'), # '1.3.6.1.2.1.2.2.1.10' cmdgen.MibVariable('IF-MIB', 'ifOutOctets'), #'1.3.6.1.2.1.2.2.1.16' #lookupValues=True, #lookupNames=True ) if errIndication: print errIndication else: if errStatus: print '%s at %s' % (errStatus.prettyPrint(), errIndex \ and varBindTable[-1][int(errIndex)-1] or '?') else: result = [] #print varBindTable for var in varBindTable: tempResult = {} for name , val in var: tempResult[name.getLabel()[len(name.getLabel())-1]] = val.prettyPrint() result.append(tempResult) return result preTraffic = getNowTraffic() #print preTraffic time.sleep(period) afterTraffic = getNowTraffic() #print afterTraffic traffic = [] if(len(preTraffic) != len(afterTraffic)): return None else: ifaceNum = len(preTraffic) for i in range(ifaceNum): if preTraffic[i]['ifDescr'] == afterTraffic[i]['ifDescr']: m = float(preTraffic[i]['ifInOctets']) mm = float(afterTraffic[i]['ifInOctets']) n = float(preTraffic[i]['ifOutOctets']) nn = float(afterTraffic[i]['ifOutOctets']) ifaceName = preTraffic[i]['ifDescr'] traffic.append({ 'ifaceName':ifaceName, 'inTraffic(Mbps)':(mm-m)/period/1048576*8, 'outTraffic(Mbps)':(nn-n)/period/1048576*8 }) else: return None return traffic
本文来自博客园,作者:游走De提莫,转载请注明原文链接:https://www.cnblogs.com/Gaimo/p/16036074.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?