Merge pull request #566 from timl/drbd
authorMarc Fournier <marc.fournier@camptocamp.com>
Thu, 7 Aug 2014 15:30:01 +0000 (17:30 +0200)
committerMarc Fournier <marc.fournier@camptocamp.com>
Thu, 7 Aug 2014 15:30:01 +0000 (17:30 +0200)
Collect drbd statistics on linux

AUTHORS
README
configure.ac
src/Makefile.am
src/collectd.conf.in
src/drbd.c [new file with mode: 0644]
src/types.db

diff --git a/AUTHORS b/AUTHORS
index 38d20b9..16a75a4 100644 (file)
--- a/AUTHORS
+++ b/AUTHORS
@@ -235,6 +235,9 @@ Sven Trenkel <collectd at semidefinite.de>
  - netapp plugin.
  - python plugin.
 
+Tim Laszlo <tim.laszlo at gmail.com>
+ - drbd plugin
+
 Thomas Meson <zllak at hycik.org>
  - Graphite support for the AMQP plugin.
 
diff --git a/README b/README
index cbf7574..60de1ed 100644 (file)
--- a/README
+++ b/README
@@ -87,6 +87,9 @@ Features
       DNS traffic: Query types, response codes, opcodes and traffic/octets
       transfered.
 
+    - drbd
+      Collect individual drbd resource statistics.
+
     - email
       Email statistics: Count, traffic, spam scores and checks.
       See collectd-email(5).
index 1757e2f..c009b47 100644 (file)
@@ -4893,6 +4893,7 @@ plugin_curl_json="no"
 plugin_curl_xml="no"
 plugin_df="no"
 plugin_disk="no"
+plugin_drbd="no"
 plugin_entropy="no"
 plugin_ethstat="no"
 plugin_fscache="no"
@@ -4933,6 +4934,7 @@ then
        plugin_cpu="yes"
        plugin_cpufreq="yes"
        plugin_disk="yes"
+       plugin_drbd="yes"
        plugin_entropy="yes"
        plugin_fscache="yes"
        plugin_interface="yes"
@@ -5251,6 +5253,7 @@ AC_PLUGIN([cgroups],     [$plugin_cgroups],    [CGroups CPU usage accounting])
 AC_PLUGIN([dbi],         [$with_libdbi],       [General database statistics])
 AC_PLUGIN([df],          [$plugin_df],         [Filesystem usage statistics])
 AC_PLUGIN([disk],        [$plugin_disk],       [Disk usage statistics])
+AC_PLUGIN([drbd],        [$plugin_drbd],       [DRBD statistics])
 AC_PLUGIN([dns],         [$with_libpcap],      [DNS traffic analysis])
 AC_PLUGIN([email],       [yes],                [EMail statistics])
 AC_PLUGIN([entropy],     [$plugin_entropy],    [Entropy statistics])
@@ -5614,6 +5617,7 @@ Configuration:
     df  . . . . . . . . . $enable_df
     disk  . . . . . . . . $enable_disk
     dns . . . . . . . . . $enable_dns
+    drbd  . . . . . . . . $enable_drbd
     email . . . . . . . . $enable_email
     entropy . . . . . . . $enable_entropy
     ethstat . . . . . . . $enable_ethstat
index 6c7a1d4..1a8ebbb 100644 (file)
@@ -417,6 +417,15 @@ collectd_LDADD += "-dlopen" dns.la
 collectd_DEPENDENCIES += dns.la
 endif
 
+if BUILD_PLUGIN_DRBD
+pkglib_LTLIBRARIES += drbd.la
+drbd_la_SOURCES = drbd.c
+drbd_la_LDFLAGS = -module -avoid-version
+drbd_la_LIBADD = -lpthread
+collectd_LDADD += "-dlopen" drbd.la
+collectd_DEPENDENCIES += drbd.la
+endif
+
 if BUILD_PLUGIN_EMAIL
 pkglib_LTLIBRARIES += email.la
 email_la_SOURCES = email.c
index 2d51aec..3dcae18 100644 (file)
 #@BUILD_PLUGIN_DF_TRUE@LoadPlugin df
 #@BUILD_PLUGIN_DISK_TRUE@LoadPlugin disk
 #@BUILD_PLUGIN_DNS_TRUE@LoadPlugin dns
+#@BUILD_PLUGIN_DRBD_TRUE@LoadPlugin drbd
 #@BUILD_PLUGIN_EMAIL_TRUE@LoadPlugin email
 #@BUILD_PLUGIN_ENTROPY_TRUE@LoadPlugin entropy
 #@BUILD_PLUGIN_ETHSTAT_TRUE@LoadPlugin ethstat
