--- /dev/null
+---
+BasedOnStyle: LLVM
+IncludeCategories:
+ - Regex: '"collectd.h"'
+ - Priority: -1
--- /dev/null
+* 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
# lint stuff
*.ln
+#ide stuff
+.vscode
+
+# cscope stuff
+cscope.*
+
# Unit tests
src/daemon/test-suite.log
src/tests/
- Normalization in the CPU plugin.
- Relative values in the Load plugin.
-Ruben Kerkhof <ruben@rubenkerkhof.com>
+Ruben Kerkhof <ruben at rubenkerkhof.com>
- Bugfixes and enhancements in many places all around the project.
- - Fedora package.
+ - Fedora and EPEL packages.
Sebastian "tokkee" Harl <sh at tokkee.org>
- Bugfixes and enhancements in many places all around the project.
- - gprc plugin.
+ - grpc plugin.
- perl plugin.
- postgresql plugin.
- users plugin.
Jiri Tyr <jiri.tyr at gmail.com>
- fhcount plugin.
+Julien Ammous <j.ammous at gmail.com>
+ - Lua plugin.
+
Kevin Bowling <kbowling at llnw.com>
- write_tsdb plugin for http://opentsdb.net/
Mirko Buffoni <briareos at eswat.org>
- Port/Socket selection in the MySQL plugin.
+Nicolas Jourden <nicolas.jourden at laposte.net>
+ - gps plugin.
+
Niki W. Waibel <niki.waibel at newlogic.com>
- Initial autotools fixes.
- libltdl code.
-# 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)
+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.
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
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,
- 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.
- 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.
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).
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.
Used by the `network' plugin for encryption and authentication.
<http://www.gnupg.org/>
+ * libgps (optional)
+ Used by the `gps' plugin.
+ <http://developer.berlios.de/projects/gpsd/>
+
* libhal (optional)
If present, the `uuid' plugin will check for UUID from HAL.
<http://hal.freedesktop.org/>
Used by the `openldap' plugin.
<http://www.openldap.org/>
+ * liblua (optional)
+ Used by the `lua' plugin. Currently, Lua 5.1 and later are supported.
+ <https://www.lua.org/>
+
* liblvm2 (optional)
Used by the `lvm' plugin.
<ftp://sources.redhat.com/pub/lvm2/>
<http://code.google.com/p/protobuf-c/>
* 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.
<http://www.python.org/>
Sebastian tokkee Harl <sh at tokkee.org>,
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.
+++ /dev/null
-* 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/
key = attrName.remove (0);
- TabularData tabularData = (TabularData) parent;
- Collection<CompositeData> table =
- (Collection<CompositeData>)tabularData.values();
+ @SuppressWarnings("unchecked")
+ Collection<CompositeData> table = (Collection<CompositeData>) parent.values();
for (CompositeData compositeData : table)
{
if (key.equals(compositeData.get("key")))
my $type = shift;
my %plugins;
- my $interval;
our $cb_name = undef;
}
if (TYPE_LOG != $type) {
- DEBUG ("Collectd::plugin_call: type = \"$type\" ("
+ DEBUG ("Collectd::plugin_call_all: type = \"$type\" ("
. $types{$type} . "), args=\""
. join(', ', map { defined($_) ? $_ : '<undef>' } @_) . "\"");
}
if (! defined $plugins[$type]) {
- ERROR ("Collectd::plugin_call: unknown type \"$type\"");
+ ERROR ("Collectd::plugin_call_all: unknown type \"$type\"");
return;
}
%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;
}
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. "
}
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.");
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};
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)
#
# 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
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
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 (<google/protobuf-c/protobuf-c.h> 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
#include <linux/major.h>
#include <linux/types.h>
])
+ AC_CHECK_HEADERS([sys/sysmacros.h])
else
have_linux_raid_md_u_h="no"
fi
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)
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 <time.h>
+]],
+[[
+ 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"])
#
# 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
# }}}
+# --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"
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
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 (<grpc++/grpc++.h> 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++/grpc++.h>]],
+ [[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 {{{
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
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=""
# 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
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
# }}}
# --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"
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 {{{
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"
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"
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 (<google/protobuf/util/time_util.h> 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 (<protobuf-c.h> 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 <Python.h>]],
+ [[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=""
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 {{{
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" \
# 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
# 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
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
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])
[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)"])
plugin_contextswitch="no"
plugin_cpu="no"
plugin_cpufreq="no"
+plugin_cpusleep="no"
plugin_curl_json="no"
plugin_curl_xml="no"
plugin_df="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"
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"
plugin_entropy="yes"
plugin_fhcount="yes"
plugin_fscache="yes"
+ plugin_hugepages="yes"
plugin_interface="yes"
plugin_ipc="yes"
plugin_irq="yes"
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"
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"
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
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"
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])
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])
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])
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])
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"
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])
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])
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])
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])
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])
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])
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])
#endif /* ! HAVE_CONFIG */
#include <collectd/collectd.h>
+
#include <collectd/common.h>
#include <collectd/plugin.h>
} /* 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) */
/*
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"],
%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}
%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}
%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}
# 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
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 <collectd@verplant.org>
%if 0%{?fedora} || 0%{?rhel} >= 7
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
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
%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
%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
%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
%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
%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
%endif
%configure CFLAGS="%{optflags} -DLT_LAZY_OR_NOW=\"RTLD_LAZY|RTLD_GLOBAL\"" \
+ %{?_python_config} \
--disable-static \
--without-included-ltdl \
--enable-all-plugins=yes \
%{?_with_conntrack} \
%{?_with_contextswitch} \
%{?_with_cpufreq} \
+ %{?_with_cpusleep} \
%{?_with_cpu} \
%{?_with_csv} \
%{?_with_curl_json} \
%{?_with_filecount} \
%{?_with_fscache} \
%{?_with_gmond} \
+ %{?_with_gps} \
%{?_with_grpc} \
%{?_with_hddtemp} \
+ %{?_with_hugepages} \
%{?_with_interface} \
%{?_with_ipc} \
%{?_with_ipmi} \
%{?_with_log_logstash} \
%{?_with_logfile} \
%{?_with_lpar} \
+ %{?_with_lua} \
%{?_with_lvm} \
%{?_with_madwifi} \
%{?_with_mbmon} \
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*
%if %{with_cpufreq}
%{_libdir}/%{name}/cpufreq.so
%endif
+%if %{with_cpusleep}
+%{_libdir}/%{name}/cpusleep.so
+%endif
%if %{with_csv}
%{_libdir}/%{name}/csv.so
%endif
%if %{with_fscache}
%{_libdir}/%{name}/fscache.so
%endif
+%if %{with_hugepages}
+%{_libdir}/%{name}/hugepages.so
+%endif
%if %{with_interface}
%{_libdir}/%{name}/interface.so
%endif
%{_libdir}/%{name}/gmond.so
%endif
+%if %{with_gps}
+%files gps
+%{_libdir}/%{name}/gps.so
+%endif
+
%if %{with_grpc}
%files grpc
%{_libdir}/%{name}/grpc.so
%{_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
%doc contrib/
%changelog
+* Tue Aug 23 2016 Marc Fournier <marc.fournier@camptocamp.com> - 5.7.0-1
+- New PRE-RELEASE version
+- New plugins enabled by default: hugepages
+
+* Sun Aug 14 2016 Ruben Kerkhof <ruben@rubenkerkhof.com> - 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 <ruben@rubenkerkhof.com> - 5.5.2-1
- New upstream version
- Contains fix for CVE-2016-6254
* Sat Jun 04 2016 Ruben Kerkhof <ruben@rubenkerkhof.com> 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 <marc.fournier@camptocamp.com> 5.5.0-1
- New upstream version
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; }
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;
}
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
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
apache_la_LIBADD = $(BUILD_WITH_LIBCURL_LIBS)
endif
+
if BUILD_PLUGIN_APCUPS
pkglib_LTLIBRARIES += apcups.la
apcups_la_SOURCES = apcups.c
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
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
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
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
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
# 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)\"
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
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
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
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
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
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
collectd-exec.5 \
collectdctl.1 \
collectd-java.5 \
+ collectd-lua.5 \
collectdmon.1 \
collectd-nagios.1 \
collectd-perl.5 \
collectd-exec.pod \
collectdctl.pod \
collectd-java.pod \
+ collectd-lua.pod \
collectdmon.pod \
collectd-nagios.pod \
collectd-perl.pod \
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:
#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"
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)
{
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;
aggregation_t *agg;
_Bool is_valid;
int status;
- int i;
agg = calloc (1, sizeof (*agg));
if (agg == NULL)
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;
static int agg_config (oconfig_item_t *ci) /* {{{ */
{
- int i;
-
pthread_mutex_lock (&agg_instance_list_lock);
if (lookup == 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;
static int agg_read (void) /* {{{ */
{
- agg_instance_t *this;
cdtime_t t;
int success;
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;
**/
#include "collectd.h"
+
#include "common.h"
#include "plugin.h"
#include "utils_cmd_putval.h"
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
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)
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,
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,
/* 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] = '/';
{
camqp_config_t *conf;
int status;
- int i;
conf = calloc (1, sizeof (*conf));
if (conf == NULL)
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;
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);
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;
**/
#include "collectd.h"
+
#include "common.h"
#include "plugin.h"
-#include "configfile.h"
#include <curl/curl.h>
static int config_add (oconfig_item_t *ci)
{
apache_t *st;
- int i;
int status;
st = calloc (1, sizeof (*st));
}
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;
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)
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;
} /* 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)
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++;
**/
#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 <sys/types.h>
{
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)
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;
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));
**/
#include "collectd.h"
+
#include "common.h"
#include "plugin.h"
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));
char inst[128];
int value_int;
double value_double;
- int i;
-
if (!io_master_port || (io_master_port == MACH_PORT_NULL))
return (-1);
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;
**/
#include "collectd.h"
+
#include "common.h"
#include "plugin.h"
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;
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));
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;
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)
{
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))
**/
#include "collectd.h"
+
#include "common.h"
#include "plugin.h"
-#include "configfile.h"
#include <curl/curl.h>
#include <libxml/parser.h>
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));
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]);
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))
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))
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))
{
xmlDoc *doc;
xmlNode *cur;
- xmlNode *child;
#if 0
doc = xmlParseMemory (data, strlen (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))
**/
#include "collectd.h"
+
#include "common.h"
#include "utils_cache.h"
#include "plugin.h"
#include <unistd.h>
#include <linux/i2c-dev.h>
#include <math.h>
+#include <sys/ioctl.h>
/* ------------ MPL115 defines ------------ */
/* I2C address of the MPL115 sensor */
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];
list->initialized = 1;
list->num_values = values_num;
- for(i=0; i<values_num; ++i)
+ for(size_t i=0; i<values_num; ++i)
{
DEBUG ("barometer: get_reference_temperature - rate %zu: %lf **",
i, values[i]);
continue;
}
- for(i=0; i<REF_TEMP_AVG_NUM*list->num_values; ++i)
+ for(size_t i=0; i<REF_TEMP_AVG_NUM*list->num_values; ++i)
{
DEBUG ("barometer: get_reference_temperature - history %zu: %lf",
i, values_history[i]);
continue;
}
- for(i=0; i<values_num; ++i)
+ for(size_t i=0; i<values_num; ++i)
{
DEBUG ("barometer: get_reference_temperature - rate last %zu: %lf **",
i, values[i]);
already available. */
if(!avg_initialized)
{
- int i;
- for(i=0; i<config_oversample-1; ++i)
+ for(int i=0; i<config_oversample-1; ++i)
{
result = MPL115_read_averaged(&pressure, &temperature);
if(result)
**/
#include "collectd.h"
+
#include "common.h"
#include "plugin.h"
# define SYSFS_FACTOR 0.000001
#endif /* KERNEL_LINUX */
+int battery_read_statefs (void); /* defined in battery_statefs; used by StateFS backend */
+
static _Bool report_percent = 0;
static _Bool report_degraded = 0;
+static _Bool query_statefs = 0;
static void battery_submit2 (char const *plugin_instance, /* {{{ */
char const *type, char const *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, "battery", sizeof (vl.plugin));
CFTypeRef ps_obj;
double temp_double;
- int i;
ps_raw = IOPSCopyPowerSourcesInfo ();
ps_array = IOPSCopyPowerSourcesList (ps_raw);
DEBUG ("ps_array_len == %i", ps_array_len);
- for (i = 0; i < ps_array_len; i++)
+ for (int i = 0; i < ps_array_len; i++)
{
ps_obj = CFArrayGetValueAtIndex (ps_array, i);
ps_dict = IOPSGetPowerSourceDescription (ps_raw, ps_obj);
CFDictionaryRef bat_root_dict;
CFArrayRef bat_info_arry;
CFIndex bat_info_arry_len;
- CFIndex bat_info_arry_pos;
CFDictionaryRef bat_info_dict;
double temp_double;
}
bat_info_arry_len = CFArrayGetCount (bat_info_arry);
- for (bat_info_arry_pos = 0;
+ for (CFIndex bat_info_arry_pos = 0;
bat_info_arry_pos < bat_info_arry_len;
bat_info_arry_pos++)
{
gauge_t capacity_full = NAN; /* Total capacity */
gauge_t capacity_design = NAN; /* Full design capacity */
+ if (query_statefs)
+ return battery_read_statefs ();
+
#if HAVE_IOKIT_PS_IOPOWERSOURCES_H
get_via_io_power_sources (&charge_rel, ¤t, &voltage);
#endif
char const *basename,
char *buffer, size_t buffer_size)
{
- int status;
- FILE *fp;
char filename[PATH_MAX];
+ int status;
ssnprintf (filename, sizeof (filename), "%s/%s/%s",
dir, power_supply, basename);
- /* No file isn't the end of the world -- not every system will be
- * reporting the same set of statistics */
- if (access (filename, R_OK) != 0)
- return ENOENT;
-
- fp = fopen (filename, "r");
- if (fp == NULL)
- {
- status = errno;
- if (status != ENOENT)
- {
- char errbuf[1024];
- WARNING ("battery plugin: fopen (%s) failed: %s", filename,
- sstrerror (status, errbuf, sizeof (errbuf)));
- }
+ status = (int) read_file_contents (filename, buffer, buffer_size);
+ if (status < 0)
return status;
- }
-
- if (fgets (buffer, buffer_size, fp) == NULL)
- {
- status = errno;
- if (status != ENODEV)
- {
- char errbuf[1024];
- WARNING ("battery plugin: fgets (%s) failed: %s", filename,
- sstrerror (status, errbuf, sizeof (errbuf)));
- }
- fclose (fp);
- return status;
- }
strstripnewline (buffer);
-
- fclose (fp);
return 0;
} /* }}} int sysfs_file_to_buffer */
static int read_pmu (void) /* {{{ */
{
- int i;
-
+ int i = 0;
/* The upper limit here is just a safeguard. If there is a system with
* more than 100 batteries, this can easily be increased. */
- for (i = 0; i < 100; i++)
+ for (; i < 100; i++)
{
FILE *fh;
{
int status;
+ if (query_statefs)
+ return battery_read_statefs ();
+
DEBUG ("battery plugin: Trying sysfs ...");
status = read_sysfs ();
if (status == 0)
static int battery_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;
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\".",
--- /dev/null
+/**
+ * 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 <http://github.com/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 <stdio.h>
+
+#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);
+}
#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. */
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);
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;
xmlNode *node;
char *str_ptr;
char *tmp;
- struct tm tm;
+ struct tm tm = { 0 };
xpathObj = xmlXPathEvalExpression (BAD_CAST xpath_expression, xpathCtx);
if (xpathObj == NULL)
return (-1);
}
- memset (&tm, 0, sizeof(tm));
tmp = strptime (str_ptr, "%Y-%m-%dT%T", &tm);
xmlFree(str_ptr);
if (tmp == NULL)
{
xmlXPathObject *xpathObj = NULL;
int num_entries;
- int i;
xpathObj = xmlXPathEvalExpression(BAD_CAST xpath_expression, xpathCtx);
if (xpathObj == NULL)
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)
{
{
xmlXPathObject *xpathObj = NULL;
int num_entries;
- int i;
xpathObj = xmlXPathEvalExpression(BAD_CAST xpath_expression, xpathCtx);
if (xpathObj == NULL)
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)
{
{
xmlXPathObject *xpathObj = NULL;
int num_entries;
- int i;
xpathObj = xmlXPathEvalExpression(BAD_CAST xpath_expression, xpathCtx);
if (xpathObj == NULL)
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)
{
{
xmlXPathObject *path_obj;
char *zone_name = NULL;
- int i;
size_t j;
if (version >= 3)
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);
{
xmlXPathObject *zone_nodes = NULL;
xmlXPathContext *zone_path_context;
- int i;
zone_path_context = xmlXPathNewContext (doc);
if (zone_path_context == NULL)
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);
{
char *view_name = NULL;
cb_view_t *view;
- int i;
size_t j;
if (version == 3)
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);
{
xmlXPathObject *view_nodes = NULL;
xmlXPathContext *view_path_context;
- int i;
view_path_context = xmlXPathNewContext (doc);
if (view_path_context == NULL)
return (-1);
}
- for (i = 0; i < view_nodes->nodesetval->nodeNr; i++)
+ for (int i = 0; i < view_nodes->nodesetval->nodeNr; i++)
{
xmlNode *node;
xmlXPathContext *xpathCtx = NULL;
xmlXPathObject *xpathObj = NULL;
int ret = -1;
- int i;
doc = xmlParseMemory (data, strlen (data));
if (doc == NULL)
}
else
{
- for (i = 0; i < xpathObj->nodesetval->nodeNr; i++)
+ for (int i = 0; i < xpathObj->nodesetval->nodeNr; i++)
{
xmlNode *node;
char *attr_version;
return (-1);
}
- for (i = 0; i < xpathObj->nodesetval->nodeNr; i++)
+ for (int i = 0; i < xpathObj->nodesetval->nodeNr; i++)
{
xmlNode *node;
char *attr_version;
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))
{
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;
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;
#define _BSD_SOURCE
#include "collectd.h"
+
#include "common.h"
#include "plugin.h"
#if HAVE_YAJL_YAJL_VERSION_H
#include <yajl/yajl_version.h>
#endif
+#ifdef HAVE_SYS_CAPABILITY_H
+# include <sys/capability.h>
+#endif
#include <limits.h>
#include <poll.h>
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.
#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)
{
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;
{
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
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]);
}
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]);
}
/* 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;
{
uint32_t type;
char ds_name[DATA_MAX_NAME_LEN];
- memset(ds_name, 0, sizeof(ds_name));
if(convert_special_metrics)
{
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))
{
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;
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)
*/
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)
{
*/
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;
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))
{
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)
{
"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);
*/
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 */
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;
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))
{
}
}
}
- 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);
}
/******* 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]);
}
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);
**/
#include "collectd.h"
+
#include "common.h"
#include "plugin.h"
-#include "configfile.h"
#include "utils_mount.h"
#include "utils_ignorelist.h"
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. */
*/
#include "collectd.h"
+
#include "common.h" /* auxiliary functions */
#include "plugin.h" /* plugin_register_*, plugin_dispatch_values */
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)
{
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;
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? */
}
#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),
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);
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)
{
{
/* 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)
{
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);
--- /dev/null
+# 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<Lua plugin>
+
+=head1 SYNOPSIS
+
+ LoadPlugin lua
+ # ...
+ <Plugin lua>
+ BasePath "/path/to/your/lua/scripts"
+ Script "script1.lua"
+ Script "script2.lua"
+ </Plugin>
+
+=head1 DESCRIPTION
+
+The C<Lua plugin> 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<exec plugin> (see
+L<collectd-exec(5)>) and provides a lot more functionality, too.
+
+The minimum required Lua version is I<5.1>.
+
+=head1 CONFIGURATION
+
+=over 4
+
+=item B<LoadPlugin> I<Lua>
+
+Loads the Lua plugin.
+
+=item B<BasePath> I<Name>
+
+The directory the C<Lua plugin> looks in to find script B<Script>.
+If set, this is also prepended to B<package.path>.
+
+=item B<Script> I<Name>
+
+The script the C<Lua plugin> is going to run.
+If B<BasePath> is not specified, this needs to be an absolute path.
+
+=back
+
+=head1 WRITING YOUR OWN PLUGINS
+
+Writing your own plugins is quite simple. collectd manages plugins by means of
+B<dispatch functions> which call the appropriate B<callback functions>
+registered by the plugins. Any plugin basically consists of the implementation
+of these callback functions and initializing code which registers the
+functions with collectd. See the section "EXAMPLES" below for a really basic
+example. The following types of B<callback functions> are implemented in the
+Lua plugin (all of them are optional):
+
+=over 4
+
+=item read functions
+
+These are used to collect the actual data. It is called once
+per interval (see the B<Interval> configuration option of collectd). Usually
+it will call B<collectd.dispatch_values> to dispatch the values to collectd
+which will pass them on to all registered B<write functions>. If this function
+does not return 0 the plugin will be skipped for an increasing
+amount of time until it returns normally again.
+
+=item write functions
+
+These are used to write the dispatched values. They are called
+once for every value that was dispatched by any plugin.
+
+=back
+
+=head1 FUNCTIONS
+
+The following functions are provided to Lua modules:
+
+=over 4
+
+=item register_read(callback)
+
+The callback will be called without arguments.
+If this callback function does not return 0 the next call will be delayed by
+an increasing interval.
+
+=item register_write
+
+The callback function will be called with one argument passed, which will be a
+table of values.
+If this callback function does not return 0 next call will be delayed by
+an increasing interval.
+
+=item log_error, log_warning, log_notice, log_info, log_debug(I<message>)
+
+Log a message with the specified severity.
+
+=back
+
+=head1 EXAMPLES
+
+=over 4
+
+A very simple read function might look like:
+
+ function read()
+ collectd.log_info("read function called")
+ t = {
+ host = 'localhost',
+ plugin = 'myplugin',
+ type = 'counter',
+ values = {42},
+ }
+ collectd.dispatch_values(t)
+ return 0
+ end
+
+A very simple write function might look like:
+
+ function write(vl)
+ for i = 1, #vl.values do
+ collectd.log_info(vl.host .. '.' .. vl.plugin .. '.' .. vl.type .. ' ' .. vl.values[i])
+ end
+ return 0
+ end
+
+To register those functions with collectd:
+
+ collectd.register_read(read)
+ collectd.register_write(write)
+
+=back
+
+=head1 SEE ALSO
+
+L<collectd(1)>,
+L<collectd.conf(5)>,
+L<lua(1)>,
+
+=head1 AUTHOR
+
+The C<Lua plugin> has been written by
+Julien Ammous E<lt>j.ammous<nbsp>atE<nbsp>gmail.comE<gt>,
+Florian Forster E<lt>octoE<nbsp>atE<nbsp>collectd.orgE<gt> and
+Ruben Kerkhof E<lt>ruben<nbsp>atE<nbsp>rubenkerkhof.com<gt> and
+
+This manpage has been written by Ruben Kerkhof
+E<lt>ruben<nbsp>atE<nbsp>rubenkerkhof.com<gt>.
+It is based on the L<collectd-perl(5)> manual page by
+Florian Forster E<lt>octoE<nbsp>atE<nbsp>collectd.orgE<gt> and
+Sebastian Harl E<lt>shE<nbsp>atE<nbsp>tokkee.orgE<gt>.
+
+=cut
gauge_t *new_values;
char **new_names;
- size_t i;
-
if (match_ds_g == NULL)
return (RET_OKAY);
return (RET_UNKNOWN);
}
- for (i = 0; i < match_ds_num_g; i++)
+ for (size_t i = 0; i < match_ds_num_g; i++)
{
size_t j;
}
free (*values);
- for (i = 0; i < *values_num; i++)
+ for (size_t i = 0; i < *values_num; i++)
free ((*values_names)[i]);
free (*values_names);
char *hostname = NULL;
int status;
- size_t i;
status = lcc_listval (connection, &ret_ident, &ret_ident_num);
if (status != 0) {
return (RET_UNKNOWN);
}
- for (i = 0; i < ret_ident_num; ++i) {
+ for (size_t i = 0; i < ret_ident_num; ++i) {
char id[1024];
if ((hostname_g != NULL) && (strcasecmp (hostname_g, ret_ident[i].host)))
int num_okay = 0;
const char *status_str = "UNKNOWN";
int status_code = RET_UNKNOWN;
- size_t i;
- for (i = 0; i < values_num; i++)
+ for (size_t i = 0; i < values_num; i++)
{
if (isnan (values[i]))
{
if (values_num > 0)
{
printf (" |");
- for (i = 0; i < values_num; i++)
+ for (size_t i = 0; i < values_num; i++)
printf (" %s=%f;;;;", values_names[i], values[i]);
}
printf ("\n");
static int do_check_con_average (size_t values_num,
double *values, char **values_names)
{
- size_t i;
double total;
int total_num;
double average;
total = 0.0;
total_num = 0;
- for (i = 0; i < values_num; i++)
+ for (size_t i = 0; i < values_num; i++)
{
if (isnan (values[i]))
{
}
printf ("%s: %g average |", status_str, average);
- for (i = 0; i < values_num; i++)
+ for (size_t i = 0; i < values_num; i++)
printf (" %s=%f;;;;", values_names[i], values[i]);
printf ("\n");
static int do_check_con_sum (size_t values_num,
double *values, char **values_names)
{
- size_t i;
double total;
int total_num;
const char *status_str = "UNKNOWN";
total = 0.0;
total_num = 0;
- for (i = 0; i < values_num; i++)
+ for (size_t i = 0; i < values_num; i++)
{
if (isnan (values[i]))
{
}
printf ("%s: %g sum |", status_str, total);
- for (i = 0; i < values_num; i++)
+ for (size_t i = 0; i < values_num; i++)
printf (" %s=%f;;;;", values_names[i], values[i]);
printf ("\n");
static int do_check_con_percentage (size_t values_num,
double *values, char **values_names)
{
- size_t i;
double sum = 0.0;
double percentage;
return (RET_WARNING);
}
- for (i = 0; i < values_num; i++)
+ for (size_t i = 0; i < values_num; i++)
{
if (isnan (values[i]))
{
}
printf ("%s: %lf percent |", status_str, percentage);
- for (i = 0; i < values_num; i++)
+ for (size_t i = 0; i < values_num; i++)
printf (" %s=%lf;;;;", values_names[i], values[i]);
return (status_code);
} /* int do_check_con_percentage */
size_t values_num;
char ident_str[1024];
lcc_identifier_t ident;
- size_t i;
int status;
snprintf (ident_str, sizeof (ident_str), "%s/%s",
hostname_g, value_string_g);
ident_str[sizeof (ident_str) - 1] = 0;
- memset (&ident, 0, sizeof (ident));
status = lcc_string_to_identifier (connection, &ident, ident_str);
if (status != 0)
{
free (values);
if (values_names != NULL)
- for (i = 0; i < values_num; i++)
+ for (size_t i = 0; i < values_num; i++)
free (values_names[i]);
free (values_names);
command line option or B<use lib Dir> in the source code. Please note that it
only has effect on plugins loaded after this option.
+=item B<RegisterLegacyFlush> I<true|false>
+
+The C<Perl plugin> used to register one flush callback (called B<"perl">) and
+call all Perl-based flush handlers when this callback was called. Newer versions
+of the plugin wrap the Perl flush handlers and register them directly with the
+daemon I<in addition> to the legacy B<"perl"> callback. This allows to call
+specific Perl flush handlers, but has the downside that flushing I<all> plugins
+now calls the Perl flush handlers twice (once directly and once via the legacy
+callback). Unfortunately, removing the B<"perl"> callback would break backwards
+compatibility.
+
+This option allows you to disable the legacy B<"perl"> flush callback if you care
+about the double call and don't call the B<"perl"> callback in your setup.
+
=back
=head1 WRITING YOUR OWN PLUGINS
=back
-=head1 KNOWN BUGS
-
-=over 4
-
-=item *
-
-Currently, it is not possible to flush a single Perl plugin only. You can
-either flush all Perl plugins or none at all and you have to use C<perl> as
-plugin name when doing so.
-
-=back
-
=head1 SEE ALSO
L<collectd(1)>,
Python-script every time you want to read a value with the C<exec plugin> (see
L<collectd-exec(5)>) and provides a lot more functionality, too.
-The minimum required Python version is I<2.3>.
+The minimum required Python version is I<2.6>.
=head1 CONFIGURATION
=item *
-B<2.> collectd will block I<SIGINT>. Pressing I<Ctrl+C> will usually cause
+B<2.> Python will be handling I<SIGINT>. Pressing I<Ctrl+C> will usually cause
collectd to shut down. This would be problematic in an interactive session,
-therefore this signal will be blocked. You can still use it to interrupt
-syscalls like sleep and pause but it won't generate a I<KeyboardInterrupt>
-exception either.
+therefore Python will be handling it in interactive sessions. This allows you
+to use I<Ctrl+C> to interrupt Python code without killing collectd. This also
+means you can catch I<KeyboardInterrupt> exceptions which does not work during
+normal operation.
To quit collectd send I<EOF> (press I<Ctrl+D> at the beginning of a new line).
A very simple read function might look like:
+ import random
+
def read(data=None):
vl = collectd.Values(type='gauge')
vl.plugin='python.spam'
To register those functions with collectd:
- collectd.register_read(read);
- collectd.register_write(write);
+ collectd.register_read(read)
+ collectd.register_write(write)
See the section L<"CLASSES"> above for a complete documentation of the data
types used by the read, write and match functions.
-=head1 NOTES
-
-=over 4
-
-=item *
-
-Please feel free to send in new plugins to collectd's mailing list at
-E<lt>collectdE<nbsp>atE<nbsp>collectd.orgE<gt> for review and, possibly,
-inclusion in the main distribution. In the latter case, we will take care of
-keeping the plugin up to date and adapting it to new versions of collectd.
-
-Before submitting your plugin, please take a look at
-L<http://collectd.org/dev-info.shtml>.
-
-=back
-
=head1 CAVEATS
=over 4
int main (int argc, char **argv) /* {{{ */
{
- int i;
double last_time;
int values_sent = 0;
fprintf (stdout, "Creating %i values ... ", conf_num_values);
fflush (stdout);
- for (i = 0; i < conf_num_values; i++)
+ for (int i = 0; i < conf_num_values; i++)
{
lcc_value_list_t *vl;
#@BUILD_PLUGIN_CONTEXTSWITCH_TRUE@LoadPlugin contextswitch
@BUILD_PLUGIN_CPU_TRUE@@BUILD_PLUGIN_CPU_TRUE@LoadPlugin cpu
#@BUILD_PLUGIN_CPUFREQ_TRUE@LoadPlugin cpufreq
+#@BUILD_PLUGIN_CPUSLEEP_TRUE@LoadPlugin cpusleep
@LOAD_PLUGIN_CSV@LoadPlugin csv
#@BUILD_PLUGIN_CURL_TRUE@LoadPlugin curl
#@BUILD_PLUGIN_CURL_JSON_TRUE@LoadPlugin curl_json
#@BUILD_PLUGIN_FILECOUNT_TRUE@LoadPlugin filecount
#@BUILD_PLUGIN_FSCACHE_TRUE@LoadPlugin fscache
#@BUILD_PLUGIN_GMOND_TRUE@LoadPlugin gmond
+#@BUILD_PLUGIN_GPS_TRUE@LoadPlugin gps
#@BUILD_PLUGIN_GRPC_TRUE@LoadPlugin grpc
#@BUILD_PLUGIN_HDDTEMP_TRUE@LoadPlugin hddtemp
+#@BUILD_PLUGIN_HUGEPAGES_TRUE@LoadPlugin hugepages
@BUILD_PLUGIN_INTERFACE_TRUE@@BUILD_PLUGIN_INTERFACE_TRUE@LoadPlugin interface
#@BUILD_PLUGIN_IPC_TRUE@LoadPlugin ipc
#@BUILD_PLUGIN_IPMI_TRUE@LoadPlugin ipmi
#@BUILD_PLUGIN_JAVA_TRUE@LoadPlugin java
@BUILD_PLUGIN_LOAD_TRUE@@BUILD_PLUGIN_LOAD_TRUE@LoadPlugin load
#@BUILD_PLUGIN_LPAR_TRUE@LoadPlugin lpar
+#@BUILD_PLUGIN_LUA_TRUE@LoadPlugin lua
#@BUILD_PLUGIN_LVM_TRUE@LoadPlugin lvm
#@BUILD_PLUGIN_MADWIFI_TRUE@LoadPlugin madwifi
#@BUILD_PLUGIN_MBMON_TRUE@LoadPlugin mbmon
#<Plugin "battery">
# ValuesPercentage false
# ReportDegraded false
+# QueryStateFS false
#</Plugin>
#<Plugin "bind">
# </Metric>
#</Plugin>
+#<Plugin gps>
+# Host "127.0.0.1"
+# Port "2947"
+# Timeout 0.015
+# PauseConnect 5
+#</Plugin>
+
#<Plugin grpc>
-# WorkerThreads 5
+# <Server "example.com" "50051">
+# EnableSSL true
+# SSLCACertificateFile "/path/to/root.pem"
+# SSLCertificateFile "/path/to/server.pem"
+# SSLCertificateKeyFile "/path/to/server.key"
+# </Server>
# <Listen "0.0.0.0" "50051">
# EnableSSL true
-# SSLRootCerts "/path/to/root.pem"
-# SSLServerCert "/path/to/server.pem"
-# SSLServerKey "/path/to/server.key"
+# SSLCACertificateFile "/path/to/root.pem"
+# SSLCertificateFile "/path/to/client.pem"
+# SSLCertificateKeyFile "/path/to/client.key"
# </Listen>
#</Plugin>
# Port "7634"
#</Plugin>
+#<Plugin hugepages>
+# ReportPerNodeHP true
+# ReportRootHP true
+# ValuesPages true
+# ValuesBytes false
+# ValuesPercentage false
+#</Plugin>
+
#<Plugin interface>
# Interface "eth0"
# IgnoreSelected false
+# ReportInactive true
# UniqueName false
#</Plugin>
# ReportBySerial false
#</Plugin>
+#<Plugin lua>
+# BasePath "@prefix@/share/@PACKAGE_NAME@/lua"
+# Script "script1.lua"
+# Script "script2.lua"
+#</Plugin>
+
#<Plugin madwifi>
# Interface "wlan0"
# IgnoreSelected false
# User "db_user"
# Password "secret"
# Database "db_name"
+# SSLKey "/path/to/key.pem"
+# SSLCert "/path/to/cert.pem"
+# SSLCA "/path/to/ca.pem"
+# SSLCAPath "/path/to/cas/"
+# SSLCipher "DHE-RSA-AES256-SHA"
# MasterStats true
# ConnectTimeout 10
# InnodbStats true
# SlaveStats true
# SlaveNotifications true
# </Database>
+# <Database galera>
+# Alias "galera"
+# Host "localhost"
+# Socket "/var/run/mysql/mysqld.sock"
+# WsrepStats true
+# </Database>
#</Plugin>
#<Plugin netapp>
# StoreRates true
# AlwaysAppendDS false
# EscapeCharacter "_"
+# SeparateInstances false
+# DropDuplicateFields false
# </Node>
#</Plugin>
# Header "X-Custom-Header: custom_value"
# SSLVersion "TLSv1"
# Format "Command"
+# Metrics true
+# Notifications false
# StoreRates false
# BufferSize 4096
# LowSpeedLimit 0
Set one or more files that contain the data-set descriptions. See
L<types.db(5)> for a description of the format of this file.
+If this option is not specified, a default file is read. If you need to define
+custom types in addition to the types defined in the default file, you need to
+explicitly load both. In other words, if the B<TypesDB> option is encountered
+the default behavior is disabled and if you need the default types you have to
+also explicitly load them.
+
=item B<Interval> I<Seconds>
Configures the interval in which to query the read plugins. Obviously smaller
and "remaining capacity") and B<degraded> (difference between "design capacity"
and "last full capacity").
+=item B<QueryStateFS> B<false>|B<true>
+
+When set to B<true>, the battery plugin will only read statistics
+related to battery performance as exposed by StateFS at
+/run/state. StateFS is used in Mer-based Sailfish OS, for
+example.
+
=back
=head2 Plugin C<bind>
Jiffies. By setting this option to B<true>, you can request percentage values
in the un-aggregated (per-CPU, per-state) mode as well.
+=item B<ReportNumCpu> B<false>|B<true>
+
+When set to B<true>, reports the number of available CPUs.
+Defaults to B<false>.
+
=back
=head2 Plugin C<cpufreq>
sure B<cpufreqd> (L<http://cpufreqd.sourceforge.net/>) or a similar tool is
installed and an "cpu governor" (that's a kernel module) is loaded.
+=head2 Plugin C<cpusleep>
+
+This plugin doesn't have any options. It reads CLOCK_BOOTTIME and
+CLOCK_MONOTONIC and reports the difference between these clocks. Since
+BOOTTIME clock increments while device is suspended and MONOTONIC
+clock does not, the derivative of the difference between these clocks
+gives the relative amount of time the device has spent in suspend
+state. The recorded value is in milliseconds of sleep per seconds of
+wall clock.
+
=head2 Plugin C<csv>
=over 4
=over 4
+=item B<Host> I<Name>
+
+Use I<Name> as the host name when submitting values. Defaults to the global
+host name setting.
+
=item B<Instance> I<Instance>
Sets the plugin instance to I<Instance>.
=item B<MappedOnly> B<true>|B<false>
-When set to B<true>, only metrics that can be mapped to to a I<type> will be
+When set to B<true>, only metrics that can be mapped to a I<type> will be
collected, all other metrics will be ignored. Defaults to B<false>.
=back
=back
+=head2 Plugin C<gps>
+
+The C<gps plugin> connects to gpsd on the host machine.
+The host, port, timeout and pause are configurable.
+
+This is useful if you run an NTP server using a GPS for source and you want to
+monitor it.
+
+Mind your GPS must send $--GSA for having the data reported!
+
+The following elements are collected:
+
+=over 4
+
+=item B<satellites>
+
+Number of satellites used for fix (type instance "used") and in view (type
+instance "visible"). 0 means no GPS satellites are visible.
+
+=item B<dilution_of_precision>
+
+Vertical and horizontal dilution (type instance "horizontal" or "vertical").
+It should be between 0 and 3.
+Look at the documentation of your GPS to know more.
+
+=back
+
+Synopsis:
+
+ LoadPlugin gps
+ <Plugin "gps">
+ # Connect to localhost on gpsd regular port:
+ Host "127.0.0.1"
+ Port "2947"
+ # 15 ms timeout
+ Timeout 0.015
+ # PauseConnect of 5 sec. between connection attempts.
+ PauseConnect 5
+ </Plugin>
+
+Available configuration options:
+
+=over 4
+
+=item B<Host> I<Host>
+
+The host on which gpsd daemon runs. Defaults to B<localhost>.
+
+=item B<Port> I<Port>
+
+Port to connect to gpsd on the host machine. Defaults to B<2947>.
+
+=item B<Timeout> I<Seconds>
+
+Timeout in seconds (default 0.015 sec).
+
+The GPS data stream is fetch by the plugin form the daemon.
+It waits for data to be available, if none arrives it times out
+and loop for another reading.
+Mind to put a low value gpsd expects value in the micro-seconds area
+(recommended is 500 us) since the waiting function is blocking.
+Value must be between 500 us and 5 sec., if outside that range the
+default value is applied.
+
+This only applies from gpsd release-2.95.
+
+=item B<PauseConnect> I<Seconds>
+
+Pause to apply between attempts of connection to gpsd in seconds (default 5 sec).
+
+=back
+
=head2 Plugin C<grpc>
The I<grpc> plugin provides an RPC interface to submit values to or query
=over 4
+=item B<Server> I<Host> I<Port>
+
+The B<Server> statement sets the address of a server to which to send metrics
+via the C<DispatchValues> function.
+
+The argument I<Host> may be a hostname, an IPv4 address, or an IPv6 address.
+
+Optionally, B<Server> may be specified as a configuration block which supports
+the following options:
+
+=over 4
+
+=item B<EnableSSL> B<false>|B<true>
+
+Whether to require SSL for outgoing connections. Default: false.
+
+=item B<SSLCACertificateFile> I<Filename>
+
+=item B<SSLCertificateFile> I<Filename>
+
+=item B<SSLCertificateKeyFile> I<Filename>
+
+Filenames specifying SSL certificate and key material to be used with SSL
+connections.
+
+=back
+
=item B<Listen> I<Host> I<Port>
The B<Listen> statement sets the network address to bind to. When multiple
Whether to enable SSL for incoming connections. Default: false.
-=item B<SSLRootCerts> I<Filename>
+=item B<SSLCACertificateFile> I<Filename>
-=item B<SSLServerKey> I<Filename>
+=item B<SSLCertificateFile> I<Filename>
-=item B<SSLServerCert> I<Filename>
+=item B<SSLCertificateKeyFile> I<Filename>
Filenames specifying SSL certificate and key material to be used with SSL
connections.
=back
-=item B<WorkerThreads> I<Num>
-
-Number of threads to start for handling incoming connections. The default
-value is B<5>.
-
=back
=head2 Plugin C<hddtemp>
=back
+=head2 Plugin C<hugepages>
+
+To collect B<hugepages> information, collectd reads directories
+"/sys/devices/system/node/*/hugepages" and
+"/sys/kernel/mm/hugepages".
+Reading of these directories can be disabled by the following
+options (default is enabled).
+
+=over 4
+
+=item B<ReportPerNodeHP> B<true>|B<false>
+
+If enabled, information will be collected from the hugepage
+counters in "/sys/devices/system/node/*/hugepages".
+This is used to check the per-node hugepage statistics on
+a NUMA system.
+
+=item B<ReportRootHP> B<true>|B<false>
+
+If enabled, information will be collected from the hugepage
+counters in "/sys/kernel/mm/hugepages".
+This can be used on both NUMA and non-NUMA systems to check
+the overall hugepage statistics.
+
+=item B<ValuesPages> B<true>|B<false>
+
+Whether to report hugepages metrics in number of pages.
+Defaults to B<true>.
+
+=item B<ValuesBytes> B<false>|B<true>
+
+Whether to report hugepages metrics in bytes.
+Defaults to B<false>.
+
+=item B<ValuesPercentage> B<false>|B<true>
+
+Whether to report hugepages metrics as percentage.
+Defaults to B<false>.
+
+=back
+
=head2 Plugin C<interface>
=over 4
with I<veth> and all interfaces with names starting with I<tun> followed by
at least one digit.
+=item B<ReportInactive> I<true>|I<false>
+
+When set to I<false>, only interfaces with non-zero traffic will be
+reported. Note that the check is done by looking into whether a
+package was sent at any time from boot and the corresponding counter
+is non-zero. So, if the interface has been sending data in the past
+since boot, but not during the reported time-interval, it will still
+be reported.
+
+The default value is I<true> and results in collection of the data
+from all interfaces that are selected by B<Interface> and
+B<IgnoreSelected> options.
=item B<UniqueName> I<true>|I<false>
=back
+=head2 Plugin C<lua>
+
+This plugin embeds a Lua interpreter into collectd and provides an interface
+to collectd's plugin system. See L<collectd-lua(5)> for its documentation.
+
+
=head2 Plugin C<mbmon>
The C<mbmon plugin> uses mbmon to retrieve temperature, voltage, etc.
Port "3306"
MasterStats true
ConnectTimeout 10
+ SSLKey "/path/to/key.pem"
+ SSLCert "/path/to/cert.pem"
+ SSLCA "/path/to/ca.pem"
+ SSLCAPath "/path/to/cas/"
+ SSLCipher "DHE-RSA-AES256-SHA"
</Database>
<Database bar>
SlaveStats true
SlaveNotifications true
</Database>
+
+ <Database galera>
+ Alias "galera"
+ Host "localhost"
+ Socket "/var/run/mysql/mysqld.sock"
+ WsrepStats true
+ </Database>
</Plugin>
A B<Database> block defines one connection to a MySQL database. It accepts a
single argument which specifies the name of the database. None of the other
options are required. MySQL will use default values as documented in the
-section "mysql_real_connect()" in the B<MySQL reference manual>.
+"mysql_real_connect()" and "mysql_ssl_set()" sections in the
+B<MySQL reference manual>.
=over 4
If enabled, the plugin sends a notification if the replication slave I/O and /
or SQL threads are not running. Defaults to B<false>.
+=item B<WsrepStats> I<true|false>
+
+ Enable the collection of wsrep plugin statistics, used in Master-Master
+ replication setups like in MySQL Galera/Percona XtraDB Cluster.
+ User needs only privileges to execute 'SHOW GLOBAL STATUS'
+
=item B<ConnectTimeout> I<Seconds>
Sets the connect timeout for the MySQL client.
+=item B<SSLKey> I<Path>
+
+If provided, the X509 key in PEM format.
+
+=item B<SSLCert> I<Path>
+
+If provided, the X509 cert in PEM format.
+
+=item B<SSLCA> I<Path>
+
+If provided, the CA file in PEM format (check OpenSSL docs).
+
+=item B<SSLCAPath> I<Path>
+
+If provided, the CA directory (check OpenSSL docs).
+
+=item B<SSLCipher> I<String>
+
+If provided, the SSL cipher to use.
+
=back
=head2 Plugin C<netapp>
=item B<$1>
-The timestamp of the queried value as a floating point number.
+The timestamp of the queried value as an RFC 3339-formatted local time.
=item B<$2>
=item B<AllPortsSummary> I<true>|I<false>
If this option is set to I<true> a summary of statistics from all connections
-are collectd. This option defaults to I<false>.
+are collected. This option defaults to I<false>.
=back
identifier. If set to B<false> (the default), this is only done when there is
more than one DS.
+=item B<DropDuplicateFields> B<false>|B<true>
+
+If set to B<true>, detect and remove duplicate components in Graphite metric
+names. For example, the metric name C<host.load.load.shortterm> will
+be shortened to C<host.load.shortterm>.
+
+=back
+
+=head2 Plugin C<write_log>
+
+The C<write_log> plugin writes metrics as INFO log messages.
+
+This plugin supports two output formats: I<Graphite> and I<JSON>.
+
+Synopsis:
+
+ <Plugin write_log>
+ Format Graphite
+ </Plugin>
+
+=over 4
+
+=item B<Format> I<Format>
+
+The output format to use. Can be one of C<Graphite> or C<JSON>.
+
=back
=head2 Plugin C<write_tsdb>
Defaults to B<Command>.
+=item B<Metrics> B<true>|B<false>
+
+Controls whether I<metrics> are POSTed to this location. Defaults to B<true>.
+
+=item B<Notifications> B<false>|B<true>
+
+Controls whether I<notifications> are POSTed to this location. Defaults to B<false>.
+
=item B<StoreRates> B<true|false>
If set to B<true>, convert counter values to rates. If set to B<false> (the
=item B<TypeInstance> I<Regex>
+=item B<MetaData> I<String> I<Regex>
+
Match values where the given regular expressions match the various fields of
the identifier of a value. If multiple regular expressions are given, B<all>
regexen must match for a value to match.
=item B<TypeInstance> I<Regex> I<Replacement>
+=item B<MetaData> I<String> I<Regex> I<Replacement>
+
+=item B<DeleteMetaData> I<String> I<Regex>
+
Match the appropriate field with the given regular expression I<Regex>. If the
regular expression matches, that part that matches is replaced with
I<Replacement>. If multiple places of the input buffer match a given regular
=item B<TypeInstance> I<String>
-=item B<MetaDataSet> I<String> I<String>
+=item B<MetaData> I<String> I<String>
+
+Set the appropriate field to the given string. The strings for plugin instance,
+type instance, and meta data may be empty, the strings for host and plugin may
+not be empty. It's currently not possible to set the type of a value this way.
+
+The following placeholders will be replaced by an appropriate value:
+
+=over 4
+
+=item B<%{host}>
+
+=item B<%{plugin}>
+
+=item B<%{plugin_instance}>
+
+=item B<%{type}>
+
+=item B<%{type_instance}>
+
+These placeholders are replaced by the identifier field of the same name.
+
+=item B<%{meta:>I<name>B<}>
+
+These placeholders are replaced by the meta data value with the given name.
+
+=back
+
+Please note that these placeholders are B<case sensitive>!
+
+=item B<DeleteMetaData> I<String>
-Set the appropriate field to the given string. The strings for plugin instance
-and type instance may be empty, the strings for host and plugin may not be
-empty. It's currently not possible to set the type of a value this way.
+Delete the named meta data field.
=back
#include "libcollectdclient/collectd/client.h"
+#ifndef PREFIX
+# define PREFIX "/opt/" PACKAGE_NAME
+#endif
+
+#ifndef LOCALSTATEDIR
+# define LOCALSTATEDIR PREFIX "/var"
+#endif
+
#define DEFAULT_SOCK LOCALSTATEDIR"/run/"PACKAGE_NAME"-unixsock"
extern char *optarg;
char **ret_values_names = NULL;
int status;
- size_t i;
assert (strcasecmp (argv[0], "getval") == 0);
return (-1);
}
- memset (&ident, 0, sizeof (ident));
status = parse_identifier (c, argv[1], &ident);
if (status != 0)
return (status);
if (ret_values != NULL) \
free (ret_values); \
if (ret_values_names != NULL) { \
- for (i = 0; i < ret_values_num; ++i) \
+ for (size_t i = 0; i < ret_values_num; ++i) \
free (ret_values_names[i]); \
free (ret_values_names); \
} \
BAIL_OUT (-1);
}
- for (i = 0; i < ret_values_num; ++i)
+ for (size_t i = 0; i < ret_values_num; ++i)
printf ("%s=%e\n", ret_values_names[i], ret_values[i]);
BAIL_OUT (0);
#undef BAIL_OUT
size_t plugins_num = 0;
int status;
- int i;
assert (strcasecmp (argv[0], "flush") == 0);
return (s); \
} while (0)
- for (i = 1; i < argc; ++i) {
+ for (int i = 1; i < argc; ++i) {
char *key, *value;
key = argv[i];
plugins[0] = NULL;
}
- for (i = 0; i < plugins_num; ++i) {
+ for (size_t i = 0; i < plugins_num; ++i) {
if (identifiers_num == 0) {
status = lcc_flush (c, plugins[i], NULL, timeout);
if (status != 0)
(plugins[i] == NULL) ? "(all)" : plugins[i], lcc_strerror (c));
}
else {
- int j;
-
- for (j = 0; j < identifiers_num; ++j) {
+ for (size_t j = 0; j < identifiers_num; ++j) {
status = lcc_flush (c, plugins[i], identifiers + j, timeout);
if (status != 0) {
char id[1024];
size_t ret_ident_num = 0;
int status;
- size_t i;
assert (strcasecmp (argv[0], "listval") == 0);
BAIL_OUT (status);
}
- for (i = 0; i < ret_ident_num; ++i) {
+ for (size_t i = 0; i < ret_ident_num; ++i) {
char id[1024];
status = lcc_identifier_to_string (c, id, sizeof (id), ret_ident + i);
size_t values_len = 0;
int status;
- int i;
assert (strcasecmp (argv[0], "putval") == 0);
if (status != 0)
return (status);
- for (i = 2; i < argc; ++i) {
+ for (int i = 2; i < argc; ++i) {
char *tmp;
tmp = strchr (argv[i], (int)'=');
#include <unistd.h>
+#ifndef PREFIX
+# define PREFIX "/opt/" PACKAGE_NAME
+#endif
+
+#ifndef LOCALSTATEDIR
+# define LOCALSTATEDIR PREFIX "/var"
+#endif
+
#ifndef COLLECTDMON_PIDFILE
# define COLLECTDMON_PIDFILE LOCALSTATEDIR"/run/collectdmon.pid"
#endif /* ! COLLECTDMON_PIDFILE */
**/
#include "collectd.h"
+
#include "common.h"
#include "plugin.h"
static int conntrack_read (void)
{
value_t conntrack, conntrack_max, conntrack_pct;
- FILE *fh;
- char buffer[64];
- size_t buffer_len;
-
- fh = fopen (old_files?CONNTRACK_FILE_OLD:CONNTRACK_FILE, "r");
- if (fh == NULL)
- return (-1);
- memset (buffer, 0, sizeof (buffer));
- if (fgets (buffer, sizeof (buffer), fh) == NULL)
+ char const *path = old_files ? CONNTRACK_FILE_OLD : CONNTRACK_FILE;
+ if (parse_value_file (path, &conntrack, DS_TYPE_GAUGE) != 0)
{
- fclose (fh);
+ ERROR ("conntrack plugin: Reading \"%s\" failed.", path);
return (-1);
}
- fclose (fh);
-
- /* strip trailing newline. */
- buffer_len = strlen (buffer);
- while ((buffer_len > 0) && isspace ((int) buffer[buffer_len - 1]))
- {
- buffer[buffer_len - 1] = 0;
- buffer_len--;
- }
-
- if (parse_value (buffer, &conntrack, DS_TYPE_GAUGE) != 0)
- return (-1);
- conntrack_submit ("conntrack", NULL, conntrack);
-
- fh = fopen (old_files?CONNTRACK_MAX_FILE_OLD:CONNTRACK_MAX_FILE, "r");
- if (fh == NULL)
- return (-1);
-
- memset (buffer, 0, sizeof (buffer));
- if (fgets (buffer, sizeof (buffer), fh) == NULL)
+ path = old_files ? CONNTRACK_MAX_FILE_OLD : CONNTRACK_MAX_FILE;
+ if (parse_value_file (path, &conntrack_max, DS_TYPE_GAUGE) != 0)
{
- fclose (fh);
+ ERROR ("conntrack plugin: Reading \"%s\" failed.", path);
return (-1);
}
- fclose (fh);
-
- /* strip trailing newline. */
- buffer_len = strlen (buffer);
- while ((buffer_len > 0) && isspace ((int) buffer[buffer_len - 1]))
- {
- buffer[buffer_len - 1] = 0;
- buffer_len--;
- }
-
- if (parse_value (buffer, &conntrack_max, DS_TYPE_GAUGE) != 0)
- return (-1);
- conntrack_submit ("conntrack", "max", conntrack_max);
conntrack_pct.gauge = (conntrack.gauge / conntrack_max.gauge) * 100;
- conntrack_submit ("percent", "used", conntrack_pct);
+ conntrack_submit ("conntrack", NULL, conntrack);
+ conntrack_submit ("conntrack", "max", conntrack_max);
+ conntrack_submit ("percent", "used", conntrack_pct);
return (0);
} /* static int conntrack_read */
**/
#include "collectd.h"
+
#include "common.h"
#include "plugin.h"
static void cs_submit (derive_t context_switches)
{
- value_t values[1];
value_list_t vl = VALUE_LIST_INIT;
- values[0].derive = (derive_t) context_switches;
-
- vl.values = values;
+ vl.values = &(value_t) { .derive = context_switches };
vl.values_len = 1;
sstrncpy (vl.host, hostname_g, sizeof (vl.host));
sstrncpy (vl.plugin, "contextswitch", sizeof (vl.plugin));
**/
#include "collectd.h"
+
#include "common.h"
#include "plugin.h"
static _Bool report_by_cpu = 1;
static _Bool report_by_state = 1;
static _Bool report_percent = 0;
+static _Bool report_num_cpu = 0;
static const char *config_keys[] =
{
"ReportByCpu",
"ReportByState",
+ "ReportNumCpu",
"ValuesPercentage"
};
static int config_keys_num = STATIC_ARRAY_SIZE (config_keys);
report_percent = IS_TRUE (value) ? 1 : 0;
else if (strcasecmp (key, "ReportByState") == 0)
report_by_state = IS_TRUE (value) ? 1 : 0;
+ else if (strcasecmp (key, "ReportNumCpu") == 0)
+ report_num_cpu = IS_TRUE (value) ? 1 : 0;
else
return (-1);
static void submit_value (int cpu_num, int cpu_state, const char *type, value_t value)
{
- value_t values[1];
value_list_t vl = VALUE_LIST_INIT;
- memcpy(&values[0], &value, sizeof(value));
-
- vl.values = values;
+ vl.values = &value;
vl.values_len = 1;
sstrncpy (vl.host, hostname_g, sizeof (vl.host));
plugin_dispatch_values (&vl);
}
-static void submit_percent(int cpu_num, int cpu_state, gauge_t percent)
+static void submit_percent (int cpu_num, int cpu_state, gauge_t value)
{
- value_t value;
-
/* This function is called for all known CPU states, but each read
* method will only report a subset. The remaining states are left as
* NAN and we ignore them here. */
- if (isnan (percent))
+ if (isnan (value))
return;
- value.gauge = percent;
- submit_value (cpu_num, cpu_state, "percent", value);
+ submit_value (cpu_num, cpu_state, "percent",
+ (value_t) { .gauge = value });
}
-static void submit_derive(int cpu_num, int cpu_state, derive_t derive)
+static void submit_derive (int cpu_num, int cpu_state, derive_t value)
{
- value_t value;
-
- value.derive = derive;
- submit_value (cpu_num, cpu_state, "cpu", value);
+ submit_value (cpu_num, cpu_state, "cpu",
+ (value_t) { .derive = value });
}
/* Takes the zero-index number of a CPU and makes sure that the module-global
* array. */
static void aggregate (gauge_t *sum_by_state) /* {{{ */
{
- size_t cpu_num;
- size_t state;
-
- for (state = 0; state < COLLECTD_CPU_STATE_MAX; state++)
+ for (size_t state = 0; state < COLLECTD_CPU_STATE_MAX; state++)
sum_by_state[state] = NAN;
- for (cpu_num = 0; cpu_num < global_cpu_num; cpu_num++)
+ for (size_t cpu_num = 0; cpu_num < global_cpu_num; cpu_num++)
{
cpu_state_t *this_cpu_states = get_cpu_state (cpu_num, 0);
this_cpu_states[COLLECTD_CPU_STATE_ACTIVE].rate = NAN;
- for (state = 0; state < COLLECTD_CPU_STATE_ACTIVE; state++)
+ for (size_t state = 0; state < COLLECTD_CPU_STATE_ACTIVE; state++)
{
if (!this_cpu_states[state].has_value)
continue;
static void cpu_commit_one (int cpu_num, /* {{{ */
gauge_t rates[static COLLECTD_CPU_STATE_MAX])
{
- size_t state;
gauge_t sum;
sum = rates[COLLECTD_CPU_STATE_ACTIVE];
return;
}
- for (state = 0; state < COLLECTD_CPU_STATE_ACTIVE; state++)
+ for (size_t state = 0; state < COLLECTD_CPU_STATE_ACTIVE; state++)
{
gauge_t percent = 100.0 * rates[state] / sum;
submit_percent (cpu_num, state, percent);
}
} /* }}} void cpu_commit_one */
+/* Commits the number of cores */
+static void cpu_commit_num_cpu (gauge_t value) /* {{{ */
+{
+ 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, "cpu", sizeof (vl.plugin));
+ sstrncpy (vl.type, "count", sizeof (vl.type));
+
+ plugin_dispatch_values (&vl);
+} /* }}} void cpu_commit_num_cpu */
+
/* Resets the internal aggregation. This is called by the read callback after
* each iteration / after each call to cpu_commit(). */
static void cpu_reset (void) /* {{{ */
{
- size_t i;
-
- for (i = 0; i < cpu_states_num; i++)
+ for (size_t i = 0; i < cpu_states_num; i++)
cpu_states[i].has_value = 0;
global_cpu_num = 0;
/* Legacy behavior: Dispatches the raw derive values without any aggregation. */
static void cpu_commit_without_aggregation (void) /* {{{ */
{
- int state;
-
- for (state = 0; state < COLLECTD_CPU_STATE_ACTIVE; state++)
+ for (int state = 0; state < COLLECTD_CPU_STATE_ACTIVE; state++)
{
- size_t cpu_num;
-
- for (cpu_num = 0; cpu_num < global_cpu_num; cpu_num++)
+ for (size_t cpu_num = 0; cpu_num < global_cpu_num; cpu_num++)
{
cpu_state_t *s = get_cpu_state (cpu_num, state);
gauge_t global_rates[COLLECTD_CPU_STATE_MAX] = {
NAN, NAN, NAN, NAN, NAN, NAN, NAN, NAN, NAN, NAN /* Batman! */
};
- size_t cpu_num;
+
+ if (report_num_cpu)
+ cpu_commit_num_cpu ((gauge_t) global_cpu_num);
if (report_by_state && report_by_cpu && !report_percent)
{
return;
}
- for (cpu_num = 0; cpu_num < global_cpu_num; cpu_num++)
+ for (size_t cpu_num = 0; cpu_num < global_cpu_num; cpu_num++)
{
cpu_state_t *this_cpu_states = get_cpu_state (cpu_num, 0);
gauge_t local_rates[COLLECTD_CPU_STATE_MAX] = {
NAN, NAN, NAN, NAN, NAN, NAN, NAN, NAN, NAN, NAN
};
- size_t state;
- for (state = 0; state < COLLECTD_CPU_STATE_MAX; state++)
+ for (size_t state = 0; state < COLLECTD_CPU_STATE_MAX; state++)
if (this_cpu_states[state].has_value)
local_rates[state] = this_cpu_states[state].rate;
int status;
cpu_state_t *s;
gauge_t rate = NAN;
- value_t val = {.derive = d};
+ value_t val = { .derive = d };
if (state >= COLLECTD_CPU_STATE_ACTIVE)
return (EINVAL);
cdtime_t now = cdtime ();
#if PROCESSOR_CPU_LOAD_INFO /* {{{ */
- int cpu;
-
kern_return_t status;
processor_cpu_load_info_data_t cpu_info;
host_t cpu_host;
- for (cpu = 0; cpu < cpu_list_len; cpu++)
+ for (mach_msg_type_number_t cpu = 0; cpu < cpu_list_len; cpu++)
{
cpu_host = 0;
cpu_info_len = PROCESSOR_BASIC_INFO_COUNT;
/* }}} #endif defined(KERNEL_LINUX) */
#elif defined(HAVE_LIBKSTAT) /* {{{ */
- int cpu;
static cpu_stat_t cs;
if (kc == NULL)
return (-1);
- for (cpu = 0; cpu < numcpu; cpu++)
+ for (int cpu = 0; cpu < numcpu; cpu++)
{
if (kstat_read (kc, ksp[cpu], &cs) == -1)
continue; /* error message? */
uint64_t cpuinfo[numcpu][CPUSTATES];
size_t cpuinfo_size;
int status;
- int i;
if (numcpu < 1)
{
#if defined(KERN_CPTIME2)
if (numcpu > 1) {
- for (i = 0; i < numcpu; i++) {
+ for (int i = 0; i < numcpu; i++) {
int mib[] = {CTL_KERN, KERN_CPTIME2, i};
cpuinfo_size = sizeof (cpuinfo[0]);
return (-1);
}
- for(i = 0; i < CPUSTATES; i++) {
+ for(int i = 0; i < CPUSTATES; i++) {
cpuinfo[0][i] = cpuinfo_tmp[i];
}
}
- for (i = 0; i < numcpu; i++) {
+ for (int i = 0; i < numcpu; i++) {
cpu_stage (i, COLLECTD_CPU_STATE_USER, (derive_t) cpuinfo[i][CP_USER], now);
cpu_stage (i, COLLECTD_CPU_STATE_NICE, (derive_t) cpuinfo[i][CP_NICE], now);
cpu_stage (i, COLLECTD_CPU_STATE_SYSTEM, (derive_t) cpuinfo[i][CP_SYS], now);
#elif defined(HAVE_SYSCTLBYNAME) && defined(HAVE_SYSCTL_KERN_CP_TIMES) /* {{{ */
long cpuinfo[maxcpu][CPUSTATES];
size_t cpuinfo_size;
- int i;
memset (cpuinfo, 0, sizeof (cpuinfo));
return (-1);
}
- for (i = 0; i < numcpu; i++) {
+ for (int i = 0; i < numcpu; i++) {
cpu_stage (i, COLLECTD_CPU_STATE_USER, (derive_t) cpuinfo[i][CP_USER], now);
cpu_stage (i, COLLECTD_CPU_STATE_NICE, (derive_t) cpuinfo[i][CP_NICE], now);
cpu_stage (i, COLLECTD_CPU_STATE_SYSTEM, (derive_t) cpuinfo[i][CP_SYS], now);
#elif defined(HAVE_PERFSTAT) /* {{{ */
perfstat_id_t id;
- int i, cpus;
+ int cpus;
numcpu = perfstat_cpu(NULL, NULL, sizeof(perfstat_cpu_t), 0);
if(numcpu == -1)
return (-1);
}
- for (i = 0; i < cpus; i++)
+ for (int i = 0; i < cpus; i++)
{
cpu_stage (i, COLLECTD_CPU_STATE_IDLE, (derive_t) perfcpu[i].idle, now);
cpu_stage (i, COLLECTD_CPU_STATE_SYSTEM, (derive_t) perfcpu[i].sys, now);
**/
#include "collectd.h"
+
#include "common.h"
#include "plugin.h"
-#define MODULE_NAME "cpufreq"
-
static int num_cpu = 0;
static int cpufreq_init (void)
return (0);
} /* int cpufreq_init */
-static void cpufreq_submit (int cpu_num, double value)
+static void cpufreq_submit (int cpu_num, value_t value)
{
- value_t values[1];
value_list_t vl = VALUE_LIST_INIT;
- values[0].gauge = value;
-
- vl.values = values;
+ vl.values = &value;
vl.values_len = 1;
sstrncpy (vl.host, hostname_g, sizeof (vl.host));
sstrncpy (vl.plugin, "cpufreq", sizeof (vl.plugin));
sstrncpy (vl.type, "cpufreq", sizeof (vl.type));
- ssnprintf (vl.type_instance, sizeof (vl.type_instance),
- "%i", cpu_num);
+ ssnprintf (vl.type_instance, sizeof (vl.type_instance), "%i", cpu_num);
plugin_dispatch_values (&vl);
}
static int cpufreq_read (void)
{
- int status;
- unsigned long long val;
- int i = 0;
- FILE *fp;
- char filename[256];
- char buffer[16];
-
- for (i = 0; i < num_cpu; i++)
+ for (int i = 0; i < num_cpu; i++)
{
- status = ssnprintf (filename, sizeof (filename),
- "/sys/devices/system/cpu/cpu%d/cpufreq/"
- "scaling_cur_freq", i);
- if ((status < 1) || ((unsigned int)status >= sizeof (filename)))
- return (-1);
-
- if ((fp = fopen (filename, "r")) == NULL)
- {
- char errbuf[1024];
- WARNING ("cpufreq: fopen (%s): %s", filename,
- sstrerror (errno, errbuf,
- sizeof (errbuf)));
- return (-1);
- }
+ char filename[PATH_MAX];
+ ssnprintf (filename, sizeof (filename),
+ "/sys/devices/system/cpu/cpu%d/cpufreq/scaling_cur_freq", i);
- if (fgets (buffer, 16, fp) == NULL)
+ value_t v;
+ if (parse_value_file (filename, &v, DS_TYPE_GAUGE) != 0)
{
- char errbuf[1024];
- WARNING ("cpufreq: fgets: %s",
- sstrerror (errno, errbuf,
- sizeof (errbuf)));
- fclose (fp);
- return (-1);
+ WARNING ("cpufreq plugin: Reading \"%s\" failed.", filename);
+ continue;
}
- if (fclose (fp))
- {
- char errbuf[1024];
- WARNING ("cpufreq: fclose: %s",
- sstrerror (errno, errbuf,
- sizeof (errbuf)));
- }
-
-
- /* You're seeing correctly: The file is reporting kHz values.. */
- val = atoll (buffer) * 1000;
+ /* convert kHz to Hz */
+ v.gauge *= 1000.0;
- cpufreq_submit (i, val);
+ cpufreq_submit (i, v);
}
return (0);
--- /dev/null
+/**
+ * collectd - src/cpusleep.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 <http://github.com/rinigus>
+ *
+ * CPU sleep is reported in milliseconds of sleep per second of wall
+ * time. For that, the time difference between BOOT and MONOTONIC clocks
+ * is reported using derive type.
+**/
+
+#include "collectd.h"
+
+#include "common.h"
+#include "plugin.h"
+#include <time.h>
+
+static void cpusleep_submit(derive_t cpu_sleep) {
+ value_list_t vl = VALUE_LIST_INIT;
+
+ vl.values = &(value_t) { .derive = cpu_sleep };
+ vl.values_len = 1;
+ sstrncpy(vl.host, hostname_g, sizeof(vl.host));
+ sstrncpy(vl.plugin, "cpusleep", sizeof(vl.plugin));
+ sstrncpy(vl.type, "total_time_in_ms", sizeof(vl.type));
+
+ plugin_dispatch_values(&vl);
+}
+
+static int cpusleep_read(void) {
+ struct timespec b, m;
+ if (clock_gettime(CLOCK_BOOTTIME, &b) < 0) {
+ ERROR("cpusleep plugin: clock_boottime failed");
+ return (-1);
+ }
+
+ if (clock_gettime(CLOCK_MONOTONIC, &m) < 0) {
+ ERROR("cpusleep plugin: clock_monotonic failed");
+ return (-1);
+ }
+
+ // to avoid false positives in counter overflow due to reboot,
+ // derive is used. Sleep is calculated in milliseconds
+ derive_t diffsec = b.tv_sec - m.tv_sec;
+ derive_t diffnsec = b.tv_nsec - m.tv_nsec;
+ derive_t sleep = diffsec * 1000 + diffnsec / 1000000;
+
+ cpusleep_submit(sleep);
+
+ return (0);
+}
+
+void module_register(void) {
+ plugin_register_read("cpusleep", cpusleep_read);
+} /* void module_register */
PyGILState_Release(gil_state);\
}
-/* Python 2.4 has this macro, older versions do not. */
-#ifndef Py_VISIT
-#define Py_VISIT(o) do {\
- int _vret;\
- if ((o) != NULL) {\
- _vret = visit((o), arg);\
- if (_vret != 0)\
- return _vret;\
- }\
-} while (0)
-#endif
-
-/* Python 2.4 has this macro, older versions do not. */
-#ifndef Py_CLEAR
-#define Py_CLEAR(o) do {\
- PyObject *tmp = o;\
- (o) = NULL;\
- Py_XDECREF(tmp);\
-} while (0)
-#endif
-
-/* Python 2.4 has this macro, older versions do not. */
-#ifndef Py_RETURN_NONE
-# define Py_RETURN_NONE return Py_INCREF(Py_None), Py_None
-#endif
-
/* This macro is a shortcut for calls like
* x = PyObject_Repr(x);
* This can't be done like this example because this would leak
PyObject *values; /* Sequence */
PyObject *children; /* Sequence */
} Config;
-PyTypeObject ConfigType;
+extern PyTypeObject ConfigType;
typedef struct {
PyObject_HEAD /* No semicolon! */
char type[DATA_MAX_NAME_LEN];
char type_instance[DATA_MAX_NAME_LEN];
} PluginData;
-PyTypeObject PluginDataType;
+extern PyTypeObject PluginDataType;
#define PluginData_New() PyObject_CallFunctionObjArgs((PyObject *) &PluginDataType, (void *) 0)
typedef struct {
PyObject *meta; /* dict */
double interval;
} Values;
-PyTypeObject ValuesType;
+extern PyTypeObject ValuesType;
#define Values_New() PyObject_CallFunctionObjArgs((PyObject *) &ValuesType, (void *) 0)
typedef struct {
int severity;
char message[NOTIF_MAX_MSG_LEN];
} Notification;
-PyTypeObject NotificationType;
+extern PyTypeObject NotificationType;
#define Notification_New() PyObject_CallFunctionObjArgs((PyObject *) &NotificationType, (void *) 0)
typedef PyLongObject Signed;
-PyTypeObject SignedType;
+extern PyTypeObject SignedType;
typedef PyLongObject Unsigned;
-PyTypeObject UnsignedType;
+extern PyTypeObject UnsignedType;
**/
#include "collectd.h"
+
#include "plugin.h"
#include "common.h"
#include "utils_cache.h"
{
int offset;
int status;
- size_t i;
gauge_t *rates = NULL;
assert (0 == strcmp (ds->type, vl->type));
return (-1);
offset = status;
- for (i = 0; i < ds->ds_num; i++)
+ for (size_t i = 0; i < ds->ds_num; i++)
{
if ((ds->ds[i].type != DS_TYPE_COUNTER)
&& (ds->ds[i].type != DS_TYPE_GAUGE)
static int csv_create_file (const char *filename, const data_set_t *ds)
{
FILE *csv;
- size_t i;
if (check_create_dir (filename))
return (-1);
}
fprintf (csv, "epoch");
- for (i = 0; i < ds->ds_num; i++)
+ for (size_t i = 0; i < ds->ds_num; i++)
fprintf (csv, ",%s", ds->ds[i].name);
fprintf (csv, "\n");
char values[4096];
FILE *csv;
int csv_fd;
- struct flock fl;
+ struct flock fl = { 0 };
int status;
if (0 != strcmp (ds->type, vl->type)) {
if (use_stdio)
{
- size_t i;
-
escape_string (filename, sizeof (filename));
/* Replace commas by colons for PUTVAL compatible output. */
- for (i = 0; i < sizeof (values); i++)
+ for (size_t i = 0; i < sizeof (values); i++)
{
if (values[i] == 0)
break;
}
csv_fd = fileno (csv);
- memset (&fl, '\0', sizeof (fl));
- fl.l_start = 0;
- fl.l_len = 0; /* till end of file */
fl.l_pid = getpid ();
fl.l_type = F_WRLCK;
fl.l_whence = SEEK_SET;
**/
#include "collectd.h"
+
#include "common.h"
#include "plugin.h"
-#include "configfile.h"
#include "utils_curl_stats.h"
#include "utils_match.h"
#include "utils_time.h"
{
web_match_t *match;
int status;
- int i;
if (ci->values_num != 0)
{
}
status = 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;
{
web_page_t *page;
int status;
- int i;
if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING))
{
/* Process all children */
status = 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;
int success;
int errors;
int status;
- int i;
success = 0;
errors = 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;
} /* }}} int cc_init */
static void cc_submit (const web_page_t *wp, const web_match_t *wm, /* {{{ */
- const cu_match_value_t *mv)
+ value_t value)
{
- value_t values[1];
value_list_t vl = VALUE_LIST_INIT;
- values[0] = mv->value;
-
- vl.values = values;
+ vl.values = &value;
vl.values_len = 1;
sstrncpy (vl.host, hostname_g, sizeof (vl.host));
sstrncpy (vl.plugin, "curl", sizeof (vl.plugin));
static void cc_submit_response_code (const web_page_t *wp, long code) /* {{{ */
{
- value_t values[1];
value_list_t vl = VALUE_LIST_INIT;
- values[0].gauge = code;
-
- vl.values = values;
+ vl.values = &(value_t) { .gauge = (gauge_t) code };
vl.values_len = 1;
sstrncpy (vl.host, hostname_g, sizeof (vl.host));
sstrncpy (vl.plugin, "curl", sizeof (vl.plugin));
static void cc_submit_response_time (const web_page_t *wp, /* {{{ */
cdtime_t response_time)
{
- value_t values[1];
value_list_t vl = VALUE_LIST_INIT;
- values[0].gauge = CDTIME_T_TO_DOUBLE (response_time);
-
- vl.values = values;
+ vl.values = &(value_t) { .gauge = CDTIME_T_TO_DOUBLE (response_time) };
vl.values_len = 1;
sstrncpy (vl.host, hostname_g, sizeof (vl.host));
sstrncpy (vl.plugin, "curl", sizeof (vl.plugin));
static int cc_read_page (web_page_t *wp) /* {{{ */
{
- web_match_t *wm;
int status;
cdtime_t start = 0;
}
}
- for (wm = wp->matches; wm != NULL; wm = wm->next)
+ for (web_match_t *wm = wp->matches; wm != NULL; wm = wm->next)
{
cu_match_value_t *mv;
continue;
}
- cc_submit (wp, wm, mv);
+ cc_submit (wp, wm, mv->value);
match_value_reset (mv);
} /* for (wm = wp->matches; wm != NULL; wm = wm->next) */
static int cc_read (void) /* {{{ */
{
- web_page_t *wp;
-
- for (wp = pages_g; wp != NULL; wp = wp->next)
+ for (web_page_t *wp = pages_g; wp != NULL; wp = wp->next)
cc_read_page (wp);
return (0);
**/
#include "collectd.h"
+
#include "common.h"
#include "plugin.h"
-#include "configfile.h"
#include "utils_avltree.h"
#include "utils_complain.h"
#include "utils_curl_stats.h"
{
const data_set_t *ds;
+ if ((key == NULL) || !CJ_IS_KEY (key))
+ return -EINVAL;
+
ds = plugin_get_ds (key->type);
if (ds == NULL)
{
buffer[sizeof (buffer) - 1] = 0;
if ((key == NULL) || !CJ_IS_KEY (key)) {
- if (key != NULL && !db->state[db->depth].in_array/*can be inhomogeneous*/)
+ if (key != NULL && !db->state[db->depth].in_array/*can be inhomogeneous*/) {
NOTICE ("curl_json plugin: Found \"%s\", but the configuration expects"
" a map.", buffer);
+ return (CJ_CB_CONTINUE);
+ }
+
cj_cb_inc_array_index (ctx, /* update_key = */ 1);
key = db->state[db->depth].key;
- if (key == NULL) {
+ if ((key == NULL) || !CJ_IS_KEY (key)) {
return (CJ_CB_CONTINUE);
}
}
{
cj_key_t *key;
int status;
- int i;
if ((ci->values_num != 1)
|| (ci->values[0].type != OCONFIG_TYPE_STRING))
}
status = 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;
{
cj_t *db;
int status = 0;
- int i;
if ((ci->values_num != 1)
|| (ci->values[0].type != OCONFIG_TYPE_STRING))
}
/* Fill the `cj_t' structure.. */
- 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 all went well, register this database for reading */
if (status == 0)
{
- user_data_t ud;
char *cb_name;
if (db->instance == NULL)
DEBUG ("curl_json plugin: Registering new read callback: %s",
db->instance);
- memset (&ud, 0, sizeof (ud));
- ud.data = (void *) db;
- ud.free_func = cj_free;
-
cb_name = ssnprintf_alloc ("curl_json-%s-%s",
db->instance, db->url ? db->url : db->sock);
plugin_register_complex_read (/* group = */ NULL, cb_name, cj_read,
/* interval = */ db->interval,
- &ud);
+ &(user_data_t) {
+ .data = db,
+ .free_func = cj_free,
+ });
sfree (cb_name);
}
else
int success;
int errors;
int status;
- int i;
success = 0;
errors = 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;
if (key->instance == NULL)
{
- int i, len = 0;
- for (i = 0; i < db->depth; i++)
+ int len = 0;
+ for (int i = 0; i < db->depth; i++)
len += ssnprintf(vl.type_instance+len, sizeof(vl.type_instance)-len,
i ? "-%s" : "%s", db->state[i+1].name);
}
**/
#include "collectd.h"
+
#include "common.h"
#include "plugin.h"
-#include "configfile.h"
#include "utils_curl_stats.h"
#include "utils_llist.h"
static void cx_free (void *arg) /* {{{ */
{
cx_t *db;
- size_t i;
DEBUG ("curl_xml plugin: cx_free (arg = %p);", arg);
curl_slist_free_all (db->headers);
curl_stats_destroy (db->stats);
- for (i = 0; i < db->namespaces_num; i++)
+ for (size_t i = 0; i < db->namespaces_num; i++)
{
sfree (db->namespaces[i].prefix);
sfree (db->namespaces[i].url);
{
value_t values[xpath->values_len];
int status;
- size_t i;
assert (xpath->values_len > 0);
assert (xpath->values_len == vl->values_len);
assert (xpath->values_len == ds->ds_num);
vl->values = values;
- for (i = 0; i < xpath->values_len; i++)
+ for (size_t i = 0; i < xpath->values_len; i++)
{
status = cx_handle_single_value_xpath (xpath_ctx, xpath, ds, vl, i);
if (status != 0)
char *base_xpath, cx_xpath_t *xpath)
{
int total_nodes;
- int i;
xmlXPathObjectPtr base_node_obj = NULL;
xmlNodeSetPtr base_nodes = NULL;
if (plugin_instance != NULL)
sstrncpy (vl.plugin_instance, plugin_instance, sizeof (vl.plugin_instance));
- for (i = 0; i < total_nodes; i++)
+ for (int i = 0; i < total_nodes; i++)
{
int status;
int status;
xmlDocPtr doc;
xmlXPathContextPtr xpath_ctx;
- size_t i;
/* Load the XML */
doc = xmlParseDoc(xml);
return (-1);
}
- for (i = 0; i < db->namespaces_num; i++)
+ for (size_t i = 0; i < db->namespaces_num; i++)
{
cx_namespace_t const *ns = db->namespaces + i;
status = xmlXPathRegisterNs (xpath_ctx,
static int cx_config_add_values (const char *name, cx_xpath_t *xpath, /* {{{ */
oconfig_item_t *ci)
{
- int i;
-
if (ci->values_num < 1)
{
WARNING ("curl_xml plugin: `ValuesFrom' needs at least one argument.");
return (-1);
}
- for (i = 0; i < ci->values_num; i++)
+ for (int i = 0; i < ci->values_num; i++)
if (ci->values[i].type != OCONFIG_TYPE_STRING)
{
WARNING ("curl_xml plugin: `ValuesFrom' needs only string argument.");
xpath->values_len = (size_t) ci->values_num;
/* populate cx_values_t structure */
- for (i = 0; i < ci->values_num; i++)
+ for (int i = 0; i < ci->values_num; i++)
{
xpath->values[i].path_len = sizeof (ci->values[i].value.string);
sstrncpy (xpath->values[i].path, ci->values[i].value.string, sizeof (xpath->values[i].path));
char *name;
llentry_t *le;
int status;
- int i;
xpath = calloc (1, sizeof (*xpath));
if (xpath == NULL)
}
status = 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;
{
cx_t *db;
int status = 0;
- int i;
if ((ci->values_num != 1)
|| (ci->values[0].type != OCONFIG_TYPE_STRING))
}
/* Fill the `cx_t' structure.. */
- 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 all went well, register this database for reading */
if (status == 0)
{
- user_data_t ud;
char *cb_name;
if (db->instance == NULL)
DEBUG ("curl_xml plugin: Registering new read callback: %s",
db->instance);
- memset (&ud, 0, sizeof (ud));
- ud.data = (void *) db;
- ud.free_func = cx_free;
-
cb_name = ssnprintf_alloc ("curl_xml-%s-%s", db->instance, db->url);
+
plugin_register_complex_read (/* group = */ "curl_xml", cb_name, cx_read,
- /* interval = */ 0, &ud);
+ /* interval = */ 0,
+ &(user_data_t) {
+ .data = db,
+ .free_func = cx_free,
+ });
sfree (cb_name);
}
else
int success;
int errors;
int status;
- int i;
success = 0;
errors = 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;
**/
#include "collectd.h"
-#include "common.h"
+#include "common.h"
#include "plugin.h"
#include "configfile.h"
{
const char *str;
- struct addrinfo ai_hints;
struct addrinfo *ai_list;
- struct addrinfo *ai_ptr;
int status;
str = global_option_get ("Hostname");
if (IS_FALSE (str))
return (0);
- memset (&ai_hints, '\0', sizeof (ai_hints));
- ai_hints.ai_flags = AI_CANONNAME;
+ struct addrinfo ai_hints = {
+ .ai_flags = AI_CANONNAME
+ };
status = getaddrinfo (hostname_g, NULL, &ai_hints, &ai_list);
if (status != 0)
return (-1);
}
- for (ai_ptr = ai_list; ai_ptr != NULL; ai_ptr = ai_ptr->ai_next)
+ for (struct addrinfo *ai_ptr = ai_list; ai_ptr != NULL; ai_ptr = ai_ptr->ai_next)
{
if (ai_ptr->ai_canonname == NULL)
continue;
{
int fd;
const char *notifysocket;
- struct sockaddr_un su;
+ struct sockaddr_un su = { 0 };
size_t su_size;
char buffer[] = "READY=1\n";
return 0;
}
- memset (&su, 0, sizeof (su));
su.sun_family = AF_UNIX;
if (notifysocket[0] != '@')
{
int main (int argc, char **argv)
{
- struct sigaction sig_int_action;
- struct sigaction sig_term_action;
- struct sigaction sig_usr1_action;
- struct sigaction sig_pipe_action;
const char *configfile = CONFIGFILE;
int test_config = 0;
int test_readall = 0;
const char *basedir;
#if COLLECT_DAEMON
- struct sigaction sig_chld_action;
pid_t pid;
int daemonize = 1;
#endif
/*
* fork off child
*/
- memset (&sig_chld_action, '\0', sizeof (sig_chld_action));
- sig_chld_action.sa_handler = SIG_IGN;
+ struct sigaction sig_chld_action = {
+ .sa_handler = SIG_IGN
+ };
+
sigaction (SIGCHLD, &sig_chld_action, NULL);
/*
} /* if (daemonize) */
#endif /* COLLECT_DAEMON */
- memset (&sig_pipe_action, '\0', sizeof (sig_pipe_action));
- sig_pipe_action.sa_handler = SIG_IGN;
+ struct sigaction sig_pipe_action = {
+ .sa_handler = SIG_IGN
+ };
+
sigaction (SIGPIPE, &sig_pipe_action, NULL);
/*
* install signal handlers
*/
- memset (&sig_int_action, '\0', sizeof (sig_int_action));
- sig_int_action.sa_handler = sig_int_handler;
+ struct sigaction sig_int_action = {
+ .sa_handler = sig_int_handler
+ };
+
if (0 != sigaction (SIGINT, &sig_int_action, NULL)) {
char errbuf[1024];
ERROR ("Error: Failed to install a signal handler for signal INT: %s",
return (1);
}
- memset (&sig_term_action, '\0', sizeof (sig_term_action));
- sig_term_action.sa_handler = sig_term_handler;
+ struct sigaction sig_term_action = {
+ .sa_handler = sig_term_handler
+ };
+
if (0 != sigaction (SIGTERM, &sig_term_action, NULL)) {
char errbuf[1024];
ERROR ("Error: Failed to install a signal handler for signal TERM: %s",
return (1);
}
- memset (&sig_usr1_action, '\0', sizeof (sig_usr1_action));
- sig_usr1_action.sa_handler = sig_usr1_handler;
+ struct sigaction sig_usr1_action = {
+ .sa_handler = sig_usr1_handler
+ };
+
if (0 != sigaction (SIGUSR1, &sig_usr1_action, NULL)) {
char errbuf[1024];
ERROR ("Error: Failed to install a signal handler for signal USR1: %s",
#endif
#include "collectd.h"
+
#include "common.h"
#include "plugin.h"
#include "utils_cache.h"
# include <netinet/in.h>
#endif
+#if HAVE_NETINET_TCP_H
+# include <netinet/tcp.h>
+#endif
+
/* for ntohl and htonl */
#if HAVE_ARPA_INET_H
# include <arpa/inet.h>
#endif
+#ifdef HAVE_SYS_CAPABILITY_H
+# include <sys/capability.h>
+#endif
+
#ifdef HAVE_LIBKSTAT
extern kstat_ctl_t *kc;
#endif
return ((int) i);
}
-int strjoin (char *buffer, size_t buffer_size,
- char **fields, size_t fields_num,
- const char *sep)
-{
- size_t avail;
- char *ptr;
- size_t sep_len;
- size_t i;
+int strjoin(char *buffer, size_t buffer_size, char **fields, size_t fields_num,
+ const char *sep) {
+ size_t avail = 0;
+ char *ptr = buffer;
+ size_t sep_len = 0;
- if ((buffer_size < 1) || (fields_num == 0))
- return (-1);
+ size_t buffer_req = 0;
- memset (buffer, 0, buffer_size);
- ptr = buffer;
- avail = buffer_size - 1;
+ if (((fields_num != 0) && (fields == NULL)) ||
+ ((buffer_size != 0) && (buffer == NULL)))
+ return (-EINVAL);
- sep_len = 0;
- if (sep != NULL)
- sep_len = strlen (sep);
+ if (buffer != NULL)
+ buffer[0] = 0;
- for (i = 0; i < fields_num; i++)
- {
- size_t field_len;
+ if (buffer_size != 0)
+ avail = buffer_size - 1;
- if ((i > 0) && (sep_len > 0))
- {
- if (avail < sep_len)
- return (-1);
+ if (sep != NULL)
+ sep_len = strlen(sep);
- memcpy (ptr, sep, sep_len);
- ptr += sep_len;
- avail -= sep_len;
- }
+ for (size_t i = 0; i < fields_num; i++) {
+ size_t field_len = strlen(fields[i]);
- field_len = strlen (fields[i]);
- if (avail < field_len)
- return (-1);
+ if (i != 0)
+ buffer_req += sep_len;
+ buffer_req += field_len;
- memcpy (ptr, fields[i], field_len);
- ptr += field_len;
- avail -= field_len;
- }
+ if ((i != 0) && (sep_len > 0)) {
+ if (sep_len >= avail) {
+ /* prevent subsequent iterations from writing to the
+ * buffer. */
+ avail = 0;
+ continue;
+ }
+
+ memcpy(ptr, sep, sep_len);
+
+ ptr += sep_len;
+ avail -= sep_len;
+ }
+
+ if (field_len > avail)
+ field_len = avail;
+
+ memcpy(ptr, fields[i], field_len);
+ ptr += field_len;
+
+ avail -= field_len;
+ if (ptr != NULL)
+ *ptr = 0;
+ }
- assert (buffer[buffer_size - 1] == 0);
- return ((int) strlen (buffer));
+ return (int)buffer_req;
}
int escape_string (char *buffer, size_t buffer_size)
{
char *temp;
- size_t i;
size_t j;
/* Check if we need to escape at all first */
temp[0] = '"';
j = 1;
- for (i = 0; i < buffer_size; i++)
+ for (size_t i = 0; i < buffer_size; i++)
{
if (buffer[i] == 0)
{
int strunescape (char *buf, size_t buf_len)
{
- size_t i;
-
- for (i = 0; (i < buf_len) && (buf[i] != '\0'); ++i)
+ for (size_t i = 0; (i < buf_len) && (buf[i] != '\0'); ++i)
{
if (buf[i] != '\\')
continue;
int escape_slashes (char *buffer, size_t buffer_size)
{
size_t buffer_len;
- size_t i;
buffer_len = strlen (buffer);
buffer_len--;
}
- for (i = 0; i < buffer_len; i++)
+ for (size_t i = 0; i < buffer_len; i++)
{
if (buffer[i] == '/')
buffer[i] = '_';
void replace_special (char *buffer, size_t buffer_size)
{
- size_t i;
-
- for (i = 0; i < buffer_size; i++)
+ for (size_t i = 0; i < buffer_size; i++)
{
if (buffer[i] == 0)
return;
int last_is_file = 1;
int path_is_absolute = 0;
size_t len;
- int i;
/*
* Sanity checks first
/*
* For each component, do..
*/
- for (i = 0; i < (fields_num - last_is_file); i++)
+ for (int i = 0; i < (fields_num - last_is_file); i++)
{
/*
* Do not create directories that start with a dot. This
{
size_t offset = 0;
int status;
- size_t i;
gauge_t *rates = NULL;
assert (0 == strcmp (ds->type, vl->type));
BUFFER_ADD ("%.3f", CDTIME_T_TO_DOUBLE (vl->time));
- for (i = 0; i < ds->ds_num; i++)
+ for (size_t i = 0; i < ds->ds_num; i++)
{
if (ds->ds[i].type == DS_TYPE_GAUGE)
BUFFER_ADD (":"GAUGE_FORMAT, vl->values[i].gauge);
return (0);
} /* int parse_values */
+int parse_value_file (char const *path, value_t *ret_value, int ds_type)
+{
+ FILE *fh;
+ char buffer[256];
+
+ fh = fopen (path, "r");
+ if (fh == NULL)
+ return (-1);
+
+ if (fgets (buffer, sizeof (buffer), fh) == NULL)
+ {
+ fclose (fh);
+ return (-1);
+ }
+
+ fclose (fh);
+
+ strstripnewline (buffer);
+
+ return parse_value (buffer, ret_value, ds_type);
+} /* int parse_value_file */
+
#if !HAVE_GETPWNAM_R
int getpwnam_r (const char *name, struct passwd *pwbuf, char *buf,
size_t buflen, struct passwd **pwbufp)
int service_name_to_port_number (const char *service_name)
{
struct addrinfo *ai_list;
- struct addrinfo *ai_ptr;
- struct addrinfo ai_hints;
int status;
int service_number;
if (service_name == NULL)
return (-1);
- ai_list = NULL;
- memset (&ai_hints, 0, sizeof (ai_hints));
- ai_hints.ai_family = AF_UNSPEC;
+ struct addrinfo ai_hints = {
+ .ai_family = AF_UNSPEC
+ };
status = getaddrinfo (/* node = */ NULL, service_name,
&ai_hints, &ai_list);
}
service_number = -1;
- for (ai_ptr = ai_list; ai_ptr != NULL; ai_ptr = ai_ptr->ai_next)
+ for (struct addrinfo *ai_ptr = ai_list; ai_ptr != NULL; ai_ptr = ai_ptr->ai_next)
{
if (ai_ptr->ai_family == AF_INET)
{
return (-1);
} /* int service_name_to_port_number */
+void set_sock_opts (int sockfd) /* {{{ */
+{
+ int status;
+ int socktype;
+
+ socklen_t socklen = sizeof (socklen_t);
+ int so_keepalive = 1;
+
+ status = getsockopt (sockfd, SOL_SOCKET, SO_TYPE, &socktype, &socklen);
+ if (status != 0)
+ {
+ WARNING ("set_sock_opts: failed to determine socket type");
+ return;
+ }
+
+ if (socktype == SOCK_STREAM)
+ {
+ status = setsockopt(sockfd, SOL_SOCKET, SO_KEEPALIVE,
+ &so_keepalive, sizeof (so_keepalive));
+ if (status != 0)
+ WARNING ("set_sock_opts: failed to set socket keepalive flag");
+
+#ifdef TCP_KEEPIDLE
+ int tcp_keepidle = ((CDTIME_T_TO_MS(plugin_get_interval()) - 1) / 100 + 1);
+ status = setsockopt(sockfd, IPPROTO_TCP, TCP_KEEPIDLE,
+ &tcp_keepidle, sizeof (tcp_keepidle));
+ if (status != 0)
+ WARNING ("set_sock_opts: failed to set socket tcp keepalive time");
+#endif
+
+#ifdef TCP_KEEPINTVL
+ int tcp_keepintvl = ((CDTIME_T_TO_MS(plugin_get_interval()) - 1) / 1000 + 1);
+ status = setsockopt(sockfd, IPPROTO_TCP, TCP_KEEPINTVL,
+ &tcp_keepintvl, sizeof (tcp_keepintvl));
+ if (status != 0)
+ WARNING ("set_sock_opts: failed to set socket tcp keepalive interval");
+#endif
+ }
+} /* }}} void set_sock_opts */
+
int strtoderive (const char *string, derive_t *ret_value) /* {{{ */
{
derive_t tmp;
void strarray_free (char **array, size_t array_len) /* {{{ */
{
- size_t i;
-
- for (i = 0; i < array_len; i++)
+ for (size_t i = 0; i < array_len; i++)
sfree (array[i]);
sfree (array);
} /* }}} void strarray_free */
+
+#ifdef HAVE_SYS_CAPABILITY_H
+int check_capability (int capability) /* {{{ */
+{
+#ifdef _LINUX_CAPABILITY_VERSION_3
+ cap_user_header_t cap_header = calloc(1, sizeof (*cap_header));
+ if (cap_header == NULL)
+ {
+ ERROR("check_capability: calloc failed");
+ return (-1);
+ }
+
+ cap_user_data_t cap_data = calloc(1, sizeof (*cap_data));
+ if (cap_data == NULL)
+ {
+ ERROR("check_capability: calloc failed");
+ sfree(cap_header);
+ return (-1);
+ }
+
+ cap_header->pid = getpid();
+ cap_header->version = _LINUX_CAPABILITY_VERSION;
+ if (capget(cap_header, cap_data) < 0)
+ {
+ ERROR("check_capability: capget failed");
+ sfree(cap_header);
+ sfree(cap_data);
+ return (-1);
+ }
+
+ if ((cap_data->effective & (1 << capability)) == 0)
+ {
+ sfree(cap_header);
+ sfree(cap_data);
+ return (-1);
+ }
+ else
+ {
+ sfree(cap_header);
+ sfree(cap_data);
+ return (0);
+ }
+#else
+ WARNING ("check_capability: unsupported capability implementation. "
+ "Some plugin(s) may require elevated privileges to work properly.");
+ return (0);
+#endif /* _LINUX_CAPABILITY_VERSION_3 */
+} /* }}} int check_capability */
+#endif /* HAVE_SYS_CAPABILITY_H */
#define COMMON_H
#include "collectd.h"
+
#include "plugin.h"
#if HAVE_PWD_H
* is equivalent to the Perl built-in `join'.
*
* PARAMETERS
- * `dst' Buffer where the result is stored.
+ * `dst' Buffer where the result is stored. Can be NULL if you need to
+ * determine the required buffer size only.
* `dst_len' Length of the destination buffer. No more than this many
* bytes will be written to the memory pointed to by `dst',
- * including the trailing null-byte.
+ * including the trailing null-byte. Must be zero if dst is
+ * NULL.
* `fields' Array of strings to be joined.
* `fields_num' Number of elements in the `fields' array.
* `sep' String to be inserted between any two elements of `fields'.
* Instead of passing "" (empty string) one can pass NULL.
*
* RETURN VALUE
- * Returns the number of characters in `dst', NOT including the trailing
- * null-byte. If an error occurred (empty array or `dst' too small) a value
- * smaller than zero will be returned.
+ * Returns the number of characters in the resulting string, excluding a
+ * tailing null byte. If this value is greater than or equal to "dst_len", the
+ * result in "dst" is truncated (but still null terminated). On error a
+ * negative value is returned.
*/
int strjoin (char *dst, size_t dst_len, char **fields, size_t fields_num, const char *sep);
int parse_value (const char *value, value_t *ret_value, int ds_type);
int parse_values (char *buffer, value_list_t *vl, const data_set_t *ds);
+/* parse_value_file reads "path" and parses its content as an integer or
+ * floating point, depending on "ds_type". On success, the value is stored in
+ * "ret_value" and zero is returned. On failure, a non-zero value is returned. */
+int parse_value_file (char const *path, value_t *ret_value, int ds_type);
+
#if !HAVE_GETPWNAM_R
int getpwnam_r (const char *name, struct passwd *pwbuf, char *buf,
size_t buflen, struct passwd **pwbufp);
* (in the range [1-65535]). Returns less than zero on error. */
int service_name_to_port_number (const char *service_name);
+/* Sets various, non-default, socket options */
+void set_sock_opts (int sockfd);
+
/** Parse a string to a derive_t value. Returns zero on success or non-zero on
* failure. If failure is returned, ret_value is not touched. */
int strtoderive (const char *string, derive_t *ret_value);
int strarray_add (char ***ret_array, size_t *ret_array_len, char const *str);
void strarray_free (char **array, size_t array_len);
+#ifdef HAVE_SYS_CAPABILITY_H
+/** Check if the current process benefits from the capability passed in
+ * argument. Returns zero if it does, less than zero if it doesn't or on error.
+ * See capabilities(7) for the list of possible capabilities.
+ * */
+int check_capability (int capability);
+#endif /* HAVE_SYS_CAPABILITY_H */
+
#endif /* COMMON_H */
return (0);
}
-DEF_TEST(strjoin)
-{
- char buffer[16];
- char *fields[4];
- int status;
-
- fields[0] = "foo";
- fields[1] = "bar";
- fields[2] = "baz";
- fields[3] = "qux";
-
- status = strjoin (buffer, sizeof (buffer), fields, 2, "!");
- OK(status == 7);
- EXPECT_EQ_STR ("foo!bar", buffer);
-
- status = strjoin (buffer, sizeof (buffer), fields, 1, "!");
- OK(status == 3);
- EXPECT_EQ_STR ("foo", buffer);
-
- status = strjoin (buffer, sizeof (buffer), fields, 0, "!");
- OK(status < 0);
-
- status = strjoin (buffer, sizeof (buffer), fields, 2, "rcht");
- OK(status == 10);
- EXPECT_EQ_STR ("foorchtbar", buffer);
-
- status = strjoin (buffer, sizeof (buffer), fields, 4, "");
- OK(status == 12);
- EXPECT_EQ_STR ("foobarbazqux", buffer);
+DEF_TEST(strjoin) {
+ struct {
+ char **fields;
+ size_t fields_num;
+ char *separator;
+
+ int want_return;
+ char *want_buffer;
+ } cases
+ [] = {
+ /* Normal case. */
+ {(char *[]){"foo", "bar"}, 2, "!", 7, "foo!bar"},
+ /* One field only. */
+ {(char *[]){"foo"}, 1, "!", 3, "foo"},
+ /* No fields at all. */
+ {NULL, 0, "!", 0, ""},
+ /* Longer separator. */
+ {(char *[]){"foo", "bar"}, 2, "rcht", 10, "foorchtbar"},
+ /* Empty separator. */
+ {(char *[]){"foo", "bar"}, 2, "", 6, "foobar"},
+ /* NULL separator. */
+ {(char *[]){"foo", "bar"}, 2, NULL, 6, "foobar"},
+ /* buffer not large enough -> string is truncated. */
+ {(char *[]){"aaaaaa", "bbbbbb", "c!"}, 3, "-", 16, "aaaaaa-bbbbbb-c"},
+ /* buffer not large enough -> last field fills buffer completely. */
+ {(char *[]){"aaaaaaa", "bbbbbbb", "!"}, 3, "-", 17,
+ "aaaaaaa-bbbbbbb"},
+ /* buffer not large enough -> string does *not* end in separator. */
+ {(char *[]){"aaaa", "bbbb", "cccc", "!"}, 4, "-", 16,
+ "aaaa-bbbb-cccc"},
+ /* buffer not large enough -> string does not end with partial
+ separator. */
+ {(char *[]){"aaaaaa", "bbbbbb", "!"}, 3, "+-", 17, "aaaaaa+-bbbbbb"},
+ };
+
+ for (size_t i = 0; i < STATIC_ARRAY_SIZE(cases); i++) {
+ char buffer[16];
+ int status;
- status = strjoin (buffer, sizeof (buffer), fields, 4, "!");
- OK(status == 15);
- EXPECT_EQ_STR ("foo!bar!baz!qux", buffer);
+ memset(buffer, 0xFF, sizeof(buffer));
+ status = strjoin(buffer, sizeof(buffer), cases[i].fields,
+ cases[i].fields_num, cases[i].separator);
+ EXPECT_EQ_INT(cases[i].want_return, status);
+ EXPECT_EQ_STR(cases[i].want_buffer, buffer);
+ }
- fields[0] = "0123";
- fields[1] = "4567";
- fields[2] = "8901";
- fields[3] = "2345";
- status = strjoin (buffer, sizeof (buffer), fields, 4, "-");
- OK(status < 0);
+ /* use (NULL, 0) to determine required buffer size. */
+ EXPECT_EQ_INT(3, strjoin(NULL, 0, (char *[]){"a", "b"}, 2, "-"));
return (0);
}
{"trailing/slash/", "trailing_slash_"},
{"foo//bar", "foo__bar"},
};
- size_t i;
- for (i = 0; i < STATIC_ARRAY_SIZE (cases); i++) {
+ for (size_t i = 0; i < STATIC_ARRAY_SIZE (cases); i++) {
char buffer[32];
strncpy (buffer, cases[i].str, sizeof (buffer));
{"012345 78901234", "\"012345 789012\""},
{"012345 78901\"34", "\"012345 78901\""},
};
- size_t i;
- for (i = 0; i < STATIC_ARRAY_SIZE (cases); i++) {
+ for (size_t i = 0; i < STATIC_ARRAY_SIZE (cases); i++) {
char buffer[16];
strncpy (buffer, cases[i].str, sizeof (buffer));
{"T:42.0", -1, NAN},
};
- size_t i;
- for (i = 0; i < STATIC_ARRAY_SIZE (cases); i++)
+ for (size_t i = 0; i < STATIC_ARRAY_SIZE (cases); i++)
{
data_source_t dsrc = {
.name = "value",
/* 64bit wrap-around. */
{30, 40, DS_TYPE_COUNTER, {.counter = 18446744073709551558ULL}, {.counter = 42}, 10.0},
};
- size_t i;
- for (i = 0; i < STATIC_ARRAY_SIZE (cases); i++) {
+ for (size_t i = 0; i < STATIC_ARRAY_SIZE (cases); i++) {
value_to_rate_state_t state = { cases[i].v0, TIME_T_TO_CDTIME_T (cases[i].t0) };
gauge_t got;
char *key;
char *value;
int ret;
- int i;
+ int i = 0;
if (orig_key == NULL)
return (EINVAL);
static int dispatch_value_typesdb (oconfig_item_t *ci)
{
- int i = 0;
-
assert (strcasecmp (ci->key, "TypesDB") == 0);
cf_default_typesdb = 0;
return (-1);
}
- for (i = 0; i < ci->values_num; ++i)
+ for (int i = 0; i < ci->values_num; ++i)
{
if (OCONFIG_TYPE_STRING != ci->values[i].type) {
WARNING ("configfile: TypesDB: Skipping %i. argument which "
static int dispatch_loadplugin (oconfig_item_t *ci)
{
- int i;
const char *name;
unsigned int flags = 0;
- plugin_ctx_t ctx;
+ plugin_ctx_t ctx = { 0 };
plugin_ctx_t old_ctx;
int ret_val;
name = "virt";
/* default to the global interval set before loading this plugin */
- memset (&ctx, 0, sizeof (ctx));
ctx.interval = cf_get_default_interval ();
ctx.flush_interval = 0;
ctx.flush_timeout = 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;
char buffer[4096];
char *buffer_ptr;
int buffer_free;
- int i;
buffer_ptr = buffer;
buffer_free = sizeof (buffer);
- for (i = 0; i < ci->values_num; i++)
+ for (int i = 0; i < ci->values_num; i++)
{
int status = -1;
static int dispatch_value (oconfig_item_t *ci)
{
int ret = 0;
- int i;
- for (i = 0; i < cf_value_map_num; i++)
+ for (int i = 0; i < cf_value_map_num; i++)
if (strcasecmp (cf_value_map[i].key, ci->key) == 0)
{
ret = cf_value_map[i].func (ci);
break;
}
- for (i = 0; i < cf_global_options_num; i++)
+ for (int i = 0; i < cf_global_options_num; i++)
if (strcasecmp (cf_global_options[i].key, ci->key) == 0)
{
ret = dispatch_global_option (ci);
static int dispatch_block_plugin (oconfig_item_t *ci)
{
- int i;
const char *name;
- cf_complex_callback_t *cb;
-
if (strcasecmp (ci->key, "Plugin") != 0)
return (-1);
if (ci->values_num < 1)
if (IS_TRUE (global_option_get ("AutoLoadPlugin")))
{
- plugin_ctx_t ctx;
+ plugin_ctx_t ctx = { 0 };
plugin_ctx_t old_ctx;
int status;
/* default to the global interval set before loading this plugin */
- memset (&ctx, 0, sizeof (ctx));
ctx.interval = cf_get_default_interval ();
old_ctx = plugin_set_ctx (ctx);
}
/* Check for a complex callback first */
- for (cb = complex_callback_head; cb != NULL; cb = cb->next)
+ for (cf_complex_callback_t *cb = complex_callback_head; cb != NULL; cb = cb->next)
{
if (strcasecmp (name, cb->type) == 0)
{
}
/* Hm, no complex plugin found. Dispatch the values one by one */
- for (i = 0; i < ci->children_num; i++)
+ for (int i = 0; i < ci->children_num; i++)
{
if (ci->children[i].children == NULL)
dispatch_value_plugin (name, ci->children + i);
int offset)
{
oconfig_item_t *temp;
- int i;
assert (offset >= 0);
assert (dst->children_num > offset);
/* Free the memory used by the replaced child. Usually that's the
* `Include "blah"' statement. */
temp = dst->children + offset;
- for (i = 0; i < temp->values_num; i++)
+ for (int i = 0; i < temp->values_num; i++)
{
if (temp->values[i].type == OCONFIG_TYPE_STRING)
{
static int cf_include_all (oconfig_item_t *root, int depth)
{
- int i;
-
- for (i = 0; i < root->children_num; i++)
+ for (int i = 0; i < root->children_num; i++)
{
oconfig_item_t *new;
oconfig_item_t *old;
char *pattern = NULL;
- int j;
-
if (strcasecmp (root->children[i].key, "Include") != 0)
continue;
continue;
}
- for (j = 0; j < old->children_num; ++j)
+ for (int j = 0; j < old->children_num; ++j)
{
oconfig_item_t *child = old->children + j;
char **filenames = NULL;
int filenames_num = 0;
int status;
- int i;
assert (depth < CF_MAX_DEPTH);
" name is too long.",
dir, de->d_name);
closedir (dh);
- for (i = 0; i < filenames_num; ++i)
+ for (int i = 0; i < filenames_num; ++i)
free (filenames[i]);
free (filenames);
free (root);
if (tmp == NULL) {
ERROR ("configfile: realloc failed.");
closedir (dh);
- for (i = 0; i < filenames_num - 1; ++i)
+ for (int i = 0; i < filenames_num - 1; ++i)
free (filenames[i]);
free (filenames);
free (root);
qsort ((void *) filenames, filenames_num, sizeof (*filenames),
cf_compare_string);
- for (i = 0; i < filenames_num; ++i)
+ for (int i = 0; i < filenames_num; ++i)
{
oconfig_item_t *temp;
char *name = filenames[i];
*
* There are two versions of this function: If `wordexp' exists shell wildcards
* will be expanded and the function will include all matches found. If
- * `wordexp' (or, more precisely, it's header file) is not available the
+ * `wordexp' (or, more precisely, its header file) is not available the
* simpler function is used which does not do any such expansion.
*/
#if HAVE_WORDEXP_H
int status;
const char *path_ptr;
wordexp_t we;
- size_t i;
if (depth >= CF_MAX_DEPTH)
{
qsort ((void *) we.we_wordv, we.we_wordc, sizeof (*we.we_wordv),
cf_compare_string);
- for (i = 0; i < we.we_wordc; i++)
+ for (size_t i = 0; i < we.we_wordc; i++)
{
oconfig_item_t *temp;
struct stat statbuf;
int global_option_set (const char *option, const char *value, _Bool from_cli)
{
int i;
-
DEBUG ("option = %s; value = %s;", option, value);
for (i = 0; i < cf_global_options_num; i++)
const char *global_option_get (const char *option)
{
int i;
-
for (i = 0; i < cf_global_options_num; i++)
if (strcasecmp (cf_global_options[i].key, option) == 0)
break;
void cf_unregister (const char *type)
{
- cf_callback_t *this, *prev;
-
- for (prev = NULL, this = first_callback;
+ for (cf_callback_t *prev = NULL, *this = first_callback;
this != NULL;
prev = this, this = this->next)
if (strcasecmp (this->type, type) == 0)
void cf_unregister_complex (const char *type)
{
- cf_complex_callback_t *this, *prev;
-
- for (prev = NULL, this = complex_callback_head;
+ for (cf_complex_callback_t *prev = NULL, *this = complex_callback_head;
this != NULL;
prev = this, this = this->next)
if (strcasecmp (this->type, type) == 0)
int cf_read (const char *filename)
{
oconfig_item_t *conf;
- int i;
int ret = 0;
conf = cf_read_generic (filename, /* pattern = */ NULL, /* depth = */ 0);
return (-1);
}
- for (i = 0; i < conf->children_num; i++)
+ for (int i = 0; i < conf->children_num; i++)
{
if (conf->children[i].children == NULL)
{
#define CONFIGFILE_H
#include "collectd.h"
+
#include "utils_time.h"
#include "liboconfig/oconfig.h"
int global_option_set (const char *option, const char *value, _Bool from_cli);
const char *global_option_get (const char *option);
long global_option_get_long (const char *option, long default_value);
-long global_option_get_long_in_range (const char *option, long default_value, long min, long max);
cdtime_t global_option_get_time (char const *option, cdtime_t default_value);
**/
#include "collectd.h"
+
#include "configfile.h"
#include "plugin.h"
#include "utils_complain.h"
fc_rule_t *rule;
char rule_name[2*DATA_MAX_NAME_LEN] = "Unnamed rule";
int status = 0;
- int i;
if (ci->values_num > 1)
{
ci->values[0].value.string);
}
- for (i = 0; i < ci->children_num; i++)
+ for (int i = 0; i < ci->children_num; i++)
{
oconfig_item_t *option = ci->children + i;
{
fc_chain_t *chain = NULL;
int status = 0;
- int i;
int new_chain = 1;
if ((ci->values_num != 1)
sstrncpy (chain->name, ci->values[0].value.string, sizeof (chain->name));
}
- for (i = 0; i < ci->children_num; i++)
+ for (int i = 0; i < ci->children_num; i++)
{
oconfig_item_t *option = ci->children + i;
static int fc_bit_write_create (const oconfig_item_t *ci, /* {{{ */
void **user_data)
{
- int i;
-
fc_writer_t *plugin_list = NULL;
size_t plugin_list_len = 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;
fc_writer_t *temp;
- int j;
if (strcasecmp ("Plugin", child->key) != 0)
{
continue;
}
- for (j = 0; j < child->values_num; j++)
+ for (int j = 0; j < child->values_num; j++)
{
char *plugin;
static int fc_bit_write_destroy (void **user_data) /* {{{ */
{
fc_writer_t *plugin_list;
- size_t i;
if ((user_data == NULL) || (*user_data == NULL))
return (0);
plugin_list = *user_data;
- for (i = 0; plugin_list[i].plugin != NULL; i++)
+ for (size_t i = 0; plugin_list[i].plugin != NULL; i++)
free (plugin_list[i].plugin);
free (plugin_list);
}
else
{
- size_t i;
-
- for (i = 0; plugin_list[i].plugin != NULL; i++)
+ for (size_t i = 0; plugin_list[i].plugin != NULL; i++)
{
status = plugin_write (plugin_list[i].plugin, ds, vl);
if (status != 0)
static int fc_init_once (void) /* {{{ */
{
static int done = 0;
- target_proc_t tproc;
+ target_proc_t tproc = { 0 };
if (done != 0)
return (0);
- memset (&tproc, 0, sizeof (tproc));
tproc.create = fc_bit_jump_create;
tproc.destroy = fc_bit_jump_destroy;
tproc.invoke = fc_bit_jump_invoke;
fc_chain_t *fc_chain_get_by_name (const char *chain_name) /* {{{ */
{
- fc_chain_t *chain;
-
if (chain_name == NULL)
return (NULL);
- for (chain = chain_list_head; chain != NULL; chain = chain->next)
+ for (fc_chain_t *chain = chain_list_head; chain != NULL; chain = chain->next)
if (strcasecmp (chain_name, chain->name) == 0)
return (chain);
int fc_process_chain (const data_set_t *ds, value_list_t *vl, /* {{{ */
fc_chain_t *chain)
{
- fc_rule_t *rule;
fc_target_t *target;
int status = FC_TARGET_CONTINUE;
DEBUG ("fc_process_chain (chain = %s);", chain->name);
- for (rule = chain->rules; rule != NULL; rule = rule->next)
+ for (fc_rule_t *rule = chain->rules; rule != NULL; rule = rule->next)
{
fc_match_t *match;
status = FC_TARGET_CONTINUE;
#define FILTER_CHAIN_H 1
#include "collectd.h"
+
#include "plugin.h"
#define FC_MATCH_NO_MATCH 0
**/
#include "collectd.h"
+
+#include "common.h"
#include "plugin.h"
#include "meta_data.h"
+#define MD_MAX_NONSTRING_CHARS 128
+
/*
* Data types
*/
int meta_data_clone_merge (meta_data_t **dest, meta_data_t *orig) /* {{{ */
{
- meta_entry_t *e;
-
if (orig == NULL)
return (0);
}
pthread_mutex_lock (&orig->lock);
- for (e=orig->head; e != NULL; e = e->next)
+ for (meta_entry_t *e=orig->head; e != NULL; e = e->next)
{
md_entry_insert_clone((*dest), e);
}
int meta_data_exists (meta_data_t *md, const char *key) /* {{{ */
{
- meta_entry_t *e;
-
if ((md == NULL) || (key == NULL))
return (-EINVAL);
pthread_mutex_lock (&md->lock);
- for (e = md->head; e != NULL; e = e->next)
+ for (meta_entry_t *e = md->head; e != NULL; e = e->next)
{
if (strcasecmp (key, e->key) == 0)
{
int meta_data_type (meta_data_t *md, const char *key) /* {{{ */
{
- meta_entry_t *e;
-
if ((md == NULL) || (key == NULL))
return -EINVAL;
pthread_mutex_lock (&md->lock);
- for (e = md->head; e != NULL; e = e->next)
+ for (meta_entry_t *e = md->head; e != NULL; e = e->next)
{
if (strcasecmp (key, e->key) == 0)
{
int meta_data_toc (meta_data_t *md, char ***toc) /* {{{ */
{
int i = 0, count = 0;
- meta_entry_t *e;
if ((md == NULL) || (toc == NULL))
return -EINVAL;
pthread_mutex_lock (&md->lock);
- for (e = md->head; e != NULL; e = e->next)
+ for (meta_entry_t *e = md->head; e != NULL; e = e->next)
++count;
if (count == 0)
}
*toc = calloc(count, sizeof(**toc));
- for (e = md->head; e != NULL; e = e->next)
+ for (meta_entry_t *e = md->head; e != NULL; e = e->next)
(*toc)[i++] = strdup(e->key);
pthread_mutex_unlock (&md->lock);
return (0);
} /* }}} int meta_data_get_boolean */
+int meta_data_as_string (meta_data_t *md, /* {{{ */
+ const char *key, char **value)
+{
+ meta_entry_t *e;
+ char *actual;
+ char buffer[MD_MAX_NONSTRING_CHARS]; /* For non-string types. */
+ char *temp;
+ int type;
+
+ if ((md == NULL) || (key == NULL) || (value == NULL))
+ return (-EINVAL);
+
+ pthread_mutex_lock (&md->lock);
+
+ e = md_entry_lookup (md, key);
+ if (e == NULL)
+ {
+ pthread_mutex_unlock (&md->lock);
+ return (-ENOENT);
+ }
+
+ type = e->type;
+
+ switch (type)
+ {
+ case MD_TYPE_STRING:
+ actual = e->value.mv_string;
+ break;
+ case MD_TYPE_SIGNED_INT:
+ ssnprintf (buffer, sizeof (buffer), "%"PRIi64, e->value.mv_signed_int);
+ actual = buffer;
+ break;
+ case MD_TYPE_UNSIGNED_INT:
+ ssnprintf (buffer, sizeof (buffer), "%"PRIu64, e->value.mv_unsigned_int);
+ actual = buffer;
+ break;
+ case MD_TYPE_DOUBLE:
+ ssnprintf (buffer, sizeof (buffer), GAUGE_FORMAT, e->value.mv_double);
+ actual = buffer;
+ break;
+ case MD_TYPE_BOOLEAN:
+ actual = e->value.mv_boolean ? "true" : "false";
+ break;
+ default:
+ pthread_mutex_unlock (&md->lock);
+ ERROR ("meta_data_as_string: unknown type %d for key `%s'", type, key);
+ return (-ENOENT);
+ }
+
+ pthread_mutex_unlock (&md->lock);
+
+ temp = md_strdup (actual);
+ if (temp == NULL)
+ {
+ pthread_mutex_unlock (&md->lock);
+ ERROR ("meta_data_as_string: md_strdup failed for key `%s'.", key);
+ return (-ENOMEM);
+ }
+
+ *value = temp;
+
+ return (0);
+} /* }}} int meta_data_as_string */
+
/* vim: set sw=2 sts=2 et fdm=marker : */
#include "collectd.h"
+
/*
* Defines
*/
const char *key,
_Bool *value);
+/* Returns the value as a string, regardless of the type. */
+int meta_data_as_string (meta_data_t *md,
+ const char *key,
+ char **value);
+
#endif /* META_DATA_H */
/* vim: set sw=2 sts=2 et : */
#include "common.h" /* for STATIC_ARRAY_SIZE */
#include "collectd.h"
+
#include "testing.h"
#include "meta_data.h"
**/
#include "collectd.h"
+
#include "common.h"
#include "plugin.h"
#include "configfile.h"
}
static void plugin_update_internal_statistics (void) { /* {{{ */
- derive_t copy_write_queue_length;
- value_list_t vl = VALUE_LIST_INIT;
- value_t values[2];
- copy_write_queue_length = write_queue_length;
+ gauge_t copy_write_queue_length = (gauge_t) write_queue_length;
/* Initialize `vl' */
- vl.values = values;
- vl.values_len = 2;
- vl.time = 0;
+ value_list_t vl = VALUE_LIST_INIT;
sstrncpy (vl.host, hostname_g, sizeof (vl.host));
sstrncpy (vl.plugin, "collectd", sizeof (vl.plugin));
- vl.type_instance[0] = 0;
- vl.values_len = 1;
-
/* Write queue */
sstrncpy (vl.plugin_instance, "write_queue",
sizeof (vl.plugin_instance));
/* Write queue : queue length */
- vl.values[0].gauge = (gauge_t) copy_write_queue_length;
+ vl.values = &(value_t) { .gauge = copy_write_queue_length };
+ vl.values_len = 1;
sstrncpy (vl.type, "queue_length", sizeof (vl.type));
vl.type_instance[0] = 0;
plugin_dispatch_values (&vl);
/* Write queue : Values dropped (queue length > low limit) */
- vl.values[0].derive = (derive_t) stats_values_dropped;
+ vl.values = &(value_t) { .gauge = (gauge_t) stats_values_dropped };
+ vl.values_len = 1;
sstrncpy (vl.type, "derive", sizeof (vl.type));
sstrncpy (vl.type_instance, "dropped", sizeof (vl.type_instance));
plugin_dispatch_values (&vl);
sizeof (vl.plugin_instance));
/* Cache : Nb entry in cache tree */
- vl.values[0].gauge = (gauge_t) uc_get_size();
+ vl.values = &(value_t) { .gauge = (gauge_t) uc_get_size() };
+ vl.values_len = 1;
sstrncpy (vl.type, "cache_size", sizeof (vl.type));
vl.type_instance[0] = 0;
plugin_dispatch_values (&vl);
{
char *str;
int len;
- llentry_t *le;
int i;
+ llentry_t *le;
int n;
char **keys;
static void start_read_threads (int num)
{
- int i;
-
if (read_threads != NULL)
return;
}
read_threads_num = 0;
- for (i = 0; i < num; i++)
+ for (int i = 0; i < num; i++)
{
if (pthread_create (read_threads + read_threads_num, NULL,
plugin_read_thread, NULL) == 0)
static void stop_read_threads (void)
{
- int i;
-
if (read_threads == NULL)
return;
pthread_cond_broadcast (&read_cond);
pthread_mutex_unlock (&read_lock);
- for (i = 0; i < read_threads_num; i++)
+ for (int i = 0; i < read_threads_num; i++)
{
if (pthread_join (read_threads[i], NULL) != 0)
{
static void start_write_threads (size_t num) /* {{{ */
{
- size_t i;
-
if (write_threads != NULL)
return;
}
write_threads_num = 0;
- for (i = 0; i < num; i++)
+ for (size_t i = 0; i < num; i++)
{
int status;
int plugin_register_data_set (const data_set_t *ds)
{
data_set_t *ds_copy;
- size_t i;
if ((data_sets != NULL)
&& (c_avl_get (data_sets, ds->type, NULL) == 0))
return (-1);
}
- for (i = 0; i < ds->ds_num; i++)
+ for (size_t i = 0; i < ds->ds_num; i++)
memcpy (ds_copy->ds + i, ds->ds + i, sizeof (data_source_t));
return (c_avl_insert (data_sets, (void *) ds_copy->type, (void *) ds_copy));
llentry_t *le;
int ret = 0; // Assume success.
- stop_read_threads ();
-
destroy_all_callbacks (&list_init);
+ stop_read_threads ();
+
pthread_mutex_lock (&read_lock);
llist_destroy (read_list);
read_list = NULL;
destroy_read_heap ();
+ /* blocks until all write threads have shut down. */
+ stop_write_threads ();
+
+ /* ask all plugins to write out the state they kept. */
plugin_flush (/* plugin = */ NULL,
/* timeout = */ 0,
/* identifier = */ NULL);
plugin_set_ctx (old_ctx);
}
- stop_write_threads ();
-
/* Write plugins which use the `user_data' pointer usually need the
* same data available to the flush callback. If this is the case, set
* the free_function to NULL when registering the flush callback and to
case DS_TYPE_GAUGE:
vl->values[0].gauge = va_arg (ap, gauge_t);
if (store_percentage)
- vl->values[0].gauge *= sum ? (100.0 / sum) : 0;
+ vl->values[0].gauge *= sum ? (100.0 / sum) : NAN;
break;
case DS_TYPE_ABSOLUTE:
vl->values[0].absolute = va_arg (ap, absolute_t);
int plugin_notification_meta_copy (notification_t *dst,
const notification_t *src)
{
- notification_meta_t *meta;
-
assert (dst != NULL);
assert (src != NULL);
assert (dst != src);
assert ((src->meta == NULL) || (src->meta != dst->meta));
- for (meta = src->meta; meta != NULL; meta = meta->next)
+ for (notification_meta_t *meta = src->meta; meta != NULL; meta = meta->next)
{
if (meta->type == NM_TYPE_STRING)
plugin_notification_meta_add_string (dst, meta->name,
#define PLUGIN_H
#include "collectd.h"
+
#include "configfile.h"
#include "meta_data.h"
#include "utils_time.h"
#define PLUGIN_FLAGS_GLOBAL 0x0001
#ifndef DATA_MAX_NAME_LEN
-# define DATA_MAX_NAME_LEN 64
+# define DATA_MAX_NAME_LEN 128
#endif
#define DS_TYPE_COUNTER 0
typedef int (*plugin_shutdown_cb) (void);
typedef int (*plugin_notification_cb) (const notification_t *,
user_data_t *);
-
/*
* NAME
* plugin_set_dir
**/
#include "collectd.h"
+
#include "common.h"
#include "plugin.h"
char *fields[64];
size_t fields_num;
data_set_t *ds;
- size_t i;
fields_num = strsplit (buf, fields, 64);
if (fields_num < 2)
return;
}
- for (i = 0; i < ds->ds_num; i++)
+ for (size_t i = 0; i < ds->ds_num; i++)
if (parse_ds (ds->ds + i, fields[i + 1], strlen (fields[i + 1])) != 0)
{
ERROR ("types_list: parse_line: Cannot parse data source #%zu "
*
* PARAMETERS
* `compare' The function-pointer `compare' is used to compare two keys. It
- * has to return less than zero if it's first argument is smaller
+ * has to return less than zero if its first argument is smaller
* then the second argument, more than zero if the first argument
* is bigger than the second argument and zero if they are equal.
* If your keys are char-pointers, you can use the `strcmp'
* c_avl_pick
*
* DESCRIPTION
- * Remove a (pseudo-)random element from the tree and return it's `key' and
+ * Remove a (pseudo-)random element from the tree and return its `key' and
* `value'. Entries are not returned in any particular order. This function
* is intended for cache-flushes that don't care about the order but simply
* want to remove all elements, one at a time.
#include "common.h" /* STATIC_ARRAY_SIZE */
#include "collectd.h"
+
#include "testing.h"
#include "utils_avltree.h"
};
c_avl_tree_t *t;
- size_t i;
RESET_COUNTS ();
CHECK_NOT_NULL (t = c_avl_create (compare_callback));
/* insert */
- for (i = 0; i < STATIC_ARRAY_SIZE (cases); i++)
+ for (size_t i = 0; i < STATIC_ARRAY_SIZE (cases); i++)
{
char *key;
char *value;
}
/* Key already exists. */
- for (i = 0; i < STATIC_ARRAY_SIZE (cases); i++)
+ for (size_t i = 0; i < STATIC_ARRAY_SIZE (cases); i++)
EXPECT_EQ_INT (1, c_avl_insert (t, cases[i].key, cases[i].value));
/* get */
- for (i = 0; i < STATIC_ARRAY_SIZE (cases); i++)
+ for (size_t i = 0; i < STATIC_ARRAY_SIZE (cases); i++)
{
char *value_ret = NULL;
}
/* remove half */
- for (i = 0; i < STATIC_ARRAY_SIZE (cases) / 2; i++)
+ for (size_t i = 0; i < STATIC_ARRAY_SIZE (cases) / 2; i++)
{
char *key = NULL;
char *value = NULL;
}
/* pick the other half */
- for (i = STATIC_ARRAY_SIZE (cases) / 2; i < STATIC_ARRAY_SIZE (cases); i++)
+ for (size_t i = STATIC_ARRAY_SIZE (cases) / 2; i < STATIC_ARRAY_SIZE (cases); i++)
{
char *key = NULL;
char *value = NULL;
**/
#include "collectd.h"
+
#include "common.h"
#include "plugin.h"
#include "utils_avltree.h"
static void uc_check_range (const data_set_t *ds, cache_entry_t *ce)
{
- size_t i;
-
- for (i = 0; i < ds->ds_num; i++)
+ for (size_t i = 0; i < ds->ds_num; i++)
{
if (isnan (ce->values_gauge[i]))
continue;
{
char *key_copy;
cache_entry_t *ce;
- size_t i;
/* `cache_lock' has been locked by `uc_update' */
sstrncpy (ce->name, key, sizeof (ce->name));
- for (i = 0; i < ds->ds_num; i++)
+ for (size_t i = 0; i < ds->ds_num; i++)
{
switch (ds->ds[i].type)
{
c_avl_iterator_t *iter;
int status;
- int i;
pthread_mutex_lock (&cache_lock);
* including plugin specific meta data, rates, history, …. This must be done
* without holding the lock, otherwise we will run into a deadlock if a
* plugin calls the cache interface. */
- for (i = 0; i < keys_len; i++)
+ for (int i = 0; i < keys_len; i++)
{
value_list_t vl = VALUE_LIST_INIT;
* the timestamp again, so in theory it is possible we remove a value after
* it is updated here. */
pthread_mutex_lock (&cache_lock);
- for (i = 0; i < keys_len; i++)
+ for (int i = 0; i < keys_len; i++)
{
key = NULL;
ce = NULL;
char name[6 * DATA_MAX_NAME_LEN];
cache_entry_t *ce = NULL;
int status;
- size_t i;
if (FORMAT_VL (name, sizeof (name), vl) != 0)
{
return (-1);
}
- for (i = 0; i < ds->ds_num; i++)
+ for (size_t i = 0; i < ds->ds_num; i++)
{
switch (ds->ds[i].type)
{
if (ce->history != NULL)
{
assert (ce->history_index < ce->history_length);
- for (i = 0; i < ce->values_num; i++)
+ for (size_t i = 0; i < ce->values_num; i++)
{
size_t hist_idx = (ce->values_num * ce->history_index) + i;
ce->history[hist_idx] = ce->values_gauge[i];
if (status != 0)
{
- size_t i;
-
- for (i = 0; i < number; i++)
+ for (size_t i = 0; i < number; i++)
{
sfree (names[i]);
}
gauge_t *ret_history, size_t num_steps, size_t num_ds)
{
cache_entry_t *ce = NULL;
- size_t i;
int status = 0;
pthread_mutex_lock (&cache_lock);
return (-ENOMEM);
}
- for (i = ce->history_length * ce->values_num;
+ for (size_t i = ce->history_length * ce->values_num;
i < (num_steps * ce->values_num);
i++)
tmp[i] = NAN;
} /* if (ce->history_length < num_steps) */
/* Copy the values to the output buffer. */
- for (i = 0; i < num_steps; i++)
+ for (size_t i = 0; i < num_steps; i++)
{
size_t src_index;
size_t dst_index;
int uc_iterator_get_values (uc_iter_t *iter, value_t **ret_values, size_t *ret_num)
{
- size_t i;
-
if ((iter == NULL) || (iter->entry == NULL)
|| (ret_values == NULL) || (ret_num == NULL))
return (-1);
*ret_values = calloc (iter->entry->values_num, sizeof(*iter->entry->values_raw));
if (*ret_values == NULL)
return (-1);
- for (i = 0; i < iter->entry->values_num; ++i)
+ for (size_t i = 0; i < iter->entry->values_num; ++i)
*ret_values[i] = iter->entry->values_raw[i];
*ret_num = iter->entry->values_num;
**/
#include "collectd.h"
+
#include "utils_complain.h"
#include "plugin.h"
/* vcomplain returns 0 if it did not report, 1 else */
+__attribute__ ((format (printf, 3, 0)))
static int vcomplain (int level, c_complain_t *c,
const char *format, va_list ap)
{
*
* PARAMETERS
* `compare' The function-pointer `compare' is used to compare two keys. It
- * has to return less than zero if it's first argument is smaller
+ * has to return less than zero if its first argument is smaller
* then the second argument, more than zero if the first argument
* is bigger than the second argument and zero if they are equal.
* If your keys are char-pointers, you can use the `strcmp'
*/
#include "collectd.h"
+
#include "testing.h"
#include "utils_heap.h"
DEF_TEST(simple)
{
int values[] = { 9, 5, 6, 1, 3, 4, 0, 8, 2, 7 };
- int i;
c_heap_t *h;
CHECK_NOT_NULL(h = c_heap_create (compare));
- for (i = 0; i < 10; i++)
+ for (int i = 0; i < 10; i++)
CHECK_ZERO(c_heap_insert (h, &values[i]));
- for (i = 0; i < 5; i++)
+ for (int i = 0; i < 5; i++)
{
int *ret = NULL;
CHECK_NOT_NULL(ret = c_heap_get_root(h));
CHECK_ZERO(c_heap_insert (h, &values[4] /* = 3 */));
CHECK_ZERO(c_heap_insert (h, &values[5] /* = 4 */));
- for (i = 0; i < 10; i++)
+ for (int i = 0; i < 10; i++)
{
int *ret = NULL;
CHECK_NOT_NULL(ret = c_heap_get_root(h));
*/
int ignorelist_match (ignorelist_t *il, const char *entry)
{
- ignorelist_item_t *traverse;
-
/* if no entries, collect all */
if ((il == NULL) || (il->head == NULL))
return (0);
return (0);
/* traverse list and check entries */
- for (traverse = il->head; traverse != NULL; traverse = traverse->next)
+ for (ignorelist_item_t *traverse = il->head; traverse != NULL; traverse = traverse->next)
{
#if HAVE_REGEX_H
if (traverse->rmatch != NULL)
**/
#include "collectd.h"
+
#include "common.h"
#include "plugin.h"
if (data->ds_type & UTILS_MATCH_CF_DERIVE_INC)
{
- data->value.counter++;
+ data->value.derive++;
data->values_num++;
return (0);
}
{
int status;
regmatch_t re_match[32];
- char *matches[32];
+ char *matches[32] = { 0 };
size_t matches_num;
- size_t i;
if ((obj == NULL) || (str == NULL))
return (-1);
if (status != 0)
return (0);
- memset (matches, '\0', sizeof (matches));
for (matches_num = 0; matches_num < STATIC_ARRAY_SIZE (matches); matches_num++)
{
if ((re_match[matches_num].rm_so < 0)
}
}
- for (i = 0; i < matches_num; i++)
+ for (size_t i = 0; i < matches_num; i++)
{
sfree (matches[i]);
}
**/
#include "collectd.h"
+
#include "utils_time.h"
#include "utils_random.h"
*/
#include "collectd.h"
+
#include "common.h"
#include "utils_subst.h"
#include "common.h" /* for STATIC_ARRAY_SIZE */
#include "collectd.h"
+
#include "testing.h"
#include "utils_subst.h"
{"foo bar", 4, 3, "_", NULL}, /* off1 > off2 */
{"foo bar", 3, 4, NULL, NULL}, /* no replacement */
};
- size_t i;
- for (i = 0; i < STATIC_ARRAY_SIZE (cases); i++) {
+ for (size_t i = 0; i < STATIC_ARRAY_SIZE (cases); i++) {
char buffer[16] = "!!!!!!!!!!!!!!!";
if (cases[i].want == NULL) {
{"foo bar", "oo", "oo", "foo bar"},
{"sixteen chars", "chars", "characters", "sixteen charact"},
};
- size_t i;
- for (i = 0; i < STATIC_ARRAY_SIZE (cases); i++) {
+ for (size_t i = 0; i < STATIC_ARRAY_SIZE (cases); i++) {
char buffer[16];
if (cases[i].want == NULL) {
**/
#include "collectd.h"
+
#include "common.h"
#include "utils_tail.h"
{
int seek_end = 0;
FILE *fh;
- struct stat stat_buf;
+ struct stat stat_buf = { 0 };
int status;
- memset (&stat_buf, 0, sizeof (stat_buf));
status = stat (obj->file, &stat_buf);
if (status != 0)
{
*/
#include "collectd.h"
+
#include "common.h"
#include "plugin.h"
#include "utils_match.h"
int __attribute__((unused)) buflen)
{
cu_tail_match_t *obj = (cu_tail_match_t *) data;
- size_t i;
- for (i = 0; i < obj->matches_num; i++)
+ for (size_t i = 0; i < obj->matches_num; i++)
match_apply (obj->matches[i].match, buf);
return (0);
void tail_match_destroy (cu_tail_match_t *obj)
{
- size_t i;
-
if (obj == NULL)
return;
obj->tail = NULL;
}
- for (i = 0; i < obj->matches_num; i++)
+ for (size_t i = 0; i < obj->matches_num; i++)
{
cu_tail_match_match_t *match = obj->matches + i;
if (match->match != NULL)
{
char buffer[4096];
int status;
- size_t i;
status = cu_tail_read (obj->tail, buffer, sizeof (buffer), tail_callback,
(void *) obj);
return (status);
}
- for (i = 0; i < obj->matches_num; i++)
+ for (size_t i = 0; i < obj->matches_num; i++)
{
cu_tail_match_match_t *lt_match = obj->matches + i;
**/
#include "collectd.h"
+
#include "common.h"
#include "utils_avltree.h"
#include "utils_threshold.h"
**/
#include "collectd.h"
+
#include "utils_time.h"
#include "plugin.h"
#include "common.h"
char errbuf[1024];
ERROR ("cdtime: clock_gettime failed: %s",
sstrerror (errno, errbuf, sizeof (errbuf)));
- return (0);
+ return 0;
}
- return (TIMESPEC_TO_CDTIME_T (&ts));
+ return TIMESPEC_TO_CDTIME_T (&ts);
} /* }}} cdtime_t cdtime */
# else /* !HAVE_CLOCK_GETTIME */
/* Work around for Mac OS X which doesn't have clock_gettime(2). *sigh* */
char errbuf[1024];
ERROR ("cdtime: gettimeofday failed: %s",
sstrerror (errno, errbuf, sizeof (errbuf)));
- return (0);
+ return 0;
}
- return (TIMEVAL_TO_CDTIME_T (&tv));
+ return TIMEVAL_TO_CDTIME_T (&tv);
} /* }}} cdtime_t cdtime */
# endif
#endif
+/**********************************************************************
+ Time retrieval functions
+***********************************************************************/
+
+static int get_utc_time (cdtime_t t, struct tm *t_tm, long *nsec) /* {{{ */
+{
+ struct timespec t_spec;
+ int status;
+
+ CDTIME_T_TO_TIMESPEC (t, &t_spec);
+ NORMALIZE_TIMESPEC (t_spec);
+
+ if (gmtime_r (&t_spec.tv_sec, t_tm) == NULL) {
+ char errbuf[1024];
+ status = errno;
+ ERROR ("get_utc_time: gmtime_r failed: %s",
+ sstrerror (status, errbuf, sizeof (errbuf)));
+ return status;
+ }
+
+ *nsec = t_spec.tv_nsec;
+ return 0;
+} /* }}} int get_utc_time */
+
+static int get_local_time (cdtime_t t, struct tm *t_tm, long *nsec) /* {{{ */
+{
+ struct timespec t_spec;
+ int status;
+
+ CDTIME_T_TO_TIMESPEC (t, &t_spec);
+ NORMALIZE_TIMESPEC (t_spec);
+
+ if (localtime_r (&t_spec.tv_sec, t_tm) == NULL) {
+ char errbuf[1024];
+ status = errno;
+ ERROR ("get_local_time: localtime_r failed: %s",
+ sstrerror (status, errbuf, sizeof (errbuf)));
+ return status;
+ }
+
+ *nsec = t_spec.tv_nsec;
+ return 0;
+} /* }}} int get_local_time */
+
+/**********************************************************************
+ Formatting functions
+***********************************************************************/
+
+static const char zulu_zone[] = "Z";
+
/* format_zone reads time zone information from "extern long timezone", exported
* by <time.h>, and formats it according to RFC 3339. This differs from
* strftime()'s "%z" format by including a colon between hour and minute. */
return 0;
} /* }}} int format_zone */
-static int format_rfc3339 (char *buffer, size_t buffer_size, cdtime_t t, _Bool print_nano) /* {{{ */
+int format_rfc3339 (char *buffer, size_t buffer_size, struct tm const *t_tm, long nsec, _Bool print_nano, char const *zone) /* {{{ */
+{
+ int len;
+ char *pos = buffer;
+ size_t size_left = buffer_size;
+
+ if ((len = strftime (pos, size_left, "%Y-%m-%dT%H:%M:%S", t_tm)) == 0)
+ return ENOMEM;
+ pos += len;
+ size_left -= len;
+
+ if (print_nano) {
+ if ((len = ssnprintf (pos, size_left, ".%09ld", nsec)) == 0)
+ return ENOMEM;
+ pos += len;
+ size_left -= len;
+ }
+
+ sstrncpy (pos, zone, size_left);
+ return 0;
+} /* }}} int format_rfc3339 */
+
+int format_rfc3339_utc (char *buffer, size_t buffer_size, cdtime_t t, _Bool print_nano) /* {{{ */
{
- struct timespec t_spec;
struct tm t_tm;
- char base[20]; /* 2006-01-02T15:04:05 */
- char nano[11]; /* .999999999 */
- char zone[7]; /* +00:00 */
- char *fields[] = {base, nano, zone};
- size_t len;
+ long nsec = 0;
int status;
- CDTIME_T_TO_TIMESPEC (t, &t_spec);
- NORMALIZE_TIMESPEC (t_spec);
+ if ((status = get_utc_time (t, &t_tm, &nsec)) != 0)
+ return status; /* The error should have already be reported. */
- if (localtime_r (&t_spec.tv_sec, &t_tm) == NULL) {
- char errbuf[1024];
- status = errno;
- ERROR ("format_rfc3339: localtime_r failed: %s",
- sstrerror (status, errbuf, sizeof (errbuf)));
- return (status);
- }
+ return format_rfc3339 (buffer, buffer_size, &t_tm, nsec, print_nano, zulu_zone);
+} /* }}} int format_rfc3339_utc */
- len = strftime (base, sizeof (base), "%Y-%m-%dT%H:%M:%S", &t_tm);
- if (len == 0)
- return ENOMEM;
+int format_rfc3339_local (char *buffer, size_t buffer_size, cdtime_t t, _Bool print_nano) /* {{{ */
+{
+ struct tm t_tm;
+ long nsec = 0;
+ int status;
+ char zone[7]; /* +00:00 */
- if (print_nano)
- ssnprintf (nano, sizeof (nano), ".%09ld", (long) t_spec.tv_nsec);
- else
- sstrncpy (nano, "", sizeof (nano));
+ if ((status = get_local_time (t, &t_tm, &nsec)) != 0)
+ return status; /* The error should have already be reported. */
- status = format_zone (zone, sizeof (zone), &t_tm);
- if (status != 0)
+ if ((status = format_zone (zone, sizeof (zone), &t_tm)) != 0)
return status;
- if (strjoin (buffer, buffer_size, fields, STATIC_ARRAY_SIZE (fields), "") < 0)
- return ENOMEM;
- return 0;
-} /* }}} int format_rfc3339 */
+ return format_rfc3339 (buffer, buffer_size, &t_tm, nsec, print_nano, zone);
+} /* }}} int format_rfc3339_local */
+
+/**********************************************************************
+ Public functions
+***********************************************************************/
int rfc3339 (char *buffer, size_t buffer_size, cdtime_t t) /* {{{ */
{
if (buffer_size < RFC3339_SIZE)
return ENOMEM;
- return format_rfc3339 (buffer, buffer_size, t, 0);
-} /* }}} size_t cdtime_to_rfc3339 */
+ return format_rfc3339_utc (buffer, buffer_size, t, 0);
+} /* }}} int rfc3339 */
int rfc3339nano (char *buffer, size_t buffer_size, cdtime_t t) /* {{{ */
{
if (buffer_size < RFC3339NANO_SIZE)
return ENOMEM;
- return format_rfc3339 (buffer, buffer_size, t, 1);
-} /* }}} size_t cdtime_to_rfc3339nano */
+ return format_rfc3339_utc (buffer, buffer_size, t, 1);
+} /* }}} int rfc3339nano */
+
+int rfc3339_local (char *buffer, size_t buffer_size, cdtime_t t) /* {{{ */
+{
+ if (buffer_size < RFC3339_SIZE)
+ return ENOMEM;
+
+ return format_rfc3339_local (buffer, buffer_size, t, 0);
+} /* }}} int rfc3339 */
+
+int rfc3339nano_local (char *buffer, size_t buffer_size, cdtime_t t) /* {{{ */
+{
+ if (buffer_size < RFC3339NANO_SIZE)
+ return ENOMEM;
+
+ return format_rfc3339_local (buffer, buffer_size, t, 1);
+} /* }}} int rfc3339nano */
/* vim: set sw=2 sts=2 et fdm=marker : */
cdtime_t cdtime (void);
-#define RFC3339_SIZE 26
-#define RFC3339NANO_SIZE 36
+#define RFC3339_SIZE 26 /* 2006-01-02T15:04:05+00:00 */
+#define RFC3339NANO_SIZE 36 /* 2006-01-02T15:04:05.999999999+00:00 */
-/* rfc3339 formats a cdtime_t time in RFC 3339 format with second precision. */
+/* rfc3339 formats a cdtime_t time as UTC in RFC 3339 zulu format with second
+ * precision, e.g., "2006-01-02T15:04:05Z". */
int rfc3339 (char *buffer, size_t buffer_size, cdtime_t t);
-/* rfc3339nano formats a cdtime_t time in RFC 3339 format with nanosecond
- * precision. */
+/* rfc3339nano formats a cdtime_t as UTC time in RFC 3339 zulu format with
+ * nanosecond precision, e.g., "2006-01-02T15:04:05.999999999Z". */
int rfc3339nano (char *buffer, size_t buffer_size, cdtime_t t);
+/* rfc3339 formats a cdtime_t time as local in RFC 3339 format with second
+ * precision, e.g., "2006-01-02T15:04:05+00:00". */
+int rfc3339_local (char *buffer, size_t buffer_size, cdtime_t t);
+
+/* rfc3339nano formats a cdtime_t time as local in RFC 3339 format with
+ * nanosecond precision, e.g., "2006-01-02T15:04:05.999999999+00:00". */
+int rfc3339nano_local (char *buffer, size_t buffer_size, cdtime_t t);
+
#endif /* UTILS_TIME_H */
/* vim: set sw=2 sts=2 et : */
#define DBL_PRECISION 1e-3
#include "collectd.h"
+
#include "testing.h"
#include "utils_time.h"
// 1546167986577716567 / 2^30 = 1439981150.0475896215...
{1546167986577716567ULL, 1439981150.048, 1439981150, 1439981150048ULL, {1439981150, 47590}, {1439981150, 47589622}},
};
- size_t i;
- for (i = 0; i < (sizeof (cases) / sizeof (cases[0])); i++) {
+ for (size_t i = 0; i < (sizeof (cases) / sizeof (cases[0])); i++) {
struct timeval tv;
struct timespec ts;
// 1439981880053705608 * 2^30 / 10^9 = 1546168770415815077.4
{1439981880053705608ULL, 1546168770415815077ULL},
};
- size_t i;
- for (i = 0; i < (sizeof (cases) / sizeof (cases[0])); i++) {
+ for (size_t i = 0; i < (sizeof (cases) / sizeof (cases[0])); i++) {
EXPECT_EQ_UINT64 (cases[i].want, NS_TO_CDTIME_T (cases[i].ns));
}
**/
#include "collectd.h"
+
#include "common.h"
#include "plugin.h"
-#include "configfile.h"
#include "utils_db_query.h"
#include <dbi/dbi.h>
static void cdbi_database_free (cdbi_database_t *db) /* {{{ */
{
- size_t i;
-
if (db == NULL)
return;
sfree (db->name);
sfree (db->driver);
- for (i = 0; i < db->driver_options_num; i++)
+ for (size_t i = 0; i < db->driver_options_num; i++)
{
sfree (db->driver_options[i].key);
if (!db->driver_options[i].is_numeric)
sfree (db->driver_options);
if (db->q_prep_areas)
- for (i = 0; i < db->queries_num; ++i)
+ for (size_t i = 0; i < db->queries_num; ++i)
udb_query_delete_preparation_area (db->q_prep_areas[i]);
free (db->q_prep_areas);
{
cdbi_database_t *db;
int status;
- int i;
if ((ci->values_num != 1)
|| (ci->values[0].type != OCONFIG_TYPE_STRING))
}
/* Fill the `cdbi_database_t' structure.. */
- for (i = 0; i < ci->children_num; i++)
+ for (int i = 0; i < ci->children_num; i++)
{
oconfig_item_t *child = ci->children + i;
while ((status == 0) && (db->queries_num > 0))
{
- size_t j;
-
db->q_prep_areas = calloc (db->queries_num, sizeof (*db->q_prep_areas));
if (db->q_prep_areas == NULL)
{
break;
}
- for (j = 0; j < db->queries_num; ++j)
+ for (size_t i = 0; i < db->queries_num; ++i)
{
- db->q_prep_areas[j]
- = udb_query_allocate_preparation_area (db->queries[j]);
+ db->q_prep_areas[i]
+ = udb_query_allocate_preparation_area (db->queries[i]);
- if (db->q_prep_areas[j] == NULL)
+ if (db->q_prep_areas[i] == NULL)
{
WARNING ("dbi plugin: udb_query_allocate_preparation_area failed");
status = -1;
}
else
{
- user_data_t ud;
- char *name = NULL;
-
databases = temp;
databases[databases_num] = db;
databases_num++;
- memset (&ud, 0, sizeof (ud));
- ud.data = (void *) db;
- ud.free_func = NULL;
- name = ssnprintf_alloc("dbi:%s", db->name);
-
+ char *name = ssnprintf_alloc("dbi:%s", db->name);
plugin_register_complex_read (/* group = */ NULL,
/* name = */ name ? name : db->name,
/* callback = */ cdbi_read_database,
/* interval = */ (db->interval > 0) ? db->interval : 0,
- /* user_data = */ &ud);
- free (name);
+ &(user_data_t) {
+ .data = db,
+ });
+ sfree (name);
}
}
static int cdbi_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;
if (strcasecmp ("Query", child->key) == 0)
if (queries_num == 0)
{
ERROR ("dbi plugin: No <Query> blocks have been found. Without them, "
- "this plugin can't do anything useful, so we will returns an error.");
+ "this plugin can't do anything useful, so we will return an error.");
return (-1);
}
if (databases_num == 0)
{
ERROR ("dbi plugin: No <Database> blocks have been found. Without them, "
- "this plugin can't do anything useful, so we will returns an error.");
+ "this plugin can't do anything useful, so we will return an error.");
return (-1);
}
char **column_names;
char **column_values;
int status;
- size_t i;
/* Macro that cleans up dynamically allocated memory and returns the
* specified status. */
ERROR ("dbi plugin: calloc failed.");
BAIL_OUT (-1);
}
- for (i = 1; i < column_num; i++)
+ for (size_t i = 1; i < column_num; i++)
column_names[i] = column_names[i - 1] + DATA_MAX_NAME_LEN;
column_values = calloc (column_num, sizeof (*column_values));
ERROR ("dbi plugin: calloc failed.");
BAIL_OUT (-1);
}
- for (i = 1; i < column_num; i++)
+ for (size_t i = 1; i < column_num; i++)
column_values[i] = column_values[i - 1] + DATA_MAX_NAME_LEN;
/* }}} */
/* Copy the field names to `column_names' */
- for (i = 0; i < column_num; i++) /* {{{ */
+ for (size_t i = 0; i < column_num; i++) /* {{{ */
{
const char *column_name;
{
status = 0;
/* Copy the value of the columns to `column_values' */
- for (i = 0; i < column_num; i++) /* {{{ */
+ for (size_t i = 0; i < column_num; i++) /* {{{ */
{
status = cdbi_result_get_field (res, (unsigned int) (i + 1),
column_values[i], DATA_MAX_NAME_LEN);
{
dbi_driver driver;
dbi_conn connection;
- size_t i;
int status;
if (db->connection != NULL)
* encountered, it will get a list of options understood by the driver and
* report that as `INFO'. This way, users hopefully don't have too much
* trouble finding out how to configure the plugin correctly.. */
- for (i = 0; i < db->driver_options_num; i++)
+ for (size_t i = 0; i < db->driver_options_num; i++)
{
if (db->driver_options[i].is_numeric)
{
if (status != 0)
{
- char const *opt;
-
INFO ("dbi plugin: This is a list of all options understood "
"by the `%s' driver:", db->driver);
- for (opt = dbi_conn_get_option_list (connection, NULL);
+ for (const char *opt = dbi_conn_get_option_list (connection, NULL);
opt != NULL;
opt = dbi_conn_get_option_list (connection, opt))
{
static int cdbi_read_database (user_data_t *ud) /* {{{ */
{
cdbi_database_t *db = (cdbi_database_t *) ud->data;
- size_t i;
int success;
int status;
/* TODO: Complain if `db_version == 0' */
success = 0;
- for (i = 0; i < db->queries_num; i++)
+ for (size_t i = 0; i < db->queries_num; i++)
{
/* Check if we know the database's version and if so, if this query applies
* to that version. */
static int cdbi_shutdown (void) /* {{{ */
{
- size_t i;
-
- for (i = 0; i < databases_num; i++)
+ for (size_t i = 0; i < databases_num; i++)
{
if (databases[i]->connection != NULL)
{
**/
#include "collectd.h"
+
#include "common.h"
#include "plugin.h"
-#include "configfile.h"
#include "utils_mount.h"
#include "utils_ignorelist.h"
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, "df", sizeof (vl.plugin));
#endif
/* struct STATANYFS statbuf; */
cu_mount_t *mnt_list;
- cu_mount_t *mnt_ptr;
mnt_list = NULL;
if (cu_mount_getlist (&mnt_list) == NULL)
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)
{
unsigned long long blocksize;
char disk_name[256];
}
/* Duplicate found: leave non-NULL dup_ptr. */
- if (by_device && (strcmp (mnt_ptr->spec_device, dup_ptr->spec_device) == 0))
+ if (by_device
+ && (mnt_ptr->spec_device != NULL)
+ && (dup_ptr->spec_device != NULL)
+ && (strcmp (mnt_ptr->spec_device, dup_ptr->spec_device) == 0))
break;
else if (!by_device && (strcmp (mnt_ptr->dir, dup_ptr->dir) == 0))
break;
sstrncpy (disk_name, "root", sizeof (disk_name));
else
{
- int i, len;
+ int len;
sstrncpy (disk_name, mnt_ptr->dir + 1, sizeof (disk_name));
len = strlen (disk_name);
- for (i = 0; i < len; i++)
+ for (int i = 0; i < len; i++)
if (disk_name[i] == '/')
disk_name[i] = '-';
}
**/
#include "collectd.h"
+
#include "common.h"
#include "plugin.h"
#include "utils_ignorelist.h"
/* #endif HAVE_LIBKSTAT */
#elif defined(HAVE_LIBSTATGRAB)
-/* #endif HAVE_LIBKSTATGRAB */
+/* #endif HAVE_LIBSTATGRAB */
#elif HAVE_PERFSTAT
static perfstat_disk_t * stat_disk;
const char *type,
derive_t read, derive_t write)
{
- value_t values[2];
value_list_t vl = VALUE_LIST_INIT;
-
- values[0].derive = read;
- values[1].derive = write;
+ value_t values[] = {
+ { .derive = read },
+ { .derive = write },
+ };
vl.values = values;
- vl.values_len = 2;
+ vl.values_len = STATIC_ARRAY_SIZE (values);
sstrncpy (vl.host, hostname_g, sizeof (vl.host));
sstrncpy (vl.plugin, "disk", sizeof (vl.plugin));
sstrncpy (vl.plugin_instance, plugin_instance,
#if KERNEL_FREEBSD || KERNEL_LINUX
static void submit_io_time (char const *plugin_instance, derive_t io_time, derive_t weighted_time)
{
- value_t values[2];
value_list_t vl = VALUE_LIST_INIT;
-
- values[0].derive = io_time;
- values[1].derive = weighted_time;
+ value_t values[] = {
+ { .derive = io_time },
+ { .derive = weighted_time },
+ };
vl.values = values;
- vl.values_len = 2;
+ vl.values_len = STATIC_ARRAY_SIZE (values);
sstrncpy (vl.host, hostname_g, sizeof (vl.host));
sstrncpy (vl.plugin, "disk", sizeof (vl.plugin));
sstrncpy (vl.plugin_instance, plugin_instance, sizeof (vl.plugin_instance));
#if KERNEL_LINUX
static void submit_in_progress (char const *disk_name, gauge_t in_progress)
{
- value_t v;
value_list_t vl = VALUE_LIST_INIT;
- v.gauge = in_progress;
-
- vl.values = &v;
+ vl.values = &(value_t) { .gauge = in_progress };
vl.values_len = 1;
sstrncpy (vl.host, hostname_g, sizeof (vl.host));
sstrncpy (vl.plugin, "disk", sizeof (vl.plugin));
plugin_dispatch_values (&vl);
}
-
static counter_t disk_calc_time_incr (counter_t delta_time, counter_t delta_ops)
{
double interval = CDTIME_T_TO_DOUBLE (plugin_get_interval ());
# error "kstat_io_t does not have the required members"
# endif
static kstat_io_t kio;
- int i;
if (kc == NULL)
return (-1);
- for (i = 0; i < numdisk; i++)
+ for (int i = 0; i < numdisk; i++)
{
if (kstat_read (kc, ksp[i], &kio) == -1)
continue;
# else
int disks;
#endif
- int counter;
char name[DATA_MAX_NAME_LEN];
if ((ds = sg_get_disk_io_stats(&disks)) == NULL)
return (0);
- for (counter=0; counter < disks; counter++) {
+ for (int counter = 0; counter < disks; counter++) {
strncpy(name, ds->disk_name, sizeof(name));
name[sizeof(name)-1] = '\0'; /* strncpy doesn't terminate longer strings */
derive_t write_ops;
perfstat_id_t firstpath;
int rnumdisk;
- int i;
if ((numdisk = perfstat_disk(NULL, NULL, sizeof(perfstat_disk_t), 0)) < 0)
{
return (-1);
}
- for (i = 0; i < rnumdisk; i++)
+ for (int i = 0; i < rnumdisk; i++)
{
if (ignorelist_match (ignorelist, stat_disk[i].name) != 0)
continue;
#define _BSD_SOURCE
#include "collectd.h"
+
#include "common.h"
#include "plugin.h"
-#include "configfile.h"
#include "utils_dns.h"
#include <poll.h>
#include <pcap.h>
+#ifdef HAVE_SYS_CAPABILITY_H
+# include <sys/capability.h>
+#endif
+
/*
* Private data types
*/
{
pcap_t *pcap_obj;
char pcap_error[PCAP_ERRBUF_SIZE];
- struct bpf_program fp;
+ struct bpf_program fp = { 0 };
int status;
return (PCAP_ERROR);
}
- memset (&fp, 0, sizeof (fp));
status = pcap_compile (pcap_obj, &fp, "udp port 53", 1, 0);
if (status < 0)
{
listen_thread_init = 1;
+#if defined(HAVE_SYS_CAPABILITY_H) && defined(CAP_NET_RAW)
+ if (check_capability (CAP_NET_RAW) != 0)
+ {
+ if (getuid () == 0)
+ WARNING ("dns plugin: Running collectd as root, but the CAP_NET_RAW "
+ "capability is missing. The plugin's read function will probably "
+ "fail. Is your init system dropping capabilities?");
+ else
+ WARNING ("dns plugin: collectd doesn't have the CAP_NET_RAW capability. "
+ "If you don't want to run collectd as root, try running \"setcap "
+ "cap_net_raw=ep\" on the collectd binary.");
+ }
+#endif
+
return (0);
} /* int dns_init */
static void submit_derive (const char *type, const char *type_instance,
derive_t value)
{
- value_t values[1];
value_list_t vl = VALUE_LIST_INIT;
- values[0].derive = value;
-
- vl.values = values;
+ vl.values = &(value_t) { .derive = value };
vl.values_len = 1;
sstrncpy (vl.host, hostname_g, sizeof (vl.host));
sstrncpy (vl.plugin, "dns", sizeof (vl.plugin));
static void submit_octets (derive_t queries, derive_t responses)
{
- value_t values[2];
+ value_t values[] = {
+ { .derive = queries },
+ { .derive = responses },
+ };
value_list_t vl = VALUE_LIST_INIT;
- values[0].derive = queries;
- values[1].derive = responses;
-
vl.values = values;
- vl.values_len = 2;
+ vl.values_len = STATIC_ARRAY_SIZE (values);
sstrncpy (vl.host, hostname_g, sizeof (vl.host));
sstrncpy (vl.plugin, "dns", sizeof (vl.plugin));
sstrncpy (vl.type, "dns_octets", sizeof (vl.type));
unsigned int keys[T_MAX];
unsigned int values[T_MAX];
int len;
- int i;
counter_list_t *ptr;
}
pthread_mutex_unlock (&qtype_mutex);
- for (i = 0; i < len; i++)
+ for (int i = 0; i < len; i++)
{
DEBUG ("dns plugin: qtype = %u; counter = %u;", keys[i], values[i]);
submit_derive ("dns_qtype", qtype_str (keys[i]), values[i]);
}
pthread_mutex_unlock (&opcode_mutex);
- for (i = 0; i < len; i++)
+ for (int i = 0; i < len; i++)
{
DEBUG ("dns plugin: opcode = %u; counter = %u;", keys[i], values[i]);
submit_derive ("dns_opcode", opcode_str (keys[i]), values[i]);
}
pthread_mutex_unlock (&rcode_mutex);
- for (i = 0; i < len; i++)
+ for (int i = 0; i < len; i++)
{
DEBUG ("dns plugin: rcode = %u; counter = %u;", keys[i], values[i]);
submit_derive ("dns_rcode", rcode_str (keys[i]), values[i]);
*/
#include "collectd.h"
+
#include "common.h"
#include "plugin.h"
char plugin_instance[DATA_MAX_NAME_LEN];
value_t values[fields_num];
value_list_t vl = VALUE_LIST_INIT;
- size_t i;
if (resource < 0)
{
ssnprintf (plugin_instance, sizeof (plugin_instance), "r%ld",
resource);
- for (i = 0; i < drbd_names_num; i++)
+ for (size_t i = 0; i < drbd_names_num; i++)
{
char *data;
/* skip non numeric wo */
sizeof (vl.plugin_instance));
sstrncpy (vl.type, "drbd_resource", sizeof (vl.type));
- for (i = 0; i < fields_num; i++)
+ for (size_t i = 0; i < fields_num; i++)
{
if (drbd_names[i] == NULL)
continue;
*/
#include "collectd.h"
+
#include "common.h"
#include "plugin.h"
-#include "configfile.h"
-
#include <stddef.h>
#include <sys/un.h>
}
{ /* initialize collector threads */
- int i = 0;
-
pthread_attr_t ptattr;
conns.head = NULL;
collectors =
smalloc (max_conns * sizeof (*collectors));
- for (i = 0; i < max_conns; ++i) {
+ for (int i = 0; i < max_conns; ++i) {
collectors[i] = smalloc (sizeof (*collectors[i]));
collectors[i]->socket = NULL;
static int email_shutdown (void)
{
- int i = 0;
-
if (connector != ((pthread_t) 0)) {
pthread_kill (connector, SIGTERM);
connector = (pthread_t) 0;
available_collectors = 0;
if (collectors != NULL) {
- for (i = 0; i < max_conns; ++i) {
+ for (int i = 0; i < max_conns; ++i) {
if (collectors[i] == NULL)
continue;
static void email_submit (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, "email", sizeof (vl.plugin));
* after they have been copied to l2. */
static void copy_type_list (type_list_t *l1, type_list_t *l2)
{
- type_t *ptr1;
- type_t *ptr2;
-
type_t *last = NULL;
- for (ptr1 = l1->head, ptr2 = l2->head; NULL != ptr1;
+ for (type_t *ptr1 = l1->head, *ptr2 = l2->head; NULL != ptr1;
ptr1 = ptr1->next, last = ptr2, ptr2 = ptr2->next) {
if (NULL == ptr2) {
ptr2 = smalloc (sizeof (*ptr2));
static int email_read (void)
{
- type_t *ptr;
-
double score_old;
int score_count_old;
pthread_mutex_unlock (&count_mutex);
- for (ptr = list_count_copy.head; NULL != ptr; ptr = ptr->next) {
+ for (type_t *ptr = list_count_copy.head; NULL != ptr; ptr = ptr->next) {
email_submit ("email_count", ptr->name, ptr->value);
}
pthread_mutex_unlock (&size_mutex);
- for (ptr = list_size_copy.head; NULL != ptr; ptr = ptr->next) {
+ for (type_t *ptr = list_size_copy.head; NULL != ptr; ptr = ptr->next) {
email_submit ("email_size", ptr->name, ptr->value);
}
pthread_mutex_unlock (&check_mutex);
- for (ptr = list_check_copy.head; NULL != ptr; ptr = ptr->next)
+ for (type_t *ptr = list_check_copy.head; NULL != ptr; ptr = ptr->next)
email_submit ("spam_check", ptr->name, ptr->value);
return (0);
**/
#include "collectd.h"
+
#include "common.h"
#include "plugin.h"
#define ENTROPY_FILE "/proc/sys/kernel/random/entropy_avail"
-static void entropy_submit (double entropy)
+static void entropy_submit (value_t value)
{
- value_t values[1];
value_list_t vl = VALUE_LIST_INIT;
- values[0].gauge = entropy;
-
- vl.values = values;
+ vl.values = &value;
vl.values_len = 1;
sstrncpy (vl.host, hostname_g, sizeof (vl.host));
sstrncpy (vl.plugin, "entropy", sizeof (vl.plugin));
static int entropy_read (void)
{
- double entropy;
- FILE *fh;
- char buffer[64];
-
- fh = fopen (ENTROPY_FILE, "r");
- if (fh == NULL)
- return (-1);
-
- if (fgets (buffer, sizeof (buffer), fh) == NULL)
+ value_t v;
+ if (parse_value_file (ENTROPY_FILE, &v, DS_TYPE_GAUGE) != 0)
{
- fclose (fh);
+ ERROR ("entropy plugin: Reading \""ENTROPY_FILE"\" failed.");
return (-1);
}
- fclose (fh);
-
- entropy = atof (buffer);
-
- if (entropy > 0.0)
- entropy_submit (entropy);
+ entropy_submit (v);
return (0);
}
**/
#include "collectd.h"
+
#include "common.h"
#include "plugin.h"
-#include "configfile.h"
#include "utils_avltree.h"
#include "utils_complain.h"
static int ethstat_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;
{
static c_complain_t complain_no_map = C_COMPLAIN_INIT_STATIC;
- value_t values[1];
value_list_t vl = VALUE_LIST_INIT;
value_map_t *map = NULL;
return;
}
- values[0].derive = value;
- vl.values = values;
+ vl.values = &(value_t) { .derive = value };
vl.values_len = 1;
sstrncpy (vl.host, hostname_g, sizeof (vl.host));
static int ethstat_read_interface (char *device)
{
int fd;
- struct ifreq req;
- struct ethtool_drvinfo drvinfo;
struct ethtool_gstrings *strings;
struct ethtool_stats *stats;
size_t n_stats;
size_t strings_size;
size_t stats_size;
- size_t i;
int status;
- memset (&req, 0, sizeof (req));
- sstrncpy(req.ifr_name, device, sizeof (req.ifr_name));
-
fd = socket(AF_INET, SOCK_DGRAM, /* protocol = */ 0);
if (fd < 0)
{
return 1;
}
- memset (&drvinfo, 0, sizeof (drvinfo));
- drvinfo.cmd = ETHTOOL_GDRVINFO;
- req.ifr_data = (void *) &drvinfo;
+ struct ethtool_drvinfo drvinfo = {
+ .cmd = ETHTOOL_GDRVINFO
+ };
+
+ struct ifreq req = {
+ .ifr_data = (void *) &drvinfo
+ };
+
+ sstrncpy(req.ifr_name, device, sizeof (req.ifr_name));
+
status = ioctl (fd, SIOCETHTOOL, &req);
if (status < 0)
{
return (-1);
}
- for (i = 0; i < n_stats; i++)
+ for (size_t i = 0; i < n_stats; i++)
{
char *stat_name;
static int ethstat_read(void)
{
- size_t i;
-
- for (i = 0; i < interfaces_num; i++)
+ for (size_t i = 0; i < interfaces_num; i++)
ethstat_read_interface (interfaces[i]);
return 0;
#define _BSD_SOURCE /* For setgroups */
#include "collectd.h"
+
#include "common.h"
#include "plugin.h"
#include <grp.h>
#include <signal.h>
+#ifdef HAVE_SYS_CAPABILITY_H
+# include <sys/capability.h>
+#endif
+
#define PL_NORMAL 0x01
#define PL_NOTIF_ACTION 0x02
static int exec_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;
if ((strcasecmp ("Exec", child->key) == 0)
{
sigset_t ss;
- memset (&ss, 0, sizeof (ss));
sigemptyset (&ss);
sigprocmask (SIG_SETMASK, &ss, /* old mask = */ NULL);
} /* }}} void reset_signal_mask */
else if (pid == 0)
{
int fd_num;
- int fd;
/* Close all file descriptors but the pipe end we need. */
fd_num = getdtablesize ();
- for (fd = 0; fd < fd_num; fd++)
+ for (int fd = 0; fd < fd_num; fd++)
{
if ((fd == fd_pipe_in[0])
|| (fd == fd_pipe_out[1])
{
program_list_t *pl = ((program_list_and_notification_t *) arg)->pl;
notification_t *n = &((program_list_and_notification_t *) arg)->n;
- notification_meta_t *meta;
int fd;
FILE *fh;
int pid;
if (strlen (n->type_instance) > 0)
fprintf (fh, "TypeInstance: %s\n", n->type_instance);
- for (meta = n->meta; meta != NULL; meta = meta->next)
+ for (notification_meta_t *meta = n->meta; meta != NULL; meta = meta->next)
{
if (meta->type == NM_TYPE_STRING)
fprintf (fh, "%s: %s\n", meta->name, meta->nm_value.nm_string);
static int exec_init (void) /* {{{ */
{
- struct sigaction sa;
+ struct sigaction sa = {
+ .sa_handler = sigchld_handler
+ };
- memset (&sa, '\0', sizeof (sa));
- sa.sa_handler = sigchld_handler;
sigaction (SIGCHLD, &sa, NULL);
+#if defined(HAVE_SYS_CAPABILITY_H) && defined(CAP_SETUID) && defined(CAP_SETGID)
+ if ((check_capability (CAP_SETUID) != 0) ||
+ (check_capability (CAP_SETGID) != 0))
+ {
+ if (getuid () == 0)
+ WARNING ("exec plugin: Running collectd as root, but the CAP_SETUID "
+ "or CAP_SETGID capabilities are missing. The plugin's read function "
+ "will probably fail. Is your init system dropping capabilities?");
+ else
+ WARNING ("exec plugin: collectd doesn't have the CAP_SETUID or "
+ "CAP_SETGID capabilities. If you don't want to run collectd as root, "
+ "try running \"setcap 'cap_setuid=ep cap_setgid=ep'\" on the "
+ "collectd binary.");
+ }
+#endif
+
return (0);
} /* int exec_init }}} */
static int exec_read (void) /* {{{ */
{
- program_list_t *pl;
-
- for (pl = pl_head; pl != NULL; pl = pl->next)
+ for (program_list_t *pl = pl_head; pl != NULL; pl = pl->next)
{
pthread_t t;
pthread_attr_t attr;
static int exec_notification (const notification_t *n, /* {{{ */
user_data_t __attribute__((unused)) *user_data)
{
- program_list_t *pl;
program_list_and_notification_t *pln;
- for (pl = pl_head; pl != NULL; pl = pl->next)
+ for (program_list_t *pl = pl_head; pl != NULL; pl = pl->next)
{
pthread_t t;
pthread_attr_t attr;
**/
#include "collectd.h"
+
#include "common.h"
#include "plugin.h"
-#include "configfile.h"
static const char *config_keys[] = {
static void fhcount_submit(
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;
// Compose the metric
plugin_dispatch_values(&vl);
}
-
static int fhcount_read(void) {
int numfields = 0;
int buffer_len = 60;
**/
#include "collectd.h"
+
#include "common.h"
#include "plugin.h"
static void fc_submit_dir (const fc_directory_conf_t *dir)
{
- value_t values[1];
value_list_t vl = VALUE_LIST_INIT;
- values[0].gauge = (gauge_t) dir->files_num;
-
- vl.values = values;
- vl.values_len = STATIC_ARRAY_SIZE (values);
+ vl.values = &(value_t) { .gauge = (gauge_t) dir->files_num };
+ vl.values_len = 1;
sstrncpy (vl.host, hostname_g, sizeof (vl.host));
sstrncpy (vl.plugin, "filecount", sizeof (vl.plugin));
sstrncpy (vl.plugin_instance, dir->instance, sizeof (vl.plugin_instance));
plugin_dispatch_values (&vl);
- values[0].gauge = (gauge_t) dir->files_size;
+ vl.values = &(value_t) { .gauge = (gauge_t) dir->files_size };
sstrncpy (vl.type, "bytes", sizeof (vl.type));
plugin_dispatch_values (&vl);
{
fc_directory_conf_t *dir;
int status;
- int i;
if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING))
{
dir->size = 0;
status = 0;
- for (i = 0; i < ci->children_num; i++)
+ for (int i = 0; i < ci->children_num; i++)
{
oconfig_item_t *option = ci->children + i;
static int fc_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;
if (strcasecmp ("Directory", child->key) == 0)
static int fc_read (void)
{
- size_t i;
-
- for (i = 0; i < directories_num; i++)
+ for (size_t i = 0; i < directories_num; i++)
fc_read_dir (directories[i]);
return (0);
**/
#include "collectd.h"
+
#include "common.h"
#include "plugin.h"
#include <stdio.h> /* a header needed for FILE */
char *lineptr;
char *fields[32];
int fields_num;
- int i;
/* Find the colon and replace it with a null byte */
lineptr = strchr (linebuffer, ':');
if (fields_num <= 0)
continue;
- for (i = 0; i < fields_num; i++)
+ for (int i = 0; i < fields_num; i++)
{
char *field_name;
char *field_value_str;
**/
#include "collectd.h"
+
#include "plugin.h"
#include "common.h"
-#include "configfile.h"
#include "utils_avltree.h"
#if HAVE_NETDB_H
size_t *ret_sockets_num,
const char *node, const char *service, int listen)
{
- struct addrinfo ai_hints;
struct addrinfo *ai_list;
- struct addrinfo *ai_ptr;
int ai_return;
socket_entry_t *sockets = NULL;
if (*ret_sockets != NULL)
return (EINVAL);
- memset (&ai_hints, 0, sizeof (ai_hints));
- ai_hints.ai_flags = 0;
-#ifdef AI_PASSIVE
- ai_hints.ai_flags |= AI_PASSIVE;
-#endif
-#ifdef AI_ADDRCONFIG
- ai_hints.ai_flags |= AI_ADDRCONFIG;
-#endif
- ai_hints.ai_family = AF_UNSPEC;
- ai_hints.ai_socktype = SOCK_DGRAM;
- ai_hints.ai_protocol = IPPROTO_UDP;
+ struct addrinfo ai_hints = {
+ .ai_family = AF_UNSPEC,
+ .ai_flags = AI_ADDRCONFIG | AI_PASSIVE,
+ .ai_protocol = IPPROTO_UDP,
+ .ai_socktype = SOCK_DGRAM
+ };
ai_return = getaddrinfo (node, service, &ai_hints, &ai_list);
if (ai_return != 0)
return (-1);
}
- for (ai_ptr = ai_list; ai_ptr != NULL; ai_ptr = ai_ptr->ai_next) /* {{{ */
+ for (struct addrinfo *ai_ptr = ai_list; ai_ptr != NULL; ai_ptr = ai_ptr->ai_next) /* {{{ */
{
socket_entry_t *tmp;
if (ai_ptr->ai_family == AF_INET)
{
struct sockaddr_in *addr;
- struct ip_mreq mreq;
int loop;
addr = (struct sockaddr_in *) ai_ptr->ai_addr;
sstrerror (errno, errbuf, sizeof (errbuf)));
}
- memset (&mreq, 0, sizeof (mreq));
- mreq.imr_multiaddr.s_addr = addr->sin_addr.s_addr;
- mreq.imr_interface.s_addr = htonl (INADDR_ANY);
+ struct ip_mreq mreq = {
+ .imr_multiaddr.s_addr = addr->sin_addr.s_addr,
+ .imr_interface.s_addr = htonl (INADDR_ANY)
+ };
status = setsockopt (sockets[sockets_num].fd, IPPROTO_IP, IP_ADD_MEMBERSHIP,
(void *) &mreq, sizeof (mreq));
else if (ai_ptr->ai_family == AF_INET6)
{
struct sockaddr_in6 *addr;
- struct ipv6_mreq mreq;
int loop;
addr = (struct sockaddr_in6 *) ai_ptr->ai_addr;
sstrerror (errno, errbuf, sizeof (errbuf)));
}
- memset (&mreq, 0, sizeof (mreq));
+ struct ipv6_mreq mreq = {
+ .ipv6mr_interface = 0 /* any */
+ };
+
memcpy (&mreq.ipv6mr_multiaddr,
&addr->sin6_addr, sizeof (addr->sin6_addr));
- mreq.ipv6mr_interface = 0; /* any */
status = setsockopt (sockets[sockets_num].fd, IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP,
(void *) &mreq, sizeof (mreq));
if (status != 0)
static int request_meta_data (const char *host, const char *name) /* {{{ */
{
- Ganglia_metadata_msg msg;
- char buffer[BUFF_SIZE];
+ Ganglia_metadata_msg msg = { 0 };
+ char buffer[BUFF_SIZE] = { 0 };
unsigned int buffer_size;
XDR xdr;
- size_t i;
-
- memset (&msg, 0, sizeof (msg));
msg.id = gmetadata_request;
msg.Ganglia_metadata_msg_u.grequest.metric_id.host = strdup (host);
return (-1);
}
- memset (buffer, 0, sizeof (buffer));
xdrmem_create (&xdr, buffer, sizeof (buffer), XDR_ENCODE);
if (!xdr_Ganglia_metadata_msg (&xdr, &msg))
host, name);
pthread_mutex_lock (&mc_send_sockets_lock);
- for (i = 0; i < mc_send_sockets_num; i++)
+ for (size_t i = 0; i < mc_send_sockets_num; i++)
{
ssize_t status = sendto (mc_send_sockets[i].fd, buffer, (size_t) buffer_size,
/* flags = */ 0,
case gmetric_float:
case gmetric_double:
{
- Ganglia_value_msg msg;
+ Ganglia_value_msg msg = { 0 };
- memset (&msg, 0, sizeof (msg));
if (xdr_Ganglia_value_msg (&xdr, &msg))
mc_handle_value_msg (&msg);
break;
case gmetadata_full:
case gmetadata_request:
{
- Ganglia_metadata_msg msg;
- memset (&msg, 0, sizeof (msg));
+ Ganglia_metadata_msg msg = { 0 };
if (xdr_Ganglia_metadata_msg (&xdr, &msg))
mc_handle_metadata_msg (&msg);
break;
{
socket_entry_t *mc_receive_socket_entries;
int status;
- size_t i;
mc_receive_socket_entries = NULL;
status = create_sockets (&mc_receive_socket_entries, &mc_receive_sockets_num,
if (mc_receive_sockets == NULL)
{
ERROR ("gmond plugin: calloc failed.");
- for (i = 0; i < mc_receive_sockets_num; i++)
+ for (size_t i = 0; i < mc_receive_sockets_num; i++)
close (mc_receive_socket_entries[i].fd);
free (mc_receive_socket_entries);
mc_receive_socket_entries = NULL;
return ((void *) -1);
}
- for (i = 0; i < mc_receive_sockets_num; i++)
+ for (size_t i = 0; i < mc_receive_sockets_num; i++)
{
mc_receive_sockets[i].fd = mc_receive_socket_entries[i].fd;
mc_receive_sockets[i].events = POLLIN | POLLPRI;
break;
}
- for (i = 0; i < mc_receive_sockets_num; i++)
+ for (size_t i = 0; i < mc_receive_sockets_num; i++)
{
if (mc_receive_sockets[i].revents != 0)
mc_handle_socket (mc_receive_sockets + i);
static int gmond_config_add_metric (oconfig_item_t *ci) /* {{{ */
{
metric_map_t *map;
- int i;
if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING))
{
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;
if (strcasecmp ("Type", child->key) == 0)
static int gmond_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;
if (strcasecmp ("MCReceiveFrom", child->key) == 0)
static int gmond_shutdown (void) /* {{{ */
{
- size_t i;
-
mc_receive_thread_stop ();
pthread_mutex_lock (&mc_send_sockets_lock);
- for (i = 0; i < mc_send_sockets_num; i++)
+ for (size_t i = 0; i < mc_send_sockets_num; i++)
{
close (mc_send_sockets[i].fd);
mc_send_sockets[i].fd = -1;
--- /dev/null
+/**
+ * collectd - src/gps.c
+ * Copyright (C) 2015 Nicolas JOURDEN
+ *
+ * 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:
+ * Nicolas JOURDEN <nicolas.jourden at laposte.net>
+ * Florian octo Forster <octo at collectd.org>
+ * Marc Fournier <marc.fournier at camptocamp.com>
+ **/
+
+#include "collectd.h"
+#include "common.h"
+#include "plugin.h"
+#include "utils_time.h"
+
+#define CGPS_TRUE 1
+#define CGPS_FALSE 0
+#define CGPS_DEFAULT_HOST "localhost"
+#define CGPS_DEFAULT_PORT "2947" /* DEFAULT_GPSD_PORT */
+#define CGPS_DEFAULT_TIMEOUT MS_TO_CDTIME_T (15)
+#define CGPS_DEFAULT_PAUSE_CONNECT TIME_T_TO_CDTIME_T (5)
+#define CGPS_MAX_ERROR 100
+#define CGPS_CONFIG "?WATCH={\"enable\":true,\"json\":true,\"nmea\":false}\r\n"
+
+#include <gps.h>
+#include <pthread.h>
+
+typedef struct {
+ char *host;
+ char *port;
+ cdtime_t timeout;
+ cdtime_t pause_connect;
+} cgps_config_t;
+
+typedef struct {
+ gauge_t sats_used;
+ gauge_t sats_visible;
+ gauge_t hdop;
+ gauge_t vdop;
+} cgps_data_t;
+
+static cgps_config_t cgps_config_data;
+
+static cgps_data_t cgps_data = {NAN, NAN, NAN, NAN};
+
+static pthread_t cgps_thread_id;
+static pthread_mutex_t cgps_data_lock = PTHREAD_MUTEX_INITIALIZER;
+static pthread_mutex_t cgps_thread_lock = PTHREAD_MUTEX_INITIALIZER;
+static int cgps_thread_shutdown = CGPS_FALSE;
+static int cgps_thread_running = CGPS_FALSE;
+
+/**
+ * Non blocking pause for the thread.
+ */
+static int cgps_thread_pause(cdtime_t pTime)
+{
+ cdtime_t now;
+ now = cdtime ();
+ struct timespec pause_th;
+ CDTIME_T_TO_TIMESPEC (MS_TO_CDTIME_T(10), &pause_th);
+ while (CGPS_TRUE)
+ {
+ if ( (cdtime () - now) > pTime )
+ {
+ break;
+ }
+
+ pthread_mutex_lock (&cgps_thread_lock);
+ if (cgps_thread_shutdown == CGPS_TRUE)
+ {
+ return CGPS_FALSE;
+ }
+ pthread_mutex_unlock (&cgps_thread_lock);
+ nanosleep (&pause_th, NULL);
+ }
+
+ return CGPS_TRUE;
+}
+
+/**
+ * Thread reading from gpsd.
+ */
+static void * cgps_thread (void * pData)
+{
+ struct gps_data_t gpsd_conn;
+ unsigned int err_count;
+ cgps_thread_running = CGPS_TRUE;
+
+ while (CGPS_TRUE)
+ {
+ pthread_mutex_lock (&cgps_thread_lock);
+ if (cgps_thread_shutdown == CGPS_TRUE)
+ {
+ goto quit;
+ }
+ pthread_mutex_unlock (&cgps_thread_lock);
+
+ err_count = 0;
+
+#if GPSD_API_MAJOR_VERSION > 4
+ int status = gps_open (cgps_config_data.host, cgps_config_data.port, &gpsd_conn);
+#else
+ int status = gps_open_r (cgps_config_data.host, cgps_config_data.port, &gpsd_conn);
+#endif
+ if (status < 0)
+ {
+ WARNING ("gps plugin: connecting to %s:%s failed: %s",
+ cgps_config_data.host, cgps_config_data.port, gps_errstr (status));
+
+ // Here we make a pause until a new tentative to connect, we check also if
+ // the thread does not need to stop.
+ if (cgps_thread_pause(cgps_config_data.pause_connect) == CGPS_FALSE)
+ {
+ goto quit;
+ }
+
+ continue;
+ }
+
+ gps_stream (&gpsd_conn, WATCH_ENABLE | WATCH_JSON | WATCH_NEWSTYLE, NULL);
+ gps_send (&gpsd_conn, CGPS_CONFIG);
+
+ while (CGPS_TRUE)
+ {
+ pthread_mutex_lock (&cgps_thread_lock);
+ if (cgps_thread_shutdown == CGPS_TRUE)
+ {
+ goto stop;
+ }
+ pthread_mutex_unlock (&cgps_thread_lock);
+
+#if GPSD_API_MAJOR_VERSION > 4
+ long timeout_us = CDTIME_T_TO_US (cgps_config_data.timeout);
+ if (!gps_waiting (&gpsd_conn, (int) timeout_us ))
+#else
+ if (!gps_waiting (&gpsd_conn))
+#endif
+ {
+ continue;
+ }
+
+ if (gps_read (&gpsd_conn) == -1)
+ {
+ WARNING ("gps plugin: incorrect data! (err_count: %d)", err_count);
+ err_count++;
+
+ if (err_count > CGPS_MAX_ERROR)
+ {
+ // Server is not responding ...
+ if (gps_send (&gpsd_conn, CGPS_CONFIG) == -1)
+ {
+ WARNING ("gps plugin: gpsd seems to be down, reconnecting");
+ gps_close (&gpsd_conn);
+ break;
+ }
+ // Server is responding ...
+ else
+ {
+ err_count = 0;
+ }
+ }
+
+ continue;
+ }
+
+ pthread_mutex_lock (&cgps_data_lock);
+
+ // Number of sats in view:
+ cgps_data.sats_used = (gauge_t) gpsd_conn.satellites_used;
+ cgps_data.sats_visible = (gauge_t) gpsd_conn.satellites_visible;
+
+ // dilution of precision:
+ cgps_data.vdop = NAN;
+ cgps_data.hdop = NAN;
+ if (cgps_data.sats_used > 0)
+ {
+ cgps_data.hdop = gpsd_conn.dop.hdop;
+ cgps_data.vdop = gpsd_conn.dop.vdop;
+ }
+
+ DEBUG ("gps plugin: %.0f sats used (of %.0f visible), hdop = %.3f, vdop = %.3f",
+ cgps_data.sats_used, cgps_data.sats_visible, cgps_data.hdop, cgps_data.vdop);
+
+ pthread_mutex_unlock (&cgps_data_lock);
+ }
+ }
+
+stop:
+ DEBUG ("gps plugin: thread closing gpsd connection ... ");
+ gps_stream (&gpsd_conn, WATCH_DISABLE, NULL);
+ gps_close (&gpsd_conn);
+quit:
+ DEBUG ("gps plugin: thread shutting down ... ");
+ cgps_thread_running = CGPS_FALSE;
+ pthread_mutex_unlock (&cgps_thread_lock);
+ pthread_exit (NULL);
+}
+
+
+/**
+ * Submit a piece of the data.
+ */
+static void cgps_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, "gps", sizeof (vl.plugin));
+ sstrncpy (vl.type, type, sizeof (vl.type));
+ sstrncpy (vl.type_instance, type_instance, sizeof (vl.type_instance));
+
+ plugin_dispatch_values (&vl);
+}
+
+/**
+ * Read the data and submit by piece.
+ */
+static int cgps_read (void)
+{
+ cgps_data_t data_copy;
+
+ pthread_mutex_lock (&cgps_data_lock);
+ data_copy = cgps_data;
+ pthread_mutex_unlock (&cgps_data_lock);
+
+ cgps_submit ("dilution_of_precision", data_copy.hdop, "horizontal");
+ cgps_submit ("dilution_of_precision", data_copy.vdop, "vertical");
+ cgps_submit ("satellites", data_copy.sats_used, "used");
+ cgps_submit ("satellites", data_copy.sats_visible, "visible");
+
+ return (0);
+}
+
+/**
+ * Read configuration.
+ */
+static int cgps_config (oconfig_item_t *ci)
+{
+ int i;
+
+ for (i = 0; i < ci->children_num; i++)
+ {
+ oconfig_item_t *child = ci->children + i;
+
+ if (strcasecmp ("Host", child->key) == 0)
+ cf_util_get_string (child, &cgps_config_data.host);
+ else if (strcasecmp ("Port", child->key) == 0)
+ cf_util_get_service (child, &cgps_config_data.port);
+ else if (strcasecmp ("Timeout", child->key) == 0)
+ cf_util_get_cdtime (child, &cgps_config_data.timeout);
+ else if (strcasecmp ("PauseConnect", child->key) == 0)
+ cf_util_get_cdtime (child, &cgps_config_data.pause_connect);
+ else
+ WARNING ("gps plugin: Ignoring unknown config option \"%s\".", child->key);
+ }
+
+ // Controlling the value for timeout:
+ // If set too high it blocks the reading (> 5 s), too low it gets not reading (< 500 us).
+ // To avoid any issues we replace "out of range" value by the default value.
+ if (
+ cgps_config_data.timeout > TIME_T_TO_CDTIME_T(5)
+ ||
+ cgps_config_data.timeout < US_TO_CDTIME_T(500)
+ )
+ {
+ WARNING ("gps plugin: timeout set to %.6f sec. setting to default (%.6f).",
+ CDTIME_T_TO_DOUBLE(cgps_config_data.timeout),
+ CDTIME_T_TO_DOUBLE(CGPS_DEFAULT_TIMEOUT)
+ );
+ cgps_config_data.timeout = CGPS_DEFAULT_TIMEOUT;
+ }
+
+ return (0);
+}
+
+/**
+ * Init.
+ */
+static int cgps_init (void)
+{
+ int status;
+
+ if (cgps_thread_running == CGPS_TRUE)
+ {
+ DEBUG ("gps plugin: error gps thread already running ... ");
+ return 0;
+ }
+
+ DEBUG ("gps plugin: config{host: \"%s\", port: \"%s\", timeout: %.6f sec., pause connect: %.3f sec.}",
+ cgps_config_data.host, cgps_config_data.port,
+ CDTIME_T_TO_DOUBLE (cgps_config_data.timeout),
+ CDTIME_T_TO_DOUBLE (cgps_config_data.pause_connect));
+
+ status = plugin_thread_create (&cgps_thread_id, NULL, cgps_thread, NULL);
+ if (status != 0)
+ {
+ ERROR ("gps plugin: pthread_create() failed.");
+ return (-1);
+ }
+
+ return (0);
+}
+
+/**
+ * Shutdown.
+ */
+static int cgps_shutdown (void)
+{
+ void * res;
+
+ pthread_mutex_lock (&cgps_thread_lock);
+ cgps_thread_shutdown = CGPS_TRUE;
+ pthread_mutex_unlock (&cgps_thread_lock);
+
+ pthread_join(cgps_thread_id, &res);
+ free(res);
+
+ // Clean mutex:
+ pthread_mutex_unlock(&cgps_thread_lock);
+ pthread_mutex_destroy(&cgps_thread_lock);
+ pthread_mutex_unlock(&cgps_data_lock);
+ pthread_mutex_destroy(&cgps_data_lock);
+
+ sfree (cgps_config_data.port);
+ sfree (cgps_config_data.host);
+
+ return (0);
+}
+
+/**
+ * Register the module.
+ */
+void module_register (void)
+{
+ cgps_config_data.host = sstrdup (CGPS_DEFAULT_HOST);
+ cgps_config_data.port = sstrdup (CGPS_DEFAULT_PORT);
+ cgps_config_data.timeout = CGPS_DEFAULT_TIMEOUT;
+ cgps_config_data.pause_connect = CGPS_DEFAULT_PAUSE_CONNECT;
+
+ plugin_register_complex_config ("gps", cgps_config);
+ plugin_register_init ("gps", cgps_init);
+ plugin_register_read ("gps", cgps_read);
+ plugin_register_shutdown ("gps", cgps_shutdown);
+}
#include <fstream>
#include <iostream>
+#include <queue>
#include <vector>
#include "collectd.grpc.pb.h"
#include "collectd.h"
#include "common.h"
-#include "configfile.h"
#include "plugin.h"
#include "daemon/utils_cache.h"
using collectd::Collectd;
-using collectd::DispatchValuesRequest;
-using collectd::DispatchValuesReply;
+using collectd::PutValuesRequest;
+using collectd::PutValuesResponse;
using collectd::QueryValuesRequest;
-using collectd::QueryValuesReply;
+using collectd::QueryValuesResponse;
using google::protobuf::util::TimeUtil;
msg->set_allocated_interval(new google::protobuf::Duration(d));
for (size_t i = 0; i < vl->values_len; ++i) {
- auto v = msg->add_value();
+ auto v = msg->add_values();
switch (ds->ds[i].type) {
case DS_TYPE_COUNTER:
v->set_counter(vl->values[i].counter);
return grpc::Status(grpc::StatusCode::INTERNAL,
grpc::string("unknown value type"));
}
+
+ auto name = msg->add_ds_names();
+ name->assign(ds->ds[i].name);
}
return grpc::Status::OK;
size_t values_len = 0;
status = grpc::Status::OK;
- for (auto v : msg.value()) {
+ for (auto v : msg.values()) {
value_t *val = (value_t *)realloc(values, (values_len + 1) * sizeof(*values));
if (!val) {
status = grpc::Status(grpc::StatusCode::RESOURCE_EXHAUSTED,
} /* unmarshal_value_list() */
/*
- * request call-backs and call objects
+ * Collectd service
*/
+class CollectdImpl : public collectd::Collectd::Service {
+public:
+ grpc::Status QueryValues(grpc::ServerContext *ctx, QueryValuesRequest const *req, grpc::ServerWriter<QueryValuesResponse> *writer) override {
+ value_list_t match;
+ auto status = unmarshal_ident(req->identifier(), &match, false);
+ if (!status.ok()) {
+ return status;
+ }
-static grpc::Status Process(grpc::ServerContext *ctx,
- DispatchValuesRequest request, DispatchValuesReply *reply)
-{
- value_list_t vl = VALUE_LIST_INIT;
- auto status = unmarshal_value_list(request.values(), &vl);
- if (!status.ok())
- return status;
-
- if (plugin_dispatch_values(&vl))
- status = grpc::Status(grpc::StatusCode::INTERNAL,
- grpc::string("failed to enqueue values for writing"));
- return status;
-} /* Process(): DispatchValues */
+ std::queue<value_list_t> value_lists;
+ status = this->queryValuesRead(&match, &value_lists);
+ if (status.ok()) {
+ status = this->queryValuesWrite(ctx, writer, &value_lists);
+ }
-static grpc::Status Process(grpc::ServerContext *ctx,
- QueryValuesRequest request, QueryValuesReply *reply)
-{
- uc_iter_t *iter;
- char *name = NULL;
+ while (!value_lists.empty()) {
+ auto vl = value_lists.front();
+ value_lists.pop();
+ sfree(vl.values);
+ }
- value_list_t matcher;
- auto status = unmarshal_ident(request.identifier(), &matcher, false);
- if (!status.ok())
return status;
-
- if ((iter = uc_get_iterator()) == NULL) {
- return grpc::Status(grpc::StatusCode::INTERNAL,
- grpc::string("failed to query values: cannot create iterator"));
}
- while (uc_iterator_next(iter, &name) == 0) {
- value_list_t res;
- if (parse_identifier_vl(name, &res) != 0)
- return grpc::Status(grpc::StatusCode::INTERNAL,
- grpc::string("failed to parse identifier"));
+ grpc::Status PutValues(grpc::ServerContext *ctx,
+ grpc::ServerReader<PutValuesRequest> *reader,
+ PutValuesResponse *res) override {
+ PutValuesRequest req;
- if (!ident_matches(&res, &matcher))
- continue;
+ while (reader->Read(&req)) {
+ value_list_t vl = VALUE_LIST_INIT;
+ auto status = unmarshal_value_list(req.value_list(), &vl);
+ if (!status.ok())
+ return status;
- if (uc_iterator_get_time(iter, &res.time) < 0)
- return grpc::Status(grpc::StatusCode::INTERNAL,
- grpc::string("failed to retrieve value timestamp"));
- if (uc_iterator_get_interval(iter, &res.interval) < 0)
- return grpc::Status(grpc::StatusCode::INTERNAL,
- grpc::string("failed to retrieve value interval"));
- if (uc_iterator_get_values(iter, &res.values, &res.values_len) < 0)
- return grpc::Status(grpc::StatusCode::INTERNAL,
- grpc::string("failed to retrieve values"));
-
- auto vl = reply->add_values();
- status = marshal_value_list(&res, vl);
- free(res.values);
- if (!status.ok())
- return status;
- }
-
- uc_iterator_destroy(iter);
-
- return grpc::Status::OK;
-} /* Process(): QueryValues */
-
-class Call
-{
-public:
- Call(Collectd::AsyncService *service, grpc::ServerCompletionQueue *cq)
- : service_(service), cq_(cq), status_(CREATE)
- { }
-
- virtual ~Call()
- { }
-
- void Handle()
- {
- if (status_ == CREATE) {
- Create();
- status_ = PROCESS;
- }
- else if (status_ == PROCESS) {
- Process();
- status_ = FINISH;
- }
- else {
- GPR_ASSERT(status_ == FINISH);
- Finish();
+ if (plugin_dispatch_values(&vl))
+ return grpc::Status(grpc::StatusCode::INTERNAL,
+ grpc::string("failed to enqueue values for writing"));
}
- } /* Handle() */
-
-protected:
- virtual void Create() = 0;
- virtual void Process() = 0;
- virtual void Finish() = 0;
- Collectd::AsyncService *service_;
- grpc::ServerCompletionQueue *cq_;
- grpc::ServerContext ctx_;
+ res->Clear();
+ return grpc::Status::OK;
+ }
private:
- enum CallStatus { CREATE, PROCESS, FINISH };
- CallStatus status_;
-}; /* class Call */
+ grpc::Status queryValuesRead(value_list_t const *match, std::queue<value_list_t> *value_lists) {
+ uc_iter_t *iter;
+ if ((iter = uc_get_iterator()) == NULL) {
+ return grpc::Status(grpc::StatusCode::INTERNAL,
+ grpc::string("failed to query values: cannot create iterator"));
+ }
-template<typename RequestT, typename ReplyT>
-class RpcCall final : public Call
-{
- typedef void (Collectd::AsyncService::*CreatorT)(grpc::ServerContext *,
- RequestT *, grpc::ServerAsyncResponseWriter<ReplyT> *,
- grpc::CompletionQueue *, grpc::ServerCompletionQueue *, void *);
+ grpc::Status status = grpc::Status::OK;
+ char *name = NULL;
+ while (uc_iterator_next(iter, &name) == 0) {
+ value_list_t vl;
+ if (parse_identifier_vl(name, &vl) != 0) {
+ status = grpc::Status(grpc::StatusCode::INTERNAL,
+ grpc::string("failed to parse identifier"));
+ break;
+ }
-public:
- RpcCall(Collectd::AsyncService *service,
- CreatorT creator, grpc::ServerCompletionQueue *cq)
- : Call(service, cq), creator_(creator), responder_(&ctx_)
- {
- Handle();
- } /* RpcCall() */
+ if (!ident_matches(&vl, match))
+ continue;
- virtual ~RpcCall()
- { }
+ if (uc_iterator_get_time(iter, &vl.time) < 0) {
+ status = grpc::Status(grpc::StatusCode::INTERNAL,
+ grpc::string("failed to retrieve value timestamp"));
+ break;
+ }
+ if (uc_iterator_get_interval(iter, &vl.interval) < 0) {
+ status = grpc::Status(grpc::StatusCode::INTERNAL,
+ grpc::string("failed to retrieve value interval"));
+ break;
+ }
+ if (uc_iterator_get_values(iter, &vl.values, &vl.values_len) < 0) {
+ status = grpc::Status(grpc::StatusCode::INTERNAL,
+ grpc::string("failed to retrieve values"));
+ break;
+ }
-private:
- void Create()
- {
- (service_->*creator_)(&ctx_, &request_, &responder_, cq_, cq_, this);
- } /* Create() */
+ value_lists->push(vl);
+ } // while (uc_iterator_next(iter, &name) == 0)
- void Process()
- {
- // Add a new request object to the queue.
- new RpcCall<RequestT, ReplyT>(service_, creator_, cq_);
- grpc::Status status = ::Process(&ctx_, request_, &reply_);
- responder_.Finish(reply_, status, this);
- } /* Process() */
+ uc_iterator_destroy(iter);
+ return status;
+ }
- void Finish()
- {
- delete this;
- } /* Finish() */
+ grpc::Status queryValuesWrite(grpc::ServerContext *ctx,
+ grpc::ServerWriter<QueryValuesResponse> *writer,
+ std::queue<value_list_t> *value_lists) {
+ while (!value_lists->empty()) {
+ auto vl = value_lists->front();
+ QueryValuesResponse res;
+ res.Clear();
+
+ auto status = marshal_value_list(&vl, res.mutable_value_list());
+ if (!status.ok()) {
+ return status;
+ }
- CreatorT creator_;
+ if (!writer->Write(res)) {
+ return grpc::Status::CANCELLED;
+ }
- RequestT request_;
- ReplyT reply_;
+ value_lists->pop();
+ sfree(vl.values);
+ }
- grpc::ServerAsyncResponseWriter<ReplyT> responder_;
-}; /* class RpcCall */
+ return grpc::Status::OK;
+ }
+};
/*
* gRPC server implementation
*/
-
class CollectdServer final
{
public:
}
}
- builder.RegisterService(&service_);
- cq_ = builder.AddCompletionQueue();
+ builder.RegisterService(&collectd_service_);
+
server_ = builder.BuildAndStart();
} /* Start() */
void Shutdown()
{
server_->Shutdown();
- cq_->Shutdown();
} /* Shutdown() */
- void Mainloop()
- {
- // Register request types.
- new RpcCall<DispatchValuesRequest, DispatchValuesReply>(&service_,
- &Collectd::AsyncService::RequestDispatchValues, cq_.get());
- new RpcCall<QueryValuesRequest, QueryValuesReply>(&service_,
- &Collectd::AsyncService::RequestQueryValues, cq_.get());
-
- while (true) {
- void *req = NULL;
- bool ok = false;
-
- if (!cq_->Next(&req, &ok))
- break; // Queue shut down.
- if (!ok) {
- ERROR("grpc: Failed to read from queue");
- break;
- }
-
- static_cast<Call *>(req)->Handle();
- }
- } /* Mainloop() */
-
private:
- Collectd::AsyncService service_;
+ CollectdImpl collectd_service_;
std::unique_ptr<grpc::Server> server_;
- std::unique_ptr<grpc::ServerCompletionQueue> cq_;
}; /* class CollectdServer */
+class CollectdClient final
+{
+public:
+ CollectdClient(std::shared_ptr<grpc::ChannelInterface> channel) : stub_(Collectd::NewStub(channel)) {
+ }
+
+ int PutValues(value_list_t const *vl) {
+ grpc::ClientContext ctx;
+
+ PutValuesRequest req;
+ auto status = marshal_value_list(vl, req.mutable_value_list());
+ if (!status.ok()) {
+ ERROR("grpc: Marshalling value_list_t failed.");
+ return -1;
+ }
+
+ PutValuesResponse res;
+ auto stream = stub_->PutValues(&ctx, &res);
+ if (!stream->Write(req)) {
+ NOTICE("grpc: Broken stream.");
+ /* intentionally not returning. */
+ }
+
+ stream->WritesDone();
+ status = stream->Finish();
+ if (!status.ok()) {
+ ERROR ("grpc: Error while closing stream.");
+ return -1;
+ }
+
+ return 0;
+ } /* int PutValues */
+
+private:
+ std::unique_ptr<Collectd::Stub> stub_;
+};
+
static CollectdServer *server = nullptr;
/*
* collectd plugin interface
*/
-
extern "C" {
- static pthread_t *workers;
- static size_t workers_num = 5;
+ static void c_grpc_destroy_write_callback (void *ptr) {
+ delete (CollectdClient *) ptr;
+ }
- static void *worker_thread(void *arg)
- {
- CollectdServer *s = (CollectdServer *)arg;
- s->Mainloop();
- return NULL;
- } /* worker_thread() */
+ static int c_grpc_write(__attribute__((unused)) data_set_t const *ds,
+ value_list_t const *vl,
+ user_data_t *ud) {
+ CollectdClient *c = (CollectdClient *) ud->data;
+ return c->PutValues(vl);
+ }
static int c_grpc_config_listen(oconfig_item_t *ci)
{
return -1;
}
}
- else if (!strcasecmp("SSLRootCerts", child->key)) {
+ else if (!strcasecmp("SSLCACertificateFile", child->key)) {
char *certs = NULL;
if (cf_util_get_string(child, &certs)) {
ERROR("grpc: Option `%s` expects a string value",
}
ssl_opts->pem_root_certs = read_file(certs);
}
- else if (!strcasecmp("SSLServerKey", child->key)) {
+ else if (!strcasecmp("SSLCertificateKeyFile", child->key)) {
char *key = NULL;
if (cf_util_get_string(child, &key)) {
ERROR("grpc: Option `%s` expects a string value",
}
pkcp.private_key = read_file(key);
}
- else if (!strcasecmp("SSLServerCert", child->key)) {
+ else if (!strcasecmp("SSLCertificateFile", child->key)) {
char *cert = NULL;
if (cf_util_get_string(child, &cert)) {
ERROR("grpc: Option `%s` expects a string value",
return 0;
} /* c_grpc_config_listen() */
+ static int c_grpc_config_server(oconfig_item_t *ci)
+ {
+ if ((ci->values_num != 2)
+ || (ci->values[0].type != OCONFIG_TYPE_STRING)
+ || (ci->values[1].type != OCONFIG_TYPE_STRING)) {
+ ERROR("grpc: The `%s` config option needs exactly "
+ "two string argument (address and port).", ci->key);
+ return -1;
+ }
+
+ grpc::SslCredentialsOptions ssl_opts;
+ bool use_ssl = false;
+
+ for (int i = 0; i < ci->children_num; i++) {
+ oconfig_item_t *child = ci->children + i;
+
+ if (!strcasecmp("EnableSSL", child->key)) {
+ if (cf_util_get_boolean(child, &use_ssl)) {
+ return -1;
+ }
+ }
+ else if (!strcasecmp("SSLCACertificateFile", child->key)) {
+ char *certs = NULL;
+ if (cf_util_get_string(child, &certs)) {
+ return -1;
+ }
+ ssl_opts.pem_root_certs = read_file(certs);
+ }
+ else if (!strcasecmp("SSLCertificateKeyFile", child->key)) {
+ char *key = NULL;
+ if (cf_util_get_string(child, &key)) {
+ return -1;
+ }
+ ssl_opts.pem_private_key = read_file(key);
+ }
+ else if (!strcasecmp("SSLCertificateFile", child->key)) {
+ char *cert = NULL;
+ if (cf_util_get_string(child, &cert)) {
+ return -1;
+ }
+ ssl_opts.pem_cert_chain = read_file(cert);
+ }
+ else {
+ WARNING("grpc: Option `%s` not allowed in <%s> block.",
+ child->key, ci->key);
+ }
+ }
+
+ auto node = grpc::string(ci->values[0].value.string);
+ auto service = grpc::string(ci->values[1].value.string);
+ auto addr = node + ":" + service;
+
+ CollectdClient *client;
+ if (use_ssl) {
+ auto channel_creds = grpc::SslCredentials(ssl_opts);
+ auto channel = grpc::CreateChannel(addr, channel_creds);
+ client = new CollectdClient(channel);
+ } else {
+ auto channel = grpc::CreateChannel(addr, grpc::InsecureChannelCredentials());
+ client = new CollectdClient(channel);
+ }
+
+ auto callback_name = grpc::string("grpc/") + addr;
+ user_data_t ud = {
+ .data = client,
+ .free_func = c_grpc_destroy_write_callback,
+ };
+
+ plugin_register_write (callback_name.c_str(), c_grpc_write, &ud);
+ return 0;
+ } /* c_grpc_config_server() */
+
static int c_grpc_config(oconfig_item_t *ci)
{
int i;
if (c_grpc_config_listen(child))
return -1;
}
- else if (!strcasecmp("WorkerThreads", child->key)) {
- int n;
- if (cf_util_get_int(child, &n))
+ else if (!strcasecmp("Server", child->key)) {
+ if (c_grpc_config_server(child))
return -1;
- workers_num = (size_t)n;
}
+
else {
WARNING("grpc: Option `%s` not allowed here.", child->key);
}
static int c_grpc_init(void)
{
server = new CollectdServer();
- size_t i;
-
- if (! server) {
+ if (!server) {
ERROR("grpc: Failed to create server");
return -1;
}
- workers = (pthread_t *)calloc(workers_num, sizeof(*workers));
- if (! workers) {
- delete server;
- server = nullptr;
-
- ERROR("grpc: Failed to allocate worker threads");
- return -1;
- }
-
server->Start();
- for (i = 0; i < workers_num; i++) {
- plugin_thread_create(&workers[i], /* attr = */ NULL,
- worker_thread, server);
- }
- INFO("grpc: Started %zu workers", workers_num);
return 0;
} /* c_grpc_init() */
static int c_grpc_shutdown(void)
{
- size_t i;
-
if (!server)
- return -1;
+ return 0;
server->Shutdown();
- INFO("grpc: Waiting for %zu workers to terminate", workers_num);
- for (i = 0; i < workers_num; i++)
- pthread_join(workers[i], NULL);
- free(workers);
- workers = NULL;
- workers_num = 0;
-
delete server;
server = nullptr;
**/
#include "collectd.h"
+
#include "common.h"
#include "plugin.h"
-#include "configfile.h"
# include <netdb.h>
# include <netinet/in.h>
const char *host;
const char *port;
- struct addrinfo ai_hints;
- struct addrinfo *ai_list, *ai_ptr;
+ struct addrinfo *ai_list;
int ai_return;
- memset (&ai_hints, '\0', sizeof (ai_hints));
- ai_hints.ai_flags = 0;
-#ifdef AI_ADDRCONFIG
- ai_hints.ai_flags |= AI_ADDRCONFIG;
-#endif
- ai_hints.ai_family = PF_UNSPEC;
- ai_hints.ai_socktype = SOCK_STREAM;
- ai_hints.ai_protocol = IPPROTO_TCP;
-
host = hddtemp_host;
if (host == NULL)
host = HDDTEMP_DEF_HOST;
if (strlen (port) == 0)
port = HDDTEMP_DEF_PORT;
+ struct addrinfo ai_hints = {
+ .ai_flags = AI_ADDRCONFIG,
+ .ai_family = AF_UNSPEC,
+ .ai_protocol = IPPROTO_TCP,
+ .ai_socktype = SOCK_STREAM
+ };
+
if ((ai_return = getaddrinfo (host, port, &ai_hints, &ai_list)) != 0)
{
char errbuf[1024];
}
fd = -1;
- for (ai_ptr = ai_list; ai_ptr != NULL; ai_ptr = ai_ptr->ai_next)
+ for (struct addrinfo *ai_ptr = ai_list; ai_ptr != NULL; ai_ptr = ai_ptr->ai_next)
{
/* create our socket descriptor */
fd = socket (ai_ptr->ai_family, ai_ptr->ai_socktype,
static void hddtemp_submit (char *type_instance, 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, "hddtemp", sizeof (vl.plugin));
char *saveptr;
int num_fields;
int num_disks;
- int i;
/* get data from daemon */
if (hddtemp_query_daemon (buf, sizeof (buf)) < 0)
num_disks = num_fields / 4;
- for (i = 0; i < num_disks; i++)
+ for (int i = 0; i < num_disks; i++)
{
char *name;
double temperature;
--- /dev/null
+/*-
+ * collectd - src/hugepages.c
+ * MIT License
+ *
+ * Copyright(c) 2016 Intel Corporation. All rights reserved.
+ *
+ * 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:
+ * Jaroslav Safka <jaroslavx.safka@intel.com>
+ * Kim-Marie Jones <kim-marie.jones@intel.com>
+ * Florian Forster <octo at collectd.org>
+ */
+
+#include "collectd.h"
+
+#include "common.h" /* auxiliary functions */
+#include "plugin.h" /* plugin_register_*, plugin_dispatch_values */
+
+static const char g_plugin_name[] = "hugepages";
+
+static _Bool g_flag_rpt_numa = 1;
+static _Bool g_flag_rpt_mm = 1;
+
+static _Bool g_values_pages = 1;
+static _Bool g_values_bytes = 0;
+static _Bool g_values_percent = 0;
+
+#define HP_HAVE_NR 0x01
+#define HP_HAVE_SURPLUS 0x02
+#define HP_HAVE_FREE 0x04
+#define HP_HAVE_ALL 0x07
+
+struct entry_info {
+ char *d_name;
+ const char *node;
+ size_t page_size_kb;
+
+ gauge_t nr;
+ gauge_t surplus;
+ gauge_t free;
+ uint8_t flags;
+};
+
+static int hp_config(oconfig_item_t *ci) {
+ for (int i = 0; i < ci->children_num; i++) {
+ oconfig_item_t *child = ci->children + i;
+ if (strcasecmp("ReportPerNodeHP", child->key) == 0)
+ cf_util_get_boolean(child, &g_flag_rpt_numa);
+ else if (strcasecmp("ReportRootHP", child->key) == 0)
+ cf_util_get_boolean(child, &g_flag_rpt_mm);
+ else if (strcasecmp("ValuesPages", child->key) == 0)
+ cf_util_get_boolean(child, &g_values_pages);
+ else if (strcasecmp("ValuesBytes", child->key) == 0)
+ cf_util_get_boolean(child, &g_values_bytes);
+ else if (strcasecmp("ValuesPercentage", child->key) == 0)
+ cf_util_get_boolean(child, &g_values_percent);
+ else
+ ERROR("%s: Invalid configuration option: \"%s\".", g_plugin_name,
+ child->key);
+ }
+
+ return (0);
+}
+
+static void submit_hp(const struct entry_info *info) {
+ value_list_t vl = VALUE_LIST_INIT;
+
+ vl.values = &(value_t) { .gauge = NAN };
+ vl.values_len = 1;
+
+ sstrncpy(vl.host, hostname_g, sizeof(vl.host));
+ sstrncpy(vl.plugin, g_plugin_name, sizeof(vl.plugin));
+ if (info->node) {
+ ssnprintf(vl.plugin_instance, sizeof(vl.plugin_instance), "%s-%zuKb",
+ info->node, info->page_size_kb);
+ } else {
+ ssnprintf(vl.plugin_instance, sizeof(vl.plugin_instance), "%zuKb",
+ info->page_size_kb);
+ }
+
+ /* ensure all metrics have the same timestamp */
+ vl.time = cdtime();
+
+ gauge_t free = info->free;
+ gauge_t used = (info->nr + info->surplus) - info->free;
+
+ if (g_values_pages) {
+ sstrncpy(vl.type, "vmpage_number", sizeof(vl.type));
+ plugin_dispatch_multivalue(&vl, /* store_percentage = */ 0, DS_TYPE_GAUGE,
+ "free", free, "used", used, NULL);
+ }
+ if (g_values_bytes) {
+ gauge_t page_size = (gauge_t)(1024 * info->page_size_kb);
+ sstrncpy(vl.type, "memory", sizeof(vl.type));
+ plugin_dispatch_multivalue(&vl, /* store_percentage = */ 0, DS_TYPE_GAUGE,
+ "free", free * page_size, "used",
+ used * page_size, NULL);
+ }
+ if (g_values_percent) {
+ sstrncpy(vl.type, "percent", sizeof(vl.type));
+ plugin_dispatch_multivalue(&vl, /* store_percentage = */ 1, DS_TYPE_GAUGE,
+ "free", free, "used", used, NULL);
+ }
+}
+
+static int read_hugepage_entry(const char *path, const char *entry,
+ void *e_info) {
+ char path2[PATH_MAX];
+ struct entry_info *info = e_info;
+ double value;
+
+ ssnprintf(path2, sizeof(path2), "%s/%s", path, entry);
+
+ FILE *fh = fopen(path2, "rt");
+ if (fh == NULL) {
+ ERROR("%s: cannot open %s", g_plugin_name, path2);
+ return -1;
+ }
+
+ if (fscanf(fh, "%lf", &value) != 1) {
+ ERROR("%s: cannot parse file %s", g_plugin_name, path2);
+ fclose(fh);
+ return -1;
+ }
+ fclose(fh);
+
+ if (strcmp(entry, "nr_hugepages") == 0) {
+ info->nr = value;
+ info->flags |= HP_HAVE_NR;
+ } else if (strcmp(entry, "surplus_hugepages") == 0) {
+ info->surplus = value;
+ info->flags |= HP_HAVE_SURPLUS;
+ } else if (strcmp(entry, "free_hugepages") == 0) {
+ info->free = value;
+ info->flags |= HP_HAVE_FREE;
+ }
+
+ if (info->flags != HP_HAVE_ALL) {
+ return 0;
+ }
+
+ submit_hp(info);
+
+ /* Reset flags so subsequent calls don't submit again. */
+ info->flags = 0;
+ return 0;
+}
+
+static int read_syshugepages(const char *path, const char *node) {
+ static const char hugepages_dir[] = "hugepages-";
+ DIR *dir;
+ struct dirent *result;
+ char path2[PATH_MAX];
+
+ dir = opendir(path);
+ if (dir == NULL) {
+ ERROR("%s: cannot open directory %s", g_plugin_name, path);
+ return -1;
+ }
+
+ /* read "hugepages-XXXXXkB" entries */
+ while ((result = readdir(dir)) != NULL) {
+ if (strncmp(result->d_name, hugepages_dir, sizeof(hugepages_dir) - 1)) {
+ /* not node dir */
+ errno = 0;
+ continue;
+ }
+
+ long page_size = strtol(result->d_name + strlen(hugepages_dir),
+ /* endptr = */ NULL, /* base = */ 10);
+ if (errno != 0) {
+ char errbuf[1024];
+ ERROR("%s: failed to determine page size from directory name \"%s\": %s",
+ g_plugin_name, result->d_name,
+ sstrerror(errno, errbuf, sizeof(errbuf)));
+ continue;
+ }
+
+ /* /sys/devices/system/node/node?/hugepages/ */
+ ssnprintf(path2, sizeof(path2), "%s/%s", path, result->d_name);
+
+ walk_directory(path2, read_hugepage_entry,
+ &(struct entry_info){
+ .d_name = result->d_name,
+ .node = node,
+ .page_size_kb = (size_t)page_size,
+ },
+ /* hidden = */ 0);
+ errno = 0;
+ }
+
+ /* Check if NULL return from readdir() was an error */
+ if (errno != 0) {
+ ERROR("%s: readdir failed", g_plugin_name);
+ closedir(dir);
+ return -1;
+ }
+
+ closedir(dir);
+ return 0;
+}
+
+static int read_nodes(void) {
+ static const char sys_node[] = "/sys/devices/system/node";
+ static const char node_string[] = "node";
+ static const char sys_node_hugepages[] =
+ "/sys/devices/system/node/%s/hugepages";
+ DIR *dir;
+ struct dirent *result;
+ char path[PATH_MAX];
+
+ dir = opendir(sys_node);
+ if (dir == NULL) {
+ ERROR("%s: cannot open directory %s", g_plugin_name, sys_node);
+ return -1;
+ }
+
+ while ((result = readdir(dir)) != NULL) {
+ if (strncmp(result->d_name, node_string, sizeof(node_string) - 1)) {
+ /* not node dir */
+ errno = 0;
+ continue;
+ }
+
+ ssnprintf(path, sizeof(path), sys_node_hugepages, result->d_name);
+ read_syshugepages(path, result->d_name);
+ errno = 0;
+ }
+
+ /* Check if NULL return from readdir() was an error */
+ if (errno != 0) {
+ ERROR("%s: readdir failed", g_plugin_name);
+ closedir(dir);
+ return -1;
+ }
+
+ closedir(dir);
+ return 0;
+}
+
+static int huge_read(void) {
+ static const char sys_mm_hugepages[] = "/sys/kernel/mm/hugepages";
+
+ if (g_flag_rpt_mm) {
+ if (read_syshugepages(sys_mm_hugepages, "mm") != 0) {
+ return -1;
+ }
+ }
+ if (g_flag_rpt_numa) {
+ if (read_nodes() != 0) {
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
+void module_register(void) {
+ plugin_register_complex_config(g_plugin_name, hp_config);
+ plugin_register_read(g_plugin_name, huge_read);
+}
**/
#include "collectd.h"
+
#include "common.h"
#include "plugin.h"
-#include "configfile.h"
#include "utils_ignorelist.h"
#if HAVE_SYS_TYPES_H
{
"Interface",
"IgnoreSelected",
- NULL
+ "ReportInactive",
};
-static int config_keys_num = 2;
+static int config_keys_num = STATIC_ARRAY_SIZE (config_keys);
static ignorelist_t *ignorelist = NULL;
+static _Bool report_inactive = 1;
+
#ifdef HAVE_LIBKSTAT
#define MAX_NUMIF 256
extern kstat_ctl_t *kc;
invert = 0;
ignorelist_set_invert (ignorelist, invert);
}
+ else if (strcasecmp (key, "ReportInactive") == 0)
+ report_inactive = IS_TRUE (value);
else if (strcasecmp (key, "UniqueName") == 0)
{
#ifdef HAVE_LIBKSTAT
derive_t rx,
derive_t tx)
{
- value_t values[2];
value_list_t vl = VALUE_LIST_INIT;
+ value_t values[] = {
+ { .derive = rx },
+ { .derive = tx },
+ };
if (ignorelist_match (ignorelist, dev) != 0)
return;
- values[0].derive = rx;
- values[1].derive = tx;
-
vl.values = values;
- vl.values_len = 2;
+ vl.values_len = STATIC_ARRAY_SIZE (values);
sstrncpy (vl.host, hostname_g, sizeof (vl.host));
sstrncpy (vl.plugin, "interface", sizeof (vl.plugin));
sstrncpy (vl.plugin_instance, dev, sizeof (vl.plugin_instance));
{
#if HAVE_GETIFADDRS
struct ifaddrs *if_list;
- struct ifaddrs *if_ptr;
/* Darwin/Mac OS X and possible other *BSDs */
#if HAVE_STRUCT_IF_DATA
if (getifaddrs (&if_list) != 0)
return (-1);
- for (if_ptr = if_list; if_ptr != NULL; if_ptr = if_ptr->ifa_next)
+ for (struct ifaddrs *if_ptr = if_list; if_ptr != NULL; if_ptr = if_ptr->ifa_next)
{
if (if_ptr->ifa_addr != NULL && if_ptr->ifa_addr->sa_family == AF_LINK) {
if_data = (struct IFA_DATA *) if_ptr->ifa_data;
+ if (!report_inactive && if_data->IFA_RX_PACKT == 0 && if_data->IFA_TX_PACKT == 0)
+ continue;
+
if_submit (if_ptr->ifa_name, "if_octets",
if_data->IFA_RX_BYTES,
if_data->IFA_TX_BYTES);
if (numfields < 11)
continue;
- incoming = atoll (fields[0]);
- outgoing = atoll (fields[8]);
- if_submit (device, "if_octets", incoming, outgoing);
-
incoming = atoll (fields[1]);
outgoing = atoll (fields[9]);
+ if (!report_inactive && incoming == 0 && outgoing == 0)
+ continue;
+
if_submit (device, "if_packets", incoming, outgoing);
+ incoming = atoll (fields[0]);
+ outgoing = atoll (fields[8]);
+ if_submit (device, "if_octets", incoming, outgoing);
+
incoming = atoll (fields[2]);
outgoing = atoll (fields[10]);
if_submit (device, "if_errors", incoming, outgoing);
/* #endif KERNEL_LINUX */
#elif HAVE_LIBKSTAT
- int i;
derive_t rx;
derive_t tx;
char iname[DATA_MAX_NAME_LEN];
if (kc == NULL)
return (-1);
- for (i = 0; i < numif; i++)
+ for (int i = 0; i < numif; i++)
{
if (kstat_read (kc, ksp[i], NULL) == -1)
continue;
sstrncpy(iname, ksp[i]->ks_name, sizeof(iname));
/* try to get 64bit counters */
- rx = get_kstat_value (ksp[i], "rbytes64");
- tx = get_kstat_value (ksp[i], "obytes64");
+ rx = get_kstat_value (ksp[i], "ipackets64");
+ tx = get_kstat_value (ksp[i], "opackets64");
/* or fallback to 32bit */
if (rx == -1LL)
- rx = get_kstat_value (ksp[i], "rbytes");
+ rx = get_kstat_value (ksp[i], "ipackets");
if (tx == -1LL)
- tx = get_kstat_value (ksp[i], "obytes");
+ tx = get_kstat_value (ksp[i], "opackets");
+ if (!report_inactive && rx == 0 && tx == 0)
+ continue;
if ((rx != -1LL) || (tx != -1LL))
- if_submit (iname, "if_octets", rx, tx);
+ if_submit (iname, "if_packets", rx, tx);
/* try to get 64bit counters */
- rx = get_kstat_value (ksp[i], "ipackets64");
- tx = get_kstat_value (ksp[i], "opackets64");
+ rx = get_kstat_value (ksp[i], "rbytes64");
+ tx = get_kstat_value (ksp[i], "obytes64");
/* or fallback to 32bit */
if (rx == -1LL)
- rx = get_kstat_value (ksp[i], "ipackets");
+ rx = get_kstat_value (ksp[i], "rbytes");
if (tx == -1LL)
- tx = get_kstat_value (ksp[i], "opackets");
+ tx = get_kstat_value (ksp[i], "obytes");
if ((rx != -1LL) || (tx != -1LL))
- if_submit (iname, "if_packets", rx, tx);
+ if_submit (iname, "if_octets", rx, tx);
/* no 64bit error counters yet */
rx = get_kstat_value (ksp[i], "ierrors");
#elif defined(HAVE_LIBSTATGRAB)
sg_network_io_stats *ios;
- int i, num;
+ int num;
ios = sg_get_network_io_stats (&num);
- for (i = 0; i < num; i++)
+ for (int i = 0; i < num; i++) {
+ if (!report_inactive && ios[i].rx == 0 && ios[i].tx == 0)
+ continue;
if_submit (ios[i].interface_name, "if_octets", ios[i].rx, ios[i].tx);
+ }
/* #endif HAVE_LIBSTATGRAB */
#elif defined(HAVE_PERFSTAT)
perfstat_id_t id;
- int i, ifs;
+ int ifs;
if ((nif = perfstat_netinterface(NULL, NULL, sizeof(perfstat_netinterface_t), 0)) < 0)
{
return (-1);
}
- for (i = 0; i < ifs; i++)
+ for (int i = 0; i < ifs; i++)
{
+ if (!report_inactive && ifstat[i].ipackets == 0 && ifstat[i].opackets == 0)
+ continue;
+
if_submit (ifstat[i].name, "if_octets", ifstat[i].ibytes, ifstat[i].obytes);
if_submit (ifstat[i].name, "if_packets", ifstat[i].ipackets ,ifstat[i].opackets);
if_submit (ifstat[i].name, "if_errors", ifstat[i].ierrors, ifstat[i].oerrors );
#endif
plugin_register_read ("interface", interface_read);
} /* void module_register */
+
*/
#include "collectd.h"
+
#include "common.h"
#include "plugin.h"
-#include "configfile.h"
#if KERNEL_LINUX
/* _GNU_SOURCE is needed for struct shm_info.used_ids on musl libc */
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, "ipc", sizeof (vl.plugin));
ipcinfo_sem_t *ipcinfo_sem;
unsigned short sem_nsems=0;
unsigned short sems=0;
- int i,n;
+ int n;
ipcinfo_sem = (ipcinfo_sem_t *)ipc_get_info(0,
GET_IPCINFO_SEM_ALL, IPCINFO_SEM_VERSION, sizeof(ipcinfo_sem_t), &n);
if (ipcinfo_sem == NULL)
return -1;
- for (i=0; i<n; i++) {
+ for (int i=0; i<n; i++) {
sem_nsems += ipcinfo_sem[i].sem_nsems;
sems++;
}
ipcinfo_shm_t *pshm;
unsigned int shm_segments=0;
size64_t shm_bytes=0;
- int i,n;
+ int n;
ipcinfo_shm = (ipcinfo_shm_t *)ipc_get_info(0,
GET_IPCINFO_SHM_ALL, IPCINFO_SHM_VERSION, sizeof(ipcinfo_shm_t), &n);
if (ipcinfo_shm == NULL)
return -1;
- for (i=0, pshm=ipcinfo_shm; i<n; i++, pshm++) {
+ for (int i=0, pshm=ipcinfo_shm; i<n; i++, pshm++) {
shm_segments++;
shm_bytes += pshm->shm_segsz;
}
uint32_t msg_used_space=0;
uint32_t msg_alloc_queues=0;
msgqnum32_t msg_qnum=0;
- int i,n;
+ int n;
ipcinfo_msg = (ipcinfo_msg_t *)ipc_get_info(0,
GET_IPCINFO_MSG_ALL, IPCINFO_MSG_VERSION, sizeof(ipcinfo_msg_t), &n);
if (ipcinfo_msg == NULL)
return -1;
- for (i=0; i<n; i++) {
+ for (int i=0; i<n; i++) {
msg_alloc_queues++;
msg_used_space += ipcinfo_msg[i].msg_cbytes;
msg_qnum += ipcinfo_msg[i].msg_qnum;
**/
#include "collectd.h"
+
#include "common.h"
#include "plugin.h"
#include "utils_ignorelist.h"
*/
static void c_ipmi_error (const char *func, int status)
{
- char errbuf[4096];
-
- memset (errbuf, 0, sizeof (errbuf));
+ char errbuf[4096] = { 0 };
if (IPMI_IS_OS_ERR (status))
{
ipmi_states_t __attribute__((unused)) *states,
void *user_data)
{
- value_t values[1];
value_list_t vl = VALUE_LIST_INIT;
c_ipmi_sensor_list_t *list_item = (c_ipmi_sensor_list_t *)user_data;
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));
c_ipmi_sensor_list_t *list_item;
c_ipmi_sensor_list_t *list_prev;
- char buffer[DATA_MAX_NAME_LEN];
+ char buffer[DATA_MAX_NAME_LEN] = { 0 };
const char *entity_id_string;
char sensor_name[DATA_MAX_NAME_LEN];
char *sensor_name_ptr;
sensor_id = ipmi_sensor_convert_to_id (sensor);
- memset (buffer, 0, sizeof (buffer));
ipmi_sensor_get_name (sensor, buffer, sizeof (buffer));
buffer[sizeof (buffer) - 1] = 0;
static int sensor_list_read_all (void)
{
- c_ipmi_sensor_list_t *list_item;
-
pthread_mutex_lock (&sensor_list_lock);
- for (list_item = sensor_list;
+ for (c_ipmi_sensor_list_t *list_item = sensor_list;
list_item != NULL;
list_item = list_item->next)
{
static int thread_init (os_handler_t **ret_os_handler)
{
os_handler_t *os_handler;
- ipmi_open_option_t open_option[1];
ipmi_con_t *smi_connection = NULL;
ipmi_domain_id_t domain_id;
int status;
return (-1);
}
- memset (open_option, 0, sizeof (open_option));
- open_option[0].option = IPMI_OPEN_OPTION_ALL;
- open_option[0].ival = 1;
+ ipmi_open_option_t open_option[1] = {
+ [0] = {
+ .option = IPMI_OPEN_OPTION_ALL,
+ { .ival = 1 }
+ }
+ };
status = ipmi_open_domain ("mydomain", &smi_connection, /* num_con = */ 1,
domain_connection_change_handler, /* user data = */ NULL,
**/
#include "collectd.h"
+
#include "common.h"
#include "plugin.h"
-#include "configfile.h"
#include <libiptc/libiptc.h>
#include <libiptc/libip6tc.h>
+#ifdef HAVE_SYS_CAPABILITY_H
+# include <sys/capability.h>
+#endif
+
/*
* iptc_handle_t was available before libiptc was officially available as a
* shared library. Note, that when the shared lib was introduced, the API and
else
return (1);
- ip_chain_t temp, *final, **list;
+ ip_chain_t temp = { 0 };
+ ip_chain_t *final, **list;
char *table;
int table_len;
char *chain;
char *fields[4];
int fields_num;
- memset (&temp, 0, sizeof (temp));
-
value_copy = strdup (value);
if (value_copy == NULL)
{
int rule_num)
{
int status;
- value_t values[1];
value_list_t vl = VALUE_LIST_INIT;
/* Select the rules to collect */
return (0);
}
- vl.values = values;
- vl.values_len = 1;
sstrncpy (vl.host, hostname_g, sizeof (vl.host));
sstrncpy (vl.plugin, "ip6tables", sizeof (vl.plugin));
}
sstrncpy (vl.type, "ipt_bytes", sizeof (vl.type));
- values[0].derive = (derive_t) entry->counters.bcnt;
+ vl.values = &(value_t) { .derive = (derive_t) entry->counters.bcnt };
+ vl.values_len = 1;
plugin_dispatch_values (&vl);
sstrncpy (vl.type, "ipt_packets", sizeof (vl.type));
- values[0].derive = (derive_t) entry->counters.pcnt;
+ vl.values = &(value_t) { .derive = (derive_t) entry->counters.pcnt };
plugin_dispatch_values (&vl);
return (0);
-} /* int submit_match */
-
+} /* int submit6_match */
/* This needs to return `int' for IPT_MATCH_ITERATE to work. */
static int submit_match (const struct ipt_entry_match *match,
int rule_num)
{
int status;
- value_t values[1];
value_list_t vl = VALUE_LIST_INIT;
/* Select the rules to collect */
return (0);
}
- vl.values = values;
- vl.values_len = 1;
sstrncpy (vl.host, hostname_g, sizeof (vl.host));
sstrncpy (vl.plugin, "iptables", sizeof (vl.plugin));
}
sstrncpy (vl.type, "ipt_bytes", sizeof (vl.type));
- values[0].derive = (derive_t) entry->counters.bcnt;
+ vl.values = &(value_t) { .derive = (derive_t) entry->counters.bcnt };
+ vl.values_len = 1;
plugin_dispatch_values (&vl);
sstrncpy (vl.type, "ipt_packets", sizeof (vl.type));
- values[0].derive = (derive_t) entry->counters.pcnt;
+ vl.values = &(value_t) { .derive = (derive_t) entry->counters.pcnt };
plugin_dispatch_values (&vl);
return (0);
static int iptables_read (void)
{
- int i;
int num_failures = 0;
ip_chain_t *chain;
/* Init the iptc handle structure and query the correct table */
- for (i = 0; i < chain_num; i++)
+ for (int i = 0; i < chain_num; i++)
{
chain = chain_list[i];
static int iptables_shutdown (void)
{
- int i;
-
- for (i = 0; i < chain_num; i++)
+ for (int i = 0; i < chain_num; i++)
{
if ((chain_list[i] != NULL) && (chain_list[i]->rule_type == RTYPE_COMMENT))
sfree (chain_list[i]->rule.comment);
return (0);
} /* int iptables_shutdown */
+static int iptables_init (void)
+{
+#if defined(HAVE_SYS_CAPABILITY_H) && defined(CAP_NET_ADMIN)
+ if (check_capability (CAP_NET_ADMIN) != 0)
+ {
+ if (getuid () == 0)
+ WARNING ("iptables plugin: Running collectd as root, but the "
+ "CAP_NET_ADMIN capability is missing. The plugin's read "
+ "function will probably fail. Is your init system dropping "
+ "capabilities?");
+ else
+ WARNING ("iptables plugin: collectd doesn't have the CAP_NET_ADMIN "
+ "capability. If you don't want to run collectd as root, try "
+ "running \"setcap cap_net_admin=ep\" on the collectd binary.");
+ }
+#endif
+ return (0);
+} /* int iptables_init */
+
void module_register (void)
{
plugin_register_config ("iptables", iptables_config,
config_keys, config_keys_num);
+ plugin_register_init ("iptables", iptables_init);
plugin_register_read ("iptables", iptables_read);
plugin_register_shutdown ("iptables", iptables_shutdown);
} /* void module_register */
*/
#include "collectd.h"
+
#include "plugin.h"
#include "common.h"
static void cipvs_submit_connections (const char *pi, const char *ti,
derive_t value)
{
- value_t values[1];
value_list_t vl = VALUE_LIST_INIT;
- values[0].derive = value;
-
- vl.values = values;
+ vl.values = &(value_t) { .derive = value };
vl.values_len = 1;
sstrncpy (vl.host, hostname_g, sizeof (vl.host));
static void cipvs_submit_if (const char *pi, const char *t, const char *ti,
derive_t rx, derive_t tx)
{
- value_t values[2];
+ value_t values[] = {
+ { .derive = rx },
+ { .derive = tx },
+ };
value_list_t vl = VALUE_LIST_INIT;
- values[0].derive = rx;
- values[1].derive = tx;
-
vl.values = values;
- vl.values_len = 2;
+ vl.values_len = STATIC_ARRAY_SIZE (values);
sstrncpy (vl.host, hostname_g, sizeof (vl.host));
sstrncpy (vl.plugin, "ipvs", sizeof (vl.plugin));
char pi[DATA_MAX_NAME_LEN];
- size_t i;
-
if (0 != get_pi (se, pi, sizeof (pi)))
{
free (dests);
cipvs_submit_if (pi, "if_packets", NULL, stats.inpkts, stats.outpkts);
cipvs_submit_if (pi, "if_octets", NULL, stats.inbytes, stats.outbytes);
- for (i = 0; i < dests->num_dests; ++i)
+ for (size_t i = 0; i < dests->num_dests; ++i)
cipvs_submit_dest (pi, &dests->entrytable[i]);
free (dests);
static int cipvs_read (void)
{
struct ip_vs_get_services *services = NULL;
- size_t i;
if (sockfd < 0)
return (-1);
if (NULL == (services = ipvs_get_services ()))
return -1;
- for (i = 0; i < services->num_services; ++i)
+ for (size_t i = 0; i < services->num_services; ++i)
cipvs_submit_service (&services->entrytable[i]);
free (services);
**/
#include "collectd.h"
+
#include "common.h"
#include "plugin.h"
-#include "configfile.h"
#include "utils_ignorelist.h"
#if !KERNEL_LINUX
static void irq_submit (const char *irq_name, derive_t value)
{
- value_t values[1];
value_list_t vl = VALUE_LIST_INIT;
if (ignorelist_match (ignorelist, irq_name) != 0)
return;
- values[0].derive = value;
-
- vl.values = values;
+ vl.values = &(value_t) { .derive = value };
vl.values_len = 1;
sstrncpy (vl.host, hostname_g, sizeof (vl.host));
sstrncpy (vl.plugin, "irq", sizeof (vl.plugin));
**/
#include "collectd.h"
+
#include "plugin.h"
#include "common.h"
#include "filter_chain.h"
jmethodID m_addchild;
jobject o_key;
jobject o_ocitem;
- int i;
c_ocitem = (*jvm_env)->FindClass (jvm_env, "org/collectd/api/OConfigItem");
if (c_ocitem == NULL)
(*jvm_env)->DeleteLocalRef (jvm_env, o_key);
/* Call OConfigItem.addValue for each value */
- for (i = 0; i < ci->values_num; i++) /* {{{ */
+ for (int i = 0; i < ci->values_num; i++) /* {{{ */
{
jobject o_value;
} /* }}} for (i = 0; i < ci->values_num; i++) */
/* Call OConfigItem.addChild for each child */
- for (i = 0; i < ci->children_num; i++) /* {{{ */
+ for (int i = 0; i < ci->children_num; i++) /* {{{ */
{
jobject o_child;
jmethodID m_add;
jobject o_type;
jobject o_dataset;
- size_t i;
/* Look up the org/collectd/api/DataSet class */
c_dataset = (*jvm_env)->FindClass (jvm_env, "org/collectd/api/DataSet");
/* Decrease reference counter on the java.lang.String object. */
(*jvm_env)->DeleteLocalRef (jvm_env, o_type);
- for (i = 0; i < ds->ds_num; i++)
+ for (size_t i = 0; i < ds->ds_num; i++)
{
jobject o_datasource;
jmethodID m_valuelist_constructor;
jobject o_valuelist;
int status;
- size_t i;
/* First, create a new ValueList instance..
* Look up the class.. */
return (NULL);
}
- for (i = 0; i < vl->values_len; i++)
+ for (size_t i = 0; i < vl->values_len; i++)
{
status = ctoj_value_list_add_value (jvm_env, vl->values[i], ds->ds[i].type,
c_valuelist, o_valuelist);
value_t *values;
int values_num;
- int i;
values_num = ds->ds_num;
BAIL_OUT (-1);
}
- for (i = 0; i < values_num; i++)
+ for (int i = 0; i < values_num; i++)
{
jobject o_number;
int status;
static jint JNICALL cjni_api_dispatch_notification (JNIEnv *jvm_env, /* {{{ */
jobject this, jobject o_notification)
{
- notification_t n;
+ notification_t n = { 0 };
int status;
- memset (&n, 0, sizeof (n));
- n.meta = NULL;
-
status = jtoc_notification (jvm_env, &n, o_notification);
if (status != 0)
{
static jint JNICALL cjni_api_register_read (JNIEnv *jvm_env, /* {{{ */
jobject this, jobject o_name, jobject o_read)
{
- user_data_t ud;
cjni_callback_info_t *cbi;
cbi = cjni_callback_info_create (jvm_env, o_name, o_read, CB_TYPE_READ);
DEBUG ("java plugin: Registering new read callback: %s", cbi->name);
- memset (&ud, 0, sizeof (ud));
- ud.data = (void *) cbi;
- ud.free_func = cjni_callback_info_destroy;
-
plugin_register_complex_read (/* group = */ NULL, cbi->name, cjni_read,
- /* interval = */ 0, &ud);
+ /* interval = */ 0, &(user_data_t) {
+ .data = cbi,
+ .free_func = cjni_callback_info_destroy,
+ });
(*jvm_env)->DeleteLocalRef (jvm_env, o_read);
static jint JNICALL cjni_api_register_write (JNIEnv *jvm_env, /* {{{ */
jobject this, jobject o_name, jobject o_write)
{
- user_data_t ud;
cjni_callback_info_t *cbi;
cbi = cjni_callback_info_create (jvm_env, o_name, o_write, CB_TYPE_WRITE);
DEBUG ("java plugin: Registering new write callback: %s", cbi->name);
- memset (&ud, 0, sizeof (ud));
- ud.data = (void *) cbi;
- ud.free_func = cjni_callback_info_destroy;
-
- plugin_register_write (cbi->name, cjni_write, &ud);
+ plugin_register_write (cbi->name, cjni_write, &(user_data_t) {
+ .data = cbi,
+ .free_func = cjni_callback_info_destroy,
+ });
(*jvm_env)->DeleteLocalRef (jvm_env, o_write);
static jint JNICALL cjni_api_register_flush (JNIEnv *jvm_env, /* {{{ */
jobject this, jobject o_name, jobject o_flush)
{
- user_data_t ud;
cjni_callback_info_t *cbi;
cbi = cjni_callback_info_create (jvm_env, o_name, o_flush, CB_TYPE_FLUSH);
DEBUG ("java plugin: Registering new flush callback: %s", cbi->name);
- memset (&ud, 0, sizeof (ud));
- ud.data = (void *) cbi;
- ud.free_func = cjni_callback_info_destroy;
-
- plugin_register_flush (cbi->name, cjni_flush, &ud);
+ plugin_register_flush (cbi->name, cjni_flush, &(user_data_t) {
+ .data = cbi,
+ .free_func = cjni_callback_info_destroy,
+ });
(*jvm_env)->DeleteLocalRef (jvm_env, o_flush);
static jint JNICALL cjni_api_register_log (JNIEnv *jvm_env, /* {{{ */
jobject this, jobject o_name, jobject o_log)
{
- user_data_t ud;
cjni_callback_info_t *cbi;
cbi = cjni_callback_info_create (jvm_env, o_name, o_log, CB_TYPE_LOG);
DEBUG ("java plugin: Registering new log callback: %s", cbi->name);
- memset (&ud, 0, sizeof (ud));
- ud.data = (void *) cbi;
- ud.free_func = cjni_callback_info_destroy;
-
- plugin_register_log (cbi->name, cjni_log, &ud);
+ plugin_register_log (cbi->name, cjni_log, &(user_data_t) {
+ .data = cbi,
+ .free_func = cjni_callback_info_destroy,
+ });
(*jvm_env)->DeleteLocalRef (jvm_env, o_log);
static jint JNICALL cjni_api_register_notification (JNIEnv *jvm_env, /* {{{ */
jobject this, jobject o_name, jobject o_notification)
{
- user_data_t ud;
cjni_callback_info_t *cbi;
cbi = cjni_callback_info_create (jvm_env, o_name, o_notification,
DEBUG ("java plugin: Registering new notification callback: %s", cbi->name);
- memset (&ud, 0, sizeof (ud));
- ud.data = (void *) cbi;
- ud.free_func = cjni_callback_info_destroy;
-
- plugin_register_notification (cbi->name, cjni_notification, &ud);
+ plugin_register_notification (cbi->name, cjni_notification, &(user_data_t) {
+ .data = cbi,
+ .free_func = cjni_callback_info_destroy,
+ });
(*jvm_env)->DeleteLocalRef (jvm_env, o_notification);
if (type == CB_TYPE_MATCH)
{
- match_proc_t m_proc;
+ match_proc_t m_proc = { 0 };
- memset (&m_proc, 0, sizeof (m_proc));
m_proc.create = cjni_match_target_create;
m_proc.destroy = cjni_match_target_destroy;
m_proc.match = (void *) cjni_match_target_invoke;
}
else if (type == CB_TYPE_TARGET)
{
- target_proc_t t_proc;
+ target_proc_t t_proc = { 0 };
- memset (&t_proc, 0, sizeof (t_proc));
t_proc.create = cjni_match_target_create;
t_proc.destroy = cjni_match_target_destroy;
t_proc.invoke = cjni_match_target_invoke;
static int cjni_create_jvm (void) /* {{{ */
{
JNIEnv *jvm_env;
- JavaVMInitArgs vm_args;
+ JavaVMInitArgs vm_args = { 0 };
JavaVMOption vm_options[jvm_argc];
int status;
- size_t i;
if (jvm != NULL)
return (0);
jvm_env = NULL;
- memset (&vm_args, 0, sizeof (vm_args));
vm_args.version = JNI_VERSION_1_2;
vm_args.options = vm_options;
vm_args.nOptions = (jint) jvm_argc;
- for (i = 0; i < jvm_argc; i++)
+ for (size_t i = 0; i < jvm_argc; i++)
{
DEBUG ("java plugin: cjni_create_jvm: jvm_argv[%zu] = %s",
i, jvm_argv[i]);
else
{
int status;
- JavaVMAttachArgs args;
+ JavaVMAttachArgs args = { 0 };
assert (cjni_env->jvm_env == NULL);
- memset (&args, 0, sizeof (args));
args.version = JNI_VERSION_1_2;
status = (*jvm)->AttachCurrentThread (jvm, (void *) &jvm_env, (void *) &args);
{ /* Replace all dots ('.') with slashes ('/'). Dots are usually used
thorough the Java community, but (Sun's) `FindClass' and friends need
slashes. */
- size_t i;
- for (i = 0; class->name[i] != 0; i++)
+ for (size_t i = 0; class->name[i] != 0; i++)
if (class->name[i] == '.')
class->name[i] = '/';
}
cjni_callback_info_t *cbi;
jobject o_ocitem;
const char *name;
- size_t i;
jclass class;
jmethodID method;
name = ci->values[0].value.string;
cbi = NULL;
- for (i = 0; i < java_callbacks_num; i++)
+ for (size_t i = 0; i < java_callbacks_num; i++)
{
if (java_callbacks[i].type != CB_TYPE_CONFIG)
continue;
int success;
int errors;
int status;
- int i;
success = 0;
errors = 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;
jobject o_ci;
jobject o_tmp;
int type;
- size_t i;
cbi_ret = NULL;
o_ci = NULL;
/* Lets see if we have a matching factory here.. */
cbi_factory = NULL;
- for (i = 0; i < java_callbacks_num; i++)
+ for (size_t i = 0; i < java_callbacks_num; i++)
{
if (java_callbacks[i].type != type)
continue;
* `value_list_t'. */
if (cbi->type == CB_TYPE_TARGET)
{
- value_list_t new_vl;
+ value_list_t new_vl = { 0 };
- memset (&new_vl, 0, sizeof (new_vl));
status = jtoc_value_list (jvm_env, &new_vl, o_vl);
if (status != 0)
{
static int cjni_init_plugins (JNIEnv *jvm_env) /* {{{ */
{
int status;
- size_t i;
- for (i = 0; i < java_callbacks_num; i++)
+ for (size_t i = 0; i < java_callbacks_num; i++)
{
if (java_callbacks[i].type != CB_TYPE_INIT)
continue;
static int cjni_shutdown_plugins (JNIEnv *jvm_env) /* {{{ */
{
int status;
- size_t i;
- for (i = 0; i < java_callbacks_num; i++)
+ for (size_t i = 0; i < java_callbacks_num; i++)
{
if (java_callbacks[i].type != CB_TYPE_SHUTDOWN)
continue;
static int cjni_shutdown (void) /* {{{ */
{
JNIEnv *jvm_env;
- JavaVMAttachArgs args;
+ JavaVMAttachArgs args = { 0 };
int status;
- size_t i;
if (jvm == NULL)
return (0);
jvm_env = NULL;
- memset (&args, 0, sizeof (args));
args.version = JNI_VERSION_1_2;
status = (*jvm)->AttachCurrentThread (jvm, (void *) &jvm_env, &args);
cjni_shutdown_plugins (jvm_env);
/* Release all the global references to callback functions */
- for (i = 0; i < java_callbacks_num; i++)
+ for (size_t i = 0; i < java_callbacks_num; i++)
{
if (java_callbacks[i].object != NULL)
{
sfree (java_callbacks);
/* Release all the global references to directly loaded classes. */
- for (i = 0; i < java_classes_list_len; i++)
+ for (size_t i = 0; i < java_classes_list_len; i++)
{
if (java_classes_list[i].object != NULL)
{
pthread_key_delete (jvm_env_key);
/* Free the JVM argument list */
- for (i = 0; i < jvm_argc; i++)
+ for (size_t i = 0; i < jvm_argc; i++)
sfree (jvm_argv[i]);
jvm_argc = 0;
sfree (jvm_argv);
#include <stdlib.h>
#include <stdio.h>
+#include <stdarg.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
(c)->errbuf[sizeof ((c)->errbuf) - 1] = 0; \
} while (0)
-#if COLLECT_DEBUG
-# define LCC_DEBUG(...) printf (__VA_ARGS__)
-#else
-# define LCC_DEBUG(...) /**/
-#endif
-
/*
* Types
*/
/*
* Private functions
*/
+__attribute__ ((format (printf, 1, 0)))
+static int lcc_tracef(char const *format, ...)
+{
+ va_list ap;
+ int status;
+
+ char const *trace = getenv (LCC_TRACE_ENV);
+ if (!trace || (strcmp ("", trace) == 0) || (strcmp ("0", trace) == 0))
+ return 0;
+
+ va_start (ap, format);
+ status = vprintf (format, ap);
+ va_end (ap);
+
+ return status;
+}
+
/* Even though Posix requires "strerror_r" to return an "int",
* some systems (e.g. the GNU libc) return a "char *" _and_
* ignore the second argument ... -tokkee */
static void lcc_response_free (lcc_response_t *res) /* {{{ */
{
- size_t i;
-
if (res == NULL)
return;
- for (i = 0; i < res->lines_num; i++)
+ for (size_t i = 0; i < res->lines_num; i++)
free (res->lines[i]);
free (res->lines);
res->lines = NULL;
{
int status;
- LCC_DEBUG ("send: --> %s\n", command);
+ lcc_tracef ("send: --> %s\n", command);
status = fprintf (c->fh, "%s\r\n", command);
if (status < 0)
static int lcc_receive (lcc_connection_t *c, /* {{{ */
lcc_response_t *ret_res)
{
- lcc_response_t res;
+ lcc_response_t res = { 0 };
char *ptr;
char buffer[4096];
size_t i;
- memset (&res, 0, sizeof (res));
-
/* Read the first line, containing the status and a message */
ptr = fgets (buffer, sizeof (buffer), c->fh);
if (ptr == NULL)
return (-1);
}
lcc_chomp (buffer);
- LCC_DEBUG ("receive: <-- %s\n", buffer);
+ lcc_tracef ("receive: <-- %s\n", buffer);
/* Convert the leading status to an integer and make `ptr' to point to the
* beginning of the message. */
break;
}
lcc_chomp (buffer);
- LCC_DEBUG ("receive: <-- %s\n", buffer);
+ lcc_tracef ("receive: <-- %s\n", buffer);
res.lines[i] = strdup (buffer);
if (res.lines[i] == NULL)
static int lcc_sendreceive (lcc_connection_t *c, /* {{{ */
const char *command, lcc_response_t *ret_res)
{
- lcc_response_t res;
+ lcc_response_t res = { 0 };
int status;
if (c->fh == NULL)
if (status != 0)
return (status);
- memset (&res, 0, sizeof (res));
status = lcc_receive (c, &res);
if (status == 0)
memcpy (ret_res, &res, sizeof (*ret_res));
static int lcc_open_unixsocket (lcc_connection_t *c, const char *path) /* {{{ */
{
- struct sockaddr_un sa;
+ struct sockaddr_un sa = { 0 };
int fd;
int status;
return (-1);
}
- memset (&sa, 0, sizeof (sa));
sa.sun_family = AF_UNIX;
strncpy (sa.sun_path, path, sizeof (sa.sun_path) - 1);
static int lcc_open_netsocket (lcc_connection_t *c, /* {{{ */
const char *addr_orig)
{
- struct addrinfo ai_hints;
struct addrinfo *ai_res;
- struct addrinfo *ai_ptr;
char addr_copy[NI_MAXHOST];
char *addr;
char *port;
addr_copy[sizeof(addr_copy) - 1] = '\0';
addr = addr_copy;
- memset (&ai_hints, 0, sizeof (ai_hints));
- ai_hints.ai_flags = 0;
-#ifdef AI_ADDRCONFIG
- ai_hints.ai_flags |= AI_ADDRCONFIG;
-#endif
- ai_hints.ai_family = AF_UNSPEC;
- ai_hints.ai_socktype = SOCK_STREAM;
-
port = NULL;
if (*addr == '[') /* IPv6+port format */
{
}
}
- ai_res = NULL;
+ struct addrinfo ai_hints = {
+ .ai_family = AF_UNSPEC,
+ .ai_flags = AI_ADDRCONFIG,
+ .ai_socktype = SOCK_STREAM
+ };
+
status = getaddrinfo (addr,
port == NULL ? LCC_DEFAULT_PORT : port,
&ai_hints, &ai_res);
return (-1);
}
- for (ai_ptr = ai_res; ai_ptr != NULL; ai_ptr = ai_ptr->ai_next)
+ for (struct addrinfo *ai_ptr = ai_res; ai_ptr != NULL; ai_ptr = ai_ptr->ai_next)
{
fd = socket (ai_ptr->ai_family, ai_ptr->ai_socktype, ai_ptr->ai_protocol);
if (fd < 0)
char command[1024] = "";
lcc_response_t res;
int status;
- size_t i;
if ((c == NULL) || (vl == NULL) || (vl->values_len < 1)
|| (vl->values == NULL) || (vl->values_types == NULL))
else
SSTRCAT (command, " N");
- for (i = 0; i < vl->values_len; i++)
+ for (size_t i = 0; i < vl->values_len; i++)
{
if (vl->values_types[i] == LCC_TYPE_COUNTER)
SSTRCATF (command, ":%"PRIu64, vl->values[i].counter);
lcc_identifier_t **ret_ident, size_t *ret_ident_num)
{
lcc_response_t res;
- size_t i;
int status;
lcc_identifier_t *ident;
return (-1);
}
- for (i = 0; i < res.lines_num; i++)
+ for (size_t i = 0; i < res.lines_num; i++)
{
char *time_str;
char *ident_str;
#include "lcc_features.h"
+/* COLLECTD_TRACE is the environment variable used to control trace output. When
+ * set to something non-zero, all lines sent to / received from the daemon are
+ * printed to STDOUT. */
+#ifndef LCC_TRACE_ENV
+# define LCC_TRACE_ENV "COLLECTD_TRACE"
+#endif
+
/*
* Includes (for data types)
*/
static int server_open_socket (lcc_server_t *srv) /* {{{ */
{
- struct addrinfo ai_hints = { 0 };
- struct addrinfo *ai_list = NULL;
- struct addrinfo *ai_ptr;
+ struct addrinfo *ai_list;
int status;
if (srv == NULL)
if (srv->fd >= 0)
server_close_socket (srv);
-#ifdef AI_ADDRCONFIG
- ai_hints.ai_flags |= AI_ADDRCONFIG;
-#endif
- ai_hints.ai_family = AF_UNSPEC;
- ai_hints.ai_socktype = SOCK_DGRAM;
+ struct addrinfo ai_hints = {
+ .ai_family = AF_UNSPEC,
+ .ai_flags = AI_ADDRCONFIG,
+ .ai_socktype = SOCK_DGRAM
+ };
status = getaddrinfo (srv->node, srv->service, &ai_hints, &ai_list);
if (status != 0)
return (status);
assert (ai_list != NULL);
- for (ai_ptr = ai_list; ai_ptr != NULL; ai_ptr = ai_ptr->ai_next)
+ for (struct addrinfo *ai_ptr = ai_list; ai_ptr != NULL; ai_ptr = ai_ptr->ai_next)
{
srv->fd = socket (ai_ptr->ai_family, ai_ptr->ai_socktype, ai_ptr->ai_protocol);
if (srv->fd < 0)
static int server_send_buffer (lcc_server_t *srv) /* {{{ */
{
- char buffer[LCC_NETWORK_BUFFER_SIZE_DEFAULT];
+ char buffer[LCC_NETWORK_BUFFER_SIZE_DEFAULT] = { 0 };
size_t buffer_size;
int status;
return (status);
}
- memset (buffer, 0, sizeof (buffer));
buffer_size = sizeof (buffer);
status = lcc_network_buffer_finalize (srv->buffer);
* index is preferred here, because of its similarity
* to the way IPv6 handles this. Unfortunately, it
* appears not to be portable. */
- struct ip_mreqn mreq;
-
- memset (&mreq, 0, sizeof (mreq));
- mreq.imr_multiaddr.s_addr = addr->sin_addr.s_addr;
- mreq.imr_address.s_addr = ntohl (INADDR_ANY);
- mreq.imr_ifindex = (int) if_index;
+ struct ip_mreqn mreq = {
+ .imr_multiaddr.s_addr = addr->sin_addr.s_addr,
+ .imr_address.s_addr = ntohl (INADDR_ANY),
+ .imr_ifindex = (int) if_index
+ };
#else
- struct ip_mreq mreq;
-
- memset (&mreq, 0, sizeof (mreq));
- mreq.imr_multiaddr.s_addr = addr->sin_addr.s_addr;
- mreq.imr_interface.s_addr = ntohl (INADDR_ANY);
+ struct ip_mreq mreq = {
+ .imr_multiaddr.s_addr = addr->sin_addr.s_addr,
+ .imr_interface.s_addr = ntohl (INADDR_ANY)
+ };
#endif
status = setsockopt (srv->fd, IPPROTO_IP, IP_MULTICAST_IF,
int lcc_network_values_send (lcc_network_t *net, /* {{{ */
const lcc_value_list_t *vl)
{
- lcc_server_t *srv;
-
if ((net == NULL) || (vl == NULL))
return (EINVAL);
- for (srv = net->servers; srv != NULL; srv = srv->next)
+ for (lcc_server_t *srv = net->servers; srv != NULL; srv = srv->next)
server_value_add (srv, vl);
return (0);
value_t pkg_values[vl->values_len];
size_t offset;
- size_t i;
packet_len = sizeof (pkg_type) + sizeof (pkg_length)
+ sizeof (pkg_num_values)
pkg_length = htons ((uint16_t) packet_len);
pkg_num_values = htons ((uint16_t) vl->values_len);
- for (i = 0; i < vl->values_len; i++)
+ for (size_t i = 0; i < vl->values_len; i++)
{
pkg_values_types[i] = (uint8_t) vl->values_types[i];
switch (vl->values_types[i])
uint16_t pkg_type = htons (TYPE_ENCR_AES256);
uint16_t pkg_length = 0; /* Filled in in finalize. */
uint16_t pkg_user_len = htons ((uint16_t) username_length);
- char hash[20];
+ /* Filled in in finalize. */
+ char hash[20] = { 0 };
nb->encr_header_len = username_length;
nb->encr_header_len += PART_ENCRYPTION_AES256_SIZE;
gcry_randomize ((void *) &nb->encr_iv, sizeof (nb->encr_iv),
GCRY_STRONG_RANDOM);
- /* Filled in in finalize. */
- memset (hash, 0, sizeof (hash));
-
ADD_STATIC (nb, pkg_type);
ADD_STATIC (nb, pkg_length);
ADD_STATIC (nb, pkg_user_len);
yyin = fd;
} /* void yyset_in */
-oconfig_item_t *oconfig_parse_fh (FILE *fh)
+static oconfig_item_t *oconfig_parse_fh (FILE *fh)
{
int status;
oconfig_item_t *ret;
if (ci_orig->values_num > 0) /* {{{ */
{
- int i;
-
ci_copy->values = (oconfig_value_t *) calloc ((size_t) ci_orig->values_num,
sizeof (*ci_copy->values));
if (ci_copy->values == NULL)
}
ci_copy->values_num = ci_orig->values_num;
- for (i = 0; i < ci_copy->values_num; i++)
+ for (int i = 0; i < ci_copy->values_num; i++)
{
ci_copy->values[i].type = ci_orig->values[i].type;
if (ci_copy->values[i].type == OCONFIG_TYPE_STRING)
if (ci_orig->children_num > 0) /* {{{ */
{
- int i;
-
ci_copy->children = (oconfig_item_t *) calloc ((size_t) ci_orig->children_num,
sizeof (*ci_copy->children));
if (ci_copy->children == NULL)
}
ci_copy->children_num = ci_orig->children_num;
- for (i = 0; i < ci_copy->children_num; i++)
+ for (int i = 0; i < ci_copy->children_num; i++)
{
oconfig_item_t *child;
static void oconfig_free_all (oconfig_item_t *ci)
{
- int i;
-
if (ci == NULL)
return;
if (ci->key != NULL)
free (ci->key);
- for (i = 0; i < ci->values_num; i++)
+ for (int i = 0; i < ci->values_num; i++)
if ((ci->values[i].type == OCONFIG_TYPE_STRING)
&& (NULL != ci->values[i].value.string))
free (ci->values[i].value.string);
if (ci->values != NULL)
free (ci->values);
- for (i = 0; i < ci->children_num; i++)
+ for (int i = 0; i < ci->children_num; i++)
oconfig_free_all (ci->children + i);
if (ci->children != NULL)
/*
* Functions
*/
-oconfig_item_t *oconfig_parse_fh (FILE *fh);
oconfig_item_t *oconfig_parse_file (const char *file);
oconfig_item_t *oconfig_clone (const oconfig_item_t *ci);
{
char *ret = strdup (orig);
int len;
- int i;
if (ret == NULL)
return (NULL);
memmove (ret, ret + 1, len);
ret[len] = '\0';
- for (i = 0; i < len; i++)
+ for (int i = 0; i < len; i++)
{
if (ret[i] == '\\')
{
#include "aux_types.h"
#include "parser.h"
+#ifdef __clang__
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wmissing-noreturn"
+#endif
+
+
/* multiline string buffer */
static char *ml_buffer = NULL;
static int ml_pos = 0;
return;
} /* ml_append */
+#ifdef __clang__
+#pragma clang diagnostic pop
+#endif
#define _BSD_SOURCE
#include "collectd.h"
+
#include "common.h"
#include "plugin.h"
}
static void load_submit (gauge_t snum, gauge_t mnum, gauge_t lnum)
{
- value_t values[3];
- value_list_t vl = VALUE_LIST_INIT;
int cores = 0;
char errbuf[1024];
lnum /= cores;
}
- values[0].gauge = snum;
- values[1].gauge = mnum;
- values[2].gauge = lnum;
+ value_list_t vl = VALUE_LIST_INIT;
+ value_t values[] = {
+ { .gauge = snum },
+ { .gauge = mnum },
+ { .gauge = lnum },
+ };
vl.values = values;
vl.values_len = STATIC_ARRAY_SIZE (values);
**/
#include "collectd.h"
+
#include "common.h"
#include "plugin.h"
**/
#include "collectd.h"
+
#include "common.h"
#include "plugin.h"
**/
#include "collectd.h"
+
#include "common.h"
#include "plugin.h"
static void lpar_submit (const char *type_instance, double value)
{
- value_t values[1];
value_list_t vl = VALUE_LIST_INIT;
- values[0].gauge = (gauge_t)value;
-
- vl.values = values;
+ vl.values = &(value_t) { .gauge = value };
vl.values_len = 1;
if (report_by_serial)
{
--- /dev/null
+/**
+ * collectd - src/lua.c
+ * Copyright (C) 2010 Julien Ammous
+ * Copyright (C) 2010 Florian Forster
+ * Copyright (C) 2016 Ruben Kerkhof
+ *
+ * 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:
+ * Julien Ammous
+ * Florian Forster <octo at collectd.org>
+ * Ruben Kerkhof <ruben at rubenkerkhof.com>
+ **/
+
+/* <lua5.1/luaconf.h> defines a macro using "sprintf". Although not used here,
+ * GCC will complain about the macro definition. */
+#define DONT_POISON_SPRINTF_YET
+
+#include "collectd.h"
+#include "common.h"
+#include "plugin.h"
+
+/* Include the Lua API header files. */
+#include "utils_lua.h"
+#include <lauxlib.h>
+#include <lua.h>
+#include <lualib.h>
+
+#include <pthread.h>
+
+#if COLLECT_DEBUG && __GNUC__
+#undef sprintf
+#pragma GCC poison sprintf
+#endif
+
+typedef struct lua_script_s {
+ char *script_path;
+ lua_State *lua_state;
+ struct lua_script_s *next;
+} lua_script_t;
+
+typedef struct {
+ lua_State *lua_state;
+ const char *lua_function_name;
+ pthread_mutex_t lock;
+ int callback_id;
+} clua_callback_data_t;
+
+static char base_path[PATH_MAX];
+static lua_script_t *scripts;
+
+static int clua_store_callback(lua_State *L, int idx) /* {{{ */
+{
+ /* Copy the function pointer */
+ lua_pushvalue(L, idx);
+
+ return luaL_ref(L, LUA_REGISTRYINDEX);
+} /* }}} int clua_store_callback */
+
+static int clua_load_callback(lua_State *L, int callback_ref) /* {{{ */
+{
+ lua_rawgeti(L, LUA_REGISTRYINDEX, callback_ref);
+
+ if (!lua_isfunction(L, -1)) {
+ lua_pop(L, 1);
+ return (-1);
+ }
+
+ return (0);
+} /* }}} int clua_load_callback */
+
+/* Store the threads in a global variable so they are not cleaned up by the
+ * garbage collector. */
+static int clua_store_thread(lua_State *L, int idx) /* {{{ */
+{
+ if (idx < 0)
+ idx += lua_gettop(L) + 1;
+
+ /* Copy the thread pointer */
+ lua_pushvalue(L, idx); /* +1 = 3 */
+ if (!lua_isthread(L, -1)) {
+ lua_pop(L, 3); /* -3 = 0 */
+ return (-1);
+ }
+
+ luaL_ref(L, LUA_REGISTRYINDEX);
+ lua_pop(L, 1); /* -1 = 0 */
+ return (0);
+} /* }}} int clua_store_thread */
+
+static int clua_read(user_data_t *ud) /* {{{ */
+{
+ clua_callback_data_t *cb = ud->data;
+
+ pthread_mutex_lock(&cb->lock);
+
+ lua_State *L = cb->lua_state;
+
+ int status = clua_load_callback(L, cb->callback_id);
+ if (status != 0) {
+ ERROR("Lua plugin: Unable to load callback \"%s\" (id %i).",
+ cb->lua_function_name, cb->callback_id);
+ pthread_mutex_unlock(&cb->lock);
+ return (-1);
+ }
+ /* +1 = 1 */
+
+ status = lua_pcall(L, 0, 1, 0);
+ if (status != 0) {
+ const char *errmsg = lua_tostring(L, -1);
+ if (errmsg == NULL)
+ ERROR("Lua plugin: Calling a read callback failed. "
+ "In addition, retrieving the error message failed.");
+ else
+ ERROR("Lua plugin: Calling a read callback failed: %s", errmsg);
+ lua_pop(L, 1);
+ pthread_mutex_unlock(&cb->lock);
+ return (-1);
+ }
+
+ if (!lua_isnumber(L, -1)) {
+ ERROR("Lua plugin: Read function \"%s\" (id %i) did not return a numeric "
+ "status.",
+ cb->lua_function_name, cb->callback_id);
+ status = -1;
+ } else {
+ status = (int)lua_tointeger(L, -1);
+ }
+
+ /* pop return value and function */
+ lua_pop(L, 1); /* -1 = 0 */
+
+ pthread_mutex_unlock(&cb->lock);
+ return (status);
+} /* }}} int clua_read */
+
+static int clua_write(const data_set_t *ds, const value_list_t *vl, /* {{{ */
+ user_data_t *ud) {
+ clua_callback_data_t *cb = ud->data;
+
+ pthread_mutex_lock(&cb->lock);
+
+ lua_State *L = cb->lua_state;
+
+ int status = clua_load_callback(L, cb->callback_id);
+ if (status != 0) {
+ ERROR("Lua plugin: Unable to load callback \"%s\" (id %i).",
+ cb->lua_function_name, cb->callback_id);
+ pthread_mutex_unlock(&cb->lock);
+ return (-1);
+ }
+ /* +1 = 1 */
+
+ status = luaC_pushvaluelist(L, ds, vl);
+ if (status != 0) {
+ lua_pop(L, 1); /* -1 = 0 */
+ pthread_mutex_unlock(&cb->lock);
+ ERROR("Lua plugin: luaC_pushvaluelist failed.");
+ return (-1);
+ }
+ /* +1 = 2 */
+
+ status = lua_pcall(L, 1, 1, 0); /* -2+1 = 1 */
+ if (status != 0) {
+ const char *errmsg = lua_tostring(L, -1);
+ if (errmsg == NULL)
+ ERROR("Lua plugin: Calling the write callback failed. "
+ "In addition, retrieving the error message failed.");
+ else
+ ERROR("Lua plugin: Calling the write callback failed:\n%s", errmsg);
+ lua_pop(L, 1); /* -1 = 0 */
+ pthread_mutex_unlock(&cb->lock);
+ return (-1);
+ }
+
+ if (!lua_isnumber(L, -1)) {
+ ERROR("Lua plugin: Write function \"%s\" (id %i) did not return a numeric "
+ "value.",
+ cb->lua_function_name, cb->callback_id);
+ status = -1;
+ } else {
+ status = (int)lua_tointeger(L, -1);
+ }
+
+ lua_pop(L, 1); /* -1 = 0 */
+ pthread_mutex_unlock(&cb->lock);
+ return (status);
+} /* }}} int clua_write */
+
+/*
+ * Exported functions
+ */
+
+static int lua_cb_log_debug(lua_State *L) /* {{{ */
+{
+ const char *msg = luaL_checkstring(L, 1);
+ plugin_log(LOG_DEBUG, "%s", msg);
+ return 0;
+} /* }}} int lua_cb_log_debug */
+
+static int lua_cb_log_error(lua_State *L) /* {{{ */
+{
+ const char *msg = luaL_checkstring(L, 1);
+ plugin_log(LOG_ERR, "%s", msg);
+ return 0;
+} /* }}} int lua_cb_log_error */
+
+static int lua_cb_log_info(lua_State *L) /* {{{ */
+{
+ const char *msg = luaL_checkstring(L, 1);
+ plugin_log(LOG_INFO, "%s", msg);
+ return 0;
+} /* }}} int lua_cb_log_info */
+
+static int lua_cb_log_notice(lua_State *L) /* {{{ */
+{
+ const char *msg = luaL_checkstring(L, 1);
+ plugin_log(LOG_NOTICE, "%s", msg);
+ return 0;
+} /* }}} int lua_cb_log_notice */
+
+static int lua_cb_log_warning(lua_State *L) /* {{{ */
+{
+ const char *msg = luaL_checkstring(L, 1);
+ plugin_log(LOG_WARNING, "%s", msg);
+ return 0;
+} /* }}} int lua_cb_log_warning */
+
+static int lua_cb_dispatch_values(lua_State *L) /* {{{ */
+{
+ int nargs = lua_gettop(L);
+
+ if (nargs != 1)
+ return luaL_error(L, "Invalid number of arguments (%d != 1)", nargs);
+
+ luaL_checktype(L, 1, LUA_TTABLE);
+
+ value_list_t *vl = luaC_tovaluelist(L, -1);
+ if (vl == NULL)
+ return luaL_error(L, "%s", "luaC_tovaluelist failed");
+
+#if COLLECT_DEBUG
+ char identifier[6 * DATA_MAX_NAME_LEN];
+ FORMAT_VL(identifier, sizeof(identifier), vl);
+
+ DEBUG("Lua plugin: collectd.dispatch_values(): Received value list \"%s\", "
+ "time %.3f, interval %.3f.",
+ identifier, CDTIME_T_TO_DOUBLE(vl->time),
+ CDTIME_T_TO_DOUBLE(vl->interval));
+#endif
+
+ plugin_dispatch_values(vl);
+
+ sfree(vl->values);
+ sfree(vl);
+ return 0;
+} /* }}} lua_cb_dispatch_values */
+
+static int lua_cb_register_read(lua_State *L) /* {{{ */
+{
+ int nargs = lua_gettop(L);
+
+ if (nargs != 1)
+ return luaL_error(L, "Invalid number of arguments (%d != 1)", nargs);
+
+ luaL_checktype(L, 1, LUA_TFUNCTION);
+
+ char function_name[DATA_MAX_NAME_LEN];
+ ssnprintf(function_name, sizeof(function_name), "lua/%s", lua_tostring(L, 1));
+
+ int callback_id = clua_store_callback(L, 1);
+ if (callback_id < 0)
+ return luaL_error(L, "%s", "Storing callback function failed");
+
+ lua_State *thread = lua_newthread(L);
+ if (thread == NULL)
+ return luaL_error(L, "%s", "lua_newthread failed");
+ clua_store_thread(L, -1);
+ lua_pop(L, 1);
+
+ clua_callback_data_t *cb = calloc(1, sizeof(*cb));
+ if (cb == NULL)
+ return luaL_error(L, "%s", "calloc failed");
+
+ cb->lua_state = thread;
+ cb->callback_id = callback_id;
+ cb->lua_function_name = strdup(function_name);
+ pthread_mutex_init(&cb->lock, NULL);
+
+ int status = plugin_register_complex_read(/* group = */ "lua",
+ /* name = */ function_name,
+ /* callback = */ clua_read,
+ /* interval = */ 0,
+ &(user_data_t) {
+ .data = cb,
+ });
+
+ if (status != 0)
+ return luaL_error(L, "%s", "plugin_register_complex_read failed");
+ return 0;
+} /* }}} int lua_cb_register_read */
+
+static int lua_cb_register_write(lua_State *L) /* {{{ */
+{
+ int nargs = lua_gettop(L);
+
+ if (nargs != 1)
+ return luaL_error(L, "Invalid number of arguments (%d != 1)", nargs);
+
+ luaL_checktype(L, 1, LUA_TFUNCTION);
+
+ char function_name[DATA_MAX_NAME_LEN] = "";
+ ssnprintf(function_name, sizeof(function_name), "lua/%s", lua_tostring(L, 1));
+
+ int callback_id = clua_store_callback(L, 1);
+ if (callback_id < 0)
+ return luaL_error(L, "%s", "Storing callback function failed");
+
+ lua_State *thread = lua_newthread(L);
+ if (thread == NULL)
+ return luaL_error(L, "%s", "lua_newthread failed");
+ clua_store_thread(L, -1);
+ lua_pop(L, 1);
+
+ clua_callback_data_t *cb = calloc(1, sizeof(*cb));
+ if (cb == NULL)
+ return luaL_error(L, "%s", "calloc failed");
+
+ cb->lua_state = thread;
+ cb->callback_id = callback_id;
+ cb->lua_function_name = strdup(function_name);
+ pthread_mutex_init(&cb->lock, NULL);
+
+ int status = plugin_register_write(/* name = */ function_name,
+ /* callback = */ clua_write,
+ &(user_data_t) {
+ .data = cb,
+ });
+
+ if (status != 0)
+ return luaL_error(L, "%s", "plugin_register_write failed");
+ return 0;
+} /* }}} int lua_cb_register_write */
+
+static const luaL_Reg collectdlib[] = {
+ {"log_debug", lua_cb_log_debug},
+ {"log_error", lua_cb_log_error},
+ {"log_info", lua_cb_log_info},
+ {"log_notice", lua_cb_log_notice},
+ {"log_warning", lua_cb_log_warning},
+ {"dispatch_values", lua_cb_dispatch_values},
+ {"register_read", lua_cb_register_read},
+ {"register_write", lua_cb_register_write},
+ {NULL, NULL}
+};
+
+static int open_collectd(lua_State *L) /* {{{ */
+{
+#if LUA_VERSION_NUM < 502
+ luaL_register(L, "collectd", collectdlib);
+#else
+ luaL_newlib(L, collectdlib);
+#endif
+ return 1;
+} /* }}} */
+
+static void lua_script_free(lua_script_t *script) /* {{{ */
+{
+ if (script == NULL)
+ return;
+
+ lua_script_t *next = script->next;
+
+ if (script->lua_state != NULL) {
+ lua_close(script->lua_state);
+ script->lua_state = NULL;
+ }
+
+ sfree(script->script_path);
+ sfree(script);
+
+ lua_script_free(next);
+} /* }}} void lua_script_free */
+
+static int lua_script_init(lua_script_t *script) /* {{{ */
+{
+ memset(script, 0, sizeof(*script));
+
+ /* initialize the lua context */
+ script->lua_state = luaL_newstate();
+ if (script->lua_state == NULL) {
+ ERROR("Lua plugin: luaL_newstate() failed.");
+ return (-1);
+ }
+
+ /* Open up all the standard Lua libraries. */
+ luaL_openlibs(script->lua_state);
+
+ /* Load the 'collectd' library */
+#if LUA_VERSION_NUM < 502
+ lua_pushcfunction(script->lua_state, open_collectd);
+ lua_pushstring(script->lua_state, "collectd");
+ lua_call(script->lua_state, 1, 0);
+#else
+ luaL_requiref(script->lua_state, "collectd", open_collectd, 1);
+ lua_pop(script->lua_state, 1);
+#endif
+
+ /* Prepend BasePath to package.path */
+ if (base_path[0] != '\0') {
+ lua_getglobal(script->lua_state, "package");
+ lua_getfield(script->lua_state, -1, "path");
+
+ const char *cur_path = lua_tostring(script->lua_state, -1);
+ char *new_path = ssnprintf_alloc("%s/?.lua;%s", base_path, cur_path);
+
+ lua_pop(script->lua_state, 1);
+ lua_pushstring(script->lua_state, new_path);
+
+ free(new_path);
+
+ lua_setfield(script->lua_state, -2, "path");
+ lua_pop(script->lua_state, 1);
+ }
+
+ return (0);
+} /* }}} int lua_script_init */
+
+static int lua_script_load(const char *script_path) /* {{{ */
+{
+ lua_script_t *script = malloc(sizeof(*script));
+ if (script == NULL) {
+ ERROR("Lua plugin: malloc failed.");
+ return (-1);
+ }
+
+ int status = lua_script_init(script);
+ if (status != 0) {
+ lua_script_free(script);
+ return (status);
+ }
+
+ script->script_path = strdup(script_path);
+ if (script->script_path == NULL) {
+ ERROR("Lua plugin: strdup failed.");
+ lua_script_free(script);
+ return (-1);
+ }
+
+ status = luaL_loadfile(script->lua_state, script->script_path);
+ if (status != 0) {
+ ERROR("Lua plugin: luaL_loadfile failed: %s",
+ lua_tostring(script->lua_state, -1));
+ lua_pop(script->lua_state, 1);
+ lua_script_free(script);
+ return (-1);
+ }
+
+ status = lua_pcall(script->lua_state,
+ /* nargs = */ 0,
+ /* nresults = */ LUA_MULTRET,
+ /* errfunc = */ 0);
+ if (status != 0) {
+ const char *errmsg = lua_tostring(script->lua_state, -1);
+
+ if (errmsg == NULL)
+ ERROR("Lua plugin: lua_pcall failed with status %i. "
+ "In addition, no error message could be retrieved from the stack.",
+ status);
+ else
+ ERROR("Lua plugin: Executing script \"%s\" failed:\n%s",
+ script->script_path, errmsg);
+
+ lua_script_free(script);
+ return (-1);
+ }
+
+ /* Append this script to the global list of scripts. */
+ if (scripts) {
+ lua_script_t *last = scripts;
+ while (last->next)
+ last = last->next;
+
+ last->next = script;
+ } else {
+ scripts = script;
+ }
+
+ return (0);
+} /* }}} int lua_script_load */
+
+static int lua_config_base_path(const oconfig_item_t *ci) /* {{{ */
+{
+ int status = cf_util_get_string_buffer(ci, base_path, sizeof(base_path));
+ if (status != 0)
+ return (status);
+
+ size_t len = strlen(base_path);
+ while ((len > 0) && (base_path[len - 1] == '/')) {
+ len--;
+ base_path[len] = '\0';
+ }
+
+ DEBUG("Lua plugin: base_path = \"%s\";", base_path);
+
+ return (0);
+} /* }}} int lua_config_base_path */
+
+static int lua_config_script(const oconfig_item_t *ci) /* {{{ */
+{
+ char rel_path[PATH_MAX];
+
+ int status = cf_util_get_string_buffer(ci, rel_path, sizeof(rel_path));
+ if (status != 0)
+ return (status);
+
+ char abs_path[PATH_MAX];
+
+ if (base_path[0] == '\0')
+ sstrncpy(abs_path, rel_path, sizeof(abs_path));
+ else
+ ssnprintf(abs_path, sizeof(abs_path), "%s/%s", base_path, rel_path);
+
+ DEBUG("Lua plugin: abs_path = \"%s\";", abs_path);
+
+ status = lua_script_load(abs_path);
+ if (status != 0)
+ return (status);
+
+ INFO("Lua plugin: File \"%s\" loaded succesfully", abs_path);
+
+ return 0;
+} /* }}} int lua_config_script */
+
+/*
+ * <Plugin lua>
+ * BasePath "/"
+ * Script "script1.lua"
+ * Script "script2.lua"
+ * </Plugin>
+ */
+static int lua_config(oconfig_item_t *ci) /* {{{ */
+{
+ int status = 0;
+ for (int i = 0; i < ci->children_num; i++) {
+ oconfig_item_t *child = ci->children + i;
+
+ if (strcasecmp("BasePath", child->key) == 0) {
+ status = lua_config_base_path(child);
+ } else if (strcasecmp("Script", child->key) == 0) {
+ status = lua_config_script(child);
+ } else {
+ ERROR("Lua plugin: Option `%s' is not allowed here.", child->key);
+ status = 1;
+ }
+ }
+
+ return status;
+} /* }}} int lua_config */
+
+static int lua_shutdown(void) /* {{{ */
+{
+ lua_script_free(scripts);
+
+ return (0);
+} /* }}} int lua_shutdown */
+
+void module_register(void) {
+ plugin_register_complex_config("lua", lua_config);
+ plugin_register_shutdown("lua", lua_shutdown);
+}
+
+/* vim: set sw=2 sts=2 et fdm=marker : */
#include <lvm2app.h>
#include "collectd.h"
+
#include "common.h"
#include "plugin.h"
static void lvm_submit (char const *plugin_instance, char const *type_instance,
uint64_t ivalue)
{
- value_t v;
value_list_t vl = VALUE_LIST_INIT;
- v.gauge = (gauge_t) ivalue;
-
- vl.values = &v;
+ vl.values = &(value_t) { .gauge = (gauge_t) ivalue };
vl.values_len = 1;
sstrncpy(vl.host, hostname_g, sizeof (vl.host));
#include "collectd.h"
+
#include "common.h"
#include "plugin.h"
-#include "configfile.h"
#include "utils_ignorelist.h"
#include <dirent.h>
static inline void watchlist_set (uint32_t *wl, uint32_t val)
{
- int i;
- for (i = 0; i < WL_LEN; i++)
+ for (int i = 0; i < WL_LEN; i++)
wl[i] = val;
}
static int watchitem_find (const char *name)
{
int max = STATIC_ARRAY_SIZE (specs);
- int i;
- for (i = 0; i < max; i++)
+ for (int i = 0; i < max; i++)
if (strcasecmp (name, specs[i].name) == 0)
return i;
static int madwifi_real_init (void)
{
size_t max = STATIC_ARRAY_SIZE (specs);
- size_t i;
- for (i = 0; i < STATIC_ARRAY_SIZE (bounds); i++)
+ for (size_t i = 0; i < STATIC_ARRAY_SIZE (bounds); i++)
bounds[i] = 0;
watchlist_set(watch_items, 0);
watchlist_set(misc_items, 0);
- for (i = 0; i < max; i++)
+ for (size_t i = 0; i < max; i++)
{
bounds[specs[i].flags & SRC_MASK] = i;
misc_items[i / 32] |= FLAG (i);
}
- for (i = 0; i < STATIC_ARRAY_SIZE (bounds); i++)
+ for (size_t i = 0; i < STATIC_ARRAY_SIZE (bounds); i++)
bounds[i]++;
return (0);
static void submit (const char *dev, const char *type, const char *ti1,
- const char *ti2, value_t *val, int len)
+ const char *ti2, value_t *val, size_t len)
{
value_list_t vl = VALUE_LIST_INIT;
}
static void submit_derive (const char *dev, const char *type, const char *ti1,
- const char *ti2, derive_t val)
+ const char *ti2, derive_t value)
{
- value_t item;
- item.derive = val;
- submit (dev, type, ti1, ti2, &item, 1);
+ submit (dev, type, ti1, ti2, &(value_t) { .derive = value }, 1);
}
static void submit_derive2 (const char *dev, const char *type, const char *ti1,
const char *ti2, derive_t val1, derive_t val2)
{
- value_t items[2];
- items[0].derive = val1;
- items[1].derive = val2;
- submit (dev, type, ti1, ti2, items, 2);
+ value_t values[] = {
+ { .derive = val1 },
+ { .derive = val2 },
+ };
+
+ submit (dev, type, ti1, ti2, values, STATIC_ARRAY_SIZE (values));
}
static void submit_gauge (const char *dev, const char *type, const char *ti1,
- const char *ti2, gauge_t val)
+ const char *ti2, gauge_t value)
{
- value_t item;
- item.gauge = val;
- submit (dev, type, ti1, ti2, &item, 1);
+ submit (dev, type, ti1, ti2, &(value_t) { .gauge = value }, 1);
}
static void submit_antx (const char *dev, const char *name,
u_int32_t *vals, int vals_num)
{
char ti2[16];
- int i;
- for (i = 0; i < vals_num; i++)
+ for (int i = 0; i < vals_num; i++)
{
if (vals[i] == 0)
continue;
const char *type_name, const char *misc_name)
{
uint32_t misc = 0;
- int i;
assert (which >= 1);
assert (((size_t) which) < STATIC_ARRAY_SIZE (bounds));
- for (i = bounds[which - 1]; i < bounds[which]; i++)
+ for (int i = bounds[which - 1]; i < bounds[which]; i++)
{
uint32_t val = *(uint32_t *)(((char *) ptr) + specs[i].offset) ;
static int
process_station (int sk, const char *dev, struct ieee80211req_sta_info *si)
{
- struct iwreq iwr;
static char mac[DATA_MAX_NAME_LEN];
struct ieee80211req_sta_stats stats;
const struct ieee80211_nodestats *ns = &stats.is_stats;
if (item_watched (STAT_NODE_RSSI))
submit_gauge (dev, "node_rssi", mac, NULL, si->isi_rssi);
- memset (&iwr, 0, sizeof (iwr));
+ struct iwreq iwr = {
+ .u.data.pointer = (void *) &stats,
+ .u.data.length = sizeof (stats)
+ };
sstrncpy(iwr.ifr_name, dev, sizeof (iwr.ifr_name));
- iwr.u.data.pointer = (void *) &stats;
- iwr.u.data.length = sizeof (stats);
+
memcpy(stats.is_u.macaddr, si->isi_macaddr, IEEE80211_ADDR_LEN);
status = ioctl(sk, IEEE80211_IOCTL_STA_STATS, &iwr);
if (status < 0)
static int
process_stations (int sk, const char *dev)
{
- uint8_t buf[24*1024];
- struct iwreq iwr;
+ uint8_t buf[24*1024] = { 0 };
uint8_t *cp;
int nodes;
size_t len;
int status;
- memset (&iwr, 0, sizeof (iwr));
+ struct iwreq iwr = {
+ .u.data.pointer = (void *) buf,
+ .u.data.length = sizeof (buf)
+ };
sstrncpy (iwr.ifr_name, dev, sizeof (iwr.ifr_name));
- iwr.u.data.pointer = (void *) buf;
- iwr.u.data.length = sizeof (buf);
status = ioctl (sk, IEEE80211_IOCTL_STA_INFO, &iwr);
if (status < 0)
**/
#include "collectd.h"
+
#include "common.h"
#include "filter_chain.h"
{
int num_counters = 0;
int num_empty = 0;
- size_t i;
- for (i = 0; i < ds->ds_num; i++)
+ for (size_t i = 0; i < ds->ds_num; i++)
{
if ((ds->ds[i].type != DS_TYPE_DERIVE)
&& (ds->ds[i].type != DS_TYPE_COUNTER))
**/
#include "collectd.h"
+
#include "common.h"
#include "filter_chain.h"
static int mh_create (const oconfig_item_t *ci, void **user_data) /* {{{ */
{
mh_match_t *m;
- int i;
m = calloc (1, sizeof (*m));
if (m == NULL)
return (-ENOMEM);
}
- for (i = 0; i < ci->children_num; i++)
+ for (int i = 0; i < ci->children_num; i++)
{
oconfig_item_t *child = ci->children + i;
{
mh_match_t *m;
uint32_t hash_val;
- const char *host_ptr;
- size_t i;
if ((user_data == NULL) || (*user_data == NULL))
return (-1);
hash_val = 0;
- for (host_ptr = vl->host; *host_ptr != 0; host_ptr++)
+ for (const char *host_ptr = vl->host; *host_ptr != 0; host_ptr++)
{
/* 2184401929 is some appropriately sized prime number. */
hash_val = (hash_val * UINT32_C (2184401929)) + ((uint32_t) *host_ptr);
}
DEBUG ("hashed match: host = %s; hash_val = %"PRIu32";", vl->host, hash_val);
- for (i = 0; i < m->matches_num; i++)
+ for (size_t i = 0; i < m->matches_num; i++)
if ((hash_val % m->matches[i].total) == m->matches[i].match)
return (FC_MATCH_MATCHES);
void module_register (void)
{
- match_proc_t mproc;
+ match_proc_t mproc = { 0 };
- memset (&mproc, 0, sizeof (mproc));
mproc.create = mh_create;
mproc.destroy = mh_destroy;
mproc.match = mh_match;
*/
#include "collectd.h"
+
+#include "common.h"
#include "filter_chain.h"
+#include "meta_data.h"
+#include "utils_llist.h"
#include <sys/types.h>
#include <regex.h>
mr_regex_t *plugin_instance;
mr_regex_t *type;
mr_regex_t *type_instance;
+ llist_t *meta; /* Maps each meta key into mr_regex_t* */
_Bool invert;
};
regfree (&r->re);
memset (&r->re, 0, sizeof (r->re));
- free (r->re_str);
+ sfree (r->re_str);
if (r->next != NULL)
mr_free_regex (r->next);
mr_free_regex (m->plugin_instance);
mr_free_regex (m->type);
mr_free_regex (m->type_instance);
+ for (llentry_t *e = llist_head(m->meta); e != NULL; e = e->next)
+ {
+ sfree (e->key);
+ mr_free_regex ((mr_regex_t *) e->value);
+ }
+ llist_destroy (m->meta);
- free (m);
+ sfree (m);
} /* }}} void mr_free_match */
static int mr_match_regexen (mr_regex_t *re_head, /* {{{ */
const char *string)
{
- mr_regex_t *re;
-
if (re_head == NULL)
return (FC_MATCH_MATCHES);
- for (re = re_head; re != NULL; re = re->next)
+ for (mr_regex_t *re = re_head; re != NULL; re = re->next)
{
int status;
return (FC_MATCH_MATCHES);
} /* }}} int mr_match_regexen */
-static int mr_config_add_regex (mr_regex_t **re_head, /* {{{ */
- oconfig_item_t *ci)
+static int mr_add_regex (mr_regex_t **re_head, const char *re_str, /* {{{ */
+ const char *option)
{
mr_regex_t *re;
int status;
- if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING))
- {
- log_warn ("`%s' needs exactly one string argument.", ci->key);
- return (-1);
- }
-
re = calloc (1, sizeof (*re));
if (re == NULL)
{
- log_err ("mr_config_add_regex: calloc failed.");
+ log_err ("mr_add_regex: calloc failed.");
return (-1);
}
re->next = NULL;
- re->re_str = strdup (ci->values[0].value.string);
+ re->re_str = strdup (re_str);
if (re->re_str == NULL)
{
- free (re);
- log_err ("mr_config_add_regex: strdup failed.");
+ sfree (re);
+ log_err ("mr_add_regex: strdup failed.");
return (-1);
}
regerror (status, &re->re, errmsg, sizeof (errmsg));
errmsg[sizeof (errmsg) - 1] = 0;
log_err ("Compiling regex `%s' for `%s' failed: %s.",
- re->re_str, ci->key, errmsg);
- free (re->re_str);
- free (re);
+ re->re_str, option, errmsg);
+ sfree (re->re_str);
+ sfree (re);
return (-1);
}
}
return (0);
+} /* }}} int mr_add_regex */
+
+static int mr_config_add_regex (mr_regex_t **re_head, /* {{{ */
+ oconfig_item_t *ci)
+{
+ if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING))
+ {
+ log_warn ("`%s' needs exactly one string argument.", ci->key);
+ return (-1);
+ }
+
+ return mr_add_regex (re_head, ci->values[0].value.string, ci->key);
} /* }}} int mr_config_add_regex */
+static int mr_config_add_meta_regex (llist_t **meta, /* {{{ */
+ oconfig_item_t *ci)
+{
+ char *meta_key;
+ llentry_t *entry;
+ mr_regex_t *re_head;
+ int status;
+ char buffer[1024];
+
+ if ((ci->values_num != 2)
+ || (ci->values[0].type != OCONFIG_TYPE_STRING)
+ || (ci->values[1].type != OCONFIG_TYPE_STRING))
+ {
+ log_warn ("`%s' needs exactly two string arguments.", ci->key);
+ return (-1);
+ }
+
+ if (*meta == NULL)
+ {
+ *meta = llist_create();
+ if (*meta == NULL)
+ {
+ log_err ("mr_config_add_meta_regex: llist_create failed.");
+ return (-1);
+ }
+ }
+
+ meta_key = ci->values[0].value.string;
+ entry = llist_search (*meta, meta_key);
+ if (entry == NULL)
+ {
+ meta_key = strdup (meta_key);
+ if (meta_key == NULL)
+ {
+ log_err ("mr_config_add_meta_regex: strdup failed.");
+ return (-1);
+ }
+ entry = llentry_create (meta_key, NULL);
+ if (entry == NULL)
+ {
+ log_err ("mr_config_add_meta_regex: llentry_create failed.");
+ sfree (meta_key);
+ return (-1);
+ }
+ /* meta_key and entry will now be freed by mr_free_match(). */
+ llist_append (*meta, entry);
+ }
+
+ ssnprintf (buffer, sizeof (buffer), "%s `%s'", ci->key, meta_key);
+ /* Can't pass &entry->value into mr_add_regex, so copy in/out. */
+ re_head = entry->value;
+ status = mr_add_regex (&re_head, ci->values[1].value.string, buffer);
+ if (status == 0) {
+ entry->value = re_head;
+ }
+ return status;
+} /* }}} int mr_config_add_meta_regex */
+
static int mr_create (const oconfig_item_t *ci, void **user_data) /* {{{ */
{
mr_match_t *m;
int status;
- int i;
m = calloc (1, sizeof (*m));
if (m == NULL)
m->invert = 0;
status = 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;
status = mr_config_add_regex (&m->type, child);
else if (strcasecmp ("TypeInstance", child->key) == 0)
status = mr_config_add_regex (&m->type_instance, child);
+ else if (strcasecmp ("MetaData", child->key) == 0)
+ status = mr_config_add_meta_regex (&m->meta, child);
else if (strcasecmp ("Invert", child->key) == 0)
status = cf_util_get_boolean(child, &m->invert);
else
&& (m->plugin == NULL)
&& (m->plugin_instance == NULL)
&& (m->type == NULL)
- && (m->type_instance == NULL))
+ && (m->type_instance == NULL)
+ && (m->meta == NULL))
{
log_err ("No (valid) regular expressions have been configured. "
"This match will be ignored.");
if (mr_match_regexen (m->type_instance,
vl->type_instance) == FC_MATCH_NO_MATCH)
return (nomatch_value);
+ if (vl->meta != NULL)
+ {
+ for (llentry_t *e = llist_head(m->meta); e != NULL; e = e->next)
+ {
+ mr_regex_t *meta_re = (mr_regex_t *) e->value;
+ char *value;
+ int status = meta_data_get_string (vl->meta, e->key, &value);
+ if (status == (-ENOENT)) /* key is not present */
+ return (nomatch_value);
+ if (status != 0) /* some other problem */
+ continue; /* error will have already been printed. */
+ if (mr_match_regexen (meta_re, value) == FC_MATCH_NO_MATCH)
+ {
+ sfree (value);
+ return (nomatch_value);
+ }
+ sfree (value);
+ }
+ }
return (match_value);
} /* }}} int mr_match */
void module_register (void)
{
- match_proc_t mproc;
+ match_proc_t mproc = { 0 };
- memset (&mproc, 0, sizeof (mproc));
mproc.create = mr_create;
mproc.destroy = mr_destroy;
mproc.match = mr_match;
**/
#include "collectd.h"
+
#include "common.h"
#include "filter_chain.h"
{
mt_match_t *m;
int status;
- int i;
m = calloc (1, sizeof (*m));
if (m == NULL)
m->past = 0;
status = 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;
void module_register (void)
{
- match_proc_t mproc;
+ match_proc_t mproc = { 0 };
- memset (&mproc, 0, sizeof (mproc));
mproc.create = mt_create;
mproc.destroy = mt_destroy;
mproc.match = mt_match;
*/
#include "collectd.h"
+
#include "common.h"
#include "utils_cache.h"
#include "filter_chain.h"
*/
static void mv_free_match (mv_match_t *m) /* {{{ */
{
- size_t i;
-
if (m == NULL)
return;
if (m->data_sources != NULL)
{
- for (i = 0; i < m->data_sources_num; ++i)
+ for (size_t i = 0; i < m->data_sources_num; ++i)
free(m->data_sources[i]);
free(m->data_sources);
}
{
size_t new_data_sources_num;
char **temp;
- int i;
/* Check number of arbuments. */
if (ci->values_num < 1)
}
/* Check type of arguments */
- for (i = 0; i < ci->values_num; i++)
+ for (int i = 0; i < ci->values_num; i++)
{
if (ci->values[i].type == OCONFIG_TYPE_STRING)
continue;
m->data_sources = temp;
/* Copy the strings, allocating memory as needed. */
- for (i = 0; i < ci->values_num; i++)
+ for (int i = 0; i < ci->values_num; i++)
{
- size_t j;
-
/* If we get here, there better be memory for us to write to. */
assert (m->data_sources_num < new_data_sources_num);
- j = m->data_sources_num;
+ size_t j = m->data_sources_num;
m->data_sources[j] = sstrdup (ci->values[i].value.string);
if (m->data_sources[j] == NULL)
{
{
mv_match_t *m;
int status;
- int i;
m = calloc (1, sizeof (*m));
if (m == NULL)
m->data_sources_num = 0;
status = 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;
mv_match_t *m;
gauge_t *values;
int status;
- size_t i;
if ((user_data == NULL) || (*user_data == NULL))
return (-1);
status = FC_MATCH_NO_MATCH;
- for (i = 0; i < ds->ds_num; i++)
+ for (size_t i = 0; i < ds->ds_num; i++)
{
int value_matches = 0;
void module_register (void)
{
- match_proc_t mproc;
+ match_proc_t mproc = { 0 };
- memset (&mproc, 0, sizeof (mproc));
mproc.create = mv_create;
mproc.destroy = mv_destroy;
mproc.match = mv_match;
**/
#include "collectd.h"
+
#include "common.h"
#include "plugin.h"
-#include "configfile.h"
#include <netdb.h>
#include <netinet/in.h>
const char *host;
const char *port;
- struct addrinfo ai_hints;
- struct addrinfo *ai_list, *ai_ptr;
+ struct addrinfo *ai_list;
int ai_return;
- memset (&ai_hints, '\0', sizeof (ai_hints));
- ai_hints.ai_flags = 0;
-#ifdef AI_ADDRCONFIG
- ai_hints.ai_flags |= AI_ADDRCONFIG;
-#endif
- ai_hints.ai_family = PF_UNSPEC;
- ai_hints.ai_socktype = SOCK_STREAM;
- ai_hints.ai_protocol = IPPROTO_TCP;
-
host = mbmon_host;
if (host == NULL)
host = MBMON_DEF_HOST;
if (port == NULL)
port = MBMON_DEF_PORT;
+ struct addrinfo ai_hints = {
+ .ai_family = AF_UNSPEC,
+ .ai_flags = AI_ADDRCONFIG,
+ .ai_protocol = IPPROTO_TCP,
+ .ai_socktype = SOCK_STREAM
+ };
+
if ((ai_return = getaddrinfo (host, port, &ai_hints, &ai_list)) != 0)
{
char errbuf[1024];
}
fd = -1;
- for (ai_ptr = ai_list; ai_ptr != NULL; ai_ptr = ai_ptr->ai_next)
+ for (struct addrinfo *ai_ptr = ai_list; ai_ptr != NULL; ai_ptr = ai_ptr->ai_next)
{
/* create our socket descriptor */
if ((fd = socket (ai_ptr->ai_family, ai_ptr->ai_socktype, ai_ptr->ai_protocol)) < 0)
static void mbmon_submit (const char *type, const char *type_instance,
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, "mbmon", sizeof (vl.plugin));
/* Trim trailing whitespace from a string. */
static void trim_spaces (char *s)
{
- size_t l;
-
- for (l = strlen (s) - 1; (l > 0) && isspace ((int) s[l]); l--)
+ for (size_t l = strlen (s) - 1; (l > 0) && isspace ((int) s[l]); l--)
s[l] = '\0';
}
**/
#include "collectd.h"
+
#include "common.h"
#include "plugin.h"
#include "utils_ignorelist.h"
#include <linux/major.h>
#include <linux/raid/md_u.h>
+#ifdef HAVE_SYS_SYSMACROS_H
+#include <sys/sysmacros.h>
+#endif
+
#define PROC_DISKSTATS "/proc/diskstats"
#define DEV_DIR "/dev"
static void md_submit (const int minor, 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, "md", sizeof (vl.plugin));
**/
#include "collectd.h"
+
#include "common.h"
#include "plugin.h"
-#include "configfile.h"
#include "utils_match.h"
#include <libmemcached/memcached.h>
{
web_match_t *match;
int status;
- int i;
if (ci->values_num != 0)
{
}
status = 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;
{
web_page_t *page;
int status;
- int i;
if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING))
{
/* Process all children */
status = 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;
int success;
int errors;
int status;
- int i;
success = 0;
errors = 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;
} /* }}} int cmc_init */
static void cmc_submit (const web_page_t *wp, const web_match_t *wm, /* {{{ */
- const cu_match_value_t *mv)
+ value_t value)
{
- value_t values[1];
value_list_t vl = VALUE_LIST_INIT;
- values[0] = mv->value;
-
- vl.values = values;
+ vl.values = &value;
vl.values_len = 1;
sstrncpy (vl.host, hostname_g, sizeof (vl.host));
sstrncpy (vl.plugin, "memcachec", sizeof (vl.plugin));
static int cmc_read_page (web_page_t *wp) /* {{{ */
{
- web_match_t *wm;
memcached_return rc;
size_t string_length;
uint32_t flags;
return (-1);
}
- for (wm = wp->matches; wm != NULL; wm = wm->next)
+ for (web_match_t *wm = wp->matches; wm != NULL; wm = wm->next)
{
cu_match_value_t *mv;
continue;
}
- cmc_submit (wp, wm, mv);
+ cmc_submit (wp, wm, mv->value);
match_value_reset (mv);
} /* for (wm = wp->matches; wm != NULL; wm = wm->next) */
static int cmc_read (void) /* {{{ */
{
- web_page_t *wp;
-
- for (wp = pages_g; wp != NULL; wp = wp->next)
+ for (web_page_t *wp = pages_g; wp != NULL; wp = wp->next)
cmc_read_page (wp);
return (0);
**/
#include "collectd.h"
+
#include "common.h"
#include "plugin.h"
-#include "configfile.h"
#include <netdb.h>
#include <sys/un.h>
static int memcached_connect_unix (memcached_t *st)
{
- struct sockaddr_un serv_addr;
+ struct sockaddr_un serv_addr = { 0 };
int fd;
- memset (&serv_addr, 0, sizeof (serv_addr));
serv_addr.sun_family = AF_UNIX;
sstrncpy (serv_addr.sun_path, st->socket,
sizeof (serv_addr.sun_path));
const char *host;
const char *port;
- struct addrinfo ai_hints;
- struct addrinfo *ai_list, *ai_ptr;
+ struct addrinfo *ai_list;
int status;
int fd = -1;
- memset (&ai_hints, 0, sizeof (ai_hints));
- ai_hints.ai_flags = 0;
-#ifdef AI_ADDRCONFIG
- ai_hints.ai_flags |= AI_ADDRCONFIG;
-#endif
- ai_hints.ai_family = AF_UNSPEC;
- ai_hints.ai_socktype = SOCK_STREAM;
- ai_hints.ai_protocol = 0;
-
host = (st->host != NULL) ? st->host : MEMCACHED_DEF_HOST;
port = (st->port != NULL) ? st->port : MEMCACHED_DEF_PORT;
- ai_list = NULL;
+ struct addrinfo ai_hints = {
+ .ai_family = AF_UNSPEC,
+ .ai_flags = AI_ADDRCONFIG,
+ .ai_socktype = SOCK_STREAM
+ };
+
status = getaddrinfo (host, port, &ai_hints, &ai_list);
if (status != 0)
{
return (-1);
}
- for (ai_ptr = ai_list; ai_ptr != NULL; ai_ptr = ai_ptr->ai_next)
+ for (struct addrinfo *ai_ptr = ai_list; ai_ptr != NULL; ai_ptr = ai_ptr->ai_next)
{
/* create our socket descriptor */
fd = socket (ai_ptr->ai_family, ai_ptr->ai_socktype, ai_ptr->ai_protocol);
static void memcached_init_vl (value_list_t *vl, memcached_t const *st)
{
+ char const *host = st->host;
+
+ /* Set vl->host to hostname_g, if:
+ * - Legacy mode is used.
+ * - "Socket" option is given (doc: "Host option is ignored").
+ * - "Host" option is not provided.
+ * - "Host" option is set to "localhost" or "127.0.0.1". */
+ if ((strcmp (st->name, "__legacy__") == 0)
+ || (st->socket != NULL)
+ || (st->host == NULL)
+ || (strcmp ("127.0.0.1", st->host) == 0)
+ || (strcmp ("localhost", st->host) == 0))
+ host = hostname_g;
+
sstrncpy (vl->plugin, "memcached", sizeof (vl->plugin));
- if (strcmp (st->name, "__legacy__") == 0) /* legacy mode */
- {
- sstrncpy (vl->host, hostname_g, sizeof (vl->host));
- }
- else
- {
- if (st->socket != NULL)
- sstrncpy (vl->host, hostname_g, sizeof (vl->host));
- else
- sstrncpy (vl->host,
- (st->host != NULL) ? st->host : MEMCACHED_DEF_HOST,
- sizeof (vl->host));
+ sstrncpy (vl->host, host, sizeof (vl->host));
+ if (strcmp (st->name, "__legacy__") != 0)
sstrncpy (vl->plugin_instance, st->name, sizeof (vl->plugin_instance));
- }
}
static void submit_derive (const char *type, const char *type_inst,
derive_t value, memcached_t *st)
{
- value_t values[1];
value_list_t vl = VALUE_LIST_INIT;
- memcached_init_vl (&vl, st);
-
- values[0].derive = value;
- vl.values = values;
+ memcached_init_vl (&vl, st);
+ vl.values = &(value_t) { .derive = value };
vl.values_len = 1;
sstrncpy (vl.type, type, sizeof (vl.type));
if (type_inst != NULL)
static void submit_derive2 (const char *type, const char *type_inst,
derive_t value0, derive_t value1, memcached_t *st)
{
- value_t values[2];
value_list_t vl = VALUE_LIST_INIT;
- memcached_init_vl (&vl, st);
-
- values[0].derive = value0;
- values[1].derive = value1;
+ value_t values[] = {
+ { .derive = value0 },
+ { .derive = value1 },
+ };
+ memcached_init_vl (&vl, st);
vl.values = values;
- vl.values_len = 2;
+ vl.values_len = STATIC_ARRAY_SIZE (values);
sstrncpy (vl.type, type, sizeof (vl.type));
if (type_inst != NULL)
sstrncpy (vl.type_instance, type_inst, sizeof (vl.type_instance));
static void submit_gauge (const char *type, const char *type_inst,
gauge_t value, memcached_t *st)
{
- value_t values[1];
value_list_t vl = VALUE_LIST_INIT;
- memcached_init_vl (&vl, st);
-
- values[0].gauge = value;
- vl.values = values;
+ memcached_init_vl (&vl, st);
+ vl.values = &(value_t) { .gauge = value };
vl.values_len = 1;
sstrncpy (vl.type, type, sizeof (vl.type));
if (type_inst != NULL)
static void submit_gauge2 (const char *type, const char *type_inst,
gauge_t value0, gauge_t value1, memcached_t *st)
{
- value_t values[2];
value_list_t vl = VALUE_LIST_INIT;
- memcached_init_vl (&vl, st);
-
- values[0].gauge = value0;
- values[1].gauge = value1;
+ value_t values[] = {
+ { .gauge = value0 },
+ { .gauge = value1 },
+ };
+ memcached_init_vl (&vl, st);
vl.values = values;
- vl.values_len = 2;
+ vl.values_len = STATIC_ARRAY_SIZE (values);
sstrncpy (vl.type, type, sizeof (vl.type));
if (type_inst != NULL)
sstrncpy (vl.type_instance, type_inst, sizeof (vl.type_instance));
static int memcached_add_read_callback (memcached_t *st)
{
- user_data_t ud;
char callback_name[3*DATA_MAX_NAME_LEN];
int status;
- memset (&ud, 0, sizeof (ud));
- ud.data = st;
- ud.free_func = memcached_free;
-
assert (st->name != NULL);
ssnprintf (callback_name, sizeof (callback_name), "memcached/%s", st->name);
/* name = */ callback_name,
/* callback = */ memcached_read,
/* interval = */ 0,
- /* user_data = */ &ud);
+ &(user_data_t) {
+ .data = st,
+ .free_func = memcached_free,
+ });
+
return (status);
} /* int memcached_add_read_callback */
static int config_add_instance(oconfig_item_t *ci)
{
memcached_t *st;
- int i;
int status = 0;
/* Disable automatic generation of default instance in the init callback. */
}
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;
{
int status = 0;
_Bool have_instance_block = 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;
**/
#include "collectd.h"
+
#include "common.h"
#include "plugin.h"
static int memory_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;
if (strcasecmp ("ValuesAbsolute", child->key) == 0)
};
double sysctl_vals[8];
- int i;
-
- for (i = 0; sysctl_keys[i] != NULL; i++)
+ for (int i = 0; sysctl_keys[i] != NULL; i++)
{
int value;
size_t value_len = sizeof (value);
} /* for (sysctl_keys) */
/* multiply all all page counts with the pagesize */
- for (i = 1; sysctl_keys[i] != NULL; i++)
+ for (int i = 1; sysctl_keys[i] != NULL; i++)
if (!isnan (sysctl_vals[i]))
sysctl_vals[i] *= sysctl_vals[0];
#elif HAVE_SYSCTL
int mib[] = {CTL_VM, VM_METER};
- struct vmtotal vmtotal;
+ struct vmtotal vmtotal = { 0 };
gauge_t mem_active;
gauge_t mem_inactive;
gauge_t mem_free;
size_t size;
- memset (&vmtotal, 0, sizeof (vmtotal));
size = sizeof (vmtotal);
if (sysctl (mib, 2, &vmtotal, &size, NULL, 0) < 0) {
/* #endif HAVE_LIBSTATGRAB */
#elif HAVE_PERFSTAT
- perfstat_memory_total_t pmemory;
+ perfstat_memory_total_t pmemory = { 0 };
- memset (&pmemory, 0, sizeof (pmemory));
if (perfstat_memory_total(NULL, &pmemory, sizeof(pmemory), 1) < 0)
{
char errbuf[1024];
**/
#include "collectd.h"
+
#include "plugin.h"
#include "common.h"
#include "utils_ignorelist.h"
return (0);
}
-static void mic_submit_memory_use(int micnumber, const char *type_instance, U32 val)
+static void mic_submit_memory_use(int micnumber, const char *type_instance, U32 value)
{
- value_t values[1];
value_list_t vl = VALUE_LIST_INIT;
/* MicAccessAPI reports KB's of memory, adjust for this */
- DEBUG("mic plugin: Memory Value Report; %u %lf",val,((gauge_t)val)*1024.0);
- values[0].gauge = ((gauge_t)val)*1024.0;
+ DEBUG("mic plugin: Memory Value Report; %u %lf",value,((gauge_t)value)*1024.0);
- vl.values=values;
- vl.values_len=1;
+ vl.values = &(value_t) { .gauge = ((gauge_t)value) * 1024.0 };
+ vl.values_len = 1;
strncpy (vl.host, hostname_g, sizeof (vl.host));
strncpy (vl.plugin, "mic", sizeof (vl.plugin));
return (0);
}
-static void mic_submit_temp(int micnumber, const char *type, gauge_t val)
+static void mic_submit_temp(int micnumber, const char *type, gauge_t value)
{
- value_t values[1];
value_list_t vl = VALUE_LIST_INIT;
- values[0].gauge = val;
-
- vl.values=values;
- vl.values_len=1;
+ vl.values = &(value_t) { .gauge = value };
+ vl.values_len = 1;
strncpy (vl.host, hostname_g, sizeof (vl.host));
strncpy (vl.plugin, "mic", sizeof (vl.plugin));
static int mic_read_temps(int mic)
{
size_t num_therms = STATIC_ARRAY_SIZE(therm_ids);
- size_t j;
- for (j = 0; j < num_therms; j++) {
+ for (size_t j = 0; j < num_therms; j++) {
U32 status;
U32 temp_buffer;
U32 buffer_size = (U32)sizeof(temp_buffer);
}
static void mic_submit_cpu(int micnumber, const char *type_instance,
- int core, derive_t val)
+ int core, derive_t value)
{
- value_t values[1];
value_list_t vl = VALUE_LIST_INIT;
- values[0].derive = val;
-
- vl.values=values;
- vl.values_len=1;
+ vl.values = &(value_t) { .derive = value };
+ vl.values_len = 1;
strncpy (vl.host, hostname_g, sizeof (vl.host));
strncpy (vl.plugin, "mic", sizeof (vl.plugin));
}
if (show_cpu_cores) {
- int j;
- for (j = 0; j < core_util.core; j++) {
+ for (int j = 0; j < core_util.core; j++) {
mic_submit_cpu(mic, "user", j, core_jiffs[j].user);
mic_submit_cpu(mic, "sys", j, core_jiffs[j].sys);
mic_submit_cpu(mic, "nice", j, core_jiffs[j].nice);
return (0);
}
-static void mic_submit_power(int micnumber, const char *type, const char *type_instance, gauge_t val)
+static void mic_submit_power(int micnumber, const char *type, const char *type_instance, gauge_t value)
{
- value_t values[1];
value_list_t vl = VALUE_LIST_INIT;
- values[0].gauge = val;
-
- vl.values=values;
- vl.values_len=1;
+ vl.values = &(value_t) { .gauge = value };
+ vl.values_len = 1;
strncpy (vl.host, hostname_g, sizeof (vl.host));
strncpy (vl.plugin, "mic", sizeof (vl.plugin));
static int mic_read (void)
{
- int i;
U32 ret;
int error;
- error=0;
- for (i=0;i<num_mics;i++) {
+ error = 0;
+ for (int i = 0;i<num_mics;i++) {
ret = MicInitAdapter(&mic_handle,&mics[i]);
if (ret != MIC_ACCESS_API_SUCCESS) {
ERROR("mic plugin: Problem initializing MicAdapter: %s",
MicGetErrorString(ret));
- error=1;
+ error = 1;
}
if (error == 0 && show_memory)
if (ret != MIC_ACCESS_API_SUCCESS) {
ERROR("mic plugin: Problem closing MicAdapter: %s",
MicGetErrorString(ret));
- error=2;
+ error = 2;
break;
}
}
if (num_mics==0)
- error=3;
+ error = 3;
return error;
}
**/
#include "collectd.h"
+
#include "common.h"
#include "plugin.h"
-#include "configfile.h"
#include <netdb.h>
static mb_data_t *data_get_by_name (mb_data_t *src, /* {{{ */
const char *name)
{
- mb_data_t *ptr;
-
if (name == NULL)
return (NULL);
- for (ptr = src; ptr != NULL; ptr = ptr->next)
+ for (mb_data_t *ptr = src; ptr != NULL; ptr = ptr->next)
if (strcasecmp (ptr->name, name) == 0)
return (ptr);
static int mb_read_data (mb_host_t *host, mb_slave_t *slave, /* {{{ */
mb_data_t *data)
{
- uint16_t values[2];
+ uint16_t values[2] = { 0 };
int values_num;
const data_set_t *ds;
int status = 0;
"is not UINT32.", data->type, DS_TYPE_TO_STRING (ds->ds[0].type));
}
- memset (values, 0, sizeof (values));
if ((data->register_type == REG_TYPE_INT32)
|| (data->register_type == REG_TYPE_UINT32)
|| (data->register_type == REG_TYPE_FLOAT))
}
else if (host->conntype == MBCONN_TCP)
{
- struct sockaddr sockaddr;
- socklen_t saddrlen = sizeof (sockaddr);
-
+ /* getpeername() is used only to determine if the socket is connected, not
+ * because we're really interested in the peer's IP address. */
status = getpeername (modbus_get_socket (host->connection),
- &sockaddr, &saddrlen);
+ (struct sockaddr *) &(struct sockaddr_storage) { 0 },
+ &(socklen_t) { sizeof (struct sockaddr_storage) });
if (status != 0)
status = errno;
}
static int mb_read_slave (mb_host_t *host, mb_slave_t *slave) /* {{{ */
{
- mb_data_t *data;
int success;
int status;
return (EINVAL);
success = 0;
- for (data = slave->collect; data != NULL; data = data->next)
+ for (mb_data_t *data = slave->collect; data != NULL; data = data->next)
{
status = mb_read_data (host, slave, data);
if (status == 0)
static int mb_read (user_data_t *user_data) /* {{{ */
{
mb_host_t *host;
- size_t i;
int success;
int status;
host = user_data->data;
success = 0;
- for (i = 0; i < host->slaves_num; i++)
+ for (size_t i = 0; i < host->slaves_num; i++)
{
status = mb_read_slave (host, host->slaves + i);
if (status == 0)
static void slaves_free_all (mb_slave_t *slaves, size_t slaves_num) /* {{{ */
{
- size_t i;
-
if (slaves == NULL)
return;
- for (i = 0; i < slaves_num; i++)
+ for (size_t i = 0; i < slaves_num; i++)
data_free_all (slaves[i].collect);
sfree (slaves);
} /* }}} void slaves_free_all */
static int mb_config_add_data (oconfig_item_t *ci) /* {{{ */
{
- mb_data_t data;
+ mb_data_t data = { 0 };
int status;
- int i;
- memset (&data, 0, sizeof (data));
data.name = NULL;
data.register_type = REG_TYPE_UINT16;
data.next = NULL;
if (status != 0)
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;
const char *address)
{
struct addrinfo *ai_list;
- struct addrinfo *ai_ptr;
- struct addrinfo ai_hints;
int status;
if ((host == NULL) || (address == NULL))
return (EINVAL);
- memset (&ai_hints, 0, sizeof (ai_hints));
-#if AI_ADDRCONFIG
- ai_hints.ai_flags |= AI_ADDRCONFIG;
-#endif
- /* XXX: libmodbus can only handle IPv4 addresses. */
- ai_hints.ai_family = AF_INET;
- ai_hints.ai_addr = NULL;
- ai_hints.ai_canonname = NULL;
- ai_hints.ai_next = NULL;
+ struct addrinfo ai_hints = {
+ /* XXX: libmodbus can only handle IPv4 addresses. */
+ .ai_family = AF_INET,
+ .ai_flags = AI_ADDRCONFIG
+ };
- ai_list = NULL;
status = getaddrinfo (address, /* service = */ NULL,
&ai_hints, &ai_list);
if (status != 0)
return (status);
}
- for (ai_ptr = ai_list; ai_ptr != NULL; ai_ptr = ai_ptr->ai_next)
+ for (struct addrinfo *ai_ptr = ai_list; ai_ptr != NULL; ai_ptr = ai_ptr->ai_next)
{
status = getnameinfo (ai_ptr->ai_addr, ai_ptr->ai_addrlen,
host->node, sizeof (host->node),
{
mb_slave_t *slave;
int status;
- int i;
if ((host == NULL) || (ci == NULL))
return (EINVAL);
if (status != 0)
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;
{
mb_host_t *host;
int status;
- int i;
host = calloc (1, sizeof (*host));
if (host == NULL)
return (EINVAL);
}
- for (i = 0; i < ci->children_num; i++)
+ for (int i = 0; i < ci->children_num; i++)
{
oconfig_item_t *child = ci->children + i;
status = 0;
if (status == 0)
{
- user_data_t ud;
char name[1024];
- ud.data = host;
- ud.free_func = host_free;
-
ssnprintf (name, sizeof (name), "modbus-%s", host->host);
plugin_register_complex_read (/* group = */ NULL, name,
/* callback = */ mb_read,
/* interval = */ host->interval,
- &ud);
+ &(user_data_t) {
+ .data = host,
+ .free_func = host_free,
+ });
}
else
{
static int mb_config (oconfig_item_t *ci) /* {{{ */
{
- int i;
-
if (ci == NULL)
return (EINVAL);
- for (i = 0; i < ci->children_num; i++)
+ for (int i = 0; i < ci->children_num; i++)
{
oconfig_item_t *child = ci->children + i;
#include "collectd.h"
+
#include "common.h"
#include "plugin.h"
#include "utils_complain.h"
static char *strip_prefix (char *topic)
{
- size_t num;
- size_t i;
+ size_t num = 0;
- num = 0;
- for (i = 0; topic[i] != 0; i++)
+ for (size_t i = 0; topic[i] != 0; i++)
if (topic[i] == '/')
num++;
{
mqtt_client_conf_t *conf;
char cb_name[1024];
- user_data_t user_data;
int status;
- int i;
conf = calloc (1, sizeof (*conf));
if (conf == NULL)
C_COMPLAIN_INIT (&conf->complaint_cantpublish);
- 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 ("Host", child->key) == 0)
}
ssnprintf (cb_name, sizeof (cb_name), "mqtt/%s", conf->name);
- memset (&user_data, 0, sizeof (user_data));
- user_data.data = conf;
-
- plugin_register_write (cb_name, mqtt_write, &user_data);
+ plugin_register_write (cb_name, mqtt_write, &(user_data_t) {
+ .data = conf,
+ });
return (0);
} /* mqtt_config_publisher */
mqtt_client_conf_t **tmp;
mqtt_client_conf_t *conf;
int status;
- int i;
conf = calloc (1, sizeof (*conf));
if (conf == NULL)
C_COMPLAIN_INIT (&conf->complaint_cantpublish);
- 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 ("Host", child->key) == 0)
*/
static int mqtt_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;
static int mqtt_init (void)
{
- size_t i;
-
mosquitto_lib_init ();
- for (i = 0; i < subscribers_num; i++)
+ for (size_t i = 0; i < subscribers_num; i++)
{
int status;
**/
#include "collectd.h"
+
#include "common.h"
#include "plugin.h"
static int multimeter_init (void)
{
- int i;
char device[] = "/dev/ttyS ";
- for (i = 0; i < 10; i++)
+ for (int i = 0; i < 10; i++)
{
device[strlen(device)-1] = i + '0';
if ((fd = open(device, O_RDWR | O_NOCTTY)) != -1)
{
- struct termios tios;
+ struct termios tios = { 0 };
int rts = TIOCM_RTS;
double value;
- memset (&tios, 0, sizeof (tios));
tios.c_cflag = B1200 | CS7 | CSTOPB | CREAD | CLOCAL;
tios.c_iflag = IGNBRK | IGNPAR;
tios.c_oflag = 0;
static void multimeter_submit (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, "multimeter", sizeof (vl.plugin));
**/
#include "collectd.h"
+
#include "common.h"
#include "plugin.h"
-#include "configfile.h"
#ifdef HAVE_MYSQL_H
#include <mysql.h>
char *user;
char *pass;
char *database;
+
+ /* mysql_ssl_set params */
+ char *key;
+ char *cert;
+ char *ca;
+ char *capath;
+ char *cipher;
+
char *socket;
int port;
int timeout;
_Bool master_stats;
_Bool slave_stats;
_Bool innodb_stats;
+ _Bool wsrep_stats;
_Bool slave_notif;
_Bool slave_io_running;
sfree (db->socket);
sfree (db->instance);
sfree (db->database);
+ sfree (db->key);
+ sfree (db->cert);
+ sfree (db->ca);
+ sfree (db->capath);
+ sfree (db->cipher);
sfree (db);
} /* }}} void mysql_database_free */
{
mysql_database_t *db;
int status = 0;
- int i;
if ((ci->values_num != 1)
|| (ci->values[0].type != OCONFIG_TYPE_STRING))
db->user = NULL;
db->pass = NULL;
db->database = NULL;
+ db->key = NULL;
+ db->cert = NULL;
+ db->ca = NULL;
+ db->capath = NULL;
+ db->cipher = NULL;
+
db->socket = NULL;
db->con = NULL;
db->timeout = 0;
assert (db->instance != NULL);
/* Fill the `mysql_database_t' structure.. */
- for (i = 0; i < ci->children_num; i++)
+ for (int i = 0; i < ci->children_num; i++)
{
oconfig_item_t *child = ci->children + i;
status = cf_util_get_string (child, &db->socket);
else if (strcasecmp ("Database", child->key) == 0)
status = cf_util_get_string (child, &db->database);
+ else if (strcasecmp ("SSLKey", child->key) == 0)
+ status = cf_util_get_string (child, &db->key);
+ else if (strcasecmp ("SSLCert", child->key) == 0)
+ status = cf_util_get_string (child, &db->cert);
+ else if (strcasecmp ("SSLCA", child->key) == 0)
+ status = cf_util_get_string (child, &db->ca);
+ else if (strcasecmp ("SSLCAPath", child->key) == 0)
+ status = cf_util_get_string (child, &db->capath);
+ else if (strcasecmp ("SSLCipher", child->key) == 0)
+ status = cf_util_get_string (child, &db->cipher);
else if (strcasecmp ("ConnectTimeout", child->key) == 0)
status = cf_util_get_int (child, &db->timeout);
else if (strcasecmp ("MasterStats", child->key) == 0)
status = cf_util_get_boolean (child, &db->slave_notif);
else if (strcasecmp ("InnodbStats", child->key) == 0)
status = cf_util_get_boolean (child, &db->innodb_stats);
+ else if (strcasecmp ("WsrepStats", child->key) == 0)
+ status = cf_util_get_boolean (child, &db->wsrep_stats);
else
{
WARNING ("mysql plugin: Option `%s' not allowed here.", child->key);
/* If all went well, register this database for reading */
if (status == 0)
{
- user_data_t ud;
char cb_name[DATA_MAX_NAME_LEN];
DEBUG ("mysql plugin: Registering new read callback: %s",
(db->database != NULL) ? db->database : "<default>");
- memset (&ud, 0, sizeof (ud));
- ud.data = (void *) db;
- ud.free_func = mysql_database_free;
-
if (db->instance != NULL)
ssnprintf (cb_name, sizeof (cb_name), "mysql-%s",
db->instance);
sstrncpy (cb_name, "mysql", sizeof (cb_name));
plugin_register_complex_read (/* group = */ NULL, cb_name,
- mysql_read,
- /* interval = */ 0, &ud);
+ mysql_read, /* interval = */ 0, &(user_data_t) {
+ .data = db,
+ .free_func = mysql_database_free,
+ });
}
else
{
static int mysql_config (oconfig_item_t *ci) /* {{{ */
{
- int i;
-
if (ci == NULL)
return (EINVAL);
/* Fill the `mysql_database_t' structure.. */
- for (i = 0; i < ci->children_num; i++)
+ for (int i = 0; i < ci->children_num; i++)
{
oconfig_item_t *child = ci->children + i;
static MYSQL *getconnection (mysql_database_t *db)
{
+ const char *cipher;
+
if (db->is_connected)
{
int status;
/* Configure TCP connect timeout (default: 0) */
db->con->options.connect_timeout = db->timeout;
+ mysql_ssl_set (db->con, db->key, db->cert, db->ca, db->capath, db->cipher);
+
if (mysql_real_connect (db->con, db->host, db->user, db->pass,
db->database, db->port, db->socket, 0) == NULL)
{
return (NULL);
}
+ cipher = mysql_get_ssl_cipher (db->con);
+
INFO ("mysql plugin: Successfully connected to database %s "
- "at server %s (server version: %s, protocol version: %d)",
+ "at server %s with cipher %s "
+ "(server version: %s, protocol version: %d) ",
(db->database != NULL) ? db->database : "<none>",
mysql_get_host_info (db->con),
+ (cipher != NULL) ? cipher : "<none>",
mysql_get_server_info (db->con),
mysql_get_proto_info (db->con));
plugin_dispatch_values (&vl);
} /* submit */
-static void counter_submit (const char *type, const char *type_instance,
- derive_t value, mysql_database_t *db)
-{
- value_t values[1];
-
- values[0].derive = value;
- submit (type, type_instance, values, STATIC_ARRAY_SIZE (values), db);
-} /* void counter_submit */
-
static void gauge_submit (const char *type, const char *type_instance,
gauge_t value, mysql_database_t *db)
{
- value_t values[1];
-
- values[0].gauge = value;
- submit (type, type_instance, values, STATIC_ARRAY_SIZE (values), db);
+ submit (type, type_instance, &(value_t) { .gauge = value }, 1, db);
} /* void gauge_submit */
static void derive_submit (const char *type, const char *type_instance,
derive_t value, mysql_database_t *db)
{
- value_t values[1];
-
- values[0].derive = value;
- submit (type, type_instance, values, STATIC_ARRAY_SIZE (values), db);
+ submit (type, type_instance, &(value_t) { .derive = value }, 1, db);
} /* void derive_submit */
static void traffic_submit (derive_t rx, derive_t tx, mysql_database_t *db)
{
- value_t values[2];
-
- values[0].derive = rx;
- values[1].derive = tx;
+ value_t values[] = {
+ { .derive = rx },
+ { .derive = tx },
+ };
submit ("mysql_octets", NULL, values, STATIC_ARRAY_SIZE (values), db);
} /* void traffic_submit */
}
position = atoll (row[1]);
- counter_submit ("mysql_log_position", "master-bin", position, db);
+ derive_submit ("mysql_log_position", "master-bin", position, db);
row = mysql_fetch_row (res);
if (row != NULL)
double gauge;
counter = atoll (row[READ_MASTER_LOG_POS_IDX]);
- counter_submit ("mysql_log_position", "slave-read", counter, db);
+ derive_submit ("mysql_log_position", "slave-read", counter, db);
counter = atoll (row[EXEC_MASTER_LOG_POS_IDX]);
- counter_submit ("mysql_log_position", "slave-exec", counter, db);
+ derive_submit ("mysql_log_position", "slave-exec", counter, db);
if (row[SECONDS_BEHIND_MASTER_IDX] != NULL)
{
{ "lock_row_lock_current_waits", "mysql_locks", DS_TYPE_DERIVE },
{ "buffer_pool_size", "bytes", DS_TYPE_GAUGE },
- { "buffer_pool_reads", "operations", DS_TYPE_DERIVE },
- { "buffer_pool_read_requests", "operations", DS_TYPE_DERIVE },
- { "buffer_pool_write_requests", "operations", DS_TYPE_DERIVE },
- { "buffer_pool_wait_free", "operations", DS_TYPE_DERIVE },
- { "buffer_pool_read_ahead", "operations", DS_TYPE_DERIVE },
- { "buffer_pool_read_ahead_evicted", "operations", DS_TYPE_DERIVE },
-
- { "buffer_pool_pages_total", "gauge", DS_TYPE_GAUGE },
- { "buffer_pool_pages_misc", "gauge", DS_TYPE_GAUGE },
- { "buffer_pool_pages_data", "gauge", DS_TYPE_GAUGE },
- { "buffer_pool_bytes_data", "gauge", DS_TYPE_GAUGE },
- { "buffer_pool_pages_dirty", "gauge", DS_TYPE_GAUGE },
- { "buffer_pool_bytes_dirty", "gauge", DS_TYPE_GAUGE },
- { "buffer_pool_pages_free", "gauge", DS_TYPE_GAUGE },
-
- { "buffer_pages_created", "operations", DS_TYPE_DERIVE },
- { "buffer_pages_written", "operations", DS_TYPE_DERIVE },
- { "buffer_pages_read", "operations", DS_TYPE_DERIVE },
- { "buffer_data_reads", "operations", DS_TYPE_DERIVE },
- { "buffer_data_written", "operations", DS_TYPE_DERIVE },
-
- { "os_data_reads", "operations", DS_TYPE_DERIVE },
- { "os_data_writes", "operations", DS_TYPE_DERIVE },
- { "os_data_fsyncs", "operations", DS_TYPE_DERIVE },
{ "os_log_bytes_written", "operations", DS_TYPE_DERIVE },
- { "os_log_fsyncs", "operations", DS_TYPE_DERIVE },
{ "os_log_pending_fsyncs", "operations", DS_TYPE_DERIVE },
{ "os_log_pending_writes", "operations", DS_TYPE_DERIVE },
{ "trx_rseg_history_len", "gauge", DS_TYPE_GAUGE },
- { "log_waits", "operations", DS_TYPE_DERIVE },
- { "log_write_requests", "operations", DS_TYPE_DERIVE },
- { "log_writes", "operations", DS_TYPE_DERIVE },
{ "adaptive_hash_searches", "operations", DS_TYPE_DERIVE },
{ "file_num_open_files", "gauge", DS_TYPE_GAUGE },
{ "ibuf_size", "bytes", DS_TYPE_GAUGE },
{ "innodb_activity_count", "gauge", DS_TYPE_GAUGE },
- { "innodb_dblwr_writes", "operations", DS_TYPE_DERIVE },
- { "innodb_dblwr_pages_written", "operations", DS_TYPE_DERIVE },
- { "innodb_dblwr_page_size", "gauge", DS_TYPE_GAUGE },
{ "innodb_rwlock_s_spin_waits", "operations", DS_TYPE_DERIVE },
{ "innodb_rwlock_x_spin_waits", "operations", DS_TYPE_DERIVE },
switch (metrics[i].ds_type) {
case DS_TYPE_COUNTER:
- counter_submit(metrics[i].type, key, (counter_t)val, db);
+ derive_submit(metrics[i].type, key, (counter_t)val, db);
break;
case DS_TYPE_GAUGE:
gauge_submit(metrics[i].type, key, (gauge_t)val, db);
return (0);
}
+static int mysql_read_wsrep_stats (mysql_database_t *db, MYSQL *con)
+{
+ MYSQL_RES *res;
+ MYSQL_ROW row;
+
+ const char *query;
+ struct {
+ const char *key;
+ const char *type;
+ int ds_type;
+ } metrics[] = {
+
+ { "wsrep_apply_oooe", "operations", DS_TYPE_DERIVE },
+ { "wsrep_apply_oool", "operations", DS_TYPE_DERIVE },
+ { "wsrep_causal_reads", "operations", DS_TYPE_DERIVE },
+ { "wsrep_commit_oooe", "operations", DS_TYPE_DERIVE },
+ { "wsrep_commit_oool", "operations", DS_TYPE_DERIVE },
+ { "wsrep_flow_control_recv", "operations", DS_TYPE_DERIVE },
+ { "wsrep_flow_control_sent", "operations", DS_TYPE_DERIVE },
+ { "wsrep_flow_control_paused", "operations", DS_TYPE_DERIVE },
+ { "wsrep_local_bf_aborts", "operations", DS_TYPE_DERIVE },
+ { "wsrep_local_cert_failures", "operations", DS_TYPE_DERIVE },
+ { "wsrep_local_commits", "operations", DS_TYPE_DERIVE },
+ { "wsrep_local_replays", "operations", DS_TYPE_DERIVE },
+ { "wsrep_received", "operations", DS_TYPE_DERIVE },
+ { "wsrep_replicated", "operations", DS_TYPE_DERIVE },
+
+ { "wsrep_received_bytes", "total_bytes", DS_TYPE_DERIVE },
+ { "wsrep_replicated_bytes", "total_bytes", DS_TYPE_DERIVE },
+
+ { "wsrep_apply_window", "gauge", DS_TYPE_GAUGE },
+ { "wsrep_commit_window", "gauge", DS_TYPE_GAUGE },
+
+ { "wsrep_cluster_size", "gauge", DS_TYPE_GAUGE },
+ { "wsrep_cert_deps_distance", "gauge", DS_TYPE_GAUGE },
+
+ { "wsrep_local_recv_queue", "queue_length", DS_TYPE_GAUGE },
+ { "wsrep_local_send_queue", "queue_length", DS_TYPE_GAUGE },
+
+ { NULL, NULL, 0}
+
+ };
+
+ query = "SHOW GLOBAL STATUS LIKE 'wsrep_%'";
+
+ res = exec_query (con, query);
+ if (res == NULL)
+ return (-1);
+
+ row = mysql_fetch_row (res);
+ if (row == NULL)
+ {
+ ERROR ("mysql plugin: Failed to get wsrep statistics: "
+ "`%s' did not return any rows.", query);
+ mysql_free_result (res);
+ return (-1);
+ }
+
+ while ((row = mysql_fetch_row (res)))
+ {
+ int i;
+ char *key;
+ unsigned long long val;
+
+ key = row[0];
+ val = atoll (row[1]);
+
+ for (i = 0; metrics[i].key != NULL && strcmp(metrics[i].key, key) != 0; i++)
+ ;
+
+ if (metrics[i].key == NULL)
+ continue;
+
+ switch (metrics[i].ds_type) {
+ case DS_TYPE_GAUGE:
+ gauge_submit(metrics[i].type, key, (gauge_t)val, db);
+ break;
+ case DS_TYPE_DERIVE:
+ derive_submit(metrics[i].type, key, (derive_t)val, db);
+ break;
+ }
+ }
+
+ mysql_free_result(res);
+ return (0);
+} /* mysql_read_wsrep_stats */
+
static int mysql_read (user_data_t *ud)
{
mysql_database_t *db;
/* Ignore `prepared statements' */
if (strncmp (key, "Com_stmt_", strlen ("Com_stmt_")) != 0)
- counter_submit ("mysql_commands",
+ derive_submit ("mysql_commands",
key + strlen ("Com_"),
val, db);
}
if (val == 0ULL)
continue;
- counter_submit ("mysql_handler",
+ derive_submit ("mysql_handler",
key + strlen ("Handler_"),
val, db);
}
else if (strncmp (key, "Table_locks_",
strlen ("Table_locks_")) == 0)
{
- counter_submit ("mysql_locks",
+ derive_submit ("mysql_locks",
key + strlen ("Table_locks_"),
val, db);
}
else if (strcmp (key, "Innodb_buffer_pool_pages_dirty") == 0)
gauge_submit ("mysql_bpool_pages", "dirty", val, db);
else if (strcmp (key, "Innodb_buffer_pool_pages_flushed") == 0)
- counter_submit ("mysql_bpool_counters", "pages_flushed", val, db);
+ derive_submit ("mysql_bpool_counters", "pages_flushed", val, db);
else if (strcmp (key, "Innodb_buffer_pool_pages_free") == 0)
gauge_submit ("mysql_bpool_pages", "free", val, db);
else if (strcmp (key, "Innodb_buffer_pool_pages_misc") == 0)
else if (strcmp (key, "Innodb_buffer_pool_pages_total") == 0)
gauge_submit ("mysql_bpool_pages", "total", val, db);
else if (strcmp (key, "Innodb_buffer_pool_read_ahead_rnd") == 0)
- counter_submit ("mysql_bpool_counters", "read_ahead_rnd", val, db);
+ derive_submit ("mysql_bpool_counters", "read_ahead_rnd", val, db);
else if (strcmp (key, "Innodb_buffer_pool_read_ahead") == 0)
- counter_submit ("mysql_bpool_counters", "read_ahead", val, db);
+ derive_submit ("mysql_bpool_counters", "read_ahead", val, db);
else if (strcmp (key, "Innodb_buffer_pool_read_ahead_evicted") == 0)
- counter_submit ("mysql_bpool_counters", "read_ahead_evicted", val, db);
+ derive_submit ("mysql_bpool_counters", "read_ahead_evicted", val, db);
else if (strcmp (key, "Innodb_buffer_pool_read_requests") == 0)
- counter_submit ("mysql_bpool_counters", "read_requests", val, db);
+ derive_submit ("mysql_bpool_counters", "read_requests", val, db);
else if (strcmp (key, "Innodb_buffer_pool_reads") == 0)
- counter_submit ("mysql_bpool_counters", "reads", val, db);
+ derive_submit ("mysql_bpool_counters", "reads", val, db);
+ else if (strcmp (key, "Innodb_buffer_pool_wait_free") == 0)
+ derive_submit ("mysql_bpool_counters", "wait_free", val, db);
else if (strcmp (key, "Innodb_buffer_pool_write_requests") == 0)
- counter_submit ("mysql_bpool_counters", "write_requests", val, db);
+ derive_submit ("mysql_bpool_counters", "write_requests", val, db);
else if (strcmp (key, "Innodb_buffer_pool_bytes_data") == 0)
gauge_submit ("mysql_bpool_bytes", "data", val, db);
else if (strcmp (key, "Innodb_buffer_pool_bytes_dirty") == 0)
/* data */
if (strcmp (key, "Innodb_data_fsyncs") == 0)
- counter_submit ("mysql_innodb_data", "fsyncs", val, db);
+ derive_submit ("mysql_innodb_data", "fsyncs", val, db);
else if (strcmp (key, "Innodb_data_read") == 0)
- counter_submit ("mysql_innodb_data", "read", val, db);
+ derive_submit ("mysql_innodb_data", "read", val, db);
else if (strcmp (key, "Innodb_data_reads") == 0)
- counter_submit ("mysql_innodb_data", "reads", val, db);
+ derive_submit ("mysql_innodb_data", "reads", val, db);
else if (strcmp (key, "Innodb_data_writes") == 0)
- counter_submit ("mysql_innodb_data", "writes", val, db);
+ derive_submit ("mysql_innodb_data", "writes", val, db);
else if (strcmp (key, "Innodb_data_written") == 0)
- counter_submit ("mysql_innodb_data", "written", val, db);
+ derive_submit ("mysql_innodb_data", "written", val, db);
/* double write */
else if (strcmp (key, "Innodb_dblwr_writes") == 0)
- counter_submit ("mysql_innodb_dblwr", "writes", val, db);
+ derive_submit ("mysql_innodb_dblwr", "writes", val, db);
else if (strcmp (key, "Innodb_dblwr_pages_written") == 0)
- counter_submit ("mysql_innodb_dblwr", "written", val, db);
+ derive_submit ("mysql_innodb_dblwr", "written", val, db);
+ else if (strcmp (key, "Innodb_dblwr_page_size") == 0)
+ gauge_submit ("mysql_innodb_dblwr", "page_size", val, db);
/* log */
else if (strcmp (key, "Innodb_log_waits") == 0)
- counter_submit ("mysql_innodb_log", "waits", val, db);
+ derive_submit ("mysql_innodb_log", "waits", val, db);
else if (strcmp (key, "Innodb_log_write_requests") == 0)
- counter_submit ("mysql_innodb_log", "write_requests", val, db);
+ derive_submit ("mysql_innodb_log", "write_requests", val, db);
else if (strcmp (key, "Innodb_log_writes") == 0)
- counter_submit ("mysql_innodb_log", "writes", val, db);
+ derive_submit ("mysql_innodb_log", "writes", val, db);
else if (strcmp (key, "Innodb_os_log_fsyncs") == 0)
- counter_submit ("mysql_innodb_log", "fsyncs", val, db);
+ derive_submit ("mysql_innodb_log", "fsyncs", val, db);
else if (strcmp (key, "Innodb_os_log_written") == 0)
- counter_submit ("mysql_innodb_log", "written", val, db);
+ derive_submit ("mysql_innodb_log", "written", val, db);
/* pages */
else if (strcmp (key, "Innodb_pages_created") == 0)
- counter_submit ("mysql_innodb_pages", "created", val, db);
+ derive_submit ("mysql_innodb_pages", "created", val, db);
else if (strcmp (key, "Innodb_pages_read") == 0)
- counter_submit ("mysql_innodb_pages", "read", val, db);
+ derive_submit ("mysql_innodb_pages", "read", val, db);
else if (strcmp (key, "Innodb_pages_written") == 0)
- counter_submit ("mysql_innodb_pages", "written", val, db);
+ derive_submit ("mysql_innodb_pages", "written", val, db);
/* row lock */
else if (strcmp (key, "Innodb_row_lock_time") == 0)
- counter_submit ("mysql_innodb_row_lock", "time", val, db);
+ derive_submit ("mysql_innodb_row_lock", "time", val, db);
else if (strcmp (key, "Innodb_row_lock_waits") == 0)
- counter_submit ("mysql_innodb_row_lock", "waits", val, db);
+ derive_submit ("mysql_innodb_row_lock", "waits", val, db);
/* rows */
else if (strcmp (key, "Innodb_rows_deleted") == 0)
- counter_submit ("mysql_innodb_rows", "deleted", val, db);
+ derive_submit ("mysql_innodb_rows", "deleted", val, db);
else if (strcmp (key, "Innodb_rows_inserted") == 0)
- counter_submit ("mysql_innodb_rows", "inserted", val, db);
+ derive_submit ("mysql_innodb_rows", "inserted", val, db);
else if (strcmp (key, "Innodb_rows_read") == 0)
- counter_submit ("mysql_innodb_rows", "read", val, db);
+ derive_submit ("mysql_innodb_rows", "read", val, db);
else if (strcmp (key, "Innodb_rows_updated") == 0)
- counter_submit ("mysql_innodb_rows", "updated", val, db);
+ derive_submit ("mysql_innodb_rows", "updated", val, db);
}
else if (strncmp (key, "Select_", strlen ("Select_")) == 0)
{
- counter_submit ("mysql_select", key + strlen ("Select_"),
+ derive_submit ("mysql_select", key + strlen ("Select_"),
val, db);
}
else if (strncmp (key, "Sort_", strlen ("Sort_")) == 0)
{
if (strcmp (key, "Sort_merge_passes") == 0)
- counter_submit ("mysql_sort_merge_passes", NULL, val, db);
+ derive_submit ("mysql_sort_merge_passes", NULL, val, db);
else if (strcmp (key, "Sort_rows") == 0)
- counter_submit ("mysql_sort_rows", NULL, val, db);
+ derive_submit ("mysql_sort_rows", NULL, val, db);
else if (strcmp (key, "Sort_range") == 0)
- counter_submit ("mysql_sort", "range", val, db);
+ derive_submit ("mysql_sort", "range", val, db);
else if (strcmp (key, "Sort_scan") == 0)
- counter_submit ("mysql_sort", "scan", val, db);
+ derive_submit ("mysql_sort", "scan", val, db);
}
- else if (strncmp (key, "Slow_queries", strlen ("Slow_queries")) == 0)
+ else if (strncmp (key, "Slow_queries", strlen ("Slow_queries")) == 0)
{
- counter_submit ("mysql_slow_queries", NULL , val, db);
+ derive_submit ("mysql_slow_queries", NULL , val, db);
}
}
mysql_free_result (res); res = NULL;
if ((db->slave_stats) || (db->slave_notif))
mysql_read_slave_stats (db, con);
+ if (db->wsrep_stats)
+ mysql_read_wsrep_stats (db, con);
+
return (0);
} /* int mysql_read */
**/
#include "collectd.h"
+
#include "common.h"
#include "utils_ignorelist.h"
static int submit_values (const char *host, /* {{{ */
const char *plugin_inst,
const char *type, const char *type_inst,
- value_t *values, int values_len,
+ value_t *values, size_t values_len,
cdtime_t timestamp, cdtime_t interval)
{
value_list_t vl = VALUE_LIST_INIT;
const char *type, const char *type_inst, derive_t val0, derive_t val1,
cdtime_t timestamp, cdtime_t interval)
{
- value_t values[2];
-
- values[0].derive = val0;
- values[1].derive = val1;
+ value_t values[] = {
+ { .derive = val0 },
+ { .derive = val1 },
+ };
return (submit_values (host, plugin_inst, type, type_inst,
- values, 2, timestamp, interval));
+ values, STATIC_ARRAY_SIZE (values), timestamp, interval));
} /* }}} int submit_two_derive */
static int submit_derive (const char *host, const char *plugin_inst, /* {{{ */
const char *type, const char *type_inst, derive_t counter,
cdtime_t timestamp, cdtime_t interval)
{
- value_t v;
-
- v.derive = counter;
-
return (submit_values (host, plugin_inst, type, type_inst,
- &v, 1, timestamp, interval));
+ &(value_t) { .derive = counter }, 1, timestamp, interval));
} /* }}} int submit_derive */
static int submit_two_gauge (const char *host, const char *plugin_inst, /* {{{ */
const char *type, const char *type_inst, gauge_t val0, gauge_t val1,
cdtime_t timestamp, cdtime_t interval)
{
- value_t values[2];
-
- values[0].gauge = val0;
- values[1].gauge = val1;
+ value_t values[] = {
+ { .gauge = val0 },
+ { .gauge = val1 },
+ };
return (submit_values (host, plugin_inst, type, type_inst,
- values, 2, timestamp, interval));
+ values, STATIC_ARRAY_SIZE (values), timestamp, interval));
} /* }}} int submit_two_gauge */
static int submit_double (const char *host, const char *plugin_inst, /* {{{ */
const char *type, const char *type_inst, double d,
cdtime_t timestamp, cdtime_t interval)
{
- value_t v;
-
- v.gauge = (gauge_t) d;
-
return (submit_values (host, plugin_inst, type, type_inst,
- &v, 1, timestamp, interval));
+ &(value_t) { .gauge = counter }, 1, timestamp, interval));
} /* }}} int submit_uint64 */
/* Calculate hit ratio from old and new counters and submit the resulting
cdtime_t timestamp,
cdtime_t interval)
{
- value_t v;
+ value_t v = { .gauge = NAN };
if ((new_hits >= old_hits) && (new_misses >= old_misses)) {
uint64_t hits;
misses = new_misses - old_misses;
v.gauge = 100.0 * ((gauge_t) hits) / ((gauge_t) (hits + misses));
- } else {
- v.gauge = NAN;
}
return (submit_values (host, plugin_inst, "cache_ratio", type_inst,
static int cna_handle_wafl_data (const char *hostname, cfg_wafl_t *cfg_wafl, /* {{{ */
na_elem_t *data, cdtime_t interval)
{
- cfg_wafl_t perf_data;
+ cfg_wafl_t perf_data = { 0 };
const char *plugin_inst;
na_elem_t *instances;
- na_elem_t *counter;
na_elem_iter_t counter_iter;
- memset (&perf_data, 0, sizeof (perf_data));
-
perf_data.timestamp = cna_child_get_cdtime (data);
instances = na_elem_child(na_elem_child (data, "instances"), "instance-data");
/* Iterate over all counters */
counter_iter = na_child_iterator (na_elem_child (instances, "counters"));
- for (counter = na_iterator_next (&counter_iter);
+ for (na_elem_t *counter = na_iterator_next (&counter_iter);
counter != NULL;
counter = na_iterator_next (&counter_iter))
{
{
cdtime_t timestamp;
na_elem_t *instances;
- na_elem_t *instance;
na_elem_iter_t instance_iter;
disk_t *worst_disk = NULL;
/* Iterate over all children */
instance_iter = na_child_iterator (instances);
- for (instance = na_iterator_next (&instance_iter);
+ for (na_elem_t *instance = na_iterator_next (&instance_iter);
instance != NULL;
instance = na_iterator_next(&instance_iter))
{
disk_t *old_data;
- disk_t new_data;
+ disk_t new_data = { 0 };
na_elem_iter_t counter_iterator;
- na_elem_t *counter;
- memset (&new_data, 0, sizeof (new_data));
new_data.timestamp = timestamp;
new_data.disk_busy_percent = NAN;
/* Look for the "disk_busy" and "base_for_disk_busy" counters */
counter_iterator = na_child_iterator(na_elem_child(instance, "counters"));
- for (counter = na_iterator_next(&counter_iterator);
+ for (na_elem_t *counter = na_iterator_next(&counter_iterator);
counter != NULL;
counter = na_iterator_next(&counter_iterator))
{
cdtime_t timestamp;
na_elem_t *elem_instances;
na_elem_iter_t iter_instances;
- na_elem_t *elem_instance;
timestamp = cna_child_get_cdtime (data);
}
iter_instances = na_child_iterator (elem_instances);
- for (elem_instance = na_iterator_next(&iter_instances);
+ for (na_elem_t *elem_instance = na_iterator_next(&iter_instances);
elem_instance != NULL;
elem_instance = na_iterator_next(&iter_instances))
{
const char *name;
- data_volume_perf_t perf_data;
+ data_volume_perf_t perf_data = { 0 };
data_volume_perf_t *v;
na_elem_t *elem_counters;
na_elem_iter_t iter_counters;
- na_elem_t *elem_counter;
- memset (&perf_data, 0, sizeof (perf_data));
perf_data.timestamp = timestamp;
name = na_child_get_string (elem_instance, "name");
continue;
iter_counters = na_child_iterator (elem_counters);
- for (elem_counter = na_iterator_next(&iter_counters);
+ for (na_elem_t *elem_counter = na_iterator_next(&iter_counters);
elem_counter != NULL;
elem_counter = na_iterator_next(&iter_counters))
{
static int cna_submit_volume_usage_data (const char *hostname, /* {{{ */
cfg_volume_usage_t *cfg_volume, int interval)
{
- data_volume_usage_t *v;
-
- for (v = cfg_volume->volumes; v != NULL; v = v->next)
+ for (data_volume_usage_t *v = cfg_volume->volumes; v != NULL; v = v->next)
{
char plugin_instance[DATA_MAX_NAME_LEN];
static int cna_change_volume_status (const char *hostname, /* {{{ */
data_volume_usage_t *v)
{
- notification_t n;
+ notification_t n = { 0 };
- memset (&n, 0, sizeof (n));
n.time = cdtime ();
sstrncpy (n.host, hostname, sizeof (n.host));
sstrncpy (n.plugin, "netapp", sizeof (n.plugin));
data_volume_usage_t *v)
{
uint64_t snap_used = 0, value;
- na_elem_t *data, *elem_snap, *elem_snapshots;
+ na_elem_t *data, *elem_snapshots;
na_elem_iter_t iter_snap;
data = na_server_invoke_elem(host->srv, v->snap_query);
}
iter_snap = na_child_iterator (elem_snapshots);
- for (elem_snap = na_iterator_next (&iter_snap);
+ for (na_elem_t *elem_snap = na_iterator_next (&iter_snap);
elem_snap != NULL;
elem_snap = na_iterator_next (&iter_snap))
{
static int cna_handle_volume_usage_data (const host_config_t *host, /* {{{ */
cfg_volume_usage_t *cfg_volume, na_elem_t *data)
{
- na_elem_t *elem_volume;
na_elem_t *elem_volumes;
na_elem_iter_t iter_volume;
}
iter_volume = na_child_iterator (elem_volumes);
- for (elem_volume = na_iterator_next (&iter_volume);
+ for (na_elem_t *elem_volume = na_iterator_next (&iter_volume);
elem_volume != NULL;
elem_volume = na_iterator_next (&iter_volume))
{
static int cna_handle_quota_data (const host_config_t *host, /* {{{ */
cfg_quota_t *cfg_quota, na_elem_t *data)
{
- na_elem_t *elem_quota;
na_elem_t *elem_quotas;
na_elem_iter_t iter_quota;
}
iter_quota = na_child_iterator (elem_quotas);
- for (elem_quota = na_iterator_next (&iter_quota);
+ for (na_elem_t *elem_quota = na_iterator_next (&iter_quota);
elem_quota != NULL;
elem_quota = na_iterator_next (&iter_quota))
{
static int cna_handle_snapvault_data (const char *hostname, /* {{{ */
cfg_snapvault_t *cfg_snapvault, na_elem_t *data, cdtime_t interval)
{
- na_elem_t *status;
na_elem_iter_t status_iter;
status = na_elem_child (data, "status-list");
}
status_iter = na_child_iterator (status);
- for (status = na_iterator_next (&status_iter);
+ for (na_elem_t *status = na_iterator_next (&status_iter);
status != NULL;
status = na_iterator_next (&status_iter))
{
const char *tag;
uint32_t records_count;
- uint32_t i;
records_count = na_child_get_uint32 (data, "records", UINT32_MAX);
if (records_count == UINT32_MAX)
DEBUG ("netapp plugin: Iterating %u SV records (tag = %s)", records_count, tag);
- for (i = 0; i < records_count; ++i) {
+ for (uint32_t i = 0; i < records_count; ++i) {
na_elem_t *elem;
elem = na_server_invoke (host->srv,
cfg_system_t *cfg_system, na_elem_t *data, int interval)
{
na_elem_t *instances;
- na_elem_t *counter;
na_elem_iter_t counter_iter;
derive_t disk_read = 0, disk_written = 0;
}
counter_iter = na_child_iterator (na_elem_child (instances, "counters"));
- for (counter = na_iterator_next (&counter_iter);
+ for (na_elem_t *counter = na_iterator_next (&counter_iter);
counter != NULL;
counter = na_iterator_next (&counter_iter))
{
const oconfig_item_t *ci)
{
cfg_volume_perf_t *cfg_volume_perf;
- int i;
if ((host == NULL) || (ci == NULL))
return (EINVAL);
}
cfg_volume_perf = host->cfg_volume_perf;
- for (i = 0; i < ci->children_num; ++i) {
+ for (int i = 0; i < ci->children_num; ++i) {
oconfig_item_t *item = ci->children + i;
/* if (!item || !item->key || !*item->key) continue; */
static int cna_config_quota (host_config_t *host, oconfig_item_t *ci) /* {{{ */
{
cfg_quota_t *cfg_quota;
- int i;
if ((host == NULL) || (ci == NULL))
return (EINVAL);
}
cfg_quota = host->cfg_quota;
- for (i = 0; i < ci->children_num; ++i) {
+ for (int i = 0; i < ci->children_num; ++i) {
oconfig_item_t *item = ci->children + i;
if (strcasecmp (item->key, "Interval") == 0)
/* Corresponds to a <Disks /> block */
static int cna_config_disk(host_config_t *host, oconfig_item_t *ci) { /* {{{ */
cfg_disk_t *cfg_disk;
- int i;
if ((host == NULL) || (ci == NULL))
return (EINVAL);
}
cfg_disk = host->cfg_disk;
- for (i = 0; i < ci->children_num; ++i) {
+ for (int i = 0; i < ci->children_num; ++i) {
oconfig_item_t *item = ci->children + i;
/* if (!item || !item->key || !*item->key) continue; */
static int cna_config_wafl(host_config_t *host, oconfig_item_t *ci) /* {{{ */
{
cfg_wafl_t *cfg_wafl;
- int i;
if ((host == NULL) || (ci == NULL))
return (EINVAL);
}
cfg_wafl = host->cfg_wafl;
- for (i = 0; i < ci->children_num; ++i) {
+ for (int i = 0; i < ci->children_num; ++i) {
oconfig_item_t *item = ci->children + i;
if (strcasecmp(item->key, "Interval") == 0)
const oconfig_item_t *ci)
{
cfg_volume_usage_t *cfg_volume_usage;
- int i;
if ((host == NULL) || (ci == NULL))
return (EINVAL);
}
cfg_volume_usage = host->cfg_volume_usage;
- for (i = 0; i < ci->children_num; ++i) {
+ for (int i = 0; i < ci->children_num; ++i) {
oconfig_item_t *item = ci->children + i;
/* if (!item || !item->key || !*item->key) continue; */
const oconfig_item_t *ci)
{
cfg_snapvault_t *cfg_snapvault;
- int i;
if ((host == NULL) || (ci == NULL))
return EINVAL;
cfg_snapvault = host->cfg_snapvault;
- for (i = 0; i < ci->children_num; ++i) {
+ for (int i = 0; i < ci->children_num; ++i) {
oconfig_item_t *item = ci->children + i;
if (strcasecmp (item->key, "Interval") == 0)
oconfig_item_t *ci)
{
cfg_system_t *cfg_system;
- int i;
if ((host == NULL) || (ci == NULL))
return (EINVAL);
}
cfg_system = host->cfg_system;
- for (i = 0; i < ci->children_num; ++i) {
+ for (int i = 0; i < ci->children_num; ++i) {
oconfig_item_t *item = ci->children + i;
if (strcasecmp(item->key, "Interval") == 0) {
static int cna_register_host (host_config_t *host) /* {{{ */
{
char cb_name[256];
- user_data_t ud;
if (host->vfiler)
ssnprintf (cb_name, sizeof (cb_name), "netapp-%s-%s",
else
ssnprintf (cb_name, sizeof (cb_name), "netapp-%s", host->name);
- memset (&ud, 0, sizeof (ud));
- ud.data = host;
- ud.free_func = (void (*) (void *)) free_host_config;
-
plugin_register_complex_read (/* group = */ NULL, cb_name,
/* callback = */ cna_read,
/* interval = */ host->interval,
- /* user data = */ &ud);
+ &(user_data_t) {
+ .data = host,
+ .free_func = (void *) free_host_config,
+ });
return (0);
} /* }}} int cna_register_host */
oconfig_item_t *item;
_Bool is_vfiler = 0;
int status;
- int i;
if (! strcasecmp (ci->key, "VFiler"))
is_vfiler = 1;
if (status != 0)
return (1);
- for (i = 0; i < ci->children_num; ++i) {
+ for (int i = 0; i < ci->children_num; ++i) {
item = ci->children + i;
status = 0;
static int cna_init (void) /* {{{ */
{
- char err[256];
+ char err[256] = { 0 };
- memset (err, 0, sizeof (err));
if (!na_startup(err, sizeof(err))) {
err[sizeof (err) - 1] = 0;
ERROR("netapp plugin: Error initializing netapp API: %s", err);
} /* }}} int cna_read */
static int cna_config (oconfig_item_t *ci) { /* {{{ */
- int i;
oconfig_item_t *item;
- for (i = 0; i < ci->children_num; ++i) {
+ for (int i = 0; i < ci->children_num; ++i) {
item = ci->children + i;
if (strcasecmp(item->key, "Host") == 0)
**/
#include "collectd.h"
+
#include "plugin.h"
#include "common.h"
static int check_ignorelist (const char *dev,
const char *type, const char *type_instance)
{
- ir_ignorelist_t *i;
-
assert ((dev != NULL) && (type != NULL));
if (ir_ignorelist_head == NULL)
return (ir_ignorelist_invert ? 0 : 1);
- for (i = ir_ignorelist_head; i != NULL; i = i->next)
+ for (ir_ignorelist_t *i = ir_ignorelist_head; i != NULL; i = i->next)
{
/* i->device == NULL => match all devices */
if ((i->device != NULL)
static void submit_one (const char *dev, const char *type,
const char *type_instance, derive_t value)
{
- value_t values[1];
value_list_t vl = VALUE_LIST_INIT;
- values[0].derive = value;
-
- vl.values = values;
+ vl.values = &(value_t) { .derive = value };
vl.values_len = 1;
sstrncpy (vl.host, hostname_g, sizeof (vl.host));
sstrncpy (vl.plugin, "netlink", sizeof (vl.plugin));
const char *type_instance,
derive_t rx, derive_t tx)
{
- value_t values[2];
value_list_t vl = VALUE_LIST_INIT;
-
- values[0].derive = rx;
- values[1].derive = tx;
+ value_t values[] = {
+ { .derive = rx },
+ { .derive = tx },
+ };
vl.values = values;
- vl.values_len = 2;
+ vl.values_len = STATIC_ARRAY_SIZE (values);
sstrncpy (vl.host, hostname_g, sizeof (vl.host));
sstrncpy (vl.plugin, "netlink", sizeof (vl.plugin));
sstrncpy (vl.plugin_instance, dev, sizeof (vl.plugin_instance));
int ret;
unsigned int seq, portid;
- size_t ifindex;
-
static const int type_id[] = { RTM_GETQDISC, RTM_GETTCLASS, RTM_GETTFILTER };
static const char *type_name[] = { "qdisc", "class", "filter" };
/* `link_filter_cb' will update `iflist' which is used here to iterate
* over all interfaces. */
- for (ifindex = 1; ifindex < iflist_len; ifindex++)
+ for (size_t ifindex = 1; ifindex < iflist_len; ifindex++)
{
struct tcmsg *tm;
- size_t type_index;
if (iflist[ifindex] == NULL)
continue;
- for (type_index = 0; type_index < STATIC_ARRAY_SIZE (type_id); type_index++)
+ for (size_t type_index = 0; type_index < STATIC_ARRAY_SIZE (type_id); type_index++)
{
if (check_ignorelist (iflist[ifindex], type_name[type_index], NULL))
{
#define _BSD_SOURCE /* For struct ip_mreq */
#include "collectd.h"
+
#include "plugin.h"
#include "common.h"
-#include "configfile.h"
#include "utils_fbhash.h"
#include "utils_cache.h"
#include "utils_complain.h"
static _Bool check_notify_received (const notification_t *n) /* {{{ */
{
- notification_meta_t *ptr;
-
- for (ptr = n->meta; ptr != NULL; ptr = ptr->next)
+ for (notification_meta_t *ptr = n->meta; ptr != NULL; ptr = ptr->next)
if ((strcmp ("network:received", ptr->name) == 0)
&& (ptr->type == NM_TYPE_BOOLEAN))
return ((_Bool) ptr->nm_value.nm_boolean);
} /* }}} int network_dispatch_notification */
#if HAVE_LIBGCRYPT
-static void network_init_gcrypt (void) /* {{{ */
+static int network_init_gcrypt (void) /* {{{ */
{
gcry_error_t err;
* Because you can't know in a library whether another library has
* already initialized the library */
if (gcry_control (GCRYCTL_ANY_INITIALIZATION_P))
- return;
+ return (0);
/* http://www.gnupg.org/documentation/manuals/gcrypt/Multi_002dThreading.html
* To ensure thread-safety, it's important to set GCRYCTL_SET_THREAD_CBS
if (err)
{
ERROR ("network plugin: gcry_control (GCRYCTL_SET_THREAD_CBS) failed: %s", gcry_strerror (err));
- abort ();
+ return (-1);
}
# endif
if (err)
{
ERROR ("network plugin: gcry_control (GCRYCTL_INIT_SECMEM) failed: %s", gcry_strerror (err));
- abort ();
+ return (-1);
}
gcry_control (GCRYCTL_INITIALIZATION_FINISHED);
-} /* }}} void network_init_gcrypt */
+ return (0);
+} /* }}} int network_init_gcrypt */
static gcry_cipher_hd_t network_get_aes256_cypher (sockent_t *se, /* {{{ */
const void *iv, size_t iv_size, const char *username)
value_t *pkg_values;
size_t offset;
- int i;
num_values = vl->values_len;
packet_len = sizeof (part_header_t) + sizeof (uint16_t)
pkg_num_values = htons ((uint16_t) vl->values_len);
- for (i = 0; i < num_values; i++)
+ for (int i = 0; i < num_values; i++)
{
pkg_values_types[i] = (uint8_t) ds->ds[i].type;
switch (ds->ds[i].type)
uint16_t tmp16;
size_t exp_size;
- size_t i;
uint16_t pkg_length;
uint16_t pkg_type;
memcpy (pkg_values, buffer, pkg_numval * sizeof (*pkg_values));
buffer += pkg_numval * sizeof (*pkg_values);
- for (i = 0; i < pkg_numval; i++)
+ for (size_t i = 0; i < pkg_numval; i++)
{
switch (pkg_types[i])
{
if (memcmp (pss.hash, hash, sizeof (pss.hash)) != 0)
{
WARNING ("network plugin: Verifying HMAC-SHA-256 signature failed: "
- "Hash mismatch.");
+ "Hash mismatch. Username: %s", pss.username);
}
else
{
size_t buffer_offset;
uint16_t username_len;
part_encryption_aes256_t pea;
- unsigned char hash[sizeof (pea.hash)];
+ unsigned char hash[sizeof (pea.hash)] = { 0 };
gcry_cipher_hd_t cypher;
gcry_error_t err;
pea.username);
if (cypher == NULL)
{
+ ERROR ("network plugin: Failed to get cypher. Username: %s", pea.username);
sfree (pea.username);
return (-1);
}
if (err != 0)
{
sfree (pea.username);
- ERROR ("network plugin: gcry_cipher_decrypt returned: %s",
- gcry_strerror (err));
+ ERROR ("network plugin: gcry_cipher_decrypt returned: %s. Username: %s",
+ gcry_strerror (err), pea.username);
return (-1);
}
assert (buffer_offset == (part_size - payload_len));
/* Check hash sum */
- memset (hash, 0, sizeof (hash));
gcry_md_hash_buffer (GCRY_MD_SHA1, hash,
buffer + buffer_offset, payload_len);
if (memcmp (hash, pea.hash, sizeof (hash)) != 0)
{
+ ERROR ("network plugin: Checksum mismatch. Username: %s", pea.username);
sfree (pea.username);
- ERROR ("network plugin: Decryption failed: Checksum mismatch.");
return (-1);
}
int status;
value_list_t vl = VALUE_LIST_INIT;
- notification_t n;
+ notification_t n = { 0 };
#if HAVE_LIBGCRYPT
int packet_was_signed = (flags & PP_SIGNED);
- int packet_was_encrypted = (flags & PP_ENCRYPTED);
+ int packet_was_encrypted = (flags & PP_ENCRYPTED);
int printed_ignore_warning = 0;
#endif /* HAVE_LIBGCRYPT */
memset (&vl, '\0', sizeof (vl));
- memset (&n, '\0', sizeof (n));
status = 0;
while ((status == 0) && (0 < buffer_size)
static void free_sockent_server (struct sockent_server *ses) /* {{{ */
{
- size_t i;
-
- for (i = 0; i < ses->fd_num; i++)
+ for (size_t i = 0; i < ses->fd_num; i++)
{
if (ses->fd[i] >= 0)
{
* index is preferred here, because of its similarity
* to the way IPv6 handles this. Unfortunately, it
* appears not to be portable. */
- struct ip_mreqn mreq;
-
- memset (&mreq, 0, sizeof (mreq));
- mreq.imr_multiaddr.s_addr = addr->sin_addr.s_addr;
- mreq.imr_address.s_addr = ntohl (INADDR_ANY);
- mreq.imr_ifindex = se->interface;
+ struct ip_mreqn mreq = {
+ .imr_multiaddr.s_addr = addr->sin_addr.s_addr,
+ .imr_address.s_addr = ntohl (INADDR_ANY),
+ .imr_ifindex = se->interface
+ };
#else
- struct ip_mreq mreq;
-
- memset (&mreq, 0, sizeof (mreq));
- mreq.imr_multiaddr.s_addr = addr->sin_addr.s_addr;
- mreq.imr_interface.s_addr = ntohl (INADDR_ANY);
+ struct ip_mreq mreq = {
+ .imr_multiaddr.s_addr = addr->sin_addr.s_addr,
+ .imr_interface.s_addr = ntohl (INADDR_ANY)
+ };
#endif
if (setsockopt (se->data.client.fd, IPPROTO_IP, IP_MULTICAST_IF,
{
if (se->data.client.security_level > SECURITY_LEVEL_NONE)
{
- network_init_gcrypt ();
+ if (network_init_gcrypt () < 0)
+ {
+ ERROR ("network plugin: Cannot configure client socket with "
+ "security: Failed to initialize crypto library.");
+ return (-1);
+ }
if ((se->data.client.username == NULL)
|| (se->data.client.password == NULL))
}
else /* (se->type == SOCKENT_TYPE_SERVER) */
{
- if (se->data.server.security_level > SECURITY_LEVEL_NONE)
+ if ((se->data.server.security_level > SECURITY_LEVEL_NONE)
+ && (se->data.server.auth_file == NULL))
{
- network_init_gcrypt ();
-
- if (se->data.server.auth_file == NULL)
- {
- ERROR ("network plugin: Server socket with "
- "security requested, but no "
- "password file is configured.");
- return (-1);
- }
+ ERROR ("network plugin: Server socket with security requested, "
+ "but no \"AuthFile\" is configured.");
+ return (-1);
}
if (se->data.server.auth_file != NULL)
{
+ if (network_init_gcrypt () < 0)
+ {
+ ERROR ("network plugin: Cannot configure server socket with security: "
+ "Failed to initialize crypto library.");
+ return (-1);
+ }
+
se->data.server.userdb = fbh_create (se->data.server.auth_file);
if (se->data.server.userdb == NULL)
{
- ERROR ("network plugin: Reading password file "
- "`%s' failed.",
+ ERROR ("network plugin: Reading password file \"%s\" failed.",
se->data.server.auth_file);
- if (se->data.server.security_level > SECURITY_LEVEL_NONE)
- return (-1);
+ return (-1);
}
}
}
static c_complain_t complaint = C_COMPLAIN_INIT_STATIC;
struct sockent_client *client;
- struct addrinfo ai_hints;
- struct addrinfo *ai_list = NULL, *ai_ptr;
+ struct addrinfo *ai_list;
int status;
_Bool reconnect = 0;
cdtime_t now;
if (client->fd >= 0 && !reconnect) /* already connected and not stale*/
return (0);
- memset (&ai_hints, 0, sizeof (ai_hints));
-#ifdef AI_ADDRCONFIG
- ai_hints.ai_flags |= AI_ADDRCONFIG;
-#endif
- ai_hints.ai_family = AF_UNSPEC;
- ai_hints.ai_socktype = SOCK_DGRAM;
- ai_hints.ai_protocol = IPPROTO_UDP;
+ struct addrinfo ai_hints = {
+ .ai_family = AF_UNSPEC,
+ .ai_flags = AI_ADDRCONFIG,
+ .ai_protocol = IPPROTO_UDP,
+ .ai_socktype = SOCK_DGRAM
+ };
status = getaddrinfo (se->node,
(se->service != NULL) ? se->service : NET_DEFAULT_PORT,
se->node);
}
- for (ai_ptr = ai_list; ai_ptr != NULL; ai_ptr = ai_ptr->ai_next)
+ for (struct addrinfo *ai_ptr = ai_list; ai_ptr != NULL; ai_ptr = ai_ptr->ai_next)
{
if (client->fd >= 0) /* when we reconnect */
sockent_client_disconnect(se);
/* Open the file descriptors for a initialized sockent structure. */
static int sockent_server_listen (sockent_t *se) /* {{{ */
{
- struct addrinfo ai_hints;
- struct addrinfo *ai_list, *ai_ptr;
+ struct addrinfo *ai_list;
int status;
const char *node;
DEBUG ("network plugin: sockent_server_listen: node = %s; service = %s;",
node, service);
- memset (&ai_hints, 0, sizeof (ai_hints));
- ai_hints.ai_flags = 0;
-#ifdef AI_PASSIVE
- ai_hints.ai_flags |= AI_PASSIVE;
-#endif
-#ifdef AI_ADDRCONFIG
- ai_hints.ai_flags |= AI_ADDRCONFIG;
-#endif
- ai_hints.ai_family = AF_UNSPEC;
- ai_hints.ai_socktype = SOCK_DGRAM;
- ai_hints.ai_protocol = IPPROTO_UDP;
+ struct addrinfo ai_hints = {
+ .ai_family = AF_UNSPEC,
+ .ai_flags = AI_ADDRCONFIG | AI_PASSIVE,
+ .ai_protocol = IPPROTO_UDP,
+ .ai_socktype = SOCK_DGRAM
+ };
status = getaddrinfo (node, service, &ai_hints, &ai_list);
if (status != 0)
return (-1);
}
- for (ai_ptr = ai_list; ai_ptr != NULL; ai_ptr = ai_ptr->ai_next)
+ for (struct addrinfo *ai_ptr = ai_list; ai_ptr != NULL; ai_ptr = ai_ptr->ai_next)
{
int *tmp;
if (se->type == SOCKENT_TYPE_SERVER)
{
struct pollfd *tmp;
- size_t i;
tmp = realloc (listen_sockets_pollfd,
sizeof (*tmp) * (listen_sockets_num
listen_sockets_pollfd = tmp;
tmp = listen_sockets_pollfd + listen_sockets_num;
- for (i = 0; i < se->data.server.fd_num; i++)
+ for (size_t i = 0; i < se->data.server.fd_num; i++)
{
memset (tmp + i, 0, sizeof (*tmp));
tmp[i].fd = se->data.server.fd[i];
char buffer[network_config_packet_size];
int buffer_len;
- size_t i;
int status = 0;
receive_list_entry_t *private_list_head;
break;
}
- for (i = 0; (i < listen_sockets_num) && (status > 0); i++)
+ for (size_t i = 0; (i < listen_sockets_num) && (status > 0); i++)
{
receive_list_entry_t *ent;
static void network_send_buffer_signed (sockent_t *se, /* {{{ */
const char *in_buffer, size_t in_buffer_size)
{
- part_signature_sha256_t ps;
char buffer[BUFF_SIG_SIZE + in_buffer_size];
size_t buffer_offset;
size_t username_len;
in_buffer, in_buffer_size);
/* Initialize the `ps' structure. */
- memset (&ps, 0, sizeof (ps));
- ps.head.type = htons (TYPE_SIGN_SHA256);
- ps.head.length = htons (PART_SIGNATURE_SHA256_SIZE + username_len);
+ part_signature_sha256_t ps = {
+ .head.type = htons (TYPE_SIGN_SHA256),
+ .head.length = htons (PART_SIGNATURE_SHA256_SIZE + username_len)
+ };
/* Calculate the hash value. */
gcry_md_write (hd, buffer + PART_SIGNATURE_SHA256_SIZE,
static void network_send_buffer_encrypted (sockent_t *se, /* {{{ */
const char *in_buffer, size_t in_buffer_size)
{
- part_encryption_aes256_t pea;
char buffer[BUFF_SIG_SIZE + in_buffer_size];
size_t buffer_size;
size_t buffer_offset;
gcry_cipher_hd_t cypher;
/* Initialize the header fields */
- memset (&pea, 0, sizeof (pea));
- pea.head.type = htons (TYPE_ENCR_AES256);
-
- pea.username = se->data.client.username;
+ part_encryption_aes256_t pea = {
+ .head.type = htons (TYPE_ENCR_AES256),
+ .username = se->data.client.username
+ };
username_len = strlen (pea.username);
if ((PART_ENCRYPTION_AES256_SIZE + username_len) > BUFF_SIG_SIZE)
static void network_send_buffer (char *buffer, size_t buffer_len) /* {{{ */
{
- sockent_t *se;
-
DEBUG ("network plugin: network_send_buffer: buffer_len = %zu", buffer_len);
- for (se = sending_sockets; se != NULL; se = se->next)
+ for (sockent_t *se = sending_sockets; se != NULL; se = se->next)
{
#if HAVE_LIBGCRYPT
if (se->data.client.security_level == SECURITY_LEVEL_ENCRYPT)
{
int status;
+ /* listen_loop is set to non-zero in the shutdown callback, which is
+ * guaranteed to be called *after* all the write threads have been shut
+ * down. */
+ assert (listen_loop == 0);
+
if (!check_send_okay (vl))
{
#if COLLECT_DEBUG
{
sockent_t *se;
int status;
- int i;
if ((ci->values_num < 1) || (ci->values_num > 2)
|| (ci->values[0].type != OCONFIG_TYPE_STRING)
if (ci->values_num >= 2)
se->service = strdup (ci->values[1].value.string);
- for (i = 0; i < ci->children_num; i++)
+ for (int i = 0; i < ci->children_num; i++)
{
oconfig_item_t *child = ci->children + i;
{
sockent_t *se;
int status;
- int i;
if ((ci->values_num < 1) || (ci->values_num > 2)
|| (ci->values[0].type != OCONFIG_TYPE_STRING)
if (ci->values_num >= 2)
se->service = strdup (ci->values[1].value.string);
- for (i = 0; i < ci->children_num; i++)
+ for (int i = 0; i < ci->children_num; i++)
{
oconfig_item_t *child = ci->children + i;
static int network_config (oconfig_item_t *ci) /* {{{ */
{
- int i;
-
/* The options need to be applied first */
- 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 ("TimeToLive", child->key) == 0)
network_config_set_ttl (child);
}
- for (i = 0; i < ci->children_num; i++)
+ for (int i = 0; i < ci->children_num; i++)
{
oconfig_item_t *child = ci->children + i;
static int network_shutdown (void)
{
- sockent_t *se;
-
listen_loop++;
/* Kill the listening thread */
sfree (send_buffer);
- for (se = sending_sockets; se != NULL; se = se->next)
+ for (sockent_t *se = sending_sockets; se != NULL; se = se->next)
sockent_client_disconnect (se);
sockent_destroy (sending_sockets);
return (0);
have_init = 1;
-#if HAVE_LIBGCRYPT
- network_init_gcrypt ();
-#endif
-
if (network_config_stats)
plugin_register_read ("network", network_stats_read);
**/
#include "collectd.h"
+
#include "common.h"
#include "plugin.h"
#elif HAVE_LIBKSTAT
static int nfs_init (void)
{
- kstat_t *ksp_chain = NULL;
-
nfs2_ksp_client = NULL;
nfs2_ksp_server = NULL;
nfs3_ksp_client = NULL;
if (kc == NULL)
return (-1);
- for (ksp_chain = kc->kc_chain; ksp_chain != NULL;
+ for (kstat_t *ksp_chain = kc->kc_chain; ksp_chain != NULL;
ksp_chain = ksp_chain->ks_next)
{
if (strncmp (ksp_chain->ks_module, "nfs", 3) != 0)
value_t *values, size_t values_num)
{
value_list_t vl = VALUE_LIST_INIT;
- size_t i;
vl.values_len = 1;
sstrncpy (vl.host, hostname_g, sizeof (vl.host));
sizeof (vl.plugin_instance));
sstrncpy (vl.type, "nfs_procedure", sizeof (vl.type));
- for (i = 0; i < values_num; i++)
+ for (size_t i = 0; i < values_num; i++)
{
vl.values = values + i;
sstrncpy (vl.type_instance, type_instances[i],
{
char plugin_instance[DATA_MAX_NAME_LEN];
value_t values[fields_num];
- size_t i;
ssnprintf (plugin_instance, sizeof (plugin_instance), "v%i%s",
nfs_version, instance);
- for (i = 0; i < fields_num; i++)
+ for (size_t i = 0; i < fields_num; i++)
(void) parse_value (fields[i], &values[i], DS_TYPE_DERIVE);
nfs_procedures_submit (plugin_instance, proc_names, values,
{
char plugin_instance[DATA_MAX_NAME_LEN];
value_t values[proc_names_num];
- size_t i;
if (ksp == NULL)
return (EINVAL);
nfs_version, inst);
kstat_read(kc, ksp, NULL);
- for (i = 0; i < proc_names_num; i++)
+ for (size_t i = 0; i < proc_names_num; i++)
{
/* The name passed to kstat_data_lookup() doesn't have the
* "const" modifier, so we need to copy the name here. */
**/
#include "collectd.h"
+
#include "common.h"
#include "plugin.h"
-#include "configfile.h"
#include <curl/curl.h>
return;
vl.values = values;
- vl.values_len = 1;
+ vl.values_len = STATIC_ARRAY_SIZE (values);
sstrncpy (vl.host, hostname_g, sizeof (vl.host));
sstrncpy (vl.plugin, "nginx", sizeof (vl.plugin));
sstrncpy (vl.plugin_instance, "", sizeof (vl.plugin_instance));
static int nginx_read (void)
{
- int i;
-
char *ptr;
char *lines[16];
int lines_num = 0;
* 16630948 16630948 31070465
* Reading: 6 Writing: 179 Waiting: 106
*/
- for (i = 0; i < lines_num; i++)
+ for (int i = 0; i < lines_num; i++)
{
fields_num = strsplit (lines[i], fields,
(sizeof (fields) / sizeof (fields[0])));
*/
#include "collectd.h"
+
#include "common.h"
#include "plugin.h"
-#include "configfile.h"
#include <glib.h>
#include <libnotify/notify.h>
static int c_notify_config (oconfig_item_t *ci)
{
- int i = 0;
-
- for (i = 0; i < ci->children_num; ++i) {
+ for (int i = 0; i < ci->children_num; ++i) {
oconfig_item_t *c = ci->children + i;
if (0 == strcasecmp (c->key, "OkayTimeout"))
**/
#include "collectd.h"
+
#include "common.h"
#include "plugin.h"
static int authinteract (auth_client_request_t request, char **result,
int fields, void __attribute__((unused)) *arg)
{
- int i;
- for (i = 0; i < fields; i++)
+ for (int i = 0; i < fields; i++)
{
if (request[i].flags & AUTH_USER)
result[i] = smtp_user;
*/
#include "collectd.h"
+
#include "plugin.h"
#include "common.h"
-#include "configfile.h"
#define NAGIOS_OK 0
#define NAGIOS_WARNING 1
static int nagios_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;
char const *file = NAGIOS_COMMAND_FILE;
int fd;
int status;
- struct flock lock;
+ struct flock lock = { 0 };
if (nagios_command_file != NULL)
file = nagios_command_file;
return status;
}
- memset (&lock, 0, sizeof (lock));
lock.l_type = F_WRLCK;
lock.l_whence = SEEK_END;
- lock.l_start = 0;
- lock.l_len = 0; /* to end of file */
status = fcntl (fd, F_GETLK, &lock);
if (status != 0)
#define _BSD_SOURCE /* For NI_MAXHOST */
#include "collectd.h"
+
#include "common.h"
#include "plugin.h"
-#include "configfile.h"
#if HAVE_STDINT_H
# include <stdint.h>
static void ntpd_submit (const char *type, const char *type_inst, 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, "ntpd", sizeof (vl.plugin));
const char *host;
const char *port;
- struct addrinfo ai_hints;
struct addrinfo *ai_list;
- struct addrinfo *ai_ptr;
int status;
if (sock_descr >= 0)
if (strlen (port) == 0)
port = NTPD_DEFAULT_PORT;
- memset (&ai_hints, '\0', sizeof (ai_hints));
- ai_hints.ai_flags = 0;
-#ifdef AI_ADDRCONFIG
- ai_hints.ai_flags |= AI_ADDRCONFIG;
-#endif
- ai_hints.ai_family = PF_UNSPEC;
- ai_hints.ai_socktype = SOCK_DGRAM;
- ai_hints.ai_protocol = IPPROTO_UDP;
+ struct addrinfo ai_hints = {
+ .ai_family = AF_UNSPEC,
+ .ai_flags = AI_ADDRCONFIG,
+ .ai_protocol = IPPROTO_UDP,
+ .ai_socktype = SOCK_DGRAM
+ };
if ((status = getaddrinfo (host, port, &ai_hints, &ai_list)) != 0)
{
return (-1);
}
- for (ai_ptr = ai_list; ai_ptr != NULL; ai_ptr = ai_ptr->ai_next)
+ for (struct addrinfo *ai_ptr = ai_list; ai_ptr != NULL; ai_ptr = ai_ptr->ai_next)
{
/* create our socket descriptor */
if ((sock_descr = socket (ai_ptr->ai_family,
struct resp_pkt res;
int status;
int done;
- int i;
char *items;
size_t items_num;
struct timeval time_now;
int timeout;
- int pkt_item_num; /* items in this packet */
- int pkt_item_len; /* size of the items in this packet */
+ int pkt_item_num; /* items in this packet */
+ int pkt_item_len; /* size of the items in this packet */
int pkt_sequence;
- char pkt_recvd[MAXSEQ+1]; /* sequence numbers that have been received */
- int pkt_recvd_num; /* number of packets that have been received */
- int pkt_lastseq; /* the last sequence number */
- ssize_t pkt_padding; /* Padding in this packet */
+ char pkt_recvd[MAXSEQ+1] = { 0 }; /* sequence numbers that have been received */
+ int pkt_recvd_num; /* number of packets that have been received */
+ int pkt_lastseq; /* the last sequence number */
+ ssize_t pkt_padding; /* Padding in this packet */
if ((sd = ntpd_connect ()) < 0)
return (-1);
items = NULL;
items_num = 0;
- memset (pkt_recvd, '\0', sizeof (pkt_recvd));
pkt_recvd_num = 0;
pkt_lastseq = -1;
items_num += pkt_item_num;
*res_data = items;
- for (i = 0; i < pkt_item_num; i++)
+ for (int i = 0; i < pkt_item_num; i++)
{
/* dst: There are already `*res_items' items with
* res_item_size bytes each in in `*res_data'. Set
static int ntpd_send_request (int req_code, int req_items, int req_size, char *req_data)
{
int sd;
- struct req_pkt req;
+ struct req_pkt req = { 0 };
size_t req_data_len;
int status;
if ((sd = ntpd_connect ()) < 0)
return (-1);
- memset (&req, '\0', sizeof (req));
req.rm_vn_mode = RM_VN_MODE(0, 0, 0);
req.auth_seq = AUTH_SEQ (0, 0);
req.implementation = IMPL_XNTPD;
static int ntpd_get_name_from_address (char *buffer, size_t buffer_size,
struct info_peer_summary const *peer_info, _Bool do_reverse_lookup)
{
- struct sockaddr_storage sa;
+ struct sockaddr_storage sa = { 0 };
socklen_t sa_len;
int flags = 0;
int status;
- memset (&sa, 0, sizeof (sa));
-
if (peer_info->v6_flag)
{
- struct sockaddr_in6 sa6;
+ struct sockaddr_in6 sa6 = { 0 };
assert (sizeof (sa) >= sizeof (sa6));
- memset (&sa6, 0, sizeof (sa6));
sa6.sin6_family = AF_INET6;
sa6.sin6_port = htons (123);
memcpy (&sa6.sin6_addr, &peer_info->srcadr6,
}
else
{
- struct sockaddr_in sa4;
+ struct sockaddr_in sa4 = { 0 };
assert (sizeof (sa) >= sizeof (sa4));
- memset (&sa4, 0, sizeof (sa4));
sa4.sin_family = AF_INET;
sa4.sin_port = htons (123);
memcpy (&sa4.sin_addr, &peer_info->srcadr,
gauge_t offset_error;
int status;
- int i;
/* On Linux, if the STA_NANO bit is set in ik->status, then ik->offset
* is is nanoseconds, otherwise it's microseconds. */
return (-1);
}
- for (i = 0; i < ps_num; i++)
+ for (int i = 0; i < ps_num; i++)
{
struct info_peer_summary *ptr;
double offset;
**/
#include "collectd.h"
+
#include "common.h"
#include "plugin.h"
while (42)
{
char path[PATH_MAX];
- struct stat statbuf;
+ struct stat statbuf = { 0 };
int status;
ssnprintf (path, sizeof (path), NUMA_ROOT_DIR "/node%i", max_node + 1);
- memset (&statbuf, 0, sizeof (statbuf));
status = stat (path, &statbuf);
if (status == 0)
**/
#include "collectd.h"
+
#include "common.h"
#include "plugin.h"
static void nut_submit (nut_ups_t *ups, 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_len = STATIC_ARRAY_SIZE (values);
+ vl.values = &(value_t) { .gauge = value };
+ vl.values_len = 1;
sstrncpy (vl.host,
(strcasecmp (ups->hostname, "localhost") == 0)
? hostname_g
static int nut_read (void)
{
- nut_ups_t *ups;
int success = 0;
pthread_mutex_lock (&read_lock);
if (success != 0)
return (0);
- for (ups = upslist_head; ups != NULL; ups = ups->next)
+ for (nut_ups_t *ups = upslist_head; ups != NULL; ups = ups->next)
if (nut_read_one (ups) == 0)
success++;
**/
#include "collectd.h"
+
#include "common.h"
#include "plugin.h"
static FILE *olsrd_connect (void) /* {{{ */
{
- struct addrinfo ai_hints;
- struct addrinfo *ai_list, *ai_ptr;
+ struct addrinfo *ai_list;
int ai_return;
FILE *fh;
- memset (&ai_hints, 0, sizeof (ai_hints));
- ai_hints.ai_flags = 0;
-#ifdef AI_ADDRCONFIG
- ai_hints.ai_flags |= AI_ADDRCONFIG;
-#endif
- ai_hints.ai_family = PF_UNSPEC;
- ai_hints.ai_socktype = SOCK_STREAM;
- ai_hints.ai_protocol = IPPROTO_TCP;
+ struct addrinfo ai_hints = {
+ .ai_family = AF_UNSPEC,
+ .ai_flags = AI_ADDRCONFIG,
+ .ai_protocol = IPPROTO_TCP,
+ .ai_socktype = SOCK_STREAM
+ };
- ai_list = NULL;
ai_return = getaddrinfo (olsrd_get_node (), olsrd_get_service (),
&ai_hints, &ai_list);
if (ai_return != 0)
}
fh = NULL;
- for (ai_ptr = ai_list; ai_ptr != NULL; ai_ptr = ai_ptr->ai_next)
+ for (struct addrinfo *ai_ptr = ai_list; ai_ptr != NULL; ai_ptr = ai_ptr->ai_next)
{
int fd;
int status;
static void olsrd_submit (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));
if (config_want_topology == OLSRD_WANT_DETAIL)
{
- char type_instance[DATA_MAX_NAME_LEN];
+ char type_instance[DATA_MAX_NAME_LEN] = { 0 };
- memset (type_instance, 0, sizeof (type_instance));
ssnprintf (type_instance, sizeof (type_instance), "%s-%s-lq",
fields[0], fields[1]);
DEBUG ("olsrd plugin: type_instance = %s; lq = %g;", type_instance, lq);
}
else
{
- char type_instance[DATA_MAX_NAME_LEN];
+ char type_instance[DATA_MAX_NAME_LEN] = { 0 };
- memset (type_instance, 0, sizeof (type_instance));
ssnprintf (type_instance, sizeof (type_instance), "%s-%s-nlq",
fields[0], fields[1]);
DEBUG ("olsrd plugin: type_instance = %s; nlq = %g;", type_instance, nlq);
**/
#include "collectd.h"
+
#include "common.h"
#include "plugin.h"
#include "utils_ignorelist.h"
static int cow_read_values (const char *path, const char *name,
const ow_family_features_t *family_info)
{
- value_t values[1];
value_list_t vl = VALUE_LIST_INIT;
int success = 0;
- size_t i;
if (sensor_list != NULL)
{
return 0;
}
- vl.values = values;
- vl.values_len = 1;
-
sstrncpy (vl.host, hostname_g, sizeof (vl.host));
sstrncpy (vl.plugin, "onewire", sizeof (vl.plugin));
sstrncpy (vl.plugin_instance, name, sizeof (vl.plugin_instance));
- for (i = 0; i < family_info->features_num; i++)
+ for (size_t i = 0; i < family_info->features_num; i++)
{
char *buffer;
size_t buffer_size;
int status;
+ char errbuf[1024];
char file[4096];
char *endptr;
status = OW_get (file, &buffer, &buffer_size);
if (status < 0)
{
- ERROR ("onewire plugin: OW_get (%s/%s) failed. status = %#x;",
- path, family_info->features[i].filename, status);
+ ERROR ("onewire plugin: OW_get (%s/%s) failed. error = %s;",
+ path, family_info->features[i].filename, sstrerror(errno, errbuf, sizeof (errbuf)));
return (-1);
}
DEBUG ("Read onewire device %s as %s", file, buffer);
endptr = NULL;
- values[0].gauge = strtod (buffer, &endptr);
+ gauge_t g = strtod (buffer, &endptr);
if (endptr == NULL)
{
ERROR ("onewire plugin: Buffer is not a number: %s", buffer);
sstrncpy (vl.type_instance, family_info->features[i].type_instance,
sizeof (vl.type_instance));
+ vl.values = &(value_t) { .gauge = g };
+ vl.values_len = 1;
+
plugin_dispatch_values (&vl);
success++;
char *buffer;
size_t buffer_size;
int status;
+ char errbuf[1024];
char *buffer_ptr;
char *dummy;
status = OW_get (path, &buffer, &buffer_size);
if (status < 0)
{
- ERROR ("onewire plugin: OW_get (%s) failed. status = %#x;",
- path, status);
+ ERROR ("onewire plugin: OW_get (%s) failed. error = %s;",
+ path, sstrerror(errno, errbuf, sizeof (errbuf)));
return (-1);
}
DEBUG ("onewire plugin: OW_get (%s) returned: %s",
static int cow_simple_read (void)
{
- value_t values[1];
value_list_t vl = VALUE_LIST_INIT;
char *buffer;
size_t buffer_size;
int status;
+ char errbuf[1024];
char *endptr;
direct_access_element_t *traverse;
/* traverse list and check entries */
for (traverse = direct_list; traverse != NULL; traverse = traverse->next)
{
- vl.values = values;
- vl.values_len = 1;
-
sstrncpy (vl.host, hostname_g, sizeof (vl.host));
sstrncpy (vl.plugin, "onewire", sizeof (vl.plugin));
sstrncpy (vl.plugin_instance, traverse->address, sizeof (vl.plugin_instance));
status = OW_get (traverse->path, &buffer, &buffer_size);
if (status < 0)
{
- ERROR ("onewire plugin: OW_get (%s) failed. status = %#x;",
+ ERROR ("onewire plugin: OW_get (%s) failed. status = %s;",
traverse->path,
- status);
+ sstrerror(errno, errbuf, sizeof (errbuf)));
return (-1);
}
DEBUG ("onewire plugin: Read onewire device %s as %s", traverse->path, buffer);
-
endptr = NULL;
- values[0].gauge = strtod (buffer, &endptr);
+ gauge_t g = strtod (buffer, &endptr);
if (endptr == NULL)
{
ERROR ("onewire plugin: Buffer is not a number: %s", buffer);
sstrncpy (vl.type, traverse->file, sizeof (vl.type));
sstrncpy (vl.type_instance, "", sizeof (""));
+ vl.values = &(value_t) { .gauge = g };
+ vl.values_len = 1;
+
plugin_dispatch_values (&vl);
free (buffer);
} /* for (traverse) */
static int cow_init (void)
{
int status;
+ char errbuf[1024];
if (device_g == NULL)
{
status = (int) OW_init (device_g);
if (status != 0)
{
- ERROR ("onewire plugin: OW_init(%s) failed: %i.", device_g, status);
+ ERROR ("onewire plugin: OW_init(%s) failed: %s.", device_g, sstrerror(errno, errbuf, sizeof (errbuf)));
return (1);
}
**/
#include "collectd.h"
+
#include "common.h"
#include "plugin.h"
-#include "configfile.h"
#if defined(__APPLE__)
#pragma clang diagnostic push
static void cldap_submit_derive (const char *type, const char *type_instance, /* {{{ */
derive_t d, cldap_t *st)
{
- value_t v;
- v.derive = d;
- cldap_submit_value (type, type_instance, v, st);
+ cldap_submit_value (type, type_instance, (value_t) { .derive = d }, st);
} /* }}} void cldap_submit_derive */
static void cldap_submit_gauge (const char *type, const char *type_instance, /* {{{ */
gauge_t g, cldap_t *st)
{
- value_t v;
- v.gauge = g;
- cldap_submit_value (type, type_instance, v, st);
+ cldap_submit_value (type, type_instance, (value_t) { .gauge = g }, st);
} /* }}} void cldap_submit_gauge */
static int cldap_read_host (user_data_t *ud) /* {{{ */
{
cldap_t *st;
- LDAPMessage *e, *result;
+ LDAPMessage *result;
char *dn;
int rc;
int status;
return (-1);
}
- for (e = ldap_first_entry (st->ld, result); e != NULL;
+ for (LDAPMessage *e = ldap_first_entry (st->ld, result); e != NULL;
e = ldap_next_entry (st->ld, e))
{
if ((dn = ldap_get_dn (st->ld, e)) != NULL)
static int cldap_config_add (oconfig_item_t *ci) /* {{{ */
{
cldap_t *st;
- int i;
int status;
st = calloc (1, sizeof (*st));
st->verifyhost = 1;
st->version = LDAP_VERSION3;
- for (i = 0; i < ci->children_num; i++)
+ for (int i = 0; i < ci->children_num; i++)
{
oconfig_item_t *child = ci->children + i;
}
else
{
- user_data_t ud;
- char callback_name[3*DATA_MAX_NAME_LEN];
+ char callback_name[3*DATA_MAX_NAME_LEN] = { 0 };
databases = temp;
databases[databases_num] = st;
databases_num++;
- memset (&ud, 0, sizeof (ud));
- ud.data = st;
-
- memset (callback_name, 0, sizeof (callback_name));
ssnprintf (callback_name, sizeof (callback_name),
"openldap/%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 = */ cldap_read_host,
/* interval = */ 0,
- /* user_data = */ &ud);
+ &(user_data_t) {
+ .data = st,
+ });
}
}
static int cldap_config (oconfig_item_t *ci) /* {{{ */
{
- int i;
int status = 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;
static int cldap_shutdown (void) /* {{{ */
{
- size_t i;
-
- for (i = 0; i < databases_num; i++)
+ for (size_t i = 0; i < databases_num; i++)
if (databases[i]->ld != NULL)
ldap_unbind_ext_s (databases[i]->ld, NULL, NULL);
sfree (databases);
**/
#include "collectd.h"
+
#include "common.h"
#include "plugin.h"
static void numusers_submit (const char *pinst, const char *tinst,
gauge_t value)
{
- value_t values[1];
value_list_t vl = VALUE_LIST_INIT;
- values[0].gauge = value;
-
- vl.values = values;
- vl.values_len = STATIC_ARRAY_SIZE (values);
+ vl.values = &(value_t) { .gauge = value };
+ vl.values_len = 1;
sstrncpy (vl.host, hostname_g, sizeof (vl.host));
sstrncpy (vl.plugin, "openvpn", sizeof (vl.plugin));
sstrncpy (vl.type, "users", sizeof (vl.type));
static void iostats_submit (const char *pinst, const char *tinst,
derive_t rx, derive_t tx)
{
- value_t values[2];
value_list_t vl = VALUE_LIST_INIT;
-
- values[0].derive = rx;
- values[1].derive = tx;
+ value_t values[] = {
+ { .derive = rx },
+ { .derive = tx },
+ };
/* NOTE ON THE NEW NAMING SCHEMA:
* using plugin_instance to identify each vpn config (and
static void compression_submit (const char *pinst, const char *tinst,
derive_t uncompressed, derive_t compressed)
{
- value_t values[2];
value_list_t vl = VALUE_LIST_INIT;
-
- values[0].derive = uncompressed;
- values[1].derive = compressed;
+ value_t values[] = {
+ { .derive = uncompressed },
+ { .derive = compressed },
+ };
vl.values = values;
vl.values_len = STATIC_ARRAY_SIZE (values);
static int openvpn_read (void)
{
FILE *fh;
- int i, read;
+ int read;
read = 0;
/* call the right read function for every status entry in the list */
- for (i = 0; i < vpn_num; i++)
+ for (int i = 0; i < vpn_num; i++)
{
int vpn_read = 0;
if (strcasecmp ("StatusFile", key) == 0)
{
char *status_file, *status_name, *filename;
- int status_version, i;
+ int status_version;
vpn_status_t *temp;
/* try to detect the status file format */
}
/* scan the list looking for a clone */
- for (i = 0; i < vpn_num; i++)
+ for (int i = 0; i < vpn_num; i++)
{
if (strcasecmp (vpn_list[i]->name, status_name) == 0)
{
/* shutdown callback */
static int openvpn_shutdown (void)
{
- int i;
-
- for (i = 0; i < vpn_num; i++)
+ for (int i = 0; i < vpn_num; i++)
{
sfree (vpn_list[i]->file);
sfree (vpn_list[i]);
**/
#include "collectd.h"
+
#include "common.h"
#include "plugin.h"
-#include "configfile.h"
#include "utils_db_query.h"
#include <oci.h>
char buffer[2048];
sb4 error_code;
int status;
- unsigned int record_number;
if (db_name == NULL)
db_name = "(none)";
/* An operation may cause / return multiple errors. Loop until we have
* handled all errors available (with a fail-save limit of 16). */
- for (record_number = 1; record_number <= 16; record_number++)
+ for (unsigned int record_number = 1; record_number <= 16; record_number++)
{
memset (buffer, 0, sizeof (buffer));
error_code = -1;
static void o_database_free (o_database_t *db) /* {{{ */
{
- size_t i;
-
if (db == NULL)
return;
sfree (db->queries);
if (db->q_prep_areas != NULL)
- for (i = 0; i < db->queries_num; ++i)
+ for (size_t i = 0; i < db->queries_num; ++i)
udb_query_delete_preparation_area (db->q_prep_areas[i]);
free (db->q_prep_areas);
{
o_database_t *db;
int status;
- int i;
if ((ci->values_num != 1)
|| (ci->values[0].type != OCONFIG_TYPE_STRING))
}
/* Fill the `o_database_t' structure.. */
- for (i = 0; i < ci->children_num; i++)
+ for (int i = 0; i < ci->children_num; i++)
{
oconfig_item_t *child = ci->children + i;
break;
}
- for (i = 0; i < db->queries_num; ++i)
+ for (int i = 0; i < db->queries_num; ++i)
{
db->q_prep_areas[i]
= udb_query_allocate_preparation_area (db->queries[i]);
static int o_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;
if (strcasecmp ("Query", child->key) == 0)
OCIDefine **oci_defines;
int status;
- size_t i;
oci_statement = udb_query_get_user_data (q);
ALLOC_OR_FAIL (column_names, column_num * sizeof (char *));
ALLOC_OR_FAIL (column_names[0], column_num * DATA_MAX_NAME_LEN
* sizeof (char));
- for (i = 1; i < column_num; i++)
+ for (size_t i = 1; i < column_num; i++)
column_names[i] = column_names[i - 1] + DATA_MAX_NAME_LEN;
ALLOC_OR_FAIL (column_values, column_num * sizeof (char *));
ALLOC_OR_FAIL (column_values[0], column_num * DATA_MAX_NAME_LEN
* sizeof (char));
- for (i = 1; i < column_num; i++)
+ for (size_t i = 1; i < column_num; i++)
column_values[i] = column_values[i - 1] + DATA_MAX_NAME_LEN;
ALLOC_OR_FAIL (oci_defines, column_num * sizeof (OCIDefine *));
/* ``Define'' the returned data, i. e. bind the columns to the buffers
* allocated above. */
- for (i = 0; i < column_num; i++) /* {{{ */
+ for (size_t i = 0; i < column_num; i++) /* {{{ */
{
char *column_name;
ub4 column_name_length;
static int o_read_database (o_database_t *db) /* {{{ */
{
- size_t i;
int status;
if (db->oci_service_context != NULL)
DEBUG ("oracle plugin: o_read_database: db->connect_id = %s; db->oci_service_context = %p;",
db->connect_id, db->oci_service_context);
- for (i = 0; i < db->queries_num; i++)
+ for (size_t i = 0; i < db->queries_num; i++)
o_read_database_query (db, db->queries[i], db->q_prep_areas[i]);
return (0);
*
* Authors:
* Sebastian Harl <sh at tokkee.org>
+ * Pavel Rochnyak <pavel2000 ngs.ru>
**/
/*
#define DONT_POISON_SPRINTF_YET 1
#include "collectd.h"
-#undef DONT_POISON_SPRINTF_YET
-#include "configfile.h"
+#undef DONT_POISON_SPRINTF_YET
#if HAVE_STDBOOL_H
# include <stdbool.h>
#define PLUGIN_LOG 4
#define PLUGIN_NOTIF 5
#define PLUGIN_FLUSH 6
+#define PLUGIN_FLUSH_ALL 7 /* For collectd-5.6 only */
-#define PLUGIN_TYPES 7
+#define PLUGIN_TYPES 8
#define PLUGIN_CONFIG 254
#define PLUGIN_DATASET 255
/* this is defined in DynaLoader.a */
void boot_DynaLoader (PerlInterpreter *, CV *);
+static XS (Collectd_plugin_register_read);
+static XS (Collectd_plugin_register_write);
+static XS (Collectd_plugin_register_log);
+static XS (Collectd_plugin_register_notification);
+static XS (Collectd_plugin_register_flush);
+static XS (Collectd_plugin_unregister_read);
+static XS (Collectd_plugin_unregister_write);
+static XS (Collectd_plugin_unregister_log);
+static XS (Collectd_plugin_unregister_notification);
+static XS (Collectd_plugin_unregister_flush);
static XS (Collectd_plugin_register_ds);
static XS (Collectd_plugin_unregister_ds);
static XS (Collectd_plugin_dispatch_values);
static XS (Collectd__fc_register);
static XS (Collectd_call_by_name);
+static int perl_read (user_data_t *ud);
+static int perl_write (const data_set_t *ds, const value_list_t *vl,
+ user_data_t *user_data);
+static void perl_log (int level, const char *msg, user_data_t *user_data);
+static int perl_notify (const notification_t *notif, user_data_t *user_data);
+static int perl_flush (cdtime_t timeout, const char *identifier,
+ user_data_t *user_data);
+
/*
* private data types
*/
* private variables
*/
+static _Bool register_legacy_flush = 1;
+
/* if perl_threads != NULL perl_threads->head must
* point to the "base" thread */
static c_ithread_list_t *perl_threads = NULL;
XS ((*f));
} api[] =
{
+ { "Collectd::plugin_register_read", Collectd_plugin_register_read },
+ { "Collectd::plugin_register_write", Collectd_plugin_register_write },
+ { "Collectd::plugin_register_log", Collectd_plugin_register_log },
+ { "Collectd::plugin_register_notification",
+ Collectd_plugin_register_notification },
+ { "Collectd::plugin_register_flush", Collectd_plugin_register_flush },
+ { "Collectd::plugin_unregister_read", Collectd_plugin_unregister_read },
+ { "Collectd::plugin_unregister_write", Collectd_plugin_unregister_write },
+ { "Collectd::plugin_unregister_log", Collectd_plugin_unregister_log },
+ { "Collectd::plugin_unregister_notification",
+ Collectd_plugin_unregister_notification },
+ { "Collectd::plugin_unregister_flush", Collectd_plugin_unregister_flush },
{ "Collectd::plugin_register_data_set", Collectd_plugin_register_ds },
{ "Collectd::plugin_unregister_data_set", Collectd_plugin_unregister_ds },
{ "Collectd::plugin_dispatch_values", Collectd_plugin_dispatch_values },
static size_t av2value (pTHX_ char *name, AV *array, value_t *value, size_t array_len)
{
const data_set_t *ds;
- size_t i;
if ((NULL == name) || (NULL == array) || (NULL == value) || (array_len == 0))
return 0;
name, array_len, ds->ds_num);
}
- for (i = 0; i < ds->ds_num; ++i) {
+ for (size_t i = 0; i < ds->ds_num; ++i) {
SV **tmp = av_fetch (array, i, 0);
if (NULL != tmp) {
static int av2data_set (pTHX_ AV *array, char *name, data_set_t *ds)
{
- int len, i;
+ int len;
if ((NULL == array) || (NULL == name) || (NULL == ds))
return -1;
ds->ds = smalloc ((len + 1) * sizeof (*ds->ds));
ds->ds_num = len + 1;
- for (i = 0; i <= len; ++i) {
+ for (int i = 0; i <= len; ++i) {
SV **elem = av_fetch (array, i, 0);
if (NULL == elem) {
notification_meta_t **m = meta;
int len = av_len (array);
- int i;
- for (i = 0; i <= len; ++i) {
+ for (int i = 0; i <= len; ++i) {
SV **tmp = av_fetch (array, i, 0);
HV *hash;
static int data_set2av (pTHX_ data_set_t *ds, AV *array)
{
- size_t i;
-
if ((NULL == ds) || (NULL == array))
return -1;
av_extend (array, ds->ds_num);
- for (i = 0; i < ds->ds_num; ++i) {
+ for (size_t i = 0; i < ds->ds_num; ++i) {
HV *source = newHV ();
if (NULL == hv_store (source, "name", 4,
static int notification_meta2av (pTHX_ notification_meta_t *meta, AV *array)
{
int meta_num = 0;
- int i;
while (meta) {
++meta_num;
av_extend (array, meta_num);
- for (i = 0; NULL != meta; meta = meta->next, ++i) {
+ for (int i = 0; NULL != meta; meta = meta->next, ++i) {
HV *m = newHV ();
SV *value;
static int oconfig_item2hv (pTHX_ oconfig_item_t *ci, HV *hash)
{
- int i;
-
AV *values;
AV *children;
return -1;
}
- for (i = 0; i < ci->values_num; ++i) {
+ for (int i = 0; i < ci->values_num; ++i) {
SV *value;
switch (ci->values[i].type) {
return -1;
}
- for (i = 0; i < ci->children_num; ++i) {
+ for (int i = 0; i < ci->children_num; ++i) {
HV *child = newHV ();
if (0 != oconfig_item2hv (aTHX_ ci->children + i, child)) {
*/
static int pplugin_dispatch_notification (pTHX_ HV *notif)
{
- notification_t n;
+ notification_t n = { 0 };
int ret;
if (NULL == notif)
return -1;
- memset (&n, 0, sizeof (n));
-
if (0 != hv2notification (aTHX_ notif, &n))
return -1;
return 0;
}
- ret = call_pv (sub_name, G_SCALAR);
+ ret = call_pv (sub_name, G_SCALAR|G_EVAL);
t->running = old_running;
return ret;
/*
* Call all working functions of the given type.
*/
-static int pplugin_call_all (pTHX_ int type, ...)
+static int pplugin_call (pTHX_ int type, ...)
{
int retvals = 0;
va_list ap;
int ret = 0;
+ char *subname;
dSP;
PUSHMARK (SP);
- XPUSHs (sv_2mortal (newSViv ((IV)type)));
+ if (PLUGIN_READ == type) {
+ subname = va_arg(ap, char *);
+ }
+ else if (PLUGIN_WRITE == type) {
+ data_set_t *ds;
+ value_list_t *vl;
+
+ AV *pds = newAV ();
+ HV *pvl = newHV ();
- if (PLUGIN_WRITE == type) {
+ subname = va_arg(ap, char *);
/*
* $_[0] = $plugin_type;
*
* type_instance => $type_instance
* };
*/
- data_set_t *ds;
- value_list_t *vl;
-
- AV *pds = newAV ();
- HV *pvl = newHV ();
-
ds = va_arg (ap, data_set_t *);
vl = va_arg (ap, value_list_t *);
XPUSHs (sv_2mortal (newRV_noinc ((SV *)pvl)));
}
else if (PLUGIN_LOG == type) {
+ subname = va_arg(ap, char *);
/*
* $_[0] = $level;
*
XPUSHs (sv_2mortal (newSVpv (va_arg (ap, char *), 0)));
}
else if (PLUGIN_NOTIF == type) {
+ notification_t *n;
+ HV *notif = newHV ();
+
+ subname = va_arg(ap, char *);
/*
* $_[0] =
* {
* type_instance => $type_instance
* };
*/
- notification_t *n;
- HV *notif = newHV ();
-
n = va_arg (ap, notification_t *);
if (-1 == notification2hv (aTHX_ n, notif)) {
}
else if (PLUGIN_FLUSH == type) {
cdtime_t timeout;
+ subname = va_arg(ap, char *);
+ /*
+ * $_[0] = $timeout;
+ * $_[1] = $identifier;
+ */
+ timeout = va_arg (ap, cdtime_t);
+ XPUSHs (sv_2mortal (newSVnv (CDTIME_T_TO_DOUBLE (timeout))));
+ XPUSHs (sv_2mortal (newSVpv (va_arg (ap, char *), 0)));
+ }
+ else if (PLUGIN_FLUSH_ALL == type) {
+ cdtime_t timeout;
+ subname = "Collectd::plugin_call_all";
/*
* $_[0] = $timeout;
* $_[1] = $identifier;
*/
timeout = va_arg (ap, cdtime_t);
+ XPUSHs (sv_2mortal (newSViv ((IV)PLUGIN_FLUSH)));
XPUSHs (sv_2mortal (newSVnv (CDTIME_T_TO_DOUBLE (timeout))));
XPUSHs (sv_2mortal (newSVpv (va_arg (ap, char *), 0)));
}
+ else if (PLUGIN_INIT == type) {
+ subname = "Collectd::plugin_call_all";
+ XPUSHs (sv_2mortal (newSViv ((IV)type)));
+ }
+ else if (PLUGIN_SHUTDOWN == type) {
+ subname = "Collectd::plugin_call_all";
+ XPUSHs (sv_2mortal (newSViv ((IV)type)));
+ }
+ else { /* Unknown type. Run 'plugin_call_all' and make compiler happy */
+ subname = "Collectd::plugin_call_all";
+ XPUSHs (sv_2mortal (newSViv ((IV)type)));
+ }
PUTBACK;
- retvals = call_pv_locked (aTHX_ "Collectd::plugin_call_all");
+ retvals = call_pv_locked (aTHX_ subname);
SPAGAIN;
- if (0 < retvals) {
+ if (SvTRUE(ERRSV)) {
+ if (PLUGIN_LOG != type)
+ ERROR ("perl: %s error: %s", subname, SvPV_nolen(ERRSV));
+ ret = -1;
+ }
+ else if (0 < retvals) {
SV *tmp = POPs;
if (! SvTRUE (tmp))
ret = -1;
va_end (ap);
return ret;
-} /* static int pplugin_call_all (int, ...) */
+} /* static int pplugin_call (int, ...) */
/*
* collectd's Perl interpreter based thread implementation.
assert (NULL != perl_threads);
PERL_SET_CONTEXT (aTHX);
+ /* Mark as running to avoid deadlock:
+ c_ithread_destroy -> log_debug -> perl_log()
+ */
+ ithread->running = 1;
log_debug ("Shutting down Perl interpreter %p...", aTHX);
#if COLLECT_DEBUG
}
SPAGAIN;
- if (0 < retvals) {
+ if (SvTRUE(ERRSV)) {
+ ERROR ("perl: Collectd::fc_call error: %s", SvPV_nolen(ERRSV));
+ ret = -1;
+ }
+ else if (0 < retvals) {
SV *tmp = POPs;
/* the exec callbacks return a status, while
* Exported Perl API.
*/
+static void _plugin_register_generic_userdata (pTHX, int type, const char *desc)
+{
+ int ret = 0;
+ user_data_t userdata;
+ char *pluginname;
+
+ dXSARGS;
+
+ if (2 != items) {
+ log_err ("Usage: Collectd::plugin_register_%s(pluginname, subname)",
+ desc);
+ XSRETURN_EMPTY;
+ }
+
+ if (! SvOK (ST (0))) {
+ log_err ("Collectd::plugin_register_%s(pluginname, subname): "
+ "Invalid pluginname", desc);
+ XSRETURN_EMPTY;
+ }
+ if (! SvOK (ST (1))) {
+ log_err ("Collectd::plugin_register_%s(pluginname, subname): "
+ "Invalid subname", desc);
+ XSRETURN_EMPTY;
+ }
+
+ /* Use pluginname as-is to allow flush a single perl plugin */
+ pluginname = SvPV_nolen (ST (0));
+
+ log_debug ("Collectd::plugin_register_%s: "
+ "plugin = \"%s\", sub = \"%s\"",
+ desc, pluginname, SvPV_nolen (ST (1)));
+
+ memset(&userdata, 0, sizeof(userdata));
+ userdata.data = strdup(SvPV_nolen (ST (1)));
+ userdata.free_func = free;
+
+ if (PLUGIN_READ == type) {
+ ret = plugin_register_complex_read(
+ "perl", /* group */
+ pluginname,
+ perl_read,
+ plugin_get_interval(), /* Default interval */
+ &userdata);
+ }
+ else if (PLUGIN_WRITE == type) {
+ ret = plugin_register_write(pluginname, perl_write, &userdata);
+ }
+ else if (PLUGIN_LOG == type) {
+ ret = plugin_register_log(pluginname, perl_log, &userdata);
+ }
+ else if (PLUGIN_NOTIF == type) {
+ ret = plugin_register_notification(pluginname, perl_notify, &userdata);
+ }
+ else if (PLUGIN_FLUSH == type) {
+ if (1 == register_legacy_flush) { /* For collectd-5.7 only, #1731 */
+ register_legacy_flush = 0;
+ ret = plugin_register_flush("perl", perl_flush, /* user_data = */ NULL);
+ }
+
+ if (0 == ret)
+ ret = plugin_register_flush(pluginname, perl_flush, &userdata);
+ }
+ else {
+ ret = -1;
+ }
+
+ if (0 == ret)
+ XSRETURN_YES;
+ else {
+ free (userdata.data);
+ XSRETURN_EMPTY;
+ }
+} /* static void _plugin_register_generic_userdata ( ... ) */
+
+/*
+ * Collectd::plugin_register_TYPE (pluginname, subname).
+ *
+ * pluginname:
+ * name of the perl plugin
+ *
+ * subname:
+ * name of the plugin's subroutine that does the work
+ */
+
+static XS (Collectd_plugin_register_read) {
+ return _plugin_register_generic_userdata(aTHX, PLUGIN_READ, "read");
+}
+
+static XS (Collectd_plugin_register_write) {
+ return _plugin_register_generic_userdata(aTHX, PLUGIN_WRITE, "write");
+}
+
+static XS (Collectd_plugin_register_log) {
+ return _plugin_register_generic_userdata(aTHX, PLUGIN_LOG, "log");
+}
+
+static XS (Collectd_plugin_register_notification) {
+ return _plugin_register_generic_userdata(aTHX, PLUGIN_NOTIF, "notification");
+}
+
+static XS (Collectd_plugin_register_flush) {
+ return _plugin_register_generic_userdata(aTHX, PLUGIN_FLUSH, "flush");
+}
+
+typedef int perl_unregister_function_t(const char *name);
+
+static void _plugin_unregister_generic (pTHX,
+ perl_unregister_function_t *unreg, const char *desc)
+{
+ dXSARGS;
+
+ if (1 != items) {
+ log_err ("Usage: Collectd::plugin_unregister_%s(pluginname)", desc);
+ XSRETURN_EMPTY;
+ }
+
+ if (! SvOK (ST (0))) {
+ log_err ("Collectd::plugin_unregister_%s(pluginname): "
+ "Invalid pluginname", desc);
+ XSRETURN_EMPTY;
+ }
+
+ log_debug ("Collectd::plugin_unregister_%s: plugin = \"%s\"",
+ desc, SvPV_nolen (ST (0)));
+
+ unreg(SvPV_nolen (ST (0)));
+
+ XSRETURN_EMPTY;
+
+ return;
+} /* static void _plugin_unregister_generic ( ... ) */
+
+/*
+ * Collectd::plugin_unregister_TYPE (pluginname).
+ *
+ * TYPE:
+ * type of callback to be unregistered: read, write, log, notification, flush
+ *
+ * pluginname:
+ * name of the perl plugin
+ */
+
+static XS (Collectd_plugin_unregister_read) {
+ return _plugin_unregister_generic(aTHX,
+ plugin_unregister_read, "read");
+}
+
+static XS (Collectd_plugin_unregister_write) {
+ return _plugin_unregister_generic(aTHX,
+ plugin_unregister_write, "write");
+}
+
+static XS (Collectd_plugin_unregister_log) {
+ return _plugin_unregister_generic(aTHX,
+ plugin_unregister_log, "log");
+}
+
+static XS (Collectd_plugin_unregister_notification) {
+ return _plugin_unregister_generic(aTHX,
+ plugin_unregister_notification, "notification");
+}
+
+static XS (Collectd_plugin_unregister_flush) {
+ return _plugin_unregister_generic(aTHX,
+ plugin_unregister_flush, "flush");
+}
+
/*
* Collectd::plugin_register_data_set (type, dataset).
*
assert (aTHX == perl_threads->head->interp);
pthread_mutex_lock (&perl_threads->mutex);
- status = pplugin_call_all (aTHX_ PLUGIN_INIT);
+ status = pplugin_call (aTHX_ PLUGIN_INIT);
pthread_mutex_unlock (&perl_threads->mutex);
return status;
} /* static int perl_init (void) */
-static int perl_read (void)
+static int perl_read (user_data_t *user_data)
{
dTHX;
log_debug ("perl_read: c_ithread: interp = %p (active threads: %i)",
aTHX, perl_threads->number_of_threads);
- return pplugin_call_all (aTHX_ PLUGIN_READ);
-} /* static int perl_read (void) */
+
+ return pplugin_call (aTHX_ PLUGIN_READ, user_data->data);
+} /* static int perl_read (user_data_t *user_data) */
static int perl_write (const data_set_t *ds, const value_list_t *vl,
- user_data_t __attribute__((unused)) *user_data)
+ user_data_t *user_data)
{
int status;
dTHX;
log_debug ("perl_write: c_ithread: interp = %p (active threads: %i)",
aTHX, perl_threads->number_of_threads);
- status = pplugin_call_all (aTHX_ PLUGIN_WRITE, ds, vl);
+ status = pplugin_call (aTHX_ PLUGIN_WRITE, user_data->data, ds, vl);
if (aTHX == perl_threads->head->interp)
pthread_mutex_unlock (&perl_threads->mutex);
} /* static int perl_write (const data_set_t *, const value_list_t *) */
static void perl_log (int level, const char *msg,
- user_data_t __attribute__((unused)) *user_data)
+ user_data_t *user_data)
{
dTHX;
if (aTHX == perl_threads->head->interp)
pthread_mutex_lock (&perl_threads->mutex);
- pplugin_call_all (aTHX_ PLUGIN_LOG, level, msg);
+ pplugin_call (aTHX_ PLUGIN_LOG, user_data->data, level, msg);
if (aTHX == perl_threads->head->interp)
pthread_mutex_unlock (&perl_threads->mutex);
return;
} /* static void perl_log (int, const char *) */
-static int perl_notify (const notification_t *notif,
- user_data_t __attribute__((unused)) *user_data)
+static int perl_notify (const notification_t *notif, user_data_t *user_data)
{
dTHX;
aTHX = t->interp;
}
- return pplugin_call_all (aTHX_ PLUGIN_NOTIF, notif);
+ return pplugin_call (aTHX_ PLUGIN_NOTIF, user_data->data, notif);
} /* static int perl_notify (const notification_t *) */
static int perl_flush (cdtime_t timeout, const char *identifier,
- user_data_t __attribute__((unused)) *user_data)
+ user_data_t *user_data)
{
dTHX;
aTHX = t->interp;
}
- return pplugin_call_all (aTHX_ PLUGIN_FLUSH, timeout, identifier);
+
+ /* For collectd-5.6 only, #1731 */
+ if (user_data == NULL || user_data->data == NULL)
+ return pplugin_call (aTHX_ PLUGIN_FLUSH_ALL, timeout, identifier);
+
+ return pplugin_call (aTHX_ PLUGIN_FLUSH, user_data->data, timeout, identifier);
} /* static int perl_flush (const int) */
static int perl_shutdown (void)
dTHX;
plugin_unregister_complex_config ("perl");
+ plugin_unregister_read_group ("perl");
if (NULL == perl_threads)
return 0;
log_debug ("perl_shutdown: c_ithread: interp = %p (active threads: %i)",
aTHX, perl_threads->number_of_threads);
- plugin_unregister_log ("perl");
- plugin_unregister_notification ("perl");
plugin_unregister_init ("perl");
- plugin_unregister_read ("perl");
- plugin_unregister_write ("perl");
- plugin_unregister_flush ("perl");
+ plugin_unregister_flush ("perl"); /* For collectd-5.6 only, #1731 */
- ret = pplugin_call_all (aTHX_ PLUGIN_SHUTDOWN);
+ ret = pplugin_call (aTHX_ PLUGIN_SHUTDOWN);
pthread_mutex_lock (&perl_threads->mutex);
t = perl_threads->tail;
SV *tmp = NULL;
char *file = __FILE__;
- int i = 0;
-
dXSUB_SYS;
/* enable usage of Perl modules using shared libraries */
newXS ("DynaLoader::boot_DynaLoader", boot_DynaLoader, file);
/* register API */
- for (i = 0; NULL != api[i].f; ++i)
+ for (int i = 0; NULL != api[i].f; ++i)
newXS (api[i].name, api[i].f, file);
stash = gv_stashpv ("Collectd", 1);
/* export "constants" */
- for (i = 0; '\0' != constants[i].name[0]; ++i)
+ for (int i = 0; '\0' != constants[i].name[0]; ++i)
newCONSTSUB (stash, constants[i].name, newSViv (constants[i].value));
/* export global variables
* accessing any such variable (this is basically the same as using
* tie() in Perl) */
/* global strings */
- for (i = 0; '\0' != g_strings[i].name[0]; ++i) {
+ for (int i = 0; '\0' != g_strings[i].name[0]; ++i) {
tmp = get_sv (g_strings[i].name, 1);
sv_magicext (tmp, NULL, PERL_MAGIC_ext, &g_pv_vtbl,
g_strings[i].var, 0);
log_info ("Initializing Perl interpreter...");
#if COLLECT_DEBUG
{
- int i = 0;
-
- for (i = 0; i < argc; ++i)
+ for (int i = 0; i < argc; ++i)
log_debug ("argv[%i] = \"%s\"", i, argv[i]);
}
#endif /* COLLECT_DEBUG */
perl_run (aTHX);
- plugin_register_log ("perl", perl_log, /* user_data = */ NULL);
- plugin_register_notification ("perl", perl_notify,
- /* user_data = */ NULL);
plugin_register_init ("perl", perl_init);
-
- plugin_register_read ("perl", perl_read);
-
- plugin_register_write ("perl", perl_write, /* user_data = */ NULL);
- plugin_register_flush ("perl", perl_flush, /* user_data = */ NULL);
plugin_register_shutdown ("perl", perl_shutdown);
return 0;
} /* static int init_pi (const char **, const int) */
static int perl_config (oconfig_item_t *ci)
{
int status = 0;
- int i = 0;
dTHXa (NULL);
- for (i = 0; i < ci->children_num; ++i) {
+ for (int i = 0; i < ci->children_num; ++i) {
oconfig_item_t *c = ci->children + i;
int current_status = 0;
current_status = perl_config_includedir (aTHX_ c);
else if (0 == strcasecmp (c->key, "Plugin"))
current_status = perl_config_plugin (aTHX_ c);
+ else if (0 == strcasecmp (c->key, "RegisterLegacyFlush"))
+ cf_util_get_boolean (c, ®ister_legacy_flush);
else
{
log_warn ("Ignoring unknown config key \"%s\".", c->key);
*/
#include "collectd.h"
+
#include "plugin.h"
#include "common.h"
struct pf_status state;
int fd;
int status;
- int i;
fd = open (pf_device, O_RDONLY);
if (fd < 0)
return (-1);
}
- memset (&state, 0, sizeof (state));
status = ioctl (fd, DIOCGETSTATUS, &state);
if (status != 0)
{
return (-1);
}
- for (i = 0; i < PFRES_MAX; i++)
+ for (int i = 0; i < PFRES_MAX; i++)
pf_submit ("pf_counters", pf_reasons[i], state.counters[i],
/* is gauge = */ 0);
- for (i = 0; i < LCNT_MAX; i++)
+ for (int i = 0; i < LCNT_MAX; i++)
pf_submit ("pf_limits", pf_lcounters[i], state.lcounters[i],
/* is gauge = */ 0);
- for (i = 0; i < FCNT_MAX; i++)
+ for (int i = 0; i < FCNT_MAX; i++)
pf_submit ("pf_state", pf_fcounters[i], state.fcounters[i],
/* is gauge = */ 0);
- for (i = 0; i < SCNT_MAX; i++)
+ for (int i = 0; i < SCNT_MAX; i++)
pf_submit ("pf_source", pf_scounters[i], state.scounters[i],
/* is gauge = */ 0);
**/
#include "collectd.h"
+
#include "common.h"
#include "plugin.h"
-#include "configfile.h"
#include <netdb.h>
#include <poll.h>
static void service_process_request (Pinba__Request *request) /* {{{ */
{
- unsigned int i;
-
pthread_mutex_lock (&stat_nodes_lock);
- for (i = 0; i < stat_nodes_num; i++)
+ for (unsigned int i = 0; i < stat_nodes_num; i++)
{
if ((stat_nodes[i].host != NULL)
&& (strcmp (request->hostname, stat_nodes[i].host) != 0))
{
pinba_socket_t *s;
struct addrinfo *ai_list;
- struct addrinfo *ai_ptr;
- struct addrinfo ai_hints;
int status;
- memset (&ai_hints, 0, sizeof (ai_hints));
- ai_hints.ai_flags = AI_PASSIVE;
- ai_hints.ai_family = AF_UNSPEC;
- ai_hints.ai_socktype = SOCK_DGRAM;
- ai_hints.ai_addr = NULL;
- ai_hints.ai_canonname = NULL;
- ai_hints.ai_next = NULL;
-
if (node == NULL)
node = PINBA_DEFAULT_NODE;
if (service == NULL)
service = PINBA_DEFAULT_SERVICE;
- ai_list = NULL;
+ struct addrinfo ai_hints = {
+ .ai_family = AF_UNSPEC,
+ .ai_flags = AI_PASSIVE,
+ .ai_socktype = SOCK_DGRAM
+ };
+
status = getaddrinfo (node, service,
&ai_hints, &ai_list);
if (status != 0)
return (NULL);
}
- for (ai_ptr = ai_list; ai_ptr != NULL; ai_ptr = ai_ptr->ai_next)
+ for (struct addrinfo *ai_ptr = ai_list; ai_ptr != NULL; ai_ptr = ai_ptr->ai_next)
{
status = pb_add_socket (s, ai_ptr);
if (status != 0)
static void pinba_socket_free (pinba_socket_t *socket) /* {{{ */
{
- nfds_t i;
-
if (!socket)
return;
- for (i = 0; i < socket->fd_num; i++)
+ for (nfds_t i = 0; i < socket->fd_num; i++)
{
if (socket->fd[i].fd < 0)
continue;
while (!collector_thread_do_shutdown)
{
int status;
- nfds_t i;
if (s->fd_num < 1)
break;
return (-1);
}
- for (i = 0; i < s->fd_num; i++)
+ for (nfds_t i = 0; i < s->fd_num; i++)
{
if (s->fd[i].revents & (POLLERR | POLLHUP | POLLNVAL))
{
char *server = NULL;
char *script = NULL;
int status;
- int i;
status = cf_util_get_string (ci, &name);
if (status != 0)
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;
static int plugin_config (oconfig_item_t *ci) /* {{{ */
{
- int i;
-
/* The lock should not be necessary in the config callback, but let's be
* sure.. */
pthread_mutex_lock (&stat_nodes_lock);
- for (i = 0; i < ci->children_num; i++)
+ for (int i = 0; i < ci->children_num; i++)
{
oconfig_item_t *child = ci->children + i;
static int plugin_submit (const pinba_statnode_t *res) /* {{{ */
{
- value_t value;
value_list_t vl = VALUE_LIST_INIT;
- vl.values = &value;
vl.values_len = 1;
sstrncpy (vl.host, hostname_g, sizeof (vl.host));
sstrncpy (vl.plugin, "pinba", sizeof (vl.plugin));
sstrncpy (vl.plugin_instance, res->name, sizeof (vl.plugin_instance));
- value.derive = res->req_count;
+ vl.values = &(value_t) { .derive = res->req_count };
sstrncpy (vl.type, "total_requests", sizeof (vl.type));
plugin_dispatch_values (&vl);
- value.derive = float_counter_get (&res->req_time, /* factor = */ 1000);
+ vl.values = &(value_t) { .derive = float_counter_get (&res->req_time, /* factor = */ 1000) };
sstrncpy (vl.type, "total_time_in_ms", sizeof (vl.type));
plugin_dispatch_values (&vl);
- value.derive = res->doc_size;
+ vl.values = &(value_t) { .derive = res->doc_size };
sstrncpy (vl.type, "total_bytes", sizeof (vl.type));
plugin_dispatch_values (&vl);
- value.derive = float_counter_get (&res->ru_utime, /* factor = */ 100);
+ vl.values = &(value_t) { .derive = float_counter_get (&res->ru_utime, /* factor = */ 100) };
sstrncpy (vl.type, "cpu", sizeof (vl.type));
sstrncpy (vl.type_instance, "user", sizeof (vl.type_instance));
plugin_dispatch_values (&vl);
- value.derive = float_counter_get (&res->ru_stime, /* factor = */ 100);
+ vl.values = &(value_t) { .derive = float_counter_get (&res->ru_stime, /* factor = */ 100) };
sstrncpy (vl.type, "cpu", sizeof (vl.type));
sstrncpy (vl.type_instance, "system", sizeof (vl.type_instance));
plugin_dispatch_values (&vl);
- value.gauge = res->mem_peak;
+ vl.values = &(value_t) { .gauge = res->mem_peak };
sstrncpy (vl.type, "memory", sizeof (vl.type));
sstrncpy (vl.type_instance, "peak", sizeof (vl.type_instance));
plugin_dispatch_values (&vl);
+syntax = "proto2";
+
package Pinba;
option optimize_for = SPEED;
**/
#include "collectd.h"
+
#include "common.h"
#include "plugin.h"
-#include "configfile.h"
#include "utils_complain.h"
#include <netinet/in.h>
# include <netdb.h> /* NI_MAXHOST */
#endif
+#ifdef HAVE_SYS_CAPABILITY_H
+# include <sys/capability.h>
+#endif
+
#include <oping.h>
#ifndef NI_MAXHOST
static int ping_dispatch_all (pingobj_t *pingobj) /* {{{ */
{
- pingobj_iter_t *iter;
hostlist_t *hl;
int status;
- for (iter = ping_iterator_get (pingobj);
+ for (pingobj_iter_t *iter = ping_iterator_get (pingobj);
iter != NULL;
iter = ping_iterator_next (iter))
{ /* {{{ */
struct timespec ts_wait;
struct timespec ts_int;
- hostlist_t *hl;
int count;
c_complain_t complaint = C_COMPLAIN_INIT_STATIC;
/* Add all the hosts to the ping object. */
count = 0;
- for (hl = hostlist_head; hl != NULL; hl = hl->next)
+ for (hostlist_t *hl = hostlist_head; hl != NULL; hl = hl->next)
{
int tmp_status;
tmp_status = ping_host_add (pingobj, hl->host);
if (ping_thread_loop != 0)
{
pthread_mutex_unlock (&ping_lock);
- return (-1);
+ return (0);
}
ping_thread_loop = 1;
"Will use a timeout of %gs.", ping_timeout);
}
- if (start_thread () != 0)
- return (-1);
+#if defined(HAVE_SYS_CAPABILITY_H) && defined(CAP_NET_RAW)
+ if (check_capability (CAP_NET_RAW) != 0)
+ {
+ if (getuid () == 0)
+ WARNING ("ping plugin: Running collectd as root, but the CAP_NET_RAW "
+ "capability is missing. The plugin's read function will probably "
+ "fail. Is your init system dropping capabilities?");
+ else
+ WARNING ("ping plugin: collectd doesn't have the CAP_NET_RAW capability. "
+ "If you don't want to run collectd as root, try running \"setcap "
+ "cap_net_raw=ep\" on the collectd binary.");
+ }
+#endif
- return (0);
+ return (start_thread ());
} /* }}} int ping_init */
static int config_set_string (const char *name, /* {{{ */
/* Max IP packet size - (IPv6 + ICMP) = 65535 - (40 + 8) = 65487 */
if (size <= 65487)
{
- size_t i;
-
sfree (ping_data);
ping_data = malloc (size + 1);
if (ping_data == NULL)
* Optimally we would follow the ping(1) behaviour, but we
* cannot use byte 00 or start data payload at exactly same
* location, due to oping library limitations. */
- for (i = 0; i < size; i++) /* {{{ */
+ for (size_t i = 0; i < size; i++) /* {{{ */
{
/* This restricts data pattern to be only composed of easily
* printable characters, and not NUL character. */
static void submit (const char *host, const char *type, /* {{{ */
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, "ping", sizeof (vl.plugin));
static int ping_read (void) /* {{{ */
{
- hostlist_t *hl;
-
if (ping_thread_error != 0)
{
ERROR ("ping plugin: The ping thread had a problem. Restarting it.");
stop_thread ();
- for (hl = hostlist_head; hl != NULL; hl = hl->next)
+ for (hostlist_t *hl = hostlist_head; hl != NULL; hl = hl->next)
{
hl->pkg_sent = 0;
hl->pkg_recv = 0;
return (-1);
} /* if (ping_thread_error != 0) */
- for (hl = hostlist_head; hl != NULL; hl = hl->next) /* {{{ */
+ for (hostlist_t *hl = hostlist_head; hl != NULL; hl = hl->next) /* {{{ */
{
uint32_t pkg_sent;
uint32_t pkg_recv;
*/
#include "collectd.h"
+
#include "common.h"
-#include "configfile.h"
#include "plugin.h"
#include "utils_cache.h"
static void c_psql_database_delete (void *data)
{
- size_t i;
-
c_psql_database_t *db = data;
--db->ref_cnt;
db->conn = NULL;
if (db->q_prep_areas)
- for (i = 0; i < db->queries_num; ++i)
+ for (size_t i = 0; i < db->queries_num; ++i)
udb_query_delete_preparation_area (db->q_prep_areas[i]);
free (db->q_prep_areas);
{
const char *params[db->max_params_num];
char interval[64];
- int i;
if ((data == NULL) || (data->params_num == 0))
return (c_psql_exec_query_noparams (db, q));
assert (db->max_params_num >= data->params_num);
- for (i = 0; i < data->params_num; ++i) {
+ for (int i = 0; i < data->params_num; ++i) {
switch (data->params[i]) {
case C_PSQL_PARAM_HOST:
params[i] = C_PSQL_IS_UNIX_DOMAIN_SOCKET (db->host)
int rows_num;
int status;
- int row, col;
/* The user data may hold parameter information, but may be NULL. */
data = udb_query_get_user_data (q);
BAIL_OUT (-1);
}
- for (col = 0; col < column_num; ++col) {
+ for (int col = 0; col < column_num; ++col) {
/* Pointers returned by `PQfname' are freed by `PQclear' via
* `BAIL_OUT'. */
column_names[col] = PQfname (res, col);
BAIL_OUT (-1);
}
- for (row = 0; row < rows_num; ++row) {
+ for (int row = 0; row < rows_num; ++row) {
+ int col;
for (col = 0; col < column_num; ++col) {
/* Pointers returned by `PQgetvalue' are freed by `PQclear' via
* `BAIL_OUT'. */
c_psql_database_t *db;
int success = 0;
- size_t i;
if ((ud == NULL) || (ud->data == NULL)) {
log_err ("c_psql_read: Invalid user data.");
return -1;
}
- for (i = 0; i < db->queries_num; ++i)
+ for (size_t i = 0; i < db->queries_num; ++i)
{
udb_query_preparation_area_t *prep_area;
udb_query_t *q;
{
char *str_ptr;
size_t str_len;
- size_t i;
str_ptr = string;
str_len = string_len;
- for (i = 0; i < ds->ds_num; ++i) {
+ for (size_t i = 0; i < ds->ds_num; ++i) {
int status = ssnprintf (str_ptr, str_len, ",'%s'", ds->ds[i].name);
if (status < 1)
{
char *str_ptr;
size_t str_len;
- size_t i;
str_ptr = string;
str_len = string_len;
- for (i = 0; i < ds->ds_num; ++i) {
+ for (size_t i = 0; i < ds->ds_num; ++i) {
int status;
if (store_rates)
size_t str_len;
gauge_t *rates = NULL;
- size_t i;
str_ptr = string;
str_len = string_len;
- for (i = 0; i < vl->values_len; ++i) {
+ for (size_t i = 0; i < vl->values_len; ++i) {
int status = 0;
if ((ds->ds[i].type != DS_TYPE_GAUGE)
const char *params[9];
int success = 0;
- size_t i;
if ((ud == NULL) || (ud->data == NULL)) {
log_err ("c_psql_write: Invalid user data.");
assert (db->database != NULL);
assert (db->writers != NULL);
- if (rfc3339nano (time_str, sizeof (time_str), vl->time) != 0) {
+ if (rfc3339nano_local (time_str, sizeof (time_str), vl->time) != 0) {
log_err ("c_psql_write: Failed to convert time to RFC 3339 format");
return -1;
}
&& (db->next_commit == 0))
c_psql_begin (db);
- for (i = 0; i < db->writers_num; ++i) {
+ for (size_t i = 0; i < db->writers_num; ++i) {
c_psql_writer_t *writer;
PGresult *res;
{
c_psql_database_t **dbs = databases;
size_t dbs_num = databases_num;
- size_t i;
if ((ud != NULL) && (ud->data != NULL)) {
dbs = (void *)&ud->data;
dbs_num = 1;
}
- for (i = 0; i < dbs_num; ++i) {
+ for (size_t i = 0; i < dbs_num; ++i) {
c_psql_database_t *db = dbs[i];
/* don't commit if the timeout is larger than the regular commit
static int c_psql_shutdown (void)
{
- size_t i = 0;
-
_Bool had_flush = 0;
plugin_unregister_read_group ("postgresql");
- for (i = 0; i < databases_num; ++i) {
+ for (size_t i = 0; i < databases_num; ++i) {
c_psql_database_t *db = databases[i];
if (db->writers_num > 0) {
c_psql_writer_t *tmp;
int status = 0;
- int i;
if ((ci->values_num != 1)
|| (ci->values[0].type != OCONFIG_TYPE_STRING)) {
writer->statement = NULL;
writer->store_rates = 1;
- for (i = 0; i < ci->children_num; ++i) {
+ for (int i = 0; i < ci->children_num; ++i) {
oconfig_item_t *c = ci->children + i;
if (strcasecmp ("Statement", c->key) == 0)
c_psql_database_t *db;
char cb_name[DATA_MAX_NAME_LEN];
- user_data_t ud;
-
static _Bool have_flush = 0;
- int i;
-
if ((1 != ci->values_num)
|| (OCONFIG_TYPE_STRING != ci->values[0].type)) {
log_err ("<Database> expects a single string argument.");
return 1;
}
- memset (&ud, 0, sizeof (ud));
-
db = c_psql_database_new (ci->values[0].value.string);
if (db == NULL)
return -1;
- for (i = 0; i < ci->children_num; ++i) {
+ for (int i = 0; i < ci->children_num; ++i) {
oconfig_item_t *c = ci->children + i;
if (0 == strcasecmp (c->key, "Host"))
/* If no `Query' options were given, add the default queries.. */
if ((db->queries_num == 0) && (db->writers_num == 0)){
- for (i = 0; i < def_queries_num; i++)
+ for (int i = 0; i < def_queries_num; i++)
udb_query_pick_from_list_by_name (def_queries[i],
queries, queries_num,
&db->queries, &db->queries_num);
}
}
- for (i = 0; (size_t)i < db->queries_num; ++i) {
+ for (int i = 0; (size_t)i < db->queries_num; ++i) {
c_psql_user_data_t *data;
data = udb_query_get_user_data (db->queries[i]);
if ((data != NULL) && (data->params_num > db->max_params_num))
}
}
- ud.data = db;
- ud.free_func = c_psql_database_delete;
-
ssnprintf (cb_name, sizeof (cb_name), "postgresql-%s", db->instance);
+ user_data_t ud = {
+ .data = db,
+ .free_func = c_psql_database_delete
+ };
+
if (db->queries_num > 0) {
++db->ref_cnt;
plugin_register_complex_read ("postgresql", cb_name, c_psql_read,
{
static int have_def_config = 0;
- int i;
-
if (0 == have_def_config) {
oconfig_item_t *c;
"any queries - please check your installation.");
}
- for (i = 0; i < ci->children_num; ++i) {
+ for (int i = 0; i < ci->children_num; ++i) {
oconfig_item_t *c = ci->children + i;
if (0 == strcasecmp (c->key, "Query"))
**/
#include "collectd.h"
+
#include "common.h"
#include "plugin.h"
-#include "configfile.h"
#include "utils_llist.h"
#include <sys/stat.h>
/* <https://doc.powerdns.com/md/recursor/stats/> */
static void submit (const char *plugin_instance, /* {{{ */
- const char *pdns_type, const char *value)
+ const char *pdns_type, const char *value_str)
{
value_list_t vl = VALUE_LIST_INIT;
- value_t values[1];
+ value_t value;
const char *type = NULL;
const char *type_instance = NULL;
if (i >= lookup_table_length)
{
INFO ("powerdns plugin: submit: Not found in lookup table: %s = %s;",
- pdns_type, value);
+ pdns_type, value_str);
return;
}
return;
}
- if (0 != parse_value (value, &values[0], ds->ds[0].type))
+ if (0 != parse_value (value_str, &value, ds->ds[0].type))
{
ERROR ("powerdns plugin: Cannot convert `%s' "
- "to a number.", value);
+ "to a number.", value_str);
return;
}
- vl.values = values;
+ vl.values = &value;
vl.values_len = 1;
sstrncpy (vl.host, hostname_g, sizeof (vl.host));
sstrncpy (vl.plugin, "powerdns", sizeof (vl.plugin));
char *buffer = NULL;
size_t buffer_size = 0;
- struct sockaddr_un sa_unix;
+ struct sockaddr_un sa_unix = { 0 };
struct timeval stv_timeout;
cdtime_t cdt_timeout;
return (-1);
}
- memset (&sa_unix, 0, sizeof (sa_unix));
sa_unix.sun_family = AF_UNIX;
sstrncpy (sa_unix.sun_path,
(local_sockpath != NULL) ? local_sockpath : PDNS_LOCAL_SOCKPATH,
saveptr = NULL;
while ((key = strtok_r (dummy, ",", &saveptr)) != NULL)
{
- int i;
-
dummy = NULL;
value = strchr (key, '=');
continue;
/* Check if this item was requested. */
+ int i;
for (i = 0; i < fields_num; i++)
if (strcasecmp (key, fields[i]) == 0)
break;
static int powerdns_config_add_collect (list_item_t *li, /* {{{ */
oconfig_item_t *ci)
{
- int i;
char **temp;
if (ci->values_num < 1)
return (-1);
}
- for (i = 0; i < ci->values_num; i++)
+ for (int i = 0; i < ci->values_num; i++)
if (ci->values[i].type != OCONFIG_TYPE_STRING)
{
WARNING ("powerdns plugin: Only string arguments are allowed to "
}
li->fields = temp;
- for (i = 0; i < ci->values_num; i++)
+ for (int i = 0; i < ci->values_num; i++)
{
li->fields[li->fields_num] = strdup (ci->values[i].value.string);
if (li->fields[li->fields_num] == NULL)
list_item_t *item;
int status;
- int i;
if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING))
{
}
status = 0;
- for (i = 0; i < ci->children_num; i++)
+ for (int i = 0; i < ci->children_num; i++)
{
oconfig_item_t *option = ci->children + i;
static int powerdns_config (oconfig_item_t *ci) /* {{{ */
{
- int i;
-
DEBUG ("powerdns plugin: powerdns_config (ci = %p);", (void *) ci);
if (list == NULL)
}
}
- for (i = 0; i < ci->children_num; i++)
+ for (int i = 0; i < ci->children_num; i++)
{
oconfig_item_t *option = ci->children + i;
static int powerdns_read (void)
{
- llentry_t *e;
-
- for (e = llist_head (list); e != NULL; e = e->next)
+ for (llentry_t *e = llist_head (list); e != NULL; e = e->next)
{
list_item_t *item = e->value;
item->func (item);
static int powerdns_shutdown (void)
{
- llentry_t *e;
-
if (list == NULL)
return (0);
- for (e = llist_head (list); e != NULL; e = e->next)
+ for (llentry_t *e = llist_head (list); e != NULL; e = e->next)
{
list_item_t *item = (list_item_t *) e->value;
e->value = NULL;
**/
#include "collectd.h"
+
#include "common.h"
#include "plugin.h"
-#include "configfile.h"
/* Include header files for the mach system, if they exist.. */
#if HAVE_THREAD_INFO
/* add process entry to 'instances' of process 'name' (or refresh it) */
static void ps_list_add (const char *name, const char *cmdline, procstat_entry_t *entry)
{
- procstat_t *ps;
procstat_entry_t *pse;
if (entry->id == 0)
return;
- for (ps = list_head_g; ps != NULL; ps = ps->next)
+ for (procstat_t *ps = list_head_g; ps != NULL; ps = ps->next)
{
_Bool want_init;
/* remove old entries from instances of processes in list_head_g */
static void ps_list_reset (void)
{
- procstat_t *ps;
procstat_entry_t *pse;
procstat_entry_t *pse_prev;
- for (ps = list_head_g; ps != NULL; ps = ps->next)
+ for (procstat_t *ps = list_head_g; ps != NULL; ps = ps->next)
{
ps->num_proc = 0;
ps->num_lwp = 0;
/* put all pre-defined 'Process' names from config to list_head_g tree */
static int ps_config (oconfig_item_t *ci)
{
- int i;
-
#if KERNEL_LINUX
const size_t max_procname_len = 15;
#elif KERNEL_SOLARIS || KERNEL_FREEBSD
const size_t max_procname_len = MAXCOMLEN -1;
#endif
- for (i = 0; i < ci->children_num; ++i) {
+ for (int i = 0; i < ci->children_num; ++i) {
oconfig_item_t *c = ci->children + i;
if (strcasecmp (c->key, "Process") == 0)
/* submit global state (e.g.: qty of zombies, running, etc..) */
static void ps_submit_state (const char *state, 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, "processes", sizeof (vl.plugin));
/* submit info about specific process (e.g.: memory taken, cpu usage, etc..) */
static void ps_submit_proc_list (procstat_t *ps)
{
- value_t values[2];
value_list_t vl = VALUE_LIST_INIT;
+ value_t values[2];
vl.values = values;
- vl.values_len = 2;
sstrncpy (vl.host, hostname_g, sizeof (vl.host));
sstrncpy (vl.plugin, "processes", sizeof (vl.plugin));
sstrncpy (vl.plugin_instance, ps->name, sizeof (vl.plugin_instance));
#if KERNEL_LINUX || KERNEL_SOLARIS
static void ps_submit_fork_rate (derive_t value)
{
- value_t values[1];
value_list_t vl = VALUE_LIST_INIT;
- values[0].derive = value;
-
- vl.values = values;
+ vl.values = &(value_t) { .derive = value };
vl.values_len = 1;
sstrncpy(vl.host, hostname_g, sizeof (vl.host));
sstrncpy(vl.plugin, "processes", sizeof (vl.plugin));
static int read_fork_rate (void)
{
extern kstat_ctl_t *kc;
- kstat_t *ksp_chain = NULL;
derive_t result = 0;
if (kc == NULL)
return (-1);
- for (ksp_chain = kc->kc_chain;
+ for (kstat_t *ksp_chain = kc->kc_chain;
ksp_chain != NULL;
ksp_chain = ksp_chain->ks_next)
{
#if HAVE_THREAD_INFO
kern_return_t status;
- int pset;
processor_set_t port_pset_priv;
- int task;
task_array_t task_list;
mach_msg_type_number_t task_list_len;
int task_pid;
char task_name[MAXCOMLEN + 1];
- int thread;
thread_act_array_t thread_list;
mach_msg_type_number_t thread_list_len;
thread_basic_info_data_t thread_data;
* Tasks are assigned to sets of processors, so that's where you go to
* get a list.
*/
- for (pset = 0; pset < pset_list_len; pset++)
+ for (mach_msg_type_number_t pset = 0; pset < pset_list_len; pset++)
{
if ((status = host_processor_set_priv (port_host_self,
pset_list[pset],
continue;
}
- for (task = 0; task < task_list_len; task++)
+ for (mach_msg_type_number_t task = 0; task < task_list_len; task++)
{
ps = NULL;
if (mach_get_task_name (task_list[task],
continue; /* with next task_list */
}
- for (thread = 0; thread < thread_list_len; thread++)
+ for (mach_msg_type_number_t thread = 0; thread < thread_list_len; thread++)
{
thread_data_len = THREAD_BASIC_INFO_COUNT;
status = thread_info (thread_list[thread],
procstat_entry_t pse;
char state;
- procstat_t *ps_ptr;
-
running = sleeping = zombies = stopped = paging = blocked = 0;
ps_list_reset ();
ps_submit_state ("paging", paging);
ps_submit_state ("blocked", blocked);
- for (ps_ptr = list_head_g; ps_ptr != NULL; ps_ptr = ps_ptr->next)
+ for (procstat_t *ps_ptr = list_head_g; ps_ptr != NULL; ps_ptr = ps_ptr->next)
ps_submit_proc_list (ps_ptr);
read_fork_rate();
struct kinfo_proc *procs; /* array of processes */
struct kinfo_proc *proc_ptr = NULL;
int count; /* returns number of processes */
- int i;
- procstat_t *ps_ptr;
procstat_entry_t pse;
ps_list_reset ();
}
/* Iterate through the processes in kinfo_proc */
- for (i = 0; i < count; i++)
+ for (int i = 0; i < count; i++)
{
/* Create only one process list entry per _process_, i.e.
* filter out threads (duplicate PID entries). */
ps_submit_state ("idle", idle);
ps_submit_state ("wait", wait);
- for (ps_ptr = list_head_g; ps_ptr != NULL; ps_ptr = ps_ptr->next)
+ for (procstat_t *ps_ptr = list_head_g; ps_ptr != NULL; ps_ptr = ps_ptr->next)
ps_submit_proc_list (ps_ptr);
/* #endif HAVE_LIBKVM_GETPROCS && HAVE_STRUCT_KINFO_PROC_FREEBSD */
struct kinfo_proc *procs; /* array of processes */
struct kinfo_proc *proc_ptr = NULL;
int count; /* returns number of processes */
- int i;
- procstat_t *ps_ptr;
procstat_entry_t pse;
ps_list_reset ();
}
/* Iterate through the processes in kinfo_proc */
- for (i = 0; i < count; i++)
+ for (int i = 0; i < count; i++)
{
/* Create only one process list entry per _process_, i.e.
* filter out threads (duplicate PID entries). */
ps_submit_state ("idle", idle);
ps_submit_state ("dead", dead);
- for (ps_ptr = list_head_g; ps_ptr != NULL; ps_ptr = ps_ptr->next)
+ for (procstat_t *ps_ptr = list_head_g; ps_ptr != NULL; ps_ptr = ps_ptr->next)
ps_submit_proc_list (ps_ptr);
/* #endif HAVE_LIBKVM_GETPROCS && HAVE_STRUCT_KINFO_PROC_OPENBSD */
pid_t pindex = 0;
int nprocs;
- procstat_t *ps;
procstat_entry_t pse;
ps_list_reset ();
/* fdsinfo = */ NULL, sizeof(struct fdsinfo64),
&pindex, MAXPROCENTRY)) > 0)
{
- int i;
-
- for (i = 0; i < nprocs; i++)
+ for (int i = 0; i < nprocs; i++)
{
tid64_t thindex;
int nthreads;
ps_submit_state ("paging", paging);
ps_submit_state ("blocked", blocked);
- for (ps = list_head_g; ps != NULL; ps = ps->next)
+ for (procstat_t *ps = list_head_g; ps != NULL; ps = ps->next)
ps_submit_proc_list (ps);
/* #endif HAVE_PROCINFO_H */
DIR *proc;
int status;
- procstat_t *ps_ptr;
char state;
char cmdline[PRARGSZ];
ps_submit_state ("system", system);
ps_submit_state ("orphan", orphan);
- for (ps_ptr = list_head_g; ps_ptr != NULL; ps_ptr = ps_ptr->next)
+ for (procstat_t *ps_ptr = list_head_g; ps_ptr != NULL; ps_ptr = ps_ptr->next)
ps_submit_proc_list (ps_ptr);
read_fork_rate();
**/
#include "collectd.h"
+
#include "common.h"
#include "plugin.h"
#include "utils_ignorelist.h"
static void submit (const char *protocol_name,
const char *str_key, const char *str_value)
{
- value_t values[1];
+ value_t value;
value_list_t vl = VALUE_LIST_INIT;
int status;
- status = parse_value (str_value, values, DS_TYPE_DERIVE);
+ status = parse_value (str_value, &value, DS_TYPE_DERIVE);
if (status != 0)
{
ERROR ("protocols plugin: Parsing string as integer failed: %s",
return;
}
- vl.values = values;
+ vl.values = &value;
vl.values_len = 1;
sstrncpy (vl.host, hostname_g, sizeof (vl.host));
sstrncpy (vl.plugin, "protocols", sizeof (vl.plugin));
#include <structmember.h>
#include "collectd.h"
+
#include "common.h"
#include "cpython.h"
#include <signal.h>
#include "collectd.h"
+
#include "common.h"
#include "cpython.h"
"The callback function will be called with two or three parameters:\n"
"timeout: Indicates that only data older than 'timeout' seconds is to\n"
" be flushed.\n"
- "id: Specifies which values are to be flushed.\n"
+ "id: Specifies which values are to be flushed. Might be None.\n"
"data: The optional data parameter passed to the register function.\n"
" If the parameter was omitted it will be omitted here, too.";
" data if it was supplied.";
-static int do_interactive = 0;
+static pthread_t main_thread;
+static PyOS_sighandler_t python_sigint_handler;
+static _Bool do_interactive = 0;
/* This is our global thread state. Python saves some stuff in thread-local
* storage. So if we allow the interpreter to run in the background
static cpy_callback_t *cpy_init_callbacks;
static cpy_callback_t *cpy_shutdown_callbacks;
+/* Make sure to hold the GIL while modifying these. */
+static int cpy_shutdown_triggered = 0;
+static int cpy_num_callbacks = 0;
+
static void cpy_destroy_user_data(void *data) {
cpy_callback_t *c = data;
free(c->name);
+ CPY_LOCK_THREADS
Py_DECREF(c->callback);
Py_XDECREF(c->data);
free(c);
+ --cpy_num_callbacks;
+ if (!cpy_num_callbacks && cpy_shutdown_triggered) {
+ Py_Finalize();
+ return;
+ }
+ CPY_RELEASE_THREADS
}
/* You must hold the GIL to call this function!
}
void cpy_log_exception(const char *context) {
- int l = 0, i;
+ int l = 0;
const char *typename = NULL, *message = NULL;
PyObject *type, *value, *traceback, *tn, *m, *list;
if (list)
l = PyObject_Length(list);
- for (i = 0; i < l; ++i) {
+ for (int i = 0; i < l; ++i) {
PyObject *line;
char const *msg;
char *cpy;
}
static int cpy_write_callback(const data_set_t *ds, const value_list_t *value_list, user_data_t *data) {
- size_t i;
cpy_callback_t *c = data->data;
PyObject *ret, *list, *temp, *dict = NULL;
Values *v;
cpy_log_exception("write callback");
CPY_RETURN_FROM_THREADS 0;
}
- for (i = 0; i < value_list->values_len; ++i) {
+ for (size_t i = 0; i < value_list->values_len; ++i) {
if (ds->ds[i].type == DS_TYPE_COUNTER) {
PyList_SetItem(list, i, PyLong_FromUnsignedLongLong(value_list->values[i].counter));
} else if (ds->ds[i].type == DS_TYPE_GAUGE) {
}
dict = PyDict_New(); /* New reference. */
if (value_list->meta) {
- int num;
char **table;
meta_data_t *meta = value_list->meta;
- num = meta_data_toc(meta, &table);
- for (i = 0; i < num; ++i) {
+ int num = meta_data_toc(meta, &table);
+ for (int i = 0; i < num; ++i) {
int type;
char *string;
int64_t si;
PyObject *ret, *text;
CPY_LOCK_THREADS
- text = cpy_string_to_unicode_or_bytes(id);
+ if (id) {
+ text = cpy_string_to_unicode_or_bytes(id);
+ } else {
+ text = Py_None;
+ Py_INCREF(text);
+ }
if (c->data == NULL)
ret = PyObject_CallFunction(c->callback, "iN", timeout, text); /* New reference. */
else
c->callback = callback;
c->data = data;
c->next = *list_head;
+ ++cpy_num_callbacks;
*list_head = c;
Py_XDECREF(mod);
PyMem_Free(name);
}
static PyObject *cpy_get_dataset(PyObject *self, PyObject *args) {
- size_t i;
char *name;
const data_set_t *ds;
PyObject *list, *tuple;
return NULL;
}
list = PyList_New(ds->ds_num); /* New reference. */
- for (i = 0; i < ds->ds_num; ++i) {
+ for (size_t i = 0; i < ds->ds_num; ++i) {
tuple = PyTuple_New(4);
PyTuple_SET_ITEM(tuple, 0, cpy_string_to_unicode_or_bytes(ds->ds[i].name));
PyTuple_SET_ITEM(tuple, 1, cpy_string_to_unicode_or_bytes(DS_TYPE_TO_STRING(ds->ds[i].type)));
char buf[512];
reg_function_t *register_function = (reg_function_t *) reg;
cpy_callback_t *c = NULL;
- user_data_t user_data;
char *name = NULL;
PyObject *callback = NULL, *data = NULL;
static char *kwlist[] = {"callback", "data", "name", NULL};
c->data = data;
c->next = NULL;
- memset (&user_data, 0, sizeof (user_data));
- user_data.free_func = cpy_destroy_user_data;
- user_data.data = c;
+ register_function(buf, handler, &(user_data_t) {
+ .data = c,
+ .free_func = cpy_destroy_user_data,
+ });
- register_function(buf, handler, &user_data);
+ ++cpy_num_callbacks;
return cpy_string_to_unicode_or_bytes(buf);
}
static PyObject *cpy_register_read(PyObject *self, PyObject *args, PyObject *kwds) {
char buf[512];
cpy_callback_t *c = NULL;
- user_data_t user_data;
double interval = 0;
char *name = NULL;
PyObject *callback = NULL, *data = NULL;
c->data = data;
c->next = NULL;
- memset (&user_data, 0, sizeof (user_data));
- user_data.free_func = cpy_destroy_user_data;
- user_data.data = c;
-
plugin_register_complex_read(/* group = */ "python", buf,
- cpy_read_callback, DOUBLE_TO_CDTIME_T (interval), &user_data);
+ cpy_read_callback, DOUBLE_TO_CDTIME_T (interval),
+ &(user_data_t) {
+ .data = c,
+ .free_func = cpy_destroy_user_data,
+ });
+ ++cpy_num_callbacks;
return cpy_string_to_unicode_or_bytes(buf);
}
PyErr_Format(PyExc_RuntimeError, "Unable to unregister %s callback '%s'.", desc, name);
return NULL;
}
- /* Yes, this is actually save. To call this function the caller has to
- * hold the GIL. Well, save as long as there is only one GIL anyway ... */
+ /* Yes, this is actually safe. To call this function the caller has to
+ * hold the GIL. Well, safe as long as there is only one GIL anyway ... */
if (prev == NULL)
*list_head = tmp->next;
else
Py_RETURN_NONE;
}
+static void cpy_unregister_list(cpy_callback_t **list_head) {
+ cpy_callback_t *cur, *next;
+ for (cur = *list_head; cur; cur = next) {
+ next = cur->next;
+ cpy_destroy_user_data(cur);
+ }
+ *list_head = NULL;
+}
+
typedef int cpy_unregister_function_t(const char *name);
static PyObject *cpy_unregister_generic_userdata(cpy_unregister_function_t *unreg, PyObject *arg, const char *desc) {
};
static int cpy_shutdown(void) {
- cpy_callback_t *c;
PyObject *ret;
- /* This can happen if the module was loaded but not configured. */
- if (state != NULL)
- PyEval_RestoreThread(state);
+ if (!state) {
+ printf("================================================================\n");
+ printf("collectd shutdown while running an interactive session. This will\n");
+ printf("probably leave your terminal in a mess.\n");
+ printf("Run the command \"reset\" to get it back into a usable state.\n");
+ printf("You can press Ctrl+D in the interactive session to\n");
+ printf("close collectd and avoid this problem in the future.\n");
+ printf("================================================================\n");
+ }
+
+ CPY_LOCK_THREADS
- for (c = cpy_shutdown_callbacks; c; c = c->next) {
+ for (cpy_callback_t *c = cpy_shutdown_callbacks; c; c = c->next) {
ret = PyObject_CallFunctionObjArgs(c->callback, c->data, (void *) 0); /* New reference. */
if (ret == NULL)
cpy_log_exception("shutdown callback");
Py_DECREF(ret);
}
PyErr_Print();
- Py_Finalize();
- return 0;
-}
-static void cpy_int_handler(int sig) {
- return;
+ Py_BEGIN_ALLOW_THREADS
+ cpy_unregister_list(&cpy_config_callbacks);
+ cpy_unregister_list(&cpy_init_callbacks);
+ cpy_unregister_list(&cpy_shutdown_callbacks);
+ cpy_shutdown_triggered = 1;
+ Py_END_ALLOW_THREADS
+
+ if (!cpy_num_callbacks) {
+ Py_Finalize();
+ return 0;
+ }
+
+ CPY_RELEASE_THREADS
+ return 0;
}
-static void *cpy_interactive(void *data) {
- sigset_t sigset;
- struct sigaction sig_int_action, old;
+static void *cpy_interactive(void *pipefd) {
+ PyOS_sighandler_t cur_sig;
/* Signal handler in a plugin? Bad stuff, but the best way to
* handle it I guess. In an interactive session people will
* mess. Chances are, this isn't what the user wanted to do.
*
* So this is the plan:
- * 1. Block SIGINT in the main thread.
- * 2. Install our own signal handler that does nothing.
- * 3. Unblock SIGINT in the interactive thread.
+ * 1. Restore Python's own signal handler
+ * 2. Tell Python we just forked so it will accept this thread
+ * as the main one. No version of Python will ever handle
+ * interrupts anywhere but in the main thread.
+ * 3. After the interactive loop is done, restore collectd's
+ * SIGINT handler.
+ * 4. Raise SIGINT for a clean shutdown. The signal is sent to
+ * the main thread to ensure it wakes up the main interval
+ * sleep so that collectd shuts down immediately not in 10
+ * seconds.
*
* This will make sure that SIGINT won't kill collectd but
- * still interrupt syscalls like sleep and pause.
- * It does not raise a KeyboardInterrupt exception because so
- * far nobody managed to figure out how to do that. */
- memset (&sig_int_action, '\0', sizeof (sig_int_action));
- sig_int_action.sa_handler = cpy_int_handler;
- sigaction (SIGINT, &sig_int_action, &old);
-
- sigemptyset(&sigset);
- sigaddset(&sigset, SIGINT);
- pthread_sigmask(SIG_UNBLOCK, &sigset, NULL);
- PyEval_AcquireThread(state);
+ * still interrupt syscalls like sleep and pause. */
+
if (PyImport_ImportModule("readline") == NULL) {
/* This interactive session will suck. */
cpy_log_exception("interactive session init");
}
+ cur_sig = PyOS_setsig(SIGINT, python_sigint_handler);
+ PyOS_AfterFork();
+ PyEval_InitThreads();
+ close(*(int *) pipefd);
PyRun_InteractiveLoop(stdin, "<stdin>");
+ PyOS_setsig(SIGINT, cur_sig);
PyErr_Print();
- PyEval_ReleaseThread(state);
+ state = PyEval_SaveThread();
NOTICE("python: Interactive interpreter exited, stopping collectd ...");
- /* Restore the original collectd SIGINT handler and raise SIGINT.
- * The main thread still has SIGINT blocked and there's nothing we
- * can do about that so this thread will handle it. But that's not
- * important, except that it won't interrupt the main loop and so
- * it might take a few seconds before collectd really shuts down. */
- sigaction (SIGINT, &old, NULL);
- raise(SIGINT);
- pause();
+ pthread_kill(main_thread, SIGINT);
return NULL;
}
static int cpy_init(void) {
- cpy_callback_t *c;
PyObject *ret;
+ int pipefd[2];
+ char buf;
static pthread_t thread;
- sigset_t sigset;
if (!Py_IsInitialized()) {
WARNING("python: Plugin loaded but not configured.");
plugin_unregister_shutdown("python");
+ Py_Finalize();
return 0;
}
- PyEval_InitThreads();
- /* Now it's finally OK to use python threads. */
- for (c = cpy_init_callbacks; c; c = c->next) {
+ main_thread = pthread_self();
+ if (do_interactive) {
+ if (pipe(pipefd)) {
+ ERROR("python: Unable to create pipe.");
+ return 1;
+ }
+ if (plugin_thread_create(&thread, NULL, cpy_interactive, pipefd + 1)) {
+ ERROR("python: Error creating thread for interactive interpreter.");
+ }
+ if(read(pipefd[0], &buf, 1))
+ ;
+ (void)close(pipefd[0]);
+ } else {
+ PyEval_InitThreads();
+ state = PyEval_SaveThread();
+ }
+ CPY_LOCK_THREADS
+ for (cpy_callback_t *c = cpy_init_callbacks; c; c = c->next) {
ret = PyObject_CallFunctionObjArgs(c->callback, c->data, (void *) 0); /* New reference. */
if (ret == NULL)
cpy_log_exception("init callback");
else
Py_DECREF(ret);
}
- sigemptyset(&sigset);
- sigaddset(&sigset, SIGINT);
- pthread_sigmask(SIG_BLOCK, &sigset, NULL);
- state = PyEval_SaveThread();
- if (do_interactive) {
- if (plugin_thread_create(&thread, NULL, cpy_interactive, NULL)) {
- ERROR("python: Error creating thread for interactive interpreter.");
- }
- }
+ CPY_RELEASE_THREADS
return 0;
}
static PyObject *cpy_oconfig_to_pyconfig(oconfig_item_t *ci, PyObject *parent) {
- int i;
PyObject *item, *values, *children, *tmp;
if (parent == NULL)
parent = Py_None;
values = PyTuple_New(ci->values_num); /* New reference. */
- for (i = 0; i < ci->values_num; ++i) {
+ for (int i = 0; i < ci->values_num; ++i) {
if (ci->values[i].type == OCONFIG_TYPE_STRING) {
PyTuple_SET_ITEM(values, i, cpy_string_to_unicode_or_bytes(ci->values[i].value.string));
} else if (ci->values[i].type == OCONFIG_TYPE_NUMBER) {
if (item == NULL)
return NULL;
children = PyTuple_New(ci->children_num); /* New reference. */
- for (i = 0; i < ci->children_num; ++i) {
+ for (int i = 0; i < ci->children_num; ++i) {
PyTuple_SET_ITEM(children, i, cpy_oconfig_to_pyconfig(ci->children + i, item));
}
tmp = ((Config *) item)->children;
#endif
static int cpy_init_python(void) {
+ PyOS_sighandler_t cur_sig;
PyObject *sys;
PyObject *module;
char *argv = "";
#endif
+ /* Chances are the current signal handler is already SIG_DFL, but let's make sure. */
+ cur_sig = PyOS_setsig(SIGINT, SIG_DFL);
Py_Initialize();
+ python_sigint_handler = PyOS_setsig(SIGINT, cur_sig);
PyType_Ready(&ConfigType);
PyType_Ready(&PluginDataType);
}
static int cpy_config(oconfig_item_t *ci) {
- int i;
PyObject *tb;
+ int status = 0;
/* Ok in theory we shouldn't do initialization at this point
* but we have to. In order to give python scripts a chance
if (!Py_IsInitialized() && cpy_init_python()) return 1;
- for (i = 0; i < ci->children_num; ++i) {
+ for (int i = 0; i < ci->children_num; ++i) {
oconfig_item_t *item = ci->children + i;
if (strcasecmp(item->key, "Interactive") == 0) {
- if (item->values_num != 1 || item->values[0].type != OCONFIG_TYPE_BOOLEAN)
+ if (cf_util_get_boolean(item, &do_interactive) != 0) {
+ status = 1;
continue;
- do_interactive = item->values[0].value.boolean;
+ }
} else if (strcasecmp(item->key, "Encoding") == 0) {
- if (item->values_num != 1 || item->values[0].type != OCONFIG_TYPE_STRING)
+ char *encoding = NULL;
+ if (cf_util_get_string(item, &encoding) != 0) {
+ status = 1;
continue;
+ }
#ifdef IS_PY3K
- NOTICE("python: \"Encoding\" was used in the config file but Python3 was used, which does not support changing encodings. Ignoring this.");
+ ERROR("python: \"Encoding\" was used in the config file but Python3 was used, which does not support changing encodings");
+ status = 1;
+ sfree(encoding);
+ continue;
#else
/* Why is this even necessary? And undocumented? */
- if (PyUnicode_SetDefaultEncoding(item->values[0].value.string))
+ if (PyUnicode_SetDefaultEncoding(encoding)) {
cpy_log_exception("setting default encoding");
+ status = 1;
+ }
#endif
+ sfree(encoding);
} else if (strcasecmp(item->key, "LogTraces") == 0) {
- if (item->values_num != 1 || item->values[0].type != OCONFIG_TYPE_BOOLEAN)
+ _Bool log_traces;
+ if (cf_util_get_boolean(item, &log_traces) != 0) {
+ status = 1;
continue;
- if (!item->values[0].value.boolean) {
+ }
+ if (!log_traces) {
Py_XDECREF(cpy_format_exception);
cpy_format_exception = NULL;
continue;
tb = PyImport_ImportModule("traceback"); /* New reference. */
if (tb == NULL) {
cpy_log_exception("python initialization");
+ status = 1;
continue;
}
cpy_format_exception = PyObject_GetAttrString(tb, "format_exception"); /* New reference. */
Py_DECREF(tb);
- if (cpy_format_exception == NULL)
+ if (cpy_format_exception == NULL) {
cpy_log_exception("python initialization");
+ status = 1;
+ }
} else if (strcasecmp(item->key, "ModulePath") == 0) {
char *dir = NULL;
PyObject *dir_object;
- if (cf_util_get_string(item, &dir) != 0)
+ if (cf_util_get_string(item, &dir) != 0) {
+ status = 1;
continue;
+ }
dir_object = cpy_string_to_unicode_or_bytes(dir); /* New reference. */
if (dir_object == NULL) {
ERROR("python plugin: Unable to convert \"%s\" to "
"a python object.", dir);
free(dir);
cpy_log_exception("python initialization");
+ status = 1;
continue;
}
if (PyList_Insert(sys_path, 0, dir_object) != 0) {
ERROR("python plugin: Unable to prepend \"%s\" to "
"python module path.", dir);
cpy_log_exception("python initialization");
+ status = 1;
}
Py_DECREF(dir_object);
free(dir);
char *module_name = NULL;
PyObject *module;
- if (cf_util_get_string(item, &module_name) != 0)
+ if (cf_util_get_string(item, &module_name) != 0) {
+ status = 1;
continue;
+ }
module = PyImport_ImportModule(module_name); /* New reference. */
if (module == NULL) {
ERROR("python plugin: Error importing module \"%s\".", module_name);
cpy_log_exception("importing module");
+ status = 1;
}
free(module_name);
Py_XDECREF(module);
cpy_callback_t *c;
PyObject *ret;
- if (cf_util_get_string(item, &name) != 0)
+ if (cf_util_get_string(item, &name) != 0) {
+ status = 1;
continue;
+ }
for (c = cpy_config_callbacks; c; c = c->next) {
if (strcasecmp(c->name + 7, name) == 0)
break;
else
ret = PyObject_CallFunction(c->callback, "NO",
cpy_oconfig_to_pyconfig(item, NULL), c->data); /* New reference. */
- if (ret == NULL)
+ if (ret == NULL) {
cpy_log_exception("loading module");
- else
+ status = 1;
+ } else
Py_DECREF(ret);
} else {
- WARNING("python plugin: Ignoring unknown config key \"%s\".", item->key);
+ ERROR("python plugin: Unknown config key \"%s\".", item->key);
+ status = 1;
}
}
- return 0;
+ return (status);
}
void module_register(void) {
#include <structmember.h>
#include "collectd.h"
+
#include "common.h"
#include "cpython.h"
}
static meta_data_t *cpy_build_meta(PyObject *meta) {
- int i, s;
+ int s;
meta_data_t *m = NULL;
PyObject *l;
}
m = meta_data_create();
- for (i = 0; i < s; ++i) {
+ for (int i = 0; i < s; ++i) {
const char *string, *keystring;
PyObject *key, *value, *item, *tmp;
static PyObject *Values_dispatch(Values *self, PyObject *args, PyObject *kwds) {
int ret;
const data_set_t *ds;
- size_t size, i;
+ size_t size;
value_t *value;
value_list_t value_list = VALUE_LIST_INIT;
PyObject *values = self->values, *meta = self->meta;
return NULL;
}
value = calloc(size, sizeof(*value));
- for (i = 0; i < size; ++i) {
+ for (size_t i = 0; i < size; ++i) {
PyObject *item, *num;
item = PySequence_Fast_GET_ITEM(values, (int) i); /* Borrowed reference. */
- if (ds->ds->type == DS_TYPE_COUNTER) {
+ switch (ds->ds[i].type) {
+ case DS_TYPE_COUNTER:
num = PyNumber_Long(item); /* New reference. */
if (num != NULL) {
value[i].counter = PyLong_AsUnsignedLongLong(num);
Py_XDECREF(num);
}
- } else if (ds->ds->type == DS_TYPE_GAUGE) {
+ break;
+ case DS_TYPE_GAUGE:
num = PyNumber_Float(item); /* New reference. */
if (num != NULL) {
value[i].gauge = PyFloat_AsDouble(num);
Py_XDECREF(num);
}
- } else if (ds->ds->type == DS_TYPE_DERIVE) {
+ break;
+ case DS_TYPE_DERIVE:
/* This might overflow without raising an exception.
* Not much we can do about it */
num = PyNumber_Long(item); /* New reference. */
value[i].derive = PyLong_AsLongLong(num);
Py_XDECREF(num);
}
- } else if (ds->ds->type == DS_TYPE_ABSOLUTE) {
+ break;
+ case DS_TYPE_ABSOLUTE:
/* This might overflow without raising an exception.
* Not much we can do about it */
num = PyNumber_Long(item); /* New reference. */
value[i].absolute = PyLong_AsUnsignedLongLong(num);
Py_XDECREF(num);
}
- } else {
+ break;
+ default:
free(value);
- PyErr_Format(PyExc_RuntimeError, "unknown data type %d for %s", ds->ds->type, value_list.type);
+ PyErr_Format(PyExc_RuntimeError, "unknown data type %d for %s", ds->ds[i].type, value_list.type);
return NULL;
}
if (PyErr_Occurred() != NULL) {
static PyObject *Values_write(Values *self, PyObject *args, PyObject *kwds) {
int ret;
const data_set_t *ds;
- size_t size, i;
+ size_t size;
value_t *value;
value_list_t value_list = VALUE_LIST_INIT;
PyObject *values = self->values, *meta = self->meta;
return NULL;
}
value = calloc(size, sizeof(*value));
- for (i = 0; i < size; ++i) {
+ for (size_t i = 0; i < size; ++i) {
PyObject *item, *num;
item = PySequence_Fast_GET_ITEM(values, i); /* Borrowed reference. */
- if (ds->ds->type == DS_TYPE_COUNTER) {
+ switch (ds->ds[i].type) {
+ case DS_TYPE_COUNTER:
num = PyNumber_Long(item); /* New reference. */
if (num != NULL) {
value[i].counter = PyLong_AsUnsignedLongLong(num);
Py_XDECREF(num);
}
- } else if (ds->ds->type == DS_TYPE_GAUGE) {
+ break;
+ case DS_TYPE_GAUGE:
num = PyNumber_Float(item); /* New reference. */
if (num != NULL) {
value[i].gauge = PyFloat_AsDouble(num);
Py_XDECREF(num);
}
- } else if (ds->ds->type == DS_TYPE_DERIVE) {
+ break;
+ case DS_TYPE_DERIVE:
/* This might overflow without raising an exception.
* Not much we can do about it */
num = PyNumber_Long(item); /* New reference. */
value[i].derive = PyLong_AsLongLong(num);
Py_XDECREF(num);
}
- } else if (ds->ds->type == DS_TYPE_ABSOLUTE) {
+ break;
+ case DS_TYPE_ABSOLUTE:
/* This might overflow without raising an exception.
* Not much we can do about it */
num = PyNumber_Long(item); /* New reference. */
value[i].absolute = PyLong_AsUnsignedLongLong(num);
Py_XDECREF(num);
}
- } else {
+ break;
+ default:
free(value);
- PyErr_Format(PyExc_RuntimeError, "unknown data type %d for %s", ds->ds->type, value_list.type);
+ PyErr_Format(PyExc_RuntimeError, "unknown data type %d for %s", ds->ds[i].type, value_list.type);
return NULL;
}
if (PyErr_Occurred() != NULL) {
**/
#include "collectd.h"
+
#include "common.h"
#include "plugin.h"
-#include "configfile.h"
#include <sys/time.h>
#include <hiredis/hiredis.h>
{
redis_query_t *rq;
int status;
- int i;
rq = calloc(1, sizeof(*rq));
if (rq == NULL) {
(void)sstrncpy(rq->instance, rq->query, sizeof(rq->instance));
replace_special(rq->instance, sizeof(rq->instance));
- for (i = 0; i < ci->children_num; i++) {
+ for (int i = 0; i < ci->children_num; i++) {
oconfig_item_t *option = ci->children + i;
if (strcasecmp("Type", option->key) == 0) {
static int redis_config_node (oconfig_item_t *ci) /* {{{ */
{
- redis_node_t rn;
redis_query_t *rq;
- int i;
int status;
int timeout;
- memset (&rn, 0, sizeof (rn));
+ redis_node_t rn = {
+ .port = REDIS_DEF_PORT,
+ .timeout.tv_usec = REDIS_DEF_TIMEOUT
+ };
+
sstrncpy (rn.host, REDIS_DEF_HOST, sizeof (rn.host));
- rn.port = REDIS_DEF_PORT;
- rn.timeout.tv_usec = REDIS_DEF_TIMEOUT;
- rn.queries = NULL;
status = cf_util_get_string_buffer (ci, rn.name, sizeof (rn.name));
if (status != 0)
return (status);
- for (i = 0; i < ci->children_num; i++)
+ for (int i = 0; i < ci->children_num; i++)
{
oconfig_item_t *option = ci->children + i;
static int redis_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 *option = ci->children + i;
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;
sstrncpy (vl.host, hostname_g, sizeof (vl.host));
sstrncpy (vl.plugin, "redis", sizeof (vl.plugin));
static int redis_read (void) /* {{{ */
{
- redis_node_t *rn;
- redis_query_t *rq;
-
- for (rn = nodes_head; rn != NULL; rn = rn->next)
+ for (redis_node_t *rn = nodes_head; rn != NULL; rn = rn->next)
{
redisContext *rh;
redisReply *rr;
redis_handle_info (rn->name, rr->str, "total_bytes", "input", "total_net_input_bytes", DS_TYPE_DERIVE);
redis_handle_info (rn->name, rr->str, "total_bytes", "output", "total_net_output_bytes", DS_TYPE_DERIVE);
- for (rq = rn->queries; rq != NULL; rq = rq->next)
+ for (redis_query_t *rq = rn->queries; rq != NULL; rq = rq->next)
redis_handle_query(rh, rn, rq);
redis_fail:
**/
#include "collectd.h"
+
#include "common.h"
#include "plugin.h"
static void cr_submit_io (cr_data_t *rd, const char *type, /* {{{ */
const char *type_instance, derive_t rx, derive_t tx)
{
- value_t values[2];
value_list_t vl = VALUE_LIST_INIT;
-
- values[0].derive = rx;
- values[1].derive = tx;
+ value_t values[] = {
+ { .derive = rx },
+ { .derive = tx },
+ };
vl.values = values;
vl.values_len = STATIC_ARRAY_SIZE (values);
{
cr_data_t *router_data;
char read_name[128];
- user_data_t user_data;
int status;
- int i;
router_data = calloc (1, sizeof (*router_data));
if (router_data == NULL)
router_data->password = NULL;
status = 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;
}
ssnprintf (read_name, sizeof (read_name), "routeros/%s", router_data->node);
- user_data.data = router_data;
- user_data.free_func = (void *) cr_free_data;
if (status == 0)
status = plugin_register_complex_read (/* group = */ NULL, read_name,
- cr_read, /* interval = */ 0, &user_data);
+ cr_read, /* interval = */ 0, &(user_data_t) {
+ .data = router_data,
+ .free_func = (void *) cr_free_data,
+ });
if (status != 0)
cr_free_data (router_data);
static int cr_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;
**/
#include "collectd.h"
+
#include "plugin.h"
#include "common.h"
#include "utils_rrdcreate.h"
{
int offset;
int status;
- size_t i;
time_t t;
assert (0 == strcmp (ds->type, vl->type));
return (-1);
offset = status;
- for (i = 0; i < ds->ds_num; i++)
+ for (size_t i = 0; i < ds->ds_num; i++)
{
if ((ds->ds[i].type != DS_TYPE_COUNTER)
&& (ds->ds[i].type != DS_TYPE_GAUGE)
static int rc_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 const *child = ci->children + i;
const char *key = child->key;
{
int status;
rrdc_stats_t *head;
- rrdc_stats_t *ptr;
- value_t values[1];
value_list_t vl = VALUE_LIST_INIT;
+ vl.values = &(value_t) { .gauge = NAN };
+ vl.values_len = 1;
if (daemon_address == NULL)
return (-1);
if (!config_collect_stats)
return (-1);
- vl.values = values;
- vl.values_len = 1;
-
if ((strncmp ("unix:", daemon_address, strlen ("unix:")) == 0)
|| (daemon_address[0] == '/'))
sstrncpy (vl.host, hostname_g, sizeof (vl.host));
return (-1);
}
- for (ptr = head; ptr != NULL; ptr = ptr->next)
+ for (rrdc_stats_t *ptr = head; ptr != NULL; ptr = ptr->next)
{
if (ptr->type == RRDC_STATS_TYPE_GAUGE)
- values[0].gauge = (gauge_t) ptr->value.gauge;
+ vl.values[0].gauge = (gauge_t) ptr->value.gauge;
else if (ptr->type == RRDC_STATS_TYPE_COUNTER)
- values[0].counter = (counter_t) ptr->value.counter;
+ vl.values[0].counter = (counter_t) ptr->value.counter;
else
continue;
**/
#include "collectd.h"
+
#include "plugin.h"
#include "common.h"
#include "utils_avltree.h"
int offset;
int status;
time_t tt;
- size_t i;
memset (buffer, '\0', buffer_len);
return (-1);
offset = status;
- for (i = 0; i < ds->ds_num; i++)
+ for (size_t i = 0; i < ds->ds_num; i++)
{
if ((ds->ds[i].type != DS_TYPE_COUNTER)
&& (ds->ds[i].type != DS_TYPE_GAUGE)
char **values;
int values_num;
int status;
- int i;
values = NULL;
values_num = 0;
pthread_mutex_unlock (&queue_lock);
/* We now need the cache lock so the entry isn't updated while
- * we make a copy of it's values */
+ * we make a copy of its values */
pthread_mutex_lock (&cache_lock);
status = c_avl_get (cache, queue_entry->filename,
values_num, (values_num == 1) ? "" : "s",
queue_entry->filename);
- for (i = 0; i < values_num; i++)
+ for (int i = 0; i < values_num; i++)
{
sfree (values[i]);
}
char *key;
c_avl_iterator_t *iter;
- int i;
DEBUG ("rrdtool plugin: Flushing cache, timeout = %.3f",
CDTIME_T_TO_DOUBLE (timeout));
} /* while (c_avl_iterator_next) */
c_avl_iterator_destroy (iter);
- for (i = 0; i < keys_num; i++)
+ for (int i = 0; i < keys_num; i++)
{
if (c_avl_remove (cache, keys[i], (void *) &key, (void *) &rc) != 0)
{
while (c_avl_pick (cache, &key, &value) == 0)
{
rrd_cache_t *rc;
- int i;
sfree (key);
key = NULL;
if (rc->values_num > 0)
non_empty++;
- for (i = 0; i < rc->values_num; i++)
+ for (int i = 0; i < rc->values_num; i++)
sfree (rc->values[i]);
sfree (rc->values);
sfree (rc);
**/
#include "collectd.h"
+
#include "common.h"
#include "plugin.h"
-#include "configfile.h"
#include "utils_ignorelist.h"
#if defined(HAVE_SENSORS_SENSORS_H)
static int sensors_feature_name_to_type (const char *name)
{
- int i;
-
/* Yes, this is slow, but it's only ever done during initialization, so
* it's a one time cost.. */
- for (i = 0; i < known_features_num; i++)
+ for (int i = 0; i < known_features_num; i++)
if (strcasecmp (known_features[i].label, name) == 0)
return (known_features[i].type);
static void sensors_free_features (void)
{
- featurelist_t *thisft;
featurelist_t *nextft;
if (first_feature == NULL)
sensors_cleanup ();
- for (thisft = first_feature; thisft != NULL; thisft = nextft)
+ for (featurelist_t *thisft = first_feature; thisft != NULL; thisft = nextft)
{
nextft = thisft->next;
sfree (thisft);
static void sensors_submit (const char *plugin_instance,
const char *type, const char *type_instance,
- double val)
+ double value)
{
char match_key[1024];
int status;
- value_t values[1];
value_list_t vl = VALUE_LIST_INIT;
status = ssnprintf (match_key, sizeof (match_key), "%s/%s-%s",
return;
}
- values[0].gauge = val;
-
- vl.values = values;
+ vl.values = &(value_t) { .gauge = value };
vl.values_len = 1;
sstrncpy (vl.host, hostname_g, sizeof (vl.host));
static int sensors_read (void)
{
- featurelist_t *fl;
-
if (sensors_load_conf () != 0)
return (-1);
#if SENSORS_API_VERSION < 0x400
- for (fl = first_feature; fl != NULL; fl = fl->next)
+ for (featurelist_t *fl = first_feature; fl != NULL; fl = fl->next)
{
double value;
int status;
/* #endif SENSORS_API_VERSION < 0x400 */
#elif (SENSORS_API_VERSION >= 0x400) && (SENSORS_API_VERSION < 0x500)
- for (fl = first_feature; fl != NULL; fl = fl->next)
+ for (featurelist_t *fl = first_feature; fl != NULL; fl = fl->next)
{
double value;
int status;
**/
#include "collectd.h"
+
#include "common.h"
#include "plugin.h"
static void serial_submit (const char *type_instance,
derive_t rx, derive_t tx)
{
- value_t values[2];
value_list_t vl = VALUE_LIST_INIT;
-
- values[0].derive = rx;
- values[1].derive = tx;
+ value_t values[] = {
+ { .derive = rx },
+ { .derive = tx },
+ };
vl.values = values;
- vl.values_len = 2;
+ vl.values_len = STATIC_ARRAY_SIZE (values);
sstrncpy (vl.host, hostname_g, sizeof (vl.host));
sstrncpy (vl.plugin, "serial", sizeof (vl.plugin));
sstrncpy (vl.type, "serial_octets", sizeof (vl.type));
char *fields[16];
int numfields;
- int i;
numfields = strsplit (buffer, fields, STATIC_ARRAY_SIZE (fields));
if (numfields < 6)
continue;
fields[0][len - 1] = 0;
- for (i = 1; i < numfields; i++)
+ for (int i = 1; i < numfields; i++)
{
len = strlen (fields[i]);
if (len < 4)
*/
#include "collectd.h"
+
#include "common.h"
#include "plugin.h"
static int sigrok_config_device(oconfig_item_t *ci)
{
struct config_device *cfdev;
- int i;
if (!(cfdev = calloc(1, sizeof(*cfdev)))) {
ERROR("sigrok plugin: calloc failed.");
}
cfdev->min_dispatch_interval = DEFAULT_MIN_DISPATCH_INTERVAL;
- for (i = 0; i < ci->children_num; i++) {
+ for (int i = 0; i < ci->children_num; i++) {
oconfig_item_t *item = ci->children + i;
if (!strcasecmp(item->key, "driver"))
cf_util_get_string(item, &cfdev->driver);
static int sigrok_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 *item = ci->children + i;
if (strcasecmp("LogLevel", item->key) == 0) {
int status;
{
const struct sr_datafeed_analog *analog;
struct config_device *cfdev;
- GSList *l;
- value_t value;
value_list_t vl = VALUE_LIST_INIT;
/* Find this device's configuration. */
cfdev = NULL;
- for (l = config_devices; l; l = l->next) {
+ for (GSList *l = config_devices; l; l = l->next) {
cfdev = l->data;
if (cfdev->sdi == sdi) {
/* Found it. */
/* Ignore all but the first sample on the first probe. */
analog = packet->payload;
- value.gauge = analog->data[0];
- vl.values = &value;
+ vl.values = &(value_t) { .gauge = analog->data[0] };
vl.values_len = 1;
sstrncpy(vl.host, hostname_g, sizeof(vl.host));
sstrncpy(vl.plugin, "sigrok", sizeof(vl.plugin));
**/
#include "collectd.h"
+
#include "common.h"
#include "plugin.h"
#include "utils_ignorelist.h"
static void smart_submit (const char *dev, 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, "smart", sizeof (vl.plugin));
void* userdata)
{
const char *dev = userdata;
- value_t values[4];
- value_list_t vl = VALUE_LIST_INIT;
- if (!a->current_value_valid || !a->worst_value_valid) return;
- values[0].gauge = a->current_value;
- values[1].gauge = a->worst_value;
- values[2].gauge = a->threshold_valid?a->threshold:0;
- values[3].gauge = a->pretty_value;
+ if (!a->current_value_valid || !a->worst_value_valid)
+ return;
+
+ value_list_t vl = VALUE_LIST_INIT;
+ value_t values[] = {
+ { .gauge = a->current_value },
+ { .gauge = a->worst_value },
+ { .gauge = a->threshold_valid ? a->threshold : 0 },
+ { .gauge = a->pretty_value },
+ };
vl.values = values;
- vl.values_len = 4;
+ vl.values_len = STATIC_ARRAY_SIZE (values);
sstrncpy (vl.host, hostname_g, sizeof (vl.host));
sstrncpy (vl.plugin, "smart", sizeof (vl.plugin));
sstrncpy (vl.plugin_instance, dev, sizeof (vl.plugin_instance));
**/
#include "collectd.h"
+
#include "common.h"
#include "plugin.h"
#include "utils_complain.h"
{
char oid_str[MAX_OID_LEN][16];
char *oid_str_ptr[MAX_OID_LEN];
- size_t i;
- for (i = 0; i < o->oid_len; i++)
+ for (size_t i = 0; i < o->oid_len; i++)
{
ssnprintf (oid_str[i], sizeof (oid_str[i]), "%lu", (unsigned long) o->oid[i]);
oid_str_ptr[i] = oid_str[i];
static int csnmp_config_add_data_values (data_definition_t *dd, oconfig_item_t *ci)
{
- int i;
-
if (ci->values_num < 1)
{
WARNING ("snmp plugin: `Values' needs at least one argument.");
return (-1);
}
- for (i = 0; i < ci->values_num; i++)
+ for (int i = 0; i < ci->values_num; i++)
if (ci->values[i].type != OCONFIG_TYPE_STRING)
{
WARNING ("snmp plugin: `Values' needs only string argument.");
return (-1);
dd->values_len = (size_t) ci->values_num;
- for (i = 0; i < ci->values_num; i++)
+ for (int i = 0; i < ci->values_num; i++)
{
dd->values[i].oid_len = MAX_OID_LEN;
static int csnmp_config_add_data_blacklist(data_definition_t *dd, oconfig_item_t *ci)
{
- int i;
-
if (ci->values_num < 1)
return (0);
- for (i = 0; i < ci->values_num; i++)
+ for (int i = 0; i < ci->values_num; i++)
{
if (ci->values[i].type != OCONFIG_TYPE_STRING)
{
dd->ignores_len = 0;
dd->ignores = NULL;
- for (i = 0; i < ci->values_num; ++i)
+ for (int i = 0; i < ci->values_num; ++i)
{
if (strarray_add(&(dd->ignores), &(dd->ignores_len), ci->values[i].value.string) != 0)
{
{
data_definition_t *dd;
int status = 0;
- int i;
dd = calloc (1, sizeof (*dd));
if (dd == NULL)
dd->scale = 1.0;
dd->shift = 0.0;
- for (i = 0; i < ci->children_num; i++)
+ for (int i = 0; i < ci->children_num; i++)
{
oconfig_item_t *option = ci->children + i;
data_definition_t *data;
data_definition_t **data_list;
int data_list_len;
- int i;
if (ci->values_num < 1)
{
return (-1);
}
- for (i = 0; i < ci->values_num; i++)
+ for (int i = 0; i < ci->values_num; i++)
if (ci->values[i].type != OCONFIG_TYPE_STRING)
{
WARNING ("snmp plugin: All arguments to `Collect' must be strings.");
return (-1);
host->data_list = data_list;
- for (i = 0; i < ci->values_num; i++)
+ for (int i = 0; i < ci->values_num; i++)
{
for (data = data_head; data != NULL; data = data->next)
if (strcasecmp (ci->values[i].value.string, data->name) == 0)
{
host_definition_t *hd;
int status = 0;
- int i;
/* Registration stuff. */
char cb_name[DATA_MAX_NAME_LEN];
- user_data_t cb_data;
hd = calloc (1, sizeof (*hd));
if (hd == NULL)
hd->sess_handle = NULL;
hd->interval = 0;
- for (i = 0; i < ci->children_num; i++)
+ for (int i = 0; i < ci->children_num; i++)
{
oconfig_item_t *option = ci->children + i;
status = 0;
ssnprintf (cb_name, sizeof (cb_name), "snmp-%s", hd->name);
- memset (&cb_data, 0, sizeof (cb_data));
- cb_data.data = hd;
- cb_data.free_func = csnmp_host_definition_destroy;
-
status = plugin_register_complex_read (/* group = */ NULL, cb_name,
- csnmp_read_host, hd->interval, /* user_data = */ &cb_data);
+ csnmp_read_host, hd->interval, &(user_data_t) {
+ .data = hd,
+ .free_func = csnmp_host_definition_destroy,
+ });
if (status != 0)
{
ERROR ("snmp plugin: Registering complex read function failed.");
static int csnmp_config (oconfig_item_t *ci)
{
- int i;
-
call_snmp_init_once ();
- 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 ("Data", child->key) == 0)
}
else
{
- char oid_buffer[1024];
+ char oid_buffer[1024] = { 0 };
- memset (oid_buffer, 0, sizeof (oid_buffer));
snprint_objid (oid_buffer, sizeof (oid_buffer) - 1,
vl->name, vl->name_length);
{
char *buffer_ptr;
size_t buffer_free;
- size_t i;
dst[0] = 0;
buffer_ptr = dst;
buffer_free = dst_size;
- for (i = 0; i < vb->val_len; i++)
+ for (size_t i = 0; i < vb->val_len; i++)
{
int status;
{
char *src;
size_t num_chars;
- size_t i;
if (vb->type == ASN_OCTET_STR)
src = (char *) vb->val.string;
if (num_chars > vb->val_len)
num_chars = vb->val_len;
- for (i = 0; i < num_chars; i++)
+ for (size_t i = 0; i < num_chars; i++)
{
/* Check for control characters. */
if ((unsigned char)src[i] < 32)
struct variable_list *vb;
oid_t vb_name;
int status;
- uint32_t i;
uint32_t is_matched;
/* Set vb on the last variable */
csnmp_strvbcopy (il->instance, vb, sizeof (il->instance));
is_matched = 0;
- for (i = 0; i < dd->ignores_len; i++)
+ for (uint32_t i = 0; i < dd->ignores_len; i++)
{
status = fnmatch(dd->ignores[i], il->instance, 0);
if (status == 0)
vl.interval = host->interval;
have_more = 1;
- memset (¤t_suffix, 0, sizeof (current_suffix));
while (have_more)
{
_Bool suffix_skipped = 0;
for (i = 0; i < data->values_len; i++)
vl.values[i] = value_table_ptr[i]->value;
- /* If we get here `vl.type_instance' and all `vl.values' have been set */
- plugin_dispatch_values (&vl);
+ /* If we get here `vl.type_instance' and all `vl.values' have been set
+ * vl.type_instance can be empty, i.e. a blank port description on a
+ * switch if you're using IF-MIB::ifDescr as Instance.
+ */
+ if (vl.type_instance[0] != '\0')
+ plugin_dispatch_values (&vl);
if (instance_list != NULL)
instance_list_ptr = instance_list_ptr->next;
*/
#include "collectd.h"
+
#include "plugin.h"
#include "common.h"
-#include "configfile.h"
#include "utils_avltree.h"
#include "utils_latency.h"
struct pollfd *fds = NULL;
size_t fds_num = 0;
- struct addrinfo ai_hints;
- struct addrinfo *ai_list = NULL;
- struct addrinfo *ai_ptr;
+ struct addrinfo *ai_list;
int status;
char const *node = (conf_node != NULL) ? conf_node : STATSD_DEFAULT_NODE;
char const *service = (conf_service != NULL)
? conf_service : STATSD_DEFAULT_SERVICE;
- memset (&ai_hints, 0, sizeof (ai_hints));
- ai_hints.ai_flags = AI_PASSIVE;
-#ifdef AI_ADDRCONFIG
- ai_hints.ai_flags |= AI_ADDRCONFIG;
-#endif
- ai_hints.ai_family = AF_UNSPEC;
- ai_hints.ai_socktype = SOCK_DGRAM;
+ struct addrinfo ai_hints = {
+ .ai_family = AF_UNSPEC,
+ .ai_flags = AI_PASSIVE | AI_ADDRCONFIG,
+ .ai_socktype = SOCK_DGRAM
+ };
status = getaddrinfo (node, service, &ai_hints, &ai_list);
if (status != 0)
return (status);
}
- for (ai_ptr = ai_list; ai_ptr != NULL; ai_ptr = ai_ptr->ai_next)
+ for (struct addrinfo *ai_ptr = ai_list; ai_ptr != NULL; ai_ptr = ai_ptr->ai_next)
{
int fd;
struct pollfd *tmp;
struct pollfd *fds = NULL;
size_t fds_num = 0;
int status;
- size_t i;
status = statsd_network_init (&fds, &fds_num);
if (status != 0)
break;
}
- for (i = 0; i < fds_num; i++)
+ for (size_t i = 0; i < fds_num; i++)
{
if ((fds[i].revents & (POLLIN | POLLPRI)) == 0)
continue;
} /* while (!network_thread_shutdown) */
/* Clean up */
- for (i = 0; i < fds_num; i++)
+ for (size_t i = 0; i < fds_num; i++)
close (fds[i].fd);
sfree (fds);
static int statsd_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;
/* Must hold metrics_lock when calling this function. */
static int statsd_metric_submit_unsafe (char const *name, statsd_metric_t *metric) /* {{{ */
{
- value_t values[1];
value_list_t vl = VALUE_LIST_INIT;
- vl.values = values;
+ vl.values = &(value_t) { .gauge = NAN };
vl.values_len = 1;
sstrncpy (vl.host, hostname_g, sizeof (vl.host));
sstrncpy (vl.plugin, "statsd", sizeof (vl.plugin));
sstrncpy (vl.type_instance, name, sizeof (vl.type_instance));
if (metric->type == STATSD_GAUGE)
- values[0].gauge = (gauge_t) metric->value;
+ vl.values[0].gauge = (gauge_t) metric->value;
else if (metric->type == STATSD_TIMER)
{
- size_t i;
_Bool have_events = (metric->updates_num > 0);
/* Make sure all timer metrics share the *same* timestamp. */
ssnprintf (vl.type_instance, sizeof (vl.type_instance),
"%s-average", name);
- values[0].gauge = have_events
+ vl.values[0].gauge = have_events
? CDTIME_T_TO_DOUBLE (latency_counter_get_average (metric->latency))
: NAN;
plugin_dispatch_values (&vl);
if (conf_timer_lower) {
ssnprintf (vl.type_instance, sizeof (vl.type_instance),
"%s-lower", name);
- values[0].gauge = have_events
+ vl.values[0].gauge = have_events
? CDTIME_T_TO_DOUBLE (latency_counter_get_min (metric->latency))
: NAN;
plugin_dispatch_values (&vl);
if (conf_timer_upper) {
ssnprintf (vl.type_instance, sizeof (vl.type_instance),
"%s-upper", name);
- values[0].gauge = have_events
+ vl.values[0].gauge = have_events
? CDTIME_T_TO_DOUBLE (latency_counter_get_max (metric->latency))
: NAN;
plugin_dispatch_values (&vl);
if (conf_timer_sum) {
ssnprintf (vl.type_instance, sizeof (vl.type_instance),
"%s-sum", name);
- values[0].gauge = have_events
+ vl.values[0].gauge = have_events
? CDTIME_T_TO_DOUBLE (latency_counter_get_sum (metric->latency))
: NAN;
plugin_dispatch_values (&vl);
}
- for (i = 0; i < conf_timer_percentile_num; i++)
+ for (size_t i = 0; i < conf_timer_percentile_num; i++)
{
ssnprintf (vl.type_instance, sizeof (vl.type_instance),
"%s-percentile-%.0f", name, conf_timer_percentile[i]);
- values[0].gauge = have_events
+ vl.values[0].gauge = have_events
? CDTIME_T_TO_DOUBLE (latency_counter_get_percentile (metric->latency, conf_timer_percentile[i]))
: NAN;
plugin_dispatch_values (&vl);
sstrncpy (vl.type, "gauge", sizeof (vl.type));
ssnprintf (vl.type_instance, sizeof (vl.type_instance),
"%s-count", name);
- values[0].gauge = latency_counter_get_num (metric->latency);
+ vl.values[0].gauge = latency_counter_get_num (metric->latency);
plugin_dispatch_values (&vl);
}
else if (metric->type == STATSD_SET)
{
if (metric->set == NULL)
- values[0].gauge = 0.0;
+ vl.values[0].gauge = 0.0;
else
- values[0].gauge = (gauge_t) c_avl_size (metric->set);
+ vl.values[0].gauge = (gauge_t) c_avl_size (metric->set);
}
else { /* STATSD_COUNTER */
gauge_t delta = nearbyint (metric->value);
if (conf_counter_sum)
{
sstrncpy (vl.type, "count", sizeof (vl.type));
- values[0].gauge = delta;
+ vl.values[0].gauge = delta;
plugin_dispatch_values (&vl);
/* restore vl.type */
metric->value -= delta;
metric->counter += (derive_t) delta;
- values[0].derive = metric->counter;
+ vl.values[0].derive = metric->counter;
}
return (plugin_dispatch_values (&vl));
char **to_be_deleted = NULL;
size_t to_be_deleted_num = 0;
- size_t i;
pthread_mutex_lock (&metrics_lock);
}
c_avl_iterator_destroy (iter);
- for (i = 0; i < to_be_deleted_num; i++)
+ for (size_t i = 0; i < to_be_deleted_num; i++)
{
int status;
#endif
#include "collectd.h"
+
#include "common.h"
#include "plugin.h"
static int swap_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;
if (strcasecmp ("ReportBytes", child->key) == 0)
gauge_t used, gauge_t free,
char const *other_name, gauge_t other_value)
{
- value_t v[1];
value_list_t vl = VALUE_LIST_INIT;
- vl.values = v;
- vl.values_len = STATIC_ARRAY_SIZE (v);
+ vl.values = &(value_t) { .gauge = NAN };
+ vl.values_len = 1;
sstrncpy (vl.host, hostname_g, sizeof (vl.host));
sstrncpy (vl.plugin, "swap", sizeof (vl.plugin));
if (plugin_instance != NULL)
derive_t value)
{
value_list_t vl = VALUE_LIST_INIT;
- value_t v[1];
- v[0].derive = value;
-
- vl.values = v;
- vl.values_len = STATIC_ARRAY_SIZE (v);
+ vl.values = &(value_t) { .derive = value };
+ vl.values_len = 1;
sstrncpy (vl.host, hostname_g, sizeof (vl.host));
sstrncpy (vl.plugin, "swap", sizeof (vl.plugin));
sstrncpy (vl.type, "swap_io", sizeof (vl.type));
char *s_paths;
int swap_num;
int status;
- int i;
gauge_t avail = 0;
gauge_t total = 0;
sfree (s);
return (-1);
}
- for (i = 0; i < swap_num; i++)
+ for (int i = 0; i < swap_num; i++)
s->swt_ent[i].ste_path = s_paths + (i * PATH_MAX);
s->swt_n = swap_num;
/* less elements returned than requested */
swap_num = status;
- for (i = 0; i < swap_num; i++)
+ for (int i = 0; i < swap_num; i++)
{
char path[PATH_MAX];
gauge_t this_total;
struct swapent *swap_entries;
int swap_num;
int status;
- int i;
gauge_t used = 0;
gauge_t total = 0;
/* TODO: Report per-device stats. The path name is available from
* swap_entries[i].se_path */
- for (i = 0; i < swap_num; i++)
+ for (int i = 0; i < swap_num; i++)
{
if ((swap_entries[i].se_flags & SWF_ENABLE) == 0)
continue;
{
ERROR ("swap plugin: Total swap space (%g) is less than used swap space (%g).",
total, used);
+ sfree (swap_entries);
return (-1);
}
#elif HAVE_PERFSTAT
static int swap_read (void) /* {{{ */
{
- perfstat_memory_total_t pmemory;
+ perfstat_memory_total_t pmemory = { 0 };
int status;
gauge_t total;
gauge_t free;
gauge_t reserved;
- memset (&pmemory, 0, sizeof (pmemory));
status = perfstat_memory_total (NULL, &pmemory, sizeof(perfstat_memory_total_t), 1);
if (status < 0)
{
**/
#include "collectd.h"
+
#include "common.h"
#include "plugin.h"
*/
#include "collectd.h"
+
#include "common.h"
-#include "configfile.h"
#include "plugin.h"
#define log_err(...) ERROR ("table plugin: " __VA_ARGS__)
static void tbl_clear (tbl_t *tbl)
{
- size_t i;
-
sfree (tbl->file);
sfree (tbl->sep);
sfree (tbl->instance);
- for (i = 0; i < tbl->results_num; ++i)
+ for (size_t i = 0; i < tbl->results_num; ++i)
tbl_result_clear (tbl->results + i);
sfree (tbl->results);
tbl->results_num = 0;
{
size_t *tmp;
size_t num;
- size_t i;
if (1 > ci->values_num) {
log_err ("\"%s\" expects at least one argument.", name);
}
num = (size_t) ci->values_num;
- for (i = 0; i < num; ++i) {
+ for (size_t i = 0; i < num; ++i) {
if (OCONFIG_TYPE_NUMBER != ci->values[i].type) {
log_err ("\"%s\" expects numerical arguments only.", name);
return 1;
}
*var = tmp;
- for (i = 0; i < num; ++i) {
+ for (size_t i = 0; i < num; ++i) {
(*var)[*len] = (size_t) ci->values[i].value.number;
(*len)++;
}
tbl_result_t *res;
int status = 0;
- int i;
if (0 != ci->values_num) {
log_err ("<Result> does not expect any arguments.");
res = tbl->results + tbl->results_num - 1;
tbl_result_setup (res);
- for (i = 0; i < ci->children_num; ++i) {
+ for (int i = 0; i < ci->children_num; ++i) {
oconfig_item_t *c = ci->children + i;
if (0 == strcasecmp (c->key, "Type"))
tbl_t *tbl;
int status = 0;
- size_t i;
if ((1 != ci->values_num)
|| (OCONFIG_TYPE_STRING != ci->values[0].type)) {
tbl = tables + tables_num - 1;
tbl_setup (tbl, ci->values[0].value.string);
- for (i = 0; i < ((size_t) ci->children_num); ++i) {
+ for (size_t i = 0; i < ((size_t) ci->children_num); ++i) {
oconfig_item_t *c = ci->children + i;
if (0 == strcasecmp (c->key, "Separator"))
return status;
}
- for (i = 0; i < tbl->results_num; ++i) {
+ for (size_t i = 0; i < tbl->results_num; ++i) {
tbl_result_t *res = tbl->results + i;
- size_t j;
- for (j = 0; j < res->instances_num; ++j)
+ for (size_t j = 0; j < res->instances_num; ++j)
if (res->instances[j] > tbl->max_colnum)
tbl->max_colnum = res->instances[j];
- for (j = 0; j < res->values_num; ++j)
+ for (size_t j = 0; j < res->values_num; ++j)
if (res->values[j] > tbl->max_colnum)
tbl->max_colnum = res->values[j];
}
static int tbl_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 *c = ci->children + i;
if (0 == strcasecmp (c->key, "Table"))
static int tbl_prepare (tbl_t *tbl)
{
- size_t i;
-
- for (i = 0; i < tbl->results_num; ++i) {
+ for (size_t i = 0; i < tbl->results_num; ++i) {
tbl_result_t *res = tbl->results + i;
res->ds = plugin_get_ds (res->type);
static int tbl_finish (tbl_t *tbl)
{
- size_t i;
-
- for (i = 0; i < tbl->results_num; ++i)
+ for (size_t i = 0; i < tbl->results_num; ++i)
tbl->results[i].ds = NULL;
return 0;
} /* tbl_finish */
value_list_t vl = VALUE_LIST_INIT;
value_t values[res->values_num];
- size_t i;
-
assert (NULL != res->ds);
assert (res->values_num == res->ds->ds_num);
- for (i = 0; i < res->values_num; ++i) {
+ for (size_t i = 0; i < res->values_num; ++i) {
char *value;
assert (res->values[i] < fields_num);
char *instances[res->instances_num];
char instances_str[DATA_MAX_NAME_LEN];
- for (i = 0; i < res->instances_num; ++i) {
+ for (size_t i = 0; i < res->instances_num; ++i) {
assert (res->instances[i] < fields_num);
instances[i] = fields[res->instances[i]];
}
char *fields[tbl->max_colnum + 1];
char *ptr, *saveptr;
- size_t i;
+ size_t i = 0;
- i = 0;
ptr = line;
saveptr = NULL;
while (NULL != (fields[i] = strtok_r (ptr, tbl->sep, &saveptr))) {
static int tbl_read (void)
{
int status = -1;
- size_t i;
if (0 == tables_num)
return 0;
- for (i = 0; i < tables_num; ++i) {
+ for (size_t i = 0; i < tables_num; ++i) {
tbl_t *tbl = tables + i;
if (0 != tbl_prepare (tbl)) {
static int tbl_shutdown (void)
{
- size_t i;
-
- for (i = 0; i < tables_num; ++i)
+ for (size_t i = 0; i < tables_num; ++i)
tbl_clear (&tables[i]);
sfree (tables);
return 0;
**/
#include "collectd.h"
+
#include "common.h"
#include "plugin.h"
#include "utils_tail_match.h"
static int ctail_config_add_match (cu_tail_match_t *tm,
const char *plugin_instance, oconfig_item_t *ci, cdtime_t interval)
{
- ctail_config_match_t cm;
+ ctail_config_match_t cm = { 0 };
int status;
- int i;
-
- memset (&cm, '\0', sizeof (cm));
if (ci->values_num != 0)
{
}
status = 0;
- for (i = 0; i < ci->children_num; i++)
+ for (int i = 0; i < ci->children_num; i++)
{
oconfig_item_t *option = ci->children + i;
cdtime_t interval = 0;
char *plugin_instance = NULL;
int num_matches = 0;
- int i;
if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING))
{
return (-1);
}
- for (i = 0; i < ci->children_num; i++)
+ for (int i = 0; i < ci->children_num; i++)
{
oconfig_item_t *option = ci->children + i;
int status = 0;
static int ctail_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 *option = ci->children + i;
static int ctail_init (void)
{
char str[255];
- user_data_t ud;
- size_t i;
if (tail_match_list_num == 0)
{
return (-1);
}
- memset(&ud, '\0', sizeof(ud));
-
- for (i = 0; i < tail_match_list_num; i++)
+ for (size_t i = 0; i < tail_match_list_num; i++)
{
- ud.data = (void *)tail_match_list[i];
ssnprintf(str, sizeof(str), "tail-%zu", i);
- plugin_register_complex_read (NULL, str, ctail_read, tail_match_list_intervals[i], &ud);
+
+ plugin_register_complex_read (NULL, str, ctail_read, tail_match_list_intervals[i],
+ &(user_data_t) {
+ .data = tail_match_list[i],
+ });
}
return (0);
static int ctail_shutdown (void)
{
- size_t i;
-
- for (i = 0; i < tail_match_list_num; i++)
+ for (size_t i = 0; i < tail_match_list_num; i++)
{
tail_match_destroy (tail_match_list[i]);
tail_match_list[i] = NULL;
**/
#include "collectd.h"
+
#include "plugin.h" /* plugin_register_*, plugin_dispatch_values */
#include "common.h" /* auxiliary functions */
#include "utils_tail.h"
static int tcsv_config_add_metric(oconfig_item_t *ci){
metric_definition_t *md;
int status;
- int i;
md = calloc(1, sizeof(*md));
if (md == NULL)
return (-1);
}
- for (i = 0; i < ci->children_num; ++i){
+ for (int i = 0; i < ci->children_num; ++i){
oconfig_item_t *option = ci->children + i;
if (strcasecmp("Type", option->key) == 0)
metric_definition_t *metric;
metric_definition_t **metric_list;
size_t metric_list_size;
- int i;
if (ci->values_num < 1) {
WARNING("tail_csv plugin: The `Collect' config option needs at least one argument.");
return (-1);
id->metric_list = metric_list;
- for (i = 0; i < ci->values_num; i++) {
+ for (int i = 0; i < ci->values_num; i++) {
char *metric_name;
if (ci->values[i].type != OCONFIG_TYPE_STRING) {
{
instance_definition_t* id;
int status = 0;
- int i;
/* Registration variables */
char cb_name[DATA_MAX_NAME_LEN];
- user_data_t cb_data;
id = calloc(1, sizeof(*id));
if (id == NULL)
/* Use default interval. */
id->interval = plugin_get_interval();
- for (i = 0; i < ci->children_num; ++i){
+ for (int i = 0; i < ci->children_num; ++i){
oconfig_item_t *option = ci->children + i;
status = 0;
}
ssnprintf (cb_name, sizeof (cb_name), "tail_csv/%s", id->path);
- memset(&cb_data, 0, sizeof(cb_data));
- cb_data.data = id;
- cb_data.free_func = tcsv_instance_definition_destroy;
- status = plugin_register_complex_read(NULL, cb_name, tcsv_read, id->interval, &cb_data);
+ status = plugin_register_complex_read(NULL, cb_name, tcsv_read, id->interval,
+ &(user_data_t) {
+ .data = id,
+ .free_func = tcsv_instance_definition_destroy,
+ });
if (status != 0){
ERROR("tail_csv plugin: Registering complex read function failed.");
tcsv_instance_definition_destroy(id);
/* Parse blocks */
static int tcsv_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;
if (strcasecmp("Metric", child->key) == 0)
tcsv_config_add_metric(child);
**/
#include "collectd.h"
+
#include "common.h"
#include "plugin.h"
const char *type,
derive_t read, derive_t write)
{
- value_t values[2];
value_list_t vl = VALUE_LIST_INIT;
-
- values[0].derive = read;
- values[1].derive = write;
+ value_t values[] = {
+ { .derive = read },
+ { .derive = write },
+ };
vl.values = values;
- vl.values_len = 2;
+ vl.values_len = STATIC_ARRAY_SIZE (values);
sstrncpy (vl.host, hostname_g, sizeof (vl.host));
sstrncpy (vl.plugin, "tape", sizeof (vl.plugin));
sstrncpy (vl.plugin_instance, plugin_instance,
# error "kstat_io_t does not have the required members"
#endif
static kstat_io_t kio;
- int i;
if (kc == NULL)
return (-1);
if (numtape <= 0)
return (-1);
- for (i = 0; i < numtape; i++)
+ for (int i = 0; i < numtape; i++)
{
if (kstat_read (kc, ksp[i], &kio) == -1)
continue;
**/
#include "collectd.h"
+
#include "common.h"
#include "filter_chain.h"
#include "utils_cache.h"
{
tn_data_t *data;
int status;
- int i;
data = calloc (1, sizeof (*data));
if (data == NULL)
data->severity = 0;
status = 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;
notification_meta_t __attribute__((unused)) **meta, void **user_data)
{
tn_data_t *data;
- notification_t n;
+ notification_t n = { 0 };
char temp[NOTIF_MAX_MSG_LEN];
gauge_t *rates;
int rates_failed;
- size_t i;
-
if ((ds == NULL) || (vl == NULL) || (user_data == NULL))
return (-EINVAL);
}
/* Initialize the structure. */
- memset (&n, 0, sizeof (n));
n.severity = data->severity;
n.time = cdtime ();
sstrncpy (n.message, data->message, sizeof (n.message));
rates_failed = 0;
rates = NULL;
- for (i = 0; i < ds->ds_num; i++)
+
+ for (size_t i = 0; i < ds->ds_num; i++)
{
char template[DATA_MAX_NAME_LEN];
char value_str[DATA_MAX_NAME_LEN];
void module_register (void)
{
- target_proc_t tproc;
+ target_proc_t tproc = { 0 };
- memset (&tproc, 0, sizeof (tproc));
tproc.create = tn_create;
tproc.destroy = tn_destroy;
tproc.invoke = tn_invoke;
**/
#include "collectd.h"
+
#include "common.h"
#include "filter_chain.h"
#include "utils_subst.h"
{
regex_t re;
char *replacement;
- int may_be_empty;
+ _Bool may_be_empty;
tr_action_t *next;
};
+struct tr_meta_data_action_s;
+typedef struct tr_meta_data_action_s tr_meta_data_action_t;
+struct tr_meta_data_action_s
+{
+ char *key;
+ regex_t re;
+ char *replacement;
+
+ tr_meta_data_action_t *next;
+};
+
struct tr_data_s
{
tr_action_t *host;
tr_action_t *plugin_instance;
/* tr_action_t *type; */
tr_action_t *type_instance;
+ tr_meta_data_action_t *meta;
};
typedef struct tr_data_s tr_data_t;
sfree (act);
} /* }}} void tr_action_destroy */
+static void tr_meta_data_action_destroy (tr_meta_data_action_t *act) /* {{{ */
+{
+ if (act == NULL)
+ return;
+
+ sfree (act->key);
+ regfree (&act->re);
+ sfree (act->replacement);
+
+ if (act->next != NULL)
+ tr_meta_data_action_destroy (act->next);
+
+ sfree (act);
+} /* }}} void tr_meta_data_action_destroy */
+
static int tr_config_add_action (tr_action_t **dest, /* {{{ */
- const oconfig_item_t *ci, int may_be_empty)
+ const oconfig_item_t *ci, _Bool may_be_empty)
{
tr_action_t *act;
int status;
if (act->replacement == NULL)
{
ERROR ("tr_config_add_action: tr_strdup failed.");
- regfree (&act->re);
- sfree (act);
+ tr_action_destroy (act);
return (-ENOMEM);
}
return (0);
} /* }}} int tr_config_add_action */
+static int tr_config_add_meta_action (tr_meta_data_action_t **dest, /* {{{ */
+ const oconfig_item_t *ci, _Bool should_delete)
+{
+ tr_meta_data_action_t *act;
+ int status;
+
+ if (dest == NULL)
+ return (-EINVAL);
+
+ if (should_delete)
+ {
+ if ((ci->values_num != 2)
+ || (ci->values[0].type != OCONFIG_TYPE_STRING)
+ || (ci->values[1].type != OCONFIG_TYPE_STRING))
+ {
+ ERROR ("Target `replace': The `%s' option requires exactly two string "
+ "arguments.", ci->key);
+ return (-1);
+ }
+ }
+ else
+ {
+ if ((ci->values_num != 3)
+ || (ci->values[0].type != OCONFIG_TYPE_STRING)
+ || (ci->values[1].type != OCONFIG_TYPE_STRING)
+ || (ci->values[2].type != OCONFIG_TYPE_STRING))
+ {
+ ERROR ("Target `replace': The `%s' option requires exactly three string "
+ "arguments.", ci->key);
+ return (-1);
+ }
+ }
+
+ if (strlen (ci->values[0].value.string) == 0)
+ {
+ ERROR ("Target `replace': The `%s' option does not accept empty string as "
+ "first argument.", ci->key);
+ return (-1);
+ }
+
+ act = calloc (1, sizeof (*act));
+ if (act == NULL)
+ {
+ ERROR ("tr_config_add_meta_action: calloc failed.");
+ return (-ENOMEM);
+ }
+
+ act->key = NULL;
+ act->replacement = NULL;
+
+ status = regcomp (&act->re, ci->values[1].value.string, REG_EXTENDED);
+ if (status != 0)
+ {
+ char errbuf[1024] = "";
+
+ /* regerror assures null termination. */
+ regerror (status, &act->re, errbuf, sizeof (errbuf));
+ ERROR ("Target `replace': Compiling the regular expression `%s' "
+ "failed: %s.",
+ ci->values[1].value.string, errbuf);
+ sfree (act->key);
+ sfree (act);
+ return (-EINVAL);
+ }
+
+ act->key = tr_strdup (ci->values[0].value.string);
+ if (act->key == NULL)
+ {
+ ERROR ("tr_config_add_meta_action: tr_strdup failed.");
+ tr_meta_data_action_destroy (act);
+ return (-ENOMEM);
+ }
+
+ if (!should_delete) {
+ act->replacement = tr_strdup (ci->values[2].value.string);
+ if (act->replacement == NULL)
+ {
+ ERROR ("tr_config_add_meta_action: tr_strdup failed.");
+ tr_meta_data_action_destroy (act);
+ return (-ENOMEM);
+ }
+ }
+
+ /* Insert action at end of list. */
+ if (*dest == NULL)
+ *dest = act;
+ else
+ {
+ tr_meta_data_action_t *prev;
+
+ prev = *dest;
+ while (prev->next != NULL)
+ prev = prev->next;
+
+ prev->next = act;
+ }
+
+ return (0);
+} /* }}} int tr_config_add_meta_action */
+
static int tr_action_invoke (tr_action_t *act_head, /* {{{ */
- char *buffer_in, size_t buffer_in_size, int may_be_empty)
+ char *buffer_in, size_t buffer_in_size, _Bool may_be_empty)
{
- tr_action_t *act;
int status;
char buffer[DATA_MAX_NAME_LEN];
- regmatch_t matches[8];
+ regmatch_t matches[8] = { [0] = { 0 } };
if (act_head == NULL)
return (-EINVAL);
sstrncpy (buffer, buffer_in, sizeof (buffer));
- memset (matches, 0, sizeof (matches));
DEBUG ("target_replace plugin: tr_action_invoke: <- buffer = %s;", buffer);
- for (act = act_head; act != NULL; act = act->next)
+ for (tr_action_t *act = act_head; act != NULL; act = act->next)
{
char temp[DATA_MAX_NAME_LEN];
char *subst_status;
return (0);
} /* }}} int tr_action_invoke */
+static int tr_meta_data_action_invoke ( /* {{{ */
+ tr_meta_data_action_t *act_head, meta_data_t **dest)
+{
+ int status;
+ regmatch_t matches[8] = { [0] = { 0 } };
+
+ if (act_head == NULL)
+ return (-EINVAL);
+
+ if ((*dest) == NULL) /* nothing to do */
+ return (0);
+
+ for (tr_meta_data_action_t *act = act_head; act != NULL; act = act->next)
+ {
+ char temp[DATA_MAX_NAME_LEN];
+ char *subst_status;
+ int value_type;
+ int meta_data_status;
+ char *value;
+ meta_data_t *result;
+
+ value_type = meta_data_type (*dest, act->key);
+ if (value_type == 0) /* not found */
+ continue;
+ if (value_type != MD_TYPE_STRING)
+ {
+ WARNING ("Target `replace': Attempting replace on metadata key `%s', "
+ "which isn't a string.",
+ act->key);
+ continue;
+ }
+
+ meta_data_status = meta_data_get_string (*dest, act->key, &value);
+ if (meta_data_status != 0)
+ {
+ ERROR ("Target `replace': Unable to retrieve metadata value for `%s'.",
+ act->key);
+ return (meta_data_status);
+ }
+
+ DEBUG ("target_replace plugin: tr_meta_data_action_invoke: `%s' "
+ "old value = `%s'", act->key, value);
+
+ status = regexec (&act->re, value,
+ STATIC_ARRAY_SIZE (matches), matches,
+ /* flags = */ 0);
+ if (status == REG_NOMATCH)
+ {
+ sfree (value);
+ continue;
+ }
+ else if (status != 0)
+ {
+ char errbuf[1024] = "";
+
+ regerror (status, &act->re, errbuf, sizeof (errbuf));
+ ERROR ("Target `replace': Executing a regular expression failed: %s.",
+ errbuf);
+ sfree (value);
+ continue;
+ }
+
+ if (act->replacement == NULL)
+ {
+ /* no replacement; delete the key */
+ DEBUG ("target_replace plugin: tr_meta_data_action_invoke: "
+ "deleting `%s'", act->key);
+ meta_data_delete (*dest, act->key);
+ sfree (value);
+ continue;
+ }
+
+ subst_status = subst (temp, sizeof (temp), value,
+ (size_t) matches[0].rm_so, (size_t) matches[0].rm_eo, act->replacement);
+ if (subst_status == NULL)
+ {
+ ERROR ("Target `replace': subst (value = %s, start = %zu, end = %zu, "
+ "replacement = %s) failed.",
+ value, (size_t) matches[0].rm_so, (size_t) matches[0].rm_eo,
+ act->replacement);
+ sfree (value);
+ continue;
+ }
+
+ DEBUG ("target_replace plugin: tr_meta_data_action_invoke: `%s' "
+ "value `%s' -> `%s'", act->key, value, temp);
+
+ if ((result = meta_data_create()) == NULL)
+ {
+ ERROR ("Target `replace': failed to create metadata for `%s'.",
+ act->key);
+ sfree (value);
+ return (-ENOMEM);
+ }
+
+ meta_data_status = meta_data_add_string (result, act->key, temp);
+ if (meta_data_status != 0)
+ {
+ ERROR ("Target `replace': Unable to set metadata value for `%s'.",
+ act->key);
+ meta_data_destroy (result);
+ sfree (value);
+ return (meta_data_status);
+ }
+
+ meta_data_clone_merge (dest, result);
+ meta_data_destroy (result);
+ sfree (value);
+ } /* for (act = act_head; act != NULL; act = act->next) */
+
+ return (0);
+} /* }}} int tr_meta_data_action_invoke */
+
static int tr_destroy (void **user_data) /* {{{ */
{
tr_data_t *data;
tr_action_destroy (data->plugin_instance);
/* tr_action_destroy (data->type); */
tr_action_destroy (data->type_instance);
+ tr_meta_data_action_destroy (data->meta);
sfree (data);
return (0);
{
tr_data_t *data;
int status;
- int i;
data = calloc (1, sizeof (*data));
if (data == NULL)
data->plugin_instance = NULL;
/* data->type = NULL; */
data->type_instance = NULL;
+ data->meta = NULL;
status = 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;
else if (strcasecmp ("TypeInstance", child->key) == 0)
status = tr_config_add_action (&data->type_instance, child,
/* may be empty = */ 1);
+ else if (strcasecmp ("MetaData", child->key) == 0)
+ status = tr_config_add_meta_action (&data->meta, child,
+ /* should delete = */ 0);
+ else if (strcasecmp ("DeleteMetaData", child->key) == 0)
+ status = tr_config_add_meta_action (&data->meta, child,
+ /* should delete = */ 1);
else
{
ERROR ("Target `replace': The `%s' configuration option is not understood "
&& (data->plugin == NULL)
&& (data->plugin_instance == NULL)
/* && (data->type == NULL) */
- && (data->type_instance == NULL))
+ && (data->type_instance == NULL)
+ && (data->meta == NULL))
{
ERROR ("Target `replace': You need to set at least one of `Host', "
"`Plugin', `PluginInstance' or `TypeInstance'.");
return (-EINVAL);
}
+ if (data->meta != NULL)
+ {
+ tr_meta_data_action_invoke (data->meta, &(vl->meta));
+ }
+
#define HANDLE_FIELD(f,e) \
if (data->f != NULL) \
tr_action_invoke (data->f, vl->f, sizeof (vl->f), e)
HANDLE_FIELD (host, 0);
HANDLE_FIELD (plugin, 0);
HANDLE_FIELD (plugin_instance, 1);
- /* HANDLE_FIELD (type); */
+ /* HANDLE_FIELD (type, 0); */
HANDLE_FIELD (type_instance, 1);
return (FC_TARGET_CONTINUE);
void module_register (void)
{
- target_proc_t tproc;
+ target_proc_t tproc = { 0 };
- memset (&tproc, 0, sizeof (tproc));
tproc.create = tr_create;
tproc.destroy = tr_destroy;
tproc.invoke = tr_invoke;
**/
#include "collectd.h"
+
#include "common.h"
#include "filter_chain.h"
{
size_t new_data_sources_num;
char **temp;
- int i;
/* Check number of arbuments. */
if (ci->values_num < 1)
}
/* Check type of arguments */
- for (i = 0; i < ci->values_num; i++)
+ for (int i = 0; i < ci->values_num; i++)
{
if (ci->values[i].type == OCONFIG_TYPE_STRING)
continue;
data->data_sources = temp;
/* Copy the strings, allocating memory as needed. */
- for (i = 0; i < ci->values_num; i++)
+ for (int i = 0; i < ci->values_num; i++)
{
size_t j;
if ((data != NULL) && (data->data_sources != NULL))
{
- size_t i;
- for (i = 0; i < data->data_sources_num; i++)
+ for (size_t i = 0; i < data->data_sources_num; i++)
sfree (data->data_sources[i]);
sfree (data->data_sources);
}
{
ts_data_t *data;
int status;
- int i;
data = calloc (1, sizeof (*data));
if (data == NULL)
data->offset = NAN;
status = 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;
notification_meta_t __attribute__((unused)) **meta, void **user_data)
{
ts_data_t *data;
- size_t i;
if ((ds == NULL) || (vl == NULL) || (user_data == NULL))
return (-EINVAL);
return (-EINVAL);
}
- for (i = 0; i < ds->ds_num; i++)
+ for (size_t i = 0; i < ds->ds_num; i++)
{
/* If we've got a list of data sources, is it in the list? */
if (data->data_sources) {
void module_register (void)
{
- target_proc_t tproc;
+ target_proc_t tproc = { 0 };
- memset (&tproc, 0, sizeof (tproc));
tproc.create = ts_create;
tproc.destroy = ts_destroy;
tproc.invoke = ts_invoke;
**/
#include "collectd.h"
+
#include "common.h"
#include "filter_chain.h"
+#include "meta_data.h"
+#include "utils_subst.h"
+
+struct ts_key_list_s
+{
+ char *key;
+ struct ts_key_list_s *next;
+};
+typedef struct ts_key_list_s ts_key_list_t;
+
+static void ts_key_list_free (ts_key_list_t *l) /* {{{ */
+{
+ if (l == NULL)
+ return;
+
+ sfree (l->key);
+
+ if (l->next != NULL)
+ ts_key_list_free (l->next);
+
+ sfree (l);
+} /* }}} void ts_name_list_free */
struct ts_data_s
{
/* char *type; */
char *type_instance;
meta_data_t *meta;
+ ts_key_list_t *meta_delete;
};
typedef struct ts_data_s ts_data_t;
|| (ci->values[1].type != OCONFIG_TYPE_STRING))
{
ERROR ("ts_util_get_key_and_string_wo_strdup: The %s option requires "
- "exactly two string argument.", ci->key);
+ "exactly two string arguments.", ci->key);
return (-1);
}
if (strlen (key) == 0)
{
- ERROR ("Target `set': The `%s' option does not accept empty string as first argument.",
- ci->key);
+ ERROR ("Target `set': The `%s' option does not accept empty string as "
+ "first argument.", ci->key);
return (-1);
}
if (!may_be_empty && (strlen (string) == 0))
{
- ERROR ("Target `set': The `%s' option does not accept empty string as second argument.",
- ci->key);
+ ERROR ("Target `set': The `%s' option does not accept empty string as "
+ "second argument.", ci->key);
return (-1);
}
if ((*dest) == NULL)
{
- // Create a new meta_data_t
+ /* Create a new meta_data_t */
if ((*dest = meta_data_create()) == NULL)
{
ERROR ("Target `set': failed to create a meta data for `%s'.", ci->key);
- return (-1);
+ return (-ENOMEM);
}
}
return (meta_data_add_string (*dest, key, string));
} /* }}} int ts_config_add_meta */
+static int ts_config_add_meta_delete (ts_key_list_t **dest, /* {{{ */
+ const oconfig_item_t *ci)
+{
+ ts_key_list_t *entry = NULL;
+
+ entry = calloc (1, sizeof (*entry));
+ if (entry == NULL)
+ {
+ ERROR ("ts_config_add_meta_delete: calloc failed.");
+ return (-ENOMEM);
+ }
+
+ if (cf_util_get_string (ci, &entry->key) != 0)
+ {
+ ts_key_list_free (entry);
+ return (-1); /* An error has already been reported. */
+ }
+
+ if (strlen (entry->key) == 0)
+ {
+ ERROR ("Target `set': The `%s' option does not accept empty string as "
+ "first argument.", ci->key);
+ ts_key_list_free (entry);
+ return (-1);
+ }
+
+ entry->next = *dest;
+ *dest = entry;
+
+ return (0);
+} /* }}} int ts_config_add_meta_delete */
+
+static void ts_subst (char *dest, size_t size, const char *string, /* {{{ */
+ const value_list_t *vl)
+{
+ char temp[DATA_MAX_NAME_LEN];
+
+ /* Initialize the field with the template. */
+ sstrncpy (dest, string, size);
+
+ if (strchr (dest, '%') == NULL)
+ return;
+
+#define REPLACE_FIELD(t, v) \
+ if (subst_string (temp, sizeof (temp), dest, t, v) != NULL) \
+ sstrncpy (dest, temp, size);
+ REPLACE_FIELD ("%{host}", vl->host);
+ REPLACE_FIELD ("%{plugin}", vl->plugin);
+ REPLACE_FIELD ("%{plugin_instance}", vl->plugin_instance);
+ REPLACE_FIELD ("%{type}", vl->type);
+ REPLACE_FIELD ("%{type_instance}", vl->type_instance);
+
+ if (vl->meta != NULL)
+ {
+ char **meta_toc;
+ int meta_entries = meta_data_toc (vl->meta, &meta_toc);
+ for (int i = 0; i < meta_entries; i++)
+ {
+ char meta_name[DATA_MAX_NAME_LEN];
+ char *value_str;
+ const char *key = meta_toc[i];
+
+ ssnprintf (meta_name, sizeof (meta_name), "%%{meta:%s}", key);
+ if (meta_data_as_string (vl->meta, key, &value_str) != 0)
+ continue;
+
+ REPLACE_FIELD (meta_name, value_str);
+ sfree (value_str);
+ }
+
+ strarray_free (meta_toc, (size_t) meta_entries);
+ }
+} /* }}} int ts_subst */
+
static int ts_destroy (void **user_data) /* {{{ */
{
ts_data_t *data;
/* free (data->type); */
free (data->type_instance);
meta_data_destroy(data->meta);
+ ts_key_list_free (data->meta_delete);
free (data);
return (0);
{
ts_data_t *data;
int status;
- int i;
data = calloc (1, sizeof (*data));
if (data == NULL)
/* data->type = NULL; */
data->type_instance = NULL;
data->meta = NULL;
+ data->meta_delete = NULL;
status = 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;
else if (strcasecmp ("TypeInstance", child->key) == 0)
status = ts_config_add_string (&data->type_instance, child,
/* may be empty = */ 1);
- else if (strcasecmp ("MetaDataSet", child->key) == 0)
+ else if (strcasecmp ("MetaData", child->key) == 0)
status = ts_config_add_meta (&data->meta, child,
/* may be empty = */ 1);
+ else if (strcasecmp ("DeleteMetaData", child->key) == 0)
+ status = ts_config_add_meta_delete (&data->meta_delete, child);
else
{
ERROR ("Target `set': The `%s' configuration option is not understood "
&& (data->plugin_instance == NULL)
/* && (data->type == NULL) */
&& (data->type_instance == NULL)
- && (data->meta == NULL))
+ && (data->meta == NULL)
+ && (data->meta_delete == NULL))
{
ERROR ("Target `set': You need to set at least one of `Host', "
"`Plugin', `PluginInstance', `TypeInstance', "
- "`MetaDataSet' or `MetaDataEval'.");
+ "`MetaData', or `DeleteMetaData'.");
status = -1;
}
+ if (data->meta != NULL)
+ {
+ /* If data->meta_delete is NULL, this loop is a no-op. */
+ for (ts_key_list_t *l=data->meta_delete; l != NULL; l = l->next)
+ {
+ if (meta_data_type (data->meta, l->key) != 0)
+ {
+ /* MetaData and DeleteMetaData for the same key. */
+ ERROR ("Target `set': Can only have one of `MetaData' or "
+ "`DeleteMetaData' for any given key.");
+ status = -1;
+ }
+ }
+ }
+
break;
}
notification_meta_t __attribute__((unused)) **meta, void **user_data)
{
ts_data_t *data;
+ value_list_t orig;
+ meta_data_t *new_meta = NULL;
if ((ds == NULL) || (vl == NULL) || (user_data == NULL))
return (-EINVAL);
return (-EINVAL);
}
+ orig = *vl;
+
if (data->meta != NULL)
{
- meta_data_clone_merge(&(vl->meta), data->meta);
+ char temp[DATA_MAX_NAME_LEN*2];
+ int meta_entries;
+ char **meta_toc;
+
+ if ((new_meta = meta_data_create()) == NULL)
+ {
+ ERROR ("Target `set': failed to create replacement metadata.");
+ return (-ENOMEM);
+ }
+
+ meta_entries = meta_data_toc (data->meta, &meta_toc);
+ for (int i = 0; i < meta_entries; i++)
+ {
+ const char *key = meta_toc[i];
+ char *string;
+ int status;
+
+ status = meta_data_get_string (data->meta, key, &string);
+ if (status)
+ {
+ ERROR ("Target `set': Unable to get replacement metadata value `%s'.",
+ key);
+ strarray_free (meta_toc, (size_t) meta_entries);
+ return (status);
+ }
+
+ ts_subst (temp, sizeof (temp), string, &orig);
+
+ DEBUG ("target_set: ts_invoke: setting metadata value for key `%s': "
+ "`%s'.", key, temp);
+
+ sfree (string);
+
+ status = meta_data_add_string (new_meta, key, temp);
+ if (status)
+ {
+ ERROR ("Target `set': Unable to set metadata value `%s'.", key);
+ strarray_free (meta_toc, (size_t) meta_entries);
+ return (status);
+ }
+ }
+
+ strarray_free (meta_toc, (size_t) meta_entries);
+ }
+
+#define SUBST_FIELD(f) \
+ if (data->f != NULL) { \
+ ts_subst (vl->f, sizeof (vl->f), data->f, &orig); \
+ DEBUG ("target_set: ts_invoke: setting "#f": `%s'.", vl->f); \
+ }
+ SUBST_FIELD (host);
+ SUBST_FIELD (plugin);
+ SUBST_FIELD (plugin_instance);
+ /* SUBST_FIELD (type); */
+ SUBST_FIELD (type_instance);
+
+ /* Need to merge the metadata in now, because of the shallow copy. */
+ if (new_meta != NULL)
+ {
+ meta_data_clone_merge(&(vl->meta), new_meta);
+ meta_data_destroy(new_meta);
}
-#define SET_FIELD(f) if (data->f != NULL) { sstrncpy (vl->f, data->f, sizeof (vl->f)); }
- SET_FIELD (host);
- SET_FIELD (plugin);
- SET_FIELD (plugin_instance);
- /* SET_FIELD (type); */
- SET_FIELD (type_instance);
+ /* If data->meta_delete is NULL, this loop is a no-op. */
+ for (ts_key_list_t *l=data->meta_delete; l != NULL; l = l->next)
+ {
+ DEBUG ("target_set: ts_invoke: deleting metadata value for key `%s'.",
+ l->key);
+ meta_data_delete(vl->meta, l->key);
+ }
return (FC_TARGET_CONTINUE);
} /* }}} int ts_invoke */
void module_register (void)
{
- target_proc_t tproc;
+ target_proc_t tproc = { 0 };
- memset (&tproc, 0, sizeof (tproc));
tproc.create = ts_create;
tproc.destroy = ts_destroy;
tproc.invoke = ts_invoke;
**/
#include "collectd.h"
+
#include "plugin.h"
#include "common.h"
#include "filter_chain.h"
static int v5_df (const data_set_t *ds, value_list_t *vl) /* {{{ */
{
value_list_t new_vl;
- value_t new_value;
/* Can't upgrade if both instances have been set. */
if ((vl->plugin_instance[0] != 0)
memcpy (&new_vl, vl, sizeof (new_vl));
/* Reset data we can't simply copy */
- new_vl.values = &new_value;
+ new_vl.values = &(value_t) { .gauge = NAN };
new_vl.values_len = 1;
new_vl.meta = NULL;
static int v5_mysql_qcache (const data_set_t *ds, value_list_t *vl) /* {{{ */
{
value_list_t new_vl;
- value_t new_value;
if (vl->values_len != 5)
return (FC_TARGET_STOP);
memcpy (&new_vl, vl, sizeof (new_vl));
/* Reset data we can't simply copy */
- new_vl.values = &new_value;
+ new_vl.values = &(value_t) { .gauge = NAN };
new_vl.values_len = 1;
new_vl.meta = NULL;
static int v5_mysql_threads (const data_set_t *ds, value_list_t *vl) /* {{{ */
{
value_list_t new_vl;
- value_t new_value;
if (vl->values_len != 4)
return (FC_TARGET_STOP);
memcpy (&new_vl, vl, sizeof (new_vl));
/* Reset data we can't simply copy */
- new_vl.values = &new_value;
+ new_vl.values = &(value_t) { .gauge = NAN };
new_vl.values_len = 1;
new_vl.meta = NULL;
static int v5_zfs_arc_counts (const data_set_t *ds, value_list_t *vl) /* {{{ */
{
value_list_t new_vl;
- value_t new_value;
_Bool is_hits;
if (vl->values_len != 4)
memcpy (&new_vl, vl, sizeof (new_vl));
/* Reset data we can't simply copy */
- new_vl.values = &new_value;
+ new_vl.values = &(value_t) { .gauge = NAN };
new_vl.values_len = 1;
new_vl.meta = NULL;
static int v5_zfs_arc_l2_bytes (const data_set_t *ds, value_list_t *vl) /* {{{ */
{
value_list_t new_vl;
- value_t new_values[2];
if (vl->values_len != 2)
return (FC_TARGET_STOP);
memcpy (&new_vl, vl, sizeof (new_vl));
/* Reset data we can't simply copy */
- new_vl.values = new_values;
- new_vl.values_len = 2;
new_vl.meta = NULL;
/* Change the type/-instance to "io_octets-L2" */
sstrncpy (new_vl.type_instance, "L2", sizeof (new_vl.type_instance));
/* Copy the actual values. */
- new_vl.values[0].derive = (derive_t) vl->values[0].counter;
- new_vl.values[1].derive = (derive_t) vl->values[1].counter;
+ value_t values[] = {
+ { .derive = (derive_t) vl->values[0].counter },
+ { .derive = (derive_t) vl->values[1].counter },
+ };
+ new_vl.values = values;
+ new_vl.values_len = STATIC_ARRAY_SIZE (values);
/* Dispatch new value lists instead of this one */
plugin_dispatch_values (&new_vl);
static int v5_zfs_arc_l2_size (const data_set_t *ds, value_list_t *vl) /* {{{ */
{
value_list_t new_vl;
- value_t new_value;
if (vl->values_len != 1)
return (FC_TARGET_STOP);
memcpy (&new_vl, vl, sizeof (new_vl));
/* Reset data we can't simply copy */
- new_vl.values = &new_value;
+ new_vl.values = &(value_t) { .gauge = NAN };
new_vl.values_len = 1;
new_vl.meta = NULL;
static int v5_zfs_arc_ratio (const data_set_t *ds, value_list_t *vl) /* {{{ */
{
value_list_t new_vl;
- value_t new_value;
if (vl->values_len != 1)
return (FC_TARGET_STOP);
memcpy (&new_vl, vl, sizeof (new_vl));
/* Reset data we can't simply copy */
- new_vl.values = &new_value;
+ new_vl.values = &(value_t) { .gauge = NAN };
new_vl.values_len = 1;
new_vl.meta = NULL;
static int v5_zfs_arc_size (const data_set_t *ds, value_list_t *vl) /* {{{ */
{
value_list_t new_vl;
- value_t new_value;
if (vl->values_len != 4)
return (FC_TARGET_STOP);
memcpy (&new_vl, vl, sizeof (new_vl));
/* Reset data we can't simply copy */
- new_vl.values = &new_value;
+ new_vl.values = &(value_t) { .gauge = NAN };
new_vl.values_len = 1;
new_vl.meta = NULL;
void module_register (void)
{
- target_proc_t tproc;
+ target_proc_t tproc = { 0 };
- memset (&tproc, 0, sizeof (tproc));
tproc.create = v5_create;
tproc.destroy = v5_destroy;
tproc.invoke = v5_invoke;
*/
#include "collectd.h"
+
#include "common.h"
#include "plugin.h"
{
value_t values[1];
value_list_t vl = VALUE_LIST_INIT;
- int i;
conn_prepare_vl (&vl, values);
ssnprintf (vl.plugin_instance, sizeof (vl.plugin_instance),
"%"PRIu16"-local", pe->port);
- for (i = 1; i <= TCP_STATE_MAX; i++)
+ for (int i = 1; i <= TCP_STATE_MAX; i++)
{
vl.values[0].gauge = pe->count_local[i];
ssnprintf (vl.plugin_instance, sizeof (vl.plugin_instance),
"%"PRIu16"-remote", pe->port);
- for (i = 1; i <= TCP_STATE_MAX; i++)
+ for (int i = 1; i <= TCP_STATE_MAX; i++)
{
vl.values[0].gauge = pe->count_remote[i];
{
value_t values[1];
value_list_t vl = VALUE_LIST_INIT;
- int i;
conn_prepare_vl (&vl, values);
sstrncpy (vl.plugin_instance, "all", sizeof (vl.plugin_instance));
- for (i = 1; i <= TCP_STATE_MAX; i++)
+ for (int i = 1; i <= TCP_STATE_MAX; i++)
{
vl.values[0].gauge = count_total[i];
static void conn_submit_all (void)
{
- port_entry_t *pe;
-
if (port_collect_total)
conn_submit_port_total ();
- for (pe = port_list_head; pe != NULL; pe = pe->next)
+ for (port_entry_t *pe = port_list_head; pe != NULL; pe = pe->next)
conn_submit_port_entry (pe);
} /* void conn_submit_all */
{
#if HAVE_STRUCT_LINUX_INET_DIAG_REQ
int fd;
- struct sockaddr_nl nladdr;
- struct nlreq req;
- struct msghdr msg;
- struct iovec iov;
struct inet_diag_msg *r;
char buf[8192];
return (-1);
}
- memset(&nladdr, 0, sizeof(nladdr));
- nladdr.nl_family = AF_NETLINK;
-
- memset(&req, 0, sizeof(req));
- req.nlh.nlmsg_len = sizeof(req);
- req.nlh.nlmsg_type = TCPDIAG_GETSOCK;
- /* NLM_F_ROOT: return the complete table instead of a single entry.
- * NLM_F_MATCH: return all entries matching criteria (not implemented)
- * NLM_F_REQUEST: must be set on all request messages */
- req.nlh.nlmsg_flags = NLM_F_ROOT | NLM_F_MATCH | NLM_F_REQUEST;
- req.nlh.nlmsg_pid = 0;
- /* The sequence_number is used to track our messages. Since netlink is not
- * reliable, we don't want to end up with a corrupt or incomplete old
- * message in case the system is/was out of memory. */
- req.nlh.nlmsg_seq = ++sequence_number;
- req.r.idiag_family = AF_INET;
- req.r.idiag_states = 0xfff;
- req.r.idiag_ext = 0;
-
- memset(&iov, 0, sizeof(iov));
- iov.iov_base = &req;
- iov.iov_len = sizeof(req);
-
- memset(&msg, 0, sizeof(msg));
- msg.msg_name = (void*)&nladdr;
- msg.msg_namelen = sizeof(nladdr);
- msg.msg_iov = &iov;
- msg.msg_iovlen = 1;
+ struct sockaddr_nl nladdr = {
+ .nl_family = AF_NETLINK
+ };
+
+ struct nlreq req = {
+ .nlh.nlmsg_len = sizeof(req),
+ .nlh.nlmsg_type = TCPDIAG_GETSOCK,
+ /* NLM_F_ROOT: return the complete table instead of a single entry.
+ * NLM_F_MATCH: return all entries matching criteria (not implemented)
+ * NLM_F_REQUEST: must be set on all request messages */
+ .nlh.nlmsg_flags = NLM_F_ROOT | NLM_F_MATCH | NLM_F_REQUEST,
+ .nlh.nlmsg_pid = 0,
+ /* The sequence_number is used to track our messages. Since netlink is not
+ * reliable, we don't want to end up with a corrupt or incomplete old
+ * message in case the system is/was out of memory. */
+ .nlh.nlmsg_seq = ++sequence_number,
+ .r.idiag_family = AF_INET,
+ .r.idiag_states = 0xfff,
+ .r.idiag_ext = 0
+ };
+
+ struct iovec iov = {
+ .iov_base = &req,
+ .iov_len = sizeof(req)
+ };
+
+ struct msghdr msg = {
+ .msg_name = (void*)&nladdr,
+ .msg_namelen = sizeof(nladdr),
+ .msg_iov = &iov,
+ .msg_iovlen = 1
+ };
if (sendmsg (fd, &msg, 0) < 0)
{
static int conn_read (void)
{
int size;
- int i;
int nconn;
void *data;
struct netinfo_header *header;
nconn = header->size;
conn = (struct netinfo_conn *)(data + sizeof(struct netinfo_header));
- for (i=0; i < nconn; conn++, i++)
+ for (int i = 0; i < nconn; conn++, i++)
{
conn_handle_ports (conn->srcport, conn->dstport, conn->tcp_state);
}
**/
#include "collectd.h"
+
#include "common.h"
#include "plugin.h"
/*
* Submits a gauge value to the collectd daemon
*/
- 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, "teamspeak2", sizeof (vl.plugin));
/*
* Submits the io rx/tx tuple to the collectd daemon
*/
- value_t values[2];
value_list_t vl = VALUE_LIST_INIT;
-
- values[0].derive = rx;
- values[1].derive = tx;
+ value_t values[] = {
+ { .derive = rx },
+ { .derive = tx },
+ };
vl.values = values;
- vl.values_len = 2;
+ vl.values_len = STATIC_ARRAY_SIZE (values);
sstrncpy (vl.host, hostname_g, sizeof (vl.host));
sstrncpy (vl.plugin, "teamspeak2", sizeof (vl.plugin));
* Returns connected file objects or establishes the connection
* if it's not already present
*/
- struct addrinfo ai_hints;
struct addrinfo *ai_head;
- struct addrinfo *ai_ptr;
int sd = -1;
int status;
}
/* Get all addrs for this hostname */
- memset (&ai_hints, 0, sizeof (ai_hints));
-#ifdef AI_ADDRCONFIG
- ai_hints.ai_flags |= AI_ADDRCONFIG;
-#endif
- ai_hints.ai_family = AF_UNSPEC;
- ai_hints.ai_socktype = SOCK_STREAM;
+ struct addrinfo ai_hints = {
+ .ai_family = AF_UNSPEC,
+ .ai_flags = AI_ADDRCONFIG,
+ .ai_socktype = SOCK_STREAM
+ };
status = getaddrinfo ((config_host != NULL) ? config_host : DEFAULT_HOST,
(config_port != NULL) ? config_port : DEFAULT_PORT,
}
/* Try all given hosts until we can connect to one */
- for (ai_ptr = ai_head; ai_ptr != NULL; ai_ptr = ai_ptr->ai_next)
+ for (struct addrinfo *ai_ptr = ai_head; ai_ptr != NULL; ai_ptr = ai_ptr->ai_next)
{
/* Create socket */
sd = socket (ai_ptr->ai_family, ai_ptr->ai_socktype,
gauge_t packet_loss = NAN;
int valid = 0;
- char plugin_instance[DATA_MAX_NAME_LEN];
+ char plugin_instance[DATA_MAX_NAME_LEN] = { 0 };
FILE *read_fh;
FILE *write_fh;
if (vserver == NULL)
{
/* Request global information */
- memset (plugin_instance, 0, sizeof (plugin_instance));
-
status = tss2_send_request (write_fh, "gi\r\n");
}
else
* Poll function which collects global and vserver information
* and submits it to collectd
*/
- vserver_list_t *vserver;
int success = 0;
int status;
}
/* Handle vservers */
- for (vserver = server_list; vserver != NULL; vserver = vserver->next)
+ for (vserver_list_t *vserver = server_list; vserver != NULL; vserver = vserver->next)
{
status = tss2_read_vserver (vserver);
if (status == 0)
**/
#include "collectd.h"
+
#include "common.h"
#include "plugin.h"
-#include "configfile.h"
#if HAVE_TERMIOS_H && HAVE_SYS_IOCTL_H && HAVE_MATH_H
# include <termios.h>
int package_buffer_pos;
fd_set input;
- struct timeval timeout;
+
+ /* Initialize timeout structure, set to 2 seconds */
+ struct timeval timeout = {
+ .tv_sec = 2
+ };
int end_flag;
int escape_flag;
FD_ZERO (&input);
FD_SET (fd, &input);
- /* Initialize timeout structure, set to 2 seconds */
- memset (&timeout, 0, sizeof (timeout));
- timeout.tv_sec = 2;
- timeout.tv_usec = 0;
-
/* clear out anything in the buffer */
tcflush (fd, TCIFLUSH);
while (end_flag == 0)
{
ssize_t receive_buffer_length;
- ssize_t i;
/* check for timeout or input error*/
status = select (fd + 1, &input, NULL, NULL, &timeout);
* the beginning of the package has been found. */
escape_flag = 0;
- for (i = 0; i < receive_buffer_length; i++)
+ for (ssize_t i = 0; i < receive_buffer_length; i++)
{
/* Check if previous byte was the escape byte. */
if (escape_flag == 1)
static void ted_submit (const char *type, 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, "ted", sizeof (vl.plugin));
double power;
double voltage;
int status;
- int i;
status = ted_open_device ();
if (status != 0)
power = NAN;
voltage = NAN;
- for (i = 0; i <= conf_retries; i++)
+ for (int i = 0; i <= conf_retries; i++)
{
status = ted_read_value (&power, &voltage);
if (status == 0)
**/
#include "collectd.h"
+
#include "common.h"
#include "plugin.h"
-#include "configfile.h"
#include "utils_ignorelist.h"
#if !KERNEL_LINUX
};
static void thermal_submit (const char *plugin_instance, enum dev_type dt,
- gauge_t value)
+ value_t value)
{
value_list_t vl = VALUE_LIST_INIT;
- value_t v;
-
- v.gauge = value;
- vl.values = &v;
+ vl.values = &value;
vl.values_len = 1;
sstrncpy (vl.host, hostname_g, sizeof (vl.host));
static int thermal_sysfs_device_read (const char __attribute__((unused)) *dir,
const char *name, void __attribute__((unused)) *user_data)
{
- char filename[256];
- char data[1024];
- int len;
+ char filename[PATH_MAX];
_Bool success = 0;
+ value_t value;
if (device_list && ignorelist_match (device_list, name))
return -1;
- len = ssnprintf (filename, sizeof (filename),
- "%s/%s/temp", dirname_sysfs, name);
- if ((len < 0) || ((size_t) len >= sizeof (filename)))
- return -1;
-
- len = (ssize_t) read_file_contents (filename, data, sizeof(data));
- if (len > 1 && data[--len] == '\n') {
- char *endptr = NULL;
- double temp;
-
- data[len] = 0;
- errno = 0;
- temp = strtod (data, &endptr) / 1000.0;
-
- if (endptr == data + len && errno == 0) {
- thermal_submit(name, TEMP, temp);
- success = 1;
- }
+ ssnprintf (filename, sizeof (filename), "%s/%s/temp", dirname_sysfs, name);
+ if (parse_value_file (filename, &value, DS_TYPE_GAUGE) == 0)
+ {
+ value.gauge /= 1000.0;
+ thermal_submit(name, TEMP, value);
+ success = 1;
}
- len = ssnprintf (filename, sizeof (filename),
- "%s/%s/cur_state", dirname_sysfs, name);
- if ((len < 0) || ((size_t) len >= sizeof (filename)))
- return -1;
-
- len = (ssize_t) read_file_contents (filename, data, sizeof(data));
- if (len > 1 && data[--len] == '\n') {
- char *endptr = NULL;
- double state;
-
- data[len] = 0;
- errno = 0;
- state = strtod (data, &endptr);
-
- if (endptr == data + len && errno == 0) {
- thermal_submit(name, COOLING_DEV, state);
- success = 1;
- }
+ ssnprintf (filename, sizeof (filename), "%s/%s/cur_state", dirname_sysfs, name);
+ if (parse_value_file (filename, &value, DS_TYPE_GAUGE) == 0)
+ {
+ thermal_submit(name, COOLING_DEV, value);
+ success = 1;
}
return (success ? 0 : -1);
temp = (strtod (data + len, &endptr) + add) * factor;
if (endptr != data + len && errno == 0) {
- thermal_submit(name, TEMP, temp);
+ thermal_submit(name, TEMP, (value_t) { .gauge = temp });
return 0;
}
}
**/
#include "collectd.h"
+
#include "common.h"
#include "plugin.h"
#include "utils_avltree.h"
static int ut_config_type (const threshold_t *th_orig, oconfig_item_t *ci)
{
- int i;
threshold_t th;
int status = 0;
th.hysteresis = 0;
th.flags = UT_FLAG_INTERESTING; /* interesting by default */
- for (i = 0; i < ci->children_num; i++)
+ for (int i = 0; i < ci->children_num; i++)
{
oconfig_item_t *option = ci->children + i;
static int ut_config_plugin (const threshold_t *th_orig, oconfig_item_t *ci)
{
- int i;
threshold_t th;
int status = 0;
memcpy (&th, th_orig, sizeof (th));
sstrncpy (th.plugin, ci->values[0].value.string, sizeof (th.plugin));
- for (i = 0; i < ci->children_num; i++)
+ for (int i = 0; i < ci->children_num; i++)
{
oconfig_item_t *option = ci->children + i;
static int ut_config_host (const threshold_t *th_orig, oconfig_item_t *ci)
{
- int i;
threshold_t th;
int status = 0;
memcpy (&th, th_orig, sizeof (th));
sstrncpy (th.host, ci->values[0].value.string, sizeof (th.host));
- for (i = 0; i < ci->children_num; i++)
+ for (int i = 0; i < ci->children_num; i++)
{
oconfig_item_t *option = ci->children + i;
{
gauge_t value;
gauge_t sum;
- size_t i;
sum = 0.0;
- for (i = 0; i < vl->values_len; i++)
+ for (size_t i = 0; i < vl->values_len; i++)
{
if (isnan (values[i]))
continue;
{ /* {{{ */
int ret = -1;
int ds_index = -1;
- size_t i;
gauge_t values_copy[ds->ds_num];
memcpy (values_copy, values, sizeof (values_copy));
}
/* Prepare `sum' and `num'. */
- for (i = 0; i < ds->ds_num; i++)
+ for (size_t i = 0; i < ds->ds_num; i++)
if (!isnan (values[i]))
{
num++;
if ((num == 0) /* All data sources are undefined. */
|| (sum == 0.0)) /* Sum is zero, cannot calculate percentage. */
{
- for (i = 0; i < ds->ds_num; i++)
+ for (size_t i = 0; i < ds->ds_num; i++)
values_copy[i] = NAN;
}
else /* We can actually calculate the percentage. */
{
- for (i = 0; i < ds->ds_num; i++)
+ for (size_t i = 0; i < ds->ds_num; i++)
values_copy[i] = 100.0 * values[i] / sum;
}
} /* if (UT_FLAG_PERCENTAGE) */
- for (i = 0; i < ds->ds_num; i++)
+ for (size_t i = 0; i < ds->ds_num; i++)
{
int status;
static int ut_config (oconfig_item_t *ci)
{ /* {{{ */
- int i;
int status = 0;
int old_size = c_avl_size (threshold_tree);
- threshold_t th;
-
if (threshold_tree == NULL)
{
threshold_tree = c_avl_create ((int (*) (const void *, const void *)) strcmp);
}
}
- memset (&th, '\0', sizeof (th));
- th.warning_min = NAN;
- th.warning_max = NAN;
- th.failure_min = NAN;
- th.failure_max = NAN;
-
- th.hits = 0;
- th.hysteresis = 0;
- th.flags = UT_FLAG_INTERESTING; /* interesting by default */
+ threshold_t th = {
+ .warning_min = NAN,
+ .warning_max = NAN,
+ .failure_min = NAN,
+ .failure_max = NAN,
+ .flags = UT_FLAG_INTERESTING /* interesting by default */
+ };
- for (i = 0; i < ci->children_num; i++)
+ for (int i = 0; i < ci->children_num; i++)
{
oconfig_item_t *option = ci->children + i;
**/
#include "collectd.h"
+
#include "plugin.h"
#include "common.h"
#include "utils_cache.h"
ecode, tcrdberrmsg(ecode));
}
-static void tt_submit (gauge_t val, const char* type)
+static void tt_submit (gauge_t value, const char* type)
{
- value_t values[1];
value_list_t vl = VALUE_LIST_INIT;
- values[0].gauge = val;
-
- vl.values = values;
- vl.values_len = STATIC_ARRAY_SIZE (values);
+ vl.values = &(value_t) { .gauge = value };
+ vl.values_len = 1;
sstrncpy (vl.host, config_host, sizeof (vl.host));
sstrncpy (vl.plugin, "tokyotyrant", sizeof (vl.plugin));
#define _GNU_SOURCE
#include "collectd.h"
+
#include "common.h"
#include "plugin.h"
#include "utils_time.h"
gauge_t value)
{
value_list_t vl = VALUE_LIST_INIT;
- value_t v;
- v.gauge = value;
- vl.values = &v;
+ vl.values = &(value_t) { .gauge = value };
vl.values_len = 1;
sstrncpy (vl.host, hostname_g, sizeof (vl.host));
sstrncpy (vl.plugin, PLUGIN_NAME, sizeof (vl.plugin));
struct thread_data *thread_base, struct core_data *core_base, struct pkg_data *pkg_base)
{
int retval;
- unsigned int pkg_no, core_no, thread_no;
- for (pkg_no = 0; pkg_no < topology.num_packages; ++pkg_no) {
- for (core_no = 0; core_no < topology.num_cores; ++core_no) {
- for (thread_no = 0; thread_no < topology.num_threads; ++thread_no) {
+ for (unsigned int pkg_no = 0; pkg_no < topology.num_packages; ++pkg_no) {
+ for (unsigned int core_no = 0; core_no < topology.num_cores; ++core_no) {
+ for (unsigned int thread_no = 0; thread_no < topology.num_threads; ++thread_no) {
struct thread_data *t;
struct core_data *c;
struct pkg_data *p;
const struct thread_data *thread_old_base, const struct core_data *core_old_base, const struct pkg_data *pkg_old_base)
{
int retval;
- unsigned int pkg_no, core_no, thread_no;
- for (pkg_no = 0; pkg_no < topology.num_packages; ++pkg_no) {
- for (core_no = 0; core_no < topology.num_cores; ++core_no) {
- for (thread_no = 0; thread_no < topology.num_threads; ++thread_no) {
+ for (unsigned int pkg_no = 0; pkg_no < topology.num_packages; ++pkg_no) {
+ for (unsigned int core_no = 0; core_no < topology.num_cores; ++core_no) {
+ for (unsigned int thread_no = 0; thread_no < topology.num_threads; ++thread_no) {
struct thread_data *t_delta;
const struct thread_data *t_old, *t_new;
struct core_data *c_delta;
{
va_list args;
char path[PATH_MAX];
- FILE *filep;
- int len, value;
+ int len;
va_start(args, fmt);
len = vsnprintf(path, sizeof(path), fmt, args);
return -1;
}
- filep = fopen(path, "r");
- if (!filep) {
- ERROR("turbostat plugin: Failed to open '%s'", path);
- return -1;
- }
- if (fscanf(filep, "%d", &value) != 1) {
- ERROR("turbostat plugin: Failed to parse number from '%s'", path);
- fclose(filep);
+ value_t v;
+ if (parse_value_file (path, &v, DS_TYPE_DERIVE) != 0) {
+ ERROR ("turbostat plugin: Parsing \"%s\" failed.", path);
return -1;
}
- fclose(filep);
- return value;
+
+ return (int) v.derive;
}
static int
static int __attribute__((warn_unused_result))
topology_probe(void)
{
- unsigned int i;
int ret;
unsigned int max_package_id, max_core_id, max_threads;
max_package_id = max_core_id = max_threads = 0;
* For online cpus
* find max_core_id, max_package_id
*/
- for (i = 0; i <= topology.max_cpu_id; ++i) {
+ for (unsigned int i = 0; i <= topology.max_cpu_id; ++i) {
unsigned int num_threads;
struct cpu_topology *cpu = &topology.cpus[i];
static int
allocate_counters(struct thread_data **threads, struct core_data **cores, struct pkg_data **packages)
{
- unsigned int i;
unsigned int total_threads, total_cores;
if ((topology.num_threads == 0)
return -1;
}
- for (i = 0; i < total_threads; ++i)
+ for (unsigned int i = 0; i < total_threads; ++i)
(*threads)[i].cpu_id = topology.max_cpu_id + 1;
total_cores = topology.num_cores * topology.num_packages;
static void
initialize_counters(void)
{
- unsigned int cpu_id;
-
- for (cpu_id = 0; cpu_id <= topology.max_cpu_id; ++cpu_id) {
+ for (unsigned int cpu_id = 0; cpu_id <= topology.max_cpu_id; ++cpu_id) {
if (cpu_is_not_present(cpu_id))
continue;
init_counter(EVEN_COUNTERS, cpu_id);
static int
check_permissions(void)
{
-#ifdef HAVE_SYS_CAPABILITY_H
- struct __user_cap_header_struct cap_header_data;
- cap_user_header_t cap_header = &cap_header_data;
- struct __user_cap_data_struct cap_data_data;
- cap_user_data_t cap_data = &cap_data_data;
- int ret = 0;
-#endif /* HAVE_SYS_CAPABILITY_H */
if (getuid() == 0) {
/* We have everything we need */
return 0;
-#ifndef HAVE_SYS_CAPABILITY_H
+#if !defined(HAVE_SYS_CAPABILITY_H) && !defined(CAP_SYS_RAWIO)
} else {
ERROR("turbostat plugin: Initialization failed: this plugin "
"requires collectd to run as root");
return -1;
}
-#else /* HAVE_SYS_CAPABILITY_H */
+#else /* HAVE_SYS_CAPABILITY_H && CAP_SYS_RAWIO */
}
- /* check for CAP_SYS_RAWIO */
- cap_header->pid = getpid();
- cap_header->version = _LINUX_CAPABILITY_VERSION;
- if (capget(cap_header, cap_data) < 0) {
- ERROR("turbostat plugin: capget failed");
- return -1;
- }
+ int ret = 0;
- if ((cap_data->effective & (1 << CAP_SYS_RAWIO)) == 0) {
+ if (check_capability(CAP_SYS_RAWIO) != 0) {
WARNING("turbostat plugin: Collectd doesn't have the "
"CAP_SYS_RAWIO capability. If you don't want to run "
"collectd as root, try running \"setcap "
"collectd a special capability (CAP_SYS_RAWIO) and read "
"access to /dev/cpu/*/msr (see previous warnings)");
return ret;
-#endif /* HAVE_SYS_CAPABILITY_H */
+#endif /* HAVE_SYS_CAPABILITY_H && CAP_SYS_RAWIO */
}
static int
df used:GAUGE:0:1125899906842623, free:GAUGE:0:1125899906842623
df_complex value:GAUGE:0:U
df_inodes value:GAUGE:0:U
+dilution_of_precision value:GAUGE:0:U
disk_io_time io_time:DERIVE:0:U, weighted_io_time:DERIVE:0:U
disk_latency read:GAUGE:0:U, write:GAUGE:0:U
disk_merged read:DERIVE:0:U, write:DERIVE:0:U
email_check value:GAUGE:0:U
email_count value:GAUGE:0:U
email_size value:GAUGE:0:U
+energy value:GAUGE:U:U
+energy_wh value:GAUGE:U:U
entropy value:GAUGE:0:4294967295
errors value:DERIVE:0:U
evicted_keys value:DERIVE:0:U
ping_droprate value:GAUGE:0:100
ping_stddev value:GAUGE:0:65535
players value:GAUGE:0:1000000
-power value:GAUGE:0:U
+power value:GAUGE:U:U
pressure value:GAUGE:0:U
protocol_counter value:DERIVE:0:U
ps_code value:GAUGE:0:9223372036854775807
route_etx value:GAUGE:0:U
route_metric value:GAUGE:0:U
routes value:GAUGE:0:U
+satellites value:GAUGE:0:U
segments value:GAUGE:0:65535
serial_octets rx:DERIVE:0:U, tx:DERIVE:0:U
signal_noise value:GAUGE:U:0
**/
#include "collectd.h"
+
#include "common.h"
#include "plugin.h"
-#include "configfile.h"
#include "utils_cmd_flush.h"
#include "utils_cmd_getval.h"
*/
static int us_open_socket (void)
{
- struct sockaddr_un sa;
+ struct sockaddr_un sa = { 0 };
int status;
sock_fd = socket (PF_UNIX, SOCK_STREAM, 0);
return (-1);
}
- memset (&sa, '\0', sizeof (sa));
sa.sun_family = AF_UNIX;
sstrncpy (sa.sun_path, (sock_file != NULL) ? sock_file : US_DEFAULT_PATH,
sizeof (sa.sun_path));
**/
#include "collectd.h"
+
#include "common.h"
#include "plugin.h"
extern kstat_ctl_t *kc;
#endif /* #endif HAVE_LIBKSTAT */
-static void uptime_submit (gauge_t uptime)
+static void uptime_submit (gauge_t value)
{
- value_t values[1];
value_list_t vl = VALUE_LIST_INIT;
- values[0].gauge = uptime;
-
- vl.values = values;
+ vl.values = &(value_t) { .gauge = value };
vl.values_len = 1;
sstrncpy (vl.host, hostname_g, sizeof (vl.host));
/* #endif HAVE_LIBKSTAT */
# elif HAVE_SYS_SYSCTL_H
- struct timeval boottv;
+ struct timeval boottv = { 0 };
size_t boottv_len;
int status;
- int mib[2];
-
- mib[0] = CTL_KERN;
- mib[1] = KERN_BOOTTIME;
+ int mib[] = { CTL_KERN, KERN_BOOTTIME };
boottv_len = sizeof (boottv);
- memset (&boottv, 0, boottv_len);
status = sysctl (mib, STATIC_ARRAY_SIZE (mib), &boottv, &boottv_len,
/* new_value = */ NULL, /* new_length = */ 0);
**/
#include "collectd.h"
+
#include "common.h"
#include "plugin.h"
static void users_submit (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, "users", sizeof (vl.plugin));
**/
#include "collectd.h"
+
#include "common.h"
#include "plugin.h"
#include "utils_parse_option.h"
char **identifiers = NULL;
size_t identifiers_num = 0;
- size_t i;
-
#define PRINT_TO_SOCK(fh, ...) \
do { \
if (fprintf (fh, __VA_ARGS__) < 0) { \
}
} /* while (*buffer != 0) */
- for (i = 0; (i == 0) || (i < plugins_num); i++)
+ for (size_t i = 0; (i == 0) || (i < plugins_num); i++)
{
char *plugin = NULL;
- size_t j;
if (plugins_num != 0)
plugin = plugins[i];
- for (j = 0; (j == 0) || (j < identifiers_num); j++)
+ for (size_t j = 0; (j == 0) || (j < identifiers_num); j++)
{
char *identifier = NULL;
int status;
**/
#include "collectd.h"
+
#include "common.h"
#include "plugin.h"
char *type;
char *type_instance;
- value_list_t vl;
threshold_t threshold;
int status;
return (-1);
}
- memset (&vl, 0, sizeof (vl));
+ value_list_t vl = {
+ .values = NULL
+ };
sstrncpy (vl.host, host, sizeof (vl.host));
sstrncpy (vl.plugin, plugin, sizeof (vl.plugin));
if (plugin_instance != NULL)
sstrncpy (vl.type_instance, type_instance, sizeof (vl.type_instance));
sfree (identifier_copy);
- memset (&threshold, 0, sizeof (threshold));
status = ut_search_threshold (&vl, &threshold);
if (status == ENOENT)
{
**/
#include "collectd.h"
+
#include "common.h"
#include "plugin.h"
const data_set_t *ds;
int status;
- size_t i;
if ((fh == NULL) || (buffer == NULL))
return (-1);
print_to_socket (fh, "%zu Value%s found\n", values_num,
(values_num == 1) ? "" : "s");
- for (i = 0; i < values_num; i++)
+ for (size_t i = 0; i < values_num; i++)
{
print_to_socket (fh, "%s=", ds->ds[i].name);
if (isnan (values[i]))
**/
#include "collectd.h"
+
#include "common.h"
#include "plugin.h"
#include "utils_parse_option.h"
#define free_everything_and_return(status) do { \
- size_t j; \
- for (j = 0; j < number; j++) { \
+ for (size_t j = 0; j < number; j++) { \
sfree(names[j]); \
names[j] = NULL; \
} \
char **names = NULL;
cdtime_t *times = NULL;
size_t number = 0;
- size_t i;
int status;
DEBUG ("utils_cmd_listval: handle_listval (fh = %p, buffer = %s);",
print_to_socket (fh, "%i Value%s found\n",
(int) number, (number == 1) ? "" : "s");
- for (i = 0; i < number; i++)
+ for (size_t i = 0; i < number; i++)
print_to_socket (fh, "%.3f %s\n", CDTIME_T_TO_DOUBLE (times[i]),
names[i]);
**/
#include "collectd.h"
+
#include "common.h"
#include "plugin.h"
int handle_putnotif (FILE *fh, char *buffer)
{
char *command;
- notification_t n;
+ notification_t n = { 0 };
int status;
if ((fh == NULL) || (buffer == NULL))
return (-1);
}
- memset (&n, '\0', sizeof (n));
-
status = 0;
while (*buffer != 0)
{
**/
#include "collectd.h"
+
#include "common.h"
#include "plugin.h"
uint32_t
crc32_buffer(const unsigned char *s, size_t len)
{
- size_t i;
uint32_t ret;
ret = 0;
- for (i = 0; i < len; i++)
+ for (size_t i = 0; i < len; i++)
ret = crc32_tab[(ret ^ s[i]) & 0xff] ^ (ret >> 8);
return ret;
}
**/
#include "collectd.h"
+
#include "common.h"
#include "utils_curl_stats.h"
curl_stats_t *curl_stats_from_config (oconfig_item_t *ci)
{
curl_stats_t *s;
- int i;
if (ci == NULL)
return NULL;
if (s == NULL)
return NULL;
- for (i = 0; i < ci->children_num; ++i)
+ for (int i = 0; i < ci->children_num; ++i)
{
oconfig_item_t *c = ci->children + i;
size_t field;
const char *hostname, const char *plugin, const char *plugin_instance)
{
value_list_t vl = VALUE_LIST_INIT;
- size_t field;
if (s == NULL)
return 0;
if (plugin_instance != NULL)
sstrncpy (vl.plugin_instance, plugin_instance, sizeof (vl.plugin_instance));
- for (field = 0; field < STATIC_ARRAY_SIZE (field_specs); ++field)
+ for (size_t field = 0; field < STATIC_ARRAY_SIZE (field_specs); ++field)
{
int status;
#ifndef UTILS_CURL_STATS_H
#define UTILS_CURL_STATS_H 1
-#include "configfile.h"
#include "plugin.h"
#include <curl/curl.h>
**/
#include "collectd.h"
+
#include "common.h"
#include "plugin.h"
-#include "configfile.h"
#include "utils_db_query.h"
/*
{
char **array;
size_t array_len;
- int i;
if (ci->values_num < 1)
{
return (-1);
}
- for (i = 0; i < ci->values_num; i++)
+ for (int i = 0; i < ci->values_num; i++)
{
if (ci->values[i].type != OCONFIG_TYPE_STRING)
{
}
*ret_array = array;
- for (i = 0; i < ci->values_num; i++)
+ for (int i = 0; i < ci->values_num; i++)
{
array[array_len] = strdup (ci->values[i].value.string);
if (array[array_len] == NULL)
udb_query_t const *q, udb_query_preparation_area_t *q_area)
{
value_list_t vl = VALUE_LIST_INIT;
- size_t i;
- int status;
assert (r != NULL);
assert (r_area->ds != NULL);
}
vl.values_len = r_area->ds->ds_num;
- for (i = 0; i < r->values_num; i++)
+ for (size_t i = 0; i < r->values_num; i++)
{
char *value_str = r_area->values_buffer[i];
{
if (r->instance_prefix == NULL)
{
- strjoin (vl.type_instance, sizeof (vl.type_instance),
+ int status = strjoin (vl.type_instance, sizeof (vl.type_instance),
r_area->instances_buffer, r->instances_num, "-");
+ if (status < 0)
+ {
+ ERROR ("udb_result_submit: creating type_instance failed with status %d.",
+ status);
+ return (status);
+ }
}
else
{
char tmp[DATA_MAX_NAME_LEN];
- strjoin (tmp, sizeof (tmp), r_area->instances_buffer,
+ int status = strjoin (tmp, sizeof (tmp), r_area->instances_buffer,
r->instances_num, "-");
+ if (status < 0)
+ {
+ ERROR ("udb_result_submit: creating type_instance failed with status %d.",
+ status);
+ return (status);
+ }
tmp[sizeof (tmp) - 1] = 0;
snprintf (vl.type_instance, sizeof (vl.type_instance), "%s-%s",
return (-ENOMEM);
}
- for (i = 0; i < r->metadata_num; i++)
+ for (size_t i = 0; i < r->metadata_num; i++)
{
- status = meta_data_add_string (vl.meta, r->metadata[i],
+ int status = meta_data_add_string (vl.meta, r->metadata[i],
r_area->metadata_buffer[i]);
if (status != 0)
{
udb_result_preparation_area_t *r_area,
udb_query_t const *q, char **column_values)
{
- size_t i;
-
assert (r && q_area && r_area);
- for (i = 0; i < r->instances_num; i++)
+ for (size_t i = 0; i < r->instances_num; i++)
r_area->instances_buffer[i] = column_values[r_area->instances_pos[i]];
- for (i = 0; i < r->values_num; i++)
+ for (size_t i = 0; i < r->values_num; i++)
r_area->values_buffer[i] = column_values[r_area->values_pos[i]];
- for (i = 0; i < r->metadata_num; i++)
+ for (size_t i = 0; i < r->metadata_num; i++)
r_area->metadata_buffer[i] = column_values[r_area->metadata_pos[i]];
if (q->plugin_instance_from)
udb_result_preparation_area_t *prep_area,
char **column_names, size_t column_num)
{
- size_t i;
-
if ((r == NULL) || (prep_area == NULL))
return (-EINVAL);
/* }}} */
/* Determine the position of the plugin instance column {{{ */
- for (i = 0; i < r->instances_num; i++)
+ for (size_t i = 0; i < r->instances_num; i++)
{
size_t j;
/* Determine the position of the value columns {{{ */
- for (i = 0; i < r->values_num; i++)
+ for (size_t i = 0; i < r->values_num; i++)
{
size_t j;
} /* }}} for (i = 0; i < r->values_num; i++) */
/* Determine the position of the metadata columns {{{ */
- for (i = 0; i < r->metadata_num; i++)
+ for (size_t i = 0; i < r->metadata_num; i++)
{
size_t j;
static void udb_result_free (udb_result_t *r) /* {{{ */
{
- size_t i;
-
if (r == NULL)
return;
sfree (r->type);
sfree (r->instance_prefix);
- for (i = 0; i < r->instances_num; i++)
+ for (size_t i = 0; i < r->instances_num; i++)
sfree (r->instances[i]);
sfree (r->instances);
- for (i = 0; i < r->values_num; i++)
+ for (size_t i = 0; i < r->values_num; i++)
sfree (r->values[i]);
sfree (r->values);
- for (i = 0; i < r->metadata_num; i++)
+ for (size_t i = 0; i < r->metadata_num; i++)
sfree (r->metadata[i]);
sfree (r->metadata);
{
udb_result_t *r;
int status;
- int i;
if (ci->values_num != 0)
{
/* Fill the `udb_result_t' structure.. */
status = 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;
udb_query_t *q;
int status;
- int i;
if ((ret_query_list == NULL) || (ret_query_list_len == NULL))
return (-EINVAL);
}
/* Fill the `udb_query_t' structure.. */
- for (i = 0; i < ci->children_num; i++)
+ for (int i = 0; i < ci->children_num; i++)
{
oconfig_item_t *child = ci->children + i;
void udb_query_free (udb_query_t **query_list, size_t query_list_len) /* {{{ */
{
- size_t i;
-
if (query_list == NULL)
return;
- for (i = 0; i < query_list_len; i++)
+ for (size_t i = 0; i < query_list_len; i++)
udb_query_free_one (query_list[i]);
sfree (query_list);
udb_query_t **src_list, size_t src_list_len,
udb_query_t ***dst_list, size_t *dst_list_len)
{
- size_t i;
int num_added;
if ((name == NULL) || (src_list == NULL) || (dst_list == NULL)
}
num_added = 0;
- for (i = 0; i < src_list_len; i++)
+ for (size_t i = 0; i < src_list_len; i++)
{
udb_query_t **tmp_list;
size_t tmp_list_len;
#if defined(COLLECT_DEBUG) && COLLECT_DEBUG /* {{{ */
do
{
- size_t i;
-
- for (i = 0; i < prep_area->column_num; i++)
+ for (size_t i = 0; i < prep_area->column_num; i++)
{
DEBUG ("db query utils: udb_query_handle_result (%s, %s): "
"column[%zu] = %s;",
#if defined(COLLECT_DEBUG) && COLLECT_DEBUG
do
{
- size_t i;
-
- for (i = 0; i < column_num; i++)
+ for (size_t i = 0; i < column_num; i++)
{
DEBUG ("db query utils: udb_query_prepare_result: "
"query = %s; column[%zu] = %s;",
#ifndef UTILS_DB_QUERY_H
#define UTILS_DB_QUERY_H 1
-#include "configfile.h"
-
/*
* Data types
*/
#define _BSD_SOURCE
#include "collectd.h"
+
#include "plugin.h"
#include "common.h"
static inline int ignore_list_match (const struct in6_addr *addr)
{
- ip_list_t *ptr;
-
- for (ptr = IgnoreList; ptr != NULL; ptr = ptr->next)
+ for (ip_list_t *ptr = IgnoreList; ptr != NULL; ptr = ptr->next)
if (cmp_in6_addr (addr, &ptr->addr) == 0)
return (1);
return (0);
void ignore_list_add_name (const char *name)
{
struct addrinfo *ai_list;
- struct addrinfo *ai_ptr;
struct in6_addr addr;
int status;
if (status != 0)
return;
- for (ai_ptr = ai_list; ai_ptr != NULL; ai_ptr = ai_ptr->ai_next)
+ for (struct addrinfo *ai_ptr = ai_list; ai_ptr != NULL; ai_ptr = ai_ptr->ai_next)
{
if (ai_ptr->ai_family == AF_INET)
{
return (0);
if (IPPROTO_UDP != ip->ip_p)
return 0;
- memcpy(buf, (void *) ip + offset, len - offset);
+ memcpy(buf, ((char *)ip) + offset, len - offset);
if (0 == handle_udp((struct udphdr *) buf, len - offset))
return 0;
return 1;
case ns_t_srv: return ("SRV");
case ns_t_atma: return ("ATMA");
case ns_t_naptr: return ("NAPTR");
+ case ns_t_opt: return ("OPT");
+# if __NAMESER >= 19991006
case ns_t_kx: return ("KX");
case ns_t_cert: return ("CERT");
case ns_t_a6: return ("A6");
case ns_t_dname: return ("DNAME");
case ns_t_sink: return ("SINK");
- case ns_t_opt: return ("OPT");
-# if __NAMESER >= 19991006
case ns_t_tsig: return ("TSIG");
# endif
+# if __NAMESER >= 20090302
+ case ns_t_apl: return ("APL");
+ case ns_t_ds: return ("DS");
+ case ns_t_sshfp: return ("SSHFP");
+ case ns_t_ipseckey: return ("IPSECKEY");
+ case ns_t_rrsig: return ("RRSIG");
+ case ns_t_nsec: return ("NSEC");
+ case ns_t_dnskey: return ("DNSKEY");
+ case ns_t_dhcid: return ("DHCID");
+ case ns_t_nsec3: return ("NSEC3");
+ case ns_t_nsec3param: return ("NSEC3PARAM");
+ case ns_t_hip: return ("HIP");
+ case ns_t_spf: return ("SPF");
case ns_t_ixfr: return ("IXFR");
+# endif
case ns_t_axfr: return ("AXFR");
case ns_t_mailb: return ("MAILB");
case ns_t_maila: return ("MAILA");
case ns_t_any: return ("ANY");
+# if __NAMESER >= 19991006
case ns_t_zxfr: return ("ZXFR");
-/* #endif __NAMESER >= 19991006 */
+# endif
+# if __NAMESER >= 20090302
+ case ns_t_dlv: return ("DLV");
+# endif
+/* #endif __NAMESER >= 19991001 */
#elif (defined (__BIND)) && (__BIND >= 19950621)
case T_A: return ("A"); /* 1 ... */
case T_NS: return ("NS");
**/
#include "collectd.h"
+
#include "plugin.h"
#include "utils_fbhash.h"
{
FILE *fh;
char buffer[4096];
- struct flock fl;
+ struct flock fl = { 0 };
c_avl_tree_t *tree;
int status;
if (fh == NULL)
return (-1);
- memset (&fl, 0, sizeof (fl));
fl.l_type = F_RDLCK;
fl.l_whence = SEEK_SET;
- fl.l_start = 0;
- fl.l_len = 0; /* == entire file */
/* TODO: Lock file? -> fcntl */
status = fcntl (fileno (fh), F_SETLK, &fl);
static int fbh_check_file (fbhash_t *h) /* {{{ */
{
- struct stat statbuf;
+ struct stat statbuf = { 0 };
int status;
- memset (&statbuf, 0, sizeof (statbuf));
-
status = stat (h->filename, &statbuf);
if (status != 0)
return (-1);
**/
#include "collectd.h"
+
#include "plugin.h"
#include "common.h"
static void gr_copy_escape_part (char *dst, const char *src, size_t dst_len,
char escape_char)
{
- size_t i;
-
memset (dst, 0, dst_len);
if (src == NULL)
return;
- for (i = 0; i < dst_len; i++)
+ for (size_t i = 0; i < dst_len; i++)
{
if (src[i] == 0)
{
sstrncpy (tmp_plugin, n_plugin, sizeof (tmp_plugin));
if (n_type_instance[0] != '\0')
- ssnprintf (tmp_type, sizeof (tmp_type), "%s%c%s",
- n_type,
- (flags & GRAPHITE_SEPARATE_INSTANCES) ? '.' : '-',
- n_type_instance);
+ {
+ if ((flags & GRAPHITE_DROP_DUPE_FIELDS) && strcmp(n_plugin, n_type) == 0)
+ sstrncpy (tmp_type, n_type_instance, sizeof (tmp_type));
+ else
+ ssnprintf (tmp_type, sizeof (tmp_type), "%s%c%s",
+ n_type,
+ (flags & GRAPHITE_SEPARATE_INSTANCES) ? '.' : '-',
+ n_type_instance);
+ }
else
sstrncpy (tmp_type, n_type, sizeof (tmp_type));
/* Assert always_append_ds -> ds_name */
assert (!(flags & GRAPHITE_ALWAYS_APPEND_DS) || (ds_name != NULL));
if (ds_name != NULL)
- ssnprintf (ret, ret_len, "%s%s%s.%s.%s.%s",
- prefix, n_host, postfix, tmp_plugin, tmp_type, ds_name);
+ {
+ if ((flags & GRAPHITE_DROP_DUPE_FIELDS) && strcmp(tmp_plugin, tmp_type) == 0)
+ ssnprintf (ret, ret_len, "%s%s%s.%s.%s",
+ prefix, n_host, postfix, tmp_plugin, ds_name);
+ else
+ ssnprintf (ret, ret_len, "%s%s%s.%s.%s.%s",
+ prefix, n_host, postfix, tmp_plugin, tmp_type, ds_name);
+ }
else
ssnprintf (ret, ret_len, "%s%s%s.%s.%s",
prefix, n_host, postfix, tmp_plugin, tmp_type);
static void escape_graphite_string (char *buffer, char escape_char)
{
- char *head;
-
assert (strchr(GRAPHITE_FORBIDDEN, escape_char) == NULL);
- for (head = buffer + strcspn(buffer, GRAPHITE_FORBIDDEN);
+ for (char *head = buffer + strcspn(buffer, GRAPHITE_FORBIDDEN);
*head != '\0';
head += strcspn(head, GRAPHITE_FORBIDDEN))
*head = escape_char;
unsigned int flags)
{
int status = 0;
- size_t i;
int buffer_pos = 0;
gauge_t *rates = NULL;
if (flags & GRAPHITE_STORE_RATES)
rates = uc_get_rate (ds, vl);
- for (i = 0; i < ds->ds_num; i++)
+ for (size_t i = 0; i < ds->ds_num; i++)
{
char const *ds_name = NULL;
char key[10*DATA_MAX_NAME_LEN];
#define UTILS_FORMAT_GRAPHITE_H 1
#include "collectd.h"
+
#include "plugin.h"
#define GRAPHITE_STORE_RATES 0x01
#define GRAPHITE_SEPARATE_INSTANCES 0x02
#define GRAPHITE_ALWAYS_APPEND_DS 0x04
+#define GRAPHITE_DROP_DUPE_FIELDS 0x08
int format_graphite (char *buffer,
size_t buffer_size, const data_set_t *ds,
/**
* collectd - src/utils_format_json.c
- * Copyright (C) 2009 Florian octo Forster
+ * Copyright (C) 2009-2015 Florian octo Forster
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
**/
#include "collectd.h"
+
+#include "utils_format_json.h"
+
#include "plugin.h"
#include "common.h"
-
#include "utils_cache.h"
-#include "utils_format_json.h"
+
+#if HAVE_LIBYAJL
+# include <yajl/yajl_common.h>
+# include <yajl/yajl_gen.h>
+# if HAVE_YAJL_YAJL_VERSION_H
+# include <yajl/yajl_version.h>
+# endif
+# if defined(YAJL_MAJOR) && (YAJL_MAJOR > 1)
+# define HAVE_YAJL_V2 1
+# endif
+#endif
static int json_escape_string (char *buffer, size_t buffer_size, /* {{{ */
const char *string)
{
- size_t src_pos;
size_t dst_pos;
if ((buffer == NULL) || (string == NULL))
/* Escape special characters */
BUFFER_ADD ('"');
- for (src_pos = 0; string[src_pos] != 0; src_pos++)
+ for (size_t src_pos = 0; string[src_pos] != 0; src_pos++)
{
if ((string[src_pos] == '"')
|| (string[src_pos] == '\\'))
const data_set_t *ds, const value_list_t *vl, int store_rates)
{
size_t offset = 0;
- size_t i;
gauge_t *rates = NULL;
memset (buffer, 0, buffer_size);
} while (0)
BUFFER_ADD ("[");
- for (i = 0; i < ds->ds_num; i++)
+ for (size_t i = 0; i < ds->ds_num; i++)
{
if (i > 0)
BUFFER_ADD (",");
const data_set_t *ds)
{
size_t offset = 0;
- size_t i;
memset (buffer, 0, buffer_size);
} while (0)
BUFFER_ADD ("[");
- for (i = 0; i < ds->ds_num; i++)
+ for (size_t i = 0; i < ds->ds_num; i++)
{
if (i > 0)
BUFFER_ADD (",");
const data_set_t *ds)
{
size_t offset = 0;
- size_t i;
memset (buffer, 0, buffer_size);
} while (0)
BUFFER_ADD ("[");
- for (i = 0; i < ds->ds_num; i++)
+ for (size_t i = 0; i < ds->ds_num; i++)
{
if (i > 0)
BUFFER_ADD (",");
{
size_t offset = 0;
int status;
- size_t i;
buffer[0] = 0;
offset += ((size_t) status); \
} while (0)
- for (i = 0; i < keys_num; ++i)
+ for (size_t i = 0; i < keys_num; ++i)
{
int type;
char *key = keys[i];
char **keys = NULL;
size_t keys_num;
int status;
- size_t i;
if ((buffer == NULL) || (buffer_size == 0) || (meta == NULL))
return (EINVAL);
status = meta_data_keys_to_json (buffer, buffer_size, meta, keys, keys_num);
- for (i = 0; i < keys_num; ++i)
+ for (size_t i = 0; i < keys_num; ++i)
sfree (keys[i]);
sfree (keys);
store_rates, (*ret_buffer_free) - 2));
} /* }}} int format_json_value_list */
+#if HAVE_LIBYAJL
+static int json_add_string (yajl_gen g, char const *str) /* {{{ */
+{
+ if (str == NULL)
+ return (int) yajl_gen_null (g);
+
+ return (int) yajl_gen_string (g, (unsigned char const *) str, (unsigned int) strlen (str));
+} /* }}} int json_add_string */
+
+#define JSON_ADD(g, str) do { \
+ yajl_gen_status status = json_add_string (g, str); \
+ if (status != yajl_gen_status_ok) { return -1; } \
+} while (0)
+
+#define JSON_ADDF(g, format, ...) do { \
+ char *str = ssnprintf_alloc (format, __VA_ARGS__); \
+ yajl_gen_status status = json_add_string (g, str); \
+ free (str); \
+ if (status != yajl_gen_status_ok) { return -1; } \
+} while (0)
+
+static int format_json_meta (yajl_gen g, notification_meta_t *meta) /* {{{ */
+{
+ if (meta == NULL)
+ return 0;
+
+ JSON_ADD (g, meta->name);
+ switch (meta->type)
+ {
+ case NM_TYPE_STRING:
+ JSON_ADD (g, meta->nm_value.nm_string);
+ break;
+ case NM_TYPE_SIGNED_INT:
+ JSON_ADDF (g, "%"PRIi64, meta->nm_value.nm_signed_int);
+ break;
+ case NM_TYPE_UNSIGNED_INT:
+ JSON_ADDF (g, "%"PRIu64, meta->nm_value.nm_unsigned_int);
+ break;
+ case NM_TYPE_DOUBLE:
+ JSON_ADDF (g, JSON_GAUGE_FORMAT, meta->nm_value.nm_double);
+ break;
+ case NM_TYPE_BOOLEAN:
+ JSON_ADD (g, meta->nm_value.nm_boolean ? "true" : "false");
+ break;
+ default:
+ ERROR ("format_json_meta: unknown meta data type %d (name \"%s\")", meta->type, meta->name);
+ yajl_gen_null (g);
+ }
+
+ return format_json_meta (g, meta->next);
+} /* }}} int format_json_meta */
+
+static int format_time (yajl_gen g, cdtime_t t) /* {{{ */
+{
+ char buffer[RFC3339NANO_SIZE] = "";
+
+ if (rfc3339nano (buffer, sizeof (buffer), t) != 0)
+ return -1;
+
+ JSON_ADD (g, buffer);
+ return 0;
+} /* }}} int format_time */
+
+static int format_alert (yajl_gen g, notification_t const *n) /* {{{ */
+{
+ yajl_gen_array_open (g);
+ yajl_gen_map_open (g); /* BEGIN alert */
+
+ /*
+ * labels
+ */
+ JSON_ADD (g, "labels");
+ yajl_gen_map_open (g); /* BEGIN labels */
+
+ JSON_ADD (g, "alertname");
+ if (strncmp (n->plugin, n->type, strlen (n->plugin)) == 0)
+ JSON_ADDF (g, "collectd_%s", n->type);
+ else
+ JSON_ADDF (g, "collectd_%s_%s", n->plugin, n->type);
+
+ JSON_ADD (g, "instance");
+ JSON_ADD (g, n->host);
+
+ /* mangling of plugin instance and type instance into labels is copied from
+ * the Prometheus collectd exporter. */
+ if (strlen (n->plugin_instance) > 0)
+ {
+ JSON_ADD (g, n->plugin);
+ JSON_ADD (g, n->plugin_instance);
+ }
+ if (strlen (n->type_instance) > 0)
+ {
+ if (strlen (n->plugin_instance) > 0)
+ JSON_ADD (g, "type");
+ else
+ JSON_ADD (g, n->plugin);
+ JSON_ADD (g, n->type_instance);
+ }
+
+ JSON_ADD (g, "severity");
+ JSON_ADD (g, (n->severity == NOTIF_FAILURE) ? "FAILURE"
+ : (n->severity == NOTIF_WARNING) ? "WARNING"
+ : (n->severity == NOTIF_OKAY) ? "OKAY"
+ : "UNKNOWN");
+
+ JSON_ADD (g, "service");
+ JSON_ADD (g, "collectd");
+
+ yajl_gen_map_close (g); /* END labels */
+
+ /*
+ * annotations
+ */
+ JSON_ADD (g, "annotations");
+ yajl_gen_map_open (g); /* BEGIN annotations */
+
+ JSON_ADD (g, "summary");
+ JSON_ADD (g, n->message);
+
+ if (format_json_meta (g, n->meta) != 0)
+ return -1;
+
+ yajl_gen_map_close (g); /* END annotations */
+
+ JSON_ADD (g, "startsAt");
+ format_time (g, n->time);
+
+ yajl_gen_map_close (g); /* END alert */
+ yajl_gen_array_close (g);
+
+ return 0;
+} /* }}} format_alert */
+
+/*
+ * Format (prometheus/alertmanager v1):
+ *
+ * [{
+ * "labels": {
+ * "alertname": "collectd_cpu",
+ * "instance": "host.example.com",
+ * "severity": "FAILURE",
+ * "service": "collectd",
+ * "cpu": "0",
+ * "type": "wait"
+ * },
+ * "annotations": {
+ * "summary": "...",
+ * // meta
+ * },
+ * "startsAt": <rfc3339 time>,
+ * "endsAt": <rfc3339 time>, // not used
+ * }]
+ */
+int format_json_notification (char *buffer, size_t buffer_size, /* {{{ */
+ notification_t const *n)
+{
+ yajl_gen g;
+ unsigned char const *out;
+#if HAVE_YAJL_V2
+ size_t unused_out_len;
+#else
+ unsigned int unused_out_len;
+#endif
+
+ if ((buffer == NULL) || (n == NULL))
+ return EINVAL;
+
+#if HAVE_YAJL_V2
+ g = yajl_gen_alloc (NULL);
+ if (g == NULL)
+ return -1;
+# if COLLECT_DEBUG
+ yajl_gen_config (g, yajl_gen_beautify, 1);
+ yajl_gen_config (g, yajl_gen_validate_utf8, 1);
+# endif
+
+#else /* !HAVE_YAJL_V2 */
+ yajl_gen_config conf = { 0 };
+# if COLLECT_DEBUG
+ conf.beautify = 1;
+ conf.indentString = " ";
+# endif
+ g = yajl_gen_alloc (&conf, NULL);
+ if (g == NULL)
+ return -1;
+#endif
+
+ if (format_alert (g, n) != 0)
+ {
+ yajl_gen_clear (g);
+ yajl_gen_free (g);
+ return -1;
+ }
+
+ /* copy to output buffer */
+ yajl_gen_get_buf (g, &out, &unused_out_len);
+ sstrncpy (buffer, (void *) out, buffer_size);
+
+ yajl_gen_clear (g);
+ yajl_gen_free (g);
+ return 0;
+} /* }}} format_json_notification */
+#else
+int format_json_notification (char *buffer, size_t buffer_size, /* {{{ */
+ notification_t const *n)
+{
+ ERROR ("format_json_notification: Not available (requires libyajl).");
+ return ENOTSUP;
+} /* }}} int format_json_notification */
+#endif
+
/* vim: set sw=2 sts=2 et fdm=marker : */
#define UTILS_FORMAT_JSON_H 1
#include "collectd.h"
+
#include "plugin.h"
#ifndef JSON_GAUGE_FORMAT
const data_set_t *ds, const value_list_t *vl, int store_rates);
int format_json_finalize (char *buffer,
size_t *ret_buffer_fill, size_t *ret_buffer_free);
+int format_json_notification (char *buffer, size_t buffer_size,
+ notification_t const *n);
#endif /* UTILS_FORMAT_JSON_H */
--- /dev/null
+/**
+ * collectd - src/utils_format_json_test.c
+ * Copyright (C) 2015 Florian octo Forster
+ *
+ * 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:
+ * Florian octo Forster <octo at collectd.org>
+ */
+
+/* Workaround for Solaris 10 defining label_t
+ * Issue #1301
+ */
+
+#include "config.h"
+#if KERNEL_SOLARIS
+# ifndef _POSIX_C_SOURCE
+# define _POSIX_C_SOURCE 200112L
+# endif
+# undef __EXTENSIONS__
+#endif
+
+#include "collectd.h"
+
+#include "testing.h"
+#include "utils_format_json.h"
+#include "common.h" /* for STATIC_ARRAY_SIZE */
+
+#include <yajl/yajl_common.h>
+#include <yajl/yajl_parse.h>
+#if HAVE_YAJL_YAJL_VERSION_H
+# include <yajl/yajl_version.h>
+#endif
+#if YAJL_MAJOR > 1
+# define HAVE_YAJL_V2 1
+#endif
+
+typedef struct
+{
+ char const *key;
+ char const *value;
+} label_t;
+
+typedef struct
+{
+ label_t *expected_labels;
+ size_t expected_labels_num;
+
+ label_t *current_label;
+} test_case_t;
+
+#if HAVE_YAJL_V2
+static int test_map_key (void *ctx, unsigned char const *key, size_t key_len)
+#else
+static int test_map_key (void *ctx, unsigned char const *key, unsigned int key_len)
+#endif
+{
+ test_case_t *c = ctx;
+ size_t i;
+
+ c->current_label = NULL;
+ for (i = 0; i < c->expected_labels_num; i++)
+ {
+ label_t *l = c->expected_labels + i;
+ if ((strlen (l->key) == key_len)
+ && (strncmp (l->key, (char const *) key, key_len) == 0))
+ {
+ c->current_label = l;
+ break;
+ }
+ }
+
+ return 1; /* continue */
+}
+
+static int expect_label (char const *name, char const *got, char const *want)
+{
+ _Bool ok = (strcmp (got, want) == 0);
+ char msg[1024];
+
+ if (ok)
+ snprintf (msg, sizeof (msg), "label[\"%s\"] = \"%s\"", name, got);
+ else
+ snprintf (msg, sizeof (msg), "label[\"%s\"] = \"%s\", want \"%s\"", name, got, want);
+
+ OK1 (ok, msg);
+ return 0;
+}
+
+#if HAVE_YAJL_V2
+static int test_string (void *ctx, unsigned char const *value, size_t value_len)
+#else
+static int test_string (void *ctx, unsigned char const *value, unsigned int value_len)
+#endif
+{
+ test_case_t *c = ctx;
+
+ if (c->current_label != NULL)
+ {
+ label_t *l = c->current_label;
+ char *got;
+ int status;
+
+ got = malloc (value_len + 1);
+ memmove (got, value, value_len);
+ got[value_len] = 0;
+
+ status = expect_label (l->key, got, l->value);
+
+ free (got);
+
+ if (status != 0)
+ return 0; /* abort */
+ }
+
+ return 1; /* continue */
+}
+
+static int expect_json_labels (char *json, label_t *labels, size_t labels_num)
+{
+ yajl_callbacks funcs = {
+ .yajl_string = test_string,
+ .yajl_map_key = test_map_key,
+ };
+
+ test_case_t c = { labels, labels_num, NULL };
+
+ yajl_handle hndl;
+#if HAVE_YAJL_V2
+ CHECK_NOT_NULL (hndl = yajl_alloc (&funcs, /* alloc = */ NULL, &c));
+#else
+ CHECK_NOT_NULL (hndl = yajl_alloc (&funcs, /* config = */ NULL, /* alloc = */ NULL, &c));
+#endif
+ OK (yajl_parse (hndl, (unsigned char *) json, strlen (json)) == yajl_status_ok);
+
+ yajl_free (hndl);
+ return 0;
+}
+
+DEF_TEST(notification)
+{
+ label_t labels[] = {
+ {"summary", "this is a message"},
+ {"alertname", "collectd_unit_test"},
+ {"instance", "example.com"},
+ {"service", "collectd"},
+ {"unit", "case"},
+ };
+
+ /* 1448284606.125 ^= 1555083754651779072 */
+ notification_t n = { NOTIF_WARNING, 1555083754651779072ULL, "this is a message",
+ "example.com", "unit", "", "test", "case", NULL };
+
+ char got[1024];
+ CHECK_ZERO (format_json_notification (got, sizeof (got), &n));
+ // printf ("got = \"%s\";\n", got);
+
+ return expect_json_labels (got, labels, STATIC_ARRAY_SIZE (labels));
+}
+
+int main (void)
+{
+ RUN_TEST(notification);
+
+ END_TEST;
+}
#include "collectd.h"
+
#include "plugin.h"
#include "common.h"
static int kairosdb_escape_string (char *buffer, size_t buffer_size, /* {{{ */
const char *string)
{
- size_t src_pos;
size_t dst_pos;
if ((buffer == NULL) || (string == NULL))
/* Escape special characters */
/* authorize -_. and alpha num but also escapes " */
BUFFER_ADD ('"');
- for (src_pos = 0; string[src_pos] != 0; src_pos++)
+ for (size_t src_pos = 0; string[src_pos] != 0; src_pos++)
{
if (isalnum(string[src_pos]) ||
0x2d == string[src_pos] ||
char temp[512];
size_t offset = 0;
int status;
- size_t i;
memset (buffer, 0, buffer_size);
BUFFER_ADD (",\"%s\": %s", (key), temp); \
} while (0)
- for (i = 0; i < ds->ds_num; i++)
+ for (size_t i = 0; i < ds->ds_num; i++)
{
/* All value lists have a leading comma. The first one will be replaced with
* a square bracket in `format_kairosdb_finalize'. */
#define UTILS_FORMAT_KAIROSDB_H 1
#include "collectd.h"
+
#include "plugin.h"
#ifndef JSON_GAUGE_FORMAT
**/
#include "collectd.h"
+
#include "plugin.h"
#include "utils_latency.h"
#include "common.h"
if (lc->num > 0) // if the histogram has data then iterate else skip
{
double width_change_ratio = ((double) old_bin_width) / ((double) new_bin_width);
- size_t i;
- for (i = 0; i < HISTOGRAM_NUM_BINS; i++)
+ for (size_t i = 0; i < HISTOGRAM_NUM_BINS; i++)
{
size_t new_bin = (size_t) (((double) i) * width_change_ratio);
if (i == new_bin)
if (lc == NULL)
return (NULL);
- latency_counter_reset (lc);
lc->bin_width = HISTOGRAM_DEFAULT_BIN_WIDTH;
+ latency_counter_reset (lc);
return (lc);
} /* }}} latency_counter_t *latency_counter_create */
return;
cdtime_t bin_width = lc->bin_width;
+ cdtime_t max_bin = (lc->max - 1) / lc->bin_width;
+
+/*
+ If max latency is REDUCE_THRESHOLD times less than histogram's range,
+ then cut it in half. REDUCE_THRESHOLD must be >= 2.
+ Value of 4 is selected to reduce frequent changes of bin width.
+*/
+#define REDUCE_THRESHOLD 4
+ if ((lc->num > 0) && (lc->bin_width >= HISTOGRAM_DEFAULT_BIN_WIDTH * 2)
+ && (max_bin < HISTOGRAM_NUM_BINS / REDUCE_THRESHOLD))
+ {
+ /* new bin width will be the previous power of 2 */
+ bin_width = bin_width / 2;
+
+ DEBUG("utils_latency: latency_counter_reset: max_latency = %.3f; "
+ "max_bin = %"PRIu64"; old_bin_width = %.3f; new_bin_width = %.3f;",
+ CDTIME_T_TO_DOUBLE (lc->max),
+ max_bin,
+ CDTIME_T_TO_DOUBLE (lc->bin_width),
+ CDTIME_T_TO_DOUBLE (bin_width));
+ }
+
memset (lc, 0, sizeof (*lc));
/* preserve bin width */
**/
#include "collectd.h"
+
#include "utils_time.h"
struct latency_counter_s;
#include "common.h" /* for STATIC_ARRAY_SIZE */
#include "collectd.h"
+
#include "testing.h"
#include "utils_time.h"
#include "utils_latency.h"
{ 99, 0.3, 99, 103, 20.6},
/* { -1, 0.3, 99, 103, 20.6}, see issue #1139 */
};
- size_t i;
latency_counter_t *l;
CHECK_NOT_NULL (l = latency_counter_create ());
- for (i = 0; i < STATIC_ARRAY_SIZE (cases); i++) {
+ for (size_t i = 0; i < STATIC_ARRAY_SIZE (cases); i++) {
printf ("# case %zu: DOUBLE_TO_CDTIME_T(%g) = %"PRIu64"\n",
i, cases[i].val, DOUBLE_TO_CDTIME_T (cases[i].val));
latency_counter_add (l, DOUBLE_TO_CDTIME_T (cases[i].val));
DEF_TEST(percentile)
{
- size_t i;
latency_counter_t *l;
CHECK_NOT_NULL (l = latency_counter_create ());
- for (i = 0; i < 100; i++) {
+ for (size_t i = 0; i < 100; i++) {
latency_counter_add (l, TIME_T_TO_CDTIME_T (((time_t) i) + 1));
}
--- /dev/null
+/**
+ * collectd - src/utils_lua.c
+ * Copyright (C) 2010 Florian Forster
+ *
+ * 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:
+ * Florian Forster <octo at collectd.org>
+ **/
+
+/* <lua5.1/luaconf.h> defines a macro using "sprintf". Although not used here,
+ * GCC will complain about the macro definition. */
+#define DONT_POISON_SPRINTF_YET
+
+#include "utils_lua.h"
+#include "common.h"
+
+static int ltoc_values(lua_State *L, /* {{{ */
+ const data_set_t *ds, value_t *ret_values) {
+ if (!lua_istable(L, -1)) {
+ WARNING("ltoc_values: not a table");
+ return (-1);
+ }
+
+ /* Push initial key */
+ lua_pushnil(L); /* +1 = 1 */
+ size_t i = 0;
+ while (lua_next(L, -2) != 0) /* -1+2 = 2 || -1 = 0 */
+ {
+ if (i >= ds->ds_num) {
+ lua_pop(L, 2); /* -2 = 0 */
+ i++;
+ break;
+ }
+
+ ret_values[i] = luaC_tovalue(L, -1, ds->ds[i].type);
+
+ /* Pop the value */
+ lua_pop(L, 1); /* -1 = 1 */
+ i++;
+ } /* while (lua_next) */
+
+ if (i != ds->ds_num) {
+ WARNING("ltoc_values: invalid size for datasource \"%s\": expected %zu, "
+ "got %zu",
+ ds->type, ds->ds_num, i);
+ return (-1);
+ }
+
+ return (0);
+} /* }}} int ltoc_values */
+
+static int ltoc_table_values(lua_State *L, int idx, /* {{{ */
+ const data_set_t *ds, value_list_t *vl) {
+ /* We're only called from "luaC_tovaluelist", which ensures that "idx" is an
+ * absolute index (i.e. a positive number) */
+ assert(idx > 0);
+
+ lua_getfield(L, idx, "values");
+ if (!lua_istable(L, -1)) {
+ WARNING("utils_lua: ltoc_table_values: The \"values\" member is a %s "
+ "value, not a table.",
+ lua_typename(L, lua_type(L, -1)));
+ lua_pop(L, 1);
+ return (-1);
+ }
+
+ vl->values_len = ds->ds_num;
+ vl->values = calloc(vl->values_len, sizeof(*vl->values));
+ if (vl->values == NULL) {
+ ERROR("utils_lua: calloc failed.");
+ vl->values_len = 0;
+ lua_pop(L, 1);
+ return (-1);
+ }
+
+ int status = ltoc_values(L, ds, vl->values);
+
+ lua_pop(L, 1);
+
+ if (status != 0) {
+ vl->values_len = 0;
+ sfree(vl->values);
+ }
+
+ return (status);
+} /* }}} int ltoc_table_values */
+
+static int luaC_pushvalues(lua_State *L, const data_set_t *ds,
+ const value_list_t *vl) /* {{{ */
+{
+ assert(vl->values_len == ds->ds_num);
+
+ lua_newtable(L);
+ for (size_t i = 0; i < vl->values_len; i++) {
+ lua_pushinteger(L, (lua_Integer)i + 1);
+ luaC_pushvalue(L, vl->values[i], ds->ds[i].type);
+ lua_settable(L, -3);
+ }
+
+ return (0);
+} /* }}} int luaC_pushvalues */
+
+static int luaC_pushdstypes(lua_State *L, const data_set_t *ds) /* {{{ */
+{
+ lua_newtable(L);
+ for (size_t i = 0; i < ds->ds_num; i++) {
+ lua_pushinteger(L, (lua_Integer)i);
+ lua_pushstring(L, DS_TYPE_TO_STRING(ds->ds[i].type));
+ lua_settable(L, -3);
+ }
+
+ return (0);
+} /* }}} int luaC_pushdstypes */
+
+static int luaC_pushdsnames(lua_State *L, const data_set_t *ds) /* {{{ */
+{
+ lua_newtable(L);
+ for (size_t i = 0; i < ds->ds_num; i++) {
+ lua_pushinteger(L, (lua_Integer)i);
+ lua_pushstring(L, ds->ds[i].name);
+ lua_settable(L, -3);
+ }
+
+ return (0);
+} /* }}} int luaC_pushdsnames */
+
+/*
+ * Public functions
+ */
+cdtime_t luaC_tocdtime(lua_State *L, int idx) /* {{{ */
+{
+ if (!lua_isnumber(L, /* stack pos = */ idx))
+ return (0);
+
+ double d = lua_tonumber(L, idx);
+
+ return (DOUBLE_TO_CDTIME_T(d));
+} /* }}} int ltoc_table_cdtime */
+
+int luaC_tostringbuffer(lua_State *L, int idx, /* {{{ */
+ char *buffer, size_t buffer_size) {
+ const char *str = lua_tostring(L, idx);
+ if (str == NULL)
+ return (-1);
+
+ sstrncpy(buffer, str, buffer_size);
+ return (0);
+} /* }}} int luaC_tostringbuffer */
+
+value_t luaC_tovalue(lua_State *L, int idx, int ds_type) /* {{{ */
+{
+ value_t v = { 0 };
+
+ if (!lua_isnumber(L, idx))
+ return (v);
+
+ if (ds_type == DS_TYPE_GAUGE)
+ v.gauge = (gauge_t)lua_tonumber(L, /* stack pos = */ -1);
+ else if (ds_type == DS_TYPE_DERIVE)
+ v.derive = (derive_t)lua_tointeger(L, /* stack pos = */ -1);
+ else if (ds_type == DS_TYPE_COUNTER)
+ v.counter = (counter_t)lua_tointeger(L, /* stack pos = */ -1);
+ else if (ds_type == DS_TYPE_ABSOLUTE)
+ v.absolute = (absolute_t)lua_tointeger(L, /* stack pos = */ -1);
+
+ return (v);
+} /* }}} value_t luaC_tovalue */
+
+value_list_t *luaC_tovaluelist(lua_State *L, int idx) /* {{{ */
+{
+#if COLLECT_DEBUG
+ int stack_top_before = lua_gettop(L);
+#endif
+
+ /* Convert relative indexes to absolute indexes, so it doesn't change when we
+ * push / pop stuff. */
+ if (idx < 1)
+ idx += lua_gettop(L) + 1;
+
+ /* Check that idx is in the valid range */
+ if ((idx < 1) || (idx > lua_gettop(L))) {
+ DEBUG("luaC_tovaluelist: idx(%d), top(%d)", idx, stack_top_before);
+ return (NULL);
+ }
+
+ value_list_t *vl = calloc(1, sizeof(*vl));
+ if (vl == NULL) {
+ DEBUG("luaC_tovaluelist: calloc failed");
+ return (NULL);
+ }
+
+ /* Push initial key */
+ lua_pushnil(L);
+ while (lua_next(L, idx) != 0) {
+ const char *key = lua_tostring(L, -2);
+
+ if (key == NULL) {
+ DEBUG("luaC_tovaluelist: Ignoring non-string key.");
+ } else if (strcasecmp("host", key) == 0)
+ luaC_tostringbuffer(L, -1, vl->host, sizeof(vl->host));
+ else if (strcasecmp("plugin", key) == 0)
+ luaC_tostringbuffer(L, -1, vl->plugin, sizeof(vl->plugin));
+ else if (strcasecmp("plugin_instance", key) == 0)
+ luaC_tostringbuffer(L, -1, vl->plugin_instance,
+ sizeof(vl->plugin_instance));
+ else if (strcasecmp("type", key) == 0)
+ luaC_tostringbuffer(L, -1, vl->type, sizeof(vl->type));
+ else if (strcasecmp("type_instance", key) == 0)
+ luaC_tostringbuffer(L, -1, vl->type_instance,
+ sizeof(vl->type_instance));
+ else if (strcasecmp("time", key) == 0)
+ vl->time = luaC_tocdtime(L, -1);
+ else if (strcasecmp("interval", key) == 0)
+ vl->interval = luaC_tocdtime(L, -1);
+ else if (strcasecmp("values", key) == 0) {
+ /* This key is not handled here, because we have to assure "type" is read
+ * first. */
+ } else {
+ DEBUG("luaC_tovaluelist: Ignoring unknown key \"%s\".", key);
+ }
+
+ /* Pop the value */
+ lua_pop(L, 1);
+ }
+
+ const data_set_t *ds = plugin_get_ds(vl->type);
+ if (ds == NULL) {
+ INFO("utils_lua: Unable to lookup type \"%s\".", vl->type);
+ sfree(vl);
+ return (NULL);
+ }
+
+ int status = ltoc_table_values(L, idx, ds, vl);
+ if (status != 0) {
+ WARNING("utils_lua: ltoc_table_values failed.");
+ sfree(vl);
+ return (NULL);
+ }
+
+#if COLLECT_DEBUG
+ assert(stack_top_before == lua_gettop(L));
+#endif
+ return (vl);
+} /* }}} value_list_t *luaC_tovaluelist */
+
+int luaC_pushcdtime(lua_State *L, cdtime_t t) /* {{{ */
+{
+ double d = CDTIME_T_TO_DOUBLE(t);
+
+ lua_pushnumber(L, (lua_Number)d);
+ return (0);
+} /* }}} int luaC_pushcdtime */
+
+int luaC_pushvalue(lua_State *L, value_t v, int ds_type) /* {{{ */
+{
+ if (ds_type == DS_TYPE_GAUGE)
+ lua_pushnumber(L, (lua_Number)v.gauge);
+ else if (ds_type == DS_TYPE_DERIVE)
+ lua_pushinteger(L, (lua_Integer)v.derive);
+ else if (ds_type == DS_TYPE_COUNTER)
+ lua_pushinteger(L, (lua_Integer)v.counter);
+ else if (ds_type == DS_TYPE_ABSOLUTE)
+ lua_pushinteger(L, (lua_Integer)v.absolute);
+ else
+ return (-1);
+ return (0);
+} /* }}} int luaC_pushvalue */
+
+int luaC_pushvaluelist(lua_State *L, const data_set_t *ds,
+ const value_list_t *vl) /* {{{ */
+{
+ lua_newtable(L);
+
+ lua_pushstring(L, vl->host);
+ lua_setfield(L, -2, "host");
+
+ lua_pushstring(L, vl->plugin);
+ lua_setfield(L, -2, "plugin");
+ lua_pushstring(L, vl->plugin_instance);
+ lua_setfield(L, -2, "plugin_instance");
+
+ lua_pushstring(L, vl->type);
+ lua_setfield(L, -2, "type");
+ lua_pushstring(L, vl->type_instance);
+ lua_setfield(L, -2, "type_instance");
+
+ luaC_pushvalues(L, ds, vl);
+ lua_setfield(L, -2, "values");
+
+ luaC_pushdstypes(L, ds);
+ lua_setfield(L, -2, "dstypes");
+
+ luaC_pushdsnames(L, ds);
+ lua_setfield(L, -2, "dsnames");
+
+ luaC_pushcdtime(L, vl->time);
+ lua_setfield(L, -2, "time");
+
+ luaC_pushcdtime(L, vl->interval);
+ lua_setfield(L, -2, "interval");
+
+ return (0);
+} /* }}} int luaC_pushvaluelist */
+
+/* vim: set sw=2 sts=2 et fdm=marker : */
--- /dev/null
+/**
+ * collectd - src/utils_lua.h
+ * Copyright (C) 2010 Florian Forster
+ *
+ * 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:
+ * Florian Forster <octo at collectd.org>
+ **/
+
+#ifndef UTILS_LUA_H
+#define UTILS_LUA_H 1
+
+#include "collectd.h"
+#include "plugin.h"
+
+#ifndef DONT_POISON_SPRINTF_YET
+#error "Files including utils_lua.h need to define DONT_POISON_SPRINTF_YET."
+#endif
+#include <lua.h>
+
+/*
+ * access functions (stack -> C)
+ */
+cdtime_t luaC_tocdtime(lua_State *L, int idx);
+int luaC_tostringbuffer(lua_State *L, int idx, char *buffer,
+ size_t buffer_size);
+value_t luaC_tovalue(lua_State *L, int idx, int ds_type);
+value_list_t *luaC_tovaluelist(lua_State *L, int idx);
+
+/*
+ * push functions (C -> stack)
+ */
+int luaC_pushcdtime(lua_State *L, cdtime_t t);
+int luaC_pushvalue(lua_State *L, value_t v, int ds_type);
+int luaC_pushvaluelist(lua_State *L, const data_set_t *ds,
+ const value_list_t *vl);
+
+#endif /* UTILS_LUA_H */
+/* vim: set sw=2 sts=2 et fdm=marker : */
# include "config.h"
#endif
+#define _GNU_SOURCE
+
+#include "collectd.h"
+
+#include "utils_mount.h"
+
#if HAVE_XFS_XQM_H
-# define _GNU_SOURCE
# include <xfs/xqm.h>
#define XFS_SUPER_MAGIC_STR "XFSB"
#define XFS_SUPER_MAGIC2_STR "BSFX"
#endif
-#include "collectd.h"
-#include "utils_mount.h"
-
#include "common.h" /* sstrncpy() et alii */
#include "plugin.h" /* ERROR() macro */
FILE *procpt;
char uuid[16], *label = NULL;
char device[110];
- int firstPass;
int handleOnFirst;
if(uuidCache) {
return;
}
- for(firstPass = 1; firstPass >= 0; firstPass--) {
+ for(int firstPass = 1; firstPass >= 0; firstPass--) {
fseek(procpt, 0, SEEK_SET);
while(fgets(line, sizeof(line), procpt)) {
if(sscanf(line, " %d %d %d %[^\n ]",
get_spec_by_uuid(const char *s)
{
char uuid[16];
- int i;
if(strlen(s) != 36
|| s[8] != '-' || s[13] != '-' || s[18] != '-' || s[23] != '-') {
goto bad_uuid;
}
- for(i=0; i<16; i++) {
+ for(int i=0; i<16; i++) {
if(*s == '-') {
s++;
}
static cu_mount_t *cu_mount_listmntent (void)
{
cu_mount_t *last = *list;
- struct tabmntent *p;
struct mntent *mnt;
struct tabmntent *mntlist;
#endif /* COLLECT_DEBUG */
}
- for(p = mntlist; p; p = p->next) {
+ for(struct tabmntent *p = mntlist; p; p = p->next) {
char *loop = NULL, *device = NULL;
mnt = p->ment;
STRUCT_STATFS *buf;
int num;
- int i;
cu_mount_t *first = NULL;
cu_mount_t *last = NULL;
return (NULL);
}
- for (i = 0; i < num; i++)
+ for (int i = 0; i < num; i++)
{
if ((new = calloc (1, sizeof (*new))) == NULL)
break;
void cu_mount_freelist (cu_mount_t *list)
{
- cu_mount_t *this;
cu_mount_t *next;
- for (this = list; this != NULL; this = next)
+ for (cu_mount_t *this = list; this != NULL; this = next)
{
next = this->next;
*/
#include "collectd.h"
+
#include "common.h"
#include "testing.h"
#include "utils_mount.h"
**/
#include "collectd.h"
+
#include "utils_parse_option.h"
int parse_string (char **ret_buffer, char **ret_string)
**/
#include "collectd.h"
+
#include "common.h"
#include "utils_rrdcreate.h"
*/
static void rra_free (int rra_num, char **rra_def) /* {{{ */
{
- int i;
-
- for (i = 0; i < rra_num; i++)
+ for (int i = 0; i < rra_num; i++)
{
sfree (rra_def[i]);
}
sfree (args->filename);
if (args->argv != NULL)
{
- int i;
- for (i = 0; i < args->argc; i++)
+ for (int i = 0; i < args->argc; i++)
sfree (args->argv[i]);
sfree (args->argv);
}
int cdp_num;
int cdp_len;
- int i, j;
/* The stepsize we use here: If it is user-set, use it. If not, use the
* interval of the value-list. */
rra_num = 0;
cdp_len = 0;
- for (i = 0; i < rts_num; i++)
+ for (int i = 0; i < rts_num; i++)
{
int span = rts[i];
cdp_num = (int) ceil (((double) span)
/ ((double) (cdp_len * ss)));
- for (j = 0; j < rra_types_num; j++)
+ for (int j = 0; j < rra_types_num; j++)
{
char buffer[128];
int status;
static void ds_free (int ds_num, char **ds_def) /* {{{ */
{
- int i;
-
- for (i = 0; i < ds_num; i++)
+ for (int i = 0; i < ds_num; i++)
if (ds_def[i] != NULL)
free (ds_def[i]);
free (ds_def);
#include "collectd.h"
+
#include <pthread.h>
#include <regex.h>
**/
#include "collectd.h"
+
#include "testing.h"
#include "utils_vl_lookup.h"
identifier_t ident;
void *user_class;
- memset (&ident, 0, sizeof (ident));
strncpy (ident.host, host, sizeof (ident.host));
strncpy (ident.plugin, plugin, sizeof (ident.plugin));
strncpy (ident.plugin_instance, plugin_instance, sizeof (ident.plugin_instance));
/**
* collectd - src/uuid.c
* Copyright (C) 2007 Red Hat Inc.
+ * Copyright (C) 2015 Ruben Kerkhof
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
**/
#include "collectd.h"
+
#include "common.h"
-#include "configfile.h"
#include "plugin.h"
+#if HAVE_SYS_SYSCTL_H
+#include <sys/sysctl.h>
+#endif
+
#if HAVE_LIBHAL_H
#include <libhal.h>
#endif
{
int len;
- if (!uuid) return 0;
+ if (!uuid)
+ return (0);
len = strlen (uuid);
if (len < UUID_PRINTABLE_COMPACT_LENGTH)
- return 0;
+ return (0);
while (*uuid) {
- if (!isxdigit ((int)*uuid) && *uuid != '-') return 0;
+ if (!isxdigit ((int)*uuid) && *uuid != '-')
+ return (0);
uuid++;
}
- return 1;
+ return (1);
}
static char *
if (!looks_like_a_uuid (fields[1]))
continue;
- return strdup (fields[1]);
+ return (strdup (fields[1]));
}
- return NULL;
+ return (NULL);
}
static char *
uuid_get_from_dmidecode(void)
{
- FILE *dmidecode = popen("dmidecode 2>/dev/null", "r");
+ FILE *dmidecode = popen("dmidecode -t system 2>/dev/null", "r");
char *uuid;
- if (!dmidecode) {
- return NULL;
- }
+ if (!dmidecode)
+ return (NULL);
uuid = uuid_parse_dmidecode(dmidecode);
pclose(dmidecode);
- return uuid;
+ return (uuid);
+}
+
+#if defined(__APPLE__) || defined(__FreeBSD__) || defined(__NetBSD__)
+static char *
+uuid_get_from_sysctlbyname(const char *name)
+{
+ char uuid[UUID_PRINTABLE_NORMAL_LENGTH + 1];
+ size_t len = sizeof (uuid);
+ if (sysctlbyname(name, &uuid, &len, NULL, 0) == -1)
+ return NULL;
+ return (strdup (uuid));
+}
+#elif defined(__OpenBSD__)
+static char *
+uuid_get_from_sysctl(void)
+{
+ char uuid[UUID_PRINTABLE_NORMAL_LENGTH + 1];
+ size_t len = sizeof (uuid);
+ int mib[2];
+
+ mib[0] = CTL_HW;
+ mib[1] = HW_UUID;
+
+ if (sysctl(mib, 2, uuid, &len, NULL, 0) == -1)
+ return NULL;
+ return (strdup (uuid));
}
+#endif
#if HAVE_LIBHAL_H
dbus_error_init(&error);
- if (!(con = dbus_bus_get(DBUS_BUS_SYSTEM, &error)) ) {
+ if (!(con = dbus_bus_get(DBUS_BUS_SYSTEM, &error)))
goto bailout_nobus;
- }
ctx = libhal_ctx_new();
libhal_ctx_set_dbus_connection(ctx, con);
- if (!libhal_ctx_init(ctx, &error)) {
+ if (!libhal_ctx_init(ctx, &error))
goto bailout;
- }
if (!libhal_device_property_exists(ctx,
UUID_PATH,
UUID_PROPERTY,
- &error)) {
+ &error))
goto bailout;
- }
char *uuid = libhal_device_get_property_string(ctx,
UUID_PATH,
UUID_PROPERTY,
&error);
- if (looks_like_a_uuid (uuid)) {
- return uuid;
- }
+ if (looks_like_a_uuid (uuid))
+ return (uuid);
bailout:
{
DBusError ctxerror;
dbus_error_init(&ctxerror);
- if (!(libhal_ctx_shutdown(ctx, &ctxerror))) {
+ if (!(libhal_ctx_shutdown(ctx, &ctxerror)))
dbus_error_free(&ctxerror);
- }
}
libhal_ctx_free(ctx);
- //dbus_connection_unref(con);
bailout_nobus:
- if (dbus_error_is_set(&error)) {
- /*printf("Error %s\n", error.name);*/
+ if (dbus_error_is_set(&error))
dbus_error_free(&error);
- }
- return NULL;
+ return (NULL);
}
#endif
file = fopen (path, "r");
if (file == NULL)
- return NULL;
+ return (NULL);
if (!fgets(uuid, sizeof(uuid), file)) {
fclose(file);
- return NULL;
+ return (NULL);
}
fclose(file);
strstripnewline (uuid);
- return strdup (uuid);
+ return (strdup (uuid));
}
static char *
char *uuid;
/* Check /etc/uuid / UUIDFile before any other method. */
- if ((uuid = uuid_get_from_file(uuidfile ? uuidfile : "/etc/uuid")) != NULL){
- return uuid;
- }
+ if ((uuid = uuid_get_from_file(uuidfile ? uuidfile : "/etc/uuid")) != NULL)
+ return (uuid);
+
+#if defined(__APPLE__)
+ if ((uuid = uuid_get_from_sysctlbyname("kern.uuid")) != NULL)
+ return (uuid);
+#elif defined(__FreeBSD__)
+ if ((uuid = uuid_get_from_sysctlbyname("kern.hostuuid")) != NULL)
+ return (uuid);
+#elif defined(__NetBSD__)
+ if ((uuid = uuid_get_from_sysctlbyname("machdep.dmi.system-uuid")) != NULL)
+ return (uuid);
+#elif defined(__OpenBSD__)
+ if ((uuid = uuid_get_from_sysctl()) != NULL)
+ return (uuid);
+#elif defined(__linux__)
+ if ((uuid = uuid_get_from_file("/sys/class/dmi/id/product_uuid")) != NULL)
+ return (uuid);
+#endif
#if HAVE_LIBHAL_H
- if ((uuid = uuid_get_from_hal()) != NULL) {
- return uuid;
- }
+ if ((uuid = uuid_get_from_hal()) != NULL)
+ return (uuid);
#endif
- if ((uuid = uuid_get_from_dmidecode()) != NULL) {
- return uuid;
- }
+ if ((uuid = uuid_get_from_dmidecode()) != NULL)
+ return (uuid);
- if ((uuid = uuid_get_from_file("/sys/hypervisor/uuid")) != NULL) {
- return uuid;
- }
+#if defined(__linux__)
+ if ((uuid = uuid_get_from_file("/sys/hypervisor/uuid")) != NULL)
+ return (uuid);
+#endif
- return NULL;
+ return (NULL);
}
static int
if (strcasecmp (key, "UUIDFile") == 0) {
char *tmp = strdup (value);
if (tmp == NULL)
- return -1;
+ return (-1);
sfree (uuidfile);
uuidfile = tmp;
- } else {
- return 1;
+ return (0);
}
- return 0;
+ return (1);
}
static int
if (uuid) {
sstrncpy (hostname_g, uuid, DATA_MAX_NAME_LEN);
sfree (uuid);
- return 0;
+ return (0);
}
WARNING ("uuid: could not read UUID using any known method");
- return 0;
+ return (0);
}
void module_register (void)
**/
#include "collectd.h"
+
#include "common.h"
#include "plugin.h"
-#include "configfile.h"
#if HAVE_VARNISH_V4
#include <vapi/vsm.h>
const char *category, const char *type, const char *type_instance,
uint64_t gauge_value)
{
- value_t value;
-
- value.gauge = (gauge_t) gauge_value;
-
- return (varnish_submit (plugin_instance, category, type, type_instance, value));
+ return (varnish_submit (plugin_instance, category, type, type_instance,
+ (value_t) { .gauge = (gauge_t) gauge_value }));
} /* }}} int varnish_submit_gauge */
static int varnish_submit_derive (const char *plugin_instance, /* {{{ */
const char *category, const char *type, const char *type_instance,
uint64_t derive_value)
{
- value_t value;
-
- value.derive = (derive_t) derive_value;
-
- return (varnish_submit (plugin_instance, category, type, type_instance, value));
+ return (varnish_submit (plugin_instance, category, type, type_instance,
+ (value_t) { .derive = (derive_t) derive_value }));
} /* }}} int varnish_submit_derive */
#if HAVE_VARNISH_V3 || HAVE_VARNISH_V4
static int varnish_init (void) /* {{{ */
{
user_config_t *conf;
- user_data_t ud;
if (have_instance)
return (0);
varnish_config_apply_default (conf);
- ud.data = conf;
- ud.free_func = varnish_config_free;
-
plugin_register_complex_read (/* group = */ "varnish",
/* name = */ "varnish/localhost",
/* callback = */ varnish_read,
/* interval = */ 0,
- /* user data = */ &ud);
+ &(user_data_t) {
+ .data = conf,
+ .free_func = varnish_config_free,
+ });
return (0);
} /* }}} int varnish_init */
static int varnish_config_instance (const oconfig_item_t *ci) /* {{{ */
{
user_config_t *conf;
- user_data_t ud;
char callback_name[DATA_MAX_NAME_LEN];
- int i;
conf = calloc (1, sizeof (*conf));
if (conf == NULL)
return (EINVAL);
}
- for (i = 0; i < ci->children_num; i++)
+ for (int i = 0; i < ci->children_num; i++)
{
oconfig_item_t *child = ci->children + i;
ssnprintf (callback_name, sizeof (callback_name), "varnish/%s",
(conf->instance == NULL) ? "localhost" : conf->instance);
- ud.data = conf;
- ud.free_func = varnish_config_free;
-
plugin_register_complex_read (/* group = */ "varnish",
/* name = */ callback_name,
/* callback = */ varnish_read,
/* interval = */ 0,
- /* user data = */ &ud);
+ &(user_data_t) {
+ .data = conf,
+ .free_func = varnish_config_free,
+ });
have_instance = 1;
static int varnish_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;
**/
#include "collectd.h"
+
#include "common.h"
#include "plugin.h"
-#include "configfile.h"
#include "utils_ignorelist.h"
#include "utils_complain.h"
static void
init_value_list (value_list_t *vl, virDomainPtr dom)
{
- int i, n;
+ int n;
const char *name;
char uuid[VIR_UUID_STRING_BUFLEN];
vl->host[0] = '\0';
/* Construct the hostname field according to HostnameFormat. */
- for (i = 0; i < HF_MAX_FIELDS; ++i) {
+ for (int i = 0; i < HF_MAX_FIELDS; ++i) {
if (hostname_format[i] == hf_none)
continue;
vl->host[sizeof (vl->host) - 1] = '\0';
/* Construct the plugin instance field according to PluginInstanceFormat. */
- for (i = 0; i < PLGINST_MAX_FIELDS; ++i) {
+ for (int i = 0; i < PLGINST_MAX_FIELDS; ++i) {
if (plugin_instance_format[i] == plginst_none)
continue;
} /* void init_value_list */
-static void
-memory_submit (gauge_t memory, virDomainPtr dom)
+static void submit (virDomainPtr dom,
+ char const *type, char const *type_instance,
+ value_t *values, size_t values_len)
{
- value_t values[1];
value_list_t vl = VALUE_LIST_INIT;
-
init_value_list (&vl, dom);
- values[0].gauge = memory;
-
vl.values = values;
- vl.values_len = 1;
+ vl.values_len = values_len;
- sstrncpy (vl.type, "memory", sizeof (vl.type));
- sstrncpy (vl.type_instance, "total", sizeof (vl.type_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);
}
static void
-memory_stats_submit (gauge_t memory, virDomainPtr dom, int tag_index)
+memory_submit (gauge_t value, virDomainPtr dom)
+{
+ submit (dom, "memory", "total", &(value_t) { .gauge = value }, 1);
+}
+
+static void
+memory_stats_submit (gauge_t value, virDomainPtr dom, int tag_index)
{
static const char *tags[] = { "swap_in", "swap_out", "major_fault", "minor_fault",
"unused", "available", "actual_balloon", "rss"};
- value_t values[1];
- value_list_t vl = VALUE_LIST_INIT;
-
- init_value_list (&vl, dom);
-
- values[0].gauge = memory;
-
- vl.values = values;
- vl.values_len = 1;
-
- sstrncpy (vl.type, "memory", sizeof (vl.type));
- sstrncpy (vl.type_instance, tags[tag_index], sizeof (vl.type_instance));
+ if ((tag_index < 0) || (tag_index >= STATIC_ARRAY_SIZE (tags))) {
+ ERROR ("virt plugin: Array index out of bounds: tag_index = %d", tag_index);
+ return;
+ }
- plugin_dispatch_values (&vl);
+ submit (dom, "memory", tags[tag_index], &(value_t) { .gauge = value }, 1);
}
static void
-cpu_submit (unsigned long long cpu_time,
+cpu_submit (unsigned long long value,
virDomainPtr dom, const char *type)
{
- value_t values[1];
- value_list_t vl = VALUE_LIST_INIT;
-
- init_value_list (&vl, dom);
-
- values[0].derive = cpu_time;
-
- vl.values = values;
- vl.values_len = 1;
-
- sstrncpy (vl.type, type, sizeof (vl.type));
-
- plugin_dispatch_values (&vl);
+ submit (dom, type, NULL, &(value_t) { .derive = (derive_t) value }, 1);
}
static void
-vcpu_submit (derive_t cpu_time,
+vcpu_submit (derive_t value,
virDomainPtr dom, int vcpu_nr, const char *type)
{
- value_t values[1];
- value_list_t vl = VALUE_LIST_INIT;
+ char type_instance[DATA_MAX_NAME_LEN];
- init_value_list (&vl, dom);
-
- values[0].derive = cpu_time;
- vl.values = values;
- vl.values_len = 1;
+ ssnprintf (type_instance, sizeof (type_instance), "%d", vcpu_nr);
- sstrncpy (vl.type, type, sizeof (vl.type));
- ssnprintf (vl.type_instance, sizeof (vl.type_instance), "%d", vcpu_nr);
-
- plugin_dispatch_values (&vl);
+ submit (dom, type, type_instance, &(value_t) { .derive = value }, 1);
}
static void
submit_derive2 (const char *type, derive_t v0, derive_t v1,
virDomainPtr dom, const char *devname)
{
- value_t values[2];
- value_list_t vl = VALUE_LIST_INIT;
-
- init_value_list (&vl, dom);
+ value_t values[] = {
+ { .derive = v0 },
+ { .derive = v1 },
+ };
- values[0].derive = v0;
- values[1].derive = v1;
- vl.values = values;
- vl.values_len = 2;
-
- sstrncpy (vl.type, type, sizeof (vl.type));
- sstrncpy (vl.type_instance, devname, sizeof (vl.type_instance));
-
- plugin_dispatch_values (&vl);
+ submit (dom, type, devname, values, STATIC_ARRAY_SIZE (values));
} /* void submit_derive2 */
static int
if (strcasecmp (key, "HostnameFormat") == 0) {
char *value_copy;
char *fields[HF_MAX_FIELDS];
- int i, n;
+ int n;
value_copy = strdup (value);
if (value_copy == NULL) {
return -1;
}
- for (i = 0; i < n; ++i) {
+ for (int i = 0; i < n; ++i) {
if (strcasecmp (fields[i], "hostname") == 0)
hostname_format[i] = hf_hostname;
else if (strcasecmp (fields[i], "name") == 0)
}
sfree (value_copy);
- for (i = n; i < HF_MAX_FIELDS; ++i)
+ for (int i = n; i < HF_MAX_FIELDS; ++i)
hostname_format[i] = hf_none;
return 0;
if (strcasecmp (key, "PluginInstanceFormat") == 0) {
char *value_copy;
char *fields[PLGINST_MAX_FIELDS];
- int i, n;
+ int n;
value_copy = strdup (value);
if (value_copy == NULL) {
return -1;
}
- for (i = 0; i < n; ++i) {
+ for (int i = 0; i < n; ++i) {
if (strcasecmp (fields[i], "none") == 0) {
plugin_instance_format[i] = plginst_none;
break;
}
sfree (value_copy);
- for (i = n; i < PLGINST_MAX_FIELDS; ++i)
+ for (int i = n; i < PLGINST_MAX_FIELDS; ++i)
plugin_instance_format[i] = plginst_none;
return 0;
lv_read (void)
{
time_t t;
- int i;
if (conn == NULL) {
/* `conn_string == NULL' is acceptable. */
}
#if 0
- for (i = 0; i < nr_domains; ++i)
+ for (int i = 0; i < nr_domains; ++i)
fprintf (stderr, "domain %s\n", virDomainGetName (domains[i]));
- for (i = 0; i < nr_block_devices; ++i)
+ for (int i = 0; i < nr_block_devices; ++i)
fprintf (stderr, "block device %d %s:%s\n",
i, virDomainGetName (block_devices[i].dom),
block_devices[i].path);
- for (i = 0; i < nr_interface_devices; ++i)
+ for (int i = 0; i < nr_interface_devices; ++i)
fprintf (stderr, "interface device %d %s:%s\n",
i, virDomainGetName (interface_devices[i].dom),
interface_devices[i].path);
#endif
/* Get CPU usage, memory, VCPU usage for each domain. */
- for (i = 0; i < nr_domains; ++i) {
+ for (int i = 0; i < nr_domains; ++i) {
virDomainInfo info;
virVcpuInfoPtr vinfo = NULL;
virDomainMemoryStatPtr minfo = NULL;
int status;
- int j;
status = virDomainGetInfo (domains[i], &info);
if (status != 0)
continue;
}
- for (j = 0; j < info.nrVirtCpu; ++j)
+ for (int j = 0; j < info.nrVirtCpu; ++j)
vcpu_submit (vinfo[j].cpuTime,
domains[i], vinfo[j].number, "virt_vcpu");
continue;
}
- for (j = 0; j < status; j++) {
+ for (int j = 0; j < status; j++) {
memory_stats_submit ((gauge_t) minfo[j].val * 1024, domains[i], minfo[j].tag);
}
/* Get block device stats for each domain. */
- for (i = 0; i < nr_block_devices; ++i) {
+ for (int i = 0; i < nr_block_devices; ++i) {
struct _virDomainBlockStats stats;
if (virDomainBlockStats (block_devices[i].dom, block_devices[i].path,
} /* for (nr_block_devices) */
/* Get interface stats for each domain. */
- for (i = 0; i < nr_interface_devices; ++i) {
+ for (int i = 0; i < nr_interface_devices; ++i) {
struct _virDomainInterfaceStats stats;
char *display_name = NULL;
}
if (n > 0) {
- int i;
int *domids;
/* Get list of domains. */
free_domains ();
/* Fetch each domain and add it to the list, unless ignore. */
- for (i = 0; i < n; ++i) {
+ for (int i = 0; i < n; ++i) {
virDomainPtr dom = NULL;
const char *name;
char *xml = NULL;
xmlDocPtr xml_doc = NULL;
xmlXPathContextPtr xpath_ctx = NULL;
xmlXPathObjectPtr xpath_obj = NULL;
- int j;
dom = virDomainLookupByID (conn, domids[i]);
if (dom == NULL) {
xpath_obj->nodesetval == NULL)
goto cont;
- for (j = 0; j < xpath_obj->nodesetval->nodeNr; ++j) {
+ for (int j = 0; j < xpath_obj->nodesetval->nodeNr; ++j) {
xmlNodePtr node;
char *path = NULL;
xmlNodeSetPtr xml_interfaces = xpath_obj->nodesetval;
- for (j = 0; j < xml_interfaces->nodeNr; ++j) {
+ for (int j = 0; j < xml_interfaces->nodeNr; ++j) {
char *path = NULL;
char *address = NULL;
xmlNodePtr xml_interface;
xml_interface = xml_interfaces->nodeTab[j];
if (!xml_interface) continue;
- xmlNodePtr child = NULL;
- for (child = xml_interface->children; child; child = child->next) {
+ for (xmlNodePtr child = xml_interface->children; child; child = child->next) {
if (child->type != XML_ELEMENT_NODE) continue;
if (xmlStrEqual(child->name, (const xmlChar *) "target")) {
static void
free_domains (void)
{
- int i;
-
if (domains) {
- for (i = 0; i < nr_domains; ++i)
+ for (int i = 0; i < nr_domains; ++i)
virDomainFree (domains[i]);
sfree (domains);
}
static void
free_block_devices (void)
{
- int i;
-
if (block_devices) {
- for (i = 0; i < nr_block_devices; ++i)
+ for (int i = 0; i < nr_block_devices; ++i)
sfree (block_devices[i].path);
sfree (block_devices);
}
static void
free_interface_devices (void)
{
- int i;
-
if (interface_devices) {
- for (i = 0; i < nr_interface_devices; ++i) {
+ for (int i = 0; i < nr_interface_devices; ++i) {
sfree (interface_devices[i].path);
sfree (interface_devices[i].address);
sfree (interface_devices[i].number);
**/
#include "collectd.h"
+
#include "common.h"
#include "plugin.h"
static void submit_two (const char *plugin_instance, const char *type,
const char *type_instance, derive_t c0, derive_t c1)
{
- value_t values[2];
-
- values[0].derive = c0;
- values[1].derive = c1;
+ value_t values[] = {
+ { .derive = c0 },
+ { .derive = c1 },
+ };
- submit (plugin_instance, type, type_instance, values, 2);
+ submit (plugin_instance, type, type_instance,
+ values, STATIC_ARRAY_SIZE (values));
} /* void submit_one */
static void submit_one (const char *plugin_instance, const char *type,
**/
#include "collectd.h"
+
#include "common.h"
#include "plugin.h"
static void traffic_submit (const char *plugin_instance,
const char *type_instance, derive_t rx, derive_t tx)
{
- value_t values[2];
value_list_t vl = VALUE_LIST_INIT;
-
- values[0].derive = rx;
- values[1].derive = tx;
+ value_t values[] = {
+ { .derive = rx },
+ { .derive = tx },
+ };
vl.values = values;
vl.values_len = STATIC_ARRAY_SIZE (values);
static void load_submit (const char *plugin_instance,
gauge_t snum, gauge_t mnum, gauge_t lnum)
{
- value_t values[3];
value_list_t vl = VALUE_LIST_INIT;
-
- values[0].gauge = snum;
- values[1].gauge = mnum;
- values[2].gauge = lnum;
+ value_t values[] = {
+ { .gauge = snum },
+ { .gauge = mnum },
+ { .gauge = lnum },
+ };
vl.values = values;
vl.values_len = STATIC_ARRAY_SIZE (values);
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_len = STATIC_ARRAY_SIZE (values);
+ vl.values = &(value_t) { .gauge = value };
+ vl.values_len = 1;
sstrncpy (vl.host, hostname_g, sizeof (vl.host));
sstrncpy (vl.plugin, "vserver", sizeof (vl.plugin));
sstrncpy (vl.plugin_instance, plugin_instance, sizeof (vl.plugin_instance));
**/
#include "collectd.h"
+
#include "common.h"
#include "plugin.h"
static void wireless_submit (const char *plugin_instance, const char *type,
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, "wireless", sizeof (vl.plugin));
*/
#include "collectd.h"
+
#include "common.h"
#include "plugin.h"
-#include "configfile.h"
#include "utils_complain.h"
#include "utils_format_graphite.h"
static int wg_callback_init (struct wg_callback *cb)
{
- struct addrinfo ai_hints;
struct addrinfo *ai_list;
- struct addrinfo *ai_ptr;
cdtime_t now;
int status;
return (EAGAIN);
cb->last_connect_time = now;
- memset (&ai_hints, 0, sizeof (ai_hints));
-#ifdef AI_ADDRCONFIG
- ai_hints.ai_flags |= AI_ADDRCONFIG;
-#endif
- ai_hints.ai_family = AF_UNSPEC;
+ struct addrinfo ai_hints = {
+ .ai_family = AF_UNSPEC,
+ .ai_flags = AI_ADDRCONFIG
+ };
if (0 == strcasecmp ("tcp", cb->protocol))
ai_hints.ai_socktype = SOCK_STREAM;
else
ai_hints.ai_socktype = SOCK_DGRAM;
- ai_list = NULL;
-
status = getaddrinfo (cb->node, cb->service, &ai_hints, &ai_list);
if (status != 0)
{
}
assert (ai_list != NULL);
- for (ai_ptr = ai_list; ai_ptr != NULL; ai_ptr = ai_ptr->ai_next)
+ for (struct addrinfo *ai_ptr = ai_list; ai_ptr != NULL; ai_ptr = ai_ptr->ai_next)
{
cb->sock_fd = socket (ai_ptr->ai_family, ai_ptr->ai_socktype,
ai_ptr->ai_protocol);
continue;
}
+ set_sock_opts (cb->sock_fd);
+
status = connect (cb->sock_fd, ai_ptr->ai_addr, ai_ptr->ai_addrlen);
if (status != 0)
{
static int wg_write_messages (const data_set_t *ds, const value_list_t *vl,
struct wg_callback *cb)
{
- char buffer[WG_SEND_BUF_SIZE];
+ char buffer[WG_SEND_BUF_SIZE] = { 0 };
int status;
if (0 != strcmp (ds->type, vl->type))
return -1;
}
- memset (buffer, 0, sizeof (buffer));
status = format_graphite (buffer, sizeof (buffer), ds, vl,
cb->prefix, cb->postfix, cb->escape_char, cb->format_flags);
if (status != 0) /* error message has been printed already. */
static int config_set_char (char *dest,
oconfig_item_t *ci)
{
- char buffer[4];
+ char buffer[4] = { 0 };
int status;
- memset (buffer, 0, sizeof (buffer));
-
status = cf_util_get_string_buffer (ci, buffer, sizeof (buffer));
if (status != 0)
return (status);
static int wg_config_node (oconfig_item_t *ci)
{
struct wg_callback *cb;
- user_data_t user_data;
char callback_name[DATA_MAX_NAME_LEN];
- int i;
int status = 0;
cb = calloc (1, sizeof (*cb));
pthread_mutex_init (&cb->send_lock, /* attr = */ NULL);
C_COMPLAIN_INIT (&cb->init_complaint);
- for (i = 0; i < ci->children_num; i++)
+ for (int i = 0; i < ci->children_num; i++)
{
oconfig_item_t *child = ci->children + i;
else if (strcasecmp ("AlwaysAppendDS", child->key) == 0)
cf_util_get_flag (child, &cb->format_flags,
GRAPHITE_ALWAYS_APPEND_DS);
+ else if (strcasecmp ("DropDuplicateFields", child->key) == 0)
+ cf_util_get_flag (child, &cb->format_flags,
+ GRAPHITE_DROP_DUPE_FIELDS);
else if (strcasecmp ("EscapeCharacter", child->key) == 0)
config_set_char (&cb->escape_char, child);
else
ssnprintf (callback_name, sizeof (callback_name), "write_graphite/%s",
cb->name);
- memset (&user_data, 0, sizeof (user_data));
- user_data.data = cb;
- user_data.free_func = wg_callback_free;
- plugin_register_write (callback_name, wg_write, &user_data);
+ plugin_register_write (callback_name, wg_write,
+ &(user_data_t) {
+ .data = cb,
+ .free_func = wg_callback_free,
+ });
- user_data.free_func = NULL;
- plugin_register_flush (callback_name, wg_flush, &user_data);
+ plugin_register_flush (callback_name, wg_flush, &(user_data_t) { .data = cb });
return (0);
}
static int wg_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;
**/
#include "collectd.h"
+
#include "plugin.h"
#include "common.h"
#include "utils_format_json.h"
#define WH_FORMAT_JSON 1
#define WH_FORMAT_KAIROSDB 2
int format;
+ _Bool send_metrics;
+ _Bool send_notifications;
CURL *curl;
struct curl_slist *headers;
static void wh_reset_buffer (wh_callback_t *cb) /* {{{ */
{
+ if ((cb == NULL) || (cb->send_buffer == NULL))
+ return;
+
memset (cb->send_buffer, 0, cb->send_buffer_size);
cb->send_buffer_free = cb->send_buffer_size;
cb->send_buffer_fill = 0;
}
} /* }}} wh_reset_buffer */
-static int wh_send_buffer (wh_callback_t *cb) /* {{{ */
+/* must hold cb->send_lock when calling */
+static int wh_post_nolock (wh_callback_t *cb, char const *data) /* {{{ */
{
int status = 0;
- curl_easy_setopt (cb->curl, CURLOPT_POSTFIELDS, cb->send_buffer);
+ curl_easy_setopt (cb->curl, CURLOPT_POSTFIELDS, data);
status = curl_easy_perform (cb->curl);
wh_log_http_error (cb);
status, cb->curl_errbuf);
}
return (status);
-} /* }}} wh_send_buffer */
+} /* }}} wh_post_nolock */
static int wh_callback_init (wh_callback_t *cb) /* {{{ */
{
return (0);
}
- status = wh_send_buffer (cb);
+ status = wh_post_nolock (cb, cb->send_buffer);
wh_reset_buffer (cb);
}
else if (cb->format == WH_FORMAT_JSON || cb->format == WH_FORMAT_KAIROSDB)
return (status);
}
- status = wh_send_buffer (cb);
+ status = wh_post_nolock (cb, cb->send_buffer);
wh_reset_buffer (cb);
}
else
pthread_mutex_lock (&cb->send_lock);
- if (cb->curl == NULL)
+ if (wh_callback_init (cb) != 0)
{
- status = wh_callback_init (cb);
- if (status != 0)
- {
- ERROR ("write_http plugin: wh_callback_init failed.");
- pthread_mutex_unlock (&cb->send_lock);
- return (-1);
- }
+ ERROR ("write_http plugin: wh_callback_init failed.");
+ pthread_mutex_unlock (&cb->send_lock);
+ return (-1);
}
status = wh_flush_nolock (timeout, cb);
cb = data;
- wh_flush_nolock (/* timeout = */ 0, cb);
+ if (cb->send_buffer != NULL)
+ wh_flush_nolock (/* timeout = */ 0, cb);
if (cb->curl != NULL)
{
int status;
- if (0 != strcmp (ds->type, vl->type)) {
+ /* sanity checks, primarily to make static analyzers happy. */
+ if ((cb == NULL) || (cb->send_buffer == NULL))
+ return -1;
+
+ if (strcmp (ds->type, vl->type) == 0) {
ERROR ("write_http plugin: DS type does not match "
"value list type");
return -1;
}
pthread_mutex_lock (&cb->send_lock);
-
- if (cb->curl == NULL)
+ if (wh_callback_init (cb) != 0)
{
- status = wh_callback_init (cb);
- if (status != 0)
- {
- ERROR ("write_http plugin: wh_callback_init failed.");
- pthread_mutex_unlock (&cb->send_lock);
- return (-1);
- }
+ ERROR ("write_http plugin: wh_callback_init failed.");
+ pthread_mutex_unlock (&cb->send_lock);
+ return (-1);
}
if (command_len >= cb->send_buffer_free)
}
assert (command_len < cb->send_buffer_free);
+ /* Make scan-build happy. */
+ assert (cb->send_buffer != NULL);
+
/* `command_len + 1' because `command_len' does not include the
* trailing null byte. Neither does `send_buffer_fill'. */
memcpy (cb->send_buffer + cb->send_buffer_fill,
int status;
pthread_mutex_lock (&cb->send_lock);
-
- if (cb->curl == NULL)
+ if (wh_callback_init (cb) != 0)
{
- status = wh_callback_init (cb);
- if (status != 0)
- {
- ERROR ("write_http plugin: wh_callback_init failed.");
- pthread_mutex_unlock (&cb->send_lock);
- return (-1);
- }
+ ERROR ("write_http plugin: wh_callback_init failed.");
+ pthread_mutex_unlock (&cb->send_lock);
+ return (-1);
}
status = format_json_value_list (cb->send_buffer,
return (-EINVAL);
cb = user_data->data;
+ assert (cb->send_metrics);
switch(cb->format) {
case WH_FORMAT_JSON:
return (status);
} /* }}} int wh_write */
+static int wh_notify (notification_t const *n, user_data_t *ud) /* {{{ */
+{
+ wh_callback_t *cb;
+ char alert[4096];
+ int status;
+
+ if ((ud == NULL) || (ud->data == NULL))
+ return (EINVAL);
+
+ cb = ud->data;
+ assert (cb->send_notifications);
+
+ status = format_json_notification (alert, sizeof (alert), n);
+ if (status != 0)
+ {
+ ERROR ("write_http plugin: formatting notification failed");
+ return status;
+ }
+
+ pthread_mutex_lock (&cb->send_lock);
+ if (wh_callback_init (cb) != 0)
+ {
+ ERROR ("write_http plugin: wh_callback_init failed.");
+ pthread_mutex_unlock (&cb->send_lock);
+ return (-1);
+ }
+
+ status = wh_post_nolock (cb, alert);
+ pthread_mutex_unlock (&cb->send_lock);
+
+ return (status);
+} /* }}} int wh_notify */
+
static int config_set_format (wh_callback_t *cb, /* {{{ */
oconfig_item_t *ci)
{
{
wh_callback_t *cb;
int buffer_size = 0;
- user_data_t user_data;
char callback_name[DATA_MAX_NAME_LEN];
int status = 0;
- int i;
cb = calloc (1, sizeof (*cb));
if (cb == NULL)
cb->timeout = 0;
cb->log_http_error = 0;
cb->headers = NULL;
-
+ cb->send_metrics = 1;
+ cb->send_notifications = 0;
pthread_mutex_init (&cb->send_lock, /* attr = */ NULL);
if (strcasecmp ("URL", ci->key) == 0)
cf_util_get_string (ci, &cb->location);
- for (i = 0; i < ci->children_num; i++)
+ for (int i = 0; i < ci->children_num; i++)
{
oconfig_item_t *child = ci->children + i;
}
else if (strcasecmp ("Format", child->key) == 0)
status = config_set_format (cb, child);
+ else if (strcasecmp ("Metrics", child->key) == 0)
+ cf_util_get_boolean (child, &cb->send_metrics);
+ else if (strcasecmp ("Notifications", child->key) == 0)
+ cf_util_get_boolean (child, &cb->send_notifications);
else if (strcasecmp ("StoreRates", child->key) == 0)
status = cf_util_get_boolean (child, &cb->store_rates);
else if (strcasecmp ("BufferSize", child->key) == 0)
return (-1);
}
+ if (!cb->send_metrics && !cb->send_notifications)
+ {
+ ERROR ("write_http plugin: Neither metrics nor notifications "
+ "are enabled for \"%s\".", cb->name);
+ wh_callback_free (cb);
+ return (-1);
+ }
+
if (cb->low_speed_limit > 0)
cb->low_speed_time = CDTIME_T_TO_TIME_T(plugin_get_interval());
DEBUG ("write_http: Registering write callback '%s' with URL '%s'",
callback_name, cb->location);
- memset (&user_data, 0, sizeof (user_data));
- user_data.data = cb;
- user_data.free_func = NULL;
+ user_data_t user_data = {
+ .data = cb
+ };
+
plugin_register_flush (callback_name, wh_flush, &user_data);
user_data.free_func = wh_callback_free;
- plugin_register_write (callback_name, wh_write, &user_data);
+
+ if (cb->send_metrics)
+ {
+ plugin_register_write (callback_name, wh_write, &user_data);
+ user_data.free_func = NULL;
+
+ plugin_register_flush (callback_name, wh_flush, &user_data);
+ }
+
+ if (cb->send_notifications)
+ {
+ plugin_register_notification (callback_name, wh_notify, &user_data);
+ user_data.free_func = NULL;
+ }
return (0);
} /* }}} int wh_config_node */
static int wh_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;
*/
#include "collectd.h"
+
#include "plugin.h"
#include "common.h"
-#include "configfile.h"
#include "utils_cmd_putval.h"
#include "utils_format_graphite.h"
#include "utils_format_json.h"
static void kafka_config_topic(rd_kafka_conf_t *conf, oconfig_item_t *ci) /* {{{ */
{
int status;
- int i;
struct kafka_topic_context *tctx;
char *key = NULL;
char *val;
char callback_name[DATA_MAX_NAME_LEN];
char errbuf[1024];
- user_data_t ud;
oconfig_item_t *child;
rd_kafka_conf_res_t ret;
goto errout;
}
- for (i = 0; i < ci->children_num; i++) {
+ for (int i = 0; i < ci->children_num; i++) {
/*
* The code here could be simplified but makes room
* for easy adding of new options later on.
ssnprintf(callback_name, sizeof(callback_name),
"write_kafka/%s", tctx->topic_name);
- ud.data = tctx;
- ud.free_func = kafka_topic_context_free;
-
- status = plugin_register_write (callback_name, kafka_write, &ud);
+ status = plugin_register_write (callback_name, kafka_write,
+ &(user_data_t) {
+ .data = tctx,
+ .free_func = kafka_topic_context_free,
+ });
if (status != 0) {
WARNING ("write_kafka plugin: plugin_register_write (\"%s\") "
"failed with status %i.",
static int kafka_config(oconfig_item_t *ci) /* {{{ */
{
- int i;
oconfig_item_t *child;
rd_kafka_conf_t *conf;
rd_kafka_conf_res_t ret;
WARNING("cannot allocate kafka configuration.");
return -1;
}
- for (i = 0; i < ci->children_num; i++) {
+ for (int i = 0; i < ci->children_num; i++) {
child = &ci->children[i];
if (strcasecmp("Topic", child->key) == 0) {
**/
#include "collectd.h"
+
#include "common.h"
#include "plugin.h"
-#include "configfile.h"
#include "utils_format_graphite.h"
+#include "utils_format_json.h"
#include <netdb.h>
-#define WL_BUF_SIZE 8192
+#define WL_BUF_SIZE 16384
+
+#define WL_FORMAT_GRAPHITE 1
+#define WL_FORMAT_JSON 2
-static int wl_write_messages (const data_set_t *ds, const value_list_t *vl)
+/* Plugin:WriteLog has to also operate without a config, so use a global. */
+int wl_format = WL_FORMAT_GRAPHITE;
+
+static int wl_write_graphite (const data_set_t *ds, const value_list_t *vl)
{
- char buffer[WL_BUF_SIZE];
+ char buffer[WL_BUF_SIZE] = { 0 };
int status;
if (0 != strcmp (ds->type, vl->type))
{
- ERROR ("write_log plugin: DS type does not match "
- "value list type");
+ ERROR ("write_log plugin: DS type does not match value list type");
return -1;
}
- memset (buffer, 0, sizeof (buffer));
status = format_graphite (buffer, sizeof (buffer), ds, vl,
NULL, NULL, '_', 0);
if (status != 0) /* error message has been printed already. */
INFO ("write_log values:\n%s", buffer);
return (0);
-} /* int wl_write_messages */
+} /* int wl_write_graphite */
+
+static int wl_write_json (const data_set_t *ds, const value_list_t *vl)
+{
+ char buffer[WL_BUF_SIZE] = { 0 };
+ size_t bfree = sizeof(buffer);
+ size_t bfill = 0;
+
+ if (0 != strcmp (ds->type, vl->type))
+ {
+ ERROR ("write_log plugin: DS type does not match value list type");
+ return -1;
+ }
+
+ format_json_initialize(buffer, &bfill, &bfree);
+ format_json_value_list(buffer, &bfill, &bfree, ds, vl,
+ /* store rates = */ 0);
+ format_json_finalize(buffer, &bfill, &bfree);
+
+ INFO ("write_log values:\n%s", buffer);
+
+ return (0);
+} /* int wl_write_json */
static int wl_write (const data_set_t *ds, const value_list_t *vl,
- user_data_t *user_data)
+ __attribute__ ((unused)) user_data_t *user_data)
{
- int status;
+ int status = 0;
- status = wl_write_messages (ds, vl);
+ if (wl_format == WL_FORMAT_GRAPHITE)
+ {
+ status = wl_write_graphite (ds, vl);
+ }
+ else if (wl_format == WL_FORMAT_JSON)
+ {
+ status = wl_write_json (ds, vl);
+ }
return (status);
}
+static int wl_config (oconfig_item_t *ci) /* {{{ */
+{
+ _Bool format_seen = 0;
+
+ for (int i = 0; i < ci->children_num; i++)
+ {
+ oconfig_item_t *child = ci->children + i;
+
+ if (strcasecmp ("Format", child->key) == 0)
+ {
+ char str[16];
+
+ if (cf_util_get_string_buffer (child, str, sizeof (str)) != 0)
+ continue;
+
+ if (format_seen)
+ {
+ WARNING ("write_log plugin: Redefining option `%s'.",
+ child->key);
+ }
+ format_seen = 1;
+
+ if (strcasecmp ("Graphite", str) == 0)
+ wl_format = WL_FORMAT_GRAPHITE;
+ else if (strcasecmp ("JSON", str) == 0)
+ wl_format = WL_FORMAT_JSON;
+ else
+ {
+ ERROR ("write_log plugin: Unknown format `%s' for option `%s'.",
+ str, child->key);
+ return (-EINVAL);
+ }
+ }
+ else
+ {
+ ERROR ("write_log plugin: Invalid configuration option: `%s'.",
+ child->key);
+ return (-EINVAL);
+ }
+ }
+
+ return (0);
+} /* }}} int wl_config */
+
void module_register (void)
{
+ plugin_register_complex_config ("write_log", wl_config);
+ /* If config is supplied, the global wl_format will be set. */
plugin_register_write ("write_log", wl_write, NULL);
}
**/
#include "collectd.h"
+
#include "plugin.h"
#include "common.h"
-#include "configfile.h"
#include "utils_cache.h"
#if HAVE_STDINT_H
{
bson *ret;
gauge_t *rates;
- int i;
ret = bson_alloc (); /* matched by bson_dealloc() */
if (ret == NULL)
bson_append_string (ret, "type_instance", vl->type_instance);
bson_append_start_array (ret, "values"); /* {{{ */
- for (i = 0; i < ds->ds_num; i++)
+ for (int i = 0; i < ds->ds_num; i++)
{
char key[16];
bson_append_finish_array (ret); /* }}} values */
bson_append_start_array (ret, "dstypes"); /* {{{ */
- for (i = 0; i < ds->ds_num; i++)
+ for (int i = 0; i < ds->ds_num; i++)
{
char key[16];
bson_append_finish_array (ret); /* }}} dstypes */
bson_append_start_array (ret, "dsnames"); /* {{{ */
- for (i = 0; i < ds->ds_num; i++)
+ for (int i = 0; i < ds->ds_num; i++)
{
char key[16];
{
wm_node_t *node;
int status;
- int i;
node = calloc (1, sizeof (*node));
if (node == NULL)
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;
if (status == 0)
{
char cb_name[DATA_MAX_NAME_LEN];
- user_data_t ud;
ssnprintf (cb_name, sizeof (cb_name), "write_mongodb/%s", node->name);
- ud.data = node;
- ud.free_func = wm_config_free;
-
- status = plugin_register_write (cb_name, wm_write, &ud);
+ status = plugin_register_write (cb_name, wm_write,
+ &(user_data_t) {
+ .data = node,
+ .free_func = wm_config_free,
+ });
INFO ("write_mongodb plugin: registered write plugin %s %d",cb_name,status);
}
static int wm_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;
**/
#include "collectd.h"
+
#include "plugin.h"
#include "common.h"
-#include "configfile.h"
#include <sys/time.h>
#include <hiredis/hiredis.h>
wr_node_t *node = ud->data;
char ident[512];
char key[512];
- char value[512];
+ char value[512] = { 0 };
char time[24];
size_t value_size;
char *value_ptr;
ident);
ssnprintf (time, sizeof (time), "%.9f", CDTIME_T_TO_DOUBLE(vl->time));
- memset (value, 0, sizeof (value));
value_size = sizeof (value);
value_ptr = &value[0];
status = format_values (value_ptr, value_size, ds, vl, node->store_rates);
wr_node_t *node;
int timeout;
int status;
- int i;
node = calloc (1, sizeof (*node));
if (node == NULL)
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;
if (status == 0)
{
char cb_name[DATA_MAX_NAME_LEN];
- user_data_t ud;
ssnprintf (cb_name, sizeof (cb_name), "write_redis/%s", node->name);
- ud.data = node;
- ud.free_func = wr_config_free;
-
- status = plugin_register_write (cb_name, wr_write, &ud);
+ status = plugin_register_write (cb_name, wr_write,
+ &(user_data_t) {
+ .data = node,
+ .free_func = wr_config_free,
+ });
}
if (status != 0)
static int wr_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;
#include "collectd.h"
-
-#include "plugin.h"
#include "common.h"
-#include "configfile.h"
+#include "plugin.h"
#include "utils_cache.h"
#include "utils_complain.h"
#include "write_riemann_threshold.h"
#include <errno.h>
#include <riemann/riemann-client.h>
-#define RIEMANN_HOST "localhost"
-#define RIEMANN_PORT 5555
-#define RIEMANN_TTL_FACTOR 2.0
-#define RIEMANN_BATCH_MAX 8192
+#define RIEMANN_HOST "localhost"
+#define RIEMANN_PORT 5555
+#define RIEMANN_TTL_FACTOR 2.0
+#define RIEMANN_BATCH_MAX 8192
struct riemann_host {
- c_complain_t init_complaint;
- char *name;
- char *event_service_prefix;
- pthread_mutex_t lock;
- _Bool batch_mode;
- _Bool notifications;
- _Bool check_thresholds;
- _Bool store_rates;
- _Bool always_append_ds;
- char *node;
- int port;
- riemann_client_type_t client_type;
- riemann_client_t *client;
- double ttl_factor;
- cdtime_t batch_init;
- int batch_max;
- int batch_timeout;
- int reference_count;
- riemann_message_t *batch_msg;
- char *tls_ca_file;
- char *tls_cert_file;
- char *tls_key_file;
- struct timeval timeout;
+ c_complain_t init_complaint;
+ char *name;
+ char *event_service_prefix;
+ pthread_mutex_t lock;
+ _Bool batch_mode;
+ _Bool notifications;
+ _Bool check_thresholds;
+ _Bool store_rates;
+ _Bool always_append_ds;
+ char *node;
+ int port;
+ riemann_client_type_t client_type;
+ riemann_client_t *client;
+ double ttl_factor;
+ cdtime_t batch_init;
+ int batch_max;
+ int batch_timeout;
+ int reference_count;
+ riemann_message_t *batch_msg;
+ char *tls_ca_file;
+ char *tls_cert_file;
+ char *tls_key_file;
+ struct timeval timeout;
};
-static char **riemann_tags;
-static size_t riemann_tags_num;
-static char **riemann_attrs;
-static size_t riemann_attrs_num;
+static char **riemann_tags;
+static size_t riemann_tags_num;
+static char **riemann_attrs;
+static size_t riemann_attrs_num;
/* host->lock must be held when calling this function. */
static int wrr_connect(struct riemann_host *host) /* {{{ */
{
- char const *node;
- int port;
-
- if (host->client)
- return 0;
-
- node = (host->node != NULL) ? host->node : RIEMANN_HOST;
- port = (host->port) ? host->port : RIEMANN_PORT;
-
- host->client = NULL;
-
- host->client = riemann_client_create(host->client_type, node, port,
- RIEMANN_CLIENT_OPTION_TLS_CA_FILE, host->tls_ca_file,
- RIEMANN_CLIENT_OPTION_TLS_CERT_FILE, host->tls_cert_file,
- RIEMANN_CLIENT_OPTION_TLS_KEY_FILE, host->tls_key_file,
- RIEMANN_CLIENT_OPTION_NONE);
- if (host->client == NULL) {
- c_complain (LOG_ERR, &host->init_complaint,
- "write_riemann plugin: Unable to connect to Riemann at %s:%d",
- node, port);
- return -1;
- }
- if (host->timeout.tv_sec != 0) {
- if (riemann_client_set_timeout(host->client, &host->timeout) != 0) {
- riemann_client_free(host->client);
- host->client = NULL;
- c_complain (LOG_ERR, &host->init_complaint,
- "write_riemann plugin: Unable to connect to Riemann at %s:%d",
- node, port);
- return -1;
- }
- }
-
- c_release (LOG_INFO, &host->init_complaint,
- "write_riemann plugin: Successfully connected to %s:%d",
+ char const *node;
+ int port;
+
+ if (host->client)
+ return 0;
+
+ node = (host->node != NULL) ? host->node : RIEMANN_HOST;
+ port = (host->port) ? host->port : RIEMANN_PORT;
+
+ host->client = NULL;
+
+ host->client = riemann_client_create(
+ host->client_type, node, port, RIEMANN_CLIENT_OPTION_TLS_CA_FILE,
+ host->tls_ca_file, RIEMANN_CLIENT_OPTION_TLS_CERT_FILE,
+ host->tls_cert_file, RIEMANN_CLIENT_OPTION_TLS_KEY_FILE,
+ host->tls_key_file, RIEMANN_CLIENT_OPTION_NONE);
+ if (host->client == NULL) {
+ c_complain(LOG_ERR, &host->init_complaint,
+ "write_riemann plugin: Unable to connect to Riemann at %s:%d",
node, port);
+ return -1;
+ }
+#if RCC_VERSION_NUMBER >= 0x010800
+ if (host->timeout.tv_sec != 0) {
+ if (riemann_client_set_timeout(host->client, &host->timeout) != 0) {
+ riemann_client_free(host->client);
+ host->client = NULL;
+ c_complain(LOG_ERR, &host->init_complaint,
+ "write_riemann plugin: Unable to connect to Riemann at %s:%d",
+ node, port);
+ return -1;
+ }
+ }
+#endif
+
+ set_sock_opts(riemann_client_get_fd(host->client));
+
+ c_release(LOG_INFO, &host->init_complaint,
+ "write_riemann plugin: Successfully connected to %s:%d", node,
+ port);
- return 0;
+ return 0;
} /* }}} int wrr_connect */
/* host->lock must be held when calling this function. */
static int wrr_disconnect(struct riemann_host *host) /* {{{ */
{
- if (!host->client)
- return (0);
+ if (!host->client)
+ return (0);
- riemann_client_free(host->client);
- host->client = NULL;
+ riemann_client_free(host->client);
+ host->client = NULL;
- return (0);
+ return (0);
} /* }}} int wrr_disconnect */
/**
*
* Acquires the host lock, disconnects on errors.
*/
-static int wrr_send_nolock(struct riemann_host *host, riemann_message_t *msg) /* {{{ */
+static int wrr_send_nolock(struct riemann_host *host,
+ riemann_message_t *msg) /* {{{ */
{
- int status = 0;
+ int status = 0;
+
+ status = wrr_connect(host);
+ if (status != 0) {
+ return status;
+ }
- status = wrr_connect(host);
- if (status != 0) {
- return status;
+ status = riemann_client_send_message(host->client, msg);
+ if (status != 0) {
+ wrr_disconnect(host);
+ return status;
+ }
+
+ /*
+ * For TCP we need to receive message acknowledgemenent.
+ */
+ if (host->client_type != RIEMANN_CLIENT_UDP) {
+ riemann_message_t *response;
+
+ response = riemann_client_recv_message(host->client);
+
+ if (response == NULL) {
+ wrr_disconnect(host);
+ return errno;
}
+ riemann_message_free(response);
+ }
- status = riemann_client_send_message(host->client, msg);
- if (status != 0) {
- wrr_disconnect(host);
- return status;
- }
-
- /*
- * For TCP we need to receive message acknowledgemenent.
- */
- if (host->client_type != RIEMANN_CLIENT_UDP)
- {
- riemann_message_t *response;
-
- response = riemann_client_recv_message(host->client);
-
- if (response == NULL)
- {
- wrr_disconnect(host);
- return errno;
- }
- riemann_message_free(response);
- }
-
- return 0;
+ return 0;
} /* }}} int wrr_send */
-static int wrr_send(struct riemann_host *host, riemann_message_t *msg)
-{
- int status = 0;
+static int wrr_send(struct riemann_host *host, riemann_message_t *msg) {
+ int status = 0;
- pthread_mutex_lock (&host->lock);
- status = wrr_send_nolock(host, msg);
- pthread_mutex_unlock (&host->lock);
- return status;
+ pthread_mutex_lock(&host->lock);
+ status = wrr_send_nolock(host, msg);
+ pthread_mutex_unlock(&host->lock);
+ return status;
}
-static riemann_message_t *wrr_notification_to_message(struct riemann_host *host, /* {{{ */
- notification_t const *n)
-{
- riemann_message_t *msg;
- riemann_event_t *event;
- char service_buffer[6 * DATA_MAX_NAME_LEN];
- char const *severity;
- notification_meta_t *meta;
- size_t i;
-
- switch (n->severity)
- {
- case NOTIF_OKAY: severity = "ok"; break;
- case NOTIF_WARNING: severity = "warning"; break;
- case NOTIF_FAILURE: severity = "critical"; break;
- default: severity = "unknown";
- }
-
- format_name(service_buffer, sizeof(service_buffer),
- /* host = */ "", n->plugin, n->plugin_instance,
- n->type, n->type_instance);
-
- event = riemann_event_create(RIEMANN_EVENT_FIELD_HOST, n->host,
- RIEMANN_EVENT_FIELD_TIME, (int64_t) CDTIME_T_TO_TIME_T(n->time),
- RIEMANN_EVENT_FIELD_TAGS, "notification", NULL,
- RIEMANN_EVENT_FIELD_STATE, severity,
- RIEMANN_EVENT_FIELD_SERVICE, &service_buffer[1],
- RIEMANN_EVENT_FIELD_NONE);
-
- if (n->host[0] != 0)
- riemann_event_string_attribute_add(event, "host", n->host);
- if (n->plugin[0] != 0)
- riemann_event_string_attribute_add(event, "plugin", n->plugin);
- if (n->plugin_instance[0] != 0)
- riemann_event_string_attribute_add(event, "plugin_instance", n->plugin_instance);
-
- if (n->type[0] != 0)
- riemann_event_string_attribute_add(event, "type", n->type);
- if (n->type_instance[0] != 0)
- riemann_event_string_attribute_add(event, "type_instance", n->type_instance);
-
- for (i = 0; i < riemann_attrs_num; i += 2)
- riemann_event_string_attribute_add(event, riemann_attrs[i], riemann_attrs[i+1]);
-
- for (i = 0; i < riemann_tags_num; i++)
- riemann_event_tag_add(event, riemann_tags[i]);
-
- if (n->message[0] != 0)
- riemann_event_string_attribute_add(event, "description", n->message);
-
- /* Pull in values from threshold and add extra attributes */
- for (meta = n->meta; meta != NULL; meta = meta->next)
- {
- if (strcasecmp("CurrentValue", meta->name) == 0 && meta->type == NM_TYPE_DOUBLE)
- {
- riemann_event_set(event,
- RIEMANN_EVENT_FIELD_METRIC_D,
- (double) meta->nm_value.nm_double,
- RIEMANN_EVENT_FIELD_NONE);
- continue;
- }
-
- if (meta->type == NM_TYPE_STRING) {
- riemann_event_string_attribute_add(event, meta->name, meta->nm_value.nm_string);
- continue;
- }
- }
-
- msg = riemann_message_create_with_events(event, NULL);
- if (msg == NULL)
- {
- ERROR("write_riemann plugin: riemann_message_create_with_events() failed.");
- riemann_event_free (event);
- return (NULL);
- }
-
- DEBUG("write_riemann plugin: Successfully created message for notification: "
- "host = \"%s\", service = \"%s\", state = \"%s\"",
- event->host, event->service, event->state);
- return (msg);
+static riemann_message_t *
+wrr_notification_to_message(struct riemann_host *host, /* {{{ */
+ notification_t const *n) {
+ riemann_message_t *msg;
+ riemann_event_t *event;
+ char service_buffer[6 * DATA_MAX_NAME_LEN];
+ char const *severity;
+
+ switch (n->severity) {
+ case NOTIF_OKAY:
+ severity = "ok";
+ break;
+ case NOTIF_WARNING:
+ severity = "warning";
+ break;
+ case NOTIF_FAILURE:
+ severity = "critical";
+ break;
+ default:
+ severity = "unknown";
+ }
+
+ format_name(service_buffer, sizeof(service_buffer),
+ /* host = */ "", n->plugin, n->plugin_instance, n->type,
+ n->type_instance);
+
+ event = riemann_event_create(
+ RIEMANN_EVENT_FIELD_HOST, n->host, RIEMANN_EVENT_FIELD_TIME,
+ (int64_t)CDTIME_T_TO_TIME_T(n->time), RIEMANN_EVENT_FIELD_TAGS,
+ "notification", NULL, RIEMANN_EVENT_FIELD_STATE, severity,
+ RIEMANN_EVENT_FIELD_SERVICE, &service_buffer[1],
+ RIEMANN_EVENT_FIELD_NONE);
+
+ if (n->host[0] != 0)
+ riemann_event_string_attribute_add(event, "host", n->host);
+ if (n->plugin[0] != 0)
+ riemann_event_string_attribute_add(event, "plugin", n->plugin);
+ if (n->plugin_instance[0] != 0)
+ riemann_event_string_attribute_add(event, "plugin_instance",
+ n->plugin_instance);
+
+ if (n->type[0] != 0)
+ riemann_event_string_attribute_add(event, "type", n->type);
+ if (n->type_instance[0] != 0)
+ riemann_event_string_attribute_add(event, "type_instance",
+ n->type_instance);
+
+ for (size_t i = 0; i < riemann_attrs_num; i += 2)
+ riemann_event_string_attribute_add(event, riemann_attrs[i],
+ riemann_attrs[i + 1]);
+
+ for (size_t i = 0; i < riemann_tags_num; i++)
+ riemann_event_tag_add(event, riemann_tags[i]);
+
+ if (n->message[0] != 0)
+ riemann_event_string_attribute_add(event, "description", n->message);
+
+ /* Pull in values from threshold and add extra attributes */
+ for (notification_meta_t *meta = n->meta; meta != NULL; meta = meta->next) {
+ if (strcasecmp("CurrentValue", meta->name) == 0 &&
+ meta->type == NM_TYPE_DOUBLE) {
+ riemann_event_set(event, RIEMANN_EVENT_FIELD_METRIC_D,
+ (double)meta->nm_value.nm_double,
+ RIEMANN_EVENT_FIELD_NONE);
+ continue;
+ }
+
+ if (meta->type == NM_TYPE_STRING) {
+ riemann_event_string_attribute_add(event, meta->name,
+ meta->nm_value.nm_string);
+ continue;
+ }
+ }
+
+ msg = riemann_message_create_with_events(event, NULL);
+ if (msg == NULL) {
+ ERROR("write_riemann plugin: riemann_message_create_with_events() failed.");
+ riemann_event_free(event);
+ return (NULL);
+ }
+
+ DEBUG("write_riemann plugin: Successfully created message for notification: "
+ "host = \"%s\", service = \"%s\", state = \"%s\"",
+ event->host, event->service, event->state);
+ return (msg);
} /* }}} riemann_message_t *wrr_notification_to_message */
-static riemann_event_t *wrr_value_to_event(struct riemann_host const *host, /* {{{ */
- data_set_t const *ds,
- value_list_t const *vl, size_t index,
- gauge_t const *rates,
- int status)
-{
- riemann_event_t *event;
- char name_buffer[5 * DATA_MAX_NAME_LEN];
- char service_buffer[6 * DATA_MAX_NAME_LEN];
- size_t i;
-
- event = riemann_event_new();
- if (event == NULL)
- {
- ERROR("write_riemann plugin: riemann_event_new() failed.");
- return (NULL);
- }
-
- format_name(name_buffer, sizeof(name_buffer),
- /* host = */ "", vl->plugin, vl->plugin_instance,
- vl->type, vl->type_instance);
- if (host->always_append_ds || (ds->ds_num > 1))
- {
- if (host->event_service_prefix == NULL)
- ssnprintf(service_buffer, sizeof(service_buffer), "%s/%s",
- &name_buffer[1], ds->ds[index].name);
- else
- ssnprintf(service_buffer, sizeof(service_buffer), "%s%s/%s",
- host->event_service_prefix, &name_buffer[1], ds->ds[index].name);
- }
- else
- {
- if (host->event_service_prefix == NULL)
- sstrncpy(service_buffer, &name_buffer[1], sizeof(service_buffer));
- else
- ssnprintf(service_buffer, sizeof(service_buffer), "%s%s",
- host->event_service_prefix, &name_buffer[1]);
- }
-
- riemann_event_set(event,
- RIEMANN_EVENT_FIELD_HOST, vl->host,
- RIEMANN_EVENT_FIELD_TIME, (int64_t) CDTIME_T_TO_TIME_T(vl->time),
- RIEMANN_EVENT_FIELD_TTL, (float) CDTIME_T_TO_DOUBLE(vl->interval) * host->ttl_factor,
- RIEMANN_EVENT_FIELD_STRING_ATTRIBUTES,
- "plugin", vl->plugin,
- "type", vl->type,
- "ds_name", ds->ds[index].name,
- NULL,
- RIEMANN_EVENT_FIELD_SERVICE, service_buffer,
- RIEMANN_EVENT_FIELD_NONE);
-
- if (host->check_thresholds) {
- const char *state = NULL;
-
- switch (status) {
- case STATE_OKAY:
- state = "ok";
- break;
- case STATE_ERROR:
- state = "critical";
- break;
- case STATE_WARNING:
- state = "warning";
- break;
- case STATE_MISSING:
- state = "unknown";
- break;
- }
- if (state)
- riemann_event_set(event, RIEMANN_EVENT_FIELD_STATE, state,
- RIEMANN_EVENT_FIELD_NONE);
- }
-
- if (vl->plugin_instance[0] != 0)
- riemann_event_string_attribute_add(event, "plugin_instance", vl->plugin_instance);
- if (vl->type_instance[0] != 0)
- riemann_event_string_attribute_add(event, "type_instance", vl->type_instance);
-
- if ((ds->ds[index].type != DS_TYPE_GAUGE) && (rates != NULL))
- {
- char ds_type[DATA_MAX_NAME_LEN];
-
- ssnprintf(ds_type, sizeof(ds_type), "%s:rate",
- DS_TYPE_TO_STRING(ds->ds[index].type));
- riemann_event_string_attribute_add(event, "ds_type", ds_type);
- }
- else
- {
- riemann_event_string_attribute_add(event, "ds_type",
+static riemann_event_t *
+wrr_value_to_event(struct riemann_host const *host, /* {{{ */
+ data_set_t const *ds, value_list_t const *vl, size_t index,
+ gauge_t const *rates, int status) {
+ riemann_event_t *event;
+ char name_buffer[5 * DATA_MAX_NAME_LEN];
+ char service_buffer[6 * DATA_MAX_NAME_LEN];
+ size_t i;
+
+ event = riemann_event_new();
+ if (event == NULL) {
+ ERROR("write_riemann plugin: riemann_event_new() failed.");
+ return (NULL);
+ }
+
+ format_name(name_buffer, sizeof(name_buffer),
+ /* host = */ "", vl->plugin, vl->plugin_instance, vl->type,
+ vl->type_instance);
+ if (host->always_append_ds || (ds->ds_num > 1)) {
+ if (host->event_service_prefix == NULL)
+ ssnprintf(service_buffer, sizeof(service_buffer), "%s/%s",
+ &name_buffer[1], ds->ds[index].name);
+ else
+ ssnprintf(service_buffer, sizeof(service_buffer), "%s%s/%s",
+ host->event_service_prefix, &name_buffer[1],
+ ds->ds[index].name);
+ } else {
+ if (host->event_service_prefix == NULL)
+ sstrncpy(service_buffer, &name_buffer[1], sizeof(service_buffer));
+ else
+ ssnprintf(service_buffer, sizeof(service_buffer), "%s%s",
+ host->event_service_prefix, &name_buffer[1]);
+ }
+
+ riemann_event_set(
+ event, RIEMANN_EVENT_FIELD_HOST, vl->host, RIEMANN_EVENT_FIELD_TIME,
+ (int64_t)CDTIME_T_TO_TIME_T(vl->time), RIEMANN_EVENT_FIELD_TTL,
+ (float)CDTIME_T_TO_DOUBLE(vl->interval) * host->ttl_factor,
+ RIEMANN_EVENT_FIELD_STRING_ATTRIBUTES, "plugin", vl->plugin, "type",
+ vl->type, "ds_name", ds->ds[index].name, NULL,
+ RIEMANN_EVENT_FIELD_SERVICE, service_buffer, RIEMANN_EVENT_FIELD_NONE);
+
+ if (host->check_thresholds) {
+ const char *state = NULL;
+
+ switch (status) {
+ case STATE_OKAY:
+ state = "ok";
+ break;
+ case STATE_ERROR:
+ state = "critical";
+ break;
+ case STATE_WARNING:
+ state = "warning";
+ break;
+ case STATE_MISSING:
+ state = "unknown";
+ break;
+ }
+ if (state)
+ riemann_event_set(event, RIEMANN_EVENT_FIELD_STATE, state,
+ RIEMANN_EVENT_FIELD_NONE);
+ }
+
+ if (vl->plugin_instance[0] != 0)
+ riemann_event_string_attribute_add(event, "plugin_instance",
+ vl->plugin_instance);
+ if (vl->type_instance[0] != 0)
+ riemann_event_string_attribute_add(event, "type_instance",
+ vl->type_instance);
+
+ if ((ds->ds[index].type != DS_TYPE_GAUGE) && (rates != NULL)) {
+ char ds_type[DATA_MAX_NAME_LEN];
+
+ ssnprintf(ds_type, sizeof(ds_type), "%s:rate",
+ DS_TYPE_TO_STRING(ds->ds[index].type));
+ riemann_event_string_attribute_add(event, "ds_type", ds_type);
+ } else {
+ riemann_event_string_attribute_add(event, "ds_type",
DS_TYPE_TO_STRING(ds->ds[index].type));
- }
-
- {
- char ds_index[DATA_MAX_NAME_LEN];
-
- ssnprintf(ds_index, sizeof(ds_index), "%zu", index);
- riemann_event_string_attribute_add(event, "ds_index", ds_index);
- }
-
- for (i = 0; i < riemann_attrs_num; i += 2)
- riemann_event_string_attribute_add(event, riemann_attrs[i], riemann_attrs[i +1]);
-
- for (i = 0; i < riemann_tags_num; i++)
- riemann_event_tag_add(event, riemann_tags[i]);
-
- if (ds->ds[index].type == DS_TYPE_GAUGE)
- {
- riemann_event_set(event,
- RIEMANN_EVENT_FIELD_METRIC_D,
- (double) vl->values[index].gauge,
- RIEMANN_EVENT_FIELD_NONE);
- }
- else if (rates != NULL)
- {
- riemann_event_set(event,
- RIEMANN_EVENT_FIELD_METRIC_D,
- (double) rates[index],
- RIEMANN_EVENT_FIELD_NONE);
- }
- else
- {
- int64_t metric;
-
- if (ds->ds[index].type == DS_TYPE_DERIVE)
- metric = (int64_t) vl->values[index].derive;
- else if (ds->ds[index].type == DS_TYPE_ABSOLUTE)
- metric = (int64_t) vl->values[index].absolute;
- else
- metric = (int64_t) vl->values[index].counter;
-
- riemann_event_set(event,
- RIEMANN_EVENT_FIELD_METRIC_S64,
- (int64_t) metric,
- RIEMANN_EVENT_FIELD_NONE);
- }
-
- DEBUG("write_riemann plugin: Successfully created message for metric: "
- "host = \"%s\", service = \"%s\"",
- event->host, event->service);
- return (event);
+ }
+
+ {
+ char ds_index[DATA_MAX_NAME_LEN];
+
+ ssnprintf(ds_index, sizeof(ds_index), "%zu", index);
+ riemann_event_string_attribute_add(event, "ds_index", ds_index);
+ }
+
+ for (i = 0; i < riemann_attrs_num; i += 2)
+ riemann_event_string_attribute_add(event, riemann_attrs[i],
+ riemann_attrs[i + 1]);
+
+ for (i = 0; i < riemann_tags_num; i++)
+ riemann_event_tag_add(event, riemann_tags[i]);
+
+ if (ds->ds[index].type == DS_TYPE_GAUGE) {
+ riemann_event_set(event, RIEMANN_EVENT_FIELD_METRIC_D,
+ (double)vl->values[index].gauge,
+ RIEMANN_EVENT_FIELD_NONE);
+ } else if (rates != NULL) {
+ riemann_event_set(event, RIEMANN_EVENT_FIELD_METRIC_D, (double)rates[index],
+ RIEMANN_EVENT_FIELD_NONE);
+ } else {
+ int64_t metric;
+
+ if (ds->ds[index].type == DS_TYPE_DERIVE)
+ metric = (int64_t)vl->values[index].derive;
+ else if (ds->ds[index].type == DS_TYPE_ABSOLUTE)
+ metric = (int64_t)vl->values[index].absolute;
+ else
+ metric = (int64_t)vl->values[index].counter;
+
+ riemann_event_set(event, RIEMANN_EVENT_FIELD_METRIC_S64, (int64_t)metric,
+ RIEMANN_EVENT_FIELD_NONE);
+ }
+
+ DEBUG("write_riemann plugin: Successfully created message for metric: "
+ "host = \"%s\", service = \"%s\"",
+ event->host, event->service);
+ return (event);
} /* }}} riemann_event_t *wrr_value_to_event */
-static riemann_message_t *wrr_value_list_to_message(struct riemann_host const *host, /* {{{ */
- data_set_t const *ds,
- value_list_t const *vl,
- int *statuses)
-{
- riemann_message_t *msg;
- size_t i;
- gauge_t *rates = NULL;
-
- /* Initialize the Msg structure. */
- msg = riemann_message_new();
- if (msg == NULL)
- {
- ERROR ("write_riemann plugin: riemann_message_new failed.");
- return (NULL);
- }
-
- if (host->store_rates)
- {
- rates = uc_get_rate(ds, vl);
- if (rates == NULL)
- {
- ERROR("write_riemann plugin: uc_get_rate failed.");
- riemann_message_free(msg);
- return (NULL);
- }
- }
-
- for (i = 0; i < vl->values_len; i++)
- {
- riemann_event_t *event;
-
- event = wrr_value_to_event(host, ds, vl,
- (int) i, rates, statuses[i]);
- if (event == NULL)
- {
- riemann_message_free(msg);
- sfree(rates);
- return (NULL);
- }
- riemann_message_append_events(msg, event, NULL);
- }
-
- sfree(rates);
- return (msg);
+static riemann_message_t *
+wrr_value_list_to_message(struct riemann_host const *host, /* {{{ */
+ data_set_t const *ds, value_list_t const *vl,
+ int *statuses) {
+ riemann_message_t *msg;
+ size_t i;
+ gauge_t *rates = NULL;
+
+ /* Initialize the Msg structure. */
+ msg = riemann_message_new();
+ if (msg == NULL) {
+ ERROR("write_riemann plugin: riemann_message_new failed.");
+ return (NULL);
+ }
+
+ if (host->store_rates) {
+ rates = uc_get_rate(ds, vl);
+ if (rates == NULL) {
+ ERROR("write_riemann plugin: uc_get_rate failed.");
+ riemann_message_free(msg);
+ return (NULL);
+ }
+ }
+
+ for (i = 0; i < vl->values_len; i++) {
+ riemann_event_t *event;
+
+ event = wrr_value_to_event(host, ds, vl, (int)i, rates, statuses[i]);
+ if (event == NULL) {
+ riemann_message_free(msg);
+ sfree(rates);
+ return (NULL);
+ }
+ riemann_message_append_events(msg, event, NULL);
+ }
+
+ sfree(rates);
+ return (msg);
} /* }}} riemann_message_t *wrr_value_list_to_message */
/*
* Always call while holding host->lock !
*/
-static int wrr_batch_flush_nolock(cdtime_t timeout,
- struct riemann_host *host)
-{
- cdtime_t now;
- int status = 0;
-
- now = cdtime();
- if (timeout > 0) {
- if ((host->batch_init + timeout) > now) {
- return status;
- }
- }
- wrr_send_nolock(host, host->batch_msg);
- riemann_message_free(host->batch_msg);
-
- host->batch_init = now;
- host->batch_msg = NULL;
- return status;
+static int wrr_batch_flush_nolock(cdtime_t timeout, struct riemann_host *host) {
+ cdtime_t now;
+ int status = 0;
+
+ now = cdtime();
+ if (timeout > 0) {
+ if ((host->batch_init + timeout) > now) {
+ return status;
+ }
+ }
+ wrr_send_nolock(host, host->batch_msg);
+ riemann_message_free(host->batch_msg);
+
+ host->batch_init = now;
+ host->batch_msg = NULL;
+ return status;
}
static int wrr_batch_flush(cdtime_t timeout,
- const char *identifier __attribute__((unused)),
- user_data_t *user_data)
-{
- struct riemann_host *host;
- int status;
-
- if (user_data == NULL)
- return (-EINVAL);
-
- host = user_data->data;
- pthread_mutex_lock(&host->lock);
- status = wrr_batch_flush_nolock(timeout, host);
- if (status != 0)
- c_complain (LOG_ERR, &host->init_complaint,
- "write_riemann plugin: riemann_client_send failed with status %i",
- status);
- else
- c_release (LOG_DEBUG, &host->init_complaint, "write_riemann plugin: batch sent.");
+ const char *identifier __attribute__((unused)),
+ user_data_t *user_data) {
+ struct riemann_host *host;
+ int status;
+
+ if (user_data == NULL)
+ return (-EINVAL);
- pthread_mutex_unlock(&host->lock);
- return status;
+ host = user_data->data;
+ pthread_mutex_lock(&host->lock);
+ status = wrr_batch_flush_nolock(timeout, host);
+ if (status != 0)
+ c_complain(
+ LOG_ERR, &host->init_complaint,
+ "write_riemann plugin: riemann_client_send failed with status %i",
+ status);
+ else
+ c_release(LOG_DEBUG, &host->init_complaint,
+ "write_riemann plugin: batch sent.");
+
+ pthread_mutex_unlock(&host->lock);
+ return status;
}
static int wrr_batch_add_value_list(struct riemann_host *host, /* {{{ */
- data_set_t const *ds,
- value_list_t const *vl,
- int *statuses)
-{
- riemann_message_t *msg;
- size_t len;
- int ret;
- cdtime_t timeout;
-
- msg = wrr_value_list_to_message(host, ds, vl, statuses);
- if (msg == NULL)
- return -1;
-
- pthread_mutex_lock(&host->lock);
-
- if (host->batch_msg == NULL) {
- host->batch_msg = msg;
- } else {
- int status;
-
- status = riemann_message_append_events_n(host->batch_msg,
- msg->n_events,
- msg->events);
- msg->n_events = 0;
- msg->events = NULL;
-
- riemann_message_free(msg);
-
- if (status != 0) {
- pthread_mutex_unlock(&host->lock);
- ERROR("write_riemann plugin: out of memory");
- return -1;
- }
- }
-
- len = riemann_message_get_packed_size(host->batch_msg);
- ret = 0;
- if ((host->batch_max < 0) || (((size_t) host->batch_max) <= len)) {
- ret = wrr_batch_flush_nolock(0, host);
- } else {
- if (host->batch_timeout > 0) {
- timeout = TIME_T_TO_CDTIME_T((time_t)host->batch_timeout);
- ret = wrr_batch_flush_nolock(timeout, host);
- }
+ data_set_t const *ds,
+ value_list_t const *vl, int *statuses) {
+ riemann_message_t *msg;
+ size_t len;
+ int ret;
+ cdtime_t timeout;
+
+ msg = wrr_value_list_to_message(host, ds, vl, statuses);
+ if (msg == NULL)
+ return -1;
+
+ pthread_mutex_lock(&host->lock);
+
+ if (host->batch_msg == NULL) {
+ host->batch_msg = msg;
+ } else {
+ int status;
+
+ status = riemann_message_append_events_n(host->batch_msg, msg->n_events,
+ msg->events);
+ msg->n_events = 0;
+ msg->events = NULL;
+
+ riemann_message_free(msg);
+
+ if (status != 0) {
+ pthread_mutex_unlock(&host->lock);
+ ERROR("write_riemann plugin: out of memory");
+ return -1;
}
+ }
- pthread_mutex_unlock(&host->lock);
- return ret;
+ len = riemann_message_get_packed_size(host->batch_msg);
+ ret = 0;
+ if ((host->batch_max < 0) || (((size_t)host->batch_max) <= len)) {
+ ret = wrr_batch_flush_nolock(0, host);
+ } else {
+ if (host->batch_timeout > 0) {
+ timeout = TIME_T_TO_CDTIME_T((time_t)host->batch_timeout);
+ ret = wrr_batch_flush_nolock(timeout, host);
+ }
+ }
+
+ pthread_mutex_unlock(&host->lock);
+ return ret;
} /* }}} riemann_message_t *wrr_batch_add_value_list */
static int wrr_notification(const notification_t *n, user_data_t *ud) /* {{{ */
{
- int status;
- struct riemann_host *host = ud->data;
- riemann_message_t *msg;
+ int status;
+ struct riemann_host *host = ud->data;
+ riemann_message_t *msg;
- if (!host->notifications)
- return 0;
+ if (!host->notifications)
+ return 0;
- /*
- * Never batch for notifications, send them ASAP
- */
- msg = wrr_notification_to_message(host, n);
- if (msg == NULL)
- return (-1);
-
- status = wrr_send(host, msg);
- if (status != 0)
- c_complain (LOG_ERR, &host->init_complaint,
- "write_riemann plugin: riemann_client_send failed with status %i",
- status);
- else
- c_release (LOG_DEBUG, &host->init_complaint,
- "write_riemann plugin: riemann_client_send succeeded");
+ /*
+ * Never batch for notifications, send them ASAP
+ */
+ msg = wrr_notification_to_message(host, n);
+ if (msg == NULL)
+ return (-1);
- riemann_message_free(msg);
- return (status);
+ status = wrr_send(host, msg);
+ if (status != 0)
+ c_complain(
+ LOG_ERR, &host->init_complaint,
+ "write_riemann plugin: riemann_client_send failed with status %i",
+ status);
+ else
+ c_release(LOG_DEBUG, &host->init_complaint,
+ "write_riemann plugin: riemann_client_send succeeded");
+
+ riemann_message_free(msg);
+ return (status);
} /* }}} int wrr_notification */
static int wrr_write(const data_set_t *ds, /* {{{ */
- const value_list_t *vl,
- user_data_t *ud)
-{
- int status = 0;
- int statuses[vl->values_len];
- struct riemann_host *host = ud->data;
- riemann_message_t *msg;
-
- if (host->check_thresholds) {
- status = write_riemann_threshold_check(ds, vl, statuses);
+ const value_list_t *vl, user_data_t *ud) {
+ int status = 0;
+ int statuses[vl->values_len];
+ struct riemann_host *host = ud->data;
+ riemann_message_t *msg;
+
+ if (host->check_thresholds) {
+ status = write_riemann_threshold_check(ds, vl, statuses);
if (status != 0)
return status;
} else {
- memset (statuses, 0, sizeof (statuses));
+ memset(statuses, 0, sizeof(statuses));
}
if (host->client_type != RIEMANN_CLIENT_UDP && host->batch_mode) {
- wrr_batch_add_value_list(host, ds, vl, statuses);
+ wrr_batch_add_value_list(host, ds, vl, statuses);
} else {
msg = wrr_value_list_to_message(host, ds, vl, statuses);
if (msg == NULL)
static void wrr_free(void *p) /* {{{ */
{
- struct riemann_host *host = p;
+ struct riemann_host *host = p;
if (host == NULL)
return;
pthread_mutex_lock(&host->lock);
host->reference_count--;
- if (host->reference_count > 0)
- {
- pthread_mutex_unlock(&host->lock);
- return;
- }
+ if (host->reference_count > 0) {
+ pthread_mutex_unlock(&host->lock);
+ return;
+ }
wrr_disconnect(host);
static int wrr_config_node(oconfig_item_t *ci) /* {{{ */
{
- struct riemann_host *host = NULL;
- int status = 0;
- int i;
- oconfig_item_t *child;
- char callback_name[DATA_MAX_NAME_LEN];
- user_data_t ud;
+ struct riemann_host *host = NULL;
+ int status = 0;
+ int i;
+ oconfig_item_t *child;
+ char callback_name[DATA_MAX_NAME_LEN];
if ((host = calloc(1, sizeof(*host))) == NULL) {
- ERROR ("write_riemann plugin: calloc failed.");
+ ERROR("write_riemann plugin: calloc failed.");
return ENOMEM;
}
pthread_mutex_init(&host->lock, NULL);
- C_COMPLAIN_INIT (&host->init_complaint);
+ C_COMPLAIN_INIT(&host->init_complaint);
host->reference_count = 1;
host->node = NULL;
host->port = 0;
if (status != 0)
break;
} else if (strcasecmp("Timeout", child->key) == 0) {
+#if RCC_VERSION_NUMBER >= 0x010800
status = cf_util_get_int(child, (int *)&host->timeout.tv_sec);
if (status != 0)
break;
+#else
+ WARNING("write_riemann plugin: The Timeout option is not supported. Please upgrade the Riemann client to at least 1.8.0.");
+#endif
} else if (strcasecmp("Port", child->key) == 0) {
host->port = cf_util_get_port_number(child);
if (host->port == -1) {
}
} else if (strcasecmp("Protocol", child->key) == 0) {
char tmp[16];
- status = cf_util_get_string_buffer(child,
- tmp, sizeof(tmp));
- if (status != 0)
- {
- ERROR("write_riemann plugin: cf_util_get_"
- "string_buffer failed with "
- "status %i.", status);
- break;
- }
+ status = cf_util_get_string_buffer(child, tmp, sizeof(tmp));
+ if (status != 0) {
+ ERROR("write_riemann plugin: cf_util_get_"
+ "string_buffer failed with "
+ "status %i.",
+ status);
+ break;
+ }
if (strcasecmp("UDP", tmp) == 0)
host->client_type = RIEMANN_CLIENT_UDP;
tmp);
} else if (strcasecmp("TLSCAFile", child->key) == 0) {
status = cf_util_get_string(child, &host->tls_ca_file);
- if (status != 0)
- {
- ERROR("write_riemann plugin: cf_util_get_"
- "string_buffer failed with "
- "status %i.", status);
- break;
- }
+ if (status != 0) {
+ ERROR("write_riemann plugin: cf_util_get_"
+ "string_buffer failed with "
+ "status %i.",
+ status);
+ break;
+ }
} else if (strcasecmp("TLSCertFile", child->key) == 0) {
status = cf_util_get_string(child, &host->tls_cert_file);
- if (status != 0)
- {
- ERROR("write_riemann plugin: cf_util_get_"
- "string_buffer failed with "
- "status %i.", status);
- break;
- }
+ if (status != 0) {
+ ERROR("write_riemann plugin: cf_util_get_"
+ "string_buffer failed with "
+ "status %i.",
+ status);
+ break;
+ }
} else if (strcasecmp("TLSKeyFile", child->key) == 0) {
status = cf_util_get_string(child, &host->tls_key_file);
- if (status != 0)
- {
- ERROR("write_riemann plugin: cf_util_get_"
- "string_buffer failed with "
- "status %i.", status);
- break;
- }
+ if (status != 0) {
+ ERROR("write_riemann plugin: cf_util_get_"
+ "string_buffer failed with "
+ "status %i.",
+ status);
+ break;
+ }
} else if (strcasecmp("StoreRates", child->key) == 0) {
status = cf_util_get_boolean(child, &host->store_rates);
if (status != 0)
break;
} else if (strcasecmp("AlwaysAppendDS", child->key) == 0) {
- status = cf_util_get_boolean(child,
- &host->always_append_ds);
+ status = cf_util_get_boolean(child, &host->always_append_ds);
if (status != 0)
break;
} else if (strcasecmp("TTLFactor", child->key) == 0) {
}
} else {
WARNING("write_riemann plugin: ignoring unknown config "
- "option: \"%s\"", child->key);
+ "option: \"%s\"",
+ child->key);
}
}
if (status != 0) {
ssnprintf(callback_name, sizeof(callback_name), "write_riemann/%s",
host->name);
- ud.data = host;
- ud.free_func = wrr_free;
+
+ user_data_t ud = {
+ .data = host,
+ .free_func = wrr_free
+ };
pthread_mutex_lock(&host->lock);
else /* success */
host->reference_count++;
- status = plugin_register_notification(callback_name,
- wrr_notification, &ud);
+ status = plugin_register_notification(callback_name, wrr_notification, &ud);
if (status != 0)
WARNING("write_riemann plugin: plugin_register_notification (\"%s\") "
"failed with status %i.",
else /* success */
host->reference_count++;
- if (host->reference_count <= 1)
- {
- /* Both callbacks failed => free memory.
- * We need to unlock here, because riemann_free() will lock.
- * This is not a race condition, because we're the only one
- * holding a reference. */
- pthread_mutex_unlock(&host->lock);
- wrr_free(host);
- return (-1);
- }
+ if (host->reference_count <= 1) {
+ /* Both callbacks failed => free memory.
+ * We need to unlock here, because riemann_free() will lock.
+ * This is not a race condition, because we're the only one
+ * holding a reference. */
+ pthread_mutex_unlock(&host->lock);
+ wrr_free(host);
+ return (-1);
+ }
host->reference_count--;
pthread_mutex_unlock(&host->lock);
static int wrr_config(oconfig_item_t *ci) /* {{{ */
{
- int i;
- oconfig_item_t *child;
- int status;
+ int i;
+ oconfig_item_t *child;
+ int status;
- for (i = 0; i < ci->children_num; i++) {
+ for (i = 0; i < ci->children_num; i++) {
child = &ci->children[i];
if (strcasecmp("Node", child->key) == 0) {
- wrr_config_node (child);
+ wrr_config_node(child);
} else if (strcasecmp(child->key, "attribute") == 0) {
char *key = NULL;
char *val = NULL;
return (0);
} /* }}} int wrr_config */
-void module_register(void)
-{
+void module_register(void) {
plugin_register_complex_config("write_riemann", wrr_config);
}
**/
#include "collectd.h"
+
#include "common.h"
#include "plugin.h"
#include "utils_avltree.h"
int *statuses)
{ /* {{{ */
int ret = -1;
- size_t i;
int status;
gauge_t values_copy[ds->ds_num];
}
/* Prepare `sum' and `num'. */
- for (i = 0; i < ds->ds_num; i++)
+ for (size_t i = 0; i < ds->ds_num; i++)
if (!isnan (values[i]))
{
num++;
if ((num == 0) /* All data sources are undefined. */
|| (sum == 0.0)) /* Sum is zero, cannot calculate percentage. */
{
- for (i = 0; i < ds->ds_num; i++)
+ for (size_t i = 0; i < ds->ds_num; i++)
values_copy[i] = NAN;
}
else /* We can actually calculate the percentage. */
{
- for (i = 0; i < ds->ds_num; i++)
+ for (size_t i = 0; i < ds->ds_num; i++)
values_copy[i] = 100.0 * values[i] / sum;
}
} /* if (UT_FLAG_PERCENTAGE) */
- for (i = 0; i < ds->ds_num; i++)
+ for (size_t i = 0; i < ds->ds_num; i++)
{
status = ut_check_one_data_source (ds, vl, th, values_copy, i);
if (status != -1) {
#define _GNU_SOURCE
#include "collectd.h"
+
#include "plugin.h"
#include "common.h"
-#include "configfile.h"
#include "utils_cache.h"
#include <arpa/inet.h>
#include <errno.h>
#define SENSU_HOST "localhost"
#define SENSU_PORT "3030"
+#ifdef HAVE_ASPRINTF
+#define my_asprintf asprintf
+#define my_vasprintf vasprintf
+#else
+/*
+ * asprintf() is available from Solaris 10 update 11.
+ * For older versions, use asprintf() portable implementation from
+ * https://github.com/littlstar/asprintf.c/blob/master/
+ * copyright (c) 2014 joseph werle <joseph.werle@gmail.com> under MIT license.
+ */
+
+static int my_vasprintf(char **str, const char *fmt, va_list args) {
+ int size = 0;
+ va_list tmpa;
+ // copy
+ va_copy(tmpa, args);
+ // apply variadic arguments to
+ // sprintf with format to get size
+ size = vsnprintf(NULL, size, fmt, tmpa);
+ // toss args
+ va_end(tmpa);
+ // return -1 to be compliant if
+ // size is less than 0
+ if (size < 0) { return -1; }
+ // alloc with size plus 1 for `\0'
+ *str = (char *) malloc(size + 1);
+ // return -1 to be compliant
+ // if pointer is `NULL'
+ if (NULL == *str) { return -1; }
+ // format string with original
+ // variadic arguments and set new size
+ size = vsprintf(*str, fmt, args);
+ return size;
+}
+
+static int my_asprintf(char **str, const char *fmt, ...) {
+ int size = 0;
+ va_list args;
+ // init variadic argumens
+ va_start(args, fmt);
+ // format and get size
+ size = my_vasprintf(str, fmt, args);
+ // toss args
+ va_end(args);
+ return size;
+}
+
+#endif
+
struct str_list {
int nb_strs;
char **strs;
static void free_str_list(struct str_list *strs) /* {{{ */
{
- int i;
- for (i=0; i<strs->nb_strs; i++)
+ for (int i=0; i<strs->nb_strs; i++)
free(strs->strs[i]);
free(strs->strs);
}
static int sensu_connect(struct sensu_host *host) /* {{{ */
{
int e;
- struct addrinfo *ai, hints;
char const *node;
char const *service;
// Resolve the target if we haven't done already
if (!(host->flags & F_READY)) {
- memset(&hints, 0, sizeof(hints));
memset(&service, 0, sizeof(service));
host->res = NULL;
- hints.ai_family = AF_INET;
- hints.ai_socktype = SOCK_STREAM;
-#ifdef AI_ADDRCONFIG
- hints.ai_flags |= AI_ADDRCONFIG;
-#endif
node = (host->node != NULL) ? host->node : SENSU_HOST;
service = (host->service != NULL) ? host->service : SENSU_PORT;
- if ((e = getaddrinfo(node, service, &hints, &(host->res))) != 0) {
+ struct addrinfo ai_hints = {
+ .ai_family = AF_INET,
+ .ai_flags = AI_ADDRCONFIG,
+ .ai_socktype = SOCK_STREAM
+ };
+
+ if ((e = getaddrinfo(node, service, &ai_hints, &(host->res))) != 0) {
ERROR("write_sensu plugin: Unable to resolve host \"%s\": %s",
node, gai_strerror(e));
return -1;
struct linger so_linger;
host->s = -1;
- for (ai = host->res; ai != NULL; ai = ai->ai_next) {
+ for (struct addrinfo *ai = host->res; ai != NULL; ai = ai->ai_next) {
// create the socket
if ((host->s = socket(ai->ai_family,
ai->ai_socktype,
if (setsockopt(host->s, SOL_SOCKET, SO_LINGER, &so_linger, sizeof so_linger) != 0)
WARNING("write_sensu plugin: failed to set socket close() lingering");
+ set_sock_opts(host->s);
+
// connect the socket
if (connect(host->s, ai->ai_addr, ai->ai_addrlen) != 0) {
close(host->s);
int res;
char *ret_str = NULL;
char *temp_str;
- int i;
if (list->nb_strs == 0) {
ret_str = malloc(sizeof(char));
if (ret_str == NULL) {
ret_str[0] = '\0';
}
- res = asprintf(&temp_str, "\"%s\": [\"%s\"", tag, list->strs[0]);
+ res = my_asprintf(&temp_str, "\"%s\": [\"%s\"", tag, list->strs[0]);
if (res == -1) {
ERROR("write_sensu plugin: Unable to alloc memory");
free(ret_str);
return NULL;
}
- for (i=1; i<list->nb_strs; i++) {
- res = asprintf(&ret_str, "%s, \"%s\"", temp_str, list->strs[i]);
+ for (int i=1; i<list->nb_strs; i++) {
+ res = my_asprintf(&ret_str, "%s, \"%s\"", temp_str, list->strs[i]);
free(temp_str);
if (res == -1) {
ERROR("write_sensu plugin: Unable to alloc memory");
}
temp_str = ret_str;
}
- res = asprintf(&ret_str, "%s]", temp_str);
+ res = my_asprintf(&ret_str, "%s]", temp_str);
free(temp_str);
if (res == -1) {
ERROR("write_sensu plugin: Unable to alloc memory");
static void in_place_replace_sensu_name_reserved(char *orig_name) /* {{{ */
{
- int i;
int len=strlen(orig_name);
- for (i=0; i<len; i++) {
+ for (int i=0; i<len; i++) {
// some plugins like ipmi generate special characters in metric name
switch(orig_name[i]) {
case '(': orig_name[i] = '_'; break;
{
char name_buffer[5 * DATA_MAX_NAME_LEN];
char service_buffer[6 * DATA_MAX_NAME_LEN];
- size_t i;
char *ret_str;
char *temp_str;
char *value_str;
}
}
else {
- res = asprintf(&ret_str, "%s, %s", part1, handlers_str);
+ res = my_asprintf(&ret_str, "%s, %s", part1, handlers_str);
free(handlers_str);
if (res == -1) {
ERROR("write_sensu plugin: Unable to alloc memory");
}
// incorporate the plugin name information
- res = asprintf(&temp_str, "%s, \"collectd_plugin\": \"%s\"", ret_str, vl->plugin);
+ res = my_asprintf(&temp_str, "%s, \"collectd_plugin\": \"%s\"", ret_str, vl->plugin);
free(ret_str);
if (res == -1) {
ERROR("write_sensu plugin: Unable to alloc memory");
ret_str = temp_str;
// incorporate the plugin type
- res = asprintf(&temp_str, "%s, \"collectd_plugin_type\": \"%s\"", ret_str, vl->type);
+ res = my_asprintf(&temp_str, "%s, \"collectd_plugin_type\": \"%s\"", ret_str, vl->type);
free(ret_str);
if (res == -1) {
ERROR("write_sensu plugin: Unable to alloc memory");
// incorporate the plugin instance if any
if (vl->plugin_instance[0] != 0) {
- res = asprintf(&temp_str, "%s, \"collectd_plugin_instance\": \"%s\"", ret_str, vl->plugin_instance);
+ res = my_asprintf(&temp_str, "%s, \"collectd_plugin_instance\": \"%s\"", ret_str, vl->plugin_instance);
free(ret_str);
if (res == -1) {
ERROR("write_sensu plugin: Unable to alloc memory");
// incorporate the plugin type instance if any
if (vl->type_instance[0] != 0) {
- res = asprintf(&temp_str, "%s, \"collectd_plugin_type_instance\": \"%s\"", ret_str, vl->type_instance);
+ res = my_asprintf(&temp_str, "%s, \"collectd_plugin_type_instance\": \"%s\"", ret_str, vl->type_instance);
free(ret_str);
if (res == -1) {
ERROR("write_sensu plugin: Unable to alloc memory");
if ((ds->ds[index].type != DS_TYPE_GAUGE) && (rates != NULL)) {
char ds_type[DATA_MAX_NAME_LEN];
ssnprintf (ds_type, sizeof (ds_type), "%s:rate", DS_TYPE_TO_STRING(ds->ds[index].type));
- res = asprintf(&temp_str, "%s, \"collectd_data_source_type\": \"%s\"", ret_str, ds_type);
+ res = my_asprintf(&temp_str, "%s, \"collectd_data_source_type\": \"%s\"", ret_str, ds_type);
free(ret_str);
if (res == -1) {
ERROR("write_sensu plugin: Unable to alloc memory");
}
ret_str = temp_str;
} else {
- res = asprintf(&temp_str, "%s, \"collectd_data_source_type\": \"%s\"", ret_str, DS_TYPE_TO_STRING(ds->ds[index].type));
+ res = my_asprintf(&temp_str, "%s, \"collectd_data_source_type\": \"%s\"", ret_str, DS_TYPE_TO_STRING(ds->ds[index].type));
free(ret_str);
if (res == -1) {
ERROR("write_sensu plugin: Unable to alloc memory");
}
// incorporate the data source name
- res = asprintf(&temp_str, "%s, \"collectd_data_source_name\": \"%s\"", ret_str, ds->ds[index].name);
+ res = my_asprintf(&temp_str, "%s, \"collectd_data_source_name\": \"%s\"", ret_str, ds->ds[index].name);
free(ret_str);
if (res == -1) {
ERROR("write_sensu plugin: Unable to alloc memory");
{
char ds_index[DATA_MAX_NAME_LEN];
ssnprintf (ds_index, sizeof (ds_index), "%zu", index);
- res = asprintf(&temp_str, "%s, \"collectd_data_source_index\": %s", ret_str, ds_index);
+ res = my_asprintf(&temp_str, "%s, \"collectd_data_source_index\": %s", ret_str, ds_index);
free(ret_str);
if (res == -1) {
ERROR("write_sensu plugin: Unable to alloc memory");
}
// add key value attributes from config if any
- for (i = 0; i < sensu_attrs_num; i += 2) {
- res = asprintf(&temp_str, "%s, \"%s\": \"%s\"", ret_str, sensu_attrs[i], sensu_attrs[i+1]);
+ for (size_t i = 0; i < sensu_attrs_num; i += 2) {
+ res = my_asprintf(&temp_str, "%s, \"%s\": \"%s\"", ret_str, sensu_attrs[i], sensu_attrs[i+1]);
free(ret_str);
if (res == -1) {
ERROR("write_sensu plugin: Unable to alloc memory");
// incorporate sensu tags from config if any
if ((sensu_tags != NULL) && (strlen(sensu_tags) != 0)) {
- res = asprintf(&temp_str, "%s, %s", ret_str, sensu_tags);
+ res = my_asprintf(&temp_str, "%s, %s", ret_str, sensu_tags);
free(ret_str);
if (res == -1) {
ERROR("write_sensu plugin: Unable to alloc memory");
// calculate the value and set to a string
if (ds->ds[index].type == DS_TYPE_GAUGE) {
- res = asprintf(&value_str, GAUGE_FORMAT, vl->values[index].gauge);
+ res = my_asprintf(&value_str, GAUGE_FORMAT, vl->values[index].gauge);
if (res == -1) {
free(ret_str);
ERROR("write_sensu plugin: Unable to alloc memory");
return NULL;
}
} else if (rates != NULL) {
- res = asprintf(&value_str, GAUGE_FORMAT, rates[index]);
+ res = my_asprintf(&value_str, GAUGE_FORMAT, rates[index]);
if (res == -1) {
free(ret_str);
ERROR("write_sensu plugin: Unable to alloc memory");
}
} else {
if (ds->ds[index].type == DS_TYPE_DERIVE) {
- res = asprintf(&value_str, "%"PRIi64, vl->values[index].derive);
+ res = my_asprintf(&value_str, "%"PRIi64, vl->values[index].derive);
if (res == -1) {
free(ret_str);
ERROR("write_sensu plugin: Unable to alloc memory");
}
}
else if (ds->ds[index].type == DS_TYPE_ABSOLUTE) {
- res = asprintf(&value_str, "%"PRIu64, vl->values[index].absolute);
+ res = my_asprintf(&value_str, "%"PRIu64, vl->values[index].absolute);
if (res == -1) {
free(ret_str);
ERROR("write_sensu plugin: Unable to alloc memory");
}
}
else {
- res = asprintf(&value_str, "%llu", vl->values[index].counter);
+ res = my_asprintf(&value_str, "%llu", vl->values[index].counter);
if (res == -1) {
free(ret_str);
ERROR("write_sensu plugin: Unable to alloc memory");
in_place_replace_sensu_name_reserved(service_buffer);
// finalize the buffer by setting the output and closing curly bracket
- res = asprintf(&temp_str, "%s, \"output\": \"%s %s %ld\"}\n", ret_str, service_buffer, value_str, CDTIME_T_TO_TIME_T(vl->time));
+ res = my_asprintf(&temp_str, "%s, \"output\": \"%s %s %lld\"}\n",ret_str, service_buffer, value_str, (long long)CDTIME_T_TO_TIME_T(vl->time));
free(ret_str);
free(value_str);
if (res == -1) {
{
char service_buffer[6 * DATA_MAX_NAME_LEN];
char const *severity;
- notification_meta_t *meta;
char *ret_str;
char *temp_str;
int status;
severity = "UNKNOWN";
status = 3;
}
- res = asprintf(&temp_str, "{\"status\": %d", status);
+ res = my_asprintf(&temp_str, "{\"status\": %d", status);
if (res == -1) {
ERROR("write_sensu plugin: Unable to alloc memory");
return NULL;
ret_str = temp_str;
// incorporate the timestamp
- res = asprintf(&temp_str, "%s, \"timestamp\": %ld", ret_str, CDTIME_T_TO_TIME_T(n->time));
+ res = my_asprintf(&temp_str, "%s, \"timestamp\": %lld", ret_str, (long long)CDTIME_T_TO_TIME_T(n->time));
free(ret_str);
if (res == -1) {
ERROR("write_sensu plugin: Unable to alloc memory");
}
// incorporate the handlers
if (strlen(handlers_str) != 0) {
- res = asprintf(&temp_str, "%s, %s", ret_str, handlers_str);
+ res = my_asprintf(&temp_str, "%s, %s", ret_str, handlers_str);
free(ret_str);
free(handlers_str);
if (res == -1) {
// incorporate the plugin name information if any
if (n->plugin[0] != 0) {
- res = asprintf(&temp_str, "%s, \"collectd_plugin\": \"%s\"", ret_str, n->plugin);
+ res = my_asprintf(&temp_str, "%s, \"collectd_plugin\": \"%s\"", ret_str, n->plugin);
free(ret_str);
if (res == -1) {
ERROR("write_sensu plugin: Unable to alloc memory");
// incorporate the plugin type if any
if (n->type[0] != 0) {
- res = asprintf(&temp_str, "%s, \"collectd_plugin_type\": \"%s\"", ret_str, n->type);
+ res = my_asprintf(&temp_str, "%s, \"collectd_plugin_type\": \"%s\"", ret_str, n->type);
free(ret_str);
if (res == -1) {
ERROR("write_sensu plugin: Unable to alloc memory");
// incorporate the plugin instance if any
if (n->plugin_instance[0] != 0) {
- res = asprintf(&temp_str, "%s, \"collectd_plugin_instance\": \"%s\"", ret_str, n->plugin_instance);
+ res = my_asprintf(&temp_str, "%s, \"collectd_plugin_instance\": \"%s\"", ret_str, n->plugin_instance);
free(ret_str);
if (res == -1) {
ERROR("write_sensu plugin: Unable to alloc memory");
// incorporate the plugin type instance if any
if (n->type_instance[0] != 0) {
- res = asprintf(&temp_str, "%s, \"collectd_plugin_type_instance\": \"%s\"", ret_str, n->type_instance);
+ res = my_asprintf(&temp_str, "%s, \"collectd_plugin_type_instance\": \"%s\"", ret_str, n->type_instance);
free(ret_str);
if (res == -1) {
ERROR("write_sensu plugin: Unable to alloc memory");
// add key value attributes from config if any
for (i = 0; i < sensu_attrs_num; i += 2) {
- res = asprintf(&temp_str, "%s, \"%s\": \"%s\"", ret_str, sensu_attrs[i], sensu_attrs[i+1]);
+ res = my_asprintf(&temp_str, "%s, \"%s\": \"%s\"", ret_str, sensu_attrs[i], sensu_attrs[i+1]);
free(ret_str);
if (res == -1) {
ERROR("write_sensu plugin: Unable to alloc memory");
// incorporate sensu tags from config if any
if ((sensu_tags != NULL) && (strlen(sensu_tags) != 0)) {
- res = asprintf(&temp_str, "%s, %s", ret_str, sensu_tags);
+ res = my_asprintf(&temp_str, "%s, %s", ret_str, sensu_tags);
free(ret_str);
if (res == -1) {
ERROR("write_sensu plugin: Unable to alloc memory");
n->type, n->type_instance, host->separator);
// replace sensu event name chars that are considered illegal
in_place_replace_sensu_name_reserved(service_buffer);
- res = asprintf(&temp_str, "%s, \"name\": \"%s\"", ret_str, &service_buffer[1]);
+ res = my_asprintf(&temp_str, "%s, \"name\": \"%s\"", ret_str, &service_buffer[1]);
free(ret_str);
if (res == -1) {
ERROR("write_sensu plugin: Unable to alloc memory");
free(ret_str);
return NULL;
}
- res = asprintf(&temp_str, "%s, \"output\": \"%s - %s\"", ret_str, severity, msg);
+ res = my_asprintf(&temp_str, "%s, \"output\": \"%s - %s\"", ret_str, severity, msg);
free(ret_str);
free(msg);
if (res == -1) {
}
// Pull in values from threshold and add extra attributes
- for (meta = n->meta; meta != NULL; meta = meta->next) {
+ for (notification_meta_t *meta = n->meta; meta != NULL; meta = meta->next) {
if (strcasecmp("CurrentValue", meta->name) == 0 && meta->type == NM_TYPE_DOUBLE) {
- res = asprintf(&temp_str, "%s, \"current_value\": \"%.8f\"", ret_str, meta->nm_value.nm_double);
+ res = my_asprintf(&temp_str, "%s, \"current_value\": \"%.8f\"", ret_str, meta->nm_value.nm_double);
free(ret_str);
if (res == -1) {
ERROR("write_sensu plugin: Unable to alloc memory");
ret_str = temp_str;
}
if (meta->type == NM_TYPE_STRING) {
- res = asprintf(&temp_str, "%s, \"%s\": \"%s\"", ret_str, meta->name, meta->nm_value.nm_string);
+ res = my_asprintf(&temp_str, "%s, \"%s\": \"%s\"", ret_str, meta->name, meta->nm_value.nm_string);
free(ret_str);
if (res == -1) {
ERROR("write_sensu plugin: Unable to alloc memory");
}
// close the curly bracket
- res = asprintf(&temp_str, "%s}\n", ret_str);
+ res = my_asprintf(&temp_str, "%s}\n", ret_str);
free(ret_str);
if (res == -1) {
ERROR("write_sensu plugin: Unable to alloc memory");
int statuses[vl->values_len];
struct sensu_host *host = ud->data;
gauge_t *rates = NULL;
- size_t i;
char *msg;
pthread_mutex_lock(&host->lock);
return -1;
}
}
- for (i = 0; i < vl->values_len; i++) {
+ for (size_t i = 0; i < vl->values_len; i++) {
msg = sensu_value_to_json(host, ds, vl, (int) i, rates, statuses[i]);
if (msg == NULL) {
sfree(rates);
{
struct sensu_host *host = NULL;
int status = 0;
- int i;
oconfig_item_t *child;
char callback_name[DATA_MAX_NAME_LEN];
- user_data_t ud;
if ((host = calloc(1, sizeof(*host))) == NULL) {
ERROR("write_sensu plugin: calloc failed.");
return -1;
}
- for (i = 0; i < ci->children_num; i++) {
+ for (int i = 0; i < ci->children_num; i++) {
child = &ci->children[i];
status = 0;
}
ssnprintf(callback_name, sizeof(callback_name), "write_sensu/%s", host->name);
- ud.data = host;
- ud.free_func = sensu_free;
+
+ user_data_t ud = {
+ .data = host,
+ .free_func = sensu_free
+ };
pthread_mutex_lock(&host->lock);
static int sensu_config(oconfig_item_t *ci) /* {{{ */
{
- int i;
oconfig_item_t *child;
int status;
struct str_list sensu_tags_arr;
sensu_tags_arr.nb_strs = 0;
sensu_tags_arr.strs = NULL;
- for (i = 0; i < ci->children_num; i++) {
+ for (int i = 0; i < ci->children_num; i++) {
child = &ci->children[i];
if (strcasecmp("Node", child->key) == 0) {
*/
#include "collectd.h"
+
#include "common.h"
#include "plugin.h"
-#include "configfile.h"
#include "utils_cache.h"
static int wt_callback_init(struct wt_callback *cb)
{
- struct addrinfo ai_hints;
struct addrinfo *ai_list;
- struct addrinfo *ai_ptr;
int status;
const char *node = cb->node ? cb->node : WT_DEFAULT_NODE;
if (cb->sock_fd > 0)
return 0;
- memset(&ai_hints, 0, sizeof(ai_hints));
-#ifdef AI_ADDRCONFIG
- ai_hints.ai_flags |= AI_ADDRCONFIG;
-#endif
- ai_hints.ai_family = AF_UNSPEC;
- ai_hints.ai_socktype = SOCK_STREAM;
-
- ai_list = NULL;
+ struct addrinfo ai_hints = {
+ .ai_family = AF_UNSPEC,
+ .ai_flags = AI_ADDRCONFIG,
+ .ai_socktype = SOCK_STREAM
+ };
status = getaddrinfo(node, service, &ai_hints, &ai_list);
if (status != 0)
}
assert (ai_list != NULL);
- for (ai_ptr = ai_list; ai_ptr != NULL; ai_ptr = ai_ptr->ai_next)
+ for (struct addrinfo *ai_ptr = ai_list; ai_ptr != NULL; ai_ptr = ai_ptr->ai_next)
{
cb->sock_fd = socket(ai_ptr->ai_family, ai_ptr->ai_socktype,
ai_ptr->ai_protocol);
if (cb->sock_fd < 0)
continue;
+ set_sock_opts(cb->sock_fd);
+
status = connect(cb->sock_fd, ai_ptr->ai_addr, ai_ptr->ai_addrlen);
if (status != 0)
{
char values[512];
int status;
- size_t i;
if (0 != strcmp(ds->type, vl->type))
{
return -1;
}
- for (i = 0; i < ds->ds_num; i++)
+ for (size_t i = 0; i < ds->ds_num; i++)
{
const char *ds_name = NULL;
static int wt_config_tsd(oconfig_item_t *ci)
{
struct wt_callback *cb;
- user_data_t user_data;
char callback_name[DATA_MAX_NAME_LEN];
- int i;
cb = calloc(1, sizeof(*cb));
if (cb == NULL)
pthread_mutex_init (&cb->send_lock, 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;
cb->node != NULL ? cb->node : WT_DEFAULT_NODE,
cb->service != NULL ? cb->service : WT_DEFAULT_SERVICE);
- memset(&user_data, 0, sizeof(user_data));
- user_data.data = cb;
- user_data.free_func = wt_callback_free;
+ user_data_t user_data = {
+ .data = cb,
+ .free_func = wt_callback_free
+ };
+
plugin_register_write(callback_name, wt_write, &user_data);
user_data.free_func = NULL;
static int wt_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;
**/
#include "collectd.h"
+
#include "common.h"
#include "plugin.h"
{
ERROR ("xencpu: xc_interface_open() failed");
return (-1);
- };
+ }
xc_physinfo_t *physinfo;
xc_interface_close(xc_handle);
free(physinfo);
return (-1);
- };
+ }
num_cpus = physinfo->nr_cpus;
free(physinfo);
return 0;
} /* static int xencpu_shutdown */
-static void submit_value (int cpu_num, gauge_t percent)
+static void submit_value (int cpu_num, gauge_t value)
{
- value_t values[1];
value_list_t vl = VALUE_LIST_INIT;
- values[0].gauge = percent;
-
- vl.values = values;
+ vl.values = &(value_t) { .gauge = value };
vl.values_len = 1;
sstrncpy (vl.host, hostname_g, sizeof (vl.host));
return (-1);
}
- int cpu, status;
- for (cpu = 0; cpu < nr_cpus; cpu++) {
+ int status;
+ for (int cpu = 0; cpu < nr_cpus; cpu++) {
gauge_t rate = NAN;
- value_t value = {.derive = cpu_info[cpu].idletime};
- status = value_to_rate (&rate, value, DS_TYPE_DERIVE, now, &cpu_states[cpu]);
+ status = value_to_rate (&rate,
+ (value_t) { .derive = cpu_info[cpu].idletime }, DS_TYPE_DERIVE,
+ now, &cpu_states[cpu]);
if (status == 0) {
submit_value(cpu, 100 - rate/10000000);
}
**/
#include "collectd.h"
+
#include "plugin.h"
#include "common.h"
static void cxmms_submit (const char *type, 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, "xmms", sizeof (vl.plugin));
**/
#include "collectd.h"
+
#include "common.h"
#include "plugin.h"
static void free_zfs_values (kstat_t *ksp)
{
- llentry_t *e;
-
if (ksp == NULL)
return;
- for (e = llist_head (ksp); e != NULL; e = e->next)
+ for (llentry_t *e = llist_head (ksp); e != NULL; e = e->next)
{
sfree (e->key);
sfree (e->value);
}
#endif
-static void za_submit (const char* type, const char* type_instance, value_t* values, int values_len)
+static void za_submit (const char* type, const char* type_instance, value_t* values, size_t values_len)
{
value_list_t vl = VALUE_LIST_INIT;
static void za_submit_gauge (const char* type, const char* type_instance, gauge_t value)
{
- value_t vv;
-
- vv.gauge = value;
- za_submit (type, type_instance, &vv, 1);
+ za_submit (type, type_instance, &(value_t) { .gauge = value }, 1);
}
static int za_read_derive (kstat_t *ksp, const char *kstat_value,
const char *type, const char *type_instance)
{
- long long tmp;
- value_t v;
-
- tmp = get_zfs_value (ksp, (char *)kstat_value);
+ long long tmp = get_zfs_value (ksp, (char *)kstat_value);
if (tmp == -1LL)
{
WARNING ("zfs_arc plugin: Reading kstat value \"%s\" failed.", kstat_value);
return (-1);
}
- v.derive = (derive_t) tmp;
- za_submit (type, type_instance, /* values = */ &v, /* values_num = */ 1);
+ za_submit (type, type_instance, &(value_t) { .derive = (derive_t) tmp }, /* values_num = */ 1);
return (0);
}
static int za_read_gauge (kstat_t *ksp, const char *kstat_value,
const char *type, const char *type_instance)
{
- long long tmp;
- value_t v;
-
- tmp = get_zfs_value (ksp, (char *)kstat_value);
+ long long tmp = get_zfs_value (ksp, (char *)kstat_value);
if (tmp == -1LL)
{
WARNING ("zfs_arc plugin: Reading kstat value \"%s\" failed.", kstat_value);
return (-1);
}
- v.gauge = (gauge_t) tmp;
- za_submit (type, type_instance, /* values = */ &v, /* values_num = */ 1);
+ za_submit (type, type_instance, &(value_t) { .gauge = (gauge_t) tmp }, /* values_num = */ 1);
return (0);
}
static int za_read (void)
{
gauge_t arc_hits, arc_misses, l2_hits, l2_misses;
- value_t l2_io[2];
kstat_t *ksp = NULL;
#if defined(KERNEL_LINUX)
za_read_derive (ksp, "deleted", "cache_operation", "deleted");
#if defined(KERNEL_FREEBSD)
za_read_derive (ksp, "allocated","cache_operation", "allocated");
-#if __FreeBSD_version < 1002501
- /* stolen removed from sysctl kstat.zfs.misc.arcstats on FreeBSD 10.2+ */
- za_read_derive (ksp, "stolen", "cache_operation", "stolen");
-#endif
#endif
/* Issue indicators */
za_submit_ratio ("L2", l2_hits, l2_misses);
/* I/O */
- l2_io[0].derive = get_zfs_value(ksp, "l2_read_bytes");
- l2_io[1].derive = get_zfs_value(ksp, "l2_write_bytes");
-
- za_submit ("io_octets", "L2", l2_io, /* num values = */ 2);
+ value_t l2_io[] = {
+ { .derive = (derive_t) get_zfs_value(ksp, "l2_read_bytes") },
+ { .derive = (derive_t) get_zfs_value(ksp, "l2_write_bytes") },
+ };
+ za_submit ("io_octets", "L2", l2_io, STATIC_ARRAY_SIZE (l2_io));
#if defined(KERNEL_LINUX)
free_zfs_values (ksp);
#endif
#include "collectd.h"
+
#include "common.h"
#include "plugin.h"
while (c_avl_pick (tree, (void **)&zoneid, (void **)&stats) == 0)
{
if (getzonenamebyid(*zoneid, zonename, sizeof( zonename )) == -1) {
- WARNING("zone plugin: error retreiving zonename");
+ WARNING("zone plugin: error retrieving zonename");
} else {
zone_submit_value(zonename, (gauge_t)FRC2PCT(stats->pctcpu));
}
**/
#include "collectd.h"
+
#include "common.h"
#include "plugin.h"
return 0;
}
-static void zookeeper_submit_gauge (const char * type, const char * type_inst, gauge_t val)
+static void zookeeper_submit_gauge (const char * type, const char * type_inst, gauge_t value)
{
- value_t values[1];
value_list_t vl = VALUE_LIST_INIT;
- values[0].gauge = val;
-
- vl.values = values;
+ vl.values = &(value_t) { .gauge = value };
vl.values_len = 1;
sstrncpy (vl.host, hostname_g, sizeof (vl.host));
sstrncpy (vl.plugin, "zookeeper", sizeof (vl.plugin));
plugin_dispatch_values (&vl);
} /* zookeeper_submit_gauge */
-static void zookeeper_submit_derive (const char * type, const char * type_inst, derive_t val)
+static void zookeeper_submit_derive (const char * type, const char * type_inst, derive_t value)
{
- value_t values[1];
value_list_t vl = VALUE_LIST_INIT;
- values[0].derive = val;
-
- vl.values = values;
+ vl.values = &(value_t) { .derive = value };
vl.values_len = 1;
sstrncpy (vl.host, hostname_g, sizeof (vl.host));
sstrncpy (vl.plugin, "zookeeper", sizeof (vl.plugin));
{
int sk = -1;
int status;
- struct addrinfo ai_hints;
- struct addrinfo *ai;
struct addrinfo *ai_list;
const char *host;
const char *port;
- memset (&ai_hints, '\0', sizeof (ai_hints));
- ai_hints.ai_family = AF_UNSPEC;
- ai_hints.ai_socktype = SOCK_STREAM;
-
host = (zk_host != NULL) ? zk_host : ZOOKEEPER_DEF_HOST;
port = (zk_port != NULL) ? zk_port : ZOOKEEPER_DEF_PORT;
+
+ struct addrinfo ai_hints = {
+ .ai_family = AF_UNSPEC,
+ .ai_socktype = SOCK_STREAM
+ };
+
status = getaddrinfo (host, port, &ai_hints, &ai_list);
if (status != 0)
{
return (-1);
}
- for (ai = ai_list; ai != NULL; ai = ai->ai_next)
+ for (struct addrinfo *ai = ai_list; ai != NULL; ai = ai->ai_next)
{
sk = socket (ai->ai_family, SOCK_STREAM, 0);
if (sk < 0)
#!/bin/sh
-DEFAULT_VERSION="5.5.2.git"
+DEFAULT_VERSION="5.6.0.git"
if [ -d .git ]; then
VERSION="`git describe --dirty=+ --abbrev=7 2> /dev/null | grep collectd | sed -e 's/^collectd-//' -e 's/-/./g'`"