{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE ScopedTypeVariables #-}
module OpenAPIPetstore.LoggingMonadLogger where
import qualified Control.Exception.Safe as E
import qualified Control.Monad.IO.Class as P
import qualified Data.Text as T
import qualified Data.Time as TI
import Data.Monoid ((<>))
import Data.Text (Text)
import qualified Control.Monad.Logger as LG
type LogExecWithContext = forall m. P.MonadIO m =>
LogContext -> LogExec m
type LogExec m = forall a. LG.LoggingT m a -> m a
type LogContext = LG.LogSource -> LG.LogLevel -> Bool
type LogLevel = LG.LogLevel
initLogContext :: IO LogContext
initLogContext = pure infoLevelFilter
runDefaultLogExecWithContext :: LogExecWithContext
runDefaultLogExecWithContext = runNullLogExec
stdoutLoggingExec :: LogExecWithContext
stdoutLoggingExec cxt = LG.runStdoutLoggingT . LG.filterLogger cxt
stdoutLoggingContext :: LogContext -> IO LogContext
stdoutLoggingContext = pure
stderrLoggingExec :: LogExecWithContext
stderrLoggingExec cxt = LG.runStderrLoggingT . LG.filterLogger cxt
stderrLoggingContext :: LogContext -> IO LogContext
stderrLoggingContext = pure
runNullLogExec :: LogExecWithContext
runNullLogExec = const (`LG.runLoggingT` nullLogger)
nullLogger :: LG.Loc -> LG.LogSource -> LG.LogLevel -> LG.LogStr -> IO ()
nullLogger _ _ _ _ = return ()
_log :: (P.MonadIO m, LG.MonadLogger m) => Text -> LG.LogLevel -> Text -> m ()
_log src level msg = do
now <- P.liftIO (formatTimeLog <$> TI.getCurrentTime)
LG.logOtherNS ("OpenAPIPetstore." <> src) level ("[" <> now <> "] " <> msg)
where
formatTimeLog =
T.pack . TI.formatTime TI.defaultTimeLocale "%Y-%m-%dT%H:%M:%S%Z"
logExceptions
:: (LG.MonadLogger m, E.MonadCatch m, P.MonadIO m)
=> Text -> m a -> m a
logExceptions src =
E.handle
(\(e :: E.SomeException) -> do
_log src LG.LevelError ((T.pack . show) e)
E.throw e)
levelInfo :: LogLevel
levelInfo = LG.LevelInfo
levelError :: LogLevel
levelError = LG.LevelError
levelDebug :: LogLevel
levelDebug = LG.LevelDebug
minLevelFilter :: LG.LogLevel -> LG.LogSource -> LG.LogLevel -> Bool
minLevelFilter l _ l' = l' >= l
infoLevelFilter :: LG.LogSource -> LG.LogLevel -> Bool
infoLevelFilter = minLevelFilter LG.LevelInfo