diff --git a/doc/configuration.txt b/doc/configuration.txt index 394a46f1b..761edfb57 100644 --- a/doc/configuration.txt +++ b/doc/configuration.txt @@ -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 diff --git a/include/types/counters.h b/include/types/counters.h index 33fbb5cde..6e620e186 100644 --- a/include/types/counters.h +++ b/include/types/counters.h @@ -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 */ diff --git a/src/dumpstats.c b/src/dumpstats.c index d3d036b02..b2967fc41 100644 --- a/src/dumpstats.c +++ b/src/dumpstats.c @@ -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) "%s%s" /* denied: req, resp */ "%s" - /* errors : request, connect, response */ - "%s%s\n" + /* errors : request, connect */ + "%s" + /* errors : response */ + "%s" /* warnings: retries, redispatches */ "%lld%lld" "", 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 */ "%s%s" - /* errors : request, connect, response */ - "%s%s\n" + /* errors : request, connect */ + "%s" + /* errors : response */ + "%s" /* warnings: retries, redispatches */ "%lld%lld" /* 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) "%d%d" "", 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"); diff --git a/src/proto_http.c b/src/proto_http.c index 72d2da9ec..3db8ac4a7 100644 --- a/src/proto_http.c +++ b/src/proto_http.c @@ -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; } diff --git a/src/session.c b/src/session.c index b60214745..60d8d2abb 100644 --- a/src/session.c +++ b/src/session.c @@ -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); } }