lib

Core libraries for Radroots
git clone https://radroots.dev/git/lib.git
Log | Files | Refs | README | LICENSE

commit 57bb7bfa11143c15644e9859e386223255c71963
parent 35c1c179234f92c3ecd16a933797c2c89264fd56
Author: triesap <tyson@radroots.org>
Date:   Fri, 29 Aug 2025 22:37:04 +0000

log: add `radroots-log` crate, update `radroots-net` with logging utils

Diffstat:
MCargo.lock | 12++++++++++++
MCargo.toml | 4+++-
Acrates/log/Cargo.toml | 14++++++++++++++
Acrates/log/src/error.rs | 11+++++++++++
Acrates/log/src/init.rs | 66++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Acrates/log/src/lib.rs | 24++++++++++++++++++++++++
Acrates/log/src/options.rs | 24++++++++++++++++++++++++
Mcrates/net-core/Cargo.toml | 4+++-
Mcrates/net-core/src/error.rs | 3++-
Mcrates/net-core/src/lib.rs | 12+++++++++---
Acrates/net-core/src/logging.rs | 2++
11 files changed, 170 insertions(+), 6 deletions(-)

diff --git a/Cargo.lock b/Cargo.lock @@ -1635,6 +1635,16 @@ dependencies = [ ] [[package]] +name = "radroots-log" +version = "0.1.0" +dependencies = [ + "thiserror 1.0.69", + "tracing", + "tracing-appender", + "tracing-subscriber", +] + +[[package]] name = "radroots-net" version = "0.1.0" dependencies = [ @@ -1645,9 +1655,11 @@ dependencies = [ name = "radroots-net-core" version = "0.1.0" dependencies = [ + "radroots-log", "serde", "thiserror 1.0.69", "tokio", + "tracing", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml @@ -18,6 +18,7 @@ radroots-events-indexed = { path = "crates/events-indexed", version = "0.1.0", d radroots-identity = { path = "crates/identity", version = "0.1.0", default-features = false } radroots-nostr = { path = "crates/nostr", version = "0.1.0", default-features = false } radroots-runtime = { path = "crates/runtime", version = "0.1.0", default-features = false } +radroots-log = { path = "crates/log", version = "0.1.0", default-features = false } radroots-net = { path = "crates/net", version = "0.1.0", default-features = false } radroots-net-core = { path = "crates/net-core", version = "0.1.0", default-features = false } radroots-trade = { path = "crates/trade", version = "0.1.0", default-features = false } @@ -46,8 +47,9 @@ thiserror = { version = "1" } tokio = { version = "1" } toml = { version = "0.8" } tracing = { version = "0.1" } -tracing-subscriber = { version = "0.3" } tracing-appender = { version = "0.2" } +tracing-log = { version = "0.2" } +tracing-subscriber = { version = "0.3" } typeshare = { version = "1" } url = { version = "2" } uuid = { version = "1.16.0" } diff --git a/crates/log/Cargo.toml b/crates/log/Cargo.toml @@ -0,0 +1,13 @@ +[package] +name = "radroots-log" +version.workspace = true +edition.workspace = true +authors = ["Radroots Authors"] +rust-version.workspace = true +license.workspace = true + +[dependencies] +thiserror = { workspace = true } +tracing = { workspace = true } +tracing-subscriber = { workspace = true, features = ["fmt", "env-filter"] } +tracing-appender = { workspace = true } +\ No newline at end of file diff --git a/crates/log/src/error.rs b/crates/log/src/error.rs @@ -0,0 +1,11 @@ +use thiserror::Error; + +#[derive(Debug, Error)] +pub enum Error { + #[error("{0}")] + Msg(String), + #[error("logging init failed: {0}")] + Init(&'static str), +} + +pub type Result<T> = core::result::Result<T, Error>; diff --git a/crates/log/src/init.rs b/crates/log/src/init.rs @@ -0,0 +1,66 @@ +use std::fs; +use std::sync::OnceLock; + +use tracing::{Level, info}; +use tracing_subscriber::prelude::*; +use tracing_subscriber::{EnvFilter, fmt}; + +use crate::options::LoggingOptions; +use crate::{Error, Result}; + +static GUARD: OnceLock<tracing_appender::non_blocking::WorkerGuard> = OnceLock::new(); +static INIT: OnceLock<()> = OnceLock::new(); + +pub fn init_logging(opts: LoggingOptions) -> Result<()> { + if INIT.get().is_some() { + return Ok(()); + } + + let writer = if let Some(dir) = &opts.dir { + fs::create_dir_all(dir).map_err(|_| Error::Init("mkdir"))?; + let file_appender = tracing_appender::rolling::daily(dir, &opts.file_name); + let (non_blocking, guard) = tracing_appender::non_blocking(file_appender); + let _ = GUARD.set(guard); + Some(non_blocking) + } else { + None + }; + + let env = EnvFilter::from_default_env().add_directive(Level::INFO.into()); + + let fmt_layer_file = writer.as_ref().map(|w| fmt::layer().with_writer(w.clone())); + let fmt_layer_stdout = if opts.also_stdout() { + Some(fmt::layer()) + } else { + None + }; + + let subscriber = tracing_subscriber::registry() + .with(env) + .with(fmt_layer_file) + .with(fmt_layer_stdout); + + match subscriber.try_init() { + Ok(()) => { + let _ = INIT.set(()); + info!( + "logging initialized (file: {}, stdout: {})", + opts.dir + .as_ref() + .map(|d| d.join(&opts.file_name).display().to_string()) + .unwrap_or_else(|| "<disabled>".into()), + opts.also_stdout() + ); + Ok(()) + } + Err(_) => Ok(()), + } +} + +pub fn init_stdout() -> Result<()> { + init_logging(LoggingOptions { + dir: None, + stdout: true, + ..Default::default() + }) +} diff --git a/crates/log/src/lib.rs b/crates/log/src/lib.rs @@ -0,0 +1,24 @@ +mod error; +mod init; +mod options; + +pub use error::{Error, Result}; +pub use init::{init_logging, init_stdout}; +pub use options::LoggingOptions; + +use tracing::{debug, error, info}; + +#[inline] +pub fn log_info<S: AsRef<str>>(msg: S) { + info!("{}", msg.as_ref()); +} + +#[inline] +pub fn log_error<S: AsRef<str>>(msg: S) { + error!("{}", msg.as_ref()); +} + +#[inline] +pub fn log_debug<S: AsRef<str>>(msg: S) { + debug!("{}", msg.as_ref()); +} diff --git a/crates/log/src/options.rs b/crates/log/src/options.rs @@ -0,0 +1,24 @@ +use std::path::PathBuf; + +#[derive(Debug, Clone)] +pub struct LoggingOptions { + pub dir: Option<PathBuf>, + pub file_name: String, + pub stdout: bool, +} + +impl LoggingOptions { + pub fn also_stdout(&self) -> bool { + self.stdout + } +} + +impl Default for LoggingOptions { + fn default() -> Self { + Self { + dir: None, + file_name: "radroots.log".into(), + stdout: true, + } + } +} diff --git a/crates/net-core/Cargo.toml b/crates/net-core/Cargo.toml @@ -9,9 +9,11 @@ license.workspace = true [features] default = ["std"] std = [] -rt = ["std", "dep:tokio"] +rt = ["dep:tokio"] [dependencies] +radroots-log = { workspace = true } serde = { workspace = true, features = ["derive"] } thiserror = { workspace = true } tokio = { workspace = true, optional = true, features = ["rt-multi-thread"] } +tracing = { workspace = true } diff --git a/crates/net-core/src/error.rs b/crates/net-core/src/error.rs @@ -1,3 +1,4 @@ +use alloc::string::String; use thiserror::Error; #[derive(Debug, Error)] @@ -5,7 +6,7 @@ pub enum Error { #[error("{0}")] Msg(String), - #[error("mutex lock poisoned!")] + #[error("mutex lock poisoned")] Poisoned, #[cfg(feature = "std")] diff --git a/crates/net-core/src/lib.rs b/crates/net-core/src/lib.rs @@ -1,8 +1,14 @@ #![cfg_attr(not(feature = "std"), no_std)] -pub mod builder; -pub mod config; +extern crate alloc; + pub mod error; pub mod net; -pub use net::{Net, NetHandle}; +#[cfg(feature = "std")] +pub mod logging; + +pub mod builder; +pub mod config; + +pub use net::{Net, NetHandle, NetInfo}; diff --git a/crates/net-core/src/logging.rs b/crates/net-core/src/logging.rs @@ -0,0 +1,2 @@ +#[cfg(feature = "std")] +pub use radroots_log::{LoggingOptions, init_logging, init_stdout};