rolling_file_appender/
rolling_file_appender.rs1use std::io::Read;
6
7use flate2::read::GzDecoder;
8use log4rc::{FileAppender, LogLevel, Logger, SimpleLayout};
9
10fn main() {
11 let dir = std::env::temp_dir();
12 let prefix = format!("log4rc-rolling-{}", std::process::id());
13 let log_path = dir.join(format!("{prefix}.log"));
14
15 Logger::builder(LogLevel::Info)
16 .appender(Box::new(
17 FileAppender::builder(&log_path, Box::new(SimpleLayout))
18 .max_size(100) .max_files(3) .compressed() .build()
22 .expect("failed to open log file"),
23 ))
24 .init();
25
26 for i in 0..10 {
27 log4rc::info!("This is message number {i:02} with some padding to grow the file");
28 }
29
30 let mut files: Vec<_> = std::fs::read_dir(&dir)
32 .unwrap()
33 .flatten()
34 .map(|e| e.path())
35 .filter(|p| {
36 p.file_name()
37 .and_then(|n| n.to_str())
38 .is_some_and(|n| n.starts_with(&prefix))
39 })
40 .collect();
41 files.sort();
42
43 println!("--- Log files ---");
44 let mut total_lines = 0;
45 for path in &files {
46 let contents = if path.to_string_lossy().ends_with(".gz") {
47 let mut contents = String::new();
48 let file = std::fs::File::open(path).expect("failed to open rotated file");
49 GzDecoder::new(file)
50 .read_to_string(&mut contents)
51 .expect("failed to decompress rotated file");
52 contents
53 } else {
54 std::fs::read_to_string(path).expect("failed to read log file")
55 };
56 let lines = contents.lines().count();
57 total_lines += lines;
58 println!("{} ({} lines):", path.display(), lines);
59 }
60 println!("total lines across files: {total_lines}");
61
62 for path in files {
63 let _ = std::fs::remove_file(path);
64 }
65}