-- Hoogle documentation, generated by Haddock
-- See Hoogle, http://www.haskell.org/hoogle/


-- | A structured logging framework.
--   
--   Katip is a structured logging framework. See README.md for more
--   details.
@package katip
@version 0.8.7.0


-- | This module is not meant to be imported directly and may contain
--   internal mechanisms that will change without notice.
module Katip.Core
readMay :: Read a => String -> Maybe a

-- | Represents a heirarchy of namespaces going from general to specific.
--   For instance: ["processname", "subsystem"]. Note that single-segment
--   namespaces can be created using IsString/OverloadedStrings, so "foo"
--   will result in Namespace ["foo"].
newtype Namespace
Namespace :: [Text] -> Namespace
[unNamespace] :: Namespace -> [Text]

-- | Ready namespace for emission with dots to join the segments.
intercalateNs :: Namespace -> [Text]

-- | Application environment, like <tt>prod</tt>, <tt>devel</tt>,
--   <tt>testing</tt>.
newtype Environment
Environment :: Text -> Environment
[getEnvironment] :: Environment -> Text
data Severity

-- | Debug messages
DebugS :: Severity

-- | Information
InfoS :: Severity

-- | Normal runtime Conditions
NoticeS :: Severity

-- | General Warnings
WarningS :: Severity

-- | General Errors
ErrorS :: Severity

-- | Severe situations
CriticalS :: Severity

-- | Take immediate action
AlertS :: Severity

-- | System is unusable
EmergencyS :: Severity

-- | Verbosity controls the amount of information (columns) a <a>Scribe</a>
--   emits during logging.
--   
--   The convention is: - <a>V0</a> implies no additional payload
--   information is included in message. - <a>V3</a> implies the maximum
--   amount of payload information. - Anything in between is left to the
--   discretion of the developer.
data Verbosity
V0 :: Verbosity
V1 :: Verbosity
V2 :: Verbosity
V3 :: Verbosity
renderSeverity :: Severity -> Text
textToSeverity :: Text -> Maybe Severity

-- | Log message with Builder underneath; use <a>&lt;&gt;</a> to concat in
--   O(1).
newtype LogStr
LogStr :: Builder -> LogStr
[unLogStr] :: LogStr -> Builder

-- | Pack any string-like thing into a <a>LogStr</a>. This will
--   automatically work on <a>String</a>, <tt>ByteString</tt>, <a>Text</a>
--   and any of the lazy variants.
logStr :: StringConv a Text => a -> LogStr

-- | Shorthand for <a>logStr</a>
ls :: StringConv a Text => a -> LogStr

-- | Convert any showable type into a <a>LogStr</a>.
showLS :: Show a => a -> LogStr
newtype ThreadIdText
ThreadIdText :: Text -> ThreadIdText
[getThreadIdText] :: ThreadIdText -> Text
mkThreadIdText :: ThreadId -> ThreadIdText

-- | This has everything each log message will contain.
data Item a
Item :: Namespace -> Environment -> Severity -> ThreadIdText -> HostName -> ProcessID -> a -> LogStr -> UTCTime -> Namespace -> Maybe Loc -> Item a
[_itemApp] :: Item a -> Namespace
[_itemEnv] :: Item a -> Environment
[_itemSeverity] :: Item a -> Severity
[_itemThread] :: Item a -> ThreadIdText
[_itemHost] :: Item a -> HostName
[_itemProcess] :: Item a -> ProcessID
[_itemPayload] :: Item a -> a
[_itemMessage] :: Item a -> LogStr
[_itemTime] :: Item a -> UTCTime
[_itemNamespace] :: Item a -> Namespace
[_itemLoc] :: Item a -> Maybe Loc
itemTime :: forall a_aciI. Lens' (Item a_aciI) UTCTime
itemThread :: forall a_aciI. Lens' (Item a_aciI) ThreadIdText
itemSeverity :: forall a_aciI. Lens' (Item a_aciI) Severity
itemProcess :: forall a_aciI. Lens' (Item a_aciI) ProcessID
itemPayload :: forall a_aciI a_ag6d. Lens (Item a_aciI) (Item a_ag6d) a_aciI a_ag6d
itemNamespace :: forall a_aciI. Lens' (Item a_aciI) Namespace
itemMessage :: forall a_aciI. Lens' (Item a_aciI) LogStr
itemLoc :: forall a_aciI. Lens' (Item a_aciI) (Maybe Loc)
itemHost :: forall a_aciI. Lens' (Item a_aciI) HostName
itemEnv :: forall a_aciI. Lens' (Item a_aciI) Environment
itemApp :: forall a_aciI. Lens' (Item a_aciI) Namespace
newtype LocShow
LocShow :: Loc -> LocShow
newtype LocJs
LocJs :: Loc -> LocJs
[getLocJs] :: LocJs -> Loc
processIDToText :: ProcessID -> Text
textToProcessID :: Text -> Maybe ProcessID
newtype ProcessIDJs
ProcessIDJs :: ProcessID -> ProcessIDJs
[getProcessIDJs] :: ProcessIDJs -> ProcessID

-- | Field selector by verbosity within JSON payload.
data PayloadSelection
AllKeys :: PayloadSelection
SomeKeys :: [Text] -> PayloadSelection

-- | Katip requires JSON objects to be logged as context. This typeclass
--   provides a default instance which uses ToJSON and produces an empty
--   object if <a>toJSON</a> results in any type other than object. If you
--   have a type you want to log that produces an Array or Number for
--   example, you'll want to write an explicit instance here. You can
--   trivially add a ToObject instance for something with a ToJSON instance
--   like:
--   
--   <pre>
--   instance ToObject Foo
--   </pre>
class ToObject a
toObject :: ToObject a => a -> Object
toObject :: (ToObject a, ToJSON a) => a -> Object

-- | Payload objects need instances of this class. LogItem makes it so that
--   you can have very verbose items getting logged with lots of extra
--   fields but under normal circumstances, if your scribe is configured
--   for a lower verbosity level, it will only log a selection of those
--   keys. Furthermore, each <a>Scribe</a> can be configured with a
--   different <a>Verbosity</a> level. You could even use
--   <a>registerScribe</a>, <a>unregisterScribe</a>, and
--   <a>clearScribes</a> to at runtime swap out your existing scribes for
--   more verbose debugging scribes if you wanted to.
--   
--   When defining <a>payloadKeys</a>, don't redundantly declare the same
--   keys for higher levels of verbosity. Each level of verbosity
--   automatically and recursively contains all keys from the level before
--   it.
class ToObject a => LogItem a

-- | List of keys in the JSON object that should be included in message.
payloadKeys :: LogItem a => Verbosity -> a -> PayloadSelection
data AnyLogPayload
AnyLogPayload :: a -> AnyLogPayload
newtype SimpleLogPayload
SimpleLogPayload :: [(Text, AnyLogPayload)] -> SimpleLogPayload
[unSimpleLogPayload] :: SimpleLogPayload -> [(Text, AnyLogPayload)]
toKey :: a -> a

-- | Construct a simple log from any JSON item.
sl :: ToJSON a => Text -> a -> SimpleLogPayload

-- | Constrain payload based on verbosity. Backends should use this to
--   automatically bubble higher verbosity levels to lower ones.
payloadObject :: LogItem a => Verbosity -> a -> Object
filterElems :: [Text] -> HashMap Text v -> HashMap Text v

-- | Convert log item to its JSON representation while trimming its payload
--   based on the desired verbosity. Backends that push JSON messages
--   should use this to obtain their payload.
itemJson :: LogItem a => Verbosity -> Item a -> Value

-- | Scribes are handlers of incoming items. Each registered scribe knows
--   how to push a log item somewhere.
--   
--   <h1>Guidelines for writing your own <a>Scribe</a></h1>
--   
--   Scribes should always take a <a>Severity</a> and <a>Verbosity</a>.
--   
--   Severity is used to <b>exclude log messages</b> that are lower than
--   the provided Severity. For instance, if the user passes InfoS, DebugS
--   items should be ignored. Katip provides the <a>permitItem</a> utility
--   for this. The user or the scribe may use <a>permitAND</a> and
--   <a>permitOR</a> to further customize this filtering, even dynamically
--   if they wish to.
--   
--   Verbosity is used to select keys from the log item's payload. Each
--   <a>LogItem</a> instance describes what keys should be retained for
--   each Verbosity level. Use the <a>payloadObject</a> utility for
--   extracting the keys that should be written.
--   
--   Scribes provide a finalizer IO action (<a>scribeFinalizer</a>) that is
--   meant to synchronously flush any remaining writes and clean up any
--   resources acquired when the scribe was created. Internally, katip
--   keeps a buffer for each scribe's writes. When <a>closeScribe</a> or
--   <a>closeScribes</a> is called, that buffer stops accepting new log
--   messages and after the last item in its buffer is sent to
--   <a>liPush</a>, calls the finalizer. Thus, when the finalizer returns,
--   katip can assume that all resources are cleaned up and all log
--   messages are durably written.
--   
--   While katip internally buffers messages per <a>ScribeSettings</a>, it
--   sends them one at a time to the scribe. Depending on the scribe
--   itself, it may make sense for that scribe to keep its own internal
--   buffer to batch-send logs if writing items one at a time is not
--   efficient. The scribe implementer must be sure that on finalization,
--   all writes are committed synchronously.
--   
--   Signature of a function passed to <a>Scribe</a> constructor and
--   mkScribe* functions that decides which messages to be logged.
--   Typically filters based on <a>Severity</a>, but can be combined with
--   other, custom logic with <a>permitAND</a> and <a>permitOR</a>
type PermitFunc = forall a. Item a -> IO Bool

-- | AND together 2 permit functions
permitAND :: PermitFunc -> PermitFunc -> PermitFunc

-- | OR together 2 permit functions
permitOR :: PermitFunc -> PermitFunc -> PermitFunc
data Scribe
Scribe :: (forall a. LogItem a => Item a -> IO ()) -> IO () -> PermitFunc -> Scribe

