@@ -29,7 +29,7 @@ import qualified Control.Concurrent.Async as Async
2929import Control.Concurrent.STM
3030import qualified Control.Concurrent.STM.TBQueue as BQ
3131import Control.Exception.Safe
32−import Control.Monad (unless, void)
32+import Control.Monad (unless, void, when)
3333import Control.Monad.Base
3434import Control.Monad.IO.Class
3535import Control.Monad.IO.Unlift
@@ -555,22 +555,38 @@ itemJson verb a = toJSON $ a & itemPayload %~ payloadObject verb
555555-- down gracefully before returning. This can be hooked into your
556556-- application's shutdown routine to ensure you never miss any log
557557-- messages on shutdown.
558+
559+
560+-- | Signature of a function passed to `Scribe` constructor and mkScribe* functions
561+-- that decides which messages to be logged
562+type PermitFunc = forall a. Item a -> IO Bool
563+
564+
558565data Scribe = Scribe {
559566 liPush :: forall a. LogItem a => Item a -> IO ()
560567 , scribeFinalizer :: IO ()
561568 -- ^ Provide a *blocking* finalizer to call when your scribe is
562569 -- removed. If this is not relevant to your scribe, return () is
563570 -- fine.
571+ , scribePermitItem :: PermitFunc
572+ -- ^ Provide a filtering function to allow the item to be logged, or not.
573+ -- It can check Severity or some string in item's body.
564574 }
565575
576+whenM :: Monad m => m Bool -> m () -> m ()
577+whenM mbool = (>>=) mbool . flip when
566578
567579instance Semigroup Scribe where
568− (Scribe pushA finA) <> (Scribe pushB finB) =
569− Scribe (\item -> pushA item >> pushB item) (finA `finally` finB)
580+ (Scribe pushA finA permitA) <> (Scribe pushB finB permitB) =
581+ Scribe (\item -> whenM (permitA item) (pushA item)
582+ >> whenM (permitB item) (pushB item)
583+ )
584+ (finA `finally` finB)
585+ (\item -> (||) <$> permitA item <*> permitB item)
570586
571587
572588instance Monoid Scribe where
573− mempty = Scribe (const (return ())) (return ())
589+ mempty = Scribe (const (return ())) (return ()) (permitItem DebugS)
574590 mappend = (<>)
575591
576592
@@ -589,8 +605,8 @@ data WorkerMessage where
589605
590606-------------------------------------------------------------------------------
591607-- | Should this item be logged given the user's maximum severity?
592−permitItem :: Severity -> Item a -> Bool
593−permitItem sev i = _itemSeverity i >= sev
608+permitItem :: Monad m => Severity -> Item a -> m Bool
609+permitItem sev Item{..} = return $ _itemSeverity >= sev
594610
595611
596612-------------------------------------------------------------------------------
@@ -660,7 +676,7 @@ registerScribe nm scribe ScribeSettings {..} le = do
660676
661677-------------------------------------------------------------------------------
662678spawnScribeWorker :: Scribe -> BQ.TBQueue WorkerMessage -> IO (Async.Async ())
663−spawnScribeWorker (Scribe write _) queue = Async.async go
679+spawnScribeWorker (Scribe write _ _) queue = Async.async go
664680 where
665681 go = do
666682 newCmd <- atomically (BQ.readTBQueue queue)
@@ -896,8 +912,9 @@ logItem a ns loc sev msg = do
896912 <*> _logEnvTimer
897913 <*> pure (_logEnvApp <> ns)
898914 <*> pure loc
899− FT.forM_ (M.elems _logEnvScribes) $ \ ScribeHandle {..} -> atomically (tryWriteTBQueue shChan (NewItem item))
900−
915+ FT.forM_ (M.elems _logEnvScribes) $ \ ScribeHandle {..} -> do
916+ whenM (scribePermitItem shScribe item) $
917+ void $ atomically (tryWriteTBQueue shChan (NewItem item))
901918
902919-------------------------------------------------------------------------------
903920tryWriteTBQueue