{-# LANGUAGE CPP #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE NamedFieldPuns #-}
{-# LANGUAGE OverloadedStrings #-}
module Control.Monad.Logger.Aeson
(
Message(..)
, SeriesElem
, LoggedMessage(..)
, logDebug
, logInfo
, logWarn
, logError
, logOther
, logDebugCS
, logInfoCS
, logWarnCS
, logErrorCS
, logOtherCS
, logDebugNS
, logInfoNS
, logWarnNS
, logErrorNS
, logOtherNS
, logDebugN
, logInfoN
, logWarnN
, logErrorN
, logOtherN
, withThreadContext
, myThreadContext
, runFileLoggingT
, runHandleLoggingT
, runStdoutLoggingT
, runStderrLoggingT
, runFastLoggingT
, defaultOutput
, handleOutput
, fastLoggerOutput
, defaultOutputWith
, defaultOutputOptions
, OutputOptions
, outputIncludeThreadId
, outputBaseThreadContext
, defaultLogStr
, defaultHandleFromLevel
, (.=)
, module Log
) where
import Control.Monad.Logger as Log hiding
( logDebug
, logInfo
, logWarn
, logError
, logOther
, logDebugCS
, logInfoCS
, logWarnCS
, logErrorCS
, logOtherCS
, logWithoutLoc
, logDebugN
, logInfoN
, logWarnN
, logErrorN
, logOtherN
, logDebugNS
, logInfoNS
, logWarnNS
, logErrorNS
, logOtherNS
, runFileLoggingT
, runStderrLoggingT
, runStdoutLoggingT
#if MIN_VERSION_monad_logger(0,3,36)
, defaultOutput
#endif
, defaultLogStr
)
import Control.Monad.Catch (MonadMask, MonadThrow)
import Control.Monad.IO.Class (MonadIO(liftIO))
import Control.Monad.Logger.Aeson.Internal
( LoggedMessage(..), Message(..), OutputOptions(..), KeyMap, SeriesElem
)
import Data.Aeson (KeyValue((.=)), Value(String))
import Data.Aeson.Types (Pair)
import Data.Text (Text)
import Data.Time (UTCTime)
import GHC.Stack (CallStack, HasCallStack, callStack)
import System.IO
( BufferMode(LineBuffering), IOMode(AppendMode), Handle, hClose, hSetBuffering, openFile, stderr
, stdout
)
import System.Log.FastLogger (LoggerSet)
import qualified Context
import qualified Control.Concurrent as Concurrent
import qualified Control.Monad.Catch as Catch
import qualified Control.Monad.Logger.Aeson.Internal as Internal
import qualified Data.ByteString.Char8 as BS8
import qualified Data.Text as Text
import qualified Data.Time as Time
import qualified System.Log.FastLogger as FastLogger
logDebug :: (HasCallStack, MonadLogger m) => Message -> m ()
logDebug :: forall (m :: * -> *).
(HasCallStack, MonadLogger m) =>
Message -> m ()
logDebug = forall (m :: * -> *). MonadLogger m => CallStack -> Message -> m ()
logDebugCS HasCallStack => CallStack
callStack
logInfo :: (HasCallStack, MonadLogger m) => Message -> m ()
logInfo :: forall (m :: * -> *).
(HasCallStack, MonadLogger m) =>
Message -> m ()
logInfo = forall (m :: * -> *). MonadLogger m => CallStack -> Message -> m ()
logInfoCS HasCallStack => CallStack
callStack
logWarn :: (HasCallStack, MonadLogger m) => Message -> m ()
logWarn :: forall (m :: * -> *).
(HasCallStack, MonadLogger m) =>
Message -> m ()
logWarn = forall (m :: * -> *). MonadLogger m => CallStack -> Message -> m ()
logWarnCS HasCallStack => CallStack
callStack
logError :: (HasCallStack, MonadLogger m) => Message -> m ()
logError :: forall (m :: * -> *).
(HasCallStack, MonadLogger m) =>
Message -> m ()
logError = forall (m :: * -> *). MonadLogger m => CallStack -> Message -> m ()
logErrorCS HasCallStack => CallStack
callStack
logOther :: (HasCallStack, MonadLogger m) => LogLevel -> Message -> m ()
logOther :: forall (m :: * -> *).
(HasCallStack, MonadLogger m) =>
LogLevel -> Message -> m ()
logOther = forall (m :: * -> *).
MonadLogger m =>
CallStack -> LogLevel -> Message -> m ()
logOtherCS HasCallStack => CallStack
callStack
logDebugCS :: (MonadLogger m) => CallStack -> Message -> m ()
logDebugCS :: forall (m :: * -> *). MonadLogger m => CallStack -> Message -> m ()
logDebugCS CallStack
cs Message
msg = forall (m :: * -> *).
MonadLogger m =>
CallStack -> LogSource -> LogLevel -> Message -> m ()
Internal.logCS CallStack
cs LogSource
"" LogLevel
LevelDebug Message
msg
logInfoCS :: (MonadLogger m) => CallStack -> Message -> m ()
logInfoCS :: forall (m :: * -> *). MonadLogger m => CallStack -> Message -> m ()
logInfoCS CallStack
cs Message
msg = forall (m :: * -> *).
MonadLogger m =>
CallStack -> LogSource -> LogLevel -> Message -> m ()
Internal.logCS CallStack
cs LogSource
"" LogLevel
LevelInfo Message
msg
logWarnCS :: (MonadLogger m) => CallStack -> Message -> m ()
logWarnCS :: forall (m :: * -> *). MonadLogger m => CallStack -> Message -> m ()
logWarnCS CallStack
cs Message
msg = forall (m :: * -> *).
MonadLogger m =>
CallStack -> LogSource -> LogLevel -> Message -> m ()
Internal.logCS CallStack
cs LogSource
"" LogLevel
LevelWarn Message
msg
logOtherCS :: (MonadLogger m) => CallStack -> LogLevel -> Message -> m ()
logOtherCS :: forall (m :: * -> *).
MonadLogger m =>
CallStack -> LogLevel -> Message -> m ()
logOtherCS CallStack
cs LogLevel
lvl Message
msg = forall (m :: * -> *).
MonadLogger m =>
CallStack -> LogSource -> LogLevel -> Message -> m ()
Internal.logCS CallStack
cs LogSource
"" LogLevel
lvl Message
msg
logErrorCS :: (MonadLogger m) => CallStack -> Message -> m ()
logErrorCS :: forall (m :: * -> *). MonadLogger m => CallStack -> Message -> m ()
logErrorCS CallStack
cs Message
msg = forall (m :: * -> *).
MonadLogger m =>
CallStack -> LogSource -> LogLevel -> Message -> m ()
Internal.logCS CallStack
cs LogSource
"" LogLevel
LevelError Message
msg
logDebugN :: (HasCallStack, MonadLogger m) => Message -> m ()
logDebugN :: forall (m :: * -> *).
(HasCallStack, MonadLogger m) =>
Message -> m ()
logDebugN = forall (m :: * -> *). MonadLogger m => CallStack -> Message -> m ()
logDebugCS HasCallStack => CallStack
callStack
logInfoN :: (HasCallStack, MonadLogger m) => Message -> m ()
logInfoN :: forall (m :: * -> *).
(HasCallStack, MonadLogger m) =>
Message -> m ()
logInfoN = forall (m :: * -> *). MonadLogger m => CallStack -> Message -> m ()
logInfoCS HasCallStack => CallStack
callStack
logWarnN :: (HasCallStack, MonadLogger m) => Message -> m ()
logWarnN :: forall (m :: * -> *).
(HasCallStack, MonadLogger m) =>
Message -> m ()
logWarnN = forall (m :: * -> *). MonadLogger m => CallStack -> Message -> m ()
logWarnCS HasCallStack => CallStack
callStack
logErrorN :: (HasCallStack, MonadLogger m) => Message -> m ()
logErrorN :: forall (m :: * -> *).
(HasCallStack, MonadLogger m) =>
Message -> m ()
logErrorN = forall (m :: * -> *). MonadLogger m => CallStack -> Message -> m ()
logErrorCS HasCallStack => CallStack
callStack
logOtherN :: (HasCallStack, MonadLogger m) => LogLevel -> Message -> m ()
logOtherN :: forall (m :: * -> *).
(HasCallStack, MonadLogger m) =>
LogLevel -> Message -> m ()
logOtherN = forall (m :: * -> *).
MonadLogger m =>
CallStack -> LogLevel -> Message -> m ()
logOtherCS HasCallStack => CallStack
callStack
logDebugNS :: (HasCallStack, MonadLogger m) => LogSource -> Message -> m ()
logDebugNS :: forall (m :: * -> *).
(HasCallStack, MonadLogger m) =>
LogSource -> Message -> m ()
logDebugNS LogSource
src = forall (m :: * -> *).
MonadLogger m =>
CallStack -> LogSource -> LogLevel -> Message -> m ()
Internal.logCS HasCallStack => CallStack
callStack LogSource
src LogLevel
LevelDebug
logInfoNS :: (HasCallStack, MonadLogger m) => LogSource -> Message -> m ()
logInfoNS :: forall (m :: * -> *).
(HasCallStack, MonadLogger m) =>
LogSource -> Message -> m ()
logInfoNS LogSource
src = forall (m :: * -> *).
MonadLogger m =>
CallStack -> LogSource -> LogLevel -> Message -> m ()
Internal.logCS HasCallStack => CallStack
callStack LogSource
src LogLevel
LevelInfo
logWarnNS :: (HasCallStack, MonadLogger m) => LogSource -> Message -> m ()
logWarnNS :: forall (m :: * -> *).
(HasCallStack, MonadLogger m) =>
LogSource -> Message -> m ()
logWarnNS LogSource
src = forall (m :: * -> *).
MonadLogger m =>
CallStack -> LogSource -> LogLevel -> Message -> m ()
Internal.logCS HasCallStack => CallStack
callStack LogSource
src LogLevel
LevelWarn
logErrorNS :: (HasCallStack, MonadLogger m) => LogSource -> Message -> m ()
logErrorNS :: forall (m :: * -> *).
(HasCallStack, MonadLogger m) =>
LogSource -> Message -> m ()
logErrorNS LogSource
src = forall (m :: * -> *).
MonadLogger m =>
CallStack -> LogSource -> LogLevel -> Message -> m ()
Internal.logCS HasCallStack => CallStack
callStack LogSource
src LogLevel
LevelError
logOtherNS :: (HasCallStack, MonadLogger m) => LogSource -> LogLevel -> Message -> m ()
logOtherNS :: forall (m :: * -> *).
(HasCallStack, MonadLogger m) =>
LogSource -> LogLevel -> Message -> m ()
logOtherNS = forall (m :: * -> *).
MonadLogger m =>
CallStack -> LogSource -> LogLevel -> Message -> m ()
Internal.logCS HasCallStack => CallStack
callStack
withThreadContext :: (MonadIO m, MonadMask m) => [Pair] -> m a -> m a
withThreadContext :: forall (m :: * -> *) a.
(MonadIO m, MonadMask m) =>
[Pair] -> m a -> m a
withThreadContext [Pair]
pairs =
forall (m :: * -> *) ctx a.
(MonadIO m, MonadMask m) =>
Store ctx -> (ctx -> ctx) -> m a -> m a
Context.adjust Store (KeyMap Value)
Internal.threadContextStore forall a b. (a -> b) -> a -> b
$ \KeyMap Value
pairsMap ->
forall v. KeyMap v -> KeyMap v -> KeyMap v
Internal.keyMapUnion (forall v. [(Key, v)] -> KeyMap v
Internal.keyMapFromList [Pair]
pairs) KeyMap Value
pairsMap
myThreadContext :: (MonadIO m, MonadThrow m) => m (KeyMap Value)
myThreadContext :: forall (m :: * -> *). (MonadIO m, MonadThrow m) => m (KeyMap Value)
myThreadContext = do
forall (m :: * -> *) ctx.
(MonadIO m, MonadThrow m) =>
Store ctx -> m ctx
Context.mine Store (KeyMap Value)
Internal.threadContextStore
runFileLoggingT :: (MonadIO m, MonadMask m) => FilePath -> LoggingT m a -> m a
runFileLoggingT :: forall (m :: * -> *) a.
(MonadIO m, MonadMask m) =>
FilePath -> LoggingT m a -> m a
runFileLoggingT FilePath
filePath LoggingT m a
action =
forall (m :: * -> *) a c b.
MonadMask m =>
m a -> (a -> m c) -> (a -> m b) -> m b
Catch.bracket (forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall a b. (a -> b) -> a -> b
$ FilePath -> IOMode -> IO Handle
openFile FilePath
filePath IOMode
AppendMode) (forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall b c a. (b -> c) -> (a -> b) -> a -> c
. Handle -> IO ()
hClose) forall a b. (a -> b) -> a -> b
$ \Handle
h -> do
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall a b. (a -> b) -> a -> b
$ Handle -> BufferMode -> IO ()
hSetBuffering Handle
h BufferMode
LineBuffering
forall (m :: * -> *) a.
LoggingT m a
-> (Loc -> LogSource -> LogLevel -> LogStr -> IO ()) -> m a
runLoggingT LoggingT m a
action forall a b. (a -> b) -> a -> b
$ Handle -> Loc -> LogSource -> LogLevel -> LogStr -> IO ()
defaultOutput Handle
h
runStderrLoggingT :: LoggingT m a -> m a
runStderrLoggingT :: forall (m :: * -> *) a. LoggingT m a -> m a
runStderrLoggingT = forall a b c. (a -> b -> c) -> b -> a -> c
flip forall (m :: * -> *) a.
LoggingT m a
-> (Loc -> LogSource -> LogLevel -> LogStr -> IO ()) -> m a
runLoggingT (Handle -> Loc -> LogSource -> LogLevel -> LogStr -> IO ()
defaultOutput Handle
stderr)
runStdoutLoggingT :: LoggingT m a -> m a
runStdoutLoggingT :: forall (m :: * -> *) a. LoggingT m a -> m a
runStdoutLoggingT = forall a b c. (a -> b -> c) -> b -> a -> c
flip forall (m :: * -> *) a.
LoggingT m a
-> (Loc -> LogSource -> LogLevel -> LogStr -> IO ()) -> m a
runLoggingT (Handle -> Loc -> LogSource -> LogLevel -> LogStr -> IO ()
defaultOutput Handle
stdout)
runHandleLoggingT :: (LogLevel -> Handle) -> LoggingT m a -> m a
runHandleLoggingT :: forall (m :: * -> *) a. (LogLevel -> Handle) -> LoggingT m a -> m a
runHandleLoggingT = forall a b c. (a -> b -> c) -> b -> a -> c
flip forall (m :: * -> *) a.
LoggingT m a
-> (Loc -> LogSource -> LogLevel -> LogStr -> IO ()) -> m a
runLoggingT forall b c a. (b -> c) -> (a -> b) -> a -> c
. (LogLevel -> Handle)
-> Loc -> LogSource -> LogLevel -> LogStr -> IO ()
handleOutput
runFastLoggingT :: LoggerSet -> LoggingT m a -> m a
runFastLoggingT :: forall (m :: * -> *) a. LoggerSet -> LoggingT m a -> m a
runFastLoggingT LoggerSet
loggerSet = forall a b c. (a -> b -> c) -> b -> a -> c
flip forall (m :: * -> *) a.
LoggingT m a
-> (Loc -> LogSource -> LogLevel -> LogStr -> IO ()) -> m a
runLoggingT (LoggerSet -> Loc -> LogSource -> LogLevel -> LogStr -> IO ()
fastLoggerOutput LoggerSet
loggerSet)
defaultOutput
:: Handle
-> Loc
-> LogSource
-> LogLevel
-> LogStr
-> IO ()
defaultOutput :: Handle -> Loc -> LogSource -> LogLevel -> LogStr -> IO ()
defaultOutput Handle
handle = (LogLevel -> Handle)
-> Loc -> LogSource -> LogLevel -> LogStr -> IO ()
handleOutput (forall a b. a -> b -> a
const Handle
handle)
defaultOutputOptions :: (LogLevel -> BS8.ByteString -> IO ()) -> OutputOptions
defaultOutputOptions :: (LogLevel -> ByteString -> IO ()) -> OutputOptions
defaultOutputOptions LogLevel -> ByteString -> IO ()
outputAction =
OutputOptions
{ LogLevel -> ByteString -> IO ()
outputAction :: LogLevel -> ByteString -> IO ()
outputAction :: LogLevel -> ByteString -> IO ()
outputAction
, outputIncludeThreadId :: Bool
outputIncludeThreadId = Bool
False
, outputBaseThreadContext :: [Pair]
outputBaseThreadContext = []
}
defaultOutputWith
:: OutputOptions
-> Loc
-> LogSource
-> LogLevel
-> LogStr
-> IO ()
defaultOutputWith :: OutputOptions -> Loc -> LogSource -> LogLevel -> LogStr -> IO ()
defaultOutputWith OutputOptions
outputOptions Loc
location LogSource
logSource LogLevel
logLevel LogStr
msg = do
UTCTime
now <- IO UTCTime
Time.getCurrentTime
LogSource
threadIdText <- forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (FilePath -> LogSource
Text.pack forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Show a => a -> FilePath
show) IO ThreadId
Concurrent.myThreadId
KeyMap Value
threadContext <- forall (m :: * -> *) ctx a.
(MonadIO m, MonadThrow m) =>
Store ctx -> (ctx -> a) -> m a
Context.mines Store (KeyMap Value)
Internal.threadContextStore forall a b. (a -> b) -> a -> b
$ \KeyMap Value
hashMap ->
( if Bool
outputIncludeThreadId then
forall v. Key -> v -> KeyMap v -> KeyMap v
Internal.keyMapInsert Key
"tid" forall a b. (a -> b) -> a -> b
$ LogSource -> Value
String LogSource
threadIdText
else
forall a. a -> a
id
) forall a b. (a -> b) -> a -> b
$ forall v. KeyMap v -> KeyMap v -> KeyMap v
Internal.keyMapUnion KeyMap Value
hashMap forall a b. (a -> b) -> a -> b
$ KeyMap Value
baseThreadContextHashMap
LogLevel -> ByteString -> IO ()
outputAction LogLevel
logLevel
forall a b. (a -> b) -> a -> b
$ UTCTime
-> KeyMap Value
-> Loc
-> LogSource
-> LogLevel
-> LogStr
-> ByteString
Internal.defaultLogStrBS UTCTime
now KeyMap Value
threadContext Loc
location LogSource
logSource LogLevel
logLevel LogStr
msg
where
baseThreadContextHashMap :: KeyMap Value
baseThreadContextHashMap = forall v. [(Key, v)] -> KeyMap v
Internal.keyMapFromList [Pair]
outputBaseThreadContext
OutputOptions
{ LogLevel -> ByteString -> IO ()
outputAction :: LogLevel -> ByteString -> IO ()
outputAction :: OutputOptions -> LogLevel -> ByteString -> IO ()
outputAction
, Bool
outputIncludeThreadId :: Bool
outputIncludeThreadId :: OutputOptions -> Bool
outputIncludeThreadId
, [Pair]
outputBaseThreadContext :: [Pair]
outputBaseThreadContext :: OutputOptions -> [Pair]
outputBaseThreadContext
} = OutputOptions
outputOptions
handleOutput
:: (LogLevel -> Handle)
-> Loc
-> LogSource
-> LogLevel
-> LogStr
-> IO ()
handleOutput :: (LogLevel -> Handle)
-> Loc -> LogSource -> LogLevel -> LogStr -> IO ()
handleOutput LogLevel -> Handle
levelToHandle =
OutputOptions -> Loc -> LogSource -> LogLevel -> LogStr -> IO ()
defaultOutputWith forall a b. (a -> b) -> a -> b
$ (LogLevel -> ByteString -> IO ()) -> OutputOptions
defaultOutputOptions forall a b. (a -> b) -> a -> b
$ \LogLevel
logLevel ByteString
bytes -> do
Handle -> ByteString -> IO ()
BS8.hPutStrLn (LogLevel -> Handle
levelToHandle LogLevel
logLevel) ByteString
bytes
fastLoggerOutput
:: LoggerSet
-> Loc
-> LogSource
-> LogLevel
-> LogStr
-> IO ()
fastLoggerOutput :: LoggerSet -> Loc -> LogSource -> LogLevel -> LogStr -> IO ()
fastLoggerOutput LoggerSet
loggerSet =
OutputOptions -> Loc -> LogSource -> LogLevel -> LogStr -> IO ()
defaultOutputWith forall a b. (a -> b) -> a -> b
$ (LogLevel -> ByteString -> IO ()) -> OutputOptions
defaultOutputOptions forall a b. (a -> b) -> a -> b
$ \LogLevel
_logLevel ByteString
bytes -> do
LoggerSet -> LogStr -> IO ()
FastLogger.pushLogStrLn LoggerSet
loggerSet forall a b. (a -> b) -> a -> b
$ forall msg. ToLogStr msg => msg -> LogStr
toLogStr ByteString
bytes
defaultLogStr
:: UTCTime
-> KeyMap Value
-> Loc
-> LogSource
-> LogLevel
-> LogStr
-> LogStr
defaultLogStr :: UTCTime
-> KeyMap Value -> Loc -> LogSource -> LogLevel -> LogStr -> LogStr
defaultLogStr UTCTime
now KeyMap Value
threadContext Loc
loc LogSource
logSource LogLevel
logLevel LogStr
logStr =
forall msg. ToLogStr msg => msg -> LogStr
toLogStr
forall a b. (a -> b) -> a -> b
$ UTCTime
-> KeyMap Value
-> Loc
-> LogSource
-> LogLevel
-> LogStr
-> ByteString
Internal.defaultLogStrBS UTCTime
now KeyMap Value
threadContext Loc
loc LogSource
logSource LogLevel
logLevel LogStr
logStr
defaultHandleFromLevel :: (Text -> Handle) -> LogLevel -> Handle
defaultHandleFromLevel :: (LogSource -> Handle) -> LogLevel -> Handle
defaultHandleFromLevel LogSource -> Handle
otherLevelToHandle = \case
LogLevel
LevelDebug -> Handle
stdout
LogLevel
LevelInfo -> Handle
stdout
LogLevel
LevelWarn -> Handle
stderr
LogLevel
LevelError -> Handle
stderr
LevelOther LogSource
otherLevel -> LogSource -> Handle
otherLevelToHandle LogSource
otherLevel