civodul pushed a commit to branch main
in repository shepherd.

commit d13739be17bc64aef72cafcd3bbdf9f9c59ee29e
Author: Ludovic Courtès <l...@gnu.org>
AuthorDate: Wed Feb 19 15:36:30 2025 +0100

    shepherd: Add ‘--syslog’ option.
    
    * modules/shepherd.scm (main): Add ‘--syslog’ option.  Define
    ‘syslog-requested?’ and honor it.
    * doc/shepherd.texi (Invoking shepherd): Document it.
    * tests/services/system-log-self.sh: New file.
    * Makefile.am (TESTS): Add it.
    * NEWS: Update.
---
 Makefile.am                       |  1 +
 NEWS                              |  9 +++++
 doc/shepherd.texi                 |  8 +++-
 modules/shepherd.scm              | 16 +++++++-
 tests/services/system-log-self.sh | 78 +++++++++++++++++++++++++++++++++++++++
 5 files changed, 108 insertions(+), 4 deletions(-)

diff --git a/Makefile.am b/Makefile.am
index aa2edd9..3205729 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -298,6 +298,7 @@ TESTS =                                             \
   tests/services/log-rotation-internal.scm     \
   tests/services/system-log.sh                 \
   tests/services/system-log-internal.scm       \
+  tests/services/system-log-self.sh            \
   tests/services/transient.sh
 
 TEST_EXTENSIONS = .sh .scm
diff --git a/NEWS b/NEWS
index e688533..8f584c7 100644
--- a/NEWS
+++ b/NEWS
@@ -11,6 +11,15 @@ Copyright © 2013-2014, 2016, 2018-2020, 2022-2025 Ludovic 
Courtès <l...@gnu.or
 
 Please send Shepherd bug reports to bug-g...@gnu.org.
 
+* Changes in 1.0.3
+
+*** New ‘--syslog’ option of ‘shepherd’
+
+This option forces shepherd to write its output to syslog (the /dev/log socket
+by default).  This is already the case when shepherd runs as root so this
+option only makes sense for non-root shepherd instances, and its primary
+purpose is testing.
+
 * Changes in 1.0.2
 
 ** ‘daemonize’ action preserves replacement bindings for ‘sleep’ etc.
diff --git a/doc/shepherd.texi b/doc/shepherd.texi
index 642d065..0c7d752 100644
--- a/doc/shepherd.texi
+++ b/doc/shepherd.texi
@@ -371,10 +371,14 @@ For unprivileged users, the default log file is
 @file{$XDG_STATE_HOME/shepherd/shepherd.log} with @file{$XDG_STATE_HOME}
 defaulting to @file{$HOME/.local/state}.
 
+@item --syslog[=@var{file}]
 @cindex syslog
+Force logging to @var{file} (@file{/dev/log} by default), a @dfn{syslog}
+socket (@pxref{Overview of Syslog,,, libc, The GNU C Library Reference
+Manual}).
+
 When running as root, the default behavior is to connect to
-@file{/dev/log}, the @dfn{syslog} socket (@pxref{Overview of Syslog,,,
-libc, The GNU C Library Reference Manual}).  A syslog daemon,
+@file{/dev/log}.  A syslog daemon,
 @command{syslogd}, is expected to read messages from there
 (@pxref{syslogd invocation, syslogd,, inetutils, GNU Inetutils}).
 
diff --git a/modules/shepherd.scm b/modules/shepherd.scm
index 1a860e9..eea306d 100644
--- a/modules/shepherd.scm
+++ b/modules/shepherd.scm
@@ -411,6 +411,7 @@ fork in the child process."
   (initialize-cli)
 
   (let ((config-file #f)
+        (syslog-requested? #f)
        (socket-file default-socket-file)
         (pid-file    #f)
         (secure      #t)
@@ -472,14 +473,25 @@ fork in the child process."
                    #:action (lambda (file)
                               (set! socket-file
                                     (and (not (string=? file "-"))
-                                         file)))))
+                                         file))))
+                  (option
+                   #:long-name "syslog"
+                   #:takes-argument? #t #:argument-is-optional? #t
+                   #:argument-name (l10n "FILE")
+                   #:description
+                   (l10n "log to the system log (syslog) at FILE or /dev/log")
+                   #:action (lambda (file)
+                              (when file
+                                (system-log-file file))
+                              (set! syslog-requested? #t))))
     ;; We do this early so that we can abort early if necessary.
     (and socket-file
          (verify-dir (dirname socket-file) #:secure? secure))
 
     (define syslog?
       ;; Is shepherd logging to /dev/log?
-      (and (not logfile) (= 1 (getpid))))
+      (or syslog-requested?
+          (and (not logfile) (= 1 (getpid)))))
 
     ;; By default, enable detailed deprecation warnings.
     (unless (getenv "GUILE_WARN_DEPRECATED")
diff --git a/tests/services/system-log-self.sh 
b/tests/services/system-log-self.sh
new file mode 100755
index 0000000..76062b9
--- /dev/null
+++ b/tests/services/system-log-self.sh
@@ -0,0 +1,78 @@
+# GNU Shepherd --- Test system logging service for shepherd itself.
+# Copyright © 2025 Ludovic Courtès <l...@gnu.org>
+#
+# This file is part of the GNU Shepherd.
+#
+# The GNU Shepherd is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or (at
+# your option) any later version.
+#
+# The GNU Shepherd is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with the GNU Shepherd.  If not, see <http://www.gnu.org/licenses/>.
+
+shepherd --version
+herd --version
+
+socket="t-socket-$$"
+conf="t-conf-$$"
+pid="t-pid-$$"
+syslog_file="$PWD/t-syslog-$$"
+syslog_socket="$PWD/t-syslog-socket-$$"
+
+herd="herd -s $socket"
+
+trap "cat $syslog_file || true;
+      rm -f $socket $conf $syslog_socket $syslogfile;
+      test -f $pid && kill \`cat $pid\` || true; rm -f $pid" EXIT
+
+cat > "$conf" <<EOF
+(use-modules (shepherd service system-log)
+             (shepherd endpoints))
+
+(define %endpoints
+  (list (endpoint (make-socket-address AF_UNIX "$syslog_socket")
+                  #:style SOCK_DGRAM)))
+
+(register-services
+  (list (system-log-service %endpoints
+                            #:message-destination (const '("$syslog_file"))
+                            #:kernel-log-file #f)
+        (service
+          '(logger)
+          #:requirement '(syslogd)
+          #:start (make-forkexec-constructor
+                   '("$SHELL" "-c" "while true; do echo logging from \$\$; 
sleep 0.2; done"))
+          #:stop (make-kill-destructor)
+          #:respawn? #f)))
+EOF
+
+
+rm -f "$pid"
+
+# Log to syslog, with syslog implemented by shepherd itself.
+shepherd -I -s "$socket" -c "$conf" --syslog="$syslog_socket" --pid="$pid" &
+
+# Wait till it's ready.
+until test -f "$pid" ; do sleep 0.3 ; done
+
+$herd start system-log
+$herd status system-log | grep running
+grep "system-log started" "$syslog_file"
+
+$herd start logger
+grep "logger started" "$syslog_file"
+
+logger_pid="$($herd status logger | grep "PID: [0-9]\+" \
+  | sed -e's/^.* \([0-9]\+\)$/\1/g')"
+kill -0 "$logger_pid"
+
+until grep "logging from $logger_pid" "$syslog_file"; do sleep 0.2; done
+
+$herd stop root
+grep "Exiting" "$syslog_file"

Reply via email to