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

Last change on this file since 10801 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.