pysnmp程序

功能

访问远程交换机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()
原文地址:https://www.cnblogs.com/liujitao79/p/4674068.html