| 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 |
| --- |
| Android.bp | 12 ++++++++++++ |
| src/android_logger.rs | 1 + |
| src/lib.rs | 23 +++++++++++++++++++++++ |
| 3 files changed, 36 insertions(+) |
| create mode 120000 src/android_logger.rs |
| |
| diff --git a/Android.bp b/Android.bp |
| index e6ff3cf..81c9175 100644 |
| --- a/Android.bp |
| +++ b/Android.bp |
| @@ -60,6 +60,18 @@ rust_library { |
| product_available: true, |
| vendor_available: true, |
| min_sdk_version: "29", |
| + target: { |
| + android: { |
| + cfgs: ["default_log_impl"], |
| + rustlibs: [ |
| + "libandroid_log_sys", |
| + "libonce_cell", |
| + ], |
| + shared_libs: [ |
| + "liblog", |
| + ], |
| + } |
| + } |
| } |
| |
| rust_library_rlib { |
| diff --git a/src/android_logger.rs b/src/android_logger.rs |
| new file mode 120000 |
| index 0000000..84b8625 |
| --- /dev/null |
| +++ b/src/android_logger.rs |
| @@ -0,0 +1 @@ |
| +../../android_logger/src/lib.rs |
| \ No newline at end of file |
| diff --git a/src/lib.rs b/src/lib.rs |
| index 4ead826..8eb1c50 100644 |
| --- a/src/lib.rs |
| +++ b/src/lib.rs |
| @@ -344,6 +344,11 @@ mod serde; |
| #[cfg(feature = "kv_unstable")]
|
| pub mod kv;
|
|
|
| +#[cfg(default_log_impl)]
|
| +extern crate once_cell;
|
| +#[cfg(default_log_impl)]
|
| +mod android_logger;
|
| +
|
| #[cfg(has_atomics)]
|
| use std::sync::atomic::{AtomicUsize, Ordering};
|
|
|
| @@ -405,7 +410,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"];
|
|
|
| @@ -1572,6 +1580,21 @@ impl error::Error for ParseLevelError {} |
| /// If a logger has not been set, a no-op implementation is returned.
|
| pub fn logger() -> &'static dyn Log {
|
| if STATE.load(Ordering::SeqCst) != 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 |
| |