| 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 |
| |