{- | 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 :: Maybe Facility -> Priority -> CStringLen -> IO () syslog Maybe Facility facil Priority prio (Ptr CChar ptr,Int len) = Bool -> IO () -> IO () forall a. (?callStack::CallStack) => Bool -> a -> a assert (Int len Int -> Int -> Bool forall a. Ord a => a -> a -> Bool >= Int 0) (IO () -> IO ()) -> IO () -> IO () forall a b. (a -> b) -> a -> b $ CInt -> CInt -> Ptr CChar -> CInt -> IO () _syslog (CInt -> (Facility -> CInt) -> Maybe Facility -> CInt forall b a. b -> (a -> b) -> Maybe a -> b maybe CInt 0 Facility -> CInt fromFacility Maybe Facility facil) (Priority -> CInt fromPriority Priority prio) Ptr CChar ptr (Int -> CInt forall a b. (Integral a, Num b) => a -> b fromIntegral Int 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 :: Ptr CChar -> [Option] -> Facility -> IO () openlog Ptr CChar ident [Option] opts Facility facil = Ptr CChar -> CInt -> CInt -> IO () _openlog Ptr CChar ident ((Option -> CInt -> CInt) -> CInt -> [Option] -> CInt forall (t :: * -> *) a b. Foldable t => (a -> b -> b) -> b -> t a -> b foldr (CInt -> CInt -> CInt forall a. Bits a => a -> a -> a (.|.) (CInt -> CInt -> CInt) -> (Option -> CInt) -> Option -> CInt -> CInt forall b c a. (b -> c) -> (a -> b) -> a -> c . Option -> CInt fromOption) CInt 0 [Option] opts) (Facility -> CInt fromFacility Facility facil) -- | Release all syslog-related resources. closelog :: IO () closelog :: IO () closelog = IO () _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 :: forall a. String -> [Option] -> Facility -> IO a -> IO a withSyslog String ident [Option] opts Facility facil IO a f = String -> (Ptr CChar -> IO a) -> IO a forall a. String -> (Ptr CChar -> IO a) -> IO a withCString String ident ((Ptr CChar -> IO a) -> IO a) -> (Ptr CChar -> IO a) -> IO a forall a b. (a -> b) -> a -> b $ \Ptr CChar ptr -> IO () -> IO () -> IO a -> IO a forall a b c. IO a -> IO b -> IO c -> IO c bracket_ (Ptr CChar -> [Option] -> Facility -> IO () openlog Ptr CChar ptr [Option] opts Facility facil) IO () closelog IO a 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 :: [Priority] -> IO [Priority] setlogmask [Priority] prios = (CInt -> [Priority]) -> IO CInt -> IO [Priority] forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b fmap CInt -> [Priority] fromLogMask (CInt -> IO CInt _setlogmask ([Priority] -> CInt toLogMask [Priority] prios))