#rotate #log #rotation #logging #logrotate #directory #log-line

file-rotate-record-boundary

请参阅 'file-rotate'。 (这是 Polyverse 需要修改的分支,直到上游 PR 被合并。https://github.com/BourgondAries/file-rotate/pull/3

1 个不稳定版本

0.3.0 2020 年 8 月 4 日

#7 in #logrotate

LGPL-3.0-or-later

16KB
213 行代码(不含注释)

将输出写入文件,当超过限制时旋转文件。

定义了一个简单的 std::io::Write 对象,您可以将其作为中间件插入到您的写入器中。

按行旋转

我们可以通过行数作为限制来旋转日志文件。

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

// Create a directory to store our logs, this is not strictly needed but shows how we can
// arbitrary paths.
fs::create_dir("target/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("target/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("target/my-log-directory-lines/my-log-file").unwrap());

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

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

按字节旋转

另一种旋转方法是按字节而不是按行。

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

fs::create_dir("target/my-log-directory-bytes");

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

writeln!(log, "Test file");

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

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

旋转方法

使用的旋转方法是始终写入基本路径,然后在超过限制时将文件移动到新位置。移动顺序为 0, 1, 2, n, 0, 1, 2...

以下是一个 1 字节限制的示例

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

fs::create_dir("target/my-log-directory-small");

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

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

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

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

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

write!(log, "E");
assert_eq!("A", fs::read_to_string("target/my-log-directory-small/my-log-file.0").unwrap());
assert_eq!("B", fs::read_to_string("target/my-log-directory-small/my-log-file.1").unwrap());
assert_eq!("C", fs::read_to_string("target/my-log-directory-small/my-log-file.2").unwrap());
assert_eq!("D", fs::read_to_string("target/my-log-directory-small/my-log-file.3").unwrap());
assert_eq!("E", fs::read_to_string("target/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("target/my-log-directory-small/my-log-file.0").unwrap());
assert_eq!("B", fs::read_to_string("target/my-log-directory-small/my-log-file.1").unwrap());
assert_eq!("C", fs::read_to_string("target/my-log-directory-small/my-log-file.2").unwrap());
assert_eq!("D", fs::read_to_string("target/my-log-directory-small/my-log-file.3").unwrap());
assert_eq!("F", fs::read_to_string("target/my-log-directory-small/my-log-file").unwrap());

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

文件系统错误

如果日志所在的目录被删除或无法访问,则旋转器将简单地继续无故障地运行。在旋转发生时,它尝试在目录中打开一个文件。如果可以,它将继续记录。如果不行,则将写入的日期发送到空地。

此日志记录器永远不会崩溃。

无运行时依赖