hsyslog-5.0.2: src/System/Posix/Syslog.hs
{- |
Maintainer: simons@cryp.to
Stability: provisional
Portability: POSIX
A Haskell interface to @syslog(3)@ as specified in
<http://pubs.opengroup.org/onlinepubs/9699919799/functions/syslog.html POSIX.1-2008>.
The entire public API lives in this module. There is a set of exposed
modules available underneath this one, which contain various implementation
details that may be useful to other developers who want to implement
syslog-related functionality. /Users/ of syslog, however, do not need those
modules; "System.Posix.Syslog" has all you'll need.
Check out the
<https://github.com/peti/hsyslog/blob/master/example/Main.hs example program>
that demonstrates how to use this library.
-}
module System.Posix.Syslog
( -- * Writing Log Messages
syslog, Priority(..), Facility(..)
, -- * Configuring the system's logging engine
openlog, closelog, withSyslog, setlogmask, Option(..)
)
where
import System.Posix.Syslog.Facility
import System.Posix.Syslog.Functions
import System.Posix.Syslog.LogMask
import System.Posix.Syslog.Options
import System.Posix.Syslog.Priority
import Control.Exception ( assert, bracket_ )
import Data.Bits
import Foreign.C
-- |Log the given text message via @syslog(3)@. Please note that log messages
-- are committed to the log /verbatim/ --- @printf()@-style text formatting
-- features offered by the underlying system function are /not/ available. If
-- your log message reads @"%s"@, then that string is exactly what will be
-- written to the log. Also, log messages cannot contain @\\0@ bytes. If they
-- do, all content following that byte will be cut off because the C function
-- assumes that the string ends there.
--
-- The Haskell 'String' type can be easily logged with 'withCStringLen':
--
-- @
-- withCStringLen "Hello, world." $ syslog (Just User) Info
-- @
--
-- 'ByteStrings' can be logged in the same way with the 'unsafeUseAsCStringLen'
-- function from @Data.ByteString.Unsafe@, which extracts a 'CStringLen' from
-- the 'ByteString' in constant time (no copying!).
syslog :: Maybe Facility -- ^ Categorize this message as belonging into the
-- given system facility. If left unspecified, the
-- process-wide default will be used, which tends to
-- be 'User' by default.
-> Priority -- ^ Log with the specified priority.
-> CStringLen -- ^ The actual log message. The string does not need
-- to be terminated by a @\\0@ byte. If the string
-- /does/ contain a @\\0@ byte, then the message ends
-- there regardless of what the length argument says.
-> IO ()
syslog facil prio (ptr,len) = assert (len >= 0) $
_syslog (maybe 0 fromFacility facil) (fromPriority prio) ptr (fromIntegral len)
-- | This function configures the process-wide hidden state of the system's
-- syslog engine. It's probably a bad idea to call this function anywhere
-- except at the very top of your program's 'main' function. And even then you
-- should probably prefer 'withSyslog' instead, which guarantees that syslog is
-- properly initialized within its scope.
openlog :: CString -- ^ An identifier to prepend to all log messages,
-- typically the name of the program. Note that the
-- memory that contains this name must remain valid
-- until the pointer provided here is released by
-- calling 'closelog'.
-> [Option] -- ^ A set of options that configure the behavior of
-- the system's syslog engine.
-> Facility -- ^ The facility to use by default when none has been
-- specified with a 'syslog' call.
-> IO ()
openlog ident opts facil =
_openlog ident (foldr ((.|.) . fromOption) 0 opts) (fromFacility facil)
-- | Release all syslog-related resources.
closelog :: IO ()
closelog = _closelog
-- | Run the given @IO a@ computation within an initialized syslogging scope.
-- The definition is:
--
-- @
-- withSyslog ident opts facil f =
-- 'withCString' ident $ \ptr ->
-- 'bracket_' (openlog ptr opts facil) closelog f
-- @
withSyslog :: String -> [Option] -> Facility -> IO a -> IO a
withSyslog ident opts facil f =
withCString ident $ \ptr ->
bracket_ (openlog ptr opts facil) closelog f
-- | Configure a process-wide filter that determines which logging priorities
-- are ignored and which ones are forwarded to the @syslog@ implementation. For
-- example, use @setlogmask [Emergency .. Info]@ to filter out all debug-level
-- messages from the message stream. Calling @setlogmask [minBound..maxBound]@
-- enables /everything/. The special case @setlogmask []@ does /nothing/, i.e.
-- the current filter configuration is not modified. This can be used to
-- retrieve the current configuration.
setlogmask :: [Priority] -> IO [Priority]
setlogmask prios = fmap fromLogMask (_setlogmask (toLogMask prios))