| // Copyright 2024 The ChromiumOS Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| use std::fs::{File, OpenOptions}; |
| use std::io::{self, Write}; |
| use std::sync::{Arc, Mutex}; |
| |
| use log::{Level, LevelFilter, Log}; |
| |
| const FLEXOR_TAG: &str = "flexor"; |
| const DEFAULT_DEVICE: &str = "/dev/kmsg"; |
| const MAX_LEVEL: LevelFilter = LevelFilter::Info; |
| const MAX_LOG_RECORD_SIZE: usize = 1024; |
| |
| // A logger that logs to the kernel message buffer. |
| struct KernelLogger { |
| file: Arc<Mutex<File>>, |
| } |
| |
| impl KernelLogger { |
| fn new() -> io::Result<Self> { |
| Ok(KernelLogger { |
| file: Arc::new(Mutex::new( |
| OpenOptions::new().write(true).open(DEFAULT_DEVICE)?, |
| )), |
| }) |
| } |
| } |
| |
| impl Log for KernelLogger { |
| fn enabled(&self, metadata: &log::Metadata) -> bool { |
| metadata.level() <= MAX_LEVEL |
| } |
| |
| fn log(&self, record: &log::Record) { |
| if record.level() > MAX_LEVEL { |
| return; |
| } |
| |
| let level: u8 = match record.level() { |
| Level::Error => 3, |
| Level::Warn => 4, |
| Level::Info => 5, |
| Level::Debug => 6, |
| Level::Trace => 7, |
| }; |
| |
| let message = record.args().to_string(); |
| let prefix = format!("<{level}>{FLEXOR_TAG}[{}]: ", unsafe { |
| nix::libc::getpid() |
| }); |
| |
| // The kernel log buffer can only append messages with a max size of |
| // 1024. For that reason we might log the message in chunks. |
| let msg_chunks: Vec<&str> = if message.len() < MAX_LOG_RECORD_SIZE - prefix.len() { |
| vec![&message] |
| } else { |
| message.lines().collect() |
| }; |
| |
| if let Ok(mut kmsg) = self.file.lock() { |
| for msg in msg_chunks { |
| _ = kmsg.write(format!("{prefix}{msg}").as_bytes()); |
| _ = kmsg.flush(); |
| } |
| } |
| } |
| |
| fn flush(&self) {} |
| } |
| |
| pub fn init() -> anyhow::Result<()> { |
| let klog = KernelLogger::new()?; |
| log::set_boxed_logger(Box::new(klog))?; |
| log::set_max_level(MAX_LEVEL); |
| |
| Ok(()) |
| } |