mirror of
https://github.com/munin-monitoring/contrib.git
synced 2018-11-08 00:59:34 +01:00
236 lines
6.9 KiB
Text
236 lines
6.9 KiB
Text
|
#!/usr/bin/perl
|
|||
|
# -*- cperl -*-
|
|||
|
|
|||
|
=head1 NAME
|
|||
|
|
|||
|
zenus_ - Munin plugin to monitor the usage of a Zen Internet Broadband account
|
|||
|
|
|||
|
=head1 APPLICABLE SYSTEMS
|
|||
|
|
|||
|
Any (Though most likely those connected to a Zen Internet Broadband connection)
|
|||
|
|
|||
|
=head1 CONFIGURATION
|
|||
|
|
|||
|
This plugin requires the C<zenus> module to be installed. This can be fetched
|
|||
|
from L<http://www.rachaelandtom.info/zenus>.
|
|||
|
|
|||
|
Tip: To see if it's already setup correctly, just run this plugin
|
|||
|
with the parameter 'autoconf'. If you get a "yes", everything should
|
|||
|
work like a charm already.
|
|||
|
|
|||
|
This configuration section shows the defaults of the plugin:
|
|||
|
|
|||
|
[zenus_*]
|
|||
|
env.user
|
|||
|
env.pass
|
|||
|
env.account
|
|||
|
env.tick 60
|
|||
|
|
|||
|
You must supply C<env.user> and C<env.pass>. These will be your PORTAL username and password, NOT your ADSL account details.
|
|||
|
|
|||
|
You may either specify the account to report through C<env.account> (e.g. zen12345@zen) or by naming the symlink in your plugins directory (e.g. zenus_zen12345_zen). If no account is specified, the default account will be chosen.
|
|||
|
|
|||
|
C<env.tick> specifies how often (in minutes) the data will be refreshed from upstream. This is to avoid hitting the Zen servers every five minutes. Data is cached between runs.
|
|||
|
|
|||
|
=head1 INTERPRETATION
|
|||
|
|
|||
|
The plugin shows the amount of data downloaded and uploaded since the beginning of the chargable period (i.e. the calendar month). A thick line shows the current download allowance (planned plus banked). A thinner line shows the estimated amount remaining at the end of the month. If you are estimated to exceed your allowance before the end of the month, a second line appears showing the rate at which you're downloading beyond the sustainable rate.
|
|||
|
|
|||
|
Warnings are sent if your estimated allowance drops below 25% of your cap and if the overspeed rate rises above zero. Critical warnings are sent if your estimated allowance drops below 10% of your cap.
|
|||
|
|
|||
|
=head1 MAGIC MARKERS
|
|||
|
|
|||
|
#%# family=auto contrib
|
|||
|
#%# capabilities=autoconf suggest
|
|||
|
|
|||
|
=head1 AUTHOR
|
|||
|
|
|||
|
Paul Saunders L<darac@darac.org.uk>
|
|||
|
|
|||
|
=cut
|
|||
|
|
|||
|
use strict;
|
|||
|
use warnings;
|
|||
|
|
|||
|
use lib $ENV{'MUNIN_LIBDIR'};
|
|||
|
use Munin::Plugin;
|
|||
|
use Data::Dump qw(pp);
|
|||
|
|
|||
|
my $ret = undef;
|
|||
|
|
|||
|
# Load modules like so
|
|||
|
if ( !eval "require zenus;" ) {
|
|||
|
$ret =
|
|||
|
"Could not load zenus. Get it from http://www.rachaelandtom.info/zenus";
|
|||
|
}
|
|||
|
|
|||
|
my $USER = $ENV{user};
|
|||
|
my $PASS = $ENV{pass};
|
|||
|
my $ACCT = $ENV{account} || "";
|
|||
|
my $TICK = $ENV{tick} || 60; # minutes
|
|||
|
|
|||
|
my @name_fields = split /_/, $0;
|
|||
|
if ( scalar @name_fields == 3 ) {
|
|||
|
if ( $name_fields[1] eq '' or $name_fields[2] eq '' ) {
|
|||
|
print "Misconfigured symlink. See Documentation\n";
|
|||
|
exit 1;
|
|||
|
}
|
|||
|
else {
|
|||
|
$ACCT = $name_fields[1] . '@' . $name_fields[2];
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
# If there are more or less than 3 components to the filename,
|
|||
|
# we just carry on with the default account
|
|||
|
|
|||
|
my $lastread;
|
|||
|
|
|||
|
sub save_data {
|
|||
|
my $hashref = shift;
|
|||
|
|
|||
|
# Do we need to save this info
|
|||
|
if ( time > $lastread + ( $TICK * 60 ) ) {
|
|||
|
|
|||
|
$lastread = time;
|
|||
|
|
|||
|
my @save_vector;
|
|||
|
push @save_vector, $lastread;
|
|||
|
|
|||
|
# Push the hash values on to the array
|
|||
|
foreach ( keys %$hashref ) {
|
|||
|
push @save_vector, $_ . '<27>' . $hashref->{$_};
|
|||
|
}
|
|||
|
|
|||
|
#Go!
|
|||
|
save_state(@save_vector);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
sub load_data {
|
|||
|
|
|||
|
# Bring the data back in
|
|||
|
my @save_vector = restore_state();
|
|||
|
|
|||
|
# Read the timestamp. Do we need to refresh the data?
|
|||
|
$lastread = shift @save_vector;
|
|||
|
|
|||
|
my $hashref;
|
|||
|
foreach (@save_vector) {
|
|||
|
my ( $key, $value ) = split /<2F>/;
|
|||
|
$hashref->{$key} = $value;
|
|||
|
}
|
|||
|
if ( !defined $lastread or time >= ( $lastread + ( $TICK * 60 ) ) ) {
|
|||
|
|
|||
|
# Data is stale
|
|||
|
|
|||
|
#print STDERR "REFRESHING DATA\n";
|
|||
|
my $temphash;
|
|||
|
eval {
|
|||
|
zenus::login( $USER, $PASS );
|
|||
|
|
|||
|
(
|
|||
|
$temphash->{name}, $temphash->{used},
|
|||
|
$temphash->{avail}, $temphash->{per},
|
|||
|
$temphash->{uploadAmount}
|
|||
|
) = zenus::getUsage($ACCT);
|
|||
|
(
|
|||
|
$temphash->{dayofmonth}, $temphash->{permonth},
|
|||
|
$temphash->{avedaily}, $temphash->{maxdaily},
|
|||
|
$temphash->{daysremain}, $temphash->{estusage},
|
|||
|
$temphash->{daysinmonth}
|
|||
|
)
|
|||
|
= zenus::estimateRemaining( $temphash->{used},
|
|||
|
$temphash->{avail} );
|
|||
|
$hashref = $temphash;
|
|||
|
|
|||
|
# If zenus threw an error we won't copy the data over,
|
|||
|
# so we still use the cached data.
|
|||
|
};
|
|||
|
}
|
|||
|
return $hashref;
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
if ( defined $ARGV[0] and $ARGV[0] eq "autoconf" ) {
|
|||
|
if ($ret) {
|
|||
|
print "no ($ret)\n";
|
|||
|
exit 1;
|
|||
|
}
|
|||
|
print "yes\n";
|
|||
|
exit 0;
|
|||
|
}
|
|||
|
|
|||
|
if ( defined $ARGV[0] and $ARGV[0] eq "suggest" ) {
|
|||
|
if ( defined $USER and defined $PASS ) {
|
|||
|
zenus::login( $USER, $PASS );
|
|||
|
for my $account ( zenus::getAccounts() ) {
|
|||
|
if ( defined $account ) {
|
|||
|
$account =~ s/\@/_/g;
|
|||
|
print "$account\n";
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
exit 0;
|
|||
|
}
|
|||
|
|
|||
|
if ( defined $ARGV[0] and $ARGV[0] eq "config" ) {
|
|||
|
if ($ret) {
|
|||
|
print $ret;
|
|||
|
exit 1;
|
|||
|
}
|
|||
|
my $data = load_data();
|
|||
|
my $cap = sprintf( "%.3f", $data->{avail} );
|
|||
|
my $warn = sprintf( "%.3f", $cap * 0.25 );
|
|||
|
my $crit = sprintf( "%.3f", $cap * 0.1 );
|
|||
|
print <<EOF;
|
|||
|
graph_args --base 1000
|
|||
|
graph_vlabel GBytes
|
|||
|
graph_category Network
|
|||
|
graph_title Zen Broadband Usage
|
|||
|
graph_info Usage of your Zen Broadband account: $data->{name}
|
|||
|
download.label Downloaded
|
|||
|
download.type GAUGE
|
|||
|
download.info Amount of data downloaded (Limit is $cap GB)
|
|||
|
download.draw AREA
|
|||
|
upload.label Uploaded
|
|||
|
upload.type GAUGE
|
|||
|
upload.info Amount of data uploaded (No upper limit)
|
|||
|
upload.draw AREA
|
|||
|
allowance.label Allowance
|
|||
|
allowance.type GAUGE
|
|||
|
allowance.info Amount of data you are allowed to download this month
|
|||
|
allowance.draw LINE2
|
|||
|
remaining.label Est'd Remaining
|
|||
|
remaining.type GAUGE
|
|||
|
remaining.info Estimated amount of data transfer remaining at the end of the month
|
|||
|
remaining.draw LINE1
|
|||
|
remaining.min 0
|
|||
|
remaining.max $cap
|
|||
|
remaining.warning $warn:
|
|||
|
remaining.critical $crit:
|
|||
|
overrate.label Overspeed Rate
|
|||
|
overrate.type GAUGE
|
|||
|
overrate.info Rate at which you're downloading beyond the sustainable rate
|
|||
|
overrate.draw LINE1
|
|||
|
overrate.min 0
|
|||
|
overrate.warning 0:
|
|||
|
graph_order download upload allowance remaining overrate
|
|||
|
EOF
|
|||
|
|
|||
|
save_data($data);
|
|||
|
exit 0;
|
|||
|
}
|
|||
|
|
|||
|
my $data = load_data();
|
|||
|
print "upload.value " . $data->{uploadAmount} . "\n";
|
|||
|
print "download.value " . $data->{used} . "\n";
|
|||
|
print "allowance.value " . $data->{avail} . "\n";
|
|||
|
my $remain = $data->{avail} - $data->{estusage};
|
|||
|
$remain = 0 if $remain < 0;
|
|||
|
print "remaining.value " . $remain . "\n";
|
|||
|
my $overrate = $data->{avedaily} - $data->{maxdaily};
|
|||
|
$overrate = 0 if $overrate < 0;
|
|||
|
print "overrate.value " . $overrate . "\n";
|
|||
|
save_data($data);
|
|||
|
exit 0;
|