]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: log: Enable the log sampling and load-balancing feature.
authorFrédéric Lécaille <flecaille@haproxy.com>
Thu, 25 Apr 2019 05:42:09 +0000 (07:42 +0200)
committerWilly Tarreau <w@1wt.eu>
Tue, 30 Apr 2019 07:25:09 +0000 (09:25 +0200)
This patch implements the sampling and load-balancing of log servers configured
with "sample" new keyword implemented by this commit:
    'MINOR: log: Add "sample" new keyword to "log" lines'.
As the list of ranges used to sample the log to balance is ordered, we only
have to maintain ->curr_idx member of smp_info struct which is the index of
the sample and check if it belongs or not to the current range to decide if we
must send it to the log server or not.

include/common/hathreads.h
include/proto/log.h
include/types/log.h
src/log.c

index 7cbb3495b8b8170b4998bee285d16d54925849d0..308bcb1f120e2f84b73ddb7ba3f36706a296cfa1 100644 (file)
@@ -443,6 +443,7 @@ enum lock_label {
        START_LOCK,
        TLSKEYS_REF_LOCK,
        AUTH_LOCK,
+       LOGSRV_LOCK,
        OTHER_LOCK,
        LOCK_LABELS
 };
@@ -559,6 +560,7 @@ static inline const char *lock_label(enum lock_label label)
        case START_LOCK:           return "START";
        case TLSKEYS_REF_LOCK:     return "TLSKEYS_REF";
        case AUTH_LOCK:            return "AUTH";
+       case LOGSRV_LOCK:          return "LOGSRV";
        case OTHER_LOCK:           return "OTHER";
        case LOCK_LABELS:          break; /* keep compiler happy */
        };
index b05ab3efc40f9bea1dfd83123f8c602cd752c434..7b056c5feff91ca957da96111a702a8b566bb714 100644 (file)
@@ -54,6 +54,17 @@ extern THREAD_LOCAL char *logline;
 extern THREAD_LOCAL char *logline_rfc5424;
 
 
+/*
+ * Test if <idx> index numbered from 0 is in <rg> range with low and high
+ * limits of indexes numbered from 1.
+ */
+static inline int in_smp_log_range(struct smp_log_range *rg, unsigned int idx)
+{
+       if (idx + 1 <= rg->high && idx + 1 >= rg->low)
+               return 1;
+       return 0;
+}
+
 /* Initialize/Deinitialize log buffers used for syslog messages */
 int init_log_buffers();
 void deinit_log_buffers();
index 9f9912aa20a2d34b92d8707b800ba70df23d0514..affcd92d29b302818dca9b0b99259095a0ebae31 100644 (file)
@@ -26,6 +26,7 @@
 #include <sys/un.h>
 #include <netinet/in.h>
 #include <common/config.h>
+#include <common/hathreads.h>
 #include <common/mini-clist.h>
 
 #define NB_LOG_FACILITIES       24
@@ -202,6 +203,7 @@ struct logsrv {
        int minlvl;
        int maxlen;
        struct logsrv *ref;
+       __decl_hathreads(HA_SPINLOCK_T lock);
 };
 
 #endif /* _TYPES_LOG_H */
index cffd8f1483dd994f31fd0be03f5ed0a85499066c..49de5709f402b13bdc659c4e5af2f311caaf3e45 100644 (file)
--- a/src/log.c
+++ b/src/log.c
@@ -946,6 +946,7 @@ int parse_logsrv(char **args, struct list *logsrvs, int do_del, char **err)
 
                cur_arg += 2;
        }
+       HA_SPIN_INIT(&logsrv->lock);
        /* parse the facility */
        logsrv->facility = get_log_facility(args[cur_arg]);
        if (logsrv->facility < 0) {
@@ -1722,12 +1723,32 @@ void __send_log(struct proxy *p, int level, char *message, size_t size, char *sd
        /* Send log messages to syslog server. */
        nblogger = 0;
        list_for_each_entry(logsrv, logsrvs, list) {
+               static THREAD_LOCAL int in_range = 1;
+
                /* we can filter the level of the messages that are sent to each logger */
                if (level > logsrv->level)
                        continue;
 
-               __do_send_log(logsrv, ++nblogger, pid.area, pid.data, level,
-                             message, size, sd, sd_size, tag->area, tag->data);
+               if (logsrv->lb.smp_rgs) {
+                       struct smp_log_range *curr_rg;
+
+                       HA_SPIN_LOCK(LOGSRV_LOCK, &logsrv->lock);
+                       curr_rg = &logsrv->lb.smp_rgs[logsrv->lb.curr_rg];
+                       in_range = in_smp_log_range(curr_rg, logsrv->lb.curr_idx);
+                       if (in_range) {
+                               /* Let's consume this range. */
+                               curr_rg->curr_idx = (curr_rg->curr_idx + 1) % curr_rg->sz;
+                               if (!curr_rg->curr_idx) {
+                                       /* If consumed, let's select the next range. */
+                                       logsrv->lb.curr_rg = (logsrv->lb.curr_rg + 1) % logsrv->lb.smp_rgs_sz;
+                               }
+                       }
+                       logsrv->lb.curr_idx = (logsrv->lb.curr_idx + 1) % logsrv->lb.smp_sz;
+                       HA_SPIN_UNLOCK(LOGSRV_LOCK, &logsrv->lock);
+               }
+               if (in_range)
+                       __do_send_log(logsrv, ++nblogger, pid.area, pid.data, level,
+                                     message, size, sd, sd_size, tag->area, tag->data);
        }
 }