module Main (main) where import Relude import Blammo.Logging.Simple qualified as Blammo (runSimpleLoggingT) import Control.Monad.Logger (LoggingT, MonadLogger) import Control.Monad.Logger.Aeson (Message ((:#)), (.=)) import Control.Monad.Logger.Aeson qualified as LoggerJson ( logInfo, logWarn, runStdoutLoggingT, ) import Control.Monad.Logger.CallStack qualified as Logger ( logInfo, logWarn, runStdoutLoggingT, ) data Item = Item { itemId :: Text , itemContents :: Text } getItem :: IO Item getItem = pure $ Item { itemId = "652412308" , itemContents = "
Hello world!
" } data AppEnv = AppEnv { appName :: Text , appVersion :: Text } newtype App a = App {unApp :: ReaderT AppEnv (LoggingT IO) a} deriving newtype ( Functor , Applicative , Monad , MonadIO , MonadReader AppEnv , MonadLogger ) runApp :: AppEnv -> (LoggingT IO a -> IO a) -> App a -> IO a runApp env runLogging action = runLogging $ runReaderT (unApp action) env appPlain :: (MonadReader AppEnv m, MonadLogger m, MonadIO m) => m () appPlain = do appName <- asks appName Logger.logInfo $ "App started: " <> "appName=" <> appName item <- liftIO getItem Logger.logWarn $ "Skipping invalid item: " <> "appName=" <> appName <> " itemId=" <> itemId item appJson :: (MonadReader AppEnv m, MonadLogger m, MonadIO m) => m () appJson = do appName <- asks appName LoggerJson.logInfo $ "App started" :# ["appName" .= appName] item <- liftIO getItem LoggerJson.logWarn $ "Skipping invalid item" :# [ "appName" .= appName , "itemId" .= itemId item ] mainPlain :: IO () mainPlain = do let appEnv = AppEnv { appName = "example-1a" , appVersion = "1.0.0" } runApp appEnv Logger.runStdoutLoggingT appPlain mainJson :: IO () mainJson = do let appEnv = AppEnv { appName = "example-1b" , appVersion = "1.0.0" } runApp appEnv LoggerJson.runStdoutLoggingT appJson mainBlammo :: IO () mainBlammo = do let appEnv = AppEnv { appName = "example-1c" , appVersion = "1.0.0" } runApp appEnv Blammo.runSimpleLoggingT appJson main :: IO () main = do mainPlain putStrLn "" mainJson putStrLn "" mainBlammo