-- | How do we write an item to the scribe's output?
[liPush] :: Scribe -> forall a. LogItem a => Item a -> IO ()

-- | Provide a <b>blocking</b> finalizer to call when your scribe is
--   removed. All pending writes should be flushed synchronously. If this
--   is not relevant to your scribe, return () is fine.
[scribeFinalizer] :: Scribe -> IO ()

-- | Provide a filtering function to allow the item to be logged, or not.
--   It can check Severity or some string in item's body. The initial value
--   of this is usually created from <a>permitItem</a>. Scribes and users
--   can customize this by ANDing or ORing onto the default with
--   <a>permitAND</a> or <a>permitOR</a>
[scribePermitItem] :: Scribe -> PermitFunc
whenM :: Monad m => m Bool -> m () -> m ()
data ScribeHandle
ScribeHandle :: Scribe -> TBQueue WorkerMessage -> ScribeHandle
[shScribe] :: ScribeHandle -> Scribe
[shChan] :: ScribeHandle -> TBQueue WorkerMessage
data WorkerMessage
[NewItem] :: LogItem a => Item a -> WorkerMessage
[PoisonPill] :: WorkerMessage

-- | Should this item be logged given the user's maximum severity? Most new
--   scribes will use this as a base for their <a>PermitFunc</a>
permitItem :: Monad m => Severity -> Item a -> m Bool
data LogEnv
LogEnv :: HostName -> ProcessID -> Namespace -> Environment -> IO UTCTime -> Map Text ScribeHandle -> LogEnv
[_logEnvHost] :: LogEnv -> HostName
[_logEnvPid] :: LogEnv -> ProcessID

-- | 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 <a>WebServer</a>, the final namespace will be
--   <a>MyApp.WebServer</a>
[_logEnvApp] :: LogEnv -> Namespace
[_logEnvEnv] :: LogEnv -> Environment

-- | Action to fetch the timestamp. You can use something like
--   <tt>AutoUpdate</tt> for high volume logs but note that this may cause
--   some output forms to display logs out of order. Alternatively, you
--   could just use <a>getCurrentTime</a>.
[_logEnvTimer] :: LogEnv -> IO UTCTime
[_logEnvScribes] :: LogEnv -> Map Text ScribeHandle
logEnvTimer :: Lens' LogEnv (IO UTCTime)
logEnvScribes :: Lens' LogEnv (Map Text ScribeHandle)
logEnvPid :: Lens' LogEnv ProcessID
logEnvHost :: Lens' LogEnv HostName
logEnvEnv :: Lens' LogEnv Environment
logEnvApp :: Lens' LogEnv Namespace

-- | Create a reasonable default InitLogEnv. Uses an <tt>AutoUpdate</tt>
--   which updates the timer every 1ms. If you need even more timestamp
--   precision at the cost of performance, consider setting
--   <a>_logEnvTimer</a> with <a>getCurrentTime</a>.
initLogEnv :: Namespace -> Environment -> IO LogEnv

-- | Add a scribe to the list. All future log calls will go to this scribe
--   in addition to the others. Writes will be buffered per the
--   ScribeSettings to prevent slow scribes from slowing down logging.
--   Writes will be dropped if the buffer fills.
registerScribe :: Text -> Scribe -> ScribeSettings -> LogEnv -> IO LogEnv
spawnScribeWorker :: Scribe -> TBQueue WorkerMessage -> IO (Async ())
data ScribeSettings
ScribeSettings :: Int -> ScribeSettings
[_scribeBufferSize] :: ScribeSettings -> Int
scribeBufferSize :: Lens' ScribeSettings Int

-- | Reasonable defaults for a scribe. Buffer size of 4096.
defaultScribeSettings :: ScribeSettings

-- | Remove a scribe from the environment. This does <b>not</b> finalize
--   the scribe. This mainly only makes sense to use with something like
--   MonadReader's <tt>local</tt> function to temporarily disavow a single
--   logger for a block of code.
unregisterScribe :: Text -> LogEnv -> LogEnv

-- | Unregister <b>all</b> scribes. Note that this is <b>not</b> for
--   closing or finalizing scribes, use <a>closeScribes</a> for that. This
--   mainly only makes sense to use with something like MonadReader's
--   <tt>local</tt> function to temporarily disavow any loggers for a block
--   of code.
clearScribes :: LogEnv -> LogEnv

-- | Finalize a scribe. The scribe is removed from the environment, its
--   finalizer is called so that it can never be written to again and all
--   pending writes are flushed. Note that this will throw any exceptions
--   yoru finalizer will throw, and that LogEnv is immutable, so it will
--   not be removed in that case.
closeScribe :: Text -> LogEnv -> IO LogEnv

-- | Call this at the end of your program. This is a blocking call that
--   stop writing to a scribe's queue, waits for the queue to empty,
--   finalizes each scribe in the log environment and then removes it.
--   Finalizers are all run even if one of them throws, but the exception
--   will be re-thrown at the end.
closeScribes :: LogEnv -> IO LogEnv

-- | 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
--   <tt>KatipContext</tt>, which keeps a namespace and merged context. You
--   can write simple functions that add additional namespacing and merges
--   additional context on the fly.
--   
--   <a>localLogEnv</a> was added to allow for lexically-scoped
--   modifications of the log env that are reverted when the supplied monad
--   completes. <a>katipNoLogging</a>, for example, uses this to
--   temporarily pause log outputs.
class MonadIO m => Katip m
getLogEnv :: Katip m => m LogEnv
localLogEnv :: Katip m => (LogEnv -> LogEnv) -> m a -> m a

-- | A concrete monad you can use to run logging actions. Use this if you
--   prefer an explicit monad transformer stack and adding layers as
--   opposed to implementing <a>Katip</a> for your monad.
newtype KatipT m a
KatipT :: ReaderT LogEnv m a -> KatipT m a
[unKatipT] :: KatipT m a -> ReaderT LogEnv m a

-- | Execute <a>KatipT</a> on a log env.
runKatipT :: LogEnv -> KatipT m a -> m a

-- | Disable all scribes for the given monadic action, then restore them
--   afterwards. Works in any Katip monad.
katipNoLogging :: Katip m => m a -> m a

-- | Log with everything, including a source code location. This is very
--   low level and you typically can use <a>logT</a> in its place.
logItem :: (Applicative m, LogItem a, Katip m) => a -> Namespace -> Maybe Loc -> Severity -> LogStr -> m ()

-- | Log already constructed <a>Item</a>. This is the lowest level function
--   that other log* functions use. It can be useful when implementing
--   centralised logging services.
logKatipItem :: (Applicative m, LogItem a, Katip m) => Item a -> m ()
tryWriteTBQueue :: TBQueue a -> a -> STM Bool

-- | Log with full context, but without any code location.
logF :: (Applicative m, LogItem a, Katip m) => a -> Namespace -> Severity -> LogStr -> m ()

-- | Perform an action while logging any exceptions that may occur.
--   Inspired by <a>onException</a>.
--   
--   <pre>
--   &gt;&gt;&gt; &gt; logException () mempty ErrorS (error "foo")
--   </pre>
logException :: (Katip m, LogItem a, MonadCatch m, Applicative m) => a -> Namespace -> Severity -> m b -> m b

-- | Log a message without any payload/context or code location.
logMsg :: (Applicative m, Katip m) => Namespace -> Severity -> LogStr -> m ()

-- | Lift a location into an Exp.
liftLoc :: Loc -> Q Exp

-- | For use when you want to include location in your logs. This will fill
--   the 'Maybe Loc' gap in <a>logF</a> of this module, and relies on
--   implicit callstacks when available (GHC &gt; 7.8).
getLoc :: HasCallStack => Maybe Loc
getLocTH :: ExpQ

-- | <a>Loc</a>-tagged logging when using template-haskell.
--   
--   <pre>
--   $(logT) obj mempty InfoS "Hello world"
--   </pre>
logT :: ExpQ

