Skip to content

Commit fee1bea

Browse files
rsglobalrandomPoisontyranron
authored
Support selecting target buffer of Android logging system (#50, #64)
- add `LogId` enum to identify the different log buffers - add `buf_id` argument to `PlatformLogWriter::new()` - add `Config::with_log_buffer()` allowing to specify target buffer Co-authored-by: David LeGare <[email protected]> Co-authored-by: Kai Ren <[email protected]>
1 parent 9398978 commit fee1bea

File tree

3 files changed

+111
-14
lines changed

3 files changed

+111
-14
lines changed

CHANGELOG.md

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,25 @@ All user visible changes to this project will be documented in this file. This p
66

77

88

9+
## [0.13.0] · 2023-02-??
10+
[0.13.0]: /../../tree/v0.13.0
11+
12+
[Diff](/../../compare/v0.12.0...v0.13.0)
13+
14+
### BC Breaks
15+
16+
- Added `buf_id` argument to `PlatformLogWriter::new()` method allowing to specify concrete Android logging system buffer. ([#50], [#64])
17+
18+
### Added
19+
20+
- `Config::with_log_buffer()` method to specify concrete Android logging system buffer. ([#50], [#64])
21+
22+
[#50]: /../../pull/50
23+
[#64]: /../../pull/64
24+
25+
26+
27+
928
## [0.12.0] · 2023-01-19
1029
[0.12.0]: /../../tree/v0.12.0
1130

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ once_cell = "1.9"
2222
version = "0.4"
2323

2424
[dependencies.android_log-sys]
25-
version = "0.2"
25+
version = "0.3"
2626

2727
[dependencies.env_logger]
2828
version = "0.10"

src/lib.rs

Lines changed: 91 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -85,21 +85,70 @@ pub use env_logger::fmt::Formatter;
8585

8686
pub(crate) type FormatFn = Box<dyn Fn(&mut dyn fmt::Write, &Record) -> fmt::Result + Sync + Send>;
8787

88-
/// Output log to android system.
88+
/// Possible identifiers of a specific buffer of Android logging system for
89+
/// logging a message.
90+
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
91+
pub enum LogId {
92+
/// Main log buffer.
93+
///
94+
/// This is the only log buffer available to apps.
95+
Main,
96+
97+
/// Radio log buffer.
98+
Radio,
99+
100+
/// Event log buffer.
101+
Events,
102+
103+
/// System log buffer.
104+
System,
105+
106+
/// Crash log buffer.
107+
Crash,
108+
109+
/// Kernel log buffer.
110+
Kernel,
111+
112+
/// Security log buffer.
113+
Security,
114+
115+
/// Statistics log buffer.
116+
Stats,
117+
}
118+
89119
#[cfg(target_os = "android")]
90-
fn android_log(prio: log_ffi::LogPriority, tag: &CStr, msg: &CStr) {
120+
impl LogId {
121+
fn to_native(log_id: Option<Self>) -> log_ffi::log_id_t {
122+
match log_id {
123+
Some(Self::Main) => log_ffi::log_id_t::MAIN,
124+
Some(Self::Radio) => log_ffi::log_id_t::RADIO,
125+
Some(Self::Events) => log_ffi::log_id_t::EVENTS,
126+
Some(Self::System) => log_ffi::log_id_t::SYSTEM,
127+
Some(Self::Crash) => log_ffi::log_id_t::CRASH,
128+
Some(Self::Kernel) => log_ffi::log_id_t::KERNEL,
129+
Some(Self::Security) => log_ffi::log_id_t::SECURITY,
130+
Some(Self::Stats) => log_ffi::log_id_t::STATS,
131+
None => log_ffi::log_id_t::DEFAULT,
132+
}
133+
}
134+
}
135+
136+
/// Outputs log to Android system.
137+
#[cfg(target_os = "android")]
138+
fn android_log(buf_id: log_ffi::log_id_t, prio: log_ffi::LogPriority, tag: &CStr, msg: &CStr) {
91139
unsafe {
92-
log_ffi::__android_log_write(
140+
log_ffi::__android_log_buf_write(
141+
buf_id as log_ffi::c_int,
93142
prio as log_ffi::c_int,
94143
tag.as_ptr() as *const log_ffi::c_char,
95144
msg.as_ptr() as *const log_ffi::c_char,
96-
)
145+
);
97146
};
98147
}
99148

100149
/// Dummy output placeholder for tests.
101150
#[cfg(not(target_os = "android"))]
102-
fn android_log(_priority: Level, _tag: &CStr, _msg: &CStr) {}
151+
fn android_log(_buf_id: Option<LogId>, _priority: Level, _tag: &CStr, _msg: &CStr) {}
103152

104153
/// Underlying android logger backend
105154
pub struct AndroidLogger {
@@ -172,7 +221,7 @@ impl Log for AndroidLogger {
172221

173222
// message must not exceed LOGGING_MSG_MAX_LEN
174223
// therefore split log message into multiple log calls
175-
let mut writer = PlatformLogWriter::new(record.level(), tag);
224+
let mut writer = PlatformLogWriter::new(config.buf_id, record.level(), tag);
176225

177226
// If a custom tag is used, add the module path to the message.
178227
// Use PlatformLogWriter to output chunks if they exceed max size.
@@ -215,6 +264,7 @@ impl AndroidLogger {
215264
#[derive(Default)]
216265
pub struct Config {
217266
log_level: Option<LevelFilter>,
267+
buf_id: Option<LogId>,
218268
filter: Option<env_logger::filter::Filter>,
219269
tag: Option<CString>,
220270
custom_format: Option<FormatFn>,
@@ -241,6 +291,17 @@ impl Config {
241291
self
242292
}
243293

294+
/// Changes the Android logging system buffer to be used.
295+
///
296+
/// By default, logs are sent to the [`Main`] log. Other logging buffers may
297+
/// only be accessible to certain processes.
298+
///
299+
/// [`Main`]: LogId::Main
300+
pub fn with_log_buffer(mut self, buf_id: LogId) -> Self {
301+
self.buf_id = Some(buf_id);
302+
self
303+
}
304+
244305
fn filter_matches(&self, record: &Record) -> bool {
245306
if let Some(ref filter) = self.filter {
246307
filter.matches(record)
@@ -282,6 +343,10 @@ pub struct PlatformLogWriter<'a> {
282343
priority: LogPriority,
283344
#[cfg(not(target_os = "android"))]
284345
priority: Level,
346+
#[cfg(target_os = "android")]
347+
buf_id: log_ffi::log_id_t,
348+
#[cfg(not(target_os = "android"))]
349+
buf_id: Option<LogId>,
285350
len: usize,
286351
last_newline_index: usize,
287352
tag: &'a CStr,
@@ -290,10 +355,15 @@ pub struct PlatformLogWriter<'a> {
290355

291356
impl<'a> PlatformLogWriter<'a> {
292357
#[cfg(target_os = "android")]
293-
pub fn new_with_priority(priority: log_ffi::LogPriority, tag: &CStr) -> PlatformLogWriter {
358+
pub fn new_with_priority(
359+
buf_id: Option<LogId>,
360+
priority: log_ffi::LogPriority,
361+
tag: &CStr,
362+
) -> PlatformLogWriter<'_> {
294363
#[allow(deprecated)] // created an issue #35 for this
295364
PlatformLogWriter {
296365
priority,
366+
buf_id: LogId::to_native(buf_id),
297367
len: 0,
298368
last_newline_index: 0,
299369
tag,
@@ -302,8 +372,9 @@ impl<'a> PlatformLogWriter<'a> {
302372
}
303373

304374
#[cfg(target_os = "android")]
305-
pub fn new(level: Level, tag: &CStr) -> PlatformLogWriter {
306-
Self::new_with_priority(
375+
pub fn new(buf_id: Option<LogId>, level: Level, tag: &CStr) -> PlatformLogWriter<'_> {
376+
PlatformLogWriter::new_with_priority(
377+
buf_id,
307378
match level {
308379
Level::Warn => LogPriority::WARN,
309380
Level::Info => LogPriority::INFO,
@@ -316,10 +387,11 @@ impl<'a> PlatformLogWriter<'a> {
316387
}
317388

318389
#[cfg(not(target_os = "android"))]
319-
pub fn new(level: Level, tag: &CStr) -> PlatformLogWriter {
390+
pub fn new(buf_id: Option<LogId>, level: Level, tag: &CStr) -> PlatformLogWriter<'_> {
320391
#[allow(deprecated)] // created an issue #35 for this
321392
PlatformLogWriter {
322393
priority: level,
394+
buf_id,
323395
len: 0,
324396
last_newline_index: 0,
325397
tag,
@@ -376,7 +448,7 @@ impl<'a> PlatformLogWriter<'a> {
376448
});
377449

378450
let msg: &CStr = unsafe { CStr::from_ptr(self.buffer.as_ptr().cast()) };
379-
android_log(self.priority, self.tag, msg);
451+
android_log(self.buf_id, self.priority, self.tag, msg);
380452

381453
unsafe { *self.buffer.get_unchecked_mut(len) = last_byte };
382454
}
@@ -481,9 +553,11 @@ mod tests {
481553
// Filter is checked in config_filter_match below.
482554
let config = Config::default()
483555
.with_max_level(LevelFilter::Trace)
556+
.with_log_buffer(LogId::System)
484557
.with_tag("my_app");
485558

486559
assert_eq!(config.log_level, Some(LevelFilter::Trace));
560+
assert_eq!(config.buf_id, Some(LogId::System));
487561
assert_eq!(config.tag, Some(CString::new("my_app").unwrap()));
488562
}
489563

@@ -556,7 +630,7 @@ mod tests {
556630
fn platform_log_writer_init_values() {
557631
let tag = CStr::from_bytes_with_nul(b"tag\0").unwrap();
558632

559-
let writer = PlatformLogWriter::new(Level::Warn, tag);
633+
let writer = PlatformLogWriter::new(None, Level::Warn, tag);
560634

561635
assert_eq!(writer.tag, tag);
562636
// Android uses LogPriority instead, which doesn't implement equality checks
@@ -661,7 +735,11 @@ mod tests {
661735
}
662736

663737
fn get_tag_writer() -> PlatformLogWriter<'static> {
664-
PlatformLogWriter::new(Level::Warn, CStr::from_bytes_with_nul(b"tag\0").unwrap())
738+
PlatformLogWriter::new(
739+
None,
740+
Level::Warn,
741+
CStr::from_bytes_with_nul(b"tag\0").unwrap(),
742+
)
665743
}
666744

667745
unsafe fn assume_init_slice<T>(slice: &[MaybeUninit<T>]) -> &[T] {

0 commit comments

Comments
 (0)