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

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

Do not chdir as it confuses storing files without an prefix in the WC.

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