-- | <a>Loc</a>-tagged logging using <a>Stack</a> when available.
--   
--   This function does not require template-haskell as it automatically
--   uses <a>implicit-callstacks</a> when the code is compiled using GHC
--   &gt; 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 &lt;= 7.8 may want to use the template-haskell
--   function <a>logT</a> for maximum compatibility.
--   
--   <pre>
--   logLoc obj mempty InfoS "Hello world"
--   </pre>
logLoc :: (Applicative m, LogItem a, Katip m, HasCallStack) => a -> Namespace -> Severity -> LogStr -> m ()
locationToString :: Loc -> String
instance Control.Monad.Base.MonadBase b m => Control.Monad.Base.MonadBase b (Katip.Core.KatipT m)
instance Control.Monad.Trans.Class.MonadTrans Katip.Core.KatipT
instance Control.Monad.Trans.Resource.Internal.MonadResource m => Control.Monad.Trans.Resource.Internal.MonadResource (Katip.Core.KatipT m)
instance Control.Monad.Catch.MonadThrow m => Control.Monad.Catch.MonadThrow (Katip.Core.KatipT m)
instance Control.Monad.Catch.MonadCatch m => Control.Monad.Catch.MonadCatch (Katip.Core.KatipT m)
instance Control.Monad.Catch.MonadMask m => Control.Monad.Catch.MonadMask (Katip.Core.KatipT m)
instance Control.Monad.IO.Class.MonadIO m => Control.Monad.IO.Class.MonadIO (Katip.Core.KatipT m)
instance GHC.Base.Monad m => GHC.Base.Monad (Katip.Core.KatipT m)
instance GHC.Base.Applicative m => GHC.Base.Applicative (Katip.Core.KatipT m)
instance GHC.Base.Functor m => GHC.Base.Functor (Katip.Core.KatipT m)
instance Control.Monad.IO.Class.MonadIO m => Katip.Core.Katip (Katip.Core.KatipT m)
instance Control.Monad.Trans.Control.MonadTransControl Katip.Core.KatipT
instance Control.Monad.Trans.Control.MonadBaseControl b m => Control.Monad.Trans.Control.MonadBaseControl b (Katip.Core.KatipT m)
instance Control.Monad.IO.Unlift.MonadUnliftIO m => Control.Monad.IO.Unlift.MonadUnliftIO (Katip.Core.KatipT m)
instance Control.Monad.Fail.MonadFail m => Control.Monad.Fail.MonadFail (Katip.Core.KatipT m)
instance Katip.Core.Katip m => Katip.Core.Katip (Control.Monad.Trans.Reader.ReaderT s m)
instance Katip.Core.Katip m => Katip.Core.Katip (Control.Monad.Trans.Except.ExceptT s m)
instance Katip.Core.Katip m => Katip.Core.Katip (Control.Monad.Trans.Maybe.MaybeT m)
instance Katip.Core.Katip m => Katip.Core.Katip (Control.Monad.Trans.State.Lazy.StateT s m)
instance (Katip.Core.Katip m, GHC.Base.Monoid w) => Katip.Core.Katip (Control.Monad.Trans.RWS.Lazy.RWST r w s m)
instance (Katip.Core.Katip m, GHC.Base.Monoid w) => Katip.Core.Katip (Control.Monad.Trans.RWS.Strict.RWST r w s m)
instance Katip.Core.Katip m => Katip.Core.Katip (Control.Monad.Trans.State.Strict.StateT s m)
instance (Katip.Core.Katip m, GHC.Base.Monoid s) => Katip.Core.Katip (Control.Monad.Trans.Writer.Lazy.WriterT s m)
instance (Katip.Core.Katip m, GHC.Base.Monoid s) => Katip.Core.Katip (Control.Monad.Trans.Writer.Strict.WriterT s m)
instance Katip.Core.Katip m => Katip.Core.Katip (Control.Monad.Trans.Resource.Internal.ResourceT m)
instance GHC.Classes.Eq Katip.Core.ScribeSettings
instance GHC.Show.Show Katip.Core.ScribeSettings
instance GHC.Classes.Eq Katip.Core.PayloadSelection
instance GHC.Show.Show Katip.Core.PayloadSelection
instance GHC.Base.Semigroup Katip.Core.Scribe
instance GHC.Base.Monoid Katip.Core.Scribe
instance Data.Aeson.Types.ToJSON.ToJSON Katip.Core.SimpleLogPayload
instance Katip.Core.ToObject Katip.Core.SimpleLogPayload
instance Katip.Core.LogItem Katip.Core.SimpleLogPayload
instance GHC.Base.Semigroup Katip.Core.SimpleLogPayload
instance GHC.Base.Monoid Katip.Core.SimpleLogPayload
instance Katip.Core.LogItem ()
instance Katip.Core.ToObject ()
instance Katip.Core.ToObject Data.Aeson.Types.Internal.Object
instance GHC.Base.Semigroup Katip.Core.PayloadSelection
instance GHC.Base.Monoid Katip.Core.PayloadSelection
instance Data.Aeson.Types.ToJSON.ToJSON a => Data.Aeson.Types.ToJSON.ToJSON (Katip.Core.Item a)
instance Data.Aeson.Types.FromJSON.FromJSON a => Data.Aeson.Types.FromJSON.FromJSON (Katip.Core.Item a)
instance Data.Aeson.Types.ToJSON.ToJSON Katip.Core.ProcessIDJs
instance Data.Aeson.Types.FromJSON.FromJSON Katip.Core.ProcessIDJs
instance Data.Aeson.Types.ToJSON.ToJSON Katip.Core.LocJs
instance Data.Aeson.Types.FromJSON.FromJSON Katip.Core.LocJs
instance GHC.Show.Show a => GHC.Show.Show (Katip.Core.Item a)
instance GHC.Show.Show Katip.Core.LocShow
instance GHC.Classes.Eq a => GHC.Classes.Eq (Katip.Core.Item a)
instance Language.Haskell.TH.Syntax.Lift Katip.Core.Namespace
instance GHC.Base.Monoid Katip.Core.Namespace
instance GHC.Base.Semigroup Katip.Core.Namespace
instance Data.Aeson.Types.FromJSON.FromJSON Katip.Core.Namespace
instance Data.Aeson.Types.ToJSON.ToJSON Katip.Core.Namespace
instance GHC.Generics.Generic Katip.Core.Namespace
instance GHC.Classes.Ord Katip.Core.Namespace
instance GHC.Read.Read Katip.Core.Namespace
instance GHC.Show.Show Katip.Core.Namespace
instance GHC.Classes.Eq Katip.Core.Namespace
instance Data.String.IsString Katip.Core.Environment
instance Data.Aeson.Types.FromJSON.FromJSON Katip.Core.Environment
instance Data.Aeson.Types.ToJSON.ToJSON Katip.Core.Environment
instance GHC.Generics.Generic Katip.Core.Environment
instance GHC.Classes.Ord Katip.Core.Environment
instance GHC.Read.Read Katip.Core.Environment
instance GHC.Show.Show Katip.Core.Environment
instance GHC.Classes.Eq Katip.Core.Environment
instance Language.Haskell.TH.Syntax.Lift Katip.Core.Severity
instance GHC.Enum.Bounded Katip.Core.Severity
instance GHC.Enum.Enum Katip.Core.Severity
instance GHC.Generics.Generic Katip.Core.Severity
instance GHC.Read.Read Katip.Core.Severity
instance GHC.Show.Show Katip.Core.Severity
instance GHC.Classes.Ord Katip.Core.Severity
instance GHC.Classes.Eq Katip.Core.Severity
instance Language.Haskell.TH.Syntax.Lift Katip.Core.Verbosity
instance GHC.Enum.Bounded Katip.Core.Verbosity
instance GHC.Enum.Enum Katip.Core.Verbosity
instance GHC.Generics.Generic Katip.Core.Verbosity
instance GHC.Read.Read Katip.Core.Verbosity
instance GHC.Show.Show Katip.Core.Verbosity
instance GHC.Classes.Ord Katip.Core.Verbosity
instance GHC.Classes.Eq Katip.Core.Verbosity
instance GHC.Classes.Eq Katip.Core.LogStr
instance GHC.Show.Show Katip.Core.LogStr
instance GHC.Generics.Generic Katip.Core.LogStr
instance GHC.Classes.Ord Katip.Core.ThreadIdText
instance GHC.Classes.Eq Katip.Core.ThreadIdText
instance GHC.Show.Show Katip.Core.ThreadIdText
instance Data.Aeson.Types.FromJSON.FromJSON Katip.Core.ThreadIdText
instance Data.Aeson.Types.ToJSON.ToJSON Katip.Core.ThreadIdText
instance GHC.Base.Functor Katip.Core.Item
instance GHC.Generics.Generic (Katip.Core.Item a)
instance Data.String.IsString Katip.Core.LogStr
instance GHC.Base.Semigroup Katip.Core.LogStr
instance GHC.Base.Monoid Katip.Core.LogStr
instance Data.Aeson.Types.FromJSON.FromJSON Katip.Core.LogStr
instance Data.Aeson.Types.ToJSON.ToJSON Katip.Core.Verbosity
instance Data.Aeson.Types.FromJSON.FromJSON Katip.Core.Verbosity
instance Data.Aeson.Types.ToJSON.ToJSON Katip.Core.Severity
instance Data.Aeson.Types.FromJSON.FromJSON Katip.Core.Severity
instance Data.String.IsString Katip.Core.Namespace


-- | Time and memory efficient time encoding helper functions.
module Katip.Format.Time

-- | Format <a>UTCTime</a> into a short human readable format.
--   
--   <pre>
--   &gt;&gt;&gt; formatAsLogTime $ UTCTime (fromGregorian 2016 1 23) 5025.123456789012
--   "2016-01-23 01:23:45"
--   </pre>
formatAsLogTime :: UTCTime -> Text

-- | Format <a>UTCTime</a> into a Iso8601 format.
--   
--   Note that this function may overcommit up to 12*2 bytes, depending on
--   sub-second precision. If this is an issue, make a copy with a
--   <a>copy</a>.
--   
--   <pre>
--   &gt;&gt;&gt; formatAsIso8601 $ UTCTime (fromGregorian 2016 1 23) 5025.123456789012
--   "2016-11-23T01:23:45.123456789012Z"
--   
--   &gt;&gt;&gt; formatAsIso8601 $ UTCTime (fromGregorian 2016 1 23) 5025.123
--   "2016-01-23T01:23:45.123Z"
--   
--   &gt;&gt;&gt; formatAsIso8601 $ UTCTime (fromGregorian 2016 1 23) 5025
--   "2016-01-23T01:23:45Z"
--   </pre>
formatAsIso8601 :: UTCTime -> Text


-- | Provides support for treating payloads and namespaces as composable
--   contexts. The common pattern would be to provide a <a>KatipContext</a>
--   instance for your base monad.
module Katip.Monadic

-- | Log with full context, but without any code location. Automatically
--   supplies payload and namespace.
logFM :: (Applicative m, KatipContext m) => Severity -> LogStr -> m ()

-- | <a>Loc</a>-tagged logging when using template-haskell. Automatically
--   supplies payload and namespace.
--   
--   <pre>
--   $(logTM) InfoS "Hello world"
--   </pre>
logTM :: ExpQ

-- | <a>Loc</a>-tagged logging when using <a>getCallStack</a>
--   implicit-callstacks&gt;. Automatically supplies payload and namespace.
--   
--   Same consideration as <a>logLoc</a> applies.
--   
--   By default, location will be logged from the module that invokes
--   <a>logLocM</a>. If you want to use <a>logLocM</a> in a helper, wrap
--   the entire helper in <a>withFrozenCallStack</a> to retain the callsite
--   of the helper in the logs.
--   
--   This function does not require template-haskell. Using GHC &lt;= 7.8
--   will result in the emission of a log line without any location
--   information. Users using GHC &lt;= 7.8 may want to use the
--   template-haskell function <a>logTM</a> for maximum compatibility.
--   
--   <pre>
--   logLocM InfoS "Hello world"
--   </pre>
logLocM :: (Applicative m, KatipContext m, HasCallStack) => Severity -> LogStr -> m ()

