mirror of
http://git.haproxy.org/git/haproxy.git/
synced 2025-04-19 21:45:33 +00:00
MEDIUM: log: Use linked lists for loggers
This patch settles the 2 loggers limitation. Loggers are now stored in linked lists. Using "global log", the global loggers list content is added at the end of the current proxy list. Each "log" entries are added at the end of the proxy list. "no log" flush a logger list.
This commit is contained in:
parent
0cec331a0e
commit
0f99e34978
@ -998,7 +998,7 @@ http-check send-state X - X X
|
|||||||
http-request - X X X
|
http-request - X X X
|
||||||
id - X X X
|
id - X X X
|
||||||
ignore-persist - X X X
|
ignore-persist - X X X
|
||||||
log X X X X
|
log (*) X X X X
|
||||||
maxconn X X X -
|
maxconn X X X -
|
||||||
mode X X X X
|
mode X X X X
|
||||||
monitor fail - X X -
|
monitor fail - X X -
|
||||||
@ -2560,9 +2560,16 @@ ignore-persist { if | unless } <condition>
|
|||||||
|
|
||||||
log global
|
log global
|
||||||
log <address> <facility> [<level> [<minlevel>]]
|
log <address> <facility> [<level> [<minlevel>]]
|
||||||
|
no log
|
||||||
Enable per-instance logging of events and traffic.
|
Enable per-instance logging of events and traffic.
|
||||||
May be used in sections : defaults | frontend | listen | backend
|
May be used in sections : defaults | frontend | listen | backend
|
||||||
yes | yes | yes | yes
|
yes | yes | yes | yes
|
||||||
|
|
||||||
|
Prefix :
|
||||||
|
no should be used when the logger list must be flushed. For example,
|
||||||
|
if you don't want to inherit from the default logger list. This
|
||||||
|
prefix does not allow arguments.
|
||||||
|
|
||||||
Arguments :
|
Arguments :
|
||||||
global should be used when the instance's logging parameters are the
|
global should be used when the instance's logging parameters are the
|
||||||
same as the global ones. This is the most common usage. "global"
|
same as the global ones. This is the most common usage. "global"
|
||||||
@ -2604,14 +2611,9 @@ log <address> <facility> [<level> [<minlevel>]]
|
|||||||
|
|
||||||
emerg alert crit err warning notice info debug
|
emerg alert crit err warning notice info debug
|
||||||
|
|
||||||
Note that up to two "log" entries may be specified per instance. However, if
|
It is important to keep in mind that it is the frontend which decides what to
|
||||||
"log global" is used and if the "global" section already contains 2 log
|
log from a connection, and that in case of content switching, the log entries
|
||||||
entries, then additional log entries will be ignored.
|
from the backend will be ignored. Connections are logged at level "info".
|
||||||
|
|
||||||
Also, it is important to keep in mind that it is the frontend which decides
|
|
||||||
what to log from a connection, and that in case of content switching, the log
|
|
||||||
entries from the backend will be ignored. Connections are logged at level
|
|
||||||
"info".
|
|
||||||
|
|
||||||
However, backend log declaration define how and where servers status changes
|
However, backend log declaration define how and where servers status changes
|
||||||
will be logged. Level "notice" will be used to indicate a server going up,
|
will be logged. Level "notice" will be used to indicate a server going up,
|
||||||
|
@ -79,10 +79,7 @@ struct global {
|
|||||||
char *pidfile;
|
char *pidfile;
|
||||||
char *node, *desc; /* node name & description */
|
char *node, *desc; /* node name & description */
|
||||||
char *log_tag; /* name for syslog */
|
char *log_tag; /* name for syslog */
|
||||||
int logfac1, logfac2;
|
struct list logsrvs;
|
||||||
int loglev1, loglev2;
|
|
||||||
int minlvl1, minlvl2;
|
|
||||||
struct logsrv logsrv1, logsrv2;
|
|
||||||
char *log_send_hostname; /* set hostname in syslog header */
|
char *log_send_hostname; /* set hostname in syslog header */
|
||||||
struct {
|
struct {
|
||||||
int maxpollevents; /* max number of poll events at once */
|
int maxpollevents; /* max number of poll events at once */
|
||||||
|
@ -48,7 +48,11 @@
|
|||||||
#define LW_RSPHDR 2048 /* response header(s) */
|
#define LW_RSPHDR 2048 /* response header(s) */
|
||||||
|
|
||||||
struct logsrv {
|
struct logsrv {
|
||||||
|
struct list list;
|
||||||
struct sockaddr_storage addr;
|
struct sockaddr_storage addr;
|
||||||
|
int facility;
|
||||||
|
int level;
|
||||||
|
int minlvl;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* _TYPES_LOG_H */
|
#endif /* _TYPES_LOG_H */
|
||||||
|
@ -283,10 +283,7 @@ struct proxy {
|
|||||||
char *iface_name; /* bind interface name or NULL */
|
char *iface_name; /* bind interface name or NULL */
|
||||||
int (*accept)(struct session *s); /* application layer's accept() */
|
int (*accept)(struct session *s); /* application layer's accept() */
|
||||||
struct proxy *next;
|
struct proxy *next;
|
||||||
struct logsrv logsrv1, logsrv2; /* 2 syslog servers */
|
struct list logsrvs;
|
||||||
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 to_log; /* things to be logged (LW_*) */
|
||||||
int stop_time; /* date to stop listening, when stopping != 0 (int ticks) */
|
int stop_time; /* date to stop listening, when stopping != 0 (int ticks) */
|
||||||
struct hdr_exp *req_exp; /* regular expressions for request headers */
|
struct hdr_exp *req_exp; /* regular expressions for request headers */
|
||||||
|
190
src/cfgparse.c
190
src/cfgparse.c
@ -891,9 +891,24 @@ int cfg_parse_global(const char *file, int linenum, char **args, int kwm)
|
|||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (!strcmp(args[0], "log") && kwm == KWM_NO) { /* no log */
|
||||||
|
/* delete previous herited or defined syslog servers */
|
||||||
|
struct logsrv *back;
|
||||||
|
struct logsrv *tmp;
|
||||||
|
|
||||||
|
if (*(args[1]) != 0) {
|
||||||
|
Alert("parsing [%s:%d]:%s : 'no log' does not expect arguments.\n", file, linenum, args[1]);
|
||||||
|
err_code |= ERR_ALERT | ERR_FATAL;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
list_for_each_entry_safe(tmp, back, &global.logsrvs, list) {
|
||||||
|
LIST_DEL(&tmp->list);
|
||||||
|
free(tmp);
|
||||||
|
}
|
||||||
|
}
|
||||||
else if (!strcmp(args[0], "log")) { /* syslog server address */
|
else if (!strcmp(args[0], "log")) { /* syslog server address */
|
||||||
struct logsrv logsrv;
|
struct logsrv *logsrv;
|
||||||
int facility, level, minlvl;
|
|
||||||
|
|
||||||
if (*(args[1]) == 0 || *(args[2]) == 0) {
|
if (*(args[1]) == 0 || *(args[2]) == 0) {
|
||||||
Alert("parsing [%s:%d] : '%s' expects <address> and <facility> as arguments.\n", file, linenum, args[0]);
|
Alert("parsing [%s:%d] : '%s' expects <address> and <facility> as arguments.\n", file, linenum, args[0]);
|
||||||
@ -901,30 +916,32 @@ int cfg_parse_global(const char *file, int linenum, char **args, int kwm)
|
|||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
facility = get_log_facility(args[2]);
|
logsrv = calloc(1, sizeof(struct logsrv));
|
||||||
if (facility < 0) {
|
|
||||||
|
logsrv->facility = get_log_facility(args[2]);
|
||||||
|
if (logsrv->facility < 0) {
|
||||||
Alert("parsing [%s:%d] : unknown log facility '%s'\n", file, linenum, args[2]);
|
Alert("parsing [%s:%d] : unknown log facility '%s'\n", file, linenum, args[2]);
|
||||||
err_code |= ERR_ALERT | ERR_FATAL;
|
err_code |= ERR_ALERT | ERR_FATAL;
|
||||||
facility = 0;
|
logsrv->facility = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
level = 7; /* max syslog level = debug */
|
logsrv->level = 7; /* max syslog level = debug */
|
||||||
if (*(args[3])) {
|
if (*(args[3])) {
|
||||||
level = get_log_level(args[3]);
|
logsrv->level = get_log_level(args[3]);
|
||||||
if (level < 0) {
|
if (logsrv->level < 0) {
|
||||||
Alert("parsing [%s:%d] : unknown optional log level '%s'\n", file, linenum, args[3]);
|
Alert("parsing [%s:%d] : unknown optional log level '%s'\n", file, linenum, args[3]);
|
||||||
err_code |= ERR_ALERT | ERR_FATAL;
|
err_code |= ERR_ALERT | ERR_FATAL;
|
||||||
level = 0;
|
logsrv->level = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
minlvl = 0; /* limit syslog level to this level (emerg) */
|
logsrv->minlvl = 0; /* limit syslog level to this level (emerg) */
|
||||||
if (*(args[4])) {
|
if (*(args[4])) {
|
||||||
minlvl = get_log_level(args[4]);
|
logsrv->minlvl = get_log_level(args[4]);
|
||||||
if (minlvl < 0) {
|
if (logsrv->minlvl < 0) {
|
||||||
Alert("parsing [%s:%d] : unknown optional minimum log level '%s'\n", file, linenum, args[4]);
|
Alert("parsing [%s:%d] : unknown optional minimum log level '%s'\n", file, linenum, args[4]);
|
||||||
err_code |= ERR_ALERT | ERR_FATAL;
|
err_code |= ERR_ALERT | ERR_FATAL;
|
||||||
minlvl = 0;
|
logsrv->minlvl = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -934,37 +951,24 @@ int cfg_parse_global(const char *file, int linenum, char **args, int kwm)
|
|||||||
Alert("parsing [%s:%d] : Socket path '%s' too long (max %d)\n", file, linenum,
|
Alert("parsing [%s:%d] : Socket path '%s' too long (max %d)\n", file, linenum,
|
||||||
args[1], (int)sizeof(((struct sockaddr_un *)&sk)->sun_path) - 1);
|
args[1], (int)sizeof(((struct sockaddr_un *)&sk)->sun_path) - 1);
|
||||||
err_code |= ERR_ALERT | ERR_FATAL;
|
err_code |= ERR_ALERT | ERR_FATAL;
|
||||||
|
free(logsrv);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
logsrv.addr = *sk;
|
logsrv->addr = *sk;
|
||||||
} else {
|
} else {
|
||||||
struct sockaddr_storage *sk = str2sa(args[1]);
|
struct sockaddr_storage *sk = str2sa(args[1]);
|
||||||
if (!sk) {
|
if (!sk) {
|
||||||
Alert("parsing [%s:%d] : Unknown host in '%s'\n", file, linenum, args[1]);
|
Alert("parsing [%s:%d] : Unknown host in '%s'\n", file, linenum, args[1]);
|
||||||
err_code |= ERR_ALERT | ERR_FATAL;
|
err_code |= ERR_ALERT | ERR_FATAL;
|
||||||
|
free(logsrv);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
logsrv.addr = *sk;
|
logsrv->addr = *sk;
|
||||||
if (!get_host_port(&logsrv.addr))
|
if (!get_host_port(&logsrv->addr))
|
||||||
set_host_port(&logsrv.addr, SYSLOG_PORT);
|
set_host_port(&logsrv->addr, SYSLOG_PORT);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (global.logfac1 == -1) {
|
LIST_ADDQ(&global.logsrvs, &logsrv->list);
|
||||||
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);
|
|
||||||
err_code |= ERR_ALERT | ERR_FATAL;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else if (!strcmp(args[0], "log-send-hostname")) { /* set the hostname in syslog header */
|
else if (!strcmp(args[0], "log-send-hostname")) { /* set the hostname in syslog header */
|
||||||
char *name;
|
char *name;
|
||||||
@ -1319,6 +1323,7 @@ int cfg_parse_listen(const char *file, int linenum, char **args, int kwm)
|
|||||||
unsigned val;
|
unsigned val;
|
||||||
int err_code = 0;
|
int err_code = 0;
|
||||||
struct acl_cond *cond = NULL;
|
struct acl_cond *cond = NULL;
|
||||||
|
struct logsrv *tmp;
|
||||||
|
|
||||||
if (!strcmp(args[0], "listen"))
|
if (!strcmp(args[0], "listen"))
|
||||||
rc = PR_CAP_LISTEN;
|
rc = PR_CAP_LISTEN;
|
||||||
@ -1521,14 +1526,15 @@ int cfg_parse_listen(const char *file, int linenum, char **args, int kwm)
|
|||||||
}
|
}
|
||||||
|
|
||||||
curproxy->mode = defproxy.mode;
|
curproxy->mode = defproxy.mode;
|
||||||
curproxy->logfac1 = defproxy.logfac1;
|
|
||||||
curproxy->logsrv1 = defproxy.logsrv1;
|
/* copy default logsrvs to curproxy */
|
||||||
curproxy->loglev1 = defproxy.loglev1;
|
list_for_each_entry(tmp, &defproxy.logsrvs, list) {
|
||||||
curproxy->minlvl1 = defproxy.minlvl1;
|
struct logsrv *node = malloc(sizeof(struct logsrv));
|
||||||
curproxy->logfac2 = defproxy.logfac2;
|
memcpy(node, tmp, sizeof(struct logsrv));
|
||||||
curproxy->logsrv2 = defproxy.logsrv2;
|
LIST_INIT(&node->list);
|
||||||
curproxy->loglev2 = defproxy.loglev2;
|
LIST_ADDQ(&curproxy->logsrvs, &node->list);
|
||||||
curproxy->minlvl2 = defproxy.minlvl2;
|
}
|
||||||
|
|
||||||
curproxy->grace = defproxy.grace;
|
curproxy->grace = defproxy.grace;
|
||||||
curproxy->conf.used_listener_id = EB_ROOT;
|
curproxy->conf.used_listener_id = EB_ROOT;
|
||||||
curproxy->conf.used_server_id = EB_ROOT;
|
curproxy->conf.used_server_id = EB_ROOT;
|
||||||
@ -4503,44 +4509,64 @@ stats_error_parsing:
|
|||||||
newsrv->prev_state = newsrv->state;
|
newsrv->prev_state = newsrv->state;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (!strcmp(args[0], "log") && kwm == KWM_NO) {
|
||||||
|
/* delete previous herited or defined syslog servers */
|
||||||
|
struct logsrv *back;
|
||||||
|
|
||||||
|
if (*(args[1]) != 0) {
|
||||||
|
Alert("parsing [%s:%d]:%s : 'no log' does not expect arguments.\n", file, linenum, args[1]);
|
||||||
|
err_code |= ERR_ALERT | ERR_FATAL;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
list_for_each_entry_safe(tmp, back, &curproxy->logsrvs, list) {
|
||||||
|
LIST_DEL(&tmp->list);
|
||||||
|
free(tmp);
|
||||||
|
}
|
||||||
|
}
|
||||||
else if (!strcmp(args[0], "log")) { /* syslog server address */
|
else if (!strcmp(args[0], "log")) { /* syslog server address */
|
||||||
struct logsrv logsrv;
|
struct logsrv *logsrv;
|
||||||
int facility;
|
|
||||||
|
|
||||||
if (*(args[1]) && *(args[2]) == 0 && !strcmp(args[1], "global")) {
|
if (*(args[1]) && *(args[2]) == 0 && !strcmp(args[1], "global")) {
|
||||||
curproxy->logfac1 = global.logfac1;
|
/* copy global.logrsvs linked list to the end of curproxy->logsrvs */
|
||||||
curproxy->logsrv1 = global.logsrv1;
|
list_for_each_entry(tmp, &global.logsrvs, list) {
|
||||||
curproxy->loglev1 = global.loglev1;
|
struct logsrv *node = malloc(sizeof(struct logsrv));
|
||||||
curproxy->minlvl1 = global.minlvl1;
|
memcpy(node, tmp, sizeof(struct logsrv));
|
||||||
curproxy->logfac2 = global.logfac2;
|
LIST_INIT(&node->list);
|
||||||
curproxy->logsrv2 = global.logsrv2;
|
LIST_ADDQ(&curproxy->logsrvs, &node->list);
|
||||||
curproxy->loglev2 = global.loglev2;
|
}
|
||||||
curproxy->minlvl2 = global.minlvl2;
|
|
||||||
}
|
}
|
||||||
else if (*(args[1]) && *(args[2])) {
|
else if (*(args[1]) && *(args[2])) {
|
||||||
int level, minlvl;
|
|
||||||
|
|
||||||
facility = get_log_facility(args[2]);
|
logsrv = calloc(1, sizeof(struct logsrv));
|
||||||
if (facility < 0) {
|
|
||||||
|
logsrv->facility = get_log_facility(args[2]);
|
||||||
|
if (logsrv->facility < 0) {
|
||||||
Alert("parsing [%s:%d] : unknown log facility '%s'\n", file, linenum, args[2]);
|
Alert("parsing [%s:%d] : unknown log facility '%s'\n", file, linenum, args[2]);
|
||||||
exit(1);
|
err_code |= ERR_ALERT | ERR_FATAL;
|
||||||
|
goto out;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
level = 7; /* max syslog level = debug */
|
logsrv->level = 7; /* max syslog level = debug */
|
||||||
if (*(args[3])) {
|
if (*(args[3])) {
|
||||||
level = get_log_level(args[3]);
|
logsrv->level = get_log_level(args[3]);
|
||||||
if (level < 0) {
|
if (logsrv->level < 0) {
|
||||||
Alert("parsing [%s:%d] : unknown optional log level '%s'\n", file, linenum, args[3]);
|
Alert("parsing [%s:%d] : unknown optional log level '%s'\n", file, linenum, args[3]);
|
||||||
exit(1);
|
err_code |= ERR_ALERT | ERR_FATAL;
|
||||||
|
goto out;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
minlvl = 0; /* limit syslog level to this level (emerg) */
|
logsrv->minlvl = 0; /* limit syslog level to this level (emerg) */
|
||||||
if (*(args[4])) {
|
if (*(args[4])) {
|
||||||
minlvl = get_log_level(args[4]);
|
logsrv->minlvl = get_log_level(args[4]);
|
||||||
if (level < 0) {
|
if (logsrv->level < 0) {
|
||||||
Alert("parsing [%s:%d] : unknown optional minimum log level '%s'\n", file, linenum, args[4]);
|
Alert("parsing [%s:%d] : unknown optional minimum log level '%s'\n", file, linenum, args[4]);
|
||||||
exit(1);
|
err_code |= ERR_ALERT | ERR_FATAL;
|
||||||
|
goto out;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4552,7 +4578,7 @@ stats_error_parsing:
|
|||||||
err_code |= ERR_ALERT | ERR_FATAL;
|
err_code |= ERR_ALERT | ERR_FATAL;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
logsrv.addr = *sk;
|
logsrv->addr = *sk;
|
||||||
} else {
|
} else {
|
||||||
struct sockaddr_storage *sk = str2sa(args[1]);
|
struct sockaddr_storage *sk = str2sa(args[1]);
|
||||||
if (!sk) {
|
if (!sk) {
|
||||||
@ -4560,28 +4586,12 @@ stats_error_parsing:
|
|||||||
err_code |= ERR_ALERT | ERR_FATAL;
|
err_code |= ERR_ALERT | ERR_FATAL;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
logsrv.addr = *sk;
|
logsrv->addr = *sk;
|
||||||
if (!get_host_port(&logsrv.addr))
|
if (!get_host_port(&logsrv->addr))
|
||||||
set_host_port(&logsrv.addr, SYSLOG_PORT);
|
set_host_port(&logsrv->addr, SYSLOG_PORT);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (curproxy->logfac1 == -1) {
|
LIST_ADDQ(&curproxy->logsrvs, &logsrv->list);
|
||||||
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);
|
|
||||||
err_code |= ERR_ALERT | ERR_FATAL;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
Alert("parsing [%s:%d] : 'log' expects either <address[:port]> and <facility> or 'global' as arguments.\n",
|
Alert("parsing [%s:%d] : 'log' expects either <address[:port]> and <facility> or 'global' as arguments.\n",
|
||||||
@ -5427,9 +5437,14 @@ int readcfgfile(const char *file)
|
|||||||
|
|
||||||
/* check for keyword modifiers "no" and "default" */
|
/* check for keyword modifiers "no" and "default" */
|
||||||
if (!strcmp(args[0], "no")) {
|
if (!strcmp(args[0], "no")) {
|
||||||
|
char *tmp;
|
||||||
|
|
||||||
kwm = KWM_NO;
|
kwm = KWM_NO;
|
||||||
|
tmp = args[0];
|
||||||
for (arg=0; *args[arg+1]; arg++)
|
for (arg=0; *args[arg+1]; arg++)
|
||||||
args[arg] = args[arg+1]; // shift args after inversion
|
args[arg] = args[arg+1]; // shift args after inversion
|
||||||
|
*tmp = '\0'; // fix the next arg to \0
|
||||||
|
args[arg] = tmp;
|
||||||
}
|
}
|
||||||
else if (!strcmp(args[0], "default")) {
|
else if (!strcmp(args[0], "default")) {
|
||||||
kwm = KWM_DEF;
|
kwm = KWM_DEF;
|
||||||
@ -5437,8 +5452,9 @@ int readcfgfile(const char *file)
|
|||||||
args[arg] = args[arg+1]; // shift args after inversion
|
args[arg] = args[arg+1]; // shift args after inversion
|
||||||
}
|
}
|
||||||
|
|
||||||
if (kwm != KWM_STD && strcmp(args[0], "option") != 0) {
|
if (kwm != KWM_STD && strcmp(args[0], "option") != 0 && \
|
||||||
Alert("parsing [%s:%d]: negation/default currently supported only for options.\n", file, linenum);
|
strcmp(args[0], "log") != 0) {
|
||||||
|
Alert("parsing [%s:%d]: negation/default currently supported only for options and log.\n", file, linenum);
|
||||||
err_code |= ERR_ALERT | ERR_FATAL;
|
err_code |= ERR_ALERT | ERR_FATAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -6072,7 +6088,7 @@ out_uri_auth_compat:
|
|||||||
curproxy->to_log &= ~LW_BYTES;
|
curproxy->to_log &= ~LW_BYTES;
|
||||||
|
|
||||||
if ((curproxy->mode == PR_MODE_TCP || curproxy->mode == PR_MODE_HTTP) &&
|
if ((curproxy->mode == PR_MODE_TCP || curproxy->mode == PR_MODE_HTTP) &&
|
||||||
(curproxy->cap & PR_CAP_FE) && curproxy->to_log && curproxy->logfac1 < 0) {
|
(curproxy->cap & PR_CAP_FE) && curproxy->to_log && LIST_ISEMPTY(&curproxy->logsrvs)) {
|
||||||
Warning("config : log format ignored for %s '%s' since it has no log address.\n",
|
Warning("config : log format ignored for %s '%s' since it has no log address.\n",
|
||||||
proxy_type_str(curproxy), curproxy->id);
|
proxy_type_str(curproxy), curproxy->id);
|
||||||
err_code |= ERR_WARN;
|
err_code |= ERR_WARN;
|
||||||
|
@ -144,7 +144,7 @@ int frontend_accept(struct session *s)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ((s->fe->mode == PR_MODE_TCP || s->fe->mode == PR_MODE_HTTP)
|
if ((s->fe->mode == PR_MODE_TCP || s->fe->mode == PR_MODE_HTTP)
|
||||||
&& (s->fe->logfac1 >= 0 || s->fe->logfac2 >= 0)) {
|
&& (!LIST_ISEMPTY(&s->fe->logsrvs))) {
|
||||||
if (likely(s->fe->to_log)) {
|
if (likely(s->fe->to_log)) {
|
||||||
/* we have the client ip */
|
/* we have the client ip */
|
||||||
if (s->logs.logwait & LW_CLIP)
|
if (s->logs.logwait & LW_CLIP)
|
||||||
|
@ -103,10 +103,7 @@ int relative_pid = 1; /* process id starting at 1 */
|
|||||||
|
|
||||||
/* global options */
|
/* global options */
|
||||||
struct global global = {
|
struct global global = {
|
||||||
logfac1 : -1,
|
.logsrvs = LIST_HEAD_INIT(global.logsrvs),
|
||||||
logfac2 : -1,
|
|
||||||
loglev1 : 7, /* max syslog level : debug */
|
|
||||||
loglev2 : 7,
|
|
||||||
.stats_sock = {
|
.stats_sock = {
|
||||||
.perm = {
|
.perm = {
|
||||||
.ux = {
|
.ux = {
|
||||||
@ -788,6 +785,7 @@ void deinit(void)
|
|||||||
struct wordlist *wl, *wlb;
|
struct wordlist *wl, *wlb;
|
||||||
struct cond_wordlist *cwl, *cwlb;
|
struct cond_wordlist *cwl, *cwlb;
|
||||||
struct uri_auth *uap, *ua = NULL;
|
struct uri_auth *uap, *ua = NULL;
|
||||||
|
struct logsrv *log, *logb;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
deinit_signals();
|
deinit_signals();
|
||||||
@ -893,6 +891,11 @@ void deinit(void)
|
|||||||
free(rdr);
|
free(rdr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
list_for_each_entry_safe(log, logb, &p->logsrvs, list) {
|
||||||
|
LIST_DEL(&log->list);
|
||||||
|
free(log);
|
||||||
|
}
|
||||||
|
|
||||||
deinit_tcp_rules(&p->tcp_req.inspect_rules);
|
deinit_tcp_rules(&p->tcp_req.inspect_rules);
|
||||||
deinit_tcp_rules(&p->tcp_req.l4_rules);
|
deinit_tcp_rules(&p->tcp_req.l4_rules);
|
||||||
|
|
||||||
@ -995,6 +998,10 @@ void deinit(void)
|
|||||||
free(oldpids); oldpids = NULL;
|
free(oldpids); oldpids = NULL;
|
||||||
free(global_listener_queue_task); global_listener_queue_task = NULL;
|
free(global_listener_queue_task); global_listener_queue_task = NULL;
|
||||||
|
|
||||||
|
list_for_each_entry_safe(log, logb, &global.logsrvs, list) {
|
||||||
|
LIST_DEL(&log->list);
|
||||||
|
free(log);
|
||||||
|
}
|
||||||
list_for_each_entry_safe(wl, wlb, &cfg_cfgfiles, list) {
|
list_for_each_entry_safe(wl, wlb, &cfg_cfgfiles, list) {
|
||||||
LIST_DEL(&wl->list);
|
LIST_DEL(&wl->list);
|
||||||
free(wl);
|
free(wl);
|
||||||
|
57
src/log.c
57
src/log.c
@ -157,10 +157,9 @@ void send_log(struct proxy *p, int level, const char *message, ...)
|
|||||||
static char *dataptr = NULL;
|
static char *dataptr = NULL;
|
||||||
int fac_level;
|
int fac_level;
|
||||||
int hdr_len, data_len;
|
int hdr_len, data_len;
|
||||||
struct logsrv *logsrvs[2];
|
struct list *logsrvs = NULL;
|
||||||
int facilities[2], loglevel[2], minlvl[2];
|
struct logsrv *tmp = NULL;
|
||||||
int nblogger;
|
int nblogger;
|
||||||
int nbloggers = 0;
|
|
||||||
char *log_ptr;
|
char *log_ptr;
|
||||||
|
|
||||||
if (level < 0 || message == NULL)
|
if (level < 0 || message == NULL)
|
||||||
@ -201,42 +200,25 @@ void send_log(struct proxy *p, int level, const char *message, ...)
|
|||||||
dataptr[data_len - 1] = '\n'; /* force a break on ultra-long lines */
|
dataptr[data_len - 1] = '\n'; /* force a break on ultra-long lines */
|
||||||
|
|
||||||
if (p == NULL) {
|
if (p == NULL) {
|
||||||
if (global.logfac1 >= 0) {
|
if (!LIST_ISEMPTY(&global.logsrvs)) {
|
||||||
logsrvs[nbloggers] = &global.logsrv1;
|
logsrvs = &global.logsrvs;
|
||||||
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 {
|
} else {
|
||||||
if (p->logfac1 >= 0) {
|
if (!LIST_ISEMPTY(&p->logsrvs)) {
|
||||||
logsrvs[nbloggers] = &p->logsrv1;
|
logsrvs = &p->logsrvs;
|
||||||
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++;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!logsrvs)
|
||||||
|
return;
|
||||||
|
|
||||||
/* Lazily set up syslog sockets for protocol families of configured
|
/* Lazily set up syslog sockets for protocol families of configured
|
||||||
* syslog servers. */
|
* syslog servers. */
|
||||||
for (nblogger = 0; nblogger < nbloggers; nblogger++) {
|
nblogger = 0;
|
||||||
const struct logsrv *logsrv = logsrvs[nblogger];
|
list_for_each_entry(tmp, logsrvs, list) {
|
||||||
|
const struct logsrv *logsrv = tmp;
|
||||||
int proto, *plogfd;
|
int proto, *plogfd;
|
||||||
|
|
||||||
if (logsrv->addr.ss_family == AF_UNIX) {
|
if (logsrv->addr.ss_family == AF_UNIX) {
|
||||||
proto = 0;
|
proto = 0;
|
||||||
plogfd = &logfdunix;
|
plogfd = &logfdunix;
|
||||||
@ -258,17 +240,19 @@ void send_log(struct proxy *p, int level, const char *message, ...)
|
|||||||
setsockopt(*plogfd, SOL_SOCKET, SO_RCVBUF, &zero, sizeof(zero));
|
setsockopt(*plogfd, SOL_SOCKET, SO_RCVBUF, &zero, sizeof(zero));
|
||||||
/* does nothing under Linux, maybe needed for others */
|
/* does nothing under Linux, maybe needed for others */
|
||||||
shutdown(*plogfd, SHUT_RD);
|
shutdown(*plogfd, SHUT_RD);
|
||||||
|
nblogger++;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Send log messages to syslog server. */
|
/* Send log messages to syslog server. */
|
||||||
for (nblogger = 0; nblogger < nbloggers; nblogger++) {
|
nblogger = 0;
|
||||||
const struct logsrv *logsrv = logsrvs[nblogger];
|
list_for_each_entry(tmp, logsrvs, list) {
|
||||||
|
const struct logsrv *logsrv = tmp;
|
||||||
int *plogfd = logsrv->addr.ss_family == AF_UNIX ?
|
int *plogfd = logsrv->addr.ss_family == AF_UNIX ?
|
||||||
&logfdunix : &logfdinet;
|
&logfdunix : &logfdinet;
|
||||||
int sent;
|
int sent;
|
||||||
|
|
||||||
/* we can filter the level of the messages that are sent to each logger */
|
/* we can filter the level of the messages that are sent to each logger */
|
||||||
if (level > loglevel[nblogger])
|
if (level > logsrv->level)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
/* For each target, we may have a different facility.
|
/* For each target, we may have a different facility.
|
||||||
@ -278,7 +262,7 @@ void send_log(struct proxy *p, int level, const char *message, ...)
|
|||||||
* time, we only change the facility in the pre-computed header,
|
* time, we only change the facility in the pre-computed header,
|
||||||
* and we change the pointer to the header accordingly.
|
* and we change the pointer to the header accordingly.
|
||||||
*/
|
*/
|
||||||
fac_level = (facilities[nblogger] << 3) + MAX(level, minlvl[nblogger]);
|
fac_level = (logsrv->facility << 3) + MAX(level, logsrv->minlvl);
|
||||||
log_ptr = logmsg + 3; /* last digit of the log level */
|
log_ptr = logmsg + 3; /* last digit of the log level */
|
||||||
do {
|
do {
|
||||||
*log_ptr = '0' + fac_level % 10;
|
*log_ptr = '0' + fac_level % 10;
|
||||||
@ -295,6 +279,7 @@ void send_log(struct proxy *p, int level, const char *message, ...)
|
|||||||
Alert("sendto logger #%d failed: %s (errno=%d)\n",
|
Alert("sendto logger #%d failed: %s (errno=%d)\n",
|
||||||
nblogger, strerror(errno), errno);
|
nblogger, strerror(errno), errno);
|
||||||
}
|
}
|
||||||
|
nblogger++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -320,7 +305,7 @@ void tcp_sess_log(struct session *s)
|
|||||||
addr_to_str(&s->si[0].addr.from, pn, sizeof(pn));
|
addr_to_str(&s->si[0].addr.from, pn, sizeof(pn));
|
||||||
get_localtime(s->logs.tv_accept.tv_sec, &tm);
|
get_localtime(s->logs.tv_accept.tv_sec, &tm);
|
||||||
|
|
||||||
if (fe->logfac1 < 0 && fe->logfac2 < 0)
|
if(LIST_ISEMPTY(&fe->logsrvs))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
prx_log = fe;
|
prx_log = fe;
|
||||||
|
@ -1097,7 +1097,7 @@ void http_sess_log(struct session *s)
|
|||||||
if (!err && (fe->options2 & PR_O2_NOLOGNORM))
|
if (!err && (fe->options2 & PR_O2_NOLOGNORM))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (fe->logfac1 < 0 && fe->logfac2 < 0)
|
if (LIST_ISEMPTY(&fe->logsrvs))
|
||||||
return;
|
return;
|
||||||
prx_log = fe;
|
prx_log = fe;
|
||||||
|
|
||||||
|
@ -436,11 +436,11 @@ void init_new_proxy(struct proxy *p)
|
|||||||
LIST_INIT(&p->req_add);
|
LIST_INIT(&p->req_add);
|
||||||
LIST_INIT(&p->rsp_add);
|
LIST_INIT(&p->rsp_add);
|
||||||
LIST_INIT(&p->listener_queue);
|
LIST_INIT(&p->listener_queue);
|
||||||
|
LIST_INIT(&p->logsrvs);
|
||||||
|
|
||||||
/* Timeouts are defined as -1 */
|
/* Timeouts are defined as -1 */
|
||||||
proxy_reset_timeouts(p);
|
proxy_reset_timeouts(p);
|
||||||
p->tcp_rep.inspect_delay = TICK_ETERNITY;
|
p->tcp_rep.inspect_delay = TICK_ETERNITY;
|
||||||
p->logfac1 = p->logfac2 = -1; /* log disabled */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
Loading…
Reference in New Issue
Block a user