monad-logger 0.3.7.1 → 0.3.42
raw patch · 5 files changed
Files
- ChangeLog.md +189/−0
- Control/Monad/Logger.hs +581/−146
- Control/Monad/Logger/CallStack.hs +86/−0
- README.md +9/−0
- monad-logger.cabal +59/−38
+ ChangeLog.md view
@@ -0,0 +1,189 @@+# ChangeLog for monad-logger++## 0.3.42++* Forward compatibility with `-Wnoncanonical-monad-instances` becoming an error++## 0.3.41++* Add `MonadAccum` instances for `LoggingT` and `NoLoggingT`++## 0.3.40++* Relax `fast-logger` upper bound from 3.2 to 3.3+* Add `Alternative` instances for `LoggingT` and `NoLoggingT`++## 0.3.39++* Make the previous change backwards compatible with CPP++## 0.3.38++* Drop old deprecated instances to support transformers 0.6 [#39](https://github.com/snoyberg/monad-logger/pull/39)++## 0.3.37++* Add `Semigroup`/`Monoid` instances to `LoggingT`, `NoLoggingT`, and `WriterLoggingT`++## 0.3.36++* Export the `defaultOutput` function, useful for defining custom instances of `MonadLogger`. [#29](https://github.com/snoyberg/monad-logger/pull/29)++## 0.3.35++* Add Hackage status badge+* Document `Loc` [#26](https://github.com/snoyberg/monad-logger/pull/26)++## 0.3.34++* Fix build for lts-9 resolver++## 0.3.33++* Export `LogLine` type synonym.++## 0.3.32++* Compat with `unliftio-core` 0.2++## 0.3.31++* Re-export `fromLogStr` to make implementing custom instances more convenient.+ [#14](https://github.com/snoyberg/monad-logger/pull/14)++## 0.3.30++* Added `MonadFail` instances for `LoggingT` and `NoLoggingT`.++## 0.3.29++* Export mapLoggingT and mapNoLoggingT++## 0.3.28.5++* Fix missing module [#1](https://github.com/snoyberg/monad-logger/issues/1)++## 0.3.28.4++* Move to a new repo++## 0.3.28.3++* Compat for older GHCs [#161](https://github.com/kazu-yamamoto/logger/pull/161)++## 0.3.28.2++* Support for exceptions 0.9 and 0.10 [#158](https://github.com/kazu-yamamoto/logger/issues/158)+* Drop blaze-builder dependency++## 0.3.28.1++* Fix support for GHC 7.8 [#154](https://github.com/kazu-yamamoto/logger/pull/154)++## 0.3.28++* Added `WriterLoggingT` for collecting log lines and help with testing++## 0.3.27++* Drop backwards compat with older library versions++## 0.3.26++* Add `MonadUnliftIO` instances++## 0.3.25.1++* Fix some incorrect `@since` comments++## 0.3.25++* Export all CallStack log functions [#143](https://github.com/kazu-yamamoto/logger/pull/143)++## 0.3.24+* Added `MonadReader` instance for `NoLoggingT`.++## 0.3.23+* Changed `runFileLoggingT` buffering to line buffering.+* Added `defaultLog` and `logWithoutLoc` to list of exported functions.++## 0.3.22+* Added `runFileLoggingT`.++## 0.3.21++* Reimplemented Functor & Applicative for LoggingT & NoLoggingT [#125](https://github.com/kazu-yamamoto/logger/issues/125) [#126](https://github.com/kazu-yamamoto/logger/pull/126)++## 0.3.20.2++* Support for GHC 8.2++## 0.3.20.1++* Fix #106 by correcting the default signature for MonadLoggerIO [#108](https://github.com/kazu-yamamoto/logger/pull/108)++## 0.3.20++* Generalize the type of `unChanLoggingT`+ [#104](https://github.com/kazu-yamamoto/logger/pull/104)++## 0.3.19++* Add CallStack-based functions and `Control.Monad.Logger.CallStack` module++## 0.3.18++* Added logTHShow and logDebugSH, logInfoSH, etc. Accepts an argument of `Show a => a` instead of just `Text`.++## 0.3.17++* log to a chan [#74](https://github.com/kazu-yamamoto/logger/pull/74)++## 0.3.16++* Provide default monadLoggerLog implementation [#72](https://github.com/kazu-yamamoto/logger/pull/72)++## 0.3.15++* Expose Loc constructor [#70](https://github.com/kazu-yamamoto/logger/pull/70)++## 0.3.14++* Don't include source location for defaultLoc [#69](https://github.com/kazu-yamamoto/logger/issues/69)++## 0.3.13.1++* Allow fast-logger 2.3++## 0.3.13++* Re-export LogStr from fast-logger [#56](https://github.com/kazu-yamamoto/logger/pull/56)+* Added `filterLogger`++## 0.3.12++* Use transformers-compat to provide universal ExceptT support [#53](https://github.com/kazu-yamamoto/logger/pull/53)++## 0.3.11.1++Add support for monad-control 1.0 [#52](https://github.com/kazu-yamamoto/logger/pull/52)++## 0.3.11++Add missing `MonadState` and `MonadWriter` instances for `NoLoggingT` [#51](https://github.com/kazu-yamamoto/logger/pull/51)++## 0.3.10.1++Remove unnecessary extra newline in log messages.++## 0.3.10++Introduce the `MonadLoggerIO` typeclass.++## 0.3.9++Add missing `MonadError NoLoggingT` instance #49++## 0.3.8++Simplify constraint on `MonadLogger (NoLoggingT m)` from `MonadIO m` to `Monad m` [Github issue #48](https://github.com/kazu-yamamoto/logger/issues/48).
Control/Monad/Logger.hs view
@@ -1,4 +1,10 @@ {-# LANGUAGE CPP #-}+{-# LANGUAGE GeneralizedNewtypeDeriving #-}+{-# LANGUAGE DefaultSignatures #-}+{-# LANGUAGE StandaloneDeriving #-}+#if WITH_CALLSTACK+{-# LANGUAGE ImplicitParams #-}+#endif #if WITH_TEMPLATE_HASKELL {-# LANGUAGE TemplateHaskell #-} #endif@@ -8,12 +14,14 @@ {-# LANGUAGE MultiParamTypeClasses #-} {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE UndecidableInstances #-}+{-# LANGUAGE Trustworthy #-}+{-# LANGUAGE TupleSections #-} -- | This module provides the facilities needed for a decoupled logging system. -- -- The 'MonadLogger' class is implemented by monads that give access to a -- logging facility. If you're defining a custom monad, then you may define an -- instance of 'MonadLogger' that routes the log messages to the appropriate--- place (e.g., that's what @yesod-core@'s @GHandler@ does). Otherwise, you+-- place (e.g., that's what @yesod-core@'s @HandlerT@ does). Otherwise, you -- may use the 'LoggingT' monad included in this module (see -- 'runStderrLoggingT'). To simply discard log message, use 'NoLoggingT'. --@@ -24,14 +32,29 @@ module Control.Monad.Logger ( -- * MonadLogger MonadLogger(..)+ , MonadLoggerIO (..) , LogLevel(..)+ , LogLine , LogSource- -- * Helper transformer+ -- * Re-export from fast-logger+ , LogStr+ , ToLogStr(..)+ , fromLogStr+ -- * Helper transformers , LoggingT (..) , runStderrLoggingT , runStdoutLoggingT+ , runChanLoggingT+ , runFileLoggingT+ , unChanLoggingT , withChannelLogger+ , filterLogger , NoLoggingT (..)+ , mapNoLoggingT+ , WriterLoggingT (..)+ , execWriterLoggingT+ , runWriterLoggingT+ , mapLoggingT #if WITH_TEMPLATE_HASKELL -- * TH logging , logDebug@@ -39,6 +62,12 @@ , logWarn , logError , logOther+ -- * TH logging of showable values+ , logDebugSH+ , logInfoSH+ , logWarnSH+ , logErrorSH+ , logOtherSH -- * TH logging with source , logDebugS , logInfoS@@ -55,52 +84,65 @@ , logErrorN , logOtherN -- * Non-TH logging with source+ , logWithoutLoc , logDebugNS , logInfoNS , logWarnNS , logErrorNS , logOtherNS-+#if WITH_CALLSTACK+ -- * Callstack logging+ , logDebugCS+ , logInfoCS+ , logWarnCS+ , logErrorCS+ , logOtherCS+#endif -- * utilities for defining your own loggers , defaultLogStr- , Loc+ -- $locDocs+ , Loc (..)+ , defaultLoc+ , defaultOutput ) where #if WITH_TEMPLATE_HASKELL import Language.Haskell.TH.Syntax (Lift (lift), Q, Exp, Loc (..), qLocation) #endif +import Data.Functor ((<$>)) import Data.Monoid (Monoid) -import Control.Applicative (Applicative (..))+import Control.Applicative (Alternative (..), Applicative (..))+import Control.Concurrent.Chan (Chan(),writeChan,readChan) import Control.Concurrent.STM import Control.Concurrent.STM.TBChan-import Control.Exception.Lifted (onException)-import Control.Monad (liftM, ap, when, void)-import Control.Monad.Base (MonadBase (liftBase))+import Control.Exception.Lifted (onException, bracket)+import Control.Monad (liftM, when, void, forever)+import Control.Monad.Base (MonadBase (liftBase), liftBaseDefault)+#if MIN_VERSION_base(4, 9, 0)+import qualified Control.Monad.Fail as Fail+#endif+import Control.Monad.IO.Unlift import Control.Monad.Loops (untilM)-import Control.Monad.Trans.Control (MonadBaseControl (..), MonadTransControl (..))+import Control.Monad.Trans.Control (MonadBaseControl (..), MonadTransControl (..), ComposeSt, defaultLiftBaseWith, defaultRestoreM) import qualified Control.Monad.Trans.Class as Trans import Control.Monad.IO.Class (MonadIO (liftIO))-import Control.Monad.Trans.Resource (MonadResource (liftResourceT), MonadThrow, monadThrow)-#if MIN_VERSION_resourcet(1,1,0)-import Control.Monad.Trans.Resource (throwM)-import Control.Monad.Catch (MonadCatch (..)-#if MIN_VERSION_exceptions(0,6,0)- , MonadMask (..)-#endif- )+import Control.Monad.Trans.Resource (MonadResource (liftResourceT))+import Control.Monad.Catch (MonadThrow (..), MonadCatch (..), MonadMask (..)+#if MIN_VERSION_exceptions(0, 10, 0)+ , ExitCase (..) #endif+ ) import Control.Monad.Trans.Identity ( IdentityT)-import Control.Monad.Trans.List ( ListT ) import Control.Monad.Trans.Maybe ( MaybeT )+#if !MIN_VERSION_transformers(0, 6, 0)+import Control.Monad.Trans.List ( ListT ) import Control.Monad.Trans.Error ( ErrorT, Error)--#if MIN_VERSION_transformers(0,4,0)-import Control.Monad.Trans.Except ( ExceptT ) #endif+import Control.Monad.Trans.Except ( ExceptT ) import Control.Monad.Trans.Reader ( ReaderT ) import Control.Monad.Trans.Cont ( ContT )@@ -120,7 +162,7 @@ import Data.Monoid (mappend, mempty) import System.Log.FastLogger-import System.IO (Handle, stdout, stderr)+import System.IO (Handle, IOMode(AppendMode), BufferMode(LineBuffering), openFile, hClose, hSetBuffering, stdout, stderr) import Control.Monad.Cont.Class ( MonadCont (..) ) import Control.Monad.Error.Class ( MonadError (..) )@@ -128,25 +170,37 @@ import Control.Monad.Reader.Class ( MonadReader (..) ) import Control.Monad.State.Class ( MonadState (..) ) import Control.Monad.Writer.Class ( MonadWriter (..) )--import Blaze.ByteString.Builder (toByteString)--import Prelude hiding (catch)+#if MIN_VERSION_mtl(2, 3, 1)+import Control.Monad.Accum ( MonadAccum (..) )+#endif -#if !MIN_VERSION_fast_logger(2, 1, 0) && MIN_VERSION_bytestring(0, 10, 2)-import qualified Data.ByteString.Lazy as L-import Data.ByteString.Builder (toLazyByteString)+#if WITH_CALLSTACK+import GHC.Stack as GHC #endif -#if MIN_VERSION_conduit_extra(1,1,0) import Data.Conduit.Lazy (MonadActive, monadActive)-#endif data LogLevel = LevelDebug | LevelInfo | LevelWarn | LevelError | LevelOther Text deriving (Eq, Prelude.Show, Prelude.Read, Ord) type LogSource = Text +-- $locDocs+--+-- === Loc+--+-- When @monad-logger@ is compiled with the @template_haskell@ flag set to true (the default), the 'Loc' below is a re-export from the @template-haskell@ package.+-- When the flag is false, the 'Loc' below is a copy of that data structure defined in @monad-logger@ itself.+--+-- If you are making a library that:+--+-- * Uses @monad-logger@+-- * Uses 'Loc' in a type signature+-- * But doesn't need to depend on @template-haskell@ for other reasons+--+-- You can import 'Loc' directly from this package, instead of adding an dependency on @template-haskell@ and importing from there.+-- This allows users to compile your package in environments that don't support @template-haskell@.+ #if WITH_TEMPLATE_HASKELL instance Lift LogLevel where@@ -168,10 +222,29 @@ #endif +-- | A @Monad@ which has the ability to log messages in some manner. class Monad m => MonadLogger m where monadLoggerLog :: ToLogStr msg => Loc -> LogSource -> LogLevel -> msg -> m ()+ default monadLoggerLog :: (MonadLogger m', Trans.MonadTrans t, MonadLogger (t m'), ToLogStr msg, m ~ t m')+ => Loc -> LogSource -> LogLevel -> msg -> m ()+ monadLoggerLog loc src lvl msg = Trans.lift $ monadLoggerLog loc src lvl msg +-- | An extension of @MonadLogger@ for the common case where the logging action+-- is a simple @IO@ action. The advantage of using this typeclass is that the+-- logging function itself can be extracted as a first-class value, which can+-- make it easier to manipulate monad transformer stacks, as an example.+--+-- @since 0.3.10+class (MonadLogger m, MonadIO m) => MonadLoggerIO m where+ -- | Request the logging function itself.+ --+ -- @since 0.3.10+ askLoggerIO :: m (Loc -> LogSource -> LogLevel -> LogStr -> IO ())+ default askLoggerIO :: (Trans.MonadTrans t, MonadLoggerIO n, m ~ t n)+ => m (Loc -> LogSource -> LogLevel -> LogStr -> IO ())+ askLoggerIO = Trans.lift askLoggerIO + {- instance MonadLogger IO where monadLoggerLog _ _ _ = return () instance MonadLogger Identity where monadLoggerLog _ _ _ = return ()@@ -181,14 +254,12 @@ #define DEF monadLoggerLog a b c d = Trans.lift $ monadLoggerLog a b c d instance MonadLogger m => MonadLogger (IdentityT m) where DEF+#if !MIN_VERSION_transformers(0, 6, 0) instance MonadLogger m => MonadLogger (ListT m) where DEF-instance MonadLogger m => MonadLogger (MaybeT m) where DEF instance (MonadLogger m, Error e) => MonadLogger (ErrorT e m) where DEF--#if MIN_VERSION_transformers(0,4,0)-instance MonadLogger m => MonadLogger (ExceptT e m) where DEF #endif-+instance MonadLogger m => MonadLogger (MaybeT m) where DEF+instance MonadLogger m => MonadLogger (ExceptT e m) where DEF instance MonadLogger m => MonadLogger (ReaderT r m) where DEF instance MonadLogger m => MonadLogger (ContT r m) where DEF instance MonadLogger m => MonadLogger (StateT s m) where DEF@@ -202,11 +273,39 @@ instance (MonadLogger m, Monoid w) => MonadLogger (Strict.RWST r w s m) where DEF #undef DEF +instance MonadLoggerIO m => MonadLoggerIO (IdentityT m)+#if !MIN_VERSION_transformers(0, 6, 0)+instance MonadLoggerIO m => MonadLoggerIO (ListT m)+instance (MonadLoggerIO m, Error e) => MonadLoggerIO (ErrorT e m)+#endif+instance MonadLoggerIO m => MonadLoggerIO (MaybeT m)+instance MonadLoggerIO m => MonadLoggerIO (ExceptT e m)+instance MonadLoggerIO m => MonadLoggerIO (ReaderT r m)+instance MonadLoggerIO m => MonadLoggerIO (ContT r m)+instance MonadLoggerIO m => MonadLoggerIO (StateT s m)+instance (MonadLoggerIO m, Monoid w) => MonadLoggerIO (WriterT w m)+instance (MonadLoggerIO m, Monoid w) => MonadLoggerIO (RWST r w s m)+instance MonadLoggerIO m => MonadLoggerIO (ResourceT m)+instance MonadLoggerIO m => MonadLoggerIO (Pipe l i o u m)+instance MonadLoggerIO m => MonadLoggerIO (ConduitM i o m)+instance MonadLoggerIO m => MonadLoggerIO (Strict.StateT s m)+instance (MonadLoggerIO m, Monoid w) => MonadLoggerIO (Strict.WriterT w m)+instance (MonadLoggerIO m, Monoid w) => MonadLoggerIO (Strict.RWST r w s m)+ #if WITH_TEMPLATE_HASKELL logTH :: LogLevel -> Q Exp logTH level =- [|monadLoggerLog $(qLocation >>= liftLoc) (pack "") $(lift level) . (id :: Text -> Text)|]+ [|monadLoggerLog $(qLocation >>= liftLoc) (pack "") $(lift level)+ . (id :: Text -> Text)|] +-- | Generates a function that takes a 'LogLevel' and a 'Show a => a'.+--+-- @since 0.3.18+logTHShow :: LogLevel -> Q Exp+logTHShow level =+ [|monadLoggerLog $(qLocation >>= liftLoc) (pack "") $(lift level)+ . ((pack . show) :: Show a => a -> Text)|]+ -- | Generates a function that takes a 'Text' and logs a 'LevelDebug' message. Usage: -- -- > $(logDebug) "This is a debug log message"@@ -229,9 +328,34 @@ logOther :: Text -> Q Exp logOther = logTH . LevelOther ++-- | Generates a function that takes a 'Show a => a' and logs a 'LevelDebug' message. Usage:+--+-- > $(logDebugSH) (Just "This is a debug log message")+--+-- @since 0.3.18+logDebugSH :: Q Exp+logDebugSH = logTHShow LevelDebug++-- | See 'logDebugSH'+logInfoSH :: Q Exp+logInfoSH = logTHShow LevelInfo+-- | See 'logDebugSH'+logWarnSH :: Q Exp+logWarnSH = logTHShow LevelWarn+-- | See 'logDebugSH'+logErrorSH :: Q Exp+logErrorSH = logTHShow LevelError++-- | Generates a function that takes a 'Show a => a' and logs a 'LevelOther' message. Usage:+--+-- > $(logOtherSH "My new level") "This is a log message"+logOtherSH :: Text -> Q Exp+logOtherSH = logTHShow . LevelOther+ -- | Lift a location into an Exp. ----- Since 0.3.1+-- @since 0.3.1 liftLoc :: Loc -> Q Exp liftLoc (Loc a b c (d1, d2) (e1, e2)) = [|Loc $(lift a)@@ -266,90 +390,231 @@ -- | Monad transformer that disables logging. ----- Since 0.2.4+-- @since 0.2.4 newtype NoLoggingT m a = NoLoggingT { runNoLoggingT :: m a }--instance Monad m => Functor (NoLoggingT m) where- fmap = liftM--instance Monad m => Applicative (NoLoggingT m) where- pure = return- (<*>) = ap--instance Monad m => Monad (NoLoggingT m) where- return = NoLoggingT . return- NoLoggingT ma >>= f = NoLoggingT $ ma >>= runNoLoggingT . f--instance MonadIO m => MonadIO (NoLoggingT m) where- liftIO = Trans.lift . liftIO--#if MIN_VERSION_resourcet(1,1,0)-instance MonadThrow m => MonadThrow (NoLoggingT m) where- throwM = Trans.lift . throwM+ deriving (+ Functor, Applicative, Monad, MonadIO, MonadThrow, MonadCatch, MonadMask, MonadActive, MonadBase b+ , Alternative -- ^ @since 0.3.40+ ) -instance MonadCatch m => MonadCatch (NoLoggingT m) where- catch (NoLoggingT m) c =- NoLoggingT $ m `catch` \e -> runNoLoggingT (c e)-#if MIN_VERSION_exceptions(0,6,0)-instance MonadMask m => MonadMask (NoLoggingT m) where-#endif- mask a = NoLoggingT $ mask $ \u -> runNoLoggingT (a $ q u)- where q u (NoLoggingT b) = NoLoggingT $ u b- uninterruptibleMask a =- NoLoggingT $ uninterruptibleMask $ \u -> runNoLoggingT (a $ q u)- where q u (NoLoggingT b) = NoLoggingT $ u b-#else-instance MonadThrow m => MonadThrow (NoLoggingT m) where- monadThrow = Trans.lift . monadThrow-#endif+-- For some reason GND is a fool on GHC 7.10 and older, we have to help it by providing the context explicitly.+deriving instance MonadResource m => MonadResource (NoLoggingT m) -#if MIN_VERSION_conduit_extra(1,1,0)-instance MonadActive m => MonadActive (NoLoggingT m) where- monadActive = Trans.lift monadActive instance MonadActive m => MonadActive (LoggingT m) where monadActive = Trans.lift monadActive-#endif -instance MonadResource m => MonadResource (NoLoggingT m) where- liftResourceT = Trans.lift . liftResourceT--instance MonadBase b m => MonadBase b (NoLoggingT m) where- liftBase = Trans.lift . liftBase- instance Trans.MonadTrans NoLoggingT where lift = NoLoggingT instance MonadTransControl NoLoggingT where- newtype StT NoLoggingT a = StIdent {unStIdent :: a}- liftWith f = NoLoggingT $ f $ \(NoLoggingT t) -> liftM StIdent t- restoreT = NoLoggingT . liftM unStIdent+ type StT NoLoggingT a = a+ liftWith f = NoLoggingT $ f runNoLoggingT+ restoreT = NoLoggingT {-# INLINE liftWith #-} {-# INLINE restoreT #-} +#if MIN_VERSION_base(4, 9, 0)+-- | @since 0.3.30+instance (Fail.MonadFail m) => Fail.MonadFail (NoLoggingT m) where+ fail = Trans.lift . Fail.fail+#endif+ instance MonadBaseControl b m => MonadBaseControl b (NoLoggingT m) where- newtype StM (NoLoggingT m) a = StMT' (StM m a)+ type StM (NoLoggingT m) a = StM m a liftBaseWith f = NoLoggingT $ liftBaseWith $ \runInBase ->- f $ liftM StMT' . runInBase . (\(NoLoggingT r) -> r)- restoreM (StMT' base) = NoLoggingT $ restoreM base+ f $ runInBase . runNoLoggingT+ restoreM = NoLoggingT . restoreM -instance MonadIO m => MonadLogger (NoLoggingT m) where+instance Monad m => MonadLogger (NoLoggingT m) where monadLoggerLog _ _ _ _ = return ()+instance MonadIO m => MonadLoggerIO (NoLoggingT m) where+ askLoggerIO = return $ \_ _ _ _ -> return () +-- | @since 0.3.26+instance MonadUnliftIO m => MonadUnliftIO (NoLoggingT m) where+#if MIN_VERSION_unliftio_core(0, 1, 1)+ {-# INLINE withRunInIO #-}+ withRunInIO inner =+ NoLoggingT $+ withRunInIO $ \run ->+ inner (run . runNoLoggingT)+#else+ askUnliftIO =+ NoLoggingT $+ withUnliftIO $ \u ->+ return (UnliftIO (unliftIO u . runNoLoggingT))+#endif++instance (Applicative m, Semigroup a) => Semigroup (NoLoggingT m a) where+ (<>) = liftA2 (<>)++instance (Applicative m, Monoid a) => Monoid (NoLoggingT m a) where+ mempty = pure mempty++-- | @since 0.3.32+type LogLine = (Loc, LogSource, LogLevel, LogStr)++-- | @since 0.3.28+newtype WriterLoggingT m a = WriterLoggingT { unWriterLoggingT :: m (a, DList LogLine) }++-- | Simple implementation of a difference list to support WriterLoggingT+newtype DList a = DList { unDList :: [a] -> [a] }++emptyDList :: DList a+emptyDList = DList id++singleton :: a -> DList a+singleton = DList . (:)++dListToList :: DList a -> [a]+dListToList (DList dl) = dl []++appendDList :: DList a -> DList a -> DList a+appendDList dl1 dl2 = DList (unDList dl1 . unDList dl2)++-- | Run a block using a @MonadLogger@ instance. Return a value and logs in a list+-- | @since 0.3.28+runWriterLoggingT :: Functor m => WriterLoggingT m a -> m (a, [LogLine])+runWriterLoggingT (WriterLoggingT ma) = fmap dListToList <$> ma++-- | Run a block using a @MonadLogger@ instance. Return logs in a list+-- | @since 0.3.28+execWriterLoggingT :: Functor m => WriterLoggingT m a -> m [LogLine]+execWriterLoggingT ma = snd <$> runWriterLoggingT ma++instance Monad m => Monad (WriterLoggingT m) where+ (WriterLoggingT ma) >>= f = WriterLoggingT $ do+ (a, msgs) <- ma+ (a', msgs') <- unWriterLoggingT $ f a+ return (a', appendDList msgs msgs')++instance Applicative m => Applicative (WriterLoggingT m) where+ pure a = WriterLoggingT . pure $ (a, emptyDList)+ WriterLoggingT mf <*> WriterLoggingT ma = WriterLoggingT $+ fmap (\((f, msgs), (a, msgs')) -> (f a, appendDList msgs msgs')) ((,) <$> mf <*> ma)++instance Functor m => Functor (WriterLoggingT m) where+ fmap f (WriterLoggingT ma) = WriterLoggingT $+ fmap (\(a, msgs) -> (f a, msgs)) ma++instance Monad m => MonadLogger (WriterLoggingT m) where+ monadLoggerLog loc source level msg = WriterLoggingT . return $ ((), singleton (loc, source, level, toLogStr msg))+++instance Trans.MonadTrans WriterLoggingT where+ lift ma = WriterLoggingT $ (, emptyDList) `liftM` ma++instance MonadIO m => MonadIO (WriterLoggingT m) where+ liftIO ioa = WriterLoggingT $ (, emptyDList) `liftM` liftIO ioa++instance MonadBase b m => MonadBase b (WriterLoggingT m) where+ liftBase = liftBaseDefault++instance MonadTransControl WriterLoggingT where+ type StT WriterLoggingT a = (a, DList LogLine)+ liftWith f = WriterLoggingT $ liftM (\x -> (x, emptyDList))+ (f $ unWriterLoggingT)+ restoreT = WriterLoggingT++instance MonadBaseControl b m => MonadBaseControl b (WriterLoggingT m) where+ type StM (WriterLoggingT m) a = ComposeSt WriterLoggingT m a+ liftBaseWith = defaultLiftBaseWith+ restoreM = defaultRestoreM++instance MonadThrow m => MonadThrow (WriterLoggingT m) where+ throwM = Trans.lift . throwM++instance MonadCatch m => MonadCatch (WriterLoggingT m) where+ catch (WriterLoggingT m) c =+ WriterLoggingT $ m `catch` \e -> unWriterLoggingT (c e)++instance MonadMask m => MonadMask (WriterLoggingT m) where+ mask a = WriterLoggingT $ (mask $ \ u -> unWriterLoggingT (a $ q u))+ where q u b = WriterLoggingT $ u (unWriterLoggingT b)++ uninterruptibleMask a = WriterLoggingT $ uninterruptibleMask $ \u -> unWriterLoggingT (a $ q u)+ where q u b = WriterLoggingT $ u (unWriterLoggingT b)++#if MIN_VERSION_exceptions(0, 10, 0)+ generalBracket acquire release use = WriterLoggingT $ do+ ((b, _w12), (c, w123)) <- generalBracket+ (unWriterLoggingT acquire)+ (\(resource, w1) exitCase -> case exitCase of+ ExitCaseSuccess (b, w12) -> do+ (c, w3) <- unWriterLoggingT (release resource (ExitCaseSuccess b))+ return (c, appendDList w12 w3)+ -- In the two other cases, the base monad overrides @use@'s state+ -- changes and the state reverts to @w1@.+ ExitCaseException e -> do+ (c, w3) <- unWriterLoggingT (release resource (ExitCaseException e))+ return (c, appendDList w1 w3)+ ExitCaseAbort -> do+ (c, w3) <- unWriterLoggingT (release resource ExitCaseAbort)+ return (c, appendDList w1 w3))+ (\(resource, w1) -> do+ (a, w2) <- unWriterLoggingT (use resource)+ return (a, appendDList w1 w2))+ return ((b, c), w123)+#elif MIN_VERSION_exceptions(0, 9, 0)+ generalBracket acquire release releaseEx use =+ WriterLoggingT $ generalBracket+ (unWriterLoggingT acquire)+ (\(x, w1) -> do+ (y, w2) <- unWriterLoggingT (release x)+ return (y, appendDList w1 w2))+ (\(x, w1) ex -> do+ (y, w2) <- unWriterLoggingT (releaseEx x ex)+ return (y, appendDList w1 w2))+ (\(x, w1) -> do+ (y, w2) <- unWriterLoggingT (use x)+ return (y, appendDList w1 w2))+#endif++instance (Applicative m, Semigroup a) => Semigroup (WriterLoggingT m a) where+ (<>) = liftA2 (<>)++instance (Applicative m, Monoid a) => Monoid (WriterLoggingT m a) where+ mempty = pure mempty+ -- | Monad transformer that adds a new logging function. ----- Since 0.2.2+-- @since 0.2.2 newtype LoggingT m a = LoggingT { runLoggingT :: (Loc -> LogSource -> LogLevel -> LogStr -> IO ()) -> m a } +#if __GLASGOW_HASKELL__ < 710 instance Monad m => Functor (LoggingT m) where fmap = liftM instance Monad m => Applicative (LoggingT m) where pure = return (<*>) = ap+#else+instance Functor m => Functor (LoggingT m) where+ fmap f logger = LoggingT $ \loggerFn -> fmap f $ (runLoggingT logger) loggerFn+ {-# INLINE fmap #-} +instance Applicative m => Applicative (LoggingT m) where+ pure = LoggingT . const . pure+ {-# INLINE pure #-}+ loggerF <*> loggerA = LoggingT $ \loggerFn ->+ (runLoggingT loggerF) loggerFn+ <*> (runLoggingT loggerA) loggerFn+ {-# INLINE (<*>) #-}+#endif++-- | @since 0.3.40+instance (Alternative m) => Alternative (LoggingT m) where+ empty = LoggingT (const empty)+ LoggingT x <|> LoggingT y = LoggingT (\f -> x f <|> y f)++#if MIN_VERSION_base(4, 9, 0)+-- | @since 0.3.30+instance (Fail.MonadFail m) => Fail.MonadFail (LoggingT m) where+ fail = Trans.lift . Fail.fail+#endif+ instance Monad m => Monad (LoggingT m) where- return = LoggingT . const . return LoggingT ma >>= f = LoggingT $ \r -> do a <- ma r let LoggingT f' = f a@@ -358,23 +623,30 @@ instance MonadIO m => MonadIO (LoggingT m) where liftIO = Trans.lift . liftIO -#if MIN_VERSION_resourcet(1,1,0) instance MonadThrow m => MonadThrow (LoggingT m) where throwM = Trans.lift . throwM instance MonadCatch m => MonadCatch (LoggingT m) where catch (LoggingT m) c = LoggingT $ \r -> m r `catch` \e -> runLoggingT (c e) r-#if MIN_VERSION_exceptions(0,6,0) instance MonadMask m => MonadMask (LoggingT m) where-#endif mask a = LoggingT $ \e -> mask $ \u -> runLoggingT (a $ q u) e where q u (LoggingT b) = LoggingT (u . b) uninterruptibleMask a = LoggingT $ \e -> uninterruptibleMask $ \u -> runLoggingT (a $ q u) e where q u (LoggingT b) = LoggingT (u . b)-#else-instance MonadThrow m => MonadThrow (LoggingT m) where- monadThrow = Trans.lift . monadThrow+#if MIN_VERSION_exceptions(0, 10, 0)+ generalBracket acquire release use =+ LoggingT $ \e -> generalBracket+ (runLoggingT acquire e)+ (\x ec -> runLoggingT (release x ec) e)+ (\x -> runLoggingT (use x) e)+#elif MIN_VERSION_exceptions(0, 9, 0)+ generalBracket acquire release releaseEx use =+ LoggingT $ \e -> generalBracket+ (runLoggingT acquire e)+ (\x -> runLoggingT (release x) e)+ (\x y -> runLoggingT (releaseEx x y) e)+ (\x -> runLoggingT (use x) e) #endif instance MonadResource m => MonadResource (LoggingT m) where@@ -387,22 +659,57 @@ lift = LoggingT . const instance MonadTransControl LoggingT where- newtype StT LoggingT a = StReader {unStReader :: a}- liftWith f = LoggingT $ \r -> f $ \(LoggingT t) -> liftM StReader $ t r- restoreT = LoggingT . const . liftM unStReader+ type StT LoggingT a = a+ liftWith f = LoggingT $ \r -> f $ \(LoggingT t) -> t r+ restoreT = LoggingT . const {-# INLINE liftWith #-} {-# INLINE restoreT #-} instance MonadBaseControl b m => MonadBaseControl b (LoggingT m) where- newtype StM (LoggingT m) a = StMT (StM m a)+ type StM (LoggingT m) a = StM m a liftBaseWith f = LoggingT $ \reader' -> liftBaseWith $ \runInBase ->- f $ liftM StMT . runInBase . (\(LoggingT r) -> r reader')- restoreM (StMT base) = LoggingT $ const $ restoreM base+ f $ runInBase . (\(LoggingT r) -> r reader')+ restoreM = LoggingT . const . restoreM instance MonadIO m => MonadLogger (LoggingT m) where monadLoggerLog a b c d = LoggingT $ \f -> liftIO $ f a b c (toLogStr d)+instance MonadIO m => MonadLoggerIO (LoggingT m) where+ askLoggerIO = LoggingT return +-- | @since 0.3.26+instance MonadUnliftIO m => MonadUnliftIO (LoggingT m) where+#if MIN_VERSION_unliftio_core(0, 1, 1)+ {-# INLINE withRunInIO #-}+ withRunInIO inner =+ LoggingT $ \r ->+ withRunInIO $ \run ->+ inner (run . flip runLoggingT r)+#else+ askUnliftIO =+ LoggingT $ \f ->+ withUnliftIO $ \u ->+ return (UnliftIO (unliftIO u . flip runLoggingT f))+#endif++instance (Applicative m, Semigroup a) => Semigroup (LoggingT m a) where+ (<>) = liftA2 (<>)++instance (Applicative m, Monoid a) => Monoid (LoggingT m a) where+ mempty = pure mempty++-- | A default implementation of 'monadLoggerLog' that accepts a file+-- handle as the first argument.+--+-- This is used in the definition of 'runStdoutLoggingT':+--+-- @+-- 'runStdoutLoggingT' :: 'MonadIO' m => 'LoggingT' m a -> m a+-- 'runStdoutLoggingT' action =+-- 'runLoggingT' action ('defaultOutput' 'stdout')+-- @+--+-- @since 0.3.36 defaultOutput :: Handle -> Loc -> LogSource@@ -410,24 +717,19 @@ -> LogStr -> IO () defaultOutput h loc src level msg =- S8.hPutStrLn h ls+ S8.hPutStr h ls where ls = defaultLogStrBS loc src level msg+ defaultLogStrBS :: Loc -> LogSource -> LogLevel -> LogStr -> S8.ByteString defaultLogStrBS a b c d =- toBS $ defaultLogStr a b c d+ fromLogStr $ defaultLogStr a b c d where-#if MIN_VERSION_fast_logger(2, 1, 0) toBS = fromLogStr-#elif MIN_VERSION_bytestring(0, 10, 2)- toBS = L.toStrict . toLazyByteString . logStrBuilder-#else- toBS = toByteString . logStrBuilder-#endif defaultLogLevelStr :: LogLevel -> LogStr defaultLogLevelStr level = case level of@@ -438,40 +740,20 @@ -> LogSource -> LogLevel -> LogStr-#if MIN_VERSION_fast_logger(0, 2, 0) -> LogStr-#else- -> S8.ByteString-#endif defaultLogStr loc src level msg =-#if MIN_VERSION_fast_logger(0, 2, 0) "[" `mappend` defaultLogLevelStr level `mappend` (if T.null src then mempty else "#" `mappend` toLogStr src) `mappend` "] " `mappend` msg `mappend`- " @(" `mappend`- toLogStr (S8.pack fileLocStr) `mappend`- ")\n"-#else- S8.concat- [ S8.pack "["- , case level of- LevelOther t -> encodeUtf8 t- _ -> encodeUtf8 $ pack $ drop 5 $ show level- , if T.null src- then S8.empty- else encodeUtf8 $ '#' `T.cons` src- , S8.pack "] "- , case msg of- LS s -> encodeUtf8 $ pack s- LB b -> b- , S8.pack " @("- , encodeUtf8 $ pack fileLocStr- , S8.pack ")\n"- ]-#endif+ (if isDefaultLoc loc+ then "\n"+ else+ " @(" `mappend`+ toLogStr (S8.pack fileLocStr) `mappend`+ ")\n") where -- taken from file-location package -- turn the TH Loc loaction information into a human readable string@@ -494,25 +776,57 @@ -} +-- | Run a block using a @MonadLogger@ instance which appends to the specified file.+--+-- @since 0.3.22+runFileLoggingT :: MonadBaseControl IO m => FilePath -> LoggingT m a -> m a+runFileLoggingT fp logt = bracket+ (liftBase $ openFile fp AppendMode)+ (liftBase . hClose)+ $ \h -> liftBase (hSetBuffering h LineBuffering) >> (runLoggingT logt) (defaultOutput h)+ -- | Run a block using a @MonadLogger@ instance which prints to stderr. ----- Since 0.2.2+-- @since 0.2.2 runStderrLoggingT :: MonadIO m => LoggingT m a -> m a runStderrLoggingT = (`runLoggingT` defaultOutput stderr) -- | Run a block using a @MonadLogger@ instance which prints to stdout. ----- Since 0.2.2+-- @since 0.2.2 runStdoutLoggingT :: MonadIO m => LoggingT m a -> m a runStdoutLoggingT = (`runLoggingT` defaultOutput stdout) +-- | Run a block using a @MonadLogger@ instance which writes tuples to an+-- unbounded channel.+--+-- The tuples can be extracted (ie. in another thread) with `unChanLoggingT`+-- or a custom extraction funtion, and written to a destination.+--+-- @since 0.3.17+runChanLoggingT :: MonadIO m => Chan LogLine -> LoggingT m a -> m a+runChanLoggingT chan = (`runLoggingT` sink chan)+ where+ sink chan' loc src lvl msg = writeChan chan' (loc,src,lvl,msg)++-- | Read logging tuples from an unbounded channel and log them into a+-- `MonadLoggerIO` monad, forever.+--+-- For use in a dedicated thread with a channel fed by `runChanLoggingT`.+--+-- @since 0.3.17+unChanLoggingT :: (MonadLogger m, MonadIO m) => Chan LogLine -> m void+unChanLoggingT chan = forever $ do+ (loc,src,lvl,msg) <- liftIO $ readChan chan+ monadLoggerLog loc src lvl msg+ -- | Within the 'LoggingT' monad, capture all log messages to a bounded -- channel of the indicated size, and only actually log them if there is an -- exception. ----- Since 0.3.2+-- @since 0.3.2 withChannelLogger :: (MonadBaseControl IO m, MonadIO m)- => Int -- ^ Number of mesasges to keep+ => Int -- ^ Number of messages to keep -> LoggingT m a -> LoggingT m a withChannelLogger size action = LoggingT $ \logger -> do@@ -527,6 +841,18 @@ dumpLogs chan = liftIO $ sequence_ =<< atomically (untilM (readTBChan chan) (isEmptyTBChan chan)) +-- | Only log messages passing the given predicate function.+--+-- This can be a convenient way, for example, to ignore debug level messages.+--+-- @since 0.3.13+filterLogger :: (LogSource -> LogLevel -> Bool)+ -> LoggingT m a+ -> LoggingT m a+filterLogger p (LoggingT f) = LoggingT $ \logger ->+ f $ \loc src level msg ->+ when (p src level) $ logger loc src level msg+ instance MonadCont m => MonadCont (LoggingT m) where callCC f = LoggingT $ \i -> callCC $ \c -> runLoggingT (f (LoggingT . const . c)) i @@ -534,12 +860,24 @@ throwError = Trans.lift . throwError catchError r h = LoggingT $ \i -> runLoggingT r i `catchError` \e -> runLoggingT (h e) i +instance MonadError e m => MonadError e (NoLoggingT m) where+ throwError = Trans.lift . throwError+ catchError r h = NoLoggingT $ runNoLoggingT r `catchError` \e -> runNoLoggingT (h e)+ instance MonadRWS r w s m => MonadRWS r w s (LoggingT m) instance MonadReader r m => MonadReader r (LoggingT m) where ask = Trans.lift ask local = mapLoggingT . local +-- | @since 0.3.24+instance MonadReader r m => MonadReader r (NoLoggingT m) where+ ask = Trans.lift ask+ local = mapNoLoggingT . local++-- | Map the unwrapped computation using the given function.+--+-- @since 0.3.29 mapLoggingT :: (m a -> n b) -> LoggingT m a -> LoggingT n b mapLoggingT f = LoggingT . (f .) . runLoggingT @@ -552,9 +890,44 @@ listen = mapLoggingT listen pass = mapLoggingT pass +-- | Map the unwrapped computation using the given function.+--+-- @since 0.3.29+mapNoLoggingT :: (m a -> n b) -> NoLoggingT m a -> NoLoggingT n b+mapNoLoggingT f = NoLoggingT . f . runNoLoggingT++instance MonadState s m => MonadState s (NoLoggingT m) where+ get = Trans.lift get+ put = Trans.lift . put++instance MonadWriter w m => MonadWriter w (NoLoggingT m) where+ tell = Trans.lift . tell+ listen = mapNoLoggingT listen+ pass = mapNoLoggingT pass+ +#if MIN_VERSION_mtl(2, 3, 1)+-- | @since 0.3.41+instance MonadAccum w m => MonadAccum w (LoggingT m) where+ accum = Trans.lift . accum++-- | @since 0.3.41+instance MonadAccum w m => MonadAccum w (NoLoggingT m) where+ accum = Trans.lift . accum+#endif++-- | dummy location, used with 'logWithoutLoc'+--+-- @since 0.3.23 defaultLoc :: Loc defaultLoc = Loc "<unknown>" "<unknown>" "<unknown>" (0,0) (0,0) +isDefaultLoc :: Loc -> Bool+isDefaultLoc (Loc "<unknown>" "<unknown>" "<unknown>" (0,0) (0,0)) = True+isDefaultLoc _ = False++-- |+--+-- @since 0.3.23 logWithoutLoc :: (MonadLogger m, ToLogStr msg) => LogSource -> LogLevel -> msg -> m () logWithoutLoc = monadLoggerLog defaultLoc @@ -573,17 +946,79 @@ logOtherN :: MonadLogger m => LogLevel -> Text -> m () logOtherN = logWithoutLoc "" -logDebugNS :: MonadLogger m => Text -> Text -> m ()+logDebugNS :: MonadLogger m => LogSource -> Text -> m () logDebugNS src = logWithoutLoc src LevelDebug -logInfoNS :: MonadLogger m => Text -> Text -> m ()+logInfoNS :: MonadLogger m => LogSource -> Text -> m () logInfoNS src = logWithoutLoc src LevelInfo -logWarnNS :: MonadLogger m => Text -> Text -> m ()+logWarnNS :: MonadLogger m => LogSource -> Text -> m () logWarnNS src = logWithoutLoc src LevelWarn -logErrorNS :: MonadLogger m => Text -> Text -> m ()+logErrorNS :: MonadLogger m => LogSource -> Text -> m () logErrorNS src = logWithoutLoc src LevelError -logOtherNS :: MonadLogger m => Text -> LogLevel -> Text -> m ()+logOtherNS :: MonadLogger m => LogSource -> LogLevel -> Text -> m () logOtherNS = logWithoutLoc++#if WITH_CALLSTACK+-- Callstack based logging++mkLoggerLoc :: GHC.SrcLoc -> Loc+mkLoggerLoc loc =+ Loc { loc_filename = GHC.srcLocFile loc+ , loc_package = GHC.srcLocPackage loc+ , loc_module = GHC.srcLocModule loc+ , loc_start = ( GHC.srcLocStartLine loc+ , GHC.srcLocStartCol loc)+ , loc_end = ( GHC.srcLocEndLine loc+ , GHC.srcLocEndCol loc)+ }++locFromCS :: GHC.CallStack -> Loc+locFromCS cs = case getCallStack cs of+ ((_, loc):_) -> mkLoggerLoc loc+ _ -> defaultLoc++logCS :: (MonadLogger m, ToLogStr msg)+ => GHC.CallStack+ -> LogSource+ -> LogLevel+ -> msg+ -> m ()+logCS cs src lvl msg =+ monadLoggerLog (locFromCS cs) src lvl msg++-- | Logs a message with location given by 'CallStack'.+-- See 'Control.Monad.Logger.CallStack' for more convenient+-- functions for 'CallStack' based logging.+--+-- @since 0.3.19+logDebugCS :: MonadLogger m => GHC.CallStack -> Text -> m ()+logDebugCS cs msg = logCS cs "" LevelDebug msg++-- | See 'logDebugCS'+--+-- @since 0.3.19+logInfoCS :: MonadLogger m => GHC.CallStack -> Text -> m ()+logInfoCS cs msg = logCS cs "" LevelInfo msg++-- | See 'logDebugCS'+--+-- @since 0.3.19+logWarnCS :: MonadLogger m => GHC.CallStack -> Text -> m ()+logWarnCS cs msg = logCS cs "" LevelWarn msg++-- | See 'logDebugCS'+--+-- @since 0.3.19+logErrorCS :: MonadLogger m => GHC.CallStack -> Text -> m ()+logErrorCS cs msg = logCS cs "" LevelError msg++-- | See 'logDebugCS'+--+-- @since 0.3.19+logOtherCS :: MonadLogger m => GHC.CallStack -> LogLevel -> Text -> m ()+logOtherCS cs lvl msg = logCS cs "" lvl msg++#endif
+ Control/Monad/Logger/CallStack.hs view
@@ -0,0 +1,86 @@+-- | Log functions using CallStack support in place of Template Haskell+--+-- @since 0.3.19+module Control.Monad.Logger.CallStack (+ module Log+ , logDebug+ , logInfo+ , logWarn+ , logError+ , logOther+ , logDebugSH+ , logInfoSH+ , logWarnSH+ , logErrorSH+ , logOtherSH+ ) where++import Control.Monad.Logger as Log hiding (logDebug, logDebugSH,+ logError, logErrorSH, logInfo,+ logInfoSH, logOther, logOtherSH,+ logWarn, logWarnSH)+import Data.Text (Text)+import qualified Data.Text as Text+import GHC.Stack++-- | Logs a message with the location provided by+-- an implicit 'CallStack'.+--+-- @since 0.3.19+logDebug :: (HasCallStack, Log.MonadLogger m) => Text -> m ()+logDebug = Log.logDebugCS callStack++-- | See 'logDebug'+--+-- @since 0.3.19+logInfo :: (HasCallStack, Log.MonadLogger m) => Text -> m ()+logInfo = Log.logInfoCS callStack++-- | See 'logDebug'+--+-- @since 0.3.19+logWarn :: (HasCallStack, Log.MonadLogger m) => Text -> m ()+logWarn = Log.logWarnCS callStack++-- | See 'logDebug'+--+-- @since 0.3.19+logError :: (HasCallStack, Log.MonadLogger m) => Text -> m ()+logError = Log.logErrorCS callStack++-- | See 'logDebug'+--+-- @since 0.3.25+logOther :: (HasCallStack, Log.MonadLogger m) => Log.LogLevel -> Text -> m ()+logOther = Log.logOtherCS callStack++-- | Logs a showable value with the location provided by+-- an implicit 'CallStack'.+--+-- @since 0.3.25+logDebugSH :: (HasCallStack, Log.MonadLogger m, Show a) => a -> m ()+logDebugSH = Log.logDebugCS callStack . Text.pack . show++-- | See 'logDebugSH'+--+-- @since 0.3.25+logInfoSH :: (HasCallStack, Log.MonadLogger m, Show a) => a -> m ()+logInfoSH = Log.logInfoCS callStack . Text.pack . show++-- | See 'logDebugSH'+--+-- @since 0.3.25+logWarnSH :: (HasCallStack, Log.MonadLogger m, Show a) => a -> m ()+logWarnSH = Log.logWarnCS callStack . Text.pack . show++-- | See 'logDebugSH'+--+-- @since 0.3.25+logErrorSH :: (HasCallStack, Log.MonadLogger m, Show a) => a -> m ()+logErrorSH = Log.logErrorCS callStack . Text.pack . show++-- | See 'logDebugSH'+--+-- @since 0.3.25+logOtherSH :: (HasCallStack, Log.MonadLogger m, Show a) => Log.LogLevel -> a -> m ()+logOtherSH lvl = Log.logOtherCS callStack lvl . Text.pack . show
+ README.md view
@@ -0,0 +1,9 @@+## monad-logger++[](https://travis-ci.org/snoyberg/monad-logger)+[](https://ci.appveyor.com/project/snoyberg/monad-logger/branch/master)+[](https://hackage.haskell.org/package/monad-logger)++A monad transformer approach for logging.++This package provides Template Haskell functions for determining source code locations of messages.
monad-logger.cabal view
@@ -1,44 +1,65 @@-name: monad-logger-version: 0.3.7.1-synopsis: A class of monads which can log messages.-description: This package uses template-haskell for determining source code locations of messages.-homepage: https://github.com/kazu-yamamoto/logger-license: MIT-license-file: LICENSE-author: Michael Snoyman-maintainer: michael@snoyman.com-category: System-build-type: Simple-cabal-version: >=1.8+cabal-version: 1.12 +-- This file has been generated from package.yaml by hpack version 0.37.0.+--+-- see: https://github.com/sol/hpack -flag template_haskell {- Description: Enable Template Haskell support- Default: True- Manual: True-}+name: monad-logger+version: 0.3.42+synopsis: A class of monads which can log messages.+description: See README and Haddocks at <https://www.stackage.org/package/monad-logger>+category: System+homepage: https://github.com/snoyberg/monad-logger#readme+bug-reports: https://github.com/snoyberg/monad-logger/issues+author: Michael Snoyman+maintainer: michael@snoyman.com+license: MIT+license-file: LICENSE+build-type: Simple+extra-source-files:+ ChangeLog.md+ README.md +source-repository head+ type: git+ location: https://github.com/snoyberg/monad-logger++flag template_haskell+ description: Enable Template Haskell support+ manual: True+ default: True+ library- exposed-modules: Control.Monad.Logger- build-depends: base >= 4 && < 5- , transformers- , text- , stm- , stm-chans- , lifted-base- , resourcet >= 0.4 && < 1.2- , conduit >= 1.0 && < 1.2- , conduit-extra >= 1.0 && < 1.2- , fast-logger >= 2.0 && < 2.3- , transformers-base- , monad-control- , monad-loops- , mtl- , bytestring- , blaze-builder- , exceptions+ exposed-modules:+ Control.Monad.Logger+ other-modules:+ Paths_monad_logger+ build-depends:+ base >=4.11 && <5+ , bytestring >=0.10.2+ , conduit >=1.0 && <1.4+ , conduit-extra >=1.1 && <1.4+ , exceptions >=0.6 && <0.11+ , fast-logger >=2.1 && <3.3+ , lifted-base+ , monad-control >=1.0+ , monad-loops+ , mtl+ , resourcet >=1.1 && <1.4+ , stm+ , stm-chans+ , text+ , transformers+ , transformers-base+ , transformers-compat >=0.3+ , unliftio-core+ default-language: Haskell2010+ if impl(ghc >=8.0.1)+ exposed-modules:+ Control.Monad.Logger.CallStack+ cpp-options: -DWITH_CALLSTACK if flag(template_haskell)- build-depends: template-haskell-+ build-depends:+ template-haskell if flag(template_haskell)- cpp-options: -DWITH_TEMPLATE_HASKELL+ cpp-options: -DWITH_TEMPLATE_HASKELL