X-Git-Url: https://git.octo.it/?a=blobdiff_plain;f=src%2Finterface.c;h=520f4c8d81db6470c7b19f74502e87d551d6b145;hb=633c3966f770e4d46651a2fe219a18d8a9907a9f;hp=52b2ddf0866f07f10abbfb8fb13a16a13b60e7c5;hpb=1fdb04e6cb573ad06b914b9371f21ffb255b1d13;p=collectd.git diff --git a/src/interface.c b/src/interface.c index 52b2ddf0..df8ffb46 100644 --- a/src/interface.c +++ b/src/interface.c @@ -1,6 +1,7 @@ /** * collectd - src/interface.c - * Copyright (C) 2005-2007 Florian octo Forster + * Copyright (C) 2005-2010 Florian octo Forster + * Copyright (C) 2009 Manuel Sanmartin * * 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 @@ -16,14 +17,16 @@ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * * Authors: - * Florian octo Forster + * Florian octo Forster * Sune Marcher + * Manuel Sanmartin **/ #include "collectd.h" #include "common.h" #include "plugin.h" #include "configfile.h" +#include "utils_ignorelist.h" #if HAVE_SYS_TYPES_H # include @@ -46,6 +49,15 @@ # include #endif +#if HAVE_STATGRAB_H +# include +#endif + +#if HAVE_PERFSTAT +# include +# include +#endif + /* * Various people have reported problems with `getifaddrs' and varying versions * of `glibc'. That's why it's disabled by default. Since more statistics are @@ -58,10 +70,14 @@ # endif /* !COLLECT_GETIFADDRS */ #endif /* KERNEL_LINUX */ -#if HAVE_GETIFADDRS || KERNEL_LINUX || HAVE_LIBKSTAT || HAVE_LIBSTATGRAB -# define INTERFACE_HAVE_READ 1 -#else -# define INTERFACE_HAVE_READ 0 +#if HAVE_PERFSTAT +static perfstat_netinterface_t *ifstat; +static int nif; +static int pnif; +#endif /* HAVE_PERFSTAT */ + +#if !HAVE_GETIFADDRS && !KERNEL_LINUX && !HAVE_LIBKSTAT && !HAVE_LIBSTATGRAB && !HAVE_PERFSTAT +# error "No applicable input method." #endif /* @@ -75,14 +91,7 @@ static const char *config_keys[] = }; static int config_keys_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; +static ignorelist_t *ignorelist = NULL; #ifdef HAVE_LIBKSTAT #define MAX_NUMIF 256 @@ -93,33 +102,19 @@ static int numif = 0; static int interface_config (const char *key, const char *value) { - char **temp; + if (ignorelist == NULL) + ignorelist = ignorelist_create (/* invert = */ 1); if (strcasecmp (key, "Interface") == 0) { - temp = (char **) realloc (if_list, (if_list_num + 1) * sizeof (char *)); - if (temp == NULL) - { - ERROR ("Cannot allocate more memory."); - return (1); - } - if_list = temp; - - if ((if_list[if_list_num] = strdup (value)) == NULL) - { - ERROR ("Cannot allocate memory."); - return (1); - } - if_list_num++; + ignorelist_add (ignorelist, value); } 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; + int invert = 1; + if (IS_TRUE (value)) + invert = 0; + ignorelist_set_invert (ignorelist, invert); } else { @@ -132,9 +127,8 @@ static int interface_config (const char *key, const char *value) #if HAVE_LIBKSTAT static int interface_init (void) { -#if HAVE_LIBKSTAT kstat_t *ksp_chain; - unsigned long long val; + derive_t val; numif = 0; @@ -155,54 +149,32 @@ static int interface_init (void) continue; ksp[numif++] = ksp_chain; } -#endif /* HAVE_LIBKSTAT */ return (0); } /* int interface_init */ #endif /* HAVE_LIBKSTAT */ -/* - * 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); -} /* int check_ignore_if */ - -#if INTERFACE_HAVE_READ static void if_submit (const char *dev, const char *type, - unsigned long long rx, - unsigned long long tx) + derive_t rx, + derive_t tx) { value_t values[2]; value_list_t vl = VALUE_LIST_INIT; - if (check_ignore_if (dev)) + if (ignorelist_match (ignorelist, dev) != 0) return; - values[0].counter = rx; - values[1].counter = tx; + values[0].derive = rx; + values[1].derive = tx; vl.values = values; vl.values_len = 2; - vl.time = time (NULL); - strcpy (vl.host, hostname_g); - strcpy (vl.plugin, "interface"); - strncpy (vl.type_instance, dev, sizeof (vl.type_instance)); + sstrncpy (vl.host, hostname_g, sizeof (vl.host)); + sstrncpy (vl.plugin, "interface", sizeof (vl.plugin)); + sstrncpy (vl.plugin_instance, dev, sizeof (vl.plugin_instance)); + sstrncpy (vl.type, type, sizeof (vl.type)); - plugin_dispatch_values (type, &vl); + plugin_dispatch_values (&vl); } /* void if_submit */ static int interface_read (void) @@ -241,18 +213,19 @@ static int interface_read (void) for (if_ptr = if_list; if_ptr != NULL; if_ptr = if_ptr->ifa_next) { - if ((if_data = (struct IFA_DATA *) if_ptr->ifa_data) == NULL) - continue; + if (if_ptr->ifa_addr != NULL && if_ptr->ifa_addr->sa_family == AF_LINK) { + if_data = (struct IFA_DATA *) if_ptr->ifa_data; - if_submit (if_ptr->ifa_name, "if_octets", + if_submit (if_ptr->ifa_name, "if_octets", if_data->IFA_RX_BYTES, if_data->IFA_TX_BYTES); - if_submit (if_ptr->ifa_name, "if_packets", + if_submit (if_ptr->ifa_name, "if_packets", if_data->IFA_RX_PACKT, if_data->IFA_TX_PACKT); - if_submit (if_ptr->ifa_name, "if_errors", + if_submit (if_ptr->ifa_name, "if_errors", if_data->IFA_RX_ERROR, if_data->IFA_TX_ERROR); + } } freeifaddrs (if_list); @@ -261,9 +234,9 @@ static int interface_read (void) #elif KERNEL_LINUX FILE *fh; char buffer[1024]; - unsigned long long incoming, outgoing; + derive_t incoming, outgoing; char *device; - + char *dummy; char *fields[16]; int numfields; @@ -289,7 +262,7 @@ static int interface_read (void) if (device[0] == '\0') continue; - + numfields = strsplit (dummy, fields, 16); if (numfields < 11) @@ -313,8 +286,8 @@ static int interface_read (void) #elif HAVE_LIBKSTAT int i; - unsigned long long rx; - unsigned long long tx; + derive_t rx; + derive_t tx; if (kc == NULL) return (-1); @@ -324,16 +297,29 @@ static int interface_read (void) if (kstat_read (kc, ksp[i], NULL) == -1) continue; - rx = get_kstat_value (ksp[i], "rbytes"); - tx = get_kstat_value (ksp[i], "obytes"); + /* try to get 64bit counters */ + rx = get_kstat_value (ksp[i], "rbytes64"); + tx = get_kstat_value (ksp[i], "obytes64"); + /* or fallback to 32bit */ + if (rx == -1LL) + rx = get_kstat_value (ksp[i], "rbytes"); + if (tx == -1LL) + tx = get_kstat_value (ksp[i], "obytes"); if ((rx != -1LL) || (tx != -1LL)) if_submit (ksp[i]->ks_name, "if_octets", rx, tx); - rx = get_kstat_value (ksp[i], "ipackets"); - tx = get_kstat_value (ksp[i], "opackets"); + /* try to get 64bit counters */ + rx = get_kstat_value (ksp[i], "ipackets64"); + tx = get_kstat_value (ksp[i], "opackets64"); + /* or fallback to 32bit */ + if (rx == -1LL) + rx = get_kstat_value (ksp[i], "ipackets"); + if (tx == -1LL) + tx = get_kstat_value (ksp[i], "opackets"); if ((rx != -1LL) || (tx != -1LL)) if_submit (ksp[i]->ks_name, "if_packets", rx, tx); + /* no 64bit error counters yet */ rx = get_kstat_value (ksp[i], "ierrors"); tx = get_kstat_value (ksp[i], "oerrors"); if ((rx != -1LL) || (tx != -1LL)) @@ -349,11 +335,47 @@ static int interface_read (void) for (i = 0; i < num; i++) if_submit (ios[i].interface_name, "if_octets", ios[i].rx, ios[i].tx); -#endif /* HAVE_LIBSTATGRAB */ +/* #endif HAVE_LIBSTATGRAB */ + +#elif defined(HAVE_PERFSTAT) + perfstat_id_t id; + int i, ifs; + + if ((nif = perfstat_netinterface(NULL, NULL, sizeof(perfstat_netinterface_t), 0)) < 0) + { + char errbuf[1024]; + WARNING ("interface plugin: perfstat_netinterface: %s", + sstrerror (errno, errbuf, sizeof (errbuf))); + return (-1); + } + + if (pnif != nif || ifstat == NULL) + { + if (ifstat != NULL) + free(ifstat); + ifstat = malloc(nif * sizeof(perfstat_netinterface_t)); + } + pnif = nif; + + id.name[0]='\0'; + if ((ifs = perfstat_netinterface(&id, ifstat, sizeof(perfstat_netinterface_t), nif)) < 0) + { + char errbuf[1024]; + WARNING ("interface plugin: perfstat_netinterface (interfaces=%d): %s", + nif, sstrerror (errno, errbuf, sizeof (errbuf))); + return (-1); + } + + for (i = 0; i < ifs; i++) + { + if_submit (ifstat[i].name, "if_octets", ifstat[i].ibytes, ifstat[i].obytes); + if_submit (ifstat[i].name, "if_packets", ifstat[i].ipackets ,ifstat[i].opackets); + if_submit (ifstat[i].name, "if_errors", ifstat[i].ierrors, ifstat[i].oerrors ); + } +#endif /* HAVE_PERFSTAT */ return (0); } /* int interface_read */ -#endif /* INTERFACE_HAVE_READ */ void module_register (void) { @@ -362,7 +384,5 @@ void module_register (void) #if HAVE_LIBKSTAT plugin_register_init ("interface", interface_init); #endif -#if INTERFACE_HAVE_READ plugin_register_read ("interface", interface_read); -#endif } /* void module_register */