pub struct RotatingFile { /* private fields */ }std only.Expand description
A file writer that rotates by size and/or time.
The active file is always at the configured path. On rotation it is
renamed to <path>.1, an existing <path>.1 becomes <path>.2,
and so on; the file that would move past <path>.<max_files> is
deleted. With max_files(0) the active file is deleted at rotation
instead of kept.
Rotation happens between records, never inside one: the size check
runs before each write call, and the built-in sinks write a whole
record per call. A record larger than max_bytes is written to a
fresh file on its own.
Use it as the writer of a super::WriterSink (aliased as
super::RotatingFileSink) or of a super::NonBlocking sink.
Behind a NonBlocking sink, records reach this writer in batches
through the worker’s write buffer (64 KiB by default), so a file can
exceed max_bytes by up to that buffer size and period boundaries
are honoured per batch; set the worker’s buffer_capacity(0) for
per-record precision.
§Failed rotation
The current file handle is flushed and closed before any rename, so rotation works on Windows as well as Unix. A rotation is all or nothing:
- the active file is moved to
<path>.rotating. If that fails (on Windows, typically because another process holds the file open without delete sharing), nothing else has been touched; - the history is shifted up one slot, the oldest file going to
<path>.pruningrather than being deleted; <path>.rotatingbecomes<path>.1, and only then is<path>.pruningdeleted.
If a rename in steps 2-3 fails, the renames already done are undone
in reverse order. So a failed rotation never deletes or overwrites
rotated history: every rotated file keeps its name and content. The
writer then reopens the active file, keeps appending to it, retries
after another max_bytes or at the next period, and reports the
error from the next Write::flush call (which the logger passes
to its error handler).
If an undo fails as well (a second fault, for example the directory
becoming read-only mid-rotation), the rollback stops and the files
keep whatever names they have at that point; still nothing is
deleted. Records that were in the active file stay in
<path>.rotating, the writer starts a new active file, and every
later rotation attempt fails with io::ErrorKind::AlreadyExists
naming that file (so it is never overwritten) until an operator
moves it aside.
§Examples
use log_io::format::JsonFormat;
use log_io::sink::{RotatingFile, Rotation};
use log_io::{Level, Logger};
let file = RotatingFile::builder("logs/app.jsonl")
.max_bytes(50 * 1024 * 1024)
.rotation(Rotation::Daily)
.max_files(14)
.open()?;
let logger = Logger::builder().level(Level::Info).writer(file, JsonFormat::new()).build();Implementations§
Source§impl RotatingFile
impl RotatingFile
Sourcepub fn builder(path: impl AsRef<Path>) -> RotatingFileBuilder
pub fn builder(path: impl AsRef<Path>) -> RotatingFileBuilder
Start configuring a rotating file at path. Defaults: no size
limit, Rotation::Never, keep 5 rotated files, 8 KiB buffer,
mode 0o600 for new files (Unix), symbolic links refused.
Sourcepub fn current_size(&self) -> u64
pub fn current_size(&self) -> u64
Bytes written to the active file so far (including bytes that existed when it was opened).
Sourcepub fn rotate_now(&mut self) -> Result<()>
pub fn rotate_now(&mut self) -> Result<()>
Rotate immediately, regardless of size and time.
§Errors
Returns the I/O error from flushing, renaming, or reopening. On error the writer keeps appending to the active file.
Trait Implementations§
Source§impl Debug for RotatingFile
impl Debug for RotatingFile
Source§impl Drop for RotatingFile
impl Drop for RotatingFile
Source§impl Write for RotatingFile
impl Write for RotatingFile
Source§fn write(&mut self, buf: &[u8]) -> Result<usize>
fn write(&mut self, buf: &[u8]) -> Result<usize>
Source§fn flush(&mut self) -> Result<()>
fn flush(&mut self) -> Result<()>
Source§fn is_write_vectored(&self) -> bool
fn is_write_vectored(&self) -> bool
can_vector)1.0.0 · Source§fn write_all(&mut self, buf: &[u8]) -> Result<(), Error>
fn write_all(&mut self, buf: &[u8]) -> Result<(), Error>
Source§fn write_all_vectored(&mut self, bufs: &mut [IoSlice<'_>]) -> Result<(), Error>
fn write_all_vectored(&mut self, bufs: &mut [IoSlice<'_>]) -> Result<(), Error>
write_all_vectored)