MINOR: stick-tables/counters: add http_fail_cnt and http_fail_rate data types
Historically we've been counting lots of client-triggered events in stick tables to help detect misbehaving ones, but we've been missing the same on the server side, and there's been repeated requests for being able to count the server errors per URL in order to precisely monitor the quality of service or even to avoid routing requests to certain dead services, which is also called "circuit breaking" nowadays. This commit introduces http_fail_cnt and http_fail_rate, which work like http_err_cnt and http_err_rate in that they respectively count events and their frequency, but they only consider server-side issues such as network errors, unparsable and truncated responses, and 5xx status codes other than 501 and 505 (since these ones are usually triggered by the client). Note that retryable errors are purposely not accounted for, so that only what the client really sees is considered. With this it becomes very simple to put some protective measures in place to perform a redirect or return an excuse page when the error rate goes beyond a certain threshold for a given URL, and give more chances to the server to recover from this condition. Typically it could look like this to bypass a URL causing more than 10 requests per second: stick-table type string len 80 size 4k expire 1m store http_fail_rate(1m) http-request track-sc0 base # track host+path, ignore query string http-request return status 503 content-type text/html \ lf-file excuse.html if { sc0_http_fail_rate gt 10 } A more advanced mechanism using gpt0 could even implement high/low rates to disable/enable the service. Reg-test converteers_ref_cnt_never_dec.vtc was updated to test it.
This commit is contained in:
parent
e4d247e217
commit
826f3ab5e6
@ -10838,6 +10838,19 @@ stick-table type {ip | integer | string [len <length>] | binary [len <length>]}
|
||||
http_err_cnt above for what is accounted as an error). The result is an
|
||||
integer which can be matched using ACLs.
|
||||
|
||||
- http_fail_cnt : HTTP Failure Count. It is a positive 32-bit integer which
|
||||
counts the absolute number of HTTP response failures induced by servers
|
||||
which matched this entry. Errors are counted on invalid and truncated
|
||||
responses, as well as any 5xx response other than 501 or 505. It aims at
|
||||
being used combined with path or URI to detect service failures.
|
||||
|
||||
- http_fail_rate(<period>) : frequency counter (takes 12 bytes). It takes
|
||||
an integer parameter <period> which indicates in milliseconds the length
|
||||
of the period over which the average is measured. It reports the average
|
||||
HTTP response failure rate over that period, in requests per period (see
|
||||
http_fail_cnt above for what is accounted as a failure). The result is an
|
||||
integer which can be matched using ACLs.
|
||||
|
||||
- bytes_in_cnt : client to server byte count. It is a positive 64-bit
|
||||
integer which counts the cumulative number of bytes received from clients
|
||||
which matched this entry. Headers are included in the count. This may be
|
||||
@ -16162,6 +16175,21 @@ table_http_err_rate(<table>)
|
||||
period configured in the table. See also the sc_http_err_rate sample fetch
|
||||
keyword.
|
||||
|
||||
table_http_fail_cnt(<table>)
|
||||
Uses the string representation of the input sample to perform a look up in
|
||||
the specified table. If the key is not found in the table, integer value zero
|
||||
is returned. Otherwise the converter returns the cumulative number of HTTP
|
||||
failures associated with the input sample in the designated table. See also
|
||||
the sc_http_fail_cnt sample fetch keyword.
|
||||
|
||||
table_http_fail_rate(<table>)
|
||||
Uses the string representation of the input sample to perform a look up in
|
||||
the specified table. If the key is not found in the table, integer value zero
|
||||
is returned. Otherwise the average rate of HTTP failures associated with the
|
||||
input sample in the designated table, measured in amount of failures over the
|
||||
period configured in the table. See also the sc_http_fail_rate sample fetch
|
||||
keyword.
|
||||
|
||||
table_http_req_cnt(<table>)
|
||||
Uses the string representation of the input sample to perform a look up in
|
||||
the specified table. If the key is not found in the table, integer value zero
|
||||
@ -17166,6 +17194,23 @@ sc2_http_err_rate([<table>]) : integer
|
||||
includes the both request errors and 4xx error responses. See also
|
||||
src_http_err_rate.
|
||||
|
||||
sc_http_fail_cnt(<ctr>[,<table>]) : integer
|
||||
sc0_http_fail_cnt([<table>]) : integer
|
||||
sc1_http_fail_cnt([<table>]) : integer
|
||||
sc2_http_fail_cnt([<table>]) : integer
|
||||
Returns the cumulative number of HTTP response failures from the currently
|
||||
tracked counters. This includes the both response errors and 5xx status codes
|
||||
other than 501 and 505. See also src_http_fail_cnt.
|
||||
|
||||
sc_http_fail_rate(<ctr>[,<table>]) : integer
|
||||
sc0_http_fail_rate([<table>]) : integer
|
||||
sc1_http_fail_rate([<table>]) : integer
|
||||
sc2_http_fail_rate([<table>]) : integer
|
||||
Returns the average rate of HTTP response failures from the currently tracked
|
||||
counters, measured in amount of failures over the period configured in the
|
||||
table. This includes the both response errors and 5xx status codes other than
|
||||
501 and 505. See also src_http_fail_rate.
|
||||
|
||||
sc_http_req_cnt(<ctr>[,<table>]) : integer
|
||||
sc0_http_req_cnt([<table>]) : integer
|
||||
sc1_http_req_cnt([<table>]) : integer
|
||||
@ -17402,6 +17447,21 @@ src_http_err_rate([<table>]) : integer
|
||||
includes the both request errors and 4xx error responses. If the address is
|
||||
not found, zero is returned. See also sc/sc0/sc1/sc2_http_err_rate.
|
||||
|
||||
src_http_fail_cnt([<table>]) : integer
|
||||
Returns the cumulative number of HTTP response failures triggered by the
|
||||
incoming connection's source address in the current proxy's stick-table or in
|
||||
the designated stick-table. This includes the both repsonse errors and 5xx
|
||||
status codes other than 501 and 505. See also sc/sc0/sc1/sc2_http_fail_cnt.
|
||||
If the address is not found, zero is returned.
|
||||
|
||||
src_http_fail_rate([<table>]) : integer
|
||||
Returns the average rate of HTTP response failures triggered by the incoming
|
||||
connection's source address in the current proxy's stick-table or in the
|
||||
designated stick-table, measured in amount of failures over the period
|
||||
configured in the table. This includes the both response errors and 5xx
|
||||
status codes other than 501 and 505. If the address is not found, zero is
|
||||
returned. See also sc/sc0/sc1/sc2_http_fail_rate.
|
||||
|
||||
src_http_req_cnt([<table>]) : integer
|
||||
Returns the cumulative number of HTTP requests from the incoming connection's
|
||||
source address in the current proxy's stick-table or in the designated stick-
|
||||
|
@ -97,6 +97,19 @@ static inline void session_inc_http_err_ctr(struct session *sess)
|
||||
stkctr_inc_http_err_ctr(&sess->stkctr[i]);
|
||||
}
|
||||
|
||||
/* Increase the number of cumulated failed HTTP responses in the tracked
|
||||
* counters. Only some 5xx responses should be counted here so that we can
|
||||
* distinguish between server failures and errors triggered by the client
|
||||
* (i.e. 501 and 505 may be triggered and must be ignored).
|
||||
*/
|
||||
static inline void session_inc_http_fail_ctr(struct session *sess)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < MAX_SESS_STKCTR; i++)
|
||||
stkctr_inc_http_fail_ctr(&sess->stkctr[i]);
|
||||
}
|
||||
|
||||
|
||||
/* Remove the connection from the session list, and destroy the srv_list if it's now empty */
|
||||
static inline void session_unown_conn(struct session *sess, struct connection *conn)
|
||||
|
@ -57,6 +57,9 @@ enum {
|
||||
STKTABLE_DT_GPC1, /* General Purpose Counter 1 (unsigned 32-bit integer) */
|
||||
STKTABLE_DT_GPC1_RATE, /* General Purpose Counter 1's event rate */
|
||||
STKTABLE_DT_SERVER_KEY, /* The server key */
|
||||
STKTABLE_DT_HTTP_FAIL_CNT, /* cumulated number of HTTP server failures */
|
||||
STKTABLE_DT_HTTP_FAIL_RATE,/* HTTP server failures rate */
|
||||
|
||||
STKTABLE_STATIC_DATA_TYPES,/* number of types above */
|
||||
/* up to STKTABLE_EXTRA_DATA_TYPES types may be registered here, always
|
||||
* followed by the number of data types, must always be last.
|
||||
@ -137,6 +140,8 @@ union stktable_data {
|
||||
struct freq_ctr_period bytes_in_rate;
|
||||
unsigned long long bytes_out_cnt;
|
||||
struct freq_ctr_period bytes_out_rate;
|
||||
unsigned int http_fail_cnt;
|
||||
struct freq_ctr_period http_fail_rate;
|
||||
};
|
||||
|
||||
/* known data types */
|
||||
|
@ -267,6 +267,38 @@ static inline int stkctr_inc_http_err_ctr(struct stkctr *stkctr)
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Increase the number of cumulated failed HTTP responses in the tracked counter
|
||||
* <stkctr>. It returns 0 if the entry pointer does not exist and nothing is
|
||||
* performed. Otherwise it returns 1.
|
||||
*/
|
||||
static inline int stkctr_inc_http_fail_ctr(struct stkctr *stkctr)
|
||||
{
|
||||
struct stksess *ts;
|
||||
void *ptr1, *ptr2;
|
||||
|
||||
ts = stkctr_entry(stkctr);
|
||||
if (!ts)
|
||||
return 0;
|
||||
|
||||
HA_RWLOCK_WRLOCK(STK_SESS_LOCK, &ts->lock);
|
||||
|
||||
ptr1 = stktable_data_ptr(stkctr->table, ts, STKTABLE_DT_HTTP_FAIL_CNT);
|
||||
if (ptr1)
|
||||
stktable_data_cast(ptr1, http_fail_cnt)++;
|
||||
|
||||
ptr2 = stktable_data_ptr(stkctr->table, ts, STKTABLE_DT_HTTP_FAIL_RATE);
|
||||
if (ptr2)
|
||||
update_freq_ctr_period(&stktable_data_cast(ptr2, http_fail_rate),
|
||||
stkctr->table->data_arg[STKTABLE_DT_HTTP_FAIL_RATE].u, 1);
|
||||
|
||||
HA_RWLOCK_WRUNLOCK(STK_SESS_LOCK, &ts->lock);
|
||||
|
||||
/* If data was modified, we need to touch to re-schedule sync */
|
||||
if (ptr1 || ptr2)
|
||||
stktable_touch_local(stkctr->table, ts, 0);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Increase the number of bytes received in the tracked counter <stkctr>. It
|
||||
* returns 0 if the entry pointer does not exist and nothing is
|
||||
* performed. Otherwise it returns 1.
|
||||
|
@ -270,6 +270,21 @@ static inline void stream_inc_http_err_ctr(struct stream *s)
|
||||
}
|
||||
}
|
||||
|
||||
/* Increase the number of cumulated failed HTTP responses in the tracked
|
||||
* counters. Only some 5xx responses should be counted here so that we can
|
||||
* distinguish between server failures and errors triggered by the client
|
||||
* (i.e. 501 and 505 may be triggered and must be ignored).
|
||||
*/
|
||||
static inline void stream_inc_http_fail_ctr(struct stream *s)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < MAX_SESS_STKCTR; i++) {
|
||||
if (!stkctr_inc_http_fail_ctr(&s->stkctr[i]))
|
||||
stkctr_inc_http_fail_ctr(&s->sess->stkctr[i]);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void __stream_add_srv_conn(struct stream *sess, struct server *srv)
|
||||
{
|
||||
sess->srv_conn = srv;
|
||||
|
@ -15,6 +15,7 @@
|
||||
# This should be backported to 1.8
|
||||
|
||||
#REGTEST_TYPE=bug
|
||||
#REQUIRE_VERSION=2.4
|
||||
|
||||
varnishtest "stick-tables: Test expirations when used with table_*"
|
||||
|
||||
@ -36,7 +37,7 @@ haproxy h1 -conf {
|
||||
|
||||
frontend http1
|
||||
bind "fd@${my_frontend_fd}"
|
||||
stick-table size 1k expire 1ms type ip store conn_rate(10s),http_req_cnt,http_err_cnt,http_req_rate(10s),http_err_rate(10s),gpc0,gpc0_rate(10s),gpt0
|
||||
stick-table size 1k expire 1ms type ip store conn_rate(10s),http_req_cnt,http_err_cnt,http_fail_cnt,http_req_rate(10s),http_err_rate(10s),http_fail_rate(10s),gpc0,gpc0_rate(10s),gpt0
|
||||
http-request track-sc0 req.hdr(X-Forwarded-For)
|
||||
http-request redirect location https://${s1_addr}:${s1_port}/ if { req.hdr(X-Forwarded-For),table_http_req_cnt(http1) -m int lt 0 }
|
||||
http-request redirect location https://${s1_addr}:${s1_port}/ if { req.hdr(X-Forwarded-For),table_trackers(http1) -m int lt 0 }
|
||||
@ -51,6 +52,8 @@ haproxy h1 -conf {
|
||||
http-request redirect location https://${s1_addr}:${s1_port}/ if { req.hdr(X-Forwarded-For),table_gpc0_rate(http1) -m int lt 0 }
|
||||
http-request redirect location https://${s1_addr}:${s1_port}/ if { req.hdr(X-Forwarded-For),table_http_err_cnt(http1) -m int lt 0 }
|
||||
http-request redirect location https://${s1_addr}:${s1_port}/ if { req.hdr(X-Forwarded-For),table_http_err_rate(http1) -m int lt 0 }
|
||||
http-request redirect location https://${s1_addr}:${s1_port}/ if { req.hdr(X-Forwarded-For),table_http_fail_cnt(http1) -m int lt 0 }
|
||||
http-request redirect location https://${s1_addr}:${s1_port}/ if { req.hdr(X-Forwarded-For),table_http_fail_rate(http1) -m int lt 0 }
|
||||
http-request redirect location https://${s1_addr}:${s1_port}/ if { req.hdr(X-Forwarded-For),table_http_req_cnt(http1) -m int lt 0 }
|
||||
http-request redirect location https://${s1_addr}:${s1_port}/ if { req.hdr(X-Forwarded-For),table_http_req_rate(http1) -m int lt 0 }
|
||||
http-request redirect location https://${s1_addr}:${s1_port}/ if { req.hdr(X-Forwarded-For),table_kbytes_in(http1) -m int lt 0 }
|
||||
@ -69,5 +72,5 @@ client c1 -connect ${h1_my_frontend_fd_sock} {
|
||||
|
||||
haproxy h1 -cli {
|
||||
send "show table http1"
|
||||
expect ~ "table: http1, type: ip, size:1024, used:(0|1\\n0x[0-9a-f]*: key=127\\.0\\.0\\.1 use=0 exp=[0-9]* gpt0=0 gpc0=0 gpc0_rate\\(10000\\)=0 conn_rate\\(10000\\)=1 http_req_cnt=1 http_req_rate\\(10000\\)=1 http_err_cnt=0 http_err_rate\\(10000\\)=0)\\n$"
|
||||
expect ~ "table: http1, type: ip, size:1024, used:(0|1\\n0x[0-9a-f]*: key=127\\.0\\.0\\.1 use=0 exp=[0-9]* gpt0=0 gpc0=0 gpc0_rate\\(10000\\)=0 conn_rate\\(10000\\)=1 http_req_cnt=1 http_req_rate\\(10000\\)=1 http_err_cnt=0 http_err_rate\\(10000\\)=0 http_fail_cnt=0 http_fail_rate\\(10000\\)=0)\\n$"
|
||||
} -wait
|
||||
|
@ -1777,10 +1777,10 @@ static enum act_return http_action_track_sc(struct act_rule *rule, struct proxy
|
||||
struct stktable *t;
|
||||
struct stksess *ts;
|
||||
struct stktable_key *key;
|
||||
void *ptr1, *ptr2, *ptr3, *ptr4;
|
||||
void *ptr1, *ptr2, *ptr3, *ptr4, *ptr5, *ptr6;
|
||||
int opt;
|
||||
|
||||
ptr1 = ptr2 = ptr3 = ptr4 = NULL;
|
||||
ptr1 = ptr2 = ptr3 = ptr4 = ptr5 = ptr6 = NULL;
|
||||
opt = ((rule->from == ACT_F_HTTP_REQ) ? SMP_OPT_DIR_REQ : SMP_OPT_DIR_RES) | SMP_OPT_FINAL;
|
||||
|
||||
t = rule->arg.trk_ctr.table.t;
|
||||
@ -1810,7 +1810,13 @@ static enum act_return http_action_track_sc(struct act_rule *rule, struct proxy
|
||||
ptr4 = stktable_data_ptr(t, ts, STKTABLE_DT_HTTP_ERR_RATE);
|
||||
}
|
||||
|
||||
if (ptr1 || ptr2 || ptr3 || ptr4) {
|
||||
if (rule->from == ACT_F_HTTP_RES && (unsigned)(s->txn->status - 500) < 100 &&
|
||||
s->txn->status != 501 && s->txn->status != 505) {
|
||||
ptr5 = stktable_data_ptr(t, ts, STKTABLE_DT_HTTP_FAIL_CNT);
|
||||
ptr6 = stktable_data_ptr(t, ts, STKTABLE_DT_HTTP_FAIL_RATE);
|
||||
}
|
||||
|
||||
if (ptr1 || ptr2 || ptr3 || ptr4 || ptr5 || ptr6) {
|
||||
HA_RWLOCK_WRLOCK(STK_SESS_LOCK, &ts->lock);
|
||||
|
||||
if (ptr1)
|
||||
@ -1823,6 +1829,11 @@ static enum act_return http_action_track_sc(struct act_rule *rule, struct proxy
|
||||
if (ptr4)
|
||||
update_freq_ctr_period(&stktable_data_cast(ptr4, http_err_rate),
|
||||
t->data_arg[STKTABLE_DT_HTTP_ERR_RATE].u, 1);
|
||||
if (ptr5)
|
||||
stktable_data_cast(ptr5, http_fail_cnt)++;
|
||||
if (ptr6)
|
||||
update_freq_ctr_period(&stktable_data_cast(ptr6, http_fail_rate),
|
||||
t->data_arg[STKTABLE_DT_HTTP_FAIL_RATE].u, 1);
|
||||
|
||||
HA_RWLOCK_WRUNLOCK(STK_SESS_LOCK, &ts->lock);
|
||||
|
||||
|
@ -1418,6 +1418,8 @@ int http_wait_for_response(struct stream *s, struct channel *rep, int an_bit)
|
||||
}
|
||||
txn->status = 425;
|
||||
}
|
||||
else
|
||||
stream_inc_http_fail_ctr(s);
|
||||
|
||||
s->si[1].flags |= SI_FL_NOLINGER;
|
||||
http_reply_and_close(s, txn->status, http_error_message(s));
|
||||
@ -1449,6 +1451,7 @@ int http_wait_for_response(struct stream *s, struct channel *rep, int an_bit)
|
||||
|
||||
rep->analysers &= AN_RES_FLT_END;
|
||||
txn->status = 504;
|
||||
stream_inc_http_fail_ctr(s);
|
||||
s->si[1].flags |= SI_FL_NOLINGER;
|
||||
http_reply_and_close(s, txn->status, http_error_message(s));
|
||||
|
||||
@ -1507,6 +1510,7 @@ int http_wait_for_response(struct stream *s, struct channel *rep, int an_bit)
|
||||
|
||||
rep->analysers &= AN_RES_FLT_END;
|
||||
txn->status = 502;
|
||||
stream_inc_http_fail_ctr(s);
|
||||
s->si[1].flags |= SI_FL_NOLINGER;
|
||||
http_reply_and_close(s, txn->status, http_error_message(s));
|
||||
|
||||
@ -1614,6 +1618,9 @@ int http_wait_for_response(struct stream *s, struct channel *rep, int an_bit)
|
||||
if (n == 4)
|
||||
stream_inc_http_err_ctr(s);
|
||||
|
||||
if (n == 5 && txn->status != 501 && txn->status != 505)
|
||||
stream_inc_http_fail_ctr(s);
|
||||
|
||||
if (objt_server(s->target)) {
|
||||
_HA_ATOMIC_ADD(&__objt_server(s->target)->counters.p.http.rsp[n], 1);
|
||||
_HA_ATOMIC_ADD(&__objt_server(s->target)->counters.p.http.cum_req, 1);
|
||||
@ -1784,6 +1791,7 @@ int http_wait_for_response(struct stream *s, struct channel *rep, int an_bit)
|
||||
return 0;
|
||||
}
|
||||
txn->status = 502;
|
||||
stream_inc_http_fail_ctr(s);
|
||||
/* fall through */
|
||||
|
||||
return_prx_cond:
|
||||
@ -2081,6 +2089,7 @@ int http_process_res_common(struct stream *s, struct channel *rep, int an_bit, s
|
||||
|
||||
return_bad_res:
|
||||
txn->status = 502;
|
||||
stream_inc_http_fail_ctr(s);
|
||||
_HA_ATOMIC_ADD(&s->be->be_counters.failed_resp, 1);
|
||||
if (objt_server(s->target)) {
|
||||
_HA_ATOMIC_ADD(&__objt_server(s->target)->counters.failed_resp, 1);
|
||||
@ -2331,6 +2340,7 @@ int http_response_forward_body(struct stream *s, struct channel *res, int an_bit
|
||||
_HA_ATOMIC_ADD(&sess->listener->counters->srv_aborts, 1);
|
||||
if (objt_server(s->target))
|
||||
_HA_ATOMIC_ADD(&__objt_server(s->target)->counters.srv_aborts, 1);
|
||||
stream_inc_http_fail_ctr(s);
|
||||
if (!(s->flags & SF_ERR_MASK))
|
||||
s->flags |= SF_ERR_SRVCL;
|
||||
goto return_error;
|
||||
@ -2363,6 +2373,7 @@ int http_response_forward_body(struct stream *s, struct channel *res, int an_bit
|
||||
_HA_ATOMIC_ADD(&__objt_server(s->target)->counters.failed_resp, 1);
|
||||
health_adjust(__objt_server(s->target), HANA_STATUS_HTTP_RSP);
|
||||
}
|
||||
stream_inc_http_fail_ctr(s);
|
||||
if (!(s->flags & SF_ERR_MASK))
|
||||
s->flags |= SF_ERR_SRVCL;
|
||||
/* fall through */
|
||||
|
@ -1075,6 +1075,8 @@ struct stktable_data_type stktable_data_types[STKTABLE_DATA_TYPES] = {
|
||||
[STKTABLE_DT_GPC1] = { .name = "gpc1", .std_type = STD_T_UINT },
|
||||
[STKTABLE_DT_GPC1_RATE] = { .name = "gpc1_rate", .std_type = STD_T_FRQP, .arg_type = ARG_T_DELAY },
|
||||
[STKTABLE_DT_SERVER_KEY] = { .name = "server_key", .std_type = STD_T_DICT },
|
||||
[STKTABLE_DT_HTTP_FAIL_CNT] = { .name = "http_fail_cnt", .std_type = STD_T_UINT },
|
||||
[STKTABLE_DT_HTTP_FAIL_RATE]= { .name = "http_fail_rate", .std_type = STD_T_FRQP, .arg_type = ARG_T_DELAY },
|
||||
};
|
||||
|
||||
/* Registers stick-table extra data type with index <idx>, name <name>, type
|
||||
@ -1593,6 +1595,79 @@ static int sample_conv_table_http_err_rate(const struct arg *arg_p, struct sampl
|
||||
return !!ptr;
|
||||
}
|
||||
|
||||
/* Casts sample <smp> to the type of the table specified in arg(0), and looks
|
||||
* it up into this table. Returns the cumulated number of HTTP response failures
|
||||
* for the key if the key is present in the table, otherwise zero, so that
|
||||
* comparisons can be easily performed. If the inspected parameter is not stored
|
||||
* in the table, <not found> is returned.
|
||||
*/
|
||||
static int sample_conv_table_http_fail_cnt(const struct arg *arg_p, struct sample *smp, void *private)
|
||||
{
|
||||
struct stktable *t;
|
||||
struct stktable_key *key;
|
||||
struct stksess *ts;
|
||||
void *ptr;
|
||||
|
||||
t = arg_p[0].data.t;
|
||||
|
||||
key = smp_to_stkey(smp, t);
|
||||
if (!key)
|
||||
return 0;
|
||||
|
||||
ts = stktable_lookup_key(t, key);
|
||||
|
||||
smp->flags = SMP_F_VOL_TEST;
|
||||
smp->data.type = SMP_T_SINT;
|
||||
smp->data.u.sint = 0;
|
||||
|
||||
if (!ts) /* key not present */
|
||||
return 1;
|
||||
|
||||
ptr = stktable_data_ptr(t, ts, STKTABLE_DT_HTTP_FAIL_CNT);
|
||||
if (ptr)
|
||||
smp->data.u.sint = stktable_data_cast(ptr, http_fail_cnt);
|
||||
|
||||
stktable_release(t, ts);
|
||||
return !!ptr;
|
||||
}
|
||||
|
||||
/* Casts sample <smp> to the type of the table specified in arg(0), and looks
|
||||
* it up into this table. Returns the HTTP response failure rate for the key
|
||||
* if the key is present in the table, otherwise zero, so that comparisons can
|
||||
* be easily performed. If the inspected parameter is not stored in the table,
|
||||
* <not found> is returned.
|
||||
*/
|
||||
static int sample_conv_table_http_fail_rate(const struct arg *arg_p, struct sample *smp, void *private)
|
||||
{
|
||||
struct stktable *t;
|
||||
struct stktable_key *key;
|
||||
struct stksess *ts;
|
||||
void *ptr;
|
||||
|
||||
t = arg_p[0].data.t;
|
||||
|
||||
key = smp_to_stkey(smp, t);
|
||||
if (!key)
|
||||
return 0;
|
||||
|
||||
ts = stktable_lookup_key(t, key);
|
||||
|
||||
smp->flags = SMP_F_VOL_TEST;
|
||||
smp->data.type = SMP_T_SINT;
|
||||
smp->data.u.sint = 0;
|
||||
|
||||
if (!ts) /* key not present */
|
||||
return 1;
|
||||
|
||||
ptr = stktable_data_ptr(t, ts, STKTABLE_DT_HTTP_FAIL_RATE);
|
||||
if (ptr)
|
||||
smp->data.u.sint = read_freq_ctr_period(&stktable_data_cast(ptr, http_fail_rate),
|
||||
t->data_arg[STKTABLE_DT_HTTP_FAIL_RATE].u);
|
||||
|
||||
stktable_release(t, ts);
|
||||
return !!ptr;
|
||||
}
|
||||
|
||||
/* Casts sample <smp> to the type of the table specified in arg(0), and looks
|
||||
* it up into this table. Returns the cumulated number of HTTP request for the
|
||||
* key if the key is present in the table, otherwise zero, so that comparisons
|
||||
@ -3154,6 +3229,85 @@ smp_fetch_sc_http_err_rate(const struct arg *args, struct sample *smp, const cha
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* set <smp> to the cumulated number of HTTP response failures from the stream's
|
||||
* tracked frontend counters. Supports being called as "sc[0-9]_http_fail_cnt" or
|
||||
* "src_http_fail_cnt" only.
|
||||
*/
|
||||
static int
|
||||
smp_fetch_sc_http_fail_cnt(const struct arg *args, struct sample *smp, const char *kw, void *private)
|
||||
{
|
||||
struct stkctr tmpstkctr;
|
||||
struct stkctr *stkctr;
|
||||
|
||||
stkctr = smp_fetch_sc_stkctr(smp->sess, smp->strm, args, kw, &tmpstkctr);
|
||||
if (!stkctr)
|
||||
return 0;
|
||||
|
||||
smp->flags = SMP_F_VOL_TEST;
|
||||
smp->data.type = SMP_T_SINT;
|
||||
smp->data.u.sint = 0;
|
||||
if (stkctr_entry(stkctr) != NULL) {
|
||||
void *ptr;
|
||||
|
||||
ptr = stktable_data_ptr(stkctr->table, stkctr_entry(stkctr), STKTABLE_DT_HTTP_FAIL_CNT);
|
||||
if (!ptr) {
|
||||
if (stkctr == &tmpstkctr)
|
||||
stktable_release(stkctr->table, stkctr_entry(stkctr));
|
||||
return 0; /* parameter not stored */
|
||||
}
|
||||
|
||||
HA_RWLOCK_RDLOCK(STK_SESS_LOCK, &stkctr_entry(stkctr)->lock);
|
||||
|
||||
smp->data.u.sint = stktable_data_cast(ptr, http_fail_cnt);
|
||||
|
||||
HA_RWLOCK_RDUNLOCK(STK_SESS_LOCK, &stkctr_entry(stkctr)->lock);
|
||||
|
||||
if (stkctr == &tmpstkctr)
|
||||
stktable_release(stkctr->table, stkctr_entry(stkctr));
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* set <smp> to the HTTP response failure rate from the stream's tracked frontend
|
||||
* counters. Supports being called as "sc[0-9]_http_fail_rate" or
|
||||
* "src_http_fail_rate" only.
|
||||
*/
|
||||
static int
|
||||
smp_fetch_sc_http_fail_rate(const struct arg *args, struct sample *smp, const char *kw, void *private)
|
||||
{
|
||||
struct stkctr tmpstkctr;
|
||||
struct stkctr *stkctr;
|
||||
|
||||
stkctr = smp_fetch_sc_stkctr(smp->sess, smp->strm, args, kw, &tmpstkctr);
|
||||
if (!stkctr)
|
||||
return 0;
|
||||
|
||||
smp->flags = SMP_F_VOL_TEST;
|
||||
smp->data.type = SMP_T_SINT;
|
||||
smp->data.u.sint = 0;
|
||||
if (stkctr_entry(stkctr) != NULL) {
|
||||
void *ptr;
|
||||
|
||||
ptr = stktable_data_ptr(stkctr->table, stkctr_entry(stkctr), STKTABLE_DT_HTTP_FAIL_RATE);
|
||||
if (!ptr) {
|
||||
if (stkctr == &tmpstkctr)
|
||||
stktable_release(stkctr->table, stkctr_entry(stkctr));
|
||||
return 0; /* parameter not stored */
|
||||
}
|
||||
|
||||
HA_RWLOCK_RDLOCK(STK_SESS_LOCK, &stkctr_entry(stkctr)->lock);
|
||||
|
||||
smp->data.u.sint = read_freq_ctr_period(&stktable_data_cast(ptr, http_fail_rate),
|
||||
stkctr->table->data_arg[STKTABLE_DT_HTTP_FAIL_RATE].u);
|
||||
|
||||
HA_RWLOCK_RDUNLOCK(STK_SESS_LOCK, &stkctr_entry(stkctr)->lock);
|
||||
|
||||
if (stkctr == &tmpstkctr)
|
||||
stktable_release(stkctr->table, stkctr_entry(stkctr));
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* set <smp> to the number of kbytes received from clients, as found in the
|
||||
* stream's tracked frontend counters. Supports being called as
|
||||
* "sc[0-9]_kbytes_in" or "src_kbytes_in" only.
|
||||
@ -3993,6 +4147,8 @@ static struct sample_fetch_kw_list smp_fetch_keywords = {ILH, {
|
||||
{ "sc_gpc1_rate", smp_fetch_sc_gpc1_rate, ARG2(1,SINT,TAB), NULL, SMP_T_SINT, SMP_USE_INTRN, },
|
||||
{ "sc_http_err_cnt", smp_fetch_sc_http_err_cnt, ARG2(1,SINT,TAB), NULL, SMP_T_SINT, SMP_USE_INTRN, },
|
||||
{ "sc_http_err_rate", smp_fetch_sc_http_err_rate, ARG2(1,SINT,TAB), NULL, SMP_T_SINT, SMP_USE_INTRN, },
|
||||
{ "sc_http_fail_cnt", smp_fetch_sc_http_fail_cnt, ARG2(1,SINT,TAB), NULL, SMP_T_SINT, SMP_USE_INTRN, },
|
||||
{ "sc_http_fail_rate", smp_fetch_sc_http_fail_rate, ARG2(1,SINT,TAB), NULL, SMP_T_SINT, SMP_USE_INTRN, },
|
||||
{ "sc_http_req_cnt", smp_fetch_sc_http_req_cnt, ARG2(1,SINT,TAB), NULL, SMP_T_SINT, SMP_USE_INTRN, },
|
||||
{ "sc_http_req_rate", smp_fetch_sc_http_req_rate, ARG2(1,SINT,TAB), NULL, SMP_T_SINT, SMP_USE_INTRN, },
|
||||
{ "sc_inc_gpc0", smp_fetch_sc_inc_gpc0, ARG2(1,SINT,TAB), NULL, SMP_T_SINT, SMP_USE_INTRN, },
|
||||
@ -4017,6 +4173,8 @@ static struct sample_fetch_kw_list smp_fetch_keywords = {ILH, {
|
||||
{ "sc0_gpc1_rate", smp_fetch_sc_gpc1_rate, ARG1(0,TAB), NULL, SMP_T_SINT, SMP_USE_INTRN, },
|
||||
{ "sc0_http_err_cnt", smp_fetch_sc_http_err_cnt, ARG1(0,TAB), NULL, SMP_T_SINT, SMP_USE_INTRN, },
|
||||
{ "sc0_http_err_rate", smp_fetch_sc_http_err_rate, ARG1(0,TAB), NULL, SMP_T_SINT, SMP_USE_INTRN, },
|
||||
{ "sc0_http_fail_cnt", smp_fetch_sc_http_fail_cnt, ARG1(0,TAB), NULL, SMP_T_SINT, SMP_USE_INTRN, },
|
||||
{ "sc0_http_fail_rate", smp_fetch_sc_http_fail_rate, ARG1(0,TAB), NULL, SMP_T_SINT, SMP_USE_INTRN, },
|
||||
{ "sc0_http_req_cnt", smp_fetch_sc_http_req_cnt, ARG1(0,TAB), NULL, SMP_T_SINT, SMP_USE_INTRN, },
|
||||
{ "sc0_http_req_rate", smp_fetch_sc_http_req_rate, ARG1(0,TAB), NULL, SMP_T_SINT, SMP_USE_INTRN, },
|
||||
{ "sc0_inc_gpc0", smp_fetch_sc_inc_gpc0, ARG1(0,TAB), NULL, SMP_T_SINT, SMP_USE_INTRN, },
|
||||
@ -4041,6 +4199,8 @@ static struct sample_fetch_kw_list smp_fetch_keywords = {ILH, {
|
||||
{ "sc1_gpc1_rate", smp_fetch_sc_gpc1_rate, ARG1(0,TAB), NULL, SMP_T_SINT, SMP_USE_INTRN, },
|
||||
{ "sc1_http_err_cnt", smp_fetch_sc_http_err_cnt, ARG1(0,TAB), NULL, SMP_T_SINT, SMP_USE_INTRN, },
|
||||
{ "sc1_http_err_rate", smp_fetch_sc_http_err_rate, ARG1(0,TAB), NULL, SMP_T_SINT, SMP_USE_INTRN, },
|
||||
{ "sc1_http_fail_cnt", smp_fetch_sc_http_fail_cnt, ARG1(0,TAB), NULL, SMP_T_SINT, SMP_USE_INTRN, },
|
||||
{ "sc1_http_fail_rate", smp_fetch_sc_http_fail_rate, ARG1(0,TAB), NULL, SMP_T_SINT, SMP_USE_INTRN, },
|
||||
{ "sc1_http_req_cnt", smp_fetch_sc_http_req_cnt, ARG1(0,TAB), NULL, SMP_T_SINT, SMP_USE_INTRN, },
|
||||
{ "sc1_http_req_rate", smp_fetch_sc_http_req_rate, ARG1(0,TAB), NULL, SMP_T_SINT, SMP_USE_INTRN, },
|
||||
{ "sc1_inc_gpc0", smp_fetch_sc_inc_gpc0, ARG1(0,TAB), NULL, SMP_T_SINT, SMP_USE_INTRN, },
|
||||
@ -4065,6 +4225,8 @@ static struct sample_fetch_kw_list smp_fetch_keywords = {ILH, {
|
||||
{ "sc2_gpc1_rate", smp_fetch_sc_gpc1_rate, ARG1(0,TAB), NULL, SMP_T_SINT, SMP_USE_INTRN, },
|
||||
{ "sc2_http_err_cnt", smp_fetch_sc_http_err_cnt, ARG1(0,TAB), NULL, SMP_T_SINT, SMP_USE_INTRN, },
|
||||
{ "sc2_http_err_rate", smp_fetch_sc_http_err_rate, ARG1(0,TAB), NULL, SMP_T_SINT, SMP_USE_INTRN, },
|
||||
{ "sc2_http_fail_cnt", smp_fetch_sc_http_fail_cnt, ARG1(0,TAB), NULL, SMP_T_SINT, SMP_USE_INTRN, },
|
||||
{ "sc2_http_fail_rate", smp_fetch_sc_http_fail_rate, ARG1(0,TAB), NULL, SMP_T_SINT, SMP_USE_INTRN, },
|
||||
{ "sc2_http_req_cnt", smp_fetch_sc_http_req_cnt, ARG1(0,TAB), NULL, SMP_T_SINT, SMP_USE_INTRN, },
|
||||
{ "sc2_http_req_rate", smp_fetch_sc_http_req_rate, ARG1(0,TAB), NULL, SMP_T_SINT, SMP_USE_INTRN, },
|
||||
{ "sc2_inc_gpc0", smp_fetch_sc_inc_gpc0, ARG1(0,TAB), NULL, SMP_T_SINT, SMP_USE_INTRN, },
|
||||
@ -4089,6 +4251,8 @@ static struct sample_fetch_kw_list smp_fetch_keywords = {ILH, {
|
||||
{ "src_gpc1_rate", smp_fetch_sc_gpc1_rate, ARG1(1,TAB), NULL, SMP_T_SINT, SMP_USE_L4CLI, },
|
||||
{ "src_http_err_cnt", smp_fetch_sc_http_err_cnt, ARG1(1,TAB), NULL, SMP_T_SINT, SMP_USE_L4CLI, },
|
||||
{ "src_http_err_rate", smp_fetch_sc_http_err_rate, ARG1(1,TAB), NULL, SMP_T_SINT, SMP_USE_L4CLI, },
|
||||
{ "src_http_fail_cnt", smp_fetch_sc_http_fail_cnt, ARG1(1,TAB), NULL, SMP_T_SINT, SMP_USE_L4CLI, },
|
||||
{ "src_http_fail_rate", smp_fetch_sc_http_fail_rate, ARG1(1,TAB), NULL, SMP_T_SINT, SMP_USE_L4CLI, },
|
||||
{ "src_http_req_cnt", smp_fetch_sc_http_req_cnt, ARG1(1,TAB), NULL, SMP_T_SINT, SMP_USE_L4CLI, },
|
||||
{ "src_http_req_rate", smp_fetch_sc_http_req_rate, ARG1(1,TAB), NULL, SMP_T_SINT, SMP_USE_L4CLI, },
|
||||
{ "src_inc_gpc0", smp_fetch_sc_inc_gpc0, ARG1(1,TAB), NULL, SMP_T_SINT, SMP_USE_L4CLI, },
|
||||
@ -4120,6 +4284,8 @@ static struct sample_conv_kw_list sample_conv_kws = {ILH, {
|
||||
{ "table_gpc1_rate", sample_conv_table_gpc1_rate, ARG1(1,TAB), NULL, SMP_T_ANY, SMP_T_SINT },
|
||||
{ "table_http_err_cnt", sample_conv_table_http_err_cnt, ARG1(1,TAB), NULL, SMP_T_ANY, SMP_T_SINT },
|
||||
{ "table_http_err_rate", sample_conv_table_http_err_rate, ARG1(1,TAB), NULL, SMP_T_ANY, SMP_T_SINT },
|
||||
{ "table_http_fail_cnt", sample_conv_table_http_fail_cnt, ARG1(1,TAB), NULL, SMP_T_ANY, SMP_T_SINT },
|
||||
{ "table_http_fail_rate", sample_conv_table_http_fail_rate, ARG1(1,TAB), NULL, SMP_T_ANY, SMP_T_SINT },
|
||||
{ "table_http_req_cnt", sample_conv_table_http_req_cnt, ARG1(1,TAB), NULL, SMP_T_ANY, SMP_T_SINT },
|
||||
{ "table_http_req_rate", sample_conv_table_http_req_rate, ARG1(1,TAB), NULL, SMP_T_ANY, SMP_T_SINT },
|
||||
{ "table_kbytes_in", sample_conv_table_kbytes_in, ARG1(1,TAB), NULL, SMP_T_ANY, SMP_T_SINT },
|
||||
|
Loading…
Reference in New Issue
Block a user