pub struct NonBlocking<F: Format> { /* private fields */ }std only.Expand description
A sink that formats on the calling thread and writes on a background thread.
Records are formatted into a String, queued on a bounded channel,
and written by a dedicated thread through an internal write buffer.
The worker flushes whenever the queue drains, so records reach the
OS promptly once logging pauses, and in large batches under load.
This keeps file and socket I/O off request threads and async
executor threads.
- Bounded: at most
capacityrecords, and aboutmax_queued_bytesbytes of formatted text (16 MiB by default), are queued. What happens when either limit is reached is set byOverflow; the default,Overflow::Block, never drops a record. - Flush:
Sink::flushwaits until every record queued before it has been written and the writer flushed. - Shutdown:
Sink::shutdown(called bycrate::Logger::shutdown, acrate::FlushGuard, or dropping the last logger clone) drains the queue, flushes, and joins the thread. Records logged afterwards are written synchronously on the caller’s thread, so late records are not lost. - Errors: a write error on the worker cannot be returned to the
caller that logged the record. It is counted
(
NonBlocking::write_errors), passed to the optionalNonBlockingBuilder::on_errorhandler, and returned by the nextflush. - Allocation: queued strings are recycled through a return
channel, so a single producer allocates only while the pool warms
up, which can take up to
capacityrecords when the producer outruns the writer; with heavy multi-thread contention some records allocate. The pool keeps at mostcapacitybuffers of up to 64 KiB each.
As with any buffering sink, records still queued when the process
aborts are lost; see super::FileSink for the exit paths that
skip destructors.
- Flush level: a record at or above the logger’s flush level
waits for the queue to drain under
Overflow::Blockand does not wait underOverflow::DropNewest; seeOverflow.
The writer and the worker’s on_error handler may log through a
logger that feeds this same sink, but the worker never waits for
itself: on the worker thread, a record that does not fit in the
queue is dropped and counted (even under Overflow::Block), a
flush-level flush is skipped (the worker flushes once it drains the
queue), and Sink::flush and Sink::shutdown return
Error::Closed at once. Records written that way are delayed
behind the current batch, and they feed the writer again, so keep
such logging rare.
§Examples
use log_io::format::JsonFormat;
use log_io::sink::{NonBlocking, Overflow};
use log_io::{Level, Logger};
let sink = NonBlocking::builder(std::io::sink(), JsonFormat::new())
.capacity(4096)
.overflow(Overflow::DropNewest)
.build()?;
let logger = Logger::builder().level(Level::Info).with_sink(sink).build();
log_io::info!(logger, "off the hot path", worker = 3_u32);
logger.shutdown()?; // drain and joinImplementations§
Source§impl<F: Format> NonBlocking<F>
impl<F: Format> NonBlocking<F>
Sourcepub fn new<W: Write + Send + 'static>(writer: W, format: F) -> Result<Self>
pub fn new<W: Write + Send + 'static>(writer: W, format: F) -> Result<Self>
Start a background writer with default options: capacity 8192,
16 MiB of queued text, Overflow::Block.
§Errors
Returns Error::Io if the worker thread cannot be spawned.
Sourcepub fn builder<W: Write + Send + 'static>(
writer: W,
format: F,
) -> NonBlockingBuilder<F>
pub fn builder<W: Write + Send + 'static>( writer: W, format: F, ) -> NonBlockingBuilder<F>
Start configuring a background writer.
Sourcepub fn dropped(&self) -> u64
pub fn dropped(&self) -> u64
Records dropped because the queue was full under
Overflow::DropNewest.
Sourcepub fn write_errors(&self) -> u64
pub fn write_errors(&self) -> u64
Write errors encountered by the background thread.
Sourcepub fn queued_bytes(&self) -> usize
pub fn queued_bytes(&self) -> usize
Bytes of formatted text queued and not yet written.
Trait Implementations§
Source§impl<F: Format> Drop for NonBlocking<F>
impl<F: Format> Drop for NonBlocking<F>
Source§impl<F: Format> Sink for NonBlocking<F>
impl<F: Format> Sink for NonBlocking<F>
Source§fn write_record(&self, record: &Record<'_>) -> Result<()>
fn write_record(&self, record: &Record<'_>) -> Result<()>
Source§fn flush(&self) -> Result<()>
fn flush(&self) -> Result<()>
fsync). Read moreSource§fn request_flush(&self) -> Result<()>
fn request_flush(&self) -> Result<()>
crate::LoggerBuilder::flush_on). Read moreSource§fn shutdown(&self) -> Result<()>
fn shutdown(&self) -> Result<()>
crate::Logger::shutdown, by a crate::FlushGuard on drop,
and when the last clone of a crate::Logger is dropped. Read more