diff --git a/src/cortex-cli/src/logs_cmd.rs b/src/cortex-cli/src/logs_cmd.rs index f525efc3..e8764f11 100644 --- a/src/cortex-cli/src/logs_cmd.rs +++ b/src/cortex-cli/src/logs_cmd.rs @@ -222,6 +222,27 @@ impl LogsCli { println!("Following log file: {}", log_file.display()); println!("Press Ctrl+C to stop.\n"); + let content = std::fs::read_to_string(log_file)?; + let lines: Vec<&str> = content.lines().collect(); + let filtered_lines: Vec<&str> = if let Some(ref level) = self.level { + let level_upper = level.to_uppercase(); + lines + .iter() + .filter(|line| line.to_uppercase().contains(&level_upper)) + .copied() + .collect() + } else { + lines + }; + let start = if filtered_lines.len() > self.lines { + filtered_lines.len() - self.lines + } else { + 0 + }; + for line in &filtered_lines[start..] { + println!("{}", line); + } + let file = std::fs::File::open(log_file)?; let mut reader = BufReader::new(file); diff --git a/src/cortex-cli/tests/logs_follow_lines.rs b/src/cortex-cli/tests/logs_follow_lines.rs new file mode 100644 index 00000000..c9142694 --- /dev/null +++ b/src/cortex-cli/tests/logs_follow_lines.rs @@ -0,0 +1,43 @@ +use std::fs; +use std::io::Read; +use std::process::{Command, Stdio}; +use std::thread; +use std::time::Duration; + +use tempfile::tempdir; + +#[test] +fn logs_follow_prints_requested_initial_lines() { + let home = tempdir().unwrap(); + let cache = tempdir().unwrap(); + let logs_dir = cache.path().join("cortex").join("logs"); + fs::create_dir_all(&logs_dir).unwrap(); + fs::write(logs_dir.join("cortex.log"), "one\ntwo\nthree\nfour\n").unwrap(); + + let mut child = Command::new(env!("CARGO_BIN_EXE_Cortex")) + .args(["logs", "--follow", "--lines", "2"]) + .env("HOME", home.path()) + .env("XDG_CACHE_HOME", cache.path()) + .env_remove("CORTEX_HOME") + .stdout(Stdio::piped()) + .stderr(Stdio::piped()) + .spawn() + .unwrap(); + + thread::sleep(Duration::from_millis(250)); + let _ = child.kill(); + + let mut stdout = String::new(); + child + .stdout + .take() + .unwrap() + .read_to_string(&mut stdout) + .unwrap(); + let _ = child.wait(); + + assert!(!stdout.contains("\none\n"), "output:\n{stdout}"); + assert!(!stdout.contains("\ntwo\n"), "output:\n{stdout}"); + assert!(stdout.contains("\nthree\n"), "output:\n{stdout}"); + assert!(stdout.contains("\nfour\n"), "output:\n{stdout}"); +}