hsyslog-2.0: FFI interface to syslog(3) from POSIX.1-2001

Maintainer | simons@cryp.to
Stability | provisional
Portability | Posix
Safe Haskell | Safe
Language | Haskell98

System.Posix.Syslog

Contents

- Marshaled Data Types
- Haskell API to syslog
- Helpers
- Low-level C functions

Description

FFI bindings to syslog(3) from POSIX.1-2001.

Synopsis

- data Priority
  - = Emergency
  - | Alert
  - | Critical
  - | Error
  - | Warning
  - | Notice
  - | Info
  - | Debug
- data Facility
  - = KERN
  - | USER
  - | MAIL
  - | DAEMON
  - | AUTH
  - | SYSLOG
  - | LPR
  - | NEWS
  - | UUCP
  - | CRON
  - | AUTHPRIV
  - | FTP
  - | LOCAL0
  - | LOCAL1
  - | LOCAL2
  - | LOCAL3
  - | LOCAL4
  - | LOCAL5
  - | LOCAL6
  - | LOCAL7
- data Option
  - = PID
  - | CONS
  - | ODELAY
  - | NDELAY
  - | NOWAIT
  - | PERROR
- withSyslog :: String -> [Option] -> Facility -> [Priority] -> IO a -> IO a
- syslog :: Priority -> String -> IO ()
- logUpTo :: Priority -> [Priority]
- safeMsg :: String -> String
- _openlog :: CString -> CInt -> CInt -> IO ()
- _closelog :: IO ()
- _setlogmask :: CInt -> IO CInt
- _syslog :: CInt -> CString -> IO ()

# Marshaled Data Types

data Priority Source

Log messages are prioritized.

Note that the `Enum` instance for this class is incomplete. We abuse `toEnum` and `fromEnum` to map these constructors to their corresponding bit-mask value in C, but not all uses cases provided by of enumerating that class are fully supported (issue #5).

Constructors

Emergency | system is unusable
Alert | action must be taken immediately
Critical | critical conditions
Error | error conditions
Warning | warning conditions
Notice | normal but significant condition
Info | informational
Debug | debug-level messages

Instances

Bounded Priority Source |
Enum Priority Source |
Eq Priority Source |
Read Priority Source |
Show Priority Source |
Generic Priority Source |
type Rep Priority Source |

data Facility Source

Syslog distinguishes various system facilities. Most applications should log in `USER`.

Constructors

KERN | kernel messages
USER | user-level messages (default unless set otherwise)
MAIL | mail system
DAEMON | system daemons
AUTH | security/authorization messages
SYSLOG | messages generated internally by syslogd
LPR | line printer subsystem
NEWS | network news subsystem
UUCP | UUCP subsystem
CRON | clock daemon
AUTHPRIV | security/authorization messages (effectively equals `AUTH` on some systems)
FTP | ftp daemon (effectively equals `DAEMON` on some systems)
LOCAL0 | reserved for local use
LOCAL1 | reserved for local use
LOCAL2 | reserved for local use
LOCAL3 | reserved for local use
LOCAL4 | reserved for local use
LOCAL5 | reserved for local use
LOCAL6 | reserved for local use
LOCAL7 | reserved for local use

Instances

Bounded Facility Source |
Enum Facility Source |
Eq Facility Source |
Read Facility Source |
Show Facility Source |

data Option Source

Options for the syslog service. Set with `withSyslog`.

Constructors

PID | log the pid with each message
CONS | log on the console if errors in sending
ODELAY | delay open until first `syslog()` (default)
NDELAY | don't delay open
NOWAIT | don't wait for console forks: DEPRECATED
PERROR | log to `stderr` as well (might be a no-op on some systems)

Instances

Bounded Option Source |
Enum Option Source |
Eq Option Source |
Show Option Source |

# Haskell API to syslog

withSyslog :: String -> [Option] -> Facility -> [Priority] -> IO a -> IO a Source

Bracket an `IO` computation between calls to `_openlog`, `_setlogmask`, and `_closelog`. The function can be used as follows:

    main = withSyslog "my-ident" [PID, PERROR] USER (logUpTo Debug) $ do
             putStrLn "huhu"
             syslog Debug "huhu"

Note that these are process-wide settings, so multiple calls to this function will interfere with each other in unpredictable ways.

syslog :: Priority -> String -> IO () Source

Log a message with the given priority.

Note that the API of this function is somewhat unsatisfactory and is likely to change in the future:

1. The function should accept a `[`Facility`]` argument so that messages can be logged to certain facilities without depending on the process-wide global default value set by `openlog` (issue #6).
2. The `Priority` argument should be `[`Priority`]`.
3. Accepting a `ByteString` instead of `String` would be preferrable because we can log those more efficiently, i.e. without marshaling. On top of that, we can provide a wrapper for this function that accepts anything that can be marshaled into a `ByteString` (issue #7).

logUpTo :: Priority -> [Priority] Source

Returns the list of priorities up to and including the argument. Note that the syslog priority `Debug` is considered the highest one in this context, which may counter-intuitive for some.

    >>> logUpTo(Debug)
    [Emergency,Alert,Critical,Error,Warning,Notice,Info,Debug]

    >>> logUpTo(Emergency)
    [Emergency]

# Helpers

safeMsg :: String -> String Source

Escape any occurances of '`%`' in a string, so that it is safe to pass it to `_syslog`. The `syslog` wrapper does this automatically.

Unfortunately, the application of this function to every single syslog message is a performence nightmare. Instead, we should call syslog the existence of this function is a kludge, in a way that doesn't require any escaping (issue #8).

# Low-level C functions

_openlog :: CString -> CInt -> CInt -> IO () Source

Open a connection to the system logger for a program. The string identifier passed as the first argument is prepended to every message, and is typically set to the program name. The behavior is unspecified by POSIX.1-2008 if that identifier is `nullPtr`.

_closelog :: IO () Source

Close the descriptor being used to write to the system logger.

_setlogmask :: CInt -> IO CInt Source

A process has a log priority mask that determines which calls to `syslog` may be logged. All other calls will be ignored. Logging is enabled for the priorities that have the corresponding bit set in mask. The initial mask is such that logging is enabled for all priorities. This function sets this logmask for the calling process, and returns the previous mask. If the mask argument is 0, the current logmask is not modified.

_syslog :: CInt -> CString -> IO () Source

Generate a log message, which will be distributed by `syslogd(8)`. The priority argument is formed by ORing the facility and the level values (explained below). The remaining arguments are a format, as in printf(3) and any arguments required by the format, except that the two character sequence %m will be replaced by the error message string strerror(errno). A trailing newline may be added if needed.