@@ -1079,6 +1079,17 @@ where
10791079 let _ = self . drain . log ( record, & self . list ) ;
10801080 }
10811081
1082+ /// Flush all pending log records,
1083+ /// blocking until completion.
1084+ ///
1085+ /// Will call [`std::io::Write::flush`] if applicable.
1086+ ///
1087+ /// Returns [`FlushError::NotSupported`] if the underlying drain does not support [`Drain::flush`].
1088+ #[ inline]
1089+ pub fn flush ( & self ) -> result:: Result < ( ) , FlushError > {
1090+ self . drain . flush ( )
1091+ }
1092+
10821093 /// Get list of key-value pairs assigned to this `Logger`
10831094 pub fn list ( & self ) -> & OwnedKVList {
10841095 & self . list
@@ -1159,6 +1170,53 @@ where
11591170 fn is_enabled ( & self , level : Level ) -> bool {
11601171 self . drain . is_enabled ( level)
11611172 }
1173+
1174+ #[ inline]
1175+ fn flush ( & self ) -> result:: Result < ( ) , FlushError > {
1176+ self . drain . flush ( )
1177+ }
1178+ }
1179+
1180+ /// An error that occurs when calling [`Drain::flush`].
1181+ #[ non_exhaustive]
1182+ #[ derive( Debug ) ]
1183+ pub enum FlushError {
1184+ /// An error that occurs doing IO.
1185+ ///
1186+ /// Often triggered by [`std::io::]
1187+ #[ cfg( feature = "std" ) ]
1188+ Io ( std:: io:: Error ) ,
1189+ /// Indicates this drain does not support flushing.
1190+ NotSupported ,
1191+ }
1192+ #[ cfg( feature = "std" ) ]
1193+ impl From < std:: io:: Error > for FlushError {
1194+ fn from ( value : std:: io:: Error ) -> Self {
1195+ FlushError :: Io ( value)
1196+ }
1197+ }
1198+ #[ cfg( has_std_error) ]
1199+ impl StdError for FlushError {
1200+ fn source ( & self ) -> Option < & ( dyn StdError + ' static ) > {
1201+ match self {
1202+ #[ cfg( feature = "std" ) ]
1203+ FlushError :: Io ( cause) => Some ( cause) ,
1204+ FlushError :: NotSupported => None ,
1205+ }
1206+ }
1207+ }
1208+ impl fmt:: Display for FlushError {
1209+ fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
1210+ match self {
1211+ #[ cfg( feature = "std" ) ]
1212+ FlushError :: Io ( _) => {
1213+ f. write_str ( "Encountered IO error during flushing" )
1214+ }
1215+ FlushError :: NotSupported => {
1216+ f. write_str ( "Drain does not support flushing" )
1217+ }
1218+ }
1219+ }
11621220}
11631221
11641222// {{{ Drain
@@ -1203,6 +1261,15 @@ pub trait Drain {
12031261 values : & OwnedKVList ,
12041262 ) -> result:: Result < Self :: Ok , Self :: Err > ;
12051263
1264+ /// Flush all pending log records, blocking until completion.
1265+ ///
1266+ /// Should call [`std::io::Write::flush`] if applicable.
1267+ ///
1268+ /// Returns [`FlushError::NotSupported`] if the drain has not implemented this method.
1269+ fn flush ( & self ) -> result:: Result < ( ) , FlushError > {
1270+ Err ( FlushError :: NotSupported )
1271+ }
1272+
12061273 /// **Avoid**: Check if messages at the specified log level are **maybe**
12071274 /// enabled for this logger.
12081275 ///
@@ -1365,6 +1432,10 @@ impl<'a, D: Drain + 'a> Drain for &'a D {
13651432 fn is_enabled ( & self , level : Level ) -> bool {
13661433 ( * * self ) . is_enabled ( level)
13671434 }
1435+ #[ inline]
1436+ fn flush ( & self ) -> result:: Result < ( ) , FlushError > {
1437+ ( * * self ) . flush ( )
1438+ }
13681439}
13691440
13701441impl < ' a , D : Drain + ' a > Drain for & ' a mut D {
@@ -1382,6 +1453,10 @@ impl<'a, D: Drain + 'a> Drain for &'a mut D {
13821453 fn is_enabled ( & self , level : Level ) -> bool {
13831454 ( * * self ) . is_enabled ( level)
13841455 }
1456+ #[ inline]
1457+ fn flush ( & self ) -> result:: Result < ( ) , FlushError > {
1458+ ( * * self ) . flush ( )
1459+ }
13851460}
13861461
13871462/// Internal utility module used to "maybe" bound traits
@@ -1543,6 +1618,10 @@ impl<D: Drain + ?Sized> Drain for Box<D> {
15431618 fn is_enabled ( & self , level : Level ) -> bool {
15441619 ( * * self ) . is_enabled ( level)
15451620 }
1621+ #[ inline]
1622+ fn flush ( & self ) -> result:: Result < ( ) , FlushError > {
1623+ ( * * self ) . flush ( )
1624+ }
15461625}
15471626
15481627impl < D : Drain + ?Sized > Drain for Arc < D > {
@@ -1559,6 +1638,10 @@ impl<D: Drain + ?Sized> Drain for Arc<D> {
15591638 fn is_enabled ( & self , level : Level ) -> bool {
15601639 ( * * self ) . is_enabled ( level)
15611640 }
1641+ #[ inline]
1642+ fn flush ( & self ) -> result:: Result < ( ) , FlushError > {
1643+ ( * * self ) . flush ( )
1644+ }
15621645}
15631646
15641647/// `Drain` discarding everything
@@ -1582,6 +1665,10 @@ impl Drain for Discard {
15821665 fn is_enabled ( & self , _level : Level ) -> bool {
15831666 false
15841667 }
1668+ #[ inline]
1669+ fn flush ( & self ) -> result:: Result < ( ) , FlushError > {
1670+ Ok ( ( ) )
1671+ }
15851672}
15861673
15871674/// `Drain` filtering records
@@ -1630,6 +1717,10 @@ where
16301717 */
16311718 self . 0 . is_enabled ( level)
16321719 }
1720+ #[ inline]
1721+ fn flush ( & self ) -> result:: Result < ( ) , FlushError > {
1722+ self . 0 . flush ( )
1723+ }
16331724}
16341725
16351726/// `Drain` filtering records by `Record` logging level
@@ -1670,6 +1761,10 @@ impl<D: Drain> Drain for LevelFilter<D> {
16701761 fn is_enabled ( & self , level : Level ) -> bool {
16711762 level. is_at_least ( self . 1 ) && self . 0 . is_enabled ( level)
16721763 }
1764+ #[ inline]
1765+ fn flush ( & self ) -> result:: Result < ( ) , FlushError > {
1766+ self . 0 . flush ( )
1767+ }
16731768}
16741769
16751770/// `Drain` mapping error returned by another `Drain`
@@ -1711,6 +1806,10 @@ impl<D: Drain, E> Drain for MapError<D, E> {
17111806 fn is_enabled ( & self , level : Level ) -> bool {
17121807 self . drain . is_enabled ( level)
17131808 }
1809+ #[ inline]
1810+ fn flush ( & self ) -> result:: Result < ( ) , FlushError > {
1811+ self . drain . flush ( )
1812+ }
17141813}
17151814
17161815/// `Drain` duplicating records into two other `Drain`s
@@ -1750,6 +1849,17 @@ impl<D1: Drain, D2: Drain> Drain for Duplicate<D1, D2> {
17501849 fn is_enabled ( & self , level : Level ) -> bool {
17511850 self . 0 . is_enabled ( level) || self . 1 . is_enabled ( level)
17521851 }
1852+ /// Flush both drains.
1853+ ///
1854+ /// Will return [`FlushError::NotSupported`] if either drain does not support flushing.
1855+ /// If one drain supports flushing and the other does not,
1856+ /// it is unspecified whether or not anything will be flushed at all.
1857+ #[ inline]
1858+ fn flush ( & self ) -> result:: Result < ( ) , FlushError > {
1859+ self . 0 . flush ( ) ?;
1860+ self . 1 . flush ( ) ?;
1861+ Ok ( ( ) )
1862+ }
17531863}
17541864
17551865/// `Drain` panicking on error
@@ -1796,6 +1906,10 @@ where
17961906 fn is_enabled ( & self , level : Level ) -> bool {
17971907 self . 0 . is_enabled ( level)
17981908 }
1909+ #[ inline]
1910+ fn flush ( & self ) -> result:: Result < ( ) , FlushError > {
1911+ self . 0 . flush ( )
1912+ }
17991913}
18001914
18011915/// `Drain` ignoring result
@@ -1832,6 +1946,11 @@ impl<D: Drain> Drain for IgnoreResult<D> {
18321946 fn is_enabled ( & self , level : Level ) -> bool {
18331947 self . drain . is_enabled ( level)
18341948 }
1949+
1950+ #[ inline]
1951+ fn flush ( & self ) -> result:: Result < ( ) , FlushError > {
1952+ self . drain . flush ( )
1953+ }
18351954}
18361955
18371956/// Error returned by `Mutex<D : Drain>`
@@ -1927,6 +2046,13 @@ impl<D: Drain> Drain for std::sync::Mutex<D> {
19272046 fn is_enabled ( & self , level : Level ) -> bool {
19282047 self . lock ( ) . ok ( ) . map_or ( true , |lock| lock. is_enabled ( level) )
19292048 }
2049+ #[ inline]
2050+ fn flush ( & self ) -> result:: Result < ( ) , FlushError > {
2051+ let guard = self . lock ( ) . map_err ( |_poison| {
2052+ std:: io:: Error :: new ( std:: io:: ErrorKind :: Other , "Mutex is poisoned" )
2053+ } ) ?;
2054+ guard. flush ( )
2055+ }
19302056}
19312057
19322058#[ cfg( feature = "parking_lot_0_12" ) ]
0 commit comments