-- | Add information about the 'Network.Wai.Request', 'Network.Wai.Response', -- and the response time to Katip's 'Katip.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":"curl/8.9.1"},"httpVersion":"HTTP/1.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":"curl/8.9.1"},"httpVersion":"HTTP/1.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":"src/Katip/Wai/Example/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":"curl/8.9.1"},"httpVersion":"HTTP/1.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"} -- @ module Katip.Wai ( -- * Middleware -- | 'Network.Wai.Middleware' for logging request and response information. Middleware.middleware , Middleware.middlewareCustom -- ** Helpers -- | Since logging with @Katip@ is monadic, we need the ability to run an -- 'Network.Wai.Application' or 'Network.Wai.Middleware' in a monad other -- than @IO@. , Middleware.ApplicationT , Middleware.MiddlewareT , Middleware.runApplication -- * Options -- | Options for customizing the way 'Middleware.middlewareCustom' handles the requests and responses. , Options.Options (..) , Options.addRequestAndResponseToContext , Options.logRequestAndResponse , Options.options , Options.defaultOptions -- ** Formatting -- | Functions for formatting the 'Request.Request's and 'Response.Response's. , Options.Formatter , Options.TimeUnit (..) , Options.IncludedHeaders , Options.defaultIncludedHeaders , Options.defaultRequestFormat , Options.defaultResponseFormat -- * Request , Request.Request (..) , Request.traceRequest -- * Response , Response.Response (..) , Response.traceResponse ) where import qualified Katip.Wai.Middleware as Middleware import qualified Katip.Wai.Options as Options import qualified Katip.Wai.Request as Request import qualified Katip.Wai.Response as Response