diff --git a/pageserver/src/metrics.rs b/pageserver/src/metrics.rs index d8ebdbe30c..a5644eb7de 100644 --- a/pageserver/src/metrics.rs +++ b/pageserver/src/metrics.rs @@ -689,6 +689,46 @@ pub static LAYER_GET_VALUE_RECONSTRUCT_DATA_SPAWN_BLOCKING_QUEUE_DELAY: Lazy = Lazy::new(|| { + register_histogram_vec!( + "pageserver_layer_get_value_reconstruct_data_completion_time_seconds", + "Time a Layer::get_value_reconstruct_data call takes to complete", + &["result"], + vec![ + 0.000_005, + 0.000_010, + 0.000_025, + 0.000_050, + 0.000_100, + 0.000_250, + 0.000_500, + 0.001_000, + 0.002_500, + 0.005_000, + 0.010_000, + 0.025_000, + 0.050_000, + 0.100_000, + 0.250_000, + 0.500_000, + 1.000_000, + 2.000_000, + 5.000_000, + 10.000_000, + 25.000_000, + 50.000_000, + 100.000_000, + ] + ) + .expect("failed to define a metric") +}); + +pub static LAYER_GET_VALUE_RECONSTRUCT_DATA_COMPLETION_TIME_OK: Lazy = + Lazy::new(|| LAYER_GET_VALUE_RECONSTRUCT_DATA_COMPLETION_TIME.with_label_values(&["ok"])); + +pub static LAYER_GET_VALUE_RECONSTRUCT_DATA_COMPLETION_TIME_ERROR: Lazy = + Lazy::new(|| LAYER_GET_VALUE_RECONSTRUCT_DATA_COMPLETION_TIME.with_label_values(&["error"])); + // Metrics collected on WAL redo operations // // We collect the time spent in actual WAL redo ('redo'), and time waiting diff --git a/pageserver/src/tenant/storage_layer.rs b/pageserver/src/tenant/storage_layer.rs index c949ef8618..c71fbfec40 100644 --- a/pageserver/src/tenant/storage_layer.rs +++ b/pageserver/src/tenant/storage_layer.rs @@ -396,14 +396,22 @@ pub trait Layer: std::fmt::Debug + Send + Sync + 'static { ) -> Result<(ValueReconstructState, ValueReconstructResult)> { let span = tracing::info_span!("get_value_reconstruct_data_spawn_blocking"); let start = Instant::now(); - tokio::task::spawn_blocking(move || { + let res = tokio::task::spawn_blocking(move || { crate::metrics::LAYER_GET_VALUE_RECONSTRUCT_DATA_SPAWN_BLOCKING_QUEUE_DELAY .observe(start.elapsed().as_secs_f64()); let _enter = span.enter(); self.get_value_reconstruct_data_blocking(key, lsn_range, reconstruct_data, ctx) }) .await - .context("spawn_blocking")? + .context("spawn_blocking"); + let histo = match &res { + Ok(Ok(_)) => &crate::metrics::LAYER_GET_VALUE_RECONSTRUCT_DATA_COMPLETION_TIME_OK, + Ok(Err(_)) | Err(_) => { + &crate::metrics::LAYER_GET_VALUE_RECONSTRUCT_DATA_COMPLETION_TIME_ERROR + } + }; + histo.observe(start.elapsed().as_secs_f64()); + res? } /// A short ID string that uniquely identifies the given layer within a [`LayerMap`].