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

-- | Trek through your code forest and make logs
--   
--   This is a logging facility. Yes, there are many, and this is the one
--   with a beard, wearing flannel and boots, that gets the job done. It's
--   not the fanciest, it doesn't have a cargo-van full of features. This
--   logger is designed to be straightforward to use, provide a good set of
--   standard features, and be useable across a broad set of code.
--   
--   
--   
- Logging itself is a monadic activity. This activity is most often
--   performed in a monad stack with a MonadIO context to allow writing to
--   files.
--   
- The specific logging action implementations are managed separately
--   from the actions of logging messages in the target code. This allows
--   logging to be configurable and the manner of logging to be specified
--   at startup time without requiring changes in the code from which log
--   messages are being generated.
--   
- The logging implementation code can use contravariant functors to
--   adjust existing logging.
--   
- Main code will typically retrieve the logging actions from a
--   Reader context in your monad stack. That said, Log actions are not
--   tied to an enclosing Monad. There are helpers to support a Monad which
--   can store Log actions, but Log actions can also be explicitly passed
--   and used.
--   
- The prettyprinter package is used for formatting.
--   
@package lumberjack
@version 1.0.3.0

-- | This module defines a general logging facility that can be used to
--   output log messages to various targets.
--   
--   The LogAction is the fundamental operation that decides how to
--   log a provided message.
--   
--   Code wishing to output a logged message simply uses the LogAction
--   object:
--   
--   
--   writeLog action msg
--   
--   
--   For convenience, the LogAction can be stored in the local operating
--   monad context, from which it can be retrieved (and modified). A monad
--   which can supply a LogAction is a member of the HasLog class, and the
--   writeLogM function will automatically retrieve the LogAction
--   from the monad and write to it:
--   
--   
--   writeLogM msg
--   
--   
--   LogActions can be combined via Semigroup operations (<>) and the
--   resulting LogAction will perform both actions with each message. The
--   Monoidal mempty LogAction simply does nothing. For example, logging to
--   both a file and stdout can be done by logToFile <>
--   logToStdout.
--   
--   LogActions are also Contravariant (and Divisible and Decidable) to
--   allow easy conversion of a LogAction for the base message type into a
--   LogAction for a different message type (or types) that can be
--   converted to (and combined into) the base message type.
module Lumberjack

-- | The LogAction holds the ability to log a message of type msg
--   (the second parameter) via a monad m (the first parameter).
--   
--   LogActions are semigroup and monoid combineable, which results in both
--   LogActions being taken (or no action in the case of mempty), and
--   contravariant to allow the msg to be modified via function prior to
--   being logged (as well as Divisible and Decidable).
newtype LogAction m msg
LogAction :: (msg -> m ()) -> LogAction m msg
[writeLog] :: LogAction m msg -> msg -> m ()

-- | Any monad which will support retrieving a LogAction from the Monad's
--   environment should support the HasLog class.
class Monad m => HasLog msg m
getLogAction :: HasLog msg m => m (LogAction m msg)

-- | An instance of the LoggingMonad class can be defined for the
--   base monadic logging action to allow adjusting that logging action.
--   This class can only be instantiated (and only needs to be
--   instantiated) for the base message type; all other message types will
--   use contramapping to convert their message type to the
--   LoggingMonad base message type.
class (Monad m, HasLog msg m) => LoggingMonad msg m
adjustLogAction :: LoggingMonad msg m => (forall k. LogAction k msg -> LogAction k msg) -> m a -> m a

-- | This obtains the LogAction from the current monad's environment
--   to use for outputting the log message. Most code will use this
--   function.
writeLogM :: HasLog msg m => msg -> m ()

-- | Ensures that the LogAction does not fail if the logging operation
--   itself throws an exception (the exception is ignored).
safeLogAction :: MonadCatch m => LogAction m msg -> LogAction m msg

-- | The logFilter can be used on a LogAction to determine which messages
--   the LogAction should be invoked for (only those for which the filter
--   function returns True).
logFilter :: Applicative m => (msg -> Bool) -> LogAction m msg -> LogAction m msg

-- | The Severity indicates the relative importance of the logging message.
--   This can be useful for filtering log messages.
data Severity
Debug :: Severity
Info :: Severity
Warning :: Severity
Error :: Severity

-- | The LogType indicates what type of message this is. These are printed
--   on the log line and can be used for filtering different types of log
--   messages.
data LogType
Progress :: LogType
FuncEntry :: LogType
FuncExit :: LogType
MiscLog :: LogType
UserOp :: LogType

-- | Each logged output is described by a LogMessage object.
data LogMessage
LogMessage :: LogType -> Severity -> UTCTime -> [(Text, Text)] -> Text -> LogMessage
[logType] :: LogMessage -> LogType
[logLevel] :: LogMessage -> Severity
[logTime] :: LogMessage -> UTCTime
[logTags] :: LogMessage -> [(Text, Text)]
[logText] :: LogMessage -> Text

