Safe Haskell | None |
---|---|
Language | Haskell2010 |
The Logger
type of logging back-ends.
- data Logger
- mkLogger :: Text -> (LogMessage -> IO ()) -> IO Logger
- mkBulkLogger :: Text -> ([LogMessage] -> IO ()) -> IO () -> IO Logger
- execLogger :: Logger -> LogMessage -> IO ()
- waitForLogger :: Logger -> IO ()
- shutdownLogger :: Logger -> IO ()
Documentation
An object used for communication with a logger thread that
outputs LogMessage
s using e.g. PostgreSQL, Elasticsearch or
stdout (depending on the back-end chosen).
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. 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 LogMessage
s stored in the internal queue are
serialized.