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


-- | Structured logging solution (base package)
--   
--   A library that provides a way to record structured log messages. Use
--   this package in conjunction with 'log-elasticsearch' or
--   'log-postgres', depending on which back end you need.
@package log-base
@version 0.7.4.0


-- | Basic data types used throughout the package.
module Log.Data

-- | Available log levels.
data LogLevel
LogAttention :: LogLevel
LogInfo :: LogLevel
LogTrace :: LogLevel
showLogLevel :: LogLevel -> Text

-- | This function is partial.
readLogLevel :: Text -> LogLevel

-- | Represents message to be logged.
data LogMessage
LogMessage :: !Text -> ![Text] -> !UTCTime -> !LogLevel -> !Text -> !Value -> LogMessage

-- | Component of an application.
[lmComponent] :: LogMessage -> !Text

-- | Application log domain.
[lmDomain] :: LogMessage -> ![Text]

-- | Time of the logged event.
[lmTime] :: LogMessage -> !UTCTime

-- | Log level.
[lmLevel] :: LogMessage -> !LogLevel

-- | Message to be logged.
[lmMessage] :: LogMessage -> !Text

-- | Additional data associated with the message.
[lmData] :: LogMessage -> !Value

-- | Render a <a>LogMessage</a> to <tt>Text</tt>.
showLogMessage :: Maybe UTCTime -> LogMessage -> Text
instance GHC.Show.Show Log.Data.LogMessage
instance GHC.Classes.Eq Log.Data.LogMessage
instance GHC.Show.Show Log.Data.LogLevel
instance GHC.Classes.Ord Log.Data.LogLevel
instance GHC.Classes.Eq Log.Data.LogLevel
instance GHC.Enum.Bounded Log.Data.LogLevel
instance Data.Aeson.Types.ToJSON.ToJSON Log.Data.LogMessage
instance Data.Aeson.Types.FromJSON.FromJSON Log.Data.LogMessage
instance Control.DeepSeq.NFData Log.Data.LogMessage
instance Data.Aeson.Types.ToJSON.ToJSON Log.Data.LogLevel
instance Data.Aeson.Types.FromJSON.FromJSON Log.Data.LogLevel
instance Control.DeepSeq.NFData Log.Data.LogLevel


-- | The <a>MonadLog</a> type class of monads with logging capabilities.
module Log.Class

-- | This is the simplest representation of UTC. It consists of the day
--   number, and a time offset from midnight. Note that if a day has a leap
--   second added to it, it will have 86401 seconds.
data UTCTime

-- | Class of monads which carry the notion of the current time.
class Monad m => MonadTime (m :: Type -> Type)
currentTime :: MonadTime m => m UTCTime

-- | Represents the family of monads with logging capabilities. Each
--   <a>MonadLog</a> carries with it some associated state (the logging
--   environment) that can be modified locally with <a>localData</a> and
--   <a>localDomain</a>.
class MonadTime m => MonadLog m

-- | Write a message to the log.
logMessage :: MonadLog m => UTCTime -> LogLevel -> Text -> Value -> m ()

-- | Extend the additional data associated with each log message locally.
localData :: MonadLog m => [Pair] -> m a -> m a

-- | Extend the current application domain locally.
localDomain :: MonadLog m => Text -> m a -> m a

-- | Log a message and its associated data using current time as the event
--   time and the <a>LogAttention</a> log level.
logAttention :: (MonadLog m, ToJSON a) => Text -> a -> m ()

-- | Log a message and its associated data using current time as the event
--   time and the <a>LogInfo</a> log level.
logInfo :: (MonadLog m, ToJSON a) => Text -> a -> m ()

-- | Log a message and its associated data using current time as the event
--   time and the <a>LogTrace</a> log level.
logTrace :: (MonadLog m, ToJSON a) => Text -> a -> m ()

-- | Like <a>logAttention</a>, but without any additional associated data.
logAttention_ :: MonadLog m => Text -> m ()

-- | Like <a>logInfo</a>, but without any additional associated data.
logInfo_ :: MonadLog m => Text -> m ()

-- | Like <a>logTrace</a>, but without any additional associated data.
logTrace_ :: MonadLog m => Text -> m ()
instance (Log.Class.MonadLog m, GHC.Base.Monad (t m), Control.Monad.Trans.Control.MonadTransControl t) => Log.Class.MonadLog (t m)


-- | A logger that produces in-memory <tt>Text</tt> values. Mainly useful
--   for testing.
module Log.Backend.Text

-- | Create an in-memory logger for the duration of the given action,
--   returning both the result of the action and the logger's output as a
--   <tt>Text</tt> value afterwards.
withSimpleTextLogger :: (Logger -> IO r) -> IO (Text, r)


-- | The <a>Logger</a> type of logging back-ends.
module Log.Logger

