]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
DEBUG: stream: Add debug counters to track some client/server aborts
authorChristopher Faulet <cfaulet@haproxy.com>
Tue, 22 Oct 2024 14:46:34 +0000 (16:46 +0200)
committerChristopher Faulet <cfaulet@haproxy.com>
Tue, 22 Oct 2024 14:46:37 +0000 (16:46 +0200)
Not all aborts are tracked for now but only those a bit ambiguous. Mainly,
aborts during the data forwarding are concerned. Those triggered during the
request or the response analysis are easier to analyze with the stream
termination state.

src/http_ana.c
src/stream.c

index a30100ffd6f313691e2a7e1973e16e78c0dad8ed..d94ca18f4b48e3aca3d916bd2d337569c4a1860a 100644 (file)
@@ -515,8 +515,9 @@ int http_process_req_common(struct stream *s, struct channel *req, int an_bit, s
                        if (!ret)
                                continue;
                }
-               if (!http_apply_redirect_rule(rule, s, txn))
+               if (!http_apply_redirect_rule(rule, s, txn)) {
                        goto return_int_err;
+               }
                goto done;
        }
 
@@ -1007,8 +1008,10 @@ int http_request_forward_body(struct stream *s, struct channel *req, int an_bit)
                 * response. Otherwise, let a change to forward the response
                 * first.
                 */
-               if (htx_is_empty(htxbuf(&s->res.buf)))
+               if (htx_is_empty(htxbuf(&s->res.buf))) {
+                       COUNT_IF(1, "Server abort during request forwarding");
                        goto return_srv_abort;
+               }
        }
 
        http_end_request(s);
@@ -1040,8 +1043,10 @@ int http_request_forward_body(struct stream *s, struct channel *req, int an_bit)
 
  missing_data_or_waiting:
        /* stop waiting for data if the input is closed before the end */
-       if (msg->msg_state < HTTP_MSG_ENDING && (s->scf->flags & (SC_FL_ABRT_DONE|SC_FL_EOS)))
+       if (msg->msg_state < HTTP_MSG_ENDING && (s->scf->flags & (SC_FL_ABRT_DONE|SC_FL_EOS))) {
+               COUNT_IF(1, "Client abort during request forwarding");
                goto return_cli_abort;
+       }
 
  waiting:
        /* waiting for the last bits to leave the buffer */
@@ -1049,8 +1054,10 @@ int http_request_forward_body(struct stream *s, struct channel *req, int an_bit)
                /* Handle server aborts only if there is no response. Otherwise,
                 * let a change to forward the response first.
                 */
-               if (htx_is_empty(htxbuf(&s->res.buf)))
+               if (htx_is_empty(htxbuf(&s->res.buf))) {
+                       COUNT_IF(1, "Server abort during request forwarding");
                        goto return_srv_abort;
+               }
        }
 
        /* When TE: chunked is used, we need to get there again to parse remaining
@@ -1113,6 +1120,7 @@ int http_request_forward_body(struct stream *s, struct channel *req, int an_bit)
        if (objt_server(s->target))
                _HA_ATOMIC_INC(&__objt_server(s->target)->counters.internal_errors);
        status = 500;
+       COUNT_IF(1, "Internal error during request forwarding");
        goto return_prx_cond;
 
   return_bad_req:
@@ -1120,6 +1128,7 @@ int http_request_forward_body(struct stream *s, struct channel *req, int an_bit)
        if (sess->listener && sess->listener->counters)
                _HA_ATOMIC_INC(&sess->listener->counters->failed_req);
        status = 400;
+       COUNT_IF(1, "Request parsing error during request forwarding");
        /* fall through */
 
   return_prx_cond:
