Adding fhcount plugin
authorJiri Tyr <jiri.tyr@gmail.com>
Thu, 23 Apr 2015 13:43:16 +0000 (14:43 +0100)
committerJiri Tyr <jiri.tyr@gmail.com>
Tue, 19 May 2015 14:57:45 +0000 (15:57 +0100)
AUTHORS
README
configure.ac
contrib/redhat/collectd.spec
src/Makefile.am
src/collectd.conf.in
src/collectd.conf.pod
src/fhcount.c [new file with mode: 0644]
src/types.db

diff --git a/AUTHORS b/AUTHORS
index 027ac96..9ee3bd1 100644 (file)
--- a/AUTHORS
+++ b/AUTHORS
@@ -128,6 +128,9 @@ Jeremy Katz <jeremy at katzbox.net>
 Jérôme Renard <jerome.renard at gmail.com>
  - varnish plugin.
 
+Jiri Tyr <jiri.tyr at gmail.com>
+ - fhcount plugin.
+
 Kevin Bowling <kbowling at llnw.com>
  - write_tsdb plugin for http://opentsdb.net/
 
diff --git a/README b/README
index 12ab7c6..5582e51 100644 (file)
--- a/README
+++ b/README
@@ -107,6 +107,9 @@ Features
       Values gathered by a custom program or script.
       See collectd-exec(5).
 
+    - fhcount
+      File handles statistics.
+
     - filecount
       Count the number of files in directories.
 
index 6a48b72..2d5ce60 100644 (file)
@@ -5498,6 +5498,7 @@ AC_PLUGIN([email],       [yes],                [EMail statistics])
 AC_PLUGIN([entropy],     [$plugin_entropy],    [Entropy statistics])
 AC_PLUGIN([ethstat],     [$plugin_ethstat],    [Stats from NIC driver])
 AC_PLUGIN([exec],        [yes],                [Execution of external programs])
+AC_PLUGIN([fhcount],     [yes],                [File handles statistics])
 AC_PLUGIN([filecount],   [yes],                [Count files in directories])
 AC_PLUGIN([fscache],     [$plugin_fscache],    [fscache statistics])
 AC_PLUGIN([gmond],       [$with_libganglia],   [Ganglia plugin])
@@ -5874,6 +5875,7 @@ Configuration:
     entropy . . . . . . . $enable_entropy
     ethstat . . . . . . . $enable_ethstat
     exec  . . . . . . . . $enable_exec
+    fhcount . . . . . . . $enable_fhcount
     filecount . . . . . . $enable_filecount
     fscache . . . . . . . $enable_fscache
     gmond . . . . . . . . $enable_gmond
index e023a34..421b955 100644 (file)
@@ -94,6 +94,7 @@
 %define with_entropy 0%{!?_without_entropy:1}
 %define with_ethstat 0%{!?_without_ethstat:0%{?_has_recent_sockios_h}}
 %define with_exec 0%{!?_without_exec:1}
+%define with_fhcount 0%{!?_without_fhcount:1}
 %define with_filecount 0%{!?_without_filecount:1}
 %define with_fscache 0%{!?_without_fscache:1}
 %define with_gmond 0%{!?_without_gmond:0%{?_has_recent_libganglia}}
@@ -999,6 +1000,12 @@ Collectd utilities
 %define _with_exec --disable-exec
 %endif
 
+%if %{with_fhcount}
+%define _with_fhcount --enable-fhcount
+%else
+%define _with_fhcount --disable-fhcount
+%endif
+
 %if %{with_filecount}
 %define _with_filecount --enable-filecount
 %else
@@ -1604,6 +1611,7 @@ Collectd utilities
        %{?_with_entropy} \
        %{?_with_ethstat} \
        %{?_with_exec} \
+       %{?_with_fhcount} \
        %{?_with_filecount} \
        %{?_with_fscache} \
        %{?_with_gmond} \
@@ -1880,6 +1888,9 @@ fi
 %if %{with_exec}
 %{_libdir}/%{name}/exec.so
 %endif
+%if %{with_fhcount}
+%{_libdir}/%{name}/fhcount.so
+%endif
 %if %{with_filecount}
 %{_libdir}/%{name}/filecount.so
 %endif
index 5303c8a..a95dbca 100644 (file)
@@ -359,6 +359,12 @@ ethstat_la_SOURCES = ethstat.c
 ethstat_la_LDFLAGS = $(PLUGIN_LDFLAGS)
 endif
 
+if BUILD_PLUGIN_FHCOUNT
+pkglib_LTLIBRARIES += fhcount.la
+fhcount_la_SOURCES = fhcount.c
+fhcount_la_LDFLAGS = $(PLUGIN_LDFLAGS)
+endif
+
 if BUILD_PLUGIN_FILECOUNT
 pkglib_LTLIBRARIES += filecount.la
 filecount_la_SOURCES = filecount.c
index d31ef15..a09ed2b 100644 (file)
 #@BUILD_PLUGIN_ENTROPY_TRUE@LoadPlugin entropy
 #@BUILD_PLUGIN_ETHSTAT_TRUE@LoadPlugin ethstat
 #@BUILD_PLUGIN_EXEC_TRUE@LoadPlugin exec
+#@BUILD_PLUGIN_FHCOUNT_TRUE@LoadPlugin fhcount
 #@BUILD_PLUGIN_FILECOUNT_TRUE@LoadPlugin filecount
 #@BUILD_PLUGIN_FSCACHE_TRUE@LoadPlugin fscache
 #@BUILD_PLUGIN_GMOND_TRUE@LoadPlugin gmond
 #      NotificationExec "user:group" "/path/to/exec"
 #</Plugin>
 
