@@ -1072,6 +1072,17 @@ where
10721072 let _ = self . drain . log ( record, & self . list ) ;
10731073 }
10741074
1075+ /// Flush all pending log records,
1076+ /// blocking until competion.
1077+ ///
1078+ /// Will call [`std::io::Write::flush`] if applicable.
1079+ ///
1080+ /// Returns [`FlushError::NotSupported`] if the underlying drain does not support [`Drain::flush`].
1081+ #[ inline]
1082+ pub fn flush ( & self ) -> result:: Result < ( ) , FlushError > {
1083+ self . drain . flush ( )
1084+ }
1085+
10751086 /// Get list of key-value pairs assigned to this `Logger`
10761087 pub fn list ( & self ) -> & OwnedKVList {
10771088 & self . list
@@ -1152,6 +1163,53 @@ where
11521163 fn is_enabled ( & self , level : Level ) -> bool {
11531164 self . drain . is_enabled ( level)
11541165 }
1166+
1167+ #[ inline]
1168+ fn flush ( & self ) -> result:: Result < ( ) , FlushError > {
1169+ self . drain . flush ( )
1170+ }
1171+ }
1172+
1173+ /// An error that occurs when calling [`Drain::flush`].
1174+ #[ non_exhaustive]
1175+ #[ derive( Debug ) ]
1176+ pub enum FlushError {
1177+ /// An error that occurs doing IO.
1178+ ///
1179+ /// Often triggered by [`std::io::]
1180+ #[ cfg( feature = "std" ) ]
1181+ Io ( std:: io:: Error ) ,
1182+ /// Indicates this drain does not support flushing.
1183+ NotSupported ,
1184+ }
1185+ #[ cfg( feature = "std" ) ]
1186+ impl From < std:: io:: Error > for FlushError {
1187+ fn from ( value : std:: io:: Error ) -> Self {
1188+ FlushError :: Io ( value)
1189+ }
1190+ }
1191+ #[ cfg( has_std_error) ]
1192+ impl StdError for FlushError {
1193+ fn source ( & self ) -> Option < & ( dyn StdError + ' static ) > {
1194+ match self {
1195+ #[ cfg( feature = "std" ) ]
1196+ FlushError :: Io ( cause) => Some ( cause) ,
1197+ FlushError :: NotSupported => None ,
1198+ }
1199+ }
1200+ }
1201+ impl fmt:: Display for FlushError {
1202+ fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
1203+ match self {
1204+ #[ cfg( feature = "std" ) ]
1205+ FlushError :: Io ( _) => {
1206+ f. write_str ( "Encountered IO error during flushing" )
1207+ }
1208+ FlushError :: NotSupported => {
1209+ f. write_str ( "Drain does not support flushing" )
1210+ }
1211+ }
1212+ }
11551213}
11561214
11571215// {{{ Drain
@@ -1196,6 +1254,15 @@ pub trait Drain {
11961254 values : & OwnedKVList ,
11971255 ) -> result:: Result < Self :: Ok , Self :: Err > ;
11981256
1257+ /// Flush all pending log records, blocking until competion.
1258+ ///
1259+ /// Should call [`std::io::Write::flush`] if applicable.
1260+ ///
1261+ /// Returns [`FlushError::NotSupported`] if the drain has not implemented this method.
1262+ fn flush ( & self ) -> result:: Result < ( ) , FlushError > {
1263+ Err ( FlushError :: NotSupported )
1264+ }
1265+
11991266 /// **Avoid**: Check if messages at the specified log level are **maybe**
12001267 /// enabled for this logger.
12011268 ///
@@ -1358,6 +1425,10 @@ impl<'a, D: Drain + 'a> Drain for &'a D {
13581425 fn is_enabled ( & self , level : Level ) -> bool {
13591426 ( * * self ) . is_enabled ( level)
13601427 }
1428+ #[ inline]
1429+ fn flush ( & self ) -> result:: Result < ( ) , FlushError > {
1430+ ( * * self ) . flush ( )
1431+ }
13611432}
13621433
13631434impl < ' a , D : Drain + ' a > Drain for & ' a mut D {
@@ -1375,6 +1446,10 @@ impl<'a, D: Drain + 'a> Drain for &'a mut D {
13751446 fn is_enabled ( & self , level : Level ) -> bool {
13761447 ( * * self ) . is_enabled ( level)
13771448 }
1449+ #[ inline]
1450+ fn flush ( & self ) -> result:: Result < ( ) , FlushError > {
1451+ ( * * self ) . flush ( )
1452+ }
13781453}
13791454
13801455/// Internal utility module used to "maybe" bound traits
@@ -1536,6 +1611,10 @@ impl<D: Drain + ?Sized> Drain for Box<D> {
15361611 fn is_enabled ( & self , level : Level ) -> bool {
15371612 ( * * self ) . is_enabled ( level)
15381613 }
1614+ #[ inline]
1615+ fn flush ( & self ) -> result:: Result < ( ) , FlushError > {
1616+ ( * * self ) . flush ( )
1617+ }
15391618}
15401619
15411620impl < D : Drain + ?Sized > Drain for Arc < D > {
@@ -1552,6 +1631,10 @@ impl<D: Drain + ?Sized> Drain for Arc<D> {
15521631 fn is_enabled ( & self , level : Level ) -> bool {
15531632 ( * * self ) . is_enabled ( level)
15541633 }
1634+ #[ inline]
1635+ fn flush ( & self ) -> result:: Result < ( ) , FlushError > {
1636+ ( * * self ) . flush ( )
1637+ }
15551638}
15561639
15571640/// `Drain` discarding everything
@@ -1575,6 +1658,10 @@ impl Drain for Discard {
15751658 fn is_enabled ( & self , _level : Level ) -> bool {
15761659 false
15771660 }
1661+ #[ inline]
1662+ fn flush ( & self ) -> result:: Result < ( ) , FlushError > {
1663+ Ok ( ( ) )
1664+ }
15781665}
15791666
15801667/// `Drain` filtering records
@@ -1623,6 +1710,10 @@ where
16231710 */
16241711 self . 0 . is_enabled ( level)
16251712 }
1713+ #[ inline]
1714+ fn flush ( & self ) -> result:: Result < ( ) , FlushError > {
1715+ self . 0 . flush ( )
1716+ }
16261717}
16271718
16281719/// `Drain` filtering records by `Record` logging level
@@ -1663,6 +1754,10 @@ impl<D: Drain> Drain for LevelFilter<D> {
16631754 fn is_enabled ( & self , level : Level ) -> bool {
16641755 level. is_at_least ( self . 1 ) && self . 0 . is_enabled ( level)
16651756 }
1757+ #[ inline]
1758+ fn flush ( & self ) -> result:: Result < ( ) , FlushError > {
1759+ self . 0 . flush ( )
1760+ }
16661761}
16671762
16681763/// `Drain` mapping error returned by another `Drain`
@@ -1704,6 +1799,10 @@ impl<D: Drain, E> Drain for MapError<D, E> {
17041799 fn is_enabled ( & self , level : Level ) -> bool {
17051800 self . drain . is_enabled ( level)
17061801 }
1802+ #[ inline]
1803+ fn flush ( & self ) -> result:: Result < ( ) , FlushError > {
1804+ self . drain . flush ( )
1805+ }
17071806}
17081807
17091808/// `Drain` duplicating records into two other `Drain`s
@@ -1743,6 +1842,17 @@ impl<D1: Drain, D2: Drain> Drain for Duplicate<D1, D2> {
17431842 fn is_enabled ( & self , level : Level ) -> bool {
17441843 self . 0 . is_enabled ( level) || self . 1 . is_enabled ( level)
17451844 }
1845+ /// Flush both drains.
1846+ ///
1847+ /// Will return [`FlushError::NotSupported`] if either drain does not support flushing.
1848+ /// If one drain supports flushing and the other does not,
1849+ /// it is unspecified whether or not anything will be flushed at all.
1850+ #[ inline]
1851+ fn flush ( & self ) -> result:: Result < ( ) , FlushError > {
1852+ self . 0 . flush ( ) ?;
1853+ self . 1 . flush ( ) ?;
1854+ Ok ( ( ) )
1855+ }
17461856}
17471857
17481858/// `Drain` panicking on error
@@ -1789,6 +1899,10 @@ where
17891899 fn is_enabled ( & self , level : Level ) -> bool {
17901900 self . 0 . is_enabled ( level)
17911901 }
1902+ #[ inline]
1903+ fn flush ( & self ) -> result:: Result < ( ) , FlushError > {
1904+ self . 0 . flush ( )
1905+ }
17921906}
17931907
17941908/// `Drain` ignoring result
@@ -1825,6 +1939,11 @@ impl<D: Drain> Drain for IgnoreResult<D> {
18251939 fn is_enabled ( & self , level : Level ) -> bool {
18261940 self . drain . is_enabled ( level)
18271941 }
1942+
1943+ #[ inline]
1944+ fn flush ( & self ) -> result:: Result < ( ) , FlushError > {
1945+ self . drain . flush ( )
1946+ }
18281947}
18291948
18301949/// Error returned by `Mutex<D : Drain>`
@@ -1920,6 +2039,13 @@ impl<D: Drain> Drain for std::sync::Mutex<D> {
19202039 fn is_enabled ( & self , level : Level ) -> bool {
19212040 self . lock ( ) . ok ( ) . map_or ( true , |lock| lock. is_enabled ( level) )
19222041 }
2042+ #[ inline]
2043+ fn flush ( & self ) -> result:: Result < ( ) , FlushError > {
2044+ let guard = self . lock ( ) . map_err ( |_poison| {
2045+ std:: io:: Error :: new ( std:: io:: ErrorKind :: Other , "Mutex is poisoned" )
2046+ } ) ?;
2047+ guard. flush ( )
2048+ }
19232049}
19242050// }}}
19252051
0 commit comments