|
18 | 18 | //! ```
|
19 | 19 | //!
|
20 | 20 | //! # Log Levels
|
21 |
| -//! |
| 21 | +//! |
22 | 22 | //! Rust's log levels map to the browser's console log in the following way.
|
23 |
| -//! |
| 23 | +//! |
24 | 24 | //! | Rust | Web Console |
|
25 | 25 | //! |------------|-------------------|
|
26 | 26 | //! | `trace!()` | `console.debug()` |
|
27 | 27 | //! | `debug!()` | `console.log()` |
|
28 | 28 | //! | `info!()` | `console.info()` |
|
29 | 29 | //! | `warn!()` | `console.warn()` |
|
30 | 30 | //! | `error!()` | `console.error()` |
|
31 |
| -//! |
| 31 | +//! |
32 | 32 | //! # Getting Fancy
|
33 | 33 | //!
|
34 | 34 | //! The feature set provided by this crate is intentionally very basic. If you need more flexible
|
35 | 35 | //! formatting of log messages (timestamps, file and line info, etc.) this crate can be used with
|
36 | 36 | //! the [`fern`] logger via the [`console_log::log`] function.
|
37 | 37 | //!
|
| 38 | +//! ## Colors |
| 39 | +//! |
| 40 | +//! The `"color"` feature adds styling to the log messages. |
| 41 | +//! |
| 42 | +//! `Cargo.toml` |
| 43 | +//! ```toml |
| 44 | +//! console_log = { version = "0.1", features = ["color"] } |
| 45 | +//! ``` |
| 46 | +//! |
| 47 | +//! The styled log messages will be rendered as follows: |
| 48 | +//! |
| 49 | +//!  |
| 50 | +//! |
38 | 51 | //! # Code Size
|
39 |
| -//! |
| 52 | +//! |
40 | 53 | //! [Twiggy] reports this library adding about 180Kb to the size of a minimal wasm binary in a
|
41 | 54 | //! debug build. If you want to avoid this, mark the library as optional and conditionally
|
42 | 55 | //! initialize it in your code for non-release builds.
|
43 |
| -//! |
| 56 | +//! |
44 | 57 | //! `Cargo.toml`
|
45 | 58 | //! ```toml
|
46 | 59 | //! [dependencies]
|
47 | 60 | //! cfg_if = "0.1"
|
48 | 61 | //! log = "0.4"
|
49 | 62 | //! console_log = { version = "0.1", optional = true }
|
50 |
| -//! |
| 63 | +//! |
51 | 64 | //! [features]
|
52 | 65 | //! default = ["console_log"]
|
53 | 66 | //! ```
|
54 |
| -//! |
| 67 | +//! |
55 | 68 | //! `lib.rs`
|
56 | 69 | //! ```rust,ignore
|
57 | 70 | //! use wasm_bindgen::prelude::*;
|
|
67 | 80 | //! fn init_log() {}
|
68 | 81 | //! }
|
69 | 82 | //! }
|
70 |
| -//! |
| 83 | +//! |
71 | 84 | //! #[wasm_bindgen]
|
72 | 85 | //! pub fn main() {
|
73 | 86 | //! init_log();
|
74 | 87 | //! // ...
|
75 | 88 | //! }
|
76 | 89 | //! ```
|
77 |
| -//! |
| 90 | +//! |
78 | 91 | //! # Limitations
|
79 |
| -//! |
| 92 | +//! |
80 | 93 | //! The file and line number information associated with the log messages reports locations from
|
81 | 94 | //! the shims generated by `wasm-bindgen`, not the location of the logger call.
|
82 | 95 | //!
|
83 | 96 | //! [Twiggy]: https://github.com/rustwasm/twiggy
|
84 | 97 | //! [`console_log::log`]: fn.log.html
|
85 | 98 | //! [`fern`]: https://docs.rs/fern
|
86 | 99 |
|
87 |
| -use log::{Log, Level, Record, Metadata, SetLoggerError}; |
| 100 | +use log::{Level, Log, Metadata, Record, SetLoggerError}; |
88 | 101 | use web_sys::console;
|
89 | 102 |
|
| 103 | +#[cfg(feature = "color")] |
| 104 | +use wasm_bindgen::JsValue; |
| 105 | + |
| 106 | +#[cfg(feature = "color")] |
| 107 | +const STYLE: style::Style<'static> = style::Style::default(); |
| 108 | + |
| 109 | +#[cfg(feature = "color")] |
| 110 | +#[doc(hidden)] |
| 111 | +mod style; |
| 112 | + |
90 | 113 | static LOGGER: WebConsoleLogger = WebConsoleLogger {};
|
91 | 114 |
|
92 | 115 | struct WebConsoleLogger {}
|
@@ -119,16 +142,60 @@ impl Log for WebConsoleLogger {
|
119 | 142 | /// .apply()?;
|
120 | 143 | /// ```
|
121 | 144 | pub fn log(record: &Record) {
|
122 |
| - // pick the console.log() variant for the appropriate logging level |
123 |
| - let console_log = match record.level() { |
124 |
| - Level::Error => console::error_1, |
125 |
| - Level::Warn => console::warn_1, |
126 |
| - Level::Info => console::info_1, |
127 |
| - Level::Debug => console::log_1, |
128 |
| - Level::Trace => console::debug_1, |
129 |
| - }; |
130 |
| - |
131 |
| - console_log(&format!("{}", record.args()).into()); |
| 145 | + #[cfg(not(feature = "color"))] |
| 146 | + { |
| 147 | + // pick the console.log() variant for the appropriate logging level |
| 148 | + let console_log = match record.level() { |
| 149 | + Level::Error => console::error_1, |
| 150 | + Level::Warn => console::warn_1, |
| 151 | + Level::Info => console::info_1, |
| 152 | + Level::Debug => console::log_1, |
| 153 | + Level::Trace => console::debug_1, |
| 154 | + }; |
| 155 | + |
| 156 | + console_log(&format!("{}", record.args()).into()); |
| 157 | + } |
| 158 | + |
| 159 | + #[cfg(feature = "color")] |
| 160 | + { |
| 161 | + // pick the console.log() variant for the appropriate logging level |
| 162 | + let console_log = match record.level() { |
| 163 | + Level::Error => console::error_4, |
| 164 | + Level::Warn => console::warn_4, |
| 165 | + Level::Info => console::info_4, |
| 166 | + Level::Debug => console::log_4, |
| 167 | + Level::Trace => console::debug_4, |
| 168 | + }; |
| 169 | + |
| 170 | + let message = { |
| 171 | + let message = format!( |
| 172 | + "%c{level}%c {file}:{line} %c\n{text}", |
| 173 | + level = record.level(), |
| 174 | + file = record.file().unwrap_or_else(|| record.target()), |
| 175 | + line = record |
| 176 | + .line() |
| 177 | + .map_or_else(|| "[Unknown]".to_string(), |line| line.to_string()), |
| 178 | + text = record.args(), |
| 179 | + ); |
| 180 | + JsValue::from(&message) |
| 181 | + }; |
| 182 | + |
| 183 | + let level_style = { |
| 184 | + let style_str = match record.level() { |
| 185 | + Level::Trace => STYLE.trace, |
| 186 | + Level::Debug => STYLE.debug, |
| 187 | + Level::Info => STYLE.info, |
| 188 | + Level::Warn => STYLE.warn, |
| 189 | + Level::Error => STYLE.error, |
| 190 | + }; |
| 191 | + |
| 192 | + JsValue::from(style_str) |
| 193 | + }; |
| 194 | + |
| 195 | + let file_line_style = JsValue::from_str(STYLE.file_line); |
| 196 | + let text_style = JsValue::from_str(STYLE.text); |
| 197 | + console_log(&message, &level_style, &file_line_style, &text_style); |
| 198 | + } |
132 | 199 | }
|
133 | 200 |
|
134 | 201 | /// Initializes the global logger setting `max_log_level` to the given value.
|
|
0 commit comments