]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
[STATS] count transfer aborts caused by client and by server
authorWilly Tarreau <w@1wt.eu>
Thu, 4 Mar 2010 19:34:23 +0000 (20:34 +0100)
committerWilly Tarreau <w@1wt.eu>
Thu, 4 Mar 2010 19:34:23 +0000 (20:34 +0100)
Often we need to understand why some transfers were aborted or what
constitutes server response errors. With those two counters, it is
now possible to detect an unexpected transfer abort during a data
phase (eg: too short HTTP response), and to know what part of the
server response errors may in fact be assigned to aborted transfers.

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

index 394a46f1b78584c44dc499e24af9680bbce092c1..761edfb57c0ed6076dba96eccfcf3504ad5fa253 100644 (file)
@@ -7584,7 +7584,7 @@ page. Both means provide a CSV format whose fields follow.
  11. dresp: denied responses
  12. ereq: request errors
  13. econ: connection errors
- 14. eresp: response errors
+ 14. eresp: response errors (among which srv_abrt)
  15. wretr: retries (warning)
  16. wredis: redispatches (warning)
  17. status: status (UP/DOWN/NOLB/MAINT/MAINT(via)...)
@@ -7635,6 +7635,8 @@ page. Both means provide a CSV format whose fields follow.
  46. req_rate: HTTP requests per second over last elapsed second
  47. req_rate_max: max number of HTTP requests per second observed
  48. req_tot: total number of HTTP requests received
+ 49. cli_abrt: number of data transfers aborted by the client
+ 50. srv_abrt: number of data transfers aborted by the server (inc. in eresp)
 
 
 9.2. Unix Socket commands
index 33fbb5cde7d8fbaa2bd236ce48679ea98296dd91..6e620e186428556259edbba53e13a479a639794e 100644 (file)
@@ -47,6 +47,7 @@ struct pxcounters {
        } fe, be;                               /* FE and BE stats */
 
        long long failed_conns, failed_resp;    /* failed connect() and responses */
+       long long cli_aborts, srv_aborts;       /* aborted responses during DATA phase due to client or server */
        long long retries, redispatches;        /* retried and redispatched connections */
 };
 
@@ -74,6 +75,7 @@ struct srvcounters {
        long long bytes_out;                    /* number of bytes transferred from the server to the client */
 
        long long failed_conns, failed_resp;    /* failed connect() and responses */
+       long long cli_aborts, srv_aborts;       /* aborted responses during DATA phase due to client or server */
        long long retries, redispatches;        /* retried and redispatched connections */
        long long failed_secu;                  /* blocked responses because of security concerns */
 
index d3d036b024e4a12ff6800666a62e4009fc451611..b2967fc41086712cf51d3b4d7f62216b8896b8e0 100644 (file)
@@ -248,7 +248,8 @@ int print_csv_header(struct chunk *msg)
                            "rate,rate_lim,rate_max,"
                            "check_status,check_code,check_duration,"
                            "hrsp_1xx,hrsp_2xx,hrsp_3xx,hrsp_4xx,hrsp_5xx,hrsp_other,hanafail,"
-                           "req_rate, req_rate_max, req_tot,"
+                           "req_rate,req_rate_max,req_tot,"
+                           "cli_abrt,srv_abrt,"
                            "\n");
 }
 
@@ -1543,6 +1544,9 @@ int stats_dump_proxy(struct session *s, struct proxy *px, struct uri_auth *uri)
                                             read_freq_ctr(&px->fe_req_per_sec),
                                             px->counters.fe_rps_max, px->counters.cum_fe_req);
 
+                               /* errors: cli_aborts, srv_aborts */
+                               chunk_printf(&msg, ",,");
+
                                /* finish with EOL */
                                chunk_printf(&msg, "\n");
                        }
@@ -1672,6 +1676,8 @@ int stats_dump_proxy(struct session *s, struct proxy *px, struct uri_auth *uri)
                                     ","
                                     /* requests : req_rate, req_rate_max, req_tot, */
                                     ",,,"
+                                    /* errors: cli_aborts, srv_aborts */
+                                    ",,"
                                     "\n",
                                     px->id, l->name,
                                     l->nbconn, l->counters->conn_max,
@@ -1828,14 +1834,19 @@ int stats_dump_proxy(struct session *s, struct proxy *px, struct uri_auth *uri)
                                     "<td>%s</td><td>%s</td>"
                                     /* denied: req, resp */
                                     "<td></td><td>%s</td>"
