commit a39a69a810620946ba52770c3a9572e4e126f9d5
parent 214fcdea64c0a1b64cd7497652340a64460e2ab7
Author: Laurent Bercot <ska-skaware@skarnet.org>
Date: Tue, 15 Jan 2019 14:48:41 +0000
Add readiness notification to s6-log, and 8kB default on -l
Diffstat:
2 files changed, 29 insertions(+), 9 deletions(-)
diff --git a/doc/s6-log.html b/doc/s6-log.html
@@ -27,7 +27,7 @@ with full POSIX regular expression support.
<h2> Interface </h2>
<pre>
- s6-log [ -q | -v ] [ -b ] [ -p ] [ -t ] [ -e ] [ -l linelimit ] <em>logging script</em>
+ s6-log [ -d <em>notif</em> ] [ -q | -v ] [ -b ] [ -p ] [ -t ] [ -e ] [ -l <em>linelimit</em> ] <em>logging script</em>
</pre>
<p>
@@ -41,6 +41,13 @@ it receives a SIGTERM or a SIGHUP.
<h2> Options </h2>
<ul>
+ <li> <tt>-d <em>notif</em></tt> :
+<a href="notifywhenup.html">readiness notification.</a>
+With this option, s6-log writes a newline character to file descriptor
+<em>notif</em> when it is <em>ready</em>, i.e. when it has successfully
+parsed its logging script and initialized all its necessary resources
+such as the logdirs defined in the script, and is now listening to stdin
+in order to process log lines. </li>
<li> <tt>-b</tt> : blocking mode. With this option, s6-log stops
reading its standard input while it has unflushed buffers. This ensures that
every log line has been fully processed before reading the next one; this is also
@@ -71,8 +78,7 @@ Currently supported verbosity levels:
may appear anywhere after <em>linelimit</em> or more bytes. <em>linelimit</em>
cannot be less than 48. Using this option ensures that an ill-formatted log
stream will not make s6-log uncontrollably eat memory by trying to read and
-process an extremely long line in one go. The default is no cap on line
-length. </li>
+process an extremely long line in one go. The default is 8192 bytes. </li>
</ul>
<h2> Logdirs </h2>
diff --git a/src/daemontools-extras/s6-log.c b/src/daemontools-extras/s6-log.c
@@ -1,5 +1,6 @@
/* ISC license. */
+#include <fcntl.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <stdint.h>
@@ -10,6 +11,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <regex.h>
+
#include <skalibs/posixplz.h>
#include <skalibs/uint64.h>
#include <skalibs/types.h>
@@ -31,9 +33,10 @@
#include <skalibs/siovec.h>
#include <skalibs/skamisc.h>
#include <skalibs/environ.h>
+
#include <execline/config.h>
-#define USAGE "s6-log [ -q | -v ] [ -b ] [ -p ] [ -t ] [ -e ] [ -l linelimit ] logging_script"
+#define USAGE "s6-log [ -d notif ] [ -q | -v ] [ -b ] [ -p ] [ -t ] [ -e ] [ -l linelimit ] logging_script"
#define dieusage() strerr_dieusage(100, USAGE)
#define dienomem() strerr_diefu1sys(111, "stralloc_catb")
@@ -611,9 +614,7 @@ static inline void logdir_init (unsigned int index, uint32_t s, uint32_t n, uint
if (finish(ldp, "current", 'u') < 0)
strerr_diefu2sys(111, "finish current .u for logdir ", ldp->dir) ;
memcpy(x + dirlen + 1, "state", 6) ;
- ldp->fd = open_trunc(x) ;
- if (ldp->fd < 0) strerr_diefu2sys(111, "open_trunc ", x) ;
- fd_close(ldp->fd) ;
+ if (truncate(x, 0) == -1) strerr_diefu2sys(111, "truncate ", x) ;
st.st_size = 0 ;
memcpy(x + dirlen + 1, "current", 8) ;
opencurrent:
@@ -1141,14 +1142,17 @@ static inline void handle_signals (void)
int main (int argc, char const *const *argv)
{
unsigned int sellen, actlen, scriptlen ;
- unsigned int linelimit = 0, gflags = 0, compat_gflags = 0 ;
+ unsigned int linelimit = 8192 ;
+ unsigned int notif = 0 ;
+ unsigned int gflags = 0 ;
+ unsigned int compat_gflags = 0 ;
int flagblock = 0 ;
PROG = "s6-log" ;
{
subgetopt_t l = SUBGETOPT_ZERO ;
for (;;)
{
- int opt = subgetopt_r(argc, argv, "qvbptel:", &l) ;
+ int opt = subgetopt_r(argc, argv, "qvbptel:d:", &l) ;
if (opt == -1) break ;
switch (opt)
{
@@ -1159,6 +1163,11 @@ int main (int argc, char const *const *argv)
case 't' : gflags |= 1 ; compat_gflags |= 1 ; break ;
case 'e' : gflags |= 1 ; compat_gflags |= 2 ; break ;
case 'l' : if (!uint0_scan(l.arg, &linelimit)) dieusage() ; break ;
+ case 'd' :
+ if (!uint0_scan(l.arg, ¬if)) dieusage() ;
+ if (notif < 3) strerr_dief1x(100, "notification fd must be 3 or more") ;
+ if (fcntl(notif, F_GETFD) < 0) strerr_dief1sys(100, "invalid notification fd") ;
+ break ;
default : dieusage() ;
}
}
@@ -1194,6 +1203,11 @@ int main (int argc, char const *const *argv)
strerr_diefu1sys(111, "selfpipe_trapset") ;
}
x[0].events = IOPAUSE_READ ;
+ if (notif)
+ {
+ fd_write(notif, "\n", 1) ;
+ fd_close(notif) ;
+ }
for (;;)
{