1 //! Expose some internal methods to set the log level for system syslog.
2 //!
3 //! On systems that use syslog (i.e. `vlog_syslog.cc`), there is support
4 //! to filter out logs before they go to syslog. This module provides Rust apis
5 //! to tune log levels for syslog.
6 
7 use num_derive::{FromPrimitive, ToPrimitive};
8 use num_traits::cast::ToPrimitive;
9 use std::ffi::CString;
10 use std::os::raw::c_char;
11 
12 #[derive(FromPrimitive, ToPrimitive, Debug, Clone, Copy, PartialEq)]
13 #[repr(u8)]
14 /// Android framework log priority levels.
15 /// They are defined in system/logging/liblog/include/android/log.h by
16 /// the Android Framework code.
17 pub enum Level {
18     Verbose = 2,
19     Debug = 3,
20     Info = 4,
21     Warn = 5,
22     Error = 6,
23     Fatal = 7,
24 }
25 
26 impl From<Level> for i32 {
from(item: Level) -> Self27     fn from(item: Level) -> Self {
28         item.to_i32().unwrap_or(4)
29     }
30 }
31 
32 impl From<Level> for u8 {
from(item: Level) -> Self33     fn from(item: Level) -> Self {
34         item.to_u8().unwrap_or(4)
35     }
36 }
37 
38 impl Default for Level {
default() -> Self39     fn default() -> Self {
40         Level::Info
41     }
42 }
43 
44 // Defined in syslog linkage. See |vlog_syslog.cc|.
45 extern "C" {
SetLogLevelForTag(tag: *const c_char, level: u8)46     fn SetLogLevelForTag(tag: *const c_char, level: u8);
SetDefaultLogLevel(level: u8)47     fn SetDefaultLogLevel(level: u8);
48 }
49 
50 /// Set a default level value for failed |level.to_u8()| of |Level::Info|.
51 const DEFAULT_LEVEL: u8 = 4;
52 
53 /// Set the level of logs which will get printed for the given tag.
54 ///
55 /// Args:
56 ///     tag - LOG_TAG for the system module that's logging.
57 ///     level - Minimum log level that will be sent to syslog.
set_log_level_for_tag(tag: &str, level: Level)58 pub fn set_log_level_for_tag(tag: &str, level: Level) {
59     let cstr: CString = CString::new(tag).expect("CString::new failed on log tag");
60 
61     unsafe {
62         SetLogLevelForTag(cstr.as_ptr(), level.to_u8().unwrap_or(DEFAULT_LEVEL));
63     }
64 }
65 
66 /// Set the default log level for log tags. Will be overridden by any tag specific levels.
67 ///
68 /// Args:
69 ///     level - Minimum log level that will be sent to syslog.
set_default_log_level(level: Level)70 pub fn set_default_log_level(level: Level) {
71     unsafe {
72         SetDefaultLogLevel(level.to_u8().unwrap_or(DEFAULT_LEVEL));
73     }
74 }
75