Files
agent-manager/src/commands/logs_cmd.rs
T

57 lines
1.8 KiB
Rust

//! logs: tail the log file of an agent (--follow for a live view).
use super::*;
use crate::output::print_json;
use anyhow::{bail, Result};
use std::path::PathBuf;
/// Resolve the log path of an agent (validates the agent first).
pub fn log_path(app: &App, agent_name: &str) -> Result<PathBuf> {
let agent = require_agent(app, agent_name)?;
Ok(crate::process::agent_log_path(app, &agent.name))
}
pub fn run(app: &App, agent: &str, lines: usize, follow: bool) -> Result<i32> {
let path = log_path(app, agent)?;
if !path.exists() {
bail!(
"no log yet for '{}' — start it with 'am start {} --background'",
agent,
agent
);
}
if app.json() {
let tail = crate::process::last_lines(&path, lines);
print_json(&serde_json::json!({
"agent": agent,
"log": path.display().to_string(),
"tail": tail,
}));
return Ok(0);
}
if !follow {
print!("{}", crate::process::last_lines(&path, lines));
return Ok(0);
}
// Live follow: print the initial tail, then new bytes as they arrive.
let mut seen: usize = std::fs::metadata(&path).map(|m| m.len() as usize).unwrap_or(0);
loop {
if let Ok(text) = std::fs::read_to_string(&path) {
let bytes = text.as_bytes();
if bytes.len() > seen {
// Slicer sans risque de couper un caractere UTF-8.
let tail: String = text
.char_indices()
.filter(|(i, _)| *i >= seen)
.map(|(_, c)| c)
.collect();
print!("{tail}");
use std::io::Write;
let _ = std::io::stdout().flush();
}
seen = bytes.len();
}
std::thread::sleep(std::time::Duration::from_secs(1));
}
}