prom: add option to set stat name prefix 14/35214/6
authorFlorin Coras <fcoras@cisco.com>
Thu, 3 Feb 2022 23:17:21 +0000 (15:17 -0800)
committerFlorin Coras <florin.coras@gmail.com>
Thu, 3 Feb 2022 23:19:57 +0000 (23:19 +0000)
Type: improvement

Signed-off-by: Florin Coras <fcoras@cisco.com>
Change-Id: I8b40d4e935c9280ff89a3d0f8b30bd7beac1e08a

src/plugins/prom/prom.c
src/plugins/prom/prom.h
src/plugins/prom/prom_cli.c

index 77b739a..3fb3704 100644 (file)
 
 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;
 }
index baacc28..898e4c2 100644 (file)
@@ -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_ */
 
 /*
index 453e8a0..705e54a 100644 (file)
@@ -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 <n>] [used-only]"
+  .short_help = "prom [enable] [min-scrape-interval <n>] [used-only] "
+               "[all-stats] [stat-name-prefix <prefix>] "
                "[stat-patterns <patterns>...]",
   .function = prom_command_fn,
 };