1 // Copyright 2020 The Chromium OS Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 //! Implementation of the Syslog trait as a wrapper around Android's logging library, liblog.
6
7 extern crate android_log_sys;
8
9 use super::super::syslog::{Error, Facility, Priority, Syslog};
10 use android_log_sys::{
11 __android_log_is_loggable, __android_log_message, __android_log_write_log_message, log_id_t,
12 LogPriority,
13 };
14 use std::{
15 ffi::{CString, NulError},
16 fmt,
17 mem::size_of,
18 os::unix::io::RawFd,
19 };
20
21 pub struct PlatformSyslog {
22 enabled: bool,
23 }
24
25 impl Syslog for PlatformSyslog {
new() -> Result<Self, Error>26 fn new() -> Result<Self, Error> {
27 Ok(Self { enabled: true })
28 }
29
enable(&mut self, enable: bool) -> Result<(), Error>30 fn enable(&mut self, enable: bool) -> Result<(), Error> {
31 self.enabled = enable;
32 Ok(())
33 }
34
push_fds(&self, _fds: &mut Vec<RawFd>)35 fn push_fds(&self, _fds: &mut Vec<RawFd>) {}
36
log( &self, proc_name: Option<&str>, pri: Priority, _fac: Facility, file_line: Option<(&str, u32)>, args: fmt::Arguments, )37 fn log(
38 &self,
39 proc_name: Option<&str>,
40 pri: Priority,
41 _fac: Facility,
42 file_line: Option<(&str, u32)>,
43 args: fmt::Arguments,
44 ) {
45 let priority = match pri {
46 Priority::Emergency => LogPriority::ERROR,
47 Priority::Alert => LogPriority::ERROR,
48 Priority::Critical => LogPriority::ERROR,
49 Priority::Error => LogPriority::ERROR,
50 Priority::Warning => LogPriority::WARN,
51 Priority::Notice => LogPriority::INFO,
52 Priority::Info => LogPriority::DEBUG,
53 Priority::Debug => LogPriority::VERBOSE,
54 };
55 let tag = proc_name.unwrap_or("crosvm");
56 let message = std::fmt::format(args);
57 let _ = android_log(
58 log_id_t::SYSTEM,
59 priority,
60 tag,
61 file_line.map(|(file, _)| file),
62 file_line.map(|(_, line)| line),
63 &message,
64 );
65 }
66 }
67
68 /// Send a log message to the Android logger (logd, by default) if it is currently configured to be
69 /// loggable based on the priority and tag.
70 ///
71 /// # Arguments
72 /// * `priority` - The Android log priority. Used to determine whether the message is loggable.
73 /// * `tag` - A tag to indicate where the log comes from.
74 /// * `file` - The name of the file from where the message is being logged, if available.
75 /// * `line` - The line number from where the message is being logged, if available.
76 /// * `message` - The message to log.
android_log( buffer_id: log_id_t, priority: LogPriority, tag: &str, file: Option<&str>, line: Option<u32>, message: &str, ) -> Result<(), NulError>77 fn android_log(
78 buffer_id: log_id_t,
79 priority: LogPriority,
80 tag: &str,
81 file: Option<&str>,
82 line: Option<u32>,
83 message: &str,
84 ) -> Result<(), NulError> {
85 let tag = CString::new(tag)?;
86 let default_pri = LogPriority::VERBOSE;
87 if unsafe { __android_log_is_loggable(priority as i32, tag.as_ptr(), default_pri as i32) } != 0
88 {
89 let c_file_name = match file {
90 Some(file_name) => CString::new(file_name)?.as_ptr(),
91 None => std::ptr::null(),
92 };
93 let line = line.unwrap_or(0);
94 let message = CString::new(message)?;
95 let mut log_message = __android_log_message {
96 struct_size: size_of::<__android_log_message>(),
97 buffer_id: buffer_id as i32,
98 priority: priority as i32,
99 tag: tag.as_ptr(),
100 file: c_file_name,
101 line,
102 message: message.as_ptr(),
103 };
104 unsafe { __android_log_write_log_message(&mut log_message) };
105 }
106 Ok(())
107 }
108