]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
REORG: log: split send_log function
authorWilliam Lallemand <wlallemand@exceliance.fr>
Mon, 6 Feb 2012 15:00:33 +0000 (16:00 +0100)
committerWilly Tarreau <w@1wt.eu>
Thu, 9 Feb 2012 14:54:43 +0000 (15:54 +0100)
send_log function is now splited in 3 functions
* hdr_log: generate the syslog header
* send_log: send a syslog message with a printf format string
* __send_log: send a syslog message

include/proto/log.h
src/log.c

index f2ecf0b909b72e40b62b94fd378fa787eed0c121..fabd40011c05922998edc52d7a5aa2cac4be9b47 100644 (file)
@@ -53,15 +53,24 @@ void Warning(const char *fmt, ...)
 void qfprintf(FILE *out, const char *fmt, ...)
        __attribute__ ((format(printf, 2, 3)));
 
+/* generate the syslog header one time per second */
+char *hdr_log(char *dst);
+
+/*
+ * This function adds a header to the message and sends the syslog message
+ * using a printf format string
+ */
+void send_log(struct proxy *p, int level, const char *format, ...)
+       __attribute__ ((format(printf, 3, 4)));
+
 /*
  * This function sends a syslog message to both log servers of a proxy,
  * or to global log servers if the proxy is NULL.
  * It also tries not to waste too much time computing the message header.
  * It doesn't care about errors nor does it report them.
  */
-void send_log(struct proxy *p, int level, const char *message, ...)
-       __attribute__ ((format(printf, 3, 4)));
 
+void __send_log(struct proxy *p, int level, char *message, size_t size);
 /*
  * send a log for the session when we have enough info about it
  */
index dd1b63f13caa1bc977dbb05004fc130f67d2c967..7c0e14873e0b6a5f7fd85c14925c79ccc616635b 100644 (file)
--- a/src/log.c
+++ b/src/log.c
@@ -137,33 +137,16 @@ int get_log_facility(const char *fac)
        facility = NB_LOG_FACILITIES - 1;
        while (facility >= 0 && strcmp(log_facilities[facility], fac))
                facility--;
-       
+
        return facility;
 }
 
