-- | Stdout logging back-end.
module Log.Backend.StandardOutput
  ( withSimpleStdOutLogger
  , withStdOutLogger
  , withJsonStdOutLogger
  ) where

import Data.Aeson
import Prelude
import System.IO
import qualified Data.Text.IO as T
import qualified Data.ByteString.Lazy.Char8 as BSL

import Log.Data
import Log.Internal.Logger
import Log.Logger

-- | Create a simple, synchronous logger that prints messages to standard output
-- and flushes 'stdout' on each call to 'loggerWriteMessage' for the duration of
-- the given action.
withSimpleStdOutLogger :: (Logger -> IO r) -> IO r
withSimpleStdOutLogger :: (Logger -> IO r) -> IO r
withSimpleStdOutLogger = Logger -> (Logger -> IO r) -> IO r
forall r. Logger -> (Logger -> IO r) -> IO r
withLogger (Logger -> (Logger -> IO r) -> IO r)
-> Logger -> (Logger -> IO r) -> IO r
forall a b. (a -> b) -> a -> b
$ $WLogger :: (LogMessage -> IO ()) -> IO () -> IO () -> Logger
Logger
  { loggerWriteMessage :: LogMessage -> IO ()
loggerWriteMessage = \msg :: LogMessage
msg -> do
      Text -> IO ()
T.putStrLn (Text -> IO ()) -> Text -> IO ()
forall a b. (a -> b) -> a -> b
$ Maybe UTCTime -> LogMessage -> Text
showLogMessage Maybe UTCTime
forall a. Maybe a
Nothing LogMessage
msg
      Handle -> IO ()
hFlush Handle
stdout
  , loggerWaitForWrite :: IO ()
loggerWaitForWrite = () -> IO ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
  , loggerShutdown :: IO ()
loggerShutdown     = () -> IO ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
  }

-- | Create a logger that prints messages to standard output for the duration of
-- the given action.
withStdOutLogger :: (Logger -> IO r) -> IO r
withStdOutLogger :: (Logger -> IO r) -> IO r
withStdOutLogger act :: Logger -> IO r
act = do
  Logger
logger <- Text -> (LogMessage -> IO ()) -> IO Logger
mkLogger "stdout" ((LogMessage -> IO ()) -> IO Logger)
-> (LogMessage -> IO ()) -> IO Logger
forall a b. (a -> b) -> a -> b
$ \msg :: LogMessage
msg -> do
    Text -> IO ()
T.putStrLn (Text -> IO ()) -> Text -> IO ()
forall a b. (a -> b) -> a -> b
$ Maybe UTCTime -> LogMessage -> Text
showLogMessage Maybe UTCTime
forall a. Maybe a
Nothing LogMessage
msg
    Handle -> IO ()
hFlush Handle
stdout
  Logger -> (Logger -> IO r) -> IO r
forall r. Logger -> (Logger -> IO r) -> IO r
withLogger Logger
logger Logger -> IO r
act

-- | Create a logger that prints messages in the JSON format to standard output
-- for the duration of the given action.
withJsonStdOutLogger :: (Logger -> IO r) -> IO r
withJsonStdOutLogger :: (Logger -> IO r) -> IO r
withJsonStdOutLogger act :: Logger -> IO r
act = do
  Logger
logger <- Text -> (LogMessage -> IO ()) -> IO Logger
mkLogger "stdout-json" ((LogMessage -> IO ()) -> IO Logger)
-> (LogMessage -> IO ()) -> IO Logger
forall a b. (a -> b) -> a -> b
$ \msg :: LogMessage
msg -> do
    ByteString -> IO ()
BSL.putStrLn (ByteString -> IO ()) -> ByteString -> IO ()
forall a b. (a -> b) -> a -> b
$ LogMessage -> ByteString
forall a. ToJSON a => a -> ByteString
encode LogMessage
msg
    Handle -> IO ()
hFlush Handle
stdout
  Logger -> (Logger -> IO r) -> IO r
forall r. Logger -> (Logger -> IO r) -> IO r
withLogger Logger
logger Logger -> IO r
act