mirror of
http://git.haproxy.org/git/haproxy.git/
synced 2025-04-07 01:31:35 +00:00
MAJOR: log: introduce log backends
Using "mode log" in a backend section turns the proxy in a log backend which can be used to log-balance logs between multiple log targets (udp or tcp servers) log backends can be used as regular log targets using the log directive with "backend@be_name" prefix, like so: | log backend@mybackend local0 A log backend will distribute log messages to servers according to the log load-balancing algorithm that can be set using the "log-balance" option from the log backend section. For now, only the roundrobin algorithm is supported and set by default.
This commit is contained in:
parent
e58a9b4baf
commit
9a74a6cb17
@ -4426,6 +4426,7 @@ id - X X X
|
|||||||
ignore-persist - - X X
|
ignore-persist - - X X
|
||||||
load-server-state-from-file X - X X
|
load-server-state-from-file X - X X
|
||||||
log (*) X X X X
|
log (*) X X X X
|
||||||
|
log-balance X - X X
|
||||||
log-format X X X -
|
log-format X X X -
|
||||||
log-format-sd X X X -
|
log-format-sd X X X -
|
||||||
log-tag X X X X
|
log-tag X X X X
|
||||||
@ -8692,6 +8693,12 @@ no log
|
|||||||
when used as a complement this can help troubleshooting by
|
when used as a complement this can help troubleshooting by
|
||||||
having the logs instantly available.
|
having the logs instantly available.
|
||||||
|
|
||||||
|
- A log backend in the form "backend@<name>", which will send
|
||||||
|
log messages to the corresponding log backend responsible for
|
||||||
|
sending the message to the proper server according to the
|
||||||
|
backend's lb settings. A log backend is a backend section with
|
||||||
|
"mode log" set (see "mode" for more information).
|
||||||
|
|
||||||
- An explicit stream address prefix such as "tcp@","tcp6@",
|
- An explicit stream address prefix such as "tcp@","tcp6@",
|
||||||
"tcp4@" or "uxst@" will allocate an implicit ring buffer with
|
"tcp4@" or "uxst@" will allocate an implicit ring buffer with
|
||||||
a stream forward server targeting the given address.
|
a stream forward server targeting the given address.
|
||||||
@ -8809,6 +8816,43 @@ no log
|
|||||||
# level and send in tcp
|
# level and send in tcp
|
||||||
log "${LOCAL_SYSLOG}:514" local0 notice # send to local server
|
log "${LOCAL_SYSLOG}:514" local0 notice # send to local server
|
||||||
|
|
||||||
|
log-balance <algorithm> [ <arguments> ]
|
||||||
|
|
||||||
|
Define the load balancing algorithm to be used in a log backend.
|
||||||
|
("mode log" enabled)
|
||||||
|
|
||||||
|
May be used in sections : defaults | frontend | listen | backend
|
||||||
|
yes | no | yes | yes
|
||||||
|
Arguments :
|
||||||
|
<algorithm> is the algorithm used to select a server when doing load
|
||||||
|
balancing. This only applies when no persistence information
|
||||||
|
is available, or when a connection is redispatched to another
|
||||||
|
server. <algorithm> may be one of the following :
|
||||||
|
|
||||||
|
roundrobin Each server is used in turns. This is the smoothest and
|
||||||
|
fairest algorithm when the server's processing time remains
|
||||||
|
equally distributed.
|
||||||
|
|
||||||
|
<arguments> is an optional list of arguments which may be needed by some
|
||||||
|
algorithms.
|
||||||
|
|
||||||
|
The load balancing algorithm of a log backend is set to roundrobin when
|
||||||
|
no other algorithm has been set. The algorithm may only be set once for each
|
||||||
|
log backend. The above algorithms support the "backup" server option and the
|
||||||
|
"allbackups" proxy option. However server "weight" is not supported and will
|
||||||
|
be ignored.
|
||||||
|
|
||||||
|
Examples :
|
||||||
|
|
||||||
|
global
|
||||||
|
log backend@mylog-rrb local0 # send all logs to mylog-rrb backend
|
||||||
|
|
||||||
|
backend mylog-rrb
|
||||||
|
mode log
|
||||||
|
log-balance roundrobin
|
||||||
|
|
||||||
|
server s1 udp@127.0.0.1:514 # will receive 50% of log messages
|
||||||
|
server s2 udp@127.0.0.1:514
|
||||||
|
|
||||||
log-format <string>
|
log-format <string>
|
||||||
Specifies the log format string to use for traffic logs
|
Specifies the log format string to use for traffic logs
|
||||||
@ -8923,7 +8967,7 @@ maxconn <conns>
|
|||||||
See also : "server", global section's "maxconn", "fullconn"
|
See also : "server", global section's "maxconn", "fullconn"
|
||||||
|
|
||||||
|
|
||||||
mode { tcp|http }
|
mode { tcp|http|log }
|
||||||
Set the running mode or protocol of the instance
|
Set the running mode or protocol of the instance
|
||||||
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
|
||||||
@ -8939,6 +8983,16 @@ mode { tcp|http }
|
|||||||
processing and switching will be possible. This is the mode which
|
processing and switching will be possible. This is the mode which
|
||||||
brings HAProxy most of its value.
|
brings HAProxy most of its value.
|
||||||
|
|
||||||
|
log When used in a backend section, it will turn the backend into a
|
||||||
|
log backend. Such backend can be used as a log destination for
|
||||||
|
any "log" directive by using the "backend@<name>" syntax. Log
|
||||||
|
messages will be distributed to the servers from the backend
|
||||||
|
according to the lb settings which can be configured using the
|
||||||
|
"log-balance" keyword (in place of the "balance" keyword for TCP
|
||||||
|
and HTTP backends). Log backends support UDP servers by prefixing
|
||||||
|
the server's address with the "udp@" prefix. Common backend and
|
||||||
|
server features are supported, but not TCP or HTTP related ones.
|
||||||
|
|
||||||
When doing content switching, it is mandatory that the frontend and the
|
When doing content switching, it is mandatory that the frontend and the
|
||||||
backend are in the same mode (generally HTTP), otherwise the configuration
|
backend are in the same mode (generally HTTP), otherwise the configuration
|
||||||
will be refused.
|
will be refused.
|
||||||
@ -16082,7 +16136,7 @@ downinter <delay>
|
|||||||
|
|
||||||
log-proto <logproto>
|
log-proto <logproto>
|
||||||
The "log-proto" specifies the protocol used to forward event messages to
|
The "log-proto" specifies the protocol used to forward event messages to
|
||||||
a server configured in a ring section. Possible values are "legacy"
|
a server configured in a log or ring section. Possible values are "legacy"
|
||||||
and "octet-count" corresponding respectively to "Non-transparent-framing"
|
and "octet-count" corresponding respectively to "Non-transparent-framing"
|
||||||
and "Octet counting" in rfc6587. "legacy" is the default.
|
and "Octet counting" in rfc6587. "legacy" is the default.
|
||||||
|
|
||||||
|
@ -145,6 +145,11 @@ struct lbprm {
|
|||||||
struct lb_fwlc fwlc;
|
struct lb_fwlc fwlc;
|
||||||
struct lb_chash chash;
|
struct lb_chash chash;
|
||||||
struct lb_fas fas;
|
struct lb_fas fas;
|
||||||
|
struct {
|
||||||
|
struct server **srv; /* array containing in-use log servers */
|
||||||
|
struct list avail; /* servers available for lb are registered in this list */
|
||||||
|
uint32_t lastid; /* last relative id used */
|
||||||
|
} log; /* used in log-balancing context (PR_MODE_SYSLOG backend) */
|
||||||
};
|
};
|
||||||
int algo; /* load balancing algorithm and variants: BE_LB_* */
|
int algo; /* load balancing algorithm and variants: BE_LB_* */
|
||||||
int tot_wact, tot_wbck; /* total effective weights of active and backup servers */
|
int tot_wact, tot_wbck; /* total effective weights of active and backup servers */
|
||||||
|
@ -45,6 +45,7 @@ void back_handle_st_cer(struct stream *s);
|
|||||||
|
|
||||||
const char *backend_lb_algo_str(int algo);
|
const char *backend_lb_algo_str(int algo);
|
||||||
int backend_parse_balance(const char **args, char **err, struct proxy *curproxy);
|
int backend_parse_balance(const char **args, char **err, struct proxy *curproxy);
|
||||||
|
int backend_parse_log_balance(const char **args, char **err, struct proxy *curproxy);
|
||||||
int tcp_persist_rdp_cookie(struct stream *s, struct channel *req, int an_bit);
|
int tcp_persist_rdp_cookie(struct stream *s, struct channel *req, int an_bit);
|
||||||
|
|
||||||
int be_downtime(struct proxy *px);
|
int be_downtime(struct proxy *px);
|
||||||
|
@ -116,6 +116,7 @@ enum log_tgt {
|
|||||||
LOG_TARGET_DGRAM = 0, // datagram address (udp, unix socket)
|
LOG_TARGET_DGRAM = 0, // datagram address (udp, unix socket)
|
||||||
LOG_TARGET_FD, // file descriptor
|
LOG_TARGET_FD, // file descriptor
|
||||||
LOG_TARGET_BUFFER, // ring buffer
|
LOG_TARGET_BUFFER, // ring buffer
|
||||||
|
LOG_TARGET_BACKEND, // backend with SYSLOG mode
|
||||||
};
|
};
|
||||||
|
|
||||||
/* lists of fields that can be logged, for logformat_node->type */
|
/* lists of fields that can be logged, for logformat_node->type */
|
||||||
@ -240,8 +241,11 @@ enum log_target_flags {
|
|||||||
struct log_target {
|
struct log_target {
|
||||||
struct sockaddr_storage *addr;
|
struct sockaddr_storage *addr;
|
||||||
union {
|
union {
|
||||||
char *ring_name; /* type = BUFFER - preparsing */
|
char *ring_name; /* type = BUFFER - preparsing */
|
||||||
struct sink *sink; /* type = BUFFER - postparsing */
|
struct sink *sink; /* type = BUFFER - postparsing */
|
||||||
|
char *be_name; /* type = BACKEND - preparsing */
|
||||||
|
struct proxy *be; /* type = BACKEND - postparsing */
|
||||||
|
char *resolv_name; /* generic - preparsing */
|
||||||
};
|
};
|
||||||
enum log_tgt type;
|
enum log_tgt type;
|
||||||
uint16_t flags;
|
uint16_t flags;
|
||||||
|
@ -274,7 +274,8 @@ struct server {
|
|||||||
char *rdr_pfx; /* the redirection prefix */
|
char *rdr_pfx; /* the redirection prefix */
|
||||||
|
|
||||||
struct proxy *proxy; /* the proxy this server belongs to */
|
struct proxy *proxy; /* the proxy this server belongs to */
|
||||||
const struct mux_proto_list *mux_proto; /* the mux to use for all outgoing connections (specified by the "proto" keyword) */
|
const struct mux_proto_list *mux_proto; /* the mux to use for all outgoing connections (specified by the "proto" keyword) */
|
||||||
|
struct log_target *log_target; /* when 'mode log' is enabled, target facility used to transport log messages */
|
||||||
unsigned maxconn, minconn; /* max # of active sessions (0 = unlimited), min# for dynamic limit. */
|
unsigned maxconn, minconn; /* max # of active sessions (0 = unlimited), min# for dynamic limit. */
|
||||||
struct srv_per_thread *per_thr; /* array of per-thread stuff such as connections lists */
|
struct srv_per_thread *per_thr; /* array of per-thread stuff such as connections lists */
|
||||||
struct srv_per_tgroup *per_tgrp; /* array of per-tgroup stuff such as idle conns */
|
struct srv_per_tgroup *per_tgrp; /* array of per-tgroup stuff such as idle conns */
|
||||||
@ -331,7 +332,10 @@ struct server {
|
|||||||
THREAD_PAD(63);
|
THREAD_PAD(63);
|
||||||
__decl_thread(HA_SPINLOCK_T lock); /* may enclose the proxy's lock, must not be taken under */
|
__decl_thread(HA_SPINLOCK_T lock); /* may enclose the proxy's lock, must not be taken under */
|
||||||
unsigned npos, lpos; /* next and last positions in the LB tree, protected by LB lock */
|
unsigned npos, lpos; /* next and last positions in the LB tree, protected by LB lock */
|
||||||
struct eb32_node lb_node; /* node used for tree-based load balancing */
|
union {
|
||||||
|
struct eb32_node lb_node; /* node used for tree-based load balancing */
|
||||||
|
struct list lb_list; /* elem used for list-based load balancing */
|
||||||
|
};
|
||||||
struct server *next_full; /* next server in the temporary full list */
|
struct server *next_full; /* next server in the temporary full list */
|
||||||
|
|
||||||
/* usually atomically updated by any thread during parsing or on end of request */
|
/* usually atomically updated by any thread during parsing or on end of request */
|
||||||
@ -374,7 +378,7 @@ struct server {
|
|||||||
char *hostname; /* server hostname */
|
char *hostname; /* server hostname */
|
||||||
struct sockaddr_storage init_addr; /* plain IP address specified on the init-addr line */
|
struct sockaddr_storage init_addr; /* plain IP address specified on the init-addr line */
|
||||||
unsigned int init_addr_methods; /* initial address setting, 3-bit per method, ends at 0, enough to store 10 entries */
|
unsigned int init_addr_methods; /* initial address setting, 3-bit per method, ends at 0, enough to store 10 entries */
|
||||||
enum srv_log_proto log_proto; /* used proto to emit messages on server lines from ring section */
|
enum srv_log_proto log_proto; /* used proto to emit messages on server lines from log or ring section */
|
||||||
|
|
||||||
char *sni_expr; /* Temporary variable to store a sample expression for SNI */
|
char *sni_expr; /* Temporary variable to store a sample expression for SNI */
|
||||||
struct {
|
struct {
|
||||||
@ -621,6 +625,7 @@ struct srv_kw_list {
|
|||||||
#define SRV_PARSE_PARSE_ADDR 0x08 /* required to parse the server address in the second argument */
|
#define SRV_PARSE_PARSE_ADDR 0x08 /* required to parse the server address in the second argument */
|
||||||
#define SRV_PARSE_DYNAMIC 0x10 /* dynamic server created at runtime with cli */
|
#define SRV_PARSE_DYNAMIC 0x10 /* dynamic server created at runtime with cli */
|
||||||
#define SRV_PARSE_INITIAL_RESOLVE 0x20 /* resolve immediately the fqdn to an ip address */
|
#define SRV_PARSE_INITIAL_RESOLVE 0x20 /* resolve immediately the fqdn to an ip address */
|
||||||
|
#define SRV_PARSE_IN_LOG_BE 0x40 /* keyword in log backend */
|
||||||
|
|
||||||
#endif /* _HAPROXY_SERVER_T_H */
|
#endif /* _HAPROXY_SERVER_T_H */
|
||||||
|
|
||||||
|
@ -2824,6 +2824,33 @@ int backend_parse_balance(const char **args, char **err, struct proxy *curproxy)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* This function parses a "balance" statement in a log backend section
|
||||||
|
* describing <curproxy>. It returns -1 if there is any error, otherwise zero.
|
||||||
|
* If it returns -1, it will write an error message into the <err> buffer which
|
||||||
|
* will automatically be allocated and must be passed as NULL. The trailing '\n'
|
||||||
|
* will not be written. The function must be called with <args> pointing to the
|
||||||
|
* first word after "balance".
|
||||||
|
*/
|
||||||
|
int backend_parse_log_balance(const char **args, char **err, struct proxy *curproxy)
|
||||||
|
{
|
||||||
|
if (!*(args[0])) {
|
||||||
|
/* if no option is set, use round-robin by default */
|
||||||
|
curproxy->lbprm.algo &= ~BE_LB_ALGO;
|
||||||
|
curproxy->lbprm.algo |= BE_LB_ALGO_RR;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strcmp(args[0], "roundrobin") == 0) {
|
||||||
|
curproxy->lbprm.algo &= ~BE_LB_ALGO;
|
||||||
|
curproxy->lbprm.algo |= BE_LB_ALGO_RR;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
memprintf(err, "only supports 'roundrobin' option");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/************************************************************************/
|
/************************************************************************/
|
||||||
/* All supported sample and ACL keywords must be declared here. */
|
/* All supported sample and ACL keywords must be declared here. */
|
||||||
|
@ -50,7 +50,7 @@ static const char *common_kw_list[] = {
|
|||||||
"use-server", "force-persist", "ignore-persist", "force-persist",
|
"use-server", "force-persist", "ignore-persist", "force-persist",
|
||||||
"stick-table", "stick", "stats", "option", "default_backend",
|
"stick-table", "stick", "stats", "option", "default_backend",
|
||||||
"http-reuse", "monitor", "transparent", "maxconn", "backlog",
|
"http-reuse", "monitor", "transparent", "maxconn", "backlog",
|
||||||
"fullconn", "dispatch", "balance", "hash-type",
|
"fullconn", "dispatch", "balance", "log-balance", "hash-type",
|
||||||
"hash-balance-factor", "unique-id-format", "unique-id-header",
|
"hash-balance-factor", "unique-id-format", "unique-id-header",
|
||||||
"log-format", "log-format-sd", "log-tag", "log", "source", "usesrc",
|
"log-format", "log-format-sd", "log-tag", "log", "source", "usesrc",
|
||||||
"error-log-format",
|
"error-log-format",
|
||||||
@ -438,6 +438,7 @@ int cfg_parse_listen(const char *file, int linenum, char **args, int kwm)
|
|||||||
if ((strcmp(args[0], "server") == 0)) {
|
if ((strcmp(args[0], "server") == 0)) {
|
||||||
err_code |= parse_server(file, linenum, args,
|
err_code |= parse_server(file, linenum, args,
|
||||||
curproxy, curr_defproxy,
|
curproxy, curr_defproxy,
|
||||||
|
(curproxy->mode == PR_MODE_SYSLOG ? SRV_PARSE_IN_LOG_BE : 0) |
|
||||||
SRV_PARSE_PARSE_ADDR);
|
SRV_PARSE_PARSE_ADDR);
|
||||||
|
|
||||||
if (err_code & ERR_FATAL)
|
if (err_code & ERR_FATAL)
|
||||||
@ -446,6 +447,7 @@ int cfg_parse_listen(const char *file, int linenum, char **args, int kwm)
|
|||||||
else if (strcmp(args[0], "default-server") == 0) {
|
else if (strcmp(args[0], "default-server") == 0) {
|
||||||
err_code |= parse_server(file, linenum, args,
|
err_code |= parse_server(file, linenum, args,
|
||||||
curproxy, curr_defproxy,
|
curproxy, curr_defproxy,
|
||||||
|
(curproxy->mode == PR_MODE_SYSLOG ? SRV_PARSE_IN_LOG_BE : 0) |
|
||||||
SRV_PARSE_DEFAULT_SERVER);
|
SRV_PARSE_DEFAULT_SERVER);
|
||||||
|
|
||||||
if (err_code & ERR_FATAL)
|
if (err_code & ERR_FATAL)
|
||||||
@ -454,6 +456,7 @@ int cfg_parse_listen(const char *file, int linenum, char **args, int kwm)
|
|||||||
else if (strcmp(args[0], "server-template") == 0) {
|
else if (strcmp(args[0], "server-template") == 0) {
|
||||||
err_code |= parse_server(file, linenum, args,
|
err_code |= parse_server(file, linenum, args,
|
||||||
curproxy, curr_defproxy,
|
curproxy, curr_defproxy,
|
||||||
|
(curproxy->mode == PR_MODE_SYSLOG ? SRV_PARSE_IN_LOG_BE : 0) |
|
||||||
SRV_PARSE_TEMPLATE|SRV_PARSE_PARSE_ADDR);
|
SRV_PARSE_TEMPLATE|SRV_PARSE_PARSE_ADDR);
|
||||||
|
|
||||||
if (err_code & ERR_FATAL)
|
if (err_code & ERR_FATAL)
|
||||||
@ -544,6 +547,7 @@ int cfg_parse_listen(const char *file, int linenum, char **args, int kwm)
|
|||||||
|
|
||||||
if (strcmp(args[1], "http") == 0) curproxy->mode = PR_MODE_HTTP;
|
if (strcmp(args[1], "http") == 0) curproxy->mode = PR_MODE_HTTP;
|
||||||
else if (strcmp(args[1], "tcp") == 0) curproxy->mode = PR_MODE_TCP;
|
else if (strcmp(args[1], "tcp") == 0) curproxy->mode = PR_MODE_TCP;
|
||||||
|
else if (strcmp(args[1], "log") == 0 && (curproxy->cap & PR_CAP_BE)) curproxy->mode = PR_MODE_SYSLOG;
|
||||||
else if (strcmp(args[1], "health") == 0) {
|
else if (strcmp(args[1], "health") == 0) {
|
||||||
ha_alert("parsing [%s:%d] : 'mode health' doesn't exist anymore. Please use 'http-request return status 200' instead.\n", file, linenum);
|
ha_alert("parsing [%s:%d] : 'mode health' doesn't exist anymore. Please use 'http-request return status 200' instead.\n", file, linenum);
|
||||||
err_code |= ERR_ALERT | ERR_FATAL;
|
err_code |= ERR_ALERT | ERR_FATAL;
|
||||||
@ -554,6 +558,15 @@ int cfg_parse_listen(const char *file, int linenum, char **args, int kwm)
|
|||||||
err_code |= ERR_ALERT | ERR_FATAL;
|
err_code |= ERR_ALERT | ERR_FATAL;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
/* mode log shares lbprm struct with other modes, but makes a different use of it,
|
||||||
|
* thus, we must ensure that defproxy settings cannot persist between incompatibles
|
||||||
|
* modes at this point.
|
||||||
|
*/
|
||||||
|
if ((curr_defproxy->mode == PR_MODE_SYSLOG && curproxy->mode != PR_MODE_SYSLOG) ||
|
||||||
|
(curr_defproxy->mode != PR_MODE_SYSLOG && curproxy->mode == PR_MODE_SYSLOG)) {
|
||||||
|
/* lbprm settings from incompatible defproxy, back to defaults */
|
||||||
|
memset(&curproxy->lbprm, 0, sizeof(curproxy->lbprm));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (strcmp(args[0], "id") == 0) {
|
else if (strcmp(args[0], "id") == 0) {
|
||||||
struct eb32_node *node;
|
struct eb32_node *node;
|
||||||
@ -2539,6 +2552,21 @@ stats_error_parsing:
|
|||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (strcmp(args[0], "log-balance") == 0) { /* set log-balancing with optional algorithm */
|
||||||
|
if (warnifnotcap(curproxy, PR_CAP_BE, file, linenum, args[0], NULL))
|
||||||
|
err_code |= ERR_WARN;
|
||||||
|
if (curproxy->mode != PR_MODE_SYSLOG) {
|
||||||
|
ha_alert("parsing [%s:%d] : %s %s\n", file, linenum, args[0], "only available for log backends");
|
||||||
|
err_code |= ERR_ALERT | ERR_FATAL;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (backend_parse_log_balance((const char **)args + 1, &errmsg, curproxy) < 0) {
|
||||||
|
ha_alert("parsing [%s:%d] : %s %s\n", file, linenum, args[0], errmsg);
|
||||||
|
err_code |= ERR_ALERT | ERR_FATAL;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
}
|
||||||
else if (strcmp(args[0], "hash-type") == 0) { /* set hashing method */
|
else if (strcmp(args[0], "hash-type") == 0) { /* set hashing method */
|
||||||
/**
|
/**
|
||||||
* The syntax for hash-type config element is
|
* The syntax for hash-type config element is
|
||||||
|
@ -3744,6 +3744,12 @@ out_uri_auth_compat:
|
|||||||
* on what LB algorithm was chosen.
|
* on what LB algorithm was chosen.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
if (curproxy->mode == PR_MODE_SYSLOG) {
|
||||||
|
/* log load-balancing requires special init that is performed
|
||||||
|
* during log-postparsing step
|
||||||
|
*/
|
||||||
|
goto skip_server_lb_init;
|
||||||
|
}
|
||||||
curproxy->lbprm.algo &= ~(BE_LB_LKUP | BE_LB_PROP_DYN);
|
curproxy->lbprm.algo &= ~(BE_LB_LKUP | BE_LB_PROP_DYN);
|
||||||
switch (curproxy->lbprm.algo & BE_LB_KIND) {
|
switch (curproxy->lbprm.algo & BE_LB_KIND) {
|
||||||
case BE_LB_KIND_RR:
|
case BE_LB_KIND_RR:
|
||||||
@ -3783,6 +3789,7 @@ out_uri_auth_compat:
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
skip_server_lb_init:
|
||||||
HA_RWLOCK_INIT(&curproxy->lbprm.lock);
|
HA_RWLOCK_INIT(&curproxy->lbprm.lock);
|
||||||
|
|
||||||
if (curproxy->options & PR_O_LOGASAP)
|
if (curproxy->options & PR_O_LOGASAP)
|
||||||
|
274
src/log.c
274
src/log.c
@ -740,14 +740,14 @@ static inline void init_log_target(struct log_target *target)
|
|||||||
target->type = 0;
|
target->type = 0;
|
||||||
target->flags = LOG_TARGET_FL_NONE;
|
target->flags = LOG_TARGET_FL_NONE;
|
||||||
target->addr = NULL;
|
target->addr = NULL;
|
||||||
target->ring_name = NULL;
|
target->resolv_name = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void deinit_log_target(struct log_target *target)
|
static void deinit_log_target(struct log_target *target)
|
||||||
{
|
{
|
||||||
ha_free(&target->addr);
|
ha_free(&target->addr);
|
||||||
if (!(target->flags & LOG_TARGET_FL_RESOLVED))
|
if (!(target->flags & LOG_TARGET_FL_RESOLVED))
|
||||||
ha_free(&target->ring_name);
|
ha_free(&target->resolv_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* returns 0 on failure and positive value on success */
|
/* returns 0 on failure and positive value on success */
|
||||||
@ -761,9 +761,9 @@ static int dup_log_target(struct log_target *def, struct log_target *cpy)
|
|||||||
goto error;
|
goto error;
|
||||||
*cpy->addr = *def->addr;
|
*cpy->addr = *def->addr;
|
||||||
}
|
}
|
||||||
if (def->ring_name) {
|
if (def->resolv_name) {
|
||||||
cpy->ring_name = strdup(def->ring_name);
|
cpy->resolv_name = strdup(def->resolv_name);
|
||||||
if (!cpy->ring_name)
|
if (!cpy->resolv_name)
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
cpy->type = def->type;
|
cpy->type = def->type;
|
||||||
@ -773,6 +773,172 @@ static int dup_log_target(struct log_target *def, struct log_target *cpy)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* must be called under the lbprm lock */
|
||||||
|
static void _log_backend_srv_queue(struct server *srv)
|
||||||
|
{
|
||||||
|
struct proxy *p = srv->proxy;
|
||||||
|
|
||||||
|
/* queue the server in the proxy lb array to make it easily searcheable by
|
||||||
|
* log-balance algorithms. Here we use the srv array as a general server
|
||||||
|
* pool of in-use servers, lookup is done using a relative positional id
|
||||||
|
* (array is contiguous)
|
||||||
|
*
|
||||||
|
* We use the avail server list to get a quick hand on available servers
|
||||||
|
* (those that are UP)
|
||||||
|
*/
|
||||||
|
if (srv->flags & SRV_F_BACKUP) {
|
||||||
|
if (!p->srv_act)
|
||||||
|
p->lbprm.log.srv[p->srv_bck] = srv;
|
||||||
|
p->srv_bck++;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (!p->srv_act) {
|
||||||
|
/* we will be switching to act tree in LB logic, thus we need to
|
||||||
|
* reset the lastid
|
||||||
|
*/
|
||||||
|
HA_ATOMIC_STORE(&p->lbprm.log.lastid, 0);
|
||||||
|
}
|
||||||
|
p->lbprm.log.srv[p->srv_act] = srv;
|
||||||
|
p->srv_act++;
|
||||||
|
}
|
||||||
|
/* append the server to the list of available servers */
|
||||||
|
LIST_APPEND(&p->lbprm.log.avail, &srv->lb_list);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void log_backend_srv_up(struct server *srv)
|
||||||
|
{
|
||||||
|
struct proxy *p = srv->proxy;
|
||||||
|
|
||||||
|
if (!srv_lb_status_changed(srv))
|
||||||
|
return; /* nothing to do */
|
||||||
|
if (srv_currently_usable(srv) || !srv_willbe_usable(srv))
|
||||||
|
return; /* false alarm */
|
||||||
|
|
||||||
|
HA_RWLOCK_WRLOCK(LBPRM_LOCK, &p->lbprm.lock);
|
||||||
|
_log_backend_srv_queue(srv);
|
||||||
|
HA_RWLOCK_WRUNLOCK(LBPRM_LOCK, &p->lbprm.lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* must be called under lbprm lock */
|
||||||
|
static void _log_backend_srv_recalc(struct proxy *p)
|
||||||
|
{
|
||||||
|
unsigned int it = 0;
|
||||||
|
struct server *cur_srv;
|
||||||
|
|
||||||
|
list_for_each_entry(cur_srv, &p->lbprm.log.avail, lb_list) {
|
||||||
|
uint8_t backup = cur_srv->flags & SRV_F_BACKUP;
|
||||||
|
|
||||||
|
if ((!p->srv_act && backup) ||
|
||||||
|
(p->srv_act && !backup))
|
||||||
|
p->lbprm.log.srv[it++] = cur_srv;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* must be called under the lbprm lock */
|
||||||
|
static void _log_backend_srv_dequeue(struct server *srv)
|
||||||
|
{
|
||||||
|
struct proxy *p = srv->proxy;
|
||||||
|
|
||||||
|
if (srv->flags & SRV_F_BACKUP) {
|
||||||
|
p->srv_bck--;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
p->srv_act--;
|
||||||
|
if (!p->srv_act) {
|
||||||
|
/* we will be switching to bck tree in LB logic, thus we need to
|
||||||
|
* reset the lastid
|
||||||
|
*/
|
||||||
|
HA_ATOMIC_STORE(&p->lbprm.log.lastid, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* remove the srv from the list of available (UP) servers */
|
||||||
|
LIST_DELETE(&srv->lb_list);
|
||||||
|
|
||||||
|
/* reconstruct the array of usable servers */
|
||||||
|
_log_backend_srv_recalc(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void log_backend_srv_down(struct server *srv)
|
||||||
|
{
|
||||||
|
struct proxy *p = srv->proxy;
|
||||||
|
|
||||||
|
if (!srv_lb_status_changed(srv))
|
||||||
|
return; /* nothing to do */
|
||||||
|
if (!srv_currently_usable(srv) || srv_willbe_usable(srv))
|
||||||
|
return; /* false alarm */
|
||||||
|
|
||||||
|
HA_RWLOCK_WRLOCK(LBPRM_LOCK, &p->lbprm.lock);
|
||||||
|
_log_backend_srv_dequeue(srv);
|
||||||
|
HA_RWLOCK_WRUNLOCK(LBPRM_LOCK, &p->lbprm.lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int postcheck_log_backend(struct proxy *be)
|
||||||
|
{
|
||||||
|
char *msg = NULL;
|
||||||
|
struct server *srv;
|
||||||
|
int err_code = ERR_NONE;
|
||||||
|
int target_type = -1; // -1 is unused in log_tgt enum
|
||||||
|
|
||||||
|
if (be->mode != PR_MODE_SYSLOG ||
|
||||||
|
(be->flags & (PR_FL_DISABLED|PR_FL_STOPPED)))
|
||||||
|
return ERR_NONE; /* nothing to do */
|
||||||
|
|
||||||
|
/* First time encoutering this log backend, perform some init
|
||||||
|
*/
|
||||||
|
be->lbprm.set_server_status_up = log_backend_srv_up;
|
||||||
|
be->lbprm.set_server_status_down = log_backend_srv_down;
|
||||||
|
be->lbprm.log.lastid = 0; /* initial value */
|
||||||
|
LIST_INIT(&be->lbprm.log.avail);
|
||||||
|
|
||||||
|
/* alloc srv array (it will be used for active and backup server lists in turn,
|
||||||
|
* so we ensure that the longest list will fit
|
||||||
|
*/
|
||||||
|
be->lbprm.log.srv = calloc(MAX(be->srv_act, be->srv_bck), sizeof(struct server *));
|
||||||
|
|
||||||
|
if (!be->lbprm.log.srv ) {
|
||||||
|
memprintf(&msg, "memory error when allocating server array (%d entries)",
|
||||||
|
MAX(be->srv_act, be->srv_bck));
|
||||||
|
err_code |= ERR_ALERT | ERR_FATAL;
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* reinit srv counters, lbprm queueing will recount */
|
||||||
|
be->srv_act = 0;
|
||||||
|
be->srv_bck = 0;
|
||||||
|
|
||||||
|
/* finish the initialization of proxy's servers */
|
||||||
|
srv = be->srv;
|
||||||
|
while (srv) {
|
||||||
|
if (target_type == -1)
|
||||||
|
target_type = srv->log_target->type;
|
||||||
|
if (target_type != srv->log_target->type) {
|
||||||
|
memprintf(&msg, "cannot mix server types within a log backend, '%s' srv's network type differs from previous server", srv->id);
|
||||||
|
err_code |= ERR_ALERT | ERR_FATAL;
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
if (target_type == LOG_TARGET_BUFFER) {
|
||||||
|
srv->log_target->sink = sink_new_from_srv(srv, "log backend");
|
||||||
|
if (!srv->log_target->sink) {
|
||||||
|
memprintf(&msg, "error when creating sink from '%s' log server", srv->id);
|
||||||
|
err_code |= ERR_ALERT | ERR_FATAL;
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
srv->cur_eweight = 1; /* ignore weights, all servers have the same weight */
|
||||||
|
_log_backend_srv_queue(srv);
|
||||||
|
srv = srv->next;
|
||||||
|
}
|
||||||
|
end:
|
||||||
|
if (err_code & ERR_CODE) {
|
||||||
|
ha_free(&be->lbprm.log.srv); /* free log servers array */
|
||||||
|
ha_alert("log backend '%s': failed to initialize: %s.\n", be->id, msg);
|
||||||
|
ha_free(&msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
return err_code;
|
||||||
|
}
|
||||||
|
|
||||||
/* resolves a single logger entry (it is expected to be called
|
/* resolves a single logger entry (it is expected to be called
|
||||||
* at postparsing stage)
|
* at postparsing stage)
|
||||||
*
|
*
|
||||||
@ -791,7 +957,26 @@ int resolve_logger(struct logger *logger, char **msg)
|
|||||||
|
|
||||||
if (target->type == LOG_TARGET_BUFFER)
|
if (target->type == LOG_TARGET_BUFFER)
|
||||||
err_code = sink_resolve_logger_buffer(logger, msg);
|
err_code = sink_resolve_logger_buffer(logger, msg);
|
||||||
|
else if (target->type == LOG_TARGET_BACKEND) {
|
||||||
|
struct proxy *be;
|
||||||
|
|
||||||
|
/* special case */
|
||||||
|
be = proxy_find_by_name(target->be_name, PR_CAP_BE, 0);
|
||||||
|
if (!be) {
|
||||||
|
memprintf(msg, "uses unknown log backend '%s'", target->be_name);
|
||||||
|
err_code |= ERR_ALERT | ERR_FATAL;
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
else if (be->mode != PR_MODE_SYSLOG) {
|
||||||
|
memprintf(msg, "uses incompatible log backend '%s'", target->be_name);
|
||||||
|
err_code |= ERR_ALERT | ERR_FATAL;
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
ha_free(&target->be_name); /* backend is resolved and will replace name hint */
|
||||||
|
target->be = be;
|
||||||
|
}
|
||||||
|
|
||||||
|
end:
|
||||||
target->flags |= LOG_TARGET_FL_RESOLVED;
|
target->flags |= LOG_TARGET_FL_RESOLVED;
|
||||||
|
|
||||||
return err_code;
|
return err_code;
|
||||||
@ -861,6 +1046,11 @@ static int parse_log_target(char *raw, struct log_target *target, char **err)
|
|||||||
target->ring_name = strdup(raw + 5);
|
target->ring_name = strdup(raw + 5);
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
else if (strncmp(raw, "backend@", 8) == 0) {
|
||||||
|
target->type = LOG_TARGET_BACKEND;
|
||||||
|
target->be_name = strdup(raw + 8);
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
/* try to allocate log target addr */
|
/* try to allocate log target addr */
|
||||||
target->addr = malloc(sizeof(*target->addr));
|
target->addr = malloc(sizeof(*target->addr));
|
||||||
@ -1876,6 +2066,69 @@ static inline void __do_send_log(struct log_target *target, struct log_header hd
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* does the same as __do_send_log() does for a single target, but here the log
|
||||||
|
* will be sent according to the log backend's lb settings. The function will
|
||||||
|
* leverage __do_send_log() function to actually send the log messages.
|
||||||
|
*/
|
||||||
|
static inline void __do_send_log_backend(struct proxy *be, struct log_header hdr,
|
||||||
|
int nblogger, size_t maxlen,
|
||||||
|
char *message, size_t size)
|
||||||
|
{
|
||||||
|
struct server *srv;
|
||||||
|
uint32_t targetid = ~0; /* default value to check if it was explicitly assigned */
|
||||||
|
uint32_t nb_srv;
|
||||||
|
|
||||||
|
HA_RWLOCK_RDLOCK(LBPRM_LOCK, &be->lbprm.lock);
|
||||||
|
|
||||||
|
if (be->srv_act) {
|
||||||
|
nb_srv = be->srv_act;
|
||||||
|
}
|
||||||
|
else if (be->srv_bck) {
|
||||||
|
/* no more active servers but backup ones are, switch to backup farm */
|
||||||
|
nb_srv = be->srv_bck;
|
||||||
|
if (!(be->options & PR_O_USE_ALL_BK)) {
|
||||||
|
/* log balancing disabled on backup farm */
|
||||||
|
targetid = 0; /* use first server */
|
||||||
|
goto skip_lb;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* no srv available, can't log */
|
||||||
|
goto drop;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* log-balancing logic: */
|
||||||
|
|
||||||
|
if ((be->lbprm.algo & BE_LB_ALGO) == BE_LB_ALGO_RR) {
|
||||||
|
/* Atomically load and update lastid since it's not protected
|
||||||
|
* by any write lock
|
||||||
|
*
|
||||||
|
* Wrapping is expected and could lead to unexpected ID reset in the
|
||||||
|
* middle of a cycle, but given that this only happens once in every
|
||||||
|
* 4 billions it is quite negligible
|
||||||
|
*/
|
||||||
|
targetid = HA_ATOMIC_FETCH_ADD(&be->lbprm.log.lastid, 1) % nb_srv;
|
||||||
|
}
|
||||||
|
|
||||||
|
skip_lb:
|
||||||
|
|
||||||
|
if (targetid == ~0) {
|
||||||
|
/* no target assigned, nothing to do */
|
||||||
|
goto drop;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* find server based on targetid */
|
||||||
|
srv = be->lbprm.log.srv[targetid];
|
||||||
|
HA_RWLOCK_RDUNLOCK(LBPRM_LOCK, &be->lbprm.lock);
|
||||||
|
|
||||||
|
__do_send_log(srv->log_target, hdr, nblogger, maxlen, message, size);
|
||||||
|
return;
|
||||||
|
|
||||||
|
drop:
|
||||||
|
HA_RWLOCK_RDUNLOCK(LBPRM_LOCK, &be->lbprm.lock);
|
||||||
|
_HA_ATOMIC_INC(&dropped_logs);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This function sends a syslog message.
|
* This function sends a syslog message.
|
||||||
* It doesn't care about errors nor does it report them.
|
* It doesn't care about errors nor does it report them.
|
||||||
@ -1931,7 +2184,15 @@ void process_send_log(struct list *loggers, int level, int facility,
|
|||||||
hdr.facility = (facility == -1) ? logger->facility : facility;
|
hdr.facility = (facility == -1) ? logger->facility : facility;
|
||||||
hdr.format = logger->format;
|
hdr.format = logger->format;
|
||||||
hdr.metadata = metadata;
|
hdr.metadata = metadata;
|
||||||
__do_send_log(&logger->target, hdr, ++nblogger, logger->maxlen, message, size);
|
|
||||||
|
nblogger += 1;
|
||||||
|
if (logger->target.type == LOG_TARGET_BACKEND) {
|
||||||
|
__do_send_log_backend(logger->target.be, hdr, nblogger, logger->maxlen, message, size);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* normal target */
|
||||||
|
__do_send_log(&logger->target, hdr, nblogger, logger->maxlen, message, size);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -4181,6 +4442,7 @@ static int postresolve_loggers()
|
|||||||
/* config parsers for this section */
|
/* config parsers for this section */
|
||||||
REGISTER_CONFIG_SECTION("log-forward", cfg_parse_log_forward, NULL);
|
REGISTER_CONFIG_SECTION("log-forward", cfg_parse_log_forward, NULL);
|
||||||
REGISTER_POST_CHECK(postresolve_loggers);
|
REGISTER_POST_CHECK(postresolve_loggers);
|
||||||
|
REGISTER_POST_PROXY_CHECK(postcheck_log_backend);
|
||||||
|
|
||||||
REGISTER_PER_THREAD_ALLOC(init_log_buffers);
|
REGISTER_PER_THREAD_ALLOC(init_log_buffers);
|
||||||
REGISTER_PER_THREAD_FREE(deinit_log_buffers);
|
REGISTER_PER_THREAD_FREE(deinit_log_buffers);
|
||||||
|
@ -190,6 +190,8 @@ void free_proxy(struct proxy *p)
|
|||||||
free(p->conf.uif_file);
|
free(p->conf.uif_file);
|
||||||
if ((p->lbprm.algo & BE_LB_LKUP) == BE_LB_LKUP_MAP)
|
if ((p->lbprm.algo & BE_LB_LKUP) == BE_LB_LKUP_MAP)
|
||||||
free(p->lbprm.map.srv);
|
free(p->lbprm.map.srv);
|
||||||
|
if (p->mode == PR_MODE_SYSLOG)
|
||||||
|
free(p->lbprm.log.srv);
|
||||||
|
|
||||||
if (p->conf.logformat_sd_string != default_rfc5424_sd_log_format)
|
if (p->conf.logformat_sd_string != default_rfc5424_sd_log_format)
|
||||||
free(p->conf.logformat_sd_string);
|
free(p->conf.logformat_sd_string);
|
||||||
|
43
src/server.c
43
src/server.c
@ -1901,7 +1901,7 @@ static struct srv_kw_list srv_kws = { "ALL", { }, {
|
|||||||
{ "ws", srv_parse_ws, 1, 1, 1 }, /* websocket protocol */
|
{ "ws", srv_parse_ws, 1, 1, 1 }, /* websocket protocol */
|
||||||
{ "id", srv_parse_id, 1, 0, 1 }, /* set id# of server */
|
{ "id", srv_parse_id, 1, 0, 1 }, /* set id# of server */
|
||||||
{ "init-addr", srv_parse_init_addr, 1, 1, 0 }, /* */
|
{ "init-addr", srv_parse_init_addr, 1, 1, 0 }, /* */
|
||||||
{ "log-proto", srv_parse_log_proto, 1, 1, 0 }, /* Set the protocol for event messages, only relevant in a ring section */
|
{ "log-proto", srv_parse_log_proto, 1, 1, 0 }, /* Set the protocol for event messages, only relevant in a log or ring section */
|
||||||
{ "maxconn", srv_parse_maxconn, 1, 1, 1 }, /* Set the max number of concurrent connection */
|
{ "maxconn", srv_parse_maxconn, 1, 1, 1 }, /* Set the max number of concurrent connection */
|
||||||
{ "maxqueue", srv_parse_maxqueue, 1, 1, 1 }, /* Set the max number of connection to put in queue */
|
{ "maxqueue", srv_parse_maxqueue, 1, 1, 1 }, /* Set the max number of connection to put in queue */
|
||||||
{ "max-reuse", srv_parse_max_reuse, 1, 1, 0 }, /* Set the max number of requests on a connection, -1 means unlimited */
|
{ "max-reuse", srv_parse_max_reuse, 1, 1, 0 }, /* Set the max number of requests on a connection, -1 means unlimited */
|
||||||
@ -2495,6 +2495,7 @@ void srv_free_params(struct server *srv)
|
|||||||
free(srv->resolvers_id);
|
free(srv->resolvers_id);
|
||||||
free(srv->addr_node.key);
|
free(srv->addr_node.key);
|
||||||
free(srv->lb_nodes);
|
free(srv->lb_nodes);
|
||||||
|
free(srv->log_target);
|
||||||
|
|
||||||
if (xprt_get(XPRT_SSL) && xprt_get(XPRT_SSL)->destroy_srv)
|
if (xprt_get(XPRT_SSL) && xprt_get(XPRT_SSL)->destroy_srv)
|
||||||
xprt_get(XPRT_SSL)->destroy_srv(srv);
|
xprt_get(XPRT_SSL)->destroy_srv(srv);
|
||||||
@ -2701,6 +2702,7 @@ static int _srv_parse_init(struct server **srv, char **args, int *cur_arg,
|
|||||||
const char *err = NULL;
|
const char *err = NULL;
|
||||||
int err_code = 0;
|
int err_code = 0;
|
||||||
char *fqdn = NULL;
|
char *fqdn = NULL;
|
||||||
|
struct protocol *proto;
|
||||||
int tmpl_range_low = 0, tmpl_range_high = 0;
|
int tmpl_range_low = 0, tmpl_range_high = 0;
|
||||||
char *errmsg = NULL;
|
char *errmsg = NULL;
|
||||||
|
|
||||||
@ -2806,11 +2808,12 @@ static int _srv_parse_init(struct server **srv, char **args, int *cur_arg,
|
|||||||
if (!(parse_flags & SRV_PARSE_PARSE_ADDR))
|
if (!(parse_flags & SRV_PARSE_PARSE_ADDR))
|
||||||
goto skip_addr;
|
goto skip_addr;
|
||||||
|
|
||||||
sk = str2sa_range(args[*cur_arg], &port, &port1, &port2, NULL, NULL,
|
sk = str2sa_range(args[*cur_arg], &port, &port1, &port2, NULL, &proto,
|
||||||
&errmsg, NULL, &fqdn,
|
&errmsg, NULL, &fqdn,
|
||||||
|
(parse_flags & SRV_PARSE_IN_LOG_BE ? PA_O_DGRAM : PA_O_CONNECT) |
|
||||||
(parse_flags & SRV_PARSE_INITIAL_RESOLVE ? PA_O_RESOLVE : 0) | PA_O_PORT_OK |
|
(parse_flags & SRV_PARSE_INITIAL_RESOLVE ? PA_O_RESOLVE : 0) | PA_O_PORT_OK |
|
||||||
(parse_flags & SRV_PARSE_IN_PEER_SECTION ? PA_O_PORT_MAND : PA_O_PORT_OFS) |
|
(parse_flags & SRV_PARSE_IN_PEER_SECTION ? PA_O_PORT_MAND : PA_O_PORT_OFS) |
|
||||||
PA_O_STREAM | PA_O_XPRT | PA_O_CONNECT);
|
PA_O_STREAM | PA_O_XPRT);
|
||||||
if (!sk) {
|
if (!sk) {
|
||||||
ha_alert("%s\n", errmsg);
|
ha_alert("%s\n", errmsg);
|
||||||
err_code |= ERR_ALERT | ERR_FATAL;
|
err_code |= ERR_ALERT | ERR_FATAL;
|
||||||
@ -2843,6 +2846,35 @@ static int _srv_parse_init(struct server **srv, char **args, int *cur_arg,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((parse_flags & SRV_PARSE_IN_LOG_BE) && proto) {
|
||||||
|
/* mode log enabled, and found proto:
|
||||||
|
* pre-resolve related log target from known infos
|
||||||
|
*/
|
||||||
|
newsrv->log_target = malloc(sizeof(*newsrv->log_target));
|
||||||
|
if (!newsrv->log_target) {
|
||||||
|
ha_alert("memory error when allocating log server\n");
|
||||||
|
err_code |= ERR_ALERT | ERR_FATAL;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
newsrv->log_target->addr = &newsrv->addr;
|
||||||
|
switch (proto->xprt_type) {
|
||||||
|
case PROTO_TYPE_DGRAM:
|
||||||
|
newsrv->log_target->type = LOG_TARGET_DGRAM;
|
||||||
|
break;
|
||||||
|
case PROTO_TYPE_STREAM:
|
||||||
|
/* for now BUFFER type only supports TCP server to it's almost
|
||||||
|
* explicit. This will require ring buffer creation during log
|
||||||
|
* postresolving step.
|
||||||
|
*/
|
||||||
|
newsrv->log_target->type = LOG_TARGET_BUFFER;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
ha_alert("log server type not supported for log backend server.\n");
|
||||||
|
err_code |= ERR_ALERT | ERR_FATAL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
newsrv->addr = *sk;
|
newsrv->addr = *sk;
|
||||||
newsrv->svc_port = port;
|
newsrv->svc_port = port;
|
||||||
/*
|
/*
|
||||||
@ -4863,6 +4895,11 @@ static int cli_parse_add_server(char **args, char *payload, struct appctx *appct
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (be->mode == PR_MODE_SYSLOG) {
|
||||||
|
cli_err(appctx," Dynamic servers cannot be used with log backends.");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
/* At this point, some operations might not be thread-safe anymore. This
|
/* At this point, some operations might not be thread-safe anymore. This
|
||||||
* might be the case for parsing handlers which were designed to run
|
* might be the case for parsing handlers which were designed to run
|
||||||
* only at the starting stage on single-thread mode.
|
* only at the starting stage on single-thread mode.
|
||||||
|
Loading…
Reference in New Issue
Block a user