-- 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.9.0.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 LogMessage to Text. 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 -- | A logger that produces in-memory Text 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 -- Text value afterwards. withSimpleTextLogger :: (Logger -> IO r) -> IO (Text, r) -- | The Logger type of logging back-ends. module Log.Logger -- | The state that every LogT carries around. data LoggerEnv LoggerEnv :: !Logger -> !Text -> ![Text] -> ![Pair] -> LoggerEnv -- | The Logger 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] -- | An object used for communication with a logger thread that outputs -- LogMessages 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. -- -- Note: a bounded queue of size 1000000 is used internally to -- avoid unrestricted memory consumption. mkLogger :: Text -> (LogMessage -> IO ()) -> IO Logger -- | Like mkBulkLogger, but with configurable queue size. mkLogger' :: Int -> Text -> (LogMessage -> IO ()) -> IO Logger -- | Start an asynchronous logger thread that consumes all queued messages -- once per second. -- -- Note: a bounded queue of size 1000000 is used internally to -- avoid unrestricted memory consumption. -- -- To make sure that the messages get written out in the presence of -- exceptions, use high-level wrappers like withLogger, -- withElasticSearchLogger or withBulkStdOutLogger 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: -- https://mail.haskell.org/pipermail/haskell-cafe/2014-February/112754.html -- -- To work around this issue, make sure that the main thread doesn't exit -- until all its children have terminated. The async package -- makes this easy. -- -- Problematic example: -- --
-- import Control.Concurrent.Async -- -- main :: IO () -- main = do -- logger <- elasticSearchLogger -- a <- async (withElasticSearchLogger $ \logger -> -- runLogT "main" logger $ logTrace_ "foo") -- -- Main thread exits without waiting for the child -- -- to finish and without giving the child a chance -- -- to do proper cleanup. ---- -- Fixed example: -- --
-- import Control.Concurrent.Async -- -- main :: IO () -- main = do -- logger <- elasticSearchLogger -- a <- async (withElasticSearchLogger $ \logger -> -- runLogT "main" logger $ logTrace_ "foo") -- wait 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. --mkBulkLogger :: Text -> ([LogMessage] -> IO ()) -> IO () -> IO Logger -- | Like mkBulkLogger, but with configurable queue size and thread -- delay. mkBulkLogger' :: Int -> Int -> Text -> ([LogMessage] -> IO ()) -> IO () -> IO Logger -- | Execute logger to serialize a LogMessage. execLogger :: Logger -> LogMessage -> IO () -- | Wait until all LogMessages stored in the internal queue are -- serialized. waitForLogger :: Logger -> IO () -- | Shutdown the logger thread associated with this Logger object. -- Subsequent attempts to write messages via this Logger will -- result in an exception. shutdownLogger :: Logger -> IO () -- | The MonadLog 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 -- MonadLog carries with it some associated state (the logging -- environment) that can be modified locally with localData and -- localDomain. 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 -- | Get current LoggerEnv object. Useful for construction of -- logging functions that work in a different monad, see -- getLoggerIO as an example. getLoggerEnv :: MonadLog m => m LoggerEnv -- | Log a message and its associated data using current time as the event -- time and the LogAttention 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 LogInfo 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 LogTrace log level. logTrace :: (MonadLog m, ToJSON a) => Text -> a -> m () -- | Like logAttention, but without any additional associated data. logAttention_ :: MonadLog m => Text -> m () -- | Like logInfo, but without any additional associated data. logInfo_ :: MonadLog m => Text -> m () -- | Like logTrace, 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) -- | Bulk stdout logging back-end. module Log.Backend.StandardOutput.Bulk -- | Create an asynchronouis logger thread that prints messages to standard -- output once per second for the duration of the given action. Flushes -- stdout on each bulk write. withBulkStdOutLogger :: (Logger -> IO r) -> IO r -- | Create a bulk logger that prints messages in the JSON format to -- standard output once per second for the duration of the given action. -- Flushes stdout on each bulk write. withBulkJsonStdOutLogger :: (Logger -> IO r) -> IO r -- | Stdout logging back-end. module Log.Backend.StandardOutput -- | Create a simple, synchronous logger that prints messages to standard -- output and flushes stdout on each call to -- loggerWriteMessage for the duration of the given action. withSimpleStdOutLogger :: (Logger -> IO r) -> IO r -- | Create a logger that prints messages to standard output for the -- duration of the given action. withStdOutLogger :: (Logger -> IO r) -> IO r -- | Create a logger that prints messages in the JSON format to standard -- output for the duration of the given action. withJsonStdOutLogger :: (Logger -> IO r) -> IO r -- | The LogT monad transformer for adding logging capabilities to -- any monad. module Log.Monad -- | An object used for communication with a logger thread that outputs -- LogMessages using e.g. PostgreSQL, Elasticsearch or stdout -- (depending on the back-end chosen). data Logger -- | The state that every LogT carries around. data LoggerEnv LoggerEnv :: !Logger -> !Text -> ![Text] -> ![Pair] -> LoggerEnv -- | The Logger 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 LogT computation. -- -- Note that in the case of asynchronous/bulk loggers runLogT -- doesn't guarantee that all messages are actually written to the log -- once it finishes. Use withPGLogger or -- withElasticSearchLogger for that. runLogT :: Text -> Logger -> LogT m a -> m a -- | Transform the computation inside a LogT. mapLogT :: (m a -> n b) -> LogT m a -> LogT n b -- | Base implementation of logMessage for use with a specific -- LoggerEnv. Useful for reimplementation of MonadLog -- instance. logMessageIO :: LoggerEnv -> UTCTime -> LogLevel -> Text -> Value -> IO () -- | Return an IO action that logs messages using the current -- MonadLog context. Useful for interfacing with libraries such as -- aws or amazonka that accept logging callbacks -- operating in IO. getLoggerIO :: MonadLog m => m (UTCTime -> LogLevel -> Text -> Value -> IO ()) 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.Fail.MonadFail m => Control.Monad.Fail.MonadFail (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.IO.Unlift.MonadUnliftIO m => Control.Monad.IO.Unlift.MonadUnliftIO (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. -- --
-- {-# LANGUAGE OverloadedStrings #-}
--
-- module Main where
--
-- import Log
-- import Log.Backend.ElasticSearch
--
-- import System.Random
--
-- main :: IO ()
-- main = do
-- let config = ElasticSearchConfig {
-- esServer = "http://localhost:9200",
-- esIndex = "logs",
-- esMapping = "log"
-- }
-- withElasticSearchLogger config randomIO $ \logger -> do
-- runLogT "main" logger $ do
-- logTrace_ "foo"
--
module Log
-- | Create a Value from a list of name/value Pairs. If
-- duplicate keys arise, earlier keys and their associated values win.
object :: [Pair] -> Value
(.=) :: (KeyValue kv, ToJSON v) => Text -> v -> kv
infixr 8 .=