s6

Mirror/fork of https://skarnet.org/software/s6/
git clone https://ccx.te2000.cz/git/s6
Log | Files | Refs | README | LICENSE

commit ddc76841398dfd5e18b22943727ad74b880236d3
parent cac30eda3f3dbb3c690715df5b2867d22b1fc497
Author: Laurent Bercot <ska-skaware@skarnet.org>
Date:   Wed,  7 Dec 2022 17:40:23 +0000

 s6-log: add p directive to add a prefix to every line

Signed-off-by: Laurent Bercot <ska@appnovation.com>

Diffstat:
Mdoc/s6-log.html | 6++++++
Msrc/daemontools-extras/s6-log.c | 65++++++++++++++++++++++++++++++++++++++++++++++++-----------------
2 files changed, 54 insertions(+), 17 deletions(-)

diff --git a/doc/s6-log.html b/doc/s6-log.html @@ -228,6 +228,12 @@ bytes of the selected lines will be used in the next status file updates. If a line is shorter than <em>statussize</em> bytes, the status file will be padded with newlines so it is always <em>statussize</em> bytes long. 0 means an unpadded, unlimited status file. By default, <em>statussize</em> is 1001. </li> + <li> <strong>p<em>prefix</em></strong>: sets <em>prefix</em> as a prefix to be +printed on every output line. For instance, a <tt>pfoobar:</tt> directive means +that the next action directives should prepend every line with <tt>foobar:</tt> +(plus a space) before outputting it. Note that a prefix is always printed +<em>after</em> the timestamps, if any. To remove a prefix for the next action +directives, use <tt>p</tt>. </li> <li> <strong>!<em>processor</em></strong>: registers <tt>execlineb -Pc <em>processor</em></tt> as a processor for the next logdirs; <tt>execlineb</tt> must be found in s6-log's PATH. This directive is only diff --git a/src/daemontools-extras/s6-log.c b/src/daemontools-extras/s6-log.c @@ -128,6 +128,8 @@ struct act_s acttype_t type ; actstuff_t data ; unsigned int flags ; + char const *prefix ; + size_t prefixlen ; } ; typedef struct scriptelem_s scriptelem_t, *scriptelem_t_ref ; @@ -714,6 +716,7 @@ static inline void script_firstpass (char const *const *argv, unsigned int *sell case 'r' : case 'E' : case '^' : + case 'p' : #ifdef S6_USE_EXECLINE case '!' : #endif @@ -773,6 +776,8 @@ static inline void script_secondpass (char const *const *argv, scriptelem_t *scr uint32_t tolerance = 2000 ; uint64_t maxdirsize = 0 ; char const *processor = 0 ; + char const *prefix = 0 ; + size_t prefixlen = 0 ; unsigned int sel = 0, act = 0, lidx = 0, flags = 0 ; int flagacted = 0 ; tain_uint(&retrytto, 2) ; @@ -839,6 +844,10 @@ static inline void script_secondpass (char const *const *argv, scriptelem_t *scr case '^' : if (!uint0_scan(*argv + 1, &status_size)) goto fail ; break ; + case 'p' : + if ((*argv)[1]) { prefix = *argv + 1 ; prefixlen = strlen(prefix) ; } + else { prefix = 0 ; prefixlen = 0 ; } + break ; #ifdef S6_USE_EXECLINE case '!' : processor = (*argv)[1] ? *argv + 1 : 0 ; @@ -857,26 +866,26 @@ static inline void script_secondpass (char const *const *argv, scriptelem_t *scr break ; case '1' : { - act_t a = { .type = ACTTYPE_FD1, .flags = flags } ; + act_t a = { .type = ACTTYPE_FD1, .flags = flags, .prefix = prefix, .prefixlen = prefixlen } ; actions[act++] = a ; flagacted = 1 ; flags = 0 ; break ; } case '2' : { - act_t a = { .type = ACTTYPE_FD2, .flags = flags, .data = { .fd2_size = fd2_size } } ; + act_t a = { .type = ACTTYPE_FD2, .flags = flags, .prefix = prefix, .prefixlen = prefixlen, .data = { .fd2_size = fd2_size } } ; actions[act++] = a ; flagacted = 1 ; flags = 0 ; break ; } case '=' : { - act_t a = { .type = ACTTYPE_STATUS, .flags = flags, .data = { .status = { .file = *argv + 1, .filelen = status_size } } } ; + act_t a = { .type = ACTTYPE_STATUS, .flags = flags, .prefix = prefix, .prefixlen = prefixlen, .data = { .status = { .file = *argv + 1, .filelen = status_size } } } ; actions[act++] = a ; flagacted = 1 ; flags = 0 ; break ; } case '.' : case '/' : { - act_t a = { .type = ACTTYPE_DIR, .flags = flags, .data = { .ld = lidx } } ; + act_t a = { .type = ACTTYPE_DIR, .flags = flags, .prefix = prefix, .prefixlen = prefixlen, .data = { .ld = lidx } } ; logdir_init(lidx, s, n, tolerance, maxdirsize, &retrytto, processor, *argv, flags) ; lidx++ ; actions[act++] = a ; flagacted = 1 ; flags = 0 ; @@ -949,11 +958,33 @@ static void script_run (scriptelem_t const *script, unsigned int scriptlen, char for (j = 0 ; j < script[i].actlen ; j++) { act_t const *act = script[i].acts + j ; - struct iovec v[4] = { { .iov_base = tstamp, .iov_len = act->flags & 1 ? TIMESTAMP+1 : 0 }, { .iov_base = hstamp, .iov_len = act->flags & 2 ? hlen : 0 }, { .iov_base = (char *)s, .iov_len = len }, { .iov_base = "\n", .iov_len = 1 } } ; + unsigned int m = 0 ; + struct iovec v[6] ; + if (act->flags & 1) + { + v[m].iov_base = tstamp ; + v[m++].iov_len = TIMESTAMP+1 ; + } + if (act->flags & 2) + { + v[m].iov_base = hstamp ; + v[m++].iov_len = hlen ; + } + if (act->prefix) + { + v[m].iov_base = (char *)act->prefix ; + v[m++].iov_len = act->prefixlen ; + v[m].iov_base = " " ; + v[m++].iov_len = 1 ; + } + v[m].iov_base = (char *)s ; + v[m++].iov_len = len ; + v[m].iov_base = "\n" ; + v[m++].iov_len = 1 ; switch (act->type) { case ACTTYPE_FD1 : - if (!bufalloc_putv(bufalloc_1, v, 4)) dienomem() ; + if (!bufalloc_putv(bufalloc_1, v, m)) dienomem() ; case ACTTYPE_NOTHING : break ; @@ -962,38 +993,38 @@ static void script_run (scriptelem_t const *script, unsigned int scriptlen, char buffer_puts(buffer_2, ": alert: ") ; if (act->data.fd2_size && act->data.fd2_size + 3 < len) { - v[2].iov_len = act->data.fd2_size ; - v[3].iov_base = "...\n" ; - v[3].iov_len = 4 ; + v[m-2].iov_len = act->data.fd2_size ; + v[m-1].iov_base = "...\n" ; + v[m-1].iov_len = 4 ; } - buffer_putv(buffer_2, v, 4) ; + buffer_putv(buffer_2, v, m) ; buffer_flush(buffer_2) ; /* if it blocks, too bad */ break ; case ACTTYPE_STATUS : if (act->data.status.filelen) { - size_t reallen = siovec_len(v, 4) ; + size_t reallen = siovec_len(v, m) ; if (reallen > act->data.status.filelen) - siovec_trunc(v, 4, act->data.status.filelen) ; + siovec_trunc(v, m, act->data.status.filelen) ; else { size_t k = act->data.status.filelen - reallen + 1 ; char pad[k] ; - v[3].iov_base = pad ; - v[3].iov_len = k ; + v[m-1].iov_base = pad ; + v[m-1].iov_len = k ; while (k--) pad[k] = '\n' ; - if (!openwritevnclose_suffix(act->data.status.file, v, 4, ".new") && verbosity) + if (!openwritevnclose_suffix(act->data.status.file, v, m, ".new") && verbosity) strerr_warnwu2sys("write status file ", act->data.status.file) ; break ; } } - if (!openwritevnclose_suffix(act->data.status.file, v, 4, ".new") && verbosity) + if (!openwritevnclose_suffix(act->data.status.file, v, m, ".new") && verbosity) strerr_warnwu2sys("write status file ", act->data.status.file) ; break ; case ACTTYPE_DIR : - if (!bufalloc_putv(&logdirs[act->data.ld].out, v, 4)) dienomem() ; + if (!bufalloc_putv(&logdirs[act->data.ld].out, v, m)) dienomem() ; break ; default :