-                                    /* errors : request, connect, response */
-                                    "<td></td><td>%s</td><td>%s</td>\n"
+                                    /* errors : request, connect */
+                                    "<td></td><td>%s</td>"
+                                    /* errors : response */
+                                    "<td title=\"Connection resets during transfers: %s client, %s server\"><u>%s</u></td>"
                                     /* warnings: retries, redispatches */
                                     "<td>%lld</td><td>%lld</td>"
                                     "",
                                     U2H0(sv->counters.bytes_in), U2H1(sv->counters.bytes_out),
                                     U2H2(sv->counters.failed_secu),
-                                    U2H3(sv->counters.failed_conns), U2H4(sv->counters.failed_resp),
+                                    U2H3(sv->counters.failed_conns),
+                                    U2H4(sv->counters.cli_aborts),
+                                    U2H5(sv->counters.srv_aborts),
+                                    U2H6(sv->counters.failed_resp),
                                     sv->counters.retries, sv->counters.redispatches);
 
                                /* status, lest check */
@@ -2062,6 +2073,10 @@ int stats_dump_proxy(struct session *s, struct proxy *px, struct uri_auth *uri)
                                /* requests : req_rate, req_rate_max, req_tot, */
                                chunk_printf(&msg, ",,,");
 
+                               /* errors: cli_aborts, srv_aborts */
+                               chunk_printf(&msg, "%lld,%lld,",
+                                            sv->counters.cli_aborts, sv->counters.srv_aborts);
+
                                /* finish with EOL */
                                chunk_printf(&msg, "\n");
                        }
@@ -2150,8 +2165,10 @@ int stats_dump_proxy(struct session *s, struct proxy *px, struct uri_auth *uri)
                                chunk_printf(&msg,
                                     /* denied: req, resp */
                                     "<td>%s</td><td>%s</td>"
-                                    /* errors : request, connect, response */
-                                    "<td></td><td>%s</td><td>%s</td>\n"
+                                    /* errors : request, connect */
+                                    "<td></td><td>%s</td>"
+                                    /* errors : response */
+                                    "<td title=\"Connection resets during transfers: %s client, %s server\"><u>%s</u></td>"
                                     /* warnings: retries, redispatches */
                                     "<td>%lld</td><td>%lld</td>"
                                     /* backend status: reflect backend status (up/down): we display UP
@@ -2162,7 +2179,10 @@ int stats_dump_proxy(struct session *s, struct proxy *px, struct uri_auth *uri)
                                     "<td class=ac>%d</td><td class=ac>%d</td>"
                                     "",
                                     U2H0(px->counters.denied_req), U2H1(px->counters.denied_resp),
-                                    U2H2(px->counters.failed_conns), U2H3(px->counters.failed_resp),
+                                    U2H2(px->counters.failed_conns),
+                                    U2H3(px->counters.cli_aborts),
+                                    U2H4(px->counters.srv_aborts),
+                                    U2H5(px->counters.failed_resp),
                                     px->counters.retries, px->counters.redispatches,
                                     human_time(now.tv_sec - px->last_change, 1),
                                     (px->lbprm.tot_weight > 0 || !px->srv) ? "UP" :
@@ -2243,6 +2263,10 @@ int stats_dump_proxy(struct session *s, struct proxy *px, struct uri_auth *uri)
                                /* requests : req_rate, req_rate_max, req_tot, */
                                chunk_printf(&msg, ",,,");
 
+                               /* errors: cli_aborts, srv_aborts */
+                               chunk_printf(&msg, "%lld,%lld,",
+                                            px->counters.cli_aborts, px->counters.srv_aborts);
+
                                /* finish with EOL */
                                chunk_printf(&msg, "\n");
 
index 72d2da9ec926c965a63ae2dee25a32527d4f2777..3db8ac4a782e0923f6a9e793631b1b7301b25639 100644 (file)
@@ -3971,6 +3971,9 @@ int http_sync_res_state(struct session *s)
                }
                else if (buf->flags & BF_SHUTW) {
                        txn->rsp.msg_state = HTTP_MSG_ERROR;
+                       s->be->counters.cli_aborts++;
+                       if (s->srv)
+                               s->srv->counters.cli_aborts++;
                        goto wait_other_side;
                }
        }
