refactor: simplify logger middleware

This commit is contained in:
Wolfgang Walther
2022-01-05 11:01:54 +01:00
committed by Wolfgang Walther
parent cde9cd4ab7
commit 826ae7459a
7 changed files with 73 additions and 54 deletions
+15 -43
View File
@@ -6,7 +6,6 @@ Description : Sets CORS policy. Also the PostgreSQL GUCs, role, search_path and
{-# LANGUAGE RecordWildCards #-}
module PostgREST.Middleware
( runPgLocals
, pgrstFormat
, pgrstMiddleware
, optionalRollback
) where
@@ -24,21 +23,16 @@ import qualified Hasql.DynamicStatements.Snippet as SQL hiding
import qualified Hasql.DynamicStatements.Statement as SQL
import qualified Hasql.Transaction as SQL
import qualified Network.Wai as Wai
import qualified Network.Wai.Logger as Wai
import qualified Network.Wai.Middleware.Cors as Wai
import qualified Network.Wai.Middleware.Gzip as Wai
import qualified Network.Wai.Middleware.RequestLogger as Wai
import Control.Arrow ((***))
import Data.Function (id)
import Data.List (lookup)
import Data.Scientific (FPFormat (..), formatScientific,
isInteger)
import Network.HTTP.Types.Status (Status, status400, status500,
statusCode)
import Network.HTTP.Types.Status (status400, status500)
import System.IO.Unsafe (unsafePerformIO)
import System.Log.FastLogger (toLogStr)
import PostgREST.Config (AppConfig (..), LogLevel (..))
import PostgREST.Config.PgVersion (PgVersion (..), pgVersion140)
@@ -95,45 +89,23 @@ runPgLocals conf claims app req jsonDbS actualPgVersion = do
unquoted (JSON.Bool b) = show b
unquoted v = T.decodeUtf8 . LBS.toStrict $ JSON.encode v
-- | Log in apache format. Only requests that have a status greater than minStatus are logged.
-- | There's no way to filter logs in the apache format on wai-extra: https://hackage.haskell.org/package/wai-extra-3.0.29.2/docs/Network-Wai-Middleware-RequestLogger.html#t:OutputFormat.
-- | So here we copy wai-logger apacheLogStr function: https://github.com/kazu-yamamoto/logger/blob/a4f51b909a099c51af7a3f75cf16e19a06f9e257/wai-logger/Network/Wai/Logger/Apache.hs#L45
-- | TODO: Add the ability to filter apache logs on wai-extra and remove this function.
pgrstFormat :: Status -> Wai.OutputFormatter
pgrstFormat minStatus date req status responseSize =
if status < minStatus
then mempty
else toLogStr (getSourceFromSocket req)
<> " - - ["
<> toLogStr date
<> "] \""
<> toLogStr (Wai.requestMethod req)
<> " "
<> toLogStr (Wai.rawPathInfo req <> Wai.rawQueryString req)
<> " "
<> toLogStr (show (Wai.httpVersion req)::Text)
<> "\" "
<> toLogStr (show (statusCode status)::Text)
<> " "
<> toLogStr (maybe "-" show responseSize::Text)
<> " \""
<> toLogStr (fromMaybe mempty $ Wai.requestHeaderReferer req)
<> "\" \""
<> toLogStr (fromMaybe mempty $ Wai.requestHeaderUserAgent req)
<> "\"\n"
where
getSourceFromSocket = BS.pack . Wai.showSockAddr . Wai.remoteHost
pgrstMiddleware :: LogLevel -> Wai.Application -> Wai.Application
pgrstMiddleware :: LogLevel -> Wai.Middleware
pgrstMiddleware logLevel =
logger
logger logLevel
. Wai.cors corsPolicy
logger :: LogLevel -> Wai.Middleware
logger logLevel = case logLevel of
LogInfo -> requestLogger (const True)
LogWarn -> requestLogger (>= status400)
LogError -> requestLogger (>= status500)
LogCrit -> requestLogger (const False)
where
logger = case logLevel of
LogCrit -> id
LogError -> unsafePerformIO $ Wai.mkRequestLogger Wai.def { Wai.outputFormat = Wai.CustomOutputFormat $ pgrstFormat status500}
LogWarn -> unsafePerformIO $ Wai.mkRequestLogger Wai.def { Wai.outputFormat = Wai.CustomOutputFormat $ pgrstFormat status400}
LogInfo -> Wai.logStdout
requestLogger filterStatus = unsafePerformIO $ Wai.mkRequestLogger Wai.defaultRequestLoggerSettings
{ Wai.outputFormat = Wai.ApacheWithSettings $
Wai.defaultApacheSettings
& Wai.setApacheRequestFilter (\_ res -> filterStatus $ Wai.responseStatus res)
}
-- | CORS policy to be used in by Wai Cors middleware
corsPolicy :: Wai.Request -> Maybe Wai.CorsResourcePolicy