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


-- | Typeful hierarchical structured logging using di, mtl and df1.
--   
--   Typeful hierarchical structured logging using di, mtl and df1.
--   
--   This is meta-package bringing in together things from the
--   <tt>di-core</tt>, <tt>di-monad</tt>, <tt>di-handle</tt> and
--   <tt>di-df1</tt> libraries.
--   
--   See the <a>Di</a> module for more documentation.
@package di
@version 1.0.1


-- | This module is a highly opinionated, basic, and yet sufficient choice
--   of a concrete stack of logging solutions belonging to the <a>di
--   logging ecosystem</a>—an otherwise rather general ecosystem, flexible
--   and full of choices.
--   
--   For most logging scenarios out there, the choices made here should
--   suffice, but if you find these are not sufficient for your particular
--   use case, please refer to other libraries of the <i>di logging
--   ecosystem</i> such as <a>di-core</a>, <a>di-monad</a>,
--   <a>di-handle</a>, or <a>di-df1</a>, and you are likely to find a
--   compatible and composable solution there. For this reason, staring
--   with this package rather than one of the those other lower-level
--   packages is always recommended.
--   
--   The choices made here are:
--   
--   <ul>
--   <li>We encourage a <a>mtl</a> approach through a typeclass called
--   <a>MonadDi</a>, for which all of the monad transformers in
--   <a>transformers</a> and <a>pipes</a> have instances.</li>
--   <li>We provide our own <a>DiT</a> monad transformer which has a
--   <tt>MonadDi</tt> instance, as well as instances for all the relevant
--   typeclasses in the <a>base</a>, <a>mtl</a>, and <a>exceptions</a>
--   libraries. All of the <tt>MonadDi</tt> instances exported by this
--   package expect a <tt>DiT</tt> transformer in the stack somewhere, and
--   defer all work to it.</li>
--   <li>We embrace the <a>df1</a> hierarchical structured logging format,
--   both at the type-level and when rendering the log lines as text. Most
--   notably, this means that we embrace the <i>df1</i> importance
--   <a>Level</a>s.</li>
--   <li>We commit logs to the outside world by printing them to
--   <a>stderr</a>.</li>
--   </ul>
--   
--   You will notice that some of the functions in this module mention the
--   types <a>Level</a>, <a>Path</a> and <a>Message</a>, and some other
--   functions talk about <tt>level</tt>, <tt>path</tt> and <tt>msg</tt>
--   type variables. This is because even while our particular set of
--   choices require some monomorphic types, as demonstrated by the
--   <a>Df1</a> and <a>MonadDf1</a> type-synonyms, the larger <i>di logging
--   ecosystem</i> treats these values polymorphically, so they will show
--   up in the types in one way or another, either in concrete or
--   polymorphic form. This can seem a bit noisy, but the good news is that
--   if, for example, want to call a third party library that uses other
--   types for conveying the idea of a “log importance level” or a “log
--   message”, then you can do so if you can convert between these
--   different types. You are of course encouraged to use the <a>Df1</a>
--   and <a>MonadDf1</a> type-synonyms yourself. For more information about
--   this, see <a>Di.Monad</a> and <a>Di.Core</a>, but not today.
--   
--   The intended usage of this module is:
--   
--   <pre>
--   import qualified <a>Di</a>
--   </pre>
module Di

-- | Obtain a <a>Di</a> that will write logs in the <i>df1</i> format to
--   <a>stderr</a>.
--   
--   Generally, you will want to call <a>new</a> just once per application,
--   right from your <tt>main</tt> function. For example:
--   
--   <pre>
--   main :: <a>IO</a> ()
--   main = do
--      <a>new</a> $ \di -&gt; do
--         -- <i>The rest of your program goes here.</i>
--         -- <i>You can start logging right away.</i>
--         <a>runDiT</a> di $ do
--             <a>notice</a> "Welcome to my program!"
--             -- <i>You can use <a>push</a> to separate different</i>
--             -- <i>logging scopes of your program:</i>
--             <a>push</a> "initialization" $ do
--                 -- <i>something something do initialization</i>
--                 <a>notice</a> "Starting web server"
--             <a>push</a> "server" $ do
--                 -- <i>And you can use <a>attr</a> to add metadata to</i>
--                 -- <i>messages logged within a particular scope.</i>
--                 <a>attr</a> "port" "80" $ do
--                      <a>info</a> "Listening for new clients"
--                      clientAddress &lt;- <i>somehow get a client connection</i>
--                      <a>push</a> "handler" $ do
--                         <a>attr</a> "client-address" clientAddress $ do
--                            <a>info</a> "Connection established"
--   </pre>
--   
--   That program will render something like this to <a>stderr</a> (in
--   colors!):
--   
--   <pre>
--   2018-05-06T19:48:06.194579393Z NOTICE Welcome to my program!
--   2018-05-06T19:48:06.195041422Z /initialization NOTICE Starting web server
--   2018-05-06T19:48:06.195052862Z /server port=80 INFO Listening for new clients
--   2018-05-06T19:48:06.195059084Z /server port=80 /handler client%2daddress=192%2e168%2e0%2e25%3a32528 INFO Connection established
--   </pre>
--   
--   (Unrelated: Notice how <i>df1</i> escapes pretty much all punctuation
--   characters. This is temporal until <i>df1</i> is formalized and a more
--   limited set of punctuation characters is reserved.)
new :: (MonadIO m, MonadMask m) => (Di Level Path Message -> m a) -> m a

