[][src]Crate file_rotate

Write output to a file and rotate the files when limits have been exceeded.

Rotating by Lines

We can rotate log files by using the amount of lines as a limit.

use file_rotate::{FileRotate, RotationMode};
use std::{fs, io::Write};

fn main() {
    // Create a directory to store our logs, this is not strictly needed but shows how we can
    // arbitrary paths.
    fs::create_dir("my-log-directory-lines");

    // Create a new log writer. The first argument is anything resembling a path. The
    // basename is used for naming the log files.
    //
    // Here we choose to limit logs by 10 lines, and have at most 2 rotated log files. This
    // makes the total amount of log files 4, since the original file is present as well as
    // file 0.
    let mut log = FileRotate::new("my-log-directory-lines/my-log-file", RotationMode::Lines(3), 2);

    // Write a bunch of lines
    writeln![log, "Line 1: Hello World!"];
    for idx in 2..11 {
        writeln![log, "Line {}", idx];
    }

    assert_eq!["Line 10\n", fs::read_to_string("my-log-directory-lines/my-log-file").unwrap()];

    assert_eq!["Line 1: Hello World!\nLine 2\nLine 3\n", fs::read_to_string("my-log-directory-lines/my-log-file.0").unwrap()];
    assert_eq!["Line 4\nLine 5\nLine 6\n", fs::read_to_string("my-log-directory-lines/my-log-file.1").unwrap()];
    assert_eq!["Line 7\nLine 8\nLine 9\n", fs::read_to_string("my-log-directory-lines/my-log-file.2").unwrap()];

    fs::remove_dir_all("my-log-directory-lines");
}

Rotating by Bytes

Another method of rotation is by bytes instead of lines.

use file_rotate::{FileRotate, RotationMode};
use std::{fs, io::Write};

fn main() {
    fs::create_dir("my-log-directory-bytes");

    let mut log = FileRotate::new("my-log-directory-bytes/my-log-file", RotationMode::Bytes(5), 2);

    writeln![log, "Test file"];

    assert_eq!["Test ", fs::read_to_string("my-log-directory-bytes/my-log-file.0").unwrap()];
    assert_eq!["file\n", fs::read_to_string("my-log-directory-bytes/my-log-file").unwrap()];

    fs::remove_dir_all("my-log-directory-bytes");
}

Rotation Method

The rotation method used is to always write to the base path, and then move the file to a new location when the limit is exceeded. The moving occurs in the sequence 0, 1, 2, n, 0, 1, 2...

Here's an example with 1 byte limits:

use file_rotate::{FileRotate, RotationMode};
use std::{fs, io::Write};

fn main() {
    fs::create_dir("my-log-directory-small");

    let mut log = FileRotate::new("my-log-directory-small/my-log-file", RotationMode::Bytes(1), 3);

    write![log, "A"];
    assert_eq!["A", fs::read_to_string("my-log-directory-small/my-log-file").unwrap()];

    write![log, "B"];
    assert_eq!["A", fs::read_to_string("my-log-directory-small/my-log-file.0").unwrap()];
    assert_eq!["B", fs::read_to_string("my-log-directory-small/my-log-file").unwrap()];

    write![log, "C"];
    assert_eq!["A", fs::read_to_string("my-log-directory-small/my-log-file.0").unwrap()];
    assert_eq!["B", fs::read_to_string("my-log-directory-small/my-log-file.1").unwrap()];
    assert_eq!["C", fs::read_to_string("my-log-directory-small/my-log-file").unwrap()];

    write![log, "D"];
    assert_eq!["A", fs::read_to_string("my-log-directory-small/my-log-file.0").unwrap()];
    assert_eq!["B", fs::read_to_string("my-log-directory-small/my-log-file.1").unwrap()];
    assert_eq!["C", fs::read_to_string("my-log-directory-small/my-log-file.2").unwrap()];
    assert_eq!["D", fs::read_to_string("my-log-directory-small/my-log-file").unwrap()];

    write![log, "E"];
    assert_eq!["A", fs::read_to_string("my-log-directory-small/my-log-file.0").unwrap()];
    assert_eq!["B", fs::read_to_string("my-log-directory-small/my-log-file.1").unwrap()];
    assert_eq!["C", fs::read_to_string("my-log-directory-small/my-log-file.2").unwrap()];
    assert_eq!["D", fs::read_to_string("my-log-directory-small/my-log-file.3").unwrap()];
    assert_eq!["E", fs::read_to_string("my-log-directory-small/my-log-file").unwrap()];


    // Here we overwrite the 0 file since we're out of log files, restarting the sequencing
    write![log, "F"];
    assert_eq!["E", fs::read_to_string("my-log-directory-small/my-log-file.0").unwrap()];
    assert_eq!["B", fs::read_to_string("my-log-directory-small/my-log-file.1").unwrap()];
    assert_eq!["C", fs::read_to_string("my-log-directory-small/my-log-file.2").unwrap()];
    assert_eq!["D", fs::read_to_string("my-log-directory-small/my-log-file.3").unwrap()];
    assert_eq!["F", fs::read_to_string("my-log-directory-small/my-log-file").unwrap()];

    fs::remove_dir_all("my-log-directory-small");
}

Filesystem Errors

If the directory containing the logs is deleted or somehow made unaccessible then the rotator will simply continue operating without fault. When a rotation occurs, it attempts to open a file in the directory. If it can, it will just continue logging. If it can't then the written date is sent to the void.

This logger never panics.

Structs

FileRotate

The main writer used for rotating logs

Enums

RotationMode

Condition on which a file is rotated