#!/usr/bin/perl ############################################################################### # #Multigraph munin plugin to monitor Ubiquiti AirOS devices various parameters. # #To use this plugin, copy it to the munin's plugin directory (eg. /usr/share/munin/plugins) #under the name "ubiquiti_airos_". Don't change this filename! Follow these steps: # #1. Give names to your devices, in fqdn style. Like "apo.wlan" or "cli.wlan". To make the # system understand that, in your /etc/hosts file, add to localhost these names which corespond # to your devices: # 127.0.0.1 localhost apo.wlan cli.wlan # Don't be fooled by 127.0.0.1, this is the localhost IP address, since munin will handle # them as virtual nodes! # #2. Then symlink it to munin's configured plugins directory (eg. /etc/munin/plugins) with names # according to the devices you wish to monitor, eg: # ubiquiti_airos_apo.wlan # ubiquiti_airos_cli.wlan # # Important: make sure to use the same names in your symlinks and other config places! # #3. In /etc/munin/plugin-conf.d/munin-node add the following, to be able to contact # those devices via telnet (obviously replacing these with your own data): # # [ubiquiti_airos_apo.wlan] # env.Name AccessPoint # env.Host 192.168.2.2 # env.TelnetPort 23 # env.TelnetUser foobar # env.TelnetPass raboof # # [ubiquiti_airos_cli.wlan] # env.Name Client # env.Host 192.168.2.3 # env.TelnetPort 23 # env.TelnetUser foobar # env.TelnetPass raboof # #4. In /etc/munin/munin.conf add them as new virtual nodes: # # [apo.wlan] # address 127.0.0.1 # # [cli.wlan] # address 127.0.0.1 # #5. Restart the munin node by 'service munin-node restart'. # # If all went well, after 5 minutes or so you should have two additional nodes listed # on the Web Interface of munin. # #Plugin based on aramsey's script, which is based on a MicroTik plugin, see for more info see this link: #http://community.ubnt.com/t5/NanoStation-and-Loco-Devices/SNMP-data-for-NF-dBm/m-p/39070/highlight/true#M11372 # #Tested & working with munin v.2.0.14 and AirOS v5.5.4. #Created in 2013 by robi # ############################################################################### use diagnostics; use Net::Telnet; use strict; use warnings; ############################################################################## ## Retrieve environmental variables my $Name = $ENV{'Name'}; my $Host = $ENV{'Host'}; my $TelnetPort = $ENV{'TelnetPort'}; my $TelnetUser = $ENV{'TelnetUser'}; my $TelnetPass = $ENV{'TelnetPass'}; my $graph_period = "second"; ############################################################################### ## Determine Hostname my $Hostname = undef; $0 =~ /ubiquiti_airos_(.+)*$/; unless ($Hostname = $1) { exit 2; } ############################################################################### ## Initiate Telnet Session my $MT = Net::Telnet->new(Host => $Host, Port => $TelnetPort, Prompt => '/ $/', Timeout => 30); ############################################################################### ## Configuration if(exists $ARGV[0] and $ARGV[0] eq "config") { print "multigraph airos_load\n"; print "host_name " . $Hostname . "\n"; print "graph_args --base 1000 -l 0 \n"; print "graph_title Load average\n"; print "graph_vlabel load\n"; print "graph_category system\n"; print "graph_scale no\n"; print "load.label load\n"; print "graph_info The load average of " . $Name . " describes how many processes are in the run-queue (scheduled to run 'immediately').\n"; print "load.info 5 minute load average\n"; print "\n"; print "multigraph airos_uptime\n"; print "host_name " . $Hostname . "\n"; print "graph_args --base 1000 -l 0 \n"; print "graph_title Uptime\n"; print "graph_vlabel uptime in days\n"; print "graph_category system\n"; print "graph_scale no\n"; print "uptime.label uptime\n"; print "uptime.draw AREA\n"; print "graph_info This graph shows how many days have passed since the bootup of " . $Name . ".\n"; print "\n"; print "multigraph airos_airmax\n"; print "host_name " . $Hostname . "\n"; print "graph_args -l 0 --lower-limit 0 --upper-limit 100\n"; print "graph_title AirMAX Quality and Capacity\n"; print "graph_vlabel %\n"; print "graph_category radio\n"; print "graph_info This graph shows the AirMAX Quality and AirMAX Capacity of " . $Name . ".\n"; print "graph_scale no\n"; print "amc.label AirMAX Capacity\n"; print "amq.label AirMAX Quality\n"; print "\n"; print "multigraph airos_wconn\n"; print "host_name " . $Hostname . "\n"; print "graph_title WLAN connections\n"; print "graph_category network\n"; print "graph_info This graph shows the number of wireless connections to the wlan interface of " . $Name . ".\n"; print "graph_scale no\n"; print "conn.label Connections\n"; print "\n"; print "multigraph airos_errl\n"; print "graph_order errlrcvd errltrans\n"; print "graph_args --base 1000\n"; print "graph_period " . $graph_period . "\n"; print "graph_vlabel packets in (-) / out (+) per " . $graph_period . "\n"; print "graph_info This graph shows the amount of errors on the LAN network interface of " . $Name . ".\n"; print "errlrcvd.label errors\n"; print "errlrcvd.type COUNTER\n"; print "errlrcvd.graph no\n"; print "errlrcvd.warning 1\n"; print "errltrans.label errors\n"; print "errltrans.type COUNTER\n"; print "errltrans.negative errlrcvd\n"; print "errltrans.warning 1\n"; print "host_name " . $Hostname . "\n"; print "graph_title LAN errors\n"; print "graph_category network\n"; print "\n"; print "multigraph airos_errw\n"; print "graph_order errwrcvd errwtrans\n"; print "graph_args --base 1000\n"; print "graph_period " . $graph_period . "\n"; print "graph_vlabel packets in (-) / out (+) per " . $graph_period . "\n"; print "graph_info This graph shows the amount of errors on the WLAN network interface of " . $Name . ".\n"; print "errwrcvd.label errors\n"; print "errwrcvd.type COUNTER\n"; print "errwrcvd.graph no\n"; print "errwrcvd.warning 1\n"; print "errwtrans.label errors\n"; print "errwtrans.type COUNTER\n"; print "errwtrans.negative errwrcvd\n"; print "errwtrans.warning 1\n"; print "host_name " . $Hostname . "\n"; print "graph_title WLAN errors\n"; print "graph_category network\n"; print "\n"; print "multigraph airos_trfl\n"; print "graph_order trfldown trflup\n"; print "graph_args --base 1000\n"; print "graph_period " . $graph_period . "\n"; print "graph_vlabel bits in (-) / out (+) per " . $graph_period . "\n"; print "graph_info This graph shows the traffic of the LAN network interface of " . $Name . ".\n"; print "trfldown.label received\n"; print "trfldown.type DERIVE\n"; print "trfldown.graph no\n"; print "trfldown.cdef trfldown,8,*\n"; print "trfldown.min 0\n"; print "trflup.label bps\n"; print "trflup.type DERIVE\n"; print "trflup.negative trfldown\n"; print "trflup.cdef trflup,8,*\n"; print "trflup.min 0\n"; print "host_name " . $Hostname . "\n"; print "graph_title LAN traffic\n"; print "graph_category network\n"; print "\n"; print "multigraph airos_trfw\n"; print "graph_order down up\n"; print "graph_args --base 1000\n"; print "graph_period " . $graph_period . "\n"; print "graph_vlabel bits in (-) / out (+) per " . $graph_period . "\n"; print "graph_info This graph shows the traffic of the WLAN network interface of " . $Name . ".\n"; print "trfwdown.label received\n"; print "trfwdown.type DERIVE\n"; print "trfwdown.graph no\n"; print "trfwdown.cdef trfwdown,8,*\n"; print "trfwdown.min 0\n"; print "trfwup.label bps\n"; print "trfwup.type DERIVE\n"; print "trfwup.negative trfwdown\n"; print "trfwup.cdef trfwup,8,*\n"; print "trfwup.min 0\n"; print "host_name " . $Hostname . "\n"; print "graph_title WLAN traffic\n"; print "graph_category network\n"; print "\n"; print "multigraph airos_freq\n"; print "host_name " . $Hostname . "\n"; print "graph_args -l 0 --units-exponent 0 --lower-limit 5100 --upper-limit 5800\n"; print "graph_title Frequency\n"; print "graph_vlabel MHz\n"; print "graph_category radio\n"; print "graph_info This graph shows the operating frequency of the wireless interface of " . $Name . ".\n"; print "graph_scale no\n"; print "freq.label MHz\n"; print "\n"; print "multigraph airos_mem\n"; print "host_name " . $Hostname . "\n"; print "graph_args -l 0 \n"; print "graph_title Memory usage\n"; print "graph_vlabel kB\n"; print "graph_category system\n"; print "graph_info This graph shows the device memory usage status of " . $Name . ".\n"; print "memTotal.label Total\n"; print "memFree.label Free\n"; print "memBuffers.label Buffers\n"; print "\n"; print "multigraph airos_ccq\n"; print "host_name " . $Hostname . "\n"; print "graph_args -l 0 --lower-limit 0 --upper-limit 100\n"; print "graph_title Client Connection Quality\n"; print "graph_vlabel %\n"; print "graph_category radio\n"; print "graph_info This graph shows the Client Connection Quality value of " . $Name . ".\n"; print "graph_scale no\n"; print "txccq.label Transmit CCQ\n"; print "\n"; print "multigraph airos_ack\n"; print "host_name " . $Hostname . "\n"; print "graph_title ACK timeout\n"; print "graph_vlabel us\n"; print "graph_category radio\n"; print "graph_info This graph shows the ACK (Acknowledgement) timeout value of " . $Name . ".\n"; print "acttimeout.label ACK Timeout\n"; print "\n"; print "multigraph airos_dbm\n"; print "host_name " . $Hostname . "\n"; print "graph_title Signal levels\n"; print "graph_vlabel dBm\n"; print "graph_category radio\n"; print "graph_info This graph shows the radio signal levels of " . $Name . ".\n"; print "txsignal.label Signal Strength\n"; print "noisefloor.label Noise Floor\n"; print "\n"; print "multigraph airos_wrate\n"; print "graph_order rxrate txrate\n"; print "graph_args -l 0 --lower-limit -300 --upper-limit 300\n"; print "graph_period " . $graph_period . "\n"; print "graph_vlabel RX (-) / TX (+) Mbps\n"; print "graph_info This graph shows the wireless link connection speed of " . $Name . ".\n"; print "rxrate.label RX/TX Rate\n"; print "rxrate.graph no\n"; # print "rxrate.min 0\n"; print "txrate.label Mbps\n"; print "txrate.negative rxrate\n"; # print "txrate.min 0\n"; print "host_name " . $Hostname . "\n"; print "graph_category radio\n"; print "graph_title Wireless link speed\n"; print "\n"; exit; } ############################################################################### ## Execution if (!defined($MT->login($TelnetUser, $TelnetPass))) { die "Croaking: $MT->error"; } else { my @OutLoad = $MT->cmd("cat /proc/loadavg\n"); my ($load) = undef; foreach my $Line (@OutLoad) { if ($Line !~ /XM.v/ && $Line =~ m/(\d+)/) { $load = substr($Line, 0,4); } } my @OutUpt = $MT->cmd("cat /proc/uptime\n"); my ($uptime) = undef; foreach my $Line (@OutUpt) { if ($Line !~ /XM.v/ && $Line =~ m/(\d+)/) { $uptime = $1 / 86400; } } my @OutMca = $MT->cmd("ubntbox mca-status\n"); my ($amc, $amq, $conn, $mt, $mf, $mb, $errlrcvd, $errltrans, $errwrcvd, $errwtrans, $trflup, $trfldown, $trfwup, $trfwdown, $freq, $txccq, $acttimeout, $txsignal, $noisefloor, $txrate, $rxrate) = undef; foreach my $Line (@OutMca) { if ($Line =~ /wlanRxErrors/ && $Line =~ m/(.\d+)/) { $errwrcvd = substr($Line, 13); } if ($Line =~ /wlanTxErrors/ && $Line =~ m/(.\d+)/) { $errwtrans = substr($Line, 13); } if ($Line =~ /lanRxErrors/ && $Line !~ /wlan/ && $Line =~ m/(.\d+)/) { $errlrcvd = substr($Line, 12); } if ($Line =~ /lanTxErrors/ && $Line !~ /wlan/ && $Line =~ m/(.\d+)/) { $errltrans = substr($Line, 12); } if ($Line =~ /wlanPollingCapacity/ && $Line =~ m/(.\d+)/) { $amc = substr($Line, 20); } if ($Line =~ /wlanPollingQuality/ && $Line =~ m/(.\d+)/) { $amq = substr($Line, 19); } if ($Line =~ /wlanConnections/ && $Line =~ m/(.\d+)/) { $conn = substr($Line, 16); } if ($Line =~ /lanRxBytes/ && $Line !~ /wlan/ && $Line =~ m/(.\d+)/) { $trfldown = substr($Line, 11); } if ($Line =~ /lanTxBytes/ && $Line !~ /wlan/ && $Line =~ m/(.\d+)/) { $trflup = substr($Line, 11); } if ($Line =~ /wlanRxBytes/ && $Line =~ m/(.\d+)/) { $trfwdown = substr($Line, 12); } if ($Line =~ /wlanTxBytes/ && $Line =~ m/(.\d+)/) { $trfwup = substr($Line, 12); } if ($Line =~ /freq/ && $Line =~ m/(.\d+)/) { $freq = substr($Line, 5); } if ($Line =~ /memTotal/ && $Line =~ m/(\d+)/) { $mt = $1; } if ($Line =~ /memFree/ && $Line =~ m/(\d+)/) { $mf = $1; } if ($Line =~ /memBuffers/ && $Line =~ m/(\d+)/) { $mb = $1; } if (($Line =~ /ccq/ && $Line !~ /overall-tx-ccq/) && $Line =~ m/(\d+)/) { $txccq = $1 / 10; } if ($Line =~ /signal/ && $Line =~ m/(.\d+)/) { $txsignal = $1; } if ($Line =~ /noise/ && $Line =~ m/(.\d+)/) { $noisefloor = $1; } if ($Line =~ /ackTimeout/ && $Line =~ m/(\d+)/) { $acttimeout = $1; } if ($Line =~ /wlanTxRate/ && $Line =~ m/(\d+)/) { $txrate = $1; } if ($Line =~ /wlanRxRate/ && $Line =~ m/(\d+)/) { $rxrate = $1; } } print "multigraph airos_wrate\n"; print "txrate.value " . $txrate . "\n"; print "rxrate.value " . $rxrate . "\n"; print "\n"; print "multigraph airos_ccq\n"; print "txccq.value " . $txccq . "\n"; print "\n"; print "multigraph airos_ack\n"; print "acttimeout.value " . $acttimeout . "\n"; print "\n"; print "multigraph airos_dbm\n"; print "txsignal.value " . $txsignal . "\n"; print "noisefloor.value " . $noisefloor . "\n"; print "\n"; print "multigraph airos_mem\n"; print "memTotal.value " . $mt . "\n"; print "memFree.value " . $mf . "\n"; print "memBuffers.value " . $mb . "\n"; print "\n"; print "multigraph airos_freq\n"; print "freq.value " . $freq;# . "\n"; print "\n"; print "multigraph airos_trfw\n"; print "trfwup.value " . $trfwup;# . "\n"; print "trfwdown.value " . $trfwdown;# . "\n"; print "\n"; print "multigraph airos_trfl\n"; print "trflup.value " . $trflup;# . "\n"; print "trfldown.value " . $trfldown;# . "\n"; print "\n"; print "multigraph airos_errw\n"; print "errwrcvd.value " . $errwrcvd;# . "\n"; print "errwtrans.value " . $errwtrans;# . "\n"; print "\n"; print "multigraph airos_errl\n"; print "errlrcvd.value " . $errlrcvd;# . "\n"; print "errltrans.value " . $errltrans;# . "\n"; print "\n"; print "multigraph airos_airmax\n"; print "amc.value " . $amc;# . "\n"; print "amq.value " . $amq;# . "\n"; print "\n"; print "multigraph airos_wconn\n"; print "conn.value " . $conn;# . "\n"; print "\n"; print "multigraph airos_load\n"; print "load.value " . $load . "\n"; print "\n"; print "multigraph airos_uptime\n"; print "uptime.value " . $uptime . "\n"; print "\n"; exit; }