From 71453dd3418caaf0bd8fbc50d25e3ddf51ae1bc8 Mon Sep 17 00:00:00 2001 From: Graham Christensen Date: Thu, 10 Jun 2021 17:45:45 -0400 Subject: [PATCH] Expose Prometheus metrics at /metrics Exposes metrics: * http_request_duration_seconds_bucket * http_request_size_bytes_bucket * http_response_size_bytes_bucket * http_requests_total with labels of action and controller to help identify popular endpoints and their performance characteristics. --- flake.nix | 16 ++++++++++++++++ src/lib/Hydra.pm | 6 +++++- t/Controller/metrics.t | 30 ++++++++++++++++++++++++++++++ 3 files changed, 51 insertions(+), 1 deletion(-) create mode 100644 t/Controller/metrics.t diff --git a/flake.nix b/flake.nix index 6231cc8a..f53ed808 100644 --- a/flake.nix +++ b/flake.nix @@ -70,6 +70,21 @@ }; }; + CatalystPluginPrometheusTiny = final.buildPerlPackage { + pname = "Catalyst-Plugin-PrometheusTiny"; + version = "0.005"; + src = final.fetchurl { + url = "mirror://cpan/authors/id/S/SY/SYSPETE/Catalyst-Plugin-PrometheusTiny-0.005.tar.gz"; + sha256 = "a42ef09efdc3053899ae007c41220d3ed7207582cc86e491b4f534539c992c5a"; + }; + buildInputs = with final.perlPackages; [ HTTPMessage Plack SubOverride TestDeep ]; + propagatedBuildInputs = with final.perlPackages; [ CatalystRuntime Moose PrometheusTiny PrometheusTinyShared ]; + meta = { + description = "Prometheus metrics for Catalyst"; + license = with final.lib.licenses; [ artistic1 gpl1Plus ]; + }; + }; + CryptArgon2 = final.perlPackages.buildPerlModule { pname = "Crypt-Argon2"; version = "0.010"; @@ -358,6 +373,7 @@ CatalystPluginAccessLog CatalystPluginAuthorizationRoles CatalystPluginCaptcha + CatalystPluginPrometheusTiny CatalystPluginSessionStateCookie CatalystPluginSessionStoreFastMmap CatalystPluginStackTrace diff --git a/src/lib/Hydra.pm b/src/lib/Hydra.pm index 0ff86f11..d77c3dba 100644 --- a/src/lib/Hydra.pm +++ b/src/lib/Hydra.pm @@ -16,7 +16,8 @@ use Catalyst qw/ConfigLoader Session Session::Store::FastMmap Session::State::Cookie - Captcha/, + Captcha + PrometheusTiny/, '-Log=warn,fatal,error'; use CatalystX::RoleApplicator; use YAML qw(LoadFile); @@ -47,6 +48,9 @@ __PACKAGE__->config( file($ENV{'HYDRA_LDAP_CONFIG'}) ) : undef }, + 'Plugin::PrometheusTiny' => { + include_action_labels => 1, + }, 'Plugin::Static::Simple' => { send_etag => 1, expires => 3600 diff --git a/t/Controller/metrics.t b/t/Controller/metrics.t new file mode 100644 index 00000000..8915104d --- /dev/null +++ b/t/Controller/metrics.t @@ -0,0 +1,30 @@ +use feature 'unicode_strings'; +use strict; +use Setup; +use JSON qw(decode_json encode_json); + +my %ctx = test_init(); + +require Hydra::Schema; +require Hydra::Model::DB; +require Hydra::Helper::Nix; +use HTTP::Request::Common; + +use Test2::V0; +require Catalyst::Test; +Catalyst::Test->import('Hydra'); + +my $db = Hydra::Model::DB->new; +hydra_setup($db); + +request(GET '/'); +my $metrics = request(GET '/metrics'); +ok($metrics->is_success); + +like( + $metrics->content, + qr/http_requests_total\{action="index",code="200",controller="Hydra::Controller::Root",method="GET"\} 1/, + "Metrics are collected" +); + +done_testing;