1
0
Fork 0
mirror of https://github.com/munin-monitoring/contrib.git synced 2025-09-18 16:48:44 +00:00

Plugin-Gallery: Better 2nd level headings

This commit is contained in:
dipohl 2017-02-24 04:09:58 +01:00
parent e10e386b02
commit d216113740
24 changed files with 5 additions and 5 deletions

View file

@ -1,83 +0,0 @@
#!/usr/bin/env python3
# -*- python -*-
# This plugin graphs the following values of the ARRIS TM502G cable
# modem:
#
# * upstream and downstream powers
# * downstream signal-to-noise ratio
#
# The values are retrieved from the cable modem's status web pages at
# 192.168.100.1. So, this plugin must be installed on a munin node
# which can access those pages.
#
# Symlink this plugin into the node's plugins directory (like
# /etc/munin/plugins) as arris-tm502g_power for the powers, and
# arris-tm502g_snr for the SNR.
#
# Copyright © 2013 Kenyon Ralph <kenyon@kenyonralph.com>
#
# This program is free software. It comes without any warranty, to the
# extent permitted by applicable law. You can redistribute it and/or
# modify it under the terms of the Do What The Fuck You Want To Public
# License, Version 2, as published by Sam Hocevar. See
# http://www.wtfpl.net/ for more details.
#
# The latest version of this plugin can be found in the munin contrib
# repository at https://github.com/munin-monitoring/contrib. Issues
# with this plugin may be reported there. Patches accepted through the
# normal github process of forking the repository and submitting a
# pull request with your commits.
import html.parser
import os
import urllib.request
import sys
plugin_name=list(os.path.split(sys.argv[0]))[1]
plugin_var=plugin_name.split('_', 1)[-1]
if len(sys.argv) == 2 and sys.argv[1] == 'config':
if plugin_var == 'power':
print('graph_title ARRIS Cable Modem Power')
print('graph_vlabel Signal Strength (dBmV)')
print('graph_info This graph shows the downstream and upstream power reported by an ARRIS TM502G cable modem.')
print('downstream.label Downstream Power (dBmV)')
print('upstream.label Upstream Power (dBmV)')
if plugin_var == 'snr':
print('graph_title ARRIS Cable Modem SNR')
print('graph_vlabel Signal-to-Noise Ratio (dB)')
print('graph_info This graph shows the downstream signal-to-noise ratio reported by an ARRIS TM502G cable modem.')
print('snr.label Signal-to-Noise Ratio (dB)')
print('graph_category network')
sys.exit(0)
class ArrisHTMLParser(html.parser.HTMLParser):
stats = list()
down_power = 'U'
up_power = 'U'
snr = 'U'
def handle_data(self, data):
data = data.strip()
if data != '' and 'dB' in data:
self.stats.append(data)
def done(self):
"""Call this when done feeding the HTML page to the parser."""
self.down_power = self.stats[0].split()[0]
self.snr = self.stats[1].split()[0]
self.up_power = self.stats[2].split()[0]
page = urllib.request.urlopen("http://192.168.100.1/")
parser = ArrisHTMLParser()
for line in page:
parser.feed(line.decode())
parser.done()
if plugin_var == 'power':
print('downstream.value ' + parser.down_power)
print('upstream.value ' + parser.up_power)
sys.exit(0)
if plugin_var == 'snr':
print('snr.value ' + parser.snr)
sys.exit(0)

View file

@ -1,253 +0,0 @@
#!/usr/bin/ruby
#
# Munin plugin for the D-link DIR-655 router
#
# This plugin can graph # of wifi clients, # of DHCP clients, collisions & errors for all network interfaces, dropped packets for all interfaces, and both transmit and receive rates for all interfaces of the router.
#
# Author: David Reitz
#
# 1. Copy script to a Linux server on your network.
# 2. Create symlink. (ln -s /path/to/dlink_dir655 /etc/munin/plugins/dlink_dir655)
# 3. Edit plugin configuration for this script (vi /etc/munin/plugin-conf.d/munin-node) and add:
# [dlink_dir655]
# host_name dir655
# env.router_password password
# env.router_ip_address 10.0.0.1
# 4. Edit munin configuration to point to itself to gather the data from your router (vi /etc/munin/munin-conf.d/munin) and add:
# [dir655]
# address 127.0.0.1
# use_node_name no
# 5. Modify the 'password' and 'router_path' variables below to reflect the correct password for the 'User' user on your D-link DIR-655 router and to reflect the correct IP address of your router (this *MUST* be on your local subnet/LAN).
#
# NOTICE 1: This is the first Ruby script I've written (as well as being my first Munin plugin), so I consider this a bit of a hack. Just letting you know ahead of time. :)
#
# NOTICE 2: I provide this script *as-is*. Use at your own risk! I thought other people may find this script useful/interesting but have no plans to support it for anyone else.
#
# Many thanks go to Clarke Brunsdon for his code listed at http://clarkebrunsdon.com/2010/12/the-dlink-dir-655-hash-changes/!!! This really helped me out!
#
# Original Implementation: 13 Jan 2011
gem 'mechanize'
require 'mechanize'
require 'digest/md5'
require 'nokogiri'
def output
nics = Hash.new
nics["LAN"] = Hash.new
nics["WAN"] = Hash.new
nics["WLAN"] = Hash.new
password = ENV['router_password'] || ""
router_path = ENV['router_ip_address'] || "10.0.0.1"
router_path = "http://" + router_path
agent = Mechanize.new
x = agent.get(router_path)
salt = x.body.match(/salt = "(.*)"/)[1]
# pad the pasword to length 16
pad_size = (16 - password.length)
padded_password = password + "\x01" * pad_size
# pad it the rest of the way, length 64 for user
salted_password = salt + padded_password + ("\x01" * (63 - salt.length - padded_password.length)) + "U"
login_hash = salt + Digest::MD5.hexdigest(salted_password)
# authenticate against the router using the hash that we just built
login_path = "#{router_path}/post_login.xml?hash=#{login_hash}"
x = agent.get(login_path)
# grab the statistics for all interfaces and parse it into a usable form
clients_xml = agent.get("#{router_path}/interface_stats.xml").body
doc = Nokogiri::XML(clients_xml.to_s)
doc.xpath('//interface').each do |interface|
children = interface.children
name = children.search('name')[0].text
nics[name]["packets_sent"] = children.search('packets_sent')[0].text
nics[name]["packets_received"] = children.search('packets_received')[0].text
nics[name]["tx_dropped"] = children.search('tx_dropped')[0].text
begin
nics[name]["tx_collisions"] = children.search('tx_collisions')[0].text
rescue Exception
nics[name]["tx_collisions"] = "0"
end
nics[name]["rx_dropped"] = children.search('rx_dropped')[0].text
nics[name]["rx_errors"] = children.search('rx_errors')[0].text
end
# get wifi associations and print out info for munin graph
puts "multigraph clients"
clients_xml = agent.get("#{router_path}/wifi_assoc.xml").body
j = 0
doc = Nokogiri::XML(clients_xml.to_s)
doc.xpath('//assoc').each do |assoc|
j+=1
end
puts "wifi_assoc.value " + j.to_s
# get dhcp clients and print out info for munin graph
clients_xml = agent.get("#{router_path}/dhcp_clients.xml").body
j = 0
doc = Nokogiri::XML(clients_xml.to_s)
doc.xpath('//client').each do |client|
j+=1
end
puts "dhcp_clients.value " + j.to_s
puts "multigraph uptime"
# get uptime of connection
clients_xml = agent.get("#{router_path}/wan_connection_status.xml").body
doc = Nokogiri::XML(clients_xml.to_s)
uptime = doc.children.search('wan_interface_up_time_0')[0].text
puts "uptime.value " + sprintf( "%.2f", (Float(uptime)/86400) )
# graph overall interface packets transferred per interval
puts "multigraph if_packets"
for i in [ "LAN", "WAN", "WLAN" ] do
puts "#{i}_recv.value " + nics[i]["packets_received"]
puts "#{i}_send.value " + nics[i]["packets_sent"]
end
# graph overall interface dropped packets per interval
puts "multigraph if_drop"
for i in [ "LAN", "WAN", "WLAN" ] do
puts "#{i}_recv.value " + nics[i]["rx_dropped"]
puts "#{i}_send.value " + nics[i]["tx_dropped"]
end
# graph overall interface collisions & errors per interval
puts "multigraph if_collerr"
for i in [ "LAN", "WAN", "WLAN" ] do
puts "#{i}_coll.value " + nics[i]["tx_collisions"]
puts "#{i}_err.value " + nics[i]["rx_errors"]
end
# graph stats for each interface
for i in [ "LAN", "WAN", "WLAN" ] do
puts "multigraph if_packets.#{i}"
puts "send.value " + nics[i]["packets_sent"]
puts "recv.value " + nics[i]["packets_received"]
puts "multigraph if_drop.#{i}"
puts "send.value " + nics[i]["tx_dropped"]
puts "recv.value " + nics[i]["rx_dropped"]
puts "multigraph if_collerr.#{i}"
puts "coll.value " + nics[i]["tx_collisions"]
puts "err.value " + nics[i]["rx_errors"]
end
end
def config
# build the configuration for graphs
puts "multigraph if_packets"
puts 'graph_title D-Link DIR-655 interface traffic'
puts 'graph_category network'
puts 'graph_order LAN_recv LAN_send WAN_recv WAN_send WLAN_recv WLAN_send'
puts 'graph_vlabel packets in (-) / out (+) per ${graph_period}'
for i in [ "LAN", "WAN", "WLAN" ] do
puts "#{i}_recv.type DERIVE"
puts "#{i}_recv.graph no"
puts "#{i}_recv.min 0"
puts "#{i}_send.label #{i}"
puts "#{i}_send.type DERIVE"
puts "#{i}_send.negative #{i}_recv"
puts "#{i}_send.min 0"
end
puts "multigraph if_drop"
puts 'graph_title D-Link DIR-655 interface drops'
puts 'graph_category network'
puts 'graph_order LAN_recv LAN_send WAN_recv WAN_send WLAN_recv WLAN_send'
puts 'graph_vlabel packets / ${graph_period}'
for i in [ "LAN", "WAN", "WLAN" ] do
puts "#{i}_recv.type DERIVE"
puts "#{i}_recv.graph no"
puts "#{i}_recv.min 0"
puts "#{i}_send.label #{i}"
puts "#{i}_send.type DERIVE"
puts "#{i}_send.negative #{i}_recv"
puts "#{i}_send.min 0"
end
puts "multigraph if_collerr"
puts 'graph_title D-Link DIR-655 interface collisions & errors'
puts 'graph_category network'
puts 'graph_order LAN_coll LAN_err WAN_coll WAN_err WLAN_coll WLAN_coll'
puts 'graph_vlabel packets / ${graph_period}'
for i in [ "LAN", "WAN", "WLAN" ] do
puts "#{i}_coll.label #{i} collisions"
puts "#{i}_coll.type DERIVE"
puts "#{i}_coll.min 0"
puts "#{i}_err.label #{i} errors"
puts "#{i}_err.type DERIVE"
puts "#{i}_err.min 0"
end
puts "multigraph clients"
puts "graph_title D-Link DIR-655 client information"
puts "graph_category system"
puts "graph_order dhcp_clients wifi_assoc"
puts "graph_vlabel number of clients"
puts "dhcp_clients.label DHCP clients"
puts "dhcp_clients.type GAUGE"
puts "dhcp_clients.min 0"
puts "wifi_assoc.label wifi clients"
puts "wifi_assoc.type GAUGE"
puts "wifi_assoc.min 0"
puts "multigraph uptime"
puts "graph_title Uptime"
puts 'graph_vlabel uptime in days'
puts 'graph_category system'
puts 'uptime.label uptime'
puts 'uptime.draw AREA'
for i in [ "LAN", "WAN", "WLAN" ] do
puts "multigraph if_packets.#{i}"
puts "graph_title D-Link DIR-655 #{i} traffic"
puts 'graph_category network'
puts 'graph_order recv send'
puts 'graph_vlabel packets in (-) / out (+) per ${graph_period}'
puts 'recv.label received'
puts 'recv.type DERIVE'
puts 'recv.graph no'
puts 'recv.min 0'
puts 'send.label packets/sec'
puts 'send.type DERIVE'
puts 'send.negative recv'
puts 'send.min 0'
puts "multigraph if_drop.#{i}"
puts "graph_title D-Link DIR-655 #{i} drops"
puts 'graph_category network'
puts 'graph_order recv send'
puts 'graph_vlabel packets / ${graph_period}'
puts 'recv.label RX packets dropped'
puts 'recv.type DERIVE'
puts 'recv.graph no'
puts 'recv.min 0'
puts 'send.label TX packets dropped'
puts 'send.type DERIVE'
puts 'send.negative recv'
puts 'send.min 0'
puts "multigraph if_collerr.#{i}"
puts "graph_title D-Link DIR-655 #{i} collisions & errors"
puts 'graph_category network'
puts 'graph_order coll err'
puts 'graph_vlabel packets / ${graph_period}'
puts 'coll.label collisions'
puts 'coll.type DERIVE'
puts 'coll.min 0'
puts 'err.label errors'
puts 'err.type DERIVE'
puts 'err.min 0'
end
end
# main
if ARGV.length == 1 and ARGV[0] == 'config'
config()
else
output()
end

