]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
[MINOR] Collect & provide http response codes received from servers
authorKrzysztof Piotr Oledzki <ole@ans.pl>
Tue, 13 Oct 2009 19:14:09 +0000 (21:14 +0200)
committerWilly Tarreau <w@1wt.eu>
Wed, 14 Oct 2009 19:49:53 +0000 (21:49 +0200)
Additional data is provided on both html & csv stats:
 - html: when passing a mouse over Sessions -> Total (servers, backends)
 - cvs: by 6 additional fields (hrsp_1xx, hrsp_2xx, hrsp_3xx, hrsp_4xx, hrsp_5xx, hspr_other)

Patch inspired by:
 http://www.formilux.org/archives/haproxy/0910/2528.html
 http://www.formilux.org/archives/haproxy/0910/2529.html

doc/configuration.txt
include/types/counters.h
src/dumpstats.c
src/proto_http.c

index 2a34d225d22595f55a21fb6e3ba72fd43da61d67..0e6eff84ada2cbc8fdddd05d2f9ed8b2c322987b 100644 (file)
@@ -6741,6 +6741,12 @@ page. Both means provide a CSV format whose fields follow.
        L7STS  -> layer 7 response error, for example HTTP 5xx
  37. check_code: layer5-7 code, if available
  38. check_duration: time in ms took to finish last health check
+ 39. hrsp_1xx: http responces with 1xx code
+ 40. hrsp_2xx: http responces with 2xx code
+ 41. hrsp_3xx: http responces with 3xx code
+ 42. hrsp_4xx: http responces with 4xx code
+ 43. hrsp_5xx: http responces with 5xx code
+ 44. hrsp_other: http responces with other codes (protocol error)
 
 
 9.2. Unix Socket commands
index 6dfef2295852fd27a5526beb152bc04f3fb89e77..f551bf07aba73e3dfecf374fa3939bdbbc7bd5b7 100644 (file)
@@ -38,6 +38,12 @@ struct pxcounters {
        long long denied_req, denied_resp;      /* blocked requests/responses because of security concerns */
        long long failed_req;                   /* failed requests (eg: invalid or timeout) */
 
+       union {
+               struct {
+                       long long rsp[6];               /* http resonse codes */
+               } http;
+       } p;
+
        long long failed_conns, failed_resp;    /* failed connect() and responses */
        long long retries, redispatches;        /* retried and redispatched connections */
 };
@@ -69,6 +75,12 @@ struct srvcounters {
        long long retries, redispatches;        /* retried and redispatched connections */
        long long failed_secu;                  /* blocked responses because of security concerns */
 
+       union {
+               struct {
+                       long long rsp[6];               /* http resonse codes */
+               } http;
+       } p;
+
        long long failed_checks, down_trans;    /* failed checks and up->down transitions */
 };
 
index 86b88927b86f9df67ff6d54c4e440a7fad4d63fc..032921b7385a2e4b27d939f95a6d3fb22216f055 100644 (file)
@@ -244,6 +244,7 @@ int print_csv_header(struct chunk *msg)
                            "pid,iid,sid,throttle,lbtot,tracked,type,"
                            "rate,rate_lim,rate_max,"
                            "check_status,check_code,check_duration,"
+                           "hrsp_1xx,hrsp_2xx,hrsp_3xx,hrsp_4xx,hrsp_5xx,hspr_other,"
                            "\n");
 }
 
@@ -1317,6 +1318,8 @@ int stats_dump_proxy(struct session *s, struct proxy *px, struct uri_auth *uri)
                                     "%u,%u,%u,"
                                     /* check_status, check_code, check_duration */
                                     ",,,"
+                                    /* http response: 1xx, 2xx, 3xx, 4xx, 5xx, other */
+                                    ",,,,,,"
                                     "\n",
                                     px->id,
                                     px->feconn, px->counters.feconn_max, px->maxconn, px->counters.cum_feconn,
