#! /usr/bin/env perl

use strict;
use utf8;
use Net::Statsd;
use File::Slurp;
use JSON;

STDERR->autoflush(1);
binmode STDERR, ":encoding(utf8)";

sub gauge {
    my ($name, $val) = @_;
    die unless defined $val;
    Net::Statsd::gauge($name, $val);
}

sub sendQueueRunnerStats {
    my $s = `hydra-queue-runner --status`;
    die "cannot get queue runner stats\n" if $? != 0;

    my $json = decode_json($s) or die "cannot decode queue runner status";

    gauge("hydra.queue.up", $json->{status} eq "up" ? 1 : 0);

    return if $json->{status} ne "up";

    gauge("hydra.queue.steps.active", $json->{nrActiveSteps});
    gauge("hydra.queue.steps.building", $json->{nrStepsBuilding});
    gauge("hydra.queue.steps.copying_to", $json->{nrStepsCopyingTo});
    gauge("hydra.queue.steps.copying_from", $json->{nrStepsCopyingFrom});
    gauge("hydra.queue.steps.waiting", $json->{nrStepsWaiting});
    gauge("hydra.queue.steps.runnable", $json->{nrRunnableSteps});
    gauge("hydra.queue.steps.unfinished", $json->{nrUnfinishedSteps});
    gauge("hydra.queue.steps.finished", $json->{nrStepsDone});
    gauge("hydra.queue.steps.retries", $json->{nrRetries});
    gauge("hydra.queue.steps.max_retries", $json->{maxNrRetries});
    if ($json->{nrStepsDone}) {
        gauge("hydra.queue.steps.avg_total_time", $json->{avgStepTime});
        gauge("hydra.queue.steps.avg_build_time", $json->{avgStepBuildTime});
    }

    gauge("hydra.queue.builds.read", $json->{nrBuildsRead});
    gauge("hydra.queue.builds.unfinished", $json->{nrQueuedBuilds});
    gauge("hydra.queue.builds.finished", $json->{nrBuildsDone});

    gauge("hydra.queue.checks", $json->{nrQueueWakeups});

    gauge("hydra.queue.bytes_sent", $json->{bytesSent});
    gauge("hydra.queue.bytes_received", $json->{bytesReceived});
}

while (1) {
    eval { sendQueueRunnerStats(); };
    if ($@) { warn "$@"; }

    my $meminfo = read_file("/proc/meminfo", err_mode => 'quiet') // "";
    $meminfo =~ m/Dirty:\s*(\d+) kB/;
    if (defined $1) {
        my $dirty = $1 / (1024.0 * 1024.0);
        gauge("hydra.mem.dirty", $dirty);
    }

    sleep(30);
}