diff --git a/ChangeLog.md b/ChangeLog.md
--- a/ChangeLog.md
+++ b/ChangeLog.md
@@ -1,5 +1,9 @@
 # Changelog for wai-extra
 
+## 3.1.7
+
+* Added new `mPrelogRequests` option to `DetailedSettings` [#857](https://github.com/yesodweb/wai/pull/857)
+
 ## 3.1.6
 
 * Remove unused dependencies [#837](https://github.com/yesodweb/wai/pull/837)
diff --git a/Network/Wai/Middleware/RequestLogger.hs b/Network/Wai/Middleware/RequestLogger.hs
--- a/Network/Wai/Middleware/RequestLogger.hs
+++ b/Network/Wai/Middleware/RequestLogger.hs
@@ -1,4 +1,5 @@
 {-# LANGUAGE RecordWildCards #-}
+
 -- NOTE: Due to https://github.com/yesodweb/wai/issues/192, this module should
 -- not use CPP.
 module Network.Wai.Middleware.RequestLogger
@@ -36,7 +37,7 @@
 import Network.HTTP.Types as H
 import Data.Maybe (fromMaybe, isJust, mapMaybe)
 import Data.Monoid (mconcat, (<>))
-import Data.Time (getCurrentTime, diffUTCTime, NominalDiffTime)
+import Data.Time (getCurrentTime, diffUTCTime, NominalDiffTime, UTCTime)
 import Network.Wai.Parse (sinkRequestBody, lbsBackEnd, fileName, Param, File
                          , getRequestBodyType)
 import qualified Data.ByteString.Lazy as LBS
@@ -76,12 +77,15 @@
     { useColors :: Bool
     , mModifyParams :: Maybe (Param -> Maybe Param)
     , mFilterRequests :: Maybe (Request -> Response -> Bool)
+    , mPrelogRequests :: Bool -- ^ @since 3.1.7
     }
+
 instance Default DetailedSettings where
     def = DetailedSettings
         { useColors = True
         , mModifyParams = Nothing
         , mFilterRequests = Nothing
+        , mPrelogRequests = False
         }
 
 type OutputFormatter = ZonedDate -> Request -> Status -> Maybe Integer -> LogStr
@@ -360,6 +364,11 @@
               in if null par then [""] else ansiColor White "  Params: " <> par <> ["\n"]
 
   t0 <- getCurrentTime
+
+  -- Optionally prelog the request
+  when mPrelogRequests $
+    cb $ "PRELOGGING REQUEST: " <> mkRequestLog params reqbody accept
+
   app req' $ \rsp -> do
       case mFilterRequests of
         Just f | not $ f req' rsp -> pure ()
@@ -373,14 +382,10 @@
           t1 <- getCurrentTime
 
           -- log the status of the response
-          cb $ mconcat $ map toLogStr $
-              ansiMethod (requestMethod req) ++ [" ", rawPathInfo req, "\n"] ++
-              params ++ reqbody ++
-              ansiColor White "  Accept: " ++ [accept, "\n"] ++
-              if isRaw then [] else
-                  ansiColor White "  Status: " ++
-                  ansiStatusCode stCode (stCode <> " " <> stMsg) ++
-                  [" ", pack $ show $ diffUTCTime t1 t0, "\n"]
+          cb $
+            mkRequestLog params reqbody accept
+            <> mkResponseLog isRaw stCode stMsg t1 t0
+
       sendResponse rsp
   where
     allPostParams body =
@@ -401,8 +406,27 @@
     collectPostParams :: ([Param], [File LBS.ByteString]) -> [Param]
     collectPostParams (postParams, files) = postParams ++
       map (\(k,v) -> (k, "FILE: " <> fileName v)) files
-
+    
+    mkRequestLog :: (Foldable t, ToLogStr m) => t m -> t m -> m -> LogStr
+    mkRequestLog params reqbody accept =
+        foldMap toLogStr (ansiMethod (requestMethod req))
+        <> " "
+        <> toLogStr (rawPathInfo req)
+        <> "\n"
+        <> foldMap toLogStr params
+        <> foldMap toLogStr reqbody
+        <> foldMap toLogStr (ansiColor White "  Accept: ")
+        <> toLogStr accept
+        <> "\n"
 
+    mkResponseLog :: Bool -> S8.ByteString -> S8.ByteString -> UTCTime -> UTCTime -> LogStr
+    mkResponseLog isRaw stCode stMsg t1 t0 =
+      if isRaw then "" else
+        foldMap toLogStr (ansiColor White "  Status: ")
+        <> foldMap toLogStr (ansiStatusCode stCode (stCode <> " " <> stMsg))
+        <> " "
+        <> toLogStr (pack $ show $ diffUTCTime t1 t0)
+        <> "\n"
 
 statusBS :: Response -> BS.ByteString
 statusBS = pack . show . statusCode . responseStatus
diff --git a/test/WaiExtraSpec.hs b/test/WaiExtraSpec.hs
--- a/test/WaiExtraSpec.hs
+++ b/test/WaiExtraSpec.hs
@@ -458,9 +458,9 @@
 
 caseModifyPostParamsInLogs :: Assertion
 caseModifyPostParamsInLogs = do
-    let formatUnredacted = DetailedWithSettings $ DetailedSettings False Nothing Nothing
+    let formatUnredacted = DetailedWithSettings $ DetailedSettings False Nothing Nothing False
         outputUnredacted = [("username", "some_user"), ("password", "dont_show_me")]
-        formatRedacted = DetailedWithSettings $ DetailedSettings False (Just hidePasswords) Nothing
+        formatRedacted = DetailedWithSettings $ DetailedSettings False (Just hidePasswords) Nothing False
         hidePasswords p@(k,_) = Just $ if k == "password" then (k, "***REDACTED***") else p
         outputRedacted = [("username", "some_user"), ("password", "***REDACTED***")]
 
@@ -492,8 +492,8 @@
 
 caseFilterRequestsInLogs :: Assertion
 caseFilterRequestsInLogs = do
-    let formatUnfiltered = DetailedWithSettings $ DetailedSettings False Nothing Nothing
-        formatFiltered = DetailedWithSettings . DetailedSettings False Nothing $ Just hideHealthCheck
+    let formatUnfiltered = DetailedWithSettings $ DetailedSettings False Nothing Nothing False
+        formatFiltered = DetailedWithSettings $ DetailedSettings False Nothing (Just hideHealthCheck) False
         pathHidden = "/health-check"
         pathNotHidden = "/foobar"
 
diff --git a/wai-extra.cabal b/wai-extra.cabal
--- a/wai-extra.cabal
+++ b/wai-extra.cabal
@@ -1,5 +1,5 @@
 Name:                wai-extra
-Version:             3.1.6
+Version:             3.1.7
 Synopsis:            Provides some basic WAI handlers and middleware.
 description:
   Provides basic WAI handler and middleware functionality:
@@ -87,7 +87,7 @@
   default:            False
 
 Library
-  Build-Depends:     base                      >= 4.10 && < 5
+  Build-Depends:     base                      >= 4.12 && < 5
                    , bytestring                >= 0.10.4
                    , wai                       >= 3.0.3.0  && < 3.3
                    , time                      >= 1.1.4
