X-Git-Url: http://gitweb.michael.orlitzky.com/?a=blobdiff_plain;f=src%2FLogging.hs;h=ede739a28ba9a9027bbbebc894dc51a5ad0cdd18;hb=fdd40277556133bd14cf0a3f13749f4663b5f3ba;hp=db7260a1fc74c3600088684974075ffce56c1171;hpb=52e788e676ea2a67ad20b23d2e5c5b351f27b834;p=dead%2Fhtsn.git diff --git a/src/Logging.hs b/src/Logging.hs index db7260a..ede739a 100644 --- a/src/Logging.hs +++ b/src/Logging.hs @@ -6,9 +6,16 @@ module Logging ( log_warning ) where -import System.Log.Handler.Simple ( GenericHandler ) +import Control.Monad ( when ) +import System.Log.Formatter ( simpleLogFormatter ) +import System.Log.Handler ( setFormatter ) +import System.Log.Handler.Simple ( GenericHandler, fileHandler ) +import System.Log.Handler.Syslog ( + Facility ( USER ), + openlog ) import System.Log.Logger ( - Priority ( DEBUG, INFO ), + Priority ( INFO ), + addHandler, debugM, errorM, infoM, @@ -18,24 +25,57 @@ import System.Log.Logger ( updateGlobalLogger, warningM ) + +-- | Log a message at the DEBUG level. log_debug :: String -> IO () log_debug = debugM rootLoggerName +-- | Log a message at the ERROR level. log_error :: String -> IO () log_error = errorM rootLoggerName +-- | Log a message at the INFO level. log_info :: String -> IO () log_info = infoM rootLoggerName +-- | Log a message at the WARNING level. log_warning :: String -> IO () log_warning = warningM rootLoggerName -init_logging :: Bool -> IO () -init_logging use_syslog = do - let max_level = if use_syslog then INFO else DEBUG - -- We need to specify the type here; otherwise, setHandlers won't - -- accept the empty list as an instance of [LogHandler a]. + +-- | Set up the logging. All logs are handled by the global "root" +-- logger provided by HSLogger. We remove all of its handlers so +-- that it does nothing; then we conditionally add back two handlers +-- -- one for syslog, and one for a normal file -- dependent upon +-- the 'syslog' and 'log_file' configuration items. +-- +-- Why don't we take a Configuration as an argument? Because it +-- would create circular imports! +init_logging :: Maybe FilePath -> Priority -> Bool -> IO () +init_logging log_file log_level syslog = do + -- First set the global log level and clear the default handler. let no_handlers = [] :: [GenericHandler a] - -- Removes the default "echo to stdout" handler. - updateGlobalLogger rootLoggerName (setLevel max_level - . setHandlers no_handlers) + updateGlobalLogger rootLoggerName (setLevel log_level . + setHandlers no_handlers) + + when syslog $ do + let min_level = INFO + let sl_level = if log_level < min_level then min_level else log_level + + -- The syslog handle gets its own level which will cowardly refuse + -- to log all debug info (i.e. the entire feed) to syslog. + sl_handler' <- openlog rootLoggerName [] USER sl_level + + -- Syslog should output the date by itself. + let sl_formatter = simpleLogFormatter "htsn[$pid] $prio: $msg" + let sl_handler = setFormatter sl_handler' sl_formatter + + updateGlobalLogger rootLoggerName (addHandler sl_handler) + + case log_file of + Nothing -> return () + Just lf -> do + lf_handler' <- fileHandler lf log_level + let lf_formatter = simpleLogFormatter "$time: htsn[$pid] $prio: $msg" + let lf_handler = setFormatter lf_handler' lf_formatter + updateGlobalLogger rootLoggerName (addHandler lf_handler)