MEDIUM: log: make http_sess_log use log_format
http_sess_log now use the logformat linked list to make the log
string, snprintf is not used for speed issue.
CLF mode also uses logformat.
NOTE: as of now, empty fields in CLF now are "" not "-" anymore.
diff --git a/include/proto/log.h b/include/proto/log.h
index 2cf114b..34d3813 100644
--- a/include/proto/log.h
+++ b/include/proto/log.h
@@ -113,6 +113,14 @@
*/
int get_log_facility(const char *fac);
+/*
+ * Write a string in the log string
+ * Take cares of mandatory and quote options
+ *
+ * Return the adress of the \0 character, or NULL on error
+ */
+char *logformat_write_string(char *dst, char *src, size_t size, struct logformat_node *node);
+
#endif /* _PROTO_LOG_H */
/*
diff --git a/src/log.c b/src/log.c
index 8f639e0..17dc281 100644
--- a/src/log.c
+++ b/src/log.c
@@ -430,6 +430,60 @@
return facility;
}
+/*
+ * Write a string in the log string
+ * Take cares of mandatory and quote options
+ *
+ * Return the adress of the \0 character, or NULL on error
+ */
+char *logformat_write_string(char *dst, char *src, size_t size, struct logformat_node *node)
+{
+ char *orig = dst;
+
+ if (src == NULL || *src == '\0') {
+ if (node->options & LOG_OPT_QUOTE) {
+ if (size > 2) {
+ *(dst++) = '"';
+ *(dst++) = '"';
+ *dst = '\0';
+ node->options |= LOG_OPT_WRITTEN;
+ } else {
+ dst = NULL;
+ return dst;
+ }
+ } else {
+ if (size > 1) {
+ *(dst++) = '-';
+ *dst = '\0';
+ node->options |= LOG_OPT_WRITTEN;
+ } else { // error no space available
+ dst = NULL;
+ return dst;
+ }
+ }
+ } else {
+ if (node->options & LOG_OPT_QUOTE) {
+ if (size-- > 1 ) {
+ *(dst++) = '"';
+ } else {
+ dst = NULL;
+ return NULL;
+ }
+ dst += strlcpy2(dst, src, size);
+ size -= orig - dst + 1;
+ if (size > 1) {
+ *(dst++) = '"';
+ *dst = '\0';
+ } else {
+ dst = NULL;
+ }
+ } else {
+ dst += strlcpy2(dst, src, size);
+ }
+ }
+ return dst;
+}
+
/* generate the syslog header once a second */
char *hdr_log(char *dst)
{
diff --git a/src/proto_http.c b/src/proto_http.c
index 52efdf8..dd40f94 100644
--- a/src/proto_http.c
+++ b/src/proto_http.c
@@ -851,7 +851,19 @@
struct pool_head *pool2_requri;
struct pool_head *pool2_capture;
-void http_sess_clflog(struct session *s)
+#define LOGCHAR(x) do { \
+ if (MAX_SYSLOG_LEN - (tmplog - logline) > 1) { \
+ *(tmplog++) = (x); \
+ } else { \
+ goto out; \
+ } \
+ } while(0)
+
+/*
+ * send a log for the session when we have enough info about it.
+ * Will not log if the frontend has no log defined.
+ */
+void http_sess_log(struct session *s)
{
char pn[INET6_ADDRSTRLEN];
struct proxy *fe = s->fe;
@@ -859,85 +871,33 @@
struct proxy *prx_log;
struct http_txn *txn = &s->txn;
int tolog, level, err;
- char *uri, *h;
+ char *uri;
const char *svid;
struct tm tm;
- static char tmpline[MAX_SYSLOG_LEN];
- int hdr;
- size_t w;
int t_request;
+ int hdr;
+ int last_isspace = 1;
+ static char logline[MAX_SYSLOG_LEN] = { 0 };
+ static char *tmplog;
+ struct logformat_node *tmp;
- prx_log = fe;
+ /* if we don't want to log normal traffic, return now */
err = (s->flags & (SN_ERR_MASK | SN_REDISP)) ||
(s->req->cons->conn_retries != be->conn_retries) ||
txn->status >= 500;
+ if (!err && (fe->options2 & PR_O2_NOLOGNORM))
+ return;
+
+ if (LIST_ISEMPTY(&fe->logsrvs))
+ return;
+ prx_log = fe;
if (addr_to_str(&s->req->prod->addr.from, pn, sizeof(pn)) == AF_UNIX)
snprintf(pn, sizeof(pn), "unix:%d", s->listener->luid);
- get_gmtime(s->logs.accept_date.tv_sec, &tm);
-
/* FIXME: let's limit ourselves to frontend logging for now. */
tolog = fe->to_log;
- h = tmpline;
-
- w = snprintf(h, sizeof(tmpline),
- "%s - - [%02d/%s/%04d:%02d:%02d:%02d +0000]",
- pn,
- tm.tm_mday, monthname[tm.tm_mon], tm.tm_year+1900,
- tm.tm_hour, tm.tm_min, tm.tm_sec);
- if (w < 0 || w >= sizeof(tmpline) - (h - tmpline))
- goto trunc;
- h += w;
-
- if (h >= tmpline + sizeof(tmpline) - 4)
- goto trunc;
-
- *(h++) = ' ';
- *(h++) = '\"';
- uri = txn->uri ? txn->uri : "<BADREQ>";
- h = encode_string(h, tmpline + sizeof(tmpline) - 1,
- '#', url_encode_map, uri);
- *(h++) = '\"';
-
- w = snprintf(h, sizeof(tmpline) - (h - tmpline), " %d %lld", txn->status, s->logs.bytes_out);
- if (w < 0 || w >= sizeof(tmpline) - (h - tmpline))
- goto trunc;
- h += w;
-
- if (h >= tmpline + sizeof(tmpline) - 9)
- goto trunc;
- memcpy(h, " \"-\" \"-\"", 8);
- h += 8;
-
- w = snprintf(h, sizeof(tmpline) - (h - tmpline),
- " %d %03d",
- s->req->prod->addr.from.ss_family == AF_UNIX ? s->listener->luid :
- get_host_port(&s->req->prod->addr.from),
- (int)s->logs.accept_date.tv_usec/1000);
- if (w < 0 || w >= sizeof(tmpline) - (h - tmpline))
- goto trunc;
- h += w;
-
- w = strlen(fe->id);
- if (h >= tmpline + sizeof(tmpline) - 4 - w)
- goto trunc;
- *(h++) = ' ';
- *(h++) = '\"';
- memcpy(h, fe->id, w);
- h += w;
- *(h++) = '\"';
-
- w = strlen(be->id);
- if (h >= tmpline + sizeof(tmpline) - 4 - w)
- goto trunc;
- *(h++) = ' ';
- *(h++) = '\"';
- memcpy(h, be->id, w);
- h += w;
- *(h++) = '\"';
-
if (!(tolog & LW_SVID))
svid = "-";
else switch (s->target.type) {
@@ -952,262 +912,339 @@
break;
}
- w = strlen(svid);
- if (h >= tmpline + sizeof(tmpline) - 4 - w)
- goto trunc;
- *(h++) = ' ';
- *(h++) = '\"';
- memcpy(h, svid, w);
- h += w;
- *(h++) = '\"';
-
t_request = -1;
if (tv_isge(&s->logs.tv_request, &s->logs.tv_accept))
t_request = tv_ms_elapsed(&s->logs.tv_accept, &s->logs.tv_request);
- w = snprintf(h, sizeof(tmpline) - (h - tmpline),
- " %d %ld %ld %ld %ld",
- t_request,
- (s->logs.t_queue >= 0) ? s->logs.t_queue - t_request : -1,
- (s->logs.t_connect >= 0) ? s->logs.t_connect - s->logs.t_queue : -1,
- (s->logs.t_data >= 0) ? s->logs.t_data - s->logs.t_connect : -1,
- s->logs.t_close);
- if (w < 0 || w >= sizeof(tmpline) - (h - tmpline))
- goto trunc;
- h += w;
- if (h >= tmpline + sizeof(tmpline) - 8)
- goto trunc;
- *(h++) = ' ';
- *(h++) = '\"';
- *(h++) = sess_term_cond[(s->flags & SN_ERR_MASK) >> SN_ERR_SHIFT];
- *(h++) = sess_fin_state[(s->flags & SN_FINST_MASK) >> SN_FINST_SHIFT];
- *(h++) = (be->options & PR_O_COOK_ANY) ? sess_cookie[(txn->flags & TX_CK_MASK) >> TX_CK_SHIFT] : '-',
- *(h++) = (be->options & PR_O_COOK_ANY) ? sess_set_cookie[(txn->flags & TX_SCK_MASK) >> TX_SCK_SHIFT] : '-';
- *(h++) = '\"';
+ level = LOG_INFO;
+ if (err && (fe->options2 & PR_O2_LOGERRORS))
+ level = LOG_ERR;
- w = snprintf(h, sizeof(tmpline) - (h - tmpline),
- " %d %d %d %d %d %ld %ld",
- actconn, fe->feconn, be->beconn, target_srv(&s->target) ? target_srv(&s->target)->cur_sess : 0,
- (s->req->cons->conn_retries > 0) ? (be->conn_retries - s->req->cons->conn_retries) : be->conn_retries,
- s->logs.srv_queue_size, s->logs.prx_queue_size);
+ /* fill logbuffer */
- if (w < 0 || w >= sizeof(tmpline) - (h - tmpline))
- goto trunc;
- h += w;
+ tmplog = logline;
+ tmplog = hdr_log(tmplog);
- if (txn->cli_cookie) {
- w = strlen(txn->cli_cookie);
- if (h >= tmpline + sizeof(tmpline) - 4 - w)
- goto trunc;
- *(h++) = ' ';
- *(h++) = '\"';
- memcpy(h, txn->cli_cookie, w);
- h += w;
- *(h++) = '\"';
- } else {
- if (h >= tmpline + sizeof(tmpline) - 5)
- goto trunc;
- memcpy(h, " \"-\"", 4);
- h += 4;
- }
+ list_for_each_entry(tmp, &fe->logformat, list) {
+ char *src = NULL;
+ switch (tmp->type) {
- if (txn->srv_cookie) {
- w = strlen(txn->srv_cookie);
- if (h >= tmpline + sizeof(tmpline) - 4 - w)
- goto trunc;
- *(h++) = ' ';
- *(h++) = '\"';
- memcpy(h, txn->srv_cookie, w);
- h += w;
- *(h++) = '\"';
- } else {
- if (h >= tmpline + sizeof(tmpline) - 5)
- goto trunc;
- memcpy(h, " \"-\"", 4);
- h += 4;
- }
+ case LOG_SEPARATOR:
+ if (!last_isspace) {
+ LOGCHAR(' ');
+ last_isspace = 1;
+ *tmplog = '\0';
+ }
+ break;
- if ((fe->to_log & LW_REQHDR) && txn->req.cap) {
- for (hdr = 0; hdr < fe->nb_req_cap; hdr++) {
- if (h >= sizeof (tmpline) + tmpline - 4)
- goto trunc;
- if (txn->req.cap[hdr] != NULL) {
- *(h++) = ' ';
- *(h++) = '\"';
- h = encode_string(h, tmpline + sizeof(tmpline) - 2,
- '#', hdr_encode_map, txn->req.cap[hdr]);
- *(h++) = '\"';
- } else {
- memcpy(h, " \"-\"", 4);
- h += 4;
- }
- }
- }
+ case LOG_TEXT: // text
+ src = tmp->arg;
+ tmplog += strlcpy2(tmplog, src, MAX_SYSLOG_LEN - (tmplog - logline));
+ if (!tmplog)
+ goto out;
+ last_isspace = 0;
+ break;
- if ((fe->to_log & LW_RSPHDR) && txn->rsp.cap) {
- for (hdr = 0; hdr < fe->nb_rsp_cap; hdr++) {
- if (h >= sizeof (tmpline) + tmpline - 4)
- goto trunc;
- if (txn->rsp.cap[hdr] != NULL) {
- *(h++) = ' ';
- *(h++) = '\"';
- h = encode_string(h, tmpline + sizeof(tmpline) - 2,
- '#', hdr_encode_map, txn->rsp.cap[hdr]);
- *(h++) = '\"';
- } else {
- memcpy(h, " \"-\"", 4);
- h += 4;
- }
- }
- }
+ case LOG_CLIENTIP: // %Ci
+ src = (s->req->prod->addr.from.ss_family == AF_UNIX) ? "unix" : pn;
+ tmplog = logformat_write_string(tmplog, src, MAX_SYSLOG_LEN - (tmplog - logline), tmp);
-trunc:
- *h = '\0';
+ if (!tmplog)
+ goto out;
+ last_isspace = 0;
+ break;
- level = LOG_INFO;
- if (err && (fe->options2 & PR_O2_LOGERRORS))
- level = LOG_ERR;
+ case LOG_CLIENTPORT: // %Cp
+ tmplog = ltoa_o((s->req->prod->addr.from.ss_family == AF_UNIX) ? s->listener->luid : get_host_port(&s->req->prod->addr.from),
+ tmplog, MAX_SYSLOG_LEN - (tmplog - logline));
+ if (!tmplog)
+ goto out;
+ last_isspace = 0;
+ break;
- send_log(prx_log, level, "%s\n", tmpline);
+ 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));
+ if (!tmplog)
+ goto out;
+ last_isspace = 0;
+ break;
- s->logs.logwait = 0;
-}
+ case LOG_DATEGMT: // %T
+ get_gmtime(s->logs.accept_date.tv_sec, &tm);
+ tmplog = gmt2str_log(tmplog, &tm, MAX_SYSLOG_LEN - (tmplog - logline));
+ if (!tmplog)
+ goto out;
+ last_isspace = 0;
+ break;
-/*
- * send a log for the session when we have enough info about it.
- * Will not log if the frontend has no log defined.
- */
-void http_sess_log(struct session *s)
-{
- char pn[INET6_ADDRSTRLEN];
- struct proxy *fe = s->fe;
- struct proxy *be = s->be;
- struct proxy *prx_log;
- struct http_txn *txn = &s->txn;
- int tolog, level, err;
- char *uri, *h;
- const char *svid;
- struct tm tm;
- static char tmpline[MAX_SYSLOG_LEN];
- int t_request;
- int hdr;
+ case LOG_MS: // %ms
+ if ((MAX_SYSLOG_LEN - (tmplog - logline)) < 4) {
+ tmplog = NULL;
+ goto out;
+ }
+ tmplog = utoa_pad((unsigned int)s->logs.accept_date.tv_usec/1000,
+ tmplog, 4);
+ last_isspace = 0;
- /* if we don't want to log normal traffic, return now */
- err = (s->flags & (SN_ERR_MASK | SN_REDISP)) ||
- (s->req->cons->conn_retries != be->conn_retries) ||
- txn->status >= 500;
- if (!err && (fe->options2 & PR_O2_NOLOGNORM))
- return;
+ break;
- if (LIST_ISEMPTY(&fe->logsrvs))
- return;
- prx_log = fe;
+ case LOG_FRONTEND: // %f
+ src = fe->id;
+ tmplog = logformat_write_string(tmplog, src, MAX_SYSLOG_LEN - (tmplog - logline), tmp);
+ if (!tmplog)
+ goto out;
+ last_isspace = 0 ;
+ break;
- if (prx_log->options2 & PR_O2_CLFLOG)
- return http_sess_clflog(s);
+ case LOG_BACKEND: // %b
+ src = be->id;
+ tmplog = logformat_write_string(tmplog, src, MAX_SYSLOG_LEN - (tmplog - logline), tmp);
+ if (!tmplog)
+ goto out;
+ last_isspace = 0 ;
+ break;
- if (addr_to_str(&s->req->prod->addr.from, pn, sizeof(pn)) == AF_UNIX)
- snprintf(pn, sizeof(pn), "unix:%d", s->listener->luid);
+ case LOG_SERVER: // %s
+ src = (char *)svid;
+ tmplog = logformat_write_string(tmplog, src, MAX_SYSLOG_LEN - (tmplog - logline), tmp);
+ if (!tmplog)
+ goto out;
+ last_isspace = 0;
+ break;
- get_localtime(s->logs.accept_date.tv_sec, &tm);
+ case LOG_TQ: // %Tq
+ tmplog = ltoa_o(t_request, tmplog, MAX_SYSLOG_LEN - (tmplog - logline));
+ if (!tmplog)
+ goto out;
+ last_isspace = 0;
+ break;
- /* FIXME: let's limit ourselves to frontend logging for now. */
- tolog = fe->to_log;
+ case LOG_TW: // %Tw
+ tmplog = ltoa_o((s->logs.t_queue >= 0) ? s->logs.t_queue - t_request : -1, tmplog, MAX_SYSLOG_LEN - (tmplog - logline));
+ if (!tmplog)
+ goto out;
+ last_isspace = 0;
+ break;
- h = tmpline;
- if (fe->to_log & LW_REQHDR &&
- txn->req.cap &&
- (h < tmpline + sizeof(tmpline) - 10)) {
- *(h++) = ' ';
- *(h++) = '{';
- for (hdr = 0; hdr < fe->nb_req_cap; hdr++) {
- if (hdr)
- *(h++) = '|';
- if (txn->req.cap[hdr] != NULL)
- h = encode_string(h, tmpline + sizeof(tmpline) - 7,
- '#', hdr_encode_map, txn->req.cap[hdr]);
- }
- *(h++) = '}';
- }
+ case LOG_TC: // %Tc
+ tmplog = ltoa_o((s->logs.t_connect >= 0) ? s->logs.t_connect - s->logs.t_queue : -1, tmplog, MAX_SYSLOG_LEN - (tmplog - logline));
+ if (!tmplog)
+ goto out;
+ last_isspace = 0;
+ break;
- if (fe->to_log & LW_RSPHDR &&
- txn->rsp.cap &&
- (h < tmpline + sizeof(tmpline) - 7)) {
- *(h++) = ' ';
- *(h++) = '{';
- for (hdr = 0; hdr < fe->nb_rsp_cap; hdr++) {
- if (hdr)
- *(h++) = '|';
- if (txn->rsp.cap[hdr] != NULL)
- h = encode_string(h, tmpline + sizeof(tmpline) - 4,
- '#', hdr_encode_map, txn->rsp.cap[hdr]);
- }
- *(h++) = '}';
- }
+ case LOG_TR: // %Tr
+ tmplog = ltoa_o((s->logs.t_data >= 0) ? s->logs.t_data - s->logs.t_connect : -1, tmplog, MAX_SYSLOG_LEN - (tmplog - logline));
+ if (!tmplog)
+ goto out;
+ last_isspace = 0;
+ break;
- if (h < tmpline + sizeof(tmpline) - 4) {
- *(h++) = ' ';
- *(h++) = '"';
- uri = txn->uri ? txn->uri : "<BADREQ>";
- h = encode_string(h, tmpline + sizeof(tmpline) - 1,
- '#', url_encode_map, uri);
- *(h++) = '"';
- }
- *h = '\0';
+ case LOG_TT: // %Tt
+ if (!(tolog & LW_BYTES))
+ *(tmplog++) = '+';
+ tmplog = ltoa_o(s->logs.t_close, tmplog, MAX_SYSLOG_LEN - (tmplog - logline));
+ if (!tmplog)
+ goto out;
+ last_isspace = 0;
+ break;
- if (!(tolog & LW_SVID))
- svid = "-";
- else switch (s->target.type) {
- case TARG_TYPE_SERVER:
- svid = s->target.ptr.s->id;
- break;
- case TARG_TYPE_APPLET:
- svid = s->target.ptr.a->name;
- break;
- default:
- svid = "<NOSRV>";
- break;
- }
+ case LOG_STATUS: // %st
+ tmplog = ultoa_o(txn->status, tmplog, MAX_SYSLOG_LEN - (tmplog - logline));
+ if (!tmplog)
+ goto out;
+ last_isspace = 0;
+ break;
- t_request = -1;
- if (tv_isge(&s->logs.tv_request, &s->logs.tv_accept))
- t_request = tv_ms_elapsed(&s->logs.tv_accept, &s->logs.tv_request);
+ case LOG_BYTES: // %B
+ if (!(tolog & LW_BYTES))
+ *(tmplog++) = '+';
+ tmplog = lltoa(s->logs.bytes_out, tmplog, MAX_SYSLOG_LEN - (tmplog - logline));
+ if (!tmplog)
+ goto out;
+ last_isspace = 0;
+ break;
- level = LOG_INFO;
- if (err && (fe->options2 & PR_O2_LOGERRORS))
- level = LOG_ERR;
+ case LOG_CCLIENT: // %cc
+ src = txn->cli_cookie;
+ tmplog = logformat_write_string(tmplog, src, MAX_SYSLOG_LEN - (tmplog - logline), tmp);
+ last_isspace = 0;
+ break;
+
+ case LOG_CSERVER: // %cs
+ src = txn->srv_cookie;
+ tmplog = logformat_write_string(tmplog, src, MAX_SYSLOG_LEN - (tmplog - logline), tmp);
+ last_isspace = 0;
+ break;
+
+ case LOG_TERMSTATE: // %ts
+ if (MAX_SYSLOG_LEN - (tmplog - logline) < 5)
+ goto out;
+ *(tmplog++) = sess_term_cond[(s->flags & SN_ERR_MASK) >> SN_ERR_SHIFT];
+ *(tmplog++) = sess_fin_state[(s->flags & SN_FINST_MASK) >> SN_FINST_SHIFT];
+ *(tmplog++) = (be->options & PR_O_COOK_ANY) ? sess_cookie[(txn->flags & TX_CK_MASK) >> TX_CK_SHIFT] : '-';
+ *(tmplog++) = (be->options & PR_O_COOK_ANY) ? sess_set_cookie[(txn->flags & TX_SCK_MASK) >> TX_SCK_SHIFT] : '-';
+ *tmplog = '\0';
+ last_isspace = 0;
+ break;
+
+ case LOG_ACTCONN: // %ac
+ tmplog = ltoa_o(actconn, tmplog, MAX_SYSLOG_LEN - (tmplog - logline));
+ if (!tmplog)
+ goto out;
+ last_isspace = 0;
+ break;
+
+ case LOG_FECONN: // %fc
+ tmplog = ltoa_o(fe->feconn, tmplog, MAX_SYSLOG_LEN - (tmplog - logline));
+ if (!tmplog)
+ goto out;
+ last_isspace = 0;
+ break;
+
+ case LOG_BECONN: // %bc
+ tmplog = ltoa_o(be->beconn, tmplog, MAX_SYSLOG_LEN - (tmplog - logline));
+ if (!tmplog)
+ goto out;
+ last_isspace = 0;
+ break;
- send_log(prx_log, level,
- "%s:%d [%02d/%s/%04d:%02d:%02d:%02d.%03d]"
- " %s %s/%s %d/%ld/%ld/%ld/%s%ld %d %s%lld"
- " %s %s %c%c%c%c %d/%d/%d/%d/%s%u %ld/%ld%s\n",
- (s->req->prod->addr.from.ss_family == AF_UNIX) ? "unix" : pn,
- (s->req->prod->addr.from.ss_family == AF_UNIX) ? s->listener->luid :
- get_host_port(&s->req->prod->addr.from),
- tm.tm_mday, monthname[tm.tm_mon], tm.tm_year+1900,
- tm.tm_hour, tm.tm_min, tm.tm_sec, (int)s->logs.accept_date.tv_usec/1000,
- fe->id, be->id, svid,
- t_request,
- (s->logs.t_queue >= 0) ? s->logs.t_queue - t_request : -1,
- (s->logs.t_connect >= 0) ? s->logs.t_connect - s->logs.t_queue : -1,
- (s->logs.t_data >= 0) ? s->logs.t_data - s->logs.t_connect : -1,
- (tolog & LW_BYTES) ? "" : "+", s->logs.t_close,
- txn->status,
- (tolog & LW_BYTES) ? "" : "+", s->logs.bytes_out,
- txn->cli_cookie ? txn->cli_cookie : "-",
- txn->srv_cookie ? txn->srv_cookie : "-",
- sess_term_cond[(s->flags & SN_ERR_MASK) >> SN_ERR_SHIFT],
- sess_fin_state[(s->flags & SN_FINST_MASK) >> SN_FINST_SHIFT],
- (be->options & PR_O_COOK_ANY) ? sess_cookie[(txn->flags & TX_CK_MASK) >> TX_CK_SHIFT] : '-',
- (be->options & PR_O_COOK_ANY) ? sess_set_cookie[(txn->flags & TX_SCK_MASK) >> TX_SCK_SHIFT] : '-',
- actconn, fe->feconn, be->beconn, target_srv(&s->target) ? target_srv(&s->target)->cur_sess : 0,
- (s->flags & SN_REDISP)?"+":"",
- (s->req->cons->conn_retries>0)?(be->conn_retries - s->req->cons->conn_retries):be->conn_retries,
- s->logs.srv_queue_size, s->logs.prx_queue_size, tmpline);
+ case LOG_SRVCONN: // %sc
+ tmplog = ultoa_o(target_srv(&s->target) ? target_srv(&s->target)->cur_sess : 0, tmplog, MAX_SYSLOG_LEN - (tmplog - logline));
+ if (!tmplog)
+ goto out;
+ last_isspace = 0;
+ break;
+ case LOG_RETRIES: // %rq
+ if (s->flags & SN_REDISP)
+ *(tmplog++) = '+';
+ tmplog = ltoa_o((s->req->cons->conn_retries>0)?(be->conn_retries - s->req->cons->conn_retries):be->conn_retries, tmplog, MAX_SYSLOG_LEN - (tmplog - logline));
+ last_isspace = 0;
+ break;
+
+ case LOG_SRVQUEUE: // %sq
+ tmplog = ltoa_o(s->logs.srv_queue_size, tmplog, MAX_SYSLOG_LEN - (tmplog - logline));
+ if (!tmplog)
+ goto out;
+ last_isspace = 0;
+ break;
+
+ case LOG_BCKQUEUE: // %bq
+ tmplog = ltoa_o(s->logs.prx_queue_size, tmplog, MAX_SYSLOG_LEN - (tmplog - logline));
+ if (!tmplog)
+ goto out;
+ last_isspace = 0;
+ break;
+
+ case LOG_HDRREQUEST: // %hr
+ /* request header */
+ if (fe->to_log & LW_REQHDR && txn->req.cap) {
+ if (tmp->options & LOG_OPT_QUOTE)
+ LOGCHAR('"');
+ LOGCHAR('{');
+ for (hdr = 0; hdr < fe->nb_req_cap; hdr++) {
+ if (hdr)
+ LOGCHAR('|');
+ if (txn->req.cap[hdr] != NULL)
+ tmplog = encode_string(tmplog, logline + MAX_SYSLOG_LEN,
+ '#', hdr_encode_map, txn->req.cap[hdr]);
+ }
+ LOGCHAR('}');
+ last_isspace = 0;
+ }
+ *tmplog = '\0';
+ break;
+
+ case LOG_HDRREQUESTLIST: // %hrl
+ /* request header list */
+ if (fe->to_log & LW_REQHDR && txn->req.cap) {
+ for (hdr = 0; hdr < fe->nb_req_cap; hdr++) {
+ if (hdr > 0)
+ LOGCHAR(' ');
+ if (tmp->options & LOG_OPT_QUOTE)
+ LOGCHAR('"');
+ if (txn->req.cap[hdr] != NULL) {
+ tmplog = encode_string(tmplog, logline + MAX_SYSLOG_LEN,
+ '#', hdr_encode_map, txn->req.cap[hdr]);
+ } else if (!(tmp->options & LOG_OPT_QUOTE))
+ LOGCHAR('-');
+ if (tmp->options & LOG_OPT_QUOTE)
+ LOGCHAR('"');
+ *tmplog = '\0';
+ last_isspace = 0;
+ }
+ }
+ break;
+
+ case LOG_HDRRESPONS: // %hs
+ /* response header */
+ if (fe->to_log & LW_RSPHDR &&
+ txn->rsp.cap) {
+ if (tmp->options & LOG_OPT_QUOTE)
+ LOGCHAR('"');
+ LOGCHAR('{');
+ for (hdr = 0; hdr < fe->nb_rsp_cap; hdr++) {
+ if (hdr)
+ LOGCHAR('|');
+ if (txn->rsp.cap[hdr] != NULL)
+ tmplog = encode_string(tmplog, logline + MAX_SYSLOG_LEN,
+ '#', hdr_encode_map, txn->rsp.cap[hdr]);
+ }
+ LOGCHAR('}');
+ last_isspace = 0;
+ if (tmp->options & LOG_OPT_QUOTE)
+ LOGCHAR('"');
+ }
+ *tmplog = '\0';
+ break;
+
+ case LOG_HDRRESPONSLIST: // %hsl
+ /* response header list */
+ if (fe->to_log & LW_RSPHDR && txn->rsp.cap) {
+ for (hdr = 0; hdr < fe->nb_rsp_cap; hdr++) {
+ if (hdr > 0)
+ LOGCHAR(' ');
+ if (tmp->options & LOG_OPT_QUOTE)
+ LOGCHAR('"');
+ if (txn->rsp.cap[hdr] != NULL) {
+ tmplog = encode_string(tmplog, logline + MAX_SYSLOG_LEN,
+ '#', hdr_encode_map, txn->rsp.cap[hdr]);
+ } else if (!(tmp->options & LOG_OPT_QUOTE))
+ LOGCHAR('-');
+ if (tmp->options & LOG_OPT_QUOTE)
+ LOGCHAR('"');
+ *tmplog = '\0';
+ last_isspace = 0;
+ }
+ }
+ break;
+
+ case LOG_REQ: // %r
+ /* Request */
+ if (tmp->options & LOG_OPT_QUOTE)
+ LOGCHAR('"');
+ uri = txn->uri ? txn->uri : "<BADREQ>";
+ tmplog = encode_string(tmplog, logline + MAX_SYSLOG_LEN,
+ '#', url_encode_map, uri);
+ if (tmp->options & LOG_OPT_QUOTE)
+ LOGCHAR('"');
+ *tmplog = '\0';
+ last_isspace = 0;
+ break;
+ }
+ }
+
+out:
+
+ if (tmplog == NULL) // if previous error
+ tmplog = logline + MAX_SYSLOG_LEN - 1;
+
+ __send_log(prx_log, level, logline, tmplog - logline + 2);
s->logs.logwait = 0;
-}
+}
/*
* Capture headers from message starting at <som> according to header list