-- | Log with everything, including a source code location. This is very
--   low level and you typically can use <a>logTM</a> in its place.
--   Automatically supplies payload and namespace.
logItemM :: (Applicative m, KatipContext m, HasCallStack) => Maybe Loc -> Severity -> LogStr -> m ()

-- | Perform an action while logging any exceptions that may occur.
--   Inspired by <a>onException</a>.
--   
--   <pre>
--   &gt;&gt;&gt; &gt; error "foo" `logExceptionM` ErrorS
--   </pre>
logExceptionM :: (KatipContext m, MonadCatch m, Applicative m) => m a -> Severity -> m a

-- | A monadic context that has an inherant way to get logging context and
--   namespace. Examples include a web application monad or database monad.
--   The <tt>local</tt> variants are just like <tt>local</tt> from Reader
--   and indeed you can easily implement them with <tt>local</tt> if you
--   happen to be using a Reader in your monad. These give us
--   <a>katipAddNamespace</a> and <a>katipAddContext</a> that works with
--   *any* <a>KatipContext</a>, as opposed to making users have to
--   implement these functions on their own in each app.
class Katip m => KatipContext m
getKatipContext :: KatipContext m => m LogContexts

-- | Temporarily modify the current context for the duration of the
--   supplied monad. Used in <a>katipAddContext</a>
localKatipContext :: KatipContext m => (LogContexts -> LogContexts) -> m a -> m a
getKatipNamespace :: KatipContext m => m Namespace

-- | Temporarily modify the current namespace for the duration of the
--   supplied monad. Used in <a>katipAddNamespace</a>
localKatipNamespace :: KatipContext m => (Namespace -> Namespace) -> m a -> m a

-- | A wrapper around a log context that erases type information so that
--   contexts from multiple layers can be combined intelligently.
data AnyLogContext

-- | Heterogeneous list of log contexts that provides a smart
--   <tt>LogContext</tt> 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. Also note that contexts are treated as a sequence
--   and <a>&lt;&gt;</a> 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
--   <tt>Map</tt> and <tt>HashMap</tt>, so bear that in mind. The reasoning
--   is that if the user is <i>sequentially</i> 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.
data LogContexts

-- | Lift a log context into the generic wrapper so that it can combine
--   with the existing log context.
liftPayload :: LogItem a => a -> LogContexts

-- | Provides a simple transformer that defines a <a>KatipContext</a>
--   instance for a fixed namespace and context. Just like <a>KatipT</a>,
--   you should use this if you prefer an explicit transformer stack and
--   don't want to (or cannot) define <a>KatipContext</a> for your monad .
--   This is the slightly more powerful version of KatipT in that it
--   provides KatipContext instead of just Katip. For instance:
--   
--   <pre>
--   threadWithLogging = do
--     le &lt;- getLogEnv
--     ctx &lt;- getKatipContext
--     ns &lt;- getKatipNamespace
--     forkIO $ runKatipContextT le ctx ns $ do
--       $(logTM) InfoS "Look, I can log in IO and retain context!"
--       doOtherStuff
--   </pre>
newtype KatipContextT m a
KatipContextT :: ReaderT KatipContextTState m a -> KatipContextT m a
[unKatipContextT] :: KatipContextT m a -> ReaderT KatipContextTState m a
runKatipContextT :: LogItem c => LogEnv -> c -> Namespace -> KatipContextT m a -> m a

-- | Append a namespace segment to the current namespace for the given
--   monadic action, then restore the previous state afterwards. Works with
--   anything implementing KatipContext.
katipAddNamespace :: KatipContext m => Namespace -> m a -> m a

-- | Append some context to the current context for the given monadic
--   action, then restore the previous state afterwards. Important note: be
--   careful using this in a loop. If you're using something like
--   <a>forever</a> or <a>replicateM_</a> that does explicit sharing to
--   avoid a memory leak, youll be fine as it will *sequence* calls to
--   <a>katipAddNamespace</a>, so each loop will get the same context
--   added. If you instead roll your own recursion and you're recursing in
--   the action you provide, you'll instead accumulate tons of redundant
--   contexts and even if they all merge on log, they are stored in a
--   sequence and will leak memory. Works with anything implementing
--   KatipContext.
katipAddContext :: (LogItem i, KatipContext m) => i -> m a -> m a
data KatipContextTState
KatipContextTState :: !LogEnv -> !LogContexts -> !Namespace -> KatipContextTState
[ltsLogEnv] :: KatipContextTState -> !LogEnv
[ltsContext] :: KatipContextTState -> !LogContexts
[ltsNamespace] :: KatipContextTState -> !Namespace
newtype NoLoggingT m a
NoLoggingT :: m a -> NoLoggingT m a
[runNoLoggingT] :: NoLoggingT m a -> m a

-- | Convenience function for when you have to integrate with a third party
--   API that takes a generic logging function as an argument.
askLoggerIO :: (Applicative m, KatipContext m) => m (Severity -> LogStr -> IO ())
instance GHC.Base.Semigroup Katip.Monadic.LogContexts
instance GHC.Base.Monoid Katip.Monadic.LogContexts
instance Control.Monad.Trans.Class.MonadTrans Katip.Monadic.KatipContextT
instance Control.Monad.Fix.MonadFix m => Control.Monad.Fix.MonadFix (Katip.Monadic.KatipContextT m)
instance GHC.Base.Alternative m => GHC.Base.Alternative (Katip.Monadic.KatipContextT m)
instance Control.Monad.Trans.Resource.Internal.MonadResource m => Control.Monad.Trans.Resource.Internal.MonadResource (Katip.Monadic.KatipContextT m)
instance GHC.Base.MonadPlus m => GHC.Base.MonadPlus (Katip.Monadic.KatipContextT m)
instance Control.Monad.Error.Class.MonadError e m => Control.Monad.Error.Class.MonadError e (Katip.Monadic.KatipContextT m)
instance Control.Monad.Writer.Class.MonadWriter w m => Control.Monad.Writer.Class.MonadWriter w (Katip.Monadic.KatipContextT m)
instance Control.Monad.State.Class.MonadState s m => Control.Monad.State.Class.MonadState s (Katip.Monadic.KatipContextT m)
instance Control.Monad.Base.MonadBase b m => Control.Monad.Base.MonadBase b (Katip.Monadic.KatipContextT m)
instance Control.Monad.Catch.MonadMask m => Control.Monad.Catch.MonadMask (Katip.Monadic.KatipContextT m)
instance Control.Monad.Catch.MonadCatch m => Control.Monad.Catch.MonadCatch (Katip.Monadic.KatipContextT m)
instance Control.Monad.Catch.MonadThrow m => Control.Monad.Catch.MonadThrow (Katip.Monadic.KatipContextT m)
instance Control.Monad.IO.Class.MonadIO m => Control.Monad.IO.Class.MonadIO (Katip.Monadic.KatipContextT m)
instance GHC.Base.Monad m => GHC.Base.Monad (Katip.Monadic.KatipContextT m)
instance GHC.Base.Applicative m => GHC.Base.Applicative (Katip.Monadic.KatipContextT m)
instance GHC.Base.Functor m => GHC.Base.Functor (Katip.Monadic.KatipContextT m)
instance Control.Monad.Reader.Class.MonadReader r m => Control.Monad.Reader.Class.MonadReader r (Katip.Monadic.NoLoggingT m)
instance Control.Monad.Fix.MonadFix m => Control.Monad.Fix.MonadFix (Katip.Monadic.NoLoggingT m)
instance GHC.Base.Alternative m => GHC.Base.Alternative (Katip.Monadic.NoLoggingT m)
instance GHC.Base.MonadPlus m => GHC.Base.MonadPlus (Katip.Monadic.NoLoggingT m)
instance Control.Monad.Error.Class.MonadError e m => Control.Monad.Error.Class.MonadError e (Katip.Monadic.NoLoggingT m)
instance Control.Monad.Writer.Class.MonadWriter w m => Control.Monad.Writer.Class.MonadWriter w (Katip.Monadic.NoLoggingT m)
instance Control.Monad.State.Class.MonadState s m => Control.Monad.State.Class.MonadState s (Katip.Monadic.NoLoggingT m)
instance Control.Monad.Base.MonadBase b m => Control.Monad.Base.MonadBase b (Katip.Monadic.NoLoggingT m)
instance Control.Monad.Catch.MonadMask m => Control.Monad.Catch.MonadMask (Katip.Monadic.NoLoggingT m)
instance Control.Monad.Catch.MonadCatch m => Control.Monad.Catch.MonadCatch (Katip.Monadic.NoLoggingT m)
instance Control.Monad.Catch.MonadThrow m => Control.Monad.Catch.MonadThrow (Katip.Monadic.NoLoggingT m)
instance Control.Monad.IO.Class.MonadIO m => Control.Monad.IO.Class.MonadIO (Katip.Monadic.NoLoggingT m)
instance GHC.Base.Monad m => GHC.Base.Monad (Katip.Monadic.NoLoggingT m)
instance GHC.Base.Applicative m => GHC.Base.Applicative (Katip.Monadic.NoLoggingT m)
instance GHC.Base.Functor m => GHC.Base.Functor (Katip.Monadic.NoLoggingT m)
instance (GHC.Base.Monad m, Katip.Monadic.KatipContext m) => Katip.Monadic.KatipContext (Katip.Core.KatipT m)
instance Control.Monad.Trans.Class.MonadTrans Katip.Monadic.NoLoggingT
instance Control.Monad.Trans.Control.MonadTransControl Katip.Monadic.NoLoggingT
instance Control.Monad.Trans.Control.MonadBaseControl b m => Control.Monad.Trans.Control.MonadBaseControl b (Katip.Monadic.NoLoggingT m)
instance Control.Monad.IO.Unlift.MonadUnliftIO m => Control.Monad.IO.Unlift.MonadUnliftIO (Katip.Monadic.NoLoggingT m)
instance Control.Monad.IO.Class.MonadIO m => Katip.Core.Katip (Katip.Monadic.NoLoggingT m)
instance Control.Monad.IO.Class.MonadIO m => Katip.Monadic.KatipContext (Katip.Monadic.NoLoggingT m)
instance Control.Monad.Trans.Control.MonadTransControl Katip.Monadic.KatipContextT
instance Control.Monad.Trans.Control.MonadBaseControl b m => Control.Monad.Trans.Control.MonadBaseControl b (Katip.Monadic.KatipContextT m)
instance Control.Monad.Reader.Class.MonadReader r m => Control.Monad.Reader.Class.MonadReader r (Katip.Monadic.KatipContextT m)
instance Control.Monad.IO.Class.MonadIO m => Katip.Core.Katip (Katip.Monadic.KatipContextT m)
instance Control.Monad.IO.Class.MonadIO m => Katip.Monadic.KatipContext (Katip.Monadic.KatipContextT m)
instance Control.Monad.IO.Unlift.MonadUnliftIO m => Control.Monad.IO.Unlift.MonadUnliftIO (Katip.Monadic.KatipContextT m)
instance Control.Monad.Fail.MonadFail m => Control.Monad.Fail.MonadFail (Katip.Monadic.KatipContextT m)
instance (Katip.Monadic.KatipContext m, Katip.Core.Katip (Control.Monad.Trans.Identity.IdentityT m)) => Katip.Monadic.KatipContext (Control.Monad.Trans.Identity.IdentityT m)
instance (Katip.Monadic.KatipContext m, Katip.Core.Katip (Control.Monad.Trans.Maybe.MaybeT m)) => Katip.Monadic.KatipContext (Control.Monad.Trans.Maybe.MaybeT m)
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)
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)
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)
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)
instance (Katip.Monadic.KatipContext m, Katip.Core.Katip (Control.Monad.Trans.Except.ExceptT e m)) => Katip.Monadic.KatipContext (Control.Monad.Trans.Except.ExceptT e m)
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)
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)
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)
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)
instance Data.Aeson.Types.ToJSON.ToJSON Katip.Monadic.LogContexts
instance Katip.Core.ToObject Katip.Monadic.LogContexts
instance Katip.Core.LogItem Katip.Monadic.LogContexts

