summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: 43066b1)
raw | patch | inline | side by side (parent: 43066b1)
author | Florian Forster <octo@leeloo.lan.home.verplant.org> | |
Sat, 28 Feb 2009 11:12:54 +0000 (12:12 +0100) | ||
committer | Florian Forster <octo@leeloo.lan.home.verplant.org> | |
Sat, 28 Feb 2009 11:18:42 +0000 (12:18 +0100) |
Currently a Linux only plugin. This plugin collects information about
IP, TCP, UDP, etc.
Thanks to Ulf Zimmermann for his (indirect) suggestion ;)
IP, TCP, UDP, etc.
Thanks to Ulf Zimmermann for his (indirect) suggestion ;)
README | patch | blob | history | |
configure.in | patch | blob | history | |
src/Makefile.am | patch | blob | history | |
src/collectd.conf.pod | patch | blob | history | |
src/common.c | patch | blob | history | |
src/common.h | patch | blob | history | |
src/protocols.c | [new file with mode: 0644] | patch | blob |
src/types.db | patch | blob | history |
index a6a5354435da496bc282ec45157a8ab78daccbc2..7889d2c7b48c76aa16d74b882d3200a893788c71 100644 (file)
--- a/README
+++ b/README
- processes
Process counts: Number of running, sleeping, zombie, ... processes.
+ - protocols
+ Counts various aspects of network protocols such as IP, TCP, UDP, etc.
+
- rrdcached
RRDtool caching daemon (RRDcacheD) statistics.
diff --git a/configure.in b/configure.in
index 401604f9f1ad0b534c52177b4e3d89fe50cd31ce..c772f36cc7fd66804ef0999dfb760f2080ea7dff 100644 (file)
--- a/configure.in
+++ b/configure.in
plugin_nfs="no"
plugin_perl="no"
plugin_processes="no"
+plugin_protocols="no"
plugin_serial="no"
plugin_swap="no"
plugin_tape="no"
plugin_memory="yes"
plugin_nfs="yes"
plugin_processes="yes"
+ plugin_protocols="yes"
plugin_serial="yes"
plugin_swap="yes"
plugin_tcpconns="yes"
AC_PLUGIN([postgresql], [$with_libpq], [PostgreSQL database statistics])
AC_PLUGIN([powerdns], [yes], [PowerDNS statistics])
AC_PLUGIN([processes], [$plugin_processes], [Process statistics])
+AC_PLUGIN([protocols], [$plugin_protocols], [Protocol (IP, TCP, ...) statistics])
AC_PLUGIN([rrdcached], [$librrd_rrdc_update], [RRDTool output plugin])
AC_PLUGIN([rrdtool], [$with_librrd], [RRDTool output plugin])
AC_PLUGIN([sensors], [$with_libsensors], [lm_sensors statistics])
diff --git a/src/Makefile.am b/src/Makefile.am
index f4f2be9ffbf3aef09118fd7d1226918f3bb49cdf..5401bba7e0d3cb672e78b7b76f4d47f89e5d3364 100644 (file)
--- a/src/Makefile.am
+++ b/src/Makefile.am
endif
endif
+if BUILD_PLUGIN_PROTOCOLS
+pkglib_LTLIBRARIES += protocols.la
+protocols_la_SOURCES = protocols.c
+protocols_la_LDFLAGS = -module -avoid-version
+collectd_LDADD += "-dlopen" protocols.la
+collectd_DEPENDENCIES += protocols.la
+endif
+
if BUILD_PLUGIN_RRDCACHED
pkglib_LTLIBRARIES += rrdcached.la
rrdcached_la_SOURCES = rrdcached.c utils_rrdcreate.c utils_rrdcreate.h
diff --git a/src/collectd.conf.pod b/src/collectd.conf.pod
index 1ab436078f877e38c2c16a0101c19829082eaede..391f0f32c0aaf03fc6f4ed13a136d2026eb21fa8 100644 (file)
--- a/src/collectd.conf.pod
+++ b/src/collectd.conf.pod
=back
+=head2 Plugin C<protocols>
+
+Collects a lot of information about various network protocols, such as I<IP>,
+I<TCP>, I<UDP>, etc.
+
+Available configuration options:
+
+=over 4
+
+=item B<Value> I<Selector>
+
+Selects whether or not to select a specific value. The string being matched is
+of the form "I<Protocol>:I<ValueName>", where I<Protocol> will be used as the
+plugin instance and I<ValueName> will be used as type instance. An example of
+the string being used would be C<Tcp:RetransSegs>.
+
+You can use regular expressions to match a large number of values with just one
+configuration option. To select all "extended" I<TCP> values, you could use the
+following statement:
+
+ Value "/^TcpExt:/"
+
+Whether only matched values are selected or all matched values are ignored
+depends on the B<IgnoreSelected>. By default, only matched values are selected.
+If no value is configured at all, all values will be selected.
+
+=item B<IgnoreSelected> B<true>|B<false>
+
+If set to B<true>, inverts the selection made by B<Value>, i.E<nbsp>e. all
+matching values will be ignored.
+
+=back
+
=head2 Plugin C<rrdcached>
The C<rrdcached> plugin uses the RRDTool accelerator daemon, L<rrdcached(1)>,
diff --git a/src/common.c b/src/common.c
index ef808851948ccb47d9ba05b7c2913faa4cb95c43..b37db889b36d5c704fb94bb13f29f5650720c6e2 100644 (file)
--- a/src/common.c
+++ b/src/common.c
break;
}
- return (i);
+ return ((int) i);
}
int strjoin (char *dst, size_t dst_len,
diff --git a/src/common.h b/src/common.h
index 72098083e53be05744a6b78e806bc9413a4c1b8d..113f044086bd71803512d19df64e6b92a0de2b10 100644 (file)
--- a/src/common.h
+++ b/src/common.h
*
* DESCRIPTION
* Splits a string into parts and stores pointers to the parts in `fields'.
- * The characters split at are ` ' (space) and "\t" (tab).
+ * The characters split at are: " ", "\t", "\r", and "\n".
*
* PARAMETERS
* `string' String to split. This string will be modified. `fields' will
diff --git a/src/protocols.c b/src/protocols.c
--- /dev/null
+++ b/src/protocols.c
@@ -0,0 +1,248 @@
+/**
+ * collectd - src/protocols.c
+ * Copyright (C) 2009 Florian octo Forster
+ *
+ * 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; only version 2 of the License is applicable.
+ *
+ * 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:
+ * Florian octo Forster <octo at verplant.org>
+ **/
+
+#include "collectd.h"
+#include "common.h"
+#include "plugin.h"
+#include "utils_ignorelist.h"
+
+#if !KERNEL_LINUX
+# error "No applicable input method."
+#endif
+
+#define SNMP_FILE "/proc/net/snmp"
+#define NETSTAT_FILE "/proc/net/netstat"
+
+/*
+ * Global variables
+ */
+static const char *config_keys[] =
+{
+ "Value",
+ "IgnoreSelected",
+};
+static int config_keys_num = STATIC_ARRAY_SIZE (config_keys);
+
+static ignorelist_t *values_list = NULL;
+
+/*
+ * Functions
+ */
+static void submit (const char *protocol_name,
+ const char *str_key, const char *str_value)
+{
+ value_t values[1];
+ value_list_t vl = VALUE_LIST_INIT;
+
+ char *tmp_ptr;
+
+ errno = 0;
+ tmp_ptr = NULL;
+ values[0].counter = (counter_t) strtoll (str_value, &tmp_ptr,
+ /* base = */ 0);
+ if ((errno != 0) || (tmp_ptr == str_value))
+ {
+ ERROR ("protocols plugin: Parsing string as integer failed: %s",
+ str_value);
+ return;
+ }
+
+ vl.values = values;
+ vl.values_len = 1;
+ sstrncpy (vl.host, hostname_g, sizeof (vl.host));
+ sstrncpy (vl.plugin, "protocols", sizeof (vl.plugin));
+ sstrncpy (vl.plugin_instance, protocol_name, sizeof (vl.plugin_instance));
+ sstrncpy (vl.type, "protocol_counter", sizeof (vl.type));
+ sstrncpy (vl.type_instance, str_key, sizeof (vl.type_instance));
+
+ plugin_dispatch_values (&vl);
+} /* void submit */
+
+static int read_file (const char *path)
+{
+ FILE *fh;
+ char key_buffer[4096];
+ char value_buffer[4096];
+ char *key_ptr;
+ char *value_ptr;
+ char *key_fields[256];
+ char *value_fields[256];
+ int key_fields_num;
+ int value_fields_num;
+ int status;
+ int i;
+
+ fh = fopen (path, "r");
+ if (fh == NULL)
+ {
+ ERROR ("protocols plugin: fopen (%s) failed: %s.",
+ path, sstrerror (errno, key_buffer, sizeof (key_buffer)));
+ return (-1);
+ }
+
+ status = -1;
+ while (42)
+ {
+ clearerr (fh);
+ key_ptr = fgets (key_buffer, sizeof (key_buffer), fh);
+ if (key_ptr == NULL)
+ {
+ if (feof (fh) != 0)
+ {
+ status = 0;
+ break;
+ }
+ else if (ferror (fh) != 0)
+ {
+ ERROR ("protocols plugin: Reading from %s failed.", path);
+ break;
+ }
+ else
+ {
+ ERROR ("protocols plugin: fgets failed for an unknown reason.");
+ break;
+ }
+ } /* if (key_ptr == NULL) */
+
+ value_ptr = fgets (value_buffer, sizeof (value_buffer), fh);
+ if (value_ptr == NULL)
+ {
+ ERROR ("protocols plugin: read_file (%s): Could not read values line.",
+ path);
+ break;
+ }
+
+ key_ptr = strchr (key_buffer, ':');
+ if (key_ptr == NULL)
+ {
+ ERROR ("protocols plugin: Could not find protocol name in keys line.");
+ break;
+ }
+ *key_ptr = 0;
+ key_ptr++;
+
+ value_ptr = strchr (value_buffer, ':');
+ if (value_ptr == NULL)
+ {
+ ERROR ("protocols plugin: Could not find protocol name "
+ "in values line.");
+ break;
+ }
+ *value_ptr = 0;
+ value_ptr++;
+
+ if (strcmp (key_buffer, value_buffer) != 0)
+ {
+ ERROR ("protocols plugin: Protocol names in keys and values lines "
+ "don't match: `%s' vs. `%s'.",
+ key_buffer, value_buffer);
+ break;
+ }
+
+
+ key_fields_num = strsplit (key_ptr,
+ key_fields, STATIC_ARRAY_SIZE (key_fields));
+ value_fields_num = strsplit (value_ptr,
+ value_fields, STATIC_ARRAY_SIZE (value_fields));
+
+ if (key_fields_num != value_fields_num)
+ {
+ ERROR ("protocols plugin: Number of fields in keys and values lines "
+ "dont match: %i vs %i.",
+ key_fields_num, value_fields_num);
+ break;
+ }
+
+ for (i = 0; i < key_fields_num; i++)
+ {
+ if (values_list != NULL)
+ {
+ char match_name[2 * DATA_MAX_NAME_LEN];
+
+ ssnprintf (match_name, sizeof (match_name), "%s:%s",
+ key_buffer, key_fields[i]);
+
+ if (ignorelist_match (values_list, match_name))
+ continue;
+ } /* if (values_list != NULL) */
+
+ submit (key_buffer, key_fields[i], value_fields[i]);
+ } /* for (i = 0; i < key_fields_num; i++) */
+ } /* while (42) */
+
+ fclose (fh);
+
+ return (status);
+} /* int read_file */
+
+static int protocols_read (void)
+{
+ int status;
+ int success = 0;
+
+ status = read_file (SNMP_FILE);
+ if (status == 0)
+ success++;
+
+ status = read_file (NETSTAT_FILE);
+ if (status == 0)
+ success++;
+
+ if (success == 0)
+ return (-1);
+
+ return (0);
+} /* int protocols_read */
+
+static int protocols_config (const char *key, const char *value)
+{
+ if (values_list == NULL)
+ values_list = ignorelist_create (/* invert = */ 1);
+
+ if (strcasecmp (key, "Value") == 0)
+ {
+ ignorelist_add (values_list, value);
+ }
+ else if (strcasecmp (key, "IgnoreSelected") == 0)
+ {
+ int invert = 1;
+ if ((strcasecmp (value, "True") == 0)
+ || (strcasecmp (value, "Yes") == 0)
+ || (strcasecmp (value, "On") == 0))
+ invert = 0;
+ ignorelist_set_invert (values_list, invert);
+ }
+ else
+ {
+ return (-1);
+ }
+
+ return (0);
+} /* int protocols_config */
+
+void module_register (void)
+{
+ plugin_register_config ("protocols", protocols_config,
+ config_keys, config_keys_num);
+ plugin_register_read ("protocols", protocols_read);
+} /* void module_register */
+
+/* vim: set sw=2 sts=2 et : */
diff --git a/src/types.db b/src/types.db
index 82b5b4f3c1f5128bfcafac092fbec1af55b83f82..cde4e30943d0b9847ceebec9ab7d4a7310caea62 100644 (file)
--- a/src/types.db
+++ b/src/types.db
ping ping:GAUGE:0:65535
players value:GAUGE:0:1000000
power value:GAUGE:0:U
+protocol_counter value:COUNTER:0:U
ps_count processes:GAUGE:0:1000000, threads:GAUGE:0:1000000
ps_cputime user:COUNTER:0:16000000, syst:COUNTER:0:16000000
ps_pagefaults minflt:COUNTER:0:9223372036854775807, majflt:COUNTER:0:9223372036854775807