X-Git-Url: https://git.tokkee.org/?a=blobdiff_plain;f=src%2Ftraffic.c;h=14b7dc32b1c6ac9ca33caab29466f5b2a16fd3c2;hb=44d73d6556833bcfbc4678a01731aafee95c3caf;hp=5bf9a502d417ab058d214271045292bd66b454c8;hpb=906bea765c23150bcbe3320bd1b92ff0a704389d;p=collectd.git diff --git a/src/traffic.c b/src/traffic.c index 5bf9a502..14b7dc32 100644 --- a/src/traffic.c +++ b/src/traffic.c @@ -18,11 +18,13 @@ * * Authors: * Florian octo Forster + * Sune Marcher **/ #include "collectd.h" #include "common.h" #include "plugin.h" +#include "configfile.h" #if HAVE_SYS_TYPES_H # include @@ -47,6 +49,18 @@ #define MODULE_NAME "traffic" +/* + * Various people have reported problems with `getifaddrs' and varying versions + * of `glibc'. That's why it's disabled by default. Since more statistics are + * available this way one may enable it using the `--enable-getifaddrs' option + * of the configure script. -octo + */ +#if KERNEL_LINUX +# if !COLLECT_GETIFADDRS +# undef HAVE_GETIFADDRS +# endif /* !COLLECT_GETIFADDRS */ +#endif /* KERNEL_LINUX */ + #if HAVE_GETIFADDRS || KERNEL_LINUX || HAVE_LIBKSTAT || HAVE_LIBSTATGRAB # define TRAFFIC_HAVE_READ 1 #else @@ -55,9 +69,22 @@ #define BUFSIZE 512 +/* + * (Module-)Global variables + */ +/* TODO: Move this to `interface-%s/.rrd' in version 4. */ static char *bytes_file = "traffic-%s.rrd"; -static char *packets_file = "interface-%s/packets.rrd"; -static char *errors_file = "interface-%s/errors.rrd"; +static char *packets_file = "interface-%s/if_packets.rrd"; +static char *errors_file = "interface-%s/if_errors.rrd"; +/* TODO: Maybe implement multicast and broadcast counters */ + +static char *config_keys[] = +{ + "Interface", + "IgnoreSelected", + NULL +}; +static int config_keys_num = 2; static char *bytes_ds_def[] = { @@ -83,6 +110,15 @@ static char *errors_ds_def[] = }; static int errors_ds_num = 2; +static char **if_list = NULL; +static int if_list_num = 0; +/* + * if_list_action: + * 0 => default is to collect selected interface + * 1 => ignore selcted interfaces + */ +static int if_list_action = 0; + #ifdef HAVE_LIBKSTAT #define MAX_NUMIF 256 extern kstat_ctl_t *kc; @@ -90,6 +126,44 @@ static kstat_t *ksp[MAX_NUMIF]; static int numif = 0; #endif /* HAVE_LIBKSTAT */ +static int traffic_config (char *key, char *value) +{ + char **temp; + + if (strcasecmp (key, "Interface") == 0) + { + temp = (char **) realloc (if_list, (if_list_num + 1) * sizeof (char *)); + if (temp == NULL) + { + syslog (LOG_EMERG, "Cannot allocate more memory."); + return (1); + } + if_list = temp; + + if ((if_list[if_list_num] = strdup (value)) == NULL) + { + syslog (LOG_EMERG, "Cannot allocate memory."); + return (1); + } + if_list_num++; + } + else if (strcasecmp (key, "IgnoreSelected") == 0) + { + if ((strcasecmp (value, "True") == 0) + || (strcasecmp (value, "Yes") == 0) + || (strcasecmp (value, "On") == 0)) + if_list_action = 1; + else + if_list_action = 0; + } + else + { + return (-1); + } + + return (0); +} + static void traffic_init (void) { #if HAVE_GETIFADDRS @@ -132,6 +206,26 @@ static void traffic_init (void) return; } +/* + * Check if this interface/instance should be ignored. This is called from + * both, `submit' and `write' to give client and server the ability to + * ignore certain stuff.. + */ +static int check_ignore_if (const char *interface) +{ + int i; + + /* If no interfaces are given collect all interfaces. Mostly to be + * backwards compatible, but also because this is much easier. */ + if (if_list_num < 1) + return (0); + + for (i = 0; i < if_list_num; i++) + if (strcasecmp (interface, if_list[i]) == 0) + return (if_list_action); + return (1 - if_list_action); +} + static void generic_write (char *host, char *inst, char *val, char *file_template, char **ds_def, int ds_num) @@ -139,6 +233,9 @@ static void generic_write (char *host, char *inst, char *val, char file[512]; int status; + if (check_ignore_if (inst)) + return; + status = snprintf (file, BUFSIZE, file_template, inst); if (status < 1) return; @@ -164,19 +261,26 @@ static void errors_write (char *host, char *inst, char *val) } #if TRAFFIC_HAVE_READ -static void bytes_submit (char *device, - unsigned long long incoming, - unsigned long long outgoing) +static void bytes_submit (char *dev, + unsigned long long rx, + unsigned long long tx) { - char buf[BUFSIZE]; + char buf[512]; + int status; - if (snprintf (buf, BUFSIZE, "%u:%lld:%lld", (unsigned int) curtime, incoming, outgoing) >= BUFSIZE) + if (check_ignore_if (dev)) return; - plugin_submit (MODULE_NAME, device, buf); + status = snprintf (buf, 512, "%u:%lld:%lld", + (unsigned int) curtime, + rx, tx); + if ((status >= 512) || (status < 1)) + return; + + plugin_submit (MODULE_NAME, dev, buf); } -#if HAVE_GETIFADDRS +#if HAVE_GETIFADDRS || KERNEL_LINUX || HAVE_LIBKSTAT static void packets_submit (char *dev, unsigned long long rx, unsigned long long tx) @@ -184,6 +288,9 @@ static void packets_submit (char *dev, char buf[512]; int status; + if (check_ignore_if (dev)) + return; + status = snprintf (buf, 512, "%u:%lld:%lld", (unsigned int) curtime, rx, tx); @@ -199,6 +306,9 @@ static void errors_submit (char *dev, char buf[512]; int status; + if (check_ignore_if (dev)) + return; + status = snprintf (buf, 512, "%u:%lld:%lld", (unsigned int) curtime, rx, tx); @@ -206,7 +316,7 @@ static void errors_submit (char *dev, return; plugin_submit ("if_errors", dev, buf); } -#endif /* HAVE_GETIFADDRS */ +#endif /* HAVE_GETIFADDRS || KERNEL_LINUX || HAVE_LIBKSTAT */ static void traffic_read (void) { @@ -279,9 +389,10 @@ static void traffic_read (void) while (fgets (buffer, 1024, fh) != NULL) { - if (buffer[6] != ':') + if (!(dummy = strchr(buffer, ':'))) continue; - buffer[6] = '\0'; + dummy[0] = '\0'; + dummy++; device = buffer; while (device[0] == ' ') @@ -290,24 +401,31 @@ static void traffic_read (void) if (device[0] == '\0') continue; - dummy = buffer + 7; numfields = strsplit (dummy, fields, 16); - if (numfields < 9) + if (numfields < 11) continue; incoming = atoll (fields[0]); outgoing = atoll (fields[8]); - bytes_submit (device, incoming, outgoing); + + incoming = atoll (fields[1]); + outgoing = atoll (fields[9]); + packets_submit (device, incoming, outgoing); + + incoming = atoll (fields[2]); + outgoing = atoll (fields[10]); + errors_submit (device, incoming, outgoing); } fclose (fh); /* #endif KERNEL_LINUX */ -#elif defined(HAVE_LIBKSTAT) +#elif HAVE_LIBKSTAT int i; - unsigned long long incoming, outgoing; + unsigned long long rx; + unsigned long long tx; if (kc == NULL) return; @@ -317,12 +435,20 @@ static void traffic_read (void) if (kstat_read (kc, ksp[i], NULL) == -1) continue; - if ((incoming = get_kstat_value (ksp[i], "rbytes")) == -1LL) - continue; - if ((outgoing = get_kstat_value (ksp[i], "obytes")) == -1LL) - continue; + rx = get_kstat_value (ksp[i], "rbytes"); + tx = get_kstat_value (ksp[i], "obytes"); + if ((rx != -1LL) || (tx != -1LL)) + bytes_submit (ksp[i]->ks_name, rx, tx); + + rx = get_kstat_value (ksp[i], "ipackets"); + tx = get_kstat_value (ksp[i], "opackets"); + if ((rx != -1LL) || (tx != -1LL)) + packets_submit (ksp[i]->ks_name, rx, tx); - bytes_submit (ksp[i]->ks_name, incoming, outgoing); + rx = get_kstat_value (ksp[i], "ierrors"); + tx = get_kstat_value (ksp[i], "oerrors"); + if ((rx != -1LL) || (tx != -1LL)) + errors_submit (ksp[i]->ks_name, rx, tx); } /* #endif HAVE_LIBKSTAT */ @@ -345,6 +471,7 @@ void module_register (void) plugin_register (MODULE_NAME, traffic_init, traffic_read, bytes_write); plugin_register ("if_packets", NULL, NULL, packets_write); plugin_register ("if_errors", NULL, NULL, errors_write); + cf_register (MODULE_NAME, traffic_config, config_keys, config_keys_num); } #undef BUFSIZE