]> git.ipfire.org Git - thirdparty/collectd.git/commitdiff
buddyinfo plugin: new plugin for memory fragmentation info
authorAsaf Kahlon <asafka7@gmail.com>
Sat, 12 Oct 2019 18:20:11 +0000 (21:20 +0300)
committerAsaf Kahlon <asafka7@gmail.com>
Sat, 12 Oct 2019 18:20:11 +0000 (21:20 +0300)
Signed-off-by: Asaf Kahlon <asafka7@gmail.com>
AUTHORS
Makefile.am
README
configure.ac
src/buddyinfo.c [new file with mode: 0644]
src/collectd.conf.in
src/collectd.conf.pod
src/types.db

diff --git a/AUTHORS b/AUTHORS
index d8548d1b47f6cdcf1bd777735369f240ea2cd76c..ef4ca5d0494e5e733eaaa66661cca5719150c799 100644 (file)
--- a/AUTHORS
+++ b/AUTHORS
@@ -70,7 +70,7 @@ Aneesh Puttur <aputtur at redhat.com>
 
 Andy Smith <ansmith at redhat.com>
  - AMQP 1.0 plugin.
+
 Aneesh Puttur <aputtur at redhat.com>
  - connectivity plugin.
 
@@ -83,6 +83,9 @@ Anthony Gialluca <tonyabg at charter.net>
 Antony Dovgal <tony at daylessday.org>
  - memcached plugin.
 
+Asaf Kahlon <asafka7 at gmail.com>
+ - buddyinfo plugin
+
 AurĂ©lien Reynaud <collectd at wattapower.net>
  - LPAR plugin.
  - Various fixes for AIX, HP-UX and Solaris.
index bdb95a1b367eca87908eac31f097968769c24b68..169f85ca81e42f9c3f5769f67d8434a7c79e0bef 100644 (file)
@@ -746,6 +746,13 @@ bind_la_LDFLAGS = $(PLUGIN_LDFLAGS)
 bind_la_LIBADD = $(BUILD_WITH_LIBCURL_LIBS) $(BUILD_WITH_LIBXML2_LIBS)
 endif
 
+if BUILD_PLUGIN_BUDDYINFO
+pkglib_LTLIBRARIES += buddyinfo.la
+buddyinfo_la_SOURCES = src/buddyinfo.c
+buddyinfo_la_LDFLAGS = $(PLUGIN_LDFLAGS)
+buddyinfo_la_LIBADD = libignorelist.la
+endif
+
 if BUILD_PLUGIN_CEPH
 pkglib_LTLIBRARIES += ceph.la
 ceph_la_SOURCES = src/ceph.c
