packages feed

co-log-polysemy-formatting-0.1.0.0: example/Main.hs

-- Required for formatting
{-# LANGUAGE OverloadedStrings #-}

-- Required for Polysemy
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE GADTs #-}

-- Required for co-log-polysemy-formatting.
-- This should re-export everything you need for logging.
import Colog.Polysemy.Formatting

-- Other imports for this example
import Data.Function ((&))
import Formatting
import Polysemy
import Polysemy.Async
import System.IO (stderr)

-- main needs the 'HasCallStack' constraint for log functions to know where they were called from
main :: HasCallStack => IO ()
main = do
  -- Set up a logging environment, logging to stderr and using the local timezone
  logEnvStderr <- newLogEnv stderr

  (do
    -- This debug message will show up only if 'debugMode' is True
    logDebug "MyApp version 0.1.0.0"

    -- Run our Polysemy program
    program
    )
      -- Set the level of logging we want (for more control see 'filterLogs')
      & setLogLevel Debug

      -- This lets us log the thread id and message timestamp with each log message
      & addThreadAndTimeToLog

      -- If you are using the 'Async' effect then interpret it here, after adding the thread and time,
      -- but before running the log action.
      & asyncToIO

      -- Log to stderr, using our logging environment
      & runLogAction (logTextStderr & cmap (renderThreadTimeMessage logEnvStderr))

      & runM

program :: (WithLog r, Members '[Async, Embed IO] r) => Sem r ()
program = do
  -- This concurrency is just here to demonstrate that it is possible.
  -- It isn't required.
  _ <- sequenceConcurrently $
    replicate 10 asyncProg
    <> [logError ("Error message: '" % accessed fst text <> "', number: " % accessed snd int) ("It's all broken!", 17 :: Int)]
    <> replicate 10 asyncProg
  pure ()
  where
    asyncProg = do
      logInfo "Hello, logging!"
      embed $ fprintLn "Hello, logging!"