collectd: add dhcpleases plugin
authorNick Hainke <vincent@systemli.org>
Fri, 11 Dec 2020 19:19:02 +0000 (20:19 +0100)
committerNick Hainke <vincent@systemli.org>
Sat, 12 Dec 2020 13:59:49 +0000 (14:59 +0100)
Count the current dhcpleases. Currently, we use a bash script
that does the same job (Freifunk Berlin). We want to use native
collectd plugin for that.

Signed-off-by: Nick Hainke <vincent@systemli.org>
utils/collectd/Makefile
utils/collectd/patches/930-dhcpleases-add-dhcpleases-plugin.patch [new file with mode: 0644]

index 6c9b6e1eb1d8edf70466d38c739aeabbda5e0a19..01cc944e1029bcbc453560d25c5b1974ca326ee6 100644 (file)
@@ -9,7 +9,7 @@ include $(TOPDIR)/rules.mk
 
 PKG_NAME:=collectd
 PKG_VERSION:=5.12.0
-PKG_RELEASE:=1
+PKG_RELEASE:=2
 
 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2
 PKG_SOURCE_URL:=https://collectd.org/files/ \
@@ -144,6 +144,7 @@ COLLECTD_PLUGINS_SELECTED:= \
        csv \
        curl \
        df \
+       dhcpleases \
        disk \
        dns \
        email \
@@ -408,6 +409,7 @@ $(eval $(call BuildPlugin,csv,CSV output,csv,))
 $(eval $(call BuildPlugin,curl,cURL input,curl,+PACKAGE_collectd-mod-curl:libcurl))
 #$(eval $(call BuildPlugin,dbi,relational database input,dbi,+PACKAGE_collectd-mod-dbi:libdbi))
 $(eval $(call BuildPlugin,df,disk space input,df,))
+$(eval $(call BuildPlugin,dhcpleases,show dhcpleases,dhcpleases,))
 $(eval $(call BuildPlugin,disk,disk usage/timing input,disk,))
 $(eval $(call BuildPlugin,dns,DNS traffic input,dns,+PACKAGE_collectd-mod-dns:libpcap))
 $(eval $(call BuildPlugin,email,email output,email,))