@@ -1411,6 +1414,8 @@ int stats_dump_proxy(struct session *s, struct proxy *px, struct uri_auth *uri)
                                     ",,,"
                                     /* check_status, check_code, check_duration */
                                     ",,,"
+                                    /* http response: 1xx, 2xx, 3xx, 4xx, 5xx, other */
+                                    ",,,,,,"
                                     "\n",
                                     px->id, l->name,
                                     l->nbconn, l->counters->conn_max,
@@ -1489,16 +1494,32 @@ int stats_dump_proxy(struct session *s, struct proxy *px, struct uri_auth *uri)
                                     "<td>%s</td><td>%s</td><td>%s</td>"
                                     /* sessions rate : current, max, limit */
                                     "<td>%s</td><td>%s</td><td></td>"
-                                    /* sessions : current, max, limit, total, lbtot */
+                                    /* sessions: current, max, limit */
                                     "<td>%s</td><td>%s</td><td>%s</td>"
-                                    "<td>%s</td><td>%s</td>"
+                                    "<td"
                                     "",
                                     (sv->state & SRV_BACKUP) ? "backup" : "active",
                                     sv_state, sv->id,
                                     U2H0(sv->nbpend), U2H1(sv->counters.nbpend_max), LIM2A2(sv->maxqueue, "-"),
                                     U2H3(read_freq_ctr(&sv->sess_per_sec)), U2H4(sv->counters.sps_max),
-                                    U2H5(sv->cur_sess), U2H6(sv->counters.cur_sess_max), LIM2A7(sv->maxconn, "-"),
-                                    U2H8(sv->counters.cum_sess), U2H9(sv->counters.cum_lbconn));
+                                    U2H5(sv->cur_sess), U2H6(sv->counters.cur_sess_max), LIM2A7(sv->maxconn, "-"));
+
+                               /* http response (via td title): 1xx, 2xx, 3xx, 4xx, 5xx, other */
+                               if (px->mode == PR_MODE_HTTP) {
+                                       int i;
+
+                                       chunk_printf(&msg, " title=\"rsp codes:");
+
+                                       for (i = 1; i < 6; i++)
+                                               chunk_printf(&msg, " %dxx=%lld,", i, sv->counters.p.http.rsp[i]);
+
+                                       chunk_printf(&msg, " other=%lld\"", sv->counters.p.http.rsp[0]);
+                               }
+
+                               chunk_printf(&msg,
+                                    /* sessions: total, lbtot */
+                                    ">%s</td><td>%s</td>",
+                                    U2H0(sv->counters.cum_sess), U2H1(sv->counters.cum_lbconn));
 
                                chunk_printf(&msg,
                                     /* bytes : in, out */
@@ -1696,6 +1717,18 @@ int stats_dump_proxy(struct session *s, struct proxy *px, struct uri_auth *uri)
                                        chunk_printf(&msg, ",,,");
                                }
 
+                               /* http response: 1xx, 2xx, 3xx, 4xx, 5xx, other */
+                               if (px->mode == PR_MODE_HTTP) {
+                                       int i;
+
+                                       for (i=1; i<6; i++)
+                                               chunk_printf(&msg, "%lld,", sv->counters.p.http.rsp[i]);
+
+                                       chunk_printf(&msg, "%lld,", sv->counters.p.http.rsp[0]);
+                               } else {
+                                       chunk_printf(&msg, ",,,,,,");
+                               }
+
                                /* finish with EOL */
                                chunk_printf(&msg, "\n");
                        }
