diff --git a/Cargo.lock b/Cargo.lock index 9a14f838..cafae4f3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -131,14 +131,20 @@ dependencies = [ "log", ] +[[package]] +name = "ansi_term" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2" +dependencies = [ + "winapi", +] + [[package]] name = "anyhow" version = "1.0.56" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4361135be9122e0870de935d7c439aef945b9f9ddd4199a553b5270b49c82a27" -dependencies = [ - "backtrace", -] [[package]] name = "arraydeque" @@ -738,7 +744,7 @@ dependencies = [ "libc", "num-integer", "num-traits 0.2.14", - "time", + "time 0.1.43", "winapi", ] @@ -795,6 +801,33 @@ dependencies = [ "bitflags", ] +[[package]] +name = "color-eyre" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ebf286c900a6d5867aeff75cfee3192857bb7f24b547d4f0df2ed6baa812c90" +dependencies = [ + "backtrace", + "color-spantrace", + "eyre", + "indenter", + "once_cell", + "owo-colors", + "tracing-error", +] + +[[package]] +name = "color-spantrace" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ba75b3d9449ecdccb27ecbc479fdc0b87fa2dd43d2f8298f9bf0e59aacc8dce" +dependencies = [ + "once_cell", + "owo-colors", + "tracing-core", + "tracing-error", +] + [[package]] name = "combine" version = "4.6.3" @@ -1274,7 +1307,6 @@ checksum = "f2fb860ca6fafa5552fb6d0e816a69c8e49f0908bf524e30a90d97c85892d506" dependencies = [ "block-buffer 0.10.2", "crypto-common", - "subtle", ] [[package]] @@ -1324,7 +1356,7 @@ dependencies = [ "curve25519-dalek", "ed25519", "rand 0.7.3", - "sha2 0.9.9", + "sha2", "zeroize", ] @@ -1466,6 +1498,16 @@ version = "2.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "77f3309417938f28bf8228fcff79a4a37103981e3e186d2ccd19c74b38f4eb71" +[[package]] +name = "eyre" +version = "0.6.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c2b6b5a29c02cdc822728b7d7b8ae1bab3e3b05d44522770ddd49722eeac7eb" +dependencies = [ + "indenter", + "once_cell", +] + [[package]] name = "failure" version = "0.1.8" @@ -1847,7 +1889,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "51ab2f639c231793c5f6114bdb9bbe50a7dbbfcd7c7c6bd8475dec2d991e964f" dependencies = [ "digest 0.9.0", - "hmac 0.10.1", + "hmac", ] [[package]] @@ -1860,15 +1902,6 @@ dependencies = [ "digest 0.9.0", ] -[[package]] -name = "hmac" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" -dependencies = [ - "digest 0.10.3", -] - [[package]] name = "hostname" version = "0.3.1" @@ -1962,6 +1995,12 @@ dependencies = [ "syn", ] +[[package]] +name = "indenter" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce23b50ad8242c51a442f3ff322d56b02f08852c77e4c0b4d3fd684abc89c683" + [[package]] name = "indexmap" version = "1.8.0" @@ -2239,24 +2278,6 @@ dependencies = [ "vcpkg", ] -[[package]] -name = "libsystemd" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8144587c71c16756b1055d3dcb0c75cb605a10ecd6523cc33702d5f90902bf6d" -dependencies = [ - "hmac 0.12.1", - "libc", - "log", - "nix 0.23.1", - "nom 7.1.0", - "once_cell", - "serde 1.0.136", - "sha2 0.10.2", - "thiserror", - "uuid", -] - [[package]] name = "linked-hash-map" version = "0.3.0" @@ -2331,6 +2352,15 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ffbee8634e0d45d258acb448e7eaab3fce7a0a467395d4d9f228e3c1f01fb2e4" +[[package]] +name = "matchers" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558" +dependencies = [ + "regex-automata", +] + [[package]] name = "matches" version = "0.1.9" @@ -2754,6 +2784,15 @@ dependencies = [ "syn", ] +[[package]] +name = "num_threads" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2819ce041d2ee131036f4fc9d6ae7ae125a3a40e97ba64d04fe799ad9dabbb44" +dependencies = [ + "libc", +] + [[package]] name = "object" version = "0.27.1" @@ -3335,6 +3374,9 @@ name = "regex-automata" version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" +dependencies = [ + "regex-syntax", +] [[package]] name = "regex-syntax" @@ -3590,7 +3632,7 @@ dependencies = [ "num 0.3.1", "rand 0.8.5", "serde 1.0.136", - "sha2 0.9.9", + "sha2", "zbus", "zbus_macros", "zvariant", @@ -3839,14 +3881,12 @@ dependencies = [ ] [[package]] -name = "sha2" -version = "0.10.2" +name = "sharded-slab" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "55deaec60f81eefe3cce0dc50bda92d6d8e88f2a27df7c5033b42afeb1ed2676" +checksum = "900fba806f70c630b0a382d0d825e17a0f19fcd059a2ade1ff237bcddf446b31" dependencies = [ - "cfg-if 1.0.0", - "cpufeatures 0.2.1", - "digest 0.10.3", + "lazy_static", ] [[package]] @@ -4023,16 +4063,6 @@ dependencies = [ "winapi", ] -[[package]] -name = "systemd-journal-logger" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2b2b2ff370208ad472629786a66dc252933843755a1d620a54a8fdd0fccb31f" -dependencies = [ - "libsystemd", - "log", -] - [[package]] name = "tap" version = "1.0.1" @@ -4097,6 +4127,15 @@ dependencies = [ "syn", ] +[[package]] +name = "thread_local" +version = "1.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5516c27b78311c50bf42c071425c560ac799b11c30b31f87e3081965fe5e0180" +dependencies = [ + "once_cell", +] + [[package]] name = "time" version = "0.1.43" @@ -4107,6 +4146,17 @@ dependencies = [ "winapi", ] +[[package]] +name = "time" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2702e08a7a860f005826c6815dcac101b19b5eb330c27fe4a5928fec1d20ddd" +dependencies = [ + "itoa 1.0.1", + "libc", + "num_threads", +] + [[package]] name = "tiny-keccak" version = "2.0.2" @@ -4161,6 +4211,112 @@ dependencies = [ "serde 1.0.136", ] +[[package]] +name = "tracing" +version = "0.1.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d0ecdcb44a79f0fe9844f0c4f33a342cbcbb5117de8001e6ba0dc2351327d09" +dependencies = [ + "cfg-if 1.0.0", + "log", + "pin-project-lite", + "tracing-attributes", + "tracing-core", +] + +[[package]] +name = "tracing-appender" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09d48f71a791638519505cefafe162606f706c25592e4bde4d97600c0195312e" +dependencies = [ + "crossbeam-channel", + "time 0.3.9", + "tracing-subscriber", +] + +[[package]] +name = "tracing-attributes" +version = "0.1.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc6b8ad3567499f98a1db7a752b07a7c8c7c7c34c332ec00effb2b0027974b7c" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "tracing-core" +version = "0.1.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f54c8ca710e81886d498c2fd3331b56c93aa248d49de2222ad2742247c60072f" +dependencies = [ + "lazy_static", + "valuable", +] + +[[package]] +name = "tracing-error" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d686ec1c0f384b1277f097b2f279a2ecc11afe8c133c1aabf036a27cb4cd206e" +dependencies = [ + "tracing", + "tracing-subscriber", +] + +[[package]] +name = "tracing-journald" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba316a74e8fc3c3896a850dba2375928a9fa171b085ecddfc7c054d39970f3fd" +dependencies = [ + "libc", + "tracing-core", + "tracing-subscriber", +] + +[[package]] +name = "tracing-log" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78ddad33d2d10b1ed7eb9d1f518a5674713876e97e5bb9b7345a7984fbb4f922" +dependencies = [ + "lazy_static", + "log", + "tracing-core", +] + +[[package]] +name = "tracing-subscriber" +version = "0.3.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4bc28f93baff38037f64e6f43d34cfa1605f27a49c34e8a04c5e78b0babf2596" +dependencies = [ + "ansi_term", + "lazy_static", + "matchers", + "regex", + "sharded-slab", + "smallvec", + "thread_local", + "tracing", + "tracing-core", + "tracing-log", +] + +[[package]] +name = "tracing-wasm" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4575c663a174420fa2d78f4108ff68f65bf2fbb7dd89f33749b6e826b3626e07" +dependencies = [ + "tracing", + "tracing-subscriber", + "wasm-bindgen", +] + [[package]] name = "trust-dns-proto" version = "0.21.2" @@ -4340,13 +4496,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" [[package]] -name = "uuid" -version = "0.8.2" +name = "valuable" +version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc5cf98d8186244414c848017f0e2676b3fcb46807f6668a97dfe67359a3c4b7" -dependencies = [ - "serde 1.0.136", -] +checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" [[package]] name = "value-bag" @@ -4399,7 +4552,6 @@ name = "veilid-core" version = "0.1.0" dependencies = [ "android_logger", - "anyhow", "async-io", "async-lock", "async-std", @@ -4416,6 +4568,7 @@ dependencies = [ "chacha20", "chacha20poly1305", "chrono", + "color-eyre", "config 0.12.0", "console_error_panic_hook", "curve25519-dalek-ng", @@ -4441,7 +4594,6 @@ dependencies = [ "keyvaluedb-web", "lazy_static", "libc", - "log", "lru", "maplit", "ndk", @@ -4468,6 +4620,9 @@ dependencies = [ "socket2", "static_assertions", "thiserror", + "tracing", + "tracing-error", + "tracing-subscriber", "wasm-bindgen", "wasm-bindgen-futures", "wasm-bindgen-test", @@ -4487,17 +4642,17 @@ name = "veilid-flutter" version = "0.1.0" dependencies = [ "allo-isolate", - "anyhow", "async-std", "backtrace", "ffi-support", "futures", "jni", "lazy_static", - "log", "parking_lot 0.12.0", "serde 1.0.136", "serde_json", + "tracing", + "tracing-subscriber", "veilid-core", ] @@ -4505,6 +4660,7 @@ dependencies = [ name = "veilid-server" version = "0.1.0" dependencies = [ + "ansi_term", "async-std", "async-tungstenite 0.17.1", "bugsalot", @@ -4521,7 +4677,6 @@ dependencies = [ "flume", "futures", "lazy_static", - "log", "nix 0.23.1", "parking_lot 0.12.0", "rpassword 6.0.1", @@ -4531,8 +4686,10 @@ dependencies = [ "serial_test 0.6.0", "signal-hook", "signal-hook-async-std", - "simplelog", - "systemd-journal-logger", + "tracing", + "tracing-appender", + "tracing-journald", + "tracing-subscriber", "url", "veilid-core", "windows-service", @@ -4547,10 +4704,11 @@ dependencies = [ "futures-util", "js-sys", "lazy_static", - "log", "send_wrapper", "serde 1.0.136", "serde_json", + "tracing-subscriber", + "tracing-wasm", "veilid-core", "wasm-bindgen", "wasm-bindgen-futures", diff --git a/veilid-core/Cargo.toml b/veilid-core/Cargo.toml index 406332ea..48b285ac 100644 --- a/veilid-core/Cargo.toml +++ b/veilid-core/Cargo.toml @@ -15,12 +15,14 @@ ios_tests = [ "simplelog", "backtrace" ] tracking = [ "backtrace" ] [dependencies] +tracing = { version = "^0", features = ["log", "attributes"] } +tracing-subscriber = "^0" +tracing-error = "^0" +color-eyre = "^0" capnp = { version = "^0", default_features = false } rust-fsm = "^0" static_assertions = "^1" -log = "^0" cfg-if = "^1" -anyhow = "^1" thiserror = "^1" hex = "^0" generic-array = "^0" diff --git a/veilid-core/src/api_logger.rs b/veilid-core/src/api_logger.rs deleted file mode 100644 index 8cffe706..00000000 --- a/veilid-core/src/api_logger.rs +++ /dev/null @@ -1,150 +0,0 @@ -use crate::core_context::*; -use crate::veilid_api::*; -use crate::xx::*; -use log::{set_boxed_logger, set_max_level, Level, LevelFilter, Log, Metadata, Record}; -use once_cell::sync::OnceCell; - -cfg_if! { - if #[cfg(target_arch = "wasm32")] { - use send_wrapper::*; - - struct ApiLoggerInner { - level: LevelFilter, - filter_ignore: Cow<'static, [Cow<'static, str>]>, - update_callback: SendWrapper, - } - } else { - struct ApiLoggerInner { - level: LevelFilter, - filter_ignore: Cow<'static, [Cow<'static, str>]>, - update_callback: UpdateCallback, - } - } -} - -#[derive(Clone)] -pub struct ApiLogger { - inner: Arc>>, -} - -static API_LOGGER: OnceCell = OnceCell::new(); - -impl ApiLogger { - fn new_inner(level: LevelFilter, update_callback: UpdateCallback) -> ApiLoggerInner { - cfg_if! { - if #[cfg(target_arch = "wasm32")] { - ApiLoggerInner { - level, - filter_ignore: Default::default(), - update_callback: SendWrapper::new(update_callback), - } - } else { - ApiLoggerInner { - level, - filter_ignore: Default::default(), - update_callback, - } - } - } - } - - pub async fn init(log_level: LevelFilter, update_callback: UpdateCallback) { - set_max_level(log_level); - let api_logger = API_LOGGER.get_or_init(|| { - let api_logger = ApiLogger { - inner: Arc::new(Mutex::new(None)), - }; - set_boxed_logger(Box::new(api_logger.clone())).expect("failed to set api logger"); - api_logger - }); - let apilogger_inner = Some(Self::new_inner(log_level, update_callback)); - *api_logger.inner.lock() = apilogger_inner; - } - - pub async fn terminate() { - if let Some(api_logger) = API_LOGGER.get() { - let mut inner = api_logger.inner.lock(); - *inner = None; - - // Clear everything and we're done - set_max_level(LevelFilter::Off); - } - } - - pub fn change_log_level(log_level: LevelFilter) { - if let Some(api_logger) = API_LOGGER.get() { - if let Some(inner) = &mut *api_logger.inner.lock() { - set_max_level(log_level); - inner.level = log_level; - } - } - } - - pub fn add_filter_ignore_str(filter_ignore: &'static str) { - if let Some(api_logger) = API_LOGGER.get() { - if let Some(inner) = &mut *api_logger.inner.lock() { - let mut list = Vec::from(&*inner.filter_ignore); - list.push(Cow::Borrowed(filter_ignore)); - inner.filter_ignore = Cow::Owned(list); - } - } - } -} - -impl Log for ApiLogger { - fn enabled(&self, metadata: &Metadata<'_>) -> bool { - if let Some(inner) = &mut *self.inner.lock() { - return metadata.level() <= inner.level; - } - false - } - - fn log(&self, record: &Record<'_>) { - if let Some(inner) = &mut *self.inner.lock() { - // Skip filtered targets - let skip = match (record.target(), &*inner.filter_ignore) { - (path, ignore) if !ignore.is_empty() => { - // Check that the module path does not match any ignore filters - ignore.iter().any(|v| path.starts_with(&**v)) - } - _ => false, - }; - if skip { - return; - } - - let metadata = record.metadata(); - let level = metadata.level(); - if level <= inner.level { - let ll = VeilidLogLevel::from_log_level(level); - - let file = record.file().unwrap_or(""); - let loc = if level >= Level::Debug { - if let Some(line) = record.line() { - format!("[{}:{}] ", file, line) - } else { - format!("[{}:] ", file) - } - } else { - "".to_owned() - }; - let tgt = if record.target().is_empty() { - "".to_owned() - } else { - format!("{}: ", record.target()) - }; - - let s = format!("{}{}{}", tgt, loc, record.args()); - - (inner.update_callback)(VeilidUpdate::Log(VeilidStateLog { - log_level: ll, - message: s, - })) - } - } - } - - fn flush(&self) { - // always flushes - } -} diff --git a/veilid-core/src/api_tracing_layer.rs b/veilid-core/src/api_tracing_layer.rs new file mode 100644 index 00000000..daf42b9e --- /dev/null +++ b/veilid-core/src/api_tracing_layer.rs @@ -0,0 +1,310 @@ +use crate::core_context::*; +use crate::veilid_api::*; +use crate::xx::*; +use core::fmt::Write; +use once_cell::sync::OnceCell; +use tracing_subscriber::*; + +cfg_if! { + if #[cfg(target_arch = "wasm32")] { + use send_wrapper::*; + + struct ApiLoggerInner { + max_level: Option, + filter_ignore: Cow<'static, [Cow<'static, str>]>, + update_callback: SendWrapper, + } + } else { + struct ApiLoggerInner { + max_level: Option, + filter_ignore: Cow<'static, [Cow<'static, str>]>, + update_callback: UpdateCallback, + } + } +} + +#[derive(Clone)] +pub struct ApiTracingLayer { + inner: Arc>>, +} + +static API_LOGGER: OnceCell = OnceCell::new(); + +impl ApiTracingLayer { + fn new_inner( + max_level: Option, + update_callback: UpdateCallback, + ) -> ApiLoggerInner { + cfg_if! { + if #[cfg(target_arch = "wasm32")] { + ApiLoggerInner { + max_level, + filter_ignore: Default::default(), + update_callback: SendWrapper::new(update_callback), + } + } else { + ApiLoggerInner { + max_level, + filter_ignore: Default::default(), + update_callback, + } + } + } + } + + pub async fn init(max_level: Option, update_callback: UpdateCallback) { + let api_logger = API_LOGGER.get_or_init(|| ApiTracingLayer { + inner: Arc::new(Mutex::new(None)), + }); + let apilogger_inner = Some(Self::new_inner(max_level, update_callback)); + *api_logger.inner.lock() = apilogger_inner; + } + + pub async fn terminate() { + if let Some(api_logger) = API_LOGGER.get() { + let mut inner = api_logger.inner.lock(); + *inner = None; + } + } + + pub fn get() -> ApiTracingLayer { + API_LOGGER + .get_or_init(|| ApiTracingLayer { + inner: Arc::new(Mutex::new(None)), + }) + .clone() + } + + pub fn change_api_log_level(max_level: Option) { + if let Some(api_logger) = API_LOGGER.get() { + if let Some(inner) = &mut *api_logger.inner.lock() { + *inner = Self::new_inner(max_level, inner.update_callback.clone()); + } + } + } + + pub fn add_filter_ignore_str(filter_ignore: &'static str) { + if let Some(api_logger) = API_LOGGER.get() { + if let Some(inner) = &mut *api_logger.inner.lock() { + let mut list = Vec::from(&*inner.filter_ignore); + list.push(Cow::Borrowed(filter_ignore)); + inner.filter_ignore = Cow::Owned(list); + } + } + } +} + +fn display_current_thread_id() -> String { + cfg_if! { + if #[cfg(target_arch = "wasm32")] { + "".to_owned() + } else { + format!("({}:{:?})", + if let Some(n) = async_std::task::current().name() { + n.to_string() + } + else { + async_std::task::current().id().to_string() + }, + std::thread::current().id() + ) + } + } +} + +impl registry::LookupSpan<'a>> Layer for ApiTracingLayer { + fn enabled(&self, metadata: &tracing::Metadata<'_>, _: layer::Context<'_, S>) -> bool { + if let Some(inner) = &mut *self.inner.lock() { + // Skip things that are out of our level + if let Some(max_level) = inner.max_level { + if VeilidLogLevel::from_tracing_level(*metadata.level()) > max_level { + return false; + } + } else { + return false; + } + // Skip filtered targets + let skip = match (metadata.target(), &*inner.filter_ignore) { + (path, ignore) if !ignore.is_empty() => { + // Check that the module path does not match any ignore filters + ignore.iter().any(|v| path.starts_with(&**v)) + } + _ => false, + }; + !skip + } else { + false + } + } + + fn on_new_span( + &self, + attrs: &tracing::span::Attributes<'_>, + id: &tracing::Id, + ctx: layer::Context<'_, S>, + ) { + if let Some(_inner) = &mut *self.inner.lock() { + let mut new_debug_record = StringRecorder::new(); + attrs.record(&mut new_debug_record); + + if let Some(span_ref) = ctx.span(id) { + span_ref + .extensions_mut() + .insert::(new_debug_record); + } + } + } + + fn on_record( + &self, + id: &tracing::Id, + values: &tracing::span::Record<'_>, + ctx: layer::Context<'_, S>, + ) { + if let Some(_inner) = &mut *self.inner.lock() { + if let Some(span_ref) = ctx.span(id) { + if let Some(debug_record) = span_ref.extensions_mut().get_mut::() { + values.record(debug_record); + } + } + } + } + + fn on_event(&self, event: &tracing::Event<'_>, _ctx: layer::Context<'_, S>) { + if let Some(inner) = &mut *self.inner.lock() { + let mut recorder = StringRecorder::new(); + event.record(&mut recorder); + let meta = event.metadata(); + let level = meta.level(); + if let Some(max_level) = inner.max_level { + if VeilidLogLevel::from_tracing_level(*level) <= max_level { + let log_level = VeilidLogLevel::from_tracing_level(*level); + + let origin = meta + .file() + .and_then(|file| meta.line().map(|ln| format!("{}:{}", file, ln))) + .unwrap_or_default(); + + let message = format!("{}{} {}", origin, display_current_thread_id(), recorder); + + (inner.update_callback)(VeilidUpdate::Log(VeilidStateLog { + log_level, + message, + })) + } + } + } + } +} + +struct StringRecorder { + display: String, + is_following_args: bool, +} +impl StringRecorder { + fn new() -> Self { + StringRecorder { + display: String::new(), + is_following_args: false, + } + } +} + +impl tracing::field::Visit for StringRecorder { + fn record_debug(&mut self, field: &tracing::field::Field, value: &dyn core::fmt::Debug) { + if field.name() == "message" { + if !self.display.is_empty() { + self.display = format!("{:?}\n{}", value, self.display) + } else { + self.display = format!("{:?}", value) + } + } else { + if self.is_following_args { + // following args + writeln!(self.display).unwrap(); + } else { + // first arg + write!(self.display, " ").unwrap(); + self.is_following_args = true; + } + write!(self.display, "{} = {:?};", field.name(), value).unwrap(); + } + } +} + +impl core::fmt::Display for StringRecorder { + fn fmt(&self, mut f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + if !self.display.is_empty() { + write!(&mut f, " {}", self.display) + } else { + Ok(()) + } + } +} + +impl core::default::Default for StringRecorder { + fn default() -> Self { + StringRecorder::new() + } +} + +impl log::Log for ApiTracingLayer { + fn enabled(&self, metadata: &log::Metadata<'_>) -> bool { + if let Some(inner) = &mut *self.inner.lock() { + if let Some(max_level) = inner.max_level { + return VeilidLogLevel::from_log_level(metadata.level()) <= max_level; + } + } + false + } + + fn log(&self, record: &log::Record<'_>) { + if let Some(inner) = &mut *self.inner.lock() { + // Skip filtered targets + let skip = match (record.target(), &*inner.filter_ignore) { + (path, ignore) if !ignore.is_empty() => { + // Check that the module path does not match any ignore filters + ignore.iter().any(|v| path.starts_with(&**v)) + } + _ => false, + }; + if skip { + return; + } + + let metadata = record.metadata(); + let level = metadata.level(); + let log_level = VeilidLogLevel::from_log_level(level); + if let Some(max_level) = inner.max_level { + if log_level <= max_level { + let file = record.file().unwrap_or(""); + let loc = if level >= log::Level::Debug { + if let Some(line) = record.line() { + format!("[{}:{}] ", file, line) + } else { + format!("[{}:] ", file) + } + } else { + "".to_owned() + }; + let tgt = if record.target().is_empty() { + "".to_owned() + } else { + format!("{}: ", record.target()) + }; + + let message = format!("{}{}{}", tgt, loc, record.args()); + + (inner.update_callback)(VeilidUpdate::Log(VeilidStateLog { + log_level, + message, + })) + } + } + } + } + + fn flush(&self) { + // always flushes + } +} diff --git a/veilid-core/src/core_context.rs b/veilid-core/src/core_context.rs index 4eb17d34..43753a59 100644 --- a/veilid-core/src/core_context.rs +++ b/veilid-core/src/core_context.rs @@ -1,4 +1,4 @@ -use crate::api_logger::*; +use crate::api_tracing_layer::*; use crate::attachment_manager::*; use crate::dht::Crypto; use crate::intf::*; @@ -60,11 +60,15 @@ impl ServicesContext { } pub async fn startup(&mut self) -> Result<(), VeilidAPIError> { - let log_level: VeilidConfigLogLevel = self.config.get().log_level; - if log_level != VeilidConfigLogLevel::Off { - ApiLogger::init(log_level.to_level_filter(), self.update_callback.clone()).await; + let api_log_level: VeilidConfigLogLevel = self.config.get().api_log_level; + if api_log_level != VeilidConfigLogLevel::Off { + ApiTracingLayer::init( + api_log_level.to_veilid_log_level(), + self.update_callback.clone(), + ) + .await; for ig in crate::DEFAULT_LOG_IGNORE_LIST { - ApiLogger::add_filter_ignore_str(ig); + ApiTracingLayer::add_filter_ignore_str(ig); } info!("Veilid logging initialized"); } @@ -154,7 +158,7 @@ impl ServicesContext { info!("Veilid API shutdown complete"); // api logger terminate is idempotent - ApiLogger::terminate().await; + ApiTracingLayer::terminate().await; // send final shutdown update (self.update_callback)(VeilidUpdate::Shutdown); diff --git a/veilid-core/src/lib.rs b/veilid-core/src/lib.rs index 5eda1e27..e6f0ce79 100644 --- a/veilid-core/src/lib.rs +++ b/veilid-core/src/lib.rs @@ -4,7 +4,7 @@ #[macro_use] extern crate alloc; -mod api_logger; +mod api_tracing_layer; mod attachment_manager; mod callback_state_machine; mod core_context; @@ -21,6 +21,7 @@ mod veilid_rng; #[macro_use] pub mod xx; +pub use self::api_tracing_layer::ApiTracingLayer; pub use self::attachment_manager::AttachmentState; pub use self::core_context::{api_startup, api_startup_json, UpdateCallback}; pub use self::veilid_api::*; diff --git a/veilid-core/src/tests/common/test_veilid_config.rs b/veilid-core/src/tests/common/test_veilid_config.rs index 6972577e..75d5b56c 100644 --- a/veilid-core/src/tests/common/test_veilid_config.rs +++ b/veilid-core/src/tests/common/test_veilid_config.rs @@ -169,7 +169,7 @@ fn config_callback(key: String) -> ConfigCallbackReturn { match key.as_str() { "program_name" => Ok(Box::new(String::from("Veilid"))), "namespace" => Ok(Box::new(String::from(""))), - "log_level" => Ok(Box::new(VeilidConfigLogLevel::Off)), + "api_log_level" => Ok(Box::new(VeilidConfigLogLevel::Off)), "capabilities.protocol_udp" => Ok(Box::new(true)), "capabilities.protocol_connect_tcp" => Ok(Box::new(true)), "capabilities.protocol_accept_tcp" => Ok(Box::new(true)), @@ -291,7 +291,7 @@ pub async fn test_config() { let inner = vc.get(); assert_eq!(inner.program_name, String::from("Veilid")); assert_eq!(inner.namespace, String::from("")); - assert_eq!(inner.log_level, VeilidConfigLogLevel::Off); + assert_eq!(inner.api_log_level, VeilidConfigLogLevel::Off); assert_eq!(inner.capabilities.protocol_udp, true); assert_eq!(inner.capabilities.protocol_connect_tcp, true); assert_eq!(inner.capabilities.protocol_accept_tcp, true); diff --git a/veilid-core/src/veilid_api/mod.rs b/veilid-core/src/veilid_api/mod.rs index 75d25167..eaf30aed 100644 --- a/veilid-core/src/veilid_api/mod.rs +++ b/veilid-core/src/veilid_api/mod.rs @@ -1,7 +1,9 @@ #![allow(dead_code)] mod debug; +mod serialize_helpers; pub use debug::*; +pub use serialize_helpers::*; use crate::*; @@ -21,6 +23,7 @@ pub use network_manager::NetworkManager; pub use routing_table::RoutingTable; pub use rpc_processor::StatusAnswer; +use api_tracing_layer::*; use core::fmt; use core_context::{api_shutdown, VeilidCoreContext}; use enumset::*; @@ -146,7 +149,7 @@ macro_rules! parse_error { ///////////////////////////////////////////////////////////////////////////////////////////////////// -#[derive(Debug, Clone, Copy, Serialize, Deserialize)] +#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Copy, Serialize, Deserialize)] pub enum VeilidLogLevel { Error = 1, Warn, @@ -156,13 +159,22 @@ pub enum VeilidLogLevel { } impl VeilidLogLevel { + pub fn from_tracing_level(level: tracing::Level) -> VeilidLogLevel { + match level { + tracing::Level::ERROR => VeilidLogLevel::Error, + tracing::Level::WARN => VeilidLogLevel::Warn, + tracing::Level::INFO => VeilidLogLevel::Info, + tracing::Level::DEBUG => VeilidLogLevel::Debug, + tracing::Level::TRACE => VeilidLogLevel::Trace, + } + } pub fn from_log_level(level: log::Level) -> VeilidLogLevel { match level { - Level::Error => VeilidLogLevel::Error, - Level::Warn => VeilidLogLevel::Warn, - Level::Info => VeilidLogLevel::Info, - Level::Debug => VeilidLogLevel::Debug, - Level::Trace => VeilidLogLevel::Trace, + log::Level::Error => VeilidLogLevel::Error, + log::Level::Warn => VeilidLogLevel::Warn, + log::Level::Info => VeilidLogLevel::Info, + log::Level::Debug => VeilidLogLevel::Debug, + log::Level::Trace => VeilidLogLevel::Trace, } } } @@ -1804,15 +1816,8 @@ impl VeilidAPI { } // Change api logging level if it is enabled - pub async fn change_log_level(&self, log_level: VeilidConfigLogLevel) { - cfg_if! { - if #[cfg(target_arch = "wasm32")] { - set_max_level(log_level.to_level_filter()); - } else { - use api_logger::ApiLogger; - ApiLogger::change_log_level(log_level.to_level_filter()); - } - } + pub async fn change_api_log_level(&self, log_level: VeilidConfigLogLevel) { + ApiTracingLayer::change_api_log_level(log_level.to_veilid_log_level()); } //////////////////////////////////////////////////////////////// diff --git a/veilid-flutter/rust/src/dart_serialize.rs b/veilid-core/src/veilid_api/serialize_helpers.rs similarity index 56% rename from veilid-flutter/rust/src/dart_serialize.rs rename to veilid-core/src/veilid_api/serialize_helpers.rs index 1124b46e..71842d4a 100644 --- a/veilid-flutter/rust/src/dart_serialize.rs +++ b/veilid-core/src/veilid_api/serialize_helpers.rs @@ -1,9 +1,9 @@ -use serde::*; +use super::*; pub fn deserialize_json<'a, T: de::Deserialize<'a>>( arg: &'a str, -) -> Result { - serde_json::from_str(arg).map_err(|e| veilid_core::VeilidAPIError::ParseError { +) -> Result { + serde_json::from_str(arg).map_err(|e| VeilidAPIError::ParseError { message: e.to_string(), value: String::new(), }) @@ -11,9 +11,9 @@ pub fn deserialize_json<'a, T: de::Deserialize<'a>>( pub fn deserialize_opt_json( arg: Option, -) -> Result { - let arg = arg.ok_or_else(|| veilid_core::VeilidAPIError::ParseError { - message: "invalid null string passed to rust".to_owned(), +) -> Result { + let arg = arg.ok_or_else(|| VeilidAPIError::ParseError { + message: "invalid null string".to_owned(), value: String::new(), })?; deserialize_json(&arg) diff --git a/veilid-core/src/veilid_config.rs b/veilid-core/src/veilid_config.rs index b4329f83..f166d5ef 100644 --- a/veilid-core/src/veilid_config.rs +++ b/veilid-core/src/veilid_config.rs @@ -1,7 +1,5 @@ -use crate::dht::*; -use crate::intf; use crate::xx::*; - +use crate::*; use serde::*; //////////////////////////////////////////////////////////////////////////////////////////////// @@ -195,14 +193,24 @@ pub enum VeilidConfigLogLevel { } impl VeilidConfigLogLevel { - pub fn to_level_filter(&self) -> LevelFilter { + pub fn to_veilid_log_level(&self) -> Option { match self { - Self::Off => LevelFilter::Off, - Self::Error => LevelFilter::Error, - Self::Warn => LevelFilter::Warn, - Self::Info => LevelFilter::Info, - Self::Debug => LevelFilter::Debug, - Self::Trace => LevelFilter::Trace, + Self::Off => None, + Self::Error => Some(VeilidLogLevel::Error), + Self::Warn => Some(VeilidLogLevel::Warn), + Self::Info => Some(VeilidLogLevel::Info), + Self::Debug => Some(VeilidLogLevel::Debug), + Self::Trace => Some(VeilidLogLevel::Trace), + } + } + pub fn from_veilid_log_level(level: Option) -> Self { + match level { + None => Self::Off, + Some(VeilidLogLevel::Error) => Self::Error, + Some(VeilidLogLevel::Warn) => Self::Warn, + Some(VeilidLogLevel::Info) => Self::Info, + Some(VeilidLogLevel::Debug) => Self::Debug, + Some(VeilidLogLevel::Trace) => Self::Trace, } } } @@ -216,7 +224,7 @@ impl Default for VeilidConfigLogLevel { pub struct VeilidConfigInner { pub program_name: String, pub namespace: String, - pub log_level: VeilidConfigLogLevel, + pub api_log_level: VeilidConfigLogLevel, pub capabilities: VeilidConfigCapabilities, pub protected_store: VeilidConfigProtectedStore, pub table_store: VeilidConfigTableStore, @@ -272,7 +280,7 @@ impl VeilidConfig { let mut inner = self.inner.write(); get_config!(inner.program_name); get_config!(inner.namespace); - get_config!(inner.log_level); + get_config!(inner.api_log_level); get_config!(inner.capabilities.protocol_udp); get_config!(inner.capabilities.protocol_connect_tcp); get_config!(inner.capabilities.protocol_accept_tcp); @@ -552,7 +560,7 @@ impl VeilidConfig { // If we have a node id from storage, check it if node_id.valid && node_id_secret.valid { // Validate node id - if !validate_key(&node_id, &node_id_secret) { + if !dht::validate_key(&node_id, &node_id_secret) { return Err("node id secret and node id key don't match".to_owned()); } } diff --git a/veilid-core/src/xx/mod.rs b/veilid-core/src/xx/mod.rs index 95609b14..fcfc8c02 100644 --- a/veilid-core/src/xx/mod.rs +++ b/veilid-core/src/xx/mod.rs @@ -20,12 +20,12 @@ pub use futures_util::future::{select, Either}; pub use futures_util::select; pub use futures_util::stream::FuturesUnordered; pub use futures_util::{AsyncRead, AsyncWrite}; -pub use log::*; pub use log_thru::*; pub use owo_colors::OwoColorize; pub use parking_lot::*; pub use split_url::*; pub use static_assertions::*; +pub use tracing::*; pub type PinBox = Pin>; pub type PinBoxFuture = PinBox + 'static>; diff --git a/veilid-flutter/lib/veilid.dart b/veilid-flutter/lib/veilid.dart index 3789d32b..499c8aaa 100644 --- a/veilid-flutter/lib/veilid.dart +++ b/veilid-flutter/lib/veilid.dart @@ -745,7 +745,7 @@ class VeilidConfigCapabilities { class VeilidConfig { String programName; String namespace; - VeilidConfigLogLevel logLevel; + VeilidConfigLogLevel apiLogLevel; VeilidConfigCapabilities capabilities; VeilidConfigProtectedStore protectedStore; VeilidConfigTableStore tableStore; @@ -755,7 +755,7 @@ class VeilidConfig { VeilidConfig({ required this.programName, required this.namespace, - required this.logLevel, + required this.apiLogLevel, required this.capabilities, required this.protectedStore, required this.tableStore, @@ -767,7 +767,7 @@ class VeilidConfig { return { 'program_name': programName, 'namespace': namespace, - 'log_level': logLevel.json, + 'api_log_level': apiLogLevel.json, 'capabilities': capabilities.json, 'protected_store': protectedStore.json, 'table_store': tableStore.json, @@ -779,7 +779,7 @@ class VeilidConfig { VeilidConfig.fromJson(Map json) : programName = json['program_name'], namespace = json['namespace'], - logLevel = json['log_level'], + apiLogLevel = json['api_log_level'], capabilities = VeilidConfigCapabilities.fromJson(json['capabilities']), protectedStore = VeilidConfigProtectedStore.fromJson(json['protected_store']), @@ -797,7 +797,7 @@ abstract class VeilidUpdate { case "Log": { return VeilidUpdateLog( - veilidLogLevelFromJson(json["log_level"]), json["message"]); + veilidLogLevelFromJson(json["api_log_level"]), json["message"]); } case "Attachment": { @@ -1072,7 +1072,7 @@ abstract class Veilid { Stream startupVeilidCore(VeilidConfig config); Future getVeilidState(); - Future changeLogLevel(VeilidConfigLogLevel logLevel); + Future changeApiLogLevel(VeilidConfigLogLevel logLevel); Future shutdownVeilidCore(); Future debug(String command); String veilidVersionString(); diff --git a/veilid-flutter/lib/veilid_ffi.dart b/veilid-flutter/lib/veilid_ffi.dart index a37cb411..0e4c2acc 100644 --- a/veilid-flutter/lib/veilid_ffi.dart +++ b/veilid-flutter/lib/veilid_ffi.dart @@ -35,9 +35,9 @@ typedef _StartupVeilidCoreDart = void Function(int, Pointer); // fn get_veilid_state(port: i64) typedef _GetVeilidStateC = Void Function(Int64); typedef _GetVeilidStateDart = void Function(int); -// fn change_log_level(port: i64, log_level: FfiStr) -typedef _ChangeLogLevelC = Void Function(Int64, Pointer); -typedef _ChangeLogLevelDart = void Function(int, Pointer); +// fn change_api_log_level(port: i64, log_level: FfiStr) +typedef _ChangeApiLogLevelC = Void Function(Int64, Pointer); +typedef _ChangeApiLogLevelDart = void Function(int, Pointer); // fn debug(port: i64, log_level: FfiStr) typedef _DebugC = Void Function(Int64, Pointer); typedef _DebugDart = void Function(int, Pointer); @@ -243,7 +243,7 @@ class VeilidFFI implements Veilid { final _FreeStringDart _freeString; final _StartupVeilidCoreDart _startupVeilidCore; final _GetVeilidStateDart _getVeilidState; - final _ChangeLogLevelDart _changeLogLevel; + final _ChangeApiLogLevelDart _changeApiLogLevel; final _ShutdownVeilidCoreDart _shutdownVeilidCore; final _DebugDart _debug; final _VeilidVersionStringDart _veilidVersionString; @@ -259,9 +259,9 @@ class VeilidFFI implements Veilid { _getVeilidState = dylib.lookupFunction<_GetVeilidStateC, _GetVeilidStateDart>( 'get_veilid_state'), - _changeLogLevel = - dylib.lookupFunction<_ChangeLogLevelC, _ChangeLogLevelDart>( - 'change_log_level'), + _changeApiLogLevel = + dylib.lookupFunction<_ChangeApiLogLevelC, _ChangeApiLogLevelDart>( + 'change_api_log_level'), _shutdownVeilidCore = dylib.lookupFunction<_ShutdownVeilidCoreC, _ShutdownVeilidCoreDart>( 'shutdown_veilid_core'), @@ -299,11 +299,11 @@ class VeilidFFI implements Veilid { } @override - Future changeLogLevel(VeilidConfigLogLevel logLevel) async { + Future changeApiLogLevel(VeilidConfigLogLevel logLevel) async { var nativeLogLevel = logLevel.json.toNativeUtf8(); - final recvPort = ReceivePort("change_log_level"); + final recvPort = ReceivePort("change_api_log_level"); final sendPort = recvPort.sendPort; - _changeLogLevel(sendPort.nativePort, nativeLogLevel); + _changeApiLogLevel(sendPort.nativePort, nativeLogLevel); malloc.free(nativeLogLevel); return processFutureVoid(recvPort.first); } diff --git a/veilid-flutter/lib/veilid_js.dart b/veilid-flutter/lib/veilid_js.dart index 344bc9a9..fb490601 100644 --- a/veilid-flutter/lib/veilid_js.dart +++ b/veilid-flutter/lib/veilid_js.dart @@ -46,8 +46,8 @@ class VeilidJS implements Veilid { } @override - Future changeLogLevel(VeilidConfigLogLevel logLevel) { - return _wrapApiPromise(js_util.callMethod(wasm, "change_log_level", + Future changeApiLogLevel(VeilidConfigLogLevel logLevel) { + return _wrapApiPromise(js_util.callMethod(wasm, "change_api_log_level", [jsonEncode(logLevel.json, toEncodable: veilidApiToEncodable)])); } diff --git a/veilid-flutter/rust/Cargo.toml b/veilid-flutter/rust/Cargo.toml index 4aff68bf..d7b42161 100644 --- a/veilid-flutter/rust/Cargo.toml +++ b/veilid-flutter/rust/Cargo.toml @@ -8,8 +8,9 @@ crate-type = ["cdylib", "staticlib", "rlib"] [dependencies] veilid-core = { path="../../veilid-core" } +tracing = { version = "^0", features = ["log", "attributes"] } +tracing-subscriber = "^0" parking_lot = "^0" -log = "^0" backtrace = "^0" serde_json = "^1" serde = "^1" @@ -19,11 +20,13 @@ futures = "^0" # Linux, Windows, Mac, iOS, Android [target.'cfg(not(target_arch = "wasm32"))'.dependencies] async-std = { version = "^1", features = ["unstable"] } -anyhow = { version = "^1", features = ["backtrace"] } allo-isolate = "^0" ffi-support = "^0" lazy_static = "^1" +# Dependencies for WASM builds only +# [target.'cfg(target_arch = "wasm32")'.dependencies] + # Dependencies for Android builds only [target.'cfg(target_os = "android")'.dependencies] jni = "^0" diff --git a/veilid-flutter/rust/src/dart_ffi.rs b/veilid-flutter/rust/src/dart_ffi.rs index 39a0d965..cff8508e 100644 --- a/veilid-flutter/rust/src/dart_ffi.rs +++ b/veilid-flutter/rust/src/dart_ffi.rs @@ -1,13 +1,11 @@ use crate::dart_isolate_wrapper::*; -use crate::dart_serialize::*; - use allo_isolate::*; use async_std::sync::Mutex as AsyncMutex; use ffi_support::*; use lazy_static::*; -use log::*; use std::os::raw::c_char; use std::sync::Arc; +use tracing::*; // Globals @@ -71,7 +69,7 @@ pub extern "C" fn initialize_veilid_flutter(dart_post_c_object_ptr: ffi::DartPos } else { ("", 0) }; - log::error!("### Rust `panic!` hit at file '{}', line {}", file, line); + error!("### Rust `panic!` hit at file '{}', line {}", file, line); if let Some(s) = panic_info.payload().downcast_ref::<&str>() { error!("panic payload: {:?}", s); } else if let Some(s) = panic_info.payload().downcast_ref::() { @@ -81,7 +79,7 @@ pub extern "C" fn initialize_veilid_flutter(dart_post_c_object_ptr: ffi::DartPos } else { error!("no panic payload"); } - log::error!(" Complete stack trace:\n{:?}", backtrace::Backtrace::new()); + error!(" Complete stack trace:\n{:?}", backtrace::Backtrace::new()); // And stop the process, no recovery is going to be possible here std::process::abort(); @@ -143,12 +141,13 @@ pub extern "C" fn get_veilid_state(port: i64) { } #[no_mangle] -pub extern "C" fn change_log_level(port: i64, log_level: FfiStr) { +pub extern "C" fn change_api_log_level(port: i64, log_level: FfiStr) { let log_level = log_level.into_opt_string(); DartIsolateWrapper::new(port).spawn_result_json(async move { - let log_level: veilid_core::VeilidConfigLogLevel = deserialize_opt_json(log_level)?; + let log_level: veilid_core::VeilidConfigLogLevel = + veilid_core::deserialize_opt_json(log_level)?; let veilid_api = get_veilid_api().await?; - veilid_api.change_log_level(log_level).await; + veilid_api.change_api_log_level(log_level).await; APIRESULT_VOID }); } diff --git a/veilid-flutter/rust/src/dart_isolate_wrapper.rs b/veilid-flutter/rust/src/dart_isolate_wrapper.rs index 51277c94..b9aebd30 100644 --- a/veilid-flutter/rust/src/dart_isolate_wrapper.rs +++ b/veilid-flutter/rust/src/dart_isolate_wrapper.rs @@ -1,4 +1,3 @@ -use crate::dart_serialize::*; pub use allo_isolate::ffi::DartCObject; pub use allo_isolate::IntoDart; use allo_isolate::Isolate; @@ -71,7 +70,7 @@ impl DartIsolateWrapper { pub fn ok_json(self, value: T) -> bool { self.isolate.post(vec![ MESSAGE_OK_JSON.into_dart(), - serialize_json(value).into_dart(), + veilid_core::serialize_json(value).into_dart(), ]) } @@ -83,7 +82,7 @@ impl DartIsolateWrapper { pub fn err_json(self, error: E) -> bool { self.isolate.post(vec![ MESSAGE_ERR_JSON.into_dart(), - serialize_json(error).into_dart(), + veilid_core::serialize_json(error).into_dart(), ]) } } @@ -128,7 +127,7 @@ impl DartIsolateStream { if let Some(isolate) = &inner.isolate { isolate.post(vec![ MESSAGE_STREAM_ITEM_JSON.into_dart(), - serialize_json(value).into_dart(), + veilid_core::serialize_json(value).into_dart(), ]) } else { false @@ -149,7 +148,7 @@ impl DartIsolateStream { if let Some(isolate) = inner.isolate.take() { isolate.post(vec![ MESSAGE_STREAM_ABORT_JSON.into_dart(), - serialize_json(error).into_dart(), + veilid_core::serialize_json(error).into_dart(), ]) } else { false diff --git a/veilid-flutter/rust/src/lib.rs b/veilid-flutter/rust/src/lib.rs index 09131662..f67c8499 100644 --- a/veilid-flutter/rust/src/lib.rs +++ b/veilid-flutter/rust/src/lib.rs @@ -1,6 +1,5 @@ mod dart_ffi; mod dart_isolate_wrapper; -mod dart_serialize; #[cfg(target_os = "android")] use jni::{objects::JClass, objects::JObject, JNIEnv}; diff --git a/veilid-server/Cargo.toml b/veilid-server/Cargo.toml index ca221acd..d105c614 100644 --- a/veilid-server/Cargo.toml +++ b/veilid-server/Cargo.toml @@ -11,8 +11,9 @@ name = "veilid-server" path = "src/main.rs" [dependencies] -log = "^0" -simplelog = { version = "^0", features = ["test"] } +tracing = { version = "^0", features = ["log", "attributes"] } +tracing-subscriber = { version = "^0", features = ["env-filter"] } +tracing-appender = "^0" clap = "^3" async-std = { version = "^1", features = ["unstable"] } async-tungstenite = { version = "^0", features = ["async-std-runtime", "async-tls"] } @@ -37,6 +38,7 @@ rpassword = "^6" [target.'cfg(windows)'.dependencies] windows-service = "^0" +ansi_term = "^0" [target.'cfg(unix)'.dependencies] daemonize = "^0" @@ -45,7 +47,7 @@ signal-hook-async-std = "^0" nix = "^0" [target.'cfg(target_os = "linux")'.dependencies] -systemd-journal-logger = "^0" +tracing-journald = "^0" [dev-dependencies] serial_test = "^0" diff --git a/veilid-server/proto/veilid-client.capnp b/veilid-server/proto/veilid-client.capnp index 0b8544ae..5bf47382 100644 --- a/veilid-server/proto/veilid-client.capnp +++ b/veilid-server/proto/veilid-client.capnp @@ -1,55 +1,20 @@ @0xd29582d26b2fb073; -enum AttachmentState { - detached @0; - attaching @1; - attachedWeak @2; - attachedGood @3; - attachedStrong @4; - fullyAttached @5; - overAttached @6; - detaching @7; -} - -struct VeilidStateAttachment { - state @0 :AttachmentState; -} - -struct VeilidStateNetwork { - started @0 :Bool; - bpsDown @1 :UInt64; - bpsUp @2 :UInt64; -} - -struct VeilidUpdate { - union { - attachment @0 :VeilidStateAttachment; - network @1 :VeilidStateNetwork; - shutdown @2 :Void; - } -} - -struct VeilidState { - attachment @0 :VeilidStateAttachment; - network @1 :VeilidStateNetwork; -} - interface Registration {} interface VeilidServer { - register @0 (veilidClient: VeilidClient) -> (registration: Registration, state: VeilidState); + register @0 (veilidClient: VeilidClient) -> (registration: Registration, state: Text); debug @1 (what: Text) -> (output: Text); attach @2 (); detach @3 (); shutdown @4 (); - getState @5 () -> (state: VeilidState); + getState @5 () -> (state: Text); } interface VeilidClient { - update @0 (veilidUpdate: VeilidUpdate); - logMessage @1 (message: Text); + update @0 (veilidUpdate: Text); } \ No newline at end of file diff --git a/veilid-server/src/client_api.rs b/veilid-server/src/client_api.rs index 043c84d1..f26494a0 100644 --- a/veilid-server/src/client_api.rs +++ b/veilid-server/src/client_api.rs @@ -7,74 +7,18 @@ use failure::*; use futures::io::AsyncReadExt; use futures::FutureExt as FuturesFutureExt; use futures::StreamExt; -use log::*; use std::cell::RefCell; use std::collections::HashMap; use std::net::SocketAddr; use std::rc::Rc; +use tracing::*; use veilid_core::xx::Eventual; +use veilid_core::*; #[derive(Fail, Debug)] #[fail(display = "Client API error: {}", _0)] pub struct ClientAPIError(String); -fn convert_attachment_state(state: &veilid_core::AttachmentState) -> AttachmentState { - match state { - veilid_core::AttachmentState::Detached => AttachmentState::Detached, - veilid_core::AttachmentState::Attaching => AttachmentState::Attaching, - veilid_core::AttachmentState::AttachedWeak => AttachmentState::AttachedWeak, - veilid_core::AttachmentState::AttachedGood => AttachmentState::AttachedGood, - veilid_core::AttachmentState::AttachedStrong => AttachmentState::AttachedStrong, - veilid_core::AttachmentState::FullyAttached => AttachmentState::FullyAttached, - veilid_core::AttachmentState::OverAttached => AttachmentState::OverAttached, - veilid_core::AttachmentState::Detaching => AttachmentState::Detaching, - } -} - -fn convert_update( - update: &veilid_core::VeilidUpdate, - mut rpc_update: crate::veilid_client_capnp::veilid_update::Builder, -) { - match update { - veilid_core::VeilidUpdate::Log(veilid_core::VeilidStateLog { - log_level: _, - message: _, - }) => { - panic!("Should not be logging to api in server!"); - } - veilid_core::VeilidUpdate::Attachment(veilid_core::VeilidStateAttachment { state }) => { - let mut att = rpc_update.init_attachment(); - att.set_state(convert_attachment_state(state)); - } - veilid_core::VeilidUpdate::Network(veilid_core::VeilidStateNetwork { - started, - bps_down, - bps_up, - }) => { - let mut nb = rpc_update.init_network(); - nb.set_started(*started); - nb.set_bps_down(*bps_down); - nb.set_bps_up(*bps_up); - } - veilid_core::VeilidUpdate::Shutdown => { - rpc_update.set_shutdown(()); - } - } -} - -fn convert_state( - state: &veilid_core::VeilidState, - mut rpc_state: crate::veilid_client_capnp::veilid_state::Builder, -) { - let mut ab = rpc_state.reborrow().init_attachment(); - ab.set_state(convert_attachment_state(&state.attachment.state)); - - let mut nb = rpc_state.reborrow().init_network(); - nb.set_started(state.network.started); - nb.set_bps_down(state.network.bps_down); - nb.set_bps_up(state.network.bps_up); -} - // --- interface Registration --------------------------------- struct RegistrationHandle { @@ -166,11 +110,17 @@ impl veilid_server::Server for VeilidServerImpl { .get_state() .await .map_err(|e| ::capnp::Error::failed(format!("{:?}", e)))?; + let state = serialize_json(state); let mut res = results.get(); res.set_registration(registration); - let rpc_state = res.init_state(); - convert_state(&state, rpc_state); + let mut rpc_state = res.init_state( + state + .len() + .try_into() + .map_err(|e| ::capnp::Error::failed(format!("{:?}", e)))?, + ); + rpc_state.push_str(&state); Ok(()) }) @@ -256,9 +206,17 @@ impl veilid_server::Server for VeilidServerImpl { .get_state() .await .map_err(|e| ::capnp::Error::failed(format!("{:?}", e)))?; + let state = serialize_json(state); + + let res = results.get(); + let mut rpc_state = res.init_state( + state + .len() + .try_into() + .map_err(|e| ::capnp::Error::failed(format!("{:?}", e)))?, + ); + rpc_state.push_str(&state); - let rpc_state = results.get().init_state(); - convert_state(&state, rpc_state); Ok(()) }) } @@ -345,7 +303,7 @@ impl ClientApi { fn send_request_to_all_clients(self: Rc, request: F) where - F: Fn(u64, &mut RegistrationHandle) -> ::capnp::capability::RemotePromise, + F: Fn(u64, &mut RegistrationHandle) -> Option<::capnp::capability::RemotePromise>, T: capnp::traits::Pipelined + for<'a> capnp::traits::Owned<'a> + 'static + Unpin, { // Send status update to each registered client @@ -361,40 +319,44 @@ impl ClientApi { } registration.requests_in_flight += 1; - let request_promise = request(id, registration); - - let registration_map2 = registration_map1.clone(); - async_std::task::spawn_local(request_promise.promise.map(move |r| match r { - Ok(_) => { - if let Some(ref mut s) = - registration_map2.borrow_mut().registrations.get_mut(&id) - { - s.requests_in_flight -= 1; + if let Some(request_promise) = request(id, registration) { + let registration_map2 = registration_map1.clone(); + async_std::task::spawn_local(request_promise.promise.map(move |r| match r { + Ok(_) => { + if let Some(ref mut s) = + registration_map2.borrow_mut().registrations.get_mut(&id) + { + s.requests_in_flight -= 1; + } } - } - Err(e) => { - println!("Got error: {:?}. Dropping registation.", e); - registration_map2.borrow_mut().registrations.remove(&id); - } - })); + Err(e) => { + println!("Got error: {:?}. Dropping registation.", e); + registration_map2.borrow_mut().registrations.remove(&id); + } + })); + } } } pub fn handle_update(self: Rc, veilid_update: veilid_core::VeilidUpdate) { + // serialize update + let veilid_update = serialize_json(veilid_update); + // Pass other updates to clients self.send_request_to_all_clients(|_id, registration| { - let mut request = registration.client.update_request(); - let rpc_veilid_update = request.get().init_veilid_update(); - convert_update(&veilid_update, rpc_veilid_update); - request.send() - }); - } - - pub fn handle_client_log(self: Rc, message: String) { - self.send_request_to_all_clients(|_id, registration| { - let mut request = registration.client.log_message_request(); - request.get().set_message(&message); - request.send() + match veilid_update + .len() + .try_into() + .map_err(|e| ::capnp::Error::failed(format!("{:?}", e))) + { + Ok(len) => { + let mut request = registration.client.update_request(); + let mut rpc_veilid_update = request.get().init_veilid_update(len); + rpc_veilid_update.push_str(&veilid_update); + Some(request.send()) + } + Err(_) => None, + } }); } diff --git a/veilid-server/src/main.rs b/veilid-server/src/main.rs index 061f3b63..e7eca527 100644 --- a/veilid-server/src/main.rs +++ b/veilid-server/src/main.rs @@ -24,6 +24,9 @@ pub mod veilid_client_capnp { } fn main() -> Result<(), String> { + #[cfg(windows)] + let _ = ansi_term::enable_ansi_support(); + let (settings, matches) = cmdline::process_command_line()?; // --- Dump Config --- @@ -55,7 +58,7 @@ fn main() -> Result<(), String> { // Handle non-normal server modes if !matches!(server_mode, ServerMode::Normal) { // Init combined console/file logger - let logs = VeilidLogs::setup_normal_logs(settings.clone())?; + let logs = VeilidLogs::setup(settings.clone())?; // run the server to set the node id and quit return task::block_on(async { run_veilid_server(settings, logs, server_mode).await }) .map(|v| { @@ -80,7 +83,7 @@ fn main() -> Result<(), String> { } // Init combined console/file logger - let logs = VeilidLogs::setup_normal_logs(settings.clone())?; + let logs = VeilidLogs::setup(settings.clone())?; // --- Normal Startup --- ctrlc::set_handler(move || { diff --git a/veilid-server/src/server.rs b/veilid-server/src/server.rs index 6b123e23..d81a4128 100644 --- a/veilid-server/src/server.rs +++ b/veilid-server/src/server.rs @@ -3,10 +3,10 @@ use crate::settings::*; use crate::veilid_logs::*; use flume::{bounded, Receiver, Sender}; use lazy_static::*; -use log::*; use parking_lot::Mutex; use std::sync::Arc; use std::time::{Duration, Instant}; +use tracing::*; use veilid_core::xx::SingleShotEventual; #[derive(Copy, Clone, PartialEq, Eq)] @@ -91,41 +91,6 @@ pub async fn run_veilid_server_internal( } } }); - // Handle log messages on main thread for capnproto rpc - let client_log_receiver_jh = capi.clone().and_then(|capi| { - logs.client_log_channel - .clone() - .map(|mut client_log_channel| { - async_std::task::spawn_local(async move { - // Batch messages to either 16384 chars at once or every second to minimize packets - let rate = Duration::from_secs(1); - let mut start = Instant::now(); - let mut messages = String::new(); - loop { - let timeout_dur = - rate.checked_sub(start.elapsed()).unwrap_or(Duration::ZERO); - match async_std::future::timeout(timeout_dur, client_log_channel.recv()) - .await - { - Ok(Ok(message)) => { - messages += &message; - if messages.len() > 16384 { - capi.clone() - .handle_client_log(core::mem::take(&mut messages)); - start = Instant::now(); - } - } - Ok(Err(_)) => break, - Err(_) => { - capi.clone() - .handle_client_log(core::mem::take(&mut messages)); - start = Instant::now(); - } - } - } - }) - }) - }); // Auto-attach if desired let mut out = Ok(()); @@ -193,18 +158,8 @@ pub async fn run_veilid_server_internal( // Shut down Veilid API to release state change sender veilid_api.shutdown().await; - // Close the client api log channel if it is open to release client log sender - if let Some(client_log_channel_closer) = logs.client_log_channel_closer { - client_log_channel_closer.close(); - } - // Wait for update receiver to exit update_receiver_jh.await; - // Wait for client api log receiver to exit - if let Some(client_log_receiver_jh) = client_log_receiver_jh { - client_log_receiver_jh.await; - } - out } diff --git a/veilid-server/src/settings.rs b/veilid-server/src/settings.rs index 14b2962e..3c155934 100644 --- a/veilid-server/src/settings.rs +++ b/veilid-server/src/settings.rs @@ -1,7 +1,6 @@ #![allow(clippy::bool_assert_comparison)] use directories::*; -use log::*; use parking_lot::*; use serde_derive::*; @@ -34,7 +33,7 @@ logging: path: '' append: true level: 'info' - client: + api: enabled: false level: 'info' testing: @@ -226,13 +225,13 @@ impl serde::Serialize for LogLevel { } } -pub fn convert_loglevel(log_level: LogLevel) -> LevelFilter { +pub fn convert_loglevel(log_level: LogLevel) -> veilid_core::VeilidLogLevel { match log_level { - LogLevel::Error => LevelFilter::Error, - LogLevel::Warn => LevelFilter::Warn, - LogLevel::Info => LevelFilter::Info, - LogLevel::Debug => LevelFilter::Debug, - LogLevel::Trace => LevelFilter::Trace, + LogLevel::Error => veilid_core::VeilidLogLevel::Error, + LogLevel::Warn => veilid_core::VeilidLogLevel::Warn, + LogLevel::Info => veilid_core::VeilidLogLevel::Info, + LogLevel::Debug => veilid_core::VeilidLogLevel::Debug, + LogLevel::Trace => veilid_core::VeilidLogLevel::Trace, } } @@ -419,7 +418,7 @@ pub struct System { } #[derive(Debug, Deserialize, Serialize)] -pub struct Client { +pub struct Api { pub enabled: bool, pub level: LogLevel, } @@ -435,7 +434,7 @@ pub struct Logging { pub system: System, pub terminal: Terminal, pub file: File, - pub client: Client, + pub api: Api, } #[derive(Debug, Deserialize, Serialize)] @@ -862,7 +861,13 @@ impl Settings { } else { format!("subnode{}", inner.testing.subnode_index) })), - "log_level" => Ok(Box::new(veilid_core::VeilidConfigLogLevel::Off)), + "api_log_level" => Ok(Box::new(if inner.logging.api.enabled { + veilid_core::VeilidConfigLogLevel::from_veilid_log_level(Some( + convert_loglevel(inner.logging.api.level), + )) + } else { + veilid_core::VeilidConfigLogLevel::Off + })), "capabilities.protocol_udp" => Ok(Box::new(true)), "capabilities.protocol_connect_tcp" => Ok(Box::new(true)), "capabilities.protocol_accept_tcp" => Ok(Box::new(true)), @@ -1257,8 +1262,8 @@ mod tests { assert_eq!(s.logging.file.path, ""); assert_eq!(s.logging.file.append, true); assert_eq!(s.logging.file.level, LogLevel::Info); - assert_eq!(s.logging.client.enabled, false); - assert_eq!(s.logging.client.level, LogLevel::Info); + assert_eq!(s.logging.api.enabled, false); + assert_eq!(s.logging.api.level, LogLevel::Info); assert_eq!(s.testing.subnode_index, 0); assert_eq!( diff --git a/veilid-server/src/unix.rs b/veilid-server/src/unix.rs index d2ca5e85..03253ca2 100644 --- a/veilid-server/src/unix.rs +++ b/veilid-server/src/unix.rs @@ -93,7 +93,7 @@ pub fn run_daemon(settings: Settings, _matches: ArgMatches) -> Result<(), String }; // Init combined console/file logger - let logs = VeilidLogs::setup_normal_logs(settings.clone())?; + let logs = VeilidLogs::setup(settings.clone())?; // Daemonize daemon diff --git a/veilid-server/src/veilid_logs.rs b/veilid-server/src/veilid_logs.rs index eb994609..55434924 100644 --- a/veilid-server/src/veilid_logs.rs +++ b/veilid-server/src/veilid_logs.rs @@ -1,162 +1,127 @@ -use crate::log_safe_channel::*; use crate::settings::*; use cfg_if::*; -use log::*; -use simplelog::*; -use std::fs::OpenOptions; -use std::path::Path; +use std::path::*; +use tracing::*; +use tracing_appender::*; +use tracing_subscriber::prelude::*; +use tracing_subscriber::*; pub struct VeilidLogs { - pub client_log_channel: Option, - pub client_log_channel_closer: Option, + pub guard: Option, } -cfg_if! { - if #[cfg(target_os = "linux")] { - use systemd_journal_logger::JournalLog; - pub struct SystemLogger { - level_filter: LevelFilter, - config: Config, - journal_log: JournalLog, - } - - impl SystemLogger { - pub fn new(level_filter: LevelFilter, config: Config) -> Box { - Box::new(Self { - level_filter, - config, - journal_log: JournalLog::with_extra_fields(Vec::new()) - }) - } - - pub fn should_skip(record: &Record<'_>) -> bool { - // // If a module path and allowed list are available - // match (record.target(), &*config.filter_allow) { - // (path, allowed) if !allowed.is_empty() => { - // // Check that the module path matches at least one allow filter - // if !allowed.iter().any(|v| path.starts_with(&**v)) { - // // If not, skip any further writing - // return true; - // } - // } - // _ => {} - // } - - // If a module path and ignore list are available - match (record.target(), &veilid_core::DEFAULT_LOG_IGNORE_LIST) { - (path, ignore) if !ignore.is_empty() => { - // Check that the module path does not match any ignore filters - if ignore.iter().any(|v| path.starts_with(&**v)) { - // If not, skip any further writing - return true; - } - } - _ => {} - } - - false - } - - } - - impl Log for SystemLogger { - fn enabled(&self, metadata: &Metadata<'_>) -> bool { - metadata.level() <= self.level_filter - } - - fn log(&self, record: &Record<'_>) { - if self.enabled(record.metadata()) && ! Self::should_skip(record) { - self.journal_log.log(record); - } - } - - fn flush(&self) { - self.journal_log.flush(); - } - } - - impl SharedLogger for SystemLogger { - fn level(&self) -> LevelFilter { - self.level_filter - } - fn config(&self) -> Option<&Config> { - Some(&self.config) - } - fn as_log(self: Box) -> Box { - Box::new(*self) - } +fn logfilter, V: AsRef<[T]>>( + metadata: &Metadata, + max_level: veilid_core::VeilidLogLevel, + ignore_list: V, +) -> bool { + // Skip filtered targets + !match (metadata.target(), ignore_list.as_ref()) { + (path, ignore) if !ignore.is_empty() => { + // Check that the module path does not match any ignore filters + ignore.iter().any(|v| path.starts_with(v.as_ref())) } + _ => false, } } impl VeilidLogs { - pub fn setup_normal_logs(settings: Settings) -> Result { + pub fn setup(settings: Settings) -> Result { let settingsr = settings.read(); - // Set up loggers - let mut logs: Vec> = Vec::new(); - let mut client_log_channel: Option = None; - let mut client_log_channel_closer: Option = None; - let mut cb = ConfigBuilder::new(); + // Set up subscriber and layers + + let mut ignore_list = Vec::::new(); for ig in veilid_core::DEFAULT_LOG_IGNORE_LIST { - cb.add_filter_ignore_str(ig); + ignore_list.push(ig.to_owned()); } - if settingsr.logging.terminal.enabled { - logs.push(TermLogger::new( - convert_loglevel(settingsr.logging.terminal.level), - cb.build(), - TerminalMode::Mixed, - ColorChoice::Auto, - )) - } - if settingsr.logging.file.enabled { + let subscriber = Registry::default(); + + let subscriber = subscriber.with( + EnvFilter::builder() + .with_default_directive(level_filters::LevelFilter::INFO.into()) + .from_env_lossy(), + ); + + let subscriber = subscriber.with(if settingsr.logging.terminal.enabled { + let terminal_max_log_level = convert_loglevel(settingsr.logging.terminal.level); + Some( + fmt::Layer::new() + .compact() + .with_writer(std::io::stdout) + .with_filter(filter::FilterFn::new(move |metadata| { + logfilter(metadata, terminal_max_log_level, &ignore_list) + })), + ) + } else { + None + }); + + let mut guard = None; + let subscriber = subscriber.with(if settingsr.logging.file.enabled { + let file_max_log_level = convert_loglevel(settingsr.logging.file.level); + let log_path = Path::new(&settingsr.logging.file.path); + let full_path = std::env::current_dir() + .unwrap_or(PathBuf::from(MAIN_SEPARATOR.to_string())) + .join(log_path); + let log_parent = full_path + .parent() + .unwrap_or(Path::new(&MAIN_SEPARATOR.to_string())) + .canonicalize() + .map_err(|e| { + format!( + "File log path parent does not exist: {} ({})", + settingsr.logging.file.path, e + ) + })?; + let log_filename = full_path.file_name().ok_or(format!( + "File log filename not specified in path: {}", + settingsr.logging.file.path + ))?; - let logfile = if settingsr.logging.file.append { - OpenOptions::new() - .create(true) - .append(true) - .open(log_path) - .map_err(|e| format!("failed to open log file: {}", e))? - } else { - OpenOptions::new() - .create(true) - .truncate(true) - .write(true) - .open(log_path) - .map_err(|e| format!("failed to open log file: {}", e))? - }; - logs.push(WriteLogger::new( - convert_loglevel(settingsr.logging.file.level), - cb.build(), - logfile, - )) - } - if settingsr.logging.client.enabled { - let (clog, clogwriter, clogcloser) = LogSafeChannel::new(); - client_log_channel = Some(clog); - client_log_channel_closer = Some(clogcloser); - logs.push(WriteLogger::new( - convert_loglevel(settingsr.logging.client.level), - cb.build(), - clogwriter, - )) - } + let appender = tracing_appender::rolling::never(log_parent, Path::new(log_filename)); + let (non_blocking_appender, non_blocking_guard) = + tracing_appender::non_blocking(appender); + guard = Some(non_blocking_guard); + + Some( + fmt::Layer::new() + .compact() + .with_writer(non_blocking_appender) + .with_filter(filter::FilterFn::new(|metadata| { + logfilter(metadata, file_max_log_level, &ignore_list) + })), + ) + } else { + None + }); + + let subscriber = subscriber.with(if settingsr.logging.api.enabled { + // Get layer from veilid core, filtering is done by ApiTracingLayer automatically + Some(veilid_core::ApiTracingLayer::get()) + } else { + None + }); cfg_if! { if #[cfg(target_os = "linux")] { - if settingsr.logging.system.enabled { - logs.push(SystemLogger::new(convert_loglevel(settingsr.logging.system.level), cb.build())) - } + let subscriber = subscriber.with(if settingsr.logging.system.enabled { + let system_max_log_level = convert_loglevel(settingsr.logging.system.level); + Some(tracing_journald::layer().map_err(|e| format!("failed to set up journald logging: {}", e))?.with_filter(filter::FilterFn::new(|metadata| { + logfilter(metadata, system_max_log_level, &ignore_list) + }))) + } else { + None + }); } } - CombinedLogger::init(logs).map_err(|e| format!("failed to init logs: {}", e))?; + subscriber + .try_init() + .map_err(|e| format!("failed to initialize logging: {}", e))?; - Ok(VeilidLogs { - client_log_channel, - client_log_channel_closer, - }) + Ok(VeilidLogs { guard }) } } diff --git a/veilid-wasm/Cargo.toml b/veilid-wasm/Cargo.toml index e79b5487..8612b6be 100644 --- a/veilid-wasm/Cargo.toml +++ b/veilid-wasm/Cargo.toml @@ -12,7 +12,8 @@ crate-type = ["cdylib", "rlib"] wasm-bindgen = { version = "^0", features = ["serde-serialize"] } console_error_panic_hook = "^0" wee_alloc = "^0" -log = "^0" +tracing-wasm = "^0" +tracing-subscriber = "^0" veilid-core = { path = "../veilid-core" } cfg-if = "^1" wasm-bindgen-futures = "^0" diff --git a/veilid-wasm/src/lib.rs b/veilid-wasm/src/lib.rs index 63b1e608..7ce52537 100644 --- a/veilid-wasm/src/lib.rs +++ b/veilid-wasm/src/lib.rs @@ -139,11 +139,11 @@ pub fn get_veilid_state() -> Promise { } #[wasm_bindgen()] -pub fn change_log_level(log_level: String) -> Promise { +pub fn change_api_log_level(log_level: String) -> Promise { wrap_api_future(async move { let veilid_api = get_veilid_api()?; let log_level: veilid_core::VeilidConfigLogLevel = deserialize_json(&log_level)?; - veilid_api.change_log_level(log_level).await; + veilid_api.change_api_log_level(log_level).await; APIRESULT_UNDEFINED }) }