hugepages plugin: Implement the "ValuesPages", "ValuesBytes" and "ValuesPercentage...
authorFlorian Forster <octo@collectd.org>
Mon, 5 Sep 2016 11:21:45 +0000 (13:21 +0200)
committerFlorian Forster <octo@collectd.org>
Wed, 14 Sep 2016 18:38:52 +0000 (20:38 +0200)
src/collectd.conf.in
src/collectd.conf.pod
src/hugepages.c
src/types.db

index 6a207ab..345af3d 100644 (file)
 #</Plugin>
 
 #<Plugin hugepages>
-#    ReportPerNodeHP "true"
-#    ReportRootHP "true"
+#    ReportPerNodeHP  true
+#    ReportRootHP     true
+#    ValuesPages      true
+#    ValuesBytes      false
+#    ValuesPercentage false
 #</Plugin>
 
 #<Plugin interface>
index baef1c3..f244359 100644 (file)
@@ -2836,20 +2836,35 @@ options (default is enabled).
 
 =over 4
 
-=item B<ReportPerNodeHP> I<true>|I<false>
+=item B<ReportPerNodeHP> B<true>|B<false>
 
 If enabled, information will be collected from the hugepage
 counters in "/sys/devices/system/node/*/hugepages".
 This is used to check the per-node hugepage statistics on
 a NUMA system.
 
-=item B<ReportRootHP> I<true>|I<false>
+=item B<ReportRootHP> B<true>|B<false>
 
 If enabled, information will be collected from the hugepage
 counters in "/sys/kernel/mm/hugepages".
 This can be used on both NUMA and non-NUMA systems to check
 the overall hugepage statistics.
 
+=item B<ValuesPages> B<true>|B<false>
+
+Whether to report hugepages metrics in number of pages.
+Defaults to B<true>.
+
+=item B<ValuesBytes> B<false>|B<true>
+
+Whether to report hugepages metrics in bytes.
+Defaults to B<false>.
+
+=item B<ValuesPercentage> B<false>|B<true>
+
+Whether to report hugepages metrics as percentage.
+Defaults to B<false>.
+
 =back
 
 =head2 Plugin C<interface>
index b5acfba..957eedb 100644 (file)
@@ -36,6 +36,10 @@ static const char g_plugin_name[] = "hugepages";
 static _Bool g_flag_rpt_numa = 1;
 static _Bool g_flag_rpt_mm = 1;
 
+static _Bool values_pages = 1;
+static _Bool values_bytes = 0;
+static _Bool values_percent = 0;
+
 #define HP_HAVE_NR 0x01
 #define HP_HAVE_SURPLUS 0x02
 #define HP_HAVE_FREE 0x04
@@ -59,6 +63,12 @@ static int hp_config(oconfig_item_t *ci) {
       cf_util_get_boolean(child, &g_flag_rpt_numa);
     else if (strcasecmp("ReportRootHP", child->key) == 0)
       cf_util_get_boolean(child, &g_flag_rpt_mm);
+    else if (strcasecmp("ValuesPages", child->key) == 0)
+      cf_util_get_boolean(child, &values_pages);
+    else if (strcasecmp("ValuesBytes", child->key) == 0)
+      cf_util_get_boolean(child, &values_bytes);
+    else if (strcasecmp("ValuesPercentage", child->key) == 0)
+      cf_util_get_boolean(child, &values_percent);
     else
       ERROR("%s: Invalid configuration option: \"%s\".", g_plugin_name,
             child->key);
@@ -67,29 +77,45 @@ static int hp_config(oconfig_item_t *ci) {
   return (0);
 }
 
-static void submit_hp(const char *plug_inst, const char *type_instance,
-                      gauge_t free_value, gauge_t used_value) {
+static void submit_hp(const struct entry_info *info) {
   value_list_t vl = VALUE_LIST_INIT;
-  value_t values[] = {
-    { .gauge = free_value },
-    { .gauge = used_value },
-  };
 
-  vl.values = values;
-  vl.values_len = STATIC_ARRAY_SIZE (values);
+  vl.values = &(value_t) { .gauge = NAN };
+  vl.values_len = 1;
+
   sstrncpy(vl.host, hostname_g, sizeof(vl.host));
   sstrncpy(vl.plugin, g_plugin_name, sizeof(vl.plugin));
-  sstrncpy(vl.plugin_instance, plug_inst, sizeof(vl.plugin_instance));
-  sstrncpy(vl.type, "hugepages", sizeof(vl.type));
-
-  if (type_instance != NULL) {
-    sstrncpy(vl.type_instance, type_instance, sizeof(vl.type_instance));
+  if (info->node) {
+    ssnprintf(vl.plugin_instance, sizeof(vl.plugin_instance), "%s-%zuKb",
+              info->node, info->page_size_kb);
+  } else {
+    ssnprintf(vl.plugin_instance, sizeof(vl.plugin_instance), "%zuKb",
+              info->page_size_kb);
   }
 
-  DEBUG("submit_hp pl_inst:%s, inst_type %s, free=%lf, used=%lf", plug_inst,
-        type_instance, free_value, used_value);
+  /* ensure all metrics have the same timestamp */
+  vl.time = cdtime();
+
+  gauge_t free = info->free;
+  gauge_t used = (info->nr + info->surplus) - info->free;
 
-  plugin_dispatch_values(&vl);
+  if (values_pages) {
+    sstrncpy(vl.type, "vmpage_number", sizeof(vl.type));
+    plugin_dispatch_multivalue(&vl, /* store_percentage = */ 0, DS_TYPE_GAUGE,
+                               "free", free, "used", used, NULL);
+  }
+  if (values_bytes) {
+    gauge_t page_size = (gauge_t)(1024 * info->page_size_kb);
+    sstrncpy(vl.type, "memory", sizeof(vl.type));
+    plugin_dispatch_multivalue(&vl, /* store_percentage = */ 0, DS_TYPE_GAUGE,
+                               "free", free * page_size, "used",
+                               used * page_size, NULL);
+  }
+  if (values_percent) {
+    sstrncpy(vl.type, "percent", sizeof(vl.type));
+    plugin_dispatch_multivalue(&vl, /* store_percentage = */ 1, DS_TYPE_GAUGE,
+                               "free", free, "used", used, NULL);
+  }
 }
 
 static int read_hugepage_entry(const char *path, const char *entry,
@@ -131,8 +157,7 @@ static int read_hugepage_entry(const char *path, const char *entry,
 
   ssnprintf(type_instance, sizeof(type_instance), "free_used-%zukB",
             info->page_size_kb);
-  submit_hp(info->node, type_instance, info->free,
-            (info->nr + info->surplus) - info->free);
+  submit_hp(info);
 
   /* Reset flags so subsequent calls don't submit again. */
   info->flags = 0;
index 6ec7812..4f8d31c 100644 (file)
@@ -94,7 +94,6 @@ hash_collisions         value:DERIVE:0:U
 http_request_methods    value:DERIVE:0:U
 http_requests           value:DERIVE:0:U
 http_response_codes     value:DERIVE:0:U
-hugepages               free:GAUGE:0:4294967295, used:GAUGE:0:4294967295
 humidity                value:GAUGE:0:100
 if_collisions           value:DERIVE:0:U
 if_dropped              rx:DERIVE:0:U, tx:DERIVE:0:U