diff --git a/doc/configuration.txt b/doc/configuration.txt index 454bbd395..43627b565 100644 --- a/doc/configuration.txt +++ b/doc/configuration.txt @@ -415,7 +415,7 @@ group Similar to "gid" but uses the GID of group name from /etc/group. See also "gid" and "user". -log
[max level] +log
[max level [min level]] Adds a global syslog server. Up to two global servers can be defined. They will receive logs for startups and exits, as well as all logs from proxies configured with "log global". @@ -438,8 +438,12 @@ log
[max level] local0 local1 local2 local3 local4 local5 local6 local7 An optional level can be specified to filter outgoing messages. By default, - all messages are sent. If a level is specified, only messages with a severity - at least as important as this level will be sent. 8 levels are known : + all messages are sent. If a maximum level is specified, only messages with a + severity at least as important as this level will be sent. An optional minimum + level can be specified. If it is set, logs emitted with a more severe level + than this one will be capped to this level. This is used to avoid sending + "emerg" messages on all terminals on some default syslog configurations. + Eight levels are known : emerg alert crit err warning notice info debug @@ -1640,7 +1644,7 @@ id log global -log
[] +log
[ []] Enable per-instance logging of events and traffic. May be used in sections : defaults | frontend | listen | backend yes | yes | yes | yes @@ -1673,7 +1677,11 @@ log
[] is optional and can be specified to filter outgoing messages. By default, all messages are sent. If a level is specified, only messages with a severity at least as important as this level - will be sent. 8 levels are known : + will be sent. An optional minimum level can be specified. If it + is set, logs emitted with a more severe level than this one will + be capped to this level. This is used to avoid sending "emerg" + messages on all terminals on some default syslog configurations. + Eight levels are known : emerg alert crit err warning notice info debug @@ -1696,7 +1704,8 @@ log
[] Example : log global - log 127.0.0.1:514 local0 notice + log 127.0.0.1:514 local0 notice # only send important events + log 127.0.0.1:514 local0 notice notice # same but limit output level maxconn diff --git a/include/types/global.h b/include/types/global.h index d0c22bcb4..1ba0b1180 100644 --- a/include/types/global.h +++ b/include/types/global.h @@ -72,6 +72,7 @@ struct global { char *pidfile; int logfac1, logfac2; int loglev1, loglev2; + int minlvl1, minlvl2; struct logsrv logsrv1, logsrv2; struct { int maxpollevents; /* max number of poll events at once */ diff --git a/include/types/proxy.h b/include/types/proxy.h index 3cb60c0f4..7ef5fc89a 100644 --- a/include/types/proxy.h +++ b/include/types/proxy.h @@ -266,6 +266,7 @@ struct proxy { struct logsrv logsrv1, logsrv2; /* 2 syslog servers */ signed char logfac1, logfac2; /* log facility for both servers. -1 = disabled */ int loglev1, loglev2; /* log level for each server, 7 by default */ + int minlvl1, minlvl2; /* minimum log level for each server, 0 by default */ int to_log; /* things to be logged (LW_*) */ int stop_time; /* date to stop listening, when stopping != 0 (int ticks) */ int nb_reqadd, nb_rspadd; diff --git a/src/cfgparse.c b/src/cfgparse.c index 3a71df250..e3c8b6295 100644 --- a/src/cfgparse.c +++ b/src/cfgparse.c @@ -553,7 +553,7 @@ int cfg_parse_global(const char *file, int linenum, char **args, int inv) } else if (!strcmp(args[0], "log")) { /* syslog server address */ struct logsrv logsrv; - int facility, level; + int facility, level, minlvl; if (*(args[1]) == 0 || *(args[2]) == 0) { Alert("parsing [%s:%d] : '%s' expects
and as arguments.\n", file, linenum, args[0]); @@ -575,6 +575,15 @@ int cfg_parse_global(const char *file, int linenum, char **args, int inv) } } + minlvl = 0; /* limit syslog level to this level (emerg) */ + if (*(args[4])) { + minlvl = get_log_level(args[4]); + if (level < 0) { + Alert("parsing [%s:%d] : unknown optional minimum log level '%s'\n", file, linenum, args[4]); + exit(1); + } + } + if (args[1][0] == '/') { logsrv.u.addr.sa_family = AF_UNIX; logsrv.u.un = *str2sun(args[1]); @@ -589,11 +598,13 @@ int cfg_parse_global(const char *file, int linenum, char **args, int inv) global.logsrv1 = logsrv; global.logfac1 = facility; global.loglev1 = level; + global.minlvl1 = minlvl; } else if (global.logfac2 == -1) { global.logsrv2 = logsrv; global.logfac2 = facility; global.loglev2 = level; + global.minlvl2 = minlvl; } else { Alert("parsing [%s:%d] : too many syslog servers\n", file, linenum); @@ -847,9 +858,11 @@ int cfg_parse_listen(const char *file, int linenum, char **args, int inv) curproxy->logfac1 = defproxy.logfac1; curproxy->logsrv1 = defproxy.logsrv1; curproxy->loglev1 = defproxy.loglev1; + curproxy->minlvl1 = defproxy.minlvl1; curproxy->logfac2 = defproxy.logfac2; curproxy->logsrv2 = defproxy.logsrv2; curproxy->loglev2 = defproxy.loglev2; + curproxy->minlvl2 = defproxy.minlvl2; curproxy->grace = defproxy.grace; curproxy->uuid = next_pxid++; /* generate a uuid for this proxy */ curproxy->next_svid = 1; /* server id 0 is reserved */ @@ -2302,12 +2315,14 @@ int cfg_parse_listen(const char *file, int linenum, char **args, int inv) curproxy->logfac1 = global.logfac1; curproxy->logsrv1 = global.logsrv1; curproxy->loglev1 = global.loglev1; + curproxy->minlvl1 = global.minlvl1; curproxy->logfac2 = global.logfac2; curproxy->logsrv2 = global.logsrv2; curproxy->loglev2 = global.loglev2; + curproxy->minlvl2 = global.minlvl2; } else if (*(args[1]) && *(args[2])) { - int level; + int level, minlvl; facility = get_log_facility(args[2]); if (facility < 0) { @@ -2324,6 +2339,15 @@ int cfg_parse_listen(const char *file, int linenum, char **args, int inv) } } + minlvl = 0; /* limit syslog level to this level (emerg) */ + if (*(args[4])) { + minlvl = get_log_level(args[4]); + if (level < 0) { + Alert("parsing [%s:%d] : unknown optional minimum log level '%s'\n", file, linenum, args[4]); + exit(1); + } + } + if (args[1][0] == '/') { logsrv.u.addr.sa_family = AF_UNIX; logsrv.u.un = *str2sun(args[1]); @@ -2340,11 +2364,13 @@ int cfg_parse_listen(const char *file, int linenum, char **args, int inv) curproxy->logsrv1 = logsrv; curproxy->logfac1 = facility; curproxy->loglev1 = level; + curproxy->minlvl1 = minlvl; } else if (curproxy->logfac2 == -1) { curproxy->logsrv2 = logsrv; curproxy->logfac2 = facility; curproxy->loglev2 = level; + curproxy->minlvl2 = minlvl; } else { Alert("parsing [%s:%d] : too many syslog servers\n", file, linenum); diff --git a/src/log.c b/src/log.c index bc9fd0a4b..093accb28 100644 --- a/src/log.c +++ b/src/log.c @@ -176,7 +176,7 @@ void send_log(struct proxy *p, int level, const char *message, ...) int fac_level; int hdr_len, data_len; struct logsrv *logsrvs[2]; - int facilities[2], loglevel[2]; + int facilities[2], loglevel[2], minlvl[2]; int nblogger; int nbloggers = 0; char *log_ptr; @@ -222,12 +222,14 @@ void send_log(struct proxy *p, int level, const char *message, ...) logsrvs[nbloggers] = &global.logsrv1; facilities[nbloggers] = global.logfac1; loglevel[nbloggers] = global.loglev1; + minlvl[nbloggers] = global.minlvl1; nbloggers++; } if (global.logfac2 >= 0) { logsrvs[nbloggers] = &global.logsrv2; facilities[nbloggers] = global.logfac2; loglevel[nbloggers] = global.loglev2; + minlvl[nbloggers] = global.minlvl2; nbloggers++; } } else { @@ -235,12 +237,14 @@ void send_log(struct proxy *p, int level, const char *message, ...) logsrvs[nbloggers] = &p->logsrv1; facilities[nbloggers] = p->logfac1; loglevel[nbloggers] = p->loglev1; + minlvl[nbloggers] = p->minlvl1; nbloggers++; } if (p->logfac2 >= 0) { logsrvs[nbloggers] = &p->logsrv2; facilities[nbloggers] = p->logfac2; loglevel[nbloggers] = p->loglev2; + minlvl[nbloggers] = p->minlvl2; nbloggers++; } } @@ -292,7 +296,7 @@ void send_log(struct proxy *p, int level, const char *message, ...) * time, we only change the facility in the pre-computed header, * and we change the pointer to the header accordingly. */ - fac_level = (facilities[nblogger] << 3) + level; + fac_level = (facilities[nblogger] << 3) + MAX(level, minlvl[nblogger]); log_ptr = logmsg + 3; /* last digit of the log level */ do { *log_ptr = '0' + fac_level % 10;