-- | Convenience type-synonym for a <a>Di</a> restricted to all the
--   <i>df1</i> monomorphic types.
--   
--   <pre>
--   <a>Df1</a> == <a>Di</a> <a>Level</a> <a>Path</a> <a>Message</a>
--      :: *
--   </pre>
--   
--   This type-synonym is not used within the <tt>di-df1</tt> library
--   itself because all functions exposed in the library have more general
--   types. However, users are encouraged to use <a>Df1</a> if they find it
--   useful to reduce boilerplate and improve type inferrence.
type Df1 = Di Level Path Message

-- | Convenience type-synonym for a <a>MonadDi</a> restricted to all the
--   <i>df1</i> monomorphic types.
--   
--   <pre>
--   <a>MonadDf1</a> == <a>MonadDi</a> <a>Level</a> <a>Path</a> <a>Message</a>
--      :: (* -&gt; *) -&gt; <a>Constraint</a>
--   
--   <a>MonadDf1</a> m == <a>MonadDi</a> <a>Level</a> <a>Path</a> <a>Message</a> m
--      :: <a>Constraint</a>
--   </pre>
--   
--   This type-synonym is not used within the <tt>di-df1</tt> library
--   itself because all functions exposed in the library have more general
--   types. However, users are encouraged to use <a>MonadDf1</a> if they
--   find it useful to reduce boilerplate and improve type inferrence.
type MonadDf1 = MonadDi Level Path Message

-- | Push a new <a>Segment</a> to the <a>MonadDi</a>.
push :: MonadDi level Path msg m => Segment -> m a -> m a

-- | <a>Path</a> represents the hierarchical structure of logged messages.
--   
--   For example, consider a <i>df1</i> log line as like the following:
--   
--   <pre>
--   1999-12-20T07:11:39.230553031Z <i>foo x=a y=b </i>qux z=c z=d WARNING Something
--   </pre>
--   
--   For that line, the <a>log_path</a> attribute of the <a>Log</a>
--   datatype will contain the following:
--   
--   <pre>
--   [ <a>Push</a> (<a>segment</a> "foo")
--   , <a>Attr</a> (<a>key</a> "x") (<a>value</a> "a")
--   , <a>Attr</a> (<a>key</a> "y") (<a>value</a> "b")
--   , <a>Push</a> (<a>segment</a> "qux")
--   , <a>Attr</a> (<a>key</a> "z") (<a>value</a> "c")
--   , <a>Attr</a> (<a>key</a> "z") (<a>value</a> "d")
--   ] :: <a>Seq</a> <a>Path</a>
--   </pre>
--   
--   Please notice that <tt>[] :: <a>Seq</a> <a>Path</a></tt> is a valid
--   path insofar as <i>df1</i> is concerned, and that <a>Attr</a> and
--   <a>Push</a> can be juxtapositioned in any order.
data Path

-- | A path segment.
--   
--   If you have the <tt>OverloadedStrings</tt> GHC extension enabled, you
--   can build a <a>Segment</a> using a string literal:
--   
--   <pre>
--   "foo" :: <a>Segment</a>
--   </pre>
--   
--   Otherwise, you can use <a>fromString</a> or the <a>Segment</a>
--   constructor directly.
data Segment
segment :: Text -> Segment

-- | Push a new attribute <a>Key</a> and <a>Value</a> to the
--   <a>MonadDi</a>.
attr :: MonadDi level Path msg m => Key -> Value -> m a -> m a

-- | An attribute key (see <a>Attr</a>).
--   
--   If you have the <tt>OverloadedStrings</tt> GHC extension enabled, you
--   can build a <a>Key</a> using a string literal:
--   
--   <pre>
--   "foo" :: <a>Key</a>
--   </pre>
--   
--   Otherwise, you can use <a>fromString</a> or the <a>key</a> function.
--   
--   Please keep in mind that <a>Key</a> will always strip surrounding
--   whitespace. That is:
--   
--   <pre>
--   "x" :: <a>Key</a>  ==  " x"  == "x " == " x "
--   </pre>
data Key
key :: Text -> Key

-- | An attribute value (see <a>Attr</a>).
--   
--   If you have the <tt>OverloadedStrings</tt> GHC extension enabled, you
--   can build a <a>Value</a> using a string literal:
--   
--   <pre>
--   "foo" :: <a>Value</a>
--   </pre>
--   
--   Otherwise, you can use <a>fromString</a> or the <a>value</a> function.
--   
--   Please keep in mind that <a>value</a> will always strip surrounding
--   whitespace. That is:
--   
--   <pre>
--   "x" :: <a>Value</a>  ==  " x"  == "x " == " x "
--   </pre>
data Value
value :: Text -> Value

