New plugin: synproxy
authorMarek Becka <marek.becka@superhosting.cz>
Wed, 26 Jul 2017 10:12:12 +0000 (06:12 -0400)
committerFlorian Forster <octo@collectd.org>
Mon, 18 Sep 2017 06:37:48 +0000 (08:37 +0200)
Makefile.am
configure.ac
src/synproxy.c [new file with mode: 0644]
src/types.db

index cd5dbea..c93e364 100644 (file)
@@ -1554,6 +1554,12 @@ endif
 
 endif
 
+if BUILD_PLUGIN_SYNPROXY
+pkglib_LTLIBRARIES += synproxy.la
+synproxy_la_SOURCES = synproxy.c
+synproxy_la_LDFLAGS = $(PLUGIN_LDFLAGS)
+endif
+
 if BUILD_PLUGIN_SYSLOG
 pkglib_LTLIBRARIES += syslog.la
 syslog_la_SOURCES = src/syslog.c
index f50df28..8f2a9ab 100644 (file)
@@ -6169,6 +6169,7 @@ plugin_python="no"
 plugin_serial="no"
 plugin_smart="no"
 plugin_swap="no"
+plugin_synproxy="no"
 plugin_tape="no"
 plugin_tcpconns="no"
 plugin_ted="no"
@@ -6213,6 +6214,7 @@ if test "x$ac_system" = "xLinux"; then
   plugin_protocols="yes"
   plugin_serial="yes"
   plugin_swap="yes"
+  plugin_synproxy="yes"
   plugin_tcpconns="yes"
   plugin_thermal="yes"
   plugin_uptime="yes"
@@ -6625,6 +6627,7 @@ AC_PLUGIN([snmp],                [$with_libnetsnmp],        [SNMP querying plugi
 AC_PLUGIN([snmp_agent],          [$with_libnetsnmpagent],   [SNMP agent plugin])
 AC_PLUGIN([statsd],              [yes],                     [StatsD plugin])
 AC_PLUGIN([swap],                [$plugin_swap],            [Swap usage statistics])
+AC_PLUGIN([synproxy],            [$plugin_synproxy],        [Synproxy stats plugin])
 AC_PLUGIN([syslog],              [$have_syslog],            [Syslog logging plugin])
 AC_PLUGIN([table],               [yes],                     [Parsing of tabular data])
 AC_PLUGIN([tail],                [yes],                     [Parsing of logfiles])
@@ -7042,6 +7045,7 @@ AC_MSG_RESULT([    snmp  . . . . . . . . $enable_snmp])
 AC_MSG_RESULT([    snmp_agent  . . . . . $enable_snmp_agent])
 AC_MSG_RESULT([    statsd  . . . . . . . $enable_statsd])
 AC_MSG_RESULT([    swap  . . . . . . . . $enable_swap])
+AC_MSG_RESULT([    synproxy  . . . . . . $enable_synproxy])
 AC_MSG_RESULT([    syslog  . . . . . . . $enable_syslog])
 AC_MSG_RESULT([    table . . . . . . . . $enable_table])
 AC_MSG_RESULT([    tail_csv  . . . . . . $enable_tail_csv])
diff --git a/src/synproxy.c b/src/synproxy.c
new file mode 100644 (file)
index 0000000..eea65ba
--- /dev/null
@@ -0,0 +1,114 @@
+/**
+ * collectd - src/synproxy.c
+ * Copyright (C) 2017 Marek Becka
+ *
+ * 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:
+ *   Marek Becka <https://github.com/marekbecka>
+ **/
+
+#include "collectd.h"
+
+#include "common.h"
+#include "plugin.h"
+
+#if !KERNEL_LINUX
+#error "No applicable input method."
+#endif
+
+static const char *synproxy_stat_path = "/proc/net/stat/synproxy";
+
+static const char *column_names[] = {
+  "entries", "syn_received", "invalid", "valid", "retransmission", "reopened"
+};
+static const char *column_types[] = {
+  "current_connections", "synproxy_connections", "synproxy_cookies", 
+  "synproxy_cookies", "synproxy_cookies", "synproxy_connections"
+};
+
+static void synproxy_submit(value_t *results) {
+  value_list_t vl = VALUE_LIST_INIT;
+
+  for (unsigned n = 1; n < 6; n++) {
+    vl.values = &results[n];
+    vl.values_len = 1;
+
+    sstrncpy(vl.plugin, "synproxy", sizeof(vl.plugin));
+    sstrncpy(vl.type, column_types[n], sizeof(vl.type));
+    sstrncpy(vl.type_instance, column_names[n], sizeof(vl.type_instance));
+
+    plugin_dispatch_values(&vl);
+  } 
+}
+
+static int synproxy_read(void) {
+  FILE *fh;
+  char buf[1024];
+  value_t results[6];
+  int is_header = 1, status = 0;
+
+  fh = fopen(synproxy_stat_path, "r");
+  if (fh == NULL) {
+    ERROR("synproxy plugin: unable to open %s", synproxy_stat_path);
+    return -1;
+  }
+
+  memset(results, 0, sizeof(results));
+
+  while (fgets(buf, sizeof(buf), fh) != NULL) {
+    int numfields;
+    char *fields[6], *endprt;
+
+    if (is_header) {
+      is_header = 0;
+      continue;
+    }
+
+    numfields = strsplit(buf, fields, STATIC_ARRAY_SIZE(fields));
+    if (numfields != 6) {
+      ERROR("synproxy plugin: unexpected number of columns in %s", 
+             synproxy_stat_path);
+      status = -1;
+      break;
+    }
+
+    /* 1st column (entries) is hardcoded to 0 in kernel code */
+    for (unsigned n = 1; n < 6; n++) {
+      char *endptr = NULL;
+      errno = 0;
+
+      results[n].derive += strtoull(fields[n], &endprt, 16);
+      if ((endptr == fields[n]) || errno != 0) {
+        ERROR("synproxy plugin: unable to parse value: %s", fields[n]);
+        status = -1;
+        goto err_close;
+      }
+    }
+  }
+
+err_close:
+  fclose(fh);
+
+  if (status == 0) {
+    synproxy_submit(results);
+  }
+
+  return status;  
+}
+
+void module_register(void) {
+  plugin_register_read("synproxy", synproxy_read);
+} /* void module_register */
+
index 9ba33e8..a0a1782 100644 (file)
@@ -232,6 +232,8 @@ spam_score              value:GAUGE:U:U
 spl                     value:GAUGE:U:U
 swap                    value:GAUGE:0:1099511627776
 swap_io                 value:DERIVE:0:U
+synproxy_connections    value:DERIVE:0:U
+synproxy_cookies        value:DERIVE:0:U
 tcp_connections         value:GAUGE:0:4294967295
 temperature             value:GAUGE:U:U
 threads                 value:GAUGE:0:U