-- | Fast start -- -- Create log config: -- -- @ --myCfg = logCfg [(\"\", Info), (\"app\", Trace), (\"app.sub\", Debug)] -- @ -- -- Create log and run log monad -- -- @ --run ∷ IO () --run = runLog myCfg [handler text (file \"out.log\")] $ yourFunction -- @ -- -- Function within log monad: -- -- @ --yourFunction ∷ MonadLog m ⇒ m () --yourFunction = component \"app\" $ scope \"your\" $ do -- sendLog Trace \"Hello from your function\" -- @ -- -- Each component can have different level in config, subcomponents are specified with \'.\' -- Components have independent scopes -- Scopes can be nested and separated with \'/\': -- -- @ --function2 ∷ MonadLog m ⇒ m () --function2 = component \"app.sub\" $ scope \"foo\" $ do -- scope \"bar/baz\" $ do -- sendLog Info \"Component app.sub and scope foo/bar/baz\" -- sendLog Trace \"Invisible: app.sub configured with debug level\" -- sendLog Info \"Same component and scope foo\" -- component \"module\" $ sendLog Info \"Component module and root scope\" -- @ -- -- You can update config with @updateLogConfig@ (or @modifyLogConfig@ within log monad) function -- And change handlers with @updateLogHandlers@ (@modifyLogHandlers@) -- -- There're also global logger @globalLog@, that can be used with @runGlobalLog@ -- -- @ --test ∷ IO () --test = do -- updateLogHandlers globalLog ([handler text (file \"test.log\")]:) -- runGlobalLog $ do -- sendLog Info \"This will go to test.log too\" -- modifyLogConfig (set (ix \"\") Debug) -- sendLog Debug \"Now debug is logged too\" -- @ -- module System.Log.Simple ( module System.Log.Simple.Base, module System.Log.Simple.Monad, module System.Log.Simple.Text, module System.Log.Simple.Stream, module System.Log.Simple.File, globalLog, runGlobalLog, runConsoleLog, runLogMsgs, runLogTexts ) where import Prelude.Unicode import Control.Monad.IO.Class import Control.Monad.Catch (MonadMask) import Control.Concurrent import Data.Maybe import Data.Text (Text) import System.IO.Unsafe (unsafePerformIO) import System.Log.Simple.Base ( Level(..), Message, Converter, Consumer, LogHandler, handler, LogConfig(..), defCfg, logCfg, componentCfg, Log(..), newLog, rootLog, getLog, subLog, updateLogConfig, updateLogHandlers, writeLog, stopLog) import System.Log.Simple.Monad ( MonadLog(..), LogT(..), noLog, withLog, runLog, sendLog, component, scope_, scope, scopeM, scoper, scoperM, trace, modifyLogConfig, modifyLogHandlers) import System.Log.Simple.Text import System.Log.Simple.Stream import System.Log.Simple.File import System.Log.Simple.Chan globalLog ∷ Log globalLog = unsafePerformIO $ newLog defCfg [handler text coloredConsole] runGlobalLog ∷ LogT m a → m a runGlobalLog = withLog globalLog runConsoleLog ∷ (MonadIO m, MonadMask m) ⇒ LogConfig → LogT m a → m a runConsoleLog cfg = runLog cfg [handler text coloredConsole] runLogChan ∷ (MonadIO m, MonadMask m) ⇒ (Chan w → LogHandler) → LogConfig → LogT m a → m (a, [w]) runLogChan c cfg act = do ch ← liftIO newChan mch ← liftIO newChan _ ← liftIO $ forkIO $ getChanContents ch >>= mapM_ (writeChan mch . Just) r ← runLog cfg [c ch] act liftIO $ writeChan mch Nothing msgs ← liftIO ((catMaybes ∘ takeWhile isJust) <$> getChanContents mch) return (r, msgs) runLogMsgs ∷ (MonadIO m, MonadMask m) ⇒ LogConfig → LogT m a → m (a, [Message]) runLogMsgs = runLogChan chan runLogTexts ∷ (MonadIO m, MonadMask m) ⇒ Converter Text → LogConfig → LogT m a → m (a, [Text]) runLogTexts txt = runLogChan (handler txt ∘ chan)