]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MEDIUM: streams: support looking up stkctr in the session
authorWilly Tarreau <w@1wt.eu>
Sat, 4 Apr 2015 14:29:12 +0000 (16:29 +0200)
committerWilly Tarreau <w@1wt.eu>
Mon, 6 Apr 2015 09:37:31 +0000 (11:37 +0200)
In order to support sessions tracking counters, we first ensure that there
is no overlap between streams' stkctr and sessions', and we allow an
automatic lookup into the session's counters when the stream doesn't
have a counter or when the stream doesn't exist during an access via
a sample fetch. The functions used to update the stream counters only
update them and not the session counters however.

include/proto/stream.h
src/stream.c

index cb166152386211edc7874a0912958fd3b1279fde..f8eba1298b8ebf7a4f26a8127fe8663962075ec1 100644 (file)
@@ -178,41 +178,50 @@ static void inline stream_inc_http_req_ctr(struct stream *s)
        int i;
 
        for (i = 0; i < MAX_SESS_STKCTR; i++) {
-               if (!stkctr_entry(&s->stkctr[i]))
-                       continue;
+               struct stkctr *stkctr = &s->stkctr[i];
+
+               if (!stkctr_entry(stkctr)) {
+                       stkctr = &s->sess->stkctr[i];
+                       if (!stkctr_entry(stkctr))
+                               continue;
+               }
 
-               ptr = stktable_data_ptr(s->stkctr[i].table, stkctr_entry(&s->stkctr[i]), STKTABLE_DT_HTTP_REQ_CNT);
+               ptr = stktable_data_ptr(stkctr->table, stkctr_entry(stkctr), STKTABLE_DT_HTTP_REQ_CNT);
                if (ptr)
                        stktable_data_cast(ptr, http_req_cnt)++;
 
-               ptr = stktable_data_ptr(s->stkctr[i].table, stkctr_entry(&s->stkctr[i]), STKTABLE_DT_HTTP_REQ_RATE);
+               ptr = stktable_data_ptr(stkctr->table, stkctr_entry(stkctr), STKTABLE_DT_HTTP_REQ_RATE);
                if (ptr)
                        update_freq_ctr_period(&stktable_data_cast(ptr, http_req_rate),
-                                              s->stkctr[i].table->data_arg[STKTABLE_DT_HTTP_REQ_RATE].u, 1);
+                                              stkctr->table->data_arg[STKTABLE_DT_HTTP_REQ_RATE].u, 1);
        }
 }
 
-/* Increase the number of cumulated HTTP requests in the backend's tracked counters */
+/* Increase the number of cumulated HTTP requests in the backend's tracked
+ * counters. We don't look up the session since it cannot happen in the bakcend.
+ */
 static void inline stream_inc_be_http_req_ctr(struct stream *s)
 {
        void *ptr;
        int i;
 
        for (i = 0; i < MAX_SESS_STKCTR; i++) {
-               if (!stkctr_entry(&s->stkctr[i]))
+               struct stkctr *stkctr = &s->stkctr[i];
+
+               if (!stkctr_entry(stkctr))
                        continue;
 
                if (!(stkctr_flags(&s->stkctr[i]) & STKCTR_TRACK_BACKEND))
                        continue;
 
-               ptr = stktable_data_ptr(s->stkctr[i].table, stkctr_entry(&s->stkctr[i]), STKTABLE_DT_HTTP_REQ_CNT);
+               ptr = stktable_data_ptr(stkctr->table, stkctr_entry(stkctr), STKTABLE_DT_HTTP_REQ_CNT);
                if (ptr)
                        stktable_data_cast(ptr, http_req_cnt)++;
 
-               ptr = stktable_data_ptr(s->stkctr[i].table, stkctr_entry(&s->stkctr[i]), STKTABLE_DT_HTTP_REQ_RATE);
+               ptr = stktable_data_ptr(stkctr->table, stkctr_entry(stkctr), STKTABLE_DT_HTTP_REQ_RATE);
                if (ptr)
                        update_freq_ctr_period(&stktable_data_cast(ptr, http_req_rate),
-                                              s->stkctr[i].table->data_arg[STKTABLE_DT_HTTP_REQ_RATE].u, 1);
+                                              stkctr->table->data_arg[STKTABLE_DT_HTTP_REQ_RATE].u, 1);
        }
 }
 
