From: Florian Forster Date: Thu, 10 Jan 2008 08:48:52 +0000 (+0100) Subject: Merge branch 'collectd-4.1' into collectd-4.2 X-Git-Tag: collectd-4.2.4~4 X-Git-Url: https://git.octo.it/?p=collectd.git;a=commitdiff_plain;h=225494e854ddaa1c0570ac9a5fa15380b333a919;hp=79f871e0c04262f4769d23324236ce75d0b04d3f Merge branch 'collectd-4.1' into collectd-4.2 --- diff --git a/AUTHORS b/AUTHORS index 0c1b3225..ee7e3920 100644 --- a/AUTHORS +++ b/AUTHORS @@ -16,6 +16,9 @@ iptables module by: mbmon plugin by: Flavio Stanchina +memcached plugin by: + Antony Dovgal + nfs module by: Jason Pepas diff --git a/ChangeLog b/ChangeLog index 74a13e05..618f22ca 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,47 @@ +2007-12-28, Version 4.2.3 + * sensors plugin: Updated the plugin to build and work with version 3 + of the libsensors library. + +2007-12-15, Version 4.2.2 + * nginx plugin: Incorrect comparison of strings lead to a segfault + when using the plugin. Thanks to Saulius Grigaliunas for fixing + this. + * logfile plugin: The config option `Timestamp' was handled + incorrectly and basically always active. Thanks to Luke Heberling + for fixing this. + +2007-11-08, Version 4.2.1 + * tcpconns plugin: Don't complain about a missing file if IPv6 is not + enabled on the host. + * snmp plugin: Fix a memory leak. + +2007-10-27, Version 4.2.0 + * collectd: The new config option `Include' lets you include other + configfiles and thus split up your config into smaller parts. This + may be especially interesting for the snmp plugin to keep the data + definitions separate from the host definitions. + * ipvs plugin: The new `ipvs' plugin collects IPVS connection statistics + (number of connections, octets and packets for each service and + destination). Thanks to Sebastian Harl for this plugin. + * memcached plugin: The new `memcached' plugin connects to a memcached + daemon process and collects statistics of this distributed caching + system. Thanks to Antony Dovgal for contributing this plugin. + * nginx plugin: The new `nginx' plugin reads the status page of an + nginx daemon and saves the handled connections and requests. + * perl plugin: Many changes, including the added `EnableDebugger' + config option which lets you debug your Perl plugins more easily. + * rrdtool plugin: Use the thread-safe RRD-library if available. Try to + be more thread-safe otherwise by locking calls to the library. + * snmp plugin: Added the options `Scale' and `Shift' to Data-blocks to + correct the values returned by SNMP-agents. If a block is + defined as `table' the instance is now optional. The sequence number + is used as the type-instance in this case. The new `InstancePrefix' + option allows to add arbitrary prefixes to the type-instance. + * tcpconns plugin: The new `tcpconns' plugin collects the number of + certain TCP connections and what state they're in. This can be used + to see how many connections your FTP server has to handle or how + many outgoing connections your mailserver has open. + 2007-12-27, Version 4.1.5 * rrdtool plugin: Fix a memory leak that only occured in very-low- memory situations. @@ -17,8 +61,8 @@ 2007-10-24, Version 4.1.3 * collectd: A build issue under Solaris has been resolved by renaming data types. - * rrdtool plugin: Use the threadsafe RRD-library if available. Try to - be more threadsafe otherwise by locking calls to the library. + * rrdtool plugin: Use the thread-safe RRD-library if available. Try to + be more thread-safe otherwise by locking calls to the library. 2007-09-28, Version 4.1.2 * apcups plugin: Fix reporting of the `load percent' data. @@ -252,7 +296,7 @@ * The sample config file has been improved. * Errors in the manpages have been corrected. * The ping-plugin now adds hosts during initialization, not during - startup. This speeds up starup when no network connectivity is + startup. This speeds up startup when no network connectivity is available. Also, the hosts are being added later when the network is available. * Improved BSD-support for the df-plugin. @@ -275,7 +319,7 @@ * A plugin to monitor APC UPSes using `apcupsd' has been added. Thanks to Anthony Gialluca for contributing this plugin and providing me with a test environment :) - * A plugin for moniroting an NTP instance and the local clock drift + * A plugin for monitoring an NTP instance and the local clock drift has been added. 2006-06-25, Version 3.9.4 @@ -319,7 +363,7 @@ * A plugin for wireless LAN cards has been added. It monitors signal strength, link quality and noise ratio.. * A plugin for Apple hardware sensors has been added. - * An option to compile collectd with different `step' and `hearbeat' + * An option to compile collectd with different `step' and `heartbeat' settings has been added. The size of RRAs is no longer static but calculated based on the settings for `step' and `width'. * The `ping' plugin can now be configured to use a certain TTL. @@ -344,7 +388,7 @@ `/etc/mtab'. 2006-03-13, Version 3.8.1 - * Fixes for building collectd unter FreeBSD, Mac OS X and Solaris. + * Fixes for building collectd under FreeBSD, Mac OS X and Solaris. * Fixes in the debian `postinst' and `init.d' scripts. 2006-03-09, Version 3.8.0 @@ -354,7 +398,7 @@ 2006-02-18, Version 3.7.2 * A simple bug in the `battery' plugin has been fixed. It should now - work with ACPI based batteries as well. Thankt to Sebastian for + work with ACPI based batteries as well. Thanks to Sebastian for fixing this. * Fixing a bug that prevented collectd to be built without librrd. Thanks to Werner Heuser for reporting it. @@ -395,7 +439,7 @@ * A `df' plugin has been added. * A `mysql' plugin has been added. * The `ping' plugin doesn't entirely give up hope when a socket error - occured, but will back of and increase the intervals between tries. + occurred, but will back of and increase the intervals between tries. 2006-01-21, Version 3.5.2 * Fixed yet another bug in the signal handling.. Stupid typo.. @@ -431,12 +475,12 @@ - `serial', for monitoring traffic on the serial interfaces - `nfs', for graphing NFS procedure calls - `tape', traffic from/to tape devices - * The the memory.rrd now accepts more than 4Gig of memory. + * The memory.rrd now accepts more than 4Gig of memory. 2005-10-26, Version 3.2.0 (Revision 200) * Support for graphing the processes has been added (thanks to Lyonel Vincent) - * If reading from hddtemp failes collectd will increase the time + * If reading from hddtemp fails collectd will increase the time between polls up to one day. * The init.d files have been improved. * Problems with the spec file have been fixed. @@ -460,7 +504,7 @@ 2005-09-09, Version 2.0.0 (Revision 135) * Filenames can no longer be configured at program startup. The only options as of this version are the directory and ping hosts. - * CPU statistics now include Wait-IO. If privided under Linux IRQ and + * CPU statistics now include Wait-IO. If provided under Linux IRQ and Soft-IRQ statistics are added to `System'. * Diskstats now collect read and write bytes, not sectors. * Ping statistics can now be collected for more than one host. There @@ -471,7 +515,7 @@ 2005-09-01, Version 1.8.1 (Revision 123) * Much improved configure-script: libraries and features may now be disabled. - * More detailed warnings/error messages when RRD update failes. + * More detailed warnings/error messages when RRD update fails. 2005-08-29, Version 1.8.0: * Support for collecting disk statistics under Solaris. @@ -482,14 +526,14 @@ libstatgrab returns insufficient information. I will contact the authors. * Improved the CPU-initialization code for Solaris. Apparently CPUs - aren't neccessarily counted linear which is now handled correctly. + aren't necessarily counted linear which is now handled correctly. [1]: http://www.i-scream.org/libstatgrab/ 2005-08-21, Version 1.6.0: * Basic support for Solaris: System load and cpu-usage can be - collected unter Solaris, too. Other stats will follow later. + collected under Solaris, too. Other stats will follow later. * Many fixes in the autoconf-script - * Collection/Museum scripts have been added unter contrib/museum + * Collection/Museum scripts have been added under contrib/museum * collectd may now be started in unprivileged mode, though ping statistics will not work. @@ -502,7 +546,7 @@ about the disks and partitions. 2005-07-11, Version 1.4.2: - * The meminfo mofule has been changed to work with more platforms + * The meminfo module has been changed to work with more platforms and/or kernel versions. 2005-07-10, Version 1.4.1: Correct traffic stats @@ -522,7 +566,7 @@ * The default directory is now /var/db/collectd 2004-07-10, Version 1.1: Minor changes - * Nothing really usefull to say ;) + * Nothing really useful to say ;) 2004-07-09, Version 1.0: Initial Version * The following modules are provided: diff --git a/Makefile.am b/Makefile.am index 34c36cc0..9a96eb27 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,8 +1,8 @@ -SUBDIRS = libltdl src +SUBDIRS = libltdl src bindings INCLUDES = $(LTDLINCL) -EXTRA_DIST = contrib +EXTRA_DIST = contrib version-gen.sh dist-hook: find $(distdir) -type d -name '.svn' | xargs rm -rf diff --git a/README b/README index 37eee3ea..24061549 100644 --- a/README +++ b/README @@ -69,6 +69,11 @@ Features Iptables' counters: Number of bytes that were matched by a certain iptables rule. + - ipvs + IPVS connection statistics (number of connections, octets and packets + for each service and destination). + See http://www.linuxvirtualserver.org/software/index.html. + - irq IRQ counters: Frequency in which certain interrupts occur. @@ -79,6 +84,10 @@ Features Motherboard sensors: temperature, fanspeed and voltage information, using mbmon(1). + - memcached + Statistics of the memcached distributed caching system. + + - memory Memory utilization: Memory occupied by running processes, page cache, buffer cache and free. @@ -105,6 +114,10 @@ Features NFS Procedures: Which NFS command were called how often. Only NFSv2 and NFSv3 right now. + - nginx + Collects statistics from `nginx' (speak: engine X), a HTTP and mail + server/proxy. + - ntp NTP daemon statistics: Local clock drift, offset to peers, etc. @@ -145,6 +158,9 @@ Features - tape Bytes and operations read and written on tape devices. Solaris only. + - tcpconns + Number of TCP connections to specific local and remote ports. + - users Users currently logged in. @@ -261,16 +277,19 @@ Prerequisites platforms. * libcurl (optional) - If you want to use the `apache' plugin + If you want to use the `apache' and/or `nginx' plugins. * libiptc (optional) For querying iptables counters. * libmysqlclient (optional) + Unsurprisingly used by the `mysql' plugin. * libnetlink (optional) + Used, obviously, for the `netlink' plugin. * libnetsnmp (optional) + For the `snmp' plugin. * liboping (optional, if not found a version shipped with this distribution can be used) @@ -286,7 +305,7 @@ Prerequisites instead. * libsensors (optional) - To read from `lm_sensors'. + To read from `lm_sensors', see the `sensors' plugin. * libstatgrab may be used to collect statistics on systems other than Linux and/or Solaris. Note that CPU- and disk-statistics, while being provided diff --git a/bindings/Makefile.am b/bindings/Makefile.am new file mode 100644 index 00000000..c7247252 --- /dev/null +++ b/bindings/Makefile.am @@ -0,0 +1,28 @@ +EXTRA_DIST = perl/Collectd.pm perl/Makefile.PL perl/Collectd/Makefile.PL perl/Collectd/Unixsock.pm + +all-local: @PERL_BINDINGS@ + +install-exec-local: + [ ! -f perl/Makefile ] || ( cd perl && $(MAKE) install ) + +clean-local: + [ ! -f perl/Makefile ] || ( cd perl && $(MAKE) realclean ) + +perl: perl/Makefile + cd perl && $(MAKE) + +perl/Makefile: .perl-directory-stamp perl/Makefile.PL perl/Collectd/Makefile.PL + cd perl && @PERL@ Makefile.PL PREFIX=$(prefix) @PERL_BINDINGS_OPTIONS@ + +.perl-directory-stamp: + if test ! -d perl; then \ + mkdir -p perl/Collectd; \ + cp $(srcdir)/perl/Collectd.pm perl/; \ + cp $(srcdir)/perl/Makefile.PL perl/; \ + cp $(srcdir)/perl/Collectd/Unixsock.pm perl/Collectd/; \ + cp $(srcdir)/perl/Collectd/Makefile.PL perl/Collectd/; \ + fi + touch $@ + +.PHONY: perl + diff --git a/bindings/perl/Collectd.pm b/bindings/perl/Collectd.pm new file mode 100644 index 00000000..fd5632a4 --- /dev/null +++ b/bindings/perl/Collectd.pm @@ -0,0 +1,231 @@ +# collectd - Collectd.pm +# Copyright (C) 2007 Sebastian Harl +# +# 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 +# +# Author: +# Sebastian Harl + +package Collectd; + +use strict; +use warnings; + +require Exporter; + +our @ISA = qw( Exporter ); + +our %EXPORT_TAGS = ( + 'plugin' => [ qw( + plugin_register + plugin_unregister + plugin_dispatch_values + plugin_log + ) ], + 'types' => [ qw( + TYPE_INIT + TYPE_READ + TYPE_WRITE + TYPE_SHUTDOWN + TYPE_LOG + TYPE_DATASET + ) ], + 'ds_types' => [ qw( + DS_TYPE_COUNTER + DS_TYPE_GAUGE + ) ], + 'log' => [ qw( + ERROR + WARNING + NOTICE + INFO + DEBUG + LOG_ERR + LOG_WARNING + LOG_NOTICE + LOG_INFO + LOG_DEBUG + ) ], +); + +{ + my %seen; + push @{$EXPORT_TAGS{'all'}}, grep {! $seen{$_}++ } @{$EXPORT_TAGS{$_}} + foreach keys %EXPORT_TAGS; +} + +Exporter::export_ok_tags ('all'); + +my @plugins = (); +my @datasets = (); + +my %types = ( + TYPE_INIT, "init", + TYPE_READ, "read", + TYPE_WRITE, "write", + TYPE_SHUTDOWN, "shutdown", + TYPE_LOG, "log" +); + +foreach my $type (keys %types) { + $plugins[$type] = {}; +} + +sub _log { + my $caller = shift; + my $lvl = shift; + my $msg = shift; + + if ("Collectd" eq $caller) { + $msg = "perl: $msg"; + } + return plugin_log ($lvl, $msg); +} + +sub ERROR { _log (scalar caller, LOG_ERR, shift); } +sub WARNING { _log (scalar caller, LOG_WARNING, shift); } +sub NOTICE { _log (scalar caller, LOG_NOTICE, shift); } +sub INFO { _log (scalar caller, LOG_INFO, shift); } +sub DEBUG { _log (scalar caller, LOG_DEBUG, shift); } + +sub plugin_call_all { + my $type = shift; + + if (! defined $type) { + return; + } + + if (TYPE_LOG != $type) { + DEBUG ("Collectd::plugin_call: type = \"$type\", args=\"@_\""); + } + + if (! defined $plugins[$type]) { + ERROR ("Collectd::plugin_call: unknown type \"$type\""); + return; + } + + foreach my $plugin (keys %{$plugins[$type]}) { + my $p = $plugins[$type]->{$plugin}; + + if ($p->{'wait_left'} > 0) { + # TODO: use interval_g + $p->{'wait_left'} -= 10; + } + + next if ($p->{'wait_left'} > 0); + + if (my $status = $p->{'code'}->(@_)) { + $p->{'wait_left'} = 0; + $p->{'wait_time'} = 10; + } + elsif (TYPE_READ == $type) { + $p->{'wait_left'} = $p->{'wait_time'}; + $p->{'wait_time'} *= 2; + + if ($p->{'wait_time'} > 86400) { + $p->{'wait_time'} = 86400; + } + + WARNING ("${plugin}->read() failed with status $status. " + . "Will suspend it for $p->{'wait_left'} seconds."); + } + elsif (TYPE_INIT == $type) { + foreach my $type (keys %types) { + plugin_unregister ($type, $plugin); + } + + ERROR ("${plugin}->init() failed with status $status. " + . "Plugin will be disabled."); + } + elsif (TYPE_LOG != $type) { + WARNING ("${plugin}->$types{$type}() failed with status $status."); + } + } + return 1; +} + +# Collectd::plugin_register (type, name, data). +# +# type: +# init, read, write, shutdown, data set +# +# name: +# name of the plugin +# +# data: +# reference to the plugin's subroutine that does the work or the data set +# definition +sub plugin_register { + my $type = shift; + my $name = shift; + my $data = shift; + + DEBUG ("Collectd::plugin_register: " + . "type = \"$type\", name = \"$name\", data = \"$data\""); + + if (! ((defined $type) && (defined $name) && (defined $data))) { + ERROR ("Usage: Collectd::plugin_register (type, name, data)"); + return; + } + + if ((! defined $plugins[$type]) && (TYPE_DATASET != $type)) { + ERROR ("Collectd::plugin_register: Invalid type \"$type\""); + return; + } + + if ((TYPE_DATASET == $type) && ("ARRAY" eq ref $data)) { + return plugin_register_data_set ($name, $data); + } + elsif ("CODE" eq ref $data) { + # TODO: make interval_g available at configuration time + $plugins[$type]->{$name} = { + wait_time => 10, + wait_left => 0, + code => $data, + }; + } + else { + ERROR ("Collectd::plugin_register: Invalid data."); + return; + } + return 1; +} + +sub plugin_unregister { + my $type = shift; + my $name = shift; + + DEBUG ("Collectd::plugin_unregister: type = \"$type\", name = \"$name\""); + + if (! ((defined $type) && (defined $name))) { + ERROR ("Usage: Collectd::plugin_unregister (type, name)"); + return; + } + + if (TYPE_DATASET == $type) { + return plugin_unregister_data_set ($name); + } + elsif (defined $plugins[$type]) { + delete $plugins[$type]->{$name}; + } + else { + ERROR ("Collectd::plugin_unregister: Invalid type."); + return; + } +} + +1; + +# vim: set sw=4 ts=4 tw=78 noexpandtab : + diff --git a/bindings/perl/Collectd/Makefile.PL b/bindings/perl/Collectd/Makefile.PL new file mode 100644 index 00000000..baf71662 --- /dev/null +++ b/bindings/perl/Collectd/Makefile.PL @@ -0,0 +1,8 @@ +use ExtUtils::MakeMaker; + +WriteMakefile( + 'NAME' => 'Collectd::Unixsock', + 'AUTHOR' => 'Florian Forster ', +); + +# vim: set sw=4 ts=4 tw=78 noexpandtab : diff --git a/bindings/perl/Collectd/Unixsock.pm b/bindings/perl/Collectd/Unixsock.pm new file mode 100644 index 00000000..3b8a91cf --- /dev/null +++ b/bindings/perl/Collectd/Unixsock.pm @@ -0,0 +1,322 @@ +package Collectd::Unixsock; + +=head1 NAME + +Collectd::Unixsock - Abstraction layer for accessing the functionality by collectd's unixsock plugin. + +=head1 SYNOPSIS + + use Collectd::Unixsock (); + + my $sock = Collectd::Unixsock->new ($path); + + my $value = $sock->getval (%identifier); + $sock->putval (%identifier, + time => time (), + values => [123, 234, 345]); + + $sock->destroy (); + +=head1 DESCRIPTION + +collectd's unixsock plugin allows external programs to access the values it has +collected or received and to submit own values. This Perl-module is simply a +little abstraction layer over this interface to make it even easier for +programmers to interact with the daemon. + +=cut + +use strict; +use warnings; + +use Carp (qw(cluck confess)); +use IO::Socket::UNIX; +use Regexp::Common (qw(number)); + +return (1); + +sub _create_socket +{ + my $path = shift; + my $sock = IO::Socket::UNIX->new (Type => SOCK_STREAM, Peer => $path); + if (!$sock) + { + cluck ("Cannot open UNIX-socket $path: $!"); + return; + } + return ($sock); +} # _create_socket + +=head1 VALUE IDENTIFIER + +The values in the collectd are identified using an five-tupel (host, plugin, +plugin-instance, type, type-instance) where only plugin-instance and +type-instance may be NULL (or undefined). Many functions expect an +I<%identifier> hash that has at least the members B, B, and +B, possibly completed by B and B. + +Usually you can pass this hash as follows: + + $obj->method (host => $host, plugin => $plugin, type => $type, %other_args); + +=cut + +sub _create_identifier +{ + my $args = shift; + my $host; + my $plugin; + my $type; + + if (!$args->{'host'} || !$args->{'plugin'} || !$args->{'type'}) + { + cluck ("Need `host', `plugin' and `type'"); + return; + } + + $host = $args->{'host'}; + $plugin = $args->{'plugin'}; + $plugin .= '-' . $args->{'plugin_instance'} if (defined ($args->{'plugin_instance'})); + $type = $args->{'type'}; + $type .= '-' . $args->{'type_instance'} if (defined ($args->{'type_instance'})); + + return ("$host/$plugin/$type"); +} # _create_identifier + +sub _parse_identifier +{ + my $string = shift; + my $host; + my $plugin; + my $plugin_instance; + my $type; + my $type_instance; + my $ident; + + ($host, $plugin, $type) = split ('/', $string); + + ($plugin, $plugin_instance) = split ('-', $plugin, 2); + ($type, $type_instance) = split ('-', $type, 2); + + $ident = + { + host => $host, + plugin => $plugin, + type => $type + }; + $ident->{'plugin_instance'} = $plugin_instance if (defined ($plugin_instance)); + $ident->{'type_instance'} = $type_instance if (defined ($type_instance)); + + return ($ident); +} # _parse_identifier + +=head1 PUBLIC METHODS + +=over 4 + +=item I<$obj> = Collectd::Unixsock->B ([I<$path>]); + +Creates a new connection to the daemon. The optional I<$path> argument gives +the path to the UNIX socket of the C and defaults to +F. Returns the newly created object on success and +false on error. + +=cut + +sub new +{ + my $pkg = shift; + my $path = @_ ? shift : '/var/run/collectd-unixsock'; + my $sock = _create_socket ($path) or return; + my $obj = bless ( + { + path => $path, + sock => $sock, + error => 'No error' + }, $pkg); + return ($obj); +} # new + +=item I<$res> = I<$obj>-EB (I<%identifier>); + +Requests a value-list from the daemon. On success a hash-ref is returned with +the name of each data-source as the key and the according value as, well, the +value. On error false is returned. + +=cut + +sub getval +{ + my $obj = shift; + my %args = @_; + + my $status; + my $fh = $obj->{'sock'} or confess; + my $msg; + my $identifier; + + my $ret = {}; + + $identifier = _create_identifier (\%args) or return; + + $msg = "GETVAL $identifier\n"; + #print "-> $msg"; + send ($fh, $msg, 0) or confess ("send: $!"); + + $msg = undef; + recv ($fh, $msg, 1024, 0) or confess ("recv: $!"); + #print "<- $msg"; + + ($status, $msg) = split (' ', $msg, 2); + if ($status <= 0) + { + $obj->{'error'} = $msg; + return; + } + + for (split (' ', $msg)) + { + my $entry = $_; + if ($entry =~ m/^(\w+)=NaN$/) + { + $ret->{$1} = undef; + } + elsif ($entry =~ m/^(\w+)=($RE{num}{real})$/) + { + $ret->{$1} = 0.0 + $2; + } + } + + return ($ret); +} # getval + +=item I<$obj>-EB (I<%identifier>, B