-- | An object used for communication with a logger thread that outputs
--   <a>LogMessage</a>s using e.g. PostgreSQL, Elasticsearch or stdout
--   (depending on the back-end chosen).
data Logger

-- | Start a logger thread that consumes one queued message at a time.
mkLogger :: Text -> (LogMessage -> IO ()) -> IO Logger

-- | Start an asynchronous logger thread that consumes all queued messages
--   once per second. Uses a bounded queue internally to avoid space leaks.
--   To make sure that the messages get written out in the presence of
--   exceptions, use high-level wrappers like <a>withLogger</a>,
--   <a>withElasticSearchLogger</a> or <a>withBulkStdOutLogger</a> instead
--   of this function directly.
--   
--   Note: some messages can be lost when the main thread shuts down
--   without making sure that all logger threads have written out all
--   messages, because in that case child threads are not given a chance to
--   clean up by the RTS. This is apparently a feature:
--   <a>https://mail.haskell.org/pipermail/haskell-cafe/2014-February/112754.html</a>
--   
--   To work around this issue, make sure that the main thread doesn't exit
--   until all its children have terminated. The <tt>async</tt> package
--   makes this easy.
--   
--   Problematic example:
--   
--   <pre>
--   import Control.Concurrent.Async
--   
--   main :: IO ()
--   main = do
--      logger &lt;- <a>elasticSearchLogger</a>
--      a &lt;- <a>async</a> (<a>withElasticSearchLogger</a> $ \logger -&gt;
--                  <a>runLogT</a> "main" logger $ <a>logTrace_</a> "foo")
--      -- Main thread exits without waiting for the child
--      -- to finish and without giving the child a chance
--      -- to do proper cleanup.
--   </pre>
--   
--   Fixed example:
--   
--   <pre>
--   import Control.Concurrent.Async
--   
--   main :: IO ()
--   main = do
--      logger &lt;- <a>elasticSearchLogger</a>
--      a &lt;- <a>async</a> (<a>withElasticSearchLogger</a> $ \logger -&gt;
--                  <a>runLogT</a> "main" logger $ <a>logTrace_</a> "foo")
--      <a>wait</a> a
--      -- Main thread waits for the child to finish, giving
--      -- it a chance to shut down properly. This works even
--      -- in the presence of exceptions in the child thread.
--   </pre>
mkBulkLogger :: Text -> ([LogMessage] -> IO ()) -> IO () -> IO Logger

-- | Like <a>mkBulkLogger</a>, but with configurable queue size and thread
--   delay.
mkBulkLogger' :: Int -> Int -> Text -> ([LogMessage] -> IO ()) -> IO () -> IO Logger

-- | Execute logger to serialize a <a>LogMessage</a>.
execLogger :: Logger -> LogMessage -> IO ()

-- | Wait until all <a>LogMessage</a>s stored in the internal queue are
--   serialized.
waitForLogger :: Logger -> IO ()

-- | Shutdown the logger thread associated with this <a>Logger</a> object.
--   Subsequent attempts to write messages via this <a>Logger</a> will
--   result in an exception.
shutdownLogger :: Logger -> IO ()


-- | Bulk stdout logging back-end, useful mainly for testing.
module Log.Backend.StandardOutput.Bulk

-- | Create a <a>bulkStdoutLogger</a> for the duration of the given action,
--   and shut it down afterwards, making sure that all buffered messages
--   are actually written to stdout. Flushes <a>stdout</a> on each bulk
--   write.
withBulkStdOutLogger :: (Logger -> IO r) -> IO r

-- | Start an asynchronous logger thread that prints messages to standard
--   output.
--   
--   Please use <tt>withBulkStdOutLogger'</tt> instead, which is more
--   exception-safe (see the note attached to <a>mkBulkLogger</a>).

-- | <i>Deprecated: Use <a>withBulkStdOutLogger</a> instead!</i>
bulkStdoutLogger :: IO Logger


-- | Stdout logging back-end.
module Log.Backend.StandardOutput

-- | Simple, synchronous logger that prints messages to standard output.
--   Flushes <a>stdout</a> on each call to <a>loggerWriteMessage</a>. Use
--   <a>withBulkStdOutLogger</a> if you want buffering.

-- | <i>Deprecated: Use <a>withSimpleStdOutLogger</a></i>
simpleStdoutLogger :: Logger

-- | Create a logger that prints messages to standard output.

-- | <i>Deprecated: Use <a>withSimpleStdOutLogger</a></i>
stdoutLogger :: IO Logger

-- | Create a <tt>simpleStdoutlogger</tt> for the duration of the given
--   action, making sure that stdout is flushed afterwards.
withSimpleStdOutLogger :: (Logger -> IO r) -> IO r


-- | The <a>LogT</a> monad transformer for adding logging capabilities to
--   any monad.
module Log.Monad

