ravi
ravi

Reputation: 10733

How do I use log4rs' RollingFileAppender to incorporate rolling logging?

I am trying to build a logger based on a rolling policy. Below is the closest I was able to implement:

let logfile = FileAppender::builder()
    .encoder(Box::new(PatternEncoder::new("{d} {l}::{m}{n}")))
    .build("log/output.log")?;

let config = Config::builder()
    .appender(Appender::builder().build("logfile", Box::new(logfile)))
    .build(Root::builder()
                .appender("logfile")
                .build(LevelFilter::Debug))?;

log4rs::init_config(config)?;

This helped me log messages at all levels. However, logging to a file for a long time can be a dangerous proposition. Consequently, I am looking for something which can limit the amount of log data that's preserved. I came across RollingFileAppender, but I am not able to find the proper usage of Policy.

Please guide me through this. I am mostly looking for programmatic configuration.

Upvotes: 4

Views: 3417

Answers (1)

Akiner Alkan
Akiner Alkan

Reputation: 6912

You can implement it via using RollingFileAppender CompoundPolicy , FixedWindowRoller and SizeTrigger from log4rs crate.

You need to implement the followings in order to create your rolling file logic:

  1. FixedWindowRoller

Specify FixedWindowRoller to roll your log file in a fixed window_size like following:

let window_size = 3; // log0, log1, log2
let fixed_window_roller = 
FixedWindowRoller::builder().build("log{}",window_size).unwrap();
  1. SizeTrigger

Specify SizeTrigger to declare the size limit of the file to trigger the Roller like following:

let size_limit = 5 * 1024; // 5KB as max log file size to roll
let size_trigger = SizeTrigger::new(size_limit);
  1. CompoundPolicy

Declare CompoundPolicy to use it in RollingFileAppender like following:

let compound_policy = CompoundPolicy::new(Box::new(size_trigger),Box::new(fixed_window_roller));

Then in your Config, you need to use RollingFileAppender in order to get desired behavior.

let config = Config::builder()
    .appender(
        Appender::builder()
            .filter(Box::new(ThresholdFilter::new(LevelFilter::Debug)))
            .build(
                "logfile",
                Box::new(
                    RollingFileAppender::builder()
                        .encoder(Box::new(PatternEncoder::new("{d} {l}::{m}{n}")))
                        .build("logfile", Box::new(compound_policy))?,
                ),
            ),
    )
    .build(
        Root::builder()
            .appender("logfile")
            .build(LevelFilter::Debug),
    )?;

With this implementation, you get a rolling file for the window size 3 and the roll size 5KB


If you want to compress the rolled files you can define this in your roller file extension. Instead of log{}you can specify extension as log{}.gz

However, if you want to enable compression with the log files you need to enable this feature in your cargo.toml as following:

log4rs = { version ="1.0.0", features = ["gzip"] }

Note: If you want to have a custom roller and custom trigger for your own purpose, you can implement your own Trigger and Roller from the respective traits

Upvotes: 13

Related Questions