munin-contrib/plugins/2wire/2wire

456 lines
12 KiB
Perl
Executable File

#!/usr/bin/perl
# -*- perl -*-
=head1 NAME
2wire - Plugin to monitor 2Wire/Pace residential gateway
=head1 CONFIGURATION
[2wire]
env.gatewayaddr http://192.168.1.254
env.drawline true
env.monthline 250000000000
env.weekline 62500000000
env.dayline 8333333333
=head1 LICENSE
GPLv2
=head1 AUTHOR
Daniel Lee <Longinus00@gmail.com>
=head1 MAGICK MARKERS
#%# family=network
#%# capabilities=autoconf
=cut
use strict;
use warnings;
use POSIX;
use WWW::Mechanize;
use WWW::Mechanize::TreeBuilder;
use Munin::Plugin;
my $gatewayAddr = $ENV{'gatewayaddr'} || 'http://192.168.1.254';
my $drawLine = $ENV{'drawline'} || 'false';
my $monthLine = $ENV{'monthline'} || 250000000000;
my $weekLine = $ENV{'weekline'} || 62500000000;
my $dayLine = $ENV{'dayline'} || 8333333333;
my $mech = WWW::Mechanize->new;
WWW::Mechanize::TreeBuilder->meta->apply($mech);
sub autoconf {
my $url = $gatewayAddr."/xslt?PAGE=C_0_0";
$mech->get( $url );
if($mech->success()) {
print "yes\n";
}
else {
print "no\n";
}
exit 0;
}
sub config {
print << "EOF";
multigraph 2wire_session_count
graph_title 2wire NAT session count
graph_args --base 1000 -l 0
#graph_vlabel number of sessions in (-) / out (+)
graph_vlabel number of sessions
graph_scale no
graph_category network
graph_total Total
graph_printf %.0lf
inboundSessions.label Inbound
inboundSessions.draw AREASTACK
#inboundSessions.graph no
outboundSessions.label Outbound
outboundSessions.draw AREASTACK
#outboundSessions.negative inboundSessions
#inboundSessions.line 512:ff0000:Inbound session limit
outboundSessions.line 1024:ff0000:Session table limit
multigraph 2wire_session_type
graph_title 2wire NAT session type
graph_args --base 1000 -l 0
graph_vlabel number of sessions
graph_scale no
graph_category network
graph_total Total
graph_printf %.0lf
tcpSessions.label TCP
tcpSessions.draw AREASTACK
udpSessions.label UDP
udpSessions.draw AREASTACK
udpSessions.line 1024:ff0000:Session table limit
multigraph 2wire_session_uptime
graph_title 2wire session uptime
graph_args --base 1000 -l 0
graph_vlabel Uptime in days
graph_scale no
graph_category network
sessionUptime.label Uptime
sessionUptime.draw AREA
sessionUptime.cdef sessionUptime,86400,/
###
multigraph 2wire_dsl_power
graph_title 2wire DSL output power
graph_args --base 1000
graph_vlabel dBmV
graph_scale no
graph_category network
powerDown.label Down
#powerDown.graph no
powerUp.label Up
#powerUp.negative powerDown
multigraph 2wire_dsl_details
graph_title 2wire DSL details
graph_args --base 1000
graph_vlabel dB
graph_scale no
graph_category network
noiseM.label Noise margin
attenuation.label Attenuation
attenuation300.label Attenuation @ 300kHz
gain.label Final Receive Gain
multigraph 2wire_dsl_seconds
graph_title 2wire Errors Time
graph_args --base 1000
graph_vlabel s
graph_scale no
graph_category network
cumSecErrors.label Cumulative Seconds w/Errors
cumSecSevErrors.label Cumulative Seconds w/Severe Errors
unavailable.label DSL Unavailable Seconds
multigraph 2wire_dsl_blocks
graph_title 2wire Block Correction
graph_args --base 1000
graph_vlabel blocks/s
graph_scale no
graph_category network
correctedBlocks.label Corrected Blocks
correctedBlocks.type DERIVE
correctedBlocks.min 0
uncorrectableBlocks.label Uncorrectable Blocks
uncorrectableBlocks.type DERIVE
uncorrectableBlocks.min 0
multigraph 2wire_dsl_traffic
graph_title 2wire DSL traffic
graph_args --base 1024 -l 0
graph_vlabel Bytes in (-) / out (+) per second
graph_category network
receive.label Bps
receive.type DERIVE
receive.min 0
receive.graph no
transmit.label Bps
transmit.type DERIVE
transmit.min 0
transmit.negative receive
####
multigraph 2wire_dsl_bandwidth_monthly
graph_title 2wire DSL bandwidth usage (monthly)
graph_args --base 1024 -l 0 -M
graph_vlabel Bytes
graph_category network
down.label Down
up.label Up
total.label Total
EOF
if($drawLine eq 'true') {
print "total.line ".$monthLine.":ff0000\n"
}
print << "EOF";
multigraph 2wire_dsl_bandwidth_weekly
graph_title 2wire DSL bandwidth usage (weekly)
graph_args --base 1024 -l 0 -M
graph_vlabel Bytes
graph_category network
down.label Down
up.label Up
total.label Total
EOF
if($drawLine eq 'true') {
print "total.line ".$weekLine.":ff0000\n"
}
print << "EOF";
multigraph 2wire_dsl_bandwidth_daily
graph_title 2wire DSL bandwidth usage (daily)
graph_args --base 1024 -l 0 -M
graph_vlabel Bytes
graph_category network
down.label Down
up.label Up
total.label Total
EOF
if($drawLine eq 'true') {
print "total.line ".$dayLine.":ff0000\n"
}
exit 0;
}
sub bandwidth_acc {
my $date = shift;
my $bandwidth = shift;
my $str = shift;
my $up = shift;
my $down = shift;
unless(exists $bandwidth->{$str}) {
$bandwidth->{$str} = $date;
$bandwidth->{$str.'_u_c'} = 0;
$bandwidth->{$str.'_d_c'} = 0;
$bandwidth->{$str.'_u_t'} = $up;
$bandwidth->{$str.'_d_t'} = $down;
}
if($date != $bandwidth->{$str}) {
$bandwidth->{$str} = $date;
if($bandwidth->{$str.'_u_t'} <= $up || $bandwidth->{$str.'_d_t'} <= $down) {
$bandwidth->{$str.'_u_c'} = $up - $bandwidth->{$str.'_u_t'};
$bandwidth->{$str.'_d_c'} = $down - $bandwidth->{$str.'_d_t'};
}
else {
$bandwidth->{$str.'_u_c'} = 0;
$bandwidth->{$str.'_d_c'} = 0;
}
}
elsif($bandwidth->{$str.'_u_t'} > $up || $bandwidth->{$str.'_d_t'} > $down) {
$bandwidth->{$str.'_u_c'} += $up;
$bandwidth->{$str.'_d_c'} += $down;
}
else {
$bandwidth->{$str.'_u_c'} += $up - $bandwidth->{$str.'_u_t'};
$bandwidth->{$str.'_d_c'} += $down - $bandwidth->{$str.'_d_t'};
}
$bandwidth->{$str.'_u_t'} = $up;
$bandwidth->{$str.'_d_t'} = $down;
}
sub process_bandwidth {
my $values = shift;
my ($up,$down) = ($values->{'transmit'}, $values->{'receive'});
my ($day, $week, $month) = map(int, split(/ /, POSIX::strftime("%j %U %m", localtime)));
$month = int(($week-1) / 4);
my %bandwidth = restore_state();
my %bandwidth = ();
bandwidth_acc($month,\%bandwidth,'month',$up,$down);
bandwidth_acc($week,\%bandwidth,'week',$up,$down);
bandwidth_acc($day,\%bandwidth,'day',$up,$down);
save_state(%bandwidth);
print "multigraph 2wire_dsl_bandwidth_monthly\n";
print "up.value ", $bandwidth{'month_u_c'},"\n";
print "down.value ", $bandwidth{'month_d_c'},"\n";
print "total.value ", $bandwidth{'month_u_c'}+$bandwidth{'month_d_c'},"\n";
print "\n";
print "multigraph 2wire_dsl_bandwidth_weekly\n";
print "up.value ", $bandwidth{'week_u_c'},"\n";
print "down.value ", $bandwidth{'week_d_c'},"\n";
print "total.value ", $bandwidth{'week_u_c'}+$bandwidth{'week_d_c'},"\n";
print "\n";
print "multigraph 2wire_dsl_bandwidth_daily\n";
print "up.value ", $bandwidth{'day_u_c'},"\n";
print "down.value ", $bandwidth{'day_d_c'},"\n";
print "total.value ", $bandwidth{'day_u_c'}+$bandwidth{'day_d_c'},"\n";
print "\n";
}
sub process_values {
my $values = shift;
print << "EOF";
multigraph 2wire_dsl_power
powerDown.value $values->{'power-down'}
powerUp.value $values->{'power-up'}
multigraph 2wire_dsl_details
noiseM.value $values->{'noise-margin'}
attenuation.value $values->{'attenuation'}
attenuation300.value $values->{'attenuation300'}
gain.value $values->{'gain'}
multigraph 2wire_dsl_seconds
cumSecErrors.value $values->{'cum-sec-errors'}
cumSecSevErrors.value $values->{'cum-sec-sev-errors'}
unavailable.value $values->{'sec-unavailable'}
multigraph 2wire_dsl_blocks
correctedBlocks.value $values->{'corrected-blocks'}
uncorrectableBlocks.value $values->{'uncorrectable-blocks'}
multigraph 2wire_dsl_traffic
transmit.value $values->{'transmit'}
receive.value $values->{'receive'}
EOF
}
sub broadband_page {
my $url = $gatewayAddr."/xslt?PAGE=C_1_0";
$mech->get( $url );
die unless $mech->success();
my (%values, $m);
$m = $mech->look_down(_tag => 'td', sub { $_[0]->as_text eq 'Noise Margin'});
$m->right()->as_text =~ /(\S+) dB/;
$values{'noise-margin'} = $1;
$m = $mech->look_down(_tag => 'td', sub { $_[0]->as_text eq 'Attenuation'});
$m->right()->as_text =~ /(\S+) dB/;
$values{'attenuation'} = $1;
$m = $mech->look_down(_tag => 'td', sub { $_[0]->as_text eq 'Output Power'});
$m->right()->as_text =~ /(\S+) dB/;
$values{'power-down'} = $1;
$m = $m->right();
$m->right()->as_text =~ /(\S+) dB/;
$values{'power-up'} = $1;
$m = $mech->look_down(_tag => 'td', sub { $_[0]->as_text eq 'Attenuation @ 300kHz'});
$m->right()->as_text =~ /(\S+) dB/;
$values{'attenuation300'} = $1;
$m = $mech->look_down(_tag => 'td', sub { $_[0]->as_text eq 'Final Receive Gain'});
$m->right()->as_text =~ /(\S+) dB/;
$values{'gain'} = $1;
$m = $mech->look_down(_tag => 'td', sub { $_[0]->as_text eq 'Transmit'});
$m->right()->as_text =~ /(\d+)/;
$values{'transmit'} = int $1;
$m = $mech->look_down(_tag => 'td', sub { $_[0]->as_text eq 'Receive'});
$m->right()->as_text =~ /(\d+)/;
$values{'receive'} = int $1;
$m = $mech->look_down(_tag => 'td', sub { $_[0]->as_text eq 'Receive'});
$m->right()->as_text =~ /(\d+)/;
$values{'receive'} = int $1;
$m = $mech->look_down(_tag => 'td', sub { $_[0]->as_text eq 'Link Retrains'});
$m->right()->as_text =~ /(\d+)/;
$values{'link-retrains'} = int $1;
$m = $mech->look_down(_tag => 'td', sub { $_[0]->as_text eq 'DSL Training Errors'});
$m->right()->as_text =~ /(\d+)/;
$values{'dsl-training-errors'} = int $1;
$m = $mech->look_down(_tag => 'td', sub { $_[0]->as_text eq 'Training Timeouts'});
$m->right()->as_text =~ /(\d+)/;
$values{'training-timeouts'} = int $1;
$m = $mech->look_down(_tag => 'td', sub { $_[0]->as_text eq 'Cum. Seconds w/Errors'});
$m->right()->as_text =~ /(\d+)/;
$values{'cum-sec-errors'} = int $1;
$m = $mech->look_down(_tag => 'td', sub { $_[0]->as_text eq 'Cum. Sec. w/Severe Errors'});
$m->right()->as_text =~ /(\d+)/;
$values{'cum-sec-sev-errors'} = int $1;
$m = $mech->look_down(_tag => 'td', sub { $_[0]->as_text eq 'Corrected Blocks'});
$m->right()->as_text =~ /(\d+)/;
$values{'corrected-blocks'} = int $1;
$m = $mech->look_down(_tag => 'td', sub { $_[0]->as_text eq 'Uncorrectable Blocks'});
$m->right()->as_text =~ /(\d+)/;
$values{'uncorrectable-blocks'} = int $1;
$m = $mech->look_down(_tag => 'td', sub { $_[0]->as_text eq 'DSL Unavailable Seconds'});
$m->right()->as_text =~ /(\d+)/;
$values{'sec-unavailable'} = int $1;
process_values(\%values);
process_bandwidth(\%values);
}
sub nat_page {
my $url = $gatewayAddr."/xslt?PAGE=C_5_5";
$mech->get( $url );
die unless $mech->success();
my (%sessions, $uptime);
my ($m, $raw, @stext);
$m = $mech->look_down(_tag => 'h2', sub { $_[0]->as_text eq 'Current NAT Sessions'});
$raw = $m->right()->as_text;
$raw =~ s/^\n//;
@stext = split("\n", $raw);
$stext[0] =~ /boot: (\d+)/;
$uptime = int $1;
$stext[1] =~ /session table (\d+)\/(\d+) available, (\d+)\/\d+ used/;
($sessions{'used'}, $sessions{'inbound'}) = ($2 - $1, $3);
$sessions{'outbound'} = $sessions{'used'} - $sessions{'inbound'};
my $i = 0;
foreach (@stext) {
$i += 1 if /proto: 6/;
}
($sessions{'tcp'}, $sessions{'udp'}) = ($i, $sessions{'used'} - $i);
print << "EOF";
multigraph 2wire_session_count
inboundSessions.value $sessions{'inbound'}
outboundSessions.value $sessions{'outbound'}
multigraph 2wire_session_type
tcpSessions.value $sessions{'tcp'}
udpSessions.value $sessions{'udp'}
multigraph 2wire_session_uptime
sessionUptime.value $uptime
EOF
}
if($ARGV[0] and $ARGV[0] eq "autoconf") {
autoconf
}
elsif($ARGV[0] and $ARGV[0] eq "config") {
config
}
else {
broadband_page;
nat_page;
}