Skip to content

Instantly share code, notes, and snippets.

@DamianZaremba
Created February 3, 2013 17:43
Show Gist options
  • Save DamianZaremba/4702763 to your computer and use it in GitHub Desktop.
Save DamianZaremba/4702763 to your computer and use it in GitHub Desktop.
Badly written POC for snmpish switches -> graphite graphing
#!/usr/bin/env python
import time
import re
import socket
from pysnmp.entity.rfc3413.oneliner import cmdgen
cmdGen = cmdgen.CommandGenerator()
CARBON_IP = '10.44.206.51'
CARBON_PORT = 2030
def get_stats(host, community):
errorIndication, errorStatus, errorIndex, varBindTable = cmdGen.bulkCmd(
cmdgen.CommunityData(community),
cmdgen.UdpTransportTarget((host, 161)),
0, 25, '1.3.6.1.2.1.2.2.1',
)
if errorIndication or errorStatus:
# Todo add error logging here
return False
# OID to Object mapping
mapping = {
'1.3.6.1.2.1.2.2.1.10': 'ifInOctets',
'1.3.6.1.2.1.2.2.1.16': 'ifOutOctets',
'1.3.6.1.2.1.2.2.1.11': 'ifInUcastPkts',
'1.3.6.1.2.1.2.2.1.17': 'ifOutUcastPkts',
'1.3.6.1.2.1.2.2.1.13': 'ifInDiscards',
'1.3.6.1.2.1.2.2.1.19': 'ifOutDiscards',
'1.3.6.1.2.1.2.2.1.14': 'ifInErrors',
'1.3.6.1.2.1.2.2.1.20': 'ifOutErrors',
'1.3.6.1.2.1.2.2.1.15': 'ifInUnknownProtos',
'1.3.6.1.2.1.2.2.1.5': 'ifSpeed',
'1.3.6.1.2.1.2.2.1.4': 'ifMtu',
'1.3.6.1.2.1.2.2.1.8': 'ifOperStatus',
'1.3.6.1.2.1.2.2.1.7': 'ifAdminStatus',
'1.3.6.1.2.1.2.2.1.2': 'ifDescr',
}
data = {}
# Go over each table
for varBindTableRow in varBindTable:
# Go over each row
for name, value in varBindTableRow:
# We don't need anything more than the string
value = str(value)
name = str(name)
# Map the values
for m, v in mapping.items():
oid = '%s.' % m
if not name.startswith(oid):
continue
# Grab the port id
pid = str(name).replace(oid, '').strip()
value = str(value).strip()
if len(value) == 0:
# TODO add logging
continue
if len(pid) == 0:
# TODO add logging
continue
# If we've not seen it before make a new entry
if not pid in data.keys():
data[pid] = {}
# Store the data
data[pid][v] = value
# Sort the data
log_data = []
for p, pv in data.items():
if 'ifDescr' not in pv.keys():
# Todo add logging
continue
# Make the log entries
for k, v in pv.items():
# Don't care
if k == 'ifDescr':
continue
# Get rid of anything dodgy
k = str(k).replace(' ', '')
v = str(v).replace(' ', '')
chost = host.replace('.', '_')
interface = pv['ifDescr']
# Make the interface logical <type>.<slot>.<module>.<port>
# For some reason cisco don't do a seperator for the slot -.-
match = re.match('^(([^/0-9.]+)([0-9]+))/?', interface)
if match and len(match.groups()) == 3:
interface = interface.replace(match.group(1), '%s.%s' %
(match.group(2),
match.group(3)))
interface = interface.replace('/', '.')
if not re.match('^[0-9\.]+$', v.strip()):
# Todo add logging
continue
# Network.<Host>.<Interface>.<Metric> <Value> <Time>
host_part = 'network.%s.interfaces.%s' % (chost, interface)
log_data.append('%s.%s %s %d' % (host_part, k, v,
int(time.time())))
# BOOM
return log_data
def send_to_graphite(data):
sock = socket.socket()
try:
sock.connect((CARBON_IP, CARBON_PORT))
except:
# TODO add logging
return False
else:
print "Sending:\n%s\n" % '\n'.join(data)
sock.sendall('%s\n' % '\n'.join(data))
sock.close()
def main(devices):
data = []
# Do something better to loop over devices
# Probably use a threadpool or such
# Maybe be lazy and just use a global list and push data in
for x in devices:
d = get_stats(x[0], x[1])
if d:
data.extend(d)
print "Sending:\n%s\n" % '\n'.join(data)
#send_to_graphite(data)
if __name__ == "__main__":
devices = [('10.70.86.47', 'n1ppl3s'), ]
main(devices)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment