68 lines
1.7 KiB
Rust
68 lines
1.7 KiB
Rust
use super::{now_unix, EventSource, SystemEvent};
|
|
use tokio::fs::File;
|
|
use tokio::io::{AsyncBufReadExt, BufReader};
|
|
use tokio::sync::mpsc;
|
|
|
|
pub async fn watch(tx: mpsc::Sender<SystemEvent>) {
|
|
let file = match File::open("/dev/kmsg").await {
|
|
Ok(f) => f,
|
|
Err(e) => {
|
|
log::warn!("kmsg watcher: cannot open /dev/kmsg: {e}");
|
|
return;
|
|
}
|
|
};
|
|
|
|
let mut lines = BufReader::new(file).lines();
|
|
while let Ok(Some(line)) = lines.next_line().await {
|
|
if let Some(msg) = parse_kmsg(&line) {
|
|
let _ = tx
|
|
.send(SystemEvent {
|
|
source: EventSource::Kmsg,
|
|
raw_line: msg,
|
|
timestamp: now_unix(),
|
|
})
|
|
.await;
|
|
}
|
|
}
|
|
}
|
|
|
|
fn parse_kmsg(line: &str) -> Option<String> {
|
|
let msg = if let Some(pos) = line.find(';') {
|
|
&line[pos + 1..]
|
|
} else {
|
|
line
|
|
};
|
|
if msg.is_empty() {
|
|
return None;
|
|
}
|
|
Some(msg.to_string())
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod tests {
|
|
use super::*;
|
|
|
|
#[test]
|
|
fn parses_kmsg_line_with_semicolon() {
|
|
let line = "6,1234,56789,-;usb 1-1: new full-speed USB device number 2";
|
|
assert_eq!(
|
|
parse_kmsg(line),
|
|
Some("usb 1-1: new full-speed USB device number 2".to_string())
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn parses_kmsg_line_without_semicolon() {
|
|
let line = "plain message without header";
|
|
assert_eq!(
|
|
parse_kmsg(line),
|
|
Some("plain message without header".to_string())
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn skips_empty_message_after_semicolon() {
|
|
let line = "6,1234,56789,-;";
|
|
assert_eq!(parse_kmsg(line), None);
|
|
}
|
|
}
|