diff --git a/utils/collectd/patches/930-dhcpleases-add-dhcpleases-plugin.patch b/utils/collectd/patches/930-dhcpleases-add-dhcpleases-plugin.patch
new file mode 100644 (file)
index 0000000..8db3c1d
--- /dev/null
@@ -0,0 +1,186 @@
+From: Nick Hainke <vincent@systemli.org>
+Date: Mon, 7 Dec 2020 23:07:30 +0100
+Subject: [PATCH] dhcpleases: add dhcpleases plugin
+
+Changelog: dhcpleases: add plugin for counting current dhcp leases
+
+The plugin is useful for the Freifunk Community. Currently, we use
+the exec-plugin. With that dhcpleases plugin we have native collectd
+support to measure this important statistic.
+
+Signed-off-by: Nick Hainke <vincent@systemli.org>
+---
+ Makefile.am          |  6 ++++
+ README               |  3 ++
+ configure.ac         |  2 ++
+ src/collectd.conf.in |  5 +++
+ src/dhcpleases.c     | 83 ++++++++++++++++++++++++++++++++++++++++++++
+ 5 files changed, 99 insertions(+)
+ create mode 100644 src/dhcpleases.c
+
+diff --git a/Makefile.am b/Makefile.am
+index 00947da0..5ee76a00 100644
+--- a/Makefile.am
++++ b/Makefile.am
+@@ -963,6 +963,12 @@ df_la_LDFLAGS = $(PLUGIN_LDFLAGS)
+ df_la_LIBADD = libignorelist.la libmount.la
+ endif
++if BUILD_PLUGIN_DHCPLEASES
++pkglib_LTLIBRARIES += dhcpleases.la
++dhcpleases_la_SOURCES = src/dhcpleases.c
++dhcpleases_la_LDFLAGS = $(PLUGIN_LDFLAGS)
++endif
++
+ if BUILD_PLUGIN_DISK
+ pkglib_LTLIBRARIES += disk.la
+ disk_la_SOURCES = src/disk.c
+diff --git a/README b/README
+index e42e9c24..dd104408 100644
+--- a/README
++++ b/README
+@@ -106,6 +106,9 @@ Features
+       Disk utilization: Sectors read/written, number of read/write actions,
+       average time an IO-operation took to complete.
++    - dhcpleases
++      Collect number of current dhcp leases.
++
+     - dns
+       DNS traffic: Query types, response codes, opcodes and traffic/octets
+       transferred.
+diff --git a/configure.ac b/configure.ac
+index bcfb8cf5..6c2b6574 100644
+--- a/configure.ac
++++ b/configure.ac
+@@ -7061,6 +7061,7 @@ AC_PLUGIN([curl_xml],            [$plugin_curl_xml],          [CURL generic xml
+ AC_PLUGIN([dbi],                 [$with_libdbi],              [General database statistics])
+ AC_PLUGIN([dcpmm],               [$with_libpmwapi],           [Intel(R) Optane(TM) DC Persistent Memory performance and health statistics])
+ AC_PLUGIN([df],                  [$plugin_df],                [Filesystem usage statistics])
++AC_PLUGIN([dhcpleases],          [yes],                       [DHCP Leases])
+ AC_PLUGIN([disk],                [$plugin_disk],              [Disk usage statistics])
+ AC_PLUGIN([dns],                 [$with_libpcap],             [DNS traffic analysis])
+ AC_PLUGIN([dpdkevents],          [$plugin_dpdkevents],        [Events from DPDK])
+@@ -7508,6 +7509,7 @@ AC_MSG_RESULT([    curl_xml  . . . . . . $enable_curl_xml])
+ AC_MSG_RESULT([    dbi . . . . . . . . . $enable_dbi])
+ AC_MSG_RESULT([    dcpmm  . . . . . .  . $enable_dcpmm])
+ AC_MSG_RESULT([    df  . . . . . . . . . $enable_df])
++AC_MSG_RESULT([    dhcpleases. . . . . . $enable_dhcpleases])
+ AC_MSG_RESULT([    disk  . . . . . . . . $enable_disk])
+ AC_MSG_RESULT([    dns . . . . . . . . . $enable_dns])
+ AC_MSG_RESULT([    dpdkevents. . . . . . $enable_dpdkevents])
+diff --git a/src/collectd.conf.in b/src/collectd.conf.in
+index 562a55d9..94659e81 100644
+--- a/src/collectd.conf.in
++++ b/src/collectd.conf.in
+@@ -119,6 +119,7 @@
+ #@BUILD_PLUGIN_DBI_TRUE@LoadPlugin dbi
+ #@BUILD_PLUGIN_DCPMM_TRUE@LoadPlugin dcpmm
+ #@BUILD_PLUGIN_DF_TRUE@LoadPlugin df
++#@BUILD_PLUGIN_DHCPLEASES_TRUE@LoadPlugin dhcpleases
+ #@BUILD_PLUGIN_DISK_TRUE@LoadPlugin disk
+ #@BUILD_PLUGIN_DNS_TRUE@LoadPlugin dns
+ #@BUILD_PLUGIN_DPDKEVENTS_TRUE@LoadPlugin dpdkevents
+@@ -689,6 +690,10 @@
+ #     SelectNumericQueryTypes true
+ #</Plugin>
++#<Plugin dhcpleases>
++#     Path "/tmp/dhcp.leases"
++#</Plugin>
++
+ #<Plugin "dpdkevents">
+ #  <EAL>
+ #    Coremask "0x1"
+diff --git a/src/dhcpleases.c b/src/dhcpleases.c
+new file mode 100644
+index 00000000..f43d62bf
+--- /dev/null
++++ b/src/dhcpleases.c
+@@ -0,0 +1,83 @@
++#include <errno.h>
++#include <stdio.h>
++
++#include "utils/common/common.h"
++
++#include "configfile.h"
++#include "plugin.h"
++
++static char *dhcp_lease_file;
++
++static const char *config_keys[] = {
++    "Path",
++};
++static int config_keys_num = STATIC_ARRAY_SIZE(config_keys);
++
++/* copied from ping.c plugin */
++static int config_set_string(const char *name, /* {{{ */
++                             char **var, const char *value) {
++  char *tmp;
++
++  tmp = strdup(value);
++  if (tmp == NULL) {
++    ERROR("dhcpleases plugin: Setting `%s' to `%s' failed: strdup failed: %s", name,
++          value, STRERRNO);
++    return 1;
++  }
++
++  if (*var != NULL)
++    free(*var);
++  *var = tmp;
++  return 0;
++} /* }}} int config_set_string */
++
++static int dhcpleases_config(const char *key, const char *value) {
++  if (strcasecmp(key, "Path") == 0) {
++    int status = config_set_string(key, &dhcp_lease_file, value);
++    if (status != 0)
++      return status;
++  }
++  return 0;
++}
++
++static void dhcpleases_submit(gauge_t counter) {
++  value_list_t vl = VALUE_LIST_INIT;
++  value_t values[] = {
++      {.gauge = counter},
++  };
++
++  vl.values = values;
++  vl.values_len = STATIC_ARRAY_SIZE(values);
++
++  sstrncpy(vl.plugin, "dhcpleases", sizeof(vl.plugin));
++  sstrncpy(vl.type, "count", sizeof(vl.type));
++
++  plugin_dispatch_values(&vl);
++}
++
++static int dhcp_leases_read(void) {
++
++  FILE *fh;
++  char buffer[1024];
++  gauge_t count = 0;
++
++  if ((fh = fopen(dhcp_lease_file, "r")) == NULL) {
++    WARNING("interface plugin: fopen: %s", STRERRNO);
++    return -1;
++  }
++
++  while (fgets(buffer, 1024, fh) != NULL) {
++    count++;
++  }
++  fclose(fh);
++
++  dhcpleases_submit(count);
++
++  return 0;
++}
++
++void module_register(void) {
++  plugin_register_config("dhcpleases", dhcpleases_config, config_keys,
++                         config_keys_num);
++  plugin_register_read("dhcpleases", dhcp_leases_read);
++}
+-- 
+2.29.2
+