View file

@ -1,138 +0,0 @@
#! /bin/sh
# Parse box information
# (c) 2013 - GPLv2 - Steve Schnepp <steve.schnepp@pwkf.org>
#
# Configuration is done via ENV vars, here is the default :
#
# [dartybox]
# env.IP 192.168.1.254
. $MUNIN_LIBDIR/plugins/plugin.sh
is_multigraph
# fail on error
set -e
IP=${IP:-"192.168.1.254"}
if [ "$1" = "config" ]
then
echo multigraph dbox_adsl_bw
echo graph_title DartyBox Adsl Bandwidth
echo graph_category other
echo up.label UpStream
echo down.label DownStream
echo multigraph dbox_adsl_att
echo graph_title DartyBox Adsl Attenuation
echo graph_category other
echo up.label UpStream
echo down.label DownStream
echo multigraph dbox_adsl_snr
echo graph_title DartyBox Adsl SignalNoise Ratio
echo graph_category other
echo up.label UpStream
echo down.label DownStream
echo multigraph dbox_adsl_pkt
echo graph_title DartyBox Adsl Packets
echo graph_category other
echo up.label UpStream
echo down.label DownStream
echo up_c.label UpStream "(Correctable)"
echo down_c.label DownStream "(Correctable)"
echo up_u.label UpStream "(Uncorrectable)"
echo down_u.label DownStream "(Uncorrectable)"
echo up.type DERIVE
echo down.type DERIVE
echo up_c.type DERIVE
echo down_c.type DERIVE
echo up_u.type DERIVE
echo down_u.type DERIVE
echo up.min 0
echo down.min 0
echo up_c.min 0
echo down_c.min 0
echo up_u.min 0
echo down_u.min 0
echo multigraph dbox_adsl_uptime
echo graph_title DartyBox Adsl Uptime
echo graph_category other
echo graph_vlabel days
echo uptime.label Uptime
exit 0
fi
TMPFILE=$(mktemp)
trap 'rm -f $TMPFILE' EXIT
wget -qO "$TMPFILE" http://$IP/adslstats.html
[ "$MUNIN_DEBUG" = 1 ] && cat "$TMPFILE"
get() {
PATTERN=$1
gawk "match(\$0, /var $PATTERN\s+=\s+\"([^\"]+)\"/, a) { print a[1] }" $TMPFILE
}
getDays() {
# Convert "20 jours 2 heures 2 mn" in a number of days
echo "$@" | gawk "match(\$0, /([0-9.]+) jours ([0-9.]+) heures ([0-9.]+) mn/, a) { print a[1] + a[2]/24 + a[3]/1440 }"
}
echo multigraph dbox_adsl_bw
echo up.value $(get UpStream)
echo down.value $(get DownStream)
echo multigraph dbox_adsl_att
echo up.value $(get AttNear)
echo down.value $(get AttFar)
echo multigraph dbox_adsl_snr
echo up.value $(get SNRNear)
echo down.value $(get SNRFar)
echo multigraph dbox_adsl_pkt
echo up.value $(get RSWORDSNear)
echo down.value $(get RSWORDSFar)
echo up_c.value $(get RSCORRERRORNear)
echo down_c.value $(get RSCORRERRORFar)
echo up_u.value $(get RSUNCORRERRORNear)
echo down_u.value $(get RSUNCORRERRORFar)
echo multigraph dbox_adsl_uptime
echo uptime.value $(getDays $(get AdslUpTime))
exit 0
:<<'EOF'
var ADSLLineStatus = "Etabli";
var ADSLMode = "G992_1_A (G.DMT) ";
var UpStream = "704";
var DownStream = "7616";
var AttNear = "33.5";
var AttFar = "16.5";
var SNRNear = "11.0";
var SNRFar = "15.0";
var HECCountNear= "4836";
var HECCountFar= "6";
var AdslVer1 = "0x81ef5379";
var AdslVer2 = "0x6397bde2";
var CmvVer1 = "0x6f249e71";
var CmvVer2 = "0xa703362e";
var ES15CntNear = "0";
var ES15CntFar = "0";
var CRCErrorsNear = "641";
var CRCErrorsFar = "7";
var ES1CNTNear = "8";
var ES1CNTFar = "0";
var ESTOTCNTFar = "5";
var ESTOTCNTNear = "452";
var RSWORDSNear = "1802451823";
var RSWORDSFar = "2881437753";
var RSCORRERRORNear = "57293";
var RSCORRERRORFar = "301";
var RSUNCORRERRORNear = "641";
var RSUNCORRERRORFar = "7";
var RSRatioNear = "0";
var RSRatioFar = "0";
var AdslUpTime = "20 jours 2 heures 2 mn";
EOF

View file

