@@ -28,33 +28,18 @@ module Katip.Monadic
2828 , AnyLogContext
2929 , LogContexts
3030 , liftPayload
31−
32− -- * Transformer for appending to a log context
33− , LogT'
34− , LogT
35− , runLogT
36− , BlankLogT
37− , runBlankLogT
3831 ) where
3932
4033
4134-------------------------------------------------------------------------------
42−import Control.Applicative
43−import Control.Monad
44−import Control.Monad.Base
4535import Control.Monad.Catch
46−import Control.Monad.Error.Class
47−import Control.Monad.Fix
48−import Control.Monad.IO.Class
49−import Control.Monad.RWS.Class
5036import Control.Monad.Trans.Class
51−import Control.Monad.Trans.Control
5237import Control.Monad.Trans.Either (EitherT)
5338import Control.Monad.Trans.Except (ExceptT)
5439import Control.Monad.Trans.Identity (IdentityT)
5540import Control.Monad.Trans.List (ListT)
5641import Control.Monad.Trans.Maybe (MaybeT)
57−import Control.Monad.Trans.Reader (ReaderT (..), runReaderT)
42+import Control.Monad.Trans.Reader (ReaderT)
5843import Control.Monad.Trans.Resource (ResourceT)
5944import Control.Monad.Trans.RWS (RWST)
6045import qualified Control.Monad.Trans.RWS.Strict as Strict (RWST)
@@ -195,128 +180,3 @@ logExceptionM action sev = action `catchAll` \e -> f e >> throwM e
195180 where
196181 f e = logFM sev (msg e)
197182 msg e = ls ("An exception has occured: " :: Text) <> showLS e
198−
199−
200−-------------------------------------------------------------------------------
201−-- | Wrapper over 'ReaderT' that provides a passthrough instance for
202−-- 'MonadReader' so your stack will not be affected. Also provides a
203−-- 'KatipContext' instance which combines with the inner monad's
204−-- instance.
205−--
206−-- @
207−-- instance KatipContext m WebMonad where
208−-- getKatipContext = ...
209−-- getKatipNamespace = Namespace ["web"]
210−--
211−-- dbCallInWeb = runLogT getDBContext (Namespace ["db"]) $ do
212−-- someStuff
213−-- @
214−--
215−-- In the above example, any logging inside of @dbCallInWeb@ will get
216−-- the (optionally) monadic log context for the db, combine it with
217−-- the web server's and will use the namespace @Namespace ["web","db"]@.
218−--
219−-- 'LogT' is exported which fixes @n ~ m@. The two type
220−-- variables must be present for defining a 'MonadTransControl' instance.
221−newtype LogT' n m a = LogT {
222− unLogT :: ReaderT (n LogContexts, n Namespace) m a
223− } deriving ( Functor
224− , Applicative
225− , Monad
226− , MonadIO
227− , MonadThrow
228− , MonadCatch
229− , MonadMask
230− , MonadBase b
231− , MonadState s
232− , MonadWriter w
233− , MonadError e
234− , MonadPlus
235− , Alternative
236− , MonadFix
237− , Katip
238− )
239−
240−type LogT m a = LogT' m m a
241−
242−instance MonadTrans (LogT' n) where
243− lift = LogT . lift
244−
245−-- Reader is a passthrough. We don't expose our internal reader so as not to conflict
246−instance (MonadReader r m) => MonadReader r (LogT' n m) where
247− ask = lift ask
248− local f (LogT (ReaderT m)) = LogT $ ReaderT $ \r ->
249− local f (m r)
250−
251−instance MonadTransControl (LogT' n) where
252− type StT (LogT' n) a = StT (ReaderT (n LogContexts)) a
253− liftWith = defaultLiftWith LogT unLogT
254− restoreT = defaultRestoreT LogT
255− {-# INLINE liftWith #-}
256− {-# INLINE restoreT #-}
257−
258−instance (MonadBaseControl b m) => MonadBaseControl b (LogT' n m) where
259− type StM ((LogT' n) m) a = ComposeSt (LogT' n) m a
260− liftBaseWith = defaultLiftBaseWith
261− restoreM = defaultRestoreM
262−
263−instance (KatipContext m, Monad m) => KatipContext (LogT' m m) where
264− getKatipContext = LogT $ ReaderT $ \(gctxs, _) -> do
265− ctxs <- gctxs
266− ctxs' <- getKatipContext
267− return $ ctxs <> ctxs'
268− getKatipNamespace = LogT $ ReaderT $ \(_, getNsInner) -> do
269− nsOuter <- getKatipNamespace
270− nsInner <- getNsInner
271− return $ nsOuter <> nsInner
272−
273−runLogT
274− :: (Functor m, LogItem a)
275− => m a
276− -> m Namespace
277− -> LogT m b
278− -> m b
279−runLogT lgtr nsgtr m = runReaderT (unLogT m) (liftPayload <$> lgtr, nsgtr)
280−
281−
282−-------------------------------------------------------------------------------
283−-- | Type analogous to IdentityT that provides an empty log
284−-- context. Use this if your root monad doesn't have a LogContext instance.
285−newtype BlankLogT m a = BlankLogT {
286− runBlankLogT :: m a
287− } deriving ( Functor
288− , Applicative
289− , Monad
290− , MonadIO
291− , MonadThrow
292− , MonadCatch
293− , MonadMask
294− , MonadBase b
295− , MonadReader r
296− , MonadState s
297− , MonadWriter w
298− , MonadError e
299− , MonadPlus
300− , Alternative
301− , MonadFix
302− , Katip
303− )
304−
305−instance Katip m => KatipContext (BlankLogT m) where
306− getKatipContext = return mempty
307− getKatipNamespace = return mempty
308−
309−instance MonadTrans BlankLogT where
310− lift = BlankLogT
311−
312−instance MonadTransControl BlankLogT where
313− type StT BlankLogT a = a
314− liftWith f = BlankLogT $ f runBlankLogT
315− restoreT = BlankLogT
316− {-# INLINABLE liftWith #-}
317− {-# INLINABLE restoreT #-}
318−
319−instance (MonadBaseControl b m) => MonadBaseControl b (BlankLogT m) where
320− type StM (BlankLogT m) a = ComposeSt BlankLogT m a
321− liftBaseWith = defaultLiftBaseWith
322− restoreM = defaultRestoreM