]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MEDIUM: logs: remove the hostname, tag and pid part from the logheader
authorDragan Dosen <ddosen@haproxy.com>
Sat, 19 Sep 2015 20:35:44 +0000 (22:35 +0200)
committerWilly Tarreau <w@1wt.eu>
Mon, 28 Sep 2015 12:01:27 +0000 (14:01 +0200)
At the moment we have to call snprintf() for every log line just to
rebuild a constant. Thanks to sendmsg(), we send the message in 3 parts:
time-based header, proxy-specific hostname+log-tag+pid, session-specific
message.

include/proto/log.h
include/types/log.h
include/types/proxy.h
src/cfgparse.c
src/haproxy.c
src/log.c

index 14dfc5bcd40c143a27053e1a9c252ab7b2d80b90..e8b57d867f3c66fee7a369aa1121da621c586081 100644 (file)
@@ -138,6 +138,11 @@ char *lf_ip(char *dst, struct sockaddr *sockaddr, size_t size, struct logformat_
  */
 char *lf_port(char *dst, struct sockaddr *sockaddr, size_t size, struct logformat_node *node);
 
+/*
+ * Write hostname, log_tag and pid to the log string
+ */
+char *lf_host_tag_pid(char *dst, const char *hostname, const char *log_tag, int pid, size_t size);
+
 
 #endif /* _PROTO_LOG_H */
 
index 6707aa6b5640c727e207cc0c58c96be748183b4c..0214ae675aaf31f8957ca92e19e183de6cb08092 100644 (file)
@@ -30,7 +30,7 @@
 
 #define NB_LOG_FACILITIES       24
 #define NB_LOG_LEVELS           8
-#define NB_MSG_IOVEC_ELEMENTS   2
+#define NB_MSG_IOVEC_ELEMENTS   3
 #define SYSLOG_PORT             514
 #define UNIQUEID_LEN            128
 
index 170e6f7145282a4aac4e21ddbe318f8fc4691f16..1400126deac7fdd0f0dbd2309fb1ed1b040d0a07 100644 (file)
@@ -346,6 +346,7 @@ struct proxy {
        struct list logsrvs;
        struct list logformat;                  /* log_format linked list */
        char *log_tag;                          /* override default syslog tag */
+       struct chunk log_htp;                   /* a syslog header part that contains hostname, log_tag and pid */
        char *header_unique_id;                 /* unique-id header */
        struct list format_unique_id;           /* unique-id format */
        int to_log;                             /* things to be logged (LW_*) */
index 39ee3598808b63d231ecd02baeb95f14c01188c8..fdbb462f6e63e4ead44f2d80a3715758a3ce0ffe 100644 (file)
@@ -7818,6 +7818,27 @@ int check_config_validity()
                }
 out_uri_auth_compat:
 
+               /* write a syslog header string that contains hostname, log_tag and pid */
+               curproxy->log_htp.str = lf_host_tag_pid(logheader,
+                                                       global.log_send_hostname ? global.log_send_hostname : "",
+                                                       curproxy->log_tag ? curproxy->log_tag : global.log_tag, pid,
+                                                       global.max_syslog_len);
+
+               if ((curproxy->log_htp.str == NULL) ||
+                   (curproxy->log_htp.len = curproxy->log_htp.str - logheader) >= global.max_syslog_len) {
+                       Alert("Proxy '%s': cannot write a syslog header string that contains "
+                             "hostname, log_tag and pid.\n",
+                             curproxy->id);
+                       cfgerr++;
+               }
+               else {
+                       curproxy->log_htp.str = (char *)malloc(curproxy->log_htp.len);
+                       memcpy(curproxy->log_htp.str, logheader, curproxy->log_htp.len);
+                       curproxy->log_htp.size = 0;
+               }
+
+               logheader[0] = 0;
+
                /* compile the log format */
                if (!(curproxy->cap & PR_CAP_FE)) {
                        if (curproxy->conf.logformat_string != default_http_log_format &&
index f6ba96b381b75011248dc8def1fed03d0d758e16..1edb823d763f2c05d227b760d494c9069cd394dc 100644 (file)
@@ -1328,6 +1328,7 @@ void deinit(void)
                        LIST_DEL(&log->list);
                        free(log);
                }
+               chunk_destroy(&p->log_htp);
 
                list_for_each_entry_safe(lf, lfb, &p->logformat, list) {
                        LIST_DEL(&lf->list);
index 3724dd47e22653a34f946f56ccdf48bf2a47fbcd..ad25174d224fff2528d98eb6c9f0834d8f721440 100644 (file)
--- a/src/log.c
+++ b/src/log.c
@@ -152,8 +152,7 @@ char default_tcp_log_format[] = "%ci:%cp [%t] %ft %b/%s %Tw/%Tc/%Tt %B %ts %ac/%
 char *log_format = NULL;
 
 /* This is a global syslog header, common to all outgoing messages. It
- * begins with the syslog tag and the date that are updated by
- * update_log_hdr().
+ * begins with time-based part and is updated by update_log_hdr().
  */
 char *logheader = NULL;
 
@@ -740,14 +739,26 @@ char *lf_port(char *dst, struct sockaddr *sockaddr, size_t size, struct logforma
        return ret;
 }
 
+char *lf_host_tag_pid(char *dst, const char *hostname, const char *log_tag, int pid, size_t size)
+{
+       char *ret = dst;
+       int iret;
+
+       iret = snprintf(dst, size, "%s%s[%d]: ", hostname, log_tag, pid);
+       if (iret < 0 || iret > size)
+               return NULL;
+       ret += iret;
+
+       return ret;
+}
+
 /* Re-generate the syslog header at the beginning of logheader once a second and
  * return the pointer to the first character after the header.
  */
-static char *update_log_hdr(const char *log_tag)
+char *update_log_hdr()
 {
        static long tvsec;
        static char *dataptr = NULL; /* backup of last end of header, NULL first time */
-       int tag_len;
 
        if (unlikely(date.tv_sec != tvsec || dataptr == NULL)) {
                /* this string is rebuild only once a second */
@@ -758,10 +769,9 @@ static char *update_log_hdr(const char *log_tag)
                get_localtime(tvsec, &tm);
 
                hdr_len = snprintf(logheader, global.max_syslog_len,
-                                  "<<<<>%s %2d %02d:%02d:%02d %s",
+                                  "<<<<>%s %2d %02d:%02d:%02d ",
                                   monthname[tm.tm_mon],
-                                  tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec,
-                                  global.log_send_hostname ? global.log_send_hostname : "");
+                                  tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec);
                /* WARNING: depending upon implementations, snprintf may return
                 * either -1 or the number of bytes that would be needed to store
                 * the total message. In both cases, we must adjust it.
@@ -774,11 +784,7 @@ static char *update_log_hdr(const char *log_tag)
 
        dataptr[0] = 0; // ensure we get rid of any previous attempt
 
-       tag_len = snprintf(dataptr, logheader + global.max_syslog_len - dataptr, "%s[%d]: ", log_tag, pid);
-       if (tag_len < 0 || tag_len > logheader + global.max_syslog_len - dataptr)
-               tag_len = logheader + global.max_syslog_len - dataptr;
-
-       return dataptr + tag_len;
+       return dataptr;
 }
 
 /*
@@ -821,7 +827,6 @@ void __send_log(struct proxy *p, int level, char *message, size_t size)
        struct list *logsrvs = NULL;
        struct logsrv *tmp = NULL;
        int nblogger;
-       char *log_tag = global.log_tag;
        char *log_ptr;
        char *hdr_ptr;
        size_t hdr_size;
@@ -836,15 +841,12 @@ void __send_log(struct proxy *p, int level, char *message, size_t size)
                if (!LIST_ISEMPTY(&p->logsrvs)) {
                        logsrvs = &p->logsrvs;
                }
-               if (p->log_tag) {
-                       log_tag = p->log_tag;
-               }
        }
 
        if (!logsrvs)
                return;
 
-       hdr_ptr = update_log_hdr(log_tag);
+       hdr_ptr = update_log_hdr();
        hdr_size = hdr_ptr - logheader;
 
        /* Send log messages to syslog server. */
@@ -854,7 +856,9 @@ void __send_log(struct proxy *p, int level, char *message, size_t size)
                int *plogfd = logsrv->addr.ss_family == AF_UNIX ?
                        &logfdunix : &logfdinet;
                int sent;
+               int maxlen;
                int hdr_max = 0;
+               int htp_max = 0;
                int max = 1;
                char backup;
 
@@ -904,7 +908,15 @@ void __send_log(struct proxy *p, int level, char *message, size_t size)
                        goto send;
                }
 
-               max = MIN(size, logsrv->maxlen - hdr_max);
+               maxlen = logsrv->maxlen - hdr_max;
+               htp_max = p->log_htp.len;
+
+               if (unlikely(htp_max >= maxlen)) {
+                       htp_max = maxlen - 1;
+                       goto send;
+               }
+
+               max = MIN(size, maxlen - htp_max);
 
                log_ptr += max - 1;
 
@@ -918,8 +930,10 @@ send:
 
                iovec[0].iov_base = hdr_ptr;
                iovec[0].iov_len = hdr_max;
-               iovec[1].iov_base = dataptr;
-               iovec[1].iov_len = max;
+               iovec[1].iov_base = p->log_htp.str;
+               iovec[1].iov_len = htp_max;
+               iovec[2].iov_base = dataptr;
+               iovec[2].iov_len = max;
 
                msghdr.msg_name = (struct sockaddr *)&logsrv->addr;
                msghdr.msg_namelen = get_addr_len(&logsrv->addr);