@ -1,197 +0,0 @@
#!/usr/bin/perl -w
#
# Copyright (C) 2008 Rien Broekstra <rien@rename-it.nl>
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; version 2 dated June,
# 1991.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
#
# Munin plugin to measure saturation of DHCP pools.
#
# Configuration variables:
#
# conffile - path to dhcpd's configuration file (default "/etc/dhcpd.conf")
# leasefile - path to dhcpd's leases file (default "/var/lib/dhcp/dhcpd.leases")
#
# Parameters:
#
# config (required)
#
# Version 1.0, 2-12-2008
use POSIX;
use Time::Local;
use strict;
my $CONFFILE = exists $ENV{'conffile'} ? $ENV{'conffile'} : "/etc/dhcpd.conf";
my $LEASEFILE = exists $ENV{'leasefile'} ? $ENV{'leasefile'} : "/var/lib/dhcp/dhcpd.leases";
if ( defined $ARGV[0] and $ARGV[0] eq "autoconf" ) {
}
elsif ( defined $ARGV[0] and $ARGV[0] eq "config" ) {
my (%pools, $start, $label);
# Print general information
print "graph_title DHCP pool usage (in %)\n";
print "graph_args --upper-limit 100 -l 0\n";
print "graph_vlabel %\n";
print "graph_category network\n";
# Determine the available IP pools
%pools = determine_pools();
# Print a label for each pool
foreach $start (keys %pools) {
$label = ip2string($start);
$label =~ s/\./\_/g;
print "$label.label Pool ".ip2string($start)."\n";
print "$label.warning 75\n";
print "$label.critical 100\n";
}
}
else {
my (@activeleases, %pools, $start, $end, $size, $free, $label, $lease);
# Determine all leased IP addresses
@activeleases = determine_active_leases();
# Determine the available IP pools
%pools = determine_pools();
# For each pool, count how many leases from that pool are currently active
foreach $start (keys %pools) {
$size = $pools{$start};
$end = $start+$size-1;
$free = $size;
foreach $lease (@activeleases) {
if ($lease >= $start && $lease <= $end) {
$free--;
}
}
$label = ip2string($start);
$label =~ s/\./\_/g;
print "$label.value ".sprintf("%.1f", 100*($size-$free)/$size)."\n";
}
}
# Parse dhcpd.conf for range statements.
#
# Returns a hash with start IP -> size
sub determine_pools {
my (%pools, @conffile, $line, $start, $end, $size);
open(CONFFILE, "<${CONFFILE}") || exit -1;
@conffile = <CONFFILE>;
close (CONFFILE);
foreach $line (@conffile) {
next if $line =~ /^\s*#/;
if ($line =~ /range[\s]+([\d]+\.[\d]+\.[\d]+\.[\d]+)[\s]+([\d]+\.[\d]+\.[\d]+\.[\d]+)/) {
$start = string2ip($1);
$end = string2ip($2);
defined($start) || next;
defined($end) || next;
# The range statement gives the lowest and highest IP addresses in a range.
$size = $end - $start + 1;
$pools{$start} = $size;
}
}
return %pools;
}
# Very simple parser for dhcpd.leases. This will break very easily if dhcpd decides to
# format the file differently. Ideally a simple recursive-descent parser should be used.
#
# Returns an array with currently leased IP's
sub determine_active_leases {
my (@leasefile, $startdate, $enddate, $lease, @activeleases, $mytz, $line, %saw);
open(LEASEFILE, "<${LEASEFILE}") || exit -1;
@leasefile = <LEASEFILE>;
close (LEASEFILE);
@activeleases = ();
# Portable way of converting a GMT date/time string to timestamp is setting TZ to UTC, and then calling mktime()
$mytz = $ENV{'TZ'};
$ENV{'TZ'} = 'UTC 0';
tzset();
foreach $line (@leasefile) {
if ($line =~ /lease ([\d]+\.[\d]+\.[\d]+\.[\d]+)/) {
$lease = string2ip($1);
defined($lease) || next;
undef $startdate;
undef $enddate;
}
elsif ($line =~ /starts \d ([\d]{4})\/([\d]{2})\/([\d]{2}) ([\d]{2}):([\d]{2}):([\d]{2})/) {
$startdate = mktime($6, $5, $4, $3, $2-1, $1-1900, 0, 0);
}
elsif ($line =~ /ends \d ([\d]{4})\/([\d]{2})\/([\d]{2}) ([\d]{2}):([\d]{2}):([\d]{2})/) {
$enddate = mktime($6, $5, $4, $3, $2-1, $1-1900, 0, 0);
if (defined($enddate) && defined($startdate) && defined($lease)) {
if ($startdate < time() && $enddate > time()) {
push (@activeleases, $lease);
}
}
}
}
# Set TZ back to its original setting
if (defined($mytz)) {
$ENV{'TZ'} = $mytz;
}
else {
delete $ENV{'TZ'};
}
tzset();
# Sort the array, strip doubles, and return
return grep(!$saw{$_}++, @activeleases);
}
#
# Helper routine to convert an IP address a.b.c.d into an integer
#
# Returns an integer representation of an IP address
sub string2ip {
my $string = shift;
defined($string) || return undef;
if ($string =~ /([\d]+)\.([\d]+)\.([\d]+)\.([\d]+)/) {
if ($1 < 0 || $1 > 255 || $2 < 0 || $2 > 255 || $3 < 0 || $3 > 255 || $4 < 0 || $4 > 255) {
return undef;
}
else {
return $1 << 24 | $2 << 16 | $3 << 8 | $4;
}
}
return undef;
}
#
# Returns a dotted quad notation of an
#
sub ip2string {
my $ip = shift;
defined ($ip) || return undef;
return sprintf ("%d.%d.%d.%d", ($ip >> 24) & 0xff, ($ip >> 16) & 0xff, ($ip >> 8) & 0xff, $ip & 0xff);
}

View file

@ -1,70 +0,0 @@
#!/bin/bash
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#
# Written by Daniele Albrizio <daniele@albrizio.it> march 2014
# Requires dhcpd-pools - ISC dhcpd pools usage analysis http://dhcpd-pools.sourceforge.net/
#
####
#%# family=manual
#%# capabilities=autoconf,multigraph
export WARN=85
export CRIT=98
DHCPD_POOLS_BIN=/usr/local/bin/dhcpd-pools
DHCPDCONF=/etc/dhcp3/dhcpd.conf
if [ "$1" = "autoconf" ]; then
echo yes
exit 0
fi
$DHCPD_POOLS_BIN -c $DHCPDCONF --minsize=15 --limit=01 -fc | grep -v "^$" | sort | sed 's/","/\t/g' | sed 's/"//g' |\
while read SCOPENAME IPSTART IPSTOP POOLMAX POOLCUR PERCENT TOUCH TC TCPERCENT BU BUPERCENT
do
IPSTARTUS=`echo $IPSTART | sed 's/\./_/g'`
let POOLWARN=${POOLMAX}*${WARN}/100
let POOLCRIT=${POOLMAX}*${CRIT}/100
let GRAPHTOP=${POOLMAX}*110/100
if [ "$1" = "config" ]; then
echo "multigraph ${SCOPENAME}_$IPSTARTUS"
echo "graph_title $SCOPENAME $IPSTART -> $IPSTOP (${POOLMAX})"
echo "graph_args --base 1000 -l 0 --upper-limit $GRAPHTOP"
echo "graph_vlabel Active Leases"
echo "graph_scale no"
echo "graph_category network"
echo "pool.label $SCOPENAME Active Leases"
echo "pool.info Pool utilization"
echo "pool.type GAUGE"
echo "pool.min 0"
echo "pool.max $POOLMAX"
echo "pool.colour 00ff00"
echo "pool.draw AREA"
echo "pool.warning $POOLWARN"
echo "pool.line $POOLWARN:ffc000:$WARN%"
echo "pool.critical $POOLCRIT"
echo "pool_fover.label Peer available leases"
echo "pool_fover.colour aaaaaa"
echo "pool_fover.draw LINESTACK1"
echo "pool_fover.type GAUGE"
echo "pool_fover.line $POOLCRIT:ff0000:$CRIT%"
echo "#"
else
echo "multigraph ${SCOPENAME}_$IPSTARTUS"
echo "pool.value $POOLCUR"
echo "pool_fover.value $BU"
fi
done

View file

@ -1,51 +0,0 @@
#!/bin/sh
#
# Description : Plugin to monitor a server/network availability.
# Author : Thomas VIAL
# Author URL : http://tvi.al
# Usage : ln -s /path/to/fping_ /etc/munin/plugins/fping_www.google.com
# Explanation : Will graph connection to www.google.com
# Requirements :
# * fping
#
target=`basename $0 | sed 's/^fping_//g'`
item=`echo $target | sed -e 's/\.//g'`
#
# Config
#
if [ "$1" = "config" ]; then
echo "graph_title ${target} availability"
echo "graph_args --base 1000 -r -l 0 -u 100"
echo "graph_vlabel Availability in %"
echo "graph_category network"
echo "graph_info Displays Network Availability"
# Failure
echo "failure.label Unreachable"
echo "failure.draw AREA"
echo "failure.colour ff0000"
# Success
echo "success.label Reachable"
echo "success.draw STACK"
echo "success.colour 00CC00CC"
exit 0
fi
#
# Let's go!
#
fping -q $target
status=$?
if [ $status -eq 0 ]; then
# Success
echo "success.value 100"
echo "failure.value 0"
else
# Failure
echo "success.value 0"
echo "failure.value 100"
fi

View file

