Expose meta_data_toc function in utils_cache.
matrix:
include:
- os: osx
- osx_image: xcode10.1
+ osx_image: xcode11.2
compiler: clang
+ jdk: openjdk10
env:
- CXX=clang++
- PATH="/usr/local/opt/mysql-client/bin:$PATH"
+ - JAVA_HOME="/Library/Java/JavaVirtualMachines/openjdk-13.jdk/Contents/Home"
- os: linux
dist: xenial
compiler: clang
+ jdk: openjdk10
- os: linux
dist: xenial
compiler: gcc
+ jdk: openjdk10
before_install:
# When building the coverity_scan branch, allow only the first job to continue to avoid travis-ci/travis-ci#1975.
script:
- if [[ "${TRAVIS_BRANCH}" == "coverity_scan" ]]; then exit 0; fi
+ - type pkg-config
+ - pkg-config --list-all | sort -u
- ./configure
+ - cat config.log
- make distcheck DISTCHECK_CONFIGURE_FLAGS="--disable-dependency-tracking --enable-debug"
addons:
- liblua50-dev
- liblua5.1-0-dev
- liblua5.2-dev
- - liblvm2-dev
- libmemcached-dev
- libmicrohttpd-dev
- libmnl-dev
- libsensors4-dev
- libsigrok-dev
- libsnmp-dev
- - libstatgrab-dev
- libtokyocabinet-dev
- libtokyotyrant-dev
- libudev-dev
- liboping
- libpcap
- librdkafka
- - libstatgrab
- libvirt
+ - libxml2
- lua
+ - mongo-c-driver
- mosquitto
- mysql-client
- net-snmp
Andreas Henriksson <andreas at fatal.se>
- libmnl support in the netlink plugin.
+Andrew Bays <abays at redhat.com>
+ - connectivity plugin.
+ - procevent plugin.
+ - sysevent plugin.
+ - connectivity plugin.
+
Andy Parkins <andyp at fussylogic.co.uk>
- battery plugin: sysfs code.
+Aneesh Puttur <aputtur at redhat.com>
+ - connectivity plugin.
+
Andy Smith <ansmith at redhat.com>
- AMQP 1.0 plugin.
+
+Aneesh Puttur <aputtur at redhat.com>
+ - connectivity plugin.
Anthony Dewhurst <dewhurst at gmail.com>
- zfs_arc plugin.
# These owners will be the default owners for everything in the repo. Unless a
# later match takes precedence, # @trusted-contributors will be requested for
# review when someone opens a pull request.
-* @trusted-contributors
/src/intel_pmu.c @kwiatrox @sunkuranganath
/src/intel_rdt.c @kwiatrox @sunkuranganath
/src/virt.c @anaudx @rjablonx
# TODO(#2926): Add the following owners:
#/src/redfish.c @kkepka @mkobyli
+
+# Order is important; the last matching pattern takes the most
+# precedence.
+* @trusted-contributors
+2019-10-01, Version 5.9.2
+ * syslog plugin: Don't fail if syslog loglevel doesn't match. Thanks to
+ Fabien Wernli. #3236 #3238
+ * collectd: Fix ssnprintf wrapper. Thanks to Fabien Wernli. #3237
+ * rdt plugin: Fix compile time issues. Thanks to Matthias Runge. #3245
+
+2019-07-24, Version 5.9.1
+ * collectd: redhat spec: fix build due to new upstream plugins. Thanks
+ to Fabien Wernli. #3175
+ * collectd: regex match: Fix unexpected match with empty meta data .
+ Thanks to Takuro Ashie. #3178
+ * collectd: Fix return value or loglevel for several plugins. Thanks to
+ Fabien Wernli. #3182
+ * collectd: Add standard include early or _FILE_OFFSET_BITS will have
+ definition … . Thanks to Dagobert Michelsen. #3193
+ * collectd: Use GCC-specific flags only when compiling with GCC. Thanks
+ to Dagobert Michelsen. #3195
+ * Use test_utils_proc_pids only when compiling the plugin that uses it.
+ Thanks to Dagobert Michelsen. #3197
+ * DNS plugin: Do not use headers from glibc. Thanks to Pavel Rochnyak.
+ #3156, #3145
+ * collectd: Add missing definitions for libnetsnmpagent. Thanks to
+ Dagobert Michelsen. #3203
+ * collectd: Move Makefile rules for pid_test inside conditional for
+ code. Thanks to Dagobert Michelsen. #3206
+ * collectd: Recover setlocale() call in src/daemon/collectd.c do_init().
+ Thanks to Pavel Rochnyak. #3214, #3181
+ * collectd: Add snprintf wrapper for GCC 8.2/3. Thanks to zebity. #3153,
+ #2895, #3038
+ * collectd: Fix bug that leads to CPPFLAGS gets overridden with CFLAGS
+ when libxmms is enabled. Thanks to Dagobert Michelsen. #3207
+ * Write_Riemann plugin: Copy MetaData to Riemann events in
+ write_riemann. Thanks to Romain Tartière. #3158
+ * virt plugin: Fix memory leak with libvirt MetadataXPath enabled.
+ Thanks to Pavel Rochnyak. #3225, #3230
+
+2019-06-13, Version 5.9.0
+ * Build System: configure.ac: option "--with-libxml2" has been added.
+ Thanks to Dimitrios Apostolou, Pavel Rochnyak. #2864
+ * Build System: configure.ac: run dpdk build tests only if pkgconfig
+ fails. Thanks to Luca Boccassi, Pavel Rochnyak. #3015
+ * Build System: The "df" plugin is now built when "getmntent_r()" is
+ available. Thanks to Florian Forster. #3095
+ * Build System: The ability to turn on collectd "debug" feature in RPMs
+ has been added. Thanks to dehotot. #2755
+ * collectd: A new "UNKNOWN" state as the initial state of metrics has
+ been added. Thanks to Luis Fernández Álvarez, Florian Forster. #2976
+ * collectd: Base port to Windows. Thanks to Sean Campbell. #2810
+ * collectd: Code ownership of five plugins has been handed out to folks
+ from Intel. Thanks to Florian Forster. #3053
+ * collectd: config parser: Improved error reporting on global options.
+ Thanks to Pavel Rochnyak. #2813
+ * collectd: daemon: make plugin_dispatch_multivalue() obey write queue
+ limits. Thanks to Adam Romanek. #2898
+ * collectd: Macros "STRERROR" and "STRERRNO" have been added. Thanks to
+ Florian Forster. #2519
+ * collectd: Plugin name field has been added to plugin context to
+ improve error reporting. Thanks to Pavel Rochnyak. #2821
+ * collectd-tg: Use "CLOCK_REALTIME" for collectd-tg times. Thanks to
+ Andrew Bays. #2837
+ * tree-wide: Don't initialize static pointers to NULL, use "bool" from
+ "stdbool.h" (instead of "_Bool"). Thanks to Ruben Kerkhof. #2771,
+ #2772
+ * tree-wide: Replace zu with "PRIsz" and llu with "PRIu64". Thanks to
+ Sean Campbell. #2512
+ * tree-wide: Use interval value from plugin context, do not set
+ "vl->interval" in plugins more. Thanks to Pavel Rochnyak. #2847
+ * tree-wide: Utilities and libraries have been moved to "src/utils/".
+ Thanks to Florian Forster. #2961
+ * AMPQ1 plugin: A new plugin to write to amqp1 protocol. Thanks to Andy
+ Smith. #2618
+ * Chrony plugin: Ignoring late responses has been added. Thanks to
+ Miroslav Lichvar, Pavel Rochnyak. #2896
+ * CPUFreq plugin: Read number of p-state transitions and time spent in
+ each p-state. Thanks to Sexton Rory. #2803
+ * cURL, cURL-XML plugins: Option "Interval" has been added. Thanks to
+ Pavel Rochnyak. #2847
+ * Disk plugin: Report number of in progress disk IO requests on FreeBSD.
+ Thanks to Nathan Huff. #2878
+ * Exec plugin: Dynamic allocation of grname buffer has been added.
+ Thanks to sreedi, Florian Forster. #2937
+ * GPU NVML plugin: New plugin to collect NVIDIA GPU stats. Thanks to
+ Evgeny Naumov. #2923
+ * gRPC plugin: The "VerifyPeer" option for servers has been added.
+ Thanks to Florian Forster. #2593
+ * Intel RDT plugin: Support for groups of PIDs has been added. Thanks to
+ Wojciech Andralojc, Mateusz Starzyk, Michal Aleksinski. #2891
+ * IPMI plugin: Config options "SELSensor" and "SELIgnoreSelected" have
+ been added. Thanks to Mariusz Szafranski. #2796
+ * Modbus plugin: Support for 64 bit vals has been added, support for
+ CDAB endian 32-bit modbus polls has been added. Thanks to Anthony
+ Vickers, PJ Bostley. #2670, #2660
+ * Modbus plugin: The "Scale" and "Shift" metrics have been added. Thanks
+ to cekstam. #2729
+ * Netlink plugin: Handle new counter from Linux kernel version 4.6+.
+ Thanks to Pavel Rochnyak. #2767
+ * Network plugin: Option "BindAddress" has been added. Thanks to Ofir
+ Hermesh. #2831
+ * Ping plugin: An "AddressFamily" configuration option has been added.
+ Thanks to 依云 lilydjwg. #2961
+ * OVS Stats plugin: Extended metrics "ovs-dpdk" have been added. Thanks
+ to Matteo Croce, Ryan McCabe. #3000
+ * OVS Stats plugin: Support of bond interface and a "InterfaceStats"
+ config option have been added. Thanks to Andrew Bays. #2880
+ * PCIe Errors plugin: New plugin to read "PCIe" errors. Thanks to Kamil
+ Wiatrowski. #2733
+ * Processes plugin: Support for Linux Delay Accounting has been added.
+ Thanks to Florian Forster. #2598
+ * Redis plugin: Keyspace "hitratio" metric has been added, metric
+ "operations_per_second" has been removed, an option for connecting via
+ UNIX socket has been added. Thanks to Pavel Rochnyak. #2838, #2845,
+ #2904
+ * RouterOS plugin: Support for temperature and voltage data has been
+ added, use MAC-address when Radio-name is missing. Thanks to Pavel
+ Rochnyak. #2851, #2854
+ * RRDCacheD plugin: Time resolution has been improved to microseconds.
+ Thanks to Brian T. O'Neill. #3065
+ * Sensors plugin: Checks for upper limit of "SENSORS_API_VERSION" have
+ been removed, support for libsensors older than 3.0.0 has been
+ dropped. Thanks to Pavel Rochnyak. #3013, #3014
+ * SNMP plugin: New options "PluginInstance", "TypeInstance",
+ "TypeInstanceOID", "PluginInstanceOID", "FilterOID", "FilterValues"
+ and "FilterIgnoreSelected" have been added. Thanks to Pavel Rochnyak.
+ #2817, #2819
+ * SNMP Agent plugin: Multiple key indexes to snmp table and other new
+ features have been added, refactoring, coverity scan issues have been
+ fixed. Thanks to Marcin Mozejko. #2702, #2844
+ * Swap plugin: Support for Linux 2.4 has been dropped. Thanks to Pavel
+ Rochnyak. #2979
+ * Turbostat plugin: Configuration option "RestoreAffinityPolicy" has
+ been added. Thanks to Pablo Llopis. #2627
+ * Turbostat plugin: New metrics "P-states", "Turboboost", "Platform
+ TDP", "Uncore bus ratio" have been added. Thanks to Sexton Rory. #2806
+ * Turbostat plugin: Support of reporting GPU power on SKL has been
+ added. Thanks to Gordon Kelly. #2605
+ * virt plugin: Allow read "Hostname" from libvirt metadata. Thanks to
+ Mehdi ABAAKOUK. #2807
+ * virt plugin: Block info statistics for disk devices have been added.
+ Thanks to Radoslaw Jablonski. #2874
+ * Wireless plugin: A "bitrate" metric has been added. Thanks to Florian
+ Forster. #2950
+ * Write Graphite, Write Kafka plugins: Support for Graphite 1.1+ tag has
+ been added. Thanks to Dan Cech. #2631
+ * Write Prometheus plugin: Option "Host" has been added. Thanks to Pavel
+ Rochnyak. #2969
+ * Write Stackdriver plugin: New plugin to write to Google Stackdriver
+ Monitoring. Thanks to Florian Forster. #2472
+ * Write Syslog plugin: "write_syslog" plugin writes values lists as
+ syslog messages. Thanks to Shirly Radco. #3019
+ * Build System: A warning that pkgdatadir and pkglibdir were previously
+ defined has been fixed, additional plugins have been enabled,
+ GNULIB_DIR has been added to LDFLAGS in configure.ac on Windows.
+ Thanks to Sean Campbell. #2907, #2885, #2882
+ * Build System: Including "utils/mount/mount.h" has been fixed. Thanks
+ to Florian Forster. #3097
+ * Build System: The amount of output from ./configure has been reduced,
+ rendering of collectd-lua(5) manpage has been fixed, don't hide errors
+ when creating manpage. Thanks to Ruben Kerkhof. #3086, #3088, #3092
+ * collectd: A bug in "c_avl_iterator_prev" has been fixed. Thanks to
+ volth. #2917
+ * collectd: A stringop compiler warning has been fixed. Thanks to Ruben
+ Kerkhof, Juan Osorio Robles. #3021
+ * collectd: An invalid memory access in the "strjoin()" function has
+ been fixed. Thanks to Florian Forster. #3063
+ * collectd: collectd binary has been refactored. Thanks to Sean
+ Campbell, Sebastian Harl. #2745
+ * collectd: collectdmon cannot exit command line options parse loop has
+ been fixed. Thanks to takahashi-tsc. #2774
+ * collectd: Endianness checks for AIX have been added, gcc issue on Mac
+ byteorder has been fixed, fallback for endianness conversion has been
+ added. Thanks to Dagobert Michelsen. #2761, #2741, #2717
+ * collectd: Handle failure of simple config callbacks. Thanks to Ruben
+ Kerkhof. #3085
+ * collectd: Include "kstat.h" if available to provide "kstat_ctl_t",
+ include "kstat.h" when available. Thanks to Dagobert Michelsen. #2716,
+ #2711
+ * collectd: Parsing option for avoiding making BaseDir has been fixed.
+ Thanks to Mariusz Białończyk. #2856
+ * collectd: Remove empty "cmd_listval_t" data structure and related
+ no-op code. Thanks to Pavel Rochnyak. #2779
+ * collectd: src/daemon/plugin.c: Refactor plugin_load_file(),
+ src/utils_format_json.c: Remove chatty debug messages. Thanks to
+ Florian Forster. #2558, #2938
+ * collectd: Stop poisoning function in debug mode. Thanks to Ruben
+ Kerkhof. #2804
+ * collectd: The number of allocations when parsing types.db has been
+ reduced. Thanks to Ruben Kerkhof. #3091
+ * collectd: The organization of the source repository has been improved.
+ Thanks to Florian Forster. #2961
+ * collectd: Typos have been fixed. Thanks to Florian Forster, Jakub
+ Jankowski, William Pursell. #2944, #2692, #2643
+ * tree-wide: cleanup: cf_util_get* instead of local copy in plugins,
+ prefixed error reporting. Thanks to Pavel Rochnyak. #2833
+ * tree-wide: Some style issues have been fixed. Thanks to Ruben Kerkhof.
+ #3022
+ * tree-wide: "sstrerror()" has been replaced with "STRERRNO". Thanks to
+ Pavel Rochnyak. #2735
+ * AMQP1 plugin: Potential memory leaks found via scan-build have been
+ fixed, a typo in error log message has been fixed, cleanups. Thanks to
+ Andy Smith, Andrew Bays, Ruben Kerkhof. #2802, #2876, #2797
+ * Barometer plugin: Support to "libi2c-4.0" has been added. Thanks to
+ Pavel Rochnyak. #2783
+ * DBI, Oracle, PostgreSQL plugins: Fixes and improvements. Thanks to
+ Pavel Rochnyak. #1705
+ * Disk plugin: "HAVE_UDEV_H" has been changed to "HAVE_LIBUDEV_H".
+ Thanks to Dylan Stephano-Shachter. #2668
+ * Disk plugin: In linux, reset the disk when it disappears from
+ "/proc/diskstats". Thanks to Nikita Kozlov, Pavel Rochnyak. #2551
+ * DPDK Events, DPDK Stats plugins: Buffer size for parsing lcores has
+ been increased, a deprecation warning has been fixed, runtime config
+ file path has been fixed. Thanks to Kevin Laatz. #2722, #2840, #2924
+ * DPDK Stats plugin: A compilation issue has been fixed. Thanks to
+ Volodymyr Mytnyk. #2524
+ * GPS plugin: Build with gpsd version 3.18 has been fixed. Thanks to
+ Baruch Siach. #2947
+ * Intel RDT plugin: Compiler warnings have been fixed. Thanks to Ruben
+ Kerkhof. #3104
+ * Log Logstash plugin: Non-portable struct initialization with "{}" has
+ been fixed. Thanks to Florian Forster. #2988
+ * LUA plugin: A memory leak has been fixed. Thanks to Ruben Kerkhof.
+ #3090
+ * MySQL plugin: Properly cleanup dropped MySQL connections. Thanks to
+ Dhrupad Bhardwaj. #2704
+ * Netlink plugin: Truncation warnings have been fixed. Thanks to Ruben
+ Kerkhof. #2777
+ * NFS plugin: Message "Unexpected number of fields for NFSv4 server
+ statistics: 62" has been fixed. Thanks to Yedidyah Bar David. #2076
+ * NFS plugin: Number of fields for "NFSv4" has been fixed. Thanks to
+ Jan-Philipp Litza. #2915
+ * Notify Email plugin: All notification parameters have been included
+ into email. Thanks to Pavel Rochnyak. #2834
+ * NTPd plugin: Don't treat normal peers as refclocks, skip "0.0.0.0"
+ hosts in ntpd plugin. Thanks to Pavel Rochnyak, Ivan Kurnosov. #2822,
+ #2376
+ * OAuth plugin: src/utils_oauth.c: Renew OAuth tokens 30 seconds before
+ they expire. Thanks to Florian Forster. #2970
+ * OVS Stats plugin: A macro to populate counters list has been added,
+ value of "OpenFlow" has been corrected. Thanks to Matteo Croce. #2966,
+ #2963
+ * OVS Stats plugin: Code style, cleanup and improvements. Thanks to
+ Pavel Rochnyak. #3011, #3012
+ * OVS Stats, OVS Events plugins: utils_ovs: Avoid potential access of
+ freed memory, fixes. Thanks to Ciara Loftus, Mark Kavanagh. #2801,
+ #2731
+ * Processes plugin: Compilation has been fixed when ps_delay() is not
+ used. Thanks to Pavel Rochnyak. #2610
+ * Python plugin: A compilation warning with Python 3.7 has been fixed.
+ Thanks to Manoj Srivastava. #3042
+ * Redis plugin: Bugfixes, extended error reporting, persistent
+ connections and parallel polling, ability to select db for queries has
+ been fixed. Thanks to Pavel Rochnyak, skob. #2826, #2789
+ * Router OS plugin: Unset radio-name showing up as "(null)" has been
+ fixed. Thanks to melak. #2740
+ * RRDCacheD plugin: Cleanup rrdcached plugin a bit. Thanks to Pavel
+ Rochnyak. #3080
+ * RRDTool plugin: Error reporting has been extended. Thanks to Pavel
+ Rochnyak. #2825
+ * Sensors plugin: Support for humidity sensors has been added. Thanks to
+ Sarah Fischmann. #2913
+ * Sensu, OVS Stat, Turbostat, virt, OAuth, Write Prometheus, Intel RDT
+ plugins: Compiler warnings have been fixed. Thanks to Ruben Kerkhof.
+ #3093, #3098, #3099, #3100, #3102, #3103, #3104
+ * virt plugin: Code "do {} while(0)" around macro has been removed.
+ Thanks to Florian Forster. #2579
+ * virt plugin: Compiler warnings, a segfault in libvirt, typo in error
+ messages have been fixed. Thanks to Antoine Naud, Ruben Kerkhof, sarah
+ niuxu18. #2808, #2919, #2957
+ * virt plugin: Optional "virDomainGetCPUStats()" has been removed from
+ main flow, cleanup. Thanks to Pavel Rochnyak. #2972, #2978
+ * virt plugin: Tracking of VM state changes has been fixed. Thanks to
+ Radoslaw Jablonski. #2701
+ * Write MongoDB plugin: Plugin dependencies have been fixed. Thanks to
+ Pavel Rochnyak. #3010
+ * Write Prometheus plugin: A compilation issue on Mac OS X has been
+ fixed. Thanks to Florian Forster. #3059
+ * Write Redis plugin: Bug ""max_set_duration" deletes unexpected data"
+ has been fixed. Thanks to takahashi-tsc. #2773
+ * Write Stackdriver plugin: Potential NULL dereference and error
+ reporting have been fixed. Thanks to Florian Forster. #2960
+ * collectd.conf(5): a typo has been fixed, the tail plugin's
+ documentation has been improved. Thanks to Ruben Kerkhof, Florian
+ Forster. #3087, #2994
+ * collectd.conf.pod: virt: "Instances" option has been documented, a
+ clarifying example has been added. Thanks to Pavel Rochnyak, Fabien
+ Wernli. #2990, #2903
+ * collectd-python: "Import" configuration option has been documented.
+ Thanks to Tyler Harper. #2985
+ * collectd-snmp.pod: Document thread usage correctly. Thanks to Nathan
+ Ward. #3078
+ * CONTRIBUTING.md: Improve wording around ChangeLog; fix example,
+ document the new change log requirement / behavior. Thanks to Florian
+ Forster. #3061, #3054
+ * docs/review_comments.md: document with frequent review comments has
+ been started. Thanks to Florian Forster. #2964
+ * README: Include compiler defenses suggestion, do not point users to
+ non-existing file. Thanks to Kevin Laatz, Ruben Kerkhof. #2721, #2045
+
2018-10-23, Version 5.8.1
* collectd: Fix "BaseDir" option. Thanks to Mariusz Białończyk and
Pavel Rochnyak. #2857
libheap.la \
libignorelist.la \
liblatency.la \
+ libllist.la \
liblookup.la \
libmetadata.la \
libmount.la \
test_utils_time \
test_utils_vl_lookup \
test_libcollectd_network_parse \
- test_utils_config_cores \
- test_utils_proc_pids
+ test_utils_config_cores
TESTS = $(check_PROGRAMS)
src/daemon/utils_cache.h \
src/daemon/utils_complain.c \
src/daemon/utils_complain.h \
- src/daemon/utils_llist.c \
- src/daemon/utils_llist.h \
src/daemon/utils_random.c \
src/daemon/utils_random.h \
src/daemon/utils_subst.c \
libavltree.la \
libcommon.la \
libheap.la \
+ libllist.la \
liboconfig.la \
-lm \
$(COMMON_LIBS) \
src/testing.h
test_utils_config_cores_LDADD = libplugin_mock.la
-test_utils_proc_pids_SOURCES = \
- src/utils/proc_pids/proc_pids_test.c \
- src/testing.h
-test_utils_proc_pids_LDADD = libplugin_mock.la
-
libavltree_la_SOURCES = \
src/utils/avltree/avltree.c \
src/utils/avltree/avltree.h
src/utils/ignorelist/ignorelist.c \
src/utils/ignorelist/ignorelist.h
+libllist_la_SOURCES = \
+ src/daemon/utils_llist.c \
+ src/daemon/utils_llist.h
+
libmetadata_la_SOURCES = \
src/utils/metadata/meta_data.c \
src/utils/metadata/meta_data.h
chrony_la_LIBADD = -lm
endif
+if BUILD_PLUGIN_CHECK_UPTIME
+pkglib_LTLIBRARIES += check_uptime.la
+check_uptime_la_SOURCES = src/check_uptime.c
+check_uptime_la_LDFLAGS = $(PLUGIN_LDFLAGS)
+endif
+
+if BUILD_PLUGIN_CONNECTIVITY
+pkglib_LTLIBRARIES += connectivity.la
+connectivity_la_SOURCES = src/connectivity.c
+connectivity_la_CFLAGS = $(AM_CFLAGS) $(BUILD_WITH_LIBMNL_CFLAGS)
+connectivity_la_CPPFLAGS = $(AM_CPPFLAGS) $(BUILD_WITH_LIBYAJL_CPPFLAGS)
+connectivity_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_LIBYAJL_LDFLAGS)
+connectivity_la_LIBADD = $(BUILD_WITH_LIBYAJL_LIBS) $(BUILD_WITH_LIBMNL_LIBS) libignorelist.la
+endif
+
if BUILD_PLUGIN_CONNTRACK
pkglib_LTLIBRARIES += conntrack.la
conntrack_la_SOURCES = src/conntrack.c
test_plugin_intel_rdt_LDADD = liboconfig.la libplugin_mock.la
check_PROGRAMS += test_plugin_intel_rdt
TESTS += test_plugin_intel_rdt
+
+test_utils_proc_pids_SOURCES = \
+ src/utils/proc_pids/proc_pids_test.c \
+ src/testing.h
+test_utils_proc_pids_LDADD = libplugin_mock.la
+check_PROGRAMS += test_utils_proc_pids
+TESTS += test_utils_proc_pids
endif
if BUILD_PLUGIN_INTERFACE
lua_la_LIBADD = $(BUILD_WITH_LIBLUA_LIBS)
endif
-if BUILD_PLUGIN_LVM
-pkglib_LTLIBRARIES += lvm.la
-lvm_la_SOURCES = src/lvm.c
-lvm_la_CPPFLAGS = $(AM_CPPFLAGS) $(BUILD_WITH_LIBLVM2APP_CPPFLAGS)
-lvm_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_LIBLVM2APP_LDFLAGS)
-lvm_la_LIBADD = $(BUILD_WITH_LIBLVM2APP_LIBS)
-endif
-
if BUILD_PLUGIN_MADWIFI
pkglib_LTLIBRARIES += madwifi.la
madwifi_la_SOURCES = \
network_la_LDFLAGS += $(GCRYPT_LDFLAGS)
network_la_LIBADD += $(GCRYPT_LIBS)
endif
+
+test_plugin_network_SOURCES = \
+ src/network_test.c \
+ src/utils_fbhash.c \
+ src/daemon/configfile.c \
+ src/daemon/types_list.c
+test_plugin_network_CPPFLAGS = $(AM_CPPFLAGS) $(GCRYPT_CPPFLAGS)
+test_plugin_network_LDFLAGS = $(PLUGIN_LDFLAGS) $(GCRYPT_LDFLAGS)
+test_plugin_network_LDADD = \
+ libavltree.la \
+ liboconfig.la \
+ libplugin_mock.la \
+ libmetadata.la \
+ $(GCRYPT_LIBS)
+if BUILD_WITH_LIBSOCKET
+test_plugin_network_LDADD += -lsocket
+endif
+if BUILD_WITH_LIBNSL
+test_plugin_network_LDADD += -lnsl
+endif
+check_PROGRAMS += test_plugin_network
endif
if BUILD_PLUGIN_NFS
endif
endif
+if BUILD_PLUGIN_PROCEVENT
+pkglib_LTLIBRARIES += procevent.la
+procevent_la_SOURCES = src/procevent.c
+procevent_la_CPPFLAGS = $(AM_CPPFLAGS) $(BUILD_WITH_LIBYAJL_CPPFLAGS)
+procevent_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_LIBYAJL_LDFLAGS)
+procevent_la_LIBADD = $(BUILD_WITH_LIBYAJL_LIBS) libignorelist.la
+endif
+
if BUILD_PLUGIN_PROTOCOLS
pkglib_LTLIBRARIES += protocols.la
protocols_la_SOURCES = src/protocols.c
synproxy_la_LDFLAGS = $(PLUGIN_LDFLAGS)
endif
+if BUILD_PLUGIN_SYSEVENT
+pkglib_LTLIBRARIES += sysevent.la
+sysevent_la_SOURCES = src/sysevent.c
+sysevent_la_CPPFLAGS = $(AM_CPPFLAGS) $(BUILD_WITH_LIBYAJL_CPPFLAGS)
+sysevent_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_LIBYAJL_LDFLAGS)
+sysevent_la_LIBADD = $(BUILD_WITH_LIBYAJL_LIBS) libignorelist.la
+endif
+
if BUILD_PLUGIN_SYSLOG
pkglib_LTLIBRARIES += syslog.la
syslog_la_SOURCES = src/syslog.c
- chrony
Chrony daemon statistics: Local clock drift, offset to peers, etc.
+ - connectivity
+ Event-based interface status.
+
- conntrack
Number of nf_conntrack entries.
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).
-
- madwifi
Queries very detailed usage statistics from wireless LAN adapters and
interfaces that use the Atheros chipset and the MadWifi driver.
- processes
Process counts: Number of running, sleeping, zombie, ... processes.
+ - procevent
+ Listens for process starts and exits via netlink.
+
- protocols
Counts various aspects of network protocols such as IP, TCP, UDP, etc.
Acts as a StatsD server, reading values sent over the network from StatsD
clients and calculating rates and other aggregates out of these values.
+ - sysevent
+ Listens to rsyslog events and submits matched values.
+
- swap
Pages swapped out onto hard disk or whatever is called `swap' by the OS..
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/>
-
* libmemcached (optional)
Used by the `memcachec' plugin to connect to a memcache daemon.
<http://tangent.org/552/libmemcached.html>
$v{'type_instance'} = $cpu_instances[$key];
$v{'values'} = [ $counters[$key] ];
plugin_dispatch_values(\%v);
+ }
}
}
-}
sub df_read {
my $veid = shift;
$v{'type_instance'} = $val;
$v{'values'} = [ $parts[5] * ($parts[6] - $parts[7]), $parts[5] * $parts[7] ];
plugin_dispatch_values(\%v);
-}
+ }
}
sub load_read {
$v{'type_instance'} = $key;
$v{'values'} = [ $ps_states->{$key} ];
plugin_dispatch_values(\%v);
-}
+ }
}
sub users_read {
kstat.h \
kvm.h \
libgen.h \
+ locale.h \
mntent.h \
mnttab.h \
netdb.h \
# }}}
-# For the dns plugin
-AC_CHECK_HEADERS([arpa/nameser.h])
-AC_CHECK_HEADERS([arpa/nameser_compat.h], [], [],
- [[
- #if HAVE_ARPA_NAMESER_H
- # include <arpa/nameser.h>
- #endif
- ]]
-)
-
AC_CHECK_HEADERS([net/if_arp.h], [], [],
[[
#if HAVE_SYS_SOCKET_H
#
AC_CHECK_FUNCS_ONCE([ \
asprintf \
- closelog \
- getaddrinfo \
- getgrnam_r \
- getnameinfo \
+ execvpe \
getpwnam \
getpwnam_r \
- gettimeofday \
if_indextoname \
- openlog \
- regcomp \
- regerror \
- regexec \
- regfree \
- select \
- setenv \
setgroups \
- strcasecmp \
- strdup \
- strncasecmp \
- sysconf
+ setlocale
]
)
AC_FUNC_STRERROR_R
-SAVE_CFLAGS="$CFLAGS"
-CFLAGS="-Wall -Werror"
+if test "x$GCC" = "xyes"; then
+ SAVE_CFLAGS="$CFLAGS"
+ CFLAGS="$CFLAGS -Wall -Werror"
+fi
SAVE_LDFLAGS="$LDFLAGS"
LDFLAGS=""
if test "x$ac_system" = "xWindows"; then
AM_CONDITIONAL([BUILD_WITH_LIBSOCKET], [test "x$socket_needs_socket" = "xyes"])
AM_CONDITIONAL([BUILD_WITH_GNULIB], [test "x$socket_needs_gnulib" = "xyes"])
+AC_CHECK_FUNCS([inet_ntop],
+ [],
+ [
+ AC_CHECK_LIB([nsl], [inet_ntop],
+ [inet_ntop_needs_nsl="yes"],
+ [AC_MSG_ERROR([cannot find inet_ntop() in libnsl])]
+ )
+ ]
+)
+AM_CONDITIONAL([BUILD_WITH_LIBNSL], [test "x$inet_ntop_needs_nsl" = "xyes"])
+
clock_gettime_needs_posix4="no"
AC_CHECK_FUNCS([clock_gettime],
[have_clock_gettime="yes"],
else
AC_MSG_RESULT([no])
with_libgrpcpp="no (requires C++11 support)"
+ with_libprotobuf="no (<google/protobuf/util/time_util.h> requires C++11 support)"
fi
fi
AC_SUBST(BUILD_WITH_LIBLUA_LIBS)
# }}}
-# --with-liblvm2app {{{
-AC_ARG_WITH([liblvm2app],
- [AS_HELP_STRING([--with-liblvm2app@<:@=PREFIX@:>@], [Path to liblvm2app.])],
- [
- if test "x$withval" = "xno"; then
- with_liblvm2app="no"
- else
- with_liblvm2app="yes"
- if test "x$withval" != "xyes"; then
- with_liblvm2app_cppflags="-I$withval/include"
- with_liblvm2app_ldflags="-L$withval/lib"
- fi
- fi
- ],
- [
- if test "x$ac_system" = "xLinux"; then
- with_liblvm2app="yes"
- else
- with_liblvm2app="no (Linux only library)"
- fi
- ]
-)
-
-if test "x$with_liblvm2app" = "xyes"; then
- SAVE_CPPFLAGS="$CPPFLAGS"
- CPPFLAGS="$CPPFLAGS $with_liblvm2app_cppflags"
-
- AC_CHECK_HEADERS([lvm2app.h],
- [with_liblvm2app="yes"],
- [with_liblvm2app="no (lvm2app.h not found)"]
- )
-
- CPPFLAGS="$SAVE_CPPFLAGS"
-fi
-
-if test "x$with_liblvm2app" = "xyes"; then
- SAVE_CPPFLAGS="$CPPFLAGS"
- SAVE_LDFLAGS="$LDFLAGS"
- CPPFLAGS="$CPPFLAGS $with_liblvm2app_cppflags"
- LDFLAGS="$LDFLAGS $with_liblvm2app_ldflags"
-
- AC_CHECK_LIB([lvm2app], [lvm_lv_get_property],
- [with_liblvm2app="yes"],
- [with_liblvm2app="no (Symbol 'lvm_lv_get_property' not found)"]
- )
-
- CPPFLAGS="$SAVE_CPPFLAGS"
- LDFLAGS="$SAVE_LDFLAGS"
-fi
-
-if test "x$with_liblvm2app" = "xyes"; then
- BUILD_WITH_LIBLVM2APP_CPPFLAGS="$with_liblvm2app_cppflags"
- BUILD_WITH_LIBLVM2APP_LDFLAGS="$with_liblvm2app_ldflags"
- BUILD_WITH_LIBLVM2APP_LIBS="-llvm2app"
-fi
-
-AC_SUBST([BUILD_WITH_LIBLVM2APP_CPPFLAGS])
-AC_SUBST([BUILD_WITH_LIBLVM2APP_LDFLAGS])
-AC_SUBST([BUILD_WITH_LIBLVM2APP_LIBS])
-# }}}
-
# --with-libmemcached {{{
AC_ARG_WITH([libmemcached],
[AS_HELP_STRING([--with-libmemcached@<:@=PREFIX@:>@], [Path to libmemcached.])],
SAVE_CPPFLAGS="$CPPFLAGS"
SAVE_LDFLAGS="$LDFLAGS"
SAVE_LIBS="$LIBS"
- CPPFLAGS="$CPPFLAGS $with_libnetsnmp_cppflags -Wall -Werror"
+ CPPFLAGS="$CPPFLAGS $with_libnetsnmp_cppflags"
+ if test "x$GCC" = "xyes"; then
+ CPPFLAGS="$CPPFLAGS -Wall -Werror"
+ fi
LDFLAGS="$LDFLAGS $with_libnetsnmp_ldflags"
LIBS="$LIBS -lnetsnmp"
)
AC_CHECK_LIB([netsnmpagent], [init_agent],
- [with_libnetsnmpagent="yes"],
+ [
+ # libnetsnmp can be built without mib loading support
+ AC_CHECK_LIB([netsnmp], [get_tree],
+ [with_libnetsnmpagent="yes"],
+ [with_libnetsnmpagent="no (libnetsnmp doesn't support mib loading)"]
+ )
+ ],
[with_libnetsnmpagent="no (libnetsnmpagent not found)"],
[$libnetsnmphelpers]
)
fi
if test "x$with_libnetsnmpagent" = "xyes"; then
+ BUILD_WITH_LIBNETSNMPAGENT_CPPFLAGS="$with_libnetsnmpagent_cppflags"
+ BUILD_WITH_LIBNETSNMPAGENT_LDFLAGS="$with_libnetsnmpagent_ldflags"
BUILD_WITH_LIBNETSNMPAGENT_LIBS="-lnetsnmpagent $libnetsnmphelpers"
fi
# (see issues #41 and #42)
SAVE_CFLAGS="$CFLAGS"
SAVE_LIBS="$LIBS"
- CFLAGS="$CFLAGS $PERL_CFLAGS -Wall -Werror"
+ CFLAGS="$CFLAGS $PERL_CFLAGS"
+ if test "x$GCC" = "xyes"; then
+ CFLAGS="$CFLAGS -Wall -Werror"
+ fi
LIBS="$LIBS $PERL_LIBS"
AC_CACHE_CHECK([for broken Perl_load_module()],
AC_CHECK_LIB([protobuf], [main],
[
SAVE_CPPFLAGS="$CPPFLAGS"
- CPPFLAGS="$with_libprotobuf_cppflags $PROTOBUF_CFLAGS"
+ CPPFLAGS="-std=c++11 $with_libprotobuf_cppflags $PROTOBUF_CFLAGS"
if test "x$PROTOBUF_LIBS" = "x"
then
PROTOBUF_LIBS="-lprotobuf"
if test $? -ne 0; then
with_libpython="no"
fi
- LIBPYTHON_LDFLAGS="`${PYTHON_CONFIG} --ldflags`"
+ LIBPYTHON_LDFLAGS="`${PYTHON_CONFIG} --ldflags --embed`" || LIBPYTHON_LDFLAGS="`${PYTHON_CONFIG} --ldflags`"
if test $? -ne 0; then
with_libpython="no"
fi
- LIBPYTHON_LIBS="`${PYTHON_CONFIG} --libs`"
+ LIBPYTHON_LIBS="`${PYTHON_CONFIG} --libs --embed`" || LIBPYTHON_LIBS="`${PYTHON_CONFIG} --libs`"
if test $? -ne 0; then
with_libpython="no"
fi
with_libtokyotyrant="$withval"
else
with_libtokyotyrant_cppflags="-I$withval/include"
- with_libtokyotyrant_ldflags="-L$withval/include"
+ with_libtokyotyrant_ldflags="-L$withval/lib"
with_libtokyotyrant_libs="-ltokyotyrant"
with_libtokyotyrant="yes"
fi
else if test "x$withval" = "xyes"; then
with_libupsclient="use_pkgconfig"
else
- if test -x "$withval"; then
+ if test -f "$withval" && test -x "$withval"; then
with_libupsclient_config="$withval"
with_libupsclient="use_libupsclient_config"
else if test -x "$withval/bin/libupsclient-config"; then
fi
if test "x$with_libxmms" = "xyes"; then
- SAVE_CPPFLAGS="$CFLAGS"
+ SAVE_CPPFLAGS="$CPPFLAGS"
CPPFLAGS="$with_xmms_cflags"
AC_CHECK_HEADER([xmmsctrl.h],
plugin_bind="no"
plugin_ceph="no"
plugin_cgroups="no"
+plugin_connectivity="no"
plugin_conntrack="no"
plugin_contextswitch="no"
plugin_cpu="no"
plugin_perl="no"
plugin_pinba="no"
plugin_processes="no"
+plugin_procevent="no"
plugin_protocols="no"
plugin_python="no"
plugin_serial="no"
plugin_smart="no"
plugin_swap="no"
plugin_synproxy="no"
+plugin_sysevent="no"
plugin_tape="no"
plugin_tcpconns="no"
plugin_ted="no"
plugin_ipc="yes"
plugin_irq="yes"
plugin_load="yes"
- plugin_lvm="yes"
plugin_mcelog="yes"
plugin_memory="yes"
plugin_nfs="yes"
if test "x$with_libyajl" = "xyes" && test "x$with_libyajl2" = "xyes"; then
plugin_ovs_events="yes"
plugin_ovs_stats="yes"
+ plugin_procevent="yes"
+
+ if test "x$with_libmnl" = "xyes"; then
+ plugin_connectivity="yes"
+ fi
fi
if test "x$have_pci_regs_h" = "xyes"; then
if test "x$with_libyajl" = "xyes"; then
plugin_ceph="yes"
+ plugin_sysevent="yes"
fi
if test "x$have_processor_info" = "xyes"; then
AC_PLUGIN([ceph], [$plugin_ceph], [Ceph daemon statistics])
AC_PLUGIN([cgroups], [$plugin_cgroups], [CGroups CPU usage accounting])
AC_PLUGIN([chrony], [yes], [Chrony statistics])
+AC_PLUGIN([check_uptime], [yes], [Notify about uptime reset])
+AC_PLUGIN([connectivity], [$plugin_connectivity], [Network interface up/down events])
AC_PLUGIN([conntrack], [$plugin_conntrack], [nf_conntrack statistics])
AC_PLUGIN([contextswitch], [$plugin_contextswitch], [context switch statistics])
AC_PLUGIN([cpu], [$plugin_cpu], [CPU usage statistics])
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([match_hashed], [yes], [The hashed match])
AC_PLUGIN([postgresql], [$with_libpq], [PostgreSQL database statistics])
AC_PLUGIN([powerdns], [yes], [PowerDNS statistics])
AC_PLUGIN([processes], [$plugin_processes], [Process statistics])
+AC_PLUGIN([procevent], [$plugin_procevent], [Process event (start, stop) statistics])
AC_PLUGIN([protocols], [$plugin_protocols], [Protocol (IP, TCP, ...) statistics])
AC_PLUGIN([python], [$plugin_python], [Embed a Python interpreter])
AC_PLUGIN([redis], [$with_libhiredis], [Redis plugin])
AC_PLUGIN([statsd], [yes], [StatsD plugin])
AC_PLUGIN([swap], [$plugin_swap], [Swap usage statistics])
AC_PLUGIN([synproxy], [$plugin_synproxy], [Synproxy stats plugin])
+AC_PLUGIN([sysevent], [$plugin_sysevent], [rsyslog events])
AC_PLUGIN([syslog], [$have_syslog], [Syslog logging plugin])
AC_PLUGIN([table], [yes], [Parsing of tabular data])
AC_PLUGIN([tail], [yes], [Parsing of logfiles])
AC_CONFIG_FILES([src/libcollectdclient/collectd/lcc_features.h])
-AM_CFLAGS="-Wall"
-AM_CXXFLAGS="-Wall"
-if test "x$enable_werror" != "xno"; then
- AM_CFLAGS="$AM_CFLAGS -Werror"
- AM_CXXFLAGS="$AM_CXXFLAGS -Werror"
+if test "x$GCC" = "xyes"; then
+ AM_CFLAGS="-Wall"
+ AM_CXXFLAGS="-Wall"
+ if test "x$enable_werror" != "xno"; then
+ AM_CFLAGS="$AM_CFLAGS -Werror"
+ AM_CXXFLAGS="$AM_CXXFLAGS -Werror"
+ fi
fi
AC_SUBST([AM_CFLAGS])
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([ libmicrohttpd . . . . $with_libmicrohttpd])
AC_MSG_RESULT([ libmnl . . . . . . . $with_libmnl])
AC_MSG_RESULT([ ceph . . . . . . . . $enable_ceph])
AC_MSG_RESULT([ cgroups . . . . . . . $enable_cgroups])
AC_MSG_RESULT([ chrony. . . . . . . . $enable_chrony])
+AC_MSG_RESULT([ check_uptime. . . . . $enable_check_uptime])
+AC_MSG_RESULT([ connectivity. . . . . $enable_connectivity])
AC_MSG_RESULT([ conntrack . . . . . . $enable_conntrack])
AC_MSG_RESULT([ contextswitch . . . . $enable_contextswitch])
AC_MSG_RESULT([ cpu . . . . . . . . . $enable_cpu])
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])
AC_MSG_RESULT([ match_hashed . . . . $enable_match_hashed])
AC_MSG_RESULT([ postgresql . . . . . $enable_postgresql])
AC_MSG_RESULT([ powerdns . . . . . . $enable_powerdns])
AC_MSG_RESULT([ processes . . . . . . $enable_processes])
+AC_MSG_RESULT([ procevent . . . . . . $enable_procevent])
AC_MSG_RESULT([ protocols . . . . . . $enable_protocols])
AC_MSG_RESULT([ python . . . . . . . $enable_python])
AC_MSG_RESULT([ redis . . . . . . . . $enable_redis])
AC_MSG_RESULT([ statsd . . . . . . . $enable_statsd])
AC_MSG_RESULT([ swap . . . . . . . . $enable_swap])
AC_MSG_RESULT([ synproxy . . . . . . $enable_synproxy])
+AC_MSG_RESULT([ sysevent. . . . . . . $enable_sysevent])
AC_MSG_RESULT([ syslog . . . . . . . $enable_syslog])
AC_MSG_RESULT([ table . . . . . . . . $enable_table])
AC_MSG_RESULT([ tail_csv . . . . . . $enable_tail_csv])
Collectd network protocol implementation.
"""
-import socket,struct,sys
+import socket,struct
import platform
if platform.python_version() < '2.8.0':
# Python 2.7 and below io.StringIO does not like unicode
function nav_calculate_event_x (e)
{
var pos = 0;
- var off = 0;
if (!e || !e.target)
return;
- off = nav_calculate_offset_x (e.target);
+ nav_calculate_offset_x (e.target);
if (e.pageX || e.pageY)
{
newOption.setAttribute('style', 'font-style: italic');
newOption.appendChild(document.createTextNode('- please select -'));
select.appendChild(newOption);
- for (i = 0; i < optCnt; i++) {
- newOption = document.createElement("option");
+ for (var i = 0; i < optCnt; i++) {
+ var newOption = document.createElement("option");
newOption.value = options[i].firstChild ? options[i].firstChild.data : '';
if (keepSelection && newOption.value == oldValue)
newOption.setAttribute('selected', 'selected');
function ListOfGraph(response) {
var graphs = response ? response.getElementsByTagName('graph') : null;
if (graphs && graphs.length > 0) {
- for (i = 0; i < graphs.length; i++)
+ for (var i = 0; i < graphs.length; i++)
GraphDoAppend(graphs[i].getAttribute('host'), graphs[i].getAttribute('plugin'), graphs[i].getAttribute('plugin_instance'),
graphs[i].getAttribute('type'), graphs[i].getAttribute('type_instance'), graphs[i].getAttribute('timespan'),
graphs[i].getAttribute('tinyLegend') == '1', graphs[i].getAttribute('logarithmic') == '1');
var graph_id = 'graph_'+nextGraphId++;
var graph_src = graph_url+'?host='+encodeURIComponent(host)+'&plugin='+encodeURIComponent(plugin)+'&plugin_instance='+encodeURIComponent(pinst)+'&type='+encodeURIComponent(type);
var graph_alt = '';
- var grap_title = '';
+ var graph_title = '';
if (tinst == '@') {
graph_alt = host+'/'+plugin+(pinst.length > 0 ? '-'+pinst : '')+'/'+type;
graph_title = type+' of '+plugin+(pinst.length > 0 ? '-'+pinst : '')+' plugin for '+host;
graphList.push(graph_id+' '+encodeURIComponent(graph_alt)+(logarithmic ? '&logarithmic=1' : '')+(tinyLegend ? '&tinylegend=1' : '')+'×pan='+encodeURIComponent(timespan));
// Graph container
- newGraph = document.createElement('div');
+ var newGraph = document.createElement('div');
newGraph.setAttribute('class', 'graph');
newGraph.setAttribute('id', graph_id);
// Graph cell + graph
- newImg = document.createElement('img');
+ var newImg = document.createElement('img');
newImg.setAttribute('src', graph_src);
newImg.setAttribute('alt', graph_alt);
newImg.setAttribute('title', graph_title);
document.getElementById('ge_graphid').value = graph;
document.getElementById('ge_tinylegend').checked = src_url.match(/&tinylegend=1/);
document.getElementById('ge_logarithmic').checked = src_url.match(/&logarithmic=1/);
- for (i = 0; i < ts_sel.options.length; i++)
+ for (var i = 0; i < ts_sel.options.length; i++)
if (ts_sel.options[i].value == ts) {
ts_sel.selectedIndex = i;
break;
imgs[imgCnt].setAttribute('src', newSrc);
var myList = Array();
- for (i = 0; i < graphList.length; i++)
+ for (var i = 0; i < graphList.length; i++)
if (graphList[i].substring(0, graphId.length) == graphId && graphList[i].charAt(graphId.length) == ' ') {
newSrc = graphList[i];
newSrc = newSrc.replace(/&logarithmic=[^&]*/, '');
document.getElementById('nograph').style.display = 'block';
var myList = Array();
- for (i = 0; i < graphList.length; i++)
+ for (var i = 0; i < graphList.length; i++)
if (graphList[i].substring(0, graphId.length) == graphId && graphList[i].charAt(graphId.length) == ' ')
continue;
else
var graphId = graph == null ? document.getElementById('ge_graphid').value : graph;
var childCnt = graphs.childNodes.length;
var prevGraph = null;
- for (i = 0; i < childCnt; i++)
+ for (var i = 0; i < childCnt; i++)
if (graphs.childNodes[i].nodeName == 'div' || graphs.childNodes[i].nodeName == 'DIV') {
if (graphs.childNodes[i].id == 'nograph') {
// Skip
var childCnt = graphs.childNodes.length;
var nextGraph = null;
var myGraph = null;
- for (i = 0; i < childCnt; i++)
+ for (var i = 0; i < childCnt; i++)
if (graphs.childNodes[i].nodeName == 'div' || graphs.childNodes[i].nodeName == 'DIV') {
if (graphs.childNodes[i].id == 'nograph') {
// Skip
break;
}
}
- for (i = 0; i < graphList.length; i++)
- if (graphList[i].substring(0, graphId.length) == graphId && graphList[i].charAt(graphId.length) == ' ') {
- if (i+1 < graphList.length) {
- var tmp = graphList[i+1];
- graphList[i+1] = graphList[i];
- graphList[i] = tmp;
+ for (var j = 0; j < graphList.length; j++)
+ if (graphList[j].substring(0, graphId.length) == graphId && graphList[j].charAt(graphId.length) == ' ') {
+ if (j+1 < graphList.length) {
+ var tmp = graphList[j+1];
+ graphList[j+1] = graphList[i];
+ graphList[j] = tmp;
}
break;
}
if (document.cookie.length > 0) {
var cname= 'graphLst'+lname+'=';
var cookies = document.cookie.split('; ');
- for (i = 0; i < cookies.length; i++)
+ for (var i = 0; i < cookies.length; i++)
if (cookies[i].substring(0, cname.length) == cname)
return cookies[i].substring(cname.length).split('/');
}
} else {
select.removeAttribute('disabled');
for (i = 0; i < optCnt; i++) {
- newOption = document.createElement("option");
+ var newOption = document.createElement("option");
newOption.value = options[i][0];
if (newOption.value == oldValue)
newOption.setAttribute('selected', 'selected');
if (graphList.length > 0) {
// Save graph list to cookie
var str = '';
- for (i = 0; i < graphList.length; i++) {
+ for (var i = 0; i < graphList.length; i++) {
var g = graphList[i].indexOf(' ');
if (i > 0)
str += '/';
// Load graph list from cookie
var grLst = GraphListFromCookie(cname);
var oldLength = graphList.length;
- for (i = 0; i < grLst.length; i++) {
+ for (var i = 0; i < grLst.length; i++) {
var host = '';
var plugin = '';
var pinst = '';
var logarithmic = false;
var tinyLegend = false;
var graph = grLst[i].split('&');
- for (j = 0; j < graph.length; j++)
+ for (var j = 0; j < graph.length; j++)
if (graph[j] == 'logarithmic=1')
logarithmic = true;
else if (graph[j] == 'tinylegend=1')
%define with_ceph 0%{!?_without_ceph:1}
%define with_cgroups 0%{!?_without_cgroups:1}
%define with_chrony 0%{!?_without_chrony:1}
+%define with_connectivity 0%{!?_without_connectivity:1}
%define with_conntrack 0%{!?_without_conntrack:1}
%define with_contextswitch 0%{!?_without_contextswitch:1}
%define with_cpu 0%{!?_without_cpu: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}
%define with_mcelog 0%{!?_without_mcelog:1}
%define with_openvpn 0%{!?_without_openvpn:1}
%define with_ovs_events 0%{!?_without_ovs_events:1}
%define with_ovs_stats 0%{!?_without_ovs_stats:1}
+%define with_pcie_errors 0%{!?_without_pcie_errors:1}
%define with_perl 0%{!?_without_perl:1}
%define with_pinba 0%{!?_without_pinba:1}
%define with_ping 0%{!?_without_ping:1}
%define with_postgresql 0%{!?_without_postgresql:1}
%define with_powerdns 0%{!?_without_powerdns:1}
%define with_processes 0%{!?_without_processes:1}
+%define with_procevent 0%{!?_without_procevent:1}
%define with_protocols 0%{!?_without_protocols:1}
%define with_python 0%{!?_without_python:1}
%define with_redis 0%{!?_without_redis:1}
%define with_statsd 0%{!?_without_statsd:1}
%define with_swap 0%{!?_without_swap:1}
%define with_synproxy 0%{!?_without_synproxy:0}
+%define with_sysevent 0%{!?_without_sysevent:1}
%define with_syslog 0%{!?_without_syslog:1}
%define with_table 0%{!?_without_table:1}
%define with_tail 0%{!?_without_tail:1}
%define with_write_prometheus 0%{!?_without_write_prometheus:1}
%define with_write_redis 0%{!?_without_write_redis:1}
%define with_write_riemann 0%{!?_without_write_riemann:1}
+%define with_write_stackdriver 0%{!?_without_write_stackdriver:1}
%define with_write_sensu 0%{!?_without_write_sensu:1}
%define with_write_syslog 0%{!?_without_write_syslog:1}
%define with_write_tsdb 0%{!?_without_write_tsdb:1}
%define with_xencpu 0%{!?_without_xencpu:0}
# plugin zone disabled, requires Solaris
%define with_zone 0%{!?_without_zone:0}
+# plugin gpu_nvidia requires cuda-nvml-dev
+# get it from https://developer.nvidia.com/cuda-downloads
+# then install cuda-nvml-dev-10-1 or other version
+%define with_gpu_nvidia 0%{!?_without_gpu_nvidia:0}
+# not sure why this one's failing
+%define with_write_stackdriver 0%{!?_without_write_stackdriver:0}
# Plugins not buildable on RHEL < 6
%if 0%{?rhel} && 0%{?rhel} < 6
%define with_gmond 0
%define with_iptables 0
%define with_ipvs 0
-%define with_lvm 0
%define with_modbus 0
%define with_netlink 0
%define with_redis 0
# Plugins not buildable on RHEL < 7
%if 0%{?rhel} && 0%{?rhel} < 7
+%define with_connectivity 0
%define with_cpusleep 0
%define with_gps 0
%define with_mqtt 0
%define with_ovs_events 0
%define with_ovs_stats 0
+%define with_procevent 0
%define with_redis 0
%define with_rrdcached 0
+%define with_sysevent 0
%define with_write_redis 0
%define with_write_riemann 0
%define with_xmms 0
Summary: Statistics collection and monitoring daemon
Name: collectd
-Version: 5.7.1
-Release: 9%{?dist}
+Version: 5.9.2
+Release: 2%{?dist}
URL: https://collectd.org
Source: https://collectd.org/files/%{name}-%{version}.tar.bz2
License: GPLv2
Chrony plugin for collectd
%endif
+%if %{with_connectivity}
+%package connectivity
+Summary: Connectivity plugin for collectd
+Group: System Environment/Daemons
+Requires: %{name}%{?_isa} = %{version}-%{release}
+BuildRequires: libmnl-devel, yajl-devel
+%description connectivity
+Monitors network interface up/down status via netlink library.
+%endif
+
%if %{with_curl}
%package curl
Summary: Curl plugin for collectd
application programming interface (API) to Lua scripts.
%endif
-%if %{with_lvm}
-%package lvm
-Summary: LVM plugin for collectd
-Group: System Environment/Daemons
-Requires: %{name}%{?_isa} = %{version}-%{release}
-BuildRequires: lvm2-devel
-%description lvm
-This plugin collects size of “Logical Volumes” (LV) and “Volume Groups” (VG)
-of Linux' “Logical Volume Manager” (LVM).
-%endif
-
%if %{with_mcelog}
%package mcelog
Summary: Mcelog plugin for collectd
application programming interface (API) to Perl-scripts.
%endif
+%if %{with_pcie_errors}
+%package pcie_errors
+Summary: PCI Express errors plugin for collectd
+Group: System Environment/Daemons
+Requires: %{name}%{?_isa} = %{version}-%{release}
+%description pcie_errors
+The pcie_errors plugin collects PCI Express errors from Device Status in Capability
+structure and from Advanced Error Reporting Extended Capability.
+%endif
+
%if %{with_pinba}
%package pinba
Summary: Pinba plugin for collectd
database.
%endif
+%if %{with_procevent}
+%package procevent
+Summary: Processes event plugin for collectd
+Group: System Environment/Daemons
+Requires: %{name}%{?_isa} = %{version}-%{release}
+BuildRequires: yajl-devel
+%description procevent
+Monitors process starts/stops via netlink library.
+%endif
+
%if %{with_python}
%package python
Summary: Python plugin for collectd
This plugin for collectd to support AgentX integration.
%endif
+%if %{with_sysevent}
+%package sysevent
+Summary: Rsyslog event plugin for collectd
+Group: System Environment/Daemons
+Requires: %{name}%{?_isa} = %{version}-%{release}
+BuildRequires: yajl-devel
+%description sysevent
+Monitors rsyslog for system events.
+%endif
+
%if %{with_varnish}
%package varnish
Summary: Varnish plugin for collectd
The riemann plugin submits values to Riemann, an event stream processor.
%endif
+%if %{with_write_stackdriver}
+%package write_stackdriver
+Summary: stackdriver plugin for collectd
+Group: System Environment/Daemons
+Requires: %{name}%{?_isa} = %{version}-%{release}
+BuildRequires: curl-devel, yajl-devel, openssl-devel
+%description write_stackdriver
+The write_stackdriver collectd plugin writes metrics to the
+Google Stackdriver Monitoring service.
+%endif
+
+%if %{with_gpu_nvidia}
+%package gpu_nvidia
+Summary: stackdriver plugin for collectd
+Group: System Environment/Daemons
+Requires: %{name}%{?_isa} = %{version}-%{release}
+BuildRequires: cuda-nvml-dev-10-1
+%description gpu_nvidia
+The gpu_nvidia collectd plugin collects NVidia GPU metrics.
+%endif
+
%if %{with_xencpu}
%package xencpu
Summary: xencpu plugin for collectd
%define _with_chrony --disable-chrony
%endif
+%if %{with_connectivity}
+%define _with_connectivity --enable-connectivity
+%else
+%define _with_connectivity --disable-connectivity
+%endif
+
%if %{with_conntrack}
%define _with_conntrack --enable-conntrack
%else
%define _with_lua --disable-lua
%endif
-%if %{with_lvm}
-%define _with_lvm --enable-lvm
-%else
-%define _with_lvm --disable-lvm
-%endif
-
%if %{with_madwifi}
%define _with_madwifi --enable-madwifi
%else
%define _with_perl --disable-perl
%endif
+%if %{with_pcie_errors}
+%define _with_pcie_errors --enable-pcie_errors
+%else
+%define _with_pcie_errors --disable-pcie_errors
+%endif
+
%if %{with_pf}
%define _with_pf --enable-pf
%else
%define _with_processes --disable-processes
%endif
+%if %{with_procevent}
+%define _with_procevent --enable-procevent
+%else
+%define _with_procevent --disable-procevent
+%endif
+
%if %{with_protocols}
%define _with_protocols --enable-protocols
%else
%define _with_synproxy --disable-synproxy
%endif
+%if %{with_sysevent}
+%define _with_sysevent --enable-sysevent
+%else
+%define _with_sysevent --disable-sysevent
+%endif
+
%if %{with_syslog}
%define _with_syslog --enable-syslog
%else
%define _with_write_riemann --disable-write_riemann
%endif
+%if %{with_write_stackdriver}
+%define _with_write_stackdriver --enable-write_stackdriver
+%else
+%define _with_write_stackdriver --disable-write_stackdriver
+%endif
+
+%if %{with_gpu_nvidia}
+%define _with_gpu_nvidia --enable-gpu_nvidia
+%else
+%define _with_gpu_nvidia --disable-gpu_nvidia
+%endif
+
%if %{with_write_sensu}
%define _with_write_sensu --enable-write_sensu
%else
%{?_with_ceph} \
%{?_with_cgroups} \
%{?_with_chrony} \
+ %{?_with_connectivity} \
%{?_with_conntrack} \
%{?_with_contextswitch} \
%{?_with_cpufreq} \
%{?_with_logfile} \
%{?_with_lpar} \
%{?_with_lua} \
- %{?_with_lvm} \
%{?_with_madwifi} \
%{?_with_mbmon} \
%{?_with_mcelog} \
%{?_with_ovs_events} \
%{?_with_ovs_stats} \
%{?_with_perl} \
+ %{?_with_pcie_errors} \
%{?_with_pf} \
%{?_with_pinba} \
%{?_with_ping} \
%{?_with_postgresql} \
%{?_with_powerdns} \
%{?_with_processes} \
+ %{?_with_procevent} \
%{?_with_protocols} \
%{?_with_python} \
%{?_with_redis} \
%{?_with_statsd} \
%{?_with_swap} \
%{?_with_synproxy} \
+ %{?_with_sysevent} \
%{?_with_syslog} \
%{?_with_table} \
%{?_with_tail_csv} \
%{?_with_write_prometheus} \
%{?_with_write_redis} \
%{?_with_write_riemann} \
+ %{?_with_write_stackdriver} \
+ %{?_with_gpu_nvidia} \
%{?_with_write_sensu} \
%{?_with_write_syslog} \
%{?_with_write_tsdb} \
%{_libdir}/%{name}/chrony.so
%endif
+%if %{with_connectivity}
+%files connectivity
+%{_libdir}/%{name}/connectivity.so
+%endif
+
%if %{with_curl}
%files curl
%{_libdir}/%{name}/curl.so
%{_libdir}/%{name}/lua.so
%endif
-%if %{with_lvm}
-%files lvm
-%{_libdir}/%{name}/lvm.so
-%endif
-
%if %{with_memcachec}
%files memcachec
%{_libdir}/%{name}/memcachec.so
%{_libdir}/%{name}/perl.so
%endif
+%if %{with_pcie_errors}
+%files pcie_errors
+%{_libdir}/%{name}/pcie_errors.so
+%endif
+
%if %{with_pinba}
%files pinba
%{_libdir}/%{name}/pinba.so
%{_libdir}/%{name}/postgresql.so
%endif
+%if %{with_procevent}
+%files procevent
+%{_libdir}/%{name}/procevent.so
+%endif
+
%if %{with_python}
%files python
%{_mandir}/man5/collectd-python*
%{_libdir}/%{name}/snmp_agent.so
%endif
+%if %{with_sysevent}
+%files sysevent
+%{_libdir}/%{name}/sysevent.so
+%endif
+
%if %{with_varnish}
%files varnish
%{_libdir}/%{name}/varnish.so
%{_libdir}/%{name}/write_riemann.so
%endif
+%if %{with_write_stackdriver}
+%files write_stackdriver
+%{_libdir}/%{name}/write_stackdriver.so
+%endif
+
+%if %{with_gpu_nvidia}
+%files write_gpu_nvidia
+%{_libdir}/%{name}/write_gpu_nvidia.so
+%endif
+
%if %{with_xencpu}
%files xencpu
%{_libdir}/%{name}/xencpu.so
%doc contrib/
%changelog
+* Mon Oct 14 2019 Ruben Kerkhof <ruben@rubenkerkhof.com> - 5.9.2-2
+- Remove lvm plugin, liblvmapp has been deprecated upstream
+
+* Fri Jun 14 2019 Fabien Wernli <rpmbuild@faxmodem.org> - 5.9.0-1
+- add code for write_stackdriver (disabled for now)
+- add code for gpu_nvidia (disabled for now)
+- add pcie_errors
+
* Thu Sep 28 2017 Jakub Jankowski <shasta@toxcorp.com> - 5.7.1-9
- Fix mbmon/mcelog build options
sstrncpy(tmp_plugin_instance, agg->ident.plugin_instance,
sizeof(tmp_plugin_instance));
+ // Both tmp_plugin and tmp_plugin_instance are empty.
if ((strcmp("", tmp_plugin) == 0) && (strcmp("", tmp_plugin_instance) == 0))
sstrncpy(inst->ident.plugin_instance, AGG_FUNC_PLACEHOLDER,
sizeof(inst->ident.plugin_instance));
- else if (strcmp("", tmp_plugin) != 0)
- snprintf(inst->ident.plugin_instance, sizeof(inst->ident.plugin_instance),
- "%s-%s", tmp_plugin, AGG_FUNC_PLACEHOLDER);
- else if (strcmp("", tmp_plugin_instance) != 0)
- snprintf(inst->ident.plugin_instance, sizeof(inst->ident.plugin_instance),
- "%s-%s", tmp_plugin_instance, AGG_FUNC_PLACEHOLDER);
+ // tmp_plugin is non-empty, and tmp_plugin_instance is empty.
+ else if (strcmp("", tmp_plugin_instance) == 0)
+ ssnprintf(inst->ident.plugin_instance,
+ sizeof(inst->ident.plugin_instance), "%s-%s", tmp_plugin,
+ AGG_FUNC_PLACEHOLDER);
+ // tmp_plugin is empty, and tmp_plugin_instance is non-empty.
+ else if (strcmp("", tmp_plugin) == 0)
+ ssnprintf(inst->ident.plugin_instance,
+ sizeof(inst->ident.plugin_instance), "%s-%s",
+ tmp_plugin_instance, AGG_FUNC_PLACEHOLDER);
+ // Both tmp_plugin and tmp_plugin_instance are non-empty.
else
- snprintf(inst->ident.plugin_instance, sizeof(inst->ident.plugin_instance),
- "%s-%s-%s", tmp_plugin, tmp_plugin_instance,
- AGG_FUNC_PLACEHOLDER);
+ ssnprintf(inst->ident.plugin_instance,
+ sizeof(inst->ident.plugin_instance), "%s-%s-%s", tmp_plugin,
+ tmp_plugin_instance, AGG_FUNC_PLACEHOLDER);
}
/* Type */
READ_FUNC(average, (inst->sum / ((gauge_t)inst->num)));
READ_FUNC(min, inst->min);
READ_FUNC(max, inst->max);
- READ_FUNC(stddev,
- sqrt((((gauge_t)inst->num) * inst->squares_sum) -
- (inst->sum * inst->sum)) /
- ((gauge_t)inst->num));
+ READ_FUNC(stddev, sqrt((((gauge_t)inst->num) * inst->squares_sum) -
+ (inst->sum * inst->sum)) /
+ ((gauge_t)inst->num));
}
/* Reset internal state. */
if (r.reply.id == AMQP_CONNECTION_CLOSE_METHOD) {
amqp_connection_close_t *m = r.reply.decoded;
char *tmp = camqp_bytes_cstring(&m->reply_text);
- snprintf(buffer, buffer_size, "Server connection error %d: %s",
- m->reply_code, tmp);
+ ssnprintf(buffer, buffer_size, "Server connection error %d: %s",
+ m->reply_code, tmp);
sfree(tmp);
} else if (r.reply.id == AMQP_CHANNEL_CLOSE_METHOD) {
amqp_channel_close_t *m = r.reply.decoded;
char *tmp = camqp_bytes_cstring(&m->reply_text);
- snprintf(buffer, buffer_size, "Server channel error %d: %s",
- m->reply_code, tmp);
+ ssnprintf(buffer, buffer_size, "Server channel error %d: %s",
+ m->reply_code, tmp);
sfree(tmp);
} else {
- snprintf(buffer, buffer_size, "Server error method %#" PRIx32,
- r.reply.id);
+ ssnprintf(buffer, buffer_size, "Server error method %#" PRIx32,
+ r.reply.id);
}
break;
default:
- snprintf(buffer, buffer_size, "Unknown reply type %i", (int)r.reply_type);
+ ssnprintf(buffer, buffer_size, "Unknown reply type %i", (int)r.reply_type);
}
return buffer;
amqp_queue_declare_ok_t *qd_ret;
amqp_basic_consume_ok_t *cm_ret;
- qd_ret = amqp_queue_declare(conf->connection,
- /* channel = */ CAMQP_CHANNEL,
- /* queue = */ (conf->queue != NULL)
- ? amqp_cstring_bytes(conf->queue)
- : AMQP_EMPTY_BYTES,
- /* passive = */ 0,
- /* durable = */ conf->queue_durable,
- /* exclusive = */ 0,
- /* auto_delete = */ conf->queue_auto_delete,
- /* arguments = */ AMQP_EMPTY_TABLE);
+ qd_ret =
+ amqp_queue_declare(conf->connection,
+ /* channel = */ CAMQP_CHANNEL,
+ /* queue = */
+ (conf->queue != NULL) ? amqp_cstring_bytes(conf->queue)
+ : AMQP_EMPTY_BYTES,
+ /* passive = */ 0,
+ /* durable = */ conf->queue_durable,
+ /* exclusive = */ 0,
+ /* auto_delete = */ conf->queue_auto_delete,
+ /* arguments = */ AMQP_EMPTY_TABLE);
if (qd_ret == NULL) {
ERROR("amqp plugin: amqp_queue_declare failed.");
camqp_close_connection(conf);
amqp_queue_bind_ok_t *qb_ret;
assert(conf->queue != NULL);
- qb_ret =
- amqp_queue_bind(conf->connection,
- /* channel = */ CAMQP_CHANNEL,
- /* queue = */ amqp_cstring_bytes(conf->queue),
- /* exchange = */ amqp_cstring_bytes(conf->exchange),
- /* routing_key = */ (conf->routing_key != NULL)
- ? amqp_cstring_bytes(conf->routing_key)
- : AMQP_EMPTY_BYTES,
- /* arguments = */ AMQP_EMPTY_TABLE);
+ qb_ret = amqp_queue_bind(
+ conf->connection,
+ /* channel = */ CAMQP_CHANNEL,
+ /* queue = */ amqp_cstring_bytes(conf->queue),
+ /* exchange = */ amqp_cstring_bytes(conf->exchange),
+ /* routing_key = */
+ (conf->routing_key != NULL) ? amqp_cstring_bytes(conf->routing_key)
+ : AMQP_EMPTY_BYTES,
+ /* arguments = */ AMQP_EMPTY_TABLE);
if ((qb_ret == NULL) && camqp_is_error(conf)) {
char errbuf[1024];
ERROR("amqp plugin: amqp_queue_bind failed: %s",
#ifdef HAVE_AMQP_TCP_SOCKET
#define CLOSE_SOCKET() /* amqp_destroy_connection() closes the socket for us \
- */
+ */
/* TODO: add support for SSL using amqp_ssl_socket_new
* and related functions */
socket = amqp_tcp_socket_new(conf->connection);
if (conf->routing_key != NULL) {
sstrncpy(routing_key, conf->routing_key, sizeof(routing_key));
} else {
- snprintf(routing_key, sizeof(routing_key), "collectd/%s/%s/%s/%s/%s",
- vl->host, vl->plugin, vl->plugin_instance, vl->type,
- vl->type_instance);
+ ssnprintf(routing_key, sizeof(routing_key), "collectd/%s/%s/%s/%s/%s",
+ vl->host, vl->plugin, vl->plugin_instance, vl->type,
+ vl->type_instance);
/* Switch slashes (the only character forbidden by collectd) and dots
* (the separation character used by AMQP). */
if (publish) {
char cbname[128];
- snprintf(cbname, sizeof(cbname), "amqp/%s", conf->name);
+ ssnprintf(cbname, sizeof(cbname), "amqp/%s", conf->name);
- status =
- plugin_register_write(cbname, camqp_write,
- &(user_data_t){
- .data = conf, .free_func = camqp_config_free,
- });
+ status = plugin_register_write(cbname, camqp_write,
+ &(user_data_t){
+ .data = conf,
+ .free_func = camqp_config_free,
+ });
if (status != 0) {
camqp_config_free(conf);
return status;
else if (strcasecmp("Format", child->key) == 0) {
char *key = NULL;
status = cf_util_get_string(child, &key);
- if (status != 0)
+ if (status != 0) {
+ amqp1_config_instance_free(instance);
return status;
+ }
assert(key != NULL);
if (strcasecmp(key, "Command") == 0) {
instance->format = AMQP1_FORMAT_COMMAND;
return status;
} else {
char tpname[DATA_MAX_NAME_LEN];
- status = snprintf(tpname, sizeof(tpname), "amqp1/%s", instance->name);
+ status = ssnprintf(tpname, sizeof(tpname), "amqp1/%s", instance->name);
if ((status < 0) || (size_t)status >= sizeof(tpname)) {
ERROR("amqp1 plugin: Instance name would have been truncated.");
+ amqp1_config_instance_free(instance);
return -1;
}
- status = snprintf(instance->send_to, sizeof(instance->send_to), "/%s/%s",
- transport->address, instance->name);
+ status = ssnprintf(instance->send_to, sizeof(instance->send_to), "/%s/%s",
+ transport->address, instance->name);
if ((status < 0) || (size_t)status >= sizeof(instance->send_to)) {
ERROR("amqp1 plugin: send_to address would have been truncated.");
+ amqp1_config_instance_free(instance);
return -1;
}
if (instance->notify) {
status = plugin_register_notification(
tpname, amqp1_notify,
&(user_data_t){
- .data = instance, .free_func = amqp1_config_instance_free,
+ .data = instance,
+ .free_func = amqp1_config_instance_free,
});
} else {
- status = plugin_register_write(
- tpname, amqp1_write,
- &(user_data_t){
- .data = instance, .free_func = amqp1_config_instance_free,
- });
+ status =
+ plugin_register_write(tpname, amqp1_write,
+ &(user_data_t){
+ .data = instance,
+ .free_func = amqp1_config_instance_free,
+ });
}
if (status != 0) {
/* callback = */ apache_read_host,
/* interval = */ 0,
&(user_data_t){
- .data = st, .free_func = apache_free,
+ .data = st,
+ .free_func = apache_free,
});
} /* int config_add */
if (value_array[i] == AQ5_FLOAT_UNDEF)
continue;
- snprintf(type_instance, sizeof(type_instance), "%s%d", type_instance_prefix,
- i + 1);
+ ssnprintf(type_instance, sizeof(type_instance), "%s%d",
+ type_instance_prefix, i + 1);
aquaero_submit(type, type_instance, value_array[i]);
}
}
(aq_data.fan_vrm_temp[i] != AQ5_FLOAT_UNDEF))
continue;
- snprintf(type_instance, sizeof(type_instance), "fan%d", i + 1);
+ ssnprintf(type_instance, sizeof(type_instance), "fan%d", i + 1);
aquaero_submit("fanspeed", type_instance, aq_data.fan_rpm[i]);
aquaero_submit("percent", type_instance, aq_data.fan_duty[i]);
/* Report the voltage reglator module (VRM) temperature with a
* different type instance. */
- snprintf(type_instance, sizeof(type_instance), "fan%d-vrm", i + 1);
+ ssnprintf(type_instance, sizeof(type_instance), "fan%d-vrm", i + 1);
aquaero_submit("temperature", type_instance, aq_data.fan_vrm_temp[i]);
}
static char credentials[1024];
int status;
- status = snprintf(credentials, sizeof(credentials), "%s:%s", user,
- (pass == NULL) ? "" : pass);
+ status = ssnprintf(credentials, sizeof(credentials), "%s:%s", user,
+ (pass == NULL) ? "" : pass);
if ((status < 0) || ((size_t)status >= sizeof(credentials))) {
ERROR("ascent plugin: ascent_init: Returning an error because the "
"credentials have been truncated.");
} else if (strcasecmp(key, "Normalization") == 0) {
int normalize_tmp = atoi(value);
if (normalize_tmp < 0 || normalize_tmp > 2) {
- WARNING("barometer: collectd_barometer_config: invalid normalization: %d",
- normalize_tmp);
+ ERROR("barometer: collectd_barometer_config: invalid normalization: %d",
+ normalize_tmp);
return 1;
}
config_normalize = normalize_tmp;
return 0;
} /* }}} int battery_read */
-/* #endif HAVE_IOKIT_IOKITLIB_H || HAVE_IOKIT_PS_IOPOWERSOURCES_H */
+ /* #endif HAVE_IOKIT_IOKITLIB_H || HAVE_IOKIT_PS_IOPOWERSOURCES_H */
#elif KERNEL_LINUX
/* Reads a file which contains only a number (and optionally a trailing
snprintf(filename, sizeof(filename), "%s/%s/%s", dir, power_supply, basename);
- status = (int)read_file_contents(filename, buffer, buffer_size - 1);
+ status = (int)read_text_file_contents(filename, buffer, buffer_size);
if (status < 0)
return status;
- buffer[status] = '\0';
-
strstripnewline(buffer);
return 0;
} /* }}} int sysfs_file_to_buffer */
curl_easy_setopt(curl, CURLOPT_MAXREDIRS, 50L);
#ifdef HAVE_CURLOPT_TIMEOUT_MS
curl_easy_setopt(curl, CURLOPT_TIMEOUT_MS,
- (timeout >= 0) ? (long)timeout : (long)CDTIME_T_TO_MS(
- plugin_get_interval()));
+ (timeout >= 0)
+ ? (long)timeout
+ : (long)CDTIME_T_TO_MS(plugin_get_interval()));
#endif
return 0;
return err;
}
address.sun_family = AF_UNIX;
- snprintf(address.sun_path, sizeof(address.sun_path), "%s", io->d->asok_path);
+ ssnprintf(address.sun_path, sizeof(address.sun_path), "%s", io->d->asok_path);
RETRY_ON_EINTR(err, connect(fd, (struct sockaddr *)&address,
sizeof(struct sockaddr_un)));
if (err < 0) {
return -EDOM;
case CSTATE_WRITE_REQUEST: {
char cmd[32];
- snprintf(cmd, sizeof(cmd), "%s%d%s", "{ \"prefix\": \"", io->request_type,
- "\" }\n");
+ ssnprintf(cmd, sizeof(cmd), "%s%d%s", "{ \"prefix\": \"", io->request_type,
+ "\" }\n");
size_t cmd_len = strlen(cmd);
RETRY_ON_EINTR(
ret, write(io->asok, ((char *)&cmd) + io->amt, cmd_len - io->amt));
--- /dev/null
+/**
+ * collectd - src/check_uptime.c
+ * Copyright (C) 2007-2019 Florian Forster
+ * Copyright (C) 2019 Pavel V. Rochnyack
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; only version 2 of the License is applicable.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Author:
+ * Florian octo Forster <octo at collectd.org>
+ * Pavel Rochnyak <pavel2000 ngs.ru>
+ **/
+
+#include "collectd.h"
+#include "plugin.h"
+#include "utils/avltree/avltree.h"
+#include "utils/common/common.h"
+#include "utils_cache.h"
+
+/* Types are registered only in `config` phase, so access is not protected by
+ * locks */
+c_avl_tree_t *types_tree = NULL;
+
+static int format_uptime(unsigned long uptime_sec, char *buf, size_t bufsize) {
+
+ unsigned int uptime_days = uptime_sec / 24 / 3600;
+ uptime_sec -= uptime_days * 24 * 3600;
+ unsigned int uptime_hours = uptime_sec / 3600;
+ uptime_sec -= uptime_hours * 3600;
+ unsigned int uptime_mins = uptime_sec / 60;
+ uptime_sec -= uptime_mins * 60;
+
+ int ret = 0;
+ if (uptime_days) {
+ ret += snprintf(buf + ret, bufsize - ret, " %u day(s)", uptime_days);
+ }
+ if (uptime_days || uptime_hours) {
+ ret += snprintf(buf + ret, bufsize - ret, " %u hour(s)", uptime_hours);
+ }
+ if (uptime_days || uptime_hours || uptime_mins) {
+ ret += snprintf(buf + ret, bufsize - ret, " %u min", uptime_mins);
+ }
+ ret += snprintf(buf + ret, bufsize - ret, " %lu sec.", uptime_sec);
+ return ret;
+}
+
+static int cu_notify(enum cache_event_type_e event_type, const value_list_t *vl,
+ gauge_t old_uptime, gauge_t new_uptime) {
+ notification_t n;
+ NOTIFICATION_INIT_VL(&n, vl);
+
+ int status;
+ char *buf = n.message;
+ size_t bufsize = sizeof(n.message);
+
+ n.time = vl->time;
+
+ const char *service = "Service";
+ if (strcmp(vl->plugin, "uptime") == 0)
+ service = "Host";
+
+ switch (event_type) {
+ case CE_VALUE_NEW:
+ n.severity = NOTIF_OKAY;
+ status = snprintf(buf, bufsize, "%s is running.", service);
+ buf += status;
+ bufsize -= status;
+ break;
+ case CE_VALUE_UPDATE:
+ n.severity = NOTIF_WARNING;
+ status = snprintf(buf, bufsize, "%s just restarted.", service);
+ buf += status;
+ bufsize -= status;
+ break;
+ case CE_VALUE_EXPIRED:
+ n.severity = NOTIF_FAILURE;
+ status = snprintf(buf, bufsize, "%s is unreachable.", service);
+ buf += status;
+ bufsize -= status;
+ break;
+ }
+
+ if (!isnan(old_uptime)) {
+ status = snprintf(buf, bufsize, " Uptime was:");
+ buf += status;
+ bufsize -= status;
+
+ status = format_uptime(old_uptime, buf, bufsize);
+ buf += status;
+ bufsize -= status;
+
+ plugin_notification_meta_add_double(&n, "LastValue", old_uptime);
+ }
+
+ if (!isnan(new_uptime)) {
+ status = snprintf(buf, bufsize, " Uptime now:");
+ buf += status;
+ bufsize -= status;
+
+ status = format_uptime(new_uptime, buf, bufsize);
+ buf += status;
+ bufsize -= status;
+
+ plugin_notification_meta_add_double(&n, "CurrentValue", new_uptime);
+ }
+
+ plugin_dispatch_notification(&n);
+
+ plugin_notification_meta_free(n.meta);
+ return 0;
+}
+
+static int cu_cache_event(cache_event_t *event,
+ __attribute__((unused)) user_data_t *ud) {
+ gauge_t values_history[2];
+
+ /* For CE_VALUE_EXPIRED */
+ int ret;
+ value_t *values;
+ size_t values_num;
+ gauge_t old_uptime = NAN;
+
+ switch (event->type) {
+ case CE_VALUE_NEW:
+ DEBUG("check_uptime: CE_VALUE_NEW, %s", event->value_list_name);
+ if (c_avl_get(types_tree, event->value_list->type, NULL) == 0) {
+ event->ret = 1;
+ assert(event->value_list->values_len > 0);
+ cu_notify(CE_VALUE_NEW, event->value_list, NAN /* old */,
+ event->value_list->values[0].gauge /* new */);
+ }
+ break;
+ case CE_VALUE_UPDATE:
+ DEBUG("check_uptime: CE_VALUE_UPDATE, %s", event->value_list_name);
+ if (uc_get_history_by_name(event->value_list_name, values_history, 2, 1)) {
+ ERROR("check_uptime plugin: Failed to get value history for %s.",
+ event->value_list_name);
+ } else {
+ if (!isnan(values_history[0]) && !isnan(values_history[1]) &&
+ values_history[0] < values_history[1]) {
+ cu_notify(CE_VALUE_UPDATE, event->value_list,
+ values_history[1] /* old */, values_history[0] /* new */);
+ }
+ }
+ break;
+ case CE_VALUE_EXPIRED:
+ DEBUG("check_uptime: CE_VALUE_EXPIRED, %s", event->value_list_name);
+ ret = uc_get_value_by_name(event->value_list_name, &values, &values_num);
+ if (ret == 0) {
+ old_uptime = values[0].gauge;
+ sfree(values);
+ }
+
+ cu_notify(CE_VALUE_EXPIRED, event->value_list, old_uptime, NAN /* new */);
+ break;
+ }
+ return 0;
+}
+
+static int cu_config(oconfig_item_t *ci) {
+ if (types_tree == NULL) {
+ types_tree = c_avl_create((int (*)(const void *, const void *))strcmp);
+ if (types_tree == NULL) {
+ ERROR("check_uptime plugin: c_avl_create failed.");
+ return -1;
+ }
+ }
+
+ for (int i = 0; i < ci->children_num; ++i) {
+ oconfig_item_t *child = ci->children + i;
+ if (strcasecmp("Type", child->key) == 0) {
+ if ((child->values_num != 1) ||
+ (child->values[0].type != OCONFIG_TYPE_STRING)) {
+ WARNING("check_uptime plugin: The `Type' option needs exactly one "
+ "string argument.");
+ return -1;
+ }
+ char *type = child->values[0].value.string;
+
+ if (c_avl_get(types_tree, type, NULL) == 0) {
+ ERROR("check_uptime plugin: Type `%s' already added.", type);
+ return -1;
+ }
+
+ char *type_copy = strdup(type);
+ if (type_copy == NULL) {
+ ERROR("check_uptime plugin: strdup failed.");
+ return -1;
+ }
+
+ int status = c_avl_insert(types_tree, type_copy, NULL);
+ if (status != 0) {
+ ERROR("check_uptime plugin: c_avl_insert failed.");
+ sfree(type_copy);
+ return -1;
+ }
+ } else
+ WARNING("check_uptime plugin: Ignore unknown config option `%s'.",
+ child->key);
+ }
+
+ return 0;
+}
+
+static int cu_init(void) {
+ if (types_tree == NULL) {
+ types_tree = c_avl_create((int (*)(const void *, const void *))strcmp);
+ if (types_tree == NULL) {
+ ERROR("check_uptime plugin: c_avl_create failed.");
+ return -1;
+ }
+ /* Default configuration */
+ char *type = strdup("uptime");
+ if (type == NULL) {
+ ERROR("check_uptime plugin: strdup failed.");
+ return -1;
+ }
+ int status = c_avl_insert(types_tree, type, NULL);
+ if (status != 0) {
+ ERROR("check_uptime plugin: c_avl_insert failed.");
+ sfree(type);
+ return -1;
+ }
+ }
+
+ int ret = 0;
+ char *type;
+ void *val;
+ c_avl_iterator_t *iter = c_avl_get_iterator(types_tree);
+ while (c_avl_iterator_next(iter, (void *)&type, (void *)&val) == 0) {
+ data_set_t const *ds = plugin_get_ds(type);
+ if (ds == NULL) {
+ ERROR("check_uptime plugin: Failed to look up type \"%s\".", type);
+ ret = -1;
+ continue;
+ }
+ if (ds->ds_num != 1) {
+ ERROR("check_uptime plugin: The type \"%s\" has %" PRIsz " data sources. "
+ "Only types with a single GAUGE data source are supported.",
+ ds->type, ds->ds_num);
+ ret = -1;
+ continue;
+ }
+ if (ds->ds[0].type != DS_TYPE_GAUGE) {
+ ERROR("check_uptime plugin: The type \"%s\" has wrong data source type. "
+ "Only types with a single GAUGE data source are supported.",
+ ds->type);
+ ret = -1;
+ continue;
+ }
+ }
+ c_avl_iterator_destroy(iter);
+
+ if (ret == 0)
+ plugin_register_cache_event("check_uptime", cu_cache_event, NULL);
+
+ return ret;
+}
+
+void module_register(void) {
+ plugin_register_complex_config("check_uptime", cu_config);
+ plugin_register_init("check_uptime", cu_init);
+}
#define ATTRIB_PACKED
#endif
-typedef struct ATTRIB_PACKED { int32_t value; } tFloat;
+typedef struct ATTRIB_PACKED {
+ int32_t value;
+} tFloat;
typedef struct ATTRIB_PACKED {
uint32_t tv_sec_high;
Amplification) */
} tChrony_Req_Tracking;
-typedef struct ATTRIB_PACKED { uint32_t f_n_sources; } tChrony_Req_N_Sources;
+typedef struct ATTRIB_PACKED {
+ uint32_t f_n_sources;
+} tChrony_Req_N_Sources;
typedef struct ATTRIB_PACKED {
int32_t f_index;
} tChrony_Request;
/* Chrony daemon response packets */
-typedef struct ATTRIB_PACKED { uint32_t f_n_sources; } tChrony_Resp_N_Sources;
+typedef struct ATTRIB_PACKED {
+ uint32_t f_n_sources;
+} tChrony_Resp_N_Sources;
typedef struct ATTRIB_PACKED {
union {
The number of times that a query should be retried after the Timeout expires.
The C<Net-SNMP> library default is 5.
+=item B<BulkSize> I<Integer>
+
+Configures the size of SNMP bulk transfers. The default is 0, which disables bulk transfers altogether.
+
=back
=head1 SEE ALSO
#@BUILD_PLUGIN_CEPH_TRUE@LoadPlugin ceph
#@BUILD_PLUGIN_CGROUPS_TRUE@LoadPlugin cgroups
#@BUILD_PLUGIN_CHRONY_TRUE@LoadPlugin chrony
+#@BUILD_PLUGIN_CHECK_UPTIME_TRUE@LoadPlugin check_uptime
+#@BUILD_PLUGIN_CONNECTIVITY_TRUE@LoadPlugin connectivity
#@BUILD_PLUGIN_CONNTRACK_TRUE@LoadPlugin conntrack
#@BUILD_PLUGIN_CONTEXTSWITCH_TRUE@LoadPlugin contextswitch
@BUILD_PLUGIN_CPU_TRUE@@BUILD_PLUGIN_CPU_TRUE@LoadPlugin cpu
@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
#@BUILD_PLUGIN_MCELOG_TRUE@LoadPlugin mcelog
#@BUILD_PLUGIN_POSTGRESQL_TRUE@LoadPlugin postgresql
#@BUILD_PLUGIN_POWERDNS_TRUE@LoadPlugin powerdns
#@BUILD_PLUGIN_PROCESSES_TRUE@LoadPlugin processes
+#@BUILD_PLUGIN_PROCEVENT_TRUE@LoadPlugin procevent
#@BUILD_PLUGIN_PROTOCOLS_TRUE@LoadPlugin protocols
#@BUILD_PLUGIN_PYTHON_TRUE@LoadPlugin python
#@BUILD_PLUGIN_REDIS_TRUE@LoadPlugin redis
#@BUILD_PLUGIN_SNMP_AGENT_TRUE@LoadPlugin snmp_agent
#@BUILD_PLUGIN_STATSD_TRUE@LoadPlugin statsd
#@BUILD_PLUGIN_SWAP_TRUE@LoadPlugin swap
+#@BUILD_PLUGIN_SYSEVENT_TRUE@LoadPlugin sysevent
#@BUILD_PLUGIN_TABLE_TRUE@LoadPlugin table
#@BUILD_PLUGIN_TAIL_TRUE@LoadPlugin tail
#@BUILD_PLUGIN_TAIL_CSV_TRUE@LoadPlugin tail_csv
# Timeout "2"
#</Plugin>
+#<Plugin connectivity>
+# Interface eth0
+#</Plugin>
+
#<Plugin cgroups>
# CGroup "libvirt"
# IgnoreSelected false
# </Process>
#</Plugin>
+#<Plugin "procevent">
+# BufferLength 10
+# ProcessRegex "/^ovs.*$/"
+# Process tuned
+#</Plugin>
+
#<Plugin protocols>
# Value "/^Tcp:/"
# IgnoreSelected false
# Version 2
# Community "another_string"
# Collect "std_traffic" "hr_users"
+# BulkSize 0
# </Host>
# <Host "some.ups.mydomain.org">
# Address "192.168.0.3"
# Timeout 5
# Retries 5
# </Host>
+# <Host "highend.switch.example.org">
+# Address "192.168.0.3"
+# Version 2
+# Community "another_string"
+# Collect "std_traffic"
+# Interval 10
+# Timeout 10
+# BulkSize 100
+# </Host>
#</Plugin>
#<Plugin snmp_agent>
# ReportIO true
#</Plugin>
+#<Plugin sysevent>
+# Listen "127.0.0.1" "6666"
+# BufferSize 1024
+# BufferLength 10
+# RegexFilter "regex"
+#</Plugin>
+
#<Plugin table>
# <Table "/proc/slabinfo">
# #Plugin "table"
=back
+=head2 Plugin C<check_uptime>
+
+The I<check_uptime plugin> designed to check and notify about host or service
+status based on I<uptime> metric.
+
+When new metric of I<uptime> type appears in cache, OK notification is sent.
+When new value for metric is less than previous value, WARNING notification is
+sent about host/service restart.
+When no new updates comes for metric and cache entry expires, then FAILURE
+notification is sent about unreachable host or service.
+
+By default (when no explicit configuration), plugin checks for I<uptime> metric.
+
+B<Synopsis:>
+
+ <Plugin "check_uptime">
+ Type "uptime"
+ Type "my_uptime_type"
+ </Plugin>
+
+=over 4
+
+=item B<Type> I<Type>
+
+Metric type to check for status/values. The type should consist single GAUGE
+data source.
+
+=back
+
=head2 Plugin C<chrony>
The C<chrony> plugin collects ntp data from a B<chronyd> server, such as clock
=back
+=head2 Plugin Connectivity
+
+connectivity - Documentation of collectd's C<connectivity plugin>
+
+
+ LoadPlugin connectivity
+ # ...
+ <Plugin connectivity>
+ Interface eth0
+ </Plugin>
+
+The C<connectivity plugin> queries interface status using netlink (man 7 netlink) which provides information about network interfaces via the NETLINK_ROUTE family (man 7 rtnetlink). The plugin translates the value it receives to collectd's internal format and, depending on the write plugins you have loaded, it may be written to disk or submitted to another instance.
+The plugin listens to interfaces enumerated within the plugin configuration (see below). If no interfaces are listed, then the default is for all interfaces to be monitored.
+
+This example shows C<connectivity plugin> monitoring all interfaces.
+LoadPlugin connectivity
+<Plugin connectivity>
+</Plugin>
+
+This example shows C<connectivity plugin> monitoring 2 interfaces, "eth0" and "eth1".
+LoadPlugin connectivity
+<Plugin connectivity>
+ Interface eth0
+ Interface eth1
+</Plugin>
+
+This example shows C<connectivity plugin> monitoring all interfaces except "eth1".
+LoadPlugin connectivity
+<Plugin connectivity>
+ Interface eth1
+ IgnoreSelected true
+</Plugin>
+
+=over 4
+
+=item B<Interface> I<interface_name>
+
+interface(s) to monitor connect to.
+
+=back
+
=head2 Plugin C<conntrack>
This plugin collects IP conntrack statistics.
Username to use when connecting to the database. The user does not have to be
granted any privileges (which is synonym to granting the C<USAGE> privilege),
-unless you want to collectd replication statistics (see B<MasterStats> and
+unless you want to collect replication statistics (see B<MasterStats> and
B<SlaveStats> below). In this case, the user needs the C<REPLICATION CLIENT>
(or C<SUPER>) privileges. Else, any existing MySQL user will do.
=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'
+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'.
+Defaults to B<false>.
=item B<ConnectTimeout> I<Seconds>
B<ProcessMatch> blocks these options set the default value for subsequent
matches.
+=head2 Plugin C<procevent>
+
+The I<procevent> plugin monitors when processes start (EXEC) and stop (EXIT).
+
+B<Synopsis:>
+
+ <Plugin procevent>
+ BufferLength 10
+ Process "name"
+ ProcessRegex "regex"
+ </Plugin>
+
+B<Options:>
+
+=over 4
+
+=item B<BufferLength> I<length>
+
+Maximum number of process events that can be stored in plugin's ring buffer.
+By default, this is set to 10. Once an event has been read, its location
+becomes available for storing a new event.
+
+=item B<Process> I<name>
+
+Enumerate a process name to monitor. All processes that match this exact
+name will be monitored for EXECs and EXITs.
+
+=item B<ProcessRegex> I<regex>
+
+Enumerate a process pattern to monitor. All processes that match this
+regular expression will be monitored for EXECs and EXITs.
+
+=back
+
=head2 Plugin C<protocols>
Collects a lot of information about various network protocols, such as I<IP>,
=back
+=head2 Plugin C<sysevent>
+
+The I<sysevent> plugin monitors rsyslog messages.
+
+B<Synopsis:>
+
+ <Plugin sysevent>
+ Listen "192.168.0.2" "6666"
+ BufferSize 1024
+ BufferLength 10
+ RegexFilter "regex"
+ </Plugin>
+
+ rsyslog should be configured such that it sends data to the IP and port you
+ include in the plugin configuration. For example, given the configuration
+ above, something like this would be set in /etc/rsyslog.conf:
+
+ if $programname != 'collectd' then
+ *.* @192.168.0.2:6666
+
+ This plugin is designed to consume JSON rsyslog data, so a more complete
+ rsyslog configuration would look like so (where we define a JSON template
+ and use it when sending data to our IP and port):
+
+ $template ls_json,"{%timestamp:::date-rfc3339,jsonf:@timestamp%, \
+ %source:::jsonf:@source_host%,\"@source\":\"syslog://%fromhost-ip:::json%\", \
+ \"@message\":\"%timestamp% %app-name%:%msg:::json%\",\"@fields\": \
+ {%syslogfacility-text:::jsonf:facility%,%syslogseverity:::jsonf:severity-num%, \
+ %syslogseverity-text:::jsonf:severity%,%programname:::jsonf:program%, \
+ %procid:::jsonf:processid%}}"
+
+ if $programname != 'collectd' then
+ *.* @192.168.0.2:6666;ls_json
+
+ Please note that these rsyslog.conf examples are *not* complete, as rsyslog
+ requires more than these options in the configuration file. These examples
+ are meant to demonstration the proper remote logging and JSON format syntax.
+
+B<Options:>
+
+=over 4
+
+=item B<Listen> I<host> I<port>
+
+Listen on this IP on this port for incoming rsyslog messages.
+
+=item B<BufferSize> I<length>
+
+Maximum allowed size for incoming rsyslog messages. Messages that exceed
+this number will be truncated to this size. Default is 4096 bytes.
+
+=item B<BufferLength> I<length>
+
+Maximum number of rsyslog events that can be stored in plugin's ring buffer.
+By default, this is set to 10. Once an event has been read, its location
+becomes available for storing a new event.
+
+=item B<RegexFilter> I<regex>
+
+Enumerate a regex filter to apply to all incoming rsyslog messages. If a
+message matches this filter, it will be published.
+
+=back
+
=head2 Plugin C<syslog>
=over 4
#include "config.h"
#endif
+#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
extern char *optarg;
extern int optind;
+/* _ssnprintf returns result from vsnprintf (consistent with snprintf) */
+static int _ssnprintf(char *str, size_t sz, const char *format, ...) {
+ va_list ap;
+ va_start(ap, format);
+
+ int ret = vsnprintf(str, sz, format, ap);
+
+ va_end(ap);
+
+ return ret;
+} /* int _ssnprintf */
+
__attribute__((noreturn)) static void exit_usage(const char *name, int status) {
fprintf(
(status == 0) ? stdout : stderr,
}
hostname[sizeof(hostname) - 1] = '\0';
- snprintf(ident_str, sizeof(ident_str), "%s/%s", hostname, value);
+ _ssnprintf(ident_str, sizeof(ident_str), "%s/%s", hostname, value);
ident_str[sizeof(ident_str) - 1] = '\0';
} else {
strncpy(ident_str, value, sizeof(ident_str));
value);
BAIL_OUT(-1);
} else if ((endptr != NULL) && (*endptr != '\0')) {
- fprintf(stderr, "WARNING: Ignoring trailing garbage after timeout: "
- "%s.\n",
+ fprintf(stderr,
+ "WARNING: Ignoring trailing garbage after timeout: "
+ "%s.\n",
endptr);
}
} else if (strcasecmp(key, "plugin") == 0) {
char id[1024];
lcc_identifier_to_string(c, id, sizeof(id), identifiers + j);
- fprintf(stderr, "ERROR: Failed to flush plugin `%s', "
- "identifier `%s': %s.\n",
+ fprintf(stderr,
+ "ERROR: Failed to flush plugin `%s', "
+ "identifier `%s': %s.\n",
(plugins[i] == NULL) ? "(all)" : plugins[i], id,
lcc_strerror(c));
}
status = lcc_identifier_to_string(c, id, sizeof(id), ret_ident + i);
if (status != 0) {
- fprintf(stderr, "ERROR: listval: Failed to convert returned "
- "identifier to a string: %s\n",
+ fprintf(stderr,
+ "ERROR: listval: Failed to convert returned "
+ "identifier to a string: %s\n",
lcc_strerror(c));
continue;
}
value);
return -1;
} else if ((endptr != NULL) && (*endptr != '\0')) {
- fprintf(stderr, "WARNING: Ignoring trailing garbage after "
- "interval: %s.\n",
+ fprintf(stderr,
+ "WARNING: Ignoring trailing garbage after "
+ "interval: %s.\n",
endptr);
}
} else {
switch (opt) {
case 's':
- snprintf(address, sizeof(address), "unix:%s", optarg);
+ _ssnprintf(address, sizeof(address), "unix:%s", optarg);
address[sizeof(address) - 1] = '\0';
break;
case 'h':
if (counter >= 10) {
unsigned int time_left = 300;
- syslog(LOG_ERR, "Error: collectd is respawning too fast - "
- "disabled for %i seconds",
+ syslog(LOG_ERR,
+ "Error: collectd is respawning too fast - "
+ "disabled for %i seconds",
time_left);
while (((time_left = sleep(time_left)) > 0) && loop == 0)
}
struct sigaction sa = {
- .sa_handler = sig_int_term_handler, .sa_flags = 0,
+ .sa_handler = sig_int_term_handler,
+ .sa_flags = 0,
};
sigemptyset(&sa.sa_mask);
--- /dev/null
+/**
+ * collectd - src/connectivity.c
+ *
+ * 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:
+ * Red Hat NFVPE
+ * Andrew Bays <abays at redhat.com>
+ * Aneesh Puttur <aputtur at redhat.com>
+ **/
+
+#include "collectd.h"
+
+#include "plugin.h"
+#include "utils/common/common.h"
+#include "utils/ignorelist/ignorelist.h"
+#include "utils_complain.h"
+
+#include <asm/types.h>
+#include <errno.h>
+#include <net/if.h>
+#include <netinet/in.h>
+#include <pthread.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/socket.h>
+#include <unistd.h>
+
+#include <libmnl/libmnl.h>
+#include <linux/netlink.h>
+#include <linux/rtnetlink.h>
+
+#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
+
+#define MYPROTO NETLINK_ROUTE
+
+#define LINK_STATE_DOWN 0
+#define LINK_STATE_UP 1
+#define LINK_STATE_UNKNOWN 2
+
+#define CONNECTIVITY_DOMAIN_FIELD "domain"
+#define CONNECTIVITY_DOMAIN_VALUE "stateChange"
+#define CONNECTIVITY_EVENT_ID_FIELD "eventId"
+#define CONNECTIVITY_EVENT_NAME_FIELD "eventName"
+#define CONNECTIVITY_EVENT_NAME_DOWN_VALUE "down"
+#define CONNECTIVITY_EVENT_NAME_UP_VALUE "up"
+#define CONNECTIVITY_LAST_EPOCH_MICROSEC_FIELD "lastEpochMicrosec"
+#define CONNECTIVITY_PRIORITY_FIELD "priority"
+#define CONNECTIVITY_PRIORITY_VALUE "high"
+#define CONNECTIVITY_REPORTING_ENTITY_NAME_FIELD "reportingEntityName"
+#define CONNECTIVITY_REPORTING_ENTITY_NAME_VALUE "collectd connectivity plugin"
+#define CONNECTIVITY_SEQUENCE_FIELD "sequence"
+#define CONNECTIVITY_SEQUENCE_VALUE "0"
+#define CONNECTIVITY_SOURCE_NAME_FIELD "sourceName"
+#define CONNECTIVITY_START_EPOCH_MICROSEC_FIELD "startEpochMicrosec"
+#define CONNECTIVITY_VERSION_FIELD "version"
+#define CONNECTIVITY_VERSION_VALUE "1.0"
+
+#define CONNECTIVITY_NEW_STATE_FIELD "newState"
+#define CONNECTIVITY_NEW_STATE_FIELD_DOWN_VALUE "outOfService"
+#define CONNECTIVITY_NEW_STATE_FIELD_UP_VALUE "inService"
+#define CONNECTIVITY_OLD_STATE_FIELD "oldState"
+#define CONNECTIVITY_OLD_STATE_FIELD_DOWN_VALUE "outOfService"
+#define CONNECTIVITY_OLD_STATE_FIELD_UP_VALUE "inService"
+#define CONNECTIVITY_STATE_CHANGE_FIELDS_FIELD "stateChangeFields"
+#define CONNECTIVITY_STATE_CHANGE_FIELDS_VERSION_FIELD \
+ "stateChangeFieldsVersion"
+#define CONNECTIVITY_STATE_CHANGE_FIELDS_VERSION_VALUE "1.0"
+#define CONNECTIVITY_STATE_INTERFACE_FIELD "stateInterface"
+
+/*
+ * Private data types
+ */
+
+struct interface_list_s {
+ char *interface;
+
+ uint32_t status;
+ uint32_t prev_status;
+ uint32_t sent;
+ cdtime_t timestamp;
+
+ struct interface_list_s *next;
+};
+typedef struct interface_list_s interface_list_t;
+
+/*
+ * Private variables
+ */
+
+static ignorelist_t *ignorelist = NULL;
+
+static interface_list_t *interface_list_head = NULL;
+static int monitor_all_interfaces = 1;
+
+static int connectivity_netlink_thread_loop = 0;
+static int connectivity_netlink_thread_error = 0;
+static pthread_t connectivity_netlink_thread_id;
+static int connectivity_dequeue_thread_loop = 0;
+static pthread_t connectivity_dequeue_thread_id;
+static pthread_mutex_t connectivity_threads_lock = PTHREAD_MUTEX_INITIALIZER;
+static pthread_mutex_t connectivity_data_lock = PTHREAD_MUTEX_INITIALIZER;
+static pthread_cond_t connectivity_cond = PTHREAD_COND_INITIALIZER;
+static int nl_sock = -1;
+static int event_id = 0;
+static int statuses_to_send = 0;
+
+static const char *config_keys[] = {"Interface", "IgnoreSelected"};
+static int config_keys_num = STATIC_ARRAY_SIZE(config_keys);
+
+/*
+ * Private functions
+ */
+
+static int gen_message_payload(int state, int old_state, const char *interface,
+ cdtime_t timestamp, char **buf) {
+ const unsigned char *buf2;
+ yajl_gen g;
+ char json_str[DATA_MAX_NAME_LEN];
+
+#if !defined(HAVE_YAJL_V2)
+ yajl_gen_config conf = {0};
+#endif
+
+#if HAVE_YAJL_V2
+ size_t len;
+ g = yajl_gen_alloc(NULL);
+ yajl_gen_config(g, yajl_gen_beautify, 0);
+#else
+ unsigned int len;
+ g = yajl_gen_alloc(&conf, NULL);
+#endif
+
+ yajl_gen_clear(g);
+
+ // *** BEGIN common event header ***
+
+ if (yajl_gen_map_open(g) != yajl_gen_status_ok)
+ goto err;
+
+ // domain
+ if (yajl_gen_string(g, (u_char *)CONNECTIVITY_DOMAIN_FIELD,
+ strlen(CONNECTIVITY_DOMAIN_FIELD)) != yajl_gen_status_ok)
+ goto err;
+
+ if (yajl_gen_string(g, (u_char *)CONNECTIVITY_DOMAIN_VALUE,
+ strlen(CONNECTIVITY_DOMAIN_VALUE)) != yajl_gen_status_ok)
+ goto err;
+
+ // eventId
+ if (yajl_gen_string(g, (u_char *)CONNECTIVITY_EVENT_ID_FIELD,
+ strlen(CONNECTIVITY_EVENT_ID_FIELD)) !=
+ yajl_gen_status_ok)
+ goto err;
+
+ event_id = event_id + 1;
+ if (snprintf(json_str, sizeof(json_str), "%d", event_id) < 0) {
+ goto err;
+ }
+
+ if (yajl_gen_number(g, json_str, strlen(json_str)) != yajl_gen_status_ok) {
+ goto err;
+ }
+
+ // eventName
+ if (yajl_gen_string(g, (u_char *)CONNECTIVITY_EVENT_NAME_FIELD,
+ strlen(CONNECTIVITY_EVENT_NAME_FIELD)) !=
+ yajl_gen_status_ok)
+ goto err;
+
+ if (snprintf(json_str, sizeof(json_str), "interface %s %s", interface,
+ (state == 0 ? CONNECTIVITY_EVENT_NAME_DOWN_VALUE
+ : CONNECTIVITY_EVENT_NAME_UP_VALUE)) < 0) {
+ goto err;
+ }
+
+ if (yajl_gen_string(g, (u_char *)json_str, strlen(json_str)) !=
+ yajl_gen_status_ok) {
+ goto err;
+ }
+
+ // lastEpochMicrosec
+ if (yajl_gen_string(g, (u_char *)CONNECTIVITY_LAST_EPOCH_MICROSEC_FIELD,
+ strlen(CONNECTIVITY_LAST_EPOCH_MICROSEC_FIELD)) !=
+ yajl_gen_status_ok)
+ goto err;
+
+ if (snprintf(json_str, sizeof(json_str), "%" PRIu64,
+ CDTIME_T_TO_US(cdtime())) < 0) {
+ goto err;
+ }
+
+ if (yajl_gen_number(g, json_str, strlen(json_str)) != yajl_gen_status_ok) {
+ goto err;
+ }
+
+ // priority
+ if (yajl_gen_string(g, (u_char *)CONNECTIVITY_PRIORITY_FIELD,
+ strlen(CONNECTIVITY_PRIORITY_FIELD)) !=
+ yajl_gen_status_ok)
+ goto err;
+
+ if (yajl_gen_string(g, (u_char *)CONNECTIVITY_PRIORITY_VALUE,
+ strlen(CONNECTIVITY_PRIORITY_VALUE)) !=
+ yajl_gen_status_ok)
+ goto err;
+
+ // reportingEntityName
+ if (yajl_gen_string(g, (u_char *)CONNECTIVITY_REPORTING_ENTITY_NAME_FIELD,
+ strlen(CONNECTIVITY_REPORTING_ENTITY_NAME_FIELD)) !=
+ yajl_gen_status_ok)
+ goto err;
+
+ if (yajl_gen_string(g, (u_char *)CONNECTIVITY_REPORTING_ENTITY_NAME_VALUE,
+ strlen(CONNECTIVITY_REPORTING_ENTITY_NAME_VALUE)) !=
+ yajl_gen_status_ok)
+ goto err;
+
+ // sequence
+ if (yajl_gen_string(g, (u_char *)CONNECTIVITY_SEQUENCE_FIELD,
+ strlen(CONNECTIVITY_SEQUENCE_FIELD)) !=
+ yajl_gen_status_ok)
+ goto err;
+
+ if (yajl_gen_number(g, CONNECTIVITY_SEQUENCE_VALUE,
+ strlen(CONNECTIVITY_SEQUENCE_VALUE)) !=
+ yajl_gen_status_ok)
+ goto err;
+
+ // sourceName
+ if (yajl_gen_string(g, (u_char *)CONNECTIVITY_SOURCE_NAME_FIELD,
+ strlen(CONNECTIVITY_SOURCE_NAME_FIELD)) !=
+ yajl_gen_status_ok)
+ goto err;
+
+ if (yajl_gen_string(g, (u_char *)interface, strlen(interface)) !=
+ yajl_gen_status_ok)
+ goto err;
+
+ // startEpochMicrosec
+ if (yajl_gen_string(g, (u_char *)CONNECTIVITY_START_EPOCH_MICROSEC_FIELD,
+ strlen(CONNECTIVITY_START_EPOCH_MICROSEC_FIELD)) !=
+ yajl_gen_status_ok)
+ goto err;
+
+ if (snprintf(json_str, sizeof(json_str), "%" PRIu64,
+ CDTIME_T_TO_US(timestamp)) < 0) {
+ goto err;
+ }
+
+ if (yajl_gen_number(g, json_str, strlen(json_str)) != yajl_gen_status_ok) {
+ goto err;
+ }
+
+ // version
+ if (yajl_gen_string(g, (u_char *)CONNECTIVITY_VERSION_FIELD,
+ strlen(CONNECTIVITY_VERSION_FIELD)) != yajl_gen_status_ok)
+ goto err;
+
+ if (yajl_gen_number(g, CONNECTIVITY_VERSION_VALUE,
+ strlen(CONNECTIVITY_VERSION_VALUE)) != yajl_gen_status_ok)
+ goto err;
+
+ // *** END common event header ***
+
+ // *** BEGIN state change fields ***
+
+ if (yajl_gen_string(g, (u_char *)CONNECTIVITY_STATE_CHANGE_FIELDS_FIELD,
+ strlen(CONNECTIVITY_STATE_CHANGE_FIELDS_FIELD)) !=
+ yajl_gen_status_ok)
+ goto err;
+
+ if (yajl_gen_map_open(g) != yajl_gen_status_ok)
+ goto err;
+
+ // newState
+ if (yajl_gen_string(g, (u_char *)CONNECTIVITY_NEW_STATE_FIELD,
+ strlen(CONNECTIVITY_NEW_STATE_FIELD)) !=
+ yajl_gen_status_ok)
+ goto err;
+
+ int new_state_len =
+ (state == 0 ? strlen(CONNECTIVITY_NEW_STATE_FIELD_DOWN_VALUE)
+ : strlen(CONNECTIVITY_NEW_STATE_FIELD_UP_VALUE));
+
+ if (yajl_gen_string(g,
+ (u_char *)(state == 0
+ ? CONNECTIVITY_NEW_STATE_FIELD_DOWN_VALUE
+ : CONNECTIVITY_NEW_STATE_FIELD_UP_VALUE),
+ new_state_len) != yajl_gen_status_ok)
+ goto err;
+
+ // oldState
+ if (yajl_gen_string(g, (u_char *)CONNECTIVITY_OLD_STATE_FIELD,
+ strlen(CONNECTIVITY_OLD_STATE_FIELD)) !=
+ yajl_gen_status_ok)
+ goto err;
+
+ int old_state_len =
+ (old_state == 0 ? strlen(CONNECTIVITY_OLD_STATE_FIELD_DOWN_VALUE)
+ : strlen(CONNECTIVITY_OLD_STATE_FIELD_UP_VALUE));
+
+ if (yajl_gen_string(g,
+ (u_char *)(old_state == 0
+ ? CONNECTIVITY_OLD_STATE_FIELD_DOWN_VALUE
+ : CONNECTIVITY_OLD_STATE_FIELD_UP_VALUE),
+ old_state_len) != yajl_gen_status_ok)
+ goto err;
+
+ // stateChangeFieldsVersion
+ if (yajl_gen_string(g,
+ (u_char *)CONNECTIVITY_STATE_CHANGE_FIELDS_VERSION_FIELD,
+ strlen(CONNECTIVITY_STATE_CHANGE_FIELDS_VERSION_FIELD)) !=
+ yajl_gen_status_ok)
+ goto err;
+
+ if (yajl_gen_number(g, CONNECTIVITY_STATE_CHANGE_FIELDS_VERSION_VALUE,
+ strlen(CONNECTIVITY_STATE_CHANGE_FIELDS_VERSION_VALUE)) !=
+ yajl_gen_status_ok)
+ goto err;
+
+ // stateInterface
+ if (yajl_gen_string(g, (u_char *)CONNECTIVITY_STATE_INTERFACE_FIELD,
+ strlen(CONNECTIVITY_STATE_INTERFACE_FIELD)) !=
+ yajl_gen_status_ok)
+ goto err;
+
+ if (yajl_gen_string(g, (u_char *)interface, strlen(interface)) !=
+ yajl_gen_status_ok)
+ goto err;
+
+ // close state change and header fields
+ if (yajl_gen_map_close(g) != yajl_gen_status_ok ||
+ yajl_gen_map_close(g) != yajl_gen_status_ok)
+ goto err;
+
+ // *** END state change fields ***
+
+ if (yajl_gen_get_buf(g, &buf2, &len) != yajl_gen_status_ok)
+ goto err;
+
+ *buf = strdup((char *)buf2);
+
+ if (*buf == NULL) {
+ ERROR("connectivity plugin: strdup failed during gen_message_payload: %s",
+ STRERRNO);
+ goto err;
+ }
+
+ yajl_gen_free(g);
+
+ return 0;
+
+err:
+ yajl_gen_free(g);
+ ERROR("connectivity plugin: gen_message_payload failed to generate JSON");
+ return -1;
+}
+
+static interface_list_t *add_interface(const char *interface, int status,
+ int prev_status) {
+ interface_list_t *il = calloc(1, sizeof(*il));
+
+ if (il == NULL) {
+ ERROR("connectivity plugin: calloc failed during add_interface: %s",
+ STRERRNO);
+ return NULL;
+ }
+
+ char *interface2 = strdup(interface);
+ if (interface2 == NULL) {
+ sfree(il);
+ ERROR("connectivity plugin: strdup failed during add_interface: %s",
+ STRERRNO);
+ return NULL;
+ }
+
+ il->interface = interface2;
+ il->status = status;
+ il->prev_status = prev_status;
+ il->timestamp = cdtime();
+ il->sent = 0;
+ il->next = interface_list_head;
+ interface_list_head = il;
+
+ DEBUG("connectivity plugin: added interface %s", interface2);
+
+ return il;
+}
+
+static int connectivity_link_state(struct nlmsghdr *msg) {
+ pthread_mutex_lock(&connectivity_data_lock);
+
+ struct nlattr *attr;
+ struct ifinfomsg *ifi = mnl_nlmsg_get_payload(msg);
+
+ /* Scan attribute list for device name. */
+ mnl_attr_for_each(attr, msg, sizeof(*ifi)) {
+ if (mnl_attr_get_type(attr) != IFLA_IFNAME)
+ continue;
+
+ if (mnl_attr_validate(attr, MNL_TYPE_STRING) < 0) {
+ ERROR("connectivity plugin: connectivity_link_state: IFLA_IFNAME "
+ "mnl_attr_validate "
+ "failed.");
+ pthread_mutex_unlock(&connectivity_data_lock);
+ return MNL_CB_ERROR;
+ }
+
+ const char *dev = mnl_attr_get_str(attr);
+
+ // Check the list of interfaces we should monitor, if we've chosen
+ // a subset. If we don't care about this one, abort.
+ if (ignorelist_match(ignorelist, dev) != 0) {
+ DEBUG("connectivity plugin: Ignoring link state change for unmonitored "
+ "interface: %s",
+ dev);
+ break;
+ }
+
+ interface_list_t *il = NULL;
+
+ for (il = interface_list_head; il != NULL; il = il->next)
+ if (strcmp(dev, il->interface) == 0)
+ break;
+
+ if (il == NULL) {
+ // We haven't encountered this interface yet, so add it to the linked list
+ il = add_interface(dev, LINK_STATE_UNKNOWN, LINK_STATE_UNKNOWN);
+
+ if (il == NULL) {
+ ERROR("connectivity plugin: unable to add interface %s during "
+ "connectivity_link_state",
+ dev);
+ return MNL_CB_ERROR;
+ }
+ }
+
+ uint32_t prev_status = il->status;
+ il->status =
+ ((ifi->ifi_flags & IFF_RUNNING) ? LINK_STATE_UP : LINK_STATE_DOWN);
+ il->timestamp = cdtime();
+
+ // If the new status is different than the previous status,
+ // store the previous status and set sent to zero, and set the
+ // global flag to indicate there are statuses to dispatch
+ if (il->status != prev_status) {
+ il->prev_status = prev_status;
+ il->sent = 0;
+ statuses_to_send = 1;
+ }
+
+ DEBUG("connectivity plugin (%llu): Interface %s status is now %s",
+ (unsigned long long)il->timestamp, dev,
+ ((ifi->ifi_flags & IFF_RUNNING) ? "UP" : "DOWN"));
+
+ // no need to loop again, we found the interface name attr
+ // (otherwise the first if-statement in the loop would
+ // have moved us on with 'continue')
+ break;
+ }
+
+ pthread_mutex_unlock(&connectivity_data_lock);
+
+ return 0;
+}
+
+static int msg_handler(struct nlmsghdr *msg) {
+ // We are only interested in RTM_NEWLINK messages
+ if (msg->nlmsg_type != RTM_NEWLINK) {
+ return 0;
+ }
+ return connectivity_link_state(msg);
+}
+
+static int read_event(int (*msg_handler)(struct nlmsghdr *)) {
+ int ret = 0;
+ int recv_flags = MSG_DONTWAIT;
+
+ if (nl_sock == -1 || msg_handler == NULL)
+ return EINVAL;
+
+ while (42) {
+ pthread_mutex_lock(&connectivity_threads_lock);
+
+ if (connectivity_netlink_thread_loop <= 0) {
+ pthread_mutex_unlock(&connectivity_threads_lock);
+ return ret;
+ }
+
+ pthread_mutex_unlock(&connectivity_threads_lock);
+
+ char buf[4096];
+ int status = recv(nl_sock, buf, sizeof(buf), recv_flags);
+
+ if (status < 0) {
+
+ // If there were no more messages to drain from the socket,
+ // then signal the dequeue thread and allow it to dispatch
+ // any saved interface status changes. Then continue, but
+ // block and wait for new messages
+ if (errno == EWOULDBLOCK || errno == EAGAIN) {
+ pthread_cond_signal(&connectivity_cond);
+
+ recv_flags = 0;
+ continue;
+ }
+
+ if (errno == EINTR) {
+ // Interrupt, so just continue and try again
+ continue;
+ }
+
+ /* Anything else is an error */
+ ERROR("connectivity plugin: read_event: Error recv: %d", status);
+ return status;
+ }
+
+ // Message received successfully, so we'll stop blocking on the
+ // receive call for now (until we get a "would block" error, which
+ // will be handled above)
+ recv_flags = MSG_DONTWAIT;
+
+ if (status == 0) {
+ DEBUG("connectivity plugin: read_event: EOF");
+ }
+
+ /* We need to handle more than one message per 'recvmsg' */
+ for (struct nlmsghdr *h = (struct nlmsghdr *)buf;
+ NLMSG_OK(h, (unsigned int)status); h = NLMSG_NEXT(h, status)) {
+ /* Finish reading */
+ if (h->nlmsg_type == NLMSG_DONE)
+ return ret;
+
+ /* Message is some kind of error */
+ if (h->nlmsg_type == NLMSG_ERROR) {
+ struct nlmsgerr *l_err = (struct nlmsgerr *)NLMSG_DATA(h);
+ ERROR("connectivity plugin: read_event: Message is an error: %d",
+ l_err->error);
+ return -1; // Error
+ }
+
+ /* Call message handler */
+ if (msg_handler) {
+ ret = (*msg_handler)(h);
+ if (ret < 0) {
+ ERROR("connectivity plugin: read_event: Message handler error %d",
+ ret);
+ return ret;
+ }
+ } else {
+ ERROR("connectivity plugin: read_event: Error NULL message handler");
+ return -1;
+ }
+ }
+ }
+
+ return ret;
+}
+
+static void connectivity_dispatch_notification(const char *interface,
+ gauge_t value, gauge_t old_value,
+ cdtime_t timestamp) {
+
+ notification_t n = {
+ .severity = (value == LINK_STATE_UP ? NOTIF_OKAY : NOTIF_FAILURE),
+ .time = cdtime(),
+ .plugin = "connectivity",
+ .type = "gauge",
+ .type_instance = "interface_status",
+ };
+
+ sstrncpy(n.host, hostname_g, sizeof(n.host));
+ sstrncpy(n.plugin_instance, interface, sizeof(n.plugin_instance));
+
+ char *buf = NULL;
+
+ gen_message_payload(value, old_value, interface, timestamp, &buf);
+
+ int status = plugin_notification_meta_add_string(&n, "ves", buf);
+
+ if (status < 0) {
+ sfree(buf);
+ ERROR("connectivity plugin: unable to set notification VES metadata: %s",
+ STRERRNO);
+ return;
+ }
+
+ DEBUG("connectivity plugin: notification VES metadata: %s",
+ n.meta->nm_value.nm_string);
+
+ DEBUG("connectivity plugin: dispatching state %d for interface %s",
+ (int)value, interface);
+
+ plugin_dispatch_notification(&n);
+ plugin_notification_meta_free(n.meta);
+
+ // strdup'd in gen_message_payload
+ if (buf != NULL)
+ sfree(buf);
+}
+
+// NOTE: Caller MUST hold connectivity_data_lock when calling this function
+static void send_interface_status() {
+ for (interface_list_t *il = interface_list_head; il != NULL;
+ il = il->next) /* {{{ */
+ {
+ uint32_t status = il->status;
+ uint32_t prev_status = il->prev_status;
+ uint32_t sent = il->sent;
+
+ if (status != prev_status && sent == 0) {
+ connectivity_dispatch_notification(il->interface, status, prev_status,
+ il->timestamp);
+ il->sent = 1;
+ }
+ } /* }}} for (il = interface_list_head; il != NULL; il = il->next) */
+
+ statuses_to_send = 0;
+}
+
+static void read_interface_status() /* {{{ */
+{
+ pthread_mutex_lock(&connectivity_data_lock);
+
+ // If we don't have any interface statuses to dispatch,
+ // then we wait until signalled
+ if (!statuses_to_send)
+ pthread_cond_wait(&connectivity_cond, &connectivity_data_lock);
+
+ send_interface_status();
+
+ pthread_mutex_unlock(&connectivity_data_lock);
+} /* }}} int *read_interface_status */
+
+static void *connectivity_netlink_thread(void *arg) /* {{{ */
+{
+ pthread_mutex_lock(&connectivity_threads_lock);
+
+ while (connectivity_netlink_thread_loop > 0) {
+ pthread_mutex_unlock(&connectivity_threads_lock);
+
+ int status = read_event(msg_handler);
+
+ pthread_mutex_lock(&connectivity_threads_lock);
+
+ if (status < 0) {
+ connectivity_netlink_thread_error = 1;
+ break;
+ }
+ } /* while (connectivity_netlink_thread_loop > 0) */
+
+ pthread_mutex_unlock(&connectivity_threads_lock);
+
+ return (void *)0;
+} /* }}} void *connectivity_netlink_thread */
+
+static void *connectivity_dequeue_thread(void *arg) /* {{{ */
+{
+ pthread_mutex_lock(&connectivity_threads_lock);
+
+ while (connectivity_dequeue_thread_loop > 0) {
+ pthread_mutex_unlock(&connectivity_threads_lock);
+
+ read_interface_status();
+
+ pthread_mutex_lock(&connectivity_threads_lock);
+ } /* while (connectivity_dequeue_thread_loop > 0) */
+
+ pthread_mutex_unlock(&connectivity_threads_lock);
+
+ return ((void *)0);
+} /* }}} void *connectivity_dequeue_thread */
+
+static int nl_connect() {
+ struct sockaddr_nl sa_nl = {
+ .nl_family = AF_NETLINK,
+ .nl_groups = RTMGRP_LINK,
+ .nl_pid = getpid(),
+ };
+
+ nl_sock = socket(AF_NETLINK, SOCK_DGRAM, NETLINK_ROUTE);
+ if (nl_sock == -1) {
+ ERROR("connectivity plugin: socket open failed: %s", STRERRNO);
+ return -1;
+ }
+
+ int rc = bind(nl_sock, (struct sockaddr *)&sa_nl, sizeof(sa_nl));
+ if (rc == -1) {
+ ERROR("connectivity plugin: socket bind failed: %s", STRERRNO);
+ close(nl_sock);
+ nl_sock = -1;
+ return -1;
+ }
+
+ return 0;
+}
+
+static int start_netlink_thread(void) /* {{{ */
+{
+ pthread_mutex_lock(&connectivity_threads_lock);
+
+ if (connectivity_netlink_thread_loop != 0) {
+ pthread_mutex_unlock(&connectivity_threads_lock);
+ return 0;
+ }
+
+ connectivity_netlink_thread_loop = 1;
+ connectivity_netlink_thread_error = 0;
+
+ int status;
+
+ if (nl_sock == -1) {
+ status = nl_connect();
+
+ if (status != 0) {
+ pthread_mutex_unlock(&connectivity_threads_lock);
+ return status;
+ }
+ }
+
+ status = plugin_thread_create(&connectivity_netlink_thread_id,
+ /* attr = */ NULL, connectivity_netlink_thread,
+ /* arg = */ (void *)0, "connectivity");
+ if (status != 0) {
+ connectivity_netlink_thread_loop = 0;
+ ERROR("connectivity plugin: Starting thread failed.");
+ pthread_mutex_unlock(&connectivity_threads_lock);
+
+ int status2 = close(nl_sock);
+
+ if (status2 != 0) {
+ ERROR("connectivity plugin: failed to close socket %d: %d (%s)", nl_sock,
+ status2, STRERRNO);
+ }
+
+ nl_sock = -1;
+
+ return -1;
+ }
+
+ pthread_mutex_unlock(&connectivity_threads_lock);
+
+ return status;
+}
+
+static int start_dequeue_thread(void) /* {{{ */
+{
+ pthread_mutex_lock(&connectivity_threads_lock);
+
+ if (connectivity_dequeue_thread_loop != 0) {
+ pthread_mutex_unlock(&connectivity_threads_lock);
+ return 0;
+ }
+
+ connectivity_dequeue_thread_loop = 1;
+
+ int status =
+ plugin_thread_create(&connectivity_dequeue_thread_id,
+ /* attr = */ NULL, connectivity_dequeue_thread,
+ /* arg = */ (void *)0, "connectivity");
+ if (status != 0) {
+ connectivity_dequeue_thread_loop = 0;
+ ERROR("connectivity plugin: Starting dequeue thread failed.");
+ pthread_mutex_unlock(&connectivity_threads_lock);
+ return -1;
+ }
+
+ pthread_mutex_unlock(&connectivity_threads_lock);
+
+ return status;
+} /* }}} int start_dequeue_thread */
+
+static int start_threads(void) /* {{{ */
+{
+ int status = start_netlink_thread();
+ int status2 = start_dequeue_thread();
+
+ if (status != 0)
+ return status;
+ else
+ return status2;
+} /* }}} int start_threads */
+
+static int stop_netlink_thread(int shutdown) /* {{{ */
+{
+ int socket_status;
+
+ if (nl_sock != -1) {
+ socket_status = close(nl_sock);
+ if (socket_status != 0) {
+ ERROR("connectivity plugin: failed to close socket %d: %d (%s)", nl_sock,
+ socket_status, STRERRNO);
+ }
+
+ nl_sock = -1;
+ } else
+ socket_status = 0;
+
+ pthread_mutex_lock(&connectivity_threads_lock);
+
+ if (connectivity_netlink_thread_loop == 0) {
+ pthread_mutex_unlock(&connectivity_threads_lock);
+ // Thread has already been terminated, nothing more to attempt
+ return socket_status;
+ }
+
+ // Set thread termination status
+ connectivity_netlink_thread_loop = 0;
+ pthread_mutex_unlock(&connectivity_threads_lock);
+
+ // Let threads waiting on access to the interface list know to move
+ // on such that they'll see the thread's termination status
+ pthread_cond_broadcast(&connectivity_cond);
+
+ int thread_status;
+
+ if (shutdown == 1) {
+ // Since the thread is blocking, calling pthread_join
+ // doesn't actually succeed in stopping it. It will stick around
+ // until a NETLINK message is received on the socket (at which
+ // it will realize that "connectivity_netlink_thread_loop" is 0 and will
+ // break out of the read loop and be allowed to die). This is
+ // fine when the process isn't supposed to be exiting, but in
+ // the case of a process shutdown, we don't want to have an
+ // idle thread hanging around. Calling pthread_cancel here in
+ // the case of a shutdown is just assures that the thread is
+ // gone and that the process has been fully terminated.
+
+ DEBUG("connectivity plugin: Canceling netlink thread for process shutdown");
+
+ thread_status = pthread_cancel(connectivity_netlink_thread_id);
+
+ if (thread_status != 0 && thread_status != ESRCH) {
+ ERROR("connectivity plugin: Unable to cancel netlink thread: %d",
+ thread_status);
+ thread_status = -1;
+ } else
+ thread_status = 0;
+ } else {
+ thread_status =
+ pthread_join(connectivity_netlink_thread_id, /* return = */ NULL);
+ if (thread_status != 0 && thread_status != ESRCH) {
+ ERROR("connectivity plugin: Stopping netlink thread failed: %d",
+ thread_status);
+ thread_status = -1;
+ } else
+ thread_status = 0;
+ }
+
+ pthread_mutex_lock(&connectivity_threads_lock);
+ memset(&connectivity_netlink_thread_id, 0,
+ sizeof(connectivity_netlink_thread_id));
+ connectivity_netlink_thread_error = 0;
+ pthread_mutex_unlock(&connectivity_threads_lock);
+
+ DEBUG("connectivity plugin: Finished requesting stop of netlink thread");
+
+ if (socket_status != 0)
+ return socket_status;
+ else
+ return thread_status;
+}
+
+static int stop_dequeue_thread() /* {{{ */
+{
+ pthread_mutex_lock(&connectivity_threads_lock);
+
+ if (connectivity_dequeue_thread_loop == 0) {
+ pthread_mutex_unlock(&connectivity_threads_lock);
+ return -1;
+ }
+
+ // Set thread termination status
+ connectivity_dequeue_thread_loop = 0;
+ pthread_mutex_unlock(&connectivity_threads_lock);
+
+ // Let threads waiting on access to the interface list know to move
+ // on such that they'll see the threads termination status
+ pthread_cond_broadcast(&connectivity_cond);
+
+ // Calling pthread_cancel here just assures that the thread is
+ // gone and that the process has been fully terminated.
+
+ DEBUG("connectivity plugin: Canceling dequeue thread for process shutdown");
+
+ int status = pthread_cancel(connectivity_dequeue_thread_id);
+
+ if (status != 0 && status != ESRCH) {
+ ERROR("connectivity plugin: Unable to cancel dequeue thread: %d", status);
+ status = -1;
+ } else
+ status = 0;
+
+ pthread_mutex_lock(&connectivity_threads_lock);
+ memset(&connectivity_dequeue_thread_id, 0,
+ sizeof(connectivity_dequeue_thread_id));
+ pthread_mutex_unlock(&connectivity_threads_lock);
+
+ DEBUG("connectivity plugin: Finished requesting stop of dequeue thread");
+
+ return status;
+} /* }}} int stop_dequeue_thread */
+
+static int stop_threads() /* {{{ */
+{
+ int status = stop_netlink_thread(1);
+ int status2 = stop_dequeue_thread();
+
+ if (status != 0)
+ return status;
+ else
+ return status2;
+} /* }}} int stop_threads */
+
+static int connectivity_init(void) /* {{{ */
+{
+ if (monitor_all_interfaces) {
+ NOTICE("connectivity plugin: No interfaces have been selected, so all will "
+ "be monitored");
+ }
+
+ return start_threads();
+} /* }}} int connectivity_init */
+
+static int connectivity_config(const char *key, const char *value) /* {{{ */
+{
+ if (ignorelist == NULL) {
+ ignorelist = ignorelist_create(/* invert = */ 1);
+
+ if (ignorelist == NULL)
+ return -1;
+ }
+
+ if (strcasecmp(key, "Interface") == 0) {
+ ignorelist_add(ignorelist, value);
+ monitor_all_interfaces = 0;
+ } else if (strcasecmp(key, "IgnoreSelected") == 0) {
+ int invert = 1;
+ if (IS_TRUE(value))
+ invert = 0;
+ ignorelist_set_invert(ignorelist, invert);
+ } else {
+ return -1;
+ }
+
+ return 0;
+} /* }}} int connectivity_config */
+
+static int connectivity_read(void) /* {{{ */
+{
+ pthread_mutex_lock(&connectivity_threads_lock);
+
+ if (connectivity_netlink_thread_error != 0) {
+
+ pthread_mutex_unlock(&connectivity_threads_lock);
+
+ ERROR("connectivity plugin: The netlink thread had a problem. Restarting "
+ "it.");
+
+ stop_netlink_thread(0);
+
+ for (interface_list_t *il = interface_list_head; il != NULL;
+ il = il->next) {
+ il->status = LINK_STATE_UNKNOWN;
+ il->prev_status = LINK_STATE_UNKNOWN;
+ il->sent = 0;
+ }
+
+ start_netlink_thread();
+
+ return -1;
+ } /* if (connectivity_netlink_thread_error != 0) */
+
+ pthread_mutex_unlock(&connectivity_threads_lock);
+
+ return 0;
+} /* }}} int connectivity_read */
+
+static int connectivity_shutdown(void) /* {{{ */
+{
+ DEBUG("connectivity plugin: Shutting down thread.");
+
+ int status = stop_threads();
+
+ interface_list_t *il = interface_list_head;
+ while (il != NULL) {
+ interface_list_t *il_next;
+
+ il_next = il->next;
+
+ sfree(il->interface);
+ sfree(il);
+
+ il = il_next;
+ }
+
+ ignorelist_free(ignorelist);
+
+ return status;
+} /* }}} int connectivity_shutdown */
+
+void module_register(void) {
+ plugin_register_config("connectivity", connectivity_config, config_keys,
+ config_keys_num);
+ plugin_register_init("connectivity", connectivity_init);
+ plugin_register_read("connectivity", connectivity_read);
+ plugin_register_shutdown("connectivity", connectivity_shutdown);
+} /* void module_register */
#include "plugin.h"
#include "utils/common/common.h"
-#ifdef HAVE_SYS_SYSCTL_H
+#if defined(HAVE_SYSCTLBYNAME) && defined(HAVE_SYS_SYSCTL_H)
#include <sys/sysctl.h>
-#endif
-
-#if HAVE_SYSCTLBYNAME
/* no global variables */
/* #endif HAVE_SYSCTLBYNAME */
}
cs_submit(value);
-/* #endif HAVE_SYSCTLBYNAME */
+ /* #endif HAVE_SYSCTLBYNAME */
#elif KERNEL_LINUX
FILE *fh;
if (status == -2)
ERROR("contextswitch plugin: Unable to find context switch value.");
-/* #endif KERNEL_LINUX */
+ /* #endif KERNEL_LINUX */
#elif HAVE_PERFSTAT
int status = 0;
#include <sys/sysinfo.h>
#endif /* HAVE_LIBKSTAT */
-#if (defined(HAVE_SYSCTL) && HAVE_SYSCTL) || \
- (defined(HAVE_SYSCTLBYNAME) && HAVE_SYSCTLBYNAME)
-#ifdef HAVE_SYS_SYSCTL_H
+#if (defined(HAVE_SYSCTL) && defined(HAVE_SYSCTLBYNAME)) || defined(__OpenBSD__)
+/* Implies BSD variant */
#include <sys/sysctl.h>
#endif
#ifdef HAVE_SYS_DKSTAT_H
+/* implies BSD variant */
#include <sys/dkstat.h>
-#endif
#if !defined(CP_USER) || !defined(CP_NICE) || !defined(CP_SYS) || \
!defined(CP_INTR) || !defined(CP_IDLE) || !defined(CPUSTATES)
#define CP_IDLE 4
#define CPUSTATES 5
#endif
-#endif /* HAVE_SYSCTL || HAVE_SYSCTLBYNAME */
+#endif /* HAVE_SYS_DKSTAT_H */
-#if HAVE_SYSCTL
+#define CAN_USE_SYSCTL 0
+#if (defined(HAVE_SYSCTL) && defined(HAVE_SYSCTLBYNAME)) || defined(__OpenBSD__)
+/* Implies BSD variant */
#if defined(CTL_HW) && defined(HW_NCPU) && defined(CTL_KERN) && \
defined(KERN_CPTIME) && defined(CPUSTATES)
#define CAN_USE_SYSCTL 1
-#else
-#define CAN_USE_SYSCTL 0
-#endif
-#else
-#define CAN_USE_SYSCTL 0
#endif
+#endif /* HAVE_SYSCTL_H && HAVE_SYSCTLBYNAME || __OpenBSD__ */
#define COLLECTD_CPU_STATE_USER 0
#define COLLECTD_CPU_STATE_SYSTEM 1
/* #endif HAVE_LIBKSTAT */
#elif CAN_USE_SYSCTL
+/* Only possible for (Open) BSD variant */
static int numcpu;
/* #endif CAN_USE_SYSCTL */
#elif defined(HAVE_SYSCTLBYNAME)
+/* Implies BSD variant */
static int numcpu;
#ifdef HAVE_SYSCTL_KERN_CP_TIMES
static int maxcpu;
INFO("cpu plugin: Found %i processor%s.", (int)cpu_list_len,
cpu_list_len == 1 ? "" : "s");
-/* #endif PROCESSOR_CPU_LOAD_INFO */
+ /* #endif PROCESSOR_CPU_LOAD_INFO */
#elif defined(HAVE_LIBKSTAT)
kstat_t *ksp_chain;
ksp_chain = ksp_chain->ks_next)
if (strncmp(ksp_chain->ks_module, "cpu_stat", 8) == 0)
ksp[numcpu++] = ksp_chain;
-/* #endif HAVE_LIBKSTAT */
+ /* #endif HAVE_LIBKSTAT */
#elif CAN_USE_SYSCTL
+ /* Only on (Open) BSD variant */
size_t numcpu_size;
int mib[2] = {CTL_HW, HW_NCPU};
int status;
WARNING("cpu plugin: sysctl: %s", STRERRNO);
return -1;
}
-/* #endif CAN_USE_SYSCTL */
+ /* #endif CAN_USE_SYSCTL */
#elif defined(HAVE_SYSCTLBYNAME)
+ /* Only on BSD varient */
size_t numcpu_size;
numcpu_size = sizeof(numcpu);
"%i)",
numcpu);
#endif
-/* #endif HAVE_SYSCTLBYNAME */
+ /* #endif HAVE_SYSCTLBYNAME */
#elif defined(HAVE_LIBSTATGRAB)
/* nothing to initialize */
cpu_stage(cpu, COLLECTD_CPU_STATE_IDLE,
(derive_t)cpu_info.cpu_ticks[CPU_STATE_IDLE], now);
}
-/* }}} #endif PROCESSOR_CPU_LOAD_INFO */
+ /* }}} #endif PROCESSOR_CPU_LOAD_INFO */
#elif defined(KERNEL_LINUX) /* {{{ */
int cpu;
cpu_stage(cpu, COLLECTD_CPU_STATE_NICE, (derive_t)nice_value, now);
}
fclose(fh);
-/* }}} #endif defined(KERNEL_LINUX) */
+ /* }}} #endif defined(KERNEL_LINUX) */
#elif defined(HAVE_LIBKSTAT) /* {{{ */
static cpu_stat_t cs;
cpu_stage(ksp[cpu]->ks_instance, COLLECTD_CPU_STATE_WAIT,
(derive_t)cs.cpu_sysinfo.cpu[CPU_WAIT], now);
}
-/* }}} #endif defined(HAVE_LIBKSTAT) */
+ /* }}} #endif defined(HAVE_LIBKSTAT) */
#elif CAN_USE_SYSCTL /* {{{ */
+ /* Only on (Open) BSD variant */
uint64_t cpuinfo[numcpu][CPUSTATES];
size_t cpuinfo_size;
int status;
cpu_stage(i, COLLECTD_CPU_STATE_INTERRUPT, (derive_t)cpuinfo[i][CP_INTR],
now);
}
-/* }}} #endif CAN_USE_SYSCTL */
+ /* }}} #endif CAN_USE_SYSCTL */
#elif defined(HAVE_SYSCTLBYNAME) && defined(HAVE_SYSCTL_KERN_CP_TIMES) /* {{{ \
- */
+ */
+ /* Only on BSD variant */
long cpuinfo[maxcpu][CPUSTATES];
size_t cpuinfo_size;
cpu_stage(i, COLLECTD_CPU_STATE_INTERRUPT, (derive_t)cpuinfo[i][CP_INTR],
now);
}
-/* }}} #endif HAVE_SYSCTL_KERN_CP_TIMES */
+ /* }}} #endif HAVE_SYSCTL_KERN_CP_TIMES */
#elif defined(HAVE_SYSCTLBYNAME) /* {{{ */
+ /* Only on BSD variant */
long cpuinfo[CPUSTATES];
size_t cpuinfo_size;
cpu_stage(0, COLLECTD_CPU_STATE_SYSTEM, (derive_t)cpuinfo[CP_SYS], now);
cpu_stage(0, COLLECTD_CPU_STATE_IDLE, (derive_t)cpuinfo[CP_IDLE], now);
cpu_stage(0, COLLECTD_CPU_STATE_INTERRUPT, (derive_t)cpuinfo[CP_INTR], now);
-/* }}} #endif HAVE_SYSCTLBYNAME */
+ /* }}} #endif HAVE_SYSCTLBYNAME */
#elif defined(HAVE_LIBSTATGRAB) /* {{{ */
sg_cpu_stats *cs;
cpu_state(0, COLLECTD_CPU_STATE_SYSTEM, (derive_t)cs->kernel);
cpu_state(0, COLLECTD_CPU_STATE_USER, (derive_t)cs->user);
cpu_state(0, COLLECTD_CPU_STATE_WAIT, (derive_t)cs->iowait);
-/* }}} #endif HAVE_LIBSTATGRAB */
+ /* }}} #endif HAVE_LIBSTATGRAB */
#elif defined(HAVE_PERFSTAT) /* {{{ */
perfstat_id_t id;
* 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"
typedef struct {
PluginData data;
- PyObject *meta; /* dict */
+ PyObject *meta; /* dict */
int severity;
char message[NOTIF_MAX_MSG_LEN];
} Notification;
plugin_register_complex_read(/* group = */ NULL, cb_name, cc_read_page,
interval,
&(user_data_t){
- .data = page, .free_func = cc_web_page_free,
+ .data = page,
+ .free_func = cc_web_page_free,
});
sfree(cb_name);
plugin_register_complex_read(/* group = */ NULL, cb_name, cj_read, interval,
&(user_data_t){
- .data = db, .free_func = cj_free,
+ .data = db,
+ .free_func = cj_free,
});
sfree(cb_name);
} else {
return EINVAL;
}
- cx_namespace_t *ns = realloc(
- db->namespaces, sizeof(*db->namespaces) * (db->namespaces_num + 1));
+ cx_namespace_t *ns = realloc(db->namespaces, sizeof(*db->namespaces) *
+ (db->namespaces_num + 1));
if (ns == NULL) {
ERROR("curl_xml plugin: realloc failed.");
return ENOMEM;
plugin_register_complex_read(/* group = */ "curl_xml", cb_name, cx_read,
/* interval = */ interval,
&(user_data_t){
- .data = db, .free_func = cx_free,
+ .data = db,
+ .free_func = cx_free,
});
sfree(cb_name);
return 0;
#ifdef KERNEL_LINUX
&& notify_upstart() == 0 && notify_systemd() == 0
#endif
- ) {
+ ) {
pid_t pid;
if ((pid = fork()) == -1) {
/* error */
static void read_cmdline(int argc, char **argv, struct cmdline_config *config) {
/* read options */
while (1) {
- int c = getopt(argc, argv, "BhtTC:"
+ int c = getopt(argc, argv,
+ "BhtTC:"
#if COLLECT_DAEMON
- "fP:"
+ "fP:"
#endif
- );
+ );
if (c == -1)
break;
struct cmdline_config init_config(int argc, char **argv) {
struct cmdline_config config = {
- .daemonize = true, .create_basedir = true, .configfile = CONFIGFILE,
+ .daemonize = true,
+ .create_basedir = true,
+ .configfile = CONFIGFILE,
};
read_cmdline(argc, argv, &config);
return cf_cb;
}
-static int cf_dispatch(const char *type, const char *orig_key,
- const char *orig_value) {
- cf_callback_t *cf_cb;
- plugin_ctx_t old_ctx;
- char *key;
- char *value;
- int ret;
- int i = 0;
+static int cf_dispatch_option(const cf_callback_t *cf_cb, oconfig_item_t *ci) {
+ const char *plugin = cf_cb->type;
+ const char *orig_key = ci->key;
if (orig_key == NULL)
return EINVAL;
- DEBUG("type = %s, key = %s, value = %s", ESCAPE_NULL(type), orig_key,
- ESCAPE_NULL(orig_value));
+ /* (Re)construct string value for option */
+ char buffer[4096];
+ int buffer_free = sizeof(buffer);
+ char *buffer_ptr = buffer;
- if ((cf_cb = cf_search(type)) == NULL) {
- WARNING("Found a configuration for the `%s' plugin, but "
- "the plugin isn't loaded or didn't register "
- "a configuration callback.",
- type);
- return -1;
+ for (int i = 0; i < ci->values_num; i++) {
+ int status = -1;
+
+ if (ci->values[i].type == OCONFIG_TYPE_STRING)
+ status =
+ ssnprintf(buffer_ptr, buffer_free, " %s", ci->values[i].value.string);
+ else if (ci->values[i].type == OCONFIG_TYPE_NUMBER)
+ status = ssnprintf(buffer_ptr, buffer_free, " %lf",
+ ci->values[i].value.number);
+ else if (ci->values[i].type == OCONFIG_TYPE_BOOLEAN)
+ status = ssnprintf(buffer_ptr, buffer_free, " %s",
+ ci->values[i].value.boolean ? "true" : "false");
+
+ if ((status < 0) || (status >= buffer_free))
+ return -1;
+ buffer_free -= status;
+ buffer_ptr += status;
}
- if ((key = strdup(orig_key)) == NULL)
+ /* skip the initial space */
+ const char *orig_value = buffer + 1;
+
+ DEBUG("plugin = %s, key = %s, value = %s", ESCAPE_NULL(plugin), orig_key,
+ ESCAPE_NULL(orig_value));
+
+ char *key = strdup(orig_key);
+ if (key == NULL)
return 1;
- if ((value = strdup(orig_value)) == NULL) {
+
+ char *value = strdup(orig_value);
+ if (value == NULL) {
free(key);
return 2;
}
- ret = -1;
+ int ret = -1;
- old_ctx = plugin_set_ctx(cf_cb->ctx);
+ plugin_ctx_t old_ctx = plugin_set_ctx(cf_cb->ctx);
+ int i;
for (i = 0; i < cf_cb->keys_num; i++) {
if ((cf_cb->keys[i] != NULL) && (strcasecmp(cf_cb->keys[i], key) == 0)) {
ret = (*cf_cb->callback)(key, value);
plugin_set_ctx(old_ctx);
if (i >= cf_cb->keys_num)
- WARNING("Plugin `%s' did not register for value `%s'.", type, key);
+ WARNING("Plugin `%s' did not register for value `%s'.", plugin, key);
free(key);
free(value);
return ret;
-} /* int cf_dispatch */
+} /* int cf_dispatch_option */
static int dispatch_global_option(const oconfig_item_t *ci) {
if (ci->values_num != 1) {
return global_option_set(ci->key, ci->values[0].value.string, 0);
else if (ci->values[0].type == OCONFIG_TYPE_NUMBER) {
char tmp[128];
- snprintf(tmp, sizeof(tmp), "%lf", ci->values[0].value.number);
+ ssnprintf(tmp, sizeof(tmp), "%lf", ci->values[0].value.number);
return global_option_set(ci->key, tmp, 0);
} else if (ci->values[0].type == OCONFIG_TYPE_BOOLEAN) {
if (ci->values[0].value.boolean)
/* default to the global interval set before loading this plugin */
plugin_ctx_t ctx = {
- .interval = cf_get_default_interval(), .name = strdup(name),
+ .interval = cf_get_default_interval(),
+ .name = strdup(name),
};
if (ctx.name == NULL)
return ENOMEM;
return ret_val;
} /* int dispatch_value_loadplugin */
-static int dispatch_value_plugin(const char *plugin, oconfig_item_t *ci) {
- char buffer[4096];
- char *buffer_ptr;
- int buffer_free;
-
- buffer_ptr = buffer;
- buffer_free = sizeof(buffer);
-
- for (int i = 0; i < ci->values_num; i++) {
- int status = -1;
-
- if (ci->values[i].type == OCONFIG_TYPE_STRING)
- status =
- snprintf(buffer_ptr, buffer_free, " %s", ci->values[i].value.string);
- else if (ci->values[i].type == OCONFIG_TYPE_NUMBER)
- status =
- snprintf(buffer_ptr, buffer_free, " %lf", ci->values[i].value.number);
- else if (ci->values[i].type == OCONFIG_TYPE_BOOLEAN)
- status = snprintf(buffer_ptr, buffer_free, " %s",
- ci->values[i].value.boolean ? "true" : "false");
-
- if ((status < 0) || (status >= buffer_free))
- return -1;
- buffer_free -= status;
- buffer_ptr += status;
- }
- /* skip the initial space */
- buffer_ptr = buffer + 1;
-
- return cf_dispatch(plugin, ci->key, buffer_ptr);
-} /* int dispatch_value_plugin */
-
static int dispatch_value(oconfig_item_t *ci) {
int ret = 0;
return -1;
}
- const char *name = ci->values[0].value.string;
- if (strcmp("libvirt", name) == 0) {
+ const char *plugin_name = ci->values[0].value.string;
+ if (strcmp("libvirt", plugin_name) == 0) {
/* TODO(octo): Remove this legacy. */
WARNING("The \"libvirt\" plugin has been renamed to \"virt\" to avoid "
"problems with the build system. "
"Your configuration is still using the old name. "
"Please change it to use \"virt\" as soon as possible. "
"This compatibility code will go away eventually.");
- name = "virt";
+ plugin_name = "virt";
}
- if (IS_TRUE(global_option_get("AutoLoadPlugin"))) {
+ bool plugin_loaded = plugin_is_loaded(plugin_name);
+
+ if (!plugin_loaded && IS_TRUE(global_option_get("AutoLoadPlugin"))) {
plugin_ctx_t ctx = {0};
- plugin_ctx_t old_ctx;
- int status;
/* default to the global interval set before loading this plugin */
ctx.interval = cf_get_default_interval();
- ctx.name = strdup(name);
+ ctx.name = strdup(plugin_name);
- old_ctx = plugin_set_ctx(ctx);
- status = plugin_load(name, /* flags = */ false);
+ plugin_ctx_t old_ctx = plugin_set_ctx(ctx);
+ int status = plugin_load(plugin_name, /* flags = */ false);
/* reset to the "global" context */
plugin_set_ctx(old_ctx);
if (status != 0) {
- ERROR("Automatically loading plugin \"%s\" failed "
+ ERROR("Automatically loading plugin `%s' failed "
"with status %i.",
- name, status);
+ plugin_name, status);
return status;
}
+ plugin_loaded = true;
+ }
+
+ if (!plugin_loaded) {
+ WARNING("There is configuration for the `%s' plugin, but the plugin isn't "
+ "loaded. Please check your configuration.",
+ plugin_name);
+
+ /* Try to be backward-compatible with previous versions */
+ return 0;
}
/* Check for a complex callback first */
for (cf_complex_callback_t *cb = complex_callback_head; cb != NULL;
cb = cb->next) {
- if (strcasecmp(name, cb->type) == 0) {
- plugin_ctx_t old_ctx;
- int ret_val;
-
- old_ctx = plugin_set_ctx(cb->ctx);
- ret_val = (cb->callback(ci));
+ if (strcasecmp(plugin_name, cb->type) == 0) {
+ plugin_ctx_t old_ctx = plugin_set_ctx(cb->ctx);
+ int ret_val = (cb->callback(ci));
plugin_set_ctx(old_ctx);
return ret_val;
}
}
+ /* Try to be backward-compatible with previous versions */
+ if (ci->children_num == 0)
+ return 0;
+
/* Hm, no complex plugin found. Dispatch the values one by one */
- for (int i = 0, ret = 0; i < ci->children_num; i++) {
+ cf_callback_t *cf_cb = cf_search(plugin_name);
+ if (cf_cb == NULL) {
+ WARNING("Found a configuration for the `%s' plugin, but "
+ "the plugin didn't register a configuration callback.",
+ plugin_name);
+ return -1;
+ }
+
+ for (int i = 0; i < ci->children_num; i++) {
if (ci->children[i].children == NULL) {
- ret = dispatch_value_plugin(name, ci->children + i);
- if (ret != 0)
+ oconfig_item_t *child = ci->children + i;
+ int ret = cf_dispatch_option(cf_cb, child);
+ if (ret != 0) {
+ ERROR("Plugin `%s' failed to handle option `%s', return code: %i",
+ plugin_name, child->key, ret);
return ret;
+ }
} else {
WARNING("There is a `%s' block within the "
- "configuration for the %s plugin. "
- "The plugin either only expects "
- "\"simple\" configuration statements "
- "or wasn't loaded using `LoadPlugin'."
- " Please check your configuration.",
- ci->children[i].key, name);
+ "configuration for the `%s' plugin. "
+ "The plugin only expects \"simple\" configuration options. "
+ "Blocks are not supported. Please check your configuration.",
+ ci->children[i].key, plugin_name);
}
}
return 0;
}
- temp = realloc(dst->children,
- sizeof(oconfig_item_t) *
- (dst->children_num + src->children_num - 1));
+ temp =
+ realloc(dst->children, sizeof(oconfig_item_t) *
+ (dst->children_num + src->children_num - 1));
if (temp == NULL) {
ERROR("configfile: realloc failed.");
return -1;
if ((src == NULL) || (src->children_num == 0))
return 0;
- temp =
- realloc(dst->children,
- sizeof(oconfig_item_t) * (dst->children_num + src->children_num));
+ temp = realloc(dst->children, sizeof(oconfig_item_t) *
+ (dst->children_num + src->children_num));
if (temp == NULL) {
ERROR("configfile: realloc failed.");
return -1;
if ((de->d_name[0] == '.') || (de->d_name[0] == 0))
continue;
- status = snprintf(name, sizeof(name), "%s/%s", dir, de->d_name);
+ status = ssnprintf(name, sizeof(name), "%s/%s", dir, de->d_name);
if ((status < 0) || ((size_t)status >= sizeof(name))) {
ERROR("configfile: Not including `%s/%s' because its"
" name is too long.",
return root;
} /* oconfig_item_t *cf_read_generic */
-/* #endif HAVE_WORDEXP_H */
+ /* #endif HAVE_WORDEXP_H */
#else /* if !HAVE_WORDEXP_H */
static oconfig_item_t *cf_read_generic(const char *path, const char *pattern,
P_ERROR("cf_util_get_service: Out of memory.");
return -1;
}
- snprintf(service, 6, "%i", port);
+ ssnprintf(service, 6, "%i", port);
sfree(*ret_string);
*ret_string = service;
* DEALINGS IN THE SOFTWARE.
**/
-#include "globals.h"
+// clang-format off
+/*
+ * Explicit order is required or _FILE_OFFSET_BITS will have definition mismatches on Solaris
+ * See Github Issue #3193 for details
+ */
#include "utils/common/common.h"
+#include "globals.h"
+// clang-format on
#if HAVE_KSTAT_H
#include <kstat.h>
};
typedef struct read_func_s read_func_t;
+struct cache_event_func_s {
+ plugin_cache_event_cb callback;
+ char *name;
+ user_data_t user_data;
+ plugin_ctx_t plugin_ctx;
+};
+typedef struct cache_event_func_s cache_event_func_t;
+
struct write_queue_s;
typedef struct write_queue_s write_queue_t;
struct write_queue_s {
static llist_t *list_log;
static llist_t *list_notification;
+static size_t list_cache_event_num;
+static cache_event_func_t list_cache_event[32];
+
static fc_chain_t *pre_cache_chain;
static fc_chain_t *post_cache_chain;
static int register_callback(llist_t **list, /* {{{ */
const char *name, callback_func_t *cf) {
- llentry_t *le;
- char *key;
if (*list == NULL) {
*list = llist_create();
}
}
- key = strdup(name);
+ char *key = strdup(name);
if (key == NULL) {
ERROR("plugin: register_callback: strdup failed.");
destroy_callback(cf);
return -1;
}
- le = llist_search(*list, name);
+ llentry_t *le = llist_search(*list, name);
if (le == NULL) {
le = llentry_create(key, cf);
if (le == NULL) {
llist_append(*list, le);
} else {
- callback_func_t *old_cf;
-
- old_cf = le->value;
+ callback_func_t *old_cf = le->value;
le->value = cf;
P_WARNING("register_callback: "
cf->cf_callback = callback;
if (ud == NULL) {
cf->cf_udata = (user_data_t){
- .data = NULL, .free_func = NULL,
+ .data = NULL,
+ .free_func = NULL,
};
} else {
cf->cf_udata = *ud;
}
char name[THREAD_NAME_MAX];
- snprintf(name, sizeof(name), "reader#%" PRIu64, (uint64_t)read_threads_num);
+ ssnprintf(name, sizeof(name), "reader#%" PRIu64,
+ (uint64_t)read_threads_num);
set_thread_name(read_threads[read_threads_num], name);
read_threads_num++;
}
char name[THREAD_NAME_MAX];
- snprintf(name, sizeof(name), "writer#%" PRIu64,
- (uint64_t)write_threads_num);
+ ssnprintf(name, sizeof(name), "writer#%" PRIu64,
+ (uint64_t)write_threads_num);
set_thread_name(write_threads[write_threads_num], name);
write_threads_num++;
ERROR("plugin_set_dir: strdup(\"%s\") failed", dir);
}
-static bool plugin_is_loaded(char const *name) {
- int status;
-
+bool plugin_is_loaded(char const *name) {
if (plugins_loaded == NULL)
plugins_loaded =
c_avl_create((int (*)(const void *, const void *))strcasecmp);
assert(plugins_loaded != NULL);
- status = c_avl_get(plugins_loaded, name, /* ret_value = */ NULL);
+ int status = c_avl_get(plugins_loaded, name, /* ret_value = */ NULL);
return status == 0;
}
/* name = */ flush_name,
/* callback = */ plugin_flush_timeout_callback,
/* interval = */ ctx.flush_interval,
- /* user data = */ &(user_data_t){
- .data = cb, .free_func = plugin_flush_timeout_callback_free,
+ /* user data = */
+ &(user_data_t){
+ .data = cb,
+ .free_func = plugin_flush_timeout_callback_free,
});
sfree(flush_name);
return create_register_callback(&list_missing, name, (void *)callback, ud);
} /* int plugin_register_missing */
+EXPORT int plugin_register_cache_event(const char *name,
+ plugin_cache_event_cb callback,
+ user_data_t const *ud) {
+
+ if (name == NULL || callback == NULL)
+ return EINVAL;
+
+ char *name_copy = strdup(name);
+ if (name_copy == NULL) {
+ P_ERROR("plugin_register_cache_event: strdup failed.");
+ free_userdata(ud);
+ return ENOMEM;
+ }
+
+ if (list_cache_event_num >= 32) {
+ P_ERROR("plugin_register_cache_event: Too much cache event callbacks tried "
+ "to be registered.");
+ free_userdata(ud);
+ return ENOMEM;
+ }
+
+ for (size_t i = 0; i < list_cache_event_num; i++) {
+ cache_event_func_t *cef = &list_cache_event[i];
+ if (!cef->callback)
+ continue;
+
+ if (strcmp(name, cef->name) == 0) {
+ P_ERROR("plugin_register_cache_event: a callback named `%s' already "
+ "registered!",
+ name);
+ free_userdata(ud);
+ return -1;
+ }
+ }
+
+ user_data_t user_data;
+ if (ud == NULL) {
+ user_data = (user_data_t){
+ .data = NULL, .free_func = NULL,
+ };
+ } else {
+ user_data = *ud;
+ }
+
+ list_cache_event[list_cache_event_num] =
+ (cache_event_func_t){.callback = callback,
+ .name = name_copy,
+ .user_data = user_data,
+ .plugin_ctx = plugin_get_ctx()};
+ list_cache_event_num++;
+
+ return 0;
+} /* int plugin_register_cache_event */
+
EXPORT int plugin_register_shutdown(const char *name, int (*callback)(void)) {
return create_register_callback(&list_shutdown, name, (void *)callback, NULL);
} /* int plugin_register_shutdown */
return plugin_unregister(list_missing, name);
}
+EXPORT int plugin_unregister_cache_event(const char *name) {
+ for (size_t i = 0; i < list_cache_event_num; i++) {
+ cache_event_func_t *cef = &list_cache_event[i];
+ if (!cef->callback)
+ continue;
+ if (strcmp(name, cef->name) == 0) {
+ /* Mark callback as inactive, so mask in cache entries remains actual */
+ cef->callback = NULL;
+ sfree(cef->name);
+ free_userdata(&cef->user_data);
+ }
+ }
+ return 0;
+}
+
+static void destroy_cache_event_callbacks() {
+ for (size_t i = 0; i < list_cache_event_num; i++) {
+ cache_event_func_t *cef = &list_cache_event[i];
+ if (!cef->callback)
+ continue;
+ cef->callback = NULL;
+ sfree(cef->name);
+ free_userdata(&cef->user_data);
+ }
+}
+
EXPORT int plugin_unregister_shutdown(const char *name) {
return plugin_unregister(list_shutdown, name);
}
* the data isn't freed twice. */
destroy_all_callbacks(&list_flush);
destroy_all_callbacks(&list_missing);
+ destroy_cache_event_callbacks();
destroy_all_callbacks(&list_write);
destroy_all_callbacks(&list_notification);
return 0;
} /* int }}} plugin_dispatch_missing */
+void plugin_dispatch_cache_event(enum cache_event_type_e event_type,
+ unsigned long callbacks_mask, const char *name,
+ const value_list_t *vl) {
+ switch (event_type) {
+ case CE_VALUE_NEW:
+ callbacks_mask = 0;
+ for (size_t i = 0; i < list_cache_event_num; i++) {
+ cache_event_func_t *cef = &list_cache_event[i];
+ plugin_cache_event_cb callback = cef->callback;
+
+ if (!callback)
+ continue;
+
+ cache_event_t event = (cache_event_t){.type = event_type,
+ .value_list = vl,
+ .value_list_name = name,
+ .ret = 0};
+
+ plugin_ctx_t old_ctx = plugin_set_ctx(cef->plugin_ctx);
+ int status = (*callback)(&event, &cef->user_data);
+ plugin_set_ctx(old_ctx);
+
+ if (status != 0) {
+ ERROR("plugin_dispatch_cache_event: Callback \"%s\" failed with status "
+ "%i for event NEW.",
+ cef->name, status);
+ } else {
+ if (event.ret) {
+ DEBUG(
+ "plugin_dispatch_cache_event: Callback \"%s\" subscribed to %s.",
+ cef->name, name);
+ callbacks_mask |= (1 << (i));
+ } else {
+ DEBUG("plugin_dispatch_cache_event: Callback \"%s\" ignores %s.",
+ cef->name, name);
+ }
+ }
+ }
+
+ if (callbacks_mask)
+ uc_set_callbacks_mask(name, callbacks_mask);
+
+ break;
+ case CE_VALUE_UPDATE:
+ case CE_VALUE_EXPIRED:
+ for (size_t i = 0; i < list_cache_event_num; i++) {
+ cache_event_func_t *cef = &list_cache_event[i];
+ plugin_cache_event_cb callback = cef->callback;
+
+ if (!callback)
+ continue;
+
+ if (callbacks_mask && (1 << (i)) == 0)
+ continue;
+
+ cache_event_t event = (cache_event_t){.type = event_type,
+ .value_list = vl,
+ .value_list_name = name,
+ .ret = 0};
+
+ plugin_ctx_t old_ctx = plugin_set_ctx(cef->plugin_ctx);
+ int status = (*callback)(&event, &cef->user_data);
+ plugin_set_ctx(old_ctx);
+
+ if (status != 0) {
+ ERROR("plugin_dispatch_cache_event: Callback \"%s\" failed with status "
+ "%i for event %s.",
+ cef->name, status,
+ ((event_type == CE_VALUE_UPDATE) ? "UPDATE" : "EXPIRED"));
+ }
+ }
+ break;
+ }
+ return;
+}
+
static int plugin_dispatch_values_internal(value_list_t *vl) {
int status;
static c_complain_t no_write_complaint = C_COMPLAIN_INIT_STATIC;
};
typedef struct user_data_s user_data_t;
+enum cache_event_type_e { CE_VALUE_NEW, CE_VALUE_UPDATE, CE_VALUE_EXPIRED };
+
+typedef struct cache_event_s {
+ enum cache_event_type_e type;
+ const value_list_t *value_list;
+ const char *value_list_name;
+ int ret;
+} cache_event_t;
+
struct plugin_ctx_s {
char *name;
cdtime_t interval;
* callbacks should be called, greater than zero if no more callbacks should be
* called. */
typedef int (*plugin_missing_cb)(const value_list_t *, user_data_t *);
+/* "cache event" callback. CE_VALUE_NEW events are sent to all registered
+ * callbacks. Callback should check if it interested in further CE_VALUE_UPDATE
+ * and CE_VALUE_EXPIRED events for metric and set event->ret = 1 if so.
+ */
+typedef int (*plugin_cache_event_cb)(cache_event_t *, user_data_t *);
typedef void (*plugin_log_cb)(int severity, const char *message, user_data_t *);
typedef int (*plugin_shutdown_cb)(void);
typedef int (*plugin_notification_cb)(const notification_t *, user_data_t *);
* this case.
*/
int plugin_load(const char *name, bool global);
+bool plugin_is_loaded(char const *name);
int plugin_init_all(void);
void plugin_read_all(void);
user_data_t const *user_data);
int plugin_register_missing(const char *name, plugin_missing_cb callback,
user_data_t const *user_data);
+int plugin_register_cache_event(const char *name,
+ plugin_cache_event_cb callback,
+ user_data_t const *ud);
int plugin_register_shutdown(const char *name, plugin_shutdown_cb callback);
int plugin_register_data_set(const data_set_t *ds);
int plugin_register_log(const char *name, plugin_log_cb callback,
int plugin_unregister_write(const char *name);
int plugin_unregister_flush(const char *name);
int plugin_unregister_missing(const char *name);
+int plugin_unregister_cache_event(const char *name);
int plugin_unregister_shutdown(const char *name);
int plugin_unregister_data_set(const char *name);
int plugin_unregister_log(const char *name);
int store_type, ...);
int plugin_dispatch_missing(const value_list_t *vl);
+void plugin_dispatch_cache_event(enum cache_event_type_e event_type,
+ unsigned long callbacks_mask, const char *name,
+ const value_list_t *vl);
int plugin_dispatch_notification(const notification_t *notif);
int plugin_load(const char *name, bool global) { return ENOTSUP; }
+bool plugin_is_loaded(const char *name) { return false; }
+
int plugin_register_config(const char *name,
int (*callback)(const char *key, const char *val),
const char **keys, int keys_num) {
return ENOTSUP;
}
+int plugin_register_flush(__attribute__((unused)) const char *name,
+ __attribute__((unused)) plugin_flush_cb callback,
+ __attribute__((unused))
+ user_data_t const *user_data) {
+ return ENOTSUP;
+}
+
int plugin_register_missing(const char *name, plugin_missing_cb callback,
user_data_t const *ud) {
return ENOTSUP;
int plugin_register_data_set(const data_set_t *ds) { return ENOTSUP; }
+int plugin_register_notification(__attribute__((unused)) const char *name,
+ __attribute__((unused))
+ plugin_notification_cb callback,
+ __attribute__((unused))
+ user_data_t const *user_data) {
+ return ENOTSUP;
+}
+
+#define DECLARE_UNREGISTER(t) \
+ int plugin_unregister_##t(__attribute__((unused)) char const *name) { \
+ return ENOTSUP; \
+ }
+DECLARE_UNREGISTER(config)
+DECLARE_UNREGISTER(complex_config)
+DECLARE_UNREGISTER(init)
+DECLARE_UNREGISTER(read)
+DECLARE_UNREGISTER(read_group)
+DECLARE_UNREGISTER(write)
+DECLARE_UNREGISTER(flush)
+DECLARE_UNREGISTER(missing)
+DECLARE_UNREGISTER(shutdown)
+DECLARE_UNREGISTER(data_set)
+DECLARE_UNREGISTER(log)
+DECLARE_UNREGISTER(notification)
+
int plugin_dispatch_values(value_list_t const *vl) { return ENOTSUP; }
int plugin_dispatch_notification(__attribute__((unused))
cdtime_t plugin_get_interval(void) { return mock_context.interval; }
+int plugin_thread_create(__attribute__((unused)) pthread_t *thread,
+ __attribute__((unused)) const pthread_attr_t *attr,
+ __attribute__((unused)) void *(*start_routine)(void *),
+ __attribute__((unused)) void *arg,
+ __attribute__((unused)) char const *name) {
+ return ENOTSUP;
+}
+
/* TODO(octo): this function is actually from filter_chain.h, but in order not
* to tumble down that rabbit hole, we're declaring it here. A better solution
* would be to hard-code the top-level config keys in daemon/collectd.c to avoid
size_t history_length;
meta_data_t *meta;
+ unsigned long callbacks_mask;
} cache_entry_t;
struct uc_iter_s {
static int uc_insert(const data_set_t *ds, const value_list_t *vl,
const char *key) {
- char *key_copy;
- cache_entry_t *ce;
-
/* `cache_lock' has been locked by `uc_update' */
- key_copy = strdup(key);
+ char *key_copy = strdup(key);
if (key_copy == NULL) {
ERROR("uc_insert: strdup failed.");
return -1;
}
- ce = cache_alloc(ds->ds_num);
+ cache_entry_t *ce = cache_alloc(ds->ds_num);
if (ce == NULL) {
sfree(key_copy);
ERROR("uc_insert: cache_alloc (%" PRIsz ") failed.", ds->ds_num);
ce->interval = vl->interval;
ce->state = STATE_UNKNOWN;
+ if (vl->meta != NULL) {
+ ce->meta = meta_data_clone(vl->meta);
+ }
+
if (c_avl_insert(cache_tree, key_copy, ce) != 0) {
sfree(key_copy);
ERROR("uc_insert: c_avl_insert failed.");
char *key;
cdtime_t time;
cdtime_t interval;
+ unsigned long callbacks_mask;
} *expired = NULL;
size_t expired_num = 0;
expired[expired_num].key = strdup(key);
expired[expired_num].time = ce->last_time;
expired[expired_num].interval = ce->interval;
+ expired[expired_num].callbacks_mask = ce->callbacks_mask;
if (expired[expired_num].key == NULL) {
ERROR("uc_check_timeout: strdup failed.");
* plugin calls the cache interface. */
for (size_t i = 0; i < expired_num; i++) {
value_list_t vl = {
- .time = expired[i].time, .interval = expired[i].interval,
+ .time = expired[i].time,
+ .interval = expired[i].interval,
};
if (parse_identifier_vl(expired[i].key, &vl) != 0) {
}
plugin_dispatch_missing(&vl);
+
+ if (expired[i].callbacks_mask)
+ plugin_dispatch_cache_event(CE_VALUE_EXPIRED, expired[i].callbacks_mask,
+ expired[i].key, &vl);
} /* for (i = 0; i < expired_num; i++) */
/* Now actually remove all the values from the cache. We don't re-evaluate
int uc_update(const data_set_t *ds, const value_list_t *vl) {
char name[6 * DATA_MAX_NAME_LEN];
- cache_entry_t *ce = NULL;
- int status;
if (FORMAT_VL(name, sizeof(name), vl) != 0) {
ERROR("uc_update: FORMAT_VL failed.");
pthread_mutex_lock(&cache_lock);
- status = c_avl_get(cache_tree, name, (void *)&ce);
+ cache_entry_t *ce = NULL;
+ int status = c_avl_get(cache_tree, name, (void *)&ce);
if (status != 0) /* entry does not yet exist */
{
status = uc_insert(ds, vl, name);
pthread_mutex_unlock(&cache_lock);
+
+ if (status == 0)
+ plugin_dispatch_cache_event(CE_VALUE_NEW, 0 /* mask */, name, vl);
+
return status;
}
ce->last_update = cdtime();
ce->interval = vl->interval;
+ /* Check if cache entry has registered callbacks */
+ unsigned long callbacks_mask = ce->callbacks_mask;
+
pthread_mutex_unlock(&cache_lock);
+ if (callbacks_mask)
+ plugin_dispatch_cache_event(CE_VALUE_UPDATE, callbacks_mask, name, vl);
+
return 0;
} /* int uc_update */
+int uc_set_callbacks_mask(const char *name, unsigned long mask) {
+ pthread_mutex_lock(&cache_lock);
+ cache_entry_t *ce = NULL;
+ int status = c_avl_get(cache_tree, name, (void *)&ce);
+ if (status != 0) { /* Ouch, just created entry disappeared ?! */
+ ERROR("uc_set_callbacks_mask: Couldn't find %s entry!", name);
+ pthread_mutex_unlock(&cache_lock);
+ return -1;
+ }
+ DEBUG("uc_set_callbacks_mask: set mask for \"%s\" to %lu.", name, mask);
+ ce->callbacks_mask = mask;
+ pthread_mutex_unlock(&cache_lock);
+ return 0;
+}
+
int uc_get_rate_by_name(const char *name, gauge_t **ret_values,
size_t *ret_values_num) {
gauge_t *ret = NULL;
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 (size_t i = 0; i < iter->entry->values_num; ++i)
- *ret_values[i] = iter->entry->values_raw[i];
+ (*ret_values)[i] = iter->entry->values_raw[i];
*ret_num = iter->entry->values_num;
pthread_mutex_unlock(&cache_lock); \
return status; \
}
-int uc_meta_data_exists(const value_list_t *vl,
- const char *key) UC_WRAP(meta_data_exists)
+int uc_meta_data_exists(const value_list_t *vl, const char *key)
+ UC_WRAP(meta_data_exists)
+
+ int uc_meta_data_delete(const value_list_t *vl, const char *key)
+ UC_WRAP(meta_data_delete)
+
+ /* The second argument is called `toc` in the API, but the macro expects
+ * `key`. */
+ int uc_meta_data_toc(const value_list_t *vl,
+ char ***key) UC_WRAP(meta_data_toc)
- int uc_meta_data_delete(const value_list_t *vl,
- const char *key) UC_WRAP(meta_data_delete)
#undef UC_WRAP
/* We need a new version of this macro because the following functions take
int uc_set_hits(const data_set_t *ds, const value_list_t *vl, int hits);
int uc_inc_hits(const data_set_t *ds, const value_list_t *vl, int step);
+int uc_set_callbacks_mask(const char *name, unsigned long callbacks_mask);
+
int uc_get_history(const data_set_t *ds, const value_list_t *vl,
gauge_t *ret_history, size_t num_steps, size_t num_ds);
int uc_get_history_by_name(const char *name, gauge_t *ret_history,
*/
int uc_meta_data_exists(const value_list_t *vl, const char *key);
int uc_meta_data_delete(const value_list_t *vl, const char *key);
+/* Same API as meta_data_toc. */
+int uc_meta_data_toc(const value_list_t *vl, char ***toc);
int uc_meta_data_add_string(const value_list_t *vl, const char *key,
const char *value);
* Florian Forster <octo at collectd.org>
**/
+#ifndef UTILS_RANDOM_H
+#define UTILS_RANDOM_H 1
+
/**
* Returns a random double value in the range [0..1), i.e. excluding 1.
*
* outside the intended range. This function is thread- and reentrant-safe.
*/
long cdrand_range(long min, long max);
+
+#endif /* !UTILS_RANDOM_H */
#include <libgeom.h>
#endif
-#if HAVE_LIMITS_H
-#include <limits.h>
-#endif
#ifndef UINT_MAX
#define UINT_MAX 4294967295U
#endif
io_master_port = MACH_PORT_NULL;
return -1;
}
-/* #endif HAVE_IOKIT_IOKITLIB_H */
+ /* #endif HAVE_IOKIT_IOKITLIB_H */
#elif KERNEL_LINUX
#if HAVE_LIBUDEV_H
}
}
#endif /* HAVE_LIBUDEV_H */
-/* #endif KERNEL_LINUX */
+ /* #endif KERNEL_LINUX */
#elif KERNEL_FREEBSD
int rv;
ERROR("geom_stats_open() failed, returned %d", rv);
return -1;
}
-/* #endif KERNEL_FREEBSD */
+ /* #endif KERNEL_FREEBSD */
#elif HAVE_LIBKSTAT
kstat_t *ksp_chain;
derive_t read, derive_t write) {
value_list_t vl = VALUE_LIST_INIT;
value_t values[] = {
- {.derive = read}, {.derive = write},
+ {.derive = read},
+ {.derive = write},
};
vl.values = values;
derive_t weighted_time) {
value_list_t vl = VALUE_LIST_INIT;
value_t values[] = {
- {.derive = io_time}, {.derive = weighted_time},
+ {.derive = io_time},
+ {.derive = weighted_time},
};
vl.values = values;
sstrncpy(disk_name, props_disk_name_bsd, sizeof(disk_name));
else {
ERROR("disk plugin: can't find bsd disk name.");
- snprintf(disk_name, sizeof(disk_name), "%i-%i", disk_major, disk_minor);
+ ssnprintf(disk_name, sizeof(disk_name), "%i-%i", disk_major,
+ disk_minor);
}
} else
- snprintf(disk_name, sizeof(disk_name), "%i-%i", disk_major, disk_minor);
+ ssnprintf(disk_name, sizeof(disk_name), "%i-%i", disk_major, disk_minor);
DEBUG("disk plugin: disk_name = \"%s\"", disk_name);
disk_submit(disk_name, "disk_time", read_tme / 1000, write_tme / 1000);
}
IOObjectRelease(disk_list);
-/* #endif HAVE_IOKIT_IOKITLIB_H */
+ /* #endif HAVE_IOKIT_IOKITLIB_H */
#elif KERNEL_FREEBSD
int retry, dirty;
free(missing_ds);
}
fclose(fh);
-/* #endif defined(KERNEL_LINUX) */
+ /* #endif defined(KERNEL_LINUX) */
#elif HAVE_LIBKSTAT
#if HAVE_KSTAT_IO_T_WRITES && HAVE_KSTAT_IO_T_NWRITES && HAVE_KSTAT_IO_T_WTIME
disk_submit(ksp[i]->ks_name, "disk_ops", kio.KIO_ROPS, kio.KIO_WOPS);
}
}
-/* #endif defined(HAVE_LIBKSTAT) */
+ /* #endif defined(HAVE_LIBKSTAT) */
#elif defined(HAVE_LIBSTATGRAB)
sg_disk_io_stats *ds;
disk_submit(name, "disk_octets", ds->read_bytes, ds->write_bytes);
ds++;
}
-/* #endif defined(HAVE_LIBSTATGRAB) */
+ /* #endif defined(HAVE_LIBSTATGRAB) */
#elif defined(HAVE_PERFSTAT)
derive_t read_sectors;
static void submit_octets(derive_t queries, derive_t responses) {
value_t values[] = {
- {.derive = queries}, {.derive = responses},
+ {.derive = queries},
+ {.derive = responses},
};
value_list_t vl = VALUE_LIST_INIT;
char dev_name[DATA_MAX_NAME_LEN];
if (ec->config.link_status.port_name[i][0] != 0) {
- snprintf(dev_name, sizeof(dev_name), "%s",
- ec->config.link_status.port_name[i]);
+ ssnprintf(dev_name, sizeof(dev_name), "%s",
+ ec->config.link_status.port_name[i]);
} else {
- snprintf(dev_name, sizeof(dev_name), "port.%d", i);
+ ssnprintf(dev_name, sizeof(dev_name), "port.%d", i);
}
if (ec->config.link_status.notify) {
int sev = ec->link_info[i].link_status ? NOTIF_OKAY : NOTIF_WARNING;
char msg[DATA_MAX_NAME_LEN];
- snprintf(msg, sizeof(msg), "Link Status: %s",
- ec->link_info[i].link_status ? "UP" : "DOWN");
+ ssnprintf(msg, sizeof(msg), "Link Status: %s",
+ ec->link_info[i].link_status ? "UP" : "DOWN");
dpdk_events_notification_dispatch(sev, dev_name,
ec->link_info[i].read_time, msg);
} else {
}
char core_name[DATA_MAX_NAME_LEN];
- snprintf(core_name, sizeof(core_name), "lcore%u", i);
+ ssnprintf(core_name, sizeof(core_name), "lcore%u", i);
if (!ec->config.keep_alive.send_updated ||
(ec->core_info[i].lcore_state !=
switch (ec->config.keep_alive.shm->core_state[i]) {
case RTE_KA_STATE_ALIVE:
sev = NOTIF_OKAY;
- snprintf(msg, sizeof(msg), "lcore %u Keep Alive Status: ALIVE", i);
+ ssnprintf(msg, sizeof(msg), "lcore %u Keep Alive Status: ALIVE", i);
break;
case RTE_KA_STATE_MISSING:
- snprintf(msg, sizeof(msg), "lcore %u Keep Alive Status: MISSING", i);
+ ssnprintf(msg, sizeof(msg), "lcore %u Keep Alive Status: MISSING", i);
sev = NOTIF_WARNING;
break;
case RTE_KA_STATE_DEAD:
- snprintf(msg, sizeof(msg), "lcore %u Keep Alive Status: DEAD", i);
+ ssnprintf(msg, sizeof(msg), "lcore %u Keep Alive Status: DEAD", i);
sev = NOTIF_FAILURE;
break;
case RTE_KA_STATE_UNUSED:
- snprintf(msg, sizeof(msg), "lcore %u Keep Alive Status: UNUSED", i);
+ ssnprintf(msg, sizeof(msg), "lcore %u Keep Alive Status: UNUSED", i);
sev = NOTIF_OKAY;
break;
case RTE_KA_STATE_GONE:
- snprintf(msg, sizeof(msg), "lcore %u Keep Alive Status: GONE", i);
+ ssnprintf(msg, sizeof(msg), "lcore %u Keep Alive Status: GONE", i);
sev = NOTIF_FAILURE;
break;
case RTE_KA_STATE_DOZING:
- snprintf(msg, sizeof(msg), "lcore %u Keep Alive Status: DOZING", i);
+ ssnprintf(msg, sizeof(msg), "lcore %u Keep Alive Status: DOZING", i);
sev = NOTIF_OKAY;
break;
case RTE_KA_STATE_SLEEP:
- snprintf(msg, sizeof(msg), "lcore %u Keep Alive Status: SLEEP", i);
+ ssnprintf(msg, sizeof(msg), "lcore %u Keep Alive Status: SLEEP", i);
sev = NOTIF_OKAY;
break;
default:
- snprintf(msg, sizeof(msg), "lcore %u Keep Alive Status: UNKNOWN", i);
+ ssnprintf(msg, sizeof(msg), "lcore %u Keep Alive Status: UNKNOWN", i);
sev = NOTIF_FAILURE;
}
char dev_name[64];
if (ctx->config.port_name[i][0] != 0) {
- snprintf(dev_name, sizeof(dev_name), "%s", ctx->config.port_name[i]);
+ ssnprintf(dev_name, sizeof(dev_name), "%s", ctx->config.port_name[i]);
} else {
- snprintf(dev_name, sizeof(dev_name), "port.%d", i);
+ ssnprintf(dev_name, sizeof(dev_name), "port.%d", i);
}
DEBUG(" === Dispatch stats for port %d (name=%s; stats_count=%d)", i,
long int tmp = strtol(value, NULL, 0);
if (tmp < 1) {
- fprintf(stderr, "email plugin: `MaxConns' was set to invalid "
- "value %li, will use default %i.\n",
+ fprintf(stderr,
+ "email plugin: `MaxConns' was set to invalid "
+ "value %li, will use default %i.\n",
tmp, MAX_CONNS);
ERROR("email plugin: `MaxConns' was set to invalid "
"value %li, will use default %i.\n",
tmp, MAX_CONNS);
max_conns = MAX_CONNS;
} else if (tmp > MAX_CONNS_LIMIT) {
- fprintf(stderr, "email plugin: `MaxConns' was set to invalid "
- "value %li, will use hardcoded limit %i.\n",
+ fprintf(stderr,
+ "email plugin: `MaxConns' was set to invalid "
+ "value %li, will use hardcoded limit %i.\n",
tmp, MAX_CONNS_LIMIT);
ERROR("email plugin: `MaxConns' was set to invalid "
"value %li, will use hardcoded limit %i.\n",
#define _DEFAULT_SOURCE
#define _BSD_SOURCE /* For setgroups */
+/* _GNU_SOURCE is needed in Linux to use execvpe */
+#define _GNU_SOURCE
+
#include "collectd.h"
#include "plugin.h"
#include <sys/capability.h>
#endif
+extern char **environ;
+
#define PL_NORMAL 0x01
#define PL_NOTIF_ACTION 0x02
return 0;
} /* int exec_config }}} */
-#if !defined(HAVE_SETENV)
-static char env_interval[64];
-// max hostname len is 255, so this should be enough
-static char env_hostname[300];
-#endif
-
-static void set_environment(void) /* {{{ */
-{
-#ifdef HAVE_SETENV
- char buffer[1024];
-
- snprintf(buffer, sizeof(buffer), "%.3f",
- CDTIME_T_TO_DOUBLE(plugin_get_interval()));
- setenv("COLLECTD_INTERVAL", buffer, /* overwrite = */ 1);
-
- sstrncpy(buffer, hostname_g, sizeof(buffer));
- setenv("COLLECTD_HOSTNAME", buffer, /* overwrite = */ 1);
-#else
- snprintf(env_interval, sizeof(env_interval), "COLLECTD_INTERVAL=%.3f",
- CDTIME_T_TO_DOUBLE(plugin_get_interval()));
- putenv(env_interval);
-
- snprintf(env_hostname, sizeof(env_hostname), "COLLECTD_HOSTNAME=%s",
- hostname_g);
- putenv(env_hostname);
-#endif
-} /* }}} void set_environment */
-
-static void unset_environment(void) /* {{{ */
-{
-#ifdef HAVE_SETENV
- unsetenv("COLLECTD_INTERVAL");
- unsetenv("COLLECTD_HOSTNAME");
-#else
- snprintf(env_interval, sizeof(env_interval), "COLLECTD_INTERVAL");
- putenv(env_interval);
- snprintf(env_hostname, sizeof(env_hostname), "COLLECTD_HOSTNAME");
- putenv(env_hostname);
-#endif
-} /* }}} void unset_environment */
-
-__attribute__((noreturn)) static void exec_child(program_list_t *pl, int uid,
- int gid, int egid) /* {{{ */
+__attribute__((noreturn)) static void exec_child(program_list_t *pl,
+ char **envp, int uid, int gid,
+ int egid) /* {{{ */
{
int status;
exit(-1);
}
+#ifdef HAVE_EXECVPE
+ execvpe(pl->exec, pl->argv, envp);
+#else
+ environ = envp;
execvp(pl->exec, pl->argv);
+#endif
ERROR("exec plugin: Failed to execute ``%s'': %s", pl->exec, STRERRNO);
exit(-1);
goto failed;
}
- set_environment();
+ double interval = CDTIME_T_TO_DOUBLE(plugin_get_interval());
pid = fork();
if (pid < 0) {
ERROR("exec plugin: fork failed: %s", STRERRNO);
goto failed;
} else if (pid == 0) {
- int fd_num;
+ char interval_buf[128];
+ snprintf(interval_buf, sizeof(interval_buf), "COLLECTD_INTERVAL=%.3f",
+ interval);
+
+ /* max hostname len is 255, so this should be enough */
+ char hostname_buf[300];
+ snprintf(hostname_buf, sizeof(hostname_buf), "COLLECTD_HOSTNAME=%s",
+ hostname_g);
+
+ size_t env_size = 0;
+ while (environ[env_size] != NULL) {
+ ++env_size;
+ }
+
+ /* Copy the environment variables */
+ char *envp[env_size + 3];
+ size_t envp_idx;
+ for (envp_idx = 0; environ[envp_idx] != NULL && envp_idx < env_size;
+ ++envp_idx) {
+ envp[envp_idx] = environ[envp_idx];
+ }
+
+ /* Add the collectd environment variables */
+ envp[envp_idx++] = interval_buf;
+ envp[envp_idx++] = hostname_buf;
+ envp[envp_idx++] = NULL;
/* Close all file descriptors but the pipe end we need. */
- fd_num = getdtablesize();
+ int fd_num = getdtablesize();
for (int fd = 0; fd < fd_num; fd++) {
if ((fd == fd_pipe_in[0]) || (fd == fd_pipe_out[1]) ||
(fd == fd_pipe_err[1]))
/* Unblock all signals */
reset_signal_mask();
- exec_child(pl, uid, gid, egid);
+ exec_child(pl, envp, uid, gid, egid);
/* does not return */
}
- unset_environment();
-
close(fd_pipe_in[0]);
close(fd_pipe_out[1]);
close(fd_pipe_err[1]);
return pid;
failed:
- unset_environment();
-
close_pipe(fd_pipe_in);
close_pipe(fd_pipe_out);
close_pipe(fd_pipe_err);
else if (n->severity == NOTIF_OKAY)
severity = "OKAY";
- fprintf(fh, "Severity: %s\n"
- "Time: %.3f\n",
+ fprintf(fh,
+ "Severity: %s\n"
+ "Time: %.3f\n",
severity, CDTIME_T_TO_DOUBLE(n->time));
/* Print the optional fields */
INFO("exec plugin: Sent SIGTERM to %hu", (unsigned short int)pl->pid);
}
+ for (int i = 0; pl->argv[i] != NULL; i++) {
+ sfree(pl->argv[i]);
+ }
+ sfree(pl->argv);
+ sfree(pl->exec);
sfree(pl->user);
sfree(pl);
if (staging_tree == NULL)
return NULL;
- snprintf(key, sizeof(key), "%s/%s/%s", host, type,
- (type_instance != NULL) ? type_instance : "");
+ ssnprintf(key, sizeof(key), "%s/%s/%s", host, type,
+ (type_instance != NULL) ? type_instance : "");
se = NULL;
status = c_avl_get(staging_tree, key, (void *)&se);
#define KEY_IGNORESELECTED "IgnoreSelected"
static const char *config_keys[] = {
- KEY_GPUINDEX, KEY_IGNORESELECTED,
+ KEY_GPUINDEX,
+ KEY_IGNORESELECTED,
};
static const unsigned int n_config_keys = STATIC_ARRAY_SIZE(config_keys);
auto callback_name = grpc::string("grpc/") + addr;
user_data_t ud = {
- .data = client, .free_func = c_grpc_destroy_write_callback,
+ .data = client,
+ .free_func = c_grpc_destroy_write_callback,
};
plugin_register_write(callback_name.c_str(), c_grpc_write, &ud);
vl.values_len = 1;
sstrncpy(vl.plugin, RDT_PLUGIN, sizeof(vl.plugin));
- snprintf(vl.plugin_instance, sizeof(vl.plugin_instance), "%s", cgroup);
+ ssnprintf(vl.plugin_instance, sizeof(vl.plugin_instance), "%s", cgroup);
sstrncpy(vl.type, type, sizeof(vl.type));
if (type_instance)
sstrncpy(vl.type_instance, type_instance, sizeof(vl.type_instance));
vl.values_len = 1;
sstrncpy(vl.plugin, RDT_PLUGIN, sizeof(vl.plugin));
- snprintf(vl.plugin_instance, sizeof(vl.plugin_instance), "%s", cgroup);
+ ssnprintf(vl.plugin_instance, sizeof(vl.plugin_instance), "%s", cgroup);
sstrncpy(vl.type, type, sizeof(vl.type));
if (type_instance)
sstrncpy(vl.type_instance, type_instance, sizeof(vl.type_instance));
memset(cores, 0, sizeof(cores));
for (size_t j = 0; j < cgroup->num_cores; j++) {
- snprintf(cores + strlen(cores), sizeof(cores) - strlen(cores) - 1, " %d",
- cgroup->cores[j]);
+ ssnprintf(cores + strlen(cores), sizeof(cores) - strlen(cores) - 1, " %d",
+ cgroup->cores[j]);
}
DEBUG(RDT_PLUGIN ": group[%zu]:", i);
for (size_t i = 0; i < g_rdt->num_ngroups; i++) {
memset(names, 0, sizeof(names));
for (size_t j = 0; j < g_rdt->ngroups[i].num_names; j++)
- snprintf(names + strlen(names), sizeof(names) - strlen(names) - 1, " %s",
- g_rdt->ngroups[i].names[j]);
+ ssnprintf(names + strlen(names), sizeof(names) - strlen(names) - 1, " %s",
+ g_rdt->ngroups[i].names[j]);
DEBUG(RDT_PLUGIN ": group[%d]:", (int)i);
DEBUG(RDT_PLUGIN ": description: %s", g_rdt->ngroups[i].desc);
for (size_t j = 0; j < g_rdt->ngroups[i].num_names; ++j) {
pids_list_t *list = g_rdt->ngroups[i].proc_pids[j]->curr;
for (size_t k = 0; k < list->size; k++)
- snprintf(pids + strlen(pids), sizeof(pids) - strlen(pids) - 1, " %u",
- list->pids[k]);
+ ssnprintf(pids + strlen(pids), sizeof(pids) - strlen(pids) - 1, " %u",
+ list->pids[k]);
}
DEBUG(RDT_PLUGIN ": [%s] %s", g_rdt->ngroups[i].desc, pids);
}
continue;
if ((isdupstr((const char **)*names, *names_num, token))) {
- ERROR(RDT_PLUGIN ": Duplicated process name \'%s\' in group \'%s\'",
- token, str_list);
+ ERROR(RDT_PLUGIN ": Duplicated process name \'%s\'", token);
+
return -EINVAL;
} else {
if (0 != strarray_add(names, names_num, token)) {
}
/* update global proc_pids table */
- proc_pids_t **proc_pids = realloc(g_rdt->proc_pids,
- (g_rdt->num_proc_pids + ng->num_names) *
- sizeof(*g_rdt->proc_pids));
+ proc_pids_t **proc_pids =
+ realloc(g_rdt->proc_pids, (g_rdt->num_proc_pids + ng->num_names) *
+ sizeof(*g_rdt->proc_pids));
if (NULL == proc_pids) {
ERROR(RDT_PLUGIN ": Alloc error\n");
continue;
cgroup->num_cores = 1;
cgroup->cores[0] = i;
- snprintf(desc, sizeof(desc), "%d", g_rdt->pqos_cpu->cores[i].lcore);
+ ssnprintf(desc, sizeof(desc), "%d", g_rdt->pqos_cpu->cores[i].lcore);
cgroup->desc = strdup(desc);
if (cgroup->desc == NULL) {
ERROR(RDT_PLUGIN ": Error allocating core group description");
{.value.string = "proc1", .type = OCONFIG_TYPE_STRING},
};
oconfig_item_t config_item = {
- .values = values, .values_num = STATIC_ARRAY_SIZE(values),
+ .values = values,
+ .values_num = STATIC_ARRAY_SIZE(values),
};
/* check */
{.value.string = "proc21,proc22,proc23", .type = OCONFIG_TYPE_STRING},
};
oconfig_item_t config_item = {
- .values = values, .values_num = STATIC_ARRAY_SIZE(values),
+ .values = values,
+ .values_num = STATIC_ARRAY_SIZE(values),
};
/* check */
{.value.string = "_seventeen_chars_", .type = OCONFIG_TYPE_STRING},
};
oconfig_item_t config_item = {
- .values = values, .values_num = STATIC_ARRAY_SIZE(values),
+ .values = values,
+ .values_num = STATIC_ARRAY_SIZE(values),
};
/* check */
{.value.string = "proc21,proc,proc23", .type = OCONFIG_TYPE_STRING},
};
oconfig_item_t config_item = {
- .values = values, .values_num = STATIC_ARRAY_SIZE(values),
+ .values = values,
+ .values_num = STATIC_ARRAY_SIZE(values),
};
/* check */
{.value.string = "proc11,proc,proc,proc14", .type = OCONFIG_TYPE_STRING},
};
oconfig_item_t config_item = {
- .values = values, .values_num = STATIC_ARRAY_SIZE(values),
+ .values = values,
+ .values_num = STATIC_ARRAY_SIZE(values),
};
/* check */
};
oconfig_item_t config_item = {
- .values = values, .values_num = STATIC_ARRAY_SIZE(values),
+ .values = values,
+ .values_num = STATIC_ARRAY_SIZE(values),
};
/* check */
{.value.string = "proc11,,proc13", .type = OCONFIG_TYPE_STRING},
};
oconfig_item_t config_item = {
- .values = values, .values_num = STATIC_ARRAY_SIZE(values),
+ .values = values,
+ .values_num = STATIC_ARRAY_SIZE(values),
};
/* check */
* (Module-)Global variables
*/
static const char *config_keys[] = {
- "Interface", "IgnoreSelected", "ReportInactive",
+ "Interface",
+ "IgnoreSelected",
+ "ReportInactive",
};
static int config_keys_num = STATIC_ARRAY_SIZE(config_keys);
derive_t tx) {
value_list_t vl = VALUE_LIST_INIT;
value_t values[] = {
- {.derive = rx}, {.derive = tx},
+ {.derive = rx},
+ {.derive = tx},
};
if (ignorelist_match(ignorelist, dev) != 0)
#define IFA_TX_PACKT ifi_opackets
#define IFA_RX_ERROR ifi_ierrors
#define IFA_TX_ERROR ifi_oerrors
-/* #endif HAVE_STRUCT_IF_DATA */
+ /* #endif HAVE_STRUCT_IF_DATA */
#elif HAVE_STRUCT_NET_DEVICE_STATS
#define IFA_DATA net_device_stats
}
freeifaddrs(if_list);
-/* #endif HAVE_GETIFADDRS */
+ /* #endif HAVE_GETIFADDRS */
#elif KERNEL_LINUX
FILE *fh;
}
fclose(fh);
-/* #endif KERNEL_LINUX */
+ /* #endif KERNEL_LINUX */
#elif HAVE_LIBKSTAT
derive_t rx;
continue;
if (unique_name)
- snprintf(iname, sizeof(iname), "%s_%d_%s", ksp[i]->ks_module,
- ksp[i]->ks_instance, ksp[i]->ks_name);
+ ssnprintf(iname, sizeof(iname), "%s_%d_%s", ksp[i]->ks_module,
+ ksp[i]->ks_instance, ksp[i]->ks_name);
else
sstrncpy(iname, ksp[i]->ks_name, sizeof(iname));
if ((rx != -1LL) || (tx != -1LL))
if_submit(iname, "if_errors", rx, tx);
}
-/* #endif HAVE_LIBKSTAT */
+ /* #endif HAVE_LIBKSTAT */
#elif defined(HAVE_LIBSTATGRAB)
sg_network_io_stats *ios;
continue;
if_submit(ios[i].interface_name, "if_octets", ios[i].rx, ios[i].tx);
}
-/* #endif HAVE_LIBSTATGRAB */
+ /* #endif HAVE_LIBSTATGRAB */
#elif defined(HAVE_PERFSTAT)
perfstat_id_t id;
pagesize_g = sysconf(_SC_PAGESIZE);
return 0;
}
-/* }}} */
-/* #endif KERNEL_LINUX */
+ /* }}} */
+ /* #endif KERNEL_LINUX */
#elif KERNEL_AIX
static caddr_t ipc_get_info(cid_t cid, int cmd, int version, int stsize,
}
if (errbuf[0] == 0) {
- snprintf(errbuf, sizeof(errbuf), "Unknown error %#x", status);
+ ssnprintf(errbuf, sizeof(errbuf), "Unknown error %#x", status);
}
errbuf[sizeof(errbuf) - 1] = '\0';
sstrncpy(n.type_instance, list_item->type_instance,
sizeof(n.type_instance));
sstrncpy(n.type, list_item->sensor_type, sizeof(n.type));
- snprintf(n.message, sizeof(n.message), "sensor %s not present",
- list_item->sensor_name);
+ ssnprintf(n.message, sizeof(n.message), "sensor %s not present",
+ list_item->sensor_name);
plugin_dispatch_notification(&n);
}
sstrncpy(n.type_instance, list_item->type_instance,
sizeof(n.type_instance));
sstrncpy(n.type, list_item->sensor_type, sizeof(n.type));
- snprintf(n.message, sizeof(n.message), "sensor %s present",
- list_item->sensor_name);
+ ssnprintf(n.message, sizeof(n.message), "sensor %s present",
+ list_item->sensor_name);
plugin_dispatch_notification(&n);
}
temp[sizeof(temp) - 1] = '\0';
if (entity_id_string != NULL && strlen(temp))
- snprintf(sensor_name, sizeof(sensor_name), "%s %s", temp, entity_id_string);
+ ssnprintf(sensor_name, sizeof(sensor_name), "%s %s", temp,
+ entity_id_string);
else if (entity_id_string != NULL)
sstrncpy(sensor_name, entity_id_string, sizeof(sensor_name));
else
sensor_id_ptr = strstr(temp, "(");
if (sensor_id_ptr != NULL) {
/* `sensor_id_ptr' now points to "(123)". */
- snprintf(sensor_name, sizeof(sensor_name), "%s %s", sensor_name_ptr,
- sensor_id_ptr);
+ ssnprintf(sensor_name, sizeof(sensor_name), "%s %s", sensor_name_ptr,
+ sensor_id_ptr);
}
/* else: don't touch sensor_name. */
}
/* if sensor provides the percentage value, use "percent" collectd type
and add the `percent` to the type instance of the reported value */
if (ipmi_sensor_get_percentage(sensor)) {
- snprintf(list_item->type_instance, sizeof(list_item->type_instance),
- "percent-%s", sensor_name_ptr);
+ ssnprintf(list_item->type_instance, sizeof(list_item->type_instance),
+ "percent-%s", sensor_name_ptr);
type = "percent";
} else {
/* use type instance as a name of the sensor */
sstrncpy(n.type_instance, list_item->type_instance,
sizeof(n.type_instance));
sstrncpy(n.type, list_item->sensor_type, sizeof(n.type));
- snprintf(n.message, sizeof(n.message), "sensor %s added",
- list_item->sensor_name);
+ ssnprintf(n.message, sizeof(n.message), "sensor %s added",
+ list_item->sensor_name);
plugin_dispatch_notification(&n);
}
sstrncpy(n.type_instance, list_item->type_instance,
sizeof(n.type_instance));
sstrncpy(n.type, list_item->sensor_type, sizeof(n.type));
- snprintf(n.message, sizeof(n.message), "sensor %s removed",
- list_item->sensor_name);
+ ssnprintf(n.message, sizeof(n.message), "sensor %s removed",
+ list_item->sensor_name);
plugin_dispatch_notification(&n);
}
ipmi_get_reading_name(event_type, sensor_type, offset);
sensor_get_name(sensor, n.type_instance, sizeof(n.type_instance));
if (value_present != IPMI_NO_VALUES_PRESENT)
- snprintf(n.message, sizeof(n.message),
- "sensor %s received event: %s, value is %f", n.type_instance,
- event_state, value);
+ ssnprintf(n.message, sizeof(n.message),
+ "sensor %s received event: %s, value is %f", n.type_instance,
+ event_state, value);
else
- snprintf(n.message, sizeof(n.message),
- "sensor %s received event: %s, value not provided",
- n.type_instance, event_state);
+ ssnprintf(n.message, sizeof(n.message),
+ "sensor %s received event: %s, value not provided",
+ n.type_instance, event_state);
DEBUG("Threshold event received for sensor %s", n.type_instance);
/* both values present, so fall-through to add raw value too */
case IPMI_RAW_VALUE_PRESENT: {
char buf[DATA_MAX_NAME_LEN] = {0};
- snprintf(buf, sizeof(buf), "0x%2.2x", raw_value);
+ ssnprintf(buf, sizeof(buf), "0x%2.2x", raw_value);
plugin_notification_meta_add_string(&n, "raw", buf);
} break;
default:
const char *event_state =
ipmi_get_reading_name(event_type, sensor_type, offset);
sensor_get_name(sensor, n.type_instance, sizeof(n.type_instance));
- snprintf(n.message, sizeof(n.message), "sensor %s received event: %s",
- n.type_instance, event_state);
+ ssnprintf(n.message, sizeof(n.message), "sensor %s received event: %s",
+ n.type_instance, event_state);
DEBUG("Discrete event received for sensor %s", n.type_instance);
/* The `st->name` is used as "domain name" for ipmi_open_domain().
* That value should be unique, so we do plugin_register_complex_read()
* at first as it checks the uniqueness. */
- snprintf(callback_name, sizeof(callback_name), "ipmi/%s", st->name);
+ ssnprintf(callback_name, sizeof(callback_name), "ipmi/%s", st->name);
user_data_t ud = {
.data = st,
sstrncpy(vl.plugin, "ip6tables", sizeof(vl.plugin));
- status = snprintf(vl.plugin_instance, sizeof(vl.plugin_instance), "%s-%s",
- chain->table, chain->chain);
+ status = ssnprintf(vl.plugin_instance, sizeof(vl.plugin_instance), "%s-%s",
+ chain->table, chain->chain);
if ((status < 1) || ((unsigned int)status >= sizeof(vl.plugin_instance)))
return 0;
sstrncpy(vl.type_instance, chain->name, sizeof(vl.type_instance));
} else {
if (chain->rule_type == RTYPE_NUM)
- snprintf(vl.type_instance, sizeof(vl.type_instance), "%i",
- chain->rule.num);
+ ssnprintf(vl.type_instance, sizeof(vl.type_instance), "%i",
+ chain->rule.num);
else
sstrncpy(vl.type_instance, (char *)match->data, sizeof(vl.type_instance));
}
sstrncpy(vl.plugin, "iptables", sizeof(vl.plugin));
- status = snprintf(vl.plugin_instance, sizeof(vl.plugin_instance), "%s-%s",
- chain->table, chain->chain);
+ status = ssnprintf(vl.plugin_instance, sizeof(vl.plugin_instance), "%s-%s",
+ chain->table, chain->chain);
if ((status < 1) || ((unsigned int)status >= sizeof(vl.plugin_instance)))
return 0;
sstrncpy(vl.type_instance, chain->name, sizeof(vl.type_instance));
} else {
if (chain->rule_type == RTYPE_NUM)
- snprintf(vl.type_instance, sizeof(vl.type_instance), "%i",
- chain->rule.num);
+ ssnprintf(vl.type_instance, sizeof(vl.type_instance), "%i",
+ chain->rule.num);
else
sstrncpy(vl.type_instance, (char *)match->data, sizeof(vl.type_instance));
}
static void cipvs_submit_if(const char *pi, const char *t, const char *ti,
derive_t rx, derive_t tx) {
value_t values[] = {
- {.derive = rx}, {.derive = tx},
+ {.derive = rx},
+ {.derive = tx},
};
value_list_t vl = VALUE_LIST_INIT;
/* group = */ NULL, cbi->name, cjni_read,
/* interval = */ 0,
&(user_data_t){
- .data = cbi, .free_func = cjni_callback_info_destroy,
+ .data = cbi,
+ .free_func = cjni_callback_info_destroy,
});
(*jvm_env)->DeleteLocalRef(jvm_env, o_read);
DEBUG("java plugin: Registering new write callback: %s", cbi->name);
- plugin_register_write(
- cbi->name, cjni_write,
- &(user_data_t){
- .data = cbi, .free_func = cjni_callback_info_destroy,
- });
+ 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);
DEBUG("java plugin: Registering new flush callback: %s", cbi->name);
- plugin_register_flush(
- cbi->name, cjni_flush,
- &(user_data_t){
- .data = cbi, .free_func = cjni_callback_info_destroy,
- });
+ 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);
plugin_register_log(cbi->name, cjni_log,
&(user_data_t){
- .data = cbi, .free_func = cjni_callback_info_destroy,
+ .data = cbi,
+ .free_func = cjni_callback_info_destroy,
});
(*jvm_env)->DeleteLocalRef(jvm_env, o_log);
DEBUG("java plugin: Registering new notification callback: %s", cbi->name);
- plugin_register_notification(
- cbi->name, cjni_notification,
- &(user_data_t){
- .data = cbi, .free_func = cjni_callback_info_destroy,
- });
+ 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);
"(Ljava/lang/String;Lorg/collectd/api/CollectdLogInterface;)I",
cjni_api_register_log},
- {"registerNotification", "(Ljava/lang/String;Lorg/collectd/api/"
- "CollectdNotificationInterface;)I",
+ {"registerNotification",
+ "(Ljava/lang/String;Lorg/collectd/api/"
+ "CollectdNotificationInterface;)I",
cjni_api_register_notification},
- {"registerMatch", "(Ljava/lang/String;Lorg/collectd/api/"
- "CollectdMatchFactoryInterface;)I",
+ {"registerMatch",
+ "(Ljava/lang/String;Lorg/collectd/api/"
+ "CollectdMatchFactoryInterface;)I",
cjni_api_register_match},
- {"registerTarget", "(Ljava/lang/String;Lorg/collectd/api/"
- "CollectdTargetFactoryInterface;)I",
+ {"registerTarget",
+ "(Ljava/lang/String;Lorg/collectd/api/"
+ "CollectdTargetFactoryInterface;)I",
cjni_api_register_target},
{"log", "(ILjava/lang/String;)V", cjni_api_log},
class->object = NULL;
if (class->object == NULL) {
ERROR("java plugin: cjni_config_load_plugin: "
- "Could create a new `%s' object.",
+ "Could not create a new `%s' object.",
class->name);
cjni_thread_detach();
free(class->name);
#if !HAVE_STRERROR_R
snprintf(buf, buflen, "Error #%i; strerror_r is not available.", errnum);
-/* #endif !HAVE_STRERROR_R */
+ /* #endif !HAVE_STRERROR_R */
#elif STRERROR_R_CHAR_P
{
if ((temp != NULL) && (temp != buf) && (temp[0] != 0))
strncpy(buf, temp, buflen);
else
- strncpy(buf, "strerror_r did not return "
- "an error message",
+ strncpy(buf,
+ "strerror_r did not return "
+ "an error message",
buflen);
}
}
-/* #endif STRERROR_R_CHAR_P */
+ /* #endif STRERROR_R_CHAR_P */
#else
if (strerror_r(errnum, buf, buflen) != 0) {
- snprintf(buf, buflen, "Error #%i; "
- "Additionally, strerror_r failed.",
+ snprintf(buf, buflen,
+ "Error #%i; "
+ "Additionally, strerror_r failed.",
errnum);
}
#endif /* STRERROR_R_CHAR_P */
static int parse_values(void *payload, size_t payload_size,
lcc_value_list_t *state) {
buffer_t *b = &(buffer_t){
- .data = payload, .len = payload_size,
+ .data = payload,
+ .len = payload_size,
};
uint16_t n;
}
buffer_t *b = &(buffer_t){
- .data = signature, .len = signature_len,
+ .data = signature,
+ .len = signature_len,
};
uint8_t hash[32];
}
buffer_t *b = &(buffer_t){
- .data = data, .len = data_size,
+ .data = data,
+ .len = data_size,
};
uint16_t username_len;
static int network_parse(void *data, size_t data_size, lcc_security_level_t sl,
lcc_network_parse_options_t const *opts) {
buffer_t *b = &(buffer_t){
- .data = data, .len = data_size,
+ .data = data,
+ .len = data_size,
};
lcc_value_list_t state = {0};
uint8_t buffer[LCC_NETWORK_BUFFER_SIZE_DEFAULT];
size_t buffer_size = sizeof(buffer);
if (decode_string(raw_packet_data[i], buffer, &buffer_size)) {
- fprintf(stderr, "lcc_network_parse(raw_packet_data[%" PRIsz "]):"
- " decoding string failed\n",
+ fprintf(stderr,
+ "lcc_network_parse(raw_packet_data[%" PRIsz "]):"
+ " decoding string failed\n",
i);
return -1;
}
- int status =
- lcc_network_parse(buffer, buffer_size, (lcc_network_parse_options_t){
- .writer = nop_writer,
- });
+ int status = lcc_network_parse(buffer, buffer_size,
+ (lcc_network_parse_options_t){
+ .writer = nop_writer,
+ });
if (status != 0) {
fprintf(stderr,
"lcc_network_parse(raw_packet_data[%" PRIsz "]) = %d, want 0\n",
int status = decrypt_aes256(
&(buffer_t){
- .data = ciphertext, .len = ciphertext_len,
+ .data = ciphertext,
+ .len = ciphertext_len,
},
iv, iv_len, "admin");
if (status != 0) {
#ifndef AUX_TYPES_H
#define AUX_TYPES_H 1
-struct statement_list_s
-{
- oconfig_item_t *statement;
- int statement_num;
+struct statement_list_s {
+ oconfig_item_t *statement;
+ int statement_num;
};
typedef struct statement_list_s statement_list_t;
-struct argument_list_s
-{
- oconfig_value_t *argument;
- int argument_num;
+struct argument_list_s {
+ oconfig_value_t *argument;
+ int argument_num;
};
typedef struct argument_list_s argument_list_t;
static int config_keys_num = STATIC_ARRAY_SIZE(config_keys);
static int load_config(const char *key, const char *value) {
- if (strcasecmp(key, "ReportRelative") == 0)
+ if (strcasecmp(key, "ReportRelative") == 0) {
#ifdef _SC_NPROCESSORS_ONLN
report_relative_load = IS_TRUE(value);
#else
"is not available, because I can't determine the "
"number of CPUS on this system. Sorry.");
#endif
+ return 0;
+ }
return -1;
}
static void load_submit(gauge_t snum, gauge_t mnum, gauge_t lnum) {
value_list_t vl = VALUE_LIST_INIT;
value_t values[] = {
- {.gauge = snum}, {.gauge = mnum}, {.gauge = lnum},
+ {.gauge = snum},
+ {.gauge = mnum},
+ {.gauge = lnum},
};
vl.values = values;
else {
WARNING("load: getloadavg failed: %s", STRERRNO);
}
-/* #endif HAVE_GETLOADAVG */
+ /* #endif HAVE_GETLOADAVG */
#elif defined(KERNEL_LINUX)
gauge_t snum, mnum, lnum;
lnum = atof(fields[2]);
load_submit(snum, mnum, lnum);
-/* #endif KERNEL_LINUX */
+ /* #endif KERNEL_LINUX */
#elif HAVE_LIBSTATGRAB
gauge_t snum, mnum, lnum;
mnum = ls->min5;
lnum = ls->min15;
load_submit(snum, mnum, lnum);
-/* #endif HAVE_LIBSTATGRAB */
+ /* #endif HAVE_LIBSTATGRAB */
#elif HAVE_PERFSTAT
gauge_t snum, mnum, lnum;
mnum = (float)cputotal.loadavg[1] / (float)(1 << SBITS);
lnum = (float)cputotal.loadavg[2] / (float)(1 << SBITS);
load_submit(snum, mnum, lnum);
-/* #endif HAVE_PERFSTAT */
+ /* #endif HAVE_PERFSTAT */
#else
#error "No applicable input method."
log_level = parse_log_severity(value);
if (log_level < 0) {
log_level = LOG_INFO;
- ERROR("logfile: invalid loglevel [%s] defaulting to 'info'", value);
- return 1;
+ WARNING("logfile: invalid loglevel [%s] defaulting to 'info'", value);
+ return 0;
}
} else if (0 == strcasecmp(key, "File")) {
sfree(log_file);
if (pool_busy_cpus < 0.0)
pool_busy_cpus = 0.0;
- snprintf(typinst, sizeof(typinst), "pool-%X-busy", lparstats.pool_id);
+ ssnprintf(typinst, sizeof(typinst), "pool-%X-busy", lparstats.pool_id);
lpar_submit(typinst, pool_busy_cpus);
- snprintf(typinst, sizeof(typinst), "pool-%X-idle", lparstats.pool_id);
+ ssnprintf(typinst, sizeof(typinst), "pool-%X-idle", lparstats.pool_id);
lpar_submit(typinst, pool_idle_cpus);
}
char subname[DATA_MAX_NAME_LEN];
if (!lua_isfunction(L, 1) && lua_isstring(L, 1)) {
const char *fname = lua_tostring(L, 1);
- snprintf(subname, sizeof(subname), "%s()", fname);
+ ssnprintf(subname, sizeof(subname), "%s()", fname);
lua_getglobal(L, fname); // Push function into stack
lua_remove(L, 1); // Remove string from stack
} else {
lua_getfield(L, LUA_REGISTRYINDEX, "collectd:callback_num");
int tmp = lua_tointeger(L, -1);
- snprintf(subname, sizeof(subname), "callback_%d", tmp);
+ ssnprintf(subname, sizeof(subname), "callback_%d", tmp);
lua_pop(L, 1); // Remove old value from stack
lua_pushinteger(L, tmp + 1);
lua_setfield(L, LUA_REGISTRYINDEX, "collectd:callback_num"); // pops value
lua_getfield(L, LUA_REGISTRYINDEX, "collectd:script_path");
char function_name[DATA_MAX_NAME_LEN];
- snprintf(function_name, sizeof(function_name), "lua/%s/%s",
- lua_tostring(L, -1), subname);
+ ssnprintf(function_name, sizeof(function_name), "lua/%s/%s",
+ lua_tostring(L, -1), subname);
lua_pop(L, 1);
int callback_id = clua_store_callback(L, 1);
pthread_mutex_init(&cb->lock, NULL);
if (PLUGIN_READ == type) {
- int status =
- plugin_register_complex_read(/* group = */ "lua",
- /* name = */ function_name,
- /* callback = */ clua_read,
- /* interval = */ 0,
- &(user_data_t){
- .data = cb, .free_func = lua_cb_free,
- });
+ int status = plugin_register_complex_read(/* group = */ "lua",
+ /* name = */ function_name,
+ /* callback = */ clua_read,
+ /* interval = */ 0,
+ &(user_data_t){
+ .data = cb,
+ .free_func = lua_cb_free,
+ });
if (status != 0)
return luaL_error(L, "%s", "plugin_register_complex_read failed");
int status = plugin_register_write(/* name = */ function_name,
/* callback = */ clua_write,
&(user_data_t){
- .data = cb, .free_func = lua_cb_free,
+ .data = cb,
+ .free_func = lua_cb_free,
});
if (status != 0)
if (base_path[0] == '\0')
sstrncpy(abs_path, rel_path, sizeof(abs_path));
else
- snprintf(abs_path, sizeof(abs_path), "%s/%s", base_path, rel_path);
+ ssnprintf(abs_path, sizeof(abs_path), "%s/%s", base_path, rel_path);
DEBUG("Lua plugin: abs_path = \"%s\";", abs_path);
+++ /dev/null
-/**
- * collectd - src/lvm.c
- * Copyright (C) 2013 Chad Malfait
- * Copyright (C) 2014 Carnegie Mellon University
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; only version 2 of the License is applicable.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Authors:
- * Chad Malfait <malfaitc at yahoo.com>
- * Benjamin Gilbert <bgilbert at backtick.net>
- **/
-
-#include "collectd.h"
-
-#include "plugin.h"
-#include "utils/common/common.h"
-
-#include <lvm2app.h>
-
-#ifdef HAVE_SYS_CAPABILITY_H
-#include <sys/capability.h>
-#endif /* HAVE_SYS_CAPABILITY_H */
-
-#define NO_VALUE UINT64_MAX
-#define PERCENT_SCALE_FACTOR 1e-8
-
-static uint64_t get_lv_property_int(lv_t lv, char const *property) {
- lvm_property_value_t v;
-
- v = lvm_lv_get_property(lv, property);
- if (!v.is_valid || !v.is_integer)
- return NO_VALUE;
- /* May be NO_VALUE if @property does not apply to this LV */
- return v.value.integer;
-}
-
-static char const *get_lv_property_string(lv_t lv, char const *property) {
- lvm_property_value_t v;
-
- v = lvm_lv_get_property(lv, property);
- if (!v.is_valid || !v.is_string)
- return NULL;
- return v.value.string;
-}
-
-static void lvm_submit(char const *plugin_instance, char const *type_instance,
- uint64_t ivalue) {
- value_list_t vl = VALUE_LIST_INIT;
-
- vl.values = &(value_t){.gauge = (gauge_t)ivalue};
- vl.values_len = 1;
-
- sstrncpy(vl.plugin, "lvm", sizeof(vl.plugin));
- sstrncpy(vl.plugin_instance, plugin_instance, sizeof(vl.plugin_instance));
- sstrncpy(vl.type, "df_complex", sizeof(vl.type));
- sstrncpy(vl.type_instance, type_instance, sizeof(vl.type_instance));
-
- plugin_dispatch_values(&vl);
-}
-
-static void report_lv_utilization(lv_t lv, char const *vg_name,
- char const *lv_name, uint64_t lv_size,
- char const *used_percent_property) {
- uint64_t used_percent_unscaled;
- uint64_t used_bytes;
- char plugin_instance[DATA_MAX_NAME_LEN];
-
- used_percent_unscaled = get_lv_property_int(lv, used_percent_property);
- if (used_percent_unscaled == NO_VALUE)
- return;
- used_bytes = lv_size * (used_percent_unscaled * PERCENT_SCALE_FACTOR);
-
- snprintf(plugin_instance, sizeof(plugin_instance), "%s-%s", vg_name, lv_name);
- lvm_submit(plugin_instance, "used", used_bytes);
- lvm_submit(plugin_instance, "free", lv_size - used_bytes);
-}
-
-static void report_thin_pool_utilization(lv_t lv, char const *vg_name,
- uint64_t lv_size) {
- char const *data_lv;
- char const *metadata_lv;
- uint64_t metadata_size;
-
- data_lv = get_lv_property_string(lv, "data_lv");
- metadata_lv = get_lv_property_string(lv, "metadata_lv");
- metadata_size = get_lv_property_int(lv, "lv_metadata_size");
- if (data_lv == NULL || metadata_lv == NULL || metadata_size == NO_VALUE)
- return;
-
- report_lv_utilization(lv, vg_name, data_lv, lv_size, "data_percent");
- report_lv_utilization(lv, vg_name, metadata_lv, metadata_size,
- "metadata_percent");
-}
-
-static void vg_read(vg_t vg, char const *vg_name) {
- struct dm_list *lvs;
- struct lvm_lv_list *lvl;
- char const *name;
- char const *attrs;
- uint64_t size;
-
- lvm_submit(vg_name, "free", lvm_vg_get_free_size(vg));
-
- lvs = lvm_vg_list_lvs(vg);
- if (!lvs) {
- /* no VGs are defined, which is not an error per se */
- return;
- }
-
- dm_list_iterate_items(lvl, lvs) {
- name = lvm_lv_get_name(lvl->lv);
- attrs = get_lv_property_string(lvl->lv, "lv_attr");
- size = lvm_lv_get_size(lvl->lv);
- if (name == NULL || attrs == NULL || size == NO_VALUE)
- continue;
-
- /* Condition on volume type. We want the reported sizes in the
- volume group to sum to the size of the volume group, so we ignore
- virtual volumes. */
- switch (attrs[0]) {
- case 's':
- case 'S':
- /* Snapshot. Also report used/free space. */
- report_lv_utilization(lvl->lv, vg_name, name, size, "data_percent");
- break;
- case 't':
- /* Thin pool virtual volume. We report the underlying data
- and metadata volumes, not this one. Report used/free
- space, then ignore. */
- report_thin_pool_utilization(lvl->lv, vg_name, size);
- continue;
- case 'v':
- /* Virtual volume. Ignore. */
- continue;
- case 'V':
- /* Thin volume or thin snapshot. Ignore. */
- continue;
- }
- lvm_submit(vg_name, name, size);
- }
-}
-
-static int lvm_read(void) {
- lvm_t lvm;
- struct dm_list *vg_names;
- struct lvm_str_list *name_list;
-
- lvm = lvm_init(NULL);
- if (!lvm) {
- ERROR("lvm plugin: lvm_init failed.");
- return -1;
- }
-
- vg_names = lvm_list_vg_names(lvm);
- if (!vg_names) {
- ERROR("lvm plugin lvm_list_vg_name failed %s", lvm_errmsg(lvm));
- lvm_quit(lvm);
- return -1;
- }
-
- dm_list_iterate_items(name_list, vg_names) {
- vg_t vg;
-
- vg = lvm_vg_open(lvm, name_list->str, "r", 0);
- if (!vg) {
- ERROR("lvm plugin: lvm_vg_open (%s) failed: %s", name_list->str,
- lvm_errmsg(lvm));
- continue;
- }
-
- vg_read(vg, name_list->str);
- lvm_vg_close(vg);
- }
-
- lvm_quit(lvm);
- return 0;
-} /*lvm_read */
-
-static int c_lvm_init(void) {
-#if defined(HAVE_SYS_CAPABILITY_H) && defined(CAP_SYS_ADMIN)
- if (check_capability(CAP_SYS_ADMIN) != 0) {
- if (getuid() == 0)
- WARNING("lvm plugin: Running collectd as root, but the "
- "CAP_SYS_ADMIN capability is missing. The plugin's read "
- "function will probably fail. Is your init system dropping "
- "capabilities?");
- else
- WARNING("lvm plugin: collectd doesn't have the CAP_SYS_ADMIN "
- "capability. If you don't want to run collectd as root, try "
- "running \"setcap cap_sys_admin=ep\" on the collectd binary.");
- }
-#endif
- return 0;
-}
-
-void module_register(void) {
- plugin_register_init("lvm", c_lvm_init);
- plugin_register_read("lvm", lvm_read);
-} /* void module_register */
static void submit_derive2(const char *dev, const char *type, const char *ti1,
const char *ti2, derive_t val1, derive_t val2) {
value_t values[] = {
- {.derive = val1}, {.derive = val2},
+ {.derive = val1},
+ {.derive = val2},
};
submit(dev, type, ti1, ti2, values, STATIC_ARRAY_SIZE(values));
#ifndef MADWIFI_H
#define MADWIFI_H
-#define IEEE80211_ADDR_LEN 6 /* size of 802.11 address */
-#define IEEE80211_RATE_VAL 0x7f
-#define IEEE80211_RATE_SIZE 8 /* 802.11 standard */
-#define IEEE80211_RATE_MAXSIZE 15 /* max rates we'll handle */
-
+#define IEEE80211_ADDR_LEN 6 /* size of 802.11 address */
+#define IEEE80211_RATE_VAL 0x7f
+#define IEEE80211_RATE_SIZE 8 /* 802.11 standard */
+#define IEEE80211_RATE_MAXSIZE 15 /* max rates we'll handle */
/*
* Per/node (station) statistics available when operating as an AP.
*/
struct ieee80211_nodestats {
- u_int32_t ns_rx_data; /* rx data frames */
- u_int32_t ns_rx_mgmt; /* rx management frames */
- u_int32_t ns_rx_ctrl; /* rx control frames */
- u_int32_t ns_rx_ucast; /* rx unicast frames */
- u_int32_t ns_rx_mcast; /* rx multi/broadcast frames */
- u_int64_t ns_rx_bytes; /* rx data count (bytes) */
- u_int64_t ns_rx_beacons; /* rx beacon frames */
- u_int32_t ns_rx_proberesp; /* rx probe response frames */
+ u_int32_t ns_rx_data; /* rx data frames */
+ u_int32_t ns_rx_mgmt; /* rx management frames */
+ u_int32_t ns_rx_ctrl; /* rx control frames */
+ u_int32_t ns_rx_ucast; /* rx unicast frames */
+ u_int32_t ns_rx_mcast; /* rx multi/broadcast frames */
+ u_int64_t ns_rx_bytes; /* rx data count (bytes) */
+ u_int64_t ns_rx_beacons; /* rx beacon frames */
+ u_int32_t ns_rx_proberesp; /* rx probe response frames */
- u_int32_t ns_rx_dup; /* rx discard because it's a dup */
- u_int32_t ns_rx_noprivacy; /* rx w/ wep but privacy off */
- u_int32_t ns_rx_wepfail; /* rx wep processing failed */
- u_int32_t ns_rx_demicfail; /* rx demic failed */
- u_int32_t ns_rx_decap; /* rx decapsulation failed */
- u_int32_t ns_rx_defrag; /* rx defragmentation failed */
- u_int32_t ns_rx_disassoc; /* rx disassociation */
- u_int32_t ns_rx_deauth; /* rx deauthentication */
- u_int32_t ns_rx_decryptcrc; /* rx decrypt failed on crc */
- u_int32_t ns_rx_unauth; /* rx on unauthorized port */
- u_int32_t ns_rx_unencrypted; /* rx unecrypted w/ privacy */
+ u_int32_t ns_rx_dup; /* rx discard because it's a dup */
+ u_int32_t ns_rx_noprivacy; /* rx w/ wep but privacy off */
+ u_int32_t ns_rx_wepfail; /* rx wep processing failed */
+ u_int32_t ns_rx_demicfail; /* rx demic failed */
+ u_int32_t ns_rx_decap; /* rx decapsulation failed */
+ u_int32_t ns_rx_defrag; /* rx defragmentation failed */
+ u_int32_t ns_rx_disassoc; /* rx disassociation */
+ u_int32_t ns_rx_deauth; /* rx deauthentication */
+ u_int32_t ns_rx_decryptcrc; /* rx decrypt failed on crc */
+ u_int32_t ns_rx_unauth; /* rx on unauthorized port */
+ u_int32_t ns_rx_unencrypted; /* rx unecrypted w/ privacy */
- u_int32_t ns_tx_data; /* tx data frames */
- u_int32_t ns_tx_mgmt; /* tx management frames */
- u_int32_t ns_tx_ucast; /* tx unicast frames */
- u_int32_t ns_tx_mcast; /* tx multi/broadcast frames */
- u_int64_t ns_tx_bytes; /* tx data count (bytes) */
- u_int32_t ns_tx_probereq; /* tx probe request frames */
- u_int32_t ns_tx_uapsd; /* tx on uapsd queue */
+ u_int32_t ns_tx_data; /* tx data frames */
+ u_int32_t ns_tx_mgmt; /* tx management frames */
+ u_int32_t ns_tx_ucast; /* tx unicast frames */
+ u_int32_t ns_tx_mcast; /* tx multi/broadcast frames */
+ u_int64_t ns_tx_bytes; /* tx data count (bytes) */
+ u_int32_t ns_tx_probereq; /* tx probe request frames */
+ u_int32_t ns_tx_uapsd; /* tx on uapsd queue */
- u_int32_t ns_tx_novlantag; /* tx discard due to no tag */
- u_int32_t ns_tx_vlanmismatch; /* tx discard due to of bad tag */
+ u_int32_t ns_tx_novlantag; /* tx discard due to no tag */
+ u_int32_t ns_tx_vlanmismatch; /* tx discard due to of bad tag */
- u_int32_t ns_tx_eosplost; /* uapsd EOSP retried out */
+ u_int32_t ns_tx_eosplost; /* uapsd EOSP retried out */
- u_int32_t ns_ps_discard; /* ps discard due to of age */
+ u_int32_t ns_ps_discard; /* ps discard due to of age */
- u_int32_t ns_uapsd_triggers; /* uapsd triggers */
+ u_int32_t ns_uapsd_triggers; /* uapsd triggers */
- /* MIB-related state */
- u_int32_t ns_tx_assoc; /* [re]associations */
- u_int32_t ns_tx_assoc_fail; /* [re]association failures */
- u_int32_t ns_tx_auth; /* [re]authentications */
- u_int32_t ns_tx_auth_fail; /* [re]authentication failures*/
- u_int32_t ns_tx_deauth; /* deauthentications */
- u_int32_t ns_tx_deauth_code; /* last deauth reason */
- u_int32_t ns_tx_disassoc; /* disassociations */
- u_int32_t ns_tx_disassoc_code; /* last disassociation reason */
- u_int32_t ns_psq_drops; /* power save queue drops */
+ /* MIB-related state */
+ u_int32_t ns_tx_assoc; /* [re]associations */
+ u_int32_t ns_tx_assoc_fail; /* [re]association failures */
+ u_int32_t ns_tx_auth; /* [re]authentications */
+ u_int32_t ns_tx_auth_fail; /* [re]authentication failures*/
+ u_int32_t ns_tx_deauth; /* deauthentications */
+ u_int32_t ns_tx_deauth_code; /* last deauth reason */
+ u_int32_t ns_tx_disassoc; /* disassociations */
+ u_int32_t ns_tx_disassoc_code; /* last disassociation reason */
+ u_int32_t ns_psq_drops; /* power save queue drops */
};
/*
* Summary statistics.
*/
struct ieee80211_stats {
- u_int32_t is_rx_badversion; /* rx frame with bad version */
- u_int32_t is_rx_tooshort; /* rx frame too short */
- u_int32_t is_rx_wrongbss; /* rx from wrong bssid */
- u_int32_t is_rx_dup; /* rx discard due to it's a dup */
- u_int32_t is_rx_wrongdir; /* rx w/ wrong direction */
- u_int32_t is_rx_mcastecho; /* rx discard due to of mcast echo */
- u_int32_t is_rx_notassoc; /* rx discard due to sta !assoc */
- u_int32_t is_rx_noprivacy; /* rx w/ wep but privacy off */
- u_int32_t is_rx_unencrypted; /* rx w/o wep and privacy on */
- u_int32_t is_rx_wepfail; /* rx wep processing failed */
- u_int32_t is_rx_decap; /* rx decapsulation failed */
- u_int32_t is_rx_mgtdiscard; /* rx discard mgt frames */
- u_int32_t is_rx_ctl; /* rx discard ctrl frames */
- u_int32_t is_rx_beacon; /* rx beacon frames */
- u_int32_t is_rx_rstoobig; /* rx rate set truncated */
- u_int32_t is_rx_elem_missing; /* rx required element missing*/
- u_int32_t is_rx_elem_toobig; /* rx element too big */
- u_int32_t is_rx_elem_toosmall; /* rx element too small */
- u_int32_t is_rx_elem_unknown; /* rx element unknown */
- u_int32_t is_rx_badchan; /* rx frame w/ invalid chan */
- u_int32_t is_rx_chanmismatch; /* rx frame chan mismatch */
- u_int32_t is_rx_nodealloc; /* rx frame dropped */
- u_int32_t is_rx_ssidmismatch; /* rx frame ssid mismatch */
- u_int32_t is_rx_auth_unsupported;/* rx w/ unsupported auth alg */
- u_int32_t is_rx_auth_fail; /* rx sta auth failure */
- u_int32_t is_rx_auth_countermeasures;/* rx auth discard due to CM */
- u_int32_t is_rx_assoc_bss; /* rx assoc from wrong bssid */
- u_int32_t is_rx_assoc_notauth; /* rx assoc w/o auth */
- u_int32_t is_rx_assoc_capmismatch;/* rx assoc w/ cap mismatch */
- u_int32_t is_rx_assoc_norate; /* rx assoc w/ no rate match */
- u_int32_t is_rx_assoc_badwpaie; /* rx assoc w/ bad WPA IE */
- u_int32_t is_rx_deauth; /* rx deauthentication */
- u_int32_t is_rx_disassoc; /* rx disassociation */
- u_int32_t is_rx_badsubtype; /* rx frame w/ unknown subtype*/
- u_int32_t is_rx_nobuf; /* rx failed for lack of buf */
- u_int32_t is_rx_decryptcrc; /* rx decrypt failed on crc */
- u_int32_t is_rx_ahdemo_mgt; /* rx discard ahdemo mgt frame*/
- u_int32_t is_rx_bad_auth; /* rx bad auth request */
- u_int32_t is_rx_unauth; /* rx on unauthorized port */
- u_int32_t is_rx_badkeyid; /* rx w/ incorrect keyid */
- u_int32_t is_rx_ccmpreplay; /* rx seq# violation (CCMP) */
- u_int32_t is_rx_ccmpformat; /* rx format bad (CCMP) */
- u_int32_t is_rx_ccmpmic; /* rx MIC check failed (CCMP) */
- u_int32_t is_rx_tkipreplay; /* rx seq# violation (TKIP) */
- u_int32_t is_rx_tkipformat; /* rx format bad (TKIP) */
- u_int32_t is_rx_tkipmic; /* rx MIC check failed (TKIP) */
- u_int32_t is_rx_tkipicv; /* rx ICV check failed (TKIP) */
- u_int32_t is_rx_badcipher; /* rx failed due to of key type */
- u_int32_t is_rx_nocipherctx; /* rx failed due to key !setup */
- u_int32_t is_rx_acl; /* rx discard due to of acl policy */
- u_int32_t is_rx_ffcnt; /* rx fast frames */
- u_int32_t is_rx_badathtnl; /* driver key alloc failed */
- u_int32_t is_tx_nobuf; /* tx failed for lack of buf */
- u_int32_t is_tx_nonode; /* tx failed for no node */
- u_int32_t is_tx_unknownmgt; /* tx of unknown mgt frame */
- u_int32_t is_tx_badcipher; /* tx failed due to of key type */
- u_int32_t is_tx_nodefkey; /* tx failed due to no defkey */
- u_int32_t is_tx_noheadroom; /* tx failed due to no space */
- u_int32_t is_tx_ffokcnt; /* tx fast frames sent success */
- u_int32_t is_tx_fferrcnt; /* tx fast frames sent success */
- u_int32_t is_scan_active; /* active scans started */
- u_int32_t is_scan_passive; /* passive scans started */
- u_int32_t is_node_timeout; /* nodes timed out inactivity */
- u_int32_t is_crypto_nomem; /* no memory for crypto ctx */
- u_int32_t is_crypto_tkip; /* tkip crypto done in s/w */
- u_int32_t is_crypto_tkipenmic; /* tkip en-MIC done in s/w */
- u_int32_t is_crypto_tkipdemic; /* tkip de-MIC done in s/w */
- u_int32_t is_crypto_tkipcm; /* tkip counter measures */
- u_int32_t is_crypto_ccmp; /* ccmp crypto done in s/w */
- u_int32_t is_crypto_wep; /* wep crypto done in s/w */
- u_int32_t is_crypto_setkey_cipher;/* cipher rejected key */
- u_int32_t is_crypto_setkey_nokey;/* no key index for setkey */
- u_int32_t is_crypto_delkey; /* driver key delete failed */
- u_int32_t is_crypto_badcipher; /* unknown cipher */
- u_int32_t is_crypto_nocipher; /* cipher not available */
- u_int32_t is_crypto_attachfail; /* cipher attach failed */
- u_int32_t is_crypto_swfallback; /* cipher fallback to s/w */
- u_int32_t is_crypto_keyfail; /* driver key alloc failed */
- u_int32_t is_crypto_enmicfail; /* en-MIC failed */
- u_int32_t is_ibss_capmismatch; /* merge failed-cap mismatch */
- u_int32_t is_ibss_norate; /* merge failed-rate mismatch */
- u_int32_t is_ps_unassoc; /* ps-poll for unassoc. sta */
- u_int32_t is_ps_badaid; /* ps-poll w/ incorrect aid */
- u_int32_t is_ps_qempty; /* ps-poll w/ nothing to send */
+ u_int32_t is_rx_badversion; /* rx frame with bad version */
+ u_int32_t is_rx_tooshort; /* rx frame too short */
+ u_int32_t is_rx_wrongbss; /* rx from wrong bssid */
+ u_int32_t is_rx_dup; /* rx discard due to it's a dup */
+ u_int32_t is_rx_wrongdir; /* rx w/ wrong direction */
+ u_int32_t is_rx_mcastecho; /* rx discard due to of mcast echo */
+ u_int32_t is_rx_notassoc; /* rx discard due to sta !assoc */
+ u_int32_t is_rx_noprivacy; /* rx w/ wep but privacy off */
+ u_int32_t is_rx_unencrypted; /* rx w/o wep and privacy on */
+ u_int32_t is_rx_wepfail; /* rx wep processing failed */
+ u_int32_t is_rx_decap; /* rx decapsulation failed */
+ u_int32_t is_rx_mgtdiscard; /* rx discard mgt frames */
+ u_int32_t is_rx_ctl; /* rx discard ctrl frames */
+ u_int32_t is_rx_beacon; /* rx beacon frames */
+ u_int32_t is_rx_rstoobig; /* rx rate set truncated */
+ u_int32_t is_rx_elem_missing; /* rx required element missing*/
+ u_int32_t is_rx_elem_toobig; /* rx element too big */
+ u_int32_t is_rx_elem_toosmall; /* rx element too small */
+ u_int32_t is_rx_elem_unknown; /* rx element unknown */
+ u_int32_t is_rx_badchan; /* rx frame w/ invalid chan */
+ u_int32_t is_rx_chanmismatch; /* rx frame chan mismatch */
+ u_int32_t is_rx_nodealloc; /* rx frame dropped */
+ u_int32_t is_rx_ssidmismatch; /* rx frame ssid mismatch */
+ u_int32_t is_rx_auth_unsupported; /* rx w/ unsupported auth alg */
+ u_int32_t is_rx_auth_fail; /* rx sta auth failure */
+ u_int32_t is_rx_auth_countermeasures; /* rx auth discard due to CM */
+ u_int32_t is_rx_assoc_bss; /* rx assoc from wrong bssid */
+ u_int32_t is_rx_assoc_notauth; /* rx assoc w/o auth */
+ u_int32_t is_rx_assoc_capmismatch; /* rx assoc w/ cap mismatch */
+ u_int32_t is_rx_assoc_norate; /* rx assoc w/ no rate match */
+ u_int32_t is_rx_assoc_badwpaie; /* rx assoc w/ bad WPA IE */
+ u_int32_t is_rx_deauth; /* rx deauthentication */
+ u_int32_t is_rx_disassoc; /* rx disassociation */
+ u_int32_t is_rx_badsubtype; /* rx frame w/ unknown subtype*/
+ u_int32_t is_rx_nobuf; /* rx failed for lack of buf */
+ u_int32_t is_rx_decryptcrc; /* rx decrypt failed on crc */
+ u_int32_t is_rx_ahdemo_mgt; /* rx discard ahdemo mgt frame*/
+ u_int32_t is_rx_bad_auth; /* rx bad auth request */
+ u_int32_t is_rx_unauth; /* rx on unauthorized port */
+ u_int32_t is_rx_badkeyid; /* rx w/ incorrect keyid */
+ u_int32_t is_rx_ccmpreplay; /* rx seq# violation (CCMP) */
+ u_int32_t is_rx_ccmpformat; /* rx format bad (CCMP) */
+ u_int32_t is_rx_ccmpmic; /* rx MIC check failed (CCMP) */
+ u_int32_t is_rx_tkipreplay; /* rx seq# violation (TKIP) */
+ u_int32_t is_rx_tkipformat; /* rx format bad (TKIP) */
+ u_int32_t is_rx_tkipmic; /* rx MIC check failed (TKIP) */
+ u_int32_t is_rx_tkipicv; /* rx ICV check failed (TKIP) */
+ u_int32_t is_rx_badcipher; /* rx failed due to of key type */
+ u_int32_t is_rx_nocipherctx; /* rx failed due to key !setup */
+ u_int32_t is_rx_acl; /* rx discard due to of acl policy */
+ u_int32_t is_rx_ffcnt; /* rx fast frames */
+ u_int32_t is_rx_badathtnl; /* driver key alloc failed */
+ u_int32_t is_tx_nobuf; /* tx failed for lack of buf */
+ u_int32_t is_tx_nonode; /* tx failed for no node */
+ u_int32_t is_tx_unknownmgt; /* tx of unknown mgt frame */
+ u_int32_t is_tx_badcipher; /* tx failed due to of key type */
+ u_int32_t is_tx_nodefkey; /* tx failed due to no defkey */
+ u_int32_t is_tx_noheadroom; /* tx failed due to no space */
+ u_int32_t is_tx_ffokcnt; /* tx fast frames sent success */
+ u_int32_t is_tx_fferrcnt; /* tx fast frames sent success */
+ u_int32_t is_scan_active; /* active scans started */
+ u_int32_t is_scan_passive; /* passive scans started */
+ u_int32_t is_node_timeout; /* nodes timed out inactivity */
+ u_int32_t is_crypto_nomem; /* no memory for crypto ctx */
+ u_int32_t is_crypto_tkip; /* tkip crypto done in s/w */
+ u_int32_t is_crypto_tkipenmic; /* tkip en-MIC done in s/w */
+ u_int32_t is_crypto_tkipdemic; /* tkip de-MIC done in s/w */
+ u_int32_t is_crypto_tkipcm; /* tkip counter measures */
+ u_int32_t is_crypto_ccmp; /* ccmp crypto done in s/w */
+ u_int32_t is_crypto_wep; /* wep crypto done in s/w */
+ u_int32_t is_crypto_setkey_cipher; /* cipher rejected key */
+ u_int32_t is_crypto_setkey_nokey; /* no key index for setkey */
+ u_int32_t is_crypto_delkey; /* driver key delete failed */
+ u_int32_t is_crypto_badcipher; /* unknown cipher */
+ u_int32_t is_crypto_nocipher; /* cipher not available */
+ u_int32_t is_crypto_attachfail; /* cipher attach failed */
+ u_int32_t is_crypto_swfallback; /* cipher fallback to s/w */
+ u_int32_t is_crypto_keyfail; /* driver key alloc failed */
+ u_int32_t is_crypto_enmicfail; /* en-MIC failed */
+ u_int32_t is_ibss_capmismatch; /* merge failed-cap mismatch */
+ u_int32_t is_ibss_norate; /* merge failed-rate mismatch */
+ u_int32_t is_ps_unassoc; /* ps-poll for unassoc. sta */
+ u_int32_t is_ps_badaid; /* ps-poll w/ incorrect aid */
+ u_int32_t is_ps_qempty; /* ps-poll w/ nothing to send */
};
/*
* Retrieve per-node statistics.
*/
struct ieee80211req_sta_stats {
- union {
- /* NB: explicitly force 64-bit alignment */
- u_int8_t macaddr[IEEE80211_ADDR_LEN];
- u_int64_t pad;
- } is_u;
- struct ieee80211_nodestats is_stats;
+ union {
+ /* NB: explicitly force 64-bit alignment */
+ u_int8_t macaddr[IEEE80211_ADDR_LEN];
+ u_int64_t pad;
+ } is_u;
+ struct ieee80211_nodestats is_stats;
};
/*
* to retrieve other data like stats, unicast key, etc.
*/
struct ieee80211req_sta_info {
- u_int16_t isi_len; /* length (mult of 4) */
- u_int16_t isi_freq; /* MHz */
- u_int16_t isi_flags; /* channel flags */
- u_int16_t isi_state; /* state flags */
- u_int8_t isi_authmode; /* authentication algorithm */
- u_int8_t isi_rssi;
- u_int16_t isi_capinfo; /* capabilities */
- u_int8_t isi_athflags; /* Atheros capabilities */
- u_int8_t isi_erp; /* ERP element */
- u_int8_t isi_macaddr[IEEE80211_ADDR_LEN];
- u_int8_t isi_nrates; /* negotiated rates */
- u_int8_t isi_rates[IEEE80211_RATE_MAXSIZE];
- u_int8_t isi_txrate; /* index to isi_rates[] */
- u_int16_t isi_ie_len; /* IE length */
- u_int16_t isi_associd; /* assoc response */
- u_int16_t isi_txpower; /* current tx power */
- u_int16_t isi_vlan; /* vlan tag */
- u_int16_t isi_txseqs[17]; /* seq to be transmitted */
- u_int16_t isi_rxseqs[17]; /* seq previous for qos frames*/
- u_int16_t isi_inact; /* inactivity timer */
- u_int8_t isi_uapsd; /* UAPSD queues */
- u_int8_t isi_opmode; /* sta operating mode */
+ u_int16_t isi_len; /* length (mult of 4) */
+ u_int16_t isi_freq; /* MHz */
+ u_int16_t isi_flags; /* channel flags */
+ u_int16_t isi_state; /* state flags */
+ u_int8_t isi_authmode; /* authentication algorithm */
+ u_int8_t isi_rssi;
+ u_int16_t isi_capinfo; /* capabilities */
+ u_int8_t isi_athflags; /* Atheros capabilities */
+ u_int8_t isi_erp; /* ERP element */
+ u_int8_t isi_macaddr[IEEE80211_ADDR_LEN];
+ u_int8_t isi_nrates; /* negotiated rates */
+ u_int8_t isi_rates[IEEE80211_RATE_MAXSIZE];
+ u_int8_t isi_txrate; /* index to isi_rates[] */
+ u_int16_t isi_ie_len; /* IE length */
+ u_int16_t isi_associd; /* assoc response */
+ u_int16_t isi_txpower; /* current tx power */
+ u_int16_t isi_vlan; /* vlan tag */
+ u_int16_t isi_txseqs[17]; /* seq to be transmitted */
+ u_int16_t isi_rxseqs[17]; /* seq previous for qos frames*/
+ u_int16_t isi_inact; /* inactivity timer */
+ u_int8_t isi_uapsd; /* UAPSD queues */
+ u_int8_t isi_opmode; /* sta operating mode */
- /* XXX frag state? */
- /* variable length IE data */
+ /* XXX frag state? */
+ /* variable length IE data */
};
-
struct ath_stats {
- u_int32_t ast_watchdog; /* device reset by watchdog */
- u_int32_t ast_hardware; /* fatal hardware error interrupts */
- u_int32_t ast_bmiss; /* beacon miss interrupts */
- u_int32_t ast_rxorn; /* rx overrun interrupts */
- u_int32_t ast_rxeol; /* rx eol interrupts */
- u_int32_t ast_txurn; /* tx underrun interrupts */
- u_int32_t ast_mib; /* mib interrupts */
- u_int32_t ast_tx_packets; /* packet sent on the interface */
- u_int32_t ast_tx_mgmt; /* management frames transmitted */
- u_int32_t ast_tx_discard; /* frames discarded prior to assoc */
- u_int32_t ast_tx_invalid; /* frames discarded due to is device gone */
- u_int32_t ast_tx_qstop; /* tx queue stopped because it's full */
- u_int32_t ast_tx_encap; /* tx encapsulation failed */
- u_int32_t ast_tx_nonode; /* tx failed due to of no node */
- u_int32_t ast_tx_nobuf; /* tx failed due to of no tx buffer (data) */
- u_int32_t ast_tx_nobufmgt; /* tx failed due to of no tx buffer (mgmt)*/
- u_int32_t ast_tx_xretries; /* tx failed due to of too many retries */
- u_int32_t ast_tx_fifoerr; /* tx failed due to of FIFO underrun */
- u_int32_t ast_tx_filtered; /* tx failed due to xmit filtered */
- u_int32_t ast_tx_shortretry; /* tx on-chip retries (short) */
- u_int32_t ast_tx_longretry; /* tx on-chip retries (long) */
- u_int32_t ast_tx_badrate; /* tx failed due to of bogus xmit rate */
- u_int32_t ast_tx_noack; /* tx frames with no ack marked */
- u_int32_t ast_tx_rts; /* tx frames with rts enabled */
- u_int32_t ast_tx_cts; /* tx frames with cts enabled */
- u_int32_t ast_tx_shortpre; /* tx frames with short preamble */
- u_int32_t ast_tx_altrate; /* tx frames with alternate rate */
- u_int32_t ast_tx_protect; /* tx frames with protection */
- u_int32_t ast_rx_orn; /* rx failed due to of desc overrun */
- u_int32_t ast_rx_crcerr; /* rx failed due to of bad CRC */
- u_int32_t ast_rx_fifoerr; /* rx failed due to of FIFO overrun */
- u_int32_t ast_rx_badcrypt; /* rx failed due to of decryption */
- u_int32_t ast_rx_badmic; /* rx failed due to of MIC failure */
- u_int32_t ast_rx_phyerr; /* rx PHY error summary count */
- u_int32_t ast_rx_phy[32]; /* rx PHY error per-code counts */
- u_int32_t ast_rx_tooshort; /* rx discarded due to frame too short */
- u_int32_t ast_rx_toobig; /* rx discarded due to frame too large */
- u_int32_t ast_rx_nobuf; /* rx setup failed due to of no skbuff */
- u_int32_t ast_rx_packets; /* packet recv on the interface */
- u_int32_t ast_rx_mgt; /* management frames received */
- u_int32_t ast_rx_ctl; /* control frames received */
- int8_t ast_tx_rssi; /* tx rssi of last ack */
- int8_t ast_rx_rssi; /* rx rssi from histogram */
- u_int32_t ast_be_xmit; /* beacons transmitted */
- u_int32_t ast_be_nobuf; /* no skbuff available for beacon */
- u_int32_t ast_per_cal; /* periodic calibration calls */
- u_int32_t ast_per_calfail; /* periodic calibration failed */
- u_int32_t ast_per_rfgain; /* periodic calibration rfgain reset */
- u_int32_t ast_rate_calls; /* rate control checks */
- u_int32_t ast_rate_raise; /* rate control raised xmit rate */
- u_int32_t ast_rate_drop; /* rate control dropped xmit rate */
- u_int32_t ast_ant_defswitch; /* rx/default antenna switches */
- u_int32_t ast_ant_txswitch; /* tx antenna switches */
- u_int32_t ast_ant_rx[8]; /* rx frames with antenna */
- u_int32_t ast_ant_tx[8]; /* tx frames with antenna */
+ u_int32_t ast_watchdog; /* device reset by watchdog */
+ u_int32_t ast_hardware; /* fatal hardware error interrupts */
+ u_int32_t ast_bmiss; /* beacon miss interrupts */
+ u_int32_t ast_rxorn; /* rx overrun interrupts */
+ u_int32_t ast_rxeol; /* rx eol interrupts */
+ u_int32_t ast_txurn; /* tx underrun interrupts */
+ u_int32_t ast_mib; /* mib interrupts */
+ u_int32_t ast_tx_packets; /* packet sent on the interface */
+ u_int32_t ast_tx_mgmt; /* management frames transmitted */
+ u_int32_t ast_tx_discard; /* frames discarded prior to assoc */
+ u_int32_t ast_tx_invalid; /* frames discarded due to is device gone */
+ u_int32_t ast_tx_qstop; /* tx queue stopped because it's full */
+ u_int32_t ast_tx_encap; /* tx encapsulation failed */
+ u_int32_t ast_tx_nonode; /* tx failed due to of no node */
+ u_int32_t ast_tx_nobuf; /* tx failed due to of no tx buffer (data) */
+ u_int32_t ast_tx_nobufmgt; /* tx failed due to of no tx buffer (mgmt)*/
+ u_int32_t ast_tx_xretries; /* tx failed due to of too many retries */
+ u_int32_t ast_tx_fifoerr; /* tx failed due to of FIFO underrun */
+ u_int32_t ast_tx_filtered; /* tx failed due to xmit filtered */
+ u_int32_t ast_tx_shortretry; /* tx on-chip retries (short) */
+ u_int32_t ast_tx_longretry; /* tx on-chip retries (long) */
+ u_int32_t ast_tx_badrate; /* tx failed due to of bogus xmit rate */
+ u_int32_t ast_tx_noack; /* tx frames with no ack marked */
+ u_int32_t ast_tx_rts; /* tx frames with rts enabled */
+ u_int32_t ast_tx_cts; /* tx frames with cts enabled */
+ u_int32_t ast_tx_shortpre; /* tx frames with short preamble */
+ u_int32_t ast_tx_altrate; /* tx frames with alternate rate */
+ u_int32_t ast_tx_protect; /* tx frames with protection */
+ u_int32_t ast_rx_orn; /* rx failed due to of desc overrun */
+ u_int32_t ast_rx_crcerr; /* rx failed due to of bad CRC */
+ u_int32_t ast_rx_fifoerr; /* rx failed due to of FIFO overrun */
+ u_int32_t ast_rx_badcrypt; /* rx failed due to of decryption */
+ u_int32_t ast_rx_badmic; /* rx failed due to of MIC failure */
+ u_int32_t ast_rx_phyerr; /* rx PHY error summary count */
+ u_int32_t ast_rx_phy[32]; /* rx PHY error per-code counts */
+ u_int32_t ast_rx_tooshort; /* rx discarded due to frame too short */
+ u_int32_t ast_rx_toobig; /* rx discarded due to frame too large */
+ u_int32_t ast_rx_nobuf; /* rx setup failed due to of no skbuff */
+ u_int32_t ast_rx_packets; /* packet recv on the interface */
+ u_int32_t ast_rx_mgt; /* management frames received */
+ u_int32_t ast_rx_ctl; /* control frames received */
+ int8_t ast_tx_rssi; /* tx rssi of last ack */
+ int8_t ast_rx_rssi; /* rx rssi from histogram */
+ u_int32_t ast_be_xmit; /* beacons transmitted */
+ u_int32_t ast_be_nobuf; /* no skbuff available for beacon */
+ u_int32_t ast_per_cal; /* periodic calibration calls */
+ u_int32_t ast_per_calfail; /* periodic calibration failed */
+ u_int32_t ast_per_rfgain; /* periodic calibration rfgain reset */
+ u_int32_t ast_rate_calls; /* rate control checks */
+ u_int32_t ast_rate_raise; /* rate control raised xmit rate */
+ u_int32_t ast_rate_drop; /* rate control dropped xmit rate */
+ u_int32_t ast_ant_defswitch; /* rx/default antenna switches */
+ u_int32_t ast_ant_txswitch; /* tx antenna switches */
+ u_int32_t ast_ant_rx[8]; /* rx frames with antenna */
+ u_int32_t ast_ant_tx[8]; /* tx frames with antenna */
};
-#define SIOCGATHSTATS (SIOCDEVPRIVATE+0)
-#define SIOCGATHDIAG (SIOCDEVPRIVATE+1)
-#define SIOCGATHRADARSIG (SIOCDEVPRIVATE+2)
-#define SIOCGATHHALDIAG (SIOCDEVPRIVATE+3)
-#define SIOCG80211STATS (SIOCDEVPRIVATE+2)
+#define SIOCGATHSTATS (SIOCDEVPRIVATE + 0)
+#define SIOCGATHDIAG (SIOCDEVPRIVATE + 1)
+#define SIOCGATHRADARSIG (SIOCDEVPRIVATE + 2)
+#define SIOCGATHHALDIAG (SIOCDEVPRIVATE + 3)
+#define SIOCG80211STATS (SIOCDEVPRIVATE + 2)
/* NB: require in+out parameters so cannot use wireless extensions, yech */
-#define IEEE80211_IOCTL_GETKEY (SIOCDEVPRIVATE+3)
-#define IEEE80211_IOCTL_GETWPAIE (SIOCDEVPRIVATE+4)
-#define IEEE80211_IOCTL_STA_STATS (SIOCDEVPRIVATE+5)
-#define IEEE80211_IOCTL_STA_INFO (SIOCDEVPRIVATE+6)
-#define SIOC80211IFCREATE (SIOCDEVPRIVATE+7)
-#define SIOC80211IFDESTROY (SIOCDEVPRIVATE+8)
-#define IEEE80211_IOCTL_SCAN_RESULTS (SIOCDEVPRIVATE+9)
-
+#define IEEE80211_IOCTL_GETKEY (SIOCDEVPRIVATE + 3)
+#define IEEE80211_IOCTL_GETWPAIE (SIOCDEVPRIVATE + 4)
+#define IEEE80211_IOCTL_STA_STATS (SIOCDEVPRIVATE + 5)
+#define IEEE80211_IOCTL_STA_INFO (SIOCDEVPRIVATE + 6)
+#define SIOC80211IFCREATE (SIOCDEVPRIVATE + 7)
+#define SIOC80211IFDESTROY (SIOCDEVPRIVATE + 8)
+#define IEEE80211_IOCTL_SCAN_RESULTS (SIOCDEVPRIVATE + 9)
#endif
} /* }}} int mec_match */
void module_register(void) {
- fc_register_match(
- "empty_counter",
- (match_proc_t){
- .create = mec_create, .destroy = mec_destroy, .match = mec_match,
- });
+ fc_register_match("empty_counter", (match_proc_t){
+ .create = mec_create,
+ .destroy = mec_destroy,
+ .match = mec_match,
+ });
} /* module_register */
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;
- }
+ 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;
+ if (vl->meta == NULL)
+ return nomatch_value;
+ 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;
static int socket_receive(socket_adapter_t *self, FILE **p_file);
static mcelog_config_t g_mcelog_config = {
- .logfile = "/var/log/mcelog", .persist = false,
+ .logfile = "/var/log/mcelog",
+ .persist = false,
};
static socket_adapter_t socket_adapter = {
.sock_fd = -1,
.unix_sock =
{
- .sun_family = AF_UNIX, .sun_path = "/var/run/mcelog-client",
+ .sun_family = AF_UNIX,
+ .sun_path = "/var/run/mcelog-client",
},
.lock = PTHREAD_RWLOCK_INITIALIZER,
.close = socket_close,
int res = -1;
pthread_rwlock_rdlock(&self->lock);
struct pollfd poll_fd = {
- .fd = self->sock_fd, .events = POLLIN | POLLPRI,
+ .fd = self->sock_fd,
+ .events = POLLIN | POLLPRI,
};
if ((res = poll(&poll_fd, 1, MCELOG_POLL_TIMEOUT)) <= 0) {
/* Wait until connection establishes */
struct pollfd pollfd = {
- .fd = fd, .events = POLLOUT,
+ .fd = fd,
+ .events = POLLOUT,
};
do
status = poll(&pollfd, 1, MEMCACHED_CONNECT_TIMEOUT);
}
struct pollfd pollfd = {
- .fd = st->fd, .events = POLLOUT,
+ .fd = st->fd,
+ .events = POLLOUT,
};
do
derive_t value0, derive_t value1, memcached_t *st) {
value_list_t vl = VALUE_LIST_INIT;
value_t values[] = {
- {.derive = value0}, {.derive = value1},
+ {.derive = value0},
+ {.derive = value1},
};
memcached_init_vl(&vl, st);
gauge_t value0, gauge_t value1, memcached_t *st) {
value_list_t vl = VALUE_LIST_INIT;
value_t values[] = {
- {.gauge = value0}, {.gauge = value1},
+ {.gauge = value0},
+ {.gauge = value1},
};
memcached_init_vl(&vl, st);
}
/*
+ * Number of secs since the server started
+ */
+ else if (FIELD_IS("uptime")) {
+ submit_gauge("uptime", NULL, atof(fields[2]), st);
+ }
+
+ /*
* Number of bytes used and available (total - used)
*/
else if (FIELD_IS("bytes")) {
/* callback = */ memcached_read,
/* interval = */ 0,
&(user_data_t){
- .data = st, .free_func = memcached_free,
+ .data = st,
+ .free_func = memcached_free,
});
} /* int memcached_add_read_callback */
#include "plugin.h"
#include "utils/common/common.h"
-#ifdef HAVE_SYS_SYSCTL_H
+#if (defined(HAVE_SYS_SYSCTL_H) && defined(HAVE_SYSCTLBYNAME)) || \
+ defined(__OpenBSD__)
+/* Implies BSD variant */
#include <sys/sysctl.h>
#endif
#ifdef HAVE_SYS_VMMETER_H
static kstat_t *ksz;
/* #endif HAVE_LIBKSTAT */
-#elif HAVE_SYSCTL
+#elif HAVE_SYSCTL && __OpenBSD__
+/* OpenBSD variant does not have sysctlbyname */
static int pagesize;
-/* #endif HAVE_SYSCTL */
+/* #endif HAVE_SYSCTL && __OpenBSD__ */
#elif HAVE_LIBSTATGRAB
/* no global variables */
#if HAVE_HOST_STATISTICS
port_host = mach_host_self();
host_page_size(port_host, &pagesize);
-/* #endif HAVE_HOST_STATISTICS */
+ /* #endif HAVE_HOST_STATISTICS */
#elif HAVE_SYSCTLBYNAME
/* no init stuff */
return -1;
}
-/* #endif HAVE_LIBKSTAT */
+ /* #endif HAVE_LIBKSTAT */
-#elif HAVE_SYSCTL
+#elif HAVE_SYSCTL && __OpenBSD__
+ /* OpenBSD variant does not have sysctlbyname */
pagesize = getpagesize();
if (pagesize <= 0) {
ERROR("memory plugin: Invalid pagesize: %i", pagesize);
return -1;
}
-/* #endif HAVE_SYSCTL */
+ /* #endif HAVE_SYSCTL && __OpenBSD__ */
#elif HAVE_LIBSTATGRAB
/* no init stuff */
MEMORY_SUBMIT("wired", wired, "active", active, "inactive", inactive, "free",
free);
-/* #endif HAVE_HOST_STATISTICS */
+ /* #endif HAVE_HOST_STATISTICS */
#elif HAVE_SYSCTLBYNAME
/*
(gauge_t)sysctl_vals[3], "active", (gauge_t)sysctl_vals[4],
"inactive", (gauge_t)sysctl_vals[5], "cache",
(gauge_t)sysctl_vals[6]);
-/* #endif HAVE_SYSCTLBYNAME */
+ /* #endif HAVE_SYSCTLBYNAME */
#elif KERNEL_LINUX
FILE *fh;
else
MEMORY_SUBMIT("used", mem_used, "buffered", mem_buffered, "cached",
mem_cached, "free", mem_free, "slab", mem_slab_total);
-/* #endif KERNEL_LINUX */
+ /* #endif KERNEL_LINUX */
#elif HAVE_LIBKSTAT
/* Most of the additions here were taken as-is from the k9toolkit from
MEMORY_SUBMIT("used", (gauge_t)mem_used, "free", (gauge_t)mem_free, "locked",
(gauge_t)mem_lock, "kernel", (gauge_t)mem_kern, "arc",
(gauge_t)arcsize, "unusable", (gauge_t)mem_unus);
-/* #endif HAVE_LIBKSTAT */
+ /* #endif HAVE_LIBKSTAT */
-#elif HAVE_SYSCTL
+#elif HAVE_SYSCTL && __OpenBSD__
+ /* OpenBSD variant does not have HAVE_SYSCTLBYNAME */
int mib[] = {CTL_VM, VM_METER};
struct vmtotal vmtotal = {0};
gauge_t mem_active;
MEMORY_SUBMIT("active", mem_active, "inactive", mem_inactive, "free",
mem_free);
-/* #endif HAVE_SYSCTL */
+ /* #endif HAVE_SYSCTL && __OpenBSD__ */
#elif HAVE_LIBSTATGRAB
sg_mem_stats *ios;
MEMORY_SUBMIT("used", (gauge_t)ios->used, "cached", (gauge_t)ios->cache,
"free", (gauge_t)ios->free);
-/* #endif HAVE_LIBSTATGRAB */
+ /* #endif HAVE_LIBSTATGRAB */
#elif HAVE_PERFSTAT
perfstat_memory_total_t pmemory = {0};
vl.values_len = 1;
strncpy(vl.plugin, "mic", sizeof(vl.plugin));
- snprintf(vl.plugin_instance, sizeof(vl.plugin_instance), "%i", micnumber);
+ ssnprintf(vl.plugin_instance, sizeof(vl.plugin_instance), "%i", micnumber);
strncpy(vl.type, "memory", sizeof(vl.type));
strncpy(vl.type_instance, type_instance, sizeof(vl.type_instance));
vl.values_len = 1;
strncpy(vl.plugin, "mic", sizeof(vl.plugin));
- snprintf(vl.plugin_instance, sizeof(vl.plugin_instance), "%i", micnumber);
+ ssnprintf(vl.plugin_instance, sizeof(vl.plugin_instance), "%i", micnumber);
strncpy(vl.type, "temperature", sizeof(vl.type));
strncpy(vl.type_instance, type, sizeof(vl.type_instance));
strncpy(vl.plugin, "mic", sizeof(vl.plugin));
if (core < 0) /* global aggregation */
- snprintf(vl.plugin_instance, sizeof(vl.plugin_instance), "%i", micnumber);
+ ssnprintf(vl.plugin_instance, sizeof(vl.plugin_instance), "%i", micnumber);
else /* per-core statistics */
- snprintf(vl.plugin_instance, sizeof(vl.plugin_instance), "%i-cpu-%i",
- micnumber, core);
+ ssnprintf(vl.plugin_instance, sizeof(vl.plugin_instance), "%i-cpu-%i",
+ micnumber, core);
strncpy(vl.type, "cpu", sizeof(vl.type));
strncpy(vl.type_instance, type_instance, sizeof(vl.type_instance));
vl.values_len = 1;
strncpy(vl.plugin, "mic", sizeof(vl.plugin));
- snprintf(vl.plugin_instance, sizeof(vl.plugin_instance), "%i", micnumber);
+ ssnprintf(vl.plugin_instance, sizeof(vl.plugin_instance), "%i", micnumber);
strncpy(vl.type, type, sizeof(vl.type));
strncpy(vl.type_instance, type_instance, sizeof(vl.type_instance));
return EINVAL;
if (slave->instance[0] == 0)
- snprintf(slave->instance, sizeof(slave->instance), "slave_%i", slave->id);
+ ssnprintf(slave->instance, sizeof(slave->instance), "slave_%i", slave->id);
vl.values = &value;
vl.values_len = 1;
host->is_connected = true;
return 0;
} /* }}} int mb_init_connection */
-/* #endif LEGACY_LIBMODBUS */
+ /* #endif LEGACY_LIBMODBUS */
#else /* if !LEGACY_LIBMODBUS */
/* Version 2.9.2 */
if (status == 0) {
char name[1024];
- snprintf(name, sizeof(name), "modbus-%s", host->host);
+ ssnprintf(name, sizeof(name), "modbus-%s", host->host);
plugin_register_complex_read(/* group = */ NULL, name,
/* callback = */ mb_read,
/* interval = */ interval,
&(user_data_t){
- .data = host, .free_func = host_free,
+ .data = host,
+ .free_func = host_free,
});
} else {
host_free(host);
if (status != 0)
return status;
- status = snprintf(buf, buf_len, "%s/%s", conf->topic_prefix, name);
+ status = ssnprintf(buf, buf_len, "%s/%s", conf->topic_prefix, name);
if ((status < 0) || (((size_t)status) >= buf_len))
return ENOMEM;
ERROR("mqtt plugin: Unknown config option: %s", child->key);
}
- snprintf(cb_name, sizeof(cb_name), "mqtt/%s", conf->name);
+ ssnprintf(cb_name, sizeof(cb_name), "mqtt/%s", conf->name);
plugin_register_write(cb_name, mqtt_write,
&(user_data_t){
.data = conf,
(db->database != NULL) ? db->database : "<default>");
if (db->instance != NULL)
- snprintf(cb_name, sizeof(cb_name), "mysql-%s", db->instance);
+ ssnprintf(cb_name, sizeof(cb_name), "mysql-%s", db->instance);
else
sstrncpy(cb_name, "mysql", sizeof(cb_name));
plugin_register_complex_read(
/* group = */ NULL, cb_name, mysql_read, /* interval = */ 0,
&(user_data_t){
- .data = db, .free_func = mysql_database_free,
+ .data = db,
+ .free_func = mysql_database_free,
});
} else {
mysql_database_free(db);
static void traffic_submit(derive_t rx, derive_t tx, mysql_database_t *db) {
value_t values[] = {
- {.derive = rx}, {.derive = tx},
+ {.derive = rx},
+ {.derive = tx},
};
submit("mysql_octets", NULL, values, STATIC_ARRAY_SIZE(values), db);
if (((io == NULL) || (strcasecmp(io, "yes") != 0)) &&
(db->slave_io_running)) {
n.severity = NOTIF_WARNING;
- snprintf(n.message, sizeof(n.message),
- "slave I/O thread not started or not connected to master");
+ ssnprintf(n.message, sizeof(n.message),
+ "slave I/O thread not started or not connected to master");
plugin_dispatch_notification(&n);
db->slave_io_running = false;
} else if (((io != NULL) && (strcasecmp(io, "yes") == 0)) &&
(!db->slave_io_running)) {
n.severity = NOTIF_OKAY;
- snprintf(n.message, sizeof(n.message),
- "slave I/O thread started and connected to master");
+ ssnprintf(n.message, sizeof(n.message),
+ "slave I/O thread started and connected to master");
plugin_dispatch_notification(&n);
db->slave_io_running = true;
}
if (((sql == NULL) || (strcasecmp(sql, "yes") != 0)) &&
(db->slave_sql_running)) {
n.severity = NOTIF_WARNING;
- snprintf(n.message, sizeof(n.message), "slave SQL thread not started");
+ ssnprintf(n.message, sizeof(n.message), "slave SQL thread not started");
plugin_dispatch_notification(&n);
db->slave_sql_running = false;
} else if (((sql != NULL) && (strcasecmp(sql, "yes") == 0)) &&
(!db->slave_sql_running)) {
n.severity = NOTIF_OKAY;
- snprintf(n.message, sizeof(n.message), "slave SQL thread started");
+ ssnprintf(n.message, sizeof(n.message), "slave SQL thread started");
plugin_dispatch_notification(&n);
db->slave_sql_running = true;
}
derive_t val0, derive_t val1, cdtime_t timestamp,
cdtime_t interval) {
value_t values[] = {
- {.derive = val0}, {.derive = val1},
+ {.derive = val0},
+ {.derive = val1},
};
return submit_values(host, plugin_inst, type, type_inst, values,
gauge_t val0, gauge_t val1, cdtime_t timestamp,
cdtime_t interval) {
value_t values[] = {
- {.gauge = val0}, {.gauge = val1},
+ {.gauge = val0},
+ {.gauge = val1},
};
return submit_values(host, plugin_inst, type, type_inst, values,
if ((hostname == NULL) || (old_data == NULL) || (new_data == NULL))
return -1;
- snprintf(plugin_instance, sizeof(plugin_instance), "volume-%s",
- old_data->name);
+ ssnprintf(plugin_instance, sizeof(plugin_instance), "volume-%s",
+ old_data->name);
/* Check for and submit disk-octet values */
if (HAS_ALL_FLAGS(old_data->flags, CFG_VOLUME_PERF_IO) &&
- HAS_ALL_FLAGS(new_data->flags,
- HAVE_VOLUME_PERF_BYTES_READ |
- HAVE_VOLUME_PERF_BYTES_WRITE)) {
+ HAS_ALL_FLAGS(new_data->flags, HAVE_VOLUME_PERF_BYTES_READ |
+ HAVE_VOLUME_PERF_BYTES_WRITE)) {
submit_two_derive(
hostname, plugin_instance, "disk_octets", /* type instance = */ NULL,
(derive_t)new_data->read_bytes, (derive_t)new_data->write_bytes,
}
/* Check for, calculate and submit disk-latency values */
- if (HAS_ALL_FLAGS(old_data->flags,
- CFG_VOLUME_PERF_LATENCY | HAVE_VOLUME_PERF_OPS_READ |
- HAVE_VOLUME_PERF_OPS_WRITE |
- HAVE_VOLUME_PERF_LATENCY_READ |
- HAVE_VOLUME_PERF_LATENCY_WRITE) &&
- HAS_ALL_FLAGS(new_data->flags,
- HAVE_VOLUME_PERF_OPS_READ | HAVE_VOLUME_PERF_OPS_WRITE |
- HAVE_VOLUME_PERF_LATENCY_READ |
- HAVE_VOLUME_PERF_LATENCY_WRITE)) {
+ if (HAS_ALL_FLAGS(old_data->flags, CFG_VOLUME_PERF_LATENCY |
+ HAVE_VOLUME_PERF_OPS_READ |
+ HAVE_VOLUME_PERF_OPS_WRITE |
+ HAVE_VOLUME_PERF_LATENCY_READ |
+ HAVE_VOLUME_PERF_LATENCY_WRITE) &&
+ HAS_ALL_FLAGS(new_data->flags, HAVE_VOLUME_PERF_OPS_READ |
+ HAVE_VOLUME_PERF_OPS_WRITE |
+ HAVE_VOLUME_PERF_LATENCY_READ |
+ HAVE_VOLUME_PERF_LATENCY_WRITE)) {
gauge_t latency_per_op_read;
gauge_t latency_per_op_write;
uint64_t snap_reserve_free = v->snap_reserved;
uint64_t snap_norm_used = v->snap_used;
- snprintf(plugin_instance, sizeof(plugin_instance), "volume-%s", v->name);
+ ssnprintf(plugin_instance, sizeof(plugin_instance), "volume-%s", v->name);
- if (HAS_ALL_FLAGS(v->flags,
- HAVE_VOLUME_USAGE_SNAP_USED |
- HAVE_VOLUME_USAGE_SNAP_RSVD)) {
+ if (HAS_ALL_FLAGS(v->flags, HAVE_VOLUME_USAGE_SNAP_USED |
+ HAVE_VOLUME_USAGE_SNAP_RSVD)) {
if (v->snap_reserved > v->snap_used) {
snap_reserve_free = v->snap_reserved - v->snap_used;
snap_reserve_used = v->snap_used;
/* The space used by snapshots but not reserved for them is included in
* both, norm_used and snap_norm_used. If possible, subtract this here. */
- if (HAS_ALL_FLAGS(v->flags,
- HAVE_VOLUME_USAGE_NORM_USED |
- HAVE_VOLUME_USAGE_SNAP_USED)) {
+ if (HAS_ALL_FLAGS(v->flags, HAVE_VOLUME_USAGE_NORM_USED |
+ HAVE_VOLUME_USAGE_SNAP_USED)) {
if (norm_used >= snap_norm_used)
norm_used -= snap_norm_used;
else {
"df_complex", "snap_reserved", (double)snap_reserve_free,
/* timestamp = */ 0, interval);
- if (HAS_ALL_FLAGS(v->flags,
- HAVE_VOLUME_USAGE_SNAP_USED |
- HAVE_VOLUME_USAGE_SNAP_RSVD))
+ if (HAS_ALL_FLAGS(v->flags, HAVE_VOLUME_USAGE_SNAP_USED |
+ HAVE_VOLUME_USAGE_SNAP_RSVD))
submit_double(hostname, /* plugin instance = */ plugin_instance,
"df_complex", "snap_reserve_used",
(double)snap_reserve_used, /* timestamp = */ 0, interval);
if ((v->flags & IS_VOLUME_USAGE_OFFLINE) != 0) {
n.severity = NOTIF_OKAY;
- snprintf(n.message, sizeof(n.message), "Volume %s is now online.", v->name);
+ ssnprintf(n.message, sizeof(n.message), "Volume %s is now online.",
+ v->name);
v->flags &= ~IS_VOLUME_USAGE_OFFLINE;
} else {
n.severity = NOTIF_WARNING;
- snprintf(n.message, sizeof(n.message), "Volume %s is now offline.",
- v->name);
+ ssnprintf(n.message, sizeof(n.message), "Volume %s is now offline.",
+ v->name);
v->flags |= IS_VOLUME_USAGE_OFFLINE;
}
if (volume_name == NULL)
continue;
- snprintf(plugin_instance, sizeof(plugin_instance), "quota-%s-%s",
- volume_name, tree_name);
+ ssnprintf(plugin_instance, sizeof(plugin_instance), "quota-%s-%s",
+ volume_name, tree_name);
value = na_child_get_uint64(elem_quota, "disk-used", UINT64_MAX);
if (value != UINT64_MAX) {
continue;
/* possible TODO: make plugin instance configurable */
- snprintf(plugin_instance, sizeof(plugin_instance), "snapvault-%s",
- dest_path);
+ ssnprintf(plugin_instance, sizeof(plugin_instance), "snapvault-%s",
+ dest_path);
submit_double(hostname, plugin_instance, /* type = */ "delay", NULL,
(double)value, /* timestamp = */ 0, interval);
char cb_name[256];
if (host->vfiler)
- snprintf(cb_name, sizeof(cb_name), "netapp-%s-%s", host->name,
- host->vfiler);
+ ssnprintf(cb_name, sizeof(cb_name), "netapp-%s-%s", host->name,
+ host->vfiler);
else
- snprintf(cb_name, sizeof(cb_name), "netapp-%s", host->name);
+ ssnprintf(cb_name, sizeof(cb_name), "netapp-%s", host->name);
plugin_register_complex_read(
/* group = */ NULL, cb_name,
/* callback = */ cna_read,
/* interval = */ host->interval,
&(user_data_t){
- .data = host, .free_func = (void *)free_host_config,
+ .data = host,
+ .free_func = (void *)free_host_config,
});
return 0;
const char *type_instance, derive_t rx, derive_t tx) {
value_list_t vl = VALUE_LIST_INIT;
value_t values[] = {
- {.derive = rx}, {.derive = tx},
+ {.derive = rx},
+ {.derive = tx},
};
vl.values = values;
if (strcmp(tc_type, "filter") == 0)
numberic_id = tm->tcm_parent;
- snprintf(tc_inst, sizeof(tc_inst), "%s-%x:%x", kind, numberic_id >> 16,
- numberic_id & 0x0000FFFF);
+ ssnprintf(tc_inst, sizeof(tc_inst), "%s-%x:%x", kind, numberic_id >> 16,
+ numberic_id & 0x0000FFFF);
}
DEBUG("netlink plugin: qos_filter_cb: got %s for %s (%i).", tc_type, dev,
stats_submitted = true;
- int r = snprintf(type_instance, sizeof(type_instance), "%s-%s", tc_type,
- tc_inst);
+ int r = ssnprintf(type_instance, sizeof(type_instance), "%s-%s", tc_type,
+ tc_inst);
if ((size_t)r >= sizeof(type_instance)) {
ERROR("netlink plugin: type_instance truncated to %zu bytes, need %d",
sizeof(type_instance), r);
if (!stats_submitted && ts != NULL) {
char type_instance[DATA_MAX_NAME_LEN];
- int r = snprintf(type_instance, sizeof(type_instance), "%s-%s", tc_type,
- tc_inst);
+ int r = ssnprintf(type_instance, sizeof(type_instance), "%s-%s", tc_type,
+ tc_inst);
if ((size_t)r >= sizeof(type_instance)) {
ERROR("netlink plugin: type_instance truncated to %zu bytes, need %d",
sizeof(type_instance), r);
} else if ((strcasecmp(key, "QDisc") == 0) ||
(strcasecmp(key, "Class") == 0) ||
(strcasecmp(key, "Filter") == 0)) {
- if ((fields_num < 1) || (fields_num > 2)) {
+ if (fields_num > 2) {
ERROR("netlink plugin: Invalid number of fields for option "
"`%s'. Got %i, expected 1 or 2.",
key, fields_num);
} data;
struct sockent *next;
+ pthread_mutex_t lock;
} sockent_t;
/* 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3
LOG_ERR, &complain_forwarding,
"network plugin: A notification has been received via the network "
"and forwarding is enabled. Forwarding of notifications is currently "
- "not supported, because there is not loop-deteciton available. "
+ "not supported, because there is not loop-detection available. "
"Please contact the collectd mailing list if you need this "
"feature.");
}
return 0;
} /* }}} int parse_part_sign_sha256 */
-/* #endif HAVE_GCRYPT_H */
+ /* #endif HAVE_GCRYPT_H */
#else /* if !HAVE_GCRYPT_H */
static int parse_part_sign_sha256(sockent_t *se, /* {{{ */
return 0;
} /* }}} int parse_part_encr_aes256 */
-/* #endif HAVE_GCRYPT_H */
+ /* #endif HAVE_GCRYPT_H */
#else /* if !HAVE_GCRYPT_H */
static int parse_part_encr_aes256(sockent_t *se, /* {{{ */
sfree(se->node);
sfree(se->service);
+ pthread_mutex_destroy(&se->lock);
if (se->type == SOCKENT_TYPE_CLIENT)
free_sockent_client(&se->data.client);
ERROR("network plugin: setsockopt (bind-if): %s", STRERRNO);
return -1;
}
-/* #endif HAVE_IF_INDEXTONAME && SO_BINDTODEVICE */
+ /* #endif HAVE_IF_INDEXTONAME && SO_BINDTODEVICE */
#else
WARNING("network plugin: Cannot set the interface on a unicast "
se->service = NULL;
se->interface = 0;
se->next = NULL;
+ pthread_mutex_init(&se->lock, NULL);
if (type == SOCKENT_TYPE_SERVER) {
se->data.server.fd = NULL;
client->fd = -1;
}
+ DEBUG("network plugin: free (se = %p, addr = %p);", (void *)se,
+ (void *)client->addr);
sfree(client->addr);
client->addrlen = 0;
client->fd = -1;
continue;
}
+ DEBUG("network plugin: alloc (se = %p, addr = %p);", (void *)se,
+ (void *)client->addr);
assert(sizeof(*client->addr) >= ai_ptr->ai_addrlen);
memcpy(client->addr, ai_ptr->ai_addr, ai_ptr->ai_addrlen);
buffer_len);
for (sockent_t *se = sending_sockets; se != NULL; se = se->next) {
+ pthread_mutex_lock(&se->lock);
#if HAVE_GCRYPT_H
if (se->data.client.security_level == SECURITY_LEVEL_ENCRYPT)
network_send_buffer_encrypted(se, buffer, buffer_len);
else /* if (se->data.client.security_level == SECURITY_LEVEL_NONE) */
#endif /* HAVE_GCRYPT_H */
network_send_buffer_plain(se, buffer, buffer_len);
+ pthread_mutex_unlock(&se->lock);
} /* for (sending_sockets) */
} /* }}} void network_send_buffer */
*bind_address = malloc(sizeof(**bind_address));
if (*bind_address == NULL) {
ERROR("network plugin: network_config_set_bind_address: malloc failed.");
+ freeaddrinfo(res);
return -1;
}
(*bind_address)->ss_family = res->ai_family;
--- /dev/null
+/**
+ * Copyright (C) 2019 Florian octo Forster
+ *
+ * ISC License (ISC)
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Authors:
+ * Florian octo Forster <octo at collectd.org>
+ **/
+
+#define TEST_PLUGIN_NETWORK 1
+
+#include "network.c" /* (sic) */
+
+#include "testing.h"
+
+char *raw_packet_data[] = {
+ "0000000e6c6f63616c686f7374000008000c1513676ac3a6e0970009000c00000002800000"
+ "000002000973776170000004000973776170000005000966726565000006000f0001010000"
+ "0080ff610f420008000c1513676ac3a8fc120004000c737761705f696f0000050007696e00"
+ "0006000f00010200000000000000000008000c1513676ac3a9077d000500086f7574000006"
+ "000f00010200000000000000000008000c1513676ac3bd2a8c0002000e696e746572666163"
+ "65000003000965746830000004000e69665f6f637465747300000500050000060018000202"
+ "02000000000000000000000000000000000008000c1513676ac3bd5a970004000e69665f65"
+ "72726f7273000006001800020202000000000000000000000000000000000008000c151367"
+ "6ac3bd7fea000300076c6f000004000e69665f6f6374657473000006001800020202000000"
+ "000009e79c000000000009e79c0008000c1513676ac3bdaae60003000a776c616e30000006"
+ "001800020202000000001009fa5400000000011cf6670008000c1513676ac3bdb0e0000400"
+ "0e69665f6572726f7273000006001800020202000000000000000000000000000000000008"
+ "000c1513676ac3bd3d6d0003000965746830000004000f69665f7061636b65747300000600"
+ "1800020202000000000000000000000000000000000008000c1513676ac3bdae290003000a"
+ "776c616e300000060018000202020000000000032f8f00000000000205e50008000c151367"
+ "6ac3bdbb7b0003000c646f636b657230000006001800020202000000000000000000000000"
+ "000000000008000c1513676ac3bda0db000300076c6f000004000e69665f6572726f727300"
+ "0006001800020202000000000000000000000000000000000008000c1513676ac3bdbde800"
+ "03000c646f636b657230000006001800020202000000000000000000000000000000000008"
+ "000c1513676ac3bd8d8e000300076c6f000004000f69665f7061636b657473000006001800"
+ "0202020000000000000c9c0000000000000c9c0008000c1513676ac3bdb90b0003000c646f"
+ "636b657230000004000e69665f6f6374657473000006001800020202000000000000000000"
+ "000000000000000008000c1513676ac469b10f0002000e70726f6365737365730000030005"
+ "000004000d70735f7374617465000005000c7a6f6d62696573000006000f00010100000000"
+ "000000000008000c1513676ac469a4a30005000d736c656570696e67000006000f00010100"
+ "00000000006e400008000c1513676ac469c6320005000b706167696e67000006000f000101"
+ "00000000000000000008000c1513676ac469f06e0005000c626c6f636b6564000006000f00"
+ "010100000000000000000008000c1513676ac4698af40005000c72756e6e696e6700000600"
+ "0f00010100000000000000000008000c1513676ac469bbe10005000c73746f707065640000"
+ "06000f00010100000000000000000008000c1513676ac46b8e710004000e666f726b5f7261"
+ "74650000050005000006000f0001020000000000001bcf0008000c1513676d437f12960002"
+ "00086370750000030006300000040008637075000005000b73797374656d000006000f0001"
+ "0200000000000021870008000c1513676d437f36020005000969646c65000006000f000102"
+ "000000000005847a0008000c1513676d437f979b0005000977616974000006000f00010200"
+ "000000000005210008000c1513676d43802ff60005000c736f6674697271000006000f0001"
+ "02000000000000001f0008000c1513676d43803b3a0005000a737465616c000006000f0001"
+ "020000000000000000",
+ "0000000e6c6f63616c686f7374000008000c1513676d4380551f0009000c00000002800000"
+ "00000200086370750000030006310000040008637075000005000975736572000006000f00"
+ "01020000000000007cad0008000c1513676d43805dbe000500096e696365000006000f0001"
+ "0200000000000001de0008000c1513676d4380697d0005000b73797374656d000006000f00"
+ "01020000000000001ce80008000c1513676d438072bd0005000969646c65000006000f0001"
+ "02000000000005931c0008000c1513676d43807c430005000977616974000006000f000102"
+ "000000000000094b0008000c1513676d43808cee0005000c736f6674697271000006000f00"
+ "010200000000000000120008000c1513676d4380843a0005000e696e746572727570740000"
+ "06000f00010200000000000000000008000c1513676d438096230005000a737465616c0000"
+ "06000f00010200000000000000000008000c1513676d4380aa9c0003000632000005000975"
+ "736572000006000f00010200000000000089580008000c1513676d4380b29f000500096e69"
+ "6365000006000f00010200000000000003610008000c1513676d4380c44c0005000969646c"
+ "65000006000f000102000000000005873d0008000c1513676d4380bc0f0005000b73797374"
+ "656d000006000f000102000000000000201d0008000c1513676d4380cea400050009776169"
+ "74000006000f00010200000000000005810008000c1513676d4380d7370005000e696e7465"
+ "7272757074000006000f00010200000000000000000008000c1513676d4380ea830005000a"
+ "737465616c000006000f00010200000000000000000008000c1513676d437eef6200030006"
+ "3000000500096e696365000006000f00010200000000000003920008000c1513676d4380e0"
+ "260003000632000005000c736f6674697271000006000f0001020000000000000016000800"
+ "0c1513676d438101410003000633000005000975736572000006000f000102000000000000"
+ "7d8a0008000c1513676d438109f5000500096e696365000006000f00010200000000000004"
+ "350008000c1513676d4380244b0003000630000005000e696e74657272757074000006000f"
+ "00010200000000000000000008000c1513676d438122070003000633000005000969646c65"
+ "000006000f0001020000000000058eb60008000c1513676d43812e83000500097761697400"
+ "0006000f0001020000000000000ca80008000c1513676d438141480005000c736f66746972"
+ "71000006000f000102000000000000001e0008000c1513676d43814a5d0005000a73746561"
+ "6c000006000f00010200000000000000000008000c1513676d4381149e0005000b73797374"
+ "656d000006000f0001020000000000001b9a0008000c1513676d437ea86000030006300000"
+ "05000975736572000006000f00010200000000000089a80008000c1513676d438138190003"
+ "000633000005000e696e74657272757074000006000f00010200000000000000000008000c"
+ "1513676d438a9ca00002000e696e74657266616365000003000965746830000004000e6966"
+ "5f6f6374657473000005000500000600180002020200000000000000000000000000000000"
+ "0008000c1513676d438aea760004000f69665f7061636b6574730000060018000202020000"
+ "00000000000000000000000000000008000c1513676d438b214d0004000e69665f6572726f"
+ "727300000600180002020200000000000000000000000000000000",
+ "0000000e6c6f63616c686f7374000008000c1513676d438aac590009000c00000002800000"
+ "000002000764660000030009726f6f74000004000f64665f636f6d706c6578000005000966"
+ "726565000006000f0001010000004c077e57420008000c1513676d438b6ada0005000d7265"
+ "736572766564000006000f00010100000000338116420008000c1513676d438b7a17000200"
+ "0e696e7465726661636500000300076c6f000004000e69665f6f6374657473000005000500"
+ "0006001800020202000000000009ecf5000000000009ecf50008000c1513676d438b757800"
+ "02000764660000030009726f6f74000004000f64665f636f6d706c65780000050009757365"
+ "64000006000f000101000000e0a41b26420008000c1513676d438b8ed20002000e696e7465"
+ "726661636500000300076c6f000004000e69665f6572726f72730000050005000006001800"
+ "020202000000000000000000000000000000000008000c1513676d438b86bf0004000f6966"
+ "5f7061636b6574730000060018000202020000000000000c9d0000000000000c9d0008000c"
+ "1513676d438bb3e60003000a776c616e300000060018000202020000000000032fab000000"
+ "00000205ed0008000c1513676d438bd62e0003000c646f636b657230000004000e69665f6f"
+ "6374657473000006001800020202000000000000000000000000000000000008000c151367"
+ "6d438bbc8f0003000a776c616e30000004000e69665f6572726f7273000006001800020202"
+ "000000000000000000000000000000000008000c1513676d438bdf030003000c646f636b65"
+ "7230000004000f69665f7061636b6574730000060018000202020000000000000000000000"
+ "00000000000008000c1513676d438baaf10003000a776c616e30000004000e69665f6f6374"
+ "65747300000600180002020200000000100a042300000000011cfa460008000c1513676d43"
+ "8c5f100002000764660000030009626f6f74000004000f64665f636f6d706c657800000500"
+ "0966726565000006000f0001010000000010e198410008000c1513676d438c689c0005000d"
+ "7265736572766564000006000f00010100000000804c68410008000c1513676d438c70ce00"
+ "05000975736564000006000f0001010000000020ea9e410008000c1513676d438be7bc0002"
+ "000e696e74657266616365000003000c646f636b657230000004000e69665f6572726f7273"
+ "0000050005000006001800020202000000000000000000000000000000000008000c151367"
+ "6d43beca8c0002000c656e74726f70790000030005000004000c656e74726f707900000600"
+ "0f0001010000000000088f400008000c1513676d43bf1d13000200096c6f61640000040009"
+ "6c6f6164000006002100030101019a9999999999a93f666666666666d63f5c8fc2f5285cdf"
+ "3f0008000c1513676d43c02b85000200096469736b00000300087364610000040010646973"
+ "6b5f6f63746574730000060018000202020000000075887800000000005b6f3c000008000c"
+ "1513676d43c06d1f0004000d6469736b5f6f7073000006001800020202000000000003cbbd"
+ "000000000001c0510008000c1513676d43c08b6a0004000e6469736b5f74696d6500000600"
+ "1800020202000000000000003f00000000000001720008000c1513676d43c0a5fb00040010"
+ "6469736b5f6d65726765640000060018000202020000000000001285000000000000f80100"
+ "08000c1513676d43c0c8b4000300097364613100000400106469736b5f6f63746574730000"
+ "060018000202020000000001107c000000000000003c00",
+ "0000000e6c6f63616c686f7374000008000c1513676d43c0d00a0009000c00000002800000"
+ "00000200096469736b000003000973646131000004000d6469736b5f6f7073000006001800"
+ "020202000000000000029b00000000000000080008000c1513676d43c0d7b20004000e6469"
+ "736b5f74696d650000060018000202020000000000000004000000000000000f0008000c15"
+ "13676d43c0df73000400106469736b5f6d6572676564000006001800020202000000000000"
+ "0fb400000000000000010008000c1513676d43c0f87c000300097364613200000400106469"
+ "736b5f6f637465747300000600180002020200000000000008000000000000000000000800"
+ "0c1513676d43c1003e0004000d6469736b5f6f707300000600180002020200000000000000"
+ "0200000000000000000008000c1513676d43c107bf000400106469736b5f6d657267656400"
+ "0006001800020202000000000000000000000000000000000008000c1513676d43c12fa400"
+ "03000973646135000004000d6469736b5f6f7073000006001800020202000000000003c867"
+ "000000000001aef20008000c1513676d43c13d5e000400106469736b5f6d65726765640000"
+ "0600180002020200000000000002d1000000000000f8000008000c1513676d43c136a90004"
+ "000e6469736b5f74696d65000006001800020202000000000000003f000000000000011c00"
+ "08000c1513676d43c1740500030009646d2d3000000400106469736b5f6f63746574730000"
+ "060018000202020000000074596400000000005b6f00000008000c1513676d43c179c70004"
+ "000d6469736b5f6f7073000006001800020202000000000003cae4000000000002b0f30008"
+ "000c1513676d43c18abe000400106469736b5f6d6572676564000006001800020202000000"
+ "000000000000000000000000000008000c1513676d43c181b90004000e6469736b5f74696d"
+ "650000060018000202020000000000000040000000000000013e0008000c1513676d43c1a9"
+ "5e00030009646d2d3100000400106469736b5f6f6374657473000006001800020202000000"
+ "00000e000000000000000000000008000c1513676d43c1b7ea0004000e6469736b5f74696d"
+ "65000006001800020202000000000000000200000000000000000008000c1513676d43c1b0"
+ "3e0004000d6469736b5f6f707300000600180002020200000000000000e000000000000000"
+ "000008000c1513676d43c1c00d000400106469736b5f6d6572676564000006001800020202"
+ "000000000000000000000000000000000008000c1513676d43c12818000300097364613500"
+ "000400106469736b5f6f637465747300000600180002020200000000746c6400000000005b"
+ "6f00000008000c1513676d43d320a80002000c62617474657279000003000630000004000b"
+ "636861726765000006000f0001018fc2f5285c2f58400008000c1513676d43d36fd6000400"
+ "0c63757272656e74000006000f00010100000000000000800008000c1513676d43d3cdb600"
+ "04000c766f6c74616765000006000f000101736891ed7cbf28400008000c1513676d43d59d"
+ "d60002000869727100000300050000040008697271000005000630000006000f0001020000"
+ "0000000000110008000c1513676d43d5d2cf0005000631000006000f000102000000000000"
+ "00100008000c1513676d43d5fe820005000638000006000f00010200000000000000010008"
+ "000c1513676d43d635440005000639000006000f00010200000000000035210008000c1513"
+ "676d43d66265000500073132000006000f0001020000000000000790",
+ "0000000e6c6f63616c686f7374000008000c1513676d43d68e940009000c00000002800000"
+ "0000020008697271000004000869727100000500073136000006000f000102000000000000"
+ "00210008000c1513676d43d69be20002000a7573657273000004000a757365727300000500"
+ "05000006000f00010100000000000010400008000c1513676d43d6aa5d0002000869727100"
+ "0004000869727100000500073233000006000f00010200000000000000250008000c151367"
+ "6d43d6c7dc000500073431000006000f000102000000000000ff7d0008000c1513676d43d6"
+ "e23d000500073432000006000f00010200000000000008070008000c1513676d43d9aa3a00"
+ "0500073437000006000f0001020000000000079a260008000c1513676d43d9cca900050007"
+ "3438000006000f00010200000000000000c70008000c1513676d43d9ea5d00050007343900"
+ "0006000f00010200000000000004c20008000c1513676d43da050e00050007353000000600"
+ "0f000102000000000000001c0008000c1513676d43da1efa000500084e4d49000006000f00"
+ "010200000000000000000008000c1513676d43da3c82000500084c4f43000006000f000102"
+ "000000000018d3080008000c1513676d43da544e00050008535055000006000f0001020000"
+ "0000000000000008000c1513676d43da6cca00050008504d49000006000f00010200000000"
+ "000000000008000c1513676d43da885400050008495749000006000f000102000000000000"
+ "a9da0008000c1513676d43daa23a00050008525452000006000f0001020000000000000003"
+ "0008000c1513676d43dabaed00050008524553000006000f00010200000000000ac8360008"
+ "000c1513676d43dad4150005000843414c000006000f000102000000000000191f0008000c"
+ "1513676d43daeef300050008544c42000006000f000102000000000003dbdc0008000c1513"
+ "676d43db11410005000854524d000006000f00010200000000000000000008000c1513676d"
+ "43db292c00050008544852000006000f00010200000000000000000008000c1513676d43db"
+ "411d000500084d4345000006000f00010200000000000000000008000c1513676d43db5b59"
+ "000500084d4350000006000f000102000000000000003c0008000c1513676d43db68010005"
+ "0008455252000006000f00010200000000000000000008000c1513676d43db758a00050008"
+ "4d4953000006000f00010200000000000000000008000c1513676d43dd2e800002000b6d65"
+ "6d6f7279000004000b6d656d6f7279000005000975736564000006000f00010100000000fe"
+ "bbe0410008000c1513676d43dd3f4b0005000d6275666665726564000006000f0001010000"
+ "000070fbc8410008000c1513676d43dd48700005000b636163686564000006000f00010100"
+ "000000c008df410008000c1513676d43dd51c60005000966726565000006000f0001010000"
+ "0080481d05420008000c1513676d43dec7e300020009737761700000040009737761700000"
+ "05000975736564000006000f00010100000000000000000008000c1513676d43ded4490005"
+ "000966726565000006000f00010100000080ff610f420008000c1513676d43dedcfd000500"
+ "0b636163686564000006000f00010100000000000000000008000c1513676d43d715e30002"
+ "0008697271000004000869727100000500073434000006000f0001020000000000031b6100"
+ "08000c1513676d43d73116000500073435000006000f00010200000000000000180008000c"
+ "1513676d43ee00150002000973776170000004000c737761705f696f0000050007696e0000"
+ "06000f0001020000000000000000",
+};
+
+static int decode_string(char const *in, uint8_t *out, size_t *out_size) {
+ size_t in_size = strlen(in);
+ if (*out_size < (in_size / 2))
+ return -1;
+ *out_size = in_size / 2;
+
+ for (size_t i = 0; i < *out_size; i++) {
+ char tmp[] = {in[2 * i], in[2 * i + 1], 0};
+ out[i] = (uint8_t)strtoul(tmp, NULL, 16);
+ }
+
+ return 0;
+}
+
+DEF_TEST(parse_packet) {
+ sockent_t se = {
+ .data.server =
+ (struct sockent_server){
+#if HAVE_GCRYPT_H
+ .cypher = NULL,
+ .userdb = NULL,
+ .security_level = SECURITY_LEVEL_NONE,
+#endif
+ },
+ };
+
+ for (size_t i = 0; i < sizeof(raw_packet_data) / sizeof(raw_packet_data[0]);
+ i++) {
+ uint8_t buffer[network_config_packet_size];
+ size_t buffer_size = sizeof(buffer);
+
+ EXPECT_EQ_INT(0, decode_string(raw_packet_data[i], buffer, &buffer_size));
+ EXPECT_EQ_INT(0, parse_packet(&se, buffer, buffer_size, 0, NULL));
+ }
+ EXPECT_EQ_INT(139, (int)stats_values_dispatched);
+
+ return 0;
+}
+
+int main() {
+ RUN_TEST(parse_packet);
+
+ END_TEST;
+}
#if KERNEL_LINUX
static int nfs_init(void) { return 0; }
-/* #endif KERNEL_LINUX */
+ /* #endif KERNEL_LINUX */
#elif HAVE_LIBKSTAT
static int nfs_init(void) {
return 0;
}
-/* #endif KERNEL_LINUX */
+ /* #endif KERNEL_LINUX */
#elif HAVE_LIBKSTAT
static int nfs_read(void) {
curl_easy_setopt(curl, CURLOPT_PASSWORD, (pass == NULL) ? "" : pass);
#else
static char credentials[1024];
- int status = snprintf(credentials, sizeof(credentials), "%s:%s", user,
- pass == NULL ? "" : pass);
+ int status = ssnprintf(credentials, sizeof(credentials), "%s:%s", user,
+ pass == NULL ? "" : pass);
if ((status < 0) || ((size_t)status >= sizeof(credentials))) {
ERROR("nginx plugin: Credentials would have been truncated.");
return -1;
timeout = fail_timeout;
}
- snprintf(summary, sizeof(summary), "collectd %s notification",
- (NOTIF_FAILURE == n->severity)
- ? "FAILURE"
- : (NOTIF_WARNING == n->severity)
- ? "WARNING"
- : (NOTIF_OKAY == n->severity) ? "OKAY" : "UNKNOWN");
+ ssnprintf(summary, sizeof(summary), "collectd %s notification",
+ (NOTIF_FAILURE == n->severity)
+ ? "FAILURE"
+ : (NOTIF_WARNING == n->severity)
+ ? "WARNING"
+ : (NOTIF_OKAY == n->severity) ? "OKAY" : "UNKNOWN");
notification = notify_notification_new(summary, n->message, NULL
#if NOTIFY_CHECK_VERSION(0, 7, 0)
- );
+ );
#else
,
NULL);
static int notify_email_init(void) {
char server[MAXSTRING];
- snprintf(server, sizeof(server), "%s:%i",
- (smtp_host == NULL) ? DEFAULT_SMTP_HOST : smtp_host, smtp_port);
+ ssnprintf(server, sizeof(server), "%s:%i",
+ (smtp_host == NULL) ? DEFAULT_SMTP_HOST : smtp_host, smtp_port);
pthread_mutex_lock(&session_lock);
char *buf_ptr = buf;
int buf_len = sizeof(buf);
- snprintf(severity, sizeof(severity), "%s",
- (n->severity == NOTIF_FAILURE)
- ? "FAILURE"
- : ((n->severity == NOTIF_WARNING)
- ? "WARNING"
- : ((n->severity == NOTIF_OKAY) ? "OKAY" : "UNKNOWN")));
+ ssnprintf(severity, sizeof(severity), "%s",
+ (n->severity == NOTIF_FAILURE)
+ ? "FAILURE"
+ : ((n->severity == NOTIF_WARNING)
+ ? "WARNING"
+ : ((n->severity == NOTIF_OKAY) ? "OKAY" : "UNKNOWN")));
- snprintf(subject, sizeof(subject),
- (email_subject == NULL) ? DEFAULT_SMTP_SUBJECT : email_subject,
- severity, n->host);
+ ssnprintf(subject, sizeof(subject),
+ (email_subject == NULL) ? DEFAULT_SMTP_SUBJECT : email_subject,
+ severity, n->host);
localtime_r(&CDTIME_T_TO_TIME_T(n->time), ×tamp_tm);
strftime(timestamp_str, sizeof(timestamp_str), "%Y-%m-%d %H:%M:%S",
timestamp_str[sizeof(timestamp_str) - 1] = '\0';
/* Let's make RFC822 message text with \r\n EOLs */
- int status = snprintf(buf, buf_len,
- "MIME-Version: 1.0\r\n"
- "Content-Type: text/plain; charset=\"US-ASCII\"\r\n"
- "Content-Transfer-Encoding: 8bit\r\n"
- "Subject: %s\r\n"
- "\r\n"
- "%s - %s@%s\r\n"
- "\r\n",
- subject, timestamp_str, severity, n->host);
+ int status = ssnprintf(buf, buf_len,
+ "MIME-Version: 1.0\r\n"
+ "Content-Type: text/plain; charset=\"US-ASCII\"\r\n"
+ "Content-Transfer-Encoding: 8bit\r\n"
+ "Subject: %s\r\n"
+ "\r\n"
+ "%s - %s@%s\r\n"
+ "\r\n",
+ subject, timestamp_str, severity, n->host);
if (status > 0) {
buf_ptr += status;
#define APPEND(format, value) \
if ((buf_len > 0) && (strlen(value) > 0)) { \
- status = snprintf(buf_ptr, buf_len, format "\r\n", value); \
+ status = ssnprintf(buf_ptr, buf_len, format "\r\n", value); \
if (status > 0) { \
buf_ptr += status; \
buf_len -= status; \
/* name = */ cb_name,
/* callback = */ nut_read,
/* interval = */ 0,
- /* user_data = */ &(user_data_t){
- .data = ups, .free_func = free_nut_ups_t,
+ /* user_data = */
+ &(user_data_t){
+ .data = ups,
+ .free_func = free_nut_ups_t,
});
sfree(cb_name);
char file[4096];
char *endptr;
- snprintf(file, sizeof(file), "%s/%s", path,
- family_info->features[i].filename);
+ ssnprintf(file, sizeof(file), "%s/%s", path,
+ family_info->features[i].filename);
file[sizeof(file) - 1] = '\0';
buffer = NULL;
char subpath[4096];
int status;
- status = snprintf(subpath, sizeof(subpath), "%s/main", path);
+ status = ssnprintf(subpath, sizeof(subpath), "%s/main", path);
if ((status > 0) && (status < (int)sizeof(subpath)))
cow_read_bus(subpath);
- status = snprintf(subpath, sizeof(subpath), "%s/aux", path);
+ status = ssnprintf(subpath, sizeof(subpath), "%s/aux", path);
if ((status > 0) && (status < (int)sizeof(subpath)))
cow_read_bus(subpath);
dummy = NULL;
if (strcmp("/", path) == 0)
- status = snprintf(subpath, sizeof(subpath), "/%s", buffer_ptr);
+ status = ssnprintf(subpath, sizeof(subpath), "/%s", buffer_ptr);
else
- status = snprintf(subpath, sizeof(subpath), "%s/%s", path, buffer_ptr);
+ status = ssnprintf(subpath, sizeof(subpath), "%s/%s", path, buffer_ptr);
if ((status <= 0) || (status >= (int)sizeof(subpath)))
continue;
if ((olmbdb_list =
ldap_get_values_len(st->ld, e, "olmBDBEntryCache")) != NULL) {
olmbdb_data = *olmbdb_list[0];
- snprintf(typeinst, sizeof(typeinst), "bdbentrycache-%s",
- nc_data.bv_val);
+ ssnprintf(typeinst, sizeof(typeinst), "bdbentrycache-%s",
+ nc_data.bv_val);
cldap_submit_gauge("cache_size", typeinst, atoll(olmbdb_data.bv_val),
st);
ldap_value_free_len(olmbdb_list);
if ((olmbdb_list = ldap_get_values_len(st->ld, e, "olmBDBDNCache")) !=
NULL) {
olmbdb_data = *olmbdb_list[0];
- snprintf(typeinst, sizeof(typeinst), "bdbdncache-%s", nc_data.bv_val);
+ ssnprintf(typeinst, sizeof(typeinst), "bdbdncache-%s",
+ nc_data.bv_val);
cldap_submit_gauge("cache_size", typeinst, atoll(olmbdb_data.bv_val),
st);
ldap_value_free_len(olmbdb_list);
if ((olmbdb_list = ldap_get_values_len(st->ld, e, "olmBDBIDLCache")) !=
NULL) {
olmbdb_data = *olmbdb_list[0];
- snprintf(typeinst, sizeof(typeinst), "bdbidlcache-%s",
- nc_data.bv_val);
+ ssnprintf(typeinst, sizeof(typeinst), "bdbidlcache-%s",
+ nc_data.bv_val);
cldap_submit_gauge("cache_size", typeinst, atoll(olmbdb_data.bv_val),
st);
ldap_value_free_len(olmbdb_list);
char callback_name[3 * DATA_MAX_NAME_LEN] = {0};
- snprintf(callback_name, sizeof(callback_name), "openldap/%s/%s",
- (st->host != NULL) ? st->host : hostname_g,
- (st->name != NULL) ? st->name : "default");
+ ssnprintf(callback_name, sizeof(callback_name), "openldap/%s/%s",
+ (st->host != NULL) ? st->host : hostname_g,
+ (st->name != NULL) ? st->name : "default");
return plugin_register_complex_read(/* group = */ NULL,
/* name = */ callback_name,
/* callback = */ cldap_read_host,
/* interval = */ 0,
&(user_data_t){
- .data = st, .free_func = cldap_free,
+ .data = st,
+ .free_func = cldap_free,
});
} /* }}} int cldap_config_add */
derive_t tx) {
value_list_t vl = VALUE_LIST_INIT;
value_t values[] = {
- {.derive = rx}, {.derive = tx},
+ {.derive = rx},
+ {.derive = tx},
};
/* NOTE ON THE NEW NAMING SCHEMA:
derive_t uncompressed, derive_t compressed) {
value_list_t vl = VALUE_LIST_INIT;
value_t values[] = {
- {.derive = uncompressed}, {.derive = compressed},
+ {.derive = uncompressed},
+ {.derive = compressed},
};
vl.values = values;
/* callback = */ openvpn_read,
/* interval = */ 0,
&(user_data_t){
- .data = instance, .free_func = openvpn_free,
+ .data = instance,
+ .free_func = openvpn_free,
});
if (status == EINVAL) {
- WARNING("openvpn plugin: status filename \"%s\" "
- "already used, please choose a "
- "different one.",
- status_name);
+ ERROR("openvpn plugin: status filename \"%s\" "
+ "already used, please choose a "
+ "different one.",
+ status_name);
return -1;
}
if ((status != OCI_SUCCESS) && (status != OCI_SUCCESS_WITH_INFO)) {
char errfunc[256];
- snprintf(errfunc, sizeof(errfunc), "OCILogon(\"%s\")", db->connect_id);
+ ssnprintf(errfunc, sizeof(errfunc), "OCILogon(\"%s\")", db->connect_id);
o_report_error("o_read_database", db->name, NULL, errfunc, oci_error);
DEBUG("oracle plugin: OCILogon (%s): db->oci_service_context = %p;",
return NULL;
}
opt_buff = new_buff;
- int ret = snprintf(opt_buff + buff_off, buff_size - buff_off, option_fmt,
- iface->name);
+ int ret = ssnprintf(opt_buff + buff_off, buff_size - buff_off, option_fmt,
+ iface->name);
if (ret < 0) {
sfree(opt_buff);
return NULL;
}
/* fill the notification data */
- snprintf(n.message, sizeof(n.message),
- "link state of \"%s\" interface has been changed to \"%s\"",
- ifinfo->name, msg_link_status);
+ ssnprintf(n.message, sizeof(n.message),
+ "link state of \"%s\" interface has been changed to \"%s\"",
+ ifinfo->name, msg_link_status);
sstrncpy(n.host, hostname_g, sizeof(n.host));
sstrncpy(n.plugin_instance, ifinfo->name, sizeof(n.plugin_instance));
sstrncpy(n.type, "gauge", sizeof(n.type));
}
strjoin(devname, sizeof(devname),
(char *[]){
- bridge->name, port->name, iface->name,
+ bridge->name,
+ port->name,
+ iface->name,
},
3, ".");
ovs_stats_submit_one(devname, "if_collisions", NULL,
for (interface_list_t *iface = port->iface; iface != NULL;
iface = iface->next) {
- snprintf(key_str, sizeof(key_str), "uuid%d", i);
+ ssnprintf(key_str, sizeof(key_str), "uuid%d", i);
meta_data_add_string(meta, key_str, iface->iface_uuid);
if (strlen(iface->ex_vm_id)) {
- snprintf(key_str, sizeof(key_str), "vm-uuid%d", i);
+ ssnprintf(key_str, sizeof(key_str), "vm-uuid%d", i);
meta_data_add_string(meta, key_str, iface->ex_vm_id);
}
if (strlen(iface->ex_iface_id)) {
- snprintf(key_str, sizeof(key_str), "iface-id%d", i);
+ ssnprintf(key_str, sizeof(key_str), "iface-id%d", i);
meta_data_add_string(meta, key_str, iface->ex_iface_id);
}
}
}
bridge_list_t *bridge = port->br;
- snprintf(devname, sizeof(devname), "%s.%s", bridge->name, port->name);
+ ssnprintf(devname, sizeof(devname), "%s.%s", bridge->name, port->name);
ovs_stats_submit_one(devname, "if_collisions", NULL,
ovs_stats_get_port_stat_value(port, collisions), meta);
ovs_stats_submit_two(devname, "if_dropped", NULL,
/* Find offset of PCI Express Capability Structure
* in PCI configuration space.
* Returns offset, -1 if not found.
-**/
+ **/
static int pcie_find_cap_exp(pcie_device_t *dev) {
int pos = pcie_read8(dev, PCI_CAPABILITY_LIST) & ~3;
/* Find offset of Advanced Error Reporting Capability.
* Returns AER offset, -1 if not found.
-**/
+ **/
static int pcie_find_ecap_aer(pcie_device_t *dev) {
int pos = PCIE_ECAP_OFFSET;
uint32_t header = pcie_read32(dev, pos);
static char *get_module_name(char *buf, size_t buf_len, const char *module) {
int status = 0;
if (base_name[0] == '\0')
- status = snprintf(buf, buf_len, "%s", module);
+ status = ssnprintf(buf, buf_len, "%s", module);
else
- status = snprintf(buf, buf_len, "%s::%s", base_name, module);
+ status = ssnprintf(buf, buf_len, "%s::%s", base_name, module);
if ((status < 0) || ((unsigned int)status >= buf_len))
return NULL;
return buf;
* is ignored. */
#define C_PSQL_PAR_APPEND(buf, buf_len, parameter, value) \
if ((0 < (buf_len)) && (NULL != (value)) && ('\0' != *(value))) { \
- int s = snprintf(buf, buf_len, " %s = '%s'", parameter, value); \
+ int s = ssnprintf(buf, buf_len, " %s = '%s'", parameter, value); \
if (0 < s) { \
buf += s; \
buf_len -= s; \
if ((!db) || (!db->database))
return -1;
- status = snprintf(buf, buf_len, "dbname = '%s'", db->database);
+ status = ssnprintf(buf, buf_len, "dbname = '%s'", db->database);
if (0 < status) {
buf += status;
buf_len -= status;
params[i] = db->user;
break;
case C_PSQL_PARAM_INTERVAL:
- snprintf(interval, sizeof(interval), "%.3f",
- CDTIME_T_TO_DOUBLE(plugin_get_interval()));
+ ssnprintf(interval, sizeof(interval), "%.3f",
+ CDTIME_T_TO_DOUBLE(plugin_get_interval()));
params[i] = interval;
break;
case C_PSQL_PARAM_INSTANCE:
str_len = string_len;
for (size_t i = 0; i < ds->ds_num; ++i) {
- int status = snprintf(str_ptr, str_len, ",'%s'", ds->ds[i].name);
+ int status = ssnprintf(str_ptr, str_len, ",'%s'", ds->ds[i].name);
if (status < 1)
return NULL;
int status;
if (store_rates)
- status = snprintf(str_ptr, str_len, ",'gauge'");
+ status = ssnprintf(str_ptr, str_len, ",'gauge'");
else
- status = snprintf(str_ptr, str_len, ",'%s'",
- DS_TYPE_TO_STRING(ds->ds[i].type));
+ status = ssnprintf(str_ptr, str_len, ",'%s'",
+ DS_TYPE_TO_STRING(ds->ds[i].type));
if (status < 1) {
str_len = 0;
if (ds->ds[i].type == DS_TYPE_GAUGE)
status =
- snprintf(str_ptr, str_len, "," GAUGE_FORMAT, vl->values[i].gauge);
+ ssnprintf(str_ptr, str_len, "," GAUGE_FORMAT, vl->values[i].gauge);
else if (store_rates) {
if (rates == NULL)
rates = uc_get_rate(ds, vl);
return NULL;
}
- status = snprintf(str_ptr, str_len, ",%lf", rates[i]);
+ status = ssnprintf(str_ptr, str_len, ",%lf", rates[i]);
} else if (ds->ds[i].type == DS_TYPE_COUNTER)
- status = snprintf(str_ptr, str_len, ",%" PRIu64,
- (uint64_t)vl->values[i].counter);
+ status = ssnprintf(str_ptr, str_len, ",%" PRIu64,
+ (uint64_t)vl->values[i].counter);
else if (ds->ds[i].type == DS_TYPE_DERIVE)
- status = snprintf(str_ptr, str_len, ",%" PRIi64, vl->values[i].derive);
+ status = ssnprintf(str_ptr, str_len, ",%" PRIi64, vl->values[i].derive);
else if (ds->ds[i].type == DS_TYPE_ABSOLUTE)
- status = snprintf(str_ptr, str_len, ",%" PRIu64, vl->values[i].absolute);
+ status = ssnprintf(str_ptr, str_len, ",%" PRIu64, vl->values[i].absolute);
if (status < 1) {
str_len = 0;
if (db->writers_num > 0) {
char cb_name[DATA_MAX_NAME_LEN];
- snprintf(cb_name, sizeof(cb_name), "postgresql-%s", db->database);
+ ssnprintf(cb_name, sizeof(cb_name), "postgresql-%s", db->database);
if (!had_flush) {
plugin_unregister_flush("postgresql");
}
}
- snprintf(cb_name, sizeof(cb_name), "postgresql-%s", db->instance);
+ ssnprintf(cb_name, sizeof(cb_name), "postgresql-%s", db->instance);
user_data_t ud = {.data = db, .free_func = c_psql_database_delete};
answers-slow counts the number of queries answered after 1 second
answers0-1 counts the number of queries answered within 1 millisecond
answers1-10 counts the number of queries answered within 10
-milliseconds
+ milliseconds
answers10-100 counts the number of queries answered within 100
-milliseconds
+ milliseconds
answers100-1000 counts the number of queries answered within 1 second
cache-bytes size of the cache in bytes (since 3.3.1)
cache-entries shows the number of entries in the cache
cache-hits counts the number of cache hits since starting, this does
-not include hits that got answered from the packet-cache
+ not include hits that got answered from the packet-cache
cache-misses counts the number of cache misses since starting
case-mismatches counts the number of mismatches in character case since
-starting
+ starting
chain-resends number of queries chained to existing outstanding query
client-parse-errors counts number of client packets that could not be parsed
concurrent-queries shows the number of MThreads currently running
dlg-only-drops number of records dropped because of delegation only
-setting
+ setting
dont-outqueries number of outgoing queries dropped because of 'dont-query'
-setting (since 3.3)
+ setting (since 3.3)
edns-ping-matches number of servers that sent a valid EDNS PING respons
edns-ping-mismatches number of servers that sent an invalid EDNS PING response
failed-host-entries number of servers that failed to resolve
ipv6-outqueries number of outgoing queries over IPv6
ipv6-questions counts all End-user initiated queries with the RD bit set,
-received over IPv6 UDP
+ received over IPv6 UDP
malloc-bytes returns the number of bytes allocated by the process
-(broken, always returns 0)
+ (broken, always returns 0)
max-mthread-stack maximum amount of thread stack ever used
negcache-entries shows the number of entries in the Negative answer cache
no-packet-error number of errorneous received packets
noedns-outqueries number of queries sent out without EDNS
noerror-answers counts the number of times it answered NOERROR since
-starting
+ starting
noping-outqueries number of queries sent out without ENDS PING
nsset-invalidations number of times an nsset was dropped because it no longer
-worked
+ worked
nsspeeds-entries shows the number of entries in the NS speeds map
nxdomain-answers counts the number of times it answered NXDOMAIN since
-starting
+ starting
outgoing-timeouts counts the number of timeouts on outgoing UDP queries
-since starting
+ since starting
over-capacity-drops questions dropped because over maximum concurrent query
-limit (since 3.2)
+ limit (since 3.2)
packetcache-bytes size of the packet cache in bytes (since 3.3.1)
packetcache-entries size of packet cache (since 3.2)
packetcache-hits packet cache hits (since 3.2)
qa-latency shows the current latency average
questions counts all end-user initiated queries with the RD bit set
resource-limits counts number of queries that could not be performed
-because of resource limits
+ because of resource limits
security-status security status based on security polling
server-parse-errors counts number of server replied packets that could not be
-parsed
+ parsed
servfail-answers counts the number of times it answered SERVFAIL since
-starting
+ starting
spoof-prevents number of times PowerDNS considered itself spoofed, and
-dropped the data
+ dropped the data
sys-msec number of CPU milliseconds spent in 'system' mode
tcp-client-overflow number of times an IP address was denied TCP access
-because it already had too many connections
+ because it already had too many connections
tcp-clients counts the number of currently active TCP/IP clients
tcp-outqueries counts the number of outgoing TCP queries since starting
tcp-questions counts all incoming TCP queries (since starting)
throttle-entries shows the number of entries in the throttle map
throttled-out counts the number of throttled outgoing UDP queries since
-starting
+ starting
throttled-outqueries idem to throttled-out
unauthorized-tcp number of TCP questions denied because of allow-from
-restrictions
+ restrictions
unauthorized-udp number of UDP questions denied because of allow-from
-restrictions
+ restrictions
unexpected-packets number of answers from remote servers that were unexpected
-(might point to spoofing)
+ (might point to spoofing)
unreachables number of times nameservers were unreachable since
-starting
+ starting
uptime number of seconds process has been running (since 3.1.5)
user-msec number of CPU milliseconds spent in 'user' mode
}}} */
{"unauthorized-tcp", "counter", "denied-unauthorized_tcp"},
{"unauthorized-udp", "counter", "denied-unauthorized_udp"},
{"unexpected-packets", "dns_answer", "unexpected"},
+ {"unreachables", "counter", "unreachables"},
{"uptime", "uptime", NULL}}; /* }}} */
static int lookup_table_length = STATIC_ARRAY_SIZE(lookup_table);
pset_list_len = 0;
return -1;
}
-/* #endif HAVE_THREAD_INFO */
+ /* #endif HAVE_THREAD_INFO */
#elif KERNEL_LINUX
pagesize_g = sysconf(_SC_PAGESIZE);
}
}
#endif
-/* #endif KERNEL_LINUX */
+ /* #endif KERNEL_LINUX */
#elif HAVE_LIBKVM_GETPROCS && \
(HAVE_STRUCT_KINFO_PROC_FREEBSD || HAVE_STRUCT_KINFO_PROC_OPENBSD)
pagesize = getpagesize();
-/* #endif HAVE_LIBKVM_GETPROCS && (HAVE_STRUCT_KINFO_PROC_FREEBSD ||
- * HAVE_STRUCT_KINFO_PROC_OPENBSD) */
+ /* #endif HAVE_LIBKVM_GETPROCS && (HAVE_STRUCT_KINFO_PROC_FREEBSD ||
+ * HAVE_STRUCT_KINFO_PROC_OPENBSD) */
#elif HAVE_PROCINFO_H
pagesize = getpagesize();
snprintf(filename, sizeof(filename), "/proc/%li/stat", pid);
- status = read_file_contents(filename, buffer, sizeof(buffer) - 1);
+ status = read_text_file_contents(filename, buffer, sizeof(buffer));
if (status <= 0)
return -1;
buffer_len = (size_t)status;
- buffer[buffer_len] = 0;
/* The name of the process is enclosed in parens. Since the name can
* contain parens itself, spaces, numbers and pretty much everything
snprintf(path, sizeof(path), "/proc/%li/psinfo", pid);
- status = read_file_contents(path, (void *)&info, sizeof(info));
+ status = read_file_contents(path, &info, sizeof(info));
if ((status < 0) || (((size_t)status) != sizeof(info))) {
ERROR("processes plugin: Unexpected return value "
"while reading \"%s\": "
/*
* TODO: context switch counters for Solaris
-*/
+ */
ps->cswitch_vol = -1;
ps->cswitch_invol = -1;
for (ps = list_head_g; ps != NULL; ps = ps->next)
ps_submit_proc_list(ps);
-/* #endif HAVE_THREAD_INFO */
+ /* #endif HAVE_THREAD_INFO */
#elif KERNEL_LINUX
int running = 0;
ps_submit_proc_list(ps_ptr);
read_fork_rate();
-/* #endif KERNEL_LINUX */
+ /* #endif KERNEL_LINUX */
#elif HAVE_LIBKVM_GETPROCS && HAVE_STRUCT_KINFO_PROC_FREEBSD
int running = 0;
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 */
+ /* #endif HAVE_LIBKVM_GETPROCS && HAVE_STRUCT_KINFO_PROC_FREEBSD */
#elif HAVE_LIBKVM_GETPROCS && HAVE_STRUCT_KINFO_PROC_OPENBSD
int running = 0;
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 */
+ /* #endif HAVE_LIBKVM_GETPROCS && HAVE_STRUCT_KINFO_PROC_OPENBSD */
#elif HAVE_PROCINFO_H
/* AIX */
for (procstat_t *ps = list_head_g; ps != NULL; ps = ps->next)
ps_submit_proc_list(ps);
-/* #endif HAVE_PROCINFO_H */
+ /* #endif HAVE_PROCINFO_H */
#elif KERNEL_SOLARIS
/*
--- /dev/null
+/**
+ * collectd - src/procevent.c
+ *
+ * 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:
+ * Red Hat NFVPE
+ * Andrew Bays <abays at redhat.com>
+ **/
+
+#include "collectd.h"
+
+#include "plugin.h"
+#include "utils/common/common.h"
+#include "utils/ignorelist/ignorelist.h"
+#include "utils_complain.h"
+
+#include <errno.h>
+#include <pthread.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/socket.h>
+#include <unistd.h>
+
+#include <dirent.h>
+#include <linux/cn_proc.h>
+#include <linux/connector.h>
+#include <linux/netlink.h>
+#include <linux/rtnetlink.h>
+#include <signal.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <string.h>
+
+#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
+
+#define PROCEVENT_EXITED 0
+#define PROCEVENT_STARTED 1
+#define PROCEVENT_FIELDS 3 // pid, status, timestamp
+#define BUFSIZE 512
+#define PROCDIR "/proc"
+#define RBUF_PROC_ID_INDEX 0
+#define RBUF_PROC_STATUS_INDEX 1
+#define RBUF_TIME_INDEX 2
+
+#define PROCEVENT_DOMAIN_FIELD "domain"
+#define PROCEVENT_DOMAIN_VALUE "fault"
+#define PROCEVENT_EVENT_ID_FIELD "eventId"
+#define PROCEVENT_EVENT_NAME_FIELD "eventName"
+#define PROCEVENT_EVENT_NAME_DOWN_VALUE "down"
+#define PROCEVENT_EVENT_NAME_UP_VALUE "up"
+#define PROCEVENT_LAST_EPOCH_MICROSEC_FIELD "lastEpochMicrosec"
+#define PROCEVENT_PRIORITY_FIELD "priority"
+#define PROCEVENT_PRIORITY_VALUE "high"
+#define PROCEVENT_REPORTING_ENTITY_NAME_FIELD "reportingEntityName"
+#define PROCEVENT_REPORTING_ENTITY_NAME_VALUE "collectd procevent plugin"
+#define PROCEVENT_SEQUENCE_FIELD "sequence"
+#define PROCEVENT_SEQUENCE_VALUE "0"
+#define PROCEVENT_SOURCE_NAME_FIELD "sourceName"
+#define PROCEVENT_START_EPOCH_MICROSEC_FIELD "startEpochMicrosec"
+#define PROCEVENT_VERSION_FIELD "version"
+#define PROCEVENT_VERSION_VALUE "1.0"
+
+#define PROCEVENT_ALARM_CONDITION_FIELD "alarmCondition"
+#define PROCEVENT_ALARM_INTERFACE_A_FIELD "alarmInterfaceA"
+#define PROCEVENT_EVENT_SEVERITY_FIELD "eventSeverity"
+#define PROCEVENT_EVENT_SEVERITY_CRITICAL_VALUE "CRITICAL"
+#define PROCEVENT_EVENT_SEVERITY_NORMAL_VALUE "NORMAL"
+#define PROCEVENT_EVENT_SOURCE_TYPE_FIELD "eventSourceType"
+#define PROCEVENT_EVENT_SOURCE_TYPE_VALUE "process"
+#define PROCEVENT_FAULT_FIELDS_FIELD "faultFields"
+#define PROCEVENT_FAULT_FIELDS_VERSION_FIELD "faultFieldsVersion"
+#define PROCEVENT_FAULT_FIELDS_VERSION_VALUE "1.0"
+#define PROCEVENT_SPECIFIC_PROBLEM_FIELD "specificProblem"
+#define PROCEVENT_SPECIFIC_PROBLEM_DOWN_VALUE "down"
+#define PROCEVENT_SPECIFIC_PROBLEM_UP_VALUE "up"
+#define PROCEVENT_VF_STATUS_FIELD "vfStatus"
+#define PROCEVENT_VF_STATUS_CRITICAL_VALUE "Ready to terminate"
+#define PROCEVENT_VF_STATUS_NORMAL_VALUE "Active"
+
+/*
+ * Private data types
+ */
+
+typedef struct {
+ int head;
+ int tail;
+ int maxLen;
+ cdtime_t **buffer;
+} circbuf_t;
+
+struct processlist_s {
+ char *process;
+
+ long pid;
+ int32_t last_status;
+
+ struct processlist_s *next;
+};
+typedef struct processlist_s processlist_t;
+
+/*
+ * Private variables
+ */
+static ignorelist_t *ignorelist = NULL;
+
+static int procevent_netlink_thread_loop = 0;
+static int procevent_netlink_thread_error = 0;
+static pthread_t procevent_netlink_thread_id;
+static int procevent_dequeue_thread_loop = 0;
+static pthread_t procevent_dequeue_thread_id;
+static pthread_mutex_t procevent_thread_lock = PTHREAD_MUTEX_INITIALIZER;
+static pthread_mutex_t procevent_data_lock = PTHREAD_MUTEX_INITIALIZER;
+static pthread_cond_t procevent_cond = PTHREAD_COND_INITIALIZER;
+static int nl_sock = -1;
+static int buffer_length;
+static circbuf_t ring;
+static processlist_t *processlist_head = NULL;
+static int event_id = 0;
+
+static const char *config_keys[] = {"BufferLength", "Process", "ProcessRegex"};
+static int config_keys_num = STATIC_ARRAY_SIZE(config_keys);
+
+/*
+ * Private functions
+ */
+
+static int gen_message_payload(int state, long pid, char *process,
+ cdtime_t timestamp, char **buf) {
+ const unsigned char *buf2;
+ yajl_gen g;
+ char json_str[DATA_MAX_NAME_LEN];
+
+#if !defined(HAVE_YAJL_V2)
+ yajl_gen_config conf = {0};
+#endif
+
+#if HAVE_YAJL_V2
+ size_t len;
+ g = yajl_gen_alloc(NULL);
+ yajl_gen_config(g, yajl_gen_beautify, 0);
+#else
+ unsigned int len;
+ g = yajl_gen_alloc(&conf, NULL);
+#endif
+
+ yajl_gen_clear(g);
+
+ // *** BEGIN common event header ***
+
+ if (yajl_gen_map_open(g) != yajl_gen_status_ok)
+ goto err;
+
+ // domain
+ if (yajl_gen_string(g, (u_char *)PROCEVENT_DOMAIN_FIELD,
+ strlen(PROCEVENT_DOMAIN_FIELD)) != yajl_gen_status_ok)
+ goto err;
+
+ if (yajl_gen_string(g, (u_char *)PROCEVENT_DOMAIN_VALUE,
+ strlen(PROCEVENT_DOMAIN_VALUE)) != yajl_gen_status_ok)
+ goto err;
+
+ // eventId
+ if (yajl_gen_string(g, (u_char *)PROCEVENT_EVENT_ID_FIELD,
+ strlen(PROCEVENT_EVENT_ID_FIELD)) != yajl_gen_status_ok)
+ goto err;
+
+ event_id = event_id + 1;
+ if (snprintf(json_str, sizeof(json_str), "%d", event_id) < 0) {
+ goto err;
+ }
+
+ if (yajl_gen_number(g, json_str, strlen(json_str)) != yajl_gen_status_ok) {
+ goto err;
+ }
+
+ // eventName
+ if (yajl_gen_string(g, (u_char *)PROCEVENT_EVENT_NAME_FIELD,
+ strlen(PROCEVENT_EVENT_NAME_FIELD)) != yajl_gen_status_ok)
+ goto err;
+
+ if (snprintf(json_str, sizeof(json_str), "process %s (%ld) %s", process, pid,
+ (state == 0 ? PROCEVENT_EVENT_NAME_DOWN_VALUE
+ : PROCEVENT_EVENT_NAME_UP_VALUE)) < 0) {
+ goto err;
+ }
+
+ if (yajl_gen_string(g, (u_char *)json_str, strlen(json_str)) !=
+ yajl_gen_status_ok) {
+ goto err;
+ }
+
+ // lastEpochMicrosec
+ if (yajl_gen_string(g, (u_char *)PROCEVENT_LAST_EPOCH_MICROSEC_FIELD,
+ strlen(PROCEVENT_LAST_EPOCH_MICROSEC_FIELD)) !=
+ yajl_gen_status_ok)
+ goto err;
+
+ if (snprintf(json_str, sizeof(json_str), "%" PRIu64,
+ CDTIME_T_TO_US(cdtime())) < 0) {
+ goto err;
+ }
+
+ if (yajl_gen_number(g, json_str, strlen(json_str)) != yajl_gen_status_ok) {
+ goto err;
+ }
+
+ // priority
+ if (yajl_gen_string(g, (u_char *)PROCEVENT_PRIORITY_FIELD,
+ strlen(PROCEVENT_PRIORITY_FIELD)) != yajl_gen_status_ok)
+ goto err;
+
+ if (yajl_gen_string(g, (u_char *)PROCEVENT_PRIORITY_VALUE,
+ strlen(PROCEVENT_PRIORITY_VALUE)) != yajl_gen_status_ok)
+ goto err;
+
+ // reportingEntityName
+ if (yajl_gen_string(g, (u_char *)PROCEVENT_REPORTING_ENTITY_NAME_FIELD,
+ strlen(PROCEVENT_REPORTING_ENTITY_NAME_FIELD)) !=
+ yajl_gen_status_ok)
+ goto err;
+
+ if (yajl_gen_string(g, (u_char *)PROCEVENT_REPORTING_ENTITY_NAME_VALUE,
+ strlen(PROCEVENT_REPORTING_ENTITY_NAME_VALUE)) !=
+ yajl_gen_status_ok)
+ goto err;
+
+ // sequence
+ if (yajl_gen_string(g, (u_char *)PROCEVENT_SEQUENCE_FIELD,
+ strlen(PROCEVENT_SEQUENCE_FIELD)) != yajl_gen_status_ok)
+ goto err;
+
+ if (yajl_gen_number(g, PROCEVENT_SEQUENCE_VALUE,
+ strlen(PROCEVENT_SEQUENCE_VALUE)) != yajl_gen_status_ok)
+ goto err;
+
+ // sourceName
+ if (yajl_gen_string(g, (u_char *)PROCEVENT_SOURCE_NAME_FIELD,
+ strlen(PROCEVENT_SOURCE_NAME_FIELD)) !=
+ yajl_gen_status_ok)
+ goto err;
+
+ if (yajl_gen_string(g, (u_char *)process, strlen(process)) !=
+ yajl_gen_status_ok)
+ goto err;
+
+ // startEpochMicrosec
+ if (yajl_gen_string(g, (u_char *)PROCEVENT_START_EPOCH_MICROSEC_FIELD,
+ strlen(PROCEVENT_START_EPOCH_MICROSEC_FIELD)) !=
+ yajl_gen_status_ok)
+ goto err;
+
+ if (snprintf(json_str, sizeof(json_str), "%" PRIu64,
+ CDTIME_T_TO_US(timestamp)) < 0) {
+ goto err;
+ }
+
+ if (yajl_gen_number(g, json_str, strlen(json_str)) != yajl_gen_status_ok) {
+ goto err;
+ }
+
+ // version
+ if (yajl_gen_string(g, (u_char *)PROCEVENT_VERSION_FIELD,
+ strlen(PROCEVENT_VERSION_FIELD)) != yajl_gen_status_ok)
+ goto err;
+
+ if (yajl_gen_number(g, PROCEVENT_VERSION_VALUE,
+ strlen(PROCEVENT_VERSION_VALUE)) != yajl_gen_status_ok)
+ goto err;
+
+ // *** END common event header ***
+
+ // *** BEGIN fault fields ***
+
+ if (yajl_gen_string(g, (u_char *)PROCEVENT_FAULT_FIELDS_FIELD,
+ strlen(PROCEVENT_FAULT_FIELDS_FIELD)) !=
+ yajl_gen_status_ok)
+ goto err;
+
+ if (yajl_gen_map_open(g) != yajl_gen_status_ok)
+ goto err;
+
+ // alarmCondition
+ if (yajl_gen_string(g, (u_char *)PROCEVENT_ALARM_CONDITION_FIELD,
+ strlen(PROCEVENT_ALARM_CONDITION_FIELD)) !=
+ yajl_gen_status_ok)
+ goto err;
+
+ if (snprintf(json_str, sizeof(json_str), "process %s (%ld) state change",
+ process, pid) < 0) {
+ goto err;
+ }
+
+ if (yajl_gen_string(g, (u_char *)json_str, strlen(json_str)) !=
+ yajl_gen_status_ok) {
+ goto err;
+ }
+
+ // alarmInterfaceA
+ if (yajl_gen_string(g, (u_char *)PROCEVENT_ALARM_INTERFACE_A_FIELD,
+ strlen(PROCEVENT_ALARM_INTERFACE_A_FIELD)) !=
+ yajl_gen_status_ok)
+ goto err;
+
+ if (yajl_gen_string(g, (u_char *)process, strlen(process)) !=
+ yajl_gen_status_ok)
+ goto err;
+
+ // eventSeverity
+ if (yajl_gen_string(g, (u_char *)PROCEVENT_EVENT_SEVERITY_FIELD,
+ strlen(PROCEVENT_EVENT_SEVERITY_FIELD)) !=
+ yajl_gen_status_ok)
+ goto err;
+
+ if (yajl_gen_string(
+ g,
+ (u_char *)(state == 0 ? PROCEVENT_EVENT_SEVERITY_CRITICAL_VALUE
+ : PROCEVENT_EVENT_SEVERITY_NORMAL_VALUE),
+ strlen((state == 0 ? PROCEVENT_EVENT_SEVERITY_CRITICAL_VALUE
+ : PROCEVENT_EVENT_SEVERITY_NORMAL_VALUE))) !=
+ yajl_gen_status_ok)
+ goto err;
+
+ // eventSourceType
+ if (yajl_gen_string(g, (u_char *)PROCEVENT_EVENT_SOURCE_TYPE_FIELD,
+ strlen(PROCEVENT_EVENT_SOURCE_TYPE_FIELD)) !=
+ yajl_gen_status_ok)
+ goto err;
+
+ if (yajl_gen_string(g, (u_char *)PROCEVENT_EVENT_SOURCE_TYPE_VALUE,
+ strlen(PROCEVENT_EVENT_SOURCE_TYPE_VALUE)) !=
+ yajl_gen_status_ok)
+ goto err;
+
+ // faultFieldsVersion
+ if (yajl_gen_string(g, (u_char *)PROCEVENT_FAULT_FIELDS_VERSION_FIELD,
+ strlen(PROCEVENT_FAULT_FIELDS_VERSION_FIELD)) !=
+ yajl_gen_status_ok)
+ goto err;
+
+ if (yajl_gen_number(g, PROCEVENT_FAULT_FIELDS_VERSION_VALUE,
+ strlen(PROCEVENT_FAULT_FIELDS_VERSION_VALUE)) !=
+ yajl_gen_status_ok)
+ goto err;
+
+ // specificProblem
+ if (yajl_gen_string(g, (u_char *)PROCEVENT_SPECIFIC_PROBLEM_FIELD,
+ strlen(PROCEVENT_SPECIFIC_PROBLEM_FIELD)) !=
+ yajl_gen_status_ok)
+ goto err;
+
+ if (snprintf(json_str, sizeof(json_str), "process %s (%ld) %s", process, pid,
+ (state == 0 ? PROCEVENT_SPECIFIC_PROBLEM_DOWN_VALUE
+ : PROCEVENT_SPECIFIC_PROBLEM_UP_VALUE)) < 0) {
+ goto err;
+ }
+
+ if (yajl_gen_string(g, (u_char *)json_str, strlen(json_str)) !=
+ yajl_gen_status_ok) {
+ goto err;
+ }
+
+ // vfStatus
+ if (yajl_gen_string(g, (u_char *)PROCEVENT_VF_STATUS_FIELD,
+ strlen(PROCEVENT_VF_STATUS_FIELD)) != yajl_gen_status_ok)
+ goto err;
+
+ if (yajl_gen_string(
+ g,
+ (u_char *)(state == 0 ? PROCEVENT_VF_STATUS_CRITICAL_VALUE
+ : PROCEVENT_VF_STATUS_NORMAL_VALUE),
+ strlen((state == 0 ? PROCEVENT_VF_STATUS_CRITICAL_VALUE
+ : PROCEVENT_VF_STATUS_NORMAL_VALUE))) !=
+ yajl_gen_status_ok)
+ goto err;
+
+ // *** END fault fields ***
+
+ // close fault and header fields
+ if (yajl_gen_map_close(g) != yajl_gen_status_ok ||
+ yajl_gen_map_close(g) != yajl_gen_status_ok)
+ goto err;
+
+ if (yajl_gen_get_buf(g, &buf2, &len) != yajl_gen_status_ok)
+ goto err;
+
+ *buf = strdup((char *)buf2);
+
+ if (*buf == NULL) {
+ ERROR("procevent plugin: strdup failed during gen_message_payload: %s",
+ STRERRNO);
+ goto err;
+ }
+
+ yajl_gen_free(g);
+
+ return 0;
+
+err:
+ yajl_gen_free(g);
+ ERROR("procevent plugin: gen_message_payload failed to generate JSON");
+ return -1;
+}
+
+// Does /proc/<pid>/comm contain a process name we are interested in?
+// NOTE: Caller MUST hold procevent_data_lock when calling this function
+static processlist_t *process_check(long pid) {
+ char file[BUFSIZE];
+
+ int len = snprintf(file, sizeof(file), PROCDIR "/%ld/comm", pid);
+
+ if ((len < 0) || (len >= BUFSIZE)) {
+ WARNING("procevent process_check: process name too large");
+ return NULL;
+ }
+
+ FILE *fh;
+
+ if (NULL == (fh = fopen(file, "r"))) {
+ // No /proc/<pid>/comm for this pid, just ignore
+ DEBUG("procevent plugin: no comm file available for pid %ld", pid);
+ return NULL;
+ }
+
+ char buffer[BUFSIZE];
+ int retval = fscanf(fh, "%[^\n]", buffer);
+
+ if (retval < 0) {
+ WARNING("procevent process_check: unable to read comm file for pid %ld",
+ pid);
+ fclose(fh);
+ return NULL;
+ }
+
+ // Now that we have the process name in the buffer, check if we are
+ // even interested in it
+ if (ignorelist_match(ignorelist, buffer) != 0) {
+ DEBUG("procevent process_check: ignoring process %s (%ld)", buffer, pid);
+ fclose(fh);
+ return NULL;
+ }
+
+ if (fh != NULL) {
+ fclose(fh);
+ fh = NULL;
+ }
+
+ //
+ // Go through the processlist linked list and look for the process name
+ // in /proc/<pid>/comm. If found:
+ // 1. If pl->pid is -1, then set pl->pid to <pid> (and return that object)
+ // 2. If pl->pid is not -1, then another <process name> process was already
+ // found. If <pid> == pl->pid, this is an old match, so do nothing.
+ // If the <pid> is different, however, make a new processlist_t and
+ // associate <pid> with it (with the same process name as the existing).
+ //
+
+ processlist_t *match = NULL;
+
+ for (processlist_t *pl = processlist_head; pl != NULL; pl = pl->next) {
+
+ int is_match = (strcmp(buffer, pl->process) == 0 ? 1 : 0);
+
+ if (is_match == 1) {
+ DEBUG("procevent plugin: process %ld name match for %s", pid, buffer);
+
+ if (pl->pid == pid) {
+ // this is a match, and we've already stored the exact pid/name combo
+ DEBUG("procevent plugin: found exact match with name %s, PID %ld for "
+ "incoming PID %ld",
+ pl->process, pl->pid, pid);
+ match = pl;
+ break;
+ } else if (pl->pid == -1) {
+ // this is a match, and we've found a candidate processlist_t to store
+ // this new pid/name combo
+ DEBUG("procevent plugin: reusing pl object with PID %ld for incoming "
+ "PID %ld",
+ pl->pid, pid);
+ pl->pid = pid;
+ match = pl;
+ break;
+ } else if (pl->pid != -1) {
+ // this is a match, but another instance of this process has already
+ // claimed this pid/name combo,
+ // so keep looking
+ DEBUG("procevent plugin: found pl object with matching name for "
+ "incoming PID %ld, but object is in use by PID %ld",
+ pid, pl->pid);
+ match = pl;
+ continue;
+ }
+ }
+ }
+
+ if (match == NULL ||
+ (match != NULL && match->pid != -1 && match->pid != pid)) {
+ // if there wasn't an existing match, OR
+ // if there was a match but the associated processlist_t object already
+ // contained a pid/name combo,
+ // then make a new one and add it to the linked list
+
+ DEBUG("procevent plugin: allocating new processlist_t object for PID %ld "
+ "(%s)",
+ pid, buffer);
+
+ processlist_t *pl2 = calloc(1, sizeof(*pl2));
+ if (pl2 == NULL) {
+ ERROR("procevent plugin: calloc failed during process_check: %s",
+ STRERRNO);
+ return NULL;
+ }
+
+ char *process = strdup(buffer);
+ if (process == NULL) {
+ sfree(pl2);
+ ERROR("procevent plugin: strdup failed during process_check: %s",
+ STRERRNO);
+ return NULL;
+ }
+
+ pl2->process = process;
+ pl2->pid = pid;
+ pl2->next = processlist_head;
+ processlist_head = pl2;
+
+ match = pl2;
+ }
+
+ return match;
+}
+
+// Does our map have this PID or name?
+// NOTE: Caller MUST hold procevent_data_lock when calling this function
+static processlist_t *process_map_check(long pid, char *process) {
+ for (processlist_t *pl = processlist_head; pl != NULL; pl = pl->next) {
+ int match_pid = 0;
+
+ if (pid > 0) {
+ if (pl->pid == pid)
+ match_pid = 1;
+ }
+
+ int match_process = 0;
+
+ if (process != NULL) {
+ if (strcmp(pl->process, process) == 0)
+ match_process = 1;
+ }
+
+ int match = 0;
+
+ if ((pid > 0 && process == NULL && match_pid == 1) ||
+ (pid < 0 && process != NULL && match_process == 1) ||
+ (pid > 0 && process != NULL && match_pid == 1 && match_process == 1)) {
+ match = 1;
+ }
+
+ if (match == 1) {
+ return pl;
+ }
+ }
+
+ return NULL;
+}
+
+static int process_map_refresh(void) {
+ errno = 0;
+ DIR *proc = opendir(PROCDIR);
+
+ if (proc == NULL) {
+ ERROR("procevent plugin: fopen (%s): %s", PROCDIR, STRERRNO);
+ return -1;
+ }
+
+ while (42) {
+ errno = 0;
+ struct dirent *dent = readdir(proc);
+ if (dent == NULL) {
+ if (errno == 0) /* end of directory */
+ break;
+
+ ERROR("procevent plugin: failed to read directory %s: %s", PROCDIR,
+ STRERRNO);
+ closedir(proc);
+ return -1;
+ }
+
+ if (dent->d_name[0] == '.')
+ continue;
+
+ char file[BUFSIZE];
+
+ int len = snprintf(file, sizeof(file), PROCDIR "/%s", dent->d_name);
+ if ((len < 0) || (len >= BUFSIZE))
+ continue;
+
+ struct stat statbuf;
+
+ int status = stat(file, &statbuf);
+ if (status != 0) {
+ WARNING("procevent plugin: stat (%s) failed: %s", file, STRERRNO);
+ continue;
+ }
+
+ if (!S_ISDIR(statbuf.st_mode))
+ continue;
+
+ len = snprintf(file, sizeof(file), PROCDIR "/%s/comm", dent->d_name);
+ if ((len < 0) || (len >= BUFSIZE))
+ continue;
+
+ int not_number = 0;
+
+ for (int i = 0; i < strlen(dent->d_name); i++) {
+ if (!isdigit(dent->d_name[i])) {
+ not_number = 1;
+ break;
+ }
+ }
+
+ if (not_number != 0)
+ continue;
+
+ // Check if we need to store this pid/name combo in our processlist_t linked
+ // list
+ int this_pid = atoi(dent->d_name);
+ pthread_mutex_lock(&procevent_data_lock);
+ processlist_t *pl = process_check(this_pid);
+ pthread_mutex_unlock(&procevent_data_lock);
+
+ if (pl != NULL)
+ DEBUG("procevent plugin: process map refreshed for PID %d and name %s",
+ this_pid, pl->process);
+ }
+
+ closedir(proc);
+
+ return 0;
+}
+
+static int nl_connect() {
+ struct sockaddr_nl sa_nl = {
+ .nl_family = AF_NETLINK,
+ .nl_groups = CN_IDX_PROC,
+ .nl_pid = getpid(),
+ };
+
+ nl_sock = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_CONNECTOR);
+ if (nl_sock == -1) {
+ ERROR("procevent plugin: socket open failed: %d", errno);
+ return -1;
+ }
+
+ int rc = bind(nl_sock, (struct sockaddr *)&sa_nl, sizeof(sa_nl));
+ if (rc == -1) {
+ ERROR("procevent plugin: socket bind failed: %d", errno);
+ close(nl_sock);
+ nl_sock = -1;
+ return -1;
+ }
+
+ return 0;
+}
+
+static int set_proc_ev_listen(bool enable) {
+ struct __attribute__((aligned(NLMSG_ALIGNTO))) {
+ struct nlmsghdr nl_hdr;
+ struct __attribute__((__packed__)) {
+ struct cn_msg cn_msg;
+ enum proc_cn_mcast_op cn_mcast;
+ };
+ } nlcn_msg;
+
+ memset(&nlcn_msg, 0, sizeof(nlcn_msg));
+ nlcn_msg.nl_hdr.nlmsg_len = sizeof(nlcn_msg);
+ nlcn_msg.nl_hdr.nlmsg_pid = getpid();
+ nlcn_msg.nl_hdr.nlmsg_type = NLMSG_DONE;
+
+ nlcn_msg.cn_msg.id.idx = CN_IDX_PROC;
+ nlcn_msg.cn_msg.id.val = CN_VAL_PROC;
+ nlcn_msg.cn_msg.len = sizeof(enum proc_cn_mcast_op);
+
+ nlcn_msg.cn_mcast = enable ? PROC_CN_MCAST_LISTEN : PROC_CN_MCAST_IGNORE;
+
+ int rc = send(nl_sock, &nlcn_msg, sizeof(nlcn_msg), 0);
+ if (rc == -1) {
+ ERROR("procevent plugin: subscribing to netlink process events failed: %d",
+ errno);
+ return -1;
+ }
+
+ return 0;
+}
+
+// Read from netlink socket and write to ring buffer
+static int read_event() {
+ int recv_flags = MSG_DONTWAIT;
+ struct __attribute__((aligned(NLMSG_ALIGNTO))) {
+ struct nlmsghdr nl_hdr;
+ struct __attribute__((__packed__)) {
+ struct cn_msg cn_msg;
+ struct proc_event proc_ev;
+ };
+ } nlcn_msg;
+
+ if (nl_sock == -1)
+ return 0;
+
+ while (42) {
+ pthread_mutex_lock(&procevent_thread_lock);
+
+ if (procevent_netlink_thread_loop <= 0) {
+ pthread_mutex_unlock(&procevent_thread_lock);
+ return 0;
+ }
+
+ pthread_mutex_unlock(&procevent_thread_lock);
+
+ int status = recv(nl_sock, &nlcn_msg, sizeof(nlcn_msg), recv_flags);
+
+ if (status == 0) {
+ return 0;
+ } else if (status < 0) {
+ if (errno == EAGAIN || errno == EWOULDBLOCK) {
+ pthread_mutex_lock(&procevent_data_lock);
+
+ // There was nothing more to receive for now, so...
+ // If ring head does not equal ring tail, then there is data
+ // in the ring buffer for the dequeue thread to read, so
+ // signal it
+ if (ring.head != ring.tail)
+ pthread_cond_signal(&procevent_cond);
+
+ pthread_mutex_unlock(&procevent_data_lock);
+
+ // Since there was nothing to receive, set recv to block and
+ // try again
+ recv_flags = 0;
+ continue;
+ } else if (errno != EINTR) {
+ ERROR("procevent plugin: socket receive error: %d", errno);
+ return -1;
+ } else {
+ // Interrupt, so just continue and try again
+ continue;
+ }
+ }
+
+ // We successfully received a message, so don't block on the next
+ // read in case there are more (and if there aren't, it will be
+ // handled above in the EWOULDBLOCK error-checking)
+ recv_flags = MSG_DONTWAIT;
+
+ int proc_id = -1;
+ int proc_status = -1;
+
+ switch (nlcn_msg.proc_ev.what) {
+ case PROC_EVENT_EXEC:
+ proc_status = PROCEVENT_STARTED;
+ proc_id = nlcn_msg.proc_ev.event_data.exec.process_pid;
+ break;
+ case PROC_EVENT_EXIT:
+ proc_id = nlcn_msg.proc_ev.event_data.exit.process_pid;
+ proc_status = PROCEVENT_EXITED;
+ break;
+ default:
+ // Otherwise not of interest
+ break;
+ }
+
+ // If we're interested in this process status event, place the event
+ // in the ring buffer for consumption by the dequeue (dispatch) thread.
+
+ if (proc_status != -1) {
+ pthread_mutex_lock(&procevent_data_lock);
+
+ int next = ring.head + 1;
+ if (next >= ring.maxLen)
+ next = 0;
+
+ if (next == ring.tail) {
+ // Buffer is full, signal the dequeue thread to process the buffer
+ // and clean it out, and then sleep
+ WARNING("procevent plugin: ring buffer full");
+
+ pthread_cond_signal(&procevent_cond);
+ pthread_mutex_unlock(&procevent_data_lock);
+
+ usleep(1000);
+ continue;
+ } else {
+ DEBUG("procevent plugin: Process %d status is now %s at %llu", proc_id,
+ (proc_status == PROCEVENT_EXITED ? "EXITED" : "STARTED"),
+ (unsigned long long)cdtime());
+
+ ring.buffer[ring.head][RBUF_PROC_ID_INDEX] = proc_id;
+ ring.buffer[ring.head][RBUF_PROC_STATUS_INDEX] = proc_status;
+ ring.buffer[ring.head][RBUF_TIME_INDEX] = cdtime();
+
+ ring.head = next;
+ }
+
+ pthread_mutex_unlock(&procevent_data_lock);
+ }
+ }
+
+ return 0;
+}
+
+static void procevent_dispatch_notification(long pid, gauge_t value,
+ char *process, cdtime_t timestamp) {
+
+ notification_t n = {
+ .severity = (value == 1 ? NOTIF_OKAY : NOTIF_FAILURE),
+ .time = cdtime(),
+ .plugin = "procevent",
+ .type = "gauge",
+ .type_instance = "process_status",
+ };
+
+ sstrncpy(n.host, hostname_g, sizeof(n.host));
+ sstrncpy(n.plugin_instance, process, sizeof(n.plugin_instance));
+
+ char *buf = NULL;
+ gen_message_payload(value, pid, process, timestamp, &buf);
+
+ int status = plugin_notification_meta_add_string(&n, "ves", buf);
+
+ if (status < 0) {
+ sfree(buf);
+ ERROR("procevent plugin: unable to set notification VES metadata: %s",
+ STRERRNO);
+ return;
+ }
+
+ DEBUG("procevent plugin: notification VES metadata: %s",
+ n.meta->nm_value.nm_string);
+
+ DEBUG("procevent plugin: dispatching state %d for PID %ld (%s)", (int)value,
+ pid, process);
+
+ plugin_dispatch_notification(&n);
+ plugin_notification_meta_free(n.meta);
+
+ // strdup'd in gen_message_payload
+ if (buf != NULL)
+ sfree(buf);
+}
+
+// Read from ring buffer and dispatch to write plugins
+static void read_ring_buffer() {
+ pthread_mutex_lock(&procevent_data_lock);
+
+ // If there's currently nothing to read from the buffer,
+ // then wait
+ if (ring.head == ring.tail)
+ pthread_cond_wait(&procevent_cond, &procevent_data_lock);
+
+ while (ring.head != ring.tail) {
+ int next = ring.tail + 1;
+
+ if (next >= ring.maxLen)
+ next = 0;
+
+ if (ring.buffer[ring.tail][RBUF_PROC_STATUS_INDEX] == PROCEVENT_EXITED) {
+ processlist_t *pl = process_map_check(ring.buffer[ring.tail][0], NULL);
+
+ if (pl != NULL) {
+ // This process is of interest to us, so publish its EXITED status
+ procevent_dispatch_notification(
+ ring.buffer[ring.tail][RBUF_PROC_ID_INDEX],
+ ring.buffer[ring.tail][RBUF_PROC_STATUS_INDEX], pl->process,
+ ring.buffer[ring.tail][RBUF_TIME_INDEX]);
+ DEBUG(
+ "procevent plugin: PID %ld (%s) EXITED, removing PID from process "
+ "list",
+ pl->pid, pl->process);
+ pl->pid = -1;
+ pl->last_status = -1;
+ }
+ } else if (ring.buffer[ring.tail][RBUF_PROC_STATUS_INDEX] ==
+ PROCEVENT_STARTED) {
+ // a new process has started, so check if we should monitor it
+ processlist_t *pl = process_check(ring.buffer[ring.tail][0]);
+
+ // If we had already seen this process name and pid combo before,
+ // and the last message was a "process started" message, don't send
+ // the notfication again
+
+ if (pl != NULL && pl->last_status != PROCEVENT_STARTED) {
+ // This process is of interest to us, so publish its STARTED status
+ procevent_dispatch_notification(
+ ring.buffer[ring.tail][RBUF_PROC_ID_INDEX],
+ ring.buffer[ring.tail][RBUF_PROC_STATUS_INDEX], pl->process,
+ ring.buffer[ring.tail][RBUF_TIME_INDEX]);
+
+ pl->last_status = PROCEVENT_STARTED;
+
+ DEBUG("procevent plugin: PID %ld (%s) STARTED, adding PID to process "
+ "list",
+ pl->pid, pl->process);
+ }
+ }
+
+ ring.tail = next;
+ }
+
+ pthread_mutex_unlock(&procevent_data_lock);
+}
+
+// Entry point for thread responsible for listening
+// to netlink socket and writing data to ring buffer
+static void *procevent_netlink_thread(void *arg) /* {{{ */
+{
+ pthread_mutex_lock(&procevent_thread_lock);
+
+ while (procevent_netlink_thread_loop > 0) {
+ pthread_mutex_unlock(&procevent_thread_lock);
+
+ int status = read_event();
+
+ pthread_mutex_lock(&procevent_thread_lock);
+
+ if (status < 0) {
+ procevent_netlink_thread_error = 1;
+ break;
+ }
+ } /* while (procevent_netlink_thread_loop > 0) */
+
+ pthread_mutex_unlock(&procevent_thread_lock);
+
+ return (void *)0;
+} /* }}} void *procevent_netlink_thread */
+
+// Entry point for thread responsible for reading from
+// ring buffer and dispatching notifications
+static void *procevent_dequeue_thread(void *arg) /* {{{ */
+{
+ pthread_mutex_lock(&procevent_thread_lock);
+
+ while (procevent_dequeue_thread_loop > 0) {
+ pthread_mutex_unlock(&procevent_thread_lock);
+
+ read_ring_buffer();
+
+ pthread_mutex_lock(&procevent_thread_lock);
+ } /* while (procevent_dequeue_thread_loop > 0) */
+
+ pthread_mutex_unlock(&procevent_thread_lock);
+
+ return (void *)0;
+} /* }}} void *procevent_dequeue_thread */
+
+static int start_netlink_thread(void) /* {{{ */
+{
+ pthread_mutex_lock(&procevent_thread_lock);
+
+ if (procevent_netlink_thread_loop != 0) {
+ pthread_mutex_unlock(&procevent_thread_lock);
+ return 0;
+ }
+
+ int status;
+
+ if (nl_sock == -1) {
+ status = nl_connect();
+
+ if (status != 0) {
+ pthread_mutex_unlock(&procevent_thread_lock);
+ return status;
+ }
+
+ status = set_proc_ev_listen(true);
+ if (status == -1) {
+ pthread_mutex_unlock(&procevent_thread_lock);
+ return status;
+ }
+ }
+
+ DEBUG("procevent plugin: socket created and bound");
+
+ procevent_netlink_thread_loop = 1;
+ procevent_netlink_thread_error = 0;
+
+ status = plugin_thread_create(&procevent_netlink_thread_id, /* attr = */ NULL,
+ procevent_netlink_thread,
+ /* arg = */ (void *)0, "procevent");
+ if (status != 0) {
+ procevent_netlink_thread_loop = 0;
+ ERROR("procevent plugin: Starting netlink thread failed.");
+ pthread_mutex_unlock(&procevent_thread_lock);
+
+ int status2 = close(nl_sock);
+
+ if (status2 != 0) {
+ ERROR("procevent plugin: failed to close socket %d: %d (%s)", nl_sock,
+ status2, STRERRNO);
+ }
+
+ nl_sock = -1;
+
+ return -1;
+ }
+
+ pthread_mutex_unlock(&procevent_thread_lock);
+
+ return status;
+} /* }}} int start_netlink_thread */
+
+static int start_dequeue_thread(void) /* {{{ */
+{
+ pthread_mutex_lock(&procevent_thread_lock);
+
+ if (procevent_dequeue_thread_loop != 0) {
+ pthread_mutex_unlock(&procevent_thread_lock);
+ return 0;
+ }
+
+ procevent_dequeue_thread_loop = 1;
+
+ int status = plugin_thread_create(&procevent_dequeue_thread_id,
+ /* attr = */ NULL, procevent_dequeue_thread,
+ /* arg = */ (void *)0, "procevent");
+ if (status != 0) {
+ procevent_dequeue_thread_loop = 0;
+ ERROR("procevent plugin: Starting dequeue thread failed.");
+ pthread_mutex_unlock(&procevent_thread_lock);
+ return -1;
+ }
+
+ pthread_mutex_unlock(&procevent_thread_lock);
+
+ return status;
+} /* }}} int start_dequeue_thread */
+
+static int start_threads(void) /* {{{ */
+{
+ int status = start_netlink_thread();
+ int status2 = start_dequeue_thread();
+
+ if (status != 0)
+ return status;
+ else
+ return status2;
+} /* }}} int start_threads */
+
+static int stop_netlink_thread(int shutdown) /* {{{ */
+{
+ int socket_status;
+
+ if (nl_sock != -1) {
+ socket_status = close(nl_sock);
+ if (socket_status != 0) {
+ ERROR("procevent plugin: failed to close socket %d: %d (%s)", nl_sock,
+ socket_status, strerror(errno));
+ }
+
+ nl_sock = -1;
+ } else
+ socket_status = 0;
+
+ pthread_mutex_lock(&procevent_thread_lock);
+
+ if (procevent_netlink_thread_loop == 0) {
+ pthread_mutex_unlock(&procevent_thread_lock);
+ return -1;
+ }
+
+ // Set thread termination status
+ procevent_netlink_thread_loop = 0;
+ pthread_mutex_unlock(&procevent_thread_lock);
+
+ // Let threads waiting on access to the data know to move
+ // on such that they'll see the thread's termination status
+ pthread_cond_broadcast(&procevent_cond);
+
+ int thread_status;
+
+ if (shutdown == 1) {
+ // Calling pthread_cancel here in
+ // the case of a shutdown just assures that the thread is
+ // gone and that the process has been fully terminated.
+
+ DEBUG("procevent plugin: Canceling netlink thread for process shutdown");
+
+ thread_status = pthread_cancel(procevent_netlink_thread_id);
+
+ if (thread_status != 0 && thread_status != ESRCH) {
+ ERROR("procevent plugin: Unable to cancel netlink thread: %d",
+ thread_status);
+ thread_status = -1;
+ } else
+ thread_status = 0;
+ } else {
+ thread_status =
+ pthread_join(procevent_netlink_thread_id, /* return = */ NULL);
+ if (thread_status != 0 && thread_status != ESRCH) {
+ ERROR("procevent plugin: Stopping netlink thread failed.");
+ thread_status = -1;
+ } else
+ thread_status = 0;
+ }
+
+ pthread_mutex_lock(&procevent_thread_lock);
+ memset(&procevent_netlink_thread_id, 0, sizeof(procevent_netlink_thread_id));
+ procevent_netlink_thread_error = 0;
+ pthread_mutex_unlock(&procevent_thread_lock);
+
+ DEBUG("procevent plugin: Finished requesting stop of netlink thread");
+
+ if (socket_status != 0)
+ return socket_status;
+ else
+ return thread_status;
+} /* }}} int stop_netlink_thread */
+
+static int stop_dequeue_thread() /* {{{ */
+{
+ pthread_mutex_lock(&procevent_thread_lock);
+
+ if (procevent_dequeue_thread_loop == 0) {
+ pthread_mutex_unlock(&procevent_thread_lock);
+ return -1;
+ }
+
+ procevent_dequeue_thread_loop = 0;
+ pthread_mutex_unlock(&procevent_thread_lock);
+
+ pthread_cond_broadcast(&procevent_cond);
+
+ // Calling pthread_cancel here just assures that the thread is
+ // gone and that the process has been fully terminated.
+
+ DEBUG("procevent plugin: Canceling dequeue thread for process shutdown");
+
+ int status = pthread_cancel(procevent_dequeue_thread_id);
+
+ if (status != 0 && status != ESRCH) {
+ ERROR("procevent plugin: Unable to cancel dequeue thread: %d", status);
+ status = -1;
+ } else
+ status = 0;
+
+ pthread_mutex_lock(&procevent_thread_lock);
+ memset(&procevent_dequeue_thread_id, 0, sizeof(procevent_dequeue_thread_id));
+ pthread_mutex_unlock(&procevent_thread_lock);
+
+ DEBUG("procevent plugin: Finished requesting stop of dequeue thread");
+
+ return status;
+} /* }}} int stop_dequeue_thread */
+
+static int stop_threads() /* {{{ */
+{
+ int status = stop_netlink_thread(1);
+ int status2 = stop_dequeue_thread();
+
+ if (status != 0)
+ return status;
+ else
+ return status2;
+} /* }}} int stop_threads */
+
+static int procevent_init(void) /* {{{ */
+{
+ ring.head = 0;
+ ring.tail = 0;
+ ring.maxLen = buffer_length;
+ ring.buffer = (cdtime_t **)calloc(buffer_length, sizeof(cdtime_t *));
+
+ for (int i = 0; i < buffer_length; i++) {
+ ring.buffer[i] = (cdtime_t *)calloc(PROCEVENT_FIELDS, sizeof(cdtime_t));
+ }
+
+ int status = process_map_refresh();
+
+ if (status == -1) {
+ ERROR("procevent plugin: Initial process mapping failed.");
+ return -1;
+ }
+
+ if (ignorelist == NULL) {
+ NOTICE("procevent plugin: No processes have been configured.");
+ return -1;
+ }
+
+ return start_threads();
+} /* }}} int procevent_init */
+
+static int procevent_config(const char *key, const char *value) /* {{{ */
+{
+ if (ignorelist == NULL)
+ ignorelist = ignorelist_create(/* invert = */ 1);
+
+ if (ignorelist == NULL) {
+ return -1;
+ }
+
+ if (strcasecmp(key, "BufferLength") == 0) {
+ buffer_length = atoi(value);
+ } else if (strcasecmp(key, "Process") == 0) {
+ ignorelist_add(ignorelist, value);
+ } else if (strcasecmp(key, "ProcessRegex") == 0) {
+#if HAVE_REGEX_H
+ int status = ignorelist_add(ignorelist, value);
+
+ if (status != 0) {
+ ERROR("procevent plugin: invalid regular expression: %s", value);
+ return 1;
+ }
+#else
+ WARNING("procevent plugin: The plugin has been compiled without support "
+ "for the \"ProcessRegex\" option.");
+#endif
+ } else {
+ return -1;
+ }
+
+ return 0;
+} /* }}} int procevent_config */
+
+static int procevent_read(void) /* {{{ */
+{
+ pthread_mutex_lock(&procevent_thread_lock);
+
+ if (procevent_netlink_thread_error != 0) {
+
+ pthread_mutex_unlock(&procevent_thread_lock);
+
+ ERROR("procevent plugin: The netlink thread had a problem. Restarting it.");
+
+ stop_netlink_thread(0);
+
+ start_netlink_thread();
+
+ return -1;
+ } /* if (procevent_netlink_thread_error != 0) */
+
+ pthread_mutex_unlock(&procevent_thread_lock);
+
+ return 0;
+} /* }}} int procevent_read */
+
+static int procevent_shutdown(void) /* {{{ */
+{
+ DEBUG("procevent plugin: Shutting down threads.");
+
+ int status = stop_threads();
+
+ for (int i = 0; i < buffer_length; i++) {
+ free(ring.buffer[i]);
+ }
+
+ free(ring.buffer);
+
+ processlist_t *pl = processlist_head;
+ while (pl != NULL) {
+ processlist_t *pl_next;
+
+ pl_next = pl->next;
+
+ sfree(pl->process);
+ sfree(pl);
+
+ pl = pl_next;
+ }
+
+ ignorelist_free(ignorelist);
+
+ return status;
+} /* }}} int procevent_shutdown */
+
+void module_register(void) {
+ plugin_register_config("procevent", procevent_config, config_keys,
+ config_keys_num);
+ plugin_register_init("procevent", procevent_init);
+ plugin_register_read("procevent", procevent_read);
+ plugin_register_shutdown("procevent", procevent_shutdown);
+} /* void module_register */
* Global variables
*/
static const char *config_keys[] = {
- "Value", "IgnoreSelected",
+ "Value",
+ "IgnoreSelected",
};
static int config_keys_num = STATIC_ARRAY_SIZE(config_keys);
if (values_list != NULL) {
char match_name[2 * DATA_MAX_NAME_LEN];
- snprintf(match_name, sizeof(match_name), "%s:%s", key_buffer,
- key_fields[i]);
+ ssnprintf(match_name, sizeof(match_name), "%s:%s", key_buffer,
+ key_fields[i]);
if (ignorelist_match(values_list, match_name))
continue;
PyObject *mod = NULL;
if (name != NULL) {
- snprintf(buf, size, "python.%s", name);
+ ssnprintf(buf, size, "python.%s", name);
return;
}
module = cpy_unicode_or_bytes_to_string(&mod);
if (module != NULL) {
- snprintf(buf, size, "python.%s", module);
+ ssnprintf(buf, size, "python.%s", module);
Py_XDECREF(mod);
PyErr_Clear();
return;
}
Py_XDECREF(mod);
- snprintf(buf, size, "python.%p", callback);
+ ssnprintf(buf, size, "python.%p", callback);
PyErr_Clear();
}
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)));
+ PyTuple_SET_ITEM(
+ tuple, 1,
+ cpy_string_to_unicode_or_bytes(DS_TYPE_TO_STRING(ds->ds[i].type)));
PyTuple_SET_ITEM(tuple, 2, float_or_none(ds->ds[i].min));
PyTuple_SET_ITEM(tuple, 3, float_or_none(ds->ds[i].max));
PyList_SET_ITEM(list, i, tuple);
register_function(buf, handler,
&(user_data_t){
- .data = c, .free_func = cpy_destroy_user_data,
+ .data = c,
+ .free_func = cpy_destroy_user_data,
});
++cpy_num_callbacks;
/* group = */ "python", buf, cpy_read_callback,
DOUBLE_TO_CDTIME_T(interval),
&(user_data_t){
- .data = c, .free_func = cpy_destroy_user_data,
+ .data = c,
+ .free_func = cpy_destroy_user_data,
});
++cpy_num_callbacks;
return cpy_string_to_unicode_or_bytes(buf);
values = PyTuple_New(ci->values_num); /* New reference. */
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));
+ 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) {
PyTuple_SET_ITEM(values, i,
PyFloat_FromDouble(ci->values[i].value.number));
redis_have_instances = true;
char cb_name[sizeof("redis/") + DATA_MAX_NAME_LEN];
- snprintf(cb_name, sizeof(cb_name), "redis/%s", rn->name);
+ ssnprintf(cb_name, sizeof(cb_name), "redis/%s", rn->name);
return plugin_register_complex_read(
/* group = */ "redis",
/* callback = */ redis_read,
/* interval = */ 0,
&(user_data_t){
- .data = rn, .free_func = redis_node_free,
+ .data = rn,
+ .free_func = redis_node_free,
});
} /* }}} */
char *str;
int i;
- snprintf(field_name, sizeof(field_name), "db%d:keys=", db);
+ ssnprintf(field_name, sizeof(field_name), "db%d:keys=", db);
str = strstr(info_line, field_name);
if (!str)
return -1;
}
- snprintf(db_id, sizeof(db_id), "%d", db);
+ ssnprintf(db_id, sizeof(db_id), "%d", db);
redis_submit(node, "records", db_id, val);
}
return 0;
const char *type_instance, derive_t rx, derive_t tx) {
value_list_t vl = VALUE_LIST_INIT;
value_t values[] = {
- {.derive = rx}, {.derive = tx},
+ {.derive = rx},
+ {.derive = tx},
};
vl.values = values;
name = "default";
/*** RX ***/
- snprintf(type_instance, sizeof(type_instance), "%s-%s-rx", r->interface,
- name);
+ ssnprintf(type_instance, sizeof(type_instance), "%s-%s-rx", r->interface,
+ name);
cr_submit_gauge(rd, "bitrate", type_instance,
(gauge_t)(1000000.0 * r->rx_rate));
cr_submit_gauge(rd, "signal_power", type_instance,
cr_submit_gauge(rd, "signal_quality", type_instance, (gauge_t)r->rx_ccq);
/*** TX ***/
- snprintf(type_instance, sizeof(type_instance), "%s-%s-tx", r->interface,
- name);
+ ssnprintf(type_instance, sizeof(type_instance), "%s-%s-tx", r->interface,
+ name);
cr_submit_gauge(rd, "bitrate", type_instance,
(gauge_t)(1000000.0 * r->tx_rate));
cr_submit_gauge(rd, "signal_power", type_instance,
cr_submit_gauge(rd, "signal_quality", type_instance, (gauge_t)r->tx_ccq);
/*** RX / TX ***/
- snprintf(type_instance, sizeof(type_instance), "%s-%s", r->interface, name);
+ ssnprintf(type_instance, sizeof(type_instance), "%s-%s", r->interface, name);
cr_submit_io(rd, "if_octets", type_instance, (derive_t)r->rx_bytes,
(derive_t)r->tx_bytes);
cr_submit_gauge(rd, "snr", type_instance, (gauge_t)r->signal_to_noise);
return status;
}
- snprintf(read_name, sizeof(read_name), "routeros/%s", router_data->node);
+ ssnprintf(read_name, sizeof(read_name), "routeros/%s", router_data->node);
return plugin_register_complex_read(
/* group = */ NULL, read_name, cr_read, /* interval = */ 0,
&(user_data_t){
- .data = router_data, .free_func = (void *)cr_free_data,
+ .data = router_data,
+ .free_func = (void *)cr_free_data,
});
} /* }}} int cr_config_router */
memset(buffer, '\0', buffer_len);
int status =
- snprintf(buffer, buffer_len, "%.6f", CDTIME_T_TO_DOUBLE(vl->time));
+ ssnprintf(buffer, buffer_len, "%.6f", CDTIME_T_TO_DOUBLE(vl->time));
if ((status < 1) || (status >= buffer_len))
return -1;
int offset = status;
return -1;
if (ds->ds[i].type == DS_TYPE_COUNTER) {
- status = snprintf(buffer + offset, buffer_len - offset, ":%" PRIu64,
- (uint64_t)vl->values[i].counter);
+ status = ssnprintf(buffer + offset, buffer_len - offset, ":%" PRIu64,
+ (uint64_t)vl->values[i].counter);
} else if (ds->ds[i].type == DS_TYPE_GAUGE) {
- status = snprintf(buffer + offset, buffer_len - offset, ":%f",
- vl->values[i].gauge);
+ status = ssnprintf(buffer + offset, buffer_len - offset, ":%f",
+ vl->values[i].gauge);
} else if (ds->ds[i].type == DS_TYPE_DERIVE) {
- status = snprintf(buffer + offset, buffer_len - offset, ":%" PRIi64,
- vl->values[i].derive);
+ status = ssnprintf(buffer + offset, buffer_len - offset, ":%" PRIi64,
+ vl->values[i].derive);
} else /* if (ds->ds[i].type == DS_TYPE_ABSOLUTE) */ {
- status = snprintf(buffer + offset, buffer_len - offset, ":%" PRIu64,
- vl->values[i].absolute);
+ status = ssnprintf(buffer + offset, buffer_len - offset, ":%" PRIu64,
+ vl->values[i].absolute);
}
if ((status < 1) || (status >= (buffer_len - offset)))
}
char *values_array[2] = {
- [0] = values, [1] = NULL,
+ [0] = values,
+ [1] = NULL,
};
while (42) {
char filename[PATH_MAX + 1];
if (datadir != NULL)
- snprintf(filename, sizeof(filename), "%s/%s.rrd", datadir, identifier);
+ ssnprintf(filename, sizeof(filename), "%s/%s.rrd", datadir, identifier);
else
- snprintf(filename, sizeof(filename), "%s.rrd", identifier);
+ ssnprintf(filename, sizeof(filename), "%s.rrd", identifier);
rrd_clear_error();
int status = rrdc_connect(daemon_address);
return status;
} /* int srrd_update */
-/* #endif HAVE_THREADSAFE_LIBRRD */
+ /* #endif HAVE_THREADSAFE_LIBRRD */
#else /* !HAVE_THREADSAFE_LIBRRD */
static int srrd_update(char *filename, char *template, int argc,
memset(buffer, '\0', buffer_len);
tt = CDTIME_T_TO_TIME_T(vl->time);
- status = snprintf(buffer, buffer_len, "%u", (unsigned int)tt);
+ status = ssnprintf(buffer, buffer_len, "%u", (unsigned int)tt);
if ((status < 1) || (status >= buffer_len))
return -1;
offset = status;
return -1;
if (ds->ds[i].type == DS_TYPE_COUNTER)
- status = snprintf(buffer + offset, buffer_len - offset, ":%" PRIu64,
- (uint64_t)vl->values[i].counter);
+ status = ssnprintf(buffer + offset, buffer_len - offset, ":%" PRIu64,
+ (uint64_t)vl->values[i].counter);
else if (ds->ds[i].type == DS_TYPE_GAUGE)
- status = snprintf(buffer + offset, buffer_len - offset, ":" GAUGE_FORMAT,
- vl->values[i].gauge);
+ status = ssnprintf(buffer + offset, buffer_len - offset, ":" GAUGE_FORMAT,
+ vl->values[i].gauge);
else if (ds->ds[i].type == DS_TYPE_DERIVE)
- status = snprintf(buffer + offset, buffer_len - offset, ":%" PRIi64,
- vl->values[i].derive);
+ status = ssnprintf(buffer + offset, buffer_len - offset, ":%" PRIi64,
+ vl->values[i].derive);
else /*if (ds->ds[i].type == DS_TYPE_ABSOLUTE) */
- status = snprintf(buffer + offset, buffer_len - offset, ":%" PRIu64,
- vl->values[i].absolute);
+ status = ssnprintf(buffer + offset, buffer_len - offset, ":%" PRIu64,
+ vl->values[i].absolute);
if ((status < 1) || (status >= (buffer_len - offset)))
return -1;
tt = CDTIME_T_TO_TIME_T(vl->time);
switch (ds->ds[0].type) {
case DS_TYPE_DERIVE:
- status = snprintf(buffer, buffer_len, "%u:%" PRIi64, (unsigned)tt,
- vl->values[0].derive);
+ status = ssnprintf(buffer, buffer_len, "%u:%" PRIi64, (unsigned)tt,
+ vl->values[0].derive);
break;
case DS_TYPE_GAUGE:
- status = snprintf(buffer, buffer_len, "%u:" GAUGE_FORMAT, (unsigned)tt,
- vl->values[0].gauge);
+ status = ssnprintf(buffer, buffer_len, "%u:" GAUGE_FORMAT, (unsigned)tt,
+ vl->values[0].gauge);
break;
case DS_TYPE_COUNTER:
- status = snprintf(buffer, buffer_len, "%u:%" PRIu64, (unsigned)tt,
- (uint64_t)vl->values[0].counter);
+ status = ssnprintf(buffer, buffer_len, "%u:%" PRIu64, (unsigned)tt,
+ (uint64_t)vl->values[0].counter);
break;
case DS_TYPE_ABSOLUTE:
- status = snprintf(buffer, buffer_len, "%u:%" PRIu64, (unsigned)tt,
- vl->values[0].absolute);
+ status = ssnprintf(buffer, buffer_len, "%u:%" PRIu64, (unsigned)tt,
+ vl->values[0].absolute);
break;
default:
return EINVAL;
now = cdtime();
if (datadir == NULL)
- snprintf(key, sizeof(key), "%s.rrd", identifier);
+ ssnprintf(key, sizeof(key), "%s.rrd", identifier);
else
- snprintf(key, sizeof(key), "%s/%s.rrd", datadir, identifier);
+ ssnprintf(key, sizeof(key), "%s/%s.rrd", datadir, identifier);
key[sizeof(key) - 1] = '\0';
status = c_avl_get(cache, key, (void *)&rc);
last_feature = fl;
} /* while sensors_get_all_features */
} /* while sensors_get_detected_chips */
-/* #endif SENSORS_API_VERSION < 0x400 */
+ /* #endif SENSORS_API_VERSION < 0x400 */
#elif (SENSORS_API_VERSION >= 0x400)
chip_num = 0;
sensors_submit(plugin_instance, sensor_type_name_map[fl->type],
type_instance, value);
} /* for fl = first_feature .. NULL */
-/* #endif SENSORS_API_VERSION < 0x400 */
+ /* #endif SENSORS_API_VERSION < 0x400 */
#elif (SENSORS_API_VERSION >= 0x400)
for (featurelist_t *fl = first_feature; fl != NULL; fl = fl->next) {
static void serial_submit(const char *type_instance, derive_t rx, derive_t tx) {
value_list_t vl = VALUE_LIST_INIT;
value_t values[] = {
- {.derive = rx}, {.derive = tx},
+ {.derive = rx},
+ {.derive = tx},
};
vl.values = values;
}
cfdev->sdi = devlist->data;
g_slist_free(devlist);
- snprintf(hwident, sizeof(hwident), "%s %s %s",
- cfdev->sdi->vendor ? cfdev->sdi->vendor : "",
- cfdev->sdi->model ? cfdev->sdi->model : "",
- cfdev->sdi->version ? cfdev->sdi->version : "");
+ ssnprintf(hwident, sizeof(hwident), "%s %s %s",
+ cfdev->sdi->vendor ? cfdev->sdi->vendor : "",
+ cfdev->sdi->model ? cfdev->sdi->model : "",
+ cfdev->sdi->version ? cfdev->sdi->version : "");
INFO("sigrok plugin: Device \"%s\" is a %s", cfdev->name, hwident);
if (sr_dev_open(cfdev->sdi) != SR_OK)
sstrncpy(notif.host, hostname_g, sizeof(notif.host));
sstrncpy(notif.plugin_instance, name, sizeof(notif.plugin_instance));
sstrncpy(notif.type_instance, a->name, sizeof(notif.type_instance));
- snprintf(notif.message, sizeof(notif.message),
- "attribute %s is below allowed threshold (%d < %d)", a->name,
- a->current_value, a->threshold);
+ ssnprintf(notif.message, sizeof(notif.message),
+ "attribute %s is below allowed threshold (%d < %d)", a->name,
+ a->current_value, a->threshold);
plugin_dispatch_notification(¬if);
}
}
c_complain_t complaint;
data_definition_t **data_list;
int data_list_len;
+ int bulk_size;
};
typedef struct host_definition_s host_definition_t;
char *oid_str_ptr[MAX_OID_LEN];
for (size_t i = 0; i < o->oid_len; i++) {
- snprintf(oid_str[i], sizeof(oid_str[i]), "%lu", (unsigned long)o->oid[i]);
+ ssnprintf(oid_str[i], sizeof(oid_str[i]), "%lu", (unsigned long)o->oid[i]);
oid_str_ptr[i] = oid_str[i];
}
/* These mean that we have not set a timeout or retry value */
hd->timeout = 0;
hd->retries = -1;
+ hd->bulk_size = 0;
for (int i = 0; i < ci->children_num; i++) {
oconfig_item_t *option = ci->children + i;
status = csnmp_config_add_host_security_level(hd, option);
else if (strcasecmp("Context", option->key) == 0)
status = cf_util_get_string(option, &hd->context);
+ else if (strcasecmp("BulkSize", option->key) == 0)
+ status = cf_util_get_int(option, &hd->bulk_size);
else {
WARNING(
"snmp plugin: csnmp_config_add_host: Option `%s' not allowed here.",
status = -1;
break;
}
+ if (hd->bulk_size > 0 && hd->version < 2) {
+ WARNING("snmp plugin: Bulk transfers is only available for SNMP v2 and "
+ "later, host '%s' is configured as version '%d'",
+ hd->name, hd->version);
+ }
if (hd->version == 3) {
if (hd->username == NULL) {
WARNING("snmp plugin: `Username' not given for host `%s'", hd->name);
"= %i }",
hd->name, hd->address, hd->community, hd->version);
- snprintf(cb_name, sizeof(cb_name), "snmp-%s", hd->name);
+ ssnprintf(cb_name, sizeof(cb_name), "snmp-%s", hd->name);
status = plugin_register_complex_read(
/* group = */ NULL, cb_name, csnmp_read_host, interval,
&(user_data_t){
- .data = hd, .free_func = csnmp_host_definition_destroy,
+ .data = hd,
+ .free_func = csnmp_host_definition_destroy,
});
if (status != 0) {
ERROR("snmp plugin: Registering complex read function failed.");
for (size_t i = 0; i < vb->val_len; i++) {
int status;
- status = snprintf(buffer_ptr, buffer_free, (i == 0) ? "%02x" : ":%02x",
- (unsigned int)vb->val.bitstring[i]);
+ status = ssnprintf(buffer_ptr, buffer_free, (i == 0) ? "%02x" : ":%02x",
+ (unsigned int)vb->val.bitstring[i]);
assert(status >= 0);
if (((size_t)status) >= buffer_free) /* truncated */
else if (vb->type == ASN_BIT_STR)
src = (char *)vb->val.bitstring;
else if (vb->type == ASN_IPADDRESS) {
- return snprintf(dst, dst_size,
- "%" PRIu8 ".%" PRIu8 ".%" PRIu8 ".%" PRIu8 "",
- (uint8_t)vb->val.string[0], (uint8_t)vb->val.string[1],
- (uint8_t)vb->val.string[2], (uint8_t)vb->val.string[3]);
+ return ssnprintf(dst, dst_size,
+ "%" PRIu8 ".%" PRIu8 ".%" PRIu8 ".%" PRIu8 "",
+ (uint8_t)vb->val.string[0], (uint8_t)vb->val.string[1],
+ (uint8_t)vb->val.string[2], (uint8_t)vb->val.string[3]);
} else {
dst[0] = 0;
return EINVAL;
value_t val = csnmp_value_list_to_value(
vb, DS_TYPE_COUNTER,
/* scale = */ 1.0, /* shift = */ 0.0, hd->name, dd->name);
- snprintf(il->value, sizeof(il->value), "%" PRIu64, (uint64_t)val.counter);
+ ssnprintf(il->value, sizeof(il->value), "%" PRIu64, (uint64_t)val.counter);
}
return il;
if (data->host.prefix == NULL)
sstrncpy(vl.host, temp, sizeof(vl.host));
else
- snprintf(vl.host, sizeof(vl.host), "%s%s", data->host.prefix, temp);
+ ssnprintf(vl.host, sizeof(vl.host), "%s%s", data->host.prefix, temp);
} else {
sstrncpy(vl.host, host->name, sizeof(vl.host));
}
if (data->type_instance.prefix == NULL)
sstrncpy(vl.type_instance, temp, sizeof(vl.type_instance));
else
- snprintf(vl.type_instance, sizeof(vl.type_instance), "%s%s",
- data->type_instance.prefix, temp);
+ ssnprintf(vl.type_instance, sizeof(vl.type_instance), "%s%s",
+ data->type_instance.prefix, temp);
} else if (data->type_instance.value) {
sstrncpy(vl.type_instance, data->type_instance.value,
sizeof(vl.type_instance));
if (data->plugin_instance.prefix == NULL)
sstrncpy(vl.plugin_instance, temp, sizeof(vl.plugin_instance));
else
- snprintf(vl.plugin_instance, sizeof(vl.plugin_instance), "%s%s",
- data->plugin_instance.prefix, temp);
+ ssnprintf(vl.plugin_instance, sizeof(vl.plugin_instance), "%s%s",
+ data->plugin_instance.prefix, temp);
} else if (data->plugin_instance.value) {
sstrncpy(vl.plugin_instance, data->plugin_instance.value,
sizeof(vl.plugin_instance));
status = 0;
while (status == 0) {
- req = snmp_pdu_create(SNMP_MSG_GETNEXT);
+ /* If SNMP v2 and later and bulk transfers enabled, use GETBULK PDU */
+ if (host->version > 1 && host->bulk_size > 0) {
+ req = snmp_pdu_create(SNMP_MSG_GETBULK);
+ req->non_repeaters = 0;
+ req->max_repetitions = host->bulk_size;
+ } else {
+ req = snmp_pdu_create(SNMP_MSG_GETNEXT);
+ }
if (req == NULL) {
ERROR("snmp plugin: snmp_pdu_create failed.");
status = -1;
break;
}
+ if (req->command == SNMP_MSG_GETBULK) {
+ /* In bulk mode the host will send 'max_repetitions' values per
+ requested variable, so we need to split it per number of variable
+ to stay 'in budget' */
+ req->max_repetitions = floor(host->bulk_size / oid_list_todo_num);
+ }
+
res = NULL;
status = snmp_sess_synch_response(host->sess_handle, req, &res);
continue;
}
- for (vb = res->variables, i = 0; (vb != NULL);
- vb = vb->next_variable, i++) {
+ size_t j;
+ for (vb = res->variables, j = 0; (vb != NULL);
+ vb = vb->next_variable, j++) {
+ i = j;
+ /* If bulk request is active convert value index of the extra value */
+ if (host->version > 1 && host->bulk_size > 0) {
+ i %= oid_list_todo_num;
+ }
/* Calculate value index from todo list */
while ((i < oid_list_len) && !oid_list_todo[i]) {
i++;
+ j++;
}
if (i >= oid_list_len) {
break;
char *oid_str_ptr[MAX_OID_LEN];
for (size_t i = 0; i < o->oid_len; i++) {
- snprintf(oid_str[i], sizeof(oid_str[i]), "%lu", (unsigned long)o->oid[i]);
+ ssnprintf(oid_str[i], sizeof(oid_str[i]), "%lu", (unsigned long)o->oid[i]);
oid_str_ptr[i] = oid_str[i];
}
if (index == NULL)
snmp_agent_oid_to_string(index_str, sizeof(index_str), index_oid);
else
- snprintf(index_str, sizeof(index_str), "%d", *index);
+ ssnprintf(index_str, sizeof(index_str), "%d", *index);
notification_t n = {
.severity = NOTIF_WARNING, .time = cdtime(), .plugin = PLUGIN_NAME};
sstrncpy(n.host, hostname_g, sizeof(n.host));
- snprintf(n.message, sizeof(n.message),
- "Removed data row from table %s with index %s", td->name, index_str);
+ ssnprintf(n.message, sizeof(n.message),
+ "Removed data row from table %s with index %s", td->name,
+ index_str);
DEBUG(PLUGIN_NAME ": %s", n.message);
plugin_dispatch_notification(&n);
strncat(out, tok->str, DATA_MAX_NAME_LEN - strlen(out) - 1);
if (tok->key != NULL) {
if (tok->key->type == ASN_INTEGER) {
- snprintf(str, sizeof(str), "%ld", *tok->key->val.integer);
+ ssnprintf(str, sizeof(str), "%ld", *tok->key->val.integer);
strncat(out, str, DATA_MAX_NAME_LEN - strlen(out) - 1);
} else /* OCTET_STR */
strncat(out, (char *)tok->key->val.string,
}
if (td->index_keys[i].type == ASN_INTEGER) {
- snprintf(str, sizeof(str), "%ld", *key->val.integer);
+ ssnprintf(str, sizeof(str), "%ld", *key->val.integer);
fields[source] = str;
} else /* OCTET_STR */
fields[source] = (char *)key->val.string;
case ASN_OCTET_STR:
if (type == DS_TYPE_GAUGE) {
char buf[DATA_MAX_NAME_LEN];
- snprintf(buf, sizeof(buf), "%.2f", val->gauge);
+ ssnprintf(buf, sizeof(buf), "%.2f", val->gauge);
if (*data_len < strlen(buf))
return -EINVAL;
*data_len = strlen(buf);
if (index == NULL)
snmp_agent_oid_to_string(index_str, sizeof(index_str), index_oid);
else
- snprintf(index_str, sizeof(index_str), "%d", *index);
+ ssnprintf(index_str, sizeof(index_str), "%d", *index);
notification_t n = {
.severity = NOTIF_OKAY, .time = cdtime(), .plugin = PLUGIN_NAME};
sstrncpy(n.host, hostname_g, sizeof(n.host));
- snprintf(n.message, sizeof(n.message),
- "Data added to table %s with index %s", td->name, index_str);
+ ssnprintf(n.message, sizeof(n.message),
+ "Data added to table %s with index %s", td->name, index_str);
DEBUG(PLUGIN_NAME ": %s", n.message);
plugin_dispatch_notification(&n);
return ERANGE;
}
- tmp =
- realloc(conf_timer_percentile,
- sizeof(*conf_timer_percentile) * (conf_timer_percentile_num + 1));
+ tmp = realloc(conf_timer_percentile, sizeof(*conf_timer_percentile) *
+ (conf_timer_percentile_num + 1));
if (tmp == NULL) {
ERROR("statsd plugin: realloc failed.");
return ENOMEM;
#if HAVE_SYS_PARAM_H
#include <sys/param.h>
#endif
-#if HAVE_SYS_SYSCTL_H
+#if (defined(HAVE_SYS_SYSCTL_H) && defined(HAVE_SYSCTLBYNAME)) || \
+ defined(__OpenBSD__)
+/* implies BSD variant */
#include <sys/sysctl.h>
#endif
#if HAVE_SYS_DKSTAT_H
{
#if KERNEL_LINUX
pagesize = (derive_t)sysconf(_SC_PAGESIZE);
-/* #endif KERNEL_LINUX */
+ /* #endif KERNEL_LINUX */
#elif HAVE_SWAPCTL && HAVE_SWAPCTL_TWO_ARGS
/* getpagesize(3C) tells me this does not fail.. */
pagesize = (derive_t)getpagesize();
-/* #endif HAVE_SWAPCTL */
+ /* #endif HAVE_SWAPCTL */
#elif defined(VM_SWAPUSAGE)
/* No init stuff */
ERROR("swap plugin: kvm_openfiles failed, %s", errbuf);
return -1;
}
-/* #endif HAVE_LIBKVM_GETSWAPINFO */
+ /* #endif HAVE_LIBKVM_GETSWAPINFO */
#elif HAVE_LIBSTATGRAB
/* No init stuff */
--- /dev/null
+/**
+ * collectd - src/sysevent.c
+ *
+ * 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:
+ * Red Hat NFVPE
+ * Andrew Bays <abays at redhat.com>
+ **/
+
+#include "collectd.h"
+
+#include "plugin.h"
+#include "utils/common/common.h"
+#include "utils/ignorelist/ignorelist.h"
+#include "utils_complain.h"
+
+#include <errno.h>
+#include <netdb.h>
+#include <netinet/in.h>
+#include <pthread.h>
+#include <regex.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/socket.h>
+#include <unistd.h>
+
+#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)
+#include <yajl/yajl_tree.h>
+#define HAVE_YAJL_V2 1
+#endif
+
+#define SYSEVENT_DOMAIN_FIELD "domain"
+#define SYSEVENT_DOMAIN_VALUE "syslog"
+#define SYSEVENT_EVENT_ID_FIELD "eventId"
+#define SYSEVENT_EVENT_NAME_FIELD "eventName"
+#define SYSEVENT_EVENT_NAME_VALUE "syslog message"
+#define SYSEVENT_LAST_EPOCH_MICROSEC_FIELD "lastEpochMicrosec"
+#define SYSEVENT_PRIORITY_FIELD "priority"
+#define SYSEVENT_PRIORITY_VALUE_HIGH "high"
+#define SYSEVENT_PRIORITY_VALUE_LOW "low"
+#define SYSEVENT_PRIORITY_VALUE_MEDIUM "medium"
+#define SYSEVENT_PRIORITY_VALUE_NORMAL "normal"
+#define SYSEVENT_PRIORITY_VALUE_UNKNOWN "unknown"
+#define SYSEVENT_REPORTING_ENTITY_NAME_FIELD "reportingEntityName"
+#define SYSEVENT_REPORTING_ENTITY_NAME_VALUE "collectd sysevent plugin"
+#define SYSEVENT_SEQUENCE_FIELD "sequence"
+#define SYSEVENT_SEQUENCE_VALUE "0"
+#define SYSEVENT_SOURCE_NAME_FIELD "sourceName"
+#define SYSEVENT_SOURCE_NAME_VALUE "syslog"
+#define SYSEVENT_START_EPOCH_MICROSEC_FIELD "startEpochMicrosec"
+#define SYSEVENT_VERSION_FIELD "version"
+#define SYSEVENT_VERSION_VALUE "1.0"
+
+#define SYSEVENT_EVENT_SOURCE_HOST_FIELD "eventSourceHost"
+#define SYSEVENT_EVENT_SOURCE_TYPE_FIELD "eventSourceType"
+#define SYSEVENT_EVENT_SOURCE_TYPE_VALUE "host"
+#define SYSEVENT_SYSLOG_FIELDS_FIELD "syslogFields"
+#define SYSEVENT_SYSLOG_FIELDS_VERSION_FIELD "syslogFieldsVersion"
+#define SYSEVENT_SYSLOG_FIELDS_VERSION_VALUE "1.0"
+#define SYSEVENT_SYSLOG_MSG_FIELD "syslogMsg"
+#define SYSEVENT_SYSLOG_PROC_FIELD "syslogProc"
+#define SYSEVENT_SYSLOG_SEV_FIELD "syslogSev"
+#define SYSEVENT_SYSLOG_TAG_FIELD "syslogTag"
+#define SYSEVENT_SYSLOG_TAG_VALUE "NILVALUE"
+
+/*
+ * Private data types
+ */
+
+typedef struct {
+ int head;
+ int tail;
+ int maxLen;
+ char **buffer;
+ cdtime_t *timestamp;
+} circbuf_t;
+
+/*
+ * Private variables
+ */
+
+static ignorelist_t *ignorelist = NULL;
+
+static int sysevent_socket_thread_loop = 0;
+static int sysevent_socket_thread_error = 0;
+static pthread_t sysevent_socket_thread_id;
+static int sysevent_dequeue_thread_loop = 0;
+static pthread_t sysevent_dequeue_thread_id;
+static pthread_mutex_t sysevent_thread_lock = PTHREAD_MUTEX_INITIALIZER;
+static pthread_mutex_t sysevent_data_lock = PTHREAD_MUTEX_INITIALIZER;
+static pthread_cond_t sysevent_cond = PTHREAD_COND_INITIALIZER;
+static int sock = -1;
+static int event_id = 0;
+static circbuf_t ring;
+
+static char *listen_ip;
+static char *listen_port;
+static int listen_buffer_size = 4096;
+static int buffer_length = 10;
+
+static int monitor_all_messages = 1;
+
+#if HAVE_YAJL_V2
+static const char *rsyslog_keys[3] = {"@timestamp", "@source_host", "@message"};
+static const char *rsyslog_field_keys[5] = {
+ "facility", "severity", "severity-num", "program", "processid"};
+#endif
+
+/*
+ * Private functions
+ */
+
+static int gen_message_payload(const char *msg, char *sev, int sev_num,
+ char *process, char *host, cdtime_t timestamp,
+ char **buf) {
+ const unsigned char *buf2;
+ yajl_gen g;
+ char json_str[DATA_MAX_NAME_LEN];
+
+#if !defined(HAVE_YAJL_V2)
+ yajl_gen_config conf = {0};
+#endif
+
+#if HAVE_YAJL_V2
+ size_t len;
+ g = yajl_gen_alloc(NULL);
+ yajl_gen_config(g, yajl_gen_beautify, 0);
+#else
+ unsigned int len;
+ g = yajl_gen_alloc(&conf, NULL);
+#endif
+
+ yajl_gen_clear(g);
+
+ // *** BEGIN common event header ***
+
+ if (yajl_gen_map_open(g) != yajl_gen_status_ok)
+ goto err;
+
+ // domain
+ if (yajl_gen_string(g, (u_char *)SYSEVENT_DOMAIN_FIELD,
+ strlen(SYSEVENT_DOMAIN_FIELD)) != yajl_gen_status_ok)
+ goto err;
+
+ if (yajl_gen_string(g, (u_char *)SYSEVENT_DOMAIN_VALUE,
+ strlen(SYSEVENT_DOMAIN_VALUE)) != yajl_gen_status_ok)
+ goto err;
+
+ // eventId
+ if (yajl_gen_string(g, (u_char *)SYSEVENT_EVENT_ID_FIELD,
+ strlen(SYSEVENT_EVENT_ID_FIELD)) != yajl_gen_status_ok)
+ goto err;
+
+ event_id = event_id + 1;
+ snprintf(json_str, sizeof(json_str), "%d", event_id);
+
+ if (yajl_gen_number(g, json_str, strlen(json_str)) != yajl_gen_status_ok) {
+ goto err;
+ }
+
+ // eventName
+ if (yajl_gen_string(g, (u_char *)SYSEVENT_EVENT_NAME_FIELD,
+ strlen(SYSEVENT_EVENT_NAME_FIELD)) != yajl_gen_status_ok)
+ goto err;
+
+ snprintf(json_str, sizeof(json_str), "host %s rsyslog message", host);
+
+ if (yajl_gen_string(g, (u_char *)json_str, strlen(json_str)) !=
+ yajl_gen_status_ok) {
+ goto err;
+ }
+
+ // lastEpochMicrosec
+ if (yajl_gen_string(g, (u_char *)SYSEVENT_LAST_EPOCH_MICROSEC_FIELD,
+ strlen(SYSEVENT_LAST_EPOCH_MICROSEC_FIELD)) !=
+ yajl_gen_status_ok)
+ goto err;
+
+ snprintf(json_str, sizeof(json_str), "%" PRIu64, CDTIME_T_TO_US(cdtime()));
+
+ if (yajl_gen_number(g, json_str, strlen(json_str)) != yajl_gen_status_ok) {
+ goto err;
+ }
+
+ // priority
+ if (yajl_gen_string(g, (u_char *)SYSEVENT_PRIORITY_FIELD,
+ strlen(SYSEVENT_PRIORITY_FIELD)) != yajl_gen_status_ok)
+ goto err;
+
+ switch (sev_num) {
+ case 4:
+ if (yajl_gen_string(g, (u_char *)SYSEVENT_PRIORITY_VALUE_MEDIUM,
+ strlen(SYSEVENT_PRIORITY_VALUE_MEDIUM)) !=
+ yajl_gen_status_ok)
+ goto err;
+ break;
+ case 5:
+ if (yajl_gen_string(g, (u_char *)SYSEVENT_PRIORITY_VALUE_NORMAL,
+ strlen(SYSEVENT_PRIORITY_VALUE_NORMAL)) !=
+ yajl_gen_status_ok)
+ goto err;
+ break;
+ case 6:
+ case 7:
+ if (yajl_gen_string(g, (u_char *)SYSEVENT_PRIORITY_VALUE_LOW,
+ strlen(SYSEVENT_PRIORITY_VALUE_LOW)) !=
+ yajl_gen_status_ok)
+ goto err;
+ break;
+ default:
+ if (yajl_gen_string(g, (u_char *)SYSEVENT_PRIORITY_VALUE_UNKNOWN,
+ strlen(SYSEVENT_PRIORITY_VALUE_UNKNOWN)) !=
+ yajl_gen_status_ok)
+ goto err;
+ break;
+ }
+
+ // reportingEntityName
+ if (yajl_gen_string(g, (u_char *)SYSEVENT_REPORTING_ENTITY_NAME_FIELD,
+ strlen(SYSEVENT_REPORTING_ENTITY_NAME_FIELD)) !=
+ yajl_gen_status_ok)
+ goto err;
+
+ if (yajl_gen_string(g, (u_char *)SYSEVENT_REPORTING_ENTITY_NAME_VALUE,
+ strlen(SYSEVENT_REPORTING_ENTITY_NAME_VALUE)) !=
+ yajl_gen_status_ok)
+ goto err;
+
+ // sequence
+ if (yajl_gen_string(g, (u_char *)SYSEVENT_SEQUENCE_FIELD,
+ strlen(SYSEVENT_SEQUENCE_FIELD)) != yajl_gen_status_ok)
+ goto err;
+
+ if (yajl_gen_number(g, SYSEVENT_SEQUENCE_VALUE,
+ strlen(SYSEVENT_SEQUENCE_VALUE)) != yajl_gen_status_ok)
+ goto err;
+
+ // sourceName
+ if (yajl_gen_string(g, (u_char *)SYSEVENT_SOURCE_NAME_FIELD,
+ strlen(SYSEVENT_SOURCE_NAME_FIELD)) != yajl_gen_status_ok)
+ goto err;
+
+ if (yajl_gen_string(g, (u_char *)SYSEVENT_SOURCE_NAME_VALUE,
+ strlen(SYSEVENT_SOURCE_NAME_VALUE)) != yajl_gen_status_ok)
+ goto err;
+
+ // startEpochMicrosec
+ if (yajl_gen_string(g, (u_char *)SYSEVENT_START_EPOCH_MICROSEC_FIELD,
+ strlen(SYSEVENT_START_EPOCH_MICROSEC_FIELD)) !=
+ yajl_gen_status_ok)
+ goto err;
+
+ snprintf(json_str, sizeof(json_str), "%" PRIu64, CDTIME_T_TO_US(timestamp));
+
+ if (yajl_gen_number(g, json_str, strlen(json_str)) != yajl_gen_status_ok) {
+ goto err;
+ }
+
+ // version
+ if (yajl_gen_string(g, (u_char *)SYSEVENT_VERSION_FIELD,
+ strlen(SYSEVENT_VERSION_FIELD)) != yajl_gen_status_ok)
+ goto err;
+
+ if (yajl_gen_number(g, SYSEVENT_VERSION_VALUE,
+ strlen(SYSEVENT_VERSION_VALUE)) != yajl_gen_status_ok)
+ goto err;
+
+ // *** END common event header ***
+
+ // *** BEGIN syslog fields ***
+
+ if (yajl_gen_string(g, (u_char *)SYSEVENT_SYSLOG_FIELDS_FIELD,
+ strlen(SYSEVENT_SYSLOG_FIELDS_FIELD)) !=
+ yajl_gen_status_ok)
+ goto err;
+
+ if (yajl_gen_map_open(g) != yajl_gen_status_ok)
+ goto err;
+
+ // eventSourceHost
+ if (yajl_gen_string(g, (u_char *)SYSEVENT_EVENT_SOURCE_HOST_FIELD,
+ strlen(SYSEVENT_EVENT_SOURCE_HOST_FIELD)) !=
+ yajl_gen_status_ok)
+ goto err;
+
+ if (yajl_gen_string(g, (u_char *)host, strlen(host)) != yajl_gen_status_ok)
+ goto err;
+
+ // eventSourceType
+ if (yajl_gen_string(g, (u_char *)SYSEVENT_EVENT_SOURCE_TYPE_FIELD,
+ strlen(SYSEVENT_EVENT_SOURCE_TYPE_FIELD)) !=
+ yajl_gen_status_ok)
+ goto err;
+
+ if (yajl_gen_string(g, (u_char *)SYSEVENT_EVENT_SOURCE_TYPE_VALUE,
+ strlen(SYSEVENT_EVENT_SOURCE_TYPE_VALUE)) !=
+ yajl_gen_status_ok)
+ goto err;
+
+ // syslogFieldsVersion
+ if (yajl_gen_string(g, (u_char *)SYSEVENT_SYSLOG_FIELDS_VERSION_FIELD,
+ strlen(SYSEVENT_SYSLOG_FIELDS_VERSION_FIELD)) !=
+ yajl_gen_status_ok)
+ goto err;
+
+ if (yajl_gen_number(g, SYSEVENT_SYSLOG_FIELDS_VERSION_VALUE,
+ strlen(SYSEVENT_SYSLOG_FIELDS_VERSION_VALUE)) !=
+ yajl_gen_status_ok)
+ goto err;
+
+ // syslogMsg
+ if (msg != NULL) {
+ if (yajl_gen_string(g, (u_char *)SYSEVENT_SYSLOG_MSG_FIELD,
+ strlen(SYSEVENT_SYSLOG_MSG_FIELD)) !=
+ yajl_gen_status_ok)
+ goto err;
+
+ if (yajl_gen_string(g, (u_char *)msg, strlen(msg)) != yajl_gen_status_ok)
+ goto err;
+ }
+
+ // syslogProc
+ if (process != NULL) {
+ if (yajl_gen_string(g, (u_char *)SYSEVENT_SYSLOG_PROC_FIELD,
+ strlen(SYSEVENT_SYSLOG_PROC_FIELD)) !=
+ yajl_gen_status_ok)
+ goto err;
+
+ if (yajl_gen_string(g, (u_char *)process, strlen(process)) !=
+ yajl_gen_status_ok)
+ goto err;
+ }
+
+ // syslogSev
+ if (sev != NULL) {
+ if (yajl_gen_string(g, (u_char *)SYSEVENT_SYSLOG_SEV_FIELD,
+ strlen(SYSEVENT_SYSLOG_SEV_FIELD)) !=
+ yajl_gen_status_ok)
+ goto err;
+
+ if (yajl_gen_string(g, (u_char *)sev, strlen(sev)) != yajl_gen_status_ok)
+ goto err;
+ }
+
+ // syslogTag
+ if (yajl_gen_string(g, (u_char *)SYSEVENT_SYSLOG_TAG_FIELD,
+ strlen(SYSEVENT_SYSLOG_TAG_FIELD)) != yajl_gen_status_ok)
+ goto err;
+
+ if (yajl_gen_string(g, (u_char *)SYSEVENT_SYSLOG_TAG_VALUE,
+ strlen(SYSEVENT_SYSLOG_TAG_VALUE)) != yajl_gen_status_ok)
+ goto err;
+
+ // *** END syslog fields ***
+
+ // close syslog and header fields
+ if (yajl_gen_map_close(g) != yajl_gen_status_ok ||
+ yajl_gen_map_close(g) != yajl_gen_status_ok)
+ goto err;
+
+ if (yajl_gen_get_buf(g, &buf2, &len) != yajl_gen_status_ok)
+ goto err;
+
+ *buf = strdup((char *)buf2);
+
+ if (*buf == NULL) {
+ ERROR("sysevent plugin: gen_message_payload strdup failed");
+ goto err;
+ }
+
+ yajl_gen_free(g);
+
+ return 0;
+
+err:
+ yajl_gen_free(g);
+ ERROR("sysevent plugin: gen_message_payload failed to generate JSON");
+ return -1;
+}
+
+static int read_socket() {
+ int recv_flags = MSG_DONTWAIT;
+
+ while (42) {
+ struct sockaddr_storage src_addr;
+ socklen_t src_addr_len = sizeof(src_addr);
+
+ char buffer[listen_buffer_size];
+ memset(buffer, '\0', listen_buffer_size);
+
+ ssize_t count = recvfrom(sock, buffer, sizeof(buffer), recv_flags,
+ (struct sockaddr *)&src_addr, &src_addr_len);
+
+ if (count < 0) {
+ if (errno == EAGAIN || errno == EWOULDBLOCK) {
+ pthread_mutex_lock(&sysevent_data_lock);
+
+ // There was nothing more to receive for now, so...
+ // If ring head does not equal ring tail, there is data
+ // in the ring buffer for the dequeue thread to read, so
+ // signal it
+ if (ring.head != ring.tail)
+ pthread_cond_signal(&sysevent_cond);
+
+ pthread_mutex_unlock(&sysevent_data_lock);
+
+ // Since there was nothing to receive, set recv to block and
+ // try again
+ recv_flags = 0;
+ continue;
+ } else if (errno != EINTR) {
+ ERROR("sysevent plugin: failed to receive data: %s", STRERRNO);
+ return -1;
+ } else {
+ // Interrupt, so continue and try again
+ continue;
+ }
+ }
+
+ if (count >= sizeof(buffer)) {
+ WARNING("sysevent plugin: datagram too large for buffer: truncated");
+ }
+
+ // We successfully received a message, so don't block on the next
+ // read in case there are more (and if there aren't, it will be
+ // handled above in the EWOULDBLOCK error-checking)
+ recv_flags = MSG_DONTWAIT;
+
+ // 1. Acquire data lock
+ // 2. Push to buffer if there is room, otherwise raise warning
+ // and allow dequeue thread to take over
+
+ pthread_mutex_lock(&sysevent_data_lock);
+
+ int next = ring.head + 1;
+ if (next >= ring.maxLen)
+ next = 0;
+
+ if (next == ring.tail) {
+ // Buffer is full, signal the dequeue thread to process the buffer
+ // and clean it out, and then sleep
+ WARNING("sysevent plugin: ring buffer full");
+
+ pthread_cond_signal(&sysevent_cond);
+ pthread_mutex_unlock(&sysevent_data_lock);
+
+ usleep(1000);
+ continue;
+ } else {
+ DEBUG("sysevent plugin: writing %s", buffer);
+
+ sstrncpy(ring.buffer[ring.head], buffer, sizeof(buffer));
+ ring.timestamp[ring.head] = cdtime();
+ ring.head = next;
+ }
+
+ pthread_mutex_unlock(&sysevent_data_lock);
+ }
+}
+
+static void sysevent_dispatch_notification(const char *message,
+#if HAVE_YAJL_V2
+ yajl_val *node,
+#endif
+ cdtime_t timestamp) {
+ char *buf = NULL;
+
+ notification_t n = {
+ .severity = NOTIF_OKAY,
+ .time = cdtime(),
+ .plugin = "sysevent",
+ .type = "gauge",
+ };
+
+#if HAVE_YAJL_V2
+ if (node != NULL) {
+ // If we have a parsed-JSON node to work with, use that
+ // msg
+ const char *msg_path[] = {rsyslog_keys[2], (const char *)0};
+ yajl_val msg_v = yajl_tree_get(*node, msg_path, yajl_t_string);
+
+ char msg[listen_buffer_size];
+
+ if (msg_v != NULL) {
+ memset(msg, '\0', listen_buffer_size);
+ snprintf(msg, listen_buffer_size, "%s%c", YAJL_GET_STRING(msg_v), '\0');
+ }
+
+ // severity
+ const char *severity_path[] = {"@fields", rsyslog_field_keys[1],
+ (const char *)0};
+ yajl_val severity_v = yajl_tree_get(*node, severity_path, yajl_t_string);
+
+ char severity[listen_buffer_size];
+
+ if (severity_v != NULL) {
+ memset(severity, '\0', listen_buffer_size);
+ snprintf(severity, listen_buffer_size, "%s%c",
+ YAJL_GET_STRING(severity_v), '\0');
+ }
+
+ // sev_num
+ const char *sev_num_str_path[] = {"@fields", rsyslog_field_keys[2],
+ (const char *)0};
+ yajl_val sev_num_str_v =
+ yajl_tree_get(*node, sev_num_str_path, yajl_t_string);
+
+ char sev_num_str[listen_buffer_size];
+ int sev_num = -1;
+
+ if (sev_num_str_v != NULL) {
+ memset(sev_num_str, '\0', listen_buffer_size);
+ snprintf(sev_num_str, listen_buffer_size, "%s%c",
+ YAJL_GET_STRING(sev_num_str_v), '\0');
+
+ sev_num = atoi(sev_num_str);
+
+ if (sev_num < 4)
+ n.severity = NOTIF_FAILURE;
+ }
+
+ // process
+ const char *process_path[] = {"@fields", rsyslog_field_keys[3],
+ (const char *)0};
+ yajl_val process_v = yajl_tree_get(*node, process_path, yajl_t_string);
+
+ char process[listen_buffer_size];
+
+ if (process_v != NULL) {
+ memset(process, '\0', listen_buffer_size);
+ snprintf(process, listen_buffer_size, "%s%c", YAJL_GET_STRING(process_v),
+ '\0');
+ }
+
+ // hostname
+ const char *hostname_path[] = {rsyslog_keys[1], (const char *)0};
+ yajl_val hostname_v = yajl_tree_get(*node, hostname_path, yajl_t_string);
+
+ char hostname_str[listen_buffer_size];
+
+ if (hostname_v != NULL) {
+ memset(hostname_str, '\0', listen_buffer_size);
+ snprintf(hostname_str, listen_buffer_size, "%s%c",
+ YAJL_GET_STRING(hostname_v), '\0');
+ }
+
+ gen_message_payload(
+ (msg_v != NULL ? msg : NULL), (severity_v != NULL ? severity : NULL),
+ (sev_num_str_v != NULL ? sev_num : -1),
+ (process_v != NULL ? process : NULL),
+ (hostname_v != NULL ? hostname_str : hostname_g), timestamp, &buf);
+ } else {
+ // Data was not sent in JSON format, so just treat the whole log entry
+ // as the message (and we'll be unable to acquire certain data, so the
+ // payload
+ // generated below will be less informative)
+
+ gen_message_payload(message, NULL, -1, NULL, hostname_g, timestamp, &buf);
+ }
+#else
+ gen_message_payload(message, NULL, -1, NULL, hostname_g, timestamp, &buf);
+#endif
+
+ sstrncpy(n.host, hostname_g, sizeof(n.host));
+
+ int status = plugin_notification_meta_add_string(&n, "ves", buf);
+
+ if (status < 0) {
+ sfree(buf);
+ ERROR("sysevent plugin: unable to set notification VES metadata: %s",
+ STRERRNO);
+ return;
+ }
+
+ DEBUG("sysevent plugin: notification VES metadata: %s",
+ n.meta->nm_value.nm_string);
+
+ DEBUG("sysevent plugin: dispatching message");
+
+ plugin_dispatch_notification(&n);
+ plugin_notification_meta_free(n.meta);
+
+ // strdup'd in gen_message_payload
+ if (buf != NULL)
+ sfree(buf);
+}
+
+static void read_ring_buffer() {
+ pthread_mutex_lock(&sysevent_data_lock);
+
+ // If there's currently nothing to read from the buffer,
+ // then wait
+ if (ring.head == ring.tail)
+ pthread_cond_wait(&sysevent_cond, &sysevent_data_lock);
+
+ while (ring.head != ring.tail) {
+ int next = ring.tail + 1;
+
+ if (next >= ring.maxLen)
+ next = 0;
+
+ DEBUG("sysevent plugin: reading from ring buffer: %s",
+ ring.buffer[ring.tail]);
+
+ cdtime_t timestamp = ring.timestamp[ring.tail];
+ char *match_str = NULL;
+
+#if HAVE_YAJL_V2
+ // Try to parse JSON, and if it fails, fall back to plain string
+ char errbuf[1024];
+ errbuf[0] = 0;
+ yajl_val node = yajl_tree_parse((const char *)ring.buffer[ring.tail],
+ errbuf, sizeof(errbuf));
+
+ if (node != NULL) {
+ // JSON rsyslog data
+
+ // If we have any regex filters, we need to see if the message portion of
+ // the data matches any of them (otherwise we're not interested)
+ if (monitor_all_messages == 0) {
+ const char *path[] = {"@message", (const char *)0};
+ yajl_val v = yajl_tree_get(node, path, yajl_t_string);
+
+ char json_val[listen_buffer_size];
+ memset(json_val, '\0', listen_buffer_size);
+
+ snprintf(json_val, listen_buffer_size, "%s%c", YAJL_GET_STRING(v),
+ '\0');
+
+ match_str = (char *)&json_val;
+ }
+ } else {
+ // non-JSON rsyslog data
+
+ // If we have any regex filters, we need to see if the message data
+ // matches any of them (otherwise we're not interested)
+ if (monitor_all_messages == 0)
+ match_str = ring.buffer[ring.tail];
+ }
+#else
+ // If we have any regex filters, we need to see if the message data
+ // matches any of them (otherwise we're not interested)
+ if (monitor_all_messages == 0)
+ match_str = ring.buffer[ring.tail];
+#endif
+
+ int is_match = 1;
+
+ // If we care about matching, do that comparison here
+ if (match_str != NULL) {
+ if (ignorelist_match(ignorelist, match_str) != 0)
+ is_match = 0;
+ else
+ DEBUG("sysevent plugin: regex filter match");
+ }
+
+#if HAVE_YAJL_V2
+ if (is_match == 1 && node != NULL) {
+ sysevent_dispatch_notification(NULL, &node, timestamp);
+ yajl_tree_free(node);
+ } else if (is_match == 1)
+ sysevent_dispatch_notification(ring.buffer[ring.tail], NULL, timestamp);
+#else
+ if (is_match == 1)
+ sysevent_dispatch_notification(ring.buffer[ring.tail], timestamp);
+#endif
+
+ ring.tail = next;
+ }
+
+ pthread_mutex_unlock(&sysevent_data_lock);
+}
+
+static void *sysevent_socket_thread(void *arg) /* {{{ */
+{
+ pthread_mutex_lock(&sysevent_thread_lock);
+
+ while (sysevent_socket_thread_loop > 0) {
+ pthread_mutex_unlock(&sysevent_thread_lock);
+
+ if (sock == -1)
+ return (void *)0;
+
+ int status = read_socket();
+
+ pthread_mutex_lock(&sysevent_thread_lock);
+
+ if (status < 0) {
+ WARNING("sysevent plugin: problem with socket thread (status: %d)",
+ status);
+ sysevent_socket_thread_error = 1;
+ break;
+ }
+ } /* while (sysevent_socket_thread_loop > 0) */
+
+ pthread_mutex_unlock(&sysevent_thread_lock);
+
+ return (void *)0;
+} /* }}} void *sysevent_socket_thread */
+
+// Entry point for thread responsible for reading from
+// ring buffer and dispatching notifications
+static void *sysevent_dequeue_thread(void *arg) /* {{{ */
+{
+ pthread_mutex_lock(&sysevent_thread_lock);
+
+ while (sysevent_dequeue_thread_loop > 0) {
+ pthread_mutex_unlock(&sysevent_thread_lock);
+
+ read_ring_buffer();
+
+ pthread_mutex_lock(&sysevent_thread_lock);
+ } /* while (sysevent_dequeue_thread_loop > 0) */
+
+ pthread_mutex_unlock(&sysevent_thread_lock);
+
+ return (void *)0;
+} /* }}} void *sysevent_dequeue_thread */
+
+static int start_socket_thread(void) /* {{{ */
+{
+ pthread_mutex_lock(&sysevent_thread_lock);
+
+ if (sysevent_socket_thread_loop != 0) {
+ pthread_mutex_unlock(&sysevent_thread_lock);
+ return 0;
+ }
+
+ sysevent_socket_thread_loop = 1;
+ sysevent_socket_thread_error = 0;
+
+ DEBUG("sysevent plugin: starting socket thread");
+
+ int status = plugin_thread_create(&sysevent_socket_thread_id,
+ /* attr = */ NULL, sysevent_socket_thread,
+ /* arg = */ (void *)0, "sysevent");
+ if (status != 0) {
+ sysevent_socket_thread_loop = 0;
+ ERROR("sysevent plugin: starting socket thread failed.");
+ pthread_mutex_unlock(&sysevent_thread_lock);
+ return -1;
+ }
+
+ pthread_mutex_unlock(&sysevent_thread_lock);
+
+ return 0;
+} /* }}} int start_socket_thread */
+
+static int start_dequeue_thread(void) /* {{{ */
+{
+ pthread_mutex_lock(&sysevent_thread_lock);
+
+ if (sysevent_dequeue_thread_loop != 0) {
+ pthread_mutex_unlock(&sysevent_thread_lock);
+ return 0;
+ }
+
+ sysevent_dequeue_thread_loop = 1;
+
+ int status = plugin_thread_create(&sysevent_dequeue_thread_id,
+ /* attr = */ NULL, sysevent_dequeue_thread,
+ /* arg = */ (void *)0, "ssyevent");
+ if (status != 0) {
+ sysevent_dequeue_thread_loop = 0;
+ ERROR("sysevent plugin: Starting dequeue thread failed.");
+ pthread_mutex_unlock(&sysevent_thread_lock);
+ return -1;
+ }
+
+ pthread_mutex_unlock(&sysevent_thread_lock);
+
+ return status;
+} /* }}} int start_dequeue_thread */
+
+static int start_threads(void) /* {{{ */
+{
+ int status = start_socket_thread();
+ int status2 = start_dequeue_thread();
+
+ if (status != 0)
+ return status;
+ else
+ return status2;
+} /* }}} int start_threads */
+
+static int stop_socket_thread(int shutdown) /* {{{ */
+{
+ pthread_mutex_lock(&sysevent_thread_lock);
+
+ if (sysevent_socket_thread_loop == 0) {
+ pthread_mutex_unlock(&sysevent_thread_lock);
+ return -1;
+ }
+
+ sysevent_socket_thread_loop = 0;
+ pthread_cond_broadcast(&sysevent_cond);
+ pthread_mutex_unlock(&sysevent_thread_lock);
+
+ int status;
+
+ if (shutdown == 1) {
+ // Since the thread is blocking, calling pthread_join
+ // doesn't actually succeed in stopping it. It will stick around
+ // until a message is received on the socket (at which
+ // it will realize that "sysevent_socket_thread_loop" is 0 and will
+ // break out of the read loop and be allowed to die). This is
+ // fine when the process isn't supposed to be exiting, but in
+ // the case of a process shutdown, we don't want to have an
+ // idle thread hanging around. Calling pthread_cancel here in
+ // the case of a shutdown is just assures that the thread is
+ // gone and that the process has been fully terminated.
+
+ DEBUG("sysevent plugin: Canceling socket thread for process shutdown");
+
+ status = pthread_cancel(sysevent_socket_thread_id);
+
+ if (status != 0 && status != ESRCH) {
+ ERROR("sysevent plugin: Unable to cancel socket thread: %d (%s)", status,
+ STRERRNO);
+ status = -1;
+ } else
+ status = 0;
+ } else {
+ status = pthread_join(sysevent_socket_thread_id, /* return = */ NULL);
+ if (status != 0 && status != ESRCH) {
+ ERROR("sysevent plugin: Stopping socket thread failed.");
+ status = -1;
+ } else
+ status = 0;
+ }
+
+ pthread_mutex_lock(&sysevent_thread_lock);
+ memset(&sysevent_socket_thread_id, 0, sizeof(sysevent_socket_thread_id));
+ sysevent_socket_thread_error = 0;
+ pthread_mutex_unlock(&sysevent_thread_lock);
+
+ DEBUG("sysevent plugin: Finished requesting stop of socket thread");
+
+ return status;
+} /* }}} int stop_socket_thread */
+
+static int stop_dequeue_thread() /* {{{ */
+{
+ pthread_mutex_lock(&sysevent_thread_lock);
+
+ if (sysevent_dequeue_thread_loop == 0) {
+ pthread_mutex_unlock(&sysevent_thread_lock);
+ return -1;
+ }
+
+ sysevent_dequeue_thread_loop = 0;
+ pthread_cond_broadcast(&sysevent_cond);
+ pthread_mutex_unlock(&sysevent_thread_lock);
+
+ // Since the thread is blocking, calling pthread_join
+ // doesn't actually succeed in stopping it. It will stick around
+ // until a message is received on the socket (at which
+ // it will realize that "sysevent_dequeue_thread_loop" is 0 and will
+ // break out of the read loop and be allowed to die). Since this
+ // function is called when the processing is exiting, we don't want to
+ // have an idle thread hanging around. Calling pthread_cancel here
+ // just assures that the thread is gone and that the process has been
+ // fully terminated.
+
+ DEBUG("sysevent plugin: Canceling dequeue thread for process shutdown");
+
+ int status = pthread_cancel(sysevent_dequeue_thread_id);
+
+ if (status != 0 && status != ESRCH) {
+ ERROR("sysevent plugin: Unable to cancel dequeue thread: %d (%s)", status,
+ STRERRNO);
+ status = -1;
+ } else
+ status = 0;
+
+ pthread_mutex_lock(&sysevent_thread_lock);
+ memset(&sysevent_dequeue_thread_id, 0, sizeof(sysevent_dequeue_thread_id));
+ pthread_mutex_unlock(&sysevent_thread_lock);
+
+ DEBUG("sysevent plugin: Finished requesting stop of dequeue thread");
+
+ return status;
+} /* }}} int stop_dequeue_thread */
+
+static int stop_threads() /* {{{ */
+{
+ int status = stop_socket_thread(1);
+ int status2 = stop_dequeue_thread();
+
+ if (status != 0)
+ return status;
+ else
+ return status2;
+} /* }}} int stop_threads */
+
+static int sysevent_init(void) /* {{{ */
+{
+ ring.head = 0;
+ ring.tail = 0;
+ ring.maxLen = buffer_length;
+ ring.buffer = (char **)calloc(buffer_length, sizeof(char *));
+
+ if (ring.buffer == NULL) {
+ ERROR("sysevent plugin: sysevent_init ring buffer calloc failed");
+ return -1;
+ }
+
+ for (int i = 0; i < buffer_length; i++) {
+ ring.buffer[i] = calloc(1, listen_buffer_size);
+
+ if (ring.buffer[i] == NULL) {
+ ERROR("sysevent plugin: sysevent_init ring buffer entry calloc failed");
+ return -1;
+ }
+ }
+
+ ring.timestamp = (cdtime_t *)calloc(buffer_length, sizeof(cdtime_t));
+
+ if (ring.timestamp == NULL) {
+ ERROR("sysevent plugin: sysevent_init ring buffer timestamp calloc failed");
+ return -1;
+ }
+
+ if (sock == -1) {
+ struct addrinfo hints = {
+ .ai_family = AF_UNSPEC,
+ .ai_socktype = SOCK_DGRAM,
+ .ai_protocol = 0,
+ .ai_flags = AI_PASSIVE | AI_ADDRCONFIG,
+ };
+ struct addrinfo *res = 0;
+
+ int err = getaddrinfo(listen_ip, listen_port, &hints, &res);
+
+ if (err != 0) {
+ ERROR("sysevent plugin: failed to resolve local socket address (err=%d)",
+ err);
+ freeaddrinfo(res);
+ return -1;
+ }
+
+ sock = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
+ if (sock == -1) {
+ ERROR("sysevent plugin: failed to open socket: %s", STRERRNO);
+ freeaddrinfo(res);
+ return -1;
+ }
+
+ if (bind(sock, res->ai_addr, res->ai_addrlen) == -1) {
+ ERROR("sysevent plugin: failed to bind socket: %s", STRERRNO);
+ freeaddrinfo(res);
+ sock = -1;
+ return -1;
+ }
+
+ freeaddrinfo(res);
+ }
+
+ DEBUG("sysevent plugin: socket created and bound");
+
+ return start_threads();
+} /* }}} int sysevent_init */
+
+static int sysevent_config_add_listen(const oconfig_item_t *ci) /* {{{ */
+{
+ if (ci->values_num != 2 || ci->values[0].type != OCONFIG_TYPE_STRING ||
+ ci->values[1].type != OCONFIG_TYPE_STRING) {
+ ERROR("sysevent plugin: The `%s' config option needs "
+ "two string arguments (ip and port).",
+ ci->key);
+ return -1;
+ }
+
+ listen_ip = strdup(ci->values[0].value.string);
+ listen_port = strdup(ci->values[1].value.string);
+
+ return 0;
+}
+
+static int sysevent_config_add_buffer_size(const oconfig_item_t *ci) /* {{{ */
+{
+ int tmp = 0;
+
+ if (cf_util_get_int(ci, &tmp) != 0)
+ return -1;
+ else if ((tmp >= 1024) && (tmp <= 65535))
+ listen_buffer_size = tmp;
+ else {
+ WARNING(
+ "sysevent plugin: The `BufferSize' must be between 1024 and 65535.");
+ return -1;
+ }
+
+ return 0;
+}
+
+static int sysevent_config_add_buffer_length(const oconfig_item_t *ci) /* {{{ */
+{
+ int tmp = 0;
+
+ if (cf_util_get_int(ci, &tmp) != 0)
+ return -1;
+ else if ((tmp >= 3) && (tmp <= 4096))
+ buffer_length = tmp;
+ else {
+ WARNING("sysevent plugin: The `Bufferlength' must be between 3 and 4096.");
+ return -1;
+ }
+
+ return 0;
+}
+
+static int sysevent_config_add_regex_filter(const oconfig_item_t *ci) /* {{{ */
+{
+ if (ci->values_num != 1 || ci->values[0].type != OCONFIG_TYPE_STRING) {
+ ERROR("sysevent plugin: The `%s' config option needs "
+ "one string argument, a regular expression.",
+ ci->key);
+ return -1;
+ }
+
+#if HAVE_REGEX_H
+ if (ignorelist == NULL)
+ ignorelist = ignorelist_create(/* invert = */ 1);
+
+ int status = ignorelist_add(ignorelist, ci->values[0].value.string);
+
+ if (status != 0) {
+ ERROR("sysevent plugin: invalid regular expression: %s",
+ ci->values[0].value.string);
+ return 1;
+ }
+
+ monitor_all_messages = 0;
+#else
+ WARNING("sysevent plugin: The plugin has been compiled without support "
+ "for the \"RegexFilter\" option.");
+#endif
+
+ return 0;
+}
+
+static int sysevent_config(oconfig_item_t *ci) /* {{{ */
+{
+ for (int i = 0; i < ci->children_num; i++) {
+ oconfig_item_t *child = ci->children + i;
+
+ if (strcasecmp("Listen", child->key) == 0)
+ sysevent_config_add_listen(child);
+ else if (strcasecmp("BufferSize", child->key) == 0)
+ sysevent_config_add_buffer_size(child);
+ else if (strcasecmp("BufferLength", child->key) == 0)
+ sysevent_config_add_buffer_length(child);
+ else if (strcasecmp("RegexFilter", child->key) == 0)
+ sysevent_config_add_regex_filter(child);
+ else {
+ WARNING("sysevent plugin: Option `%s' is not allowed here.", child->key);
+ }
+ }
+
+ return 0;
+} /* }}} int sysevent_config */
+
+static int sysevent_read(void) /* {{{ */
+{
+ pthread_mutex_lock(&sysevent_thread_lock);
+
+ if (sysevent_socket_thread_error != 0) {
+ pthread_mutex_unlock(&sysevent_thread_lock);
+
+ ERROR("sysevent plugin: The sysevent socket thread had a problem (%d). "
+ "Restarting it.",
+ sysevent_socket_thread_error);
+
+ stop_threads();
+
+ start_threads();
+
+ return -1;
+ } /* if (sysevent_socket_thread_error != 0) */
+
+ pthread_mutex_unlock(&sysevent_thread_lock);
+
+ return 0;
+} /* }}} int sysevent_read */
+
+static int sysevent_shutdown(void) /* {{{ */
+{
+ DEBUG("sysevent plugin: Shutting down thread.");
+
+ int status = stop_threads();
+ int status2 = 0;
+
+ if (sock != -1) {
+ status2 = close(sock);
+ if (status2 != 0) {
+ ERROR("sysevent plugin: failed to close socket %d: %d (%s)", sock, status,
+ STRERRNO);
+ }
+
+ sock = -1;
+ }
+
+ free(listen_ip);
+ free(listen_port);
+
+ for (int i = 0; i < buffer_length; i++) {
+ free(ring.buffer[i]);
+ }
+
+ free(ring.buffer);
+ free(ring.timestamp);
+
+ if (status != 0)
+ return status;
+ else
+ return status2;
+} /* }}} int sysevent_shutdown */
+
+void module_register(void) {
+ plugin_register_complex_config("sysevent", sysevent_config);
+ plugin_register_init("sysevent", sysevent_init);
+ plugin_register_read("sysevent", sysevent_read);
+ plugin_register_shutdown("sysevent", sysevent_shutdown);
+} /* void module_register */
static int notif_severity;
static const char *config_keys[] = {
- "LogLevel", "NotifyLevel",
+ "LogLevel",
+ "NotifyLevel",
};
static int config_keys_num = STATIC_ARRAY_SIZE(config_keys);
log_level = parse_log_severity(value);
if (log_level < 0) {
log_level = LOG_INFO;
- ERROR("syslog: invalid loglevel [%s] defaulting to 'info'", value);
- return 1;
+ WARNING("syslog: invalid loglevel [%s] defaulting to 'info'", value);
}
} else if (strcasecmp(key, "NotifyLevel") == 0) {
notif_severity = parse_notif_severity(value);
- if (notif_severity < 0)
+ if (notif_severity < 0) {
+ ERROR("syslog: invalid notification severity [%s]", value);
return 1;
+ }
}
return 0;
status = plugin_register_complex_read(
NULL, cb_name, tcsv_read, interval,
&(user_data_t){
- .data = id, .free_func = tcsv_instance_definition_destroy,
+ .data = id,
+ .free_func = tcsv_instance_definition_destroy,
});
if (status != 0) {
ERROR("tail_csv plugin: Registering complex read function failed.");
derive_t read, derive_t write) {
value_list_t vl = VALUE_LIST_INIT;
value_t values[] = {
- {.derive = read}, {.derive = write},
+ {.derive = read},
+ {.derive = write},
};
vl.values = values;
#if TCP_STATE_MIN > 0
|| (state < TCP_STATE_MIN)
#endif
- ) {
+ ) {
NOTICE("tcpconns plugin: Ignoring connection with "
"unknown state 0x%02" PRIx8 ".",
state);
return 0;
} /* int conn_read_file */
-/* #endif KERNEL_LINUX */
+ /* #endif KERNEL_LINUX */
#elif HAVE_SYSCTLBYNAME
-/* #endif HAVE_SYSCTLBYNAME */
+ /* #endif HAVE_SYSCTLBYNAME */
#elif HAVE_LIBKVM_NLIST
#endif /* HAVE_LIBKVM_NLIST */
return 0;
} /* int conn_read */
-/* #endif KERNEL_LINUX */
+ /* #endif KERNEL_LINUX */
#elif HAVE_SYSCTLBYNAME
static int conn_read(void) {
return 0;
}
-/* int conn_read */
-/* #endif HAVE_KVM_GETFILES */
+ /* int conn_read */
+ /* #endif HAVE_KVM_GETFILES */
#elif HAVE_LIBKVM_NLIST
static int kread(u_long addr, void *buf, int size) {
return 0;
}
-/* #endif HAVE_LIBKVM_NLIST */
+ /* #endif HAVE_LIBKVM_NLIST */
#elif KERNEL_AIX
*/
value_list_t vl = VALUE_LIST_INIT;
value_t values[] = {
- {.derive = rx}, {.derive = tx},
+ {.derive = rx},
+ {.derive = tx},
};
vl.values = values;
tmp = atoi(value);
if (tmp < 0) {
- WARNING("ted plugin: Invalid retry count: %i", tmp);
+ ERROR("ted plugin: Invalid retry count: %i", tmp);
return 1;
}
conf_retries = tmp;
if ((len < 0) || ((size_t)len >= sizeof(filename)))
return -1;
- len = (ssize_t)read_file_contents(filename, data, sizeof(data));
+ len = (ssize_t)read_text_file_contents(filename, data, sizeof(data));
if ((len > 0) && ((size_t)len > sizeof(str_temp)) && (data[--len] == '\n') &&
(!strncmp(data, str_temp, sizeof(str_temp) - 1))) {
char *endptr = NULL;
n.time = vl->time;
- status = snprintf(buf, bufsize, "Host %s, plugin %s", vl->host, vl->plugin);
+ status = ssnprintf(buf, bufsize, "Host %s, plugin %s", vl->host, vl->plugin);
buf += status;
bufsize -= status;
if (vl->plugin_instance[0] != '\0') {
- status = snprintf(buf, bufsize, " (instance %s)", vl->plugin_instance);
+ status = ssnprintf(buf, bufsize, " (instance %s)", vl->plugin_instance);
buf += status;
bufsize -= status;
}
- status = snprintf(buf, bufsize, " type %s", vl->type);
+ status = ssnprintf(buf, bufsize, " type %s", vl->type);
buf += status;
bufsize -= status;
if (vl->type_instance[0] != '\0') {
- status = snprintf(buf, bufsize, " (instance %s)", vl->type_instance);
+ status = ssnprintf(buf, bufsize, " (instance %s)", vl->type_instance);
buf += status;
bufsize -= status;
}
/* Send an okay notification */
if (state == STATE_OKAY) {
if (state_old == STATE_MISSING)
- snprintf(buf, bufsize, ": Value is no longer missing.");
+ ssnprintf(buf, bufsize, ": Value is no longer missing.");
else
- snprintf(buf, bufsize, ": All data sources are within range again. "
- "Current value of \"%s\" is %f.",
- ds->ds[ds_index].name, values[ds_index]);
+ ssnprintf(buf, bufsize,
+ ": All data sources are within range again. "
+ "Current value of \"%s\" is %f.",
+ ds->ds[ds_index].name, values[ds_index]);
} else if (state == STATE_UNKNOWN) {
ERROR("ut_report_state: metric transition to UNKNOWN from a different "
"state. This shouldn't happen.");
if (th->flags & UT_FLAG_INVERT) {
if (!isnan(min) && !isnan(max)) {
- snprintf(buf, bufsize,
- ": Data source \"%s\" is currently "
- "%f. That is within the %s region of %f%s and %f%s.",
- ds->ds[ds_index].name, values[ds_index],
- (state == STATE_ERROR) ? "failure" : "warning", min,
- ((th->flags & UT_FLAG_PERCENTAGE) != 0) ? "%" : "", max,
- ((th->flags & UT_FLAG_PERCENTAGE) != 0) ? "%" : "");
+ ssnprintf(buf, bufsize,
+ ": Data source \"%s\" is currently "
+ "%f. That is within the %s region of %f%s and %f%s.",
+ ds->ds[ds_index].name, values[ds_index],
+ (state == STATE_ERROR) ? "failure" : "warning", min,
+ ((th->flags & UT_FLAG_PERCENTAGE) != 0) ? "%" : "", max,
+ ((th->flags & UT_FLAG_PERCENTAGE) != 0) ? "%" : "");
} else {
- snprintf(buf, bufsize, ": Data source \"%s\" is currently "
- "%f. That is %s the %s threshold of %f%s.",
- ds->ds[ds_index].name, values[ds_index],
- isnan(min) ? "below" : "above",
- (state == STATE_ERROR) ? "failure" : "warning",
- isnan(min) ? max : min,
- ((th->flags & UT_FLAG_PERCENTAGE) != 0) ? "%" : "");
+ ssnprintf(buf, bufsize,
+ ": Data source \"%s\" is currently "
+ "%f. That is %s the %s threshold of %f%s.",
+ ds->ds[ds_index].name, values[ds_index],
+ isnan(min) ? "below" : "above",
+ (state == STATE_ERROR) ? "failure" : "warning",
+ isnan(min) ? max : min,
+ ((th->flags & UT_FLAG_PERCENTAGE) != 0) ? "%" : "");
}
} else if (th->flags & UT_FLAG_PERCENTAGE) {
gauge_t value;
else
value = 100.0 * values[ds_index] / sum;
- snprintf(buf, bufsize,
- ": Data source \"%s\" is currently "
- "%g (%.2f%%). That is %s the %s threshold of %.2f%%.",
- ds->ds[ds_index].name, values[ds_index], value,
- (value < min) ? "below" : "above",
- (state == STATE_ERROR) ? "failure" : "warning",
- (value < min) ? min : max);
+ ssnprintf(buf, bufsize,
+ ": Data source \"%s\" is currently "
+ "%g (%.2f%%). That is %s the %s threshold of %.2f%%.",
+ ds->ds[ds_index].name, values[ds_index], value,
+ (value < min) ? "below" : "above",
+ (state == STATE_ERROR) ? "failure" : "warning",
+ (value < min) ? min : max);
} else /* is not inverted */
{
- snprintf(buf, bufsize, ": Data source \"%s\" is currently "
- "%f. That is %s the %s threshold of %f.",
- ds->ds[ds_index].name, values[ds_index],
- (values[ds_index] < min) ? "below" : "above",
- (state == STATE_ERROR) ? "failure" : "warning",
- (values[ds_index] < min) ? min : max);
+ ssnprintf(buf, bufsize,
+ ": Data source \"%s\" is currently "
+ "%f. That is %s the %s threshold of %f.",
+ ds->ds[ds_index].name, values[ds_index],
+ (values[ds_index] < min) ? "below" : "above",
+ (state == STATE_ERROR) ? "failure" : "warning",
+ (values[ds_index] < min) ? min : max);
}
}
FORMAT_VL(identifier, sizeof(identifier), vl);
NOTIFICATION_INIT_VL(&n, vl);
- snprintf(n.message, sizeof(n.message),
- "%s has not been updated for %.3f seconds.", identifier,
- CDTIME_T_TO_DOUBLE(missing_time));
+ ssnprintf(n.message, sizeof(n.message),
+ "%s has not been updated for %.3f seconds.", identifier,
+ CDTIME_T_TO_DOUBLE(missing_time));
n.time = now;
plugin_dispatch_notification(&n);
/* Ivy Bridge */
case 0x3A: /* IVB */
case 0x3E: /* IVB Xeon */
+ case 0x55: /* SKX,CLX Xeon */
+ case 0x6A: /* ICX Xeon */
do_smi = true;
do_core_cstate = (1 << 3) | (1 << 6) | (1 << 7);
do_pkg_cstate = (1 << 2) | (1 << 3) | (1 << 6) | (1 << 7);
break;
case 0x2D: /* SNB Xeon */
case 0x3E: /* IVB Xeon */
+ case 0x55: /* SKX,CLX Xeon */
+ case 0x6A: /* ICX Xeon */
do_rapl = RAPL_PKG | RAPL_CORES | RAPL_DRAM;
do_power_fields = TURBO_PLATFORM | PSTATES_PLATFORM;
break;
parse_int_file(const char *fmt, ...) {
va_list args;
char path[PATH_MAX];
+ char buf[256];
int len;
+ value_t v;
+ char *c;
+ FILE *fp;
va_start(args, fmt);
len = vsnprintf(path, sizeof(path), fmt, args);
return -1;
}
- value_t v;
- if (parse_value_file(path, &v, DS_TYPE_DERIVE) != 0) {
+ fp = fopen(path, "r");
+ if (fp == NULL) {
+ ERROR("turbostat plugin: unable to open: '%s': %s", path, strerror(errno));
+ return -1;
+ }
+
+ if (fgets(buf, sizeof(buf), fp) == NULL) {
+ ERROR("turbostat plugin: unable to read: '%s': %s", path, strerror(errno));
+ fclose(fp);
+ return -1;
+ }
+ fclose(fp);
+
+ /* We only care about the first integer in the range */
+ c = strchr(buf, '-');
+ if (c != NULL)
+ *c = '\0';
+ c = strchr(buf, ',');
+ if (c != NULL)
+ *c = '\0';
+ strstripnewline(buf);
+
+ if (parse_value(buf, &v, DS_TYPE_DERIVE) != 0) {
ERROR("turbostat plugin: Parsing \"%s\" failed.", path);
return -1;
}
package_delta = NULL;
}
-/**********************
- * Collectd functions *
- **********************/
+ /**********************
+ * Collectd functions *
+ **********************/
#define DO_OR_GOTO_ERR(something) \
do { \
spl value:GAUGE:U:U
swap value:GAUGE:0:1099511627776
swap_io value:DERIVE:0:U
+sysevent value:GAUGE:0:1
tcp_connections value:GAUGE:0:4294967295
tdp value:GAUGE:U:U
temperature value:GAUGE:U:U
}
result = (time_t)info.uptime;
-/* #endif KERNEL_LINUX */
+ /* #endif KERNEL_LINUX */
#elif HAVE_LIBKSTAT
kstat_t *ksp;
}
result = time(NULL) - (time_t)knp->value.ui32;
-/* #endif HAVE_LIBKSTAT */
+ /* #endif HAVE_LIBKSTAT */
#elif HAVE_SYS_SYSCTL_H
struct timeval boottv = {0};
}
result = time(NULL) - boottv.tv_sec;
-/* #endif HAVE_SYS_SYSCTL_H */
+ /* #endif HAVE_SYS_SYSCTL_H */
#elif HAVE_PERFSTAT
int status;
endutxent();
users_submit(users);
-/* #endif HAVE_GETUTXENT */
+ /* #endif HAVE_GETUTXENT */
#elif HAVE_GETUTENT
unsigned int users = 0;
endutent();
users_submit(users);
-/* #endif HAVE_GETUTENT */
+ /* #endif HAVE_GETUTENT */
#elif HAVE_LIBSTATGRAB
sg_user_stats *us;
#else
us->num_entries);
#endif
-/* #endif HAVE_LIBSTATGRAB */
+ /* #endif HAVE_LIBSTATGRAB */
#else
#error "No applicable input method."
* Sebastian 'tokkee' Harl <sh at tokkee.org>
**/
+// clang-format off
+/*
+ * Explicit order is required or _FILE_OFFSET_BITS will have definition mismatches on Solaris
+ * See Github Issue #3193 for details
+ */
+#include "utils/common/common.h"
#include "testing.h"
#include "utils/cmds/cmds.h"
-#include "utils/common/common.h"
+// clang-format on
static void error_cb(void *ud, cmd_status_t status, const char *format,
va_list ap) {
} parse_data[] = {
/* Valid FLUSH commands. */
{
- "FLUSH", NULL, CMD_OK, CMD_FLUSH,
+ "FLUSH",
+ NULL,
+ CMD_OK,
+ CMD_FLUSH,
},
{
- "FLUSH identifier=myhost/magic/MAGIC", NULL, CMD_OK, CMD_FLUSH,
+ "FLUSH identifier=myhost/magic/MAGIC",
+ NULL,
+ CMD_OK,
+ CMD_FLUSH,
},
{
- "FLUSH identifier=magic/MAGIC", &default_host_opts, CMD_OK, CMD_FLUSH,
+ "FLUSH identifier=magic/MAGIC",
+ &default_host_opts,
+ CMD_OK,
+ CMD_FLUSH,
},
{
- "FLUSH timeout=123 plugin=\"A\"", NULL, CMD_OK, CMD_FLUSH,
+ "FLUSH timeout=123 plugin=\"A\"",
+ NULL,
+ CMD_OK,
+ CMD_FLUSH,
},
/* Invalid FLUSH commands. */
{
/* Missing hostname; no default. */
- "FLUSH identifier=magic/MAGIC", NULL, CMD_PARSE_ERROR, CMD_UNKNOWN,
+ "FLUSH identifier=magic/MAGIC",
+ NULL,
+ CMD_PARSE_ERROR,
+ CMD_UNKNOWN,
},
{
/* Missing 'identifier' key. */
- "FLUSH myhost/magic/MAGIC", NULL, CMD_PARSE_ERROR, CMD_UNKNOWN,
+ "FLUSH myhost/magic/MAGIC",
+ NULL,
+ CMD_PARSE_ERROR,
+ CMD_UNKNOWN,
},
{
/* Invalid timeout. */
- "FLUSH timeout=A", NULL, CMD_PARSE_ERROR, CMD_UNKNOWN,
+ "FLUSH timeout=A",
+ NULL,
+ CMD_PARSE_ERROR,
+ CMD_UNKNOWN,
},
{
/* Invalid identifier. */
- "FLUSH identifier=invalid", NULL, CMD_PARSE_ERROR, CMD_UNKNOWN,
+ "FLUSH identifier=invalid",
+ NULL,
+ CMD_PARSE_ERROR,
+ CMD_UNKNOWN,
},
{
/* Invalid option. */
- "FLUSH invalid=option", NULL, CMD_PARSE_ERROR, CMD_UNKNOWN,
+ "FLUSH invalid=option",
+ NULL,
+ CMD_PARSE_ERROR,
+ CMD_UNKNOWN,
},
/* Valid GETVAL commands. */
{
- "GETVAL myhost/magic/MAGIC", NULL, CMD_OK, CMD_GETVAL,
+ "GETVAL myhost/magic/MAGIC",
+ NULL,
+ CMD_OK,
+ CMD_GETVAL,
},
{
- "GETVAL magic/MAGIC", &default_host_opts, CMD_OK, CMD_GETVAL,
+ "GETVAL magic/MAGIC",
+ &default_host_opts,
+ CMD_OK,
+ CMD_GETVAL,
},
/* Invalid GETVAL commands. */
{
- "GETVAL magic/MAGIC", NULL, CMD_PARSE_ERROR, CMD_UNKNOWN,
+ "GETVAL magic/MAGIC",
+ NULL,
+ CMD_PARSE_ERROR,
+ CMD_UNKNOWN,
},
{
- "GETVAL", NULL, CMD_PARSE_ERROR, CMD_UNKNOWN,
+ "GETVAL",
+ NULL,
+ CMD_PARSE_ERROR,
+ CMD_UNKNOWN,
},
{
- "GETVAL invalid", NULL, CMD_PARSE_ERROR, CMD_UNKNOWN,
+ "GETVAL invalid",
+ NULL,
+ CMD_PARSE_ERROR,
+ CMD_UNKNOWN,
},
/* Valid LISTVAL commands. */
{
- "LISTVAL", NULL, CMD_OK, CMD_LISTVAL,
+ "LISTVAL",
+ NULL,
+ CMD_OK,
+ CMD_LISTVAL,
},
/* Invalid LISTVAL commands. */
{
- "LISTVAL invalid", NULL, CMD_PARSE_ERROR, CMD_UNKNOWN,
+ "LISTVAL invalid",
+ NULL,
+ CMD_PARSE_ERROR,
+ CMD_UNKNOWN,
},
/* Valid PUTVAL commands. */
{
- "PUTVAL magic/MAGIC N:42", &default_host_opts, CMD_OK, CMD_PUTVAL,
+ "PUTVAL magic/MAGIC N:42",
+ &default_host_opts,
+ CMD_OK,
+ CMD_PUTVAL,
},
{
- "PUTVAL myhost/magic/MAGIC N:42", NULL, CMD_OK, CMD_PUTVAL,
+ "PUTVAL myhost/magic/MAGIC N:42",
+ NULL,
+ CMD_OK,
+ CMD_PUTVAL,
},
{
- "PUTVAL myhost/magic/MAGIC 1234:42", NULL, CMD_OK, CMD_PUTVAL,
+ "PUTVAL myhost/magic/MAGIC 1234:42",
+ NULL,
+ CMD_OK,
+ CMD_PUTVAL,
},
{
- "PUTVAL myhost/magic/MAGIC 1234:42 2345:23", NULL, CMD_OK, CMD_PUTVAL,
+ "PUTVAL myhost/magic/MAGIC 1234:42 2345:23",
+ NULL,
+ CMD_OK,
+ CMD_PUTVAL,
},
{
- "PUTVAL myhost/magic/MAGIC interval=2 1234:42", NULL, CMD_OK,
+ "PUTVAL myhost/magic/MAGIC interval=2 1234:42",
+ NULL,
+ CMD_OK,
CMD_PUTVAL,
},
{
- "PUTVAL myhost/magic/MAGIC interval=2 1234:42 interval=5 2345:23", NULL,
- CMD_OK, CMD_PUTVAL,
+ "PUTVAL myhost/magic/MAGIC interval=2 1234:42 interval=5 2345:23",
+ NULL,
+ CMD_OK,
+ CMD_PUTVAL,
},
/* Invalid PUTVAL commands. */
{
- "PUTVAL magic/MAGIC N:42", NULL, CMD_PARSE_ERROR, CMD_UNKNOWN,
+ "PUTVAL magic/MAGIC N:42",
+ NULL,
+ CMD_PARSE_ERROR,
+ CMD_UNKNOWN,
},
{
- "PUTVAL", NULL, CMD_PARSE_ERROR, CMD_UNKNOWN,
+ "PUTVAL",
+ NULL,
+ CMD_PARSE_ERROR,
+ CMD_UNKNOWN,
},
{
- "PUTVAL invalid N:42", NULL, CMD_PARSE_ERROR, CMD_UNKNOWN,
+ "PUTVAL invalid N:42",
+ NULL,
+ CMD_PARSE_ERROR,
+ CMD_UNKNOWN,
},
{
- "PUTVAL myhost/magic/MAGIC A:42", NULL, CMD_PARSE_ERROR, CMD_UNKNOWN,
+ "PUTVAL myhost/magic/MAGIC A:42",
+ NULL,
+ CMD_PARSE_ERROR,
+ CMD_UNKNOWN,
},
{
- "PUTVAL myhost/magic/MAGIC 1234:A", NULL, CMD_PARSE_ERROR, CMD_UNKNOWN,
+ "PUTVAL myhost/magic/MAGIC 1234:A",
+ NULL,
+ CMD_PARSE_ERROR,
+ CMD_UNKNOWN,
},
{
- "PUTVAL myhost/magic/MAGIC", NULL, CMD_PARSE_ERROR, CMD_UNKNOWN,
+ "PUTVAL myhost/magic/MAGIC",
+ NULL,
+ CMD_PARSE_ERROR,
+ CMD_UNKNOWN,
},
{
- "PUTVAL 1234:A", NULL, CMD_PARSE_ERROR, CMD_UNKNOWN,
+ "PUTVAL 1234:A",
+ NULL,
+ CMD_PARSE_ERROR,
+ CMD_UNKNOWN,
},
{
- "PUTVAL myhost/magic/UNKNOWN 1234:42", NULL, CMD_PARSE_ERROR,
+ "PUTVAL myhost/magic/UNKNOWN 1234:42",
+ NULL,
+ CMD_PARSE_ERROR,
CMD_UNKNOWN,
},
/*
/* Invalid commands. */
{
- "INVALID", NULL, CMD_UNKNOWN_COMMAND, CMD_UNKNOWN,
+ "INVALID",
+ NULL,
+ CMD_UNKNOWN_COMMAND,
+ CMD_UNKNOWN,
},
{
- "INVALID interval=2", NULL, CMD_UNKNOWN_COMMAND, CMD_UNKNOWN,
+ "INVALID interval=2",
+ NULL,
+ CMD_UNKNOWN_COMMAND,
+ CMD_UNKNOWN,
},
};
memset(&cmd, 0, sizeof(cmd));
status = cmd_parse(input, &cmd, parse_data[i].opts, &err);
- snprintf(description, sizeof(description), "cmd_parse (\"%s\", opts=%p) = "
- "%d (type=%d [%s]); want %d "
- "(type=%d [%s])",
- parse_data[i].input, parse_data[i].opts, status, cmd.type,
- CMD_TO_STRING(cmd.type), parse_data[i].expected_status,
- parse_data[i].expected_type,
- CMD_TO_STRING(parse_data[i].expected_type));
+ ssnprintf(description, sizeof(description),
+ "cmd_parse (\"%s\", opts=%p) = "
+ "%d (type=%d [%s]); want %d "
+ "(type=%d [%s])",
+ parse_data[i].input, parse_data[i].opts, status, cmd.type,
+ CMD_TO_STRING(cmd.type), parse_data[i].expected_status,
+ parse_data[i].expected_type,
+ CMD_TO_STRING(parse_data[i].expected_type));
result = (status == parse_data[i].expected_status) &&
(cmd.type == parse_data[i].expected_type);
LOG(result, description);
* Niki W. Waibel <niki.waibel@gmx.net>
* Sebastian Harl <sh at tokkee.org>
* Michał Mirosław <mirq-linux at rere.qmqm.pl>
-**/
+ **/
#include "collectd.h"
return dest;
} /* char *sstrncpy */
+/* ssnprintf returns result from vsnprintf conistent with snprintf */
+int ssnprintf(char *str, size_t sz, const char *format, ...) {
+ va_list ap;
+ va_start(ap, format);
+
+ int ret = vsnprintf(str, sz, format, ap);
+
+ va_end(ap);
+
+ return ret;
+} /* int ssnprintf */
+
char *ssnprintf_alloc(char const *format, ...) /* {{{ */
{
char static_buffer[1024] = "";
pthread_mutex_unlock(&strerror_r_lock);
}
-/* #endif !HAVE_STRERROR_R */
+ /* #endif !HAVE_STRERROR_R */
#elif STRERROR_R_CHAR_P
{
if ((temp != NULL) && (temp != buf) && (temp[0] != '\0'))
sstrncpy(buf, temp, buflen);
else
- sstrncpy(buf, "strerror_r did not return "
- "an error message",
+ sstrncpy(buf,
+ "strerror_r did not return "
+ "an error message",
buflen);
}
}
-/* #endif STRERROR_R_CHAR_P */
+ /* #endif STRERROR_R_CHAR_P */
#else
if (strerror_r(errnum, buf, buflen) != 0) {
- snprintf(buf, buflen, "Error #%i; "
- "Additionally, strerror_r failed.",
+ snprintf(buf, buflen,
+ "Error #%i; "
+ "Additionally, strerror_r failed.",
errnum);
}
#endif /* STRERROR_R_CHAR_P */
else if (kn->data_type == KSTAT_DATA_UINT32)
retval = (long long)kn->value.ui32;
else if (kn->data_type == KSTAT_DATA_INT64)
- retval =
- (long long)kn->value.i64; /* According to ANSI C99 `long long' must hold
- at least 64 bits */
+ retval = (long long)kn->value.i64; /* According to ANSI C99 `long long' must
+ hold at least 64 bits */
else if (kn->data_type == KSTAT_DATA_UINT64)
retval = (long long)kn->value.ui64; /* XXX: Might overflow! */
else
#endif /* HAVE_HTONLL */
#if FP_LAYOUT_NEED_NOTHING
-/* Well, we need nothing.. */
-/* #endif FP_LAYOUT_NEED_NOTHING */
+ /* Well, we need nothing.. */
+ /* #endif FP_LAYOUT_NEED_NOTHING */
#elif FP_LAYOUT_NEED_ENDIANFLIP || FP_LAYOUT_NEED_INTSWAP
#if FP_LAYOUT_NEED_ENDIANFLIP
return 0;
}
-ssize_t read_file_contents(const char *filename, char *buf, size_t bufsize) {
+ssize_t read_file_contents(const char *filename, void *buf, size_t bufsize) {
FILE *fh;
ssize_t ret;
return ret;
}
+ssize_t read_text_file_contents(const char *filename, char *buf,
+ size_t bufsize) {
+ ssize_t ret = read_file_contents(filename, buf, bufsize - 1);
+ if (ret < 0)
+ return ret;
+
+ buf[ret] = '\0';
+ return ret + 1;
+}
+
counter_t counter_diff(counter_t old_value, counter_t new_value) {
counter_t diff;
service_number = (int)ntohs(sa->sin6_port);
}
- if ((service_number > 0) && (service_number <= 65535))
+ if (service_number > 0)
break;
}
freeaddrinfo(ai_list);
- if ((service_number > 0) && (service_number <= 65535))
+ if (service_number > 0)
return service_number;
return -1;
} /* int service_name_to_port_number */
* Authors:
* Florian octo Forster <octo at collectd.org>
* Niki W. Waibel <niki.waibel@gmx.net>
-**/
+ **/
#ifndef COMMON_H
#define COMMON_H
char *sstrncpy(char *dest, const char *src, size_t n);
+__attribute__((format(printf, 3, 4))) int ssnprintf(char *str, size_t size,
+ char const *format, ...);
+
__attribute__((format(printf, 1, 2))) char *ssnprintf_alloc(char const *format,
...);
int walk_directory(const char *dir, dirwalk_callback_f callback,
void *user_data, int hidden);
/* Returns the number of bytes read or negative on error. */
-ssize_t read_file_contents(char const *filename, char *buf, size_t bufsize);
+ssize_t read_file_contents(char const *filename, void *buf, size_t bufsize);
+/* Writes the contents of the file into the buffer with a trailing NUL.
+ * Returns the number of bytes written to the buffer or negative on error. */
+ssize_t read_text_file_contents(char const *filename, char *buf,
+ size_t bufsize);
counter_t counter_diff(counter_t old_value, counter_t new_value);
* Florian octo Forster <octo at collectd.org>
*/
-#include "testing.h"
+// clang-format off
+/*
+ * Explicit order is required or _FILE_OFFSET_BITS will have definition mismatches on Solaris
+ * See Github Issue #3193 for details
+ */
#include "utils/common/common.h"
+#include "testing.h"
+// clang-format on
#if HAVE_KSTAT_H
#include <kstat.h>
};
for (size_t i = 0; i < STATIC_ARRAY_SIZE(cases); i++) {
- char buffer[32];
+ char buffer[32] = {0};
- strncpy(buffer, cases[i].str, sizeof(buffer));
+ strncpy(buffer, cases[i].str, sizeof(buffer) - 1);
OK(escape_slashes(buffer, sizeof(buffer)) == 0);
EXPECT_EQ_STR(cases[i].want, buffer);
}
};
for (size_t i = 0; i < STATIC_ARRAY_SIZE(cases); i++) {
- char buffer[16];
+ char buffer[16] = {0};
- strncpy(buffer, cases[i].str, sizeof(buffer));
+ strncpy(buffer, cases[i].str, sizeof(buffer) - 1);
OK(escape_string(buffer, sizeof(buffer)) == 0);
EXPECT_EQ_STR(cases[i].want, buffer);
}
}
DEF_TEST(strunescape) {
- char buffer[16];
+ char buffer[32] = {0};
int status;
- strncpy(buffer, "foo\\tbar", sizeof(buffer));
+ strncpy(buffer, "foo\\tbar", sizeof(buffer) - 1);
status = strunescape(buffer, sizeof(buffer));
OK(status == 0);
EXPECT_EQ_STR("foo\tbar", buffer);
- strncpy(buffer, "\\tfoo\\r\\n", sizeof(buffer));
+ strncpy(buffer, "\\tfoo\\r\\n", sizeof(buffer) - 1);
status = strunescape(buffer, sizeof(buffer));
OK(status == 0);
EXPECT_EQ_STR("\tfoo\r\n", buffer);
- strncpy(buffer, "With \\\"quotes\\\"", sizeof(buffer));
+ strncpy(buffer, "With \\\"quotes\\\"", sizeof(buffer) - 1);
status = strunescape(buffer, sizeof(buffer));
OK(status == 0);
EXPECT_EQ_STR("With \"quotes\"", buffer);
/* Backslash before null byte */
- strncpy(buffer, "\\tbackslash end\\", sizeof(buffer));
+ strncpy(buffer, "\\tbackslash end\\", sizeof(buffer) - 1);
status = strunescape(buffer, sizeof(buffer));
OK(status != 0);
EXPECT_EQ_STR("\tbackslash end", buffer);
return 0;
/* Backslash at buffer end */
- strncpy(buffer, "\\t3\\56", sizeof(buffer));
+ strncpy(buffer, "\\t3\\56", sizeof(buffer) - 1);
status = strunescape(buffer, 4);
OK(status != 0);
OK(buffer[0] == '\t');
for (size_t i = 0; i < STATIC_ARRAY_SIZE(cases); i++) {
data_source_t dsrc = {
- .name = "value", .type = DS_TYPE_GAUGE, .min = 0.0, .max = NAN,
+ .name = "value",
+ .type = DS_TYPE_GAUGE,
+ .min = 0.0,
+ .max = NAN,
};
data_set_t ds = {
- .type = "example", .ds_num = 1, .ds = &dsrc,
+ .type = "example",
+ .ds_num = 1,
+ .ds = &dsrc,
};
value_t v = {
for (size_t i = 0; i < STATIC_ARRAY_SIZE(cases); i++) {
cdtime_t t0 = TIME_T_TO_CDTIME_T(cases[i].t0);
value_to_rate_state_t state = {
- .last_value = cases[i].v0, .last_time = t0,
+ .last_value = cases[i].v0,
+ .last_time = t0,
};
gauge_t got;
} else {
for (size_t j = 0; j < n && cg_idx < STATIC_ARRAY_SIZE(cgroups); j++) {
char desc[DATA_MAX_NAME_LEN];
- snprintf(desc, sizeof(desc), "%u", cores[j]);
+ ssnprintf(desc, sizeof(desc), "%u", cores[j]);
cgroups[cg_idx].desc = strdup(desc);
if (cgroups[cg_idx].desc == NULL) {
for (int i = 0; i < num_cores; i++) {
char desc[DATA_MAX_NAME_LEN];
- snprintf(desc, sizeof(desc), "%d", i);
+ ssnprintf(desc, sizeof(desc), "%d", i);
cgl->cgroups[i].cores = calloc(1, sizeof(*(cgl->cgroups[i].cores)));
if (cgl->cgroups[i].cores == NULL) {
}
tmp[sizeof(tmp) - 1] = '\0';
- snprintf(vl.type_instance, sizeof(vl.type_instance), "%s-%s",
- r->instance_prefix, tmp);
+ ssnprintf(vl.type_instance, sizeof(vl.type_instance), "%s-%s",
+ r->instance_prefix, tmp);
}
}
vl.type_instance[sizeof(vl.type_instance) - 1] = '\0';
#if HAVE_ARPA_INET_H
#include <arpa/inet.h>
#endif
-#if HAVE_ARPA_NAMESER_H
-#include <arpa/nameser.h>
-#endif
-#if HAVE_ARPA_NAMESER_COMPAT_H
-#include <arpa/nameser_compat.h>
-#endif
#if HAVE_NETDB_H
#include <netdb.h>
return 1; /* Success */
} /* int handle_ipv6 */
-/* #endif HAVE_IPV6 */
+ /* #endif HAVE_IPV6 */
#else /* if !HAVE_IPV6 */
static int handle_ipv6(__attribute__((unused)) void *pkg,
const char *qtype_str(int t) {
static char buf[32];
+ // clang-format off
+ /*
+ Built (with minor cleanup) from glibc-2.29 by
+ cat resolv/arpa/nameser.h | grep "ns_t_" | \
+ perl -ne '/ns_t_(\S+)\ =\ (\d+)/; print " case $2:\n return \"".uc($1)."\";\n";'
+ */
+ // clang-format on
switch (t) {
-#if (defined(__NAMESER)) && (__NAMESER >= 19991001)
- case ns_t_a:
+ case 1:
return "A";
- case ns_t_ns:
+ case 2:
return "NS";
- case ns_t_md:
+ case 3:
return "MD";
- case ns_t_mf:
+ case 4:
return "MF";
- case ns_t_cname:
+ case 5:
return "CNAME";
- case ns_t_soa:
+ case 6:
return "SOA";
- case ns_t_mb:
+ case 7:
return "MB";
- case ns_t_mg:
+ case 8:
return "MG";
- case ns_t_mr:
+ case 9:
return "MR";
- case ns_t_null:
+ case 10:
return "NULL";
- case ns_t_wks:
+ case 11:
return "WKS";
- case ns_t_ptr:
+ case 12:
return "PTR";
- case ns_t_hinfo:
+ case 13:
return "HINFO";
- case ns_t_minfo:
+ case 14:
return "MINFO";
- case ns_t_mx:
+ case 15:
return "MX";
- case ns_t_txt:
+ case 16:
return "TXT";
- case ns_t_rp:
+ case 17:
return "RP";
- case ns_t_afsdb:
+ case 18:
return "AFSDB";
- case ns_t_x25:
+ case 19:
return "X25";
- case ns_t_isdn:
+ case 20:
return "ISDN";
- case ns_t_rt:
+ case 21:
return "RT";
- case ns_t_nsap:
+ case 22:
return "NSAP";
- case ns_t_nsap_ptr:
+ case 23:
return "NSAP-PTR";
- case ns_t_sig:
+ case 24:
return "SIG";
- case ns_t_key:
+ case 25:
return "KEY";
- case ns_t_px:
+ case 26:
return "PX";
- case ns_t_gpos:
+ case 27:
return "GPOS";
- case ns_t_aaaa:
+ case 28:
return "AAAA";
- case ns_t_loc:
+ case 29:
return "LOC";
- case ns_t_nxt:
+ case 30:
return "NXT";
- case ns_t_eid:
+ case 31:
return "EID";
- case ns_t_nimloc:
+ case 32:
return "NIMLOC";
- case ns_t_srv:
+ case 33:
return "SRV";
- case ns_t_atma:
+ case 34:
return "ATMA";
- case ns_t_naptr:
+ case 35:
return "NAPTR";
- case ns_t_opt:
- return "OPT";
-#if __NAMESER >= 19991006
- case ns_t_kx:
+ case 36:
return "KX";
- case ns_t_cert:
+ case 37:
return "CERT";
- case ns_t_a6:
+ case 38:
return "A6";
- case ns_t_dname:
+ case 39:
return "DNAME";
- case ns_t_sink:
+ case 40:
return "SINK";
- case ns_t_tsig:
- return "TSIG";
-#endif
-#if __NAMESER >= 20090302
- case ns_t_apl:
+ case 41:
+ return "OPT";
+ case 42:
return "APL";
- case ns_t_ds:
+ case 43:
return "DS";
- case ns_t_sshfp:
+ case 44:
return "SSHFP";
- case ns_t_ipseckey:
+ case 45:
return "IPSECKEY";
- case ns_t_rrsig:
+ case 46:
return "RRSIG";
- case ns_t_nsec:
+ case 47:
return "NSEC";
- case ns_t_dnskey:
+ case 48:
return "DNSKEY";
- case ns_t_dhcid:
+ case 49:
return "DHCID";
- case ns_t_nsec3:
+ case 50:
return "NSEC3";
- case ns_t_nsec3param:
+ case 51:
return "NSEC3PARAM";
- case ns_t_hip:
+ case 52:
+ return "TLSA";
+ case 53:
+ return "SMIMEA";
+ case 55:
return "HIP";
- case ns_t_spf:
+ case 56:
+ return "NINFO";
+ case 57:
+ return "RKEY";
+ case 58:
+ return "TALINK";
+ case 59:
+ return "CDS";
+ case 60:
+ return "CDNSKEY";
+ case 61:
+ return "OPENPGPKEY";
+ case 62:
+ return "CSYNC";
+ case 99:
return "SPF";
- case ns_t_ixfr:
+ case 100:
+ return "UINFO";
+ case 101:
+ return "UID";
+ case 102:
+ return "GID";
+ case 103:
+ return "UNSPEC";
+ case 104:
+ return "NID";
+ case 105:
+ return "L32";
+ case 106:
+ return "L64";
+ case 107:
+ return "LP";
+ case 108:
+ return "EUI48";
+ case 109:
+ return "EUI64";
+ case 249:
+ return "TKEY";
+ case 250:
+ return "TSIG";
+ case 251:
return "IXFR";
-#endif
- case ns_t_axfr:
+ case 252:
return "AXFR";
- case ns_t_mailb:
+ case 253:
return "MAILB";
- case ns_t_maila:
+ case 254:
return "MAILA";
- case ns_t_any:
+ case 255:
return "ANY";
-#if __NAMESER >= 19991006
- case ns_t_zxfr:
- return "ZXFR";
-#endif
-#if __NAMESER >= 20090302
- case ns_t_dlv:
+ case 256:
+ return "URI";
+ case 257:
+ return "CAA";
+ case 258:
+ return "AVC";
+ case 32768:
+ return "TA";
+ case 32769:
return "DLV";
-#endif
-/* #endif __NAMESER >= 19991001 */
-#elif (defined(__BIND)) && (__BIND >= 19950621)
- case T_A:
- return "A"; /* 1 ... */
- case T_NS:
- return "NS";
- case T_MD:
- return "MD";
- case T_MF:
- return "MF";
- case T_CNAME:
- return "CNAME";
- case T_SOA:
- return "SOA";
- case T_MB:
- return "MB";
- case T_MG:
- return "MG";
- case T_MR:
- return "MR";
- case T_NULL:
- return "NULL";
- case T_WKS:
- return "WKS";
- case T_PTR:
- return "PTR";
- case T_HINFO:
- return "HINFO";
- case T_MINFO:
- return "MINFO";
- case T_MX:
- return "MX";
- case T_TXT:
- return "TXT";
- case T_RP:
- return "RP";
- case T_AFSDB:
- return "AFSDB";
- case T_X25:
- return "X25";
- case T_ISDN:
- return "ISDN";
- case T_RT:
- return "RT";
- case T_NSAP:
- return "NSAP";
- case T_NSAP_PTR:
- return "NSAP_PTR";
- case T_SIG:
- return "SIG";
- case T_KEY:
- return "KEY";
- case T_PX:
- return "PX";
- case T_GPOS:
- return "GPOS";
- case T_AAAA:
- return "AAAA";
- case T_LOC:
- return "LOC";
- case T_NXT:
- return "NXT";
- case T_EID:
- return "EID";
- case T_NIMLOC:
- return "NIMLOC";
- case T_SRV:
- return "SRV";
- case T_ATMA:
- return "ATMA";
- case T_NAPTR:
- return "NAPTR"; /* ... 35 */
-#if (__BIND >= 19960801)
- case T_KX:
- return "KX"; /* 36 ... */
- case T_CERT:
- return "CERT";
- case T_A6:
- return "A6";
- case T_DNAME:
- return "DNAME";
- case T_SINK:
- return "SINK";
- case T_OPT:
- return "OPT";
- case T_APL:
- return "APL";
- case T_DS:
- return "DS";
- case T_SSHFP:
- return "SSHFP";
- case T_RRSIG:
- return "RRSIG";
- case T_NSEC:
- return "NSEC";
- case T_DNSKEY:
- return "DNSKEY"; /* ... 48 */
- case T_TKEY:
- return "TKEY"; /* 249 */
-#endif /* __BIND >= 19960801 */
- case T_TSIG:
- return "TSIG"; /* 250 ... */
- case T_IXFR:
- return "IXFR";
- case T_AXFR:
- return "AXFR";
- case T_MAILB:
- return "MAILB";
- case T_MAILA:
- return "MAILA";
- case T_ANY:
- return "ANY"; /* ... 255 */
-#endif /* __BIND >= 19950621 */
default:
- snprintf(buf, sizeof(buf), "#%i", t);
+ ssnprintf(buf, sizeof(buf), "#%i", t);
return buf;
} /* switch (t) */
}
case 5:
return "Update";
default:
- snprintf(buf, sizeof(buf), "Opcode%d", o);
+ ssnprintf(buf, sizeof(buf), "Opcode%d", o);
return buf;
}
}
const char *rcode_str(int rcode) {
static char buf[32];
+ /* RFC2136 rcodes */
+ // clang-format off
+ /*
+ Built (with minor cleanup) from glibc-2.29 by
+ cat resolv/arpa/nameser.h | grep "ns_r_" | \
+ perl -ne '/ns_r_(\S+)\ =\ (\d+)/; print " case $2:\n return \"".uc($1)."\";\n";'
+
+ https://tools.ietf.org/html/rfc2671 assigns EDNS Extended RCODE "16" to "BADVERS"
+ https://tools.ietf.org/html/rfc2845 declares 0..15 as DNS RCODE and 16 is BADSIG.
+ */
+ // clang-format on
switch (rcode) {
-#if (defined(__NAMESER)) && (__NAMESER >= 19991006)
- case ns_r_noerror:
- return "NOERROR";
- case ns_r_formerr:
+ case 1:
return "FORMERR";
- case ns_r_servfail:
+ case 2:
return "SERVFAIL";
- case ns_r_nxdomain:
+ case 3:
return "NXDOMAIN";
- case ns_r_notimpl:
+ case 4:
return "NOTIMPL";
- case ns_r_refused:
+ case 5:
return "REFUSED";
- case ns_r_yxdomain:
+ case 6:
return "YXDOMAIN";
- case ns_r_yxrrset:
+ case 7:
return "YXRRSET";
- case ns_r_nxrrset:
+ case 8:
return "NXRRSET";
- case ns_r_notauth:
+ case 9:
return "NOTAUTH";
- case ns_r_notzone:
+ case 10:
return "NOTZONE";
- case ns_r_max:
+ case 11:
return "MAX";
- case ns_r_badsig:
+ case 16:
return "BADSIG";
- case ns_r_badkey:
+ case 17:
return "BADKEY";
- case ns_r_badtime:
+ case 18:
return "BADTIME";
-/* #endif __NAMESER >= 19991006 */
-#elif (defined(__BIND)) && (__BIND >= 19950621)
- case NOERROR:
- return "NOERROR";
- case FORMERR:
- return "FORMERR";
- case SERVFAIL:
- return "SERVFAIL";
- case NXDOMAIN:
- return "NXDOMAIN";
- case NOTIMP:
- return "NOTIMP";
- case REFUSED:
- return "REFUSED";
-#if defined(YXDOMAIN) && defined(NXRRSET)
- case YXDOMAIN:
- return "YXDOMAIN";
- case YXRRSET:
- return "YXRRSET";
- case NXRRSET:
- return "NXRRSET";
- case NOTAUTH:
- return "NOTAUTH";
- case NOTZONE:
- return "NOTZONE";
-#endif /* RFC2136 rcodes */
-#endif /* __BIND >= 19950621 */
default:
- snprintf(buf, sizeof(buf), "RCode%i", rcode);
+ ssnprintf(buf, sizeof(buf), "RCode%i", rcode);
return buf;
}
} /* const char *rcode_str (int rcode) */
#include "config.h"
-#include <arpa/nameser.h>
#include <stdint.h>
#if HAVE_PCAP_H
DPDK_HELPER_TRACE(phc->shm_name);
- snprintf(phc->eal_config.coremask, DATA_MAX_NAME_LEN, "%s", "0xf");
- snprintf(phc->eal_config.memory_channels, DATA_MAX_NAME_LEN, "%s", "1");
- snprintf(phc->eal_config.file_prefix, DATA_MAX_NAME_LEN, "%s",
- DPDK_DEFAULT_RTE_CONFIG);
+ ssnprintf(phc->eal_config.coremask, DATA_MAX_NAME_LEN, "%s", "0xf");
+ ssnprintf(phc->eal_config.memory_channels, DATA_MAX_NAME_LEN, "%s", "1");
+ ssnprintf(phc->eal_config.file_prefix, DATA_MAX_NAME_LEN, "%s",
+ DPDK_DEFAULT_RTE_CONFIG);
}
int dpdk_helper_eal_config_set(dpdk_helper_ctx_t *phc, dpdk_eal_config_t *ec) {
status = cf_util_get_string_buffer(child, prefix, sizeof(prefix));
if (status == 0) {
#if RTE_VERSION <= RTE_VERSION_NUM(18, 5, 0, 0)
- snprintf(phc->eal_config.file_prefix, DATA_MAX_NAME_LEN,
- "/var/run/.%s_config", prefix);
+ ssnprintf(phc->eal_config.file_prefix, DATA_MAX_NAME_LEN,
+ "/var/run/.%s_config", prefix);
#else
- snprintf(phc->eal_config.file_prefix, DATA_MAX_NAME_LEN,
- "/var/run/dpdk/%s/config", prefix);
+ ssnprintf(phc->eal_config.file_prefix, DATA_MAX_NAME_LEN,
+ "/var/run/dpdk/%s/config", prefix);
#endif
DEBUG("dpdk_common: EAL:File prefix %s", phc->eal_config.file_prefix);
}
DPDK_HELPER_TRACE(name);
/* Allocate dpdk_helper_ctx_t and
- * initialize a POSIX SHared Memory (SHM) object.
- */
+ * initialize a POSIX SHared Memory (SHM) object.
+ */
int err = dpdk_shm_init(name, shm_size, (void **)&phc);
if (err != 0) {
return -errno;
/* non blocking check on helper logging pipe */
struct pollfd fds = {
- .fd = phc->pipes[0], .events = POLLIN,
+ .fd = phc->pipes[0],
+ .events = POLLIN,
};
int data_avail = poll(&fds, 1, 0);
DEBUG("%s:dpdk_helper_check_pipe: poll data_avail=%d", phc->shm_name,
};
char want[1024];
- snprintf(want, sizeof(want), "%s 42 1480063672\r\n", cases[i].want_name);
+ ssnprintf(want, sizeof(want), "%s 42 1480063672\r\n", cases[i].want_name);
if (cases[i].plugin_instance != NULL)
sstrncpy(vl.plugin_instance, cases[i].plugin_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, (n->severity == NOTIF_FAILURE)
+ ? "FAILURE"
+ : (n->severity == NOTIF_WARNING)
+ ? "WARNING"
+ : (n->severity == NOTIF_OKAY) ? "OKAY" : "UNKNOWN");
JSON_ADD(g, "service");
JSON_ADD(g, "collectd");
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,
+ .yajl_string = test_string,
+ .yajl_map_key = test_map_key,
};
test_case_t c = {labels, labels_num, NULL};
}
case DS_TYPE_DERIVE: {
derive_t diff = v.derive - (derive_t)start_value;
- snprintf(integer, sizeof(integer), "%" PRIi64, diff);
+ ssnprintf(integer, sizeof(integer), "%" PRIi64, diff);
break;
}
case DS_TYPE_COUNTER: {
counter_t diff = counter_diff((counter_t)start_value, v.counter);
- snprintf(integer, sizeof(integer), "%llu", diff);
+ ssnprintf(integer, sizeof(integer), "%llu", diff);
break;
}
case DS_TYPE_ABSOLUTE: {
- snprintf(integer, sizeof(integer), "%" PRIu64, v.absolute);
+ ssnprintf(integer, sizeof(integer), "%" PRIu64, v.absolute);
break;
}
default: {
* "CUMULATIVE",
* "GAUGE"
* )
-*/
+ */
static int format_metric_kind(yajl_gen gen, int ds_type) {
switch (ds_type) {
case DS_TYPE_GAUGE:
* "DOUBLE",
* "INT64"
* )
-*/
+ */
static int format_value_type(yajl_gen gen, int ds_type) {
return json_string(gen, (ds_type == DS_TYPE_GAUGE) ? "DOUBLE" : "INT64");
}
#define GCM_PREFIX "custom.googleapis.com/collectd/"
if ((ds_index != 0) || strcmp("value", ds_name) != 0) {
- snprintf(buffer, buffer_size, GCM_PREFIX "%s/%s_%s", vl->plugin, vl->type,
- ds_name);
+ ssnprintf(buffer, buffer_size, GCM_PREFIX "%s/%s_%s", vl->plugin, vl->type,
+ ds_name);
} else {
- snprintf(buffer, buffer_size, GCM_PREFIX "%s/%s", vl->plugin, vl->type);
+ ssnprintf(buffer, buffer_size, GCM_PREFIX "%s/%s", vl->plugin, vl->type);
}
char const *whitelist = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
}
char start_value_key[DATA_MAX_NAME_LEN];
- snprintf(start_value_key, sizeof(start_value_key),
- "stackdriver:start_value[%d]", ds_index);
+ ssnprintf(start_value_key, sizeof(start_value_key),
+ "stackdriver:start_value[%d]", ds_index);
int status =
uc_meta_data_get_signed_int(vl, start_value_key, ret_start_value);
DEF_TEST(sd_format_metric_descriptor) {
value_list_t vl = {
- .host = "example.com", .plugin = "unit-test", .type = "example",
+ .host = "example.com",
+ .plugin = "unit-test",
+ .type = "example",
};
char got[1024];
.ds_num = 1,
.ds =
&(data_source_t){
- .name = "value", .type = DS_TYPE_GAUGE, .min = NAN, .max = NAN,
+ .name = "value",
+ .type = DS_TYPE_GAUGE,
+ .min = NAN,
+ .max = NAN,
},
};
EXPECT_EQ_INT(
{
char url[1024];
- snprintf(url, sizeof(url), GCE_SCOPE_URL_FORMAT,
- (email != NULL) ? email : GCE_DEFAULT_SERVICE_ACCOUNT);
+ ssnprintf(url, sizeof(url), GCE_SCOPE_URL_FORMAT,
+ (email != NULL) ? email : GCE_DEFAULT_SERVICE_ACCOUNT);
return read_url(url);
} /* }}} char *gce_scope */
return 0;
}
- snprintf(url, sizeof(url), GCE_TOKEN_URL_FORMAT, email);
+ ssnprintf(url, sizeof(url), GCE_TOKEN_URL_FORMAT, email);
json = read_url(url);
if (json == NULL) {
pthread_mutex_unlock(&token_lock);
};
/*
-* Histogram represents the distribution of data, it has a list of "bins".
-* Each bin represents an interval and has a count (frequency) of
-* number of values fall within its interval.
-*
-* Histogram's range is determined by the number of bins and the bin width,
-* There are 1000 bins and all bins have the same width of default 1 millisecond.
-* When a value above this range is added, Histogram's range is increased by
-* increasing the bin width (note that number of bins remains always at 1000).
-* This operation of increasing bin width is little expensive as each bin need
-* to be visited to update its count. To reduce frequent change of bin width,
-* new bin width will be the next nearest power of 2. Example: 2, 4, 8, 16, 32,
-* 64, 128, 256, 512, 1024, 2048, 5086, ...
-*
-* So, if the required bin width is 300, then new bin width will be 512 as it is
-* the next nearest power of 2.
-*/
+ * Histogram represents the distribution of data, it has a list of "bins".
+ * Each bin represents an interval and has a count (frequency) of
+ * number of values fall within its interval.
+ *
+ * Histogram's range is determined by the number of bins and the bin width,
+ * There are 1000 bins and all bins have the same width of default 1
+ * millisecond. When a value above this range is added, Histogram's range is
+ * increased by increasing the bin width (note that number of bins remains
+ * always at 1000). This operation of increasing bin width is little expensive
+ * as each bin need to be visited to update its count. To reduce frequent change
+ * of bin width, new bin width will be the next nearest power of 2. Example: 2,
+ * 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 5086, ...
+ *
+ * So, if the required bin width is 300, then new bin width will be 512 as it is
+ * the next nearest power of 2.
+ */
static void change_bin_width(latency_counter_t *lc, cdtime_t latency) /* {{{ */
{
/* This function is called because the new value is above histogram's range.
* Florian Forster <ff at octo.it>
**/
+#ifndef UTILS_LATENCY_LATENCY_H
+#define UTILS_LATENCY_LATENCY_H 1
+
#include "collectd.h"
#include "utils_time.h"
*/
double latency_counter_get_rate(const latency_counter_t *lc, cdtime_t lower,
cdtime_t upper, const cdtime_t now);
+
+#endif /* UTILS_LATENCY_LATENCY_H */
int latency_config_copy(latency_config_t *dst, const latency_config_t src) {
*dst = (latency_config_t){
- .percentile_num = src.percentile_num, .buckets_num = src.buckets_num,
+ .percentile_num = src.percentile_num,
+ .buckets_num = src.buckets_num,
};
dst->percentile = calloc(dst->percentile_num, sizeof(*dst->percentile));
} cases[] = {
{
// bucket 6 is zero
- DOUBLE_TO_CDTIME_T_STATIC(0.750), DOUBLE_TO_CDTIME_T_STATIC(0.875),
+ DOUBLE_TO_CDTIME_T_STATIC(0.750),
+ DOUBLE_TO_CDTIME_T_STATIC(0.875),
0.00,
},
{
// bucket 7 contains the t=1 update
- DOUBLE_TO_CDTIME_T_STATIC(0.875), DOUBLE_TO_CDTIME_T_STATIC(1.000),
+ DOUBLE_TO_CDTIME_T_STATIC(0.875),
+ DOUBLE_TO_CDTIME_T_STATIC(1.000),
1.00,
},
{
// range: bucket 7 - bucket 15; contains the t=1 and t=2 updates
- DOUBLE_TO_CDTIME_T_STATIC(0.875), DOUBLE_TO_CDTIME_T_STATIC(2.000),
+ DOUBLE_TO_CDTIME_T_STATIC(0.875),
+ DOUBLE_TO_CDTIME_T_STATIC(2.000),
2.00,
},
{
// lower bucket is only partially applied
DOUBLE_TO_CDTIME_T_STATIC(0.875 + (0.125 / 4)),
- DOUBLE_TO_CDTIME_T_STATIC(2.000), 1.75,
+ DOUBLE_TO_CDTIME_T_STATIC(2.000),
+ 1.75,
},
{
// upper bucket is only partially applied
DOUBLE_TO_CDTIME_T_STATIC(0.875),
- DOUBLE_TO_CDTIME_T_STATIC(2.000 - (0.125 / 4)), 1.75,
+ DOUBLE_TO_CDTIME_T_STATIC(2.000 - (0.125 / 4)),
+ 1.75,
},
{
// both buckets are only partially applied
DOUBLE_TO_CDTIME_T_STATIC(0.875 + (0.125 / 4)),
- DOUBLE_TO_CDTIME_T_STATIC(2.000 - (0.125 / 4)), 1.50,
+ DOUBLE_TO_CDTIME_T_STATIC(2.000 - (0.125 / 4)),
+ 1.50,
},
{
// lower bound is unspecified
- 0, DOUBLE_TO_CDTIME_T_STATIC(2.000), 2.00,
+ 0,
+ DOUBLE_TO_CDTIME_T_STATIC(2.000),
+ 2.00,
},
{
// upper bound is unspecified
- DOUBLE_TO_CDTIME_T_STATIC(125.000 - 0.125), 0, 1.00,
+ DOUBLE_TO_CDTIME_T_STATIC(125.000 - 0.125),
+ 0,
+ 1.00,
},
{
// overflow test: upper >> longest latency
- DOUBLE_TO_CDTIME_T_STATIC(1.000), DOUBLE_TO_CDTIME_T_STATIC(999999),
+ DOUBLE_TO_CDTIME_T_STATIC(1.000),
+ DOUBLE_TO_CDTIME_T_STATIC(999999),
124.00,
},
{
// overflow test: lower > longest latency
- DOUBLE_TO_CDTIME_T_STATIC(130), 0, 0.00,
+ DOUBLE_TO_CDTIME_T_STATIC(130),
+ 0,
+ 0.00,
},
{
// lower > upper => error
- DOUBLE_TO_CDTIME_T_STATIC(10), DOUBLE_TO_CDTIME_T_STATIC(9), NAN,
+ DOUBLE_TO_CDTIME_T_STATIC(10),
+ DOUBLE_TO_CDTIME_T_STATIC(9),
+ NAN,
},
{
// lower == upper => zero
- DOUBLE_TO_CDTIME_T_STATIC(9), DOUBLE_TO_CDTIME_T_STATIC(9), 0.00,
+ DOUBLE_TO_CDTIME_T_STATIC(9),
+ DOUBLE_TO_CDTIME_T_STATIC(9),
+ 0.00,
},
};
*
* Author:
* Niki W. Waibel <niki.waibel@gmx.net>
-**/
+ **/
#if HAVE_CONFIG_H
#include "config.h"
if (isdigit((int)s[-1])) {
/*
- * Note: this is a heuristic only - there is no reason
- * why these devices should live in /dev.
- * Perhaps this directory should be specifiable by option.
- * One might for example have /devlabel with links to /dev
- * for the devices that may be accessed in this way.
- * (This is useful, if the cdrom on /dev/hdc must not
- * be accessed.)
- */
+ * Note: this is a heuristic only - there is no reason
+ * why these devices should live in /dev.
+ * Perhaps this directory should be specifiable by option.
+ * One might for example have /devlabel with links to /dev
+ * for the devices that may be accessed in this way.
+ * (This is useful, if the cdrom on /dev/hdc must not
+ * be accessed.)
+ */
snprintf(device, sizeof(device), "%s/%s", DEVLABELDIR, ptname);
if (!get_label_uuid(device, &label, uuid)) {
uuidcache_addentry(sstrdup(device), label, uuid);
#elif HAVE_SEQ_GETMNTENT
#warn "This version of `getmntent' hat not yet been implemented!"
-/* #endif HAVE_SEQ_GETMNTENT */
+ /* #endif HAVE_SEQ_GETMNTENT */
#elif HAVE_GETMNTENT_R
static cu_mount_t *cu_mount_getmntent(void) {
*
* Author:
* Niki W. Waibel <niki.waibel@gmx.net>
-**/
+ **/
/* See below for instructions how to use the public functions. */
/* create the claim set */
status =
- snprintf(claim, sizeof(claim), OAUTH_CLAIM_FORMAT, auth->iss, auth->scope,
- auth->aud, (unsigned long)CDTIME_T_TO_TIME_T(exp),
- (unsigned long)CDTIME_T_TO_TIME_T(iat));
+ ssnprintf(claim, sizeof(claim), OAUTH_CLAIM_FORMAT, auth->iss,
+ auth->scope, auth->aud, (unsigned long)CDTIME_T_TO_TIME_T(exp),
+ (unsigned long)CDTIME_T_TO_TIME_T(iat));
if (status < 1)
return -1;
else if ((size_t)status >= sizeof(claim))
int status;
/* Make the string to sign */
- payload_len = snprintf(payload, sizeof(payload), "%s.%s", header, claim);
+ payload_len = ssnprintf(payload, sizeof(payload), "%s.%s", header, claim);
if (payload_len < 1) {
return -1;
} else if (payload_len >= sizeof(payload)) {
if (status != 0)
return -1;
- status = snprintf(buffer, buffer_size, "%s.%s.%s", header, claim, signature);
+ status = ssnprintf(buffer, buffer_size, "%s.%s.%s", header, claim, signature);
if (status < 1)
return -1;
else if ((size_t)status >= buffer_size)
return -1;
}
- snprintf(post_data, sizeof(post_data), "grant_type=%s&assertion=%s",
- OAUTH_GRANT_TYPE, assertion);
+ ssnprintf(post_data, sizeof(post_data), "grant_type=%s&assertion=%s",
+ OAUTH_GRANT_TYPE, assertion);
curl = curl_easy_init();
if (curl == NULL) {
}
oauth_google_t ret = {
- .project_id = strdup(project_id), .oauth = oauth,
+ .project_id = strdup(project_id),
+ .oauth = oauth,
};
yajl_tree_free(root);
char const *home;
if ((home = getenv("HOME")) != NULL) {
char path[PATH_MAX];
- snprintf(path, sizeof(path),
- "%s/.config/gcloud/application_default_credentials.json", home);
+ ssnprintf(path, sizeof(path),
+ "%s/.config/gcloud/application_default_credentials.json", home);
oauth_google_t ret = oauth_create_google_file(path, scope);
if (ret.oauth != NULL) {
} cases[] = {
{
"{\"access_token\":\"MaeC6kaePhie1ree\",\"expires_in\":3600}",
- /* status = */ 0, "MaeC6kaePhie1ree", TIME_T_TO_CDTIME_T_STATIC(3600),
+ /* status = */ 0,
+ "MaeC6kaePhie1ree",
+ TIME_T_TO_CDTIME_T_STATIC(3600),
},
{
"{\"token_type\":\"Bearer\",\"expires_in\":1800,\"access_token\":"
"\"aeThiebee2gushuY\"}",
- /* status = */ 0, "aeThiebee2gushuY", TIME_T_TO_CDTIME_T_STATIC(1800),
+ /* status = */ 0,
+ "aeThiebee2gushuY",
+ TIME_T_TO_CDTIME_T_STATIC(1800),
},
{
"{\"ignored_key\":\"uaph5aewaeghi1Ge\",\"expires_in\":3600}",
- /* status = */ -1, NULL, 0,
+ /* status = */ -1,
+ NULL,
+ 0,
},
{
/* expires_in missing */
"{\"access_token\":\"shaephohbie9Ahch\"}",
- /* status = */ -1, NULL, 0,
+ /* status = */ -1,
+ NULL,
+ 0,
},
};
ovs_db_t *pdb = (ovs_db_t *)arg; /* pointer to OVS DB */
ovs_json_reader_t *jreader = NULL;
struct pollfd poll_fd = {
- .fd = pdb->sock, .events = POLLIN | POLLPRI, .revents = 0,
+ .fd = pdb->sock,
+ .events = POLLIN | POLLPRI,
+ .revents = 0,
};
/* create JSON reader instance */
/* generate id field */
OVS_YAJL_CALL(ovs_yajl_gen_tstring, jgen, "id");
uid = ovs_uid_generate();
- snprintf(uid_buff, sizeof(uid_buff), "%" PRIX64, uid);
+ ssnprintf(uid_buff, sizeof(uid_buff), "%" PRIX64, uid);
OVS_YAJL_CALL(ovs_yajl_gen_tstring, jgen, uid_buff);
OVS_YAJL_CALL(yajl_gen_map_close, jgen);
OVS_YAJL_CALL(ovs_yajl_gen_tstring, jgen, OVS_DB_DEFAULT_DB_NAME);
/* uid string <json-value> */
- snprintf(uid_str, sizeof(uid_str), "%" PRIX64, new_cb->uid);
+ ssnprintf(uid_str, sizeof(uid_str), "%" PRIX64, new_cb->uid);
OVS_YAJL_CALL(ovs_yajl_gen_tstring, jgen, uid_str);
/* <monitor-requests> */
* RETURN VALUE
* On success, the number of read bytes (includes stripped \n).
* -1 on file open error
-*/
+ */
static int read_proc_name(const char *procfs_path,
const struct dirent *pid_entry, char *name,
const size_t out_size) {
* Michał Aleksiński <michalx.aleksinski@intel.com>
**/
+#ifndef UTILS_PROC_PIDS_PROC_PIDS_H
+#define UTILS_PROC_PIDS_PROC_PIDS_H 1
+
#include <dirent.h>
#include <sys/types.h>
* 0 on success. -1 on error.
*/
int proc_pids_free(proc_pids_t *proc_pids[], size_t proc_pids_num);
+
+#endif /* UTILS_PROC_PIDS_PROC_PIDS_H */
-#include "testing.h"
+// clang-format off
+/*
+ * Explicit order is required or _FILE_OFFSET_BITS will have definition mismatches on Solaris
+ * See Github Issue #3193 for details
+ */
#include "utils/proc_pids/proc_pids.c" /* sic */
+#include "testing.h"
+// clang-format on
#include <sys/stat.h>
/***************************************************************************
if (rra_num >= rra_max)
break;
- status = snprintf(buffer, sizeof(buffer), "RRA:%s:%.10f:%u:%u",
- rra_types[j], cfg->xff, cdp_len, cdp_num);
+ status = ssnprintf(buffer, sizeof(buffer), "RRA:%s:%.10f:%u:%u",
+ rra_types[j], cfg->xff, cdp_len, cdp_num);
if ((status < 0) || ((size_t)status >= sizeof(buffer))) {
P_ERROR("rra_get: Buffer would have been truncated.");
if (isnan(d->min)) {
sstrncpy(min, "U", sizeof(min));
} else
- snprintf(min, sizeof(min), "%f", d->min);
+ ssnprintf(min, sizeof(min), "%f", d->min);
if (isnan(d->max)) {
sstrncpy(max, "U", sizeof(max));
} else
- snprintf(max, sizeof(max), "%f", d->max);
+ ssnprintf(max, sizeof(max), "%f", d->max);
- status = snprintf(
+ status = ssnprintf(
buffer, sizeof(buffer), "DS:%s:%s:%i:%s:%s", d->name, type,
(cfg->heartbeat > 0) ? cfg->heartbeat
: (int)CDTIME_T_TO_TIME_T(2 * vl->interval),
return status;
} /* }}} int srrd_create */
-/* #endif HAVE_THREADSAFE_LIBRRD */
+ /* #endif HAVE_THREADSAFE_LIBRRD */
#else /* !HAVE_THREADSAFE_LIBRRD */
static int srrd_create(const char *filename, /* {{{ */
if (last_up == 0)
last_up = time(NULL) - 10;
- snprintf(pdp_step_str, sizeof(pdp_step_str), "%lu", pdp_step);
- snprintf(last_up_str, sizeof(last_up_str), "%lu", (unsigned long)last_up);
+ ssnprintf(pdp_step_str, sizeof(pdp_step_str), "%lu", pdp_step);
+ ssnprintf(last_up_str, sizeof(last_up_str), "%lu", (unsigned long)last_up);
new_argv[0] = "create";
new_argv[1] = (void *)filename;
return 0;
}
- snprintf(tmpfile, sizeof(tmpfile), "%s.async", args->filename);
+ ssnprintf(tmpfile, sizeof(tmpfile), "%s.async", args->filename);
status = srrd_create(tmpfile, args->pdp_step, args->last_up, args->argc,
(void *)args->argv);
struct genlmsghdr *genh = mnl_nlmsg_put_extra_header(nlh, sizeof(*genh));
*genh = (struct genlmsghdr){
- .cmd = CTRL_CMD_GETFAMILY, .version = 0x01,
+ .cmd = CTRL_CMD_GETFAMILY,
+ .version = 0x01,
};
mnl_attr_put_strz(nlh, CTRL_ATTR_FAMILY_NAME, TASKSTATS_GENL_NAME);
* regular expressions.
*/
+#ifndef UTILS_TAIL_MATCH_H
+#define UTILS_TAIL_MATCH_H 1
+
#include "utils/latency/latency_config.h"
#include "utils/match/match.h"
*
* RETURN VALUE
* Zero on success, nonzero on failure.
-*/
+ */
int tail_match_read(cu_tail_match_t *obj);
+
+#endif /* UTILS_TAIL_MATCH_H */
#include "plugin.h"
#include "utils/common/common.h"
-#if HAVE_SYS_SYSCTL_H
+#if defined(HAVE_SYS_SYSCTL_H) && defined(HAVE_SYSCTLBYNAME) || \
+ defined(__OpenBSD__)
+/* Implies have BSD variant */
#include <sys/sysctl.h>
#endif
if (plugin_instance == NULL)
plugin_instance = "default";
- snprintf(vl.plugin_instance, sizeof(vl.plugin_instance), "%s-%s",
- plugin_instance, category);
+ ssnprintf(vl.plugin_instance, sizeof(vl.plugin_instance), "%s-%s",
+ plugin_instance, category);
sstrncpy(vl.type, type, sizeof(vl.type));
/* callback = */ varnish_read,
/* interval = */ 0,
&(user_data_t){
- .data = conf, .free_func = varnish_config_free,
+ .data = conf,
+ .free_func = varnish_config_free,
});
return 0;
!conf->collect_mgt && !conf->collect_lck && !conf->collect_mempool &&
!conf->collect_mse
#endif
- ) {
+ ) {
WARNING("Varnish plugin: No metric has been configured for "
"instance \"%s\". Disabling this instance.",
(conf->instance == NULL) ? "localhost" : conf->instance);
return EINVAL;
}
- snprintf(callback_name, sizeof(callback_name), "varnish/%s",
- (conf->instance == NULL) ? "localhost" : conf->instance);
+ ssnprintf(callback_name, sizeof(callback_name), "varnish/%s",
+ (conf->instance == NULL) ? "localhost" : conf->instance);
plugin_register_complex_read(
/* group = */ "varnish",
/* callback = */ varnish_read,
/* interval = */ 0,
&(user_data_t){
- .data = conf, .free_func = varnish_config_free,
+ .data = conf,
+ .free_func = varnish_config_free,
});
have_instance = true;
static virt_notif_thread_t notif_thread;
const char *domain_states[] = {
- [VIR_DOMAIN_NOSTATE] = "no state",
- [VIR_DOMAIN_RUNNING] = "the domain is running",
- [VIR_DOMAIN_BLOCKED] = "the domain is blocked on resource",
- [VIR_DOMAIN_PAUSED] = "the domain is paused by user",
- [VIR_DOMAIN_SHUTDOWN] = "the domain is being shut down",
- [VIR_DOMAIN_SHUTOFF] = "the domain is shut off",
- [VIR_DOMAIN_CRASHED] = "the domain is crashed",
+ [VIR_DOMAIN_NOSTATE] = "no state",
+ [VIR_DOMAIN_RUNNING] = "the domain is running",
+ [VIR_DOMAIN_BLOCKED] = "the domain is blocked on resource",
+ [VIR_DOMAIN_PAUSED] = "the domain is paused by user",
+ [VIR_DOMAIN_SHUTDOWN] = "the domain is being shut down",
+ [VIR_DOMAIN_SHUTOFF] = "the domain is shut off",
+ [VIR_DOMAIN_CRASHED] = "the domain is crashed",
#ifdef HAVE_DOM_STATE_PMSUSPENDED
- [VIR_DOMAIN_PMSUSPENDED] =
- "the domain is suspended by guest power management",
+ [VIR_DOMAIN_PMSUSPENDED] =
+ "the domain is suspended by guest power management",
#endif
};
#define DOMAIN_STATE_REASON_MAX_SIZE 20
const char *domain_reasons[][DOMAIN_STATE_REASON_MAX_SIZE] = {
- [VIR_DOMAIN_NOSTATE][VIR_DOMAIN_NOSTATE_UNKNOWN] =
- "the reason is unknown",
-
- [VIR_DOMAIN_RUNNING][VIR_DOMAIN_RUNNING_UNKNOWN] =
- "the reason is unknown",
- [VIR_DOMAIN_RUNNING][VIR_DOMAIN_RUNNING_BOOTED] =
- "normal startup from boot",
- [VIR_DOMAIN_RUNNING][VIR_DOMAIN_RUNNING_MIGRATED] =
- "migrated from another host",
- [VIR_DOMAIN_RUNNING][VIR_DOMAIN_RUNNING_RESTORED] =
- "restored from a state file",
- [VIR_DOMAIN_RUNNING][VIR_DOMAIN_RUNNING_FROM_SNAPSHOT] =
- "restored from snapshot",
- [VIR_DOMAIN_RUNNING][VIR_DOMAIN_RUNNING_UNPAUSED] =
- "returned from paused state",
- [VIR_DOMAIN_RUNNING][VIR_DOMAIN_RUNNING_MIGRATION_CANCELED] =
- "returned from migration",
- [VIR_DOMAIN_RUNNING][VIR_DOMAIN_RUNNING_SAVE_CANCELED] =
- "returned from failed save process",
+ [VIR_DOMAIN_NOSTATE][VIR_DOMAIN_NOSTATE_UNKNOWN] = "the reason is unknown",
+
+ [VIR_DOMAIN_RUNNING][VIR_DOMAIN_RUNNING_UNKNOWN] = "the reason is unknown",
+ [VIR_DOMAIN_RUNNING][VIR_DOMAIN_RUNNING_BOOTED] =
+ "normal startup from boot",
+ [VIR_DOMAIN_RUNNING][VIR_DOMAIN_RUNNING_MIGRATED] =
+ "migrated from another host",
+ [VIR_DOMAIN_RUNNING][VIR_DOMAIN_RUNNING_RESTORED] =
+ "restored from a state file",
+ [VIR_DOMAIN_RUNNING][VIR_DOMAIN_RUNNING_FROM_SNAPSHOT] =
+ "restored from snapshot",
+ [VIR_DOMAIN_RUNNING][VIR_DOMAIN_RUNNING_UNPAUSED] =
+ "returned from paused state",
+ [VIR_DOMAIN_RUNNING][VIR_DOMAIN_RUNNING_MIGRATION_CANCELED] =
+ "returned from migration",
+ [VIR_DOMAIN_RUNNING][VIR_DOMAIN_RUNNING_SAVE_CANCELED] =
+ "returned from failed save process",
#ifdef HAVE_DOM_REASON_RUNNING_WAKEUP
- [VIR_DOMAIN_RUNNING][VIR_DOMAIN_RUNNING_WAKEUP] =
- "returned from pmsuspended due to wakeup event",
+ [VIR_DOMAIN_RUNNING][VIR_DOMAIN_RUNNING_WAKEUP] =
+ "returned from pmsuspended due to wakeup event",
#endif
#ifdef HAVE_DOM_REASON_CRASHED
- [VIR_DOMAIN_RUNNING][VIR_DOMAIN_RUNNING_CRASHED] =
- "resumed from crashed",
+ [VIR_DOMAIN_RUNNING][VIR_DOMAIN_RUNNING_CRASHED] = "resumed from crashed",
#endif
#ifdef HAVE_DOM_REASON_POSTCOPY
- [VIR_DOMAIN_RUNNING][VIR_DOMAIN_RUNNING_POSTCOPY] =
- "running in post-copy migration mode",
-#endif
- [VIR_DOMAIN_BLOCKED][VIR_DOMAIN_BLOCKED_UNKNOWN] =
- "the reason is unknown",
-
- [VIR_DOMAIN_PAUSED][VIR_DOMAIN_PAUSED_UNKNOWN] =
- "the reason is unknown",
- [VIR_DOMAIN_PAUSED][VIR_DOMAIN_PAUSED_USER] = "paused on user request",
- [VIR_DOMAIN_PAUSED][VIR_DOMAIN_PAUSED_MIGRATION] =
- "paused for offline migration",
- [VIR_DOMAIN_PAUSED][VIR_DOMAIN_PAUSED_SAVE] = "paused for save",
- [VIR_DOMAIN_PAUSED][VIR_DOMAIN_PAUSED_DUMP] =
- "paused for offline core dump",
- [VIR_DOMAIN_PAUSED][VIR_DOMAIN_PAUSED_IOERROR] =
- "paused due to a disk I/O error",
- [VIR_DOMAIN_PAUSED][VIR_DOMAIN_PAUSED_WATCHDOG] =
- "paused due to a watchdog event",
- [VIR_DOMAIN_PAUSED][VIR_DOMAIN_PAUSED_FROM_SNAPSHOT] =
- "paused after restoring from snapshot",
+ [VIR_DOMAIN_RUNNING][VIR_DOMAIN_RUNNING_POSTCOPY] =
+ "running in post-copy migration mode",
+#endif
+ [VIR_DOMAIN_BLOCKED][VIR_DOMAIN_BLOCKED_UNKNOWN] = "the reason is unknown",
+
+ [VIR_DOMAIN_PAUSED][VIR_DOMAIN_PAUSED_UNKNOWN] = "the reason is unknown",
+ [VIR_DOMAIN_PAUSED][VIR_DOMAIN_PAUSED_USER] = "paused on user request",
+ [VIR_DOMAIN_PAUSED][VIR_DOMAIN_PAUSED_MIGRATION] =
+ "paused for offline migration",
+ [VIR_DOMAIN_PAUSED][VIR_DOMAIN_PAUSED_SAVE] = "paused for save",
+ [VIR_DOMAIN_PAUSED][VIR_DOMAIN_PAUSED_DUMP] =
+ "paused for offline core dump",
+ [VIR_DOMAIN_PAUSED][VIR_DOMAIN_PAUSED_IOERROR] =
+ "paused due to a disk I/O error",
+ [VIR_DOMAIN_PAUSED][VIR_DOMAIN_PAUSED_WATCHDOG] =
+ "paused due to a watchdog event",
+ [VIR_DOMAIN_PAUSED][VIR_DOMAIN_PAUSED_FROM_SNAPSHOT] =
+ "paused after restoring from snapshot",
#ifdef HAVE_DOM_REASON_PAUSED_SHUTTING_DOWN
- [VIR_DOMAIN_PAUSED][VIR_DOMAIN_PAUSED_SHUTTING_DOWN] =
- "paused during shutdown process",
+ [VIR_DOMAIN_PAUSED][VIR_DOMAIN_PAUSED_SHUTTING_DOWN] =
+ "paused during shutdown process",
#endif
#ifdef HAVE_DOM_REASON_PAUSED_SNAPSHOT
- [VIR_DOMAIN_PAUSED][VIR_DOMAIN_PAUSED_SNAPSHOT] =
- "paused while creating a snapshot",
+ [VIR_DOMAIN_PAUSED][VIR_DOMAIN_PAUSED_SNAPSHOT] =
+ "paused while creating a snapshot",
#endif
#ifdef HAVE_DOM_REASON_PAUSED_CRASHED
- [VIR_DOMAIN_PAUSED][VIR_DOMAIN_PAUSED_CRASHED] =
- "paused due to a guest crash",
+ [VIR_DOMAIN_PAUSED][VIR_DOMAIN_PAUSED_CRASHED] =
+ "paused due to a guest crash",
#endif
#ifdef HAVE_DOM_REASON_PAUSED_STARTING_UP
- [VIR_DOMAIN_PAUSED][VIR_DOMAIN_PAUSED_STARTING_UP] =
- "the domain is being started",
+ [VIR_DOMAIN_PAUSED][VIR_DOMAIN_PAUSED_STARTING_UP] =
+ "the domain is being started",
#endif
#ifdef HAVE_DOM_REASON_POSTCOPY
- [VIR_DOMAIN_PAUSED][VIR_DOMAIN_PAUSED_POSTCOPY] =
- "paused for post-copy migration",
- [VIR_DOMAIN_PAUSED][VIR_DOMAIN_PAUSED_POSTCOPY_FAILED] =
- "paused after failed post-copy",
-#endif
- [VIR_DOMAIN_SHUTDOWN][VIR_DOMAIN_SHUTDOWN_UNKNOWN] =
- "the reason is unknown",
- [VIR_DOMAIN_SHUTDOWN][VIR_DOMAIN_SHUTDOWN_USER] =
- "shutting down on user request",
-
- [VIR_DOMAIN_SHUTOFF][VIR_DOMAIN_SHUTOFF_UNKNOWN] =
- "the reason is unknown",
- [VIR_DOMAIN_SHUTOFF][VIR_DOMAIN_SHUTOFF_SHUTDOWN] = "normal shutdown",
- [VIR_DOMAIN_SHUTOFF][VIR_DOMAIN_SHUTOFF_DESTROYED] = "forced poweroff",
- [VIR_DOMAIN_SHUTOFF][VIR_DOMAIN_SHUTOFF_CRASHED] = "domain crashed",
- [VIR_DOMAIN_SHUTOFF][VIR_DOMAIN_SHUTOFF_MIGRATED] =
- "migrated to another host",
- [VIR_DOMAIN_SHUTOFF][VIR_DOMAIN_SHUTOFF_SAVED] = "saved to a file",
- [VIR_DOMAIN_SHUTOFF][VIR_DOMAIN_SHUTOFF_FAILED] =
- "domain failed to start",
- [VIR_DOMAIN_SHUTOFF][VIR_DOMAIN_SHUTOFF_FROM_SNAPSHOT] =
- "restored from a snapshot which was taken while domain was shutoff",
+ [VIR_DOMAIN_PAUSED][VIR_DOMAIN_PAUSED_POSTCOPY] =
+ "paused for post-copy migration",
+ [VIR_DOMAIN_PAUSED][VIR_DOMAIN_PAUSED_POSTCOPY_FAILED] =
+ "paused after failed post-copy",
+#endif
+ [VIR_DOMAIN_SHUTDOWN][VIR_DOMAIN_SHUTDOWN_UNKNOWN] =
+ "the reason is unknown",
+ [VIR_DOMAIN_SHUTDOWN][VIR_DOMAIN_SHUTDOWN_USER] =
+ "shutting down on user request",
+
+ [VIR_DOMAIN_SHUTOFF][VIR_DOMAIN_SHUTOFF_UNKNOWN] = "the reason is unknown",
+ [VIR_DOMAIN_SHUTOFF][VIR_DOMAIN_SHUTOFF_SHUTDOWN] = "normal shutdown",
+ [VIR_DOMAIN_SHUTOFF][VIR_DOMAIN_SHUTOFF_DESTROYED] = "forced poweroff",
+ [VIR_DOMAIN_SHUTOFF][VIR_DOMAIN_SHUTOFF_CRASHED] = "domain crashed",
+ [VIR_DOMAIN_SHUTOFF][VIR_DOMAIN_SHUTOFF_MIGRATED] =
+ "migrated to another host",
+ [VIR_DOMAIN_SHUTOFF][VIR_DOMAIN_SHUTOFF_SAVED] = "saved to a file",
+ [VIR_DOMAIN_SHUTOFF][VIR_DOMAIN_SHUTOFF_FAILED] = "domain failed to start",
+ [VIR_DOMAIN_SHUTOFF][VIR_DOMAIN_SHUTOFF_FROM_SNAPSHOT] =
+ "restored from a snapshot which was taken while domain was shutoff",
#ifdef HAVE_DOM_REASON_SHUTOFF_DAEMON
- [VIR_DOMAIN_SHUTOFF][VIR_DOMAIN_SHUTOFF_DAEMON] =
- "daemon decides to kill domain during reconnection processing",
+ [VIR_DOMAIN_SHUTOFF][VIR_DOMAIN_SHUTOFF_DAEMON] =
+ "daemon decides to kill domain during reconnection processing",
#endif
- [VIR_DOMAIN_CRASHED][VIR_DOMAIN_CRASHED_UNKNOWN] =
- "the reason is unknown",
+ [VIR_DOMAIN_CRASHED][VIR_DOMAIN_CRASHED_UNKNOWN] = "the reason is unknown",
#ifdef VIR_DOMAIN_CRASHED_PANICKED
- [VIR_DOMAIN_CRASHED][VIR_DOMAIN_CRASHED_PANICKED] = "domain panicked",
+ [VIR_DOMAIN_CRASHED][VIR_DOMAIN_CRASHED_PANICKED] = "domain panicked",
#endif
#ifdef HAVE_DOM_STATE_PMSUSPENDED
- [VIR_DOMAIN_PMSUSPENDED][VIR_DOMAIN_PMSUSPENDED_UNKNOWN] =
- "the reason is unknown",
+ [VIR_DOMAIN_PMSUSPENDED][VIR_DOMAIN_PMSUSPENDED_UNKNOWN] =
+ "the reason is unknown",
#endif
};
#endif /* HAVE_DOM_REASON */
ERROR(PLUGIN_NAME " plugin: %s failed: %s", (s), err->message); \
} while (0)
-static char *metadata_get_hostname(virDomainPtr dom) {
+enum metadata_set_type_e { META_APPEND_HOST, META_APPEND_PLUGIN_INSTANCE };
+
+static void set_field_from_metadata(value_list_t *vl, virDomainPtr dom,
+ enum metadata_set_type_e field) {
const char *xpath_str = NULL;
if (hm_xpath == NULL)
xpath_str = "/instance/name/text()";
const char *namespace = NULL;
if (hm_ns == NULL) {
namespace = "http://openstack.org/xmlns/libvirt/nova/1.0";
- } else {
+ } // namespace =hm_ns;
+ else {
namespace = hm_ns;
}
char *metadata_str = virDomainGetMetadata(
dom, VIR_DOMAIN_METADATA_ELEMENT, namespace, VIR_DOMAIN_AFFECT_CURRENT);
if (metadata_str == NULL) {
- return NULL;
+ return;
}
- char *hostname = NULL;
+ const char *value = NULL;
xmlXPathContextPtr xpath_ctx = NULL;
xmlXPathObjectPtr xpath_obj = NULL;
xmlNodePtr xml_node = NULL;
xml_node = xpath_obj->nodesetval->nodeTab[0];
if (xml_node->type == XML_TEXT_NODE) {
- hostname = strdup((const char *)xml_node->content);
+ value = (const char *)xml_node->content;
} else if (xml_node->type == XML_ATTRIBUTE_NODE) {
- hostname = strdup((const char *)xml_node->children->content);
+ value = (const char *)xml_node->children->content;
} else {
ERROR(PLUGIN_NAME " plugin: xmlXPathEval(%s) unsupported node type %d",
xpath_str, xml_node->type);
goto metadata_end;
}
- if (hostname == NULL) {
- ERROR(PLUGIN_NAME " plugin: strdup(%s) hostname failed", xpath_str);
+ if (value == NULL)
goto metadata_end;
+
+ switch (field) {
+ case META_APPEND_HOST:
+ SSTRNCAT(vl->host, value, sizeof(vl->host));
+ break;
+ case META_APPEND_PLUGIN_INSTANCE:
+ SSTRNCAT(vl->plugin_instance, value, sizeof(vl->plugin_instance));
+ break;
}
metadata_end:
if (xml_doc)
xmlFreeDoc(xml_doc);
sfree(metadata_str);
- return hostname;
}
static void init_value_list(value_list_t *vl, virDomainPtr dom) {
SSTRNCAT(vl->host, uuid, sizeof(vl->host));
break;
case hf_metadata:
- name = metadata_get_hostname(dom);
- if (name)
- SSTRNCAT(vl->host, name, sizeof(vl->host));
+ set_field_from_metadata(vl, dom, META_APPEND_HOST);
break;
}
}
SSTRNCAT(vl->plugin_instance, uuid, sizeof(vl->plugin_instance));
break;
case plginst_metadata:
- name = metadata_get_hostname(dom);
- if (name)
- SSTRNCAT(vl->plugin_instance, name, sizeof(vl->plugin_instance));
+ set_field_from_metadata(vl, dom, META_APPEND_PLUGIN_INSTANCE);
break;
}
}
-
} /* void init_value_list */
static int init_notif(notification_t *notif, const virDomainPtr domain,
static void submit_derive2(const char *type, derive_t v0, derive_t v1,
virDomainPtr dom, const char *devname) {
value_t values[] = {
- {.derive = v0}, {.derive = v1},
+ {.derive = v0},
+ {.derive = v1},
};
submit(dom, type, devname, values, STATIC_ARRAY_SIZE(values));
const char *type) {
char type_instance[DATA_MAX_NAME_LEN];
- snprintf(type_instance, sizeof(type_instance), "%d", vcpu_nr);
+ ssnprintf(type_instance, sizeof(type_instance), "%d", vcpu_nr);
submit(dom, type, type_instance, &(value_t){.derive = value}, 1);
}
}
char flush_type_instance[DATA_MAX_NAME_LEN];
- snprintf(flush_type_instance, sizeof(flush_type_instance), "flush-%s",
- type_instance);
+ ssnprintf(flush_type_instance, sizeof(flush_type_instance), "flush-%s",
+ type_instance);
if ((bstats->bi.rd_req != -1) && (bstats->bi.wr_req != -1))
submit_derive2("disk_ops", (derive_t)bstats->bi.rd_req,
const char *reason_str = "N/A";
#endif
- snprintf(msg, sizeof(msg), "Domain state: %s. Reason: %s", state_str,
- reason_str);
+ ssnprintf(msg, sizeof(msg), "Domain state: %s. Reason: %s", state_str,
+ reason_str);
int severity;
switch (state) {
char type_instance[DATA_MAX_NAME_LEN];
bool is_set = VIR_CPU_USABLE(cpu_maps, cpu_map_len, vcpu, cpu);
- snprintf(type_instance, sizeof(type_instance), "vcpu_%d-cpu_%d", vcpu, cpu);
+ ssnprintf(type_instance, sizeof(type_instance), "vcpu_%d-cpu_%d", vcpu,
+ cpu);
submit(dom, "cpu_affinity", type_instance, &(value_t){.gauge = is_set}, 1);
}
}
}
value_t values[] = {
- {.gauge = (gauge_t)domain_state}, {.gauge = (gauge_t)domain_reason},
+ {.gauge = (gauge_t)domain_state},
+ {.gauge = (gauge_t)domain_reason},
};
submit(domain, "domain_state", NULL, values, STATIC_ARRAY_SIZE(values));
if (min_flt > 0 || maj_flt > 0) {
value_t values[] = {
- {.gauge = (gauge_t)min_flt}, {.gauge = (gauge_t)maj_flt},
+ {.gauge = (gauge_t)min_flt},
+ {.gauge = (gauge_t)maj_flt},
};
submit(domain, "ps_pagefaults", NULL, values, STATIC_ARRAY_SIZE(values));
}
memset(lv_ud, 0, sizeof(*lv_ud));
- snprintf(inst->tag, sizeof(inst->tag), "%s-%" PRIsz, PLUGIN_NAME, i);
+ ssnprintf(inst->tag, sizeof(inst->tag), "%s-%" PRIsz, PLUGIN_NAME, i);
inst->id = i;
user_data_t *ud = &(lv_ud->ud);
goto done;
}
- snprintf(xpath_str, sizeof(xpath_str), "/domain/metadata/%s:%s/text()",
- METADATA_VM_PARTITION_PREFIX, METADATA_VM_PARTITION_ELEMENT);
+ ssnprintf(xpath_str, sizeof(xpath_str), "/domain/metadata/%s:%s/text()",
+ METADATA_VM_PARTITION_PREFIX, METADATA_VM_PARTITION_ELEMENT);
xpath_obj = xmlXPathEvalExpression((xmlChar *)xpath_str, xpath_ctx);
if (xpath_obj == NULL) {
ERROR(PLUGIN_NAME " plugin: xmlXPathEval(%s) failed on domain %s",
break;
case if_number: {
char number_string[4];
- snprintf(number_string, sizeof(number_string), "%d", itf_number);
+ ssnprintf(number_string, sizeof(number_string), "%d", itf_number);
if (ignore_device_match(il_interface_devices, domname, number_string) !=
0)
device_ignored = true;
}
char number_string[21];
- snprintf(number_string, sizeof(number_string), "interface-%u", number);
+ ssnprintf(number_string, sizeof(number_string), "interface-%u", number);
char *number_copy = strdup(number_string);
if (!number_copy) {
sfree(path_copy);
ERROR(PLUGIN_NAME " plugin: malloc failed.");
return 0;
}
- snprintf(name, n, "%s:%s", domname, devpath);
+ ssnprintf(name, n, "%s:%s", domname, devpath);
int r = ignorelist_match(il, name);
sfree(name);
return r;
static void submit_two(const char *plugin_instance, const char *type,
const char *type_instance, derive_t c0, derive_t c1) {
value_t values[] = {
- {.derive = c0}, {.derive = c1},
+ {.derive = c0},
+ {.derive = c1},
};
submit(plugin_instance, type, type_instance, values,
derive_t tx) {
value_list_t vl = VALUE_LIST_INIT;
value_t values[] = {
- {.derive = rx}, {.derive = tx},
+ {.derive = rx},
+ {.derive = tx},
};
vl.values = values;
gauge_t lnum) {
value_list_t vl = VALUE_LIST_INIT;
value_t values[] = {
- {.gauge = snum}, {.gauge = mnum}, {.gauge = lnum},
+ {.gauge = snum},
+ {.gauge = mnum},
+ {.gauge = lnum},
};
vl.values = values;
plugin_register_write(callback_name, wg_write,
&(user_data_t){
- .data = cb, .free_func = wg_callback_free,
+ .data = cb,
+ .free_func = wg_callback_free,
});
plugin_register_flush(callback_name, wg_flush, &(user_data_t){.data = cb});
callback_name, cb->location);
user_data_t user_data = {
- .data = cb, .free_func = wh_callback_free,
+ .data = cb,
+ .free_func = wh_callback_free,
};
if (cb->send_metrics) {
#define KAFKA_RANDOM_KEY_BUFFER \
(char[KAFKA_RANDOM_KEY_SIZE]) { "" }
static char *kafka_random_key(char buffer[static KAFKA_RANDOM_KEY_SIZE]) {
- snprintf(buffer, KAFKA_RANDOM_KEY_SIZE, "%08" PRIX32, cdrand_u());
+ ssnprintf(buffer, KAFKA_RANDOM_KEY_SIZE, "%08" PRIX32, cdrand_u());
return buffer;
}
rd_kafka_topic_conf_set_partitioner_cb(tctx->conf, kafka_partition);
rd_kafka_topic_conf_set_opaque(tctx->conf, tctx);
- snprintf(callback_name, sizeof(callback_name), "write_kafka/%s",
- tctx->topic_name);
+ ssnprintf(callback_name, sizeof(callback_name), "write_kafka/%s",
+ tctx->topic_name);
- status = plugin_register_write(
- callback_name, kafka_write,
- &(user_data_t){
- .data = tctx, .free_func = kafka_topic_context_free,
- });
+ 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.",
snprintf(cb_name, sizeof(cb_name), "write_mongodb/%s", node->name);
- status =
- plugin_register_write(cb_name, wm_write,
- &(user_data_t){
- .data = node, .free_func = wm_config_free,
- });
+ 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);
}
#define LABEL_BUFFER_SIZE (LABEL_KEY_SIZE + LABEL_VALUE_SIZE + 4)
char *labels[3] = {
- (char[LABEL_BUFFER_SIZE]){0}, (char[LABEL_BUFFER_SIZE]){0},
+ (char[LABEL_BUFFER_SIZE]){0},
+ (char[LABEL_BUFFER_SIZE]){0},
(char[LABEL_BUFFER_SIZE]){0},
};
* know that they are sane. */
for (size_t i = 0; i < m->n_label; i++) {
char value[LABEL_VALUE_SIZE];
- snprintf(labels[i], LABEL_BUFFER_SIZE, "%s=\"%s\"", m->label[i]->name,
- escape_label_value(value, sizeof(value), m->label[i]->value));
+ ssnprintf(labels[i], LABEL_BUFFER_SIZE, "%s=\"%s\"", m->label[i]->name,
+ escape_label_value(value, sizeof(value), m->label[i]->value));
}
strjoin(buffer, buffer_size, labels, m->n_label, ",");
while (c_avl_iterator_next(iter, (void *)&unused_name, (void *)&fam) == 0) {
char line[1024]; /* 4x DATA_MAX_NAME_LEN? */
- snprintf(line, sizeof(line), "# HELP %s %s\n", fam->name, fam->help);
+ ssnprintf(line, sizeof(line), "# HELP %s %s\n", fam->name, fam->help);
buffer->append(buffer, strlen(line), (uint8_t *)line);
- snprintf(line, sizeof(line), "# TYPE %s %s\n", fam->name,
- (fam->type == IO__PROMETHEUS__CLIENT__METRIC_TYPE__GAUGE)
- ? "gauge"
- : "counter");
+ ssnprintf(line, sizeof(line), "# TYPE %s %s\n", fam->name,
+ (fam->type == IO__PROMETHEUS__CLIENT__METRIC_TYPE__GAUGE)
+ ? "gauge"
+ : "counter");
buffer->append(buffer, strlen(line), (uint8_t *)line);
for (size_t i = 0; i < fam->n_metric; i++) {
char timestamp_ms[24] = "";
if (m->has_timestamp_ms)
- snprintf(timestamp_ms, sizeof(timestamp_ms), " %" PRIi64,
- m->timestamp_ms);
+ ssnprintf(timestamp_ms, sizeof(timestamp_ms), " %" PRIi64,
+ m->timestamp_ms);
if (fam->type == IO__PROMETHEUS__CLIENT__METRIC_TYPE__GAUGE)
- snprintf(line, sizeof(line), "%s{%s} " GAUGE_FORMAT "%s\n", fam->name,
- format_labels(labels, sizeof(labels), m), m->gauge->value,
- timestamp_ms);
+ ssnprintf(line, sizeof(line), "%s{%s} " GAUGE_FORMAT "%s\n", fam->name,
+ format_labels(labels, sizeof(labels), m), m->gauge->value,
+ timestamp_ms);
else /* if (fam->type == IO__PROMETHEUS__CLIENT__METRIC_TYPE__COUNTER) */
- snprintf(line, sizeof(line), "%s{%s} %.0f%s\n", fam->name,
- format_labels(labels, sizeof(labels), m), m->counter->value,
- timestamp_ms);
+ ssnprintf(line, sizeof(line), "%s{%s} %.0f%s\n", fam->name,
+ format_labels(labels, sizeof(labels), m), m->counter->value,
+ timestamp_ms);
buffer->append(buffer, strlen(line), (uint8_t *)line);
}
c_avl_iterator_destroy(iter);
char server[1024];
- snprintf(server, sizeof(server), "\n# collectd/write_prometheus %s at %s\n",
- PACKAGE_VERSION, hostname_g);
+ ssnprintf(server, sizeof(server), "\n# collectd/write_prometheus %s at %s\n",
+ PACKAGE_VERSION, hostname_g);
buffer->append(buffer, strlen(server), (uint8_t *)server);
pthread_mutex_unlock(&metrics_lock);
msg->name = name;
char help[1024];
- snprintf(
+ ssnprintf(
help, sizeof(help),
"write_prometheus plugin: '%s' Type: '%s', Dstype: '%s', Dsname: '%s'",
vl->plugin, vl->type, DS_TYPE_TO_STRING(ds->ds[ds_index].type),
static int prom_open_socket(int addrfamily) {
/* {{{ */
char service[NI_MAXSERV];
- snprintf(service, sizeof(service), "%hu", httpd_port);
+ ssnprintf(service, sizeof(service), "%hu", httpd_port);
struct addrinfo *res;
int status = getaddrinfo(httpd_host, service,
status = FORMAT_VL(ident, sizeof(ident), vl);
if (status != 0)
return status;
- snprintf(key, sizeof(key), "%s%s",
- (node->prefix != NULL) ? node->prefix : REDIS_DEFAULT_PREFIX, ident);
- snprintf(time, sizeof(time), "%.9f", CDTIME_T_TO_DOUBLE(vl->time));
+ ssnprintf(key, sizeof(key), "%s%s",
+ (node->prefix != NULL) ? node->prefix : REDIS_DEFAULT_PREFIX,
+ ident);
+ ssnprintf(time, sizeof(time), "%.9f", CDTIME_T_TO_DOUBLE(vl->time));
value_size = sizeof(value);
value_ptr = &value[0];
if (status == 0) {
char cb_name[sizeof("write_redis/") + DATA_MAX_NAME_LEN];
- snprintf(cb_name, sizeof(cb_name), "write_redis/%s", node->name);
+ ssnprintf(cb_name, sizeof(cb_name), "write_redis/%s", node->name);
- status =
- plugin_register_write(cb_name, wr_write,
- &(user_data_t){
- .data = node, .free_func = wr_config_free,
- });
+ status = plugin_register_write(cb_name, wr_write,
+ &(user_data_t){
+ .data = node,
+ .free_func = wr_config_free,
+ });
}
if (status != 0)
vl->type_instance);
if (host->always_append_ds || (ds->ds_num > 1)) {
if (host->event_service_prefix == NULL)
- snprintf(service_buffer, sizeof(service_buffer), "%s/%s", &name_buffer[1],
- ds->ds[index].name);
+ ssnprintf(service_buffer, sizeof(service_buffer), "%s/%s",
+ &name_buffer[1], ds->ds[index].name);
else
- snprintf(service_buffer, sizeof(service_buffer), "%s%s/%s",
- host->event_service_prefix, &name_buffer[1], ds->ds[index].name);
+ 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
- snprintf(service_buffer, sizeof(service_buffer), "%s%s",
- host->event_service_prefix, &name_buffer[1]);
+ ssnprintf(service_buffer, sizeof(service_buffer), "%s%s",
+ host->event_service_prefix, &name_buffer[1]);
}
riemann_event_set(
if ((ds->ds[index].type != DS_TYPE_GAUGE) && (rates != NULL)) {
char ds_type[DATA_MAX_NAME_LEN];
- snprintf(ds_type, sizeof(ds_type), "%s:rate",
- DS_TYPE_TO_STRING(ds->ds[index].type));
+ 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",
{
char ds_index[DATA_MAX_NAME_LEN];
- snprintf(ds_index, sizeof(ds_index), "%" PRIsz, index);
+ ssnprintf(ds_index, sizeof(ds_index), "%" PRIsz, index);
riemann_event_string_attribute_add(event, "ds_index", ds_index);
}
return status;
}
- snprintf(callback_name, sizeof(callback_name), "write_riemann/%s",
- host->name);
+ ssnprintf(callback_name, sizeof(callback_name), "write_riemann/%s",
+ host->name);
user_data_t ud = {.data = host, .free_func = wrr_free};
return NULL;
}
- status = snprintf(authorization_header, sizeof(authorization_header),
- "Authorization: Bearer %s", access_token);
+ status = ssnprintf(authorization_header, sizeof(authorization_header),
+ "Authorization: Bearer %s", access_token);
if ((status < 1) || ((size_t)status >= sizeof(authorization_header)))
return NULL;
if (err == NULL) {
strncpy(buffer, "Unknown error (API error is NULL)", buffer_size);
} else if (err->message == NULL) {
- snprintf(buffer, buffer_size, "API error %d", err->code);
+ ssnprintf(buffer, buffer_size, "API error %d", err->code);
} else {
- snprintf(buffer, buffer_size, "API error %d: %s", err->code, err->message);
+ ssnprintf(buffer, buffer_size, "API error %d: %s", err->code, err->message);
}
return buffer;
static int wg_call_metricdescriptor_create(wg_callback_t *cb,
char const *payload) {
char url[1024];
- snprintf(url, sizeof(url), "%s/projects/%s/metricDescriptors", cb->url,
- cb->project);
+ ssnprintf(url, sizeof(url), "%s/projects/%s/metricDescriptors", cb->url,
+ cb->project);
wg_memory_t response = {0};
int status = do_post(cb, url, payload, &response);
static int wg_call_timeseries_write(wg_callback_t *cb, char const *payload) {
char url[1024];
- snprintf(url, sizeof(url), "%s/projects/%s/timeSeries", cb->url, cb->project);
+ ssnprintf(url, sizeof(url), "%s/projects/%s/timeSeries", cb->url,
+ cb->project);
wg_memory_t response = {0};
int status = do_post(cb, url, payload, &response);
size_t valuelen = sizeof(value);
int rv;
- snprintf(buffer, sizeof(buffer), "%s%s", zfs_arcstat, name);
+ ssnprintf(buffer, sizeof(buffer), "%s%s", zfs_arcstat, name);
rv = sysctlbyname(buffer, (void *)&value, &valuelen,
/* new value = */ NULL, /* new length = */ (size_t)0);
if (rv == 0)
return -1;
}
- // Ignore the first two lines because they contain information about
- // the rest of the file.
- // See kstat_seq_show_headers module/spl/spl-kstat.c of the spl kernel
- // module.
- if (fgets(buffer, sizeof(buffer), fh) == NULL) {
- ERROR("zfs_arc plugin: \"%s\" does not contain a single line.",
- ZOL_ARCSTATS_FILE);
- fclose(fh);
- return (-1);
- }
- if (fgets(buffer, sizeof(buffer), fh) == NULL) {
- ERROR("zfs_arc plugin: \"%s\" does not contain at least two lines.",
- ZOL_ARCSTATS_FILE);
- fclose(fh);
- return (-1);
- }
-
while (fgets(buffer, sizeof(buffer), fh) != NULL) {
char *fields[3];
value_t v;
za_read_gauge(ksp, "mfu_size", "cache_size", "mfu_size");
za_read_gauge(ksp, "mru_ghost_size", "cache_size", "mru_ghost_size");
za_read_gauge(ksp, "mru_size", "cache_size", "mru_size");
- za_read_gauge(ksp, "other_size", "cache_size", "other_size");
za_read_gauge(ksp, "p", "cache_size", "p");
za_read_gauge(ksp, "size", "cache_size", "arc");
+ /* The "other_size" value was replaced by more specific values in ZFS on Linux
+ * version 0.7.0 (commit 25458cb)
+ */
+ if (za_read_gauge(ksp, "dbuf_size", "cache_size", "dbuf_size") != 0 ||
+ za_read_gauge(ksp, "dnode_size", "cache_size", "dnode_size") != 0 ||
+ za_read_gauge(ksp, "bonus_size", "cache_size", "bonus_size") != 0)
+ za_read_gauge(ksp, "other_size", "cache_size", "other_size");
+
/* The "l2_size" value has disappeared from Solaris some time in
* early 2013, and has only reappeared recently in Solaris 11.2.
* Stop trying if we ever fail to read it, so we don't spam the log.
#!/bin/sh
-DEFAULT_VERSION="5.8.1.git"
+DEFAULT_VERSION="5.9.2.git"
if [ -d .git ]; then
VERSION="`git describe --dirty=+ --abbrev=7 2> /dev/null | grep collectd | sed -e 's/^collectd-//' -e 's/-/./g'`"