Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I log an entire HTTP request in WAI/scotty?

Tags:

haskell

I currently run the middleware logStdoutDev from Network.Wai.Middleware.RequestLogger, but it only logs the path and the Accept header (possibly other headers too). I want to see the body of the POST and PUT requests as well. This body happens to be json, so just printing it to stdout will do fine.

I have searched for a WAI middleware that logs everything but have not found any. I don't really know enough about WAI internals to write something that extracts POST body and then puts it back in myself, so I was hoping to avoid that learning curve right now.

like image 394
Gurgeh Avatar asked May 02 '13 12:05

Gurgeh


2 Answers

WAI Middleware is just a transformation over Application:

type Middleware = Application -> Application

And Application is just a handler:

type Application = Request -> (Response -> IO ResponseReceived) -> IO ResponseReceived

All you need to do is define handler that will log whatever you want and delegate "real work" downstream:

-- note that this is equivalent to Application -> Application
logAllMiddleware :: Application -> Request -> (Response -> IO ResponseReceived) -> IO ResponseReceived
logAllMiddleware app req respond = do
    print . unpack . requestBody req
    app req respond

Please keep in mind that I wrote this code without access to ghc. It may not be completely correct.

like image 178
joozek Avatar answered Nov 07 '22 23:11

joozek


This functionality is provided from the wai-extra package.

{-# LANGUAGE OverloadedStrings #-}

import Web.Scotty
import Network.HTTP.Types
import Network.Wai.Middleware.RequestLogger

main = scotty 3000 $ do
  middleware logStdoutDev
  get "/" $ do
    text "example"

Example output:

Setting phasers to stun... (port 3000) (ctrl-c to quit)
GET /
  Accept: */*
  Status: 200 OK 0.000050947s
like image 4
Chris Stryczynski Avatar answered Nov 07 '22 23:11

Chris Stryczynski