    {-# LANGUAGE FlexibleContexts #-}
    {-# LANGUAGE ConstraintKinds #-}
    -- |
    -- This module is intended to be imported qualified:
    --
    -- > import qualified System.Logging.Facade as Log
    module System.Logging.Facade (
    -- * Producing log messages
      log
    , trace
    , debug
    , info
    , warn
    , error

    -- * Types
    , Logging
    , LogLevel(..)
    ) where

    import           Prelude hiding (log, error)
    import           Data.CallStack

    import           System.Logging.Facade.Types
    import           System.Logging.Facade.Class

    -- | Produce a log message with specified log level.
    log :: (HasCallStack, Logging m) => LogLevel -> String -> m ()
    log :: forall (m :: * -> *).
    (HasCallStack, Logging m) =>
    LogLevel -> String -> m ()
    log LogLevel
    level String
    message = LogRecord -> m ()
    forall (m :: * -> *). Logging m => LogRecord -> m ()
    consumeLogRecord (LogLevel -> Maybe Location -> String -> LogRecord
    LogRecord LogLevel
    level Maybe Location
    HasCallStack => Maybe Location
    location String
    message)

    location :: HasCallStack => Maybe Location
    location :: HasCallStack => Maybe Location
    location = case [(String, SrcLoc)] -> [(String, SrcLoc)]
    forall a. [a] -> [a]
    reverse [(String, SrcLoc)]
    HasCallStack => [(String, SrcLoc)]
    callStack of
      (String
    _, SrcLoc
    loc) : [(String, SrcLoc)]
    _ -> Location -> Maybe Location
    forall a. a -> Maybe a
    Just (Location -> Maybe Location) -> Location -> Maybe Location
    forall a b. (a -> b) -> a -> b
    $ String -> String -> String -> Int -> Int -> Location
    Location (SrcLoc -> String
    srcLocPackage SrcLoc
    loc) (SrcLoc -> String
    srcLocModule SrcLoc
    loc) (SrcLoc -> String
    srcLocFile SrcLoc
    loc) (SrcLoc -> Int
    srcLocStartLine SrcLoc
    loc) (SrcLoc -> Int
    srcLocStartCol SrcLoc
    loc)
      [(String, SrcLoc)]
    _ -> Maybe Location
    forall a. Maybe a
    Nothing

    -- | Produce a log message with log level `TRACE`.
    trace :: (HasCallStack, Logging m) => String -> m ()
    trace :: forall (m :: * -> *). (HasCallStack, Logging m) => String -> m ()
    trace = LogLevel -> String -> m ()
    forall (m :: * -> *).
    (HasCallStack, Logging m) =>
    LogLevel -> String -> m ()
    log LogLevel
    TRACE

    -- | Produce a log message with log level `DEBUG`.
    debug :: (HasCallStack, Logging m) => String -> m ()
    debug :: forall (m :: * -> *). (HasCallStack, Logging m) => String -> m ()
    debug = LogLevel -> String -> m ()
    forall (m :: * -> *).
    (HasCallStack, Logging m) =>
    LogLevel -> String -> m ()
    log LogLevel
    DEBUG

    -- | Produce a log message with log level `INFO`.
    info :: (HasCallStack, Logging m) => String -> m ()
    info :: forall (m :: * -> *). (HasCallStack, Logging m) => String -> m ()
    info = LogLevel -> String -> m ()
    forall (m :: * -> *).
    (HasCallStack, Logging m) =>
    LogLevel -> String -> m ()
    log LogLevel
    INFO

    -- | Produce a log message with log level `WARN`.
    warn :: (HasCallStack, Logging m) => String -> m ()
    warn :: forall (m :: * -> *). (HasCallStack, Logging m) => String -> m ()
    warn = LogLevel -> String -> m ()
    forall (m :: * -> *).
    (HasCallStack, Logging m) =>
    LogLevel -> String -> m ()
    log LogLevel
    WARN

    -- | Produce a log message with log level `ERROR`.
    error :: (HasCallStack, Logging m) => String -> m ()
    error :: forall (m :: * -> *). (HasCallStack, Logging m) => String -> m ()
    error = LogLevel -> String -> m ()
    forall (m :: * -> *).
    (HasCallStack, Logging m) =>
    LogLevel -> String -> m ()
    log LogLevel
    ERROR