Compare commits

...

3 Commits

2 changed files with 93 additions and 12 deletions
+38 -11
View File
@@ -59,7 +59,7 @@ pub fn init_logging_config() -> log4rs::Config {
let trigger = SizeTrigger::new(10 * 1024 * 1024); let trigger = SizeTrigger::new(10 * 1024 * 1024);
let roller = FixedWindowRoller::builder() let roller = FixedWindowRoller::builder()
.build(&archive_pattern, 3) .build(&archive_pattern, 3)
.unwrap(); .expect("Failed to build log roller");
let policy = CompoundPolicy::new(Box::new(trigger), Box::new(roller)); let policy = CompoundPolicy::new(Box::new(trigger), Box::new(roller));
let logfile = RollingFileAppender::builder() let logfile = RollingFileAppender::builder()
@@ -67,7 +67,7 @@ pub fn init_logging_config() -> log4rs::Config {
"{d(%Y-%m-%d %H:%M:%S%.3f)(utc)} <{i}> [{l}] {f}:{L} - {m}{n}", "{d(%Y-%m-%d %H:%M:%S%.3f)(utc)} <{i}> [{l}] {f}:{L} - {m}{n}",
))) )))
.build(log_path, Box::new(policy)) .build(log_path, Box::new(policy))
.unwrap(); .expect("Failed to build rolling file appender");
log4rs::Config::builder() log4rs::Config::builder()
.appender(Appender::builder().build("logfile", Box::new(logfile))) .appender(Appender::builder().build("logfile", Box::new(logfile)))
@@ -104,16 +104,29 @@ pub async fn tail_logs(no_color: bool) -> Result<()> {
.seek(SeekFrom::End(0)) .seek(SeekFrom::End(0))
.with_context(|| "Unable to tail log file")?; .with_context(|| "Unable to tail log file")?;
let mut lines = reader.lines(); tokio::task::spawn_blocking(move || {
let mut line_buf = String::new();
tokio::spawn(async move {
loop { loop {
if let Some(Ok(line)) = lines.next() { line_buf.clear();
if no_color { match reader.read_line(&mut line_buf) {
println!("{line}"); Ok(0) => {
} else { if was_log_rotated(&file_path, &mut reader) {
let colored_line = colorize_log_line(&line, &re); continue;
println!("{colored_line}"); }
std::thread::sleep(Duration::from_millis(100));
}
Ok(_) => {
let line = line_buf.trim_end();
if no_color {
println!("{line}");
} else {
let colored_line = colorize_log_line(line, &re);
println!("{colored_line}");
}
}
Err(_) => {
std::thread::sleep(Duration::from_millis(100));
} }
} }
} }
@@ -121,6 +134,20 @@ pub async fn tail_logs(no_color: bool) -> Result<()> {
.await? .await?
} }
pub(crate) fn was_log_rotated(file_path: &PathBuf, reader: &mut BufReader<File>) -> bool {
let current_pos = reader.stream_position().unwrap_or(0);
let file_len = fs::metadata(file_path).map(|m| m.len()).unwrap_or(0);
if file_len < current_pos
&& let Ok(new_file) = File::open(file_path)
{
*reader = BufReader::new(new_file);
return true;
}
false
}
fn colorize_log_line(line: &str, re: &Regex) -> String { fn colorize_log_line(line: &str, re: &Regex) -> String {
if let Some(caps) = re.captures(line) { if let Some(caps) = re.captures(line) {
let level = &caps["level"]; let level = &caps["level"];
+55 -1
View File
@@ -1,8 +1,11 @@
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use std::fs::{self, File};
use std::io::{BufRead, BufReader, Seek, SeekFrom, Write};
use pretty_assertions::assert_eq; use pretty_assertions::assert_eq;
use crate::utils::{convert_f64_to_gb, convert_runtime, convert_to_gb}; use crate::utils::{convert_f64_to_gb, convert_runtime, convert_to_gb, was_log_rotated};
#[test] #[test]
fn test_convert_to_gb() { fn test_convert_to_gb() {
@@ -23,4 +26,55 @@ mod tests {
assert_eq!(hours, 2); assert_eq!(hours, 2);
assert_eq!(minutes, 34); assert_eq!(minutes, 34);
} }
#[test]
fn test_was_log_rotated_returns_false_when_file_has_not_rotated() {
let path = std::env::temp_dir().join("managarr_test_no_rotation.log");
fs::write(&path, "line one\nline two\n").unwrap();
let file = File::open(&path).unwrap();
let mut reader = BufReader::new(file);
reader.seek(SeekFrom::End(0)).unwrap();
assert!(!was_log_rotated(&path, &mut reader));
fs::remove_file(&path).unwrap();
}
#[test]
fn test_was_log_rotated_returns_true_and_reopens_reader_after_rotation() {
let path = std::env::temp_dir().join("managarr_test_rotation.log");
fs::write(&path, "original content that is long enough\n").unwrap();
let file = File::open(&path).unwrap();
let mut reader = BufReader::new(file);
reader.seek(SeekFrom::End(0)).unwrap();
fs::write(&path, "new\n").unwrap();
assert!(was_log_rotated(&path, &mut reader));
let mut line = String::new();
reader.read_line(&mut line).unwrap();
assert_eq!(line, "new\n");
fs::remove_file(&path).unwrap();
}
#[test]
fn test_was_log_rotated_returns_false_when_file_grows() {
let path = std::env::temp_dir().join("managarr_test_growing.log");
fs::write(&path, "initial\n").unwrap();
let file = File::open(&path).unwrap();
let mut reader = BufReader::new(file);
reader.seek(SeekFrom::End(0)).unwrap();
let mut appender = fs::OpenOptions::new().append(true).open(&path).unwrap();
appender.write_all(b"more data\n").unwrap();
assert!(!was_log_rotated(&path, &mut reader));
fs::remove_file(&path).unwrap();
}
} }