summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: 2c4c660)
raw | patch | inline | side by side (parent: 2c4c660)
author | Cyril Feraudet <collectd@feraudet.com> | |
Tue, 4 Oct 2011 13:00:04 +0000 (15:00 +0200) | ||
committer | Florian Forster <octo@collectd.org> | |
Sun, 11 Mar 2012 14:36:35 +0000 (15:36 +0100) |
Hi all,
For my needs at work I wrote a plugin for collectd and I wish to share it with
you.
This plugins, temporary called ethstat and wrote in C, collect lot of
performance counter about network interface as "ethtool -S ethX" do by asking
NIC driver module.
At the moment this plugin work only under Linux. Any help would be great for
make it working under Solaris, AIX and co ...
If you think this plugin may be included to collectd sources, what is the
procedure to do it ?
Regards,
Cyril Feraudet
To be added to configuration file to make it work :
LoadPlugin ethstat
<Plugin ethstat>
Iface "eth0"
#Iface "eth1"
#Iface "eth2"
#Iface "eth3"
</Plugin>
Signed-off-by: Florian Forster <octo@collectd.org>
For my needs at work I wrote a plugin for collectd and I wish to share it with
you.
This plugins, temporary called ethstat and wrote in C, collect lot of
performance counter about network interface as "ethtool -S ethX" do by asking
NIC driver module.
At the moment this plugin work only under Linux. Any help would be great for
make it working under Solaris, AIX and co ...
If you think this plugin may be included to collectd sources, what is the
procedure to do it ?
Regards,
Cyril Feraudet
To be added to configuration file to make it work :
LoadPlugin ethstat
<Plugin ethstat>
Iface "eth0"
#Iface "eth1"
#Iface "eth2"
#Iface "eth3"
</Plugin>
Signed-off-by: Florian Forster <octo@collectd.org>
configure.in | patch | blob | history | |
src/Makefile.am | patch | blob | history | |
src/ethstat.c | [new file with mode: 0644] | patch | blob |
src/ethstat.h | [new file with mode: 0644] | patch | blob |
diff --git a/configure.in b/configure.in
index 0a0a8f8c813a5345af4084e55c24d79bd75fd857..0d992e1de1547c851bc51ed55e2b2a438290d079 100644 (file)
--- a/configure.in
+++ b/configure.in
AC_PLUGIN([dns], [$with_libpcap], [DNS traffic analysis])
AC_PLUGIN([email], [yes], [EMail statistics])
AC_PLUGIN([entropy], [$plugin_entropy], [Entropy statistics])
+AC_PLUGIN([ethstat], [yes], [Stats from NIC driver])
AC_PLUGIN([exec], [yes], [Execution of external programs])
AC_PLUGIN([filecount], [yes], [Count files in directories])
AC_PLUGIN([fscache], [$plugin_fscache], [fscache statistics])
dns . . . . . . . . . $enable_dns
email . . . . . . . . $enable_email
entropy . . . . . . . $enable_entropy
+ ethstat . . . . . . . $enable_ethstat
exec . . . . . . . . $enable_exec
filecount . . . . . . $enable_filecount
fscache . . . . . . . $enable_fscache
diff --git a/src/Makefile.am b/src/Makefile.am
index 05f94d9ea3aa8433acbb677647d91dd05f5d23cb..5c2eb35d89540e0472332839915ce5e101c19c95 100644 (file)
--- a/src/Makefile.am
+++ b/src/Makefile.am
collectd_DEPENDENCIES += exec.la
endif
+if BUILD_PLUGIN_ETHSTAT
+pkglib_LTLIBRARIES += ethstat.la
+ethstat_la_SOURCES = ethstat.c
+ethstat_la_LDFLAGS = -module -avoid-version
+collectd_LDADD += "-dlopen" ethstat.la
+collectd_DEPENDENCIES += ethstat.la
+endif
+
if BUILD_PLUGIN_FILECOUNT
pkglib_LTLIBRARIES += filecount.la
filecount_la_SOURCES = filecount.c
diff --git a/src/ethstat.c b/src/ethstat.c
--- /dev/null
+++ b/src/ethstat.c
@@ -0,0 +1,178 @@
+/**
+ * collectd - src/ethstat.c
+ * Copyright (C) 2011 Cyril Feraudet
+ *
+ * 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; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * 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:
+ * Cyril Feraudet <cyril at feraudet.com>
+ **/
+
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+#include <time.h>
+#include "collectd.h"
+#include "common.h"
+#include "plugin.h"
+#include "configfile.h"
+#include <sys/types.h>
+#include <sys/types.h>
+#include <sys/ioctl.h>
+#include <sys/stat.h>
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <net/if.h>
+#include <linux/sockios.h>
+#include "ethstat.h"
+
+# if KERNEL_LINUX
+
+
+static int ethstat_config (const char *key, const char *value)
+{
+ if (strcasecmp (key, "Iface") == 0) {
+ ifacelist[ifacenumber] = malloc(strlen(value) + 1);
+ strcpy(ifacelist[ifacenumber++], value);
+ INFO("ethstat: Registred iface %s", value);
+ }
+ return (0);
+}
+
+
+static void ethstat_submit_value (char *devname, char *counter, unsigned long long value)
+{
+ value_t values[1];
+ value_list_t vl = VALUE_LIST_INIT;
+
+ values[0].counter = value;
+
+ vl.values = values;
+ vl.values_len = 1;
+ sstrncpy (vl.host, hostname_g, sizeof (vl.host));
+ sstrncpy (vl.plugin, "ethstat", sizeof (vl.plugin));
+ sstrncpy (vl.plugin_instance, devname, sizeof (vl.plugin_instance));
+ sstrncpy (vl.type, "derive", sizeof (vl.type));
+ sstrncpy (vl.type_instance, counter, sizeof (vl.type_instance));
+
+ plugin_dispatch_values (&vl);
+}
+
+
+static int getstats(char *devname, struct ifreq *ifr) {
+ int fd;
+ struct ethtool_drvinfo drvinfo;
+ struct ethtool_gstrings *strings;
+ struct ethtool_stats *stats;
+ unsigned int n_stats, sz_str, sz_stats, i;
+ int err;
+
+
+ fd = socket(AF_INET, SOCK_DGRAM, 0);
+ if (fd < 0) {
+ ERROR("ethstat - %s : Cannot get control socket", devname);
+ return 1;
+ }
+
+ drvinfo.cmd = ETHTOOL_GDRVINFO;
+ ifr->ifr_data = (caddr_t)&drvinfo;
+ err = ioctl(fd, SIOCETHTOOL, ifr);
+ if (err < 0) {
+ ERROR("ethstat - %s : Cannot get driver information", devname);
+ return 1;
+ }
+
+
+ n_stats = drvinfo.n_stats;
+ if (n_stats < 1) {
+ ERROR("ethstat - %s : No stats available", devname);
+ return 1;
+ }
+
+ sz_str = n_stats * ETH_GSTRING_LEN;
+ sz_stats = n_stats * sizeof(u64);
+
+ strings = calloc(1, sz_str + sizeof(struct ethtool_gstrings));
+ stats = calloc(1, sz_stats + sizeof(struct ethtool_stats));
+ if (!strings || !stats) {
+ ERROR("ethstat - %s No memory available", devname);
+ return 1;
+ }
+
+ strings->cmd = ETHTOOL_GSTRINGS;
+ strings->string_set = ETH_SS_STATS;
+ strings->len = n_stats;
+ ifr->ifr_data = (caddr_t) strings;
+ err = ioctl(fd, SIOCETHTOOL, ifr);
+ if (err < 0) {
+ ERROR("ethstat - %s : Cannot get stats strings information", devname);
+ free(strings);
+ free(stats);
+ return 96;
+ }
+
+ stats->cmd = ETHTOOL_GSTATS;
+ stats->n_stats = n_stats;
+ ifr->ifr_data = (caddr_t) stats;
+ err = ioctl(fd, SIOCETHTOOL, ifr);
+ if (err < 0) {
+ ERROR("ethstat - %s : Cannot get stats information", devname);
+ free(strings);
+ free(stats);
+ return 97;
+ }
+
+ for (i = 0; i < n_stats; i++) {
+ DEBUG("ethstat - %s : %s: %llu",
+ devname,
+ &strings->data[i * ETH_GSTRING_LEN],
+ stats->data[i]);
+ ethstat_submit_value (
+ devname,
+ (char*)&strings->data[i * ETH_GSTRING_LEN],
+ stats->data[i]);
+ }
+ free(strings);
+ free(stats);
+
+
+ return 0;
+}
+
+
+static int ethstat_read(void)
+{
+ struct ifreq ifr;
+ int i;
+
+ for (i = 0 ; i < ifacenumber ; i++) {
+ DEBUG("ethstat - Processing : %s\n", ifacelist[i]);
+ memset(&ifr, 0, sizeof(ifr));
+ strcpy(ifr.ifr_name, ifacelist[i]);
+ getstats(ifacelist[i], &ifr);
+ }
+ return 0;
+}
+
+void module_register (void)
+{
+ ifacelist = malloc(sizeof(char*));
+ plugin_register_config ("ethstat", ethstat_config,
+ config_keys, config_keys_num);
+ plugin_register_read ("ethstat", ethstat_read);
+}
+
+#endif
diff --git a/src/ethstat.h b/src/ethstat.h
--- /dev/null
+++ b/src/ethstat.h
@@ -0,0 +1,78 @@
+/**
+ * collectd - src/ethstat.h
+ * Copyright (C) 2011 Cyril Feraudet
+ *
+ * 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; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * 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:
+ * Cyril Feraudet <cyril at feraudet.com>
+ **/
+
+#define ETHTOOL_BUSINFO_LEN 32
+#define ETHTOOL_GDRVINFO 0x00000003 /* Get driver info. */
+#define ETH_GSTRING_LEN 32
+#define ETHTOOL_GSTRINGS 0x0000001b /* get specified string set */
+#define ETHTOOL_GSTATS 0x0000001d /* get NIC-specific statistics */
+
+enum ethtool_stringset {
+ ETH_SS_TEST = 0,
+ ETH_SS_STATS,
+};
+
+typedef unsigned long long u64;
+typedef unsigned char __u8;
+typedef unsigned short __u16;
+typedef unsigned int __u32;
+typedef unsigned long long __u64;
+
+
+static const char *config_keys[] =
+{
+ "Iface"
+};
+static int config_keys_num = STATIC_ARRAY_SIZE (config_keys);
+
+static char **ifacelist;
+static int ifacenumber = 0;
+struct ethtool_drvinfo {
+ __u32 cmd;
+ char driver[32]; /* driver short name, "tulip", "eepro100" */
+ char version[32]; /* driver version string */
+ char fw_version[32]; /* firmware version string, if applicable */
+ char bus_info[ETHTOOL_BUSINFO_LEN]; /* Bus info for this IF. */
+ /* For PCI devices, use pci_name(pci_dev). */
+ char reserved1[32];
+ char reserved2[16];
+ __u32 n_stats; /* number of u64's from ETHTOOL_GSTATS */
+ __u32 testinfo_len;
+ __u32 eedump_len; /* Size of data from ETHTOOL_GEEPROM (bytes) */
+ __u32 regdump_len; /* Size of data from ETHTOOL_GREGS (bytes) */
+};
+
+struct ethtool_gstrings {
+ __u32 cmd; /* ETHTOOL_GSTRINGS */
+ __u32 string_set; /* string set id e.c. ETH_SS_TEST, etc*/
+ __u32 len; /* number of strings in the string set */
+ __u8 data[0];
+};
+
+struct ethtool_stats {
+ __u32 cmd; /* ETHTOOL_GSTATS */
+ __u32 n_stats; /* number of u64's being returned */
+ __u64 data[0];
+};
+
+
+