feat(robin): M1 System Presence — journald/kmsg/inotify watcher, pattern classifier, tray badge, chat panel #2
1 changed files with 62 additions and 3 deletions
|
|
@ -1,6 +1,65 @@
|
||||||
use super::SystemEvent;
|
use super::{EventSource, SystemEvent, now_unix};
|
||||||
|
use tokio::fs::File;
|
||||||
|
use tokio::io::{AsyncBufReadExt, BufReader};
|
||||||
use tokio::sync::mpsc;
|
use tokio::sync::mpsc;
|
||||||
|
|
||||||
pub async fn watch(_tx: mpsc::Sender<SystemEvent>) {
|
pub async fn watch(tx: mpsc::Sender<SystemEvent>) {
|
||||||
// implemented in Task 7
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue