syslogd: optional support for dropping dups. closes bug 436.
This commit is contained in:
parent
06aed4316e
commit
be048f21e6
@ -3686,22 +3686,24 @@ USE_FEATURE_RUN_PARTS_FANCY("\n -l Prints names of all matching files even when
|
|||||||
"[OPTION]..."
|
"[OPTION]..."
|
||||||
#define syslogd_full_usage \
|
#define syslogd_full_usage \
|
||||||
"System logging utility.\n" \
|
"System logging utility.\n" \
|
||||||
"Note that this version of syslogd ignores /etc/syslog.conf." \
|
"Note that this version of syslogd ignores /etc/syslog.conf.\n" \
|
||||||
"\n\nOptions:" \
|
"\nOptions:" \
|
||||||
"\n -n Run in foreground" \
|
"\n -n Run in foreground" \
|
||||||
"\n -O FILE Log to given file (default=/var/log/messages)" \
|
"\n -O FILE Log to given file (default=/var/log/messages)" \
|
||||||
"\n -l n Set local log level" \
|
"\n -l n Set local log level" \
|
||||||
"\n -S Smaller logging output" \
|
"\n -S Smaller logging output" \
|
||||||
USE_FEATURE_ROTATE_LOGFILE( \
|
USE_FEATURE_ROTATE_LOGFILE( \
|
||||||
"\n -s SIZE Max size (KB) before rotate (default=200KB, 0=off)" \
|
"\n -s SIZE Max size (KB) before rotate (default=200KB, 0=off)" \
|
||||||
"\n -b NUM Number of rotated logs to keep (default=1, max=99, 0=purge)") \
|
"\n -b NUM Number of rotated logs to keep (default=1, max=99, 0=purge)") \
|
||||||
USE_FEATURE_REMOTE_LOG( \
|
USE_FEATURE_REMOTE_LOG( \
|
||||||
"\n -R HOST[:PORT] Log to IP or hostname on PORT (default PORT=514/UDP)" \
|
"\n -R HOST[:PORT] Log to IP or hostname on PORT (default PORT=514/UDP)" \
|
||||||
"\n -L Log locally and via network (default is network only if -R)") \
|
"\n -L Log locally and via network (default is network only if -R)") \
|
||||||
|
USE_FEATURE_SYSLOGD_DUP( \
|
||||||
|
"\n -D Drop duplicates") \
|
||||||
USE_FEATURE_IPC_SYSLOG( \
|
USE_FEATURE_IPC_SYSLOG( \
|
||||||
"\n -C[size(KiB)] Log to shared mem buffer (read it using logread)")
|
"\n -C[size(KiB)] Log to shared mem buffer (read it using logread)")
|
||||||
/* NB: -Csize shouldn't have space (because size is optional) */
|
/* NB: -Csize shouldn't have space (because size is optional) */
|
||||||
/* "\n -m MIN Minutes between MARK lines (default=20, 0=off)" */
|
/* "\n -m MIN Minutes between MARK lines (default=20, 0=off)" */
|
||||||
#define syslogd_example_usage \
|
#define syslogd_example_usage \
|
||||||
"$ syslogd -R masterlog:514\n" \
|
"$ syslogd -R masterlog:514\n" \
|
||||||
"$ syslogd -R 192.168.1.1:601\n"
|
"$ syslogd -R 192.168.1.1:601\n"
|
||||||
|
@ -42,6 +42,14 @@ config FEATURE_REMOTE_LOG
|
|||||||
measure to prevent system logs from being tampered with
|
measure to prevent system logs from being tampered with
|
||||||
by an intruder.
|
by an intruder.
|
||||||
|
|
||||||
|
config FEATURE_SYSLOGD_DUP
|
||||||
|
bool "Support -D (drop dups) option"
|
||||||
|
default n
|
||||||
|
depends on SYSLOGD
|
||||||
|
help
|
||||||
|
Option -D instructs syslogd to drop consecutive messages
|
||||||
|
which are totally the same.
|
||||||
|
|
||||||
config FEATURE_IPC_SYSLOG
|
config FEATURE_IPC_SYSLOG
|
||||||
bool "Circular Buffer support"
|
bool "Circular Buffer support"
|
||||||
default n
|
default n
|
||||||
|
@ -101,7 +101,7 @@ struct globals {
|
|||||||
char *hostname;
|
char *hostname;
|
||||||
|
|
||||||
/* We recv into recvbuf... */
|
/* We recv into recvbuf... */
|
||||||
char recvbuf[MAX_READ];
|
char recvbuf[MAX_READ * (1 + ENABLE_FEATURE_SYSLOGD_DUP)];
|
||||||
/* ...then copy to parsebuf, escaping control chars */
|
/* ...then copy to parsebuf, escaping control chars */
|
||||||
/* (can grow x2 max) */
|
/* (can grow x2 max) */
|
||||||
char parsebuf[MAX_READ*2];
|
char parsebuf[MAX_READ*2];
|
||||||
@ -152,6 +152,7 @@ enum {
|
|||||||
USE_FEATURE_REMOTE_LOG( OPTBIT_remote ,) // -R
|
USE_FEATURE_REMOTE_LOG( OPTBIT_remote ,) // -R
|
||||||
USE_FEATURE_REMOTE_LOG( OPTBIT_locallog ,) // -L
|
USE_FEATURE_REMOTE_LOG( OPTBIT_locallog ,) // -L
|
||||||
USE_FEATURE_IPC_SYSLOG( OPTBIT_circularlog,) // -C
|
USE_FEATURE_IPC_SYSLOG( OPTBIT_circularlog,) // -C
|
||||||
|
USE_FEATURE_SYSLOGD_DUP( OPTBIT_dup ,) // -D
|
||||||
|
|
||||||
OPT_mark = 1 << OPTBIT_mark ,
|
OPT_mark = 1 << OPTBIT_mark ,
|
||||||
OPT_nofork = 1 << OPTBIT_nofork ,
|
OPT_nofork = 1 << OPTBIT_nofork ,
|
||||||
@ -163,13 +164,15 @@ enum {
|
|||||||
OPT_remotelog = USE_FEATURE_REMOTE_LOG( (1 << OPTBIT_remote )) + 0,
|
OPT_remotelog = USE_FEATURE_REMOTE_LOG( (1 << OPTBIT_remote )) + 0,
|
||||||
OPT_locallog = USE_FEATURE_REMOTE_LOG( (1 << OPTBIT_locallog )) + 0,
|
OPT_locallog = USE_FEATURE_REMOTE_LOG( (1 << OPTBIT_locallog )) + 0,
|
||||||
OPT_circularlog = USE_FEATURE_IPC_SYSLOG( (1 << OPTBIT_circularlog)) + 0,
|
OPT_circularlog = USE_FEATURE_IPC_SYSLOG( (1 << OPTBIT_circularlog)) + 0,
|
||||||
|
OPT_dup = USE_FEATURE_SYSLOGD_DUP( (1 << OPTBIT_dup )) + 0,
|
||||||
};
|
};
|
||||||
#define OPTION_STR "m:nO:l:S" \
|
#define OPTION_STR "m:nO:l:S" \
|
||||||
USE_FEATURE_ROTATE_LOGFILE("s:" ) \
|
USE_FEATURE_ROTATE_LOGFILE("s:" ) \
|
||||||
USE_FEATURE_ROTATE_LOGFILE("b:" ) \
|
USE_FEATURE_ROTATE_LOGFILE("b:" ) \
|
||||||
USE_FEATURE_REMOTE_LOG( "R:" ) \
|
USE_FEATURE_REMOTE_LOG( "R:" ) \
|
||||||
USE_FEATURE_REMOTE_LOG( "L" ) \
|
USE_FEATURE_REMOTE_LOG( "L" ) \
|
||||||
USE_FEATURE_IPC_SYSLOG( "C::")
|
USE_FEATURE_IPC_SYSLOG( "C::") \
|
||||||
|
USE_FEATURE_SYSLOGD_DUP( "D" )
|
||||||
#define OPTION_DECL *opt_m, *opt_l \
|
#define OPTION_DECL *opt_m, *opt_l \
|
||||||
USE_FEATURE_ROTATE_LOGFILE(,*opt_s) \
|
USE_FEATURE_ROTATE_LOGFILE(,*opt_s) \
|
||||||
USE_FEATURE_ROTATE_LOGFILE(,*opt_b) \
|
USE_FEATURE_ROTATE_LOGFILE(,*opt_b) \
|
||||||
@ -538,6 +541,13 @@ static void do_syslogd(void) ATTRIBUTE_NORETURN;
|
|||||||
static void do_syslogd(void)
|
static void do_syslogd(void)
|
||||||
{
|
{
|
||||||
int sock_fd;
|
int sock_fd;
|
||||||
|
#if ENABLE_FEATURE_SYSLOGD_DUP
|
||||||
|
int last_sz = -1;
|
||||||
|
char *last_buf;
|
||||||
|
char *recvbuf = G.recvbuf;
|
||||||
|
#else
|
||||||
|
#define recvbuf (G.recvbuf)
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Set up signal handlers */
|
/* Set up signal handlers */
|
||||||
bb_signals(0
|
bb_signals(0
|
||||||
@ -561,8 +571,16 @@ static void do_syslogd(void)
|
|||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
size_t sz;
|
size_t sz;
|
||||||
|
|
||||||
|
#if ENABLE_FEATURE_SYSLOGD_DUP
|
||||||
|
last_buf = recvbuf;
|
||||||
|
if (recvbuf == G.recvbuf)
|
||||||
|
recvbuf = G.recvbuf + MAX_READ;
|
||||||
|
else
|
||||||
|
recvbuf = G.recvbuf;
|
||||||
|
#endif
|
||||||
read_again:
|
read_again:
|
||||||
sz = safe_read(sock_fd, G.recvbuf, MAX_READ - 1);
|
sz = safe_read(sock_fd, recvbuf, MAX_READ - 1);
|
||||||
if (sz < 0)
|
if (sz < 0)
|
||||||
bb_perror_msg_and_die("read from /dev/log");
|
bb_perror_msg_and_die("read from /dev/log");
|
||||||
|
|
||||||
@ -577,11 +595,16 @@ static void do_syslogd(void)
|
|||||||
* IOW: newline is passed verbatim!
|
* IOW: newline is passed verbatim!
|
||||||
* I take it to mean that it's syslogd's job
|
* I take it to mean that it's syslogd's job
|
||||||
* to make those look identical in the log files. */
|
* to make those look identical in the log files. */
|
||||||
if (G.recvbuf[sz-1] != '\0' && G.recvbuf[sz-1] != '\n')
|
if (recvbuf[sz-1] != '\0' && recvbuf[sz-1] != '\n')
|
||||||
break;
|
break;
|
||||||
sz--;
|
sz--;
|
||||||
}
|
}
|
||||||
/* TODO: maybe suppress duplicates? */
|
#if ENABLE_FEATURE_SYSLOGD_DUP
|
||||||
|
if ((option_mask32 & OPT_dup) && (sz == last_sz))
|
||||||
|
if (memcmp(last_buf, recvbuf, sz) == 0)
|
||||||
|
continue;
|
||||||
|
last_sz = sz;
|
||||||
|
#endif
|
||||||
#if ENABLE_FEATURE_REMOTE_LOG
|
#if ENABLE_FEATURE_REMOTE_LOG
|
||||||
/* We are not modifying log messages in any way before send */
|
/* We are not modifying log messages in any way before send */
|
||||||
/* Remote site cannot trust _us_ anyway and need to do validation again */
|
/* Remote site cannot trust _us_ anyway and need to do validation again */
|
||||||
@ -593,18 +616,18 @@ static void do_syslogd(void)
|
|||||||
}
|
}
|
||||||
/* Stock syslogd sends it '\n'-terminated
|
/* Stock syslogd sends it '\n'-terminated
|
||||||
* over network, mimic that */
|
* over network, mimic that */
|
||||||
G.recvbuf[sz] = '\n';
|
recvbuf[sz] = '\n';
|
||||||
/* send message to remote logger, ignore possible error */
|
/* send message to remote logger, ignore possible error */
|
||||||
/* TODO: on some errors, close and set G.remoteFD to -1
|
/* TODO: on some errors, close and set G.remoteFD to -1
|
||||||
* so that DNS resolution and connect is retried? */
|
* so that DNS resolution and connect is retried? */
|
||||||
sendto(G.remoteFD, G.recvbuf, sz+1, MSG_DONTWAIT,
|
sendto(G.remoteFD, recvbuf, sz+1, MSG_DONTWAIT,
|
||||||
&G.remoteAddr->u.sa, G.remoteAddr->len);
|
&G.remoteAddr->u.sa, G.remoteAddr->len);
|
||||||
no_luck: ;
|
no_luck: ;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
if (!ENABLE_FEATURE_REMOTE_LOG || (option_mask32 & OPT_locallog)) {
|
if (!ENABLE_FEATURE_REMOTE_LOG || (option_mask32 & OPT_locallog)) {
|
||||||
G.recvbuf[sz] = '\0'; /* ensure it *is* NUL terminated */
|
recvbuf[sz] = '\0'; /* ensure it *is* NUL terminated */
|
||||||
split_escape_and_log(G.recvbuf, sz);
|
split_escape_and_log(recvbuf, sz);
|
||||||
}
|
}
|
||||||
} /* for (;;) */
|
} /* for (;;) */
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user