From: Willy Tarreau Date: Wed, 29 May 2013 13:54:14 +0000 (+0200) Subject: MEDIUM: counters: add a new "gpc0_rate" counter in stick-tables X-Git-Tag: v1.5-dev19~29 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=ba2ffd18b5e6b70896c8ab024b8271e1309fe606;p=thirdparty%2Fhaproxy.git MEDIUM: counters: add a new "gpc0_rate" counter in stick-tables This counter is special in that instead of reporting the gpc0 cumulative count, it returns its increase rate over the configured period. --- diff --git a/doc/configuration.txt b/doc/configuration.txt index a031cde3d2..f9d7558828 100644 --- a/doc/configuration.txt +++ b/doc/configuration.txt @@ -6085,6 +6085,13 @@ stick-table type {ip | integer | string [len ] | binary [len ]} to put a special tag on some entries, for instance to note that a specific behaviour was detected and must be known for future matches. + - gpc0_rate() : increment rate of the first General Purpose Counter + over a period. It is a positive 32-bit integer integer which may be used + for anything. Just like , it counts events, but instead of keeping + a cumulative count, it maintains the rate at which the counter is + incremented. Most of the time it will be used to measure the frequency of + occurrence of certain events (eg: requests to a specific URL). + - conn_cnt : Connection Count. It is a positive 32-bit integer which counts the absolute number of connections received from clients which matched this entry. It does not mean the connections were accepted, just that @@ -8527,7 +8534,17 @@ sc1_get_gpc0 sc2_get_gpc0 sc3_get_gpc0 Returns the value of the first General Purpose Counter associated to the - currently tracked counters. See also src_get_gpc0 and sc1/sc2_inc_gpc0. + currently tracked counters. See also src_get_gpc0 and sc1/sc2/sc3_get_gpc0. + +sc1_gpc0_rate +sc2_gpc0_rate +sc3_gpc0_rate + Returns the average increment rate of the first General Purpose Counter + associated to the currently tracked counters. It reports the frequency + which the gpc0 counter was incremented over the configured period. See also + src_gpc0_rate, sc1/sc2/sc3_get_gpc0, and sc1/sc2/sc3_inc_gpc0. Note that the + "gpc0_rate" counter must be stored in the stick-table for a value to be + returned, as "gpc0" only holds the event count. sc1_http_err_cnt sc2_http_err_cnt @@ -8684,6 +8701,16 @@ src_get_gpc0() the designated stick-table. If the address is not found, zero is returned. See also sc1/sc2_get_gpc0 and src_inc_gpc0. +src_gpc0_rate +src_gpc0_rate(
) + Returns the average increment rate of the first General Purpose Counter + associated to the connection's source IPv4 address in the current proxy's + stick-table or in the designated stick-table. It reports the frequency + which the gpc0 counter was incremented over the configured period. See also + sc1/sc2/sc3_gpc0_rate, src_get_gpc0, and sc1/sc2/sc3_inc_gpc0. Note that the + "gpc0_rate" counter must be stored in the stick-table for a value to be + returned, as "gpc0" only holds the event count. + src_http_err_cnt src_http_err_cnt(
) Returns the cumulated number of HTTP errors from the current connection's @@ -10149,6 +10176,17 @@ The list of currently supported pattern fetch functions is the following : associated to the currently tracked counters. See also src_get_gpc0 and sc1/sc2_inc_gpc0. + sc1_gpc0_rate + sc2_gpc0_rate + sc3_gpc0_rate + Returns the average increment rate of the first General Purpose + Counter associated to the currently tracked counters. It reports + the frequency which the gpc0 counter was incremented over the + configured period. See also src_gpc0_rate, sc1/sc2/sc3_get_gpc0, + and sc1/sc2/sc3_inc_gpc0. Note that the "gpc0_rate" counter must + be stored in the stick-table for a value to be returned, as + "gpc0" only holds the event count. + sc1_http_err_cnt sc2_http_err_cnt sc3_http_err_cnt @@ -10326,6 +10364,16 @@ The list of currently supported pattern fetch functions is the following : the address is not found, zero is returned. See also sc1/sc2_get_gpc0 and src_inc_gpc0. + src_gpc0_rate([
]) + Returns the average increment rate of the first General Purpose + Counter associated to the connection's source IPv4 address in + the current proxy's stick-table or in the designated stick- + table. It reports the frequency which the gpc0 counter was + incremented over the configured period. See also src_gpc0_rate, + sc1/sc2/sc3_get_gpc0, and sc1/sc2/sc3_inc_gpc0. Note that the + "gpc0_rate" counter must be stored in the stick-table for a + value to be returned, as "gpc0" only holds the event count. + src_http_err_cnt([
]) Returns the cumulated number of HTTP errors from the current connection's source IPv4 address in the current proxy's diff --git a/include/types/stick_table.h b/include/types/stick_table.h index 520f57aed0..dcdc405cce 100644 --- a/include/types/stick_table.h +++ b/include/types/stick_table.h @@ -46,6 +46,7 @@ enum { enum { STKTABLE_DT_SERVER_ID, /* the server ID to use with this session if > 0 */ STKTABLE_DT_GPC0, /* General Purpose Counter 0 (unsigned 32-bit integer) */ + STKTABLE_DT_GPC0_RATE, /* General Purpose Counter 0's event rate */ STKTABLE_DT_CONN_CNT, /* cumulated number of connections */ STKTABLE_DT_CONN_RATE, /* incoming connection rate */ STKTABLE_DT_CONN_CUR, /* concurrent number of connections */ @@ -88,6 +89,7 @@ union stktable_data { /* types of each storable data */ int server_id; unsigned int gpc0; + struct freq_ctr_period gpc0_rate; unsigned int conn_cnt; struct freq_ctr_period conn_rate; unsigned int conn_cur; diff --git a/src/session.c b/src/session.c index 10d3feb19c..7437fe8b5b 100644 --- a/src/session.c +++ b/src/session.c @@ -2645,6 +2645,77 @@ smp_fetch_src_get_gpc0(struct proxy *px, struct session *l4, void *l7, unsigned return smp_fetch_get_gpc0(&px->table, smp, stktable_lookup_key(&px->table, key)); } +/* set temp integer to the General Purpose Counter 0's event rate in the stksess entry */ +static int +smp_fetch_gpc0_rate(struct stktable *table, struct sample *smp, struct stksess *ts) +{ + smp->flags = SMP_F_VOL_TEST; + smp->type = SMP_T_UINT; + smp->data.uint = 0; + if (ts != NULL) { + void *ptr = stktable_data_ptr(table, ts, STKTABLE_DT_GPC0_RATE); + if (!ptr) + return 0; /* parameter not stored */ + smp->data.uint = read_freq_ctr_period(&stktable_data_cast(ptr, gpc0_rate), + table->data_arg[STKTABLE_DT_GPC0_RATE].u); + } + return 1; +} + +/* set temp integer to the General Purpose Counter 0's event rate from the + * session's tracked frontend counters. + */ +static int +smp_fetch_sc1_gpc0_rate(struct proxy *px, struct session *l4, void *l7, unsigned int opt, + const struct arg *args, struct sample *smp) +{ + if (!l4->stkctr[0].entry) + return 0; + return smp_fetch_gpc0_rate(l4->stkctr[0].table, smp, l4->stkctr[0].entry); +} + +/* set temp integer to the General Purpose Counter 0's event rate from the + * session's tracked backend counters. + */ +static int +smp_fetch_sc2_gpc0_rate(struct proxy *px, struct session *l4, void *l7, unsigned int opt, + const struct arg *args, struct sample *smp) +{ + if (!l4->stkctr[1].entry) + return 0; + return smp_fetch_gpc0_rate(l4->stkctr[1].table, smp, l4->stkctr[1].entry); +} + +/* set temp integer to the General Purpose Counter 0's event rate from the + * session's tracked backend counters. + */ +static int +smp_fetch_sc3_gpc0_rate(struct proxy *px, struct session *l4, void *l7, unsigned int opt, + const struct arg *args, struct sample *smp) +{ + if (!l4->stkctr[2].entry) + return 0; + return smp_fetch_gpc0_rate(l4->stkctr[2].table, smp, l4->stkctr[2].entry); +} + +/* set temp integer to the General Purpose Counter 0's event rate from the + * session's source address in the table pointed to by expr. + * Accepts exactly 1 argument of type table. + */ +static int +smp_fetch_src_gpc0_rate(struct proxy *px, struct session *l4, void *l7, unsigned int opt, + const struct arg *args, struct sample *smp) +{ + struct stktable_key *key; + + key = addr_to_stktable_key(&l4->si[0].conn->addr.from); + if (!key) + return 0; + + px = args->data.prx; + return smp_fetch_gpc0_rate(&px->table, smp, stktable_lookup_key(&px->table, key)); +} + /* Increment the General Purpose Counter 0 value in the stksess entry and * return it into temp integer. */ @@ -2655,10 +2726,22 @@ smp_fetch_inc_gpc0(struct stktable *table, struct sample *smp, struct stksess *t smp->type = SMP_T_UINT; smp->data.uint = 0; if (ts != NULL) { - void *ptr = stktable_data_ptr(table, ts, STKTABLE_DT_GPC0); - if (!ptr) - return 0; /* parameter not stored */ - smp->data.uint = ++stktable_data_cast(ptr, gpc0); + void *ptr; + + /* First, update gpc0_rate if it's tracked. Second, update its + * gpc0 if tracked. Returns gpc0's value otherwise the curr_ctr. + */ + ptr = stktable_data_ptr(table, ts, STKTABLE_DT_GPC0_RATE); + if (ptr) { + update_freq_ctr_period(&stktable_data_cast(ptr, gpc0_rate), + table->data_arg[STKTABLE_DT_GPC0_RATE].u, 1); + smp->data.uint = (&stktable_data_cast(ptr, gpc0_rate))->curr_ctr; + } + + ptr = stktable_data_ptr(table, ts, STKTABLE_DT_GPC0); + if (ptr) + smp->data.uint = ++stktable_data_cast(ptr, gpc0); + } return 1; } @@ -3825,6 +3908,7 @@ static struct acl_kw_list acl_kws = {{ },{ { "sc1_conn_cur", NULL, acl_parse_int, acl_match_int }, { "sc1_conn_rate", NULL, acl_parse_int, acl_match_int }, { "sc1_get_gpc0", NULL, acl_parse_int, acl_match_int }, + { "sc1_gpc0_rate", NULL, acl_parse_int, acl_match_int }, { "sc1_http_err_cnt", NULL, acl_parse_int, acl_match_int }, { "sc1_http_err_rate", NULL, acl_parse_int, acl_match_int }, { "sc1_http_req_cnt", NULL, acl_parse_int, acl_match_int }, @@ -3842,6 +3926,7 @@ static struct acl_kw_list acl_kws = {{ },{ { "sc2_conn_cur", NULL, acl_parse_int, acl_match_int }, { "sc2_conn_rate", NULL, acl_parse_int, acl_match_int }, { "sc2_get_gpc0", NULL, acl_parse_int, acl_match_int }, + { "sc2_gpc0_rate", NULL, acl_parse_int, acl_match_int }, { "sc2_http_err_cnt", NULL, acl_parse_int, acl_match_int }, { "sc2_http_err_rate", NULL, acl_parse_int, acl_match_int }, { "sc2_http_req_cnt", NULL, acl_parse_int, acl_match_int }, @@ -3859,6 +3944,7 @@ static struct acl_kw_list acl_kws = {{ },{ { "sc3_conn_cur", NULL, acl_parse_int, acl_match_int }, { "sc3_conn_rate", NULL, acl_parse_int, acl_match_int }, { "sc3_get_gpc0", NULL, acl_parse_int, acl_match_int }, + { "sc3_gpc0_rate", NULL, acl_parse_int, acl_match_int }, { "sc3_http_err_cnt", NULL, acl_parse_int, acl_match_int }, { "sc3_http_err_rate", NULL, acl_parse_int, acl_match_int }, { "sc3_http_req_cnt", NULL, acl_parse_int, acl_match_int }, @@ -3876,6 +3962,7 @@ static struct acl_kw_list acl_kws = {{ },{ { "src_conn_cur", NULL, acl_parse_int, acl_match_int }, { "src_conn_rate", NULL, acl_parse_int, acl_match_int }, { "src_get_gpc0", NULL, acl_parse_int, acl_match_int }, + { "src_gpc0_rate", NULL, acl_parse_int, acl_match_int }, { "src_http_err_cnt", NULL, acl_parse_int, acl_match_int }, { "src_http_err_rate", NULL, acl_parse_int, acl_match_int }, { "src_http_req_cnt", NULL, acl_parse_int, acl_match_int }, @@ -3902,6 +3989,7 @@ static struct sample_fetch_kw_list smp_fetch_keywords = {{ },{ { "sc1_conn_cur", smp_fetch_sc1_conn_cur, 0, NULL, SMP_T_UINT, SMP_USE_INTRN, }, { "sc1_conn_rate", smp_fetch_sc1_conn_rate, 0, NULL, SMP_T_UINT, SMP_USE_INTRN, }, { "sc1_get_gpc0", smp_fetch_sc1_get_gpc0, 0, NULL, SMP_T_UINT, SMP_USE_INTRN, }, + { "sc1_gpc0_rate", smp_fetch_sc1_gpc0_rate, 0, NULL, SMP_T_UINT, SMP_USE_INTRN, }, { "sc1_http_err_cnt", smp_fetch_sc1_http_err_cnt, 0, NULL, SMP_T_UINT, SMP_USE_INTRN, }, { "sc1_http_err_rate", smp_fetch_sc1_http_err_rate, 0, NULL, SMP_T_UINT, SMP_USE_INTRN, }, { "sc1_http_req_cnt", smp_fetch_sc1_http_req_cnt, 0, NULL, SMP_T_UINT, SMP_USE_INTRN, }, @@ -3919,6 +4007,7 @@ static struct sample_fetch_kw_list smp_fetch_keywords = {{ },{ { "sc2_conn_cur", smp_fetch_sc2_conn_cur, 0, NULL, SMP_T_UINT, SMP_USE_INTRN, }, { "sc2_conn_rate", smp_fetch_sc2_conn_rate, 0, NULL, SMP_T_UINT, SMP_USE_INTRN, }, { "sc2_get_gpc0", smp_fetch_sc2_get_gpc0, 0, NULL, SMP_T_UINT, SMP_USE_INTRN, }, + { "sc2_gpc0_rate", smp_fetch_sc2_gpc0_rate, 0, NULL, SMP_T_UINT, SMP_USE_INTRN, }, { "sc2_http_err_cnt", smp_fetch_sc2_http_err_cnt, 0, NULL, SMP_T_UINT, SMP_USE_INTRN, }, { "sc2_http_err_rate", smp_fetch_sc2_http_err_rate, 0, NULL, SMP_T_UINT, SMP_USE_INTRN, }, { "sc2_http_req_cnt", smp_fetch_sc2_http_req_cnt, 0, NULL, SMP_T_UINT, SMP_USE_INTRN, }, @@ -3936,6 +4025,7 @@ static struct sample_fetch_kw_list smp_fetch_keywords = {{ },{ { "sc3_conn_cur", smp_fetch_sc3_conn_cur, 0, NULL, SMP_T_UINT, SMP_USE_INTRN, }, { "sc3_conn_rate", smp_fetch_sc3_conn_rate, 0, NULL, SMP_T_UINT, SMP_USE_INTRN, }, { "sc3_get_gpc0", smp_fetch_sc3_get_gpc0, 0, NULL, SMP_T_UINT, SMP_USE_INTRN, }, + { "sc3_gpc0_rate", smp_fetch_sc3_gpc0_rate, 0, NULL, SMP_T_UINT, SMP_USE_INTRN, }, { "sc3_http_err_cnt", smp_fetch_sc3_http_err_cnt, 0, NULL, SMP_T_UINT, SMP_USE_INTRN, }, { "sc3_http_err_rate", smp_fetch_sc3_http_err_rate, 0, NULL, SMP_T_UINT, SMP_USE_INTRN, }, { "sc3_http_req_cnt", smp_fetch_sc3_http_req_cnt, 0, NULL, SMP_T_UINT, SMP_USE_INTRN, }, @@ -3953,6 +4043,7 @@ static struct sample_fetch_kw_list smp_fetch_keywords = {{ },{ { "src_conn_cur", smp_fetch_src_conn_cur, ARG1(1,TAB), NULL, SMP_T_UINT, SMP_USE_L4CLI, }, { "src_conn_rate", smp_fetch_src_conn_rate, ARG1(1,TAB), NULL, SMP_T_UINT, SMP_USE_L4CLI, }, { "src_get_gpc0", smp_fetch_src_get_gpc0, ARG1(1,TAB), NULL, SMP_T_UINT, SMP_USE_L4CLI, }, + { "src_gpc0_rate", smp_fetch_src_gpc0_rate, ARG1(1,TAB), NULL, SMP_T_UINT, SMP_USE_L4CLI, }, { "src_http_err_cnt", smp_fetch_src_http_err_cnt, ARG1(1,TAB), NULL, SMP_T_UINT, SMP_USE_L4CLI, }, { "src_http_err_rate", smp_fetch_src_http_err_rate, ARG1(1,TAB), NULL, SMP_T_UINT, SMP_USE_L4CLI, }, { "src_http_req_cnt", smp_fetch_src_http_req_cnt, ARG1(1,TAB), NULL, SMP_T_UINT, SMP_USE_L4CLI, }, diff --git a/src/stick_table.c b/src/stick_table.c index 3097e662fe..c357b320b5 100644 --- a/src/stick_table.c +++ b/src/stick_table.c @@ -685,6 +685,7 @@ int stktable_compatible_sample(struct sample_expr *expr, unsigned long table_typ struct stktable_data_type stktable_data_types[STKTABLE_DATA_TYPES] = { [STKTABLE_DT_SERVER_ID] = { .name = "server_id", .std_type = STD_T_SINT }, [STKTABLE_DT_GPC0] = { .name = "gpc0", .std_type = STD_T_UINT }, + [STKTABLE_DT_GPC0_RATE] = { .name = "gpc0_rate", .std_type = STD_T_FRQP, .arg_type = ARG_T_DELAY }, [STKTABLE_DT_CONN_CNT] = { .name = "conn_cnt", .std_type = STD_T_UINT }, [STKTABLE_DT_CONN_RATE] = { .name = "conn_rate", .std_type = STD_T_FRQP, .arg_type = ARG_T_DELAY }, [STKTABLE_DT_CONN_CUR] = { .name = "conn_cur", .std_type = STD_T_UINT },