mirror of
http://git.haproxy.org/git/haproxy.git/
synced 2025-01-05 03:29:35 +00:00
MEDIUM: log: adds log forwarding section.
Log forwarding: It is possible to declare one or multiple log forwarding section, haproxy will forward all received log messages to a log servers list. log-forward <name> Creates a new log forwarder proxy identified as <name>. bind <addr> [param*] Used to configure a log udp listener to receive messages to forward. Only udp listeners are allowed, address must be prefixed using 'udp@', 'udp4@' or 'udp6@'. This supports for all "bind" parameters found in 5.1 paragraph but most of them are irrelevant for udp/syslog case. log global log <address> [len <length>] [format <format>] [sample <ranges>:<smp_size>] <facility> [<level> [<minlevel>]] Used to configure target log servers. See more details on proxies documentation. If no format specified, haproxy tries to keep the incoming log format. Configured facility is ignored, except if incoming message does not present a facility but one is mandatory on the outgoing format. If there is no timestamp available in the input format, but the field exists in output format, haproxy will use the local date. Example: global log stderr format iso local7 ring myring description "My local buffer" format rfc5424 maxlen 1200 size 32764 timeout connect 5s timeout server 10s # syslog tcp server server mysyslogsrv 127.0.0.1:514 log-proto octet-count log-forward sylog-loadb bind udp4@127.0.0.1:1514 # all messages on stderr log global # all messages on local tcp syslog server log ring@myring local0 # load balance messages on 4 udp syslog servers log 127.0.0.1:10001 sample 1:4 local0 log 127.0.0.1:10002 sample 2:4 local0 log 127.0.0.1:10003 sample 3:4 local0 log 127.0.0.1:10004 sample 4:4 local0
This commit is contained in:
parent
54932b4408
commit
12941c82d0
@ -2738,6 +2738,57 @@ timeout server <timeout>
|
||||
timeout server 10s
|
||||
server mysyslogsrv 127.0.0.1:6514 log-proto octet-count
|
||||
|
||||
3.10. Log forwarding
|
||||
-------------------
|
||||
|
||||
It is possible to declare one or multiple log forwarding section,
|
||||
haproxy will forward all received log messages to a log servers list.
|
||||
|
||||
log-forward <name>
|
||||
Creates a new log forwarder proxy identified as <name>.
|
||||
|
||||
bind <addr> [param*]
|
||||
Used to configure a log udp listener to receive messages to forward.
|
||||
Only udp listeners are allowed, address must be prefixed using
|
||||
'udp@', 'udp4@' or 'udp6@'. This supports for all "bind" parameters
|
||||
found in 5.1 paragraph but most of them are irrelevant for udp/syslog case.
|
||||
|
||||
log global
|
||||
log <address> [len <length>] [format <format>] [sample <ranges>:<smp_size>]
|
||||
<facility> [<level> [<minlevel>]]
|
||||
Used to configure target log servers. See more details on proxies
|
||||
documentation.
|
||||
If no format specified, haproxy tries to keep the incoming log format.
|
||||
Configured facility is ignored, except if incoming message does not
|
||||
present a facility but one is mandatory on the outgoing format.
|
||||
If there is no timestamp available in the input format, but the field
|
||||
exists in output format, haproxy will use the local date.
|
||||
|
||||
Example:
|
||||
global
|
||||
log stderr format iso local7
|
||||
|
||||
ring myring
|
||||
description "My local buffer"
|
||||
format rfc5424
|
||||
maxlen 1200
|
||||
size 32764
|
||||
timeout connect 5s
|
||||
timeout server 10s
|
||||
# syslog tcp server
|
||||
server mysyslogsrv 127.0.0.1:514 log-proto octet-count
|
||||
|
||||
log-forward sylog-loadb
|
||||
bind udp4@127.0.0.1:1514
|
||||
# all messages on stderr
|
||||
log global
|
||||
# all messages on local tcp syslog server
|
||||
log ring@myring local0
|
||||
# load balance messages on 4 udp syslog servers
|
||||
log 127.0.0.1:10001 sample 1:4 local0
|
||||
log 127.0.0.1:10002 sample 2:4 local0
|
||||
log 127.0.0.1:10003 sample 3:4 local0
|
||||
log 127.0.0.1:10004 sample 4:4 local0
|
||||
|
||||
4. Proxies
|
||||
----------
|
||||
@ -3323,14 +3374,14 @@ bind /<path> [, ...] [param*]
|
||||
- 'ipv4@' -> address is always IPv4
|
||||
- 'ipv6@' -> address is always IPv6
|
||||
- 'udp@' -> address is resolved as IPv4 or IPv6 and
|
||||
protocol UDP is used. Currently there is no proxy
|
||||
mode supporting those listeners.
|
||||
protocol UDP is used. Currently those listeners are
|
||||
supported only in log-forward sections.
|
||||
- 'udp4@' -> address is always IPv4 and protocol UDP
|
||||
is used. Currently there is no proxy mode supporting
|
||||
those listeners.
|
||||
is used. Currently those listeners are supported
|
||||
only in log-forward sections.
|
||||
- 'udp6@' -> address is always IPv6 and protocol UDP
|
||||
is used. Currently there is no proxy mode supporting
|
||||
those listeners.
|
||||
is used. Currently those listeners are supported
|
||||
only in log-forward sections.
|
||||
- 'unix@' -> address is a path to a local unix socket
|
||||
- 'abns@' -> address is in abstract namespace (Linux only).
|
||||
Note: since abstract sockets are not "rebindable", they
|
||||
|
@ -43,6 +43,9 @@ extern char default_rfc5424_sd_log_format[];
|
||||
|
||||
extern unsigned int dropped_logs;
|
||||
|
||||
/* lof forward proxy list */
|
||||
extern struct proxy *cfg_log_forward;
|
||||
|
||||
extern THREAD_LOCAL char *logline;
|
||||
extern THREAD_LOCAL char *logline_rfc5424;
|
||||
|
||||
|
147
src/log.c
147
src/log.c
@ -26,12 +26,15 @@
|
||||
|
||||
#include <haproxy/api.h>
|
||||
#include <haproxy/applet-t.h>
|
||||
#include <haproxy/cfgparse.h>
|
||||
#include <haproxy/cli.h>
|
||||
#include <haproxy/fd.h>
|
||||
#include <haproxy/frontend.h>
|
||||
#include <haproxy/global.h>
|
||||
#include <haproxy/http.h>
|
||||
#include <haproxy/listener.h>
|
||||
#include <haproxy/log.h>
|
||||
#include <haproxy/proxy.h>
|
||||
#include <haproxy/ring.h>
|
||||
#include <haproxy/sample.h>
|
||||
#include <haproxy/sink.h>
|
||||
@ -43,6 +46,9 @@
|
||||
#include <haproxy/version.h>
|
||||
|
||||
|
||||
/* log forward proxy list */
|
||||
struct proxy *cfg_log_forward;
|
||||
|
||||
struct log_fmt_st {
|
||||
char *name;
|
||||
};
|
||||
@ -3543,6 +3549,144 @@ out:
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Parse "log-forward" section and create corresponding sink buffer.
|
||||
*
|
||||
* The function returns 0 in success case, otherwise, it returns error
|
||||
* flags.
|
||||
*/
|
||||
int cfg_parse_log_forward(const char *file, int linenum, char **args, int kwm)
|
||||
{
|
||||
int err_code = 0;
|
||||
struct proxy *px;
|
||||
char *errmsg = NULL;
|
||||
const char *err = NULL;
|
||||
|
||||
if (strcmp(args[0], "log-forward") == 0) {
|
||||
if (!*args[1]) {
|
||||
ha_alert("parsing [%s:%d] : missing name for ip-forward section.\n", file, linenum);
|
||||
err_code |= ERR_ALERT | ERR_ABORT;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (alertif_too_many_args(1, file, linenum, args, &err_code))
|
||||
goto out;
|
||||
|
||||
err = invalid_char(args[1]);
|
||||
if (err) {
|
||||
ha_alert("parsing [%s:%d] : character '%c' is not permitted in '%s' name '%s'.\n",
|
||||
file, linenum, *err, args[0], args[1]);
|
||||
err_code |= ERR_ALERT | ERR_ABORT;
|
||||
goto out;
|
||||
}
|
||||
|
||||
for (px = cfg_log_forward ; px ; px = px->next) {
|
||||
if (strcmp(px->id, args[1]) == 0) {
|
||||
ha_alert("Parsing [%s:%d]: log-forward section '%s' has the same name as another log-forward section declared at %s:%d.\n",
|
||||
file, linenum, args[1], px->conf.file, px->conf.line);
|
||||
err_code |= ERR_ALERT | ERR_FATAL;
|
||||
}
|
||||
}
|
||||
|
||||
px = calloc(1, sizeof *px);
|
||||
if (!px) {
|
||||
err_code |= ERR_ALERT | ERR_FATAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
px->next = cfg_log_forward;
|
||||
cfg_log_forward = px;
|
||||
|
||||
init_new_proxy(px);
|
||||
px->conf.file = strdup(file);
|
||||
px->conf.line = linenum;
|
||||
px->mode = PR_MODE_SYSLOG;
|
||||
px->id = strdup(args[1]);
|
||||
|
||||
}
|
||||
else if (strcmp(args[0], "bind") == 0) {
|
||||
int cur_arg;
|
||||
static int kws_dumped;
|
||||
struct bind_conf *bind_conf;
|
||||
struct bind_kw *kw;
|
||||
struct listener *l;
|
||||
|
||||
cur_arg = 1;
|
||||
|
||||
bind_conf = bind_conf_alloc(cfg_log_forward, file, linenum,
|
||||
NULL, xprt_get(XPRT_RAW));
|
||||
|
||||
if (!str2listener(args[1], cfg_log_forward, bind_conf, file, linenum, &errmsg)) {
|
||||
if (errmsg && *errmsg) {
|
||||
indent_msg(&errmsg, 2);
|
||||
ha_alert("parsing [%s:%d] : '%s %s' : %s\n", file, linenum, args[0], args[1], errmsg);
|
||||
}
|
||||
else {
|
||||
ha_alert("parsing [%s:%d] : '%s %s' : error encountered while parsing listening address %s.\n",
|
||||
file, linenum, args[0], args[1], args[2]);
|
||||
err_code |= ERR_ALERT | ERR_FATAL;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
list_for_each_entry(l, &bind_conf->listeners, by_bind) {
|
||||
/* Currently, only UDP handlers are allowed */
|
||||
if (l->proto->sock_domain != AF_CUST_UDP4 && l->proto->sock_domain != AF_CUST_UDP6) {
|
||||
ha_alert("parsing [%s:%d] : '%s %s' : error, listening address must be prefixed using 'udp@', 'udp4@' or 'udp6@' %s.\n",
|
||||
file, linenum, args[0], args[1], args[2]);
|
||||
err_code |= ERR_ALERT | ERR_FATAL;
|
||||
goto out;
|
||||
}
|
||||
l->maxaccept = global.tune.maxaccept ? global.tune.maxaccept : 64;
|
||||
global.maxsock++;
|
||||
}
|
||||
cur_arg++;
|
||||
|
||||
while (*args[cur_arg] && (kw = bind_find_kw(args[cur_arg]))) {
|
||||
int ret;
|
||||
|
||||
ret = kw->parse(args, cur_arg, cfg_log_forward, bind_conf, &errmsg);
|
||||
err_code |= ret;
|
||||
if (ret) {
|
||||
if (errmsg && *errmsg) {
|
||||
indent_msg(&errmsg, 2);
|
||||
ha_alert("parsing [%s:%d] : %s\n", file, linenum, errmsg);
|
||||
}
|
||||
else
|
||||
ha_alert("parsing [%s:%d]: error encountered while processing '%s'\n",
|
||||
file, linenum, args[cur_arg]);
|
||||
if (ret & ERR_FATAL)
|
||||
goto out;
|
||||
}
|
||||
cur_arg += 1 + kw->skip;
|
||||
}
|
||||
if (*args[cur_arg] != 0) {
|
||||
char *kws = NULL;
|
||||
|
||||
if (!kws_dumped) {
|
||||
kws_dumped = 1;
|
||||
bind_dump_kws(&kws);
|
||||
indent_msg(&kws, 4);
|
||||
}
|
||||
ha_alert("parsing [%s:%d] : unknown keyword '%s' in '%s' section.%s%s\n",
|
||||
file, linenum, args[cur_arg], cursection,
|
||||
kws ? " Registered keywords :" : "", kws ? kws: "");
|
||||
free(kws);
|
||||
err_code |= ERR_ALERT | ERR_FATAL;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
else if (strcmp(args[0], "log") == 0) {
|
||||
if (!parse_logsrv(args, &cfg_log_forward->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;
|
||||
}
|
||||
}
|
||||
out:
|
||||
return err_code;
|
||||
}
|
||||
|
||||
|
||||
/* parse the "show startup-logs" command, returns 1 if a message is returned, otherwise zero */
|
||||
static int cli_parse_show_startup_logs(char **args, char *payload, struct appctx *appctx, void *private)
|
||||
{
|
||||
@ -3564,6 +3708,9 @@ static struct cli_kw_list cli_kws = {{ },{
|
||||
|
||||
INITCALL1(STG_REGISTER, cli_register_kw, &cli_kws);
|
||||
|
||||
/* config parsers for this section */
|
||||
REGISTER_CONFIG_SECTION("log-forward", cfg_parse_log_forward, NULL);
|
||||
|
||||
REGISTER_PER_THREAD_ALLOC(init_log_buffers);
|
||||
REGISTER_PER_THREAD_FREE(deinit_log_buffers);
|
||||
|
||||
|
13
src/sink.c
13
src/sink.c
@ -1001,6 +1001,19 @@ int post_sink_resolve()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (px = cfg_log_forward; px; px = px->next) {
|
||||
list_for_each_entry_safe(logsrv, logb, &px->logsrvs, list) {
|
||||
if (logsrv->type == LOG_TARGET_BUFFER) {
|
||||
sink = sink_find(logsrv->ring_name);
|
||||
if (!sink || sink->type != SINK_TYPE_BUFFER) {
|
||||
ha_alert("log-forward '%s' log server uses unknown ring named '%s'.\n", px->id, logsrv->ring_name);
|
||||
err_code |= ERR_ALERT | ERR_FATAL;
|
||||
}
|
||||
logsrv->sink = sink;
|
||||
}
|
||||
}
|
||||
}
|
||||
return err_code;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user