diff --git a/Cargo.lock b/Cargo.lock index 05c2654d37..c217dfbebb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2578,6 +2578,7 @@ version = "0.1.0" dependencies = [ "lazy_static", "libc", + "once_cell", "prometheus", ] diff --git a/pageserver/src/bin/pageserver.rs b/pageserver/src/bin/pageserver.rs index 21bf0d4ba1..c763f98a7f 100644 --- a/pageserver/src/bin/pageserver.rs +++ b/pageserver/src/bin/pageserver.rs @@ -240,6 +240,7 @@ impl CfgFileParams { } fn main() -> Result<()> { + zenith_metrics::set_common_metrics_prefix("pageserver"); let arg_matches = App::new("Zenith page server") .about("Materializes WAL stream to pages and serves them to the postgres") .arg( diff --git a/test_runner/fixtures/benchmark_fixture.py b/test_runner/fixtures/benchmark_fixture.py index 86ca78d000..cced6ca1dd 100644 --- a/test_runner/fixtures/benchmark_fixture.py +++ b/test_runner/fixtures/benchmark_fixture.py @@ -136,7 +136,8 @@ class ZenithBenchmarker: # The metric should be an integer, as it's a number of bytes. But in general # all prometheus metrics are floats. So to be pedantic, read it as a float # and round to integer. - matches = re.search(r'pageserver_disk_io_bytes{io_operation="write"} (\S+)', all_metrics) + matches = re.search(r'^pageserver_disk_io_bytes{io_operation="write"} (\S+)$', all_metrics, + re.MULTILINE) return int(round(float(matches.group(1)))) @contextmanager diff --git a/zenith_metrics/Cargo.toml b/zenith_metrics/Cargo.toml index 79c59b5774..062ebc1c9c 100644 --- a/zenith_metrics/Cargo.toml +++ b/zenith_metrics/Cargo.toml @@ -7,3 +7,4 @@ edition = "2018" prometheus = {version = "0.12", default_features=false} # removes protobuf dependency libc = "0.2" lazy_static = "1.4" +once_cell = "1.8.0" diff --git a/zenith_metrics/src/lib.rs b/zenith_metrics/src/lib.rs index 0d1a60e978..639ba396dc 100644 --- a/zenith_metrics/src/lib.rs +++ b/zenith_metrics/src/lib.rs @@ -3,6 +3,7 @@ //! Otherwise, we might not see all metrics registered via //! a default registry. use lazy_static::lazy_static; +use once_cell::race::OnceBox; pub use prometheus::{exponential_buckets, linear_buckets}; pub use prometheus::{register_histogram, Histogram}; pub use prometheus::{register_histogram_vec, HistogramVec}; @@ -24,9 +25,29 @@ pub fn gather() -> Vec { prometheus::gather() } +static COMMON_METRICS_PREFIX: OnceBox<&str> = OnceBox::new(); + +/// Sets a prefix which will be used for all common metrics, typically a service +/// name like 'pageserver'. Should be executed exactly once in the beginning of +/// any executable which uses common metrics. +pub fn set_common_metrics_prefix(prefix: &'static str) { + COMMON_METRICS_PREFIX.set(prefix.into()).unwrap(); +} + +/// Prepends a prefix to a common metric name so they are distinguished between +/// different services, see https://github.com/zenithdb/zenith/pull/681 +/// A call to set_common_metrics_prefix() is necessary prior to calling this. +pub fn new_common_metric_name(unprefixed_metric_name: &str) -> String { + format!( + "{}_{}", + COMMON_METRICS_PREFIX.get().unwrap(), + unprefixed_metric_name + ) +} + lazy_static! { static ref DISK_IO_BYTES: IntGaugeVec = register_int_gauge_vec!( - "pageserver_disk_io_bytes", + new_common_metric_name("disk_io_bytes"), "Bytes written and read from disk, grouped by the operation (read|write)", &["io_operation"] ) diff --git a/zenith_utils/src/http/endpoint.rs b/zenith_utils/src/http/endpoint.rs index 03802f61ff..3c5b53b77a 100644 --- a/zenith_utils/src/http/endpoint.rs +++ b/zenith_utils/src/http/endpoint.rs @@ -9,14 +9,14 @@ use routerify::ext::RequestExt; use routerify::RequestInfo; use routerify::{Middleware, Router, RouterBuilder, RouterService}; use std::net::TcpListener; -use zenith_metrics::{register_int_counter, IntCounter}; +use zenith_metrics::{new_common_metric_name, register_int_counter, IntCounter}; use zenith_metrics::{Encoder, TextEncoder}; use super::error::ApiError; lazy_static! { static ref SERVE_METRICS_COUNT: IntCounter = register_int_counter!( - "pageserver_serve_metrics_count", + new_common_metric_name("serve_metrics_count"), "Number of metric requests made" ) .expect("failed to define a metric");