| Safe Haskell | Trustworthy |
|---|---|
| Language | Haskell98 |
System.Log.SLog
Contents
Description
SimpleLog is a library for convenient and configurable logging. It uses the usual monad transformer + associated class design: SLogT and MonadSLog.
Example usage:
import System.Log.SLog
main = simpleLog "Example.log" $ do
logD "Some debugging information"
logI "This is some other information"
logW "Something bad is about to happen"
logE "Something bad happened"
The above sample code when run will produce output similar to this:
2013-10-02 14:17:40 | INFO | [ThreadId 58] This is some other information 2013-10-02 14:17:40 | WARNING | [ThreadId 58] Something bad is about to happen 2013-10-02 14:17:40 | ERROR | [ThreadId 58] Something bad happened
Note how the debug line is not displayed. This is because the default configuration (defaultLogConfig) only logs to stdout when the severity is >= INFO.
The above code will also append the log lines to the file "Example.log", including the debug line.
The following example shows how one can fine tune SimpleLog as well as how to fork other logging threads.
-- Our log configuration specifies that no ANSI colouring should be used, all log lines
-- should be written to the TChan, and >= INFO severity lines should be written to the
-- stdout synchronously.
logConfig :: TChan LogLine -> LogConfig
logConfig tchan
= LogConfig { ansiColours = False
, loggers = [ (anySev, TChanLogger tchan)
, ((>= INFO), StdoutLogger Sync)
] }
-- Our custom logging format
logFormat :: Format
logFormat = $(format "%d(%T) (%s) %t: %m")
-- The main thread will fork a child thread, then wait until everything is flushed, then
-- count how many messages have been written in total to the TChan (which will be all
-- messages as our filter passes through everything)
main :: IO ()
main = do
tchan <- newTChanIO
(_, fkey) <- runSLogT (logConfig tchan) logFormat "main" $ do
logS "Main thread started successfully"
logD "This will not appear on stdout"
_ <- forkSLog "child" $ do
logS "I am the child"
liftIO $ threadDelay 5000000
logW "CHILD SHUTTING DOWN"
logI "Exiting main thread"
waitFlush fkey
c <- countTChan tchan
putStrLn $ show c ++ " messages have been logged in total"
-- Counts the number of elements in the TChan (and pops them all)
countTChan :: TChan a -> IO Int
countTChan tchan = do
let count = do
em <- isEmptyTChan tchan
if em then return 0
else readTChan tchan >> (1 +) <$> count
atomically count
The above code when run will produce something like this:
17:35:15 (SUCCESS) main: Main thread started successfully 17:35:15 (SUCCESS) child: I am the child, waiting for 5 seconds... 17:35:15 (INFO ) main: Exiting main thread 17:35:20 (WARNING) child: CHILD SHUTTING DOWN 5 messages have been logged in total
- data SLogT m a
- type SLog = SLogT IO
- runSLogT :: (MonadResource m, MonadBaseControl IO m) => LogConfig -> Format -> String -> SLogT m a -> m (a, FlushKey)
- simpleLog :: (MonadResource m, MonadBaseControl IO m) => FilePath -> SLogT m a -> m a
- data FlushKey
- waitFlush :: FlushKey -> IO ()
- class MonadIO m => MonadSLog m where
- logD :: MonadSLog m => String -> m ()
- logI :: MonadSLog m => String -> m ()
- logS :: MonadSLog m => String -> m ()
- logW :: MonadSLog m => String -> m ()
- logE :: MonadSLog m => String -> m ()
- data Logger
- data Sync
- data LogLine = LogLine {}
- data Severity
- type Filter = Severity -> Bool
- anySev :: Filter
- data LogConfig = LogConfig {
- ansiColours :: Bool
- loggers :: [(Filter, Logger)]
- defaultLogConfig :: FilePath -> LogConfig
- module System.Log.SLog.Format
- defaultLogFormat :: Format
- forkSLog :: (MonadBaseControl IO m, MonadIO m) => String -> SLogT m () -> SLogT m ThreadId
- formatLine :: Bool -> Format -> LogLine -> Text
- unsafeUnliftSLogT :: forall m b. (Monad m, MonadBaseControl IO m) => ((forall a. SLogT m a -> m a) -> SLogT m b) -> SLogT m b
SLogT
The SLogT monad transformer is simply a ResourceT with an environment
Instances
| MonadTransControl SLogT | |
| MonadTrans SLogT | |
| MonadBase IO m => MonadBase IO (SLogT m) | |
| MonadBaseControl IO m => MonadBaseControl IO (SLogT m) | |
| Monad m => Monad (SLogT m) | |
| Functor m => Functor (SLogT m) | |
| Applicative m => Applicative (SLogT m) | |
| MonadThrow m => MonadThrow (SLogT m) | |
| MonadIO m => MonadIO (SLogT m) | |
| (MonadBase IO m, MonadThrow m, MonadIO m) => MonadResource (SLogT m) | |
| MonadIO m => MonadSLog (SLogT m) | |
| (MonadBaseControl IO m, MonadIO m) => Forkable (SLogT m) (SLogT m) | |
| type StT SLogT a = StT ResourceT a | |
| type StM (SLogT m) a = ComposeSt SLogT m a |
Running SLogT
runSLogT :: (MonadResource m, MonadBaseControl IO m) => LogConfig -> Format -> String -> SLogT m a -> m (a, FlushKey) Source
simpleLog :: (MonadResource m, MonadBaseControl IO m) => FilePath -> SLogT m a -> m a Source
FlushKey
waitFlush :: FlushKey -> IO () Source
waitFlush will only return when all resources have been released and all streams have been flushed. Note that this includes resources allocated by the user using the exposed MonadResource instance.
All threads internally accounted for are signaled to exit (they will first finish processing of all remaining jobs) when the SLogT is run, however it is the user's responsibility to shut down threads forked with forkSLog or fork before waitFlush can return.
MonadSLog
class MonadIO m => MonadSLog m where Source
The class of monads that can perform logging
Minimal complete definition
Nothing
Methods
Convenience log functions
Loggers
The Logger type specifies the types of sinks we can log to.
Constructors
| FileLogger Sync FilePath |
|
| StdoutLogger Sync |
|
| StderrLogger Sync |
|
| TChanLogger (TChan LogLine) |
|
Sync is a type to specify whether a logger should log synchronously or asynchronously.
Syncronous logging means that the logging thread will block until the message has been written and flushed to the sink.
Asynchronous logging means that the logging thread will write to a work queue and move on. The work queue will be read by a dedicated thread that is forked for each sink.
LogLine is a log message together with the severity, time of logging and the logging thread's name.
Constructors
| LogLine | |
Fields
| |
Filters
The type of severities with increasing importance
Configuration
defaultLogConfig :: FilePath -> LogConfig Source
defaultLogConfig is the default log configuration.
It writes all non-DEBUG messages to the stdout synchronously and all messages to a specified file asynchronously.
Format
module System.Log.SLog.Format
defaultLogFormat :: Format Source
The default log format, which currently is $(format "%d(%F %T) | %s | [%t] %m"). See System.Log.SLog.Format for more details on format strings.
Utility functions
formatLine :: Bool -> Format -> LogLine -> Text Source
formatLine formats the given LogLine using the specified Format. The Boolean determines whether formatLine should insert ANSI colour codes or not.
unsafeUnliftSLogT :: forall m b. (Monad m, MonadBaseControl IO m) => ((forall a. SLogT m a -> m a) -> SLogT m b) -> SLogT m b Source
unsafeUnliftSLog gives you an unsafe unlift of an SLogT by assuming that any unlifted computation will finish earlier than the runSLogT of the calling thread.
It is unsafe because if the unlifted computation doesn't finish earlier then it may access deallocated resources.
This is useful when a library is implicitly forking but we still need to log in the forked threads, and we know that the child threads will finish earlier than the parent. An example is Network.WebSockets