little-logger-0.1.0: src/LittleLogger.hs
{-# LANGUAGE ConstraintKinds #-}
{-| Basic logging based on co-log. The difference is that our log action runs in IO, and
we expect to use it in any IO-lifting monad. -}
module LittleLogger
( LogApp (..)
, SimpleLogAction
, HasSimpleLog (..)
, WithSimpleLog
, logAppLogAction
, defaultSimpleLogAction
, logMsg
, logDebug
, logError
, logException
, logInfo
, logWarning
, logWithSeverity
, newLogApp
) where
import Colog.Actions (richMessageAction)
import Colog.Core.Action (LogAction (..))
import Colog.Core.Severity (Severity (..))
import Colog.Message (Message, Msg (..))
import Control.Exception (Exception, displayException)
import Control.Monad.IO.Class (MonadIO (..))
import Control.Monad.Reader (MonadReader (..))
import Data.Text (Text)
import qualified Data.Text as Text
import GHC.Stack (HasCallStack, callStack, withFrozenCallStack)
import Lens.Micro (Lens', lens)
import Lens.Micro.Extras (view)
import Prelude
type SimpleLogAction = LogAction IO Message
class HasSimpleLog env where
simpleLogL :: Lens' env SimpleLogAction
type WithSimpleLog env m = (MonadIO m, MonadReader env m, HasSimpleLog env, HasCallStack)
defaultSimpleLogAction :: SimpleLogAction
defaultSimpleLogAction = richMessageAction
logMsg :: WithSimpleLog env m => Message -> m ()
logMsg msg = do
env <- ask
let LogAction act = view simpleLogL env
liftIO (act msg)
logWithSeverity :: WithSimpleLog env m => Severity -> Text -> m ()
logWithSeverity sev txt = withFrozenCallStack (logMsg Msg { msgStack = callStack, msgSeverity = sev, msgText = txt })
logDebug :: WithSimpleLog env m => Text -> m ()
logDebug = withFrozenCallStack (logWithSeverity Debug)
logInfo :: WithSimpleLog env m => Text -> m ()
logInfo = withFrozenCallStack (logWithSeverity Info)
logWarning :: WithSimpleLog env m => Text -> m ()
logWarning = withFrozenCallStack (logWithSeverity Warning)
logError :: WithSimpleLog env m => Text -> m ()
logError = withFrozenCallStack (logWithSeverity Error)
logException :: (WithSimpleLog env m, Exception e) => e -> m ()
logException = withFrozenCallStack (logError . Text.pack . displayException)
newtype LogApp = LogApp { _logAppLogAction :: SimpleLogAction }
logAppLogAction :: Lens' LogApp SimpleLogAction
logAppLogAction = lens _logAppLogAction (const LogApp)
instance HasSimpleLog LogApp where
simpleLogL = logAppLogAction
newLogApp :: LogApp
newLogApp = LogApp defaultSimpleLogAction