log-base- Structured logging solution (base package)

Safe HaskellNone



The Logger type of logging back-ends.



data LoggerEnv Source #

The state that every LogT carries around.




data Logger Source #

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).

Semigroup Logger Source # 
Instance details

Defined in Log.Internal.Logger

Monoid Logger Source #

Composition of Logger objects.

Instance details

Defined in Log.Internal.Logger

mkLogger :: Text -> (LogMessage -> IO ()) -> IO Logger Source #

Start a logger thread that consumes one queued message at a time.

mkBulkLogger :: Text -> ([LogMessage] -> IO ()) -> IO () -> IO Logger Source #

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 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' Source #


:: Int

queue capacity (default 1000000)

-> Int

thread delay (microseconds, default 1000000)

-> Text

logger name

-> ([LogMessage] -> IO ())


-> IO ()


-> IO Logger 

Like mkBulkLogger, but with configurable queue size and thread delay.


execLogger :: Logger -> LogMessage -> IO () Source #

Execute logger to serialize a LogMessage.

waitForLogger :: Logger -> IO () Source #

Wait until all LogMessages stored in the internal queue are serialized.

shutdownLogger :: Logger -> IO () Source #

Shutdown the logger thread associated with this Logger object. Subsequent attempts to write messages via this Logger will result in an exception.