From: Florian Forster Date: Wed, 21 Sep 2016 06:48:56 +0000 (+0200) Subject: Merge branch 'pr/1649' X-Git-Tag: collectd-5.7.0~73 X-Git-Url: https://git.octo.it/?p=collectd.git;a=commitdiff_plain;h=e1bfa71aca1f37c2f293dc9adb44065c6e7a9ad9;hp=d0a97673ed7746184fc2338afa3c200a34310196 Merge branch 'pr/1649' --- diff --git a/.clang-format b/.clang-format new file mode 100644 index 00000000..70f50ad5 --- /dev/null +++ b/.clang-format @@ -0,0 +1,5 @@ +--- +BasedOnStyle: LLVM +IncludeCategories: + - Regex: '"collectd.h"' + - Priority: -1 diff --git a/.github/issue_template.md b/.github/issue_template.md new file mode 100644 index 00000000..49d24b30 --- /dev/null +++ b/.github/issue_template.md @@ -0,0 +1,16 @@ +* Version of collectd: +* Operating system / distribution: + +## Expected behavior + +(Description of the behavior / output that you expected) + +## Actual behavior + +(Description of the behavior / output that you observed) + +## Steps to reproduce + +* step 1 +* step 2 +* step 3 diff --git a/.gitignore b/.gitignore index d7423895..8154d733 100644 --- a/.gitignore +++ b/.gitignore @@ -81,6 +81,12 @@ bindings/java/org/collectd/java/*.class # lint stuff *.ln +#ide stuff +.vscode + +# cscope stuff +cscope.* + # Unit tests src/daemon/test-suite.log src/tests/ diff --git a/AUTHORS b/AUTHORS index bdffa923..28220e79 100644 --- a/AUTHORS +++ b/AUTHORS @@ -20,13 +20,13 @@ Pierre-Yves Ritschard - Normalization in the CPU plugin. - Relative values in the Load plugin. -Ruben Kerkhof +Ruben Kerkhof - Bugfixes and enhancements in many places all around the project. - - Fedora package. + - Fedora and EPEL packages. Sebastian "tokkee" Harl - Bugfixes and enhancements in many places all around the project. - - gprc plugin. + - grpc plugin. - perl plugin. - postgresql plugin. - users plugin. @@ -163,6 +163,9 @@ Jérôme Renard Jiri Tyr - fhcount plugin. +Julien Ammous + - Lua plugin. + Kevin Bowling - write_tsdb plugin for http://opentsdb.net/ @@ -219,6 +222,9 @@ Michał Mirosław Mirko Buffoni - Port/Socket selection in the MySQL plugin. +Nicolas Jourden + - gps plugin. + Niki W. Waibel - Initial autotools fixes. - libltdl code. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index befb76e6..eeb174ba 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,38 +1,57 @@ -# Thanks ! - -Thanks for your feedback & contributions to the -[collectd project](https://collectd.org/) ! - -## Need help using collectd ? - -Please use the -[collectd mailing list](http://mailman.verplant.org/listinfo/collectd) or the -[#collectd IRC channel](https://webchat.freenode.net/?channels=#collectd). -We'd like to keep the github issue tracker for bugreports and patch reviews. - -## Found a bug ? - -Please mention the exact collectd version you're using, how it was installed -(built from source, or installed from packages. Where was it downloaded -from). Which operating system/architecture, distribution and version are you -running collectd on. - -If collectd crashes, try to get a -[stack trace](https://collectd.org/wiki/index.php/Core_file). - -## Fixed a bug ? Want to add a feature ? - -Using git/github to submit changes is not mandatory. Sending patches to the -[mailing-list](http://mailman.verplant.org/listinfo/collectd) is also fine. -In both cases, take a quick look at the -[submission guidelines](https://collectd.org/wiki/index.php/Submitting_patches) -and the [coding style recommendations](https://collectd.org/wiki/index.php/Coding_style). - -Please try to submit **bugfixes** to the -[oldest release branch](https://github.com/collectd/collectd/milestones) on -which the bug is found, so that it gets included in every future **bugfix -release**. - -Please try to submit **new features** to the master branch (which will become -the next **feature release**). - +# Contribution guidelines + +Thanks for taking the time to contribute to the [collectd +project](https://collectd.org/)! This document tries to give some guidance to +make the process of contributing to *collectd* as pleasant and possible. + +## Bug reports + +Please report bugs as [GitHub +Issues](https://github.com/collectd/collectd/issues). Try to answer the +following questions: + +* Which version of *collectd* are you using? +* Which operating system (distribution) are you using at which version? +* What is the expected behavior / output? +* What is the actual (observed) behavior / output? +* How can we reproduce the problem you're having? +* If *collectd* crashes, try to get a + [stack trace](https://collectd.org/wiki/index.php/Core_file). + +Please monitor your issue for a couple of days and reply to questions. To keep +the project manageable have to do some housekeeping, meaning we will close +issues that have become stale. + +## Code contributions + +Please open a [GitHub Pull Request](https://github.com/collectd/collectd/pulls) +(PR) to contribute bug fixes, features, cleanups, new plugins, … Patches sent to +the mailing list have a tendency to fall through the cracks. + +* *Focus:* Fix *one thing* in your PR. The smaller your change, the faster it + will be reviewed and merged. +* *Coding style:* Please run `clang-format -style=file -i $FILE` on new files. + For existing files, please blend into surrounding code, i.e. mimic the + coding style of the code around your changes. +* *Documentation:* New config options need to be documented in two places: the + manpage (`src/collectd.conf.pod`) and the example config + (`src/collectd.conf.in`). +* *Continuous integration:* Once your PR is created, our continuous + integration environment will try to build it on a number of platforms. If + this reports a failure, please investigate and fix the problem. We will at + best do a very casual review for failing PRs. +* *Don't rebase:* Rebasing your branch destroys the review history. If a review + takes a long time, we may ask you to rebase on a more recent *master*, but + please don't do it without being asked. +* *types.db:* One of the most common mistakes made by new contributors is the + addition of (many) new *types* in the file `src/types.db`. The majority of + usecases can be met with one of the existing entries. If you plan to add new + entries to `src/types.db`, you should talk to us early in the design + process. + +## Other resources + +* [Mailing list](http://mailman.verplant.org/listinfo/collectd) +* [#collectd IRC channel](https://webchat.freenode.net/?channels=#collectd) + on *freenode*. +* [Old patch submission guideline](https://collectd.org/wiki/index.php/Submitting_patches) diff --git a/ChangeLog b/ChangeLog index 25257d76..51559545 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,161 @@ +2016-09-11, Version 5.6.0 + * Build system: An option to to avoid building the DF plugin against XFS + has been added. Thanks to Ruben Kerkhof. #1878 + * Build system: Autoconf ≥ 2.60, a C99-capable compiler and pkg-config + are now required. Thanks to Ruben Kerkhof. + * Build system: Building with "-Werror" is now optional. Thanks to Ruben + Kerkhof. #1222 + * Build system: Many compilation issues on non-Linux platforms have been + fixed, leading to wider plugin support. Thanks to Ruben Kerkhof, + Dagobert Michelsen, Havard Eidnes and Robert Viduya. + * Build system: The configuration summary now also ends up in + config.log. Thanks to Sebastian Harl. + * collectd: All command-line options now override global options from + the config file. Thanks to Sebastian Harl. #366 + * collectd: A number of unit tests for commonly used functions have been + added. Thanks to Florian Forster. + * collectd: Plugins start up and read timeouts are now logged. Thanks to + Marc Fournier. #1293, #1254 + * collectd: Support for a timeout has been added to "FLUSH" callbacks. + Thanks to Manuel Luis Sanmartín Rozada. + * collectd: The "-T" command line switch now reports more errors. Thanks + to Corey Kosak. #1642 + * collectd: The max size of value list elements ("DATA_MAX_NAME_LEN") + has been doubled and is now configurable at build time. Thanks to Amy + Lin, Florian Forster and Radu Brumariu. #1120 + * Set target: The "MetaData" option has been added. Thanks to Yves + Mettier and Kevin Bowling. #1106, #1656, #1913 + * AMQP, Write_HTTP, Write_Kafka plugins: Support for libyajl < 2 has + been added. Thanks to Florian Forster. + * APC UPS plugin: Parsing of end markers has been fixed. Thanks to + Florian Forster #617 + * APC UPS plugin: The "PersistentConnection" option has been added. + Thanks to Florian Forster #617 + * ceph, DNS, Exec, IPTables, Ping, turbostat plugins: When running + unprivileged, these plugins will now warn about insuffiscient + permissions or capabilities(7). Thanks to Marc Fournier. #1530 + * Chrony plugin: This new plugin collects NTP data from the chrony NTP + server. Thanks to Claudius Zingerli. #1548 + * cpusleep plugin: This new plugin measures time spent by CPU in deep + sleep mode. Thanks to Rinigus. #1826 + * CPU plugin: The "ReportNumCpu" option has been added. Thanks to Fabien + Wernli. + * cURL, cURL-JSON, cURL-XML plugins: The new "Statistics" reports + various per-HTTP connection timers. Thanks to Sebastian Harl. #1004 + * DBI plugin: The "Interval" option has been added to "Database" blocks. + Thanks to Michal Bebjak. + * Disk plugin: Support for FreeBSD has been added. Thanks to Xin Li, + Brad Davis, Ruben Kerfhof and Kevin Bowling. + * Empty Counter match: Support for derives has been implemented. Thanks + to Florian Forster. #1813 + * GenericJMX plugin: Support for TabularData and the "PluginName" option + have been added. Thanks to David Crane. #1290, #1291 + * GPS plugin: This new plugin reports the number of sattelites seen by + and precision of a GPS receiver. Thanks to Nicolas Jourden. #1346 + * gRPC plugin: This new client and server plugin allows sending and + receiving metrics using the gRPC protocol. Comparable to the UnixSock + plugin, but using TCP and TLS. Thanks to Sebastian Harl and Florian + Forster. + * Interface plugin: Reporting dropped packets has been added. Thanks to + Marc Falzon. #1555 + * Interface plugin: The "ReportInactive" has been added, letting users + skip inactive network interfaces. Thanks to Rinigus. #1791 + * Interface plugin: The new, Solaris-only "UniqueName" option has been + added. Thanks to Yoga Ramalingam. #1416 + * Lua plugin: This new language binding allows writing plugins using the + Lua programming language. Thanks to Julien Ammous, Florian Forster and + Ruben Kerkhof. + * Memory plugin: Reporting of ARC memory on Solaris has been added. + Thanks to Brian ONeill. + * MQTT plugin: This new plugin sends metrics to and/or receives metrics + from an MQTT broker. Thanks to Marc Falzon, Jan-Piet Mens, Nicholas + Humfrey and Florian Forster. #805, #1124 + * MySQL plugin: Connection to the database server can now be done over + SSL. Thanks to Brian Lalor. #1256 + * MySQL plugin: Monitoring slow queries has been added. Thanks to skob. + #1773 + * MySQL plugin: mysql_bpool_pages-flushed has been renamed to + mysql_bpool_counters-pages_flushed because the value is cumulative. + Thanks to Marek Becka. + * MySQL plugin: Support for Galera statistics has been added. Thanks to + Rachid Zarouali. #1849 + * MySQL plugin: Support for InnoDB metrics was improved. Thanks to Aman + Gupta. #1111 + * MySQL plugin: The "mysql_sort" type has been split into 3 different + types. Thanks to Pavel Rochnyack. #1592 + * Network plugin: Decryption error logging has been improved. Thanks to + Pavel Rochnyack. #1735 + * Notify Nagios plugin: This new plugin sends notifications to Nagios as + a passive check result. Thanks to Florian Forster. + * NTPd plugin: The plugin now detects if the ntp daemon reports + nanoseconds instead of microseconds. Thanks to Matwey V. Kornilov. + #1783 + * OpenLDAP plugin: Several connection-related improvements have been + made. Thanks to Marc Fournier. #1308 + * OpenLDAP plugin: Support for "simple authentication" has been added. + Thanks to Marek Becka. #1087 + * Ping plugin: The "Size" option has been added, allowing the ICMP data + payload size to be configured. Thanks to Witold Baryluk. #1395 + * PostgreSQL, DBI, Oracle plugins: The new "PluginInstanceFrom" option + has been added. Thanks to Pavel Rochnyack. #1707 + * PowerDNS plugin: The recursor metrics have been updated to 3.7.3 and + missing rr types have been added. Thanks to Ruben Kerkhof. + * Processes plugin: Counting of context switches was added for Linux. + Thanks to Manuel Luis Sanmartín Rozada. #1036 + * Processes plugin: Improve reliability of thread counts on Linux. + Thanks to Manuel Luis Sanmartín Rozada. + * Python plugin: Minimal Python version requirement has been bumped to + 2.6. Thanks to Ruben Kerkhof. #1864 + * Redis plugin: Several additional metrics are now collected. Thanks to + Marc Falzon and Matteo Contrini. #1807, #1483 + * Sensors plugin: The "UseLabels" option has been added. Thanks to + Christian Fetzer. + * SMART plugin: The new "IgnoreSleepMode" option has been added. Thanks + to Scott Talbert. #1770 + * SMART plugin: The new "UseSerial" option allows identifying devices in + a stable way. Thanks to Scott Talbert. #1794 + * SNMP plugin: The "IpAddress" can now be used for instances. Thanks to + Vincent Bernat. #1397 + * StatsD plugin: Latency calculation histogram is now able to shrink + automatically to optimal size. Thanks to Pavel Rochnyack. #1622 + * StatsD plugin: The "CounterSum" option has been added. Thanks to + Florian Forster. #929, #1282, #1311 + * UUID plugin: The plugin now also looks in in smbios system table and + "/sys/class/dmi". Thanks to Ruben Kerkhof. #1490 + * virt plugin: The "PluginInstanceFormat" option has been added. Thanks + to Ruben Kerkhof. #1100 + * Write Graphite plugin: The "ReconnectInterval" option has been added. + Thanks to Toni Moreno and Florian Forster. + * Write HTTP plugin: A KairosDB formatter has been added. Thanks to + Aurélien Rougemont. #1809 + * Write HTTP plugin: Notifications are now handled by this plugin. + Thanks to Florian Forster. + * Write HTTP plugin: The "LogHttpError" option has been added. Thanks to + vzubko. + * Write HTTP plugin: The new "Headers" option allows setting custom HTTP + headers in outgoing requests. Thanks to Brandon Arp. #1634 + * Write Kafka plugin: Key handling has been made more comprehensive and + reliable. Thanks to Florian Forster, Pierre-Yves Ritschard and Vincent + Bernat. #1765, #1695, #1393 + * Write Redis plugin: The "Database", "MaxSetSize", "Prefix" and + "StoreRates" options have been added. Thanks to Brian Kelly and + Sebastian Pfahl. + * Write Riemann plugin: The new "BatchFlushTimeout" and "Timeout" option + have been added. Thanks to Pierre-Yves Ritschard and Gergely Nagy. + * Write Riemann plugin: This plugin now requires the riemann-c-client + library, version 1.6.0+. This adds support for submitting values to + Riemann over TLS. Thanks to Gergely Nagy. #986 + * Write TSDB, Write Sensu, Write Riemann, Write Graphite, Write TSDB + plugin: TCP keepalive is now enabled, helping graceful recovery from + unclean network disconnections. Thanks to Marc Fournier. #1549 + * XenCPU plugin: This new plugin collects XEN Hypervisor CPU stats. + Thanks to Pavel Rochnyack. #1608 + * ZFS ARC plugin: Several new statistics have been added and a couple of + obsolete ones removed. Thanks to Brad Davis, Brian ONeill and Ruben + Kerkhof. + * Zone plugin: This new plugin reads per-zone CPU usage on Solaris. + Thanks to Mathijs Mohlmann and Dagobert Michelsen. + 2016-07-25, Version 5.5.2 * collectd: A division by zero has been fixed in the "plugin_dispatch_multivalue()" function. Thanks to Corey Kosak. @@ -396,7 +554,124 @@ Marc Fournier and Wilfried Goesgens. #552 * Zookeeper plugin: This new plugin reads data from the Apache Zookeeper "MNTR" command. Thanks to Jeremy Katz. #826 -======= + +2016-07-26, Version 5.4.3 + * Build system: A deprecation warning has been removed. Thanks to + Florian Forster. + * Build system: An ordering issue when build the AMQP plugin was + corrected. Thanks to Shahul Hameed. + * Build system: Building the gmond plugin against recent libganglia + versions has been added. Thanks to Marc Fournier. #1129 + * Build system: "collectd-tg" now builds on AIX. Thanks to Manuel Luis + Sanmartín Rozada. #542 + * Build system: "version-gen.sh" portablility was improved. Thanks to + Marc Fournier and Ruben Kerkhof. + * Build system: Compiling utils_dns.c on Solaris has beed fixed. Thanks + to Yves Mettier, Dagobert Michelsen and Florian Forster. #348 + * Build system: Default JDK detection got improved. Thanks to Ruben + Kerkhof and Marc Fournier. + * Build system: Detection and handling of librrd 1.6 and later has been + fixed. Thanks to Ruben Kerkhof. + * Build system: notify_email build options got corrected to make it + build on non-GNU libc systems. Thanks to Marc Fournier. + * Build system: Protobuf building and logging has been improved. Thanks + to Ruben Kerkhof. + * Build system: The "make distcheck" target was fixed to properly handle + java build artifacts. Thanks to Florian Forster. + * Build system: The configure script got fixed to work properly when + called with "CC="gcc -Wall -Werror"" . Thanks to Marc Fournier. + * Build system: The configure script will now fail if pkg-config isn't + available. Thanks to Ruben Kerkhof. + * Build system: The users plugin now builds properly on Solaris when + libstatgrab is available. Thanks to Dagobert Michelsen. #1061 + * Build system: Various fixes have been done to improve library + detection on FreeBSD. Thanks to Ruben Kerkhof. + * collectd2html: Several perl errors have been corrected. Thanks to Ruud + van Melick. #1103 + * collectd: A global gauge format-string is now used to avoid loss of + precision. Thanks to Florian Forster. #1039 + * collectd: A race condition at plugin initialization time was fixed. + Thanks to Jan Andres. #1316 + * collectd: Autoloading now properly sets plugin context, allowing + plugins to determine the interval. Thanks to Florian Forster. #1069 + * collectd: Empty "Plugin" blocks are now supported by the configuration + file parser. Thanks to Manuel Luis Sanmartín Rozada. #1035 + * collectd: The address of the Free Software Foundation has been fixed + in GPL license headers. Thanks to Ruben Kerkhof. + * collectd: Writing to a closed TCP socket is now properly handled. + Thanks to Tamás Földesi. #1104 + * Documentation: iptables plugin: IPv6 configuration option has been + added to the collectd.conf(5) manpage. Thanks to 'Marc Fournier''. + #1496 + * AMQP plugin: The plugin was fixed to build against librabbitmq 0.6.0. + Thanks to Remi Collet. #1008 + * Apache plugin: A warning about a possible misconfiguration has been + added. Thanks to Marc Fournier. + * Apache plugin: The plugin was extended to parse the whole response, + required to support Apache versions greater than 2.4.17. Thanks to + Marc Fournier and Florian Forster. #1170, #1343 + * APC UPS plugin: Log messages are now prefixed with the plugin name. + Thanks to Sergey. #1329 + * Bind plugin: The type_instance now gets properly sanitized. Thanks to + Thomas Kho. #992 + * CPU plugin: Error messages on MacOSX have been improved. Thanks to + Florian Forster. #22 + * cURL plugin: A typo in an error message got corrected. Thanks to Marc + Fournier. + * cURL, cURL-JSON and cURL-XML plugins: A memory leak when allocating + more memory fails has been fixed. Thanks to Brandon Arp. + * DF plugin: An bug preventing filesystems which don't report inodes + such as btrfs has been corrected. Thanks to Marek Becka. #1096 + * DF plugin: Duplicate entries are no longer reported twice. Thanks to + Stefan Brüns and Florian Forster. #1402 + * DF plugin: Legacy code for skipping "rootfs" mount points has been + removed. Thanks to Marc Fournier. #1402 + * DF plugin: Legacy references to the "ReportReserved" option have been + removed. Thanks to Marc Fournier. + * DF plugin: Reading the mtab now uses a reentrant function when + possible. Thanks to Ruben Kerkhof. #1163 + * Ethstat plugin: Code to strip leading whitespace from device names. + This works around an issue in the VMXNet3 driver. Thanks to Thomas + Guthmann. #1059 + * Exec plugin: A file descriptor leak when the plugin is configured to + run as a non-existing user was corrected. Thanks to Gautam BT and Marc + Fournier. #762 + * Exec plugin: A problem in the error handling of an fdopen() failure + has been fixed. Thanks to @ciomaire. + * Interface plugin: Documentation about regular expressions in the + ignore list has been added. Thanks to Jakub Jankowski. + * IRQ plugin: The "FIQ" line is now skipped as it doesn't contain any + counter. Thanks to Ruben Kerkhof. #971 + * Modbus plugin: The debug output has been disabled by default. It is + now only enabled when building with "--enable-debug". Thanks to Eric + Sandeen and Marc Fournier. + * MongoDB plugin: A memory leak has been fixed and some adaptations to + the current API of the mongo-c-driver have been made. Thanks to + Florian Forster. #956 + * Network plugin: A check for the initialization of secure memory has + been added. Previously, failure to initialize this memory was ignored. + Thanks to @yujokang. #1665 + * Network plugin: A heap overflow has been fixed in the server code. + This issue can be triggered remotely and is potentially exploitable. + Thanks to Emilien Gaspar. CVE-2016-6254 + * Network plugin: The TimeToLive option handling was made more robust. + Thanks to Tim Laszlo. #654 + * NTPd plugin: Documentation about the required "mode 7" has been added. + Thanks to Jakub Jankowski. + * NTPd plugin: Reporting of "time_offset-loop" was corrected to match + the values from ntpq/ntpdc. Thanks to Pierre Fersing and Florian + Forster. #1300 + * OpenVPN plugin: The plugin was fixe to avoid signaling an error when + no clients were connected. Thanks to Florian Forster. #731 + * Perl plugin: Init callbacks have been changed to run essentially + single-threaded to avoid race conditions by init functions which + create additional threads. Thanks to Pavel Rochnyack. #1706 + * PF plugin and DNS plugin: These plugins have been fixed to build + properly on OpenBSD again. Thanks to Ruben Kerkhof. + * Processes plugin: A compilation error on systems without "regex.h" has + been fixed. Thanks to Corey Kosak. + * Processes plugin: A memory leak on Solaris has been fixed. Thanks to + Jim Quinn. * Processes plugin and Swap plugin: These plugins have been corrected to also work inside FreeBSD jails. Thanks to biancalana. #1019 * Processes plugin: A warning about too long process names has been @@ -457,7 +732,6 @@ libasan, FBInfer, coverity-scan, clang and gcc-6: Thanks to Ruben Kerkhof, Florian Forster, Marc Fournier, Corey Kosak, Laurent, Claudius Zingerli and Fabien Wernli. ->>>>>>> collectd-5.4 2015-02-26, Version 5.4.2 * Build system: Numerous fixes. Thanks to Bjørn Nordbø, Jim Radford, diff --git a/NEWS b/NEWS deleted file mode 100644 index e69de29b..00000000 diff --git a/README b/README index 481d144a..9afbec60 100644 --- a/README +++ b/README @@ -67,6 +67,9 @@ Features - cpufreq CPU frequency (For laptops with speed step or a similar technology) + - cpusleep + CPU sleep: Time spent in suspend (For mobile devices which enter suspend automatically) + - curl Parse statistics from websites using regular expressions. @@ -125,12 +128,20 @@ Features - gmond Receive multicast traffic from Ganglia instances. + - gps + Monitor gps related data through gpsd. + - grpc Receive values over the network using the gRPC framework. - hddtemp Hard disk temperatures using hddtempd. + - hugepages + Report the number of used and free hugepages. More info on + hugepages can be found here: + https://www.kernel.org/doc/Documentation/vm/hugetlbpage.txt. + - interface Interface traffic: Number of octets, packets and errors for each interface. @@ -165,6 +176,12 @@ Features Detailed CPU statistics of the “Logical Partitions” virtualization technique built into IBM's POWER processors. + - lua + The Lua plugin implements a Lua interpreter into collectd. This + makes it possible to write plugins in Lua which are executed by + collectd without the need to start a heavy interpreter every interval. + See collectd-lua(5) for details. + - lvm Size of “Logical Volumes” (LV) and “Volume Groups” (VG) of Linux' “Logical Volume Manager” (LVM). @@ -419,6 +436,10 @@ Features diskspace but is extremely portable and can be analysed with almost every program that can analyse anything. Even Microsoft's Excel.. + - lua + It's possible to implement write plugins in Lua using the Lua + plugin. See collectd-lua(5) for details. + - network Send the data to a remote host to save the data somehow. This is useful for large setups where the data should be saved by a dedicated machine. @@ -700,6 +721,10 @@ Prerequisites Used by the `network' plugin for encryption and authentication. + * libgps (optional) + Used by the `gps' plugin. + + * libhal (optional) If present, the `uuid' plugin will check for UUID from HAL. @@ -722,6 +747,10 @@ Prerequisites Used by the `openldap' plugin. + * liblua (optional) + Used by the `lua' plugin. Currently, Lua 5.1 and later are supported. + + * liblvm2 (optional) Used by the `lvm' plugin. @@ -796,7 +825,7 @@ Prerequisites * libpython (optional) - Used by the `python' plugin. Currently, Python 2.3 and later and Python 3 + Used by the `python' plugin. Currently, Python 2.6 and later and Python 3 are supported. @@ -1145,6 +1174,5 @@ Author Sebastian tokkee Harl , and many contributors (see `AUTHORS'). - Please send bug reports and patches to the mailing list, see `Contact' - above. - + Please use GitHub reporting bugs and submitting pull requests. + See CONTRIBUTING.md for details. diff --git a/TODO b/TODO deleted file mode 100644 index 009eb7fc..00000000 --- a/TODO +++ /dev/null @@ -1,21 +0,0 @@ -* Finalize the onewire plugin. -* Custom notification messages? -* Implement moving-average calculation for the threshold stuff. - -src/battery.c: commend not working code. - -Wishlist: -* Port nfs module to solaris -* Port tape module to Linux -* Port the apple_sensors plugin to Linux/PPC. -* Maybe look into porting the serial module -* Build Darwin package -* Maybe let the network plugin configure whether or not notifications should be - sent/received. -* Maybe find a way for processes connected to the unixsock plugin to receive - notifications, too. - -http://developer.apple.com/documentation/DeviceDrivers/Conceptual/AccessingHardware/AH_IOKitLib_API/chapter_5_section_1.html -http://developer.apple.com/documentation/DeviceDrivers/Conceptual/IOKitFundamentals/index.html#//apple_ref/doc/uid/TP0000011 -http://www.gauchosoft.com/Software/X%20Resource%20Graph/ -http://johannes.sipsolutions.net/PowerBook/Apple_Motion_Sensor_Specification/ diff --git a/bindings/java/org/collectd/java/GenericJMXConfValue.java b/bindings/java/org/collectd/java/GenericJMXConfValue.java index 25b70d4a..63b76282 100644 --- a/bindings/java/org/collectd/java/GenericJMXConfValue.java +++ b/bindings/java/org/collectd/java/GenericJMXConfValue.java @@ -313,9 +313,8 @@ class GenericJMXConfValue key = attrName.remove (0); - TabularData tabularData = (TabularData) parent; - Collection table = - (Collection)tabularData.values(); + @SuppressWarnings("unchecked") + Collection table = (Collection) parent.values(); for (CompositeData compositeData : table) { if (key.equals(compositeData.get("key"))) diff --git a/bindings/perl/lib/Collectd.pm b/bindings/perl/lib/Collectd.pm index c1adf442..7e89e45f 100644 --- a/bindings/perl/lib/Collectd.pm +++ b/bindings/perl/lib/Collectd.pm @@ -172,7 +172,6 @@ sub plugin_call_all { my $type = shift; my %plugins; - my $interval; our $cb_name = undef; @@ -181,13 +180,13 @@ sub plugin_call_all { } if (TYPE_LOG != $type) { - DEBUG ("Collectd::plugin_call: type = \"$type\" (" + DEBUG ("Collectd::plugin_call_all: type = \"$type\" (" . $types{$type} . "), args=\"" . join(', ', map { defined($_) ? $_ : '' } @_) . "\""); } if (! defined $plugins[$type]) { - ERROR ("Collectd::plugin_call: unknown type \"$type\""); + ERROR ("Collectd::plugin_call_all: unknown type \"$type\""); return; } @@ -196,21 +195,9 @@ sub plugin_call_all { %plugins = %{$plugins[$type]}; } - $interval = plugin_get_interval (); - foreach my $plugin (keys %plugins) { - my $p = $plugins{$plugin}; - - my $status = 0; - - if ($p->{'wait_left'} > 0) { - $p->{'wait_left'} -= $interval; - } - - next if ($p->{'wait_left'} > 0); - - $cb_name = $p->{'cb_name'}; - $status = call_by_name (@_); + $cb_name = $plugins{$plugin}; + my $status = call_by_name (@_); if (! $status) { my $err = undef; @@ -230,23 +217,7 @@ sub plugin_call_all { } if ($status) { - $p->{'wait_left'} = 0; - $p->{'wait_time'} = $interval; - } - elsif (TYPE_READ == $type) { - if ($p->{'wait_time'} < $interval) { - $p->{'wait_time'} = $interval; - } - - $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."); + #NOOP } elsif (TYPE_INIT == $type) { ERROR ("${plugin}->init() failed with status $status. " @@ -309,21 +280,29 @@ sub plugin_register { } elsif ((TYPE_DATASET != $type) && (! ref $data)) { my $pkg = scalar caller; - - my %p : shared; - if ($data !~ m/^$pkg\:\:/) { $data = $pkg . "::" . $data; } - - %p = ( - wait_time => plugin_get_interval (), - wait_left => 0, - cb_name => $data, - ); - + if (TYPE_READ == $type) { + return plugin_register_read($name, $data); + } + if (TYPE_WRITE == $type) { + return plugin_register_write($name, $data); + } + if (TYPE_LOG == $type) { + return plugin_register_log($name, $data); + } + if (TYPE_NOTIF == $type) { + return plugin_register_notification($name, $data); + } + if (TYPE_FLUSH == $type) { + #For collectd-5.6 only + lock %{$plugins[$type]}; + $plugins[$type]->{$name} = $data; + return plugin_register_flush($name, $data); + } lock %{$plugins[$type]}; - $plugins[$type]->{$name} = \%p; + $plugins[$type]->{$name} = $data; } else { ERROR ("Collectd::plugin_register: Invalid data."); @@ -351,6 +330,21 @@ sub plugin_unregister { lock %cf_callbacks; delete $cf_callbacks{$name}; } + elsif (TYPE_READ == $type) { + return plugin_unregister_read ($name); + } + elsif (TYPE_WRITE == $type) { + return plugin_unregister_write($name); + } + elsif (TYPE_LOG == $type) { + return plugin_unregister_log ($name); + } + elsif (TYPE_NOTIF == $type) { + return plugin_unregister_notification($name); + } + elsif (TYPE_FLUSH == $type) { + return plugin_unregister_flush($name); + } elsif (defined $plugins[$type]) { lock %{$plugins[$type]}; delete $plugins[$type]->{$name}; diff --git a/configure.ac b/configure.ac index 42e55883..31c842af 100644 --- a/configure.ac +++ b/configure.ac @@ -1,4 +1,5 @@ dnl Process this file with autoconf to produce a configure script. +AC_PREREQ([2.60]) AC_INIT([collectd],[m4_esyscmd(./version-gen.sh)]) AC_CONFIG_SRCDIR(src/target_set.c) AC_CONFIG_HEADERS(src/config.h) @@ -42,7 +43,9 @@ AC_SYS_LARGEFILE # # Checks for programs. # -AC_PROG_CC +AC_PROG_CC_C99([], + [AC_MSG_ERROR([No compiler found that supports C99])] +) AC_PROG_CXX AC_PROG_CPP AC_PROG_EGREP @@ -76,11 +79,12 @@ then AC_MSG_ERROR([bison is missing and you do not have ${srcdir}/src/liboconfig/parser.c. Please install bison]) fi +AC_ARG_VAR([PROTOC], [path to the protoc binary]) AC_PATH_PROG([PROTOC], [protoc]) have_protoc3="no" if test "x$PROTOC" != "x"; then AC_MSG_CHECKING([for protoc 3.0.0+]) - if $PROTOC --version | grep -q libprotoc.3; then + if $PROTOC --version | $EGREP libprotoc.3 >/dev/null; then protoc3="yes (`$PROTOC --version`)" have_protoc3="yes" else @@ -90,29 +94,18 @@ if test "x$PROTOC" != "x"; then fi AM_CONDITIONAL(HAVE_PROTOC3, test "x$have_protoc3" = "xyes") +AC_ARG_VAR([GRPC_CPP_PLUGIN], [path to the grpc_cpp_plugin binary]) AC_PATH_PROG([GRPC_CPP_PLUGIN], [grpc_cpp_plugin]) AM_CONDITIONAL(HAVE_GRPC_CPP, test "x$GRPC_CPP_PLUGIN" != "x") -AC_CHECK_PROG([have_protoc_c], [protoc-c], [yes], [no]) -if test "x$have_protoc_c" = "xno" -then - have_protoc_c="no (protoc-c compiler not found)" -fi - -if test "x$have_protoc_c" = "xyes" -then - AC_CHECK_HEADERS([protobuf-c/protobuf-c.h google/protobuf-c/protobuf-c.h], - [have_protoc_c="yes"; break], - [have_protoc_c="no ( not found)"]) -fi -if test "x$have_protoc_c" = "xyes" +AC_ARG_VAR([PROTOC_C], [path to the protoc-c binary]) +AC_PATH_PROG([PROTOC_C], [protoc-c]) +if test "x$PROTOC_C" = "x" then - AC_CHECK_LIB([protobuf-c], [protobuf_c_message_pack], - [have_protoc_c="yes"], - [have_protoc_c="no (libprotobuf-c not found)"]) - + have_protoc_c="no (protoc-c compiler not found)" +else + have_protoc_c="yes" fi -AM_CONDITIONAL(HAVE_PROTOC_C, test "x$have_protoc_c" = "xyes") AC_MSG_CHECKING([for kernel type ($host_os)]) case $host_os in @@ -493,6 +486,7 @@ then #include #include ]) + AC_CHECK_HEADERS([sys/sysmacros.h]) else have_linux_raid_md_u_h="no" fi @@ -689,10 +683,26 @@ AC_CHECK_HEADERS([ \ wordexp.h \ ]) -AC_CHECK_HEADERS([xfs/xqm.h], [], [], -[ -#define _GNU_SOURCE -]) +# --enable-xfs {{{ +AC_ARG_ENABLE([xfs], + [AS_HELP_STRING([--enable-xfs], [xfs support in df plugin @<:@default=yes@:>@])], + [], + [enable_xfs="auto"] +) + +if test "x$enable_xfs" != "xno"; then + AC_CHECK_HEADERS([xfs/xqm.h], + [], + [ + if test "x$enable_xfs" = "xyes"; then + AC_MSG_ERROR([xfs/xqm.h not found]) + fi + ], + [[#define _GNU_SOURCE]] + ) +fi + +# }}} # For the dns plugin AC_CHECK_HEADERS(arpa/nameser.h) @@ -755,6 +765,23 @@ AC_CHECK_HEADERS(net/pfvar.h, have_termios_h="no" AC_CHECK_HEADERS(termios.h, [have_termios_h="yes"]) +# For cpusleep plugin +AC_CACHE_CHECK([whether clock_boottime and clock_monotonic are supported], + [c_cv_have_clock_boottime_monotonic], + AC_COMPILE_IFELSE([AC_LANG_PROGRAM( +[[ +#include +]], +[[ + struct timespec b, m; + clock_gettime(CLOCK_BOOTTIME, &b ); + clock_gettime(CLOCK_MONOTONIC, &m ); +]] + )], + [c_cv_have_clock_boottime_monotonic="yes"], + [c_cv_have_clock_boottime_monotonic="no"])) + + # For the turbostat plugin have_asm_msrindex_h="no" AC_CHECK_HEADERS(asm/msr-index.h, [have_asm_msrindex_h="yes"]) @@ -794,7 +821,7 @@ AC_HEADER_TIME # # Checks for library functions. # -AC_CHECK_FUNCS(gettimeofday select strdup strtol getaddrinfo getnameinfo strchr memcpy strstr strcmp strncmp strncpy strlen strncasecmp strcasecmp openlog closelog sysconf setenv if_indextoname setlocale) +AC_CHECK_FUNCS(gettimeofday select strdup strtol getaddrinfo getnameinfo strchr memcpy strstr strcmp strncmp strncpy strlen strncasecmp strcasecmp openlog closelog sysconf setenv if_indextoname setlocale asprintf) AC_FUNC_STRERROR_R @@ -1360,6 +1387,20 @@ AC_ARG_WITH(useragent, [AS_HELP_STRING([--with-useragent@<:@=AGENT@:>@], [User a # }}} +# --with-data-max-name-len {{{ +AC_ARG_WITH(data-max-name-len, [AS_HELP_STRING([--with-data-max-name-len@<:@=VALUE@:>@], [Maximum length of data buffers])], +[ + if test "x$withval" != "x" && test $withval -gt 0 + then + AC_DEFINE_UNQUOTED(DATA_MAX_NAME_LEN, [$withval], [Maximum length of data buffers]) + else + AC_MSG_ERROR([DATA_MAX_NAME_LEN must be a positive integer -- $withval given]) + fi +], +[ AC_DEFINE(DATA_MAX_NAME_LEN, 128, [Maximum length of data buffers])] +) +# }}} + have_getfsstat="no" AC_CHECK_FUNCS(getfsstat, [have_getfsstat="yes"]) have_getvfsstat="no" @@ -1437,15 +1478,15 @@ if test "x$have_getmntent" = "xc"; then fi if test "x$have_getmntent" = "xsun"; then AC_DEFINE(HAVE_SUN_GETMNTENT, 1, - [Define if the function getmntent exists. It's the version from libsun.]) + [Define if the function getmntent exists. It is the version from libsun.]) fi if test "x$have_getmntent" = "xseq"; then AC_DEFINE(HAVE_SEQ_GETMNTENT, 1, - [Define if the function getmntent exists. It's the version from libseq.]) + [Define if the function getmntent exists. It is the version from libseq.]) fi if test "x$have_getmntent" = "xgen"; then AC_DEFINE(HAVE_GEN_GETMNTENT, 1, - [Define if the function getmntent exists. It's the version from libgen.]) + [Define if the function getmntent exists. It is the version from libgen.]) fi # Check for htonll @@ -2260,60 +2301,144 @@ AC_SUBST(GCRYPT_LIBS) AM_CONDITIONAL(BUILD_WITH_LIBGCRYPT, test "x$with_libgcrypt" = "xyes") # }}} -# --with-grpc {{{ -AC_ARG_WITH(grpc, [AS_HELP_STRING([--without-grpc], [Disable gRPC (default: autodetect).])], +# --with-libgps {{{ +with_libgps_cflags="" +with_libgps_ldflags="" +AC_ARG_WITH(libgps, [AS_HELP_STRING([--with-libgps@<:@=PREFIX@:>@], [Path to libgps.])], [ - with_grpc="$withval" + if test "x$withval" != "xno" && test "x$withval" != "xyes" + then + with_libgps_cflags="-I$withval/include" + with_libgps_ldflags="-L$withval/lib" + with_libgps="yes" + else + with_libgps="$withval" + fi ], [ - with_grpc="yes" + with_libgps="yes" ]) +if test "x$with_libgps" = "xyes" +then + SAVE_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS $with_libgps_cflags" + + AC_CHECK_HEADERS(gps.h, [with_libgps="yes"], [with_libgps="no (gps.h not found)"]) -if test "x$with_grpc" = "xyes" + CFLAGS="$SAVE_CFLAGS" +fi +if test "x$with_libgps" = "xyes" then - if test "x$have_protoc3" != "xyes" - then - with_grpc="no (requires protoc 3.0.0+)" - else if test "x$GRPC_CPP_PLUGIN" = "x" - then - with_grpc"no (requires grpc_cpp_plugin)" - fi; fi + SAVE_CFLAGS="$CFLAGS" + SAVE_LDFLAGS="$LDFLAGS" + CFLAGS="$CFLAGS $with_libgps_cflags" + LDFLAGS="$LDFLAGS $with_libgps_ldflags" + + AC_CHECK_LIB(gps, gps_open, [with_libgps="yes"], [with_libgps="no (symbol gps_open not found)"]) + + CFLAGS="$SAVE_CFLAGS" + LDFLAGS="$SAVE_LDFLAGS" fi +if test "x$with_libgps" = "xyes" +then + BUILD_WITH_LIBGPS_CFLAGS="$with_libgps_cflags" + BUILD_WITH_LIBGPS_LDFLAGS="$with_libgps_ldflags" + BUILD_WITH_LIBGPS_LIBS="-lgps" + AC_SUBST(BUILD_WITH_LIBGPS_CFLAGS) + AC_SUBST(BUILD_WITH_LIBGPS_LDFLAGS) + AC_SUBST(BUILD_WITH_LIBGPS_LIBS) +fi +AM_CONDITIONAL(BUILD_WITH_LIBGPS, test "x$with_libgps" = "xyes") +# }}} -if test "x$with_grpc" = "xyes" +# --with-libgrpc++ {{{ +with_libgrpcpp_cppflags="" +with_libgrpcpp_ldflags="" +AC_ARG_WITH([libgrpc++], [AS_HELP_STRING([--with-libgrpc++@<:@=PREFIX@:>@], [Path to libgrpc++.])], + [ + with_grpcpp="$withval" + if test "x$withval" != "xno" && test "x$withval" != "xyes" + then + with_libgrpcpp_cppflags="-I$withval/include" + with_libgrpcpp_ldflags="-L$withval/lib" + with_libgrpcpp="yes" + fi + if test "x$withval" = "xno" + then + with_libgrpcpp="no (disabled on command line)" + fi + ], + [withval="yes"] +) +if test "x$withval" = "xyes" then - AC_MSG_CHECKING([whether $CXX accepts -std=c++11]) - if test_cxx_flags -std=c++11; then - AC_MSG_RESULT([yes]) - else - AC_MSG_RESULT([no]) - with_grpc="no (requires C++11 support)" - fi +PKG_CHECK_MODULES([GRPCPP], [grpc++], + [with_libgrpcpp="yes"], + [with_libgrpcpp="no (pkg-config could not find libgrpc++)"] +) fi -if test "x$with_grpc" = "xyes" +if test "x$withval" != "xno" then - AC_LANG_PUSH(C++) - SAVE_CPPFLAGS="$CPPFLAGS" - SAVE_CXXFLAGS="$CXXFLAGS" - CPPFLAGS="$CPPFLAGS -std=c++11" - CXXFLAGS="$CXXFLAGS -std=c++11" - AC_CHECK_HEADERS([grpc++/grpc++.h], [], - [with_grpc="no (grpc++/grpc++.h not found)"]) - CPPFLAGS="$SAVE_CPPFLAGS" - CXXFLAGS="$SAVE_CXXFLAGS" - AC_LANG_POP(C++) + AC_MSG_CHECKING([whether $CXX accepts -std=c++11]) + if test_cxx_flags -std=c++11; then + AC_MSG_RESULT([yes]) + else + AC_MSG_RESULT([no]) + with_libgrpcpp="no (requires C++11 support)" + fi fi -with_libgrpc="no" -if test "x$with_grpc" = "xyes" + +if test "x$with_libgrpcpp" = "xyes" then - AC_LANG_PUSH(C++) - AC_CHECK_LIB([grpc], [grpc_register_plugin], - [with_libgrpc="yes"], - [with_grpc="no (libgrpc not found)"], - [-lgpr -lprotobuf]) - AC_LANG_POP(C++) + AC_LANG_PUSH(C++) + SAVE_CPPFLAGS="$CPPFLAGS" + CPPFLAGS="-std=c++11 $with_libgrpcpp_cppflags $GRPCPP_CFLAGS $CPPFLAGS" + AC_CHECK_HEADERS([grpc++/grpc++.h], [], + [with_libgrpcpp="no ( not found)"] + ) + CPPFLAGS="$SAVE_CPPFLAGS" + AC_LANG_POP(C++) fi +if test "x$with_libgrpcpp" = "xyes" +then + AC_LANG_PUSH(C++) + SAVE_CPPFLAGS="$CPPFLAGS" + SAVE_LDFLAGS="$LDFLAGS" + SAVE_LIBS="$LIBS" + CPPFLAGS="-std=c++11 $with_libgrpcpp_cppflags $GRPCPP_CFLAGS $CPPFLAGS" + LDFLAGS="$with_libgrpcpp_ldflags" + if test "x$GRPCPP_LIBS" = "x" + then + LIBS="-lgrpc++" + else + LIBS="$GRPCPP_LIBS" + fi + AC_LINK_IFELSE( + [AC_LANG_PROGRAM( + [[#include ]], + [[grpc::ServerBuilder sb;]] + )], + [ + with_libgrpcpp="yes" + if test "x$GRPCPP_LIBS" = "x" + then + GRPCPP_LIBS="-lgrpc++" + fi + ], + [with_libgrpcpp="no (libgrpc++ not found)"] + ) + CPPFLAGS="$SAVE_CPPFLAGS" + LDFLAGS="$SAVE_LDFLAGS" + LIBS="$SAVE_LIBS" + AC_LANG_POP(C++) +fi +BUILD_WITH_LIBGRPCPP_CPPFLAGS="-std=c++11 $with_libgrpcpp_cppflags $GRPCPP_CFLAGS" +BUILD_WITH_LIBGRPCPP_LDFLAGS="$with_libgrpcpp_ldflags" +BUILD_WITH_LIBGRPCPP_LIBS="$GRPCPP_LIBS" +AC_SUBST([BUILD_WITH_LIBGRPCPP_CPPFLAGS]) +AC_SUBST([BUILD_WITH_LIBGRPCPP_LDFLAGS]) +AC_SUBST([BUILD_WITH_LIBGRPCPP_LIBS]) # }}} # --with-libiptc {{{ @@ -2340,11 +2465,6 @@ AC_ARG_WITH(libiptc, [AS_HELP_STRING([--with-libiptc@<:@=PREFIX@:>@], [Path to l fi ]) -if test "x$with_libiptc" = "xpkgconfig" && test "x$PKG_CONFIG" = "x" -then - with_libiptc="no (Don't have pkg-config)" -fi - if test "x$with_libiptc" = "xpkgconfig" then $PKG_CONFIG --exists 'libiptc' 2>/dev/null @@ -2721,6 +2841,86 @@ fi AM_CONDITIONAL(BUILD_WITH_LIBLDAP, test "x$with_libldap" = "xyes") # }}} +# --with-liblua {{{ +AC_ARG_VAR([LIBLUA_PKG_CONFIG_NAME], [Name of liblua used by pkg-config]) +if test "x$LIBLUA_PKG_CONFIG_NAME" != "x" +then + PKG_CHECK_MODULES([LUA], [$LIBLUA_PKG_CONFIG_NAME], + [with_liblua="yes"], + [with_liblua="no"] + ) +else + PKG_CHECK_MODULES([LUA], [lua], + [with_liblua="yes"], + [ + PKG_CHECK_MODULES([LUA], [lua-5.3], + [with_liblua="yes"], + [ + PKG_CHECK_MODULES([LUA], [lua5.3], + [with_liblua="yes"], + [ + PKG_CHECK_MODULES([LUA], [lua-5.2], + [with_liblua="yes"], + [ + PKG_CHECK_MODULES([LUA], [lua5.2], + [with_liblua="yes"], + [ + PKG_CHECK_MODULES([LUA], [lua-5.1], + [with_liblua="yes"], + [ + PKG_CHECK_MODULES([LUA], [lua5.1], + [with_liblua="yes"], + [with_liblua="no (pkg-config cannot find liblua)"] + ) + ] + ) + ] + ) + ] + ) + ] + ) + ] + ) + ] + ) +fi + +if test "x$with_liblua" = "xyes" +then + SAVE_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS $LUA_CFLAGS" + + AC_CHECK_HEADERS([lua.h lauxlib.h lualib.h], + [with_liblua="yes"], + [with_liblua="no (header not found)"] + ) + + CFLAGS="$SAVE_CFLAGS" +fi + +if test "x$with_liblua" = "xyes" +then + SAVE_LIBS="$LIBS" + LIBS="$LIBS $LUA_LIBS" + + AC_CHECK_FUNC([lua_settop], + [with_liblua="yes"], + [with_liblua="no (symbol 'lua_settop' not found)"] + ) + + LIBS="$SAVE_LIBS" +fi + +if test "x$with_liblua" = "xyes" +then + BUILD_WITH_LIBLUA_CFLAGS="$LUA_CFLAGS" + BUILD_WITH_LIBLUA_LIBS="$LUA_LIBS" +fi +AC_SUBST(BUILD_WITH_LIBLUA_CFLAGS) +AC_SUBST(BUILD_WITH_LIBLUA_LIBS) +# }}} + # --with-liblvm2app {{{ with_liblvm2app_cppflags="" with_liblvm2app_ldflags="" @@ -2857,13 +3057,6 @@ AC_ARG_WITH(libmodbus, [AS_HELP_STRING([--with-libmodbus@<:@=PREFIX@:>@], [Path # configure using pkg-config if test "x$with_libmodbus" = "xuse_pkgconfig" then - if test "x$PKG_CONFIG" = "x" - then - with_libmodbus="no (Don't have pkg-config)" - fi -fi -if test "x$with_libmodbus" = "xuse_pkgconfig" -then AC_MSG_NOTICE([Checking for libmodbus using $PKG_CONFIG]) $PKG_CONFIG --exists 'libmodbus' 2>/dev/null if test $? -ne 0 @@ -3154,10 +3347,6 @@ AC_ARG_WITH(libmnl, [AS_HELP_STRING([--with-libmnl@<:@=PREFIX@:>@], [Path to lib with_libmnl="no (Linux only library)" fi ]) -if test "x$PKG_CONFIG" = "x" -then - with_libmnl="no (Don't have pkg-config)" -fi if test "x$with_libmnl" = "xyes" then if $PKG_CONFIG --exists libmnl 2>/dev/null; then @@ -3314,9 +3503,6 @@ AM_CONDITIONAL(BUILD_WITH_LIBNETAPP, test "x$with_libnetapp" = "xyes") # }}} # --with-libnetsnmp {{{ -with_snmp_config="net-snmp-config" -with_snmp_cflags="" -with_snmp_libs="" AC_ARG_WITH(libnetsnmp, [AS_HELP_STRING([--with-libnetsnmp@<:@=PREFIX@:>@], [Path to the Net-SNMPD library.])], [ if test "x$withval" = "xno" @@ -3326,57 +3512,42 @@ AC_ARG_WITH(libnetsnmp, [AS_HELP_STRING([--with-libnetsnmp@<:@=PREFIX@:>@], [Pat then with_libnetsnmp="yes" else - if test -x "$withval" - then - with_snmp_config="$withval" - with_libnetsnmp="yes" - else - with_snmp_config="$withval/bin/net-snmp-config" - with_libnetsnmp="yes" - fi + with_libnetsnmp_cppflags="-I$withval/include" + with_libnetsnmp_ldflags="-I$withval/lib" + with_libnetsnmp="yes" fi; fi ], [with_libnetsnmp="yes"]) if test "x$with_libnetsnmp" = "xyes" then - with_snmp_cflags=`$with_snmp_config --cflags 2>/dev/null` - snmp_config_status=$? - - if test $snmp_config_status -ne 0 - then - with_libnetsnmp="no ($with_snmp_config failed)" - else - SAVE_CPPFLAGS="$CPPFLAGS" - CPPFLAGS="$CPPFLAGS $with_snmp_cflags" + SAVE_CPPFLAGS="$CPPFLAGS" + CPPFLAGS="$CPPFLAGS $with_libnetsnmp_cppflags" - AC_CHECK_HEADERS(net-snmp/net-snmp-config.h, [], [with_libnetsnmp="no (net-snmp/net-snmp-config.h not found)"]) + AC_CHECK_HEADERS(net-snmp/net-snmp-config.h, [], [with_libnetsnmp="no (net-snmp/net-snmp-config.h not found)"]) - CPPFLAGS="$SAVE_CPPFLAGS" - fi + CPPFLAGS="$SAVE_CPPFLAGS" fi if test "x$with_libnetsnmp" = "xyes" then - with_snmp_libs=`$with_snmp_config --libs 2>/dev/null` - snmp_config_status=$? + SAVE_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS $with_libnetsnmp_ldflags" - if test $snmp_config_status -ne 0 - then - with_libnetsnmp="no ($with_snmp_config failed)" - else - AC_CHECK_LIB(netsnmp, init_snmp, + AC_CHECK_LIB(netsnmp, init_snmp, [with_libnetsnmp="yes"], [with_libnetsnmp="no (libnetsnmp not found)"], [$with_snmp_libs]) - fi + + LDFLAGS="$SAVE_LDFLAGS" fi if test "x$with_libnetsnmp" = "xyes" then - BUILD_WITH_LIBSNMP_CFLAGS="$with_snmp_cflags" - BUILD_WITH_LIBSNMP_LIBS="$with_snmp_libs" - AC_SUBST(BUILD_WITH_LIBSNMP_CFLAGS) - AC_SUBST(BUILD_WITH_LIBSNMP_LIBS) + BUILD_WITH_LIBNETSNMP_CPPFLAGS="$with_libnetsnmp_cppflags" + BUILD_WITH_LIBNETSNMP_LDFLAGS="$with_libnetsnmp_ldflags" + BUILD_WITH_LIBNETSNMP_LIBS="-lnetsnmp" fi -AM_CONDITIONAL(BUILD_WITH_LIBNETSNMP, test "x$with_libnetsnmp" = "xyes") +AC_SUBST(BUILD_WITH_LIBNETSNMP_CPPFLAGS) +AC_SUBST(BUILD_WITH_LIBNETSNMP_LDFLAGS) +AC_SUBST(BUILD_WITH_LIBNETSNMP_LIBS) # }}} # --with-liboconfig {{{ @@ -3409,7 +3580,7 @@ save_LDFLAGS="$LDFLAGS" save_CPPFLAGS="$CPPFLAGS" LDFLAGS="$liboconfig_LDFLAGS" CPPFLAGS="$liboconfig_CPPFLAGS" -AC_CHECK_LIB(oconfig, oconfig_parse_fh, +AC_CHECK_LIB(oconfig, oconfig_parse_file, [ with_liboconfig="yes" with_own_liboconfig="no" @@ -3693,7 +3864,7 @@ then SAVE_CFLAGS="$CFLAGS" SAVE_LIBS="$LIBS" dnl ARCHFLAGS="" -> disable multi -arch on OSX (see Config_heavy.pl:fetch_string) - PERL_CFLAGS=`ARCHFLAGS="" $perl_interpreter -MExtUtils::Embed -e ccopts` + PERL_CFLAGS=`ARCHFLAGS="" $perl_interpreter -MExtUtils::Embed -e perl_inc` PERL_LIBS=`ARCHFLAGS="" $perl_interpreter -MExtUtils::Embed -e ldopts` CFLAGS="$CFLAGS $PERL_CFLAGS" LIBS="$LIBS $PERL_LIBS" @@ -3927,126 +4098,197 @@ fi AM_CONDITIONAL(BUILD_WITH_LIBPQ, test "x$with_libpq" = "xyes") # }}} -# --with-python {{{ -with_python_prog="" -with_python_path="$PATH" -AC_ARG_WITH(python, [AS_HELP_STRING([--with-python@<:@=PREFIX@:>@], [Path to the python interpreter.])], -[ - if test "x$withval" = "xyes" || test "x$withval" = "xno" - then - with_python="$withval" - else if test -x "$withval" - then - with_python_prog="$withval" - with_python_path="`dirname \"$withval\"`$PATH_SEPARATOR$with_python_path" - with_python="yes" - else if test -d "$withval" - then - with_python_path="$withval$PATH_SEPARATOR$with_python_path" - with_python="yes" - else - AC_MSG_WARN([Argument not recognized: $withval]) - fi; fi; fi -], [with_python="yes"]) - -SAVE_PATH="$PATH" -SAVE_CPPFLAGS="$CPPFLAGS" -SAVE_LDFLAGS="$LDFLAGS" -SAVE_LIBS="$LIBS" - -PATH="$with_python_path" - -if test "x$with_python" = "xyes" && test "x$with_python_prog" = "x" +# --with-libprotobuf {{{ +with_libprotobuf_cppflags="" +with_libprotobuf_ldflags="" +AC_ARG_WITH([libprotobuf], [AS_HELP_STRING([--with-libprotobuf@<:@=PREFIX@:>@], [Path to libprotobuf.])], + [ + if test "x$withval" != "xno" && test "x$withval" != "xyes" + then + with_libprotobuf_cppflags="-I$withval/include" + with_libprotobuf_ldflags="-L$withval/lib" + with_libprotobuf="yes" + fi + if test "x$withval" = "xno" + then + with_libprotobuf="no (disabled on command line)" + fi + ], + [withval="yes"] +) +if test "x$withval" = "xyes" then - AC_MSG_CHECKING([for python]) - with_python_prog="`which python 2>/dev/null`" - if test "x$with_python_prog" = "x" - then - AC_MSG_RESULT([not found]) - with_python="no (interpreter not found)" - else - AC_MSG_RESULT([$with_python_prog]) - fi +PKG_CHECK_MODULES([PROTOBUF], [protobuf], + [with_libprotobuf="yes"], + [with_libprotobuf="no (pkg-config could not find libprotobuf)"] +) fi -if test "x$with_python" = "xyes" +if test "x$withval" != "xno" then - AC_MSG_CHECKING([for Python CPPFLAGS]) - python_include_path=`echo "import distutils.sysconfig;import sys;sys.stdout.write(distutils.sysconfig.get_python_inc())" | "$with_python_prog" 2>&1` - python_config_status=$? - - if test "$python_config_status" -ne 0 || test "x$python_include_path" = "x" - then - AC_MSG_RESULT([failed with status $python_config_status (output: $python_include_path)]) - with_python="no" - else - AC_MSG_RESULT([$python_include_path]) - fi + SAVE_LDFLAGS="$LDFLAGS" + SAVE_LIBS="$LIBS" + LDFLAGS="$with_libprotobuf_ldflags" + LIBS="$PROTOBUF_LIBS $LIBS" + AC_LANG_PUSH([C++]) + AC_CHECK_LIB([protobuf], [main], + [ + SAVE_CPPFLAGS="$CPPFLAGS" + CPPFLAGS="$with_libprotobuf_cppflags $PROTOBUF_CFLAGS" + if test "x$PROTOBUF_LIBS" = "x" + then + PROTOBUF_LIBS="-lprotobuf" + fi + AC_CHECK_HEADERS([google/protobuf/util/time_util.h], + [with_libprotobuf="yes"], + [with_libprotobuf="no ( not found)"] + ) + CPPFLAGS="$SAVE_CPPFLAGS" + ], + [with_libprotobuf="no (libprotobuf not found)"] + ) + AC_LANG_POP([C++]) + LDFLAGS="$SAVE_LDFLAGS" + LIBS="$SAVE_LIBS" fi +BUILD_WITH_LIBPROTOBUF_CPPFLAGS="$with_libprotobuf_cppflags $PROTOBUF_CFLAGS" +BUILD_WITH_LIBPROTOBUF_LDFLAGS="$with_libprotobuf_ldflags" +BUILD_WITH_LIBPROTOBUF_LIBS="$PROTOBUF_LIBS" +AC_SUBST([BUILD_WITH_LIBPROTOBUF_CPPFLAGS]) +AC_SUBST([BUILD_WITH_LIBPROTOBUF_LDFLAGS]) +AC_SUBST([BUILD_WITH_LIBPROTOBUF_LIBS]) +# }}} -if test "x$with_python" = "xyes" +# --with-libprotobuf-c {{{ +with_libprotobuf_c_cppflags="" +with_libprotobuf_c_ldflags="" +AC_ARG_WITH([libprotobuf-c], [AS_HELP_STRING([--with-libprotobuf-c@<:@=PREFIX@:>@], [Path to libprotobuf-c.])], + [ + if test "x$withval" != "xno" && test "x$withval" != "xyes" + then + with_libprotobuf_c_cppflags="-I$withval/include" + with_libprotobuf_c_ldflags="-L$withval/lib" + with_libprotobuf_c="yes" + fi + if test "x$withval" = "xno" + then + with_libprotobuf_c="no (disabled on command line)" + fi + ], + [withval="yes"] +) +if test "x$withval" = "xyes" then - CPPFLAGS="-I$python_include_path $CPPFLAGS" - AC_CHECK_HEADERS(Python.h, - [with_python="yes"], - [with_python="no ('Python.h' not found)"]) +PKG_CHECK_MODULES([PROTOBUF_C], [libprotobuf-c], + [with_libprotobuf_c="yes"], + [with_libprotobuf_c="no (pkg-config could not find libprotobuf-c)"] +) fi -if test "x$with_python" = "xyes" +if test "x$withval" != "xno" then - AC_MSG_CHECKING([for Python LDFLAGS]) - python_library_path=`echo "import distutils.sysconfig;import sys;sys.stdout.write(distutils.sysconfig.get_config_vars(\"LIBDIR\").__getitem__(0))" | "$with_python_prog" 2>&1` - python_config_status=$? - - if test "$python_config_status" -ne 0 || test "x$python_library_path" = "x" - then - AC_MSG_RESULT([failed with status $python_config_status (output: $python_library_path)]) - with_python="no" - else - AC_MSG_RESULT([$python_library_path]) - fi + SAVE_LDFLAGS="$LDFLAGS" + SAVE_LIBS="$LIBS" + LDFLAGS="$with_libprotobuf_c_ldflags" + LIBS="$PROTOBUF_C_LIBS $LIBS" + AC_CHECK_LIB([protobuf-c], [protobuf_c_message_pack], + [ + SAVE_CPPFLAGS="$CPPFLAGS" + CPPFLAGS="$with_libprotobuf_c_cppflags $PROTOBUF_C_CFLAGS" + if test "x$PROTOBUF_C_LIBS" = "x" + then + PROTOBUF_C_LIBS="-lprotobuf-c" + fi + AC_CHECK_HEADERS([protobuf-c/protobuf-c.h google/protobuf-c/protobuf-c.h], + [ + with_libprotobuf_c="yes" + break + ], + [with_libprotobuf_c="no ( not found)"] + ) + CPPFLAGS="$SAVE_CPPFLAGS" + ], + [with_libprotobuf_c="no (libprotobuf-c not found)"] + ) + LDFLAGS="$SAVE_LDFLAGS" + LIBS="$SAVE_LIBS" fi +BUILD_WITH_LIBPROTOBUF_C_CPPFLAGS="$with_libprotobuf_c_cppflags $PROTOBUF_C_CFLAGS" +BUILD_WITH_LIBPROTOBUF_C_LDFLAGS="$with_libprotobuf_c_ldflags" +BUILD_WITH_LIBPROTOBUF_C_LIBS="$PROTOBUF_C_LIBS" +AC_SUBST([BUILD_WITH_LIBPROTOBUF_C_CPPFLAGS]) +AC_SUBST([BUILD_WITH_LIBPROTOBUF_C_LDFLAGS]) +AC_SUBST([BUILD_WITH_LIBPROTOBUF_C_LIBS]) +# }}} -if test "x$with_python" = "xyes" -then - AC_MSG_CHECKING([for Python LIBS]) - python_library_flags=`echo "import distutils.sysconfig;import sys;sys.stdout.write(distutils.sysconfig.get_config_vars(\"BLDLIBRARY\").__getitem__(0))" | "$with_python_prog" 2>&1` - python_config_status=$? +# --with-libpython {{{ +AC_ARG_VAR([LIBPYTHON_CPPFLAGS], [Preprocessor flags for libpython]) +AC_ARG_VAR([LIBPYTHON_LDFLAGS], [Linker flags for libpython]) +AC_ARG_VAR([LIBPYTHON_LIBS], [Libraries for libpython]) - if test "$python_config_status" -ne 0 || test "x$python_library_flags" = "x" - then - AC_MSG_RESULT([failed with status $python_config_status (output: $python_library_flags)]) - with_python="no" - else - AC_MSG_RESULT([$python_library_flags]) - fi +AC_ARG_WITH([libpython], + [AS_HELP_STRING([--with-libpython], + [if we should build with libpython @<:@default=yes@:>@]) + ], + [with_libpython="$withval"], + [with_libpython="check"] +) +if test "$with_libpython" != "no"; then + if test "$LIBPYTHON_CPPFLAGS" = "" && test "$LIBPYTHON_LDFLAGS" = ""; then + AC_ARG_VAR([PYTHON_CONFIG], [path to python-config]) + AC_PATH_PROGS([PYTHON_CONFIG], + [python3-config python2-config python-config] + ) + if test "$PYTHON_CONFIG" = ""; then + if test "$with_libpython" = "yes"; then + AC_MSG_ERROR([Unable to find python-config]) + fi + with_libpython="no" + fi + fi fi -if test "x$with_python" = "xyes" -then - LDFLAGS="-L$python_library_path $LDFLAGS" - LIBS="$python_library_flags $LIBS" - - AC_CHECK_FUNC(PyObject_CallFunction, - [with_python="yes"], - [with_python="no (Symbol 'PyObject_CallFunction' not found)"]) +if test "$PYTHON_CONFIG" != ""; then + LIBPYTHON_CPPFLAGS="`${PYTHON_CONFIG} --includes`" + if test $? -ne 0; then + with_libpython="no" + fi + LIBPYTHON_LDFLAGS="`${PYTHON_CONFIG} --ldflags`" + if test $? -ne 0; then + with_libpython="no" + fi + LIBPYTHON_LIBS="`${PYTHON_CONFIG} --libs`" + if test $? -ne 0; then + with_libpython="no" + fi fi -PATH="$SAVE_PATH" -CPPFLAGS="$SAVE_CPPFLAGS" -LDFLAGS="$SAVE_LDFLAGS" -LIBS="$SAVE_LIBS" - -if test "x$with_python" = "xyes" -then - BUILD_WITH_PYTHON_CPPFLAGS="-I$python_include_path" - BUILD_WITH_PYTHON_LDFLAGS="-L$python_library_path" - BUILD_WITH_PYTHON_LIBS="$python_library_flags" - AC_SUBST(BUILD_WITH_PYTHON_CPPFLAGS) - AC_SUBST(BUILD_WITH_PYTHON_LDFLAGS) - AC_SUBST(BUILD_WITH_PYTHON_LIBS) +if test "$with_libpython" != "xno"; then + SAVE_CPPFLAGS="$CPPFLAGS" + SAVE_LDFLAGS="$LDFLAGS" + SAVE_LIBS="$LIBS" + CPPFLAGS="$LIBPYTHON_CPPFLAGS $CPPFLAGS" + LDFLAGS="$LIBPYTHON_LDFLAGS $LDFLAGS" + LIBS="$LIBPYTHON_LIBS $LIBS" + AC_CHECK_HEADERS([Python.h], + [ + AC_MSG_CHECKING([for libpython]) + AC_LINK_IFELSE([AC_LANG_PROGRAM( + [[#include ]], + [[Py_Initialize();]]) + ], + [with_libpython="yes"], + [with_libpython="no"] + ) + AC_MSG_RESULT([$with_libpython]) + ], + [with_libpython="no"] + ) + CPPFLAGS="$SAVE_CPPFLAGS" + LDFLAGS="$SAVE_LDFLAGS" + LIBS="$SAVE_LIBS" fi -# }}} --with-python +# }}} --with-libpython # --with-librabbitmq {{{ with_librabbitmq_cppflags="" @@ -4429,74 +4671,13 @@ fi AM_CONDITIONAL(BUILD_WITH_LM_SENSORS, test "x$with_libsensors" = "xyes") # }}} -# --with-libsigrok {{{ -with_libsigrok_cflags="" -with_libsigrok_ldflags="" -AC_ARG_WITH(libsigrok, [AS_HELP_STRING([--with-libsigrok@<:@=PREFIX@:>@], [Path to libsigrok.])], -[ - if test "x$withval" = "xno" - then - with_libsigrok="no" - else - with_libsigrok="yes" - if test "x$withval" != "xyes" - then - with_libsigrok_cflags="-I$withval/include" - with_libsigrok_ldflags="-L$withval/lib" - fi - fi -],[with_libsigrok="yes"]) - -# libsigrok has a glib dependency -if test "x$with_libsigrok" = "xyes" -then -m4_ifdef([AM_PATH_GLIB_2_0], - [ - AM_PATH_GLIB_2_0([2.28.0], - [with_libsigrok_cflags="$with_libsigrok_cflags $GLIB_CFLAGS"; with_libsigrok_ldflags="$with_libsigrok_ldflags $GLIB_LIBS"]) - ], - [ - with_libsigrok="no (glib not available)" - ] +# libsigrok {{{ +AC_SUBST([LIBSIGROK_CFLAGS]) +AC_SUBST([LIBSIGROK_LIBS]) +PKG_CHECK_MODULES([LIBSIGROK], [libsigrok < 0.4], + [with_libsigrok="yes"], + [with_libsigrok="no (pkg-config could not find libsigrok)"] ) -fi - -# libsigrok headers -if test "x$with_libsigrok" = "xyes" -then - SAVE_CPPFLAGS="$CPPFLAGS" - CPPFLAGS="$CPPFLAGS $with_libsigrok_cflags" - - AC_CHECK_HEADERS(libsigrok/libsigrok.h, [], [with_libsigrok="no (libsigrok/libsigrok.h not found)"]) - - CPPFLAGS="$SAVE_CPPFLAGS" -fi - -# libsigrok library -if test "x$with_libsigrok" = "xyes" -then - SAVE_CPPFLAGS="$CPPFLAGS" - SAVE_LDFLAGS="$LDFLAGS" - CPPFLAGS="$CPPFLAGS $with_libsigrok_cflags" - LDFLAGS="$LDFLAGS $with_libsigrok_ldflags" - - AC_CHECK_LIB(sigrok, sr_init, - [ - AC_DEFINE(HAVE_LIBSIGROK, 1, [Define to 1 if you have the sigrok library (-lsigrok).]) - ], - [with_libsigrok="no (libsigrok not found)"]) - - CPPFLAGS="$SAVE_CPPFLAGS" - LDFLAGS="$SAVE_LDFLAGS" -fi -if test "x$with_libsigrok" = "xyes" -then - BUILD_WITH_LIBSIGROK_CFLAGS="$with_libsigrok_cflags" - BUILD_WITH_LIBSIGROK_LDFLAGS="$with_libsigrok_ldflags" - AC_SUBST(BUILD_WITH_LIBSIGROK_CFLAGS) - AC_SUBST(BUILD_WITH_LIBSIGROK_LDFLAGS) -fi -AM_CONDITIONAL(BUILD_WITH_LIBSIGROK, test "x$with_libsigrok" = "xyes") # }}} # --with-libstatgrab {{{ @@ -4524,23 +4705,16 @@ AC_ARG_WITH(libstatgrab, [AS_HELP_STRING([--with-libstatgrab@<:@=PREFIX@:>@], [P if test "x$with_libstatgrab" = "xyes" \ && test "x$with_libstatgrab_pkg_config" = "xyes" then - if test "x$PKG_CONFIG" != "x" + AC_MSG_CHECKING([pkg-config for libstatgrab]) + temp_result="found" + $PKG_CONFIG --exists libstatgrab 2>/dev/null + if test "$?" != "0" then - AC_MSG_CHECKING([pkg-config for libstatgrab]) - temp_result="found" - $PKG_CONFIG --exists libstatgrab 2>/dev/null - if test "$?" != "0" - then - with_libstatgrab_pkg_config="no" - with_libstatgrab="no (pkg-config doesn't know libstatgrab)" - temp_result="not found" - fi - AC_MSG_RESULT([$temp_result]) - else - AC_MSG_NOTICE([pkg-config not available, trying to guess flags for the statgrab library.]) with_libstatgrab_pkg_config="no" - with_libstatgrab_ldflags="$with_libstatgrab_ldflags -lstatgrab" + with_libstatgrab="no (pkg-config doesn't know libstatgrab)" + temp_result="not found" fi + AC_MSG_RESULT([$temp_result]) fi if test "x$with_libstatgrab" = "xyes" \ @@ -4839,13 +5013,6 @@ fi # configure using pkg-config if test "x$with_libupsclient" = "xuse_pkgconfig" then - if test "x$PKG_CONFIG" = "x" - then - with_libupsclient="no (Don't have pkg-config)" - fi -fi -if test "x$with_libupsclient" = "xuse_pkgconfig" -then AC_MSG_NOTICE([Checking for libupsclient using $PKG_CONFIG]) $PKG_CONFIG --exists 'libupsclient' 2>/dev/null if test $? -ne 0 @@ -5167,13 +5334,6 @@ AC_ARG_WITH(libvarnish, [AS_HELP_STRING([--with-libvarnish@<:@=PREFIX@:>@], [Pat # configure using pkg-config if test "x$with_libvarnish" = "xuse_pkgconfig" then - if test "x$PKG_CONFIG" = "x" - then - with_libvarnish="no (Don't have pkg-config)" - fi -fi -if test "x$with_libvarnish" = "xuse_pkgconfig" -then AC_MSG_NOTICE([Checking for varnishapi using $PKG_CONFIG]) $PKG_CONFIG --exists 'varnishapi' 2>/dev/null if test $? -ne 0 @@ -5233,23 +5393,20 @@ with_libxml2_ldflags="" with_libvirt="no (pkg-config isn't available)" with_libvirt_cflags="" with_libvirt_ldflags="" -if test "x$PKG_CONFIG" != "x" +$PKG_CONFIG --exists 'libxml-2.0' 2>/dev/null +if test "$?" = "0" then - $PKG_CONFIG --exists 'libxml-2.0' 2>/dev/null - if test "$?" = "0" - then - with_libxml2="yes" - else - with_libxml2="no (pkg-config doesn't know libxml-2.0)" - fi + with_libxml2="yes" +else + with_libxml2="no (pkg-config doesn't know libxml-2.0)" +fi - $PKG_CONFIG --exists libvirt 2>/dev/null - if test "$?" = "0" - then - with_libvirt="yes" - else - with_libvirt="no (pkg-config doesn't know libvirt)" - fi +$PKG_CONFIG --exists libvirt 2>/dev/null +if test "$?" = "0" +then + with_libvirt="yes" +else + with_libvirt="no (pkg-config doesn't know libvirt)" fi if test "x$with_libxml2" = "xyes" then @@ -5348,17 +5505,6 @@ with_libopenipmipthread="yes" with_libopenipmipthread_cflags="" with_libopenipmipthread_libs="" -AC_MSG_CHECKING([for pkg-config]) -temp_result="no" -if test "x$PKG_CONFIG" = "x" -then - with_libopenipmipthread="no" - temp_result="no" -else - temp_result="$PKG_CONFIG" -fi -AC_MSG_RESULT([$temp_result]) - if test "x$with_libopenipmipthread" = "xyes" then AC_MSG_CHECKING([for libOpenIPMIpthread]) @@ -5485,7 +5631,7 @@ PKG_CHECK_MODULES([LIBNOTIFY], [libnotify], [with_libnotify="no (pkg-config doesn't know libnotify)"] ) -PKG_CHECK_MODULES([LIBRIEMANN_CLIENT], [riemann-client >= 1.8.0], +PKG_CHECK_MODULES([LIBRIEMANN_CLIENT], [riemann-client >= 1.6.0], [with_libriemann_client="yes"], [with_libriemann_client="no (pkg-config doesn't know libriemann-client)"]) @@ -5626,6 +5772,7 @@ plugin_conntrack="no" plugin_contextswitch="no" plugin_cpu="no" plugin_cpufreq="no" +plugin_cpusleep="no" plugin_curl_json="no" plugin_curl_xml="no" plugin_df="no" @@ -5636,6 +5783,9 @@ plugin_entropy="no" plugin_ethstat="no" plugin_fhcount="no" plugin_fscache="no" +plugin_gps="no" +plugin_grpc="no" +plugin_hugepages="no" plugin_interface="no" plugin_ipmi="no" plugin_ipvs="no" @@ -5647,8 +5797,10 @@ plugin_multimeter="no" plugin_nfs="no" plugin_numa="no" plugin_perl="no" +plugin_pinba="no" plugin_processes="no" plugin_protocols="no" +plugin_python="no" plugin_serial="no" plugin_smart="no" plugin_swap="no" @@ -5682,6 +5834,7 @@ then plugin_entropy="yes" plugin_fhcount="yes" plugin_fscache="yes" + plugin_hugepages="yes" plugin_interface="yes" plugin_ipc="yes" plugin_irq="yes" @@ -5710,6 +5863,11 @@ then then plugin_turbostat="yes" fi + + if test "x$c_cv_have_clock_boottime_monotonic" = "xyes" + then + plugin_cpusleep="yes" + fi fi if test "x$ac_system" = "xOpenBSD" @@ -5911,11 +6069,21 @@ then plugin_ethstat="yes" fi +if test "x$with_libgrpcpp" = "xyes" && test "x$with_libprotobuf" = "xyes" && test "x$have_protoc3" = "xyes" && test "x$GRPC_CPP_PLUGIN" != "x" +then + plugin_grpc="yes" +fi + if test "x$have_getifaddrs" = "xyes" then plugin_interface="yes" fi +if test "x$with_libgps" = "xyes" +then + plugin_gps="yes" +fi + if test "x$have_getloadavg" = "xyes" then plugin_load="yes" @@ -5931,6 +6099,11 @@ then plugin_perl="yes" fi +if test "x$have_protoc_c" = "xyes" && test "x$with_libprotobuf_c" = "xyes" +then + plugin_pinba="yes" +fi + # Mac OS X memory interface if test "x$have_host_statistics" = "xyes" then @@ -5961,6 +6134,11 @@ then plugin_processes="yes" fi +if test "x$with_libpython" != "xno" +then + plugin_python="yes" +fi + if test "x$with_libatasmart" = "xyes" && test "x$with_libudev" = "xyes" then plugin_smart="yes" @@ -6042,6 +6220,7 @@ AC_PLUGIN([conntrack], [$plugin_conntrack], [nf_conntrack statis AC_PLUGIN([contextswitch], [$plugin_contextswitch], [context switch statistics]) AC_PLUGIN([cpu], [$plugin_cpu], [CPU usage statistics]) AC_PLUGIN([cpufreq], [$plugin_cpufreq], [CPU frequency statistics]) +AC_PLUGIN([cpusleep], [$plugin_cpusleep], [CPU sleep statistics]) AC_PLUGIN([csv], [yes], [CSV output plugin]) AC_PLUGIN([curl], [$with_libcurl], [CURL generic web statistics]) AC_PLUGIN([curl_json], [$plugin_curl_json], [CouchDB statistics]) @@ -6060,8 +6239,10 @@ AC_PLUGIN([fhcount], [$plugin_fhcount], [File handles statis AC_PLUGIN([filecount], [yes], [Count files in directories]) AC_PLUGIN([fscache], [$plugin_fscache], [fscache statistics]) AC_PLUGIN([gmond], [$with_libganglia], [Ganglia plugin]) -AC_PLUGIN([grpc], [$with_grpc], [gRPC plugin]) +AC_PLUGIN([gps], [$plugin_gps], [GPS plugin]) +AC_PLUGIN([grpc], [$plugin_grpc], [gRPC plugin]) AC_PLUGIN([hddtemp], [yes], [Query hddtempd]) +AC_PLUGIN([hugepages], [$plugin_hugepages], [Hugepages statistics]) AC_PLUGIN([interface], [$plugin_interface], [Interface traffic statistics]) AC_PLUGIN([ipc], [$plugin_ipc], [IPC statistics]) AC_PLUGIN([ipmi], [$plugin_ipmi], [IPMI sensor statistics]) @@ -6073,6 +6254,7 @@ AC_PLUGIN([load], [$plugin_load], [System load]) AC_PLUGIN([log_logstash], [$plugin_log_logstash], [Logstash json_event compatible logging]) AC_PLUGIN([logfile], [yes], [File logging plugin]) AC_PLUGIN([lpar], [$with_perfstat], [AIX logical partitions statistics]) +AC_PLUGIN([lua], [$with_liblua], [Lua plugin]) AC_PLUGIN([lvm], [$with_liblvm2app], [LVM statistics]) AC_PLUGIN([madwifi], [$have_linux_wireless_h], [Madwifi wireless statistics]) AC_PLUGIN([match_empty_counter], [yes], [The empty counter match]) @@ -6109,13 +6291,13 @@ AC_PLUGIN([oracle], [$with_oracle], [Oracle plugin]) AC_PLUGIN([perl], [$plugin_perl], [Embed a Perl interpreter]) AC_PLUGIN([pf], [$have_net_pfvar_h], [BSD packet filter (PF) statistics]) # FIXME: Check for libevent, too. -AC_PLUGIN([pinba], [$have_protoc_c], [Pinba statistics]) +AC_PLUGIN([pinba], [$plugin_pinba], [Pinba statistics]) AC_PLUGIN([ping], [$with_liboping], [Network latency statistics]) 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([python], [$with_python], [Embed a Python interpreter]) +AC_PLUGIN([python], [$plugin_python], [Embed a Python interpreter]) AC_PLUGIN([redis], [$with_libhiredis], [Redis plugin]) AC_PLUGIN([routeros], [$with_librouteros], [RouterOS plugin]) AC_PLUGIN([rrdcached], [$librrd_rrdc_update], [RRDTool output plugin]) @@ -6291,6 +6473,18 @@ AC_ARG_WITH(perl-bindings, [AS_HELP_STRING([--with-perl-bindings@<:@=OPTIONS@:>@ with_perl_bindings="no (no perl interpreter found)" fi ]) + +if test "x$with_perl_bindings" = "xyes" +then + AC_MSG_CHECKING([for the ExtUtils::MakeMaker module]) + if $PERL -MExtUtils::MakeMaker -e '' 2>/dev/null; then + AC_MSG_RESULT([yes]) + else + AC_MSG_RESULT([no]) + with_perl_bindings="no (ExtUtils::MakeMaker not found)" + fi +fi + if test "x$with_perl_bindings" = "xyes" then PERL_BINDINGS="perl" @@ -6380,7 +6574,8 @@ AC_MSG_RESULT([ libdpdk . . . . . . . $with_libdpdk]) AC_MSG_RESULT([ libesmtp . . . . . . $with_libesmtp]) AC_MSG_RESULT([ libganglia . . . . . $with_libganglia]) AC_MSG_RESULT([ libgcrypt . . . . . . $with_libgcrypt]) -AC_MSG_RESULT([ libgrpc . . . . . . . $with_libgrpc]) +AC_MSG_RESULT([ libgps . . . . . . . $with_libgps]) +AC_MSG_RESULT([ libgrpc++ . . . . . . $with_libgrpcpp]) AC_MSG_RESULT([ libhal . . . . . . . $with_libhal]) AC_MSG_RESULT([ libhiredis . . . . . $with_libhiredis]) AC_MSG_RESULT([ libi2c-dev . . . . . $with_libi2c]) @@ -6390,6 +6585,7 @@ AC_MSG_RESULT([ libjvm . . . . . . . $with_java]) AC_MSG_RESULT([ libkstat . . . . . . $with_kstat]) AC_MSG_RESULT([ libkvm . . . . . . . $with_libkvm]) AC_MSG_RESULT([ libldap . . . . . . . $with_libldap]) +AC_MSG_RESULT([ liblua . . . . . . . $with_liblua]) AC_MSG_RESULT([ liblvm2app . . . . . $with_liblvm2app]) AC_MSG_RESULT([ libmemcached . . . . $with_libmemcached]) AC_MSG_RESULT([ libmnl . . . . . . . $with_libmnl]) @@ -6408,6 +6604,9 @@ AC_MSG_RESULT([ libpcap . . . . . . . $with_libpcap]) AC_MSG_RESULT([ libperfstat . . . . . $with_perfstat]) AC_MSG_RESULT([ libperl . . . . . . . $with_libperl]) AC_MSG_RESULT([ libpq . . . . . . . . $with_libpq]) +AC_MSG_RESULT([ libprotobuf . . . . . $with_libprotobuf]) +AC_MSG_RESULT([ libprotobuf-c . . . . $with_libprotobuf_c]) +AC_MSG_RESULT([ libpython . . . . . . $with_libpython]) AC_MSG_RESULT([ librabbitmq . . . . . $with_librabbitmq]) AC_MSG_RESULT([ libriemann-client . . $with_libriemann_client]) AC_MSG_RESULT([ librdkafka . . . . . $with_librdkafka]) @@ -6427,8 +6626,7 @@ AC_MSG_RESULT([ libxmms . . . . . . . $with_libxmms]) AC_MSG_RESULT([ libyajl . . . . . . . $with_libyajl]) AC_MSG_RESULT([ oracle . . . . . . . $with_oracle]) AC_MSG_RESULT([ protobuf-c . . . . . $have_protoc_c]) -AC_MSG_RESULT([ protoc 3 . . . . . . $protoc3]) -AC_MSG_RESULT([ python . . . . . . . $with_python]) +AC_MSG_RESULT([ protoc 3 . . . . . . $have_protoc3]) AC_MSG_RESULT() AC_MSG_RESULT([ Features:]) AC_MSG_RESULT([ daemon mode . . . . . $enable_daemon]) @@ -6455,6 +6653,7 @@ AC_MSG_RESULT([ conntrack . . . . . . $enable_conntrack]) AC_MSG_RESULT([ contextswitch . . . . $enable_contextswitch]) AC_MSG_RESULT([ cpu . . . . . . . . . $enable_cpu]) AC_MSG_RESULT([ cpufreq . . . . . . . $enable_cpufreq]) +AC_MSG_RESULT([ cpusleep . . . . . . $enable_cpusleep]) AC_MSG_RESULT([ csv . . . . . . . . . $enable_csv]) AC_MSG_RESULT([ curl . . . . . . . . $enable_curl]) AC_MSG_RESULT([ curl_json . . . . . . $enable_curl_json]) @@ -6473,8 +6672,10 @@ AC_MSG_RESULT([ fhcount . . . . . . . $enable_fhcount]) AC_MSG_RESULT([ filecount . . . . . . $enable_filecount]) AC_MSG_RESULT([ fscache . . . . . . . $enable_fscache]) AC_MSG_RESULT([ gmond . . . . . . . . $enable_gmond]) +AC_MSG_RESULT([ gps . . . . . . . . . $enable_gps]) AC_MSG_RESULT([ grpc . . . . . . . . $enable_grpc]) AC_MSG_RESULT([ hddtemp . . . . . . . $enable_hddtemp]) +AC_MSG_RESULT([ hugepages . . . . . . $enable_hugepages]) AC_MSG_RESULT([ interface . . . . . . $enable_interface]) AC_MSG_RESULT([ ipc . . . . . . . . . $enable_ipc]) AC_MSG_RESULT([ ipmi . . . . . . . . $enable_ipmi]) @@ -6486,6 +6687,7 @@ AC_MSG_RESULT([ load . . . . . . . . $enable_load]) AC_MSG_RESULT([ logfile . . . . . . . $enable_logfile]) AC_MSG_RESULT([ log_logstash . . . . $enable_log_logstash]) AC_MSG_RESULT([ lpar . . . . . . . . $enable_lpar]) +AC_MSG_RESULT([ lua . . . . . . . . . $enable_lua]) AC_MSG_RESULT([ lvm . . . . . . . . . $enable_lvm]) AC_MSG_RESULT([ madwifi . . . . . . . $enable_madwifi]) AC_MSG_RESULT([ match_empty_counter . $enable_match_empty_counter]) diff --git a/contrib/examples/myplugin.c b/contrib/examples/myplugin.c index 9539062c..71fb5f8b 100644 --- a/contrib/examples/myplugin.c +++ b/contrib/examples/myplugin.c @@ -39,6 +39,7 @@ #endif /* ! HAVE_CONFIG */ #include + #include #include @@ -84,36 +85,50 @@ static int my_init (void) } /* static int my_init (void) */ /* - * This function is called in regular intervalls to collect the data. + * This is a utility function used by the read callback to populate a + * value_list_t and pass it to plugin_dispatch_values. */ -static int my_read (void) +static int my_submit (gauge_t value) { - value_t values[1]; /* the size of this list should equal the number of - data sources */ value_list_t vl = VALUE_LIST_INIT; - /* do the magic to read the data */ - values[0].gauge = random (); - - vl.values = values; + /* Convert the gauge_t to a value_t and add it to the value_list_t. */ + vl.values = &(value_t) { .gauge = value }; vl.values_len = 1; - vl.time = time (NULL); + + /* Only set vl.time yourself if you update multiple metrics (i.e. you + * have multiple calls to plugin_dispatch_values()) and they need to all + * have the same timestamp. */ + /* vl.time = cdtime(); */ + sstrncpy (vl.host, hostname_g, sizeof (vl.host)); sstrncpy (vl.plugin, "myplugin", sizeof (vl.plugin)); /* it is strongly recommended to use a type defined in the types.db file * instead of a custom type */ - sstrncpy (vl.type, "myplugin", sizeof (vl.plugin)); + sstrncpy (vl.type, "myplugin", sizeof (vl.type)); /* optionally set vl.plugin_instance and vl.type_instance to reasonable * values (default: "") */ /* dispatch the values to collectd which passes them on to all registered * write functions */ - plugin_dispatch_values (&vl); + return plugin_dispatch_values (&vl); +} + +/* + * This function is called in regular intervalls to collect the data. + */ +static int my_read (void) +{ + /* do the magic to read the data */ + gauge_t value = random (); + + if (my_submit (value) != 0) + WARNING ("myplugin plugin: Dispatching a random value failed."); /* A return value != 0 indicates an error and the plugin will be skipped * for an increasing amount of time. */ - return 0; + return 0; } /* static int my_read (void) */ /* diff --git a/contrib/migrate-4-5.px b/contrib/migrate-4-5.px index c2a95558..8e5a7ed4 100755 --- a/contrib/migrate-4-5.px +++ b/contrib/migrate-4-5.px @@ -104,8 +104,6 @@ our %TypesCounterToDerive = # {{{ protocol_counter => ["value"], ps_cputime => ["user", "syst"], ps_pagefaults => ["minflt", "majflt"], - ps_code => ["value"], - ps_data => ["value"], serial_octets => ["rx", "tx"], swap_io => ["value"], virt_cpu_total => ["ns"], diff --git a/contrib/redhat/collectd.spec b/contrib/redhat/collectd.spec index 10546c8e..73e69c75 100644 --- a/contrib/redhat/collectd.spec +++ b/contrib/redhat/collectd.spec @@ -53,6 +53,7 @@ %define with_contextswitch 0%{!?_without_contextswitch:1} %define with_cpu 0%{!?_without_cpu:1} %define with_cpufreq 0%{!?_without_cpufreq:1} +%define with_cpusleep 0%{!?_without_cpusleep:1} %define with_csv 0%{!?_without_csv:1} %define with_curl 0%{!?_without_curl:1} %define with_curl_json 0%{!?_without_curl_json:1} @@ -70,7 +71,9 @@ %define with_filecount 0%{!?_without_filecount:1} %define with_fscache 0%{!?_without_fscache:1} %define with_gmond 0%{!?_without_gmond:1} +%define with_gps 0%{!?_without_gps:1} %define with_hddtemp 0%{!?_without_hddtemp:1} +%define with_hugepages 0%{!?_without_hugepages:1} %define with_interface 0%{!?_without_interface:1} %define with_ipc 0%{!?_without_ipc:1} %define with_ipmi 0%{!?_without_ipmi:1} @@ -81,6 +84,7 @@ %define with_load 0%{!?_without_load:1} %define with_log_logstash 0%{!?_without_log_logstash:1} %define with_logfile 0%{!?_without_logfile:1} +%define with_lua 0%{!?_without_lua:1} %define with_lvm 0%{!?_without_lvm:1} %define with_madwifi 0%{!?_without_madwifi:1} %define with_mbmon 0%{!?_without_mbmon:1} @@ -214,6 +218,8 @@ # Plugins not buildable on RHEL < 7 %if 0%{?rhel} && 0%{?rhel} < 7 +%define with_cpusleep 0 +%define with_gps 0 %define with_mqtt 0 %define with_rrdcached 0 %define with_xmms 0 @@ -221,14 +227,14 @@ Summary: Statistics collection and monitoring daemon Name: collectd -Version: 5.5.2 -Release: 1%{?dist} +Version: 5.7.0 +Release: 2%{?dist} URL: https://collectd.org Source: https://collectd.org/files/%{name}-%{version}.tar.bz2 License: GPLv2 Group: System Environment/Daemons BuildRoot: %{_tmppath}/%{name}-%{version}-root -BuildRequires: libgcrypt-devel, kernel-headers, libtool-ltdl-devel, libcap-devel +BuildRequires: libgcrypt-devel, kernel-headers, libtool-ltdl-devel, libcap-devel, which Vendor: collectd development team %if 0%{?fedora} || 0%{?rhel} >= 7 @@ -416,6 +422,16 @@ The gmond plugin subscribes to a Multicast group to receive data from gmond, the client daemon of the Ganglia project. %endif +%if %{with_gps} +%package gps +Summary: GPS plugin for collectd +Group: System Environment/Daemons +Requires: %{name}%{?_isa} = %{version}-%{release} +BuildRequires: gpsd-devel +%description gps +This plugin monitor gps related data through gpsd. +%endif + %if %{with_grpc} %package grpc Summary: GRPC plugin for collectd @@ -481,6 +497,17 @@ BuildRequires: yajl-devel This plugin logs in logstash JSON format %endif +%if %{with_lua} +%package lua +Summary: Lua plugin for collectd +Group: System Environment/Daemons +Requires: %{name}%{?_isa} = %{version}-%{release} +BuildRequires: lua-devel +%description lua +The Lua plugin embeds a Lua interpreter into collectd and exposes the +application programming interface (API) to Lua scripts. +%endif + %if %{with_lvm} %package lvm Summary: LVM plugin for collectd @@ -976,6 +1003,12 @@ Collectd utilities %define _with_cpufreq --disable-cpufreq %endif +%if %{with_cpusleep} +%define _with_cpusleep --enable-cpusleep +%else +%define _with_cpusleep --disable-cpusleep +%endif + %if %{with_csv} %define _with_csv --enable-csv %else @@ -1084,6 +1117,12 @@ Collectd utilities %define _with_gmond --disable-gmond %endif +%if %{with_gps} +%define _with_gps --enable-gps +%else +%define _with_gps --disable-gps +%endif + %if %{with_grpc} %define _with_grpc --enable-grpc %else @@ -1096,6 +1135,12 @@ Collectd utilities %define _with_hddtemp --disable-hddtemp %endif +%if %{with_hugepages} +%define _with_hugepages --enable-hugepages +%else +%define _with_hugepages --disable-hugepages +%endif + %if %{with_interface} %define _with_interface --enable-interface %else @@ -1168,6 +1213,12 @@ Collectd utilities %define _with_lpar --disable-lpar %endif +%if %{with_lua} +%define _with_lua --enable-lua +%else +%define _with_lua --disable-lua +%endif + %if %{with_lvm} %define _with_lvm --enable-lvm %else @@ -1387,6 +1438,7 @@ Collectd utilities %if %{with_python} %if 0%{?rhel} && 0%{?rhel} < 6 %define _with_python --enable-python --with-python=%{_bindir}/python2.6 +%define _python_config PYTHON_CONFIG="%{_bindir}/python2.6-config" %else %define _with_python --enable-python %endif @@ -1665,6 +1717,7 @@ Collectd utilities %endif %configure CFLAGS="%{optflags} -DLT_LAZY_OR_NOW=\"RTLD_LAZY|RTLD_GLOBAL\"" \ + %{?_python_config} \ --disable-static \ --without-included-ltdl \ --enable-all-plugins=yes \ @@ -1694,6 +1747,7 @@ Collectd utilities %{?_with_conntrack} \ %{?_with_contextswitch} \ %{?_with_cpufreq} \ + %{?_with_cpusleep} \ %{?_with_cpu} \ %{?_with_csv} \ %{?_with_curl_json} \ @@ -1712,8 +1766,10 @@ Collectd utilities %{?_with_filecount} \ %{?_with_fscache} \ %{?_with_gmond} \ + %{?_with_gps} \ %{?_with_grpc} \ %{?_with_hddtemp} \ + %{?_with_hugepages} \ %{?_with_interface} \ %{?_with_ipc} \ %{?_with_ipmi} \ @@ -1725,6 +1781,7 @@ Collectd utilities %{?_with_log_logstash} \ %{?_with_logfile} \ %{?_with_lpar} \ + %{?_with_lua} \ %{?_with_lvm} \ %{?_with_madwifi} \ %{?_with_mbmon} \ @@ -1851,6 +1908,10 @@ rm -f %{buildroot}%{_datadir}/collectd/java/generic-jmx.jar rm -f %{buildroot}%{_mandir}/man5/collectd-java.5* %endif +%if ! %{with_lua} +rm -f %{buildroot}%{_mandir}/man5/collectd-lua.5* +%endif + %if ! %{with_perl} rm -f %{buildroot}%{_mandir}/man5/collectd-perl.5* rm -f %{buildroot}%{_mandir}/man3/Collectd::Unixsock.3pm* @@ -1962,6 +2023,9 @@ fi %if %{with_cpufreq} %{_libdir}/%{name}/cpufreq.so %endif +%if %{with_cpusleep} +%{_libdir}/%{name}/cpusleep.so +%endif %if %{with_csv} %{_libdir}/%{name}/csv.so %endif @@ -1989,6 +2053,9 @@ fi %if %{with_fscache} %{_libdir}/%{name}/fscache.so %endif +%if %{with_hugepages} +%{_libdir}/%{name}/hugepages.so +%endif %if %{with_interface} %{_libdir}/%{name}/interface.so %endif @@ -2233,6 +2300,11 @@ fi %{_libdir}/%{name}/gmond.so %endif +%if %{with_gps} +%files gps +%{_libdir}/%{name}/gps.so +%endif + %if %{with_grpc} %files grpc %{_libdir}/%{name}/grpc.so @@ -2271,6 +2343,12 @@ fi %{_libdir}/%{name}/log_logstash.so %endif +%if %{with_lua} +%files lua +%{_mandir}/man5/collectd-lua* +%{_libdir}/%{name}/lua.so +%endif + %if %{with_lvm} %files lvm %{_libdir}/%{name}/lvm.so @@ -2445,6 +2523,15 @@ fi %doc contrib/ %changelog +* Tue Aug 23 2016 Marc Fournier - 5.7.0-1 +- New PRE-RELEASE version +- New plugins enabled by default: hugepages + +* Sun Aug 14 2016 Ruben Kerkhof - 5.6.0-1 +- New PRE-RELEASE version +- New plugins enabled by default: chrony, cpusleep, gps, lua, mqtt, notify_nagios +- New plugins disabled by default: grpc, xencpu, zone + * Tue Jul 26 2016 Ruben Kerkhof - 5.5.2-1 - New upstream version - Contains fix for CVE-2016-6254 @@ -2452,8 +2539,6 @@ fi * Sat Jun 04 2016 Ruben Kerkhof 5.5.1-1 - New upstream version -- New plugins enabled by default: chrony, mqtt, notify_nagios -- New plugins disabled by default: grpc, zone, xencpu * Wed May 27 2015 Marc Fournier 5.5.0-1 - New upstream version diff --git a/proto/collectd.proto b/proto/collectd.proto index 608fcbb1..614d1bd0 100644 --- a/proto/collectd.proto +++ b/proto/collectd.proto @@ -25,36 +25,38 @@ syntax = "proto3"; package collectd; +option go_package = "collectd.org/rpc/proto"; import "types.proto"; -import "google/protobuf/timestamp.proto"; service Collectd { - // Dispatch collected values to collectd. - rpc DispatchValues(DispatchValuesRequest) returns (DispatchValuesReply); - - // Query a list of values available from collectd's value cache. - rpc QueryValues(QueryValuesRequest) returns (QueryValuesReply); + // PutValues reads the value lists from the PutValuesRequest stream. + // The gRPC server embedded into collectd will inject them into the system + // just like the network plugin. + rpc PutValues(stream PutValuesRequest) + returns (PutValuesResponse); + + // QueryValues returns a stream of matching value lists from collectd's + // internal cache. + rpc QueryValues(QueryValuesRequest) returns (stream QueryValuesResponse); } -// The arguments to DispatchValues. -message DispatchValuesRequest { - collectd.types.ValueList values = 1; +// The arguments to PutValues. +message PutValuesRequest { + // value_list is the metric to be sent to the server. + collectd.types.ValueList value_list = 1; } -// The response from DispatchValues. -message DispatchValuesReply { -} +// The response from PutValues. +message PutValuesResponse {} // The arguments to QueryValues. message QueryValuesRequest { - // Query by the fields of the identifier. Only return values matching the - // specified shell wildcard patterns (see fnmatch(3)). Use '*' to match - // any value. - collectd.types.Identifier identifier = 1; + // Query by the fields of the identifier. Only return values matching the + // specified shell wildcard patterns (see fnmatch(3)). Use '*' to match + // any value. + collectd.types.Identifier identifier = 1; } // The response from QueryValues. -message QueryValuesReply { - repeated collectd.types.ValueList values = 1; -} +message QueryValuesResponse { collectd.types.ValueList value_list = 1; } diff --git a/proto/types.proto b/proto/types.proto index 4a852e42..952c5418 100644 --- a/proto/types.proto +++ b/proto/types.proto @@ -25,32 +25,35 @@ syntax = "proto3"; package collectd.types; +option go_package = "collectd.org/rpc/proto/types"; import "google/protobuf/duration.proto"; import "google/protobuf/timestamp.proto"; message Identifier { - string host = 1; - string plugin = 2; - string plugin_instance = 3; - string type = 4; - string type_instance = 5; + string host = 1; + string plugin = 2; + string plugin_instance = 3; + string type = 4; + string type_instance = 5; } message Value { - oneof value { - uint64 counter = 1; - double gauge = 2; - int64 derive = 3; - uint64 absolute = 4; - }; + oneof value { + uint64 counter = 1; + double gauge = 2; + int64 derive = 3; + uint64 absolute = 4; + }; } message ValueList { - repeated Value value = 1; + repeated Value values = 1; - google.protobuf.Timestamp time = 2; - google.protobuf.Duration interval = 3; + google.protobuf.Timestamp time = 2; + google.protobuf.Duration interval = 3; - Identifier identifier = 4; + Identifier identifier = 4; + + repeated string ds_names = 5; } diff --git a/src/Makefile.am b/src/Makefile.am index 1b56c11f..99a7c024 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -27,6 +27,21 @@ noinst_LTLIBRARIES = check_PROGRAMS = TESTS = +noinst_LTLIBRARIES += libformat_json.la +libformat_json_la_SOURCES = utils_format_json.c utils_format_json.h +libformat_json_la_CPPFLAGS = $(AM_CPPFLAGS) +libformat_json_la_LDFLAGS = $(AM_LDFLAGS) +libformat_json_la_LIBADD = +if BUILD_WITH_LIBYAJL +libformat_json_la_CPPFLAGS += $(BUILD_WITH_LIBYAJL_CPPFLAGS) +libformat_json_la_LDFLAGS += $(BUILD_WITH_LIBYAJL_LDFLAGS) +libformat_json_la_LIBADD += $(BUILD_WITH_LIBYAJL_LIBS) +check_PROGRAMS += test_format_json +TESTS += test_format_json +test_format_json_SOURCES = utils_format_json_test.c testing.h +test_format_json_LDADD = libformat_json.la daemon/libmetadata.la daemon/libplugin_mock.la -lm +endif + noinst_LTLIBRARIES += liblatency.la liblatency_la_SOURCES = utils_latency.c utils_latency.h check_PROGRAMS += test_utils_latency @@ -141,11 +156,10 @@ pkglib_LTLIBRARIES += amqp.la amqp_la_SOURCES = amqp.c \ utils_cmd_putval.c utils_cmd_putval.h \ utils_parse_option.c utils_parse_option.h \ - utils_format_graphite.c utils_format_graphite.h \ - utils_format_json.c utils_format_json.h + utils_format_graphite.c utils_format_graphite.h amqp_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_LIBRABBITMQ_LDFLAGS) amqp_la_CPPFLAGS = $(AM_CPPFLAGS) $(BUILD_WITH_LIBRABBITMQ_CPPFLAGS) -amqp_la_LIBADD = $(BUILD_WITH_LIBRABBITMQ_LIBS) +amqp_la_LIBADD = $(BUILD_WITH_LIBRABBITMQ_LIBS) libformat_json.la endif if BUILD_PLUGIN_APACHE @@ -156,6 +170,7 @@ apache_la_CFLAGS = $(AM_CFLAGS) $(BUILD_WITH_LIBCURL_CFLAGS) apache_la_LIBADD = $(BUILD_WITH_LIBCURL_LIBS) endif + if BUILD_PLUGIN_APCUPS pkglib_LTLIBRARIES += apcups.la apcups_la_SOURCES = apcups.c @@ -198,7 +213,7 @@ endif if BUILD_PLUGIN_BATTERY pkglib_LTLIBRARIES += battery.la -battery_la_SOURCES = battery.c +battery_la_SOURCES = battery.c battery_statefs.c battery_la_LDFLAGS = $(PLUGIN_LDFLAGS) if BUILD_WITH_LIBIOKIT battery_la_LDFLAGS += -framework IOKit @@ -279,6 +294,12 @@ cpufreq_la_SOURCES = cpufreq.c cpufreq_la_LDFLAGS = $(PLUGIN_LDFLAGS) endif +if BUILD_PLUGIN_CPUSLEEP +pkglib_LTLIBRARIES += cpusleep.la +cpusleep_la_SOURCES = cpusleep.c +cpusleep_la_LDFLAGS = $(PLUGIN_LDFLAGS) +endif + if BUILD_PLUGIN_CSV pkglib_LTLIBRARIES += csv.la csv_la_SOURCES = csv.c @@ -430,14 +451,21 @@ gmond_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(GANGLIA_LDFLAGS) gmond_la_LIBADD = $(GANGLIA_LIBS) endif +if BUILD_PLUGIN_GPS +pkglib_LTLIBRARIES += gps.la +gps_la_SOURCES = gps.c +gps_la_CFLAGS = $(AM_CFLAGS) $(BUILD_WITH_LIBGPS_CFLAGS) +gps_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_LIBGPS_LDFLAGS) +gps_la_LIBADD = -lpthread $(BUILD_WITH_LIBGPS_LIBS) +endif + if BUILD_PLUGIN_GRPC pkglib_LTLIBRARIES += grpc.la grpc_la_SOURCES = grpc.cc nodist_grpc_la_SOURCES = collectd.grpc.pb.cc collectd.pb.cc types.pb.cc -grpc_la_CPPFLAGS = $(AM_CPPFLAGS) -std=c++11 -grpc_la_CXXFLAGS = $(AM_CXXFLAGS) -std=c++11 -grpc_la_LDFLAGS = $(PLUGIN_LDFLAGS) -grpc_la_LIBADD = -lgrpc++ -lgrpc -lgpr -lprotobuf +grpc_la_CPPFLAGS = $(AM_CPPFLAGS) $(BUILD_WITH_LIBGRPCPP_CPPFLAGS) $(BUILD_WITH_LIBPROTOBUF_CPPFLAGS) +grpc_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_LIBGRPCPP_LDFLAGS) $(BUILD_WITH_LIBPROTOBUF_LDFLAGS) +grpc_la_LIBADD = $(BUILD_WITH_LIBGRPCPP_LIBS) $(BUILD_WITH_LIBPROTOBUF_LIBS) endif if BUILD_PLUGIN_HDDTEMP @@ -450,6 +478,12 @@ hddtemp_la_LIBADD += -lsocket endif endif +if BUILD_PLUGIN_HUGEPAGES +pkglib_LTLIBRARIES += hugepages.la +hugepages_la_SOURCES = hugepages.c +hugepages_la_LDFLAGS = $(PLUGIN_LDFLAGS) +endif + if BUILD_PLUGIN_INTERFACE pkglib_LTLIBRARIES += interface.la interface_la_SOURCES = interface.c @@ -555,6 +589,15 @@ lpar_la_LDFLAGS = $(PLUGIN_LDFLAGS) lpar_la_LIBADD = -lperfstat endif +if BUILD_PLUGIN_LUA +pkglib_LTLIBRARIES += lua.la +lua_la_SOURCES = lua.c \ + utils_lua.c utils_lua.h +lua_la_CFLAGS = $(AM_CFLAGS) $(BUILD_WITH_LIBLUA_CFLAGS) +lua_la_LDFLAGS = $(PLUGIN_LDFLAGS) +lua_la_LIBADD = $(BUILD_WITH_LIBLUA_LIBS) +endif + if BUILD_PLUGIN_LVM pkglib_LTLIBRARIES += lvm.la lvm_la_SOURCES = lvm.c @@ -837,6 +880,10 @@ perl_la_SOURCES = perl.c # Despite C99 providing the "bool" type thru stdbool.h, Perl defines its own # version of that type if HAS_BOOL is not defined... *sigh* perl_la_CPPFLAGS = $(AM_CPPFLAGS) -DHAS_BOOL=1 +# Despite off_t being 64 bit wide on 64 bit platforms, Perl insist on using +# off64_t which is only exposed when _LARGEFILE64_SOURCE is defined... *sigh* +# On older platforms we also need _REENTRANT. _GNU_SOURCE sets both of these. +perl_la_CPPFLAGS += -D_GNU_SOURCE perl_la_CFLAGS = $(AM_CFLAGS) \ $(PERL_CFLAGS) \ -DXS_VERSION=\"$(VERSION)\" -DVERSION=\"$(VERSION)\" @@ -860,8 +907,9 @@ if BUILD_PLUGIN_PINBA pkglib_LTLIBRARIES += pinba.la pinba_la_SOURCES = pinba.c nodist_pinba_la_SOURCES = pinba.pb-c.c pinba.pb-c.h -pinba_la_LDFLAGS = $(PLUGIN_LDFLAGS) -pinba_la_LIBADD = -lprotobuf-c +pinba_la_CPPFLAGS = $(AM_CPPFLAGS) $(BUILD_WITH_LIBPROTOBUF_C_CPPFLAGS) +pinba_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_LIBPROTOBUF_C_LDFLAGS) +pinba_la_LIBADD = $(BUILD_WITH_LIBPROTOBUF_C_LIBS) endif if BUILD_PLUGIN_PING @@ -891,13 +939,11 @@ endif if BUILD_PLUGIN_PYTHON pkglib_LTLIBRARIES += python.la python_la_SOURCES = python.c pyconfig.c pyvalues.c cpython.h -python_la_CPPFLAGS = $(AM_CPPFLAGS) $(BUILD_WITH_PYTHON_CPPFLAGS) -python_la_CFLAGS = $(AM_CFLAGS) +python_la_CPPFLAGS = $(AM_CPPFLAGS) $(LIBPYTHON_CPPFLAGS) if COMPILER_IS_GCC -python_la_CFLAGS += -fno-strict-aliasing -Wno-strict-aliasing +python_la_CPPFLAGS += -fno-strict-aliasing -Wno-strict-aliasing endif -python_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_PYTHON_LDFLAGS) -python_la_LIBADD = $(BUILD_WITH_PYTHON_LIBS) +python_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(LIBPYTHON_LDFLAGS) endif if BUILD_PLUGIN_PROCESSES @@ -965,9 +1011,9 @@ endif if BUILD_PLUGIN_SIGROK pkglib_LTLIBRARIES += sigrok.la sigrok_la_SOURCES = sigrok.c -sigrok_la_CFLAGS = $(AM_CFLAGS) $(BUILD_WITH_LIBSIGROK_CFLAGS) -sigrok_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_LIBSIGROK_LDFLAGS) -sigrok_la_LIBADD = -lsigrok +sigrok_la_CFLAGS = $(AM_CFLAGS) $(LIBSIGROK_CFLAGS) +sigrok_la_LDFLAGS = $(PLUGIN_LDFLAGS) +sigrok_la_LIBADD = $(LIBSIGROK_LIBS) endif if BUILD_PLUGIN_SMART @@ -983,13 +1029,9 @@ endif if BUILD_PLUGIN_SNMP pkglib_LTLIBRARIES += snmp.la snmp_la_SOURCES = snmp.c -snmp_la_LDFLAGS = $(PLUGIN_LDFLAGS) -snmp_la_CFLAGS = $(AM_CFLAGS) -snmp_la_LIBADD = -if BUILD_WITH_LIBNETSNMP -snmp_la_CFLAGS += $(BUILD_WITH_LIBSNMP_CFLAGS) -snmp_la_LIBADD += $(BUILD_WITH_LIBSNMP_LIBS) -endif +snmp_la_CPPFLAGS = $(AM_CPPFLAGS) $(BUILD_WITH_LIBNETSNMP_CPPFLAGS) +snmp_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_LIBNETSNMP_LDFLAGS) +snmp_la_LIBADD = $(BUILD_WITH_LIBNETSNMP_LIBS) endif if BUILD_PLUGIN_STATSD @@ -1221,31 +1263,29 @@ endif if BUILD_PLUGIN_WRITE_GRAPHITE pkglib_LTLIBRARIES += write_graphite.la write_graphite_la_SOURCES = write_graphite.c \ - utils_format_graphite.c utils_format_graphite.h \ - utils_format_json.c utils_format_json.h + utils_format_graphite.c utils_format_graphite.h write_graphite_la_LDFLAGS = $(PLUGIN_LDFLAGS) +write_graphite_la_LIBADD = libformat_json.la endif if BUILD_PLUGIN_WRITE_HTTP pkglib_LTLIBRARIES += write_http.la write_http_la_SOURCES = write_http.c \ - utils_format_json.c utils_format_json.h \ utils_format_kairosdb.c utils_format_kairosdb.h -write_http_la_CFLAGS = $(AM_CFLAGS) $(BUILD_WITH_LIBCURL_CFLAGS) write_http_la_LDFLAGS = $(PLUGIN_LDFLAGS) -write_http_la_LIBADD = $(BUILD_WITH_LIBCURL_LIBS) +write_http_la_CFLAGS = $(AM_CFLAGS) $(BUILD_WITH_LIBCURL_CFLAGS) +write_http_la_LIBADD = $(BUILD_WITH_LIBCURL_LIBS) libformat_json.la endif if BUILD_PLUGIN_WRITE_KAFKA pkglib_LTLIBRARIES += write_kafka.la write_kafka_la_SOURCES = write_kafka.c \ utils_format_graphite.c utils_format_graphite.h \ - utils_format_json.c utils_format_json.h \ utils_cmd_putval.c utils_cmd_putval.h \ utils_crc32.c utils_crc32.h write_kafka_la_CPPFLAGS = $(AM_CPPFLAGS) $(BUILD_WITH_LIBRDKAFKA_CPPFLAGS) write_kafka_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_LIBRDKAFKA_LDFLAGS) -write_kafka_la_LIBADD = $(BUILD_WITH_LIBRDKAFKA_LIBS) +write_kafka_la_LIBADD = $(BUILD_WITH_LIBRDKAFKA_LIBS) libformat_json.la endif if BUILD_PLUGIN_WRITE_LOG @@ -1253,6 +1293,7 @@ pkglib_LTLIBRARIES += write_log.la write_log_la_SOURCES = write_log.c \ utils_format_graphite.c utils_format_graphite.h write_log_la_LDFLAGS = $(PLUGIN_LDFLAGS) +write_log_la_LIBADD = libformat_json.la endif if BUILD_PLUGIN_WRITE_MONGODB @@ -1338,6 +1379,7 @@ dist_man_MANS = collectd.1 \ collectd-exec.5 \ collectdctl.1 \ collectd-java.5 \ + collectd-lua.5 \ collectdmon.1 \ collectd-nagios.1 \ collectd-perl.5 \ @@ -1353,6 +1395,7 @@ EXTRA_DIST = collectd.conf.pod \ collectd-exec.pod \ collectdctl.pod \ collectd-java.pod \ + collectd-lua.pod \ collectdmon.pod \ collectd-nagios.pod \ collectd-perl.pod \ @@ -1400,7 +1443,7 @@ CLEANFILES += pinba.pb-c.c pinba.pb-c.h BUILT_SOURCES += pinba.pb-c.c pinba.pb-c.h pinba.pb-c.c pinba.pb-c.h: pinba.proto - $(AM_V_PROTOC_C)protoc-c -I$(srcdir) --c_out . $(srcdir)/pinba.proto + $(AM_V_PROTOC_C)$(PROTOC_C) -I$(srcdir) --c_out . $(srcdir)/pinba.proto endif install-exec-hook: diff --git a/src/aggregation.c b/src/aggregation.c index c4c1627a..2744c89e 100644 --- a/src/aggregation.c +++ b/src/aggregation.c @@ -28,7 +28,6 @@ #include "plugin.h" #include "common.h" -#include "configfile.h" #include "meta_data.h" #include "utils_cache.h" /* for uc_get_rate() */ #include "utils_subst.h" @@ -346,7 +345,6 @@ static int agg_instance_read_func (agg_instance_t *inst, /* {{{ */ else sstrncpy (vl->plugin_instance, func, sizeof (vl->plugin_instance)); - memset (&v, 0, sizeof (v)); status = rate_to_value (&v, rate, state, inst->ds_type, t); if (status != 0) { @@ -484,9 +482,7 @@ static void agg_lookup_free_obj_callback (void *user_obj) /* {{{ */ static int agg_config_handle_group_by (oconfig_item_t const *ci, /* {{{ */ aggregation_t *agg) { - int i; - - for (i = 0; i < ci->values_num; i++) + for (int i = 0; i < ci->values_num; i++) { char const *value; @@ -522,7 +518,6 @@ static int agg_config_aggregation (oconfig_item_t *ci) /* {{{ */ aggregation_t *agg; _Bool is_valid; int status; - int i; agg = calloc (1, sizeof (*agg)); if (agg == NULL) @@ -539,7 +534,7 @@ static int agg_config_aggregation (oconfig_item_t *ci) /* {{{ */ sstrncpy (agg->ident.type_instance, "/.*/", sizeof (agg->ident.type_instance)); - for (i = 0; i < ci->children_num; i++) + for (int i = 0; i < ci->children_num; i++) { oconfig_item_t *child = ci->children + i; @@ -677,8 +672,6 @@ static int agg_config_aggregation (oconfig_item_t *ci) /* {{{ */ static int agg_config (oconfig_item_t *ci) /* {{{ */ { - int i; - pthread_mutex_lock (&agg_instance_list_lock); if (lookup == NULL) @@ -695,7 +688,7 @@ static int agg_config (oconfig_item_t *ci) /* {{{ */ } } - for (i = 0; i < ci->children_num; i++) + for (int i = 0; i < ci->children_num; i++) { oconfig_item_t *child = ci->children + i; @@ -713,7 +706,6 @@ static int agg_config (oconfig_item_t *ci) /* {{{ */ static int agg_read (void) /* {{{ */ { - agg_instance_t *this; cdtime_t t; int success; @@ -734,7 +726,7 @@ static int agg_read (void) /* {{{ */ return (0); } - for (this = agg_instance_list_head; this != NULL; this = this->next) + for (agg_instance_t *this = agg_instance_list_head; this != NULL; this = this->next) { int status; diff --git a/src/amqp.c b/src/amqp.c index 99dca901..06fd1f1d 100644 --- a/src/amqp.c +++ b/src/amqp.c @@ -27,6 +27,7 @@ **/ #include "collectd.h" + #include "common.h" #include "plugin.h" #include "utils_cmd_putval.h" @@ -527,13 +528,11 @@ static int camqp_connect (camqp_config_t *conf) /* {{{ */ static int camqp_shutdown (void) /* {{{ */ { - size_t i; - DEBUG ("amqp plugin: Shutting down %zu subscriber threads.", subscriber_threads_num); subscriber_threads_running = 0; - for (i = 0; i < subscriber_threads_num; i++) + for (size_t i = 0; i < subscriber_threads_num; i++) { /* FIXME: Sending a signal is not very elegant here. Maybe find out how * to use a timeout in the thread and check for the variable in regular @@ -763,17 +762,20 @@ static int camqp_subscribe_init (camqp_config_t *conf) /* {{{ */ static int camqp_write_locked (camqp_config_t *conf, /* {{{ */ const char *buffer, const char *routing_key) { - amqp_basic_properties_t props; int status; status = camqp_connect (conf); if (status != 0) return (status); - memset (&props, 0, sizeof (props)); - props._flags = AMQP_BASIC_CONTENT_TYPE_FLAG - | AMQP_BASIC_DELIVERY_MODE_FLAG - | AMQP_BASIC_APP_ID_FLAG; + amqp_basic_properties_t props = { + ._flags = AMQP_BASIC_CONTENT_TYPE_FLAG + | AMQP_BASIC_DELIVERY_MODE_FLAG + | AMQP_BASIC_APP_ID_FLAG, + .delivery_mode = conf->delivery_mode, + .app_id = amqp_cstring_bytes("collectd") + }; + if (conf->format == CAMQP_FORMAT_COMMAND) props.content_type = amqp_cstring_bytes("text/collectd"); else if (conf->format == CAMQP_FORMAT_JSON) @@ -782,8 +784,6 @@ static int camqp_write_locked (camqp_config_t *conf, /* {{{ */ props.content_type = amqp_cstring_bytes("text/graphite"); else assert (23 == 42); - props.delivery_mode = conf->delivery_mode; - props.app_id = amqp_cstring_bytes("collectd"); status = amqp_basic_publish(conf->connection, /* channel = */ 1, @@ -814,15 +814,12 @@ static int camqp_write (const data_set_t *ds, const value_list_t *vl, /* {{{ */ if ((ds == NULL) || (vl == NULL) || (conf == NULL)) return (EINVAL); - memset (buffer, 0, sizeof (buffer)); - if (conf->routing_key != NULL) { sstrncpy (routing_key, conf->routing_key, sizeof (routing_key)); } else { - size_t i; ssnprintf (routing_key, sizeof (routing_key), "collectd/%s/%s/%s/%s/%s", vl->host, vl->plugin, vl->plugin_instance, @@ -830,7 +827,7 @@ static int camqp_write (const data_set_t *ds, const value_list_t *vl, /* {{{ */ /* Switch slashes (the only character forbidden by collectd) and dots * (the separation character used by AMQP). */ - for (i = 0; routing_key[i] != 0; i++) + for (size_t i = 0; routing_key[i] != 0; i++) { if (routing_key[i] == '.') routing_key[i] = '/'; @@ -920,7 +917,6 @@ static int camqp_config_connection (oconfig_item_t *ci, /* {{{ */ { camqp_config_t *conf; int status; - int i; conf = calloc (1, sizeof (*conf)); if (conf == NULL) @@ -967,7 +963,7 @@ static int camqp_config_connection (oconfig_item_t *ci, /* {{{ */ return (status); } - for (i = 0; i < ci->children_num; i++) + for (int i = 0; i < ci->children_num; i++) { oconfig_item_t *child = ci->children + i; @@ -1074,11 +1070,13 @@ static int camqp_config_connection (oconfig_item_t *ci, /* {{{ */ if (publish) { char cbname[128]; - user_data_t ud = { conf, camqp_config_free }; - ssnprintf (cbname, sizeof (cbname), "amqp/%s", conf->name); - status = plugin_register_write (cbname, camqp_write, &ud); + status = plugin_register_write (cbname, camqp_write, + &(user_data_t) { + .data = conf, + .free_func = camqp_config_free, + }); if (status != 0) { camqp_config_free (conf); @@ -1100,9 +1098,7 @@ static int camqp_config_connection (oconfig_item_t *ci, /* {{{ */ static int camqp_config (oconfig_item_t *ci) /* {{{ */ { - int i; - - for (i = 0; i < ci->children_num; i++) + for (int i = 0; i < ci->children_num; i++) { oconfig_item_t *child = ci->children + i; diff --git a/src/apache.c b/src/apache.c index 40d0efe2..578b8dee 100644 --- a/src/apache.c +++ b/src/apache.c @@ -25,9 +25,9 @@ **/ #include "collectd.h" + #include "common.h" #include "plugin.h" -#include "configfile.h" #include @@ -174,7 +174,6 @@ static size_t apache_header_callback (void *buf, size_t size, size_t nmemb, static int config_add (oconfig_item_t *ci) { apache_t *st; - int i; int status; st = calloc (1, sizeof (*st)); @@ -194,7 +193,7 @@ static int config_add (oconfig_item_t *ci) } assert (st->name != NULL); - for (i = 0; i < ci->children_num; i++) + for (int i = 0; i < ci->children_num; i++) { oconfig_item_t *child = ci->children + i; @@ -240,24 +239,22 @@ static int config_add (oconfig_item_t *ci) if (status == 0) { - user_data_t ud; char callback_name[3*DATA_MAX_NAME_LEN]; - memset (&ud, 0, sizeof (ud)); - ud.data = st; - ud.free_func = apache_free; - - memset (callback_name, 0, sizeof (callback_name)); ssnprintf (callback_name, sizeof (callback_name), "apache/%s/%s", (st->host != NULL) ? st->host : hostname_g, - (st->name != NULL) ? st->name : "default"), + (st->name != NULL) ? st->name : "default"); status = plugin_register_complex_read (/* group = */ NULL, /* name = */ callback_name, /* callback = */ apache_read_host, /* interval = */ 0, - /* user_data = */ &ud); + &(user_data_t) { + .data = st, + .free_func = apache_free, + }); + } if (status != 0) @@ -272,9 +269,8 @@ static int config_add (oconfig_item_t *ci) static int config (oconfig_item_t *ci) { int status = 0; - int i; - for (i = 0; i < ci->children_num; i++) + for (int i = 0; i < ci->children_num; i++) { oconfig_item_t *child = ci->children + i; @@ -415,19 +411,15 @@ static void submit_value (const char *type, const char *type_instance, } /* void submit_value */ static void submit_derive (const char *type, const char *type_instance, - derive_t c, apache_t *st) + derive_t d, apache_t *st) { - value_t v; - v.derive = c; - submit_value (type, type_instance, v, st); + submit_value (type, type_instance, (value_t) { .derive = d }, st); } /* void submit_derive */ static void submit_gauge (const char *type, const char *type_instance, gauge_t g, apache_t *st) { - value_t v; - v.gauge = g; - submit_value (type, type_instance, v, st); + submit_value (type, type_instance, (value_t) { .gauge = g }, st); } /* void submit_gauge */ static void submit_scoreboard (char *buf, apache_t *st) @@ -465,8 +457,7 @@ static void submit_scoreboard (char *buf, apache_t *st) long long response_start = 0LL; long long response_end = 0LL; - int i; - for (i = 0; buf[i] != '\0'; i++) + for (int i = 0; buf[i] != '\0'; i++) { if (buf[i] == '.') open++; else if (buf[i] == '_') waiting++; diff --git a/src/apcups.c b/src/apcups.c index 9f7476bf..821bd65e 100644 --- a/src/apcups.c +++ b/src/apcups.c @@ -25,9 +25,9 @@ **/ #include "collectd.h" + #include "common.h" /* rrd_update_file */ #include "plugin.h" /* plugin_register, plugin_submit */ -#include "configfile.h" /* cf_register */ #if HAVE_SYS_TYPES_H # include @@ -115,15 +115,14 @@ static int net_open (char const *node, char const *service) { int sd; int status; - struct addrinfo ai_hints; struct addrinfo *ai_return; struct addrinfo *ai_list; - /* Resolve name */ - memset (&ai_hints, 0, sizeof (ai_hints)); /* TODO: Change this to `AF_UNSPEC' if apcupsd can handle IPv6 */ - ai_hints.ai_family = AF_INET; - ai_hints.ai_socktype = SOCK_STREAM; + struct addrinfo ai_hints = { + .ai_family = AF_INET, + .ai_socktype = SOCK_STREAM + }; status = getaddrinfo (node, service, &ai_hints, &ai_return); if (status != 0) @@ -381,10 +380,9 @@ static int apc_query_server (char const *node, char const *service, static int apcups_config (oconfig_item_t *ci) { - int i; _Bool persistent_conn_set = 0; - for (i = 0; i < ci->children_num; i++) + for (int i = 0; i < ci->children_num; i++) { oconfig_item_t *child = ci->children + i; @@ -418,12 +416,9 @@ static int apcups_config (oconfig_item_t *ci) static void apc_submit_generic (const char *type, const char *type_inst, double value) { - value_t values[1]; value_list_t vl = VALUE_LIST_INIT; - values[0].gauge = value; - - vl.values = values; + vl.values = &(value_t) { .gauge = value }; vl.values_len = 1; sstrncpy (vl.host, hostname_g, sizeof (vl.host)); sstrncpy (vl.plugin, "apcups", sizeof (vl.plugin)); diff --git a/src/apple_sensors.c b/src/apple_sensors.c index 7ed2016f..06ca7a85 100644 --- a/src/apple_sensors.c +++ b/src/apple_sensors.c @@ -25,6 +25,7 @@ **/ #include "collectd.h" + #include "common.h" #include "plugin.h" @@ -82,15 +83,9 @@ static int as_init (void) static void as_submit (const char *type, const char *type_instance, double val) { - value_t values[1]; value_list_t vl = VALUE_LIST_INIT; - DEBUG ("type = %s; type_instance = %s; val = %f;", - type, type_instance, val); - - values[0].gauge = val; - - vl.values = values; + vl.values = &(value_t) { .gauge = val }; vl.values_len = 1; sstrncpy (vl.host, hostname_g, sizeof (vl.host)); sstrncpy (vl.plugin, "apple_sensors", sizeof (vl.plugin)); @@ -113,8 +108,6 @@ static int as_read (void) char inst[128]; int value_int; double value_double; - int i; - if (!io_master_port || (io_master_port == MACH_PORT_NULL)) return (-1); @@ -169,7 +162,7 @@ static int as_read (void) kCFStringEncodingASCII)) continue; inst[sizeof (inst) - 1] = '\0'; - for (i = 0; i < 128; i++) + for (int i = 0; i < 128; i++) { if (inst[i] == '\0') break; diff --git a/src/aquaero.c b/src/aquaero.c index 5db988e6..08271f87 100644 --- a/src/aquaero.c +++ b/src/aquaero.c @@ -20,6 +20,7 @@ **/ #include "collectd.h" + #include "common.h" #include "plugin.h" @@ -33,9 +34,7 @@ static char *conf_device = NULL; static int aquaero_config (oconfig_item_t *ci) { - int i; - - for (i = 0; i < ci->children_num; i++) + for (int i = 0; i < ci->children_num; i++) { oconfig_item_t *child = ci->children + i; @@ -61,16 +60,13 @@ static void aquaero_submit (const char *type, const char *type_instance, double value) { const char *instance = conf_device?conf_device:"default"; - value_t values[1]; value_list_t vl = VALUE_LIST_INIT; /* Don't report undefined values. */ if (value == AQ5_FLOAT_UNDEF) return; - values[0].gauge = value; - - vl.values = values; + vl.values = &(value_t) { .gauge = value }; vl.values_len = 1; sstrncpy (vl.host, hostname_g, sizeof (vl.host)); @@ -87,9 +83,8 @@ static void aquaero_submit_array (const char *type, const char *type_instance_prefix, double *value_array, int len) { char type_instance[DATA_MAX_NAME_LEN]; - int i; - for (i = 0; i < len; i++) + for (int i = 0; i < len; i++) { if (value_array[i] == AQ5_FLOAT_UNDEF) continue; @@ -106,7 +101,6 @@ static int aquaero_read (void) aq5_settings_t aq_sett; char *err_msg = NULL; char type_instance[DATA_MAX_NAME_LEN]; - int i; if (libaquaero5_poll(conf_device, &aq_data, &err_msg) < 0) { @@ -147,7 +141,7 @@ static int aquaero_read (void) AQ5_NUM_OTHER_SENSORS); /* Fans */ - for (i = 0; i < AQ5_NUM_FAN; i++) + for (int i = 0; i < AQ5_NUM_FAN; i++) { if ((aq_sett.fan_data_source[i] == NONE) || (aq_data.fan_vrm_temp[i] != AQ5_FLOAT_UNDEF)) diff --git a/src/ascent.c b/src/ascent.c index 9124c26d..16568e6c 100644 --- a/src/ascent.c +++ b/src/ascent.c @@ -25,9 +25,9 @@ **/ #include "collectd.h" + #include "common.h" #include "plugin.h" -#include "configfile.h" #include #include @@ -126,12 +126,9 @@ static int config_keys_num = STATIC_ARRAY_SIZE (config_keys); static int ascent_submit_gauge (const char *plugin_instance, /* {{{ */ const char *type, const char *type_instance, gauge_t value) { - value_t values[1]; value_list_t vl = VALUE_LIST_INIT; - values[0].gauge = value; - - vl.values = values; + vl.values = &(value_t) { .gauge = value }; vl.values_len = 1; sstrncpy (vl.host, hostname_g, sizeof (vl.host)); sstrncpy (vl.plugin, "ascent", sizeof (vl.plugin)); @@ -181,20 +178,19 @@ static size_t ascent_curl_callback (void *buf, size_t size, size_t nmemb, /* {{{ static int ascent_submit_players (player_stats_t *ps) /* {{{ */ { - size_t i; gauge_t value; - for (i = 0; i < RACES_LIST_LENGTH; i++) + for (size_t i = 0; i < RACES_LIST_LENGTH; i++) if (races_list[i] != NULL) ascent_submit_gauge ("by-race", "players", races_list[i], (gauge_t) ps->races[i]); - for (i = 0; i < CLASSES_LIST_LENGTH; i++) + for (size_t i = 0; i < CLASSES_LIST_LENGTH; i++) if (classes_list[i] != NULL) ascent_submit_gauge ("by-class", "players", classes_list[i], (gauge_t) ps->classes[i]); - for (i = 0; i < GENDERS_LIST_LENGTH; i++) + for (size_t i = 0; i < GENDERS_LIST_LENGTH; i++) if (genders_list[i] != NULL) ascent_submit_gauge ("by-gender", "players", genders_list[i], (gauge_t) ps->genders[i]); @@ -328,9 +324,7 @@ static int ascent_xml_read_int (xmlDoc *doc, xmlNode *node, /* {{{ */ static int ascent_xml_sessions_plr (xmlDoc *doc, xmlNode *node, /* {{{ */ player_info_t *pi) { - xmlNode *child; - - for (child = node->xmlChildrenNode; child != NULL; child = child->next) + for (xmlNode *child = node->xmlChildrenNode; child != NULL; child = child->next) { if ((xmlStrcmp ((const xmlChar *) "comment", child->name) == 0) || (xmlStrcmp ((const xmlChar *) "text", child->name) == 0)) @@ -364,12 +358,11 @@ static int ascent_xml_sessions_plr (xmlDoc *doc, xmlNode *node, /* {{{ */ static int ascent_xml_sessions (xmlDoc *doc, xmlNode *node) /* {{{ */ { - xmlNode *child; - player_stats_t ps; + player_stats_t ps = { + .level_sum = 0 + }; - memset (&ps, 0, sizeof (ps)); - - for (child = node->xmlChildrenNode; child != NULL; child = child->next) + for (xmlNode *child = node->xmlChildrenNode; child != NULL; child = child->next) { if ((xmlStrcmp ((const xmlChar *) "comment", child->name) == 0) || (xmlStrcmp ((const xmlChar *) "text", child->name) == 0)) @@ -396,9 +389,7 @@ static int ascent_xml_sessions (xmlDoc *doc, xmlNode *node) /* {{{ */ static int ascent_xml_status (xmlDoc *doc, xmlNode *node) /* {{{ */ { - xmlNode *child; - - for (child = node->xmlChildrenNode; child != NULL; child = child->next) + for (xmlNode *child = node->xmlChildrenNode; child != NULL; child = child->next) { if ((xmlStrcmp ((const xmlChar *) "comment", child->name) == 0) || (xmlStrcmp ((const xmlChar *) "text", child->name) == 0)) @@ -438,7 +429,6 @@ static int ascent_xml (const char *data) /* {{{ */ { xmlDoc *doc; xmlNode *cur; - xmlNode *child; #if 0 doc = xmlParseMemory (data, strlen (data), @@ -469,7 +459,7 @@ static int ascent_xml (const char *data) /* {{{ */ return (-1); } - for (child = cur->xmlChildrenNode; child != NULL; child = child->next) + for (xmlNode *child = cur->xmlChildrenNode; child != NULL; child = child->next) { if ((xmlStrcmp ((const xmlChar *) "comment", child->name) == 0) || (xmlStrcmp ((const xmlChar *) "text", child->name) == 0)) diff --git a/src/barometer.c b/src/barometer.c index f14ac049..998932da 100644 --- a/src/barometer.c +++ b/src/barometer.c @@ -20,6 +20,7 @@ **/ #include "collectd.h" + #include "common.h" #include "utils_cache.h" #include "plugin.h" @@ -29,6 +30,7 @@ #include #include #include +#include /* ------------ MPL115 defines ------------ */ /* I2C address of the MPL115 sensor */ @@ -407,7 +409,6 @@ static int get_reference_temperature(double * result) gauge_t * values = NULL; /**< rate values */ size_t values_num = 0; /**< number of rate values */ - size_t i; gauge_t values_history[REF_TEMP_AVG_NUM]; @@ -445,7 +446,7 @@ static int get_reference_temperature(double * result) list->initialized = 1; list->num_values = values_num; - for(i=0; inum_values; ++i) + for(size_t i=0; inum_values; ++i) { DEBUG ("barometer: get_reference_temperature - history %zu: %lf", i, values_history[i]); @@ -499,7 +500,7 @@ static int get_reference_temperature(double * result) continue; } - for(i=0; ichildren_num; i++) + for (int i = 0; i < ci->children_num; i++) { oconfig_item_t *child = ci->children + i; @@ -812,6 +784,8 @@ static int battery_config (oconfig_item_t *ci) cf_util_get_boolean (child, &report_percent); else if (strcasecmp ("ReportDegraded", child->key) == 0) cf_util_get_boolean (child, &report_degraded); + else if (strcasecmp ("QueryStateFS", child->key) == 0) + cf_util_get_boolean (child, &query_statefs); else WARNING ("battery plugin: Ignoring unknown " "configuration option \"%s\".", diff --git a/src/battery_statefs.c b/src/battery_statefs.c new file mode 100644 index 00000000..03729fdb --- /dev/null +++ b/src/battery_statefs.c @@ -0,0 +1,119 @@ +/** + * collectd - src/statefs_battery.c + * Copyright (C) 2016 rinigus + * + * +The MIT License (MIT) + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + + * Authors: + * rinigus + + Battery stats are collected from StateFS Battery namespace. Reported + units are as follows: + + capacity % + charge % + current A + energy Wh + power W + temperature C + timefull and timelow seconds + voltage V + + Provider at + https://git.merproject.org/mer-core/statefs-providers/blob/master/src/power_udev/provider_power_udev.cpp + + **/ + +#include "collectd.h" +#include "common.h" +#include "plugin.h" + +#include + +#define STATEFS_ROOT "/run/state/namespaces/Battery/" + +static void battery_submit(const char *type, gauge_t value, + const char *type_instance) { + value_list_t vl = VALUE_LIST_INIT; + + vl.values = &(value_t) { .gauge = value }; + vl.values_len = 1; + sstrncpy(vl.host, hostname_g, sizeof(vl.host)); + sstrncpy(vl.plugin, "battery", sizeof(vl.plugin)); + /* statefs supports 1 battery at present */ + sstrncpy(vl.plugin_instance, "0", sizeof(vl.plugin_instance)); + sstrncpy(vl.type, type, sizeof(vl.type)); + if (type_instance != NULL) + sstrncpy(vl.type_instance, type_instance, sizeof(vl.type_instance)); + plugin_dispatch_values(&vl); +} + +/* cannot be static, is referred to from battery.c */ +int battery_read_statefs(void) { + value_t v; + int success = 0; + + if (parse_value_file(STATEFS_ROOT "ChargePercentage", &v, DS_TYPE_GAUGE) == 0) { + battery_submit("charge", v.gauge, NULL); + success++; + } else if (parse_value_file(STATEFS_ROOT "Capacity", &v, DS_TYPE_GAUGE) == 0) { + // Use capacity as a charge estimate if ChargePercentage is not available + battery_submit("charge", v.gauge, NULL); + success++; + } else { + WARNING("battery plugin: Neither \""STATEFS_ROOT"ChargePercentage\" " + "nor \""STATEFS_ROOT"Capacity\" could be read."); + } + + struct { + char *path; + char *type; + char *type_instance; + gauge_t factor; + } metrics[] = { + {STATEFS_ROOT "Current", "current", NULL, 1e-6}, // from uA to A + {STATEFS_ROOT "Energy", "energy_wh", NULL, 1e-6}, // from uWh to Wh + {STATEFS_ROOT "Power", "power", NULL, 1e-6}, // from uW to W + {STATEFS_ROOT "Temperature", "temperature", NULL, 0.1}, // from 10xC to C + {STATEFS_ROOT "TimeUntilFull", "duration", "full", 1.0}, + {STATEFS_ROOT "TimeUntilLow", "duration", "low", 1.0}, + {STATEFS_ROOT "Voltage", "voltage", NULL, 1e-6}, // from uV to V + }; + + for (size_t i = 0; i < STATIC_ARRAY_SIZE(metrics); i++) { + if (parse_value_file(metrics[i].path, &v, DS_TYPE_GAUGE) != 0) { + WARNING("battery plugin: Reading \"%s\" failed.", metrics[i].path); + continue; + } + + battery_submit(metrics[i].type, v.gauge * metrics[i].factor, metrics[i].type_instance); + success++; + } + + if (success == 0) { + ERROR("battery plugin: statefs backend: none of the statistics are available"); + return (-1); + } + + return (0); +} diff --git a/src/bind.c b/src/bind.c index 7d262086..09de4a3f 100644 --- a/src/bind.c +++ b/src/bind.c @@ -36,9 +36,9 @@ #endif /* STRPTIME_NEEDS_STANDARDS */ #include "collectd.h" + #include "common.h" #include "plugin.h" -#include "configfile.h" /* Some versions of libcurl don't include this themselves and then don't have * fd_set available. */ @@ -247,12 +247,9 @@ static int memsummary_translation_table_length = static void submit (time_t ts, const char *plugin_instance, /* {{{ */ const char *type, const char *type_instance, value_t value) { - value_t values[1]; value_list_t vl = VALUE_LIST_INIT; - values[0] = value; - - vl.values = values; + vl.values = &value; vl.values_len = 1; if (config_parse_time) vl.time = TIME_T_TO_CDTIME_T (ts); @@ -309,12 +306,11 @@ static int bind_xml_table_callback (const char *name, value_t value, /* {{{ */ time_t current_time, void *user_data) { translation_table_ptr_t *table = (translation_table_ptr_t *) user_data; - size_t i; if (table == NULL) return (-1); - for (i = 0; i < table->table_length; i++) + for (size_t i = 0; i < table->table_length; i++) { if (strcmp (table->table[i].xml_name, name) != 0) continue; @@ -417,7 +413,7 @@ static int bind_xml_read_timestamp (const char *xpath_expression, /* {{{ */ xmlNode *node; char *str_ptr; char *tmp; - struct tm tm; + struct tm tm = { 0 }; xpathObj = xmlXPathEvalExpression (BAD_CAST xpath_expression, xpathCtx); if (xpathObj == NULL) @@ -458,7 +454,6 @@ static int bind_xml_read_timestamp (const char *xpath_expression, /* {{{ */ return (-1); } - memset (&tm, 0, sizeof(tm)); tmp = strptime (str_ptr, "%Y-%m-%dT%T", &tm); xmlFree(str_ptr); if (tmp == NULL) @@ -491,7 +486,6 @@ static int bind_parse_generic_name_value (const char *xpath_expression, /* {{{ * { xmlXPathObject *xpathObj = NULL; int num_entries; - int i; xpathObj = xmlXPathEvalExpression(BAD_CAST xpath_expression, xpathCtx); if (xpathObj == NULL) @@ -503,19 +497,18 @@ static int bind_parse_generic_name_value (const char *xpath_expression, /* {{{ * num_entries = 0; /* Iterate over all matching nodes. */ - for (i = 0; xpathObj->nodesetval && (i < xpathObj->nodesetval->nodeNr); i++) + for (int i = 0; xpathObj->nodesetval && (i < xpathObj->nodesetval->nodeNr); i++) { xmlNode *name_node = NULL; xmlNode *counter = NULL; xmlNode *parent; - xmlNode *child; parent = xpathObj->nodesetval->nodeTab[i]; DEBUG ("bind plugin: bind_parse_generic_name_value: parent->name = %s;", (char *) parent->name); /* Iterate over all child nodes. */ - for (child = parent->xmlChildrenNode; + for (xmlNode *child = parent->xmlChildrenNode; child != NULL; child = child->next) { @@ -578,7 +571,6 @@ static int bind_parse_generic_value_list (const char *xpath_expression, /* {{{ * { xmlXPathObject *xpathObj = NULL; int num_entries; - int i; xpathObj = xmlXPathEvalExpression(BAD_CAST xpath_expression, xpathCtx); if (xpathObj == NULL) @@ -590,12 +582,10 @@ static int bind_parse_generic_value_list (const char *xpath_expression, /* {{{ * num_entries = 0; /* Iterate over all matching nodes. */ - for (i = 0; xpathObj->nodesetval && (i < xpathObj->nodesetval->nodeNr); i++) + for (int i = 0; xpathObj->nodesetval && (i < xpathObj->nodesetval->nodeNr); i++) { - xmlNode *child; - /* Iterate over all child nodes. */ - for (child = xpathObj->nodesetval->nodeTab[i]->xmlChildrenNode; + for (xmlNode *child = xpathObj->nodesetval->nodeTab[i]->xmlChildrenNode; child != NULL; child = child->next) { @@ -649,7 +639,6 @@ static int bind_parse_generic_name_attr_value_list (const char *xpath_expression { xmlXPathObject *xpathObj = NULL; int num_entries; - int i; xpathObj = xmlXPathEvalExpression(BAD_CAST xpath_expression, xpathCtx); if (xpathObj == NULL) @@ -661,12 +650,10 @@ static int bind_parse_generic_name_attr_value_list (const char *xpath_expression num_entries = 0; /* Iterate over all matching nodes. */ - for (i = 0; xpathObj->nodesetval && (i < xpathObj->nodesetval->nodeNr); i++) + for (int i = 0; xpathObj->nodesetval && (i < xpathObj->nodesetval->nodeNr); i++) { - xmlNode *child; - /* Iterate over all child nodes. */ - for (child = xpathObj->nodesetval->nodeTab[i]->xmlChildrenNode; + for (xmlNode *child = xpathObj->nodesetval->nodeTab[i]->xmlChildrenNode; child != NULL; child = child->next) { @@ -714,7 +701,6 @@ static int bind_xml_stats_handle_zone (int version, xmlDoc *doc, /* {{{ */ { xmlXPathObject *path_obj; char *zone_name = NULL; - int i; size_t j; if (version >= 3) @@ -738,7 +724,7 @@ static int bind_xml_stats_handle_zone (int version, xmlDoc *doc, /* {{{ */ return (-1); } - for (i = 0; path_obj->nodesetval && (i < path_obj->nodesetval->nodeNr); i++) + for (int i = 0; path_obj->nodesetval && (i < path_obj->nodesetval->nodeNr); i++) { zone_name = (char *) xmlNodeListGetString (doc, path_obj->nodesetval->nodeTab[i]->xmlChildrenNode, 1); @@ -817,7 +803,6 @@ static int bind_xml_stats_search_zones (int version, xmlDoc *doc, /* {{{ */ { xmlXPathObject *zone_nodes = NULL; xmlXPathContext *zone_path_context; - int i; zone_path_context = xmlXPathNewContext (doc); if (zone_path_context == NULL) @@ -834,7 +819,7 @@ static int bind_xml_stats_search_zones (int version, xmlDoc *doc, /* {{{ */ return (-1); } - for (i = 0; i < zone_nodes->nodesetval->nodeNr; i++) + for (int i = 0; i < zone_nodes->nodesetval->nodeNr; i++) { node = zone_nodes->nodesetval->nodeTab[i]; assert (node != NULL); @@ -855,7 +840,6 @@ static int bind_xml_stats_handle_view (int version, xmlDoc *doc, /* {{{ */ { char *view_name = NULL; cb_view_t *view; - int i; size_t j; if (version == 3) @@ -887,7 +871,7 @@ static int bind_xml_stats_handle_view (int version, xmlDoc *doc, /* {{{ */ return (-1); } - for (i = 0; path_obj->nodesetval && (i < path_obj->nodesetval->nodeNr); i++) + for (int i = 0; path_obj->nodesetval && (i < path_obj->nodesetval->nodeNr); i++) { view_name = (char *) xmlNodeListGetString (doc, path_obj->nodesetval->nodeTab[i]->xmlChildrenNode, 1); @@ -1010,7 +994,6 @@ static int bind_xml_stats_search_views (int version, xmlDoc *doc, /* {{{ */ { xmlXPathObject *view_nodes = NULL; xmlXPathContext *view_path_context; - int i; view_path_context = xmlXPathNewContext (doc); if (view_path_context == NULL) @@ -1027,7 +1010,7 @@ static int bind_xml_stats_search_views (int version, xmlDoc *doc, /* {{{ */ return (-1); } - for (i = 0; i < view_nodes->nodesetval->nodeNr; i++) + for (int i = 0; i < view_nodes->nodesetval->nodeNr; i++) { xmlNode *node; @@ -1441,7 +1424,6 @@ static int bind_xml (const char *data) /* {{{ */ xmlXPathContext *xpathCtx = NULL; xmlXPathObject *xpathObj = NULL; int ret = -1; - int i; doc = xmlParseMemory (data, strlen (data)); if (doc == NULL) @@ -1471,7 +1453,7 @@ static int bind_xml (const char *data) /* {{{ */ } else { - for (i = 0; i < xpathObj->nodesetval->nodeNr; i++) + for (int i = 0; i < xpathObj->nodesetval->nodeNr; i++) { xmlNode *node; char *attr_version; @@ -1533,7 +1515,7 @@ static int bind_xml (const char *data) /* {{{ */ return (-1); } - for (i = 0; i < xpathObj->nodesetval->nodeNr; i++) + for (int i = 0; i < xpathObj->nodesetval->nodeNr; i++) { xmlNode *node; char *attr_version; @@ -1636,7 +1618,6 @@ static int bind_config_add_view_zone (cb_view_t *view, /* {{{ */ static int bind_config_add_view (oconfig_item_t *ci) /* {{{ */ { cb_view_t *tmp; - int i; if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING)) { @@ -1668,7 +1649,7 @@ static int bind_config_add_view (oconfig_item_t *ci) /* {{{ */ return (-1); } - for (i = 0; i < ci->children_num; i++) + for (int i = 0; i < ci->children_num; i++) { oconfig_item_t *child = ci->children + i; @@ -1693,9 +1674,7 @@ static int bind_config_add_view (oconfig_item_t *ci) /* {{{ */ static int bind_config (oconfig_item_t *ci) /* {{{ */ { - int i; - - for (i = 0; i < ci->children_num; i++) + for (int i = 0; i < ci->children_num; i++) { oconfig_item_t *child = ci->children + i; diff --git a/src/ceph.c b/src/ceph.c index 04a39743..64d87855 100644 --- a/src/ceph.c +++ b/src/ceph.c @@ -27,6 +27,7 @@ #define _BSD_SOURCE #include "collectd.h" + #include "common.h" #include "plugin.h" @@ -37,6 +38,9 @@ #if HAVE_YAJL_YAJL_VERSION_H #include #endif +#ifdef HAVE_SYS_CAPABILITY_H +# include +#endif #include #include @@ -163,7 +167,7 @@ static int convert_special_metrics = 1; static struct ceph_daemon **g_daemons = NULL; /** Number of elements in g_daemons */ -static int g_num_daemons = 0; +static size_t g_num_daemons = 0; /** * A set of data that we build up in memory while parsing the JSON. @@ -258,7 +262,10 @@ static int ceph_cb_boolean(void *ctx, int bool_val) #define BUFFER_ADD(dest, src) do { \ size_t dest_size = sizeof (dest); \ - strncat ((dest), (src), dest_size - strlen (dest)); \ + size_t dest_len = strlen (dest); \ + if (dest_size > dest_len) { \ + sstrncpy ((dest) + dest_len, (src), dest_size - dest_len); \ + } \ (dest)[dest_size - 1] = 0; \ } while (0) @@ -267,16 +274,14 @@ ceph_cb_number(void *ctx, const char *number_val, yajl_len_t number_len) { yajl_struct *state = (yajl_struct*) ctx; char buffer[number_len+1]; - char key[2 * DATA_MAX_NAME_LEN]; + char key[2 * DATA_MAX_NAME_LEN] = { 0 }; _Bool latency_type = 0; - size_t i; int status; memcpy(buffer, number_val, number_len); - buffer[sizeof(buffer) - 1] = 0; + buffer[sizeof(buffer) - 1] = '\0'; - memset (key, 0, sizeof (key)); - for (i = 0; i < state->depth; i++) + for (size_t i = 0; i < state->depth; i++) { if (state->stack[i] == NULL) continue; @@ -292,6 +297,11 @@ ceph_cb_number(void *ctx, const char *number_val, yajl_len_t number_len) { latency_type = 1; + /* depth >= 2 => (stack[-1] != NULL && stack[-2] != NULL) */ + assert ((state->depth < 2) + || ((state->stack[state->depth - 1] != NULL) + && (state->stack[state->depth - 2] != NULL))); + /* Super-special case for filestore.journal_wr_bytes.avgcount: For * some reason, Ceph schema encodes this as a count/sum pair while all * other "Bytes" data (excluding used/capacity bytes for OSD space) uses @@ -422,8 +432,7 @@ static void ceph_daemon_print(const struct ceph_daemon *d) static void ceph_daemons_print(void) { - int i; - for(i = 0; i < g_num_daemons; ++i) + for(size_t i = 0; i < g_num_daemons; ++i) { ceph_daemon_print(g_daemons[i]); } @@ -431,15 +440,15 @@ static void ceph_daemons_print(void) static void ceph_daemon_free(struct ceph_daemon *d) { - int i = 0; - for(; i < d->last_idx; i++) + for(int i = 0; i < d->last_idx; i++) { sfree(d->last_poll_data[i]); } sfree(d->last_poll_data); d->last_poll_data = NULL; d->last_idx = 0; - for(i = 0; i < d->ds_num; i++) + + for(int i = 0; i < d->ds_num; i++) { sfree(d->ds_names[i]); } @@ -548,10 +557,9 @@ static _Bool has_suffix (char const *str, char const *suffix) /* count_parts returns the number of elements a "foo.bar.baz" style key has. */ static size_t count_parts (char const *key) { - char const *ptr; size_t parts_num = 0; - for (ptr = key; ptr != NULL; ptr = strchr (ptr + 1, '.')) + for (const char *ptr = key; ptr != NULL; ptr = strchr (ptr + 1, '.')) parts_num++; return parts_num; @@ -593,7 +601,6 @@ static int ceph_daemon_add_ds_entry(struct ceph_daemon *d, const char *name, { uint32_t type; char ds_name[DATA_MAX_NAME_LEN]; - memset(ds_name, 0, sizeof(ds_name)); if(convert_special_metrics) { @@ -684,10 +691,9 @@ static int cc_handle_bool(struct oconfig_item_s *item, int *dest) static int cc_add_daemon_config(oconfig_item_t *ci) { - int ret, i; - struct ceph_daemon *nd, cd; + int ret; + struct ceph_daemon *nd, cd = { 0 }; struct ceph_daemon **tmp; - memset(&cd, 0, sizeof(struct ceph_daemon)); if((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING)) { @@ -702,7 +708,7 @@ static int cc_add_daemon_config(oconfig_item_t *ci) return ret; } - for(i=0; i < ci->children_num; i++) + for(int i=0; i < ci->children_num; i++) { oconfig_item_t *child = ci->children + i; @@ -753,15 +759,16 @@ static int cc_add_daemon_config(oconfig_item_t *ci) return ENOMEM; } memcpy(nd, &cd, sizeof(*nd)); - g_daemons[g_num_daemons++] = nd; + g_daemons[g_num_daemons] = nd; + g_num_daemons++; return 0; } static int ceph_config(oconfig_item_t *ci) { - int ret, i; + int ret; - for(i = 0; i < ci->children_num; ++i) + for(int i = 0; i < ci->children_num; ++i) { oconfig_item_t *child = ci->children + i; if(strcasecmp("Daemon", child->key) == 0) @@ -898,8 +905,7 @@ static int update_last(struct ceph_daemon *d, const char *ds_n, int index, */ static int backup_search_for_last_avg(struct ceph_daemon *d, const char *ds_n) { - int i = 0; - for(; i < d->last_idx; i++) + for(int i = 0; i < d->last_idx; i++) { if(strcmp(d->last_poll_data[i]->ds_name, ds_n) == 0) { @@ -959,12 +965,11 @@ static double get_last_avg(struct ceph_daemon *d, const char *ds_n, int index, */ static uint32_t backup_search_for_type(struct ceph_daemon *d, char *ds_name) { - int idx = 0; - for(; idx < d->ds_num; idx++) + for(int i = 0; i < d->ds_num; i++) { - if(strcmp(d->ds_names[idx], ds_name) == 0) + if(strcmp(d->ds_names[i], ds_name) == 0) { - return d->ds_types[idx]; + return d->ds_types[i]; } } return DSET_TYPE_UNFOUND; @@ -983,7 +988,6 @@ static int node_handler_fetch_data(void *arg, const char *val, const char *key) int index = vtmp->index; char ds_name[DATA_MAX_NAME_LEN]; - memset(ds_name, 0, sizeof(ds_name)); if (parse_keys (ds_name, sizeof (ds_name), key)) { @@ -1086,7 +1090,7 @@ static int node_handler_fetch_data(void *arg, const char *val, const char *key) static int cconn_connect(struct cconn *io) { - struct sockaddr_un address; + struct sockaddr_un address = { 0 }; int flags, fd, err; if(io->state != CSTATE_UNCONNECTED) { @@ -1101,7 +1105,6 @@ static int cconn_connect(struct cconn *io) "failed: error %d", err); return err; } - memset(&address, 0, sizeof(struct sockaddr_un)); address.sun_family = AF_UNIX; snprintf(address.sun_path, sizeof(address.sun_path), "%s", io->d->asok_path); @@ -1461,19 +1464,26 @@ static int milli_diff(const struct timeval *t1, const struct timeval *t2) */ static int cconn_main_loop(uint32_t request_type) { - int i, ret, some_unreachable = 0; + int ret, some_unreachable = 0; struct timeval end_tv; struct cconn io_array[g_num_daemons]; - DEBUG("ceph plugin: entering cconn_main_loop(request_type = %d)", request_type); + DEBUG ("ceph plugin: entering cconn_main_loop(request_type = %"PRIu32")", request_type); + + if (g_num_daemons < 1) + { + ERROR ("ceph plugin: No daemons configured. See the \"Daemon\" config option."); + return ENOENT; + } /* create cconn array */ - memset(io_array, 0, sizeof(io_array)); - for(i = 0; i < g_num_daemons; ++i) + for (size_t i = 0; i < g_num_daemons; i++) { - io_array[i].d = g_daemons[i]; - io_array[i].request_type = request_type; - io_array[i].state = CSTATE_UNCONNECTED; + io_array[i] = (struct cconn) { + .d = g_daemons[i], + .request_type = request_type, + .state = CSTATE_UNCONNECTED, + }; } /** Calculate the time at which we should give up */ @@ -1488,13 +1498,13 @@ static int cconn_main_loop(uint32_t request_type) struct pollfd fds[g_num_daemons]; memset(fds, 0, sizeof(fds)); nfds = 0; - for(i = 0; i < g_num_daemons; ++i) + for(size_t i = 0; i < g_num_daemons; ++i) { struct cconn *io = io_array + i; ret = cconn_prepare(io, fds + nfds); if(ret < 0) { - WARNING("ceph plugin: cconn_prepare(name=%s,i=%d,st=%d)=%d", + WARNING("ceph plugin: cconn_prepare(name=%s,i=%zu,st=%d)=%d", io->d->name, i, io->state, ret); cconn_close(io); io->request_type = ASOK_REQ_NONE; @@ -1526,13 +1536,14 @@ static int cconn_main_loop(uint32_t request_type) ERROR("ceph plugin: poll(2) error: %d", ret); goto done; } - for(i = 0; i < nfds; ++i) + for(int i = 0; i < nfds; ++i) { struct cconn *io = polled_io_array[i]; int revents = fds[i].revents; if(revents == 0) { /* do nothing */ + continue; } else if(cconn_validate_revents(io, revents)) { @@ -1557,7 +1568,7 @@ static int cconn_main_loop(uint32_t request_type) } } } - done: for(i = 0; i < g_num_daemons; ++i) + done: for(size_t i = 0; i < g_num_daemons; ++i) { cconn_close(io_array + i); } @@ -1580,18 +1591,35 @@ static int ceph_read(void) /******* lifecycle *******/ static int ceph_init(void) { - int ret; +#if defined(HAVE_SYS_CAPABILITY_H) && defined(CAP_DAC_OVERRIDE) + if (check_capability (CAP_DAC_OVERRIDE) != 0) + { + if (getuid () == 0) + WARNING ("ceph plugin: Running collectd as root, but the " + "CAP_DAC_OVERRIDE capability is missing. The plugin's read " + "function will probably fail. Is your init system dropping " + "capabilities?"); + else + WARNING ("ceph plugin: collectd doesn't have the CAP_DAC_OVERRIDE " + "capability. If you don't want to run collectd as root, try running " + "\"setcap cap_dac_override=ep\" on the collectd binary."); + } +#endif + ceph_daemons_print(); - ret = cconn_main_loop(ASOK_REQ_VERSION); + if (g_num_daemons < 1) + { + ERROR ("ceph plugin: No daemons configured. See the \"Daemon\" config option."); + return ENOENT; + } - return (ret) ? ret : 0; + return cconn_main_loop(ASOK_REQ_VERSION); } static int ceph_shutdown(void) { - int i; - for(i = 0; i < g_num_daemons; ++i) + for(size_t i = 0; i < g_num_daemons; ++i) { ceph_daemon_free(g_daemons[i]); } diff --git a/src/ceph_test.c b/src/ceph_test.c index 199d40ec..91f084f7 100644 --- a/src/ceph_test.c +++ b/src/ceph_test.c @@ -169,7 +169,7 @@ DEF_TEST(parse_keys) for (i = 0; i < STATIC_ARRAY_SIZE (cases); i++) { - char got[DATA_MAX_NAME_LEN]; + char got[64]; CHECK_ZERO (parse_keys (got, sizeof (got), cases[i].str)); EXPECT_EQ_STR (cases[i].want, got); diff --git a/src/cgroups.c b/src/cgroups.c index 6d419722..f7c7e0d6 100644 --- a/src/cgroups.c +++ b/src/cgroups.c @@ -22,9 +22,9 @@ **/ #include "collectd.h" + #include "common.h" #include "plugin.h" -#include "configfile.h" #include "utils_mount.h" #include "utils_ignorelist.h" @@ -206,18 +206,16 @@ static int cgroups_config (const char *key, const char *value) static int cgroups_read (void) { - cu_mount_t *mnt_list; - cu_mount_t *mnt_ptr; + cu_mount_t *mnt_list = NULL; _Bool cgroup_found = 0; - mnt_list = NULL; if (cu_mount_getlist (&mnt_list) == NULL) { ERROR ("cgroups plugin: cu_mount_getlist failed."); return (-1); } - for (mnt_ptr = mnt_list; mnt_ptr != NULL; mnt_ptr = mnt_ptr->next) + for (cu_mount_t *mnt_ptr = mnt_list; mnt_ptr != NULL; mnt_ptr = mnt_ptr->next) { /* Find the cgroup mountpoint which contains the cpuacct * controller. */ diff --git a/src/chrony.c b/src/chrony.c index 012fd9a9..353ede79 100644 --- a/src/chrony.c +++ b/src/chrony.c @@ -26,6 +26,7 @@ */ #include "collectd.h" + #include "common.h" /* auxiliary functions */ #include "plugin.h" /* plugin_register_*, plugin_dispatch_values */ @@ -306,15 +307,15 @@ static int connect_client(const char *p_hostname, const char *p_service, int p_family, int p_socktype) { - struct addrinfo hints, *res = NULL, *ressave = NULL; + struct addrinfo *res, *ressave; int n, sockfd; - memset(&hints, 0, sizeof(struct addrinfo)); - - hints.ai_family = p_family; - hints.ai_socktype = p_socktype; + struct addrinfo ai_hints = { + .ai_family = p_family, + .ai_socktype = p_socktype + }; - n = getaddrinfo(p_hostname, p_service, &hints, &res); + n = getaddrinfo(p_hostname, p_service, &ai_hints, &res); if (n < 0) { @@ -451,8 +452,8 @@ chrony_connect(void) if (chrony_set_timeout()) { - ERROR(PLUGIN_NAME ": Error setting timeout to %lds. Errno = %d", - g_chrony_timeout, errno); + ERROR(PLUGIN_NAME ": Error setting timeout to %llds. Errno = %d", + (long long)g_chrony_timeout, errno); return CHRONY_RC_FAIL; } return CHRONY_RC_OK; @@ -676,12 +677,9 @@ ntohf(tFloat p_float) static void chrony_push_data(const char *p_type, const char *p_type_inst, double p_value) { - value_t values[1]; value_list_t vl = VALUE_LIST_INIT; - values[0].gauge = p_value; /* TODO: Check type??? (counter, gauge, derive, absolute) */ - - vl.values = values; + vl.values = &(value_t) { .gauge = p_value }; vl.values_len = 1; /* XXX: Shall g_chrony_host/g_chrony_port be reflected in the plugin's output? */ @@ -852,8 +850,7 @@ chrony_request_daemon_stats(void) } #if COLLECT_DEBUG { - char src_addr[IPV6_STR_MAX_SIZE]; - memset(src_addr, 0, sizeof(src_addr)); + char src_addr[IPV6_STR_MAX_SIZE] = { 0 }; niptoha(&chrony_resp.body.tracking.addr, src_addr, sizeof(src_addr)); DEBUG(PLUGIN_NAME ": Daemon stat: .addr = %s, .ref_id= %u, .stratum = %u, .leap_status = %u, .ref_time = %u:%u:%u, .current_correction = %f, .last_offset = %f, .rms_offset = %f, .freq_ppm = %f, .skew_ppm = %f, .root_delay = %f, .root_dispersion = %f, .last_update_interval = %f", src_addr, ntohs(chrony_resp.body.tracking.f_ref_id), ntohs(chrony_resp.body.tracking.f_stratum), @@ -937,8 +934,7 @@ chrony_request_source_data(int p_src_idx, int *p_is_reachable) tChrony_Request chrony_req; tChrony_Response chrony_resp; - char src_addr[IPV6_STR_MAX_SIZE]; - memset(src_addr, 0, sizeof(src_addr)); + char src_addr[IPV6_STR_MAX_SIZE] = { 0 }; chrony_init_req(&chrony_req); chrony_req.body.source_data.f_index = htonl(p_src_idx); @@ -997,8 +993,7 @@ chrony_request_source_stats(int p_src_idx, const int *p_is_reachable) tChrony_Response chrony_resp; double skew_ppm, frequency_error, time_offset; - char src_addr[IPV6_STR_MAX_SIZE]; - memset(src_addr, 0, sizeof(src_addr)); + char src_addr[IPV6_STR_MAX_SIZE] = { 0 }; if (*p_is_reachable == 0) { @@ -1055,7 +1050,7 @@ chrony_read(void) { /* collectd read callback: Perform data acquisition */ int rc; - unsigned int now_src, n_sources; + unsigned int n_sources; if (g_chrony_seq_is_initialized == 0) { @@ -1077,7 +1072,7 @@ chrony_read(void) if (rc != CHRONY_RC_OK) return rc; - for (now_src = 0; now_src < n_sources; ++now_src) + for (unsigned int now_src = 0; now_src < n_sources; ++now_src) { int is_reachable; rc = chrony_request_source_data(now_src, &is_reachable); diff --git a/src/collectd-lua.pod b/src/collectd-lua.pod new file mode 100644 index 00000000..7a256550 --- /dev/null +++ b/src/collectd-lua.pod @@ -0,0 +1,163 @@ +# Permission is hereby granted, free of charge, to any person obtaining a +# copy of this software and associated documentation files (the "Software"), +# to deal in the Software without restriction, including without limitation +# the rights to use, copy, modify, merge, publish, distribute, sublicense, +# and/or sell copies of the Software, and to permit persons to whom the +# Software is furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. + +=encoding UTF-8 + +=head1 NAME + +collectd-lua - Documentation of collectd's C + +=head1 SYNOPSIS + + LoadPlugin lua + # ... + + BasePath "/path/to/your/lua/scripts" + Script "script1.lua" + Script "script2.lua" + + +=head1 DESCRIPTION + +The C embeds a Lua interpreter into collectd and provides an +interface to collectd's plugin system. This makes it possible to write plugins +for collectd in Lua. This is a lot more efficient than executing a +Lua script every time you want to read a value with the C (see +L) and provides a lot more functionality, too. + +The minimum required Lua version is I<5.1>. + +=head1 CONFIGURATION + +=over 4 + +=item B I + +Loads the Lua plugin. + +=item B I + +The directory the C looks in to find script B