log-base-0.7.1.1: Structured logging solution (base package)

Safe HaskellNone
LanguageHaskell2010

Log.Logger

Description

The Logger type of logging back-ends.

Synopsis

Documentation

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

Instances

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.

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.