-- | Logging via @extensible-effects@ -- -- Logging consist of __two__ effects: -- -- * __Receiving__ log messages sent by the code using e.g. 'logInfo'; this also include deep evaluation and -- dropping messages not satisfying the current 'LogPredicate'. -- -- * __Writing__ log message to disk, network, ... etc; this also includes rendering log messages and setting -- fields like the hostname, timestamp, etc -- -- == Example -- -- -- > exampleLogging :: IO () -- > exampleLogging = -- > runLift -- > $ withLogging consoleLogWriter -- > $ do -- > logDebug "test 1.1" -- > logError "test 1.2" -- > censorLogs (prefixLogMessagesWith "NESTED: ") -- > $ do -- > addLogWriter debugTraceLogWriter -- > $ setLogPredicate (\m -> (view lmMessage m) /= "not logged") -- > $ do -- > logInfo "not logged" -- > logMsg "test 2.1" -- > logWarning "test 2.2" -- > logCritical "test 1.3" -- -- == Log Message Data Type -- -- A singular /logging event/ is contained in a __'LogMessage's__ value. -- -- The 'LogMessage' is modelled along RFC-5424. -- -- There is the 'ToLogMessage' class for converting to 'LogMessage'. -- /Although the author is not clear on how to pursue the approach./ -- -- == Receiving and Filtering -- -- 'LogMessage's are sent using 'logMsg' and friends, see "Control.Eff.Log#SendingLogs" -- -- === Log Message Predicates -- -- There is a single global 'LogPredicate' that can be used to suppress logs before -- they are passed to any 'LogWriter'. -- -- This is done by the 'logMsg' function. -- -- Also, 'LogMessage's are evaluated using 'Control.DeepSeq.deepseq', __after__ they pass the 'LogPredicate', -- also inside 'logMsg'. -- -- See "Control.Eff.Log#LogPredicate" -- -- == Writing and Rendering -- -- Writing is done through a 'LogWriter'; the current 'LogWriter' value to use is held by the -- 'LogWriterReader' effect. -- -- === Log Message Rendering -- -- Message are rendered by 'LogMessageRenderer's found in the "Control.Eff.Log.MessageRenderer". -- -- === 'LogWriter's -- -- * Logging in a 'Control.Concurrent.Async.withAsync' spawned thread is done using 'withAsyncLogging'. module Control.Eff.Log ( -- * Logging API -- ** Sending Log Messages #SendingLogs# logMsg , logWithSeverity , logWithSeverity' , logEmergency , logEmergency' , logAlert , logAlert' , logCritical , logCritical' , logError , logError' , logWarning , logWarning' , logNotice , logNotice' , logInfo , logInfo' , logDebug , logDebug' -- ** Log Message Pre-Filtering #LogPredicate# -- $LogPredicate , includeLogMessages , excludeLogMessages , setLogPredicate , modifyLogPredicate , askLogPredicate -- * Log Handling API -- ** Writing Logs , setLogWriter , addLogWriter , modifyLogWriter -- *** Log Message Modification , censorLogs , censorLogsM -- ** 'Logs' Effect Handling , Logs() , LogsTo , withLogging , withSomeLogging -- ** Low-Level API for Custom Extensions -- *** Log Message Interception , runLogs , respondToLogMessage , interceptLogMessages -- * Module Re-Exports -- | The module that contains the 'LogMessage' and 'LogPredicate' definitions. -- -- The log message type corresponds roughly to RFC-5424, including structured data. , module Control.Eff.Log.Message -- | Rendering functions for 'LogMessage's -- -- The functions have been seperated from "Control.Eff.Log.Message" , module Control.Eff.Log.MessageRenderer -- | This module defines the 'LogWriter' type, which is used to give -- callback functions for log messages an explicit type. , module Control.Eff.Log.Writer ) where import Control.Eff.Log.Handler import Control.Eff.Log.Message import Control.Eff.Log.MessageRenderer import Control.Eff.Log.Writer -- $LogPredicate -- -- Ways to change the 'LogPredicate' are: -- -- * 'setLogPredicate'. -- * 'modifyLogPredicate'. -- * 'includeLogMessages' -- * 'excludeLogMessages' -- -- The current predicate is retrieved via 'askLogPredicate'. -- -- Some pre-defined 'LogPredicate's can be found here: "Control.Eff.Log.Message#PredefinedPredicates"