| From cd85e49c438e3aa9dbe2989f91e5ad7d3f4816de Mon Sep 17 00:00:00 2001 | |
| From: Marcin Radomski <dextero@google.com> | |
| Date: Thu, 17 Aug 2023 16:11:56 +0000 | |
| Subject: [PATCH] Enable default-initializing liblog_rust to write to logcat on | |
| Android | |
| Add default_log_impl cfg that, when enabled, makes `liblog_rust` use | |
| `android_logger` instead of `NopLogger` by default. | |
| This makes it possible to embed android_logger as mod inside liblog_rust | |
| crate, so that AndroidLogger can be used as default logger instead of a | |
| NopLogger. | |
| Changing that default prevents dropping logs when the logger is | |
| uninitialized. This can happen by accident when an application doesn't | |
| intialize the logger in all linker namespaces it pulls libraries from. | |
| See discussion at b/294216366#comment7. | |
| Bug: 275290559 | |
| Test: compile test app from aosp/2717614 | |
| Test: run it on a Cuttlefish device | |
| Test: observe logcat logs on all level from FFI call | |
| Test: observe all logs on non-FFI call without initializing the logger | |
| Test: observe set log filter applying only to non-FFI call | |
| Change-Id: I04dd334c66e5a2be8cfb19e87be3afb9146e5aa6 | |
| --- | |
| src/android_logger.rs | 1 + | |
| src/lib.rs | 23 +++++++++++++++++++++++ | |
| 2 files changed, 24 insertions(+) | |
| diff --git b/src/android_logger.rs a/src/android_logger.rs | |
| new file mode 120000 | |
| index 00000000..84b8625c | |
| --- /dev/null | |
| +++ a/src/android_logger.rs | |
| @@ -0,0 +1 @@ | |
| +../../android_logger/src/lib.rs | |
| \ No newline at end of file | |
| diff --git b/src/lib.rs a/src/lib.rs | |
| index 6b43a9ae..799b88e1 100644 | |
| --- b/src/lib.rs | |
| +++ a/src/lib.rs | |
| @@ -397,6 +397,11 @@ mod serde; | |
| #[cfg(feature = "kv")] | |
| pub mod kv; | |
| +#[cfg(default_log_impl)] | |
| +extern crate once_cell; | |
| +#[cfg(default_log_impl)] | |
| +mod android_logger; | |
| + | |
| #[cfg(target_has_atomic = "ptr")] | |
| use std::sync::atomic::{AtomicUsize, Ordering}; | |
| @@ -458,7 +463,10 @@ const UNINITIALIZED: usize = 0; | |
| const INITIALIZING: usize = 1; | |
| const INITIALIZED: usize = 2; | |
| +#[cfg(not(default_log_impl))] | |
| static MAX_LOG_LEVEL_FILTER: AtomicUsize = AtomicUsize::new(0); | |
| +#[cfg(default_log_impl)] | |
| +static MAX_LOG_LEVEL_FILTER: AtomicUsize = AtomicUsize::new(5); | |
| static LOG_LEVEL_NAMES: [&str; 6] = ["OFF", "ERROR", "WARN", "INFO", "DEBUG", "TRACE"]; | |
| @@ -1505,6 +1513,21 @@ pub fn logger() -> &'static dyn Log { | |
| // write to the `LOGGER` static and initialization of the logger | |
| // internal state synchronized with current thread. | |
| if STATE.load(Ordering::Acquire) != INITIALIZED { | |
| + #[cfg(default_log_impl)] | |
| + { | |
| + // On Android, default to logging to logcat if not explicitly initialized. This | |
| + // prevents logs from being dropped by default, which may happen unexpectedly in case | |
| + // of using libraries from multiple linker namespaces and failing to initialize the | |
| + // logger in each namespace. See b/294216366#comment7. | |
| + use android_logger::{AndroidLogger, Config}; | |
| + use std::sync::OnceLock; | |
| + static ANDROID_LOGGER: OnceLock<AndroidLogger> = OnceLock::new(); | |
| + return | |
| + ANDROID_LOGGER.get_or_init(|| { | |
| + // Pass all logs down to liblog - it does its own filtering. | |
| + AndroidLogger::new(Config::default().with_max_level(LevelFilter::Trace)) | |
| + }); | |
| + } | |
| static NOP: NopLogger = NopLogger; | |
| &NOP | |
| } else { | |
| -- | |
| 2.42.0.rc1.204.g551eb34607-goog | |