diff options
author | Jiyong Park <jiyong@google.com> | 2021-06-23 02:12:10 +0000 |
---|---|---|
committer | Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com> | 2021-06-23 02:12:10 +0000 |
commit | ebad4320b36da9698d6ef22185839e2aff5a680b (patch) | |
tree | fa72127b3c83c381efdb91cb30f750a586b66295 | |
parent | aad8ae1c2c3b2280ab21be37c7b07149efeb7b9f (diff) | |
parent | d7178e8a4e3e5f7ca00249ce8244b96d12eb217f (diff) | |
download | kernlog-ebad4320b36da9698d6ef22185839e2aff5a680b.tar.gz |
Import kernlog 0.3.1 am: d7178e8a4e
Original change: https://android-review.googlesource.com/c/platform/external/rust/crates/kernlog/+/1742973
Change-Id: I0f77988129215cec4dc9617999bb18d32393493e
-rw-r--r-- | Android.bp | 22 | ||||
-rw-r--r-- | Cargo.toml | 15 | ||||
-rw-r--r-- | LICENSE | 21 | ||||
-rw-r--r-- | METADATA | 17 | ||||
-rw-r--r-- | MODULE_LICENSE_MIT | 0 | ||||
-rw-r--r-- | OWNERS | 1 | ||||
-rw-r--r-- | README.md | 35 | ||||
-rw-r--r-- | src/lib.rs | 175 |
8 files changed, 286 insertions, 0 deletions
diff --git a/Android.bp b/Android.bp new file mode 100644 index 0000000..bb2a55a --- /dev/null +++ b/Android.bp @@ -0,0 +1,22 @@ +// This file is generated by cargo2android.py --run --device --dependencies. +// Do not modify this file as changes will be overridden on upgrade. + + + +rust_library { + name: "libkernlog", + // has rustc warnings + host_supported: true, + crate_name: "kernlog", + srcs: ["src/lib.rs"], + edition: "2018", + rustlibs: [ + "liblibc", + "liblog_rust", + ], +} + +// dependent_library ["feature_list"] +// cfg-if-1.0.0 +// libc-0.2.97 "default,std" +// log-0.4.14 "std" diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..480748d --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,15 @@ +[package] +name = "kernlog" +version = "0.3.1" +description = "Kernel logger implementation (for low level logging to `/dev/kmsg`)." +authors = ["Konstantin Stepanov <me@kstep.me>"] +readme = "README.md" +repository = "https://github.com/kstep/kernlog.rs.git" +documentation = "http://kstep.me/kernlog.rs/kernlog/index.html" +license = "MIT" +keywords = ["kmsg", "log", "logger", "kernel", "dmesg"] +edition = "2018" + +[dependencies] +log = { version = "0.4", features = ["std"] } +libc = "0.2" @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2020 Konstantin Stepanov + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/METADATA b/METADATA new file mode 100644 index 0000000..a38c76c --- /dev/null +++ b/METADATA @@ -0,0 +1,17 @@ +name: "kernlog" +description: + "Logger implementation for low level kernel log" + +third_party { + url { + type: HOMEPAGE + value: "https://crates.io/crates/kernlog/" + } + url { + type: GIT + value: "https://github.com/kstep/kernlog.rs" + } + version: "0.3.1" + last_upgrade_date { year: 2021 month: 6 day: 8 } + license_type: NOTICE +} diff --git a/MODULE_LICENSE_MIT b/MODULE_LICENSE_MIT new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/MODULE_LICENSE_MIT @@ -0,0 +1 @@ +include platform/prebuilts/rust:/OWNERS diff --git a/README.md b/README.md new file mode 100644 index 0000000..36c7870 --- /dev/null +++ b/README.md @@ -0,0 +1,35 @@ +# Kernel logger for Rust + +Logger implementation for low level kernel log (using `/dev/kmsg`) + +Usually intended for low level implementations, like [systemd generators][1], +which have to use `/dev/kmsg`: + +> Since syslog is not available (see above) write log messages to /dev/kmsg instead. + +[Full documentation.][2] + +[1]: http://www.freedesktop.org/wiki/Software/systemd/Generators/ +[2]: http://kstep.me/kernlog.rs/kernlog/index.html + +## Usage + +```toml +[dependencies] +log = "0.4" +kernlog = "0.3" +``` + +```rust +#[macro_use] +extern crate log; +extern crate kernlog; + +fn main() { + kernlog::init().unwrap(); + warn!("something strange happened"); +} +``` + +Note you have to have permissions to write to `/dev/kmsg`, +which normal users (not root) usually don't. diff --git a/src/lib.rs b/src/lib.rs new file mode 100644 index 0000000..157c43d --- /dev/null +++ b/src/lib.rs @@ -0,0 +1,175 @@ +//! Logger implementation for low level kernel log (using `/dev/kmsg`) +//! +//! Usually intended for low level implementations, like [systemd generators][1], +//! which have to use `/dev/kmsg`: +//! +//! > Since syslog is not available (see above) write log messages to /dev/kmsg instead. +//! +//! [1]: http://www.freedesktop.org/wiki/Software/systemd/Generators/ +//! +//! # Examples +//! +//! ```toml +//! [dependencies] +//! log = "0.4" +//! kernlog = "0.3" +//! ``` +//! +//! ```rust +//! #[macro_use] +//! extern crate log; +//! extern crate kernlog; +//! +//! fn main() { +//! kernlog::init().unwrap(); +//! warn!("something strange happened"); +//! } +//! ``` +//! Note you have to have permissions to write to `/dev/kmsg`, +//! which normal users (not root) usually don't. +//! +//! If compiled with nightly it can use libc feature to get process id +//! and report it into log. This feature is unavailable for stable release +//! for now. To enable nightly features, compile with `--features nightly`: +//! +//! ```toml +//! [dependencies.kernlog] +//! version = "*" +//! features = ["nightly"] +//! ``` + +#![deny(missing_docs)] +#![cfg_attr(feature="nightly", feature(libc))] + +#[macro_use] +extern crate log; +extern crate libc; + +use std::fs::{OpenOptions, File}; +use std::io::{Write, self}; +use std::sync::Mutex; +use std::env; + +use log::{Log, Metadata, Record, Level, LevelFilter, SetLoggerError}; + +/// Kernel logger implementation +pub struct KernelLog { + kmsg: Mutex<File>, + maxlevel: LevelFilter +} + +impl KernelLog { + /// Create new kernel logger + pub fn new() -> io::Result<KernelLog> { + KernelLog::with_level(LevelFilter::Trace) + } + + /// Create new kernel logger from `KERNLOG_LEVEL` environment variable + pub fn from_env() -> io::Result<KernelLog> { + match env::var("KERNLOG_LEVEL") { + Err(_) => KernelLog::new(), + Ok(s) => match s.parse() { + Ok(filter) => KernelLog::with_level(filter), + Err(_) => KernelLog::new(), + } + } + } + + /// Create new kernel logger with error level filter + pub fn with_level(filter: LevelFilter) -> io::Result<KernelLog> { + Ok(KernelLog { + kmsg: Mutex::new(OpenOptions::new().write(true).open("/dev/kmsg")?), + maxlevel: filter + }) + } +} + +impl Log for KernelLog { + fn enabled(&self, meta: &Metadata) -> bool { + meta.level() <= self.maxlevel + } + + fn log(&self, record: &Record) { + if record.level() > self.maxlevel { + return; + } + + let level: u8 = match record.level() { + Level::Error => 3, + Level::Warn => 4, + Level::Info => 5, + Level::Debug => 6, + Level::Trace => 7, + }; + + let mut buf = Vec::new(); + writeln!(buf, "<{}>{}[{}]: {}", level, record.target(), + unsafe { ::libc::getpid() }, + record.args()).unwrap(); + + if let Ok(mut kmsg) = self.kmsg.lock() { + let _ = kmsg.write(&buf); + let _ = kmsg.flush(); + } + } + + fn flush(&self) {} +} + +/// KernelLog initialization error +#[derive(Debug)] +pub enum KernelLogInitError { + /// IO error + Io(io::Error), + /// Set logger error + Log(SetLoggerError) +} + +impl std::fmt::Display for KernelLogInitError { + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + match self { + KernelLogInitError::Io(err) => err.fmt(f), + KernelLogInitError::Log(err) => err.fmt(f), + } + } +} + +impl std::error::Error for KernelLogInitError { + fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { + match self { + KernelLogInitError::Io(err) => Some(err), + KernelLogInitError::Log(err) => Some(err), + } + } +} + +impl From<SetLoggerError> for KernelLogInitError { + fn from(err: SetLoggerError) -> Self { + KernelLogInitError::Log(err) + } +} +impl From<io::Error> for KernelLogInitError { + fn from(err: io::Error) -> Self { + KernelLogInitError::Io(err) + } +} + +/// Setup kernel logger as a default logger +pub fn init() -> Result<(), KernelLogInitError> { + let klog = KernelLog::from_env()?; + let maxlevel = klog.maxlevel; + log::set_boxed_logger(Box::new(klog))?; + log::set_max_level(maxlevel); + Ok(()) +} + +#[cfg(test)] +mod tests { + use super::{KernelLog, init}; + + #[test] + fn log_to_kernel() { + init().unwrap(); + debug!("hello, world!"); + } +} |