@ -1,68 +0,0 @@
#!/bin/sh
#
# Patched version of ip_ plugin to support IPv6 and ip6tables.
# Most of plugin done by munin core developers. Modified for IPv6 support
# by Lasse Karstensen <lasse.karstensen@gmail.com> February 2009.
#
# Wildcard-plugin to monitor IP addresses through ip6tables. To monitor an
# IP, link ip6_<ipaddress> to this file with : replaced with _. E.g.
#
# ln -s /usr/share/node/node/plugins-auto/ip6_ /etc/munin/plugins/ip_2001_db8_1__100
#
# ...will monitor the IP 2001:db8:1::10.
#
# Additionally, you need these ip6tables rules as the first rules (they don't do anything, just make packet counts)
#
# ip6tables -A INPUT -d 2001:db8:1::10
# ip6tables -A OUTPUT -s 2001:db8:1::10
#
# Furthermore, this plugin needs to be run as root for ip6tables to work.
#
#
# Magic markers (optional - used by munin-config and some installation
# scripts):
#%# family=auto
#%# capabilities=autoconf suggest
IP=`basename $0 | sed 's/^ip6_//g' | tr '_' ':' `
if [ "$1" = "autoconf" ]; then
if [ -r /proc/net/dev ]; then
ip6tables -L INPUT -v -n -x >/dev/null 2>/dev/null
if [ $? -gt 0 ]; then
echo "no (could not run ip6tables as user `whoami`)"
exit 1
else
echo yes
exit 0
fi
else
echo "no (/proc/net/dev not found)"
exit 1
fi
fi
if [ "$1" = "suggest" ]; then
ip6tables -L INPUT -v -n -x 2>/dev/null | awk --posix '$8 ~ /^([0-9a-f]{1,4}(\:|\:\:)){1,7}([0-9a-f]{1,4})\/([0-9]{1,3})$/ { if (done[$8]!=1) {print $8; done[$8]=1;}}'|sed "s#/[0-9]\{1,3\}##"
exit 0
fi
if [ "$1" = "config" ]; then
echo "graph_order out in"
echo "graph_title $IP IPv6 traffic"
echo 'graph_args --base 1000'
echo 'graph_vlabel bits per ${graph_period}'
echo 'graph_category network'
echo 'out.label sent'
echo 'out.type DERIVE'
echo 'out.min 0'
echo 'out.cdef out,8,*'
echo 'in.label received'
echo 'in.type DERIVE'
echo 'in.min 0'
echo 'in.cdef in,8,*'
exit 0
fi;
ip6tables -L INPUT -v -n -x | grep -m1 $IP | awk "{ print \"in.value \" \$2 }"
ip6tables -L OUTPUT -v -n -x | grep -m1 $IP | awk "{ print \"out.value \" \$2 }"

View file

@ -1,22 +0,0 @@
#!/bin/sh
if [ "$1" = "config" ]; then
cat <<EOF
graph_title ip6tables bites ipv6
graph_vlabel bites numbers
graph_scale no
graph_category network
graph_args -l 0
graph_info ip6tables bites ipv6
EOF
ip6tables -vxL|grep -E 'ACC|REJ'|grep -v ^Chain|sed -e 's/dpt://g' -e 's/ .*://g'|awk '{print $NF"-"$4".label", $NF" "$4"\n",$NF"-"$4".min", 0}'|sed 's/^\s*//g'
exit 0
fi
if [ "$1" = "autoconf" ]; then
echo yes
exit 0
fi
ip6tables -vxL|grep -E 'ACC|REJ'|grep -v ^Chain|awk '{print $NF"-"$4".value", $2}'|sed 's/^dpt://'

View file

@ -1,194 +0,0 @@
#! /usr/bin/env perl
=head1 NAME
modem-nvg510 - Plugin to monitor Motorola/Arris NVG510 DSL modem stats (AT&T ADSL2+)
=head1 CONFIGURATION
[modem-nvg510]
env.url http://192.168.1.254/cgi-bin/dslstatistics.ha
=head1 MAGIC MARKERS
#%# family=auto
#%# capabilities=autoconf
=head1 AUTHOR
Samuel Smith <esaym (snail) cpan.org>
=cut
use strict;
use warnings;
use HTTP::Tiny;
use constant {
down_rate => 2,
up_rate => 3,
sn_down => 23,
sn_up => 24,
line_attn_down => 25,
line_attn_up => 26,
power_down => 27,
power_up => 28,
err_sec_down => 29,
err_sec_up => 30,
los_down => 31,
los_up => 32,
lof_down => 33,
lof_up => 34,
fec_down => 35,
fec_up => 36,
crc_down => 37,
crc_up => 38,
};
if(defined $ARGV[0] and $ARGV[0] eq 'autoconf'){
my $url = $ENV{url} || "http://192.168.1.254/cgi-bin/dslstatistics.ha";
my $html = HTTP::Tiny->new(timeout => 30 )->get($url);
if($html->{success} && $html->{content} =~ m{Broadband Status}){
print "yes\n";
}
else{
print "no\n";
}
exit 0;
}
if(defined $ARGV[0] and $ARGV[0] eq "config"){
print q|multigraph nvg510_speed
graph_args --base 1000
graph_category network
graph_info This graph show modem upload and download speeds in kilo bits per second
graph_title Modem Link Speed
graph_vlabel Kbits per ${graph_period}
down_rate.label downstream kbps
down_rate.info Link downstream speed (kbits/second)
down_rate.type GAUGE
up_rate.label upstream kbps
up_rate.info Link upload speed (kbits/second)
up_rate.type GAUGE
multigraph nvg510_line_quality
graph_args --base 1000
graph_category network
graph_info This graph shows modem line quality statistics like attenuation and noise ratios.
graph_title Modem Line Quality
graph_vlabel Line Statistics
sn_down.label sn_down
sn_down.info Downstream signal to noise margin, in decibels (dB)
sn_down.type GAUGE
sn_up.label sn_up
sn_up.info Upstream signal to noise margin, in decibels (dB)
sn_up.type GAUGE
line_attn_down.label line_attn_down
line_attn_down.info Downstream reduction in signal strength, in decibels (dB)
line_attn_down.type GAUGE
line_attn_up.label line_attn_up
line_attn_up.info Upstream reduction in signal strength, in decibels (dB)
line_attn_up.type GAUGE
power_down.label power_down
power_down.info Downstream power output to one milliwatt (dBm)
power_down.type GAUGE
power_up.label power_up
power_up.info Upstream power output to one milliwatt (dBm)
power_up.type GAUGE
multigraph nvg510_error_counts
graph_args --base 1000
graph_category network
graph_info This graph shows internal error counters of the modem.
graph_title Modem Errors
graph_vlabel Modem Errors per ${graph_period}
fec_down.label fec_down
fec_down.info Downstream Forwarded Error Correction: Number of times received errored packets were fixed without a retry.
fec_down.type DERIVE
fec_down.min 0
fec_up.label fec_up
fec_up.info Upstream Forwarded Error Correction: Number of times received errored packets were fixed without a retry.
fec_up.type DERIVE
fec_up.min 0
crc_down.label crc_down
crc_down.info Downstream number of times data packets have had to be resent due to errors
crc_down.type DERIVE
crc_down.min 0
crc_up.label crc_up
crc_up.info Upstream number of times data packets have had to be resent due to errors
crc_up.type DERIVE
crc_up.min 0
err_sec_down.label err_sec_down
err_sec_down.info The number of unconnected seconds after being down for seven consecutive seconds
err_sec_down.type DERIVE
err_sec_down.min 0
err_sec_up.label err_sec_up
err_sec_up.info The number of unconnected seconds after being down for seven consecutive seconds
err_sec_up.type DERIVE
err_sec_up.min 0
los_down.label los_down
los_down.info Loss of signal: Number of times for any reason, the signal is lost
los_down.type DERIVE
los_down.min 0
los_up.label los_up
los_up.info Loss of signal: Number of times for any reason, the signal is lost
los_up.type DERIVE
los_up.min 0
lof_down.label lof_down
lof_down.info Loss of frame: Number of times the signal is detected, but cannot sync
lof_down.type DERIVE
lof_down.min 0
lof_up.label lof_up
lof_up.info Loss of frame: Number of times the signal is detected, but cannot sync
lof_up.type DERIVE
lof_up.min 0
|;
exit 0;
}
########################## MAIN #############################
my $url = $ENV{url} || "http://192.168.1.254/cgi-bin/dslstatistics.ha";
my $html = HTTP::Tiny->new(timeout => 30 )->get($url);
die "Couldn't fetch $url" unless $html->{success};
my @stats = $html->{content} =~ m{<td class="col2">(.*?)</td>}sg;
chomp(@stats);
print qq|multigraph nvg510_speed
down_rate.value $stats[down_rate]
up_rate.value $stats[up_rate]
multigraph nvg510_line_quality
sn_down.value $stats[sn_down]
sn_up.value $stats[sn_up]
line_attn_down.value $stats[line_attn_down]
line_attn_up.value $stats[line_attn_up]
power_down.value $stats[power_down]
power_up.value $stats[power_up]
multigraph nvg510_error_counts
fec_down.value $stats[fec_down]
fec_up.value $stats[fec_up]
crc_down.value $stats[crc_down]
crc_up.value $stats[crc_up]
err_sec_down.value $stats[err_sec_down]
err_sec_up.value $stats[err_sec_up]
los_down.value $stats[los_down]
los_up.value $stats[los_up]
lof_down.value $stats[lof_down]
lof_up.value $stats[lof_up]
|;

View file