diff --git a/src/drbd.c b/src/drbd.c
new file mode 100644 (file)
index 0000000..af55667
--- /dev/null
@@ -0,0 +1,170 @@
+/**
+ * collectd - src/drbd.c
+ * Copyright (C) 2014  Tim Laszlo
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ *   Tim Laszlo <tim.laszlo at gmail.com>
+ **/
+
+/*
+ See: http://www.drbd.org/users-guide/ch-admin.html#s-performance-indicators
+
+ version: 8.3.11 (api:88/proto:86-96)
+ srcversion: 71955441799F513ACA6DA60 
+  0: cs:Connected ro:Primary/Secondary ds:UpToDate/UpToDate B r-----
+        ns:64363752 nr:0 dw:357799284 dr:846902273 al:34987022 bm:18062 lo:0 \
+                                               pe:0 ua:0 ap:0 ep:1 wo:f oos:0
+ */
+
+#include "collectd.h"
+#include "common.h"
+#include "plugin.h"
+
+static const char *drbd_stats = "/proc/drbd";
+static const char *drbd_names[] =
+{
+       "network_send",  /* ns (network send) */
+       "network_recv",  /* nr (network receive) */
+       "disk_write",      /* dw (disk write) */
+       "disk_read",            /* dr (disk read) */
+       "activity_log",  /* al (activity log) */
+       "bitmap",                  /* bm (bit map) */
+       "local_count",    /* lo (local count) */
+       "pending",                /* pe (pending) */
+       "unacknowledged",   /* ua (unacknowledged) */
+       "app pending",    /* ap (application pending) */
+       "epochs",                  /* ep (epochs) */
+       NULL,                      /* wo (write order) */
+       "oos"                      /* oos (out of sync) */
+};
+static size_t drbd_names_num = STATIC_ARRAY_SIZE (drbd_names);
+
+static int drbd_init (void)
+{
+       return (0);
+}
+
+
+static int drbd_submit_fields (long int resource,
+               char **fields, size_t fields_num)
+{
+       char plugin_instance[DATA_MAX_NAME_LEN];
+       value_t values[fields_num];
+       value_list_t vl = VALUE_LIST_INIT;
+       size_t i;
+
+       if (resource < 0)
+       {
+               WARNING ("drbd plugin: Unable to parse resource");
+               return (EINVAL);
+       }
+
+       if (fields_num != drbd_names_num)
+       {
+               WARNING ("drbd plugin: Wrong number of fields for "
+                                "r%ld statistics. Expected %zu, got %zu.",
+                                resource, drbd_names_num, fields_num);
+               return (EINVAL);
+       }
+
+       ssnprintf (plugin_instance, sizeof (plugin_instance), "r%ld",
+                       resource);
+
+       for (i = 0; i < drbd_names_num; i++)
+       {
+               char *data;
+               /* skip non numeric wo */
+               if (strncmp(fields[i], "wo", 2) == 0)
+                       continue;
+               data = strchr(fields[i], ':');
+               if (data == NULL)
+                       return (EINVAL);
+               (void) parse_value (++data, &values[i], DS_TYPE_DERIVE);
+       }
+
+       vl.values_len = 1;
+       sstrncpy (vl.host, hostname_g, sizeof (vl.host));
+       sstrncpy (vl.plugin, "drbd", sizeof (vl.plugin));
+       sstrncpy (vl.plugin_instance, plugin_instance,
+                       sizeof (vl.plugin_instance));
+       sstrncpy (vl.type, "drbd_resource", sizeof (vl.type));
+
+       for (i = 0; i < fields_num; i++)
+       {
+               if (drbd_names[i] == NULL)
+                       continue;
+               vl.values = values + i;
+               sstrncpy (vl.type_instance, drbd_names[i],
+                               sizeof (vl.type_instance));
+               plugin_dispatch_values (&vl);
+       }
+
+       return (0);
+} /* drbd_submit_fields */
+
+static int drbd_read (void)
+{
+       FILE *fh;
+       char buffer[256];
+
+       long int resource = -1;
+       char *fields[16];
+       int fields_num = 0;
+
+       fh = fopen (drbd_stats, "r");
+       if (fh == NULL)
+       {
+               WARNING ("Unable to open%s", drbd_stats);
+               return (EINVAL);
+       }
+
+       while (fgets (buffer, sizeof (buffer), fh) != NULL)
+       {
+               fields_num = strsplit (buffer,
+                               fields, STATIC_ARRAY_SIZE (fields));
+
+               /* ignore headers (first two iterations) */
+               if (fields_num < 4)
+                       continue;
+
+               if (isdigit(fields[0][0]))
+               {
+                       /* parse the resource line, next loop iteration
+                          will submit values for this resource */
+                       resource = strtol(fields[0], NULL, 10);
+               }
+               else
+               {
+                       /* handle stats data for the resource defined in the
+                          previous iteration */
+                       drbd_submit_fields(resource, fields, fields_num);
+               }
+       } /* while (fgets) */
+
+       fclose (fh);
+       return (0);
+} /* void drbd_read */
+
+void module_register (void)
+{
+       plugin_register_init ("drbd", drbd_init);
+       plugin_register_read ("drbd", drbd_read);
+} /* void module_register */
index 06f6fd2..a203872 100644 (file)
@@ -53,6 +53,7 @@ dns_response          value:DERIVE:0:U
 dns_transfer           value:DERIVE:0:U
 dns_update             value:DERIVE:0:U
 dns_zops               value:DERIVE:0:U
+drbd_resource  value:DERIVE:0:U
 duration               seconds:GAUGE:0:U
 email_check            value:GAUGE:0:U
 email_count            value:GAUGE:0:U