-/*
- * This function sends a syslog message to both log servers of a proxy,
- * or to global log servers if the proxy is NULL.
- * It also tries not to waste too much time computing the message header.
- * It doesn't care about errors nor does it report them.
- */
-void send_log(struct proxy *p, int level, const char *message, ...)
+/* generate the syslog header once a second */
+char *hdr_log(char *dst)
 {
-       static int logfdunix = -1;      /* syslog to AF_UNIX socket */
-       static int logfdinet = -1;      /* syslog to AF_INET socket */
+       int hdr_len = 0;
        static long tvsec = -1; /* to force the string to be initialized */
-       va_list argp;
-       static char logmsg[MAX_SYSLOG_LEN];
        static char *dataptr = NULL;
-       int fac_level;
-       int hdr_len, data_len;
-       struct list *logsrvs = NULL;
-       struct logsrv *tmp = NULL;
-       int nblogger;
-       char *log_ptr;
-
-       if (level < 0 || message == NULL)
-               return;
 
        if (unlikely(date.tv_sec != tvsec || dataptr == NULL)) {
                /* this string is rebuild only once a second */
@@ -172,7 +155,7 @@ void send_log(struct proxy *p, int level, const char *message, ...)
                tvsec = date.tv_sec;
                get_localtime(tvsec, &tm);
 
-               hdr_len = snprintf(logmsg, sizeof(logmsg),
+               hdr_len = snprintf(dst, MAX_SYSLOG_LEN,
                                   "<<<<>%s %2d %02d:%02d:%02d %s%s[%d]: ",
                                   monthname[tm.tm_mon],
                                   tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec,
@@ -182,22 +165,57 @@ void send_log(struct proxy *p, int level, const char *message, ...)
                 * either -1 or the number of bytes that would be needed to store
                 * the total message. In both cases, we must adjust it.
                 */
-               if (hdr_len < 0 || hdr_len > sizeof(logmsg))
-                       hdr_len = sizeof(logmsg);
+               if (hdr_len < 0 || hdr_len > MAX_SYSLOG_LEN)
+                       hdr_len = MAX_SYSLOG_LEN;
 
-               dataptr = logmsg + hdr_len;
+               dataptr = dst + hdr_len;
        }
 
-       va_start(argp, message);
-       /*
-        * FIXME: we take a huge performance hit here. We might have to replace
-        * vsnprintf() for a hard-coded log writer.
-        */
-       data_len = vsnprintf(dataptr, logmsg + sizeof(logmsg) - dataptr, message, argp);
-       if (data_len < 0 || data_len > (logmsg + sizeof(logmsg) - dataptr))
-               data_len = logmsg + sizeof(logmsg) - dataptr;
+       return dataptr;
+}
+
+/*
+ * This function adds a header to the message and sends the syslog message
+ * using a printf format string
+ */
+void send_log(struct proxy *p, int level, const char *format, ...)
+{
+       va_list argp;
+       static char logmsg[MAX_SYSLOG_LEN];
+       static char *dataptr = NULL;
+       int  data_len = 0;
+
+       if (level < 0 || format == NULL)
+               return;
+
+       dataptr = hdr_log(logmsg); /* create header */
+       data_len = dataptr - logmsg;
+
+       va_start(argp, format);
+       data_len += vsnprintf(dataptr, MAX_SYSLOG_LEN, format, argp);
+       if (data_len < 0 || data_len > MAX_SYSLOG_LEN)
+               data_len =  MAX_SYSLOG_LEN;
        va_end(argp);
-       dataptr[data_len - 1] = '\n'; /* force a break on ultra-long lines */
+
+       __send_log(p, level, logmsg, data_len);
+}
+
+/*
+ * This function sends a syslog message.
+ * It doesn't care about errors nor does it report them.
+ */
+void __send_log(struct proxy *p, int level, char *message, size_t size)
+{
+       static int logfdunix = -1;      /* syslog to AF_UNIX socket */
+       static int logfdinet = -1;      /* syslog to AF_INET socket */
+       static char *dataptr = NULL;
+       int fac_level;
+       struct list *logsrvs = NULL;
+       struct logsrv *tmp = NULL;
+       int nblogger;
+       char *log_ptr;
+
+       dataptr = message;
 
        if (p == NULL) {
                if (!LIST_ISEMPTY(&global.logsrvs)) {
@@ -212,6 +230,8 @@ void send_log(struct proxy *p, int level, const char *message, ...)
        if (!logsrvs)
                return;
 
+       message[size - 1] = '\n';
+
        /* Lazily set up syslog sockets for protocol families of configured
         * syslog servers. */
        nblogger = 0;
@@ -263,16 +283,15 @@ void send_log(struct proxy *p, int level, const char *message, ...)
                 * and we change the pointer to the header accordingly.
                 */
                fac_level = (logsrv->facility << 3) + MAX(level, logsrv->minlvl);
-               log_ptr = logmsg + 3; /* last digit of the log level */
+               log_ptr = dataptr + 3; /* last digit of the log level */
                do {
                        *log_ptr = '0' + fac_level % 10;
                        fac_level /= 10;
                        log_ptr--;
-               } while (fac_level && log_ptr > logmsg);
+               } while (fac_level && log_ptr > dataptr);
                *log_ptr = '<';
-       
-               /* the total syslog message now starts at logptr, for dataptr+data_len-logptr */
-               sent = sendto(*plogfd, log_ptr, dataptr + data_len - log_ptr,
+
+               sent = sendto(*plogfd, log_ptr, size,
                              MSG_DONTWAIT | MSG_NOSIGNAL,
                              (struct sockaddr *)&logsrv->addr, get_addr_len(&logsrv->addr));
                if (sent < 0) {