@ -1,170 +0,0 @@
#!/usr/bin/env python3
# This plugin graphs the following values of the Motorola SB6141 cable
# modem:
#
# * upstream and downstream power levels
# * downstream signal to noise ratio
# * downstream signal statistics (codeword counts)
#
# The values are retrieved from the cable modem's status web pages at
# 192.168.100.1. So, this plugin must be installed on a munin node
# which can access those pages.
#
# To install, place this plugin in the node's plugins directory,
# /etc/munin/plugins and restart munin-node.
#
# Developed and tested with firmware SB_KOMODO-1.0.6.16-SCM00-NOSH
# (build time Feb 16 2016 11:28:04), hardware version 7.0, boot
# version PSPU-Boot(25CLK) 1.0.12.18m3.
#
# Requires the multigraph and dirtyconfig capabilities available in
# munin 2.0 and newer.
#
# Copyright © 2016 Kenyon Ralph <kenyon@kenyonralph.com>
#
# This program is free software. It comes without any warranty, to the
# extent permitted by applicable law. You can redistribute it and/or
# modify it under the terms of the Do What The Fuck You Want To Public
# License, Version 2, as published by Sam Hocevar. See
# http://www.wtfpl.net/ for more details.
#
# The latest version of this plugin can be found in the munin contrib
# repository at https://github.com/munin-monitoring/contrib. Issues
# with this plugin may be reported there. Patches accepted through the
# normal github process of forking the repository and submitting a
# pull request with your commits.
import html.parser
import urllib.request
import sys
class MotorolaHTMLParser(html.parser.HTMLParser):
def __init__(self):
html.parser.HTMLParser.__init__(self)
self.signaldatapage = list()
self.downstream_channels = list()
self.downstream_SNRs = list()
self.downstream_powers = list()
self.upstream_channels = list()
self.upstream_powers = list()
self.unerrored_codewords = list()
self.correctable_codewords = list()
self.uncorrectable_codewords = list()
def handle_data(self, data):
data = data.strip()
if data != '': self.signaldatapage.append(data)
def process(self):
# first and last elements are just javascript
del self.signaldatapage[0]
del self.signaldatapage[-1]
di = iter(self.signaldatapage)
element = next(di)
while element != 'Channel ID': element = next(di)
while element != 'Frequency':
element = next(di)
if element != 'Frequency': self.downstream_channels.append(element)
while element != 'Signal to Noise Ratio': element = next(di)
while element != 'Downstream Modulation':
element = next(di)
if element != 'Downstream Modulation': self.downstream_SNRs.append(element.split()[0])
while element != 'The Downstream Power Level reading is a snapshot taken at the time this page was requested. Please Reload/Refresh this Page for a new reading': element = next(di)
while element != 'Upstream':
element = next(di)
if element != 'Upstream': self.downstream_powers.append(element.split()[0])
while element != 'Channel ID': element = next(di)
while element != 'Frequency':
element = next(di)
if element != 'Frequency': self.upstream_channels.append(element)
while element != 'Power Level': element = next(di)
while element != 'Upstream Modulation':
element = next(di)
if element != 'Upstream Modulation': self.upstream_powers.append(element.split()[0])
while element != 'Total Unerrored Codewords': element = next(di)
while element != 'Total Correctable Codewords':
element = next(di)
if element != 'Total Correctable Codewords': self.unerrored_codewords.append(element)
while element != 'Total Uncorrectable Codewords':
element = next(di)
if element != 'Total Uncorrectable Codewords': self.correctable_codewords.append(element)
while True:
try:
element = next(di)
self.uncorrectable_codewords.append(element)
except StopIteration:
break
def main():
if len(sys.argv) != 2 or sys.argv[1] != 'config':
print('Error: plugin designed for the dirtyconfig protocol, must be run with the config argument')
sys.exit(1)
parser = MotorolaHTMLParser()
for line in urllib.request.urlopen("http://192.168.100.1/cmSignalData.htm"):
parser.feed(line.decode())
parser.process()
print('multigraph motorola_sb6141_power')
print('graph_title Motorola SB6141 Cable Modem Power')
print('graph_vlabel Signal Strength (dBmV)')
print('graph_info This graph shows the downstream and upstream power reported by a Motorola SB6141 cable modem.')
print('graph_category network')
for c, p in zip(parser.downstream_channels, parser.downstream_powers):
print('ds_power_{0}.label Channel {0} Downstream Power'.format(c))
print('ds_power_{0}.type GAUGE'.format(c))
print('ds_power_{0}.value {1}'.format(c, p))
for c, p in zip(parser.upstream_channels, parser.upstream_powers):
print('us_power_{0}.label Channel {0} Upstream Power'.format(c))
print('us_power_{0}.type GAUGE'.format(c))
print('us_power_{0}.value {1}'.format(c, p))
print('multigraph motorola_sb6141_snr')
print('graph_title Motorola SB6141 Cable Modem SNR')
print('graph_vlabel Signal-to-Noise Ratio (dB)')
print('graph_info This graph shows the downstream signal-to-noise ratio reported by a Motorola SB6141 cable modem.')
print('graph_category network')
for c, snr in zip(parser.downstream_channels, parser.downstream_SNRs):
print('snr_chan_{0}.label Channel {0} SNR'.format(c))
print('snr_chan_{0}.type GAUGE'.format(c))
print('snr_chan_{0}.value {1}'.format(c, snr))
print('multigraph motorola_sb6141_codewords')
print('graph_title Motorola SB6141 Cable Modem Codewords')
print('graph_vlabel Codewords/${graph_period}')
print('graph_info This graph shows the downstream codeword rates reported by a Motorola SB6141 cable modem.')
print('graph_category network')
for c, unerr in zip(parser.downstream_channels, parser.unerrored_codewords):
print('unerr_chan_{0}.label Channel {0} Unerrored Codewords'.format(c))
print('unerr_chan_{0}.type DERIVE'.format(c))
print('unerr_chan_{0}.min 0'.format(c))
print('unerr_chan_{0}.value {1}'.format(c, unerr))
for c, corr in zip(parser.downstream_channels, parser.correctable_codewords):
print('corr_chan_{0}.label Channel {0} Correctable Codewords'.format(c))
print('corr_chan_{0}.type DERIVE'.format(c))
print('corr_chan_{0}.min 0'.format(c))
print('corr_chan_{0}.value {1}'.format(c, corr))
for c, uncorr in zip(parser.downstream_channels, parser.uncorrectable_codewords):
print('uncorr_chan_{0}.label Channel {0} Uncorrectable Codewords'.format(c))
print('uncorr_chan_{0}.type DERIVE'.format(c))
print('uncorr_chan_{0}.min 0'.format(c))
print('uncorr_chan_{0}.value {1}'.format(c, uncorr))
if __name__ == "__main__":
main()

View file

@ -1,167 +0,0 @@
#!/usr/bin/perl
=head1 NAME
multi_tcp_ping - Graphs together the TCP ping results for several hosts
=head1 SYNOPSIS
This plugin is meant to be called from Munin. You should set the
'hosts' environment variable from Munin's configuration (i.e.
/etc/munin/munin.conf) to specify which hosts and ports to query.
=head1 DESCRIPTION
This plugin expects to receive the following environment variables:
=over 4
=item hosts (REQUIRED!)
Comma-separated list of hosts to query. You can specify the TCP port
to connect to on each of the hosts by listing them as host:port - The
port defaults to 80. The following is a valid hosts declaration:
hosts='192.168.0.15, 192.168.0.18:22'
It will query host 192.168.0.15 on the default port (80), as well as
host 192.168.0.18 on port 22.
=back
If the connection was opened successfully, it gives as the return
value the time it took to establish the connection. If the requested
host is not reachable, a hard-wired '-0.01' will be returned. Why
-0.01? Because giving a negative value is the best way to easily get
-visually- that something failed. Connection establishment times are
usually in the 5-500ms range. 100ms will be not too little (and thus
invisible), not too much (and thus killing the details in our graphs).
=head1 DEPENDS ON
L<Net::Ping>
=head1 SEE ALSO
L<munin>, L<munin-node>
=head1 AUTHOR
Gunnar Wolf <gwolf@gwolf.org>
=head1 COPYRIGHT
Copyright 2008 Gunnar Wolf, Instituto de Investigaciones
Economicas, UNAM. This plugin is Free Software; you can
redistribute it and/or modify it under the terms of the GNU General
Public License as published by the Free Software Foundation; version 2
dated June, 1991, or any later version (at your choice).
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
USA.
=cut
use strict;
use warnings;
# This evil "eval" is to make Travis CI able to test the plugin syntax
# without having a perl built with threads.
#
# Also: The use of interpreter-based threads in perl is officially
# discouraged.
eval 'use threads; 1;' or die 'Could not use threads';
use Net::Ping;
my (%defaults, @hosts, $cmd_arg);
%defaults = (port => 80, timeout => 2, unreachable => -0.01);
@hosts = get_hosts($ENV{hosts});
die "Hosts not set - cannot continue\n" unless @hosts;
$cmd_arg = $ARGV[0] || '';
config() if($cmd_arg eq "config");
autoconf() if ($cmd_arg eq 'autoconf');
for my $host (@hosts) {
threads->new(\&ping_host, $host)
}
map {$_->join} threads->list;
exit 0;
sub ping_host {
my ($host, $addr, $p, $ret, $time, $ip);
$host = shift;
$addr = host_label_for($host);
$p=Net::Ping->new("tcp", $defaults{timeout});
$p->hires();
$p->{port_num} = $host->[1] || $defaults{port};
($ret, $time, $ip) = $p->ping($host->[0]);
$time = $defaults{unreachable} if !$ret;
print "${addr}.value $time\n";
}
sub get_hosts {
# Hosts are defined in the 'hosts' environment variable. It's a list of
# hosts (and optionally ports) - We parse the list and arrange it neatly
# to be easily consumed.
my ($hostsdef, @hosts);
$hostsdef = shift;
return unless $hostsdef;
for my $host (split(/,/, $hostsdef)) {
$host =~ s/\s//g;
$host =~ /^(?:([^:]+))
(?::(\d+))?$/x;
push @hosts, [$1, $2 || $defaults{port}];
}
return @hosts;
}
sub config {
my @res = ("graph_title TCP connection times",
"graph_args --base 1000 -l 0",
"graph_vlabel seconds",
"graph_category network",
"graph_info Shows the time to establish a TCP connection");
for my $host (@hosts) {
my $addr = host_label_for($host);
push @res, "$addr.label $addr";
push @res, "$addr.draw LINE2";
push @res, "$addr.info Time to establish TCP connection to " .
"$host->[0]:$host->[1]";
}
print map {"$_\n"} @res;
exit 0;
}
sub autoconf {
print "yes\n";
exit 0;
}
sub host_label_for {
my ($ip, $port) = @{$_[0]};
# Periods and colonsare not allowed in variable names
my $addr = "src_${ip}_${port}";
$addr =~ s/\./_/g;
return $addr;
}