module Katip.Scribes.Handle
brackets :: Builder -> Builder
getKeys :: LogItem s => Verbosity -> s -> [Builder]
toBuilders :: HashMap Text Value -> [[Builder]]
toTxtKeyList :: HashMap Text v -> [(Text, v)]
renderPair :: (Text, Value) -> [Builder]
data ColorStrategy

-- | Whether to use color control chars in log output
ColorLog :: Bool -> ColorStrategy

-- | Color if output is a terminal
ColorIfTerminal :: ColorStrategy

-- | Logs to a file handle such as stdout, stderr, or a file. Contexts and
--   other information will be flattened out into bracketed fields. For
--   example:
--   
--   <pre>
--   [2016-05-11 21:01:15][MyApp][Info][myhost.example.com][PID 1724][ThreadId 1154][main:Helpers.Logging Helpers/Logging.hs:32:7] Started
--   [2016-05-11 21:01:15][MyApp.confrabulation][Debug][myhost.example.com][PID 1724][ThreadId 1154][confrab_factor:42.0][main:Helpers.Logging Helpers/Logging.hs:41:9] Confrabulating widgets, with extra namespace and context
--   [2016-05-11 21:01:15][MyApp][Info][myhost.example.com][PID 1724][ThreadId 1154][main:Helpers.Logging Helpers/Logging.hs:43:7] Namespace and context are back to normal
--   </pre>
--   
--   Returns the newly-created <a>Scribe</a>. The finalizer flushes the
--   handle. Handle mode is set to <a>LineBuffering</a> automatically.
mkHandleScribe :: ColorStrategy -> Handle -> PermitFunc -> Verbosity -> IO Scribe

-- | Logs to a file handle such as stdout, stderr, or a file. Takes a
--   custom <a>ItemFormatter</a> that can be used to format <a>Item</a> as
--   needed.
--   
--   Returns the newly-created <a>Scribe</a>. The finalizer flushes the
--   handle. Handle mode is set to <a>LineBuffering</a> automatically.
mkHandleScribeWithFormatter :: (forall a. LogItem a => ItemFormatter a) -> ColorStrategy -> Handle -> PermitFunc -> Verbosity -> IO Scribe

-- | A specialization of <a>mkHandleScribe</a> that takes a <a>FilePath</a>
--   instead of a <a>Handle</a>. It is responsible for opening the file in
--   <a>AppendMode</a> and will close the file handle on
--   <a>closeScribe</a>/<a>closeScribes</a>. Does not do log coloring. Sets
--   handle to <a>LineBuffering</a> mode.
mkFileScribe :: FilePath -> PermitFunc -> Verbosity -> IO Scribe

-- | A custom ItemFormatter for logging <a>Item</a>s. Takes a <a>Bool</a>
--   indicating whether to colorize the output, <a>Verbosity</a> of output,
--   and an <a>Item</a> to format.
--   
--   See <a>bracketFormat</a> and <a>jsonFormat</a> for examples.
type ItemFormatter a = Bool -> Verbosity -> Item a -> Builder

-- | <i>Deprecated: Use bracketFormat instead</i>
formatItem :: LogItem a => ItemFormatter a

-- | A traditional <tt>bracketed</tt> log format. Contexts and other
--   information will be flattened out into bracketed fields. For example:
--   
--   <pre>
--   [2016-05-11 21:01:15][MyApp][Info][myhost.example.com][PID 1724][ThreadId 1154][main:Helpers.Logging Helpers/Logging.hs:32:7] Started
--   [2016-05-11 21:01:15][MyApp.confrabulation][Debug][myhost.example.com][PID 1724][ThreadId 1154][confrab_factor:42.0][main:Helpers.Logging Helpers/Logging.hs:41:9] Confrabulating widgets, with extra namespace and context
--   [2016-05-11 21:01:15][MyApp][Info][myhost.example.com][PID 1724][ThreadId 1154][main:Helpers.Logging Helpers/Logging.hs:43:7] Namespace and context are back to normal
--   </pre>
bracketFormat :: LogItem a => ItemFormatter a

-- | Logs items as JSON. This can be useful in circumstances where you
--   already have infrastructure that is expecting JSON to be logged to a
--   standard stream or file. For example:
--   
--   <pre>
--   {"at":"2018-10-02T21:50:30.4523848Z","env":"production","ns":["MyApp"],"data":{},"app":["MyApp"],"msg":"Started","pid":"10456","loc":{"loc_col":9,"loc_pkg":"main","loc_mod":"Helpers.Logging","loc_fn":"Helpers\\Logging.hs","loc_ln":44},"host":"myhost.example.com","sev":"Info","thread":"ThreadId 139"}
--   {"at":"2018-10-02T21:50:30.4523848Z","env":"production","ns":["MyApp","confrabulation"],"data":{"confrab_factor":42},"app":["MyApp"],"msg":"Confrabulating widgets, with extra namespace and context","pid":"10456","loc":{"loc_col":11,"loc_pkg":"main","loc_mod":"Helpers.Logging","loc_fn":"Helpers\\Logging.hs","loc_ln":53},"host":"myhost.example.com","sev":"Debug","thread":"ThreadId 139"}
--   {"at":"2018-10-02T21:50:30.4523848Z","env":"production","ns":["MyApp"],"data":{},"app":["MyApp"],"msg":"Namespace and context are back to normal","pid":"10456","loc":{"loc_col":9,"loc_pkg":"main","loc_mod":"Helpers.Logging","loc_fn":"Helpers\\Logging.hs","loc_ln":55},"host":"myhost.example.com","sev":"Info","thread":"ThreadId 139"}
--   </pre>
jsonFormat :: LogItem a => ItemFormatter a

-- | Color a text message based on <a>Severity</a>. <a>ErrorS</a> and more
--   severe errors are colored red, <a>WarningS</a> is colored yellow, and
--   all other messages are rendered in the default color.
colorBySeverity :: Bool -> Severity -> Text -> Text

-- | Provides a simple log environment with 1 scribe going to stdout. This
--   is a decent example of how to build a LogEnv and is best for scripts
--   that just need a quick, reasonable set up to log to stdout.
ioLogEnv :: PermitFunc -> Verbosity -> IO LogEnv
instance GHC.Classes.Eq Katip.Scribes.Handle.ColorStrategy
instance GHC.Show.Show Katip.Scribes.Handle.ColorStrategy


