Skip to content

Rolling file appender overgrows x.log.0 on restart when max_file_size is set #153

@Mota-Link

Description

@Mota-Link

Hello, and thanks for the great project.

I believe I’ve found an issue in the rolling file appender when max_file_size is configured.

Problem description

  • When rotation happens during a run, files are created as x.log.0, x.log.1, ...
  • After the program exits and restarts, the appender starts writing to x.log.0 again in append mode.
  • It continues appending to x.log.0 until the amount of data written in this new run reaches max_file_size, and only then rotates to the next file.
  • As a result, x.log.0 can grow to roughly 2 × max_file_size after a single restart. If the program is restarted multiple times, x.log.0 keeps growing cumulatively beyond the configured limit.

Expected behavior

  • If max_file_size is set, the appender should discover the latest existing file on startup:
    • Scan x.log.0, x.log.1, ... to find the highest index n that exists.
    • If x.log.n is not yet full (size < max_file_size), resume appending to x.log.n.
    • If x.log.n is already full (size >= max_file_size), roll to x.log.(n+1) and start a new file.
  • In short, resume from the latest index and honor the size limit across restarts.

I have attached a minimal reproducible example, adapted from the example code of rolling_file. You can reproduce the issue simply by running the program multiple times.

use logforth::append::rolling_file::RollingFileBuilder;
use logforth::layout::JsonLayout;

fn main() {
    let (rolling_writer, _guard) = RollingFileBuilder::new("logs")
        .layout(JsonLayout::default())
        .max_file_size(500)
        .filename_prefix("app_log")
        .build()
        .unwrap();

    logforth::builder()
        .dispatch(|d| d.filter(log::LevelFilter::Trace).append(rolling_writer))
        .apply();

    let repeat = 1;

    for i in 0..repeat {
        log::error!("Hello error!");
        log::warn!("Hello warn!");
        log::info!("Hello info!");
        log::debug!("Hello debug!");
        log::trace!("Hello trace!");

        if i + 1 < repeat {
            std::thread::sleep(std::time::Duration::from_secs(10));
        }
    }
}

Could you please confirm whether this is the intended behavior or if it might be a bug?

Thank you!

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions