use super::log_dedup;
use forge::signal::compactor;
use once_cell::sync::Lazy;
use regex::Regex;
static JOURNAL_PREFIX_RE: Lazy<Regex> =
Lazy::new(|| Regex::new(r"(?m)^[A-Z][a-z]{2} \d{2} \d{2}:\d{2}:\d{2} \S+ ").unwrap());
#[allow(dead_code)]
static STATUS_DOTS_RE: Lazy<Regex> = Lazy::new(|| Regex::new(r"(?m)^[●○]\s+").unwrap());
pub fn compress_journalctl(raw: &str) -> String {
let cleaned = compactor::normalise(raw);
let stripped = JOURNAL_PREFIX_RE.replace_all(&cleaned, "");
let deduped = log_dedup(&stripped);
let lines: Vec<&str> = deduped.lines().collect();
if lines.len() > 150 {
let omitted = lines.len() - 150;
return format!(
"... [{} earlier lines omitted] ...\n{}",
omitted,
lines[lines.len() - 150..].join("\n")
);
}
deduped
}
pub fn compress_systemctl_status(raw: &str) -> String {
let cleaned = compactor::normalise(raw);
let mut in_cgroup = false;
let kept: Vec<&str> = cleaned
.lines()
.filter(|l| {
let t = l.trim();
if t.starts_with("CGroup:") || t.starts_with("└─") || t.starts_with("├─") {
in_cgroup = true;
}
if in_cgroup && t.starts_with("└─") {
return true; }
if in_cgroup && (t.starts_with("│") || t.starts_with("├─")) {
return false; }
true
})
.collect();
compactor::collapse_blanks(&kept.join("\n"))
}
pub fn compress_systemctl(subcmd: &str, raw: &str) -> String {
let sub = subcmd.trim();
if sub.starts_with("status") {
return compress_systemctl_status(raw);
}
if sub.starts_with("list-units") || sub.starts_with("list-timers") {
let cleaned = compactor::normalise(raw);
let lines: Vec<&str> = cleaned.lines().collect();
if lines.len() > 40 {
return format!(
"{}\n... [{} more units] ...",
lines[..40].join("\n"),
lines.len() - 40
);
}
return cleaned;
}
compactor::normalise(raw)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn journalctl_strips_timestamps() {
let raw = "May 05 12:34:56 myhost nginx[1234]: starting\nMay 05 12:34:57 myhost nginx[1234]: ready\n";
let out = compress_journalctl(raw);
assert!(!out.contains("May 05 12:34:56 myhost"), "{out}");
assert!(out.contains("starting") || out.contains("nginx"), "{out}");
}
#[test]
fn journalctl_deduplicates_repeats() {
let raw = (0..20)
.map(|_| "May 05 12:34:56 h svc: connection refused\n")
.collect::<String>();
let out = compress_journalctl(&raw);
assert!(out.contains("repeated"), "{out}");
}
#[test]
fn systemctl_status_keeps_active_line() {
let raw = "● nginx.service - A high performance web server\n Loaded: loaded (/lib/systemd/system/nginx.service)\n Active: active (running) since Mon 2024-01-01\n Main PID: 1234\n";
let out = compress_systemctl_status(raw);
assert!(out.contains("Active"), "{out}");
}
}