packages feed

katip 0.1.1.0 → 0.2.0.0

raw patch · 11 files changed

+406/−88 lines, 11 filesdep +microlensdep +microlens-thdep −lensdep −lens-aesondep ~mtldep ~transformersdep ~transformers-basePVP ok

version bump matches the API change (PVP)

Dependencies added: microlens, microlens-th

Dependencies removed: lens, lens-aeson

Dependency ranges changed: mtl, transformers, transformers-base, unordered-containers

API changes (from Hackage documentation)

- Katip: _itemApp :: Item a -> Namespace
- Katip: _itemEnv :: Item a -> Environment
- Katip: _itemHost :: Item a -> HostName
- Katip: _itemLoc :: Item a -> Maybe Loc
- Katip: _itemMessage :: Item a -> LogStr
- Katip: _itemNamespace :: Item a -> Namespace
- Katip: _itemPayload :: Item a -> a
- Katip: _itemProcess :: Item a -> ProcessID
- Katip: _itemSeverity :: Item a -> Severity
- Katip: _itemThread :: Item a -> ThreadIdText
- Katip: _itemTime :: Item a -> UTCTime
- Katip: _logEnvEnv :: LogEnv -> Environment
- Katip: _logEnvHost :: LogEnv -> HostName
- Katip: _logEnvNs :: LogEnv -> Namespace
- Katip: _logEnvPid :: LogEnv -> ProcessID
- Katip: _logEnvScribes :: LogEnv -> Map Text Scribe
- Katip: _logEnvTimer :: LogEnv -> IO UTCTime
- Katip: getEnvironment :: Environment -> Text
- Katip: getThreadIdText :: ThreadIdText -> Text
- Katip: liPush :: Scribe -> forall a. LogItem a => Item a -> IO ()
- Katip: logEnvNs :: Lens' LogEnv Namespace
- Katip: severityText :: Prism' Text Severity
- Katip: unKatipT :: KatipT m a -> ReaderT LogEnv m a
- Katip: unLogStr :: LogStr -> Builder
- Katip: unNamespace :: Namespace -> [Text]
- Katip.Core: _itemApp :: Item a -> Namespace
- Katip.Core: _itemEnv :: Item a -> Environment
- Katip.Core: _itemHost :: Item a -> HostName
- Katip.Core: _itemLoc :: Item a -> Maybe Loc
- Katip.Core: _itemMessage :: Item a -> LogStr
- Katip.Core: _itemNamespace :: Item a -> Namespace
- Katip.Core: _itemPayload :: Item a -> a
- Katip.Core: _itemProcess :: Item a -> ProcessID
- Katip.Core: _itemSeverity :: Item a -> Severity
- Katip.Core: _itemThread :: Item a -> ThreadIdText
- Katip.Core: _itemTime :: Item a -> UTCTime
- Katip.Core: _logEnvEnv :: LogEnv -> Environment
- Katip.Core: _logEnvHost :: LogEnv -> HostName
- Katip.Core: _logEnvNs :: LogEnv -> Namespace
- Katip.Core: _logEnvPid :: LogEnv -> ProcessID
- Katip.Core: _logEnvScribes :: LogEnv -> Map Text Scribe
- Katip.Core: _logEnvTimer :: LogEnv -> IO UTCTime
- Katip.Core: getEnvironment :: Environment -> Text
- Katip.Core: getLocJs :: LocJs -> Loc
- Katip.Core: getProcessIDJs :: ProcessIDJs -> ProcessID
- Katip.Core: getThreadIdText :: ThreadIdText -> Text
- Katip.Core: instance (Katip m, Monoid s) => Katip (WriterT s m)
- Katip.Core: instance Applicative m => Applicative (KatipT m)
- Katip.Core: instance Bounded Severity
- Katip.Core: instance Constructor C1_0Environment
- Katip.Core: instance Constructor C1_0Item
- Katip.Core: instance Constructor C1_0LogStr
- Katip.Core: instance Constructor C1_0Namespace
- Katip.Core: instance Constructor C1_0Severity
- Katip.Core: instance Constructor C1_0Verbosity
- Katip.Core: instance Constructor C1_1Severity
- Katip.Core: instance Constructor C1_1Verbosity
- Katip.Core: instance Constructor C1_2Severity
- Katip.Core: instance Constructor C1_2Verbosity
- Katip.Core: instance Constructor C1_3Severity
- Katip.Core: instance Constructor C1_3Verbosity
- Katip.Core: instance Constructor C1_4Severity
- Katip.Core: instance Constructor C1_5Severity
- Katip.Core: instance Constructor C1_6Severity
- Katip.Core: instance Constructor C1_7Severity
- Katip.Core: instance Datatype D1Environment
- Katip.Core: instance Datatype D1Item
- Katip.Core: instance Datatype D1LogStr
- Katip.Core: instance Datatype D1Namespace
- Katip.Core: instance Datatype D1Severity
- Katip.Core: instance Datatype D1Verbosity
- Katip.Core: instance Enum Severity
- Katip.Core: instance Enum Verbosity
- Katip.Core: instance Eq Environment
- Katip.Core: instance Eq Namespace
- Katip.Core: instance Eq Severity
- Katip.Core: instance Eq ThreadIdText
- Katip.Core: instance Eq Verbosity
- Katip.Core: instance FromJSON Environment
- Katip.Core: instance FromJSON LocJs
- Katip.Core: instance FromJSON LogStr
- Katip.Core: instance FromJSON Namespace
- Katip.Core: instance FromJSON ProcessIDJs
- Katip.Core: instance FromJSON Severity
- Katip.Core: instance FromJSON ThreadIdText
- Katip.Core: instance FromJSON a => FromJSON (Item a)
- Katip.Core: instance Functor Item
- Katip.Core: instance Functor m => Functor (KatipT m)
- Katip.Core: instance Generic (Item a)
- Katip.Core: instance Generic Environment
- Katip.Core: instance Generic LogStr
- Katip.Core: instance Generic Namespace
- Katip.Core: instance Generic Severity
- Katip.Core: instance Generic Verbosity
- Katip.Core: instance IsString Environment
- Katip.Core: instance IsString LogStr
- Katip.Core: instance IsString Namespace
- Katip.Core: instance Katip m => Katip (EitherT s m)
- Katip.Core: instance Katip m => Katip (ExceptT s m)
- Katip.Core: instance Katip m => Katip (MaybeT m)
- Katip.Core: instance Katip m => Katip (ReaderT s m)
- Katip.Core: instance Katip m => Katip (ResourceT m)
- Katip.Core: instance Katip m => Katip (StateT s m)
- Katip.Core: instance Lift Namespace
- Katip.Core: instance Lift Severity
- Katip.Core: instance Lift Verbosity
- Katip.Core: instance LogItem ()
- Katip.Core: instance LogItem SimpleLogPayload
- Katip.Core: instance Monad m => Monad (KatipT m)
- Katip.Core: instance MonadBase b m => MonadBase b (KatipT m)
- Katip.Core: instance MonadBaseControl b m => MonadBaseControl b (KatipT m)
- Katip.Core: instance MonadCatch m => MonadCatch (KatipT m)
- Katip.Core: instance MonadIO m => Katip (KatipT m)
- Katip.Core: instance MonadIO m => MonadIO (KatipT m)
- Katip.Core: instance MonadMask m => MonadMask (KatipT m)
- Katip.Core: instance MonadThrow m => MonadThrow (KatipT m)
- Katip.Core: instance MonadTrans KatipT
- Katip.Core: instance MonadTransControl KatipT
- Katip.Core: instance Monoid LogStr
- Katip.Core: instance Monoid Namespace
- Katip.Core: instance Monoid PayloadSelection
- Katip.Core: instance Monoid Scribe
- Katip.Core: instance Monoid SimpleLogPayload
- Katip.Core: instance Ord Environment
- Katip.Core: instance Ord Namespace
- Katip.Core: instance Ord Severity
- Katip.Core: instance Ord ThreadIdText
- Katip.Core: instance Ord Verbosity
- Katip.Core: instance Read Environment
- Katip.Core: instance Read Namespace
- Katip.Core: instance Read Severity
- Katip.Core: instance Read Verbosity
- Katip.Core: instance Selector S1_0_0Environment
- Katip.Core: instance Selector S1_0_0Item
- Katip.Core: instance Selector S1_0_0LogStr
- Katip.Core: instance Selector S1_0_0Namespace
- Katip.Core: instance Selector S1_0_10Item
- Katip.Core: instance Selector S1_0_1Item
- Katip.Core: instance Selector S1_0_2Item
- Katip.Core: instance Selector S1_0_3Item
- Katip.Core: instance Selector S1_0_4Item
- Katip.Core: instance Selector S1_0_5Item
- Katip.Core: instance Selector S1_0_6Item
- Katip.Core: instance Selector S1_0_7Item
- Katip.Core: instance Selector S1_0_8Item
- Katip.Core: instance Selector S1_0_9Item
- Katip.Core: instance Show Environment
- Katip.Core: instance Show LocShow
- Katip.Core: instance Show LogStr
- Katip.Core: instance Show Namespace
- Katip.Core: instance Show Severity
- Katip.Core: instance Show ThreadIdText
- Katip.Core: instance Show Verbosity
- Katip.Core: instance Show a => Show (Item a)
- Katip.Core: instance ToJSON Environment
- Katip.Core: instance ToJSON LocJs
- Katip.Core: instance ToJSON Namespace
- Katip.Core: instance ToJSON ProcessIDJs
- Katip.Core: instance ToJSON Severity
- Katip.Core: instance ToJSON SimpleLogPayload
- Katip.Core: instance ToJSON ThreadIdText
- Katip.Core: instance ToJSON a => ToJSON (Item a)
- Katip.Core: instance ToObject ()
- Katip.Core: instance ToObject Object
- Katip.Core: instance ToObject SimpleLogPayload
- Katip.Core: liPush :: Scribe -> forall a. LogItem a => Item a -> IO ()
- Katip.Core: logEnvNs :: Lens' LogEnv Namespace
- Katip.Core: processIDText :: Prism' Text ProcessID
- Katip.Core: severityText :: Prism' Text Severity
- Katip.Core: unKatipT :: KatipT m a -> ReaderT LogEnv m a
- Katip.Core: unLogStr :: LogStr -> Builder
- Katip.Core: unNamespace :: Namespace -> [Text]
- Katip.Core: unSimpleLogPayload :: SimpleLogPayload -> [(Text, AnyLogPayload)]
- Katip.Monadic: instance (KatipContext m, Katip (EitherT e m)) => KatipContext (EitherT e m)
- Katip.Monadic: instance (KatipContext m, Katip (ExceptT s m)) => KatipContext (ExceptT s m)
- Katip.Monadic: instance (KatipContext m, Katip (IdentityT m)) => KatipContext (IdentityT m)
- Katip.Monadic: instance (KatipContext m, Katip (ListT m)) => KatipContext (ListT m)
- Katip.Monadic: instance (KatipContext m, Katip (MaybeT m)) => KatipContext (MaybeT m)
- Katip.Monadic: instance (KatipContext m, Katip (ReaderT r m)) => KatipContext (ReaderT r m)
- Katip.Monadic: instance (KatipContext m, Katip (ResourceT m)) => KatipContext (ResourceT m)
- Katip.Monadic: instance (KatipContext m, Katip (StateT s m)) => KatipContext (StateT s m)
- Katip.Monadic: instance (Monad m, KatipContext m) => KatipContext (KatipT m)
- Katip.Monadic: instance (Monoid w, KatipContext m, Katip (RWST r w s m)) => KatipContext (RWST r w s m)
- Katip.Monadic: instance (Monoid w, KatipContext m, Katip (WriterT w m)) => KatipContext (WriterT w m)
- Katip.Monadic: instance Alternative m => Alternative (KatipContextT m)
- Katip.Monadic: instance Applicative m => Applicative (KatipContextT m)
- Katip.Monadic: instance Functor m => Functor (KatipContextT m)
- Katip.Monadic: instance LogItem LogContexts
- Katip.Monadic: instance Monad m => Monad (KatipContextT m)
- Katip.Monadic: instance MonadBase b m => MonadBase b (KatipContextT m)
- Katip.Monadic: instance MonadBaseControl b m => MonadBaseControl b (KatipContextT m)
- Katip.Monadic: instance MonadCatch m => MonadCatch (KatipContextT m)
- Katip.Monadic: instance MonadError e m => MonadError e (KatipContextT m)
- Katip.Monadic: instance MonadFix m => MonadFix (KatipContextT m)
- Katip.Monadic: instance MonadIO m => Katip (KatipContextT m)
- Katip.Monadic: instance MonadIO m => KatipContext (KatipContextT m)
- Katip.Monadic: instance MonadIO m => MonadIO (KatipContextT m)
- Katip.Monadic: instance MonadMask m => MonadMask (KatipContextT m)
- Katip.Monadic: instance MonadPlus m => MonadPlus (KatipContextT m)
- Katip.Monadic: instance MonadReader r m => MonadReader r (KatipContextT m)
- Katip.Monadic: instance MonadState s m => MonadState s (KatipContextT m)
- Katip.Monadic: instance MonadThrow m => MonadThrow (KatipContextT m)
- Katip.Monadic: instance MonadTrans KatipContextT
- Katip.Monadic: instance MonadTransControl KatipContextT
- Katip.Monadic: instance MonadWriter w m => MonadWriter w (KatipContextT m)
- Katip.Monadic: instance Monoid LogContexts
- Katip.Monadic: instance ToJSON LogContexts
- Katip.Monadic: instance ToObject LogContexts
- Katip.Monadic: ltsContext :: KatipContextTState -> !LogContexts
- Katip.Monadic: ltsLogEnv :: KatipContextTState -> !LogEnv
- Katip.Monadic: ltsNamespace :: KatipContextTState -> !Namespace
- Katip.Monadic: unKatipContextT :: KatipContextT m a -> ReaderT KatipContextTState m a
- Katip.Scribes.Handle: renderPrim :: Primitive -> Builder
+ Katip: [_itemApp] :: Item a -> Namespace
+ Katip: [_itemEnv] :: Item a -> Environment
+ Katip: [_itemHost] :: Item a -> HostName
+ Katip: [_itemLoc] :: Item a -> Maybe Loc
+ Katip: [_itemMessage] :: Item a -> LogStr
+ Katip: [_itemNamespace] :: Item a -> Namespace
+ Katip: [_itemPayload] :: Item a -> a
+ Katip: [_itemProcess] :: Item a -> ProcessID
+ Katip: [_itemSeverity] :: Item a -> Severity
+ Katip: [_itemThread] :: Item a -> ThreadIdText
+ Katip: [_itemTime] :: Item a -> UTCTime
+ Katip: [_logEnvApp] :: LogEnv -> Namespace
+ Katip: [_logEnvEnv] :: LogEnv -> Environment
+ Katip: [_logEnvHost] :: LogEnv -> HostName
+ Katip: [_logEnvPid] :: LogEnv -> ProcessID
+ Katip: [_logEnvScribes] :: LogEnv -> Map Text Scribe
+ Katip: [_logEnvTimer] :: LogEnv -> IO UTCTime
+ Katip: [getEnvironment] :: Environment -> Text
+ Katip: [getThreadIdText] :: ThreadIdText -> Text
+ Katip: [liPush] :: Scribe -> forall a. LogItem a => Item a -> IO ()
+ Katip: [unKatipT] :: KatipT m a -> ReaderT LogEnv m a
+ Katip: [unLogStr] :: LogStr -> Builder
+ Katip: [unNamespace] :: Namespace -> [Text]
+ Katip: katipAddContext :: (LogItem i, Monad m) => i -> KatipContextT m a -> KatipContextT m a
+ Katip: katipAddNamespace :: (Monad m) => Namespace -> KatipContextT m a -> KatipContextT m a
+ Katip: logEnvApp :: Lens' LogEnv Namespace
+ Katip: textToSeverity :: Text -> Maybe Severity
+ Katip.Core: [_itemApp] :: Item a -> Namespace
+ Katip.Core: [_itemEnv] :: Item a -> Environment
+ Katip.Core: [_itemHost] :: Item a -> HostName
+ Katip.Core: [_itemLoc] :: Item a -> Maybe Loc
+ Katip.Core: [_itemMessage] :: Item a -> LogStr
+ Katip.Core: [_itemNamespace] :: Item a -> Namespace
+ Katip.Core: [_itemPayload] :: Item a -> a
+ Katip.Core: [_itemProcess] :: Item a -> ProcessID
+ Katip.Core: [_itemSeverity] :: Item a -> Severity
+ Katip.Core: [_itemThread] :: Item a -> ThreadIdText
+ Katip.Core: [_itemTime] :: Item a -> UTCTime
+ Katip.Core: [_logEnvApp] :: LogEnv -> Namespace
+ Katip.Core: [_logEnvEnv] :: LogEnv -> Environment
+ Katip.Core: [_logEnvHost] :: LogEnv -> HostName
+ Katip.Core: [_logEnvPid] :: LogEnv -> ProcessID
+ Katip.Core: [_logEnvScribes] :: LogEnv -> Map Text Scribe
+ Katip.Core: [_logEnvTimer] :: LogEnv -> IO UTCTime
+ Katip.Core: [getEnvironment] :: Environment -> Text
+ Katip.Core: [getLocJs] :: LocJs -> Loc
+ Katip.Core: [getProcessIDJs] :: ProcessIDJs -> ProcessID
+ Katip.Core: [getThreadIdText] :: ThreadIdText -> Text
+ Katip.Core: [liPush] :: Scribe -> forall a. LogItem a => Item a -> IO ()
+ Katip.Core: [unKatipT] :: KatipT m a -> ReaderT LogEnv m a
+ Katip.Core: [unLogStr] :: LogStr -> Builder
+ Katip.Core: [unNamespace] :: Namespace -> [Text]
+ Katip.Core: [unSimpleLogPayload] :: SimpleLogPayload -> [(Text, AnyLogPayload)]
+ Katip.Core: getLocTH :: ExpQ
+ Katip.Core: instance (Katip.Core.Katip m, GHC.Base.Monoid s) => Katip.Core.Katip (Control.Monad.Trans.Writer.Lazy.WriterT s m)
+ Katip.Core: instance Control.Monad.Base.MonadBase b m => Control.Monad.Base.MonadBase b (Katip.Core.KatipT m)
+ Katip.Core: instance Control.Monad.Catch.MonadCatch m => Control.Monad.Catch.MonadCatch (Katip.Core.KatipT m)
+ Katip.Core: instance Control.Monad.Catch.MonadMask m => Control.Monad.Catch.MonadMask (Katip.Core.KatipT m)
+ Katip.Core: instance Control.Monad.Catch.MonadThrow m => Control.Monad.Catch.MonadThrow (Katip.Core.KatipT m)
+ Katip.Core: instance Control.Monad.IO.Class.MonadIO m => Control.Monad.IO.Class.MonadIO (Katip.Core.KatipT m)
+ Katip.Core: instance Control.Monad.IO.Class.MonadIO m => Katip.Core.Katip (Katip.Core.KatipT m)
+ Katip.Core: instance Control.Monad.Trans.Class.MonadTrans Katip.Core.KatipT
+ Katip.Core: instance Control.Monad.Trans.Control.MonadBaseControl b m => Control.Monad.Trans.Control.MonadBaseControl b (Katip.Core.KatipT m)
+ Katip.Core: instance Control.Monad.Trans.Control.MonadTransControl Katip.Core.KatipT
+ Katip.Core: instance Data.Aeson.Types.Class.FromJSON Katip.Core.Environment
+ Katip.Core: instance Data.Aeson.Types.Class.FromJSON Katip.Core.LocJs
+ Katip.Core: instance Data.Aeson.Types.Class.FromJSON Katip.Core.LogStr
+ Katip.Core: instance Data.Aeson.Types.Class.FromJSON Katip.Core.Namespace
+ Katip.Core: instance Data.Aeson.Types.Class.FromJSON Katip.Core.ProcessIDJs
+ Katip.Core: instance Data.Aeson.Types.Class.FromJSON Katip.Core.Severity
+ Katip.Core: instance Data.Aeson.Types.Class.FromJSON Katip.Core.ThreadIdText
+ Katip.Core: instance Data.Aeson.Types.Class.FromJSON a => Data.Aeson.Types.Class.FromJSON (Katip.Core.Item a)
+ Katip.Core: instance Data.Aeson.Types.Class.ToJSON Katip.Core.Environment
+ Katip.Core: instance Data.Aeson.Types.Class.ToJSON Katip.Core.LocJs
+ Katip.Core: instance Data.Aeson.Types.Class.ToJSON Katip.Core.Namespace
+ Katip.Core: instance Data.Aeson.Types.Class.ToJSON Katip.Core.ProcessIDJs
+ Katip.Core: instance Data.Aeson.Types.Class.ToJSON Katip.Core.Severity
+ Katip.Core: instance Data.Aeson.Types.Class.ToJSON Katip.Core.SimpleLogPayload
+ Katip.Core: instance Data.Aeson.Types.Class.ToJSON Katip.Core.ThreadIdText
+ Katip.Core: instance Data.Aeson.Types.Class.ToJSON a => Data.Aeson.Types.Class.ToJSON (Katip.Core.Item a)
+ Katip.Core: instance Data.String.IsString Katip.Core.Environment
+ Katip.Core: instance Data.String.IsString Katip.Core.LogStr
+ Katip.Core: instance Data.String.IsString Katip.Core.Namespace
+ Katip.Core: instance GHC.Base.Applicative m => GHC.Base.Applicative (Katip.Core.KatipT m)
+ Katip.Core: instance GHC.Base.Functor Katip.Core.Item
+ Katip.Core: instance GHC.Base.Functor m => GHC.Base.Functor (Katip.Core.KatipT m)
+ Katip.Core: instance GHC.Base.Monad m => GHC.Base.Monad (Katip.Core.KatipT m)
+ Katip.Core: instance GHC.Base.Monoid Katip.Core.LogStr
+ Katip.Core: instance GHC.Base.Monoid Katip.Core.Namespace
+ Katip.Core: instance GHC.Base.Monoid Katip.Core.PayloadSelection
+ Katip.Core: instance GHC.Base.Monoid Katip.Core.Scribe
+ Katip.Core: instance GHC.Base.Monoid Katip.Core.SimpleLogPayload
+ Katip.Core: instance GHC.Classes.Eq Katip.Core.Environment
+ Katip.Core: instance GHC.Classes.Eq Katip.Core.Namespace
+ Katip.Core: instance GHC.Classes.Eq Katip.Core.PayloadSelection
+ Katip.Core: instance GHC.Classes.Eq Katip.Core.Severity
+ Katip.Core: instance GHC.Classes.Eq Katip.Core.ThreadIdText
+ Katip.Core: instance GHC.Classes.Eq Katip.Core.Verbosity
+ Katip.Core: instance GHC.Classes.Ord Katip.Core.Environment
+ Katip.Core: instance GHC.Classes.Ord Katip.Core.Namespace
+ Katip.Core: instance GHC.Classes.Ord Katip.Core.Severity
+ Katip.Core: instance GHC.Classes.Ord Katip.Core.ThreadIdText
+ Katip.Core: instance GHC.Classes.Ord Katip.Core.Verbosity
+ Katip.Core: instance GHC.Enum.Bounded Katip.Core.Severity
+ Katip.Core: instance GHC.Enum.Enum Katip.Core.Severity
+ Katip.Core: instance GHC.Enum.Enum Katip.Core.Verbosity
+ Katip.Core: instance GHC.Generics.Constructor Katip.Core.C1_0Environment
+ Katip.Core: instance GHC.Generics.Constructor Katip.Core.C1_0Item
+ Katip.Core: instance GHC.Generics.Constructor Katip.Core.C1_0LogStr
+ Katip.Core: instance GHC.Generics.Constructor Katip.Core.C1_0Namespace
+ Katip.Core: instance GHC.Generics.Constructor Katip.Core.C1_0Severity
+ Katip.Core: instance GHC.Generics.Constructor Katip.Core.C1_0Verbosity
+ Katip.Core: instance GHC.Generics.Constructor Katip.Core.C1_1Severity
+ Katip.Core: instance GHC.Generics.Constructor Katip.Core.C1_1Verbosity
+ Katip.Core: instance GHC.Generics.Constructor Katip.Core.C1_2Severity
+ Katip.Core: instance GHC.Generics.Constructor Katip.Core.C1_2Verbosity
+ Katip.Core: instance GHC.Generics.Constructor Katip.Core.C1_3Severity
+ Katip.Core: instance GHC.Generics.Constructor Katip.Core.C1_3Verbosity
+ Katip.Core: instance GHC.Generics.Constructor Katip.Core.C1_4Severity
+ Katip.Core: instance GHC.Generics.Constructor Katip.Core.C1_5Severity
+ Katip.Core: instance GHC.Generics.Constructor Katip.Core.C1_6Severity
+ Katip.Core: instance GHC.Generics.Constructor Katip.Core.C1_7Severity
+ Katip.Core: instance GHC.Generics.Datatype Katip.Core.D1Environment
+ Katip.Core: instance GHC.Generics.Datatype Katip.Core.D1Item
+ Katip.Core: instance GHC.Generics.Datatype Katip.Core.D1LogStr
+ Katip.Core: instance GHC.Generics.Datatype Katip.Core.D1Namespace
+ Katip.Core: instance GHC.Generics.Datatype Katip.Core.D1Severity
+ Katip.Core: instance GHC.Generics.Datatype Katip.Core.D1Verbosity
+ Katip.Core: instance GHC.Generics.Generic (Katip.Core.Item a)
+ Katip.Core: instance GHC.Generics.Generic Katip.Core.Environment
+ Katip.Core: instance GHC.Generics.Generic Katip.Core.LogStr
+ Katip.Core: instance GHC.Generics.Generic Katip.Core.Namespace
+ Katip.Core: instance GHC.Generics.Generic Katip.Core.Severity
+ Katip.Core: instance GHC.Generics.Generic Katip.Core.Verbosity
+ Katip.Core: instance GHC.Generics.Selector Katip.Core.S1_0_0Environment
+ Katip.Core: instance GHC.Generics.Selector Katip.Core.S1_0_0Item
+ Katip.Core: instance GHC.Generics.Selector Katip.Core.S1_0_0LogStr
+ Katip.Core: instance GHC.Generics.Selector Katip.Core.S1_0_0Namespace
+ Katip.Core: instance GHC.Generics.Selector Katip.Core.S1_0_10Item
+ Katip.Core: instance GHC.Generics.Selector Katip.Core.S1_0_1Item
+ Katip.Core: instance GHC.Generics.Selector Katip.Core.S1_0_2Item
+ Katip.Core: instance GHC.Generics.Selector Katip.Core.S1_0_3Item
+ Katip.Core: instance GHC.Generics.Selector Katip.Core.S1_0_4Item
+ Katip.Core: instance GHC.Generics.Selector Katip.Core.S1_0_5Item
+ Katip.Core: instance GHC.Generics.Selector Katip.Core.S1_0_6Item
+ Katip.Core: instance GHC.Generics.Selector Katip.Core.S1_0_7Item
+ Katip.Core: instance GHC.Generics.Selector Katip.Core.S1_0_8Item
+ Katip.Core: instance GHC.Generics.Selector Katip.Core.S1_0_9Item
+ Katip.Core: instance GHC.Read.Read Katip.Core.Environment
+ Katip.Core: instance GHC.Read.Read Katip.Core.Namespace
+ Katip.Core: instance GHC.Read.Read Katip.Core.Severity
+ Katip.Core: instance GHC.Read.Read Katip.Core.Verbosity
+ Katip.Core: instance GHC.Show.Show Katip.Core.Environment
+ Katip.Core: instance GHC.Show.Show Katip.Core.LocShow
+ Katip.Core: instance GHC.Show.Show Katip.Core.LogStr
+ Katip.Core: instance GHC.Show.Show Katip.Core.Namespace
+ Katip.Core: instance GHC.Show.Show Katip.Core.PayloadSelection
+ Katip.Core: instance GHC.Show.Show Katip.Core.Severity
+ Katip.Core: instance GHC.Show.Show Katip.Core.ThreadIdText
+ Katip.Core: instance GHC.Show.Show Katip.Core.Verbosity
+ Katip.Core: instance GHC.Show.Show a => GHC.Show.Show (Katip.Core.Item a)
+ Katip.Core: instance Katip.Core.Katip m => Katip.Core.Katip (Control.Monad.Trans.Either.EitherT s m)
+ Katip.Core: instance Katip.Core.Katip m => Katip.Core.Katip (Control.Monad.Trans.Except.ExceptT s m)
+ Katip.Core: instance Katip.Core.Katip m => Katip.Core.Katip (Control.Monad.Trans.Maybe.MaybeT m)
+ Katip.Core: instance Katip.Core.Katip m => Katip.Core.Katip (Control.Monad.Trans.Reader.ReaderT s m)
+ Katip.Core: instance Katip.Core.Katip m => Katip.Core.Katip (Control.Monad.Trans.Resource.Internal.ResourceT m)
+ Katip.Core: instance Katip.Core.Katip m => Katip.Core.Katip (Control.Monad.Trans.State.Lazy.StateT s m)
+ Katip.Core: instance Katip.Core.LogItem ()
+ Katip.Core: instance Katip.Core.LogItem Katip.Core.SimpleLogPayload
+ Katip.Core: instance Katip.Core.ToObject ()
+ Katip.Core: instance Katip.Core.ToObject Data.Aeson.Types.Internal.Object
+ Katip.Core: instance Katip.Core.ToObject Katip.Core.SimpleLogPayload
+ Katip.Core: instance Language.Haskell.TH.Syntax.Lift Katip.Core.Namespace
+ Katip.Core: instance Language.Haskell.TH.Syntax.Lift Katip.Core.Severity
+ Katip.Core: instance Language.Haskell.TH.Syntax.Lift Katip.Core.Verbosity
+ Katip.Core: logEnvApp :: Lens' LogEnv Namespace
+ Katip.Core: logLoc :: (Applicative m, LogItem a, Katip m) => a -> Namespace -> Severity -> LogStr -> m ()
+ Katip.Core: processIDToText :: ProcessID -> Text
+ Katip.Core: readMay :: Read a => String -> Maybe a
+ Katip.Core: textToProcessID :: Text -> Maybe ProcessID
+ Katip.Core: textToSeverity :: Text -> Maybe Severity
+ Katip.Monadic: [ltsContext] :: KatipContextTState -> !LogContexts
+ Katip.Monadic: [ltsLogEnv] :: KatipContextTState -> !LogEnv
+ Katip.Monadic: [ltsNamespace] :: KatipContextTState -> !Namespace
+ Katip.Monadic: [unKatipContextT] :: KatipContextT m a -> ReaderT KatipContextTState m a
+ Katip.Monadic: instance (GHC.Base.Monad m, Katip.Monadic.KatipContext m) => Katip.Monadic.KatipContext (Katip.Core.KatipT m)
+ Katip.Monadic: instance (GHC.Base.Monoid w, Katip.Monadic.KatipContext m, Katip.Core.Katip (Control.Monad.Trans.RWS.Lazy.RWST r w s m)) => Katip.Monadic.KatipContext (Control.Monad.Trans.RWS.Lazy.RWST r w s m)
+ Katip.Monadic: instance (GHC.Base.Monoid w, Katip.Monadic.KatipContext m, Katip.Core.Katip (Control.Monad.Trans.RWS.Strict.RWST r w s m)) => Katip.Monadic.KatipContext (Control.Monad.Trans.RWS.Strict.RWST r w s m)
+ Katip.Monadic: instance (GHC.Base.Monoid w, Katip.Monadic.KatipContext m, Katip.Core.Katip (Control.Monad.Trans.Writer.Lazy.WriterT w m)) => Katip.Monadic.KatipContext (Control.Monad.Trans.Writer.Lazy.WriterT w m)
+ Katip.Monadic: instance (GHC.Base.Monoid w, Katip.Monadic.KatipContext m, Katip.Core.Katip (Control.Monad.Trans.Writer.Strict.WriterT w m)) => Katip.Monadic.KatipContext (Control.Monad.Trans.Writer.Strict.WriterT w m)
+ Katip.Monadic: instance (Katip.Monadic.KatipContext m, Katip.Core.Katip (Control.Monad.Trans.Either.EitherT e m)) => Katip.Monadic.KatipContext (Control.Monad.Trans.Either.EitherT e m)
+ Katip.Monadic: instance (Katip.Monadic.KatipContext m, Katip.Core.Katip (Control.Monad.Trans.Except.ExceptT s m)) => Katip.Monadic.KatipContext (Control.Monad.Trans.Except.ExceptT s m)
+ Katip.Monadic: instance (Katip.Monadic.KatipContext m, Katip.Core.Katip (Control.Monad.Trans.Identity.IdentityT m)) => Katip.Monadic.KatipContext (Control.Monad.Trans.Identity.IdentityT m)
+ Katip.Monadic: instance (Katip.Monadic.KatipContext m, Katip.Core.Katip (Control.Monad.Trans.List.ListT m)) => Katip.Monadic.KatipContext (Control.Monad.Trans.List.ListT m)
+ Katip.Monadic: instance (Katip.Monadic.KatipContext m, Katip.Core.Katip (Control.Monad.Trans.Maybe.MaybeT m)) => Katip.Monadic.KatipContext (Control.Monad.Trans.Maybe.MaybeT m)
+ Katip.Monadic: instance (Katip.Monadic.KatipContext m, Katip.Core.Katip (Control.Monad.Trans.Reader.ReaderT r m)) => Katip.Monadic.KatipContext (Control.Monad.Trans.Reader.ReaderT r m)
+ Katip.Monadic: instance (Katip.Monadic.KatipContext m, Katip.Core.Katip (Control.Monad.Trans.Resource.Internal.ResourceT m)) => Katip.Monadic.KatipContext (Control.Monad.Trans.Resource.Internal.ResourceT m)
+ Katip.Monadic: instance (Katip.Monadic.KatipContext m, Katip.Core.Katip (Control.Monad.Trans.State.Lazy.StateT s m)) => Katip.Monadic.KatipContext (Control.Monad.Trans.State.Lazy.StateT s m)
+ Katip.Monadic: instance (Katip.Monadic.KatipContext m, Katip.Core.Katip (Control.Monad.Trans.State.Strict.StateT s m)) => Katip.Monadic.KatipContext (Control.Monad.Trans.State.Strict.StateT s m)
+ Katip.Monadic: instance Control.Monad.Base.MonadBase b m => Control.Monad.Base.MonadBase b (Katip.Monadic.KatipContextT m)
+ Katip.Monadic: instance Control.Monad.Catch.MonadCatch m => Control.Monad.Catch.MonadCatch (Katip.Monadic.KatipContextT m)
+ Katip.Monadic: instance Control.Monad.Catch.MonadMask m => Control.Monad.Catch.MonadMask (Katip.Monadic.KatipContextT m)
+ Katip.Monadic: instance Control.Monad.Catch.MonadThrow m => Control.Monad.Catch.MonadThrow (Katip.Monadic.KatipContextT m)
+ Katip.Monadic: instance Control.Monad.Error.Class.MonadError e m => Control.Monad.Error.Class.MonadError e (Katip.Monadic.KatipContextT m)
+ Katip.Monadic: instance Control.Monad.Fix.MonadFix m => Control.Monad.Fix.MonadFix (Katip.Monadic.KatipContextT m)
+ Katip.Monadic: instance Control.Monad.IO.Class.MonadIO m => Control.Monad.IO.Class.MonadIO (Katip.Monadic.KatipContextT m)
+ Katip.Monadic: instance Control.Monad.IO.Class.MonadIO m => Katip.Core.Katip (Katip.Monadic.KatipContextT m)
+ Katip.Monadic: instance Control.Monad.IO.Class.MonadIO m => Katip.Monadic.KatipContext (Katip.Monadic.KatipContextT m)
+ Katip.Monadic: instance Control.Monad.Reader.Class.MonadReader r m => Control.Monad.Reader.Class.MonadReader r (Katip.Monadic.KatipContextT m)
+ Katip.Monadic: instance Control.Monad.State.Class.MonadState s m => Control.Monad.State.Class.MonadState s (Katip.Monadic.KatipContextT m)
+ Katip.Monadic: instance Control.Monad.Trans.Class.MonadTrans Katip.Monadic.KatipContextT
+ Katip.Monadic: instance Control.Monad.Trans.Control.MonadBaseControl b m => Control.Monad.Trans.Control.MonadBaseControl b (Katip.Monadic.KatipContextT m)
+ Katip.Monadic: instance Control.Monad.Trans.Control.MonadTransControl Katip.Monadic.KatipContextT
+ Katip.Monadic: instance Control.Monad.Writer.Class.MonadWriter w m => Control.Monad.Writer.Class.MonadWriter w (Katip.Monadic.KatipContextT m)
+ Katip.Monadic: instance Data.Aeson.Types.Class.ToJSON Katip.Monadic.LogContexts
+ Katip.Monadic: instance GHC.Base.Alternative m => GHC.Base.Alternative (Katip.Monadic.KatipContextT m)
+ Katip.Monadic: instance GHC.Base.Applicative m => GHC.Base.Applicative (Katip.Monadic.KatipContextT m)
+ Katip.Monadic: instance GHC.Base.Functor m => GHC.Base.Functor (Katip.Monadic.KatipContextT m)
+ Katip.Monadic: instance GHC.Base.Monad m => GHC.Base.Monad (Katip.Monadic.KatipContextT m)
+ Katip.Monadic: instance GHC.Base.MonadPlus m => GHC.Base.MonadPlus (Katip.Monadic.KatipContextT m)
+ Katip.Monadic: instance GHC.Base.Monoid Katip.Monadic.LogContexts
+ Katip.Monadic: instance Katip.Core.LogItem Katip.Monadic.LogContexts
+ Katip.Monadic: instance Katip.Core.ToObject Katip.Monadic.LogContexts
+ Katip.Monadic: katipAddContext :: (LogItem i, Monad m) => i -> KatipContextT m a -> KatipContextT m a
+ Katip.Monadic: katipAddNamespace :: (Monad m) => Namespace -> KatipContextT m a -> KatipContextT m a
+ Katip.Monadic: logLocM :: (Applicative m, KatipContext m, Katip m) => Severity -> LogStr -> m ()
- Katip: itemApp :: Lens' (Item a_akrY) Namespace
+ Katip: itemApp :: Lens' (Item a_agYl) Namespace
- Katip: itemEnv :: Lens' (Item a_akrY) Environment
+ Katip: itemEnv :: Lens' (Item a_agYl) Environment
- Katip: itemHost :: Lens' (Item a_akrY) HostName
+ Katip: itemHost :: Lens' (Item a_agYl) HostName
- Katip: itemLoc :: Lens' (Item a_akrY) (Maybe Loc)
+ Katip: itemLoc :: Lens' (Item a_agYl) (Maybe Loc)
- Katip: itemMessage :: Lens' (Item a_akrY) LogStr
+ Katip: itemMessage :: Lens' (Item a_agYl) LogStr
- Katip: itemNamespace :: Lens' (Item a_akrY) Namespace
+ Katip: itemNamespace :: Lens' (Item a_agYl) Namespace
- Katip: itemPayload :: Lens (Item a_akrY) (Item a_aoxY) a_akrY a_aoxY
+ Katip: itemPayload :: Lens (Item a_agYl) (Item a_an5P) a_agYl a_an5P
- Katip: itemProcess :: Lens' (Item a_akrY) ProcessID
+ Katip: itemProcess :: Lens' (Item a_agYl) ProcessID
- Katip: itemSeverity :: Lens' (Item a_akrY) Severity
+ Katip: itemSeverity :: Lens' (Item a_agYl) Severity
- Katip: itemThread :: Lens' (Item a_akrY) ThreadIdText
+ Katip: itemThread :: Lens' (Item a_agYl) ThreadIdText
- Katip: itemTime :: Lens' (Item a_akrY) UTCTime
+ Katip: itemTime :: Lens' (Item a_agYl) UTCTime
- Katip: liftPayload :: LogItem a => a -> LogContexts
+ Katip: liftPayload :: (LogItem a) => a -> LogContexts
- Katip: runKatipContextT :: LogItem c => LogEnv -> c -> Namespace -> KatipContextT m a -> m a
+ Katip: runKatipContextT :: (LogItem c) => LogEnv -> c -> Namespace -> KatipContextT m a -> m a
- Katip.Core: getLoc :: Q Exp
+ Katip.Core: getLoc :: (?loc :: CallStack) => Maybe Loc
- Katip.Core: itemApp :: Lens' (Item a_akrY) Namespace
+ Katip.Core: itemApp :: Lens' (Item a_agYl) Namespace
- Katip.Core: itemEnv :: Lens' (Item a_akrY) Environment
+ Katip.Core: itemEnv :: Lens' (Item a_agYl) Environment
- Katip.Core: itemHost :: Lens' (Item a_akrY) HostName
+ Katip.Core: itemHost :: Lens' (Item a_agYl) HostName
- Katip.Core: itemLoc :: Lens' (Item a_akrY) (Maybe Loc)
+ Katip.Core: itemLoc :: Lens' (Item a_agYl) (Maybe Loc)
- Katip.Core: itemMessage :: Lens' (Item a_akrY) LogStr
+ Katip.Core: itemMessage :: Lens' (Item a_agYl) LogStr
- Katip.Core: itemNamespace :: Lens' (Item a_akrY) Namespace
+ Katip.Core: itemNamespace :: Lens' (Item a_agYl) Namespace
- Katip.Core: itemPayload :: Lens (Item a_akrY) (Item a_aoxY) a_akrY a_aoxY
+ Katip.Core: itemPayload :: Lens (Item a_agYl) (Item a_an5P) a_agYl a_an5P
- Katip.Core: itemProcess :: Lens' (Item a_akrY) ProcessID
+ Katip.Core: itemProcess :: Lens' (Item a_agYl) ProcessID
- Katip.Core: itemSeverity :: Lens' (Item a_akrY) Severity
+ Katip.Core: itemSeverity :: Lens' (Item a_agYl) Severity
- Katip.Core: itemThread :: Lens' (Item a_akrY) ThreadIdText
+ Katip.Core: itemThread :: Lens' (Item a_agYl) ThreadIdText
- Katip.Core: itemTime :: Lens' (Item a_akrY) UTCTime
+ Katip.Core: itemTime :: Lens' (Item a_agYl) UTCTime
- Katip.Monadic: liftPayload :: LogItem a => a -> LogContexts
+ Katip.Monadic: liftPayload :: (LogItem a) => a -> LogContexts
- Katip.Monadic: runKatipContextT :: LogItem c => LogEnv -> c -> Namespace -> KatipContextT m a -> m a
+ Katip.Monadic: runKatipContextT :: (LogItem c) => LogEnv -> c -> Namespace -> KatipContextT m a -> m a