View file

@ -1,106 +0,0 @@
#!/usr/bin/perl -w
#
# Copyright (C) 2008 Thomas Gutzler (thomas.gutzler@gmail.com)
# original shell script by Jimmy Olsen
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; version 2 dated June,
# 1991.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
#
# Plugin to monitor ping times
#
# Parameters:
#
# ping_args - Arguments to ping (default "-c 2 -w 1")
# ping_args2 - Arguments after the host name (required for Solaris)
# ping - Ping program to use
# hosts - List of comma-separated hosts to ping (IP address or FQDN)
# names - Friendly display name of each host given in the "hosts" parameter (comma-separated list).
# If not set, "hosts" elements will be used
#
# Arguments for Solaris:
# ping_args -s
# ping_args2 56 2
#
# Tips for very fast ping replies
# (thanks to Alex Davies and Nicolai Langfeldt):
# Apparently, old versions of munin can't handle scientific notation of values
# so, if you're getting replies like this from your node:
# site1.value 5.2e-05
# and your graph looks like a flat line, remove the -o argument from graph_args
#
# Configuration example
# [multiping]
# env.hosts www.google.com,www.yahoo.com
# env.names Google,Yahoo
# env.ping_args -A -c 5 -w 2
#
#%# family=auto
#%# capabilities=autoconf
use strict;
my @hosts = exists $ENV{hosts} ? split(/,/, $ENV{hosts}) : 'www.google.com.au';
my @names = exists $ENV{names} ? split(/,/, $ENV{names}) : @hosts;
my $ping_cmd = exists $ENV{ping} ? $ENV{ping} : 'ping';
my $ping_args = exists $ENV{ping_args} ? $ENV{ping_args} : '-c 2 -w 1';
my $ping_args2 = exists $ENV{ping_args2} ? $ENV{ping_args2} : '';
if ($#hosts != $#names) {
print "unequal amount of hosts and names\n";
exit 1;
}
if ((exists $ARGV[0]) && ($ARGV[0] eq "autoconf")) {
my @ping = `$ping_cmd $ping_args $hosts[0] $ping_args2`;
chomp @ping;
my $ping = join(" ", @ping);
if ($ping =~ m@min/avg/max@) {
print "yes\n";
exit 0;
} else {
print "no\n";
exit 1;
}
}
if ((exists $ARGV[0]) && ($ARGV[0] eq "config")) {
print "graph_title Ping times\n";
print "graph_args --base 1000 -o\n";
print "graph_vlabel seconds\n";
print "graph_category network\n";
print "graph_info This graph shows ping RTT statistics.\n";
for (my $site=1; $site<=$#hosts+1; $site++) {
my $item = lc($hosts[$site-1]);
$item =~ s/\.//g;
print "$item.label $names[$site-1]\n";
print "$item.info Ping RTT statistics for $hosts[$site-1].\n";
print "$item.draw LINE2\n";
print "${item}_packetloss.label $names[$site-1] packet loss\n";
print "${item}_packetloss.graph no\n";
}
exit 0;
}
for (my $site=1; $site<=$#hosts+1; $site++) {
my $item = lc($hosts[$site-1]);
$item =~ s/\.//g;
my $host = $hosts[$site-1];
my @ping = `$ping_cmd $ping_args $host $ping_args2`;
chomp @ping;
my $ping = join(" ", @ping);
print $item.".value ".($1 / 1000)."\n" if ($ping =~ m@min/avg/max.*\s\d+(?:\.\d+)?/(\d+(?:\.\d+)?)/\d+(?:\.\d+)?@);
print $item."_packetloss.value $1\n" if ($ping =~ /(\d+)% packet loss/);
}

View file

@ -1,86 +0,0 @@
#!/bin/sh
#
# Copyright (C) 2010 Michele Petrazzo <michele.petrazzo@gmail.com>
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; version 2 dated June,
# 1991.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
# Python (2.5+) version of the plugin to monitor ping times.
# Evolution from the standard shipped with munin by adding a ceil.
#
# Thanks to "Jimmy Olsen" for the base.
#
# Parameters:
#
# ping_args - Arguments to ping (default "-c 2")
# ping_args2 - Arguments after the host name (required for Solaris)
# ping - Ping program to use
# host - Host to ping
#
# Arguments for Solaris:
# ping_args -s
# ping_args2 56 2
#
file_host=`basename $0 | sed 's/^ping_ceil_//g'`
host=${host:-${file_host:-www.google.com}}
max_ping="250" # Leave empty if not need or an integer (in ms)
test -z "$ping" && ping="ping"
test -z "$ping_args" && ping_args="-c 2"
cmd="$ping $ping_args $ping_args2"
if [ "$1" = "config" ]; then
echo "graph_title Ping times to $host"
echo 'graph_args --base 1000 -l 0'
echo 'graph_vlabel seconds'
echo 'graph_category network'
echo 'graph_info This graph shows ping RTT statistics.'
echo "ping.label $host"
echo "ping.info Ping RTT statistics for $host."
echo 'ping.draw LINE2'
echo 'packetloss.label packet loss'
echo 'packetloss.graph no'
exit 0
fi
(
cat << EOF
import os
from subprocess import Popen, PIPE
bash_cmd = "$cmd"
command = bash_cmd.split() + ["$host"]
max_ping = float("$max_ping") if "$max_ping" else 0
try:
c = Popen(command, stdout=PIPE, stderr=PIPE)
except OSError:
print "command error:", command
raise
out, err = c.communicate()
for line in out.split("\n"):
if "packet loss" in line:
print "packetloss.value", line.split(",")[2].split()[0].replace("%", "")
elif "rtt min/avg/max/mdev" in line:
v = float(line.split("=")[1].split("/")[1])
v = min(v, max_ping) if max_ping else v
print "ping.value", "%.6f" % (v / 1000)
EOF
) | python

View file

