From e41a5e6cc08d98e2d728246368ae50e8189c1df3 Mon Sep 17 00:00:00 2001 From: Jeffrey Dallatezza Date: Mon, 20 Jul 2026 12:21:32 -0700 Subject: [PATCH 1/2] Move some metrics helpers into the metrics crate --- crates/core/src/client/client_connection.rs | 2 +- crates/core/src/host/instance_env.rs | 2 +- .../src/host/wasm_common/module_host_actor.rs | 2 +- .../subscription/module_subscription_actor.rs | 2 +- crates/core/src/util/mod.rs | 2 - crates/core/src/util/prometheus_handle.rs | 54 ------------------- crates/metrics/src/lib.rs | 1 + 7 files changed, 5 insertions(+), 60 deletions(-) delete mode 100644 crates/core/src/util/prometheus_handle.rs diff --git a/crates/core/src/client/client_connection.rs b/crates/core/src/client/client_connection.rs index f33e25a8fc6..41f28df4190 100644 --- a/crates/core/src/client/client_connection.rs +++ b/crates/core/src/client/client_connection.rs @@ -13,7 +13,6 @@ use crate::error::DBError; use crate::host::module_host::{ClientConnectedError, ProcedureResultTarget}; use crate::host::{FunctionArgs, ModuleHost, NoSuchModule, ReducerCallError}; use crate::subscription::module_subscription_manager::BroadcastError; -use crate::util::prometheus_handle::IntGaugeExt; use crate::worker_metrics::{ record_client_rejection, ClientDisconnectCause, ClientDisconnectRecorder, ClientRejectCause, WORKER_METRICS, }; @@ -29,6 +28,7 @@ use spacetimedb_durability::{DurableOffset, TxOffset}; use spacetimedb_lib::identity::{AuthCtx, RequestId}; use spacetimedb_lib::metrics::ExecutionMetrics; use spacetimedb_lib::Identity; +use spacetimedb_metrics::utils::IntGaugeExt; use tokio::sync::mpsc::error::{SendError, TrySendError}; use tokio::sync::{mpsc, oneshot, watch}; use tokio::task::AbortHandle; diff --git a/crates/core/src/host/instance_env.rs b/crates/core/src/host/instance_env.rs index 982ab6dcbff..2319a97da9b 100644 --- a/crates/core/src/host/instance_env.rs +++ b/crates/core/src/host/instance_env.rs @@ -7,7 +7,6 @@ use crate::host::wasm_common::TimingSpan; use crate::replica_context::ReplicaContext; use crate::subscription::module_subscription_actor::{commit_and_broadcast_event, ModuleSubscriptions}; use crate::subscription::module_subscription_manager::{from_tx_offset, TransactionOffset}; -use crate::util::prometheus_handle::IntGaugeExt; use chrono::{DateTime, Utc}; use core::mem; use futures::TryFutureExt; @@ -20,6 +19,7 @@ use spacetimedb_datastore::locking_tx_datastore::state_view::StateView; use spacetimedb_datastore::locking_tx_datastore::{FuncCallType, IndexScanPointOrRange, MutTxId}; use spacetimedb_datastore::traits::IsolationLevel; use spacetimedb_lib::{http as st_http, ConnectionId, Identity, Timestamp}; +use spacetimedb_metrics::utils::IntGaugeExt; use spacetimedb_primitives::{ColId, ColList, IndexId, TableId}; use spacetimedb_sats::{ bsatn::{self, ToBsatn}, diff --git a/crates/core/src/host/wasm_common/module_host_actor.rs b/crates/core/src/host/wasm_common/module_host_actor.rs index 18fb6bd7e99..21a86248e69 100644 --- a/crates/core/src/host/wasm_common/module_host_actor.rs +++ b/crates/core/src/host/wasm_common/module_host_actor.rs @@ -26,7 +26,6 @@ use crate::replica_context::ReplicaContext; use crate::sql::execute::run_with_instance; use crate::subscription::module_subscription_actor::{commit_and_broadcast_event, CommitAndBroadcastEventSuccess}; use crate::subscription::module_subscription_manager::TransactionOffset; -use crate::util::prometheus_handle::{HistogramExt, TimerGuard}; use crate::worker_metrics::WORKER_METRICS; use anyhow::{anyhow, bail, ensure, Context}; use bytes::{Buf, Bytes}; @@ -46,6 +45,7 @@ use spacetimedb_lib::de::DeserializeSeed; use spacetimedb_lib::identity::AuthCtx; use spacetimedb_lib::metrics::ExecutionMetrics; use spacetimedb_lib::{bsatn, http as st_http, ConnectionId, Hash, ProductType, RawModuleDef, Timestamp}; +use spacetimedb_metrics::utils::{HistogramExt, TimerGuard}; use spacetimedb_primitives::{HttpHandlerId, ProcedureId, TableId, ViewFnPtr, ViewId}; use spacetimedb_sats::algebraic_type::fmt::fmt_algebraic_type; use spacetimedb_sats::{AlgebraicType, AlgebraicTypeRef, Deserialize, ProductValue, Typespace, WithTypespace}; diff --git a/crates/core/src/subscription/module_subscription_actor.rs b/crates/core/src/subscription/module_subscription_actor.rs index 21d20a2aefe..ed364c8bcc8 100644 --- a/crates/core/src/subscription/module_subscription_actor.rs +++ b/crates/core/src/subscription/module_subscription_actor.rs @@ -20,7 +20,6 @@ use crate::host::{self, ModuleHost}; use crate::subscription::query::is_subscribe_to_all_tables; use crate::subscription::row_list_builder_pool::{BsatnRowListBuilderPool, JsonRowListBuilderFakePool}; use crate::subscription::{collect_table_update, collect_table_update_for_view, execute_plans}; -use crate::util::prometheus_handle::IntGaugeExt; use crate::worker_metrics::WORKER_METRICS; use core::panic; use parking_lot::RwLock; @@ -41,6 +40,7 @@ use spacetimedb_lib::identity::RequestId; use spacetimedb_lib::metrics::ExecutionMetrics; use spacetimedb_lib::Identity; use spacetimedb_lib::{bsatn, identity::AuthCtx}; +use spacetimedb_metrics::utils::IntGaugeExt; use spacetimedb_physical_plan::plan::ProjectPlan; use spacetimedb_schema::def::RawModuleDefVersion; use spacetimedb_table::static_assert_size; diff --git a/crates/core/src/util/mod.rs b/crates/core/src/util/mod.rs index dafa83dea44..a0894163d51 100644 --- a/crates/core/src/util/mod.rs +++ b/crates/core/src/util/mod.rs @@ -4,8 +4,6 @@ use std::pin::pin; use tokio::sync::oneshot; use tracing::Span; -pub mod prometheus_handle; - pub mod adaptive_recv; pub mod jobs; pub mod notify_once; diff --git a/crates/core/src/util/prometheus_handle.rs b/crates/core/src/util/prometheus_handle.rs deleted file mode 100644 index e69ca06e5bf..00000000000 --- a/crates/core/src/util/prometheus_handle.rs +++ /dev/null @@ -1,54 +0,0 @@ -use std::time::Instant; - -use prometheus::{Histogram, IntGauge}; - -/// Decrements the inner [`IntGauge`] on drop. -pub struct GaugeInc { - gauge: IntGauge, -} -impl Drop for GaugeInc { - #[inline] - fn drop(&mut self) { - self.gauge.dec(); - } -} - -/// Increment the given [`IntGauge`], and decrement it when the returned value goes out of scope. -#[inline] -pub fn inc_scope(gauge: &IntGauge) -> GaugeInc { - gauge.inc(); - GaugeInc { gauge: gauge.clone() } -} - -pub trait IntGaugeExt { - fn inc_scope(&self) -> GaugeInc; -} - -impl IntGaugeExt for IntGauge { - fn inc_scope(&self) -> GaugeInc { - inc_scope(self) - } -} - -/// A scope guard for a timer, -/// the total duration of which is written to a Histogram metric on drop. -pub struct TimerGuard { - histogram: Histogram, - timer: Instant, -} - -impl Drop for TimerGuard { - fn drop(&mut self) { - self.histogram.observe(self.timer.elapsed().as_secs_f64()); - } -} - -pub trait HistogramExt { - fn with_timer(self, timer: Instant) -> TimerGuard; -} - -impl HistogramExt for Histogram { - fn with_timer(self, timer: Instant) -> TimerGuard { - TimerGuard { histogram: self, timer } - } -} diff --git a/crates/metrics/src/lib.rs b/crates/metrics/src/lib.rs index d67b57522c0..f50134f8ce5 100644 --- a/crates/metrics/src/lib.rs +++ b/crates/metrics/src/lib.rs @@ -1 +1,2 @@ pub mod typed_prometheus; +pub mod utils; From 87eb8764f2a5e353b31bfe1e706cace29b30dffa Mon Sep 17 00:00:00 2001 From: Jeffrey Dallatezza Date: Mon, 20 Jul 2026 12:21:55 -0700 Subject: [PATCH 2/2] Actually add it --- crates/metrics/src/utils.rs | 54 +++++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) create mode 100644 crates/metrics/src/utils.rs diff --git a/crates/metrics/src/utils.rs b/crates/metrics/src/utils.rs new file mode 100644 index 00000000000..e69ca06e5bf --- /dev/null +++ b/crates/metrics/src/utils.rs @@ -0,0 +1,54 @@ +use std::time::Instant; + +use prometheus::{Histogram, IntGauge}; + +/// Decrements the inner [`IntGauge`] on drop. +pub struct GaugeInc { + gauge: IntGauge, +} +impl Drop for GaugeInc { + #[inline] + fn drop(&mut self) { + self.gauge.dec(); + } +} + +/// Increment the given [`IntGauge`], and decrement it when the returned value goes out of scope. +#[inline] +pub fn inc_scope(gauge: &IntGauge) -> GaugeInc { + gauge.inc(); + GaugeInc { gauge: gauge.clone() } +} + +pub trait IntGaugeExt { + fn inc_scope(&self) -> GaugeInc; +} + +impl IntGaugeExt for IntGauge { + fn inc_scope(&self) -> GaugeInc { + inc_scope(self) + } +} + +/// A scope guard for a timer, +/// the total duration of which is written to a Histogram metric on drop. +pub struct TimerGuard { + histogram: Histogram, + timer: Instant, +} + +impl Drop for TimerGuard { + fn drop(&mut self) { + self.histogram.observe(self.timer.elapsed().as_secs_f64()); + } +} + +pub trait HistogramExt { + fn with_timer(self, timer: Instant) -> TimerGuard; +} + +impl HistogramExt for Histogram { + fn with_timer(self, timer: Instant) -> TimerGuard { + TimerGuard { histogram: self, timer } + } +}