diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml new file mode 100644 index 0000000..09299be --- /dev/null +++ b/.github/workflows/test.yaml @@ -0,0 +1,25 @@ +name: Test + +on: + pull_request: {} + +jobs: + lint: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: dtolnay/rust-toolchain@stable + with: + components: clippy + - uses: Swatinem/rust-cache@v2 + - run: cargo fmt --all -- --check + - run: cargo clippy --all-targets --all-features -- -D warnings + + test: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: dtolnay/rust-toolchain@stable + - uses: Swatinem/rust-cache@v2 + - uses: jetli/wasm-pack-action@v0.4.0 + - run: wasm-pack test --chrome --headless diff --git a/Cargo.lock b/Cargo.lock index fefbb52..d12c7a5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,6 +1,6 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. -version = 3 +version = 4 [[package]] name = "bumpalo" @@ -8,12 +8,31 @@ version = "3.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" +[[package]] +name = "cc" +version = "1.1.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67b9470d453346108f93a59222a9a1a5724db32d0a4727b7ab7ace4b4d822dc9" +dependencies = [ + "shlex", +] + [[package]] name = "cfg-if" version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +[[package]] +name = "console_error_panic_hook" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a06aeb73f470f66dcdbf7223caeebb85984942f22f1adb2a088cf9668146bbbc" +dependencies = [ + "cfg-if", + "wasm-bindgen", +] + [[package]] name = "crossbeam-deque" version = "0.8.5" @@ -45,6 +64,16 @@ version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" +[[package]] +name = "js-sys" +version = "0.3.76" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6717b6b5b077764fb5966237269cb3c64edddde4b14ce42647430a78ced9e7b7" +dependencies = [ + "once_cell", + "wasm-bindgen", +] + [[package]] name = "lazy_static" version = "1.5.0" @@ -57,23 +86,33 @@ version = "0.4.22" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" +[[package]] +name = "minicov" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "def6d99771d7c499c26ad4d40eb6645eafd3a1553b35fc26ea5a489a45e82d9a" +dependencies = [ + "cc", + "walkdir", +] + [[package]] name = "once_cell" -version = "1.19.0" +version = "1.20.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" +checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775" [[package]] name = "pin-project-lite" -version = "0.2.14" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02" +checksum = "915a1e146535de9163f3987b8944ed8cf49a18bb0056bcebcdcece385cece4ff" [[package]] name = "proc-macro2" -version = "1.0.86" +version = "1.0.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" +checksum = "37d3544b3f2748c54e147655edb5025752e2303145b5aefb3c3ea2c78b973bb0" dependencies = [ "unicode-ident", ] @@ -107,6 +146,21 @@ dependencies = [ "crossbeam-utils", ] +[[package]] +name = "same-file" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "scoped-tls" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1cf6437eb19a8f4a6cc0f7dca544973b0b78843adbfeb3683d1a94a0024a294" + [[package]] name = "sharded-slab" version = "0.1.7" @@ -116,11 +170,17 @@ dependencies = [ "lazy_static", ] +[[package]] +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + [[package]] name = "syn" -version = "2.0.77" +version = "2.0.90" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f35bcdf61fd8e7be6caf75f429fdca8beb3ed76584befb503b1569faee373ed" +checksum = "919d3b74a5dd0ccd15aeb8f93e7006bd9e14c295087c9896a110f490752bcf31" dependencies = [ "proc-macro2", "quote", @@ -203,11 +263,21 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" +[[package]] +name = "walkdir" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" +dependencies = [ + "same-file", + "winapi-util", +] + [[package]] name = "wasm-bindgen" -version = "0.2.93" +version = "0.2.99" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a82edfc16a6c469f5f44dc7b571814045d60404b55a0ee849f9bcfa2e63dd9b5" +checksum = "a474f6281d1d70c17ae7aa6a613c87fce69a127e2624002df63dcb39d6cf6396" dependencies = [ "cfg-if", "once_cell", @@ -216,24 +286,36 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.93" +version = "0.2.99" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9de396da306523044d3302746f1208fa71d7532227f15e347e2d93e4145dd77b" +checksum = "5f89bb38646b4f81674e8f5c3fb81b562be1fd936d84320f3264486418519c79" dependencies = [ "bumpalo", "log", - "once_cell", "proc-macro2", "quote", "syn", "wasm-bindgen-shared", ] +[[package]] +name = "wasm-bindgen-futures" +version = "0.4.49" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38176d9b44ea84e9184eff0bc34cc167ed044f816accfe5922e54d84cf48eca2" +dependencies = [ + "cfg-if", + "js-sys", + "once_cell", + "wasm-bindgen", + "web-sys", +] + [[package]] name = "wasm-bindgen-macro" -version = "0.2.93" +version = "0.2.99" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "585c4c91a46b072c92e908d99cb1dcdf95c5218eeb6f3bf1efa991ee7a68cccf" +checksum = "2cc6181fd9a7492eef6fef1f33961e3695e4579b9872a6f7c83aee556666d4fe" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -241,9 +323,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.93" +version = "0.2.99" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "afc340c74d9005395cf9dd098506f7f44e38f2b4a21c6aaacf9a105ea5e1e836" +checksum = "30d7a95b763d3c45903ed6c81f156801839e5ee968bb07e534c44df0fcd330c2" dependencies = [ "proc-macro2", "quote", @@ -254,17 +336,137 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.93" +version = "0.2.99" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c62a0a307cb4a311d3a07867860911ca130c3494e8c2719593806c08bc5d0484" +checksum = "943aab3fdaaa029a6e0271b35ea10b72b943135afe9bffca82384098ad0e06a6" + +[[package]] +name = "wasm-bindgen-test" +version = "0.3.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d381749acb0943d357dcbd8f0b100640679883fcdeeef04def49daf8d33a5426" +dependencies = [ + "console_error_panic_hook", + "js-sys", + "minicov", + "scoped-tls", + "wasm-bindgen", + "wasm-bindgen-futures", + "wasm-bindgen-test-macro", +] + +[[package]] +name = "wasm-bindgen-test-macro" +version = "0.3.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c97b2ef2c8d627381e51c071c2ab328eac606d3f69dd82bcbca20a9e389d95f0" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] [[package]] name = "wasm-tracing" -version = "0.2.1" +version = "1.0.0-alpha" dependencies = [ + "console_error_panic_hook", "rayon", "tracing", "tracing-log", "tracing-subscriber", "wasm-bindgen", + "wasm-bindgen-test", +] + +[[package]] +name = "web-sys" +version = "0.3.76" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04dd7223427d52553d3702c004d3b2fe07c148165faa56313cb00211e31c12bc" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "winapi-util" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" +dependencies = [ + "windows-sys", +] + +[[package]] +name = "windows-sys" +version = "0.59.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-targets" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_gnullvm", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", ] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" diff --git a/Cargo.toml b/Cargo.toml index 0aa928f..745cd72 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "wasm-tracing" -version = "0.2.1" +version = "1.0.0-alpha" authors = ["Daniel Gallups "] edition = "2021" categories = [ @@ -29,5 +29,10 @@ tracing-subscriber = { version = "0.3", features = [ ], default-features = false } wasm-bindgen = { version = "0.2" } + +[dev-dependencies] +wasm-bindgen-test = "0.3.0" +console_error_panic_hook = "0.1.7" + [features] mark-with-rayon-thread-index = ["rayon"] diff --git a/README.md b/README.md index 889c5fd..d8a6559 100644 --- a/README.md +++ b/README.md @@ -11,8 +11,8 @@ Leverage performance profiling with your browser tools with the [tracing crate]( [crates-badge]: https://img.shields.io/crates/v/wasm-tracing.svg [crates-url]: https://crates.io/crates/wasm-tracing -[docs-badge]: https://docs.rs/tracing-wasm/badge.svg -[docs-url]: https://docs.rs/tracing-wasm +[docs-badge]: https://docs.rs/wasm-tracing/badge.svg +[docs-url]: https://docs.rs/wasm-tracing [mit-badge]: https://img.shields.io/badge/license-MIT-blue.svg [mit-url]: LICENSE-MIT [apache-2-badge]: https://img.shields.io/badge/license-APACHE%202.0-blue.svg diff --git a/src/config/console.rs b/src/config/console.rs index d87f302..1bcdfb3 100644 --- a/src/config/console.rs +++ b/src/config/console.rs @@ -1,5 +1,16 @@ +/// Determines how the web console should behave +#[derive(Debug, PartialEq, Eq, Clone, Copy)] pub enum ConsoleConfig { + /// Do not record to console NoReporting, + /// Record to console without colorful text ReportWithoutConsoleColor, + /// Record to console with colorful text ReportWithConsoleColor, } + +impl ConsoleConfig { + pub fn reporting_enabled(&self) -> bool { + !matches!(self, ConsoleConfig::NoReporting) + } +} diff --git a/src/config/mod.rs b/src/config/mod.rs index a209298..95080a1 100644 --- a/src/config/mod.rs +++ b/src/config/mod.rs @@ -1,31 +1,40 @@ -use crate::ConsoleConfig; - -pub mod console; - -#[derive(Debug, PartialEq)] -pub struct WASMLayerConfig { +#[doc(hidden)] +mod console; +pub use console::*; + +#[deprecated(since = "1.0.0", note = "Rename WASMLayerConfig to WasmLayerConfig.")] +pub type WASMLayerConfig = WasmLayerConfig; + +#[doc = r#" +Configuration parameters for the [WasmLayer](crate::prelude::WasmLayer). +"#] +#[derive(Debug, PartialEq, Eq, Clone, Copy)] +pub struct WasmLayerConfig { pub report_logs_in_timings: bool, - pub report_logs_in_console: bool, - pub use_console_color: bool, + pub console: ConsoleConfig, + /// Maximum log level pub max_level: tracing::Level, + /// Show/hide fields of types pub show_fields: bool, + /// Show origin (line number, source) + pub show_origin: bool, } -impl Default for WASMLayerConfig { +impl Default for WasmLayerConfig { fn default() -> Self { - WASMLayerConfig { + WasmLayerConfig { report_logs_in_timings: true, - report_logs_in_console: true, - use_console_color: true, + console: ConsoleConfig::ReportWithConsoleColor, max_level: tracing::Level::TRACE, show_fields: true, + show_origin: true, } } } -impl WASMLayerConfig { - pub fn new() -> WASMLayerConfig { - WASMLayerConfig::default() +impl WasmLayerConfig { + pub fn new() -> WasmLayerConfig { + WasmLayerConfig::default() } /// Set whether events should appear in performance Timings @@ -42,21 +51,12 @@ impl WASMLayerConfig { /// Set if and how events should be displayed in the browser console pub fn set_console_config(&mut self, console_config: ConsoleConfig) -> &mut Self { - match console_config { - ConsoleConfig::NoReporting => { - self.report_logs_in_console = false; - self.use_console_color = false; - } - ConsoleConfig::ReportWithoutConsoleColor => { - self.report_logs_in_console = true; - self.use_console_color = false; - } - ConsoleConfig::ReportWithConsoleColor => { - self.report_logs_in_console = true; - self.use_console_color = true; - } - } + self.console = console_config; + self + } + pub fn set_show_origin(&mut self, show_origin: bool) -> &mut Self { + self.show_origin = show_origin; self } @@ -65,27 +65,31 @@ impl WASMLayerConfig { self.show_fields = show_fields; self } + + pub fn console_enabled(&self) -> bool { + self.console.reporting_enabled() + } } #[test] fn test_default_built_config() { - let config = WASMLayerConfig::new(); + let config = WasmLayerConfig::new(); assert_eq!( config, - WASMLayerConfig { + WasmLayerConfig { report_logs_in_timings: true, - report_logs_in_console: true, - use_console_color: true, + console: ConsoleConfig::ReportWithConsoleColor, max_level: tracing::Level::TRACE, show_fields: true, + show_origin: true } ) } #[test] fn test_set_report_logs_in_timings() { - let mut config = WASMLayerConfig::new(); + let mut config = WasmLayerConfig::new(); config.set_report_logs_in_timings(false); assert!(!config.report_logs_in_timings); @@ -93,34 +97,31 @@ fn test_set_report_logs_in_timings() { #[test] fn test_set_console_config_no_reporting() { - let mut config = WASMLayerConfig::new(); + let mut config = WasmLayerConfig::new(); config.set_console_config(ConsoleConfig::NoReporting); - assert!(!config.report_logs_in_console); - assert!(!config.use_console_color); + assert!(!config.console.reporting_enabled()); } #[test] fn test_set_console_config_without_color() { - let mut config = WASMLayerConfig::new(); + let mut config = WasmLayerConfig::new(); config.set_console_config(ConsoleConfig::ReportWithoutConsoleColor); - assert!(config.report_logs_in_console); - assert!(!config.use_console_color); + assert_eq!(config.console, ConsoleConfig::ReportWithoutConsoleColor); } #[test] fn test_set_console_config_with_color() { - let mut config = WASMLayerConfig::new(); + let mut config = WasmLayerConfig::new(); config.set_console_config(ConsoleConfig::ReportWithConsoleColor); - assert!(config.report_logs_in_console); - assert!(config.use_console_color); + assert_eq!(config.console, ConsoleConfig::ReportWithConsoleColor); } #[test] fn test_set_config_log_level_warn() { - let mut config = WASMLayerConfig::new(); + let mut config = WasmLayerConfig::new(); config.set_max_level(tracing::Level::WARN); assert_eq!(config.max_level, tracing::Level::WARN); diff --git a/src/layer.rs b/src/layer.rs index 34a681e..c03f94d 100644 --- a/src/layer.rs +++ b/src/layer.rs @@ -10,28 +10,31 @@ use crate::{ thread_display_suffix, }; +#[deprecated(since = "1.0.0", note = "Rename WASMLayer to WasmLayer.")] +pub type WASMLayer = WasmLayer; + /// Implements [tracing_subscriber::layer::Layer] which uses [wasm_bindgen] for marking and measuring with `window.performance` -pub struct WASMLayer { +pub struct WasmLayer { last_event_id: AtomicUsize, - config: WASMLayerConfig, + config: WasmLayerConfig, } -impl WASMLayer { - pub fn new(config: WASMLayerConfig) -> Self { - WASMLayer { +impl WasmLayer { + pub fn new(config: WasmLayerConfig) -> Self { + WasmLayer { last_event_id: AtomicUsize::new(0), config, } } } -impl core::default::Default for WASMLayer { +impl core::default::Default for WasmLayer { fn default() -> Self { - WASMLayer::new(WASMLayerConfig::default()) + WasmLayer::new(WasmLayerConfig::default()) } } -impl LookupSpan<'a>> Layer for WASMLayer { +impl LookupSpan<'a>> Layer for WasmLayer { fn enabled(&self, metadata: &tracing::Metadata<'_>, _: Context<'_, S>) -> bool { let level = metadata.level(); level <= &self.config.max_level @@ -66,96 +69,109 @@ impl LookupSpan<'a>> Layer for WASMLayer { // fn on_follows_from(&self, _span: &tracing::Id, _follows: &tracing::Id, ctx: Context<'_, S>) {} /// doc: Notifies this layer that an event has occurred. fn on_event(&self, event: &tracing::Event<'_>, ctx: Context<'_, S>) { - if self.config.report_logs_in_timings || self.config.report_logs_in_console { - let mut recorder = StringRecorder::new(self.config.show_fields); - event.record(&mut recorder); - #[cfg(feature = "tracing-log")] - let normalized_meta = event.normalized_metadata(); - #[cfg(feature = "tracing-log")] - let meta = normalized_meta.as_ref().unwrap_or_else(|| event.metadata()); - #[cfg(not(feature = "tracing-log"))] - let meta = event.metadata(); - let level = meta.level(); - if self.config.report_logs_in_console { - let origin = meta - .file() - .and_then(|file| meta.line().map(|ln| format!("{}:{}", file, ln))) - .unwrap_or_default(); - - let fields = ctx - .lookup_current() - .and_then(|span| { - span.extensions() - .get::() - .map(|span_recorder| { - span_recorder - .fields - .iter() - .map(|(key, value)| format!("\n\t{key}: {value}")) - .collect::>() - .join("") - }) - }) - .unwrap_or_default(); - - if self.config.use_console_color { - log4( - format!( - "%c{}%c {}{}%c{}{}", - level, - origin, - thread_display_suffix(), - recorder, - fields - ), - match *level { - tracing::Level::TRACE => "color: dodgerblue; background: #444", - tracing::Level::DEBUG => "color: lawngreen; background: #444", - tracing::Level::INFO => "color: whitesmoke; background: #444", - tracing::Level::WARN => "color: orange; background: #444", - tracing::Level::ERROR => "color: red; background: #444", - }, - "color: gray; font-style: italic", - "color: inherit", - ); - } else { - log1(format!( - "{} {}{} {}{}", - level, - origin, - thread_display_suffix(), - recorder, - fields - )); - } - } - if self.config.report_logs_in_timings { - let mark_name = format!( - "c{:x}", - self.last_event_id - .fetch_add(1, core::sync::atomic::Ordering::Relaxed) - ); - // mark and measure so you can see a little blip in the profile - mark(&mark_name); - let _ = measure( - format!( - "{} {}{} {}", - level, - meta.module_path().unwrap_or("..."), - thread_display_suffix(), - recorder, - ), - mark_name, - ); - } + if !self.config.report_logs_in_timings && !self.config.console.reporting_enabled() { + return; } + + let mut recorder = StringRecorder::new(self.config.show_fields); + event.record(&mut recorder); + #[cfg(feature = "tracing-log")] + let normalized_meta = event.normalized_metadata(); + #[cfg(feature = "tracing-log")] + let meta = normalized_meta.as_ref().unwrap_or_else(|| event.metadata()); + #[cfg(not(feature = "tracing-log"))] + let meta = event.metadata(); + let level = meta.level(); + + if self.config.report_logs_in_timings { + let mark_name = format!( + "c{:x}", + self.last_event_id + .fetch_add(1, core::sync::atomic::Ordering::Relaxed) + ); + // mark and measure so you can see a little blip in the profile + mark(&mark_name); + let _ = measure( + format!( + "{} {}{} {}", + level, + meta.module_path().unwrap_or("..."), + thread_display_suffix(), + recorder, + ), + mark_name, + ); + } + if let ConsoleConfig::NoReporting = self.config.console { + return; + } + let origin = if self.config.show_origin { + meta.file() + .and_then(|file| meta.line().map(|ln| format!("{}:{}", file, ln))) + .unwrap_or_default() + } else { + String::new() + }; + + let fields = ctx + .lookup_current() + .and_then(|span| { + span.extensions() + .get::() + .map(|span_recorder| { + span_recorder + .fields + .iter() + .map(|(key, value)| format!("\n\t{key}: {value}")) + .collect::>() + .join("") + }) + }) + .unwrap_or_default(); + + match self.config.console { + ConsoleConfig::ReportWithConsoleColor => log4( + format!( + "%c{}%c {}{}%c{}{}", + level, + origin, + thread_display_suffix(), + recorder, + fields + ), + match *level { + tracing::Level::TRACE => "color: dodgerblue; background: #444", + tracing::Level::DEBUG => "color: lawngreen; background: #444", + tracing::Level::INFO => "color: whitesmoke; background: #444", + tracing::Level::WARN => "color: orange; background: #444", + tracing::Level::ERROR => "color: red; background: #444", + }, + "color: gray; font-style: italic", + "color: inherit", + ), + ConsoleConfig::ReportWithoutConsoleColor => log1(format!( + "{} {}{} {}{}", + level, + origin, + thread_display_suffix(), + recorder, + fields + )), + ConsoleConfig::NoReporting => unreachable!(), + }; } - /// doc: Notifies this layer that a span with the given ID was entered. + /// Notifies this layer that a span with the given ID was entered. fn on_enter(&self, id: &tracing::Id, _ctx: Context<'_, S>) { - mark(&mark_name(id)); + if self.config.report_logs_in_timings { + mark(&mark_name(id)); + } } - /// doc: Notifies this layer that the span with the given ID was exited. + /// Notifies this layer that the span with the given ID was exited. fn on_exit(&self, id: &tracing::Id, ctx: Context<'_, S>) { + if !self.config.report_logs_in_timings { + return; + } + if let Some(span_ref) = ctx.span(id) { let meta = span_ref.metadata(); if let Some(debug_record) = span_ref.extensions().get::() { @@ -182,9 +198,14 @@ impl LookupSpan<'a>> Layer for WASMLayer { } } } - // /// doc: Notifies this layer that the span with the given ID has been closed. - // /// We can dispose of any data for the span we might have here... - // fn on_close(&self, _id: tracing::Id, ctx: Context<'_, S>) {} + + // //If [WasmLayerConfig::report_logs_in_timings] is true, the mark is discarded + // fn on_close(&self, id: tracing::Id, _ctx: Context<'_, S>) { + // if self.config.report_logs_in_timings { + // clear_mark(&mark_name(&id)) + // } + // } + // /// doc: Notifies this layer that a span ID has been cloned, and that the subscriber returned a different ID. // /// I'm not sure if I need to do something here... // fn on_id_change(&self, _old: &tracing::Id, _new: &tracing::Id, ctx: Context<'_, S>) {} diff --git a/src/lib.rs b/src/lib.rs index 2c4bba5..4f2dfa8 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,20 +1,52 @@ +#![doc = r#" +# `wasm-tracing` + +Leverages tracing to proilfe wasm performance via `console`. + +## Usage + +For the simplest out of the box set-up, you can simply set `wasm_tracing` as your default tracing Subscriber in wasm_bindgen(start) + +We have this declared in our `./src/lib.rs` + +```rust +use console_error_panic_hook; +use wasm_bindgen::prelude::*; + +#[wasm_bindgen(start)] +pub fn start() -> Result<(), JsValue> { + // print pretty errors in wasm https://github.com/rustwasm/console_error_panic_hook + // This is not needed for tracing_wasm to work, but it is a common tool for getting proper error line numbers for panics. + console_error_panic_hook::set_once(); + + wasm_tracing::set_as_global_default(); + + Ok(()) +} +``` +"#] + use tracing::dispatcher::SetGlobalDefaultError; use tracing_subscriber::layer::*; use tracing_subscriber::registry::*; use wasm_bindgen::prelude::*; -pub mod config; -pub mod layer; +#[doc(hidden)] +mod config; +pub use config::*; + +#[doc(hidden)] +mod layer; +pub use layer::*; pub(crate) mod recorder; pub mod prelude { pub use super::{ - config::{console::ConsoleConfig, WASMLayerConfig}, - layer::WASMLayer, + config::{ConsoleConfig, WasmLayerConfig}, + layer::WasmLayer, }; } -use prelude::*; #[wasm_bindgen] extern "C" { @@ -60,23 +92,62 @@ fn mark_name(id: &tracing::Id) -> String { ) } -/// Set the global default with [tracing::subscriber::set_global_default] +/// Set the global default recorder with [tracing::subscriber::set_global_default]. Panics if the [WasmLayer] cannot be constructed. pub fn set_as_global_default() { tracing::subscriber::set_global_default( - Registry::default().with(WASMLayer::new(WASMLayerConfig::default())), + Registry::default().with(WasmLayer::new(WasmLayerConfig::default())), ) .expect("default global"); } -/// Set the global default with [tracing::subscriber::set_global_default] +#[doc = r#" +Set WASM to be the default recorder with [tracing::subscriber::set_global_default]. + +## Example + +```rust +use console_error_panic_hook; +use wasm_bindgen::prelude::*; + +#[wasm_bindgen(start)] +pub fn start() -> Result<(), JsValue> { + console_error_panic_hook::set_once(); + + wasm_tracing::try_set_as_global_default(); + + Ok(()) +} +``` +"#] pub fn try_set_as_global_default() -> Result<(), SetGlobalDefaultError> { tracing::subscriber::set_global_default( - Registry::default().with(WASMLayer::new(WASMLayerConfig::default())), + Registry::default().with(WasmLayer::new(WasmLayerConfig::default())), ) } -/// Set the global default with [tracing::subscriber::set_global_default] -pub fn set_as_global_default_with_config(config: WASMLayerConfig) { - tracing::subscriber::set_global_default(Registry::default().with(WASMLayer::new(config))) +#[doc = r#" +Given a [`WasmLayerConfig`], set WASM to be the default recorder. + +## Example + +```rust +use console_error_panic_hook; +use wasm_bindgen::prelude::*; +use wasm_tracing::prelude::*; + +#[wasm_bindgen(start)] +pub fn start() -> Result<(), JsValue> { + console_error_panic_hook::set_once(); + + let config = WasmLayerConfig::new().set_report_logs_in_timings(true).set_max_level(Level::ERROR).to_owned(); + + wasm_tracing::set_as_global_default_with_config(config); + + Ok(()) +} +``` +"#] +pub fn set_as_global_default_with_config(config: WasmLayerConfig) { + tracing::subscriber::set_global_default(Registry::default().with(WasmLayer::new(config))) .expect("default global"); } diff --git a/tests/wasm.rs b/tests/wasm.rs new file mode 100644 index 0000000..2f07436 --- /dev/null +++ b/tests/wasm.rs @@ -0,0 +1,8 @@ +use wasm_bindgen_test::*; + +wasm_bindgen_test_configure!(run_in_browser); + +#[wasm_bindgen_test] +pub fn test() { + wasm_tracing::set_as_global_default(); +}