(max_lines: usize)
| 624 | /// Best-effort read of the tail of the daemon log across service runners. |
| 625 | #[cfg(unix)] |
| 626 | fn read_daemon_log_tail(max_lines: usize) -> String { |
| 627 | // macOS launchd: a plain err-log file next to the data dir. |
| 628 | if let Some(data_dir) = crate::config::user_data_dir() { |
| 629 | let err_log = data_dir.join("daemon.err.log"); |
| 630 | if let Ok(contents) = std::fs::read_to_string(&err_log) { |
| 631 | let lines: Vec<&str> = contents.lines().collect(); |
| 632 | let start = lines.len().saturating_sub(max_lines); |
| 633 | return lines[start..].join("\n"); |
| 634 | } |
| 635 | } |
| 636 | // Linux systemd: pull recent journal lines for the user unit. |
| 637 | let output = std::process::Command::new("journalctl") |
| 638 | .args([ |
| 639 | "--user", |
| 640 | "-u", |
| 641 | SERVICE_NAME, |
| 642 | "--no-pager", |
| 643 | "-n", |
| 644 | &max_lines.to_string(), |
| 645 | ]) |
| 646 | .output(); |
| 647 | match output { |
| 648 | Ok(out) if out.status.success() => String::from_utf8_lossy(&out.stdout).into_owned(), |
| 649 | _ => String::new(), |
| 650 | } |
| 651 | } |
| 652 | |
| 653 | #[cfg(unix)] |
| 654 | fn scheduler_task_log_fields( |
no test coverage detected