diff --git a/README.md b/README.md index 1ae15479f..408cc564f 100644 --- a/README.md +++ b/README.md @@ -143,6 +143,12 @@ There are several examples, in the examples directory, that simulate real world use-cases. Try running them via the command-line, via `cargo run --release --example simple`. +## Logging + +If you want logging, enable the `logging` feature flag, and then set RUST\_LOG accordingly. +See the documentation for [env\_logger](https://docs.rs/env_logger/latest/env_logger/) for specifics. +We currently have very few logging statements, but this is useful for print-style debugging. + ## Release See the [release documentation](./RELEASE.md) for detailed information on how to release Firewood. diff --git a/firewood/Cargo.toml b/firewood/Cargo.toml index f2b077b30..04f1bb343 100644 --- a/firewood/Cargo.toml +++ b/firewood/Cargo.toml @@ -35,6 +35,11 @@ tokio = { version = "1.21.1", features = ["rt", "sync", "macros", "rt-multi-thre typed-builder = "0.18.0" bincode = "1.3.3" bitflags = "2.4.1" +env_logger = { version = "0.10.1", optional = true } +log = { version = "0.4.20", optional = true } + +[features] +logger = ["dep:env_logger", "log"] [dev-dependencies] criterion = {version = "0.5.1", features = ["async_tokio"]} diff --git a/firewood/src/db.rs b/firewood/src/db.rs index 57d3d9010..013f24c8c 100644 --- a/firewood/src/db.rs +++ b/firewood/src/db.rs @@ -465,6 +465,11 @@ impl Db { let _ = tokio::fs::remove_dir_all(db_path.as_ref()).await; } + #[cfg(feature = "logger")] + // initialize the logger, but ignore if this fails. This could fail because the calling + // library already initialized the logger or if you're opening a second database + let _ = env_logger::try_init(); + block_in_place(|| Db::new_internal(db_path, cfg.clone())) .map_err(|e| api::Error::InternalError(Box::new(e))) } diff --git a/firewood/src/lib.rs b/firewood/src/lib.rs index 8052d2b54..7fb1212b0 100644 --- a/firewood/src/lib.rs +++ b/firewood/src/lib.rs @@ -195,4 +195,5 @@ pub mod nibbles; // TODO: shale should not be pub, but there are integration test dependencies :( pub mod shale; +pub mod logger; pub mod v2; diff --git a/firewood/src/logger.rs b/firewood/src/logger.rs new file mode 100644 index 000000000..2f36a7369 --- /dev/null +++ b/firewood/src/logger.rs @@ -0,0 +1,26 @@ +// Copyright (C) 2023, Ava Labs, Inc. All rights reserved. +// See the file LICENSE.md for licensing terms. + +// Supports making the logging operations a true runtime no-op +// Since we're a library, we can't really use the logging level +// static shortcut + +#[cfg(feature = "logger")] +pub use log::{debug, error, info, trace, warn}; + +#[cfg(not(feature = "logger"))] +pub use noop_logger::{debug, error, info, trace, warn}; + +#[cfg(not(feature = "logger"))] +mod noop_logger { + #[macro_export] + macro_rules! noop { + ($(target: $a:expr,)? $b:tt) => {}; + } + + pub use noop as debug; + pub use noop as error; + pub use noop as info; + pub use noop as trace; + pub use noop as warn; +} diff --git a/firewood/src/merkle/node.rs b/firewood/src/merkle/node.rs index 0901906b2..8e736e7a5 100644 --- a/firewood/src/merkle/node.rs +++ b/firewood/src/merkle/node.rs @@ -1,6 +1,7 @@ // Copyright (C) 2023, Ava Labs, Inc. All rights reserved. // See the file LICENSE.md for licensing terms. +use crate::logger::trace; use crate::{ merkle::from_nibbles, shale::{disk_address::DiskAddress, CachedStore, ShaleError, ShaleStore, Storable}, @@ -360,7 +361,7 @@ mod type_id { use type_id::NodeTypeId; impl Storable for Node { - fn deserialize(mut offset: usize, mem: &T) -> Result { + fn deserialize(offset: usize, mem: &T) -> Result { let meta_raw = mem.get_view(offset, Meta::SIZE as u64) .ok_or(ShaleError::InvalidCacheView { @@ -368,7 +369,9 @@ impl Storable for Node { size: Meta::SIZE as u64, })?; - offset += Meta::SIZE; + trace!("[{mem:p}] Deserializing node at {offset}"); + + let offset = offset + Meta::SIZE; #[allow(clippy::indexing_slicing)] let attrs = NodeAttributes::from_bits_retain(meta_raw.as_deref()[TRIE_HASH_LEN]); @@ -458,6 +461,7 @@ impl Storable for Node { } fn serialize(&self, to: &mut [u8]) -> Result<(), ShaleError> { + trace!("[{self:p}] Serializing node"); let mut cur = Cursor::new(to); let mut attrs = match self.root_hash.get() { diff --git a/firewood/src/shale/compact.rs b/firewood/src/shale/compact.rs index 544f58103..9b0f4b148 100644 --- a/firewood/src/shale/compact.rs +++ b/firewood/src/shale/compact.rs @@ -13,6 +13,8 @@ use std::io::{Cursor, Write}; use std::num::NonZeroUsize; use std::sync::RwLock; +use crate::logger::trace; + #[derive(Debug)] pub struct CompactHeader { payload_size: u64, @@ -584,6 +586,8 @@ impl Sh #[allow(clippy::unwrap_used)] let addr = self.inner.write().unwrap().alloc(size)?; + trace!("{self:p} put_item at {addr} size {size}"); + #[allow(clippy::unwrap_used)] let obj = { let inner = self.inner.read().unwrap();