diff --git a/ChangeLog.md b/ChangeLog.md
--- a/ChangeLog.md
+++ b/ChangeLog.md
@@ -1,3 +1,7 @@
+## 0.5.5
+
+* http-client should allow to log requests and responses [#248](https://github.com/snoyberg/http-client/issues/248)
+
 ## 0.5.4
 
 * Derive ‘Eq’ for ‘ResponseTimeout’ [#239](https://github.com/snoyberg/http-client/pull/239)
diff --git a/Network/HTTP/Client.hs b/Network/HTTP/Client.hs
--- a/Network/HTTP/Client.hs
+++ b/Network/HTTP/Client.hs
@@ -108,6 +108,7 @@
     , managerWrapException
     , managerIdleConnectionCount
     , managerModifyRequest
+    , managerModifyResponse
       -- *** Manager proxy settings
     , managerSetProxy
     , managerSetInsecureProxy
diff --git a/Network/HTTP/Client/Body.hs b/Network/HTTP/Client/Body.hs
--- a/Network/HTTP/Client/Body.hs
+++ b/Network/HTTP/Client/Body.hs
@@ -7,6 +7,7 @@
     , makeUnlimitedReader
     , brConsume
     , brEmpty
+    , constBodyReader
     , brAddCleanup
     , brReadSome
     , brRead
@@ -51,6 +52,14 @@
 
 brEmpty :: BodyReader
 brEmpty = return S.empty
+
+constBodyReader :: [S.ByteString] -> IO BodyReader
+constBodyReader input = do
+  iinput <- newIORef input
+  return $ atomicModifyIORef iinput $ \input' ->
+        case input' of
+            [] -> ([], S.empty)
+            x:xs -> (xs, x)
 
 brAddCleanup :: IO () -> BodyReader -> BodyReader
 brAddCleanup cleanup brRead' = do
diff --git a/Network/HTTP/Client/Core.hs b/Network/HTTP/Client/Core.hs
--- a/Network/HTTP/Client/Core.hs
+++ b/Network/HTTP/Client/Core.hs
@@ -196,7 +196,7 @@
   wrapExc req0 $ mWrapException manager req0 $ do
     (req, res) <- go manager (redirectCount req0) req0
     checkResponse req req res
-    return res
+    mModifyResponse manager res
         { responseBody = wrapExc req0 (responseBody res)
         }
   where
diff --git a/Network/HTTP/Client/Manager.hs b/Network/HTTP/Client/Manager.hs
--- a/Network/HTTP/Client/Manager.hs
+++ b/Network/HTTP/Client/Manager.hs
@@ -110,6 +110,7 @@
          in handle wrapper
     , managerIdleConnectionCount = 512
     , managerModifyRequest = return
+    , managerModifyResponse = return
     , managerProxyInsecure = defaultProxy
     , managerProxySecure = defaultProxy
     }
@@ -194,6 +195,7 @@
             , mWrapException = managerWrapException ms
             , mIdleConnectionCount = managerIdleConnectionCount ms
             , mModifyRequest = managerModifyRequest ms
+            , mModifyResponse = managerModifyResponse ms
             , mSetProxy = \req ->
                 if secure req
                     then httpsProxy req
diff --git a/Network/HTTP/Client/Types.hs b/Network/HTTP/Client/Types.hs
--- a/Network/HTTP/Client/Types.hs
+++ b/Network/HTTP/Client/Types.hs
@@ -675,6 +675,12 @@
     -- Default: no modification
     --
     -- Since 0.4.4
+    , managerModifyResponse :: Response BodyReader -> IO (Response BodyReader)
+    -- ^ Perform the given modification to a @Response@ after receiving it.
+    --
+    -- Default: no modification
+    --
+    -- @since 0.5.5
     , managerProxyInsecure :: ProxyOverride
     -- ^ How HTTP proxy server settings should be discovered.
     --
@@ -724,6 +730,7 @@
     , mIdleConnectionCount :: Int
     , mModifyRequest :: Request -> IO Request
     , mSetProxy :: Request -> Request
+    , mModifyResponse      :: Response BodyReader -> IO (Response BodyReader)
     -- ^ See 'managerProxy'
     }
     deriving T.Typeable
diff --git a/http-client.cabal b/http-client.cabal
--- a/http-client.cabal
+++ b/http-client.cabal
@@ -1,5 +1,5 @@
 name:                http-client
-version:             0.5.4
+version:             0.5.5
 synopsis:            An HTTP client engine
 description:         Hackage documentation generation is not reliable. For up to date documentation, please see: <http://www.stackage.org/package/http-client>.
 homepage:            https://github.com/snoyberg/http-client
diff --git a/test/Network/HTTP/ClientSpec.hs b/test/Network/HTTP/ClientSpec.hs
--- a/test/Network/HTTP/ClientSpec.hs
+++ b/test/Network/HTTP/ClientSpec.hs
@@ -2,8 +2,11 @@
 module Network.HTTP.ClientSpec where
 
 import           Network                   (withSocketsDo)
+import qualified Data.ByteString.Char8        as BS
 import           Network.HTTP.Client
+import           Network.HTTP.Client.Internal
 import           Network.HTTP.Types        (status200, found302, status405)
+import           Network.HTTP.Types.Status
 import           Test.Hspec
 import           Control.Applicative       ((<$>))
 import           Data.ByteString.Lazy.Char8 () -- orphan instance
@@ -45,6 +48,32 @@
             man <- newManager defaultManagerSettings
             res <- httpLbs req man
             responseStatus res `shouldBe` found302
+
+    context "managerModifyResponse" $ do
+      it "allows to modify the response status code" $ do
+        let modify :: Response BodyReader -> IO (Response BodyReader)
+            modify res = do
+              return res {
+                responseStatus = (responseStatus res) {
+                  statusCode = 201
+                }
+              }
+            settings = defaultManagerSettings { managerModifyResponse = modify }
+        man <- newManager settings
+        res <- httpLbs "http://httpbin.org" man
+        (statusCode.responseStatus) res `shouldBe` 201
+
+      it "modifies the response body" $ do
+        let modify :: Response BodyReader -> IO (Response BodyReader)
+            modify res = do
+              reader <- constBodyReader [BS.pack "modified response body"]
+              return res {
+                responseBody = reader
+              }
+            settings = defaultManagerSettings { managerModifyResponse = modify }
+        man <- newManager settings
+        res <- httpLbs "http://httpbin.org" man
+        responseBody res `shouldBe` "modified response body"
 
     context "managerModifyRequest" $ do
         it "port" $ do