@@ -2151,6 +2160,7 @@ int http_response_forward_body(struct stream *s, struct channel *res, int an_bit
        if ((s->scf->flags & SC_FL_SHUT_DONE) && co_data(res)) {
                /* response errors are most likely due to the client aborting
                 * the transfer. */
+               COUNT_IF(1, "Client abort during response forwarding");
                goto return_cli_abort;
        }
 
@@ -2164,8 +2174,10 @@ int http_response_forward_body(struct stream *s, struct channel *res, int an_bit
        return 0;
 
   missing_data_or_waiting:
-       if (s->scf->flags & SC_FL_SHUT_DONE)
+       if (s->scf->flags & SC_FL_SHUT_DONE) {
+               COUNT_IF(1, "Client abort during response forwarding");
                goto return_cli_abort;
+       }
 
        /* stop waiting for data if the input is closed before the end. If the
         * client side was already closed, it means that the client has aborted,
@@ -2174,11 +2186,15 @@ int http_response_forward_body(struct stream *s, struct channel *res, int an_bit
         */
        if (msg->msg_state < HTTP_MSG_ENDING && (s->scb->flags & (SC_FL_EOS|SC_FL_ABRT_DONE))) {
                if ((s->scf->flags & (SC_FL_EOS|SC_FL_ABRT_DONE)) &&
-                   (s->scb->flags & SC_FL_SHUT_DONE))
+                   (s->scb->flags & SC_FL_SHUT_DONE)) {
+                       COUNT_IF(1, "Client abort during response forwarding");
                        goto return_cli_abort;
+               }
                /* If we have some pending data, we continue the processing */
-               if (htx_is_empty(htx))
+               if (htx_is_empty(htx)) {
+                       COUNT_IF(1, "Server abort during response forwarding");
                        goto return_srv_abort;
+               }
        }
 
        /* When TE: chunked is used, we need to get there again to parse
@@ -2238,6 +2254,7 @@ int http_response_forward_body(struct stream *s, struct channel *res, int an_bit
                _HA_ATOMIC_INC(&__objt_server(s->target)->counters.internal_errors);
        if (!(s->flags & SF_ERR_MASK))
                s->flags |= SF_ERR_INTERNAL;
+       COUNT_IF(1, "Internal error during response forwarding");
        goto return_error;
 
   return_bad_res:
@@ -2247,6 +2264,7 @@ int http_response_forward_body(struct stream *s, struct channel *res, int an_bit
                health_adjust(__objt_server(s->target), HANA_STATUS_HTTP_RSP);
        }
        stream_inc_http_fail_ctr(s);
+       COUNT_IF(1, "Response parsing error during response forwarding");
        /* fall through */
 
    return_error:
index bc037d8c5a3869bd433efd4d929768c73c338345..0fa942944c0639456827120c9ecc6890d78378e5 100644 (file)
@@ -1846,6 +1846,7 @@ struct task *process_stream(struct task *t, void *context, unsigned int state)
                        sc_abort(scf);
                        sc_shutdown(scf);
                        if (!(req->analysers) && !(res->analysers)) {
+                               COUNT_IF(1, "Report a client abort (no analysers)");
                                _HA_ATOMIC_INC(&s->be->be_counters.cli_aborts);
                                _HA_ATOMIC_INC(&sess->fe->fe_counters.cli_aborts);
                                if (sess->listener && sess->listener->counters)
@@ -1868,6 +1869,7 @@ struct task *process_stream(struct task *t, void *context, unsigned int state)
                        if (srv)
                                _HA_ATOMIC_INC(&srv->counters.failed_resp);
                        if (!(req->analysers) && !(res->analysers)) {
+                               COUNT_IF(1, "Report a client abort (no analysers)");
                                _HA_ATOMIC_INC(&s->be->be_counters.srv_aborts);
                                _HA_ATOMIC_INC(&sess->fe->fe_counters.srv_aborts);
                                if (sess->listener && sess->listener->counters)
@@ -2173,6 +2175,7 @@ struct task *process_stream(struct task *t, void *context, unsigned int state)
                                if (srv)
                                        _HA_ATOMIC_INC(&srv->counters.cli_aborts);
                                s->flags |= SF_ERR_CLICL;
+                               COUNT_IF(1, "Report unhandled client error");
                        }
                        else if (req->flags & CF_READ_TIMEOUT) {
                                _HA_ATOMIC_INC(&s->be->be_counters.cli_aborts);
@@ -2182,6 +2185,7 @@ struct task *process_stream(struct task *t, void *context, unsigned int state)
                                if (srv)
                                        _HA_ATOMIC_INC(&srv->counters.cli_aborts);
                                s->flags |= SF_ERR_CLITO;
+                               COUNT_IF(1, "Report unhandled client timeout (RD)");
                        }
                        else {
                                _HA_ATOMIC_INC(&s->be->be_counters.srv_aborts);
@@ -2191,6 +2195,7 @@ struct task *process_stream(struct task *t, void *context, unsigned int state)
                                if (srv)
                                        _HA_ATOMIC_INC(&srv->counters.srv_aborts);
                                s->flags |= SF_ERR_SRVTO;
+                               COUNT_IF(1, "Report unhandled server timeout (WR)");
                        }
                        sess_set_term_flags(s);
 
@@ -2219,6 +2224,7 @@ struct task *process_stream(struct task *t, void *context, unsigned int state)
                                if (srv)
                                        _HA_ATOMIC_INC(&srv->counters.srv_aborts);
                                s->flags |= SF_ERR_SRVCL;
+                               COUNT_IF(1, "Report unhandled server error");
                        }
                        else if (res->flags & CF_READ_TIMEOUT) {
                                _HA_ATOMIC_INC(&s->be->be_counters.srv_aborts);
@@ -2228,6 +2234,7 @@ struct task *process_stream(struct task *t, void *context, unsigned int state)
                                if (srv)
                                        _HA_ATOMIC_INC(&srv->counters.srv_aborts);
                                s->flags |= SF_ERR_SRVTO;
+                               COUNT_IF(1, "Report unhandled server timeout (RD)");
                        }
                        else {
                                _HA_ATOMIC_INC(&s->be->be_counters.cli_aborts);
@@ -2237,6 +2244,7 @@ struct task *process_stream(struct task *t, void *context, unsigned int state)
                                if (srv)
                                        _HA_ATOMIC_INC(&srv->counters.cli_aborts);
                                s->flags |= SF_ERR_CLITO;
+                               COUNT_IF(1, "Report unhandled client timeout (WR)");
                        }
                        sess_set_term_flags(s);
                }