Skip to content

Instantly share code, notes, and snippets.

@labeneator
Last active August 28, 2021 17:40
Show Gist options
  • Save labeneator/63efa85a10ec81835a2f4b0ac820954a to your computer and use it in GitHub Desktop.
Save labeneator/63efa85a10ec81835a2f4b0ac820954a to your computer and use it in GitHub Desktop.
Script to send SNMP metrics from Ubiquiti devices to graphite.
* * * * * root /usr/local/bin/send_metrics.sh
#!/bin/bash
# Source from:
# cat /usr/local/bin/send_metrics.sh
# Activate enviroment that has easysnmp installed
source ~someuser/venvs/snmp/bin/activate
# 192.168.0.64 is your Ubiquiti device
/usr/local/bin/ubnt_snmp.py --snmp-community myCommunity --carbon-host metrics.yourcompany.co.ke --snmp-host 192.168.0.64
#!/usr/bin/env python
# Source from:
# cat /usr/local/bin/ubnt_snmp.py
import click
import time
import socket
from contextlib import closing
from easysnmp import Session
from collections import defaultdict
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))
def mk_metric_prefix(session):
return "snmp.ubiquiti.airmax." + ".".join([session.get('sysLocation.0').value, session.get('sysName.0').value])
def mk_time(session):
return int(session.get('sysUpTimeInstance').value)
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
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