Wai package:katip-wai

Add information about the Request, Response, and the response time to Katip's LogContexts. Example setup:
import Control.Exception (bracket)
import Data.Proxy (Proxy (Proxy))
import Katip qualified
import Katip.Wai (ApplicationT, runApplication)
import Katip.Wai qualified
import Network.Wai.Handler.Warp qualified as Warp
import Servant qualified
import System.IO (stdout)
import UnliftIO (MonadUnliftIO (withRunInIO))


type Api = Servant.GetNoContent


server :: Servant.ServerT Api (Katip.KatipContextT Servant.Handler)
server = do
Katip.logLocM Katip.InfoS "This message should also have the request context"
pure Servant.NoContent


mkApplication :: ApplicationT (Katip.KatipContextT IO)
mkApplication = Katip.Wai.middleware Katip.InfoS $ request send -> do
logEnv <- Katip.getLogEnv
context <- Katip.getKatipContext
namespace <- Katip.getKatipNamespace

let hoistedApp =
let proxy = Proxy @Api
hoistedServer = Servant.hoistServer proxy (Katip.runKatipContextT logEnv context namespace) server
in Servant.serve proxy hoistedServer

withRunInIO $ toIO -> hoistedApp request (toIO . send)


withLogEnv :: (Katip.LogEnv -> IO a) -> IO a
withLogEnv useLogEnv = do
handleScribe <-
Katip.mkHandleScribeWithFormatter
Katip.jsonFormat
(Katip.ColorLog False)
stdout
(Katip.permitItem minBound)
Katip.V3

let makeLogEnv =
Katip.initLogEnv "example-app" "local-dev"
>>= Katip.registerScribe "stdout" handleScribe Katip.defaultScribeSettings

bracket makeLogEnv Katip.closeScribes useLogEnv


main :: IO ()
main = withLogEnv $ logEnv ->
let
app = runApplication (Katip.runKatipContextT logEnv () "main") mkApplication
in
Warp.run 5555 app
Example output:
{"app":["example-app"],"at":"2024-09-07T18:44:10.411097829Z","data":{"request":{"headers":{Host:"localhost:5555","User-Agent":"curl8.9.1"},"httpVersion":"HTTP1.1","id":"7ec0fbc4-722c-4c70-a168-c2abe5c7b4fa","isSecure":false,"method":GET,"path":"/","queryString":[],"receivedAt":"2024-09-07T18:44:10.411057334Z","remoteHost":"127.0.0.1:51230"}},"env":"local-dev","host":"x1g11","loc":null,"msg":"Request received.","ns":["example-app","main"],"pid":"106249","sev":Info,"thread":"27"}
{"app":["example-app"],"at":"2024-09-07T18:44:10.411097829Z","data":{"request":{"headers":{Host:"localhost:5555","User-Agent":"curl8.9.1"},"httpVersion":"HTTP1.1","id":"7ec0fbc4-722c-4c70-a168-c2abe5c7b4fa","isSecure":false,"method":GET,"path":"","queryString":[],"receivedAt":"2024-09-07T18:44:10.411057334Z","remoteHost":"127.0.0.1:51230"}},"env":"local-dev","host":"x1g11","loc":{"loc_col":3,"loc_fn":"srcKatipWaiExample/Short.hs","loc_ln":19,"loc_mod":Katip.Wai.Example.Short,"loc_pkg":"my-katip-wai-example-0.1.0.0-inplace"},"msg":"This message should also have the request context","ns":["example-app","main"],"pid":"106249","sev":Info,"thread":"27"}
{"app":["example-app"],"at":"2024-09-07T18:44:10.411097829Z","data":{"request":{"headers":{Host:"localhost:5555","User-Agent":"curl8.9.1"},"httpVersion":"HTTP1.1","id":"7ec0fbc4-722c-4c70-a168-c2abe5c7b4fa","isSecure":false,"method":GET,"path":"/","queryString":[],"receivedAt":"2024-09-07T18:44:10.411057334Z","remoteHost":"127.0.0.1:51230"},"response":{"headers":{},"respondedAt":"2024-09-07T18:44:10.411199014Z","responseTime":{"time":0.137369,"unit":"ms"},"status":{"code":204,"message":"No Content"}}},"env":"local-dev","host":"x1g11","loc":null,"msg":"Response sent.","ns":["example-app","main"],"pid":"106249","sev":Info,"thread":"27"}
WAI middleware for logging request and response info through katip. WAI middleware for logging request and response info through katip. Please see the README on GitHub at https://github.com/Disco-Dave/katip-wai#readme