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:
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};