5.1 System Log Service

Traditionally, GNU and Unix-like systems come with a system-wide logging mechanism called syslog that applications and services can use. This mechanism usually relies on a standalone process, the syslogd daemon, that listens for incoming messages, typically on the /dev/log Unix-domain socket, and writes them to files or terminals according to user settings (see syslogd in GNU Inetutils). Each message sent to syslogd specifies its priority and originating facility along with the actual message (see Overview of Syslog in The GNU C Library Reference Manual).

The Shepherd provides an optional in-process service that can be used as a substitute for the traditional syslogd program. The configuration snippet below instantiates and registers that service for shepherd running as PID 1:

(use-modules (shepherd service system-log))

(register-services
  ;; Create a system log with the default settings.
  (list (system-log-service)))

;; Start it.
(start-service (lookup-service 'system-log))

The configuration above starts the service under the names system-log and syslogd. Messages are logged in files under /var/log, on /dev/tty12 (the twelfth console terminal on Linux), and on the console for emergency messages. The system-log service is integrated with the log rotation service: log files it creates are subject to log rotation, in a “race-free” fashion (see Log Rotation Service).

The destination of syslog messages—the files, terminals, etc. where they are written—can be configured by passing a procedure as the #:message-destination argument of system-log-service:

(define (message-destination message)
  ;; Return the list of files where MESSAGE is to be written.
  (cond ((member (system-log-message-priority message)
                 (list (system-log-priority emergency)
                       (system-log-priority alert)))
         ;; Important messages go both to a file and to the console.
         '("/dev/console" "/var/log/messages))
        ((string-prefix? "sudo" (system-log-message-content message))
         ;; Messages coming from sudo go to a dedicated file.
         '("/var/log/sudo"))
        ((member (system-log-message-facility message)
                 (list (system-log-facility authorization)
                       (system-log-facility authorization/private)))
         ;; Security-sensitive messages are written only to this
         ;; one file.
         '("/var/log/secure"))
        (else
         ;; Everything else goes to /var/log/messages.
         '("/var/log/messages"))))

(define my-syslogd
  ;; Customized system log instance.
  (system-log-service #:message-destination message-destination))

The example above shows how to assign different destinations based on message priority, facility, and content. Note that each message can be written to zero, one, or more files.

The interface to the system log service is provided by the (shepherd service system-log) module and described thereafter.

Procedure: system-log-message? obj

Return true if obj is a system log message.

Procedure: system-log-message-facility message
Procedure: system-log-message-priority message
Procedure: system-log-message-content message
Procedure: system-log-message-sender message

Return the given attribute of message, a system log message:

  • Its facility, an integer as constructed by system-log-facility. For example, the expression (system-log-facility mail) evaluates to the value of the “mail” facility.
  • Its priority, an integer as constructed by system-log-priority. For example, (system-log-priority debug) returns the “debug” priority.
  • Its content, a string.
  • Its sender, either #f, in which case the message originates from the local host, or a socket address as constructed by make-socket-address if the message originates from a different host (see below).
Procedure: system-log-service [sources] [#:provision ’(system-log syslogd)] [#:requirement ’()] [#:kernel-log-file (kernel-log-file)] [#:message-destination (default-message-destination-procedure)] [#:date-format default-logfile-date-format] [#:history-size (default-log-history-size)] [#:max-silent-time (default-max-silent-time)]

Return the system log service (syslogd) with the given provision and requirement (lists of symbols). The service accepts connections on sources, a list of <endpoint> objects; optionally it also reads messages from #:kernel-log-file, which defaults to /proc/kmsg when running as root.

Log messages are passed to message-destination, a one-argument procedure that must return the list of files to write it to. Write a mark to log files when no message has been logged for more than max-silent-time seconds. Timestamps in log files are formatted according to date-format, a format string for strftime, including delimiting space—e.g., \"%c \" for a format identical to that of traditional syslogd implementations.

Keep up to history-size messages in memory for the purposes of allowing users to view recent messages without opening various files.

Procedure: default-message-destination-procedure

Return a procedure that, given a system log message, returns a “good” default destination to log it to.

Variable: kernel-log-file

This SRFI-39 parameter denotes the location of the kernel log file, /proc/kmsg by default.

Variable: default-max-silent-time

This SRFI-39 parameter denotes the maximum number of seconds after which syslogd prints a “mark” in its files if it has not printed anything for this long.