source: genesis/tools/get-link-traffic.py@ 10035

Last change on this file since 10035 was 10035, checked in by rick, 13 years ago

MultiManager dict is buggy.

  • Property svn:executable set to *
File size: 4.2 KB
Line 
1#!/usr/bin/env python
2#
3# XXX: Parsing snmpwalk is soo wrong todo, use a proper python library.
4#
5#
6# Rick van der Zwet <info@rickvanderzwet.nl>
7#
8import glob
9import logging
10import subprocess
11import sys
12import yaml
13from multiprocessing import Process, Manager, Pool, Queue, freeze_support
14
15logging.basicConfig(level=logging.DEBUG)
16logger = logging.getLogger()
17
18
19
20DATASTORE='store.yaml'
21
22class ConnectError(Exception):
23 pass
24
25def get_snmp_stats(logger, ip,target):
26 p = subprocess.Popen("snmpwalk -t 1 -r 1 -Oq -c public -v2c %s %s" % (ip, target),
27 shell=True,
28 stdout=subprocess.PIPE, stderr=subprocess.PIPE)
29 (stdout, stderr) = p.communicate()
30 if p.returncode != 0:
31 logger.error(stderr.strip())
32 raise ConnectError
33 r = {}
34 for line in stdout.strip().split('\n'):
35 index = line.split()[0][len(target)+1:]
36 value = line.split()[1]
37 r[index] = value
38 return r
39
40def get_snmp_value(logger, ip, target):
41 p = subprocess.Popen("snmpget -t 1 -r 1 -Ovt -c public -v2c %s %s" % (ip, target),
42 shell=True,
43 stdout=subprocess.PIPE, stderr=subprocess.PIPE)
44 (stdout, stderr) = p.communicate()
45 if p.returncode != 0:
46 logger.error(stderr.strip())
47 raise ConnectError
48 return stdout.strip()
49
50def find_right_snmp_ip(logger, data):
51 for k,v in data.iteritems():
52 if k.startswith('iface_'):
53 ip = v['ip'].split('/')[0]
54 logger.info("Trying ip %s", ip)
55 try:
56 uptime = get_snmp_value(logger, ip, 'DISMAN-EVENT-MIB::sysUpTimeInstance')
57 return ip
58 except ConnectError:
59 pass
60 return None
61
62try:
63 ff = sys.argv[1]
64except IndexError:
65 ff = ''
66
67def process_file(logger, m_snmp, m_traffic, m_uptime, nf, rescan):
68 data = yaml.load(open(nf,'r'))
69 nodename = data['nodename']
70
71 if m_snmp.has_key(nodename):
72 ip = m_snmp[nodename]
73 if not ip and rescan:
74 logger.info("Re-scanning for new valid IP")
75 ip = find_right_snmp_ip(logger, data)
76 m_snmp[nodename] = ip
77 else:
78 try:
79 uptime = get_snmp_value(logger, ip, 'DISMAN-EVENT-MIB::sysUpTimeInstance')
80 except ConnectError:
81 logger.info("Re-scanning for new valid IP")
82 ip = find_right_snmp_ip(logger, data)
83 m_snmp[nodename] = ip
84 else:
85 logger.info("Running discovery for %s", nodename)
86 ip = find_right_snmp_ip(logger, data)
87 m_snmp[nodename] = ip
88
89 if ip == None:
90 logger.error("No valid ip found for node %s", nodename)
91 return
92
93 logger.info("Processing %s via %s", nodename, ip)
94 target = 'IF-MIB::ifDescr'
95
96 try:
97 iface = get_snmp_stats(logger, ip, 'IF-MIB::ifDescr')
98 ifout = get_snmp_stats(logger, ip, 'IF-MIB::ifOutOctets')
99 ifin = get_snmp_stats(logger, ip, 'IF-MIB::ifInOctets')
100
101 uptime = get_snmp_value(logger, ip, 'DISMAN-EVENT-MIB::sysUpTimeInstance')
102 m_uptime[nodename] = int(uptime)
103
104 traffic = {}
105 for i,f in iface.iteritems():
106 traffic[f] = (int(ifin[i]), int(ifout[i]))
107 m_traffic[nodename] = traffic
108 except ConnectError:
109 logger.error("Unable to get all data")
110 pass
111
112def worker(i, input, m_snmp, m_traffic, m_uptime):
113 logger = logging.getLogger('Worker%s' % i)
114 logger.info("Worker")
115 for (nf, rescan) in iter(input.get, 'STOP'):
116 process_file(logger, m_snmp, m_traffic, m_uptime, nf, rescan)
117 logger.info("END")
118
119if __name__ == '__main__':
120 freeze_support()
121 task_queue = Queue()
122 manager = Manager()
123
124 try:
125 store = yaml.load(open(DATASTORE,'r'))
126 except IOError:
127 store = { 'snmp' : {}, 'traffic' : {}, 'uptime' : {}}
128 pass
129 # XXX: Manager.dict has bug of handling dicts inside dicts, using awefull quick
130 # XXX: http://bugs.python.org/issue6766
131 m_snmp = manager.dict(store['snmp'])
132 m_traffic = manager.dict(store['traffic'])
133 m_uptime = manager.dict(store['uptime'])
134
135 NUMBER_OF_PROCESSES = 10
136 RESCAN = True
137 plist = {}
138 for i in range(NUMBER_OF_PROCESSES):
139 plist[i] = Process(target=worker, args=(i, task_queue,m_snmp,m_traffic,m_uptime))
140 plist[i].start()
141
142 for nf in sorted(glob.glob('nodes/*%s*/wleiden.yaml' % ff)):
143 task_queue.put((nf, RESCAN))
144
145 for i in range(NUMBER_OF_PROCESSES):
146 task_queue.put('STOP')
147
148 for i in range(NUMBER_OF_PROCESSES):
149 plist[i].join()
150
151 store = {'snmp' : dict(m_snmp), 'traffic' : dict(m_traffic), 'uptime' : dict(m_uptime)}
152 yaml.dump(store,open(DATASTORE,'w'))
153
154
155
Note: See TracBrowser for help on using the repository browser.