-- | Includes all of the APIs youll need to use Katip. Be sure to check out
--   the included <tt>examples</tt> directory for an example of usage.
--   
--   Here's a basic example:
--   
--   <pre>
--   {-# LANGUAGE OverloadedStrings #-}
--   {-# LANGUAGE TemplateHaskell #-}
--   import Control.Exception
--   import Katip
--   
--   main :: IO ()
--   main = do
--     handleScribe &lt;- mkHandleScribe ColorIfTerminal stdout (permitItem InfoS) V2
--     let makeLogEnv = registerScribe "stdout" handleScribe defaultScribeSettings =&lt;&lt; initLogEnv "MyApp" "production"
--     -- closeScribes will stop accepting new logs, flush existing ones and clean up resources
--     bracket makeLogEnv closeScribes $ \le -&gt; do
--       let initialContext = () -- this context will be attached to every log in your app and merged w/ subsequent contexts
--       let initialNamespace = "main"
--       runKatipContextT le initialContext initialNamespace $ do
--         $(logTM) InfoS "Hello Katip"
--         -- This adds a namespace to the current namespace and merges a piece of contextual data into your context
--         katipAddNamespace "additional_namespace" $ katipAddContext (sl "some_context" True) $ do
--           $(logTM) WarningS "Now we're getting fancy"
--         katipNoLogging $ do
--           $(logTM) DebugS "You will never see this!"
--   </pre>
--   
--   And here is the output:
--   
--   <pre>
--   [2021-06-14 20:24:24][MyApp.main][Info][yourhostname][PID 14420][ThreadId 27][main:Main app/Main.hs:26:9] Hello Katip
--   [2021-06-14 20:24:24][MyApp.main.additional_namespace][Warning][yourhostname][PID 14420][ThreadId 27][some_context:True][main:Main app/Main.hs:29:11] Now we're getting fancy
--   </pre>
--   
--   Another common case that you have some sort of App monad that's based
--   on ReaderT with some Config state. This is a perfect place to insert
--   read-only katip state:
--   
--   <pre>
--   import Katip as K
--   
--   data Config = Config {
--     logNamespace :: K.Namespace
--   , logContext :: K.LogContexts
--   , logEnv :: K.LogEnv
--   -- whatever other read-only config you need
--   }
--   
--   newtype App m a = App {
--     unApp :: ReaderT Config m a
--   } deriving (Functor, Applicative, Monad, MonadIO, MonadReader Config) -- these are necessary
--   
--   
--   -- These instances get even easier with lenses!
--   instance (MonadIO m) =&gt; K.Katip (App m) where
--     getLogEnv = asks logEnv
--     -- with lens:
--     -- getLogEnv = view logEnv
--     localLogEnv f (App m) = App (local (\s -&gt; s { logEnv = f (logEnv s)}) m)
--     -- with lens:
--     -- localLogEnv f (App m) = App (local (over logEnv f) m)
--   
--   
--   instance (MonadIO m) =&gt; K.KatipContext (App m) where
--     getKatipContext = asks logContext
--     -- with lens:
--     -- getKatipContext = view logContext
--     localKatipContext f (App m) = App (local (\s -&gt; s { logContext = f (logContext s)}) m)
--     -- with lens:
--     -- localKatipContext f (App m) = App (local (over logContext f) m)
--     getKatipNamespace = asks logNamespace
--     -- with lens:
--     -- getKatipNamespace = view logNamespace
--     localKatipNamespace f (App m) = App (local (\s -&gt; s { logNamespace = f (logNamespace s)}) m)
--     -- with lens:
--     -- localKatipNamespace f (App m) = App (local (over logNamespace f) m)
--   </pre>
--   
--   To get up and running, the workflow is generally:
--   
--   <ul>
--   <li>Set up a <a>LogEnv</a> using <a>initLogEnv</a>.</li>
--   <li>Add <a>Scribe</a>s using <a>registerScribe</a>.</li>
--   <li>Either use <a>KatipT</a> or <a>KatipContextT</a> for a pre-built
--   transformer stack or add <a>Katip</a> and <a>KatipContext</a>
--   instances to your own transformer stack. If you do the latter, you may
--   want to look in the <tt>examples</tt> dir for some tips on composing
--   contexts and namespaces.</li>
--   <li>Define some structured log data throughout your application and
--   implement <a>ToObject</a> and <a>LogItem</a> for them.</li>
--   <li>Begin logging with <a>logT</a>, <a>logTM</a>, etc.</li>
--   <li>Define your own <a>Scribe</a> if you need to output to some as-yet
--   unsupported format or service. If you think it would be useful to
--   others, consider releasing your own package.</li>
--   </ul>
module Katip

-- | Represents a heirarchy of namespaces going from general to specific.
--   For instance: ["processname", "subsystem"]. Note that single-segment
--   namespaces can be created using IsString/OverloadedStrings, so "foo"
--   will result in Namespace ["foo"].
newtype Namespace
Namespace :: [Text] -> Namespace
[unNamespace] :: Namespace -> [Text]

-- | Application environment, like <tt>prod</tt>, <tt>devel</tt>,
--   <tt>testing</tt>.
newtype Environment
Environment :: Text -> Environment
[getEnvironment] :: Environment -> Text
data Severity

-- | Debug messages
DebugS :: Severity

-- | Information
InfoS :: Severity

-- | Normal runtime Conditions
NoticeS :: Severity

-- | General Warnings
WarningS :: Severity

-- | General Errors
ErrorS :: Severity

-- | Severe situations
CriticalS :: Severity

-- | Take immediate action
AlertS :: Severity

-- | System is unusable
EmergencyS :: Severity
renderSeverity :: Severity -> Text
textToSeverity :: Text -> Maybe Severity

-- | Verbosity controls the amount of information (columns) a <a>Scribe</a>
--   emits during logging.
--   
--   The convention is: - <a>V0</a> implies no additional payload
--   information is included in message. - <a>V3</a> implies the maximum
--   amount of payload information. - Anything in between is left to the
--   discretion of the developer.
data Verbosity
V0 :: Verbosity
V1 :: Verbosity
V2 :: Verbosity
V3 :: Verbosity

-- | Katip requires JSON objects to be logged as context. This typeclass
--   provides a default instance which uses ToJSON and produces an empty
--   object if <a>toJSON</a> results in any type other than object. If you
--   have a type you want to log that produces an Array or Number for
--   example, you'll want to write an explicit instance here. You can
--   trivially add a ToObject instance for something with a ToJSON instance
--   like:
--   
--   <pre>
--   instance ToObject Foo
--   </pre>
class ToObject a
toObject :: ToObject a => a -> Object
toObject :: (ToObject a, ToJSON a) => a -> Object

-- | Payload objects need instances of this class. LogItem makes it so that
--   you can have very verbose items getting logged with lots of extra
--   fields but under normal circumstances, if your scribe is configured
--   for a lower verbosity level, it will only log a selection of those
--   keys. Furthermore, each <a>Scribe</a> can be configured with a
--   different <a>Verbosity</a> level. You could even use
--   <a>registerScribe</a>, <a>unregisterScribe</a>, and
--   <a>clearScribes</a> to at runtime swap out your existing scribes for
--   more verbose debugging scribes if you wanted to.
--   
--   When defining <a>payloadKeys</a>, don't redundantly declare the same
--   keys for higher levels of verbosity. Each level of verbosity
--   automatically and recursively contains all keys from the level before
--   it.
class ToObject a => LogItem a

-- | List of keys in the JSON object that should be included in message.
payloadKeys :: LogItem a => Verbosity -> a -> PayloadSelection

-- | This has everything each log message will contain.
data Item a
Item :: Namespace -> Environment -> Severity -> ThreadIdText -> HostName -> ProcessID -> a -> LogStr -> UTCTime -> Namespace -> Maybe Loc -> Item a
[_itemApp] :: Item a -> Namespace
[_itemEnv] :: Item a -> Environment
[_itemSeverity] :: Item a -> Severity
[_itemThread] :: Item a -> ThreadIdText
[_itemHost] :: Item a -> HostName
[_itemProcess] :: Item a -> ProcessID
[_itemPayload] :: Item a -> a
[_itemMessage] :: Item a -> LogStr
[_itemTime] :: Item a -> UTCTime
[_itemNamespace] :: Item a -> Namespace
[_itemLoc] :: Item a -> Maybe Loc
newtype ThreadIdText
ThreadIdText :: Text -> ThreadIdText
[getThreadIdText] :: ThreadIdText -> Text

-- | Field selector by verbosity within JSON payload.
data PayloadSelection
AllKeys :: PayloadSelection
SomeKeys :: [Text] -> PayloadSelection
data Scribe
Scribe :: (forall a. LogItem a => Item a -> IO ()) -> IO () -> PermitFunc -> Scribe

-- | How do we write an item to the scribe's output?
[liPush] :: Scribe -> forall a. LogItem a => Item a -> IO ()

-- | Provide a <b>blocking</b> finalizer to call when your scribe is
--   removed. All pending writes should be flushed synchronously. If this
--   is not relevant to your scribe, return () is fine.
[scribeFinalizer] :: Scribe -> IO ()

-- | Provide a filtering function to allow the item to be logged, or not.
--   It can check Severity or some string in item's body. The initial value
--   of this is usually created from <a>permitItem</a>. Scribes and users
--   can customize this by ANDing or ORing onto the default with
--   <a>permitAND</a> or <a>permitOR</a>
[scribePermitItem] :: Scribe -> PermitFunc
data LogEnv
LogEnv :: HostName -> ProcessID -> Namespace -> Environment -> IO UTCTime -> Map Text ScribeHandle -> LogEnv
[_logEnvHost] :: LogEnv -> HostName
[_logEnvPid] :: LogEnv -> ProcessID

-- | 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 <a>WebServer</a>, the final namespace will be
--   <a>MyApp.WebServer</a>
[_logEnvApp] :: LogEnv -> Namespace
[_logEnvEnv] :: LogEnv -> Environment

-- | Action to fetch the timestamp. You can use something like
--   <tt>AutoUpdate</tt> for high volume logs but note that this may cause
--   some output forms to display logs out of order. Alternatively, you
--   could just use <a>getCurrentTime</a>.
[_logEnvTimer] :: LogEnv -> IO UTCTime
[_logEnvScribes] :: LogEnv -> Map Text ScribeHandle
data SimpleLogPayload

-- | Construct a simple log from any JSON item.
sl :: ToJSON a => Text -> a -> SimpleLogPayload

-- | Reasonable defaults for a scribe. Buffer size of 4096.
defaultScribeSettings :: ScribeSettings
data ScribeSettings
scribeBufferSize :: Lens' ScribeSettings Int
_scribeBufferSize :: ScribeSettings -> Int
itemApp :: forall a_aciI. Lens' (Item a_aciI) Namespace
itemEnv :: forall a_aciI. Lens' (Item a_aciI) Environment
itemSeverity :: forall a_aciI. Lens' (Item a_aciI) Severity
itemThread :: forall a_aciI. Lens' (Item a_aciI) ThreadIdText
itemHost :: forall a_aciI. Lens' (Item a_aciI) HostName
itemProcess :: forall a_aciI. Lens' (Item a_aciI) ProcessID
itemPayload :: forall a_aciI a_ag6d. Lens (Item a_aciI) (Item a_ag6d) a_aciI a_ag6d
itemMessage :: forall a_aciI. Lens' (Item a_aciI) LogStr
itemTime :: forall a_aciI. Lens' (Item a_aciI) UTCTime
itemNamespace :: forall a_aciI. Lens' (Item a_aciI) Namespace
itemLoc :: forall a_aciI. Lens' (Item a_aciI) (Maybe Loc)
logEnvHost :: Lens' LogEnv HostName
logEnvPid :: Lens' LogEnv ProcessID
logEnvApp :: Lens' LogEnv Namespace
logEnvEnv :: Lens' LogEnv Environment
logEnvTimer :: Lens' LogEnv (IO UTCTime)
logEnvScribes :: Lens' LogEnv (Map Text ScribeHandle)

-- | A concrete monad you can use to run logging actions. Use this if you
--   prefer an explicit monad transformer stack and adding layers as
--   opposed to implementing <a>Katip</a> for your monad.
newtype KatipT m a
KatipT :: ReaderT LogEnv m a -> KatipT m a
[unKatipT] :: KatipT m a -> ReaderT LogEnv m a

-- | Execute <a>KatipT</a> on a log env.
runKatipT :: LogEnv -> KatipT m a -> m a

-- | Create a reasonable default InitLogEnv. Uses an <tt>AutoUpdate</tt>
--   which updates the timer every 1ms. If you need even more timestamp
--   precision at the cost of performance, consider setting
--   <a>_logEnvTimer</a> with <a>getCurrentTime</a>.
initLogEnv :: Namespace -> Environment -> IO LogEnv

-- | Add a scribe to the list. All future log calls will go to this scribe
--   in addition to the others. Writes will be buffered per the
--   ScribeSettings to prevent slow scribes from slowing down logging.
--   Writes will be dropped if the buffer fills.
registerScribe :: Text -> Scribe -> ScribeSettings -> LogEnv -> IO LogEnv

-- | Remove a scribe from the environment. This does <b>not</b> finalize
--   the scribe. This mainly only makes sense to use with something like
--   MonadReader's <tt>local</tt> function to temporarily disavow a single
--   logger for a block of code.
unregisterScribe :: Text -> LogEnv -> LogEnv

-- | Unregister <b>all</b> scribes. Note that this is <b>not</b> for
--   closing or finalizing scribes, use <a>closeScribes</a> for that. This
--   mainly only makes sense to use with something like MonadReader's
--   <tt>local</tt> function to temporarily disavow any loggers for a block
--   of code.
clearScribes :: LogEnv -> LogEnv

-- | Call this at the end of your program. This is a blocking call that
--   stop writing to a scribe's queue, waits for the queue to empty,
--   finalizes each scribe in the log environment and then removes it.
--   Finalizers are all run even if one of them throws, but the exception
--   will be re-thrown at the end.
closeScribes :: LogEnv -> IO LogEnv

-- | Finalize a scribe. The scribe is removed from the environment, its
--   finalizer is called so that it can never be written to again and all
--   pending writes are flushed. Note that this will throw any exceptions
--   yoru finalizer will throw, and that LogEnv is immutable, so it will
--   not be removed in that case.
closeScribe :: Text -> LogEnv -> IO LogEnv

-- | Log message with Builder underneath; use <a>&lt;&gt;</a> to concat in
--   O(1).
newtype LogStr
LogStr :: Builder -> LogStr
[unLogStr] :: LogStr -> Builder

-- | Pack any string-like thing into a <a>LogStr</a>. This will
--   automatically work on <a>String</a>, <tt>ByteString</tt>, <a>Text</a>
--   and any of the lazy variants.
logStr :: StringConv a Text => a -> LogStr

-- | Shorthand for <a>logStr</a>
ls :: StringConv a Text => a -> LogStr

-- | Convert any showable type into a <a>LogStr</a>.
showLS :: Show a => a -> LogStr

-- | 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
--   <tt>KatipContext</tt>, which keeps a namespace and merged context. You
--   can write simple functions that add additional namespacing and merges
--   additional context on the fly.
--   
--   <a>localLogEnv</a> was added to allow for lexically-scoped
--   modifications of the log env that are reverted when the supplied monad
--   completes. <a>katipNoLogging</a>, for example, uses this to
--   temporarily pause log outputs.
class MonadIO m => Katip m
getLogEnv :: Katip m => m LogEnv
localLogEnv :: Katip m => (LogEnv -> LogEnv) -> m a -> m a

-- | Log with full context, but without any code location.
logF :: (Applicative m, LogItem a, Katip m) => a -> Namespace -> Severity -> LogStr -> m ()

-- | Log a message without any payload/context or code location.
logMsg :: (Applicative m, Katip m) => Namespace -> Severity -> LogStr -> m ()

-- | <a>Loc</a>-tagged logging when using template-haskell.
--   
--   <pre>
--   $(logT) obj mempty InfoS "Hello world"
--   </pre>
logT :: ExpQ

-- | <a>Loc</a>-tagged logging using <a>Stack</a> when available.
--   
--   This function does not require template-haskell as it automatically
--   uses <a>implicit-callstacks</a> when the code is compiled using GHC
--   &gt; 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 &lt;= 7.8 may want to use the template-haskell
--   function <a>logT</a> for maximum compatibility.
--   
--   <pre>
--   logLoc obj mempty InfoS "Hello world"
--   </pre>
logLoc :: (Applicative m, LogItem a, Katip m, HasCallStack) => a -> Namespace -> Severity -> LogStr -> m ()

-- | Log with everything, including a source code location. This is very
--   low level and you typically can use <a>logT</a> in its place.
logItem :: (Applicative m, LogItem a, Katip m) => a -> Namespace -> Maybe Loc -> Severity -> LogStr -> m ()

-- | Log already constructed <a>Item</a>. This is the lowest level function
--   that other log* functions use. It can be useful when implementing
--   centralised logging services.
logKatipItem :: (Applicative m, LogItem a, Katip m) => Item a -> m ()

-- | Perform an action while logging any exceptions that may occur.
--   Inspired by <a>onException</a>.
--   
--   <pre>
--   &gt;&gt;&gt; &gt; logException () mempty ErrorS (error "foo")
--   </pre>
logException :: (Katip m, LogItem a, MonadCatch m, Applicative m) => a -> Namespace -> Severity -> m b -> m b

-- | A monadic context that has an inherant way to get logging context and
--   namespace. Examples include a web application monad or database monad.
--   The <tt>local</tt> variants are just like <tt>local</tt> from Reader
--   and indeed you can easily implement them with <tt>local</tt> if you
--   happen to be using a Reader in your monad. These give us
--   <a>katipAddNamespace</a> and <a>katipAddContext</a> that works with
--   *any* <a>KatipContext</a>, as opposed to making users have to
--   implement these functions on their own in each app.
class Katip m => KatipContext m
getKatipContext :: KatipContext m => m LogContexts

-- | Temporarily modify the current context for the duration of the
--   supplied monad. Used in <a>katipAddContext</a>
localKatipContext :: KatipContext m => (LogContexts -> LogContexts) -> m a -> m a
getKatipNamespace :: KatipContext m => m Namespace

-- | Temporarily modify the current namespace for the duration of the
--   supplied monad. Used in <a>katipAddNamespace</a>
localKatipNamespace :: KatipContext m => (Namespace -> Namespace) -> m a -> m a

-- | Log with full context, but without any code location. Automatically
--   supplies payload and namespace.
logFM :: (Applicative m, KatipContext m) => Severity -> LogStr -> m ()

-- | <a>Loc</a>-tagged logging when using template-haskell. Automatically
--   supplies payload and namespace.
--   
--   <pre>
--   $(logTM) InfoS "Hello world"
--   </pre>
logTM :: ExpQ

-- | <a>Loc</a>-tagged logging when using <a>getCallStack</a>
--   implicit-callstacks&gt;. Automatically supplies payload and namespace.
--   
--   Same consideration as <a>logLoc</a> applies.
--   
--   By default, location will be logged from the module that invokes
--   <a>logLocM</a>. If you want to use <a>logLocM</a> in a helper, wrap
--   the entire helper in <a>withFrozenCallStack</a> to retain the callsite
--   of the helper in the logs.
--   
--   This function does not require template-haskell. Using GHC &lt;= 7.8
--   will result in the emission of a log line without any location
--   information. Users using GHC &lt;= 7.8 may want to use the
--   template-haskell function <a>logTM</a> for maximum compatibility.
--   
--   <pre>
--   logLocM InfoS "Hello world"
--   </pre>
logLocM :: (Applicative m, KatipContext m, HasCallStack) => Severity -> LogStr -> m ()

-- | Log with everything, including a source code location. This is very
--   low level and you typically can use <a>logTM</a> in its place.
--   Automatically supplies payload and namespace.
logItemM :: (Applicative m, KatipContext m, HasCallStack) => Maybe Loc -> Severity -> LogStr -> m ()

-- | Perform an action while logging any exceptions that may occur.
--   Inspired by <a>onException</a>.
--   
--   <pre>
--   &gt;&gt;&gt; &gt; error "foo" `logExceptionM` ErrorS
--   </pre>
logExceptionM :: (KatipContext m, MonadCatch m, Applicative m) => m a -> Severity -> m a

-- | A wrapper around a log context that erases type information so that
--   contexts from multiple layers can be combined intelligently.
data AnyLogContext

-- | Heterogeneous list of log contexts that provides a smart
--   <tt>LogContext</tt> 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. Also note that contexts are treated as a sequence
--   and <a>&lt;&gt;</a> 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
--   <tt>Map</tt> and <tt>HashMap</tt>, so bear that in mind. The reasoning
--   is that if the user is <i>sequentially</i> 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.
data LogContexts

-- | Lift a log context into the generic wrapper so that it can combine
--   with the existing log context.
liftPayload :: LogItem a => a -> LogContexts

-- | Append a namespace segment to the current namespace for the given
--   monadic action, then restore the previous state afterwards. Works with
--   anything implementing KatipContext.
katipAddNamespace :: KatipContext m => Namespace -> m a -> m a

-- | Append some context to the current context for the given monadic
--   action, then restore the previous state afterwards. Important note: be
--   careful using this in a loop. If you're using something like
--   <a>forever</a> or <a>replicateM_</a> that does explicit sharing to
--   avoid a memory leak, youll be fine as it will *sequence* calls to
--   <a>katipAddNamespace</a>, so each loop will get the same context
--   added. If you instead roll your own recursion and you're recursing in
--   the action you provide, you'll instead accumulate tons of redundant
--   contexts and even if they all merge on log, they are stored in a
--   sequence and will leak memory. Works with anything implementing
--   KatipContext.
katipAddContext :: (LogItem i, KatipContext m) => i -> m a -> m a

-- | Disable all scribes for the given monadic action, then restore them
--   afterwards. Works in any Katip monad.
katipNoLogging :: Katip m => m a -> m a

-- | Logs to a file handle such as stdout, stderr, or a file. Contexts and
--   other information will be flattened out into bracketed fields. For
--   example:
--   
--   <pre>
--   [2016-05-11 21:01:15][MyApp][Info][myhost.example.com][PID 1724][ThreadId 1154][main:Helpers.Logging Helpers/Logging.hs:32:7] Started
--   [2016-05-11 21:01:15][MyApp.confrabulation][Debug][myhost.example.com][PID 1724][ThreadId 1154][confrab_factor:42.0][main:Helpers.Logging Helpers/Logging.hs:41:9] Confrabulating widgets, with extra namespace and context
--   [2016-05-11 21:01:15][MyApp][Info][myhost.example.com][PID 1724][ThreadId 1154][main:Helpers.Logging Helpers/Logging.hs:43:7] Namespace and context are back to normal
--   </pre>
--   
--   Returns the newly-created <a>Scribe</a>. The finalizer flushes the
--   handle. Handle mode is set to <a>LineBuffering</a> automatically.
mkHandleScribe :: ColorStrategy -> Handle -> PermitFunc -> Verbosity -> IO Scribe

-- | Logs to a file handle such as stdout, stderr, or a file. Takes a
--   custom <a>ItemFormatter</a> that can be used to format <a>Item</a> as
--   needed.
--   
--   Returns the newly-created <a>Scribe</a>. The finalizer flushes the
--   handle. Handle mode is set to <a>LineBuffering</a> automatically.
mkHandleScribeWithFormatter :: (forall a. LogItem a => ItemFormatter a) -> ColorStrategy -> Handle -> PermitFunc -> Verbosity -> IO Scribe

-- | A specialization of <a>mkHandleScribe</a> that takes a <a>FilePath</a>
--   instead of a <a>Handle</a>. It is responsible for opening the file in
--   <a>AppendMode</a> and will close the file handle on
--   <a>closeScribe</a>/<a>closeScribes</a>. Does not do log coloring. Sets
--   handle to <a>LineBuffering</a> mode.
mkFileScribe :: FilePath -> PermitFunc -> Verbosity -> IO Scribe
data ColorStrategy

-- | Whether to use color control chars in log output
ColorLog :: Bool -> ColorStrategy

-- | Color if output is a terminal
ColorIfTerminal :: ColorStrategy

-- | A custom ItemFormatter for logging <a>Item</a>s. Takes a <a>Bool</a>
--   indicating whether to colorize the output, <a>Verbosity</a> of output,
--   and an <a>Item</a> to format.
--   
--   See <a>bracketFormat</a> and <a>jsonFormat</a> for examples.
type ItemFormatter a = Bool -> Verbosity -> Item a -> Builder

-- | A traditional <tt>bracketed</tt> log format. Contexts and other
--   information will be flattened out into bracketed fields. For example:
--   
--   <pre>
--   [2016-05-11 21:01:15][MyApp][Info][myhost.example.com][PID 1724][ThreadId 1154][main:Helpers.Logging Helpers/Logging.hs:32:7] Started
--   [2016-05-11 21:01:15][MyApp.confrabulation][Debug][myhost.example.com][PID 1724][ThreadId 1154][confrab_factor:42.0][main:Helpers.Logging Helpers/Logging.hs:41:9] Confrabulating widgets, with extra namespace and context
--   [2016-05-11 21:01:15][MyApp][Info][myhost.example.com][PID 1724][ThreadId 1154][main:Helpers.Logging Helpers/Logging.hs:43:7] Namespace and context are back to normal
--   </pre>
bracketFormat :: LogItem a => ItemFormatter a

-- | Logs items as JSON. This can be useful in circumstances where you
--   already have infrastructure that is expecting JSON to be logged to a
--   standard stream or file. For example:
--   
--   <pre>
--   {"at":"2018-10-02T21:50:30.4523848Z","env":"production","ns":["MyApp"],"data":{},"app":["MyApp"],"msg":"Started","pid":"10456","loc":{"loc_col":9,"loc_pkg":"main","loc_mod":"Helpers.Logging","loc_fn":"Helpers\\Logging.hs","loc_ln":44},"host":"myhost.example.com","sev":"Info","thread":"ThreadId 139"}
--   {"at":"2018-10-02T21:50:30.4523848Z","env":"production","ns":["MyApp","confrabulation"],"data":{"confrab_factor":42},"app":["MyApp"],"msg":"Confrabulating widgets, with extra namespace and context","pid":"10456","loc":{"loc_col":11,"loc_pkg":"main","loc_mod":"Helpers.Logging","loc_fn":"Helpers\\Logging.hs","loc_ln":53},"host":"myhost.example.com","sev":"Debug","thread":"ThreadId 139"}
--   {"at":"2018-10-02T21:50:30.4523848Z","env":"production","ns":["MyApp"],"data":{},"app":["MyApp"],"msg":"Namespace and context are back to normal","pid":"10456","loc":{"loc_col":9,"loc_pkg":"main","loc_mod":"Helpers.Logging","loc_fn":"Helpers\\Logging.hs","loc_ln":55},"host":"myhost.example.com","sev":"Info","thread":"ThreadId 139"}
--   </pre>
jsonFormat :: LogItem a => ItemFormatter a

-- | Scribes are handlers of incoming items. Each registered scribe knows
--   how to push a log item somewhere.
--   
--   <h1>Guidelines for writing your own <a>Scribe</a></h1>
--   
--   Scribes should always take a <a>Severity</a> and <a>Verbosity</a>.
--   
--   Severity is used to <b>exclude log messages</b> that are lower than
--   the provided Severity. For instance, if the user passes InfoS, DebugS
--   items should be ignored. Katip provides the <a>permitItem</a> utility
--   for this. The user or the scribe may use <a>permitAND</a> and
--   <a>permitOR</a> to further customize this filtering, even dynamically
--   if they wish to.
--   
--   Verbosity is used to select keys from the log item's payload. Each
--   <a>LogItem</a> instance describes what keys should be retained for
--   each Verbosity level. Use the <a>payloadObject</a> utility for
--   extracting the keys that should be written.
--   
--   Scribes provide a finalizer IO action (<a>scribeFinalizer</a>) that is
--   meant to synchronously flush any remaining writes and clean up any
--   resources acquired when the scribe was created. Internally, katip
--   keeps a buffer for each scribe's writes. When <a>closeScribe</a> or
--   <a>closeScribes</a> is called, that buffer stops accepting new log
--   messages and after the last item in its buffer is sent to
--   <a>liPush</a>, calls the finalizer. Thus, when the finalizer returns,
--   katip can assume that all resources are cleaned up and all log
--   messages are durably written.
--   
--   While katip internally buffers messages per <a>ScribeSettings</a>, it
--   sends them one at a time to the scribe. Depending on the scribe
--   itself, it may make sense for that scribe to keep its own internal
--   buffer to batch-send logs if writing items one at a time is not
--   efficient. The scribe implementer must be sure that on finalization,
--   all writes are committed synchronously.
--   
--   Signature of a function passed to <a>Scribe</a> constructor and
--   mkScribe* functions that decides which messages to be logged.
--   Typically filters based on <a>Severity</a>, but can be combined with
--   other, custom logic with <a>permitAND</a> and <a>permitOR</a>
type PermitFunc = forall a. Item a -> IO Bool

-- | AND together 2 permit functions
permitAND :: PermitFunc -> PermitFunc -> PermitFunc

-- | OR together 2 permit functions
permitOR :: PermitFunc -> PermitFunc -> PermitFunc

-- | Should this item be logged given the user's maximum severity? Most new
--   scribes will use this as a base for their <a>PermitFunc</a>
permitItem :: Monad m => Severity -> Item a -> m Bool

-- | Constrain payload based on verbosity. Backends should use this to
--   automatically bubble higher verbosity levels to lower ones.
payloadObject :: LogItem a => Verbosity -> a -> Object

-- | Convert log item to its JSON representation while trimming its payload
--   based on the desired verbosity. Backends that push JSON messages
--   should use this to obtain their payload.
itemJson :: LogItem a => Verbosity -> Item a -> Value

-- | Provides a simple transformer that defines a <a>KatipContext</a>
--   instance for a fixed namespace and context. Just like <a>KatipT</a>,
--   you should use this if you prefer an explicit transformer stack and
--   don't want to (or cannot) define <a>KatipContext</a> for your monad .
--   This is the slightly more powerful version of KatipT in that it
--   provides KatipContext instead of just Katip. For instance:
--   
--   <pre>
--   threadWithLogging = do
--     le &lt;- getLogEnv
--     ctx &lt;- getKatipContext
--     ns &lt;- getKatipNamespace
--     forkIO $ runKatipContextT le ctx ns $ do
--       $(logTM) InfoS "Look, I can log in IO and retain context!"
--       doOtherStuff
--   </pre>
data KatipContextT m a
runKatipContextT :: LogItem c => LogEnv -> c -> Namespace -> KatipContextT m a -> m a
