From cf5d93ee0f536a10eed6a3c4c99c5d124b416953 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gabriel=20N=C3=BCtzi?= Date: Sat, 16 Mar 2024 22:26:16 +0100 Subject: [PATCH 1/2] fix: Add `flush` method on `Drain` trait --- src/lib.rs | 55 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) diff --git a/src/lib.rs b/src/lib.rs index e5fd15b2..71fef808 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -306,11 +306,13 @@ extern crate erased_serde; extern crate serde; use core::str::FromStr; +use core::time::Duration; use core::{convert, fmt, result}; #[cfg(feature = "std")] use std::borrow::{Cow, ToOwned}; #[cfg(feature = "std")] use std::boxed::Box; +use std::io; #[cfg(feature = "std")] use std::rc::Rc; #[cfg(feature = "std")] @@ -1322,6 +1324,12 @@ where self.drain.log(record, &chained) } + /// Flush the underlying drain. See the the underlying `Drain`s implementation for further + /// information. + fn flush(&self, interval: Duration) -> io::Result<()> { + self.drain.flush(interval) + } + #[inline] fn is_enabled(&self, level: Level) -> bool { self.drain.is_enabled(level) @@ -1370,6 +1378,12 @@ pub trait Drain { values: &OwnedKVList, ) -> result::Result; + /// Flush the drain if possible. Certain implementations, e.g. `Async`, provide this method. + /// The flush will poll with interval `interval` till all records have been + /// processed (what that means is dependent on the actual `Drain`). + fn flush(&self, _interval: Duration) -> io::Result<()> { + return Err(io::Error::from(io::ErrorKind::Unsupported)); + } /// **Avoid**: Check if messages at the specified log level are **maybe** /// enabled for this logger. /// @@ -1717,6 +1731,10 @@ impl Drain for Box { fn is_enabled(&self, level: Level) -> bool { (**self).is_enabled(level) } + #[inline] + fn flush(&self, interval: Duration) -> io::Result<()> { + (**self).flush(interval) + } } impl Drain for Arc { @@ -1733,6 +1751,10 @@ impl Drain for Arc { fn is_enabled(&self, level: Level) -> bool { (**self).is_enabled(level) } + #[inline] + fn flush(&self, interval: Duration) -> io::Result<()> { + (**self).flush(interval) + } } /// `Drain` discarding everything @@ -1802,6 +1824,11 @@ where */ self.0.is_enabled(level) } + + #[inline] + fn flush(&self, interval: Duration) -> io::Result<()> { + self.0.flush(interval) + } } /// `Drain` filtering records by `Record` logging level @@ -1841,6 +1868,11 @@ impl Drain for LevelFilter { fn is_enabled(&self, level: Level) -> bool { level.is_at_least(self.1) && self.0.is_enabled(level) } + + #[inline] + fn flush(&self, interval: Duration) -> io::Result<()> { + self.0.flush(interval) + } } /// `Drain` mapping error returned by another `Drain` @@ -1881,6 +1913,10 @@ impl Drain for MapError { fn is_enabled(&self, level: Level) -> bool { self.drain.is_enabled(level) } + #[inline] + fn flush(&self, interval: Duration) -> io::Result<()> { + self.drain.flush(interval) + } } /// `Drain` duplicating records into two other `Drain`s @@ -1919,6 +1955,10 @@ impl Drain for Duplicate { fn is_enabled(&self, level: Level) -> bool { self.0.is_enabled(level) || self.1.is_enabled(level) } + #[inline] + fn flush(&self, interval: Duration) -> io::Result<()> { + self.0.flush(interval) + } } /// `Drain` panicking on error @@ -1964,6 +2004,10 @@ where fn is_enabled(&self, level: Level) -> bool { self.0.is_enabled(level) } + #[inline] + fn flush(&self, interval: Duration) -> io::Result<()> { + self.0.flush(interval) + } } /// `Drain` ignoring result @@ -1999,6 +2043,10 @@ impl Drain for IgnoreResult { fn is_enabled(&self, level: Level) -> bool { self.drain.is_enabled(level) } + #[inline] + fn flush(&self, interval: Duration) -> io::Result<()> { + self.drain.flush(interval) + } } /// Error returned by `Mutex` @@ -2094,6 +2142,13 @@ impl Drain for std::sync::Mutex { fn is_enabled(&self, level: Level) -> bool { self.lock().ok().map_or(true, |lock| lock.is_enabled(level)) } + #[inline] + fn flush(&self, interval: Duration) -> io::Result<()> { + match self.lock() { + Err(_) => Ok(()), + Ok(d) => d.flush(interval), + } + } } // }}} From da1e2af0fd85698db7ee25a7901b536edfc7357a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gabriel=20N=C3=BCtzi?= Date: Sat, 16 Mar 2024 23:55:35 +0100 Subject: [PATCH 2/2] feat: Update changelog --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index ef5a70d2..b54933dd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,9 @@ and this project adheres to [Semantic Versioning](http://semver.org/). * Add `ErrorRef` wrapper to enable logging error references (PR #327) * The `#` error formatter in macros was updated to automatically select `ErrorValue` or `ErrorRef` (PR #328) +* Add `flush` method to `Drain` trait (PR #322). + Only the `Async` drain supports this feature and checks if + the channel is emptied. ### 2.8.0-beta.1 - 2023-09-09