From 8ca698f0a266d5d10aabc8f8a38e4732150c1879 Mon Sep 17 00:00:00 2001 From: Steven Fackler Date: Sun, 3 Jun 2018 10:55:09 -0700 Subject: [PATCH] Optimize logging codegen The extra work involved in loading the logger and creating the record struct involves move codegen than is necessary if we take this kind of approach (which we previously used in 0.3). It's a bit unfortunate to have these public-but-not-public functions, but I think it's worth it. We want to minimize the footprint of logging so people feel comfortable using it! A main function containing nothing but `warn!("hello world")` shrinks from 204 bytes to 124 bytes in x86_64 with this change. Closes #275 --- src/lib.rs | 48 +++++++++++++++++++++++++++++++++++++++--------- src/macros.rs | 38 ++++++++++++++++---------------------- 2 files changed, 55 insertions(+), 31 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 36f8562fa..6238e8ef1 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -253,9 +253,11 @@ //! [log4rs]: https://docs.rs/log4rs/*/log4rs/ //! [fern]: https://docs.rs/fern/*/fern/ -#![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png", - html_favicon_url = "https://www.rust-lang.org/favicon.ico", - html_root_url = "https://docs.rs/log/0.4.1")] +#![doc( + html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png", + html_favicon_url = "https://www.rust-lang.org/favicon.ico", + html_root_url = "https://docs.rs/log/0.4.0-rc.1" +)] #![warn(missing_docs)] #![deny(missing_debug_implementations)] #![cfg_attr(not(feature = "std"), no_std)] @@ -298,10 +300,10 @@ static MAX_LOG_LEVEL_FILTER: AtomicUsize = ATOMIC_USIZE_INIT; static LOG_LEVEL_NAMES: [&'static str; 6] = ["OFF", "ERROR", "WARN", "INFO", "DEBUG", "TRACE"]; -static SET_LOGGER_ERROR: &'static str = "attempted to set a logger after the logging system was \ - already initialized"; -static LEVEL_PARSE_ERROR: &'static str = "attempted to convert a string that doesn't match an \ - existing log level"; +static SET_LOGGER_ERROR: &'static str = "attempted to set a logger after the logging system \ + was already initialized"; +static LEVEL_PARSE_ERROR: &'static str = + "attempted to convert a string that doesn't match an existing log level"; /// An enum representing the available verbosity levels of the logger. /// @@ -1121,6 +1123,34 @@ pub fn logger() -> &'static Log { } } +// WARNING: this is not part of the crate's public API and is subject to change at any time +#[doc(hidden)] +pub fn __private_api_log( + args: fmt::Arguments, + level: Level, + target: &str, + module_path: &str, + file: &str, + line: u32, +) { + logger().log( + &Record::builder() + .args(args) + .level(level) + .target(target) + .module_path(Some(module_path)) + .file(Some(file)) + .line(Some(line)) + .build(), + ); +} + +// WARNING: this is not part of the crate's public API and is subject to change at any time +#[doc(hidden)] +pub fn __private_api_enabled(level: Level, target: &str) -> bool { + logger().enabled(&Metadata::builder().level(level).target(target).build()) +} + /// The statically resolved maximum log level. /// /// See the crate level documentation for information on how to configure this. @@ -1163,8 +1193,8 @@ cfg_if! { #[cfg(test)] mod tests { extern crate std; - use tests::std::string::ToString; use super::{Level, LevelFilter, ParseLevelError}; + use tests::std::string::ToString; #[test] fn test_levelfilter_from_str() { @@ -1251,8 +1281,8 @@ mod tests { #[test] #[cfg(feature = "std")] fn test_error_trait() { - use std::error::Error; use super::SetLoggerError; + use std::error::Error; let e = SetLoggerError(()); assert_eq!( e.description(), diff --git a/src/macros.rs b/src/macros.rs index 25f697f75..3c7867f85 100644 --- a/src/macros.rs +++ b/src/macros.rs @@ -34,17 +34,14 @@ macro_rules! log { (target: $target:expr, $lvl:expr, $($arg:tt)+) => ({ let lvl = $lvl; if lvl <= $crate::STATIC_MAX_LEVEL && lvl <= $crate::max_level() { - $crate::Log::log( - $crate::logger(), - &$crate::RecordBuilder::new() - .args(format_args!($($arg)+)) - .level(lvl) - .target($target) - .module_path(Some(module_path!())) - .file(Some(file!())) - .line(Some(line!())) - .build() - ) + $crate::__private_api_log( + format_args!($($arg)+), + lvl, + $target, + module_path!(), + file!(), + line!(), + ); } }); ($lvl:expr, $($arg:tt)+) => (log!(target: module_path!(), $lvl, $($arg)+)) @@ -205,16 +202,13 @@ macro_rules! trace { /// ``` #[macro_export] macro_rules! log_enabled { - (target: $target:expr, $lvl:expr) => ({ + (target: $target:expr, $lvl:expr) => {{ let lvl = $lvl; - lvl <= $crate::STATIC_MAX_LEVEL && lvl <= $crate::max_level() && - $crate::Log::enabled( - $crate::logger(), - &$crate::MetadataBuilder::new() - .level(lvl) - .target($target) - .build(), - ) - }); - ($lvl:expr) => (log_enabled!(target: module_path!(), $lvl)) + lvl <= $crate::STATIC_MAX_LEVEL + && lvl <= $crate::max_level() + && $crate::__private_api_enabled(lvl, $target) + }}; + ($lvl:expr) => { + log_enabled!(target: module_path!(), $lvl) + }; }