Last active
August 28, 2021 17:40
-
-
Save labeneator/63efa85a10ec81835a2f4b0ac820954a to your computer and use it in GitHub Desktop.
Script to send SNMP metrics from Ubiquiti devices to graphite.
This file contains 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 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 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 |
This file contains 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 | |
# 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