MINOR: log: move 'log' keyword parsing in dedicated function
Now, the function parse_logsrv should be used to parse a "log" line. This function will update the list of loggers passed in argument. It can release all log servers when "no log" line was parsed (by the caller) or it can parse "log global" or "log <address> ... " lines. It takes care of checking the caller context (global or not) to prohibit "log global" usage in the global section.
This commit is contained in:
parent
36bda1cd4a
commit
4b0b79dd56
@ -82,6 +82,10 @@ int add_to_logformat_list(char *start, char *end, int type, struct list *list_fo
|
||||
* You can set arguments using { } : %{many arguments}varname
|
||||
*/
|
||||
int parse_logformat_string(const char *str, struct proxy *curproxy, struct list *list_format, int options, int cap, char **err);
|
||||
|
||||
/* Parse "log" keyword and update the linked list. */
|
||||
int parse_logsrv(char **args, struct list *logsrvs, int do_del, char **err);
|
||||
|
||||
/*
|
||||
* Displays the message on stderr with the date and pid. Overrides the quiet
|
||||
* mode during startup.
|
||||
|
254
src/cfgparse.c
254
src/cfgparse.c
@ -1500,130 +1500,12 @@ int cfg_parse_global(const char *file, int linenum, char **args, int kwm)
|
||||
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) {
|
||||
ha_alert("parsing [%s:%d]:%s : 'no log' does not expect arguments.\n", file, linenum, args[1]);
|
||||
else if (!strcmp(args[0], "log")) { /* "no log" or "log ..." */
|
||||
if (!parse_logsrv(args, &global.logsrvs, (kwm == KWM_NO), &errmsg)) {
|
||||
ha_alert("parsing [%s:%d] : %s : %s\n", file, linenum, args[0], errmsg);
|
||||
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 */
|
||||
struct sockaddr_storage *sk;
|
||||
int port1, port2;
|
||||
struct logsrv *logsrv;
|
||||
int arg = 0;
|
||||
int len = 0;
|
||||
|
||||
if (alertif_too_many_args(8, file, linenum, args, &err_code)) /* does not strictly check optional arguments */
|
||||
goto out;
|
||||
|
||||
if (*(args[1]) == 0 || *(args[2]) == 0) {
|
||||
ha_alert("parsing [%s:%d] : '%s' expects <address> and <facility> as arguments.\n", file, linenum, args[0]);
|
||||
err_code |= ERR_ALERT | ERR_FATAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
logsrv = calloc(1, sizeof(*logsrv));
|
||||
|
||||
/* just after the address, a length may be specified */
|
||||
if (strcmp(args[arg+2], "len") == 0) {
|
||||
len = atoi(args[arg+3]);
|
||||
if (len < 80 || len > 65535) {
|
||||
ha_alert("parsing [%s:%d] : invalid log length '%s', must be between 80 and 65535.\n",
|
||||
file, linenum, args[arg+3]);
|
||||
err_code |= ERR_ALERT | ERR_FATAL;
|
||||
goto out;
|
||||
}
|
||||
logsrv->maxlen = len;
|
||||
|
||||
/* skip these two args */
|
||||
arg += 2;
|
||||
}
|
||||
else
|
||||
logsrv->maxlen = MAX_SYSLOG_LEN;
|
||||
|
||||
if (logsrv->maxlen > global.max_syslog_len)
|
||||
global.max_syslog_len = logsrv->maxlen;
|
||||
|
||||
/* after the length, a format may be specified */
|
||||
if (strcmp(args[arg+2], "format") == 0) {
|
||||
logsrv->format = get_log_format(args[arg+3]);
|
||||
if (logsrv->format < 0) {
|
||||
ha_alert("parsing [%s:%d] : unknown log format '%s'\n", file, linenum, args[arg+3]);
|
||||
err_code |= ERR_ALERT | ERR_FATAL;
|
||||
free(logsrv);
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* skip these two args */
|
||||
arg += 2;
|
||||
}
|
||||
|
||||
if (alertif_too_many_args_idx(3, arg + 1, file, linenum, args, &err_code)) {
|
||||
free(logsrv);
|
||||
goto out;
|
||||
}
|
||||
|
||||
logsrv->facility = get_log_facility(args[arg+2]);
|
||||
if (logsrv->facility < 0) {
|
||||
ha_alert("parsing [%s:%d] : unknown log facility '%s'\n", file, linenum, args[arg+2]);
|
||||
err_code |= ERR_ALERT | ERR_FATAL;
|
||||
logsrv->facility = 0;
|
||||
}
|
||||
|
||||
logsrv->level = 7; /* max syslog level = debug */
|
||||
if (*(args[arg+3])) {
|
||||
logsrv->level = get_log_level(args[arg+3]);
|
||||
if (logsrv->level < 0) {
|
||||
ha_alert("parsing [%s:%d] : unknown optional log level '%s'\n", file, linenum, args[arg+3]);
|
||||
err_code |= ERR_ALERT | ERR_FATAL;
|
||||
logsrv->level = 0;
|
||||
}
|
||||
}
|
||||
|
||||
logsrv->minlvl = 0; /* limit syslog level to this level (emerg) */
|
||||
if (*(args[arg+4])) {
|
||||
logsrv->minlvl = get_log_level(args[arg+4]);
|
||||
if (logsrv->minlvl < 0) {
|
||||
ha_alert("parsing [%s:%d] : unknown optional minimum log level '%s'\n", file, linenum, args[arg+4]);
|
||||
err_code |= ERR_ALERT | ERR_FATAL;
|
||||
logsrv->minlvl = 0;
|
||||
}
|
||||
}
|
||||
|
||||
sk = str2sa_range(args[1], NULL, &port1, &port2, &errmsg, NULL, NULL, 1);
|
||||
if (!sk) {
|
||||
ha_alert("parsing [%s:%d] : '%s': %s\n", file, linenum, args[0], errmsg);
|
||||
err_code |= ERR_ALERT | ERR_FATAL;
|
||||
free(logsrv);
|
||||
goto out;
|
||||
}
|
||||
logsrv->addr = *sk;
|
||||
|
||||
if (sk->ss_family == AF_INET || sk->ss_family == AF_INET6) {
|
||||
if (port1 != port2) {
|
||||
ha_alert("parsing [%s:%d] : '%s' : port ranges and offsets are not allowed in '%s'\n",
|
||||
file, linenum, args[0], args[1]);
|
||||
err_code |= ERR_ALERT | ERR_FATAL;
|
||||
free(logsrv);
|
||||
goto out;
|
||||
}
|
||||
|
||||
logsrv->addr = *sk;
|
||||
if (!port1)
|
||||
set_host_port(&logsrv->addr, SYSLOG_PORT);
|
||||
}
|
||||
|
||||
LIST_ADDQ(&global.logsrvs, &logsrv->list);
|
||||
}
|
||||
else if (!strcmp(args[0], "log-send-hostname")) { /* set the hostname in syslog header */
|
||||
char *name;
|
||||
@ -6165,133 +6047,9 @@ stats_error_parsing:
|
||||
chunk_destroy(&curproxy->log_tag);
|
||||
chunk_initstr(&curproxy->log_tag, strdup(args[1]));
|
||||
}
|
||||
else if (!strcmp(args[0], "log") && kwm == KWM_NO) {
|
||||
/* delete previous herited or defined syslog servers */
|
||||
struct logsrv *back;
|
||||
|
||||
if (*(args[1]) != 0) {
|
||||
ha_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(tmplogsrv, back, &curproxy->logsrvs, list) {
|
||||
LIST_DEL(&tmplogsrv->list);
|
||||
free(tmplogsrv);
|
||||
}
|
||||
}
|
||||
else if (!strcmp(args[0], "log")) { /* syslog server address */
|
||||
struct logsrv *logsrv;
|
||||
|
||||
if (*(args[1]) && *(args[2]) == 0 && !strcmp(args[1], "global")) {
|
||||
/* copy global.logrsvs linked list to the end of curproxy->logsrvs */
|
||||
list_for_each_entry(tmplogsrv, &global.logsrvs, list) {
|
||||
struct logsrv *node = malloc(sizeof(*node));
|
||||
memcpy(node, tmplogsrv, sizeof(struct logsrv));
|
||||
LIST_INIT(&node->list);
|
||||
LIST_ADDQ(&curproxy->logsrvs, &node->list);
|
||||
}
|
||||
}
|
||||
else if (*(args[1]) && *(args[2])) {
|
||||
struct sockaddr_storage *sk;
|
||||
int port1, port2;
|
||||
int arg = 0;
|
||||
int len = 0;
|
||||
|
||||
logsrv = calloc(1, sizeof(*logsrv));
|
||||
|
||||
/* just after the address, a length may be specified */
|
||||
if (strcmp(args[arg+2], "len") == 0) {
|
||||
len = atoi(args[arg+3]);
|
||||
if (len < 80 || len > 65535) {
|
||||
ha_alert("parsing [%s:%d] : invalid log length '%s', must be between 80 and 65535.\n",
|
||||
file, linenum, args[arg+3]);
|
||||
err_code |= ERR_ALERT | ERR_FATAL;
|
||||
goto out;
|
||||
}
|
||||
logsrv->maxlen = len;
|
||||
|
||||
/* skip these two args */
|
||||
arg += 2;
|
||||
}
|
||||
else
|
||||
logsrv->maxlen = MAX_SYSLOG_LEN;
|
||||
|
||||
if (logsrv->maxlen > global.max_syslog_len)
|
||||
global.max_syslog_len = logsrv->maxlen;
|
||||
|
||||
/* after the length, a format may be specified */
|
||||
if (strcmp(args[arg+2], "format") == 0) {
|
||||
logsrv->format = get_log_format(args[arg+3]);
|
||||
if (logsrv->format < 0) {
|
||||
ha_alert("parsing [%s:%d] : unknown log format '%s'\n", file, linenum, args[arg+3]);
|
||||
err_code |= ERR_ALERT | ERR_FATAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* skip these two args */
|
||||
arg += 2;
|
||||
}
|
||||
|
||||
if (alertif_too_many_args_idx(3, arg + 1, file, linenum, args, &err_code))
|
||||
goto out;
|
||||
|
||||
logsrv->facility = get_log_facility(args[arg+2]);
|
||||
if (logsrv->facility < 0) {
|
||||
ha_alert("parsing [%s:%d] : unknown log facility '%s'\n", file, linenum, args[arg+2]);
|
||||
err_code |= ERR_ALERT | ERR_FATAL;
|
||||
goto out;
|
||||
|
||||
}
|
||||
|
||||
logsrv->level = 7; /* max syslog level = debug */
|
||||
if (*(args[arg+3])) {
|
||||
logsrv->level = get_log_level(args[arg+3]);
|
||||
if (logsrv->level < 0) {
|
||||
ha_alert("parsing [%s:%d] : unknown optional log level '%s'\n", file, linenum, args[arg+3]);
|
||||
err_code |= ERR_ALERT | ERR_FATAL;
|
||||
goto out;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
logsrv->minlvl = 0; /* limit syslog level to this level (emerg) */
|
||||
if (*(args[arg+4])) {
|
||||
logsrv->minlvl = get_log_level(args[arg+4]);
|
||||
if (logsrv->minlvl < 0) {
|
||||
ha_alert("parsing [%s:%d] : unknown optional minimum log level '%s'\n", file, linenum, args[arg+4]);
|
||||
err_code |= ERR_ALERT | ERR_FATAL;
|
||||
goto out;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
sk = str2sa_range(args[1], NULL, &port1, &port2, &errmsg, NULL, NULL, 1);
|
||||
if (!sk) {
|
||||
ha_alert("parsing [%s:%d] : '%s': %s\n", file, linenum, args[0], errmsg);
|
||||
err_code |= ERR_ALERT | ERR_FATAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
logsrv->addr = *sk;
|
||||
|
||||
if (sk->ss_family == AF_INET || sk->ss_family == AF_INET6) {
|
||||
if (port1 != port2) {
|
||||
ha_alert("parsing [%s:%d] : '%s' : port ranges and offsets are not allowed in '%s'\n",
|
||||
file, linenum, args[0], args[1]);
|
||||
err_code |= ERR_ALERT | ERR_FATAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!port1)
|
||||
set_host_port(&logsrv->addr, SYSLOG_PORT);
|
||||
}
|
||||
|
||||
LIST_ADDQ(&curproxy->logsrvs, &logsrv->list);
|
||||
}
|
||||
else {
|
||||
ha_alert("parsing [%s:%d] : 'log' expects either <address[:port]> and <facility> or 'global' as arguments.\n",
|
||||
file, linenum);
|
||||
else if (!strcmp(args[0], "log")) { /* "no log" or "log ..." */
|
||||
if (!parse_logsrv(args, &curproxy->logsrvs, (kwm == KWM_NO), &errmsg)) {
|
||||
ha_alert("parsing [%s:%d] : %s : %s\n", file, linenum, args[0], errmsg);
|
||||
err_code |= ERR_ALERT | ERR_FATAL;
|
||||
goto out;
|
||||
}
|
||||
|
160
src/log.c
160
src/log.c
@ -671,6 +671,166 @@ int parse_logformat_string(const char *fmt, struct proxy *curproxy, struct list
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Parse "log" keyword and update <logsrvs> list accordingly.
|
||||
*
|
||||
* When <do_del> is set, it means the "no log" line was parsed, so all log
|
||||
* servers in <logsrvs> are released.
|
||||
*
|
||||
* Otherwise, we try to parse the "log" line. First of all, when the list is not
|
||||
* the global one, we look for the parameter "global". If we find it,
|
||||
* global.logsrvs is copied. Else we parse each arguments.
|
||||
*
|
||||
* The function returns 1 in success case, otherwise, it returns 0 and err is
|
||||
* filled.
|
||||
*/
|
||||
int parse_logsrv(char **args, struct list *logsrvs, int do_del, char **err)
|
||||
{
|
||||
struct sockaddr_storage *sk;
|
||||
struct logsrv *logsrv = NULL;
|
||||
int port1, port2;
|
||||
int cur_arg;
|
||||
|
||||
/*
|
||||
* "no log": delete previous herited or defined syslog
|
||||
* servers.
|
||||
*/
|
||||
if (do_del) {
|
||||
struct logsrv *back;
|
||||
|
||||
if (*(args[1]) != 0) {
|
||||
memprintf(err, "'no log' does not expect arguments");
|
||||
goto error;
|
||||
}
|
||||
|
||||
list_for_each_entry_safe(logsrv, back, logsrvs, list) {
|
||||
LIST_DEL(&logsrv->list);
|
||||
free(logsrv);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* "log global": copy global.logrsvs linked list to the end of logsrvs
|
||||
* list. But first, we check (logsrvs != global.logsrvs).
|
||||
*/
|
||||
if (*(args[1]) && *(args[2]) == 0 && !strcmp(args[1], "global")) {
|
||||
if (logsrvs == &global.logsrvs) {
|
||||
memprintf(err, "'global' is not supported for a global syslog server");
|
||||
goto error;
|
||||
}
|
||||
list_for_each_entry(logsrv, &global.logsrvs, list) {
|
||||
struct logsrv *node = malloc(sizeof(*node));
|
||||
memcpy(node, logsrv, sizeof(struct logsrv));
|
||||
LIST_INIT(&node->list);
|
||||
LIST_ADDQ(logsrvs, &node->list);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* "log <address> ...: parse a syslog server line
|
||||
*/
|
||||
if (*(args[1]) == 0 || *(args[2]) == 0) {
|
||||
memprintf(err, "expects <address> and <facility> %s as arguments",
|
||||
((logsrvs == &global.logsrvs) ? "" : "or global"));
|
||||
goto error;
|
||||
}
|
||||
|
||||
logsrv = calloc(1, sizeof(*logsrv));
|
||||
if (!logsrv) {
|
||||
memprintf(err, "out of memory");
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* skip address for now, it will be parsed at the end */
|
||||
cur_arg = 2;
|
||||
|
||||
/* just after the address, a length may be specified */
|
||||
logsrv->maxlen = MAX_SYSLOG_LEN;
|
||||
if (strcmp(args[cur_arg], "len") == 0) {
|
||||
int len = atoi(args[cur_arg+1]);
|
||||
if (len < 80 || len > 65535) {
|
||||
memprintf(err, "invalid log length '%s', must be between 80 and 65535",
|
||||
args[cur_arg+1]);
|
||||
goto error;
|
||||
}
|
||||
logsrv->maxlen = len;
|
||||
cur_arg += 2;
|
||||
}
|
||||
if (logsrv->maxlen > global.max_syslog_len)
|
||||
global.max_syslog_len = logsrv->maxlen;
|
||||
|
||||
/* after the length, a format may be specified */
|
||||
if (strcmp(args[cur_arg], "format") == 0) {
|
||||
logsrv->format = get_log_format(args[cur_arg+1]);
|
||||
if (logsrv->format < 0) {
|
||||
memprintf(err, "unknown log format '%s'", args[cur_arg+1]);
|
||||
goto error;
|
||||
}
|
||||
cur_arg += 2;
|
||||
}
|
||||
|
||||
/* parse the facility */
|
||||
logsrv->facility = get_log_facility(args[cur_arg]);
|
||||
if (logsrv->facility < 0) {
|
||||
memprintf(err, "unknown log facility '%s'", args[cur_arg]);
|
||||
goto error;
|
||||
}
|
||||
cur_arg++;
|
||||
|
||||
/* parse the max syslog level (default: debug) */
|
||||
logsrv->level = 7;
|
||||
if (*(args[cur_arg])) {
|
||||
logsrv->level = get_log_level(args[cur_arg]);
|
||||
if (logsrv->level < 0) {
|
||||
memprintf(err, "unknown optional log level '%s'", args[cur_arg]);
|
||||
goto error;
|
||||
}
|
||||
cur_arg++;
|
||||
}
|
||||
|
||||
/* parse the limit syslog level (default: emerg) */
|
||||
logsrv->minlvl = 0;
|
||||
if (*(args[cur_arg])) {
|
||||
logsrv->minlvl = get_log_level(args[cur_arg]);
|
||||
if (logsrv->minlvl < 0) {
|
||||
memprintf(err, "unknown optional minimum log level '%s'", args[cur_arg]);
|
||||
goto error;
|
||||
}
|
||||
cur_arg++;
|
||||
}
|
||||
|
||||
/* Too many args */
|
||||
if (*(args[cur_arg])) {
|
||||
memprintf(err, "cannot handle unexpected argument '%s'", args[cur_arg]);
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* now, back to the address */
|
||||
sk = str2sa_range(args[1], NULL, &port1, &port2, err, NULL, NULL, 1);
|
||||
if (!sk)
|
||||
goto error;
|
||||
logsrv->addr = *sk;
|
||||
|
||||
if (sk->ss_family == AF_INET || sk->ss_family == AF_INET6) {
|
||||
if (port1 != port2) {
|
||||
memprintf(err, "port ranges and offsets are not allowed in '%s'", args[1]);
|
||||
goto error;
|
||||
}
|
||||
logsrv->addr = *sk;
|
||||
if (!port1)
|
||||
set_host_port(&logsrv->addr, SYSLOG_PORT);
|
||||
}
|
||||
LIST_ADDQ(logsrvs, &logsrv->list);
|
||||
return 1;
|
||||
|
||||
error:
|
||||
free(logsrv);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* Generic function to display messages prefixed by a label */
|
||||
static void print_message(const char *label, const char *fmt, va_list argp)
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user