• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1From 5463a7be6408ee158c1fe2bea948af785d45b9dc Mon Sep 17 00:00:00 2001
2From: Marcin Radomski <dextero@google.com>
3Date: Thu, 20 Mar 2025 13:37:51 +0000
4Subject: [PATCH] Enable default-initializing liblog_rust to write to logcat on
5 Android
6
7Add default_log_impl cfg that, when enabled, makes `liblog_rust` use
8`android_logger` instead of `NopLogger` by default.
9
10This makes it possible to embed android_logger as mod inside liblog_rust
11crate, so that AndroidLogger can be used as default logger instead of a
12NopLogger.
13
14Changing that default prevents dropping logs when the logger is
15uninitialized. This can happen by accident when an application doesn't
16intialize the logger in all linker namespaces it pulls libraries from.
17See discussion at b/294216366#comment7.
18
19Bug: 275290559
20Test: compile test app from aosp/2717614
21Test: run it on a Cuttlefish device
22Test: observe logcat logs on all level from FFI call
23Test: observe all logs on non-FFI call without initializing the logger
24Test: observe set log filter applying only to non-FFI call
25Change-Id: I027e3ed859718aa3aaf3ed9703466f7a9df9d1d7
26---
27 src/lib.rs | 22 ++++++++++++++++++++++
28 1 file changed, 22 insertions(+)
29
30diff --git a/src/lib.rs b/src/lib.rs
31index 843893d0..09507729 100644
32--- a/src/lib.rs
33+++ b/src/lib.rs
34@@ -405,6 +405,10 @@ mod serde;
35 #[cfg(feature = "kv")]
36 pub mod kv;
37
38+#[cfg(default_log_impl)]
39+#[path = "../../android_logger/src/lib.rs"]
40+mod android_logger;
41+
42 #[cfg(target_has_atomic = "ptr")]
43 use std::sync::atomic::{AtomicUsize, Ordering};
44
45@@ -466,7 +470,10 @@ const UNINITIALIZED: usize = 0;
46 const INITIALIZING: usize = 1;
47 const INITIALIZED: usize = 2;
48
49+#[cfg(not(default_log_impl))]
50 static MAX_LOG_LEVEL_FILTER: AtomicUsize = AtomicUsize::new(0);
51+#[cfg(default_log_impl)]
52+static MAX_LOG_LEVEL_FILTER: AtomicUsize = AtomicUsize::new(5);
53
54 static LOG_LEVEL_NAMES: [&str; 6] = ["OFF", "ERROR", "WARN", "INFO", "DEBUG", "TRACE"];
55
56@@ -1513,6 +1520,21 @@ pub fn logger() -> &'static dyn Log {
57     // write to the `LOGGER` static and initialization of the logger
58     // internal state synchronized with current thread.
59     if STATE.load(Ordering::Acquire) != INITIALIZED {
60+        #[cfg(default_log_impl)]
61+        {
62+            // On Android, default to logging to logcat if not explicitly initialized. This
63+            // prevents logs from being dropped by default, which may happen unexpectedly in case
64+            // of using libraries from multiple linker namespaces and failing to initialize the
65+            // logger in each namespace. See b/294216366#comment7.
66+            use android_logger::{AndroidLogger, Config};
67+            use std::sync::OnceLock;
68+            static ANDROID_LOGGER: OnceLock<AndroidLogger> = OnceLock::new();
69+            return
70+                ANDROID_LOGGER.get_or_init(|| {
71+                    // Pass all logs down to liblog - it does its own filtering.
72+                    AndroidLogger::new(Config::default().with_max_level(LevelFilter::Trace))
73+                });
74+        }
75         static NOP: NopLogger = NopLogger;
76         &NOP
77     } else {
78--
792.49.0.rc1.451.g8f38331e32-goog
80
81