-- | Helper routine to return an empty LogMessage, whose fields can then be
--   updated.
msgWith :: LogMessage

-- | This type is a Constraint that should be applied to any client
--   function that will perform logging in a monad context. The
--   msg is the type of message that will be logged, and the
--   m is the monad under which the logging is performed.
type WithLog msg m = (HasLog msg m)

-- | Log messages can have any number of key/value tags applied to them.
--   This function establishes a new key/value tag pair that will be in
--   effect for the monadic operation passed as the third argument.
--   withLogTag tname tval op = local (adjustLogAction $ addLogTag tname
--   tval) op
withLogTag :: LoggingMonad LogMessage m => Text -> Text -> m a -> m a

-- | Add the current timestamp to the LogMessage being logged
addLogActionTime :: MonadIO m => LogAction m LogMessage -> LogAction m LogMessage

-- | Standard LogMessage rendering function for converting a
--   LogMessage into plain Text (no colors or other
--   highlighting). This can be used as the default converter for a logger
--   (via contramap).
cvtLogMessageToPlainText :: LogMessage -> Text

-- | Standard LogMessage rendering function to convert a
--   LogMessage into Text with ANSI terminal colors and
--   bolding and other styling. This can be used as the default converter
--   for a logger (via contramap).
cvtLogMessageToANSITermText :: LogMessage -> Text

-- | This operator is a convenient infix operator for logging a Text
--   message. This is especially useful when used in conjunction with the
--   OverloadedStrings language pragma:
--   
--   
--   >>> warning|# "This is your last warning"
--   
--   >>> error|# "Failure has occurred"
--   
(|#) :: (LogMessage -> a) -> Text -> a
infixr 0 |#

-- | A wrapper for a function call that will call the provided
--   LogAction with a Debug log on entry to the function and
--   an Info log on exit from the function. The total amount of time
--   taken during execution of the function will be included in the exit
--   log message. No strictness is applied to the invoked monadic
--   operation, so the time taken may be misleading. Like
--   logFunctionCallM but needs an explicit LogAction whereas
--   logFunctionCallM will retrieve the LogAction from the
--   current monadic context.
logFunctionCall :: MonadIO m => LogAction m LogMessage -> Text -> m a -> m a

-- | A wrapper for a monadic function call that will Debug log on
--   entry to and Info log on exit from the function. The exit log
--   will also note the total amount of time taken during execution of the
--   function. Be advised that no strictness is applied to the internal
--   monadic operation, so the time taken may be misleading.
logFunctionCallM :: (MonadIO m, WithLog LogMessage m) => Text -> m a -> m a

-- | Called to output a log message to indicate that some progress in the
--   current activity has been made.
logProgress :: MonadIO m => LogAction m LogMessage -> Text -> m ()

-- | Called to output a log message within a HasLog monad to
--   indicate that some progress in the current activity has been made.
logProgressM :: (MonadIO m, WithLog LogMessage m) => Text -> m ()

-- | This is a helper function. The LogMessage normally wants a Text, but
--   show delivers a String, so tshow can be used to get the needed
--   format.
tshow :: Show a => a -> Text

-- | When using a simple IO monad, there is no ability to store a LogAction
--   in the base monad. The client can specify a specific HasLog instance
--   for IO that is appropriate to that client, and that HasLog can
--   optionally use the defaultGetIOLogAction as the
--   getLogAction implementation to log pretty messages with ANSI
--   styling to stdout.
--   
--   
--   instance HasLog Env Text IO where
--       getLogAction = return defaultGetIOLogAction
--   
defaultGetIOLogAction :: MonadIO m => LogAction m Text
instance GHC.Show.Show Lumberjack.Severity
instance GHC.Classes.Eq Lumberjack.Severity
instance GHC.Classes.Ord Lumberjack.Severity
instance GHC.Show.Show Lumberjack.LogType
instance GHC.Classes.Eq Lumberjack.LogType
instance GHC.Base.Semigroup Lumberjack.LogMessage
instance GHC.Base.Monoid Lumberjack.LogMessage
instance Prettyprinter.Internal.Pretty Lumberjack.LogMessage
instance Prettyprinter.Internal.Pretty Lumberjack.LogType
instance Prettyprinter.Internal.Pretty Lumberjack.Severity
instance GHC.Base.Applicative m => GHC.Base.Semigroup (Lumberjack.LogAction m a)
instance GHC.Base.Applicative m => GHC.Base.Monoid (Lumberjack.LogAction m a)
instance Data.Functor.Contravariant.Contravariant (Lumberjack.LogAction m)
instance GHC.Base.Applicative m => Data.Functor.Contravariant.Divisible.Divisible (Lumberjack.LogAction m)
instance GHC.Base.Applicative m => Data.Functor.Contravariant.Divisible.Decidable (Lumberjack.LogAction m)
instance Prettyprinter.Internal.Pretty Data.Time.Clock.Internal.UTCTime.UTCTime
