aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarcin Radomski <dextero@google.com>2023-08-25 14:57:40 +0000
committerAutomerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>2023-08-25 14:57:40 +0000
commit2912560fe9d6f5b8219e9984a620aed68a9c4543 (patch)
treebc821a5b1a090001abcdc07eb801ec9ddc199f5a
parent11b0450712535f60691e70fcc1b7ad535989b41c (diff)
parenta5c0b79fcb0186c16917720bc39ae04c921a0f81 (diff)
downloadlog-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.bp12
-rw-r--r--patches/0001-Enable-default-initializing-liblog_rust-to-write-to-.patch115
l---------src/android_logger.rs1
-rw-r--r--src/lib.rs23
4 files changed, 151 insertions, 0 deletions
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/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
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 {