From 22b3af61b568732861be17e9759be68715a709fb Mon Sep 17 00:00:00 2001 From: Kevin Morris <kevr@0cost.org> Date: Wed, 13 Oct 2021 17:10:16 -0700 Subject: [PATCH] fix(PHP): sanitize and produce metrics at shutdown This change now requires that PHP routes do not return HTTP 404 to be considered for the /metrics population. Additionally, we make a small sanitization here to avoid trailing '/' characters, unless we're on the homepage route. Signed-off-by: Kevin Morris <kevr@0cost.org> --- web/html/index.php | 24 ++--------------------- web/lib/metricfuncs.inc.php | 38 +++++++++++++++++++++++++++++++++++++ 2 files changed, 40 insertions(+), 22 deletions(-) diff --git a/web/html/index.php b/web/html/index.php index 82a44c55b..990469303 100644 --- a/web/html/index.php +++ b/web/html/index.php @@ -13,28 +13,8 @@ $query_string = $_SERVER['QUERY_STRING']; // If no options.cache is configured, we no-op metric storage operations. $is_cached = defined('EXTENSION_LOADED_APC') || defined('EXTENSION_LOADED_MEMCACHE'); -if ($is_cached) { - $method = $_SERVER['REQUEST_METHOD']; - // We'll always add +1 to our total request count to this $path, - // unless this path == /metrics. - if ($path !== "/metrics") - add_metric("http_requests_count", $method, $path); - - // Extract $type out of $query_string, if we can. - $type = null; - $query = array(); - if ($query_string) - parse_str($query_string, $query); - $type = $query['type']; - - // Only store RPC metrics for valid types. - $good_types = [ - "info", "multiinfo", "search", "msearch", - "suggest", "suggest-pkgbase", "get-comment-form" - ]; - if ($path === "/rpc" && in_array($type, $good_types)) - add_metric("api_requests_count", $method, $path, $type); -} +if ($is_cached) + register_shutdown_function('update_metrics'); if (config_get_bool('options', 'enable-maintenance') && (empty($tokens[1]) || ($tokens[1] != "css" && $tokens[1] != "images"))) { if (!in_array($_SERVER['REMOTE_ADDR'], explode(" ", config_get('options', 'maintenance-exceptions')))) { diff --git a/web/lib/metricfuncs.inc.php b/web/lib/metricfuncs.inc.php index acfc30d7d..7ebb59be8 100644 --- a/web/lib/metricfuncs.inc.php +++ b/web/lib/metricfuncs.inc.php @@ -13,6 +13,44 @@ use \Prometheus\RenderTextFormat; // and will start again at 0 if it's restarted. $registry = new CollectorRegistry(new InMemory()); +function update_metrics() { + // With no code given to http_response_code, it gets the current + // response code set (via http_response_code or header). + if(http_response_code() == 404) + return; + + $path = $_SERVER['PATH_INFO']; + $method = $_SERVER['REQUEST_METHOD']; + $query_string = $_SERVER['QUERY_STRING']; + + // If $path is at least 1 character, strip / off the end. + // This turns $paths like '/packages/' into '/packages'. + if (strlen($path) > 1) + $path = rtrim($path, "/"); + + // We'll always add +1 to our total request count to this $path, + // unless this path == /metrics. + if ($path !== "/metrics") + add_metric("http_requests_count", $method, $path); + + // Extract $type out of $query_string, if we can. + $type = null; + $query = array(); + if ($query_string) + parse_str($query_string, $query); + + if (array_key_exists("type", $query)) + $type = $query["type"]; + + // Only store RPC metrics for valid types. + $good_types = [ + "info", "multiinfo", "search", "msearch", + "suggest", "suggest-pkgbase", "get-comment-form" + ]; + if ($path === "/rpc" && in_array($type, $good_types)) + add_metric("api_requests_count", $method, $path, $type); +} + function add_metric($anchor, $method, $path, $type = null) { global $registry; -- GitLab