Simple SNMP Poller with Python
Just want to share how to implement simple SNMP Poller with pySNMP, this code using Oracle Database to save MIB dimension, save pool result and others.
OID Dimension Table definition:
CREATE TABLE "NMS"."DIM_OID"
( "OID" VARCHAR2(150 BYTE),
"ALIAS" VARCHAR2(150 BYTE),
"DESCRIPTION" VARCHAR2(150 BYTE),
CONSTRAINT "DIM_OID_UK1" UNIQUE ("OID")
USING INDEX PCTFREE 10 INITRANS 2 MAXTRANS 255 COMPUTE STATISTICS
STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT)
TABLESPACE "NMS" ENABLE
) PCTFREE 0 PCTUSED 40 INITRANS 1 MAXTRANS 255 COMPRESS LOGGING
STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT)
TABLESPACE "NMS" ;
Server Parameter Table definition :
CREATE TABLE "NMS"."PAR_SERVER"
( "ID" NUMBER(9,0),
"HOSTNAME" VARCHAR2(50 BYTE),
"DESCRIPTION" VARCHAR2(150 BYTE),
"IP_ADDRESS" VARCHAR2(15 BYTE),
"RO_COMMUNITY" VARCHAR2(50 BYTE),
"RW_COMMUNITY" VARCHAR2(50 BYTE),
"AUTH_USER" VARCHAR2(50 BYTE),
"AUTH_PASS" VARCHAR2(50 BYTE),
"STATUS" VARCHAR2(4 BYTE),
"SNMP_VERSION" VARCHAR2(3 BYTE),
CONSTRAINT "PAR_SERVER_UK1" UNIQUE ("ID")
USING INDEX PCTFREE 10 INITRANS 2 MAXTRANS 255 COMPUTE STATISTICS
STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT)
TABLESPACE "NMS" ENABLE
) PCTFREE 0 PCTUSED 40 INITRANS 1 MAXTRANS 255 COMPRESS LOGGING
STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT)
TABLESPACE "NMS" ;
OID Server To Be Check Table definition :
CREATE TABLE "NMS"."DIM_SERVER_CHECK"
( "HOSTNAME" VARCHAR2(50 BYTE),
"OID" VARCHAR2(150 BYTE),
CONSTRAINT "DIM_SERVER_CHECK_UK1" UNIQUE ("HOSTNAME", "OID")
USING INDEX PCTFREE 10 INITRANS 2 MAXTRANS 255 COMPUTE STATISTICS
STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT)
TABLESPACE "NMS" ENABLE
) PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255 NOCOMPRESS LOGGING
STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT)
TABLESPACE "NMS" ;
Reporting Table definition:
CREATE TABLE "NMS"."RPT_STATISTIC"
( "ID" NUMBER(9,0),
"HOSTNAME" VARCHAR2(50 BYTE),
"OID" VARCHAR2(150 BYTE),
"VALUE" VARCHAR2(200 BYTE),
"QUERY_TIME" DATE
) PCTFREE 0 PCTUSED 40 INITRANS 1 MAXTRANS 255 COMPRESS LOGGING
STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT)
TABLESPACE "NMS" ;
CREATE INDEX "NMS"."RPT_STATISTIC_INDEX1" ON "NMS"."RPT_STATISTIC" ("HOSTNAME", "OID", "QUERY_TIME")
PCTFREE 10 INITRANS 2 MAXTRANS 255 COMPUTE STATISTICS
STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT)
TABLESPACE "NMS" ;
CREATE OR REPLACE TRIGGER "NMS"."TRG_RPT_STATISTIC"
BEFORE INSERT ON RPT_STATISTIC
FOR EACH ROW
BEGIN
:NEW.QUERY_TIME := SYSDATE;
END;
/
ALTER TRIGGER "NMS"."TRG_RPT_STATISTIC" ENABLE;
Poller class definition:
import sys, os
import cx_Oracle
sys.path.append(os.environ['NMS_LIB'])
import parameters, logger, GetPoller
## [ Class Definition ]
class ServerInformation:
server = None
def __init__(self):
self.server = {"hostname":"", "ip_address":"", "ro_community":"", "rw_community":"", "auth_user":"", "auth_password":""}
class Poller:
connection = None
getPoller = GetPoller.GetPoller()
def __init__(self):
None
def createOracleConnection(self, config):
try:
self.connection = cx_Oracle.connect(config['username'] + '/' + config['password'] + '@' + config['sid'])
return self.connection
except Exception, errmsg:
logger.write(errmsg)
exit(1)
def getTargetHost(self):
try:
result = []
q_host = "SELECT hostname, ip_address, ro_community, rw_community, auth_user, auth_pass FROM PAR_SERVER WHERE STATUS = 'UP'"
stmt = self.connection.cursor()
stmt.execute(q_host)
##fetching all host information
rs = stmt.fetchall()
for res in rs:
##print res
serverInformation = ServerInformation()
serverInformation.server["hostname"] = str(res[0])
serverInformation.server["ip_address"] = res[1]
serverInformation.server["ro_community"] = res[2]
serverInformation.server["rw_community"] = res[3]
serverInformation.server["auth_user"] = res[4]
serverInformation.server["auth_password"] = res[4]
result.append(serverInformation)
stmt.close()
##print result
return result
except Exception, errmsg:
logger.write(errmsg)
exit(1)
def getConnection(self):
return self.connection
def insertStatistic(self, info, param):
try:
q_insert = "INSERT INTO RPT_STATISTIC (ID, HOSTNAME, OID, VALUE) VALUES (SEQ_RPT_STAT.nextval, :p_hostname, :p_oid, :p_value)"
binSel = {"p_hostname":info.server["hostname"], "p_oid":param["oid"], "p_value":param["value"]}
stmt = self.getConnection().cursor()
stmt.execute(q_insert, binSel)
self.getConnection().commit()
stmt.close()
except Exception, errmsg:
logger.write(errmsg)
def getOidList(self):
try:
result = []
q_host = "SELECT oid, alias FROM DIM_OID"
stmt = self.connection.cursor()
stmt.execute(q_host)
##fetching all host information
rs = stmt.fetchall()
for res in rs:
info = {"oid":"", "alias":""}
info["oid"] = str(res[0])
info["alias"] = res[1]
result.append(info)
stmt.close()
return result
except Exception, errmsg:
logger.write(errmsg)
exit(1)
GET Poller command class definition:
import os, sys
from pysnmp.entity.rfc3413.oneliner import cmdgen
sys.path.append(os.environ['NMS_LIB'])
import logger
##[ Global Variable Definition ]
## [ Class Definition ]
class ServerInformation:
server = None
def __init__(self):
self.server = {"hostname":"", "ip_address":"", "ro_community":"", "rw_community":"", "auth_user":"", "auth_password":""}
class GetPoller:
commandGenerator = cmdgen.CommandGenerator()
serverInformation = ServerInformation()
udpTransport = None
comdata = None
oid = None
def __init__(self):
None
def initialize(self, serverInformation):
self.serverInformation = serverInformation
##print 'setup connectio to SNMP agent.'
self.udpTransport = cmdgen.UdpTransportTarget((self.serverInformation.server["ip_address"], 161))
self.comdata = cmdgen.CommunityData(self.serverInformation.server["auth_user"], self.serverInformation.server["ro_community"], 0)
##print 'done.'
def get(self, oid):
self.oid = self.createOID(oid.split("."))
errorIndication, errorStatus, errorIndex, varBinds = self.commandGenerator.getCmd(self.comdata, self.udpTransport, self.oid)
for oid, val in varBinds:
return val.prettyPrint()
def createOID(self, tokens):
result = ()
for token in tokens:
result += (int(token),)
return result
Main program of poller:
import sys, os
import socket
import threading
import time
sys.path.append(os.environ['NMS_LIB'])
import parameters, logger, GetPoller, Poller
##[ Global Variable Definition ]
par = parameters.Parameter()
confFileName = os.environ['NMS_HOME'] + os.path.sep + 'config' + os.path.sep + 'connections.cfg'
dbConf = par.getParams(confFileName)
pollerConf= os.environ['NMS_HOME'] + os.path.sep + 'config' + os.path.sep + 'poller.cfg'
pollerConfig = par.getParams(pollerConf)
## [ Class Definition ]
class Starter(threading.Thread):
def __init__(self, lock):
self.lock= lock
threading.Thread.__init__ ( self )
def run(self):
poller = Poller.Poller()
##setup oracle connection
print 'setup oracle connection....'
conn = poller.createOracleConnection(dbConf)
print 'initialize target host to query....'
serverList = poller.getTargetHost()
print 'initialize oid target host to be query'
oidList = poller.getOidList()
print 'polling query to agent....'
for server in serverList:
##print server.server
poller.getPoller.initialize(server)
for info in oidList:
##print info["oid"]
param = {"oid":"", "value":""}
param["oid"] = info["oid"]
param["value"] = poller.getPoller.get(info["oid"])
if param["value"] != '':
poller.insertStatistic(server, param)
print 'process complete.....'
conn.close()
class ClientThread(threading.Thread):
# Override Thread's __init__ method to accept the parameters needed:
def __init__ ( self, channel, details, lock ):
self.channel = channel
self.details = details
self.lock = lock
threading.Thread.__init__ ( self )
def run ( self ):
flag = True
while flag:
command = self.channel.recv ( 1024 )
command = command.strip()
print 'Received connection:', self.details [ 0 ]
print command
if command == "shutdown":
self.channel.send("SNMP Poller agent will be shutdown.....\nPlease close your connection.....\n")
os.remove(self.lock)
elif command == "close":
flag = False
elif command == "help":
##print help command
self.channel.send("___________________________________________________\n")
self.channel.send("""SNMP Poller agent version 0.1\nHelp:\nshutdown\t: Used to shutdown SNMP Poller agent.\nclose\t\t: Used to close connection session.\n""")
self.channel.send("___________________________________________________\n")
else:
self.channel.send("Unknow command, type help to see detail.\n")
self.channel.close()
class Server(threading.Thread):
def __init__(self, lock):
self.lock = lock
self.flag = True
threading.Thread.__init__(self)
##create lock on server
lock = open(self.lock,"w")
lock.close()
def run(self):
## Set up the server:
server = socket.socket ( socket.AF_INET, socket.SOCK_STREAM )
server.bind ( ( '', int(pollerConfig["port"]) ) )
server.listen ( int(pollerConfig["max_connection"]) )
while self.flag == True:
channel, details = server.accept()
ClientThread ( channel, details , self.lock).start()
self.flag = os.path.exists(self.lock)
if flag == False:
break
server.close()
##[ Procedure or Function Definition ]
##[ Main Program ]
##create lock on server
lockFilename = os.environ['NMS_HOME'] + os.path.sep + 'config' + os.path.sep + "SNMPpoller.lock"
lock = open(lockFilename, "w")
lock.close()
##setup socket server
Server(lockFilename).start()
##running poller
flag = True
while flag == True:
time.sleep(int(pollerConfig["sleep"]))
Starter(lockFilename).start()
flag = os.path.exists(lockFilename)
if flag == False:
break
sys.exit()
##[ End Program ]
This poller program using some of configuration, configuration for connection to database and poller server configuration.
Sample connections.cfg :
username=nms
password=nms
sid=oratunggul
Sample poller.cfg :
sleep=300
max_connection=1
port=2728
Hopefully this will be useful..
About this entry
You’re currently reading “Simple SNMP Poller with Python,” an entry on Zhobur's
- Published:
- April 22, 2009 / 3:57 am
- Category:
- Python
- Tags:
2 Comments
Jump to comment form | comment rss [?] | trackback uri [?]