1
0
Fork 0
mirror of https://github.com/munin-monitoring/contrib.git synced 2025-07-21 18:41:03 +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

83
plugins/router/arris-tm502g_ Executable file
View file

@ -0,0 +1,83 @@
#!/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)

106
plugins/router/cisco_bgp_ Executable file
View file

@ -0,0 +1,106 @@
#!/usr/bin/perl -w
#
# Plugin to monitor BGP table summary statistics on a cisco router.
#
# Original Author: Peter Holzleitner
#
# Revision 1.1 2010/10/14 19:19
#
# Configuration variables:
#
# iosuser - username (default "")
# iospass - password (default "")
#
# Parameters:
#
# config (required)
#
# Magic markers (optional - only used by munin-config and some
# installation scripts):
#%# family=auto
use Net::Telnet::Cisco;
use Sys::Syslog;
if ($0 =~ /^(?:|.*\/)cisco_bgp_([^_]+)$/) {
$host = $1;
}
($^O eq "linux" || $^O eq "openbsd") && Sys::Syslog::setlogsock('unix');
openlog('munin.bgp', 'cons,pid', 'daemon');
my @BGP_nbr;
my @BGP_pfx;
my $tot_pfx;
my $iosuser = $ENV{iosuser} || "";
my $iospass = $ENV{iospass} || "";
&fetch_bgpstats($host, $iosuser, $iospass);
if ($ARGV[0] and $ARGV[0] eq "config") {
print "host_name $host\n";
print "graph_args --base 1024 -l 0 --vertical-label Prefixes\n";
print "graph_title BGP Neighbour Statistics\n";
print "graph_category network\n";
print "graph_info This graph shows the number of BGP prefixes received by neighbour.\n";
my($n, $i); $n = scalar @BGP_nbr; $i = 0;
while($n--) {
my $neigh = $BGP_nbr[$i++];
print "n$i.label $neigh\n";
}
# print "total.label Total\n";
# print "total.info Total number of prefixes in the BGP table\n";
} else {
my($n, $i); $n = scalar @BGP_nbr; $i = 0;
while($n--) {
my $pfx = $BGP_pfx[$i++];
print "n$i.value $pfx\n";
}
# print "total.value $tot_pfx\n";
}
sub fetch_bgpstats
{
my $hostname = shift;
my $username = shift;
my $password = shift;
my $session = Net::Telnet::Cisco->new(Host => $host);
$session->login($username, $password);
$session->cmd('terminal length 200');
$session->cmd('terminal width 200');
my @output = $session->cmd('show ip bgp summary');
# example output of router
# ------------------------
# [...]
# Neighbor V AS MsgRcvd MsgSent TblVer InQ OutQ Up/Down State/PfxRcd
# 11.111.11.111 4 98765 12403694 509571 308911893 0 0 1d23h 329193
# 122.122.122.122 4 1234 13242856 383827 308911879 0 0 00:08:22 330761
foreach(@output) {
chomp; s/\r//g;
$tot_pfx = $1 if /^BGP activity (\d+)\/(\d+) prefixes/;
syslog('debug', "$hostname: $_\n");
next unless /^(\d+\.\d+\.\d+\.\d+)\s+\d+\s+(\d+)\s+\d+\s+\d+\s+\d+\s+\d+\s+\d+\s+[0-9a-z:]+\s+(\d+)/;
my ($neigh, $as, $pfx) = ($1, $2, $3);
syslog('debug', "$neigh (AS $as)");
push @BGP_nbr, "$neigh (AS $as)";
push @BGP_pfx, $pfx;
}
}
# vim:syntax=perl:ts=8

View file

@ -0,0 +1,253 @@
#!/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

138
plugins/router/dartybox Executable file
View file

@ -0,0 +1,138 @@
#! /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 network
echo up.label UpStream
echo down.label DownStream
echo multigraph dbox_adsl_att
echo graph_title DartyBox Adsl Attenuation
echo graph_category network
echo up.label UpStream
echo down.label DownStream
echo multigraph dbox_adsl_snr
echo graph_title DartyBox Adsl SignalNoise Ratio
echo graph_category network
echo up.label UpStream
echo down.label DownStream
echo multigraph dbox_adsl_pkt
echo graph_title DartyBox Adsl Packets
echo graph_category network
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 network
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

194
plugins/router/modem-nvg510 Executable file
View file

@ -0,0 +1,194 @@
#! /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]
|;

170
plugins/router/motorola_sb6141 Executable file
View file

@ -0,0 +1,170 @@
#!/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()

1558
plugins/router/tg585v7__ Executable file

File diff suppressed because it is too large Load diff