diff options
author | Marcin Radomski <dextero@google.com> | 2023-08-25 14:57:40 +0000 |
---|---|---|
committer | Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com> | 2023-08-25 14:57:40 +0000 |
commit | 2912560fe9d6f5b8219e9984a620aed68a9c4543 (patch) | |
tree | bc821a5b1a090001abcdc07eb801ec9ddc199f5a | |
parent | 11b0450712535f60691e70fcc1b7ad535989b41c (diff) | |
parent | a5c0b79fcb0186c16917720bc39ae04c921a0f81 (diff) | |
download | log-2912560fe9d6f5b8219e9984a620aed68a9c4543.tar.gz |
Enable default-initializing liblog_rust to write to logcat on Android am: 28e0c72e03 am: 1af5e04469 am: 6e31631e59 am: 5be91b79c0 am: a5c0b79fcb
Original change: https://android-review.googlesource.com/c/platform/external/rust/crates/log/+/2717613
Change-Id: I1c3b3cc10dcf044e64005b5cbb12306db7c05dfb
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
-rw-r--r-- | Android.bp | 12 | ||||
-rw-r--r-- | patches/0001-Enable-default-initializing-liblog_rust-to-write-to-.patch | 115 | ||||
l--------- | src/android_logger.rs | 1 | ||||
-rw-r--r-- | src/lib.rs | 23 |
4 files changed, 151 insertions, 0 deletions
@@ -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/patches/0001-Enable-default-initializing-liblog_rust-to-write-to-.patch b/patches/0001-Enable-default-initializing-liblog_rust-to-write-to-.patch new file mode 100644 index 0000000..0c8c38a --- /dev/null +++ b/patches/0001-Enable-default-initializing-liblog_rust-to-write-to-.patch @@ -0,0 +1,115 @@ +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 + 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 @@ -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 {
|