From: Florian Forster Date: Sat, 1 May 2010 09:02:57 +0000 (+0200) Subject: Merge remote branch 'powdahound/master' X-Git-Tag: collectd-4.10.0~2 X-Git-Url: https://git.octo.it/?p=collectd.git;a=commitdiff_plain;h=ff8390d53b08dd36f8b0c5f4e530fe7ea9f21b90;hp=c9a98da0bdd86f7a13bbc6b00a016941d6e79dd6 Merge remote branch 'powdahound/master' --- diff --git a/.mailmap b/.mailmap index 9bb4399e..a39a1d22 100644 --- a/.mailmap +++ b/.mailmap @@ -5,4 +5,5 @@ Luboš Staněk Luboš Staněk Niki W. Waibel Sebastian Harl +Rodolphe Quiedeville diff --git a/AUTHORS b/AUTHORS index 885d021a..45689652 100644 --- a/AUTHORS +++ b/AUTHORS @@ -23,6 +23,7 @@ Alvaro Barcellos Amit Gupta - Multiple servers in the apache plugin. + - curl_xml plugin. Anthony Dewhurst - zfs_arc plugin. @@ -82,9 +83,21 @@ Luke Herberling Lyonel Vincent - processes plugin. +Manuel Sanmartin + - AIX port of the following plugins: + + cpu + + disk + + interface + + load + + memory + + processes + + swap + - Various AIX-related fixes and hacks. + Marco Chiappero - uptime plugin. - ip6tables support in the iptables plugin. + - openvpn plugin (support for more status file formats) Michael Stapelberg - OpenBSD port of the tcpconns plugin. @@ -127,6 +140,9 @@ Peter Holik - Some bugfixes in the exec plugin. - Notifications in the ipmi plugin. +Phoenix Kayo + - pinba plugin. + Piotr Hosowicz - SMF manifest for collectd. @@ -154,6 +170,7 @@ Stefan Hacker Sven Trenkel - netapp plugin. + - python plugin. Tomasz Pala - conntrack plugin. diff --git a/ChangeLog b/ChangeLog index ecc3869d..8696d468 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,213 @@ +2010-05-01, Version 4.10.0 + * collectd: JSON output now includes the "dstypes" and "dsnames" + fields. This makes it easier for external applications to interpret + the data. Thanks to Chris Buben for his work. + * collectd: The new "Timeout" option can be used to specify a + "timeout" for missing values. This is used in the threshold checking + code to detect missing values. Thanks to Andrés J. Díaz for the + patch. + * apache plugin: Support for "IdleWorkers" (Apache 1.*: "IdleServers") + has been added. + * curl plugin: The new "ExcludeRegex" allows to easily exclude certain + lines from the match. + * curl_xml plugin: This new plugin allows to read XML files using cURL + and extract metrics included in the files. Thanks to Amit Gupta for + his work. + * filecount plugin: The new "IncludeHidden" option allows to include + "hidden" files and directories in the statistics. Thanks to Vaclav + Malek for the patch. + * logfile plugin: The new "PrintSeverity" option allows to include the + severity of a message in the output. Thanks to Clément Stenac for + his patch. + * memcachec plugin: The new "ExcludeRegex" allows to easily exclude + certain lines from the match. + * modbus plugin: This new plugin allows to read registers from + Modbus-TCP enabled devices. + * network plugin: The new "Interface" option allows to set the + interface to be used for multicast and, if supported, unicast + traffic. Thanks to Max Henkel for his work. + * openvpn plugin: The "CollectUserCount" and "CollectIndividualUsers" + options allow more detailed control over how to report sessions of + multiple users. Thanks to Fabian Schuh for his work. + * pinba plugin: This new plugin receives timing information from the + Pinba PHP extension, which can be used for profiling PHP code and + webserver performance. + * ping plugin: The new "MaxMissed" allows to re-resolve a hosts + address when it doesn't reply to a number of ping requests. Thanks + to Stefan Völkel for the patch. + * postgresql plugin: The "Interval" config option has been added. The + plugin has been relicensed under the 2-clause BSD license. Thanks to + Sebastian Harl for his work. + * processes plugin: Support for "code" and "data" virtual memory sizes + has been added. Thanks to Clément Stenac for his patch. + * python plugin: Support for Python 3 has been implemented. Thanks to + Sven Trenkel for his work. + * routeros plugin: Support for collecting CPU load, memory usage, used + and free disk space, sectors written and number of bad blocks from + MikroTik devices has been added. + * swap plugin: Support for Linux < 2.6 has been added. Thanks to Lorin + Scraba for his patch. + * tail plugin: The new "ExcludeRegex" allows to easily exclude certain + lines from the match. Thanks to Peter Warasin for his patch. + * write_http plugin: The "StoreRates" option has been added. Thanks to + Paul Sadauskas for his patch. + * regex match: The "Invert" option has been added. Thanks to Julien + Ammous for his patch. + +2010-04-22, Version 4.9.2 + * Build system, various plugins: Fixes for AIX compatibility have been + added. Thanks to Manuel Sanmartin for his patches. + * Build system: Checking for "nanosleep" on old Solaris machines has + been fixed. Thanks to Vincent McIntyre and Sebastian Harl for + figuring out a way to make this work. + * collectd: Append a newline to messages written to STDERR. + * collectd: Serialization of NANs in JSON format has been fixed. + Thanks to Chris Buben for pointing out the resulting syntax error. + * collectd: Checks whether a "sleep" returned early have been added; + the cases are now handled correctly. Thanks to Michael Stapelberg + for the patch. + * collectd: Continue reading files in a directory when parsing one + file fails. + * apache plugin: Collection of the number of active connections has + been fixed for Apache 2.*. + * contextswitch plugin: Handle large counter/derive values correctly. + Thanks to Martin Merkel for reporting the bug. + * exec plugin: Error messages have been improved. The "running" flag + is now cleared correctly when forking a child fails. + * iptables plugin: Fix a violation of aliasing rules. This resolves a + warning / error with new GCC versions. Thanks to Jan Engelhardt for + the work-around. + * java plugin: The Java API files are now packaged into a .jar file. + Thanks to Amit Gupta for his patch. + * network plugin: Fix a segmentation fault when receiving packets with + an unknown data source type. + * network plugin: A memory leak when receiving encrypted network + packets has been fixed. + * openvpn plugin: Fix naming schema when reading "MULTI1" type status + files. + * oracle plugin: Fix checking for lost connections and reconnect in + this case. Thanks to Sven Trenkel for pointing out the problem. + * unixsock plugin: A memory leak in the "LISTVAL" command has been + fixed. Thanks to Peter Warasin for pointing it out. + * write_http plugin: Use the "any" authentication schema. This used to + be "digest". Thanks to Paul Sadauskas for the patch. + +2010-01-14, Version 4.9.1 + * Documentation: Some manpage fixes. + * Default config: Added sample configuration for missing plugins. + * apache plugin: Fix a segmentation fault in the config handling of + VerifyPeer / VerifyHost. Thanks to "plazmus" for his or her patch. + * processes plugin: Fix handling of derive data sources. + * rrdtool plugin: Fix a bug with random write timeouts. Due to an + incorrect initialization some files may be suspended basically + indefinitely. After flushing the files they were written regularly + again. + * routeros plugin: Use the node name for the "host" field. + * Monitorus.pm: Put the plugin into the "Collectd::Plugins" namespace. + * Perl bindings: Fix a warning that was printed when building + debugging output. + +2009-12-21, Version 4.9.0 + * contextswitch plugin: The new ContextSwitch plugin gathers the + number of context switches done by the CPU. Thanks to Patrik + Weiskircher for the patch. + * cpu plugin: Support for SMP (multiple processors) under FreeBSD has + been added. Thanks to Doug MacEachern for the patch. + * curl plugin: The “MeasureResponseTime” option has been added. Thanks + to Aman Gupta for the patch. + * df plugin: Collecting the inode count and reserved space has been + added. Thanks to Patrik Weiskircher for the patch. + * exec plugin: The environment variables “COLLECTD_INTERVAL” and + “COLLECTD_HOSTNAME” are now set before executing the application. + * Monitorus plugin: This Perl-based plugin to query statistics from + mon.itor.us has been added. Thanks to Jeff Green for the patch. + * netapp plugin: New plugin to collect statistics from NetApp filers. + Thanks to Sven Trenkel of the noris network AG for the patch. + * network plugin: Statistics collection about the plugin itself has + been implemented. + * openvpn plugin: Add support for more versions of the “status file”. + Thanks to Marco Chiappero for the patch. + * OpenVZ plugin: This Perl-based plugin to gather OpenVZ statistics + has been added. Thanks to Jonathan Kolb for the patch. + * ping plugin: The config options "SourceAddress" and "Device" + have been added. Thanks to Sebastian Harl for the patch. + * processes plugin: Collection of IO-metrics has been added. Thanks to + Andrés J. Díaz for the patch. + * python plugin: The new Python plugin integrates a Python interpreter + into collectd and allows to execute plugins written in the scripting + language. Thanks to Sven Trenkel for his work. + * routeros plugin: The new RouterOS plugin queries interface and + wireless registration statistics from RouterOS. + * Various plugins: AIX support has been added to the cpu, disk, + interface, load, memory, processes, and swap plugins. Thanks to + Manuel Sanmartin for his patches. + * hashed match: This match for simple load balancing and redundant + storage has been added. + * scale target: This target to scale (multiply) values by an arbitrary + value has been added. + +2010-04-22, Version 4.8.5 + * collectd: Append a newline to messages written to STDERR. + * network plugin: Fix a segmentation fault when receiving packets with + an unknown data source type. + +2010-04-07, Version 4.8.4 + * Build system, various plugins: Fixes for AIX compatibility have been + added. Thanks to Manuel Sanmartin for his patches. + * Build system: Checking for "nanosleep" on old Solaris machines has + been fixed. Thanks to Vincent McIntyre and Sebastian Harl for + figuring out a way to make this work. + * collectd: Serialization of NANs in JSON format has been fixed. + Thanks to Chris Buben for pointing out the resulting syntax error. + * collectd: Checks whether a "sleep" returned early have been added; + the cases are now handled correctly. Thanks to Michael Stapelberg + for the patch. + * collectd: Continue reading files in a directory when parsing one + file fails. + * apache plugin: Collection of the number of active connections has + been fixed for Apache 2.*. + * exec plugin: Error messages have been improved. The "running" flag + is now cleared correctly when forking a child fails. + * iptables plugin: Fix a violation of aliasing rules. This resolves a + warning / error with new GCC versions. Thanks to Jan Engelhardt for + the work-around. + * java plugin: The Java API files are now packaged into a .jar file. + Thanks to Amit Gupta for his patch. + * network plugin: A memory leak when receiving encrypted network + packets has been fixed. + * oracle plugin: Fix checking for lost connections and reconnect in + this case. Thanks to Sven Trenkel for pointing out the problem. + * unixsock plugin: A memory leak in the "LISTVAL" command has been + fixed. Thanks to Peter Warasin for pointing it out. + * write_http plugin: Use the "any" authentication schema. This used to + be "digest". Thanks to Paul Sadauskas for the patch. + +2010-01-14, Version 4.8.3 + * Documentation: Some manpage fixes. + * rrdtool plugin: Fix a bug with random write timeouts. Due to an + incorrect initialization some files may be suspended basically + indefinitely. After flushing the files they were written regularly + again. + +2009-12-18, Version 4.8.2 + * Build system, java plugin: Don't use “find -L” to search for Java + headers, because it's a GNU extension. + * Build system: Support for parallel builds has been improved. Thanks + Sebastian Harl and Stefan Völkel for looking into this. + * collectd: Print error messages to STDERR if no log plugin has been + loaded. + * genericjmx plugin: Close and re-open the connection upon I/O-errors. + * gmond plugin: Fix typos which caused syntax errors. + * memory plugin: Handling of >4 Gbyte of memory has been fixed. + * network plugin: The license has been changed to LGPL 2.1. + * oracle plugin: Reconnect to the database if the connection dies. + * rrdcached plugin: Work-around for a bug in RRDtool 1.4rc2 has been + added. + * snmp plugin: Handling of negative values has been fixed. Strings + containing control characters are now interpreted as hex-strings. + * unixsock plugin: A memory leak in the LISTVAL command has been + fixed. Thanks to Ben Knight for his patch. + 2009-10-04, Version 4.8.1 * Build system: Issues when building the iptables plugin have been fixed. @@ -14,7 +224,7 @@ been added. “DERIVE” can be used for counters that are reset occasionally. Thanks to Mariusz Gronczewski for implementing this. * thresholds: The advanced threshold options “Percentage”, “Hits”, and - “Hysteresis” have been added. Thanks to Andrés J. Díaz for hit + “Hysteresis” have been added. Thanks to Andrés J. Díaz for his patches. * curl_json plugin: The new cURL-JSON plugin reads JSON files using the cURL library and parses the contents according to user @@ -58,6 +268,23 @@ lists, where at least one data source is of type COUNTER and the counter value of all counter data sources is zero. +2009-12-18, Version 4.7.5 + * Build system, java plugin: Don't use “find -L” to search for Java + headers, because it's a GNU extension. + * Build system: Support for parallel builds has been improved. Thanks + Sebastian Harl and Stefan Völkel for looking into this. + * collectd: Print error messages to STDERR if no log plugin has been + loaded. + * memory plugin: Handling of >4 Gbyte of memory has been fixed. + * network plugin: The license has been changed to LGPL 2.1. + * oracle plugin: Reconnect to the database if the connection dies. + * rrdcached plugin: Work-around for a bug in RRDtool 1.4rc2 has been + added. + * snmp plugin: Handling of negative values has been fixed. Strings + containing control characters are now interpreted as hex-strings. + * unixsock plugin: A memory leak in the LISTVAL command has been + fixed. Thanks to Ben Knight for his patch. + 2009-10-03, Version 4.7.4 * Build system: Issues when building the iptables plugin have been fixed. diff --git a/README b/README index d40fd2f0..ade430cc 100644 --- a/README +++ b/README @@ -57,6 +57,10 @@ Features Retrieves JSON data via cURL and parses it according to user configuration. + - curl_xml + Retrieves XML data via cURL and parses it according to user + configuration. + - dbi Executes SQL statements on various databases and interprets the returned data. @@ -143,6 +147,10 @@ Features Memory utilization: Memory occupied by running processes, page cache, buffer cache and free. + - modbus + Reads values from Modbus/TCP enabled devices. Supports reading values + from multiple "slaves" so gateway devices can be used. + - multimeter Information provided by serial multimeters, such as the `Metex M-4650CR'. @@ -200,6 +208,10 @@ Features write your own plugins in Perl and return arbitrary values using this API. See collectd-perl(5). + - pinba + Receive and dispatch timing values from Pinba, a profiling extension for + PHP. + - ping Network latency: Time to reach the default gateway or another given host. @@ -217,6 +229,15 @@ Features - protocols Counts various aspects of network protocols such as IP, TCP, UDP, etc. + - python + The python plugin implements a Python interpreter into collectd. This + makes it possible to write plugins in Python which are executed by + collectd without the need to start a heavy interpreter every interval. + See collectd-python(5) for details. + + - routeros + Query interface and wireless registration statistics from RouterOS. + - rrdcached RRDtool caching daemon (RRDcacheD) statistics. @@ -284,7 +305,7 @@ Features - zfs_arc Statistics for ZFS' “Adaptive Replacement Cache” (ARC). - * Output can be written or send to various destinations by the following + * Output can be written or sent to various destinations by the following plugins: - csv @@ -301,6 +322,10 @@ Features you can easily do weird stuff with the plugins we didn't dare think of ;) See collectd-perl(5). + - python + It's possible to implement write plugins in Python using the python + plugin. See collectd-python(5) for details. + - rrdcached Output to round-robin-database (RRD) files using the RRDtool caching daemon (RRDcacheD) - see rrdcached(1). That daemon provides a general @@ -333,6 +358,10 @@ Features Log messages are propagated to plugins written in Perl as well. See collectd-perl(5). + - python + It's possible to implement log plugins in Python using the python plugin. + See collectd-python(5) for details. + - syslog Logs to the standard UNIX logging mechanism, syslog. @@ -362,12 +391,19 @@ Features Notifications are propagated to plugins written in Perl as well. See collectd-perl(5). + - python + It's possible to implement notification plugins in Python using the + python plugin. See collectd-python(5) for details. + * Value processing can be controlled using the "filter chain" infrastructure and "matches" and "targets". The following plugins are available: - match_empty_counter Match counter values which are currently zero. + - match_hashed + Match values using a hash function of the hostname. + - match_regex Match values by their identifier based on regular expressions. @@ -383,6 +419,9 @@ Features - target_replace Replace parts of an identifier using regular expressions. + - target_scale + Scale (multiply) values by an arbitrary value. + - target_set Set (overwrite) entire parts of an identifier. @@ -399,7 +438,7 @@ Features network plugins, makes sure your resources are used efficiently. Also, since collectd is programmed multithreaded it benefits from hyperthreading and multicore processors and makes sure that the daemon isn't idle if only - one plugins waits for an IO-operation to complete. + one plugin waits for an IO-operation to complete. * Once set up, hardly any maintenance is necessary. Setup is kept as easy as possible and the default values should be okay for most users. @@ -510,11 +549,15 @@ Prerequisites Used by the `memcachec' plugin to connect to a memcache daemon. + * libmodbus (optional) + Used by the `modbus' plugin to communicate with Modbus/TCP devices. + + * libmysqlclient (optional) Unsurprisingly used by the `mysql' plugin. - * libnatapp (optional) + * libnetapp (optional) Required for the “netapp” plugin. This library is part of the “Manage ONTAP SDK” published by NetApp. @@ -552,6 +595,19 @@ Prerequisites The PostgreSQL C client library used by the `postgresql' plugin. + * libprotobuf-c, protoc-c (optional) + Used by the `pinba' plugin to generate a parser for the network packets + sent by the Pinba PHP extension. + + + * libpython (optional) + Used by the `python' plugin. Currently, only 2.3 ≦ Python < 3 is supported. + + + * librouteros (optional) + Used by the `routeros' plugin to connect to a device running `RouterOS'. + + * librrd (optional) Used by the `rrdtool' and `rrdcached' plugins. The latter requires RRDtool client support which was added after version 1.3 of RRDtool. Versions 1.0, diff --git a/TODO b/TODO index 3c8f49eb..009eb7fc 100644 --- a/TODO +++ b/TODO @@ -5,9 +5,6 @@ src/battery.c: commend not working code. Wishlist: -* Update the RPM specfile to - - build `collectd-apache' - - be free of syntax errors. * Port nfs module to solaris * Port tape module to Linux * Port the apple_sensors plugin to Linux/PPC. diff --git a/bindings/Makefile.am b/bindings/Makefile.am index fb68657c..f39e9bbb 100644 --- a/bindings/Makefile.am +++ b/bindings/Makefile.am @@ -4,8 +4,11 @@ if BUILD_WITH_JAVA SUBDIRS += java endif -EXTRA_DIST = perl/Collectd.pm perl/Makefile.PL perl/Collectd/Makefile.PL \ - perl/Collectd/Unixsock.pm +EXTRA_DIST = perl/Makefile.PL \ + perl/lib/Collectd.pm \ + perl/lib/Collectd/Unixsock.pm \ + perl/lib/Collectd/Plugins/Monitorus.pm \ + perl/lib/Collectd/Plugins/OpenVZ.pm all-local: @PERL_BINDINGS@ @@ -19,16 +22,16 @@ perl: perl/Makefile cd perl && $(MAKE) perl/Makefile: .perl-directory-stamp perl/Makefile.PL \ - perl/Collectd/Makefile.PL $(top_builddir)/config.status + $(top_builddir)/config.status cd perl && @PERL@ Makefile.PL PREFIX=$(prefix) @PERL_BINDINGS_OPTIONS@ .perl-directory-stamp: if test ! -d perl; then \ - mkdir -p perl/Collectd; \ + mkdir -p perl/Collectd/Plugins; \ 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/; \ + cp $(srcdir)/perl/Collectd/Plugins/OpenVZ.pm perl/Collectd/Plugins/; \ fi touch $@ diff --git a/bindings/java/Makefile.am b/bindings/java/Makefile.am index d3315acc..fa253f65 100644 --- a/bindings/java/Makefile.am +++ b/bindings/java/Makefile.am @@ -27,19 +27,22 @@ EXTRA_DIST = org/collectd/api/CollectdConfigInterface.java \ java-build-stamp: org/collectd/api/*.java $(JAVAC) -d "." "$(srcdir)/org/collectd/api"/*.java $(JAVAC) -d "." "$(srcdir)/org/collectd/java"/*.java + mkdir -p .libs + $(JAR) cf .libs/collectd-api.jar "org/collectd/api"/*.class + $(JAR) cf .libs/generic-jmx.jar "org/collectd/java"/*.class touch "$@" all-local: java-build-stamp install-exec-local: java-build-stamp - mkdir -p "$(DESTDIR)$(pkgdatadir)/java/org/collectd/api" - $(INSTALL) -m 644 "org/collectd/api"/*.class \ - "$(DESTDIR)$(pkgdatadir)/java/org/collectd/api/" - mkdir -p "$(DESTDIR)$(pkgdatadir)/java/org/collectd/java" - $(INSTALL) -m 644 "org/collectd/java"/*.class \ - "$(DESTDIR)$(pkgdatadir)/java/org/collectd/java/" + mkdir -p "$(DESTDIR)$(pkgdatadir)/java" + $(INSTALL) -m 644 .libs/collectd-api.jar \ + "$(DESTDIR)$(pkgdatadir)/java" + $(INSTALL) -m 644 .libs/generic-jmx.jar \ + "$(DESTDIR)$(pkgdatadir)/java" clean-local: rm -f "org/collectd/api"/*.class rm -f "org/collectd/java"/*.class + rm -f .libs rm -f "java-build-stamp" diff --git a/bindings/java/org/collectd/java/GenericJMXConfConnection.java b/bindings/java/org/collectd/java/GenericJMXConfConnection.java index 7214fd76..ffa9ded4 100644 --- a/bindings/java/org/collectd/java/GenericJMXConfConnection.java +++ b/bindings/java/org/collectd/java/GenericJMXConfConnection.java @@ -208,7 +208,16 @@ private void connect () /* {{{ */ pd.setPlugin ("GenericJMX"); for (int i = 0; i < this._mbeans.size (); i++) - this._mbeans.get (i).query (this._jmx_connection, pd); + { + int status; + + status = this._mbeans.get (i).query (this._jmx_connection, pd); + if (status != 0) + { + this._jmx_connection = null; + return; + } + } /* for */ } /* }}} void query */ public String toString () diff --git a/bindings/java/org/collectd/java/GenericJMXConfMBean.java b/bindings/java/org/collectd/java/GenericJMXConfMBean.java index 27e9e329..1587bd5f 100644 --- a/bindings/java/org/collectd/java/GenericJMXConfMBean.java +++ b/bindings/java/org/collectd/java/GenericJMXConfMBean.java @@ -170,7 +170,7 @@ class GenericJMXConfMBean return (this._name); } /* }}} */ - public void query (MBeanServerConnection conn, PluginData pd) /* {{{ */ + public int query (MBeanServerConnection conn, PluginData pd) /* {{{ */ { Set names; Iterator iter; @@ -182,7 +182,7 @@ class GenericJMXConfMBean catch (Exception e) { Collectd.logError ("GenericJMXConfMBean: queryNames failed: " + e); - return; + return (-1); } if (names.size () == 0) @@ -236,6 +236,8 @@ class GenericJMXConfMBean for (int i = 0; i < this._values.size (); i++) this._values.get (i).query (conn, objName, pd_tmp); } + + return (0); } /* }}} void query */ } diff --git a/bindings/perl/Collectd.pm b/bindings/perl/Collectd.pm deleted file mode 100644 index 557950cb..00000000 --- a/bindings/perl/Collectd.pm +++ /dev/null @@ -1,648 +0,0 @@ -# collectd - Collectd.pm -# Copyright (C) 2007-2009 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; - -use Config; - -use threads; -use threads::shared; - -BEGIN { - if (! $Config{'useithreads'}) { - die "Perl does not support ithreads!"; - } -} - -require Exporter; - -our @ISA = qw( Exporter ); - -our %EXPORT_TAGS = ( - 'plugin' => [ qw( - plugin_register - plugin_unregister - plugin_dispatch_values - plugin_write - plugin_flush - plugin_flush_one - plugin_flush_all - plugin_dispatch_notification - plugin_log - ) ], - 'types' => [ qw( - TYPE_INIT - TYPE_READ - TYPE_WRITE - TYPE_SHUTDOWN - TYPE_LOG - TYPE_NOTIF - TYPE_FLUSH - TYPE_CONFIG - 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 - ) ], - 'filter_chain' => [ qw( - fc_register - FC_MATCH_NO_MATCH - FC_MATCH_MATCHES - FC_TARGET_CONTINUE - FC_TARGET_STOP - FC_TARGET_RETURN - ) ], - 'fc_types' => [ qw( - FC_MATCH - FC_TARGET - ) ], - 'notif' => [ qw( - NOTIF_FAILURE - NOTIF_WARNING - NOTIF_OKAY - ) ], - 'globals' => [ qw( - $hostname_g - $interval_g - ) ], -); - -{ - my %seen; - push @{$EXPORT_TAGS{'all'}}, grep {! $seen{$_}++ } @{$EXPORT_TAGS{$_}} - foreach keys %EXPORT_TAGS; -} - -# global variables -our $hostname_g; -our $interval_g; - -Exporter::export_ok_tags ('all'); - -my @plugins : shared = (); -my @fc_plugins : shared = (); -my %cf_callbacks : shared = (); - -my %types = ( - TYPE_INIT, "init", - TYPE_READ, "read", - TYPE_WRITE, "write", - TYPE_SHUTDOWN, "shutdown", - TYPE_LOG, "log", - TYPE_NOTIF, "notify", - TYPE_FLUSH, "flush" -); - -my %fc_types = ( - FC_MATCH, "match", - FC_TARGET, "target" -); - -my %fc_exec_names = ( - FC_MATCH, "match", - FC_TARGET, "invoke" -); - -foreach my $type (keys %types) { - $plugins[$type] = &share ({}); -} - -foreach my $type (keys %fc_types) { - $fc_plugins[$type] = &share ({}); -} - -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; - - my %plugins; - - our $cb_name = undef; - - 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; - } - - { - lock %{$plugins[$type]}; - %plugins = %{$plugins[$type]}; - } - - foreach my $plugin (keys %plugins) { - my $p = $plugins{$plugin}; - - my $status = 0; - - if ($p->{'wait_left'} > 0) { - $p->{'wait_left'} -= $interval_g; - } - - next if ($p->{'wait_left'} > 0); - - $cb_name = $p->{'cb_name'}; - $status = call_by_name (@_); - - if (! $status) { - my $err = undef; - - if ($@) { - $err = $@; - } - else { - $err = "callback returned false"; - } - - if (TYPE_LOG != $type) { - ERROR ("Execution of callback \"$cb_name\" failed: $err"); - } - - $status = 0; - } - - if ($status) { - $p->{'wait_left'} = 0; - $p->{'wait_time'} = $interval_g; - } - elsif (TYPE_READ == $type) { - if ($p->{'wait_time'} < $interval_g) { - $p->{'wait_time'} = $interval_g; - } - - $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) { - ERROR ("${plugin}->init() failed with status $status. " - . "Plugin will be disabled."); - - foreach my $type (keys %types) { - plugin_unregister ($type, $plugin); - } - } - 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) - && (TYPE_CONFIG != $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 ((TYPE_CONFIG == $type) && (! ref $data)) { - my $pkg = scalar caller; - - if ($data !~ m/^$pkg\:\:/) { - $data = $pkg . "::" . $data; - } - - lock %cf_callbacks; - $cf_callbacks{$name} = $data; - } - elsif ((TYPE_DATASET != $type) && (! ref $data)) { - my $pkg = scalar caller; - - my %p : shared; - - if ($data !~ m/^$pkg\:\:/) { - $data = $pkg . "::" . $data; - } - - %p = ( - wait_time => $interval_g, - wait_left => 0, - cb_name => $data, - ); - - lock %{$plugins[$type]}; - $plugins[$type]->{$name} = \%p; - } - 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 (TYPE_CONFIG == $type) { - lock %cf_callbacks; - delete $cf_callbacks{$name}; - } - elsif (defined $plugins[$type]) { - lock %{$plugins[$type]}; - delete $plugins[$type]->{$name}; - } - else { - ERROR ("Collectd::plugin_unregister: Invalid type."); - return; - } -} - -sub plugin_write { - my %args = @_; - - my @plugins = (); - my @datasets = (); - my @valuelists = (); - - if (! defined $args{'valuelists'}) { - ERROR ("Collectd::plugin_write: Missing 'valuelists' argument."); - return; - } - - DEBUG ("Collectd::plugin_write:" - . (defined ($args{'plugins'}) ? " plugins = $args{'plugins'}" : "") - . (defined ($args{'datasets'}) ? " datasets = $args{'datasets'}" : "") - . " valueslists = $args{'valuelists'}"); - - if (defined ($args{'plugins'})) { - if ("ARRAY" eq ref ($args{'plugins'})) { - @plugins = @{$args{'plugins'}}; - } - else { - @plugins = ($args{'plugins'}); - } - } - else { - @plugins = (undef); - } - - if ("ARRAY" eq ref ($args{'valuelists'})) { - @valuelists = @{$args{'valuelists'}}; - } - else { - @valuelists = ($args{'valuelists'}); - } - - if (defined ($args{'datasets'})) { - if ("ARRAY" eq ref ($args{'datasets'})) { - @datasets = @{$args{'datasets'}}; - } - else { - @datasets = ($args{'datasets'}); - } - } - else { - @datasets = (undef) x scalar (@valuelists); - } - - if ($#datasets != $#valuelists) { - ERROR ("Collectd::plugin_write: Invalid number of datasets."); - return; - } - - foreach my $plugin (@plugins) { - for (my $i = 0; $i < scalar (@valuelists); ++$i) { - _plugin_write ($plugin, $datasets[$i], $valuelists[$i]); - } - } -} - -sub plugin_flush { - my %args = @_; - - my $timeout = -1; - my @plugins = (); - my @ids = (); - - DEBUG ("Collectd::plugin_flush:" - . (defined ($args{'timeout'}) ? " timeout = $args{'timeout'}" : "") - . (defined ($args{'plugins'}) ? " plugins = $args{'plugins'}" : "") - . (defined ($args{'identifiers'}) - ? " identifiers = $args{'identifiers'}" : "")); - - if (defined ($args{'timeout'}) && ($args{'timeout'} > 0)) { - $timeout = $args{'timeout'}; - } - - if (defined ($args{'plugins'})) { - if ("ARRAY" eq ref ($args{'plugins'})) { - @plugins = @{$args{'plugins'}}; - } - else { - @plugins = ($args{'plugins'}); - } - } - else { - @plugins = (undef); - } - - if (defined ($args{'identifiers'})) { - if ("ARRAY" eq ref ($args{'identifiers'})) { - @ids = @{$args{'identifiers'}}; - } - else { - @ids = ($args{'identifiers'}); - } - } - else { - @ids = (undef); - } - - foreach my $plugin (@plugins) { - foreach my $id (@ids) { - _plugin_flush($plugin, $timeout, $id); - } - } -} - -sub plugin_flush_one { - my $timeout = shift; - my $name = shift; - - WARNING ("Collectd::plugin_flush_one is deprecated - " - . "use Collectd::plugin_flush instead."); - - if (! (defined ($timeout) && defined ($name))) { - ERROR ("Usage: Collectd::plugin_flush_one(timeout, name)"); - return; - } - - plugin_flush (plugins => $name, timeout => $timeout); -} - -sub plugin_flush_all { - my $timeout = shift; - - WARNING ("Collectd::plugin_flush_all is deprecated - " - . "use Collectd::plugin_flush instead."); - - if (! defined ($timeout)) { - ERROR ("Usage: Collectd::plugin_flush_all(timeout)"); - return; - } - - plugin_flush (timeout => $timeout); -} - -sub fc_call { - my $type = shift; - my $name = shift; - my $cb_type = shift; - - my %proc; - - our $cb_name = undef; - my $status; - - if (! ((defined $type) && (defined $name) && (defined $cb_type))) { - ERROR ("Usage: Collectd::fc_call(type, name, cb_type, ...)"); - return; - } - - if (! defined $fc_plugins[$type]) { - ERROR ("Collectd::fc_call: Invalid type \"$type\""); - return; - } - - if (! defined $fc_plugins[$type]->{$name}) { - ERROR ("Collectd::fc_call: Unknown " - . ($type == FC_MATCH ? "match" : "target") - . " \"$name\""); - return; - } - - DEBUG ("Collectd::fc_call: " - . "type = \"$type\", name = \"$name\", cb_type = \"$cb_type\""); - - { - lock %{$fc_plugins[$type]}; - %proc = %{$fc_plugins[$type]->{$name}}; - } - - if (FC_CB_EXEC == $cb_type) { - $cb_name = $proc{$fc_exec_names{$type}}; - } - elsif (FC_CB_CREATE == $cb_type) { - if (defined $proc{'create'}) { - $cb_name = $proc{'create'}; - } - else { - return 1; - } - } - elsif (FC_CB_DESTROY == $cb_type) { - if (defined $proc{'destroy'}) { - $cb_name = $proc{'destroy'}; - } - else { - return 1; - } - } - - $status = call_by_name (@_); - - if ($status < 0) { - my $err = undef; - - if ($@) { - $err = $@; - } - else { - $err = "callback returned false"; - } - - ERROR ("Execution of fc callback \"$cb_name\" failed: $err"); - return; - } - return $status; -} - -sub fc_register { - my $type = shift; - my $name = shift; - my $proc = shift; - - my %fc : shared; - - DEBUG ("Collectd::fc_register: " - . "type = \"$type\", name = \"$name\", proc = \"$proc\""); - - if (! ((defined $type) && (defined $name) && (defined $proc))) { - ERROR ("Usage: Collectd::fc_register(type, name, proc)"); - return; - } - - if (! defined $fc_plugins[$type]) { - ERROR ("Collectd::fc_register: Invalid type \"$type\""); - return; - } - - if (("HASH" ne ref ($proc)) || (! defined $proc->{$fc_exec_names{$type}}) - || ("" ne ref ($proc->{$fc_exec_names{$type}}))) { - ERROR ("Collectd::fc_register: Invalid proc."); - return; - } - - for my $p (qw( create destroy )) { - if ((defined $proc->{$p}) && ("" ne ref ($proc->{$p}))) { - ERROR ("Collectd::fc_register: Invalid proc."); - return; - } - } - - %fc = %$proc; - - foreach my $p (keys %fc) { - my $pkg = scalar caller; - - if ($p !~ m/^(create|destroy|$fc_exec_names{$type})$/) { - next; - } - - if ($fc{$p} !~ m/^$pkg\:\:/) { - $fc{$p} = $pkg . "::" . $fc{$p}; - } - } - - lock %{$fc_plugins[$type]}; - if (defined $fc_plugins[$type]->{$name}) { - WARNING ("Collectd::fc_register: Overwriting previous " - . "definition of match \"$name\"."); - } - - if (! _fc_register ($type, $name)) { - ERROR ("Collectd::fc_register: Failed to register \"$name\"."); - return; - } - - $fc_plugins[$type]->{$name} = \%fc; - return 1; -} - -sub _plugin_dispatch_config { - my $plugin = shift; - my $config = shift; - - our $cb_name = undef; - - if (! (defined ($plugin) && defined ($config))) { - return; - } - - if (! defined $cf_callbacks{$plugin}) { - WARNING ("Found a configuration for the \"$plugin\" plugin, but " - . "the plugin isn't loaded or didn't register " - . "a configuration callback."); - return; - } - - { - lock %cf_callbacks; - $cb_name = $cf_callbacks{$plugin}; - } - call_by_name ($config); -} - -1; - -# vim: set sw=4 ts=4 tw=78 noexpandtab : - diff --git a/bindings/perl/Collectd/Makefile.PL b/bindings/perl/Collectd/Makefile.PL deleted file mode 100644 index baf71662..00000000 --- a/bindings/perl/Collectd/Makefile.PL +++ /dev/null @@ -1,8 +0,0 @@ -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 deleted file mode 100644 index 199a47c5..00000000 --- a/bindings/perl/Collectd/Unixsock.pm +++ /dev/null @@ -1,656 +0,0 @@ -# -# collectd - Collectd::Unixsock -# Copyright (C) 2007,2008 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 -# -# Author: -# Florian octo Forster -# - -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 constant { NOTIF_FAILURE => 1, NOTIF_WARNING => 2, NOTIF_OKAY => 4 }; - -use Carp (qw(cluck confess)); -use IO::Socket::UNIX; -use Regexp::Common (qw(number)); - -our $Debug = 0; - -return (1); - -sub _debug -{ - if (!$Debug) - { - return; - } - print @_; -} - -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 IDENTIFIERS - -The values in the collectd are identified using an five-tuple (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 - -sub _escape_argument -{ - my $string = shift; - - if ($string =~ m/^\w+$/) - { - return ("$string"); - } - - $string =~ s#\\#\\\\#g; - $string =~ s#"#\\"#g; - $string = "\"$string\""; - - return ($string); -} - -=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 ('object has no filehandle'); - my $msg; - my $identifier; - - my $ret = {}; - - $identifier = _create_identifier (\%args) or return; - - $msg = 'GETVAL ' . _escape_argument ($identifier) . "\n"; - _debug "-> $msg"; - print $fh $msg; - - $msg = <$fh>; - chomp ($msg); - _debug "<- $msg\n"; - - ($status, $msg) = split (' ', $msg, 2); - if ($status <= 0) - { - $obj->{'error'} = $msg; - return; - } - - for (my $i = 0; $i < $status; $i++) - { - my $entry = <$fh>; - chomp ($entry); - _debug "<- $entry\n"; - - if ($entry =~ m/^(\w+)=NaN$/) - { - $ret->{$1} = undef; - } - elsif ($entry =~ m/^(\w+)=($RE{num}{real})$/) - { - $ret->{$1} = 0.0 + $2; - } - } - - return ($ret); -} # }}} sub getval - -=item I<$res> = I<$obj>-EB (I<%identifier>); - -Requests a threshold from the daemon. On success a hash-ref is returned with -the threshold data. On error false is returned. - -=cut - -sub getthreshold # {{{ -{ - my $obj = shift; - my %args = @_; - - my $status; - my $fh = $obj->{'sock'} or confess ('object has no filehandle'); - my $msg; - my $identifier; - - my $ret = {}; - - $identifier = _create_identifier (\%args) or return; - - $msg = 'GETTHRESHOLD ' . _escape_argument ($identifier) . "\n"; - _debug "-> $msg"; - print $fh $msg; - - $msg = <$fh>; - chomp ($msg); - _debug "<- $msg\n"; - - ($status, $msg) = split (' ', $msg, 2); - if ($status <= 0) - { - $obj->{'error'} = $msg; - return; - } - - for (my $i = 0; $i < $status; $i++) - { - my $entry = <$fh>; - chomp ($entry); - _debug "<- $entry\n"; - - if ($entry =~ m/^([^:]+):\s*(\S.*)$/) - { - my $key = $1; - my $value = $2; - - $key =~ s/^\s+//; - $key =~ s/\s+$//; - - $ret->{$key} = $value; - } - } - - return ($ret); -} # }}} sub getthreshold - -=item I<$obj>-EB (I<%identifier>, B