57 lines
1.8 KiB
Rust
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));
|
|
}
|
|
}
|