Consolidate option parsing for syslog.conf rules

This patch changes the syntax for per-rule log rotation and makes it
possible to have enable log rotation and RFC5424 output formatting.

The new syntax looks like this:

    	EXPR		ACTION			;OPT,OPT,...

Example:

	*.notice	-/var/log/messages	;rotate=1M:5,RFC5424

Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
This commit is contained in:
Joachim Nilsson 2019-11-03 12:15:05 +01:00
parent 4066a1e9bf
commit 84aa897628
2 changed files with 103 additions and 51 deletions

View File

@ -38,20 +38,38 @@ Every rule has at least two fields, a
.Em selector .Em selector
field and an field and an
.Em action . .Em action .
They may also have an optional flag or setting that applies only to They may also have an
that rule. E.g, .Em option
.Em logrotate field for a setting that applies only to that rule. Fields are
settings or output format flag. A rule may be divided into several separated by one or more spaces or tabs. A rule may be divided into
lines if the leading line ends with a single backslash ('\\') character. several lines if the leading line ends with a single backslash ('\\')
character.
.Bd -literal -offset indent
RULE := SELECTOR ACTION [;OPTION]
SELECTOR := [SELECTOR;]facility[,facility].[!=]severity
ACTION := /path/to/file
|= |/path/to/named/pipe
|= @remote[.host.tld]
OPTION := [OPTION,]
|= RFC3164
|= RFC5424
|= rotate=SIZE:COUNT
.Ed
.Pp .Pp
The fields are separated by one or more spaces or tabs. The The
selector field specifies a pattern of facilities and priorities .Em selector
belonging to the specified action. The action details where or what to field specifies a pattern of facilities and priorities belonging to the
do with the selected input. The optional logrotate field is only for specified action. The
files and details the max SIZE:COUNT a file can reach before it is .Em action
rotated, and later compressed. The log rotated feature is mostly details where or what to do with the selected input. The
intended for embedded systems that do not want to have cron and a .Em option
separate log rotate daemon. field currently supports log formattaing and log rotation. The default
log format is the traditional RFC3164 (included here for completeness),
RFC5424 has a new format with RFC3339 time stamps, msgid, structured
data, and more. The log rotation, which is only relevant for files,
details the max SIZE:COUNT a file can reach before it is rotated, and
later compressed. This feature is mostly intended for embedded systems
that do not want to have cron or a separate log rotate daemon.
.Pp .Pp
Comments, lines starting with a hash mark ('#'), and empty lines are Comments, lines starting with a hash mark ('#'), and empty lines are
ignored. If an error occurs during parsing the whole line is ignored. ignored. If an error occurs during parsing the whole line is ignored.
@ -272,6 +290,17 @@ that something strange is happening with the system. To specify this
feature use an asterisk ('*'). feature use an asterisk ('*').
.Sh EXAMPLES .Sh EXAMPLES
This section lists some examples, partially from actual site setups. This section lists some examples, partially from actual site setups.
.Ss Catch Everything
This example matches all facilities and priorities and stores everything
in the file
.Pa /var/log/syslog
in RFC5424 format. Every time the file reaches 10 MiB it is rotated and
five files in total are kept, including the non-rotated file.
.Bd -literal -offset indent
# Match all log messages, store in RC5424 format and rotate every 10 MiB
#
*.* /var/log/critical ;rotate=10M:5,RFC5424
.Ed
.Ss Critical .Ss Critical
This stores all messages of priority This stores all messages of priority
.Ql crit .Ql crit
@ -437,10 +466,10 @@ argument takes the same modifiers as the
command line option, command line option,
.Fl R . .Fl R .
.Bd -literal -offset indent .Bd -literal -offset indent
# Log all messages, including kernel, to messages file # Log all messages, including kernel, to messages file rotated
# rotated every 100 kB and keep up to 10 aged out and # every 100 kB and keep up to 10 aged out and compressed files
# compressed files. #
*.*;kern.none -/log/messages 100k:10 *.*;kern.none -/var/log/messages ;rotate=100k:10
.Ed .Ed
.Ss Logging to Remote Syslog Server .Ss Logging to Remote Syslog Server
This rule redirects all messages to a remote host called This rule redirects all messages to a remote host called
@ -449,7 +478,7 @@ with RFC5424 style formatting. This is useful especially in a cluster
of machines where all syslog messages will be stored on only one of machines where all syslog messages will be stored on only one
machine. machine.
.Bd -literal -offset indent .Bd -literal -offset indent
*.* @finlandia;RFC5424 *.* @finlandia ;RFC5424
.Ed .Ed
.Sh FILES .Sh FILES
.Bl -tag -compact -width /etc/syslog.d/*.conf .Bl -tag -compact -width /etc/syslog.d/*.conf

View File

@ -2437,6 +2437,59 @@ void init(void)
logit("syslogd: restarted.\n"); logit("syslogd: restarted.\n");
} }
static void cfrot(char *ptr, struct filed *f)
{
char *c;
int sz = 0, cnt = 0;
c = strchr(ptr, ':');
if (c) {
*c++ = 0;
cnt = atoi(c);
}
sz = strtobytes(ptr);
if (sz > 0 && cnt > 0) {
logit("Set rotate size %d bytes, %d rotations\n", sz, cnt);
f->f_rotatecount = cnt;
f->f_rotatesz = sz;
}
}
static int cfopt(char **ptr, const char *opt)
{
size_t len;
len = strlen(opt);
if (!strncasecmp(*ptr, opt, len)) {
logit("Found %s\n", opt);
*ptr += len;
return 1;
}
return 0;
}
/*
* Option processing
*/
static void cfopts(char *ptr, struct filed *f)
{
char *opt;
opt = strtok(ptr, ";");
while (opt) {
if (cfopt(&opt, "RFC5424"))
f->f_flags |= RFC5424;
else if (cfopt(&opt, "RFC3164"))
f->f_flags &= ~RFC5424;
else if (cfopt(&opt, "rotate="))
cfrot(opt, f);
opt = strtok(NULL, ",");
}
}
/* /*
* Crack a configuration file line * Crack a configuration file line
*/ */
@ -2595,16 +2648,8 @@ static struct filed *cfline(char *line)
logit("leading char in action: %c\n", *p); logit("leading char in action: %c\n", *p);
switch (*p) { switch (*p) {
case '@': case '@':
bp = p; cfopts(p, f);
while ((q = strchr(bp, ';'))) {
*q++ = 0;
if (q) {
if (!strncmp(q, "RFC5424", 7))
f->f_flags |= RFC5424;
/* More flags can be added here */
}
bp = q;
}
(void)strcpy(f->f_un.f_forw.f_hname, ++p); (void)strcpy(f->f_un.f_forw.f_hname, ++p);
logit("forwarding host: %s\n", p); /*ASP*/ logit("forwarding host: %s\n", p); /*ASP*/
memset(&hints, 0, sizeof(hints)); memset(&hints, 0, sizeof(hints));
@ -2629,29 +2674,7 @@ static struct filed *cfline(char *line)
case '|': case '|':
case '/': case '/':
/* Look for optional per-file rotate BYTES:COUNT */ cfopts(p, f);
for (q = p; *q && !isspace(*q); q++)
;
if (isspace(*q)) {
char *c;
int sz = 0, cnt = 0;
*q++ = 0;
while (*q && isspace(*q))
q++;
c = strchr(q, ':');
if (c) {
*c++ = 0;
cnt = atoi(c);
}
sz = strtobytes(q);
if (sz > 0 && cnt > 0) {
f->f_rotatecount = cnt;
f->f_rotatesz = sz;
}
}
(void)strcpy(f->f_un.f_fname, p); (void)strcpy(f->f_un.f_fname, p);
logit("filename: %s\n", p); /*ASP*/ logit("filename: %s\n", p); /*ASP*/