@@ -228,17 +237,22 @@ static void inline stream_inc_http_err_ctr(struct stream *s)
        int i;
 
        for (i = 0; i < MAX_SESS_STKCTR; i++) {
-               if (!stkctr_entry(&s->stkctr[i]))
-                       continue;
+               struct stkctr *stkctr = &s->stkctr[i];
+
+               if (!stkctr_entry(stkctr)) {
+                       stkctr = &s->sess->stkctr[i];
+                       if (!stkctr_entry(stkctr))
+                               continue;
+               }
 
-               ptr = stktable_data_ptr(s->stkctr[i].table, stkctr_entry(&s->stkctr[i]), STKTABLE_DT_HTTP_ERR_CNT);
+               ptr = stktable_data_ptr(stkctr->table, stkctr_entry(stkctr), STKTABLE_DT_HTTP_ERR_CNT);
                if (ptr)
                        stktable_data_cast(ptr, http_err_cnt)++;
 
-               ptr = stktable_data_ptr(s->stkctr[i].table, stkctr_entry(&s->stkctr[i]), STKTABLE_DT_HTTP_ERR_RATE);
+               ptr = stktable_data_ptr(stkctr->table, stkctr_entry(stkctr), STKTABLE_DT_HTTP_ERR_RATE);
                if (ptr)
                        update_freq_ctr_period(&stktable_data_cast(ptr, http_err_rate),
-                                              s->stkctr[i].table->data_arg[STKTABLE_DT_HTTP_ERR_RATE].u, 1);
+                                              stkctr->table->data_arg[STKTABLE_DT_HTTP_ERR_RATE].u, 1);
        }
 }
 
index e21a2a5834e47d89b8327f4e8beeccccb810e3b1..7f2f27a4459387e94870e8734b85f2eb56184dca 100644 (file)
@@ -454,18 +454,19 @@ int stream_complete(struct stream *s)
 
        for (i = 0; i < MAX_SESS_STKCTR; i++) {
                void *ptr;
+               struct stkctr *stkctr = &sess->stkctr[i];
 
-               if (!stkctr_entry(&s->stkctr[i]))
+               if (!stkctr_entry(stkctr))
                        continue;
 
-               ptr = stktable_data_ptr(s->stkctr[i].table, stkctr_entry(&s->stkctr[i]), STKTABLE_DT_SESS_CNT);
+               ptr = stktable_data_ptr(stkctr->table, stkctr_entry(stkctr), STKTABLE_DT_SESS_CNT);
                if (ptr)
                        stktable_data_cast(ptr, sess_cnt)++;
 
-               ptr = stktable_data_ptr(s->stkctr[i].table, stkctr_entry(&s->stkctr[i]), STKTABLE_DT_SESS_RATE);
+               ptr = stktable_data_ptr(stkctr->table, stkctr_entry(stkctr), STKTABLE_DT_SESS_RATE);
                if (ptr)
                        update_freq_ctr_period(&stktable_data_cast(ptr, sess_rate),
-                                              s->stkctr[i].table->data_arg[STKTABLE_DT_SESS_RATE].u, 1);
+                                              stkctr->table->data_arg[STKTABLE_DT_SESS_RATE].u, 1);
        }
 
        /* this part should be common with other protocols */
@@ -807,21 +808,22 @@ void stream_process_counters(struct stream *s)
                        sess->listener->counters->bytes_in += bytes;
 
                for (i = 0; i < MAX_SESS_STKCTR; i++) {
-                       if (!stkctr_entry(&s->stkctr[i]))
-                               continue;
+                       struct stkctr *stkctr = &s->stkctr[i];
+
+                       if (!stkctr_entry(stkctr)) {
+                               stkctr = &sess->stkctr[i];
+                               if (!stkctr_entry(stkctr))
+                                       continue;
+                       }
 
-                       ptr = stktable_data_ptr(s->stkctr[i].table,
-                                               stkctr_entry(&s->stkctr[i]),
-                                               STKTABLE_DT_BYTES_IN_CNT);
+                       ptr = stktable_data_ptr(stkctr->table, stkctr_entry(stkctr), STKTABLE_DT_BYTES_IN_CNT);
                        if (ptr)
                                stktable_data_cast(ptr, bytes_in_cnt) += bytes;
 
-                       ptr = stktable_data_ptr(s->stkctr[i].table,
-                                               stkctr_entry(&s->stkctr[i]),
-                                               STKTABLE_DT_BYTES_IN_RATE);
+                       ptr = stktable_data_ptr(stkctr->table, stkctr_entry(stkctr), STKTABLE_DT_BYTES_IN_RATE);
                        if (ptr)
                                update_freq_ctr_period(&stktable_data_cast(ptr, bytes_in_rate),
-                                                      s->stkctr[i].table->data_arg[STKTABLE_DT_BYTES_IN_RATE].u, bytes);
+                                                      stkctr->table->data_arg[STKTABLE_DT_BYTES_IN_RATE].u, bytes);
                }
        }
 