+#<Plugin fhcount>
+#      ValuesAbsolute true
+#      ValuesPercentage false
+#</Plugin>
+
 #<Plugin filecount>
 #      <Directory "/path/to/dir">
 #              Instance "foodir"
index a7a5816..11bc7fa 100644 (file)
@@ -2264,6 +2264,27 @@ expected from them. This is documented in great detail in L<collectd-exec(5)>.
 
 =back
 
+=head2 Plugin C<fhcount>
+
+The C<fhcount> plugin provides statistics about used, unused and total number of
+file handles.
+
+The I<fhcount plugin> provides the following configuration options:
+
+=over 4
+
+=item B<ValuesAbsolute> B<true>|B<false>
+
+Enables or disables reporting of file handles usage in absolute numbers,
+e.g. file handles used. Defaults to B<true>.
+
+=item B<ValuesPercentage> B<false>|B<true>
+
+Enables or disables reporting of file handles usage in percentages, e.g.
+percent of file handles used. Defaults to B<false>.
+
+=back
+
 =head2 Plugin C<filecount>
 
 The C<filecount> plugin counts the number of files in a certain directory (and
diff --git a/src/fhcount.c b/src/fhcount.c
new file mode 100644 (file)
index 0000000..4c409b5
--- /dev/null
@@ -0,0 +1,139 @@
+/**
+ *
+ * collectd - src/fhcount.c
+ * Copyright (c) 2015, Jiri Tyr <jiri.tyr at gmail.com>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ **/
+
+#include "collectd.h"
+#include "common.h"
+#include "plugin.h"
+#include "configfile.h"
+
+
+static const char *config_keys[] = {
+  "ValuesAbsolute",
+  "ValuesPercentage"
+};
+static int config_keys_num = STATIC_ARRAY_SIZE(config_keys);
+
+static _Bool values_absolute = 1;
+static _Bool values_percentage = 0;
+
+
+static int fhcount_config(const char *key, const char *value) {
+  int ret = -1;
+
+  if (strcasecmp(key, "ValuesAbsolute") == 0) {
+    if (IS_TRUE(value)) {
+      values_absolute = 1;
+    } else {
+      values_absolute = 0;
+    }
+
+    ret = 0;
+  } else if (strcasecmp(key, "ValuesPercentage") == 0) {
+    if (IS_TRUE(value)) {
+      values_percentage = 1;
+    } else {
+      values_percentage = 0;
+    }
+
+    ret = 0;
+  }
+
+  return(ret);
+}
+
+
+static void fhcount_submit(
+    const char *type, const char *type_instance, gauge_t value) {
+
+  value_t values[1];
+  value_list_t vl = VALUE_LIST_INIT;
+
+  values[0].gauge = value;
+
+  vl.values = values;
+  vl.values_len = 1;
+
+  // Compose the metric
+  sstrncpy(vl.host, hostname_g, sizeof(vl.host));
+  sstrncpy(vl.plugin, "fhcount", sizeof(vl.plugin));
+  sstrncpy(vl.type, type, sizeof(vl.type));
+  sstrncpy(vl.type_instance, type_instance, sizeof(vl.type_instance));
+
+  // Dispatch the metric
+  plugin_dispatch_values(&vl);
+}
+
+
+static int fhcount_read(void) {
+  int numfields = 0;
+  int buffer_len = 60;
+  gauge_t used, unused, max;
+  int prc_used, prc_unused;
+  char *fields[3];
+  char buffer[buffer_len];
+  char errbuf[1024];
+  FILE *fp;
+
+  // Open file
+  fp = fopen("/proc/sys/fs/file-nr" , "r");
+  if (fp == NULL) {
+    ERROR("fhcount: fopen: %s", sstrerror(errno, errbuf, sizeof(errbuf)));
+    return(EXIT_FAILURE);
+  }
+  if (fgets(buffer, buffer_len, fp) == NULL) {
+    ERROR("fhcount: fgets: %s", sstrerror(errno, errbuf, sizeof(errbuf)));
+    return(EXIT_FAILURE);
+  }
+  fclose(fp);
+
+  // Tokenize string
+  numfields = strsplit(buffer, fields, STATIC_ARRAY_SIZE(fields));
+
+  if (numfields != 3) {
+    ERROR("fhcount: Line doesn't contain 3 fields");
+    return(EXIT_FAILURE);
+  }
+
+  // Define the values
+  strtogauge(fields[0], &used);
+  strtogauge(fields[1], &unused);
+  strtogauge(fields[2], &max);
+  prc_used = (gauge_t) used/max*100;
+  prc_unused = (gauge_t) unused/max*100;
+
+  // Submit values
+  if (values_absolute) {
+    fhcount_submit("file_handles", "used", (gauge_t) used);
+    fhcount_submit("file_handles", "unused", (gauge_t) unused);
+    fhcount_submit("file_handles", "max", (gauge_t) max);
+  }
+  if (values_percentage) {
+    fhcount_submit("percent", "used", (gauge_t) prc_used);
+    fhcount_submit("percent", "unused", (gauge_t) prc_unused);
+  }
+
+  return(0);
+}
+
+
+void module_register(void) {
+  plugin_register_config(
+    "fhcount", fhcount_config, config_keys, config_keys_num);
+  plugin_register_read("fhcount", fhcount_read);
+}
index 5474659..38fb546 100644 (file)
@@ -68,6 +68,7 @@ email_size            value:GAUGE:0:U
 entropy                        value:GAUGE:0:4294967295
 expired_keys    value:GAUGE:0:U
 fanspeed               value:GAUGE:0:U
+file_handles           value:GAUGE:0:U
 file_size              value:GAUGE:0:U
 files                  value:GAUGE:0:U
 flow                   value:GAUGE:0:U