前段時間,為了實現自動化巡檢,我開發了自動化巡檢工具,由于我的系統設備版本比較多,所以我是分別開發的客戶端程序,服務端使用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
+關注
關注
87文章
11232瀏覽量
208949 -
SNMP
+關注
關注
0文章
83瀏覽量
29721 -
網絡設備
+關注
關注
0文章
309瀏覽量
29616 -
python
+關注
關注
56文章
4783瀏覽量
84473
原文標題:如何使用Python通過SNMP監控網絡設備?
文章出處:【微信號:網絡技術干貨圈,微信公眾號:網絡技術干貨圈】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
相關推薦
評論