@@ -839,21 +841,22 @@ void stream_process_counters(struct stream *s)
                        sess->listener->counters->bytes_out += bytes;
 
                for (i = 0; i < MAX_SESS_STKCTR; i++) {
-                       if (!stkctr_entry(&s->stkctr[i]))
-                               continue;
+                       struct stkctr *stkctr = &s->stkctr[i];
+
+                       if (!stkctr_entry(stkctr)) {
+                               stkctr = &sess->stkctr[i];
+                               if (!stkctr_entry(stkctr))
+                                       continue;
+                       }
 
-                       ptr = stktable_data_ptr(s->stkctr[i].table,
-                                               stkctr_entry(&s->stkctr[i]),
-                                               STKTABLE_DT_BYTES_OUT_CNT);
+                       ptr = stktable_data_ptr(stkctr->table, stkctr_entry(stkctr), STKTABLE_DT_BYTES_OUT_CNT);
                        if (ptr)
                                stktable_data_cast(ptr, bytes_out_cnt) += bytes;
 
-                       ptr = stktable_data_ptr(s->stkctr[i].table,
-                                               stkctr_entry(&s->stkctr[i]),
-                                               STKTABLE_DT_BYTES_OUT_RATE);
+                       ptr = stktable_data_ptr(stkctr->table, stkctr_entry(stkctr), STKTABLE_DT_BYTES_OUT_RATE);
                        if (ptr)
                                update_freq_ctr_period(&stktable_data_cast(ptr, bytes_out_rate),
-                                                      s->stkctr[i].table->data_arg[STKTABLE_DT_BYTES_OUT_RATE].u, bytes);
+                                                      stkctr->table->data_arg[STKTABLE_DT_BYTES_OUT_RATE].u, bytes);
                }
        }
 }
@@ -2890,12 +2893,14 @@ void stream_shutdown(struct stream *stream, int why)
  * passed. When present, the currently tracked key is then looked up
  * in the specified table instead of the current table. The purpose is
  * to be able to convery multiple values per key (eg: have gpc0 from
- * multiple tables).
+ * multiple tables). <strm> is allowed to be NULL, in which case only
+ * the session will be consulted.
  */
 struct stkctr *
 smp_fetch_sc_stkctr(struct session *sess, struct stream *strm, const struct arg *args, const char *kw)
 {
        static struct stkctr stkctr;
+       struct stkctr *stkptr;
        struct stksess *stksess;
        unsigned int num = kw[2] - '0';
        int arg = 0;
@@ -2924,9 +2929,18 @@ smp_fetch_sc_stkctr(struct session *sess, struct stream *strm, const struct arg
 
        /* Here, <num> contains the counter number from 0 to 9 for
         * the sc[0-9]_ form, or even higher using sc_(num) if needed.
-        * args[arg] is the first optional argument.
+        * args[arg] is the first optional argument. We first lookup the
+        * ctr form the stream, then from the session if it was not there.
         */
-       stksess = stkctr_entry(&strm->stkctr[num]);
+
+       stkptr = &strm->stkctr[num];
+       if (!strm || !stkctr_entry(stkptr)) {
+               stkptr = &sess->stkctr[num];
+               if (!stkctr_entry(stkptr))
+                       return NULL;
+       }
+
+       stksess = stkctr_entry(stkptr);
        if (!stksess)
                return NULL;
 
@@ -2936,7 +2950,7 @@ smp_fetch_sc_stkctr(struct session *sess, struct stream *strm, const struct arg
                stkctr_set_entry(&stkctr, stktable_lookup(stkctr.table, stksess));
                return &stkctr;
        }
-       return &strm->stkctr[num];
+       return stkptr;
 }
 
 /* set return a boolean indicating if the requested stream counter is