-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | Versatile logging framework -- -- hslogger is a logging framework for Haskell, roughly similar to -- Python's logging module. -- -- hslogger lets each log message have a priority and source be -- associated with it. The programmer can then define global handlers -- that route or filter messages based on the priority and source. -- hslogger also has a syslog handler built in. @package hslogger @version 1.2.0 -- | Haskell Logging Framework -- -- Written by John Goerzen, jgoerzen@complete.org -- -- This module defines basic types used for logging. -- -- Extensive documentation is available in System.Log.Logger. module System.Log -- | Priorities are used to define how important a log message is. Users -- can filter log messages based on priorities. -- -- These have their roots on the traditional syslog system. The standard -- definitions are given below, but you are free to interpret them -- however you like. They are listed here in ascending importance order. data Priority -- | Debug messages DEBUG :: Priority -- | Information INFO :: Priority -- | Normal runtime conditions NOTICE :: Priority -- | General Warnings WARNING :: Priority -- | General Errors ERROR :: Priority -- | Severe situations CRITICAL :: Priority -- | Take immediate action ALERT :: Priority -- | System is unusable EMERGENCY :: Priority -- | Internal type of log records type LogRecord = (Priority, String) instance Eq Priority instance Ord Priority instance Show Priority instance Read Priority -- | Definition of log formatter support -- -- A few basic, and extendable formatters are defined. -- -- Please see System.Log.Logger for extensive documentation on the -- logging system. module System.Log.Formatter -- | A LogFormatter is used to format log messages. Note that it is -- paramterized on the Handler to allow the formatter to use -- information specific to the handler (an example of can be seen in the -- formatter used in Syslog) type LogFormatter a = a -> LogRecord -> String -> IO String -- | Returns the passed message as is, ie. no formatting is done. nullFormatter :: LogFormatter a -- | Takes a format string, and returns a formatter that may be used to -- format log messages. The format string may contain variables prefixed -- with a $-sign which will be replaced at runtime with corresponding -- values. The currently supported variables are: -- --
-- DEBUG -> DEBUG -- INFO, NOTICE -> INFO -- WARNING -> WARN -- ERROR, CRITICAL, ALERT -> ERROR -- EMERGENCY -> FATAL ---- -- This is useful when the log will only be consumed by log4j tools and -- you don't want to go out of your way transforming the log or -- configuring the tools. log4jStreamHandler' :: Handle -> Priority -> IO (GenericHandler Handle) -- | Create a file log handler that uses log4j levels (see -- log4jStreamHandler' for mappings). log4jFileHandler' :: FilePath -> Priority -> IO (GenericHandler Handle) instance Show XML -- | Haskell Logging Framework, Primary Interface -- -- Written by John Goerzen, jgoerzen@complete.org -- -- Welcome to the error and information logging system for Haskell. -- -- This system is patterned after Python's logging module, -- http://www.python.org/doc/current/lib/module-logging.html and -- some of the documentation here was based on documentation there. -- -- To log a message, you perform operations on Loggers. Each -- Logger has a name, and they are arranged hierarchically. -- Periods serve as separators. Therefore, a Logger named "foo" is -- the parent of loggers "foo.printing", "foo.html", and "foo.io". These -- names can be anything you want. They're used to indicate the area of -- an application or library in which a logged message originates. Later -- you will see how you can use this concept to fine-tune logging -- behaviors based on specific application areas. -- -- You can also tune logging behaviors based upon how important a message -- is. Each message you log will have an importance associated with it. -- The different importance levels are given by the Priority type. -- I've also provided some convenient functions that correspond to these -- importance levels: debugM through emergencyM log -- messages with the specified importance. -- -- Now, an importance level (or Priority) is associated not just -- with a particular message but also with a Logger. If the -- Priority of a given log message is lower than the -- Priority configured in the Logger, that message is -- ignored. This way, you can globally control how verbose your logging -- output is. -- -- Now, let's follow what happens under the hood when you log a message. -- We'll assume for the moment that you are logging something with a high -- enough Priority that it passes the test in your Logger. -- In your code, you'll call logM or something like debugM -- to log the message. Your Logger decides to accept the message. -- What next? -- -- Well, we also have a notion of handlers (LogHandlers, to -- be precise). A LogHandler is a thing that takes a message and -- sends it somewhere. That "somewhere" may be your screen (via standard -- error), your system's logging infrastructure (via syslog), a file, or -- other things. Each Logger can have zero or more -- LogHandlers associated with it. When your Logger has a -- message to log, it passes it to every LogHandler it knows of to -- process. What's more, it is also passed to /all handlers of all -- ancestors of the Logger/, regardless of whether those Loggers -- would normally have passed on the message. -- -- Each Logger can optionally store a Priority. If a -- given Logger does not have a Priority, and you log a message to that -- logger, the system will use the priority of the parent of the -- destination logger to find out whether to log the message. If the -- parent has no priority associated with it, the system continues -- walking up the tree to figure out a priority until it hits the root -- logger. In this way, you can easily adjust the priority of an entire -- subtree of loggers. When a new logger is created, it has no priority -- by default. The exception is the root logger, which has a WARNING -- priority by default. -- -- To give you one extra little knob to turn, LogHandlers can also -- have importance levels (Priority) associated with them in the -- same way that Loggers do. They act just like the -- Priority value in the Loggers -- as a filter. It's -- useful, for instance, to make sure that under no circumstances will a -- mere DEBUG message show up in your syslog. -- -- There are three built-in handlers given in two built-in modules: -- System.Log.Handler.Simple and System.Log.Handler.Syslog. -- -- There is a special logger known as the root logger that sits at -- the top of the logger hierarchy. It is always present, and handlers -- attached there will be called for every message. You can use -- getRootLogger to get it or rootLoggerName to work with -- it by name. -- -- The formatting of log messages may be customized by setting a -- LogFormatter on the desired LogHandler. There are a -- number of simple formatters defined in System.Log.Formatter, -- which may be used directly, or extend to create your own formatter. -- -- Here's an example to illustrate some of these concepts: -- --
-- import System.Log.Logger -- import System.Log.Handler.Syslog -- import System.Log.Handler.Simple -- import System.Log.Handler (setFormatter) -- import System.Log.Formatter -- -- -- By default, all messages of level WARNING and above are sent to stderr. -- -- Everything else is ignored. -- -- -- "MyApp.Component" is an arbitrary string; you can tune -- -- logging behavior based on it later. -- main = do -- debugM "MyApp.Component" "This is a debug message -- never to be seen" -- warningM "MyApp.Component2" "Something Bad is about to happen." -- -- -- Copy everything to syslog from here on out. -- s <- openlog "SyslogStuff" [PID] USER DEBUG -- updateGlobalLogger rootLoggerName (addHandler s) -- -- errorM "MyApp.Component" "This is going to stderr and syslog." -- -- -- Now we'd like to see everything from BuggyComponent -- -- at DEBUG or higher go to syslog and stderr. -- -- Also, we'd like to still ignore things less than -- -- WARNING in other areas. -- -- -- -- So, we adjust the Logger for MyApp.BuggyComponent. -- -- updateGlobalLogger "MyApp.BuggyComponent" -- (setLevel DEBUG) -- -- -- This message will go to syslog and stderr -- debugM "MyApp.BuggyComponent" "This buggy component is buggy" -- -- -- This message will go to syslog and stderr too. -- warningM "MyApp.BuggyComponent" "Still Buggy" -- -- -- This message goes nowhere. -- debugM "MyApp.WorkingComponent" "Hello" -- -- -- Now we decide we'd also like to log everything from BuggyComponent at DEBUG -- -- or higher to a file for later diagnostics. We'd also like to customize the -- -- format of the log message, so we use a 'simpleLogFormatter' -- -- h <- fileHandler "debug.log" DEBUG >>= \lh -> return $ -- setFormatter lh (simpleLogFormatter "[$time : $loggername : $prio] $msg") -- updateGlobalLogger "MyApp.BuggyComponent" (addHandler h) -- -- -- This message will go to syslog and stderr, -- -- and to the file "debug.log" with a format like : -- -- [2010-05-23 16:47:28 : MyApp.BuggyComponent : DEBUG] Some useful diagnostics... -- debugM "MyApp.BuggyComponent" "Some useful diagnostics..." --module System.Log.Logger data Logger -- | Priorities are used to define how important a log message is. Users -- can filter log messages based on priorities. -- -- These have their roots on the traditional syslog system. The standard -- definitions are given below, but you are free to interpret them -- however you like. They are listed here in ascending importance order. data Priority -- | Debug messages DEBUG :: Priority -- | Information INFO :: Priority -- | Normal runtime conditions NOTICE :: Priority -- | General Warnings WARNING :: Priority -- | General Errors ERROR :: Priority -- | Severe situations CRITICAL :: Priority -- | Take immediate action ALERT :: Priority -- | System is unusable EMERGENCY :: Priority -- | Log a message using the given logger at a given priority. logM :: String -> Priority -> String -> IO () -- | Log a message at DEBUG priority debugM :: String -> String -> IO () -- | Log a message at INFO priority infoM :: String -> String -> IO () -- | Log a message at NOTICE priority noticeM :: String -> String -> IO () -- | Log a message at WARNING priority warningM :: String -> String -> IO () -- | Log a message at ERROR priority errorM :: String -> String -> IO () -- | Log a message at CRITICAL priority criticalM :: String -> String -> IO () -- | Log a message at ALERT priority alertM :: String -> String -> IO () -- | Log a message at EMERGENCY priority emergencyM :: String -> String -> IO () -- | Allow gracefull shutdown. Release all opened fileshandlersetc. removeAllHandlers :: IO () -- | Traps exceptions that may occur, logging them, then passing them on. -- -- Takes a logger name, priority, leading description text (you can set -- it to "" if you don't want any), and action to run. traplogging :: String -> Priority -> String -> IO a -> IO a -- | Log a message, assuming the current logger's level permits it. logL :: Logger -> Priority -> String -> IO () -- | Returns the logger for the given name. If no logger with that name -- exists, creates new loggers and any necessary parent loggers, with no -- connected handlers. getLogger :: String -> IO Logger -- | Returns the root logger. getRootLogger :: IO Logger -- | This is the base class for the various log handlers. They should all -- adhere to this class. -- -- The name of the root logger, which is always defined and present on -- the system. rootLoggerName :: String -- | Add handler to Logger. Returns a new Logger. addHandler :: LogHandler a => a -> Logger -> Logger -- | Set the 'Logger'\'s list of handlers to the list supplied. All -- existing handlers are removed first. setHandlers :: LogHandler a => [a] -> Logger -> Logger -- | Returns the level of the logger. Items beneath this level will -- be ignored. getLevel :: Logger -> Maybe Priority -- | Sets the level of the Logger. Returns a new -- Logger object with the new level. setLevel :: Priority -> Logger -> Logger -- | Clears the level of the Logger. It will now inherit the -- level of | its parent. clearLevel :: Logger -> Logger -- | Updates the global record for the given logger to take into account -- any changes you may have made. saveGlobalLogger :: Logger -> IO () -- | Helps you make changes on the given logger. Takes a function that -- makes changes and writes those changes back to the global database. -- Here's an example from above ("s" is a LogHandler): -- --
-- updateGlobalLogger "MyApp.BuggyComponent" -- (setLevel DEBUG . setHandlers [s]) --updateGlobalLogger :: String -> (Logger -> Logger) -> IO ()