diff --git a/Cargo.lock b/Cargo.lock index 47cdf3d..3841820 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1526,9 +1526,21 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0" dependencies = [ "pin-project-lite", + "tracing-attributes", "tracing-core", ] +[[package]] +name = "tracing-attributes" +version = "0.1.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "395ae124c09f9e6918a2310af6038fba074bcf474ac352496d5910dd59a2226d" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "tracing-core" version = "0.1.33" diff --git a/Cargo.toml b/Cargo.toml index c7dbfd6..f75bc8b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -31,7 +31,7 @@ reqwest = { version = "0.12.10", default-features = false, features = ["http2", serde = { version = "1.0.216", default-features = false, features = ["derive"] } syslog-tracing = { version = "0.3.1", default-features = false } tokio = { version = "1.42.0", default-features = false, features = ["rt", "rt-multi-thread", "time", "sync"] } -tracing = { version = "0.1.41", default-features = false, features = ["std"] } +tracing = { version = "0.1.41", default-features = false, features = ["std", "attributes"] } tracing-subscriber = { version = "0.3.19", default-features = false, features = ["ansi", "fmt", "std"] } walkdir = { version = "2.5.0", default-features = false } diff --git a/src/config.rs b/src/config.rs index e830d28..ca060b5 100644 --- a/src/config.rs +++ b/src/config.rs @@ -138,9 +138,10 @@ impl<'de> Deserialize<'de> for AcmedConfig { } } -pub fn load>(config_dir: P) -> Result { +#[tracing::instrument(level = "trace", err(Debug))] +pub fn load + std::fmt::Debug>(config_dir: P) -> Result { let config_dir = config_dir.as_ref(); - tracing::debug!("loading config directory: {config_dir:?}"); + tracing::debug!("loading config directory"); let settings = Config::builder() .add_source( get_files(config_dir)? @@ -149,9 +150,9 @@ pub fn load>(config_dir: P) -> Result { .collect::>(), ) .build()?; - tracing::trace!("loaded config: {settings:?}"); + tracing::trace!(?settings, "loaded config"); let config: AcmedConfig = settings.try_deserialize().context("invalid setting")?; - tracing::debug!("computed config: {config:?}"); + tracing::debug!(?config, "computed config"); Ok(config) } @@ -169,11 +170,12 @@ fn get_files(config_dir: &Path) -> Result> { } } file_lst.sort(); - tracing::debug!("configuration files found: {file_lst:?}"); + tracing::debug!(files = ?file_lst, "configuration files found"); Ok(file_lst) } #[cfg(test)] +#[tracing::instrument(level = "trace", err(Debug))] fn load_str<'de, T: serde::de::Deserialize<'de>>(config_str: &str) -> Result { let settings = Config::builder() .add_source(File::from_str(config_str, config::FileFormat::Toml)) diff --git a/src/http.rs b/src/http.rs index 9934f43..e1685f5 100644 --- a/src/http.rs +++ b/src/http.rs @@ -21,7 +21,12 @@ pub struct HttpClient { } impl HttpClient { - pub async fn send>(&self, endpoint: S, request: Request) -> Result { + #[tracing::instrument(skip(self), level = "trace", err(Debug))] + pub async fn send + std::fmt::Debug>( + &self, + endpoint: S, + request: Request, + ) -> Result { let (tx, rx) = oneshot::channel(); let raw_req = RawRequest { request, @@ -29,11 +34,7 @@ impl HttpClient { tx, }; self.tx.send(raw_req)?; - let ret = rx.await?; - if let Err(ref e) = ret { - tracing::error!("http error: {e:#?}"); - } - Ok(ret?) + Ok(rx.await??) } } @@ -50,11 +51,12 @@ pub(super) struct HttpRoutine { } impl HttpRoutine { + #[tracing::instrument(skip_all, level = "trace")] pub(super) fn new(config: &AcmedConfig) -> Self { let (tx, rx) = mpsc::unbounded_channel(); let mut endpoints = HashMap::with_capacity(config.endpoint.len()); for (name, edp) in &config.endpoint { - tracing::debug!("loading endpoint: {name}"); + tracing::debug!(name, "loading endpoint"); let client = get_http_client(config.get_global_root_certs(), &edp.root_certificates); let endpoint = HttpEndpoint { client }; endpoints.insert(name.to_owned(), endpoint); @@ -68,21 +70,22 @@ impl HttpRoutine { } } + #[tracing::instrument(skip_all, level = "trace")] pub(super) async fn run(mut self) { tracing::trace!("starting the http routine"); while let Some(raw_req) = self.rx.recv().await { - tracing::debug!("new http request: {:?}", raw_req.request); + tracing::debug!(request = ?raw_req.request, "new http request"); match self.endpoints.get(&raw_req.endpoint) { Some(edp) => { let ret = edp.client.execute(raw_req.request).await; let _ = raw_req.tx.send(ret); } None => { - tracing::error!("{}: endpoint not found", raw_req.endpoint); + tracing::error!(endpoint = raw_req.endpoint, "endpoint not found"); } } } - tracing::warn!("the http routine has stopped"); + tracing::error!("the http routine has stopped"); } } @@ -92,17 +95,15 @@ macro_rules! add_root_cert { match get_cert_pem(cert_path) { Ok(cert) => { $builder = $builder.add_root_certificate(cert); - tracing::debug!("root certificate loaded: {}", cert_path.display()); + tracing::debug!(?cert_path, "root certificate loaded"); } - Err(e) => tracing::error!( - "{} unable to load root certificate: {e:#?}", - cert_path.display() - ), + Err(e) => tracing::error!(?cert_path, "{e:#?}",), } } }; } +#[tracing::instrument(level = "trace")] fn get_http_client(base_certs_opt: Option<&[PathBuf]>, end_certs: &[PathBuf]) -> Client { let useragent = format!( "{}/{} ({}) {}", diff --git a/src/main.rs b/src/main.rs index 8c1d00e..c39b9d9 100644 --- a/src/main.rs +++ b/src/main.rs @@ -5,7 +5,7 @@ mod log; use crate::config::AcmedConfig; use crate::http::HttpRoutine; -use anyhow::{Context, Result}; +use anyhow::Result; use clap::Parser; use daemonize::Daemonize; use std::fs::File; @@ -24,19 +24,18 @@ fn main() { // Initialize the logging system log::init(args.log_level, !args.log.log_stderr); - tracing::trace!("computed args: {args:?}"); + tracing::trace!(?args, "computed args"); // Load the configuration let cfg = match config::load(args.config.as_path()) { Ok(cfg) => cfg, - Err(e) => { - tracing::error!("unable to load configuration: {e:#}"); - std::process::exit(3); - } + Err(_) => std::process::exit(3), }; // Initialize the server (PID file and daemon) - init_server(args.foreground, args.pid.get_pid_file()); + if init_server(args.foreground, args.pid.get_pid_file()).is_err() { + std::process::exit(3); + } // Starting ACMEd tokio::runtime::Builder::new_multi_thread() @@ -58,14 +57,20 @@ async fn start(cnf: AcmedConfig) { }); // TODO: REMOVE ME + debug_remove_me(http_client).await; +} + +#[tracing::instrument(skip_all, level = "trace")] +async fn debug_remove_me(http_client: crate::http::HttpClient) { use reqwest::{Method, Request, Url}; + let rsp = http_client .send( "my-ca", - Request::new(Method::GET, Url::parse("https://example.org").unwrap()), + Request::new(Method::GET, Url::parse("https://example.invalid").unwrap()), ) .await; - tracing::debug!("{rsp:?}"); + tracing::debug!(response = ?rsp, "response received"); let rsp = http_client .send( "my-ca", @@ -75,33 +80,27 @@ async fn start(cnf: AcmedConfig) { ), ) .await; - tracing::debug!("{rsp:?}"); + tracing::debug!(response = ?rsp, "response received"); } -fn init_server(foreground: bool, pid_file: Option<&Path>) { +#[tracing::instrument(level = "trace", err(Debug))] +fn init_server(foreground: bool, pid_file: Option<&Path>) -> Result<()> { if !foreground { let mut daemonize = Daemonize::new(); if let Some(f) = pid_file { daemonize = daemonize.pid_file(f); } - if let Err(e) = daemonize.start() { - tracing::error!("{e:#}"); - std::process::exit(3); - } + daemonize.start()? } else if let Some(f) = pid_file { - if let Err(e) = write_pid_file(f) { - tracing::error!("{e:#}"); - std::process::exit(3); - } + write_pid_file(f)? } + Ok(()) } fn write_pid_file(pid_file: &Path) -> Result<()> { let data = format!("{}\n", process::id()).into_bytes(); - let mut file = File::create(pid_file).with_context(|| format!("{}", pid_file.display()))?; - file.write_all(&data) - .with_context(|| format!("{}", pid_file.display()))?; - file.sync_all() - .with_context(|| format!("{}", pid_file.display()))?; + let mut file = File::create(pid_file)?; + file.write_all(&data)?; + file.sync_all()?; Ok(()) }