From 1a7344f7325e6fd37b89de60347b1618ae8e20eb Mon Sep 17 00:00:00 2001 From: Florin Coras Date: Thu, 3 Feb 2022 15:17:21 -0800 Subject: [PATCH] prom: add option to set stat name prefix Type: improvement Signed-off-by: Florin Coras Change-Id: I8b40d4e935c9280ff89a3d0f8b30bd7beac1e08a --- src/plugins/prom/prom.c | 91 ++++++++++++++++++++++++++++++++------------- src/plugins/prom/prom.h | 10 ++++- src/plugins/prom/prom_cli.c | 12 ++++-- 3 files changed, 83 insertions(+), 30 deletions(-) diff --git a/src/plugins/prom/prom.c b/src/plugins/prom/prom.c index 77b739a821b..3fb3704a9a0 100644 --- a/src/plugins/prom/prom.c +++ b/src/plugins/prom/prom.c @@ -22,17 +22,24 @@ static prom_main_t prom_main; -static char * -fix_spaces (char *s) +static u8 * +make_stat_name (char *name) { - char *p = s; + prom_main_t *pm = &prom_main; + char *p = name; + while (*p) { if (!isalnum (*p)) *p = '_'; p++; } - return s; + + /* Reuse vector, instead of always allocating, when building a name. */ + vec_reset_length (pm->name_scratch_pad); + pm->name_scratch_pad = + format (pm->name_scratch_pad, "%v%s", pm->stat_name_prefix, name); + return pm->name_scratch_pad; } static u8 * @@ -40,6 +47,9 @@ dump_counter_vector_simple (stat_segment_data_t *res, u8 *s, u8 used_only) { u8 need_header = 1; int j, k; + u8 *name; + + name = make_stat_name (res->name); for (k = 0; k < vec_len (res->simple_counter_vec); k++) for (j = 0; j < vec_len (res->simple_counter_vec[k]); j++) @@ -48,13 +58,13 @@ dump_counter_vector_simple (stat_segment_data_t *res, u8 *s, u8 used_only) continue; if (need_header) { - s = format (s, "# TYPE %s counter\n", fix_spaces (res->name)); + s = format (s, "# TYPE %v counter\n", name); need_header = 0; } - s = - format (s, "%s{thread=\"%d\",interface=\"%d\"} %lld\n", - fix_spaces (res->name), k, j, res->simple_counter_vec[k][j]); + s = format (s, "%v{thread=\"%d\",interface=\"%d\"} %lld\n", name, k, j, + res->simple_counter_vec[k][j]); } + return s; } @@ -63,6 +73,9 @@ dump_counter_vector_combined (stat_segment_data_t *res, u8 *s, u8 used_only) { u8 need_header = 1; int j, k; + u8 *name; + + name = make_stat_name (res->name); for (k = 0; k < vec_len (res->simple_counter_vec); k++) for (j = 0; j < vec_len (res->combined_counter_vec[k]); j++) @@ -71,18 +84,14 @@ dump_counter_vector_combined (stat_segment_data_t *res, u8 *s, u8 used_only) continue; if (need_header) { - s = format (s, "# TYPE %s_packets counter\n", - fix_spaces (res->name)); - s = - format (s, "# TYPE %s_bytes counter\n", fix_spaces (res->name)); + s = format (s, "# TYPE %v_packets counter\n", name); + s = format (s, "# TYPE %v_bytes counter\n", name); need_header = 0; } - s = format (s, "%s_packets{thread=\"%d\",interface=\"%d\"} %lld\n", - fix_spaces (res->name), k, j, - res->combined_counter_vec[k][j].packets); - s = format (s, "%s_bytes{thread=\"%d\",interface=\"%d\"} %lld\n", - fix_spaces (res->name), k, j, - res->combined_counter_vec[k][j].bytes); + s = format (s, "%v_packets{thread=\"%d\",interface=\"%d\"} %lld\n", + name, k, j, res->combined_counter_vec[k][j].packets); + s = format (s, "%v_bytes{thread=\"%d\",interface=\"%d\"} %lld\n", name, + k, j, res->combined_counter_vec[k][j].bytes); } return s; @@ -91,15 +100,18 @@ dump_counter_vector_combined (stat_segment_data_t *res, u8 *s, u8 used_only) static u8 * dump_error_index (stat_segment_data_t *res, u8 *s, u8 used_only) { + u8 *name; int j; + name = make_stat_name (res->name); + for (j = 0; j < vec_len (res->error_vector); j++) { if (used_only && !res->error_vector[j]) continue; - s = format (s, "# TYPE %s counter\n", fix_spaces (res->name)); - s = format (s, "%s{thread=\"%d\"} %lld\n", fix_spaces (res->name), j, - res->error_vector[j]); + s = format (s, "# TYPE %v counter\n", name); + s = + format (s, "%v{thread=\"%d\"} %lld\n", name, j, res->error_vector[j]); } return s; @@ -108,11 +120,15 @@ dump_error_index (stat_segment_data_t *res, u8 *s, u8 used_only) static u8 * dump_scalar_index (stat_segment_data_t *res, u8 *s, u8 used_only) { + u8 *name; + if (used_only && !res->scalar_value) return s; - s = format (s, "# TYPE %s counter\n", fix_spaces (res->name)); - s = format (s, "%s %.2f\n", fix_spaces (res->name), res->scalar_value); + name = make_stat_name (res->name); + + s = format (s, "# TYPE %v counter\n", name); + s = format (s, "%v %.2f\n", name, res->scalar_value); return s; } @@ -120,12 +136,15 @@ dump_scalar_index (stat_segment_data_t *res, u8 *s, u8 used_only) static u8 * dump_name_vector (stat_segment_data_t *res, u8 *s, u8 used_only) { + u8 *name; int k; - s = format (s, "# TYPE %s_info gauge\n", fix_spaces (res->name)); + name = make_stat_name (res->name); + + s = format (s, "# TYPE %v_info gauge\n", name); for (k = 0; k < vec_len (res->name_vector); k++) - s = format (s, "%s_info{index=\"%d\",name=\"%s\"} 1\n", - fix_spaces (res->name), k, res->name_vector[k]); + s = format (s, "%v_info{index=\"%d\",name=\"%s\"} 1\n", name, k, + res->name_vector[k]); return s; } @@ -348,6 +367,23 @@ prom_stat_patterns_get (void) return prom_main.stats_patterns; } +void +prom_stat_name_prefix_set (u8 *prefix) +{ + prom_main_t *pm = &prom_main; + + vec_free (pm->stat_name_prefix); + pm->stat_name_prefix = prefix; +} + +void +prom_report_used_only (u8 used_only) +{ + prom_main_t *pm = &prom_main; + + pm->used_only = used_only; +} + static void prom_stat_segment_client_init (void) { @@ -375,6 +411,8 @@ prom_enable (vlib_main_t *vm) pm->is_enabled = 1; pm->vm = vm; + if (!pm->stat_name_prefix) + pm->stat_name_prefix = format (0, "vpp"); prom_scraper_process_enable (vm); prom_stat_segment_client_init (); @@ -388,6 +426,7 @@ prom_init (vlib_main_t *vm) pm->is_enabled = 0; pm->min_scrape_interval = 1; pm->used_only = 0; + pm->stat_name_prefix = 0; return 0; } diff --git a/src/plugins/prom/prom.h b/src/plugins/prom/prom.h index baacc28a26a..898e4c209d1 100644 --- a/src/plugins/prom/prom.h +++ b/src/plugins/prom/prom.h @@ -27,11 +27,16 @@ typedef struct prom_main_ hss_session_send_fn send_data; u32 scraper_node_index; u8 is_enabled; + u8 *name_scratch_pad; + vlib_main_t *vm; + /* + * Configs + */ u8 **stats_patterns; + u8 *stat_name_prefix; f64 min_scrape_interval; u8 used_only; - vlib_main_t *vm; } prom_main_t; typedef enum prom_process_evt_codes_ @@ -47,6 +52,9 @@ void prom_stat_patterns_add (u8 **patterns); u8 **prom_stat_patterns_get (void); void prom_stat_patterns_free (void); +void prom_stat_name_prefix_set (u8 *prefix); +void prom_report_used_only (u8 used_only); + #endif /* SRC_PLUGINS_PROM_PROM_H_ */ /* diff --git a/src/plugins/prom/prom_cli.c b/src/plugins/prom/prom_cli.c index 453e8a066fc..705e54ac1b8 100644 --- a/src/plugins/prom/prom_cli.c +++ b/src/plugins/prom/prom_cli.c @@ -90,9 +90,9 @@ prom_command_fn (vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd) { unformat_input_t _line_input, *line_input = &_line_input; + u8 **patterns = 0, *stat_name_prefix = 0; prom_main_t *pm = prom_get_main (); clib_error_t *error = 0; - u8 **patterns = 0; u8 is_enable = 0; if (!unformat_user (input, unformat_line_input, line_input)) @@ -106,7 +106,12 @@ prom_command_fn (vlib_main_t *vm, unformat_input_t *input, &pm->min_scrape_interval)) ; else if (unformat (line_input, "used-only")) - pm->used_only = 1; + prom_report_used_only (1 /* used only */); + else if (unformat (line_input, "all-stats")) + prom_report_used_only (0 /* used only */); + else if (unformat (line_input, "stat-name-prefix %_%v%_", + &stat_name_prefix)) + prom_stat_name_prefix_set (stat_name_prefix); else if (unformat (line_input, "stat-patterns %U", unformat_stats_patterns, &patterns)) prom_stat_patterns_set (patterns); @@ -133,7 +138,8 @@ no_input: VLIB_CLI_COMMAND (prom_enable_command, static) = { .path = "prom", - .short_help = "prom [enable] [min-scrape-interval ] [used-only]" + .short_help = "prom [enable] [min-scrape-interval ] [used-only] " + "[all-stats] [stat-name-prefix ] " "[stat-patterns ...]", .function = prom_command_fn, }; -- 2.16.6