#!/usr/bin/env perl
use 5.010;
use strict;
use warnings;
use autodie;
use List::Util 'sum';

=head1 NAME

vnstat_month - Run C<vnstat --dumpdb> and report usage this month

=head1 SYNOPSIS

Optionally, in In F</etc/munin/plugin-conf.d/munin-node>:

    # Set the max bandwidth to 800 GB per month
    [vnstat_month]
    env.limittt 800000

=head1 AUTHOR

E<AElig>var ArnfjE<ouml>rE<eth> Bjarmason <avar@cpan.org>

=head1 LICENSE

This program is in the public domain.

=head1 MAGIC MARKERS

  #%# family=auto

=cut

my $limittt = $ENV{limittt};

given ($ARGV[0]) {
    when ("config") {
        print <<END;
graph_title Total traffic this month
graph_args --base 1000 --lower-limit 0
graph_vlabel Monthly traffic
graph_category network
graph_info Total network traffic in bytes.
totaltx.label Sent
totaltx.info Total data sent.
totaltx.cdef totaltx,1000000,*
totalrx.label Received
totalrx.info Total data received.
totalrx.cdef totalrx,1000000,*
totaltt.label Total
totaltt.info Total data sent & received.
totaltt.cdef totaltt,1000000,*
END
        if ($limittt) {
            print <<END;
limittt.label Limit
limittt.info The data transfer limit for this month
limittt.cdef limittt,1000000,*
END
        }
    }
    default {
        my @days = get_daylines();
        my @relevant = grep {
            my ($this_month) = localtime =~ /^\S+ (\S+)\b/;
            localtime($_->{time}) =~ /^\S+ $this_month\b/;
        } @days;

        my $rx = sum( map { $_->{rx_mib} } @relevant );
        my $tx = sum( map { $_->{tx_mib} } @relevant );
        my $tt = $rx + $tx;

        print <<"END";
totalrx.value $rx
totaltx.value $tx
totaltt.value $tt
END
        if ($limittt) {
            print <<"END";
limittt.value $limittt
END
        }
    }
}

sub get_daylines {
    open my $vnstat, "vnstat --dumpdb |";
    my @lines;
    while (my $line = <$vnstat>) {
        chomp $line;
        my $ns = qr/[^:]+/;
        next unless $line =~ /^d;(?<day>$ns);(?<time>$ns);(?<rx_mib>$ns);(?<tx_mib>$ns);(?<rx_kib>$ns);(?<tx_kib>$ns);(?<in_use>$ns)$/;
        push @lines => { %+ };
    }
    return @lines;
}
