#!/usr/bin/perl

use strict;
use warnings;

use Gearman::Client;
use JSON;
use Sys::Hostname;

use Getopt::Long;
my $NOSUBMIT;
GetOptions(
   'nosubmit|n+' => \$NOSUBMIT,
) or exit 1;

sub get_cpu_stats
{
   my %cpu;

   open my $fh, "<", "/proc/stat" or return;
   while( <$fh> ) {
      chomp;
      my ( $name, @data ) = split m/ +/, $_;
      if( $name eq "cpu" ) {
         @cpu{qw( user nice system idle iowait irq softirq )} = @data;
      }
   }

   return \%cpu;
}

sub get_net_stats
{
   my %net;

   open my $fh, "<", "/proc/net/dev" or return;
   <$fh>; <$fh>; # ignore top two lines
   while( <$fh> ) {
      chomp;
      s/^\s*(\S+):\s*// or next;
      my $iface = $1;
      my @stats = split m/ +/, $_;

      $net{$iface} = {
         rx => { bytes => $stats[0], packets => $stats[1], },
         tx => { bytes => $stats[8], packets => $stats[9], },
      };
   }

   return \%net;
}

my $client = Gearman::Client->new(
   job_servers => ["cel.leonerd.org.uk:4730"],
);

sub submit
{
   my ( $time, $sub_entity, $values ) = @_;

   my $json = encode_json({
      timestamp => $time,
      entity => join( ".", grep { defined } hostname(), $sub_entity ),
      values => $values,
   });

   if( $NOSUBMIT ) {
      print "$json\n";
   }
   else {
      $client->do_task( "bunny/submit", $json );
   }
}

my $nexttime = time();
while(1) {
   sleep($nexttime - time());

   my $now = time();

   submit( $now, "cpu", get_cpu_stats() );

   my $net = get_net_stats();
   foreach my $iface ( keys %$net ) {
      submit( $now, "net.$iface", $net->{$iface} );
   }

   $nexttime += 60;
}
