[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[bug#30498] [PATCH 3/3] Use syslog for logging when running as root.
From: |
Ludovic Courtès |
Subject: |
[bug#30498] [PATCH 3/3] Use syslog for logging when running as root. |
Date: |
Wed, 7 Mar 2018 12:04:54 +0100 |
* modules/shepherd/comm.scm (call-with-syslog-port, syslog-output-port):
New procedures.
* modules/shepherd.scm (main): Set 'log-output-port'
to (syslog-output-port) when running as root.
* doc/shepherd.texi (Invoking shepherd): Adjust accordingly.
---
doc/shepherd.texi | 18 ++++++++++---
modules/shepherd.scm | 2 +-
modules/shepherd/comm.scm | 66 +++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 81 insertions(+), 5 deletions(-)
diff --git a/doc/shepherd.texi b/doc/shepherd.texi
index 01d8050..7946f8b 100644
--- a/doc/shepherd.texi
+++ b/doc/shepherd.texi
@@ -406,13 +406,23 @@ permissions are not as expected.
@cindex log file
Log output into @var{file}.
-The default behavior is to write to @file{/dev/kmsg} when running as
-superuser. This special device is GNU/Linux-specific; when it does not
-exist, write to @file{/var/log/shepherd.log} instead.
-
For unprivileged users, the default log file is
@file{$XDG_CONFIG_HOME/shepherd/shepherd.log}.
address@hidden syslog
+When running as root, the default behavior is to connect to
address@hidden/dev/log}, the @dfn{syslog} socket (@pxref{Overview of Syslog,,,
+libc, The GNU C Library Reference Manual}). A syslog daemon,
address@hidden, is expected to read messages from there
+(@pxref{syslogd invocation, syslogd,, libc, GNU Inetutils}).
+
+When @file{/dev/log} is unavailable, for instance because
address@hidden is not running, as is the case during system startup
+and shutdown, @command{shepherd} falls back to the Linux kernel
address@hidden buffer}, @file{/dev/kmsg}. If @file{/dev/kmsg} is missing, as
+is the case on other operating systems, it falls back to
address@hidden/dev/console}.
+
@item address@hidden
When @command{shepherd} is ready to accept connections, write its PID to
@var{file} or
to the standard output if @var{file} is omitted.
diff --git a/modules/shepherd.scm b/modules/shepherd.scm
index 39fbe14..fede338 100644
--- a/modules/shepherd.scm
+++ b/modules/shepherd.scm
@@ -168,7 +168,7 @@
(cond (logfile
(open-file logfile "al"))
((zero? (getuid))
- (open-file "/dev/kmsg" "wl"))
+ (syslog-output-port))
(else
(open-file (user-default-log-file) "al"))))
(%current-logfile-date-format
diff --git a/modules/shepherd/comm.scm b/modules/shepherd/comm.scm
index e686bfa..cbd8686 100644
--- a/modules/shepherd/comm.scm
+++ b/modules/shepherd/comm.scm
@@ -50,6 +50,7 @@
report-command-error
log-output-port
+ syslog-output-port
start-logging
stop-logging
make-shepherd-output-port
@@ -216,6 +217,71 @@ on service '~a':")
;; 'strftime' format strings for entries in the log file.
(make-parameter default-logfile-date-format))
+(define call-with-syslog-port
+ (let ((port #f)) ;connection to /dev/log
+ (lambda (proc)
+ "Call PROC with an open output port. The output port corresponds to
+/dev/log (aka. syslog) or, if that is unavailable, a degraded logging
+mechanism."
+ (define (call/syslog)
+ (catch 'system-error
+ (lambda ()
+ (proc port))
+ (lambda args
+ (if (memv (system-error-errno args)
+ (list ENOTCONN ECONNREFUSED EPIPE))
+ (begin
+ (set! port #f)
+ (call-with-syslog-port proc))
+ (apply throw args)))))
+
+ (or (and port (not (port-closed? port)) (call/syslog))
+ (let ((sock (socket AF_UNIX SOCK_DGRAM 0)))
+ (catch 'system-error
+ (lambda ()
+ (connect sock AF_UNIX "/dev/log")
+ (setvbuf sock _IOLBF)
+ (set! port sock)
+ (call/syslog))
+ (lambda args
+ (close-port sock)
+ (if (memv (system-error-errno args)
+ (list ENOENT ECONNREFUSED))
+ (catch 'system-error
+ (lambda ()
+ (call-with-output-file "/dev/kmsg"
+ (lambda (port)
+ (setvbuf port _IOFBF)
+ (proc port))))
+ (lambda args
+ (if (memv (system-error-errno args)
+ (list ENOENT EACCES EPERM))
+ (call-with-output-file "/dev/console"
+ (lambda (port)
+ (setvbuf port _IONBF)
+ (proc port)))
+ (apply throw args))))
+ (apply throw args)))))))))
+
+(define (syslog-output-port)
+ "Return the output port to write to syslog or /dev/kmsg, whichever is
+available."
+ (make-soft-port
+ (vector
+ (lambda (char) ;write char
+ (call-with-syslog-port
+ (lambda (port)
+ (write-char char port))))
+ (lambda (str) ;write string
+ (call-with-syslog-port
+ (lambda (port)
+ (display str port))))
+ (const #t) ;flush
+ #f ;get char
+ (lambda () ;close
+ (call-with-syslog-port close-port)))
+ "w")) ;output port
+
(define %not-newline
(char-set-complement (char-set #\newline)))
--
2.16.2
- [bug#30498] [WIP v2 shepherd] shepherd: If /dev/kmsg is writable, use it for logging., Ludovic Courtès, 2018/03/03
- [bug#30498] [WIP v2 shepherd] shepherd: If /dev/kmsg is writable, use it for logging., Danny Milosavljevic, 2018/03/03
- [bug#30498] [WIP v2 shepherd] shepherd: If /dev/kmsg is writable, use it for logging., Ludovic Courtès, 2018/03/05
- [bug#30498] [PATCH 0/3] Log to syslog whenever possible, Ludovic Courtès, 2018/03/07
- [bug#30498] [PATCH 2/3] Simplify 'make-shepherd-output-port'., Ludovic Courtès, 2018/03/07
- [bug#30498] [PATCH 1/3] Turn 'log-output-port' into a parameter., Ludovic Courtès, 2018/03/07
- [bug#30498] [PATCH 3/3] Use syslog for logging when running as root.,
Ludovic Courtès <=
- [bug#30498] [PATCH 0/3] Log to syslog whenever possible, Ludovic Courtès, 2018/03/07
- bug#30498: [PATCH 0/3] Log to syslog whenever possible, Ludovic Courtès, 2018/03/15