@@ -5071,6 +5074,9 @@ int http_response_forward_body(struct session *s, struct buffer *res, int an_bit
        if (res->flags & BF_SHUTR) {
                if (!(s->flags & SN_ERR_MASK))
                        s->flags |= SN_ERR_SRVCL;
+               s->be->counters.srv_aborts++;
+               if (s->srv)
+                       s->srv->counters.srv_aborts++;
                goto return_bad_res;
        }
 
index b6021474534f76f3d8e2b0589a5c0c715e14babe..60d8d2abb2f3c6939aef3593d09233c68e66e507 100644 (file)
@@ -893,6 +893,9 @@ struct task *process_session(struct task *t)
                        s->si[0].shutw(&s->si[0]);
                        stream_int_report_error(&s->si[0]);
                        if (!(s->req->analysers) && !(s->rep->analysers)) {
+                               s->be->counters.cli_aborts++;
+                               if (s->srv)
+                                       s->srv->counters.cli_aborts++;
                                if (!(s->flags & SN_ERR_MASK))
                                        s->flags |= SN_ERR_CLICL;
                                if (!(s->flags & SN_FINST_MASK))
@@ -910,6 +913,9 @@ struct task *process_session(struct task *t)
                        if (s->srv)
                                s->srv->counters.failed_resp++;
                        if (!(s->req->analysers) && !(s->rep->analysers)) {
+                               s->be->counters.srv_aborts++;
+                               if (s->srv)
+                                       s->srv->counters.srv_aborts++;
                                if (!(s->flags & SN_ERR_MASK))
                                        s->flags |= SN_ERR_SRVCL;
                                if (!(s->flags & SN_FINST_MASK))
@@ -1212,33 +1218,67 @@ resync_stream_interface:
 
 
        /*
-        * Now we propagate unhandled errors to the session
+        * Now we propagate unhandled errors to the session. Normally
+        * we're just in a data phase here since it means we have not
+        * seen any analyser who could set an error status.
         */
        if (!(s->flags & SN_ERR_MASK)) {
                if (s->req->flags & (BF_READ_ERROR|BF_READ_TIMEOUT|BF_WRITE_ERROR|BF_WRITE_TIMEOUT)) {
                        /* Report it if the client got an error or a read timeout expired */
                        s->req->analysers = 0;
-                       if (s->req->flags & BF_READ_ERROR)
+                       if (s->req->flags & BF_READ_ERROR) {
+                               s->be->counters.cli_aborts++;
+                               if (s->srv)
+                                       s->srv->counters.cli_aborts++;
                                s->flags |= SN_ERR_CLICL;
-                       else if (s->req->flags & BF_READ_TIMEOUT)
+                       }
+                       else if (s->req->flags & BF_READ_TIMEOUT) {
+                               s->be->counters.cli_aborts++;
+                               if (s->srv)
+                                       s->srv->counters.cli_aborts++;
                                s->flags |= SN_ERR_CLITO;
-                       else if (s->req->flags & BF_WRITE_ERROR)
+                       }
+                       else if (s->req->flags & BF_WRITE_ERROR) {
+                               s->be->counters.srv_aborts++;
+                               if (s->srv)
+                                       s->srv->counters.srv_aborts++;
                                s->flags |= SN_ERR_SRVCL;
-                       else
+                       }
+                       else {
+                               s->be->counters.srv_aborts++;
+                               if (s->srv)
+                                       s->srv->counters.srv_aborts++;
                                s->flags |= SN_ERR_SRVTO;
+                       }
                        sess_set_term_flags(s);
                }
                else if (s->rep->flags & (BF_READ_ERROR|BF_READ_TIMEOUT|BF_WRITE_ERROR|BF_WRITE_TIMEOUT)) {
                        /* Report it if the server got an error or a read timeout expired */
                        s->rep->analysers = 0;
-                       if (s->rep->flags & BF_READ_ERROR)
+                       if (s->rep->flags & BF_READ_ERROR) {
+                               s->be->counters.srv_aborts++;
+                               if (s->srv)
+                                       s->srv->counters.srv_aborts++;
                                s->flags |= SN_ERR_SRVCL;
-                       else if (s->rep->flags & BF_READ_TIMEOUT)
+                       }
+                       else if (s->rep->flags & BF_READ_TIMEOUT) {
+                               s->be->counters.srv_aborts++;
+                               if (s->srv)
+                                       s->srv->counters.srv_aborts++;
                                s->flags |= SN_ERR_SRVTO;
-                       else if (s->rep->flags & BF_WRITE_ERROR)
+                       }
+                       else if (s->rep->flags & BF_WRITE_ERROR) {
+                               s->be->counters.cli_aborts++;
+                               if (s->srv)
+                                       s->srv->counters.cli_aborts++;
                                s->flags |= SN_ERR_CLICL;
-                       else
-                       s->flags |= SN_ERR_CLITO;
+                       }
+                       else {
+                               s->be->counters.cli_aborts++;
+                               if (s->srv)
+                                       s->srv->counters.cli_aborts++;
+                               s->flags |= SN_ERR_CLITO;
+                       }
                        sess_set_term_flags(s);
                }
        }