mirror of
https://git.haproxy.org/git/haproxy.git/
synced 2025-08-07 07:37:02 +02:00
MEDIUM: log-format: backend source address %Bi %Bp
%Bi return the backend source IP %Bp return the backend source port Add a function pointer in logformat_type to do additional configuration during the log-format variable parsing.
This commit is contained in:
parent
bddd4fd93b
commit
b7ff6a3a36
@ -8790,6 +8790,8 @@ Please refer to the table below for currently defined variables :
|
||||
| | %B | bytes_read | numeric |
|
||||
| | %Ci | client_ip | string |
|
||||
| | %Cp | client_port | numeric |
|
||||
| | %Bi | backend_source_ip | string |
|
||||
| | %Bp | backend_source_port | numeric |
|
||||
| | %Tc | Tc | numeric |
|
||||
| * | %Tq | Tq | numeric |
|
||||
| * | %Tr | Tr | numeric |
|
||||
|
@ -44,6 +44,8 @@ enum {
|
||||
LOG_GLOBAL,
|
||||
LOG_CLIENTIP,
|
||||
LOG_CLIENTPORT,
|
||||
LOG_SOURCEPORT,
|
||||
LOG_SOURCEIP,
|
||||
LOG_DATE,
|
||||
LOG_DATEGMT,
|
||||
LOG_MS,
|
||||
|
@ -138,7 +138,9 @@ enum {
|
||||
#define PR_O2_NODELAY 0x00020000 /* fully interactive mode, never delay outgoing data */
|
||||
#define PR_O2_USE_PXHDR 0x00040000 /* use Proxy-Connection for proxy requests */
|
||||
#define PR_O2_CHK_SNDST 0x00080000 /* send the state of each server along with HTTP health checks */
|
||||
/* unused: 0x00100000 */
|
||||
|
||||
#define PR_O2_SRC_ADDR 0x00100000 /* get the source ip and port for logs */
|
||||
|
||||
#define PR_O2_FAKE_KA 0x00200000 /* pretend we do keep-alive with server eventhough we close */
|
||||
/* unused: 0x00400000 */
|
||||
#define PR_O2_EXP_NONE 0x00000000 /* http-check : no expect rule */
|
||||
|
@ -84,6 +84,7 @@
|
||||
#define SN_IGNORE_PRST 0x00080000 /* ignore persistence */
|
||||
#define SN_BE_TRACK_SC1 0x00100000 /* backend tracks stick-counter 1 */
|
||||
#define SN_BE_TRACK_SC2 0x00200000 /* backend tracks stick-counter 2 */
|
||||
#define SN_BCK_ADDR_SET 0x00400000 /* set if the backend address has been filled */
|
||||
|
||||
/* Termination sequence tracing.
|
||||
*
|
||||
|
@ -72,6 +72,7 @@ enum {
|
||||
SI_FL_DONT_WAKE = 0x0020, /* resync in progress, don't wake up */
|
||||
SI_FL_INDEP_STR = 0x0040, /* independant streams = don't update rex on write */
|
||||
SI_FL_NOLINGER = 0x0080, /* may close without lingering. One-shot. */
|
||||
SI_FL_SRC_ADDR = 0x1000, /* get the source ip/port with getsockname */
|
||||
};
|
||||
|
||||
/* target types */
|
||||
|
@ -985,6 +985,10 @@ int connect_server(struct session *s)
|
||||
|
||||
assign_tproxy_address(s);
|
||||
|
||||
/* flag for logging source ip/port */
|
||||
if (s->fe->options2 & PR_O2_SRC_ADDR)
|
||||
s->req->cons->flags |= SI_FL_SRC_ADDR;
|
||||
|
||||
err = s->req->cons->connect(s->req->cons);
|
||||
|
||||
if (err != SN_ERR_NONE)
|
||||
|
108
src/log.c
108
src/log.c
@ -57,42 +57,47 @@ struct logformat_type {
|
||||
char *name;
|
||||
int type;
|
||||
int mode;
|
||||
int (*config_callback)(struct logformat_node *node, struct proxy *curproxy);
|
||||
};
|
||||
|
||||
int prepare_addrsource(struct logformat_node *node, struct proxy *curproxy);
|
||||
|
||||
/* log_format variable names */
|
||||
static const struct logformat_type logformat_keywords[] = {
|
||||
{ "o", LOG_GLOBAL, PR_MODE_TCP }, /* global option */
|
||||
{ "Ci", LOG_CLIENTIP, PR_MODE_TCP }, /* client ip */
|
||||
{ "Cp", LOG_CLIENTPORT, PR_MODE_TCP }, /* client port */
|
||||
{ "t", LOG_DATE, PR_MODE_TCP }, /* date */
|
||||
{ "T", LOG_DATEGMT, PR_MODE_TCP }, /* date GMT */
|
||||
{ "ms", LOG_MS, PR_MODE_TCP }, /* accept date millisecond */
|
||||
{ "f", LOG_FRONTEND, PR_MODE_TCP }, /* frontend */
|
||||
{ "b", LOG_BACKEND, PR_MODE_TCP }, /* backend */
|
||||
{ "s", LOG_SERVER, PR_MODE_TCP }, /* server */
|
||||
{ "B", LOG_BYTES, PR_MODE_TCP }, /* bytes read */
|
||||
{ "Tq", LOG_TQ, PR_MODE_HTTP }, /* Tq */
|
||||
{ "Tw", LOG_TW, PR_MODE_TCP }, /* Tw */
|
||||
{ "Tc", LOG_TC, PR_MODE_TCP }, /* Tc */
|
||||
{ "Tr", LOG_TR, PR_MODE_HTTP }, /* Tr */
|
||||
{ "Tt", LOG_TT, PR_MODE_TCP }, /* Tt */
|
||||
{ "st", LOG_STATUS, PR_MODE_HTTP }, /* status code */
|
||||
{ "cc", LOG_CCLIENT, PR_MODE_HTTP }, /* client cookie */
|
||||
{ "cs", LOG_CSERVER, PR_MODE_HTTP }, /* server cookie */
|
||||
{ "ts", LOG_TERMSTATE, PR_MODE_TCP },/* terminaison state */
|
||||
{ "ac", LOG_ACTCONN, PR_MODE_TCP }, /* actconn */
|
||||
{ "fc", LOG_FECONN, PR_MODE_TCP }, /* feconn */
|
||||
{ "bc", LOG_BECONN, PR_MODE_TCP }, /* beconn */
|
||||
{ "sc", LOG_SRVCONN, PR_MODE_TCP }, /* srv_conn */
|
||||
{ "rc", LOG_RETRIES, PR_MODE_TCP }, /* retries */
|
||||
{ "sq", LOG_SRVQUEUE, PR_MODE_TCP }, /* srv_queue */
|
||||
{ "bq", LOG_BCKQUEUE, PR_MODE_TCP }, /* backend_queue */
|
||||
{ "hr", LOG_HDRREQUEST, PR_MODE_HTTP }, /* header request */
|
||||
{ "hs", LOG_HDRRESPONS, PR_MODE_HTTP }, /* header response */
|
||||
{ "hrl", LOG_HDRREQUESTLIST, PR_MODE_HTTP }, /* header request list */
|
||||
{ "hsl", LOG_HDRRESPONSLIST, PR_MODE_HTTP }, /* header response list */
|
||||
{ "r", LOG_REQ, PR_MODE_HTTP }, /* request */
|
||||
{ 0, 0 }
|
||||
{ "o", LOG_GLOBAL, PR_MODE_TCP, NULL }, /* global option */
|
||||
{ "Ci", LOG_CLIENTIP, PR_MODE_TCP, NULL }, /* client ip */
|
||||
{ "Cp", LOG_CLIENTPORT, PR_MODE_TCP, NULL }, /* client port */
|
||||
{ "Bp", LOG_SOURCEPORT, PR_MODE_TCP, prepare_addrsource }, /* backend source port */
|
||||
{ "Bi", LOG_SOURCEIP, PR_MODE_TCP, prepare_addrsource }, /* backend source ip */
|
||||
{ "t", LOG_DATE, PR_MODE_TCP, NULL }, /* date */
|
||||
{ "T", LOG_DATEGMT, PR_MODE_TCP, NULL }, /* date GMT */
|
||||
{ "ms", LOG_MS, PR_MODE_TCP, NULL }, /* accept date millisecond */
|
||||
{ "f", LOG_FRONTEND, PR_MODE_TCP, NULL }, /* frontend */
|
||||
{ "b", LOG_BACKEND, PR_MODE_TCP, NULL }, /* backend */
|
||||
{ "s", LOG_SERVER, PR_MODE_TCP, NULL }, /* server */
|
||||
{ "B", LOG_BYTES, PR_MODE_TCP, NULL }, /* bytes read */
|
||||
{ "Tq", LOG_TQ, PR_MODE_HTTP, NULL }, /* Tq */
|
||||
{ "Tw", LOG_TW, PR_MODE_TCP, NULL }, /* Tw */
|
||||
{ "Tc", LOG_TC, PR_MODE_TCP, NULL }, /* Tc */
|
||||
{ "Tr", LOG_TR, PR_MODE_HTTP, NULL }, /* Tr */
|
||||
{ "Tt", LOG_TT, PR_MODE_TCP, NULL }, /* Tt */
|
||||
{ "st", LOG_STATUS, PR_MODE_HTTP, NULL }, /* status code */
|
||||
{ "cc", LOG_CCLIENT, PR_MODE_HTTP, NULL }, /* client cookie */
|
||||
{ "cs", LOG_CSERVER, PR_MODE_HTTP, NULL }, /* server cookie */
|
||||
{ "ts", LOG_TERMSTATE, PR_MODE_TCP, NULL },/* terminaison state */
|
||||
{ "ac", LOG_ACTCONN, PR_MODE_TCP, NULL }, /* actconn */
|
||||
{ "fc", LOG_FECONN, PR_MODE_TCP, NULL }, /* feconn */
|
||||
{ "bc", LOG_BECONN, PR_MODE_TCP, NULL }, /* beconn */
|
||||
{ "sc", LOG_SRVCONN, PR_MODE_TCP, NULL }, /* srv_conn */
|
||||
{ "rc", LOG_RETRIES, PR_MODE_TCP, NULL }, /* retries */
|
||||
{ "sq", LOG_SRVQUEUE, PR_MODE_TCP, NULL }, /* srv_queue */
|
||||
{ "bq", LOG_BCKQUEUE, PR_MODE_TCP, NULL }, /* backend_queue */
|
||||
{ "hr", LOG_HDRREQUEST, PR_MODE_HTTP, NULL }, /* header request */
|
||||
{ "hs", LOG_HDRRESPONS, PR_MODE_HTTP, NULL }, /* header response */
|
||||
{ "hrl", LOG_HDRREQUESTLIST, PR_MODE_HTTP, NULL }, /* header request list */
|
||||
{ "hsl", LOG_HDRRESPONSLIST, PR_MODE_HTTP, NULL }, /* header response list */
|
||||
{ "r", LOG_REQ, PR_MODE_HTTP, NULL }, /* request */
|
||||
{ 0, 0, 0, NULL }
|
||||
};
|
||||
|
||||
char default_http_log_format[] = "%Ci:%Cp [%t] %f %b/%s %Tq/%Tw/%Tc/%Tr/%Tt %st %B %cc %cs %ts %ac/%fc/%bc/%sc/%rc %sq/%bq %hr %hs %{+Q}r"; // default format
|
||||
@ -112,6 +117,17 @@ struct logformat_var_args var_args_list[] = {
|
||||
{ 0, 0 }
|
||||
};
|
||||
|
||||
/*
|
||||
* callback used to configure addr source retrieval
|
||||
*/
|
||||
int prepare_addrsource(struct logformat_node *node, struct proxy *curproxy)
|
||||
{
|
||||
curproxy->options2 |= PR_O2_SRC_ADDR;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Parse args in a logformat_var
|
||||
*/
|
||||
@ -201,6 +217,11 @@ int parse_logformat_var(char *str, size_t len, struct proxy *curproxy)
|
||||
logformat_options = node->options;
|
||||
free(node);
|
||||
} else {
|
||||
if (logformat_keywords[j].config_callback != NULL) {
|
||||
if (logformat_keywords[j].config_callback(node, curproxy) != 0) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
LIST_ADDQ(&curproxy->logformat, &node->list);
|
||||
}
|
||||
return 0;
|
||||
@ -678,6 +699,7 @@ const char sess_set_cookie[8] = "NPDIRU67"; /* No set-cookie, Set-cookie found a
|
||||
void sess_log(struct session *s)
|
||||
{
|
||||
char pn[INET6_ADDRSTRLEN];
|
||||
char sn[INET6_ADDRSTRLEN];
|
||||
struct proxy *fe = s->fe;
|
||||
struct proxy *be = s->be;
|
||||
struct proxy *prx_log;
|
||||
@ -707,6 +729,11 @@ void sess_log(struct session *s)
|
||||
if (addr_to_str(&s->req->prod->addr.from, pn, sizeof(pn)) == AF_UNIX)
|
||||
snprintf(pn, sizeof(pn), "unix:%d", s->listener->luid);
|
||||
|
||||
if (be->options2 & PR_O2_SRC_ADDR) {
|
||||
if (addr_to_str(&s->req->cons->addr.from, sn, sizeof(sn)) == AF_UNIX)
|
||||
snprintf(sn, sizeof(sn), "unix:%d", s->listener->luid);
|
||||
}
|
||||
|
||||
/* FIXME: let's limit ourselves to frontend logging for now. */
|
||||
tolog = fe->to_log;
|
||||
|
||||
@ -774,6 +801,23 @@ void sess_log(struct session *s)
|
||||
last_isspace = 0;
|
||||
break;
|
||||
|
||||
case LOG_SOURCEIP: // Bi
|
||||
src = (s->req->cons->addr.from.ss_family == AF_UNIX) ? "unix" : sn;
|
||||
tmplog = logformat_write_string(tmplog, src, MAX_SYSLOG_LEN - (tmplog - logline), tmp);
|
||||
|
||||
if (!tmplog)
|
||||
goto out;
|
||||
last_isspace = 0;
|
||||
break;
|
||||
|
||||
case LOG_SOURCEPORT: // %Bp
|
||||
tmplog = ltoa_o((s->req->cons->addr.from.ss_family == AF_UNIX) ? s->listener->luid : get_host_port(&s->req->cons->addr.from),
|
||||
tmplog, MAX_SYSLOG_LEN - (tmplog - logline));
|
||||
if (!tmplog)
|
||||
goto out;
|
||||
last_isspace = 0;
|
||||
break;
|
||||
|
||||
case LOG_DATE: // %t
|
||||
get_localtime(s->logs.accept_date.tv_sec, &tm);
|
||||
tmplog = date2str_log(tmplog, &tm, &(s->logs.accept_date), MAX_SYSLOG_LEN - (tmplog - logline));
|
||||
|
@ -437,6 +437,14 @@ int tcp_connect_server(struct stream_interface *si)
|
||||
}
|
||||
}
|
||||
|
||||
/* needs src ip/port for logging */
|
||||
if (si->flags & SI_FL_SRC_ADDR) {
|
||||
socklen_t addrlen = sizeof(si->addr.to);
|
||||
if (getsockname(fd, (struct sockaddr *)&si->addr.from, &addrlen) == -1) {
|
||||
Warning("Cannot get source address for logging.\n");
|
||||
}
|
||||
}
|
||||
|
||||
fdtab[fd].owner = si;
|
||||
fdtab[fd].state = FD_STCONN; /* connection in progress */
|
||||
fdtab[fd].flags = FD_FL_TCP | FD_FL_TCP_NODELAY;
|
||||
|
Loading…
Reference in New Issue
Block a user