Files

README.md view
@@ -2,7 +2,7 @@  Katip is a structured logging framework for Haskell. -![Katip](./katip.jpg)+![Katip](https://github.com/Soostone/katip/blob/master/katip/katip.jpg)  Kâtip (pronounced kah-tip) is the Turkish word for scribe. @@ -69,8 +69,11 @@   ## Examples-Be sure to look in the [examples](./examples) directory for some examples of how-to integrate Katip into your own stack.++Be sure to look in the+[examples](https://github.com/Soostone/katip/blob/master/katip/examples)+directory for some examples of how to integrate Katip into your own+stack.   ## Contributors
changelog.md view
@@ -1,3 +1,20 @@+0.2.0.0+=======++* Add GHC implicit callstack support, add logLoc.+* Drop lens in favor of type-compatible, lighter microlens.+* Renamed `logEnvNs` to clearer `logEnvApp`+* Added `katipAddNamespace` and `katipAddContext`+* Fixed nested objects not rendering in Handle scribe.+* LogContexts Monoid instance is now right-biased rather than left+  biased. This better fits the use case. For instance `ctx1 <> ctx2`+  will prefer keys in `ctx2` if there are conflicts. This makes the+  most sense because functions like `katipAddContext` will `mappend`+  on the right side.+* LogContext internally uses a `Seq` instead of a list for better+  complexity on context add.+* Improved documentation.+ 0.1.1.0 ============== 
examples/example.hs view
@@ -9,6 +9,7 @@   -------------------------------------------------------------------------------+import qualified Control.Applicative  as A import           Control.Monad.Reader import           Data.Aeson import           Data.Monoid          as M@@ -22,7 +23,7 @@ -- lens_example for a slightly cleaner and more general pattern. main :: IO () main = do-  le <- initLogEnv "main" "production"+  le <- initLogEnv "MyApp" "production"   -- We'll set up a scribe that logs to stdout and will only log item   -- fields permitted for Verbosity 2 and will throw out Debug   -- messages entirely. Note that katip provides facilities like@@ -77,7 +78,7 @@ ------------------------------------------------------------------------------- newtype MyStack m a = MyStack {       unStack :: ReaderT MyState m a-    } deriving (MonadReader MyState, Functor, Applicative, Monad, MonadIO)+    } deriving (MonadReader MyState, Functor, A.Applicative, Monad, MonadIO)   instance (MonadIO m) => Katip (MyStack m) where
examples/example_lens.hs view
@@ -9,6 +9,7 @@   -------------------------------------------------------------------------------+import           Control.Applicative  as A import           Control.Lens         hiding ((.=)) import           Control.Monad.Reader import           Data.Aeson@@ -38,7 +39,7 @@ -- lens_example for a slightly cleaner and more general pattern. main :: IO () main = do-  le <- initLogEnv "main" "production"+  le <- initLogEnv "MyApp" "production"   -- We'll set up a scribe that logs to stdout and will only log item   -- fields permitted for Verbosity 2 and will throw out Debug   -- messages entirely. Note that katip provides facilities like@@ -85,7 +86,7 @@ ------------------------------------------------------------------------------- newtype MyStack m a = MyStack {       unStack :: ReaderT MyState m a-    } deriving (MonadReader MyState, Functor, Applicative, Monad, MonadIO)+    } deriving (MonadReader MyState, Functor, A.Applicative, Monad, MonadIO)   instance (MonadIO m) => Katip (MyStack m) where
katip.cabal view
@@ -1,5 +1,5 @@ name:                katip-version:             0.1.1.0+version:             0.2.0.0 synopsis:            A structured logging framework. description:   Katip is a structured logging framework. See README.md for more details.@@ -10,6 +10,8 @@ maintainer:          ozgun.ataman@soostone.com copyright:           Soostone Inc, 2015-2016 category:            Data, Text, Logging+homepage:            https://github.com/Soostone/katip+bug-reports:         https://github.com/Soostone/katip/issues build-type:          Simple cabal-version:       >=1.10 extra-source-files:@@ -21,7 +23,12 @@   test/Main.hs   test/Katip/Tests.hs   test/Katip/Tests/Scribes/Handle.hs+tested-with: GHC == 7.8.4, GHC== 7.10.3 +source-repository head+  type:     git+  location: https://github.com/Soostone/katip.git+ flag lib-Werror   default: False   manual: True@@ -51,22 +58,22 @@                , either >= 4 && < 4.5                , exceptions >= 0.5 && < 0.9                , hostname >=1.0 && <1.1-               , lens >= 4.4 && <4.14-               , lens-aeson < 1.1                , old-locale >= 1.0 && < 1.1                , string-conv >= 0.1 && < 0.2                , template-haskell >= 2.8 && < 2.11                , text >= 0.11 && <1.3                , time >= 1 && < 1.6                , time-locale-compat >= 0.1.0.1 && < 0.2-               , transformers >= 0.3 && < 0.5+               , transformers >= 0.3 && < 0.6                , transformers-compat                , unix >= 2.5 && < 2.8                , unordered-containers >= 0.2 && < 0.3                , monad-control >= 1.0 && < 1.1-               , mtl >= 2.2 && < 2.3-               , transformers-base >= 0.4.1 && < 0.5+               , mtl >= 2.0 && < 2.3+               , transformers-base >= 0.3 && < 0.5                , resourcet >= 1.1 && < 1.2+               , microlens >= 0.2.0.0 && < 0.5+               , microlens-th >= 0.1.0.0 && < 0.5    hs-source-dirs:      src   default-language:    Haskell2010@@ -92,6 +99,7 @@                , temporary                , directory                , regex-tdfa-rc+               , unordered-containers   benchmark bench
src/Katip.hs view
@@ -26,17 +26,22 @@     (      -- * Framework Types--      Katip (..)-    , Namespace (..)+      Namespace (..)     , Environment (..)     , Severity (..)     , renderSeverity-    , severityText+    , textToSeverity     , Verbosity (..)     , ToObject (..)     , LogItem (..)     , Item(..)+    , ThreadIdText(..)+    , PayloadSelection (..)+    , Scribe (..)+    , LogEnv (..)+    , SimpleLogPayload, sl++    -- ** @lens@-compatible Lenses     , itemApp     , itemEnv     , itemSeverity@@ -48,20 +53,12 @@     , itemTime     , itemNamespace     , itemLoc-    , ThreadIdText(..)-    , PayloadSelection (..)-    , Scribe (..)-    , LogEnv (..)     , logEnvHost     , logEnvPid-    , logEnvNs+    , logEnvApp     , logEnvEnv     , logEnvTimer     , logEnvScribes-    , KatipContext(..)-    , AnyLogContext-    , LogContexts, liftPayload-    , SimpleLogPayload, sl      -- * A Built-in Monad For Logging     , KatipT (..)@@ -77,15 +74,23 @@     , LogStr (..)     , logStr, ls, showLS +    -- ** 'Katip' LoggingFunctions+    -- $katiplogging+    , Katip (..)     , logF     , logMsg     , logT     , logItem     , logException+    -- ** 'KatipContext' Logging Functions+    -- $katipcontextlogging+    , KatipContext (..)     , logFM     , logTM     , logItemM     , logExceptionM+    , AnyLogContext+    , LogContexts, liftPayload      -- * Included Scribes     , mkHandleScribe@@ -99,6 +104,8 @@     -- * KatipContextT - Utility transformer that provides Katip and KatipContext instances     , KatipContextT     , runKatipContextT+    , katipAddNamespace+    , katipAddContext     ) where  -------------------------------------------------------------------------------@@ -106,3 +113,91 @@ import           Katip.Monadic import           Katip.Scribes.Handle -------------------------------------------------------------------------------+++{- $katiplogging++   These logging functions use the basic 'Katip' constraint and thus+will require varying degrees of explicit detail such as 'Namespace'+and individual log items to be passed in. These can be described as+the primitives of Katip logging. If you find yourself making multiple+log statements within a logical logging context for your app, you may+want to look into the 'KatipContext' family of logging functions like+'logFM' and 'logTM'. 'KatipContext' in most applications should be+considered the default. Here's an example of the pain point:++@+doDatabaseThings = do+  connId <- getConnectionId+  logF (ConnectionIDContext connId) "database" InfoS "Doing database stuff"+  \-\- ...+  logF (ConnectionIDContext connId) "database" InfoS "Wow, passing in the same context is getting tedious"+@++Another pain point to look out for is nesting actions that log in+eachother. Let's say you were writing a web app. You want to capture+some detail such as the user's ID in the logs, but you also want that+info to show up in doDatabaseThings' logs so you can associate those+two pieces of information:+++@+webRequestHandler = do+  uid <- getUserId+  logF (UserIDContext uid) "web" InfoS "Starting web request"+  doDatabaseThings+@++In the above example, doDatabaseThings would overwrite that+UderIDContext with its own context and namespace. Sometimes this is+what you want and that's why 'logF' and other functions which only+require 'Katip' exist. If you are interested in combining log+contexts and namespaces, see 'KatipContext'.+-}+++{- $katipcontextlogging++  These logging functions use the 'KatipContext' constraint which is a+superclass of 'Katip' that also has a mechanism for keeping track of+the current context and namespace. This means a few things:++1. Functions that use 'KatipContext' like 'logFM' and 'logTM' do not+require you to pass in 'LogItem's or 'Namespaces', they pull them from+the monadic environment.++2. It becomes easy to add functions which add namespaces and/or+contexts to the current stack of them. You can (and should) make that+action scoped to a monadic action so that when it finishes, the+previous context and namespace will be automatically restored.+++'KatipContextT' provides a simple, 'ReaderT'-based implementation of+the 'KatipContext' typeclass, and provides 'katipAddContext' and+'katipAddNamespace' functions to append to the context for the+duration of a block:+++@+main = do+  le <- initLogEnv "MyApp" "production"+  \-\- set up scribes here+  runKatipContext le () "main" $ do+    katipAddNamespace "nextlevel" $ do+      $(logTM) InfoS "Logs here will have namespace MyApp.main.nextlevel"++    katipAddContext TrivialContext $ do+      $(logTM) InfoS "Logs here will have context from TrivialContext"++      katipAddContext AnotherContext $ do+        $(logTM) InfoS "Logs here will have context from TrivialContext *merged with* context from AnotherContext!"++    $(logTM) InfoS "Log context restored to () and namespace to MyApp.main"+@++'katipAddNamespace' and 'katipAddContext' are one-liners, implemented+in terms of 'local' from 'MonadReader'. If you have a custom monad+transformer stack and want to add your own version of these, check out+<https://github.com/Soostone/katip/tree/master/katip/examples these+examples>.+-}
src/Katip/Core.hs view
@@ -1,9 +1,11 @@+{-# LANGUAGE CPP                        #-} {-# LANGUAGE DeriveFunctor              #-} {-# LANGUAGE DeriveGeneric              #-} {-# LANGUAGE ExistentialQuantification  #-} {-# LANGUAGE FlexibleContexts           #-} {-# LANGUAGE FlexibleInstances          #-} {-# LANGUAGE GeneralizedNewtypeDeriving #-}+{-# LANGUAGE ImplicitParams             #-} {-# LANGUAGE MultiParamTypeClasses      #-} {-# LANGUAGE OverloadedStrings          #-} {-# LANGUAGE RankNTypes                 #-}@@ -11,13 +13,14 @@ {-# LANGUAGE TemplateHaskell            #-} {-# LANGUAGE TypeFamilies               #-} {-# LANGUAGE UndecidableInstances       #-}+-- | This module is not meant to be imported directly and may contain+-- internal mechanisms that will change without notice. module Katip.Core where  ------------------------------------------------------------------------------- import           Control.Applicative          as A import           Control.AutoUpdate import           Control.Concurrent-import           Control.Lens import           Control.Monad.Base import           Control.Monad.Catch import           Control.Monad.IO.Class@@ -45,13 +48,26 @@ import qualified Data.Text.Lazy.Builder       as B import           Data.Time import           GHC.Generics                 hiding (to)+#if MIN_VERSION_base(4, 8, 0)+import           GHC.SrcLoc+import           GHC.Stack+#endif import           Language.Haskell.TH import qualified Language.Haskell.TH.Syntax   as TH+import           Lens.Micro+import           Lens.Micro.TH import           Network.HostName import           System.Posix -------------------------------------------------------------------------------  +readMay :: Read a => String -> Maybe a+readMay s = case [x | (x,t) <- reads s, ("","") <- lex t] of+              [x] -> Just x+              [] -> Nothing -- no parse+              _ -> Nothing -- Ambiguous parse++ ------------------------------------------------------------------------------- -- | Represents a heirarchy of namespaces going from general to -- specific. For instance: ["processname", "subsystem"]. Note that@@ -116,27 +132,25 @@   --------------------------------------------------------------------------------severityText :: Prism' Text Severity-severityText = prism renderSeverity toSev-  where-    toSev "Debug"     = Right DebugS-    toSev "Info"      = Right InfoS-    toSev "Notice"    = Right NoticeS-    toSev "Warning"   = Right WarningS-    toSev "Error"     = Right ErrorS-    toSev "Critical"  = Right CriticalS-    toSev "Alert"     = Right AlertS-    toSev "Emergency" = Right EmergencyS-    toSev x           = Left x+textToSeverity :: Text -> Maybe Severity+textToSeverity "Debug"     = Just DebugS+textToSeverity "Info"      = Just InfoS+textToSeverity "Notice"    = Just NoticeS+textToSeverity "Warning"   = Just WarningS+textToSeverity "Error"     = Just ErrorS+textToSeverity "Critical"  = Just CriticalS+textToSeverity "Alert"     = Just AlertS+textToSeverity "Emergency" = Just EmergencyS+textToSeverity _           = Nothing -instance ToJSON Severity where-    toJSON s = A.String (s ^. re severityText) +instance ToJSON Severity where+    toJSON s = A.String (renderSeverity s)  instance FromJSON Severity where     parseJSON = A.withText "Severity" parseSeverity       where-        parseSeverity t = case t ^? severityText of+        parseSeverity t = case textToSeverity t of           Just x -> return x           Nothing -> fail $ "Invalid Severity " ++ toS t @@ -289,28 +303,27 @@           <*> (fmap getLocJs <$> o A..: "loc")  -processIDText :: Prism' Text ProcessID-processIDText = prism fromProcessID toProcessID-  where-    fromProcessID = toS . show-    toProcessID t = case toS t ^? _Show of-      Just i -> Right i-      Nothing -> Left t+processIDToText :: ProcessID -> Text+processIDToText = toS . show  +textToProcessID :: Text -> Maybe ProcessID+textToProcessID = readMay . toS++ newtype ProcessIDJs = ProcessIDJs {       getProcessIDJs :: ProcessID     }   instance ToJSON ProcessIDJs where-    toJSON (ProcessIDJs p) = A.String (p ^. re processIDText)+    toJSON (ProcessIDJs p) = A.String (processIDToText p)   instance FromJSON ProcessIDJs where     parseJSON = A.withText "ProcessID" parseProcessID       where-        parseProcessID t = case t ^? processIDText of+        parseProcessID t = case textToProcessID t of           Just p -> return $ ProcessIDJs p           Nothing -> fail $ "Invalid ProcessIDJs " ++ toS t @@ -320,6 +333,7 @@ data PayloadSelection     = AllKeys     | SomeKeys [Text]+    deriving (Show, Eq)  instance Monoid PayloadSelection where     mempty = SomeKeys []@@ -475,12 +489,18 @@ data LogEnv = LogEnv {       _logEnvHost    :: HostName     , _logEnvPid     :: ProcessID-    , _logEnvNs      :: Namespace+    , _logEnvApp     :: Namespace+    -- ^ Name of application. This will typically never change. This+    -- field gets prepended to the namespace of your individual log+    -- messages. For example, if your app is MyApp and you write a log+    -- using "logItem" and the namespace "WebServer", the final+    -- namespace will be "MyApp.WebServer"     , _logEnvEnv     :: Environment     , _logEnvTimer   :: IO UTCTime     -- ^ Action to fetch the timestamp. You can use something like     -- 'AutoUpdate' for high volume logs but note that this may cause-    -- some output forms to display logs out of order.+    -- some output forms to display logs out of order. Alternatively,+    -- you could just use 'getCurrentTime'.     , _logEnvScribes :: M.Map Text Scribe     } makeLenses ''LogEnv@@ -515,7 +535,7 @@     -> Scribe     -> LogEnv     -> LogEnv-registerScribe nm h = logEnvScribes . at nm .~ Just h+registerScribe nm h = logEnvScribes %~ M.insert nm h   -------------------------------------------------------------------------------@@ -526,7 +546,7 @@     -- ^ Name of the scribe     -> LogEnv     -> LogEnv-unregisterScribe nm = logEnvScribes . at nm .~ Nothing+unregisterScribe nm = logEnvScribes %~ M.delete nm   -------------------------------------------------------------------------------@@ -539,8 +559,16 @@   ---------------------------------------------------------------------------------- | Monads where katip logging actions can be performed-class MonadIO m =>  Katip m where+-- | Monads where katip logging actions can be performed. Katip is the+-- most basic logging monad. You will typically use this directly if+-- you either don't want to use namespaces/contexts heavily or if you+-- want to pass in specific contexts and/or namespaces at each log site.+--+-- For something more powerful, look at the docs for 'KatipContext',+-- which keeps a namespace and merged context. You can write simple+-- functions that add additional namespacing and merges additional+-- context on the fly.+class MonadIO m => Katip m where     getLogEnv :: m LogEnv  @@ -615,7 +643,7 @@     LogEnv{..} <- getLogEnv     liftIO $ do       item <- Item-        <$> pure _logEnvNs+        <$> pure _logEnvApp         <*> pure _logEnvEnv         <*> pure sev         <*> (mkThreadIdText <$> myThreadId)@@ -624,7 +652,7 @@         <*> pure a         <*> pure msg         <*> _logEnvTimer-        <*> pure (_logEnvNs <> ns)+        <*> pure (_logEnvApp <> ns)         <*> pure loc       FT.forM_ (M.elems _logEnvScribes) $ \ (Scribe h) -> h item @@ -712,17 +740,61 @@  ------------------------------------------------------------------------------- -- | For use when you want to include location in your logs. This will--- fill the 'Maybe Loc' gap in 'logF' of this module.-getLoc :: Q Exp-getLoc = [| $(location >>= liftLoc) |]+-- fill the 'Maybe Loc' gap in 'logF' of this module, and relies on implicit+-- callstacks when available (GHC > 7.8).+#if MIN_VERSION_base(4, 8, 0)+getLoc :: (?loc :: CallStack) => Maybe Loc+getLoc = case getCallStack ?loc of+  [] -> Nothing+  xs -> Just . toLoc . last $ xs+  where+    toLoc :: (String, SrcLoc) -> Loc+    toLoc (_, l) = Loc {+        loc_filename = srcLocFile l+      , loc_package  = srcLocPackage l+      , loc_module   = srcLocModule l+      , loc_start    = (srcLocStartLine l, srcLocStartCol l)+      , loc_end      = (srcLocEndLine   l, srcLocEndCol   l)+      }+#else+getLoc :: Maybe Loc+getLoc = Nothing+#endif   -------------------------------------------------------------------------------+-- Like `getLoc`, but uses template-haskell and works with older versions of+-- the compiler (GHC 7.8 or older).+getLocTH :: ExpQ+getLocTH = [| $(location >>= liftLoc) |]+++------------------------------------------------------------------------------- -- | 'Loc'-tagged logging when using template-haskell. -- -- @$(logT) obj mempty InfoS "Hello world"@ logT :: ExpQ-logT = [| \ a ns sev msg -> logItem a ns (Just $(getLoc)) sev msg |]+logT = [| \ a ns sev msg -> logItem a ns (Just $(getLocTH)) sev msg |]+++-------------------------------------------------------------------------------+-- | 'Loc'-tagged logging using implicit-callstacks when available.+--+-- This function does not require template-haskell as it+-- automatically uses <https://hackage.haskell.org/package/base-4.8.2.0/docs/GHC-Stack.html#v:getCallStack implicit-callstacks>+-- when the code is compiled using GHC > 7.8. Using an older version of the+-- compiler will result in the emission of a log line without any location information,+-- so be aware of it. Users using GHC <= 7.8 may want to use the template-haskell function+-- `logT` for maximum compatibility.+--+-- @logLoc obj mempty InfoS "Hello world"@+logLoc :: (Applicative m, LogItem a, Katip m)+       => a+       -> Namespace+       -> Severity+       -> LogStr+       -> m ()+logLoc a ns = logItem a ns getLoc   -- taken from the file-location package
src/Katip/Monadic.hs view
@@ -16,6 +16,7 @@     -- * Monadic variants of logging functions from "Katip.Core"       logFM     , logTM+    , logLocM     , logItemM     , logExceptionM @@ -28,6 +29,8 @@     -- * KatipContextT - Utility transformer that provides Katip and KatipContext instances     , KatipContextT(..)     , runKatipContextT+    , katipAddNamespace+    , katipAddContext     , KatipContextTState(..)     ) where @@ -53,8 +56,10 @@ import qualified Control.Monad.Trans.Writer.Strict as Strict (WriterT) import           Control.Monad.Writer import           Data.Aeson+import qualified Data.Foldable                     as FT import qualified Data.HashMap.Strict               as HM import           Data.Monoid                       as M+import           Data.Sequence                     as Seq import           Data.Text                         (Text) import           Language.Haskell.TH -------------------------------------------------------------------------------@@ -72,17 +77,29 @@ -- 'LogContext' instance for combining multiple payload policies. This -- is critical for log contexts deep down in a stack to be able to -- inject their own context without worrying about other context that--- has already been set.-newtype LogContexts = LogContexts [AnyLogContext] deriving (Monoid)+-- has already been set. Also note that contexts are treated as a+-- sequence and '<>' will be appended to the right hand side of the+-- sequence. If there are conflicting keys in the contexts, the /right+-- side will take precedence/, which is counter to how monoid works+-- for 'Map' and 'HashMap', so bear that in mind. The reasoning is+-- that if the user is /sequentially/ adding contexts to the right+-- side of the sequence, on conflict the intent is to overwrite with+-- the newer value (i.e. the rightmost value).+--+-- Additional note: you should not mappend LogContexts in any sort of+-- infinite loop, as it retains all data, so that would be a memory+-- leak.+newtype LogContexts = LogContexts (Seq AnyLogContext) deriving (Monoid)  instance ToJSON LogContexts where     toJSON (LogContexts cs) =-      Object $ mconcat $ map (\(AnyLogContext v) -> toObject v) cs+      -- flip mappend to get right-biased merge+      Object $ FT.foldr (flip mappend) mempty $ fmap (\(AnyLogContext v) -> toObject v) cs  instance ToObject LogContexts  instance LogItem LogContexts where-    payloadKeys verb (LogContexts vs) = mconcat $ map payloadKeys' vs+    payloadKeys verb (LogContexts vs) = FT.foldr (flip mappend) mempty $ fmap payloadKeys' vs       where         -- To ensure AllKeys doesn't leak keys from other values when         -- combined, we resolve AllKeys to its equivalent SomeKeys@@ -96,7 +113,7 @@ -- | Lift a log context into the generic wrapper so that it can -- combine with the existing log context. liftPayload :: (LogItem a) => a -> LogContexts-liftPayload = LogContexts . (:[]) . AnyLogContext+liftPayload = LogContexts . Seq.singleton . AnyLogContext   -------------------------------------------------------------------------------@@ -171,12 +188,33 @@ -- | 'Loc'-tagged logging when using template-haskell. Automatically -- supplies payload and namespace. ----- @$(logt) InfoS "Hello world"@+-- @$(logTM) InfoS "Hello world"@ logTM :: ExpQ-logTM = [| logItemM (Just $(getLoc)) |]+logTM = [| logItemM (Just $(getLocTH)) |]   -------------------------------------------------------------------------------+-- | 'Loc'-tagged logging when using template-haskell. Automatically+-- supplies payload and namespace.+--+-- Same consideration as `logLoc` applies.+--+-- This function does not require template-haskell as it+-- automatically uses <https://hackage.haskell.org/package/base-4.8.2.0/docs/GHC-Stack.html#v:getCallStack implicit-callstacks>+-- when the code is compiled using GHC > 7.8. Using an older version of the+-- compiler will result in the emission of a log line without any location information,+-- so be aware of it. Users using GHC <= 7.8 may want to use the template-haskell function+-- `logTM` for maximum compatibility.+--+-- @logLocM InfoS "Hello world"@+logLocM :: (Applicative m, KatipContext m, Katip m)+        => Severity+        -> LogStr+        -> m ()+logLocM = logItemM getLoc+++------------------------------------------------------------------------------- -- | Perform an action while logging any exceptions that may occur. -- Inspired by 'onException`. --@@ -270,3 +308,25 @@ runKatipContextT le ctx ns = flip runReaderT lts . unKatipContextT   where     lts = KatipContextTState le (liftPayload ctx) ns+++-------------------------------------------------------------------------------+katipAddNamespace+    :: (Monad m)+    => Namespace+    -> KatipContextT m a+    -> KatipContextT m a+katipAddNamespace ns (KatipContextT f) =+  KatipContextT (local (\r -> r { ltsNamespace = (ltsNamespace r) <> ns}) f)+++-------------------------------------------------------------------------------+katipAddContext+    :: ( LogItem i+       , Monad m+       )+    => i+    -> KatipContextT m a+    -> KatipContextT m a+katipAddContext i (KatipContextT f) =+  KatipContextT (local (\r -> r { ltsContext = (ltsContext r) <> liftPayload i}) f)
src/Katip/Scribes/Handle.hs view
@@ -3,11 +3,12 @@ module Katip.Scribes.Handle where  --------------------------------------------------------------------------------import           Control.Lens+import           Control.Applicative     as A import           Control.Monad-import           Data.Aeson.Lens+import           Data.Aeson import qualified Data.HashMap.Strict     as HM import           Data.Monoid+import Data.Text (Text) import           Data.Text.Lazy.Builder import           Data.Text.Lazy.IO       as T import           Data.Time@@ -26,18 +27,17 @@  ------------------------------------------------------------------------------- getKeys :: LogItem s => Verbosity -> s -> [Builder]-getKeys verb a = payloadObject verb a ^..-              to HM.toList . traverse . to rendPair+getKeys verb a = concat (renderPair A.<$> HM.toList (payloadObject verb a))   where-    rendPair (k,v) = fromText k <> fromText ":" <> (v ^. _Primitive . to renderPrim)-----------------------------------------------------------------------------------renderPrim :: Primitive -> Builder-renderPrim (StringPrim t) = fromText t-renderPrim (NumberPrim s) = fromString (show s)-renderPrim (BoolPrim b) = fromString (show b)-renderPrim NullPrim = fromText "null"+    renderPair :: (Text, Value) -> [Builder]+    renderPair (k,v) =+      case v of+        Object o -> concat [renderPair (k <> "." <> k', v')  | (k', v') <- HM.toList o]+        String t -> [fromText (k <> ":" <> t)]+        Number n -> [fromText (k <> ":") <> fromString (show n)]+        Bool b -> [fromText (k <> ":") <> fromString (show b)]+        Null -> [fromText (k <> ":null")]+        _ -> mempty -- Can't think of a sensible way to handle arrays   -------------------------------------------------------------------------------
test/Katip/Tests.hs view
@@ -1,4 +1,7 @@+{-# LANGUAGE CPP                        #-} {-# LANGUAGE GeneralizedNewtypeDeriving #-}+{-# LANGUAGE OverloadedStrings          #-}+{-# LANGUAGE RecordWildCards            #-} {-# LANGUAGE ScopedTypeVariables        #-} {-# LANGUAGE StandaloneDeriving         #-} {-# OPTIONS_GHC -fno-warn-orphans #-}@@ -10,6 +13,9 @@ ------------------------------------------------------------------------------- import           Control.Applicative import           Data.Aeson+import qualified Data.HashMap.Strict       as HM+import           Data.Monoid+import           Data.Text                 (Text) import qualified Data.Text.Lazy.Builder    as B import           Data.Time import           Data.Time.Clock.POSIX@@ -17,9 +23,11 @@ import           System.Posix.Types import           Test.QuickCheck.Instances () import           Test.Tasty+import           Test.Tasty.HUnit import           Test.Tasty.QuickCheck ------------------------------------------------------------------------------- import           Katip+import           Katip.Core -------------------------------------------------------------------------------  @@ -27,11 +35,57 @@ tests = testGroup "Katip"   [     testProperty "JSON cycle Item" $ \(i :: Item ()) ->-       prop_json_cycle i+      prop_json_cycle i+  , testProperty "renderSeverity/textToSeverity cycle" $ \sev ->+      textToSeverity(renderSeverity sev) === Just sev+  , testProperty "processIDToText/textToProcessID cycle" $ \pid ->+      textToProcessID (processIDToText pid) === Just pid+  , testCase "processIDToText is just the number" $ do+      processIDToText 123 @?= "123"+  , logContextsTests   ]   -------------------------------------------------------------------------------+logContextsTests :: TestTree+logContextsTests = testGroup "logContexts"+  [+    testCase "overwrites with the right-hand side (right-bias)" $ do+      let l1 = liftPayload (SimpleLogPayload [("foo", AnyLogPayload ("a" :: Text))])+          l2 = liftPayload (SimpleLogPayload [("foo", AnyLogPayload ("b" :: Text))])+          l3 = liftPayload (SimpleLogPayload [("foo", AnyLogPayload ("c" :: Text))])+          both = l1 <> l2 <> l3+      toObject both @?= HM.singleton "foo" (String "c")+  , testCase "respects payloadKeys for each constituent payload" $ do+      let everything = liftPayload (SimpleLogPayload [("foo", AnyLogPayload ("a" :: Text))])+          conservative = liftPayload (ConservativePayload "always" "rarely")+          both = everything <> conservative+      payloadKeys V2 both @?= SomeKeys ["often_shown", "rarely_shown", "foo"]+      payloadKeys V1 both @?= SomeKeys ["often_shown", "foo"]+  ]+++-------------------------------------------------------------------------------+data ConservativePayload = ConservativePayload {+      oftenShown  :: Text+    , rarelyShown :: Text+    }+++instance ToJSON ConservativePayload where+  toJSON ConservativePayload {..} = object ["often_shown" .= oftenShown+                                           ,"rarely_shown" .= rarelyShown]+++instance ToObject ConservativePayload+++instance LogItem ConservativePayload where+  payloadKeys V1 _ = SomeKeys ["often_shown"]+  payloadKeys V0 _ = SomeKeys []+  payloadKeys _ _  = AllKeys++------------------------------------------------------------------------------- prop_json_cycle :: (ToJSON a, FromJSON a, Eq a, Show a) => a -> Property prop_json_cycle a = eitherDecode (encode a) === Right a @@ -69,6 +123,9 @@ deriving instance Arbitrary Environment deriving instance Arbitrary ThreadIdText deriving instance Arbitrary CPid+#if !MIN_VERSION_base(4, 8, 0)+deriving instance Eq Loc+#endif deriving instance Eq LogStr deriving instance (Eq a) => Eq (Item a) 
test/Katip/Tests/Scribes/Handle.hs view
@@ -1,4 +1,4 @@-{-# LANGUAGE OverloadedStrings   #-}+{-# LANGUAGE OverloadedStrings #-} module Katip.Tests.Scribes.Handle     ( tests     ) where@@ -6,6 +6,7 @@ ------------------------------------------------------------------------------- import           Control.Monad import           Data.Aeson+import           Data.Monoid import           Data.Text        (Text) import qualified Data.Text.IO     as T import           System.Directory@@ -27,9 +28,9 @@        runKatipT le $ logItem dummyLogItem "test" Nothing InfoS "test message"        hClose h        res <- readFile path-       let pat = "\\[[[:digit:]]{4}-[[:digit:]]{2}-[[:digit:]]{2} [[:digit:]]{2}:[[:digit:]]{2}:[[:digit:]]{2}\\]\\[katip-test.test\\]\\[Info\\]\\[.+\\]\\[[[:digit:]]+\\]\\[ThreadId [[:digit:]]+\\]\\[note:some note\\] test message" :: String+       let pat = "\\[[[:digit:]]{4}-[[:digit:]]{2}-[[:digit:]]{2} [[:digit:]]{2}:[[:digit:]]{2}:[[:digit:]]{2}\\]\\[katip-test.test\\]\\[Info\\]\\[.+\\]\\[[[:digit:]]+\\]\\[ThreadId [[:digit:]]+\\]\\[note.deep:some note\\] test message" :: String        let matches = res =~ pat-       matches @?= True+       assertBool (res <> " did not match") matches   ]  @@ -40,7 +41,10 @@   instance ToJSON DummyLogItem where-  toJSON (DummyLogItem n) = object ["note" .= n]+  toJSON (DummyLogItem n) = object+    [ "note" .= object [ "deep" .= n+                       ]+    ]   instance ToObject DummyLogItem