MEDIUM: stats: Be able to access a specific field into a stats module

It is now possible to selectively retrieve extra counters from stats
modules. H1, H2, QUIC and H3 fill_stats() callback functions are updated to
return a specific counter.
This commit is contained in:
Christopher Faulet 2024-01-29 16:35:19 +01:00
parent fd366a106b
commit 3246f863d6
8 changed files with 460 additions and 127 deletions

View File

@ -511,7 +511,7 @@ struct stats_module {
const char *name;
/* functor used to generate the stats module using counters provided through data parameter */
void (*fill_stats)(void *data, struct field *);
int (*fill_stats)(void *data, struct field *, unsigned int *);
struct name_desc *stats; /* name/description of stats provided by the module */
void *counters; /* initial values of allocated counters */

View File

@ -128,40 +128,114 @@ static struct h3_counters {
long long qpack_decoder_stream_error; /* total number of QPACK_DECODER_STREAM_ERROR errors received */
} h3_counters;
static void h3_fill_stats(void *data, struct field *stats)
static int h3_fill_stats(void *data, struct field *stats, unsigned int *selected_field)
{
struct h3_counters *counters = data;
unsigned int current_field = (selected_field != NULL ? *selected_field : 0);
/* h3 frame type counters */
stats[H3_ST_DATA] = mkf_u64(FN_COUNTER, counters->h3_data);
stats[H3_ST_HEADERS] = mkf_u64(FN_COUNTER, counters->h3_headers);
stats[H3_ST_CANCEL_PUSH] = mkf_u64(FN_COUNTER, counters->h3_cancel_push);
stats[H3_ST_PUSH_PROMISE] = mkf_u64(FN_COUNTER, counters->h3_push_promise);
stats[H3_ST_MAX_PUSH_ID] = mkf_u64(FN_COUNTER, counters->h3_max_push_id);
stats[H3_ST_GOAWAY] = mkf_u64(FN_COUNTER, counters->h3_goaway);
stats[H3_ST_SETTINGS] = mkf_u64(FN_COUNTER, counters->h3_settings);
/* h3 error counters */
stats[H3_ST_H3_NO_ERROR] = mkf_u64(FN_COUNTER, counters->h3_no_error);
stats[H3_ST_H3_GENERAL_PROTOCOL_ERROR] = mkf_u64(FN_COUNTER, counters->h3_general_protocol_error);
stats[H3_ST_H3_INTERNAL_ERROR] = mkf_u64(FN_COUNTER, counters->h3_internal_error);
stats[H3_ST_H3_STREAM_CREATION_ERROR] = mkf_u64(FN_COUNTER, counters->h3_stream_creation_error);
stats[H3_ST_H3_CLOSED_CRITICAL_STREAM] = mkf_u64(FN_COUNTER, counters->h3_closed_critical_stream);
stats[H3_ST_H3_FRAME_UNEXPECTED] = mkf_u64(FN_COUNTER, counters->h3_frame_unexpected);
stats[H3_ST_H3_FRAME_ERROR] = mkf_u64(FN_COUNTER, counters->h3_frame_error);
stats[H3_ST_H3_EXCESSIVE_LOAD] = mkf_u64(FN_COUNTER, counters->h3_excessive_load);
stats[H3_ST_H3_ID_ERROR] = mkf_u64(FN_COUNTER, counters->h3_id_error);
stats[H3_ST_H3_SETTINGS_ERROR] = mkf_u64(FN_COUNTER, counters->h3_settings_error);
stats[H3_ST_H3_MISSING_SETTINGS] = mkf_u64(FN_COUNTER, counters->h3_missing_settings);
stats[H3_ST_H3_REQUEST_REJECTED] = mkf_u64(FN_COUNTER, counters->h3_request_rejected);
stats[H3_ST_H3_REQUEST_CANCELLED] = mkf_u64(FN_COUNTER, counters->h3_request_cancelled);
stats[H3_ST_H3_REQUEST_INCOMPLETE] = mkf_u64(FN_COUNTER, counters->h3_request_incomplete);
stats[H3_ST_H3_MESSAGE_ERROR] = mkf_u64(FN_COUNTER, counters->h3_message_error);
stats[H3_ST_H3_CONNECT_ERROR] = mkf_u64(FN_COUNTER, counters->h3_connect_error);
stats[H3_ST_H3_VERSION_FALLBACK] = mkf_u64(FN_COUNTER, counters->h3_version_fallback);
/* QPACK error counters */
stats[H3_ST_QPACK_DECOMPRESSION_FAILED] = mkf_u64(FN_COUNTER, counters->qpack_decompression_failed);
stats[H3_ST_QPACK_ENCODER_STREAM_ERROR] = mkf_u64(FN_COUNTER, counters->qpack_encoder_stream_error);
stats[H3_ST_QPACK_DECODER_STREAM_ERROR] = mkf_u64(FN_COUNTER, counters->qpack_decoder_stream_error);
for (; current_field < H3_STATS_COUNT; current_field++) {
struct field metric = { 0 };
switch (current_field) {
/* h3 frame type counters */
case H3_ST_DATA:
metric = mkf_u64(FN_COUNTER, counters->h3_data);
break;
case H3_ST_HEADERS:
metric = mkf_u64(FN_COUNTER, counters->h3_headers);
break;
case H3_ST_CANCEL_PUSH:
metric = mkf_u64(FN_COUNTER, counters->h3_cancel_push);
break;
case H3_ST_PUSH_PROMISE:
metric = mkf_u64(FN_COUNTER, counters->h3_push_promise);
break;
case H3_ST_MAX_PUSH_ID:
metric = mkf_u64(FN_COUNTER, counters->h3_max_push_id);
break;
case H3_ST_GOAWAY:
metric = mkf_u64(FN_COUNTER, counters->h3_goaway);
break;
case H3_ST_SETTINGS:
metric = mkf_u64(FN_COUNTER, counters->h3_settings);
break;
/* h3 error counters */
case H3_ST_H3_NO_ERROR:
metric = mkf_u64(FN_COUNTER, counters->h3_no_error);
break;
case H3_ST_H3_GENERAL_PROTOCOL_ERROR:
metric = mkf_u64(FN_COUNTER, counters->h3_general_protocol_error);
break;
case H3_ST_H3_INTERNAL_ERROR:
metric = mkf_u64(FN_COUNTER, counters->h3_internal_error);
break;
case H3_ST_H3_STREAM_CREATION_ERROR:
metric = mkf_u64(FN_COUNTER, counters->h3_stream_creation_error);
break;
case H3_ST_H3_CLOSED_CRITICAL_STREAM:
metric = mkf_u64(FN_COUNTER, counters->h3_closed_critical_stream);
break;
case H3_ST_H3_FRAME_UNEXPECTED:
metric = mkf_u64(FN_COUNTER, counters->h3_frame_unexpected);
break;
case H3_ST_H3_FRAME_ERROR:
metric = mkf_u64(FN_COUNTER, counters->h3_frame_error);
break;
case H3_ST_H3_EXCESSIVE_LOAD:
metric = mkf_u64(FN_COUNTER, counters->h3_excessive_load);
break;
case H3_ST_H3_ID_ERROR:
metric = mkf_u64(FN_COUNTER, counters->h3_id_error);
break;
case H3_ST_H3_SETTINGS_ERROR:
metric = mkf_u64(FN_COUNTER, counters->h3_settings_error);
break;
case H3_ST_H3_MISSING_SETTINGS:
metric = mkf_u64(FN_COUNTER, counters->h3_missing_settings);
break;
case H3_ST_H3_REQUEST_REJECTED:
metric = mkf_u64(FN_COUNTER, counters->h3_request_rejected);
break;
case H3_ST_H3_REQUEST_CANCELLED:
metric = mkf_u64(FN_COUNTER, counters->h3_request_cancelled);
break;
case H3_ST_H3_REQUEST_INCOMPLETE:
metric = mkf_u64(FN_COUNTER, counters->h3_request_incomplete);
break;
case H3_ST_H3_MESSAGE_ERROR:
metric = mkf_u64(FN_COUNTER, counters->h3_message_error);
break;
case H3_ST_H3_CONNECT_ERROR:
metric = mkf_u64(FN_COUNTER, counters->h3_connect_error);
break;
case H3_ST_H3_VERSION_FALLBACK:
metric = mkf_u64(FN_COUNTER, counters->h3_version_fallback);
break;
/* QPACK error counters */
case H3_ST_QPACK_DECOMPRESSION_FAILED:
metric = mkf_u64(FN_COUNTER, counters->qpack_decompression_failed);
break;
case H3_ST_QPACK_ENCODER_STREAM_ERROR:
metric = mkf_u64(FN_COUNTER, counters->qpack_encoder_stream_error);
break;
case H3_ST_QPACK_DECODER_STREAM_ERROR:
metric = mkf_u64(FN_COUNTER, counters->qpack_decoder_stream_error);
break;
default:
/* not used for frontends. If a specific metric
* is requested, return an error. Otherwise continue.
*/
if (selected_field != NULL)
return 0;
continue;
}
stats[current_field] = metric;
if (selected_field != NULL)
break;
}
return 1;
}
struct stats_module h3_stats_module = {

View File

@ -264,21 +264,54 @@ static struct h1_counters {
#endif
} h1_counters;
static void h1_fill_stats(void *data, struct field *stats)
static int h1_fill_stats(void *data, struct field *stats, unsigned int *selected_field)
{
struct h1_counters *counters = data;
unsigned int current_field = (selected_field != NULL ? *selected_field : 0);
stats[H1_ST_OPEN_CONN] = mkf_u64(FN_GAUGE, counters->open_conns);
stats[H1_ST_OPEN_STREAM] = mkf_u64(FN_GAUGE, counters->open_streams);
stats[H1_ST_TOTAL_CONN] = mkf_u64(FN_COUNTER, counters->total_conns);
stats[H1_ST_TOTAL_STREAM] = mkf_u64(FN_COUNTER, counters->total_streams);
for (; current_field < H1_STATS_COUNT; current_field++) {
struct field metric = { 0 };
stats[H1_ST_BYTES_IN] = mkf_u64(FN_COUNTER, counters->bytes_in);
stats[H1_ST_BYTES_OUT] = mkf_u64(FN_COUNTER, counters->bytes_out);
switch (current_field) {
case H1_ST_OPEN_CONN:
metric = mkf_u64(FN_GAUGE, counters->open_conns);
break;
case H1_ST_OPEN_STREAM:
metric = mkf_u64(FN_GAUGE, counters->open_streams);
break;
case H1_ST_TOTAL_CONN:
metric = mkf_u64(FN_COUNTER, counters->total_conns);
break;
case H1_ST_TOTAL_STREAM:
metric = mkf_u64(FN_COUNTER, counters->total_streams);
break;
case H1_ST_BYTES_IN:
metric = mkf_u64(FN_COUNTER, counters->bytes_in);
break;
case H1_ST_BYTES_OUT:
metric = mkf_u64(FN_COUNTER, counters->bytes_out);
break;
#if defined(USE_LINUX_SPLICE)
stats[H1_ST_SPLICED_BYTES_IN] = mkf_u64(FN_COUNTER, counters->spliced_bytes_in);
stats[H1_ST_SPLICED_BYTES_OUT] = mkf_u64(FN_COUNTER, counters->spliced_bytes_out);
case H1_ST_SPLICED_BYTES_IN:
metric = mkf_u64(FN_COUNTER, counters->spliced_bytes_in);
break;
case H1_ST_SPLICED_BYTES_OUT:
metric = mkf_u64(FN_COUNTER, counters->spliced_bytes_out);
break;
#endif
default:
/* not used for frontends. If a specific metric
* is requested, return an error. Otherwise continue.
*/
if (selected_field != NULL)
return 0;
continue;
}
stats[current_field] = metric;
if (selected_field != NULL)
break;
}
return 1;
}
static struct stats_module h1_stats_module = {

View File

@ -355,25 +355,67 @@ static struct h2_counters {
long long total_streams; /* total number of streams */
} h2_counters;
static void h2_fill_stats(void *data, struct field *stats)
static int h2_fill_stats(void *data, struct field *stats, unsigned int *selected_field)
{
struct h2_counters *counters = data;
unsigned int current_field = (selected_field != NULL ? *selected_field : 0);
stats[H2_ST_HEADERS_RCVD] = mkf_u64(FN_COUNTER, counters->headers_rcvd);
stats[H2_ST_DATA_RCVD] = mkf_u64(FN_COUNTER, counters->data_rcvd);
stats[H2_ST_SETTINGS_RCVD] = mkf_u64(FN_COUNTER, counters->settings_rcvd);
stats[H2_ST_RST_STREAM_RCVD] = mkf_u64(FN_COUNTER, counters->rst_stream_rcvd);
stats[H2_ST_GOAWAY_RCVD] = mkf_u64(FN_COUNTER, counters->goaway_rcvd);
for (; current_field < H2_STATS_COUNT; current_field++) {
struct field metric = { 0 };
stats[H2_ST_CONN_PROTO_ERR] = mkf_u64(FN_COUNTER, counters->conn_proto_err);
stats[H2_ST_STRM_PROTO_ERR] = mkf_u64(FN_COUNTER, counters->strm_proto_err);
stats[H2_ST_RST_STREAM_RESP] = mkf_u64(FN_COUNTER, counters->rst_stream_resp);
stats[H2_ST_GOAWAY_RESP] = mkf_u64(FN_COUNTER, counters->goaway_resp);
stats[H2_ST_OPEN_CONN] = mkf_u64(FN_GAUGE, counters->open_conns);
stats[H2_ST_OPEN_STREAM] = mkf_u64(FN_GAUGE, counters->open_streams);
stats[H2_ST_TOTAL_CONN] = mkf_u64(FN_COUNTER, counters->total_conns);
stats[H2_ST_TOTAL_STREAM] = mkf_u64(FN_COUNTER, counters->total_streams);
switch (current_field) {
case H2_ST_HEADERS_RCVD:
metric = mkf_u64(FN_COUNTER, counters->headers_rcvd);
break;
case H2_ST_DATA_RCVD:
metric = mkf_u64(FN_COUNTER, counters->data_rcvd);
break;
case H2_ST_SETTINGS_RCVD:
metric = mkf_u64(FN_COUNTER, counters->settings_rcvd);
break;
case H2_ST_RST_STREAM_RCVD:
metric = mkf_u64(FN_COUNTER, counters->rst_stream_rcvd);
break;
case H2_ST_GOAWAY_RCVD:
metric = mkf_u64(FN_COUNTER, counters->goaway_rcvd);
break;
case H2_ST_CONN_PROTO_ERR:
metric = mkf_u64(FN_COUNTER, counters->conn_proto_err);
break;
case H2_ST_STRM_PROTO_ERR:
metric = mkf_u64(FN_COUNTER, counters->strm_proto_err);
break;
case H2_ST_RST_STREAM_RESP:
metric = mkf_u64(FN_COUNTER, counters->rst_stream_resp);
break;
case H2_ST_GOAWAY_RESP:
metric = mkf_u64(FN_COUNTER, counters->goaway_resp);
break;
case H2_ST_OPEN_CONN:
metric = mkf_u64(FN_GAUGE, counters->open_conns);
break;
case H2_ST_OPEN_STREAM:
metric = mkf_u64(FN_GAUGE, counters->open_streams);
break;
case H2_ST_TOTAL_CONN:
metric = mkf_u64(FN_COUNTER, counters->total_conns);
break;
case H2_ST_TOTAL_STREAM:
metric = mkf_u64(FN_COUNTER, counters->total_streams);
break;
default:
/* not used for frontends. If a specific metric
* is requested, return an error. Otherwise continue.
*/
if (selected_field != NULL)
return 0;
continue;
}
stats[current_field] = metric;
if (selected_field != NULL)
break;
}
return 1;
}
static struct stats_module h2_stats_module = {

View File

@ -90,53 +90,154 @@ static struct name_desc quic_stats[] = {
struct quic_counters quic_counters;
static void quic_fill_stats(void *data, struct field *stats)
static int quic_fill_stats(void *data, struct field *stats, unsigned int *selected_field)
{
struct quic_counters *counters = data;
unsigned int current_field = (selected_field != NULL ? *selected_field : 0);
stats[QUIC_ST_RXBUF_FULL] = mkf_u64(FN_COUNTER, counters->rxbuf_full);
stats[QUIC_ST_DROPPED_PACKET] = mkf_u64(FN_COUNTER, counters->dropped_pkt);
stats[QUIC_ST_DROPPED_PACKET_BUFOVERRUN] = mkf_u64(FN_COUNTER, counters->dropped_pkt_bufoverrun);
stats[QUIC_ST_DROPPED_PARSING] = mkf_u64(FN_COUNTER, counters->dropped_parsing);
stats[QUIC_ST_SOCKET_FULL] = mkf_u64(FN_COUNTER, counters->socket_full);
stats[QUIC_ST_SENDTO_ERR] = mkf_u64(FN_COUNTER, counters->sendto_err);
stats[QUIC_ST_SENDTO_ERR_UNKNWN] = mkf_u64(FN_COUNTER, counters->sendto_err_unknown);
stats[QUIC_ST_SENT_PACKET] = mkf_u64(FN_COUNTER, counters->sent_pkt);
stats[QUIC_ST_LOST_PACKET] = mkf_u64(FN_COUNTER, counters->lost_pkt);
stats[QUIC_ST_TOO_SHORT_INITIAL_DGRAM] = mkf_u64(FN_COUNTER, counters->too_short_initial_dgram);
stats[QUIC_ST_RETRY_SENT] = mkf_u64(FN_COUNTER, counters->retry_sent);
stats[QUIC_ST_RETRY_VALIDATED] = mkf_u64(FN_COUNTER, counters->retry_validated);
stats[QUIC_ST_RETRY_ERRORS] = mkf_u64(FN_COUNTER, counters->retry_error);
stats[QUIC_ST_HALF_OPEN_CONN] = mkf_u64(FN_GAUGE, counters->half_open_conn);
stats[QUIC_ST_HDSHK_FAIL] = mkf_u64(FN_COUNTER, counters->hdshk_fail);
stats[QUIC_ST_STATELESS_RESET_SENT] = mkf_u64(FN_COUNTER, counters->stateless_reset_sent);
/* Special events of interest */
stats[QUIC_ST_CONN_MIGRATION_DONE] = mkf_u64(FN_COUNTER, counters->conn_migration_done);
/* Transport errors */
stats[QUIC_ST_TRANSP_ERR_NO_ERROR] = mkf_u64(FN_COUNTER, counters->quic_transp_err_no_error);
stats[QUIC_ST_TRANSP_ERR_INTERNAL_ERROR] = mkf_u64(FN_COUNTER, counters->quic_transp_err_internal_error);
stats[QUIC_ST_TRANSP_ERR_CONNECTION_REFUSED] = mkf_u64(FN_COUNTER, counters->quic_transp_err_connection_refused);
stats[QUIC_ST_TRANSP_ERR_FLOW_CONTROL_ERROR] = mkf_u64(FN_COUNTER, counters->quic_transp_err_flow_control_error);
stats[QUIC_ST_TRANSP_ERR_STREAM_LIMIT_ERROR] = mkf_u64(FN_COUNTER, counters->quic_transp_err_stream_limit_error);
stats[QUIC_ST_TRANSP_ERR_STREAM_STATE_ERROR] = mkf_u64(FN_COUNTER, counters->quic_transp_err_stream_state_error);
stats[QUIC_ST_TRANSP_ERR_FINAL_SIZE_ERROR] = mkf_u64(FN_COUNTER, counters->quic_transp_err_final_size_error);
stats[QUIC_ST_TRANSP_ERR_FRAME_ENCODING_ERROR] = mkf_u64(FN_COUNTER, counters->quic_transp_err_frame_encoding_error);
stats[QUIC_ST_TRANSP_ERR_TRANSPORT_PARAMETER_ERROR] = mkf_u64(FN_COUNTER, counters->quic_transp_err_transport_parameter_error);
stats[QUIC_ST_TRANSP_ERR_CONNECTION_ID_LIMIT_ERROR] = mkf_u64(FN_COUNTER, counters->quic_transp_err_connection_id_limit);
stats[QUIC_ST_TRANSP_ERR_PROTOCOL_VIOLATION] = mkf_u64(FN_COUNTER, counters->quic_transp_err_protocol_violation);
stats[QUIC_ST_TRANSP_ERR_INVALID_TOKEN] = mkf_u64(FN_COUNTER, counters->quic_transp_err_invalid_token);
stats[QUIC_ST_TRANSP_ERR_APPLICATION_ERROR] = mkf_u64(FN_COUNTER, counters->quic_transp_err_application_error);
stats[QUIC_ST_TRANSP_ERR_CRYPTO_BUFFER_EXCEEDED] = mkf_u64(FN_COUNTER, counters->quic_transp_err_crypto_buffer_exceeded);
stats[QUIC_ST_TRANSP_ERR_KEY_UPDATE_ERROR] = mkf_u64(FN_COUNTER, counters->quic_transp_err_key_update_error);
stats[QUIC_ST_TRANSP_ERR_AEAD_LIMIT_REACHED] = mkf_u64(FN_COUNTER, counters->quic_transp_err_aead_limit_reached);
stats[QUIC_ST_TRANSP_ERR_NO_VIABLE_PATH] = mkf_u64(FN_COUNTER, counters->quic_transp_err_no_viable_path);
stats[QUIC_ST_TRANSP_ERR_CRYPTO_ERROR] = mkf_u64(FN_COUNTER, counters->quic_transp_err_crypto_error);
stats[QUIC_ST_TRANSP_ERR_UNKNOWN_ERROR] = mkf_u64(FN_COUNTER, counters->quic_transp_err_unknown_error);
/* Streams related counters */
stats[QUIC_ST_DATA_BLOCKED] = mkf_u64(FN_COUNTER, counters->data_blocked);
stats[QUIC_ST_STREAM_DATA_BLOCKED] = mkf_u64(FN_COUNTER, counters->stream_data_blocked);
stats[QUIC_ST_STREAMS_BLOCKED_BIDI] = mkf_u64(FN_COUNTER, counters->streams_blocked_bidi);
stats[QUIC_ST_STREAMS_BLOCKED_UNI] = mkf_u64(FN_COUNTER, counters->streams_blocked_uni);
for (; current_field < QUIC_STATS_COUNT; current_field++) {
struct field metric = { 0 };
switch (current_field) {
case QUIC_ST_RXBUF_FULL:
metric = mkf_u64(FN_COUNTER, counters->rxbuf_full);
break;
case QUIC_ST_DROPPED_PACKET:
metric = mkf_u64(FN_COUNTER, counters->dropped_pkt);
break;
case QUIC_ST_DROPPED_PACKET_BUFOVERRUN:
metric = mkf_u64(FN_COUNTER, counters->dropped_pkt_bufoverrun);
break;
case QUIC_ST_DROPPED_PARSING:
metric = mkf_u64(FN_COUNTER, counters->dropped_parsing);
break;
case QUIC_ST_SOCKET_FULL:
metric = mkf_u64(FN_COUNTER, counters->socket_full);
break;
case QUIC_ST_SENDTO_ERR:
metric = mkf_u64(FN_COUNTER, counters->sendto_err);
break;
case QUIC_ST_SENDTO_ERR_UNKNWN:
metric = mkf_u64(FN_COUNTER, counters->sendto_err_unknown);
break;
case QUIC_ST_SENT_PACKET:
metric = mkf_u64(FN_COUNTER, counters->sent_pkt);
break;
case QUIC_ST_LOST_PACKET:
metric = mkf_u64(FN_COUNTER, counters->lost_pkt);
break;
case QUIC_ST_TOO_SHORT_INITIAL_DGRAM:
metric = mkf_u64(FN_COUNTER, counters->too_short_initial_dgram);
break;
case QUIC_ST_RETRY_SENT:
metric = mkf_u64(FN_COUNTER, counters->retry_sent);
break;
case QUIC_ST_RETRY_VALIDATED:
metric = mkf_u64(FN_COUNTER, counters->retry_validated);
break;
case QUIC_ST_RETRY_ERRORS:
metric = mkf_u64(FN_COUNTER, counters->retry_error);
break;
case QUIC_ST_HALF_OPEN_CONN:
metric = mkf_u64(FN_GAUGE, counters->half_open_conn);
break;
case QUIC_ST_HDSHK_FAIL:
metric = mkf_u64(FN_COUNTER, counters->hdshk_fail);
break;
case QUIC_ST_STATELESS_RESET_SENT:
metric = mkf_u64(FN_COUNTER, counters->stateless_reset_sent);
break;
/* Special events of interest */
case QUIC_ST_CONN_MIGRATION_DONE:
metric = mkf_u64(FN_COUNTER, counters->conn_migration_done);
break;
/* Transport errors */
case QUIC_ST_TRANSP_ERR_NO_ERROR:
metric = mkf_u64(FN_COUNTER, counters->quic_transp_err_no_error);
break;
case QUIC_ST_TRANSP_ERR_INTERNAL_ERROR:
metric = mkf_u64(FN_COUNTER, counters->quic_transp_err_internal_error);
break;
case QUIC_ST_TRANSP_ERR_CONNECTION_REFUSED:
metric = mkf_u64(FN_COUNTER, counters->quic_transp_err_connection_refused);
break;
case QUIC_ST_TRANSP_ERR_FLOW_CONTROL_ERROR:
metric = mkf_u64(FN_COUNTER, counters->quic_transp_err_flow_control_error);
break;
case QUIC_ST_TRANSP_ERR_STREAM_LIMIT_ERROR:
metric = mkf_u64(FN_COUNTER, counters->quic_transp_err_stream_limit_error);
break;
case QUIC_ST_TRANSP_ERR_STREAM_STATE_ERROR:
metric = mkf_u64(FN_COUNTER, counters->quic_transp_err_stream_state_error);
break;
case QUIC_ST_TRANSP_ERR_FINAL_SIZE_ERROR:
metric = mkf_u64(FN_COUNTER, counters->quic_transp_err_final_size_error);
break;
case QUIC_ST_TRANSP_ERR_FRAME_ENCODING_ERROR:
metric = mkf_u64(FN_COUNTER, counters->quic_transp_err_frame_encoding_error);
break;
case QUIC_ST_TRANSP_ERR_TRANSPORT_PARAMETER_ERROR:
metric = mkf_u64(FN_COUNTER, counters->quic_transp_err_transport_parameter_error);
break;
case QUIC_ST_TRANSP_ERR_CONNECTION_ID_LIMIT_ERROR:
metric = mkf_u64(FN_COUNTER, counters->quic_transp_err_connection_id_limit);
break;
case QUIC_ST_TRANSP_ERR_PROTOCOL_VIOLATION:
metric = mkf_u64(FN_COUNTER, counters->quic_transp_err_protocol_violation);
break;
case QUIC_ST_TRANSP_ERR_INVALID_TOKEN:
metric = mkf_u64(FN_COUNTER, counters->quic_transp_err_invalid_token);
break;
case QUIC_ST_TRANSP_ERR_APPLICATION_ERROR:
metric = mkf_u64(FN_COUNTER, counters->quic_transp_err_application_error);
break;
case QUIC_ST_TRANSP_ERR_CRYPTO_BUFFER_EXCEEDED:
metric = mkf_u64(FN_COUNTER, counters->quic_transp_err_crypto_buffer_exceeded);
break;
case QUIC_ST_TRANSP_ERR_KEY_UPDATE_ERROR:
metric = mkf_u64(FN_COUNTER, counters->quic_transp_err_key_update_error);
break;
case QUIC_ST_TRANSP_ERR_AEAD_LIMIT_REACHED:
metric = mkf_u64(FN_COUNTER, counters->quic_transp_err_aead_limit_reached);
break;
case QUIC_ST_TRANSP_ERR_NO_VIABLE_PATH:
metric = mkf_u64(FN_COUNTER, counters->quic_transp_err_no_viable_path);
break;
case QUIC_ST_TRANSP_ERR_CRYPTO_ERROR:
metric = mkf_u64(FN_COUNTER, counters->quic_transp_err_crypto_error);
break;
case QUIC_ST_TRANSP_ERR_UNKNOWN_ERROR:
metric = mkf_u64(FN_COUNTER, counters->quic_transp_err_unknown_error);
break;
/* Streams related counters */
case QUIC_ST_DATA_BLOCKED:
metric = mkf_u64(FN_COUNTER, counters->data_blocked);
break;
case QUIC_ST_STREAM_DATA_BLOCKED:
metric = mkf_u64(FN_COUNTER, counters->stream_data_blocked);
break;
case QUIC_ST_STREAMS_BLOCKED_BIDI:
metric = mkf_u64(FN_COUNTER, counters->streams_blocked_bidi);
break;
case QUIC_ST_STREAMS_BLOCKED_UNI:
metric = mkf_u64(FN_COUNTER, counters->streams_blocked_uni);
break;
default:
/* not used for frontends. If a specific metric
* is requested, return an error. Otherwise continue.
*/
if (selected_field != NULL)
return 0;
continue;
}
stats[current_field] = metric;
if (selected_field != NULL)
break;
}
return 1;
}
struct stats_module quic_stats_module = {

View File

@ -114,26 +114,79 @@ static struct name_desc resolv_stats[] = {
static struct dns_counters dns_counters;
static void resolv_fill_stats(void *d, struct field *stats)
static int resolv_fill_stats(void *d, struct field *stats, unsigned int *selected_field)
{
struct dns_counters *counters = d;
stats[RSLV_STAT_ID] = mkf_str(FO_CONFIG, counters->id);
stats[RSLV_STAT_PID] = mkf_str(FO_CONFIG, counters->pid);
stats[RSLV_STAT_SENT] = mkf_u64(FN_GAUGE, counters->sent);
stats[RSLV_STAT_SND_ERROR] = mkf_u64(FN_GAUGE, counters->snd_error);
stats[RSLV_STAT_VALID] = mkf_u64(FN_GAUGE, counters->app.resolver.valid);
stats[RSLV_STAT_UPDATE] = mkf_u64(FN_GAUGE, counters->app.resolver.update);
stats[RSLV_STAT_CNAME] = mkf_u64(FN_GAUGE, counters->app.resolver.cname);
stats[RSLV_STAT_CNAME_ERROR] = mkf_u64(FN_GAUGE, counters->app.resolver.cname_error);
stats[RSLV_STAT_ANY_ERR] = mkf_u64(FN_GAUGE, counters->app.resolver.any_err);
stats[RSLV_STAT_NX] = mkf_u64(FN_GAUGE, counters->app.resolver.nx);
stats[RSLV_STAT_TIMEOUT] = mkf_u64(FN_GAUGE, counters->app.resolver.timeout);
stats[RSLV_STAT_REFUSED] = mkf_u64(FN_GAUGE, counters->app.resolver.refused);
stats[RSLV_STAT_OTHER] = mkf_u64(FN_GAUGE, counters->app.resolver.other);
stats[RSLV_STAT_INVALID] = mkf_u64(FN_GAUGE, counters->app.resolver.invalid);
stats[RSLV_STAT_TOO_BIG] = mkf_u64(FN_GAUGE, counters->app.resolver.too_big);
stats[RSLV_STAT_TRUNCATED] = mkf_u64(FN_GAUGE, counters->app.resolver.truncated);
stats[RSLV_STAT_OUTDATED] = mkf_u64(FN_GAUGE, counters->app.resolver.outdated);
unsigned int current_field = (selected_field != NULL ? *selected_field : 0);
for (; current_field < RSLV_STAT_END; current_field++) {
struct field metric = { 0 };
switch (current_field) {
case RSLV_STAT_ID:
metric = mkf_str(FO_CONFIG, counters->id);
break;
case RSLV_STAT_PID:
metric = mkf_str(FO_CONFIG, counters->pid);
break;
case RSLV_STAT_SENT:
metric = mkf_u64(FN_GAUGE, counters->sent);
break;
case RSLV_STAT_SND_ERROR:
metric = mkf_u64(FN_GAUGE, counters->snd_error);
break;
case RSLV_STAT_VALID:
metric = mkf_u64(FN_GAUGE, counters->app.resolver.valid);
break;
case RSLV_STAT_UPDATE:
metric = mkf_u64(FN_GAUGE, counters->app.resolver.update);
break;
case RSLV_STAT_CNAME:
metric = mkf_u64(FN_GAUGE, counters->app.resolver.cname);
break;
case RSLV_STAT_CNAME_ERROR:
metric = mkf_u64(FN_GAUGE, counters->app.resolver.cname_error);
break;
case RSLV_STAT_ANY_ERR:
metric = mkf_u64(FN_GAUGE, counters->app.resolver.any_err);
break;
case RSLV_STAT_NX:
metric = mkf_u64(FN_GAUGE, counters->app.resolver.nx);
break;
case RSLV_STAT_TIMEOUT:
metric = mkf_u64(FN_GAUGE, counters->app.resolver.timeout);
break;
case RSLV_STAT_REFUSED:
metric = mkf_u64(FN_GAUGE, counters->app.resolver.refused);
break;
case RSLV_STAT_OTHER:
metric = mkf_u64(FN_GAUGE, counters->app.resolver.other);
break;
case RSLV_STAT_INVALID:
metric = mkf_u64(FN_GAUGE, counters->app.resolver.invalid);
break;
case RSLV_STAT_TOO_BIG:
metric = mkf_u64(FN_GAUGE, counters->app.resolver.too_big);
break;
case RSLV_STAT_TRUNCATED:
metric = mkf_u64(FN_GAUGE, counters->app.resolver.truncated);
break;
case RSLV_STAT_OUTDATED:
metric = mkf_u64(FN_GAUGE, counters->app.resolver.outdated);
break;
default:
/* not used for frontends. If a specific metric
* is requested, return an error. Otherwise continue.
*/
if (selected_field != NULL)
return 0;
continue;
}
stats[current_field] = metric;
if (selected_field != NULL)
break;
}
return 1;
}
static struct stats_module rslv_stats_module = {
@ -2711,7 +2764,8 @@ static int stats_dump_resolv_to_buffer(struct stconn *sc,
list_for_each_entry(mod, stat_modules, list) {
struct counters_node *counters = EXTRA_COUNTERS_GET(ns->extra_counters, mod);
mod->fill_stats(counters, stats + idx);
if (!mod->fill_stats(counters, stats + idx, NULL))
continue;
idx += mod->stats_count;
}

View File

@ -172,13 +172,37 @@ static struct ssl_counters {
long long failed_handshake;
} ssl_counters;
static void ssl_fill_stats(void *data, struct field *stats)
static int ssl_fill_stats(void *data, struct field *stats, unsigned int *selected_field)
{
struct ssl_counters *counters = data;
unsigned int current_field = (selected_field != NULL ? *selected_field : 0);
stats[SSL_ST_SESS] = mkf_u64(FN_COUNTER, counters->sess);
stats[SSL_ST_REUSED_SESS] = mkf_u64(FN_COUNTER, counters->reused_sess);
stats[SSL_ST_FAILED_HANDSHAKE] = mkf_u64(FN_COUNTER, counters->failed_handshake);
for (; current_field < SSL_ST_STATS_COUNT; current_field++) {
struct field metric = { 0 };
switch (current_field) {
case SSL_ST_SESS:
metric = mkf_u64(FN_COUNTER, counters->sess);
break;
case SSL_ST_REUSED_SESS:
metric = mkf_u64(FN_COUNTER, counters->reused_sess);
break;
case SSL_ST_FAILED_HANDSHAKE:
metric = mkf_u64(FN_COUNTER, counters->failed_handshake);
break;
default:
/* not used for frontends. If a specific metric
* is requested, return an error. Otherwise continue.
*/
if (selected_field != NULL)
return 0;
continue;
}
stats[current_field] = metric;
if (selected_field != NULL)
break;
}
return 1;
}
static struct stats_module ssl_stats_module = {

View File

@ -1952,7 +1952,8 @@ static int stats_dump_fe_stats(struct stconn *sc, struct proxy *px)
}
counters = EXTRA_COUNTERS_GET(px->extra_counters_fe, mod);
mod->fill_stats(counters, stats + stats_count);
if (!mod->fill_stats(counters, stats + stats_count, NULL))
continue;
stats_count += mod->stats_count;
}
@ -2119,7 +2120,8 @@ static int stats_dump_li_stats(struct stconn *sc, struct proxy *px, struct liste
}
counters = EXTRA_COUNTERS_GET(l->extra_counters, mod);
mod->fill_stats(counters, stats + stats_count);
if (!mod->fill_stats(counters, stats + stats_count, NULL))
continue;
stats_count += mod->stats_count;
}
@ -2637,7 +2639,8 @@ static int stats_dump_sv_stats(struct stconn *sc, struct proxy *px, struct serve
}
counters = EXTRA_COUNTERS_GET(sv->extra_counters, mod);
mod->fill_stats(counters, stats + stats_count);
if (!mod->fill_stats(counters, stats + stats_count, NULL))
continue;
stats_count += mod->stats_count;
}
@ -2973,7 +2976,8 @@ static int stats_dump_be_stats(struct stconn *sc, struct proxy *px)
}
counters = EXTRA_COUNTERS_GET(px->extra_counters_be, mod);
mod->fill_stats(counters, stats + stats_count);
if (!mod->fill_stats(counters, stats + stats_count, NULL))
continue;
stats_count += mod->stats_count;
}
@ -5332,6 +5336,7 @@ void stats_register_module(struct stats_module *m)
stat_count[domain] += m->stats_count;
}
static int allocate_stats_px_postcheck(void)
{
struct stats_module *mod;