@@ -1079,6 +1079,16 @@ where
10791079 let _ = self . drain . log ( record, & self . list ) ;
10801080 }
10811081
1082+ /// Flush all pending log records, blocking until completion.
1083+ ///
1084+ /// Will call [`std::io::Write::flush`] if applicable.
1085+ ///
1086+ /// Returns [`FlushError::NotSupported`] if the underlying drain does not support [`Drain::flush`].
1087+ #[ inline]
1088+ pub fn flush ( & self ) -> result:: Result < ( ) , FlushError > {
1089+ self . drain . flush ( )
1090+ }
1091+
10821092 /// Get list of key-value pairs assigned to this `Logger`
10831093 pub fn list ( & self ) -> & OwnedKVList {
10841094 & self . list
@@ -1159,6 +1169,53 @@ where
11591169 fn is_enabled ( & self , level : Level ) -> bool {
11601170 self . drain . is_enabled ( level)
11611171 }
1172+
1173+ #[ inline]
1174+ fn flush ( & self ) -> result:: Result < ( ) , FlushError > {
1175+ self . drain . flush ( )
1176+ }
1177+ }
1178+
1179+ /// An error that occurs when calling [`Drain::flush`].
1180+ #[ non_exhaustive]
1181+ #[ derive( Debug ) ]
1182+ pub enum FlushError {
1183+ /// An error that occurs doing IO.
1184+ ///
1185+ /// Often triggered by [`std::io::Write::flush`]
1186+ #[ cfg( feature = "std" ) ]
1187+ Io ( std:: io:: Error ) ,
1188+ /// Indicates this drain does not support flushing.
1189+ NotSupported ,
1190+ }
1191+ #[ cfg( feature = "std" ) ]
1192+ impl From < std:: io:: Error > for FlushError {
1193+ fn from ( value : std:: io:: Error ) -> Self {
1194+ FlushError :: Io ( value)
1195+ }
1196+ }
1197+ #[ cfg( has_std_error) ]
1198+ impl StdError for FlushError {
1199+ fn source ( & self ) -> Option < & ( dyn StdError + ' static ) > {
1200+ match self {
1201+ #[ cfg( feature = "std" ) ]
1202+ FlushError :: Io ( cause) => Some ( cause) ,
1203+ FlushError :: NotSupported => None ,
1204+ }
1205+ }
1206+ }
1207+ impl fmt:: Display for FlushError {
1208+ fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
1209+ match self {
1210+ #[ cfg( feature = "std" ) ]
1211+ FlushError :: Io ( _) => {
1212+ f. write_str ( "Encountered IO error during flushing" )
1213+ }
1214+ FlushError :: NotSupported => {
1215+ f. write_str ( "Drain does not support flushing" )
1216+ }
1217+ }
1218+ }
11621219}
11631220
11641221// {{{ Drain
@@ -1203,6 +1260,15 @@ pub trait Drain {
12031260 values : & OwnedKVList ,
12041261 ) -> result:: Result < Self :: Ok , Self :: Err > ;
12051262
1263+ /// Flush all pending log records, blocking until completion.
1264+ ///
1265+ /// Should call [`std::io::Write::flush`] if applicable.
1266+ ///
1267+ /// Returns [`FlushError::NotSupported`] if the drain has not implemented this method.
1268+ fn flush ( & self ) -> result:: Result < ( ) , FlushError > {
1269+ Err ( FlushError :: NotSupported )
1270+ }
1271+
12061272 /// **Avoid**: Check if messages at the specified log level are **maybe**
12071273 /// enabled for this logger.
12081274 ///
@@ -1365,6 +1431,10 @@ impl<'a, D: Drain + 'a> Drain for &'a D {
13651431 fn is_enabled ( & self , level : Level ) -> bool {
13661432 ( * * self ) . is_enabled ( level)
13671433 }
1434+ #[ inline]
1435+ fn flush ( & self ) -> result:: Result < ( ) , FlushError > {
1436+ ( * * self ) . flush ( )
1437+ }
13681438}
13691439
13701440impl < ' a , D : Drain + ' a > Drain for & ' a mut D {
@@ -1382,6 +1452,10 @@ impl<'a, D: Drain + 'a> Drain for &'a mut D {
13821452 fn is_enabled ( & self , level : Level ) -> bool {
13831453 ( * * self ) . is_enabled ( level)
13841454 }
1455+ #[ inline]
1456+ fn flush ( & self ) -> result:: Result < ( ) , FlushError > {
1457+ ( * * self ) . flush ( )
1458+ }
13851459}
13861460
13871461/// Internal utility module used to "maybe" bound traits
@@ -1543,6 +1617,10 @@ impl<D: Drain + ?Sized> Drain for Box<D> {
15431617 fn is_enabled ( & self , level : Level ) -> bool {
15441618 ( * * self ) . is_enabled ( level)
15451619 }
1620+ #[ inline]
1621+ fn flush ( & self ) -> result:: Result < ( ) , FlushError > {
1622+ ( * * self ) . flush ( )
1623+ }
15461624}
15471625
15481626impl < D : Drain + ?Sized > Drain for Arc < D > {
@@ -1559,6 +1637,10 @@ impl<D: Drain + ?Sized> Drain for Arc<D> {
15591637 fn is_enabled ( & self , level : Level ) -> bool {
15601638 ( * * self ) . is_enabled ( level)
15611639 }
1640+ #[ inline]
1641+ fn flush ( & self ) -> result:: Result < ( ) , FlushError > {
1642+ ( * * self ) . flush ( )
1643+ }
15621644}
15631645
15641646/// `Drain` discarding everything
@@ -1582,6 +1664,10 @@ impl Drain for Discard {
15821664 fn is_enabled ( & self , _level : Level ) -> bool {
15831665 false
15841666 }
1667+ #[ inline]
1668+ fn flush ( & self ) -> result:: Result < ( ) , FlushError > {
1669+ Ok ( ( ) )
1670+ }
15851671}
15861672
15871673/// `Drain` filtering records
@@ -1630,6 +1716,10 @@ where
16301716 */
16311717 self . 0 . is_enabled ( level)
16321718 }
1719+ #[ inline]
1720+ fn flush ( & self ) -> result:: Result < ( ) , FlushError > {
1721+ self . 0 . flush ( )
1722+ }
16331723}
16341724
16351725/// `Drain` filtering records by `Record` logging level
@@ -1670,6 +1760,10 @@ impl<D: Drain> Drain for LevelFilter<D> {
16701760 fn is_enabled ( & self , level : Level ) -> bool {
16711761 level. is_at_least ( self . 1 ) && self . 0 . is_enabled ( level)
16721762 }
1763+ #[ inline]
1764+ fn flush ( & self ) -> result:: Result < ( ) , FlushError > {
1765+ self . 0 . flush ( )
1766+ }
16731767}
16741768
16751769/// `Drain` mapping error returned by another `Drain`
@@ -1711,6 +1805,10 @@ impl<D: Drain, E> Drain for MapError<D, E> {
17111805 fn is_enabled ( & self , level : Level ) -> bool {
17121806 self . drain . is_enabled ( level)
17131807 }
1808+ #[ inline]
1809+ fn flush ( & self ) -> result:: Result < ( ) , FlushError > {
1810+ self . drain . flush ( )
1811+ }
17141812}
17151813
17161814/// `Drain` duplicating records into two other `Drain`s
@@ -1750,6 +1848,17 @@ impl<D1: Drain, D2: Drain> Drain for Duplicate<D1, D2> {
17501848 fn is_enabled ( & self , level : Level ) -> bool {
17511849 self . 0 . is_enabled ( level) || self . 1 . is_enabled ( level)
17521850 }
1851+ /// Flush both drains.
1852+ ///
1853+ /// Will return [`FlushError::NotSupported`] if either drain does not support flushing.
1854+ /// If one drain supports flushing and the other does not,
1855+ /// it is unspecified whether or not anything will be flushed at all.
1856+ #[ inline]
1857+ fn flush ( & self ) -> result:: Result < ( ) , FlushError > {
1858+ self . 0 . flush ( ) ?;
1859+ self . 1 . flush ( ) ?;
1860+ Ok ( ( ) )
1861+ }
17531862}
17541863
17551864/// `Drain` panicking on error
@@ -1796,6 +1905,10 @@ where
17961905 fn is_enabled ( & self , level : Level ) -> bool {
17971906 self . 0 . is_enabled ( level)
17981907 }
1908+ #[ inline]
1909+ fn flush ( & self ) -> result:: Result < ( ) , FlushError > {
1910+ self . 0 . flush ( )
1911+ }
17991912}
18001913
18011914/// `Drain` ignoring result
@@ -1832,6 +1945,11 @@ impl<D: Drain> Drain for IgnoreResult<D> {
18321945 fn is_enabled ( & self , level : Level ) -> bool {
18331946 self . drain . is_enabled ( level)
18341947 }
1948+
1949+ #[ inline]
1950+ fn flush ( & self ) -> result:: Result < ( ) , FlushError > {
1951+ self . drain . flush ( )
1952+ }
18351953}
18361954
18371955/// Error returned by `Mutex<D : Drain>`
@@ -1927,6 +2045,13 @@ impl<D: Drain> Drain for std::sync::Mutex<D> {
19272045 fn is_enabled ( & self , level : Level ) -> bool {
19282046 self . lock ( ) . ok ( ) . map_or ( true , |lock| lock. is_enabled ( level) )
19292047 }
2048+ #[ inline]
2049+ fn flush ( & self ) -> result:: Result < ( ) , FlushError > {
2050+ let guard = self . lock ( ) . map_err ( |_poison| {
2051+ std:: io:: Error :: new ( std:: io:: ErrorKind :: Other , "Mutex is poisoned" )
2052+ } ) ?;
2053+ guard. flush ( )
2054+ }
19302055}
19312056
19322057#[ cfg( feature = "parking_lot_0_12" ) ]
0 commit comments