MINOR: stream: Expose session terminate state via a new sample fetch
authorChristopher Faulet <cfaulet@haproxy.com>
Tue, 28 Nov 2023 07:45:33 +0000 (08:45 +0100)
committerChristopher Faulet <cfaulet@haproxy.com>
Wed, 29 Nov 2023 10:11:12 +0000 (11:11 +0100)
It is now possible to retrieve the session terminate state, using
"txn.sess_term_state". The sample fetch returns the 2-character session
termation state.

Of course, the result of this sample fetch is volatile. It is subject to
change. It is also most of time useless because no termation state is set
except at the end. It should only be useful in http-after-response rule
sets. It may also be used to customize the logs using a log-format
directive.

This patch should fix the issue #2221.

doc/configuration.txt
include/haproxy/log.h
src/stream.c

index 10ccf2f..09dec9b 100644 (file)
@@ -20103,6 +20103,18 @@ thread : integer
   the function, between 0 and (global.nbthread-1). This is useful for logging
   and debugging purposes.
 
+txn.sess_term_state : string
+  Retruns the TCP or HTTP session termination state, as reported in the log. It
+  is a 2-characters string, The final session state followed by the event which
+  caused its to terminate. See section 8.5 about session state at disconnection
+  for the list of possible events. The current value at time the sample fetch
+  is evaluated is returned. It is subject to change. Except used with ACLs in
+  "http-after-response" rule sets or in log messages, it will always be "--".
+
+  Example:
+      # Return a 429-Too-Many-Requests if session timed out in queue
+      http-after-response set-status 429 if { txn.sess_term_state  "sQ" }
+
 uuid([<version>]) : string
   Returns a UUID following the RFC4122 standard. If the version is not
   specified, a UUID version 4 (fully random) is returned.
@@ -24050,6 +24062,7 @@ Please refer to the table below for currently defined variables :
   |   |      | %[ssl_fc_protocol]                                   | string  |
   +---+------+------------------------------------------------------+---------+
   |   | %ts  | termination_state                                    | string  |
+  |   |      | %[txn.sess_term_state]                               |         |
   +---+------+------------------------------------------------------+---------+
   | H | %tsc | termination_state with cookie status                 | string  |
   +---+------+------------------------------------------------------+---------+
index d36e184..68b8207 100644 (file)
@@ -43,6 +43,9 @@ extern char default_https_log_format[];
 
 extern char default_rfc5424_sd_log_format[];
 
+extern const char sess_term_cond[];
+extern const char sess_fin_state[];
+
 extern unsigned int dropped_logs;
 
 /* lof forward proxy list */
index 392dc79..9c4e9ad 100644 (file)
@@ -3971,6 +3971,24 @@ static int smp_fetch_last_rule_line(const struct arg *args, struct sample *smp,
        return 1;
 }
 
+static int smp_fetch_sess_term_state(const struct arg *args, struct sample *smp, const char *km, void *private)
+{
+       struct buffer *trash = get_trash_chunk();
+
+       smp->flags = SMP_F_VOLATILE;
+       smp->data.type = SMP_T_STR;
+       if (!smp->strm)
+               return 0;
+
+       trash->area[trash->data++] = sess_term_cond[(smp->strm->flags & SF_ERR_MASK) >> SF_ERR_SHIFT];
+       trash->area[trash->data++] = sess_fin_state[(smp->strm->flags & SF_FINST_MASK) >> SF_FINST_SHIFT];
+
+       smp->data.u.str = *trash;
+       smp->data.type = SMP_T_STR;
+       smp->flags &= ~SMP_F_CONST;
+       return 1;
+}
+
 /* Note: must not be declared <const> as its list will be overwritten.
  * Please take care of keeping this list alphabetically sorted.
  */
@@ -3980,6 +3998,7 @@ static struct sample_fetch_kw_list smp_kws = {ILH, {
        { "cur_tunnel_timeout", smp_fetch_cur_tunnel_timeout, 0, NULL, SMP_T_SINT, SMP_USE_BKEND, },
        { "last_rule_file",     smp_fetch_last_rule_file,     0, NULL, SMP_T_STR,  SMP_USE_INTRN, },
        { "last_rule_line",     smp_fetch_last_rule_line,     0, NULL, SMP_T_SINT, SMP_USE_INTRN, },
+       { "txn.sess_term_state",smp_fetch_sess_term_state,    0, NULL, SMP_T_STR,  SMP_USE_INTRN, },
        { NULL, NULL, 0, 0, 0 },
 }};