aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2023-07-07 05:04:28 +0000
committerAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2023-07-07 05:04:28 +0000
commit907aca63a329a52b0c69342269b9f37ce2c5ea65 (patch)
treec947a8493fdab7473512377a3213273b45430dc7
parentf9f6753386f741dd38fa05ab3c5e072ef542715c (diff)
parentf6151f845dd997a9e324388d07b7142c6c346914 (diff)
downloadandroid_logger-907aca63a329a52b0c69342269b9f37ce2c5ea65.tar.gz
Change-Id: I3c23e98ae6e03a003b96fa2ddf0e754e96deb2dc
-rw-r--r--.cargo_vcs_info.json7
-rw-r--r--Android.bp19
-rw-r--r--CHANGELOG.md54
-rw-r--r--Cargo.toml32
-rw-r--r--Cargo.toml.orig6
-rw-r--r--METADATA13
-rw-r--r--OWNERS2
-rw-r--r--README.md11
-rw-r--r--TEST_MAPPING73
-rw-r--r--cargo2android.json6
-rw-r--r--patches/0001-Support-selecting-target-log-buffer.patch99
-rw-r--r--patches/0002-Use-older-API-to-avoid-requiring-API-v30.patch16
-rw-r--r--src/lib.rs227
-rw-r--r--tests/config_log_level.rs6
-rw-r--r--tests/default_init.rs2
-rw-r--r--tests/multiple_init.rs10
16 files changed, 320 insertions, 263 deletions
diff --git a/.cargo_vcs_info.json b/.cargo_vcs_info.json
index 00435b7..c1be5ef 100644
--- a/.cargo_vcs_info.json
+++ b/.cargo_vcs_info.json
@@ -1,5 +1,6 @@
{
"git": {
- "sha1": "c20ec25acacf0731583140b230e6ce94e59b054d"
- }
-}
+ "sha1": "596b92d5907f0054884412d2f7137704edae4208"
+ },
+ "path_in_vcs": ""
+} \ No newline at end of file
diff --git a/Android.bp b/Android.bp
index 056c310..f03803b 100644
--- a/Android.bp
+++ b/Android.bp
@@ -43,7 +43,7 @@ rust_test {
name: "android_logger_test_src_lib",
crate_name: "android_logger",
cargo_env_compat: true,
- cargo_pkg_version: "0.10.1",
+ cargo_pkg_version: "0.12.0",
srcs: ["src/lib.rs"],
test_suites: ["general-tests"],
auto_gen_config: true,
@@ -55,8 +55,8 @@ rust_test {
rustlibs: [
"libandroid_log_sys",
"libenv_logger",
- "liblazy_static",
"liblog_rust",
+ "libonce_cell",
],
}
@@ -64,7 +64,7 @@ rust_defaults {
name: "android_logger_test_defaults",
crate_name: "android_logger",
cargo_env_compat: true,
- cargo_pkg_version: "0.10.1",
+ cargo_pkg_version: "0.12.0",
test_suites: ["general-tests"],
auto_gen_config: true,
edition: "2015",
@@ -76,8 +76,8 @@ rust_defaults {
"libandroid_log_sys",
"libandroid_logger",
"libenv_logger",
- "liblazy_static",
"liblog_rust",
+ "libonce_cell",
],
}
@@ -103,7 +103,7 @@ rust_library {
name: "libandroid_logger",
crate_name: "android_logger",
cargo_env_compat: true,
- cargo_pkg_version: "0.10.1",
+ cargo_pkg_version: "0.12.0",
srcs: ["src/lib.rs"],
edition: "2015",
features: [
@@ -113,17 +113,14 @@ rust_library {
rustlibs: [
"libandroid_log_sys",
"libenv_logger",
- "liblazy_static",
"liblog_rust",
+ "libonce_cell",
],
apex_available: [
"//apex_available:platform",
- "com.android.bluetooth",
- "com.android.compos",
- "com.android.resolv",
- "com.android.uwb",
- "com.android.virt",
+ "//apex_available:anyapex",
],
+ product_available: true,
vendor_available: true,
min_sdk_version: "29",
}
diff --git a/CHANGELOG.md b/CHANGELOG.md
new file mode 100644
index 0000000..4952ca1
--- /dev/null
+++ b/CHANGELOG.md
@@ -0,0 +1,54 @@
+`android_logger` changelog
+==========================
+
+All user visible changes to this project will be documented in this file. This project uses [Semantic Versioning 2.0.0].
+
+
+
+
+## [0.12.0] · 2023-01-19
+[0.12.0]: /../../tree/v0.12.0
+
+[Diff](/../../compare/v0.11.3...v0.12.0)
+
+### Added
+
+- `Config::with_max_level()` method to filters logs via `log::LevelFilter`. ([#62])
+
+### Deprecated
+
+- `Config::with_min_level()` method accepting `log::Level`. ([#62])
+
+### Fixed
+
+- Incorrect logs level filtering. ([#62])
+
+[#62]: /../../pull/62
+
+
+
+
+## [0.11.3] · 2022-12-20
+[0.11.3]: /../../tree/v0.11.3
+
+[Diff](/../../compare/38186ece1056d90b8f75fd2a5eb5c860e0a1704e...v0.11.3)
+
+### Fixed
+
+- Broken compilation on [Android] targets. ([#59], [#58])
+
+[#58]: /../../issues/58
+[#59]: /../../pull/59
+
+
+
+
+## Previous releases
+
+See [Git log](/../../commits/master?after=1a5a07ec6742f0069acc2be223c1bb3b6a9d15f8+0).
+
+
+
+
+[Android]: https://www.android.com
+[Semantic Versioning 2.0.0]: https://semver.org
diff --git a/Cargo.toml b/Cargo.toml
index dec0113..a9fd573 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -3,38 +3,46 @@
# When uploading crates to the registry Cargo will automatically
# "normalize" Cargo.toml files for maximal compatibility
# with all versions of Cargo and also rewrite `path` dependencies
-# to registry (e.g., crates.io) dependencies
+# to registry (e.g., crates.io) dependencies.
#
-# If you believe there's an error in this file please file an
-# issue against the rust-lang/cargo repository. If you're
-# editing this file be aware that the upstream Cargo.toml
-# will likely look very different (and much more reasonable)
+# If you are reading this file be aware that the original Cargo.toml
+# will likely look very different (and much more reasonable).
+# See Cargo.toml.orig for the original contents.
[package]
name = "android_logger"
-version = "0.10.1"
+version = "0.12.0"
authors = ["The android_logger Developers"]
-description = "A logging implementation for `log` which hooks to android log output.\n"
+description = """
+A logging implementation for `log` which hooks to android log output.
+"""
readme = "README.md"
-keywords = ["android", "bindings", "log", "logger"]
+keywords = [
+ "android",
+ "bindings",
+ "log",
+ "logger",
+]
categories = ["api-bindings"]
license = "MIT OR Apache-2.0"
repository = "https://github.com/Nercury/android_logger-rs"
+
[dependencies.android_log-sys]
version = "0.2"
[dependencies.env_logger]
-version = "0.8"
+version = "0.10"
default-features = false
-[dependencies.lazy_static]
-version = "1.4"
-
[dependencies.log]
version = "0.4"
+[dependencies.once_cell]
+version = "1.9"
+
[features]
default = ["regex"]
regex = ["env_logger/regex"]
+
[badges.travis-ci]
repository = "Nercury/android_logger-rs"
diff --git a/Cargo.toml.orig b/Cargo.toml.orig
index a9ad77f..ca1b723 100644
--- a/Cargo.toml.orig
+++ b/Cargo.toml.orig
@@ -1,6 +1,6 @@
[package]
name = "android_logger"
-version = "0.10.1"
+version = "0.12.0"
authors = ["The android_logger Developers"]
license = "MIT OR Apache-2.0"
readme = "README.md"
@@ -16,7 +16,7 @@ default = ["regex"]
regex = ["env_logger/regex"]
[dependencies]
-lazy_static = "1.4"
+once_cell = "1.9"
[dependencies.log]
version = "0.4"
@@ -25,7 +25,7 @@ version = "0.4"
version = "0.2"
[dependencies.env_logger]
-version = "0.8"
+version = "0.10"
default-features = false
[badges]
diff --git a/METADATA b/METADATA
index 27e229f..df2996f 100644
--- a/METADATA
+++ b/METADATA
@@ -1,5 +1,5 @@
name: "android_logger"
-description: "A logging implementation for `log` which hooks to android log output."
+description: "()"
third_party {
url {
type: HOMEPAGE
@@ -7,13 +7,14 @@ third_party {
}
url {
type: ARCHIVE
- value: "https://static.crates.io/crates/android_logger/android_logger-0.10.1.crate"
+ value: "https://static.crates.io/crates/android_logger/android_logger-0.12.0.crate"
}
- version: "0.10.1"
+ version: "0.12.0"
+ # Dual-licensed, using the least restrictive per go/thirdpartylicenses#same.
license_type: NOTICE
last_upgrade_date {
- year: 2021
- month: 4
- day: 19
+ year: 2023
+ month: 2
+ day: 2
}
}
diff --git a/OWNERS b/OWNERS
index 46fc303..45dc4dd 100644
--- a/OWNERS
+++ b/OWNERS
@@ -1 +1 @@
-include platform/prebuilts/rust:/OWNERS
+include platform/prebuilts/rust:master:/OWNERS
diff --git a/README.md b/README.md
index c3b88bf..eec1eba 100644
--- a/README.md
+++ b/README.md
@@ -13,7 +13,7 @@ this library:
```toml
[target.'cfg(target_os = "android")'.dependencies]
-android_logger = "0.10"
+android_logger = "0.11"
```
Example of initialization on activity creation, with log configuration:
@@ -22,13 +22,13 @@ Example of initialization on activity creation, with log configuration:
#[macro_use] extern crate log;
extern crate android_logger;
-use log::Level;
+use log::LevelFilter;
use android_logger::{Config,FilterBuilder};
fn native_activity_create() {
android_logger::init_once(
Config::default()
- .with_min_level(Level::Trace) // limit log level
+ .with_max_level(LevelFilter::Trace) // limit log level
.with_tag("mytag") // logs will show under mytag tag
.with_filter( // configure messages for specific crate
FilterBuilder::new()
@@ -47,12 +47,13 @@ To allow all logs, use the default configuration with min level Trace:
#[macro_use] extern crate log;
extern crate android_logger;
-use log::Level;
+use log::LevelFilter;
use android_logger::Config;
fn native_activity_create() {
android_logger::init_once(
- Config::default().with_min_level(Level::Trace));
+ Config::default().with_max_level(LevelFilter::Trace),
+ );
}
```
diff --git a/TEST_MAPPING b/TEST_MAPPING
index 526e77a..d42c05d 100644
--- a/TEST_MAPPING
+++ b/TEST_MAPPING
@@ -1,50 +1,40 @@
// Generated by update_crate_tests.py for tests that depend on this crate.
{
- "presubmit": [
- {
- "name": "android_logger_test_src_lib"
- },
- {
- "name": "android_logger_test_tests_config_log_level"
- },
- {
- "name": "android_logger_test_tests_default_init"
- },
- {
- "name": "android_logger_test_tests_multiple_init"
- },
+ "imports": [
{
- "name": "authfs_device_test_src_lib"
+ "path": "packages/modules/DnsResolver"
},
{
- "name": "doh_unit_test"
+ "path": "packages/modules/Virtualization/authfs"
},
{
- "name": "keystore2_selinux_concurrency_test"
+ "path": "packages/modules/Virtualization/encryptedstore"
},
{
- "name": "keystore2_selinux_test"
+ "path": "packages/modules/Virtualization/virtualizationmanager"
},
{
- "name": "keystore2_test"
+ "path": "system/logging/rust"
},
{
- "name": "logger_device_unit_tests"
+ "path": "system/security/keystore2"
},
{
- "name": "logger_test_config_log_level"
- },
+ "path": "system/security/keystore2/selinux"
+ }
+ ],
+ "presubmit": [
{
- "name": "logger_test_default_init"
+ "name": "android_logger_test_src_lib"
},
{
- "name": "logger_test_env_log_level"
+ "name": "android_logger_test_tests_config_log_level"
},
{
- "name": "logger_test_multiple_init"
+ "name": "android_logger_test_tests_default_init"
},
{
- "name": "virtualizationservice_device_test"
+ "name": "android_logger_test_tests_multiple_init"
}
],
"presubmit-rust": [
@@ -59,39 +49,6 @@
},
{
"name": "android_logger_test_tests_multiple_init"
- },
- {
- "name": "authfs_device_test_src_lib"
- },
- {
- "name": "doh_unit_test"
- },
- {
- "name": "keystore2_selinux_concurrency_test"
- },
- {
- "name": "keystore2_selinux_test"
- },
- {
- "name": "keystore2_test"
- },
- {
- "name": "logger_device_unit_tests"
- },
- {
- "name": "logger_test_config_log_level"
- },
- {
- "name": "logger_test_default_init"
- },
- {
- "name": "logger_test_env_log_level"
- },
- {
- "name": "logger_test_multiple_init"
- },
- {
- "name": "virtualizationservice_device_test"
}
]
}
diff --git a/cargo2android.json b/cargo2android.json
index 18ba06d..2733be4 100644
--- a/cargo2android.json
+++ b/cargo2android.json
@@ -1,11 +1,7 @@
{
"apex-available": [
"//apex_available:platform",
- "com.android.bluetooth",
- "com.android.compos",
- "com.android.resolv",
- "com.android.uwb",
- "com.android.virt"
+ "//apex_available:anyapex"
],
"dependencies": true,
"device": true,
diff --git a/patches/0001-Support-selecting-target-log-buffer.patch b/patches/0001-Support-selecting-target-log-buffer.patch
index e5fc33b..a9e11a4 100644
--- a/patches/0001-Support-selecting-target-log-buffer.patch
+++ b/patches/0001-Support-selecting-target-log-buffer.patch
@@ -1,6 +1,6 @@
-From 2bc2650d0a7a11a74670a6583b16aa6714d7c993 Mon Sep 17 00:00:00 2001
-From: Matthew Maurer <mmaurer@google.com>
-Date: Thu, 17 Feb 2022 20:23:37 +0000
+From a41a079a81f381f2002917fb1c030690e0798f0c Mon Sep 17 00:00:00 2001
+From: Jeff Vander Stoep <jeffv@google.com>
+Date: Thu, 2 Feb 2023 13:33:47 +0100
Subject: [PATCH] Support selecting target log buffer
Android has several different log buffers. Previously, this library
@@ -8,16 +8,17 @@ would only support logging to the "Main" log. Now, it logs to the
default log (which is Main for most processes), with the option to
override which log buffer you send messages to in the config.
-Change-Id: I72779e62bd963586e3dfad431cd82c75daf04d92
+Test: atest
+Change-Id: I3cc393b989b8189675581ba6bf700f95715aa9e9
---
- src/lib.rs | 71 ++++++++++++++++++++++++++++++++++++++++++++----------
- 1 file changed, 58 insertions(+), 13 deletions(-)
+ src/lib.rs | 73 +++++++++++++++++++++++++++++++++++++++++++-----------
+ 1 file changed, 59 insertions(+), 14 deletions(-)
diff --git a/src/lib.rs b/src/lib.rs
-index 11a127e..d21be3f 100644
+index 0446fad..9ec7f0d 100644
--- a/src/lib.rs
+++ b/src/lib.rs
-@@ -87,21 +87,49 @@ pub use env_logger::fmt::Formatter;
+@@ -85,21 +85,49 @@ pub use env_logger::fmt::Formatter;
pub(crate) type FormatFn = Box<dyn Fn(&mut dyn fmt::Write, &Record) -> fmt::Result + Sync + Send>;
@@ -74,7 +75,7 @@ index 11a127e..d21be3f 100644
/// Underlying android logger backend
pub struct AndroidLogger {
-@@ -164,7 +192,7 @@ impl Log for AndroidLogger {
+@@ -172,7 +200,7 @@ impl Log for AndroidLogger {
// message must not exceed LOGGING_MSG_MAX_LEN
// therefore split log message into multiple log calls
@@ -83,23 +84,15 @@ index 11a127e..d21be3f 100644
// If a custom tag is used, add the module path to the message.
// Use PlatformLogWriter to output chunks if they exceed max size.
-@@ -208,6 +236,7 @@ impl AndroidLogger {
- /// Filter for android logger.
+@@ -215,6 +243,7 @@ impl AndroidLogger {
+ #[derive(Default)]
pub struct Config {
- log_level: Option<Level>,
+ log_level: Option<LevelFilter>,
+ log_id: Option<LogId>,
filter: Option<env_logger::filter::Filter>,
tag: Option<CString>,
custom_format: Option<FormatFn>,
-@@ -217,6 +246,7 @@ impl Default for Config {
- fn default() -> Self {
- Config {
- log_level: None,
-+ log_id: None,
- filter: None,
- tag: None,
- custom_format: None,
-@@ -234,6 +264,15 @@ impl Config {
+@@ -241,6 +270,15 @@ impl Config {
self
}
@@ -114,34 +107,41 @@ index 11a127e..d21be3f 100644
+
fn filter_matches(&self, record: &Record) -> bool {
if let Some(ref filter) = self.filter {
- filter.matches(&record)
-@@ -273,6 +312,8 @@ impl Config {
- struct PlatformLogWriter<'a> {
- #[cfg(target_os = "android")] priority: LogPriority,
- #[cfg(not(target_os = "android"))] priority: Level,
+ filter.matches(record)
+@@ -282,6 +320,8 @@ pub struct PlatformLogWriter<'a> {
+ priority: LogPriority,
+ #[cfg(not(target_os = "android"))]
+ priority: Level,
+ #[cfg(target_os = "android")] log_id: log_ffi::log_id_t,
+ #[cfg(not(target_os = "android"))] log_id: Option<LogId>,
len: usize,
last_newline_index: usize,
tag: &'a CStr,
-@@ -281,7 +322,7 @@ struct PlatformLogWriter<'a> {
+@@ -290,10 +330,11 @@ pub struct PlatformLogWriter<'a> {
impl<'a> PlatformLogWriter<'a> {
#[cfg(target_os = "android")]
-- pub fn new(level: Level, tag: &CStr) -> PlatformLogWriter {
-+ pub fn new(log_id: Option<LogId>, level: Level, tag: &CStr) -> PlatformLogWriter {
+- pub fn new_with_priority(priority: log_ffi::LogPriority, tag: &CStr) -> PlatformLogWriter {
++ pub fn new_with_priority(log_id: Option<LogId>, priority: log_ffi::LogPriority, tag: &CStr) -> PlatformLogWriter {
#[allow(deprecated)] // created an issue #35 for this
PlatformLogWriter {
- priority: match level {
-@@ -291,6 +332,7 @@ impl<'a> PlatformLogWriter<'a> {
- Level::Error => LogPriority::ERROR,
- Level::Trace => LogPriority::VERBOSE,
- },
+ priority,
+ log_id: LogId::to_native(log_id),
len: 0,
last_newline_index: 0,
tag,
-@@ -299,10 +341,11 @@ impl<'a> PlatformLogWriter<'a> {
+@@ -302,8 +343,9 @@ impl<'a> PlatformLogWriter<'a> {
+ }
+
+ #[cfg(target_os = "android")]
+- pub fn new(level: Level, tag: &CStr) -> PlatformLogWriter {
++ pub fn new(log_id: Option<LogId>, level: Level, tag: &CStr) -> PlatformLogWriter {
+ Self::new_with_priority(
++ log_id,
+ match level {
+ Level::Warn => LogPriority::WARN,
+ Level::Info => LogPriority::INFO,
+@@ -316,10 +358,11 @@ impl<'a> PlatformLogWriter<'a> {
}
#[cfg(not(target_os = "android"))]
@@ -154,44 +154,45 @@ index 11a127e..d21be3f 100644
len: 0,
last_newline_index: 0,
tag,
-@@ -358,7 +401,7 @@ impl<'a> PlatformLogWriter<'a> {
+@@ -376,7 +419,7 @@ impl<'a> PlatformLogWriter<'a> {
});
- let msg: &CStr = unsafe { CStr::from_ptr(mem::transmute(self.buffer.as_ptr())) };
+ let msg: &CStr = unsafe { CStr::from_ptr(self.buffer.as_ptr().cast()) };
- android_log(self.priority, self.tag, msg);
+ android_log(self.log_id, self.priority, self.tag, msg);
- *unsafe { self.buffer.get_unchecked_mut(len) } = last_byte;
+ unsafe { *self.buffer.get_unchecked_mut(len) = last_byte };
}
-@@ -458,9 +501,11 @@ mod tests {
+@@ -481,9 +524,11 @@ mod tests {
// Filter is checked in config_filter_match below.
let config = Config::default()
- .with_min_level(Level::Trace)
+ .with_max_level(LevelFilter::Trace)
+ .with_log_id(LogId::System)
.with_tag("my_app");
- assert_eq!(config.log_level, Some(Level::Trace));
+ assert_eq!(config.log_level, Some(LevelFilter::Trace));
+ assert_eq!(config.log_id, Some(LogId::System));
assert_eq!(config.tag, Some(CString::new("my_app").unwrap()));
}
-@@ -531,7 +576,7 @@ mod tests {
+@@ -556,7 +601,7 @@ mod tests {
fn platform_log_writer_init_values() {
let tag = CStr::from_bytes_with_nul(b"tag\0").unwrap();
-- let writer = PlatformLogWriter::new(Level::Warn, &tag);
-+ let writer = PlatformLogWriter::new(None, Level::Warn, &tag);
+- let writer = PlatformLogWriter::new(Level::Warn, tag);
++ let writer = PlatformLogWriter::new(None, Level::Warn, tag);
assert_eq!(writer.tag, tag);
// Android uses LogPriority instead, which doesn't implement equality checks
-@@ -630,6 +675,6 @@ mod tests {
+@@ -661,7 +706,7 @@ mod tests {
}
fn get_tag_writer() -> PlatformLogWriter<'static> {
-- PlatformLogWriter::new(Level::Warn, &CStr::from_bytes_with_nul(b"tag\0").unwrap())
-+ PlatformLogWriter::new(None, Level::Warn, &CStr::from_bytes_with_nul(b"tag\0").unwrap())
+- PlatformLogWriter::new(Level::Warn, CStr::from_bytes_with_nul(b"tag\0").unwrap())
++ PlatformLogWriter::new(None, Level::Warn, CStr::from_bytes_with_nul(b"tag\0").unwrap())
}
- }
+
+ unsafe fn assume_init_slice<T>(slice: &[MaybeUninit<T>]) -> &[T] {
--
-2.35.1.265.g69c8d7142f-goog
+2.39.1.456.gfc5497dd1b-goog
diff --git a/patches/0002-Use-older-API-to-avoid-requiring-API-v30.patch b/patches/0002-Use-older-API-to-avoid-requiring-API-v30.patch
index 721e9eb..44f08fb 100644
--- a/patches/0002-Use-older-API-to-avoid-requiring-API-v30.patch
+++ b/patches/0002-Use-older-API-to-avoid-requiring-API-v30.patch
@@ -1,20 +1,20 @@
-From ec84856e0f0bc5a307529122bfed3d94d2ef4011 Mon Sep 17 00:00:00 2001
-From: Matthew Maurer <mmaurer@google.com>
-Date: Thu, 24 Feb 2022 14:07:03 -0800
-Subject: [PATCH] Use older API to avoid requiring API v30
+From b5ee33076e1868c5946345b2cfb15a519b8c2577 Mon Sep 17 00:00:00 2001
+From: Jeff Vander Stoep <jeffv@google.com>
+Date: Mon, 5 Dec 2022 12:42:22 +0100
+Subject: [PATCH 2/2] Use older API to avoid requiring API v30
Test: Check that keystore still outputs logs to system
Bug: 221185310
-Change-Id: I25174f1617557e270db70cd432cec78c037c6b75
+Change-Id: If81d66cb145cbb41b4338fd64ac024d77243482e
---
src/lib.rs | 14 ++++----------
1 file changed, 4 insertions(+), 10 deletions(-)
diff --git a/src/lib.rs b/src/lib.rs
-index d21be3f..bc4fa61 100644
+index 4bcce0c..59f942b 100644
--- a/src/lib.rs
+++ b/src/lib.rs
-@@ -113,17 +113,11 @@ impl LogId {
+@@ -111,17 +111,11 @@ impl LogId {
/// Output log to android system.
#[cfg(target_os = "android")]
fn android_log(log_id: log_ffi::log_id_t, prio: log_ffi::LogPriority, tag: &CStr, msg: &CStr) {
@@ -37,5 +37,5 @@ index d21be3f..bc4fa61 100644
}
--
-2.35.1.574.g5d30c73bfb-goog
+2.39.0.rc0.267.gcb52ba06e7-goog
diff --git a/src/lib.rs b/src/lib.rs
index bc4fa61..c22f07e 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -13,13 +13,13 @@
//! #[macro_use] extern crate log;
//! extern crate android_logger;
//!
-//! use log::Level;
+//! use log::LevelFilter;
//! use android_logger::Config;
//!
//! /// Android code may not have obvious "main", this is just an example.
//! fn main() {
//! android_logger::init_once(
-//! Config::default().with_min_level(Level::Trace),
+//! Config::default().with_max_level(LevelFilter::Trace),
//! );
//!
//! debug!("this is a debug {}", "message");
@@ -36,13 +36,13 @@
//! #[macro_use] extern crate log;
//! extern crate android_logger;
//!
-//! use log::Level;
+//! use log::LevelFilter;
//! use android_logger::{Config,FilterBuilder};
//!
//! fn main() {
//! android_logger::init_once(
//! Config::default()
-//! .with_min_level(Level::Trace)
+//! .with_max_level(LevelFilter::Trace)
//! .with_tag("mytag")
//! .with_filter(FilterBuilder::new().parse("debug,hello::crate=trace").build()),
//! );
@@ -58,31 +58,29 @@
//!
//! android_logger::init_once(
//! Config::default()
-//! .with_min_level(log::Level::Trace)
+//! .with_max_level(log::LevelFilter::Trace)
//! .format(|f, record| write!(f, "my_app: {}", record.args()))
//! )
//! ```
#[cfg(target_os = "android")]
extern crate android_log_sys as log_ffi;
-#[macro_use]
-extern crate lazy_static;
+extern crate once_cell;
+use once_cell::sync::OnceCell;
#[macro_use]
extern crate log;
extern crate env_logger;
-use std::sync::RwLock;
-
+use log::{Level, LevelFilter, Log, Metadata, Record};
#[cfg(target_os = "android")]
use log_ffi::LogPriority;
-use log::{Level, Log, Metadata, Record};
use std::ffi::{CStr, CString};
-use std::mem;
use std::fmt;
+use std::mem::{self, MaybeUninit};
use std::ptr;
-pub use env_logger::filter::{Filter, Builder as FilterBuilder};
+pub use env_logger::filter::{Builder as FilterBuilder, Filter};
pub use env_logger::fmt::Formatter;
pub(crate) type FormatFn = Box<dyn Fn(&mut dyn fmt::Write, &Record) -> fmt::Result + Sync + Send>;
@@ -127,22 +125,24 @@ fn android_log(_log_id: Option<LogId>, _priority: Level, _tag: &CStr, _msg: &CSt
/// Underlying android logger backend
pub struct AndroidLogger {
- config: RwLock<Config>,
+ config: OnceCell<Config>,
}
impl AndroidLogger {
/// Create new logger instance from config
pub fn new(config: Config) -> AndroidLogger {
AndroidLogger {
- config: RwLock::new(config),
+ config: OnceCell::from(config),
}
}
-}
-lazy_static! {
- static ref ANDROID_LOGGER: AndroidLogger = AndroidLogger::default();
+ fn config(&self) -> &Config {
+ self.config.get_or_init(Config::default)
+ }
}
+static ANDROID_LOGGER: OnceCell<AndroidLogger> = OnceCell::new();
+
const LOGGING_TAG_MAX_LEN: usize = 23;
const LOGGING_MSG_MAX_LEN: usize = 4000;
@@ -150,34 +150,42 @@ impl Default for AndroidLogger {
/// Create a new logger with default config
fn default() -> AndroidLogger {
AndroidLogger {
- config: RwLock::new(Config::default()),
+ config: OnceCell::from(Config::default()),
}
}
}
impl Log for AndroidLogger {
- fn enabled(&self, _: &Metadata) -> bool {
- true
+ fn enabled(&self, metadata: &Metadata) -> bool {
+ let config = self.config();
+ // todo: consider __android_log_is_loggable.
+ metadata.level() <= config.log_level.unwrap_or_else(log::max_level)
}
fn log(&self, record: &Record) {
- let config = self.config
- .read()
- .expect("failed to acquire android_log filter lock for read");
+ let config = self.config();
+
+ if !self.enabled(record.metadata()) {
+ return;
+ }
+ // this also checks the level, but only if a filter was
+ // installed.
if !config.filter_matches(record) {
return;
}
// tag must not exceed LOGGING_TAG_MAX_LEN
- #[allow(deprecated)] // created an issue #35 for this
- let mut tag_bytes: [u8; LOGGING_TAG_MAX_LEN + 1] = unsafe { mem::uninitialized() };
+ let mut tag_bytes: [MaybeUninit<u8>; LOGGING_TAG_MAX_LEN + 1] = uninit_array();
let module_path = record.module_path().unwrap_or_default().to_owned();
// If no tag was specified, use module name
let custom_tag = &config.tag;
- let tag = custom_tag.as_ref().map(|s| s.as_bytes()).unwrap_or(module_path.as_bytes());
+ let tag = custom_tag
+ .as_ref()
+ .map(|s| s.as_bytes())
+ .unwrap_or_else(|| module_path.as_bytes());
// truncate the tag here to fit into LOGGING_TAG_MAX_LEN
self.fill_tag_bytes(&mut tag_bytes, tag);
@@ -207,53 +215,51 @@ impl Log for AndroidLogger {
}
impl AndroidLogger {
- fn fill_tag_bytes(&self, array: &mut [u8], tag: &[u8]) {
+ fn fill_tag_bytes(&self, array: &mut [MaybeUninit<u8>], tag: &[u8]) {
if tag.len() > LOGGING_TAG_MAX_LEN {
- for (input, output) in tag.iter()
+ for (input, output) in tag
+ .iter()
.take(LOGGING_TAG_MAX_LEN - 2)
.chain(b"..\0".iter())
.zip(array.iter_mut())
{
- *output = *input;
+ output.write(*input);
}
} else {
- for (input, output) in tag.iter()
- .chain(b"\0".iter())
- .zip(array.iter_mut())
- {
- *output = *input;
+ for (input, output) in tag.iter().chain(b"\0".iter()).zip(array.iter_mut()) {
+ output.write(*input);
}
}
}
}
/// Filter for android logger.
+#[derive(Default)]
pub struct Config {
- log_level: Option<Level>,
+ log_level: Option<LevelFilter>,
log_id: Option<LogId>,
filter: Option<env_logger::filter::Filter>,
tag: Option<CString>,
custom_format: Option<FormatFn>,
}
-impl Default for Config {
- fn default() -> Self {
- Config {
- log_level: None,
- log_id: None,
- filter: None,
- tag: None,
- custom_format: None,
- }
+impl Config {
+ // TODO: Remove on 0.13 version release.
+ /// **DEPRECATED**, use [`Config::with_max_level()`] instead.
+ #[deprecated(note = "use `.with_max_level()` instead")]
+ pub fn with_min_level(self, level: Level) -> Self {
+ self.with_max_level(level.to_level_filter())
}
-}
-impl Config {
- /// Change the minimum log level.
+ /// Changes the maximum log level.
///
- /// All values above the set level are logged. For example, if
- /// `Warn` is set, the `Error` is logged too, but `Info` isn't.
- pub fn with_min_level(mut self, level: Level) -> Self {
+ /// Note, that `Trace` is the maximum level, because it provides the
+ /// maximum amount of detail in the emitted logs.
+ ///
+ /// If `Off` level is provided, then nothing is logged at all.
+ ///
+ /// [`log::max_level()`] is considered as the default level.
+ pub fn with_max_level(mut self, level: LevelFilter) -> Self {
self.log_level = Some(level);
self
}
@@ -269,7 +275,7 @@ impl Config {
fn filter_matches(&self, record: &Record) -> bool {
if let Some(ref filter) = self.filter {
- filter.matches(&record)
+ filter.matches(record)
} else {
true
}
@@ -290,7 +296,7 @@ impl Config {
/// # use android_logger::Config;
/// android_logger::init_once(
/// Config::default()
- /// .with_min_level(log::Level::Trace)
+ /// .with_max_level(log::LevelFilter::Trace)
/// .format(|f, record| write!(f, "my_app: {}", record.args()))
/// )
/// ```
@@ -303,35 +309,46 @@ impl Config {
}
}
-struct PlatformLogWriter<'a> {
- #[cfg(target_os = "android")] priority: LogPriority,
- #[cfg(not(target_os = "android"))] priority: Level,
+pub struct PlatformLogWriter<'a> {
+ #[cfg(target_os = "android")]
+ priority: LogPriority,
+ #[cfg(not(target_os = "android"))]
+ priority: Level,
#[cfg(target_os = "android")] log_id: log_ffi::log_id_t,
#[cfg(not(target_os = "android"))] log_id: Option<LogId>,
len: usize,
last_newline_index: usize,
tag: &'a CStr,
- buffer: [u8; LOGGING_MSG_MAX_LEN + 1],
+ buffer: [MaybeUninit<u8>; LOGGING_MSG_MAX_LEN + 1],
}
impl<'a> PlatformLogWriter<'a> {
#[cfg(target_os = "android")]
- pub fn new(log_id: Option<LogId>, level: Level, tag: &CStr) -> PlatformLogWriter {
+ pub fn new_with_priority(log_id: Option<LogId>, priority: log_ffi::LogPriority, tag: &CStr) -> PlatformLogWriter {
#[allow(deprecated)] // created an issue #35 for this
PlatformLogWriter {
- priority: match level {
+ priority,
+ log_id: LogId::to_native(log_id),
+ len: 0,
+ last_newline_index: 0,
+ tag,
+ buffer: uninit_array(),
+ }
+ }
+
+ #[cfg(target_os = "android")]
+ pub fn new(log_id: Option<LogId>, level: Level, tag: &CStr) -> PlatformLogWriter {
+ Self::new_with_priority(
+ log_id,
+ match level {
Level::Warn => LogPriority::WARN,
Level::Info => LogPriority::INFO,
Level::Debug => LogPriority::DEBUG,
Level::Error => LogPriority::ERROR,
Level::Trace => LogPriority::VERBOSE,
},
- log_id: LogId::to_native(log_id),
- len: 0,
- last_newline_index: 0,
tag,
- buffer: unsafe { mem::uninitialized() },
- }
+ )
}
#[cfg(not(target_os = "android"))]
@@ -343,7 +360,7 @@ impl<'a> PlatformLogWriter<'a> {
len: 0,
last_newline_index: 0,
tag,
- buffer: unsafe { mem::uninitialized() },
+ buffer: uninit_array(),
}
}
@@ -375,7 +392,7 @@ impl<'a> PlatformLogWriter<'a> {
}
/// Flush everything remaining to android logger.
- fn flush(&mut self) {
+ pub fn flush(&mut self) {
let total_len = self.len;
if total_len == 0 {
@@ -389,21 +406,22 @@ impl<'a> PlatformLogWriter<'a> {
/// Output buffer up until the \0 which will be placed at `len` position.
fn output_specified_len(&mut self, len: usize) {
- let mut last_byte: u8 = b'\0';
+ let mut last_byte = MaybeUninit::new(b'\0');
+
mem::swap(&mut last_byte, unsafe {
self.buffer.get_unchecked_mut(len)
});
- let msg: &CStr = unsafe { CStr::from_ptr(mem::transmute(self.buffer.as_ptr())) };
+ let msg: &CStr = unsafe { CStr::from_ptr(self.buffer.as_ptr().cast()) };
android_log(self.log_id, self.priority, self.tag, msg);
- *unsafe { self.buffer.get_unchecked_mut(len) } = last_byte;
+ unsafe { *self.buffer.get_unchecked_mut(len) = last_byte };
}
/// Copy `len` bytes from `index` position to starting position.
fn copy_bytes_to_start(&mut self, index: usize, len: usize) {
- let src = unsafe { self.buffer.as_ptr().offset(index as isize) };
let dst = self.buffer.as_mut_ptr();
+ let src = unsafe { self.buffer.as_ptr().add(index) };
unsafe { ptr::copy(src, dst, len) };
}
}
@@ -422,7 +440,7 @@ impl<'a> fmt::Write for PlatformLogWriter<'a> {
.zip(incomming_bytes)
.enumerate()
.fold(None, |acc, (i, (output, input))| {
- *output = *input;
+ output.write(*input);
if *input == b'\n' {
Some(i)
} else {
@@ -460,7 +478,9 @@ impl<'a> fmt::Write for PlatformLogWriter<'a> {
/// This action does not require initialization. However, without initialization it
/// will use the default filter, which allows all logs.
pub fn log(record: &Record) {
- ANDROID_LOGGER.log(record)
+ ANDROID_LOGGER
+ .get_or_init(AndroidLogger::default)
+ .log(record)
}
/// Initializes the global logger with an android logger.
@@ -471,19 +491,22 @@ pub fn log(record: &Record) {
/// It is ok to call this at the activity creation, and it will be
/// repeatedly called on every lifecycle restart (i.e. screen rotation).
pub fn init_once(config: Config) {
- if let Err(err) = log::set_logger(&*ANDROID_LOGGER) {
+ let log_level = config.log_level;
+ let logger = ANDROID_LOGGER.get_or_init(|| AndroidLogger::new(config));
+
+ if let Err(err) = log::set_logger(logger) {
debug!("android_logger: log::set_logger failed: {}", err);
- } else {
- if let Some(level) = config.log_level {
- log::set_max_level(level.to_level_filter());
- }
- *ANDROID_LOGGER
- .config
- .write()
- .expect("failed to acquire android_log filter lock for write") = config;
+ } else if let Some(level) = log_level {
+ log::set_max_level(level);
}
}
+// FIXME: When `maybe_uninit_uninit_array ` is stabilized, use it instead of this helper
+fn uninit_array<const N: usize, T>() -> [MaybeUninit<T>; N] {
+ // SAFETY: Array contains MaybeUninit, which is fine to be uninit
+ unsafe { MaybeUninit::uninit().assume_init() }
+}
+
#[cfg(test)]
mod tests {
use super::*;
@@ -494,11 +517,11 @@ mod tests {
fn check_config_values() {
// Filter is checked in config_filter_match below.
let config = Config::default()
- .with_min_level(Level::Trace)
+ .with_max_level(LevelFilter::Trace)
.with_log_id(LogId::System)
.with_tag("my_app");
- assert_eq!(config.log_level, Some(Level::Trace));
+ assert_eq!(config.log_level, Some(LevelFilter::Trace));
assert_eq!(config.log_id, Some(LogId::System));
assert_eq!(config.tag, Some(CString::new("my_app").unwrap()));
}
@@ -507,7 +530,7 @@ mod tests {
fn log_calls_formatter() {
static FORMAT_FN_WAS_CALLED: AtomicBool = AtomicBool::new(false);
let config = Config::default()
- .with_min_level(Level::Info)
+ .with_max_level(LevelFilter::Info)
.format(|_, _| {
FORMAT_FN_WAS_CALLED.store(true, Ordering::SeqCst);
Ok(())
@@ -520,10 +543,12 @@ mod tests {
}
#[test]
- fn logger_always_enabled() {
- let logger = AndroidLogger::new(Config::default());
+ fn logger_enabled_threshold() {
+ let logger = AndroidLogger::new(Config::default().with_max_level(LevelFilter::Info));
- assert!(logger.enabled(&log::MetadataBuilder::new().build()));
+ assert!(logger.enabled(&log::MetadataBuilder::new().level(Level::Warn).build()));
+ assert!(logger.enabled(&log::MetadataBuilder::new().level(Level::Info).build()));
+ assert!(!logger.enabled(&log::MetadataBuilder::new().level(Level::Debug).build()));
}
// Test whether the filter gets called correctly. Not meant to be exhaustive for all filter
@@ -545,12 +570,12 @@ mod tests {
let logger = AndroidLogger::new(Config::default());
let too_long_tag: [u8; LOGGING_TAG_MAX_LEN + 20] = [b'a'; LOGGING_TAG_MAX_LEN + 20];
- let mut result: [u8; LOGGING_TAG_MAX_LEN + 1] = Default::default();
+ let mut result: [MaybeUninit<u8>; LOGGING_TAG_MAX_LEN + 1] = uninit_array();
logger.fill_tag_bytes(&mut result, &too_long_tag);
let mut expected_result = [b'a'; LOGGING_TAG_MAX_LEN - 2].to_vec();
expected_result.extend("..\0".as_bytes());
- assert_eq!(result.to_vec(), expected_result);
+ assert_eq!(unsafe { assume_init_slice(&result) }, expected_result);
}
#[test]
@@ -558,19 +583,19 @@ mod tests {
let logger = AndroidLogger::new(Config::default());
let short_tag: [u8; 3] = [b'a'; 3];
- let mut result: [u8; LOGGING_TAG_MAX_LEN + 1] = Default::default();
+ let mut result: [MaybeUninit<u8>; LOGGING_TAG_MAX_LEN + 1] = uninit_array();
logger.fill_tag_bytes(&mut result, &short_tag);
let mut expected_result = short_tag.to_vec();
expected_result.push(0);
- assert_eq!(result.to_vec()[..4], expected_result);
+ assert_eq!(unsafe { assume_init_slice(&result[..4]) }, expected_result);
}
#[test]
fn platform_log_writer_init_values() {
let tag = CStr::from_bytes_with_nul(b"tag\0").unwrap();
- let writer = PlatformLogWriter::new(None, Level::Warn, &tag);
+ let writer = PlatformLogWriter::new(None, Level::Warn, tag);
assert_eq!(writer.tag, tag);
// Android uses LogPriority instead, which doesn't implement equality checks
@@ -591,7 +616,10 @@ mod tests {
// Should have flushed up until the last newline.
assert_eq!(writer.len, 3);
assert_eq!(writer.last_newline_index, 0);
- assert_eq!(&writer.buffer.to_vec()[..writer.len], "\n90".as_bytes());
+ assert_eq!(
+ unsafe { assume_init_slice(&writer.buffer[..writer.len]) },
+ "\n90".as_bytes()
+ );
writer.temporal_flush();
// Should have flushed all remaining bytes.
@@ -634,7 +662,7 @@ mod tests {
writer.output_specified_len(5);
assert_eq!(
- writer.buffer[..log_string.len()].to_vec(),
+ unsafe { assume_init_slice(&writer.buffer[..log_string.len()]) },
log_string.as_bytes()
);
}
@@ -648,7 +676,10 @@ mod tests {
writer.copy_bytes_to_start(3, 2);
- assert_eq!(writer.buffer[..10].to_vec(), "3423456789".as_bytes());
+ assert_eq!(
+ unsafe { assume_init_slice(&writer.buffer[..10]) },
+ "3423456789".as_bytes()
+ );
}
#[test]
@@ -663,12 +694,16 @@ mod tests {
writer.copy_bytes_to_start(10, 0);
assert_eq!(
- writer.buffer[..test_string.len()].to_vec(),
+ unsafe { assume_init_slice(&writer.buffer[..test_string.len()]) },
test_string.as_bytes()
);
}
fn get_tag_writer() -> PlatformLogWriter<'static> {
- PlatformLogWriter::new(None, Level::Warn, &CStr::from_bytes_with_nul(b"tag\0").unwrap())
+ PlatformLogWriter::new(None, Level::Warn, CStr::from_bytes_with_nul(b"tag\0").unwrap())
+ }
+
+ unsafe fn assume_init_slice<T>(slice: &[MaybeUninit<T>]) -> &[T] {
+ &*(slice as *const [MaybeUninit<T>] as *const [T])
}
}
diff --git a/tests/config_log_level.rs b/tests/config_log_level.rs
index ca6ad59..864b229 100644
--- a/tests/config_log_level.rs
+++ b/tests/config_log_level.rs
@@ -3,7 +3,9 @@ extern crate log;
#[test]
fn config_log_level() {
- android_logger::init_once(android_logger::Config::default().with_min_level(log::Level::Trace));
+ android_logger::init_once(
+ android_logger::Config::default().with_max_level(log::LevelFilter::Trace),
+ );
assert_eq!(log::max_level(), log::LevelFilter::Trace);
-} \ No newline at end of file
+}
diff --git a/tests/default_init.rs b/tests/default_init.rs
index e7ca9e2..7b04c24 100644
--- a/tests/default_init.rs
+++ b/tests/default_init.rs
@@ -7,4 +7,4 @@ fn default_init() {
// android_logger has default log level "off"
assert_eq!(log::max_level(), log::LevelFilter::Off);
-} \ No newline at end of file
+}
diff --git a/tests/multiple_init.rs b/tests/multiple_init.rs
index 99b58c8..26f815d 100644
--- a/tests/multiple_init.rs
+++ b/tests/multiple_init.rs
@@ -3,10 +3,14 @@ extern crate log;
#[test]
fn multiple_init() {
- android_logger::init_once(android_logger::Config::default().with_min_level(log::Level::Trace));
+ android_logger::init_once(
+ android_logger::Config::default().with_max_level(log::LevelFilter::Trace),
+ );
// Second initialization should be silently ignored
- android_logger::init_once(android_logger::Config::default().with_min_level(log::Level::Error));
+ android_logger::init_once(
+ android_logger::Config::default().with_max_level(log::LevelFilter::Error),
+ );
assert_eq!(log::max_level(), log::LevelFilter::Trace);
-} \ No newline at end of file
+}