@ -1,201 +0,0 @@
#!/usr/bin/perl -w
=cut
=head1 NAME
ping - Plugin to monitor ping times
=head1 CONFIGURATION
ping_args - Arguments to ping (default "-c 2 -w 1")
ping_args2 - Arguments after the host name (required for Solaris)
ping - Ping program to use
ping6 - Ping program to use with IPv6
hosts - List of comma-separated hosts to ping (IPv4/6 address or FQDN)
You can prepend host name with:
'A:' - to resolve all IPv4 addresses
and create an entry per address (requires 'host' program)
'AAAA:' - the same for IPv6 (requires 'host' program)
'6:' - do not try to resolve, but use ping6 for this host
names - Friendly display name of each host given in the "hosts" parameter (comma-separated list).
If not set, "hosts" elements will be used
fork - If set to non-zero, fork each ping into parallel process to ping asynchronously
Configuration example
[ping*]
env.hosts mail.example.org,6:www.example.org,AAAA:search.example.org
env.names Mail,Web,Search
env.fork yes
Configuration example for Solaris
[ping*]
env.host www.example.org mail.example.org
env.ping_args -s
env.ping_args2 56 2
You can also append '_packetloss' to the plugin filename for packet loss statistics.
=head1 AUTHOR
Original Perl script Copyright (C) 2008 Thomas Gutzler (thomas.gutzler@gmail.com)
Original Shell script Copyright (C) 2004 Jimmy Olsen
=head1 LICENSE
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; version 2 dated June,
1991.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
=head1 MAGIC MARKERS
#%# family=manual
=cut
use strict;
use Munin::Plugin;
my $ping = exists $ENV{ping} ? $ENV{ping} : "ping";
my $ping6 = exists $ENV{ping6} ? $ENV{ping6} : "ping6";
# Since ping sends a packet every second (-i 1) by default,
# we may need 2 total seconds (-w 2) for <1000msec replies
my $ping_args = exists $ENV{ping_args} ? $ENV{ping_args} : "-c 2 -w 2";
my $ping_args2 = exists $ENV{ping_args2} ? $ENV{ping_args2} : "";
my $fork = exists $ENV{fork} ? $ENV{fork} : 0;
my $packetloss_mode = ($0 =~ /_packetloss$/);
my @host_options = exists $ENV{hosts} ? split(/,/, $ENV{hosts}) : "A:www.google.com";
# bare addresses
my @host_addrs = @host_options;
# ping program to use
my @host_ping = ($ping) x @host_options;
# resolve record type, if specified
my @host_resolv = (0) x @host_options;
my $config_mode = ($ARGV[0] and $ARGV[0] eq 'config');
if ($config_mode) {
print "graph_title " . ($packetloss_mode ? "Ping packet loss" : "Ping times") . "\n";
print "graph_args --base 1000 -l 0\n";
print "graph_vlabel " . ($packetloss_mode ? "%" : "seconds") . "\n";
print "graph_category network\n";
print "graph_info This graph shows ping " . ($packetloss_mode ? "packet loss" : "RTT") . " statistics.\n";
}
for (my $host_option = 0; $host_option < @host_options; ++$host_option) {
my $h_addr = $host_options[$host_option];
my @config = split(/:/, $h_addr, 2);
if ($#config) {
my $h_ping = $ping;
my $h_resolv = 0;
if ($config[0] eq "6") {
# user wants this host to be pinged via IPv6
$h_ping = $ping6;
$h_addr = $config[1];
} elsif ($config[0] eq "A") {
# user wants this host to be resolved via IPv4
$h_resolv = "A";
$h_addr = $config[1];
} elsif ($config[0] eq "AAAA") {
# user wants this host to be resolved as IPv6
$h_resolv = "AAAA";
$h_addr = $config[1];
$h_ping = $ping6;
} elsif ($config[0] =~ /^[[:xdigit:]]+$/) {
# this is IPv6 addr
$h_ping = $ping6;
} else {
# let 'host' decide what resolve type do we need
$h_resolv = $config[0];
$h_addr = $config[1];
}
$host_addrs[$host_option] = $h_addr;
$host_resolv[$host_option] = $h_resolv;
$host_ping[$host_option] = $h_ping;
}
}
# display names
my @host_names = exists $ENV{names} ? split(/,/, $ENV{names}) : @host_addrs;
if (@host_names != @host_addrs) {
print "Warning: host names specified does not match addresses\n";
}
# forked children
my @children = ();
for (my $host_i = 0; $host_i < @host_addrs; ++$host_i) {
my @h_addrs = ($host_addrs[$host_i]);
my $h_ping = $host_ping[$host_i];
my $h_resolv = $host_resolv[$host_i];
my $h_name = ($host_names[$host_i] or $h_addrs[0]);
if ($h_resolv) {
# we have to resolve the host to (probably multiple) addresses
my $h_base_addr = pop @h_addrs;
my @host = `host -t $h_resolv $h_base_addr`;
chomp @host;
for (my $h_host_i = 0; $h_host_i < @host; ++$h_host_i) {
my $h_host = $host[$h_host_i];
my ($h_addr) = $h_host =~ /address (.*)$/;
if ($h_addr) {
push @h_addrs, $h_addr;
}
}
}
for (my $h_addr_i = 0; $h_addr_i < @h_addrs; ++$h_addr_i) {
my $h_addr = $h_addrs[$h_addr_i];
my $h_cur_name = $h_resolv ? $h_name . " ($h_addr)" : $h_name;
my $h_norm_name = clean_fieldname($h_cur_name);
if ($config_mode) {
print "$h_norm_name.min 0\n$h_norm_name.label $h_cur_name\n$h_norm_name.draw LINE2\n";
my ( $warning, $critical ) =
get_thresholds($h_norm_name);
printf "%s.warning %s\n", $h_norm_name, $warning
if $warning;
printf "%s.critical %s\n", $h_norm_name, $critical
if $critical;
} else {
my $pid = $fork ? fork() : -1;
if ($pid <= 0) {
# either we can't fork, or don't want to, or we are child
my @ping = `$h_ping $ping_args $h_addr $ping_args2`;
chomp @ping;
my $ping = join(" ", @ping);
my $ping_time = "U";
my $packet_loss = "U";
$ping_time = ($1 / 1000) if ($ping =~ m@min/avg/max.*\s\d+(?:\.\d+)?/(\d+(?:\.\d+)?)/\d+(?:\.\d+)?@);
$packet_loss = $1 if ($ping =~ /(\d+)% packet loss/);
print "$h_norm_name.value ". ($packetloss_mode ? $packet_loss : $ping_time) . "\n";
if ($pid == 0) {
# this is a child process, don't forget to exit
exit(0);
}
} else {
# in parent
push @children, $pid;
}
}
}
}
for (my $child_i = 0; $child_i < @children; ++$child_i) {
waitpid($children[$child_i], 0);
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

View file

@ -1,26 +0,0 @@
#!/bin/sh
H=`echo $0 | awk -F_ '{print $2}'`
if [ "$1" = "config" ] ; then
echo "graph_title Ping RTT $H"
echo "graph_category network"
echo "graph_info this graph shows the average RTT of five pings to $H"
echo "graph_vlabel ping_rtt"
echo "ping_rtt.label ms"
echo "ping_rtt.warning 12"
echo "ping_rtt.critical 15"
echo "ping_loss.warning 40"
echo "ping_loss.critical 60"
exit
fi
/sbin/ping -W 1 -c 5 $H > /tmp/munin-node-ping-$H
RTTAVG=`sed -n '2,6p' /tmp/munin-node-ping-$H | sed -e 's/.*time=//g' -e 's/ ms//g' | awk '{ ORS= "" ; print $1 " " }' | sed -e 's#$# + + + + 3 k 4 / p#g' | dc`
PKTLOSS=`sed -n 9p /tmp/munin-node-ping-$H | sed -e 's/.*received, //g' -e 's/% packet loss//g'`
echo "ping_rtt.value $RTTAVG"
echo "ping_loss.value $PKTLOSS"

View file

@ -1,101 +0,0 @@
#!/bin/bash
# This script is intended for use with Munin to monitor
# ping response time from hosts and through interfaces specified.
# v. 1.1, 12/16/2007
# (c) Alex Yanchenko (yanchenko{at}gmail.com), 2007
# Distributed under GPL v.3 (http://www.gnu.org/licenses/gpl-3.0.txt)
#
# The plugin can utilize automatic configuration,
# here are the basic steps (require root privileges):
# 1. Copy it as /usr/share/munin/plugins/pinger
# 2. Make executable: "chmod 755 /usr/share/munin/plugins/pinger"
# 3. Customize hosts, interfaces and ping count below
# 4. As pinging takes much time, add a
# --
# [pinger]
# timeout 60
# --
# record to /etc/munin/munin-node.conf to avoid timeouts.
# 5. Run "munin-node-configure --shell", you should see smth like
# "ln -s /usr/share/munin/plugins/pinger /etc/munin/plugins/pinger"
# 6. Run the proposed command to create a link.
# 7. To verify, run "munin-node-configure", you should notice the "pinger" record
#
# Plugin | Used | Suggestions
# ------ | ---- | -----------
# pinger | yes |
#
# 8. Restart munin: "/etc/init.d/munin-node restart"
# 9. Hold on for 5 minutes at most and watch the graphs appear.
#
#%# family=contrib
#%# capabilities=autoconf
#----- PROPERTIES START -----#
# An array of interfaces to ping through, space-separated.
# In case vnstat is installed, interface names will be fetced
# from it, 'nicknames'included.
INTERFACE=(eth2 eth3)
# An array of hosts to ping, space-separated.
HOST=(dc.volia.com hosting.rbc.ru slicehost.com)
# Ping count, higher values lead to more precise
# results yet take more time
PING=3
#----- PROPERTIES END -----#
# Try to get interface name from vnstat, make sure the name is assigned
function IF_NAME() {
ARG=$1
if [[ $(which vnstat &>/dev/null; echo $?) == 0 ]]
then
IF_NAME="$(vnstat | grep "$ARG" | cut -d" " -f2,3 | cut -d":" -f1)"
else
IF_NAME="$ARG"
fi
echo $IF_NAME
}
# Ping given host through a given interface
function PINGER() {
ping $2 -c${PING} -I$1 | grep "rtt min/avg/max/mdev" | cut -d" " -f4 | cut -d"/" -f2 | cut -d"." -f1
}
case $1 in
autoconf)
which ping
if [[ "$?" = "0" ]]; then
echo yes
exit 0
else
echo "no (ping not present)"
exit 1
fi
;;
config)
cat << EOM
graph_title Pinger
graph_category network
graph_info A nice thingy to ping remote hosts.
graph_vlabel msec
graph_args --base 1000 --lower-limit 0
EOM
for (( i=0; i<"${#HOST[*]}"; i++ ))
do
for (( j=0; j<"${#INTERFACE[*]}"; j++ ))
do
echo "${j}_${i}.label $(IF_NAME ${INTERFACE[$j]}) - ${HOST[$i]}"
done
done
;;
*)
for (( i=0; i<"${#HOST[*]}"; i++ ))
do
for (( j=0; j<"${#INTERFACE[*]}"; j++ ))
do
echo "${j}_${i}.value $(PINGER ${INTERFACE[$j]} ${HOST[$i]})"
done
done
;;
esac

View file

@ -1,45 +0,0 @@
#!/bin/sh
# tcp_retries revision 2 (Feb 2012)
#
# TCP retransmission rate. Useful for network debugging.
#
# Required privileges: none
#
# OS: Linux with procfs
#
# Author: Artem Sheremet <dot.doom@gmail.com>
#
#%# family=auto
#%# capabilities=autoconf
TCPSTAT=/proc/net/tcp
case $1 in
autoconf)
[ -r $TCPSTAT -o -r ${TCPSTAT}6 ] && echo "yes" || echo "no"
;;
config)
cat <<CONFIG
graph_title TCP retransmissions
graph_vlabel Rate, retrs/sockets
graph_category network
graph_info TCP sockets retransmission counters from $TCPSTAT
rate.label Retransmission rate
rate.draw LINE2
rate.min 0
CONFIG
;;
esac
cat /proc/net/tcp* | awk '
{
TOTAL += $7;
COUNT++;
}
END {
printf "rate.value %.3f\n", TOTAL/COUNT
}
'

