1From cd85e49c438e3aa9dbe2989f91e5ad7d3f4816de Mon Sep 17 00:00:00 2001 2From: Marcin Radomski <[email protected]> 3Date: Thu, 17 Aug 2023 16:11:56 +0000 4Subject: [PATCH] Enable default-initializing liblog_rust to write to logcat on 5 Android 6 7Add default_log_impl cfg that, when enabled, makes `liblog_rust` use 8`android_logger` instead of `NopLogger` by default. 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: I04dd334c66e5a2be8cfb19e87be3afb9146e5aa6 26--- 27 src/android_logger.rs | 1 + 28 src/lib.rs | 23 +++++++++++++++++++++++ 29 2 files changed, 24 insertions(+) 30 31diff --git b/src/android_logger.rs a/src/android_logger.rs 32new file mode 120000 33index 00000000..84b8625c 34--- /dev/null 35+++ a/src/android_logger.rs 36@@ -0,0 +1 @@ 37+../../android_logger/src/lib.rs 38\ No newline at end of file 39diff --git b/src/lib.rs a/src/lib.rs 40index 6b43a9ae..799b88e1 100644 41--- b/src/lib.rs 42+++ a/src/lib.rs 43@@ -397,6 +397,11 @@ mod serde; 44 #[cfg(feature = "kv")] 45 pub mod kv; 46 47+#[cfg(default_log_impl)] 48+extern crate once_cell; 49+#[cfg(default_log_impl)] 50+mod android_logger; 51+ 52 #[cfg(target_has_atomic = "ptr")] 53 use std::sync::atomic::{AtomicUsize, Ordering}; 54 55@@ -458,7 +463,10 @@ const UNINITIALIZED: usize = 0; 56 const INITIALIZING: usize = 1; 57 const INITIALIZED: usize = 2; 58 59+#[cfg(not(default_log_impl))] 60 static MAX_LOG_LEVEL_FILTER: AtomicUsize = AtomicUsize::new(0); 61+#[cfg(default_log_impl)] 62+static MAX_LOG_LEVEL_FILTER: AtomicUsize = AtomicUsize::new(5); 63 64 static LOG_LEVEL_NAMES: [&str; 6] = ["OFF", "ERROR", "WARN", "INFO", "DEBUG", "TRACE"]; 65 66@@ -1505,6 +1513,21 @@ pub fn logger() -> &'static dyn Log { 67 // write to the `LOGGER` static and initialization of the logger 68 // internal state synchronized with current thread. 69 if STATE.load(Ordering::Acquire) != INITIALIZED { 70+ #[cfg(default_log_impl)] 71+ { 72+ // On Android, default to logging to logcat if not explicitly initialized. This 73+ // prevents logs from being dropped by default, which may happen unexpectedly in case 74+ // of using libraries from multiple linker namespaces and failing to initialize the 75+ // logger in each namespace. See b/294216366#comment7. 76+ use android_logger::{AndroidLogger, Config}; 77+ use std::sync::OnceLock; 78+ static ANDROID_LOGGER: OnceLock<AndroidLogger> = OnceLock::new(); 79+ return 80+ ANDROID_LOGGER.get_or_init(|| { 81+ // Pass all logs down to liblog - it does its own filtering. 82+ AndroidLogger::new(Config::default().with_max_level(LevelFilter::Trace)) 83+ }); 84+ } 85 static NOP: NopLogger = NopLogger; 86 &NOP 87 } else { 88-- 892.42.0.rc1.204.g551eb34607-goog 90 91