diff --git a/Cargo.lock b/Cargo.lock index a357573abb..782cffd7b8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -252,6 +252,17 @@ version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" +[[package]] +name = "chrono" +version = "0.4.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "80094f509cf8b5ae86a4966a39b3ff66cd7e2a3e594accec3743ff3fabeab5b2" +dependencies = [ + "num-integer", + "num-traits", + "time", +] + [[package]] name = "clap" version = "2.33.1" @@ -1138,6 +1149,15 @@ dependencies = [ "libc", ] +[[package]] +name = "matchers" +version = "0.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f099785f7595cc4b4553a174ce30dd7589ef93391ff414dbb67f62392b9e0ce1" +dependencies = [ + "regex-automata", +] + [[package]] name = "maybe-uninit" version = "2.0.0" @@ -1175,6 +1195,16 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0debeb9fcf88823ea64d64e4a815ab1643f33127d995978e099942ce38f25238" +[[package]] +name = "num-integer" +version = "0.1.42" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f6ea62e9d81a77cd3ee9a2a5b9b609447857f3d358704331e4ef39eb247fcba" +dependencies = [ + "autocfg 1.0.0", + "num-traits", +] + [[package]] name = "num-traits" version = "0.2.11" @@ -1669,6 +1699,16 @@ dependencies = [ "thread_local", ] +[[package]] +name = "regex-automata" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae1ded71d66a4a97f5e961fd0cb25a5f366a42a41570d16a763a69c092c26ae4" +dependencies = [ + "byteorder", + "regex-syntax", +] + [[package]] name = "regex-syntax" version = "0.6.18" @@ -1847,6 +1887,15 @@ dependencies = [ "opaque-debug", ] +[[package]] +name = "sharded-slab" +version = "0.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06d5a3f5166fb5b42a5439f2eee8b9de149e235961e3eb21c5808fc3ea17ff3e" +dependencies = [ + "lazy_static", +] + [[package]] name = "smallvec" version = "1.4.0" @@ -2038,6 +2087,16 @@ dependencies = [ "lazy_static", ] +[[package]] +name = "time" +version = "0.1.43" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca8a50ef2360fbd1eeb0ecd46795a87a19024eb4b53c5dc916ca1fd95fe62438" +dependencies = [ + "libc", + "winapi", +] + [[package]] name = "toml" version = "0.5.6" @@ -2047,6 +2106,78 @@ dependencies = [ "serde", ] +[[package]] +name = "tracing" +version = "0.1.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7c6b59d116d218cb2d990eb06b77b64043e0268ef7323aae63d8b30ae462923" +dependencies = [ + "cfg-if", + "tracing-attributes", + "tracing-core", +] + +[[package]] +name = "tracing-attributes" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "99bbad0de3fd923c9c3232ead88510b783e5a4d16a6154adffa3d53308de984c" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "tracing-core" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0aa83a9a47081cd522c09c81b31aec2c9273424976f922ad61c053b58350b715" +dependencies = [ + "lazy_static", +] + +[[package]] +name = "tracing-log" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e0f8c7178e13481ff6765bd169b33e8d554c5d2bbede5e32c356194be02b9b9" +dependencies = [ + "lazy_static", + "log", + "tracing-core", +] + +[[package]] +name = "tracing-serde" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6ccba2f8f16e0ed268fc765d9b7ff22e965e7185d32f8f1ec8294fe17d86e79" +dependencies = [ + "serde", + "tracing-core", +] + +[[package]] +name = "tracing-subscriber" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d53c40489aa69c9aed21ff483f26886ca8403df33bdc2d2f87c60c1617826d2" +dependencies = [ + "ansi_term", + "chrono", + "lazy_static", + "matchers", + "regex", + "serde", + "serde_json", + "sharded-slab", + "smallvec", + "tracing-core", + "tracing-log", + "tracing-serde", +] + [[package]] name = "traitobject" version = "0.1.0" @@ -2525,6 +2656,9 @@ name = "wiggle-test" version = "0.17.0" dependencies = [ "proptest", + "thiserror", + "tracing", + "tracing-subscriber", "wiggle", ] diff --git a/crates/wiggle/generate/src/config.rs b/crates/wiggle/generate/src/config.rs index 735cb92546..8769504780 100644 --- a/crates/wiggle/generate/src/config.rs +++ b/crates/wiggle/generate/src/config.rs @@ -321,6 +321,7 @@ impl Parse for ErrorConfField { } /// Configure logging statements in generated code +#[derive(Debug, Clone)] pub enum LoggingConf { Log { cfg_feature: Option }, Tracing, diff --git a/crates/wiggle/generate/src/funcs.rs b/crates/wiggle/generate/src/funcs.rs index 2c8cf2b350..33827b75b6 100644 --- a/crates/wiggle/generate/src/funcs.rs +++ b/crates/wiggle/generate/src/funcs.rs @@ -1,6 +1,7 @@ use proc_macro2::TokenStream; use quote::quote; +use crate::config::LoggingConf; use crate::error_transform::ErrorTransform; use crate::lifetimes::anon_lifetime; use crate::module_trait::passed_by_reference; @@ -11,6 +12,7 @@ pub fn define_func( func: &witx::InterfaceFunc, trait_name: TokenStream, errxform: &ErrorTransform, + logging: &LoggingConf, ) -> TokenStream { let funcname = func.name.as_str(); @@ -161,27 +163,12 @@ pub fn define_func( quote!() }; - let (placeholders, args): (Vec<_>, Vec<_>) = func - .params - .iter() - .map(|param| { - let name = names.func_param(¶m.name); - let fmt = if passed_by_reference(&*param.tref.type_()) { - "{:?}" - } else { - "{}" - }; - (format!("{}={}", name.to_string(), fmt), quote!(#name)) - }) - .unzip(); - let trace_fmt = format!("{}({})", ident.to_string(), placeholders.join(",")); + let log_args = logging.args(&func, names); + quote!(pub fn #ident(#abi_args) -> #abi_ret { #(#marshal_args)* #(#marshal_rets_pre)* - #[cfg(feature = "trace_log")] - { - log::trace!(#trace_fmt, #(#args),*); - } + #log_args let #trait_bindings = match #trait_name::#ident(ctx, #(#trait_args),*) { Ok(#trait_bindings) => { #trait_rets }, Err(e) => { #ret_err }, @@ -336,3 +323,51 @@ where _ => write_val_to_ptr, } } + +impl LoggingConf { + fn args(&self, func: &witx::InterfaceFunc, names: &Names) -> TokenStream { + match self { + Self::Log { cfg_feature } => { + let (placeholders, args): (Vec<_>, Vec<_>) = func + .params + .iter() + .map(|param| { + let name = names.func_param(¶m.name); + let fmt = if passed_by_reference(&*param.tref.type_()) { + "{:?}" + } else { + "{}" + }; + (format!("{}={}", name.to_string(), fmt), quote!(#name)) + }) + .unzip(); + let trace_fmt = format!( + "{}({})", + names.func(&func.name).to_string(), + placeholders.join(",") + ); + let trace_stmt = quote!(log::trace!(#trace_fmt, #(#args),*);); + if let Some(feature) = cfg_feature { + quote! { + #[cfg(feature = #feature)] + { + #trace_stmt + } + } + } else { + trace_stmt + } + } + Self::Tracing => { + let args = func.params.iter().map(|param| { + let name = names.func_param(¶m.name); + quote!( #name = #name ) + }); + let func_name = names.func(&func.name).to_string(); + quote! { + tracing::debug!(function = #func_name, #(#args),*, "marshalled arguments"); + } + } + } + } +} diff --git a/crates/wiggle/generate/src/lib.rs b/crates/wiggle/generate/src/lib.rs index bd6d5d9e40..459d22f472 100644 --- a/crates/wiggle/generate/src/lib.rs +++ b/crates/wiggle/generate/src/lib.rs @@ -11,14 +11,19 @@ use quote::quote; use lifetimes::anon_lifetime; -pub use config::Config; +pub use config::{Config, LoggingConf}; pub use error_transform::{ErrorTransform, UserErrorType}; pub use funcs::define_func; pub use module_trait::define_module_trait; pub use names::Names; pub use types::define_datatype; -pub fn generate(doc: &witx::Document, names: &Names, errs: &ErrorTransform) -> TokenStream { +pub fn generate( + doc: &witx::Document, + names: &Names, + errs: &ErrorTransform, + logging: &LoggingConf, +) -> TokenStream { // TODO at some point config should grow more ability to configure name // overrides. let rt = names.runtime_mod(); @@ -52,7 +57,7 @@ pub fn generate(doc: &witx::Document, names: &Names, errs: &ErrorTransform) -> T let trait_name = names.trait_name(&module.name); let fs = module .funcs() - .map(|f| define_func(&names, &f, quote!(#trait_name), &errs)); + .map(|f| define_func(&names, &f, quote!(#trait_name), &errs, logging)); let modtrait = define_module_trait(&names, &module, &errs); let ctx_type = names.ctx_type(); quote!( diff --git a/crates/wiggle/macro/src/lib.rs b/crates/wiggle/macro/src/lib.rs index ed4a3dc6f0..fced356f34 100644 --- a/crates/wiggle/macro/src/lib.rs +++ b/crates/wiggle/macro/src/lib.rs @@ -101,7 +101,7 @@ pub fn from_witx(args: TokenStream) -> TokenStream { let error_transform = wiggle_generate::ErrorTransform::new(&config.errors, &doc) .expect("validating error transform"); - let code = wiggle_generate::generate(&doc, &names, &error_transform); + let code = wiggle_generate::generate(&doc, &names, &error_transform, &config.logging); let metadata = if cfg!(feature = "wiggle_metadata") { wiggle_generate::generate_metadata(&doc, &names) } else { diff --git a/crates/wiggle/test-helpers/Cargo.toml b/crates/wiggle/test-helpers/Cargo.toml index da548e3950..71015052c7 100644 --- a/crates/wiggle/test-helpers/Cargo.toml +++ b/crates/wiggle/test-helpers/Cargo.toml @@ -14,5 +14,11 @@ include = ["src/**/*", "LICENSE"] proptest = "0.9" wiggle = { path = ".." } +[dev-dependencies] +thiserror = "1.0" +tracing = "0.1.14" +tracing-subscriber = "0.2.4" + + [badges] maintenance = { status = "actively-developed" }