-- | Importance of the logged message.
--   
--   These levels, listed in increasing order of importance, correspond to
--   the levels used by <a>syslog(3)</a>.
data Level

-- | A message text.
--   
--   If you have the <tt>OverloadedStrings</tt> GHC extension enabled, you
--   can build a <a>Message</a> using a string literal:
--   
--   <pre>
--   "foo" :: <a>Message</a>
--   </pre>
--   
--   Please keep in mind that <a>Message</a> will always strip surrounding
--   whitespace. That is:
--   
--   <pre>
--   "x" :: <a>Message</a>  ==  " x"  == "x " == " x "
--   </pre>
data Message

-- | Log a message intended to be useful only when deliberately debugging a
--   program.
debug :: MonadDi Level path Message m => Message -> m ()

-- | Log an informational message.
info :: MonadDi Level path Message m => Message -> m ()

-- | Log a condition that is not an error, but should possibly be handled
--   specially.
notice :: MonadDi Level path Message m => Message -> m ()

-- | Log a warning condition, such as an exception being gracefully handled
--   or some missing configuration setting being assigned a default value.
warning :: MonadDi Level path Message m => Message -> m ()

-- | Log an error condition, such as an unhandled exception.
error :: MonadDi Level path Message m => Message -> m ()

-- | Log a condition that should be corrected immediately, such as a
--   corrupted database.
alert :: MonadDi Level path Message m => Message -> m ()

-- | Log a critical condition that could result in system failure, such as
--   a disk running out of space.
critical :: MonadDi Level path Message m => Message -> m ()

-- | Log a message stating that the system is unusable.
emergency :: MonadDi Level path Message m => Message -> m ()

-- | Convenience type-synonym for a <a>DiT</a> restricted to all the
--   <i>df1</i> monomorphic types.
--   
--   <pre>
--   <a>Df1T</a> == <a>DiT</a> <a>Level</a> <a>Path</a> <a>Message</a>
--      :: (* -&gt; *) -&gt; * -&gt; *
--   
--   <a>Df1T</a> m == <a>DiT</a> <a>Level</a> <a>Path</a> <a>Message</a> m
--      :: * -&gt; *
--   
--   <a>Df1T</a> m a == <a>DiT</a> <a>Level</a> <a>Path</a> <a>Message</a> m a
--      :: *
--   </pre>
--   
--   This type-synonym is not used within the <tt>di-df1</tt> library
--   itself because all functions exposed in the library have more general
--   types. However, users are encouraged to use <a>MonadDf1</a> if they
--   find it useful to reduce boilerplate and improve type inferrence.
type Df1T = DiT Level Path Message

-- | Run a <a>DiT</a>.
--   
--   <pre>
--   forall di.
--      <a>runDiT</a> di (<a>diT</a> (\nat' di' -&gt; pure (nat', di')))
--          == <a>pure</a> (<a>natSTM</a>, di)
--   </pre>
--   
--   This is like <a>runDiT'</a>, but specialized to run with an underlying
--   <a>MonadIO</a>.
--   
--   <pre>
--   <a>runDiT</a>  ==  <a>runDiT'</a> (<a>liftIO</a> . <a>atomically</a>)
--   </pre>
--   
--   Please notice that <a>runDiT</a> doesn't perform a <a>flush</a> on the
--   given <a>Di</a> before returning. You are responsible for doing that
--   (or, more likely, <a>new</a> will do it for you).
--   
--   Also, notice that <a>runDiT</a> is a <i>monad morphism</i> from
--   <tt><a>DiT</a> m</tt> to <tt>m</tt>.
runDiT :: MonadIO m => Di level path msg -> DiT level path msg m a -> m a

-- | Lift a monad morphism from <tt>m</tt> to <tt>n</tt> to a monad
--   morphism from <tt><a>DiT</a> level path msg m</tt> to <tt><a>DiT</a>
--   n</tt>.
--   
--   Notice that <a>DiT</a> itself is not a functor in the category of
--   monads, so it can't be an instance of <a>MFunctor</a> from the
--   <a>mmorph</a> package. However, it becomes one if you pair it with a
--   natural transformation <tt><tt>nat</tt> :: forall x. n x -&gt; m
--   x</tt>. That is:
--   
--   <pre>
--   forall nat.  <i>such that <tt>nat</tt> is a natural transformation</i>
--      <a>hoistDiT</a> nat  ==  <a>hoist</a>
--   </pre>
--   
--   In practical terms, it means that most times you can “hoist” a
--   <a>DiT</a> anyway, just not through <a>hoist</a>.
hoistDiT :: () => forall x. () => n x -> m x -> forall x. () => m x -> n x -> DiT level path msg m a -> DiT level path msg n a