-- | An object used for communication with a logger thread that outputs
--   <a>LogMessage</a>s using e.g. PostgreSQL, Elasticsearch or stdout
--   (depending on the back-end chosen).
data Logger

-- | The state that every <a>LogT</a> carries around.
data LoggerEnv
LoggerEnv :: !Logger -> !Text -> ![Text] -> ![Pair] -> LoggerEnv

-- | The <a>Logger</a> to use.
[leLogger] :: LoggerEnv -> !Logger

-- | Current application component.
[leComponent] :: LoggerEnv -> !Text

-- | Current application domain.
[leDomain] :: LoggerEnv -> ![Text]

-- | Additional data to be merged with the log message's data.
[leData] :: LoggerEnv -> ![Pair]
type InnerLogT = ReaderT LoggerEnv

-- | Monad transformer that adds logging capabilities to the underlying
--   monad.
newtype LogT m a
LogT :: InnerLogT m a -> LogT m a
[unLogT] :: LogT m a -> InnerLogT m a

-- | Run a <a>LogT</a> computation.
--   
--   Note that in the case of asynchronous/bulk loggers <a>runLogT</a>
--   doesn't guarantee that all messages are actually written to the log
--   once it finishes. Use <tt>withPGLogger</tt> or
--   <tt>withElasticSearchLogger</tt> for that.
runLogT :: Text -> Logger -> LogT m a -> m a

-- | Transform the computation inside a <a>LogT</a>.
mapLogT :: (m a -> n b) -> LogT m a -> LogT n b
instance Control.Monad.State.Class.MonadState s m => Control.Monad.State.Class.MonadState s (Log.Monad.LogT m)
instance Control.Monad.Writer.Class.MonadWriter w m => Control.Monad.Writer.Class.MonadWriter w (Log.Monad.LogT m)
instance Control.Monad.Error.Class.MonadError e m => Control.Monad.Error.Class.MonadError e (Log.Monad.LogT m)
instance Control.Monad.Trans.Class.MonadTrans Log.Monad.LogT
instance Control.Monad.Catch.MonadThrow m => Control.Monad.Catch.MonadThrow (Log.Monad.LogT m)
instance GHC.Base.MonadPlus m => GHC.Base.MonadPlus (Log.Monad.LogT m)
instance Control.Monad.Catch.MonadMask m => Control.Monad.Catch.MonadMask (Log.Monad.LogT m)
instance Control.Monad.IO.Class.MonadIO m => Control.Monad.IO.Class.MonadIO (Log.Monad.LogT m)
instance Control.Monad.Catch.MonadCatch m => Control.Monad.Catch.MonadCatch (Log.Monad.LogT m)
instance Control.Monad.Base.MonadBase b m => Control.Monad.Base.MonadBase b (Log.Monad.LogT m)
instance GHC.Base.Monad m => GHC.Base.Monad (Log.Monad.LogT m)
instance GHC.Base.Functor m => GHC.Base.Functor (Log.Monad.LogT m)
instance GHC.Base.Applicative m => GHC.Base.Applicative (Log.Monad.LogT m)
instance GHC.Base.Alternative m => GHC.Base.Alternative (Log.Monad.LogT m)
instance Control.Monad.Reader.Class.MonadReader r m => Control.Monad.Reader.Class.MonadReader r (Log.Monad.LogT m)
instance Control.Monad.Morph.MFunctor Log.Monad.LogT
instance Control.Monad.Trans.Control.MonadTransControl Log.Monad.LogT
instance Control.Monad.Trans.Control.MonadBaseControl b m => Control.Monad.Trans.Control.MonadBaseControl b (Log.Monad.LogT m)
instance (Control.Monad.Base.MonadBase GHC.Types.IO m, Control.Monad.Time.MonadTime m) => Log.Class.MonadLog (Log.Monad.LogT m)


-- | Structured logging solution with multiple backends.
--   
--   <pre>
--   {-# LANGUAGE OverloadedStrings #-}
--   
--   module Main where
--   
--   import Log
--   import Log.Backend.ElasticSearch
--   
--   import System.Random
--   
--   main :: IO ()
--   main = do
--     let config = <a>ElasticSearchConfig</a> {
--           esServer  = "<a>http://localhost:9200"</a>,
--           esIndex   = "logs",
--           esMapping = "log"
--           }
--     <a>withElasticSearchLogger</a> config randomIO $ \logger -&gt; do
--       <a>runLogT</a> "main" logger $ do
--         <a>logTrace_</a> "foo"
--   </pre>
module Log

-- | Create a <a>Value</a> from a list of name/value <a>Pair</a>s. If
--   duplicate keys arise, earlier keys and their associated values win.
object :: [Pair] -> Value
(.=) :: (KeyValue kv, ToJSON v) => Text -> v -> kv
infixr 8 .=
