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:
parent
e10e386b02
commit
d216113740
24 changed files with 5 additions and 5 deletions
|
@ -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)
|
|
@ -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
|
|
@ -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
|
|
@ -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);
|
||||
}
|
|
@ -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
|
|
@ -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
|
|
@ -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 }"
|
|
@ -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://'
|
||||
|
|
@ -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]
|
||||
|
||||
|;
|
||||
|
||||
|
|
@ -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()
|
|
@ -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;
|
||||
}
|
|
@ -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/);
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
@ -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 |
|
@ -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"
|
||||
|
|
@ -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
|
|
@ -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
|
||||
}
|
||||
'
|
|
@ -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
|
@ -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;
|
|
@ -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
|
||||
|
|
@ -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
|
Loading…
Add table
Add a link
Reference in a new issue