diff --git a/database/Cargo.toml b/database/Cargo.toml index 8a827c7..e8da4f0 100644 --- a/database/Cargo.toml +++ b/database/Cargo.toml @@ -9,6 +9,7 @@ repository = "https://github.com/Cuprate/cuprate/tree/main/database" keywords = ["cuprate", "database"] [features] +# default = ["heed", "redb", "service", "tracing"] default = ["heed", "redb", "service"] # default = ["redb", "service"] # default = ["redb-memory", "service"] @@ -33,7 +34,6 @@ monero-serai = { workspace = true, features = ["std"] } paste = { workspace = true } page_size = { version = "0.6.0" } # Needed for database resizes, they must be a multiple of the OS page size. thiserror = { workspace = true } -tracing = { workspace = true } # `service` feature. crossbeam = { workspace = true, features = ["std"], optional = true } @@ -45,9 +45,10 @@ thread_local = { workspace = true } rayon = { workspace = true, optional = true } # Optional features. -heed = { version = "0.20.0", features = ["read-txn-no-tls"], optional = true } -redb = { version = "2.1.0", optional = true } -serde = { workspace = true, optional = true } +heed = { version = "0.20.0", features = ["read-txn-no-tls"], optional = true } +redb = { version = "2.1.0", optional = true } +serde = { workspace = true, optional = true } +tracing = { workspace = true, optional = true } [dev-dependencies] bytemuck = { version = "1.14.3", features = ["must_cast", "derive", "min_const_generics", "extern_crate_alloc"] } diff --git a/database/src/lib.rs b/database/src/lib.rs index f1d2b2e..cf433a3 100644 --- a/database/src/lib.rs +++ b/database/src/lib.rs @@ -58,6 +58,7 @@ //! //! `ConcreteEnv` invariants you can rely on: //! - It implements [`Env`] +//! - It implements [`Debug`] //! - Upon [`Drop::drop`], all database data will sync to disk //! //! Note that `ConcreteEnv` itself is not a clonable type, @@ -78,8 +79,9 @@ //! //! The default is `heed`. //! -//! `tracing` is always enabled and cannot be disabled via feature-flag. -//! +//! Logging with [`tracing`](https://docs.rs/tracing) +//! can be enabled with the `tracing` feature flag, +//! this is disabled by default. //! //! # Invariants when not using `service` //! `cuprate_database` can be used without the `service` feature enabled but @@ -274,6 +276,8 @@ pub mod resize; mod key; pub use key::Key; +mod macros; + mod storable; pub use storable::{Storable, StorableBytes, StorableVec}; diff --git a/database/src/macros.rs b/database/src/macros.rs new file mode 100644 index 0000000..1e29e95 --- /dev/null +++ b/database/src/macros.rs @@ -0,0 +1,155 @@ +//! General macros. + +//---------------------------------------------------------------------------------------------------- Logging +// The below macros/types/functions allow for conditional +// logging with `tracing` depending on if the feature flag +// is enabled or not. +// +// These macros (e.g. [`info2`]) are used instead of the tracing macro directly. +// #[tracing::instrument] will still need to be handled by us by using `#[cfg_attr]`. + +/// Dummy structure with methods that copy the ones on [`tracing::Span`]. +/// +/// This is used when "tracing" is disabled such that span functions: +/// ```rust,ignore +/// let span: DummySpan = info_span2!("span"); +/// let _guard = span.enter(); +/// ``` +/// will still work as this struct will just be returned, then +/// [`DummySpan::enter`] will be called instead, which is just a dummy method. +pub(crate) struct DummySpan; + +impl DummySpan { + /// Emulates [`tracing::Span::enter`]. + #[inline] + pub(crate) const fn enter(&self) -> &Self { + self + } +} + +/// Drop impl is needed to satisfy clippy. +impl Drop for DummySpan { + #[inline] + fn drop(&mut self) {} +} + +/// [`tracing::warn_span`]. +macro_rules! warn_span2 { + ($($token:tt)*) => {{ + cfg_if::cfg_if! { + if #[cfg(feature = "tracing")] { + tracing::warn_span!($($token)*) + } else { + $crate::macros::DummySpan + } + } + }}; +} +pub(crate) use warn_span2; + +/// [`tracing::warn`]. +macro_rules! warn2 { + ($($token:tt)*) => { + #[cfg(feature = "tracing")] + tracing::warn!($($token)*) + }; +} +pub(crate) use warn2; + +/// [`tracing::trace_span`]. +macro_rules! trace_span2 { + ($($token:tt)*) => {{ + cfg_if::cfg_if! { + if #[cfg(feature = "tracing")] { + tracing::trace_span!($($token)*) + } else { + $crate::macros::DummySpan + } + } + }}; +} +pub(crate) use trace_span2; + +/// [`tracing::trace`]. +macro_rules! trace2 { + ($($token:tt)*) => { + #[cfg(feature = "tracing")] + tracing::trace!($($token)*) + }; +} +pub(crate) use trace2; + +/// [`tracing::info_span`]. +macro_rules! info_span2 { + ($($token:tt)*) => {{ + cfg_if::cfg_if! { + if #[cfg(feature = "tracing")] { + tracing::info_span!($($token)*) + } else { + $crate::macros::DummySpan + } + } + }}; +} +pub(crate) use info_span2; + +/// [`tracing::info`]. +macro_rules! info2 { + ($($token:tt)*) => { + #[cfg(feature = "tracing")] + tracing::info!($($token)*) + }; +} +pub(crate) use info2; + +/// [`tracing::error_span`]. +macro_rules! error_span2 { + ($($token:tt)*) => {{ + cfg_if::cfg_if! { + if #[cfg(feature = "tracing")] { + tracing::error_span!($($token)*) + } else { + $crate::macros::DummySpan + } + } + }}; +} +pub(crate) use error_span2; + +/// [`tracing::error`]. +macro_rules! error2 { + ($($token:tt)*) => { + #[cfg(feature = "tracing")] + tracing::error!($($token)*) + }; +} +pub(crate) use error2; + +/// [`tracing::debug_span`]. +macro_rules! debug_span2 { + ($($token:tt)*) => {{ + cfg_if::cfg_if! { + if #[cfg(feature = "tracing")] { + tracing::debug_span!($($token)*) + } else { + $crate::macros::DummySpan + } + } + }}; +} +pub(crate) use debug_span2; + +/// [`tracing::debug`]. +macro_rules! debug2 { + ($($token:tt)*) => { + #[cfg(feature = "tracing")] + tracing::debug!($($token)*) + }; +} +pub(crate) use debug2; + +//---------------------------------------------------------------------------------------------------- Tests +#[cfg(test)] +mod test { + // use super::*; +}