Created
September 18, 2018 08:11
-
-
Save labeneator/046c05b1ae8a63eadc48f7060f366966 to your computer and use it in GitHub Desktop.
Simple Cron invoked job to send metrics from airmax devices to Carbon-cache (Graphite).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
* * * * * root /usr/local/bin/send_metrics.sh |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Create a virtual env with the following packages | |
# This will be sourced by your runner script. (source ~/path/to/my/venv/snmp/bin/activate) | |
backports-abc==0.5 | |
backports.shutil-get-terminal-size==1.0.0 | |
bleach==2.1.4 | |
click==6.7 | |
configparser==3.5.0 | |
decorator==4.3.0 | |
easysnmp==0.2.5 | |
entrypoints==0.2.3 | |
enum34==1.1.6 | |
functools32==3.2.3.post2 | |
futures==3.2.0 | |
html5lib==1.0.1 | |
ipaddress==1.0.22 | |
ipykernel==4.8.2 | |
ipython==5.8.0 | |
ipython-genutils==0.2.0 | |
Jinja2==2.10 | |
jsonschema==2.6.0 | |
jupyter-client==5.2.3 | |
jupyter-core==4.4.0 | |
MarkupSafe==1.0 | |
mistune==0.8.3 | |
nbconvert==5.3.1 | |
nbformat==4.4.0 | |
notebook==5.6.0 | |
pandocfilters==1.4.2 | |
pathlib2==2.3.2 | |
pexpect==4.6.0 | |
pickleshare==0.7.4 | |
prometheus-client==0.3.1 | |
prompt-toolkit==1.0.15 | |
ptyprocess==0.6.0 | |
Pygments==2.2.0 | |
python-dateutil==2.7.3 | |
pyzmq==17.1.2 | |
scandir==1.9.0 | |
Send2Trash==1.5.0 | |
simplegeneric==0.8.1 | |
singledispatch==3.4.0.3 | |
six==1.11.0 | |
terminado==0.8.1 | |
testpath==0.3.1 | |
tornado==5.1 | |
traitlets==4.3.2 | |
wcwidth==0.1.7 | |
webencodings==0.5.1 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
source ~/path/to/my/venv/snmp/bin/activate | |
/usr/local/bin/ubnt_snmp.py --snmp-community public --carbon-host metrics.xyz.co.ke --snmp-host 172.16.0.1 | |
/usr/local/bin/ubnt_snmp.py --snmp-community public --carbon-host metrics.xyz.co.ke --snmp-host 172.16.0.2 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python | |
import click | |
import time | |
import socket | |
from contextlib import closing | |
from easysnmp import Session | |
from collections import defaultdict | |
# Dict of OIDs and functions to transmute their values | |
INTERFACE_DICT = dict( | |
ifInUcastPkts=dict(oid=".1.3.6.1.2.1.2.2.1.11", fn=int), | |
ifInOctets=dict(oid=".1.3.6.1.2.1.2.2.1.10", fn=int), | |
ifAdminStatus=dict(oid=".1.3.6.1.2.1.2.2.1.7", fn=int), | |
ifDescr= dict(oid=".1.3.6.1.2.1.2.2.1.2", fn=lambda x: x), | |
ifInNUcastPkts= dict(oid=".1.3.6.1.2.1.2.2.1.12", fn=int), | |
ifInDiscards=dict(oid=".1.3.6.1.2.1.2.2.1.13", fn=int), | |
ifInErrors=dict(oid=".1.3.6.1.2.1.2.2.1.14", fn=int), | |
ifOutOctets=dict(oid=".1.3.6.1.2.1.2.2.1.16", fn=int), | |
ifOutUcastPkts=dict(oid=".1.3.6.1.2.1.2.2.1.17", fn=int), | |
ifOutNUcastPkts=dict(oid=".1.3.6.1.2.1.2.2.1.18", fn=int), | |
ifOutDiscards=dict(oid=".1.3.6.1.2.1.2.2.1.19", fn=int), | |
ifOutErrors=dict(oid=".1.3.6.1.2.1.2.2.1.20", fn=int), | |
ifOutQLen=dict(oid=".1.3.6.1.2.1.2.2.1.21" , fn=int)) | |
# Change your name space below to fit your carbon/graphite one. | |
def mk_metric_prefix(session): | |
return "<my_name_space>.ubiquiti.airmax." + ".".join([session.get('sysLocation.0').value, session.get('sysName.0').value]) | |
def mk_time(session): | |
return int(session.get('sysUpTimeInstance').value) | |
# Convert the interfaces tree into a dict | |
def mk_interfaces_metrics(session): | |
interfaces = defaultdict(dict) | |
for key, op_dict in INTERFACE_DICT.items(): | |
for idx, entry in enumerate(session.walk(op_dict['oid'])): interfaces[idx][key] = op_dict['fn'](entry.value) | |
return interfaces | |
# Walk the device and generate a dict of metrics | |
def snmp_walk(snmp_version, snmp_host, snmp_community): | |
session = Session(hostname=snmp_host, community=snmp_community, version=snmp_version) | |
metrics_dict = {} | |
metrics_dict['metric_prefix'] = mk_metric_prefix(session) | |
metrics_dict['uptime'] = mk_time(session) | |
metrics_dict['interface_metrics'] = mk_interfaces_metrics(session) | |
return metrics_dict | |
def send_metric(sock, timestamp, metric_prefix, metric): | |
msg = "%s %s %s\n" % (metric_prefix, metric, timestamp) | |
print("Sending: %s" % msg) | |
sock.sendall(msg) | |
def send_metrics(carbon_host, carbon_port, metrics): | |
timestamp = int(time.time()) | |
with closing(socket.socket()) as sock: | |
sock.connect((carbon_host, carbon_port)) | |
metric_prefix = metrics.get('metric_prefix') | |
send_metric(sock, timestamp, metric_prefix+".uptime", metrics.get('uptime')) | |
interface_metrics = metrics.get('interface_metrics') | |
for interface_metric in interface_metrics.values(): | |
interface_name = interface_metric.pop('ifDescr') | |
for metric_name, metric_value in interface_metric.items(): | |
metric_name = "%s.%s.%s" % (metric_prefix, interface_name, metric_name) | |
send_metric(sock, timestamp, metric_name, metric_value) | |
@click.command() | |
@click.option('--snmp-version', default=1, help='SNMP Version.') | |
@click.option('--snmp-host', required=True, help='The host to walk') | |
@click.option('--snmp-community', default='public', help='SNMP Community') | |
@click.option('--carbon-host', default="localhost", help='The carbon host') | |
@click.option('--carbon-port', default=2003, type=int, help='The carbon port') | |
def main(snmp_version, snmp_host, snmp_community, carbon_host, carbon_port): | |
"""Simple program that SNMP walks an AIRMAX device and sends metrics to Carbon""" | |
click.echo('SNMP walking %s' % snmp_host) | |
metrics = snmp_walk(snmp_version, snmp_host, snmp_community) | |
send_metrics(carbon_host, carbon_port, metrics) | |
if __name__ == '__main__': | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment