/**
* collectd - src/interface.c
- * Copyright (C) 2005-2007 Florian octo Forster
+ * Copyright (C) 2005-2008 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
* Authors:
* Florian octo Forster <octo at verplant.org>
* Sune Marcher <sm at flork.dk>
+ * Manuel Sanmartin
**/
#include "collectd.h"
#include "common.h"
#include "plugin.h"
#include "configfile.h"
+#include "utils_ignorelist.h"
#if HAVE_SYS_TYPES_H
# include <sys/types.h>
# include <statgrab.h>
#endif
+#if HAVE_PERFSTAT
+# include <sys/protosw.h>
+# include <libperfstat.h>
+#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
# endif /* !COLLECT_GETIFADDRS */
#endif /* KERNEL_LINUX */
-#if !HAVE_GETIFADDRS && !KERNEL_LINUX && !HAVE_LIBKSTAT && !HAVE_LIBSTATGRAB
+#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
};
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
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
{
} /* 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 */
-
static void if_submit (const char *dev, const char *type,
unsigned long long rx,
unsigned long long 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;
vl.values = values;
vl.values_len = 2;
- vl.time = time (NULL);
sstrncpy (vl.host, hostname_g, sizeof (vl.host));
sstrncpy (vl.plugin, "interface", sizeof (vl.plugin));
sstrncpy (vl.type, type, sizeof (vl.type));
char buffer[1024];
unsigned long long incoming, outgoing;
char *device;
-
+
char *dummy;
char *fields[16];
int numfields;
if (device[0] == '\0')
continue;
-
+
numfields = strsplit (dummy, fields, 16);
if (numfields < 11)
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 */