Skip to main content

FileAppender

Struct FileAppender 

Source
pub struct FileAppender { /* private fields */ }
Expand description

Appender that writes formatted log events to a file, appending to it.

The file is opened in append mode (created if it does not exist) and flushed after every event so log output survives crashes. When a size limit is configured with FileAppender::builder’s max_size, the current file is rolled over to a timestamped sibling (e.g. app.log.20260809-102530-1) once the next line would exceed the limit. A max_files retention policy (see FileAppenderBuilder::max_files) deletes the oldest rotated files once the count is exceeded. With FileAppenderBuilder::compressed, rotated files are gzip-compressed (.gz) on rollover. Write errors are silently ignored: a logging appender should never crash the application.

Internally synchronized, so it is safe to share between threads even when appenders run outside the global logger lock.

Implementations§

Source§

impl FileAppender

Source

pub fn open(path: impl AsRef<Path>, layout: Box<dyn Layout>) -> Result<Self>

Open (or create) path for appending, formatting events with layout.

Examples found in repository?
examples/file_appender.rs (line 14)
8fn main() {
9    let log_path = std::env::temp_dir().join("log4rc-file-appender.log");
10
11    Logger::builder(LogLevel::Info)
12        .appender(Box::new(ConsoleAppender::new(Box::new(SimpleLayout))))
13        .appender(Box::new(
14            FileAppender::open(&log_path, Box::new(SimpleLayout))
15                .expect("failed to open log file"),
16        ))
17        .init();
18
19    log4rc::info!("Writing to console and file");
20    log4rc::error!("An error also goes to both");
21    log4rc::debug!("Filtered out at Info level");
22
23    // Read the file back to prove the messages were written to disk.
24    let mut contents = String::new();
25    std::fs::File::open(&log_path)
26        .expect("failed to reopen log file")
27        .read_to_string(&mut contents)
28        .expect("failed to read log file");
29
30    println!("\n--- Contents of {} ---", log_path.display());
31    print!("{contents}");
32    let _ = std::fs::remove_file(&log_path);
33}
Source

pub fn builder( path: impl AsRef<Path>, layout: Box<dyn Layout>, ) -> FileAppenderBuilder

Configure a FileAppender, e.g. with size-based rotation.

Examples found in repository?
examples/rolling_file_appender.rs (line 17)
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) // tiny limit so a few messages trigger a roll
19                .max_files(3) // keep only the 3 newest rotated files
20                .compressed() // gzip rotated files
21                .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    // List the active file plus any rotated siblings.
31    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}

Trait Implementations§

Source§

impl Appender for FileAppender

Source§

fn append(&self, event: &LogEvent<'_>)

Append a log event to the output target

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.