1From ff9b04d9a87d2bda1281cf31e9df32c60133ef42 Mon Sep 17 00:00:00 2001 2From: Marcin Radomski <[email protected]> 3Date: Thu, 17 Aug 2023 16:07:56 +0000 4Subject: [PATCH] Enable embedding android_logger in liblog_rust 5 6Add default_log_impl cfg that, when enabled: 7* Removes the dependency on env_logger, 8* Imports all log crate symbols from current crate. 9 10This makes it possible to embed android_logger as mod inside liblog_rust 11crate, so that AndroidLogger can be used as default logger instead of a 12NopLogger. 13 14Changing that default prevents dropping logs when the logger is 15uninitialized. This can happen by accident when an application doesn't 16intialize the logger in all linker namespaces it pulls libraries from. 17See discussion at b/294216366#comment7. 18 19Bug: 275290559 20Test: compile test app from aosp/2717614 21Test: run it on a Cuttlefish device 22Test: observe logcat logs on all level from FFI call 23Test: observe all logs on non-FFI call without initializing the logger 24Test: observe set log filter applying only to non-FFI call 25Change-Id: I324f77d840101391299e2693acc6f814d062c659 26--- 27 src/lib.rs | 26 ++++++++++++++++++++++++-- 28 1 file changed, 24 insertions(+), 2 deletions(-) 29 30diff --git b/src/lib.rs a/src/lib.rs 31index faf2779b..cfd2bb99 100644 32--- b/src/lib.rs 33+++ a/src/lib.rs 34@@ -67,20 +67,35 @@ 35 extern crate android_log_sys as log_ffi; 36 extern crate once_cell; 37 use once_cell::sync::OnceCell; 38+#[cfg(default_log_impl)] 39+use crate as log; 40+#[cfg(not(default_log_impl))] 41 #[macro_use] 42 extern crate log; 43 44+#[cfg(not(default_log_impl))] 45 extern crate env_logger; 46 47-use log::{Level, LevelFilter, Log, Metadata, Record}; 48+use self::log::{Level, LevelFilter, Log, Metadata, Record}; 49 #[cfg(target_os = "android")] 50-use log_ffi::LogPriority; 51+use self::log_ffi::LogPriority; 52 use std::ffi::{CStr, CString}; 53 use std::fmt; 54 use std::mem::{self, MaybeUninit}; 55 use std::ptr; 56 57+#[cfg(default_log_impl)] 58+pub mod env_logger { 59+ pub mod filter { 60+ pub struct Filter; 61+ impl Filter { 62+ pub fn matches(&self, _: &crate::Record) -> bool { true } 63+ } 64+ } 65+} 66+#[cfg(not(default_log_impl))] 67 pub use env_logger::filter::{Builder as FilterBuilder, Filter}; 68+#[cfg(not(default_log_impl))] 69 pub use env_logger::fmt::Formatter; 70 71 pub(crate) type FormatFn = Box<dyn Fn(&mut dyn fmt::Write, &Record) -> fmt::Result + Sync + Send>; 72@@ -542,6 +557,12 @@ pub fn init_once(config: Config) { 73 } else if let Some(level) = log_level { 74 log::set_max_level(level); 75 } 76+ // On Android, log crate is patched to default to LevelFilter::Trace rather than Off. Preserve 77+ // the existing "android_logger default level is Off" behavior by explicitly setting the level. 78+ #[cfg(target_os = "android")] 79+ if log_level.is_none() { 80+ log::set_max_level(LevelFilter::Off); 81+ } 82 } 83 84 // FIXME: When `maybe_uninit_uninit_array ` is stabilized, use it instead of this helper 85@@ -596,6 +617,7 @@ mod tests { 86 87 // Test whether the filter gets called correctly. Not meant to be exhaustive for all filter 88 // options, as these are handled directly by the filter itself. 89+ #[cfg(not(default_log_impl))] 90 #[test] 91 fn config_filter_match() { 92 let info_record = Record::builder().level(Level::Info).build(); 93-- 942.42.0.rc1.204.g551eb34607-goog 95 96