功能
访问远程交换机snmp数据,写入本地influxdb数据库
#!/usr/bin/env python
# -*- encoding: utf-8 -*-
import os, yaml, time
import cPickle as pickle
import threading
import Queue
from pysnmp.entity.rfc3413.oneliner import cmdgen
from influxdb import InfluxDBClient
def get_config_info(file):
with open(file, 'r') as f:
content = yaml.load(f)
return content['web'], content['interval'], content['switch']
def mib_vars(mib, oids, indices = None):
if indices is None:
return [cmdgen.MibVariable(mib, x) for x in oids.split()]
else:
return [cmdgen.MibVariable(mib, x, indices) for x in oids.split()]
def int_str(x):
try:
return int(x)
except ValueError:
return str(x)
def get_traffic_snmp(ip, community, interface, *args):
count = 0
while count < 2:
try:
errorIndication, errorStatus, errorIndex, varBindTable = cmdgen.CommandGenerator().nextCmd(
cmdgen.CommunityData(community),
cmdgen.UdpTransportTarget((ip, 161)),
*args, lookupNames = True, lookupValues = True
)
for varBindRow in varBindTable:
row = [ int_str(val) for name, val in varBindRow if name]
if row[0] == interface:
return row[1], row[2]
except Exception:
count += 1
continue
return 0, 0
class SwitchTraffic(threading.Thread):
def __init__(self, queue, name, ip, community, interface, interval):
threading.Thread.__init__(self)
self.queue = queue
self.name = name
self.ip = ip
self.community = community
self.interface = interface
self.interval = interval
def run(self):
oids = mib_vars('IF-MIB', 'ifName ifHCInOctets ifHCOutOctets')
file = os.path.join('/tmp', 'cache-' + self.ip)
while 1:
if os.path.exists(file):
with open(file, 'rb+') as f:
p = pickle.load(f)
time_pre, in_pre, out_pre = (p[0], p[1], p[2])
in_cur, out_cur = get_traffic_snmp(self.ip, self.community, self.interface, *oids)
time_cur = int(time.time())
pickle.dump([time_cur, in_cur, out_cur], f)
if in_cur - in_pre != 0:
total = (in_cur * 8 - in_pre * 8)
diff = time_cur - time_pre if time_cur - time_pre != 0 else 0
in_mbit = float(total) / diff / 1000 / 1000
else:
in_mbit = 0
if out_cur - out_pre != 0:
total = (out_cur * 8 - out_pre * 8)
diff = time_cur - time_pre if time_cur - time_pre != 0 else 0
out_mbit = float(total) / diff / 1000 / 1000
else:
out_mbit = 0
self.queue.put( (time_cur, self.name, round(in_mbit, 2), round(out_mbit, 2)) )
else:
with open(file, 'wb') as f:
time_cur = int(time.time())
in_pre, out_pre = get_traffic_snmp(self.ip, self.community, self.interface, *oids)
time_pre = int(time.time())
pickle.dump([time_pre, in_pre, out_pre], f)
self.queue.put( (time_cur, self.name, 0, 0) )
time.sleep(self.interval)
class TimeSeriesDB(threading.Thread):
def __init__(self, queue):
threading.Thread.__init__(self)
self.queue = queue
def run(self):
while True:
try:
client = InfluxDBClient('localhost', 8086, 'root', 'root', 'dashboard')
timestamp, name, traffic_in, traffic_out = self.queue.get()
data = [
{ 'measurement': 'traffic_in', 'tags': {'host': name}, 'time': timestamp, 'fields': {'value': traffic_in} },
{ 'measurement': 'traffic_out', 'tags': {'host': name}, 'time': timestamp, 'fields': {'value': traffic_out} },
]
client.write_points(data, time_precision='s')
print name, int(time.time()), traffic_in, traffic_out
except Exception:
continue
def main():
queue = Queue.Queue()
file = 'dashboard.yaml'
web, interval, switch = get_config_info(file)
for i in switch:
producer = SwitchTraffic(queue, i['name'], i['ip'], i['community'], i['interface'], interval)
producer.start()
consumer = TimeSeriesDB(queue)
consumer.start()
if __name__ == '__main__':
main()