From 937e16532880ea447d2e1ea19cc6997cbeb371b5 Mon Sep 17 00:00:00 2001 From: Graham Christensen Date: Tue, 24 Sep 2019 16:34:16 -0400 Subject: [PATCH] export a /prometheus endpoint Currently only shows per-machine build times --- release.nix | 1 + src/lib/Hydra/Controller/Root.pm | 45 ++++++++++++++++++++++++++++++++ 2 files changed, 46 insertions(+) diff --git a/release.nix b/release.nix index 04fdc682..92760b3c 100644 --- a/release.nix +++ b/release.nix @@ -99,6 +99,7 @@ rec { LWP LWPProtocolHttps NetAmazonS3 + NetPrometheus NetStatsd PadWalker Readonly diff --git a/src/lib/Hydra/Controller/Root.pm b/src/lib/Hydra/Controller/Root.pm index 188d73bd..32c841b0 100644 --- a/src/lib/Hydra/Controller/Root.pm +++ b/src/lib/Hydra/Controller/Root.pm @@ -6,6 +6,7 @@ use warnings; use base 'Hydra::Base::Controller::ListBuilds'; use Hydra::Helper::Nix; use Hydra::Helper::CatalystUtils; +use Hydra::View::TT; use Digest::SHA1 qw(sha1_hex); use Nix::Store; use Nix::Config; @@ -13,6 +14,7 @@ use Encode; use File::Basename; use JSON; use List::MoreUtils qw{any}; +use Net::Prometheus; # Put this controller at top-level. __PACKAGE__->config->{namespace} = ''; @@ -200,6 +202,49 @@ sub machines :Local Args(0) { $self->status_ok($c, entity => $c->stash->{machines}); } +sub prometheus :Local Args(0) { + my ($self, $c) = @_; + my $machines = getMachines; + + my $client = Net::Prometheus->new; + my $duration = $client->new_histogram( + name => "hydra_machine_build_duration", + help => "How long builds are taking per server. Note: counts are gauges, NOT counters.", + labels => [ "machine" ], + buckets => [ + 60, + 600, + 1800, + 3600, + 7200, + 21600, + 43200, + 86400, + 172800, + 259200, + 345600, + 518400, + 604800, + 691200 + ] + ); + + my $steps = dbh($c)->selectall_arrayref( + "select machine, s.starttime as starttime " . + "from BuildSteps s join Builds b on s.build = b.id " . + "where busy != 0 order by machine, stepnr", + { Slice => {} }); + + foreach my $step (@$steps) { + my $name = $step->{machine} ? Hydra::View::TT->stripSSHUser(undef, $step->{machine}) : ""; + $name = "localhost" unless $name; + $duration->labels($name)->observe(time - $step->{starttime}); + } + + $c->stash->{'plain'} = { data => $client->render }; + $c->forward('Hydra::View::Plain'); +} + # Hydra::Base::Controller::ListBuilds needs this. sub get_builds : Chained('/') PathPart('') CaptureArgs(0) {