View file

@ -1,54 +0,0 @@
#!/bin/sh
#
# Plugin to monitor TCP states.
#
# Parameters:
#
# config (required)
# autoconf (optional - only used by munin-config)
#
# (C) Marki - count number of connections in each state
# - no LISTEN as we are running netstat without the "-a" option
#
#
# Magic markers (optional - used by munin-config and some installation
# scripts):
#%# family=auto
#%# capabilities=autoconf
if [ "$1" = "autoconf" ]; then
if ( netstat -nt 2>/dev/null >/dev/null ); then
echo yes
exit 0
else
if [ $? -eq 127 ]
then
echo "no (netstat program not found)"
exit 1
else
echo no
exit 1
fi
fi
fi
if [ "$1" = "config" ]; then
echo 'graph_title TCP Connection States'
echo 'graph_args -l 0 --base 1000'
echo 'graph_vlabel connections'
echo 'graph_category network'
echo 'graph_period second'
echo 'graph_info This graph shows the TCP connections states of all the network interfaces combined.'
for i in ESTABLISHED SYN_SENT SYN_RECV FIN_WAIT1 FIN_WAIT2 TIME_WAIT CLOSE CLOSE_WAIT LAST_ACK CLOSING; do
echo "$i.label $i"
echo "$i.type GAUGE"
echo "$i.max 32999"
echo "$i.min 0"
done
exit 0
fi
netstat -nt | awk '/^tcp/ { states[$6]++ } END { for (idx in states) print idx ".value " states[idx] }'

File diff suppressed because it is too large Load diff

View file

@ -1,65 +0,0 @@
#!/usr/bin/perl -w
if ( $ARGV[0] ) {
if ( $ARGV[0] eq 'autoconf' ) {
if ( -r '/bin/netstat') {
print "yes\n";
exit 0;
}
print "no\n";
exit 0;
} elsif ( $ARGV[0] eq 'config' ) {
print <<EOM;
graph_title UDP Statistics
graph_args --base 1000 -l 0
graph_vlabel Packets/\${graph_period}
graph_category network
sent.label Sent
sent.draw LINE1
sent.type DERIVE
sent.min 0
received.label Received
received.draw AREA
received.type DERIVE
received.min 0
unknown_ports.label In Unknown Port
unknown_ports.draw LINE1
unknown_ports.type DERIVE
unknown_ports.min 0
receive_buffer_errors.label Receive Buffer Errors
receive_buffer_errors.draw LINE1
receive_buffer_errors.type DERIVE
receive_buffer_errors.min 0
send_buffer_errors.label Send Buffer Errors
send_buffer_errors.draw LINE1
send_buffer_errors.type DERIVE
send_buffer_errors.min 0
in_csum_errors.label In CSUM Errors
in_csum_errors.draw LINE1
in_csum_errors.type DERIVE
in_csum_errors.min 0
ignored_multis.label In Ignored Multis
ignored_multis.draw LINE1
ignored_multis.type DERIVE
ignored_multis.min 0
receive_errors.label Receive Errors
receive_errors.draw LINE1
receive_errors.type DERIVE
receive_errors.min 0
EOM
exit 0;
}
}
@netstat = qx{/bin/netstat -us | grep -A8 '^Udp:' | awk '/packets sent/ \{ print "sent.value " \$1 \}
/packets received/ \{ print "received.value " \$1 \}
/packets to unknown port received/ \{ print "unknown_ports.value " \$1 \}
/receive buffer errors/ \{ print "receive_buffer_errors.value " \$1 \}
/send buffer errors/ \{ print "send_buffer_errors.value " \$1 \}
/InCsumErrors/ \{ print "in_csum_errors.value " \$2 \}
/IgnoredMulti/ \{ print "ignored_multis.value " \$2 \}
/packet receive errors/ \{ print "receive_errors.value " \$1 \}'};
print @netstat;

View file

@ -1,62 +0,0 @@
#!/bin/bash
#
# Show noise and signal levels of wifi enabled devices.
# Author: Nicolai Langfeldt, janl@linprolno
# Modifications: Sebastián Cruz, crux@lugmen.org.ar
# License: GPL v. 2
#
#%# family=auto
#%# capabilitoes=autoconf
PNWL=/proc/net/wireless
do_fetch () {
awk -F'[ :]*' '/:/ {
gsub(/\. /," ",$0); # Remove periods with no decimals after
print $2"_noise.value "$6;
print $2"_signal.value "$5;
}' $PNWL
}
do_config () {
echo "graph_title WiFi signal and noise"
echo "graph_args --base 1000 -u 0"
echo "graph_vlabel dB"
echo "graph_category network"
echo "graph_info This graph shows the noise and singal levels of your WiFi devices"
awk -F'[ :]*' '/:/ {
print $2"_noise.label Noise "$2;
print $2"_signal.label Signal "$2;
}' $PNWL
}
do_autoconf () {
if [ ! -f $PNWL ] ; then
echo "no (no $PNWL)"
exit 1
fi
if [ ! -r $PNWL ] ; then
echo "no (could not read $PNWL)"
exit 1
fi
if grep -qs : $PNWL ; then
echo yes
exit 0
fi
echo "no (no devices in $PNWL)"
exit 1
}
case $1 in
config|autoconf)
eval do_$1
exit 0;;
'')
do_fetch
exit 0;;
esac

View file

@ -1,108 +0,0 @@
#!/bin/sh
#
# Show current signal strength and noise for all connected peers of wifi devices.
# This plugin is suitable for wifi interfaces with a stable selection of peers
# (e.g. infrastructure).
# Author: Lars Kruse, devel@sumpfralle.de
# License: GPL v3 or later
#
# Requirements:
# * "iwinfo" tool (alternatively: fall back to "iw" - with incomplete data)
# * root privileges (for "iw" and "iwinfo")
#
# Magic markers
#%# capabilities=autoconf suggest
#%# family=auto
set -eu
# prefer "iwinfo" for information retrieval, if it is available
if which iwinfo >/dev/null; then
# "iwinfo" has a stable output format but is only available on openwrt
get_wifi_interfaces() { iwinfo | grep "^[a-zA-Z]" | awk '{print $1}'; }
# return MAC of peer and the signal strength
get_wifi_peers() { iwinfo "$1" assoclist | grep "^[0-9a-fA-F]" | awk '{print $1,$2}'; }
# the noise should be the same for all peers
get_wifi_noise() { iwinfo "$1" info | sed -n 's/^.* Noise: \([0-9-]\+\).*/\1/p'; }
else
# "iw" is available everywhere - but its output format is not recommended for non-humans
get_wifi_interfaces() { iw dev | awk '{ if ($1 == "Interface") print $2; }'; }
get_wifi_peers() { iw dev wlan0 station dump \
| awk '{ if ($1 == "Station") mac=$2; if (($1 == "signal") && ($2 == "avg:")) print mac,$3}'; }
# TODO: there seems to be no way to retrieve the noise level via "iw"
get_wifi_noise() { echo; }
fi
clean_fieldname() {
echo "$1" | sed 's/^\([^A-Za-z_]\)/_\1/; s/[^A-Za-z0-9_]/_/g'
}
get_ip_for_mac() {
local ip
ip=$(arp -n | grep -iw "$1$" | awk '{print $1}' | sort | head -1)
[ -n "$ip" ] && echo "$ip" && return 0
# no IP found - return MAC instead
echo "$1"
}
get_wifi_device_from_suffix() {
local suffix
local real_dev
# pick the part after the basename of the real file
suffix=$(basename "$0" | sed "s/^$(basename "$(readlink "$0")")//")
for real_dev in $(get_wifi_interfaces); do
[ "$suffix" != "$(clean_fieldname "$real_dev")" ] || echo "$real_dev"
done | head -1
}
ACTION="${1:-}"
case "$ACTION" in
config)
wifi=$(get_wifi_device_from_suffix)
echo "graph_title Wireless signal quality - $wifi"
echo "graph_args --upper-limit 0"
echo "graph_vlabel Signal and noise [dBm]"
echo "graph_category network"
echo "graph_info This graph shows the signal and noise for all wifi peers"
echo "noise.label Noise floor"
echo "noise.draw LINE"
# sub graphs for all peers
get_wifi_peers "$wifi" | while read mac signal; do
fieldname=$(clean_fieldname "peer_${mac}")
peer=$(get_ip_for_mac "$mac")
echo "signal_${fieldname}.label $peer"
echo "signal_${fieldname}.draw LINE"
done
;;
autoconf)
[ -z "$(get_wifi_interfaces)" ] && echo "no (no wifi interfaces found)" && exit 1
echo "yes"
;;
suggest)
get_wifi_interfaces | while read ifname; do
clean_fieldname "$ifname"
done
;;
"")
wifi=$(get_wifi_device_from_suffix)
peer_data=$(get_wifi_peers "$wifi")
echo "$peer_data" | while read mac signal; do
# ignore empty datasets
[ -z "$signal" ] && continue
fieldname=$(clean_fieldname "peer_${mac}")
echo "signal_${fieldname}.value $signal"
done
echo "noise.value $(get_wifi_noise "$wifi")"
;;
*)
echo >&2 "Invalid action (valid: config)"
echo >&2
;;
esac