mirror of
https://github.com/sheumann/hush.git
synced 2024-11-19 23:31:39 +00:00
svlogd: fix bug 521: use line buffering if any filtering is done
function old new delta logdirs_reopen 1296 1310 +14 svlogd_main 1439 1444 +5 Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
This commit is contained in:
parent
e2944af43e
commit
aebb742939
@ -34,6 +34,7 @@ ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
#include "libbb.h"
|
#include "libbb.h"
|
||||||
#include "runit_lib.h"
|
#include "runit_lib.h"
|
||||||
|
|
||||||
|
#ifdef UNUSED
|
||||||
unsigned byte_chr(char *s,unsigned n,int c)
|
unsigned byte_chr(char *s,unsigned n,int c)
|
||||||
{
|
{
|
||||||
char ch;
|
char ch;
|
||||||
@ -50,7 +51,6 @@ unsigned byte_chr(char *s,unsigned n,int c)
|
|||||||
return t - s;
|
return t - s;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef UNUSED
|
|
||||||
static /* as it isn't used anywhere else */
|
static /* as it isn't used anywhere else */
|
||||||
void tai_pack(char *s, const struct tai *t)
|
void tai_pack(char *s, const struct tai *t)
|
||||||
{
|
{
|
||||||
|
@ -27,10 +27,8 @@ ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
|
|
||||||
PUSH_AND_SET_FUNCTION_VISIBILITY_TO_HIDDEN
|
PUSH_AND_SET_FUNCTION_VISIBILITY_TO_HIDDEN
|
||||||
|
|
||||||
extern unsigned byte_chr(char *s,unsigned n,int c);
|
//extern unsigned byte_chr(char *s,unsigned n,int c);
|
||||||
|
//
|
||||||
#define direntry struct dirent
|
|
||||||
|
|
||||||
//struct tai {
|
//struct tai {
|
||||||
// uint64_t x;
|
// uint64_t x;
|
||||||
//};
|
//};
|
||||||
|
@ -129,7 +129,7 @@ static NOINLINE pid_t runsv(const char *name)
|
|||||||
static NOINLINE int do_rescan(void)
|
static NOINLINE int do_rescan(void)
|
||||||
{
|
{
|
||||||
DIR *dir;
|
DIR *dir;
|
||||||
direntry *d;
|
struct dirent *d;
|
||||||
int i;
|
int i;
|
||||||
struct stat s;
|
struct stat s;
|
||||||
int need_rescan = 0;
|
int need_rescan = 0;
|
||||||
|
154
runit/svlogd.c
154
runit/svlogd.c
@ -28,6 +28,103 @@ ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
/* Busyboxed by Denys Vlasenko <vda.linux@googlemail.com> */
|
/* Busyboxed by Denys Vlasenko <vda.linux@googlemail.com> */
|
||||||
/* TODO: depends on runit_lib.c - review and reduce/eliminate */
|
/* TODO: depends on runit_lib.c - review and reduce/eliminate */
|
||||||
|
|
||||||
|
/*
|
||||||
|
Config files
|
||||||
|
|
||||||
|
On startup, and after receiving a HUP signal, svlogd checks for each
|
||||||
|
log directory log if the configuration file log/config exists,
|
||||||
|
and if so, reads the file line by line and adjusts configuration
|
||||||
|
for log as follows:
|
||||||
|
|
||||||
|
If the line is empty, or starts with a #, it is ignored. A line
|
||||||
|
of the form
|
||||||
|
|
||||||
|
ssize
|
||||||
|
sets the maximum file size of current when svlogd should rotate
|
||||||
|
the current log file to size bytes. Default is 1000000.
|
||||||
|
If size is zero, svlogd doesnt rotate log files
|
||||||
|
You should set size to at least (2 * len).
|
||||||
|
nnum
|
||||||
|
sets the number of old log files svlogd should maintain to num.
|
||||||
|
If svlogd sees more that num old log files in log after log file
|
||||||
|
rotation, it deletes the oldest one. Default is 10.
|
||||||
|
If num is zero, svlogd doesnt remove old log files.
|
||||||
|
Nmin
|
||||||
|
sets the minimum number of old log files svlogd should maintain
|
||||||
|
to min. min must be less than num. If min is set, and svlogd
|
||||||
|
cannot write to current because the filesystem is full,
|
||||||
|
and it sees more than min old log files, it deletes the oldest one.
|
||||||
|
ttimeout
|
||||||
|
sets the maximum age of the current log file when svlogd should
|
||||||
|
rotate the current log file to timeout seconds. If current
|
||||||
|
is timeout seconds old, and is not empty, svlogd forces log file rotation.
|
||||||
|
!processor
|
||||||
|
tells svlogd to feed each recent log file through processor
|
||||||
|
(see above) on log file rotation. By default log files are not processed.
|
||||||
|
ua.b.c.d[:port]
|
||||||
|
tells svlogd to transmit the first len characters of selected
|
||||||
|
log messages to the IP address a.b.c.d, port number port.
|
||||||
|
If port isnt set, the default port for syslog is used (514).
|
||||||
|
len can be set through the -l option, see below. If svlogd
|
||||||
|
has trouble sending udp packets, it writes error messages
|
||||||
|
to the log directory. Attention: logging through udp is unreliable,
|
||||||
|
and should be used in private networks only.
|
||||||
|
Ua.b.c.d[:port]
|
||||||
|
is the same as the u line above, but the log messages are no longer
|
||||||
|
written to the log directory, but transmitted through udp only.
|
||||||
|
Error messages from svlogd concerning sending udp packages still go
|
||||||
|
to the log directory.
|
||||||
|
pprefix
|
||||||
|
tells svlogd to prefix each line to be written to the log directory,
|
||||||
|
to standard error, or through UDP, with prefix.
|
||||||
|
|
||||||
|
If a line starts with a -, +, e, or E, svlogd matches the first len characters
|
||||||
|
of each log message against pattern and acts accordingly:
|
||||||
|
|
||||||
|
-pattern
|
||||||
|
the log message is deselected.
|
||||||
|
+pattern
|
||||||
|
the log message is selected.
|
||||||
|
epattern
|
||||||
|
the log message is selected to be printed to standard error.
|
||||||
|
Epattern
|
||||||
|
the log message is deselected to be printed to standard error.
|
||||||
|
|
||||||
|
Initially each line is selected to be written to log/current. Deselected
|
||||||
|
log messages are discarded from log. Initially each line is deselected
|
||||||
|
to be written to standard err. Log messages selected for standard error
|
||||||
|
are written to standard error.
|
||||||
|
|
||||||
|
Pattern Matching
|
||||||
|
|
||||||
|
svlogd matches a log message against the string pattern as follows:
|
||||||
|
|
||||||
|
pattern is applied to the log message one character by one, starting
|
||||||
|
with the first. A character not a star (*) and not a plus (+) matches itself.
|
||||||
|
A plus matches the next character in pattern in the log message one
|
||||||
|
or more times. A star before the end of pattern matches any string
|
||||||
|
in the log message that does not include the next character in pattern.
|
||||||
|
A star at the end of pattern matches any string.
|
||||||
|
|
||||||
|
Timestamps optionally added by svlogd are not considered part
|
||||||
|
of the log message.
|
||||||
|
|
||||||
|
An svlogd pattern is not a regular expression. For example consider
|
||||||
|
a log message like this
|
||||||
|
|
||||||
|
2005-12-18_09:13:50.97618 tcpsvd: info: pid 1977 from 10.4.1.14
|
||||||
|
|
||||||
|
The following pattern doesnt match
|
||||||
|
|
||||||
|
-*pid*
|
||||||
|
|
||||||
|
because the first star matches up to the first p in tcpsvd,
|
||||||
|
and then the match fails because i is not s. To match this
|
||||||
|
log message, you can use a pattern like this instead
|
||||||
|
|
||||||
|
-*: *: pid *
|
||||||
|
*/
|
||||||
|
|
||||||
#include <sys/poll.h>
|
#include <sys/poll.h>
|
||||||
#include <sys/file.h>
|
#include <sys/file.h>
|
||||||
#include "libbb.h"
|
#include "libbb.h"
|
||||||
@ -72,6 +169,8 @@ struct globals {
|
|||||||
int wstat;
|
int wstat;
|
||||||
unsigned nearest_rotate;
|
unsigned nearest_rotate;
|
||||||
|
|
||||||
|
void* (*memRchr)(const void *, int, size_t);
|
||||||
|
|
||||||
smallint exitasap;
|
smallint exitasap;
|
||||||
smallint rotateasap;
|
smallint rotateasap;
|
||||||
smallint reopenasap;
|
smallint reopenasap;
|
||||||
@ -94,6 +193,7 @@ struct globals {
|
|||||||
#define fndir (G.fndir )
|
#define fndir (G.fndir )
|
||||||
#define fdwdir (G.fdwdir )
|
#define fdwdir (G.fdwdir )
|
||||||
#define wstat (G.wstat )
|
#define wstat (G.wstat )
|
||||||
|
#define memRchr (G.memRchr )
|
||||||
#define nearest_rotate (G.nearest_rotate)
|
#define nearest_rotate (G.nearest_rotate)
|
||||||
#define exitasap (G.exitasap )
|
#define exitasap (G.exitasap )
|
||||||
#define rotateasap (G.rotateasap )
|
#define rotateasap (G.rotateasap )
|
||||||
@ -121,7 +221,6 @@ struct globals {
|
|||||||
#define PAUSE "pausing: "
|
#define PAUSE "pausing: "
|
||||||
#define INFO "info: "
|
#define INFO "info: "
|
||||||
|
|
||||||
#define usage() bb_show_usage()
|
|
||||||
static void fatalx(const char *m0)
|
static void fatalx(const char *m0)
|
||||||
{
|
{
|
||||||
bb_error_msg_and_die(FATAL"%s", m0);
|
bb_error_msg_and_die(FATAL"%s", m0);
|
||||||
@ -273,7 +372,8 @@ static unsigned processorstop(struct logdir *ld)
|
|||||||
sig_block(SIGHUP);
|
sig_block(SIGHUP);
|
||||||
ld->ppid = 0;
|
ld->ppid = 0;
|
||||||
}
|
}
|
||||||
if (ld->fddir == -1) return 1;
|
if (ld->fddir == -1)
|
||||||
|
return 1;
|
||||||
while (fchdir(ld->fddir) == -1)
|
while (fchdir(ld->fddir) == -1)
|
||||||
pause2cannot("change directory, want processor", ld->name);
|
pause2cannot("change directory, want processor", ld->name);
|
||||||
if (WEXITSTATUS(wstat) != 0) {
|
if (WEXITSTATUS(wstat) != 0) {
|
||||||
@ -564,6 +664,10 @@ static unsigned logdir_open(struct logdir *ld, const char *fn)
|
|||||||
case '-':
|
case '-':
|
||||||
case 'e':
|
case 'e':
|
||||||
case 'E':
|
case 'E':
|
||||||
|
/* Filtering requires one-line buffering,
|
||||||
|
* resetting the "find newline" function
|
||||||
|
* accordingly */
|
||||||
|
memRchr = memchr;
|
||||||
/* Add '\n'-terminated line to ld->inst */
|
/* Add '\n'-terminated line to ld->inst */
|
||||||
while (1) {
|
while (1) {
|
||||||
int l = asprintf(&new, "%s%s\n", ld->inst ? : "", s);
|
int l = asprintf(&new, "%s%s\n", ld->inst ? : "", s);
|
||||||
@ -708,7 +812,7 @@ static int buffer_pread(/*int fd, */char *s, unsigned len)
|
|||||||
struct pollfd input;
|
struct pollfd input;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
input.fd = 0;
|
input.fd = STDIN_FILENO;
|
||||||
input.events = POLLIN;
|
input.events = POLLIN;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
@ -852,12 +956,11 @@ static void logmatch(struct logdir *ld)
|
|||||||
int svlogd_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
|
int svlogd_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
|
||||||
int svlogd_main(int argc, char **argv)
|
int svlogd_main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
char *r,*l,*b;
|
char *r, *l, *b;
|
||||||
ssize_t stdin_cnt = 0;
|
ssize_t stdin_cnt = 0;
|
||||||
int i;
|
int i;
|
||||||
unsigned opt;
|
unsigned opt;
|
||||||
unsigned timestamp = 0;
|
unsigned timestamp = 0;
|
||||||
void* (*memRchr)(const void *, int, size_t) = memchr;
|
|
||||||
|
|
||||||
INIT_G();
|
INIT_G();
|
||||||
|
|
||||||
@ -866,13 +969,16 @@ int svlogd_main(int argc, char **argv)
|
|||||||
&r, &replace, &l, &b, ×tamp, &verbose);
|
&r, &replace, &l, &b, ×tamp, &verbose);
|
||||||
if (opt & 1) { // -r
|
if (opt & 1) { // -r
|
||||||
repl = r[0];
|
repl = r[0];
|
||||||
if (!repl || r[1]) usage();
|
if (!repl || r[1])
|
||||||
|
bb_show_usage();
|
||||||
}
|
}
|
||||||
if (opt & 2) if (!repl) repl = '_'; // -R
|
if (opt & 2) if (!repl) repl = '_'; // -R
|
||||||
if (opt & 4) { // -l
|
if (opt & 4) { // -l
|
||||||
linemax = xatou_range(l, 0, BUFSIZ-26);
|
linemax = xatou_range(l, 0, BUFSIZ-26);
|
||||||
if (linemax == 0) linemax = BUFSIZ-26;
|
if (linemax == 0)
|
||||||
if (linemax < 256) linemax = 256;
|
linemax = BUFSIZ-26;
|
||||||
|
if (linemax < 256)
|
||||||
|
linemax = 256;
|
||||||
}
|
}
|
||||||
////if (opt & 8) { // -b
|
////if (opt & 8) { // -b
|
||||||
//// buflen = xatoi_u(b);
|
//// buflen = xatoi_u(b);
|
||||||
@ -885,11 +991,12 @@ int svlogd_main(int argc, char **argv)
|
|||||||
argc -= optind;
|
argc -= optind;
|
||||||
|
|
||||||
dirn = argc;
|
dirn = argc;
|
||||||
if (dirn <= 0) usage();
|
if (dirn <= 0)
|
||||||
////if (buflen <= linemax) usage();
|
bb_show_usage();
|
||||||
|
////if (buflen <= linemax) bb_show_usage();
|
||||||
fdwdir = xopen(".", O_RDONLY|O_NDELAY);
|
fdwdir = xopen(".", O_RDONLY|O_NDELAY);
|
||||||
close_on_exec_on(fdwdir);
|
close_on_exec_on(fdwdir);
|
||||||
dir = xzalloc(dirn * sizeof(struct logdir));
|
dir = xzalloc(dirn * sizeof(dir[0]));
|
||||||
for (i = 0; i < dirn; ++i) {
|
for (i = 0; i < dirn; ++i) {
|
||||||
dir[i].fddir = -1;
|
dir[i].fddir = -1;
|
||||||
dir[i].fdcur = -1;
|
dir[i].fdcur = -1;
|
||||||
@ -914,13 +1021,14 @@ int svlogd_main(int argc, char **argv)
|
|||||||
bb_signals_recursive_norestart(1 << SIGALRM, sig_alarm_handler);
|
bb_signals_recursive_norestart(1 << SIGALRM, sig_alarm_handler);
|
||||||
bb_signals_recursive_norestart(1 << SIGHUP, sig_hangup_handler);
|
bb_signals_recursive_norestart(1 << SIGHUP, sig_hangup_handler);
|
||||||
|
|
||||||
logdirs_reopen();
|
|
||||||
|
|
||||||
/* Without timestamps, we don't have to print each line
|
/* Without timestamps, we don't have to print each line
|
||||||
* separately, so we can look for _last_ newline, not first,
|
* separately, so we can look for _last_ newline, not first,
|
||||||
* thus batching writes */
|
* thus batching writes. If filtering is enabled in config,
|
||||||
if (!timestamp)
|
* logdirs_reopen resets it to memchr.
|
||||||
memRchr = memrchr;
|
*/
|
||||||
|
memRchr = (timestamp ? memchr : memrchr);
|
||||||
|
|
||||||
|
logdirs_reopen();
|
||||||
|
|
||||||
setvbuf(stderr, NULL, _IOFBF, linelen);
|
setvbuf(stderr, NULL, _IOFBF, linelen);
|
||||||
|
|
||||||
@ -988,7 +1096,8 @@ int svlogd_main(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
for (i = 0; i < dirn; ++i) {
|
for (i = 0; i < dirn; ++i) {
|
||||||
struct logdir *ld = &dir[i];
|
struct logdir *ld = &dir[i];
|
||||||
if (ld->fddir == -1) continue;
|
if (ld->fddir == -1)
|
||||||
|
continue;
|
||||||
if (ld->inst)
|
if (ld->inst)
|
||||||
logmatch(ld);
|
logmatch(ld);
|
||||||
if (ld->matcherr == 'e') {
|
if (ld->matcherr == 'e') {
|
||||||
@ -996,7 +1105,8 @@ int svlogd_main(int argc, char **argv)
|
|||||||
////full_write(STDERR_FILENO, printptr, printlen);
|
////full_write(STDERR_FILENO, printptr, printlen);
|
||||||
fwrite(printptr, 1, printlen, stderr);
|
fwrite(printptr, 1, printlen, stderr);
|
||||||
}
|
}
|
||||||
if (ld->match != '+') continue;
|
if (ld->match != '+')
|
||||||
|
continue;
|
||||||
buffer_pwrite(i, printptr, printlen);
|
buffer_pwrite(i, printptr, printlen);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1019,12 +1129,14 @@ int svlogd_main(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
/* linelen == no of chars incl. '\n' (or == stdin_cnt) */
|
/* linelen == no of chars incl. '\n' (or == stdin_cnt) */
|
||||||
for (i = 0; i < dirn; ++i) {
|
for (i = 0; i < dirn; ++i) {
|
||||||
if (dir[i].fddir == -1) continue;
|
if (dir[i].fddir == -1)
|
||||||
|
continue;
|
||||||
if (dir[i].matcherr == 'e') {
|
if (dir[i].matcherr == 'e') {
|
||||||
////full_write(STDERR_FILENO, lineptr, linelen);
|
////full_write(STDERR_FILENO, lineptr, linelen);
|
||||||
fwrite(lineptr, 1, linelen, stderr);
|
fwrite(lineptr, 1, linelen, stderr);
|
||||||
}
|
}
|
||||||
if (dir[i].match != '+') continue;
|
if (dir[i].match != '+')
|
||||||
|
continue;
|
||||||
buffer_pwrite(i, lineptr, linelen);
|
buffer_pwrite(i, lineptr, linelen);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1046,7 +1158,7 @@ int svlogd_main(int argc, char **argv)
|
|||||||
for (i = 0; i < dirn; ++i) {
|
for (i = 0; i < dirn; ++i) {
|
||||||
if (dir[i].ppid)
|
if (dir[i].ppid)
|
||||||
while (!processorstop(&dir[i]))
|
while (!processorstop(&dir[i]))
|
||||||
/* repeat */;
|
continue;
|
||||||
logdir_close(&dir[i]);
|
logdir_close(&dir[i]);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
Loading…
Reference in New Issue
Block a user