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
 
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<Self::Ok, Self::Err>;
 
+    /// 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<D: Drain + ?Sized> Drain for Box<D> {
     fn is_enabled(&self, level: Level) -> bool {
         (**self).is_enabled(level)
     }
+    #[inline]
+    fn flush(&self, interval: Duration) -> io::Result<()> {
+        (**self).flush(interval)
+    }
 }
 
 impl<D: Drain + ?Sized> Drain for Arc<D> {
@@ -1733,6 +1751,10 @@ impl<D: Drain + ?Sized> Drain for Arc<D> {
     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<D: Drain> Drain for LevelFilter<D> {
     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<D: Drain, E> Drain for MapError<D, E> {
     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<D1: Drain, D2: Drain> Drain for Duplicate<D1, D2> {
     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<D: Drain> Drain for IgnoreResult<D> {
     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<D : Drain>`
@@ -2094,6 +2142,13 @@ impl<D: Drain> Drain for std::sync::Mutex<D> {
     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),
+        }
+    }
 }
 // }}}