diff --git a/README b/README
index f77efd219583ee1f72589ce12ff98b04c40a1407..017cb51e1deeb69989def82b056297c492d1f492 100644 (file)
--- a/README
+++ b/README
@@ -45,6 +45,9 @@ Features
       Name server and resolver statistics from the `statistics-channel'
       interface of BIND 9.5, 9,6 and later.
 
+    - buddyinfo
+      Statistics from buddyinfo file about memory fragmentation.
+
     - ceph
       Statistics from the Ceph distributed storage system.
 
index 4e585bd2165c2c73d0b728a56b2d0ebc38959403..631616bb188921f98a8edb9547bf03765805aef8 100644 (file)
@@ -6371,6 +6371,7 @@ plugin_ascent="no"
 plugin_barometer="no"
 plugin_battery="no"
 plugin_bind="no"
+plugin_buddyinfo="no"
 plugin_ceph="no"
 plugin_cgroups="no"
 plugin_connectivity="no"
@@ -6443,6 +6444,7 @@ plugin_zookeeper="no"
 # Linux
 if test "x$ac_system" = "xLinux"; then
   plugin_battery="yes"
+  plugin_buddyinfo="yes"
   plugin_cgroups="yes"
   plugin_conntrack="yes"
   plugin_contextswitch="yes"
@@ -6803,6 +6805,7 @@ AC_PLUGIN([ascent],              [$plugin_ascent],            [AscentEmu player
 AC_PLUGIN([barometer],           [$plugin_barometer],         [Barometer sensor on I2C])
 AC_PLUGIN([battery],             [$plugin_battery],           [Battery statistics])
 AC_PLUGIN([bind],                [$plugin_bind],              [ISC Bind nameserver statistics])
+AC_PLUGIN([buddyinfo],           [$plugin_buddyinfo],         [buddyinfo statistics])
 AC_PLUGIN([ceph],                [$plugin_ceph],              [Ceph daemon statistics])
 AC_PLUGIN([cgroups],             [$plugin_cgroups],           [CGroups CPU usage accounting])
 AC_PLUGIN([chrony],              [yes],                       [Chrony statistics])
@@ -7236,6 +7239,7 @@ AC_MSG_RESULT([    ascent  . . . . . . . $enable_ascent])
 AC_MSG_RESULT([    barometer . . . . . . $enable_barometer])
 AC_MSG_RESULT([    battery . . . . . . . $enable_battery])
 AC_MSG_RESULT([    bind  . . . . . . . . $enable_bind])
+AC_MSG_RESULT([    buddyinfo . . . . . . $enable_buddyinfo])
 AC_MSG_RESULT([    ceph  . . . . . . . . $enable_ceph])
 AC_MSG_RESULT([    cgroups . . . . . . . $enable_cgroups])
 AC_MSG_RESULT([    chrony. . . . . . . . $enable_chrony])
diff --git a/src/buddyinfo.c b/src/buddyinfo.c
new file mode 100644 (file)
index 0000000..5b0de52
--- /dev/null
@@ -0,0 +1,110 @@
+/**
+ * collectd - src/buddyinfo.c
+ * Copyright (C) 2005-2010  Florian octo Forster
+ * Copyright (C) 2009       Manuel Sanmartin
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; only version 2 of the License is applicable.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+ *
+ * Authors:
+ *   Asaf Kahlon <asafka7 at gmail.com>
+ **/
+
+#include "collectd.h"
+
+#include "plugin.h"
+#include "utils/common/common.h"
+#include "utils/ignorelist/ignorelist.h"
+
+#if !KERNEL_LINUX
+#error "No applicable input method."
+#endif
+
+#include <unistd.h>
+
+#define MAX_ORDER 11
+#define BUDDYINFO_FIELDS MAX_ORDER + 2 // "zone" + Name + (MAX_ORDER entries)
+#define NUM_OF_KB(pagesize, order) ((pagesize) / 1024) * (1 << (order))
+
+static const char *config_keys[] = {"Zone"};
+static int config_keys_num = STATIC_ARRAY_SIZE(config_keys);
+
+static ignorelist_t *ignorelist;
+
+static int buddyinfo_config(const char *key, const char *value) {
+  if (ignorelist == NULL)
+    ignorelist = ignorelist_create(1);
+
+  if (strcasecmp(key, "Zone") == 0)
+    ignorelist_add(ignorelist, value);
+  else
+    return -1;
+
+  return 0;
+}
+
+static void buddyinfo_submit(const char *zone, const char *size,
+                             const int freepages) {
+  value_list_t vl = VALUE_LIST_INIT;
+  value_t value = {.gauge = freepages};
+
+  if (ignorelist_match(ignorelist, zone) != 0)
+    return;
+
+  vl.values = &value;
+  vl.values_len = 1;
+  sstrncpy(vl.plugin, "buddyinfo", sizeof(vl.plugin));
+  sstrncpy(vl.plugin_instance, zone, sizeof(vl.plugin_instance));
+  sstrncpy(vl.type, "freepages", sizeof(vl.type));
+  sstrncpy(vl.type_instance, size, sizeof(vl.type_instance));
+
+  plugin_dispatch_values(&vl);
+}
+
+static int buddyinfo_read(void) {
+  FILE *fh;
+  char buffer[1024], pagesize_kb[8];
+  char *dummy, *zone;
+  char *fields[BUDDYINFO_FIELDS];
+  int numfields, pagesize = getpagesize();
+
+  if ((fh = fopen("/proc/buddyinfo", "r")) == NULL) {
+    WARNING("buddyinfo plugin: fopen: %s", STRERRNO);
+    return -1;
+  }
+
+  while (fgets(buffer, sizeof(buffer), fh) != NULL) {
+    if (!(dummy = strstr(buffer, "zone")))
+      continue;
+
+    numfields = strsplit(dummy, fields, BUDDYINFO_FIELDS);
+    if (numfields != BUDDYINFO_FIELDS)
+      continue;
+
+    zone = fields[1];
+    for (int i = 1; i <= MAX_ORDER; i++) {
+      ssnprintf(pagesize_kb, sizeof(pagesize_kb), "%dKB",
+                NUM_OF_KB(pagesize, i - 1));
+      buddyinfo_submit(zone, pagesize_kb, atoll(fields[i + 1]));
+    }
+  }
+
+  fclose(fh);
+  return 0;
+}
+
+void module_register(void) {
+  plugin_register_config("buddyinfo", buddyinfo_config, config_keys,
+                         config_keys_num);
+  plugin_register_read("buddyinfo", buddyinfo_read);
+}
index a194b4752bf8d5772f0271de41ad9dcd521fccf0..cbfc3a3294d83169b8a01509ae24f71578e43f7d 100644 (file)
@@ -99,6 +99,7 @@
 #@BUILD_PLUGIN_BAROMETER_TRUE@LoadPlugin barometer
 #@BUILD_PLUGIN_BATTERY_TRUE@LoadPlugin battery
 #@BUILD_PLUGIN_BIND_TRUE@LoadPlugin bind
+#@BUILD_PLUGIN_BUDDYINFO_TRUE@LoadPlugin buddyinfo
 #@BUILD_PLUGIN_CEPH_TRUE@LoadPlugin ceph
 #@BUILD_PLUGIN_CGROUPS_TRUE@LoadPlugin cgroups
 #@BUILD_PLUGIN_CHRONY_TRUE@LoadPlugin chrony
 #  </View>
 #</Plugin>
 
+#<Plugin buddyinfo>
+#      Zone "Normal"
+#</Plugin>
+
 #<Plugin ceph>
 #  LongRunAvgLatency false
 #  ConvertSpecialMetricTypes true
 
 #<Plugin "procevent">
 #  BufferLength 10
-#  ProcessRegex "/^ovs.*$/" 
+#  ProcessRegex "/^ovs.*$/"
 #  Process tuned
 #</Plugin>
 
index cda1002c5de721ebde9d3ed6ada459ae1c255e0a..f7a5b1126f269adccf552c5be68504eb4e37134a 100644 (file)
@@ -1455,6 +1455,20 @@ By default no detailed zone information is collected.
 
 =back
 
+=head2 Plugin C<buddyinfo>
+
+The B<buddyinfo> plugin collects information by reading "/proc/buddyinfo".
+This file contains information about the number of available contagious
+physical pages at the moment.
+
+=over 4
+
+=item B<Zone> I<ZoneName>
+
+Zone to collect info about. Will collect all zones by default.
+
+=back
+
 =head2 Plugin C<ceph>
 
 The ceph plugin collects values from JSON data to be parsed by B<libyajl>
@@ -1635,12 +1649,12 @@ LoadPlugin connectivity
   Interface eth1
   IgnoreSelected true
 </Plugin>
+
 =over 4
 
 =item B<Interface> I<interface_name>
 
-interface(s) to monitor connect to. 
+interface(s) to monitor connect to.
 
 =back
 
@@ -5615,7 +5629,7 @@ necessary in rare cases.
 
 Set the outgoing IP address for IP packets. This option can be used instead of
 the I<Interface> option to explicitly define the IP address which will be used
-to send Packets to the remote server. 
+to send Packets to the remote server.
 
 =item B<ResolveInterval> I<Seconds>
 
@@ -7386,37 +7400,37 @@ B<ProcessMatch> blocks these options set the default value for subsequent
 matches.
 
 =head2 Plugin C<procevent>
+
 The I<procevent> plugin monitors when processes start (EXEC) and stop (EXIT).
+
 B<Synopsis:>
+
   <Plugin procevent>
     BufferLength 10
     Process "name"
     ProcessRegex "regex"
   </Plugin>
+
 B<Options:>
+
 =over 4
+
 =item B<BufferLength> I<length>
+
 Maximum number of process events that can be stored in plugin's ring buffer.
 By default, this is set to 10.  Once an event has been read, its location
 becomes available for storing a new event.
+
 =item B<Process> I<name>
+
 Enumerate a process name to monitor.  All processes that match this exact
 name will be monitored for EXECs and EXITs.
 
 =item B<ProcessRegex> I<regex>
-Enumerate a process pattern to monitor.  All processes that match this 
+
+Enumerate a process pattern to monitor.  All processes that match this
 regular expression will be monitored for EXECs and EXITs.
+
 =back
 
 =head2 Plugin C<protocols>
@@ -8353,11 +8367,11 @@ or is not reliable.
 =back
 
 =head2 Plugin C<sysevent>
+
 The I<sysevent> plugin monitors rsyslog messages.
+
 B<Synopsis:>
+
   <Plugin sysevent>
     Listen "192.168.0.2" "6666"
     BufferSize 1024
@@ -8387,33 +8401,33 @@ B<Synopsis:>
     *.* @192.168.0.2:6666;ls_json
 
   Please note that these rsyslog.conf examples are *not* complete, as rsyslog
-  requires more than these options in the configuration file.  These examples 
+  requires more than these options in the configuration file.  These examples
   are meant to demonstration the proper remote logging and JSON format syntax.
 
 B<Options:>
+
 =over 4
+
 =item B<Listen> I<host> I<port>
+
 Listen on this IP on this port for incoming rsyslog messages.
 
 =item B<BufferSize> I<length>
-Maximum allowed size for incoming rsyslog messages.  Messages that exceed 
+
+Maximum allowed size for incoming rsyslog messages.  Messages that exceed
 this number will be truncated to this size.  Default is 4096 bytes.
 
 =item B<BufferLength> I<length>
+
 Maximum number of rsyslog events that can be stored in plugin's ring buffer.
 By default, this is set to 10.  Once an event has been read, its location
 becomes available for storing a new event.
 
 =item B<RegexFilter> I<regex>
+
 Enumerate a regex filter to apply to all incoming rsyslog messages.  If a
 message matches this filter, it will be published.
+
 =back
 
 =head2 Plugin C<syslog>
@@ -8736,7 +8750,7 @@ the following schema:
   Bucket  20  50
   Bucket  50   0
 
-Metrics are reported with the I<type> set by B<BucketType> option (C<bucket> 
+Metrics are reported with the I<type> set by B<BucketType> option (C<bucket>
 by default) and the I<type instance>
 C<E<lt>TypeE<gt>[-E<lt>InstanceE<gt>]-E<lt>lower_boundE<gt>_E<lt>upper_boundE<gt>>.
 
index 6c08936e948d7865c2c768f4cb47666c51a3788f..7face74d1bde23bf2027a45a5133f448b133622a 100644 (file)
@@ -97,6 +97,7 @@ files                   value:GAUGE:0:U
 filter_result           value:DERIVE:0:U
 flow                    value:GAUGE:0:U
 fork_rate               value:DERIVE:0:U
+freepages               value:GAUGE:0:U
 frequency               value:GAUGE:0:U
 frequency_error         value:GAUGE:-1000000:1000000
 frequency_offset        value:GAUGE:-1000000:1000000