@@ -1723,13 +1756,30 @@ int stats_dump_proxy(struct session *s, struct proxy *px, struct uri_auth *uri)
                                     U2H2(read_freq_ctr(&px->be_sess_per_sec)), U2H3(px->counters.be_sps_max));
 
                                chunk_printf(&msg,
-                                    /* sessions : current, max, limit, total, lbtot */
+                                    /* sessions: current, max, limit */
                                     "<td>%s</td><td>%s</td><td>%s</td>"
-                                    "<td>%s</td><td>%s</td>"
-                                    /* bytes : in, out */
+                                    "<td"
+                                    "",
+                                    U2H2(px->beconn), U2H3(px->counters.beconn_max), U2H4(px->fullconn));
+
+                               /* http response (via td title): 1xx, 2xx, 3xx, 4xx, 5xx, other */
+                               if (px->mode == PR_MODE_HTTP) {
+                                       int i;
+
+                                       chunk_printf(&msg, " title=\"rsp codes:");
+
+                                       for (i = 1; i < 6; i++)
+                                               chunk_printf(&msg, " %dxx=%lld", i, px->counters.p.http.rsp[i]);
+
+                                       chunk_printf(&msg, " other=%lld\"", px->counters.p.http.rsp[0]);
+                               }
+
+                               chunk_printf(&msg,
+                                    /* sessions: total, lbtot */
+                                    ">%s</td><td>%s</td>"
+                                    /* bytes: in, out */
                                     "<td>%s</td><td>%s</td>"
                                     "",
-                                    U2H2(px->beconn), U2H3(px->counters.beconn_max), U2H4(px->fullconn),
                                     U2H6(px->counters.cum_beconn), U2H7(px->counters.cum_lbconn),
                                     U2H8(px->counters.bytes_in), U2H9(px->counters.bytes_out));
 
@@ -1793,8 +1843,7 @@ int stats_dump_proxy(struct session *s, struct proxy *px, struct uri_auth *uri)
                                     /* rate, rate_lim, rate_max, */
                                     "%u,,%u,"
                                     /* check_status, check_code, check_duration */
-                                    ",,,"
-                                    "\n",
+                                    ",,,",
                                     px->id,
                                     px->nbpend /* or px->totpend ? */, px->counters.nbpend_max,
                                     px->beconn, px->counters.beconn_max, px->fullconn, px->counters.cum_beconn,
@@ -1811,6 +1860,22 @@ int stats_dump_proxy(struct session *s, struct proxy *px, struct uri_auth *uri)
                                     px->counters.cum_lbconn, STATS_TYPE_BE,
                                     read_freq_ctr(&px->be_sess_per_sec),
                                     px->counters.be_sps_max);
+
+                               /* http response: 1xx, 2xx, 3xx, 4xx, 5xx, other */
+                               if (px->mode == PR_MODE_HTTP) {
+                                       int i;
+
+                                       for (i=1; i<6; i++)
+                                               chunk_printf(&msg, "%lld,", px->counters.p.http.rsp[i]);
+
+                                       chunk_printf(&msg, "%lld,", px->counters.p.http.rsp[0]);
+                               } else {
+                                       chunk_printf(&msg, ",,,,,,");
+                               }
+
+                               /* finish with EOL */
+                               chunk_printf(&msg, "\n");
+
                        }
                        if (buffer_feed_chunk(rep, &msg) >= 0)
                                return 0;
index 869859404723a2b56d0f4bfeaf4086574e07533c..23007384310f33376d2c2203dbd42d286389f882 100644 (file)
@@ -2775,6 +2775,7 @@ int process_response(struct session *t)
        struct http_txn *txn = &t->txn;
        struct buffer *req = t->req;
        struct buffer *rep = t->rep;
+       int n;
 
  next_response:
        DPRINTF(stderr,"[%u] %s: session=%p b=%p, exp(r,w)=%u,%u bf=%08x bl=%d analysers=%02x\n",
@@ -2966,6 +2967,13 @@ int process_response(struct session *t)
                t->logs.logwait &= ~LW_RESP;
                txn->status = strl2ui(rep->data + msg->sl.st.c, msg->sl.st.c_l);
 
+               n = rep->data[msg->sl.st.c] - '0';
+               if (n < 1 || n > 5)
+                       n = 0;
+
+               t->srv->counters.p.http.rsp[n]++;
+               t->be->counters.p.http.rsp[n]++;
+
                switch (txn->status) {
                case 200:
                case 203: