Skip to content

Commit 44c50e8

Browse files
randomPoisonrsglobal
authored andcommitted
Support selecting target buffer
* Add `LogId` enum to identify the different log buffers. * Add an argument to `PlatformLogWriter::new` to allow a target buffer to be specified. * Update `Config` to allow specifying a target buffer.
1 parent 9398978 commit 44c50e8

2 files changed

Lines changed: 89 additions & 14 deletions

File tree

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: 88 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -85,21 +85,69 @@ 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+
/// Identifies a specific log buffer to use when logging a message.
89+
#[derive(Copy, Clone, Eq, PartialEq, Debug)]
90+
pub enum LogId {
91+
/// The main log buffer.
92+
///
93+
/// This is the only log buffer available to apps.
94+
Main,
95+
96+
/// The radio log buffer.
97+
Radio,
98+
99+
/// The event log buffer.
100+
Events,
101+
102+
/// The system log buffer.
103+
System,
104+
105+
/// The crash log buffer.
106+
Crash,
107+
108+
/// The kernel log buffer.
109+
Kernel,
110+
111+
/// The security log buffer.
112+
Security,
113+
114+
/// The statistics log buffer.
115+
Stats,
116+
}
117+
118+
impl LogId {
119+
#[cfg(target_os = "android")]
120+
fn to_native(log_id: Option<Self>) -> log_ffi::log_id_t {
121+
match log_id {
122+
Some(LogId::Main) => log_ffi::log_id_t::MAIN,
123+
Some(LogId::Radio) => log_ffi::log_id_t::RADIO,
124+
Some(LogId::Events) => log_ffi::log_id_t::EVENTS,
125+
Some(LogId::System) => log_ffi::log_id_t::SYSTEM,
126+
Some(LogId::Crash) => log_ffi::log_id_t::CRASH,
127+
Some(LogId::Kernel) => log_ffi::log_id_t::KERNEL,
128+
Some(LogId::Security) => log_ffi::log_id_t::SECURITY,
129+
Some(LogId::Stats) => log_ffi::log_id_t::STATS,
130+
None => log_ffi::log_id_t::DEFAULT,
131+
}
132+
}
133+
}
134+
88135
/// Output log to android system.
89136
#[cfg(target_os = "android")]
90-
fn android_log(prio: log_ffi::LogPriority, tag: &CStr, msg: &CStr) {
137+
fn android_log(log_id: log_ffi::log_id_t, prio: log_ffi::LogPriority, tag: &CStr, msg: &CStr) {
91138
unsafe {
92-
log_ffi::__android_log_write(
93-
prio as log_ffi::c_int,
139+
log_ffi::__android_log_buf_write(
140+
log_id as i32,
141+
prio as i32,
94142
tag.as_ptr() as *const log_ffi::c_char,
95143
msg.as_ptr() as *const log_ffi::c_char,
96-
)
144+
);
97145
};
98146
}
99147

100148
/// Dummy output placeholder for tests.
101149
#[cfg(not(target_os = "android"))]
102-
fn android_log(_priority: Level, _tag: &CStr, _msg: &CStr) {}
150+
fn android_log(_log_id: Option<LogId>, _priority: Level, _tag: &CStr, _msg: &CStr) {}
103151

104152
/// Underlying android logger backend
105153
pub struct AndroidLogger {
@@ -172,7 +220,7 @@ impl Log for AndroidLogger {
172220

173221
// message must not exceed LOGGING_MSG_MAX_LEN
174222
// therefore split log message into multiple log calls
175-
let mut writer = PlatformLogWriter::new(record.level(), tag);
223+
let mut writer = PlatformLogWriter::new(config.log_id, record.level(), tag);
176224

177225
// If a custom tag is used, add the module path to the message.
178226
// Use PlatformLogWriter to output chunks if they exceed max size.
@@ -215,6 +263,7 @@ impl AndroidLogger {
215263
#[derive(Default)]
216264
pub struct Config {
217265
log_level: Option<LevelFilter>,
266+
log_id: Option<LogId>,
218267
filter: Option<env_logger::filter::Filter>,
219268
tag: Option<CString>,
220269
custom_format: Option<FormatFn>,
@@ -241,6 +290,15 @@ impl Config {
241290
self
242291
}
243292

293+
/// Change which log buffer is used
294+
///
295+
/// By default, logs are sent to the `Main` log. Other logging buffers may only be accessible
296+
/// to certain processes.
297+
pub fn with_log_id(mut self, log_id: LogId) -> Self {
298+
self.log_id = Some(log_id);
299+
self
300+
}
301+
244302
fn filter_matches(&self, record: &Record) -> bool {
245303
if let Some(ref filter) = self.filter {
246304
filter.matches(record)
@@ -282,6 +340,10 @@ pub struct PlatformLogWriter<'a> {
282340
priority: LogPriority,
283341
#[cfg(not(target_os = "android"))]
284342
priority: Level,
343+
#[cfg(target_os = "android")]
344+
log_id: log_ffi::log_id_t,
345+
#[cfg(not(target_os = "android"))]
346+
log_id: Option<LogId>,
285347
len: usize,
286348
last_newline_index: usize,
287349
tag: &'a CStr,
@@ -290,9 +352,14 @@ pub struct PlatformLogWriter<'a> {
290352

291353
impl<'a> PlatformLogWriter<'a> {
292354
#[cfg(target_os = "android")]
293-
pub fn new_with_priority(priority: log_ffi::LogPriority, tag: &CStr) -> PlatformLogWriter {
355+
pub fn new_with_priority(
356+
log_id: Option<LogId>,
357+
priority: log_ffi::LogPriority,
358+
tag: &CStr,
359+
) -> PlatformLogWriter {
294360
#[allow(deprecated)] // created an issue #35 for this
295361
PlatformLogWriter {
362+
log_id: LogId::to_native(log_id),
296363
priority,
297364
len: 0,
298365
last_newline_index: 0,
@@ -302,8 +369,9 @@ impl<'a> PlatformLogWriter<'a> {
302369
}
303370

304371
#[cfg(target_os = "android")]
305-
pub fn new(level: Level, tag: &CStr) -> PlatformLogWriter {
372+
pub fn new(log_id: Option<LogId>, level: Level, tag: &CStr) -> PlatformLogWriter {
306373
Self::new_with_priority(
374+
log_id,
307375
match level {
308376
Level::Warn => LogPriority::WARN,
309377
Level::Info => LogPriority::INFO,
@@ -316,10 +384,11 @@ impl<'a> PlatformLogWriter<'a> {
316384
}
317385

318386
#[cfg(not(target_os = "android"))]
319-
pub fn new(level: Level, tag: &CStr) -> PlatformLogWriter {
387+
pub fn new(log_id: Option<LogId>, level: Level, tag: &CStr) -> PlatformLogWriter {
320388
#[allow(deprecated)] // created an issue #35 for this
321389
PlatformLogWriter {
322390
priority: level,
391+
log_id,
323392
len: 0,
324393
last_newline_index: 0,
325394
tag,
@@ -375,8 +444,8 @@ impl<'a> PlatformLogWriter<'a> {
375444
self.buffer.get_unchecked_mut(len)
376445
});
377446

378-
let msg: &CStr = unsafe { CStr::from_ptr(self.buffer.as_ptr().cast()) };
379-
android_log(self.priority, self.tag, msg);
447+
let msg: &CStr = unsafe { CStr::from_ptr(mem::transmute(self.buffer.as_ptr())) };
448+
android_log(self.log_id, self.priority, self.tag, msg);
380449

381450
unsafe { *self.buffer.get_unchecked_mut(len) = last_byte };
382451
}
@@ -481,9 +550,11 @@ mod tests {
481550
// Filter is checked in config_filter_match below.
482551
let config = Config::default()
483552
.with_max_level(LevelFilter::Trace)
553+
.with_log_id(LogId::System)
484554
.with_tag("my_app");
485555

486556
assert_eq!(config.log_level, Some(LevelFilter::Trace));
557+
assert_eq!(config.log_id, Some(LogId::System));
487558
assert_eq!(config.tag, Some(CString::new("my_app").unwrap()));
488559
}
489560

@@ -556,7 +627,7 @@ mod tests {
556627
fn platform_log_writer_init_values() {
557628
let tag = CStr::from_bytes_with_nul(b"tag\0").unwrap();
558629

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

561632
assert_eq!(writer.tag, tag);
562633
// Android uses LogPriority instead, which doesn't implement equality checks
@@ -661,7 +732,11 @@ mod tests {
661732
}
662733

663734
fn get_tag_writer() -> PlatformLogWriter<'static> {
664-
PlatformLogWriter::new(Level::Warn, CStr::from_bytes_with_nul(b"tag\0").unwrap())
735+
PlatformLogWriter::new(
736+
None,
737+
Level::Warn,
738+
CStr::from_bytes_with_nul(b"tag\0").unwrap(),
739+
)
665740
}
666741

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

0 commit comments

Comments
 (0)