[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[shepherd] 04/04: Use syslog for logging when running as root.
From: |
Ludovic Courtès |
Subject: |
[shepherd] 04/04: Use syslog for logging when running as root. |
Date: |
Thu, 15 Mar 2018 12:58:35 -0400 (EDT) |
civodul pushed a commit to branch master
in repository shepherd.
commit 968678c04b488a944e5951f710b80af4b6a80607
Author: Ludovic Courtès <address@hidden>
Date: Tue Mar 6 21:43:07 2018 +0100
Use syslog for logging when running as root.
* 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)))