module Log.Internal.Logger (
Logger(..)
, execLogger
, waitForLogger
, shutdownLogger
, withLogger
) where
import Data.Semigroup
import Control.Exception
import Prelude
import Log.Data
data Logger = Logger {
loggerWriteMessage :: !(LogMessage -> IO ())
, loggerWaitForWrite :: !(IO ())
, loggerShutdown :: !(IO ())
}
execLogger :: Logger -> LogMessage -> IO ()
execLogger Logger{..} = loggerWriteMessage
waitForLogger :: Logger -> IO ()
waitForLogger Logger{..} = loggerWaitForWrite
shutdownLogger :: Logger -> IO ()
shutdownLogger Logger{..} = loggerShutdown
withLogger :: Logger -> (Logger -> IO r) -> IO r
withLogger logger act = act logger `finally` cleanup
where
cleanup = waitForLogger logger >> shutdownLogger logger
instance Semigroup Logger where
l1 <> l2 = Logger {
loggerWriteMessage = \msg -> do
loggerWriteMessage l1 msg
loggerWriteMessage l2 msg
, loggerWaitForWrite = do
loggerWaitForWrite l1
loggerWaitForWrite l2
, loggerShutdown = do
loggerShutdown l1
loggerShutdown l2
}
instance Monoid Logger where
mempty = Logger (const $ return ()) (return ()) (return ())
mappend = (<>)