diff --git a/.cirrus.yml b/.cirrus.yml new file mode 100644 index 0000000000..ab88daf640 --- /dev/null +++ b/.cirrus.yml @@ -0,0 +1,225 @@ +env: + LANG: C + CIRRUS_CLONE_DEPTH: 1 + DEFAULT_CONFIG_OPTS: --enable-debug --without-libstatgrab --disable-dependency-tracking + + +### +# make distcheck and other sanity checks +# +release_ready_task: + container: + image: collectd/ci:stretch_amd64 + lint_script: + - /checks/check-bashisms.sh + - /checks/check-pod.sh + configure_script: + - ./build.sh + - ./configure $DEFAULT_CONFIG_OPTS + checks_script: + - make -j2 -s distcheck DISTCHECK_CONFIGURE_FLAGS="${DEFAULT_CONFIG_OPTS}" + +### +# Default toolchain and build flags used in deb packages, on a range of Debian +# and Ubuntu releases (+ Debian/unstable) +# Most should succeed, and PRs shouldn't break them. +# +debian_default_toolchain_task: + matrix: + - allow_failures: false + container: + image: collectd/ci:jessie_amd64 + - allow_failures: false + container: + image: collectd/ci:stretch_amd64 + - allow_failures: false + container: + image: collectd/ci:stretch_i386 + - allow_failures: false + container: + image: collectd/ci:trusty_amd64 + - allow_failures: false + container: + image: collectd/ci:xenial_amd64 + # debian/unstable is expected to fail + - allow_failures: true + skip_notifications: true + only_if: $CIRRUS_BRANCH == 'master' + container: + image: collectd/ci:sid_amd64 + configure_script: + - ./build.sh + - gcc --version + - > + ./configure CC=gcc $DEFAULT_CONFIG_OPTS + CFLAGS="$(dpkg-buildflags --get CFLAGS)" + CPPLAGS="$(dpkg-buildflags --get CPPFLAGS)" + LDFLAGS="$(dpkg-buildflags --get LDFLAGS)" + build_script: + - make -j2 -sk + tests_script: + - make -j2 -sk check + - /checks/check-built-plugins.sh + +### +# Default toolchain and build flags used in RPM packages, on a range of RedHat +# and Fedora releases (+ Fedora/rawhide) +# Most should succeed, and PRs shouldn't break them. +# +redhat_default_toolchain_task: + matrix: + - allow_failures: false + skip_notifications: false + container: + image: collectd/ci:el6_x86_64 + - allow_failures: true + skip_notifications: true + container: + image: collectd/ci:el7_x86_64 # TODO: fix this platform + - allow_failures: true + skip_notifications: true + container: + image: collectd/ci:fedora28_x86_64 + # fedora/rawhide is expected to fail + - allow_failures: true + skip_notifications: true + only_if: $CIRRUS_BRANCH == 'master' + container: + image: collectd/ci:fedora_rawhide_x86_64 + configure_script: + - ./build.sh + - gcc --version + - ./configure CC=gcc $DEFAULT_CONFIG_OPTS CFLAGS="$(rpm --eval '%optflags')" + build_script: + - make -j2 -sk + tests_script: + - make -j2 -sk check + - /checks/check-built-plugins.sh + + +### +# Misc non-standard build environment & options on most recent released debian +# version. +# Some are expected to fail, others should always pass +non_standard_toolchains_task: + container: + image: collectd/ci:stretch_amd64 + only_if: $CIRRUS_PR == '' + + matrix: + + # build using clang with default build flags, should always pass + - env: + LABEL: clang + allow_failures: true # TODO: fix this platform + skip_notifications: true + configure_script: + - ./build.sh + - clang --version + - > + ./configure CC=clang CXX=clang++ + $DEFAULT_CONFIG_OPTS + CFLAGS="$(dpkg-buildflags --get CFLAGS)" + CPPLAGS="$(dpkg-buildflags --get CPPFLAGS)" + LDFLAGS="$(dpkg-buildflags --get LDFLAGS)" + build_script: + - make -j2 -sk + tests_script: + - make -j2 -sk check + + # build against libstatgrab, should always pass + - env: + LABEL: statgrab + allow_failures: false + skip_notifications: false + configure_script: + - ./build.sh + - gcc --version + - > + ./configure --with-libstatgrab --enable-debug + CFLAGS="$(dpkg-buildflags --get CFLAGS)" + CPPLAGS="$(dpkg-buildflags --get CPPFLAGS)" + LDFLAGS="$(dpkg-buildflags --get LDFLAGS)" + build_script: + - make -j2 -sk + tests_script: + - > + for i in cpu disk interface load memory swap users; do + if ! $(ldd ".libs/${i}.so" 2>/dev/null | grep -q 'libstatgrab.so'); then + echo "plugin $i NOT linked against libstatgrab" + exit 1 + fi + done + + # build using clang with a collection of strict build flags, will most + # probably always fail + - env: + LABEL: clang strict + allow_failures: true + skip_notifications: true + configure_script: + - ./build.sh + - clang --version + - > + ./configure CC=clang CXX=clang++ + $DEFAULT_CONFIG_OPTS + CFLAGS='-Wall + -Wno-error + -Wextra + -Wformat=2 + -Wformat-security + -Wformat-nonliteral + -Wmissing-include-dirs + -Wold-style-definition + -Wpointer-arith + -Winit-self + -Wmissing-prototypes + -Wimplicit-function-declaration + -Wmissing-declarations + -Wstrict-prototypes + -Wmissing-noreturn + -Wshadow + -Wendif-labels + -Wwrite-strings + -Wno-unused-parameter + -Wno-missing-field-initializers + -Wdate-time + -Wnested-externs + -Wno-typedef-redefinition + -Wno-gnu-variable-sized-type-not-at-end' + build_script: + - make -j2 -sk + tests_script: + - make -j2 -sk check + +### +# Build using a range of compilers, available in debian/unstable. NB: might +# fail because of changes to the distro, not the compiler used. +# +bleeding_edge_compilers_task: + container: + image: collectd/ci:sid_amd64 + only_if: $CIRRUS_BRANCH == 'master' + allow_failures: true + skip_notifications: true + env: + matrix: + CC: gcc-7 + CC: gcc-8 + CC: clang-6.0 + CC: clang-7 + CC: clang-8 + CC: clang-9 + configure_script: + - ./build.sh + - $CC --version + - > + ./configure CC=$CC + $DEFAULT_CONFIG_OPTS + CFLAGS="$(dpkg-buildflags --get CFLAGS)" + CPPLAGS="$(dpkg-buildflags --get CPPFLAGS)" + LDFLAGS="$(dpkg-buildflags --get LDFLAGS)" + build_script: + - make -j2 -sk + tests_script: + - make -j2 -sk check diff --git a/.clang-format b/.clang-format new file mode 100644 index 0000000000..70f50ad590 --- /dev/null +++ b/.clang-format @@ -0,0 +1,5 @@ +--- +BasedOnStyle: LLVM +IncludeCategories: + - Regex: '"collectd.h"' + - Priority: -1 diff --git a/.github/issue_template.md b/.github/issue_template.md new file mode 100644 index 0000000000..05d2987537 --- /dev/null +++ b/.github/issue_template.md @@ -0,0 +1,17 @@ +* Version of collectd: +* Operating system / distribution: +* Kernel version (if applicable): + +## Expected behavior + +(Description of the behavior / output that you expected) + +## Actual behavior + +(Description of the behavior / output that you observed) + +## Steps to reproduce + +* step 1 +* step 2 +* step 3 diff --git a/.gitignore b/.gitignore index 7c7c848fab..afdbe5cd03 100644 --- a/.gitignore +++ b/.gitignore @@ -4,6 +4,7 @@ Makefile.in /aclocal.m4 /autom4te.cache /autom4te.cache +/build-aux/ /compile /config.guess /config.sub @@ -12,15 +13,21 @@ Makefile.in /install-sh /libltdl/ /ltmain.sh +/m4/libtool.m4 +/m4/ltargz.m4 +/m4/ltdl.m4 +/m4/lt~obsolete.m4 +/m4/ltoptions.m4 +/m4/ltsugar.m4 +/m4/ltversion.m4 /missing -src/config.h.in +/src/config.h.in # configure stuff: Makefile config.log config.status libtool -src/.deps src/collectd.conf src/config.h src/libcollectdclient/libcollectdclient.pc @@ -30,14 +37,16 @@ src/stamp-h1 *.la *.lo *.o +.dirstamp .libs/ -src/collectd -src/collectd-nagios -src/collectd-tg -src/collectdctl -src/collectdmon +.deps/ +/collectd-nagios +/collectd-tg +/collectdctl +/collectdmon src/*.1 src/*.5 +src/.pod2man.tmp.* src/libcollectdclient/collectd/lcc_features.h # patch stuff @@ -51,28 +60,48 @@ src/liboconfig/parser.h src/liboconfig/scanner.c # protobuf stuff: -src/*.pb-c.[ch] +*.pb-c.[ch] +*.grpc.pb.cc +*.pb.cc +*.pb.h # make dist stuff: /collectd-*.tar.gz /collectd-*.tar.bz2 # perl stuff: -bindings/.perl-directory-stamp +/.perl-directory-stamp bindings/perl/Collectd/pm_to_blib bindings/perl/blib/ bindings/perl/pm_to_blib +/buildperl # java stuff -bindings/java/java-build-stamp -bindings/java/org/collectd/api/*.class -bindings/java/org/collectd/java/*.class +*.jar +/org/collectd/api/*.class +/org/collectd/java/*.class +/bindings/java/java-build-stamp +/classnoinst.stamp # python stuff *.pyc -# tag stuff -src/tags - # backup stuff *~ + +# lint stuff +*.ln + +#ide stuff +.vscode + +# cscope stuff +cscope.* + +# Unit tests +test-suite.log +src/tests/ +test_* + +# src/daemon/... +/collectd diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000000..009ae439e1 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "gnulib"] + path = gnulib + url = git://git.savannah.gnu.org/gnulib.git diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000000..ca25dee957 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,146 @@ +# Travis CI configuration file +# https://travis-ci.org/collectd/collectd +language: c + +env: + global: + - MAKEFLAGS="-j 2" + # The next declaration is the encrypted COVERITY_SCAN_TOKEN, created + # via the "travis encrypt" command using the project repo's public key + - secure: "ZdWWp0XX3C4sLIp4lqeQTWC7vt+GsWjmyRiD17T9833NBAW4dddz310I6iyeXe6oX09ZFFiVIN4ogx9ANcNBx9jriGXI2/82nBhpxOJBebet8JCNS5VeTr4rDSfQOKP+Oc+ko5KbbghTuAtO2CFYiH3jZUcn4TdsYbVanf+TwUs=" + +matrix: + include: + - os: osx + 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: bionic + compiler: clang + jdk: openjdk10 + - os: linux + dist: bionic + 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. + - if [[ "${TRAVIS_BRANCH}" == "coverity_scan" && ! "${TRAVIS_JOB_NUMBER}" =~ \.1$ ]]; then exit 0; fi + +before_script: autoreconf -vif + +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: + apt: + packages: + - autotools-dev + - iptables-dev + - libatasmart-dev + - libcap-dev + - libcurl4-gnutls-dev + - libdbi0-dev + - libesmtp-dev + - libganglia1-dev + - libgcrypt11-dev + - libglib2.0-dev + - libgps-dev + - libhiredis-dev + - libi2c-dev + - libldap2-dev + - libltdl-dev + - liblua50-dev + - liblua5.1-0-dev + - liblua5.2-dev + - libmemcached-dev + - libmicrohttpd-dev + - libmnl-dev + - libmodbus-dev + - libmosquitto-dev + - libmysqlclient-dev + - libnotify-dev + - libopenipmi-dev + - liboping-dev + - libow-dev + - libpcap-dev + - libperl-dev + - libpq-dev + - libprotobuf-c0-dev + - librabbitmq-dev + - librdkafka-dev + - libriemann-client-dev + - librrd-dev + - libsensors4-dev + - libsigrok-dev + - libsnmp-dev + - libtokyocabinet-dev + - libtokyotyrant-dev + - libudev-dev + - libupsclient-dev + - libvarnish-dev + - libvirt-dev + - libxen-dev + - libxml2-dev + - libyajl-dev + - linux-libc-dev + - perl + - protobuf-c-compiler + - python3-dev + - python-dev + - xfslibs-dev + coverity_scan: + project: + name: "collectd/collectd" + description: "Build submitted via Travis CI" + notification_email: collectd-changes@verplant.org + build_command_prepend: "./configure; make clean" + build_command: "make -j $(nproc)" + branch_pattern: coverity_scan + homebrew: + packages: + - curl + - glib + - hiredis + - libdbi + - libmemcached + - libmicrohttpd + - libmodbus + - libnotify + - liboping + - libpcap + - librdkafka + - libvirt + - libxml2 + - lua + - mongo-c-driver + - mosquitto + - mysql-client + - net-snmp + - openldap + - perl + - protobuf + - protobuf-c + - python + - qpid-proton + - rabbitmq-c + - riemann-client + - rrdtool + - tokyo-cabinet + - varnish + - yajl + +git: + quiet: true + submodules: false + depth: 1 diff --git a/AUTHORS b/AUTHORS index 31d132fbfa..c1fa48d6e9 100644 --- a/AUTHORS +++ b/AUTHORS @@ -4,9 +4,34 @@ Permanent project members Florian "octo" Forster - Initial author. +Marc Fournier + - Various fixes to the varnish plugin. + - RPM specfile maintenance. + - libmnl support in the netlink plugin. + - linux support in the zfs_arc plugin. + - openldap plugin. + - continuous integration system. + +Matthias Runge + - general house keeping. + +Pierre-Yves Ritschard + - Write-Riemann plugin. + - Write-Graphite plugin: Notification support. + - Write-Kafka plugin. + - Log-Logstash plugin. + - Normalization in the CPU plugin. + - Relative values in the Load plugin. + +Ruben Kerkhof + - Bugfixes and enhancements in many places all around the project. + - Fedora and EPEL packages. + Sebastian "tokkee" Harl - - Bugfixes and enhancments in many places all around the project. + - Bugfixes and enhancements in many places all around the project. + - grpc plugin. - perl plugin. + - postgresql plugin. - users plugin. - vserver plugin. - Debian package. @@ -15,6 +40,10 @@ Sebastian "tokkee" Harl Contributors (sorted alphabetically) ==================================== +Adrian Boczkowski + - Logparser plugin. + - Redfish plugin. + Akkarit Sangpetch - write_mongodb plugin. @@ -34,6 +63,24 @@ Amit Gupta Andreas Henriksson - libmnl support in the netlink plugin. +Andrew Bays + - connectivity plugin. + - procevent plugin. + - sysevent plugin. + - connectivity plugin. + +Andy Parkins + - battery plugin: sysfs code. + +Aneesh Puttur + - connectivity plugin. + +Andy Smith + - AMQP 1.0 plugin. + +Aneesh Puttur + - connectivity plugin. + Anthony Dewhurst - zfs_arc plugin. @@ -43,22 +90,37 @@ Anthony Gialluca Antony Dovgal - memcached plugin. +Asaf Kahlon + - buddyinfo plugin + Aurélien Reynaud - LPAR plugin. - Various fixes for AIX, HP-UX and Solaris. +Benjamin Gilbert + - Improvements to the LVM plugin. + Bert Vermeulen - sigrok plugin +Brett Hawn + - write_tsdb plugin for http://opentsdb.net/ + Bruno Prémont - BIND plugin. - - Many bugreports and -fixes in various plugins, + - Many bug reports and -fixes in various plugins, especially a nasty bug in the network plugin. - Wireshark dissector. +Carlos Peon Costa + - Write_Influxdb_UDP plugin + Chad Malfait - LVM plugin. +Chris Brown + - Zookeeper plugin, add quorum stat. + Chris Lundquist - Improvements to the write_mongodb plugin. @@ -66,15 +128,33 @@ Christophe Kalt - The version 3 `log' mode. - Many Solaris related hints and fixes. +Claudius Zingerli + - chrony plugin. + Cyril Feraudet - ethstat plugin. +Dagobert Michelsen + - zone plugin. + - Many Solaris related hints and fixes. + - Capabilities plugin. + - NFS plugin for BSD + Dan Berrange - uuid plugin. +Dan Ryder + - ceph plugin. + David Bacher - serial plugin. +Denis Pompilio + - Improvements to the write_http plugin. + +Dheeraj Gupta + - Tail_CSV plugin, field separator option + Doug MacEachern - The `-T' option (config testing mode). - OpenVPN plugin. @@ -82,6 +162,9 @@ Doug MacEachern - A few other patches to various plugins. - curl_json plugin. +Edgar Fuß + - NFS plugin implementation on NetBSD + Edward “Koko” Konetzko - fscache plugin. @@ -94,24 +177,59 @@ Fabian Linzberger Fabien Wernli - Solaris improvements in the memory and interfaces plugin. +Fabrice A. Marie + - write_sensu plugin. + Flavio Stanchina - mbmon plugin. Franck Lombardi - UNIX socket code for the memcached plugin. +Gergely Nagy + - Write-Riemann plugin. + +Hari TG + - dcpmm plugin. + Jason Pepas - nfs plugin. J. Javier Maestro - Write-Graphite plugin: UDP support and LogSendErrors flag. +Jeremy Katz + - percentage reporting in memory and swap plugins. + - zookeeper plugin. + Jérôme Renard - varnish plugin. +Jiri Tyr + - fhcount plugin. + +Julien Ammous + - Lua plugin. + +Kamil Wiatrowski + - Capabilities plugin. + - Logparser plugin. + +Kevin Bowling + - write_tsdb plugin for http://opentsdb.net/ + +Kimo Rosenbaum + - openldap plugin. + Kris Nielander - tail_csv plugin. +Krzysztof Kepka + - Redfish plugin. + +Krzysztof Matczak + - Logparser plugin. + Luboš Staněk - sensors plugin improvements. - Time and effort to find a nasty bug in the ntpd-plugin. @@ -123,6 +241,9 @@ Luke Herberling Lyonel Vincent - processes plugin. +Man Singh + - Redfish plugin. + Manuel Sanmartin - AIX port of the following plugins: + cpu @@ -134,23 +255,34 @@ Manuel Sanmartin + swap - Various AIX-related fixes and hacks. -Marc Fournier - - Various fixes to the varnish plugin. - - RPM specfile update. - - libmnl support in the netlink plugin. +Marcin Mozejko + - Logparser plugin. + - Redfish plugin. Marco Chiappero - uptime plugin. - ip6tables support in the iptables plugin. - openvpn plugin (support for more status file formats) +Märt Bakhof + - TLS support for AMQP plugin + +Mathijs Möhlmann + - zone plugin. + Michael Hanselmann - md plugin. +Michael Schenck + - IO time support to disk plugin. + Michael Stapelberg - OpenBSD port of the tcpconns plugin. - cgroups plugin. +Michal Kobylinski + - Redfish plugin. + Michał Mirosław - thermal plugin. - Streamlines recursive directory traversion. @@ -158,6 +290,9 @@ Michał Mirosław Mirko Buffoni - Port/Socket selection in the MySQL plugin. +Nicolas Jourden + - gps plugin. + Niki W. Waibel - Initial autotools fixes. - libltdl code. @@ -172,6 +307,10 @@ Oleg King Ondrej Zajicek - madwifi plugin. +Pablo Llopis + - Slurm plugin + - RestoreAffinityPolicy in turbostat plugin + Patrik Weiskircher - Contextswitch plugin. - Forkrate counter in the processes plugin. @@ -182,6 +321,10 @@ Paul Sadauskas - `ReportByDevice' option of the df plugin. - write_http plugin. +Pavel Rochnyack + - xencpu plugin. + - Bugfixes and enhancements in many places all around the project. + Peter Holik - cpufreq plugin. - multimeter plugin. @@ -189,18 +332,23 @@ Peter Holik - Some bugfixes in the exec plugin. - Notifications in the ipmi plugin. +Pierre Lebleu + - UBI plugin. + Phoenix Kayo - pinba plugin. -Pierre-Yves Ritschard - - Write-Riemann plugin. - - Write-Graphite plugin: Notification support. - Piotr Hosowicz - SMF manifest for collectd. +Radoslaw Jablonski + - Logparser plugin. + +Reshma Pattan + - DPDK Telemetry plugin. + Richard W. M. Jones - - libvirt plugin. + - virt plugin. - uuid plugin. Roman Klesel @@ -216,7 +364,15 @@ Scott Sanders - Write-Graphite plugin. Sebastien Pahl - - AMQP plugin. + - AMQP 0.9 plugin. + +Serhiy Pshyk + - intel_pmu plugin + - intel_rdt plugin + - snmp_agent plugin + +Shirly Radco + - write_syslog plugin. Simon Kuhnle - OpenBSD code for the cpu and memory plugins. @@ -227,10 +383,19 @@ Sjoerd van der Berg Stefan Hacker - teamspeak2 plugin. +Steven Bell + - nut plugin. + Sven Trenkel - netapp plugin. - python plugin. +Takuro Ashie + - Network plugin fixes. + +Tim Laszlo + - drbd plugin. + Thomas Meson - Graphite support for the AMQP plugin. @@ -240,12 +405,24 @@ Tomasz Pala Tommie Gannert - PID-file patch. +Vincent Bernat + - smart plugin. + +Vincent Brillault + - turbostat plugin, based on Len Brown kernel tool + Vincent Stehlé - hddtemp plugin. +Wilfried Goesgens + - linux support in the zfs_arc plugin. + Xin Li - FreeBSD port of the ZFS-ARC plugin. +Zoltan Szabo + - Redfish plugin. + collectd is available at: diff --git a/CODEOWNERS b/CODEOWNERS new file mode 100644 index 0000000000..f60ab20ba5 --- /dev/null +++ b/CODEOWNERS @@ -0,0 +1,46 @@ +# Code ownership information. +# See +# https://help.github.com/en/github/creating-cloning-and-archiving-repositories/about-code-owners +# for details. + +# Order is important; the *last* matching pattern takes precedence. + +# Default +# +# These owners will be the default owners for everything in the repo. Unless a +# later match takes precedence, @collectd/trusted-contributors will be +# requested for review when someone opens a pull request. +* @collectd/trusted-contributors + +# Per-plugin owners +# +# These plugins are owned by subject matter experts and require their review. +/src/intel_pmu.c @collectd/intel +/src/intel_rdt.c @collectd/intel +/src/ipmi.c @collectd/intel +/src/mcelog.c @collectd/intel +/src/virt.c @collectd/intel +# TODO(#2926): Add the following owners: +#/src/redfish.c @collectd/intel + +# Core +# +# The daemon and some plugins with a huge "blast radius" are considered "core" +# to the collectd project and require review form a "core owner". +/CODEOWNERS @collectd/core-maintainers +/src/daemon/ @collectd/core-maintainers +/src/liboconfig/ @collectd/core-maintainers +/src/cpu.c @collectd/core-maintainers +/src/df.c @collectd/core-maintainers +/src/disk.c @collectd/core-maintainers +/src/exec.c @collectd/core-maintainers +/src/interface.c @collectd/core-maintainers +/src/memory.c @collectd/core-maintainers +/src/network.* @collectd/core-maintainers +/src/utils/avltree/ @collectd/core-maintainers +/src/utils/common/ @collectd/core-maintainers +/src/utils_fbhash.* @collectd/core-maintainers +/src/utils/heap/ @collectd/core-maintainers +/src/utils/ignorelist/ @collectd/core-maintainers +/src/utils/metadata/ @collectd/core-maintainers +/src/utils/mount/ @collectd/core-maintainers diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md new file mode 100644 index 0000000000..aca1ed8a4e --- /dev/null +++ b/CODE_OF_CONDUCT.md @@ -0,0 +1,139 @@ +# Code of Conduct + +Contributor Covenant 2.0 + +## Our Pledge + +We as members, contributors, and leaders pledge to make participation in our +community a harassment-free experience for everyone, regardless of age, body +size, visible or invisible disability, ethnicity, sex characteristics, gender +identity and expression, level of experience, education, socio-economic status, +nationality, personal appearance, race, religion, or sexual identity +and orientation. + +We pledge to act and interact in ways that contribute to an open, welcoming, +diverse, inclusive, and healthy community. + +## Our Standards + +Examples of behavior that contributes to a positive environment for our +community include: + +* Demonstrating empathy and kindness toward other people +* Being respectful of differing opinions, viewpoints, and experiences +* Giving and gracefully accepting constructive feedback +* Accepting responsibility and apologizing to those affected by our mistakes, + and learning from the experience +* Focusing on what is best not just for us as individuals, but for the + overall community + +Examples of unacceptable behavior include: + +* The use of sexualized language or imagery, and sexual attention or + advances of any kind +* Trolling, insulting or derogatory comments, and personal or political attacks +* Public or private harassment +* Publishing others' private information, such as a physical or email + address, without their explicit permission +* Other conduct which could reasonably be considered inappropriate in a + professional setting + +## Enforcement Responsibilities + +Community leaders are responsible for clarifying and enforcing our standards of +acceptable behavior and will take appropriate and fair corrective action in +response to any behavior that they deem inappropriate, threatening, offensive, +or harmful. + +Community leaders have the right and responsibility to remove, edit, or reject +comments, commits, code, wiki edits, issues, and other contributions that are +not aligned to this Code of Conduct, and will communicate reasons for moderation +decisions when appropriate. + +## Scope + +This Code of Conduct applies within all community spaces, and also applies when +an individual is officially representing the community in public spaces. +Examples of representing our community include using an official e-mail address, +posting via an official social media account, or acting as an appointed +representative at an online or offline event. + +## Enforcement + +Instances of abusive, harassing, or otherwise unacceptable behavior may be +reported to the community leaders responsible for enforcement. Currently +responsible are: + +* Florian Forster <octo at collectd.org> +* Kinga Grabarczyk <kinga.grabarczyk at intel.com> +* Nikolay Tsvetkov <n.tsvetkov at cern.ch> +* Sunku Ranganath <sunku.ranganath at intel.com> + +You can reach this group by sending an email to: +<conduct at collectd.org>. +All complaints will be reviewed and investigated promptly and fairly. + +All community leaders are obligated to respect the privacy and security of the +reporter of any incident. + +## Enforcement Guidelines + +Community leaders will follow these Community Impact Guidelines in determining +the consequences for any action they deem in violation of this Code of Conduct: + +### 1. Correction + +**Community Impact**: Use of inappropriate language or other behavior deemed +unprofessional or unwelcome in the community. + +**Consequence**: A private, written warning from community leaders, providing +clarity around the nature of the violation and an explanation of why the +behavior was inappropriate. A public apology may be requested. + +### 2. Warning + +**Community Impact**: A violation through a single incident or series +of actions. + +**Consequence**: A warning with consequences for continued behavior. No +interaction with the people involved, including unsolicited interaction with +those enforcing the Code of Conduct, for a specified period of time. This +includes avoiding interactions in community spaces as well as external channels +like social media. Violating these terms may lead to a temporary or +permanent ban. + +### 3. Temporary Ban + +**Community Impact**: A serious violation of community standards, including +sustained inappropriate behavior. + +**Consequence**: A temporary ban from any sort of interaction or public +communication with the community for a specified period of time. No public or +private interaction with the people involved, including unsolicited interaction +with those enforcing the Code of Conduct, is allowed during this period. +Violating these terms may lead to a permanent ban. + +### 4. Permanent Ban + +**Community Impact**: Demonstrating a pattern of violation of community +standards, including sustained inappropriate behavior, harassment of an +individual, or aggression toward or disparagement of classes of individuals. + +**Consequence**: A permanent ban from any sort of public interaction within +the community. + +## Attribution + +This Code of Conduct is adapted from the [Contributor Covenant][homepage], +version 2.0, available at +https://www.contributor-covenant.org/version/2/0/code_of_conduct.html. + +Community Impact Guidelines were inspired by [Mozilla's code of conduct +enforcement ladder](https://github.com/mozilla/diversity). + +[homepage]: https://www.contributor-covenant.org + +For answers to common questions about this code of conduct, see the FAQ at +https://www.contributor-covenant.org/faq. Translations are available at +https://www.contributor-covenant.org/translations. + diff --git a/COPYING b/COPYING index d511905c16..191af71e05 100644 --- a/COPYING +++ b/COPYING @@ -1,3 +1,35 @@ +collectd consists of a daemon and numerous plugins. The daemon is licensed +under the "MIT License"; its source files are located at src/daemon/. The +plugins are licenses individually, please check the top of the plugin's source +file(s) to see which license applies. The majority of plugins is licensed +either under the "MIT License" or the "GNU General Public License". + +The "MIT License" and "GNU General Public License" follow. Other licenses, not +included in this file, should be considered "as published by the Open Source +Initiative (OSI)". + +MIT License +=========== +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. + +GNU General Public License (GPL) +================================ GNU GENERAL PUBLIC LICENSE Version 2, June 1991 diff --git a/ChangeLog b/ChangeLog index 3c8128a8f9..ff4283467d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,1892 @@ +2020-03-15, Version 5.11.0 + * collectd: A Code of Conduct has been added. Thanks to Florian Forster. + #3401 + * text protocol: Support for meta_data in PUTVAL has been added. Thanks + to Rafael Marinheiro, Dagobert Michelsen. #3381, #2726 + * utils_cache: Internal API has changed - exposed meta_data_toc + function. Thanks to Javier Kohen. #3339 + * filter_chain: Auto load matches and targets if AutoLoadPlugin option + is set. Thanks to Manuel Luis Sanmartín Rozada. #1034 + * AMQP plugin: TLS support has been added. Thanks to Märt Bakhoff. + #3391 + * Battery plugin: Read from Linux sysfs charge files has been added. + Thanks to Nimrod Maclomhair. #3190 + * Buddyinfo plugin: New plugin for memory fragmentation info has been + added. Thanks to Asaf Kahlon. #3303 + * capabilities plugin: New plugin to read static platform data has been + added. Thanks to Kamil Wiatrowski, Dagobert Michelsen. #3384, #3292 + * DCPMM plugin: New plugin for Intel Optane DC Presistent Memory (DCPMM) + has been added. Thanks to Hari TG. #3274 + * DF plugin: LogOnce option has been added. Thanks to themylogin. #2910 + * DPDK Telemetry plugin: New plugin to fetch DPDK metrics (with intent + to replace dpdk_stat) has been added. Thanks to Reshma Pattan. #3273 + * Disk plugin: A native (sysctl-based) implementation for NetBSD has + been added. Thanks to Edgar Fuß, Dagobert Michelsen. #3379, #3334 + * GPU_Nvidia‏‎ plugin: Configurable plugin instance by GPU name + and/or GPU index has been added. Thanks to Robert Dietrich. #3264 + * Intel_PMU plugin: Support for uncore multi pmu has been added. Thanks + to Kamil Wiatrowski. #3388 + * Ipstats plugin: New plugin to count incoming, outgoing, forwarded + packets on FreeBSD has been added. Thanks to Marco van Tol. #3187 + * Java plugin: Support boolean input has been added. Thanks to Caden. + #3044 + * Logparser plugin: New plugin for filtering and parsing log messages + has been added. Thanks to Kamil Wiatrowski, Krzysztof Matczak, Marcin + Możejko, Adrian Boczkowski, Radosław Jabłonski. #3045 + * Network plugin: New metadata "network:ip_address" has been added. + Thanks to Takuro Ashie. #3191 + * NFS plugin: An implementation for NetBSD (using sysctl) has been + added. Thanks to Edgar Fuß, Dagobert Michelsen. #3377, #3333 + * NUT plugin: Support for the "output.realpower" value from the ups code + has been added. Thanks to Michael Poetters. #2528 + * Redfish plugin: New read plugin to collect out-of-band sensor data + from Redfish endpoints has been added. Thanks to Marcin Możejko, + Adrian Boczkowski, Michal Kobyliński, Krzysztof Kepka, Man Singh, + Zoltan Szabo. #2926 + * Slurm plugin: The new SLURM plugin gathers metrics from the SLURM + workload manager has been added. Thanks to Pablo Llopis. #3037 + * Tail_CSV plugin: FieldSeparator option has been added. Thanks to + Dheeraj Gupta. #3394 + * UBI plugin: The new "ubifs" plugin reports block state for flash + memory devices with UBIFS filesystem has been added. Thanks to Pierre + Lebleu. #3204 + * Write_HTTP plugin: Ability to configure cURL statistics has been + added. Thanks to Nelson. #3265 + * Write_Influxdb_UDP plugin: New plugin to send values to InfluxDB using + line protocol via udp has been added. Thanks to Carlos Peón Costa. + #3162 + * Zookeeper plugin: 'quorum' stat has been added. Thanks to Chris Brown. + #2991 + * collectd: Missing package in specfile has been fixed. Thanks to Fabien + Wernli. #3399 + * collectd: Factored out read_text_file_contents for reading text files + and used it to fix a potential unterminated string in the thermal + plugin. Thanks to Igor Peshansky. #3359 + * collectd: Error/warning messages has been extended with more + information. Thanks to Dagobert Michelsen. #3386 + * collectd: Regression caused by #3217 has been fixed. Thanks to Pavel + Rochnyak. #3349 + * build: version-gen.sh has been cleaned up. Thanks to William Pursell. + #2635 + * build: Linking with Python 3.8 has been fixed. Thanks to Alexander + Meshcheryakov. #3344 + * build: Avoid $< (implied source) in non-inference rules / Building + grpc with non-GNU make has been fixed. Thanks to Edgar Fuß, Dagobert + Michelsen. #3376, #3330 + * filter_chain: Constant for max plugin name length introduced in #1034 + has been fixed. Thanks to Dagobert Michelsen. #3385 + * ignorelist: Coding style has been fixed. Thanks to Dagobert Michelsen. + #3397 + * match_regex: Accept all data types of meta data. Thanks to Takuro + Ashie. #3231 + * perl unixsock: Made the module robust against socket errors and + disconnects. Thanks to Guillem Jover. #3083 + * tree-wide: Race condition when setting thread names has been fixed. + Thanks to Michael Kaufmann. #2762 + * types.db: ping_droprate range spec has been fixed. Thanks to Yousong + Zhou. #3244 + * utils/format_graphite: Comma sign has been added to the list of + prohibited characters. Thanks to Marat Salimzianov. #2998 + * Aggregation plugin: Unreachable clause where both tmp_plugin and + tmp_plugin_instance are non-empty has been fixed. Thanks to Ling + Huang. #3350 + * AMQP1 plugin: Leaks on error paths has been fixed. Thanks to Ryan + McCabe. #3352 + * Apache plugin: BusyWorkers/IdleWorkers update has been fixed. Thanks + to Christian W. Zuckschwerdt. #3131 + * CPU plugin, Memory plugin, Swap plugin, UUID plugin: Contain use of + sysctl / sysctrlbyname to BSD variants, as deprecated on Linux. Thanks + to Zebity Spring. #3342 + * Exec plugin: Select has been replaced with poll to allow more then + 1024 open file descriptors. Thanks to Kamil Wiatrowski. #3363 + * GPU_Nvidia plugin: Build issues has been fixed. Thanks to Ruben + Kerkhof. #3393 + * Interface plugin: Reorder so that Linux-specific code is actually + executed. Thanks to Dagobert Michelsen. #3378 + * NFS plugin: Condition on existence of libkstat has been fixed. Thanks + to Dagobert Michelsen. #3382 + * Network plugin: Memory leak has been fixed. Thanks to Ryan McCabe. + #3352 + * Processes plugin: Number of running processes has been fixed. Thanks + to Bart De Vos. #3243 + * Write_Riemann plugin: Memory leak has been fixed. Thanks to Fabien + Wernli. #3351 + * Write_Stackdriver plugin: NaN value handing with gauge metrics has + been fixed. Thanks to Jaroslaw Przybylowicz. #3226 + + +2019-10-17, Version 5.10.0 + * turbostat plugin: Power metrics update for recent server CPUs. Thanks + to Chris MacNamara. #3276 + * turbostat plugin: Fix warnings generated by the turbostat plugin. + Thanks to Ryan Mccabe. #3340 + * ZFS ARC plugin: New cache values are now read on Linux. Thanks to + Jan-Philipp Litza. #3247, #2843 + * connectivity plugin: monitor the network interface up/down status via + the netlink library. Thanks to Andrew Bays. #2622 + * sysevent plugin: A new plugin that monitors rsyslog for system events. + Thanks to Andrew Bays. #2624 + * procevent plugin: A new plugin that monitors process starts/stops via + netlink library. Thanks to Andrew Bays. #2623 + * daemon: Check if plugin actually loaded before reporting configuration + issues. Thanks to Pavel Rochnyak. #3217 + * daemon: Recover setlocale() call in src/daemon/collectd.c do_init(). + Thanks to Pavel Rochnyak. #3181, #3214 + * Build System: Only include when needed. Thanks to Ruben + Kerkhof. #3298 + * Build System: Link to libnsl.so if needed for inet_ntop(). Thanks to + Dagobert Michelsen. #3291 + * Build System: Remove double "without" added by commit b781871. Thanks + to Fabrice Fontaine. #3261 + * Build System: fix compile time issues. Thanks to Matthias Runge. + #3179, #3242, #3245 + * Build System: Fix activation of snmp_agent. Thanks to Fabrice + Fontaine. #3241 + * Build System: Fix bug that leads to CPPFLAGS gets overridden with + CFLAGS when libxmms is enabled. Thanks to Dagobert Michelsen. #3207 + * perl module: Collectd::Plugins::Openvz: Fix indentation of some + closing curlies. Thanks to Christian Bartolomäus. #3239 + * tree-wide: Fix a few issues found with LGTM. Thanks to Ruben Kerkhof. + #3252 + * tree-wide: fix ssnprintf wrapper. Thanks to Fabien Wernli. + #3237, #3232, #3235, #3236 + * tree-wide: Fix make check. Thanks to Ruben Kerkhof. #3306 + * CI System: Travis: switch to Bionic. Thanks to Ruben Kerkhof. #3307 + * CI System: Travis improvements for MacOS. Thanks to Ruben Kerkhof. + #3308 + * MySQL plugin: Minor documentation improvements. Thanks to Christian + Bartolomäus. #3288 + * Java plugin: Fix typo in an error message. Thanks to Matthias Runge. + #3285, #3286 + * sysevent plugin: Add a few missing calloc result checks in the + sysevent_init function. Thanks to Andrew Bays. #3282 + * ZFS ARC plugin: A bug that caused the first to values to be skipped + was fixed. Thanks to Jan-Philipp Litza. #3246 + * SysLog plugin: restore previous behaviour: fallback to info for + unsupported level. Thanks to Fabien Wernli. #3236, #3238 + * virt plugin: Fix memory leak with libvirt MetadataXPath enabled. + Thanks to Pavel Rochnyak. #3225, #3228 + * GPU NVidia plugin: Fix build of the plugin. Thanks to Ruben Kerkhof. + #3320 + +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 + * collectd: improve error handling, check return values. Thanks to + Florian Forster. + * Build System: use "kstat.h", when available. Thanks to Dagobert + Michelsen and Pavel Rochnyak. #2784 + * Build System: Fix distcheck on MacOS. Thanks to Ruben Kerkhof. + * Build System: add missing include of ""collectd.h"" to fix builds on + Solaris. Thanks to Pavel Rochnyak. + * Build System: add endianess checks for AIX, fix GCC issue on Mac + byteorder, fix byteorder on Solaris, add fallback for endianess + conversion. Thanks to Dagobert Michelsen (multiple cherry picks from + master). + * Build System: Out-of-tree builds have been fixed. Thanks to Florian + Forster. #2602 + * Configuration: Error handling in the config parsing code has been + improved. Thanks to Florian Forster. + * Documentation: Fix typo in collectd.conf(5). Thanks to Pavel Rochnyak. + #2760 + * Documentation: update note on dpdkstat. Thanks to Maryam Tahhan. #2613 + * Various plugins: Errors found by the static code analysis tool + Coverity were fixed. Thanks to Florian Forster. #2559, #2560, #2561, + #2562, #2563, #2565, #2568, #2575, #2579, #2580, #2588, #2589 + * Ceph plugin: A segfault has been fixed. Thanks to Aleksei Zakharov and + Matthias Runge. #2572 + * DF plugin: fix memory leak in error case. Thanks to Takahashi tsc. + * Exec plugin: check return value of "plugin_thread_create()". Thanks to + Florian Forster. + * Exec plugin: Handling of large groups has been fixed. Thanks to + Sridhar Mallem. #2696 + * Exec plugin: Incorrect use of *putenv(3)* has been fixed. Thanks to + Daniel Vrátil. + * Exec plugin: A deadlock related to setting environment variables after + *fork()* has been fixed. Thanks to Daniel Vrátil. + * Intel PMU plugin: add core groups feature. Thanks to Kamil Wiatrowski. + #2681 + * Intel PMU plugin: fix compatibility issue with collectd 5.8. Thanks to + Kamil Wiatrowski. + * Intel PMU plugin: fix possible "NULL" pointer dereference. Thanks to + Kamil Wiatrowski. #2676 + * IPMI plugin: A segfault caused by a wrong data type has been fixed. + Thanks to Mariusz Szafrański. #2742 + * IPMI plugin: The sensor configuration option has been fixed. Thanks to + Pavel Rochnyak. #2629 + * memcached plugin: A deadlock situation has been fixed. Thanks to Pavel + Rochnyak. #2612 + * NFS plugin: Support for NFSv4 has been fixed. Thanks to Jan-Philipp + Litza. #2076 + * NTPd plugin: A memory leak in the error handling path has been fixed. + Thanks to Ruben Kerkhof. #2942 + * OVS Stats plugin: A deadlock situation has been fixed. Thanks to + Volodymyr Mytnyk. #2590 + * OVS Stats plugin: Fix reconnect after thread terminated. Thanks to + Volodymyr Mytnyk and Maram Tahhan. #2574 + * Perl plugin: A compilation failure has been fixed. Thanks to Pavel + Rochnyak. #2732 + * Perl plugin: Fix exporting notification meta data. Thanks to Florian + Forster. + * RRDtool plugin: Handling of very large "GAUGE" metrics has been fixed. + Thanks to Miroslav Lichvar. #2566 + * Tail plugin: Several regressions have been fixed. Thanks to Pavel + Rochnyak. #2535, #2587, #2611 + * turbostat plugin: A potential segfault due to an incorrect *free()* + has been fixed. Thanks to Ruben Kerkhof. #2948 + * UUID plugin: Fix hostname setting. Thanks to Pavel Rochnyak. #2723 + * virt plugin: A segfault during error handling has been fixed. Thanks + to Ruben Kerkhof. {{Issue|2919]} + * Write Kafka plugin: A build failure due to a deprecated API call has + been fixed. Thanks to Pavel Rochnyak. #2607, #2628, #2640 + * Write Prometheus plugin: Fix "MHD_USE_INTERNAL_POLLING_THREAD" flag in + newer libmicrohttpd. Thanks to Pavel Rochnyak. #2849 + * Write Prometheus plugin: set "SO_REUSEADDRESS" on listening socket. + Thanks to Pavel Rochnyak. #2570, #2673 + * Write Syslog plugin: The new "write_syslog" plugin writes value + lists as syslog messages. Thanks to Shirly Radco. #3019 + +2017-11-17, Version 5.8.0 + * collectd: The core daemon is now completely licensed under the MIT + license. + * collectd: Added daemon option to avoid making BaseDir. Thanks to + Nathaniel Wesley Filardo and Florian Forster. #2422 + * collectd: Global variables have been moved to their own module to make + porting collectd easier. Thanks to Sean Campbell. #2467 + * collectd as well as Apache, memcached, OpenLDAP, Perl, RouterOS, SNMP, + Tail-CSV plugins: Free userdata for "plugin_register_complex_read()". + Thanks to Pavel Rochnyack. #2349 + * Collectd client library: Added parsing and server code. Thanks to + Florian Forster. #2258 + * Build system: Dependency on libltdl has been removed, support for + libtool 1 has been dropped. Thanks to Ruben Kerkhof. #1898 + * Build system: The build system has been switched to non-recursive + make. Thanks to Ruben Kerkhof. #2085 + * APC UPS plugin: The plugin's configuration is now optional. Without a + "" block reasonable defaults will be used. Thanks to Pavel + Rochnyack. #2351 + * Chrony plugin: Several issues found when working with a stratum-1 + server have been fixed. Thanks to Miroslav Lichvar. #2190 + * Ceph plugin: Support for the Ceph version "Luminous" has been added. + Thanks to Aleksei Zakharov. #2464 + * CPU plugin : Linux-specific "guest" states have been added. Thanks to + Xavier G. #2439 + * cURL plugin, cURL-JSON, cURL-XML, DBI, FileCount, memcachec, Oracle, + PostgreSQL, Table, Tail, Tail CSV plugins: The ability to configure + the "plugin" field of generated metrics has been added. Thanks to + Pavel Rochnyack. #1944, #1681, #1558 + * cURL-JSON plugin: Parsing of arrays has been fixed. Thanks to Florian + Forster. #2281 + * DPDKEvents plugin: This new plugin reports link status and keep alive + events. Thanks to Maryam Tahhan, Harry van Haaren, Serhiy Pshyk, + Kim-Marie Jones, Krzysztof Matczak, Przemyslaw Szczerbik, Christian + Ehrhardt and Luca Boccassi. #2157, #2348, #2400, #2405, #2417 + * DPDKStat plugin: The plugin has been refactored to make DPDK related + utility functions reusable. Thanks to Krzysztof Matczak, Przemyslaw + Szczerbik, Christian Ehrhardt and Luca Boccassi. #2130, #2348, #2400, + #2405, #2417 + * DPDKStat plugin: The "LogLevel" and "RteDriverLibPath" config options + have been added. Thanks to Jiri Prokes. #2505 + * Email plugin as well as Exec and Unixsock plugins: Use + "_SC_GETPW_R_SIZE_MAX". Thanks to Florian Forster. #2451 + * FileCount plugin: Custom values for reported plugin, type and type + instance. Thanks to Pavel Rochnyack. #1979 + * GenericJMX plugin: Support for "AtomicInteger" and "AtomicLong" has + been added. Thanks to Pierre Mauduit. #2158 + * gRPC plugin: Support for meta data has been added. Thanks to Taylor + Cramer. #2378 + * IPC plugin: Fixed failed compilation on AIX. Thanks to Pavel + Rochnyack. #2357 + * Intel PMU plugin: This new plugin collects CPU performance metrics + using Intel's Performance Monitoring Unit (PMU). Scaling information + added to metadata. Thanks to Serhiy Pshyk and Roman Korynkevych. + #2276, #2398, #2374 + * Intel RDT plugin: Support for collectd's logging infrastructure has + been added. PQoS monitoring groups are being reset on start-up to fix + potential previous unclean shutdowns. Thanks to Roman Korynkevych. + #2089. + * IPMI plugin: Support for System Event Log (SEL) has been added. Thanks + to Roman Korynkevych. #2091 + * IPMI plugin: Support for remote IPMI controllers has been added. + Thanks to Pavel Rochnyack. #2024 + * LVM plugin: A check for the "CAP_SYS_ADMIN" capability has been added. + This will give users an informative warning when the process is not + running with the required privileges for this plugin. Thanks to + Florian Forster. #2426, #2499 + * mcelog plugin: This new plugin subscribes to Machine Check Exceptions + (MCE) and dispatches notifications. Metadata reset. Thanks to Maryam + Tahhan, Volodymyr Mytnyk, Taras Chornyi, Krzysztof Matczak and Roman + Korynkevych. #2003, #2246, #2380 + * MQTT plugin: Add support for TLS in "Subscriber" blocks. Thanks to + Florian Forster. #2434 + * memcached plugin: Persistent connections have been implemented. Fix + hit ratio reporting, add connections rate report. Thanks to Pavel + Rochnyack. #2388, #2385 + * memcached plugin: The type of the "listen_disabled" metric has been + changed to "total_events". Thanks to Florian Forster. #2386, #2468 + * Netlink plugin: The dropped packets metric has been added. Thanks to + Denys Fedoryshchenko. #2053 + * NFS plugin: Support for NFS 4.2 metrics has been added. Thanks to + Marek Becka. #2369 + * NFS plugin: Config options to ignore specified NFS versions have been + added. Thanks to Christian Bartolomäus. #2430 + * NUT plugin: The "ConnectTimeout", "ForceSSL", "VerifyPeer" and + "CAPath" options have been added. Thanks to Pavel Rochnyack and Steven + Bell. #2145, #2354 + * OpenLDAP plugin: A segfault after a connection failure has been fixed. + Thanks to Pavel Rochnyack. #2377 + * Openvpn plugin: Added support for status files from latest OpenVPN-2.4 + and possible from future versions. Thanks to Pavel Rochnyack. #2352 + * OVS Events plugin: This new plugin reports link state changes from + Open vSwitch (OVS). Thanks to Volodymyr Mytnyk. #1971 + * OVS Stats plugin: This new plugin reports bridge / interface + statistics from Open vSwitch (OVS). Thanks to Volodymyr Mytnyk and + Taras Chornyi. #2137 + * Perl plugin: Bugfix, added check of proper interpreter initialization. + Thanks to Pavel Rochnyack. #2391 + * PostgreSQL plugin: The plugin now sets the "application_name" + parameter when connecting to the database. Thanks to daniacs. #2497 + * Processes plugin: The I/O operations reported for selected processes + has been fixed. The metric "ps_disk_octets" has been renamed to + "io_octets" because it actually contains the number of I/O operation + by the process, not just disk related I/O. Same for "io_ops" + (previously "ps_disk_ops"). The new metric "disk_octets" has been + added and is reporting disk I/O only. Add option to collect the count + of active memory maps for Linux processes. The "CollectFileDescriptor" + and "CollectContextSwitch" options have been added. Thanks to Pavel + Rochnyack and to Wilfried Goesgens. #2232, #2454, #1989 + * Processes and TCPConns plugins: The OpenBSD implementation has been + changed to use "kvm_openfiles" with "KVM_NO_FILES". Thanks to Jeremie + Courreges-Anglas. #2061 + * Python plugin: Extend Notification class to include metadata. Thanks + to Volodymyr Mytnyk. #2135 + * Python plugin: The "CollectdException" class has been added. This + allows to throw an exception without a stack trace being logged. + Thanks to Sven Trenkel. #2330, #2346 + * Sensors plugin: Support for (electrical) current has been added. + Thanks to Clemens Gruber. #2255 + * SNMP plugin: Error handling has been improved: a potential double-free + is now avoided (potentially leaking memory) and handling of + non-failing subtrees has been fixed. Thanks to Pavel Rochnyack. #2449 + * SNMP plugin: The "Timeout" and "Retries" config options have been + added. Thanks to Carlos Vicente. #1472, #2488 + * SNMP Agent plugin: This new plugin implements an SNMP AgentX subagent + that receives and handles queries from SNMP master agent and returns + configured metrics. Thanks to Roman Korynkevych, Serhiy Pshyk and + Pavel Rochnyack. #2105, #2362 + * Synproxy plugin: This new plugin provides statistics for Linux + SYNPROXY. Thanks to Marek Bečka. #2381 + * Tail plugin: Allow the calculation of several distributions in one + "tail" instance through a "bucket" type. Thanks to Pavel Rochnyack. + #2442 + * Turbostat plugin: Import "msr-index.h" header from Linux and better + support for mutliple packages. Thanks to Vincent Brillault. #2445, + #2446 + * Uptime plugin: Changed implementation to read from "/proc/uptime" + instead of "/proc/stat". Update for Linux and AIX, uptime is read + directly using a system call. Update for BSD and Solaris, uptime is + calculated by subtracting boot time from current time. Thanks to Ivan + Kurnosov and Marcin Jurkowski. #2431, #2034 + * UUID plugin: Support for libhal has been removed. Thanks to Ruben + Kerkhof. #2080 + * Varnish plugin: Extended the varnish plugin with varnish-plus + counters. Fixed invalid data source type. Thanks to Denes Matetelki. + #2453, #2463 + * virt plugin: The plugin has been updated to use + "virConnectListAllDomains()". Thanks to Denis Silakov. #2051 + * virt plugin: Support for domain tags has been added. Thanks to + Francesco Romani. #2048 + * virt plugin: Connection handling has been improved. Thanks to + Francesco Romani. #2100, #2101 + * virt plugin: Many metrics have been added, including disk, hypervisor + CPU usage, performance monitoring events, domain state, CPU pinning + (affinity), file system, and job statistics. Thanks to Francesco + Romani and Przemyslaw Szczerbik. #2103, #2175, #2168 + * Write Graphite plugin: Additional tests have been added. Thanks to + Florian Forster. + * Write HTTP plugin: The "Attribute" and "TTL" options for the KairosDB + format have been added. Implementation of "Prefix" option. Thanks to + jaroug, Denis Pompilio and Pavel Rochnyack. #2199, #2252, #2482 + * Write MongoDB plugin: Memory leaks have been fixed. Thanks to + Saikrishna Arcot. #2307 + * Write Prometheus plugin: Label values are now properly escaped. Thanks + to Florian Forster. #2035 + * Write Redis plugin: Add "max_set_duration" to set duration for value. + Thanks to Tomofumi Hayashi. #2440 + * Write Riemann plugin: Export times with microsecond resolution. Thanks + to mcorbin. #2315 + * Write TSDB plugin: The options "ResolveInterval" and "ResolveJitter" + have been added to control DNS lookup behavior. This prevents DNS + flooding in case TSDB is not available. Thanks to Yves Mettier and + Florian Forster. #2059 + * ZFS ARC plugin: Header lines are now ignored in the Linux + implementation. Thanks to YmrDtnJu. #2097 + +2017-06-06, Version 5.7.2 + * Build system: The Notify Email plugin is no longer linked with + indirect dependencies. Thanks to Marc Fournier. + * collectd: A race condition when calculating a metric's rate has been + fixed. Thanks to Florian Forster. #1193 + * AMQP, Exec, UnixSock, Write Kafka plugins: Parsing of the PUTVAL + command with multiple values has been fixed. Thanks to Florian + Forster. #2274 + * AMQP plugin: The "ExchangeType" option is now also valid for + publishers. Thanks to Florian Forster. #2286 + * BIND plugin: Fix parsing of the sample time provided by BIND. + Previously, the time was assumed to be in the local timezone when in + fact it was in UTC. Thanks to Ed Ravin. #1268 + * BIND plugin: Memory leaks have been fixed. Thanks to Ruben Kerkhof. + #2303 + * cURL-JSON plugin: Handling of arrays has been fixed. Thanks to Florian + Forster. #2266 + * DPDKStat plugin: Error handling during initialization has been + improved. Thanks to Ruben Kerkhof. + * DPDKStat plugin: Handling of a number of metrics has been improved, + for example "rx_q0bytes". Thanks to Przemyslaw Szczerbik. #2167 + * Intel RDT plugin: Configuration handling has been changed to be more + graceful. Thanks to Maryam Tahhan. #2165 + * Log Logstash plugin: If writing the log entry fails, print it to + "STDERR" instead. Thanks to Marc Fournier. + * LogFile plugin: If writing to the file fails, print log messages on + "STDERR" instead. Thanks to Marc Fournier. + * memcachec, Tail plugins: A resource leak in the matching + infrastructure has been fixed. Thanks to Krzysztof Matczak. #2192 + * MQTT plugin: Invalid symbols in topic names are now replaced and a + resource leak has been fixed. Thanks to Denys Fedoryshchenko. #2123 + * Network plugin: A potential endless-loop has been fixed. This can be + triggered remotely by sending a signed network packet to a server + which is not set up to check signatures. Thanks to Marcin Kozlowski + and Pavel Rochnyack. #2174, #2233, CVE-2017-7401 + * Perl plugin: A potential double-free has been fixed. Thanks to Florian + Forster. #2278 + * Processes plugin: A compilation error on AIX has been fixed. Thanks to + Pavel Rochnyack. #2210 + * SMART plugin: A check for the "CAP_SYS_RAWIO" capability has been + added. Thanks to Marc Fournier. + * Write Graphite plugin: Error handling in the case that calculating a + metric's rate fails has been improved. Previously, the raw counter + values were sent to Graphite. Thanks to Iain Buclaw. #2209 + * Write Prometheus plugin: An incorrect use of "realloc(3)" has been + fixed. Thanks to Florian Forster. #2275 + +2017-01-23, Version 5.7.1 + * collectd: Handling of boolean configuration options has been unified. + Thanks to Sebastian Harl. #2083, #2098 + * collectd: Reporting of internal statistics has been fixed. Thanks to + Florian Forster. #2108 + * collectd, various plugins: Bugs and issues reported by scan-build and + coverity-scan have been fixed. Thanks to Ruben Kerkhof and Florian + Forster. + * Build system: Parallel build have been fixed. Thanks to Ruben Kerkhof. + #2110 + * DPDKStat plugin: Portability issues and a double-close bug have been + fixed. Thanks to Ruben Kerkhof and Marc Fournier. + * Intel RDT plugin: A check for the libpqos library version has been + added. Thanks to Serhiy Pshyk. + * NetApp plugin: Compilation problems have been corrected. Thanks to + Florian Forster. #2120 + * Write Prometheus plugin: A memory leak has been fixed. Thanks to Ruben + Kerkhof. + +2016-12-12, Version 5.7.0 + * Documentation: The Turbostat plugin section has been improved. Thanks + to Florian Forster + * Documentation: The semantics of the "TypesDB" option have been + improved. Thanks to Florian Forster. + * collectd: A generic interface for parsing the text protocol has been + added. Thanks to Sebastian Harl. #1749 + * collectd: Threads now get named, making them easier to track using + tools such as top, ps, etc. Thanks to Manuel Luis Sanmartín Rozada + and Marc Fournier. #547 + * AMQP plugin, Write Graphite plugin, Write Kafka plugin: The new + "[Graphite]PreserveSeparator" option allows retaining the default dot + separator rather than escaping it. Thanks to Florian Forster. #419 + * Battery plugin: A StateFS backend for gathering statistics has been + added. Thanks to Rinigus. #1795 + * CPU plugin: CPU aggregation on AIX was fixed. Thanks to Chao Yang. + #1957 + * Collectd::Unixsock: Fractional seconds support has been made more + robust. Thanks to Matthias Bethke. #2052 + * DPDKStat plugin: This new plugin collects DPDK interface statistics. + Thanks to Maryam Tahhan, Harry van Haaren, Taras Chornyi and Kim + Jones. #1649 + * gRPC plugin: The "DispatchValues" option has been renamed to + "PutValues". Thanks to Florian Forster. + * HDDTemp plugin: The 32 devices limit has been removed. Thanks to + Benjamin Gilbert. #631 + * Hugepages plugin: This new plugin reports the number of used and free + hugepages on Linux. Thanks to Jaroslav Safka, Maryam Tahhan, Kim Jones + and Florian Forster. #1799 + * Intel RDT plugin: This new plugin collects statistics exposed by + Intel's Resource Director Technology . Thanks to SerhiyX. #1970 + * memcached plugin: The new "Address" option allows connecting to a + different server than specified by the "Host" option. Thanks to Pavel + Rochnyack. #1975 + * nginx plugin: Support for reporting failed connections has been added. + Thanks to Pavel Rochnyack. #1609 + * Perl plugin: Significant internal reworking has been made. The new + "RegisterLegacyFlush" option has been added. Thanks to Pavel + Rochnyack. #1731 + * PostgreSQL plugin: Timestamps are now RFC 3339-formatted local time. + Thanks to Igor Peshansky and Dave Cunningham. #1918 + * Processes plugin: Internal performance improvements have been made. + Thanks to Pavel Rochnyack. #1980, #1981 + * RRDCacheD plugin: The plugin now tries to reconnect upon failed + operations. Thanks to Sebastian Harl. #1959 + * SpamAssassin: The plugin can now run in Perl's "tainted mode" ("-T"). + Thanks to Akos Vandra. #1962 + * Tail plugin: Support for calculating latency distribution of matching + values has been added. Thanks to Pavel Rochnyack and Florian Forster. + #1700 + * Tail plugin: The new "GaugePersist" option has been added. Thanks to + Florian Forster. #2015 + * Target:Set, Target:Replace, Match:RegEx: MetaData support has been + added . Thanks to Igor Peshansky. #1922, #1923, #1930 + * turbostat plugin: The new "LogicalCoreNames" option allows switching + to per-core naming rather than per-CPU. Thanks to Brock Johnson. #2056 + * virt plugin: The new "BlockDeviceFormat" and + "BlockDeviceFormatBasename" options help controlling the names + reported for block-device metrics. Thanks to Deyan Chepishev. #2004 + * Write Graphite plugin: A new "DropDuplicateFields" option has been + added. Thanks to Michael Leinartas. #1915 + * Write Kafka plugin: The "Key Random" setting has been reintroduced. + Thanks to Florian Forster. #1977 + * Write Log plugin: Support for formatting output in JSON has been + added, using the new "Format" configuration option. Thanks to Igor + Peshansky. #1924 + * Write Prometheus plugin: This new plugin publishes values using an + embedded HTTP server, in a format compatible with Prometheus' + collectd_exporter. Thanks to Florian Forster. #1967 + +2017-10-06, Version 5.6.3 + * collectd: support for boolean string config values has been + reintroduced. Thanks to Sebastian Harl. #2083, #2098 + * collectd: The capability checking has been changed to use + "cap_get_proc()". Thanks to Marc Fournier. #2151 + * Documentation: A section documenting ignore lists has been added to + collectd.conf(5). Thanks to Florian Forster. + * AMQP plugin: The "ExchangeType" option is now also valid for + publishers. Thanks to Florian Forster. #2286 + * Apache, Ascent, BIND, cURL, cURL-JSON, cURL-XML, nginx, Write HTTP + plugins: Handling of URLs that redirect elsewhere has been fixed. + Thanks to Pavel Rochnyack. #2328 + * BIND plugin: Fix parsing of the sample time provided by BIND. + Previously, the time was assumed to be in the local time zone when in + fact it was in UTC. Thanks to Ed Ravin. #1268 + * BIND plugin: Memory leaks have been fixed. Thanks to Ruben Kerkhof. + #2303 + * Chrony plugin: Build flags have been fixed. Thanks to Thomas Jost and + Marc Fournier. #2133 + * cURL-JSON plugin: The timeout value has been changed to default to the + collection interval. This fixes a regression. Thanks to Marc Fournier. + * cURL-JSON plugin: Handling of arrays has been fixed. Thanks to Florian + Forster. #2266 + * DBI plugin: Memory leaks at shutdown have been fixes. Thanks to Pavel + Rochnyack and Florian Forster. + * E-Mail, Exec, UnixSock plugins: Group ID lookup on systems with many + groups has been fixed. Thanks to Ruben Kerkhof and Florian Forster. + #2208 + * IPC plugin: A compilation error on AIX has been fixed. Thanks to Pavel + Rochnyack. #2305 + * LogFile plugin: If writing to the file fails, print log messages on + "STDERR" instead. Thanks to Marc Fournier. + * Log Logstash plugin: If writing the log entry fails, print it to + "STDERR" instead. Thanks to Marc Fournier. + * memcachec, Tail plugins: A resource leak in the matching + infrastructure has been fixed. Thanks to Krzysztof Matczak. #2192 + * MQTT plugin: Invalid symbols in topic names are now replaced and a + resource leak has been fixed. Thanks to Denys Fedoryshchenko. #2123 + * Network plugin: A potential endless-loop has been fixed. This can be + triggered remotely by sending a signed network packet to a server + which is not set up to check signatures. Thanks to Marcin Kozlowski + and Pavel Rochnyack. #2174, #2233, CVE-2017-7401 + * Network plugin: A use-after-free has been fixed. Thanks to Pavel + Rochnyack. #2375 + * Notify Email plugin: The plugin is no longer explicitly linked against + libssl and libcrypto, relies on libesmtp being linked correctly. + Thanks to Marc Fournier. Debian#852924 + * NTPd plugin: Calculation of loop offset and error has been fixed. + Thanks to Neil Wilson. #2188 + * OpenLDAP plugin: An incorrect use of the ldap library, leading to a + crash, has been fixed. Thanks to Marc Fournier. #2331 + * Perl plugin: A potential double-free has been fixed. Thanks to Florian + Forster. #2278 + * Perl plugin: Print an error when an incorrect configuration is + encountered. Thanks to Pavel Rochnyack. #927 + * RRDtool plugin: Incorrect handling of the flushes timeout option has + been fixed. Handling of the "RandomTimeout" has been fixed. Thanks to + Pavel Rochnyack. #2363 + * SMART plugin: Some warning messages have been removed and the code has + been cleaned up. Thanks to Florian Forster. #2062 + * SMART plugin: A check for the "CAP_SYS_RAWIO" capability has been + added. Thanks to Marc Fournier. + * SNMP plugin: A double free has been fixed. Thanks to Pavel Rochnyack. + #2291 + * Write Graphite plugin: Error handling in the case that calculating a + metric's rate fails has been improved. Previously, the raw counter + values were sent to Graphite. Thanks to Iain Buclaw. #2209 + * Write Kafka plugin: A 32 bit random number is now used when formatting + a random key. Thanks to Florian Forster. #2074 + + +2016-11-30, Version 5.6.2 + * collectd: A compile error on AIX has been fixed: "MSG_DONTWAIT" is not + available on AIX. Thanks to Chao Yang. + * collectd: The capability checking has been rewritten to be more + portable. Thanks to Florian Forster. #2009 + * collectd.conf(5): Various typos have been fixed. Thanks to Marc + Fournier. + * collectd-tg: Incorrect usage of "nanosleep()" has been fixed which + caused the tool to sleep (almost) indefinitely. Thanks to Florian + Forster. + * Build system: Detection of the Java environment has been made + deterministic to allow for reproducible builds. Thanks to Marc + Fournier. #1523 + * Build system: Detection of the Lua headers has been improved. Thanks + to Ruben Kerkhof. + * APC UPS plugin: Unavailable metrics are now skipped instead of + reported as 0 (zero). Thanks to Florian Forster. #2025 + * Modbus plugin: Build issues on FreeBSD have been fixed. Thanks to + Florian Forster. + * OpenVPN plugin: Gracefully handle empty configurations. Thanks to + Pavel Rochnyack. #1932 + * PowerDNS plugin: The "recursor command" has been fixed so PowerDNS can + correctly parse all requested fields. Thanks to Ruben Kerkhof. + * Write Graphite and AMQP plugins: A bug that could lead to a missing + null-termination has been fixed. Thanks to Markus Linnala. + * Write HTTP plugin: A logic error when checking the correctness of the + data set has been fixed. Thanks to Pavel Rochnyack. #1996 + * Write Kafka plugin: The "Key Random" config option has been fixed. + Thanks to Florian Forster. #1977 + * Write Kafka plugin: Support for librdkafka 0.9.0 has been added. + Thanks to Florian Forster. + * Write Riemann plugin: Build issues on Solaris have been fixed. Thanks + to Florian Forster. + * ZFS ARC plugin: A duplicate metric has been removed. Thanks to Ruben + Kerkhof. #1963 + +2016-10-07, Version 5.6.1 + * Build system: Unnecessary linking of the Write Graphite plugin with + libyajl has been removed. Thanks to Marc Fournier. + Debian#839771, #1976 + * collectd: A bug in the "FlushInterval" option that caused a + segmentation fault in the Write HTTP plugin has been fixed. Thanks to + Florian Forster. #1954 + * Apache plugin: A syntax error has been fixed. Thanks to Florian + Forster. + * cURL-JSON plugin: A segmentation fault that occurred when handling + JSON with unexpected structure has been fixed. Thanks to Florian + Forster. #1896 + * PostgreSQL plugin: Handling of "NULL" values in the "query_plans" and + "query_plans_by_table" queries has been fixed. Thanks to Bernd + Zeimetz. #1905 + * RRDCacheD plugin: Reconnection behavior has been added. Thanks to + Sebastian Harl. Debian#657877 + * VServer plugin: Use of a deprecated API ("readdir_r()") has been + fixed. Thanks to Sebastian Harl. + * Write Graphite plugin: Make default values configurable at compile + time again. Thanks to Florian Forster. #1953 + * Write HTTP plugin: A bug has been fixed that lead to flush callbacks + being registered twice. Thanks to Florian Forster. #1955 + +2016-09-11, Version 5.6.0 + * Build system: An option to to avoid building the DF plugin against XFS + has been added. Thanks to Ruben Kerkhof. #1878 + * Build system: Autoconf ≥ 2.60, a C99-capable compiler and pkg-config + are now required. Thanks to Ruben Kerkhof. + * Build system: Building with "-Werror" is now optional. Thanks to Ruben + Kerkhof. #1222 + * Build system: Many compilation issues on non-Linux platforms have been + fixed, leading to wider plugin support. Thanks to Ruben Kerkhof, + Dagobert Michelsen, Havard Eidnes and Robert Viduya. + * Build system: The configuration summary now also ends up in + config.log. Thanks to Sebastian Harl. + * collectd: All command-line options now override global options from + the config file. Thanks to Sebastian Harl. #366 + * collectd: A number of unit tests for commonly used functions have been + added. Thanks to Florian Forster. + * collectd: Plugins start up and read timeouts are now logged. Thanks to + Marc Fournier. #1293, #1254 + * collectd: Support for a timeout has been added to "FLUSH" callbacks. + Thanks to Manuel Luis Sanmartín Rozada. + * collectd: The "-T" command line switch now reports more errors. Thanks + to Corey Kosak. #1642 + * collectd: The max size of value list elements ("DATA_MAX_NAME_LEN") + has been doubled and is now configurable at build time. Thanks to Amy + Lin, Florian Forster and Radu Brumariu. #1120 + * Set target: The "MetaData" option has been added. Thanks to Yves + Mettier and Kevin Bowling. #1106, #1656, #1913 + * AMQP, Write_HTTP, Write_Kafka plugins: Support for libyajl < 2 has + been added. Thanks to Florian Forster. + * APC UPS plugin: Parsing of end markers has been fixed. Thanks to + Florian Forster #617 + * APC UPS plugin: The "PersistentConnection" option has been added. + Thanks to Florian Forster #617 + * ceph, DNS, Exec, IPTables, Ping, turbostat plugins: When running + unprivileged, these plugins will now warn about insuffiscient + permissions or capabilities(7). Thanks to Marc Fournier. #1530 + * Chrony plugin: This new plugin collects NTP data from the chrony NTP + server. Thanks to Claudius Zingerli. #1548 + * cpusleep plugin: This new plugin measures time spent by CPU in deep + sleep mode. Thanks to Rinigus. #1826 + * CPU plugin: The "ReportNumCpu" option has been added. Thanks to Fabien + Wernli. + * cURL, cURL-JSON, cURL-XML plugins: The new "Statistics" reports + various per-HTTP connection timers. Thanks to Sebastian Harl. #1004 + * DBI plugin: The "Interval" option has been added to "Database" blocks. + Thanks to Michal Bebjak. + * Disk plugin: Support for FreeBSD has been added. Thanks to Xin Li, + Brad Davis, Ruben Kerfhof and Kevin Bowling. + * Empty Counter match: Support for derives has been implemented. Thanks + to Florian Forster. #1813 + * GenericJMX plugin: Support for TabularData and the "PluginName" option + have been added. Thanks to David Crane. #1290, #1291 + * GPS plugin: This new plugin reports the number of sattelites seen by + and precision of a GPS receiver. Thanks to Nicolas Jourden. #1346 + * gRPC plugin: This new client and server plugin allows sending and + receiving metrics using the gRPC protocol. Comparable to the UnixSock + plugin, but using TCP and TLS. Thanks to Sebastian Harl and Florian + Forster. + * Interface plugin: Reporting dropped packets has been added. Thanks to + Marc Falzon. #1555 + * Interface plugin: The "ReportInactive" has been added, letting users + skip inactive network interfaces. Thanks to Rinigus. #1791 + * Interface plugin: The new, Solaris-only "UniqueName" option has been + added. Thanks to Yoga Ramalingam. #1416 + * Lua plugin: This new language binding allows writing plugins using the + Lua programming language. Thanks to Julien Ammous, Florian Forster and + Ruben Kerkhof. + * Memory plugin: Reporting of ARC memory on Solaris has been added. + Thanks to Brian ONeill. + * MQTT plugin: This new plugin sends metrics to and/or receives metrics + from an MQTT broker. Thanks to Marc Falzon, Jan-Piet Mens, Nicholas + Humfrey and Florian Forster. #805, #1124 + * MySQL plugin: Connection to the database server can now be done over + SSL. Thanks to Brian Lalor. #1256 + * MySQL plugin: Monitoring slow queries has been added. Thanks to skob. + #1773 + * MySQL plugin: mysql_bpool_pages-flushed has been renamed to + mysql_bpool_counters-pages_flushed because the value is cumulative. + Thanks to Marek Becka. + * MySQL plugin: Support for Galera statistics has been added. Thanks to + Rachid Zarouali. #1849 + * MySQL plugin: Support for InnoDB metrics was improved. Thanks to Aman + Gupta. #1111 + * MySQL plugin: The "mysql_sort" type has been split into 3 different + types. Thanks to Pavel Rochnyack. #1592 + * Network plugin: Decryption error logging has been improved. Thanks to + Pavel Rochnyack. #1735 + * Notify Nagios plugin: This new plugin sends notifications to Nagios as + a passive check result. Thanks to Florian Forster. + * NTPd plugin: The plugin now detects if the ntp daemon reports + nanoseconds instead of microseconds. Thanks to Matwey V. Kornilov. + #1783 + * OpenLDAP plugin: Several connection-related improvements have been + made. Thanks to Marc Fournier. #1308 + * OpenLDAP plugin: Support for "simple authentication" has been added. + Thanks to Marek Becka. #1087 + * Ping plugin: The "Size" option has been added, allowing the ICMP data + payload size to be configured. Thanks to Witold Baryluk. #1395 + * PostgreSQL, DBI, Oracle plugins: The new "PluginInstanceFrom" option + has been added. Thanks to Pavel Rochnyack. #1707 + * PowerDNS plugin: The recursor metrics have been updated to 3.7.3 and + missing rr types have been added. Thanks to Ruben Kerkhof. + * Processes plugin: Counting of context switches was added for Linux. + Thanks to Manuel Luis Sanmartín Rozada. #1036 + * Processes plugin: Improve reliability of thread counts on Linux. + Thanks to Manuel Luis Sanmartín Rozada. + * Python plugin: Minimal Python version requirement has been bumped to + 2.6. Thanks to Ruben Kerkhof. #1864 + * Redis plugin: Several additional metrics are now collected. Thanks to + Marc Falzon and Matteo Contrini. #1807, #1483 + * Sensors plugin: The "UseLabels" option has been added. Thanks to + Christian Fetzer. + * SMART plugin: The new "IgnoreSleepMode" option has been added. Thanks + to Scott Talbert. #1770 + * SMART plugin: The new "UseSerial" option allows identifying devices in + a stable way. Thanks to Scott Talbert. #1794 + * SNMP plugin: The "IpAddress" can now be used for instances. Thanks to + Vincent Bernat. #1397 + * StatsD plugin: Latency calculation histogram is now able to shrink + automatically to optimal size. Thanks to Pavel Rochnyack. #1622 + * StatsD plugin: The "CounterSum" option has been added. Thanks to + Florian Forster. #929, #1282, #1311 + * UUID plugin: The plugin now also looks in in smbios system table and + "/sys/class/dmi". Thanks to Ruben Kerkhof. #1490 + * virt plugin: The "PluginInstanceFormat" option has been added. Thanks + to Ruben Kerkhof. #1100 + * Write Graphite plugin: The "ReconnectInterval" option has been added. + Thanks to Toni Moreno and Florian Forster. + * Write HTTP plugin: A KairosDB formatter has been added. Thanks to + Aurélien Rougemont. #1809 + * Write HTTP plugin: Notifications are now handled by this plugin. + Thanks to Florian Forster. + * Write HTTP plugin: The "LogHttpError" option has been added. Thanks to + vzubko. + * Write HTTP plugin: The new "Headers" option allows setting custom HTTP + headers in outgoing requests. Thanks to Brandon Arp. #1634 + * Write Kafka plugin: Key handling has been made more comprehensive and + reliable. Thanks to Florian Forster, Pierre-Yves Ritschard and Vincent + Bernat. #1765, #1695, #1393 + * Write Redis plugin: The "Database", "MaxSetSize", "Prefix" and + "StoreRates" options have been added. Thanks to Brian Kelly and + Sebastian Pfahl. + * Write Riemann plugin: The new "BatchFlushTimeout" and "Timeout" option + have been added. Thanks to Pierre-Yves Ritschard and Gergely Nagy. + * Write Riemann plugin: This plugin now requires the riemann-c-client + library, version 1.6.0+. This adds support for submitting values to + Riemann over TLS. Thanks to Gergely Nagy. #986 + * Write TSDB, Write Sensu, Write Riemann, Write Graphite, Write TSDB + plugin: TCP keepalive is now enabled, helping graceful recovery from + unclean network disconnections. Thanks to Marc Fournier. #1549 + * XenCPU plugin: This new plugin collects XEN Hypervisor CPU stats. + Thanks to Pavel Rochnyack. #1608 + * ZFS ARC plugin: Several new statistics have been added and a couple of + obsolete ones removed. Thanks to Brad Davis, Brian ONeill and Ruben + Kerkhof. + * Zone plugin: This new plugin reads per-zone CPU usage on Solaris. + Thanks to Mathijs Mohlmann and Dagobert Michelsen. + +2016-11-28, Version 5.5.3 + * collectd: Write threads are stopped before shutdown callbacks are + called. Thanks to Florian Forster. #1110 + * collectd: A compile error on AIX has been fixed: "MSG_DONTWAIT" is not + available on AIX. Thanks to Chao Yang. + * libcollectdclient: Lines printed to "STDERR" are now guarded by the + environment variable "COLLECTD_TRACE". Thanks to Florian Forster. #105 + * collectd.conf(5): Various typos have been fixed. Thanks to Marc + Fournier. + * Build system: Detection of the Java environment has been made + deterministic to allow for reproducible builds. Thanks to Marc + Fournier. #1523 + * APC UPS plugin: Unavailable metrics are now skipped instead of + reported as 0 (zero). Thanks to Florian Forster. #2025 + * Battery plugin: The minimum value has been removed from the power type + to allow the plugin to report discharging batteries as negative power. + Thanks to Florian Forster. + * DBI, Oracle and PostgreSQL plugins: An error message when the type + instance is truncated has been added. Thanks to Florian Forster. #4 + * cURL-JSON plugin: A possible segmentation fault when parsing + unexpected JSON has been fixed. Thanks to Florian Forster. #1896 + * DF plugin: Compilation with xfsprogs ≥ 4.7.0 has been fixed. Thanks + to Thomas Deutschmann. #1877 + * Modbus plugin: Build issues on FreeBSD have been fixed. Thanks to + Florian Forster. + * Network plugin: An error message has been corrected. Thanks to Florian + Forster. + * Network plugin: Handling of errors form secure memory initialization + has been improved: the plugin fails gracefully now instead of calling + "abort()". Thanks to Sebastian Harl. + * Network plugin: The gcrypt library is only initialized when it is + actually required due to the network plugin's configuration. Thanks to + Florian Forster. #1902 + * Ping plugin: The init callback has been changed to be idempotent, + fixing errors being reported on Solaris. Thanks to Florian Forster. + #869 + * PostgreSQL plugin: The query_plans and query_plans_by_table queries + have been improved to return 0 (zero) instead of "NULL" when not + available. Thanks to Bernd Zeimetz. #1905 + * PowerDNS plugin: The "recursor command" has been fixed so PowerDNS can + correctly parse all requested fields. Thanks to Ruben Kerkhof. + * Python plugin: Handling of data sets with multiple data sources of + different type has been fixed. Thanks to Sebastian Harl. + * RRDCacheD plugin: Reconnection behavior after failed operations has + been added. Thanks to Sebastian Harl. Debian#657877 + * Write Graphite and AMQP plugins: A bug that could lead to a missing + null-termination has been fixed. Thanks to Markus Linnala. + * Write Kafka plugin: Support for librdkafka 0.9.0 has been added. + Thanks to Florian Forster. + * Write Riemann plugin: Build issues on Solaris have been fixed. Thanks + to Florian Forster. + +2016-07-25, Version 5.5.2 + * collectd: A division by zero has been fixed in the + "plugin_dispatch_multivalue()" function. Thanks to Corey Kosak. + * collectd: The address of the Free Software Foundation has been fixed + in GPL license headers. Thanks to Ruben Kerkhof. + * Build system: Detection and handling of librrd 1.6 and later has been + fixed. Thanks to Ruben Kerkof. + * Apache plugin: A warning about a possible misconfiguration has been + added. Thanks to Marc Fournier. + * cURL, cURL-JSON and cURL-XML plugins: A memory leak when allocating + more memory fails has been fixed. Thanks to Brandon Arp. + * DF plugin: A build issue on DragonFlyBSD has been fixed. Thanks to + Ruben Kerkhof. #1575 + * Ethstat plugin: Code to strip leading whitespace from device names. + This works around an issue in the VMXNet3 driver. Thanks to Thomas + Guthmann. #1059 + * Exec plugin: A problem in the error handling of an fdopen() failure + has been fixed. Thanks to @ciomaire. + * Modbus plugin: The debug output has been disabled by default. It is + now only enabled when building with "--enable-debug". Thanks to Eric + Sandeen and Marc Fournier. + * Network plugin: A check for the initialization of secure memory has + been added. Previously, failure to initialize this memory was + ignored. Thanks to @yujokang. #1665 + * Network plugin: A heap overflow has been fixed in the server code. + This issue can be triggered remotely and is potentially exploitable. + Thanks to Emilien Gaspar. CVE-2016-6254 + * Perl plugin: Init callbacks have been changed to run essentially + single-threaded to avoid race conditions by init functions which + create additional threads. Thanks to Pavel Rochnyack. #1706 + * Processes plugin: A warning about too long process names has been + added. Thanks to Marc Fournier. #1284 + * Redis plugin: A memory leak in an error handling code path has been + fixed. Thanks to Andrés J. Díaz. + * Redis plugin: The data source type of the expired_keys metric has been + corrected to "DERIVE". Thanks to Marc Falzon and Marc Fournier. #1483. + * SMART plugin: A build dependency on libudev has been added. Thanks to + Pavel Rochnyack. #1724 + * StatsD plugin: A deadlock on plugin shutdown has been fixed. Thanks to + Pavel Rochnyack #1703 + * Write HTTP plugin: Freeing of memory holding HTTP headers during + shutdown has been fixed. Thanks to Tolga Ceylan. + * Write Sensu plugin: A segfault when the Tag was unset has been fixed. + Thanks to Marc Fournier. + * ZFS ARC plugin: The cache_operation-stolen metric has been removed for + FreeBSD 10.2 and later. Thanks to Ruben Kerkhof. #1580 + +2016-01-22, Version 5.5.1 + * Build system: Compilation errors have been avoided by correctly + defining package name and version used by autoconf. Thanks to Nathan + Berkley. #1063 + * Build system: Dependency ordering was fixed to ensure parallel builds + work reliably. Thanks to Gustavo Zacarias. #1125 + * Build system: Error messages have been improved and building the unit + tests has been fixed on Solaris. Thanks to Florian Forster and + Dagobert Michelsen. #1077 + * Build system: The move of the "utils_ignorelist" functions has been + reverted. This fixes build issues of numerous plugins. Thanks to + Benjamin Drung;. #1323 + * Build system: The fhcount plugin has been restricted to Linux. Thanks + to Ruben Kerkhof. #1195 + * Build system: Detection of header files for the turbostat plugin has + been fixed. Thanks to Marc Fournier. #1075 + * collectd: The "LC_NUMERIC" locale is now forced, to prevent issues + with some plugins on environments using a comma as decimal separator. + Thanks to Florian Forster. #1237 + * Documentation: Some precisions related to the virt plugin have beed + added. Thanks to Wojtek Bocer and Ruben Kerkhof. + * Documentation: The CollectdInternalStats documentation has been + improved. Thanks to Yves Mettier and Florian Forster. + * Battery plugin: A missing Type has been added. Thanks to Marc + Fournier. #1338 + * Bind plugin: An off-by-one error has been fixed: an index was checked + against a wrong variable, which may lead to an out-of-bounds read. + Thanks to Michal Humpula. #1123 + * Ceph plugin: JSON parsing has been refactored to support ceph 10.0.0 + and fixes several buffer overflows. Thanks to Florian Forster. #1350 + * CPU plugin: A Mac OS X specific bug has been fixed: the plugin + expected an incorrect number of CPU states, resulting in failing read + callbacks. This regression was introduced in 5.5.0. Thanks to Robert + Viduya. + * Disk plugin: Support for Mac OS X 10.10 has been added. Thanks to + Robert Viduya. #1065 + * IPC plugin: Support for building with musl-libc has been added. Thanks + to Natanael Copa. #1147 + * Log Logstash plugin: A segfault when using libyajl, version 1 was + fixed. Thanks to Vincent Bernat. #1190 + * Log Logstash plugin: The timestamp is now ISO 8601 compliant. Thanks + to Marc Fournier. #1132 + * memcached plugin: The Type of the listen-disabled metric was fixed. + Thanks to Florian Forster. #1356 + * MySQL plugin: The Type used by Innodb_buffer_pool_pages_flushed was + fixed. Thanks to Marek Becka. #1085 + * OpenLDAP plugin: A crash when using LDAPI (LDAP-over-IPC) got fixed. + Thanks to Marek Becka. #1080 + * OpenLDAP plugin: Support for Mac OS X has been added. Thanks to Ruben + Kerkhof. #1489 + * SMART plugin: A memory leak has been fixed. Thanks to Florian + Schüller and Pierre-Yves Ritschard. #1076 + * Swap plugin: A regression that would lead to swap usage being reported + in kilobytes (instead of bytes) has been fixed. Thanks to Marek Becka. + #1071 + * Varnish plugin: Support for FreeBSD has been added. Thanks to Ruben + Kerkhof. #1182 + * Varnish plugin: Support for versions 3 and 4 has been made more + tolerant to minor changes in Varnish point releases. Thanks to Marc + Fournier. #1302 + * virt plugin: A copy-and-paste mistake in an error message has been + fixed. Thanks to Ruben Kerkhof. #1101 + * Write Kafka plugin: Support for Solaris has been added. Thanks to + Shahul Hameed. #1171 + * Write Redis plugin: Dead code has been removed. Thanks to Brian Kelly. + #1143 + * 27 patches have been applied to numerous plugins and core components, + fixing various programming errors which were reported by scan-build, + libasan, FBInfer, coverity-scan and clang: Thanks to Ruben Kerkhof, + Florian Forster and Marek Becka. + * Collectd::Unixsock: A Perl error got corrected. Thanks to Ciaran Mac + An Iomaire. #1295 + +2015-05-27, Version 5.5.0 + * Build system: Ability to make out-of-tree builds has been fixed. + Thanks to Vincent Bernat. #792 + * Build system, Disk and Users plugins: Detection and use of libstatgrab + ≧ 0.90 has been added. Thanks to Vincent Bernat. #445, #795, #806, + #807, #908 + * Build system, Memory, CPU, TCPConns and Processes plugins: Numerous + fixes related to OpenBSD support have been added. Thanks to Landry + Breuil. #777, #778, #779, #808 + * Build system: Plugins now only export "module_register()". Thanks to + Florian Forster. + * Build system: Various cleanups and improvements have been done. Thanks + to Marc Fournier. + * collectd: Numerous internal changes and improvements to the daemon and + the plugin API have been make. Thanks to Florian Forster, Pierre-Yves + Ritschard and Alex Petrov. #512, #727 + * collectd: Numerous spelling mistakes have been corrected in comments + and documentation and several error messages have been improved. + Thanks to Ruben Kerkhof, Abhinav Upadhyay, Olivier Bazoud, Pierre-Yves + Ritschard, Tim Smith, Moshe Zada, Katelyn Perry and Marc Fournier. + * collectd: Rules/Targets can now be appended to existing Filter Chains. + Thanks to Marc Falzon. #444 + * collectd: Failing Filter Chains destinations will now log the list of + available write targets. Thanks to Wilfried Goesgens. #650, #1043 + * collectd: Support for process signaling and management by upstart and + systemd has been implemented for the Linux platform. Thanks to + Pierre-Yves Ritschard and Marc Fournier. #798, #811, #814 + * collectd: The "CollectInternalStats" option has been added. Thanks to + Yves Mettier. #691 + * collectd: The daemon source code and dependencies have moved to the + "src/daemon/" directory. Thanks to Florian Forster. + * collectd: The new "MaxReadInterval" option allows to cap the + exponential retry interval of plugins read errors. Thanks to Alexey + Remizov and Florian Forster. #713 + * collectd: The "-P" command-line option now has precedence over the + "PIDFile" option. Thanks to Thomas D. #553 + * collection.cgi: Various data-source related adjustments have been + made. Thanks to Fabiano Pires and Sebastian Harl. + * libcollectdclient: Now propagates errors when signing / encrypting + network packets. Thanks to Florian Forster. + * Configuration: Support for unquoted IPv6 addresses has been added. + Thanks to Sebastian Harl. #489 + * Documentation: Various improvements have been done. Thanks to Florian + Forster and Marc Fournier. + * Examples: the sample C plugin has been updated to the current plugin + API. Thanks to Sebastian Harl. + * Licensing: The following components have been relicensed to the MIT + license: the Apple Sensors, Ascent, DBI, E-Mail, Entropy, GenericJMX, + gmond, LogFile, nginx, Notify Desktop, NTPd, NUT, olsrd, Perl, Ping, + PostgreSQL, Protocols, RouterOS, RRDCacheD, SNMP, StatsD, SysLog, + Table, Tail, UnixSock, vmem, VServer, Wireless, Write Riemann and XMMS + plugins, the core collectd daemon, the collectdmon, collectd-nagios + and collectd-tg utilities, all the Targets and Matches, liboconfig, + most of the "utils_*" files and the plugin API. + * Tests: A test suite has been added. Thanks to Florian Forster. + * Threshold: The hysteresis calculation has been made more reliable. + Thanks to Jan Kundrát. #581 + * Threshold: Various fixes and improvements have been made. Thanks to + Manuel Luis Sanmartín Rozada. #649, #644 + * AMQP plugin: The "ConnectionRetryDelay" option has been added, + allowing to delay reconnection. Thanks to Yoga Ramalingam and Marc + Fournier. #833 + * AMQP plugin: The "QueueDurable" and "QueueAutoDelete" options have + been added, giving control over queue creation and deletion. Thanks to + David Blundell and Marc Fournier. #623 + * Apache, Ascent, BIND, cURL, cURL-JSON, cURL-XML, nginx and Write HTTP + plugins: Customizing the "User-Agent" field is now possible at + compile-time. Thanks to Jeremy Katz. #440 + * Apache, Ascent, BIND, cURL, cURL-JSON, cURL-XML, nginx plugins: The + connection will be reset if it hasn't completed within the configured + "Interval". The new "Timeout" option gives control over this behavior. + Thanks to Jan Kundrát and Marc Fournier. #982, #983, #993 + * Apache, Ascent, cURL, cURL-JSON, cURL-XML, nginx, Write HTTP plugins: + Allow usernames and passwords to contain colons if built against + libcurl ≧ 7.19.1. Thanks to Marc Fournier. #695, #947 + * Apache plugin: The "SSLCiphers" option gives control over the + encryption algorithms to use with TLS connections. Thanks to Toni + Moreno. #946 + * Barometer plugin: This new plugin reads sensor data from various + Freescale and Bosch digital barometers. Thanks to Tomas Menzl. #69, + #693 + * Battery plugin: Reporting values as percentages and reporting degraded + batteries has been added. Thanks to Florian Forster. + * Battery plugin: Support for reading values from sysfs on Linux has + been added. Thanks to Andy Parkins, Nicholas Humfrey, Peter Wu and + Florian Forster. #725, #810, #998 + * Battery plugin: The value for current is no longer supplied unless the + battery provides this information. Thanks to Florian Forster. + * BIND plugin: Bind's XML v3 API is now supported; Thanks to Victor + Berger, Bruno Prémont and Michal Humpula. #742, #847 + * Ceph plugin: This new plugin collects statistics from the Ceph + distributed storage system. Thanks to Dan Ryder, Dennis Zou, Colin + McCabe, Sage Weil. #522, #598 + * ConnTrack plugin: Support for reporting values as percentages as well + as legacy conntrack files in "/proc" has been added. Thanks to + Pierre-Yves Ritschard. #497, #680 + * CPU plugin: The plugin is now able to report values as percentages and + aggregate values per-state and per-CPU. Thanks to Pierre-Yves + Ritschard, Florian Forster, Fabien Wernli, Nicholas Humfrey and + Wilfried Goesgens. #499, #516, #639 #734, #812, #802 + * cURL-JSON plugin: Extracting values from complex JSON structures has + been enhanced. Thanks to Jim Radford. #408, #411 + * cURL-JSON plugin: Intervals can now be configured on a per-URL basis. + Thanks to Stan Sawa. #685 + * cURL-JSON, cURL-XML, Write HTTP plugins: These plugins now also follow + HTTP redirects. Thanks to Marc Fournier. + * cURL, cURL-JSON, cURL-XML plugins: HTTP Digest authentication has been + implemented. Thanks to Frank Cornelis. #482 + * DBI, Oracle, PostgreSQL plugins: A "MetadataFrom" parameter has been + added which allows to set metadata from database columns. Thanks to + Mark Wong. #317, #321 + * DBI plugin: Querying several databases in parallel is now possible. + Thanks to Vincent Bernat. #453 + * Disk plugin: On the Linux platform, disk names can now get looked up + in udev with the "UdevNameAttr" option. Thanks to Patrick Mooney. #537 + * Disk plugin: This plugin now collects several additional I/O-related + metrics on the Linux platform. Thanks to Florian Forster and Michael + Schenck. #705, #759 + * DRBD plugin: This new plugin reads Linux's Distributed Replicated + Block Device (DRBD) statistics. Thanks to Tim Laszlo. #566, #700 + * Exec, UnixSock plugins: The "PUTNOTIF" command now allows to set + metadata on notifications. Thanks to John-John Tedro. #416 + * fhcount plugin: This new plugin reports the number of used file + handles. Thanks to Jiri Tyr. #1009 + * GenericJMX plugin: A Class Loader for "JMXConnectorFactory" has been + added, allowing the plugin to work with JBOSS > 7. Thanks to Alexandre + Moutot. #452 + * IPC plugin: This new plugin collects information related to shared + memory. Thanks to Andrés J. Díaz. #925 + * Java plugin: Now uses the hostname defined in the configuration file. + Thanks to Pierre-Yves Ritschard. #530, #681 + * Load plugin: The plugin is now able to report values as percentages. + Thanks to Vedran Bartonicek and Pierre-Yves Ritschard. #344, #498 + * Log Logstash plugin: This new plugin writes collectd logs and events + as Logstash JSON formatted events. Thanks to Pierre-Yves Ritschard. + #360 + * LVM plugin: The plugin collects thin pool data volumes size, and no + longer reports virtual volumes. Thanks to Benjamin Gilbert. #603 + * memcached plugin: "listen_disabled_num" are now also reported. Thanks + to Matt Cottingham. #622 + * Memory plugin: Slab memory reporting on the Linux platform has been + added. Thanks to Manuel CISSÉ and Marc Fournier. #560, #697 + * Memory plugin: The plugin is now able to report values as percentages. + Thanks to Jeremy Katz, Florian Forster and Manuel CISSÉ. #501, #511, + #559 + * Modbus plugin: Selecting between holding and input registers is now + possible. Thanks to Jan Vitek. #338 + * Modbus plugin: Support for accessing devices through an RS-485 serial + port has been added. Thanks to Eric Sandeen. + * Multimeter plugin: This plugin isn't built by default on the AIX + platform anymore. Thanks to Manuel Luis Sanmartin Rozada. #549, #684 + * MySQL and PostgreSQL plugins: Passing "127.0.0.1" as a host will now + result in the global Hostname being used in metric names. Thanks to + Jeremy Katz. #441 + * MySQL plugin: InnoDB, Select and Sort statistics collection has been + added. Thanks to Wilson Felipe, Marek Becka and Pierre-Yves Ritschard. + #248, #621, #699, #824 + * MySQL plugin: The "Alias" and "ConnectTimeout" options have been + added. Thanks to William Tisäter. + * Netlink plugin: Support for 64bit netlink counters has been added. + Thanks to Marek Becka. #435 + * Network plugin: The "ReconnectInterval" configuration option has been + added. Thanks to John Ferlito. #732 + * NFS plugin: Support for NFSv4.0 has been implemented. Thanks to Marek + Becka. #550 + * OneWire plugin: Support for more temperature-providing sensor families + has been added. Thanks to Tomasz Torcz. #672 + * OneWire plugin: Support for full OWFS path and more device families + has been implemented. Thanks to Tomas Menzl. #68 + * OpenLDAP plugin: This new plugin reads monitoring information from + OpenLDAP's "cn=Monitor" subtree. Thanks to Kimo Rosenbaum, Marc + Fournier and Nicholas Humfrey. #719 + * OpenVPN plugin: Support for OpenVPN 2.3.0 has been implemented. Thanks + to Ed Okerson. #252 + * OpenVZ plugin: Various improvements have been made, making the plugin + report values like the other collectd plugins do. Thanks to Chris + Lundquist. #264 + * Perl plugin: A new "listval_filter" method has been added, various + internal cleanups and improvements have been made and a test suite has + been added. Thanks to Matthias Bethke. #728 + * PostgreSQL plugin: The new "ExpireDelay" option allows skipping older + values pending write when the database slows down. Thanks to Stephen + O'Dor. #593 + * PowerDNS plugin: The plugin was updated for stats from pdns 3.4.3. + Thanks to Ruben Kerkhof. #965 + * Processes plugin: A memory-usage related optimization for low-profile + systems has been added. Thanks to Florian Forster. #652 + * Python plugin: Support for Python3 has been improved, "ModulePath" is + now prepended to "sys.path", and the "get_dataset()" function has been + added to the Python API. Thanks to Sven Trenkel and Patrick Browne. + #890, #751, #771 + * Redis and Write_Redis plugins: The support library has been switched + from credis to hiredis. Thanks to Andrés J. Díaz, Victor Seva, Marc + Fournier, Johan Bergström, Michael Spiegle and brianpkelly. #296, + #464, #475, #799, #1030 + * Redis plugin: Custom commands can now be used to fetch values stored + in Redis. Thanks to Pierre-Yves Ritschard. #816 + * Redis plugin: Support for passwords up to 512 characters long has been + added. Thanks to Jeremy Katz. #532 + * Sensors plugin: Support for lm_sensors' power sensors has been added. + Thanks to Jan Kundrát. #571 + * SMART plugin: This new plugin collects SMART statistics from disk + drives. Thanks to Vincent Bernat. #797 + * SNMP plugin: A blacklist/whitelist feature can now be used to filter + which OIDs to collect. Thanks to Christophe Courtaut. #414 + * SNMP plugin: SNMPv3 authentication and encryption support has been + implemented. Thanks to Michael Pilat. #362 + * SNMP plugin: Two error messages have been disambiguated. Thanks to + Sergey. #939, #952 + * Swap plugin: The plugin is now able to report values as percentages. + Thanks to Jeremy Katz and Florian Forster. #500, #510 + * Swap plugin: The plugin no longer fails on Linux systems where + "SwapCached" isn't exposed by the kernel. Thanks to Florian Forster. + #733 + * Tail plugin: "GaugeInc" and "GaugeAdd" options have been implemented. + Thanks to Andre Ferraz. #673 + * Tail plugin: Intervals can now be configured on a per-File basis. + Thanks to Tom Leaman. #446 + * TCPConns plugin: The "AllPortsSummary" option, allowing to summarize + all connections, has been added. Thanks to Marek Becka. #488 + * TCPConns plugin: Three metrics were renamed on the AIX platform, for + the sake of consistency. Thanks to Manuel Luis Sanmartín Rozada. #546 + * Turbostat plugin: This new plugin reads CPU frequency and C-state + residency on modern Intel turbo-capable processors. Thanks to Vincent + Brillault, Jean Delvare and Nicolas Iooss. #651 + * UnixSock plugin: The "GETTHRESHOLD" command has been re-added. Thanks + to Manuel Luis Sanmartín Rozada. #674 + * Varnish plugin: Varnish 4 support has been added, as well as as + monitoring metrics only available in Varnish 4. Thanks to Marc + Fournier. #618, #783 + * virt plugin: Guests memory usage is now also collected. Thanks to + Tiago Carvalho, jazzmes and Zollner Robert. + * virt plugin: It is now possible to chose between using guests' name or + UUID as plugin_instance. Thanks to Remi Ferrand. #385 + * virt plugin: The libvirt plugin has been renamed to virt. Thanks to + Florian Forster. + * Write Graphite plugin: When the connection to graphite fails, + reconnection attempts are now limited to once per second. Thanks to + Florian Forster. #625 + * Write HTTP plugin: Multi-instance support of this plugin has been + improved. The "" block has been deprecated in favor of + "". Thanks to Marc Fournier. #902 + * Write HTTP plugin: Several TLS-related configuration options have been + added. Thanks to Ingmar Runge. #666 + * Write HTTP plugin: The "LowSpeedLimit" and "Timeout" options allow to + reset slow/stalled network connections. Thanks to loginator17 and Marc + Fournier. #752, #985 + * Write HTTP plugin: The size of the payload posted to the HTTP server + can now be controlled with the "BufferSize" option. Thanks to Florian + Forster. #722 + * Write Kafka plugin: This new plugin sends data to Apache Kafka, a + distributed messaging queue. Thanks to Pierre-Yves Ritschard, + ciomaire, Vincent Bernat, Marc Fournier. #670, #694, #794, #853, #014 + * Write Log plugin: This new plugin dispatches collected values to the + configured log destination(s). Thanks to Pierre-Yves Ritschard. #886 + * Write Riemann plugin: Extra meta strings are now added as attributes + in notifications. Thanks to John-John Tedro. #417 + * Write Riemann plugin: Notification message are now sent to the Riemann + server via the description field. Thanks to Adrian Miron. #575 + * Write Riemann plugin: Support for custom attributes has been added. + Thanks to Pierre-Yves Ritschard. #459 + * Write Riemann plugin: Support had been implemented for sending events + to Riemann in batches (when using TCP), and is enabled by default. + Thanks to Pierre-Yves Ritschard. #800 + * Write Riemann plugin: The "EventServicePrefix" option has been added, + which adds a prefix to event service names. Thanks to Moshe Zada. #706 + * Write Riemann plugin: Threshold checks can now be passed down to the + Riemann server. Thanks to Pierre-Yves Ritschard. #518 + * Write Sensu plugin: This new plugin submits values to Sensu, a stream + processing and monitoring system. Thanks to Fabrice A. Marie and Marc + Fournier. #912, #1001, #1016 + * Write TSDB plugin: This new plugin sends data to OpenTSDB, a scalable + time series database. Thanks to Kevin Bowling, Florian Forster, Dallin + Young, Michael Schenck and Pierre-Yves Ritschard. #703, #772, #945 + * ZFS ARC plugin: Support for ZFS-on-Linux has been added. Thanks to + Marc Fournier and Wilfried Goesgens. #552 + * Zookeeper plugin: This new plugin reads data from the Apache Zookeeper + "MNTR" command. Thanks to Jeremy Katz. #826 + +2016-07-26, Version 5.4.3 + * Build system: A deprecation warning has been removed. Thanks to + Florian Forster. + * Build system: An ordering issue when build the AMQP plugin was + corrected. Thanks to Shahul Hameed. + * Build system: Building the gmond plugin against recent libganglia + versions has been added. Thanks to Marc Fournier. #1129 + * Build system: "collectd-tg" now builds on AIX. Thanks to Manuel Luis + Sanmartín Rozada. #542 + * Build system: "version-gen.sh" portablility was improved. Thanks to + Marc Fournier and Ruben Kerkhof. + * Build system: Compiling utils_dns.c on Solaris has beed fixed. Thanks + to Yves Mettier, Dagobert Michelsen and Florian Forster. #348 + * Build system: Default JDK detection got improved. Thanks to Ruben + Kerkhof and Marc Fournier. + * Build system: Detection and handling of librrd 1.6 and later has been + fixed. Thanks to Ruben Kerkhof. + * Build system: notify_email build options got corrected to make it + build on non-GNU libc systems. Thanks to Marc Fournier. + * Build system: Protobuf building and logging has been improved. Thanks + to Ruben Kerkhof. + * Build system: The "make distcheck" target was fixed to properly handle + java build artifacts. Thanks to Florian Forster. + * Build system: The configure script got fixed to work properly when + called with "CC="gcc -Wall -Werror"" . Thanks to Marc Fournier. + * Build system: The configure script will now fail if pkg-config isn't + available. Thanks to Ruben Kerkhof. + * Build system: The users plugin now builds properly on Solaris when + libstatgrab is available. Thanks to Dagobert Michelsen. #1061 + * Build system: Various fixes have been done to improve library + detection on FreeBSD. Thanks to Ruben Kerkhof. + * collectd2html: Several perl errors have been corrected. Thanks to Ruud + van Melick. #1103 + * collectd: A global gauge format-string is now used to avoid loss of + precision. Thanks to Florian Forster. #1039 + * collectd: A race condition at plugin initialization time was fixed. + Thanks to Jan Andres. #1316 + * collectd: Autoloading now properly sets plugin context, allowing + plugins to determine the interval. Thanks to Florian Forster. #1069 + * collectd: Empty "Plugin" blocks are now supported by the configuration + file parser. Thanks to Manuel Luis Sanmartín Rozada. #1035 + * collectd: The address of the Free Software Foundation has been fixed + in GPL license headers. Thanks to Ruben Kerkhof. + * collectd: Writing to a closed TCP socket is now properly handled. + Thanks to Tamás Földesi. #1104 + * Documentation: iptables plugin: IPv6 configuration option has been + added to the collectd.conf(5) manpage. Thanks to 'Marc Fournier''. + #1496 + * AMQP plugin: The plugin was fixed to build against librabbitmq 0.6.0. + Thanks to Remi Collet. #1008 + * Apache plugin: A warning about a possible misconfiguration has been + added. Thanks to Marc Fournier. + * Apache plugin: The plugin was extended to parse the whole response, + required to support Apache versions greater than 2.4.17. Thanks to + Marc Fournier and Florian Forster. #1170, #1343 + * APC UPS plugin: Log messages are now prefixed with the plugin name. + Thanks to Sergey. #1329 + * Bind plugin: The type_instance now gets properly sanitized. Thanks to + Thomas Kho. #992 + * CPU plugin: Error messages on MacOSX have been improved. Thanks to + Florian Forster. #22 + * cURL plugin: A typo in an error message got corrected. Thanks to Marc + Fournier. + * cURL, cURL-JSON and cURL-XML plugins: A memory leak when allocating + more memory fails has been fixed. Thanks to Brandon Arp. + * DF plugin: An bug preventing filesystems which don't report inodes + such as btrfs has been corrected. Thanks to Marek Becka. #1096 + * DF plugin: Duplicate entries are no longer reported twice. Thanks to + Stefan Brüns and Florian Forster. #1402 + * DF plugin: Legacy code for skipping "rootfs" mount points has been + removed. Thanks to Marc Fournier. #1402 + * DF plugin: Legacy references to the "ReportReserved" option have been + removed. Thanks to Marc Fournier. + * DF plugin: Reading the mtab now uses a reentrant function when + possible. Thanks to Ruben Kerkhof. #1163 + * Ethstat plugin: Code to strip leading whitespace from device names. + This works around an issue in the VMXNet3 driver. Thanks to Thomas + Guthmann. #1059 + * Exec plugin: A file descriptor leak when the plugin is configured to + run as a non-existing user was corrected. Thanks to Gautam BT and Marc + Fournier. #762 + * Exec plugin: A problem in the error handling of an fdopen() failure + has been fixed. Thanks to @ciomaire. + * Interface plugin: Documentation about regular expressions in the + ignore list has been added. Thanks to Jakub Jankowski. + * IRQ plugin: The "FIQ" line is now skipped as it doesn't contain any + counter. Thanks to Ruben Kerkhof. #971 + * Modbus plugin: The debug output has been disabled by default. It is + now only enabled when building with "--enable-debug". Thanks to Eric + Sandeen and Marc Fournier. + * MongoDB plugin: A memory leak has been fixed and some adaptations to + the current API of the mongo-c-driver have been made. Thanks to + Florian Forster. #956 + * Network plugin: A check for the initialization of secure memory has + been added. Previously, failure to initialize this memory was ignored. + Thanks to @yujokang. #1665 + * Network plugin: A heap overflow has been fixed in the server code. + This issue can be triggered remotely and is potentially exploitable. + Thanks to Emilien Gaspar. CVE-2016-6254 + * Network plugin: The TimeToLive option handling was made more robust. + Thanks to Tim Laszlo. #654 + * NTPd plugin: Documentation about the required "mode 7" has been added. + Thanks to Jakub Jankowski. + * NTPd plugin: Reporting of "time_offset-loop" was corrected to match + the values from ntpq/ntpdc. Thanks to Pierre Fersing and Florian + Forster. #1300 + * OpenVPN plugin: The plugin was fixe to avoid signaling an error when + no clients were connected. Thanks to Florian Forster. #731 + * Perl plugin: Init callbacks have been changed to run essentially + single-threaded to avoid race conditions by init functions which + create additional threads. Thanks to Pavel Rochnyack. #1706 + * PF plugin and DNS plugin: These plugins have been fixed to build + properly on OpenBSD again. Thanks to Ruben Kerkhof. + * Processes plugin: A compilation error on systems without "regex.h" has + been fixed. Thanks to Corey Kosak. + * Processes plugin: A memory leak on Solaris has been fixed. Thanks to + Jim Quinn. + * Processes plugin and Swap plugin: These plugins have been corrected to + also work inside FreeBSD jails. Thanks to biancalana. #1019 + * Processes plugin: A warning about too long process names has been + added. Thanks to Marc Fournier. #1284 + * Processes plugin: Process counting on the FreeBSD and OpenBSD + platforms has been fixed. Thanks to Herve COMMOWICK. #1298 + * Processes plugin: The plugin was fixed to work properly on Solaris. + Thanks to Jan Andres. #919 + * Python plugin: A double-free bug got fixed. Thanks to Sven Trenkel. + #1285 + * RRDtool plugin: A race condition leading to corrupt RRD file creation + has been fixed. Thanks to Manuel Luis Sanmartín Rozada. #1031 + * SNMP plugin: The "Gauge32" signedness was corrected to match RFC1902. + Thanks to Nathan Ward. #1325 + * StatsD plugin: A deadlock on plugin shutdown has been fixed. Thanks to + Pavel Rochnyack #1703 + * StatsD plugin: A memory leak was corrected. Thanks to Florian Forster. + #997 + * StatsD plugin: A symbol lookup error was fixed by properly linking the + plugin against libm. Thanks to Florian Forster. + * StatsD plugin: "utils_latency": Support for including values above + 1000 in percentile calculation has been added. Thanks to Yoga + Ramalingam. #401 + * StatsD plugin: "utils_latency": Two division by zero error conditions + have been corrected. Thanks to Wilfried Goesgens. #655 + * StatsD plugin: Counters absolute counts are now also reported. Thanks + to Pierre-Yves Ritschard. #1311 + * StatsD plugin: The plugin now emits NaN values when no timer event is + recorded. Thanks to Florian Forster. #1038, #1039 + * StatsD plugin: The plugin was corrected to avoid crashing when + negative timer values are submitted. Thanks to Florian Forster. #1131 + * Tail CSV plugin: The plugin was fixed to work properly with multiple + "Collect" options and a bug got fixed when no "TimeFrom" is specified. + Thanks to Manuel Luis Sanmartín Rozada and Florian Forster. #1032 + * TCPConns plugin: A memory leak was fixed. Thanks to Florian Forster. + #1074 + * TCPConns plugin: An bug causing collectd to enter an inifinite loop on + OpenBSD was fixed. Thanks to Landry Breuil. #1094 + * Threshold plugin: Threshold configuration blocks can now be defined in + different files. Thanks to Michael Salmon. #551 + * vmem plugin: Support for pgsteal in recent Linux kernels has been + added. Thanks to Jakub Jankowski. #1307 + * vmem plugin: The DSType for nr_dirtied and nr_written was corrected to + report a derive. Thanks to Marek Becka. #1072 + * Write Graphite plugin: Error handling when submitting metrics to the + server is now more robust. Thanks to Sam Pointer. #1364 + * Write HTTP plugin: Freeing of memory holding HTTP headers during + shutdown has been fixed. Thanks to Tolga Ceylan. + * Write Redis plugin: Multi-Valued key was made easier to parse by + adding a "|" character as a delimiter. Thanks to brianpkelly and + Florian Forster. #1070 + * Write Redis plugin: The timestamp format was corrected. Thanks to + Florian Forster. + * ZFS ARC plugin: The plugin was will not emit warning about missing + "l2_size" stats anymore. Thanks to Jan Andres. #919 + * 152 patches have been applied to numerous plugins and core components, + fixing various programming errors which were reported by scan-build, + libasan, FBInfer, coverity-scan, clang and gcc-6: Thanks to Ruben + Kerkhof, Florian Forster, Marc Fournier, Corey Kosak, Laurent, + Claudius Zingerli and Fabien Wernli. + +2015-02-26, Version 5.4.2 + * Build system: Numerous fixes. Thanks to Bjørn Nordbø, Jim Radford, + KOMEDA Shinji, Lauri Tirkkonen, Manuel Luis Sanmartin Rozada, Marc + Fournier, Rainer Müller, Yoga Ramalingam and Yves Mettier. #326, + #373, #653, #828 + * collectd: A use-after-free has been fixed in the "parse_value()" + function. Thanks to Matthias Urlichs. + * collectd: Fix carriage return sign in types_list Thanks to Marc + Fournier and @NsLib. + * collectd: Fix programming error in src/configfile.c. Thanks to + Wilfried Goesgens. + * collectd: An off-by-one error has been fixed in the + "strstripnewline()" function. Patch by Florian Forster. + * collectd: Use the complain mechanism to report filter chain write + failures. Thanks to Sebastian Harl. + * collectd: Spelling and grammar of error messages have been fixed. + Thanks to Katelyn Perry and Tim Laszlo. + * collectdctl: Fixed buffering issues which caused trouble on AIX and + Solaris. Thanks to Yoga Ramalingam. + * Documentation: Details and example about multi-instance filterchain + targets have been added. Thanks to Marc Fournier. + * Documentation: The "CollectStatistics" option of the rrdcached has + been documented. Thanks to Micha Krause. #907 + * Documentation: The write_redis has been documented. Thanks to Marc + Fournier. + * Documentation: The "GraphiteSeparateInstances" and + "GraphiteAlwaysAppendDS" options of the amqp have been documented. + Thanks to Marc Fournier. + * Documentation: Documentation of the "AutoLoadPlugin" option has been + improved. Thanks to Florian Forster. #715 + * aggregation: "utils_vl_lookup": A race when creating user objects + has been fixed. Thanks to Sebastian Harl. #535 + * cpu: Temperature code for Mac OS X has been removed. + Thanks to Florian Forster and Marc Fournier. #22 + * cURL, cURL-JSON, cURL-XML and Write HTTP plugins: Call + "curl_global_init()" in the plugins' "init()" callback. Thanks to + Jeremy Katz. + * cURL and memcachec plugins: Fix calculation of gauge, average, + minimum and maximum. Previously, they were calculated from the start + of the daemon, which is not the documented behavior. Thanks to + Florian Forster. #663 + * curl-json: A bug, which triggered when two URLs with a long common + prefix were configured, was fixed. Thanks to Marc Fournier. #582 + * dbi: Compatibility with new versions of libdbi has been restored. + Thanks to Florian Forster. #950 + * Exec, UnixSock plugins: Fix parsing of the "time" option of the + "PUTNOTIF" command. Thanks to Adrian Miron. #477 + * ipmi: A conflict with the java over the "SIGUSR2" signal has been + fixed. Thanks to Vincent Bernat. #114 + * java: Conversion from Java's time representation to collectd's + representation has been fixed. Thanks to Manuel Luis Sanmartín + Rozada. + * java: Make sure "cjni_thread_detach()" is called on all paths. + Thanks to Florian Forster. + * LogFile and SysLog plugins: Avoid total silence in case of a + misconfiguration. Thanks to Marc Fournier and Wilfried Goesgens. + * network: Support for recent versions of gcrypt has been added. + Thanks to Vincent Bernat. #632 + * network: Robustness of the client connecting behavior has been + improved. Thanks to Florian Forster. #627 + * python: Don't create empty "meta_data_t" objects. Thanks to Florian + Forster. #716 + * python: Fix Py list length check in "cpy_build_meta()". Thanks to + Yoga Ramalingam. + * python: The "interval" member was fixed to export seconds as a + double. Thanks to Justin Burnham. + * RRDtool and RRDCacheD plugins: A memory leak when creating RRD files + has been fixed. Thanks to Yves Mettier. #661 + * snmp: Fix a memory leak. Thanks to Marc Fournier and Pierre-Yves + Ritschard. #610, #804 + * statsd: Support for samplerates in timer metrics was added. Thanks + to John Leach. #461 + * swap: Fix behavior under OpenVZ by making "cached" optional. Thanks + to Florian Forster. #733 + * threshold: Population of the "time" field in notifications has been + added. Thanks to Manuel Luis Sanmartín Rozada. + * libvirt: Only gather stats for running domains. Thanks to Ruben + Kerkhof. + * lvm: An issue with Volume Groups (VGs) without Logical Volumes (LVs) + has been fixed. Thanks to Jan Kundrát. + * write_graphite: Escape characters not supported by Graphite. Thanks + to Pierre-Yves Ritschard and Marc Fournier. + * write_http: Make callback names context-dependent. Thanks to Marc + Fournier. #821 + * write_redis: A formatting bug, which resulted in totally unusable + numbers being transmitted to Redis, was fixed. Thanks to Marc + Fournier. + * write_riemann: Receive acknowledge message when using TCP. Thanks to + John-John Tedro. + +2014-01-26, Version 5.4.1 + * amqp plugin: Add support for RabbitMQ 0.4.x to avoid compiler + warnings. Thanks to Sebastian Harl for implementing this. + * apache / network plugins: Improved initialization order hopefully + resolved gcrypt initialization problems. + * aquaero plugin: The type used to submit fan utilization was fixed. + Thanks to Alex Deymo for the patch. + * cgroups plugin: A small memory leak was fixed. Checking the existence + of a mount option without a value was fixed. More permissive parsing + of the cpuacct.stats file fixes support for some versions of Linux. + Thanks to Marc Fournier for bug reports and patches. + * curl plugin: Fix blocks without an instance. Thanks to + Alexander Golovko for reporting and Sebastian Harl for fixing this. + * curl_json plugin: Potentially invalid memory access has been + sanitized. Thanks to Jim Radford for his patch. + * interface plugin: Fix behavior under FreeBSD 10: Reporting of + per-address statistics caused duplicate updates to the same metric. + Thanks to demon / @trtrmitya for the patch. + * write_graphite plugin: Use TCP to connect to Graphite by default. The + default changed from TCP to UDP between 5.3.1 and 5.4.0, which is a + regression. Thanks to Marc Fournier for fixing this. Reconnect + behavior was improved. Thanks to Michael Hart for his patch. + * zfs_arc plugin: Collect "allocated" and "stolen" on FreeBSD only. + 2013-08-18, Version 5.4.0 * collectd: The "LoadPlugin" config option no longer attempts to load plugins twice. If more than one "LoadPlugin" statement or block is @@ -50,6 +1939,95 @@ * zfs_arc plugin: Support for FreeBSD has been added. Thanks to Xin Li for his patch. +2015-02-26, Version 5.3.2 + * Build system: Numerous fixes. Thanks to Bjørn Nordbø, Jim Radford, + KOMEDA Shinji, Lauri Tirkkonen, Manuel Luis Sanmartin Rozada, Marc + Fournier, Rainer Müller, Yoga Ramalingam and Yves Mettier. #326, + #373, #653, #828 + * collectd: A use-after-free has been fixed in the "parse_value()" + function. Thanks to Matthias Urlichs. + * collectd: Fix carriage return sign in types_list Thanks to Marc + Fournier and @NsLib. + * collectd: Fix programming error in src/configfile.c Thanks to + Wilfried Goesgens. + * collectd: An off-by-one error has been fixed in the + "strstripnewline()" function. Patch by Florian Forster. + * collectd: Use the complain mechanism to report filter chain write + failures. Thanks to Sebastian Harl. + * collectd: Spelling and grammar of error messages have been fixed. + Thanks to Katelyn Perry and Tim Laszlo. + * collectdctl: Fixed buffering issues which caused trouble on AIX and + Solaris. Thanks to Yoga Ramalingam. + * Documentation: Details and example about multi-instance filterchain + targets have been added. Thanks to Marc Fournier. + * Documentation: The "CollectStatistics" option of the rrdcached has + been documented. Thanks to Micha Krause. #907 + * Documentation: The write_redis has been documented. Thanks to Marc + Fournier. + * Documentation: The synopsis of the threshold has been fixed. Thanks + to Fabien Wernli. + * Documentation: The "GraphiteSeparateInstances" and + "GraphiteAlwaysAppendDS" options of the amqp have been documented. + Thanks to Marc Fournier. + * aggregation: "utils_vl_lookup": A race when creating user objects + has been fixed. Thanks to Sebastian Harl. #535 + * cpu: Temperature code for Mac OS X has been removed. + Thanks to Florian Forster and Marc Fournier. #22 + * csv: A regression which would lead to the "DataDir" option to be + ignored has been fixed. Thanks to Manuel Luis Sanmartin Rozada. + * curl, curl-json, curl-xml and write_http plugins: Call + "curl_global_init()" in the plugins' "init()" callback. Thanks to + Jeremy Katz. + * curl and memcachec plugins: Fix calculation of gauge, average, + minimum and maximum. Previously, they were calculated from the start + of the daemon, which is not the documented behavior. Thanks to + Florian Forster. #663 + * dbi plugin: Compatibility with new versions of libdbi has been + restored. Thanks to Florian Forster. #950 + * exec, unixsock plugins: Fix parsing of the "time" option of the + "PUTNOTIF" command. Thanks to Adrian Miron. #477 + * java: Conversion from Java's time representation to collectd's + representation has been fixed. Thanks to Manuel Luis Sanmartín + Rozada. + * ipmi: A conflict with the java over the "SIGUSR2" signal has been + fixed. Thanks to Vincent Bernat. #114 + * java: Make sure "cjni_thread_detach()" is called on all paths. + Thanks to Florian Forster. + * logfile and syslog plugins: Avoid total silence in case of a + misconfiguration. Thanks to Marc Fournier and Wilfried Goesgens. + * memcached: Connecting to a UNIX socket has been fixed. Thanks to Jim + Radford. + * network: Support for recent versions of gcrypt has been added. + Thanks to Vincent Bernat. #632 + * network: Robustness of the client connecting behavior has been + improved. Thanks to Florian Forster. #627 + * python: Don't create empty "meta_data_t" objects. Thanks to Florian + Forster. #716 + * python: Fix Py list length check in "cpy_build_meta()". Thanks to + Yoga Ramalingam. + * python: The "interval" member was fixed to export seconds as a + double. Thanks to Justin Burnham. + * replace and set targets: Fix error message. Thanks to Marc Fournier. + #448 + * rrdtool and rrdcached plugins: Honor the "DataDir" config option; + this fixes a regression. Thanks to Florian Forster. #380 + * rrdtool and rrdcached plugins: A memory leak when creating RRD files + has been fixed. Thanks to Yves Mettier. #661 + * snmp: Fix a memory leak. Thanks to Marc Fournier and Pierre-Yves + Ritschard. #610, #804 + * swap: Fix behavior under OpenVZ by making "cached" optional. Thanks + to Florian Forster. #733 + * threshold: Population of the "time" field in notifications has been + added. Thanks to Manuel Luis Sanmartín Rozada. + * libvirt: Only gather stats for running domains. Thanks to Ruben + Kerkhof. + * write_graphite: Escape characters not supported by Graphite. Thanks + to Pierre-Yves Ritschard and Marc Fournier. + * write_http: Make callback names context-dependent. Thanks to Marc + Fournier. #821 + * write_riemann: Receive acknowledge message when using TCP. Thanks to + John-John Tedro. + 2013-07-13, Version 5.3.1 * Documentation: Various fixes. * Configuration: Fix error handling: Errors in included files were @@ -1632,7 +3610,7 @@ 2008-07-15, Version 4.4.2 * build system: Use pkg-config to detect the upsclient library. - * collectd: Try even harder to determine the endianess of the + * collectd: Try even harder to determine the endianness of the architecture collectd is being built on. * disk plugin: Fix for Linux 2.4: A wrong field was used as the name of disks. @@ -1697,7 +3675,7 @@ 2008-08-30, Version 4.3.4 * Build system: Improved detection of and linking with the statgrab library. - * collectd: Portability fixes, especially to determine endianess more + * collectd: Portability fixes, especially to determine endianness more reliable. * Various plugins: Fix format strings. * disk plugin: A fix for giving disks under Linux 2.4 the right names diff --git a/Makefile.am b/Makefile.am index 52671235e5..cb8205fccb 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,17 +1,2492 @@ -ACLOCAL_AMFLAGS = -I libltdl/m4 +ACLOCAL_AMFLAGS = -I m4 +AM_YFLAGS = -d -SUBDIRS = libltdl src bindings . +if BUILD_WIN32 +cpkgdatadir=$(datadir) +cpkglibdir=$(libdir)/plugins +cpkglocalstatedir=${localstatedir} +else +cpkgdatadir=$(pkgdatadir) +cpkglibdir=$(pkglibdir) +cpkglocalstatedir=${localstatedir}/lib/${PACKAGE_NAME} +endif -INCLUDES = $(LTDLINCL) +BUILT_SOURCES = \ + src/libcollectdclient/collectd/lcc_features.h \ + src/liboconfig/parser.h \ + $(dist_man_MANS) -EXTRA_DIST = contrib version-gen.sh + +CLEANFILES = \ + .perl-directory-stamp \ + bindings/buildperl/Collectd.pm \ + bindings/buildperl/Collectd/Plugins/OpenVZ.pm \ + bindings/buildperl/Collectd/Unixsock.pm \ + bindings/buildperl/Makefile.PL \ + collectd-api.jar \ + collectd.grpc.pb.cc \ + collectd.grpc.pb.h \ + collectd.pb.cc \ + collectd.pb.h \ + generic-jmx.jar \ + org/collectd/api/*.class \ + org/collectd/java/*.class \ + prometheus.pb-c.c \ + prometheus.pb-c.h \ + src/pinba.pb-c.c \ + src/pinba.pb-c.h \ + types.pb.cc \ + types.pb.h + + +EXTRA_DIST = \ + bindings/perl/Makefile.PL \ + bindings/perl/lib/Collectd.pm \ + bindings/perl/lib/Collectd/Plugins/Monitorus.pm \ + bindings/perl/lib/Collectd/Plugins/OpenVZ.pm \ + bindings/perl/lib/Collectd/Unixsock.pm \ + bindings/perl/uninstall_mod.pl \ + contrib \ + proto/collectd.proto \ + proto/prometheus.proto \ + proto/types.proto \ + src/collectd-email.pod \ + src/collectd-exec.pod \ + src/collectd-java.pod \ + src/collectd-lua.pod \ + src/collectd-nagios.pod \ + src/collectd-perl.pod \ + src/collectd-python.pod \ + src/collectd-snmp.pod \ + src/collectd-tg.pod \ + src/collectd-threshold.pod \ + src/collectd-unixsock.pod \ + src/collectd.conf.pod \ + src/collectd.pod \ + src/collectdctl.pod \ + src/collectdmon.pod \ + src/pinba.proto \ + src/postgresql_default.conf \ + src/types.db \ + src/types.db.pod \ + src/valgrind.FreeBSD.suppress \ + src/valgrind.suppress \ + testwrapper.sh \ + version-gen.sh + + +dist_man_MANS = \ + src/collectd.1 \ + src/collectd.conf.5 \ + src/collectd-email.5 \ + src/collectd-exec.5 \ + src/collectdctl.1 \ + src/collectd-java.5 \ + src/collectd-lua.5 \ + src/collectdmon.1 \ + src/collectd-nagios.1 \ + src/collectd-perl.5 \ + src/collectd-python.5 \ + src/collectd-snmp.5 \ + src/collectd-tg.1 \ + src/collectd-threshold.5 \ + src/collectd-unixsock.5 \ + src/types.db.5 + + +nodist_pkgconfig_DATA = \ + src/libcollectdclient/libcollectdclient.pc + +pkginclude_HEADERS = \ + src/libcollectdclient/collectd/client.h \ + src/libcollectdclient/collectd/lcc_features.h \ + src/libcollectdclient/collectd/network_buffer.h \ + src/libcollectdclient/collectd/network.h \ + src/libcollectdclient/collectd/network_parse.h \ + src/libcollectdclient/collectd/server.h \ + src/libcollectdclient/collectd/types.h + +lib_LTLIBRARIES = libcollectdclient.la + +if BUILD_WIN32 +# TODO: Build all executables on Windows as well. +sbin_PROGRAMS = \ + collectd + +bin_PROGRAMS = +else +sbin_PROGRAMS = \ + collectd \ + collectdmon + + +bin_PROGRAMS = \ + collectd-nagios \ + collectd-tg \ + collectdctl +endif # BUILD_WIN32 + + +noinst_LTLIBRARIES = \ + libavltree.la \ + libcmds.la \ + libcommon.la \ + libformat_graphite.la \ + libformat_json.la \ + libheap.la \ + libignorelist.la \ + liblatency.la \ + libllist.la \ + liblookup.la \ + libmetadata.la \ + libmount.la \ + liboconfig.la + + +check_LTLIBRARIES = \ + libplugin_mock.la + + +check_PROGRAMS = \ + test_common \ + test_format_graphite \ + test_meta_data \ + test_utils_avltree \ + test_utils_cmds \ + test_utils_heap \ + test_utils_latency \ + test_utils_message_parser \ + test_utils_mount \ + test_utils_subst \ + test_utils_time \ + test_utils_vl_lookup \ + test_libcollectd_network_parse \ + test_utils_config_cores + + +TESTS = $(check_PROGRAMS) + +LOG_COMPILER = env VALGRIND="@VALGRIND@" $(abs_srcdir)/testwrapper.sh + + +jardir = $(cpkgdatadir)/java + +pkglib_LTLIBRARIES = + + +PLUGIN_LDFLAGS = \ + -module \ + -avoid-version \ + -export-symbols-regex '\' +if BUILD_WIN32 +PLUGIN_LDFLAGS += -shared -no-undefined -lcollectd -L. +endif + + +AM_CPPFLAGS = \ + -I$(top_srcdir)/src -I$(top_srcdir)/src/daemon \ + -DPREFIX='"${prefix}"' \ + -DCONFIGFILE='"${sysconfdir}/${PACKAGE_NAME}.conf"' \ + -DLOCALSTATEDIR='"${localstatedir}"' \ + -DPKGLOCALSTATEDIR='"${cpkglocalstatedir}"' \ + -DPLUGINDIR='"${cpkglibdir}"' \ + -DPKGDATADIR='"${cpkgdatadir}"' +if BUILD_WIN32 +AM_CPPFLAGS += -DNOGDI +endif + +COMMON_DEPS = +if BUILD_WIN32 +COMMON_DEPS += collectd.exe +endif + +# Link to these libraries.. +COMMON_LIBS = $(PTHREAD_LIBS) +if BUILD_WIN32 +COMMON_LIBS += -lws2_32 +endif +if BUILD_WITH_GNULIB +COMMON_LIBS += -lgnu +endif +if BUILD_WITH_CAPABILITY +COMMON_LIBS += -lcap +endif +if BUILD_WITH_LIBRT +COMMON_LIBS += -lrt +endif +if BUILD_WITH_LIBPOSIX4 +COMMON_LIBS += -lposix4 +endif +if BUILD_WITH_LIBSOCKET +COMMON_LIBS += -lsocket +endif +if BUILD_WITH_LIBKSTAT +COMMON_LIBS += -lkstat +endif +if BUILD_WITH_LIBDEVINFO +COMMON_LIBS += -ldevinfo +endif + + +collectd_SOURCES = \ + src/daemon/cmd.h \ + src/daemon/collectd.c \ + src/daemon/collectd.h \ + src/daemon/configfile.c \ + src/daemon/configfile.h \ + src/daemon/filter_chain.c \ + src/daemon/filter_chain.h \ + src/daemon/globals.c \ + src/daemon/globals.h \ + src/utils/metadata/meta_data.c \ + src/utils/metadata/meta_data.h \ + src/daemon/plugin.c \ + src/daemon/plugin.h \ + src/daemon/utils_cache.c \ + src/daemon/utils_cache.h \ + src/daemon/utils_complain.c \ + src/daemon/utils_complain.h \ + src/daemon/utils_random.c \ + src/daemon/utils_random.h \ + src/daemon/utils_subst.c \ + src/daemon/utils_subst.h \ + src/daemon/utils_time.c \ + src/daemon/utils_time.h \ + src/daemon/types_list.c \ + src/daemon/types_list.h \ + src/daemon/utils_threshold.c \ + src/daemon/utils_threshold.h + + +collectd_CFLAGS = $(AM_CFLAGS) +collectd_CPPFLAGS = $(AM_CPPFLAGS) +collectd_LDFLAGS = -export-dynamic +collectd_LDADD = \ + libavltree.la \ + libcommon.la \ + libheap.la \ + libllist.la \ + liboconfig.la \ + -lm \ + $(COMMON_LIBS) \ + $(DLOPEN_LIBS) + +if BUILD_WIN32 +collectd_SOURCES += src/daemon/cmd_windows.c +collectd_LDFLAGS += -ldl -Wl,--out-implib,libcollectd.a +else +collectd_SOURCES += src/daemon/cmd.c +endif + +if BUILD_FEATURE_DAEMON +collectd_CPPFLAGS += -DPIDFILE='"${localstatedir}/run/${PACKAGE_NAME}.pid"' +endif + +# The daemon needs to call sg_init, so we need to link it against libstatgrab, +# too. -octo +if BUILD_WITH_LIBSTATGRAB +collectd_CFLAGS += $(BUILD_WITH_LIBSTATGRAB_CFLAGS) +collectd_LDADD += $(BUILD_WITH_LIBSTATGRAB_LDFLAGS) +endif + +if BUILD_WIN32 +collectd_LDFLAGS += -Wl,--out-implib,libcollectd.a +endif + +collectdmon_SOURCES = src/collectdmon.c + + +collectd_nagios_SOURCES = src/collectd-nagios.c +collectd_nagios_CPPFLAGS = $(AM_CPPFLAGS) \ + -I$(srcdir)/src/libcollectdclient \ + -I$(top_builddir)/src/libcollectdclient +collectd_nagios_LDADD = libcollectdclient.la +if BUILD_WITH_LIBSOCKET +collectd_nagios_LDADD += -lsocket +endif +if BUILD_AIX +collectd_nagios_LDADD += -lm +endif + + +collectdctl_SOURCES = src/collectdctl.c +collectdctl_CPPFLAGS = $(AM_CPPFLAGS) \ + -I$(srcdir)/src/libcollectdclient \ + -I$(top_builddir)/src/libcollectdclient +collectdctl_LDADD = libcollectdclient.la +if BUILD_WITH_LIBSOCKET +collectdctl_LDADD += -lsocket +endif +if BUILD_AIX +collectdctl_LDADD += -lm +endif + + +collectd_tg_SOURCES = src/collectd-tg.c +collectd_tg_CPPFLAGS = $(AM_CPPFLAGS) \ + -I$(srcdir)/src/libcollectdclient \ + -I$(top_builddir)/src/libcollectdclient +collectd_tg_LDADD = \ + $(PTHREAD_LIBS) \ + libheap.la \ + libcollectdclient.la +if BUILD_WITH_LIBSOCKET +collectd_tg_LDADD += -lsocket +endif +if BUILD_WITH_LIBRT +collectd_tg_LDADD += -lrt +endif +if BUILD_AIX +collectd_tg_LDADD += -lm +endif + + +test_common_SOURCES = \ + src/utils/common/common_test.c \ + src/testing.h +test_common_LDADD = libplugin_mock.la + +test_meta_data_SOURCES = \ + src/utils/metadata/meta_data_test.c \ + src/testing.h +test_meta_data_LDADD = libmetadata.la libplugin_mock.la + +test_utils_avltree_SOURCES = \ + src/utils/avltree/avltree_test.c \ + src/testing.h +test_utils_avltree_LDADD = libavltree.la $(COMMON_LIBS) + +test_utils_heap_SOURCES = \ + src/utils/heap/heap_test.c \ + src/testing.h +test_utils_heap_LDADD = libheap.la $(COMMON_LIBS) + +test_utils_message_parser_SOURCES = \ + src/utils/message_parser/message_parser_test.c \ + src/testing.h \ + src/daemon/configfile.c \ + src/daemon/types_list.c \ + src/utils_tail_match.c src/utils_tail_match.h \ + src/utils/tail/tail.c src/utils/tail/tail.h \ + src/utils/match/match.c src/utils/match/match.h \ + src/utils/latency/latency.c src/utils/latency/latency.h \ + src/utils/latency/latency_config.c src/utils/latency/latency_config.h +test_utils_message_parser_CPPFLAGS = $(AM_CPPFLAGS) +test_utils_message_parser_LDADD = liboconfig.la libplugin_mock.la -lm + +test_utils_time_SOURCES = \ + src/daemon/utils_time_test.c \ + src/testing.h + +test_utils_subst_SOURCES = \ + src/daemon/utils_subst_test.c \ + src/testing.h \ + src/daemon/utils_subst.c \ + src/daemon/utils_subst.h +test_utils_subst_LDADD = libplugin_mock.la + +test_utils_config_cores_SOURCES = \ + src/utils/config_cores/config_cores_test.c \ + src/testing.h +test_utils_config_cores_LDADD = libplugin_mock.la + +libavltree_la_SOURCES = \ + src/utils/avltree/avltree.c \ + src/utils/avltree/avltree.h + +libcommon_la_SOURCES = \ + src/utils/common/common.c \ + src/utils/common/common.h +libcommon_la_LIBADD = $(COMMON_LIBS) + +libheap_la_SOURCES = \ + src/utils/heap/heap.c \ + src/utils/heap/heap.h + +libignorelist_la_SOURCES = \ + 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 + +libplugin_mock_la_SOURCES = \ + src/daemon/plugin_mock.c \ + src/daemon/utils_cache_mock.c \ + src/daemon/utils_complain.c \ + src/daemon/utils_complain.h \ + src/daemon/utils_time.c \ + src/daemon/utils_time.h + +libplugin_mock_la_CPPFLAGS = $(AM_CPPFLAGS) -DMOCK_TIME +libplugin_mock_la_LIBADD = libcommon.la libignorelist.la $(COMMON_LIBS) + +libformat_graphite_la_SOURCES = \ + src/utils/format_graphite/format_graphite.c \ + src/utils/format_graphite/format_graphite.h + +test_format_graphite_SOURCES = \ + src/utils/format_graphite/format_graphite_test.c \ + src/testing.h +test_format_graphite_LDADD = \ + libformat_graphite.la \ + libmetadata.la \ + libplugin_mock.la \ + -lm + +libformat_json_la_SOURCES = \ + src/utils/format_json/format_json.c \ + src/utils/format_json/format_json.h +libformat_json_la_CPPFLAGS = $(AM_CPPFLAGS) +libformat_json_la_LDFLAGS = $(AM_LDFLAGS) +libformat_json_la_LIBADD = +if BUILD_WITH_LIBYAJL +libformat_json_la_CPPFLAGS += $(BUILD_WITH_LIBYAJL_CPPFLAGS) +libformat_json_la_LDFLAGS += $(BUILD_WITH_LIBYAJL_LDFLAGS) +libformat_json_la_LIBADD += $(BUILD_WITH_LIBYAJL_LIBS) + +check_PROGRAMS += test_format_json + +test_format_json_SOURCES = \ + src/utils/format_json/format_json_test.c \ + src/testing.h +test_format_json_LDADD = \ + libformat_json.la \ + libmetadata.la \ + libplugin_mock.la \ + -lm +endif + +if BUILD_PLUGIN_CEPH +test_plugin_ceph_SOURCES = src/ceph_test.c +test_plugin_ceph_CPPFLAGS = $(AM_CPPFLAGS) $(BUILD_WITH_LIBYAJL_CPPFLAGS) +test_plugin_ceph_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_LIBYAJL_LDFLAGS) +test_plugin_ceph_LDADD = libplugin_mock.la $(BUILD_WITH_LIBYAJL_LIBS) +check_PROGRAMS += test_plugin_ceph +endif + +liblatency_la_SOURCES = \ + src/utils/latency/latency.c \ + src/utils/latency/latency.h \ + src/utils/latency/latency_config.c \ + src/utils/latency/latency_config.h +liblatency_la_LIBADD = \ + libcommon.la \ + -lm + +test_utils_latency_SOURCES = \ + src/utils/latency/latency_test.c \ + src/testing.h +test_utils_latency_LDADD = \ + liblatency.la \ + libplugin_mock.la \ + -lm + +libcmds_la_SOURCES = \ + src/utils/cmds/cmds.c \ + src/utils/cmds/cmds.h \ + src/utils/cmds/flush.c \ + src/utils/cmds/flush.h \ + src/utils/cmds/getthreshold.c \ + src/utils/cmds/getthreshold.h \ + src/utils/cmds/getval.c \ + src/utils/cmds/getval.h \ + src/utils/cmds/listval.c \ + src/utils/cmds/listval.h \ + src/utils/cmds/putnotif.c \ + src/utils/cmds/putnotif.h \ + src/utils/cmds/putval.c \ + src/utils/cmds/putval.h \ + src/utils/cmds/parse_option.c \ + src/utils/cmds/parse_option.h +libcmds_la_LIBADD = \ + libcommon.la \ + libmetadata.la \ + -lm + +test_utils_cmds_SOURCES = \ + src/utils/cmds/cmds_test.c \ + src/testing.h +test_utils_cmds_LDADD = \ + libcmds.la \ + libplugin_mock.la + +liblookup_la_SOURCES = \ + src/utils/lookup/vl_lookup.c \ + src/utils/lookup/vl_lookup.h +liblookup_la_LIBADD = libavltree.la + +test_utils_vl_lookup_SOURCES = \ + src/utils/lookup/vl_lookup_test.c \ + src/testing.h +test_utils_vl_lookup_LDADD = \ + liblookup.la \ + libplugin_mock.la +if BUILD_WITH_LIBKSTAT +test_utils_vl_lookup_LDADD += -lkstat +endif + +libmount_la_SOURCES = \ + src/utils/mount/mount.c \ + src/utils/mount/mount.h + +test_utils_mount_SOURCES = \ + src/utils/mount/mount_test.c \ + src/testing.h +test_utils_mount_LDADD = \ + libmount.la \ + libplugin_mock.la +if BUILD_WITH_LIBKSTAT +test_utils_mount_LDADD += -lkstat +endif + + +libcollectdclient_la_SOURCES = \ + src/libcollectdclient/client.c \ + src/libcollectdclient/network.c \ + src/libcollectdclient/network_buffer.c \ + src/libcollectdclient/network_parse.c \ + src/libcollectdclient/server.c \ + src/libcollectdclient/collectd/stdendian.h +libcollectdclient_la_CPPFLAGS = \ + $(AM_CPPFLAGS) \ + -I$(srcdir)/src/libcollectdclient \ + -I$(top_builddir)/src/libcollectdclient \ + -I$(srcdir)/src/daemon +libcollectdclient_la_LDFLAGS = -version-info 2:0:1 +libcollectdclient_la_LIBADD = -lm +if BUILD_WIN32 +libcollectdclient_la_LDFLAGS += -shared -no-undefined +libcollectdclient_la_LIBADD += -lgnu -lws2_32 -liphlpapi +endif +if BUILD_WITH_LIBGCRYPT +libcollectdclient_la_CPPFLAGS += $(GCRYPT_CPPFLAGS) +libcollectdclient_la_LDFLAGS += $(GCRYPT_LDFLAGS) +libcollectdclient_la_LIBADD += $(GCRYPT_LIBS) +endif + +# network_parse_test.c includes network_parse.c, so no need to link with +# libcollectdclient.so. +test_libcollectd_network_parse_SOURCES = src/libcollectdclient/network_parse_test.c +test_libcollectd_network_parse_CPPFLAGS = \ + $(AM_CPPFLAGS) \ + -I$(srcdir)/src/libcollectdclient \ + -I$(top_builddir)/src/libcollectdclient +if BUILD_WITH_LIBGCRYPT +test_libcollectd_network_parse_CPPFLAGS += $(GCRYPT_CPPFLAGS) +test_libcollectd_network_parse_LDFLAGS = $(GCRYPT_LDFLAGS) +test_libcollectd_network_parse_LDADD = $(GCRYPT_LIBS) +endif + +liboconfig_la_SOURCES = \ + src/liboconfig/oconfig.c \ + src/liboconfig/oconfig.h \ + src/liboconfig/aux_types.h \ + src/liboconfig/scanner.l \ + src/liboconfig/parser.y +liboconfig_la_CPPFLAGS = -I$(srcdir)/src/liboconfig $(AM_CPPFLAGS) +liboconfig_la_LDFLAGS = -avoid-version $(LEXLIB) + +if BUILD_WITH_LIBCURL +if BUILD_WITH_LIBSSL +if BUILD_WITH_LIBYAJL2 +noinst_LTLIBRARIES += liboauth.la +liboauth_la_SOURCES = \ + src/utils/oauth/oauth.c \ + src/utils/oauth/oauth.h +liboauth_la_CPPFLAGS = \ + $(AM_CPPFLAGS) \ + $(BUILD_WITH_LIBCURL_CFLAGS) \ + $(BUILD_WITH_LIBSSL_CFLAGS) \ + $(BUILD_WITH_LIBYAJL_CPPFLAGS) +liboauth_la_LIBADD = \ + $(BUILD_WITH_LIBCURL_LIBS) \ + $(BUILD_WITH_LIBSSL_LIBS) \ + $(BUILD_WITH_LIBYAJL_LIBS) + +check_PROGRAMS += test_utils_oauth +TESTS += test_utils_oauth +test_utils_oauth_SOURCES = \ + src/utils/oauth/oauth_test.c +test_utils_oauth_LDADD = \ + liboauth.la \ + libcommon.la \ + libplugin_mock.la + +noinst_LTLIBRARIES += libgce.la +libgce_la_SOURCES = \ + src/utils/gce/gce.c \ + src/utils/gce/gce.h +libgce_la_CPPFLAGS = \ + $(AM_CPPFLAGS) \ + $(BUILD_WITH_LIBCURL_CFLAGS) +libgce_la_LIBADD = \ + $(BUILD_WITH_LIBCURL_LIBS) +endif +endif +endif + +if BUILD_WITH_LIBYAJL2 +noinst_LTLIBRARIES += libformat_stackdriver.la +libformat_stackdriver_la_SOURCES = \ + src/utils/format_stackdriver/format_stackdriver.c \ + src/utils/format_stackdriver/format_stackdriver.h +libformat_stackdriver_la_CPPFLAGS = \ + $(AM_CPPFLAGS) \ + $(BUILD_WITH_LIBYAJL_CPPFLAGS) +libformat_stackdriver_la_LIBADD = \ + libavltree.la \ + $(BUILD_WITH_LIBSSL_LIBS) \ + $(BUILD_WITH_LIBYAJL_LIBS) + +check_PROGRAMS += test_format_stackdriver +TESTS += test_format_stackdriver +test_format_stackdriver_SOURCES = \ + src/utils/format_stackdriver/format_stackdriver_test.c \ + src/testing.h +test_format_stackdriver_LDADD = \ + libformat_stackdriver.la \ + libplugin_mock.la \ + -lm +endif + +if BUILD_PLUGIN_AGGREGATION +pkglib_LTLIBRARIES += aggregation.la +aggregation_la_SOURCES = \ + src/aggregation.c \ + src/utils/lookup/vl_lookup.c \ + src/utils/lookup/vl_lookup.h +aggregation_la_LDFLAGS = $(PLUGIN_LDFLAGS) +aggregation_la_LIBADD = -lm +endif + +if BUILD_PLUGIN_AMQP +pkglib_LTLIBRARIES += amqp.la +amqp_la_SOURCES = src/amqp.c +amqp_la_CPPFLAGS = $(AM_CPPFLAGS) $(BUILD_WITH_LIBRABBITMQ_CPPFLAGS) +amqp_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_LIBRABBITMQ_LDFLAGS) +amqp_la_LIBADD = \ + $(BUILD_WITH_LIBRABBITMQ_LIBS) \ + libcmds.la \ + libformat_graphite.la \ + libformat_json.la +endif + +if BUILD_PLUGIN_AMQP1 +pkglib_LTLIBRARIES += amqp1.la +amqp1_la_SOURCES = \ + src/amqp1.c \ + src/utils/deq/deq.h +amqp1_la_CPPFLAGS = $(AM_CPPFLAGS) $(BUILD_WITH_LIBQPIDPROTON_CPPFLAGS) +amqp1_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_LIBQPIDPROTON_LDFLAGS) +amqp1_la_LIBADD = \ + $(BUILD_WITH_LIBQPIDPROTON_LIBS) \ + libcmds.la \ + libformat_graphite.la \ + libformat_json.la +endif + +if BUILD_PLUGIN_APACHE +pkglib_LTLIBRARIES += apache.la +apache_la_SOURCES = src/apache.c +apache_la_CFLAGS = $(AM_CFLAGS) $(BUILD_WITH_LIBCURL_CFLAGS) +apache_la_LDFLAGS = $(PLUGIN_LDFLAGS) +apache_la_LIBADD = $(BUILD_WITH_LIBCURL_LIBS) +endif + + +if BUILD_PLUGIN_APCUPS +pkglib_LTLIBRARIES += apcups.la +apcups_la_SOURCES = src/apcups.c +apcups_la_LDFLAGS = $(PLUGIN_LDFLAGS) +apcups_la_LIBADD = +if BUILD_WITH_LIBSOCKET +apcups_la_LIBADD += -lsocket +endif +endif + +if BUILD_PLUGIN_APPLE_SENSORS +pkglib_LTLIBRARIES += apple_sensors.la +apple_sensors_la_SOURCES = src/apple_sensors.c +apple_sensors_la_LDFLAGS = $(PLUGIN_LDFLAGS) -framework IOKit +endif + +if BUILD_PLUGIN_AQUAERO +pkglib_LTLIBRARIES += aquaero.la +aquaero_la_SOURCES = src/aquaero.c +aquaero_la_CFLAGS = $(AM_CFLAGS) $(BUILD_WITH_LIBAQUAERO5_CFLAGS) +aquaero_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_LIBAQUAERO5_LDFLAGS) +aquaero_la_LIBADD = -laquaero5 +endif + +if BUILD_PLUGIN_ASCENT +pkglib_LTLIBRARIES += ascent.la +ascent_la_SOURCES = src/ascent.c +ascent_la_CFLAGS = \ + $(AM_CFLAGS) \ + $(BUILD_WITH_LIBCURL_CFLAGS) \ + $(BUILD_WITH_LIBXML2_CFLAGS) +ascent_la_LDFLAGS = $(PLUGIN_LDFLAGS) +ascent_la_LIBADD = \ + $(BUILD_WITH_LIBCURL_LIBS) \ + $(BUILD_WITH_LIBXML2_LIBS) +endif + +if BUILD_PLUGIN_BAROMETER +pkglib_LTLIBRARIES += barometer.la +barometer_la_SOURCES = src/barometer.c +barometer_la_LDFLAGS = $(PLUGIN_LDFLAGS) +barometer_la_LIBADD = -lm $(BUILD_WITH_LIBI2C_LIBS) +endif + +if BUILD_PLUGIN_BATTERY +pkglib_LTLIBRARIES += battery.la +battery_la_SOURCES = \ + src/battery.c \ + src/battery_statefs.c +battery_la_LDFLAGS = $(PLUGIN_LDFLAGS) +if BUILD_WITH_LIBIOKIT +battery_la_LDFLAGS += -framework IOKit +endif +endif + +if BUILD_PLUGIN_BIND +pkglib_LTLIBRARIES += bind.la +bind_la_SOURCES = src/bind.c +bind_la_CFLAGS = $(AM_CFLAGS) \ + $(BUILD_WITH_LIBCURL_CFLAGS) $(BUILD_WITH_LIBXML2_CFLAGS) +bind_la_LDFLAGS = $(PLUGIN_LDFLAGS) +bind_la_LIBADD = $(BUILD_WITH_LIBCURL_LIBS) $(BUILD_WITH_LIBXML2_LIBS) +endif + +if BUILD_PLUGIN_BUDDYINFO +pkglib_LTLIBRARIES += buddyinfo.la +buddyinfo_la_SOURCES = src/buddyinfo.c +buddyinfo_la_LDFLAGS = $(PLUGIN_LDFLAGS) +buddyinfo_la_LIBADD = libignorelist.la +endif + +if BUILD_PLUGIN_CAPABILITIES +pkglib_LTLIBRARIES += capabilities.la +capabilities_la_SOURCES = src/capabilities.c \ + src/utils/dmi/dmi.c \ + src/utils/dmi/dmi.h +capabilities_la_CPPFLAGS = $(AM_CPPFLAGS) \ + $(BUILD_WITH_LIBMICROHTTPD_CPPFLAGS) $(BUILD_WITH_LIBJANSSON_CPPFLAGS) +capabilities_la_LDFLAGS = $(PLUGIN_LDFLAGS) \ + $(BUILD_WITH_LIBMICROHTTPD_LDFLAGS) $(BUILD_WITH_LIBJANSSON_LDFLAGS) +capabilities_la_LIBADD = $(BUILD_WITH_LIBMICROHTTPD_LIBS) \ + $(BUILD_WITH_LIBJANSSON_LIBS) + +test_plugin_capabilities_SOURCES = \ + src/capabilities_test.c \ + src/daemon/configfile.c \ + src/daemon/types_list.c +test_plugin_capabilities_CPPFLAGS = $(AM_CPPFLAGS) \ + $(BUILD_WITH_LIBJANSSON_CPPFLAGS) +test_plugin_capabilities_LDFLAGS = $(PLUGIN_LDFLAGS) \ + $(BUILD_WITH_LIBJANSSON_LDFLAGS) +test_plugin_capabilities_LDADD = liboconfig.la libplugin_mock.la \ + $(BUILD_WITH_LIBJANSSON_LIBS) +check_PROGRAMS += test_plugin_capabilities +TESTS += test_plugin_capabilities +endif + +if BUILD_PLUGIN_CEPH +pkglib_LTLIBRARIES += ceph.la +ceph_la_SOURCES = src/ceph.c +ceph_la_CPPFLAGS = $(AM_CPPFLAGS) $(BUILD_WITH_LIBYAJL_CPPFLAGS) +ceph_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_LIBYAJL_LDFLAGS) +ceph_la_LIBADD = $(BUILD_WITH_LIBYAJL_LIBS) +endif + +if BUILD_PLUGIN_CGROUPS +pkglib_LTLIBRARIES += cgroups.la +cgroups_la_SOURCES = src/cgroups.c +cgroups_la_LDFLAGS = $(PLUGIN_LDFLAGS) +cgroups_la_LIBADD = libignorelist.la libmount.la +endif + +if BUILD_PLUGIN_CHRONY +pkglib_LTLIBRARIES += chrony.la +chrony_la_SOURCES = src/chrony.c +chrony_la_LDFLAGS = $(PLUGIN_LDFLAGS) +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 +conntrack_la_LDFLAGS = $(PLUGIN_LDFLAGS) +endif + +if BUILD_PLUGIN_CONTEXTSWITCH +pkglib_LTLIBRARIES += contextswitch.la +contextswitch_la_SOURCES = src/contextswitch.c +contextswitch_la_LDFLAGS = $(PLUGIN_LDFLAGS) +contextswitch_la_LIBADD = +if BUILD_WITH_PERFSTAT +contextswitch_la_LIBADD += -lperfstat +endif +endif + +if BUILD_PLUGIN_CPU +pkglib_LTLIBRARIES += cpu.la +cpu_la_SOURCES = src/cpu.c +cpu_la_CFLAGS = $(AM_CFLAGS) +cpu_la_LDFLAGS = $(PLUGIN_LDFLAGS) +cpu_la_LIBADD = +if BUILD_WITH_LIBKSTAT +cpu_la_LIBADD += -lkstat +endif +if BUILD_WITH_LIBDEVINFO +cpu_la_LIBADD += -ldevinfo +endif +if BUILD_WITH_LIBSTATGRAB +cpu_la_CFLAGS += $(BUILD_WITH_LIBSTATGRAB_CFLAGS) +cpu_la_LIBADD += $(BUILD_WITH_LIBSTATGRAB_LDFLAGS) +endif +if BUILD_WITH_PERFSTAT +cpu_la_LIBADD += -lperfstat +endif +endif + +if BUILD_PLUGIN_CPUFREQ +pkglib_LTLIBRARIES += cpufreq.la +cpufreq_la_SOURCES = src/cpufreq.c +cpufreq_la_LDFLAGS = $(PLUGIN_LDFLAGS) +endif + +if BUILD_PLUGIN_CPUSLEEP +pkglib_LTLIBRARIES += cpusleep.la +cpusleep_la_SOURCES = src/cpusleep.c +cpusleep_la_LDFLAGS = $(PLUGIN_LDFLAGS) +endif + +if BUILD_PLUGIN_CSV +pkglib_LTLIBRARIES += csv.la +csv_la_SOURCES = src/csv.c +csv_la_LDFLAGS = $(PLUGIN_LDFLAGS) +endif + +if BUILD_PLUGIN_CURL +pkglib_LTLIBRARIES += curl.la +curl_la_SOURCES = \ + src/curl.c \ + src/utils/curl_stats/curl_stats.c \ + src/utils/curl_stats/curl_stats.h \ + src/utils/match/match.c \ + src/utils/match/match.h +curl_la_CFLAGS = $(AM_CFLAGS) $(BUILD_WITH_LIBCURL_CFLAGS) +curl_la_LDFLAGS = $(PLUGIN_LDFLAGS) +curl_la_LIBADD = liblatency.la $(BUILD_WITH_LIBCURL_LIBS) +endif + +if BUILD_PLUGIN_CURL_JSON +pkglib_LTLIBRARIES += curl_json.la +curl_json_la_SOURCES = \ + src/curl_json.c \ + src/utils/curl_stats/curl_stats.c \ + src/utils/curl_stats/curl_stats.h +curl_json_la_CFLAGS = $(AM_CFLAGS) $(BUILD_WITH_LIBCURL_CFLAGS) +curl_json_la_CPPFLAGS = $(AM_CPPFLAGS) $(BUILD_WITH_LIBYAJL_CPPFLAGS) +curl_json_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_LIBYAJL_LDFLAGS) +curl_json_la_LIBADD = $(BUILD_WITH_LIBCURL_LIBS) $(BUILD_WITH_LIBYAJL_LIBS) + +test_plugin_curl_json_SOURCES = src/curl_json_test.c \ + src/utils/curl_stats/curl_stats.c \ + src/daemon/configfile.c \ + src/daemon/types_list.c +test_plugin_curl_json_CPPFLAGS = $(AM_CPPFLAGS) $(BUILD_WITH_LIBYAJL_CPPFLAGS) +test_plugin_curl_json_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_LIBYAJL_LDFLAGS) +test_plugin_curl_json_LDADD = libavltree.la liboconfig.la libplugin_mock.la $(BUILD_WITH_LIBCURL_LIBS) $(BUILD_WITH_LIBYAJL_LIBS) +check_PROGRAMS += test_plugin_curl_json +endif + +if BUILD_PLUGIN_CURL_XML +pkglib_LTLIBRARIES += curl_xml.la +curl_xml_la_SOURCES = \ + src/curl_xml.c \ + src/utils/curl_stats/curl_stats.c \ + src/utils/curl_stats/curl_stats.h +curl_xml_la_CFLAGS = $(AM_CFLAGS) \ + $(BUILD_WITH_LIBCURL_CFLAGS) $(BUILD_WITH_LIBXML2_CFLAGS) +curl_xml_la_LDFLAGS = $(PLUGIN_LDFLAGS) +curl_xml_la_LIBADD = $(BUILD_WITH_LIBCURL_LIBS) $(BUILD_WITH_LIBXML2_LIBS) +endif + +if BUILD_PLUGIN_DBI +pkglib_LTLIBRARIES += dbi.la +dbi_la_SOURCES = \ + src/dbi.c \ + src/utils/db_query/db_query.c \ + src/utils/db_query/db_query.h +dbi_la_CPPFLAGS = $(AM_CPPFLAGS) $(BUILD_WITH_LIBDBI_CPPFLAGS) +dbi_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_LIBDBI_LDFLAGS) +dbi_la_LIBADD = $(BUILD_WITH_LIBDBI_LIBS) +endif + +if BUILD_PLUGIN_DCPMM +pkglib_LTLIBRARIES += dcpmm.la +dcpmm_la_SOURCES = src/dcpmm.c +dcpmm_la_CFLAGS = $(AM_CFLAGS) $(BUILD_WITH_LIBPMWAPI_CPPFLAGS) +dcpmm_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_LIBPMWAPI_LDFLAGS) +dcpmm_la_LIBADD = -lpmwapi +endif + +if BUILD_PLUGIN_DF +pkglib_LTLIBRARIES += df.la +df_la_SOURCES = src/df.c +df_la_LDFLAGS = $(PLUGIN_LDFLAGS) +df_la_LIBADD = libignorelist.la libmount.la +endif + +if BUILD_PLUGIN_DISK +pkglib_LTLIBRARIES += disk.la +disk_la_SOURCES = src/disk.c +disk_la_CFLAGS = $(AM_CFLAGS) +disk_la_CPPFLAGS = $(AM_CPPFLAGS) +disk_la_LDFLAGS = $(PLUGIN_LDFLAGS) +disk_la_LIBADD = libignorelist.la +if BUILD_WITH_LIBKSTAT +disk_la_LIBADD += -lkstat +endif +if BUILD_WITH_LIBDEVINFO +disk_la_LIBADD += -ldevinfo +endif +if BUILD_WITH_LIBIOKIT +disk_la_LDFLAGS += -framework IOKit +endif +if BUILD_WITH_LIBSTATGRAB +disk_la_CFLAGS += $(BUILD_WITH_LIBSTATGRAB_CFLAGS) +disk_la_LIBADD += $(BUILD_WITH_LIBSTATGRAB_LDFLAGS) +endif +if BUILD_WITH_LIBUDEV +disk_la_CPPFLAGS += $(BUILD_WITH_LIBUDEV_CPPFLAGS) +disk_la_LDFLAGS += $(BUILD_WITH_LIBUDEV_LDFLAGS) +disk_la_LIBADD += $(BUILD_WITH_LIBUDEV_LIBS) +endif +if BUILD_FREEBSD +disk_la_LIBADD += -ldevstat -lgeom +endif +if BUILD_WITH_PERFSTAT +disk_la_LIBADD += -lperfstat +endif +endif + +if BUILD_PLUGIN_DNS +pkglib_LTLIBRARIES += dns.la +dns_la_SOURCES = \ + src/dns.c \ + src/utils/dns/dns.c \ + src/utils/dns/dns.h +dns_la_CPPFLAGS = $(AM_CPPFLAGS) $(BUILD_WITH_LIBPCAP_CPPFLAGS) +dns_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_LIBPCAP_LDFLAGS) +dns_la_LIBADD = $(BUILD_WITH_LIBPCAP_LIBS) +endif + +if BUILD_PLUGIN_DPDKEVENTS +pkglib_LTLIBRARIES += dpdkevents.la +dpdkevents_la_SOURCES = src/dpdkevents.c src/utils/dpdk/dpdk.c src/utils/dpdk/dpdk.h +dpdkevents_la_CPPFLAGS = $(AM_CPPFLAGS) $(LIBDPDK_CPPFLAGS) +dpdkevents_la_CFLAGS = $(AM_CFLAGS) $(LIBDPDK_CFLAGS) +dpdkevents_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(LIBDPDK_LDFLAGS) +dpdkevents_la_LIBADD = $(LIBDPDK_LIBS) +endif + +if BUILD_PLUGIN_DPDKSTAT +pkglib_LTLIBRARIES += dpdkstat.la +dpdkstat_la_SOURCES = src/dpdkstat.c src/utils/dpdk/dpdk.c src/utils/dpdk/dpdk.h +dpdkstat_la_CPPFLAGS = $(AM_CPPFLAGS) $(LIBDPDK_CPPFLAGS) +dpdkstat_la_CFLAGS = $(AM_CFLAGS) $(LIBDPDK_CFLAGS) +dpdkstat_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(LIBDPDK_LDFLAGS) +dpdkstat_la_LIBADD = $(LIBDPDK_LIBS) +endif +if BUILD_PLUGIN_DPDK_TELEMETRY +pkglib_LTLIBRARIES += dpdk_telemetry.la +dpdk_telemetry_la_SOURCES = src/dpdk_telemetry.c +dpdk_telemetry_la_CFLAGS = $(AM_CFLAGS) +dpdk_telemetry_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_LIBJANSSON_LDFLAGS) +dpdk_telemetry_la_LIBADD = $(BUILD_WITH_LIBJANSSON_LIBS) +endif + +if BUILD_PLUGIN_DRBD +pkglib_LTLIBRARIES += drbd.la +drbd_la_SOURCES = src/drbd.c +drbd_la_LDFLAGS = $(PLUGIN_LDFLAGS) +endif + +if BUILD_PLUGIN_EMAIL +pkglib_LTLIBRARIES += email.la +email_la_SOURCES = src/email.c +email_la_LDFLAGS = $(PLUGIN_LDFLAGS) +endif + +if BUILD_PLUGIN_ENTROPY +pkglib_LTLIBRARIES += entropy.la +entropy_la_SOURCES = src/entropy.c +entropy_la_LDFLAGS = $(PLUGIN_LDFLAGS) +endif + +if BUILD_PLUGIN_EXEC +pkglib_LTLIBRARIES += exec.la +exec_la_SOURCES = src/exec.c +exec_la_LDFLAGS = $(PLUGIN_LDFLAGS) +exec_la_LIBADD = libcmds.la +endif + +if BUILD_PLUGIN_ETHSTAT +pkglib_LTLIBRARIES += ethstat.la +ethstat_la_SOURCES = src/ethstat.c +ethstat_la_LDFLAGS = $(PLUGIN_LDFLAGS) +endif + +if BUILD_PLUGIN_FHCOUNT +pkglib_LTLIBRARIES += fhcount.la +fhcount_la_SOURCES = src/fhcount.c +fhcount_la_LDFLAGS = $(PLUGIN_LDFLAGS) +endif + +if BUILD_PLUGIN_FILECOUNT +pkglib_LTLIBRARIES += filecount.la +filecount_la_SOURCES = src/filecount.c +filecount_la_LDFLAGS = $(PLUGIN_LDFLAGS) +endif + +if BUILD_PLUGIN_FSCACHE +pkglib_LTLIBRARIES += fscache.la +fscache_la_SOURCES = src/fscache.c +fscache_la_LDFLAGS = $(PLUGIN_LDFLAGS) +endif + +if BUILD_PLUGIN_GMOND +pkglib_LTLIBRARIES += gmond.la +gmond_la_SOURCES = src/gmond.c +gmond_la_CPPFLAGS = $(AM_CPPFLAGS) $(GANGLIA_CPPFLAGS) +gmond_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(GANGLIA_LDFLAGS) +gmond_la_LIBADD = $(GANGLIA_LIBS) +endif + +if BUILD_PLUGIN_GPS +pkglib_LTLIBRARIES += gps.la +gps_la_SOURCES = src/gps.c +gps_la_CFLAGS = $(AM_CFLAGS) $(BUILD_WITH_LIBGPS_CFLAGS) +gps_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_LIBGPS_LDFLAGS) +gps_la_LIBADD = -lpthread $(BUILD_WITH_LIBGPS_LIBS) +endif + +if BUILD_PLUGIN_GPU_NVIDIA +pkglib_LTLIBRARIES += gpu_nvidia.la +gpu_nvidia_la_SOURCES = src/gpu_nvidia.c +gpu_nvidia_la_CPPFLAGS = $(AM_CPPFLAGS) $(PLUGIN_CPPFLAGS) $(BUILD_WITH_CUDA_CPPFLAGS) +gpu_nvidia_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_CUDA_LDFLAGS) +gpu_nvidia_la_LIBADD = $(BUILD_WITH_CUDA_LIBS) +endif + +if BUILD_PLUGIN_GRPC +pkglib_LTLIBRARIES += grpc.la +grpc_la_SOURCES = src/grpc.cc +nodist_grpc_la_SOURCES = \ + collectd.grpc.pb.cc \ + collectd.pb.cc \ + types.pb.cc +grpc_la_CPPFLAGS = $(AM_CPPFLAGS) $(BUILD_WITH_LIBGRPCPP_CPPFLAGS) $(BUILD_WITH_LIBPROTOBUF_CPPFLAGS) +grpc_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_LIBGRPCPP_LDFLAGS) $(BUILD_WITH_LIBPROTOBUF_LDFLAGS) +grpc_la_LIBADD = $(BUILD_WITH_LIBGRPCPP_LIBS) $(BUILD_WITH_LIBPROTOBUF_LIBS) +endif + +if BUILD_PLUGIN_HDDTEMP +pkglib_LTLIBRARIES += hddtemp.la +hddtemp_la_SOURCES = src/hddtemp.c +hddtemp_la_LDFLAGS = $(PLUGIN_LDFLAGS) +hddtemp_la_LIBADD = +if BUILD_WITH_LIBSOCKET +hddtemp_la_LIBADD += -lsocket +endif +endif + +if BUILD_PLUGIN_HUGEPAGES +pkglib_LTLIBRARIES += hugepages.la +hugepages_la_SOURCES = src/hugepages.c +hugepages_la_LDFLAGS = $(PLUGIN_LDFLAGS) +endif + +if BUILD_PLUGIN_INTEL_PMU +pkglib_LTLIBRARIES += intel_pmu.la +intel_pmu_la_SOURCES = \ + src/intel_pmu.c \ + src/utils/config_cores/config_cores.h \ + src/utils/config_cores/config_cores.c +intel_pmu_la_CPPFLAGS = $(AM_CPPFLAGS) $(BUILD_WITH_LIBJEVENTS_CPPFLAGS) +intel_pmu_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_LIBJEVENTS_LDFLAGS) +intel_pmu_la_LIBADD = $(BUILD_WITH_LIBJEVENTS_LIBS) +endif + +if BUILD_PLUGIN_INTEL_RDT +pkglib_LTLIBRARIES += intel_rdt.la +intel_rdt_la_SOURCES = \ + src/intel_rdt.c \ + src/utils/proc_pids/proc_pids.c \ + src/utils/proc_pids/proc_pids.h \ + src/utils/config_cores/config_cores.h \ + src/utils/config_cores/config_cores.c +intel_rdt_la_CFLAGS = $(AM_CFLAGS) $(BUILD_WITH_LIBPQOS_CPPFLAGS) +intel_rdt_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_LIBPQOS_LDFLAGS) +intel_rdt_la_LIBADD = $(BUILD_WITH_LIBPQOS_LIBS) + +test_plugin_intel_rdt_SOURCES = \ + src/intel_rdt_test.c \ + src/utils/config_cores/config_cores.c \ + src/utils/proc_pids/proc_pids.c \ + src/daemon/configfile.c \ + src/daemon/types_list.c +test_plugin_intel_rdt_CPPFLAGS = $(AM_CPPFLAGS) +test_plugin_intel_rdt_LDFLAGS = $(PLUGIN_LDFLAGS) +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 +pkglib_LTLIBRARIES += interface.la +interface_la_SOURCES = src/interface.c +interface_la_CFLAGS = $(AM_CFLAGS) +interface_la_LDFLAGS = $(PLUGIN_LDFLAGS) +interface_la_LIBADD = libignorelist.la +if BUILD_WITH_LIBSTATGRAB +interface_la_CFLAGS += $(BUILD_WITH_LIBSTATGRAB_CFLAGS) +interface_la_LIBADD += $(BUILD_WITH_LIBSTATGRAB_LDFLAGS) +else +if BUILD_WITH_LIBKSTAT +interface_la_LIBADD += -lkstat +endif +if BUILD_WITH_LIBDEVINFO +interface_la_LIBADD += -ldevinfo +endif # BUILD_WITH_LIBDEVINFO +endif # !BUILD_WITH_LIBSTATGRAB +if BUILD_WITH_PERFSTAT +interface_la_LIBADD += -lperfstat +endif +endif # BUILD_PLUGIN_INTERFACE + +if BUILD_PLUGIN_IPC +pkglib_LTLIBRARIES += ipc.la +ipc_la_SOURCES = src/ipc.c +ipc_la_LDFLAGS = $(PLUGIN_LDFLAGS) +endif + +if BUILD_PLUGIN_IPTABLES +pkglib_LTLIBRARIES += iptables.la +iptables_la_SOURCES = src/iptables.c +iptables_la_CPPFLAGS = $(AM_CPPFLAGS) $(BUILD_WITH_LIBIPTC_CPPFLAGS) +iptables_la_LDFLAGS = $(PLUGIN_LDFLAGS) +iptables_la_LIBADD = $(BUILD_WITH_LIBIPTC_LDFLAGS) +endif + +if BUILD_PLUGIN_IPMI +pkglib_LTLIBRARIES += ipmi.la +ipmi_la_SOURCES = src/ipmi.c +ipmi_la_CFLAGS = $(AM_CFLAGS) $(BUILD_WITH_OPENIPMI_CFLAGS) +ipmi_la_LDFLAGS = $(PLUGIN_LDFLAGS) +ipmi_la_LIBADD = libignorelist.la $(BUILD_WITH_OPENIPMI_LIBS) +endif + +if BUILD_PLUGIN_IPSTATS +pkglib_LTLIBRARIES += ipstats.la +ipstats_la_SOURCES = src/ipstats.c +ipstats_la_LDFLAGS = $(PLUGIN_LDFLAGS) +endif + +if BUILD_PLUGIN_IPVS +pkglib_LTLIBRARIES += ipvs.la +ipvs_la_SOURCES = src/ipvs.c +ipvs_la_LDFLAGS = $(PLUGIN_LDFLAGS) +endif + +if BUILD_PLUGIN_IRQ +pkglib_LTLIBRARIES += irq.la +irq_la_SOURCES = src/irq.c +irq_la_LDFLAGS = $(PLUGIN_LDFLAGS) +irq_la_LIBADD = libignorelist.la +endif + +if BUILD_PLUGIN_JAVA +pkglib_LTLIBRARIES += java.la +java_la_SOURCES = src/java.c +java_la_CPPFLAGS = $(AM_CPPFLAGS) $(JAVA_CPPFLAGS) +java_la_CFLAGS = $(AM_CFLAGS) $(JAVA_CFLAGS) +java_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(JAVA_LDFLAGS) +java_la_LIBADD = $(JAVA_LIBS) +endif + +if BUILD_PLUGIN_LOAD +pkglib_LTLIBRARIES += load.la +load_la_SOURCES = src/load.c +load_la_CFLAGS = $(AM_CFLAGS) +load_la_LDFLAGS = $(PLUGIN_LDFLAGS) +load_la_LIBADD = +if BUILD_WITH_LIBSTATGRAB +load_la_CFLAGS += $(BUILD_WITH_LIBSTATGRAB_CFLAGS) +load_la_LIBADD += $(BUILD_WITH_LIBSTATGRAB_LDFLAGS) +endif # BUILD_WITH_LIBSTATGRAB +if BUILD_WITH_PERFSTAT +load_la_LIBADD += -lperfstat +endif +endif # BUILD_PLUGIN_LOAD + +if BUILD_PLUGIN_LOGFILE +pkglib_LTLIBRARIES += logfile.la +logfile_la_SOURCES = src/logfile.c +logfile_la_LDFLAGS = $(PLUGIN_LDFLAGS) +logfile_la_DEPENDENCIES = $(COMMON_DEPS) +endif + +if BUILD_PLUGIN_LOGPARSER +pkglib_LTLIBRARIES += logparser.la +logparser_la_SOURCES = src/logparser.c \ + src/utils/message_parser/message_parser.c src/utils/message_parser/message_parser.h \ + src/utils_tail_match.c src/utils_tail_match.h \ + src/utils/tail/tail.c src/utils/tail/tail.h \ + src/utils/match/match.c src/utils/match/match.h \ + src/utils/latency/latency.c src/utils/latency/latency.h \ + src/utils/latency/latency_config.c src/utils/latency/latency_config.h +logparser_la_CPPFLAGS = $(AM_CPPFLAGS) +logparser_la_LDFLAGS = $(PLUGIN_LDFLAGS) -lm + +test_plugin_logparser_SOURCES = src/logparser_test.c \ + src/utils/message_parser/message_parser.c \ + src/utils_tail_match.c src/utils_tail_match.h \ + src/utils/tail/tail.c src/utils/tail/tail.h \ + src/utils/match/match.c src/utils/match/match.h \ + src/daemon/configfile.c \ + src/daemon/types_list.c +test_plugin_logparser_CPPFLAGS = $(AM_CPPFLAGS) +test_plugin_logparser_LDFLAGS = $(PLUGIN_LDFLAGS) +test_plugin_logparser_LDADD = liboconfig.la libplugin_mock.la liblatency.la +check_PROGRAMS += test_plugin_logparser +TESTS += test_plugin_logparser +endif + +if BUILD_PLUGIN_LOG_LOGSTASH +pkglib_LTLIBRARIES += log_logstash.la +log_logstash_la_SOURCES = src/log_logstash.c +log_logstash_la_CPPFLAGS = $(AM_CPPFLAGS) $(BUILD_WITH_LIBYAJL_CPPFLAGS) +log_logstash_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_LIBYAJL_LDFLAGS) +log_logstash_la_LIBADD = $(BUILD_WITH_LIBYAJL_LIBS) +endif + +if BUILD_PLUGIN_LPAR +pkglib_LTLIBRARIES += lpar.la +lpar_la_SOURCES = src/lpar.c +lpar_la_LDFLAGS = $(PLUGIN_LDFLAGS) +lpar_la_LIBADD = -lperfstat +endif + +if BUILD_PLUGIN_LUA +pkglib_LTLIBRARIES += lua.la +lua_la_SOURCES = \ + src/lua.c \ + src/utils_lua.c \ + src/utils_lua.h +lua_la_CFLAGS = $(AM_CFLAGS) $(BUILD_WITH_LIBLUA_CFLAGS) +lua_la_LDFLAGS = $(PLUGIN_LDFLAGS) +lua_la_LIBADD = $(BUILD_WITH_LIBLUA_LIBS) +endif + +if BUILD_PLUGIN_MADWIFI +pkglib_LTLIBRARIES += madwifi.la +madwifi_la_SOURCES = \ + src/madwifi.c \ + src/madwifi.h +madwifi_la_LDFLAGS = $(PLUGIN_LDFLAGS) +madwifi_la_LIBADD = libignorelist.la +endif + +if BUILD_PLUGIN_MATCH_EMPTY_COUNTER +pkglib_LTLIBRARIES += match_empty_counter.la +match_empty_counter_la_SOURCES = src/match_empty_counter.c +match_empty_counter_la_LDFLAGS = $(PLUGIN_LDFLAGS) +endif + +if BUILD_PLUGIN_MATCH_HASHED +pkglib_LTLIBRARIES += match_hashed.la +match_hashed_la_SOURCES = src/match_hashed.c +match_hashed_la_LDFLAGS = $(PLUGIN_LDFLAGS) +endif + +if BUILD_PLUGIN_MATCH_REGEX +pkglib_LTLIBRARIES += match_regex.la +match_regex_la_SOURCES = src/match_regex.c +match_regex_la_LDFLAGS = $(PLUGIN_LDFLAGS) +endif + +if BUILD_PLUGIN_MATCH_TIMEDIFF +pkglib_LTLIBRARIES += match_timediff.la +match_timediff_la_SOURCES = src/match_timediff.c +match_timediff_la_LDFLAGS = $(PLUGIN_LDFLAGS) +endif + +if BUILD_PLUGIN_MATCH_VALUE +pkglib_LTLIBRARIES += match_value.la +match_value_la_SOURCES = src/match_value.c +match_value_la_LDFLAGS = $(PLUGIN_LDFLAGS) +endif + +if BUILD_PLUGIN_MBMON +pkglib_LTLIBRARIES += mbmon.la +mbmon_la_SOURCES = src/mbmon.c +mbmon_la_LDFLAGS = $(PLUGIN_LDFLAGS) +mbmon_la_LIBADD = +if BUILD_WITH_LIBSOCKET +mbmon_la_LIBADD += -lsocket +endif +endif + +if BUILD_PLUGIN_MCELOG +pkglib_LTLIBRARIES += mcelog.la +mcelog_la_SOURCES = src/mcelog.c +mcelog_la_LDFLAGS = $(PLUGIN_LDFLAGS) +endif + +if BUILD_PLUGIN_MD +pkglib_LTLIBRARIES += md.la +md_la_SOURCES = src/md.c +md_la_LDFLAGS = $(PLUGIN_LDFLAGS) +md_la_LIBADD = libignorelist.la +endif + +if BUILD_PLUGIN_MDEVENTS +pkglib_LTLIBRARIES += mdevents.la +mdevents_la_SOURCES = src/mdevents.c +mdevents_la_CFLAGS = $(AM_FLAGS) +mdevents_la_LDFLAGS = $(PLUGIN_LDFLAGS) +mdevents_la_LIBADD = libignorelist.la + +test_plugin_mdevents_SOURCES = src/mdevents_test.c +test_plugin_mdevents_CFLAGS = $(AM_FLAGS) +test_plugin_mdevents_LDFLAGS = $(PLUGIN_LDFLAGS) +test_plugin_mdevents_LDADD = libplugin_mock.la +check_PROGRAMS += test_plugin_mdevents +TESTS += test_plugin_mdevents +endif + +if BUILD_PLUGIN_MEMCACHEC +pkglib_LTLIBRARIES += memcachec.la +memcachec_la_SOURCES = \ + src/memcachec.c \ + src/utils/match/match.c \ + src/utils/match/match.h +memcachec_la_CPPFLAGS = $(AM_CPPFLAGS) $(BUILD_WITH_LIBMEMCACHED_CPPFLAGS) +memcachec_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_LIBMEMCACHED_LDFLAGS) +memcachec_la_LIBADD = liblatency.la $(BUILD_WITH_LIBMEMCACHED_LIBS) +endif + +if BUILD_PLUGIN_MEMCACHED +pkglib_LTLIBRARIES += memcached.la +memcached_la_SOURCES = src/memcached.c +memcached_la_LDFLAGS = $(PLUGIN_LDFLAGS) +memcached_la_LIBADD = +if BUILD_WITH_LIBSOCKET +memcached_la_LIBADD += -lsocket +endif +endif + +if BUILD_PLUGIN_MEMORY +pkglib_LTLIBRARIES += memory.la +memory_la_SOURCES = src/memory.c +memory_la_CFLAGS = $(AM_CFLAGS) +memory_la_LDFLAGS = $(PLUGIN_LDFLAGS) +memory_la_LIBADD = +if BUILD_WITH_LIBKSTAT +memory_la_LIBADD += -lkstat +endif +if BUILD_WITH_LIBDEVINFO +memory_la_LIBADD += -ldevinfo +endif +if BUILD_WITH_LIBSTATGRAB +memory_la_CFLAGS += $(BUILD_WITH_LIBSTATGRAB_CFLAGS) +memory_la_LIBADD += $(BUILD_WITH_LIBSTATGRAB_LDFLAGS) +endif +if BUILD_WITH_PERFSTAT +memory_la_LIBADD += -lperfstat +endif +endif + +if BUILD_PLUGIN_MIC +pkglib_LTLIBRARIES += mic.la +mic_la_SOURCES = src/mic.c +mic_la_CPPFLAGS = $(AM_CPPFLAGS) $(BUILD_WITH_MIC_CPPFLAGS) +mic_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_MIC_LDFLAGS) +mic_la_LIBADD = libignorelist.la $(BUILD_WITH_MIC_LIBS) +endif + +if BUILD_PLUGIN_MODBUS +pkglib_LTLIBRARIES += modbus.la +modbus_la_SOURCES = src/modbus.c +modbus_la_CFLAGS = $(AM_CFLAGS) $(BUILD_WITH_LIBMODBUS_CFLAGS) +modbus_la_LDFLAGS = $(PLUGIN_LDFLAGS) +modbus_la_LIBADD = $(BUILD_WITH_LIBMODBUS_LIBS) +endif + +if BUILD_PLUGIN_MQTT +pkglib_LTLIBRARIES += mqtt.la +mqtt_la_SOURCES = src/mqtt.c +mqtt_la_CPPFLAGS = $(AM_CPPFLAGS) $(BUILD_WITH_LIBMOSQUITTO_CPPFLAGS) +mqtt_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_LIBMOSQUITTO_LDFLAGS) +mqtt_la_LIBADD = $(BUILD_WITH_LIBMOSQUITTO_LIBS) +endif + +if BUILD_PLUGIN_MULTIMETER +pkglib_LTLIBRARIES += multimeter.la +multimeter_la_SOURCES = src/multimeter.c +multimeter_la_LDFLAGS = $(PLUGIN_LDFLAGS) +endif + +if BUILD_PLUGIN_MYSQL +pkglib_LTLIBRARIES += mysql.la +mysql_la_SOURCES = src/mysql.c +mysql_la_CFLAGS = $(AM_CFLAGS) $(BUILD_WITH_LIBMYSQL_CFLAGS) +mysql_la_LDFLAGS = $(PLUGIN_LDFLAGS) +mysql_la_LIBADD = $(BUILD_WITH_LIBMYSQL_LIBS) +endif + +if BUILD_PLUGIN_NETAPP +pkglib_LTLIBRARIES += netapp.la +netapp_la_SOURCES = src/netapp.c +netapp_la_CPPFLAGS = $(AM_CPPFLAGS) $(LIBNETAPP_CPPFLAGS) +netapp_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(LIBNETAPP_LDFLAGS) +netapp_la_LIBADD = libignorelist.la $(LIBNETAPP_LIBS) +endif + +if BUILD_PLUGIN_NETLINK +pkglib_LTLIBRARIES += netlink.la +netlink_la_SOURCES = src/netlink.c +netlink_la_CFLAGS = $(AM_CFLAGS) $(BUILD_WITH_LIBMNL_CFLAGS) +netlink_la_LDFLAGS = $(PLUGIN_LDFLAGS) +netlink_la_LIBADD = $(BUILD_WITH_LIBMNL_LIBS) +endif + +if BUILD_PLUGIN_NETWORK +pkglib_LTLIBRARIES += network.la +network_la_SOURCES = \ + src/network.c \ + src/network.h \ + src/utils_fbhash.c \ + src/utils_fbhash.h +network_la_CPPFLAGS = $(AM_CPPFLAGS) +network_la_LDFLAGS = $(PLUGIN_LDFLAGS) +network_la_LIBADD = +if BUILD_WITH_LIBSOCKET +network_la_LIBADD += -lsocket +endif +if BUILD_WITH_LIBGCRYPT +network_la_CPPFLAGS += $(GCRYPT_CPPFLAGS) +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 +pkglib_LTLIBRARIES += nfs.la +nfs_la_SOURCES = src/nfs.c +nfs_la_LDFLAGS = $(PLUGIN_LDFLAGS) +endif + +if BUILD_PLUGIN_NGINX +pkglib_LTLIBRARIES += nginx.la +nginx_la_SOURCES = src/nginx.c +nginx_la_CFLAGS = $(AM_CFLAGS) $(BUILD_WITH_LIBCURL_CFLAGS) +nginx_la_LDFLAGS = $(PLUGIN_LDFLAGS) +nginx_la_LIBADD = $(BUILD_WITH_LIBCURL_LIBS) +endif + +if BUILD_PLUGIN_NOTIFY_DESKTOP +pkglib_LTLIBRARIES += notify_desktop.la +notify_desktop_la_SOURCES = src/notify_desktop.c +notify_desktop_la_CFLAGS = $(AM_CFLAGS) $(LIBNOTIFY_CFLAGS) +notify_desktop_la_LDFLAGS = $(PLUGIN_LDFLAGS) +notify_desktop_la_LIBADD = $(LIBNOTIFY_LIBS) +endif + +if BUILD_PLUGIN_NOTIFY_EMAIL +pkglib_LTLIBRARIES += notify_email.la +notify_email_la_SOURCES = src/notify_email.c +notify_email_la_CPPFLAGS = $(AM_CPPFLAGS) $(BUILD_WITH_LIBESMTP_CPPFLAGS) +notify_email_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_LIBESMTP_LDFLAGS) +notify_email_la_LIBADD = $(BUILD_WITH_LIBESMTP_LIBS) +endif + +if BUILD_PLUGIN_NOTIFY_NAGIOS +pkglib_LTLIBRARIES += notify_nagios.la +notify_nagios_la_SOURCES = src/notify_nagios.c +notify_nagios_la_LDFLAGS = $(PLUGIN_LDFLAGS) +endif + +if BUILD_PLUGIN_NTPD +pkglib_LTLIBRARIES += ntpd.la +ntpd_la_SOURCES = src/ntpd.c +ntpd_la_LDFLAGS = $(PLUGIN_LDFLAGS) +ntpd_la_LIBADD = +if BUILD_WITH_LIBSOCKET +ntpd_la_LIBADD += -lsocket +endif +endif + +if BUILD_PLUGIN_NUMA +pkglib_LTLIBRARIES += numa.la +numa_la_SOURCES = src/numa.c +numa_la_LDFLAGS = $(PLUGIN_LDFLAGS) +endif + +if BUILD_PLUGIN_NUT +pkglib_LTLIBRARIES += nut.la +nut_la_SOURCES = src/nut.c +nut_la_CFLAGS = $(AM_CFLAGS) $(BUILD_WITH_LIBUPSCLIENT_CFLAGS) +nut_la_LDFLAGS = $(PLUGIN_LDFLAGS) +nut_la_LIBADD = $(BUILD_WITH_LIBUPSCLIENT_LIBS) +endif + +if BUILD_PLUGIN_OLSRD +pkglib_LTLIBRARIES += olsrd.la +olsrd_la_SOURCES = src/olsrd.c +olsrd_la_LDFLAGS = $(PLUGIN_LDFLAGS) +olsrd_la_LIBADD = +if BUILD_WITH_LIBSOCKET +olsrd_la_LIBADD += -lsocket +endif +endif + +if BUILD_PLUGIN_ONEWIRE +pkglib_LTLIBRARIES += onewire.la +onewire_la_SOURCES = src/onewire.c +onewire_la_CPPFLAGS = $(AM_CPPFLAGS) $(BUILD_WITH_LIBOWCAPI_CPPFLAGS) +onewire_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_LIBOWCAPI_LDFLAGS) +onewire_la_LIBADD = libignorelist.la $(BUILD_WITH_LIBOWCAPI_LIBS) +endif + +if BUILD_PLUGIN_OPENLDAP +pkglib_LTLIBRARIES += openldap.la +openldap_la_SOURCES = src/openldap.c +openldap_la_CPPFLAGS = $(AM_CPPFLAGS) $(BUILD_WITH_LIBLDAP_CPPFLAGS) +openldap_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_LIBLDAP_LDFLAGS) +openldap_la_LIBADD = -lldap +endif + +if BUILD_PLUGIN_OPENVPN +pkglib_LTLIBRARIES += openvpn.la +openvpn_la_SOURCES = src/openvpn.c +openvpn_la_LDFLAGS = $(PLUGIN_LDFLAGS) +endif + +if BUILD_PLUGIN_ORACLE +pkglib_LTLIBRARIES += oracle.la +oracle_la_SOURCES = \ + src/oracle.c \ + src/utils/db_query/db_query.c \ + src/utils/db_query/db_query.h +oracle_la_CPPFLAGS = $(AM_CPPFLAGS) $(BUILD_WITH_ORACLE_CPPFLAGS) +oracle_la_LIBADD = $(BUILD_WITH_ORACLE_LIBS) +oracle_la_LDFLAGS = $(PLUGIN_LDFLAGS) +endif + +if BUILD_PLUGIN_OVS_EVENTS +pkglib_LTLIBRARIES += ovs_events.la +ovs_events_la_SOURCES = \ + src/ovs_events.c \ + src/utils/ovs/ovs.c \ + src/utils/ovs/ovs.h +ovs_events_la_CPPFLAGS = $(AM_CPPFLAGS) $(BUILD_WITH_LIBYAJL_CPPFLAGS) +ovs_events_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_LIBYAJL_LDFLAGS) +ovs_events_la_LIBADD = $(BUILD_WITH_LIBYAJL_LIBS) +endif + +if BUILD_PLUGIN_OVS_STATS +pkglib_LTLIBRARIES += ovs_stats.la +ovs_stats_la_SOURCES = \ + src/ovs_stats.c \ + src/utils/ovs/ovs.c \ + src/utils/ovs/ovs.h +ovs_stats_la_CPPFLAGS = $(AM_CPPFLAGS) $(BUILD_WITH_LIBYAJL_CPPFLAGS) +ovs_stats_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_LIBYAJL_LDFLAGS) +ovs_stats_la_LIBADD = $(BUILD_WITH_LIBYAJL_LIBS) +endif + +if BUILD_PLUGIN_PCIE_ERRORS +pkglib_LTLIBRARIES += pcie_errors.la +pcie_errors_la_SOURCES = src/pcie_errors.c +pcie_errors_la_CPPFLAGS = $(AM_CPPFLAGS) +pcie_errors_la_LDFLAGS = $(PLUGIN_LDFLAGS) + +test_plugin_pcie_errors_SOURCES = \ + src/pcie_errors_test.c \ + src/daemon/utils_llist.c \ + src/daemon/configfile.c \ + src/daemon/types_list.c +test_plugin_pcie_errors_CPPFLAGS = $(AM_CPPFLAGS) +test_plugin_pcie_errors_LDFLAGS = $(PLUGIN_LDFLAGS) +test_plugin_pcie_errors_LDADD = liboconfig.la libplugin_mock.la +check_PROGRAMS += test_plugin_pcie_errors +TESTS += test_plugin_pcie_errors +endif + +if BUILD_PLUGIN_PERL +pkglib_LTLIBRARIES += perl.la +perl_la_SOURCES = src/perl.c +# Despite C99 providing the "bool" type thru stdbool.h, Perl defines its own +# version of that type if HAS_BOOL is not defined... *sigh* +perl_la_CPPFLAGS = $(AM_CPPFLAGS) -DHAS_BOOL=1 +# Despite off_t being 64 bit wide on 64 bit platforms, Perl insist on using +# off64_t which is only exposed when _LARGEFILE64_SOURCE is defined... *sigh* +# On older platforms we also need _REENTRANT. _GNU_SOURCE sets both of these. +perl_la_CPPFLAGS += -D_GNU_SOURCE +perl_la_CFLAGS = $(AM_CFLAGS) \ + $(PERL_CFLAGS) \ + -DXS_VERSION=\"$(VERSION)\" -DVERSION=\"$(VERSION)\" +perl_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(PERL_LDFLAGS) +perl_la_LIBADD = $(PERL_LIBS) +endif + +if BUILD_PLUGIN_PF +pkglib_LTLIBRARIES += pf.la +pf_la_SOURCES = src/pf.c +pf_la_LDFLAGS = $(PLUGIN_LDFLAGS) +endif + +if BUILD_PLUGIN_PINBA +pkglib_LTLIBRARIES += pinba.la +pinba_la_SOURCES = src/pinba.c +nodist_pinba_la_SOURCES = \ + src/pinba.pb-c.c \ + src/pinba.pb-c.h +pinba_la_CPPFLAGS = $(AM_CPPFLAGS) $(BUILD_WITH_LIBPROTOBUF_C_CPPFLAGS) +pinba_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_LIBPROTOBUF_C_LDFLAGS) +pinba_la_LIBADD = $(BUILD_WITH_LIBPROTOBUF_C_LIBS) +endif + +if BUILD_PLUGIN_PING +pkglib_LTLIBRARIES += ping.la +ping_la_SOURCES = src/ping.c +ping_la_CPPFLAGS = $(AM_CPPFLAGS) $(BUILD_WITH_LIBOPING_CPPFLAGS) +ping_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_LIBOPING_LDFLAGS) +ping_la_LIBADD = -loping -lm +endif + +if BUILD_PLUGIN_POSTGRESQL +pkglib_LTLIBRARIES += postgresql.la +postgresql_la_SOURCES = \ + src/postgresql.c \ + src/utils/db_query/db_query.c \ + src/utils/db_query/db_query.h +postgresql_la_CPPFLAGS = $(AM_CPPFLAGS) $(BUILD_WITH_LIBPQ_CPPFLAGS) +postgresql_la_LDFLAGS = $(PLUGIN_LDFLAGS) \ + $(BUILD_WITH_LIBPQ_LDFLAGS) +postgresql_la_LIBADD = $(BUILD_WITH_LIBPQ_LIBS) +endif + +if BUILD_PLUGIN_POWERDNS +pkglib_LTLIBRARIES += powerdns.la +powerdns_la_SOURCES = src/powerdns.c +powerdns_la_LDFLAGS = $(PLUGIN_LDFLAGS) +endif + +if BUILD_PLUGIN_PYTHON +pkglib_LTLIBRARIES += python.la +python_la_SOURCES = \ + src/python.c \ + src/pyconfig.c \ + src/pyvalues.c \ + src/cpython.h +python_la_CPPFLAGS = $(AM_CPPFLAGS) $(LIBPYTHON_CPPFLAGS) +python_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(LIBPYTHON_LDFLAGS) +endif + +if HAVE_LIBMNL +noinst_LTLIBRARIES += libtaskstats.la +libtaskstats_la_SOURCES = \ + src/utils/taskstats/taskstats.c \ + src/utils/taskstats/taskstats.h +libtaskstats_la_CFLAGS = $(AM_CFLAGS) $(BUILD_WITH_LIBMNL_CFLAGS) +libtaskstats_la_LIBADD = $(BUILD_WITH_LIBMNL_LIBS) +endif + +if BUILD_PLUGIN_PROCESSES +pkglib_LTLIBRARIES += processes.la +processes_la_SOURCES = src/processes.c +processes_la_CPPFLAGS = $(AM_CPPFLAGS) +processes_la_LDFLAGS = $(PLUGIN_LDFLAGS) +processes_la_LIBADD = +if BUILD_WITH_LIBKVM_GETPROCS +processes_la_LIBADD += -lkvm +endif +if HAVE_LIBMNL +processes_la_CPPFLAGS += -DHAVE_LIBTASKSTATS=1 +processes_la_LIBADD += libtaskstats.la +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 +protocols_la_LDFLAGS = $(PLUGIN_LDFLAGS) +protocols_la_LIBADD = libignorelist.la +endif + +if BUILD_PLUGIN_REDFISH +pkglib_LTLIBRARIES += redfish.la +redfish_la_SOURCES = src/redfish.c +redfish_la_CPPFLAGS = $(AM_CPPFLAGS) $(BUILD_WITH_LIBREDFISH_CPPFLAGS) +redfish_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_LIBREDFISH_LDFLAGS) +redfish_la_LIBADD = $(BUILD_WITH_LIBREDFISH_LIBS) -lredfish + +test_plugin_redfish_SOURCES = src/redfish_test.c \ + src/utils/avltree/avltree.c \ + src/daemon/utils_llist.c \ + src/daemon/configfile.c \ + src/daemon/types_list.c +test_plugin_redfish_CPPFLAGS = $(AM_CPPFLAGS) $(BUILD_WITH_LIBREDFISH_CPPFLAGS) +test_plugin_redfish_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_LIBREDFISH_LDFLAGS) +test_plugin_redfish_LDADD = liboconfig.la libplugin_mock.la \ + $(BUILD_WITH_LIBREDFISH_LIBS) -lredfish -ljansson +check_PROGRAMS += test_plugin_redfish +TESTS += test_plugin_redfish +endif + +if BUILD_PLUGIN_REDIS +pkglib_LTLIBRARIES += redis.la +redis_la_SOURCES = src/redis.c +redis_la_CFLAGS = $(AM_CFLAGS) $(BUILD_WITH_LIBHIREDIS_CPPFLAGS) +redis_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_LIBHIREDIS_LDFLAGS) +redis_la_LIBADD = -lhiredis +endif + +if BUILD_PLUGIN_ROUTEROS +pkglib_LTLIBRARIES += routeros.la +routeros_la_SOURCES = src/routeros.c +routeros_la_CPPFLAGS = $(AM_CPPFLAGS) $(BUILD_WITH_LIBROUTEROS_CPPFLAGS) +routeros_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_LIBROUTEROS_LDFLAGS) +routeros_la_LIBADD = -lrouteros +endif + +if BUILD_PLUGIN_RRDCACHED +pkglib_LTLIBRARIES += rrdcached.la +rrdcached_la_SOURCES = \ + src/rrdcached.c \ + src/utils/rrdcreate/rrdcreate.c \ + src/utils/rrdcreate/rrdcreate.h +rrdcached_la_CFLAGS = $(AM_CFLAGS) $(BUILD_WITH_LIBRRD_CFLAGS) +rrdcached_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_LIBRRD_LDFLAGS) +rrdcached_la_LIBADD = $(BUILD_WITH_LIBRRD_LIBS) +endif + +if BUILD_PLUGIN_RRDTOOL +pkglib_LTLIBRARIES += rrdtool.la +rrdtool_la_SOURCES = \ + src/rrdtool.c \ + src/utils/rrdcreate/rrdcreate.c \ + src/utils/rrdcreate/rrdcreate.h +rrdtool_la_CFLAGS = $(AM_CFLAGS) $(BUILD_WITH_LIBRRD_CFLAGS) +rrdtool_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_LIBRRD_LDFLAGS) +rrdtool_la_LIBADD = $(BUILD_WITH_LIBRRD_LIBS) +endif + +if BUILD_PLUGIN_SENSORS +pkglib_LTLIBRARIES += sensors.la +sensors_la_SOURCES = src/sensors.c +sensors_la_CPPFLAGS = $(AM_CPPFLAGS) $(BUILD_WITH_LIBSENSORS_CPPFLAGS) +sensors_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_LIBSENSORS_LDFLAGS) +sensors_la_LIBADD = libignorelist.la $(BUILD_WITH_LIBSENSORS_LIBS) +endif + +if BUILD_PLUGIN_SERIAL +pkglib_LTLIBRARIES += serial.la +serial_la_SOURCES = src/serial.c +serial_la_LDFLAGS = $(PLUGIN_LDFLAGS) +endif + +if BUILD_PLUGIN_SIGROK +pkglib_LTLIBRARIES += sigrok.la +sigrok_la_SOURCES = src/sigrok.c +sigrok_la_CFLAGS = $(AM_CFLAGS) $(LIBSIGROK_CFLAGS) +sigrok_la_LDFLAGS = $(PLUGIN_LDFLAGS) +sigrok_la_LIBADD = $(LIBSIGROK_LIBS) +endif + +if BUILD_PLUGIN_SLURM +pkglib_LTLIBRARIES += slurm.la +slurm_la_SOURCES = src/slurm.c +slurm_la_CFLAGS = $(AM_CFLAGS) $(BUILD_WITH_LIBSLURM_CFLAGS) +slurm_la_LDFLAGS = $(PLUGIN_LDFLAGS) +slurm_la_LIBADD = $(BUILD_WITH_LIBSLURM_LIBS) +endif + +if BUILD_PLUGIN_SMART +if BUILD_WITH_LIBUDEV +pkglib_LTLIBRARIES += smart.la +smart_la_SOURCES = src/smart.c +smart_la_CPPFLAGS = $(AM_CPPFLAGS) $(BUILD_WITH_LIBATASMART_CPPFLAGS) $(BUILD_WITH_LIBUDEV_CPPFLAGS) +smart_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_LIBATASMART_LDFLAGS) $(BUILD_WITH_LIBUDEV_LDFLAGS) +smart_la_LIBADD = libignorelist.la $(BUILD_WITH_LIBATASMART_LIBS) $(BUILD_WITH_LIBUDEV_LIBS) +endif +endif + +if BUILD_PLUGIN_SNMP +pkglib_LTLIBRARIES += snmp.la +snmp_la_SOURCES = src/snmp.c +snmp_la_CPPFLAGS = $(AM_CPPFLAGS) $(BUILD_WITH_LIBNETSNMP_CPPFLAGS) +snmp_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_LIBNETSNMP_LDFLAGS) +snmp_la_LIBADD = libignorelist.la $(BUILD_WITH_LIBNETSNMP_LIBS) +endif + +if BUILD_PLUGIN_SNMP_AGENT +pkglib_LTLIBRARIES += snmp_agent.la +snmp_agent_la_SOURCES = src/snmp_agent.c +snmp_agent_la_CPPFLAGS = $(AM_CPPFLAGS) $(BUILD_WITH_LIBNETSNMPAGENT_CPPFLAGS) +snmp_agent_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_LIBNETSNMPAGENT_LDFLAGS) +snmp_agent_la_LIBADD = $(BUILD_WITH_LIBNETSNMPAGENT_LIBS) + +test_plugin_snmp_agent_SOURCES = src/snmp_agent_test.c \ + src/utils/avltree/avltree.c \ + src/daemon/utils_llist.c \ + src/daemon/configfile.c \ + src/daemon/types_list.c +test_plugin_snmp_agent_CPPFLAGS = $(AM_CPPFLAGS) \ + $(BUILD_WITH_LIBNETSNMPAGENT_CPPFLAGS) +test_plugin_snmp_agent_LDFLAGS = $(PLUGIN_LDFLAGS) \ + $(BUILD_WITH_LIBNETSNMPAGENT_LDFLAGS) +test_plugin_snmp_agent_LDADD = liboconfig.la libplugin_mock.la \ + $(BUILD_WITH_LIBNETSNMPAGENT_LIBS) $(BUILD_WITH_LIBNETSNMP_LIBS) + +check_PROGRAMS += test_plugin_snmp_agent +TESTS += test_plugin_snmp_agent + + +endif + +if BUILD_PLUGIN_STATSD +pkglib_LTLIBRARIES += statsd.la +statsd_la_SOURCES = src/statsd.c +statsd_la_LDFLAGS = $(PLUGIN_LDFLAGS) +statsd_la_LIBADD = liblatency.la +endif + +if BUILD_PLUGIN_SWAP +pkglib_LTLIBRARIES += swap.la +swap_la_SOURCES = src/swap.c +swap_la_CFLAGS = $(AM_CFLAGS) +swap_la_LDFLAGS = $(PLUGIN_LDFLAGS) +swap_la_LIBADD = +if BUILD_WITH_LIBKSTAT +swap_la_LIBADD += -lkstat +endif +if BUILD_WITH_LIBDEVINFO +swap_la_LIBADD += -ldevinfo +endif +if BUILD_WITH_LIBKVM_GETSWAPINFO +swap_la_LIBADD += -lkvm +endif +if BUILD_WITH_LIBSTATGRAB +swap_la_CFLAGS += $(BUILD_WITH_LIBSTATGRAB_CFLAGS) +swap_la_LIBADD += $(BUILD_WITH_LIBSTATGRAB_LDFLAGS) +endif +if BUILD_WITH_PERFSTAT +swap_la_LIBADD += -lperfstat +endif + +endif + +if BUILD_PLUGIN_SYNPROXY +pkglib_LTLIBRARIES += synproxy.la +synproxy_la_SOURCES = src/synproxy.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 +syslog_la_LDFLAGS = $(PLUGIN_LDFLAGS) +endif + +if BUILD_PLUGIN_TABLE +pkglib_LTLIBRARIES += table.la +table_la_SOURCES = src/table.c +table_la_LDFLAGS = $(PLUGIN_LDFLAGS) +endif + +if BUILD_PLUGIN_TAIL +pkglib_LTLIBRARIES += tail.la +tail_la_SOURCES = \ + src/tail.c \ + src/utils/match/match.c \ + src/utils/match/match.h \ + src/utils/tail/tail.c \ + src/utils/tail/tail.h \ + src/utils_tail_match.c \ + src/utils_tail_match.h +tail_la_LDFLAGS = $(PLUGIN_LDFLAGS) +tail_la_LIBADD = liblatency.la +endif + +if BUILD_PLUGIN_TAIL_CSV +pkglib_LTLIBRARIES += tail_csv.la +tail_csv_la_SOURCES = \ + src/tail_csv.c \ + src/utils/tail/tail.c \ + src/utils/tail/tail.h +tail_csv_la_LDFLAGS = $(PLUGIN_LDFLAGS) +endif + +if BUILD_PLUGIN_TAPE +pkglib_LTLIBRARIES += tape.la +tape_la_SOURCES = src/tape.c +tape_la_LDFLAGS = $(PLUGIN_LDFLAGS) +tape_la_LIBADD = -lkstat -ldevinfo +endif + +if BUILD_PLUGIN_TARGET_NOTIFICATION +pkglib_LTLIBRARIES += target_notification.la +target_notification_la_SOURCES = src/target_notification.c +target_notification_la_LDFLAGS = $(PLUGIN_LDFLAGS) +endif + +if BUILD_PLUGIN_TARGET_REPLACE +pkglib_LTLIBRARIES += target_replace.la +target_replace_la_SOURCES = src/target_replace.c +target_replace_la_LDFLAGS = $(PLUGIN_LDFLAGS) +endif + +if BUILD_PLUGIN_TARGET_SCALE +pkglib_LTLIBRARIES += target_scale.la +target_scale_la_SOURCES = src/target_scale.c +target_scale_la_LDFLAGS = $(PLUGIN_LDFLAGS) +endif + +if BUILD_PLUGIN_TARGET_SET +pkglib_LTLIBRARIES += target_set.la +target_set_la_SOURCES = src/target_set.c +target_set_la_LDFLAGS = $(PLUGIN_LDFLAGS) +endif + +if BUILD_PLUGIN_TARGET_V5UPGRADE +pkglib_LTLIBRARIES += target_v5upgrade.la +target_v5upgrade_la_SOURCES = src/target_v5upgrade.c +target_v5upgrade_la_LDFLAGS = $(PLUGIN_LDFLAGS) +endif + +if BUILD_PLUGIN_TCPCONNS +pkglib_LTLIBRARIES += tcpconns.la +tcpconns_la_SOURCES = src/tcpconns.c +tcpconns_la_LDFLAGS = $(PLUGIN_LDFLAGS) +tcpconns_la_LIBADD = +if BUILD_WITH_LIBKVM_NLIST +tcpconns_la_LIBADD += -lkvm +endif +endif + +if BUILD_PLUGIN_TEAMSPEAK2 +pkglib_LTLIBRARIES += teamspeak2.la +teamspeak2_la_SOURCES = src/teamspeak2.c +teamspeak2_la_LDFLAGS = $(PLUGIN_LDFLAGS) +endif + +if BUILD_PLUGIN_TED +pkglib_LTLIBRARIES += ted.la +ted_la_SOURCES = src/ted.c +ted_la_LDFLAGS = $(PLUGIN_LDFLAGS) +endif + +if BUILD_PLUGIN_THERMAL +pkglib_LTLIBRARIES += thermal.la +thermal_la_SOURCES = src/thermal.c +thermal_la_LDFLAGS = $(PLUGIN_LDFLAGS) +thermal_la_LIBADD = libignorelist.la +endif + +if BUILD_PLUGIN_THRESHOLD +pkglib_LTLIBRARIES += threshold.la +threshold_la_SOURCES = src/threshold.c +threshold_la_LDFLAGS = $(PLUGIN_LDFLAGS) +endif + +if BUILD_PLUGIN_TOKYOTYRANT +pkglib_LTLIBRARIES += tokyotyrant.la +tokyotyrant_la_SOURCES = src/tokyotyrant.c +tokyotyrant_la_CPPFLAGS = $(AM_CPPFLAGS) $(BUILD_WITH_LIBTOKYOTYRANT_CPPFLAGS) +tokyotyrant_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_LIBTOKYOTYRANT_LDFLAGS) +tokyotyrant_la_LIBADD = $(BUILD_WITH_LIBTOKYOTYRANT_LIBS) +if BUILD_WITH_LIBSOCKET +tokyotyrant_la_LIBADD += -lsocket +endif +endif + +if BUILD_PLUGIN_TURBOSTAT +pkglib_LTLIBRARIES += turbostat.la +turbostat_la_SOURCES = \ + src/turbostat.c \ + src/msr-index.h +turbostat_la_LDFLAGS = $(PLUGIN_LDFLAGS) +endif + +if BUILD_PLUGIN_UBI +pkglib_LTLIBRARIES += ubi.la +ubi_la_SOURCES = src/ubi.c +ubi_la_LDFLAGS = $(PLUGIN_LDFLAGS) +ubi_la_LIBADD = libignorelist.la +endif + +if BUILD_PLUGIN_UNIXSOCK +pkglib_LTLIBRARIES += unixsock.la +unixsock_la_SOURCES = src/unixsock.c +unixsock_la_LDFLAGS = $(PLUGIN_LDFLAGS) +unixsock_la_LIBADD = libcmds.la +endif + +if BUILD_PLUGIN_UPTIME +pkglib_LTLIBRARIES += uptime.la +uptime_la_SOURCES = src/uptime.c +uptime_la_CFLAGS = $(AM_CFLAGS) +uptime_la_LDFLAGS = $(PLUGIN_LDFLAGS) +uptime_la_LIBADD = +if BUILD_WITH_LIBKSTAT +uptime_la_LIBADD += -lkstat +endif +if BUILD_WITH_PERFSTAT +uptime_la_LIBADD += -lperfstat +endif +endif + +if BUILD_PLUGIN_USERS +pkglib_LTLIBRARIES += users.la +users_la_SOURCES = src/users.c +users_la_CFLAGS = $(AM_CFLAGS) +users_la_LDFLAGS = $(PLUGIN_LDFLAGS) +users_la_LIBADD = +if BUILD_WITH_LIBSTATGRAB +users_la_CFLAGS += $(BUILD_WITH_LIBSTATGRAB_CFLAGS) +users_la_LIBADD += $(BUILD_WITH_LIBSTATGRAB_LDFLAGS) +endif +endif + +if BUILD_PLUGIN_UUID +pkglib_LTLIBRARIES += uuid.la +uuid_la_SOURCES = src/uuid.c +uuid_la_LDFLAGS = $(PLUGIN_LDFLAGS) +endif + +if BUILD_PLUGIN_VARNISH +pkglib_LTLIBRARIES += varnish.la +varnish_la_SOURCES = src/varnish.c +varnish_la_CFLAGS = $(AM_CFLAGS) $(BUILD_WITH_LIBVARNISH_CFLAGS) +varnish_la_LDFLAGS = $(PLUGIN_LDFLAGS) +varnish_la_LIBADD = $(BUILD_WITH_LIBVARNISH_LIBS) +endif + +if BUILD_PLUGIN_VIRT +pkglib_LTLIBRARIES += virt.la +virt_la_SOURCES = src/virt.c +virt_la_CFLAGS = $(AM_CFLAGS) \ + $(BUILD_WITH_LIBVIRT_CFLAGS) $(BUILD_WITH_LIBXML2_CFLAGS) +virt_la_LDFLAGS = $(PLUGIN_LDFLAGS) +virt_la_LIBADD = libignorelist.la $(BUILD_WITH_LIBVIRT_LIBS) $(BUILD_WITH_LIBXML2_LIBS) + +test_plugin_virt_SOURCES = src/virt_test.c src/daemon/configfile.c \ + src/daemon/types_list.c +test_plugin_virt_CPPFLAGS = $(AM_CPPFLAGS) \ + $(BUILD_WITH_LIBVIRT_CPPFLAGS) $(BUILD_WITH_LIBXML2_CFLAGS) +test_plugin_virt_LDFLAGS = $(PLUGIN_LDFLAGS) \ + $(BUILD_WITH_LIBVIRT_LDFLAGS) $(BUILD_WITH_LIBXML2_LDFLAGS) +test_plugin_virt_LDADD = liboconfig.la libplugin_mock.la \ + $(BUILD_WITH_LIBVIRT_LIBS) $(BUILD_WITH_LIBXML2_LIBS) +check_PROGRAMS += test_plugin_virt +TESTS += test_plugin_virt +endif + +if BUILD_PLUGIN_VMEM +pkglib_LTLIBRARIES += vmem.la +vmem_la_SOURCES = src/vmem.c +vmem_la_LDFLAGS = $(PLUGIN_LDFLAGS) +endif + +if BUILD_PLUGIN_VSERVER +pkglib_LTLIBRARIES += vserver.la +vserver_la_SOURCES = src/vserver.c +vserver_la_LDFLAGS = $(PLUGIN_LDFLAGS) +endif + +if BUILD_PLUGIN_WIRELESS +pkglib_LTLIBRARIES += wireless.la +wireless_la_SOURCES = src/wireless.c +wireless_la_LDFLAGS = $(PLUGIN_LDFLAGS) +endif + +if BUILD_PLUGIN_WRITE_GRAPHITE +pkglib_LTLIBRARIES += write_graphite.la +write_graphite_la_SOURCES = src/write_graphite.c +write_graphite_la_LDFLAGS = $(PLUGIN_LDFLAGS) +write_graphite_la_LIBADD = libformat_graphite.la +endif + +if BUILD_PLUGIN_WRITE_HTTP +pkglib_LTLIBRARIES += write_http.la +write_http_la_SOURCES = \ + src/write_http.c \ + src/utils/curl_stats/curl_stats.c \ + src/utils/curl_stats/curl_stats.h \ + src/utils/format_kairosdb/format_kairosdb.c \ + src/utils/format_kairosdb/format_kairosdb.h +write_http_la_CFLAGS = $(AM_CFLAGS) $(BUILD_WITH_LIBCURL_CFLAGS) +write_http_la_LDFLAGS = $(PLUGIN_LDFLAGS) +write_http_la_LIBADD = libformat_json.la $(BUILD_WITH_LIBCURL_LIBS) +endif + +if BUILD_PLUGIN_WRITE_INFLUXDB_UDP +pkglib_LTLIBRARIES += write_influxdb_udp.la +write_influxdb_udp_la_SOURCES = src/write_influxdb_udp.c +write_influxdb_udp_la_CPPFLAGS = $(AM_CPPFLAGS) +write_influxdb_udp_la_LDFLAGS = $(PLUGIN_LDFLAGS) +if BUILD_WITH_LIBSOCKET +write_influxdb_udp_la_LIBADD = -lsocket +endif +endif + +if BUILD_PLUGIN_WRITE_KAFKA +pkglib_LTLIBRARIES += write_kafka.la +write_kafka_la_SOURCES = src/write_kafka.c +write_kafka_la_CPPFLAGS = $(AM_CPPFLAGS) $(BUILD_WITH_LIBRDKAFKA_CPPFLAGS) +write_kafka_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_LIBRDKAFKA_LDFLAGS) +write_kafka_la_LIBADD = \ + libcmds.la \ + libformat_graphite.la \ + libformat_json.la \ + $(BUILD_WITH_LIBRDKAFKA_LIBS) +endif + +if BUILD_PLUGIN_WRITE_LOG +pkglib_LTLIBRARIES += write_log.la +write_log_la_SOURCES = src/write_log.c +write_log_la_LDFLAGS = $(PLUGIN_LDFLAGS) +write_log_la_LIBADD = libformat_graphite.la libformat_json.la +endif + +if BUILD_PLUGIN_WRITE_MONGODB +pkglib_LTLIBRARIES += write_mongodb.la +write_mongodb_la_SOURCES = src/write_mongodb.c +write_mongodb_la_CFLAGS = $(AM_CFLAGS) $(BUILD_WITH_LIBMONGOC_CFLAGS) +write_mongodb_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_LIBMONGOC_LDFLAGS) +write_mongodb_la_LIBADD = $(BUILD_WITH_LIBMONGOC_LIBS) +endif + +if BUILD_PLUGIN_WRITE_PROMETHEUS +pkglib_LTLIBRARIES += write_prometheus.la +write_prometheus_la_SOURCES = src/write_prometheus.c +nodist_write_prometheus_la_SOURCES = \ + prometheus.pb-c.c \ + prometheus.pb-c.h +write_prometheus_la_CPPFLAGS = $(AM_CPPFLAGS) $(BUILD_WITH_LIBPROTOBUF_C_CPPFLAGS) $(BUILD_WITH_LIBMICROHTTPD_CPPFLAGS) +write_prometheus_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_LIBPROTOBUF_C_LDFLAGS) $(BUILD_WITH_LIBMICROHTTPD_LDFLAGS) +write_prometheus_la_LIBADD = $(BUILD_WITH_LIBPROTOBUF_C_LIBS) $(BUILD_WITH_LIBMICROHTTPD_LIBS) +endif + +if BUILD_PLUGIN_WRITE_REDIS +pkglib_LTLIBRARIES += write_redis.la +write_redis_la_SOURCES = src/write_redis.c +write_redis_la_CPPFLAGS = $(AM_CPPFLAGS) $(BUILD_WITH_LIBHIREDIS_CPPFLAGS) +write_redis_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_LIBHIREDIS_LDFLAGS) +write_redis_la_LIBADD = -lhiredis +endif + +if BUILD_PLUGIN_WRITE_RIEMANN +pkglib_LTLIBRARIES += write_riemann.la +write_riemann_la_SOURCES = \ + src/write_riemann.c \ + src/write_riemann_threshold.c \ + src/write_riemann_threshold.h +write_riemann_la_CFLAGS = $(AM_CFLAGS) $(LIBRIEMANN_CLIENT_CFLAGS) +write_riemann_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(LIBRIEMANN_CLIENT_LIBS) +endif + +if BUILD_PLUGIN_WRITE_SENSU +pkglib_LTLIBRARIES += write_sensu.la +write_sensu_la_SOURCES = src/write_sensu.c +write_sensu_la_LDFLAGS = $(PLUGIN_LDFLAGS) +endif + +if BUILD_PLUGIN_WRITE_STACKDRIVER +pkglib_LTLIBRARIES += write_stackdriver.la +write_stackdriver_la_SOURCES = src/write_stackdriver.c +write_stackdriver_la_LDFLAGS = $(PLUGIN_LDFLAGS) +write_stackdriver_la_CPPFLAGS = $(AM_CPPFLAGS) $(BUILD_WITH_LIBCURL_CFLAGS) +write_stackdriver_la_LIBADD = libformat_stackdriver.la libgce.la liboauth.la \ + $(BUILD_WITH_LIBCURL_LIBS) +endif + +if BUILD_PLUGIN_WRITE_SYSLOG +pkglib_LTLIBRARIES += write_syslog.la +write_syslog_la_SOURCES = src/write_syslog.c +write_syslog_la_LDFLAGS = $(PLUGIN_LDFLAGS) +endif + +if BUILD_PLUGIN_WRITE_TSDB +pkglib_LTLIBRARIES += write_tsdb.la +write_tsdb_la_SOURCES = src/write_tsdb.c +write_tsdb_la_LDFLAGS = $(PLUGIN_LDFLAGS) +endif + +if BUILD_PLUGIN_XENCPU +pkglib_LTLIBRARIES += xencpu.la +xencpu_la_SOURCES = src/xencpu.c +xencpu_la_CPPFLAGS = $(AM_CPPFLAGS) $(LIBXENCTL_CPPFLAGS) +xencpu_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(LIBXENCTL_LDFLAGS) +xencpu_la_LIBADD = -lxenctrl +endif + +if BUILD_PLUGIN_XMMS +pkglib_LTLIBRARIES += xmms.la +xmms_la_SOURCES = src/xmms.c +xmms_la_CFLAGS = $(AM_CFLAGS) $(BUILD_WITH_LIBXMMS_CFLAGS) +xmms_la_LDFLAGS = $(PLUGIN_LDFLAGS) +xmms_la_LIBADD = $(BUILD_WITH_LIBXMMS_LIBS) +endif + +if BUILD_PLUGIN_ZFS_ARC +pkglib_LTLIBRARIES += zfs_arc.la +zfs_arc_la_SOURCES = src/zfs_arc.c +zfs_arc_la_LDFLAGS = $(PLUGIN_LDFLAGS) +if BUILD_FREEBSD +zfs_arc_la_LIBADD = -lm +endif +if BUILD_SOLARIS +zfs_arc_la_LIBADD = -lkstat +endif +endif + +if BUILD_PLUGIN_ZOOKEEPER +pkglib_LTLIBRARIES += zookeeper.la +zookeeper_la_SOURCES = src/zookeeper.c +zookeeper_la_LDFLAGS = $(PLUGIN_LDFLAGS) +endif + +if BUILD_PLUGIN_ZONE +pkglib_LTLIBRARIES += zone.la +zone_la_SOURCES = src/zone.c +zone_la_LDFLAGS = $(PLUGIN_LDFLAGS) +endif + +AM_V_POD2MAN_C = $(am__v_POD2MAN_C_@AM_V@) +am__v_POD2MAN_C_ = $(am__v_POD2MAN_C_@AM_DEFAULT_V@) +am__v_POD2MAN_C_0 = @echo " POD2MAN " $@; +am__v_POD2MAN_C_1 = + +.pod.1: + $(AM_V_POD2MAN_C)pod2man --release=$(VERSION) --center=$(PACKAGE) $< $@ + +.pod.5: + $(AM_V_POD2MAN_C)pod2man --section=5 --release=$(VERSION) --center=$(PACKAGE) $< $@ + +V_PROTOC = $(v_protoc_@AM_V@) +v_protoc_ = $(v_protoc_@AM_DEFAULT_V@) +v_protoc_0 = @echo " PROTOC " $@; + +AM_V_PROTOC_C = $(am__v_PROTOC_C_@AM_V@) +am__v_PROTOC_C_ = $(am__v_PROTOC_C_@AM_DEFAULT_V@) +am__v_PROTOC_C_0 = @echo " PROTOC-C" $@; +am__v_PROTOC_C_1 = + +# Protocol buffer for the "pinba" plugin. +if BUILD_PLUGIN_PINBA +BUILT_SOURCES += src/pinba.pb-c.c src/pinba.pb-c.h + +src/pinba.pb-c.c src/pinba.pb-c.h: $(srcdir)/src/pinba.proto + $(AM_V_PROTOC_C)$(PROTOC_C) -I$(srcdir) --c_out . $(srcdir)/src/pinba.proto +endif + +# Protocol buffer for the "write_prometheus" plugin. +if BUILD_PLUGIN_WRITE_PROMETHEUS +BUILT_SOURCES += prometheus.pb-c.c prometheus.pb-c.h + +prometheus.pb-c.c prometheus.pb-c.h: $(srcdir)/proto/prometheus.proto + $(AM_V_PROTOC_C)$(PROTOC_C) -I$(srcdir)/proto --c_out=$(builddir) $(srcdir)/proto/prometheus.proto +endif + +if HAVE_PROTOC3 +if HAVE_GRPC_CPP +BUILT_SOURCES += collectd.grpc.pb.cc collectd.pb.cc types.pb.cc + +collectd.grpc.pb.cc: $(srcdir)/proto/collectd.proto $(srcdir)/proto/types.proto + $(V_PROTOC)$(PROTOC) -I$(srcdir)/proto \ + --grpc_out=$(builddir) --plugin=protoc-gen-grpc=$(GRPC_CPP_PLUGIN) \ + $(srcdir)/proto/collectd.proto $(srcdir)/proto/types.proto + +collectd.pb.cc: $(srcdir)/proto/collectd.proto $(srcdir)/proto/types.proto + $(V_PROTOC)$(PROTOC) -I$(srcdir)/proto --cpp_out=$(builddir) \ + $(srcdir)/proto/collectd.proto $(srcdir)/proto/types.proto + +types.pb.cc: $(srcdir)/proto/types.proto + $(V_PROTOC)$(PROTOC) -I$(srcdir)/proto --cpp_out=$(builddir) \ + $(srcdir)/proto/types.proto +endif +endif install-exec-hook: $(mkinstalldirs) $(DESTDIR)$(localstatedir)/run $(mkinstalldirs) $(DESTDIR)$(localstatedir)/lib/$(PACKAGE_NAME) $(mkinstalldirs) $(DESTDIR)$(localstatedir)/log + $(mkinstalldirs) $(DESTDIR)$(sysconfdir) + if test -e $(DESTDIR)$(sysconfdir)/collectd.conf; \ + then \ + $(INSTALL) -m 0640 $(builddir)/src/collectd.conf $(DESTDIR)$(sysconfdir)/collectd.conf.pkg-orig; \ + else \ + $(INSTALL) -m 0640 $(builddir)/src/collectd.conf $(DESTDIR)$(sysconfdir)/collectd.conf; \ + fi; \ + $(mkinstalldirs) $(DESTDIR)$(cpkgdatadir) + $(INSTALL) -m 0644 $(srcdir)/src/types.db $(DESTDIR)$(cpkgdatadir)/types.db; + $(INSTALL) -m 0644 $(srcdir)/src/postgresql_default.conf \ + $(DESTDIR)$(cpkgdatadir)/postgresql_default.conf; + +uninstall-hook: + rm -f $(DESTDIR)$(cpkgdatadir)/types.db; + rm -f $(DESTDIR)$(sysconfdir)/collectd.conf + rm -f $(DESTDIR)$(cpkgdatadir)/postgresql_default.conf; + +all-local: @PERL_BINDINGS@ + +install-exec-local: + [ ! -f buildperl/Makefile ] || ( cd buildperl && $(MAKE) install ) + +# Perl 'make uninstall' does not work as well as wanted. +# So we do the work here. +uninstall-local: + @PERL@ -I$(DESTDIR)$(prefix) $(srcdir)/bindings/perl/uninstall_mod.pl Collectd + find $(DESTDIR)$(prefix) -name "perllocal.pod" -exec rm {} \; + +clean-local: + rm -rf buildperl + +perl: buildperl/Makefile + cd buildperl && $(MAKE) + +buildperl/Makefile: .perl-directory-stamp buildperl/Makefile.PL \ + $(top_builddir)/config.status + @# beautify the output a bit + @echo 'cd buildperl && @PERL@ Makefile.PL @PERL_BINDINGS_OPTIONS@' + @cd buildperl && ( if ! @PERL@ Makefile.PL @PERL_BINDINGS_OPTIONS@; then \ + echo ""; \ + echo 'Check whether you have set $$PERL_MM_OPT in your environment and try using ./configure --with-perl-bindings=""'; \ + echo ""; \ + fi ) + +buildperl/Makefile.PL: .perl-directory-stamp $(top_builddir)/config.status + +.perl-directory-stamp: + if test ! -d buildperl; then \ + mkdir -p buildperl/Collectd/Plugins; \ + cp $(srcdir)/bindings/perl/lib/Collectd.pm buildperl/; \ + cp $(srcdir)/bindings/perl/Makefile.PL buildperl/; \ + cp $(srcdir)/bindings/perl/lib/Collectd/Unixsock.pm buildperl/Collectd/; \ + cp $(srcdir)/bindings/perl/lib/Collectd/Plugins/OpenVZ.pm buildperl/Collectd/Plugins/; \ + fi + touch $@ + +.PHONY: perl + + +if BUILD_WITH_JAVA +dist_noinst_JAVA = \ + bindings/java/org/collectd/api/Collectd.java \ + bindings/java/org/collectd/api/CollectdConfigInterface.java \ + bindings/java/org/collectd/api/CollectdFlushInterface.java \ + bindings/java/org/collectd/api/CollectdInitInterface.java \ + bindings/java/org/collectd/api/CollectdLogInterface.java \ + bindings/java/org/collectd/api/CollectdMatchFactoryInterface.java \ + bindings/java/org/collectd/api/CollectdMatchInterface.java \ + bindings/java/org/collectd/api/CollectdNotificationInterface.java \ + bindings/java/org/collectd/api/CollectdReadInterface.java \ + bindings/java/org/collectd/api/CollectdShutdownInterface.java \ + bindings/java/org/collectd/api/CollectdTargetFactoryInterface.java \ + bindings/java/org/collectd/api/CollectdTargetInterface.java \ + bindings/java/org/collectd/api/CollectdWriteInterface.java \ + bindings/java/org/collectd/api/DataSet.java \ + bindings/java/org/collectd/api/DataSource.java \ + bindings/java/org/collectd/api/Notification.java \ + bindings/java/org/collectd/api/OConfigItem.java \ + bindings/java/org/collectd/api/OConfigValue.java \ + bindings/java/org/collectd/api/PluginData.java \ + bindings/java/org/collectd/api/ValueList.java \ + bindings/java/org/collectd/java/GenericJMX.java \ + bindings/java/org/collectd/java/GenericJMXConfConnection.java \ + bindings/java/org/collectd/java/GenericJMXConfMBean.java \ + bindings/java/org/collectd/java/GenericJMXConfValue.java \ + bindings/java/org/collectd/java/JMXMemory.java + +collectd-api.jar: $(JAVA_TIMESTAMP_FILE) + $(JAR) cf $(JARFLAGS) $@ org/collectd/api/*.class + +generic-jmx.jar: $(JAVA_TIMESTAMP_FILE) + $(JAR) cf $(JARFLAGS) $@ org/collectd/java/*.class + +jar_DATA = collectd-api.jar generic-jmx.jar +endif -maintainer-clean-local: - -rm -f -r libltdl - -rm -f INSTALL - -rm -f aclocal.m4 diff --git a/NEWS b/NEWS deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/README b/README index c0d703633d..b13192f1bd 100644 --- a/README +++ b/README @@ -1,6 +1,6 @@ collectd - System information collection daemon ================================================= -http://collectd.org/ +https://collectd.org/ About ----- @@ -16,22 +16,27 @@ Features * collectd is able to collect the following data: - apache - Apache server utilization: Number of bytes transfered, number of + Apache server utilization: Number of bytes transferred, number of requests handled and detailed scoreboard statistics - apcups APC UPS Daemon: UPS charge, load, input/output/battery voltage, etc. - apple_sensors - Sensors in Macs running Mac OS X / Darwin: Temperature, fanspeed and + Sensors in Macs running Mac OS X / Darwin: Temperature, fan speed and voltage sensors. - aquaero - Various sensors in the Aquaero 5 watercooling board made by Aquacomputer. + Various sensors in the Aquaero 5 water cooling board made by Aquacomputer. - ascent Statistics about Ascent, a free server for the game `World of Warcraft'. + - barometer + Reads absolute barometric pressure, air pressure reduced to sea level and + temperature. Supported sensors are MPL115A2 and MPL3115 from Freescale + and BMP085 from Bosch. + - battery Batterycharge, -current and voltage of ACPI and PMU based laptop batteries. @@ -40,9 +45,26 @@ Features Name server and resolver statistics from the `statistics-channel' interface of BIND 9.5, 9,6 and later. + - buddyinfo + Statistics from buddyinfo file about memory fragmentation. + + - capabilities + Platform capabilities decoded from hardware subsystems, for example from + SMBIOS using dmidecode. + + + - ceph + Statistics from the Ceph distributed storage system. + - cgroups CPU accounting information for process groups under Linux. + - chrony + Chrony daemon statistics: Local clock drift, offset to peers, etc. + + - connectivity + Event-based interface status. + - conntrack Number of nf_conntrack entries. @@ -56,6 +78,9 @@ Features - cpufreq CPU frequency (For laptops with speed step or a similar technology) + - cpusleep + CPU sleep: Time spent in suspend (For mobile devices which enter suspend automatically) + - curl Parse statistics from websites using regular expressions. @@ -71,6 +96,9 @@ Features Executes SQL statements on various databases and interprets the returned data. + - dcpmm + Collects Intel Optane DC Presistent Memory (DCPMM) performance and health statistics. + - df Mountpoint usage (Basically the values `df(1)' delivers) @@ -80,7 +108,26 @@ Features - dns DNS traffic: Query types, response codes, opcodes and traffic/octets - transfered. + transferred. + + - dpdkstat + Collect DPDK interface statistics. + See docs/BUILD.dpdkstat.md for detailed build instructions. + + This plugin should be compiled with compiler defenses enabled, for + example -fstack-protector. + + - dpdk_telemetry + Collect DPDK interface, application and global statistics. + This plugin can be used as substitute to dpdkstat plugin. + + This plugin is dependent on DPDK 19.08 release and must be used + along with the DPDK application. + + Also, this plugin has dependency on Jansson library. + + - drbd + Collect individual drbd resource statistics. - email Email statistics: Count, traffic, spam scores and checks. @@ -96,6 +143,9 @@ Features Values gathered by a custom program or script. See collectd-exec(5). + - fhcount + File handles statistics. + - filecount Count the number of files in directories. @@ -105,20 +155,55 @@ Features - gmond Receive multicast traffic from Ganglia instances. + - gps + Monitor gps related data through gpsd. + + - gpu_nvidia + Monitor NVIDIA GPU statistics available through NVML. + - hddtemp - Harddisk temperatures using hddtempd. + Hard disk temperatures using hddtempd. + + - hugepages + Report the number of used and free hugepages. More info on + hugepages can be found here: + https://www.kernel.org/doc/Documentation/vm/hugetlbpage.txt. + + This plugin should be compiled with compiler defenses enabled, for + example -fstack-protector. + + - intel_pmu + The intel_pmu plugin reads performance counters provided by the Linux + kernel perf interface. The plugin uses jevents library to resolve named + events to perf events and access perf interface. + + - intel_rdt + The intel_rdt plugin collects information provided by monitoring features + of Intel Resource Director Technology (Intel(R) RDT) like Cache Monitoring + Technology (CMT), Memory Bandwidth Monitoring (MBM). These features + provide information about utilization of shared resources like last level + cache occupancy, local memory bandwidth usage, remote memory bandwidth + usage, instructions per clock. + - interface Interface traffic: Number of octets, packets and errors for each interface. - - iptables - Iptables' counters: Number of bytes that were matched by a certain - iptables rule. + - ipc + IPC counters: semaphores used, number of allocated segments in shared + memory and more. - ipmi IPMI (Intelligent Platform Management Interface) sensors information. + - ipstats + IPv4 and IPv6; incoming, outgoing, forwarded counters. FreeBSD only. + + - iptables + Iptables' counters: Number of bytes that were matched by a certain + iptables rule. + - ipvs IPVS connection statistics (number of connections, octets and packets for each service and destination). @@ -129,7 +214,8 @@ Features - java Integrates a `Java Virtual Machine' (JVM) to execute plugins in Java - bytecode. See “Configuring with libjvm” below. + bytecode. + See docs/BUILD.java.md for detailed build instructions. - load System load average over the last 1, 5 and 15 minutes. @@ -138,21 +224,25 @@ Features Detailed CPU statistics of the “Logical Partitions” virtualization technique built into IBM's POWER processors. - - libvirt - CPU, memory, disk and network I/O statistics from virtual machines. - - - lvm - Size of “Logical Volumes” (LV) and “Volume Groups” (VG) of Linux' - “Logical Volume Manager” (LVM). + - lua + The Lua plugin implements a Lua interpreter into collectd. This + makes it possible to write plugins in Lua which are executed by + collectd without the need to start a heavy interpreter every interval. + See collectd-lua(5) for details. - madwifi Queries very detailed usage statistics from wireless LAN adapters and interfaces that use the Atheros chipset and the MadWifi driver. - mbmon - Motherboard sensors: temperature, fanspeed and voltage information, + Motherboard sensors: temperature, fan speed and voltage information, using mbmon(1). + - mcelog + Monitor machine check exceptions (hardware errors detected by hardware + and reported to software) reported by mcelog and generate appropriate + notifications when machine check exceptions are detected. + - md Linux software-RAID device information (number of active, failed, spare and missing disks). @@ -186,7 +276,7 @@ Features - netapp Plugin to query performance values from a NetApp storage system using the - “Manage ONTAP” SDK provided by NetApp. + “Manage ONTAP” SDK provided by NetApp. - netlink Very detailed Linux network interface and routing statistics. You can get @@ -199,8 +289,7 @@ Features plugin of choice for that. - nfs - NFS Procedures: Which NFS command were called how often. Only NFSv2 and - NFSv3 right now. + NFS Procedures: Which NFS command were called how often. - nginx Collects statistics from `nginx' (speak: engine X), a HTTP and mail @@ -209,13 +298,13 @@ Features - ntpd NTP daemon statistics: Local clock drift, offset to peers, etc. + - numa + Information about Non-Uniform Memory Access (NUMA). + - nut Network UPS tools: UPS current, voltage, power, charge, utilisation, temperature, etc. See upsd(8). - - numa - Information about Non-Uniform Memory Access (NUMA). - - olsrd Queries routing information from the “Optimized Link State Routing” daemon. @@ -224,6 +313,9 @@ Features Read onewire sensors using the owcapu library of the owfs project. Please read in collectd.conf(5) why this plugin is experimental. + - openldap + Read monitoring information from OpenLDAP's cn=Monitor subtree. + - openvpn RX and TX of each client in openvpn-status.log (status-version 2). @@ -231,6 +323,26 @@ Features - oracle Query data from an Oracle database. + - ovs_events + The plugin monitors the link status of Open vSwitch (OVS) connected + interfaces, dispatches the values to collectd and sends the notification + whenever the link state change occurs in the OVS database. It requires + YAJL library to be installed. + Detailed instructions for installing and setting up Open vSwitch, see + OVS documentation. + + + - ovs_stats + The plugin collects the statistics of OVS connected bridges and + interfaces. It requires YAJL library to be installed. + Detailed instructions for installing and setting up Open vSwitch, see + OVS documentation. + + + - pcie_errors + Read errors from PCI Express Device Status and AER extended capabilities. + + - perl The perl plugin implements a Perl-interpreter into collectd. You can write your own plugins in Perl and return arbitrary values using this @@ -257,6 +369,9 @@ Features - 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. @@ -267,7 +382,7 @@ Features See collectd-python(5) for details. - redis - The redis plugin gathers information from a redis server, including: + The redis plugin gathers information from a Redis server, including: uptime, used memory, total connections etc. - routeros @@ -288,19 +403,34 @@ Features to have its measurements fed to collectd. This includes multimeters, sound level meters, thermometers, and much more. + - slurm + Gathers per-partition node and job state information using libslurm, + as well as internal health statistics. + + - smart + Collect SMART statistics, notably load cycle count, temperature + and bad sectors. + - snmp Read values from SNMP (Simple Network Management Protocol) enabled network devices such as switches, routers, thermometers, rack monitoring servers, etc. See collectd-snmp(5). + - statsd + 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 harddisk or whatever is called `swap' by the OS.. + Pages swapped out onto hard disk or whatever is called `swap' by the OS.. - table Parse table-like structured files. - tail - Follows (tails) logfiles, parses them by lines and submits matched + Follows (tails) log files, parses them by lines and submits matched values. - tail_csv @@ -326,6 +456,14 @@ Features Reads the number of records and file size from a running Tokyo Tyrant server. + - turbostat + Reads CPU frequency and C-state residency on modern Intel + turbo-capable processors. + + - ubi + Reads the count of bad physical eraseblocks and the current + maximum erase counter value on UBI volumes. + - uptime System uptime statistics. @@ -335,8 +473,11 @@ Features - varnish Various statistics from Varnish, an HTTP accelerator. + - virt + CPU, memory, disk and network I/O statistics from virtual machines. + - vmem - Virtual memory statistics, e. g. the number of page-ins/-outs or the + Virtual memory statistics, e.g. the number of page-ins/-outs or the number of pagefaults. - vserver @@ -346,24 +487,48 @@ Features - wireless Link quality of wireless cards. Linux only. + - xencpu + XEN Hypervisor CPU stats. + - xmms Bitrate and frequency of music played with XMMS. - zfs_arc Statistics for ZFS' “Adaptive Replacement Cache” (ARC). + - zone + Measures the percentage of cpu load per container (zone) under Solaris 10 + and higher + + - zookeeper + Read data from Zookeeper's MNTR command. + * Output can be written or sent to various destinations by the following plugins: - amqp Sends JSON-encoded data to an Advanced Message Queuing Protocol (AMQP) - server, such as RabbitMQ. + 0.9.1 server, such as RabbitMQ. + + - amqp1 + Sends JSON-encoded data to an Advanced Message Queuing Protocol (AMQP) + 1.0 server, such as Qpid Dispatch Router or Apache Artemis Broker. - csv Write to comma separated values (CSV) files. This needs lots of diskspace but is extremely portable and can be analysed with almost every program that can analyse anything. Even Microsoft's Excel.. + - grpc + Send and receive values over the network using the gRPC framework. + + - lua + It's possible to implement write plugins in Lua using the Lua + plugin. See collectd-lua(5) for details. + + - mqtt + Publishes and subscribes to MQTT topics. + - network Send the data to a remote host to save the data somehow. This is useful for large setups where the data should be saved by a dedicated machine. @@ -389,6 +554,13 @@ Features updates to the files and write a bunch of updates at once, which lessens system load a lot. + - snmp_agent + Receives and handles queries from SNMP master agent and returns the data + collected by read plugins. Handles requests only for OIDs specified in + configuration file. To handle SNMP queries the plugin gets data from + collectd and translates requested values from collectd's internal format + to SNMP format. + - unixsock One can query the values from the unixsock plugin whenever they're needed. Please read collectd-unixsock(5) for a description on how that's @@ -404,20 +576,42 @@ Features requests. The transmitted data is either in a form understood by the Exec plugin or formatted in JSON. + - write_kafka + Sends data to Apache Kafka, a distributed queue. + + - write_log + Writes data to the log + - write_mongodb Sends data to MongoDB, a NoSQL database. + - write_prometheus + Publish values using an embedded HTTP server, in a format compatible + with Prometheus' collectd_exporter. + - write_redis Sends the values to a Redis key-value database server. - write_riemann Sends data to Riemann, a stream processing and monitoring system. + - write_sensu + Sends data to Sensu, a stream processing and monitoring system, via the + Sensu client local TCP socket. + + - write_syslog + Sends data in syslog format, using TCP, where the message + contains the metric in human or JSON format. + + - write_tsdb + Sends data OpenTSDB, a scalable no master, no shared state time series + database. + * Logging is, as everything in collectd, provided by plugins. The following - plugins keep up informed about what's going on: + plugins keep us informed about what's going on: - logfile - Writes logmessages to a file or STDOUT/STDERR. + Writes log messages to a file or STDOUT/STDERR. - perl Log messages are propagated to plugins written in Perl as well. @@ -430,6 +624,9 @@ Features - syslog Logs to the standard UNIX logging mechanism, syslog. + - log_logstash + Writes log messages formatted as logstash JSON events. + * Notifications can be handled by the following plugins: - notify_desktop @@ -442,6 +639,9 @@ Features Send an E-mail with the notification message to the configured recipients. + - notify_nagios + Submit notifications as passive check results to a local nagios instance. + - exec Execute a program or script to handle the notification. See collectd-exec(5). @@ -501,7 +701,7 @@ Features values are out of bounds. See collectd-threshold(5) for details. - uuid - Sets the hostname to an unique identifier. This is meant for setups + Sets the hostname to a unique identifier. This is meant for setups where each client may migrate to another physical host, possibly going through one or more name changes in the process. @@ -509,7 +709,7 @@ Features time starting up again and again. With the exception of the exec plugin no processes are forked. Caching in output plugins, such as the rrdtool and network plugins, makes sure your resources are used efficiently. Also, - since collectd is programmed multithreaded it benefits from hyperthreading + since collectd is programmed multithreaded it benefits from hyper-threading and multicore processors and makes sure that the daemon isn't idle if only one plugin waits for an IO-operation to complete. @@ -521,7 +721,7 @@ Operation --------- * collectd's configuration file can be found at `sysconfdir'/collectd.conf. - Run `collectd -h' for a list of builtin defaults. See `collectd.conf(5)' + Run `collectd -h' for a list of built-in defaults. See `collectd.conf(5)' for a list of options and a syntax description. * When the `csv' or `rrdtool' plugins are loaded they'll write the values to @@ -563,12 +763,22 @@ Prerequisites * Usual suspects: C compiler, linker, preprocessor, make, ... + collectd makes use of some common C99 features, e.g. compound literals and + mixed declarations, and therefore requires a C99 compatible compiler. + + On Debian and Ubuntu, the "build-essential" package should pull in + everything that's necessary. + * A POSIX-threads (pthread) implementation. Since gathering some statistics is slow (network connections, slow devices, - etc) the collectd is parallelized. The POSIX threads interface is being + etc) collectd is parallelized. The POSIX threads interface is being used and should be found in various implementations for hopefully all platforms. + * When building from the Git repository, flex (tokenizer) and bison (parser + generator) are required. Release tarballs include the generated files – you + don't need these packages in that case. + * aerotools-ng (optional) Used by the `aquaero' plugin. Currently, the `libaquaero5' library, which is used by the `aerotools-ng' toolkit, is not compiled as a shared object @@ -582,16 +792,30 @@ Prerequisites particular. + * CUDA (optional) + Used by the `gpu_nvidia' plugin + + + * libatasmart (optional) + Used by the `smart' plugin. + + + * libcap (optional) + The `turbostat' plugin can optionally build Linux Capabilities support, + which avoids full privileges requirement (aka. running as root) to read + values. + + * libclntsh (optional) Used by the `oracle' plugin. - * libcredis (optional) - Used by the redis plugin. Please note that you require a 0.2.2 version - or higher. + * libhiredis (optional) + Used by the redis plugin. Please note that you require a 0.10.0 version + or higher. * libcurl (optional) - If you want to use the `apache', `ascent', `curl', `nginx', or `write_http' - plugin. + If you want to use the `apache', `ascent', `bind', `curl', `curl_json', + `curl_xml', `nginx', or `write_http' plugin. * libdbi (optional) @@ -606,41 +830,67 @@ Prerequisites Used by the `gmond' plugin to process data received from Ganglia. + * libgrpc (optional) + Used by the `grpc' plugin. gRPC requires a C++ compiler supporting the + C++11 standard. + + * libgcrypt (optional) Used by the `network' plugin for encryption and authentication. - * libhal (optional) - If present, the uuid plugin will check for UUID from HAL. - + * libgps (optional) + Used by the `gps' plugin. + + + * libi2c-dev (optional) + Used for the plugin `barometer', provides just the i2c-dev.h header file + for user space i2c development. * libiptc (optional) For querying iptables counters. - If not found on the system, a version shipped with this distribution can - be used. It requires some Linux headers in /usr/include/linux. You can - force the build system to use the shipped version by specifying - --with-libiptc=shipped - when running the configure script. + * libjansson (optional) + Parse JSON data. This is used for the `capabilities' and `dpdk_telemetry` plugins. + + + * libjevents (optional) + The jevents library is used by the `intel_pmu' plugin to access the Linux + kernel perf interface. + Note: the library should be build with -fPIC flag to be linked with + intel_pmu shared object correctly. + * libjvm (optional) Library that encapsulates the `Java Virtual Machine' (JVM). This library is - used by the Java plugin to execute Java bytecode. See “Configuring with - libjvm” below. + used by the `java' plugin to execute Java bytecode. + See docs/BUILD.java.md for detailed build instructions. (and others) + * libldap (optional) + Used by the `openldap' plugin. + + + * liblua (optional) + Used by the `lua' plugin. Currently, Lua 5.1 and later are supported. + + * libmemcached (optional) Used by the `memcachec' plugin to connect to a memcache daemon. + * libmicrohttpd (optional) + Used by the write_prometheus plugin to run an http daemon. + + * libmnl (optional) Used by the `netlink' plugin. * libmodbus (optional) - Used by the “modbus” plugin to communicate with Modbus/TCP devices. The - “modbus” plugin works with version 2.0.3 of the library – due to frequent + Used by the `modbus' plugin to communicate with Modbus/TCP devices. The + `modbus' plugin works with version 2.0.3 of the library – due to frequent API changes other versions may or may not compile cleanly. @@ -649,20 +899,28 @@ Prerequisites * libnetapp (optional) - Required for the “netapp” plugin. + Required for the `netapp' plugin. This library is part of the “Manage ONTAP SDK” published by NetApp. * libnetsnmp (optional) - For the `snmp' plugin. + For the `snmp' and 'snmp_agent' plugins. + + + * libnetsnmpagent (optional) + Required for the 'snmp_agent' plugin. * libnotify (optional) For the `notify_desktop' plugin. + * libopenipmi (optional) + Used by the `ipmi' plugin to prove IPMI devices. + + * liboping (optional) Used by the `ping' plugin to send and receive ICMP packets. - + * libowcapi (optional) Used by the `onewire' plugin to read values from onewire sensors (or the @@ -681,27 +939,54 @@ Prerequisites ithread support (introduced in Perl 5.6.0). + * libpmwapi (optional) + Used by the `dcpmm` plugin. + The library github: https://github.com/intel/intel-pmwatch + Follow the pmwatch build instructions mentioned for dcpmm plugin and + use the install path to resolve the dependency here. + * libpq (optional) The PostgreSQL C client library used by the `postgresql' plugin. + * libpqos (optional) + The PQoS library for Intel(R) Resource Director Technology used by the + `intel_rdt' plugin. + + + * libprotobuf, protoc 3.0+ (optional) + Used by the `grpc' plugin to generate service stubs and code to handle + network packets of collectd's protobuf-based network protocol. + + * libprotobuf-c, protoc-c (optional) Used by the `pinba' plugin to generate a parser for the network packets sent by the Pinba PHP extension. * libpython (optional) - Used by the `python' plugin. Currently, Python 2.3 and later and Python 3 + Used by the `python' plugin. Currently, Python 2.6 and later and Python 3 are supported. + * libqpid-proton (optional) + Used by the `amqp1' plugin for AMQP 1.0 connections, for example to + Qdrouterd. + + * librabbitmq (optional; also called “rabbitmq-c”) - Used by the AMQP plugin for AMQP connections, for example to RabbitMQ. + Used by the `amqp' plugin for AMQP 0.9.1 connections, for example to + RabbitMQ. + * librdkafka (optional; also called “rdkafka”) + Used by the `write_kafka' plugin for producing messages and sending them + to a Kafka broker. + + * librouteros (optional) Used by the `routeros' plugin to connect to a device running `RouterOS'. - + * librrd (optional) Used by the `rrdtool' and `rrdcached' plugins. The latter requires RRDtool @@ -718,17 +1003,21 @@ Prerequisites * libsigrok (optional) - Used by the sigrok plugin. In addition, libsigrok depends on glib, + Used by the `sigrok' plugin. In addition, libsigrok depends on glib, libzip, and optionally (depending on which drivers are enabled) on libusb, libftdi and libudev. + * libslurm (optional) + Used by the `slurm` plugin. + + * libstatgrab (optional) Used by various plugins to collect statistics on systems other than Linux and/or Solaris. * libtokyotyrant (optional) - Used by the tokyotyrant plugin. + Used by the `tokyotyrant' plugin. * libupsclient/nut (optional) @@ -740,27 +1029,37 @@ Prerequisites * libxml2 (optional) - Parse XML data. This is needed for the `ascent' and `libvirt' plugins. + Parse XML data. This is needed for the `ascent', `bind', `curl_xml' and + `virt' plugins. + * libxen (optional) + Used by the `xencpu' plugin. + + * libxmms (optional) * libyajl (optional) - Parse JSON data. This is needed for the `curl_json' plugin. + Parse JSON data. This is needed for the `ceph', `curl_json', 'ovs_events', + 'ovs_stats' and `log_logstash' plugins. * libvarnish (optional) - Fetches statistics from a Varnish instance. This is needed for the Varnish plugin + Fetches statistics from a Varnish instance. This is needed for the + `varnish' plugin. + * riemann-c-client (optional) + For the `write_riemann' plugin. + + Configuring / Compiling / Installing ------------------------------------ To configure, build and install collectd with the default settings, run - `./configure && make && make install'. For detailed, generic instructions - see INSTALL. For a complete list of configure options and their description, - run `./configure --help'. + `./configure && make && make install'. For a complete list of configure + options and their description, run `./configure --help'. By default, the configure script will check for all build dependencies and disable all plugins whose requirements cannot be fulfilled (any other plugin @@ -784,42 +1083,54 @@ Configuring / Compiling / Installing prefixed to all installation directories. This might be useful when creating packages for collectd. -Configuring with libjvm ------------------------ +Generating the configure script +------------------------------- - To determine the location of the required files of a Java installation is not - an easy task, because the locations vary with your kernel (Linux, SunOS, …) - and with your architecture (x86, SPARC, …) and there is no ‘java-config’ - script we could use. Configuration of the JVM library is therefore a bit - tricky. +Collectd ships with a `build.sh' script to generate the `configure' +script shipped with releases. - The easiest way to use the `--with-java=$JAVA_HOME' option, where - `$JAVA_HOME' is usually something like: - /usr/lib/jvm/java-1.5.0-sun-1.5.0.14 +To generate the `configure` script, you'll need the following dependencies: - The configure script will then use find(1) to look for the following files: +- autoconf +- automake +- flex +- bison +- libtool +- pkg-config - - jni.h - - jni_md.h - - libjvm.so +The `build.sh' script takes no arguments. - If found, appropriate CPP-flags and LD-flags are set and the following - library checks succeed. - If this doesn't work for you, you have the possibility to specify CPP-flags, - C-flags and LD-flags for the ‘Java’ plugin by hand, using the following three - (environment) variables: +Building on Windows +----------------------------------------------- - - JAVA_CPPFLAGS - - JAVA_CFLAGS - - JAVA_LDFLAGS +Collectd can be built on Windows using Cygwin, and the result is a binary that +runs natively on Windows. That is, Cygwin is only needed for building, not running, +collectd. - For example (shortened for demonstration purposes): +You will need to install the following Cygwin packages: +- automake +- bison +- flex +- git +- libtool +- make +- mingw64-x86_64-dlfcn +- mingw64-x86_64-gcc-core +- mingw64-x86_64-zlib +- pkg-config - ./configure JAVA_CPPFLAGS="-I$JAVA_HOME/include -I$JAVA_HOME/include/linux" +To build, just run the `build.sh' script in your Cygwin terminal. By default, it installs +to "C:/Program Files/collectd". You can change the location by setting the INSTALL_DIR +variable: + +$ export INSTALL_DIR="C:/some/other/install/directory" +$ ./build.sh + +or: + +$ INSTALL_DIR="C:/some/other/install/directory" ./build.sh - Adding "-ljvm" to the JAVA_LDFLAGS is done automatically, you don't have to - do that. Crosscompiling -------------- @@ -855,9 +1166,13 @@ Crosscompiling Contact ------- - For questions, bug reports, development information and basically all other - concerns please send an email to collectd's mailing list at - . + Please use GitHub to report bugs and submit pull requests: + . + See CONTRIBUTING.md for details. + + For questions, development information and basically all other concerns please + send an email to collectd's mailing list at + . For live discussion and more personal contact visit us in IRC, we're in channel #collectd on freenode. @@ -866,10 +1181,7 @@ Contact Author ------ - Florian octo Forster , + Florian octo Forster , Sebastian tokkee Harl , and many contributors (see `AUTHORS'). - Please send bug reports and patches to the mailing list, see `Contact' - above. - diff --git a/TODO b/TODO deleted file mode 100644 index 009eb7fca1..0000000000 --- a/TODO +++ /dev/null @@ -1,21 +0,0 @@ -* Finalize the onewire plugin. -* Custom notification messages? -* Implement moving-average calculation for the threshold stuff. - -src/battery.c: commend not working code. - -Wishlist: -* Port nfs module to solaris -* Port tape module to Linux -* Port the apple_sensors plugin to Linux/PPC. -* Maybe look into porting the serial module -* Build Darwin package -* Maybe let the network plugin configure whether or not notifications should be - sent/received. -* Maybe find a way for processes connected to the unixsock plugin to receive - notifications, too. - -http://developer.apple.com/documentation/DeviceDrivers/Conceptual/AccessingHardware/AH_IOKitLib_API/chapter_5_section_1.html -http://developer.apple.com/documentation/DeviceDrivers/Conceptual/IOKitFundamentals/index.html#//apple_ref/doc/uid/TP0000011 -http://www.gauchosoft.com/Software/X%20Resource%20Graph/ -http://johannes.sipsolutions.net/PowerBook/Apple_Motion_Sensor_Specification/ diff --git a/bindings/Makefile.am b/bindings/Makefile.am deleted file mode 100644 index 07373e87a6..0000000000 --- a/bindings/Makefile.am +++ /dev/null @@ -1,69 +0,0 @@ -SUBDIRS = - -if BUILD_WITH_JAVA -SUBDIRS += java -endif - -EXTRA_DIST = perl/Makefile.PL \ - perl/uninstall_mod.pl \ - perl/lib/Collectd.pm \ - perl/lib/Collectd/Unixsock.pm \ - perl/lib/Collectd/Plugins/Monitorus.pm \ - perl/lib/Collectd/Plugins/OpenVZ.pm - -CLEANFILES = \ - buildperl/Collectd.pm \ - buildperl/Collectd/Plugins/OpenVZ.pm \ - buildperl/Collectd/Unixsock.pm \ - buildperl/Makefile.PL \ - .perl-directory-stamp - -DISTCLEANFILES = \ - buildperl/Collectd.pm \ - buildperl/Collectd/Plugins/OpenVZ.pm \ - buildperl/Collectd/Unixsock.pm \ - buildperl/Makefile.PL \ - .perl-directory-stamp - -all-local: @PERL_BINDINGS@ - - -install-exec-local: - [ ! -f buildperl/Makefile ] || ( cd buildperl && $(MAKE) install ) - -# Perl 'make uninstall' does not work as well as wanted. -# So we do the work here. -uninstall-local: - @PERL@ -I$(DESTDIR)$(prefix) $(srcdir)/perl/uninstall_mod.pl Collectd - find $(DESTDIR)$(prefix) -name "perllocal.pod" -exec rm {} \; - -clean-local: - rm -rf buildperl - -perl: buildperl/Makefile - cd buildperl && $(MAKE) - -buildperl/Makefile: .perl-directory-stamp buildperl/Makefile.PL \ - $(top_builddir)/config.status - @# beautify the output a bit - @echo 'cd buildperl && @PERL@ Makefile.PL @PERL_BINDINGS_OPTIONS@' - @cd buildperl && ( if ! @PERL@ Makefile.PL @PERL_BINDINGS_OPTIONS@; then \ - echo ""; \ - echo 'Check whether you have set $$PERL_MM_OPT in your environment and try using ./configure --with-perl-bindings=""'; \ - echo ""; \ - fi ) - -buildperl/Makefile.PL: .perl-directory-stamp $(top_builddir)/config.status - -.perl-directory-stamp: - if test ! -d buildperl; then \ - mkdir -p buildperl/Collectd/Plugins; \ - cp $(srcdir)/perl/lib/Collectd.pm buildperl/; \ - cp $(srcdir)/perl/Makefile.PL buildperl/; \ - cp $(srcdir)/perl/lib/Collectd/Unixsock.pm buildperl/Collectd/; \ - cp $(srcdir)/perl/lib/Collectd/Plugins/OpenVZ.pm buildperl/Collectd/Plugins/; \ - fi - touch $@ - -.PHONY: perl - diff --git a/bindings/java/Makefile.am b/bindings/java/Makefile.am deleted file mode 100644 index f8e936a8af..0000000000 --- a/bindings/java/Makefile.am +++ /dev/null @@ -1,48 +0,0 @@ -EXTRA_DIST = org/collectd/api/CollectdConfigInterface.java \ - org/collectd/api/CollectdFlushInterface.java \ - org/collectd/api/CollectdInitInterface.java \ - org/collectd/api/Collectd.java \ - org/collectd/api/CollectdLogInterface.java \ - org/collectd/api/CollectdMatchFactoryInterface.java \ - org/collectd/api/CollectdMatchInterface.java \ - org/collectd/api/CollectdNotificationInterface.java \ - org/collectd/api/CollectdReadInterface.java \ - org/collectd/api/CollectdShutdownInterface.java \ - org/collectd/api/CollectdTargetFactoryInterface.java \ - org/collectd/api/CollectdTargetInterface.java \ - org/collectd/api/CollectdWriteInterface.java \ - org/collectd/api/DataSet.java \ - org/collectd/api/DataSource.java \ - org/collectd/api/Notification.java \ - org/collectd/api/OConfigItem.java \ - org/collectd/api/OConfigValue.java \ - org/collectd/api/PluginData.java \ - org/collectd/api/ValueList.java \ - org/collectd/java/GenericJMXConfConnection.java \ - org/collectd/java/GenericJMXConfMBean.java \ - org/collectd/java/GenericJMXConfValue.java \ - org/collectd/java/GenericJMX.java \ - org/collectd/java/JMXMemory.java - -java-build-stamp: org/collectd/api/*.java org/collectd/java/*.java - $(JAVAC) -d "." "$(srcdir)/org/collectd/api"/*.java - $(JAVAC) -d "." "$(srcdir)/org/collectd/java"/*.java - mkdir -p .libs - $(JAR) cf .libs/collectd-api.jar "org/collectd/api"/*.class - $(JAR) cf .libs/generic-jmx.jar "org/collectd/java"/*.class - touch "$@" - -all-local: java-build-stamp - -install-exec-local: java-build-stamp - mkdir -p "$(DESTDIR)$(pkgdatadir)/java" - $(INSTALL) -m 644 .libs/collectd-api.jar \ - "$(DESTDIR)$(pkgdatadir)/java" - $(INSTALL) -m 644 .libs/generic-jmx.jar \ - "$(DESTDIR)$(pkgdatadir)/java" - -clean-local: - rm -f "org/collectd/api"/*.class - rm -f "org/collectd/java"/*.class - rm -f .libs - rm -f "java-build-stamp" diff --git a/bindings/java/org/collectd/api/Collectd.java b/bindings/java/org/collectd/api/Collectd.java index 84e6592658..450f87ae8f 100644 --- a/bindings/java/org/collectd/api/Collectd.java +++ b/bindings/java/org/collectd/api/Collectd.java @@ -1,22 +1,27 @@ -/* - * collectd/java - org/collectd/api/Collectd.java - * Copyright (C) 2009 Florian octo Forster +/** + * collectd - bindings/java/org/collectd/api/Collectd.java + * Copyright (C) 2009 Florian octo Forster * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; only version 2 of the License is applicable. + * 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: * - * 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. + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. * - * 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 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. * * Authors: - * Florian octo Forster + * Florian octo Forster */ package org.collectd.api; @@ -28,7 +33,7 @@ * object of this class (in fact, you can't). Just call these functions * directly. * - * @author Florian Forster <octo at verplant.org> + * @author Florian Forster <octo at collectd.org> */ public class Collectd { @@ -251,6 +256,13 @@ native public static int registerTarget (String name, */ native private static void log (int severity, String message); + /** + * Yield contents of collectd/src/collectd.h:hostname_g + * + * @return The hostname as set in the collectd configuration. + */ + native public static java.lang.String getHostname (); + /** * Prints an error message. */ diff --git a/bindings/java/org/collectd/api/CollectdConfigInterface.java b/bindings/java/org/collectd/api/CollectdConfigInterface.java index 060f9442fb..4b66097801 100644 --- a/bindings/java/org/collectd/api/CollectdConfigInterface.java +++ b/bindings/java/org/collectd/api/CollectdConfigInterface.java @@ -1,22 +1,27 @@ -/* - * collectd/java - org/collectd/api/CollectdConfigInterface.java - * Copyright (C) 2009 Florian octo Forster +/** + * collectd - bindings/java/org/collectd/api/CollectdConfigInterface.java + * Copyright (C) 2009 Florian octo Forster * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; only version 2 of the License is applicable. + * 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: * - * 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. + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. * - * 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 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. * * Authors: - * Florian octo Forster + * Florian octo Forster */ package org.collectd.api; @@ -24,7 +29,7 @@ /** * Interface for objects implementing a config method. * - * @author Florian Forster <octo at verplant.org> + * @author Florian Forster <octo at collectd.org> * @see Collectd#registerConfig(String, CollectdConfigInterface) */ public interface CollectdConfigInterface diff --git a/bindings/java/org/collectd/api/CollectdFlushInterface.java b/bindings/java/org/collectd/api/CollectdFlushInterface.java index 410c61c60e..ea7bd64f01 100644 --- a/bindings/java/org/collectd/api/CollectdFlushInterface.java +++ b/bindings/java/org/collectd/api/CollectdFlushInterface.java @@ -1,22 +1,27 @@ -/* - * collectd/java - org/collectd/api/CollectdFlushInterface.java - * Copyright (C) 2009 Florian octo Forster +/** + * collectd - bindings/java/org/collectd/api/CollectdFlushInterface.java + * Copyright (C) 2009 Florian octo Forster * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; only version 2 of the License is applicable. + * 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: * - * 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. + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. * - * 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 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. * * Authors: - * Florian octo Forster + * Florian octo Forster */ package org.collectd.api; @@ -24,7 +29,7 @@ /** * Interface for objects implementing a flush method. * - * @author Florian Forster <octo at verplant.org> + * @author Florian Forster <octo at collectd.org> * @see Collectd#registerFlush */ public interface CollectdFlushInterface diff --git a/bindings/java/org/collectd/api/CollectdInitInterface.java b/bindings/java/org/collectd/api/CollectdInitInterface.java index fbfd3061cf..545f41eb26 100644 --- a/bindings/java/org/collectd/api/CollectdInitInterface.java +++ b/bindings/java/org/collectd/api/CollectdInitInterface.java @@ -1,22 +1,27 @@ -/* - * collectd/java - org/collectd/api/CollectdInitInterface.java - * Copyright (C) 2009 Florian octo Forster +/** + * collectd - bindings/java/org/collectd/api/CollectdInitInterface.java + * Copyright (C) 2009 Florian octo Forster * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; only version 2 of the License is applicable. + * 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: * - * 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. + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. * - * 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 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. * * Authors: - * Florian octo Forster + * Florian octo Forster */ package org.collectd.api; @@ -24,7 +29,7 @@ /** * Interface for objects implementing an init method. * - * @author Florian Forster <octo at verplant.org> + * @author Florian Forster <octo at collectd.org> * @see Collectd#registerInit */ public interface CollectdInitInterface diff --git a/bindings/java/org/collectd/api/CollectdLogInterface.java b/bindings/java/org/collectd/api/CollectdLogInterface.java index ba0350a243..a516df5463 100644 --- a/bindings/java/org/collectd/api/CollectdLogInterface.java +++ b/bindings/java/org/collectd/api/CollectdLogInterface.java @@ -1,22 +1,27 @@ -/* - * collectd/java - org/collectd/api/CollectdLogInterface.java - * Copyright (C) 2009 Florian octo Forster +/** + * collectd - bindings/java/org/collectd/api/CollectdLogInterface.java + * Copyright (C) 2009 Florian octo Forster * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; only version 2 of the License is applicable. + * 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: * - * 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. + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. * - * 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 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. * * Authors: - * Florian octo Forster + * Florian octo Forster */ package org.collectd.api; @@ -24,7 +29,7 @@ /** * Interface for objects implementing a log method. * - * @author Florian Forster <octo at verplant.org> + * @author Florian Forster <octo at collectd.org> * @see Collectd#registerLog */ public interface CollectdLogInterface diff --git a/bindings/java/org/collectd/api/CollectdMatchFactoryInterface.java b/bindings/java/org/collectd/api/CollectdMatchFactoryInterface.java index 7b1c71a470..b19c77918e 100644 --- a/bindings/java/org/collectd/api/CollectdMatchFactoryInterface.java +++ b/bindings/java/org/collectd/api/CollectdMatchFactoryInterface.java @@ -1,22 +1,27 @@ -/* - * collectd/java - org/collectd/api/CollectdMatchFactoryInterface.java - * Copyright (C) 2009 Florian octo Forster +/** + * collectd - bindings/java/org/collectd/api/CollectdMatchFactoryInterface.java + * Copyright (C) 2009 Florian octo Forster * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; only version 2 of the License is applicable. + * 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: * - * 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. + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. * - * 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 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. * * Authors: - * Florian octo Forster + * Florian octo Forster */ package org.collectd.api; @@ -27,7 +32,7 @@ * Objects implementing this interface are used to create objects implementing * the CollectdMatchInterface interface. * - * @author Florian Forster <octo at verplant.org> + * @author Florian Forster <octo at collectd.org> * @see CollectdMatchInterface * @see Collectd#registerMatch */ diff --git a/bindings/java/org/collectd/api/CollectdMatchInterface.java b/bindings/java/org/collectd/api/CollectdMatchInterface.java index cc8a99e6e0..20a03d2aab 100644 --- a/bindings/java/org/collectd/api/CollectdMatchInterface.java +++ b/bindings/java/org/collectd/api/CollectdMatchInterface.java @@ -1,22 +1,27 @@ -/* - * collectd/java - org/collectd/api/CollectdMatchInterface.java - * Copyright (C) 2009 Florian octo Forster +/** + * collectd - bindings/java/org/collectd/api/CollectdMatchInterface.java + * Copyright (C) 2009 Florian octo Forster * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; only version 2 of the License is applicable. + * 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: * - * 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. + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. * - * 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 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. * * Authors: - * Florian octo Forster + * Florian octo Forster */ package org.collectd.api; @@ -28,7 +33,7 @@ * CollectdMatchFactoryInterface interface. They are not instantiated by the * daemon directly! * - * @author Florian Forster <octo at verplant.org> + * @author Florian Forster <octo at collectd.org> * @see CollectdMatchFactoryInterface * @see Collectd#registerMatch */ diff --git a/bindings/java/org/collectd/api/CollectdNotificationInterface.java b/bindings/java/org/collectd/api/CollectdNotificationInterface.java index d278fe21a4..ddff6cd93d 100644 --- a/bindings/java/org/collectd/api/CollectdNotificationInterface.java +++ b/bindings/java/org/collectd/api/CollectdNotificationInterface.java @@ -1,22 +1,27 @@ -/* - * collectd/java - org/collectd/api/CollectdNotificationInterface.java - * Copyright (C) 2009 Florian octo Forster +/** + * collectd - bindings/java/org/collectd/api/CollectdNotificationInterface.java + * Copyright (C) 2009 Florian octo Forster * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; only version 2 of the License is applicable. + * 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: * - * 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. + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. * - * 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 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. * * Authors: - * Florian octo Forster + * Florian octo Forster */ package org.collectd.api; @@ -24,7 +29,7 @@ /** * Interface for objects implementing a notification method. * - * @author Florian Forster <octo at verplant.org> + * @author Florian Forster <octo at collectd.org> * @see Collectd#registerNotification */ public interface CollectdNotificationInterface diff --git a/bindings/java/org/collectd/api/CollectdReadInterface.java b/bindings/java/org/collectd/api/CollectdReadInterface.java index 67f1898ba2..996841aad7 100644 --- a/bindings/java/org/collectd/api/CollectdReadInterface.java +++ b/bindings/java/org/collectd/api/CollectdReadInterface.java @@ -1,22 +1,27 @@ -/* - * collectd/java - org/collectd/api/CollectdReadInterface.java - * Copyright (C) 2009 Florian octo Forster +/** + * collectd - bindings/java/org/collectd/api/CollectdReadInterface.java + * Copyright (C) 2009 Florian octo Forster * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; only version 2 of the License is applicable. + * 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: * - * 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. + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. * - * 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 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. * * Authors: - * Florian octo Forster + * Florian octo Forster */ package org.collectd.api; @@ -27,7 +32,7 @@ * Objects implementing this interface can be registered with the daemon. Their * read method is then called periodically to acquire and submit values. * - * @author Florian Forster <octo at verplant.org> + * @author Florian Forster <octo at collectd.org> * @see Collectd#registerRead */ public interface CollectdReadInterface diff --git a/bindings/java/org/collectd/api/CollectdShutdownInterface.java b/bindings/java/org/collectd/api/CollectdShutdownInterface.java index 108c54ed0c..e496d3c2ca 100644 --- a/bindings/java/org/collectd/api/CollectdShutdownInterface.java +++ b/bindings/java/org/collectd/api/CollectdShutdownInterface.java @@ -1,22 +1,27 @@ -/* - * collectd/java - org/collectd/api/CollectdShutdownInterface.java - * Copyright (C) 2009 Florian octo Forster +/** + * collectd - bindings/java/org/collectd/api/CollectdShutdownInterface.java + * Copyright (C) 2009 Florian octo Forster * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; only version 2 of the License is applicable. + * 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: * - * 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. + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. * - * 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 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. * * Authors: - * Florian octo Forster + * Florian octo Forster */ package org.collectd.api; @@ -24,7 +29,7 @@ /** * Interface for objects implementing a shutdown method. * - * @author Florian Forster <octo at verplant.org> + * @author Florian Forster <octo at collectd.org> * @see Collectd#registerShutdown */ public interface CollectdShutdownInterface diff --git a/bindings/java/org/collectd/api/CollectdTargetFactoryInterface.java b/bindings/java/org/collectd/api/CollectdTargetFactoryInterface.java index 65f6181806..b4c2321c22 100644 --- a/bindings/java/org/collectd/api/CollectdTargetFactoryInterface.java +++ b/bindings/java/org/collectd/api/CollectdTargetFactoryInterface.java @@ -1,22 +1,27 @@ -/* - * collectd/java - org/collectd/api/CollectdTargetFactoryInterface.java - * Copyright (C) 2009 Florian octo Forster +/** + * collectd - bindings/java/org/collectd/api/CollectdTargetFactoryInterface.java + * Copyright (C) 2009 Florian octo Forster * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; only version 2 of the License is applicable. + * 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: * - * 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. + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. * - * 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 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. * * Authors: - * Florian octo Forster + * Florian octo Forster */ package org.collectd.api; @@ -27,7 +32,7 @@ * Objects implementing this interface are used to create objects implementing * the CollectdTargetInterface interface. * - * @author Florian Forster <octo at verplant.org> + * @author Florian Forster <octo at collectd.org> * @see CollectdTargetInterface * @see Collectd#registerTarget */ diff --git a/bindings/java/org/collectd/api/CollectdTargetInterface.java b/bindings/java/org/collectd/api/CollectdTargetInterface.java index 74412a3204..1f5ece1672 100644 --- a/bindings/java/org/collectd/api/CollectdTargetInterface.java +++ b/bindings/java/org/collectd/api/CollectdTargetInterface.java @@ -1,22 +1,27 @@ -/* - * collectd/java - org/collectd/api/CollectdTargetInterface.java - * Copyright (C) 2009 Florian octo Forster +/** + * collectd - bindings/java/org/collectd/api/CollectdTargetInterface.java + * Copyright (C) 2009 Florian octo Forster * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; only version 2 of the License is applicable. + * 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: * - * 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. + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. * - * 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 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. * * Authors: - * Florian octo Forster + * Florian octo Forster */ package org.collectd.api; @@ -28,7 +33,7 @@ * CollectdTargetFactoryInterface interface. They are not instantiated by the * daemon directly! * - * @author Florian Forster <octo at verplant.org> + * @author Florian Forster <octo at collectd.org> * @see CollectdTargetFactoryInterface * @see Collectd#registerTarget */ diff --git a/bindings/java/org/collectd/api/CollectdWriteInterface.java b/bindings/java/org/collectd/api/CollectdWriteInterface.java index 28e0230b68..f95169a606 100644 --- a/bindings/java/org/collectd/api/CollectdWriteInterface.java +++ b/bindings/java/org/collectd/api/CollectdWriteInterface.java @@ -1,22 +1,27 @@ -/* - * collectd/java - org/collectd/api/CollectdWriteInterface.java - * Copyright (C) 2009 Florian octo Forster +/** + * collectd - bindings/java/org/collectd/api/CollectdWriteInterface.java + * Copyright (C) 2009 Florian octo Forster * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; only version 2 of the License is applicable. + * 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: * - * 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. + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. * - * 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 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. * * Authors: - * Florian octo Forster + * Florian octo Forster */ package org.collectd.api; @@ -24,7 +29,7 @@ /** * Interface for objects implementing a write method. * - * @author Florian Forster <octo at verplant.org> + * @author Florian Forster <octo at collectd.org> * @see Collectd#registerWrite */ public interface CollectdWriteInterface diff --git a/bindings/java/org/collectd/api/DataSet.java b/bindings/java/org/collectd/api/DataSet.java index 9823073028..3cba5eb043 100644 --- a/bindings/java/org/collectd/api/DataSet.java +++ b/bindings/java/org/collectd/api/DataSet.java @@ -1,22 +1,27 @@ -/* - * collectd/java - org/collectd/api/OConfigItem.java - * Copyright (C) 2009 Florian octo Forster +/** + * collectd - bindings/java/org/collectd/api/DataSet.java + * Copyright (C) 2009 Florian octo Forster * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; only version 2 of the License is applicable. + * 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: * - * 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. + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. * - * 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 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. * * Authors: - * Florian octo Forster + * Florian octo Forster */ package org.collectd.api; @@ -27,7 +32,7 @@ /** * Java representation of collectd/src/plugin.h:data_set_t structure. * - * @author Florian Forster <octo at verplant.org> + * @author Florian Forster <octo at collectd.org> */ public class DataSet { diff --git a/bindings/java/org/collectd/api/OConfigItem.java b/bindings/java/org/collectd/api/OConfigItem.java index 4c6a778d0c..08d8b70886 100644 --- a/bindings/java/org/collectd/api/OConfigItem.java +++ b/bindings/java/org/collectd/api/OConfigItem.java @@ -1,22 +1,27 @@ -/* - * collectd/java - org/collectd/api/OConfigItem.java - * Copyright (C) 2009 Florian octo Forster +/** + * collectd - bindings/java/org/collectd/api/OConfigItem.java + * Copyright (C) 2009 Florian octo Forster * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; only version 2 of the License is applicable. + * 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: * - * 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. + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. * - * 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 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. * * Authors: - * Florian octo Forster + * Florian octo Forster */ package org.collectd.api; @@ -27,7 +32,7 @@ /** * Java representation of collectd/src/liboconfig/oconfig.h:oconfig_item_t structure. * - * @author Florian Forster <octo at verplant.org> + * @author Florian Forster <octo at collectd.org> */ public class OConfigItem { diff --git a/bindings/java/org/collectd/api/OConfigValue.java b/bindings/java/org/collectd/api/OConfigValue.java index 1ebafff7a0..0a33773a76 100644 --- a/bindings/java/org/collectd/api/OConfigValue.java +++ b/bindings/java/org/collectd/api/OConfigValue.java @@ -1,22 +1,27 @@ -/* - * collectd/java - org/collectd/api/OConfigValue.java - * Copyright (C) 2009 Florian octo Forster +/** + * collectd - bindings/java/org/collectd/api/OConfigValue.java + * Copyright (C) 2009 Florian octo Forster * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; only version 2 of the License is applicable. + * 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: * - * 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. + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. * - * 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 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. * * Authors: - * Florian octo Forster + * Florian octo Forster */ package org.collectd.api; @@ -24,7 +29,7 @@ /** * Java representation of collectd/src/liboconfig/oconfig.h:oconfig_value_t structure. * - * @author Florian Forster <octo at verplant.org> + * @author Florian Forster <octo at collectd.org> */ public class OConfigValue { diff --git a/bindings/java/org/collectd/java/GenericJMX.java b/bindings/java/org/collectd/java/GenericJMX.java index 319615c96f..a678d5fb9f 100644 --- a/bindings/java/org/collectd/java/GenericJMX.java +++ b/bindings/java/org/collectd/java/GenericJMX.java @@ -1,22 +1,27 @@ -/* - * collectd/java - org/collectd/java/GenericJMX.java - * Copyright (C) 2009 Florian octo Forster +/** + * collectd - bindings/java/org/collectd/java/GenericJMX.java + * Copyright (C) 2009 Florian octo Forster * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; only version 2 of the License is applicable. + * 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: * - * 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. + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. * - * 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 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. * * Authors: - * Florian octo Forster + * Florian octo Forster */ package org.collectd.java; diff --git a/bindings/java/org/collectd/java/GenericJMXConfConnection.java b/bindings/java/org/collectd/java/GenericJMXConfConnection.java index 7fad08f922..887c289562 100644 --- a/bindings/java/org/collectd/java/GenericJMXConfConnection.java +++ b/bindings/java/org/collectd/java/GenericJMXConfConnection.java @@ -1,19 +1,24 @@ -/* - * collectd/java - org/collectd/java/GenericJMXConfConnection.java +/** + * collectd - bindings/java/org/collectd/java/GenericJMXConfConnection.java * Copyright (C) 2009-2012 Florian octo Forster * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; only version 2 of the License is applicable. + * 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: * - * 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. + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. * - * 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 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. * * Authors: * Florian octo Forster @@ -30,8 +35,6 @@ import java.net.UnknownHostException; import javax.management.MBeanServerConnection; -import javax.management.ObjectName; -import javax.management.MalformedObjectNameException; import javax.management.remote.JMXServiceURL; import javax.management.remote.JMXConnector; @@ -49,7 +52,8 @@ class GenericJMXConfConnection private String _host = null; private String _instance_prefix = null; private String _service_url = null; - private MBeanServerConnection _jmx_connection = null; + private JMXConnector _jmx_connector = null; + private MBeanServerConnection _mbean_connection = null; private List _mbeans = null; /* @@ -86,65 +90,77 @@ private String getHost () /* {{{ */ return (this._host); } - try - { - InetAddress localHost = InetAddress.getLocalHost(); - return (localHost.getHostName ()); - } - catch (UnknownHostException e) - { - return ("localhost"); - } + return Collectd.getHostname(); } /* }}} String getHost */ -private void connect () /* {{{ */ -{ - JMXServiceURL service_url; - JMXConnector connector; - Map environment; + private void connect () /* {{{ */ + { + JMXServiceURL service_url; + Map environment; - if (_jmx_connection != null) - return; + // already connected + if (this._jmx_connector != null) { + return; + } - environment = null; - if (this._password != null) - { - String[] credentials; + environment = null; + if (this._password != null) + { + String[] credentials; - if (this._username == null) - this._username = new String ("monitorRole"); + if (this._username == null) + this._username = new String ("monitorRole"); - credentials = new String[] { this._username, this._password }; + credentials = new String[] { this._username, this._password }; - environment = new HashMap (); - environment.put (JMXConnector.CREDENTIALS, credentials); - } + environment = new HashMap (); + environment.put (JMXConnector.CREDENTIALS, credentials); + environment.put (JMXConnectorFactory.PROTOCOL_PROVIDER_CLASS_LOADER, this.getClass().getClassLoader()); + } - try - { - service_url = new JMXServiceURL (this._service_url); - connector = JMXConnectorFactory.connect (service_url, environment); - _jmx_connection = connector.getMBeanServerConnection (); - } - catch (Exception e) + try + { + service_url = new JMXServiceURL (this._service_url); + this._jmx_connector = JMXConnectorFactory.connect (service_url, environment); + this._mbean_connection = _jmx_connector.getMBeanServerConnection (); + } + catch (Exception e) + { + Collectd.logError ("GenericJMXConfConnection: " + + "Creating MBean server connection failed: " + e); + disconnect (); + return; + } + } /* }}} void connect */ + + private void disconnect () /* {{{ */ { - Collectd.logError ("GenericJMXConfConnection: " - + "Creating MBean server connection failed: " + e); - return; - } -} /* }}} void connect */ + try + { + if (this._jmx_connector != null) { + this._jmx_connector.close(); + } + } + catch (Exception e) + { + // It's fine if close throws an exception + } -/* - * public methods - * - * - * Host "tomcat0.mycompany" - * ServiceURL "service:jmx:rmi:///jndi/rmi://localhost:17264/jmxrmi" - * Collect "java.lang:type=GarbageCollector,name=Copy" - * Collect "java.lang:type=Memory" - * - * - */ + this._jmx_connector = null; + this._mbean_connection = null; + } /* }}} void disconnect */ + + /* + * public methods + * + * + * Host "tomcat0.mycompany" + * ServiceURL "service:jmx:rmi:///jndi/rmi://localhost:17264/jmxrmi" + * Collect "java.lang:type=GarbageCollector,name=Copy" + * Collect "java.lang:type=Memory" + * + * + */ public GenericJMXConfConnection (OConfigItem ci) /* {{{ */ throws IllegalArgumentException { @@ -221,9 +237,10 @@ public void query () /* {{{ */ { PluginData pd; + // try to connect connect (); - if (this._jmx_connection == null) + if (this._mbean_connection == null) return; Collectd.logDebug ("GenericJMXConfConnection.query: " @@ -238,11 +255,11 @@ public void query () /* {{{ */ { int status; - status = this._mbeans.get (i).query (this._jmx_connection, pd, + status = this._mbeans.get (i).query (this._mbean_connection, pd, this._instance_prefix); if (status != 0) { - this._jmx_connection = null; + disconnect (); return; } } /* for */ diff --git a/bindings/java/org/collectd/java/GenericJMXConfMBean.java b/bindings/java/org/collectd/java/GenericJMXConfMBean.java index b1fbfb3ec1..64a53acb0f 100644 --- a/bindings/java/org/collectd/java/GenericJMXConfMBean.java +++ b/bindings/java/org/collectd/java/GenericJMXConfMBean.java @@ -1,22 +1,27 @@ -/* - * collectd/java - org/collectd/java/GenericJMXConfMBean.java +/** + * collectd - bindings/java/org/collectd/java/GenericJMXConfMBean.java * Copyright (C) 2009,2010 Florian octo Forster * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; only version 2 of the License is applicable. + * 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: * - * 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. + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. * - * 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 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. * * Authors: - * Florian octo Forster + * Florian octo Forster */ package org.collectd.java; diff --git a/bindings/java/org/collectd/java/GenericJMXConfValue.java b/bindings/java/org/collectd/java/GenericJMXConfValue.java index 9fb0fc2eda..2827daa58a 100644 --- a/bindings/java/org/collectd/java/GenericJMXConfValue.java +++ b/bindings/java/org/collectd/java/GenericJMXConfValue.java @@ -1,29 +1,37 @@ -/* - * collectd/java - org/collectd/java/GenericJMXConfValue.java - * Copyright (C) 2009 Florian octo Forster +/** + * collectd - bindings/java/org/collectd/java/GenericJMXConfValue.java + * Copyright (C) 2009 Florian octo Forster * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; only version 2 of the License is applicable. + * 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: * - * 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. + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. * - * 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 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. * * Authors: - * Florian octo Forster + * Florian octo Forster */ package org.collectd.java; import java.util.Arrays; import java.util.List; +import java.util.Collection; import java.util.Set; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.atomic.AtomicLong; import java.util.Iterator; import java.util.ArrayList; @@ -34,6 +42,7 @@ import javax.management.ObjectName; import javax.management.openmbean.OpenType; import javax.management.openmbean.CompositeData; +import javax.management.openmbean.TabularData; import javax.management.openmbean.InvalidKeyException; import org.collectd.api.Collectd; @@ -56,71 +65,64 @@ * * @see GenericJMXConfMBean */ -class GenericJMXConfValue -{ - private String _ds_name; - private DataSet _ds; - private List _attributes; - private String _instance_prefix; - private List _instance_from; - private boolean _is_table; +class GenericJMXConfValue { +private + String _ds_name; +private + DataSet _ds; +private + List _attributes; +private + String _instance_prefix; +private + List _instance_from; +private + String _plugin_name; +private + boolean _is_table; /** * Converts a generic (OpenType) object to a number. * * Returns null if a conversion is not possible or not implemented. */ - private Number genericObjectToNumber (Object obj, int ds_type) /* {{{ */ +private + Number genericObjectToNumber(Object obj, int ds_type) /* {{{ */ { - if (obj instanceof String) - { - String str = (String) obj; - - try - { + if (obj instanceof String) { + String str = (String)obj; + + try { if (ds_type == DataSource.TYPE_GAUGE) - return (new Double (str)); + return (new Double(str)); else - return (new Long (str)); - } - catch (NumberFormatException e) - { + return (new Long(str)); + } catch (NumberFormatException e) { return (null); } + } else if (obj instanceof Byte) { + return (new Byte((Byte)obj)); + } else if (obj instanceof Short) { + return (new Short((Short)obj)); + } else if (obj instanceof Integer) { + return (new Integer((Integer)obj)); + } else if (obj instanceof Long) { + return (new Long((Long)obj)); + } else if (obj instanceof Float) { + return (new Float((Float)obj)); + } else if (obj instanceof Double) { + return (new Double((Double)obj)); + } else if (obj instanceof BigDecimal) { + return (BigDecimal.ZERO.add((BigDecimal)obj)); + } else if (obj instanceof BigInteger) { + return (BigInteger.ZERO.add((BigInteger)obj)); + } else if (obj instanceof AtomicInteger) { + return (new Integer(((AtomicInteger)obj).get())); + } else if (obj instanceof AtomicLong) { + return (new Long(((AtomicLong)obj).get())); + } else if (obj instanceof Boolean) { + return (Boolean)obj ? 1 : 0; } - else if (obj instanceof Byte) - { - return (new Byte ((Byte) obj)); - } - else if (obj instanceof Short) - { - return (new Short ((Short) obj)); - } - else if (obj instanceof Integer) - { - return (new Integer ((Integer) obj)); - } - else if (obj instanceof Long) - { - return (new Long ((Long) obj)); - } - else if (obj instanceof Float) - { - return (new Float ((Float) obj)); - } - else if (obj instanceof Double) - { - return (new Double ((Double) obj)); - } - else if (obj instanceof BigDecimal) - { - return (BigDecimal.ZERO.add ((BigDecimal) obj)); - } - else if (obj instanceof BigInteger) - { - return (BigInteger.ZERO.add ((BigInteger) obj)); - } - return (null); } /* }}} Number genericObjectToNumber */ @@ -129,21 +131,21 @@ else if (obj instanceof BigInteger) * * Returns null if one or more objects could not be converted. */ - private List genericListToNumber (List objects) /* {{{ */ +private + List genericListToNumber(List objects) /* {{{ */ { - List ret = new ArrayList (); - List dsrc = this._ds.getDataSources (); + List ret = new ArrayList(); + List dsrc = this._ds.getDataSources(); - assert (objects.size () == dsrc.size ()); + assert(objects.size() == dsrc.size()); - for (int i = 0; i < objects.size (); i++) - { + for (int i = 0; i < objects.size(); i++) { Number n; - n = genericObjectToNumber (objects.get (i), dsrc.get (i).getType ()); + n = genericObjectToNumber(objects.get(i), dsrc.get(i).getType()); if (n == null) return (null); - ret.add (n); + ret.add(n); } return (ret); @@ -157,280 +159,293 @@ private List genericListToNumber (List objects) /* {{{ */ * CompositeData doesn't have the specified key or one returned * object cannot converted to a number then the function will return null. */ - private List genericCompositeToNumber (List cdlist, /* {{{ */ - String key) - { - List objects = new ArrayList (); +private + List genericCompositeToNumber(List cdlist, /* {{{ */ + String key) { + List objects = new ArrayList(); - for (int i = 0; i < cdlist.size (); i++) - { + for (int i = 0; i < cdlist.size(); i++) { CompositeData cd; Object value; - cd = cdlist.get (i); - try - { - value = cd.get (key); - } - catch (InvalidKeyException e) - { + cd = cdlist.get(i); + try { + value = cd.get(key); + } catch (InvalidKeyException e) { return (null); } - objects.add (value); + objects.add(value); } - return (genericListToNumber (objects)); + return (genericListToNumber(objects)); } /* }}} List genericCompositeToNumber */ - private void submitTable (List objects, ValueList vl, /* {{{ */ - String instancePrefix) - { +private + void submitTable(List objects, ValueList vl, /* {{{ */ + String instancePrefix) { List cdlist; Set keySet = null; Iterator keyIter; - cdlist = new ArrayList (); - for (int i = 0; i < objects.size (); i++) - { + cdlist = new ArrayList(); + for (int i = 0; i < objects.size(); i++) { Object obj; - obj = objects.get (i); - if (obj instanceof CompositeData) - { + obj = objects.get(i); + if (obj instanceof CompositeData) { CompositeData cd; - cd = (CompositeData) obj; + cd = (CompositeData)obj; if (i == 0) - keySet = cd.getCompositeType ().keySet (); - - cdlist.add (cd); - } - else - { - Collectd.logError ("GenericJMXConfValue: At least one of the " - + "attributes was not of type `CompositeData', as required " - + "when table is set to `true'."); + keySet = cd.getCompositeType().keySet(); + + cdlist.add(cd); + } else { + Collectd.logError( + "GenericJMXConfValue: At least one of the " + + "attributes was not of type `CompositeData', as required " + + "when table is set to `true'."); return; } } - assert (keySet != null); + assert(keySet != null); - keyIter = keySet.iterator (); - while (keyIter.hasNext ()) - { + keyIter = keySet.iterator(); + while (keyIter.hasNext()) { String key; List values; - key = keyIter.next (); - values = genericCompositeToNumber (cdlist, key); - if (values == null) - { - Collectd.logError ("GenericJMXConfValue: Cannot build a list of " - + "numbers for key " + key + ". Most likely not all attributes " - + "have this key."); + key = keyIter.next(); + values = genericCompositeToNumber(cdlist, key); + if (values == null) { + Collectd.logError("GenericJMXConfValue: Cannot build a list of " + + "numbers for key " + key + + ". Most likely not all attributes " + + "have this key."); continue; } if (instancePrefix == null) - vl.setTypeInstance (key); + vl.setTypeInstance(key); else - vl.setTypeInstance (instancePrefix + key); - vl.setValues (values); + vl.setTypeInstance(instancePrefix + key); + vl.setValues(values); - Collectd.dispatchValues (vl); + Collectd.dispatchValues(vl); } } /* }}} void submitTable */ - private void submitScalar (List objects, ValueList vl, /* {{{ */ - String instancePrefix) - { +private + void submitScalar(List objects, ValueList vl, /* {{{ */ + String instancePrefix) { List values; - values = genericListToNumber (objects); - if (values == null) - { - Collectd.logError ("GenericJMXConfValue: Cannot convert list of " - + "objects to numbers."); + values = genericListToNumber(objects); + if (values == null) { + Collectd.logError("GenericJMXConfValue: Cannot convert list of " + + "objects to numbers."); return; } if (instancePrefix == null) - vl.setTypeInstance (""); + vl.setTypeInstance(""); else - vl.setTypeInstance (instancePrefix); - vl.setValues (values); + vl.setTypeInstance(instancePrefix); + vl.setValues(values); - Collectd.dispatchValues (vl); + Collectd.dispatchValues(vl); } /* }}} void submitScalar */ - private Object queryAttributeRecursive (CompositeData parent, /* {{{ */ - List attrName) - { +private + Object queryAttributeRecursive(CompositeData parent, /* {{{ */ + List attrName) { String key; Object value; - key = attrName.remove (0); + key = attrName.remove(0); - try - { - value = parent.get (key); - } - catch (InvalidKeyException e) - { + try { + value = parent.get(key); + } catch (InvalidKeyException e) { return (null); } - if (attrName.size () == 0) - { + if (attrName.size() == 0) { return (value); + } else { + if (value instanceof CompositeData) + return (queryAttributeRecursive((CompositeData)value, attrName)); + else if (value instanceof TabularData) + return (queryAttributeRecursive((TabularData)value, attrName)); + else + return (null); } - else - { + } /* }}} queryAttributeRecursive */ + +private + Object queryAttributeRecursive(TabularData parent, /* {{{ */ + List attrName) { + String key; + Object value = null; + + key = attrName.remove(0); + + @SuppressWarnings("unchecked") Collection table = + (Collection)parent.values(); + for (CompositeData compositeData : table) { + if (key.equals(compositeData.get("key"))) { + value = compositeData.get("value"); + } + } + if (null == value) { + return (null); + } + + if (attrName.size() == 0) { + return (value); + } else { if (value instanceof CompositeData) - return (queryAttributeRecursive ((CompositeData) value, attrName)); + return (queryAttributeRecursive((CompositeData)value, attrName)); + else if (value instanceof TabularData) + return (queryAttributeRecursive((TabularData)value, attrName)); else return (null); } } /* }}} queryAttributeRecursive */ - private Object queryAttribute (MBeanServerConnection conn, /* {{{ */ - ObjectName objName, String attrName) - { +private + Object queryAttribute(MBeanServerConnection conn, /* {{{ */ + ObjectName objName, String attrName) { List attrNameList; String key; Object value; String[] attrNameArray; - attrNameList = new ArrayList (); + attrNameList = new ArrayList(); - attrNameArray = attrName.split ("\\."); + attrNameArray = attrName.split("\\."); key = attrNameArray[0]; for (int i = 1; i < attrNameArray.length; i++) - attrNameList.add (attrNameArray[i]); - - try - { - try - { - value = conn.getAttribute (objName, key); + attrNameList.add(attrNameArray[i]); + + try { + try { + value = conn.getAttribute(objName, key); + } catch (javax.management.AttributeNotFoundException e) { + value = + conn.invoke(objName, key, /* args = */ null, /* types = */ null); } - catch (javax.management.AttributeNotFoundException e) - { - value = conn.invoke (objName, key, /* args = */ null, /* types = */ null); - } - } - catch (Exception e) - { - Collectd.logError ("GenericJMXConfValue.query: getAttribute failed: " - + e); + } catch (Exception e) { + Collectd.logError("GenericJMXConfValue.query: getAttribute failed: " + e); return (null); } - if (attrNameList.size () == 0) - { + if (attrNameList.size() == 0) { return (value); - } - else - { + } else { if (value instanceof CompositeData) - return (queryAttributeRecursive((CompositeData) value, attrNameList)); - else if (value instanceof OpenType) - { - OpenType ot = (OpenType) value; - Collectd.logNotice ("GenericJMXConfValue: Handling of OpenType \"" - + ot.getTypeName () + "\" is not yet implemented."); + return (queryAttributeRecursive((CompositeData)value, attrNameList)); + else if (value instanceof TabularData) + return (queryAttributeRecursive((TabularData)value, attrNameList)); + else if (value instanceof OpenType) { + OpenType ot = (OpenType)value; + Collectd.logNotice("GenericJMXConfValue: Handling of OpenType \"" + + ot.getTypeName() + "\" is not yet implemented."); return (null); - } - else - { - Collectd.logError ("GenericJMXConfValue: Received object of " - + "unknown class."); + } else { + Collectd.logError( + "GenericJMXConfValue: Received object of " + "unknown class. " + + attrName + " " + + ((value == null) ? "null" : value.getClass().getName())); return (null); } } } /* }}} Object queryAttribute */ - private String join (String separator, List list) /* {{{ */ +private + String join(String separator, List list) /* {{{ */ { StringBuffer sb; - sb = new StringBuffer (); + sb = new StringBuffer(); - for (int i = 0; i < list.size (); i++) - { + for (int i = 0; i < list.size(); i++) { if (i > 0) - sb.append ("-"); - sb.append (list.get (i)); + sb.append("-"); + sb.append(list.get(i)); } - return (sb.toString ()); + return (sb.toString()); } /* }}} String join */ - private String getConfigString (OConfigItem ci) /* {{{ */ +private + String getConfigString(OConfigItem ci) /* {{{ */ { List values; OConfigValue v; - values = ci.getValues (); - if (values.size () != 1) - { - Collectd.logError ("GenericJMXConfValue: The " + ci.getKey () - + " configuration option needs exactly one string argument."); + values = ci.getValues(); + if (values.size() != 1) { + Collectd.logError( + "GenericJMXConfValue: The " + ci.getKey() + + " configuration option needs exactly one string argument."); return (null); } - v = values.get (0); - if (v.getType () != OConfigValue.OCONFIG_TYPE_STRING) - { - Collectd.logError ("GenericJMXConfValue: The " + ci.getKey () - + " configuration option needs exactly one string argument."); + v = values.get(0); + if (v.getType() != OConfigValue.OCONFIG_TYPE_STRING) { + Collectd.logError( + "GenericJMXConfValue: The " + ci.getKey() + + " configuration option needs exactly one string argument."); return (null); } - return (v.getString ()); + return (v.getString()); } /* }}} String getConfigString */ - private Boolean getConfigBoolean (OConfigItem ci) /* {{{ */ +private + Boolean getConfigBoolean(OConfigItem ci) /* {{{ */ { List values; OConfigValue v; Boolean b; - values = ci.getValues (); - if (values.size () != 1) - { - Collectd.logError ("GenericJMXConfValue: The " + ci.getKey () - + " configuration option needs exactly one boolean argument."); + values = ci.getValues(); + if (values.size() != 1) { + Collectd.logError( + "GenericJMXConfValue: The " + ci.getKey() + + " configuration option needs exactly one boolean argument."); return (null); } - v = values.get (0); - if (v.getType () != OConfigValue.OCONFIG_TYPE_BOOLEAN) - { - Collectd.logError ("GenericJMXConfValue: The " + ci.getKey () - + " configuration option needs exactly one boolean argument."); + v = values.get(0); + if (v.getType() != OConfigValue.OCONFIG_TYPE_BOOLEAN) { + Collectd.logError( + "GenericJMXConfValue: The " + ci.getKey() + + " configuration option needs exactly one boolean argument."); return (null); } - return (new Boolean (v.getBoolean ())); + return (new Boolean(v.getBoolean())); } /* }}} String getConfigBoolean */ /** * Constructs a new value with the configured properties. */ - public GenericJMXConfValue (OConfigItem ci) /* {{{ */ - throws IllegalArgumentException - { +public + GenericJMXConfValue(OConfigItem ci) /* {{{ */ + throws IllegalArgumentException { List children; Iterator iter; this._ds_name = null; this._ds = null; - this._attributes = new ArrayList (); + this._attributes = new ArrayList(); this._instance_prefix = null; - this._instance_from = new ArrayList (); + this._instance_from = new ArrayList(); + this._plugin_name = null; this._is_table = false; /* @@ -444,51 +459,44 @@ public GenericJMXConfValue (OConfigItem ci) /* {{{ */ * InstancePrefix "heap-" * */ - children = ci.getChildren (); - iter = children.iterator (); - while (iter.hasNext ()) - { - OConfigItem child = iter.next (); - - if (child.getKey ().equalsIgnoreCase ("Type")) - { - String tmp = getConfigString (child); + children = ci.getChildren(); + iter = children.iterator(); + while (iter.hasNext()) { + OConfigItem child = iter.next(); + + if (child.getKey().equalsIgnoreCase("Type")) { + String tmp = getConfigString(child); if (tmp != null) this._ds_name = tmp; - } - else if (child.getKey ().equalsIgnoreCase ("Table")) - { - Boolean tmp = getConfigBoolean (child); + } else if (child.getKey().equalsIgnoreCase("Table")) { + Boolean tmp = getConfigBoolean(child); if (tmp != null) - this._is_table = tmp.booleanValue (); - } - else if (child.getKey ().equalsIgnoreCase ("Attribute")) - { - String tmp = getConfigString (child); + this._is_table = tmp.booleanValue(); + } else if (child.getKey().equalsIgnoreCase("Attribute")) { + String tmp = getConfigString(child); if (tmp != null) - this._attributes.add (tmp); - } - else if (child.getKey ().equalsIgnoreCase ("InstancePrefix")) - { - String tmp = getConfigString (child); + this._attributes.add(tmp); + } else if (child.getKey().equalsIgnoreCase("InstancePrefix")) { + String tmp = getConfigString(child); if (tmp != null) this._instance_prefix = tmp; - } - else if (child.getKey ().equalsIgnoreCase ("InstanceFrom")) - { - String tmp = getConfigString (child); + } else if (child.getKey().equalsIgnoreCase("InstanceFrom")) { + String tmp = getConfigString(child); if (tmp != null) - this._instance_from.add (tmp); - } - else - throw (new IllegalArgumentException ("Unknown option: " - + child.getKey ())); + this._instance_from.add(tmp); + } else if (child.getKey().equalsIgnoreCase("PluginName")) { + String tmp = getConfigString(child); + if (tmp != null) + this._plugin_name = tmp; + } else + throw( + new IllegalArgumentException("Unknown option: " + child.getKey())); } if (this._ds_name == null) - throw (new IllegalArgumentException ("No data set was defined.")); - else if (this._attributes.size () == 0) - throw (new IllegalArgumentException ("No attribute was defined.")); + throw(new IllegalArgumentException("No data set was defined.")); + else if (this._attributes.size() == 0) + throw(new IllegalArgumentException("No attribute was defined.")); } /* }}} GenericJMXConfValue (OConfigItem ci) */ /** @@ -500,94 +508,90 @@ else if (this._attributes.size () == 0) * @param pd Preset naming components. The members host, plugin and * plugin instance will be used. */ - public void query (MBeanServerConnection conn, ObjectName objName, /* {{{ */ - PluginData pd) - { +public + void query(MBeanServerConnection conn, ObjectName objName, /* {{{ */ + PluginData pd) { ValueList vl; List dsrc; List values; List instanceList; String instancePrefix; - if (this._ds == null) - { - this._ds = Collectd.getDS (this._ds_name); - if (this._ds == null) - { - Collectd.logError ("GenericJMXConfValue: Unknown type: " - + this._ds_name); + if (this._ds == null) { + this._ds = Collectd.getDS(this._ds_name); + if (this._ds == null) { + Collectd.logError("GenericJMXConfValue: Unknown type: " + + this._ds_name); return; } } - dsrc = this._ds.getDataSources (); - if (dsrc.size () != this._attributes.size ()) - { - Collectd.logError ("GenericJMXConfValue.query: The data set " - + this._ds_name + " has " + this._ds.getDataSources ().size () - + " data sources, but there were " + this._attributes.size () - + " attributes configured. This doesn't match!"); + dsrc = this._ds.getDataSources(); + if (dsrc.size() != this._attributes.size()) { + Collectd.logError( + "GenericJMXConfValue.query: The data set " + this._ds_name + " has " + + this._ds.getDataSources().size() + " data sources, but there were " + + this._attributes.size() + + " attributes configured. This doesn't match!"); this._ds = null; return; } - vl = new ValueList (pd); - vl.setType (this._ds_name); + vl = new ValueList(pd); + vl.setType(this._ds_name); + if (this._plugin_name != null) { + vl.setPlugin(this._plugin_name); + } /* * Build the instnace prefix from the fixed string prefix and the * properties of the objName. */ - instanceList = new ArrayList (); - for (int i = 0; i < this._instance_from.size (); i++) - { + instanceList = new ArrayList(); + for (int i = 0; i < this._instance_from.size(); i++) { String propertyName; String propertyValue; - propertyName = this._instance_from.get (i); - propertyValue = objName.getKeyProperty (propertyName); - if (propertyValue == null) - { - Collectd.logError ("GenericJMXConfMBean: " - + "No such property in object name: " + propertyName); - } - else - { - instanceList.add (propertyValue); + propertyName = this._instance_from.get(i); + propertyValue = objName.getKeyProperty(propertyName); + if (propertyValue == null) { + Collectd.logError("GenericJMXConfMBean: " + + "No such property in object name: " + propertyName); + } else { + instanceList.add(propertyValue); } } if (this._instance_prefix != null) - instancePrefix = new String (this._instance_prefix - + join ("-", instanceList)); + instancePrefix = + new String(this._instance_prefix + join("-", instanceList)); else - instancePrefix = join ("-", instanceList); + instancePrefix = join("-", instanceList); /* * Build a list of `Object's which is then passed to `submitTable' and * `submitScalar'. */ - values = new ArrayList (); - assert (dsrc.size () == this._attributes.size ()); - for (int i = 0; i < this._attributes.size (); i++) - { + values = new ArrayList(); + assert(dsrc.size() == this._attributes.size()); + for (int i = 0; i < this._attributes.size(); i++) { Object v; - v = queryAttribute (conn, objName, this._attributes.get (i)); - if (v == null) - { - Collectd.logError ("GenericJMXConfValue.query: " - + "Querying attribute " + this._attributes.get (i) + " failed."); + v = queryAttribute(conn, objName, this._attributes.get(i)); + if (v == null) { + Collectd.logError( + "GenericJMXConfValue.query: " + "Querying attribute " + + this._attributes.get(i) + " failed."); return; } - values.add (v); + values.add(v); } if (this._is_table) - submitTable (values, vl, instancePrefix); + submitTable(values, vl, instancePrefix); else - submitScalar (values, vl, instancePrefix); + submitScalar(values, vl, instancePrefix); } /* }}} void query */ } /* class GenericJMXConfValue */ diff --git a/bindings/java/org/collectd/java/JMXMemory.java b/bindings/java/org/collectd/java/JMXMemory.java index 6e6a2fb09e..050d8936f6 100644 --- a/bindings/java/org/collectd/java/JMXMemory.java +++ b/bindings/java/org/collectd/java/JMXMemory.java @@ -1,22 +1,27 @@ -/* - * collectd/java - org/collectd/java/JMXMemory.java - * Copyright (C) 2009 Florian octo Forster +/** + * collectd - bindings/java/org/collectd/java/JMXMemory.java + * Copyright (C) 2009 Florian octo Forster * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; only version 2 of the License is applicable. + * 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: * - * 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. + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. * - * 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 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. * * Authors: - * Florian octo Forster + * Florian octo Forster */ package org.collectd.java; diff --git a/bindings/perl/Makefile.PL b/bindings/perl/Makefile.PL index f2ef2fd33c..68fb260d58 100644 --- a/bindings/perl/Makefile.PL +++ b/bindings/perl/Makefile.PL @@ -1,8 +1,9 @@ use ExtUtils::MakeMaker; WriteMakefile( - 'NAME' => 'Collectd', - 'AUTHOR' => 'Sebastian Harl ', + NAME => 'Collectd', + AUTHOR => 'Sebastian Harl ', + TEST_REQUIRES => { 'YAML::Any' => 0 }, ); # vim: set sw=4 ts=4 tw=78 noexpandtab : diff --git a/bindings/perl/lib/Collectd.pm b/bindings/perl/lib/Collectd.pm index c1adf44262..7e89e45f5d 100644 --- a/bindings/perl/lib/Collectd.pm +++ b/bindings/perl/lib/Collectd.pm @@ -172,7 +172,6 @@ sub plugin_call_all { my $type = shift; my %plugins; - my $interval; our $cb_name = undef; @@ -181,13 +180,13 @@ sub plugin_call_all { } if (TYPE_LOG != $type) { - DEBUG ("Collectd::plugin_call: type = \"$type\" (" + DEBUG ("Collectd::plugin_call_all: type = \"$type\" (" . $types{$type} . "), args=\"" . join(', ', map { defined($_) ? $_ : '' } @_) . "\""); } if (! defined $plugins[$type]) { - ERROR ("Collectd::plugin_call: unknown type \"$type\""); + ERROR ("Collectd::plugin_call_all: unknown type \"$type\""); return; } @@ -196,21 +195,9 @@ sub plugin_call_all { %plugins = %{$plugins[$type]}; } - $interval = plugin_get_interval (); - foreach my $plugin (keys %plugins) { - my $p = $plugins{$plugin}; - - my $status = 0; - - if ($p->{'wait_left'} > 0) { - $p->{'wait_left'} -= $interval; - } - - next if ($p->{'wait_left'} > 0); - - $cb_name = $p->{'cb_name'}; - $status = call_by_name (@_); + $cb_name = $plugins{$plugin}; + my $status = call_by_name (@_); if (! $status) { my $err = undef; @@ -230,23 +217,7 @@ sub plugin_call_all { } if ($status) { - $p->{'wait_left'} = 0; - $p->{'wait_time'} = $interval; - } - elsif (TYPE_READ == $type) { - if ($p->{'wait_time'} < $interval) { - $p->{'wait_time'} = $interval; - } - - $p->{'wait_left'} = $p->{'wait_time'}; - $p->{'wait_time'} *= 2; - - if ($p->{'wait_time'} > 86400) { - $p->{'wait_time'} = 86400; - } - - WARNING ("${plugin}->read() failed with status $status. " - . "Will suspend it for $p->{'wait_left'} seconds."); + #NOOP } elsif (TYPE_INIT == $type) { ERROR ("${plugin}->init() failed with status $status. " @@ -309,21 +280,29 @@ sub plugin_register { } elsif ((TYPE_DATASET != $type) && (! ref $data)) { my $pkg = scalar caller; - - my %p : shared; - if ($data !~ m/^$pkg\:\:/) { $data = $pkg . "::" . $data; } - - %p = ( - wait_time => plugin_get_interval (), - wait_left => 0, - cb_name => $data, - ); - + if (TYPE_READ == $type) { + return plugin_register_read($name, $data); + } + if (TYPE_WRITE == $type) { + return plugin_register_write($name, $data); + } + if (TYPE_LOG == $type) { + return plugin_register_log($name, $data); + } + if (TYPE_NOTIF == $type) { + return plugin_register_notification($name, $data); + } + if (TYPE_FLUSH == $type) { + #For collectd-5.6 only + lock %{$plugins[$type]}; + $plugins[$type]->{$name} = $data; + return plugin_register_flush($name, $data); + } lock %{$plugins[$type]}; - $plugins[$type]->{$name} = \%p; + $plugins[$type]->{$name} = $data; } else { ERROR ("Collectd::plugin_register: Invalid data."); @@ -351,6 +330,21 @@ sub plugin_unregister { lock %cf_callbacks; delete $cf_callbacks{$name}; } + elsif (TYPE_READ == $type) { + return plugin_unregister_read ($name); + } + elsif (TYPE_WRITE == $type) { + return plugin_unregister_write($name); + } + elsif (TYPE_LOG == $type) { + return plugin_unregister_log ($name); + } + elsif (TYPE_NOTIF == $type) { + return plugin_unregister_notification($name); + } + elsif (TYPE_FLUSH == $type) { + return plugin_unregister_flush($name); + } elsif (defined $plugins[$type]) { lock %{$plugins[$type]}; delete $plugins[$type]->{$name}; diff --git a/bindings/perl/lib/Collectd/MockDaemon.pm b/bindings/perl/lib/Collectd/MockDaemon.pm new file mode 100644 index 0000000000..300d2c4a85 --- /dev/null +++ b/bindings/perl/lib/Collectd/MockDaemon.pm @@ -0,0 +1,10756 @@ +package Collectd::MockDaemon; +use strict; +use warnings; +use IO::Socket::UNIX; +use IO::Handle; +use File::Temp; +use Carp; +use YAML::Any qw/Load/; + +use base 'Exporter'; +our @EXPORT = qw/ mockd_start mockd_stop /; + +my ($pid, $childfh, $sock_path); +my $data = Load(do{local $/; }); +my @metrics = sort keys %$data; + +sub mockd_start { + croak "don't call me twice" if defined $pid; + $sock_path = File::Temp::mktemp('collectd-mocksock.XXXXXX'); + + my $sock = IO::Socket::UNIX->new( + Type => SOCK_STREAM, + Local => $sock_path, + Listen => 1 + ) or die "Can't open Unix domain socket `$sock_path': $!"; + $pid = open(my $kid, "-|"); + croak "cannot fork(): $!" unless defined $pid; + if($pid) { + $childfh = $kid; + } else { + daemon($sock); + exit 0; + } + return $sock_path; +} + +sub mockd_stop { + return unless defined $childfh; + kill 'TERM', $pid; # kill it with fire + unlink $sock_path; + $childfh = $pid = undef; +} + +sub daemon { + my $sock = shift; + while(my $csock = $sock->accept) { + while(<$csock>) { + chomp; + /^LISTVAL\s*$/i and $csock->print(listval()), next; + /^GETVAL\s+(.*)$/i and $csock->print(getval($1), "\n"), next; + /^PUTVAL|PUTNOTIF|FLUSH\s+(.*)$/i and $csock->print("-1 Unimplemented command `$1'\n"), next; + $csock->print("-1 Unknown command: $_\n"), next; + } + } +} + +sub listval { + my @timevals = ( + 1479835353.75, + 1479835354.434, + 1479835356, + 1479835354, + 1479835354, + 1479835350.820, + 1479835351, + 1479835354.2, + 1479835353, + ); + my $i = 0; + return print_nvalues(scalar @metrics) . + join('', map { $timevals[$i++ % @timevals] . " $_\n" } @metrics); +} + +sub getval { + my ($val) = @_; + $val =~ s/(?:^\s+|\s+$)//g; + $val =~ s/(?:^"|"$)//g; + my $id = _parse_identifier($val) or return "-1 Cannot parse identifier `$val'"; + return "-1 No such value ($val)" unless exists $data->{$val}; + my $result = print_nvalues(scalar keys %{$data->{$val}}); + return $result . join("\n", map { "$_=$data->{$val}{$_}" } keys %{$data->{$val}}); +} + +sub _parse_identifier +{ + my $s = shift; + my ($plugin_instance, $type_instance); + + my ($host, $plugin, $type) = split ('/', $s); + return unless length $host and length $plugin and length $type; + + ($plugin, $plugin_instance) = split ('-', $plugin, 2); + ($type, $type_instance) = split ('-', $type, 2); + + my $ident = + { + host => $host, + plugin => $plugin, + type => $type + }; + $ident->{'plugin_instance'} = $plugin_instance if (defined ($plugin_instance)); + $ident->{'type_instance'} = $type_instance if (defined ($type_instance)); + + return $ident; +} + +sub print_nvalues { + my $nvals = shift; + return sprintf("%d Value%s found\n", $nvals, $nvals > 1 ? 's' : ''); +} + +1; + +__DATA__ +--- +a1d8f6310/cpu-0/cpu-idle: + value: 9.999973e+01 +a1d8f6310/cpu-0/cpu-interrupt: + value: 0.000000e+00 +a1d8f6310/cpu-0/cpu-nice: + value: 0.000000e+00 +a1d8f6310/cpu-0/cpu-softirq: + value: 0.000000e+00 +a1d8f6310/cpu-0/cpu-steal: + value: 0.000000e+00 +a1d8f6310/cpu-0/cpu-system: + value: 0.000000e+00 +a1d8f6310/cpu-0/cpu-user: + value: 9.999996e-02 +a1d8f6310/cpu-0/cpu-wait: + value: 0.000000e+00 +a1d8f6310/cpu-1/cpu-idle: + value: 9.989979e+01 +a1d8f6310/cpu-1/cpu-interrupt: + value: 0.000000e+00 +a1d8f6310/cpu-1/cpu-nice: + value: 0.000000e+00 +a1d8f6310/cpu-1/cpu-softirq: + value: 0.000000e+00 +a1d8f6310/cpu-1/cpu-steal: + value: 0.000000e+00 +a1d8f6310/cpu-1/cpu-system: + value: 0.000000e+00 +a1d8f6310/cpu-1/cpu-user: + value: 0.000000e+00 +a1d8f6310/cpu-1/cpu-wait: + value: 0.000000e+00 +a1d8f6310/df-boot/df_complex-free: + value: 4.368712e+08 +a1d8f6310/df-boot/df_complex-reserved: + value: 2.684109e+07 +a1d8f6310/df-boot/df_complex-used: + value: 6.471270e+07 +a1d8f6310/df-boot/df_inodes-free: + value: 3.271800e+04 +a1d8f6310/df-boot/df_inodes-reserved: + value: 0.000000e+00 +a1d8f6310/df-boot/df_inodes-used: + value: 5.000000e+01 +a1d8f6310/df-boot/percent_bytes-free: + value: 8.267421e+01 +a1d8f6310/df-boot/percent_bytes-reserved: + value: 5.079451e+00 +a1d8f6310/df-boot/percent_bytes-used: + value: 1.224634e+01 +a1d8f6310/df-boot/percent_inodes-free: + value: 9.984741e+01 +a1d8f6310/df-boot/percent_inodes-reserved: + value: 0.000000e+00 +a1d8f6310/df-boot/percent_inodes-used: + value: 1.525879e-01 +a1d8f6310/df-data1/df_complex-free: + value: 2.636943e+10 +a1d8f6310/df-data1/df_complex-reserved: + value: 1.476235e+09 +a1d8f6310/df-data1/df_complex-used: + value: 1.215783e+09 +a1d8f6310/df-data1/df_inodes-free: + value: 1.797470e+06 +a1d8f6310/df-data1/df_inodes-reserved: + value: 0.000000e+00 +a1d8f6310/df-data1/df_inodes-used: + value: 4.770000e+03 +a1d8f6310/df-data1/percent_bytes-free: + value: 9.073681e+01 +a1d8f6310/df-data1/percent_bytes-reserved: + value: 5.079704e+00 +a1d8f6310/df-data1/percent_bytes-used: + value: 4.183491e+00 +a1d8f6310/df-data1/percent_inodes-free: + value: 9.973533e+01 +a1d8f6310/df-data1/percent_inodes-reserved: + value: 0.000000e+00 +a1d8f6310/df-data1/percent_inodes-used: + value: 2.646706e-01 +a1d8f6310/df-dev-shm/df_complex-free: + value: 9.842483e+08 +a1d8f6310/df-dev-shm/df_complex-reserved: + value: 0.000000e+00 +a1d8f6310/df-dev-shm/df_complex-used: + value: 0.000000e+00 +a1d8f6310/df-dev-shm/df_inodes-free: + value: 2.402940e+05 +a1d8f6310/df-dev-shm/df_inodes-reserved: + value: 0.000000e+00 +a1d8f6310/df-dev-shm/df_inodes-used: + value: 1.000000e+00 +a1d8f6310/df-dev-shm/percent_bytes-free: + value: 1.000000e+02 +a1d8f6310/df-dev-shm/percent_bytes-reserved: + value: 0.000000e+00 +a1d8f6310/df-dev-shm/percent_bytes-used: + value: 0.000000e+00 +a1d8f6310/df-dev-shm/percent_inodes-free: + value: 9.999958e+01 +a1d8f6310/df-dev-shm/percent_inodes-reserved: + value: 0.000000e+00 +a1d8f6310/df-dev-shm/percent_inodes-used: + value: 4.161551e-04 +a1d8f6310/df-root/df_complex-free: + value: 1.072081e+10 +a1d8f6310/df-root/df_complex-reserved: + value: 6.442435e+08 +a1d8f6310/df-root/df_complex-used: + value: 1.317655e+09 +a1d8f6310/df-root/df_inodes-free: + value: 7.423750e+05 +a1d8f6310/df-root/df_inodes-reserved: + value: 0.000000e+00 +a1d8f6310/df-root/df_inodes-used: + value: 4.405700e+04 +a1d8f6310/df-root/percent_bytes-free: + value: 8.453092e+01 +a1d8f6310/df-root/percent_bytes-reserved: + value: 5.079700e+00 +a1d8f6310/df-root/percent_bytes-used: + value: 1.038938e+01 +a1d8f6310/df-root/percent_inodes-free: + value: 9.439786e+01 +a1d8f6310/df-root/percent_inodes-reserved: + value: 0.000000e+00 +a1d8f6310/df-root/percent_inodes-used: + value: 5.602138e+00 +a1d8f6310/df-var/df_complex-free: + value: 7.454015e+09 +a1d8f6310/df-var/df_complex-reserved: + value: 4.294943e+08 +a1d8f6310/df-var/df_complex-used: + value: 5.716091e+08 +a1d8f6310/df-var/df_inodes-free: + value: 5.222690e+05 +a1d8f6310/df-var/df_inodes-reserved: + value: 0.000000e+00 +a1d8f6310/df-var/df_inodes-used: + value: 2.019000e+03 +a1d8f6310/df-var/percent_bytes-free: + value: 8.815979e+01 +a1d8f6310/df-var/percent_bytes-reserved: + value: 5.079695e+00 +a1d8f6310/df-var/percent_bytes-used: + value: 6.760509e+00 +a1d8f6310/df-var/percent_inodes-free: + value: 9.961491e+01 +a1d8f6310/df-var/percent_inodes-reserved: + value: 0.000000e+00 +a1d8f6310/df-var/percent_inodes-used: + value: 3.850937e-01 +a1d8f6310/disk-vda/disk_merged: + read: 0.000000e+00 + write: 9.999910e-02 +a1d8f6310/disk-vda/disk_octets: + read: 0.000000e+00 + write: 1.228789e+03 +a1d8f6310/disk-vda/disk_ops: + read: 0.000000e+00 + write: 1.999982e-01 +a1d8f6310/disk-vda/disk_time: + read: 0.000000e+00 + write: 4.999955e-01 +a1d8f6310/disk-vda1/disk_merged: + read: 0.000000e+00 + write: 0.000000e+00 +a1d8f6310/disk-vda1/disk_octets: + read: 0.000000e+00 + write: 0.000000e+00 +a1d8f6310/disk-vda1/disk_ops: + read: 0.000000e+00 + write: 0.000000e+00 +a1d8f6310/disk-vda1/disk_time: + read: 0.000000e+00 + write: 0.000000e+00 +a1d8f6310/disk-vda2/disk_merged: + read: 0.000000e+00 + write: 0.000000e+00 +a1d8f6310/disk-vda2/disk_octets: + read: 0.000000e+00 + write: 0.000000e+00 +a1d8f6310/disk-vda2/disk_ops: + read: 0.000000e+00 + write: 0.000000e+00 +a1d8f6310/disk-vda2/disk_time: + read: 0.000000e+00 + write: 0.000000e+00 +a1d8f6310/disk-vda3/disk_merged: + read: 0.000000e+00 + write: 0.000000e+00 +a1d8f6310/disk-vda3/disk_octets: + read: 0.000000e+00 + write: 0.000000e+00 +a1d8f6310/disk-vda3/disk_ops: + read: 0.000000e+00 + write: 0.000000e+00 +a1d8f6310/disk-vda3/disk_time: + read: 0.000000e+00 + write: 0.000000e+00 +a1d8f6310/disk-vda4/disk_merged: + read: 0.000000e+00 + write: 0.000000e+00 +a1d8f6310/disk-vda4/disk_octets: + read: 0.000000e+00 + write: 0.000000e+00 +a1d8f6310/disk-vda4/disk_ops: + read: 0.000000e+00 + write: 0.000000e+00 +a1d8f6310/disk-vda4/disk_time: + read: 0.000000e+00 + write: 0.000000e+00 +a1d8f6310/disk-vda5/disk_merged: + read: 0.000000e+00 + write: 0.000000e+00 +a1d8f6310/disk-vda5/disk_octets: + read: 0.000000e+00 + write: 0.000000e+00 +a1d8f6310/disk-vda5/disk_ops: + read: 0.000000e+00 + write: 0.000000e+00 +a1d8f6310/disk-vda5/disk_time: + read: 0.000000e+00 + write: 0.000000e+00 +a1d8f6310/disk-vda6/disk_merged: + read: 0.000000e+00 + write: 9.999878e-02 +a1d8f6310/disk-vda6/disk_octets: + read: 0.000000e+00 + write: 1.228786e+03 +a1d8f6310/disk-vda6/disk_ops: + read: 0.000000e+00 + write: 1.999976e-01 +a1d8f6310/disk-vda6/disk_time: + read: 0.000000e+00 + write: 4.999941e-01 +a1d8f6310/load/load: + longterm: 7.000000e-02 + midterm: 6.000000e-02 + shortterm: 0.000000e+00 +a1d8f6310/memory/memory-buffered: + value: 2.348646e+08 +a1d8f6310/memory/memory-cached: + value: 5.790310e+08 +a1d8f6310/memory/memory-free: + value: 2.351022e+08 +a1d8f6310/memory/memory-used: + value: 9.194988e+08 +a1d8f6310/network/if_octets: + rx: 0.000000e+00 + tx: 6.586002e+02 +a1d8f6310/network/if_packets: + rx: 0.000000e+00 + tx: 4.999991e-01 +a1d8f6310/network/queue_length: + value: 0.000000e+00 +a1d8f6310/network/total_values-dispatch-accepted: + value: 0.000000e+00 +a1d8f6310/network/total_values-dispatch-rejected: + value: 0.000000e+00 +a1d8f6310/network/total_values-send-accepted: + value: 1.480003e+01 +a1d8f6310/network/total_values-send-rejected: + value: 0.000000e+00 +a1d8f6310/swap/swap-cached: + value: 4.173824e+06 +a1d8f6310/swap/swap-free: + value: 2.118148e+09 +a1d8f6310/swap/swap-used: + value: 2.515354e+07 +a1d8f6310/swap/swap_io-in: + value: 0.000000e+00 +a1d8f6310/swap/swap_io-out: + value: 0.000000e+00 +a1d8f6310/vmem/vmpage_faults: + majflt: 0.000000e+00 + minflt: 6.999952e-01 +a1d8f6310/vmem/vmpage_io-memory: + in: 0.000000e+00 + out: 0.000000e+00 +a1d8f6310/vmem/vmpage_io-swap: + in: 0.000000e+00 + out: 0.000000e+00 +a1d8f6310/vmem/vmpage_number-active_anon: + value: 5.748900e+04 +a1d8f6310/vmem/vmpage_number-active_file: + value: 1.023940e+05 +a1d8f6310/vmem/vmpage_number-anon_pages: + value: 5.851400e+04 +a1d8f6310/vmem/vmpage_number-anon_transparent_hugepages: + value: 1.920000e+02 +a1d8f6310/vmem/vmpage_number-boudfe: + value: 0.000000e+00 +a1d8f6310/vmem/vmpage_number-dirty: + value: 2.000000e+00 +a1d8f6310/vmem/vmpage_number-file_pages: + value: 1.997240e+05 +a1d8f6310/vmem/vmpage_number-free_pages: + value: 5.739800e+04 +a1d8f6310/vmem/vmpage_number-inactive_anon: + value: 1.004470e+05 +a1d8f6310/vmem/vmpage_number-inactive_file: + value: 9.618100e+04 +a1d8f6310/vmem/vmpage_number-isolated_anon: + value: 0.000000e+00 +a1d8f6310/vmem/vmpage_number-isolated_file: + value: 0.000000e+00 +a1d8f6310/vmem/vmpage_number-kernel_stack: + value: 1.280000e+02 +a1d8f6310/vmem/vmpage_number-mapped: + value: 4.414000e+03 +a1d8f6310/vmem/vmpage_number-mlock: + value: 0.000000e+00 +a1d8f6310/vmem/vmpage_number-page_table_pages: + value: 2.171000e+03 +a1d8f6310/vmem/vmpage_number-shmem: + value: 1.290000e+02 +a1d8f6310/vmem/vmpage_number-slab_reclaimable: + value: 5.264400e+04 +a1d8f6310/vmem/vmpage_number-slab_unreclaimable: + value: 5.743000e+03 +a1d8f6310/vmem/vmpage_number-unevictable: + value: 0.000000e+00 +a1d8f6310/vmem/vmpage_number-unstable: + value: 0.000000e+00 +a1d8f6310/vmem/vmpage_number-vmscan_write: + value: 7.366000e+03 +a1d8f6310/vmem/vmpage_number-writeback: + value: 0.000000e+00 +a1d8f6310/vmem/vmpage_number-writeback_temp: + value: 0.000000e+00 +a1d8f6410/cpu-0/cpu-idle: + value: 9.920010e+01 +a1d8f6410/cpu-0/cpu-interrupt: + value: 0.000000e+00 +a1d8f6410/cpu-0/cpu-nice: + value: 0.000000e+00 +a1d8f6410/cpu-0/cpu-softirq: + value: 0.000000e+00 +a1d8f6410/cpu-0/cpu-steal: + value: 0.000000e+00 +a1d8f6410/cpu-0/cpu-system: + value: 1.000001e-01 +a1d8f6410/cpu-0/cpu-user: + value: 3.000003e-01 +a1d8f6410/cpu-0/cpu-wait: + value: 0.000000e+00 +a1d8f6410/cpu-1/cpu-idle: + value: 9.900000e+01 +a1d8f6410/cpu-1/cpu-interrupt: + value: 0.000000e+00 +a1d8f6410/cpu-1/cpu-nice: + value: 0.000000e+00 +a1d8f6410/cpu-1/cpu-softirq: + value: 0.000000e+00 +a1d8f6410/cpu-1/cpu-steal: + value: 0.000000e+00 +a1d8f6410/cpu-1/cpu-system: + value: 2.000000e-01 +a1d8f6410/cpu-1/cpu-user: + value: 2.000002e-01 +a1d8f6410/cpu-1/cpu-wait: + value: 2.000000e-01 +a1d8f6410/df-boot/df_complex-free: + value: 4.369080e+08 +a1d8f6410/df-boot/df_complex-reserved: + value: 2.684109e+07 +a1d8f6410/df-boot/df_complex-used: + value: 6.467584e+07 +a1d8f6410/df-boot/df_inodes-free: + value: 3.271800e+04 +a1d8f6410/df-boot/df_inodes-reserved: + value: 0.000000e+00 +a1d8f6410/df-boot/df_inodes-used: + value: 5.000000e+01 +a1d8f6410/df-boot/percent_bytes-free: + value: 8.268118e+01 +a1d8f6410/df-boot/percent_bytes-reserved: + value: 5.079451e+00 +a1d8f6410/df-boot/percent_bytes-used: + value: 1.223936e+01 +a1d8f6410/df-boot/percent_inodes-free: + value: 9.984741e+01 +a1d8f6410/df-boot/percent_inodes-reserved: + value: 0.000000e+00 +a1d8f6410/df-boot/percent_inodes-used: + value: 1.525879e-01 +a1d8f6410/df-data1/df_complex-free: + value: 2.740489e+10 +a1d8f6410/df-data1/df_complex-reserved: + value: 1.476235e+09 +a1d8f6410/df-data1/df_complex-used: + value: 1.803182e+08 +a1d8f6410/df-data1/df_inodes-free: + value: 1.802223e+06 +a1d8f6410/df-data1/df_inodes-reserved: + value: 0.000000e+00 +a1d8f6410/df-data1/df_inodes-used: + value: 1.700000e+01 +a1d8f6410/df-data1/percent_bytes-free: + value: 9.429982e+01 +a1d8f6410/df-data1/percent_bytes-reserved: + value: 5.079704e+00 +a1d8f6410/df-data1/percent_bytes-used: + value: 6.204723e-01 +a1d8f6410/df-data1/percent_inodes-free: + value: 9.999906e+01 +a1d8f6410/df-data1/percent_inodes-reserved: + value: 0.000000e+00 +a1d8f6410/df-data1/percent_inodes-used: + value: 9.432706e-04 +a1d8f6410/df-dev-shm/df_complex-free: + value: 2.008437e+09 +a1d8f6410/df-dev-shm/df_complex-reserved: + value: 0.000000e+00 +a1d8f6410/df-dev-shm/df_complex-used: + value: 0.000000e+00 +a1d8f6410/df-dev-shm/df_inodes-free: + value: 4.903400e+05 +a1d8f6410/df-dev-shm/df_inodes-reserved: + value: 0.000000e+00 +a1d8f6410/df-dev-shm/df_inodes-used: + value: 1.000000e+00 +a1d8f6410/df-dev-shm/percent_bytes-free: + value: 1.000000e+02 +a1d8f6410/df-dev-shm/percent_bytes-reserved: + value: 0.000000e+00 +a1d8f6410/df-dev-shm/percent_bytes-used: + value: 0.000000e+00 +a1d8f6410/df-dev-shm/percent_inodes-free: + value: 9.999979e+01 +a1d8f6410/df-dev-shm/percent_inodes-reserved: + value: 0.000000e+00 +a1d8f6410/df-dev-shm/percent_inodes-used: + value: 2.039397e-04 +a1d8f6410/df-root/df_complex-free: + value: 1.030750e+10 +a1d8f6410/df-root/df_complex-reserved: + value: 6.442435e+08 +a1d8f6410/df-root/df_complex-used: + value: 1.730961e+09 +a1d8f6410/df-root/df_inodes-free: + value: 7.294150e+05 +a1d8f6410/df-root/df_inodes-reserved: + value: 0.000000e+00 +a1d8f6410/df-root/df_inodes-used: + value: 5.701700e+04 +a1d8f6410/df-root/percent_bytes-free: + value: 8.127210e+01 +a1d8f6410/df-root/percent_bytes-reserved: + value: 5.079700e+00 +a1d8f6410/df-root/percent_bytes-used: + value: 1.364820e+01 +a1d8f6410/df-root/percent_inodes-free: + value: 9.274991e+01 +a1d8f6410/df-root/percent_inodes-reserved: + value: 0.000000e+00 +a1d8f6410/df-root/percent_inodes-used: + value: 7.250086e+00 +a1d8f6410/df-var/df_complex-free: + value: 6.861853e+09 +a1d8f6410/df-var/df_complex-reserved: + value: 4.294943e+08 +a1d8f6410/df-var/df_complex-used: + value: 1.163772e+09 +a1d8f6410/df-var/df_inodes-free: + value: 5.104480e+05 +a1d8f6410/df-var/df_inodes-reserved: + value: 0.000000e+00 +a1d8f6410/df-var/df_inodes-used: + value: 1.384000e+04 +a1d8f6410/df-var/percent_bytes-free: + value: 8.115620e+01 +a1d8f6410/df-var/percent_bytes-reserved: + value: 5.079695e+00 +a1d8f6410/df-var/percent_bytes-used: + value: 1.376411e+01 +a1d8f6410/df-var/percent_inodes-free: + value: 9.736023e+01 +a1d8f6410/df-var/percent_inodes-reserved: + value: 0.000000e+00 +a1d8f6410/df-var/percent_inodes-used: + value: 2.639771e+00 +a1d8f6410/disk-vda/disk_merged: + read: 0.000000e+00 + write: 3.569994e+01 +a1d8f6410/disk-vda/disk_octets: + read: 0.000000e+00 + write: 1.724413e+05 +a1d8f6410/disk-vda/disk_ops: + read: 0.000000e+00 + write: 6.399989e+00 +a1d8f6410/disk-vda/disk_time: + read: 0.000000e+00 + write: 3.099995e+01 +a1d8f6410/disk-vda1/disk_merged: + read: 0.000000e+00 + write: 0.000000e+00 +a1d8f6410/disk-vda1/disk_octets: + read: 0.000000e+00 + write: 0.000000e+00 +a1d8f6410/disk-vda1/disk_ops: + read: 0.000000e+00 + write: 0.000000e+00 +a1d8f6410/disk-vda1/disk_time: + read: 0.000000e+00 + write: 0.000000e+00 +a1d8f6410/disk-vda2/disk_merged: + read: 0.000000e+00 + write: 3.999993e-01 +a1d8f6410/disk-vda2/disk_octets: + read: 0.000000e+00 + write: 7.372786e+03 +a1d8f6410/disk-vda2/disk_ops: + read: 0.000000e+00 + write: 1.399997e+00 +a1d8f6410/disk-vda2/disk_time: + read: 0.000000e+00 + write: 9.999982e-01 +a1d8f6410/disk-vda3/disk_merged: + read: 0.000000e+00 + write: 3.529993e+01 +a1d8f6410/disk-vda3/disk_octets: + read: 0.000000e+00 + write: 1.650685e+05 +a1d8f6410/disk-vda3/disk_ops: + read: 0.000000e+00 + write: 4.999991e+00 +a1d8f6410/disk-vda3/disk_time: + read: 0.000000e+00 + write: 3.939993e+01 +a1d8f6410/disk-vda4/disk_merged: + read: 0.000000e+00 + write: 0.000000e+00 +a1d8f6410/disk-vda4/disk_octets: + read: 0.000000e+00 + write: 0.000000e+00 +a1d8f6410/disk-vda4/disk_ops: + read: 0.000000e+00 + write: 0.000000e+00 +a1d8f6410/disk-vda4/disk_time: + read: 0.000000e+00 + write: 0.000000e+00 +a1d8f6410/disk-vda5/disk_merged: + read: 0.000000e+00 + write: 0.000000e+00 +a1d8f6410/disk-vda5/disk_octets: + read: 0.000000e+00 + write: 0.000000e+00 +a1d8f6410/disk-vda5/disk_ops: + read: 0.000000e+00 + write: 0.000000e+00 +a1d8f6410/disk-vda5/disk_time: + read: 0.000000e+00 + write: 0.000000e+00 +a1d8f6410/disk-vda6/disk_merged: + read: 0.000000e+00 + write: 0.000000e+00 +a1d8f6410/disk-vda6/disk_octets: + read: 0.000000e+00 + write: 0.000000e+00 +a1d8f6410/disk-vda6/disk_ops: + read: 0.000000e+00 + write: 0.000000e+00 +a1d8f6410/disk-vda6/disk_time: + read: 0.000000e+00 + write: 0.000000e+00 +a1d8f6410/load/load: + longterm: 0.000000e+00 + midterm: 3.000000e-02 + shortterm: 5.000000e-02 +a1d8f6410/memory/memory-buffered: + value: 3.095921e+08 +a1d8f6410/memory/memory-cached: + value: 1.241870e+09 +a1d8f6410/memory/memory-free: + value: 2.926060e+08 +a1d8f6410/memory/memory-used: + value: 2.172809e+09 +a1d8f6410/network/if_octets: + rx: 0.000000e+00 + tx: 6.586998e+02 +a1d8f6410/network/if_packets: + rx: 0.000000e+00 + tx: 4.999999e-01 +a1d8f6410/network/queue_length: + value: 0.000000e+00 +a1d8f6410/network/total_values-dispatch-accepted: + value: 0.000000e+00 +a1d8f6410/network/total_values-dispatch-rejected: + value: 0.000000e+00 +a1d8f6410/network/total_values-send-accepted: + value: 1.479998e+01 +a1d8f6410/network/total_values-send-rejected: + value: 0.000000e+00 +a1d8f6410/swap/swap-cached: + value: 2.048000e+05 +a1d8f6410/swap/swap-free: + value: 2.147271e+09 +a1d8f6410/swap/swap-used: + value: 0.000000e+00 +a1d8f6410/swap/swap_io-in: + value: 0.000000e+00 +a1d8f6410/swap/swap_io-out: + value: 0.000000e+00 +a1d8f6410/vmem/vmpage_faults: + majflt: 0.000000e+00 + minflt: 6.400115e+00 +a1d8f6410/vmem/vmpage_io-memory: + in: 0.000000e+00 + out: 1.684030e+02 +a1d8f6410/vmem/vmpage_io-swap: + in: 0.000000e+00 + out: 0.000000e+00 +a1d8f6410/vmem/vmpage_number-active_anon: + value: 2.143920e+05 +a1d8f6410/vmem/vmpage_number-active_file: + value: 1.979880e+05 +a1d8f6410/vmem/vmpage_number-anon_pages: + value: 2.734200e+04 +a1d8f6410/vmem/vmpage_number-anon_transparent_hugepages: + value: 3.880000e+02 +a1d8f6410/vmem/vmpage_number-boudfe: + value: 0.000000e+00 +a1d8f6410/vmem/vmpage_number-dirty: + value: 2.700000e+01 +a1d8f6410/vmem/vmpage_number-file_pages: + value: 3.788250e+05 +a1d8f6410/vmem/vmpage_number-free_pages: + value: 7.143700e+04 +a1d8f6410/vmem/vmpage_number-inactive_anon: + value: 1.176200e+04 +a1d8f6410/vmem/vmpage_number-inactive_file: + value: 1.806700e+05 +a1d8f6410/vmem/vmpage_number-isolated_anon: + value: 0.000000e+00 +a1d8f6410/vmem/vmpage_number-isolated_file: + value: 0.000000e+00 +a1d8f6410/vmem/vmpage_number-kernel_stack: + value: 3.000000e+02 +a1d8f6410/vmem/vmpage_number-mapped: + value: 1.012100e+04 +a1d8f6410/vmem/vmpage_number-mlock: + value: 0.000000e+00 +a1d8f6410/vmem/vmpage_number-page_table_pages: + value: 1.602000e+03 +a1d8f6410/vmem/vmpage_number-shmem: + value: 1.170000e+02 +a1d8f6410/vmem/vmpage_number-slab_reclaimable: + value: 2.856060e+05 +a1d8f6410/vmem/vmpage_number-slab_unreclaimable: + value: 6.201000e+03 +a1d8f6410/vmem/vmpage_number-unevictable: + value: 0.000000e+00 +a1d8f6410/vmem/vmpage_number-unstable: + value: 0.000000e+00 +a1d8f6410/vmem/vmpage_number-vmscan_write: + value: 7.900000e+01 +a1d8f6410/vmem/vmpage_number-writeback: + value: 0.000000e+00 +a1d8f6410/vmem/vmpage_number-writeback_temp: + value: 0.000000e+00 +a1ddf6210/cpu-0/cpu-idle: + value: 9.020090e+01 +a1ddf6210/cpu-0/cpu-interrupt: + value: 0.000000e+00 +a1ddf6210/cpu-0/cpu-nice: + value: 0.000000e+00 +a1ddf6210/cpu-0/cpu-softirq: + value: 4.000034e-01 +a1ddf6210/cpu-0/cpu-steal: + value: 0.000000e+00 +a1ddf6210/cpu-0/cpu-system: + value: 3.000031e-01 +a1ddf6210/cpu-0/cpu-user: + value: 4.200047e+00 +a1ddf6210/cpu-0/cpu-wait: + value: 0.000000e+00 +a1ddf6210/cpu-1/cpu-idle: + value: 9.969991e+01 +a1ddf6210/cpu-1/cpu-interrupt: + value: 0.000000e+00 +a1ddf6210/cpu-1/cpu-nice: + value: 0.000000e+00 +a1ddf6210/cpu-1/cpu-softirq: + value: 0.000000e+00 +a1ddf6210/cpu-1/cpu-steal: + value: 0.000000e+00 +a1ddf6210/cpu-1/cpu-system: + value: 0.000000e+00 +a1ddf6210/cpu-1/cpu-user: + value: 2.000011e-01 +a1ddf6210/cpu-1/cpu-wait: + value: 0.000000e+00 +a1ddf6210/cpu-10/cpu-idle: + value: 9.979942e+01 +a1ddf6210/cpu-10/cpu-interrupt: + value: 0.000000e+00 +a1ddf6210/cpu-10/cpu-nice: + value: 0.000000e+00 +a1ddf6210/cpu-10/cpu-softirq: + value: 0.000000e+00 +a1ddf6210/cpu-10/cpu-steal: + value: 0.000000e+00 +a1ddf6210/cpu-10/cpu-system: + value: 0.000000e+00 +a1ddf6210/cpu-10/cpu-user: + value: 9.999943e-02 +a1ddf6210/cpu-10/cpu-wait: + value: 0.000000e+00 +a1ddf6210/cpu-11/cpu-idle: + value: 9.989938e+01 +a1ddf6210/cpu-11/cpu-interrupt: + value: 0.000000e+00 +a1ddf6210/cpu-11/cpu-nice: + value: 0.000000e+00 +a1ddf6210/cpu-11/cpu-softirq: + value: 0.000000e+00 +a1ddf6210/cpu-11/cpu-steal: + value: 0.000000e+00 +a1ddf6210/cpu-11/cpu-system: + value: 9.999938e-02 +a1ddf6210/cpu-11/cpu-user: + value: 0.000000e+00 +a1ddf6210/cpu-11/cpu-wait: + value: 0.000000e+00 +a1ddf6210/cpu-2/cpu-idle: + value: 9.959987e+01 +a1ddf6210/cpu-2/cpu-interrupt: + value: 0.000000e+00 +a1ddf6210/cpu-2/cpu-nice: + value: 0.000000e+00 +a1ddf6210/cpu-2/cpu-softirq: + value: 0.000000e+00 +a1ddf6210/cpu-2/cpu-steal: + value: 0.000000e+00 +a1ddf6210/cpu-2/cpu-system: + value: 1.999997e-01 +a1ddf6210/cpu-2/cpu-user: + value: 9.999988e-02 +a1ddf6210/cpu-2/cpu-wait: + value: 0.000000e+00 +a1ddf6210/cpu-3/cpu-idle: + value: 9.989985e+01 +a1ddf6210/cpu-3/cpu-interrupt: + value: 0.000000e+00 +a1ddf6210/cpu-3/cpu-nice: + value: 0.000000e+00 +a1ddf6210/cpu-3/cpu-softirq: + value: 0.000000e+00 +a1ddf6210/cpu-3/cpu-steal: + value: 0.000000e+00 +a1ddf6210/cpu-3/cpu-system: + value: 0.000000e+00 +a1ddf6210/cpu-3/cpu-user: + value: 0.000000e+00 +a1ddf6210/cpu-3/cpu-wait: + value: 0.000000e+00 +a1ddf6210/cpu-4/cpu-idle: + value: 9.989964e+01 +a1ddf6210/cpu-4/cpu-interrupt: + value: 0.000000e+00 +a1ddf6210/cpu-4/cpu-nice: + value: 0.000000e+00 +a1ddf6210/cpu-4/cpu-softirq: + value: 0.000000e+00 +a1ddf6210/cpu-4/cpu-steal: + value: 0.000000e+00 +a1ddf6210/cpu-4/cpu-system: + value: 0.000000e+00 +a1ddf6210/cpu-4/cpu-user: + value: 0.000000e+00 +a1ddf6210/cpu-4/cpu-wait: + value: 0.000000e+00 +a1ddf6210/cpu-5/cpu-idle: + value: 9.989956e+01 +a1ddf6210/cpu-5/cpu-interrupt: + value: 0.000000e+00 +a1ddf6210/cpu-5/cpu-nice: + value: 0.000000e+00 +a1ddf6210/cpu-5/cpu-softirq: + value: 0.000000e+00 +a1ddf6210/cpu-5/cpu-steal: + value: 0.000000e+00 +a1ddf6210/cpu-5/cpu-system: + value: 0.000000e+00 +a1ddf6210/cpu-5/cpu-user: + value: 0.000000e+00 +a1ddf6210/cpu-5/cpu-wait: + value: 0.000000e+00 +a1ddf6210/cpu-6/cpu-idle: + value: 8.899957e+01 +a1ddf6210/cpu-6/cpu-interrupt: + value: 0.000000e+00 +a1ddf6210/cpu-6/cpu-nice: + value: 0.000000e+00 +a1ddf6210/cpu-6/cpu-softirq: + value: 0.000000e+00 +a1ddf6210/cpu-6/cpu-steal: + value: 0.000000e+00 +a1ddf6210/cpu-6/cpu-system: + value: 1.599993e+00 +a1ddf6210/cpu-6/cpu-user: + value: 9.499956e+00 +a1ddf6210/cpu-6/cpu-wait: + value: 0.000000e+00 +a1ddf6210/cpu-7/cpu-idle: + value: 9.969946e+01 +a1ddf6210/cpu-7/cpu-interrupt: + value: 0.000000e+00 +a1ddf6210/cpu-7/cpu-nice: + value: 0.000000e+00 +a1ddf6210/cpu-7/cpu-softirq: + value: 0.000000e+00 +a1ddf6210/cpu-7/cpu-steal: + value: 0.000000e+00 +a1ddf6210/cpu-7/cpu-system: + value: 1.999989e-01 +a1ddf6210/cpu-7/cpu-user: + value: 9.999947e-02 +a1ddf6210/cpu-7/cpu-wait: + value: 0.000000e+00 +a1ddf6210/cpu-8/cpu-idle: + value: 9.079948e+01 +a1ddf6210/cpu-8/cpu-interrupt: + value: 0.000000e+00 +a1ddf6210/cpu-8/cpu-nice: + value: 0.000000e+00 +a1ddf6210/cpu-8/cpu-softirq: + value: 0.000000e+00 +a1ddf6210/cpu-8/cpu-steal: + value: 0.000000e+00 +a1ddf6210/cpu-8/cpu-system: + value: 8.999950e-01 +a1ddf6210/cpu-8/cpu-user: + value: 8.099954e+00 +a1ddf6210/cpu-8/cpu-wait: + value: 0.000000e+00 +a1ddf6210/cpu-9/cpu-idle: + value: 9.989942e+01 +a1ddf6210/cpu-9/cpu-interrupt: + value: 0.000000e+00 +a1ddf6210/cpu-9/cpu-nice: + value: 0.000000e+00 +a1ddf6210/cpu-9/cpu-softirq: + value: 0.000000e+00 +a1ddf6210/cpu-9/cpu-steal: + value: 0.000000e+00 +a1ddf6210/cpu-9/cpu-system: + value: 9.999942e-02 +a1ddf6210/cpu-9/cpu-user: + value: 0.000000e+00 +a1ddf6210/cpu-9/cpu-wait: + value: 0.000000e+00 +a1ddf6210/df-boot/df_complex-free: + value: 3.880919e+08 +a1ddf6210/df-boot/df_complex-reserved: + value: 2.684109e+07 +a1ddf6210/df-boot/df_complex-used: + value: 1.134920e+08 +a1ddf6210/df-boot/df_inodes-free: + value: 3.270600e+04 +a1ddf6210/df-boot/df_inodes-reserved: + value: 0.000000e+00 +a1ddf6210/df-boot/df_inodes-used: + value: 6.200000e+01 +a1ddf6210/df-boot/percent_bytes-free: + value: 7.344315e+01 +a1ddf6210/df-boot/percent_bytes-reserved: + value: 5.079451e+00 +a1ddf6210/df-boot/percent_bytes-used: + value: 2.147740e+01 +a1ddf6210/df-boot/percent_inodes-free: + value: 9.981079e+01 +a1ddf6210/df-boot/percent_inodes-reserved: + value: 0.000000e+00 +a1ddf6210/df-boot/percent_inodes-used: + value: 1.892090e-01 +a1ddf6210/df-data1/df_complex-free: + value: 5.390209e+11 +a1ddf6210/df-data1/df_complex-reserved: + value: 2.933339e+10 +a1ddf6210/df-data1/df_complex-used: + value: 9.088414e+09 +a1ddf6210/df-data1/df_inodes-free: + value: 3.587710e+07 +a1ddf6210/df-data1/df_inodes-reserved: + value: 0.000000e+00 +a1ddf6210/df-data1/df_inodes-used: + value: 7.000000e+01 +a1ddf6210/df-data1/percent_bytes-free: + value: 9.334621e+01 +a1ddf6210/df-data1/percent_bytes-reserved: + value: 5.079879e+00 +a1ddf6210/df-data1/percent_bytes-used: + value: 1.573908e+00 +a1ddf6210/df-data1/percent_inodes-free: + value: 9.999979e+01 +a1ddf6210/df-data1/percent_inodes-reserved: + value: 0.000000e+00 +a1ddf6210/df-data1/percent_inodes-used: + value: 1.951102e-04 +a1ddf6210/df-data2/df_complex-free: + value: 1.042212e+13 +a1ddf6210/df-data2/df_complex-reserved: + value: 1.200219e+11 +a1ddf6210/df-data2/df_complex-used: + value: 1.271712e+12 +a1ddf6210/df-data2/df_inodes-free: + value: 7.319628e+08 +a1ddf6210/df-data2/df_inodes-reserved: + value: 0.000000e+00 +a1ddf6210/df-data2/df_inodes-used: + value: 5.985960e+05 +a1ddf6210/df-data2/percent_bytes-free: + value: 8.821947e+01 +a1ddf6210/df-data2/percent_bytes-reserved: + value: 1.015942e+00 +a1ddf6210/df-data2/percent_bytes-used: + value: 1.076458e+01 +a1ddf6210/df-data2/percent_inodes-free: + value: 9.991829e+01 +a1ddf6210/df-data2/percent_inodes-reserved: + value: 0.000000e+00 +a1ddf6210/df-data2/percent_inodes-used: + value: 8.171274e-02 +a1ddf6210/df-data3/df_complex-free: + value: 1.143610e+13 +a1ddf6210/df-data3/df_complex-reserved: + value: 1.200219e+11 +a1ddf6210/df-data3/df_complex-used: + value: 2.577290e+11 +a1ddf6210/df-data3/df_inodes-free: + value: 7.323576e+08 +a1ddf6210/df-data3/df_inodes-reserved: + value: 0.000000e+00 +a1ddf6210/df-data3/df_inodes-used: + value: 2.037680e+05 +a1ddf6210/df-data3/percent_bytes-free: + value: 9.680247e+01 +a1ddf6210/df-data3/percent_bytes-reserved: + value: 1.015942e+00 +a1ddf6210/df-data3/percent_bytes-used: + value: 2.181582e+00 +a1ddf6210/df-data3/percent_inodes-free: + value: 9.997218e+01 +a1ddf6210/df-data3/percent_inodes-reserved: + value: 0.000000e+00 +a1ddf6210/df-data3/percent_inodes-used: + value: 2.781583e-02 +a1ddf6210/df-dev-shm/df_complex-free: + value: 3.375733e+10 +a1ddf6210/df-dev-shm/df_complex-reserved: + value: 0.000000e+00 +a1ddf6210/df-dev-shm/df_complex-used: + value: 0.000000e+00 +a1ddf6210/df-dev-shm/df_inodes-free: + value: 8.241535e+06 +a1ddf6210/df-dev-shm/df_inodes-reserved: + value: 0.000000e+00 +a1ddf6210/df-dev-shm/df_inodes-used: + value: 1.000000e+00 +a1ddf6210/df-dev-shm/percent_bytes-free: + value: 1.000000e+02 +a1ddf6210/df-dev-shm/percent_bytes-reserved: + value: 0.000000e+00 +a1ddf6210/df-dev-shm/percent_bytes-used: + value: 0.000000e+00 +a1ddf6210/df-dev-shm/percent_inodes-free: + value: 9.999998e+01 +a1ddf6210/df-dev-shm/percent_inodes-reserved: + value: 0.000000e+00 +a1ddf6210/df-dev-shm/percent_inodes-used: + value: 1.213366e-05 +a1ddf6210/df-root/df_complex-free: + value: 2.006712e+08 +a1ddf6210/df-root/df_complex-reserved: + value: 1.073725e+08 +a1ddf6210/df-root/df_complex-used: + value: 1.805705e+09 +a1ddf6210/df-root/df_inodes-free: + value: 7.542600e+04 +a1ddf6210/df-root/df_inodes-reserved: + value: 0.000000e+00 +a1ddf6210/df-root/df_inodes-used: + value: 5.564600e+04 +a1ddf6210/df-root/percent_bytes-free: + value: 9.493617e+00 +a1ddf6210/df-root/percent_bytes-reserved: + value: 5.079720e+00 +a1ddf6210/df-root/percent_bytes-used: + value: 8.542667e+01 +a1ddf6210/df-root/percent_inodes-free: + value: 5.754547e+01 +a1ddf6210/df-root/percent_inodes-reserved: + value: 0.000000e+00 +a1ddf6210/df-root/percent_inodes-used: + value: 4.245453e+01 +a1ddf6210/df-tmp/df_complex-free: + value: 1.102356e+08 +a1ddf6210/df-tmp/df_complex-reserved: + value: 0.000000e+00 +a1ddf6210/df-tmp/df_complex-used: + value: 2.398208e+07 +a1ddf6210/df-tmp/df_inodes-free: + value: 8.241515e+06 +a1ddf6210/df-tmp/df_inodes-reserved: + value: 0.000000e+00 +a1ddf6210/df-tmp/df_inodes-used: + value: 2.100000e+01 +a1ddf6210/df-tmp/percent_bytes-free: + value: 8.213196e+01 +a1ddf6210/df-tmp/percent_bytes-reserved: + value: 0.000000e+00 +a1ddf6210/df-tmp/percent_bytes-used: + value: 1.786804e+01 +a1ddf6210/df-tmp/percent_inodes-free: + value: 9.999974e+01 +a1ddf6210/df-tmp/percent_inodes-reserved: + value: 0.000000e+00 +a1ddf6210/df-tmp/percent_inodes-used: + value: 2.548069e-04 +a1ddf6210/df-var/df_complex-free: + value: 6.870528e+09 +a1ddf6210/df-var/df_complex-reserved: + value: 4.294943e+08 +a1ddf6210/df-var/df_complex-used: + value: 1.155097e+09 +a1ddf6210/df-var/df_inodes-free: + value: 5.196230e+05 +a1ddf6210/df-var/df_inodes-reserved: + value: 0.000000e+00 +a1ddf6210/df-var/df_inodes-used: + value: 4.665000e+03 +a1ddf6210/df-var/percent_bytes-free: + value: 8.125880e+01 +a1ddf6210/df-var/percent_bytes-reserved: + value: 5.079695e+00 +a1ddf6210/df-var/percent_bytes-used: + value: 1.366151e+01 +a1ddf6210/df-var/percent_inodes-free: + value: 9.911022e+01 +a1ddf6210/df-var/percent_inodes-reserved: + value: 0.000000e+00 +a1ddf6210/df-var/percent_inodes-used: + value: 8.897781e-01 +a1ddf6210/disk-sda/disk_merged: + read: 0.000000e+00 + write: 2.080016e+01 +a1ddf6210/disk-sda/disk_octets: + read: 0.000000e+00 + write: 1.212425e+05 +a1ddf6210/disk-sda/disk_ops: + read: 0.000000e+00 + write: 8.700063e+00 +a1ddf6210/disk-sda/disk_time: + read: 0.000000e+00 + write: 1.000007e-01 +a1ddf6210/disk-sda1/disk_merged: + read: 0.000000e+00 + write: 0.000000e+00 +a1ddf6210/disk-sda1/disk_octets: + read: 0.000000e+00 + write: 0.000000e+00 +a1ddf6210/disk-sda1/disk_ops: + read: 0.000000e+00 + write: 0.000000e+00 +a1ddf6210/disk-sda1/disk_time: + read: 0.000000e+00 + write: 0.000000e+00 +a1ddf6210/disk-sda2/disk_merged: + read: 0.000000e+00 + write: 1.960018e+01 +a1ddf6210/disk-sda2/disk_octets: + read: 0.000000e+00 + write: 1.138698e+05 +a1ddf6210/disk-sda2/disk_ops: + read: 0.000000e+00 + write: 8.200073e+00 +a1ddf6210/disk-sda2/disk_time: + read: 0.000000e+00 + write: 1.000009e-01 +a1ddf6210/disk-sda3/disk_merged: + read: 0.000000e+00 + write: 0.000000e+00 +a1ddf6210/disk-sda3/disk_octets: + read: 0.000000e+00 + write: 0.000000e+00 +a1ddf6210/disk-sda3/disk_ops: + read: 0.000000e+00 + write: 0.000000e+00 +a1ddf6210/disk-sda3/disk_time: + read: 0.000000e+00 + write: 0.000000e+00 +a1ddf6210/disk-sda4/disk_merged: + read: 0.000000e+00 + write: 0.000000e+00 +a1ddf6210/disk-sda4/disk_octets: + read: 0.000000e+00 + write: 0.000000e+00 +a1ddf6210/disk-sda4/disk_ops: + read: 0.000000e+00 + write: 0.000000e+00 +a1ddf6210/disk-sda4/disk_time: + read: 0.000000e+00 + write: 0.000000e+00 +a1ddf6210/disk-sda5/disk_merged: + read: 0.000000e+00 + write: 1.200011e+00 +a1ddf6210/disk-sda5/disk_octets: + read: 0.000000e+00 + write: 6.144060e+03 +a1ddf6210/disk-sda5/disk_ops: + read: 0.000000e+00 + write: 3.000029e-01 +a1ddf6210/disk-sda5/disk_time: + read: 0.000000e+00 + write: 0.000000e+00 +a1ddf6210/disk-sda6/disk_merged: + read: 0.000000e+00 + write: 0.000000e+00 +a1ddf6210/disk-sda6/disk_octets: + read: 0.000000e+00 + write: 1.228812e+03 +a1ddf6210/disk-sda6/disk_ops: + read: 0.000000e+00 + write: 2.000019e-01 +a1ddf6210/disk-sda6/disk_time: + read: 0.000000e+00 + write: 0.000000e+00 +a1ddf6210/disk-sdb/disk_merged: + read: 0.000000e+00 + write: 0.000000e+00 +a1ddf6210/disk-sdb/disk_octets: + read: 0.000000e+00 + write: 0.000000e+00 +a1ddf6210/disk-sdb/disk_ops: + read: 0.000000e+00 + write: 0.000000e+00 +a1ddf6210/disk-sdb/disk_time: + read: 0.000000e+00 + write: 0.000000e+00 +a1ddf6210/disk-sdc/disk_merged: + read: 0.000000e+00 + write: 0.000000e+00 +a1ddf6210/disk-sdc/disk_octets: + read: 0.000000e+00 + write: 0.000000e+00 +a1ddf6210/disk-sdc/disk_ops: + read: 0.000000e+00 + write: 0.000000e+00 +a1ddf6210/disk-sdc/disk_time: + read: 0.000000e+00 + write: 0.000000e+00 +a1ddf6210/load/load: + longterm: 9.000000e-02 + midterm: 1.400000e-01 + shortterm: 1.400000e-01 +a1ddf6210/memory/memory-buffered: + value: 7.775150e+08 +a1ddf6210/memory/memory-cached: + value: 2.349433e+10 +a1ddf6210/memory/memory-free: + value: 2.759657e+10 +a1ddf6210/memory/memory-used: + value: 1.564624e+10 +a1ddf6210/network/if_octets: + rx: 0.000000e+00 + tx: 1.455100e+03 +a1ddf6210/network/if_packets: + rx: 0.000000e+00 + tx: 1.100000e+00 +a1ddf6210/network/queue_length: + value: 0.000000e+00 +a1ddf6210/network/total_values-dispatch-accepted: + value: 0.000000e+00 +a1ddf6210/network/total_values-dispatch-rejected: + value: 0.000000e+00 +a1ddf6210/network/total_values-send-accepted: + value: 2.720003e+01 +a1ddf6210/network/total_values-send-rejected: + value: 0.000000e+00 +a1ddf6210/swap/swap-cached: + value: 0.000000e+00 +a1ddf6210/swap/swap-free: + value: 2.147475e+09 +a1ddf6210/swap/swap-used: + value: 0.000000e+00 +a1ddf6210/swap/swap_io-in: + value: 0.000000e+00 +a1ddf6210/swap/swap_io-out: + value: 0.000000e+00 +a1ddf6210/vmem/vmpage_faults: + majflt: 0.000000e+00 + minflt: 1.770240e+04 +a1ddf6210/vmem/vmpage_io-memory: + in: 0.000000e+00 + out: 1.100000e+02 +a1ddf6210/vmem/vmpage_io-swap: + in: 0.000000e+00 + out: 0.000000e+00 +a1ddf6210/vmem/vmpage_number-active_anon: + value: 7.455600e+05 +a1ddf6210/vmem/vmpage_number-active_file: + value: 3.175860e+05 +a1ddf6210/vmem/vmpage_number-anon_pages: + value: 5.005000e+04 +a1ddf6210/vmem/vmpage_number-anon_transparent_hugepages: + value: 1.356000e+03 +a1ddf6210/vmem/vmpage_number-boudfe: + value: 0.000000e+00 +a1ddf6210/vmem/vmpage_number-dirty: + value: 1.550000e+02 +a1ddf6210/vmem/vmpage_number-file_pages: + value: 5.925744e+06 +a1ddf6210/vmem/vmpage_number-free_pages: + value: 6.737445e+06 +a1ddf6210/vmem/vmpage_number-inactive_anon: + value: 4.923000e+03 +a1ddf6210/vmem/vmpage_number-inactive_file: + value: 5.601994e+06 +a1ddf6210/vmem/vmpage_number-isolated_anon: + value: 0.000000e+00 +a1ddf6210/vmem/vmpage_number-isolated_file: + value: 0.000000e+00 +a1ddf6210/vmem/vmpage_number-kernel_stack: + value: 3.480000e+02 +a1ddf6210/vmem/vmpage_number-mapped: + value: 6.515000e+03 +a1ddf6210/vmem/vmpage_number-mlock: + value: 0.000000e+00 +a1ddf6210/vmem/vmpage_number-page_table_pages: + value: 4.479000e+03 +a1ddf6210/vmem/vmpage_number-shmem: + value: 6.170000e+03 +a1ddf6210/vmem/vmpage_number-slab_reclaimable: + value: 2.916436e+06 +a1ddf6210/vmem/vmpage_number-slab_unreclaimable: + value: 4.737700e+04 +a1ddf6210/vmem/vmpage_number-unevictable: + value: 0.000000e+00 +a1ddf6210/vmem/vmpage_number-unstable: + value: 0.000000e+00 +a1ddf6210/vmem/vmpage_number-vmscan_write: + value: 0.000000e+00 +a1ddf6210/vmem/vmpage_number-writeback: + value: 0.000000e+00 +a1ddf6210/vmem/vmpage_number-writeback_temp: + value: 0.000000e+00 +a1ddf6510/cpu-0/cpu-idle: + value: 9.159977e+01 +a1ddf6510/cpu-0/cpu-interrupt: + value: 0.000000e+00 +a1ddf6510/cpu-0/cpu-nice: + value: 0.000000e+00 +a1ddf6510/cpu-0/cpu-softirq: + value: 0.000000e+00 +a1ddf6510/cpu-0/cpu-steal: + value: 0.000000e+00 +a1ddf6510/cpu-0/cpu-system: + value: 2.999997e+00 +a1ddf6510/cpu-0/cpu-user: + value: 5.200008e+00 +a1ddf6510/cpu-0/cpu-wait: + value: 0.000000e+00 +a1ddf6510/cpu-1/cpu-idle: + value: 9.989949e+01 +a1ddf6510/cpu-1/cpu-interrupt: + value: 0.000000e+00 +a1ddf6510/cpu-1/cpu-nice: + value: 0.000000e+00 +a1ddf6510/cpu-1/cpu-softirq: + value: 0.000000e+00 +a1ddf6510/cpu-1/cpu-steal: + value: 0.000000e+00 +a1ddf6510/cpu-1/cpu-system: + value: 9.999952e-02 +a1ddf6510/cpu-1/cpu-user: + value: 0.000000e+00 +a1ddf6510/cpu-1/cpu-wait: + value: 0.000000e+00 +a1ddf6510/cpu-10/cpu-idle: + value: 9.799903e+01 +a1ddf6510/cpu-10/cpu-interrupt: + value: 0.000000e+00 +a1ddf6510/cpu-10/cpu-nice: + value: 0.000000e+00 +a1ddf6510/cpu-10/cpu-softirq: + value: 0.000000e+00 +a1ddf6510/cpu-10/cpu-steal: + value: 0.000000e+00 +a1ddf6510/cpu-10/cpu-system: + value: 1.199988e+00 +a1ddf6510/cpu-10/cpu-user: + value: 5.999943e-01 +a1ddf6510/cpu-10/cpu-wait: + value: 0.000000e+00 +a1ddf6510/cpu-11/cpu-idle: + value: 9.999894e+01 +a1ddf6510/cpu-11/cpu-interrupt: + value: 0.000000e+00 +a1ddf6510/cpu-11/cpu-nice: + value: 0.000000e+00 +a1ddf6510/cpu-11/cpu-softirq: + value: 0.000000e+00 +a1ddf6510/cpu-11/cpu-steal: + value: 0.000000e+00 +a1ddf6510/cpu-11/cpu-system: + value: 0.000000e+00 +a1ddf6510/cpu-11/cpu-user: + value: 0.000000e+00 +a1ddf6510/cpu-11/cpu-wait: + value: 0.000000e+00 +a1ddf6510/cpu-2/cpu-idle: + value: 9.989933e+01 +a1ddf6510/cpu-2/cpu-interrupt: + value: 0.000000e+00 +a1ddf6510/cpu-2/cpu-nice: + value: 0.000000e+00 +a1ddf6510/cpu-2/cpu-softirq: + value: 0.000000e+00 +a1ddf6510/cpu-2/cpu-steal: + value: 0.000000e+00 +a1ddf6510/cpu-2/cpu-system: + value: 0.000000e+00 +a1ddf6510/cpu-2/cpu-user: + value: 0.000000e+00 +a1ddf6510/cpu-2/cpu-wait: + value: 0.000000e+00 +a1ddf6510/cpu-3/cpu-idle: + value: 9.989927e+01 +a1ddf6510/cpu-3/cpu-interrupt: + value: 0.000000e+00 +a1ddf6510/cpu-3/cpu-nice: + value: 0.000000e+00 +a1ddf6510/cpu-3/cpu-softirq: + value: 9.999927e-02 +a1ddf6510/cpu-3/cpu-steal: + value: 0.000000e+00 +a1ddf6510/cpu-3/cpu-system: + value: 0.000000e+00 +a1ddf6510/cpu-3/cpu-user: + value: 0.000000e+00 +a1ddf6510/cpu-3/cpu-wait: + value: 0.000000e+00 +a1ddf6510/cpu-4/cpu-idle: + value: 9.999933e+01 +a1ddf6510/cpu-4/cpu-interrupt: + value: 0.000000e+00 +a1ddf6510/cpu-4/cpu-nice: + value: 0.000000e+00 +a1ddf6510/cpu-4/cpu-softirq: + value: 0.000000e+00 +a1ddf6510/cpu-4/cpu-steal: + value: 0.000000e+00 +a1ddf6510/cpu-4/cpu-system: + value: 0.000000e+00 +a1ddf6510/cpu-4/cpu-user: + value: 9.999930e-02 +a1ddf6510/cpu-4/cpu-wait: + value: 0.000000e+00 +a1ddf6510/cpu-5/cpu-idle: + value: 9.999932e+01 +a1ddf6510/cpu-5/cpu-interrupt: + value: 0.000000e+00 +a1ddf6510/cpu-5/cpu-nice: + value: 0.000000e+00 +a1ddf6510/cpu-5/cpu-softirq: + value: 0.000000e+00 +a1ddf6510/cpu-5/cpu-steal: + value: 0.000000e+00 +a1ddf6510/cpu-5/cpu-system: + value: 0.000000e+00 +a1ddf6510/cpu-5/cpu-user: + value: 0.000000e+00 +a1ddf6510/cpu-5/cpu-wait: + value: 0.000000e+00 +a1ddf6510/cpu-6/cpu-idle: + value: 9.589926e+01 +a1ddf6510/cpu-6/cpu-interrupt: + value: 0.000000e+00 +a1ddf6510/cpu-6/cpu-nice: + value: 0.000000e+00 +a1ddf6510/cpu-6/cpu-softirq: + value: 0.000000e+00 +a1ddf6510/cpu-6/cpu-steal: + value: 0.000000e+00 +a1ddf6510/cpu-6/cpu-system: + value: 2.099986e+00 +a1ddf6510/cpu-6/cpu-user: + value: 1.999987e+00 +a1ddf6510/cpu-6/cpu-wait: + value: 0.000000e+00 +a1ddf6510/cpu-7/cpu-idle: + value: 9.679919e+01 +a1ddf6510/cpu-7/cpu-interrupt: + value: 0.000000e+00 +a1ddf6510/cpu-7/cpu-nice: + value: 0.000000e+00 +a1ddf6510/cpu-7/cpu-softirq: + value: 0.000000e+00 +a1ddf6510/cpu-7/cpu-steal: + value: 0.000000e+00 +a1ddf6510/cpu-7/cpu-system: + value: 2.199982e+00 +a1ddf6510/cpu-7/cpu-user: + value: 1.099991e+00 +a1ddf6510/cpu-7/cpu-wait: + value: 0.000000e+00 +a1ddf6510/cpu-8/cpu-idle: + value: 9.439919e+01 +a1ddf6510/cpu-8/cpu-interrupt: + value: 0.000000e+00 +a1ddf6510/cpu-8/cpu-nice: + value: 0.000000e+00 +a1ddf6510/cpu-8/cpu-softirq: + value: 0.000000e+00 +a1ddf6510/cpu-8/cpu-steal: + value: 0.000000e+00 +a1ddf6510/cpu-8/cpu-system: + value: 4.399963e+00 +a1ddf6510/cpu-8/cpu-user: + value: 1.099991e+00 +a1ddf6510/cpu-8/cpu-wait: + value: 0.000000e+00 +a1ddf6510/cpu-9/cpu-idle: + value: 9.949910e+01 +a1ddf6510/cpu-9/cpu-interrupt: + value: 0.000000e+00 +a1ddf6510/cpu-9/cpu-nice: + value: 0.000000e+00 +a1ddf6510/cpu-9/cpu-softirq: + value: 0.000000e+00 +a1ddf6510/cpu-9/cpu-steal: + value: 0.000000e+00 +a1ddf6510/cpu-9/cpu-system: + value: 1.999982e-01 +a1ddf6510/cpu-9/cpu-user: + value: 9.999913e-02 +a1ddf6510/cpu-9/cpu-wait: + value: 0.000000e+00 +a1ddf6510/df-boot/df_complex-free: + value: 4.369039e+08 +a1ddf6510/df-boot/df_complex-reserved: + value: 2.684109e+07 +a1ddf6510/df-boot/df_complex-used: + value: 6.467994e+07 +a1ddf6510/df-boot/df_inodes-free: + value: 3.271800e+04 +a1ddf6510/df-boot/df_inodes-reserved: + value: 0.000000e+00 +a1ddf6510/df-boot/df_inodes-used: + value: 5.000000e+01 +a1ddf6510/df-boot/percent_bytes-free: + value: 8.268041e+01 +a1ddf6510/df-boot/percent_bytes-reserved: + value: 5.079451e+00 +a1ddf6510/df-boot/percent_bytes-used: + value: 1.224014e+01 +a1ddf6510/df-boot/percent_inodes-free: + value: 9.984741e+01 +a1ddf6510/df-boot/percent_inodes-reserved: + value: 0.000000e+00 +a1ddf6510/df-boot/percent_inodes-used: + value: 1.525879e-01 +a1ddf6510/df-data1/df_complex-free: + value: 5.378703e+11 +a1ddf6510/df-data1/df_complex-reserved: + value: 2.879652e+10 +a1ddf6510/df-data1/df_complex-used: + value: 2.072412e+08 +a1ddf6510/df-data1/df_inodes-free: + value: 3.522052e+07 +a1ddf6510/df-data1/df_inodes-reserved: + value: 0.000000e+00 +a1ddf6510/df-data1/df_inodes-used: + value: 1.300000e+01 +a1ddf6510/df-data1/percent_bytes-free: + value: 9.488357e+01 +a1ddf6510/df-data1/percent_bytes-reserved: + value: 5.079879e+00 +a1ddf6510/df-data1/percent_bytes-used: + value: 3.655860e-02 +a1ddf6510/df-data1/percent_inodes-free: + value: 9.999996e+01 +a1ddf6510/df-data1/percent_inodes-reserved: + value: 0.000000e+00 +a1ddf6510/df-data1/percent_inodes-used: + value: 3.691029e-05 +a1ddf6510/df-dev-shm/df_complex-free: + value: 3.375725e+10 +a1ddf6510/df-dev-shm/df_complex-reserved: + value: 0.000000e+00 +a1ddf6510/df-dev-shm/df_complex-used: + value: 0.000000e+00 +a1ddf6510/df-dev-shm/df_inodes-free: + value: 8.241515e+06 +a1ddf6510/df-dev-shm/df_inodes-reserved: + value: 0.000000e+00 +a1ddf6510/df-dev-shm/df_inodes-used: + value: 1.000000e+00 +a1ddf6510/df-dev-shm/percent_bytes-free: + value: 1.000000e+02 +a1ddf6510/df-dev-shm/percent_bytes-reserved: + value: 0.000000e+00 +a1ddf6510/df-dev-shm/percent_bytes-used: + value: 0.000000e+00 +a1ddf6510/df-dev-shm/percent_inodes-free: + value: 9.999998e+01 +a1ddf6510/df-dev-shm/percent_inodes-reserved: + value: 0.000000e+00 +a1ddf6510/df-dev-shm/percent_inodes-used: + value: 1.213369e-05 +a1ddf6510/df-root/df_complex-free: + value: 1.057486e+10 +a1ddf6510/df-root/df_complex-reserved: + value: 6.442435e+08 +a1ddf6510/df-root/df_complex-used: + value: 1.463607e+09 +a1ddf6510/df-root/df_inodes-free: + value: 7.435400e+05 +a1ddf6510/df-root/df_inodes-reserved: + value: 0.000000e+00 +a1ddf6510/df-root/df_inodes-used: + value: 4.289200e+04 +a1ddf6510/df-root/percent_bytes-free: + value: 8.338012e+01 +a1ddf6510/df-root/percent_bytes-reserved: + value: 5.079700e+00 +a1ddf6510/df-root/percent_bytes-used: + value: 1.154018e+01 +a1ddf6510/df-root/percent_inodes-free: + value: 9.454601e+01 +a1ddf6510/df-root/percent_inodes-reserved: + value: 0.000000e+00 +a1ddf6510/df-root/percent_inodes-used: + value: 5.454000e+00 +a1ddf6510/df-var/df_complex-free: + value: 6.990479e+09 +a1ddf6510/df-var/df_complex-reserved: + value: 4.294943e+08 +a1ddf6510/df-var/df_complex-used: + value: 1.035145e+09 +a1ddf6510/df-var/df_inodes-free: + value: 5.169860e+05 +a1ddf6510/df-var/df_inodes-reserved: + value: 0.000000e+00 +a1ddf6510/df-var/df_inodes-used: + value: 7.302000e+03 +a1ddf6510/df-var/percent_bytes-free: + value: 8.267748e+01 +a1ddf6510/df-var/percent_bytes-reserved: + value: 5.079695e+00 +a1ddf6510/df-var/percent_bytes-used: + value: 1.224282e+01 +a1ddf6510/df-var/percent_inodes-free: + value: 9.860725e+01 +a1ddf6510/df-var/percent_inodes-reserved: + value: 0.000000e+00 +a1ddf6510/df-var/percent_inodes-used: + value: 1.392746e+00 +a1ddf6510/disk-sda/disk_merged: + read: 0.000000e+00 + write: 0.000000e+00 +a1ddf6510/disk-sda/disk_octets: + read: 0.000000e+00 + write: 2.457548e+03 +a1ddf6510/disk-sda/disk_ops: + read: 0.000000e+00 + write: 5.999873e-01 +a1ddf6510/disk-sda/disk_time: + read: 0.000000e+00 + write: 9.999788e-01 +a1ddf6510/disk-sda1/disk_merged: + read: 0.000000e+00 + write: 0.000000e+00 +a1ddf6510/disk-sda1/disk_octets: + read: 0.000000e+00 + write: 0.000000e+00 +a1ddf6510/disk-sda1/disk_ops: + read: 0.000000e+00 + write: 0.000000e+00 +a1ddf6510/disk-sda1/disk_time: + read: 0.000000e+00 + write: 0.000000e+00 +a1ddf6510/disk-sda2/disk_merged: + read: 0.000000e+00 + write: 0.000000e+00 +a1ddf6510/disk-sda2/disk_octets: + read: 0.000000e+00 + write: 2.457548e+03 +a1ddf6510/disk-sda2/disk_ops: + read: 0.000000e+00 + write: 5.999872e-01 +a1ddf6510/disk-sda2/disk_time: + read: 0.000000e+00 + write: 9.999786e-01 +a1ddf6510/disk-sda3/disk_merged: + read: 0.000000e+00 + write: 0.000000e+00 +a1ddf6510/disk-sda3/disk_octets: + read: 0.000000e+00 + write: 0.000000e+00 +a1ddf6510/disk-sda3/disk_ops: + read: 0.000000e+00 + write: 0.000000e+00 +a1ddf6510/disk-sda3/disk_time: + read: 0.000000e+00 + write: 0.000000e+00 +a1ddf6510/disk-sda4/disk_merged: + read: 0.000000e+00 + write: 0.000000e+00 +a1ddf6510/disk-sda4/disk_octets: + read: 0.000000e+00 + write: 0.000000e+00 +a1ddf6510/disk-sda4/disk_ops: + read: 0.000000e+00 + write: 0.000000e+00 +a1ddf6510/disk-sda4/disk_time: + read: 0.000000e+00 + write: 0.000000e+00 +a1ddf6510/disk-sda5/disk_merged: + read: 0.000000e+00 + write: 0.000000e+00 +a1ddf6510/disk-sda5/disk_octets: + read: 0.000000e+00 + write: 0.000000e+00 +a1ddf6510/disk-sda5/disk_ops: + read: 0.000000e+00 + write: 0.000000e+00 +a1ddf6510/disk-sda5/disk_time: + read: 0.000000e+00 + write: 0.000000e+00 +a1ddf6510/disk-sda6/disk_merged: + read: 0.000000e+00 + write: 0.000000e+00 +a1ddf6510/disk-sda6/disk_octets: + read: 0.000000e+00 + write: 0.000000e+00 +a1ddf6510/disk-sda6/disk_ops: + read: 0.000000e+00 + write: 0.000000e+00 +a1ddf6510/disk-sda6/disk_time: + read: 0.000000e+00 + write: 0.000000e+00 +a1ddf6510/load/load: + longterm: 0.000000e+00 + midterm: 0.000000e+00 + shortterm: 0.000000e+00 +a1ddf6510/memory/memory-buffered: + value: 2.371871e+08 +a1ddf6510/memory/memory-cached: + value: 1.447993e+09 +a1ddf6510/memory/memory-free: + value: 6.351406e+10 +a1ddf6510/memory/memory-used: + value: 2.315260e+09 +a1ddf6510/network/if_octets: + rx: 0.000000e+00 + tx: 1.052800e+03 +a1ddf6510/network/if_packets: + rx: 0.000000e+00 + tx: 8.000000e-01 +a1ddf6510/network/queue_length: + value: 0.000000e+00 +a1ddf6510/network/total_values-dispatch-accepted: + value: 0.000000e+00 +a1ddf6510/network/total_values-dispatch-rejected: + value: 0.000000e+00 +a1ddf6510/network/total_values-send-accepted: + value: 2.280001e+01 +a1ddf6510/network/total_values-send-rejected: + value: 0.000000e+00 +a1ddf6510/swap/swap-cached: + value: 0.000000e+00 +a1ddf6510/swap/swap-free: + value: 2.147475e+09 +a1ddf6510/swap/swap-used: + value: 0.000000e+00 +a1ddf6510/swap/swap_io-in: + value: 0.000000e+00 +a1ddf6510/swap/swap_io-out: + value: 0.000000e+00 +a1ddf6510/vmem/vmpage_faults: + majflt: 0.000000e+00 + minflt: 3.700034e+00 +a1ddf6510/vmem/vmpage_io-memory: + in: 0.000000e+00 + out: 0.000000e+00 +a1ddf6510/vmem/vmpage_io-swap: + in: 0.000000e+00 + out: 0.000000e+00 +a1ddf6510/vmem/vmpage_number-active_anon: + value: 8.369400e+04 +a1ddf6510/vmem/vmpage_number-active_file: + value: 2.449340e+05 +a1ddf6510/vmem/vmpage_number-anon_pages: + value: 4.576400e+04 +a1ddf6510/vmem/vmpage_number-anon_transparent_hugepages: + value: 7.500000e+01 +a1ddf6510/vmem/vmpage_number-boudfe: + value: 0.000000e+00 +a1ddf6510/vmem/vmpage_number-dirty: + value: 1.000000e+00 +a1ddf6510/vmem/vmpage_number-file_pages: + value: 4.114210e+05 +a1ddf6510/vmem/vmpage_number-free_pages: + value: 1.550636e+07 +a1ddf6510/vmem/vmpage_number-inactive_anon: + value: 2.130000e+02 +a1ddf6510/vmem/vmpage_number-inactive_file: + value: 1.662360e+05 +a1ddf6510/vmem/vmpage_number-isolated_anon: + value: 0.000000e+00 +a1ddf6510/vmem/vmpage_number-isolated_file: + value: 0.000000e+00 +a1ddf6510/vmem/vmpage_number-kernel_stack: + value: 3.110000e+02 +a1ddf6510/vmem/vmpage_number-mapped: + value: 6.615000e+03 +a1ddf6510/vmem/vmpage_number-mlock: + value: 0.000000e+00 +a1ddf6510/vmem/vmpage_number-page_table_pages: + value: 2.683000e+03 +a1ddf6510/vmem/vmpage_number-shmem: + value: 2.550000e+02 +a1ddf6510/vmem/vmpage_number-slab_reclaimable: + value: 3.633060e+05 +a1ddf6510/vmem/vmpage_number-slab_unreclaimable: + value: 1.422200e+04 +a1ddf6510/vmem/vmpage_number-unevictable: + value: 0.000000e+00 +a1ddf6510/vmem/vmpage_number-unstable: + value: 0.000000e+00 +a1ddf6510/vmem/vmpage_number-vmscan_write: + value: 0.000000e+00 +a1ddf6510/vmem/vmpage_number-writeback: + value: 0.000000e+00 +a1ddf6510/vmem/vmpage_number-writeback_temp: + value: 0.000000e+00 +a1ddf6610/cpu-0/cpu-idle: + value: 8.969821e+01 +a1ddf6610/cpu-0/cpu-interrupt: + value: 0.000000e+00 +a1ddf6610/cpu-0/cpu-nice: + value: 0.000000e+00 +a1ddf6610/cpu-0/cpu-softirq: + value: 1.099984e+00 +a1ddf6610/cpu-0/cpu-steal: + value: 0.000000e+00 +a1ddf6610/cpu-0/cpu-system: + value: 3.499955e+00 +a1ddf6610/cpu-0/cpu-user: + value: 2.199975e+00 +a1ddf6610/cpu-0/cpu-wait: + value: 0.000000e+00 +a1ddf6610/cpu-1/cpu-idle: + value: 9.719322e+01 +a1ddf6610/cpu-1/cpu-interrupt: + value: 0.000000e+00 +a1ddf6610/cpu-1/cpu-nice: + value: 0.000000e+00 +a1ddf6610/cpu-1/cpu-softirq: + value: 0.000000e+00 +a1ddf6610/cpu-1/cpu-steal: + value: 0.000000e+00 +a1ddf6610/cpu-1/cpu-system: + value: 1.899957e+00 +a1ddf6610/cpu-1/cpu-user: + value: 5.999838e-01 +a1ddf6610/cpu-1/cpu-wait: + value: 0.000000e+00 +a1ddf6610/cpu-10/cpu-idle: + value: 9.979814e+01 +a1ddf6610/cpu-10/cpu-interrupt: + value: 0.000000e+00 +a1ddf6610/cpu-10/cpu-nice: + value: 0.000000e+00 +a1ddf6610/cpu-10/cpu-softirq: + value: 0.000000e+00 +a1ddf6610/cpu-10/cpu-steal: + value: 0.000000e+00 +a1ddf6610/cpu-10/cpu-system: + value: 9.999814e-02 +a1ddf6610/cpu-10/cpu-user: + value: 0.000000e+00 +a1ddf6610/cpu-10/cpu-wait: + value: 0.000000e+00 +a1ddf6610/cpu-11/cpu-idle: + value: 9.979789e+01 +a1ddf6610/cpu-11/cpu-interrupt: + value: 0.000000e+00 +a1ddf6610/cpu-11/cpu-nice: + value: 0.000000e+00 +a1ddf6610/cpu-11/cpu-softirq: + value: 0.000000e+00 +a1ddf6610/cpu-11/cpu-steal: + value: 0.000000e+00 +a1ddf6610/cpu-11/cpu-system: + value: 9.999790e-02 +a1ddf6610/cpu-11/cpu-user: + value: 0.000000e+00 +a1ddf6610/cpu-11/cpu-wait: + value: 0.000000e+00 +a1ddf6610/cpu-12/cpu-idle: + value: 9.709848e+01 +a1ddf6610/cpu-12/cpu-interrupt: + value: 0.000000e+00 +a1ddf6610/cpu-12/cpu-nice: + value: 0.000000e+00 +a1ddf6610/cpu-12/cpu-softirq: + value: 0.000000e+00 +a1ddf6610/cpu-12/cpu-steal: + value: 0.000000e+00 +a1ddf6610/cpu-12/cpu-system: + value: 1.599972e+00 +a1ddf6610/cpu-12/cpu-user: + value: 1.199978e+00 +a1ddf6610/cpu-12/cpu-wait: + value: 0.000000e+00 +a1ddf6610/cpu-13/cpu-idle: + value: 7.879859e+01 +a1ddf6610/cpu-13/cpu-interrupt: + value: 0.000000e+00 +a1ddf6610/cpu-13/cpu-nice: + value: 0.000000e+00 +a1ddf6610/cpu-13/cpu-softirq: + value: 0.000000e+00 +a1ddf6610/cpu-13/cpu-steal: + value: 0.000000e+00 +a1ddf6610/cpu-13/cpu-system: + value: 1.309976e+01 +a1ddf6610/cpu-13/cpu-user: + value: 8.099863e+00 +a1ddf6610/cpu-13/cpu-wait: + value: 0.000000e+00 +a1ddf6610/cpu-14/cpu-idle: + value: 9.309875e+01 +a1ddf6610/cpu-14/cpu-interrupt: + value: 0.000000e+00 +a1ddf6610/cpu-14/cpu-nice: + value: 0.000000e+00 +a1ddf6610/cpu-14/cpu-softirq: + value: 0.000000e+00 +a1ddf6610/cpu-14/cpu-steal: + value: 0.000000e+00 +a1ddf6610/cpu-14/cpu-system: + value: 4.699934e+00 +a1ddf6610/cpu-14/cpu-user: + value: 2.099971e+00 +a1ddf6610/cpu-14/cpu-wait: + value: 0.000000e+00 +a1ddf6610/cpu-15/cpu-idle: + value: 8.789892e+01 +a1ddf6610/cpu-15/cpu-interrupt: + value: 0.000000e+00 +a1ddf6610/cpu-15/cpu-nice: + value: 0.000000e+00 +a1ddf6610/cpu-15/cpu-softirq: + value: 0.000000e+00 +a1ddf6610/cpu-15/cpu-steal: + value: 0.000000e+00 +a1ddf6610/cpu-15/cpu-system: + value: 7.999894e+00 +a1ddf6610/cpu-15/cpu-user: + value: 3.599950e+00 +a1ddf6610/cpu-15/cpu-wait: + value: 0.000000e+00 +a1ddf6610/cpu-16/cpu-idle: + value: 9.959880e+01 +a1ddf6610/cpu-16/cpu-interrupt: + value: 0.000000e+00 +a1ddf6610/cpu-16/cpu-nice: + value: 0.000000e+00 +a1ddf6610/cpu-16/cpu-softirq: + value: 0.000000e+00 +a1ddf6610/cpu-16/cpu-steal: + value: 0.000000e+00 +a1ddf6610/cpu-16/cpu-system: + value: 2.999964e-01 +a1ddf6610/cpu-16/cpu-user: + value: 9.999874e-02 +a1ddf6610/cpu-16/cpu-wait: + value: 0.000000e+00 +a1ddf6610/cpu-17/cpu-idle: + value: 9.959911e+01 +a1ddf6610/cpu-17/cpu-interrupt: + value: 0.000000e+00 +a1ddf6610/cpu-17/cpu-nice: + value: 0.000000e+00 +a1ddf6610/cpu-17/cpu-softirq: + value: 0.000000e+00 +a1ddf6610/cpu-17/cpu-steal: + value: 0.000000e+00 +a1ddf6610/cpu-17/cpu-system: + value: 1.999981e-01 +a1ddf6610/cpu-17/cpu-user: + value: 9.999911e-02 +a1ddf6610/cpu-17/cpu-wait: + value: 0.000000e+00 +a1ddf6610/cpu-18/cpu-idle: + value: 9.519927e+01 +a1ddf6610/cpu-18/cpu-interrupt: + value: 0.000000e+00 +a1ddf6610/cpu-18/cpu-nice: + value: 0.000000e+00 +a1ddf6610/cpu-18/cpu-softirq: + value: 0.000000e+00 +a1ddf6610/cpu-18/cpu-steal: + value: 0.000000e+00 +a1ddf6610/cpu-18/cpu-system: + value: 2.499979e+00 +a1ddf6610/cpu-18/cpu-user: + value: 1.899982e+00 +a1ddf6610/cpu-18/cpu-wait: + value: 0.000000e+00 +a1ddf6610/cpu-19/cpu-idle: + value: 8.319942e+01 +a1ddf6610/cpu-19/cpu-interrupt: + value: 0.000000e+00 +a1ddf6610/cpu-19/cpu-nice: + value: 0.000000e+00 +a1ddf6610/cpu-19/cpu-softirq: + value: 0.000000e+00 +a1ddf6610/cpu-19/cpu-steal: + value: 0.000000e+00 +a1ddf6610/cpu-19/cpu-system: + value: 1.189992e+01 +a1ddf6610/cpu-19/cpu-user: + value: 3.999985e+00 +a1ddf6610/cpu-19/cpu-wait: + value: 0.000000e+00 +a1ddf6610/cpu-2/cpu-idle: + value: 9.899200e+01 +a1ddf6610/cpu-2/cpu-interrupt: + value: 0.000000e+00 +a1ddf6610/cpu-2/cpu-nice: + value: 0.000000e+00 +a1ddf6610/cpu-2/cpu-softirq: + value: 0.000000e+00 +a1ddf6610/cpu-2/cpu-steal: + value: 0.000000e+00 +a1ddf6610/cpu-2/cpu-system: + value: 3.999674e-01 +a1ddf6610/cpu-2/cpu-user: + value: 2.999799e-01 +a1ddf6610/cpu-2/cpu-wait: + value: 0.000000e+00 +a1ddf6610/cpu-20/cpu-idle: + value: 9.389955e+01 +a1ddf6610/cpu-20/cpu-interrupt: + value: 0.000000e+00 +a1ddf6610/cpu-20/cpu-nice: + value: 0.000000e+00 +a1ddf6610/cpu-20/cpu-softirq: + value: 0.000000e+00 +a1ddf6610/cpu-20/cpu-steal: + value: 0.000000e+00 +a1ddf6610/cpu-20/cpu-system: + value: 4.199980e+00 +a1ddf6610/cpu-20/cpu-user: + value: 1.399991e+00 +a1ddf6610/cpu-20/cpu-wait: + value: 0.000000e+00 +a1ddf6610/cpu-21/cpu-idle: + value: 8.779956e+01 +a1ddf6610/cpu-21/cpu-interrupt: + value: 0.000000e+00 +a1ddf6610/cpu-21/cpu-nice: + value: 0.000000e+00 +a1ddf6610/cpu-21/cpu-softirq: + value: 0.000000e+00 +a1ddf6610/cpu-21/cpu-steal: + value: 0.000000e+00 +a1ddf6610/cpu-21/cpu-system: + value: 8.199940e+00 +a1ddf6610/cpu-21/cpu-user: + value: 3.599972e+00 +a1ddf6610/cpu-21/cpu-wait: + value: 0.000000e+00 +a1ddf6610/cpu-22/cpu-idle: + value: 9.959932e+01 +a1ddf6610/cpu-22/cpu-interrupt: + value: 0.000000e+00 +a1ddf6610/cpu-22/cpu-nice: + value: 0.000000e+00 +a1ddf6610/cpu-22/cpu-softirq: + value: 0.000000e+00 +a1ddf6610/cpu-22/cpu-steal: + value: 0.000000e+00 +a1ddf6610/cpu-22/cpu-system: + value: 2.999981e-01 +a1ddf6610/cpu-22/cpu-user: + value: 9.999956e-02 +a1ddf6610/cpu-22/cpu-wait: + value: 0.000000e+00 +a1ddf6610/cpu-23/cpu-idle: + value: 9.929916e+01 +a1ddf6610/cpu-23/cpu-interrupt: + value: 0.000000e+00 +a1ddf6610/cpu-23/cpu-nice: + value: 0.000000e+00 +a1ddf6610/cpu-23/cpu-softirq: + value: 0.000000e+00 +a1ddf6610/cpu-23/cpu-steal: + value: 0.000000e+00 +a1ddf6610/cpu-23/cpu-system: + value: 4.999943e-01 +a1ddf6610/cpu-23/cpu-user: + value: 0.000000e+00 +a1ddf6610/cpu-23/cpu-wait: + value: 0.000000e+00 +a1ddf6610/cpu-3/cpu-idle: + value: 9.949283e+01 +a1ddf6610/cpu-3/cpu-interrupt: + value: 0.000000e+00 +a1ddf6610/cpu-3/cpu-nice: + value: 0.000000e+00 +a1ddf6610/cpu-3/cpu-softirq: + value: 0.000000e+00 +a1ddf6610/cpu-3/cpu-steal: + value: 0.000000e+00 +a1ddf6610/cpu-3/cpu-system: + value: 9.999309e-02 +a1ddf6610/cpu-3/cpu-user: + value: 1.999852e-01 +a1ddf6610/cpu-3/cpu-wait: + value: 0.000000e+00 +a1ddf6610/cpu-4/cpu-idle: + value: 9.989305e+01 +a1ddf6610/cpu-4/cpu-interrupt: + value: 0.000000e+00 +a1ddf6610/cpu-4/cpu-nice: + value: 0.000000e+00 +a1ddf6610/cpu-4/cpu-softirq: + value: 0.000000e+00 +a1ddf6610/cpu-4/cpu-steal: + value: 0.000000e+00 +a1ddf6610/cpu-4/cpu-system: + value: 0.000000e+00 +a1ddf6610/cpu-4/cpu-user: + value: 0.000000e+00 +a1ddf6610/cpu-4/cpu-wait: + value: 0.000000e+00 +a1ddf6610/cpu-5/cpu-idle: + value: 9.989362e+01 +a1ddf6610/cpu-5/cpu-interrupt: + value: 0.000000e+00 +a1ddf6610/cpu-5/cpu-nice: + value: 0.000000e+00 +a1ddf6610/cpu-5/cpu-softirq: + value: 0.000000e+00 +a1ddf6610/cpu-5/cpu-steal: + value: 0.000000e+00 +a1ddf6610/cpu-5/cpu-system: + value: 9.999406e-02 +a1ddf6610/cpu-5/cpu-user: + value: 0.000000e+00 +a1ddf6610/cpu-5/cpu-wait: + value: 0.000000e+00 +a1ddf6610/cpu-6/cpu-idle: + value: 9.469571e+01 +a1ddf6610/cpu-6/cpu-interrupt: + value: 0.000000e+00 +a1ddf6610/cpu-6/cpu-nice: + value: 0.000000e+00 +a1ddf6610/cpu-6/cpu-softirq: + value: 0.000000e+00 +a1ddf6610/cpu-6/cpu-steal: + value: 0.000000e+00 +a1ddf6610/cpu-6/cpu-system: + value: 3.499803e+00 +a1ddf6610/cpu-6/cpu-user: + value: 1.199947e+00 +a1ddf6610/cpu-6/cpu-wait: + value: 0.000000e+00 +a1ddf6610/cpu-7/cpu-idle: + value: 9.819573e+01 +a1ddf6610/cpu-7/cpu-interrupt: + value: 0.000000e+00 +a1ddf6610/cpu-7/cpu-nice: + value: 0.000000e+00 +a1ddf6610/cpu-7/cpu-softirq: + value: 0.000000e+00 +a1ddf6610/cpu-7/cpu-steal: + value: 0.000000e+00 +a1ddf6610/cpu-7/cpu-system: + value: 1.299941e+00 +a1ddf6610/cpu-7/cpu-user: + value: 2.999861e-01 +a1ddf6610/cpu-7/cpu-wait: + value: 0.000000e+00 +a1ddf6610/cpu-8/cpu-idle: + value: 9.929729e+01 +a1ddf6610/cpu-8/cpu-interrupt: + value: 0.000000e+00 +a1ddf6610/cpu-8/cpu-nice: + value: 0.000000e+00 +a1ddf6610/cpu-8/cpu-softirq: + value: 0.000000e+00 +a1ddf6610/cpu-8/cpu-steal: + value: 0.000000e+00 +a1ddf6610/cpu-8/cpu-system: + value: 1.999943e-01 +a1ddf6610/cpu-8/cpu-user: + value: 9.999644e-02 +a1ddf6610/cpu-8/cpu-wait: + value: 0.000000e+00 +a1ddf6610/cpu-9/cpu-idle: + value: 9.989737e+01 +a1ddf6610/cpu-9/cpu-interrupt: + value: 0.000000e+00 +a1ddf6610/cpu-9/cpu-nice: + value: 0.000000e+00 +a1ddf6610/cpu-9/cpu-softirq: + value: 0.000000e+00 +a1ddf6610/cpu-9/cpu-steal: + value: 0.000000e+00 +a1ddf6610/cpu-9/cpu-system: + value: 9.999736e-02 +a1ddf6610/cpu-9/cpu-user: + value: 0.000000e+00 +a1ddf6610/cpu-9/cpu-wait: + value: 0.000000e+00 +a1ddf6610/df-boot/df_complex-free: + value: 4.793754e+08 +a1ddf6610/df-boot/df_complex-reserved: + value: 2.684109e+07 +a1ddf6610/df-boot/df_complex-used: + value: 2.220851e+07 +a1ddf6610/df-boot/df_inodes-free: + value: 3.273000e+04 +a1ddf6610/df-boot/df_inodes-reserved: + value: 0.000000e+00 +a1ddf6610/df-boot/df_inodes-used: + value: 3.800000e+01 +a1ddf6610/df-boot/percent_bytes-free: + value: 9.071777e+01 +a1ddf6610/df-boot/percent_bytes-reserved: + value: 5.079451e+00 +a1ddf6610/df-boot/percent_bytes-used: + value: 4.202775e+00 +a1ddf6610/df-boot/percent_inodes-free: + value: 9.988403e+01 +a1ddf6610/df-boot/percent_inodes-reserved: + value: 0.000000e+00 +a1ddf6610/df-boot/percent_inodes-used: + value: 1.159668e-01 +a1ddf6610/df-data1/df_complex-free: + value: 2.574899e+11 +a1ddf6610/df-data1/df_complex-reserved: + value: 1.379019e+10 +a1ddf6610/df-data1/df_complex-used: + value: 1.961411e+08 +a1ddf6610/df-data1/df_inodes-free: + value: 1.683454e+07 +a1ddf6610/df-data1/df_inodes-reserved: + value: 0.000000e+00 +a1ddf6610/df-data1/df_inodes-used: + value: 1.800000e+01 +a1ddf6610/df-data1/percent_bytes-free: + value: 9.484805e+01 +a1ddf6610/df-data1/percent_bytes-reserved: + value: 5.079704e+00 +a1ddf6610/df-data1/percent_bytes-used: + value: 7.224981e-02 +a1ddf6610/df-data1/percent_inodes-free: + value: 9.999989e+01 +a1ddf6610/df-data1/percent_inodes-reserved: + value: 0.000000e+00 +a1ddf6610/df-data1/percent_inodes-used: + value: 1.069229e-04 +a1ddf6610/df-dev-shm/df_complex-free: + value: 3.375709e+10 +a1ddf6610/df-dev-shm/df_complex-reserved: + value: 0.000000e+00 +a1ddf6610/df-dev-shm/df_complex-used: + value: 0.000000e+00 +a1ddf6610/df-dev-shm/df_inodes-free: + value: 8.241475e+06 +a1ddf6610/df-dev-shm/df_inodes-reserved: + value: 0.000000e+00 +a1ddf6610/df-dev-shm/df_inodes-used: + value: 1.000000e+00 +a1ddf6610/df-dev-shm/percent_bytes-free: + value: 1.000000e+02 +a1ddf6610/df-dev-shm/percent_bytes-reserved: + value: 0.000000e+00 +a1ddf6610/df-dev-shm/percent_bytes-used: + value: 0.000000e+00 +a1ddf6610/df-dev-shm/percent_inodes-free: + value: 9.999998e+01 +a1ddf6610/df-dev-shm/percent_inodes-reserved: + value: 0.000000e+00 +a1ddf6610/df-dev-shm/percent_inodes-used: + value: 1.213375e-05 +a1ddf6610/df-root/df_complex-free: + value: 1.030392e+10 +a1ddf6610/df-root/df_complex-reserved: + value: 6.442435e+08 +a1ddf6610/df-root/df_complex-used: + value: 1.734545e+09 +a1ddf6610/df-root/df_inodes-free: + value: 7.387960e+05 +a1ddf6610/df-root/df_inodes-reserved: + value: 0.000000e+00 +a1ddf6610/df-root/df_inodes-used: + value: 4.763600e+04 +a1ddf6610/df-root/percent_bytes-free: + value: 8.124384e+01 +a1ddf6610/df-root/percent_bytes-reserved: + value: 5.079700e+00 +a1ddf6610/df-root/percent_bytes-used: + value: 1.367646e+01 +a1ddf6610/df-root/percent_inodes-free: + value: 9.394276e+01 +a1ddf6610/df-root/percent_inodes-reserved: + value: 0.000000e+00 +a1ddf6610/df-root/percent_inodes-used: + value: 6.057231e+00 +a1ddf6610/df-var/df_complex-free: + value: 5.412876e+09 +a1ddf6610/df-var/df_complex-reserved: + value: 4.294943e+08 +a1ddf6610/df-var/df_complex-used: + value: 2.612748e+09 +a1ddf6610/df-var/df_inodes-free: + value: 5.218510e+05 +a1ddf6610/df-var/df_inodes-reserved: + value: 0.000000e+00 +a1ddf6610/df-var/df_inodes-used: + value: 2.437000e+03 +a1ddf6610/df-var/percent_bytes-free: + value: 6.401893e+01 +a1ddf6610/df-var/percent_bytes-reserved: + value: 5.079695e+00 +a1ddf6610/df-var/percent_bytes-used: + value: 3.090138e+01 +a1ddf6610/df-var/percent_inodes-free: + value: 9.953518e+01 +a1ddf6610/df-var/percent_inodes-reserved: + value: 0.000000e+00 +a1ddf6610/df-var/percent_inodes-used: + value: 4.648209e-01 +a1ddf6610/disk-sda/disk_merged: + read: 0.000000e+00 + write: 1.224974e+02 +a1ddf6610/disk-sda/disk_octets: + read: 0.000000e+00 + write: 5.377975e+05 +a1ddf6610/disk-sda/disk_ops: + read: 0.000000e+00 + write: 8.799739e+00 +a1ddf6610/disk-sda/disk_time: + read: 0.000000e+00 + write: 1.599958e+00 +a1ddf6610/disk-sda1/disk_merged: + read: 0.000000e+00 + write: 0.000000e+00 +a1ddf6610/disk-sda1/disk_octets: + read: 0.000000e+00 + write: 0.000000e+00 +a1ddf6610/disk-sda1/disk_ops: + read: 0.000000e+00 + write: 0.000000e+00 +a1ddf6610/disk-sda1/disk_time: + read: 0.000000e+00 + write: 0.000000e+00 +a1ddf6610/disk-sda2/disk_merged: + read: 0.000000e+00 + write: 1.148967e+02 +a1ddf6610/disk-sda2/disk_octets: + read: 0.000000e+00 + write: 4.829033e+05 +a1ddf6610/disk-sda2/disk_ops: + read: 0.000000e+00 + write: 2.999895e+00 +a1ddf6610/disk-sda2/disk_time: + read: 0.000000e+00 + write: 3.999861e-01 +a1ddf6610/disk-sda3/disk_merged: + read: 0.000000e+00 + write: 7.599447e+00 +a1ddf6610/disk-sda3/disk_octets: + read: 0.000000e+00 + write: 5.488478e+04 +a1ddf6610/disk-sda3/disk_ops: + read: 0.000000e+00 + write: 5.799747e+00 +a1ddf6610/disk-sda3/disk_time: + read: 0.000000e+00 + write: 2.299833e+00 +a1ddf6610/disk-sda4/disk_merged: + read: 0.000000e+00 + write: 0.000000e+00 +a1ddf6610/disk-sda4/disk_octets: + read: 0.000000e+00 + write: 0.000000e+00 +a1ddf6610/disk-sda4/disk_ops: + read: 0.000000e+00 + write: 0.000000e+00 +a1ddf6610/disk-sda4/disk_time: + read: 0.000000e+00 + write: 0.000000e+00 +a1ddf6610/disk-sda5/disk_merged: + read: 0.000000e+00 + write: 0.000000e+00 +a1ddf6610/disk-sda5/disk_octets: + read: 0.000000e+00 + write: 0.000000e+00 +a1ddf6610/disk-sda5/disk_ops: + read: 0.000000e+00 + write: 0.000000e+00 +a1ddf6610/disk-sda5/disk_time: + read: 0.000000e+00 + write: 0.000000e+00 +a1ddf6610/disk-sda6/disk_merged: + read: 0.000000e+00 + write: 0.000000e+00 +a1ddf6610/disk-sda6/disk_octets: + read: 0.000000e+00 + write: 0.000000e+00 +a1ddf6610/disk-sda6/disk_ops: + read: 0.000000e+00 + write: 0.000000e+00 +a1ddf6610/disk-sda6/disk_time: + read: 0.000000e+00 + write: 0.000000e+00 +a1ddf6610/load/load: + longterm: 2.600000e-01 + midterm: 2.400000e-01 + shortterm: 3.000000e-02 +a1ddf6610/memory/memory-buffered: + value: 2.945802e+08 +a1ddf6610/memory/memory-cached: + value: 2.390438e+09 +a1ddf6610/memory/memory-free: + value: 6.154120e+10 +a1ddf6610/memory/memory-used: + value: 3.287953e+09 +a1ddf6610/network/if_octets: + rx: 2.326949e+04 + tx: 0.000000e+00 +a1ddf6610/network/if_packets: + rx: 1.759976e+01 + tx: 0.000000e+00 +a1ddf6610/network/queue_length: + value: 0.000000e+00 +a1ddf6610/network/total_values-dispatch-accepted: + value: 4.607941e+02 +a1ddf6610/network/total_values-dispatch-rejected: + value: 0.000000e+00 +a1ddf6610/network/total_values-send-accepted: + value: 0.000000e+00 +a1ddf6610/network/total_values-send-rejected: + value: 0.000000e+00 +a1ddf6610/swap/swap-cached: + value: 0.000000e+00 +a1ddf6610/swap/swap-free: + value: 2.147475e+09 +a1ddf6610/swap/swap-used: + value: 0.000000e+00 +a1ddf6610/swap/swap_io-in: + value: 0.000000e+00 +a1ddf6610/swap/swap_io-out: + value: 0.000000e+00 +a1ddf6610/vmem/vmpage_faults: + majflt: 0.000000e+00 + minflt: 1.460435e+05 +a1ddf6610/vmem/vmpage_io-memory: + in: 0.000000e+00 + out: 5.252066e+02 +a1ddf6610/vmem/vmpage_io-swap: + in: 0.000000e+00 + out: 0.000000e+00 +a1ddf6610/vmem/vmpage_number-active_anon: + value: 7.743400e+04 +a1ddf6610/vmem/vmpage_number-active_file: + value: 5.886950e+05 +a1ddf6610/vmem/vmpage_number-anon_pages: + value: 3.168900e+04 +a1ddf6610/vmem/vmpage_number-anon_transparent_hugepages: + value: 8.900000e+01 +a1ddf6610/vmem/vmpage_number-boudfe: + value: 0.000000e+00 +a1ddf6610/vmem/vmpage_number-dirty: + value: 1.217000e+03 +a1ddf6610/vmem/vmpage_number-file_pages: + value: 6.555230e+05 +a1ddf6610/vmem/vmpage_number-free_pages: + value: 1.502482e+07 +a1ddf6610/vmem/vmpage_number-inactive_anon: + value: 1.440000e+02 +a1ddf6610/vmem/vmpage_number-inactive_file: + value: 6.663400e+04 +a1ddf6610/vmem/vmpage_number-isolated_anon: + value: 0.000000e+00 +a1ddf6610/vmem/vmpage_number-isolated_file: + value: 0.000000e+00 +a1ddf6610/vmem/vmpage_number-kernel_stack: + value: 5.050000e+02 +a1ddf6610/vmem/vmpage_number-mapped: + value: 7.061000e+03 +a1ddf6610/vmem/vmpage_number-mlock: + value: 0.000000e+00 +a1ddf6610/vmem/vmpage_number-page_table_pages: + value: 2.714000e+03 +a1ddf6610/vmem/vmpage_number-shmem: + value: 2.010000e+02 +a1ddf6610/vmem/vmpage_number-slab_reclaimable: + value: 5.981700e+05 +a1ddf6610/vmem/vmpage_number-slab_unreclaimable: + value: 1.751300e+04 +a1ddf6610/vmem/vmpage_number-unevictable: + value: 0.000000e+00 +a1ddf6610/vmem/vmpage_number-unstable: + value: 0.000000e+00 +a1ddf6610/vmem/vmpage_number-vmscan_write: + value: 0.000000e+00 +a1ddf6610/vmem/vmpage_number-writeback: + value: 0.000000e+00 +a1ddf6610/vmem/vmpage_number-writeback_temp: + value: 0.000000e+00 +h2gdf6120/cpu-0/cpu-idle: + value: 9.830055e+01 +h2gdf6120/cpu-0/cpu-interrupt: + value: 0.000000e+00 +h2gdf6120/cpu-0/cpu-nice: + value: 0.000000e+00 +h2gdf6120/cpu-0/cpu-softirq: + value: 1.000006e-01 +h2gdf6120/cpu-0/cpu-steal: + value: 0.000000e+00 +h2gdf6120/cpu-0/cpu-system: + value: 2.000012e-01 +h2gdf6120/cpu-0/cpu-user: + value: 7.000045e-01 +h2gdf6120/cpu-0/cpu-wait: + value: 0.000000e+00 +h2gdf6120/cpu-1/cpu-idle: + value: 9.630047e+01 +h2gdf6120/cpu-1/cpu-interrupt: + value: 0.000000e+00 +h2gdf6120/cpu-1/cpu-nice: + value: 0.000000e+00 +h2gdf6120/cpu-1/cpu-softirq: + value: 0.000000e+00 +h2gdf6120/cpu-1/cpu-steal: + value: 0.000000e+00 +h2gdf6120/cpu-1/cpu-system: + value: 5.000024e-01 +h2gdf6120/cpu-1/cpu-user: + value: 3.300017e+00 +h2gdf6120/cpu-1/cpu-wait: + value: 0.000000e+00 +h2gdf6120/cpu-10/cpu-idle: + value: 9.990053e+01 +h2gdf6120/cpu-10/cpu-interrupt: + value: 0.000000e+00 +h2gdf6120/cpu-10/cpu-nice: + value: 0.000000e+00 +h2gdf6120/cpu-10/cpu-softirq: + value: 0.000000e+00 +h2gdf6120/cpu-10/cpu-steal: + value: 0.000000e+00 +h2gdf6120/cpu-10/cpu-system: + value: 0.000000e+00 +h2gdf6120/cpu-10/cpu-user: + value: 1.000005e-01 +h2gdf6120/cpu-10/cpu-wait: + value: 0.000000e+00 +h2gdf6120/cpu-11/cpu-idle: + value: 9.990010e+01 +h2gdf6120/cpu-11/cpu-interrupt: + value: 0.000000e+00 +h2gdf6120/cpu-11/cpu-nice: + value: 0.000000e+00 +h2gdf6120/cpu-11/cpu-softirq: + value: 0.000000e+00 +h2gdf6120/cpu-11/cpu-steal: + value: 0.000000e+00 +h2gdf6120/cpu-11/cpu-system: + value: 0.000000e+00 +h2gdf6120/cpu-11/cpu-user: + value: 0.000000e+00 +h2gdf6120/cpu-11/cpu-wait: + value: 0.000000e+00 +h2gdf6120/cpu-12/cpu-idle: + value: 9.600001e+01 +h2gdf6120/cpu-12/cpu-interrupt: + value: 0.000000e+00 +h2gdf6120/cpu-12/cpu-nice: + value: 0.000000e+00 +h2gdf6120/cpu-12/cpu-softirq: + value: 0.000000e+00 +h2gdf6120/cpu-12/cpu-steal: + value: 0.000000e+00 +h2gdf6120/cpu-12/cpu-system: + value: 7.000001e-01 +h2gdf6120/cpu-12/cpu-user: + value: 2.900000e+00 +h2gdf6120/cpu-12/cpu-wait: + value: 0.000000e+00 +h2gdf6120/cpu-13/cpu-idle: + value: 9.740004e+01 +h2gdf6120/cpu-13/cpu-interrupt: + value: 0.000000e+00 +h2gdf6120/cpu-13/cpu-nice: + value: 0.000000e+00 +h2gdf6120/cpu-13/cpu-softirq: + value: 0.000000e+00 +h2gdf6120/cpu-13/cpu-steal: + value: 0.000000e+00 +h2gdf6120/cpu-13/cpu-system: + value: 2.000001e-01 +h2gdf6120/cpu-13/cpu-user: + value: 2.100001e+00 +h2gdf6120/cpu-13/cpu-wait: + value: 0.000000e+00 +h2gdf6120/cpu-14/cpu-idle: + value: 9.920005e+01 +h2gdf6120/cpu-14/cpu-interrupt: + value: 0.000000e+00 +h2gdf6120/cpu-14/cpu-nice: + value: 0.000000e+00 +h2gdf6120/cpu-14/cpu-softirq: + value: 0.000000e+00 +h2gdf6120/cpu-14/cpu-steal: + value: 0.000000e+00 +h2gdf6120/cpu-14/cpu-system: + value: 1.000000e-01 +h2gdf6120/cpu-14/cpu-user: + value: 6.000003e-01 +h2gdf6120/cpu-14/cpu-wait: + value: 0.000000e+00 +h2gdf6120/cpu-15/cpu-idle: + value: 9.990025e+01 +h2gdf6120/cpu-15/cpu-interrupt: + value: 0.000000e+00 +h2gdf6120/cpu-15/cpu-nice: + value: 0.000000e+00 +h2gdf6120/cpu-15/cpu-softirq: + value: 0.000000e+00 +h2gdf6120/cpu-15/cpu-steal: + value: 0.000000e+00 +h2gdf6120/cpu-15/cpu-system: + value: 1.000002e-01 +h2gdf6120/cpu-15/cpu-user: + value: 0.000000e+00 +h2gdf6120/cpu-15/cpu-wait: + value: 0.000000e+00 +h2gdf6120/cpu-16/cpu-idle: + value: 9.989996e+01 +h2gdf6120/cpu-16/cpu-interrupt: + value: 0.000000e+00 +h2gdf6120/cpu-16/cpu-nice: + value: 0.000000e+00 +h2gdf6120/cpu-16/cpu-softirq: + value: 0.000000e+00 +h2gdf6120/cpu-16/cpu-steal: + value: 0.000000e+00 +h2gdf6120/cpu-16/cpu-system: + value: 0.000000e+00 +h2gdf6120/cpu-16/cpu-user: + value: 1.000000e-01 +h2gdf6120/cpu-16/cpu-wait: + value: 0.000000e+00 +h2gdf6120/cpu-17/cpu-idle: + value: 9.999995e+01 +h2gdf6120/cpu-17/cpu-interrupt: + value: 0.000000e+00 +h2gdf6120/cpu-17/cpu-nice: + value: 0.000000e+00 +h2gdf6120/cpu-17/cpu-softirq: + value: 0.000000e+00 +h2gdf6120/cpu-17/cpu-steal: + value: 0.000000e+00 +h2gdf6120/cpu-17/cpu-system: + value: 0.000000e+00 +h2gdf6120/cpu-17/cpu-user: + value: 0.000000e+00 +h2gdf6120/cpu-17/cpu-wait: + value: 0.000000e+00 +h2gdf6120/cpu-18/cpu-idle: + value: 9.989994e+01 +h2gdf6120/cpu-18/cpu-interrupt: + value: 0.000000e+00 +h2gdf6120/cpu-18/cpu-nice: + value: 0.000000e+00 +h2gdf6120/cpu-18/cpu-softirq: + value: 0.000000e+00 +h2gdf6120/cpu-18/cpu-steal: + value: 0.000000e+00 +h2gdf6120/cpu-18/cpu-system: + value: 0.000000e+00 +h2gdf6120/cpu-18/cpu-user: + value: 9.999997e-02 +h2gdf6120/cpu-18/cpu-wait: + value: 0.000000e+00 +h2gdf6120/cpu-19/cpu-idle: + value: 9.930003e+01 +h2gdf6120/cpu-19/cpu-interrupt: + value: 0.000000e+00 +h2gdf6120/cpu-19/cpu-nice: + value: 0.000000e+00 +h2gdf6120/cpu-19/cpu-softirq: + value: 0.000000e+00 +h2gdf6120/cpu-19/cpu-steal: + value: 0.000000e+00 +h2gdf6120/cpu-19/cpu-system: + value: 9.999996e-02 +h2gdf6120/cpu-19/cpu-user: + value: 4.999998e-01 +h2gdf6120/cpu-19/cpu-wait: + value: 0.000000e+00 +h2gdf6120/cpu-2/cpu-idle: + value: 9.800028e+01 +h2gdf6120/cpu-2/cpu-interrupt: + value: 0.000000e+00 +h2gdf6120/cpu-2/cpu-nice: + value: 0.000000e+00 +h2gdf6120/cpu-2/cpu-softirq: + value: 0.000000e+00 +h2gdf6120/cpu-2/cpu-steal: + value: 0.000000e+00 +h2gdf6120/cpu-2/cpu-system: + value: 3.000009e-01 +h2gdf6120/cpu-2/cpu-user: + value: 2.000007e+00 +h2gdf6120/cpu-2/cpu-wait: + value: 0.000000e+00 +h2gdf6120/cpu-20/cpu-idle: + value: 9.980000e+01 +h2gdf6120/cpu-20/cpu-interrupt: + value: 0.000000e+00 +h2gdf6120/cpu-20/cpu-nice: + value: 0.000000e+00 +h2gdf6120/cpu-20/cpu-softirq: + value: 0.000000e+00 +h2gdf6120/cpu-20/cpu-steal: + value: 0.000000e+00 +h2gdf6120/cpu-20/cpu-system: + value: 9.999990e-02 +h2gdf6120/cpu-20/cpu-user: + value: 0.000000e+00 +h2gdf6120/cpu-20/cpu-wait: + value: 0.000000e+00 +h2gdf6120/cpu-21/cpu-idle: + value: 9.990021e+01 +h2gdf6120/cpu-21/cpu-interrupt: + value: 0.000000e+00 +h2gdf6120/cpu-21/cpu-nice: + value: 0.000000e+00 +h2gdf6120/cpu-21/cpu-softirq: + value: 0.000000e+00 +h2gdf6120/cpu-21/cpu-steal: + value: 0.000000e+00 +h2gdf6120/cpu-21/cpu-system: + value: 0.000000e+00 +h2gdf6120/cpu-21/cpu-user: + value: 0.000000e+00 +h2gdf6120/cpu-21/cpu-wait: + value: 0.000000e+00 +h2gdf6120/cpu-22/cpu-idle: + value: 9.660017e+01 +h2gdf6120/cpu-22/cpu-interrupt: + value: 0.000000e+00 +h2gdf6120/cpu-22/cpu-nice: + value: 0.000000e+00 +h2gdf6120/cpu-22/cpu-softirq: + value: 0.000000e+00 +h2gdf6120/cpu-22/cpu-steal: + value: 0.000000e+00 +h2gdf6120/cpu-22/cpu-system: + value: 1.000002e-01 +h2gdf6120/cpu-22/cpu-user: + value: 3.000008e+00 +h2gdf6120/cpu-22/cpu-wait: + value: 0.000000e+00 +h2gdf6120/cpu-23/cpu-idle: + value: 1.000001e+02 +h2gdf6120/cpu-23/cpu-interrupt: + value: 0.000000e+00 +h2gdf6120/cpu-23/cpu-nice: + value: 0.000000e+00 +h2gdf6120/cpu-23/cpu-softirq: + value: 0.000000e+00 +h2gdf6120/cpu-23/cpu-steal: + value: 0.000000e+00 +h2gdf6120/cpu-23/cpu-system: + value: 0.000000e+00 +h2gdf6120/cpu-23/cpu-user: + value: 0.000000e+00 +h2gdf6120/cpu-23/cpu-wait: + value: 0.000000e+00 +h2gdf6120/cpu-3/cpu-idle: + value: 9.840034e+01 +h2gdf6120/cpu-3/cpu-interrupt: + value: 0.000000e+00 +h2gdf6120/cpu-3/cpu-nice: + value: 0.000000e+00 +h2gdf6120/cpu-3/cpu-softirq: + value: 0.000000e+00 +h2gdf6120/cpu-3/cpu-steal: + value: 0.000000e+00 +h2gdf6120/cpu-3/cpu-system: + value: 3.000008e-01 +h2gdf6120/cpu-3/cpu-user: + value: 1.700004e+00 +h2gdf6120/cpu-3/cpu-wait: + value: 0.000000e+00 +h2gdf6120/cpu-4/cpu-idle: + value: 9.930038e+01 +h2gdf6120/cpu-4/cpu-interrupt: + value: 0.000000e+00 +h2gdf6120/cpu-4/cpu-nice: + value: 0.000000e+00 +h2gdf6120/cpu-4/cpu-softirq: + value: 0.000000e+00 +h2gdf6120/cpu-4/cpu-steal: + value: 0.000000e+00 +h2gdf6120/cpu-4/cpu-system: + value: 1.000004e-01 +h2gdf6120/cpu-4/cpu-user: + value: 5.000020e-01 +h2gdf6120/cpu-4/cpu-wait: + value: 0.000000e+00 +h2gdf6120/cpu-5/cpu-idle: + value: 1.000003e+02 +h2gdf6120/cpu-5/cpu-interrupt: + value: 0.000000e+00 +h2gdf6120/cpu-5/cpu-nice: + value: 0.000000e+00 +h2gdf6120/cpu-5/cpu-softirq: + value: 0.000000e+00 +h2gdf6120/cpu-5/cpu-steal: + value: 0.000000e+00 +h2gdf6120/cpu-5/cpu-system: + value: 0.000000e+00 +h2gdf6120/cpu-5/cpu-user: + value: 0.000000e+00 +h2gdf6120/cpu-5/cpu-wait: + value: 0.000000e+00 +h2gdf6120/cpu-6/cpu-idle: + value: 9.840033e+01 +h2gdf6120/cpu-6/cpu-interrupt: + value: 0.000000e+00 +h2gdf6120/cpu-6/cpu-nice: + value: 0.000000e+00 +h2gdf6120/cpu-6/cpu-softirq: + value: 0.000000e+00 +h2gdf6120/cpu-6/cpu-steal: + value: 0.000000e+00 +h2gdf6120/cpu-6/cpu-system: + value: 3.000009e-01 +h2gdf6120/cpu-6/cpu-user: + value: 1.200004e+00 +h2gdf6120/cpu-6/cpu-wait: + value: 0.000000e+00 +h2gdf6120/cpu-7/cpu-idle: + value: 9.700041e+01 +h2gdf6120/cpu-7/cpu-interrupt: + value: 0.000000e+00 +h2gdf6120/cpu-7/cpu-nice: + value: 0.000000e+00 +h2gdf6120/cpu-7/cpu-softirq: + value: 0.000000e+00 +h2gdf6120/cpu-7/cpu-steal: + value: 0.000000e+00 +h2gdf6120/cpu-7/cpu-system: + value: 2.000008e-01 +h2gdf6120/cpu-7/cpu-user: + value: 2.500009e+00 +h2gdf6120/cpu-7/cpu-wait: + value: 0.000000e+00 +h2gdf6120/cpu-8/cpu-idle: + value: 1.000004e+02 +h2gdf6120/cpu-8/cpu-interrupt: + value: 0.000000e+00 +h2gdf6120/cpu-8/cpu-nice: + value: 0.000000e+00 +h2gdf6120/cpu-8/cpu-softirq: + value: 0.000000e+00 +h2gdf6120/cpu-8/cpu-steal: + value: 0.000000e+00 +h2gdf6120/cpu-8/cpu-system: + value: 0.000000e+00 +h2gdf6120/cpu-8/cpu-user: + value: 0.000000e+00 +h2gdf6120/cpu-8/cpu-wait: + value: 0.000000e+00 +h2gdf6120/cpu-9/cpu-idle: + value: 9.990057e+01 +h2gdf6120/cpu-9/cpu-interrupt: + value: 0.000000e+00 +h2gdf6120/cpu-9/cpu-nice: + value: 0.000000e+00 +h2gdf6120/cpu-9/cpu-softirq: + value: 0.000000e+00 +h2gdf6120/cpu-9/cpu-steal: + value: 0.000000e+00 +h2gdf6120/cpu-9/cpu-system: + value: 0.000000e+00 +h2gdf6120/cpu-9/cpu-user: + value: 0.000000e+00 +h2gdf6120/cpu-9/cpu-wait: + value: 0.000000e+00 +h2gdf6120/df-boot/df_complex-free: + value: 4.325089e+08 +h2gdf6120/df-boot/df_complex-reserved: + value: 2.684109e+07 +h2gdf6120/df-boot/df_complex-used: + value: 6.907494e+07 +h2gdf6120/df-boot/df_inodes-free: + value: 3.271800e+04 +h2gdf6120/df-boot/df_inodes-reserved: + value: 0.000000e+00 +h2gdf6120/df-boot/df_inodes-used: + value: 5.000000e+01 +h2gdf6120/df-boot/percent_bytes-free: + value: 8.184869e+01 +h2gdf6120/df-boot/percent_bytes-reserved: + value: 5.079451e+00 +h2gdf6120/df-boot/percent_bytes-used: + value: 1.307185e+01 +h2gdf6120/df-boot/percent_inodes-free: + value: 9.984741e+01 +h2gdf6120/df-boot/percent_inodes-reserved: + value: 0.000000e+00 +h2gdf6120/df-boot/percent_inodes-used: + value: 1.525879e-01 +h2gdf6120/df-data1/df_complex-free: + value: 2.503070e+11 +h2gdf6120/df-data1/df_complex-reserved: + value: 1.378982e+10 +h2gdf6120/df-data1/df_complex-used: + value: 7.372034e+09 +h2gdf6120/df-data1/df_inodes-free: + value: 1.683450e+07 +h2gdf6120/df-data1/df_inodes-reserved: + value: 0.000000e+00 +h2gdf6120/df-data1/df_inodes-used: + value: 5.900000e+01 +h2gdf6120/df-data1/percent_bytes-free: + value: 9.220468e+01 +h2gdf6120/df-data1/percent_bytes-reserved: + value: 5.079707e+00 +h2gdf6120/df-data1/percent_bytes-used: + value: 2.715609e+00 +h2gdf6120/df-data1/percent_inodes-free: + value: 9.999964e+01 +h2gdf6120/df-data1/percent_inodes-reserved: + value: 0.000000e+00 +h2gdf6120/df-data1/percent_inodes-used: + value: 3.504695e-04 +h2gdf6120/df-dev-shm/df_complex-free: + value: 3.375709e+10 +h2gdf6120/df-dev-shm/df_complex-reserved: + value: 0.000000e+00 +h2gdf6120/df-dev-shm/df_complex-used: + value: 0.000000e+00 +h2gdf6120/df-dev-shm/df_inodes-free: + value: 8.241475e+06 +h2gdf6120/df-dev-shm/df_inodes-reserved: + value: 0.000000e+00 +h2gdf6120/df-dev-shm/df_inodes-used: + value: 1.000000e+00 +h2gdf6120/df-dev-shm/percent_bytes-free: + value: 1.000000e+02 +h2gdf6120/df-dev-shm/percent_bytes-reserved: + value: 0.000000e+00 +h2gdf6120/df-dev-shm/percent_bytes-used: + value: 0.000000e+00 +h2gdf6120/df-dev-shm/percent_inodes-free: + value: 9.999998e+01 +h2gdf6120/df-dev-shm/percent_inodes-reserved: + value: 0.000000e+00 +h2gdf6120/df-dev-shm/percent_inodes-used: + value: 1.213375e-05 +h2gdf6120/df-root/df_complex-free: + value: 1.058675e+10 +h2gdf6120/df-root/df_complex-reserved: + value: 6.442435e+08 +h2gdf6120/df-root/df_complex-used: + value: 1.451717e+09 +h2gdf6120/df-root/df_inodes-free: + value: 7.435350e+05 +h2gdf6120/df-root/df_inodes-reserved: + value: 0.000000e+00 +h2gdf6120/df-root/df_inodes-used: + value: 4.289700e+04 +h2gdf6120/df-root/percent_bytes-free: + value: 8.347388e+01 +h2gdf6120/df-root/percent_bytes-reserved: + value: 5.079700e+00 +h2gdf6120/df-root/percent_bytes-used: + value: 1.144643e+01 +h2gdf6120/df-root/percent_inodes-free: + value: 9.454536e+01 +h2gdf6120/df-root/percent_inodes-reserved: + value: 0.000000e+00 +h2gdf6120/df-root/percent_inodes-used: + value: 5.454636e+00 +h2gdf6120/df-var/df_complex-free: + value: 7.503532e+09 +h2gdf6120/df-var/df_complex-reserved: + value: 4.294943e+08 +h2gdf6120/df-var/df_complex-used: + value: 5.220925e+08 +h2gdf6120/df-var/df_inodes-free: + value: 5.225340e+05 +h2gdf6120/df-var/df_inodes-reserved: + value: 0.000000e+00 +h2gdf6120/df-var/df_inodes-used: + value: 1.754000e+03 +h2gdf6120/df-var/percent_bytes-free: + value: 8.874543e+01 +h2gdf6120/df-var/percent_bytes-reserved: + value: 5.079695e+00 +h2gdf6120/df-var/percent_bytes-used: + value: 6.174870e+00 +h2gdf6120/df-var/percent_inodes-free: + value: 9.966545e+01 +h2gdf6120/df-var/percent_inodes-reserved: + value: 0.000000e+00 +h2gdf6120/df-var/percent_inodes-used: + value: 3.345490e-01 +h2gdf6120/disk-sda/disk_merged: + read: 0.000000e+00 + write: 1.000000e-01 +h2gdf6120/disk-sda/disk_octets: + read: 0.000000e+00 + write: 4.915201e+03 +h2gdf6120/disk-sda/disk_ops: + read: 0.000000e+00 + write: 1.000000e+00 +h2gdf6120/disk-sda/disk_time: + read: 0.000000e+00 + write: 0.000000e+00 +h2gdf6120/disk-sda1/disk_merged: + read: 0.000000e+00 + write: 0.000000e+00 +h2gdf6120/disk-sda1/disk_octets: + read: 0.000000e+00 + write: 0.000000e+00 +h2gdf6120/disk-sda1/disk_ops: + read: 0.000000e+00 + write: 0.000000e+00 +h2gdf6120/disk-sda1/disk_time: + read: 0.000000e+00 + write: 0.000000e+00 +h2gdf6120/disk-sda2/disk_merged: + read: 0.000000e+00 + write: 0.000000e+00 +h2gdf6120/disk-sda2/disk_octets: + read: 0.000000e+00 + write: 0.000000e+00 +h2gdf6120/disk-sda2/disk_ops: + read: 0.000000e+00 + write: 0.000000e+00 +h2gdf6120/disk-sda2/disk_time: + read: 0.000000e+00 + write: 0.000000e+00 +h2gdf6120/disk-sda3/disk_merged: + read: 0.000000e+00 + write: 0.000000e+00 +h2gdf6120/disk-sda3/disk_octets: + read: 0.000000e+00 + write: 1.638401e+03 +h2gdf6120/disk-sda3/disk_ops: + read: 0.000000e+00 + write: 4.000002e-01 +h2gdf6120/disk-sda3/disk_time: + read: 0.000000e+00 + write: 0.000000e+00 +h2gdf6120/disk-sda4/disk_merged: + read: 0.000000e+00 + write: 0.000000e+00 +h2gdf6120/disk-sda4/disk_octets: + read: 0.000000e+00 + write: 0.000000e+00 +h2gdf6120/disk-sda4/disk_ops: + read: 0.000000e+00 + write: 0.000000e+00 +h2gdf6120/disk-sda4/disk_time: + read: 0.000000e+00 + write: 0.000000e+00 +h2gdf6120/disk-sda5/disk_merged: + read: 0.000000e+00 + write: 0.000000e+00 +h2gdf6120/disk-sda5/disk_octets: + read: 0.000000e+00 + write: 0.000000e+00 +h2gdf6120/disk-sda5/disk_ops: + read: 0.000000e+00 + write: 0.000000e+00 +h2gdf6120/disk-sda5/disk_time: + read: 0.000000e+00 + write: 0.000000e+00 +h2gdf6120/disk-sda6/disk_merged: + read: 0.000000e+00 + write: 9.999979e-02 +h2gdf6120/disk-sda6/disk_octets: + read: 0.000000e+00 + write: 3.276793e+03 +h2gdf6120/disk-sda6/disk_ops: + read: 0.000000e+00 + write: 5.999987e-01 +h2gdf6120/disk-sda6/disk_time: + read: 0.000000e+00 + write: 0.000000e+00 +h2gdf6120/load/load: + longterm: 3.000000e-02 + midterm: 3.000000e-02 + shortterm: 0.000000e+00 +h2gdf6120/memory/memory-buffered: + value: 3.471032e+08 +h2gdf6120/memory/memory-cached: + value: 6.819758e+08 +h2gdf6120/memory/memory-free: + value: 5.914347e+10 +h2gdf6120/memory/memory-used: + value: 7.341625e+09 +h2gdf6120/network/if_octets: + rx: 0.000000e+00 + tx: 1.587800e+03 +h2gdf6120/network/if_packets: + rx: 0.000000e+00 + tx: 1.200000e+00 +h2gdf6120/network/queue_length: + value: 0.000000e+00 +h2gdf6120/network/total_values-dispatch-accepted: + value: 0.000000e+00 +h2gdf6120/network/total_values-dispatch-rejected: + value: 0.000000e+00 +h2gdf6120/network/total_values-send-accepted: + value: 3.189999e+01 +h2gdf6120/network/total_values-send-rejected: + value: 0.000000e+00 +h2gdf6120/swap/swap-cached: + value: 0.000000e+00 +h2gdf6120/swap/swap-free: + value: 2.147475e+09 +h2gdf6120/swap/swap-used: + value: 0.000000e+00 +h2gdf6120/swap/swap_io-in: + value: 0.000000e+00 +h2gdf6120/swap/swap_io-out: + value: 0.000000e+00 +h2gdf6120/vmem/vmpage_faults: + majflt: 0.000000e+00 + minflt: 4.499975e+00 +h2gdf6120/vmem/vmpage_io-memory: + in: 0.000000e+00 + out: 8.799950e+00 +h2gdf6120/vmem/vmpage_io-swap: + in: 0.000000e+00 + out: 0.000000e+00 +h2gdf6120/vmem/vmpage_number-active_anon: + value: 1.425964e+06 +h2gdf6120/vmem/vmpage_number-active_file: + value: 1.796950e+05 +h2gdf6120/vmem/vmpage_number-anon_pages: + value: 1.638300e+04 +h2gdf6120/vmem/vmpage_number-anon_transparent_hugepages: + value: 2.753000e+03 +h2gdf6120/vmem/vmpage_number-boudfe: + value: 0.000000e+00 +h2gdf6120/vmem/vmpage_number-dirty: + value: 8.000000e+00 +h2gdf6120/vmem/vmpage_number-file_pages: + value: 2.512400e+05 +h2gdf6120/vmem/vmpage_number-free_pages: + value: 1.443932e+07 +h2gdf6120/vmem/vmpage_number-inactive_anon: + value: 1.100000e+01 +h2gdf6120/vmem/vmpage_number-inactive_file: + value: 7.149200e+04 +h2gdf6120/vmem/vmpage_number-isolated_anon: + value: 0.000000e+00 +h2gdf6120/vmem/vmpage_number-isolated_file: + value: 0.000000e+00 +h2gdf6120/vmem/vmpage_number-kernel_stack: + value: 4.730000e+02 +h2gdf6120/vmem/vmpage_number-mapped: + value: 4.319000e+03 +h2gdf6120/vmem/vmpage_number-mlock: + value: 0.000000e+00 +h2gdf6120/vmem/vmpage_number-page_table_pages: + value: 3.607000e+03 +h2gdf6120/vmem/vmpage_number-shmem: + value: 5.700000e+01 +h2gdf6120/vmem/vmpage_number-slab_reclaimable: + value: 2.365580e+05 +h2gdf6120/vmem/vmpage_number-slab_unreclaimable: + value: 1.603500e+04 +h2gdf6120/vmem/vmpage_number-unevictable: + value: 0.000000e+00 +h2gdf6120/vmem/vmpage_number-unstable: + value: 0.000000e+00 +h2gdf6120/vmem/vmpage_number-vmscan_write: + value: 0.000000e+00 +h2gdf6120/vmem/vmpage_number-writeback: + value: 0.000000e+00 +h2gdf6120/vmem/vmpage_number-writeback_temp: + value: 0.000000e+00 +h2gdf6220/cpu-0/cpu-idle: + value: 9.760209e+01 +h2gdf6220/cpu-0/cpu-interrupt: + value: 0.000000e+00 +h2gdf6220/cpu-0/cpu-nice: + value: 0.000000e+00 +h2gdf6220/cpu-0/cpu-softirq: + value: 1.000040e-01 +h2gdf6220/cpu-0/cpu-steal: + value: 0.000000e+00 +h2gdf6220/cpu-0/cpu-system: + value: 4.000084e-01 +h2gdf6220/cpu-0/cpu-user: + value: 9.999957e-01 +h2gdf6220/cpu-0/cpu-wait: + value: 0.000000e+00 +h2gdf6220/cpu-1/cpu-idle: + value: 9.970561e+01 +h2gdf6220/cpu-1/cpu-interrupt: + value: 0.000000e+00 +h2gdf6220/cpu-1/cpu-nice: + value: 0.000000e+00 +h2gdf6220/cpu-1/cpu-softirq: + value: 0.000000e+00 +h2gdf6220/cpu-1/cpu-steal: + value: 0.000000e+00 +h2gdf6220/cpu-1/cpu-system: + value: 1.000053e-01 +h2gdf6220/cpu-1/cpu-user: + value: 1.000047e-01 +h2gdf6220/cpu-1/cpu-wait: + value: 0.000000e+00 +h2gdf6220/cpu-10/cpu-idle: + value: 9.990600e+01 +h2gdf6220/cpu-10/cpu-interrupt: + value: 0.000000e+00 +h2gdf6220/cpu-10/cpu-nice: + value: 0.000000e+00 +h2gdf6220/cpu-10/cpu-softirq: + value: 0.000000e+00 +h2gdf6220/cpu-10/cpu-steal: + value: 0.000000e+00 +h2gdf6220/cpu-10/cpu-system: + value: 0.000000e+00 +h2gdf6220/cpu-10/cpu-user: + value: 0.000000e+00 +h2gdf6220/cpu-10/cpu-wait: + value: 0.000000e+00 +h2gdf6220/cpu-11/cpu-idle: + value: 1.000060e+02 +h2gdf6220/cpu-11/cpu-interrupt: + value: 0.000000e+00 +h2gdf6220/cpu-11/cpu-nice: + value: 0.000000e+00 +h2gdf6220/cpu-11/cpu-softirq: + value: 0.000000e+00 +h2gdf6220/cpu-11/cpu-steal: + value: 0.000000e+00 +h2gdf6220/cpu-11/cpu-system: + value: 0.000000e+00 +h2gdf6220/cpu-11/cpu-user: + value: 0.000000e+00 +h2gdf6220/cpu-11/cpu-wait: + value: 0.000000e+00 +h2gdf6220/cpu-12/cpu-idle: + value: 9.780591e+01 +h2gdf6220/cpu-12/cpu-interrupt: + value: 0.000000e+00 +h2gdf6220/cpu-12/cpu-nice: + value: 0.000000e+00 +h2gdf6220/cpu-12/cpu-softirq: + value: 0.000000e+00 +h2gdf6220/cpu-12/cpu-steal: + value: 0.000000e+00 +h2gdf6220/cpu-12/cpu-system: + value: 5.000302e-01 +h2gdf6220/cpu-12/cpu-user: + value: 8.000479e-01 +h2gdf6220/cpu-12/cpu-wait: + value: 0.000000e+00 +h2gdf6220/cpu-13/cpu-idle: + value: 9.980613e+01 +h2gdf6220/cpu-13/cpu-interrupt: + value: 0.000000e+00 +h2gdf6220/cpu-13/cpu-nice: + value: 0.000000e+00 +h2gdf6220/cpu-13/cpu-softirq: + value: 0.000000e+00 +h2gdf6220/cpu-13/cpu-steal: + value: 0.000000e+00 +h2gdf6220/cpu-13/cpu-system: + value: 0.000000e+00 +h2gdf6220/cpu-13/cpu-user: + value: 0.000000e+00 +h2gdf6220/cpu-13/cpu-wait: + value: 0.000000e+00 +h2gdf6220/cpu-14/cpu-idle: + value: 1.000061e+02 +h2gdf6220/cpu-14/cpu-interrupt: + value: 0.000000e+00 +h2gdf6220/cpu-14/cpu-nice: + value: 0.000000e+00 +h2gdf6220/cpu-14/cpu-softirq: + value: 0.000000e+00 +h2gdf6220/cpu-14/cpu-steal: + value: 0.000000e+00 +h2gdf6220/cpu-14/cpu-system: + value: 0.000000e+00 +h2gdf6220/cpu-14/cpu-user: + value: 0.000000e+00 +h2gdf6220/cpu-14/cpu-wait: + value: 0.000000e+00 +h2gdf6220/cpu-15/cpu-idle: + value: 9.990596e+01 +h2gdf6220/cpu-15/cpu-interrupt: + value: 0.000000e+00 +h2gdf6220/cpu-15/cpu-nice: + value: 0.000000e+00 +h2gdf6220/cpu-15/cpu-softirq: + value: 0.000000e+00 +h2gdf6220/cpu-15/cpu-steal: + value: 0.000000e+00 +h2gdf6220/cpu-15/cpu-system: + value: 0.000000e+00 +h2gdf6220/cpu-15/cpu-user: + value: 0.000000e+00 +h2gdf6220/cpu-15/cpu-wait: + value: 0.000000e+00 +h2gdf6220/cpu-16/cpu-idle: + value: 9.990572e+01 +h2gdf6220/cpu-16/cpu-interrupt: + value: 0.000000e+00 +h2gdf6220/cpu-16/cpu-nice: + value: 0.000000e+00 +h2gdf6220/cpu-16/cpu-softirq: + value: 0.000000e+00 +h2gdf6220/cpu-16/cpu-steal: + value: 0.000000e+00 +h2gdf6220/cpu-16/cpu-system: + value: 0.000000e+00 +h2gdf6220/cpu-16/cpu-user: + value: 0.000000e+00 +h2gdf6220/cpu-16/cpu-wait: + value: 0.000000e+00 +h2gdf6220/cpu-17/cpu-idle: + value: 1.000057e+02 +h2gdf6220/cpu-17/cpu-interrupt: + value: 0.000000e+00 +h2gdf6220/cpu-17/cpu-nice: + value: 0.000000e+00 +h2gdf6220/cpu-17/cpu-softirq: + value: 0.000000e+00 +h2gdf6220/cpu-17/cpu-steal: + value: 0.000000e+00 +h2gdf6220/cpu-17/cpu-system: + value: 0.000000e+00 +h2gdf6220/cpu-17/cpu-user: + value: 0.000000e+00 +h2gdf6220/cpu-17/cpu-wait: + value: 0.000000e+00 +h2gdf6220/cpu-18/cpu-idle: + value: 1.000058e+02 +h2gdf6220/cpu-18/cpu-interrupt: + value: 0.000000e+00 +h2gdf6220/cpu-18/cpu-nice: + value: 0.000000e+00 +h2gdf6220/cpu-18/cpu-softirq: + value: 0.000000e+00 +h2gdf6220/cpu-18/cpu-steal: + value: 0.000000e+00 +h2gdf6220/cpu-18/cpu-system: + value: 0.000000e+00 +h2gdf6220/cpu-18/cpu-user: + value: 0.000000e+00 +h2gdf6220/cpu-18/cpu-wait: + value: 0.000000e+00 +h2gdf6220/cpu-19/cpu-idle: + value: 9.990559e+01 +h2gdf6220/cpu-19/cpu-interrupt: + value: 0.000000e+00 +h2gdf6220/cpu-19/cpu-nice: + value: 0.000000e+00 +h2gdf6220/cpu-19/cpu-softirq: + value: 0.000000e+00 +h2gdf6220/cpu-19/cpu-steal: + value: 0.000000e+00 +h2gdf6220/cpu-19/cpu-system: + value: 2.000113e-01 +h2gdf6220/cpu-19/cpu-user: + value: 1.000057e-01 +h2gdf6220/cpu-19/cpu-wait: + value: 0.000000e+00 +h2gdf6220/cpu-2/cpu-idle: + value: 9.990540e+01 +h2gdf6220/cpu-2/cpu-interrupt: + value: 0.000000e+00 +h2gdf6220/cpu-2/cpu-nice: + value: 0.000000e+00 +h2gdf6220/cpu-2/cpu-softirq: + value: 0.000000e+00 +h2gdf6220/cpu-2/cpu-steal: + value: 0.000000e+00 +h2gdf6220/cpu-2/cpu-system: + value: 0.000000e+00 +h2gdf6220/cpu-2/cpu-user: + value: 1.000054e-01 +h2gdf6220/cpu-2/cpu-wait: + value: 0.000000e+00 +h2gdf6220/cpu-20/cpu-idle: + value: 1.000055e+02 +h2gdf6220/cpu-20/cpu-interrupt: + value: 0.000000e+00 +h2gdf6220/cpu-20/cpu-nice: + value: 0.000000e+00 +h2gdf6220/cpu-20/cpu-softirq: + value: 0.000000e+00 +h2gdf6220/cpu-20/cpu-steal: + value: 0.000000e+00 +h2gdf6220/cpu-20/cpu-system: + value: 0.000000e+00 +h2gdf6220/cpu-20/cpu-user: + value: 0.000000e+00 +h2gdf6220/cpu-20/cpu-wait: + value: 0.000000e+00 +h2gdf6220/cpu-21/cpu-idle: + value: 1.000054e+02 +h2gdf6220/cpu-21/cpu-interrupt: + value: 0.000000e+00 +h2gdf6220/cpu-21/cpu-nice: + value: 0.000000e+00 +h2gdf6220/cpu-21/cpu-softirq: + value: 0.000000e+00 +h2gdf6220/cpu-21/cpu-steal: + value: 0.000000e+00 +h2gdf6220/cpu-21/cpu-system: + value: 0.000000e+00 +h2gdf6220/cpu-21/cpu-user: + value: 0.000000e+00 +h2gdf6220/cpu-21/cpu-wait: + value: 0.000000e+00 +h2gdf6220/cpu-22/cpu-idle: + value: 9.990534e+01 +h2gdf6220/cpu-22/cpu-interrupt: + value: 0.000000e+00 +h2gdf6220/cpu-22/cpu-nice: + value: 0.000000e+00 +h2gdf6220/cpu-22/cpu-softirq: + value: 0.000000e+00 +h2gdf6220/cpu-22/cpu-steal: + value: 0.000000e+00 +h2gdf6220/cpu-22/cpu-system: + value: 0.000000e+00 +h2gdf6220/cpu-22/cpu-user: + value: 0.000000e+00 +h2gdf6220/cpu-22/cpu-wait: + value: 0.000000e+00 +h2gdf6220/cpu-23/cpu-idle: + value: 1.000054e+02 +h2gdf6220/cpu-23/cpu-interrupt: + value: 0.000000e+00 +h2gdf6220/cpu-23/cpu-nice: + value: 0.000000e+00 +h2gdf6220/cpu-23/cpu-softirq: + value: 0.000000e+00 +h2gdf6220/cpu-23/cpu-steal: + value: 0.000000e+00 +h2gdf6220/cpu-23/cpu-system: + value: 0.000000e+00 +h2gdf6220/cpu-23/cpu-user: + value: 0.000000e+00 +h2gdf6220/cpu-23/cpu-wait: + value: 0.000000e+00 +h2gdf6220/cpu-3/cpu-idle: + value: 1.000058e+02 +h2gdf6220/cpu-3/cpu-interrupt: + value: 0.000000e+00 +h2gdf6220/cpu-3/cpu-nice: + value: 0.000000e+00 +h2gdf6220/cpu-3/cpu-softirq: + value: 0.000000e+00 +h2gdf6220/cpu-3/cpu-steal: + value: 0.000000e+00 +h2gdf6220/cpu-3/cpu-system: + value: 0.000000e+00 +h2gdf6220/cpu-3/cpu-user: + value: 0.000000e+00 +h2gdf6220/cpu-3/cpu-wait: + value: 0.000000e+00 +h2gdf6220/cpu-4/cpu-idle: + value: 9.990588e+01 +h2gdf6220/cpu-4/cpu-interrupt: + value: 0.000000e+00 +h2gdf6220/cpu-4/cpu-nice: + value: 0.000000e+00 +h2gdf6220/cpu-4/cpu-softirq: + value: 0.000000e+00 +h2gdf6220/cpu-4/cpu-steal: + value: 0.000000e+00 +h2gdf6220/cpu-4/cpu-system: + value: 0.000000e+00 +h2gdf6220/cpu-4/cpu-user: + value: 0.000000e+00 +h2gdf6220/cpu-4/cpu-wait: + value: 0.000000e+00 +h2gdf6220/cpu-5/cpu-idle: + value: 1.000061e+02 +h2gdf6220/cpu-5/cpu-interrupt: + value: 0.000000e+00 +h2gdf6220/cpu-5/cpu-nice: + value: 0.000000e+00 +h2gdf6220/cpu-5/cpu-softirq: + value: 0.000000e+00 +h2gdf6220/cpu-5/cpu-steal: + value: 0.000000e+00 +h2gdf6220/cpu-5/cpu-system: + value: 0.000000e+00 +h2gdf6220/cpu-5/cpu-user: + value: 0.000000e+00 +h2gdf6220/cpu-5/cpu-wait: + value: 0.000000e+00 +h2gdf6220/cpu-6/cpu-idle: + value: 9.980614e+01 +h2gdf6220/cpu-6/cpu-interrupt: + value: 0.000000e+00 +h2gdf6220/cpu-6/cpu-nice: + value: 0.000000e+00 +h2gdf6220/cpu-6/cpu-softirq: + value: 0.000000e+00 +h2gdf6220/cpu-6/cpu-steal: + value: 0.000000e+00 +h2gdf6220/cpu-6/cpu-system: + value: 0.000000e+00 +h2gdf6220/cpu-6/cpu-user: + value: 0.000000e+00 +h2gdf6220/cpu-6/cpu-wait: + value: 1.000062e-01 +h2gdf6220/cpu-7/cpu-idle: + value: 9.990617e+01 +h2gdf6220/cpu-7/cpu-interrupt: + value: 0.000000e+00 +h2gdf6220/cpu-7/cpu-nice: + value: 0.000000e+00 +h2gdf6220/cpu-7/cpu-softirq: + value: 0.000000e+00 +h2gdf6220/cpu-7/cpu-steal: + value: 0.000000e+00 +h2gdf6220/cpu-7/cpu-system: + value: 1.000062e-01 +h2gdf6220/cpu-7/cpu-user: + value: 0.000000e+00 +h2gdf6220/cpu-7/cpu-wait: + value: 0.000000e+00 +h2gdf6220/cpu-8/cpu-idle: + value: 1.000060e+02 +h2gdf6220/cpu-8/cpu-interrupt: + value: 0.000000e+00 +h2gdf6220/cpu-8/cpu-nice: + value: 0.000000e+00 +h2gdf6220/cpu-8/cpu-softirq: + value: 0.000000e+00 +h2gdf6220/cpu-8/cpu-steal: + value: 0.000000e+00 +h2gdf6220/cpu-8/cpu-system: + value: 0.000000e+00 +h2gdf6220/cpu-8/cpu-user: + value: 0.000000e+00 +h2gdf6220/cpu-8/cpu-wait: + value: 0.000000e+00 +h2gdf6220/cpu-9/cpu-idle: + value: 9.990601e+01 +h2gdf6220/cpu-9/cpu-interrupt: + value: 0.000000e+00 +h2gdf6220/cpu-9/cpu-nice: + value: 0.000000e+00 +h2gdf6220/cpu-9/cpu-softirq: + value: 0.000000e+00 +h2gdf6220/cpu-9/cpu-steal: + value: 0.000000e+00 +h2gdf6220/cpu-9/cpu-system: + value: 0.000000e+00 +h2gdf6220/cpu-9/cpu-user: + value: 0.000000e+00 +h2gdf6220/cpu-9/cpu-wait: + value: 0.000000e+00 +h2gdf6220/df-boot/df_complex-free: + value: 4.324721e+08 +h2gdf6220/df-boot/df_complex-reserved: + value: 2.684109e+07 +h2gdf6220/df-boot/df_complex-used: + value: 6.911181e+07 +h2gdf6220/df-boot/df_inodes-free: + value: 3.271800e+04 +h2gdf6220/df-boot/df_inodes-reserved: + value: 0.000000e+00 +h2gdf6220/df-boot/df_inodes-used: + value: 5.000000e+01 +h2gdf6220/df-boot/percent_bytes-free: + value: 8.184172e+01 +h2gdf6220/df-boot/percent_bytes-reserved: + value: 5.079451e+00 +h2gdf6220/df-boot/percent_bytes-used: + value: 1.307883e+01 +h2gdf6220/df-boot/percent_inodes-free: + value: 9.984741e+01 +h2gdf6220/df-boot/percent_inodes-reserved: + value: 0.000000e+00 +h2gdf6220/df-boot/percent_inodes-used: + value: 1.525879e-01 +h2gdf6220/df-data1/df_complex-free: + value: 2.459593e+11 +h2gdf6220/df-data1/df_complex-reserved: + value: 1.378982e+10 +h2gdf6220/df-data1/df_complex-used: + value: 1.171974e+10 +h2gdf6220/df-data1/df_inodes-free: + value: 1.683450e+07 +h2gdf6220/df-data1/df_inodes-reserved: + value: 0.000000e+00 +h2gdf6220/df-data1/df_inodes-used: + value: 6.100000e+01 +h2gdf6220/df-data1/percent_bytes-free: + value: 9.060313e+01 +h2gdf6220/df-data1/percent_bytes-reserved: + value: 5.079707e+00 +h2gdf6220/df-data1/percent_bytes-used: + value: 4.317159e+00 +h2gdf6220/df-data1/percent_inodes-free: + value: 9.999964e+01 +h2gdf6220/df-data1/percent_inodes-reserved: + value: 0.000000e+00 +h2gdf6220/df-data1/percent_inodes-used: + value: 3.623498e-04 +h2gdf6220/df-dev-shm/df_complex-free: + value: 3.375709e+10 +h2gdf6220/df-dev-shm/df_complex-reserved: + value: 0.000000e+00 +h2gdf6220/df-dev-shm/df_complex-used: + value: 0.000000e+00 +h2gdf6220/df-dev-shm/df_inodes-free: + value: 8.241475e+06 +h2gdf6220/df-dev-shm/df_inodes-reserved: + value: 0.000000e+00 +h2gdf6220/df-dev-shm/df_inodes-used: + value: 1.000000e+00 +h2gdf6220/df-dev-shm/percent_bytes-free: + value: 1.000000e+02 +h2gdf6220/df-dev-shm/percent_bytes-reserved: + value: 0.000000e+00 +h2gdf6220/df-dev-shm/percent_bytes-used: + value: 0.000000e+00 +h2gdf6220/df-dev-shm/percent_inodes-free: + value: 9.999998e+01 +h2gdf6220/df-dev-shm/percent_inodes-reserved: + value: 0.000000e+00 +h2gdf6220/df-dev-shm/percent_inodes-used: + value: 1.213375e-05 +h2gdf6220/df-root/df_complex-free: + value: 1.058283e+10 +h2gdf6220/df-root/df_complex-reserved: + value: 6.442435e+08 +h2gdf6220/df-root/df_complex-used: + value: 1.455632e+09 +h2gdf6220/df-root/df_inodes-free: + value: 7.435320e+05 +h2gdf6220/df-root/df_inodes-reserved: + value: 0.000000e+00 +h2gdf6220/df-root/df_inodes-used: + value: 4.290000e+04 +h2gdf6220/df-root/percent_bytes-free: + value: 8.344300e+01 +h2gdf6220/df-root/percent_bytes-reserved: + value: 5.079700e+00 +h2gdf6220/df-root/percent_bytes-used: + value: 1.147730e+01 +h2gdf6220/df-root/percent_inodes-free: + value: 9.454498e+01 +h2gdf6220/df-root/percent_inodes-reserved: + value: 0.000000e+00 +h2gdf6220/df-root/percent_inodes-used: + value: 5.455017e+00 +h2gdf6220/df-var/df_complex-free: + value: 7.501562e+09 +h2gdf6220/df-var/df_complex-reserved: + value: 4.294943e+08 +h2gdf6220/df-var/df_complex-used: + value: 5.240627e+08 +h2gdf6220/df-var/df_inodes-free: + value: 5.225360e+05 +h2gdf6220/df-var/df_inodes-reserved: + value: 0.000000e+00 +h2gdf6220/df-var/df_inodes-used: + value: 1.752000e+03 +h2gdf6220/df-var/percent_bytes-free: + value: 8.872214e+01 +h2gdf6220/df-var/percent_bytes-reserved: + value: 5.079695e+00 +h2gdf6220/df-var/percent_bytes-used: + value: 6.198171e+00 +h2gdf6220/df-var/percent_inodes-free: + value: 9.966583e+01 +h2gdf6220/df-var/percent_inodes-reserved: + value: 0.000000e+00 +h2gdf6220/df-var/percent_inodes-used: + value: 3.341675e-01 +h2gdf6220/disk-sda/disk_merged: + read: 0.000000e+00 + write: 5.000078e-01 +h2gdf6220/disk-sda/disk_octets: + read: 0.000000e+00 + write: 1.761274e+05 +h2gdf6220/disk-sda/disk_ops: + read: 0.000000e+00 + write: 6.599997e+00 +h2gdf6220/disk-sda/disk_time: + read: 0.000000e+00 + write: 1.200000e+00 +h2gdf6220/disk-sda1/disk_merged: + read: 0.000000e+00 + write: 0.000000e+00 +h2gdf6220/disk-sda1/disk_octets: + read: 0.000000e+00 + write: 0.000000e+00 +h2gdf6220/disk-sda1/disk_ops: + read: 0.000000e+00 + write: 0.000000e+00 +h2gdf6220/disk-sda1/disk_time: + read: 0.000000e+00 + write: 0.000000e+00 +h2gdf6220/disk-sda2/disk_merged: + read: 0.000000e+00 + write: 0.000000e+00 +h2gdf6220/disk-sda2/disk_octets: + read: 0.000000e+00 + write: 0.000000e+00 +h2gdf6220/disk-sda2/disk_ops: + read: 0.000000e+00 + write: 0.000000e+00 +h2gdf6220/disk-sda2/disk_time: + read: 0.000000e+00 + write: 0.000000e+00 +h2gdf6220/disk-sda3/disk_merged: + read: 0.000000e+00 + write: 0.000000e+00 +h2gdf6220/disk-sda3/disk_octets: + read: 0.000000e+00 + write: 0.000000e+00 +h2gdf6220/disk-sda3/disk_ops: + read: 0.000000e+00 + write: 0.000000e+00 +h2gdf6220/disk-sda3/disk_time: + read: 0.000000e+00 + write: 0.000000e+00 +h2gdf6220/disk-sda4/disk_merged: + read: 0.000000e+00 + write: 0.000000e+00 +h2gdf6220/disk-sda4/disk_octets: + read: 0.000000e+00 + write: 0.000000e+00 +h2gdf6220/disk-sda4/disk_ops: + read: 0.000000e+00 + write: 0.000000e+00 +h2gdf6220/disk-sda4/disk_time: + read: 0.000000e+00 + write: 0.000000e+00 +h2gdf6220/disk-sda5/disk_merged: + read: 0.000000e+00 + write: 0.000000e+00 +h2gdf6220/disk-sda5/disk_octets: + read: 0.000000e+00 + write: 0.000000e+00 +h2gdf6220/disk-sda5/disk_ops: + read: 0.000000e+00 + write: 0.000000e+00 +h2gdf6220/disk-sda5/disk_time: + read: 0.000000e+00 + write: 0.000000e+00 +h2gdf6220/disk-sda6/disk_merged: + read: 0.000000e+00 + write: 5.000119e-01 +h2gdf6220/disk-sda6/disk_octets: + read: 0.000000e+00 + write: 1.761322e+05 +h2gdf6220/disk-sda6/disk_ops: + read: 0.000000e+00 + write: 6.600157e+00 +h2gdf6220/disk-sda6/disk_time: + read: 0.000000e+00 + write: 1.200029e+00 +h2gdf6220/load/load: + longterm: 3.000000e-02 + midterm: 1.300000e-01 + shortterm: 1.800000e-01 +h2gdf6220/memory/memory-buffered: + value: 3.538944e+08 +h2gdf6220/memory/memory-cached: + value: 6.890127e+08 +h2gdf6220/memory/memory-free: + value: 5.744062e+10 +h2gdf6220/memory/memory-used: + value: 9.030652e+09 +h2gdf6220/network/if_octets: + rx: 0.000000e+00 + tx: 1.449803e+03 +h2gdf6220/network/if_packets: + rx: 0.000000e+00 + tx: 1.100003e+00 +h2gdf6220/network/queue_length: + value: 0.000000e+00 +h2gdf6220/network/total_values-dispatch-accepted: + value: 0.000000e+00 +h2gdf6220/network/total_values-dispatch-rejected: + value: 0.000000e+00 +h2gdf6220/network/total_values-send-accepted: + value: 2.630008e+01 +h2gdf6220/network/total_values-send-rejected: + value: 0.000000e+00 +h2gdf6220/swap/swap-cached: + value: 0.000000e+00 +h2gdf6220/swap/swap-free: + value: 2.147475e+09 +h2gdf6220/swap/swap-used: + value: 0.000000e+00 +h2gdf6220/swap/swap_io-in: + value: 0.000000e+00 +h2gdf6220/swap/swap_io-out: + value: 0.000000e+00 +h2gdf6220/vmem/vmpage_faults: + majflt: 0.000000e+00 + minflt: 7.000005e-01 +h2gdf6220/vmem/vmpage_io-memory: + in: 0.000000e+00 + out: 2.800002e+00 +h2gdf6220/vmem/vmpage_io-swap: + in: 0.000000e+00 + out: 0.000000e+00 +h2gdf6220/vmem/vmpage_number-active_anon: + value: 1.830919e+06 +h2gdf6220/vmem/vmpage_number-active_file: + value: 1.812510e+05 +h2gdf6220/vmem/vmpage_number-anon_pages: + value: 1.841200e+04 +h2gdf6220/vmem/vmpage_number-anon_transparent_hugepages: + value: 3.540000e+03 +h2gdf6220/vmem/vmpage_number-boudfe: + value: 0.000000e+00 +h2gdf6220/vmem/vmpage_number-dirty: + value: 4.000000e+00 +h2gdf6220/vmem/vmpage_number-file_pages: + value: 2.546160e+05 +h2gdf6220/vmem/vmpage_number-free_pages: + value: 1.402359e+07 +h2gdf6220/vmem/vmpage_number-inactive_anon: + value: 1.600000e+01 +h2gdf6220/vmem/vmpage_number-inactive_file: + value: 7.330700e+04 +h2gdf6220/vmem/vmpage_number-isolated_anon: + value: 0.000000e+00 +h2gdf6220/vmem/vmpage_number-isolated_file: + value: 0.000000e+00 +h2gdf6220/vmem/vmpage_number-kernel_stack: + value: 4.900000e+02 +h2gdf6220/vmem/vmpage_number-mapped: + value: 4.792000e+03 +h2gdf6220/vmem/vmpage_number-mlock: + value: 0.000000e+00 +h2gdf6220/vmem/vmpage_number-page_table_pages: + value: 4.540000e+03 +h2gdf6220/vmem/vmpage_number-shmem: + value: 6.200000e+01 +h2gdf6220/vmem/vmpage_number-slab_reclaimable: + value: 2.343820e+05 +h2gdf6220/vmem/vmpage_number-slab_unreclaimable: + value: 2.127200e+04 +h2gdf6220/vmem/vmpage_number-unevictable: + value: 0.000000e+00 +h2gdf6220/vmem/vmpage_number-unstable: + value: 0.000000e+00 +h2gdf6220/vmem/vmpage_number-vmscan_write: + value: 0.000000e+00 +h2gdf6220/vmem/vmpage_number-writeback: + value: 0.000000e+00 +h2gdf6220/vmem/vmpage_number-writeback_temp: + value: 0.000000e+00 +m01df6100/cpu-0/cpu-idle: + value: 9.980233e+01 +m01df6100/cpu-0/cpu-interrupt: + value: 0.000000e+00 +m01df6100/cpu-0/cpu-nice: + value: 0.000000e+00 +m01df6100/cpu-0/cpu-softirq: + value: 0.000000e+00 +m01df6100/cpu-0/cpu-steal: + value: 0.000000e+00 +m01df6100/cpu-0/cpu-system: + value: 0.000000e+00 +m01df6100/cpu-0/cpu-user: + value: 0.000000e+00 +m01df6100/cpu-0/cpu-wait: + value: 0.000000e+00 +m01df6100/cpu-1/cpu-idle: + value: 1.000105e+02 +m01df6100/cpu-1/cpu-interrupt: + value: 0.000000e+00 +m01df6100/cpu-1/cpu-nice: + value: 0.000000e+00 +m01df6100/cpu-1/cpu-softirq: + value: 0.000000e+00 +m01df6100/cpu-1/cpu-steal: + value: 0.000000e+00 +m01df6100/cpu-1/cpu-system: + value: 0.000000e+00 +m01df6100/cpu-1/cpu-user: + value: 0.000000e+00 +m01df6100/cpu-1/cpu-wait: + value: 0.000000e+00 +m01df6100/cpu-10/cpu-idle: + value: 1.000294e+02 +m01df6100/cpu-10/cpu-interrupt: + value: 0.000000e+00 +m01df6100/cpu-10/cpu-nice: + value: 0.000000e+00 +m01df6100/cpu-10/cpu-softirq: + value: 0.000000e+00 +m01df6100/cpu-10/cpu-steal: + value: 0.000000e+00 +m01df6100/cpu-10/cpu-system: + value: 0.000000e+00 +m01df6100/cpu-10/cpu-user: + value: 0.000000e+00 +m01df6100/cpu-10/cpu-wait: + value: 0.000000e+00 +m01df6100/cpu-11/cpu-idle: + value: 9.993001e+01 +m01df6100/cpu-11/cpu-interrupt: + value: 0.000000e+00 +m01df6100/cpu-11/cpu-nice: + value: 0.000000e+00 +m01df6100/cpu-11/cpu-softirq: + value: 0.000000e+00 +m01df6100/cpu-11/cpu-steal: + value: 0.000000e+00 +m01df6100/cpu-11/cpu-system: + value: 0.000000e+00 +m01df6100/cpu-11/cpu-user: + value: 0.000000e+00 +m01df6100/cpu-11/cpu-wait: + value: 0.000000e+00 +m01df6100/cpu-12/cpu-idle: + value: 1.000310e+02 +m01df6100/cpu-12/cpu-interrupt: + value: 0.000000e+00 +m01df6100/cpu-12/cpu-nice: + value: 0.000000e+00 +m01df6100/cpu-12/cpu-softirq: + value: 0.000000e+00 +m01df6100/cpu-12/cpu-steal: + value: 0.000000e+00 +m01df6100/cpu-12/cpu-system: + value: 0.000000e+00 +m01df6100/cpu-12/cpu-user: + value: 0.000000e+00 +m01df6100/cpu-12/cpu-wait: + value: 0.000000e+00 +m01df6100/cpu-13/cpu-idle: + value: 9.993154e+01 +m01df6100/cpu-13/cpu-interrupt: + value: 0.000000e+00 +m01df6100/cpu-13/cpu-nice: + value: 0.000000e+00 +m01df6100/cpu-13/cpu-softirq: + value: 0.000000e+00 +m01df6100/cpu-13/cpu-steal: + value: 0.000000e+00 +m01df6100/cpu-13/cpu-system: + value: 0.000000e+00 +m01df6100/cpu-13/cpu-user: + value: 0.000000e+00 +m01df6100/cpu-13/cpu-wait: + value: 0.000000e+00 +m01df6100/cpu-14/cpu-idle: + value: 1.000329e+02 +m01df6100/cpu-14/cpu-interrupt: + value: 0.000000e+00 +m01df6100/cpu-14/cpu-nice: + value: 0.000000e+00 +m01df6100/cpu-14/cpu-softirq: + value: 0.000000e+00 +m01df6100/cpu-14/cpu-steal: + value: 0.000000e+00 +m01df6100/cpu-14/cpu-system: + value: 0.000000e+00 +m01df6100/cpu-14/cpu-user: + value: 0.000000e+00 +m01df6100/cpu-14/cpu-wait: + value: 0.000000e+00 +m01df6100/cpu-15/cpu-idle: + value: 1.000341e+02 +m01df6100/cpu-15/cpu-interrupt: + value: 0.000000e+00 +m01df6100/cpu-15/cpu-nice: + value: 0.000000e+00 +m01df6100/cpu-15/cpu-softirq: + value: 0.000000e+00 +m01df6100/cpu-15/cpu-steal: + value: 0.000000e+00 +m01df6100/cpu-15/cpu-system: + value: 0.000000e+00 +m01df6100/cpu-15/cpu-user: + value: 0.000000e+00 +m01df6100/cpu-15/cpu-wait: + value: 0.000000e+00 +m01df6100/cpu-16/cpu-idle: + value: 1.000347e+02 +m01df6100/cpu-16/cpu-interrupt: + value: 0.000000e+00 +m01df6100/cpu-16/cpu-nice: + value: 0.000000e+00 +m01df6100/cpu-16/cpu-softirq: + value: 0.000000e+00 +m01df6100/cpu-16/cpu-steal: + value: 0.000000e+00 +m01df6100/cpu-16/cpu-system: + value: 0.000000e+00 +m01df6100/cpu-16/cpu-user: + value: 0.000000e+00 +m01df6100/cpu-16/cpu-wait: + value: 0.000000e+00 +m01df6100/cpu-17/cpu-idle: + value: 1.000354e+02 +m01df6100/cpu-17/cpu-interrupt: + value: 0.000000e+00 +m01df6100/cpu-17/cpu-nice: + value: 0.000000e+00 +m01df6100/cpu-17/cpu-softirq: + value: 0.000000e+00 +m01df6100/cpu-17/cpu-steal: + value: 0.000000e+00 +m01df6100/cpu-17/cpu-system: + value: 0.000000e+00 +m01df6100/cpu-17/cpu-user: + value: 0.000000e+00 +m01df6100/cpu-17/cpu-wait: + value: 0.000000e+00 +m01df6100/cpu-18/cpu-idle: + value: 9.993624e+01 +m01df6100/cpu-18/cpu-interrupt: + value: 0.000000e+00 +m01df6100/cpu-18/cpu-nice: + value: 0.000000e+00 +m01df6100/cpu-18/cpu-softirq: + value: 0.000000e+00 +m01df6100/cpu-18/cpu-steal: + value: 0.000000e+00 +m01df6100/cpu-18/cpu-system: + value: 0.000000e+00 +m01df6100/cpu-18/cpu-user: + value: 0.000000e+00 +m01df6100/cpu-18/cpu-wait: + value: 0.000000e+00 +m01df6100/cpu-19/cpu-idle: + value: 9.993717e+01 +m01df6100/cpu-19/cpu-interrupt: + value: 0.000000e+00 +m01df6100/cpu-19/cpu-nice: + value: 0.000000e+00 +m01df6100/cpu-19/cpu-softirq: + value: 0.000000e+00 +m01df6100/cpu-19/cpu-steal: + value: 0.000000e+00 +m01df6100/cpu-19/cpu-system: + value: 0.000000e+00 +m01df6100/cpu-19/cpu-user: + value: 0.000000e+00 +m01df6100/cpu-19/cpu-wait: + value: 0.000000e+00 +m01df6100/cpu-2/cpu-idle: + value: 1.000135e+02 +m01df6100/cpu-2/cpu-interrupt: + value: 0.000000e+00 +m01df6100/cpu-2/cpu-nice: + value: 0.000000e+00 +m01df6100/cpu-2/cpu-softirq: + value: 0.000000e+00 +m01df6100/cpu-2/cpu-steal: + value: 0.000000e+00 +m01df6100/cpu-2/cpu-system: + value: 0.000000e+00 +m01df6100/cpu-2/cpu-user: + value: 0.000000e+00 +m01df6100/cpu-2/cpu-wait: + value: 0.000000e+00 +m01df6100/cpu-20/cpu-idle: + value: 9.993831e+01 +m01df6100/cpu-20/cpu-interrupt: + value: 0.000000e+00 +m01df6100/cpu-20/cpu-nice: + value: 0.000000e+00 +m01df6100/cpu-20/cpu-softirq: + value: 0.000000e+00 +m01df6100/cpu-20/cpu-steal: + value: 0.000000e+00 +m01df6100/cpu-20/cpu-system: + value: 0.000000e+00 +m01df6100/cpu-20/cpu-user: + value: 0.000000e+00 +m01df6100/cpu-20/cpu-wait: + value: 0.000000e+00 +m01df6100/cpu-21/cpu-idle: + value: 1.000397e+02 +m01df6100/cpu-21/cpu-interrupt: + value: 0.000000e+00 +m01df6100/cpu-21/cpu-nice: + value: 0.000000e+00 +m01df6100/cpu-21/cpu-softirq: + value: 0.000000e+00 +m01df6100/cpu-21/cpu-steal: + value: 0.000000e+00 +m01df6100/cpu-21/cpu-system: + value: 0.000000e+00 +m01df6100/cpu-21/cpu-user: + value: 0.000000e+00 +m01df6100/cpu-21/cpu-wait: + value: 0.000000e+00 +m01df6100/cpu-22/cpu-idle: + value: 9.994092e+01 +m01df6100/cpu-22/cpu-interrupt: + value: 0.000000e+00 +m01df6100/cpu-22/cpu-nice: + value: 0.000000e+00 +m01df6100/cpu-22/cpu-softirq: + value: 0.000000e+00 +m01df6100/cpu-22/cpu-steal: + value: 0.000000e+00 +m01df6100/cpu-22/cpu-system: + value: 0.000000e+00 +m01df6100/cpu-22/cpu-user: + value: 0.000000e+00 +m01df6100/cpu-22/cpu-wait: + value: 0.000000e+00 +m01df6100/cpu-23/cpu-idle: + value: 1.000420e+02 +m01df6100/cpu-23/cpu-interrupt: + value: 0.000000e+00 +m01df6100/cpu-23/cpu-nice: + value: 0.000000e+00 +m01df6100/cpu-23/cpu-softirq: + value: 0.000000e+00 +m01df6100/cpu-23/cpu-steal: + value: 0.000000e+00 +m01df6100/cpu-23/cpu-system: + value: 0.000000e+00 +m01df6100/cpu-23/cpu-user: + value: 0.000000e+00 +m01df6100/cpu-23/cpu-wait: + value: 0.000000e+00 +m01df6100/cpu-3/cpu-idle: + value: 1.000161e+02 +m01df6100/cpu-3/cpu-interrupt: + value: 0.000000e+00 +m01df6100/cpu-3/cpu-nice: + value: 0.000000e+00 +m01df6100/cpu-3/cpu-softirq: + value: 0.000000e+00 +m01df6100/cpu-3/cpu-steal: + value: 0.000000e+00 +m01df6100/cpu-3/cpu-system: + value: 0.000000e+00 +m01df6100/cpu-3/cpu-user: + value: 0.000000e+00 +m01df6100/cpu-3/cpu-wait: + value: 0.000000e+00 +m01df6100/cpu-4/cpu-idle: + value: 1.000191e+02 +m01df6100/cpu-4/cpu-interrupt: + value: 0.000000e+00 +m01df6100/cpu-4/cpu-nice: + value: 0.000000e+00 +m01df6100/cpu-4/cpu-softirq: + value: 0.000000e+00 +m01df6100/cpu-4/cpu-steal: + value: 0.000000e+00 +m01df6100/cpu-4/cpu-system: + value: 0.000000e+00 +m01df6100/cpu-4/cpu-user: + value: 0.000000e+00 +m01df6100/cpu-4/cpu-wait: + value: 0.000000e+00 +m01df6100/cpu-5/cpu-idle: + value: 1.000243e+02 +m01df6100/cpu-5/cpu-interrupt: + value: 0.000000e+00 +m01df6100/cpu-5/cpu-nice: + value: 0.000000e+00 +m01df6100/cpu-5/cpu-softirq: + value: 0.000000e+00 +m01df6100/cpu-5/cpu-steal: + value: 0.000000e+00 +m01df6100/cpu-5/cpu-system: + value: 0.000000e+00 +m01df6100/cpu-5/cpu-user: + value: 0.000000e+00 +m01df6100/cpu-5/cpu-wait: + value: 0.000000e+00 +m01df6100/cpu-6/cpu-idle: + value: 1.000268e+02 +m01df6100/cpu-6/cpu-interrupt: + value: 0.000000e+00 +m01df6100/cpu-6/cpu-nice: + value: 0.000000e+00 +m01df6100/cpu-6/cpu-softirq: + value: 0.000000e+00 +m01df6100/cpu-6/cpu-steal: + value: 0.000000e+00 +m01df6100/cpu-6/cpu-system: + value: 1.000266e-01 +m01df6100/cpu-6/cpu-user: + value: 0.000000e+00 +m01df6100/cpu-6/cpu-wait: + value: 0.000000e+00 +m01df6100/cpu-7/cpu-idle: + value: 1.000274e+02 +m01df6100/cpu-7/cpu-interrupt: + value: 0.000000e+00 +m01df6100/cpu-7/cpu-nice: + value: 0.000000e+00 +m01df6100/cpu-7/cpu-softirq: + value: 0.000000e+00 +m01df6100/cpu-7/cpu-steal: + value: 0.000000e+00 +m01df6100/cpu-7/cpu-system: + value: 0.000000e+00 +m01df6100/cpu-7/cpu-user: + value: 0.000000e+00 +m01df6100/cpu-7/cpu-wait: + value: 0.000000e+00 +m01df6100/cpu-8/cpu-idle: + value: 1.000283e+02 +m01df6100/cpu-8/cpu-interrupt: + value: 0.000000e+00 +m01df6100/cpu-8/cpu-nice: + value: 0.000000e+00 +m01df6100/cpu-8/cpu-softirq: + value: 0.000000e+00 +m01df6100/cpu-8/cpu-steal: + value: 0.000000e+00 +m01df6100/cpu-8/cpu-system: + value: 0.000000e+00 +m01df6100/cpu-8/cpu-user: + value: 0.000000e+00 +m01df6100/cpu-8/cpu-wait: + value: 0.000000e+00 +m01df6100/cpu-9/cpu-idle: + value: 1.000291e+02 +m01df6100/cpu-9/cpu-interrupt: + value: 0.000000e+00 +m01df6100/cpu-9/cpu-nice: + value: 0.000000e+00 +m01df6100/cpu-9/cpu-softirq: + value: 0.000000e+00 +m01df6100/cpu-9/cpu-steal: + value: 0.000000e+00 +m01df6100/cpu-9/cpu-system: + value: 0.000000e+00 +m01df6100/cpu-9/cpu-user: + value: 0.000000e+00 +m01df6100/cpu-9/cpu-wait: + value: 0.000000e+00 +m01df6100/df-boot/df_complex-free: + value: 4.369408e+08 +m01df6100/df-boot/df_complex-reserved: + value: 2.684109e+07 +m01df6100/df-boot/df_complex-used: + value: 6.464307e+07 +m01df6100/df-boot/df_inodes-free: + value: 3.271800e+04 +m01df6100/df-boot/df_inodes-reserved: + value: 0.000000e+00 +m01df6100/df-boot/df_inodes-used: + value: 5.000000e+01 +m01df6100/df-boot/percent_bytes-free: + value: 8.268739e+01 +m01df6100/df-boot/percent_bytes-reserved: + value: 5.079451e+00 +m01df6100/df-boot/percent_bytes-used: + value: 1.223316e+01 +m01df6100/df-boot/percent_inodes-free: + value: 9.984741e+01 +m01df6100/df-boot/percent_inodes-reserved: + value: 0.000000e+00 +m01df6100/df-boot/percent_inodes-used: + value: 1.525879e-01 +m01df6100/df-data1/df_complex-free: + value: 2.574032e+11 +m01df6100/df-data1/df_complex-reserved: + value: 1.378982e+10 +m01df6100/df-data1/df_complex-used: + value: 2.758984e+08 +m01df6100/df-data1/df_inodes-free: + value: 1.683426e+07 +m01df6100/df-data1/df_inodes-reserved: + value: 0.000000e+00 +m01df6100/df-data1/df_inodes-used: + value: 2.960000e+02 +m01df6100/df-data1/percent_bytes-free: + value: 9.481866e+01 +m01df6100/df-data1/percent_bytes-reserved: + value: 5.079707e+00 +m01df6100/df-data1/percent_bytes-used: + value: 1.016317e-01 +m01df6100/df-data1/percent_inodes-free: + value: 9.999825e+01 +m01df6100/df-data1/percent_inodes-reserved: + value: 0.000000e+00 +m01df6100/df-data1/percent_inodes-used: + value: 1.758288e-03 +m01df6100/df-dev-shm/df_complex-free: + value: 3.375709e+10 +m01df6100/df-dev-shm/df_complex-reserved: + value: 0.000000e+00 +m01df6100/df-dev-shm/df_complex-used: + value: 0.000000e+00 +m01df6100/df-dev-shm/df_inodes-free: + value: 8.241475e+06 +m01df6100/df-dev-shm/df_inodes-reserved: + value: 0.000000e+00 +m01df6100/df-dev-shm/df_inodes-used: + value: 1.000000e+00 +m01df6100/df-dev-shm/percent_bytes-free: + value: 1.000000e+02 +m01df6100/df-dev-shm/percent_bytes-reserved: + value: 0.000000e+00 +m01df6100/df-dev-shm/percent_bytes-used: + value: 0.000000e+00 +m01df6100/df-dev-shm/percent_inodes-free: + value: 9.999998e+01 +m01df6100/df-dev-shm/percent_inodes-reserved: + value: 0.000000e+00 +m01df6100/df-dev-shm/percent_inodes-used: + value: 1.213375e-05 +m01df6100/df-root/df_complex-free: + value: 1.072688e+10 +m01df6100/df-root/df_complex-reserved: + value: 6.442435e+08 +m01df6100/df-root/df_complex-used: + value: 1.311580e+09 +m01df6100/df-root/df_inodes-free: + value: 7.454950e+05 +m01df6100/df-root/df_inodes-reserved: + value: 0.000000e+00 +m01df6100/df-root/df_inodes-used: + value: 4.093700e+04 +m01df6100/df-root/percent_bytes-free: + value: 8.457882e+01 +m01df6100/df-root/percent_bytes-reserved: + value: 5.079700e+00 +m01df6100/df-root/percent_bytes-used: + value: 1.034148e+01 +m01df6100/df-root/percent_inodes-free: + value: 9.479459e+01 +m01df6100/df-root/percent_inodes-reserved: + value: 0.000000e+00 +m01df6100/df-root/percent_inodes-used: + value: 5.205409e+00 +m01df6100/df-var/df_complex-free: + value: 7.566787e+09 +m01df6100/df-var/df_complex-reserved: + value: 4.294943e+08 +m01df6100/df-var/df_complex-used: + value: 4.588380e+08 +m01df6100/df-var/df_inodes-free: + value: 5.228090e+05 +m01df6100/df-var/df_inodes-reserved: + value: 0.000000e+00 +m01df6100/df-var/df_inodes-used: + value: 1.479000e+03 +m01df6100/df-var/percent_bytes-free: + value: 8.949355e+01 +m01df6100/df-var/percent_bytes-reserved: + value: 5.079695e+00 +m01df6100/df-var/percent_bytes-used: + value: 5.426748e+00 +m01df6100/df-var/percent_inodes-free: + value: 9.971790e+01 +m01df6100/df-var/percent_inodes-reserved: + value: 0.000000e+00 +m01df6100/df-var/percent_inodes-used: + value: 2.820969e-01 +m01df6100/disk-sda/disk_merged: + read: 0.000000e+00 + write: 0.000000e+00 +m01df6100/disk-sda/disk_octets: + read: 0.000000e+00 + write: 0.000000e+00 +m01df6100/disk-sda/disk_ops: + read: 0.000000e+00 + write: 0.000000e+00 +m01df6100/disk-sda/disk_time: + read: 0.000000e+00 + write: 0.000000e+00 +m01df6100/disk-sda1/disk_merged: + read: 0.000000e+00 + write: 0.000000e+00 +m01df6100/disk-sda1/disk_octets: + read: 0.000000e+00 + write: 0.000000e+00 +m01df6100/disk-sda1/disk_ops: + read: 0.000000e+00 + write: 0.000000e+00 +m01df6100/disk-sda1/disk_time: + read: 0.000000e+00 + write: 0.000000e+00 +m01df6100/disk-sda2/disk_merged: + read: 0.000000e+00 + write: 0.000000e+00 +m01df6100/disk-sda2/disk_octets: + read: 0.000000e+00 + write: 0.000000e+00 +m01df6100/disk-sda2/disk_ops: + read: 0.000000e+00 + write: 0.000000e+00 +m01df6100/disk-sda2/disk_time: + read: 0.000000e+00 + write: 0.000000e+00 +m01df6100/disk-sda3/disk_merged: + read: 0.000000e+00 + write: 0.000000e+00 +m01df6100/disk-sda3/disk_octets: + read: 0.000000e+00 + write: 0.000000e+00 +m01df6100/disk-sda3/disk_ops: + read: 0.000000e+00 + write: 0.000000e+00 +m01df6100/disk-sda3/disk_time: + read: 0.000000e+00 + write: 0.000000e+00 +m01df6100/disk-sda4/disk_merged: + read: 0.000000e+00 + write: 0.000000e+00 +m01df6100/disk-sda4/disk_octets: + read: 0.000000e+00 + write: 0.000000e+00 +m01df6100/disk-sda4/disk_ops: + read: 0.000000e+00 + write: 0.000000e+00 +m01df6100/disk-sda4/disk_time: + read: 0.000000e+00 + write: 0.000000e+00 +m01df6100/disk-sda5/disk_merged: + read: 0.000000e+00 + write: 0.000000e+00 +m01df6100/disk-sda5/disk_octets: + read: 0.000000e+00 + write: 0.000000e+00 +m01df6100/disk-sda5/disk_ops: + read: 0.000000e+00 + write: 0.000000e+00 +m01df6100/disk-sda5/disk_time: + read: 0.000000e+00 + write: 0.000000e+00 +m01df6100/disk-sda6/disk_merged: + read: 0.000000e+00 + write: 0.000000e+00 +m01df6100/disk-sda6/disk_octets: + read: 0.000000e+00 + write: 0.000000e+00 +m01df6100/disk-sda6/disk_ops: + read: 0.000000e+00 + write: 0.000000e+00 +m01df6100/disk-sda6/disk_time: + read: 0.000000e+00 + write: 0.000000e+00 +m01df6100/load/load: + longterm: 0.000000e+00 + midterm: 2.000000e-02 + shortterm: 3.000000e-02 +m01df6100/memory/memory-buffered: + value: 3.348275e+08 +m01df6100/memory/memory-cached: + value: 5.892219e+08 +m01df6100/memory/memory-free: + value: 6.425088e+10 +m01df6100/memory/memory-used: + value: 2.339246e+09 +m01df6100/network/if_octets: + rx: 0.000000e+00 + tx: 1.057501e+03 +m01df6100/network/if_packets: + rx: 0.000000e+00 + tx: 8.000004e-01 +m01df6100/network/queue_length: + value: 0.000000e+00 +m01df6100/network/total_values-dispatch-accepted: + value: 0.000000e+00 +m01df6100/network/total_values-dispatch-rejected: + value: 0.000000e+00 +m01df6100/network/total_values-send-accepted: + value: 1.929969e+01 +m01df6100/network/total_values-send-rejected: + value: 0.000000e+00 +m01df6100/swap/swap-cached: + value: 0.000000e+00 +m01df6100/swap/swap-free: + value: 2.147475e+09 +m01df6100/swap/swap-used: + value: 0.000000e+00 +m01df6100/swap/swap_io-in: + value: 0.000000e+00 +m01df6100/swap/swap_io-out: + value: 0.000000e+00 +m01df6100/vmem/vmpage_faults: + majflt: 0.000000e+00 + minflt: 3.199662e+00 +m01df6100/vmem/vmpage_io-memory: + in: 0.000000e+00 + out: 0.000000e+00 +m01df6100/vmem/vmpage_io-swap: + in: 0.000000e+00 + out: 0.000000e+00 +m01df6100/vmem/vmpage_number-active_anon: + value: 2.152660e+05 +m01df6100/vmem/vmpage_number-active_file: + value: 1.507500e+05 +m01df6100/vmem/vmpage_number-anon_pages: + value: 1.456100e+04 +m01df6100/vmem/vmpage_number-anon_transparent_hugepages: + value: 3.920000e+02 +m01df6100/vmem/vmpage_number-boudfe: + value: 0.000000e+00 +m01df6100/vmem/vmpage_number-dirty: + value: 0.000000e+00 +m01df6100/vmem/vmpage_number-file_pages: + value: 2.255980e+05 +m01df6100/vmem/vmpage_number-free_pages: + value: 1.568625e+07 +m01df6100/vmem/vmpage_number-inactive_anon: + value: 4.600000e+01 +m01df6100/vmem/vmpage_number-inactive_file: + value: 7.480400e+04 +m01df6100/vmem/vmpage_number-isolated_anon: + value: 0.000000e+00 +m01df6100/vmem/vmpage_number-isolated_file: + value: 0.000000e+00 +m01df6100/vmem/vmpage_number-kernel_stack: + value: 4.500000e+02 +m01df6100/vmem/vmpage_number-mapped: + value: 3.560000e+03 +m01df6100/vmem/vmpage_number-mlock: + value: 0.000000e+00 +m01df6100/vmem/vmpage_number-page_table_pages: + value: 1.060000e+03 +m01df6100/vmem/vmpage_number-shmem: + value: 4.800000e+01 +m01df6100/vmem/vmpage_number-slab_reclaimable: + value: 2.369210e+05 +m01df6100/vmem/vmpage_number-slab_unreclaimable: + value: 1.479000e+04 +m01df6100/vmem/vmpage_number-unevictable: + value: 0.000000e+00 +m01df6100/vmem/vmpage_number-unstable: + value: 0.000000e+00 +m01df6100/vmem/vmpage_number-vmscan_write: + value: 0.000000e+00 +m01df6100/vmem/vmpage_number-writeback: + value: 0.000000e+00 +m01df6100/vmem/vmpage_number-writeback_temp: + value: 0.000000e+00 +m01df6200/cpu-0/cpu-idle: + value: 9.970372e+01 +m01df6200/cpu-0/cpu-interrupt: + value: 0.000000e+00 +m01df6200/cpu-0/cpu-nice: + value: 0.000000e+00 +m01df6200/cpu-0/cpu-softirq: + value: 0.000000e+00 +m01df6200/cpu-0/cpu-steal: + value: 0.000000e+00 +m01df6200/cpu-0/cpu-system: + value: 0.000000e+00 +m01df6200/cpu-0/cpu-user: + value: 0.000000e+00 +m01df6200/cpu-0/cpu-wait: + value: 0.000000e+00 +m01df6200/cpu-1/cpu-idle: + value: 1.000038e+02 +m01df6200/cpu-1/cpu-interrupt: + value: 0.000000e+00 +m01df6200/cpu-1/cpu-nice: + value: 0.000000e+00 +m01df6200/cpu-1/cpu-softirq: + value: 0.000000e+00 +m01df6200/cpu-1/cpu-steal: + value: 0.000000e+00 +m01df6200/cpu-1/cpu-system: + value: 0.000000e+00 +m01df6200/cpu-1/cpu-user: + value: 0.000000e+00 +m01df6200/cpu-1/cpu-wait: + value: 0.000000e+00 +m01df6200/cpu-10/cpu-idle: + value: 1.000043e+02 +m01df6200/cpu-10/cpu-interrupt: + value: 0.000000e+00 +m01df6200/cpu-10/cpu-nice: + value: 0.000000e+00 +m01df6200/cpu-10/cpu-softirq: + value: 0.000000e+00 +m01df6200/cpu-10/cpu-steal: + value: 0.000000e+00 +m01df6200/cpu-10/cpu-system: + value: 0.000000e+00 +m01df6200/cpu-10/cpu-user: + value: 0.000000e+00 +m01df6200/cpu-10/cpu-wait: + value: 0.000000e+00 +m01df6200/cpu-11/cpu-idle: + value: 1.000045e+02 +m01df6200/cpu-11/cpu-interrupt: + value: 0.000000e+00 +m01df6200/cpu-11/cpu-nice: + value: 0.000000e+00 +m01df6200/cpu-11/cpu-softirq: + value: 0.000000e+00 +m01df6200/cpu-11/cpu-steal: + value: 0.000000e+00 +m01df6200/cpu-11/cpu-system: + value: 0.000000e+00 +m01df6200/cpu-11/cpu-user: + value: 0.000000e+00 +m01df6200/cpu-11/cpu-wait: + value: 0.000000e+00 +m01df6200/cpu-12/cpu-idle: + value: 1.000044e+02 +m01df6200/cpu-12/cpu-interrupt: + value: 0.000000e+00 +m01df6200/cpu-12/cpu-nice: + value: 0.000000e+00 +m01df6200/cpu-12/cpu-softirq: + value: 0.000000e+00 +m01df6200/cpu-12/cpu-steal: + value: 0.000000e+00 +m01df6200/cpu-12/cpu-system: + value: 0.000000e+00 +m01df6200/cpu-12/cpu-user: + value: 0.000000e+00 +m01df6200/cpu-12/cpu-wait: + value: 0.000000e+00 +m01df6200/cpu-13/cpu-idle: + value: 1.000045e+02 +m01df6200/cpu-13/cpu-interrupt: + value: 0.000000e+00 +m01df6200/cpu-13/cpu-nice: + value: 0.000000e+00 +m01df6200/cpu-13/cpu-softirq: + value: 0.000000e+00 +m01df6200/cpu-13/cpu-steal: + value: 0.000000e+00 +m01df6200/cpu-13/cpu-system: + value: 0.000000e+00 +m01df6200/cpu-13/cpu-user: + value: 0.000000e+00 +m01df6200/cpu-13/cpu-wait: + value: 0.000000e+00 +m01df6200/cpu-14/cpu-idle: + value: 1.000044e+02 +m01df6200/cpu-14/cpu-interrupt: + value: 0.000000e+00 +m01df6200/cpu-14/cpu-nice: + value: 0.000000e+00 +m01df6200/cpu-14/cpu-softirq: + value: 0.000000e+00 +m01df6200/cpu-14/cpu-steal: + value: 0.000000e+00 +m01df6200/cpu-14/cpu-system: + value: 0.000000e+00 +m01df6200/cpu-14/cpu-user: + value: 0.000000e+00 +m01df6200/cpu-14/cpu-wait: + value: 0.000000e+00 +m01df6200/cpu-15/cpu-idle: + value: 9.990450e+01 +m01df6200/cpu-15/cpu-interrupt: + value: 0.000000e+00 +m01df6200/cpu-15/cpu-nice: + value: 0.000000e+00 +m01df6200/cpu-15/cpu-softirq: + value: 0.000000e+00 +m01df6200/cpu-15/cpu-steal: + value: 0.000000e+00 +m01df6200/cpu-15/cpu-system: + value: 0.000000e+00 +m01df6200/cpu-15/cpu-user: + value: 0.000000e+00 +m01df6200/cpu-15/cpu-wait: + value: 0.000000e+00 +m01df6200/cpu-16/cpu-idle: + value: 1.000046e+02 +m01df6200/cpu-16/cpu-interrupt: + value: 0.000000e+00 +m01df6200/cpu-16/cpu-nice: + value: 0.000000e+00 +m01df6200/cpu-16/cpu-softirq: + value: 0.000000e+00 +m01df6200/cpu-16/cpu-steal: + value: 0.000000e+00 +m01df6200/cpu-16/cpu-system: + value: 0.000000e+00 +m01df6200/cpu-16/cpu-user: + value: 0.000000e+00 +m01df6200/cpu-16/cpu-wait: + value: 0.000000e+00 +m01df6200/cpu-17/cpu-idle: + value: 1.000047e+02 +m01df6200/cpu-17/cpu-interrupt: + value: 0.000000e+00 +m01df6200/cpu-17/cpu-nice: + value: 0.000000e+00 +m01df6200/cpu-17/cpu-softirq: + value: 0.000000e+00 +m01df6200/cpu-17/cpu-steal: + value: 0.000000e+00 +m01df6200/cpu-17/cpu-system: + value: 0.000000e+00 +m01df6200/cpu-17/cpu-user: + value: 0.000000e+00 +m01df6200/cpu-17/cpu-wait: + value: 0.000000e+00 +m01df6200/cpu-18/cpu-idle: + value: 1.000047e+02 +m01df6200/cpu-18/cpu-interrupt: + value: 0.000000e+00 +m01df6200/cpu-18/cpu-nice: + value: 0.000000e+00 +m01df6200/cpu-18/cpu-softirq: + value: 0.000000e+00 +m01df6200/cpu-18/cpu-steal: + value: 0.000000e+00 +m01df6200/cpu-18/cpu-system: + value: 0.000000e+00 +m01df6200/cpu-18/cpu-user: + value: 0.000000e+00 +m01df6200/cpu-18/cpu-wait: + value: 0.000000e+00 +m01df6200/cpu-19/cpu-idle: + value: 9.990492e+01 +m01df6200/cpu-19/cpu-interrupt: + value: 0.000000e+00 +m01df6200/cpu-19/cpu-nice: + value: 0.000000e+00 +m01df6200/cpu-19/cpu-softirq: + value: 0.000000e+00 +m01df6200/cpu-19/cpu-steal: + value: 0.000000e+00 +m01df6200/cpu-19/cpu-system: + value: 0.000000e+00 +m01df6200/cpu-19/cpu-user: + value: 0.000000e+00 +m01df6200/cpu-19/cpu-wait: + value: 0.000000e+00 +m01df6200/cpu-2/cpu-idle: + value: 1.000038e+02 +m01df6200/cpu-2/cpu-interrupt: + value: 0.000000e+00 +m01df6200/cpu-2/cpu-nice: + value: 0.000000e+00 +m01df6200/cpu-2/cpu-softirq: + value: 0.000000e+00 +m01df6200/cpu-2/cpu-steal: + value: 0.000000e+00 +m01df6200/cpu-2/cpu-system: + value: 0.000000e+00 +m01df6200/cpu-2/cpu-user: + value: 0.000000e+00 +m01df6200/cpu-2/cpu-wait: + value: 0.000000e+00 +m01df6200/cpu-20/cpu-idle: + value: 9.990475e+01 +m01df6200/cpu-20/cpu-interrupt: + value: 0.000000e+00 +m01df6200/cpu-20/cpu-nice: + value: 0.000000e+00 +m01df6200/cpu-20/cpu-softirq: + value: 0.000000e+00 +m01df6200/cpu-20/cpu-steal: + value: 0.000000e+00 +m01df6200/cpu-20/cpu-system: + value: 0.000000e+00 +m01df6200/cpu-20/cpu-user: + value: 0.000000e+00 +m01df6200/cpu-20/cpu-wait: + value: 0.000000e+00 +m01df6200/cpu-21/cpu-idle: + value: 1.000048e+02 +m01df6200/cpu-21/cpu-interrupt: + value: 0.000000e+00 +m01df6200/cpu-21/cpu-nice: + value: 0.000000e+00 +m01df6200/cpu-21/cpu-softirq: + value: 0.000000e+00 +m01df6200/cpu-21/cpu-steal: + value: 0.000000e+00 +m01df6200/cpu-21/cpu-system: + value: 0.000000e+00 +m01df6200/cpu-21/cpu-user: + value: 0.000000e+00 +m01df6200/cpu-21/cpu-wait: + value: 0.000000e+00 +m01df6200/cpu-22/cpu-idle: + value: 1.000049e+02 +m01df6200/cpu-22/cpu-interrupt: + value: 0.000000e+00 +m01df6200/cpu-22/cpu-nice: + value: 0.000000e+00 +m01df6200/cpu-22/cpu-softirq: + value: 0.000000e+00 +m01df6200/cpu-22/cpu-steal: + value: 0.000000e+00 +m01df6200/cpu-22/cpu-system: + value: 0.000000e+00 +m01df6200/cpu-22/cpu-user: + value: 0.000000e+00 +m01df6200/cpu-22/cpu-wait: + value: 0.000000e+00 +m01df6200/cpu-23/cpu-idle: + value: 9.990458e+01 +m01df6200/cpu-23/cpu-interrupt: + value: 0.000000e+00 +m01df6200/cpu-23/cpu-nice: + value: 0.000000e+00 +m01df6200/cpu-23/cpu-softirq: + value: 0.000000e+00 +m01df6200/cpu-23/cpu-steal: + value: 0.000000e+00 +m01df6200/cpu-23/cpu-system: + value: 0.000000e+00 +m01df6200/cpu-23/cpu-user: + value: 0.000000e+00 +m01df6200/cpu-23/cpu-wait: + value: 0.000000e+00 +m01df6200/cpu-3/cpu-idle: + value: 9.990383e+01 +m01df6200/cpu-3/cpu-interrupt: + value: 0.000000e+00 +m01df6200/cpu-3/cpu-nice: + value: 0.000000e+00 +m01df6200/cpu-3/cpu-softirq: + value: 0.000000e+00 +m01df6200/cpu-3/cpu-steal: + value: 0.000000e+00 +m01df6200/cpu-3/cpu-system: + value: 1.000038e-01 +m01df6200/cpu-3/cpu-user: + value: 0.000000e+00 +m01df6200/cpu-3/cpu-wait: + value: 0.000000e+00 +m01df6200/cpu-4/cpu-idle: + value: 1.000039e+02 +m01df6200/cpu-4/cpu-interrupt: + value: 0.000000e+00 +m01df6200/cpu-4/cpu-nice: + value: 0.000000e+00 +m01df6200/cpu-4/cpu-softirq: + value: 0.000000e+00 +m01df6200/cpu-4/cpu-steal: + value: 0.000000e+00 +m01df6200/cpu-4/cpu-system: + value: 0.000000e+00 +m01df6200/cpu-4/cpu-user: + value: 0.000000e+00 +m01df6200/cpu-4/cpu-wait: + value: 0.000000e+00 +m01df6200/cpu-5/cpu-idle: + value: 1.000039e+02 +m01df6200/cpu-5/cpu-interrupt: + value: 0.000000e+00 +m01df6200/cpu-5/cpu-nice: + value: 0.000000e+00 +m01df6200/cpu-5/cpu-softirq: + value: 0.000000e+00 +m01df6200/cpu-5/cpu-steal: + value: 0.000000e+00 +m01df6200/cpu-5/cpu-system: + value: 0.000000e+00 +m01df6200/cpu-5/cpu-user: + value: 0.000000e+00 +m01df6200/cpu-5/cpu-wait: + value: 0.000000e+00 +m01df6200/cpu-6/cpu-idle: + value: 1.000039e+02 +m01df6200/cpu-6/cpu-interrupt: + value: 0.000000e+00 +m01df6200/cpu-6/cpu-nice: + value: 0.000000e+00 +m01df6200/cpu-6/cpu-softirq: + value: 0.000000e+00 +m01df6200/cpu-6/cpu-steal: + value: 0.000000e+00 +m01df6200/cpu-6/cpu-system: + value: 1.000039e-01 +m01df6200/cpu-6/cpu-user: + value: 0.000000e+00 +m01df6200/cpu-6/cpu-wait: + value: 0.000000e+00 +m01df6200/cpu-7/cpu-idle: + value: 9.990388e+01 +m01df6200/cpu-7/cpu-interrupt: + value: 0.000000e+00 +m01df6200/cpu-7/cpu-nice: + value: 0.000000e+00 +m01df6200/cpu-7/cpu-softirq: + value: 0.000000e+00 +m01df6200/cpu-7/cpu-steal: + value: 0.000000e+00 +m01df6200/cpu-7/cpu-system: + value: 1.000039e-01 +m01df6200/cpu-7/cpu-user: + value: 0.000000e+00 +m01df6200/cpu-7/cpu-wait: + value: 0.000000e+00 +m01df6200/cpu-8/cpu-idle: + value: 9.990408e+01 +m01df6200/cpu-8/cpu-interrupt: + value: 0.000000e+00 +m01df6200/cpu-8/cpu-nice: + value: 0.000000e+00 +m01df6200/cpu-8/cpu-softirq: + value: 0.000000e+00 +m01df6200/cpu-8/cpu-steal: + value: 0.000000e+00 +m01df6200/cpu-8/cpu-system: + value: 0.000000e+00 +m01df6200/cpu-8/cpu-user: + value: 1.000040e-01 +m01df6200/cpu-8/cpu-wait: + value: 0.000000e+00 +m01df6200/cpu-9/cpu-idle: + value: 1.000043e+02 +m01df6200/cpu-9/cpu-interrupt: + value: 0.000000e+00 +m01df6200/cpu-9/cpu-nice: + value: 0.000000e+00 +m01df6200/cpu-9/cpu-softirq: + value: 0.000000e+00 +m01df6200/cpu-9/cpu-steal: + value: 0.000000e+00 +m01df6200/cpu-9/cpu-system: + value: 0.000000e+00 +m01df6200/cpu-9/cpu-user: + value: 1.000043e-01 +m01df6200/cpu-9/cpu-wait: + value: 0.000000e+00 +m01df6200/df-boot/df_complex-free: + value: 4.368957e+08 +m01df6200/df-boot/df_complex-reserved: + value: 2.684109e+07 +m01df6200/df-boot/df_complex-used: + value: 6.468813e+07 +m01df6200/df-boot/df_inodes-free: + value: 3.271800e+04 +m01df6200/df-boot/df_inodes-reserved: + value: 0.000000e+00 +m01df6200/df-boot/df_inodes-used: + value: 5.000000e+01 +m01df6200/df-boot/percent_bytes-free: + value: 8.267886e+01 +m01df6200/df-boot/percent_bytes-reserved: + value: 5.079451e+00 +m01df6200/df-boot/percent_bytes-used: + value: 1.224169e+01 +m01df6200/df-boot/percent_inodes-free: + value: 9.984741e+01 +m01df6200/df-boot/percent_inodes-reserved: + value: 0.000000e+00 +m01df6200/df-boot/percent_inodes-used: + value: 1.525879e-01 +m01df6200/df-data1/df_complex-free: + value: 2.574203e+11 +m01df6200/df-data1/df_complex-reserved: + value: 1.378982e+10 +m01df6200/df-data1/df_complex-used: + value: 2.587075e+08 +m01df6200/df-data1/df_inodes-free: + value: 1.683427e+07 +m01df6200/df-data1/df_inodes-reserved: + value: 0.000000e+00 +m01df6200/df-data1/df_inodes-used: + value: 2.940000e+02 +m01df6200/df-data1/percent_bytes-free: + value: 9.482500e+01 +m01df6200/df-data1/percent_bytes-reserved: + value: 5.079707e+00 +m01df6200/df-data1/percent_bytes-used: + value: 9.529912e-02 +m01df6200/df-data1/percent_inodes-free: + value: 9.999825e+01 +m01df6200/df-data1/percent_inodes-reserved: + value: 0.000000e+00 +m01df6200/df-data1/percent_inodes-used: + value: 1.746407e-03 +m01df6200/df-dev-shm/df_complex-free: + value: 3.375709e+10 +m01df6200/df-dev-shm/df_complex-reserved: + value: 0.000000e+00 +m01df6200/df-dev-shm/df_complex-used: + value: 0.000000e+00 +m01df6200/df-dev-shm/df_inodes-free: + value: 8.241475e+06 +m01df6200/df-dev-shm/df_inodes-reserved: + value: 0.000000e+00 +m01df6200/df-dev-shm/df_inodes-used: + value: 1.000000e+00 +m01df6200/df-dev-shm/percent_bytes-free: + value: 1.000000e+02 +m01df6200/df-dev-shm/percent_bytes-reserved: + value: 0.000000e+00 +m01df6200/df-dev-shm/percent_bytes-used: + value: 0.000000e+00 +m01df6200/df-dev-shm/percent_inodes-free: + value: 9.999998e+01 +m01df6200/df-dev-shm/percent_inodes-reserved: + value: 0.000000e+00 +m01df6200/df-dev-shm/percent_inodes-used: + value: 1.213375e-05 +m01df6200/df-root/df_complex-free: + value: 1.073381e+10 +m01df6200/df-root/df_complex-reserved: + value: 6.442435e+08 +m01df6200/df-root/df_complex-used: + value: 1.304654e+09 +m01df6200/df-root/df_inodes-free: + value: 7.455060e+05 +m01df6200/df-root/df_inodes-reserved: + value: 0.000000e+00 +m01df6200/df-root/df_inodes-used: + value: 4.092600e+04 +m01df6200/df-root/percent_bytes-free: + value: 8.463343e+01 +m01df6200/df-root/percent_bytes-reserved: + value: 5.079700e+00 +m01df6200/df-root/percent_bytes-used: + value: 1.028687e+01 +m01df6200/df-root/percent_inodes-free: + value: 9.479599e+01 +m01df6200/df-root/percent_inodes-reserved: + value: 0.000000e+00 +m01df6200/df-root/percent_inodes-used: + value: 5.204010e+00 +m01df6200/df-var/df_complex-free: + value: 7.567528e+09 +m01df6200/df-var/df_complex-reserved: + value: 4.294943e+08 +m01df6200/df-var/df_complex-used: + value: 4.580966e+08 +m01df6200/df-var/df_inodes-free: + value: 5.228110e+05 +m01df6200/df-var/df_inodes-reserved: + value: 0.000000e+00 +m01df6200/df-var/df_inodes-used: + value: 1.477000e+03 +m01df6200/df-var/percent_bytes-free: + value: 8.950232e+01 +m01df6200/df-var/percent_bytes-reserved: + value: 5.079695e+00 +m01df6200/df-var/percent_bytes-used: + value: 5.417980e+00 +m01df6200/df-var/percent_inodes-free: + value: 9.971828e+01 +m01df6200/df-var/percent_inodes-reserved: + value: 0.000000e+00 +m01df6200/df-var/percent_inodes-used: + value: 2.817154e-01 +m01df6200/disk-sda/disk_merged: + read: 0.000000e+00 + write: 0.000000e+00 +m01df6200/disk-sda/disk_octets: + read: 0.000000e+00 + write: 0.000000e+00 +m01df6200/disk-sda/disk_ops: + read: 0.000000e+00 + write: 0.000000e+00 +m01df6200/disk-sda/disk_time: + read: 0.000000e+00 + write: 0.000000e+00 +m01df6200/disk-sda1/disk_merged: + read: 0.000000e+00 + write: 0.000000e+00 +m01df6200/disk-sda1/disk_octets: + read: 0.000000e+00 + write: 0.000000e+00 +m01df6200/disk-sda1/disk_ops: + read: 0.000000e+00 + write: 0.000000e+00 +m01df6200/disk-sda1/disk_time: + read: 0.000000e+00 + write: 0.000000e+00 +m01df6200/disk-sda2/disk_merged: + read: 0.000000e+00 + write: 0.000000e+00 +m01df6200/disk-sda2/disk_octets: + read: 0.000000e+00 + write: 0.000000e+00 +m01df6200/disk-sda2/disk_ops: + read: 0.000000e+00 + write: 0.000000e+00 +m01df6200/disk-sda2/disk_time: + read: 0.000000e+00 + write: 0.000000e+00 +m01df6200/disk-sda3/disk_merged: + read: 0.000000e+00 + write: 0.000000e+00 +m01df6200/disk-sda3/disk_octets: + read: 0.000000e+00 + write: 0.000000e+00 +m01df6200/disk-sda3/disk_ops: + read: 0.000000e+00 + write: 0.000000e+00 +m01df6200/disk-sda3/disk_time: + read: 0.000000e+00 + write: 0.000000e+00 +m01df6200/disk-sda4/disk_merged: + read: 0.000000e+00 + write: 0.000000e+00 +m01df6200/disk-sda4/disk_octets: + read: 0.000000e+00 + write: 0.000000e+00 +m01df6200/disk-sda4/disk_ops: + read: 0.000000e+00 + write: 0.000000e+00 +m01df6200/disk-sda4/disk_time: + read: 0.000000e+00 + write: 0.000000e+00 +m01df6200/disk-sda5/disk_merged: + read: 0.000000e+00 + write: 0.000000e+00 +m01df6200/disk-sda5/disk_octets: + read: 0.000000e+00 + write: 0.000000e+00 +m01df6200/disk-sda5/disk_ops: + read: 0.000000e+00 + write: 0.000000e+00 +m01df6200/disk-sda5/disk_time: + read: 0.000000e+00 + write: 0.000000e+00 +m01df6200/disk-sda6/disk_merged: + read: 0.000000e+00 + write: 0.000000e+00 +m01df6200/disk-sda6/disk_octets: + read: 0.000000e+00 + write: 0.000000e+00 +m01df6200/disk-sda6/disk_ops: + read: 0.000000e+00 + write: 0.000000e+00 +m01df6200/disk-sda6/disk_time: + read: 0.000000e+00 + write: 0.000000e+00 +m01df6200/load/load: + longterm: 0.000000e+00 + midterm: 0.000000e+00 + shortterm: 0.000000e+00 +m01df6200/memory/memory-buffered: + value: 3.312067e+08 +m01df6200/memory/memory-cached: + value: 5.615206e+08 +m01df6200/memory/memory-free: + value: 6.428290e+10 +m01df6200/memory/memory-used: + value: 2.338546e+09 +m01df6200/network/if_octets: + rx: 0.000000e+00 + tx: 1.583300e+03 +m01df6200/network/if_packets: + rx: 0.000000e+00 + tx: 1.200000e+00 +m01df6200/network/queue_length: + value: 0.000000e+00 +m01df6200/network/total_values-dispatch-accepted: + value: 0.000000e+00 +m01df6200/network/total_values-dispatch-rejected: + value: 0.000000e+00 +m01df6200/network/total_values-send-accepted: + value: 3.150000e+01 +m01df6200/network/total_values-send-rejected: + value: 0.000000e+00 +m01df6200/swap/swap-cached: + value: 0.000000e+00 +m01df6200/swap/swap-free: + value: 2.147475e+09 +m01df6200/swap/swap-used: + value: 0.000000e+00 +m01df6200/swap/swap_io-in: + value: 0.000000e+00 +m01df6200/swap/swap_io-out: + value: 0.000000e+00 +m01df6200/vmem/vmpage_faults: + majflt: 0.000000e+00 + minflt: 3.600012e+00 +m01df6200/vmem/vmpage_io-memory: + in: 0.000000e+00 + out: 0.000000e+00 +m01df6200/vmem/vmpage_io-swap: + in: 0.000000e+00 + out: 0.000000e+00 +m01df6200/vmem/vmpage_number-active_anon: + value: 2.124650e+05 +m01df6200/vmem/vmpage_number-active_file: + value: 1.424970e+05 +m01df6200/vmem/vmpage_number-anon_pages: + value: 1.227400e+04 +m01df6200/vmem/vmpage_number-anon_transparent_hugepages: + value: 3.910000e+02 +m01df6200/vmem/vmpage_number-boudfe: + value: 0.000000e+00 +m01df6200/vmem/vmpage_number-dirty: + value: 0.000000e+00 +m01df6200/vmem/vmpage_number-file_pages: + value: 2.179510e+05 +m01df6200/vmem/vmpage_number-free_pages: + value: 1.569406e+07 +m01df6200/vmem/vmpage_number-inactive_anon: + value: 4.800000e+01 +m01df6200/vmem/vmpage_number-inactive_file: + value: 7.540800e+04 +m01df6200/vmem/vmpage_number-isolated_anon: + value: 0.000000e+00 +m01df6200/vmem/vmpage_number-isolated_file: + value: 0.000000e+00 +m01df6200/vmem/vmpage_number-kernel_stack: + value: 4.460000e+02 +m01df6200/vmem/vmpage_number-mapped: + value: 3.063000e+03 +m01df6200/vmem/vmpage_number-mlock: + value: 0.000000e+00 +m01df6200/vmem/vmpage_number-page_table_pages: + value: 8.920000e+02 +m01df6200/vmem/vmpage_number-shmem: + value: 5.000000e+01 +m01df6200/vmem/vmpage_number-slab_reclaimable: + value: 2.398380e+05 +m01df6200/vmem/vmpage_number-slab_unreclaimable: + value: 1.473600e+04 +m01df6200/vmem/vmpage_number-unevictable: + value: 0.000000e+00 +m01df6200/vmem/vmpage_number-unstable: + value: 0.000000e+00 +m01df6200/vmem/vmpage_number-vmscan_write: + value: 0.000000e+00 +m01df6200/vmem/vmpage_number-writeback: + value: 0.000000e+00 +m01df6200/vmem/vmpage_number-writeback_temp: + value: 0.000000e+00 +w838f6010/cpu-0/cpu-idle: + value: 9.990008e+01 +w838f6010/cpu-0/cpu-interrupt: + value: 0.000000e+00 +w838f6010/cpu-0/cpu-nice: + value: 0.000000e+00 +w838f6010/cpu-0/cpu-softirq: + value: 0.000000e+00 +w838f6010/cpu-0/cpu-steal: + value: 0.000000e+00 +w838f6010/cpu-0/cpu-system: + value: 0.000000e+00 +w838f6010/cpu-0/cpu-user: + value: 0.000000e+00 +w838f6010/cpu-0/cpu-wait: + value: 0.000000e+00 +w838f6010/cpu-1/cpu-idle: + value: 9.980017e+01 +w838f6010/cpu-1/cpu-interrupt: + value: 0.000000e+00 +w838f6010/cpu-1/cpu-nice: + value: 0.000000e+00 +w838f6010/cpu-1/cpu-softirq: + value: 0.000000e+00 +w838f6010/cpu-1/cpu-steal: + value: 0.000000e+00 +w838f6010/cpu-1/cpu-system: + value: 0.000000e+00 +w838f6010/cpu-1/cpu-user: + value: 0.000000e+00 +w838f6010/cpu-1/cpu-wait: + value: 0.000000e+00 +w838f6010/df-boot/df_complex-free: + value: 4.793754e+08 +w838f6010/df-boot/df_complex-reserved: + value: 2.684109e+07 +w838f6010/df-boot/df_complex-used: + value: 2.220851e+07 +w838f6010/df-boot/df_inodes-free: + value: 3.273000e+04 +w838f6010/df-boot/df_inodes-reserved: + value: 0.000000e+00 +w838f6010/df-boot/df_inodes-used: + value: 3.800000e+01 +w838f6010/df-boot/percent_bytes-free: + value: 9.071777e+01 +w838f6010/df-boot/percent_bytes-reserved: + value: 5.079451e+00 +w838f6010/df-boot/percent_bytes-used: + value: 4.202775e+00 +w838f6010/df-boot/percent_inodes-free: + value: 9.988403e+01 +w838f6010/df-boot/percent_inodes-reserved: + value: 0.000000e+00 +w838f6010/df-boot/percent_inodes-used: + value: 1.159668e-01 +w838f6010/df-data1/df_complex-free: + value: 2.740491e+10 +w838f6010/df-data1/df_complex-reserved: + value: 1.476235e+09 +w838f6010/df-data1/df_complex-used: + value: 1.802977e+08 +w838f6010/df-data1/df_inodes-free: + value: 1.802227e+06 +w838f6010/df-data1/df_inodes-reserved: + value: 0.000000e+00 +w838f6010/df-data1/df_inodes-used: + value: 1.300000e+01 +w838f6010/df-data1/percent_bytes-free: + value: 9.429990e+01 +w838f6010/df-data1/percent_bytes-reserved: + value: 5.079704e+00 +w838f6010/df-data1/percent_bytes-used: + value: 6.204019e-01 +w838f6010/df-data1/percent_inodes-free: + value: 9.999928e+01 +w838f6010/df-data1/percent_inodes-reserved: + value: 0.000000e+00 +w838f6010/df-data1/percent_inodes-used: + value: 7.213246e-04 +w838f6010/df-dev-shm/df_complex-free: + value: 9.842483e+08 +w838f6010/df-dev-shm/df_complex-reserved: + value: 0.000000e+00 +w838f6010/df-dev-shm/df_complex-used: + value: 0.000000e+00 +w838f6010/df-dev-shm/df_inodes-free: + value: 2.402940e+05 +w838f6010/df-dev-shm/df_inodes-reserved: + value: 0.000000e+00 +w838f6010/df-dev-shm/df_inodes-used: + value: 1.000000e+00 +w838f6010/df-dev-shm/percent_bytes-free: + value: 1.000000e+02 +w838f6010/df-dev-shm/percent_bytes-reserved: + value: 0.000000e+00 +w838f6010/df-dev-shm/percent_bytes-used: + value: 0.000000e+00 +w838f6010/df-dev-shm/percent_inodes-free: + value: 9.999958e+01 +w838f6010/df-dev-shm/percent_inodes-reserved: + value: 0.000000e+00 +w838f6010/df-dev-shm/percent_inodes-used: + value: 4.161551e-04 +w838f6010/df-root/df_complex-free: + value: 1.099070e+10 +w838f6010/df-root/df_complex-reserved: + value: 6.442435e+08 +w838f6010/df-root/df_complex-used: + value: 1.047761e+09 +w838f6010/df-root/df_inodes-free: + value: 7.509290e+05 +w838f6010/df-root/df_inodes-reserved: + value: 0.000000e+00 +w838f6010/df-root/df_inodes-used: + value: 3.550300e+04 +w838f6010/df-root/percent_bytes-free: + value: 8.665897e+01 +w838f6010/df-root/percent_bytes-reserved: + value: 5.079700e+00 +w838f6010/df-root/percent_bytes-used: + value: 8.261335e+00 +w838f6010/df-root/percent_inodes-free: + value: 9.548557e+01 +w838f6010/df-root/percent_inodes-reserved: + value: 0.000000e+00 +w838f6010/df-root/percent_inodes-used: + value: 4.514440e+00 +w838f6010/df-var/df_complex-free: + value: 7.638827e+09 +w838f6010/df-var/df_complex-reserved: + value: 4.294943e+08 +w838f6010/df-var/df_complex-used: + value: 3.867976e+08 +w838f6010/df-var/df_inodes-free: + value: 5.230900e+05 +w838f6010/df-var/df_inodes-reserved: + value: 0.000000e+00 +w838f6010/df-var/df_inodes-used: + value: 1.198000e+03 +w838f6010/df-var/percent_bytes-free: + value: 9.034559e+01 +w838f6010/df-var/percent_bytes-reserved: + value: 5.079695e+00 +w838f6010/df-var/percent_bytes-used: + value: 4.574715e+00 +w838f6010/df-var/percent_inodes-free: + value: 9.977150e+01 +w838f6010/df-var/percent_inodes-reserved: + value: 0.000000e+00 +w838f6010/df-var/percent_inodes-used: + value: 2.285004e-01 +w838f6010/disk-vda/disk_merged: + read: 0.000000e+00 + write: 0.000000e+00 +w838f6010/disk-vda/disk_octets: + read: 0.000000e+00 + write: 0.000000e+00 +w838f6010/disk-vda/disk_ops: + read: 0.000000e+00 + write: 0.000000e+00 +w838f6010/disk-vda/disk_time: + read: 0.000000e+00 + write: 0.000000e+00 +w838f6010/disk-vda1/disk_merged: + read: 0.000000e+00 + write: 0.000000e+00 +w838f6010/disk-vda1/disk_octets: + read: 0.000000e+00 + write: 0.000000e+00 +w838f6010/disk-vda1/disk_ops: + read: 0.000000e+00 + write: 0.000000e+00 +w838f6010/disk-vda1/disk_time: + read: 0.000000e+00 + write: 0.000000e+00 +w838f6010/disk-vda2/disk_merged: + read: 0.000000e+00 + write: 0.000000e+00 +w838f6010/disk-vda2/disk_octets: + read: 0.000000e+00 + write: 0.000000e+00 +w838f6010/disk-vda2/disk_ops: + read: 0.000000e+00 + write: 0.000000e+00 +w838f6010/disk-vda2/disk_time: + read: 0.000000e+00 + write: 0.000000e+00 +w838f6010/disk-vda3/disk_merged: + read: 0.000000e+00 + write: 0.000000e+00 +w838f6010/disk-vda3/disk_octets: + read: 0.000000e+00 + write: 0.000000e+00 +w838f6010/disk-vda3/disk_ops: + read: 0.000000e+00 + write: 0.000000e+00 +w838f6010/disk-vda3/disk_time: + read: 0.000000e+00 + write: 0.000000e+00 +w838f6010/disk-vda4/disk_merged: + read: 0.000000e+00 + write: 0.000000e+00 +w838f6010/disk-vda4/disk_octets: + read: 0.000000e+00 + write: 0.000000e+00 +w838f6010/disk-vda4/disk_ops: + read: 0.000000e+00 + write: 0.000000e+00 +w838f6010/disk-vda4/disk_time: + read: 0.000000e+00 + write: 0.000000e+00 +w838f6010/disk-vda5/disk_merged: + read: 0.000000e+00 + write: 0.000000e+00 +w838f6010/disk-vda5/disk_octets: + read: 0.000000e+00 + write: 0.000000e+00 +w838f6010/disk-vda5/disk_ops: + read: 0.000000e+00 + write: 0.000000e+00 +w838f6010/disk-vda5/disk_time: + read: 0.000000e+00 + write: 0.000000e+00 +w838f6010/disk-vda6/disk_merged: + read: 0.000000e+00 + write: 0.000000e+00 +w838f6010/disk-vda6/disk_octets: + read: 0.000000e+00 + write: 0.000000e+00 +w838f6010/disk-vda6/disk_ops: + read: 0.000000e+00 + write: 0.000000e+00 +w838f6010/disk-vda6/disk_time: + read: 0.000000e+00 + write: 0.000000e+00 +w838f6010/load/load: + longterm: 0.000000e+00 + midterm: 2.000000e-02 + shortterm: 2.000000e-02 +w838f6010/memory/memory-buffered: + value: 1.263739e+08 +w838f6010/memory/memory-cached: + value: 4.350566e+08 +w838f6010/memory/memory-free: + value: 1.024844e+09 +w838f6010/memory/memory-used: + value: 3.822223e+08 +w838f6010/network/if_octets: + rx: 0.000000e+00 + tx: 6.632999e+02 +w838f6010/network/if_packets: + rx: 0.000000e+00 + tx: 5.000010e-01 +w838f6010/network/queue_length: + value: 0.000000e+00 +w838f6010/network/total_values-dispatch-accepted: + value: 0.000000e+00 +w838f6010/network/total_values-dispatch-rejected: + value: 0.000000e+00 +w838f6010/network/total_values-send-accepted: + value: 1.480000e+01 +w838f6010/network/total_values-send-rejected: + value: 0.000000e+00 +w838f6010/swap/swap-cached: + value: 0.000000e+00 +w838f6010/swap/swap-free: + value: 2.147475e+09 +w838f6010/swap/swap-used: + value: 0.000000e+00 +w838f6010/swap/swap_io-in: + value: 0.000000e+00 +w838f6010/swap/swap_io-out: + value: 0.000000e+00 +w838f6010/vmem/vmpage_faults: + majflt: 0.000000e+00 + minflt: 4.999995e+00 +w838f6010/vmem/vmpage_io-memory: + in: 0.000000e+00 + out: 0.000000e+00 +w838f6010/vmem/vmpage_io-swap: + in: 0.000000e+00 + out: 0.000000e+00 +w838f6010/vmem/vmpage_number-active_anon: + value: 1.249400e+04 +w838f6010/vmem/vmpage_number-active_file: + value: 7.016800e+04 +w838f6010/vmem/vmpage_number-anon_pages: + value: 1.095500e+04 +w838f6010/vmem/vmpage_number-anon_transparent_hugepages: + value: 3.000000e+00 +w838f6010/vmem/vmpage_number-boudfe: + value: 0.000000e+00 +w838f6010/vmem/vmpage_number-dirty: + value: 0.000000e+00 +w838f6010/vmem/vmpage_number-file_pages: + value: 1.370680e+05 +w838f6010/vmem/vmpage_number-free_pages: + value: 2.502060e+05 +w838f6010/vmem/vmpage_number-inactive_anon: + value: 4.200000e+01 +w838f6010/vmem/vmpage_number-inactive_file: + value: 6.685900e+04 +w838f6010/vmem/vmpage_number-isolated_anon: + value: 0.000000e+00 +w838f6010/vmem/vmpage_number-isolated_file: + value: 0.000000e+00 +w838f6010/vmem/vmpage_number-kernel_stack: + value: 1.130000e+02 +w838f6010/vmem/vmpage_number-mapped: + value: 1.480000e+03 +w838f6010/vmem/vmpage_number-mlock: + value: 0.000000e+00 +w838f6010/vmem/vmpage_number-page_table_pages: + value: 4.220000e+02 +w838f6010/vmem/vmpage_number-shmem: + value: 4.500000e+01 +w838f6010/vmem/vmpage_number-slab_reclaimable: + value: 6.896900e+04 +w838f6010/vmem/vmpage_number-slab_unreclaimable: + value: 5.190000e+03 +w838f6010/vmem/vmpage_number-unevictable: + value: 0.000000e+00 +w838f6010/vmem/vmpage_number-unstable: + value: 0.000000e+00 +w838f6010/vmem/vmpage_number-vmscan_write: + value: 0.000000e+00 +w838f6010/vmem/vmpage_number-writeback: + value: 0.000000e+00 +w838f6010/vmem/vmpage_number-writeback_temp: + value: 0.000000e+00 +w838f6700/cpu-0/cpu-idle: + value: 9.619931e+01 +w838f6700/cpu-0/cpu-interrupt: + value: 0.000000e+00 +w838f6700/cpu-0/cpu-nice: + value: 0.000000e+00 +w838f6700/cpu-0/cpu-softirq: + value: 0.000000e+00 +w838f6700/cpu-0/cpu-steal: + value: 0.000000e+00 +w838f6700/cpu-0/cpu-system: + value: 1.899992e+00 +w838f6700/cpu-0/cpu-user: + value: 1.600000e+00 +w838f6700/cpu-0/cpu-wait: + value: 0.000000e+00 +w838f6700/cpu-1/cpu-idle: + value: 9.599589e+01 +w838f6700/cpu-1/cpu-interrupt: + value: 0.000000e+00 +w838f6700/cpu-1/cpu-nice: + value: 0.000000e+00 +w838f6700/cpu-1/cpu-softirq: + value: 0.000000e+00 +w838f6700/cpu-1/cpu-steal: + value: 0.000000e+00 +w838f6700/cpu-1/cpu-system: + value: 1.799923e+00 +w838f6700/cpu-1/cpu-user: + value: 1.799919e+00 +w838f6700/cpu-1/cpu-wait: + value: 0.000000e+00 +w838f6700/cpu-2/cpu-idle: + value: 9.539595e+01 +w838f6700/cpu-2/cpu-interrupt: + value: 0.000000e+00 +w838f6700/cpu-2/cpu-nice: + value: 0.000000e+00 +w838f6700/cpu-2/cpu-softirq: + value: 0.000000e+00 +w838f6700/cpu-2/cpu-steal: + value: 9.999593e-02 +w838f6700/cpu-2/cpu-system: + value: 2.299903e+00 +w838f6700/cpu-2/cpu-user: + value: 1.899919e+00 +w838f6700/cpu-2/cpu-wait: + value: 0.000000e+00 +w838f6700/cpu-3/cpu-idle: + value: 9.439610e+01 +w838f6700/cpu-3/cpu-interrupt: + value: 0.000000e+00 +w838f6700/cpu-3/cpu-nice: + value: 0.000000e+00 +w838f6700/cpu-3/cpu-softirq: + value: 0.000000e+00 +w838f6700/cpu-3/cpu-steal: + value: 0.000000e+00 +w838f6700/cpu-3/cpu-system: + value: 2.699890e+00 +w838f6700/cpu-3/cpu-user: + value: 2.599893e+00 +w838f6700/cpu-3/cpu-wait: + value: 0.000000e+00 +w838f6700/df-boot/df_complex-free: + value: 4.793713e+08 +w838f6700/df-boot/df_complex-reserved: + value: 2.684109e+07 +w838f6700/df-boot/df_complex-used: + value: 2.221261e+07 +w838f6700/df-boot/df_inodes-free: + value: 3.273000e+04 +w838f6700/df-boot/df_inodes-reserved: + value: 0.000000e+00 +w838f6700/df-boot/df_inodes-used: + value: 3.800000e+01 +w838f6700/df-boot/percent_bytes-free: + value: 9.071700e+01 +w838f6700/df-boot/percent_bytes-reserved: + value: 5.079451e+00 +w838f6700/df-boot/percent_bytes-used: + value: 4.203550e+00 +w838f6700/df-boot/percent_inodes-free: + value: 9.988403e+01 +w838f6700/df-boot/percent_inodes-reserved: + value: 0.000000e+00 +w838f6700/df-boot/percent_inodes-used: + value: 1.159668e-01 +w838f6700/df-data1/df_complex-free: + value: 2.740491e+10 +w838f6700/df-data1/df_complex-reserved: + value: 1.476235e+09 +w838f6700/df-data1/df_complex-used: + value: 1.802977e+08 +w838f6700/df-data1/df_inodes-free: + value: 1.802227e+06 +w838f6700/df-data1/df_inodes-reserved: + value: 0.000000e+00 +w838f6700/df-data1/df_inodes-used: + value: 1.300000e+01 +w838f6700/df-data1/percent_bytes-free: + value: 9.429990e+01 +w838f6700/df-data1/percent_bytes-reserved: + value: 5.079704e+00 +w838f6700/df-data1/percent_bytes-used: + value: 6.204019e-01 +w838f6700/df-data1/percent_inodes-free: + value: 9.999928e+01 +w838f6700/df-data1/percent_inodes-reserved: + value: 0.000000e+00 +w838f6700/df-data1/percent_inodes-used: + value: 7.213246e-04 +w838f6700/df-dev-shm/df_complex-free: + value: 4.126425e+09 +w838f6700/df-dev-shm/df_complex-reserved: + value: 0.000000e+00 +w838f6700/df-dev-shm/df_complex-used: + value: 0.000000e+00 +w838f6700/df-dev-shm/df_inodes-free: + value: 1.007427e+06 +w838f6700/df-dev-shm/df_inodes-reserved: + value: 0.000000e+00 +w838f6700/df-dev-shm/df_inodes-used: + value: 1.000000e+00 +w838f6700/df-dev-shm/percent_bytes-free: + value: 1.000000e+02 +w838f6700/df-dev-shm/percent_bytes-reserved: + value: 0.000000e+00 +w838f6700/df-dev-shm/percent_bytes-used: + value: 0.000000e+00 +w838f6700/df-dev-shm/percent_inodes-free: + value: 9.999990e+01 +w838f6700/df-dev-shm/percent_inodes-reserved: + value: 0.000000e+00 +w838f6700/df-dev-shm/percent_inodes-used: + value: 9.926267e-05 +w838f6700/df-root/df_complex-free: + value: 1.069915e+10 +w838f6700/df-root/df_complex-reserved: + value: 6.442435e+08 +w838f6700/df-root/df_complex-used: + value: 1.339314e+09 +w838f6700/df-root/df_inodes-free: + value: 7.466750e+05 +w838f6700/df-root/df_inodes-reserved: + value: 0.000000e+00 +w838f6700/df-root/df_inodes-used: + value: 3.975700e+04 +w838f6700/df-root/percent_bytes-free: + value: 8.436014e+01 +w838f6700/df-root/percent_bytes-reserved: + value: 5.079700e+00 +w838f6700/df-root/percent_bytes-used: + value: 1.056016e+01 +w838f6700/df-root/percent_inodes-free: + value: 9.494464e+01 +w838f6700/df-root/percent_inodes-reserved: + value: 0.000000e+00 +w838f6700/df-root/percent_inodes-used: + value: 5.055364e+00 +w838f6700/df-var/df_complex-free: + value: 6.687375e+09 +w838f6700/df-var/df_complex-reserved: + value: 4.294943e+08 +w838f6700/df-var/df_complex-used: + value: 1.338249e+09 +w838f6700/df-var/df_inodes-free: + value: 5.212840e+05 +w838f6700/df-var/df_inodes-reserved: + value: 0.000000e+00 +w838f6700/df-var/df_inodes-used: + value: 3.004000e+03 +w838f6700/df-var/percent_bytes-free: + value: 7.909262e+01 +w838f6700/df-var/percent_bytes-reserved: + value: 5.079695e+00 +w838f6700/df-var/percent_bytes-used: + value: 1.582768e+01 +w838f6700/df-var/percent_inodes-free: + value: 9.942703e+01 +w838f6700/df-var/percent_inodes-reserved: + value: 0.000000e+00 +w838f6700/df-var/percent_inodes-used: + value: 5.729675e-01 +w838f6700/disk-vda/disk_merged: + read: 0.000000e+00 + write: 1.000002e-01 +w838f6700/disk-vda/disk_octets: + read: 0.000000e+00 + write: 2.457603e+03 +w838f6700/disk-vda/disk_ops: + read: 0.000000e+00 + write: 5.000007e-01 +w838f6700/disk-vda/disk_time: + read: 0.000000e+00 + write: 1.200001e+00 +w838f6700/disk-vda1/disk_merged: + read: 0.000000e+00 + write: 0.000000e+00 +w838f6700/disk-vda1/disk_octets: + read: 0.000000e+00 + write: 0.000000e+00 +w838f6700/disk-vda1/disk_ops: + read: 0.000000e+00 + write: 0.000000e+00 +w838f6700/disk-vda1/disk_time: + read: 0.000000e+00 + write: 0.000000e+00 +w838f6700/disk-vda2/disk_merged: + read: 0.000000e+00 + write: 0.000000e+00 +w838f6700/disk-vda2/disk_octets: + read: 0.000000e+00 + write: 0.000000e+00 +w838f6700/disk-vda2/disk_ops: + read: 0.000000e+00 + write: 0.000000e+00 +w838f6700/disk-vda2/disk_time: + read: 0.000000e+00 + write: 0.000000e+00 +w838f6700/disk-vda3/disk_merged: + read: 0.000000e+00 + write: 1.000001e-01 +w838f6700/disk-vda3/disk_octets: + read: 0.000000e+00 + write: 2.457604e+03 +w838f6700/disk-vda3/disk_ops: + read: 0.000000e+00 + write: 5.000007e-01 +w838f6700/disk-vda3/disk_time: + read: 0.000000e+00 + write: 1.200002e+00 +w838f6700/disk-vda4/disk_merged: + read: 0.000000e+00 + write: 0.000000e+00 +w838f6700/disk-vda4/disk_octets: + read: 0.000000e+00 + write: 0.000000e+00 +w838f6700/disk-vda4/disk_ops: + read: 0.000000e+00 + write: 0.000000e+00 +w838f6700/disk-vda4/disk_time: + read: 0.000000e+00 + write: 0.000000e+00 +w838f6700/disk-vda5/disk_merged: + read: 0.000000e+00 + write: 0.000000e+00 +w838f6700/disk-vda5/disk_octets: + read: 0.000000e+00 + write: 0.000000e+00 +w838f6700/disk-vda5/disk_ops: + read: 0.000000e+00 + write: 0.000000e+00 +w838f6700/disk-vda5/disk_time: + read: 0.000000e+00 + write: 0.000000e+00 +w838f6700/disk-vda6/disk_merged: + read: 0.000000e+00 + write: 0.000000e+00 +w838f6700/disk-vda6/disk_octets: + read: 0.000000e+00 + write: 0.000000e+00 +w838f6700/disk-vda6/disk_ops: + read: 0.000000e+00 + write: 0.000000e+00 +w838f6700/disk-vda6/disk_time: + read: 0.000000e+00 + write: 0.000000e+00 +w838f6700/load/load: + longterm: 2.000000e-02 + midterm: 4.000000e-02 + shortterm: 0.000000e+00 +w838f6700/memory/memory-buffered: + value: 1.980662e+08 +w838f6700/memory/memory-cached: + value: 1.702576e+09 +w838f6700/memory/memory-free: + value: 4.717773e+09 +w838f6700/memory/memory-used: + value: 1.634439e+09 +w838f6700/network/if_octets: + rx: 0.000000e+00 + tx: 9.293005e+02 +w838f6700/network/if_packets: + rx: 0.000000e+00 + tx: 7.000008e-01 +w838f6700/network/queue_length: + value: 0.000000e+00 +w838f6700/network/total_values-dispatch-accepted: + value: 0.000000e+00 +w838f6700/network/total_values-dispatch-rejected: + value: 0.000000e+00 +w838f6700/network/total_values-send-accepted: + value: 1.640000e+01 +w838f6700/network/total_values-send-rejected: + value: 0.000000e+00 +w838f6700/swap/swap-cached: + value: 0.000000e+00 +w838f6700/swap/swap-free: + value: 2.147475e+09 +w838f6700/swap/swap-used: + value: 0.000000e+00 +w838f6700/swap/swap_io-in: + value: 0.000000e+00 +w838f6700/swap/swap_io-out: + value: 0.000000e+00 +w838f6700/vmem/vmpage_faults: + majflt: 0.000000e+00 + minflt: 2.519992e+01 +w838f6700/vmem/vmpage_io-memory: + in: 0.000000e+00 + out: 1.999993e+00 +w838f6700/vmem/vmpage_io-swap: + in: 0.000000e+00 + out: 0.000000e+00 +w838f6700/vmem/vmpage_number-active_anon: + value: 2.680560e+05 +w838f6700/vmem/vmpage_number-active_file: + value: 1.344860e+05 +w838f6700/vmem/vmpage_number-anon_pages: + value: 1.661620e+05 +w838f6700/vmem/vmpage_number-anon_transparent_hugepages: + value: 1.990000e+02 +w838f6700/vmem/vmpage_number-boudfe: + value: 0.000000e+00 +w838f6700/vmem/vmpage_number-dirty: + value: 6.000000e+00 +w838f6700/vmem/vmpage_number-file_pages: + value: 4.640230e+05 +w838f6700/vmem/vmpage_number-free_pages: + value: 1.151800e+06 +w838f6700/vmem/vmpage_number-inactive_anon: + value: 6.300000e+01 +w838f6700/vmem/vmpage_number-inactive_file: + value: 3.294730e+05 +w838f6700/vmem/vmpage_number-isolated_anon: + value: 0.000000e+00 +w838f6700/vmem/vmpage_number-isolated_file: + value: 0.000000e+00 +w838f6700/vmem/vmpage_number-kernel_stack: + value: 2.060000e+02 +w838f6700/vmem/vmpage_number-mapped: + value: 7.423000e+03 +w838f6700/vmem/vmpage_number-mlock: + value: 0.000000e+00 +w838f6700/vmem/vmpage_number-page_table_pages: + value: 2.612000e+03 +w838f6700/vmem/vmpage_number-shmem: + value: 6.900000e+01 +w838f6700/vmem/vmpage_number-slab_reclaimable: + value: 1.048400e+05 +w838f6700/vmem/vmpage_number-slab_unreclaimable: + value: 6.180000e+03 +w838f6700/vmem/vmpage_number-unevictable: + value: 0.000000e+00 +w838f6700/vmem/vmpage_number-unstable: + value: 0.000000e+00 +w838f6700/vmem/vmpage_number-vmscan_write: + value: 0.000000e+00 +w838f6700/vmem/vmpage_number-writeback: + value: 0.000000e+00 +w838f6700/vmem/vmpage_number-writeback_temp: + value: 0.000000e+00 +w838f6800/cpu-0/cpu-idle: + value: 1.000001e+02 +w838f6800/cpu-0/cpu-interrupt: + value: 0.000000e+00 +w838f6800/cpu-0/cpu-nice: + value: 0.000000e+00 +w838f6800/cpu-0/cpu-softirq: + value: 0.000000e+00 +w838f6800/cpu-0/cpu-steal: + value: 0.000000e+00 +w838f6800/cpu-0/cpu-system: + value: 0.000000e+00 +w838f6800/cpu-0/cpu-user: + value: 0.000000e+00 +w838f6800/cpu-0/cpu-wait: + value: 0.000000e+00 +w838f6800/cpu-1/cpu-idle: + value: 9.989984e+01 +w838f6800/cpu-1/cpu-interrupt: + value: 0.000000e+00 +w838f6800/cpu-1/cpu-nice: + value: 0.000000e+00 +w838f6800/cpu-1/cpu-softirq: + value: 0.000000e+00 +w838f6800/cpu-1/cpu-steal: + value: 0.000000e+00 +w838f6800/cpu-1/cpu-system: + value: 0.000000e+00 +w838f6800/cpu-1/cpu-user: + value: 0.000000e+00 +w838f6800/cpu-1/cpu-wait: + value: 0.000000e+00 +w838f6800/cpu-2/cpu-idle: + value: 9.989981e+01 +w838f6800/cpu-2/cpu-interrupt: + value: 0.000000e+00 +w838f6800/cpu-2/cpu-nice: + value: 0.000000e+00 +w838f6800/cpu-2/cpu-softirq: + value: 0.000000e+00 +w838f6800/cpu-2/cpu-steal: + value: 0.000000e+00 +w838f6800/cpu-2/cpu-system: + value: 0.000000e+00 +w838f6800/cpu-2/cpu-user: + value: 0.000000e+00 +w838f6800/cpu-2/cpu-wait: + value: 0.000000e+00 +w838f6800/cpu-3/cpu-idle: + value: 9.989982e+01 +w838f6800/cpu-3/cpu-interrupt: + value: 0.000000e+00 +w838f6800/cpu-3/cpu-nice: + value: 0.000000e+00 +w838f6800/cpu-3/cpu-softirq: + value: 0.000000e+00 +w838f6800/cpu-3/cpu-steal: + value: 0.000000e+00 +w838f6800/cpu-3/cpu-system: + value: 0.000000e+00 +w838f6800/cpu-3/cpu-user: + value: 0.000000e+00 +w838f6800/cpu-3/cpu-wait: + value: 0.000000e+00 +w838f6800/df-boot/df_complex-free: + value: 4.793917e+08 +w838f6800/df-boot/df_complex-reserved: + value: 2.684109e+07 +w838f6800/df-boot/df_complex-used: + value: 2.219213e+07 +w838f6800/df-boot/df_inodes-free: + value: 3.273000e+04 +w838f6800/df-boot/df_inodes-reserved: + value: 0.000000e+00 +w838f6800/df-boot/df_inodes-used: + value: 3.800000e+01 +w838f6800/df-boot/percent_bytes-free: + value: 9.072087e+01 +w838f6800/df-boot/percent_bytes-reserved: + value: 5.079451e+00 +w838f6800/df-boot/percent_bytes-used: + value: 4.199674e+00 +w838f6800/df-boot/percent_inodes-free: + value: 9.988403e+01 +w838f6800/df-boot/percent_inodes-reserved: + value: 0.000000e+00 +w838f6800/df-boot/percent_inodes-used: + value: 1.159668e-01 +w838f6800/df-data1/df_complex-free: + value: 2.740491e+10 +w838f6800/df-data1/df_complex-reserved: + value: 1.476235e+09 +w838f6800/df-data1/df_complex-used: + value: 1.802977e+08 +w838f6800/df-data1/df_inodes-free: + value: 1.802227e+06 +w838f6800/df-data1/df_inodes-reserved: + value: 0.000000e+00 +w838f6800/df-data1/df_inodes-used: + value: 1.300000e+01 +w838f6800/df-data1/percent_bytes-free: + value: 9.429990e+01 +w838f6800/df-data1/percent_bytes-reserved: + value: 5.079704e+00 +w838f6800/df-data1/percent_bytes-used: + value: 6.204019e-01 +w838f6800/df-data1/percent_inodes-free: + value: 9.999928e+01 +w838f6800/df-data1/percent_inodes-reserved: + value: 0.000000e+00 +w838f6800/df-data1/percent_inodes-used: + value: 7.213246e-04 +w838f6800/df-dev-shm/df_complex-free: + value: 4.126425e+09 +w838f6800/df-dev-shm/df_complex-reserved: + value: 0.000000e+00 +w838f6800/df-dev-shm/df_complex-used: + value: 0.000000e+00 +w838f6800/df-dev-shm/df_inodes-free: + value: 1.007427e+06 +w838f6800/df-dev-shm/df_inodes-reserved: + value: 0.000000e+00 +w838f6800/df-dev-shm/df_inodes-used: + value: 1.000000e+00 +w838f6800/df-dev-shm/percent_bytes-free: + value: 1.000000e+02 +w838f6800/df-dev-shm/percent_bytes-reserved: + value: 0.000000e+00 +w838f6800/df-dev-shm/percent_bytes-used: + value: 0.000000e+00 +w838f6800/df-dev-shm/percent_inodes-free: + value: 9.999990e+01 +w838f6800/df-dev-shm/percent_inodes-reserved: + value: 0.000000e+00 +w838f6800/df-dev-shm/percent_inodes-used: + value: 9.926267e-05 +w838f6800/df-root/df_complex-free: + value: 1.099071e+10 +w838f6800/df-root/df_complex-reserved: + value: 6.442435e+08 +w838f6800/df-root/df_complex-used: + value: 1.047757e+09 +w838f6800/df-root/df_inodes-free: + value: 7.509280e+05 +w838f6800/df-root/df_inodes-reserved: + value: 0.000000e+00 +w838f6800/df-root/df_inodes-used: + value: 3.550400e+04 +w838f6800/df-root/percent_bytes-free: + value: 8.665900e+01 +w838f6800/df-root/percent_bytes-reserved: + value: 5.079700e+00 +w838f6800/df-root/percent_bytes-used: + value: 8.261303e+00 +w838f6800/df-root/percent_inodes-free: + value: 9.548543e+01 +w838f6800/df-root/percent_inodes-reserved: + value: 0.000000e+00 +w838f6800/df-root/percent_inodes-used: + value: 4.514567e+00 +w838f6800/df-var/df_complex-free: + value: 7.635927e+09 +w838f6800/df-var/df_complex-reserved: + value: 4.294943e+08 +w838f6800/df-var/df_complex-used: + value: 3.896975e+08 +w838f6800/df-var/df_inodes-free: + value: 5.230400e+05 +w838f6800/df-var/df_inodes-reserved: + value: 0.000000e+00 +w838f6800/df-var/df_inodes-used: + value: 1.248000e+03 +w838f6800/df-var/percent_bytes-free: + value: 9.031129e+01 +w838f6800/df-var/percent_bytes-reserved: + value: 5.079695e+00 +w838f6800/df-var/percent_bytes-used: + value: 4.609013e+00 +w838f6800/df-var/percent_inodes-free: + value: 9.976196e+01 +w838f6800/df-var/percent_inodes-reserved: + value: 0.000000e+00 +w838f6800/df-var/percent_inodes-used: + value: 2.380371e-01 +w838f6800/disk-vda/disk_merged: + read: 0.000000e+00 + write: 0.000000e+00 +w838f6800/disk-vda/disk_octets: + read: 0.000000e+00 + write: 0.000000e+00 +w838f6800/disk-vda/disk_ops: + read: 0.000000e+00 + write: 0.000000e+00 +w838f6800/disk-vda/disk_time: + read: 0.000000e+00 + write: 0.000000e+00 +w838f6800/disk-vda1/disk_merged: + read: 0.000000e+00 + write: 0.000000e+00 +w838f6800/disk-vda1/disk_octets: + read: 0.000000e+00 + write: 0.000000e+00 +w838f6800/disk-vda1/disk_ops: + read: 0.000000e+00 + write: 0.000000e+00 +w838f6800/disk-vda1/disk_time: + read: 0.000000e+00 + write: 0.000000e+00 +w838f6800/disk-vda2/disk_merged: + read: 0.000000e+00 + write: 0.000000e+00 +w838f6800/disk-vda2/disk_octets: + read: 0.000000e+00 + write: 0.000000e+00 +w838f6800/disk-vda2/disk_ops: + read: 0.000000e+00 + write: 0.000000e+00 +w838f6800/disk-vda2/disk_time: + read: 0.000000e+00 + write: 0.000000e+00 +w838f6800/disk-vda3/disk_merged: + read: 0.000000e+00 + write: 0.000000e+00 +w838f6800/disk-vda3/disk_octets: + read: 0.000000e+00 + write: 0.000000e+00 +w838f6800/disk-vda3/disk_ops: + read: 0.000000e+00 + write: 0.000000e+00 +w838f6800/disk-vda3/disk_time: + read: 0.000000e+00 + write: 0.000000e+00 +w838f6800/disk-vda4/disk_merged: + read: 0.000000e+00 + write: 0.000000e+00 +w838f6800/disk-vda4/disk_octets: + read: 0.000000e+00 + write: 0.000000e+00 +w838f6800/disk-vda4/disk_ops: + read: 0.000000e+00 + write: 0.000000e+00 +w838f6800/disk-vda4/disk_time: + read: 0.000000e+00 + write: 0.000000e+00 +w838f6800/disk-vda5/disk_merged: + read: 0.000000e+00 + write: 0.000000e+00 +w838f6800/disk-vda5/disk_octets: + read: 0.000000e+00 + write: 0.000000e+00 +w838f6800/disk-vda5/disk_ops: + read: 0.000000e+00 + write: 0.000000e+00 +w838f6800/disk-vda5/disk_time: + read: 0.000000e+00 + write: 0.000000e+00 +w838f6800/disk-vda6/disk_merged: + read: 0.000000e+00 + write: 0.000000e+00 +w838f6800/disk-vda6/disk_octets: + read: 0.000000e+00 + write: 0.000000e+00 +w838f6800/disk-vda6/disk_ops: + read: 0.000000e+00 + write: 0.000000e+00 +w838f6800/disk-vda6/disk_time: + read: 0.000000e+00 + write: 0.000000e+00 +w838f6800/load/load: + longterm: 0.000000e+00 + midterm: 0.000000e+00 + shortterm: 0.000000e+00 +w838f6800/memory/memory-buffered: + value: 1.443430e+08 +w838f6800/memory/memory-cached: + value: 4.507607e+08 +w838f6800/memory/memory-free: + value: 7.122756e+09 +w838f6800/memory/memory-used: + value: 5.349949e+08 +w838f6800/network/if_octets: + rx: 0.000000e+00 + tx: 7.896001e+02 +w838f6800/network/if_packets: + rx: 0.000000e+00 + tx: 6.000121e-01 +w838f6800/network/queue_length: + value: 0.000000e+00 +w838f6800/network/total_values-dispatch-accepted: + value: 0.000000e+00 +w838f6800/network/total_values-dispatch-rejected: + value: 0.000000e+00 +w838f6800/network/total_values-send-accepted: + value: 1.530036e+01 +w838f6800/network/total_values-send-rejected: + value: 0.000000e+00 +w838f6800/swap/swap-cached: + value: 0.000000e+00 +w838f6800/swap/swap-free: + value: 2.147475e+09 +w838f6800/swap/swap-used: + value: 0.000000e+00 +w838f6800/swap/swap_io-in: + value: 0.000000e+00 +w838f6800/swap/swap_io-out: + value: 0.000000e+00 +w838f6800/vmem/vmpage_faults: + majflt: 0.000000e+00 + minflt: 4.500056e+00 +w838f6800/vmem/vmpage_io-memory: + in: 0.000000e+00 + out: 0.000000e+00 +w838f6800/vmem/vmpage_io-swap: + in: 0.000000e+00 + out: 0.000000e+00 +w838f6800/vmem/vmpage_number-active_anon: + value: 1.298400e+04 +w838f6800/vmem/vmpage_number-active_file: + value: 7.437200e+04 +w838f6800/vmem/vmpage_number-anon_pages: + value: 1.042100e+04 +w838f6800/vmem/vmpage_number-anon_transparent_hugepages: + value: 5.000000e+00 +w838f6800/vmem/vmpage_number-boudfe: + value: 0.000000e+00 +w838f6800/vmem/vmpage_number-dirty: + value: 0.000000e+00 +w838f6800/vmem/vmpage_number-file_pages: + value: 1.452890e+05 +w838f6800/vmem/vmpage_number-free_pages: + value: 1.738954e+06 +w838f6800/vmem/vmpage_number-inactive_anon: + value: 4.200000e+01 +w838f6800/vmem/vmpage_number-inactive_file: + value: 7.087600e+04 +w838f6800/vmem/vmpage_number-isolated_anon: + value: 0.000000e+00 +w838f6800/vmem/vmpage_number-isolated_file: + value: 0.000000e+00 +w838f6800/vmem/vmpage_number-kernel_stack: + value: 1.390000e+02 +w838f6800/vmem/vmpage_number-mapped: + value: 1.478000e+03 +w838f6800/vmem/vmpage_number-mlock: + value: 0.000000e+00 +w838f6800/vmem/vmpage_number-page_table_pages: + value: 4.100000e+02 +w838f6800/vmem/vmpage_number-shmem: + value: 4.500000e+01 +w838f6800/vmem/vmpage_number-slab_reclaimable: + value: 9.488500e+04 +w838f6800/vmem/vmpage_number-slab_unreclaimable: + value: 5.513000e+03 +w838f6800/vmem/vmpage_number-unevictable: + value: 0.000000e+00 +w838f6800/vmem/vmpage_number-unstable: + value: 0.000000e+00 +w838f6800/vmem/vmpage_number-vmscan_write: + value: 0.000000e+00 +w838f6800/vmem/vmpage_number-writeback: + value: 0.000000e+00 +w838f6800/vmem/vmpage_number-writeback_temp: + value: 0.000000e+00 +w838f6900/cpu-0/cpu-idle: + value: 9.700088e+01 +w838f6900/cpu-0/cpu-interrupt: + value: 0.000000e+00 +w838f6900/cpu-0/cpu-nice: + value: 0.000000e+00 +w838f6900/cpu-0/cpu-softirq: + value: 0.000000e+00 +w838f6900/cpu-0/cpu-steal: + value: 0.000000e+00 +w838f6900/cpu-0/cpu-system: + value: 1.000009e-01 +w838f6900/cpu-0/cpu-user: + value: 2.900025e+00 +w838f6900/cpu-0/cpu-wait: + value: 0.000000e+00 +w838f6900/cpu-1/cpu-idle: + value: 9.960079e+01 +w838f6900/cpu-1/cpu-interrupt: + value: 0.000000e+00 +w838f6900/cpu-1/cpu-nice: + value: 0.000000e+00 +w838f6900/cpu-1/cpu-softirq: + value: 0.000000e+00 +w838f6900/cpu-1/cpu-steal: + value: 0.000000e+00 +w838f6900/cpu-1/cpu-system: + value: 0.000000e+00 +w838f6900/cpu-1/cpu-user: + value: 0.000000e+00 +w838f6900/cpu-1/cpu-wait: + value: 0.000000e+00 +w838f6900/df-boot/df_complex-free: + value: 4.793836e+08 +w838f6900/df-boot/df_complex-reserved: + value: 2.684109e+07 +w838f6900/df-boot/df_complex-used: + value: 2.220032e+07 +w838f6900/df-boot/df_inodes-free: + value: 3.273000e+04 +w838f6900/df-boot/df_inodes-reserved: + value: 0.000000e+00 +w838f6900/df-boot/df_inodes-used: + value: 3.800000e+01 +w838f6900/df-boot/percent_bytes-free: + value: 9.071932e+01 +w838f6900/df-boot/percent_bytes-reserved: + value: 5.079451e+00 +w838f6900/df-boot/percent_bytes-used: + value: 4.201225e+00 +w838f6900/df-boot/percent_inodes-free: + value: 9.988403e+01 +w838f6900/df-boot/percent_inodes-reserved: + value: 0.000000e+00 +w838f6900/df-boot/percent_inodes-used: + value: 1.159668e-01 +w838f6900/df-data1/df_complex-free: + value: 2.740491e+10 +w838f6900/df-data1/df_complex-reserved: + value: 1.476235e+09 +w838f6900/df-data1/df_complex-used: + value: 1.802977e+08 +w838f6900/df-data1/df_inodes-free: + value: 1.802227e+06 +w838f6900/df-data1/df_inodes-reserved: + value: 0.000000e+00 +w838f6900/df-data1/df_inodes-used: + value: 1.300000e+01 +w838f6900/df-data1/percent_bytes-free: + value: 9.429990e+01 +w838f6900/df-data1/percent_bytes-reserved: + value: 5.079704e+00 +w838f6900/df-data1/percent_bytes-used: + value: 6.204019e-01 +w838f6900/df-data1/percent_inodes-free: + value: 9.999928e+01 +w838f6900/df-data1/percent_inodes-reserved: + value: 0.000000e+00 +w838f6900/df-data1/percent_inodes-used: + value: 7.213246e-04 +w838f6900/df-dev-shm/df_complex-free: + value: 9.842483e+08 +w838f6900/df-dev-shm/df_complex-reserved: + value: 0.000000e+00 +w838f6900/df-dev-shm/df_complex-used: + value: 0.000000e+00 +w838f6900/df-dev-shm/df_inodes-free: + value: 2.402940e+05 +w838f6900/df-dev-shm/df_inodes-reserved: + value: 0.000000e+00 +w838f6900/df-dev-shm/df_inodes-used: + value: 1.000000e+00 +w838f6900/df-dev-shm/percent_bytes-free: + value: 1.000000e+02 +w838f6900/df-dev-shm/percent_bytes-reserved: + value: 0.000000e+00 +w838f6900/df-dev-shm/percent_bytes-used: + value: 0.000000e+00 +w838f6900/df-dev-shm/percent_inodes-free: + value: 9.999958e+01 +w838f6900/df-dev-shm/percent_inodes-reserved: + value: 0.000000e+00 +w838f6900/df-dev-shm/percent_inodes-used: + value: 4.161551e-04 +w838f6900/df-root/df_complex-free: + value: 1.097382e+10 +w838f6900/df-root/df_complex-reserved: + value: 6.442435e+08 +w838f6900/df-root/df_complex-used: + value: 1.064645e+09 +w838f6900/df-root/df_inodes-free: + value: 7.501330e+05 +w838f6900/df-root/df_inodes-reserved: + value: 0.000000e+00 +w838f6900/df-root/df_inodes-used: + value: 3.629900e+04 +w838f6900/df-root/percent_bytes-free: + value: 8.652584e+01 +w838f6900/df-root/percent_bytes-reserved: + value: 5.079700e+00 +w838f6900/df-root/percent_bytes-used: + value: 8.394459e+00 +w838f6900/df-root/percent_inodes-free: + value: 9.538434e+01 +w838f6900/df-root/percent_inodes-reserved: + value: 0.000000e+00 +w838f6900/df-root/percent_inodes-used: + value: 4.615657e+00 +w838f6900/df-var/df_complex-free: + value: 7.637877e+09 +w838f6900/df-var/df_complex-reserved: + value: 4.294943e+08 +w838f6900/df-var/df_complex-used: + value: 3.877478e+08 +w838f6900/df-var/df_inodes-free: + value: 5.229840e+05 +w838f6900/df-var/df_inodes-reserved: + value: 0.000000e+00 +w838f6900/df-var/df_inodes-used: + value: 1.304000e+03 +w838f6900/df-var/percent_bytes-free: + value: 9.033435e+01 +w838f6900/df-var/percent_bytes-reserved: + value: 5.079695e+00 +w838f6900/df-var/percent_bytes-used: + value: 4.585954e+00 +w838f6900/df-var/percent_inodes-free: + value: 9.975128e+01 +w838f6900/df-var/percent_inodes-reserved: + value: 0.000000e+00 +w838f6900/df-var/percent_inodes-used: + value: 2.487183e-01 +w838f6900/disk-vda/disk_merged: + read: 0.000000e+00 + write: 0.000000e+00 +w838f6900/disk-vda/disk_octets: + read: 0.000000e+00 + write: 0.000000e+00 +w838f6900/disk-vda/disk_ops: + read: 0.000000e+00 + write: 0.000000e+00 +w838f6900/disk-vda/disk_time: + read: 0.000000e+00 + write: 0.000000e+00 +w838f6900/disk-vda1/disk_merged: + read: 0.000000e+00 + write: 0.000000e+00 +w838f6900/disk-vda1/disk_octets: + read: 0.000000e+00 + write: 0.000000e+00 +w838f6900/disk-vda1/disk_ops: + read: 0.000000e+00 + write: 0.000000e+00 +w838f6900/disk-vda1/disk_time: + read: 0.000000e+00 + write: 0.000000e+00 +w838f6900/disk-vda2/disk_merged: + read: 0.000000e+00 + write: 0.000000e+00 +w838f6900/disk-vda2/disk_octets: + read: 0.000000e+00 + write: 0.000000e+00 +w838f6900/disk-vda2/disk_ops: + read: 0.000000e+00 + write: 0.000000e+00 +w838f6900/disk-vda2/disk_time: + read: 0.000000e+00 + write: 0.000000e+00 +w838f6900/disk-vda3/disk_merged: + read: 0.000000e+00 + write: 0.000000e+00 +w838f6900/disk-vda3/disk_octets: + read: 0.000000e+00 + write: 0.000000e+00 +w838f6900/disk-vda3/disk_ops: + read: 0.000000e+00 + write: 0.000000e+00 +w838f6900/disk-vda3/disk_time: + read: 0.000000e+00 + write: 0.000000e+00 +w838f6900/disk-vda4/disk_merged: + read: 0.000000e+00 + write: 0.000000e+00 +w838f6900/disk-vda4/disk_octets: + read: 0.000000e+00 + write: 0.000000e+00 +w838f6900/disk-vda4/disk_ops: + read: 0.000000e+00 + write: 0.000000e+00 +w838f6900/disk-vda4/disk_time: + read: 0.000000e+00 + write: 0.000000e+00 +w838f6900/disk-vda5/disk_merged: + read: 0.000000e+00 + write: 0.000000e+00 +w838f6900/disk-vda5/disk_octets: + read: 0.000000e+00 + write: 0.000000e+00 +w838f6900/disk-vda5/disk_ops: + read: 0.000000e+00 + write: 0.000000e+00 +w838f6900/disk-vda5/disk_time: + read: 0.000000e+00 + write: 0.000000e+00 +w838f6900/disk-vda6/disk_merged: + read: 0.000000e+00 + write: 0.000000e+00 +w838f6900/disk-vda6/disk_octets: + read: 0.000000e+00 + write: 0.000000e+00 +w838f6900/disk-vda6/disk_ops: + read: 0.000000e+00 + write: 0.000000e+00 +w838f6900/disk-vda6/disk_time: + read: 0.000000e+00 + write: 0.000000e+00 +w838f6900/load/load: + longterm: 0.000000e+00 + midterm: 0.000000e+00 + shortterm: 0.000000e+00 +w838f6900/memory/memory-buffered: + value: 1.040671e+08 +w838f6900/memory/memory-cached: + value: 4.379361e+08 +w838f6900/memory/memory-free: + value: 9.871852e+08 +w838f6900/memory/memory-used: + value: 4.393083e+08 +w838f6900/network/if_octets: + rx: 0.000000e+00 + tx: 6.614006e+02 +w838f6900/network/if_packets: + rx: 0.000000e+00 + tx: 4.999994e-01 +w838f6900/network/queue_length: + value: 0.000000e+00 +w838f6900/network/total_values-dispatch-accepted: + value: 0.000000e+00 +w838f6900/network/total_values-dispatch-rejected: + value: 0.000000e+00 +w838f6900/network/total_values-send-accepted: + value: 1.479996e+01 +w838f6900/network/total_values-send-rejected: + value: 0.000000e+00 +w838f6900/swap/swap-cached: + value: 0.000000e+00 +w838f6900/swap/swap-free: + value: 2.147475e+09 +w838f6900/swap/swap-used: + value: 0.000000e+00 +w838f6900/swap/swap_io-in: + value: 0.000000e+00 +w838f6900/swap/swap_io-out: + value: 0.000000e+00 +w838f6900/vmem/vmpage_faults: + majflt: 0.000000e+00 + minflt: 4.300042e+00 +w838f6900/vmem/vmpage_io-memory: + in: 0.000000e+00 + out: 0.000000e+00 +w838f6900/vmem/vmpage_io-swap: + in: 0.000000e+00 + out: 0.000000e+00 +w838f6900/vmem/vmpage_number-active_anon: + value: 3.653600e+04 +w838f6900/vmem/vmpage_number-active_file: + value: 7.163800e+04 +w838f6900/vmem/vmpage_number-anon_pages: + value: 2.014900e+04 +w838f6900/vmem/vmpage_number-anon_transparent_hugepages: + value: 3.200000e+01 +w838f6900/vmem/vmpage_number-boudfe: + value: 0.000000e+00 +w838f6900/vmem/vmpage_number-dirty: + value: 0.000000e+00 +w838f6900/vmem/vmpage_number-file_pages: + value: 1.323250e+05 +w838f6900/vmem/vmpage_number-free_pages: + value: 2.410120e+05 +w838f6900/vmem/vmpage_number-inactive_anon: + value: 4.300000e+01 +w838f6900/vmem/vmpage_number-inactive_file: + value: 6.064500e+04 +w838f6900/vmem/vmpage_number-isolated_anon: + value: 0.000000e+00 +w838f6900/vmem/vmpage_number-isolated_file: + value: 0.000000e+00 +w838f6900/vmem/vmpage_number-kernel_stack: + value: 1.280000e+02 +w838f6900/vmem/vmpage_number-mapped: + value: 3.447000e+03 +w838f6900/vmem/vmpage_number-mlock: + value: 0.000000e+00 +w838f6900/vmem/vmpage_number-page_table_pages: + value: 6.660000e+02 +w838f6900/vmem/vmpage_number-shmem: + value: 4.600000e+01 +w838f6900/vmem/vmpage_number-slab_reclaimable: + value: 5.838000e+04 +w838f6900/vmem/vmpage_number-slab_unreclaimable: + value: 5.330000e+03 +w838f6900/vmem/vmpage_number-unevictable: + value: 0.000000e+00 +w838f6900/vmem/vmpage_number-unstable: + value: 0.000000e+00 +w838f6900/vmem/vmpage_number-vmscan_write: + value: 0.000000e+00 +w838f6900/vmem/vmpage_number-writeback: + value: 0.000000e+00 +w838f6900/vmem/vmpage_number-writeback_temp: + value: 0.000000e+00 +w83df6100/cpu-0/cpu-idle: + value: 9.979989e+01 +w83df6100/cpu-0/cpu-interrupt: + value: 0.000000e+00 +w83df6100/cpu-0/cpu-nice: + value: 0.000000e+00 +w83df6100/cpu-0/cpu-softirq: + value: 0.000000e+00 +w83df6100/cpu-0/cpu-steal: + value: 0.000000e+00 +w83df6100/cpu-0/cpu-system: + value: 0.000000e+00 +w83df6100/cpu-0/cpu-user: + value: 0.000000e+00 +w83df6100/cpu-0/cpu-wait: + value: 0.000000e+00 +w83df6100/cpu-1/cpu-idle: + value: 9.999984e+01 +w83df6100/cpu-1/cpu-interrupt: + value: 0.000000e+00 +w83df6100/cpu-1/cpu-nice: + value: 0.000000e+00 +w83df6100/cpu-1/cpu-softirq: + value: 0.000000e+00 +w83df6100/cpu-1/cpu-steal: + value: 0.000000e+00 +w83df6100/cpu-1/cpu-system: + value: 9.999985e-02 +w83df6100/cpu-1/cpu-user: + value: 0.000000e+00 +w83df6100/cpu-1/cpu-wait: + value: 0.000000e+00 +w83df6100/cpu-10/cpu-idle: + value: 9.989993e+01 +w83df6100/cpu-10/cpu-interrupt: + value: 0.000000e+00 +w83df6100/cpu-10/cpu-nice: + value: 0.000000e+00 +w83df6100/cpu-10/cpu-softirq: + value: 0.000000e+00 +w83df6100/cpu-10/cpu-steal: + value: 0.000000e+00 +w83df6100/cpu-10/cpu-system: + value: 9.999993e-02 +w83df6100/cpu-10/cpu-user: + value: 0.000000e+00 +w83df6100/cpu-10/cpu-wait: + value: 0.000000e+00 +w83df6100/cpu-11/cpu-idle: + value: 9.999994e+01 +w83df6100/cpu-11/cpu-interrupt: + value: 0.000000e+00 +w83df6100/cpu-11/cpu-nice: + value: 0.000000e+00 +w83df6100/cpu-11/cpu-softirq: + value: 0.000000e+00 +w83df6100/cpu-11/cpu-steal: + value: 0.000000e+00 +w83df6100/cpu-11/cpu-system: + value: 0.000000e+00 +w83df6100/cpu-11/cpu-user: + value: 0.000000e+00 +w83df6100/cpu-11/cpu-wait: + value: 0.000000e+00 +w83df6100/cpu-12/cpu-idle: + value: 9.999992e+01 +w83df6100/cpu-12/cpu-interrupt: + value: 0.000000e+00 +w83df6100/cpu-12/cpu-nice: + value: 0.000000e+00 +w83df6100/cpu-12/cpu-softirq: + value: 0.000000e+00 +w83df6100/cpu-12/cpu-steal: + value: 0.000000e+00 +w83df6100/cpu-12/cpu-system: + value: 0.000000e+00 +w83df6100/cpu-12/cpu-user: + value: 0.000000e+00 +w83df6100/cpu-12/cpu-wait: + value: 0.000000e+00 +w83df6100/cpu-13/cpu-idle: + value: 9.989989e+01 +w83df6100/cpu-13/cpu-interrupt: + value: 0.000000e+00 +w83df6100/cpu-13/cpu-nice: + value: 0.000000e+00 +w83df6100/cpu-13/cpu-softirq: + value: 0.000000e+00 +w83df6100/cpu-13/cpu-steal: + value: 0.000000e+00 +w83df6100/cpu-13/cpu-system: + value: 0.000000e+00 +w83df6100/cpu-13/cpu-user: + value: 9.999990e-02 +w83df6100/cpu-13/cpu-wait: + value: 0.000000e+00 +w83df6100/cpu-14/cpu-idle: + value: 9.999994e+01 +w83df6100/cpu-14/cpu-interrupt: + value: 0.000000e+00 +w83df6100/cpu-14/cpu-nice: + value: 0.000000e+00 +w83df6100/cpu-14/cpu-softirq: + value: 0.000000e+00 +w83df6100/cpu-14/cpu-steal: + value: 0.000000e+00 +w83df6100/cpu-14/cpu-system: + value: 0.000000e+00 +w83df6100/cpu-14/cpu-user: + value: 0.000000e+00 +w83df6100/cpu-14/cpu-wait: + value: 0.000000e+00 +w83df6100/cpu-15/cpu-idle: + value: 9.990003e+01 +w83df6100/cpu-15/cpu-interrupt: + value: 0.000000e+00 +w83df6100/cpu-15/cpu-nice: + value: 0.000000e+00 +w83df6100/cpu-15/cpu-softirq: + value: 0.000000e+00 +w83df6100/cpu-15/cpu-steal: + value: 0.000000e+00 +w83df6100/cpu-15/cpu-system: + value: 0.000000e+00 +w83df6100/cpu-15/cpu-user: + value: 0.000000e+00 +w83df6100/cpu-15/cpu-wait: + value: 0.000000e+00 +w83df6100/cpu-16/cpu-idle: + value: 1.000001e+02 +w83df6100/cpu-16/cpu-interrupt: + value: 0.000000e+00 +w83df6100/cpu-16/cpu-nice: + value: 0.000000e+00 +w83df6100/cpu-16/cpu-softirq: + value: 0.000000e+00 +w83df6100/cpu-16/cpu-steal: + value: 0.000000e+00 +w83df6100/cpu-16/cpu-system: + value: 0.000000e+00 +w83df6100/cpu-16/cpu-user: + value: 0.000000e+00 +w83df6100/cpu-16/cpu-wait: + value: 0.000000e+00 +w83df6100/cpu-17/cpu-idle: + value: 9.999995e+01 +w83df6100/cpu-17/cpu-interrupt: + value: 0.000000e+00 +w83df6100/cpu-17/cpu-nice: + value: 0.000000e+00 +w83df6100/cpu-17/cpu-softirq: + value: 0.000000e+00 +w83df6100/cpu-17/cpu-steal: + value: 0.000000e+00 +w83df6100/cpu-17/cpu-system: + value: 0.000000e+00 +w83df6100/cpu-17/cpu-user: + value: 0.000000e+00 +w83df6100/cpu-17/cpu-wait: + value: 0.000000e+00 +w83df6100/cpu-18/cpu-idle: + value: 9.999993e+01 +w83df6100/cpu-18/cpu-interrupt: + value: 0.000000e+00 +w83df6100/cpu-18/cpu-nice: + value: 0.000000e+00 +w83df6100/cpu-18/cpu-softirq: + value: 0.000000e+00 +w83df6100/cpu-18/cpu-steal: + value: 0.000000e+00 +w83df6100/cpu-18/cpu-system: + value: 9.999993e-02 +w83df6100/cpu-18/cpu-user: + value: 9.999991e-02 +w83df6100/cpu-18/cpu-wait: + value: 0.000000e+00 +w83df6100/cpu-19/cpu-idle: + value: 9.989974e+01 +w83df6100/cpu-19/cpu-interrupt: + value: 0.000000e+00 +w83df6100/cpu-19/cpu-nice: + value: 0.000000e+00 +w83df6100/cpu-19/cpu-softirq: + value: 0.000000e+00 +w83df6100/cpu-19/cpu-steal: + value: 0.000000e+00 +w83df6100/cpu-19/cpu-system: + value: 9.999975e-02 +w83df6100/cpu-19/cpu-user: + value: 0.000000e+00 +w83df6100/cpu-19/cpu-wait: + value: 0.000000e+00 +w83df6100/cpu-2/cpu-idle: + value: 9.999995e+01 +w83df6100/cpu-2/cpu-interrupt: + value: 0.000000e+00 +w83df6100/cpu-2/cpu-nice: + value: 0.000000e+00 +w83df6100/cpu-2/cpu-softirq: + value: 0.000000e+00 +w83df6100/cpu-2/cpu-steal: + value: 0.000000e+00 +w83df6100/cpu-2/cpu-system: + value: 0.000000e+00 +w83df6100/cpu-2/cpu-user: + value: 0.000000e+00 +w83df6100/cpu-2/cpu-wait: + value: 0.000000e+00 +w83df6100/cpu-20/cpu-idle: + value: 9.999968e+01 +w83df6100/cpu-20/cpu-interrupt: + value: 0.000000e+00 +w83df6100/cpu-20/cpu-nice: + value: 0.000000e+00 +w83df6100/cpu-20/cpu-softirq: + value: 0.000000e+00 +w83df6100/cpu-20/cpu-steal: + value: 0.000000e+00 +w83df6100/cpu-20/cpu-system: + value: 0.000000e+00 +w83df6100/cpu-20/cpu-user: + value: 0.000000e+00 +w83df6100/cpu-20/cpu-wait: + value: 0.000000e+00 +w83df6100/cpu-21/cpu-idle: + value: 9.999958e+01 +w83df6100/cpu-21/cpu-interrupt: + value: 0.000000e+00 +w83df6100/cpu-21/cpu-nice: + value: 0.000000e+00 +w83df6100/cpu-21/cpu-softirq: + value: 0.000000e+00 +w83df6100/cpu-21/cpu-steal: + value: 0.000000e+00 +w83df6100/cpu-21/cpu-system: + value: 0.000000e+00 +w83df6100/cpu-21/cpu-user: + value: 0.000000e+00 +w83df6100/cpu-21/cpu-wait: + value: 0.000000e+00 +w83df6100/cpu-22/cpu-idle: + value: 9.999951e+01 +w83df6100/cpu-22/cpu-interrupt: + value: 0.000000e+00 +w83df6100/cpu-22/cpu-nice: + value: 0.000000e+00 +w83df6100/cpu-22/cpu-softirq: + value: 0.000000e+00 +w83df6100/cpu-22/cpu-steal: + value: 0.000000e+00 +w83df6100/cpu-22/cpu-system: + value: 9.999951e-02 +w83df6100/cpu-22/cpu-user: + value: 0.000000e+00 +w83df6100/cpu-22/cpu-wait: + value: 0.000000e+00 +w83df6100/cpu-23/cpu-idle: + value: 9.989947e+01 +w83df6100/cpu-23/cpu-interrupt: + value: 0.000000e+00 +w83df6100/cpu-23/cpu-nice: + value: 0.000000e+00 +w83df6100/cpu-23/cpu-softirq: + value: 0.000000e+00 +w83df6100/cpu-23/cpu-steal: + value: 0.000000e+00 +w83df6100/cpu-23/cpu-system: + value: 0.000000e+00 +w83df6100/cpu-23/cpu-user: + value: 0.000000e+00 +w83df6100/cpu-23/cpu-wait: + value: 0.000000e+00 +w83df6100/cpu-3/cpu-idle: + value: 1.000002e+02 +w83df6100/cpu-3/cpu-interrupt: + value: 0.000000e+00 +w83df6100/cpu-3/cpu-nice: + value: 0.000000e+00 +w83df6100/cpu-3/cpu-softirq: + value: 0.000000e+00 +w83df6100/cpu-3/cpu-steal: + value: 0.000000e+00 +w83df6100/cpu-3/cpu-system: + value: 0.000000e+00 +w83df6100/cpu-3/cpu-user: + value: 0.000000e+00 +w83df6100/cpu-3/cpu-wait: + value: 0.000000e+00 +w83df6100/cpu-4/cpu-idle: + value: 1.000004e+02 +w83df6100/cpu-4/cpu-interrupt: + value: 0.000000e+00 +w83df6100/cpu-4/cpu-nice: + value: 0.000000e+00 +w83df6100/cpu-4/cpu-softirq: + value: 0.000000e+00 +w83df6100/cpu-4/cpu-steal: + value: 0.000000e+00 +w83df6100/cpu-4/cpu-system: + value: 0.000000e+00 +w83df6100/cpu-4/cpu-user: + value: 0.000000e+00 +w83df6100/cpu-4/cpu-wait: + value: 0.000000e+00 +w83df6100/cpu-5/cpu-idle: + value: 1.000004e+02 +w83df6100/cpu-5/cpu-interrupt: + value: 0.000000e+00 +w83df6100/cpu-5/cpu-nice: + value: 0.000000e+00 +w83df6100/cpu-5/cpu-softirq: + value: 0.000000e+00 +w83df6100/cpu-5/cpu-steal: + value: 0.000000e+00 +w83df6100/cpu-5/cpu-system: + value: 0.000000e+00 +w83df6100/cpu-5/cpu-user: + value: 0.000000e+00 +w83df6100/cpu-5/cpu-wait: + value: 0.000000e+00 +w83df6100/cpu-6/cpu-idle: + value: 9.990037e+01 +w83df6100/cpu-6/cpu-interrupt: + value: 0.000000e+00 +w83df6100/cpu-6/cpu-nice: + value: 0.000000e+00 +w83df6100/cpu-6/cpu-softirq: + value: 0.000000e+00 +w83df6100/cpu-6/cpu-steal: + value: 0.000000e+00 +w83df6100/cpu-6/cpu-system: + value: 1.000004e-01 +w83df6100/cpu-6/cpu-user: + value: 0.000000e+00 +w83df6100/cpu-6/cpu-wait: + value: 0.000000e+00 +w83df6100/cpu-7/cpu-idle: + value: 9.990034e+01 +w83df6100/cpu-7/cpu-interrupt: + value: 0.000000e+00 +w83df6100/cpu-7/cpu-nice: + value: 0.000000e+00 +w83df6100/cpu-7/cpu-softirq: + value: 0.000000e+00 +w83df6100/cpu-7/cpu-steal: + value: 0.000000e+00 +w83df6100/cpu-7/cpu-system: + value: 0.000000e+00 +w83df6100/cpu-7/cpu-user: + value: 0.000000e+00 +w83df6100/cpu-7/cpu-wait: + value: 0.000000e+00 +w83df6100/cpu-8/cpu-idle: + value: 9.990024e+01 +w83df6100/cpu-8/cpu-interrupt: + value: 0.000000e+00 +w83df6100/cpu-8/cpu-nice: + value: 0.000000e+00 +w83df6100/cpu-8/cpu-softirq: + value: 0.000000e+00 +w83df6100/cpu-8/cpu-steal: + value: 0.000000e+00 +w83df6100/cpu-8/cpu-system: + value: 3.000007e-01 +w83df6100/cpu-8/cpu-user: + value: 0.000000e+00 +w83df6100/cpu-8/cpu-wait: + value: 0.000000e+00 +w83df6100/cpu-9/cpu-idle: + value: 9.999998e+01 +w83df6100/cpu-9/cpu-interrupt: + value: 0.000000e+00 +w83df6100/cpu-9/cpu-nice: + value: 0.000000e+00 +w83df6100/cpu-9/cpu-softirq: + value: 0.000000e+00 +w83df6100/cpu-9/cpu-steal: + value: 0.000000e+00 +w83df6100/cpu-9/cpu-system: + value: 0.000000e+00 +w83df6100/cpu-9/cpu-user: + value: 0.000000e+00 +w83df6100/cpu-9/cpu-wait: + value: 0.000000e+00 +w83df6100/df-boot/df_complex-free: + value: 4.369900e+08 +w83df6100/df-boot/df_complex-reserved: + value: 2.684109e+07 +w83df6100/df-boot/df_complex-used: + value: 6.459392e+07 +w83df6100/df-boot/df_inodes-free: + value: 3.271800e+04 +w83df6100/df-boot/df_inodes-reserved: + value: 0.000000e+00 +w83df6100/df-boot/df_inodes-used: + value: 5.000000e+01 +w83df6100/df-boot/percent_bytes-free: + value: 8.269669e+01 +w83df6100/df-boot/percent_bytes-reserved: + value: 5.079451e+00 +w83df6100/df-boot/percent_bytes-used: + value: 1.222386e+01 +w83df6100/df-boot/percent_inodes-free: + value: 9.984741e+01 +w83df6100/df-boot/percent_inodes-reserved: + value: 0.000000e+00 +w83df6100/df-boot/percent_inodes-used: + value: 1.525879e-01 +w83df6100/df-data1/df_complex-free: + value: 2.574625e+11 +w83df6100/df-data1/df_complex-reserved: + value: 1.378982e+10 +w83df6100/df-data1/df_complex-used: + value: 2.165924e+08 +w83df6100/df-data1/df_inodes-free: + value: 1.683452e+07 +w83df6100/df-data1/df_inodes-reserved: + value: 0.000000e+00 +w83df6100/df-data1/df_inodes-used: + value: 4.400000e+01 +w83df6100/df-data1/percent_bytes-free: + value: 9.484051e+01 +w83df6100/df-data1/percent_bytes-reserved: + value: 5.079707e+00 +w83df6100/df-data1/percent_bytes-used: + value: 7.978535e-02 +w83df6100/df-data1/percent_inodes-free: + value: 9.999974e+01 +w83df6100/df-data1/percent_inodes-reserved: + value: 0.000000e+00 +w83df6100/df-data1/percent_inodes-used: + value: 2.613671e-04 +w83df6100/df-dev-shm/df_complex-free: + value: 3.375709e+10 +w83df6100/df-dev-shm/df_complex-reserved: + value: 0.000000e+00 +w83df6100/df-dev-shm/df_complex-used: + value: 0.000000e+00 +w83df6100/df-dev-shm/df_inodes-free: + value: 8.241475e+06 +w83df6100/df-dev-shm/df_inodes-reserved: + value: 0.000000e+00 +w83df6100/df-dev-shm/df_inodes-used: + value: 1.000000e+00 +w83df6100/df-dev-shm/percent_bytes-free: + value: 1.000000e+02 +w83df6100/df-dev-shm/percent_bytes-reserved: + value: 0.000000e+00 +w83df6100/df-dev-shm/percent_bytes-used: + value: 0.000000e+00 +w83df6100/df-dev-shm/percent_inodes-free: + value: 9.999998e+01 +w83df6100/df-dev-shm/percent_inodes-reserved: + value: 0.000000e+00 +w83df6100/df-dev-shm/percent_inodes-used: + value: 1.213375e-05 +w83df6100/df-root/df_complex-free: + value: 1.076427e+10 +w83df6100/df-root/df_complex-reserved: + value: 6.442435e+08 +w83df6100/df-root/df_complex-used: + value: 1.274192e+09 +w83df6100/df-root/df_inodes-free: + value: 7.458150e+05 +w83df6100/df-root/df_inodes-reserved: + value: 0.000000e+00 +w83df6100/df-root/df_inodes-used: + value: 4.061700e+04 +w83df6100/df-root/percent_bytes-free: + value: 8.487361e+01 +w83df6100/df-root/percent_bytes-reserved: + value: 5.079700e+00 +w83df6100/df-root/percent_bytes-used: + value: 1.004669e+01 +w83df6100/df-root/percent_inodes-free: + value: 9.483528e+01 +w83df6100/df-root/percent_inodes-reserved: + value: 0.000000e+00 +w83df6100/df-root/percent_inodes-used: + value: 5.164719e+00 +w83df6100/df-var/df_complex-free: + value: 7.566651e+09 +w83df6100/df-var/df_complex-reserved: + value: 4.294943e+08 +w83df6100/df-var/df_complex-used: + value: 4.589732e+08 +w83df6100/df-var/df_inodes-free: + value: 5.227920e+05 +w83df6100/df-var/df_inodes-reserved: + value: 0.000000e+00 +w83df6100/df-var/df_inodes-used: + value: 1.496000e+03 +w83df6100/df-var/percent_bytes-free: + value: 8.949196e+01 +w83df6100/df-var/percent_bytes-reserved: + value: 5.079695e+00 +w83df6100/df-var/percent_bytes-used: + value: 5.428347e+00 +w83df6100/df-var/percent_inodes-free: + value: 9.971466e+01 +w83df6100/df-var/percent_inodes-reserved: + value: 0.000000e+00 +w83df6100/df-var/percent_inodes-used: + value: 2.853394e-01 +w83df6100/disk-sda/disk_merged: + read: 0.000000e+00 + write: 0.000000e+00 +w83df6100/disk-sda/disk_octets: + read: 0.000000e+00 + write: 0.000000e+00 +w83df6100/disk-sda/disk_ops: + read: 0.000000e+00 + write: 0.000000e+00 +w83df6100/disk-sda/disk_time: + read: 0.000000e+00 + write: 0.000000e+00 +w83df6100/disk-sda1/disk_merged: + read: 0.000000e+00 + write: 0.000000e+00 +w83df6100/disk-sda1/disk_octets: + read: 0.000000e+00 + write: 0.000000e+00 +w83df6100/disk-sda1/disk_ops: + read: 0.000000e+00 + write: 0.000000e+00 +w83df6100/disk-sda1/disk_time: + read: 0.000000e+00 + write: 0.000000e+00 +w83df6100/disk-sda2/disk_merged: + read: 0.000000e+00 + write: 0.000000e+00 +w83df6100/disk-sda2/disk_octets: + read: 0.000000e+00 + write: 0.000000e+00 +w83df6100/disk-sda2/disk_ops: + read: 0.000000e+00 + write: 0.000000e+00 +w83df6100/disk-sda2/disk_time: + read: 0.000000e+00 + write: 0.000000e+00 +w83df6100/disk-sda3/disk_merged: + read: 0.000000e+00 + write: 0.000000e+00 +w83df6100/disk-sda3/disk_octets: + read: 0.000000e+00 + write: 0.000000e+00 +w83df6100/disk-sda3/disk_ops: + read: 0.000000e+00 + write: 0.000000e+00 +w83df6100/disk-sda3/disk_time: + read: 0.000000e+00 + write: 0.000000e+00 +w83df6100/disk-sda4/disk_merged: + read: 0.000000e+00 + write: 0.000000e+00 +w83df6100/disk-sda4/disk_octets: + read: 0.000000e+00 + write: 0.000000e+00 +w83df6100/disk-sda4/disk_ops: + read: 0.000000e+00 + write: 0.000000e+00 +w83df6100/disk-sda4/disk_time: + read: 0.000000e+00 + write: 0.000000e+00 +w83df6100/disk-sda5/disk_merged: + read: 0.000000e+00 + write: 0.000000e+00 +w83df6100/disk-sda5/disk_octets: + read: 0.000000e+00 + write: 0.000000e+00 +w83df6100/disk-sda5/disk_ops: + read: 0.000000e+00 + write: 0.000000e+00 +w83df6100/disk-sda5/disk_time: + read: 0.000000e+00 + write: 0.000000e+00 +w83df6100/disk-sda6/disk_merged: + read: 0.000000e+00 + write: 0.000000e+00 +w83df6100/disk-sda6/disk_octets: + read: 0.000000e+00 + write: 0.000000e+00 +w83df6100/disk-sda6/disk_ops: + read: 0.000000e+00 + write: 0.000000e+00 +w83df6100/disk-sda6/disk_time: + read: 0.000000e+00 + write: 0.000000e+00 +w83df6100/load/load: + longterm: 0.000000e+00 + midterm: 0.000000e+00 + shortterm: 0.000000e+00 +w83df6100/memory/memory-buffered: + value: 2.127012e+08 +w83df6100/memory/memory-cached: + value: 5.203763e+08 +w83df6100/memory/memory-free: + value: 6.526190e+10 +w83df6100/memory/memory-used: + value: 1.519194e+09 +w83df6100/network/if_octets: + rx: 0.000000e+00 + tx: 1.580500e+03 +w83df6100/network/if_packets: + rx: 0.000000e+00 + tx: 1.200000e+00 +w83df6100/network/queue_length: + value: 0.000000e+00 +w83df6100/network/total_values-dispatch-accepted: + value: 0.000000e+00 +w83df6100/network/total_values-dispatch-rejected: + value: 0.000000e+00 +w83df6100/network/total_values-send-accepted: + value: 3.239997e+01 +w83df6100/network/total_values-send-rejected: + value: 0.000000e+00 +w83df6100/swap/swap-cached: + value: 0.000000e+00 +w83df6100/swap/swap-free: + value: 2.147475e+09 +w83df6100/swap/swap-used: + value: 0.000000e+00 +w83df6100/swap/swap_io-in: + value: 0.000000e+00 +w83df6100/swap/swap_io-out: + value: 0.000000e+00 +w83df6100/vmem/vmpage_faults: + majflt: 0.000000e+00 + minflt: 3.899998e+00 +w83df6100/vmem/vmpage_io-memory: + in: 0.000000e+00 + out: 0.000000e+00 +w83df6100/vmem/vmpage_io-swap: + in: 0.000000e+00 + out: 0.000000e+00 +w83df6100/vmem/vmpage_number-active_anon: + value: 1.617900e+04 +w83df6100/vmem/vmpage_number-active_file: + value: 1.166460e+05 +w83df6100/vmem/vmpage_number-anon_pages: + value: 1.208200e+04 +w83df6100/vmem/vmpage_number-anon_transparent_hugepages: + value: 8.000000e+00 +w83df6100/vmem/vmpage_number-boudfe: + value: 0.000000e+00 +w83df6100/vmem/vmpage_number-dirty: + value: 0.000000e+00 +w83df6100/vmem/vmpage_number-file_pages: + value: 1.789740e+05 +w83df6100/vmem/vmpage_number-free_pages: + value: 1.593308e+07 +w83df6100/vmem/vmpage_number-inactive_anon: + value: 4.500000e+01 +w83df6100/vmem/vmpage_number-inactive_file: + value: 6.228400e+04 +w83df6100/vmem/vmpage_number-isolated_anon: + value: 0.000000e+00 +w83df6100/vmem/vmpage_number-isolated_file: + value: 0.000000e+00 +w83df6100/vmem/vmpage_number-kernel_stack: + value: 4.390000e+02 +w83df6100/vmem/vmpage_number-mapped: + value: 1.670000e+03 +w83df6100/vmem/vmpage_number-mlock: + value: 0.000000e+00 +w83df6100/vmem/vmpage_number-page_table_pages: + value: 5.870000e+02 +w83df6100/vmem/vmpage_number-shmem: + value: 4.700000e+01 +w83df6100/vmem/vmpage_number-slab_reclaimable: + value: 2.364110e+05 +w83df6100/vmem/vmpage_number-slab_unreclaimable: + value: 1.472600e+04 +w83df6100/vmem/vmpage_number-unevictable: + value: 0.000000e+00 +w83df6100/vmem/vmpage_number-unstable: + value: 0.000000e+00 +w83df6100/vmem/vmpage_number-vmscan_write: + value: 0.000000e+00 +w83df6100/vmem/vmpage_number-writeback: + value: 0.000000e+00 +w83df6100/vmem/vmpage_number-writeback_temp: + value: 0.000000e+00 +w83df6200/cpu-0/cpu-idle: + value: 9.970004e+01 +w83df6200/cpu-0/cpu-interrupt: + value: 0.000000e+00 +w83df6200/cpu-0/cpu-nice: + value: 0.000000e+00 +w83df6200/cpu-0/cpu-softirq: + value: 0.000000e+00 +w83df6200/cpu-0/cpu-steal: + value: 0.000000e+00 +w83df6200/cpu-0/cpu-system: + value: 0.000000e+00 +w83df6200/cpu-0/cpu-user: + value: 0.000000e+00 +w83df6200/cpu-0/cpu-wait: + value: 0.000000e+00 +w83df6200/cpu-1/cpu-idle: + value: 1.000000e+02 +w83df6200/cpu-1/cpu-interrupt: + value: 0.000000e+00 +w83df6200/cpu-1/cpu-nice: + value: 0.000000e+00 +w83df6200/cpu-1/cpu-softirq: + value: 0.000000e+00 +w83df6200/cpu-1/cpu-steal: + value: 0.000000e+00 +w83df6200/cpu-1/cpu-system: + value: 0.000000e+00 +w83df6200/cpu-1/cpu-user: + value: 0.000000e+00 +w83df6200/cpu-1/cpu-wait: + value: 0.000000e+00 +w83df6200/cpu-10/cpu-idle: + value: 9.990010e+01 +w83df6200/cpu-10/cpu-interrupt: + value: 0.000000e+00 +w83df6200/cpu-10/cpu-nice: + value: 0.000000e+00 +w83df6200/cpu-10/cpu-softirq: + value: 0.000000e+00 +w83df6200/cpu-10/cpu-steal: + value: 0.000000e+00 +w83df6200/cpu-10/cpu-system: + value: 0.000000e+00 +w83df6200/cpu-10/cpu-user: + value: 0.000000e+00 +w83df6200/cpu-10/cpu-wait: + value: 0.000000e+00 +w83df6200/cpu-11/cpu-idle: + value: 1.000000e+02 +w83df6200/cpu-11/cpu-interrupt: + value: 0.000000e+00 +w83df6200/cpu-11/cpu-nice: + value: 0.000000e+00 +w83df6200/cpu-11/cpu-softirq: + value: 0.000000e+00 +w83df6200/cpu-11/cpu-steal: + value: 0.000000e+00 +w83df6200/cpu-11/cpu-system: + value: 1.000001e-01 +w83df6200/cpu-11/cpu-user: + value: 0.000000e+00 +w83df6200/cpu-11/cpu-wait: + value: 0.000000e+00 +w83df6200/cpu-12/cpu-idle: + value: 9.990011e+01 +w83df6200/cpu-12/cpu-interrupt: + value: 0.000000e+00 +w83df6200/cpu-12/cpu-nice: + value: 0.000000e+00 +w83df6200/cpu-12/cpu-softirq: + value: 0.000000e+00 +w83df6200/cpu-12/cpu-steal: + value: 0.000000e+00 +w83df6200/cpu-12/cpu-system: + value: 0.000000e+00 +w83df6200/cpu-12/cpu-user: + value: 0.000000e+00 +w83df6200/cpu-12/cpu-wait: + value: 0.000000e+00 +w83df6200/cpu-13/cpu-idle: + value: 9.990010e+01 +w83df6200/cpu-13/cpu-interrupt: + value: 0.000000e+00 +w83df6200/cpu-13/cpu-nice: + value: 0.000000e+00 +w83df6200/cpu-13/cpu-softirq: + value: 0.000000e+00 +w83df6200/cpu-13/cpu-steal: + value: 0.000000e+00 +w83df6200/cpu-13/cpu-system: + value: 0.000000e+00 +w83df6200/cpu-13/cpu-user: + value: 0.000000e+00 +w83df6200/cpu-13/cpu-wait: + value: 0.000000e+00 +w83df6200/cpu-14/cpu-idle: + value: 1.000000e+02 +w83df6200/cpu-14/cpu-interrupt: + value: 0.000000e+00 +w83df6200/cpu-14/cpu-nice: + value: 0.000000e+00 +w83df6200/cpu-14/cpu-softirq: + value: 0.000000e+00 +w83df6200/cpu-14/cpu-steal: + value: 0.000000e+00 +w83df6200/cpu-14/cpu-system: + value: 0.000000e+00 +w83df6200/cpu-14/cpu-user: + value: 0.000000e+00 +w83df6200/cpu-14/cpu-wait: + value: 0.000000e+00 +w83df6200/cpu-15/cpu-idle: + value: 1.000000e+02 +w83df6200/cpu-15/cpu-interrupt: + value: 0.000000e+00 +w83df6200/cpu-15/cpu-nice: + value: 0.000000e+00 +w83df6200/cpu-15/cpu-softirq: + value: 0.000000e+00 +w83df6200/cpu-15/cpu-steal: + value: 0.000000e+00 +w83df6200/cpu-15/cpu-system: + value: 0.000000e+00 +w83df6200/cpu-15/cpu-user: + value: 0.000000e+00 +w83df6200/cpu-15/cpu-wait: + value: 0.000000e+00 +w83df6200/cpu-16/cpu-idle: + value: 9.999999e+01 +w83df6200/cpu-16/cpu-interrupt: + value: 0.000000e+00 +w83df6200/cpu-16/cpu-nice: + value: 0.000000e+00 +w83df6200/cpu-16/cpu-softirq: + value: 0.000000e+00 +w83df6200/cpu-16/cpu-steal: + value: 0.000000e+00 +w83df6200/cpu-16/cpu-system: + value: 0.000000e+00 +w83df6200/cpu-16/cpu-user: + value: 0.000000e+00 +w83df6200/cpu-16/cpu-wait: + value: 0.000000e+00 +w83df6200/cpu-17/cpu-idle: + value: 1.000000e+02 +w83df6200/cpu-17/cpu-interrupt: + value: 0.000000e+00 +w83df6200/cpu-17/cpu-nice: + value: 0.000000e+00 +w83df6200/cpu-17/cpu-softirq: + value: 0.000000e+00 +w83df6200/cpu-17/cpu-steal: + value: 0.000000e+00 +w83df6200/cpu-17/cpu-system: + value: 1.000000e-01 +w83df6200/cpu-17/cpu-user: + value: 0.000000e+00 +w83df6200/cpu-17/cpu-wait: + value: 0.000000e+00 +w83df6200/cpu-18/cpu-idle: + value: 9.990002e+01 +w83df6200/cpu-18/cpu-interrupt: + value: 0.000000e+00 +w83df6200/cpu-18/cpu-nice: + value: 0.000000e+00 +w83df6200/cpu-18/cpu-softirq: + value: 0.000000e+00 +w83df6200/cpu-18/cpu-steal: + value: 0.000000e+00 +w83df6200/cpu-18/cpu-system: + value: 0.000000e+00 +w83df6200/cpu-18/cpu-user: + value: 0.000000e+00 +w83df6200/cpu-18/cpu-wait: + value: 0.000000e+00 +w83df6200/cpu-19/cpu-idle: + value: 9.989997e+01 +w83df6200/cpu-19/cpu-interrupt: + value: 0.000000e+00 +w83df6200/cpu-19/cpu-nice: + value: 0.000000e+00 +w83df6200/cpu-19/cpu-softirq: + value: 0.000000e+00 +w83df6200/cpu-19/cpu-steal: + value: 0.000000e+00 +w83df6200/cpu-19/cpu-system: + value: 0.000000e+00 +w83df6200/cpu-19/cpu-user: + value: 0.000000e+00 +w83df6200/cpu-19/cpu-wait: + value: 0.000000e+00 +w83df6200/cpu-2/cpu-idle: + value: 9.980002e+01 +w83df6200/cpu-2/cpu-interrupt: + value: 0.000000e+00 +w83df6200/cpu-2/cpu-nice: + value: 0.000000e+00 +w83df6200/cpu-2/cpu-softirq: + value: 0.000000e+00 +w83df6200/cpu-2/cpu-steal: + value: 0.000000e+00 +w83df6200/cpu-2/cpu-system: + value: 1.000000e-01 +w83df6200/cpu-2/cpu-user: + value: 1.000000e-01 +w83df6200/cpu-2/cpu-wait: + value: 0.000000e+00 +w83df6200/cpu-20/cpu-idle: + value: 9.999997e+01 +w83df6200/cpu-20/cpu-interrupt: + value: 0.000000e+00 +w83df6200/cpu-20/cpu-nice: + value: 0.000000e+00 +w83df6200/cpu-20/cpu-softirq: + value: 0.000000e+00 +w83df6200/cpu-20/cpu-steal: + value: 0.000000e+00 +w83df6200/cpu-20/cpu-system: + value: 0.000000e+00 +w83df6200/cpu-20/cpu-user: + value: 0.000000e+00 +w83df6200/cpu-20/cpu-wait: + value: 0.000000e+00 +w83df6200/cpu-21/cpu-idle: + value: 9.989997e+01 +w83df6200/cpu-21/cpu-interrupt: + value: 0.000000e+00 +w83df6200/cpu-21/cpu-nice: + value: 0.000000e+00 +w83df6200/cpu-21/cpu-softirq: + value: 0.000000e+00 +w83df6200/cpu-21/cpu-steal: + value: 0.000000e+00 +w83df6200/cpu-21/cpu-system: + value: 0.000000e+00 +w83df6200/cpu-21/cpu-user: + value: 0.000000e+00 +w83df6200/cpu-21/cpu-wait: + value: 0.000000e+00 +w83df6200/cpu-22/cpu-idle: + value: 9.990010e+01 +w83df6200/cpu-22/cpu-interrupt: + value: 0.000000e+00 +w83df6200/cpu-22/cpu-nice: + value: 0.000000e+00 +w83df6200/cpu-22/cpu-softirq: + value: 0.000000e+00 +w83df6200/cpu-22/cpu-steal: + value: 0.000000e+00 +w83df6200/cpu-22/cpu-system: + value: 0.000000e+00 +w83df6200/cpu-22/cpu-user: + value: 0.000000e+00 +w83df6200/cpu-22/cpu-wait: + value: 0.000000e+00 +w83df6200/cpu-23/cpu-idle: + value: 1.000000e+02 +w83df6200/cpu-23/cpu-interrupt: + value: 0.000000e+00 +w83df6200/cpu-23/cpu-nice: + value: 0.000000e+00 +w83df6200/cpu-23/cpu-softirq: + value: 0.000000e+00 +w83df6200/cpu-23/cpu-steal: + value: 0.000000e+00 +w83df6200/cpu-23/cpu-system: + value: 0.000000e+00 +w83df6200/cpu-23/cpu-user: + value: 0.000000e+00 +w83df6200/cpu-23/cpu-wait: + value: 0.000000e+00 +w83df6200/cpu-3/cpu-idle: + value: 9.990001e+01 +w83df6200/cpu-3/cpu-interrupt: + value: 0.000000e+00 +w83df6200/cpu-3/cpu-nice: + value: 0.000000e+00 +w83df6200/cpu-3/cpu-softirq: + value: 0.000000e+00 +w83df6200/cpu-3/cpu-steal: + value: 0.000000e+00 +w83df6200/cpu-3/cpu-system: + value: 0.000000e+00 +w83df6200/cpu-3/cpu-user: + value: 0.000000e+00 +w83df6200/cpu-3/cpu-wait: + value: 0.000000e+00 +w83df6200/cpu-4/cpu-idle: + value: 9.989997e+01 +w83df6200/cpu-4/cpu-interrupt: + value: 0.000000e+00 +w83df6200/cpu-4/cpu-nice: + value: 0.000000e+00 +w83df6200/cpu-4/cpu-softirq: + value: 0.000000e+00 +w83df6200/cpu-4/cpu-steal: + value: 0.000000e+00 +w83df6200/cpu-4/cpu-system: + value: 0.000000e+00 +w83df6200/cpu-4/cpu-user: + value: 0.000000e+00 +w83df6200/cpu-4/cpu-wait: + value: 0.000000e+00 +w83df6200/cpu-5/cpu-idle: + value: 9.989993e+01 +w83df6200/cpu-5/cpu-interrupt: + value: 0.000000e+00 +w83df6200/cpu-5/cpu-nice: + value: 0.000000e+00 +w83df6200/cpu-5/cpu-softirq: + value: 0.000000e+00 +w83df6200/cpu-5/cpu-steal: + value: 0.000000e+00 +w83df6200/cpu-5/cpu-system: + value: 0.000000e+00 +w83df6200/cpu-5/cpu-user: + value: 0.000000e+00 +w83df6200/cpu-5/cpu-wait: + value: 0.000000e+00 +w83df6200/cpu-6/cpu-idle: + value: 9.989989e+01 +w83df6200/cpu-6/cpu-interrupt: + value: 0.000000e+00 +w83df6200/cpu-6/cpu-nice: + value: 0.000000e+00 +w83df6200/cpu-6/cpu-softirq: + value: 0.000000e+00 +w83df6200/cpu-6/cpu-steal: + value: 0.000000e+00 +w83df6200/cpu-6/cpu-system: + value: 9.999989e-02 +w83df6200/cpu-6/cpu-user: + value: 0.000000e+00 +w83df6200/cpu-6/cpu-wait: + value: 0.000000e+00 +w83df6200/cpu-7/cpu-idle: + value: 9.990003e+01 +w83df6200/cpu-7/cpu-interrupt: + value: 0.000000e+00 +w83df6200/cpu-7/cpu-nice: + value: 0.000000e+00 +w83df6200/cpu-7/cpu-softirq: + value: 0.000000e+00 +w83df6200/cpu-7/cpu-steal: + value: 0.000000e+00 +w83df6200/cpu-7/cpu-system: + value: 2.000001e-01 +w83df6200/cpu-7/cpu-user: + value: 0.000000e+00 +w83df6200/cpu-7/cpu-wait: + value: 0.000000e+00 +w83df6200/cpu-8/cpu-idle: + value: 9.990009e+01 +w83df6200/cpu-8/cpu-interrupt: + value: 0.000000e+00 +w83df6200/cpu-8/cpu-nice: + value: 0.000000e+00 +w83df6200/cpu-8/cpu-softirq: + value: 0.000000e+00 +w83df6200/cpu-8/cpu-steal: + value: 0.000000e+00 +w83df6200/cpu-8/cpu-system: + value: 0.000000e+00 +w83df6200/cpu-8/cpu-user: + value: 0.000000e+00 +w83df6200/cpu-8/cpu-wait: + value: 0.000000e+00 +w83df6200/cpu-9/cpu-idle: + value: 1.000001e+02 +w83df6200/cpu-9/cpu-interrupt: + value: 0.000000e+00 +w83df6200/cpu-9/cpu-nice: + value: 0.000000e+00 +w83df6200/cpu-9/cpu-softirq: + value: 0.000000e+00 +w83df6200/cpu-9/cpu-steal: + value: 0.000000e+00 +w83df6200/cpu-9/cpu-system: + value: 0.000000e+00 +w83df6200/cpu-9/cpu-user: + value: 0.000000e+00 +w83df6200/cpu-9/cpu-wait: + value: 0.000000e+00 +w83df6200/df-boot/df_complex-free: + value: 4.369490e+08 +w83df6200/df-boot/df_complex-reserved: + value: 2.684109e+07 +w83df6200/df-boot/df_complex-used: + value: 6.463488e+07 +w83df6200/df-boot/df_inodes-free: + value: 3.271800e+04 +w83df6200/df-boot/df_inodes-reserved: + value: 0.000000e+00 +w83df6200/df-boot/df_inodes-used: + value: 5.000000e+01 +w83df6200/df-boot/percent_bytes-free: + value: 8.268894e+01 +w83df6200/df-boot/percent_bytes-reserved: + value: 5.079451e+00 +w83df6200/df-boot/percent_bytes-used: + value: 1.223161e+01 +w83df6200/df-boot/percent_inodes-free: + value: 9.984741e+01 +w83df6200/df-boot/percent_inodes-reserved: + value: 0.000000e+00 +w83df6200/df-boot/percent_inodes-used: + value: 1.525879e-01 +w83df6200/df-data1/df_complex-free: + value: 2.574625e+11 +w83df6200/df-data1/df_complex-reserved: + value: 1.378982e+10 +w83df6200/df-data1/df_complex-used: + value: 2.165924e+08 +w83df6200/df-data1/df_inodes-free: + value: 1.683452e+07 +w83df6200/df-data1/df_inodes-reserved: + value: 0.000000e+00 +w83df6200/df-data1/df_inodes-used: + value: 4.400000e+01 +w83df6200/df-data1/percent_bytes-free: + value: 9.484051e+01 +w83df6200/df-data1/percent_bytes-reserved: + value: 5.079707e+00 +w83df6200/df-data1/percent_bytes-used: + value: 7.978535e-02 +w83df6200/df-data1/percent_inodes-free: + value: 9.999974e+01 +w83df6200/df-data1/percent_inodes-reserved: + value: 0.000000e+00 +w83df6200/df-data1/percent_inodes-used: + value: 2.613671e-04 +w83df6200/df-dev-shm/df_complex-free: + value: 3.375709e+10 +w83df6200/df-dev-shm/df_complex-reserved: + value: 0.000000e+00 +w83df6200/df-dev-shm/df_complex-used: + value: 0.000000e+00 +w83df6200/df-dev-shm/df_inodes-free: + value: 8.241475e+06 +w83df6200/df-dev-shm/df_inodes-reserved: + value: 0.000000e+00 +w83df6200/df-dev-shm/df_inodes-used: + value: 1.000000e+00 +w83df6200/df-dev-shm/percent_bytes-free: + value: 1.000000e+02 +w83df6200/df-dev-shm/percent_bytes-reserved: + value: 0.000000e+00 +w83df6200/df-dev-shm/percent_bytes-used: + value: 0.000000e+00 +w83df6200/df-dev-shm/percent_inodes-free: + value: 9.999998e+01 +w83df6200/df-dev-shm/percent_inodes-reserved: + value: 0.000000e+00 +w83df6200/df-dev-shm/percent_inodes-used: + value: 1.213375e-05 +w83df6200/df-root/df_complex-free: + value: 1.076426e+10 +w83df6200/df-root/df_complex-reserved: + value: 6.442435e+08 +w83df6200/df-root/df_complex-used: + value: 1.274200e+09 +w83df6200/df-root/df_inodes-free: + value: 7.458150e+05 +w83df6200/df-root/df_inodes-reserved: + value: 0.000000e+00 +w83df6200/df-root/df_inodes-used: + value: 4.061700e+04 +w83df6200/df-root/percent_bytes-free: + value: 8.487355e+01 +w83df6200/df-root/percent_bytes-reserved: + value: 5.079700e+00 +w83df6200/df-root/percent_bytes-used: + value: 1.004675e+01 +w83df6200/df-root/percent_inodes-free: + value: 9.483528e+01 +w83df6200/df-root/percent_inodes-reserved: + value: 0.000000e+00 +w83df6200/df-root/percent_inodes-used: + value: 5.164719e+00 +w83df6200/df-var/df_complex-free: + value: 7.567688e+09 +w83df6200/df-var/df_complex-reserved: + value: 4.294943e+08 +w83df6200/df-var/df_complex-used: + value: 4.579369e+08 +w83df6200/df-var/df_inodes-free: + value: 5.227970e+05 +w83df6200/df-var/df_inodes-reserved: + value: 0.000000e+00 +w83df6200/df-var/df_inodes-used: + value: 1.491000e+03 +w83df6200/df-var/percent_bytes-free: + value: 8.950421e+01 +w83df6200/df-var/percent_bytes-reserved: + value: 5.079695e+00 +w83df6200/df-var/percent_bytes-used: + value: 5.416090e+00 +w83df6200/df-var/percent_inodes-free: + value: 9.971561e+01 +w83df6200/df-var/percent_inodes-reserved: + value: 0.000000e+00 +w83df6200/df-var/percent_inodes-used: + value: 2.843857e-01 +w83df6200/disk-sda/disk_merged: + read: 0.000000e+00 + write: 0.000000e+00 +w83df6200/disk-sda/disk_octets: + read: 0.000000e+00 + write: 0.000000e+00 +w83df6200/disk-sda/disk_ops: + read: 0.000000e+00 + write: 0.000000e+00 +w83df6200/disk-sda/disk_time: + read: 0.000000e+00 + write: 0.000000e+00 +w83df6200/disk-sda1/disk_merged: + read: 0.000000e+00 + write: 0.000000e+00 +w83df6200/disk-sda1/disk_octets: + read: 0.000000e+00 + write: 0.000000e+00 +w83df6200/disk-sda1/disk_ops: + read: 0.000000e+00 + write: 0.000000e+00 +w83df6200/disk-sda1/disk_time: + read: 0.000000e+00 + write: 0.000000e+00 +w83df6200/disk-sda2/disk_merged: + read: 0.000000e+00 + write: 0.000000e+00 +w83df6200/disk-sda2/disk_octets: + read: 0.000000e+00 + write: 0.000000e+00 +w83df6200/disk-sda2/disk_ops: + read: 0.000000e+00 + write: 0.000000e+00 +w83df6200/disk-sda2/disk_time: + read: 0.000000e+00 + write: 0.000000e+00 +w83df6200/disk-sda3/disk_merged: + read: 0.000000e+00 + write: 0.000000e+00 +w83df6200/disk-sda3/disk_octets: + read: 0.000000e+00 + write: 0.000000e+00 +w83df6200/disk-sda3/disk_ops: + read: 0.000000e+00 + write: 0.000000e+00 +w83df6200/disk-sda3/disk_time: + read: 0.000000e+00 + write: 0.000000e+00 +w83df6200/disk-sda4/disk_merged: + read: 0.000000e+00 + write: 0.000000e+00 +w83df6200/disk-sda4/disk_octets: + read: 0.000000e+00 + write: 0.000000e+00 +w83df6200/disk-sda4/disk_ops: + read: 0.000000e+00 + write: 0.000000e+00 +w83df6200/disk-sda4/disk_time: + read: 0.000000e+00 + write: 0.000000e+00 +w83df6200/disk-sda5/disk_merged: + read: 0.000000e+00 + write: 0.000000e+00 +w83df6200/disk-sda5/disk_octets: + read: 0.000000e+00 + write: 0.000000e+00 +w83df6200/disk-sda5/disk_ops: + read: 0.000000e+00 + write: 0.000000e+00 +w83df6200/disk-sda5/disk_time: + read: 0.000000e+00 + write: 0.000000e+00 +w83df6200/disk-sda6/disk_merged: + read: 0.000000e+00 + write: 0.000000e+00 +w83df6200/disk-sda6/disk_octets: + read: 0.000000e+00 + write: 0.000000e+00 +w83df6200/disk-sda6/disk_ops: + read: 0.000000e+00 + write: 0.000000e+00 +w83df6200/disk-sda6/disk_time: + read: 0.000000e+00 + write: 0.000000e+00 +w83df6200/load/load: + longterm: 0.000000e+00 + midterm: 2.000000e-02 + shortterm: 1.000000e-02 +w83df6200/memory/memory-buffered: + value: 2.156175e+08 +w83df6200/memory/memory-cached: + value: 5.203517e+08 +w83df6200/memory/memory-free: + value: 6.524863e+10 +w83df6200/memory/memory-used: + value: 1.529577e+09 +w83df6200/network/if_octets: + rx: 0.000000e+00 + tx: 2.117499e+03 +w83df6200/network/if_packets: + rx: 0.000000e+00 + tx: 1.600001e+00 +w83df6200/network/queue_length: + value: 0.000000e+00 +w83df6200/network/total_values-dispatch-accepted: + value: 0.000000e+00 +w83df6200/network/total_values-dispatch-rejected: + value: 0.000000e+00 +w83df6200/network/total_values-send-accepted: + value: 4.570050e+01 +w83df6200/network/total_values-send-rejected: + value: 0.000000e+00 +w83df6200/swap/swap-cached: + value: 0.000000e+00 +w83df6200/swap/swap-free: + value: 2.147475e+09 +w83df6200/swap/swap-used: + value: 0.000000e+00 +w83df6200/swap/swap_io-in: + value: 0.000000e+00 +w83df6200/swap/swap_io-out: + value: 0.000000e+00 +w83df6200/vmem/vmpage_faults: + majflt: 0.000000e+00 + minflt: 8.000883e-01 +w83df6200/vmem/vmpage_io-memory: + in: 0.000000e+00 + out: 0.000000e+00 +w83df6200/vmem/vmpage_io-swap: + in: 0.000000e+00 + out: 0.000000e+00 +w83df6200/vmem/vmpage_number-active_anon: + value: 1.666900e+04 +w83df6200/vmem/vmpage_number-active_file: + value: 1.167210e+05 +w83df6200/vmem/vmpage_number-anon_pages: + value: 1.154700e+04 +w83df6200/vmem/vmpage_number-anon_transparent_hugepages: + value: 1.000000e+01 +w83df6200/vmem/vmpage_number-boudfe: + value: 0.000000e+00 +w83df6200/vmem/vmpage_number-dirty: + value: 2.000000e+00 +w83df6200/vmem/vmpage_number-file_pages: + value: 1.796800e+05 +w83df6200/vmem/vmpage_number-free_pages: + value: 1.592984e+07 +w83df6200/vmem/vmpage_number-inactive_anon: + value: 4.500000e+01 +w83df6200/vmem/vmpage_number-inactive_file: + value: 6.291600e+04 +w83df6200/vmem/vmpage_number-isolated_anon: + value: 0.000000e+00 +w83df6200/vmem/vmpage_number-isolated_file: + value: 0.000000e+00 +w83df6200/vmem/vmpage_number-kernel_stack: + value: 4.390000e+02 +w83df6200/vmem/vmpage_number-mapped: + value: 1.669000e+03 +w83df6200/vmem/vmpage_number-mlock: + value: 0.000000e+00 +w83df6200/vmem/vmpage_number-page_table_pages: + value: 5.770000e+02 +w83df6200/vmem/vmpage_number-shmem: + value: 4.700000e+01 +w83df6200/vmem/vmpage_number-slab_reclaimable: + value: 2.386770e+05 +w83df6200/vmem/vmpage_number-slab_unreclaimable: + value: 1.476200e+04 +w83df6200/vmem/vmpage_number-unevictable: + value: 0.000000e+00 +w83df6200/vmem/vmpage_number-unstable: + value: 0.000000e+00 +w83df6200/vmem/vmpage_number-vmscan_write: + value: 0.000000e+00 +w83df6200/vmem/vmpage_number-writeback: + value: 0.000000e+00 +w83df6200/vmem/vmpage_number-writeback_temp: + value: 0.000000e+00 +w83df6300/cpu-0/cpu-idle: + value: 9.980074e+01 +w83df6300/cpu-0/cpu-interrupt: + value: 0.000000e+00 +w83df6300/cpu-0/cpu-nice: + value: 0.000000e+00 +w83df6300/cpu-0/cpu-softirq: + value: 0.000000e+00 +w83df6300/cpu-0/cpu-steal: + value: 0.000000e+00 +w83df6300/cpu-0/cpu-system: + value: 0.000000e+00 +w83df6300/cpu-0/cpu-user: + value: 0.000000e+00 +w83df6300/cpu-0/cpu-wait: + value: 0.000000e+00 +w83df6300/cpu-1/cpu-idle: + value: 9.990070e+01 +w83df6300/cpu-1/cpu-interrupt: + value: 0.000000e+00 +w83df6300/cpu-1/cpu-nice: + value: 0.000000e+00 +w83df6300/cpu-1/cpu-softirq: + value: 0.000000e+00 +w83df6300/cpu-1/cpu-steal: + value: 0.000000e+00 +w83df6300/cpu-1/cpu-system: + value: 0.000000e+00 +w83df6300/cpu-1/cpu-user: + value: 0.000000e+00 +w83df6300/cpu-1/cpu-wait: + value: 0.000000e+00 +w83df6300/cpu-10/cpu-idle: + value: 1.000010e+02 +w83df6300/cpu-10/cpu-interrupt: + value: 0.000000e+00 +w83df6300/cpu-10/cpu-nice: + value: 0.000000e+00 +w83df6300/cpu-10/cpu-softirq: + value: 0.000000e+00 +w83df6300/cpu-10/cpu-steal: + value: 0.000000e+00 +w83df6300/cpu-10/cpu-system: + value: 1.000011e-01 +w83df6300/cpu-10/cpu-user: + value: 0.000000e+00 +w83df6300/cpu-10/cpu-wait: + value: 0.000000e+00 +w83df6300/cpu-11/cpu-idle: + value: 1.000011e+02 +w83df6300/cpu-11/cpu-interrupt: + value: 0.000000e+00 +w83df6300/cpu-11/cpu-nice: + value: 0.000000e+00 +w83df6300/cpu-11/cpu-softirq: + value: 0.000000e+00 +w83df6300/cpu-11/cpu-steal: + value: 0.000000e+00 +w83df6300/cpu-11/cpu-system: + value: 0.000000e+00 +w83df6300/cpu-11/cpu-user: + value: 0.000000e+00 +w83df6300/cpu-11/cpu-wait: + value: 0.000000e+00 +w83df6300/cpu-12/cpu-idle: + value: 9.980111e+01 +w83df6300/cpu-12/cpu-interrupt: + value: 0.000000e+00 +w83df6300/cpu-12/cpu-nice: + value: 0.000000e+00 +w83df6300/cpu-12/cpu-softirq: + value: 0.000000e+00 +w83df6300/cpu-12/cpu-steal: + value: 0.000000e+00 +w83df6300/cpu-12/cpu-system: + value: 0.000000e+00 +w83df6300/cpu-12/cpu-user: + value: 0.000000e+00 +w83df6300/cpu-12/cpu-wait: + value: 0.000000e+00 +w83df6300/cpu-13/cpu-idle: + value: 9.990102e+01 +w83df6300/cpu-13/cpu-interrupt: + value: 0.000000e+00 +w83df6300/cpu-13/cpu-nice: + value: 0.000000e+00 +w83df6300/cpu-13/cpu-softirq: + value: 0.000000e+00 +w83df6300/cpu-13/cpu-steal: + value: 0.000000e+00 +w83df6300/cpu-13/cpu-system: + value: 0.000000e+00 +w83df6300/cpu-13/cpu-user: + value: 0.000000e+00 +w83df6300/cpu-13/cpu-wait: + value: 0.000000e+00 +w83df6300/cpu-14/cpu-idle: + value: 9.990101e+01 +w83df6300/cpu-14/cpu-interrupt: + value: 0.000000e+00 +w83df6300/cpu-14/cpu-nice: + value: 0.000000e+00 +w83df6300/cpu-14/cpu-softirq: + value: 0.000000e+00 +w83df6300/cpu-14/cpu-steal: + value: 0.000000e+00 +w83df6300/cpu-14/cpu-system: + value: 0.000000e+00 +w83df6300/cpu-14/cpu-user: + value: 1.000010e-01 +w83df6300/cpu-14/cpu-wait: + value: 0.000000e+00 +w83df6300/cpu-15/cpu-idle: + value: 1.000010e+02 +w83df6300/cpu-15/cpu-interrupt: + value: 0.000000e+00 +w83df6300/cpu-15/cpu-nice: + value: 0.000000e+00 +w83df6300/cpu-15/cpu-softirq: + value: 0.000000e+00 +w83df6300/cpu-15/cpu-steal: + value: 0.000000e+00 +w83df6300/cpu-15/cpu-system: + value: 0.000000e+00 +w83df6300/cpu-15/cpu-user: + value: 0.000000e+00 +w83df6300/cpu-15/cpu-wait: + value: 0.000000e+00 +w83df6300/cpu-16/cpu-idle: + value: 1.000010e+02 +w83df6300/cpu-16/cpu-interrupt: + value: 0.000000e+00 +w83df6300/cpu-16/cpu-nice: + value: 0.000000e+00 +w83df6300/cpu-16/cpu-softirq: + value: 0.000000e+00 +w83df6300/cpu-16/cpu-steal: + value: 0.000000e+00 +w83df6300/cpu-16/cpu-system: + value: 0.000000e+00 +w83df6300/cpu-16/cpu-user: + value: 0.000000e+00 +w83df6300/cpu-16/cpu-wait: + value: 0.000000e+00 +w83df6300/cpu-17/cpu-idle: + value: 1.000010e+02 +w83df6300/cpu-17/cpu-interrupt: + value: 0.000000e+00 +w83df6300/cpu-17/cpu-nice: + value: 0.000000e+00 +w83df6300/cpu-17/cpu-softirq: + value: 0.000000e+00 +w83df6300/cpu-17/cpu-steal: + value: 0.000000e+00 +w83df6300/cpu-17/cpu-system: + value: 0.000000e+00 +w83df6300/cpu-17/cpu-user: + value: 0.000000e+00 +w83df6300/cpu-17/cpu-wait: + value: 0.000000e+00 +w83df6300/cpu-18/cpu-idle: + value: 1.000009e+02 +w83df6300/cpu-18/cpu-interrupt: + value: 0.000000e+00 +w83df6300/cpu-18/cpu-nice: + value: 0.000000e+00 +w83df6300/cpu-18/cpu-softirq: + value: 0.000000e+00 +w83df6300/cpu-18/cpu-steal: + value: 0.000000e+00 +w83df6300/cpu-18/cpu-system: + value: 1.000009e-01 +w83df6300/cpu-18/cpu-user: + value: 0.000000e+00 +w83df6300/cpu-18/cpu-wait: + value: 0.000000e+00 +w83df6300/cpu-19/cpu-idle: + value: 9.990092e+01 +w83df6300/cpu-19/cpu-interrupt: + value: 0.000000e+00 +w83df6300/cpu-19/cpu-nice: + value: 0.000000e+00 +w83df6300/cpu-19/cpu-softirq: + value: 0.000000e+00 +w83df6300/cpu-19/cpu-steal: + value: 0.000000e+00 +w83df6300/cpu-19/cpu-system: + value: 0.000000e+00 +w83df6300/cpu-19/cpu-user: + value: 0.000000e+00 +w83df6300/cpu-19/cpu-wait: + value: 0.000000e+00 +w83df6300/cpu-2/cpu-idle: + value: 1.000009e+02 +w83df6300/cpu-2/cpu-interrupt: + value: 0.000000e+00 +w83df6300/cpu-2/cpu-nice: + value: 0.000000e+00 +w83df6300/cpu-2/cpu-softirq: + value: 0.000000e+00 +w83df6300/cpu-2/cpu-steal: + value: 0.000000e+00 +w83df6300/cpu-2/cpu-system: + value: 0.000000e+00 +w83df6300/cpu-2/cpu-user: + value: 0.000000e+00 +w83df6300/cpu-2/cpu-wait: + value: 0.000000e+00 +w83df6300/cpu-20/cpu-idle: + value: 1.000010e+02 +w83df6300/cpu-20/cpu-interrupt: + value: 0.000000e+00 +w83df6300/cpu-20/cpu-nice: + value: 0.000000e+00 +w83df6300/cpu-20/cpu-softirq: + value: 0.000000e+00 +w83df6300/cpu-20/cpu-steal: + value: 0.000000e+00 +w83df6300/cpu-20/cpu-system: + value: 0.000000e+00 +w83df6300/cpu-20/cpu-user: + value: 0.000000e+00 +w83df6300/cpu-20/cpu-wait: + value: 0.000000e+00 +w83df6300/cpu-21/cpu-idle: + value: 1.000011e+02 +w83df6300/cpu-21/cpu-interrupt: + value: 0.000000e+00 +w83df6300/cpu-21/cpu-nice: + value: 0.000000e+00 +w83df6300/cpu-21/cpu-softirq: + value: 0.000000e+00 +w83df6300/cpu-21/cpu-steal: + value: 0.000000e+00 +w83df6300/cpu-21/cpu-system: + value: 1.000011e-01 +w83df6300/cpu-21/cpu-user: + value: 0.000000e+00 +w83df6300/cpu-21/cpu-wait: + value: 0.000000e+00 +w83df6300/cpu-22/cpu-idle: + value: 1.000012e+02 +w83df6300/cpu-22/cpu-interrupt: + value: 0.000000e+00 +w83df6300/cpu-22/cpu-nice: + value: 0.000000e+00 +w83df6300/cpu-22/cpu-softirq: + value: 0.000000e+00 +w83df6300/cpu-22/cpu-steal: + value: 0.000000e+00 +w83df6300/cpu-22/cpu-system: + value: 1.000012e-01 +w83df6300/cpu-22/cpu-user: + value: 1.000012e-01 +w83df6300/cpu-22/cpu-wait: + value: 0.000000e+00 +w83df6300/cpu-23/cpu-idle: + value: 9.990117e+01 +w83df6300/cpu-23/cpu-interrupt: + value: 0.000000e+00 +w83df6300/cpu-23/cpu-nice: + value: 0.000000e+00 +w83df6300/cpu-23/cpu-softirq: + value: 0.000000e+00 +w83df6300/cpu-23/cpu-steal: + value: 0.000000e+00 +w83df6300/cpu-23/cpu-system: + value: 0.000000e+00 +w83df6300/cpu-23/cpu-user: + value: 0.000000e+00 +w83df6300/cpu-23/cpu-wait: + value: 0.000000e+00 +w83df6300/cpu-3/cpu-idle: + value: 1.000009e+02 +w83df6300/cpu-3/cpu-interrupt: + value: 0.000000e+00 +w83df6300/cpu-3/cpu-nice: + value: 0.000000e+00 +w83df6300/cpu-3/cpu-softirq: + value: 0.000000e+00 +w83df6300/cpu-3/cpu-steal: + value: 0.000000e+00 +w83df6300/cpu-3/cpu-system: + value: 0.000000e+00 +w83df6300/cpu-3/cpu-user: + value: 0.000000e+00 +w83df6300/cpu-3/cpu-wait: + value: 0.000000e+00 +w83df6300/cpu-4/cpu-idle: + value: 9.990089e+01 +w83df6300/cpu-4/cpu-interrupt: + value: 0.000000e+00 +w83df6300/cpu-4/cpu-nice: + value: 0.000000e+00 +w83df6300/cpu-4/cpu-softirq: + value: 0.000000e+00 +w83df6300/cpu-4/cpu-steal: + value: 0.000000e+00 +w83df6300/cpu-4/cpu-system: + value: 0.000000e+00 +w83df6300/cpu-4/cpu-user: + value: 0.000000e+00 +w83df6300/cpu-4/cpu-wait: + value: 0.000000e+00 +w83df6300/cpu-5/cpu-idle: + value: 1.000010e+02 +w83df6300/cpu-5/cpu-interrupt: + value: 0.000000e+00 +w83df6300/cpu-5/cpu-nice: + value: 0.000000e+00 +w83df6300/cpu-5/cpu-softirq: + value: 0.000000e+00 +w83df6300/cpu-5/cpu-steal: + value: 0.000000e+00 +w83df6300/cpu-5/cpu-system: + value: 0.000000e+00 +w83df6300/cpu-5/cpu-user: + value: 0.000000e+00 +w83df6300/cpu-5/cpu-wait: + value: 0.000000e+00 +w83df6300/cpu-6/cpu-idle: + value: 1.000010e+02 +w83df6300/cpu-6/cpu-interrupt: + value: 0.000000e+00 +w83df6300/cpu-6/cpu-nice: + value: 0.000000e+00 +w83df6300/cpu-6/cpu-softirq: + value: 0.000000e+00 +w83df6300/cpu-6/cpu-steal: + value: 0.000000e+00 +w83df6300/cpu-6/cpu-system: + value: 1.000010e-01 +w83df6300/cpu-6/cpu-user: + value: 0.000000e+00 +w83df6300/cpu-6/cpu-wait: + value: 0.000000e+00 +w83df6300/cpu-7/cpu-idle: + value: 1.000011e+02 +w83df6300/cpu-7/cpu-interrupt: + value: 0.000000e+00 +w83df6300/cpu-7/cpu-nice: + value: 0.000000e+00 +w83df6300/cpu-7/cpu-softirq: + value: 0.000000e+00 +w83df6300/cpu-7/cpu-steal: + value: 0.000000e+00 +w83df6300/cpu-7/cpu-system: + value: 0.000000e+00 +w83df6300/cpu-7/cpu-user: + value: 0.000000e+00 +w83df6300/cpu-7/cpu-wait: + value: 0.000000e+00 +w83df6300/cpu-8/cpu-idle: + value: 9.990103e+01 +w83df6300/cpu-8/cpu-interrupt: + value: 0.000000e+00 +w83df6300/cpu-8/cpu-nice: + value: 0.000000e+00 +w83df6300/cpu-8/cpu-softirq: + value: 0.000000e+00 +w83df6300/cpu-8/cpu-steal: + value: 0.000000e+00 +w83df6300/cpu-8/cpu-system: + value: 0.000000e+00 +w83df6300/cpu-8/cpu-user: + value: 0.000000e+00 +w83df6300/cpu-8/cpu-wait: + value: 0.000000e+00 +w83df6300/cpu-9/cpu-idle: + value: 1.000010e+02 +w83df6300/cpu-9/cpu-interrupt: + value: 0.000000e+00 +w83df6300/cpu-9/cpu-nice: + value: 0.000000e+00 +w83df6300/cpu-9/cpu-softirq: + value: 0.000000e+00 +w83df6300/cpu-9/cpu-steal: + value: 0.000000e+00 +w83df6300/cpu-9/cpu-system: + value: 0.000000e+00 +w83df6300/cpu-9/cpu-user: + value: 0.000000e+00 +w83df6300/cpu-9/cpu-wait: + value: 0.000000e+00 +w83df6300/df-boot/df_complex-free: + value: 4.369449e+08 +w83df6300/df-boot/df_complex-reserved: + value: 2.684109e+07 +w83df6300/df-boot/df_complex-used: + value: 6.463898e+07 +w83df6300/df-boot/df_inodes-free: + value: 3.271800e+04 +w83df6300/df-boot/df_inodes-reserved: + value: 0.000000e+00 +w83df6300/df-boot/df_inodes-used: + value: 5.000000e+01 +w83df6300/df-boot/percent_bytes-free: + value: 8.268816e+01 +w83df6300/df-boot/percent_bytes-reserved: + value: 5.079451e+00 +w83df6300/df-boot/percent_bytes-used: + value: 1.223238e+01 +w83df6300/df-boot/percent_inodes-free: + value: 9.984741e+01 +w83df6300/df-boot/percent_inodes-reserved: + value: 0.000000e+00 +w83df6300/df-boot/percent_inodes-used: + value: 1.525879e-01 +w83df6300/df-data1/df_complex-free: + value: 2.574625e+11 +w83df6300/df-data1/df_complex-reserved: + value: 1.378982e+10 +w83df6300/df-data1/df_complex-used: + value: 2.165924e+08 +w83df6300/df-data1/df_inodes-free: + value: 1.683452e+07 +w83df6300/df-data1/df_inodes-reserved: + value: 0.000000e+00 +w83df6300/df-data1/df_inodes-used: + value: 4.400000e+01 +w83df6300/df-data1/percent_bytes-free: + value: 9.484051e+01 +w83df6300/df-data1/percent_bytes-reserved: + value: 5.079707e+00 +w83df6300/df-data1/percent_bytes-used: + value: 7.978535e-02 +w83df6300/df-data1/percent_inodes-free: + value: 9.999974e+01 +w83df6300/df-data1/percent_inodes-reserved: + value: 0.000000e+00 +w83df6300/df-data1/percent_inodes-used: + value: 2.613671e-04 +w83df6300/df-dev-shm/df_complex-free: + value: 3.375709e+10 +w83df6300/df-dev-shm/df_complex-reserved: + value: 0.000000e+00 +w83df6300/df-dev-shm/df_complex-used: + value: 0.000000e+00 +w83df6300/df-dev-shm/df_inodes-free: + value: 8.241475e+06 +w83df6300/df-dev-shm/df_inodes-reserved: + value: 0.000000e+00 +w83df6300/df-dev-shm/df_inodes-used: + value: 1.000000e+00 +w83df6300/df-dev-shm/percent_bytes-free: + value: 1.000000e+02 +w83df6300/df-dev-shm/percent_bytes-reserved: + value: 0.000000e+00 +w83df6300/df-dev-shm/percent_bytes-used: + value: 0.000000e+00 +w83df6300/df-dev-shm/percent_inodes-free: + value: 9.999998e+01 +w83df6300/df-dev-shm/percent_inodes-reserved: + value: 0.000000e+00 +w83df6300/df-dev-shm/percent_inodes-used: + value: 1.213375e-05 +w83df6300/df-root/df_complex-free: + value: 1.022576e+10 +w83df6300/df-root/df_complex-reserved: + value: 6.442435e+08 +w83df6300/df-root/df_complex-used: + value: 1.812701e+09 +w83df6300/df-root/df_inodes-free: + value: 7.415980e+05 +w83df6300/df-root/df_inodes-reserved: + value: 0.000000e+00 +w83df6300/df-root/df_inodes-used: + value: 4.483400e+04 +w83df6300/df-root/percent_bytes-free: + value: 8.062760e+01 +w83df6300/df-root/percent_bytes-reserved: + value: 5.079700e+00 +w83df6300/df-root/percent_bytes-used: + value: 1.429270e+01 +w83df6300/df-root/percent_inodes-free: + value: 9.429906e+01 +w83df6300/df-root/percent_inodes-reserved: + value: 0.000000e+00 +w83df6300/df-root/percent_inodes-used: + value: 5.700938e+00 +w83df6300/df-var/df_complex-free: + value: 7.485731e+09 +w83df6300/df-var/df_complex-reserved: + value: 4.294943e+08 +w83df6300/df-var/df_complex-used: + value: 5.398938e+08 +w83df6300/df-var/df_inodes-free: + value: 5.224290e+05 +w83df6300/df-var/df_inodes-reserved: + value: 0.000000e+00 +w83df6300/df-var/df_inodes-used: + value: 1.859000e+03 +w83df6300/df-var/percent_bytes-free: + value: 8.853490e+01 +w83df6300/df-var/percent_bytes-reserved: + value: 5.079695e+00 +w83df6300/df-var/percent_bytes-used: + value: 6.385407e+00 +w83df6300/df-var/percent_inodes-free: + value: 9.964542e+01 +w83df6300/df-var/percent_inodes-reserved: + value: 0.000000e+00 +w83df6300/df-var/percent_inodes-used: + value: 3.545761e-01 +w83df6300/disk-sda/disk_merged: + read: 0.000000e+00 + write: 0.000000e+00 +w83df6300/disk-sda/disk_octets: + read: 0.000000e+00 + write: 0.000000e+00 +w83df6300/disk-sda/disk_ops: + read: 0.000000e+00 + write: 0.000000e+00 +w83df6300/disk-sda/disk_time: + read: 0.000000e+00 + write: 0.000000e+00 +w83df6300/disk-sda1/disk_merged: + read: 0.000000e+00 + write: 0.000000e+00 +w83df6300/disk-sda1/disk_octets: + read: 0.000000e+00 + write: 0.000000e+00 +w83df6300/disk-sda1/disk_ops: + read: 0.000000e+00 + write: 0.000000e+00 +w83df6300/disk-sda1/disk_time: + read: 0.000000e+00 + write: 0.000000e+00 +w83df6300/disk-sda2/disk_merged: + read: 0.000000e+00 + write: 0.000000e+00 +w83df6300/disk-sda2/disk_octets: + read: 0.000000e+00 + write: 0.000000e+00 +w83df6300/disk-sda2/disk_ops: + read: 0.000000e+00 + write: 0.000000e+00 +w83df6300/disk-sda2/disk_time: + read: 0.000000e+00 + write: 0.000000e+00 +w83df6300/disk-sda3/disk_merged: + read: 0.000000e+00 + write: 0.000000e+00 +w83df6300/disk-sda3/disk_octets: + read: 0.000000e+00 + write: 0.000000e+00 +w83df6300/disk-sda3/disk_ops: + read: 0.000000e+00 + write: 0.000000e+00 +w83df6300/disk-sda3/disk_time: + read: 0.000000e+00 + write: 0.000000e+00 +w83df6300/disk-sda4/disk_merged: + read: 0.000000e+00 + write: 0.000000e+00 +w83df6300/disk-sda4/disk_octets: + read: 0.000000e+00 + write: 0.000000e+00 +w83df6300/disk-sda4/disk_ops: + read: 0.000000e+00 + write: 0.000000e+00 +w83df6300/disk-sda4/disk_time: + read: 0.000000e+00 + write: 0.000000e+00 +w83df6300/disk-sda5/disk_merged: + read: 0.000000e+00 + write: 0.000000e+00 +w83df6300/disk-sda5/disk_octets: + read: 0.000000e+00 + write: 0.000000e+00 +w83df6300/disk-sda5/disk_ops: + read: 0.000000e+00 + write: 0.000000e+00 +w83df6300/disk-sda5/disk_time: + read: 0.000000e+00 + write: 0.000000e+00 +w83df6300/disk-sda6/disk_merged: + read: 0.000000e+00 + write: 0.000000e+00 +w83df6300/disk-sda6/disk_octets: + read: 0.000000e+00 + write: 0.000000e+00 +w83df6300/disk-sda6/disk_ops: + read: 0.000000e+00 + write: 0.000000e+00 +w83df6300/disk-sda6/disk_time: + read: 0.000000e+00 + write: 0.000000e+00 +w83df6300/load/load: + longterm: 0.000000e+00 + midterm: 2.000000e-02 + shortterm: 1.000000e-02 +w83df6300/memory/memory-buffered: + value: 2.686280e+08 +w83df6300/memory/memory-cached: + value: 1.142759e+09 +w83df6300/memory/memory-free: + value: 6.452790e+10 +w83df6300/memory/memory-used: + value: 1.574883e+09 +w83df6300/network/if_octets: + rx: 0.000000e+00 + tx: 1.575799e+03 +w83df6300/network/if_packets: + rx: 0.000000e+00 + tx: 1.199999e+00 +w83df6300/network/queue_length: + value: 0.000000e+00 +w83df6300/network/total_values-dispatch-accepted: + value: 0.000000e+00 +w83df6300/network/total_values-dispatch-rejected: + value: 0.000000e+00 +w83df6300/network/total_values-send-accepted: + value: 3.240001e+01 +w83df6300/network/total_values-send-rejected: + value: 0.000000e+00 +w83df6300/swap/swap-cached: + value: 0.000000e+00 +w83df6300/swap/swap-free: + value: 2.147475e+09 +w83df6300/swap/swap-used: + value: 0.000000e+00 +w83df6300/swap/swap_io-in: + value: 0.000000e+00 +w83df6300/swap/swap_io-out: + value: 0.000000e+00 +w83df6300/vmem/vmpage_faults: + majflt: 0.000000e+00 + minflt: 3.800015e+00 +w83df6300/vmem/vmpage_io-memory: + in: 0.000000e+00 + out: 0.000000e+00 +w83df6300/vmem/vmpage_io-swap: + in: 0.000000e+00 + out: 0.000000e+00 +w83df6300/vmem/vmpage_number-active_anon: + value: 1.835300e+04 +w83df6300/vmem/vmpage_number-active_file: + value: 1.867190e+05 +w83df6300/vmem/vmpage_number-anon_pages: + value: 1.272000e+04 +w83df6300/vmem/vmpage_number-anon_transparent_hugepages: + value: 1.100000e+01 +w83df6300/vmem/vmpage_number-boudfe: + value: 0.000000e+00 +w83df6300/vmem/vmpage_number-dirty: + value: 4.000000e+00 +w83df6300/vmem/vmpage_number-file_pages: + value: 3.445770e+05 +w83df6300/vmem/vmpage_number-free_pages: + value: 1.575388e+07 +w83df6300/vmem/vmpage_number-inactive_anon: + value: 4.900000e+01 +w83df6300/vmem/vmpage_number-inactive_file: + value: 1.578110e+05 +w83df6300/vmem/vmpage_number-isolated_anon: + value: 0.000000e+00 +w83df6300/vmem/vmpage_number-isolated_file: + value: 0.000000e+00 +w83df6300/vmem/vmpage_number-kernel_stack: + value: 4.460000e+02 +w83df6300/vmem/vmpage_number-mapped: + value: 2.404000e+03 +w83df6300/vmem/vmpage_number-mlock: + value: 0.000000e+00 +w83df6300/vmem/vmpage_number-page_table_pages: + value: 8.250000e+02 +w83df6300/vmem/vmpage_number-shmem: + value: 5.100000e+01 +w83df6300/vmem/vmpage_number-slab_reclaimable: + value: 2.469330e+05 +w83df6300/vmem/vmpage_number-slab_unreclaimable: + value: 1.504900e+04 +w83df6300/vmem/vmpage_number-unevictable: + value: 0.000000e+00 +w83df6300/vmem/vmpage_number-unstable: + value: 0.000000e+00 +w83df6300/vmem/vmpage_number-vmscan_write: + value: 0.000000e+00 +w83df6300/vmem/vmpage_number-writeback: + value: 0.000000e+00 +w83df6300/vmem/vmpage_number-writeback_temp: + value: 0.000000e+00 +w83df6400/cpu-0/cpu-idle: + value: 9.979917e+01 +w83df6400/cpu-0/cpu-interrupt: + value: 0.000000e+00 +w83df6400/cpu-0/cpu-nice: + value: 0.000000e+00 +w83df6400/cpu-0/cpu-softirq: + value: 0.000000e+00 +w83df6400/cpu-0/cpu-steal: + value: 0.000000e+00 +w83df6400/cpu-0/cpu-system: + value: 0.000000e+00 +w83df6400/cpu-0/cpu-user: + value: 0.000000e+00 +w83df6400/cpu-0/cpu-wait: + value: 0.000000e+00 +w83df6400/cpu-1/cpu-idle: + value: 9.989810e+01 +w83df6400/cpu-1/cpu-interrupt: + value: 0.000000e+00 +w83df6400/cpu-1/cpu-nice: + value: 0.000000e+00 +w83df6400/cpu-1/cpu-softirq: + value: 0.000000e+00 +w83df6400/cpu-1/cpu-steal: + value: 0.000000e+00 +w83df6400/cpu-1/cpu-system: + value: 0.000000e+00 +w83df6400/cpu-1/cpu-user: + value: 9.999843e-02 +w83df6400/cpu-1/cpu-wait: + value: 0.000000e+00 +w83df6400/cpu-10/cpu-idle: + value: 9.999853e+01 +w83df6400/cpu-10/cpu-interrupt: + value: 0.000000e+00 +w83df6400/cpu-10/cpu-nice: + value: 0.000000e+00 +w83df6400/cpu-10/cpu-softirq: + value: 0.000000e+00 +w83df6400/cpu-10/cpu-steal: + value: 0.000000e+00 +w83df6400/cpu-10/cpu-system: + value: 9.999853e-02 +w83df6400/cpu-10/cpu-user: + value: 0.000000e+00 +w83df6400/cpu-10/cpu-wait: + value: 0.000000e+00 +w83df6400/cpu-11/cpu-idle: + value: 9.989854e+01 +w83df6400/cpu-11/cpu-interrupt: + value: 0.000000e+00 +w83df6400/cpu-11/cpu-nice: + value: 0.000000e+00 +w83df6400/cpu-11/cpu-softirq: + value: 0.000000e+00 +w83df6400/cpu-11/cpu-steal: + value: 0.000000e+00 +w83df6400/cpu-11/cpu-system: + value: 9.999853e-02 +w83df6400/cpu-11/cpu-user: + value: 0.000000e+00 +w83df6400/cpu-11/cpu-wait: + value: 0.000000e+00 +w83df6400/cpu-12/cpu-idle: + value: 9.989849e+01 +w83df6400/cpu-12/cpu-interrupt: + value: 0.000000e+00 +w83df6400/cpu-12/cpu-nice: + value: 0.000000e+00 +w83df6400/cpu-12/cpu-softirq: + value: 0.000000e+00 +w83df6400/cpu-12/cpu-steal: + value: 0.000000e+00 +w83df6400/cpu-12/cpu-system: + value: 0.000000e+00 +w83df6400/cpu-12/cpu-user: + value: 0.000000e+00 +w83df6400/cpu-12/cpu-wait: + value: 0.000000e+00 +w83df6400/cpu-13/cpu-idle: + value: 9.989843e+01 +w83df6400/cpu-13/cpu-interrupt: + value: 0.000000e+00 +w83df6400/cpu-13/cpu-nice: + value: 0.000000e+00 +w83df6400/cpu-13/cpu-softirq: + value: 0.000000e+00 +w83df6400/cpu-13/cpu-steal: + value: 0.000000e+00 +w83df6400/cpu-13/cpu-system: + value: 0.000000e+00 +w83df6400/cpu-13/cpu-user: + value: 0.000000e+00 +w83df6400/cpu-13/cpu-wait: + value: 0.000000e+00 +w83df6400/cpu-14/cpu-idle: + value: 9.999838e+01 +w83df6400/cpu-14/cpu-interrupt: + value: 0.000000e+00 +w83df6400/cpu-14/cpu-nice: + value: 0.000000e+00 +w83df6400/cpu-14/cpu-softirq: + value: 0.000000e+00 +w83df6400/cpu-14/cpu-steal: + value: 0.000000e+00 +w83df6400/cpu-14/cpu-system: + value: 0.000000e+00 +w83df6400/cpu-14/cpu-user: + value: 0.000000e+00 +w83df6400/cpu-14/cpu-wait: + value: 0.000000e+00 +w83df6400/cpu-15/cpu-idle: + value: 9.989833e+01 +w83df6400/cpu-15/cpu-interrupt: + value: 0.000000e+00 +w83df6400/cpu-15/cpu-nice: + value: 0.000000e+00 +w83df6400/cpu-15/cpu-softirq: + value: 0.000000e+00 +w83df6400/cpu-15/cpu-steal: + value: 0.000000e+00 +w83df6400/cpu-15/cpu-system: + value: 0.000000e+00 +w83df6400/cpu-15/cpu-user: + value: 0.000000e+00 +w83df6400/cpu-15/cpu-wait: + value: 0.000000e+00 +w83df6400/cpu-16/cpu-idle: + value: 9.999832e+01 +w83df6400/cpu-16/cpu-interrupt: + value: 0.000000e+00 +w83df6400/cpu-16/cpu-nice: + value: 0.000000e+00 +w83df6400/cpu-16/cpu-softirq: + value: 0.000000e+00 +w83df6400/cpu-16/cpu-steal: + value: 0.000000e+00 +w83df6400/cpu-16/cpu-system: + value: 9.999834e-02 +w83df6400/cpu-16/cpu-user: + value: 0.000000e+00 +w83df6400/cpu-16/cpu-wait: + value: 0.000000e+00 +w83df6400/cpu-17/cpu-idle: + value: 9.989833e+01 +w83df6400/cpu-17/cpu-interrupt: + value: 0.000000e+00 +w83df6400/cpu-17/cpu-nice: + value: 0.000000e+00 +w83df6400/cpu-17/cpu-softirq: + value: 0.000000e+00 +w83df6400/cpu-17/cpu-steal: + value: 0.000000e+00 +w83df6400/cpu-17/cpu-system: + value: 0.000000e+00 +w83df6400/cpu-17/cpu-user: + value: 0.000000e+00 +w83df6400/cpu-17/cpu-wait: + value: 0.000000e+00 +w83df6400/cpu-18/cpu-idle: + value: 9.999827e+01 +w83df6400/cpu-18/cpu-interrupt: + value: 0.000000e+00 +w83df6400/cpu-18/cpu-nice: + value: 0.000000e+00 +w83df6400/cpu-18/cpu-softirq: + value: 0.000000e+00 +w83df6400/cpu-18/cpu-steal: + value: 0.000000e+00 +w83df6400/cpu-18/cpu-system: + value: 0.000000e+00 +w83df6400/cpu-18/cpu-user: + value: 0.000000e+00 +w83df6400/cpu-18/cpu-wait: + value: 0.000000e+00 +w83df6400/cpu-19/cpu-idle: + value: 9.999815e+01 +w83df6400/cpu-19/cpu-interrupt: + value: 0.000000e+00 +w83df6400/cpu-19/cpu-nice: + value: 0.000000e+00 +w83df6400/cpu-19/cpu-softirq: + value: 0.000000e+00 +w83df6400/cpu-19/cpu-steal: + value: 0.000000e+00 +w83df6400/cpu-19/cpu-system: + value: 0.000000e+00 +w83df6400/cpu-19/cpu-user: + value: 0.000000e+00 +w83df6400/cpu-19/cpu-wait: + value: 0.000000e+00 +w83df6400/cpu-2/cpu-idle: + value: 9.979807e+01 +w83df6400/cpu-2/cpu-interrupt: + value: 0.000000e+00 +w83df6400/cpu-2/cpu-nice: + value: 0.000000e+00 +w83df6400/cpu-2/cpu-softirq: + value: 0.000000e+00 +w83df6400/cpu-2/cpu-steal: + value: 0.000000e+00 +w83df6400/cpu-2/cpu-system: + value: 0.000000e+00 +w83df6400/cpu-2/cpu-user: + value: 9.999811e-02 +w83df6400/cpu-2/cpu-wait: + value: 0.000000e+00 +w83df6400/cpu-20/cpu-idle: + value: 9.999811e+01 +w83df6400/cpu-20/cpu-interrupt: + value: 0.000000e+00 +w83df6400/cpu-20/cpu-nice: + value: 0.000000e+00 +w83df6400/cpu-20/cpu-softirq: + value: 0.000000e+00 +w83df6400/cpu-20/cpu-steal: + value: 0.000000e+00 +w83df6400/cpu-20/cpu-system: + value: 0.000000e+00 +w83df6400/cpu-20/cpu-user: + value: 0.000000e+00 +w83df6400/cpu-20/cpu-wait: + value: 0.000000e+00 +w83df6400/cpu-21/cpu-idle: + value: 9.999773e+01 +w83df6400/cpu-21/cpu-interrupt: + value: 0.000000e+00 +w83df6400/cpu-21/cpu-nice: + value: 0.000000e+00 +w83df6400/cpu-21/cpu-softirq: + value: 0.000000e+00 +w83df6400/cpu-21/cpu-steal: + value: 0.000000e+00 +w83df6400/cpu-21/cpu-system: + value: 0.000000e+00 +w83df6400/cpu-21/cpu-user: + value: 0.000000e+00 +w83df6400/cpu-21/cpu-wait: + value: 0.000000e+00 +w83df6400/cpu-22/cpu-idle: + value: 9.999773e+01 +w83df6400/cpu-22/cpu-interrupt: + value: 0.000000e+00 +w83df6400/cpu-22/cpu-nice: + value: 0.000000e+00 +w83df6400/cpu-22/cpu-softirq: + value: 0.000000e+00 +w83df6400/cpu-22/cpu-steal: + value: 0.000000e+00 +w83df6400/cpu-22/cpu-system: + value: 0.000000e+00 +w83df6400/cpu-22/cpu-user: + value: 0.000000e+00 +w83df6400/cpu-22/cpu-wait: + value: 0.000000e+00 +w83df6400/cpu-23/cpu-idle: + value: 9.989763e+01 +w83df6400/cpu-23/cpu-interrupt: + value: 0.000000e+00 +w83df6400/cpu-23/cpu-nice: + value: 0.000000e+00 +w83df6400/cpu-23/cpu-softirq: + value: 0.000000e+00 +w83df6400/cpu-23/cpu-steal: + value: 0.000000e+00 +w83df6400/cpu-23/cpu-system: + value: 0.000000e+00 +w83df6400/cpu-23/cpu-user: + value: 0.000000e+00 +w83df6400/cpu-23/cpu-wait: + value: 0.000000e+00 +w83df6400/cpu-3/cpu-idle: + value: 9.999817e+01 +w83df6400/cpu-3/cpu-interrupt: + value: 0.000000e+00 +w83df6400/cpu-3/cpu-nice: + value: 0.000000e+00 +w83df6400/cpu-3/cpu-softirq: + value: 0.000000e+00 +w83df6400/cpu-3/cpu-steal: + value: 0.000000e+00 +w83df6400/cpu-3/cpu-system: + value: 0.000000e+00 +w83df6400/cpu-3/cpu-user: + value: 0.000000e+00 +w83df6400/cpu-3/cpu-wait: + value: 0.000000e+00 +w83df6400/cpu-4/cpu-idle: + value: 9.989839e+01 +w83df6400/cpu-4/cpu-interrupt: + value: 0.000000e+00 +w83df6400/cpu-4/cpu-nice: + value: 0.000000e+00 +w83df6400/cpu-4/cpu-softirq: + value: 0.000000e+00 +w83df6400/cpu-4/cpu-steal: + value: 0.000000e+00 +w83df6400/cpu-4/cpu-system: + value: 0.000000e+00 +w83df6400/cpu-4/cpu-user: + value: 0.000000e+00 +w83df6400/cpu-4/cpu-wait: + value: 0.000000e+00 +w83df6400/cpu-5/cpu-idle: + value: 9.999820e+01 +w83df6400/cpu-5/cpu-interrupt: + value: 0.000000e+00 +w83df6400/cpu-5/cpu-nice: + value: 0.000000e+00 +w83df6400/cpu-5/cpu-softirq: + value: 0.000000e+00 +w83df6400/cpu-5/cpu-steal: + value: 0.000000e+00 +w83df6400/cpu-5/cpu-system: + value: 9.999815e-02 +w83df6400/cpu-5/cpu-user: + value: 0.000000e+00 +w83df6400/cpu-5/cpu-wait: + value: 0.000000e+00 +w83df6400/cpu-6/cpu-idle: + value: 9.989865e+01 +w83df6400/cpu-6/cpu-interrupt: + value: 0.000000e+00 +w83df6400/cpu-6/cpu-nice: + value: 0.000000e+00 +w83df6400/cpu-6/cpu-softirq: + value: 0.000000e+00 +w83df6400/cpu-6/cpu-steal: + value: 0.000000e+00 +w83df6400/cpu-6/cpu-system: + value: 0.000000e+00 +w83df6400/cpu-6/cpu-user: + value: 0.000000e+00 +w83df6400/cpu-6/cpu-wait: + value: 0.000000e+00 +w83df6400/cpu-7/cpu-idle: + value: 9.999866e+01 +w83df6400/cpu-7/cpu-interrupt: + value: 0.000000e+00 +w83df6400/cpu-7/cpu-nice: + value: 0.000000e+00 +w83df6400/cpu-7/cpu-softirq: + value: 0.000000e+00 +w83df6400/cpu-7/cpu-steal: + value: 0.000000e+00 +w83df6400/cpu-7/cpu-system: + value: 9.999866e-02 +w83df6400/cpu-7/cpu-user: + value: 0.000000e+00 +w83df6400/cpu-7/cpu-wait: + value: 0.000000e+00 +w83df6400/cpu-8/cpu-idle: + value: 9.999857e+01 +w83df6400/cpu-8/cpu-interrupt: + value: 0.000000e+00 +w83df6400/cpu-8/cpu-nice: + value: 0.000000e+00 +w83df6400/cpu-8/cpu-softirq: + value: 0.000000e+00 +w83df6400/cpu-8/cpu-steal: + value: 0.000000e+00 +w83df6400/cpu-8/cpu-system: + value: 9.999860e-02 +w83df6400/cpu-8/cpu-user: + value: 0.000000e+00 +w83df6400/cpu-8/cpu-wait: + value: 0.000000e+00 +w83df6400/cpu-9/cpu-idle: + value: 9.989853e+01 +w83df6400/cpu-9/cpu-interrupt: + value: 0.000000e+00 +w83df6400/cpu-9/cpu-nice: + value: 0.000000e+00 +w83df6400/cpu-9/cpu-softirq: + value: 0.000000e+00 +w83df6400/cpu-9/cpu-steal: + value: 0.000000e+00 +w83df6400/cpu-9/cpu-system: + value: 9.999854e-02 +w83df6400/cpu-9/cpu-user: + value: 0.000000e+00 +w83df6400/cpu-9/cpu-wait: + value: 0.000000e+00 +w83df6400/df-boot/df_complex-free: + value: 4.369449e+08 +w83df6400/df-boot/df_complex-reserved: + value: 2.684109e+07 +w83df6400/df-boot/df_complex-used: + value: 6.463898e+07 +w83df6400/df-boot/df_inodes-free: + value: 3.271800e+04 +w83df6400/df-boot/df_inodes-reserved: + value: 0.000000e+00 +w83df6400/df-boot/df_inodes-used: + value: 5.000000e+01 +w83df6400/df-boot/percent_bytes-free: + value: 8.268816e+01 +w83df6400/df-boot/percent_bytes-reserved: + value: 5.079451e+00 +w83df6400/df-boot/percent_bytes-used: + value: 1.223238e+01 +w83df6400/df-boot/percent_inodes-free: + value: 9.984741e+01 +w83df6400/df-boot/percent_inodes-reserved: + value: 0.000000e+00 +w83df6400/df-boot/percent_inodes-used: + value: 1.525879e-01 +w83df6400/df-data1/df_complex-free: + value: 2.574625e+11 +w83df6400/df-data1/df_complex-reserved: + value: 1.378982e+10 +w83df6400/df-data1/df_complex-used: + value: 2.165924e+08 +w83df6400/df-data1/df_inodes-free: + value: 1.683452e+07 +w83df6400/df-data1/df_inodes-reserved: + value: 0.000000e+00 +w83df6400/df-data1/df_inodes-used: + value: 4.400000e+01 +w83df6400/df-data1/percent_bytes-free: + value: 9.484051e+01 +w83df6400/df-data1/percent_bytes-reserved: + value: 5.079707e+00 +w83df6400/df-data1/percent_bytes-used: + value: 7.978535e-02 +w83df6400/df-data1/percent_inodes-free: + value: 9.999974e+01 +w83df6400/df-data1/percent_inodes-reserved: + value: 0.000000e+00 +w83df6400/df-data1/percent_inodes-used: + value: 2.613671e-04 +w83df6400/df-dev-shm/df_complex-free: + value: 3.375709e+10 +w83df6400/df-dev-shm/df_complex-reserved: + value: 0.000000e+00 +w83df6400/df-dev-shm/df_complex-used: + value: 0.000000e+00 +w83df6400/df-dev-shm/df_inodes-free: + value: 8.241475e+06 +w83df6400/df-dev-shm/df_inodes-reserved: + value: 0.000000e+00 +w83df6400/df-dev-shm/df_inodes-used: + value: 1.000000e+00 +w83df6400/df-dev-shm/percent_bytes-free: + value: 1.000000e+02 +w83df6400/df-dev-shm/percent_bytes-reserved: + value: 0.000000e+00 +w83df6400/df-dev-shm/percent_bytes-used: + value: 0.000000e+00 +w83df6400/df-dev-shm/percent_inodes-free: + value: 9.999998e+01 +w83df6400/df-dev-shm/percent_inodes-reserved: + value: 0.000000e+00 +w83df6400/df-dev-shm/percent_inodes-used: + value: 1.213375e-05 +w83df6400/df-root/df_complex-free: + value: 1.062062e+10 +w83df6400/df-root/df_complex-reserved: + value: 6.442435e+08 +w83df6400/df-root/df_complex-used: + value: 1.417847e+09 +w83df6400/df-root/df_inodes-free: + value: 7.449690e+05 +w83df6400/df-root/df_inodes-reserved: + value: 0.000000e+00 +w83df6400/df-root/df_inodes-used: + value: 4.146300e+04 +w83df6400/df-root/percent_bytes-free: + value: 8.374093e+01 +w83df6400/df-root/percent_bytes-reserved: + value: 5.079700e+00 +w83df6400/df-root/percent_bytes-used: + value: 1.117937e+01 +w83df6400/df-root/percent_inodes-free: + value: 9.472771e+01 +w83df6400/df-root/percent_inodes-reserved: + value: 0.000000e+00 +w83df6400/df-root/percent_inodes-used: + value: 5.272293e+00 +w83df6400/df-var/df_complex-free: + value: 7.567413e+09 +w83df6400/df-var/df_complex-reserved: + value: 4.294943e+08 +w83df6400/df-var/df_complex-used: + value: 4.582113e+08 +w83df6400/df-var/df_inodes-free: + value: 5.227820e+05 +w83df6400/df-var/df_inodes-reserved: + value: 0.000000e+00 +w83df6400/df-var/df_inodes-used: + value: 1.506000e+03 +w83df6400/df-var/percent_bytes-free: + value: 8.950097e+01 +w83df6400/df-var/percent_bytes-reserved: + value: 5.079695e+00 +w83df6400/df-var/percent_bytes-used: + value: 5.419336e+00 +w83df6400/df-var/percent_inodes-free: + value: 9.971275e+01 +w83df6400/df-var/percent_inodes-reserved: + value: 0.000000e+00 +w83df6400/df-var/percent_inodes-used: + value: 2.872467e-01 +w83df6400/disk-sda/disk_merged: + read: 0.000000e+00 + write: 0.000000e+00 +w83df6400/disk-sda/disk_octets: + read: 0.000000e+00 + write: 0.000000e+00 +w83df6400/disk-sda/disk_ops: + read: 0.000000e+00 + write: 0.000000e+00 +w83df6400/disk-sda/disk_time: + read: 0.000000e+00 + write: 0.000000e+00 +w83df6400/disk-sda1/disk_merged: + read: 0.000000e+00 + write: 0.000000e+00 +w83df6400/disk-sda1/disk_octets: + read: 0.000000e+00 + write: 0.000000e+00 +w83df6400/disk-sda1/disk_ops: + read: 0.000000e+00 + write: 0.000000e+00 +w83df6400/disk-sda1/disk_time: + read: 0.000000e+00 + write: 0.000000e+00 +w83df6400/disk-sda2/disk_merged: + read: 0.000000e+00 + write: 0.000000e+00 +w83df6400/disk-sda2/disk_octets: + read: 0.000000e+00 + write: 0.000000e+00 +w83df6400/disk-sda2/disk_ops: + read: 0.000000e+00 + write: 0.000000e+00 +w83df6400/disk-sda2/disk_time: + read: 0.000000e+00 + write: 0.000000e+00 +w83df6400/disk-sda3/disk_merged: + read: 0.000000e+00 + write: 0.000000e+00 +w83df6400/disk-sda3/disk_octets: + read: 0.000000e+00 + write: 0.000000e+00 +w83df6400/disk-sda3/disk_ops: + read: 0.000000e+00 + write: 0.000000e+00 +w83df6400/disk-sda3/disk_time: + read: 0.000000e+00 + write: 0.000000e+00 +w83df6400/disk-sda4/disk_merged: + read: 0.000000e+00 + write: 0.000000e+00 +w83df6400/disk-sda4/disk_octets: + read: 0.000000e+00 + write: 0.000000e+00 +w83df6400/disk-sda4/disk_ops: + read: 0.000000e+00 + write: 0.000000e+00 +w83df6400/disk-sda4/disk_time: + read: 0.000000e+00 + write: 0.000000e+00 +w83df6400/disk-sda5/disk_merged: + read: 0.000000e+00 + write: 0.000000e+00 +w83df6400/disk-sda5/disk_octets: + read: 0.000000e+00 + write: 0.000000e+00 +w83df6400/disk-sda5/disk_ops: + read: 0.000000e+00 + write: 0.000000e+00 +w83df6400/disk-sda5/disk_time: + read: 0.000000e+00 + write: 0.000000e+00 +w83df6400/disk-sda6/disk_merged: + read: 0.000000e+00 + write: 0.000000e+00 +w83df6400/disk-sda6/disk_octets: + read: 0.000000e+00 + write: 0.000000e+00 +w83df6400/disk-sda6/disk_ops: + read: 0.000000e+00 + write: 0.000000e+00 +w83df6400/disk-sda6/disk_time: + read: 0.000000e+00 + write: 0.000000e+00 +w83df6400/load/load: + longterm: 0.000000e+00 + midterm: 2.000000e-02 + shortterm: 3.000000e-02 +w83df6400/memory/memory-buffered: + value: 2.072453e+08 +w83df6400/memory/memory-cached: + value: 6.651863e+08 +w83df6400/memory/memory-free: + value: 6.511982e+10 +w83df6400/memory/memory-used: + value: 1.521922e+09 +w83df6400/network/if_octets: + rx: 0.000000e+00 + tx: 1.849000e+03 +w83df6400/network/if_packets: + rx: 0.000000e+00 + tx: 1.400000e+00 +w83df6400/network/queue_length: + value: 0.000000e+00 +w83df6400/network/total_values-dispatch-accepted: + value: 0.000000e+00 +w83df6400/network/total_values-dispatch-rejected: + value: 0.000000e+00 +w83df6400/network/total_values-send-accepted: + value: 3.370000e+01 +w83df6400/network/total_values-send-rejected: + value: 0.000000e+00 +w83df6400/swap/swap-cached: + value: 0.000000e+00 +w83df6400/swap/swap-free: + value: 2.147475e+09 +w83df6400/swap/swap-used: + value: 0.000000e+00 +w83df6400/swap/swap_io-in: + value: 0.000000e+00 +w83df6400/swap/swap_io-out: + value: 0.000000e+00 +w83df6400/vmem/vmpage_faults: + majflt: 0.000000e+00 + minflt: 4.700028e+00 +w83df6400/vmem/vmpage_io-memory: + in: 0.000000e+00 + out: 0.000000e+00 +w83df6400/vmem/vmpage_io-swap: + in: 0.000000e+00 + out: 0.000000e+00 +w83df6400/vmem/vmpage_number-active_anon: + value: 1.704400e+04 +w83df6400/vmem/vmpage_number-active_file: + value: 1.158240e+05 +w83df6400/vmem/vmpage_number-anon_pages: + value: 1.090600e+04 +w83df6400/vmem/vmpage_number-anon_transparent_hugepages: + value: 1.200000e+01 +w83df6400/vmem/vmpage_number-boudfe: + value: 0.000000e+00 +w83df6400/vmem/vmpage_number-dirty: + value: 0.000000e+00 +w83df6400/vmem/vmpage_number-file_pages: + value: 2.129960e+05 +w83df6400/vmem/vmpage_number-free_pages: + value: 1.589839e+07 +w83df6400/vmem/vmpage_number-inactive_anon: + value: 4.400000e+01 +w83df6400/vmem/vmpage_number-inactive_file: + value: 9.713000e+04 +w83df6400/vmem/vmpage_number-isolated_anon: + value: 0.000000e+00 +w83df6400/vmem/vmpage_number-isolated_file: + value: 0.000000e+00 +w83df6400/vmem/vmpage_number-kernel_stack: + value: 4.350000e+02 +w83df6400/vmem/vmpage_number-mapped: + value: 1.621000e+03 +w83df6400/vmem/vmpage_number-mlock: + value: 0.000000e+00 +w83df6400/vmem/vmpage_number-page_table_pages: + value: 4.680000e+02 +w83df6400/vmem/vmpage_number-shmem: + value: 4.600000e+01 +w83df6400/vmem/vmpage_number-slab_reclaimable: + value: 2.361780e+05 +w83df6400/vmem/vmpage_number-slab_unreclaimable: + value: 1.468100e+04 +w83df6400/vmem/vmpage_number-unevictable: + value: 0.000000e+00 +w83df6400/vmem/vmpage_number-unstable: + value: 0.000000e+00 +w83df6400/vmem/vmpage_number-vmscan_write: + value: 0.000000e+00 +w83df6400/vmem/vmpage_number-writeback: + value: 0.000000e+00 +w83df6400/vmem/vmpage_number-writeback_temp: + value: 0.000000e+00 +w83df6500/cpu-0/cpu-idle: + value: 8.689957e+01 +w83df6500/cpu-0/cpu-interrupt: + value: 0.000000e+00 +w83df6500/cpu-0/cpu-nice: + value: 0.000000e+00 +w83df6500/cpu-0/cpu-softirq: + value: 0.000000e+00 +w83df6500/cpu-0/cpu-steal: + value: 0.000000e+00 +w83df6500/cpu-0/cpu-system: + value: 2.299989e+00 +w83df6500/cpu-0/cpu-user: + value: 1.059998e+01 +w83df6500/cpu-0/cpu-wait: + value: 0.000000e+00 +w83df6500/cpu-1/cpu-idle: + value: 9.869419e+01 +w83df6500/cpu-1/cpu-interrupt: + value: 0.000000e+00 +w83df6500/cpu-1/cpu-nice: + value: 0.000000e+00 +w83df6500/cpu-1/cpu-softirq: + value: 0.000000e+00 +w83df6500/cpu-1/cpu-steal: + value: 0.000000e+00 +w83df6500/cpu-1/cpu-system: + value: 3.999803e-01 +w83df6500/cpu-1/cpu-user: + value: 6.999674e-01 +w83df6500/cpu-1/cpu-wait: + value: 0.000000e+00 +w83df6500/cpu-10/cpu-idle: + value: 9.999000e+01 +w83df6500/cpu-10/cpu-interrupt: + value: 0.000000e+00 +w83df6500/cpu-10/cpu-nice: + value: 0.000000e+00 +w83df6500/cpu-10/cpu-softirq: + value: 0.000000e+00 +w83df6500/cpu-10/cpu-steal: + value: 0.000000e+00 +w83df6500/cpu-10/cpu-system: + value: 9.999001e-02 +w83df6500/cpu-10/cpu-user: + value: 0.000000e+00 +w83df6500/cpu-10/cpu-wait: + value: 0.000000e+00 +w83df6500/cpu-11/cpu-idle: + value: 9.988985e+01 +w83df6500/cpu-11/cpu-interrupt: + value: 0.000000e+00 +w83df6500/cpu-11/cpu-nice: + value: 0.000000e+00 +w83df6500/cpu-11/cpu-softirq: + value: 0.000000e+00 +w83df6500/cpu-11/cpu-steal: + value: 0.000000e+00 +w83df6500/cpu-11/cpu-system: + value: 9.998982e-02 +w83df6500/cpu-11/cpu-user: + value: 0.000000e+00 +w83df6500/cpu-11/cpu-wait: + value: 0.000000e+00 +w83df6500/cpu-12/cpu-idle: + value: 9.988970e+01 +w83df6500/cpu-12/cpu-interrupt: + value: 0.000000e+00 +w83df6500/cpu-12/cpu-nice: + value: 0.000000e+00 +w83df6500/cpu-12/cpu-softirq: + value: 0.000000e+00 +w83df6500/cpu-12/cpu-steal: + value: 0.000000e+00 +w83df6500/cpu-12/cpu-system: + value: 0.000000e+00 +w83df6500/cpu-12/cpu-user: + value: 9.998982e-02 +w83df6500/cpu-12/cpu-wait: + value: 0.000000e+00 +w83df6500/cpu-13/cpu-idle: + value: 9.239045e+01 +w83df6500/cpu-13/cpu-interrupt: + value: 0.000000e+00 +w83df6500/cpu-13/cpu-nice: + value: 0.000000e+00 +w83df6500/cpu-13/cpu-softirq: + value: 0.000000e+00 +w83df6500/cpu-13/cpu-steal: + value: 0.000000e+00 +w83df6500/cpu-13/cpu-system: + value: 2.999690e+00 +w83df6500/cpu-13/cpu-user: + value: 4.399545e+00 +w83df6500/cpu-13/cpu-wait: + value: 0.000000e+00 +w83df6500/cpu-14/cpu-idle: + value: 9.639002e+01 +w83df6500/cpu-14/cpu-interrupt: + value: 0.000000e+00 +w83df6500/cpu-14/cpu-nice: + value: 0.000000e+00 +w83df6500/cpu-14/cpu-softirq: + value: 0.000000e+00 +w83df6500/cpu-14/cpu-steal: + value: 0.000000e+00 +w83df6500/cpu-14/cpu-system: + value: 2.999689e-01 +w83df6500/cpu-14/cpu-user: + value: 3.299658e+00 +w83df6500/cpu-14/cpu-wait: + value: 0.000000e+00 +w83df6500/cpu-15/cpu-idle: + value: 9.998962e+01 +w83df6500/cpu-15/cpu-interrupt: + value: 0.000000e+00 +w83df6500/cpu-15/cpu-nice: + value: 0.000000e+00 +w83df6500/cpu-15/cpu-softirq: + value: 0.000000e+00 +w83df6500/cpu-15/cpu-steal: + value: 0.000000e+00 +w83df6500/cpu-15/cpu-system: + value: 0.000000e+00 +w83df6500/cpu-15/cpu-user: + value: 0.000000e+00 +w83df6500/cpu-15/cpu-wait: + value: 0.000000e+00 +w83df6500/cpu-16/cpu-idle: + value: 9.998964e+01 +w83df6500/cpu-16/cpu-interrupt: + value: 0.000000e+00 +w83df6500/cpu-16/cpu-nice: + value: 0.000000e+00 +w83df6500/cpu-16/cpu-softirq: + value: 0.000000e+00 +w83df6500/cpu-16/cpu-steal: + value: 0.000000e+00 +w83df6500/cpu-16/cpu-system: + value: 0.000000e+00 +w83df6500/cpu-16/cpu-user: + value: 0.000000e+00 +w83df6500/cpu-16/cpu-wait: + value: 0.000000e+00 +w83df6500/cpu-17/cpu-idle: + value: 9.998943e+01 +w83df6500/cpu-17/cpu-interrupt: + value: 0.000000e+00 +w83df6500/cpu-17/cpu-nice: + value: 0.000000e+00 +w83df6500/cpu-17/cpu-softirq: + value: 0.000000e+00 +w83df6500/cpu-17/cpu-steal: + value: 0.000000e+00 +w83df6500/cpu-17/cpu-system: + value: 0.000000e+00 +w83df6500/cpu-17/cpu-user: + value: 0.000000e+00 +w83df6500/cpu-17/cpu-wait: + value: 0.000000e+00 +w83df6500/cpu-18/cpu-idle: + value: 9.978947e+01 +w83df6500/cpu-18/cpu-interrupt: + value: 0.000000e+00 +w83df6500/cpu-18/cpu-nice: + value: 0.000000e+00 +w83df6500/cpu-18/cpu-softirq: + value: 0.000000e+00 +w83df6500/cpu-18/cpu-steal: + value: 0.000000e+00 +w83df6500/cpu-18/cpu-system: + value: 0.000000e+00 +w83df6500/cpu-18/cpu-user: + value: 9.998947e-02 +w83df6500/cpu-18/cpu-wait: + value: 0.000000e+00 +w83df6500/cpu-19/cpu-idle: + value: 9.149020e+01 +w83df6500/cpu-19/cpu-interrupt: + value: 0.000000e+00 +w83df6500/cpu-19/cpu-nice: + value: 0.000000e+00 +w83df6500/cpu-19/cpu-softirq: + value: 0.000000e+00 +w83df6500/cpu-19/cpu-steal: + value: 0.000000e+00 +w83df6500/cpu-19/cpu-system: + value: 3.299646e+00 +w83df6500/cpu-19/cpu-user: + value: 5.099453e+00 +w83df6500/cpu-19/cpu-wait: + value: 0.000000e+00 +w83df6500/cpu-2/cpu-idle: + value: 9.999229e+01 +w83df6500/cpu-2/cpu-interrupt: + value: 0.000000e+00 +w83df6500/cpu-2/cpu-nice: + value: 0.000000e+00 +w83df6500/cpu-2/cpu-softirq: + value: 0.000000e+00 +w83df6500/cpu-2/cpu-steal: + value: 0.000000e+00 +w83df6500/cpu-2/cpu-system: + value: 0.000000e+00 +w83df6500/cpu-2/cpu-user: + value: 0.000000e+00 +w83df6500/cpu-2/cpu-wait: + value: 0.000000e+00 +w83df6500/cpu-20/cpu-idle: + value: 9.988926e+01 +w83df6500/cpu-20/cpu-interrupt: + value: 0.000000e+00 +w83df6500/cpu-20/cpu-nice: + value: 0.000000e+00 +w83df6500/cpu-20/cpu-softirq: + value: 0.000000e+00 +w83df6500/cpu-20/cpu-steal: + value: 0.000000e+00 +w83df6500/cpu-20/cpu-system: + value: 0.000000e+00 +w83df6500/cpu-20/cpu-user: + value: 0.000000e+00 +w83df6500/cpu-20/cpu-wait: + value: 0.000000e+00 +w83df6500/cpu-21/cpu-idle: + value: 9.888932e+01 +w83df6500/cpu-21/cpu-interrupt: + value: 0.000000e+00 +w83df6500/cpu-21/cpu-nice: + value: 0.000000e+00 +w83df6500/cpu-21/cpu-softirq: + value: 0.000000e+00 +w83df6500/cpu-21/cpu-steal: + value: 0.000000e+00 +w83df6500/cpu-21/cpu-system: + value: 9.998920e-02 +w83df6500/cpu-21/cpu-user: + value: 7.999136e-01 +w83df6500/cpu-21/cpu-wait: + value: 0.000000e+00 +w83df6500/cpu-22/cpu-idle: + value: 9.998916e+01 +w83df6500/cpu-22/cpu-interrupt: + value: 0.000000e+00 +w83df6500/cpu-22/cpu-nice: + value: 0.000000e+00 +w83df6500/cpu-22/cpu-softirq: + value: 0.000000e+00 +w83df6500/cpu-22/cpu-steal: + value: 0.000000e+00 +w83df6500/cpu-22/cpu-system: + value: 9.998916e-02 +w83df6500/cpu-22/cpu-user: + value: 0.000000e+00 +w83df6500/cpu-22/cpu-wait: + value: 0.000000e+00 +w83df6500/cpu-23/cpu-idle: + value: 9.988925e+01 +w83df6500/cpu-23/cpu-interrupt: + value: 0.000000e+00 +w83df6500/cpu-23/cpu-nice: + value: 0.000000e+00 +w83df6500/cpu-23/cpu-softirq: + value: 0.000000e+00 +w83df6500/cpu-23/cpu-steal: + value: 0.000000e+00 +w83df6500/cpu-23/cpu-system: + value: 0.000000e+00 +w83df6500/cpu-23/cpu-user: + value: 9.998923e-02 +w83df6500/cpu-23/cpu-wait: + value: 0.000000e+00 +w83df6500/cpu-3/cpu-idle: + value: 9.989136e+01 +w83df6500/cpu-3/cpu-interrupt: + value: 0.000000e+00 +w83df6500/cpu-3/cpu-nice: + value: 0.000000e+00 +w83df6500/cpu-3/cpu-softirq: + value: 0.000000e+00 +w83df6500/cpu-3/cpu-steal: + value: 0.000000e+00 +w83df6500/cpu-3/cpu-system: + value: 0.000000e+00 +w83df6500/cpu-3/cpu-user: + value: 0.000000e+00 +w83df6500/cpu-3/cpu-wait: + value: 0.000000e+00 +w83df6500/cpu-4/cpu-idle: + value: 9.989094e+01 +w83df6500/cpu-4/cpu-interrupt: + value: 0.000000e+00 +w83df6500/cpu-4/cpu-nice: + value: 0.000000e+00 +w83df6500/cpu-4/cpu-softirq: + value: 0.000000e+00 +w83df6500/cpu-4/cpu-steal: + value: 0.000000e+00 +w83df6500/cpu-4/cpu-system: + value: 0.000000e+00 +w83df6500/cpu-4/cpu-user: + value: 0.000000e+00 +w83df6500/cpu-4/cpu-wait: + value: 0.000000e+00 +w83df6500/cpu-5/cpu-idle: + value: 9.999060e+01 +w83df6500/cpu-5/cpu-interrupt: + value: 0.000000e+00 +w83df6500/cpu-5/cpu-nice: + value: 0.000000e+00 +w83df6500/cpu-5/cpu-softirq: + value: 0.000000e+00 +w83df6500/cpu-5/cpu-steal: + value: 0.000000e+00 +w83df6500/cpu-5/cpu-system: + value: 0.000000e+00 +w83df6500/cpu-5/cpu-user: + value: 0.000000e+00 +w83df6500/cpu-5/cpu-wait: + value: 0.000000e+00 +w83df6500/cpu-6/cpu-idle: + value: 9.959022e+01 +w83df6500/cpu-6/cpu-interrupt: + value: 0.000000e+00 +w83df6500/cpu-6/cpu-nice: + value: 0.000000e+00 +w83df6500/cpu-6/cpu-softirq: + value: 0.000000e+00 +w83df6500/cpu-6/cpu-steal: + value: 0.000000e+00 +w83df6500/cpu-6/cpu-system: + value: 9.999033e-02 +w83df6500/cpu-6/cpu-user: + value: 2.999711e-01 +w83df6500/cpu-6/cpu-wait: + value: 0.000000e+00 +w83df6500/cpu-7/cpu-idle: + value: 9.809048e+01 +w83df6500/cpu-7/cpu-interrupt: + value: 0.000000e+00 +w83df6500/cpu-7/cpu-nice: + value: 0.000000e+00 +w83df6500/cpu-7/cpu-softirq: + value: 0.000000e+00 +w83df6500/cpu-7/cpu-steal: + value: 0.000000e+00 +w83df6500/cpu-7/cpu-system: + value: 4.999515e-01 +w83df6500/cpu-7/cpu-user: + value: 1.299874e+00 +w83df6500/cpu-7/cpu-wait: + value: 0.000000e+00 +w83df6500/cpu-8/cpu-idle: + value: 9.999017e+01 +w83df6500/cpu-8/cpu-interrupt: + value: 0.000000e+00 +w83df6500/cpu-8/cpu-nice: + value: 0.000000e+00 +w83df6500/cpu-8/cpu-softirq: + value: 0.000000e+00 +w83df6500/cpu-8/cpu-steal: + value: 0.000000e+00 +w83df6500/cpu-8/cpu-system: + value: 0.000000e+00 +w83df6500/cpu-8/cpu-user: + value: 0.000000e+00 +w83df6500/cpu-8/cpu-wait: + value: 0.000000e+00 +w83df6500/cpu-9/cpu-idle: + value: 9.989011e+01 +w83df6500/cpu-9/cpu-interrupt: + value: 0.000000e+00 +w83df6500/cpu-9/cpu-nice: + value: 0.000000e+00 +w83df6500/cpu-9/cpu-softirq: + value: 0.000000e+00 +w83df6500/cpu-9/cpu-steal: + value: 0.000000e+00 +w83df6500/cpu-9/cpu-system: + value: 0.000000e+00 +w83df6500/cpu-9/cpu-user: + value: 0.000000e+00 +w83df6500/cpu-9/cpu-wait: + value: 0.000000e+00 +w83df6500/df-boot/df_complex-free: + value: 4.793876e+08 +w83df6500/df-boot/df_complex-reserved: + value: 2.684109e+07 +w83df6500/df-boot/df_complex-used: + value: 2.219622e+07 +w83df6500/df-boot/df_inodes-free: + value: 3.273000e+04 +w83df6500/df-boot/df_inodes-reserved: + value: 0.000000e+00 +w83df6500/df-boot/df_inodes-used: + value: 3.800000e+01 +w83df6500/df-boot/percent_bytes-free: + value: 9.072010e+01 +w83df6500/df-boot/percent_bytes-reserved: + value: 5.079451e+00 +w83df6500/df-boot/percent_bytes-used: + value: 4.200449e+00 +w83df6500/df-boot/percent_inodes-free: + value: 9.988403e+01 +w83df6500/df-boot/percent_inodes-reserved: + value: 0.000000e+00 +w83df6500/df-boot/percent_inodes-used: + value: 1.159668e-01 +w83df6500/df-data1/df_complex-free: + value: 2.574625e+11 +w83df6500/df-data1/df_complex-reserved: + value: 1.378982e+10 +w83df6500/df-data1/df_complex-used: + value: 2.165883e+08 +w83df6500/df-data1/df_inodes-free: + value: 1.683452e+07 +w83df6500/df-data1/df_inodes-reserved: + value: 0.000000e+00 +w83df6500/df-data1/df_inodes-used: + value: 4.300000e+01 +w83df6500/df-data1/percent_bytes-free: + value: 9.484052e+01 +w83df6500/df-data1/percent_bytes-reserved: + value: 5.079707e+00 +w83df6500/df-data1/percent_bytes-used: + value: 7.978383e-02 +w83df6500/df-data1/percent_inodes-free: + value: 9.999974e+01 +w83df6500/df-data1/percent_inodes-reserved: + value: 0.000000e+00 +w83df6500/df-data1/percent_inodes-used: + value: 2.554269e-04 +w83df6500/df-dev-shm/df_complex-free: + value: 3.375709e+10 +w83df6500/df-dev-shm/df_complex-reserved: + value: 0.000000e+00 +w83df6500/df-dev-shm/df_complex-used: + value: 0.000000e+00 +w83df6500/df-dev-shm/df_inodes-free: + value: 8.241475e+06 +w83df6500/df-dev-shm/df_inodes-reserved: + value: 0.000000e+00 +w83df6500/df-dev-shm/df_inodes-used: + value: 1.000000e+00 +w83df6500/df-dev-shm/percent_bytes-free: + value: 1.000000e+02 +w83df6500/df-dev-shm/percent_bytes-reserved: + value: 0.000000e+00 +w83df6500/df-dev-shm/percent_bytes-used: + value: 0.000000e+00 +w83df6500/df-dev-shm/percent_inodes-free: + value: 9.999998e+01 +w83df6500/df-dev-shm/percent_inodes-reserved: + value: 0.000000e+00 +w83df6500/df-dev-shm/percent_inodes-used: + value: 1.213375e-05 +w83df6500/df-root/df_complex-free: + value: 1.055831e+10 +w83df6500/df-root/df_complex-reserved: + value: 6.442435e+08 +w83df6500/df-root/df_complex-used: + value: 1.480151e+09 +w83df6500/df-root/df_inodes-free: + value: 7.465750e+05 +w83df6500/df-root/df_inodes-reserved: + value: 0.000000e+00 +w83df6500/df-root/df_inodes-used: + value: 3.985700e+04 +w83df6500/df-root/percent_bytes-free: + value: 8.324968e+01 +w83df6500/df-root/percent_bytes-reserved: + value: 5.079700e+00 +w83df6500/df-root/percent_bytes-used: + value: 1.167062e+01 +w83df6500/df-root/percent_inodes-free: + value: 9.493192e+01 +w83df6500/df-root/percent_inodes-reserved: + value: 0.000000e+00 +w83df6500/df-root/percent_inodes-used: + value: 5.068080e+00 +w83df6500/df-var/df_complex-free: + value: 7.641543e+09 +w83df6500/df-var/df_complex-reserved: + value: 4.294943e+08 +w83df6500/df-var/df_complex-used: + value: 3.840819e+08 +w83df6500/df-var/df_inodes-free: + value: 5.228880e+05 +w83df6500/df-var/df_inodes-reserved: + value: 0.000000e+00 +w83df6500/df-var/df_inodes-used: + value: 1.400000e+03 +w83df6500/df-var/percent_bytes-free: + value: 9.037771e+01 +w83df6500/df-var/percent_bytes-reserved: + value: 5.079695e+00 +w83df6500/df-var/percent_bytes-used: + value: 4.542596e+00 +w83df6500/df-var/percent_inodes-free: + value: 9.973297e+01 +w83df6500/df-var/percent_inodes-reserved: + value: 0.000000e+00 +w83df6500/df-var/percent_inodes-used: + value: 2.670288e-01 +w83df6500/disk-sda/disk_merged: + read: 0.000000e+00 + write: 7.199968e+00 +w83df6500/disk-sda/disk_octets: + read: 0.000000e+00 + write: 3.850286e+04 +w83df6500/disk-sda/disk_ops: + read: 0.000000e+00 + write: 2.200014e+00 +w83df6500/disk-sda/disk_time: + read: 0.000000e+00 + write: 4.000026e-01 +w83df6500/disk-sda1/disk_merged: + read: 0.000000e+00 + write: 0.000000e+00 +w83df6500/disk-sda1/disk_octets: + read: 0.000000e+00 + write: 0.000000e+00 +w83df6500/disk-sda1/disk_ops: + read: 0.000000e+00 + write: 0.000000e+00 +w83df6500/disk-sda1/disk_time: + read: 0.000000e+00 + write: 0.000000e+00 +w83df6500/disk-sda2/disk_merged: + read: 0.000000e+00 + write: 2.299968e+00 +w83df6500/disk-sda2/disk_octets: + read: 0.000000e+00 + write: 1.146866e+04 +w83df6500/disk-sda2/disk_ops: + read: 0.000000e+00 + write: 4.999937e-01 +w83df6500/disk-sda2/disk_time: + read: 0.000000e+00 + write: 1.999972e-01 +w83df6500/disk-sda3/disk_merged: + read: 0.000000e+00 + write: 4.899926e+00 +w83df6500/disk-sda3/disk_octets: + read: 0.000000e+00 + write: 2.703321e+04 +w83df6500/disk-sda3/disk_ops: + read: 0.000000e+00 + write: 1.699975e+00 +w83df6500/disk-sda3/disk_time: + read: 0.000000e+00 + write: 4.999926e-01 +w83df6500/disk-sda4/disk_merged: + read: 0.000000e+00 + write: 0.000000e+00 +w83df6500/disk-sda4/disk_octets: + read: 0.000000e+00 + write: 0.000000e+00 +w83df6500/disk-sda4/disk_ops: + read: 0.000000e+00 + write: 0.000000e+00 +w83df6500/disk-sda4/disk_time: + read: 0.000000e+00 + write: 0.000000e+00 +w83df6500/disk-sda5/disk_merged: + read: 0.000000e+00 + write: 0.000000e+00 +w83df6500/disk-sda5/disk_octets: + read: 0.000000e+00 + write: 0.000000e+00 +w83df6500/disk-sda5/disk_ops: + read: 0.000000e+00 + write: 0.000000e+00 +w83df6500/disk-sda5/disk_time: + read: 0.000000e+00 + write: 0.000000e+00 +w83df6500/disk-sda6/disk_merged: + read: 0.000000e+00 + write: 0.000000e+00 +w83df6500/disk-sda6/disk_octets: + read: 0.000000e+00 + write: 0.000000e+00 +w83df6500/disk-sda6/disk_ops: + read: 0.000000e+00 + write: 0.000000e+00 +w83df6500/disk-sda6/disk_time: + read: 0.000000e+00 + write: 0.000000e+00 +w83df6500/load/load: + longterm: 2.000000e-02 + midterm: 9.000000e-02 + shortterm: 1.600000e-01 +w83df6500/memory/memory-buffered: + value: 4.858675e+07 +w83df6500/memory/memory-cached: + value: 7.746028e+08 +w83df6500/memory/memory-free: + value: 6.579641e+10 +w83df6500/memory/memory-used: + value: 8.945746e+08 +w83df6500/network/if_octets: + rx: 0.000000e+00 + tx: 1.591300e+03 +w83df6500/network/if_packets: + rx: 0.000000e+00 + tx: 1.199999e+00 +w83df6500/network/queue_length: + value: 0.000000e+00 +w83df6500/network/total_values-dispatch-accepted: + value: 0.000000e+00 +w83df6500/network/total_values-dispatch-rejected: + value: 0.000000e+00 +w83df6500/network/total_values-send-accepted: + value: 3.239995e+01 +w83df6500/network/total_values-send-rejected: + value: 0.000000e+00 +w83df6500/swap/swap-cached: + value: 0.000000e+00 +w83df6500/swap/swap-free: + value: 2.147475e+09 +w83df6500/swap/swap-used: + value: 0.000000e+00 +w83df6500/swap/swap_io-in: + value: 0.000000e+00 +w83df6500/swap/swap_io-out: + value: 0.000000e+00 +w83df6500/vmem/vmpage_faults: + majflt: 0.000000e+00 + minflt: 1.747727e+04 +w83df6500/vmem/vmpage_io-memory: + in: 0.000000e+00 + out: 3.759999e+01 +w83df6500/vmem/vmpage_io-swap: + in: 0.000000e+00 + out: 0.000000e+00 +w83df6500/vmem/vmpage_number-active_anon: + value: 7.795900e+04 +w83df6500/vmem/vmpage_number-active_file: + value: 8.036800e+04 +w83df6500/vmem/vmpage_number-anon_pages: + value: 2.727800e+04 +w83df6500/vmem/vmpage_number-anon_transparent_hugepages: + value: 1.000000e+02 +w83df6500/vmem/vmpage_number-boudfe: + value: 0.000000e+00 +w83df6500/vmem/vmpage_number-dirty: + value: 3.920000e+02 +w83df6500/vmem/vmpage_number-file_pages: + value: 2.009740e+05 +w83df6500/vmem/vmpage_number-free_pages: + value: 1.606358e+07 +w83df6500/vmem/vmpage_number-inactive_anon: + value: 4.600000e+01 +w83df6500/vmem/vmpage_number-inactive_file: + value: 1.205540e+05 +w83df6500/vmem/vmpage_number-isolated_anon: + value: 0.000000e+00 +w83df6500/vmem/vmpage_number-isolated_file: + value: 0.000000e+00 +w83df6500/vmem/vmpage_number-kernel_stack: + value: 5.970000e+02 +w83df6500/vmem/vmpage_number-mapped: + value: 6.373000e+03 +w83df6500/vmem/vmpage_number-mlock: + value: 0.000000e+00 +w83df6500/vmem/vmpage_number-page_table_pages: + value: 1.091000e+03 +w83df6500/vmem/vmpage_number-shmem: + value: 4.800000e+01 +w83df6500/vmem/vmpage_number-slab_reclaimable: + value: 1.991400e+04 +w83df6500/vmem/vmpage_number-slab_unreclaimable: + value: 1.512500e+04 +w83df6500/vmem/vmpage_number-unevictable: + value: 0.000000e+00 +w83df6500/vmem/vmpage_number-unstable: + value: 0.000000e+00 +w83df6500/vmem/vmpage_number-vmscan_write: + value: 0.000000e+00 +w83df6500/vmem/vmpage_number-writeback: + value: 0.000000e+00 +w83df6500/vmem/vmpage_number-writeback_temp: + value: 0.000000e+00 +w83df6600/cpu-0/cpu-idle: + value: 9.980063e+01 +w83df6600/cpu-0/cpu-interrupt: + value: 0.000000e+00 +w83df6600/cpu-0/cpu-nice: + value: 0.000000e+00 +w83df6600/cpu-0/cpu-softirq: + value: 0.000000e+00 +w83df6600/cpu-0/cpu-steal: + value: 0.000000e+00 +w83df6600/cpu-0/cpu-system: + value: 0.000000e+00 +w83df6600/cpu-0/cpu-user: + value: 0.000000e+00 +w83df6600/cpu-0/cpu-wait: + value: 0.000000e+00 +w83df6600/cpu-1/cpu-idle: + value: 9.990608e+01 +w83df6600/cpu-1/cpu-interrupt: + value: 0.000000e+00 +w83df6600/cpu-1/cpu-nice: + value: 0.000000e+00 +w83df6600/cpu-1/cpu-softirq: + value: 0.000000e+00 +w83df6600/cpu-1/cpu-steal: + value: 0.000000e+00 +w83df6600/cpu-1/cpu-system: + value: 0.000000e+00 +w83df6600/cpu-1/cpu-user: + value: 0.000000e+00 +w83df6600/cpu-1/cpu-wait: + value: 0.000000e+00 +w83df6600/cpu-10/cpu-idle: + value: 9.991430e+01 +w83df6600/cpu-10/cpu-interrupt: + value: 0.000000e+00 +w83df6600/cpu-10/cpu-nice: + value: 0.000000e+00 +w83df6600/cpu-10/cpu-softirq: + value: 0.000000e+00 +w83df6600/cpu-10/cpu-steal: + value: 0.000000e+00 +w83df6600/cpu-10/cpu-system: + value: 0.000000e+00 +w83df6600/cpu-10/cpu-user: + value: 0.000000e+00 +w83df6600/cpu-10/cpu-wait: + value: 0.000000e+00 +w83df6600/cpu-11/cpu-idle: + value: 1.000143e+02 +w83df6600/cpu-11/cpu-interrupt: + value: 0.000000e+00 +w83df6600/cpu-11/cpu-nice: + value: 0.000000e+00 +w83df6600/cpu-11/cpu-softirq: + value: 0.000000e+00 +w83df6600/cpu-11/cpu-steal: + value: 0.000000e+00 +w83df6600/cpu-11/cpu-system: + value: 0.000000e+00 +w83df6600/cpu-11/cpu-user: + value: 0.000000e+00 +w83df6600/cpu-11/cpu-wait: + value: 0.000000e+00 +w83df6600/cpu-12/cpu-idle: + value: 1.000143e+02 +w83df6600/cpu-12/cpu-interrupt: + value: 0.000000e+00 +w83df6600/cpu-12/cpu-nice: + value: 0.000000e+00 +w83df6600/cpu-12/cpu-softirq: + value: 0.000000e+00 +w83df6600/cpu-12/cpu-steal: + value: 0.000000e+00 +w83df6600/cpu-12/cpu-system: + value: 0.000000e+00 +w83df6600/cpu-12/cpu-user: + value: 0.000000e+00 +w83df6600/cpu-12/cpu-wait: + value: 0.000000e+00 +w83df6600/cpu-13/cpu-idle: + value: 9.991410e+01 +w83df6600/cpu-13/cpu-interrupt: + value: 0.000000e+00 +w83df6600/cpu-13/cpu-nice: + value: 0.000000e+00 +w83df6600/cpu-13/cpu-softirq: + value: 0.000000e+00 +w83df6600/cpu-13/cpu-steal: + value: 0.000000e+00 +w83df6600/cpu-13/cpu-system: + value: 0.000000e+00 +w83df6600/cpu-13/cpu-user: + value: 0.000000e+00 +w83df6600/cpu-13/cpu-wait: + value: 0.000000e+00 +w83df6600/cpu-14/cpu-idle: + value: 1.000141e+02 +w83df6600/cpu-14/cpu-interrupt: + value: 0.000000e+00 +w83df6600/cpu-14/cpu-nice: + value: 0.000000e+00 +w83df6600/cpu-14/cpu-softirq: + value: 0.000000e+00 +w83df6600/cpu-14/cpu-steal: + value: 0.000000e+00 +w83df6600/cpu-14/cpu-system: + value: 0.000000e+00 +w83df6600/cpu-14/cpu-user: + value: 0.000000e+00 +w83df6600/cpu-14/cpu-wait: + value: 0.000000e+00 +w83df6600/cpu-15/cpu-idle: + value: 9.998509e+01 +w83df6600/cpu-15/cpu-interrupt: + value: 0.000000e+00 +w83df6600/cpu-15/cpu-nice: + value: 0.000000e+00 +w83df6600/cpu-15/cpu-softirq: + value: 0.000000e+00 +w83df6600/cpu-15/cpu-steal: + value: 0.000000e+00 +w83df6600/cpu-15/cpu-system: + value: 0.000000e+00 +w83df6600/cpu-15/cpu-user: + value: 0.000000e+00 +w83df6600/cpu-15/cpu-wait: + value: 0.000000e+00 +w83df6600/cpu-16/cpu-idle: + value: 9.998503e+01 +w83df6600/cpu-16/cpu-interrupt: + value: 0.000000e+00 +w83df6600/cpu-16/cpu-nice: + value: 0.000000e+00 +w83df6600/cpu-16/cpu-softirq: + value: 0.000000e+00 +w83df6600/cpu-16/cpu-steal: + value: 0.000000e+00 +w83df6600/cpu-16/cpu-system: + value: 0.000000e+00 +w83df6600/cpu-16/cpu-user: + value: 0.000000e+00 +w83df6600/cpu-16/cpu-wait: + value: 0.000000e+00 +w83df6600/cpu-17/cpu-idle: + value: 9.988509e+01 +w83df6600/cpu-17/cpu-interrupt: + value: 0.000000e+00 +w83df6600/cpu-17/cpu-nice: + value: 0.000000e+00 +w83df6600/cpu-17/cpu-softirq: + value: 0.000000e+00 +w83df6600/cpu-17/cpu-steal: + value: 0.000000e+00 +w83df6600/cpu-17/cpu-system: + value: 0.000000e+00 +w83df6600/cpu-17/cpu-user: + value: 0.000000e+00 +w83df6600/cpu-17/cpu-wait: + value: 0.000000e+00 +w83df6600/cpu-18/cpu-idle: + value: 9.988507e+01 +w83df6600/cpu-18/cpu-interrupt: + value: 0.000000e+00 +w83df6600/cpu-18/cpu-nice: + value: 0.000000e+00 +w83df6600/cpu-18/cpu-softirq: + value: 0.000000e+00 +w83df6600/cpu-18/cpu-steal: + value: 0.000000e+00 +w83df6600/cpu-18/cpu-system: + value: 0.000000e+00 +w83df6600/cpu-18/cpu-user: + value: 0.000000e+00 +w83df6600/cpu-18/cpu-wait: + value: 0.000000e+00 +w83df6600/cpu-19/cpu-idle: + value: 9.978521e+01 +w83df6600/cpu-19/cpu-interrupt: + value: 0.000000e+00 +w83df6600/cpu-19/cpu-nice: + value: 0.000000e+00 +w83df6600/cpu-19/cpu-softirq: + value: 0.000000e+00 +w83df6600/cpu-19/cpu-steal: + value: 0.000000e+00 +w83df6600/cpu-19/cpu-system: + value: 0.000000e+00 +w83df6600/cpu-19/cpu-user: + value: 0.000000e+00 +w83df6600/cpu-19/cpu-wait: + value: 0.000000e+00 +w83df6600/cpu-2/cpu-idle: + value: 9.999391e+01 +w83df6600/cpu-2/cpu-interrupt: + value: 0.000000e+00 +w83df6600/cpu-2/cpu-nice: + value: 0.000000e+00 +w83df6600/cpu-2/cpu-softirq: + value: 0.000000e+00 +w83df6600/cpu-2/cpu-steal: + value: 0.000000e+00 +w83df6600/cpu-2/cpu-system: + value: 0.000000e+00 +w83df6600/cpu-2/cpu-user: + value: 0.000000e+00 +w83df6600/cpu-2/cpu-wait: + value: 0.000000e+00 +w83df6600/cpu-20/cpu-idle: + value: 1.000140e+02 +w83df6600/cpu-20/cpu-interrupt: + value: 0.000000e+00 +w83df6600/cpu-20/cpu-nice: + value: 0.000000e+00 +w83df6600/cpu-20/cpu-softirq: + value: 0.000000e+00 +w83df6600/cpu-20/cpu-steal: + value: 0.000000e+00 +w83df6600/cpu-20/cpu-system: + value: 0.000000e+00 +w83df6600/cpu-20/cpu-user: + value: 0.000000e+00 +w83df6600/cpu-20/cpu-wait: + value: 0.000000e+00 +w83df6600/cpu-21/cpu-idle: + value: 1.000139e+02 +w83df6600/cpu-21/cpu-interrupt: + value: 0.000000e+00 +w83df6600/cpu-21/cpu-nice: + value: 0.000000e+00 +w83df6600/cpu-21/cpu-softirq: + value: 0.000000e+00 +w83df6600/cpu-21/cpu-steal: + value: 0.000000e+00 +w83df6600/cpu-21/cpu-system: + value: 0.000000e+00 +w83df6600/cpu-21/cpu-user: + value: 0.000000e+00 +w83df6600/cpu-21/cpu-wait: + value: 0.000000e+00 +w83df6600/cpu-22/cpu-idle: + value: 1.000138e+02 +w83df6600/cpu-22/cpu-interrupt: + value: 0.000000e+00 +w83df6600/cpu-22/cpu-nice: + value: 0.000000e+00 +w83df6600/cpu-22/cpu-softirq: + value: 0.000000e+00 +w83df6600/cpu-22/cpu-steal: + value: 0.000000e+00 +w83df6600/cpu-22/cpu-system: + value: 0.000000e+00 +w83df6600/cpu-22/cpu-user: + value: 0.000000e+00 +w83df6600/cpu-22/cpu-wait: + value: 0.000000e+00 +w83df6600/cpu-23/cpu-idle: + value: 1.000137e+02 +w83df6600/cpu-23/cpu-interrupt: + value: 0.000000e+00 +w83df6600/cpu-23/cpu-nice: + value: 0.000000e+00 +w83df6600/cpu-23/cpu-softirq: + value: 0.000000e+00 +w83df6600/cpu-23/cpu-steal: + value: 0.000000e+00 +w83df6600/cpu-23/cpu-system: + value: 0.000000e+00 +w83df6600/cpu-23/cpu-user: + value: 0.000000e+00 +w83df6600/cpu-23/cpu-wait: + value: 0.000000e+00 +w83df6600/cpu-3/cpu-idle: + value: 9.989001e+01 +w83df6600/cpu-3/cpu-interrupt: + value: 0.000000e+00 +w83df6600/cpu-3/cpu-nice: + value: 0.000000e+00 +w83df6600/cpu-3/cpu-softirq: + value: 0.000000e+00 +w83df6600/cpu-3/cpu-steal: + value: 0.000000e+00 +w83df6600/cpu-3/cpu-system: + value: 0.000000e+00 +w83df6600/cpu-3/cpu-user: + value: 0.000000e+00 +w83df6600/cpu-3/cpu-wait: + value: 0.000000e+00 +w83df6600/cpu-4/cpu-idle: + value: 9.998791e+01 +w83df6600/cpu-4/cpu-interrupt: + value: 0.000000e+00 +w83df6600/cpu-4/cpu-nice: + value: 0.000000e+00 +w83df6600/cpu-4/cpu-softirq: + value: 0.000000e+00 +w83df6600/cpu-4/cpu-steal: + value: 0.000000e+00 +w83df6600/cpu-4/cpu-system: + value: 9.998773e-02 +w83df6600/cpu-4/cpu-user: + value: 0.000000e+00 +w83df6600/cpu-4/cpu-wait: + value: 0.000000e+00 +w83df6600/cpu-5/cpu-idle: + value: 9.988613e+01 +w83df6600/cpu-5/cpu-interrupt: + value: 0.000000e+00 +w83df6600/cpu-5/cpu-nice: + value: 0.000000e+00 +w83df6600/cpu-5/cpu-softirq: + value: 0.000000e+00 +w83df6600/cpu-5/cpu-steal: + value: 0.000000e+00 +w83df6600/cpu-5/cpu-system: + value: 9.998665e-02 +w83df6600/cpu-5/cpu-user: + value: 0.000000e+00 +w83df6600/cpu-5/cpu-wait: + value: 0.000000e+00 +w83df6600/cpu-6/cpu-idle: + value: 9.988577e+01 +w83df6600/cpu-6/cpu-interrupt: + value: 0.000000e+00 +w83df6600/cpu-6/cpu-nice: + value: 0.000000e+00 +w83df6600/cpu-6/cpu-softirq: + value: 0.000000e+00 +w83df6600/cpu-6/cpu-steal: + value: 0.000000e+00 +w83df6600/cpu-6/cpu-system: + value: 0.000000e+00 +w83df6600/cpu-6/cpu-user: + value: 0.000000e+00 +w83df6600/cpu-6/cpu-wait: + value: 0.000000e+00 +w83df6600/cpu-7/cpu-idle: + value: 9.988529e+01 +w83df6600/cpu-7/cpu-interrupt: + value: 0.000000e+00 +w83df6600/cpu-7/cpu-nice: + value: 0.000000e+00 +w83df6600/cpu-7/cpu-softirq: + value: 0.000000e+00 +w83df6600/cpu-7/cpu-steal: + value: 0.000000e+00 +w83df6600/cpu-7/cpu-system: + value: 3.999412e-01 +w83df6600/cpu-7/cpu-user: + value: 0.000000e+00 +w83df6600/cpu-7/cpu-wait: + value: 0.000000e+00 +w83df6600/cpu-8/cpu-idle: + value: 9.998504e+01 +w83df6600/cpu-8/cpu-interrupt: + value: 0.000000e+00 +w83df6600/cpu-8/cpu-nice: + value: 0.000000e+00 +w83df6600/cpu-8/cpu-softirq: + value: 0.000000e+00 +w83df6600/cpu-8/cpu-steal: + value: 0.000000e+00 +w83df6600/cpu-8/cpu-system: + value: 0.000000e+00 +w83df6600/cpu-8/cpu-user: + value: 0.000000e+00 +w83df6600/cpu-8/cpu-wait: + value: 0.000000e+00 +w83df6600/cpu-9/cpu-idle: + value: 9.988501e+01 +w83df6600/cpu-9/cpu-interrupt: + value: 0.000000e+00 +w83df6600/cpu-9/cpu-nice: + value: 0.000000e+00 +w83df6600/cpu-9/cpu-softirq: + value: 0.000000e+00 +w83df6600/cpu-9/cpu-steal: + value: 0.000000e+00 +w83df6600/cpu-9/cpu-system: + value: 9.998501e-02 +w83df6600/cpu-9/cpu-user: + value: 0.000000e+00 +w83df6600/cpu-9/cpu-wait: + value: 0.000000e+00 +w83df6600/df-boot/df_complex-free: + value: 4.793631e+08 +w83df6600/df-boot/df_complex-reserved: + value: 2.684109e+07 +w83df6600/df-boot/df_complex-used: + value: 2.222080e+07 +w83df6600/df-boot/df_inodes-free: + value: 3.273000e+04 +w83df6600/df-boot/df_inodes-reserved: + value: 0.000000e+00 +w83df6600/df-boot/df_inodes-used: + value: 3.800000e+01 +w83df6600/df-boot/percent_bytes-free: + value: 9.071545e+01 +w83df6600/df-boot/percent_bytes-reserved: + value: 5.079451e+00 +w83df6600/df-boot/percent_bytes-used: + value: 4.205100e+00 +w83df6600/df-boot/percent_inodes-free: + value: 9.988403e+01 +w83df6600/df-boot/percent_inodes-reserved: + value: 0.000000e+00 +w83df6600/df-boot/percent_inodes-used: + value: 1.159668e-01 +w83df6600/df-data1/df_complex-free: + value: 2.574625e+11 +w83df6600/df-data1/df_complex-reserved: + value: 1.378982e+10 +w83df6600/df-data1/df_complex-used: + value: 2.165883e+08 +w83df6600/df-data1/df_inodes-free: + value: 1.683452e+07 +w83df6600/df-data1/df_inodes-reserved: + value: 0.000000e+00 +w83df6600/df-data1/df_inodes-used: + value: 4.300000e+01 +w83df6600/df-data1/percent_bytes-free: + value: 9.484052e+01 +w83df6600/df-data1/percent_bytes-reserved: + value: 5.079707e+00 +w83df6600/df-data1/percent_bytes-used: + value: 7.978383e-02 +w83df6600/df-data1/percent_inodes-free: + value: 9.999974e+01 +w83df6600/df-data1/percent_inodes-reserved: + value: 0.000000e+00 +w83df6600/df-data1/percent_inodes-used: + value: 2.554269e-04 +w83df6600/df-dev-shm/df_complex-free: + value: 3.375709e+10 +w83df6600/df-dev-shm/df_complex-reserved: + value: 0.000000e+00 +w83df6600/df-dev-shm/df_complex-used: + value: 0.000000e+00 +w83df6600/df-dev-shm/df_inodes-free: + value: 8.241475e+06 +w83df6600/df-dev-shm/df_inodes-reserved: + value: 0.000000e+00 +w83df6600/df-dev-shm/df_inodes-used: + value: 1.000000e+00 +w83df6600/df-dev-shm/percent_bytes-free: + value: 1.000000e+02 +w83df6600/df-dev-shm/percent_bytes-reserved: + value: 0.000000e+00 +w83df6600/df-dev-shm/percent_bytes-used: + value: 0.000000e+00 +w83df6600/df-dev-shm/percent_inodes-free: + value: 9.999998e+01 +w83df6600/df-dev-shm/percent_inodes-reserved: + value: 0.000000e+00 +w83df6600/df-dev-shm/percent_inodes-used: + value: 1.213375e-05 +w83df6600/df-root/df_complex-free: + value: 1.055849e+10 +w83df6600/df-root/df_complex-reserved: + value: 6.442435e+08 +w83df6600/df-root/df_complex-used: + value: 1.479975e+09 +w83df6600/df-root/df_inodes-free: + value: 7.466050e+05 +w83df6600/df-root/df_inodes-reserved: + value: 0.000000e+00 +w83df6600/df-root/df_inodes-used: + value: 3.982700e+04 +w83df6600/df-root/percent_bytes-free: + value: 8.325107e+01 +w83df6600/df-root/percent_bytes-reserved: + value: 5.079700e+00 +w83df6600/df-root/percent_bytes-used: + value: 1.166924e+01 +w83df6600/df-root/percent_inodes-free: + value: 9.493573e+01 +w83df6600/df-root/percent_inodes-reserved: + value: 0.000000e+00 +w83df6600/df-root/percent_inodes-used: + value: 5.064265e+00 +w83df6600/df-var/df_complex-free: + value: 7.642092e+09 +w83df6600/df-var/df_complex-reserved: + value: 4.294943e+08 +w83df6600/df-var/df_complex-used: + value: 3.835331e+08 +w83df6600/df-var/df_inodes-free: + value: 5.229150e+05 +w83df6600/df-var/df_inodes-reserved: + value: 0.000000e+00 +w83df6600/df-var/df_inodes-used: + value: 1.373000e+03 +w83df6600/df-var/percent_bytes-free: + value: 9.038420e+01 +w83df6600/df-var/percent_bytes-reserved: + value: 5.079695e+00 +w83df6600/df-var/percent_bytes-used: + value: 4.536105e+00 +w83df6600/df-var/percent_inodes-free: + value: 9.973812e+01 +w83df6600/df-var/percent_inodes-reserved: + value: 0.000000e+00 +w83df6600/df-var/percent_inodes-used: + value: 2.618790e-01 +w83df6600/disk-sda/disk_merged: + read: 0.000000e+00 + write: 0.000000e+00 +w83df6600/disk-sda/disk_octets: + read: 0.000000e+00 + write: 0.000000e+00 +w83df6600/disk-sda/disk_ops: + read: 0.000000e+00 + write: 0.000000e+00 +w83df6600/disk-sda/disk_time: + read: 0.000000e+00 + write: 0.000000e+00 +w83df6600/disk-sda1/disk_merged: + read: 0.000000e+00 + write: 0.000000e+00 +w83df6600/disk-sda1/disk_octets: + read: 0.000000e+00 + write: 0.000000e+00 +w83df6600/disk-sda1/disk_ops: + read: 0.000000e+00 + write: 0.000000e+00 +w83df6600/disk-sda1/disk_time: + read: 0.000000e+00 + write: 0.000000e+00 +w83df6600/disk-sda2/disk_merged: + read: 0.000000e+00 + write: 0.000000e+00 +w83df6600/disk-sda2/disk_octets: + read: 0.000000e+00 + write: 0.000000e+00 +w83df6600/disk-sda2/disk_ops: + read: 0.000000e+00 + write: 0.000000e+00 +w83df6600/disk-sda2/disk_time: + read: 0.000000e+00 + write: 0.000000e+00 +w83df6600/disk-sda3/disk_merged: + read: 0.000000e+00 + write: 0.000000e+00 +w83df6600/disk-sda3/disk_octets: + read: 0.000000e+00 + write: 0.000000e+00 +w83df6600/disk-sda3/disk_ops: + read: 0.000000e+00 + write: 0.000000e+00 +w83df6600/disk-sda3/disk_time: + read: 0.000000e+00 + write: 0.000000e+00 +w83df6600/disk-sda4/disk_merged: + read: 0.000000e+00 + write: 0.000000e+00 +w83df6600/disk-sda4/disk_octets: + read: 0.000000e+00 + write: 0.000000e+00 +w83df6600/disk-sda4/disk_ops: + read: 0.000000e+00 + write: 0.000000e+00 +w83df6600/disk-sda4/disk_time: + read: 0.000000e+00 + write: 0.000000e+00 +w83df6600/disk-sda5/disk_merged: + read: 0.000000e+00 + write: 0.000000e+00 +w83df6600/disk-sda5/disk_octets: + read: 0.000000e+00 + write: 0.000000e+00 +w83df6600/disk-sda5/disk_ops: + read: 0.000000e+00 + write: 0.000000e+00 +w83df6600/disk-sda5/disk_time: + read: 0.000000e+00 + write: 0.000000e+00 +w83df6600/disk-sda6/disk_merged: + read: 0.000000e+00 + write: 0.000000e+00 +w83df6600/disk-sda6/disk_octets: + read: 0.000000e+00 + write: 0.000000e+00 +w83df6600/disk-sda6/disk_ops: + read: 0.000000e+00 + write: 0.000000e+00 +w83df6600/disk-sda6/disk_time: + read: 0.000000e+00 + write: 0.000000e+00 +w83df6600/load/load: + longterm: 0.000000e+00 + midterm: 0.000000e+00 + shortterm: 0.000000e+00 +w83df6600/memory/memory-buffered: + value: 4.378624e+07 +w83df6600/memory/memory-cached: + value: 7.730299e+08 +w83df6600/memory/memory-free: + value: 6.607691e+10 +w83df6600/memory/memory-used: + value: 6.204498e+08 +w83df6600/network/if_octets: + rx: 0.000000e+00 + tx: 1.043100e+03 +w83df6600/network/if_packets: + rx: 0.000000e+00 + tx: 7.999960e-01 +w83df6600/network/queue_length: + value: 0.000000e+00 +w83df6600/network/total_values-dispatch-accepted: + value: 0.000000e+00 +w83df6600/network/total_values-dispatch-rejected: + value: 0.000000e+00 +w83df6600/network/total_values-send-accepted: + value: 2.019973e+01 +w83df6600/network/total_values-send-rejected: + value: 0.000000e+00 +w83df6600/swap/swap-cached: + value: 0.000000e+00 +w83df6600/swap/swap-free: + value: 2.147475e+09 +w83df6600/swap/swap-used: + value: 0.000000e+00 +w83df6600/swap/swap_io-in: + value: 0.000000e+00 +w83df6600/swap/swap_io-out: + value: 0.000000e+00 +w83df6600/vmem/vmpage_faults: + majflt: 0.000000e+00 + minflt: 8.999036e-01 +w83df6600/vmem/vmpage_io-memory: + in: 0.000000e+00 + out: 0.000000e+00 +w83df6600/vmem/vmpage_io-swap: + in: 0.000000e+00 + out: 0.000000e+00 +w83df6600/vmem/vmpage_number-active_anon: + value: 1.469200e+04 +w83df6600/vmem/vmpage_number-active_file: + value: 6.927600e+04 +w83df6600/vmem/vmpage_number-anon_pages: + value: 1.110500e+04 +w83df6600/vmem/vmpage_number-anon_transparent_hugepages: + value: 7.000000e+00 +w83df6600/vmem/vmpage_number-boudfe: + value: 0.000000e+00 +w83df6600/vmem/vmpage_number-dirty: + value: 9.000000e+00 +w83df6600/vmem/vmpage_number-file_pages: + value: 1.994180e+05 +w83df6600/vmem/vmpage_number-free_pages: + value: 1.613205e+07 +w83df6600/vmem/vmpage_number-inactive_anon: + value: 4.300000e+01 +w83df6600/vmem/vmpage_number-inactive_file: + value: 1.300980e+05 +w83df6600/vmem/vmpage_number-isolated_anon: + value: 0.000000e+00 +w83df6600/vmem/vmpage_number-isolated_file: + value: 0.000000e+00 +w83df6600/vmem/vmpage_number-kernel_stack: + value: 4.330000e+02 +w83df6600/vmem/vmpage_number-mapped: + value: 1.253000e+03 +w83df6600/vmem/vmpage_number-mlock: + value: 0.000000e+00 +w83df6600/vmem/vmpage_number-page_table_pages: + value: 4.520000e+02 +w83df6600/vmem/vmpage_number-shmem: + value: 4.600000e+01 +w83df6600/vmem/vmpage_number-slab_reclaimable: + value: 1.905300e+04 +w83df6600/vmem/vmpage_number-slab_unreclaimable: + value: 1.455200e+04 +w83df6600/vmem/vmpage_number-unevictable: + value: 0.000000e+00 +w83df6600/vmem/vmpage_number-unstable: + value: 0.000000e+00 +w83df6600/vmem/vmpage_number-vmscan_write: + value: 0.000000e+00 +w83df6600/vmem/vmpage_number-writeback: + value: 0.000000e+00 +w83df6600/vmem/vmpage_number-writeback_temp: + value: 0.000000e+00 diff --git a/bindings/perl/lib/Collectd/Plugins/OpenVZ.pm b/bindings/perl/lib/Collectd/Plugins/OpenVZ.pm index ea3cee99e1..66359da12f 100644 --- a/bindings/perl/lib/Collectd/Plugins/OpenVZ.pm +++ b/bindings/perl/lib/Collectd/Plugins/OpenVZ.pm @@ -27,162 +27,219 @@ use warnings; use Collectd qw( :all ); -my @cpu_instances = ('user', 'nice', 'system', 'idle', 'wait', 'interrupt', 'softirq', 'steal'); -my @if_instances = ('if_octets', 'if_packets', 'if_errors'); my $vzctl = '/usr/sbin/vzctl'; my $vzlist = '/usr/sbin/vzlist'; -my $last_stat = {}; +# Since OpenVZ is container based, all guests see all the host's CPUs, +# and would report the same data. So we disable CPU by default. +my $enable_interface = 1; +my $enable_cpu = 0; +my $enable_df = 1; +my $enable_load = 1; +my $enable_processes = 1; +my $enable_users = 1; -sub openvz_read -{ - my %v = (time => time(), interval => plugin_get_interval()); - my (@veids, $veid, $name, $key, $val, $i, @lines, @parts, @counters); +# We probably don't care about loopback transfer +my @ignored_interfaces = ( "lo" ); - @veids = map { s/ //g; $_; } split(/\n/, `$vzlist -Ho veid`); +sub interface_read { + my ($veid, $name) = @_; + my @rx_fields = qw(if_octets if_packets if_errors drop fifo frame compressed multicast); + my @tx_fields = qw(if_octets if_packets if_errors drop fifo frame compressed); + my %v = _build_report_hash($name); - foreach $veid (@veids) - { - ($name = `$vzlist -Ho name $veid`) =~ s/^\s*(.*?)\s*$/$1/; - $name = $veid if ($name =~ /^-$/); + my @lines = `$vzctl exec $veid cat /proc/net/dev`; - $v{'host'} = $name; + for my $line (@lines) { + # skip explanatory text + next if $line !~ /:/; - ##################################################################### - # interface + $line =~ s/^\s+|\s+$//g; - $v{'plugin'} = 'interface'; - delete $v{'plugin_instance'}; + my ($iface, %rx, %tx); - @lines = split(/\n/, `$vzctl exec $veid cat /proc/net/dev`); - foreach (@lines) - { - next if (!/:/); + # read /proc/net/dev fields + ($iface, @rx{@rx_fields}, @tx{@tx_fields}) = split /[: ]+/, $line; - @parts = split(/:/); - ($key = $parts[0]) =~ s/^\s*(.*?)\s*$/$1/; - ($val = $parts[1]) =~ s/^\s*(.*?)\s*$/$1/; - @counters = split(/ +/, $val); + # Skip this interface if it is in the ignored list + next if grep { $iface eq $_ } @ignored_interfaces; - $v{'type_instance'} = $key; - for ($key = 0; $key <= $#if_instances; ++$key) - { - $v{'type'} = $if_instances[$key]; - $v{'values'} = [ $counters[$key], $counters[$key + 8] ]; - plugin_dispatch_values(\%v); - } + for my $instance (qw(if_octets if_packets if_errors)) { + plugin_dispatch_values({ + 'plugin' => 'interface', + 'plugin_instance' => $iface, + 'type' => $instance, + 'values' => [ $rx{$instance}, $tx{$instance} ], + %v, + }); } + } +} - ##################################################################### - # cpu - - $v{'plugin'} = 'cpu'; - $v{'type'} = 'cpu'; - - $i = 0; - @lines = split(/\n/, `$vzctl exec $veid cat /proc/stat`); - foreach (@lines) - { - next if (!/^cpu[0-9]/); - - @counters = split(/ +/); - shift(@counters); - - # Remove once OpenVZ bug 1376 is resolved - if (48485 == $counters[3]) - { - $counters[3] = $last_stat->{"$veid-$i-idle"}; - $counters[4] = $last_stat->{"$veid-$i-wait"}; - } - else - { - $last_stat->{"$veid-$i-idle"} = $counters[3]; - $last_stat->{"$veid-$i-wait"} = $counters[4]; - } - - $v{'plugin_instance'} = $i++; - for ($key = 0; $key <= $#counters; ++$key) - { - $v{'type_instance'} = $cpu_instances[$key]; - $v{'values'} = [ $counters[$key] ]; - plugin_dispatch_values(\%v); - } +sub cpu_read { + my $veid = shift; + my $name = shift; + my ($key, $val, $i, @lines, @counters); + my @cpu_instances = ('user', 'nice', 'system', 'idle', 'wait', 'interrupt', 'softirq', 'steal'); + my $last_stat = {}; + my %v = _build_report_hash($name); + + $v{'plugin'} = 'cpu'; + $v{'type'} = 'cpu'; + + $i = 0; + @lines = split(/\n/, `$vzctl exec $veid cat /proc/stat`); + foreach (@lines) { + next if (!/^cpu[0-9]/); + + @counters = split(/ +/); + shift(@counters); + + # Remove once OpenVZ bug 1376 is resolved + if (48485 == $counters[3]) { + $counters[3] = $last_stat->{"$veid-$i-idle"}; + $counters[4] = $last_stat->{"$veid-$i-wait"}; + } + else { + $last_stat->{"$veid-$i-idle"} = $counters[3]; + $last_stat->{"$veid-$i-wait"} = $counters[4]; } - ##################################################################### - # df + $v{'plugin_instance'} = $i++; + for ($key = 0; $key <= $#counters; ++$key) { + $v{'type_instance'} = $cpu_instances[$key]; + $v{'values'} = [ $counters[$key] ]; + plugin_dispatch_values(\%v); + } + } +} - $v{'plugin'} = 'df'; - delete $v{'plugin_instance'}; - $v{'type'} = 'df'; +sub df_read { + my $veid = shift; + my $name = shift; + my ($key, $val, @lines, @parts); + my %v = _build_report_hash($name); - $val = join(' ', map { (split)[1] } split(/\n/, `$vzctl exec $veid cat /proc/mounts`)); - @lines = split(/\n/, `$vzctl exec $veid stat -tf $val`); - foreach (@lines) - { - @parts = split(/ /); - next if (0 == $parts[7]); + $v{'plugin'} = 'df'; + delete $v{'plugin_instance'}; + $v{'type'} = 'df'; - $val = substr($parts[0], 1); - $val = 'root' if ($val =~ /^$/); - $val =~ s#/#-#g; + $val = join(' ', map { (split)[1] } split(/\n/, `$vzctl exec $veid cat /proc/mounts`)); + @lines = split(/\n/, `$vzctl exec $veid stat -tf $val`); + foreach (@lines) { + @parts = split(/ /); + next if (0 == $parts[7]); - $v{'type_instance'} = $val; - $v{'values'} = [ $parts[5] * ($parts[6] - $parts[7]), $parts[5] * $parts[7] ]; - plugin_dispatch_values(\%v); - } + $val = substr($parts[0], 1); + $val = 'root' if ($val =~ /^$/); + $val =~ s#/#-#g; + + $v{'type_instance'} = $val; + $v{'values'} = [ $parts[5] * ($parts[6] - $parts[7]), $parts[5] * $parts[7] ]; + plugin_dispatch_values(\%v); + } +} - ##################################################################### - # load +sub load_read { + my $veid = shift; + my $name = shift; + my ($key, $val, @lines, @parts); + my %v = _build_report_hash($name); - $v{'plugin'} = 'load'; - delete $v{'plugin_instance'}; - $v{'type'} = 'load'; - delete $v{'type_instance'}; + $v{'plugin'} = 'load'; + delete $v{'plugin_instance'}; + $v{'type'} = 'load'; + delete $v{'type_instance'}; - @parts = split(/ +/, `$vzctl exec $veid cat /proc/loadavg`); - $v{'values'} = [ $parts[0], $parts[1], $parts[2] ]; + @parts = split(/ +/, `$vzctl exec $veid cat /proc/loadavg`); + $v{'values'} = [ $parts[0], $parts[1], $parts[2] ]; + plugin_dispatch_values(\%v); +} + +sub processes_read { + my $veid = shift; + my $name = shift; + my ($key, $val, @lines); + my %v = _build_report_hash($name); + + my $ps_states = { 'paging' => 0, 'blocked' => 0, 'zombies' => 0, 'stopped' => 0, + 'running' => 0, 'sleeping' => 0 }; + my $state_map = { 'R' => 'running', 'S' => 'sleeping', 'D' => 'blocked', + 'Z' => 'zombies', 'T' => 'stopped', 'W' => 'paging' }; + + $v{'plugin'} = 'processes'; + delete $v{'plugin_instance'}; + $v{'type'} = 'ps_state'; + + @lines = map { (split)[2] } split(/\n/, `$vzctl exec $veid cat '/proc/[0-9]*/stat'`); + foreach $key (@lines) { + ++$ps_states->{$state_map->{$key}}; + } + + foreach $key (keys %{$ps_states}) { + $v{'type_instance'} = $key; + $v{'values'} = [ $ps_states->{$key} ]; plugin_dispatch_values(\%v); + } +} - ##################################################################### - # processes +sub users_read { + my $veid = shift; + my $name = shift; + my ($key, $val, @lines); + my %v = _build_report_hash($name); - my $ps_states = { 'paging' => 0, 'blocked' => 0, 'zombies' => 0, 'stopped' => 0, - 'running' => 0, 'sleeping' => 0 }; - my $state_map = { 'R' => 'running', 'S' => 'sleeping', 'D' => 'blocked', - 'Z' => 'zombies', 'T' => 'stopped', 'W' => 'paging' }; + $v{'plugin'} = 'users'; + delete $v{'plugin_instance'}; + $v{'type'} = 'users'; + delete $v{'type_instance'}; - $v{'plugin'} = 'processes'; - delete $v{'plugin_instance'}; - $v{'type'} = 'ps_state'; + @lines = split(/\n/, `$vzctl exec $veid w -h`); + $v{'values'} = [ scalar(@lines) ]; + plugin_dispatch_values(\%v); +} + +sub _build_report_hash { + my $name = shift; + return (time => time(), interval => plugin_get_interval(), host => $name); +} - @lines = map { (split)[2] } split(/\n/, `$vzctl exec $veid cat '/proc/[0-9]*/stat'`); - foreach $key (@lines) - { - ++$ps_states->{$state_map->{$key}}; +sub openvz_read { + my (@veids, $veid, $name); + + @veids = map { s/ //g; $_; } split(/\n/, `$vzlist -Ho veid`); + + foreach $veid (@veids) { + ($name = `$vzlist -Ho name $veid`) =~ s/^\s*(.*?)\s*$/$1/; + ($name = `$vzlist -Ho hostname $veid`) =~ s/^\s*(.*?)\s*$/$1/ if($name =~ /^-$/); + $name = $veid if ($name =~ /^-$/); + + if($enable_interface) { + interface_read($veid, $name); } - foreach $key (keys %{$ps_states}) - { - $v{'type_instance'} = $key; - $v{'values'} = [ $ps_states->{$key} ]; - plugin_dispatch_values(\%v); + if($enable_cpu) { + cpu_read($veid, $name); } - ##################################################################### - # users + if($enable_df) { + df_read($veid, $name); + } - $v{'plugin'} = 'users'; - delete $v{'plugin_instance'}; - $v{'type'} = 'users'; - delete $v{'type_instance'}; + if($enable_load) { + load_read($veid, $name); + } - @lines = split(/\n/, `$vzctl exec $veid w -h`); - $v{'values'} = [ scalar(@lines) ]; - plugin_dispatch_values(\%v); - } + if($enable_processes) { + processes_read($veid, $name); + } - return 1; + if($enable_users) { + users_read($veid, $name); + } + + return 1; + } } plugin_register(TYPE_READ, 'OpenVZ', 'openvz_read'); diff --git a/bindings/perl/lib/Collectd/Unixsock.pm b/bindings/perl/lib/Collectd/Unixsock.pm index 199a47c5ae..28dbd57e6a 100644 --- a/bindings/perl/lib/Collectd/Unixsock.pm +++ b/bindings/perl/lib/Collectd/Unixsock.pm @@ -1,22 +1,27 @@ # -# collectd - Collectd::Unixsock +# collectd - bindings/buildperl/Collectd/Unixsock.pm # Copyright (C) 2007,2008 Florian octo Forster # -# This program is free software; you can redistribute it and/or modify it -# under the terms of the GNU General Public License as published by the -# Free Software Foundation; only version 2 of the License is applicable. +# 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: # -# 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. +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. # -# 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 +# 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. # -# Author: -# Florian octo Forster +# Authors: +# Florian Forster # package Collectd::Unixsock; @@ -28,7 +33,7 @@ collectd's unixsock plugin. =head1 SYNOPSIS - use Collectd::Unixsock (); + use Collectd::Unixsock; my $sock = Collectd::Unixsock->new ($path); @@ -51,23 +56,16 @@ programmers to interact with the daemon. use strict; use warnings; -#use constant { NOTIF_FAILURE => 1, NOTIF_WARNING => 2, NOTIF_OKAY => 4 }; - -use Carp (qw(cluck confess)); +use Carp qw(cluck confess carp croak); +use POSIX; use IO::Socket::UNIX; -use Regexp::Common (qw(number)); +use Scalar::Util qw( looks_like_number ); our $Debug = 0; -return (1); - sub _debug { - if (!$Debug) - { - return; - } - print @_; + print @_ if $Debug; } sub _create_socket @@ -84,88 +82,185 @@ sub _create_socket =head1 VALUE IDENTIFIERS -The values in the collectd are identified using an five-tuple (host, plugin, -plugin-instance, type, type-instance) where only plugin-instance and -type-instance may be NULL (or undefined). Many functions expect an -I<%identifier> hash that has at least the members B, B, and -B, possibly completed by B and B. +The values in the collectd are identified using a five-tuple (host, plugin, +plugin-instance, type, type-instance) where only plugin instance and type +instance may be undef. Many functions expect an I<%identifier> hash that has at +least the members B, B, and B, possibly completed by +B and B. Usually you can pass this hash as follows: - $obj->method (host => $host, plugin => $plugin, type => $type, %other_args); + $self->method (host => $host, plugin => $plugin, type => $type, %other_args); =cut sub _create_identifier { my $args = shift; - my $host; - my $plugin; - my $type; + my ($host, $plugin, $type); - if (!$args->{'host'} || !$args->{'plugin'} || !$args->{'type'}) + if (!$args->{host} || !$args->{plugin} || !$args->{type}) { cluck ("Need `host', `plugin' and `type'"); return; } - $host = $args->{'host'}; - $plugin = $args->{'plugin'}; - $plugin .= '-' . $args->{'plugin_instance'} if (defined ($args->{'plugin_instance'})); - $type = $args->{'type'}; - $type .= '-' . $args->{'type_instance'} if (defined ($args->{'type_instance'})); + $host = $args->{host}; + $plugin = $args->{plugin}; + $plugin .= '-' . $args->{plugin_instance} if defined $args->{plugin_instance}; + $type = $args->{type}; + $type .= '-' . $args->{type_instance} if defined $args->{type_instance}; - return ("$host/$plugin/$type"); + return "$host/$plugin/$type"; } # _create_identifier sub _parse_identifier { my $string = shift; - my $host; - my $plugin; - my $plugin_instance; - my $type; - my $type_instance; - my $ident; + my ($plugin_instance, $type_instance); - ($host, $plugin, $type) = split ('/', $string); + my ($host, $plugin, $type) = split /\//, $string; - ($plugin, $plugin_instance) = split ('-', $plugin, 2); - ($type, $type_instance) = split ('-', $type, 2); + ($plugin, $plugin_instance) = split /-/, $plugin, 2; + ($type, $type_instance) = split /-/, $type, 2; - $ident = + my $ident = { host => $host, plugin => $plugin, type => $type }; - $ident->{'plugin_instance'} = $plugin_instance if (defined ($plugin_instance)); - $ident->{'type_instance'} = $type_instance if (defined ($type_instance)); + $ident->{plugin_instance} = $plugin_instance if defined $plugin_instance; + $ident->{type_instance} = $type_instance if defined $type_instance; - return ($ident); + return $ident; } # _parse_identifier sub _escape_argument { - my $string = shift; + my $arg = shift; + + return $arg if $arg =~ /^\w+$/; + + $arg =~ s#\\#\\\\#g; + $arg =~ s#"#\\"#g; + return "\"$arg\""; +} + +# Handle socket errors. +sub _socket_error { + my ($self, $where) = @_; + + # If the peer has reset the connection, try to reconnect, + # otherwise fail. + if ($! == EPIPE) { + _debug "^^ error on $where: $!; reconnecting\n"; + $self->destroy; + $self->{sock} = _create_socket ($self->{path}) or return 1; + return; + } else { + carp ("error on $where: $!; aborting action\n"); + $self->{error} = $!; + return 1; + } +} + +# Send a command on a socket, including any required argument escaping. +# Return a single line of result. +sub _socket_command { + my ($self, $command, $args) = @_; + + my $fh = $self->{sock} or confess ('object has no filehandle'); + + if($args) { + my $identifier = _create_identifier ($args) or return; + $command .= ' ' . _escape_argument ($identifier) . "\n"; + } else { + $command .= "\n"; + } + _debug "-> $command"; + while (not $fh->print($command)) { + return if $self->_socket_error ('print'); + $fh = $self->{sock}; + } + + my $response; + while (not defined ($response = $fh->getline)) { + return if $self->_socket_error ('getline'); + $fh = $self->{sock}; + } + chomp $response; + _debug "<- $response\n"; + return $response; +} + +# Read any remaining results from a socket and pass them to +# a callback for caller-defined mangling. +sub _socket_chat +{ + my ($self, $msg, $callback, $cbdata) = @_; + my ($nresults, $ret); + my $fh = $self->{sock} or confess ('object has no filehandle'); + + ($nresults, $msg) = split / /, $msg, 2; + if ($nresults <= 0) + { + $self->{error} = $msg; + return; + } - if ($string =~ m/^\w+$/) + for (1 .. $nresults) { - return ("$string"); + my $entry; + while (not defined($entry = $fh->getline)) { + return if $self->_socket_error ('getline'); + $fh = $self->{sock}; + } + chomp $entry; + _debug "<- $entry\n"; + $callback->($entry, $cbdata); + } + return $cbdata; +} + +# Send a raw message on a socket. +# Returns true upon success and false otherwise. +sub _send_message +{ + my ($self, $msg) = @_; + + my $fh = $self->{'sock'} or confess ('object has no filehandle'); + + $msg .= "\n" unless $msg =~/\n$/; + + #1024 is default buffer size at unixsock.c us_handle_client() + warn "Collectd::Unixsock->_send_message(\$msg): message is too long!" if length($msg) > 1024; + + _debug "-> $msg"; + while (not $fh->print($msg)) { + return if $self->_socket_error ('print'); + $fh = $self->{sock}; + } + + while (not defined ($msg = <$fh>)) { + return if $self->_socket_error ('readline'); + $fh = $self->{sock}; } + chomp ($msg); + _debug "<- $msg\n"; - $string =~ s#\\#\\\\#g; - $string =~ s#"#\\"#g; - $string = "\"$string\""; + my ($status, $error) = split / /, $msg, 2; + return 1 if $status == 0; - return ($string); + $self->{error} = $error; + return; } =head1 PUBLIC METHODS =over 4 -=item I<$obj> = Collectd::Unixsock->B ([I<$path>]); +=item I<$self> = Collectd::Unixsock->B ([I<$path>]); Creates a new connection to the daemon. The optional I<$path> argument gives the path to the UNIX socket of the C and defaults to @@ -176,19 +271,18 @@ false on error. sub new { - my $pkg = shift; - my $path = @_ ? shift : '/var/run/collectd-unixsock'; + my $class = shift; + my $path = shift || '/var/run/collectd-unixsock'; my $sock = _create_socket ($path) or return; - my $obj = bless ( + return bless { path => $path, sock => $sock, error => 'No error' - }, $pkg); - return ($obj); + }, $class; } # new -=item I<$res> = I<$obj>-EB (I<%identifier>); +=item I<$res> = I<$self>-EB (I<%identifier>); Requests a value-list from the daemon. On success a hash-ref is returned with the name of each data-source as the key and the according value as, well, the @@ -198,53 +292,22 @@ value. On error false is returned. sub getval # {{{ { - my $obj = shift; + my $self = shift; my %args = @_; - - my $status; - my $fh = $obj->{'sock'} or confess ('object has no filehandle'); - my $msg; - my $identifier; - my $ret = {}; - $identifier = _create_identifier (\%args) or return; - - $msg = 'GETVAL ' . _escape_argument ($identifier) . "\n"; - _debug "-> $msg"; - print $fh $msg; - - $msg = <$fh>; - chomp ($msg); - _debug "<- $msg\n"; - - ($status, $msg) = split (' ', $msg, 2); - if ($status <= 0) - { - $obj->{'error'} = $msg; - return; - } - - for (my $i = 0; $i < $status; $i++) - { - my $entry = <$fh>; - chomp ($entry); - _debug "<- $entry\n"; - - if ($entry =~ m/^(\w+)=NaN$/) - { - $ret->{$1} = undef; - } - elsif ($entry =~ m/^(\w+)=($RE{num}{real})$/) - { - $ret->{$1} = 0.0 + $2; - } - } - - return ($ret); + my $msg = $self->_socket_command('GETVAL', \%args) or return; + $self->_socket_chat($msg, sub { + local $_ = shift; + my $ret = shift; + /^(\w+)=NaN$/ and $ret->{$1} = undef, return; + /^(\w+)=(.*)$/ and looks_like_number($2) and $ret->{$1} = 0 + $2, return; + }, $ret + ); + return $ret; } # }}} sub getval -=item I<$res> = I<$obj>-EB (I<%identifier>); +=item I<$res> = I<$self>-EB (I<%identifier>); Requests a threshold from the daemon. On success a hash-ref is returned with the threshold data. On error false is returned. @@ -253,55 +316,25 @@ the threshold data. On error false is returned. sub getthreshold # {{{ { - my $obj = shift; + my $self = shift; my %args = @_; - - my $status; - my $fh = $obj->{'sock'} or confess ('object has no filehandle'); - my $msg; - my $identifier; - my $ret = {}; - $identifier = _create_identifier (\%args) or return; - - $msg = 'GETTHRESHOLD ' . _escape_argument ($identifier) . "\n"; - _debug "-> $msg"; - print $fh $msg; - - $msg = <$fh>; - chomp ($msg); - _debug "<- $msg\n"; - - ($status, $msg) = split (' ', $msg, 2); - if ($status <= 0) - { - $obj->{'error'} = $msg; - return; - } - - for (my $i = 0; $i < $status; $i++) - { - my $entry = <$fh>; - chomp ($entry); - _debug "<- $entry\n"; - - if ($entry =~ m/^([^:]+):\s*(\S.*)$/) - { - my $key = $1; - my $value = $2; - - $key =~ s/^\s+//; - $key =~ s/\s+$//; - - $ret->{$key} = $value; - } - } - - return ($ret); + my $msg = $self->_socket_command('GETTHRESHOLD', \%args) or return; + $self->_socket_chat($msg, sub { + local $_ = shift; + my $ret = shift; + my ( $key, $val ); + ( $key, $val ) = /^\s*([^:]+):\s*(.*)/ and do { + $key =~ s/\s*$//; + $ret->{$key} = $val; + }; + }, $ret + ); + return $ret; } # }}} sub getthreshold -=item I<$obj>-EB (I<%identifier>, B DataSources value - DSName "count Requests/s" + DSName "value Requests/s" RRDTitle "Apache Traffic" RRDVerticalLabel "Requests/s" RRDFormat "%5.2lf" - Color count 00d000 + Color value 00d000 Module GenericStacked @@ -246,14 +246,14 @@ GraphWidth 400 DataSources value - DSName conntrack Conntrack count + DSName value Conntrack count RRDTitle "nf_conntrack connections on {hostname}" RRDVerticalLabel "Count" RRDFormat "%4.0lf" DataSources value - DSName entropy Entropy bits + DSName value Entropy bits RRDTitle "Available entropy on {hostname}" RRDVerticalLabel "Bits" RRDFormat "%4.0lf" @@ -268,11 +268,11 @@ GraphWidth 400 DataSources value - DSName frequency Frequency + DSName value Frequency RRDTitle "Frequency ({type_instance})" RRDVerticalLabel "Hertz" RRDFormat "%4.1lfHz" - Color frequency a000a0 + Color value a000a0 DataSources value @@ -543,15 +543,15 @@ GraphWidth 400 DataSources value - DSName percent Percent + DSName value Percent RRDTitle "Percent ({type_instance})" RRDVerticalLabel "Percent" RRDFormat "%4.1lf%%" - Color percent 0000ff + Color value 0000ff DataSources value - DSName "ping Latency" + DSName "value Latency" RRDTitle "Network latency ({type_instance})" RRDVerticalLabel "Milliseconds" RRDFormat "%5.2lfms" @@ -618,6 +618,13 @@ GraphWidth 400 RRDFormat "%5.1lf%%" DSName "value Signal quality" + + DataSources value + DSName value Temp + RRDTitle "Temperature ({instance})" + RRDVerticalLabel "°Celsius" + RRDFormat "%4.1lf°C" + DataSources value RRDTitle "Signal / noise ratio ({instance})" @@ -701,11 +708,11 @@ GraphWidth 400 DataSources value - DSName users Users + DSName value Users RRDTitle "Users ({type_instance}) on {hostname}" RRDVerticalLabel "Users" RRDFormat "%.1lf" - Color users 0000f0 + Color value 0000f0 DataSources value diff --git a/contrib/collection3/lib/Collectd/Config.pm b/contrib/collection3/lib/Collectd/Config.pm index d20be3598d..a3760027df 100644 --- a/contrib/collection3/lib/Collectd/Config.pm +++ b/contrib/collection3/lib/Collectd/Config.pm @@ -44,7 +44,7 @@ return (1); =item B (I<$file>) Reads the configuration from the file located at I<$file>. Returns B when -successfull and B otherwise. +successful and B otherwise. =cut diff --git a/contrib/collection3/lib/Collectd/Graph/Common.pm b/contrib/collection3/lib/Collectd/Graph/Common.pm index cc7e141f88..31c530f466 100644 --- a/contrib/collection3/lib/Collectd/Graph/Common.pm +++ b/contrib/collection3/lib/Collectd/Graph/Common.pm @@ -487,6 +487,8 @@ sub get_files_by_ident my $ident = shift; my $all_files; my @ret = (); + my $temp; + my $hosts; my $cache_key = ident_to_string ($ident); if (defined ($Cache->{'get_files_by_ident'}{$cache_key})) @@ -496,7 +498,20 @@ sub get_files_by_ident return ($ret) } - $all_files = _get_all_files (); + if ($ident->{'hostname'}) + { + $all_files = []; + $hosts = $ident->{'hostname'}; + foreach (@$hosts) + { + $temp = get_files_for_host ($_); + push (@$all_files, @$temp); + } + } + else + { + $all_files = _get_all_files (); + } @ret = grep { _filter_ident ($ident, $_) == 0 } (@$all_files); diff --git a/contrib/collection3/lib/Collectd/Graph/Config.pm b/contrib/collection3/lib/Collectd/Graph/Config.pm index 42582a7ec8..36f8706f3f 100644 --- a/contrib/collection3/lib/Collectd/Graph/Config.pm +++ b/contrib/collection3/lib/Collectd/Graph/Config.pm @@ -43,7 +43,7 @@ return (1); =item B (I<$file>) Reads the configuration from the file located at I<$file>. Returns B when -successfull and B otherwise. +successful and B otherwise. =cut diff --git a/contrib/collection3/lib/Collectd/Graph/TypeLoader.pm b/contrib/collection3/lib/Collectd/Graph/TypeLoader.pm index 5a0b522b42..3d6f61e366 100644 --- a/contrib/collection3/lib/Collectd/Graph/TypeLoader.pm +++ b/contrib/collection3/lib/Collectd/Graph/TypeLoader.pm @@ -59,7 +59,7 @@ sub _create_object my $module = shift; my $obj; - # Surpress warnings and error messages caused by the eval. + # Suppress warnings and error messages caused by the eval. local $SIG{__WARN__} = sub { return (1); print STDERR "WARNING: " . join (', ', @_) . "\n"; }; local $SIG{__DIE__} = sub { return (1); print STDERR "FATAL: " . join (', ', @_) . "\n"; }; diff --git a/contrib/collection3/share/navigate.js b/contrib/collection3/share/navigate.js index 3bfe56ed3d..0cf1513269 100644 --- a/contrib/collection3/share/navigate.js +++ b/contrib/collection3/share/navigate.js @@ -183,12 +183,11 @@ function nav_calculate_offset_x (obj) 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) { diff --git a/contrib/collection3/share/style.css b/contrib/collection3/share/style.css index 8c12951b1c..9c3f0ed393 100644 --- a/contrib/collection3/share/style.css +++ b/contrib/collection3/share/style.css @@ -1,3 +1,12 @@ +form { + display: flex; + margin-bottom: 10px; +} + +fieldset { + margin-left: 0; +} + div.graph { } diff --git a/contrib/curl_jolokia/curl_jolokia.conf b/contrib/curl_jolokia/curl_jolokia.conf new file mode 100755 index 0000000000..44ca01887e --- /dev/null +++ b/contrib/curl_jolokia/curl_jolokia.conf @@ -0,0 +1,85 @@ +# This configuration should be taken as an example what the python scrip generates. +LoadPlugin "curl_jolokia" + + Interval 1 + + +# Adjust the location of the jolokia plugin according to your setup +# specify a username/password which has access to the values you want to aggregate + + + Host "_APPPERF_JMX" + User "webloginname" + Password "passvoid" + Post "[{\"config\":{},\"type\":\"read\",\"mbean\":\"java.lang:name=PS Scavenge,type=GarbageCollector\",\"attribute\":[\"CollectionTime\",\"CollectionCount\"]},{\"config\":{},\"type\":\"read\",\"mbean\":\"java.lang:type=Threading\",\"attribute\":[\"CurrentThreadUserTime\",\"CurrentThreadCpuTime\"]},{\"config\":{},\"type\":\"read\",\"mbean\":\"java.lang:type=Runtime\",\"attribute\":[\"Uptime\"]},{\"config\":{},\"type\":\"read\",\"mbean\":\"java.lang:type=ClassLoading\",\"attribute\":[\"LoadedClassCount\",\"TotalLoadedClassCount\"]}]" + + + MBean "java.lang:name=PS Scavenge,type=GarbageCollector" + BeanNameSpace "java_lang" + + Attribute "CollectionTime" + type "gauge" + + + Attribute "CollectionCount" + type "gauge" + + + + + MBean "java.lang:type=Runtime" + BeanNameSpace "java_lang" + + Attribute "Uptime" + type "gauge" + + + + + MBean "java.lang:type=ClassLoading" + BeanNameSpace "java_lang" + + Attribute "LoadedClassCount" + type "gauge" + + + Attribute "TotalLoadedClassCount" + type "gauge" + + + + + MBean "java.lang:type=OperatingSystem" + BeanNameSpace "java_lang" + + Attribute "SystemLoadAverage" + type "gauge" + + + Attribute "OpenFileDescriptorCount" + type "gauge" + + + Attribute "ProcessCpuTime" + type "gauge" + + + Attribute "FreePhysicalMemorySize" + type "gauge" + + + Attribute "FreeSwapSpaceSize" + type "gauge" + + + Attribute "ProcessCpuLoad" + type "gauge" + + + Attribute "SystemCpuLoad" + type "gauge" + + + + + diff --git a/contrib/curl_jolokia/jolokia_2_collectdcfg.py b/contrib/curl_jolokia/jolokia_2_collectdcfg.py new file mode 100755 index 0000000000..f8d131cccd --- /dev/null +++ b/contrib/curl_jolokia/jolokia_2_collectdcfg.py @@ -0,0 +1,671 @@ +#!/usr/bin/python + +import sys, os, json, yaml, math +import urllib + +from pyrrd.rrd import DataSource, RRA, RRD +from pyjolokia import Jolokia +from string import maketrans +from numpy import histogram + + + +config = { + 'whisper' : { + 'path': '/var/lib/graphite/whisper/collectd_APPPERF_JMX', + 'prepend': 'collectd_APPPERF_JMX/', + + 'addToURL': '?width=586&height=308&from=-6hours&', + 'header': ''' +''', + 'footer': '''''' + }, + 'Weblogic' : { + 'AdminURL' : 'http://10.50.0.0:7101', + 'JolokiaPath' : 'jolokia-war-1.2.0/', + 'Hostname' : '_APPPERF_APP', + 'User' : 'TheUser', + 'Password' : 'passvoid' + }, + 'collectd' : { + 'charblacklist' : '-!. =,#@/()[]', + 'rrd_directory' : '/var/lib/local_collectd/rrd/' + }, + 'jolokia' : { + 'namespace_whitelist' : [ + 'hip_statistics_performance' # jetm for hip statistics... + ], + 'interesting_types' : [ + "double", + "int", + "java.lang.Double", + "java.lang.Float", + "java.lang.Integer", + "java.lang.Long", + "long" +# "java.lang.Boolean":1, # we don't need bolean... +# "[B":1 # array of byte.., we can't parse this. + ], + 'uninteresting_beantypes' : [ + "type=Config", + "type=Compilation" + ], + 'forbidden_attributes' : [ + ["name=PS Eden Space,type=MemoryPool","UsageThreshold"], + ["name=PS Eden Space,type=MemoryPool","UsageThresholdCount"], + ["name=PS Survivor Space,type=MemoryPool","UsageThreshold"], + ["name=PS Survivor Space,type=MemoryPool","UsageThresholdCount"], + ["name=Code Cache,type=MemoryPool","CollectionUsageThreshold"] + ], + 'interesting_servers' : [ + "managed1" + ] + } +} + +def WriteFlatBeanList(filename, Beans): + ''' + This outputs a CSV in the same format as the perl script used to. + ''' + f=open(filename, 'w') + for Bean in Beans: + f.write (Bean+';'+';'.join(Beans[Bean])+'\n') + f.close() + +def ReadBeanCSV(filename): + ''' + This function reads a CSV file. + ''' + f=open(filename) + lines=f.readlines() + f.close() + + JolokiaRequestStruct=[] + CollectdConfigStruct=[] + MixedConfigStruct=[] + + whichline=0 + + blacklist = config['collectd']['charblacklist'] + replacestring ='_' * len(blacklist) # generate nblacklistchar _ + transtab = maketrans(blacklist, replacestring) + + for line in lines: + beanstruct={} + try: + collectd_name="" + line = line.rstrip('\n') + parts=line.partition(';') + attributes=parts[2].rsplit(';') + bean=parts[0] + + # we try to split the bean into a key value list, so we can use its parts + # to find out more about its functions: + # the parseable part starts after the first ':' + beanparts=bean.rsplit(':')[1].rsplit(',') + namespace=bean.rsplit(':')[0] + + for beancomponent in beanparts: + # we have a list of key=value strings, split them further. + beantiles=beancomponent.split('=') + beanstruct[beantiles[0].lower()] = beantiles[1] + if beanstruct.has_key('name'): + collectd_name = beanstruct['name'].translate(transtab) + else: + collectd_name = bean.rsplit(':')[1].translate(transtab) + + # we use a translation map to replace characters invalid in collectd from the Metric name: + namespace = namespace.translate(transtab) + # we implicitely generate the structure which we require for jolokia bulk requests: + # (later on the json dumper will use it) + OneJolokiaRequest = { + "type" : "read", + "config" : {}, + "mbean" : bean, + "attribute" : attributes + } + JolokiaRequestStruct.append(OneJolokiaRequest) + # we implicitely generate the structure which we require for collectd configurations + # (later on the collecd config generator will use this) + OneCollectdKey = { + "BeanName" : collectd_name, + "BeanNameSpace" : namespace, + "Type" : "gauge", + "MBean" : bean, + "Attributes" : attributes + } + CollectdConfigStruct.append(OneCollectdKey) + + theattributes={} + for attribute in attributes: + path="%s/%s-%s/gauge-%s.rrd" % ( + config['Weblogic']['Hostname'], + namespace, + collectd_name, + attribute.lower() + ) + theattributes[attribute]=path; + + # this is the structure we require to use our black/white list + OneMixedRequest = { + "mbean" : bean, + "BeanName" : collectd_name, + "BeanNameSpace" : namespace, + "Type" : "gauge", + "attribute" : theattributes + } + + MixedConfigStruct.append(OneMixedRequest) + + whichline+=1 + except: + print beanstruct + print "error parsing line %d [%s]" %(whichline, line) + raise + + return (JolokiaRequestStruct, CollectdConfigStruct, MixedConfigStruct) + +def DumpJolokiaPost(filename, JolokiaRequestStruct): + # dump awfull json without any useless blanks: + postdata=json.dumps(JolokiaRequestStruct, separators=(',',':')) + print("writing [%s]" %(filename)) + f=open(filename, 'w') + f.write(postdata) + f.close() + + collectd_jolokia_postdata=postdata.replace('"', '\\"').strip() + return collectd_jolokia_postdata + +def DumpCollectdConfig(filename, CollectdConfigStruct, collectd_jolokia_postdata): + ''' + This function outputs a collectd configuration which consists of 3 important parts: + - Where to locate jolokia (we know this since we also query it) + - the big ugly post json with the bulk requests in it + - for each bean a mapping from the json to the metric name. + (Hint: beans may contain strings which are not valid to collectd metrics) + ''' + attribute_format = '''\ + + Attribute "%s" + type "%s" + +''' + bean_format ='''\ + + MBean "%s" + BeanNameSpace "%s" +%s + +''' + + collectdtemplate = ''' +# collectd.conf +LoadPlugin "curl_jolokia" + + Interval 1 + + + + + Host "%s" + User "%s" + Password "%s" + Post "%s" +%s + + +''' + + keys="" + for BeanStruct in CollectdConfigStruct: + AttributeStr="" + for Attribute in BeanStruct["Attributes"]: + lc_attr = Attribute.lower() + AttributeStr += ( + attribute_format % ( + lc_attr, + Attribute, + BeanStruct['Type'])) + + keys += (bean_format % (BeanStruct['BeanName'], + BeanStruct['MBean'], + BeanStruct['BeanNameSpace'], + AttributeStr)) + + JolokiaURL = '%s/%s?ignoreErrors=true&canonicalNaming=false' % ( + config['Weblogic']['AdminURL'], + config['Weblogic']['JolokiaPath'] + ) + print("writing [%s]" %(filename)) + f=open(filename, 'w') + f.write( collectdtemplate % ( + JolokiaURL, + config['Weblogic']['Hostname'], + config['Weblogic']['User'], + config['Weblogic']['Password'], + collectd_jolokia_postdata, + keys) ) + f.close + + +def GetRRDImportance(filename): + ''' + This is the very core of cinderella: + - we load one RRD into memory + - we build a histogram of its values + - we use a histogram to find out whether this is an active bean attribute. + ''' + if not os.path.isfile(filename): + print("file not found: %s\n" %filename) + return (0,0) + #print filename + myRRD = RRD(filename, mode="r") + results = myRRD.fetch()['value'] + validnums=[] + for value in results: + if not math.isnan(value[1]):# and (value[1] != 0.0): + validnums.append(value[1]) + #print len(validnums) + #print validnums + if len(validnums) > 0: + h = histogram(validnums) + #print h + count = 0 + + for counter in h[0]: + if counter > 0: + count = count + 1 + only_growing = 1 + last_val = 0 + i = 0 + if count > 2: + while only_growing and (i < len(validnums)): + only_growing = validnums[i] > last_val + last_val = validnums[i] + i+=1 + return (count, only_growing) + return (0,0) + +def AnalyzeAllRRD(filename, beans): + ''' + The cinderella job; This function spiders a tree of rrd databases + in order to find out whether its containing usefull information. + ''' + num_inspected = 0 + num_usefull = 0 + print("writing [%s]" %(filename)) + f=open(filename, 'w') + for bean in beans: + newattributes=[] + if bean['BeanNameSpace'] in config['jolokia']['namespace_whitelist']: + # User feedback: X - Whitelist item overriden. + sys.stdout.write("X") + continue + # User feedback: | - starting to process next bean + sys.stdout.write("|") + for attribute in bean['attribute']: + importance = GetRRDImportance(config['collectd']['rrd_directory'] + + bean['attribute'][attribute]) + + num_inspected += 1 + if importance[0] > 2: + num_usefull += 1 + if (importance[1] > 0): + # User feedback: ; - this one is interesting! + sys.stdout.write(";") + else: + # User feedback: : - this contains values. + sys.stdout.write(":") + newattributes.append(attribute) + else: + # User feedback: . - this is skipped from the final config. + sys.stdout.write(".") + sys.stdout.flush() + sys.stdout.write("\n") + if len(newattributes) > 0: + f.write(bean['mbean'] + ";" + ";".join(newattributes) + "\n") + f.close() + +def JolokiaQueryList(): + ''' + This function queries a jolokia for the list of all available beans. + ''' + # Enter the jolokia url + JolokiaURL = '%s/%s' % ( + config['Weblogic']['AdminURL'], + config['Weblogic']['JolokiaPath'] + ) + #print(JolokiaURL) + j4p = Jolokia(JolokiaURL) + j4p.auth(httpusername=config['Weblogic']['User'], + httppassword=config['Weblogic']['Password']) + + # Put in the type, the mbean, or other options. Check the jolokia users guide for more info + # This then will return back a python dictionary of what happend to the request + +#data = j4p.request(type = 'read', mbean='java.lang:type=Threading', attribute='ThreadCount') + data = j4p.request(type = 'list', path='') + return data + +def JolokiaParseList(data): + ''' + This function parses the jolokia list-document and applies black/whitelists. + ''' + TheValues = data['value'] + TheValueKeys = TheValues.keys() + InterestingBeans = {} + #print TheValueKeys + for BeanNamespace in TheValueKeys: + #print BeanNamespace + Beans=TheValues[BeanNamespace].keys() + #print Beans + for TheBean in Beans: + WantAttributes=[] + beanstruct={} + + beanparts=TheBean.rsplit(',') + for beancomponent in beanparts: + beantiles=beancomponent.split('=') + beanstruct[beantiles[0].lower()] = beantiles[1] + + if 'visibility' in beanstruct and (beanstruct['visibility'] != 'public'): + #print 'ignoring [%s] since its private' % TheBean + continue + if (('server' in beanstruct) and + (not beanstruct['server'] in config['jolokia']['interesting_servers'])): + continue + + if (not TheBean in config['jolokia']['uninteresting_beantypes'] and + "attr" in TheValues[BeanNamespace][TheBean]): + + OneBeanData=TheValues[BeanNamespace][TheBean]["attr"] + #print json.dumps(OneBeanData) + AllAttributes=OneBeanData.keys() + for Attribute in AllAttributes: + if OneBeanData[Attribute]['type'] in config['jolokia']['interesting_types']: + allowed = True + for check in config['jolokia']['forbidden_attributes']: + if (check[0] == TheBean) and (check[1] == Attribute): + allowed = False + if allowed: + WantAttributes.append(Attribute) + #print(Attribute) + + #print(BeanNamespace+":"+TheBean) + if len(WantAttributes) > 1: + InterestingBeans[BeanNamespace+":"+TheBean] = WantAttributes + return InterestingBeans + +def JolokiaParseList_for_desc(data): + ''' + This function parses the jolokia json tree to find the bean documentations. + ''' + TheValues = data['value'] + TheValueKeys = TheValues.keys() + InterestingBeans = {} + blacklist = config['collectd']['charblacklist'] + replacestring ='_' * len(blacklist) # generate nblacklistchar _ + transtab = maketrans(blacklist, replacestring) + for BeanNamespace in TheValueKeys: + #print BeanNamespace + Beans=TheValues[BeanNamespace].keys() + #print Beans + for TheBean in Beans: + WantAttributes={} + beanstruct={} + + beanparts=TheBean.rsplit(',') + for beancomponent in beanparts: + beantiles=beancomponent.split('=') + beanstruct[beantiles[0].lower()] = beantiles[1] + + # Skip prohibited access items + if 'visibility' in beanstruct and (beanstruct['visibility'] != 'public'): + #print 'ignoring [%s] since its private' % TheBean + continue + + # Skip uninteresting servers: + if (('server' in beanstruct) and + (not beanstruct['server'] in config['jolokia']['interesting_servers'])): + continue + + # Skip blacklist items... + if (not TheBean in config['jolokia']['uninteresting_beantypes'] and + "attr" in TheValues[BeanNamespace][TheBean]): + + OneBeanData=TheValues[BeanNamespace][TheBean]["attr"] + #print json.dumps(OneBeanData) + AllAttributes=OneBeanData.keys() + for Attribute in AllAttributes: + # skip Attributes from the Attribute-types blacklist: + if OneBeanData[Attribute]['type'] in config['jolokia']['interesting_types']: + allowed = True + for check in config['jolokia']['forbidden_attributes']: + if (check[0] == TheBean) and (check[1] == Attribute): + allowed = False + if allowed and 'desc' in OneBeanData[Attribute]: + WantAttributes[str(Attribute).lower()] = OneBeanData[Attribute]['desc'] + #print(Attribute) + + #print(BeanNamespace+":"+TheBean) + if len(WantAttributes) > 1: + beanparts=TheBean.rsplit(',') + # another place where we split the bean into its key/values: + for beancomponent in beanparts: + beantiles=beancomponent.split('=') + beanstruct[beantiles[0].lower()] = beantiles[1] + if beanstruct.has_key('name'): + s=str(beanstruct['name']) + collectd_name = s.translate(transtab) + else: + s=str(TheBean) + collectd_name = s.translate(transtab) + + # Filter the namespace for collectd disallowed characters: + s=str(BeanNamespace) + namespace = s.translate(transtab) + + if "desc" in TheValues[BeanNamespace][TheBean]: + WantAttributes["desc"] = TheValues[BeanNamespace][TheBean]["desc"] + if not namespace in InterestingBeans: + InterestingBeans[namespace] = dict() + InterestingBeans[namespace][collectd_name] = WantAttributes + return InterestingBeans + + +def PrintGraphiteURL(GaugeGroup, docu, group): + ''' + This functions generates the HTML snipet to reference a Bean whith all its attributes. + It also tries to find the documentation inside of the jolokia browse + to add information about which meaning the bean has. + all attributes of one bean are referenced. + ''' + print '
' + HaveDocu = group[0] in docu and group[1] in docu[group[0]] + if HaveDocu and ('desc' in docu[group[0]][group[1]]) and (docu[group[0]][group[1]]['desc'].find('Deprecation') >= 0): + beandoc = docu[group[0]][group[1]]['desc'] + parts=beandoc.split('' + parts[0] + '\n' + for Gauge in GaugeGroup: + # Each bean can have a set of attributes, which we want to visualise in one graph. + print ''+Gauge+'
' + # try to look up the documentation: + if HaveDocu: + gauges=Gauge.split('-') + TheGauge = gauges[len(gauges)-1] + if TheGauge in docu[group[0]][group[1]]: + print '
' + docu[group[0]][group[1]][TheGauge] + '
' + print '
\n' + #else: + #print 'x'*100 + #print docu[group[0]][group[1]].keys() + URL='/render/' + config['whisper']['addToURL'] + # now the image url to graphites render engine: + for Gauge in GaugeGroup: + # One Gauge equals a Bean Attribute: + graphmetric=Gauge + # if the attribute is a counter usually derivative delivers better graphs: + if Gauge.find('count') >= 0: + graphmetric='derivative('+Gauge+')' + URL += '&' + URL += urllib.urlencode({'target':graphmetric}) + print '\n' % URL + +def PrintHTML(dbfiles, basedirectory, prepend): + jolokia_json_list = JolokiaParseList_for_desc(JolokiaQueryList()) +# print json.dumps(jolokia_json_list) +# return + print config['whisper']['header'] + # we iterate over the carbon-cache database + for directory in dbfiles.keys(): + group = dbfiles[directory] + GrapName = directory.split('/') + + GrapName=GrapName[len(GrapName)-1] + GaugeGroup=[] + beanparts = GrapName.split('-') + if group: + for gauge in group: + # from the gauge name we try to generate its URL in the graphite tree: + BaseName = prepend + gauge.replace(basedirectory, '') + GaugeGroup.append(BaseName.rstrip('.wsp').replace('/','.')) + # We have a set of Attributes, generate one graph: + PrintGraphiteURL(GaugeGroup, jolokia_json_list, beanparts) + print config['whisper']['footer'] + + +def BrowseDirectoryStructure(directory): + ''' + We will spider a carbon-cache database structure and return the tree. + ''' + MyDirectory=dict() + TheseFiles=list() + for subdir, dirs, files in os.walk(directory): + for TheFile in files: + TheseFiles.append(directory+'/'+TheFile) + #.rstrip('.wsp') + for SubDirectory in dirs: + subdir = directory+'/'+SubDirectory + MyDirectory.update(BrowseDirectoryStructure(subdir)) + MyDirectory[directory] = TheseFiles + return MyDirectory + + +def usage( program): + usage = ''' + Average usage pattern: + ./%s query_list test /tmp/ + cut'n'paste the config into .jolokiaclient.yaml, edit enter password etc. + this time it wrote /tmp/test.txt which contains one Bean per line, + followed by a ; separated list of Attributes with valuable information. + + ./%s generate test /tmp/ + generates /tmp/generated_test.conf to be used with collectd for a test run. + put this into the site.d directory of a collectd configured to output rrds. + run collectd, run your testcases. + + ./%s.py analyse_rrd generated_test /tmp/ + will now spider all rrd files, analyse whether valuable data is inside, + and output /tmp/generated_test_reduced.txt + which only contains the valuable beans & attributes. + now generate the final collectd config to use with graphite: + + ./%s.py analyse_whisper + - will first do a jolokia list query + - will then spider a carbon cache controlled tree of whisper db files + - will output an index.html file with image references to all possible graphs + to be generated from beans + + ./%s.py generate generated_test_reduced /tmp/ + which will give you /tmp/generated_test_reduced.conf for your production collectd. + ''' % (program,program,program,program) + print( usage) + exit(0) + +if __name__=='__main__': + + + + # load our config or dump a sample. + if len(sys.argv) < 3: + print '''need at least 3 arguments: +action [generate|analyse_rrd|query_list] +Basefilename +directory +''' + usage() + exit(1) + try: + cfgfile = open('.jolokiaclient.yaml', 'r') + except: + print '\nno config ".jolokiaclient.yaml" found. Printing sample config and exit.\n\n' + print (yaml.safe_dump(config, default_flow_style=False)) + + exit(1) + + confstr = cfgfile.read() + cfgfile.close() + config = yaml.safe_load(confstr) + + basename=sys.argv[2] + + directory='.' + directory=sys.argv[3] + + FlatBeanListFile="%s/%s.txt" %(directory, basename) + collectd_outputname="%s/generated_%s.conf" %(directory, basename) + outputpostdata="%s/post_%s.json" %(directory, basename) + outputpersistance="%s/%s.json" %(directory, basename) + outputreduced="%s/%s_reduced.txt" %(directory, basename) + + # First step : get the list of all JMX beans + if (sys.argv[1] == 'query_list'): + # Jolokia gives us a list of all JMX available: + jolokia_json_list = JolokiaQueryList() + # we need to parse it, and evaluate the ones which contain valueable information + # - we will filter out values which don't contain numbers + # - we will filter out configuration values + # - we will filter out the blacklist we have. + FlatBeanList = JolokiaParseList(jolokia_json_list) + WriteFlatBeanList(FlatBeanListFile, FlatBeanList) + # we will output a list of JMX in the CSV-syntax of the perl script: + # ;metric1;metric2;... + # this file will be used for subsequent operations. + elif sys.argv[1] == 'generate': + # this step generates the jolokia bulk request from the CSV above. + # First read the CSV from disk: + (JolokiaRequestStruct, + CollectdConfigStruct, + MixedConfigStruct) = ReadBeanCSV(FlatBeanListFile) + + # now we know the metrics, we generate the Jolokia bulk request: + collectd_jolokia_postdata = DumpJolokiaPost(outputpostdata, + JolokiaRequestStruct) + + # collectd needs the Jolokia-post data, plus the mapping from Bean->grahpite metric: + DumpCollectdConfig(collectd_outputname, + CollectdConfigStruct, + collectd_jolokia_postdata) + + # We also output the json post data to disk, just in case you want to test it with cURL or such: + print("writing [%s]" %(outputpersistance)) + f = open(outputpersistance, 'w') + f.write(json.dumps(MixedConfigStruct)) + f.close() + + elif sys.argv[1] == 'analyse_rrd': + # this is cinderella. here we try to find the metrics which contain usefull values. + # first we load our CSV again: + (JolokiaRequestStruct, CollectdConfigStruct, MixedConfigStruct) = ReadBeanCSV(FlatBeanListFile) + # then we filter them according to our whitelist and mathematical analysis: + AnalyzeAllRRD(outputreduced, MixedConfigStruct) + elif sys.argv[1] == 'analyse_whisper': + # in this step we generate an index.html to referenece all metrics so we can see all results + # in one browser window without clicking together the graphs in the graphite webinterface. + # the index.html is intendet to be put into the graphite web service. + # we also use jolokia to get the text information about which information is contained in the + # jmx counters. + dbfiles = BrowseDirectoryStructure(config['whisper']['path']) + dbfiles[config['whisper']['path']] = None + # this outputs the html: + PrintHTML(dbfiles, config['whisper']['path'] + '/', config['whisper']['prepend']) diff --git a/contrib/curl_json/php-fpm.conf b/contrib/curl_json/php-fpm.conf new file mode 100644 index 0000000000..34b8b67d0f --- /dev/null +++ b/contrib/curl_json/php-fpm.conf @@ -0,0 +1,27 @@ +# Example configuration for PHP-FPM + + + Plugin "phpfpm" + Instance "main" + + Type "total_requests" + Instance "accepted" + + + Type "total_requests" + Instance "slow" + + + Type "queue_length" + Instance "listen" + + + Type "vs_processes" + Instance "active" + + + Type "vs_processes" + Instance "total" + + + diff --git a/contrib/docker/50docker-apt-conf b/contrib/docker/50docker-apt-conf new file mode 100644 index 0000000000..43b0ec95f5 --- /dev/null +++ b/contrib/docker/50docker-apt-conf @@ -0,0 +1,4 @@ +APT::Install-Recommends "1"; +APT::Install-Suggests "1"; +APT::Get::Assume-Yes "1"; +APT::Get::AutomaticRemove "1"; diff --git a/contrib/docker/Dockerfile b/contrib/docker/Dockerfile new file mode 100644 index 0000000000..fcb46b1396 --- /dev/null +++ b/contrib/docker/Dockerfile @@ -0,0 +1,25 @@ +FROM debian:stable-slim + +ENV DEBIAN_FRONTEND noninteractive +COPY 50docker-apt-conf /etc/apt/apt.conf.d/ + +COPY rootfs_prefix/ /usr/src/rootfs_prefix/ + +RUN apt-get update \ + && apt-get upgrade \ + && apt-get install \ + collectd-core \ + collectd-utils \ + build-essential \ + && make -C /usr/src/rootfs_prefix/ \ + && apt-get --purge remove build-essential \ + && apt-get clean \ + && rm -rf /var/lib/apt/lists/* + +COPY collectd.conf /etc/collectd/collectd.conf +COPY collectd.conf.d /etc/collectd/collectd.conf.d + +ENV LD_PRELOAD /usr/src/rootfs_prefix/rootfs_prefix.so + +ENTRYPOINT ["/usr/sbin/collectd"] +CMD ["-f"] diff --git a/contrib/docker/collectd.conf b/contrib/docker/collectd.conf new file mode 100644 index 0000000000..bbcd0791bb --- /dev/null +++ b/contrib/docker/collectd.conf @@ -0,0 +1,16 @@ +LoadPlugin logfile + + LogLevel "info" + File STDOUT + Timestamp true + PrintSeverity true + + +LoadPlugin unixsock + + SocketGroup "nogroup" + + + + Filter "*.conf" + diff --git a/contrib/docker/collectd.conf.d/sample.conf b/contrib/docker/collectd.conf.d/sample.conf new file mode 100644 index 0000000000..cbd7ce1511 --- /dev/null +++ b/contrib/docker/collectd.conf.d/sample.conf @@ -0,0 +1,4 @@ +LoadPlugin cpu +LoadPlugin memory +LoadPlugin disk +LoadPlugin df diff --git a/contrib/docker/rootfs_prefix/.gitignore b/contrib/docker/rootfs_prefix/.gitignore new file mode 100644 index 0000000000..c95ccf81be --- /dev/null +++ b/contrib/docker/rootfs_prefix/.gitignore @@ -0,0 +1 @@ +rootprefix.so diff --git a/contrib/docker/rootfs_prefix/Makefile b/contrib/docker/rootfs_prefix/Makefile new file mode 100644 index 0000000000..f26bebd03d --- /dev/null +++ b/contrib/docker/rootfs_prefix/Makefile @@ -0,0 +1,2 @@ +rootfs_prefix.so: rootfs_prefix.c + $(CC) -Wall -Werror -fPIC -shared -o rootfs_prefix.so rootfs_prefix.c -ldl diff --git a/contrib/docker/rootfs_prefix/rootfs_prefix.c b/contrib/docker/rootfs_prefix/rootfs_prefix.c new file mode 100644 index 0000000000..fdacf74348 --- /dev/null +++ b/contrib/docker/rootfs_prefix/rootfs_prefix.c @@ -0,0 +1,88 @@ +/** + * collectd - contrib/docker/rootfs_prefix/rootfs_prefix.c + * Copyright (C) 2016-2018 Marc Fournier + * Copyright (C) 2016-2018 Ruben Kerkhof + * + * MIT License: + * + * 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: + * Marc Fournier + * Ruben Kerkhof + **/ + +#define _GNU_SOURCE + +#include +#include +#include +#include +#include +#include + +#define PREFIX "/rootfs" +#define BUFSIZE 256 + +const char *add_prefix(const char *orig, char *prefixed) { + if ((strncmp(orig, "/proc", strlen("/proc")) != 0) && + (strncmp(orig, "/sys", strlen("/sys")) != 0)) + return orig; + + int status = snprintf(prefixed, BUFSIZE, "%s%s", PREFIX, orig); + if (status < 1) { + error(status, errno, "adding '%s' prefix to file path failed: '%s' -> '%s'", + PREFIX, orig, prefixed); + return orig; + } else if ((unsigned int)status >= BUFSIZE) { + error(status, ENAMETOOLONG, + "'%s' got truncated when adding '%s' prefix: '%s'", orig, PREFIX, + prefixed); + return orig; + } else { + return (const char *)prefixed; + } +} + +FILE *fopen(const char *path, const char *mode) { + char filename[BUFSIZE] = "\0"; + + FILE *(*original_fopen)(const char *, const char *); + original_fopen = dlsym(RTLD_NEXT, "fopen"); + + return (*original_fopen)(add_prefix(path, filename), mode); +} + +DIR *opendir(const char *name) { + char filename[BUFSIZE] = "\0"; + + DIR *(*original_opendir)(const char *); + original_opendir = dlsym(RTLD_NEXT, "opendir"); + + return (*original_opendir)(add_prefix(name, filename)); +} + +int *open(const char *pathname, int flags) { + char filename[BUFSIZE] = "\0"; + + int *(*original_open)(const char *, int); + original_open = dlsym(RTLD_NEXT, "open"); + + return (*original_open)(add_prefix(pathname, filename), flags); +} diff --git a/contrib/examples/myplugin.c b/contrib/examples/myplugin.c index f68cc1ac85..d95f10b55c 100644 --- a/contrib/examples/myplugin.c +++ b/contrib/examples/myplugin.c @@ -18,20 +18,20 @@ * is optional */ -#if ! HAVE_CONFIG_H +#if !HAVE_CONFIG_H #include #include #ifndef __USE_ISOC99 /* required for NAN */ -# define DISABLE_ISOC99 1 -# define __USE_ISOC99 1 +#define DISABLE_ISOC99 1 +#define __USE_ISOC99 1 #endif /* !defined(__USE_ISOC99) */ #include #if DISABLE_ISOC99 -# undef DISABLE_ISOC99 -# undef __USE_ISOC99 +#undef DISABLE_ISOC99 +#undef __USE_ISOC99 #endif /* DISABLE_ISOC99 */ #include @@ -39,6 +39,7 @@ #endif /* ! HAVE_CONFIG */ #include + #include #include @@ -49,10 +50,7 @@ * - minimum allowed value * - maximum allowed value */ -static data_source_t dsrc[1] = -{ - { "my_ds", DS_TYPE_GAUGE, 0, NAN } -}; +static data_source_t dsrc[1] = {{"my_ds", DS_TYPE_GAUGE, 0, NAN}}; /* * data set definition: @@ -66,157 +64,163 @@ static data_source_t dsrc[1] = * It is strongly recommended to use one of the types and data-sets * pre-defined in the types.db file. */ -static data_set_t ds = -{ - "myplugin", STATIC_ARRAY_SIZE (dsrc), dsrc -}; +static data_set_t ds = {"myplugin", STATIC_ARRAY_SIZE(dsrc), dsrc}; /* * This function is called once upon startup to initialize the plugin. */ -static int my_init (void) -{ - /* open sockets, initialize data structures, ... */ +static int my_init(void) { + /* open sockets, initialize data structures, ... */ - /* A return value != 0 indicates an error and causes the plugin to be - disabled. */ - return 0; + /* A return value != 0 indicates an error and causes the plugin to be + disabled. */ + return 0; } /* static int my_init (void) */ +/* + * This is a utility function used by the read callback to populate a + * value_list_t and pass it to plugin_dispatch_values. + */ +static int my_submit(gauge_t value) { + value_list_t vl = VALUE_LIST_INIT; + + /* Convert the gauge_t to a value_t and add it to the value_list_t. */ + vl.values = &(value_t){.gauge = value}; + vl.values_len = 1; + + /* Only set vl.time yourself if you update multiple metrics (i.e. you + * have multiple calls to plugin_dispatch_values()) and they need to all + * have the same timestamp. */ + /* vl.time = cdtime(); */ + + sstrncpy(vl.plugin, "myplugin", sizeof(vl.plugin)); + + /* it is strongly recommended to use a type defined in the types.db file + * instead of a custom type */ + sstrncpy(vl.type, "myplugin", sizeof(vl.type)); + /* optionally set vl.plugin_instance and vl.type_instance to reasonable + * values (default: "") */ + + /* dispatch the values to collectd which passes them on to all registered + * write functions */ + return plugin_dispatch_values(&vl); +} + /* * This function is called in regular intervalls to collect the data. */ -static int my_read (void) -{ - value_t values[1]; /* the size of this list should equal the number of - data sources */ - value_list_t vl = VALUE_LIST_INIT; - - /* do the magic to read the data */ - values[0].gauge = random (); - - vl.values = values; - vl.values_len = 1; - vl.time = time (NULL); - sstrncpy (vl.host, hostname_g, sizeof (vl.host)); - sstrncpy (vl.plugin, "myplugin", sizeof (vl.plugin)); - /* optionally set vl.plugin_instance and vl.type_instance to reasonable - * values (default: "") */ - - /* dispatch the values to collectd which passes them on to all registered - * write functions - the first argument is used to lookup the data set - * definition (it is strongly recommended to use a type defined in the - * types.db file) */ - plugin_dispatch_values ("myplugin", &vl); - - /* A return value != 0 indicates an error and the plugin will be skipped - * for an increasing amount of time. */ - return 0; +static int my_read(void) { + /* do the magic to read the data */ + gauge_t value = random(); + + if (my_submit(value) != 0) + WARNING("myplugin plugin: Dispatching a random value failed."); + + /* A return value != 0 indicates an error and the plugin will be skipped + * for an increasing amount of time. */ + return 0; } /* static int my_read (void) */ /* * This function is called after values have been dispatched to collectd. */ -static int my_write (const data_set_t *ds, const value_list_t *vl) -{ - char name[1024] = ""; - int i = 0; - - if (ds->ds_num != vl->values_len) { - plugin_log (LOG_WARNING, "DS number does not match values length"); - return -1; - } - - /* get the default base filename for the output file - depending on the - * provided values this will be something like - * /[-]/[-] */ - if (0 != format_name (name, 1024, vl->host, vl->plugin, - vl->plugin_instance, ds->type, vl->type_instance)) - return -1; - - for (i = 0; i < ds->ds_num; ++i) { - /* do the magic to output the data */ - printf ("%s (%s) at %i: ", name, - (ds->ds->type == DS_TYPE_GAUGE) ? "GAUGE" : "COUNTER", - (int)vl->time); - - if (ds->ds->type == DS_TYPE_GAUGE) - printf ("%f\n", vl->values[i].gauge); - else - printf ("%lld\n", vl->values[i].counter); - } - return 0; +static int my_write(const data_set_t *ds, const value_list_t *vl, + user_data_t *ud) { + char name[1024] = ""; + int i = 0; + + if (ds->ds_num != vl->values_len) { + plugin_log(LOG_WARNING, "DS number does not match values length"); + return -1; + } + + /* get the default base filename for the output file - depending on the + * provided values this will be something like + * /[-]/[-] */ + if (0 != format_name(name, 1024, vl->host, vl->plugin, vl->plugin_instance, + ds->type, vl->type_instance)) + return -1; + + for (i = 0; i < ds->ds_num; ++i) { + /* do the magic to output the data */ + printf("%s (%s) at %i: ", name, + (ds->ds->type == DS_TYPE_GAUGE) ? "GAUGE" : "COUNTER", + (int)vl->time); + + if (ds->ds->type == DS_TYPE_GAUGE) + printf("%f\n", vl->values[i].gauge); + else + printf("%lld\n", vl->values[i].counter); + } + return 0; } /* static int my_write (data_set_t *, value_list_t *) */ /* * This function is called when plugin_log () has been used. */ -static void my_log (int severity, const char *msg) -{ - printf ("LOG: %i - %s\n", severity, msg); - return; +static void my_log(int severity, const char *msg, user_data_t *ud) { + printf("LOG: %i - %s\n", severity, msg); + return; } /* static void my_log (int, const char *) */ /* * This function is called when plugin_dispatch_notification () has been used. */ -static int my_notify (const notification_t *notif) -{ - char time_str[32] = ""; - struct tm *tm = NULL; +static int my_notify(const notification_t *notif, user_data_t *ud) { + char time_str[32] = ""; + struct tm *tm = NULL; - int n = 0; + int n = 0; - if (NULL == (tm = localtime (¬if->time))) - time_str[0] = '\0'; + if (NULL == (tm = localtime(¬if->time))) + time_str[0] = '\0'; - n = strftime (time_str, 32, "%F %T", tm); - if (n >= 32) n = 31; - time_str[n] = '\0'; + n = strftime(time_str, 32, "%F %T", tm); + if (n >= 32) + n = 31; + time_str[n] = '\0'; - printf ("NOTIF (%s): %i - ", time_str, notif->severity); + printf("NOTIF (%s): %i - ", time_str, notif->severity); - if ('\0' != *notif->host) - printf ("%s: ", notif->host); + if ('\0' != *notif->host) + printf("%s: ", notif->host); - if ('\0' != *notif->plugin) - printf ("%s: ", notif->plugin); + if ('\0' != *notif->plugin) + printf("%s: ", notif->plugin); - if ('\0' != *notif->plugin_instance) - printf ("%s: ", notif->plugin_instance); + if ('\0' != *notif->plugin_instance) + printf("%s: ", notif->plugin_instance); - if ('\0' != *notif->type) - printf ("%s: ", notif->type); + if ('\0' != *notif->type) + printf("%s: ", notif->type); - if ('\0' != *notif->type_instance) - printf ("%s: ", notif->type_instance); + if ('\0' != *notif->type_instance) + printf("%s: ", notif->type_instance); - printf ("%s\n", notif->message); - return 0; + printf("%s\n", notif->message); + return 0; } /* static int my_notify (notification_t *) */ /* * This function is called before shutting down collectd. */ -static int my_shutdown (void) -{ - /* close sockets, free data structures, ... */ - return 0; +static int my_shutdown(void) { + /* close sockets, free data structures, ... */ + return 0; } /* static int my_shutdown (void) */ /* * This function is called after loading the plugin to register it with * collectd. */ -void module_register (void) -{ - plugin_register_log ("myplugin", my_log); - plugin_register_notification ("myplugin", my_notify); - plugin_register_data_set (&ds); - plugin_register_read ("myplugin", my_read); - plugin_register_init ("myplugin", my_init); - plugin_register_write ("myplugin", my_write); - plugin_register_shutdown ("myplugin", my_shutdown); - return; +void module_register(void) { + plugin_register_log("myplugin", my_log, /* user data */ NULL); + plugin_register_notification("myplugin", my_notify, + /* user data */ NULL); + plugin_register_data_set(&ds); + plugin_register_read("myplugin", my_read); + plugin_register_init("myplugin", my_init); + plugin_register_write("myplugin", my_write, /* user data */ NULL); + plugin_register_shutdown("myplugin", my_shutdown); + return; } /* void module_register (void) */ - diff --git a/contrib/exec-munin.px b/contrib/exec-munin.px index 3e62ce009a..5309cc6607 100755 --- a/contrib/exec-munin.px +++ b/contrib/exec-munin.px @@ -56,7 +56,7 @@ exit (0); =head1 CONFIGURATION -This script reads it's configuration from F. The +This script reads its configuration from F. The configuration is read using C which understands a Apache-like config syntax, so it's very similar to the F syntax, too. diff --git a/contrib/exec-nagios.px b/contrib/exec-nagios.px index c7f18c58c0..b9758ec937 100755 --- a/contrib/exec-nagios.px +++ b/contrib/exec-nagios.px @@ -36,7 +36,7 @@ exit (0); =head1 CONFIGURATION -This script reads it's configuration from F. The +This script reads its configuration from F. The configuration is read using C which understands a Apache-like config syntax, so it's very similar to the F syntax, too. @@ -442,7 +442,7 @@ sub execute_script close ($fh); # Save the exit status of the check in $state - $state = $?; + $state = $? >> 8; if ($state == 0) { diff --git a/contrib/fedora/collectd.spec b/contrib/fedora/collectd.spec deleted file mode 100644 index a35923c0bd..0000000000 --- a/contrib/fedora/collectd.spec +++ /dev/null @@ -1,376 +0,0 @@ -Summary: Statistics collection daemon for filling RRD files. -Name: collectd -Version: 4.2.0 -Release: 1.fc6 -Source: http://collectd.org/files/%{name}-%{version}.tar.gz -License: GPL -Group: System Environment/Daemons -BuildRoot: %{_tmppath}/%{name}-%{version}-root -BuildPrereq: lm_sensors-devel -BuildPrereq: mysql-devel -BuildPrereq: rrdtool-devel -BuildPrereq: net-snmp-devel -Requires: rrdtool -Requires: perl-Regexp-Common -Packager: Florian octo Forster -Vendor: Florian octo Forster - -%description -collectd is a small daemon written in C for performance. It reads various -system statistics and updates RRD files, creating them if neccessary. -Since the daemon doesn't need to startup every time it wants to update the -files it's very fast and easy on the system. Also, the statistics are very -fine grained since the files are updated every 10 seconds. - -%package apache -Summary: apache-plugin for collectd. -Group: System Environment/Daemons -Requires: collectd = %{version}, curl -%description apache -This plugin collectd data provided by Apache's `mod_status'. - -%package email -Summary: email-plugin for collectd. -Group: System Environment/Daemons -Requires: collectd = %{version}, spamassassin -%description email -This plugin collectd data provided by spamassassin. - -%package mysql -Summary: mysql-module for collectd. -Group: System Environment/Daemons -Requires: collectd = %{version}, mysql -%description mysql -MySQL querying plugin. This plugins provides data of issued commands, -called handlers and database traffic. - -%package sensors -Summary: libsensors-module for collectd. -Group: System Environment/Daemons -Requires: collectd = %{version}, lm_sensors -%description sensors -This plugin for collectd provides querying of sensors supported by -lm_sensors. - -%prep -rm -rf $RPM_BUILD_ROOT -%setup - -%build -./configure --prefix=%{_prefix} --sbindir=%{_sbindir} --mandir=%{_mandir} --libdir=%{_libdir} --sysconfdir=%{_sysconfdir} -make - -%install -make install DESTDIR=$RPM_BUILD_ROOT -mkdir -p $RPM_BUILD_ROOT/etc/rc.d/init.d -mkdir -p $RPM_BUILD_ROOT/var/www/cgi-bin -cp src/collectd.conf $RPM_BUILD_ROOT/etc/collectd.conf -cp contrib/fedora/init.d-collectd $RPM_BUILD_ROOT/etc/rc.d/init.d/collectd -cp contrib/collection.cgi $RPM_BUILD_ROOT/var/www/cgi-bin -cp contrib/collection.conf $RPM_BUILD_ROOT/etc/collection.conf -mkdir -p $RPM_BUILD_ROOT/var/lib/collectd - -%clean -rm -rf $RPM_BUILD_ROOT - -%post -/sbin/chkconfig --add collectd -/sbin/chkconfig collectd on - -%preun -if [ "$1" = 0 ]; then - /sbin/chkconfig collectd off - /etc/init.d/collectd stop - /sbin/chkconfig --del collectd -fi -exit 0 - -%postun -if [ "$1" -ge 1 ]; then - /etc/init.d/collectd restart -fi -exit 0 - -%files -%defattr(-,root,root) -%doc AUTHORS COPYING ChangeLog INSTALL NEWS README -%attr(0644,root,root) %config(noreplace) /etc/collectd.conf -%attr(0644,root,root) %config(noreplace) /etc/collection.conf -%attr(0755,root,root) /etc/rc.d/init.d/collectd -%attr(0755,root,root) /var/www/cgi-bin/collection.cgi -%attr(0755,root,root) %{_sbindir}/collectd -%attr(0755,root,root) %{_bindir}/collectd-nagios -%attr(0644,root,root) %{_mandir}/man1/* -%attr(0644,root,root) %{_mandir}/man5/* - -%attr(0644,root,root) /usr/lib/perl5/5.8.8/i386-linux-thread-multi/perllocal.pod -%attr(0644,root,root) /usr/lib/perl5/site_perl/5.8.8/Collectd.pm -%attr(0644,root,root) /usr/lib/perl5/site_perl/5.8.8/Collectd/Unixsock.pm -%attr(0644,root,root) /usr/lib/perl5/site_perl/5.8.8/i386-linux-thread-multi/auto/Collectd/.packlist -%attr(0644,root,root) %{_mandir}/man3/Collectd::Unixsock.3pm.gz - -%attr(0644,root,root) %{_libdir}/%{name}/apcups.so* -%attr(0644,root,root) %{_libdir}/%{name}/apcups.la - -# FIXME!!! -#%attr(0644,root,root) %{_libdir}/%{name}/apple_sensors.so* -#%attr(0644,root,root) %{_libdir}/%{name}/apple_sensors.la - -%attr(0644,root,root) %{_libdir}/%{name}/battery.so* -%attr(0644,root,root) %{_libdir}/%{name}/battery.la - -%attr(0644,root,root) %{_libdir}/%{name}/conntrack.so* -%attr(0644,root,root) %{_libdir}/%{name}/conntrack.la - -%attr(0644,root,root) %{_libdir}/%{name}/cpufreq.so* -%attr(0644,root,root) %{_libdir}/%{name}/cpufreq.la - -%attr(0644,root,root) %{_libdir}/%{name}/cpu.so* -%attr(0644,root,root) %{_libdir}/%{name}/cpu.la - -%attr(0644,root,root) %{_libdir}/%{name}/csv.so* -%attr(0644,root,root) %{_libdir}/%{name}/csv.la - -%attr(0644,root,root) %{_libdir}/%{name}/df.so* -%attr(0644,root,root) %{_libdir}/%{name}/df.la - -%attr(0644,root,root) %{_libdir}/%{name}/disk.so* -%attr(0644,root,root) %{_libdir}/%{name}/disk.la - -%attr(0644,root,root) %{_libdir}/%{name}/dns.so* -%attr(0644,root,root) %{_libdir}/%{name}/dns.la - -%attr(0644,root,root) %{_libdir}/%{name}/entropy.so* -%attr(0644,root,root) %{_libdir}/%{name}/entropy.la - -%attr(0644,root,root) %{_libdir}/%{name}/exec.so* -%attr(0644,root,root) %{_libdir}/%{name}/exec.la - -%attr(0644,root,root) %{_libdir}/%{name}/hddtemp.so* -%attr(0644,root,root) %{_libdir}/%{name}/hddtemp.la - -%attr(0644,root,root) %{_libdir}/%{name}/interface.so* -%attr(0644,root,root) %{_libdir}/%{name}/interface.la - -%attr(0644,root,root) %{_libdir}/%{name}/iptables.so* -%attr(0644,root,root) %{_libdir}/%{name}/iptables.la - -%attr(0644,root,root) %{_libdir}/%{name}/irq.so* -%attr(0644,root,root) %{_libdir}/%{name}/irq.la - -%attr(0644,root,root) %{_libdir}/%{name}/load.so* -%attr(0644,root,root) %{_libdir}/%{name}/load.la - -%attr(0644,root,root) %{_libdir}/%{name}/logfile.so* -%attr(0644,root,root) %{_libdir}/%{name}/logfile.la - -%attr(0644,root,root) %{_libdir}/%{name}/mbmon.so* -%attr(0644,root,root) %{_libdir}/%{name}/mbmon.la - -%attr(0644,root,root) %{_libdir}/%{name}/memcached.so* -%attr(0644,root,root) %{_libdir}/%{name}/memcached.la - -%attr(0644,root,root) %{_libdir}/%{name}/memory.so* -%attr(0644,root,root) %{_libdir}/%{name}/memory.la - -%attr(0644,root,root) %{_libdir}/%{name}/multimeter.so* -%attr(0644,root,root) %{_libdir}/%{name}/multimeter.la - -%attr(0644,root,root) %{_libdir}/%{name}/network.so* -%attr(0644,root,root) %{_libdir}/%{name}/network.la - -%attr(0644,root,root) %{_libdir}/%{name}/nfs.so* -%attr(0644,root,root) %{_libdir}/%{name}/nfs.la - -%attr(0644,root,root) %{_libdir}/%{name}/nginx.so* -%attr(0644,root,root) %{_libdir}/%{name}/nginx.la - -%attr(0644,root,root) %{_libdir}/%{name}/ntpd.so* -%attr(0644,root,root) %{_libdir}/%{name}/ntpd.la - -# FIXME!!! -#%attr(0644,root,root) %{_libdir}/%{name}/nut.so* -#%attr(0644,root,root) %{_libdir}/%{name}/nut.la - -%attr(0644,root,root) %{_libdir}/%{name}/perl.so* -%attr(0644,root,root) %{_libdir}/%{name}/perl.la - -%attr(0644,root,root) %{_libdir}/%{name}/ping.so* -%attr(0644,root,root) %{_libdir}/%{name}/ping.la - -%attr(0644,root,root) %{_libdir}/%{name}/processes.so* -%attr(0644,root,root) %{_libdir}/%{name}/processes.la - -%attr(0644,root,root) %{_libdir}/%{name}/rrdtool.so* -%attr(0644,root,root) %{_libdir}/%{name}/rrdtool.la - -%attr(0644,root,root) %{_libdir}/%{name}/serial.so* -%attr(0644,root,root) %{_libdir}/%{name}/serial.la - -%attr(0644,root,root) %{_libdir}/%{name}/swap.so* -%attr(0644,root,root) %{_libdir}/%{name}/swap.la - -%attr(0644,root,root) %{_libdir}/%{name}/snmp.so* -%attr(0644,root,root) %{_libdir}/%{name}/snmp.la - -%attr(0644,root,root) %{_libdir}/%{name}/syslog.so* -%attr(0644,root,root) %{_libdir}/%{name}/syslog.la - -# FIXME!!! -#%attr(0644,root,root) %{_libdir}/%{name}/tape.so* -#%attr(0644,root,root) %{_libdir}/%{name}/tape.la - -%attr(0644,root,root) %{_libdir}/%{name}/tcpconns.so* -%attr(0644,root,root) %{_libdir}/%{name}/tcpconns.la - -%attr(0644,root,root) %{_libdir}/%{name}/unixsock.so* -%attr(0644,root,root) %{_libdir}/%{name}/unixsock.la - -%attr(0644,root,root) %{_libdir}/%{name}/users.so* -%attr(0644,root,root) %{_libdir}/%{name}/users.la - -%attr(0644,root,root) %{_libdir}/%{name}/vserver.so* -%attr(0644,root,root) %{_libdir}/%{name}/vserver.la - -%attr(0644,root,root) %{_libdir}/%{name}/wireless.so* -%attr(0644,root,root) %{_libdir}/%{name}/wireless.la - -%attr(0644,root,root) %{_datadir}/%{name}/types.db - -%dir /var/lib/collectd - -%files apache -%attr(0644,root,root) %{_libdir}/%{name}/apache.so* -%attr(0644,root,root) %{_libdir}/%{name}/apache.la - -%files email -%attr(0644,root,root) %{_libdir}/%{name}/email.so* -%attr(0644,root,root) %{_libdir}/%{name}/email.la - -%files mysql -%attr(0644,root,root) %{_libdir}/%{name}/mysql.so* -%attr(0644,root,root) %{_libdir}/%{name}/mysql.la - -%files sensors -%attr(0644,root,root) %{_libdir}/%{name}/sensors.so* -%attr(0644,root,root) %{_libdir}/%{name}/sensors.la - -%changelog -* Wed Oct 31 2007 Iain Lea 4.2.0 -- New major release -- Changes to support 4.2.0 (ie. contrib/collection.conf) - -* Mon Aug 06 2007 Kjell Randa 4.0.6 -- New upstream version - -* Wed Jul 25 2007 Kjell Randa 4.0.5 -- New major release -- Changes to support 4.0.5 - -* Wed Jan 11 2007 Iain Lea 3.11.0-0 -- fixed spec file to build correctly on fedora core -- added improved init.d script to work with chkconfig -- added %post and %postun to call chkconfig automatically - -* Sun Jul 09 2006 Florian octo Forster 3.10.0-1 -- New upstream version - -* Tue Jun 25 2006 Florian octo Forster 3.9.4-1 -- New upstream version - -* Tue Jun 01 2006 Florian octo Forster 3.9.3-1 -- New upstream version - -* Tue May 09 2006 Florian octo Forster 3.9.2-1 -- New upstream version - -* Tue May 09 2006 Florian octo Forster 3.8.5-1 -- New upstream version - -* Fri Apr 21 2006 Florian octo Forster 3.9.1-1 -- New upstream version - -* Fri Apr 14 2006 Florian octo Forster 3.9.0-1 -- New upstream version -- Added the `apache' package. - -* Thu Mar 14 2006 Florian octo Forster 3.8.2-1 -- New upstream version - -* Thu Mar 13 2006 Florian octo Forster 3.8.1-1 -- New upstream version - -* Thu Mar 09 2006 Florian octo Forster 3.8.0-1 -- New upstream version - -* Sat Feb 18 2006 Florian octo Forster 3.7.2-1 -- Include `tape.so' so the build doesn't terminate because of missing files.. -- New upstream version - -* Sat Feb 04 2006 Florian octo Forster 3.7.1-1 -- New upstream version - -* Mon Jan 30 2006 Florian octo Forster 3.7.0-1 -- New upstream version -- Removed the extra `hddtemp' package - -* Tue Jan 24 2006 Florian octo Forster 3.6.2-1 -- New upstream version - -* Fri Jan 20 2006 Florian octo Forster 3.6.1-1 -- New upstream version - -* Fri Jan 20 2006 Florian octo Forster 3.6.0-1 -- New upstream version -- Added config file, `collectd.conf(5)', `df.so' -- Added package `collectd-mysql', dependency on `mysqlclient10 | mysql' - -* Wed Dec 07 2005 Florian octo Forster 3.5.0-1 -- New upstream version - -* Sat Nov 26 2005 Florian octo Forster 3.4.0-1 -- New upstream version - -* Sat Nov 05 2005 Florian octo Forster 3.3.0-1 -- New upstream version - -* Tue Oct 26 2005 Florian octo Forster 3.2.0-1 -- New upstream version -- Added statement to remove the `*.la' files. This fixes a problem when - `Unpackaged files terminate build' is in effect. -- Added `processes.so*' to the main package - -* Fri Oct 14 2005 Florian octo Forster 3.1.0-1 -- New upstream version -- Added package `collectd-hddtemp' - -* Fri Sep 30 2005 Florian octo Forster 3.0.0-1 -- New upstream version -- Split the package into `collectd' and `collectd-sensors' - -* Fri Sep 16 2005 Florian octo Forster 2.1.0-1 -- New upstream version - -* Mon Sep 10 2005 Florian octo Forster 2.0.0-1 -- New upstream version - -* Mon Aug 29 2005 Florian octo Forster 1.8.0-1 -- New upstream version - -* Sun Aug 25 2005 Florian octo Forster 1.7.0-1 -- New upstream version - -* Sun Aug 21 2005 Florian octo Forster 1.6.0-1 -- New upstream version - -* Sun Jul 17 2005 Florian octo Forster 1.5.1-1 -- New upstream version - -* Sun Jul 17 2005 Florian octo Forster 1.5-1 -- New upstream version - -* Mon Jul 11 2005 Florian octo Forster 1.4.2-1 -- New upstream version - -* Sat Jul 09 2005 Florian octo Forster 1.4-1 -- Built on RedHat 7.3 diff --git a/contrib/fedora/init.d-collectd b/contrib/fedora/init.d-collectd deleted file mode 100644 index ea8662ad60..0000000000 --- a/contrib/fedora/init.d-collectd +++ /dev/null @@ -1,66 +0,0 @@ -#!/bin/bash -# -# collectd Startup script for the Collectd statistics gathering daemon -# chkconfig: - 86 15 -# description: Collectd is a statistics gathering daemon used to collect \ -# system information ie. cpu, memory, disk, network -# processname: collectd -# config: /etc/collectd.conf -# config: /etc/sysconfig/collectd -# pidfile: /var/run/collectd.pid - -# Source function library. -. /etc/init.d/functions - -RETVAL=0 -ARGS="" -prog="collectd" -CONFIG=/etc/collectd.conf - -if [ -r /etc/default/$prog ]; then - . /etc/default/$prog -fi - -start () { - echo -n $"Starting $prog: " - if [ -r "$CONFIG" ] - then - daemon /usr/sbin/collectd -C "$CONFIG" - RETVAL=$? - echo - [ $RETVAL -eq 0 ] && touch /var/lock/subsys/$prog - fi -} -stop () { - echo -n $"Stopping $prog: " - killproc $prog - RETVAL=$? - echo - [ $RETVAL -eq 0 ] && rm -f /var/lock/subsys/$prog -} -# See how we were called. -case "$1" in - start) - start - ;; - stop) - stop - ;; - status) - status $prog - ;; - restart|reload) - stop - start - ;; - condrestart) - [ -f /var/lock/subsys/$prog ] && stop && start || : - ;; - *) - echo $"Usage: $0 {start|stop|status|restart|reload|condrestart}" - exit 1 -esac - -exit $? - -# vim:syntax=sh diff --git a/contrib/format.sh b/contrib/format.sh new file mode 100755 index 0000000000..18fac0aebf --- /dev/null +++ b/contrib/format.sh @@ -0,0 +1,21 @@ +#!/bin/sh + +# This script sends files to a web service using POST requests and reads back +# the correctly formatted source files. This allows to apply clang-format +# without having to install the tool locally. + +if test $# -lt 1; then + echo "Usage $0 [ ...]" + exit 1 +fi + +for i in "$@"; do + d="`dirname "${i}"`" + o="`TMPDIR="${d}" mktemp format.XXXXXX`" + + curl --silent --data-binary "@-" https://format.collectd.org/ <"${i}" >"${o}" + if test $? -eq 0; then + cat "${o}" >"${i}" + fi + rm -f "${o}" +done diff --git a/contrib/migrate-4-5.px b/contrib/migrate-4-5.px index c2a95558b2..8e5a7ed44b 100755 --- a/contrib/migrate-4-5.px +++ b/contrib/migrate-4-5.px @@ -104,8 +104,6 @@ our %TypesCounterToDerive = # {{{ protocol_counter => ["value"], ps_cputime => ["user", "syst"], ps_pagefaults => ["minflt", "majflt"], - ps_code => ["value"], - ps_data => ["value"], serial_octets => ["rx", "tx"], swap_io => ["value"], virt_cpu_total => ["ns"], diff --git a/contrib/php-collection/browser.js b/contrib/php-collection/browser.js index 4ddc424ddc..09673da8a5 100644 --- a/contrib/php-collection/browser.js +++ b/contrib/php-collection/browser.js @@ -106,8 +106,8 @@ function refillSelect(options, select) { 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'); @@ -311,7 +311,7 @@ function GraphAppend() { 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'); @@ -326,7 +326,7 @@ function GraphDoAppend(host, plugin, pinst, type, tinst, timespan, tinyLegend, l 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; @@ -346,11 +346,11 @@ function GraphDoAppend(host, plugin, pinst, type, tinst, timespan, tinyLegend, l 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); @@ -397,7 +397,7 @@ function GraphToggleTools(graph) { 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; @@ -513,7 +513,7 @@ function GraphAdjust(graph) { 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=[^&]*/, ''); @@ -544,7 +544,7 @@ function GraphRemove(graph) { 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 @@ -558,7 +558,7 @@ function GraphMoveUp(graph) { 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 @@ -590,7 +590,7 @@ function GraphMoveDown(graph) { 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 @@ -603,12 +603,12 @@ function GraphMoveDown(graph) { 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; } @@ -619,7 +619,7 @@ function GraphListFromCookie(lname) { 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('/'); } @@ -663,7 +663,7 @@ function GraphListRefresh() { } 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'); @@ -705,7 +705,7 @@ function GraphSave() { 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 += '/'; @@ -743,7 +743,7 @@ function GraphLoad() { // 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 = ''; @@ -753,7 +753,7 @@ function GraphLoad() { 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') diff --git a/contrib/php-collection/functions.php b/contrib/php-collection/functions.php index fa2badce0a..c063d57d8c 100644 --- a/contrib/php-collection/functions.php +++ b/contrib/php-collection/functions.php @@ -536,7 +536,7 @@ function rrd_get_color($code, $line = true) { } /** - * Draw RRD file based on it's structure + * Draw RRD file based on its structure * @host * @plugin * @pinst @@ -635,7 +635,7 @@ function collectd_draw_rrd($host, $plugin, $pinst = null, $type, $tinst = null, } /** - * Draw RRD file based on it's structure + * Draw RRD file based on its structure * @timespan * @host * @plugin diff --git a/contrib/php-collection/graph.php b/contrib/php-collection/graph.php index b9fefa6ad4..fdfcbaaffe 100644 --- a/contrib/php-collection/graph.php +++ b/contrib/php-collection/graph.php @@ -86,7 +86,7 @@ function error($code, $code_msg, $title, $msg) { imagestring($png, 4, ceil(($w-strlen($title)*imagefontwidth(4)) / 2), 10, $title, $c_txt); imagestring($png, 5, 60, 35, sprintf('%s [%d]', $code_msg, $code), $c_etxt); if (function_exists('imagettfbbox') && is_file($config['error_font'])) { - // Detailled error message + // Detailed error message $fmt_msg = makeTextBlock($msg, $errorfont, 10, $w-86); $fmtbox = imagettfbbox(12, 0, $errorfont, $fmt_msg); imagettftext($png, 10, 0, 55, 35+3+imagefontwidth(5)-$fmtbox[7]+$fmtbox[1], $c_txt, $errorfont, $fmt_msg); diff --git a/contrib/postgresql/collectd_insert.sql b/contrib/postgresql/collectd_insert.sql index 00c5519b7a..bee182cb71 100644 --- a/contrib/postgresql/collectd_insert.sql +++ b/contrib/postgresql/collectd_insert.sql @@ -33,8 +33,8 @@ -- and 'values' to store the value-list identifier and the actual values -- respectively. -- --- The 'values' table is partitioned to improve performance and maintainance. --- Please note that additional maintainance scripts are required in order to +-- The 'values' table is partitioned to improve performance and maintenance. +-- Please note that additional maintenance scripts are required in order to -- keep the setup running -- see the comments below for details. -- -- The function 'collectd_insert' may be used to actually insert values diff --git a/contrib/redhat/collectd.spec b/contrib/redhat/collectd.spec index 4f70fd694d..4721d47fbd 100644 --- a/contrib/redhat/collectd.spec +++ b/contrib/redhat/collectd.spec @@ -1,7 +1,7 @@ # # q: What is this ? # a: A specfile for building RPM packages of current collectd releases, for -# RHEL/CentOS versions 5 and 6. By default all the plugins which are +# RHEL/CentOS versions 5, 6 and 7. By default all the plugins which are # buildable based on the libraries available in the distribution + the # EPEL repository, will be built. Plugins depending on external libs will # be packaged in separate RPMs. @@ -14,10 +14,12 @@ # - enable the EPEL repository (http://dl.fedoraproject.org/pub/epel/) in the # configuration files for your target systems (/etc/mock/*.cfg). # -# - copy this file in your ~/rpmbuild/SPECS/ directory -# # - fetch the desired collectd release file from https://collectd.org/files/ -# and save it in your ~/rpmbuild/SOURCES/ directory +# and save it in your ~/rpmbuild/SOURCES/ directory (or build your own out of +# the git repository: ./build.sh && ./configure && make dist) +# +# - copy this file in your ~/rpmbuild/SPECS/ directory. Make sure the +# "Version:" tag matches the version from the tarball. # # - build the SRPM first: # mock -r centos-6-x86_64 --buildsrpm --spec ~/rpmbuild/SPECS/collectd.spec \ @@ -34,85 +36,110 @@ # %global _hardened_build 1 +%{?perl_default_filter} -# plugins only buildable on RHEL6 -# (NB: %{elN} macro is not available on RHEL < 6) -%{?el6:%global _has_libyajl 1} -%{?el6:%global _has_recent_libpcap 1} -%{?el6:%global _has_recent_sockios_h 1} -%{?el6:%global _has_recent_libganglia 1} -%{?el6:%global _has_working_libiptc 1} -%{?el6:%global _has_ip_vs_h 1} -%{?el6:%global _has_perl_extutils_embed 1} +# disable collectd debug by default +%bcond_with debug # plugins enabled by default %define with_aggregation 0%{!?_without_aggregation:1} %define with_amqp 0%{!?_without_amqp:1} +%define with_amqp1 0%{!?_without_amqp1:1} %define with_apache 0%{!?_without_apache:1} %define with_apcups 0%{!?_without_apcups:1} %define with_ascent 0%{!?_without_ascent:1} %define with_battery 0%{!?_without_battery:1} %define with_bind 0%{!?_without_bind:1} +%define with_ceph 0%{!?_without_ceph:1} +%define with_cgroups 0%{!?_without_cgroups:1} +%define with_check_uptime 0%{!?_without_check_uptime: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_cpufreq 0%{!?_without_cpufreq:1} +%define with_cpusleep 0%{!?_without_cpusleep:1} %define with_csv 0%{!?_without_csv:1} %define with_curl 0%{!?_without_curl:1} -%define with_curl_json 0%{!?_without_curl_json:0%{?_has_libyajl}} +%define with_curl_json 0%{!?_without_curl_json:1} %define with_curl_xml 0%{!?_without_curl_xml:1} %define with_dbi 0%{!?_without_dbi:1} %define with_df 0%{!?_without_df:1} %define with_disk 0%{!?_without_disk:1} -%define with_dns 0%{!?_without_dns:0%{?_has_recent_libpcap}} +%define with_dns 0%{!?_without_dns:1} +%define with_drbd 0%{!?_without_drbd:1} %define with_email 0%{!?_without_email:1} %define with_entropy 0%{!?_without_entropy:1} -%define with_ethstat 0%{!?_without_ethstat:0%{?_has_recent_sockios_h}} +%define with_ethstat 0%{!?_without_ethstat:1} %define with_exec 0%{!?_without_exec:1} +%define with_fhcount 0%{!?_without_fhcount:1} %define with_filecount 0%{!?_without_filecount:1} %define with_fscache 0%{!?_without_fscache:1} -%define with_gmond 0%{!?_without_gmond:0%{?_has_recent_libganglia}} +%define with_ganglia 0%{!?_without_ganglia:1} +%define with_gmond 0%{!?_without_gmond:1} +%define with_gps 0%{!?_without_gps:1} %define with_hddtemp 0%{!?_without_hddtemp:1} +%define with_hugepages 0%{!?_without_hugepages:1} %define with_interface 0%{!?_without_interface:1} +%define with_ipc 0%{!?_without_ipc:1} %define with_ipmi 0%{!?_without_ipmi:1} -%define with_iptables 0%{!?_without_iptables:0%{?_has_working_libiptc}} -%define with_ipvs 0%{!?_without_ipvs:0%{?_has_ip_vs_h}} +%define with_iptables 0%{!?_without_iptables:1} +%define with_ipvs 0%{!?_without_ipvs:1} %define with_irq 0%{!?_without_irq:1} %define with_java 0%{!?_without_java:1} -%define with_libvirt 0%{!?_without_libvirt:1} %define with_load 0%{!?_without_load:1} +%define with_log_logstash 0%{!?_without_log_logstash:1} %define with_logfile 0%{!?_without_logfile:1} +%define with_lua 0%{!?_without_lua:1} %define with_madwifi 0%{!?_without_madwifi:1} %define with_mbmon 0%{!?_without_mbmon:1} +%define with_mcelog 0%{!?_without_mcelog:1} %define with_md 0%{!?_without_md:1} %define with_memcachec 0%{!?_without_memcachec:1} %define with_memcached 0%{!?_without_memcached:1} %define with_memory 0%{!?_without_memory:1} +%define with_modbus 0%{!?_without_modbus:1} +%define with_mqtt 0%{!?_without_mqtt:1} %define with_multimeter 0%{!?_without_multimeter:1} %define with_mysql 0%{!?_without_mysql:1} +%define with_netlink 0%{!?_without_netlink:1} %define with_network 0%{!?_without_network:1} %define with_nfs 0%{!?_without_nfs:1} %define with_nginx 0%{!?_without_nginx:1} %define with_notify_desktop 0%{!?_without_notify_desktop:1} %define with_notify_email 0%{!?_without_notify_email:1} +%define with_notify_nagios 0%{!?_without_notify_nagios:1} %define with_ntpd 0%{!?_without_ntpd:1} %define with_numa 0%{!?_without_numa:1} %define with_nut 0%{!?_without_nut:1} %define with_olsrd 0%{!?_without_olsrd:1} +%define with_openldap 0%{!?_without_openldap:1} %define with_openvpn 0%{!?_without_openvpn:1} -%define with_perl 0%{!?_without_perl:0%{?_has_perl_extutils_embed}} +%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_rrdcached 0%{!?_without_rrdcached:1} %define with_rrdtool 0%{!?_without_rrdtool:1} %define with_sensors 0%{!?_without_sensors:1} %define with_serial 0%{!?_without_serial:1} +%define with_smart 0%{!?_without_smart:1} %define with_snmp 0%{!?_without_snmp:1} +%define with_snmp_agent 0%{!?_without_snmp_agent: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} @@ -122,71 +149,148 @@ %define with_ted 0%{!?_without_ted:1} %define with_thermal 0%{!?_without_thermal:1} %define with_threshold 0%{!?_without_threshold:1} +%define with_turbostat 0%{!?_without_turbostat:1} %define with_unixsock 0%{!?_without_unixsock:1} %define with_uptime 0%{!?_without_uptime:1} %define with_users 0%{!?_without_users:1} %define with_uuid 0%{!?_without_uuid:1} %define with_varnish 0%{!?_without_varnish:1} +%define with_virt 0%{!?_without_virt:1} %define with_vmem 0%{!?_without_vmem:1} %define with_vserver 0%{!?_without_vserver:1} %define with_wireless 0%{!?_without_wireless:1} %define with_write_graphite 0%{!?_without_write_graphite:1} %define with_write_http 0%{!?_without_write_http:1} +%define with_write_log 0%{!?_without_write_log: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_xmms 0%{!?_without_xmms:0%{?_has_xmms}} +%define with_zfs_arc 0%{!?_without_zfs_arc:1} +%define with_zookeeper 0%{!?_without_zookeeper:1} # Plugins not built by default because of dependencies on libraries not # available in RHEL or EPEL: # plugin apple_sensors disabled, requires a Mac %define with_apple_sensors 0%{!?_without_apple_sensors:0} +# plugin aquaero disabled, requires a libaquaero5 +%define with_aquaero 0%{!?_without_aquaero:0} +# plugin barometer disabled, requires a libi2c +%define with_barometer 0%{!?_without_barometer:0} +# plugin dpdkevents disabled, requires libdpdk +%define with_dpdkevents 0%{!?_without_dpdkevents:0} +# plugin dpdkstat disabled, requires libdpdk +%define with_dpdkstat 0%{!?_without_dpdkstat:0} +# plugin dpdk_telemetry disabled, requires libdpdk +%define with_dpdk_telemetry 0%{!?_without_dpdk_telemetry:0} +# plugin grpc disabled, requires protobuf-compiler >= 3.0 +%define with_grpc 0%{!?_without_grpc:0} # plugin lpar disabled, requires AIX %define with_lpar 0%{!?_without_lpar:0} -# plugin modbus disabled, requires libmodbus -%define with_modbus 0%{!?_without_modbus:0} +# plugin intel_pmu disabled, requires libjevents +%define with_intel_pmu 0%{!?_without_intel_pmu:0} +# plugin intel_rdt disabled, requires intel-cmt-cat +%define with_intel_rdt 0%{!?_without_intel_rdt:0} +# plugin mic disabled, requires Mic +%define with_mic 0%{!?_without_mic:0} # plugin netapp disabled, requires libnetapp %define with_netapp 0%{!?_without_netapp:0} -# plugin netlink disabled, requires libnetlink.h -%define with_netlink 0%{!?_without_netlink:0} # plugin onewire disabled, requires libowfs %define with_onewire 0%{!?_without_onewire:0} # plugin oracle disabled, requires Oracle %define with_oracle 0%{!?_without_oracle:0} # plugin oracle disabled, requires BSD %define with_pf 0%{!?_without_pf:0} -# plugin redis disabled, requires credis -%define with_redis 0%{!?_without_redis:0} # plugin routeros disabled, requires librouteros %define with_routeros 0%{!?_without_routeros:0} -# plugin rrdcached disabled, requires rrdtool >= 1.4 -%define with_rrdcached 0%{!?_without_rrdcached:0} +# plugin sigrok disabled, requires libsigrok +%define with_sigrok 0%{!?_without_sigrok:0} # plugin tape disabled, requires libkstat %define with_tape 0%{!?_without_tape:0} # plugin tokyotyrant disabled, requires tcrdb.h %define with_tokyotyrant 0%{!?_without_tokyotyrant:0} +# plugin write_kafka disabled, requires librdkafka +%define with_write_kafka 0%{!?_without_write_kafka:0} # plugin write_mongodb disabled, requires libmongoc %define with_write_mongodb 0%{!?_without_write_mongodb:0} -# plugin write_redis disabled, requires credis -%define with_write_redis 0%{!?_without_write_redis:0} -# plugin xmms disabled, requires xmms -%define with_xmms 0%{!?_without_xmms:0} -# plugin zfs_arc disabled, requires FreeBSD/Solaris -%define with_zfs_arc 0%{!?_without_zfs_arc:0} - -Summary: Statistics collection daemon for filling RRD files +# plugin xencpu disabled, requires xen-devel from non-default repo +%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} +# not available in el or epel +%define with_slurm 0%{!?_without_slurm:0} +# not available in el or epel +%define with_redfish 0%{!?_without_redfish:0} +# not available in el or epel +%define with_dcpmm 0%{!?_without_dcpmm:0} +# not available in el or epel +%define with_capabilities 0%{!?_without_capabilities:0} +# not available in el or epel +%define with_ipstats 0%{!?_without_ipstats: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_smart 0 +%define with_sysevent 0 +# missing /usr/include/varnish/vapi/vsc.h +%define with_varnish 0 +%define with_write_redis 0 +%define with_write_riemann 0 +%define with_xmms 0 +%endif + +# Plugins not buildable on RHEL 8 +%if 0%{?rhel} && 0%{?rhel} >= 8 +%define with_smart 0 +%define with_ganglia 0 +%define with_gmond 0 +%define with_gps 0 +%define with_modbus 0 +%define with_ping 0 +%define with_mqtt 0 +%endif + +Summary: Statistics collection and monitoring daemon Name: collectd -Version: 5.3.1 +Version: 5.11.0 Release: 1%{?dist} -URL: http://collectd.org -Source: http://collectd.org/files/%{name}-%{version}.tar.bz2 +URL: https://collectd.org +Source: https://collectd.org/files/%{name}-%{version}.tar.bz2 License: GPLv2 Group: System Environment/Daemons BuildRoot: %{_tmppath}/%{name}-%{version}-root -BuildRequires: libgcrypt-devel, kernel-headers +BuildRequires: libgcrypt-devel, kernel-headers, libcap-devel, which Vendor: collectd development team +%if 0%{?fedora} || 0%{?rhel} >= 7 +BuildRequires: xfsprogs-devel +%{?systemd_requires} +BuildRequires: systemd +%else Requires(post): chkconfig Requires(preun): chkconfig, initscripts Requires(postun): initscripts +%endif %description collectd is a small daemon which collects system information periodically and @@ -198,13 +302,24 @@ every 10 seconds by default. %if %{with_amqp} %package amqp -Summary: AMQP plugin for collectd +Summary: AMQP 0.9 plugin for collectd Group: System Environment/Daemons Requires: %{name}%{?_isa} = %{version}-%{release} BuildRequires: librabbitmq-devel %description amqp -The AMQP plugin transmits or receives values collected by collectd via the -Advanced Message Queuing Protocol (AMQP). +The AMQP 0.9 plugin transmits or receives values collected by collectd via the +Advanced Message Queuing Protocol v0.9 (AMQP). +%endif + +%if %{with_amqp1} +%package amqp1 +Summary: AMQP 1.0 plugin for collectd +Group: System Environment/Daemons +Requires: %{name}%{?_isa} = %{version}-%{release} +BuildRequires: qpid-proton-c-devel +%description amqp1 +The AMQP 1.0 plugin transmits or receives values collected by collectd via the +Advanced Message Queuing Protocol v1.0 (AMQP1). %endif %if %{with_apache} @@ -217,6 +332,15 @@ BuildRequires: curl-devel This plugin collects data provided by Apache's `mod_status'. %endif +%if %{with_aquaero} +%package aquaero +Summary: aquaero plugin for collectd +Group: System Environment/Daemons +Requires: %{name}%{?_isa} = %{version}-%{release} +%description aquaero +Various sensors in the Aquaero 5 watercooling board made by Aquacomputer. +%endif + %if %{with_ascent} %package ascent Summary: Ascent plugin for collectd @@ -229,6 +353,15 @@ open-source server software for the game World of Warcraft by Blizzard Entertainment. %endif +%if %{with_barometer} +%package barometer +Summary: barometer plugin for collectd +Group: System Environment/Daemons +Requires: %{name}%{?_isa} = %{version}-%{release} +%description barometer +Collects pressure and temperature from digital barometers. +%endif + %if %{with_bind} %package bind Summary: Bind plugin for collectd @@ -240,6 +373,35 @@ The BIND plugin retrieves this information that's encoded in XML and provided via HTTP and submits the values to collectd. %endif +%if %{with_ceph} +%package ceph +Summary: Ceph plugin for collectd +Group: System Environment/Daemons +Requires: %{name}%{?_isa} = %{version}-%{release} +BuildRequires: yajl-devel +%description ceph +Ceph plugin for collectd +%endif + +%if %{with_chrony} +%package chrony +Summary: Chrony plugin for collectd +Group: System Environment/Daemons +Requires: %{name}%{?_isa} = %{version}-%{release} +%description chrony +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 @@ -284,6 +446,17 @@ The DBI plugin uses libdbi, a database abstraction library, to execute SQL statements on a database and read back the result. %endif +%if %{with_disk} +%package disk +Summary: disk plugin for collectd +Group: System Environment/Daemons +Requires: %{name}%{?_isa} = %{version}-%{release} +%{?_has_libudev:BuildRequires: libudev-devel} +%description disk +The "disk" plugin collects information about the usage of physical disks and +logical disks (partitions). +%endif + %if %{with_dns} %package dns Summary: DNS plugin for collectd @@ -316,6 +489,26 @@ The gmond plugin subscribes to a Multicast group to receive data from gmond, the client daemon of the Ganglia project. %endif +%if %{with_gps} +%package gps +Summary: GPS plugin for collectd +Group: System Environment/Daemons +Requires: %{name}%{?_isa} = %{version}-%{release} +BuildRequires: gpsd-devel +%description gps +This plugin monitor gps related data through gpsd. +%endif + +%if %{with_grpc} +%package grpc +Summary: GRPC plugin for collectd +Group: System Environment/Daemons +Requires: %{name}%{?_isa} = %{version}-%{release} +BuildRequires: protobuf-compiler +%description grpc +This plugin embeds a gRPC server into Collectd. +%endif + %if %{with_hddtemp} %package hddtemp Summary: Hddtemp plugin for collectd @@ -326,6 +519,27 @@ The HDDTemp plugin collects the temperature of hard disks. The temperatures are provided via SMART and queried by the external hddtemp daemon. %endif +%if %{with_intel_pmu} +%package intel_pmu +Summary: Intel PMU plugin for collectd +Group: System Environment/Daemons +Requires: %{name}%{?_isa} = %{version}-%{release} +%description intel_pmu +The intel_pmu plugin reads performance counters provided by the Linux +kernel perf interface. +%endif + +%if %{with_intel_rdt} +%package intel_rdt +Summary: Intel RDT plugin for collectd +Group: System Environment/Daemons +Requires: %{name}%{?_isa} = %{version}-%{release} +BuildRequires: intel-cmt-cat +%description intel_rdt +The intel_rdt plugin collects information provided by monitoring features of +Intel Resource Director Technology (Intel(R) RDT). +%endif + %if %{with_ipmi} %package ipmi Summary: IPMI plugin for collectd @@ -354,21 +568,42 @@ the byte- and packet-counters of selected rules and submit them to collectd. Summary: Java plugin for collectd Group: System Environment/Daemons Requires: %{name}%{?_isa} = %{version}-%{release} -BuildRequires: java-devel, jpackage-utils -Requires: java, jpackage-utils +BuildRequires: java-devel >= 1.6, jpackage-utils >= 1.6 +Requires: java >= 1.6, jpackage-utils >= 1.6 %description java This plugin for collectd allows plugins to be written in Java and executed in an embedded JVM. %endif -%if %{with_libvirt} -%package libvirt -Summary: Libvirt plugin for collectd +%if %{with_log_logstash} +%package log_logstash +Summary: log_logstash plugin for collectd +Group: System Environment/Daemons +Requires: %{name}%{?_isa} = %{version}-%{release} +BuildRequires: yajl-devel +%description log_logstash +This plugin logs in logstash JSON format +%endif + +%if %{with_lua} +%package lua +Summary: Lua plugin for collectd Group: System Environment/Daemons Requires: %{name}%{?_isa} = %{version}-%{release} -BuildRequires: libvirt-devel -%description libvirt -This plugin collects information from virtualized guests. +BuildRequires: lua-devel +%description lua +The Lua plugin embeds a Lua interpreter into collectd and exposes the +application programming interface (API) to Lua scripts. +%endif + +%if %{with_mcelog} +%package mcelog +Summary: Mcelog plugin for collectd +Group: System Environment/Daemons +Requires: %{name}%{?_isa} = %{version}-%{release} +%description mcelog +This plugin monitors machine check exceptions reported by mcelog and generates +appropriate notifications when machine check exceptions are detected. %endif %if %{with_memcachec} @@ -383,6 +618,26 @@ instance. Note that another plugin, named `memcached', exists and does a similar job, without requiring the installation of libmemcached. %endif +%if %{with_mic} +%package mic +Summary: mic plugin for collectd +Group: System Environment/Daemons +Requires: %{name}%{?_isa} = %{version}-%{release} +%description mic +The mic plugin collects CPU usage, memory usage, temperatures and power +consumption from Intel Many Integrated Core (MIC) CPUs. +%endif + +%if %{with_modbus} +%package modbus +Summary: modbus plugin for collectd +Group: System Environment/Daemons +Requires: %{name}%{?_isa} = %{version}-%{release} +BuildRequires: libmodbus-devel +%description modbus +The modbus plugin collects values from Modbus/TCP enabled devices +%endif + %if %{with_mysql} %package mysql Summary: MySQL plugin for collectd @@ -394,6 +649,26 @@ MySQL querying plugin. This plugin provides data of issued commands, called handlers and database traffic. %endif +%if %{with_mqtt} +%package mqtt +Summary: mqtt plugin for collectd +Group: System Environment/Daemons +Requires: %{name}%{?_isa} = %{version}-%{release} +BuildRequires: mosquitto-devel +%description mqtt +The MQTT plugin publishes and subscribes to MQTT topics. +%endif + +%if %{with_netlink} +%package netlink +Summary: netlink plugin for collectd +Group: System Environment/Daemons +Requires: %{name}%{?_isa} = %{version}-%{release} +BuildRequires: libmnl-devel, iproute-devel +%description netlink +The netlink plugin collects detailed network interface and routing statistics. +%endif + %if %{with_nginx} %package nginx Summary: Nginx plugin for collectd @@ -436,6 +711,39 @@ BuildRequires: nut-devel This plugin for collectd provides Network UPS Tools support. %endif +%if %{with_openldap} +%package openldap +Summary: Openldap plugin for collectd +Group: System Environment/Daemons +Requires: %{name}%{?_isa} = %{version}-%{release} +BuildRequires: openldap-devel +%description openldap +This plugin reads monitoring information from OpenLDAP's cn=Monitor subtree. +%endif + +%if %{with_ovs_events} +%package ovs_events +Summary: Open vSwitch events plugin for collectd +Group: System Environment/Daemons +Requires: %{name}%{?_isa} = %{version}-%{release} +BuildRequires: yajl-devel +%description ovs_events +This plugin monitors the link status of Open vSwitch (OVS) connected +interfaces, dispatches the values to collectd and sends notifications +whenever a link state change occurs in the OVS database. +%endif + +%if %{with_ovs_stats} +%package ovs_stats +Summary: Open vSwitch statistics plugin for collectd +Group: System Environment/Daemons +Requires: %{name}%{?_isa} = %{version}-%{release} +BuildRequires: yajl-devel +%description ovs_stats +This plugin collects statictics of OVS connected bridges and +interfaces. +%endif + %if %{with_perl} %package perl Summary: Perl plugin for collectd @@ -448,6 +756,16 @@ The Perl plugin embeds a Perl interpreter into collectd and exposes the 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 @@ -481,15 +799,25 @@ The PostgreSQL plugin connects to and executes SQL statements on a PostgreSQL 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 Group: System Environment/Daemons Requires: %{name}%{?_isa} = %{version}-%{release} -%if 0%{?rhel} >= 6 -BuildRequires: python-devel +%if 0%{?rhel} && 0%{?rhel} >= 8 +BuildRequires: python3-devel %else -BuildRequires: python26-devel +BuildRequires: python2-devel %endif %description python The Python plugin embeds a Python interpreter into collectd and exposes the @@ -501,10 +829,10 @@ application programming interface (API) to Python-scripts. Summary: Redis plugin for collectd Group: System Environment/Daemons Requires: %{name}%{?_isa} = %{version}-%{release} -BuildRequires: credis-devel +BuildRequires: hiredis-devel %description redis The Redis plugin connects to one or more instances of Redis, a key-value store, -and collects usage information using the credis library. +and collects usage information using the hiredis library. %endif %if %{with_rrdcached} @@ -538,6 +866,28 @@ BuildRequires: lm_sensors-devel This plugin for collectd provides querying of sensors supported by lm_sensors. %endif +%if %{with_sigrok} +%package sigrok +Summary: sigrok plugin for collectd +Group: System Environment/Daemons +Requires: %{name}%{?_isa} = %{version}-%{release} +%description sigrok +Uses libsigrok as a backend, allowing any sigrok-supported device to have its +measurements fed to collectd. This includes multimeters, sound level meters, +thermometers, and much more. +%endif + +%if %{with_smart} +%package smart +Summary: SMART plugin for collectd +Group: System Environment/Daemons +Requires: %{name}%{?_isa} = %{version}-%{release} +BuildRequires: libatasmart-devel +%description smart +Collect SMART statistics, notably load cycle count, temperature and bad +sectors. +%endif + %if %{with_snmp} %package snmp Summary: SNMP plugin for collectd @@ -548,6 +898,26 @@ BuildRequires: net-snmp-devel This plugin for collectd allows querying of network equipment using SNMP. %endif +%if %{with_snmp_agent} +%package snmp_agent +Summary: SNMP AgentX plugin for collectd +Group: System Environment/Daemons +Requires: %{name}%{?_isa} = %{version}-%{release} +BuildRequires: net-snmp-devel +%description snmp_agent +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 @@ -558,6 +928,16 @@ BuildRequires: varnish-libs-devel The Varnish plugin collects information about Varnish, an HTTP accelerator. %endif +%if %{with_virt} +%package virt +Summary: Virt plugin for collectd +Group: System Environment/Daemons +Requires: %{name}%{?_isa} = %{version}-%{release} +BuildRequires: libvirt-devel +%description virt +This plugin collects information from virtualized guests. +%endif + %if %{with_write_http} %package write_http Summary: Write-HTTP plugin for collectd @@ -569,12 +949,33 @@ The Write-HTTP plugin sends the values collected by collectd to a web-server using HTTP POST requests. %endif +%if %{with_write_kafka} +%package write_kafka +Summary: Write-kafka plugin for collectd +Group: System Environment/Daemons +Requires: %{name}%{?_isa} = %{version}-%{release} +BuildRequires: librdkafka-devel +%description write_kafka +The write_kafka plugin sends values to kafka, a distributed messaging system. +%endif + +%if %{with_write_prometheus} +%package write_prometheus +Summary: Write-prometheus plugin for collectd +Group: System Environment/Daemons +Requires: %{name}%{?_isa} = %{version}-%{release} +BuildRequires: libmicrohttpd-devel +%description write_prometheus +The Write Prometheus plugin exposes collected values using an embedded HTTP +server, turning the collectd daemon into a Prometheus exporter. +%endif + %if %{with_write_redis} %package write_redis Summary: Write-Redis plugin for collectd Group: System Environment/Daemons Requires: %{name}%{?_isa} = %{version}-%{release} -BuildRequires: credis-devel +BuildRequires: hiredis-devel %description write_redis The Write Redis plugin stores values in Redis, a “data structures server”. %endif @@ -584,11 +985,62 @@ The Write Redis plugin stores values in Redis, a “data structures server”. Summary: riemann plugin for collectd Group: System Environment/Daemons Requires: %{name}%{?_isa} = %{version}-%{release} -BuildRequires: protobuf-c-devel +BuildRequires: riemann-c-client-devel >= 1.6 %description write_riemann 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_write_syslog} +%package write_syslog +Summary: write_syslog plugin for collectd +Group: System Environment/Daemons +Requires: %{name}%{?_isa} = %{version}-%{release} +%description write_syslog +The write_syslog collectd plugin writes metrics to syslog +using JSON or RFC5424 formatting +%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 +Group: System Environment/Daemons +Requires: %{name}%{?_isa} = %{version}-%{release} +BuildRequires: xen-devel +%description xencpu +The xencpu plugin collects CPU statistics from Xen. +%endif + +%if %{with_xmms} +%package xmms +Summary: XMMS plugin for collectd +Group: System Environment/Daemons +Requires: %{name}%{?_isa} = %{version}-%{release} +BuildRequires: xmms-devel +%description xmms +The xmms plugin collects information from the XMMS music player. +%endif + %package collection3 Summary: Web-based viewer for collectd Group: System Environment/Daemons @@ -631,6 +1083,13 @@ Requires: libcollectdclient%{?_isa} = %{version}-%{release} %description -n libcollectdclient-devel Development files for libcollectdclient +%package -n collectd-utils +Summary: Collectd utilities +Group: System Environment/Daemons +Requires: libcollectdclient%{?_isa} = %{version}-%{release} +Requires: collectd%{?_isa} = %{version}-%{release} +%description -n collectd-utils +Collectd utilities %prep %setup -q @@ -648,6 +1107,12 @@ Development files for libcollectdclient %define _with_amqp --disable-amqp %endif +%if %{with_amqp1} +%define _with_amqp1 --enable-amqp1 +%else +%define _with_amqp1 --disable-amqp1 +%endif + %if %{with_apache} %define _with_apache --enable-apache %else @@ -666,12 +1131,24 @@ Development files for libcollectdclient %define _with_apple_sensors --disable-apple_sensors %endif +%if %{with_aquaero} +%define _with_aquaero --enable-aquaero +%else +%define _with_aquaero --disable-aquaero +%endif + %if %{with_ascent} %define _with_ascent --enable-ascent %else %define _with_ascent --disable-ascent %endif +%if %{with_barometer} +%define _with_barometer --enable-barometer +%else +%define _with_barometer --disable-barometer +%endif + %if %{with_battery} %define _with_battery --enable-battery %else @@ -684,6 +1161,36 @@ Development files for libcollectdclient %define _with_bind --disable-bind %endif +%if %{with_capabilities} +%define _with_capabilities --enable-capabilities +%else +%define _with_capabilities --disable-capabilities +%endif + +%if %{with_cgroups} +%define _with_cgroups --enable-cgroups +%else +%define _with_cgroups --disable-cgroups +%endif + +%if %{with_check_uptime} +%define _with_check_uptime --enable-check_uptime +%else +%define _with_check_uptime --disable-check_uptime +%endif + +%if %{with_chrony} +%define _with_chrony --enable-chrony +%else +%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 @@ -708,12 +1215,24 @@ Development files for libcollectdclient %define _with_cpufreq --disable-cpufreq %endif +%if %{with_cpusleep} +%define _with_cpusleep --enable-cpusleep +%else +%define _with_cpusleep --disable-cpusleep +%endif + %if %{with_csv} %define _with_csv --enable-csv %else %define _with_csv --disable-csv %endif +%if %{with_ceph} +%define _with_ceph --enable-ceph +%else +%define _with_ceph --disable-ceph +%endif + %if %{with_curl} %define _with_curl --enable-curl %else @@ -735,7 +1254,13 @@ Development files for libcollectdclient %if %{with_dbi} %define _with_dbi --enable-dbi %else -%define _with_dbi --disable-dbi --without-libdbi +%define _with_dbi --disable-dbi +%endif + +%if %{with_dcpmm} +%define _with_dcpmm --enable-dcpmm +%else +%define _with_dcpmm --disable-dcpmm %endif %if %{with_df} @@ -756,6 +1281,30 @@ Development files for libcollectdclient %define _with_dns --disable-dns %endif +%if %{with_drbd} +%define _with_drbd --enable-drbd +%else +%define _with_drbd --disable-drbd +%endif + +%if %{with_dpdkevents} +%define _with_dpdkevents --enable-dpdkevents +%else +%define _with_dpdkevents --disable-dpdkevents +%endif + +%if %{with_dpdkstat} +%define _with_dpdkstat --enable-dpdkstat +%else +%define _with_dpdkstat --disable-dpdkstat +%endif + +%if %{with_dpdk_telemetry} +%define _with_dpdk_telemetry --enable-dpdk_telemetry +%else +%define _with_dpdk_telemetry --disable-dpdk_telemetry +%endif + %if %{with_email} %define _with_email --enable-email %else @@ -780,6 +1329,12 @@ Development files for libcollectdclient %define _with_exec --disable-exec %endif +%if %{with_fhcount} +%define _with_fhcount --enable-fhcount +%else +%define _with_fhcount --disable-fhcount +%endif + %if %{with_filecount} %define _with_filecount --enable-filecount %else @@ -792,30 +1347,78 @@ Development files for libcollectdclient %define _with_fscache --disable-fscache %endif +%if %{with_ganglia} +%define _with_ganglia --enable-ganglia +%else +%define _with_ganglia --disable-ganglia +%endif + %if %{with_gmond} %define _with_gmond --enable-gmond %else %define _with_gmond --disable-gmond %endif +%if %{with_gps} +%define _with_gps --enable-gps +%else +%define _with_gps --disable-gps +%endif + +%if %{with_grpc} +%define _with_grpc --enable-grpc +%else +%define _with_grpc --disable-grpc +%endif + %if %{with_hddtemp} %define _with_hddtemp --enable-hddtemp %else %define _with_hddtemp --disable-hddtemp %endif +%if %{with_hugepages} +%define _with_hugepages --enable-hugepages +%else +%define _with_hugepages --disable-hugepages +%endif + +%if %{with_intel_pmu} +%define _with_intel_pmu --enable-intel_pmu +%else +%define _with_intel_pmu --disable-intel_pmu +%endif + +%if %{with_intel_rdt} +%define _with_intel_rdt --enable-intel_rdt +%else +%define _with_intel_rdt --disable-intel_rdt +%endif + %if %{with_interface} %define _with_interface --enable-interface %else %define _with_interface --disable-interface %endif +%if %{with_ipc} +%define _with_ipc --enable-ipc +%else +%define _with_ipc --disable-ipc +%endif + %if %{with_ipmi} %define _with_ipmi --enable-ipmi %else %define _with_ipmi --disable-ipmi %endif +%if %{with_ipstats} +%define _with_ipstats --enable-ipstats +%else +%define _with_ipstats --disable-ipstats +%endif + %if %{with_iptables} %define _with_iptables --enable-iptables %else @@ -840,10 +1443,10 @@ Development files for libcollectdclient %define _with_java --disable-java %endif -%if %{with_libvirt} -%define _with_libvirt --enable-libvirt +%if %{with_virt} +%define _with_virt --enable-virt %else -%define _with_libvirt --disable-libvirt +%define _with_virt --disable-virt %endif %if %{with_load} @@ -858,12 +1461,24 @@ Development files for libcollectdclient %define _with_logfile --disable-logfile %endif +%if %{with_log_logstash} +%define _with_log_logstash --enable-log_logstash +%else +%define _with_log_logstash --disable-log_logstash +%endif + %if %{with_lpar} %define _with_lpar --enable-lpar %else %define _with_lpar --disable-lpar %endif +%if %{with_lua} +%define _with_lua --enable-lua +%else +%define _with_lua --disable-lua +%endif + %if %{with_madwifi} %define _with_madwifi --enable-madwifi %else @@ -876,6 +1491,12 @@ Development files for libcollectdclient %define _with_mbmon --disable-mbmon %endif +%if %{with_mcelog} +%define _with_mcelog --enable-mcelog +%else +%define _with_mcelog --disable-mcelog +%endif + %if %{with_md} %define _with_md --enable-md %else @@ -900,6 +1521,12 @@ Development files for libcollectdclient %define _with_memory --disable-memory %endif +%if %{with_mic} +%define _with_mic --enable-mic +%else +%define _with_mic --disable-mic +%endif + %if %{with_modbus} %define _with_modbus --enable-modbus %else @@ -912,6 +1539,12 @@ Development files for libcollectdclient %define _with_multimeter --disable-multimeter %endif +%if %{with_mqtt} +%define _with_mqtt --enable-mqtt +%else +%define _with_mqtt --disable-mqtt +%endif + %if %{with_mysql} %define _with_mysql --enable-mysql %else @@ -957,7 +1590,13 @@ Development files for libcollectdclient %if %{with_notify_email} %define _with_notify_email --enable-notify_email %else -%define _with_notify_email --disable-notify_email --without-libesmpt +%define _with_notify_email --disable-notify_email +%endif + +%if %{with_notify_nagios} +%define _with_notify_nagios --enable-notify_nagios +%else +%define _with_notify_nagios --disable-notify_nagios %endif %if %{with_ntpd} @@ -990,6 +1629,12 @@ Development files for libcollectdclient %define _with_onewire --disable-onewire %endif +%if %{with_openldap} +%define _with_openldap --enable-openldap +%else +%define _with_openldap --disable-openldap +%endif + %if %{with_openvpn} %define _with_openvpn --enable-openvpn %else @@ -1002,10 +1647,28 @@ Development files for libcollectdclient %define _with_oracle --disable-oracle %endif +%if %{with_ovs_events} +%define _with_ovs_events --enable-ovs_events +%else +%define _with_ovs_events --disable-ovs_events +%endif + +%if %{with_ovs_stats} +%define _with_ovs_stats --enable-ovs_stats +%else +%define _with_ovs_stats --disable-ovs_stats +%endif + %if %{with_perl} %define _with_perl --enable-perl --with-perl-bindings="INSTALLDIRS=vendor" %else -%define _with_perl --disable-perl --without-libperl +%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} @@ -1044,6 +1707,12 @@ Development files for libcollectdclient %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 @@ -1051,13 +1720,15 @@ Development files for libcollectdclient %endif %if %{with_python} -%if 0%{?rhel} >= 6 %define _with_python --enable-python %else -%define _with_python --enable-python --with-python=%{_bindir}/python2.6 +%define _with_python --disable-python %endif + +%if %{with_redfish} +%define _with_redfish --enable-redfish %else -%define _with_python --disable-python +%define _with_redfish --disable-redfish %endif %if %{with_redis} @@ -1096,18 +1767,60 @@ Development files for libcollectdclient %define _with_serial --disable-serial %endif +%if %{with_sigrok} +%define _with_sigrok --enable-sigrok +%else +%define _with_sigrok --disable-sigrok +%endif + +%if %{with_slurm} +%define _with_slurm --enable-slurm +%else +%define _with_slurm --disable-slurm +%endif + +%if %{with_smart} +%define _with_smart --enable-smart +%else +%define _with_smart --disable-smart +%endif + %if %{with_snmp} %define _with_snmp --enable-snmp %else %define _with_snmp --disable-snmp %endif +%if %{with_snmp_agent} +%define _with_snmp_agent --enable-snmp_agent +%else +%define _with_snmp_agent --disable-snmp_agent +%endif + +%if %{with_statsd} +%define _with_statsd --enable-statsd +%else +%define _with_statsd --disable-statsd +%endif + %if %{with_swap} %define _with_swap --enable-swap %else %define _with_swap --disable-swap %endif +%if %{with_synproxy} +%define _with_synproxy --enable-synproxy +%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 @@ -1174,6 +1887,12 @@ Development files for libcollectdclient %define _with_tokyotyrant --disable-tokyotyrant %endif +%if %{with_turbostat} +%define _with_turbostat --enable-turbostat +%else +%define _with_turbostat --disable-turbostat +%endif + %if %{with_unixsock} %define _with_unixsock --enable-unixsock %else @@ -1234,16 +1953,34 @@ Development files for libcollectdclient %define _with_write_http --disable-write_http %endif +%if %{with_write_kafka} +%define _with_write_kafka --enable-write_kafka +%else +%define _with_write_kafka --disable-write_kafka +%endif + +%if %{with_write_log} +%define _with_write_log --enable-write_log +%else +%define _with_write_log --disable-write_log +%endif + %if %{with_write_mongodb} %define _with_write_mongodb --enable-write_mongodb %else -%define _with_write_mongodb --disable-write_mongodb --without-libmongoc +%define _with_write_mongodb --disable-write_mongodb +%endif + +%if %{with_write_prometheus} +%define _with_write_prometheus --enable-write_prometheus +%else +%define _with_write_prometheus --disable-write_prometheus %endif %if %{with_write_redis} %define _with_write_redis --enable-write_redis %else -%define _with_write_redis --disable-write_redis --without-libcredis +%define _with_write_redis --disable-write_redis %endif %if %{with_write_riemann} @@ -1252,6 +1989,42 @@ Development files for libcollectdclient %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 +%define _with_write_sensu --disable-write_sensu +%endif + +%if %{with_write_syslog} +%define _with_write_syslog --enable-write_syslog +%else +%define _with_write_syslog --disable-write_syslog +%endif + +%if %{with_write_tsdb} +%define _with_write_tsdb --enable-write_tsdb +%else +%define _with_write_tsdb --disable-write_tsdb +%endif + +%if %{with_xencpu} +%define _with_xencpu --enable-xencpu +%else +%define _with_xencpu --disable-xencpu +%endif + %if %{with_xmms} %define _with_xmms --enable-xmms %else @@ -1264,9 +2037,28 @@ Development files for libcollectdclient %define _with_zfs_arc --disable-zfs_arc %endif +%if %{with_zone} +%define _with_zone --enable-zone +%else +%define _with_zone --disable-zone +%endif + +%if %{with_zookeeper} +%define _with_zookeeper --enable-zookeeper +%else +%define _with_zookeeper --disable-zookeeper +%endif + +%if %{with debug} +%define _feature_debug --enable-debug +%else +%define _feature_debug --disable-debug +%endif + %configure CFLAGS="%{optflags} -DLT_LAZY_OR_NOW=\"RTLD_LAZY|RTLD_GLOBAL\"" \ + %{?_python_config} \ + %{?_feature_debug} \ --disable-static \ - --without-included-ltdl \ --enable-all-plugins=yes \ --enable-match_empty_counter \ --enable-match_hashed \ @@ -1280,109 +2072,164 @@ Development files for libcollectdclient --enable-target_v5upgrade \ %{?_with_aggregation} \ %{?_with_amqp} \ + %{?_with_amqp1} \ %{?_with_apache} \ %{?_with_apcups} \ %{?_with_apple_sensors} \ + %{?_with_aquaero} \ %{?_with_ascent} \ + %{?_with_barometer} \ %{?_with_battery} \ %{?_with_bind} \ + %{?_with_capabilities} \ + %{?_with_ceph} \ + %{?_with_cgroups} \ + %{?_with_check_uptime} \ + %{?_with_chrony} \ + %{?_with_connectivity} \ %{?_with_conntrack} \ %{?_with_contextswitch} \ - %{?_with_cpu} \ %{?_with_cpufreq} \ + %{?_with_cpusleep} \ + %{?_with_cpu} \ %{?_with_csv} \ - %{?_with_curl} \ %{?_with_curl_json} \ %{?_with_curl_xml} \ + %{?_with_curl} \ %{?_with_dbi} \ + %{?_with_dcpmm} \ %{?_with_df} \ %{?_with_disk} \ %{?_with_dns} \ + %{?_with_drbd} \ + %{?_with_dpdkevents} \ + %{?_with_dpdkstat} \ + %{?_with_dpdk_telemetry} \ %{?_with_email} \ %{?_with_entropy} \ %{?_with_ethstat} \ %{?_with_exec} \ + %{?_with_fhcount} \ %{?_with_filecount} \ %{?_with_fscache} \ %{?_with_gmond} \ + %{?_with_gps} \ + %{?_with_grpc} \ %{?_with_hddtemp} \ + %{?_with_hugepages} \ + %{?_with_intel_pmu} \ + %{?_with_intel_rdt} \ %{?_with_interface} \ + %{?_with_ipc} \ %{?_with_ipmi} \ + %{?_with_ipstats} \ %{?_with_iptables} \ %{?_with_ipvs} \ + %{?_with_irq} \ %{?_with_java} \ - %{?_with_libvirt} \ + %{?_with_load} \ + %{?_with_log_logstash} \ + %{?_with_logfile} \ %{?_with_lpar} \ + %{?_with_lua} \ + --disable-lvm \ + %{?_with_madwifi} \ + %{?_with_mbmon} \ + %{?_with_mcelog} \ + %{?_with_md} \ %{?_with_memcachec} \ + %{?_with_memcached} \ + %{?_with_memory} \ + %{?_with_mic} \ %{?_with_modbus} \ + %{?_with_mqtt} \ %{?_with_multimeter} \ %{?_with_mysql} \ %{?_with_netapp} \ %{?_with_netlink} \ + %{?_with_network} \ + %{?_with_nfs} \ %{?_with_nginx} \ %{?_with_notify_desktop} \ %{?_with_notify_email} \ + %{?_with_notify_nagios} \ + %{?_with_ntpd} \ + %{?_with_numa} \ %{?_with_nut} \ + %{?_with_olsrd} \ %{?_with_onewire} \ + %{?_with_openldap} \ + %{?_with_openvpn} \ %{?_with_oracle} \ + %{?_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_redfish} \ %{?_with_redis} \ %{?_with_routeros} \ %{?_with_rrdcached} \ %{?_with_rrdtool} \ %{?_with_sensors} \ - %{?_with_snmp} \ - %{?_with_tape} \ - %{?_with_tokyotyrant} \ - %{?_with_varnish} \ - %{?_with_write_http} \ - %{?_with_write_mongodb} \ - %{?_with_write_redis} \ - %{?_with_xmms} \ - %{?_with_zfs_arc} \ - %{?_with_irq} \ - %{?_with_load} \ - %{?_with_logfile} \ - %{?_with_madwifi} \ - %{?_with_mbmon} \ - %{?_with_md} \ - %{?_with_memcached} \ - %{?_with_memory} \ - %{?_with_network} \ - %{?_with_nfs} \ - %{?_with_ntpd} \ - %{?_with_numa} \ - %{?_with_olsrd} \ - %{?_with_openvpn} \ - %{?_with_powerdns} \ - %{?_with_processes} \ - %{?_with_protocols} \ %{?_with_serial} \ + %{?_with_sigrok} \ + %{?_with_slurm} \ + %{?_with_smart} \ + %{?_with_snmp} \ + %{?_with_snmp_agent} \ + %{?_with_statsd} \ %{?_with_swap} \ + %{?_with_synproxy} \ + %{?_with_sysevent} \ %{?_with_syslog} \ %{?_with_table} \ - %{?_with_tail} \ %{?_with_tail_csv} \ + %{?_with_tail} \ + %{?_with_tape} \ %{?_with_tcpconns} \ %{?_with_teamspeak2} \ %{?_with_ted} \ %{?_with_thermal} \ %{?_with_threshold} \ + %{?_with_tokyotyrant} \ + %{?_with_turbostat} \ %{?_with_unixsock} \ %{?_with_uptime} \ %{?_with_users} \ %{?_with_uuid} \ + %{?_with_varnish} \ + %{?_with_virt} \ %{?_with_vmem} \ %{?_with_vserver} \ %{?_with_wireless}\ %{?_with_write_graphite} \ %{?_with_write_http} \ - %{?_with_write_riemann} + %{?_with_write_http} \ + %{?_with_write_kafka} \ + %{?_with_write_log} \ + %{?_with_write_mongodb} \ + %{?_with_write_prometheus} \ + %{?_with_write_redis} \ + %{?_with_write_riemann} \ + %{?_with_write_stackdriver} \ + %{?_with_gpu_nvidia} \ + %{?_with_write_sensu} \ + %{?_with_write_syslog} \ + %{?_with_write_tsdb} \ + %{?_with_xencpu} \ + %{?_with_xmms} \ + %{?_with_zfs_arc} \ + %{?_with_zone} \ + %{?_with_zookeeper} %{__make} %{?_smp_mflags} @@ -1391,7 +2238,11 @@ Development files for libcollectdclient %install rm -rf %{buildroot} %{__make} install DESTDIR=%{buildroot} -%{__install} -Dp -m 0755 contrib/redhat/init.d-collectd %{buildroot}%{_initrddir}/collectd +%if 0%{?fedora} || 0%{?rhel} >= 7 +%{__install} -Dp -m0644 contrib/systemd.collectd.service %{buildroot}%{_unitdir}/collectd.service +%else +%{__install} -Dp -m0755 contrib/redhat/init.d-collectd %{buildroot}%{_initrddir}/collectd +%endif %{__install} -Dp -m0644 src/collectd.conf %{buildroot}%{_sysconfdir}/collectd.conf %{__install} -d %{buildroot}%{_sharedstatedir}/collectd/ %{__install} -d %{buildroot}%{_sysconfdir}/collectd.d/ @@ -1399,37 +2250,42 @@ rm -rf %{buildroot} %{__mkdir} -p %{buildroot}%{_localstatedir}/www %{__mkdir} -p %{buildroot}/%{_sysconfdir}/httpd/conf.d -%{__cp} -a contrib/collection3 %{buildroot}%{_localstatedir}/www -%{__cp} -a contrib/redhat/collection3.conf %{buildroot}/%{_sysconfdir}/httpd/conf.d/ +%{__mv} contrib/collection3 %{buildroot}%{_localstatedir}/www +%{__mv} contrib/redhat/collection3.conf %{buildroot}/%{_sysconfdir}/httpd/conf.d/ -%{__cp} -a contrib/php-collection %{buildroot}%{_localstatedir}/www -%{__cp} -a contrib/redhat/php-collection.conf %{buildroot}/%{_sysconfdir}/httpd/conf.d/ +%{__mv} contrib/php-collection %{buildroot}%{_localstatedir}/www +%{__mv} contrib/redhat/php-collection.conf %{buildroot}/%{_sysconfdir}/httpd/conf.d/ ### Clean up docs find contrib/ -type f -exec %{__chmod} a-x {} \; # *.la files shouldn't be distributed. rm -f %{buildroot}/%{_libdir}/{collectd/,}*.la -# Move the Perl examples to a separate directory. -mkdir perl-examples -find contrib -name '*.p[lm]' -exec mv {} perl-examples/ \; - # Remove Perl hidden .packlist files. find %{buildroot} -type f -name .packlist -delete # Remove Perl temporary file perllocal.pod find %{buildroot} -type f -name perllocal.pod -delete %if ! %{with_java} +rm -f %{buildroot}%{_datadir}/collectd/java/collectd-api.jar +rm -f %{buildroot}%{_datadir}/collectd/java/generic-jmx.jar rm -f %{buildroot}%{_mandir}/man5/collectd-java.5* %endif +%if ! %{with_lua} +rm -f %{buildroot}%{_mandir}/man5/collectd-lua.5* +%endif + %if ! %{with_perl} rm -f %{buildroot}%{_mandir}/man5/collectd-perl.5* rm -f %{buildroot}%{_mandir}/man3/Collectd::Unixsock.3pm* -rm -fr perl-examples/ rm -fr %{buildroot}/usr/lib/perl5/ %endif +%if ! %{with_postgresql} +rm -f %{buildroot}%{_datadir}/collectd/postgresql_default.conf +%endif + %if ! %{with_python} rm -f %{buildroot}%{_mandir}/man5/collectd-python.5* %endif @@ -1443,18 +2299,32 @@ rm -f %{buildroot}%{_mandir}/man5/collectd-snmp.5* rm -rf %{buildroot} %post -/sbin/chkconfig --add collectd +%if 0%{?fedora} || 0%{?rhel} >= 7 +%systemd_post collectd.service +%else +/sbin/chkconfig --add collectd || : +%endif %preun +%if 0%{?fedora} || 0%{?rhel} >= 7 +%systemd_preun collectd.service +%else +# stop collectd only when uninstalling if [ $1 -eq 0 ]; then - /sbin/service collectd stop &>/dev/null - /sbin/chkconfig --del collectd + /sbin/service collectd stop >/dev/null 2>&1 || : + /sbin/chkconfig --del collectd || : fi +%endif %postun -if [ $1 -ge 1 ]; then - /sbin/service collectd condrestart &>/dev/null || : +%if 0%{?fedora} || 0%{?rhel} >= 7 +%systemd_postun_with_restart collectd.service +%else +# restart collectd only when upgrading +if [ $1 -eq 1 ]; then + /sbin/service collectd condrestart >/dev/null 2>&1 || : fi +%endif %post -n libcollectdclient -p /sbin/ldconfig %postun -n libcollectdclient -p /sbin/ldconfig @@ -1463,19 +2333,17 @@ fi %files %doc AUTHORS COPYING ChangeLog README %config(noreplace) %{_sysconfdir}/collectd.conf +%if 0%{?fedora} || 0%{?rhel} >= 7 +%{_unitdir}/collectd.service +%else %{_initrddir}/collectd +%endif %{_sbindir}/collectd -%{_bindir}/collectd-nagios -%{_bindir}/collectd-tg -%{_bindir}/collectdctl %{_sbindir}/collectdmon -%{_datadir}/collectd/ +%{_datadir}/collectd/types.db %{_sharedstatedir}/collectd -%{_mandir}/man1/collectd-nagios.1* %{_mandir}/man1/collectd.1* -%{_mandir}/man1/collectdctl.1* %{_mandir}/man1/collectdmon.1* -%{_mandir}/man1/collectd-tg.1* %{_mandir}/man5/collectd-email.5* %{_mandir}/man5/collectd-exec.5* %{_mandir}/man5/collectd-threshold.5* @@ -1504,6 +2372,12 @@ fi %if %{with_battery} %{_libdir}/%{name}/battery.so %endif +%if %{with_cgroups} +%{_libdir}/%{name}/cgroups.so +%endif +%if %{with_check_uptime} +%{_libdir}/%{name}/check_uptime.so +%endif %if %{with_conntrack} %{_libdir}/%{name}/conntrack.so %endif @@ -1516,14 +2390,17 @@ fi %if %{with_cpufreq} %{_libdir}/%{name}/cpufreq.so %endif +%if %{with_cpusleep} +%{_libdir}/%{name}/cpusleep.so +%endif %if %{with_csv} %{_libdir}/%{name}/csv.so %endif %if %{with_df} %{_libdir}/%{name}/df.so %endif -%if %{with_disk} -%{_libdir}/%{name}/disk.so +%if %{with_drbd} +%{_libdir}/%{name}/drbd.so %endif %if %{with_ethstat} %{_libdir}/%{name}/ethstat.so @@ -1534,15 +2411,24 @@ fi %if %{with_exec} %{_libdir}/%{name}/exec.so %endif +%if %{with_fhcount} +%{_libdir}/%{name}/fhcount.so +%endif %if %{with_filecount} %{_libdir}/%{name}/filecount.so %endif %if %{with_fscache} %{_libdir}/%{name}/fscache.so %endif +%if %{with_hugepages} +%{_libdir}/%{name}/hugepages.so +%endif %if %{with_interface} %{_libdir}/%{name}/interface.so %endif +%if %{with_ipc} +%{_libdir}/%{name}/ipc.so +%endif %if %{with_ipvs} %{_libdir}/%{name}/ipvs.so %endif @@ -1561,6 +2447,9 @@ fi %if %{with_mbmon} %{_libdir}/%{name}/mbmon.so %endif +%if %{with_mcelog} +%{_libdir}/%{name}/mcelog.so +%endif %if %{with_md} %{_libdir}/%{name}/md.so %endif @@ -1579,6 +2468,9 @@ fi %if %{with_nfs} %{_libdir}/%{name}/nfs.so %endif +%if %{with_notify_nagios} +%{_libdir}/%{name}/notify_nagios.so +%endif %if %{with_ntpd} %{_libdir}/%{name}/ntpd.so %endif @@ -1603,9 +2495,15 @@ fi %if %{with_serial} %{_libdir}/%{name}/serial.so %endif +%if %{with_statsd} +%{_libdir}/%{name}/statsd.so +%endif %if %{with_swap} %{_libdir}/%{name}/swap.so %endif +%if %{with_synproxy} +%{_libdir}/%{name}/synproxy.so +%endif %if %{with_syslog} %{_libdir}/%{name}/syslog.so %endif @@ -1630,9 +2528,12 @@ fi %if %{with_thermal} %{_libdir}/%{name}/thermal.so %endif -%if %{with_load} +%if %{with_threshold} %{_libdir}/%{name}/threshold.so %endif +%if %{with_turbostat} +%{_libdir}/%{name}/turbostat.so +%endif %if %{with_unixsock} %{_libdir}/%{name}/unixsock.so %endif @@ -1657,7 +2558,29 @@ fi %if %{with_write_graphite} %{_libdir}/%{name}/write_graphite.so %endif - +%if %{with_write_log} +%{_libdir}/%{name}/write_log.so +%endif +%if %{with_write_syslog} +%{_libdir}/%{name}/write_syslog.so +%endif +%if %{with_write_sensu} +%{_libdir}/%{name}/write_sensu.so +%endif +%if %{with_write_tsdb} +%{_libdir}/%{name}/write_tsdb.so +%endif +%if %{with_zfs_arc} +%{_libdir}/%{name}/zfs_arc.so +%endif +%if %{with_zookeeper} +%{_libdir}/%{name}/zookeeper.so +%endif +#TODO put those in separate packages +%{_libdir}/%{name}/buddyinfo.so +%{_libdir}/%{name}/logparser.so +%{_libdir}/%{name}/ubi.so +%{_libdir}/%{name}/write_influxdb_udp.so %files -n libcollectdclient-devel %{_includedir}/collectd/client.h @@ -1665,31 +2588,72 @@ fi %{_includedir}/collectd/network_buffer.h %{_includedir}/collectd/lcc_features.h %{_libdir}/pkgconfig/libcollectdclient.pc +%{_includedir}/collectd/network_parse.h +%{_includedir}/collectd/server.h +%{_includedir}/collectd/types.h +%{_libdir}/libcollectdclient.so %files -n libcollectdclient -%{_libdir}/libcollectdclient.so %{_libdir}/libcollectdclient.so.* +%files -n collectd-utils +%{_bindir}/collectd-nagios +%{_bindir}/collectd-tg +%{_bindir}/collectdctl +%{_mandir}/man1/collectdctl.1* +%{_mandir}/man1/collectd-nagios.1* +%{_mandir}/man1/collectd-tg.1* + %if %{with_amqp} %files amqp %{_libdir}/%{name}/amqp.so %endif +%if %{with_amqp1} +%files amqp1 +%{_libdir}/%{name}/amqp1.so +%endif + %if %{with_apache} %files apache %{_libdir}/%{name}/apache.so %endif +%if %{with_aquaero} +%files aquaero +%{_libdir}/%{name}/aquaero.so +%endif + %if %{with_ascent} %files ascent %{_libdir}/%{name}/ascent.so %endif +%if %{with_barometer} +%files barometer +%{_libdir}/%{name}/barometer.so +%endif + %if %{with_bind} %files bind %{_libdir}/%{name}/bind.so %endif +%if %{with_ceph} +%files ceph +%{_libdir}/%{name}/ceph.so +%endif + +%if %{with_chrony} +%files chrony +%{_libdir}/%{name}/chrony.so +%endif + +%if %{with_connectivity} +%files connectivity +%{_libdir}/%{name}/connectivity.so +%endif + %if %{with_curl} %files curl %{_libdir}/%{name}/curl.so @@ -1705,6 +2669,11 @@ fi %{_libdir}/%{name}/curl_xml.so %endif +%if %{with_disk} +%files disk +%{_libdir}/%{name}/disk.so +%endif + %if %{with_dns} %files dns %{_libdir}/%{name}/dns.so @@ -1715,6 +2684,16 @@ fi %{_libdir}/%{name}/dbi.so %endif +%if %{with_dpdkevents} +%files dpdkevents +%{_libdir}/%{name}/dpdkevents.so +%endif + +%if %{with_dpdkstat} +%files dpdkstat +%{_libdir}/%{name}/dpdkstat.so +%endif + %if %{with_email} %files email %{_libdir}/%{name}/email.so @@ -1725,11 +2704,31 @@ fi %{_libdir}/%{name}/gmond.so %endif +%if %{with_gps} +%files gps +%{_libdir}/%{name}/gps.so +%endif + +%if %{with_grpc} +%files grpc +%{_libdir}/%{name}/grpc.so +%endif + %if %{with_hddtemp} %files hddtemp %{_libdir}/%{name}/hddtemp.so %endif +%if %{with_intel_pmu} +%files intel_pmu +%{_libdir}/%{name}/intel_pmu.so +%endif + +%if %{with_intel_rdt} +%files intel_rdt +%{_libdir}/%{name}/intel_rdt.so +%endif + %if %{with_ipmi} %files ipmi %{_libdir}/%{name}/ipmi.so @@ -1742,15 +2741,26 @@ fi %if %{with_java} %files java -%{_prefix}/share/collectd/java/collectd-api.jar -%{_prefix}/share/collectd/java/generic-jmx.jar +%{_datadir}/collectd/java/collectd-api.jar +%{_datadir}/collectd/java/generic-jmx.jar %{_libdir}/%{name}/java.so %{_mandir}/man5/collectd-java.5* %endif -%if %{with_libvirt} -%files libvirt -%{_libdir}/%{name}/libvirt.so +%if %{with_virt} +%files virt +%{_libdir}/%{name}/virt.so +%endif + +%if %{with_log_logstash} +%files log_logstash +%{_libdir}/%{name}/log_logstash.so +%endif + +%if %{with_lua} +%files lua +%{_mandir}/man5/collectd-lua* +%{_libdir}/%{name}/lua.so %endif %if %{with_memcachec} @@ -1758,11 +2768,31 @@ fi %{_libdir}/%{name}/memcachec.so %endif +%if %{with_mic} +%files mic +%{_libdir}/%{name}/mic.so +%endif + +%if %{with_modbus} +%files modbus +%{_libdir}/%{name}/modbus.so +%endif + +%if %{with_mqtt} +%files mqtt +%{_libdir}/%{name}/mqtt.so +%endif + %if %{with_mysql} %files mysql %{_libdir}/%{name}/mysql.so %endif +%if %{with_netlink} +%files netlink +%{_libdir}/%{name}/netlink.so +%endif + %if %{with_nginx} %files nginx %{_libdir}/%{name}/nginx.so @@ -1783,9 +2813,23 @@ fi %{_libdir}/%{name}/nut.so %endif +%if %{with_openldap} +%files openldap +%{_libdir}/%{name}/openldap.so +%endif + +%if %{with_ovs_events} +%files ovs_events +%{_libdir}/%{name}/ovs_events.so +%endif + +%if %{with_ovs_stats} +%files ovs_stats +%{_libdir}/%{name}/ovs_stats.so +%endif + %if %{with_perl} %files perl -%doc perl-examples/* %{perl_vendorlib}/Collectd.pm %{perl_vendorlib}/Collectd/ %{_mandir}/man3/Collectd::Unixsock.3pm* @@ -1793,6 +2837,11 @@ fi %{_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 @@ -1805,10 +2854,15 @@ fi %if %{with_postgresql} %files postgresql -%{_prefix}/share/collectd/postgresql_default.conf +%{_datadir}/collectd/postgresql_default.conf %{_libdir}/%{name}/postgresql.so %endif +%if %{with_procevent} +%files procevent +%{_libdir}/%{name}/procevent.so +%endif + %if %{with_python} %files python %{_mandir}/man5/collectd-python* @@ -1835,12 +2889,32 @@ fi %{_libdir}/%{name}/sensors.so %endif +%if %{with_sigrok} +%files sigrok +%{_libdir}/%{name}/sigrok.so +%endif + +%if %{with_smart} +%files smart +%{_libdir}/%{name}/smart.so +%endif + %if %{with_snmp} %files snmp %{_mandir}/man5/collectd-snmp.5* %{_libdir}/%{name}/snmp.so %endif +%if %{with_snmp_agent} +%files snmp_agent +%{_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 @@ -1851,6 +2925,16 @@ fi %{_libdir}/%{name}/write_http.so %endif +%if %{with_write_kafka} +%files write_kafka +%{_libdir}/%{name}/write_kafka.so +%endif + +%if %{with_write_prometheus} +%files write_prometheus +%{_libdir}/%{name}/write_prometheus.so +%endif + %if %{with_write_redis} %files write_redis %{_libdir}/%{name}/write_redis.so @@ -1861,6 +2945,31 @@ fi %{_libdir}/%{name}/write_riemann.so %endif +%if %{with_write_stackdriver} +%files write_stackdriver +%{_libdir}/%{name}/write_stackdriver.so +%endif + +%if %{with_write_syslog} +%files write_syslog +%{_libdir}/%{name}/write_syslog.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 +%endif + +%if %{with_xmms} +%files xmms +%{_libdir}/%{name}/xmms.so +%endif + %files collection3 %{_localstatedir}/www/collection3 %{_sysconfdir}/httpd/conf.d/collection3.conf @@ -1873,6 +2982,100 @@ fi %doc contrib/ %changelog +* Mon Mar 16 2020 Matthias Runge - 5.11.0-1 +- update to 5.11.0 + +* Fri Oct 18 2019 Matthias Runge - 5.10.0-1 +- update to 5.10.0 + +* Mon Oct 14 2019 Ruben Kerkhof - 5.9.2-2 +- Remove lvm plugin, liblvmapp has been deprecated upstream + +* Fri Jun 14 2019 Fabien Wernli - 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 - 5.7.1-9 +- Fix mbmon/mcelog build options + +* Thu Sep 28 2017 xakru - 5.7.1-8 +- Add new libcollectdclient/network_parse +- Add new libcollectdclient/server +- Add new libcollectdclient/types +- Add new synproxy plugin + +* Fri Aug 18 2017 Ruben Kerkhof - 5.7.1-7 +- Add new intel_pmu plugin + +* Sun Mar 05 2017 Ruben Kerkhof - 5.7.1-6 +- Move recently added plugins to subpackages + +* Sun Mar 05 2017 Ruben Kerkhof - 5.7.1-5 +- Add new ovs_stats plugin + +* Sun Mar 05 2017 Ruben Kerkhof - 5.7.1-4 +- Don't enable XFS support on RHEL6, it is missing for i386 + +* Sun Mar 05 2017 Ruben Kerkhof - 5.7.1-3 +- Add dpdkevents plugin, disabled by default + +* Wed Feb 22 2017 Ruben Kerkhof - 5.7.1-2 +- Enable XFS support in df plugin +- Fix bogus date in changelog + +* Sun Jan 01 2017 Marc Fournier - 5.7.1-1 +- New upstream version + +* Sat Dec 31 2016 Ruben Kerkhof - 5.7.0-4 +- Add new ovs_events plugin + +* Sat Dec 31 2016 Ruben Kerkhof - 5.7.0-3 +- Add new mcelog plugin + +* Tue Nov 29 2016 Ruben Kerkhof - 5.7.0-2 +- Disable redis plugin on RHEL 6, hiredis has been retired from EPEL6 + +* Mon Oct 10 2016 Marc Fournier - 5.7.0-1 +- New PRE-RELEASE version +- New plugins enabled by default: hugepages, write_prometheus +- New plugins disabled by default: dpdkstat, intel_rdt + +* Mon Oct 10 2016 Victor Demonchy - 5.6.1-1 +- New upstream version + +* Sun Aug 14 2016 Ruben Kerkhof - 5.6.0-1 +- New upstream version +- New plugins enabled by default: chrony, cpusleep, gps, lua, mqtt, notify_nagios +- New plugins disabled by default: grpc, xencpu, zone + +* Tue Jul 26 2016 Ruben Kerkhof - 5.5.2-1 +- New upstream version +- Contains fix for CVE-2016-6254 +- Change collectd.org url to https + +* Sat Jun 04 2016 Ruben Kerkhof 5.5.1-1 +- New upstream version + +* Wed May 27 2015 Marc Fournier 5.5.0-1 +- New upstream version +- New plugins enabled by default: ceph, drbd, log_logstash, write_tsdb, smart, + openldap, redis, write_redis, zookeeper, write_log, write_sensu, ipc, + turbostat, fhcount +- New plugins disabled by default: barometer, write_kafka +- Enable zfs_arc, now supported on Linux +- Install disk plugin in a dedicated package, as it depends on libudev +- use systemd on EL7, sysvinit on EL6 & EL5 +- Install collectdctl, collectd-tg and collectd-nagios in collectd-utils.rpm +- Add build-dependency on libcap-devel + +* Mon Aug 19 2013 Marc Fournier 5.4.2-1 +- New upstream version +- Build netlink plugin by default +- Enable cgroups, lvm and statsd plugins +- Enable (but don't build by default) mic, aquaero and sigrok plugins +- Enable modbus, memcachec and xmms plugins on RHEL7 + * Tue Aug 06 2013 Marc Fournier 5.3.1-1 - New upstream version - Added RHEL5 support: @@ -1882,6 +3085,14 @@ fi - Removed duplicate --enable-aggregation - Added some comments & usage examples - Replaced a couple of "Buildrequires" by "BuildRequires" +- Enabled modbus plugin on RHEL6 +- Enabled netlink plugin on RHEL6 and RHEL7 +- Allow perl plugin to build on RHEL5 +- Add support for RHEL7 +- Misc perl-related improvements: + * prevent rpmbuild from extracting dependencies from files in /usr/share/doc + * don't package collection3 and php-collection twice + * keep perl scripts from contrib/ in collectd-contrib * Wed Apr 10 2013 Marc Fournier 5.3.0-1 - New upstream version @@ -1889,7 +3100,7 @@ fi - Enabled tail_csv plugin - Installed collectd-tc manpage -* Thu Jan 11 2013 Marc Fournier 5.2.0-3 +* Fri Jan 11 2013 Marc Fournier 5.2.0-3 - remove dependency on libstatgrab, which isn't required on linux * Thu Jan 03 2013 Marc Fournier 5.2.0-2 @@ -1911,7 +3122,7 @@ fi * Sat Nov 17 2012 Ruben Kerkhof 5.1.0-2 - Move perl stuff to perl_vendorlib - Replace hardcoded paths with macros -- Remove unneccesary Requires +- Remove unnecessary Requires - Removed .a and .la files - Some other small cleanups @@ -1919,7 +3130,7 @@ fi - New upstream version - Changes to support 5.1.0 - Enabled all buildable plugins based on libraries available on EL6 + EPEL -- All plugins requiring external libraries are now shipped in seperate +- All plugins requiring external libraries are now shipped in separate packages. - No longer treat Java plugin as an exception, correctly set $JAVA_HOME during the build process + ensure build deps are installed. @@ -1937,11 +3148,11 @@ fi non-essential stuff. - Replaced BuildPrereq by BuildRequires -* Tue Jan 03 2011 Monetate 5.0.1 +* Mon Jan 03 2011 Monetate 5.0.1 - New upstream version - Changes to support 5.0.1 -* Tue Jan 04 2010 Rackspace 4.9.0 +* Mon Jan 04 2010 Rackspace 4.9.0 - New upstream version - Changes to support 4.9.0 - Added support for Java/GenericJMX plugin @@ -1959,7 +3170,7 @@ fi - New major releas - Changes to support 4.0.5 -* Wed Jan 11 2007 Iain Lea 3.11.0-0 +* Thu Jan 11 2007 Iain Lea 3.11.0-0 - fixed spec file to build correctly on fedora core - added improved init.d script to work with chkconfig - added %%post and %%postun to call chkconfig automatically @@ -1967,10 +3178,10 @@ fi * Sun Jul 09 2006 Florian octo Forster 3.10.0-1 - New upstream version -* Tue Jun 25 2006 Florian octo Forster 3.9.4-1 +* Sun Jun 25 2006 Florian octo Forster 3.9.4-1 - New upstream version -* Tue Jun 01 2006 Florian octo Forster 3.9.3-1 +* Thu Jun 01 2006 Florian octo Forster 3.9.3-1 - New upstream version * Tue May 09 2006 Florian octo Forster 3.9.2-1 @@ -1986,10 +3197,10 @@ fi - New upstream version - Added the `apache' package. -* Thu Mar 14 2006 Florian octo Forster 3.8.2-1 +* Tue Mar 14 2006 Florian octo Forster 3.8.2-1 - New upstream version -* Thu Mar 13 2006 Florian octo Forster 3.8.1-1 +* Mon Mar 13 2006 Florian octo Forster 3.8.1-1 - New upstream version * Thu Mar 09 2006 Florian octo Forster 3.8.0-1 @@ -2026,7 +3237,7 @@ fi * Sat Nov 05 2005 Florian octo Forster 3.3.0-1 - New upstream version -* Tue Oct 26 2005 Florian octo Forster 3.2.0-1 +* Wed Oct 26 2005 Florian octo Forster 3.2.0-1 - New upstream version - Added statement to remove the `*.la' files. This fixes a problem when `Unpackaged files terminate build' is in effect. @@ -2043,13 +3254,13 @@ fi * Fri Sep 16 2005 Florian octo Forster 2.1.0-1 - New upstream version -* Mon Sep 10 2005 Florian octo Forster 2.0.0-1 +* Sat Sep 10 2005 Florian octo Forster 2.0.0-1 - New upstream version * Mon Aug 29 2005 Florian octo Forster 1.8.0-1 - New upstream version -* Sun Aug 25 2005 Florian octo Forster 1.7.0-1 +* Thu Aug 25 2005 Florian octo Forster 1.7.0-1 - New upstream version * Sun Aug 21 2005 Florian octo Forster 1.6.0-1 diff --git a/contrib/redhat/init.d-collectd b/contrib/redhat/init.d-collectd index abdb168f15..829eda5fcd 100644 --- a/contrib/redhat/init.d-collectd +++ b/contrib/redhat/init.d-collectd @@ -21,6 +21,8 @@ COLLECTD=/usr/sbin/collectd COLLECTDMONPIDDIR="/var/run" COLLECTDMONPID="$COLLECTDMONPIDDIR/collectdmon.pid" +MAXWAIT=30 + if [ -r /etc/sysconfig/$service ]; then . /etc/sysconfig/$service fi @@ -40,7 +42,6 @@ check_config() { return 0 } - start () { echo -n $"Starting collectd: " check_config @@ -56,13 +57,28 @@ start () { [ $RETVAL -eq 0 ] && touch /var/lock/subsys/$service fi } + stop () { echo -n $"Stopping collectd: " - killproc -p $COLLECTDMONPID $prog + killproc -p $COLLECTDMONPID -d $MAXWAIT $prog RETVAL=$? echo [ $RETVAL -eq 0 ] && rm -f /var/lock/subsys/$service } + +restart () { + check_config + rc="$?" + if test "$rc" -ne 0; then + RETVAL=6 + echo $"not restarting due to configuration error" + failure $"not restarting $service due to configuration error" + else + stop + start + fi +} + # See how we were called. case "$1" in start) @@ -75,16 +91,7 @@ case "$1" in status -p $COLLECTDMONPID $prog ;; restart|reload) - check_config - rc="$?" - if test "$rc" -ne 0; then - RETVAL=6 - echo $"not restarting due to configuration error" - failure $"not restarting $service due to configuration error" - else - stop - start - fi + restart ;; condrestart) [ -f /var/lock/subsys/$service ] && restart || : diff --git a/contrib/sles10.1/collectd.spec b/contrib/sles10.1/collectd.spec index 2d558bdb22..82d709a6c7 100644 --- a/contrib/sles10.1/collectd.spec +++ b/contrib/sles10.1/collectd.spec @@ -14,7 +14,7 @@ Vendor: Florian octo Forster %description collectd is a small daemon written in C for performance. It reads various -system statistics and updates RRD files, creating them if neccessary. +system statistics and updates RRD files, creating them if necessary. Since the daemon doesn't need to startup every time it wants to update the files it's very fast and easy on the system. Also, the statistics are very fine grained since the files are updated every 10 seconds. diff --git a/contrib/snmp-probe-host.px b/contrib/snmp-probe-host.px index d1a7a88616..9776af6265 100755 --- a/contrib/snmp-probe-host.px +++ b/contrib/snmp-probe-host.px @@ -306,9 +306,9 @@ snmp-probe-host.px - Find out what information an SNMP device provides. The C script can be used to automatically generate SNMP configuration snippets for collectd's snmp plugin (see L). -This script parses the collectd configuration and detecs all "data" blocks that +This script parses the collectd configuration and detects all "data" blocks that are defined for the SNMP plugin. It then queries the device specified on the -command line for all OIDs and registeres which OIDs could be answered correctly +command line for all OIDs and registers which OIDs could be answered correctly and which resulted in an error. With that information the script figures out which "data" blocks can be used with this hosts and prints an appropriate "host" block to standard output. diff --git a/contrib/systemd.collectd.service b/contrib/systemd.collectd.service new file mode 100644 index 0000000000..fe535bfe86 --- /dev/null +++ b/contrib/systemd.collectd.service @@ -0,0 +1,41 @@ +[Unit] +Description=Collectd statistics daemon +Documentation=man:collectd(1) man:collectd.conf(5) +After=local-fs.target network-online.target +Requires=local-fs.target network-online.target + +[Service] +ExecStart=/usr/sbin/collectd +EnvironmentFile=-/etc/sysconfig/collectd +EnvironmentFile=-/etc/default/collectd + +# A few plugins won't work without some privileges, which you'll have to +# specify using the CapabilityBoundingSet directive below. +# +# Here's a (incomplete) list of the plugins known capability requirements: +# ceph CAP_DAC_OVERRIDE +# dns CAP_NET_RAW +# exec CAP_SETUID CAP_SETGID +# intel_rdt CAP_SYS_RAWIO +# intel_pmu CAP_SYS_ADMIN +# iptables CAP_NET_ADMIN +# ping CAP_NET_RAW +# processes CAP_NET_ADMIN (CollectDelayAccounting only) +# smart CAP_SYS_RAWIO +# turbostat CAP_SYS_RAWIO +# +# Example, if you use the iptables plugin alongside the dns or ping plugin: +#CapabilityBoundingSet=CAP_NET_RAW CAP_NET_ADMIN +# +# By default, drop all capabilities: +CapabilityBoundingSet= + +# Tell systemd it will receive a notification from collectd over its control +# socket once the daemon is ready. See systemd.service(5) for more details. +Type=notify + +# Restart the collectd daemon when it fails. +Restart=on-failure + +[Install] +WantedBy=multi-user.target diff --git a/contrib/upstart.collectd.conf b/contrib/upstart.collectd.conf index 1c7fd9c732..f833edf63f 100644 --- a/contrib/upstart.collectd.conf +++ b/contrib/upstart.collectd.conf @@ -20,6 +20,7 @@ stop on runlevel [!2345] # these cannot be started at boot time by the system without # arcane trickery. Also a root user will not see these tasks/jobs # by default. set*id is a reasonable and secure compromise. +# These options are not supported on early upstart versions. #setuid nobody #setgid nobody @@ -31,17 +32,20 @@ stop on runlevel [!2345] # shell commands via `sh -e`. env DAEMON=/usr/sbin/collectd -# Tell upstart to watch for forking when tracking the pid for us. -expect fork +# Tell upstart to wait for collectd to SIGSTOP itself, signaling it is ready +# to run. Warning: this only works with collectd 5.5 and newer. You'll have to +# use "expect fork" instead, if using collectd 5.4 and older. +expect stop # prevent thrashing - 10 restarts in 5 seconds respawn respawn limit 10 5 -# Make a log available in /var/log/upstart/collectd.log -console log +# Uncomment to make a log available in /var/log/upstart/collectd.log +# (not supported on early upstart versions). +#console log # The daemon will not start if the configuration is invalid. pre-start exec $DAEMON -t -# Let's Fork! +# Let's start! exec $DAEMON diff --git a/contrib/wiki2changelog.pl b/contrib/wiki2changelog.pl new file mode 100755 index 0000000000..e6affa5d8d --- /dev/null +++ b/contrib/wiki2changelog.pl @@ -0,0 +1,75 @@ +#!/usr/bin/perl + +use strict; +use warnings; + +=head1 NAME + +wiki2changelog.pl + +=head1 DESCRIPTION + +This script takes the change log from one of the "Version x.y" pages in +collectd's wiki and converts it to the format used by the "ChangeLog" file. +This is usually done as part of the release process. + +=cut + +our $TextWidth = 80; + +sub format_entry +{ + my $in = shift; + my $out = ''; + + my $line = "\t*"; + my $line_len = 9; + + for (split (' ', $in)) { + my $word = $_; + my $word_len = 1 + length $word; + + if (($line_len + $word_len) > $TextWidth) { + $out .= "$line\n"; + $line = "\t "; + $line_len = 9; + } + + $line .= " $word"; + $line_len += $word_len; + } + + if ($line_len != 9) { + $out .= "$line\n"; + } + + return $out; +} + +while (<>) +{ + chomp; + my $line = $_; + + if ($line =~ m#^\* (.*)#) { + $line = $1; + } else { + next; + } + + $line =~ s#<#<#g; + $line =~ s#>#>#g; + $line =~ s# # #g; + $line =~ s#"#"#g; + + $line =~ s#\{\{Plugin\|([^}]+)\}\}#$1 plugin#g; + $line =~ s@\{\{Issue\|([^}]+)\}\}@#$1@g; + $line =~ s#\[\[[^|\]]+\|([^\]]+)\]\]#$1#g; + $line =~ s#\[\[([^|\]]+)\]\]#$1#g; + + $line =~ s#'''(.*?)'''#*$1*#g; + $line =~ s#''(.*?)''#$1#g; + $line =~ s#(.*?)#"$1"#gi; + + print format_entry($line); +} diff --git a/docs/BUILD.dpdkstat.md b/docs/BUILD.dpdkstat.md new file mode 100644 index 0000000000..457fc0fa30 --- /dev/null +++ b/docs/BUILD.dpdkstat.md @@ -0,0 +1,232 @@ +# The dpdkstat plugin + +This plugin is optional and only has a specific use case: monitoring DPDK applications +that don't expose stats in any other way than the DPDK xstats API. + +**Data Plane Development Kit** (DPDK) is a set of drivers and libraries for fast +packet processing. Please note that this plugin is a polling based plugin rather +than an events based plugin (using it will drive up core utilization on a system). + +**PLEASE DO NOT USE THIS PLUGIN FOR OVS-DPDK**. dpdkstat is really for DPDK +applications that have no other way of exposing stats. For OVS or OVS-with-DPDK the +Open vSwitch plugins available in collectd 5.8.0 should be used for +collecting stats and events. In addition the OVS plugin is events based rather +than polling based and will have a smaller footprint on the system. + +## Summary + +The *dpdkstat plugin* has the following requirements: + + * DPDK 16.04 or later + * GCC 4.9 or later + +You can also build with GCC 4.8 (e.g. Ubuntu 14.04) if you specify the SSSE3 +instruction set manually: + + make -j CFLAGS+='-mssse3' + +## Building DPDK + + * Setup the build environment: + + Ensure that you have GCC 4.9 or later. Ubuntu 14.04, for example, has GCC + 4.8 by default and requires an upgrade: + + add-apt-repository ppa:ubuntu-toolchain-r/test + apt-get update + apt-get install gcc-4.9 + + If you know that the platform that you wish to run collectd on supports the + SSSE3 instruction set, GCC 4.8 also works if you enable SSSE3 manually: + + make -j CFLAGS+='-mssse3' + + * Clone DPDK: + + git clone git://dpdk.org/dpdk + + * Checkout the [DPDK system + requirements](http://dpdk.org/doc/guides/linux_gsg/sys_reqs.html) and make + sure you have the required tools and hugepage setup as specified there. + + **Note:** It's recommended to use the 1GB hugepage setup for best + performance, please follow the instruction for "Reserving Hugepages for DPDK + Use" in the link above. + + However if you plan on configuring 2MB hugepages on the fly please ensure to + add appropriate commands to reserve hugepages in a system startup script if + collectd is booted at system startup time. These commands include: + + mkdir -p /mnt/huge + mount -t hugetlbfs nodev /mnt/huge + echo 64 > /sys/devices/system/node/node0/hugepages/hugepages-2048kB/nr_hugepages + + * To configure the DPDK build for the combined shared library and enable autoload + of pmd drivers modify `config/common_base` in your DPDK as follows + + # + # Compile to share library + # + -CONFIG_RTE_BUILD_SHARED_LIB=n + +CONFIG_RTE_BUILD_SHARED_LIB=y + + # Default driver path (or "" to disable) + -CONFIG_RTE_EAL_PMD_PATH="" + +CONFIG_RTE_EAL_PMD_PATH="/usr/lib/dpdk-pmd/" + + * Prepare the configuration for the appropriate target as specified at: + http://dpdk.org/doc/guides/linux_gsg/build_dpdk.html. + + For example: + + make config T=x86_64-native-linuxapp-gcc + + * Build the target: + + make + + * Install DPDK to `/usr` + + sudo make install prefix=/usr + + * Create dpdk-pmd folder + + mkdir -p /usr/lib/dpdk-pmd + + * Create symlinks to pmd drivers + + find /usr/lib -type f -name 'librte_pmd*' | while read path ; do ln -s $path /usr/lib/dpdk-pmd/`echo $path | grep -o 'librte_.*so'` ; done + + **Note 1:** You must run make install as the configuration of collectd with + DPDK expects DPDK to be installed somewhere. + + **Note 2:** If you don't specify a prefix then DPDK will be installed in + `/usr/local/`. + + **Note 3:** If you are not root then use sudo to make install DPDK to the + appropriate location. + + **Note 4:** You **MUST** create symlink to a NIC driver lib. This way collectd + will be able to work with device bound to dpdk. + + * Check that the DPDK library has been installed in `/usr/lib` or `/lib`: + + ls /usr/lib | grep dpdk + + * Bind the interfaces to use with dpdkstat to DPDK: + + DPDK devices can be setup with either the VFIO (for DPDK 1.7+) or UIO + modules. + + **Note:** UIO requires inserting an out of tree driver `igb_uio.ko` that is + available in DPDK. + + **UIO Setup:** + + * Insert `uio.ko`: + + sudo modprobe uio + + * Insert `igb_uio.ko`: + + sudo insmod $DPDK_BUILD/kmod/igb_uio.ko + + * Bind network device to `igb_uio`: + + sudo $DPDK_DIR/tools/dpdk_nic_bind.py --bind=igb_uio eth1 + + **VFIO Setup:** + + * VFIO needs to be supported in the kernel and the BIOS. More information + can be found at: http://dpdk.org/doc/guides/linux_gsg/build_dpdk.html. + * Insert the `vfio-pci.ko` module: + + modprobe vfio-pci + + * Set the correct permissions for the VFIO device: + + sudo /usr/bin/chmod a+x /dev/vfio + sudo /usr/bin/chmod 0666 /dev/vfio/* + + * Bind the network device to `vfio-pci`: + + sudo $DPDK_DIR/tools/dpdk_nic_bind.py --bind=vfio-pci eth1 + + **Note:** Please ensure to add appropriate commands to bind the network + interfaces to DPDK in a system startup script if collectd is booted at + system startup time. + + * Run `ldconfig` to update the shared library cache. + +## Build collectd with DPDK + +**Note:** DPDK 16.04 is the minimum version and currently supported version of +DPDK required for the dpdkstat plugin. This is to allow the plugin to take +advantage of functions added to detect if the DPDK primary process is alive. + + +**Note:** The *Address-Space Layout Randomization* (ASLR) security feature in +Linux should be disabled, in order for the same hugepage memory mappings to be +present in all DPDK multi-process applications. Note that this has security +implications. + + * To disable ASLR: + + echo 0 > /proc/sys/kernel/randomize_va_space + + * To fully enable ASLR: + + echo 2 > /proc/sys/kernel/randomize_va_space + +See also: http://dpdk.org/doc/guides/prog_guide/multi_proc_support.html + + * Generate the build script as specified below. (i.e. run `build.sh`). + * Configure collectd with the DPDK shared library. If DPDK is installed in + custom installation path you can specify headers include path using + LIBDPDK_CPPFLAGS variable and libraries path with LIBDPDK_LDFLAGS. + Example: + + ./configure + + or for custom DPKD installation: + + ./configure LIBDPDK_CPPFLAGS="-I/home/joe/include/dpdk" LIBDPDK_LDFLAGS="-L/home/joe/usr/lib" + + * Make sure that libdpdk and dpdkstat are enabled in the *configure* output. + + Expected output: + + Libraries: + ... + libdpdk . . . . . . . . yes + + Modules: + ... + dpdkstat . . . . . . .yes + + * Build collectd: + + make -j && make -j install + + **Note:** As mentioned above, if you are building on Ubuntu 14.04 with + GCC <= 4.8.X, you need to use: + + make -j CFLAGS+='-mssse3' && make -j install + +## Caveats + + * The same PCI device configuration should be passed to the primary process as + the secondary process uses the same port indexes as the primary. + * A blacklist / whitelist of NICs isn't supported yet. + * Plugin initialization time depends on read interval. It requires 5 read + cycles to set up internal buffers and states. During that time no statistics + are submitted. + * If number of DPDK ports is increased while plugin is running, internal + buffers are resized. That requires 3 read cycles and no port statistics + are submitted in that time. + +## License + +The *dpdkstat plugin* is copyright (c) 2016 *Intel Corporation* and licensed +under the *MIT license*. Full licensing terms can be found in the file +`COPYING`. diff --git a/docs/BUILD.java.md b/docs/BUILD.java.md new file mode 100644 index 0000000000..2f4c0c29d8 --- /dev/null +++ b/docs/BUILD.java.md @@ -0,0 +1,50 @@ +# Building with Java + +This file gives some background and hints how the *java plugin* needs to be +configured. + +## Dependencies + +The *java plugin* requires a version of Java with *Java Native Interface* (JNI) +**1.2** or later. + +## Configure and flags + +To determine the location of the required files of a Java installation is not an +easy task, because the locations vary with your kernel (Linux, SunOS, …) and +with your architecture (x86, SPARC, …) and there is no `java-config` script we +could use. Configuration of the JVM library is therefore a bit tricky. + +The easiest way to use the `--with-java="${JAVA_HOME}"` option, where +`JAVA_HOME` is usually something like: + + /usr/lib/jvm/java-1.5.0-sun-1.5.0.14 + +The configure script will then use *find(1)* to look for the following files: + + * `jni.h` + * `jni_md.h` + * `libjvm.so` + +If found, appropriate CPP-flags and LD-flags are set and the following library +checks succeed. + +If this doesn't work for you, you have the possibility to specify CPP-flags, +C-flags, LD-flags and LIBS for the *java plugin* by hand, using the following +environment variables: + + * `JAVA_CPPFLAGS` + * `JAVA_CFLAGS` + * `JAVA_LDFLAGS` + * `JAVA_LIBS` + +For example (shortened for demonstration purposes): + + ./configure JAVA_CPPFLAGS="-I$JAVA_HOME/include -I$JAVA_HOME/include/linux" + +Adding `-ljvm` to JAVA_LIBS is done automatically, you don't have to do that. + +## License + +The *java plugin* is licensed under the *GNU General Public License, version 2*. +Full licensing terms can be found in the file `COPYING`. diff --git a/docs/CONTRIBUTING.md b/docs/CONTRIBUTING.md new file mode 100644 index 0000000000..ca0f40f1f2 --- /dev/null +++ b/docs/CONTRIBUTING.md @@ -0,0 +1,85 @@ +# Contribution guidelines + +Thanks for taking the time to contribute to the [collectd +project](https://collectd.org/)! This document tries to give some guidance to +make the process of contributing to *collectd* as pleasant as possible. + +## Bug reports + +Please report bugs as [GitHub +Issues](https://github.com/collectd/collectd/issues). Try to answer the +following questions: + +* Which version of *collectd* are you using? +* Which operating system (distribution) are you using at which version? +* What is the expected behavior / output? +* What is the actual (observed) behavior / output? +* How can we reproduce the problem you're having? +* If *collectd* crashes, try to get a + [stack trace](https://collectd.org/wiki/index.php/Core_file). + +Please monitor your issue for a couple of days and reply to questions. To keep +the project manageable, we have to do some housekeeping; meaning we will close +issues that have become stale. + +## Code contributions + +Please open a [GitHub Pull Request](https://github.com/collectd/collectd/pulls) +(PR) to contribute bug fixes, features, cleanups, new plugins, … Patches sent to +the mailing list have a tendency to fall through the cracks. + +* *Focus:* Fix *one thing* in your PR. The smaller your change, the faster it + will be reviewed and merged. +* *Coding style:* Please run `clang-format -style=file -i $FILE` after editing + `.c`, `.h` and `.proto` files. If you don't want to install *clang-format* + locally or your version produces a different result than the formatting + check on Github, use `contrib/format.sh` to format files using the same web + service used by our check. +* *Documentation:* New config options need to be documented in two places: the + manpage (`src/collectd.conf.pod`) and the example config + (`src/collectd.conf.in`). New plugins need to be added to the `README` file. +* *Continuous integration:* Once your PR is created, our continuous + integration environment will try to build it on a number of platforms. If + this reports a failure, please investigate and fix the problem. We will at + best do a very casual review for failing PRs. +* *Don't rebase:* Rebasing your branch destroys the review history. If a + review takes a long time, we may ask you to rebase on a more recent + *master*, but please don't do that without being asked. +* *types.db:* One of the most common mistakes made by new contributors is the + addition of (many) new *types* in the file `src/types.db`. The majority of + usecases can be met with one of the existing entries. If you plan to add new + entries to `src/types.db`, you should talk to us early in the design + process. + +### ChangeLog + +PRs need to have a one-line summary in the *PR description*. This information +is used to automatically generate release notes. If you got here after creating +the PR, you need to go to the *PR description* (shown as the first "comment" on +the PR, made by yourself) and *edit* that description. Editing a PR will +trigger the "ChangeLog" status to be updated. + +For the summary itself, follow this style: + +``` +ChangeLog: Foo plugin: A specific issue people had has been fixed. +``` + +The summary must be on a line of its own, with a "ChangeLog:" prefix at the +beginning of the line. The text should start with "Foo plugin" to give the +reader context for the information. Other common contexts are "collectd" for +the core daemon, "Build system", and "Documentation". Use past tense and +passive voice the for remainder, e.g. "a bug has been fixed", "a feature has +been added". + +Some PRs should be excluded from the release notes, e.g. changes to project +internal documentation (such as this file). Those changes are not interesting +for external users of the project and would reduce the value of the release +notes. Maintainers may use the `Unlisted Change` label to mark those PRs. + +## Other resources + +* [Mailing list](http://mailman.verplant.org/listinfo/collectd) +* [#collectd IRC channel](https://webchat.freenode.net/?channels=#collectd) + on *freenode*. +* [Old patch submission guideline](https://collectd.org/wiki/index.php/Submitting_patches) diff --git a/docs/README.virt.md b/docs/README.virt.md new file mode 100644 index 0000000000..9a63a18ae5 --- /dev/null +++ b/docs/README.virt.md @@ -0,0 +1,239 @@ +Inside the virt plugin +====================== + +Originally written: 20161111 + +Last updated: 20161124 + +This document will explain the new domain tag support introduced +in the virt plugin, and will provide one important use case for this feature. +In the reminder of this document, we consider + +* libvirt <= 2.0.0 +* QEMU <= 2.6.0 + + +Domain tags and domains partitioning across virt reader instances +----------------------------------------------------------------- + +The virt plugin gained the `Instances` option. It allows to start +more than one reader instance, so the the libvirt domains could be queried +by more than one reader thread. +The default value for `Instances` is `1`. +With default settings, the plugin will behave in a fully transparent, +backward compatible way. +It is recommended to set this value to one multiple of the +daemon `ReadThreads` value. + +Each reader instance will query only a subset of the libvirt domain. +The subset is identified as follows: + +1. Each virt reader instance is named `virt-$NUM`, where `NUM` is + the progressive order of instances. If you configure `Instances 3` + you will have `virt-0`, `virt-1`, `virt-2`. Please note: the `virt-0` + instance is special, and will always be available. +2. Each virt reader instance will iterate over all the libvirt active domains, + and will look for one `tag` attribute (see below) in the domain metadata section. +3. Each virt reader instance will take care *only* of the libvirt domains whose + tag matches with its own +4. The special `virt-0` instance will take care of all the libvirt domains with + no tags, or with tags which are not in the set \[virt-0 ... virt-$NUM\] + +Collectd will just use the domain tags, but never enforces or requires them. +It is up to an external entity, like a software management system, +to attach and manage the tags to the domain. + +Please note that unless you have such tag-aware management software, +it most likely make no sense to enable more than one reader instance on your +setup. + + +Libvirt tag metadata format +---------------------------- + +This is the snipped to be added to libvirt domains: + + + $TAG + + +it must be included in the section. + +Check the `src/virt_test.c` file for really minimal example of libvirt domains. + + +Examples +-------- + +### Example one: 10 libvirt domains named "domain-A" ... "domain-J", virt plugin with instances=5, using 5 different tags + + + libvirt domain name - tag - read instance - reason + domain-A virt-0 0 tag match + domain-B virt-1 1 tag match + domain-C virt-2 2 tag match + domain-D virt-3 3 tag match + domain-E virt-4 4 tag match + domain-F virt-0 0 tag match + domain-G virt-1 1 tag match + domain-H virt-2 2 tag match + domain-I virt-3 3 tag match + domain-J virt-4 4 tag match + + + Because the domain where properly tagged, all the read instances have even load. Please note that the the virt plugin + knows nothing, and should know nothing, about *how* the libvirt domain are tagged. This is entirely up to the + management system. + + +Example two: 10 libvirt domains named "domain-A" ... "domain-J", virt plugin with instances=3, using 5 different tags + + + libvirt domain name - tag - read instance - reason + domain-A virt-0 0 tag match + domain-B virt-1 1 tag match + domain-C virt-2 2 tag match + domain-D virt-3 0 adopted by instance #0 + domain-E virt-4 0 adopted by instance #0 + domain-F virt-0 0 rag match + domain-G virt-1 1 tag match + domain-H virt-2 2 tag match + domain-I virt-3 0 adopted by instance #0 + domain-J virt-4 0 adopted by instance #0 + + + In this case we have uneven load, but no domain is ignored. + + +### Example three: 10 libvirt domains named "domain-A" ... "domain-J", virt plugin with instances=5, using 3 different tags + + + libvirt domain name - tag - read instance - reason + domain-A virt-0 0 tag match + domain-B virt-1 1 tag match + domain-C virt-2 2 tag match + domain-D virt-0 0 tag match + domain-E virt-1 1 tag match + domain-F virt-2 2 tag match + domain-G virt-0 0 tag match + domain-H virt-1 1 tag match + domain-I virt-2 2 tag match + domain-J virt-0 0 tag match + + + Once again we have uneven load and two idle read instances, but besides that no domain is left unmonitored + + +### Example four: 10 libvirt domains named "domain-A" ... "domain-J", virt plugin with instances=5, partial tagging + + + libvirt domain name - tag - read instance - reason + domain-A virt-0 0 tag match + domain-B virt-1 1 tag match + domain-C virt-2 2 tag match + domain-D virt-0 0 tag match + domain-E 0 adopted by instance #0 + domain-F 0 adopted by instance #0 + domain-G 0 adopted by instance #0 + domain-H 0 adopted by instance #0 + domain-I 0 adopted by instance #0 + domain-J 0 adopted by instance #0 + + +The lack of tags causes uneven load, but no domain are unmonitored. + + +Possible extensions - custom tag format +--------------------------------------- + +The aformentioned approach relies on fixed tag format, `virt-$N`. The algorithm works fine with any tag, which +is just one string, compared for equality. However, using custom strings for tags creates the need for a mapping +between tags and the read instances. +This mapping needs to be updated as long as domain are created or destroyed, and the virt plugin needs to be +notified of the changes. + +This adds a significant amount of complexity, with little gain with respect to the fixed schema adopted initially. +For this reason, the introdution of dynamic, custom mapping was not implemented. + + +Dealing with datacenters: libvirt, qemu, shared storage +------------------------------------------------------- + +When used in a datacenter, QEMU is most often configured to use shared storage. This is +the default configuration of datacenter management solutions like [oVirt](http://www.ovirt.org). +The actual shared storage could be implemented on top of NFS for small installations, or most likely +ISCSI or Fiber Channel. The key takeaway is that the storage is accessed over the network, +not using e.g. the SATA or PCI bus of any given host, so any network issue could cause +one or more storage operations to delay, or to be lost entirely. + +In that case, the userspace process that requested the operation can end up in the D state, +and become unresponsive, and unkillable. + + +Dealing with unresponsive domains +--------------------------------- + +All the above considered, one robust management or monitoring application must deal with the fact that +the libvirt API can block for a long time, or forever. This is not an issue or a bug of one specific +API, but it is rather a byproduct of how libvirt and QEMU interact. + +Whenever we query more than one VM, we should take care to avoid that one blocked VM prevent other, +well behaving VMs to be queried. We don't want one rogue VM to disrupt well-behaving VMs. +Unfortunately, any way we enumerate VMs, either implicitly, using the libvirt bulk stats API, +or explicitly, listing all libvirt domains and query each one in turn, we may unpredictably encounter +one unresponsive VM. + +There are many possible approaches to deal with this issue. The virt plugin supports +a simple but effective approach partitioning the domains, as follows. + +1. The virt plugin always register one or more `read` callbacks. The `zero` read callback is guaranteed to + be always present, so it performs special duties (more details later) + Each callback will be named 'virt-$N', where `N` ranges from 0 (zero) to M-1, where M is the number of instances configured. + `M` equals to `5` by default, because this is the same default number of threads in the libvirt worker pool. +2. Each of the read callbacks queries libvirt for the list of all the active domains, and retrieves the libvirt domain metadata. + Both of those operations are safe wrt domain blocked in I/O (they affect only the libvirtd daemon). +3. Each of the read callbacks extracts the `tag` from the domain metadata using a well-known format (see below). + Each of the read callbacks discards any domain which has no tag, or whose tag doesn't match with the read callback tag. +3.a. The read callback tag equals to the read callback name, thus `virt-$N`. Remember that `virt-0` is guaranteed to be + always present. +3.b. Since the `virt-0` reader is always present, it will take care of domains with no tag, or with unrecognized tag. + One unrecognized tag is any tag which has not the scheme `virt-$N`. +4. Each read callback only samples the subset of domains with matching tag. The `virt-0` reader will possibly do more, + but worst case the load will be unbalanced, no domain will be left unsampled. + +To make this approach work, some entity must attach the tags to the libvirt domains, in such a way that all +the domains which run on a given host and insist on the same network-based storage share the same tag. +This minimizes the disruption, because when using the shared storage, if one domain becomes unresponsive because +of unavailable storage, the most likely thing to happen is that others domain using the same storage will soon become +unavailable; should the box run other libvirt domains using other network-based storage, they could be monitored +safely. + +In case of [oVirt](http://www.ovirt.org), the aforementioned tagging is performed by the host agent. + +Please note that this approach is ineffective if the host completely lose network access to the storage network. +In this case, however, no recovery is possible and no damage limitation is possible. + +Lastly, please note that if the virt plugin is configured with instances=1, it behaves exactly like before. + + +Addendum: high level overview: libvirt client, libvirt daemon, qemu +-------------------------------------------------------------------- + +Let's review how the client application (collectd + virt plugin), the libvirtd daemon and the +QEMU processes interact with each other. + +The libvirt daemon talks to QEMU using the JSON QMP protcol over one unix domain socket. +The details of the protocol are not important now, but the key part is that the protocol +is a simple request/response, meaning that libvirtd must serialize all the interactions +with the QEMU monitor, and must protects its endpoint with a lock. +No out of order request/responses are possible (e.g. no pipelining or async replies). +This means that if for any reason one QMP request could not be completed, any other caller +trying to access the QEMU monitor will block until the blocked caller returns. + +To retrieve some key informations, most notably about the block device state or the balloon +device state, the libvirtd daemon *must* use the QMP protocol. + +The QEMU core, including the handling of the QMP protocol, is single-threaded. +All the above combined make it possible for a client to block forever waiting for one QMP +request, if QEMU itself is blocked. The most likely cause of block is I/O, and this is especially +true considering how QEMU is used in a datacenter. diff --git a/docs/maintainer_guide.md b/docs/maintainer_guide.md new file mode 100644 index 0000000000..48a3804099 --- /dev/null +++ b/docs/maintainer_guide.md @@ -0,0 +1,26 @@ +## Maintainer Guide + +This document documents best practises and guidelines for *collectd* +maintainers. + +### Ideology + +As maintainer of an open-source project, you are one of the most knowledgable +people of the project's structure, best practices, goals, etc. You are most +helping the project by *facilitating change*, in other words "help contributors +make changes to the codebase." + +The most common form of helping users is doing *code reviews* and (eventually) +using your commit rights to merge the pull request. + +### Code reviews + +* Be friendly, especially with new contributors. Write "Hi" and thank them for their contribution before diving into review comments. +* Criticize code, not people. Ideally, tell the contributor a better way to do what they need. +* Clearly mark optional suggestions as such. Best practise, start your comment with *At your option: …* +* Wait for a successful run of our [continuous integration system](https://ci.collectd.org/) before merging. + +### Repository access + +You have write access to the *collectd/collectd* repository. Please use it +responsibly. diff --git a/docs/review_comments.md b/docs/review_comments.md new file mode 100644 index 0000000000..9bad458e98 --- /dev/null +++ b/docs/review_comments.md @@ -0,0 +1,96 @@ +# Code Review Comments + +This is a collection of frequent code review comments, collected here for +reference and discussed in more depth than a typical code review would allow. + +The intended use for this document is to point to it from a code review to make +a point quickly while still providing the contributor with enough information +to resolve the issue. For example, a good review comment would be: + +![Please initialize variables at declaration. Link to comment.](review_comments_example.png) + +A link to each paragraph is provided at the beginning for easy copy'n'pasting. + +## Initialize variables + +→ [https://collectd.org/review-comments#initialize-variables](https://collectd.org/review-comments#initialize-variables) + +Initialize variables when declaring them. By default, C does not initialize +local variables when they are defined. If a code path ends up reading the +variable before it is initialized, for example because a loop body is never +executed, it will read random data, causing undefined behavior. Worst case, +pointers will point to random memory causing a segmentation fault. + +**Examples:** + +```c +/* Initialize scalar with to literal: */ +int status = 0; + +/* Initialize pointer with function call: */ +char *buffer = calloc(1, buffer_size); + +/* Initialize struct with struct initializer: */ +struct addrinfo ai = { + .ai_family = AF_UNSPEC, + .ai_flags = AI_ADDRCONFIG, + .ai_socktype = SOCK_STREAM, +}; + +/* Initialize struct with zero: */ +struct stat statbuf = {0}; +``` + +In the last example, `{0}` is the universal struct initializer that, in theory, +should be able to zero-initialize any struct. In practise, however, some +compilers don't implement this correctly and will get confused when the first +member is a struct or a union. Our *continuous integration* framework will +catch these cases. + +## Define variables on first use + +→ [https://collectd.org/review-comments#define-variables-on-first-use](https://collectd.org/review-comments#define-variables-on-first-use) + +Local variables should be defined when they are first used, ideally when they +can be initialized. For example: + +```c +struct foo *f = calloc(1, sizeof(*f)); +if (f == NULL) { + return ENOMEM; +} + +/* GOOD: status defiened and initialized late. */ +int status = function_call(f); +``` + +Sometimes variables are initialized by passing a pointer to them to a function. +In that case define them as close to the function call as you can and +zero-initialize them. The function may only partially initialize a struct or +not initialize a struct at all in some circumstances. + +**Example:** + +```c +char const *path = determine_path(); + +struct stat s = {0}; +int status = stat(path, &s); +``` + +Old C standards (C89 and ealier) required variables to be defined at the +beginning of a scope block. The following *bad* style is still frequently +found: + +```c +/* BAD: local variables defined at beginning of block. */ +struct foo *f; +int status; + +f = calloc(1, sizeof(*f)); +if (f == NULL) { + return ENOMEM; +} + +status = function_call(f); +``` diff --git a/docs/review_comments_example.png b/docs/review_comments_example.png new file mode 100644 index 0000000000..81eb4582b4 Binary files /dev/null and b/docs/review_comments_example.png differ diff --git a/gnulib b/gnulib new file mode 160000 index 0000000000..2f8140bc8c --- /dev/null +++ b/gnulib @@ -0,0 +1 @@ +Subproject commit 2f8140bc8ce5501e31dcc665b42b5df64f84c20c diff --git a/m4/.gitignore b/m4/.gitignore new file mode 100644 index 0000000000..f935021a8f --- /dev/null +++ b/m4/.gitignore @@ -0,0 +1 @@ +!.gitignore diff --git a/m4/ax_compare_version.m4 b/m4/ax_compare_version.m4 new file mode 100644 index 0000000000..9c8e208ab7 --- /dev/null +++ b/m4/ax_compare_version.m4 @@ -0,0 +1,177 @@ +# =========================================================================== +# https://www.gnu.org/software/autoconf-archive/ax_compare_version.html +# =========================================================================== +# +# SYNOPSIS +# +# AX_COMPARE_VERSION(VERSION_A, OP, VERSION_B, [ACTION-IF-TRUE], [ACTION-IF-FALSE]) +# +# DESCRIPTION +# +# This macro compares two version strings. Due to the various number of +# minor-version numbers that can exist, and the fact that string +# comparisons are not compatible with numeric comparisons, this is not +# necessarily trivial to do in a autoconf script. This macro makes doing +# these comparisons easy. +# +# The six basic comparisons are available, as well as checking equality +# limited to a certain number of minor-version levels. +# +# The operator OP determines what type of comparison to do, and can be one +# of: +# +# eq - equal (test A == B) +# ne - not equal (test A != B) +# le - less than or equal (test A <= B) +# ge - greater than or equal (test A >= B) +# lt - less than (test A < B) +# gt - greater than (test A > B) +# +# Additionally, the eq and ne operator can have a number after it to limit +# the test to that number of minor versions. +# +# eq0 - equal up to the length of the shorter version +# ne0 - not equal up to the length of the shorter version +# eqN - equal up to N sub-version levels +# neN - not equal up to N sub-version levels +# +# When the condition is true, shell commands ACTION-IF-TRUE are run, +# otherwise shell commands ACTION-IF-FALSE are run. The environment +# variable 'ax_compare_version' is always set to either 'true' or 'false' +# as well. +# +# Examples: +# +# AX_COMPARE_VERSION([3.15.7],[lt],[3.15.8]) +# AX_COMPARE_VERSION([3.15],[lt],[3.15.8]) +# +# would both be true. +# +# AX_COMPARE_VERSION([3.15.7],[eq],[3.15.8]) +# AX_COMPARE_VERSION([3.15],[gt],[3.15.8]) +# +# would both be false. +# +# AX_COMPARE_VERSION([3.15.7],[eq2],[3.15.8]) +# +# would be true because it is only comparing two minor versions. +# +# AX_COMPARE_VERSION([3.15.7],[eq0],[3.15]) +# +# would be true because it is only comparing the lesser number of minor +# versions of the two values. +# +# Note: The characters that separate the version numbers do not matter. An +# empty string is the same as version 0. OP is evaluated by autoconf, not +# configure, so must be a string, not a variable. +# +# The author would like to acknowledge Guido Draheim whose advice about +# the m4_case and m4_ifvaln functions make this macro only include the +# portions necessary to perform the specific comparison specified by the +# OP argument in the final configure script. +# +# LICENSE +# +# Copyright (c) 2008 Tim Toolan +# +# Copying and distribution of this file, with or without modification, are +# permitted in any medium without royalty provided the copyright notice +# and this notice are preserved. This file is offered as-is, without any +# warranty. + +#serial 12 + +dnl ######################################################################### +AC_DEFUN([AX_COMPARE_VERSION], [ + AC_REQUIRE([AC_PROG_AWK]) + + # Used to indicate true or false condition + ax_compare_version=false + + # Convert the two version strings to be compared into a format that + # allows a simple string comparison. The end result is that a version + # string of the form 1.12.5-r617 will be converted to the form + # 0001001200050617. In other words, each number is zero padded to four + # digits, and non digits are removed. + AS_VAR_PUSHDEF([A],[ax_compare_version_A]) + A=`echo "$1" | sed -e 's/\([[0-9]]*\)/Z\1Z/g' \ + -e 's/Z\([[0-9]]\)Z/Z0\1Z/g' \ + -e 's/Z\([[0-9]][[0-9]]\)Z/Z0\1Z/g' \ + -e 's/Z\([[0-9]][[0-9]][[0-9]]\)Z/Z0\1Z/g' \ + -e 's/[[^0-9]]//g'` + + AS_VAR_PUSHDEF([B],[ax_compare_version_B]) + B=`echo "$3" | sed -e 's/\([[0-9]]*\)/Z\1Z/g' \ + -e 's/Z\([[0-9]]\)Z/Z0\1Z/g' \ + -e 's/Z\([[0-9]][[0-9]]\)Z/Z0\1Z/g' \ + -e 's/Z\([[0-9]][[0-9]][[0-9]]\)Z/Z0\1Z/g' \ + -e 's/[[^0-9]]//g'` + + dnl # In the case of le, ge, lt, and gt, the strings are sorted as necessary + dnl # then the first line is used to determine if the condition is true. + dnl # The sed right after the echo is to remove any indented white space. + m4_case(m4_tolower($2), + [lt],[ + ax_compare_version=`echo "x$A +x$B" | sed 's/^ *//' | sort -r | sed "s/x${A}/false/;s/x${B}/true/;1q"` + ], + [gt],[ + ax_compare_version=`echo "x$A +x$B" | sed 's/^ *//' | sort | sed "s/x${A}/false/;s/x${B}/true/;1q"` + ], + [le],[ + ax_compare_version=`echo "x$A +x$B" | sed 's/^ *//' | sort | sed "s/x${A}/true/;s/x${B}/false/;1q"` + ], + [ge],[ + ax_compare_version=`echo "x$A +x$B" | sed 's/^ *//' | sort -r | sed "s/x${A}/true/;s/x${B}/false/;1q"` + ],[ + dnl Split the operator from the subversion count if present. + m4_bmatch(m4_substr($2,2), + [0],[ + # A count of zero means use the length of the shorter version. + # Determine the number of characters in A and B. + ax_compare_version_len_A=`echo "$A" | $AWK '{print(length)}'` + ax_compare_version_len_B=`echo "$B" | $AWK '{print(length)}'` + + # Set A to no more than B's length and B to no more than A's length. + A=`echo "$A" | sed "s/\(.\{$ax_compare_version_len_B\}\).*/\1/"` + B=`echo "$B" | sed "s/\(.\{$ax_compare_version_len_A\}\).*/\1/"` + ], + [[0-9]+],[ + # A count greater than zero means use only that many subversions + A=`echo "$A" | sed "s/\(\([[0-9]]\{4\}\)\{m4_substr($2,2)\}\).*/\1/"` + B=`echo "$B" | sed "s/\(\([[0-9]]\{4\}\)\{m4_substr($2,2)\}\).*/\1/"` + ], + [.+],[ + AC_WARNING( + [illegal OP numeric parameter: $2]) + ],[]) + + # Pad zeros at end of numbers to make same length. + ax_compare_version_tmp_A="$A`echo $B | sed 's/./0/g'`" + B="$B`echo $A | sed 's/./0/g'`" + A="$ax_compare_version_tmp_A" + + # Check for equality or inequality as necessary. + m4_case(m4_tolower(m4_substr($2,0,2)), + [eq],[ + test "x$A" = "x$B" && ax_compare_version=true + ], + [ne],[ + test "x$A" != "x$B" && ax_compare_version=true + ],[ + AC_WARNING([illegal OP parameter: $2]) + ]) + ]) + + AS_VAR_POPDEF([A])dnl + AS_VAR_POPDEF([B])dnl + + dnl # Execute ACTION-IF-TRUE / ACTION-IF-FALSE. + if test "$ax_compare_version" = "true" ; then + m4_ifvaln([$4],[$4],[:])dnl + m4_ifvaln([$5],[else $5])dnl + fi +]) dnl AX_COMPARE_VERSION diff --git a/m4/ax_compiler_vendor.m4 b/m4/ax_compiler_vendor.m4 new file mode 100644 index 0000000000..ee24c12f7f --- /dev/null +++ b/m4/ax_compiler_vendor.m4 @@ -0,0 +1,87 @@ +# =========================================================================== +# http://www.gnu.org/software/autoconf-archive/ax_compiler_vendor.html +# =========================================================================== +# +# SYNOPSIS +# +# AX_COMPILER_VENDOR +# +# DESCRIPTION +# +# Determine the vendor of the C/C++ compiler, e.g., gnu, intel, ibm, sun, +# hp, borland, comeau, dec, cray, kai, lcc, metrowerks, sgi, microsoft, +# watcom, etc. The vendor is returned in the cache variable +# $ax_cv_c_compiler_vendor for C and $ax_cv_cxx_compiler_vendor for C++. +# +# LICENSE +# +# Copyright (c) 2008 Steven G. Johnson +# Copyright (c) 2008 Matteo Frigo +# +# 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, either version 3 of the License, or (at your +# option) any later version. +# +# 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, see . +# +# As a special exception, the respective Autoconf Macro's copyright owner +# gives unlimited permission to copy, distribute and modify the configure +# scripts that are the output of Autoconf when processing the Macro. You +# need not follow the terms of the GNU General Public License when using +# or distributing such scripts, even though portions of the text of the +# Macro appear in them. The GNU General Public License (GPL) does govern +# all other use of the material that constitutes the Autoconf Macro. +# +# This special exception to the GPL applies to versions of the Autoconf +# Macro released by the Autoconf Archive. When you make and distribute a +# modified version of the Autoconf Macro, you may extend this special +# exception to the GPL to apply to your modified version as well. + +#serial 15 + +AC_DEFUN([AX_COMPILER_VENDOR], +[AC_CACHE_CHECK([for _AC_LANG compiler vendor], ax_cv_[]_AC_LANG_ABBREV[]_compiler_vendor, + dnl Please add if possible support to ax_compiler_version.m4 + [# note: don't check for gcc first since some other compilers define __GNUC__ + vendors="intel: __ICC,__ECC,__INTEL_COMPILER + ibm: __xlc__,__xlC__,__IBMC__,__IBMCPP__ + pathscale: __PATHCC__,__PATHSCALE__ + clang: __clang__ + cray: _CRAYC + fujitsu: __FUJITSU + gnu: __GNUC__ + sun: __SUNPRO_C,__SUNPRO_CC + hp: __HP_cc,__HP_aCC + dec: __DECC,__DECCXX,__DECC_VER,__DECCXX_VER + borland: __BORLANDC__,__CODEGEARC__,__TURBOC__ + comeau: __COMO__ + kai: __KCC + lcc: __LCC__ + sgi: __sgi,sgi + microsoft: _MSC_VER + metrowerks: __MWERKS__ + watcom: __WATCOMC__ + portland: __PGI + tcc: __TINYC__ + unknown: UNKNOWN" + for ventest in $vendors; do + case $ventest in + *:) vendor=$ventest; continue ;; + *) vencpp="defined("`echo $ventest | sed 's/,/) || defined(/g'`")" ;; + esac + AC_COMPILE_IFELSE([AC_LANG_PROGRAM(,[ + #if !($vencpp) + thisisanerror; + #endif + ])], [break]) + done + ax_cv_[]_AC_LANG_ABBREV[]_compiler_vendor=`echo $vendor | cut -d: -f1` + ]) +]) diff --git a/proto/collectd.proto b/proto/collectd.proto new file mode 100644 index 0000000000..83d2128296 --- /dev/null +++ b/proto/collectd.proto @@ -0,0 +1,61 @@ +// collectd - proto/collectd.proto +// Copyright (C) 2015-2016 Sebastian Harl +// +// 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: +// Sebastian Harl + +syntax = "proto3"; + +package collectd; +option go_package = "collectd.org/rpc/proto"; + +import "types.proto"; + +service Collectd { + // PutValues reads the value lists from the PutValuesRequest stream. + // The gRPC server embedded into collectd will inject them into the system + // just like the network plugin. + rpc PutValues(stream PutValuesRequest) returns(PutValuesResponse); + + // QueryValues returns a stream of matching value lists from collectd's + // internal cache. + rpc QueryValues(QueryValuesRequest) returns(stream QueryValuesResponse); +} + +// The arguments to PutValues. +message PutValuesRequest { + // value_list is the metric to be sent to the server. + collectd.types.ValueList value_list = 1; +} + +// The response from PutValues. +message PutValuesResponse {} + +// The arguments to QueryValues. +message QueryValuesRequest { + // Query by the fields of the identifier. Only return values matching the + // specified shell wildcard patterns (see fnmatch(3)). Use '*' to match + // any value. + collectd.types.Identifier identifier = 1; +} + +// The response from QueryValues. +message QueryValuesResponse { collectd.types.ValueList value_list = 1; } diff --git a/proto/prometheus.proto b/proto/prometheus.proto new file mode 100644 index 0000000000..17adaf4d51 --- /dev/null +++ b/proto/prometheus.proto @@ -0,0 +1,72 @@ +// Copyright 2013 Prometheus Team +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +syntax = "proto2"; + +package io.prometheus.client; +option java_package = "io.prometheus.client"; + +message LabelPair { + optional string name = 1; + optional string value = 2; +} + +enum MetricType { + COUNTER = 0; GAUGE = 1; SUMMARY = 2; UNTYPED = 3; HISTOGRAM = 4; +} + +message Gauge { optional double value = 1; } + +message Counter { optional double value = 1; } + +message Quantile { + optional double quantile = 1; + optional double value = 2; +} + +message Summary { + optional uint64 sample_count = 1; + optional double sample_sum = 2; + repeated Quantile quantile = 3; +} + +message Untyped { optional double value = 1; } + +message Histogram { + optional uint64 sample_count = 1; + optional double sample_sum = 2; + repeated Bucket bucket = + 3; // Ordered in increasing order of upper_bound, +Inf bucket is optional. +} + +message Bucket { + optional uint64 cumulative_count = 1; // Cumulative in increasing order. + optional double upper_bound = 2; // Inclusive. +} + +message Metric { + repeated LabelPair label = 1; + optional Gauge gauge = 2; + optional Counter counter = 3; + optional Summary summary = 4; + optional Untyped untyped = 5; + optional Histogram histogram = 7; + optional int64 timestamp_ms = 6; +} + +message MetricFamily { + optional string name = 1; + optional string help = 2; + optional MetricType type = 3; + repeated Metric metric = 4; +} diff --git a/proto/types.proto b/proto/types.proto new file mode 100644 index 0000000000..fde3afaf76 --- /dev/null +++ b/proto/types.proto @@ -0,0 +1,70 @@ +// collectd - proto/types.proto +// Copyright (C) 2015-2016 Sebastian Harl +// +// 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: +// Sebastian Harl + +syntax = "proto3"; + +package collectd.types; +option go_package = "collectd.org/rpc/proto/types"; + +import "google/protobuf/duration.proto"; +import "google/protobuf/timestamp.proto"; + +message Identifier { + string host = 1; + string plugin = 2; + string plugin_instance = 3; + string type = 4; + string type_instance = 5; +} + +message MetadataValue { + oneof value { + string string_value = 1; + int64 int64_value = 2; + uint64 uint64_value = 3; + double double_value = 4; + bool bool_value = 5; + }; +} + +message Value { + oneof value { + uint64 counter = 1; + double gauge = 2; + int64 derive = 3; + uint64 absolute = 4; + }; +} + +message ValueList { + repeated Value values = 1; + + google.protobuf.Timestamp time = 2; + google.protobuf.Duration interval = 3; + + Identifier identifier = 4; + + repeated string ds_names = 5; + map meta_data = 6; +} \ No newline at end of file diff --git a/src/Makefile.am b/src/Makefile.am deleted file mode 100644 index 59454dc09f..0000000000 --- a/src/Makefile.am +++ /dev/null @@ -1,1549 +0,0 @@ -SUBDIRS = libcollectdclient -if BUILD_WITH_OWN_LIBOCONFIG -SUBDIRS += liboconfig -endif - -if COMPILER_IS_GCC -AM_CFLAGS = -Wall -Werror -endif - -AM_CPPFLAGS = -DPREFIX='"${prefix}"' -AM_CPPFLAGS += -DCONFIGFILE='"${sysconfdir}/${PACKAGE_NAME}.conf"' -AM_CPPFLAGS += -DLOCALSTATEDIR='"${localstatedir}"' -AM_CPPFLAGS += -DPKGLOCALSTATEDIR='"${localstatedir}/lib/${PACKAGE_NAME}"' -if BUILD_FEATURE_DAEMON -AM_CPPFLAGS += -DPIDFILE='"${localstatedir}/run/${PACKAGE_NAME}.pid"' -endif -AM_CPPFLAGS += -DPLUGINDIR='"${pkglibdir}"' -AM_CPPFLAGS += -DPKGDATADIR='"${pkgdatadir}"' - -sbin_PROGRAMS = collectd collectdmon -bin_PROGRAMS = collectd-nagios collectdctl collectd-tg - -collectd_SOURCES = collectd.c collectd.h \ - common.c common.h \ - configfile.c configfile.h \ - filter_chain.c filter_chain.h \ - meta_data.c meta_data.h \ - plugin.c plugin.h \ - utils_avltree.c utils_avltree.h \ - utils_cache.c utils_cache.h \ - utils_complain.c utils_complain.h \ - utils_heap.c utils_heap.h \ - utils_ignorelist.c utils_ignorelist.h \ - utils_llist.c utils_llist.h \ - utils_parse_option.c utils_parse_option.h \ - utils_random.c utils_random.h \ - utils_tail_match.c utils_tail_match.h \ - utils_match.c utils_match.h \ - utils_subst.c utils_subst.h \ - utils_tail.c utils_tail.h \ - utils_time.c utils_time.h \ - types_list.c types_list.h - -collectd_CPPFLAGS = $(AM_CPPFLAGS) $(LTDLINCL) -collectd_CFLAGS = $(AM_CFLAGS) -collectd_LDFLAGS = -export-dynamic -collectd_LDADD = -lm -collectd_DEPENDENCIES = - -# Link to these libraries.. -if BUILD_WITH_LIBRT -collectd_LDADD += -lrt -endif -if BUILD_WITH_LIBPOSIX4 -collectd_LDADD += -lposix4 -endif -if BUILD_WITH_LIBSOCKET -collectd_LDADD += -lsocket -endif -if BUILD_WITH_LIBRESOLV -collectd_LDADD += -lresolv -endif -if BUILD_WITH_LIBPTHREAD -collectd_LDADD += -lpthread -endif -if BUILD_WITH_LIBKSTAT -collectd_LDADD += -lkstat -endif -if BUILD_WITH_LIBDEVINFO -collectd_LDADD += -ldevinfo -endif -if BUILD_AIX -collectd_LDFLAGS += -Wl,-bexpall,-brtllib -endif - -# The daemon needs to call sg_init, so we need to link it against libstatgrab, -# too. -octo -if BUILD_WITH_LIBSTATGRAB -collectd_CFLAGS += $(BUILD_WITH_LIBSTATGRAB_CFLAGS) -collectd_LDADD += $(BUILD_WITH_LIBSTATGRAB_LDFLAGS) -endif - -if BUILD_WITH_OWN_LIBOCONFIG -collectd_LDADD += $(LIBLTDL) liboconfig/liboconfig.la -collectd_DEPENDENCIES += liboconfig/liboconfig.la -else -collectd_LDADD += -loconfig -endif - -collectdmon_SOURCES = collectdmon.c -collectdmon_CPPFLAGS = $(AM_CPPFLAGS) - -collectd_nagios_SOURCES = collectd-nagios.c -collectd_nagios_CPPFLAGS = $(AM_CPPFLAGS) -I$(top_builddir)/src/libcollectdclient/collectd -collectd_nagios_LDADD = -if BUILD_WITH_LIBSOCKET -collectd_nagios_LDADD += -lsocket -endif -if BUILD_AIX -collectd_nagios_LDADD += -lm -endif - -collectd_nagios_LDADD += libcollectdclient/libcollectdclient.la -collectd_nagios_DEPENDENCIES = libcollectdclient/libcollectdclient.la - - -collectdctl_SOURCES = collectdctl.c -collectdctl_CPPFLAGS = $(AM_CPPFLAGS) -I$(top_builddir)/src/libcollectdclient/collectd -collectdctl_LDADD = -if BUILD_WITH_LIBSOCKET -collectdctl_LDADD += -lsocket -endif -if BUILD_AIX -collectdctl_LDADD += -lm -endif -collectdctl_LDADD += libcollectdclient/libcollectdclient.la -collectdctl_DEPENDENCIES = libcollectdclient/libcollectdclient.la - -collectd_tg_SOURCES = collectd-tg.c \ - utils_heap.c utils_heap.h -collectd_tg_CPPFLAGS = $(AM_CPPFLAGS) -I$(top_builddir)/src/libcollectdclient/collectd -collectd_tg_LDADD = -if BUILD_WITH_LIBSOCKET -collectd_tg_LDADD += -lsocket -endif -if BUILD_WITH_LIBRT -collectd_tg_LDADD += -lrt -endif -if BUILD_AIX -collectd_tg_LDADD += -lm -endif -collectd_tg_LDADD += libcollectdclient/libcollectdclient.la -collectd_tg_DEPENDENCIES = libcollectdclient/libcollectdclient.la - - -pkglib_LTLIBRARIES = - -BUILT_SOURCES = -CLEANFILES = - -if BUILD_PLUGIN_AGGREGATION -pkglib_LTLIBRARIES += aggregation.la -aggregation_la_SOURCES = aggregation.c \ - utils_vl_lookup.c utils_vl_lookup.h -aggregation_la_LDFLAGS = -module -avoid-version -aggregation_la_LIBADD = -collectd_LDADD += "-dlopen" aggregation.la -collectd_DEPENDENCIES += aggregation.la -endif - -if BUILD_PLUGIN_AMQP -pkglib_LTLIBRARIES += amqp.la -amqp_la_SOURCES = amqp.c \ - utils_cmd_putval.c utils_cmd_putval.h \ - utils_format_graphite.c utils_format_graphite.h \ - utils_format_json.c utils_format_json.h -amqp_la_LDFLAGS = -module -avoid-version $(BUILD_WITH_LIBRABBITMQ_LDFLAGS) -amqp_la_CPPFLAGS = $(AM_CPPFLAGS) $(BUILD_WITH_LIBRABBITMQ_CPPFLAGS) -amqp_la_LIBADD = $(BUILD_WITH_LIBRABBITMQ_LIBS) -collectd_LDADD += "-dlopen" amqp.la -collectd_DEPENDENCIES += amqp.la -endif - -if BUILD_PLUGIN_APACHE -pkglib_LTLIBRARIES += apache.la -apache_la_SOURCES = apache.c -apache_la_LDFLAGS = -module -avoid-version -apache_la_CFLAGS = $(AM_CFLAGS) -apache_la_LIBADD = -collectd_LDADD += "-dlopen" apache.la -if BUILD_WITH_LIBCURL -apache_la_CFLAGS += $(BUILD_WITH_LIBCURL_CFLAGS) -apache_la_LIBADD += $(BUILD_WITH_LIBCURL_LIBS) -endif -collectd_DEPENDENCIES += apache.la -endif - -if BUILD_PLUGIN_APCUPS -pkglib_LTLIBRARIES += apcups.la -apcups_la_SOURCES = apcups.c -apcups_la_LDFLAGS = -module -avoid-version -apcups_la_LIBADD = -if BUILD_WITH_LIBSOCKET -apcups_la_LIBADD += -lsocket -endif -collectd_LDADD += "-dlopen" apcups.la -collectd_DEPENDENCIES += apcups.la -endif - -if BUILD_PLUGIN_APPLE_SENSORS -pkglib_LTLIBRARIES += apple_sensors.la -apple_sensors_la_SOURCES = apple_sensors.c -apple_sensors_la_LDFLAGS = -module -avoid-version -apple_sensors_la_LIBADD = -lIOKit -collectd_LDADD += "-dlopen" apple_sensors.la -collectd_DEPENDENCIES += apple_sensors.la -endif - -if BUILD_PLUGIN_AQUAERO -pkglib_LTLIBRARIES += aquaero.la -aquaero_la_SOURCES = aquaero.c -aquaero_la_LDFLAGS = -module -avoid-version -aquaero_la_CFLAGS = $(AM_CFLAGS) $(BUILD_WITH_LIBAQUAERO5_CFLAGS) -aquaero_la_LIBADD = $(BUILD_WITH_LIBAQUAERO5_LDFLAGS) -laquaero5 -collectd_LDADD += "-dlopen" aquaero.la -collectd_DEPENDENCIES += aquaero.la -endif - -if BUILD_PLUGIN_ASCENT -pkglib_LTLIBRARIES += ascent.la -ascent_la_SOURCES = ascent.c -ascent_la_LDFLAGS = -module -avoid-version -ascent_la_CFLAGS = $(AM_CFLAGS) \ - $(BUILD_WITH_LIBCURL_CFLAGS) $(BUILD_WITH_LIBXML2_CFLAGS) -ascent_la_LIBADD = $(BUILD_WITH_LIBCURL_LIBS) $(BUILD_WITH_LIBXML2_LIBS) -collectd_LDADD += "-dlopen" ascent.la -collectd_DEPENDENCIES += ascent.la -endif - -if BUILD_PLUGIN_BATTERY -pkglib_LTLIBRARIES += battery.la -battery_la_SOURCES = battery.c -battery_la_LDFLAGS = -module -avoid-version -battery_la_LIBADD = -if BUILD_WITH_LIBIOKIT -battery_la_LIBADD += -lIOKit -endif -collectd_LDADD += "-dlopen" battery.la -collectd_DEPENDENCIES += battery.la -endif - -if BUILD_PLUGIN_BIND -pkglib_LTLIBRARIES += bind.la -bind_la_SOURCES = bind.c -bind_la_LDFLAGS = -module -avoid-version -bind_la_CFLAGS = $(AM_CFLAGS) \ - $(BUILD_WITH_LIBCURL_CFLAGS) $(BUILD_WITH_LIBXML2_CFLAGS) -bind_la_LIBADD = $(BUILD_WITH_LIBCURL_LIBS) $(BUILD_WITH_LIBXML2_LIBS) -collectd_LDADD += "-dlopen" bind.la -collectd_DEPENDENCIES += bind.la -endif - -if BUILD_PLUGIN_CGROUPS -pkglib_LTLIBRARIES += cgroups.la -cgroups_la_SOURCES = cgroups.c utils_mount.c utils_mount.h -cgroups_la_LDFLAGS = -module -avoid-version -collectd_LDADD += "-dlopen" cgroups.la -collectd_DEPENDENCIES += cgroups.la -endif - -if BUILD_PLUGIN_CONNTRACK -pkglib_LTLIBRARIES += conntrack.la -conntrack_la_SOURCES = conntrack.c -conntrack_la_LDFLAGS = -module -avoid-version -collectd_LDADD += "-dlopen" conntrack.la -collectd_DEPENDENCIES += conntrack.la -endif - -if BUILD_PLUGIN_CONTEXTSWITCH -pkglib_LTLIBRARIES += contextswitch.la -contextswitch_la_SOURCES = contextswitch.c -contextswitch_la_LDFLAGS = -module -avoid-version -contextswitch_la_LIBADD = -if BUILD_WITH_PERFSTAT -contextswitch_la_LIBADD += -lperfstat -endif -collectd_LDADD += "-dlopen" contextswitch.la -collectd_DEPENDENCIES += contextswitch.la -endif - -if BUILD_PLUGIN_CPU -pkglib_LTLIBRARIES += cpu.la -cpu_la_SOURCES = cpu.c -cpu_la_CFLAGS = $(AM_CFLAGS) -cpu_la_LDFLAGS = -module -avoid-version -cpu_la_LIBADD = -if BUILD_WITH_LIBKSTAT -cpu_la_LIBADD += -lkstat -endif -if BUILD_WITH_LIBDEVINFO -cpu_la_LIBADD += -ldevinfo -endif -if BUILD_WITH_LIBSTATGRAB -cpu_la_CFLAGS += $(BUILD_WITH_LIBSTATGRAB_CFLAGS) -cpu_la_LIBADD += $(BUILD_WITH_LIBSTATGRAB_LDFLAGS) -endif -if BUILD_WITH_PERFSTAT -cpu_la_LIBADD += -lperfstat -endif -collectd_LDADD += "-dlopen" cpu.la -collectd_DEPENDENCIES += cpu.la -endif - -if BUILD_PLUGIN_CPUFREQ -pkglib_LTLIBRARIES += cpufreq.la -cpufreq_la_SOURCES = cpufreq.c -cpufreq_la_LDFLAGS = -module -avoid-version -collectd_LDADD += "-dlopen" cpufreq.la -collectd_DEPENDENCIES += cpufreq.la -endif - -if BUILD_PLUGIN_CSV -pkglib_LTLIBRARIES += csv.la -csv_la_SOURCES = csv.c -csv_la_LDFLAGS = -module -avoid-version -collectd_LDADD += "-dlopen" csv.la -collectd_DEPENDENCIES += csv.la -endif - -if BUILD_PLUGIN_CURL -pkglib_LTLIBRARIES += curl.la -curl_la_SOURCES = curl.c -curl_la_LDFLAGS = -module -avoid-version -curl_la_CFLAGS = $(AM_CFLAGS) -curl_la_LIBADD = -collectd_LDADD += "-dlopen" curl.la -if BUILD_WITH_LIBCURL -curl_la_CFLAGS += $(BUILD_WITH_LIBCURL_CFLAGS) -curl_la_LIBADD += $(BUILD_WITH_LIBCURL_LIBS) -endif -collectd_DEPENDENCIES += curl.la -endif - -if BUILD_PLUGIN_CURL_JSON -pkglib_LTLIBRARIES += curl_json.la -curl_json_la_SOURCES = curl_json.c -curl_json_la_CFLAGS = $(AM_CFLAGS) -curl_json_la_LDFLAGS = -module -avoid-version $(BUILD_WITH_LIBYAJL_LDFLAGS) -curl_json_la_CPPFLAGS = $(BUILD_WITH_LIBYAJL_CPPFLAGS) -curl_json_la_LIBADD = $(BUILD_WITH_LIBYAJL_LIBS) -if BUILD_WITH_LIBCURL -curl_json_la_CFLAGS += $(BUILD_WITH_LIBCURL_CFLAGS) -curl_json_la_LIBADD += $(BUILD_WITH_LIBCURL_LIBS) -endif -collectd_LDADD += "-dlopen" curl_json.la -collectd_DEPENDENCIES += curl_json.la -endif - -if BUILD_PLUGIN_CURL_XML -pkglib_LTLIBRARIES += curl_xml.la -curl_xml_la_SOURCES = curl_xml.c -curl_xml_la_LDFLAGS = -module -avoid-version -curl_xml_la_CFLAGS = $(AM_CFLAGS) \ - $(BUILD_WITH_LIBCURL_CFLAGS) $(BUILD_WITH_LIBXML2_CFLAGS) -curl_xml_la_LIBADD = $(BUILD_WITH_LIBCURL_LIBS) $(BUILD_WITH_LIBXML2_LIBS) -collectd_LDADD += "-dlopen" curl_xml.la -collectd_DEPENDENCIES += curl_xml.la -endif - -if BUILD_PLUGIN_DBI -pkglib_LTLIBRARIES += dbi.la -dbi_la_SOURCES = dbi.c \ - utils_db_query.c utils_db_query.h -dbi_la_CPPFLAGS = $(AM_CPPFLAGS) $(BUILD_WITH_LIBDBI_CPPFLAGS) -dbi_la_LDFLAGS = -module -avoid-version $(BUILD_WITH_LIBDBI_LDFLAGS) -dbi_la_LIBADD = $(BUILD_WITH_LIBDBI_LIBS) -collectd_LDADD += "-dlopen" dbi.la -collectd_DEPENDENCIES += dbi.la -endif - -if BUILD_PLUGIN_DF -pkglib_LTLIBRARIES += df.la -df_la_SOURCES = df.c utils_mount.c utils_mount.h -df_la_LDFLAGS = -module -avoid-version -collectd_LDADD += "-dlopen" df.la -collectd_DEPENDENCIES += df.la -endif - -if BUILD_PLUGIN_DISK -pkglib_LTLIBRARIES += disk.la -disk_la_SOURCES = disk.c -disk_la_CFLAGS = $(AM_CFLAGS) -disk_la_LDFLAGS = -module -avoid-version -disk_la_LIBADD = -if BUILD_WITH_LIBKSTAT -disk_la_LIBADD += -lkstat -endif -if BUILD_WITH_LIBDEVINFO -disk_la_LIBADD += -ldevinfo -endif -if BUILD_WITH_LIBIOKIT -disk_la_LIBADD += -lIOKit -endif -if BUILD_WITH_LIBSTATGRAB -disk_la_CFLAGS += $(BUILD_WITH_LIBSTATGRAB_CFLAGS) -disk_la_LIBADD += $(BUILD_WITH_LIBSTATGRAB_LDFLAGS) -endif -if BUILD_WITH_PERFSTAT -disk_la_LIBADD += -lperfstat -endif -collectd_LDADD += "-dlopen" disk.la -collectd_DEPENDENCIES += disk.la -endif - -if BUILD_PLUGIN_DNS -pkglib_LTLIBRARIES += dns.la -dns_la_SOURCES = dns.c utils_dns.c utils_dns.h -dns_la_LDFLAGS = -module -avoid-version -dns_la_LIBADD = -lpcap -lpthread -collectd_LDADD += "-dlopen" dns.la -collectd_DEPENDENCIES += dns.la -endif - -if BUILD_PLUGIN_EMAIL -pkglib_LTLIBRARIES += email.la -email_la_SOURCES = email.c -email_la_LDFLAGS = -module -avoid-version -email_la_LIBADD = -lpthread -collectd_LDADD += "-dlopen" email.la -collectd_DEPENDENCIES += email.la -endif - -if BUILD_PLUGIN_ENTROPY -pkglib_LTLIBRARIES += entropy.la -entropy_la_SOURCES = entropy.c -entropy_la_LDFLAGS = -module -avoid-version -collectd_LDADD += "-dlopen" entropy.la -collectd_DEPENDENCIES += entropy.la -endif - -if BUILD_PLUGIN_EXEC -pkglib_LTLIBRARIES += exec.la -exec_la_SOURCES = exec.c \ - utils_cmd_putnotif.c utils_cmd_putnotif.h \ - utils_cmd_putval.c utils_cmd_putval.h -exec_la_LDFLAGS = -module -avoid-version -exec_la_LIBADD = -lpthread -collectd_LDADD += "-dlopen" exec.la -collectd_DEPENDENCIES += exec.la -endif - -if BUILD_PLUGIN_ETHSTAT -pkglib_LTLIBRARIES += ethstat.la -ethstat_la_SOURCES = ethstat.c -ethstat_la_LDFLAGS = -module -avoid-version -collectd_LDADD += "-dlopen" ethstat.la -collectd_DEPENDENCIES += ethstat.la -endif - -if BUILD_PLUGIN_FILECOUNT -pkglib_LTLIBRARIES += filecount.la -filecount_la_SOURCES = filecount.c -filecount_la_LDFLAGS = -module -avoid-version -collectd_LDADD += "-dlopen" filecount.la -collectd_DEPENDENCIES += filecount.la -endif - -if BUILD_PLUGIN_GMOND -pkglib_LTLIBRARIES += gmond.la -gmond_la_SOURCES = gmond.c -gmond_la_CPPFLAGS = $(AM_CPPFLAGS) $(GANGLIA_CPPFLAGS) -gmond_la_LDFLAGS = -module -avoid-version $(GANGLIA_LDFLAGS) -gmond_la_LIBADD = $(GANGLIA_LIBS) -collectd_LDADD += "-dlopen" gmond.la -collectd_DEPENDENCIES += gmond.la -endif - -if BUILD_PLUGIN_HDDTEMP -pkglib_LTLIBRARIES += hddtemp.la -hddtemp_la_SOURCES = hddtemp.c -hddtemp_la_LDFLAGS = -module -avoid-version -hddtemp_la_LIBADD = -if BUILD_WITH_LIBSOCKET -hddtemp_la_LIBADD += -lsocket -endif -collectd_LDADD += "-dlopen" hddtemp.la -collectd_DEPENDENCIES += hddtemp.la -endif - -if BUILD_PLUGIN_INTERFACE -pkglib_LTLIBRARIES += interface.la -interface_la_SOURCES = interface.c -interface_la_CFLAGS = $(AM_CFLAGS) -interface_la_LDFLAGS = -module -avoid-version -interface_la_LIBADD = -collectd_LDADD += "-dlopen" interface.la -collectd_DEPENDENCIES += interface.la -if BUILD_WITH_LIBSTATGRAB -interface_la_CFLAGS += $(BUILD_WITH_LIBSTATGRAB_CFLAGS) -interface_la_LIBADD += $(BUILD_WITH_LIBSTATGRAB_LDFLAGS) -else -if BUILD_WITH_LIBKSTAT -interface_la_LIBADD += -lkstat -endif -if BUILD_WITH_LIBDEVINFO -interface_la_LIBADD += -ldevinfo -endif # BUILD_WITH_LIBDEVINFO -endif # !BUILD_WITH_LIBSTATGRAB -if BUILD_WITH_PERFSTAT -interface_la_LIBADD += -lperfstat -endif -endif # BUILD_PLUGIN_INTERFACE - -if BUILD_PLUGIN_IPTABLES -pkglib_LTLIBRARIES += iptables.la -iptables_la_SOURCES = iptables.c -iptables_la_CPPFLAGS = $(AM_CPPFLAGS) $(BUILD_WITH_LIBIPTC_CPPFLAGS) -iptables_la_LDFLAGS = -module -avoid-version $(BUILD_WITH_LIBIPTC_LDFLAGS) -iptables_la_LIBADD = -liptc -collectd_LDADD += "-dlopen" iptables.la -collectd_DEPENDENCIES += iptables.la -endif - -if BUILD_PLUGIN_IPMI -pkglib_LTLIBRARIES += ipmi.la -ipmi_la_SOURCES = ipmi.c -ipmi_la_CFLAGS = $(AM_CFLAGS) $(BUILD_WITH_OPENIPMI_CFLAGS) -ipmi_la_LDFLAGS = -module -avoid-version -ipmi_la_LIBADD = $(BUILD_WITH_OPENIPMI_LIBS) -collectd_LDADD += "-dlopen" ipmi.la -collectd_DEPENDENCIES += ipmi.la -endif - -if BUILD_PLUGIN_IPVS -pkglib_LTLIBRARIES += ipvs.la -ipvs_la_SOURCES = ipvs.c -if IP_VS_H_NEEDS_KERNEL_CFLAGS -ipvs_la_CFLAGS = $(AM_CFLAGS) $(KERNEL_CFLAGS) -endif -ipvs_la_LDFLAGS = -module -avoid-version -collectd_LDADD += "-dlopen" ipvs.la -collectd_DEPENDENCIES += ipvs.la -endif - -if BUILD_PLUGIN_IRQ -pkglib_LTLIBRARIES += irq.la -irq_la_SOURCES = irq.c -irq_la_LDFLAGS = -module -avoid-version -collectd_LDADD += "-dlopen" irq.la -collectd_DEPENDENCIES += irq.la -endif - -if BUILD_PLUGIN_JAVA -pkglib_LTLIBRARIES += java.la -java_la_SOURCES = java.c -java_la_CPPFLAGS = $(AM_CPPFLAGS) $(JAVA_CPPFLAGS) -java_la_CFLAGS = $(AM_CFLAGS) $(JAVA_CFLAGS) -java_la_LDFLAGS = -module -avoid-version $(JAVA_LDFLAGS) -java_la_LIBADD = $(JAVA_LIBS) -collectd_LDADD += "-dlopen" java.la -collectd_DEPENDENCIES += java.la -endif - -if BUILD_PLUGIN_LIBVIRT -pkglib_LTLIBRARIES += libvirt.la -libvirt_la_SOURCES = libvirt.c -libvirt_la_CFLAGS = $(AM_CFLAGS) \ - $(BUILD_WITH_LIBVIRT_CFLAGS) $(BUILD_WITH_LIBXML2_CFLAGS) -libvirt_la_LIBADD = $(BUILD_WITH_LIBVIRT_LIBS) $(BUILD_WITH_LIBXML2_LIBS) -libvirt_la_LDFLAGS = -module -avoid-version -collectd_LDADD += "-dlopen" libvirt.la -collectd_DEPENDENCIES += libvirt.la -endif - -if BUILD_PLUGIN_LOAD -pkglib_LTLIBRARIES += load.la -load_la_SOURCES = load.c -load_la_CFLAGS = $(AM_CFLAGS) -load_la_LDFLAGS = -module -avoid-version -load_la_LIBADD = -collectd_LDADD += "-dlopen" load.la -collectd_DEPENDENCIES += load.la -if BUILD_WITH_LIBSTATGRAB -load_la_CFLAGS += $(BUILD_WITH_LIBSTATGRAB_CFLAGS) -load_la_LIBADD += $(BUILD_WITH_LIBSTATGRAB_LDFLAGS) -endif # BUILD_WITH_LIBSTATGRAB -if BUILD_WITH_PERFSTAT -load_la_LIBADD += -lperfstat -endif -endif # BUILD_PLUGIN_LOAD - -if BUILD_PLUGIN_LOGFILE -pkglib_LTLIBRARIES += logfile.la -logfile_la_SOURCES = logfile.c -logfile_la_LDFLAGS = -module -avoid-version -collectd_LDADD += "-dlopen" logfile.la -collectd_DEPENDENCIES += logfile.la -endif - -if BUILD_PLUGIN_LPAR -pkglib_LTLIBRARIES += lpar.la -lpar_la_SOURCES = lpar.c -lpar_la_LDFLAGS = -module -avoid-version -collectd_LDADD += "-dlopen" lpar.la -collectd_DEPENDENCIES += lpar.la -lpar_la_LIBADD = -lperfstat -endif - -if BUILD_PLUGIN_LVM -pkglib_LTLIBRARIES += lvm.la -lvm_la_SOURCES = lvm.c -lvm_la_LDFLAGS = -module -avoid-version -lvm_la_LIBADD = $(BUILD_WITH_LIBLVM2APP_LIBS) -collectd_LDADD += "-dlopen" lvm.la -collectd_DEPENDENCIES += lvm.la -endif - -if BUILD_PLUGIN_MADWIFI -pkglib_LTLIBRARIES += madwifi.la -madwifi_la_SOURCES = madwifi.c madwifi.h -madwifi_la_LDFLAGS = -module -avoid-version -collectd_LDADD += "-dlopen" madwifi.la -collectd_DEPENDENCIES += madwifi.la -endif - -if BUILD_PLUGIN_MATCH_EMPTY_COUNTER -pkglib_LTLIBRARIES += match_empty_counter.la -match_empty_counter_la_SOURCES = match_empty_counter.c -match_empty_counter_la_LDFLAGS = -module -avoid-version -collectd_LDADD += "-dlopen" match_empty_counter.la -collectd_DEPENDENCIES += match_empty_counter.la -endif - -if BUILD_PLUGIN_MATCH_HASHED -pkglib_LTLIBRARIES += match_hashed.la -match_hashed_la_SOURCES = match_hashed.c -match_hashed_la_LDFLAGS = -module -avoid-version -collectd_LDADD += "-dlopen" match_hashed.la -collectd_DEPENDENCIES += match_hashed.la -endif - -if BUILD_PLUGIN_MATCH_REGEX -pkglib_LTLIBRARIES += match_regex.la -match_regex_la_SOURCES = match_regex.c -match_regex_la_LDFLAGS = -module -avoid-version -collectd_LDADD += "-dlopen" match_regex.la -collectd_DEPENDENCIES += match_regex.la -endif - -if BUILD_PLUGIN_MATCH_TIMEDIFF -pkglib_LTLIBRARIES += match_timediff.la -match_timediff_la_SOURCES = match_timediff.c -match_timediff_la_LDFLAGS = -module -avoid-version -collectd_LDADD += "-dlopen" match_timediff.la -collectd_DEPENDENCIES += match_timediff.la -endif - -if BUILD_PLUGIN_MATCH_VALUE -pkglib_LTLIBRARIES += match_value.la -match_value_la_SOURCES = match_value.c -match_value_la_LDFLAGS = -module -avoid-version -collectd_LDADD += "-dlopen" match_value.la -collectd_DEPENDENCIES += match_value.la -endif - -if BUILD_PLUGIN_MBMON -pkglib_LTLIBRARIES += mbmon.la -mbmon_la_SOURCES = mbmon.c -mbmon_la_LDFLAGS = -module -avoid-version -mbmon_la_LIBADD = -if BUILD_WITH_LIBSOCKET -mbmon_la_LIBADD += -lsocket -endif -collectd_LDADD += "-dlopen" mbmon.la -collectd_DEPENDENCIES += mbmon.la -endif - -if BUILD_PLUGIN_MD -pkglib_LTLIBRARIES += md.la -md_la_SOURCES = md.c -md_la_LDFLAGS = -module -avoid-version -collectd_LDADD += "-dlopen" md.la -collectd_DEPENDENCIES += md.la -endif - -if BUILD_PLUGIN_MEMCACHEC -pkglib_LTLIBRARIES += memcachec.la -memcachec_la_SOURCES = memcachec.c -memcachec_la_LDFLAGS = -module -avoid-version $(BUILD_WITH_LIBMEMCACHED_LDFLAGS) -memcachec_la_CPPFLAGS = $(BUILD_WITH_LIBMEMCACHED_CPPFLAGS) -memcachec_la_LIBADD = $(BUILD_WITH_LIBMEMCACHED_LIBS) -collectd_LDADD += "-dlopen" memcachec.la -collectd_DEPENDENCIES += memcachec.la -endif - -if BUILD_PLUGIN_MEMCACHED -pkglib_LTLIBRARIES += memcached.la -memcached_la_SOURCES = memcached.c -memcached_la_LDFLAGS = -module -avoid-version -memcached_la_LIBADD = -if BUILD_WITH_LIBSOCKET -memcached_la_LIBADD += -lsocket -endif -collectd_LDADD += "-dlopen" memcached.la -collectd_DEPENDENCIES += memcached.la -endif - -if BUILD_PLUGIN_MEMORY -pkglib_LTLIBRARIES += memory.la -memory_la_SOURCES = memory.c -memory_la_CFLAGS = $(AM_CFLAGS) -memory_la_LDFLAGS = -module -avoid-version -memory_la_LIBADD = -collectd_LDADD += "-dlopen" memory.la -collectd_DEPENDENCIES += memory.la -if BUILD_WITH_LIBKSTAT -memory_la_LIBADD += -lkstat -endif -if BUILD_WITH_LIBDEVINFO -memory_la_LIBADD += -ldevinfo -endif -if BUILD_WITH_LIBSTATGRAB -memory_la_CFLAGS += $(BUILD_WITH_LIBSTATGRAB_CFLAGS) -memory_la_LIBADD += $(BUILD_WITH_LIBSTATGRAB_LDFLAGS) -endif -if BUILD_WITH_PERFSTAT -memory_la_LIBADD += -lperfstat -endif -endif - -if BUILD_PLUGIN_MODBUS -pkglib_LTLIBRARIES += modbus.la -modbus_la_SOURCES = modbus.c -modbus_la_LDFLAGS = -module -avoid-version -modbus_la_CFLAGS = $(AM_CFLAGS) $(BUILD_WITH_LIBMODBUS_CFLAGS) -modbus_la_LIBADD = $(BUILD_WITH_LIBMODBUS_LIBS) -collectd_LDADD += "-dlopen" modbus.la -collectd_DEPENDENCIES += modbus.la -endif - -if BUILD_PLUGIN_MULTIMETER -pkglib_LTLIBRARIES += multimeter.la -multimeter_la_SOURCES = multimeter.c -multimeter_la_LDFLAGS = -module -avoid-version -collectd_LDADD += "-dlopen" multimeter.la -collectd_DEPENDENCIES += multimeter.la -endif - -if BUILD_PLUGIN_MYSQL -pkglib_LTLIBRARIES += mysql.la -mysql_la_SOURCES = mysql.c -mysql_la_LDFLAGS = -module -avoid-version -mysql_la_CFLAGS = $(AM_CFLAGS) -mysql_la_LIBADD = -collectd_LDADD += "-dlopen" mysql.la -if BUILD_WITH_LIBMYSQL -mysql_la_CFLAGS += $(BUILD_WITH_LIBMYSQL_CFLAGS) -mysql_la_LIBADD += $(BUILD_WITH_LIBMYSQL_LIBS) -endif -collectd_DEPENDENCIES += mysql.la -endif - -if BUILD_PLUGIN_NETAPP -pkglib_LTLIBRARIES += netapp.la -netapp_la_SOURCES = netapp.c -netapp_la_CPPFLAGS = $(AM_CPPFLAGS) $(LIBNETAPP_CPPFLAGS) -netapp_la_LDFLAGS = -module -avoid-version $(LIBNETAPP_LDFLAGS) -netapp_la_LIBADD = $(LIBNETAPP_LIBS) -collectd_LDADD += "-dlopen" netapp.la -collectd_DEPENDENCIES += netapp.la -endif - -if BUILD_PLUGIN_NETLINK -pkglib_LTLIBRARIES += netlink.la -netlink_la_SOURCES = netlink.c -netlink_la_LDFLAGS = -module -avoid-version -netlink_la_CFLAGS = $(AM_CFLAGS) $(BUILD_WITH_LIBMNL_CFLAGS) -netlink_la_LIBADD = $(BUILD_WITH_LIBMNL_LIBS) -collectd_LDADD += "-dlopen" netlink.la -collectd_DEPENDENCIES += netlink.la -endif - -if BUILD_PLUGIN_NETWORK -pkglib_LTLIBRARIES += network.la -network_la_SOURCES = network.c network.h \ - utils_fbhash.c utils_fbhash.h -network_la_CPPFLAGS = $(AM_CPPFLAGS) -network_la_LDFLAGS = -module -avoid-version -network_la_LIBADD = -lpthread -if BUILD_WITH_LIBSOCKET -network_la_LIBADD += -lsocket -endif -if BUILD_WITH_LIBGCRYPT -network_la_CPPFLAGS += $(GCRYPT_CPPFLAGS) -network_la_LDFLAGS += $(GCRYPT_LDFLAGS) -network_la_LIBADD += $(GCRYPT_LIBS) -endif -collectd_LDADD += "-dlopen" network.la -collectd_DEPENDENCIES += network.la -endif - -if BUILD_PLUGIN_NFS -pkglib_LTLIBRARIES += nfs.la -nfs_la_SOURCES = nfs.c -nfs_la_LDFLAGS = -module -avoid-version -collectd_LDADD += "-dlopen" nfs.la -collectd_DEPENDENCIES += nfs.la -endif - -if BUILD_PLUGIN_FSCACHE -pkglib_LTLIBRARIES += fscache.la -fscache_la_SOURCES = fscache.c -fscache_la_LDFLAGS = -module -avoid-version -collectd_LDADD += "-dlopen" fscache.la -collectd_DEPENDENCIES += fscache.la -endif - -if BUILD_PLUGIN_NGINX -pkglib_LTLIBRARIES += nginx.la -nginx_la_SOURCES = nginx.c -nginx_la_CFLAGS = $(AM_CFLAGS) -nginx_la_LIBADD = -nginx_la_LDFLAGS = -module -avoid-version -if BUILD_WITH_LIBCURL -nginx_la_CFLAGS += $(BUILD_WITH_LIBCURL_CFLAGS) -nginx_la_LIBADD += $(BUILD_WITH_LIBCURL_LIBS) -endif -collectd_LDADD += "-dlopen" nginx.la -collectd_DEPENDENCIES += nginx.la -endif - -if BUILD_PLUGIN_NOTIFY_DESKTOP -pkglib_LTLIBRARIES += notify_desktop.la -notify_desktop_la_SOURCES = notify_desktop.c -notify_desktop_la_CFLAGS = $(AM_CFLAGS) $(LIBNOTIFY_CFLAGS) -notify_desktop_la_LDFLAGS = -module -avoid-version -notify_desktop_la_LIBADD = $(LIBNOTIFY_LIBS) -collectd_LDADD += "-dlopen" notify_desktop.la -collectd_DEPENDENCIES += notify_desktop.la -endif - -if BUILD_PLUGIN_NOTIFY_EMAIL -pkglib_LTLIBRARIES += notify_email.la -notify_email_la_SOURCES = notify_email.c -notify_email_la_LDFLAGS = -module -avoid-version -notify_email_la_LIBADD = -lesmtp -lssl -lcrypto -lpthread -ldl -collectd_LDADD += "-dlopen" notify_email.la -collectd_DEPENDENCIES += notify_email.la -endif - -if BUILD_PLUGIN_NTPD -pkglib_LTLIBRARIES += ntpd.la -ntpd_la_SOURCES = ntpd.c -ntpd_la_LDFLAGS = -module -avoid-version -ntpd_la_LIBADD = -if BUILD_WITH_LIBSOCKET -ntpd_la_LIBADD += -lsocket -endif -collectd_LDADD += "-dlopen" ntpd.la -collectd_DEPENDENCIES += ntpd.la -endif - -if BUILD_PLUGIN_NUMA -pkglib_LTLIBRARIES += numa.la -numa_la_SOURCES = numa.c -numa_la_LDFLAGS = -module -avoid-version -collectd_LDADD += "-dlopen" numa.la -collectd_DEPENDENCIES += numa.la -endif - -if BUILD_PLUGIN_NUT -pkglib_LTLIBRARIES += nut.la -nut_la_SOURCES = nut.c -nut_la_CFLAGS = $(AM_CFLAGS) $(BUILD_WITH_LIBUPSCLIENT_CFLAGS) -nut_la_LDFLAGS = -module -avoid-version -nut_la_LIBADD = -lpthread $(BUILD_WITH_LIBUPSCLIENT_LIBS) -collectd_LDADD += "-dlopen" nut.la -collectd_DEPENDENCIES += nut.la -endif - -if BUILD_PLUGIN_OLSRD -pkglib_LTLIBRARIES += olsrd.la -olsrd_la_SOURCES = olsrd.c -olsrd_la_LDFLAGS = -module -avoid-version -olsrd_la_LIBADD = -if BUILD_WITH_LIBSOCKET -olsrd_la_LIBADD += -lsocket -endif -collectd_LDADD += "-dlopen" olsrd.la -collectd_DEPENDENCIES += olsrd.la -endif - -if BUILD_PLUGIN_ONEWIRE -pkglib_LTLIBRARIES += onewire.la -onewire_la_SOURCES = onewire.c -onewire_la_CFLAGS = $(AM_CFLAGS) -onewire_la_CPPFLAGS = $(BUILD_WITH_LIBOWCAPI_CPPFLAGS) -onewire_la_LIBADD = $(BUILD_WITH_LIBOWCAPI_LIBS) -onewire_la_LDFLAGS = -module -avoid-version -collectd_LDADD += "-dlopen" onewire.la -collectd_DEPENDENCIES += onewire.la -endif - -if BUILD_PLUGIN_OPENVPN -pkglib_LTLIBRARIES += openvpn.la -openvpn_la_SOURCES = openvpn.c -openvpn_la_CFLAGS = $(AM_CFLAGS) -openvpn_la_LDFLAGS = -module -avoid-version -collectd_LDADD += "-dlopen" openvpn.la -collectd_DEPENDENCIES += openvpn.la -endif - -if BUILD_PLUGIN_ORACLE -pkglib_LTLIBRARIES += oracle.la -oracle_la_SOURCES = oracle.c \ - utils_db_query.c utils_db_query.h -oracle_la_CFLAGS = $(AM_CFLAGS) -oracle_la_CPPFLAGS = $(BUILD_WITH_ORACLE_CFLAGS) -oracle_la_LIBADD = $(BUILD_WITH_ORACLE_LIBS) -oracle_la_LDFLAGS = -module -avoid-version -collectd_LDADD += "-dlopen" oracle.la -collectd_DEPENDENCIES += oracle.la -endif - -if BUILD_PLUGIN_PERL -pkglib_LTLIBRARIES += perl.la -perl_la_SOURCES = perl.c -# Despite C99 providing the "bool" type thru stdbool.h, Perl defines its own -# version of that type if HAS_BOOL is not defined... *sigh* -perl_la_CPPFLAGS = $(AM_CPPFLAGS) -DHAS_BOOL=1 -perl_la_CFLAGS = $(AM_CFLAGS) \ - $(PERL_CFLAGS) \ - -DXS_VERSION=\"$(VERSION)\" -DVERSION=\"$(VERSION)\" -# Work-around for issues #41 and #42 - Perl 5.10 incorrectly introduced -# __attribute__nonnull__(3) for Perl_load_module(). -if HAVE_BROKEN_PERL_LOAD_MODULE -perl_la_CFLAGS += -Wno-nonnull -endif -perl_la_LDFLAGS = -module -avoid-version \ - $(PERL_LDFLAGS) -collectd_LDADD += "-dlopen" perl.la -collectd_DEPENDENCIES += perl.la -endif - -if BUILD_PLUGIN_PF -pkglib_LTLIBRARIES += pf.la -pf_la_SOURCES = pf.c -pf_la_LDFLAGS = -module -avoid-version -collectd_LDADD += "-dlopen" pf.la -collectd_DEPENDENCIES += pf.la -endif - -if BUILD_PLUGIN_PINBA -pkglib_LTLIBRARIES += pinba.la -pinba_la_SOURCES = pinba.c -nodist_pinba_la_SOURCES = pinba.pb-c.c pinba.pb-c.h -pinba_la_LDFLAGS = -module -avoid-version -pinba_la_LIBADD = -lprotobuf-c -collectd_LDADD += "-dlopen" pinba.la -collectd_DEPENDENCIES += pinba.la -endif - -if BUILD_PLUGIN_PING -pkglib_LTLIBRARIES += ping.la -ping_la_SOURCES = ping.c -ping_la_CPPFLAGS = $(AM_CPPFLAGS) $(BUILD_WITH_LIBOPING_CPPFLAGS) -ping_la_LDFLAGS = -module -avoid-version $(BUILD_WITH_LIBOPING_LDFLAGS) -ping_la_LIBADD = -loping -lm -collectd_LDADD += "-dlopen" ping.la -collectd_DEPENDENCIES += ping.la -endif - -if BUILD_PLUGIN_POSTGRESQL -pkglib_LTLIBRARIES += postgresql.la -postgresql_la_SOURCES = postgresql.c \ - utils_db_query.c utils_db_query.h -postgresql_la_CPPFLAGS = $(AM_CPPFLAGS) $(BUILD_WITH_LIBPQ_CPPFLAGS) -postgresql_la_LDFLAGS = -module -avoid-version \ - $(BUILD_WITH_LIBPQ_LDFLAGS) -postgresql_la_LIBADD = -lpq -collectd_LDADD += "-dlopen" postgresql.la -collectd_DEPENDENCIES += postgresql.la -endif - -if BUILD_PLUGIN_POWERDNS -pkglib_LTLIBRARIES += powerdns.la -powerdns_la_SOURCES = powerdns.c -powerdns_la_LDFLAGS = -module -avoid-version -collectd_LDADD += "-dlopen" powerdns.la -collectd_DEPENDENCIES += powerdns.la -endif - -if BUILD_PLUGIN_PYTHON -pkglib_LTLIBRARIES += python.la -python_la_SOURCES = python.c pyconfig.c pyvalues.c cpython.h -python_la_CPPFLAGS = $(AM_CPPFLAGS) $(BUILD_WITH_PYTHON_CPPFLAGS) -python_la_CFLAGS = $(AM_CFLAGS) -if COMPILER_IS_GCC -python_la_CFLAGS += -fno-strict-aliasing -Wno-strict-aliasing -endif -python_la_LDFLAGS = -module -avoid-version $(BUILD_WITH_PYTHON_LDFLAGS) -python_la_LIBADD = $(BUILD_WITH_PYTHON_LIBS) -collectd_LDADD += "-dlopen" python.la -collectd_DEPENDENCIES += python.la -endif - -if BUILD_PLUGIN_PROCESSES -pkglib_LTLIBRARIES += processes.la -processes_la_SOURCES = processes.c -processes_la_LDFLAGS = -module -avoid-version -processes_la_LIBADD = -collectd_LDADD += "-dlopen" processes.la -collectd_DEPENDENCIES += processes.la -if BUILD_WITH_LIBKVM_GETPROCS -processes_la_LIBADD += -lkvm -endif -endif - -if BUILD_PLUGIN_PROTOCOLS -pkglib_LTLIBRARIES += protocols.la -protocols_la_SOURCES = protocols.c -protocols_la_LDFLAGS = -module -avoid-version -collectd_LDADD += "-dlopen" protocols.la -collectd_DEPENDENCIES += protocols.la -endif - -if BUILD_PLUGIN_REDIS -pkglib_LTLIBRARIES += redis.la -redis_la_SOURCES = redis.c -redis_la_LDFLAGS = -module -avoid-version $(BUILD_WITH_LIBCREDIS_LDFLAGS) -redis_la_CFLAGS = $(AM_CFLAGS) $(BUILD_WITH_LIBCREDIS_CPPFLAGS) -redis_la_LIBADD = -lcredis -collectd_LDADD += "-dlopen" redis.la -collectd_DEPENDENCIES += redis.la -endif - -if BUILD_PLUGIN_ROUTEROS -pkglib_LTLIBRARIES += routeros.la -routeros_la_SOURCES = routeros.c -routeros_la_CPPFLAGS = $(BUILD_WITH_LIBROUTEROS_CPPFLAGS) -routeros_la_LDFLAGS = -module -avoid-version $(BUILD_WITH_LIBROUTEROS_LDFLAGS) -routeros_la_LIBADD = -lrouteros -collectd_LDADD += "-dlopen" routeros.la -collectd_DEPENDENCIES += routeros.la -endif - -if BUILD_PLUGIN_RRDCACHED -pkglib_LTLIBRARIES += rrdcached.la -rrdcached_la_SOURCES = rrdcached.c utils_rrdcreate.c utils_rrdcreate.h -rrdcached_la_LDFLAGS = -module -avoid-version -rrdcached_la_CFLAGS = $(AM_CFLAGS) $(BUILD_WITH_LIBRRD_CFLAGS) -rrdcached_la_LIBADD = $(BUILD_WITH_LIBRRD_LDFLAGS) -collectd_LDADD += "-dlopen" rrdcached.la -collectd_DEPENDENCIES += rrdcached.la -endif - -if BUILD_PLUGIN_RRDTOOL -pkglib_LTLIBRARIES += rrdtool.la -rrdtool_la_SOURCES = rrdtool.c utils_rrdcreate.c utils_rrdcreate.h -rrdtool_la_LDFLAGS = -module -avoid-version -rrdtool_la_CFLAGS = $(AM_CFLAGS) $(BUILD_WITH_LIBRRD_CFLAGS) -rrdtool_la_LIBADD = $(BUILD_WITH_LIBRRD_LDFLAGS) -collectd_LDADD += "-dlopen" rrdtool.la -collectd_DEPENDENCIES += rrdtool.la -endif - -if BUILD_PLUGIN_SENSORS -pkglib_LTLIBRARIES += sensors.la -sensors_la_SOURCES = sensors.c -sensors_la_CFLAGS = $(AM_CFLAGS) $(BUILD_WITH_LIBSENSORS_CFLAGS) -sensors_la_LDFLAGS = -module -avoid-version $(BUILD_WITH_LIBSENSORS_LDFLAGS) -sensors_la_LIBADD = -lsensors -collectd_LDADD += "-dlopen" sensors.la -collectd_DEPENDENCIES += sensors.la -endif - -if BUILD_PLUGIN_SERIAL -pkglib_LTLIBRARIES += serial.la -serial_la_SOURCES = serial.c -serial_la_LDFLAGS = -module -avoid-version -collectd_LDADD += "-dlopen" serial.la -collectd_DEPENDENCIES += serial.la -endif - -if BUILD_PLUGIN_SIGROK -pkglib_LTLIBRARIES += sigrok.la -sigrok_la_SOURCES = sigrok.c -sigrok_la_CFLAGS = $(AM_CFLAGS) $(BUILD_WITH_LIBSIGROK_CFLAGS) -sigrok_la_LDFLAGS = -module -avoid-version $(BUILD_WITH_LIBSIGROK_LDFLAGS) -sigrok_la_LIBADD = -lsigrok -collectd_LDADD += "-dlopen" sigrok.la -collectd_DEPENDENCIES += sigrok.la -endif - -if BUILD_PLUGIN_SNMP -pkglib_LTLIBRARIES += snmp.la -snmp_la_SOURCES = snmp.c -snmp_la_LDFLAGS = -module -avoid-version -snmp_la_CFLAGS = $(AM_CFLAGS) -snmp_la_LIBADD = -if BUILD_WITH_LIBNETSNMP -snmp_la_CFLAGS += $(BUILD_WITH_LIBSNMP_CFLAGS) -snmp_la_LIBADD += $(BUILD_WITH_LIBSNMP_LIBS) -endif -if BUILD_WITH_LIBPTHREAD -snmp_la_LIBADD += -lpthread -endif -collectd_LDADD += "-dlopen" snmp.la -collectd_DEPENDENCIES += snmp.la -endif - -if BUILD_PLUGIN_STATSD -pkglib_LTLIBRARIES += statsd.la -statsd_la_SOURCES = statsd.c \ - utils_latency.h utils_latency.c -statsd_la_LDFLAGS = -module -avoid-version -statsd_la_LIBADD = -lpthread -collectd_LDADD += "-dlopen" statsd.la -collectd_DEPENDENCIES += statsd.la -endif - -if BUILD_PLUGIN_SWAP -pkglib_LTLIBRARIES += swap.la -swap_la_SOURCES = swap.c -swap_la_CFLAGS = $(AM_CFLAGS) -swap_la_LDFLAGS = -module -avoid-version -swap_la_LIBADD = -collectd_LDADD += "-dlopen" swap.la -collectd_DEPENDENCIES += swap.la -if BUILD_WITH_LIBKSTAT -swap_la_LIBADD += -lkstat -endif -if BUILD_WITH_LIBDEVINFO -swap_la_LIBADD += -ldevinfo -endif -if BUILD_WITH_LIBKVM_GETSWAPINFO -swap_la_LIBADD += -lkvm -endif -if BUILD_WITH_LIBSTATGRAB -swap_la_CFLAGS += $(BUILD_WITH_LIBSTATGRAB_CFLAGS) -swap_la_LIBADD += $(BUILD_WITH_LIBSTATGRAB_LDFLAGS) -endif -if BUILD_WITH_PERFSTAT -swap_la_LIBADD += -lperfstat -endif - -endif - -if BUILD_PLUGIN_SYSLOG -pkglib_LTLIBRARIES += syslog.la -syslog_la_SOURCES = syslog.c -syslog_la_LDFLAGS = -module -avoid-version -collectd_LDADD += "-dlopen" syslog.la -collectd_DEPENDENCIES += syslog.la -endif - -if BUILD_PLUGIN_TABLE -pkglib_LTLIBRARIES += table.la -table_la_SOURCES = table.c -table_la_LDFLAGS = -module -avoid-version -collectd_LDADD += "-dlopen" table.la -collectd_DEPENDENCIES += table.la -endif - -if BUILD_PLUGIN_TAIL -pkglib_LTLIBRARIES += tail.la -tail_la_SOURCES = tail.c -tail_la_LDFLAGS = -module -avoid-version -collectd_LDADD += "-dlopen" tail.la -collectd_DEPENDENCIES += tail.la -endif - -if BUILD_PLUGIN_TAIL_CSV -pkglib_LTLIBRARIES += tail_csv.la -tail_csv_la_SOURCES = tail_csv.c -tail_csv_la_LDFLAGS = -module -avoid-version -collectd_LDADD += "-dlopen" tail_csv.la -collectd_DEPENDENCIES += tail_csv.la -endif - -if BUILD_PLUGIN_TAPE -pkglib_LTLIBRARIES += tape.la -tape_la_SOURCES = tape.c -tape_la_LDFLAGS = -module -avoid-version -tape_la_LIBADD = -lkstat -ldevinfo -collectd_LDADD += "-dlopen" tape.la -collectd_DEPENDENCIES += tape.la -endif - -if BUILD_PLUGIN_TARGET_NOTIFICATION -pkglib_LTLIBRARIES += target_notification.la -target_notification_la_SOURCES = target_notification.c -target_notification_la_LDFLAGS = -module -avoid-version -collectd_LDADD += "-dlopen" target_notification.la -collectd_DEPENDENCIES += target_notification.la -endif - -if BUILD_PLUGIN_TARGET_REPLACE -pkglib_LTLIBRARIES += target_replace.la -target_replace_la_SOURCES = target_replace.c -target_replace_la_LDFLAGS = -module -avoid-version -collectd_LDADD += "-dlopen" target_replace.la -collectd_DEPENDENCIES += target_replace.la -endif - -if BUILD_PLUGIN_TARGET_SCALE -pkglib_LTLIBRARIES += target_scale.la -target_scale_la_SOURCES = target_scale.c -target_scale_la_LDFLAGS = -module -avoid-version -collectd_LDADD += "-dlopen" target_scale.la -collectd_DEPENDENCIES += target_scale.la -endif - -if BUILD_PLUGIN_TARGET_SET -pkglib_LTLIBRARIES += target_set.la -target_set_la_SOURCES = target_set.c -target_set_la_LDFLAGS = -module -avoid-version -collectd_LDADD += "-dlopen" target_set.la -collectd_DEPENDENCIES += target_set.la -endif - -if BUILD_PLUGIN_TARGET_V5UPGRADE -pkglib_LTLIBRARIES += target_v5upgrade.la -target_v5upgrade_la_SOURCES = target_v5upgrade.c -target_v5upgrade_la_LDFLAGS = -module -avoid-version -collectd_LDADD += "-dlopen" target_v5upgrade.la -collectd_DEPENDENCIES += target_v5upgrade.la -endif - -if BUILD_PLUGIN_TCPCONNS -pkglib_LTLIBRARIES += tcpconns.la -tcpconns_la_SOURCES = tcpconns.c -tcpconns_la_LDFLAGS = -module -avoid-version -tcpconns_la_LIBADD = -collectd_LDADD += "-dlopen" tcpconns.la -collectd_DEPENDENCIES += tcpconns.la -if BUILD_WITH_LIBKVM_NLIST -tcpconns_la_LIBADD += -lkvm -endif -endif - -if BUILD_PLUGIN_TEAMSPEAK2 -pkglib_LTLIBRARIES += teamspeak2.la -teamspeak2_la_SOURCES = teamspeak2.c -teamspeak2_la_LDFLAGS = -module -avoid-version -collectd_LDADD += "-dlopen" teamspeak2.la -collectd_DEPENDENCIES += teamspeak2.la -endif - -if BUILD_PLUGIN_TED -pkglib_LTLIBRARIES += ted.la -ted_la_SOURCES = ted.c -ted_la_LDFLAGS = -module -avoid-version -collectd_LDADD += "-dlopen" ted.la -collectd_DEPENDENCIES += ted.la -endif - -if BUILD_PLUGIN_THERMAL -pkglib_LTLIBRARIES += thermal.la -thermal_la_SOURCES = thermal.c -thermal_la_LDFLAGS = -module -avoid-version -collectd_LDADD += "-dlopen" thermal.la -collectd_DEPENDENCIES += thermal.la -endif - -if BUILD_PLUGIN_THRESHOLD -pkglib_LTLIBRARIES += threshold.la -threshold_la_SOURCES = threshold.c -threshold_la_LDFLAGS = -module -avoid-version -collectd_LDADD += "-dlopen" threshold.la -collectd_DEPENDENCIES += threshold.la -endif - -if BUILD_PLUGIN_TOKYOTYRANT -pkglib_LTLIBRARIES += tokyotyrant.la -tokyotyrant_la_SOURCES = tokyotyrant.c -tokyotyrant_la_CPPFLAGS = $(AM_CPPFLAGS) $(BUILD_WITH_LIBTOKYOTYRANT_CPPFLAGS) -tokyotyrant_la_LDFLAGS = -module -avoid-version $(BUILD_WITH_LIBTOKYOTYRANT_LDFLAGS) -tokyotyrant_la_LIBADD = $(BUILD_WITH_LIBTOKYOTYRANT_LIBS) -if BUILD_WITH_LIBSOCKET -tokyotyrant_la_LIBADD += -lsocket -endif -collectd_LDADD += "-dlopen" tokyotyrant.la -collectd_DEPENDENCIES += tokyotyrant.la -endif - -if BUILD_PLUGIN_UNIXSOCK -pkglib_LTLIBRARIES += unixsock.la -unixsock_la_SOURCES = unixsock.c \ - utils_cmd_flush.h utils_cmd_flush.c \ - utils_cmd_getval.h utils_cmd_getval.c \ - utils_cmd_listval.h utils_cmd_listval.c \ - utils_cmd_putval.h utils_cmd_putval.c \ - utils_cmd_putnotif.h utils_cmd_putnotif.c -unixsock_la_LDFLAGS = -module -avoid-version -unixsock_la_LIBADD = -lpthread -collectd_LDADD += "-dlopen" unixsock.la -collectd_DEPENDENCIES += unixsock.la -endif - -if BUILD_PLUGIN_UPTIME -pkglib_LTLIBRARIES += uptime.la -uptime_la_SOURCES = uptime.c -uptime_la_CFLAGS = $(AM_CFLAGS) -uptime_la_LDFLAGS = -module -avoid-version -uptime_la_LIBADD = -if BUILD_WITH_LIBKSTAT -uptime_la_LIBADD += -lkstat -endif -if BUILD_WITH_PERFSTAT -uptime_la_LIBADD += -lperfstat -endif -collectd_LDADD += "-dlopen" uptime.la -collectd_DEPENDENCIES += uptime.la -endif - -if BUILD_PLUGIN_USERS -pkglib_LTLIBRARIES += users.la -users_la_SOURCES = users.c -users_la_CFLAGS = $(AM_CFLAGS) -users_la_LDFLAGS = -module -avoid-version -users_la_LIBADD = -if BUILD_WITH_LIBSTATGRAB -users_la_CFLAGS += $(BUILD_WITH_LIBSTATGRAB_CFLAGS) -users_la_LIBADD += $(BUILD_WITH_LIBSTATGRAB_LDFLAGS) -endif -collectd_LDADD += "-dlopen" users.la -collectd_DEPENDENCIES += users.la -endif - -if BUILD_PLUGIN_UUID -pkglib_LTLIBRARIES += uuid.la -uuid_la_SOURCES = uuid.c -uuid_la_CFLAGS = $(AM_CFLAGS) $(BUILD_WITH_LIBHAL_CFLAGS) -uuid_la_LIBADD = $(BUILD_WITH_LIBHAL_LIBS) -uuid_la_LDFLAGS = -module -avoid-version -collectd_LDADD += "-dlopen" uuid.la -collectd_DEPENDENCIES += uuid.la -endif - -if BUILD_PLUGIN_MIC -pkglib_LTLIBRARIES += mic.la -mic_la_SOURCES = mic.c -mic_la_LDFLAGS = -module -avoid-version $(BUILD_WITH_MIC_LIBPATH) -mic_la_CFLAGS = $(AM_CFLAGS) $(BUILD_WITH_MIC_CPPFLAGS) -mic_la_LIBADD = $(BUILD_WITH_MIC_LDADD) -collectd_LDADD += "-dlopen" mic.la -collectd_DEPENDENCIES += mic.la -endif - -if BUILD_PLUGIN_VARNISH -pkglib_LTLIBRARIES += varnish.la -varnish_la_SOURCES = varnish.c -varnish_la_LDFLAGS = -module -avoid-version -varnish_la_CFLAGS = $(AM_CFLAGS) $(BUILD_WITH_LIBVARNISH_CFLAGS) -varnish_la_LIBADD = $(BUILD_WITH_LIBVARNISH_LIBS) -collectd_LDADD += "-dlopen" varnish.la -collectd_DEPENDENCIES += varnish.la -endif - -if BUILD_PLUGIN_VMEM -pkglib_LTLIBRARIES += vmem.la -vmem_la_SOURCES = vmem.c -vmem_la_LDFLAGS = -module -avoid-version -collectd_LDADD += "-dlopen" vmem.la -collectd_DEPENDENCIES += vmem.la -endif - -if BUILD_PLUGIN_VSERVER -pkglib_LTLIBRARIES += vserver.la -vserver_la_SOURCES = vserver.c -vserver_la_LDFLAGS = -module -avoid-version -collectd_LDADD += "-dlopen" vserver.la -collectd_DEPENDENCIES += vserver.la -endif - -if BUILD_PLUGIN_WIRELESS -pkglib_LTLIBRARIES += wireless.la -wireless_la_SOURCES = wireless.c -wireless_la_LDFLAGS = -module -avoid-version -collectd_LDADD += "-dlopen" wireless.la -collectd_DEPENDENCIES += wireless.la -endif - -if BUILD_PLUGIN_WRITE_GRAPHITE -pkglib_LTLIBRARIES += write_graphite.la -write_graphite_la_SOURCES = write_graphite.c \ - utils_format_graphite.c utils_format_graphite.h \ - utils_format_json.c utils_format_json.h -write_graphite_la_LDFLAGS = -module -avoid-version -collectd_LDADD += "-dlopen" write_graphite.la -collectd_DEPENDENCIES += write_graphite.la -endif - -if BUILD_PLUGIN_WRITE_HTTP -pkglib_LTLIBRARIES += write_http.la -write_http_la_SOURCES = write_http.c \ - utils_format_json.c utils_format_json.h -write_http_la_LDFLAGS = -module -avoid-version -write_http_la_CFLAGS = $(AM_CFLAGS) -write_http_la_LIBADD = -collectd_LDADD += "-dlopen" write_http.la -if BUILD_WITH_LIBCURL -write_http_la_CFLAGS += $(BUILD_WITH_LIBCURL_CFLAGS) -write_http_la_LIBADD += $(BUILD_WITH_LIBCURL_LIBS) -endif -collectd_DEPENDENCIES += write_http.la -endif - -if BUILD_PLUGIN_WRITE_MONGODB -pkglib_LTLIBRARIES += write_mongodb.la -write_mongodb_la_SOURCES = write_mongodb.c -write_mongodb_la_CPPFLAGS = $(AM_CPPFLAGS) $(BUILD_WITH_LIBMONGOC_CPPFLAGS) -write_mongodb_la_LDFLAGS = -module -avoid-version $(BUILD_WITH_LIBMONGOC_LDFLAGS) -write_mongodb_la_LIBADD = -lmongoc -collectd_LDADD += "-dlopen" write_mongodb.la -collectd_DEPENDENCIES += write_mongodb.la -endif - -if BUILD_PLUGIN_WRITE_REDIS -pkglib_LTLIBRARIES += write_redis.la -write_redis_la_SOURCES = write_redis.c -write_redis_la_LDFLAGS = -module -avoid-version $(BUILD_WITH_LIBCREDIS_LDFLAGS) -write_redis_la_CFLAGS = $(AM_CFLAGS) $(BUILD_WITH_LIBCREDIS_CPPFLAGS) -write_redis_la_LIBADD = -lcredis -collectd_LDADD += "-dlopen" write_redis.la -collectd_DEPENDENCIES += write_redis.la -endif - -if BUILD_PLUGIN_WRITE_RIEMANN -pkglib_LTLIBRARIES += write_riemann.la -write_riemann_la_SOURCES = write_riemann.c -nodist_write_riemann_la_SOURCES = riemann.pb-c.c riemann.pb-c.h -write_riemann_la_LDFLAGS = -module -avoid-version -write_riemann_la_LIBADD = -lprotobuf-c -collectd_LDADD += "-dlopen" write_riemann.la -collectd_DEPENDENCIES += write_riemann.la -endif - -if BUILD_PLUGIN_XMMS -pkglib_LTLIBRARIES += xmms.la -xmms_la_SOURCES = xmms.c -xmms_la_CFLAGS = $(AM_CFLAGS) $(BUILD_WITH_LIBXMMS_CFLAGS) -xmms_la_LDFLAGS = -module -avoid-version -xmms_la_LIBADD = $(BUILD_WITH_LIBXMMS_LIBS) -collectd_LDADD += "-dlopen" xmms.la -collectd_DEPENDENCIES += xmms.la -endif - -if BUILD_PLUGIN_ZFS_ARC -pkglib_LTLIBRARIES += zfs_arc.la -zfs_arc_la_SOURCES = zfs_arc.c -zfs_arc_la_CFLAGS = $(AM_CFLAGS) -zfs_arc_la_LDFLAGS = -module -avoid-version -if BUILD_FREEBSD -zfs_arc_la_LIBADD = -lm -else -zfs_arc_la_LIBADD = -lkstat -endif -collectd_LDADD += "-dlopen" zfs_arc.la -collectd_DEPENDENCIES += zfs_arc.la -endif - -BUILT_SOURCES += $(dist_man_MANS) - -dist_man_MANS = collectd.1 \ - collectd.conf.5 \ - collectd-email.5 \ - collectd-exec.5 \ - collectdctl.1 \ - collectd-java.5 \ - collectdmon.1 \ - collectd-nagios.1 \ - collectd-perl.5 \ - collectd-python.5 \ - collectd-snmp.5 \ - collectd-tg.1 \ - collectd-threshold.5 \ - collectd-unixsock.5 \ - types.db.5 - -#collectd_1_SOURCES = collectd.pod - -EXTRA_DIST = types.db - -EXTRA_DIST += collectd.conf.pod \ - collectd-email.pod \ - collectd-exec.pod \ - collectdctl.pod \ - collectd-java.pod \ - collectdmon.pod \ - collectd-nagios.pod \ - collectd-perl.pod \ - collectd-python.pod \ - collectd.pod \ - collectd-snmp.pod \ - collectd-tg.pod \ - collectd-threshold.pod \ - collectd-unixsock.pod \ - postgresql_default.conf \ - types.db.pod - -.pod.1: - pod2man --release=$(VERSION) --center=$(PACKAGE) $< \ - >.pod2man.tmp.$$$$ 2>/dev/null && mv -f .pod2man.tmp.$$$$ $@ || true - @if grep '\' $@ >/dev/null 2>&1; \ - then \ - echo "$@ has some POD errors!"; false; \ - fi - -.pod.5: - pod2man --section=5 --release=$(VERSION) --center=$(PACKAGE) $< \ - >.pod2man.tmp.$$$$ 2>/dev/null && mv -f .pod2man.tmp.$$$$ $@ || true - @if grep '\' $@ >/dev/null 2>&1; \ - then \ - echo "$@ has some POD errors!"; false; \ - fi - -# Protocol buffer for the "pinba" plugin. -EXTRA_DIST += pinba.proto -if HAVE_PROTOC_C -CLEANFILES += pinba.pb-c.c pinba.pb-c.h -BUILT_SOURCES += pinba.pb-c.c pinba.pb-c.h - -pinba.pb-c.c pinba.pb-c.h: pinba.proto - protoc-c -I$(srcdir) --c_out . $(srcdir)/pinba.proto -endif - -# Protocol buffer for the "write_riemann" plugin. -EXTRA_DIST += riemann.proto -if HAVE_PROTOC_C -CLEANFILES += riemann.pb-c.c riemann.pb-c.h - -BUILT_SOURCES += riemann.pb-c.c riemann.pb-c.h - -riemann.pb-c.c riemann.pb-c.h: riemann.proto - protoc-c -I$(srcdir) --c_out . $(srcdir)/riemann.proto -endif - -install-exec-hook: - $(mkinstalldirs) $(DESTDIR)$(sysconfdir) - if test -e $(DESTDIR)$(sysconfdir)/collectd.conf; \ - then \ - $(INSTALL) -m 0640 collectd.conf $(DESTDIR)$(sysconfdir)/collectd.conf.pkg-orig; \ - else \ - $(INSTALL) -m 0640 collectd.conf $(DESTDIR)$(sysconfdir)/collectd.conf; \ - fi; \ - $(mkinstalldirs) $(DESTDIR)$(pkgdatadir) - $(INSTALL) -m 0644 $(srcdir)/types.db $(DESTDIR)$(pkgdatadir)/types.db; - $(INSTALL) -m 0644 $(srcdir)/postgresql_default.conf \ - $(DESTDIR)$(pkgdatadir)/postgresql_default.conf; - -uninstall-hook: - rm -f $(DESTDIR)$(pkgdatadir)/types.db; - rm -f $(DESTDIR)$(sysconfdir)/collectd.conf - rm -f $(DESTDIR)$(pkgdatadir)/postgresql_default.conf; - -if BUILD_FEATURE_DEBUG -bin_PROGRAMS += utils_vl_lookup_test -utils_vl_lookup_test_SOURCES = utils_vl_lookup_test.c \ - utils_vl_lookup.h utils_vl_lookup.c \ - utils_avltree.c utils_avltree.h \ - common.h - -utils_vl_lookup_test_CPPFLAGS = $(AM_CPPFLAGS) $(LTDLINCL) -DBUILD_TEST=1 -utils_vl_lookup_test_CFLAGS = $(AM_CFLAGS) -utils_vl_lookup_test_LDFLAGS = -export-dynamic -utils_vl_lookup_test_LDADD = -endif diff --git a/src/aggregation.c b/src/aggregation.c index 0c0f19d6fe..e2f8ff1c3d 100644 --- a/src/aggregation.c +++ b/src/aggregation.c @@ -26,22 +26,19 @@ #include "collectd.h" -#include - #include "plugin.h" -#include "common.h" -#include "configfile.h" -#include "meta_data.h" +#include "utils/common/common.h" +#include "utils/lookup/vl_lookup.h" +#include "utils/metadata/meta_data.h" #include "utils_cache.h" /* for uc_get_rate() */ #include "utils_subst.h" -#include "utils_vl_lookup.h" -#define AGG_MATCHES_ALL(str) (strcmp ("/.*/", str) == 0) +#define AGG_MATCHES_ALL(str) (strcmp("/.*/", str) == 0) #define AGG_FUNC_PLACEHOLDER "%{aggregation}" struct aggregation_s /* {{{ */ { - identifier_t ident; + lookup_identifier_t ident; unsigned int group_by; unsigned int regex_fields; @@ -51,12 +48,12 @@ struct aggregation_s /* {{{ */ char *set_plugin_instance; char *set_type_instance; - _Bool calc_num; - _Bool calc_sum; - _Bool calc_average; - _Bool calc_min; - _Bool calc_max; - _Bool calc_stddev; + bool calc_num; + bool calc_sum; + bool calc_average; + bool calc_min; + bool calc_max; + bool calc_stddev; }; /* }}} */ typedef struct aggregation_s aggregation_t; @@ -65,7 +62,7 @@ typedef struct agg_instance_s agg_instance_t; struct agg_instance_s /* {{{ */ { pthread_mutex_t lock; - identifier_t ident; + lookup_identifier_t ident; int ds_type; @@ -86,296 +83,283 @@ struct agg_instance_s /* {{{ */ agg_instance_t *next; }; /* }}} */ -static lookup_t *lookup = NULL; +static lookup_t *lookup; static pthread_mutex_t agg_instance_list_lock = PTHREAD_MUTEX_INITIALIZER; -static agg_instance_t *agg_instance_list_head = NULL; +static agg_instance_t *agg_instance_list_head; -static _Bool agg_is_regex (char const *str) /* {{{ */ +static bool agg_is_regex(char const *str) /* {{{ */ { - size_t len; - if (str == NULL) - return (0); + return false; - len = strlen (str); + size_t len = strlen(str); if (len < 3) - return (0); + return false; if ((str[0] == '/') && (str[len - 1] == '/')) - return (1); + return true; else - return (0); -} /* }}} _Bool agg_is_regex */ + return false; +} /* }}} bool agg_is_regex */ -static void agg_destroy (aggregation_t *agg) /* {{{ */ +static void agg_destroy(aggregation_t *agg) /* {{{ */ { - sfree (agg); + sfree(agg); } /* }}} void agg_destroy */ /* Frees all dynamically allocated memory within the instance. */ -static void agg_instance_destroy (agg_instance_t *inst) /* {{{ */ +static void agg_instance_destroy(agg_instance_t *inst) /* {{{ */ { if (inst == NULL) return; /* Remove this instance from the global list of instances. */ - pthread_mutex_lock (&agg_instance_list_lock); + pthread_mutex_lock(&agg_instance_list_lock); if (agg_instance_list_head == inst) agg_instance_list_head = inst->next; - else if (agg_instance_list_head != NULL) - { + else if (agg_instance_list_head != NULL) { agg_instance_t *prev = agg_instance_list_head; while ((prev != NULL) && (prev->next != inst)) prev = prev->next; if (prev != NULL) prev->next = inst->next; } - pthread_mutex_unlock (&agg_instance_list_lock); + pthread_mutex_unlock(&agg_instance_list_lock); - sfree (inst->state_num); - sfree (inst->state_sum); - sfree (inst->state_average); - sfree (inst->state_min); - sfree (inst->state_max); - sfree (inst->state_stddev); + sfree(inst->state_num); + sfree(inst->state_sum); + sfree(inst->state_average); + sfree(inst->state_min); + sfree(inst->state_max); + sfree(inst->state_stddev); - memset (inst, 0, sizeof (*inst)); + memset(inst, 0, sizeof(*inst)); inst->ds_type = -1; inst->min = NAN; inst->max = NAN; } /* }}} void agg_instance_destroy */ -static int agg_instance_create_name (agg_instance_t *inst, /* {{{ */ - value_list_t const *vl, aggregation_t const *agg) -{ -#define COPY_FIELD(buffer, buffer_size, field, group_mask, all_value) do { \ - if (agg->set_ ## field != NULL) \ - sstrncpy (buffer, agg->set_ ## field, buffer_size); \ - else if ((agg->regex_fields & group_mask) \ - && (agg->group_by & group_mask)) \ - sstrncpy (buffer, vl->field, buffer_size); \ - else if ((agg->regex_fields & group_mask) \ - && (AGG_MATCHES_ALL (agg->ident.field))) \ - sstrncpy (buffer, all_value, buffer_size); \ - else \ - sstrncpy (buffer, agg->ident.field, buffer_size); \ -} while (0) +static int agg_instance_create_name(agg_instance_t *inst, /* {{{ */ + value_list_t const *vl, + aggregation_t const *agg) { +#define COPY_FIELD(buffer, buffer_size, field, group_mask, all_value) \ + do { \ + if (agg->set_##field != NULL) \ + sstrncpy(buffer, agg->set_##field, buffer_size); \ + else if ((agg->regex_fields & group_mask) && (agg->group_by & group_mask)) \ + sstrncpy(buffer, vl->field, buffer_size); \ + else if ((agg->regex_fields & group_mask) && \ + (AGG_MATCHES_ALL(agg->ident.field))) \ + sstrncpy(buffer, all_value, buffer_size); \ + else \ + sstrncpy(buffer, agg->ident.field, buffer_size); \ + } while (0) /* Host */ - COPY_FIELD (inst->ident.host, sizeof (inst->ident.host), - host, LU_GROUP_BY_HOST, "global"); + COPY_FIELD(inst->ident.host, sizeof(inst->ident.host), host, LU_GROUP_BY_HOST, + "global"); /* Plugin */ if (agg->set_plugin != NULL) - sstrncpy (inst->ident.plugin, agg->set_plugin, - sizeof (inst->ident.plugin)); + sstrncpy(inst->ident.plugin, agg->set_plugin, sizeof(inst->ident.plugin)); else - sstrncpy (inst->ident.plugin, "aggregation", sizeof (inst->ident.plugin)); + sstrncpy(inst->ident.plugin, "aggregation", sizeof(inst->ident.plugin)); /* Plugin instance */ if (agg->set_plugin_instance != NULL) - sstrncpy (inst->ident.plugin_instance, agg->set_plugin_instance, - sizeof (inst->ident.plugin_instance)); - else - { + sstrncpy(inst->ident.plugin_instance, agg->set_plugin_instance, + sizeof(inst->ident.plugin_instance)); + else { char tmp_plugin[DATA_MAX_NAME_LEN]; char tmp_plugin_instance[DATA_MAX_NAME_LEN] = ""; - if ((agg->regex_fields & LU_GROUP_BY_PLUGIN) - && (agg->group_by & LU_GROUP_BY_PLUGIN)) - sstrncpy (tmp_plugin, vl->plugin, sizeof (tmp_plugin)); - else if ((agg->regex_fields & LU_GROUP_BY_PLUGIN) - && (AGG_MATCHES_ALL (agg->ident.plugin))) - sstrncpy (tmp_plugin, "", sizeof (tmp_plugin)); + if ((agg->regex_fields & LU_GROUP_BY_PLUGIN) && + (agg->group_by & LU_GROUP_BY_PLUGIN)) + sstrncpy(tmp_plugin, vl->plugin, sizeof(tmp_plugin)); + else if ((agg->regex_fields & LU_GROUP_BY_PLUGIN) && + (AGG_MATCHES_ALL(agg->ident.plugin))) + sstrncpy(tmp_plugin, "", sizeof(tmp_plugin)); else - sstrncpy (tmp_plugin, agg->ident.plugin, sizeof (tmp_plugin)); - - if ((agg->regex_fields & LU_GROUP_BY_PLUGIN_INSTANCE) - && (agg->group_by & LU_GROUP_BY_PLUGIN_INSTANCE)) - sstrncpy (tmp_plugin_instance, vl->plugin_instance, - sizeof (tmp_plugin_instance)); - else if ((agg->regex_fields & LU_GROUP_BY_PLUGIN_INSTANCE) - && (AGG_MATCHES_ALL (agg->ident.plugin_instance))) - sstrncpy (tmp_plugin_instance, "", sizeof (tmp_plugin_instance)); + sstrncpy(tmp_plugin, agg->ident.plugin, sizeof(tmp_plugin)); + + if ((agg->regex_fields & LU_GROUP_BY_PLUGIN_INSTANCE) && + (agg->group_by & LU_GROUP_BY_PLUGIN_INSTANCE)) + sstrncpy(tmp_plugin_instance, vl->plugin_instance, + sizeof(tmp_plugin_instance)); + else if ((agg->regex_fields & LU_GROUP_BY_PLUGIN_INSTANCE) && + (AGG_MATCHES_ALL(agg->ident.plugin_instance))) + sstrncpy(tmp_plugin_instance, "", sizeof(tmp_plugin_instance)); else - sstrncpy (tmp_plugin_instance, agg->ident.plugin_instance, - sizeof (tmp_plugin_instance)); - - 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) - ssnprintf (inst->ident.plugin_instance, - sizeof (inst->ident.plugin_instance), - "%s-%s", tmp_plugin, AGG_FUNC_PLACEHOLDER); - else if (strcmp ("", tmp_plugin_instance) != 0) - ssnprintf (inst->ident.plugin_instance, - sizeof (inst->ident.plugin_instance), - "%s-%s", tmp_plugin_instance, AGG_FUNC_PLACEHOLDER); + 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)); + // 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 - ssnprintf (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 */ - sstrncpy (inst->ident.type, agg->ident.type, sizeof (inst->ident.type)); + sstrncpy(inst->ident.type, agg->ident.type, sizeof(inst->ident.type)); /* Type instance */ - COPY_FIELD (inst->ident.type_instance, sizeof (inst->ident.type_instance), - type_instance, LU_GROUP_BY_TYPE_INSTANCE, ""); + COPY_FIELD(inst->ident.type_instance, sizeof(inst->ident.type_instance), + type_instance, LU_GROUP_BY_TYPE_INSTANCE, ""); #undef COPY_FIELD - return (0); + return 0; } /* }}} int agg_instance_create_name */ /* Create a new aggregation instance. */ -static agg_instance_t *agg_instance_create (data_set_t const *ds, /* {{{ */ - value_list_t const *vl, aggregation_t *agg) -{ - agg_instance_t *inst; - - DEBUG ("aggregation plugin: Creating new instance."); - - inst = malloc (sizeof (*inst)); - if (inst == NULL) - { - ERROR ("aggregation plugin: malloc() failed."); - return (NULL); +static agg_instance_t *agg_instance_create(data_set_t const *ds, /* {{{ */ + value_list_t const *vl, + aggregation_t *agg) { + DEBUG("aggregation plugin: Creating new instance."); + + agg_instance_t *inst = calloc(1, sizeof(*inst)); + if (inst == NULL) { + ERROR("aggregation plugin: calloc() failed."); + return NULL; } - memset (inst, 0, sizeof (*inst)); - pthread_mutex_init (&inst->lock, /* attr = */ NULL); + pthread_mutex_init(&inst->lock, /* attr = */ NULL); inst->ds_type = ds->ds[0].type; - agg_instance_create_name (inst, vl, agg); + agg_instance_create_name(inst, vl, agg); inst->min = NAN; inst->max = NAN; -#define INIT_STATE(field) do { \ - inst->state_ ## field = NULL; \ - if (agg->calc_ ## field) { \ - inst->state_ ## field = malloc (sizeof (*inst->state_ ## field)); \ - if (inst->state_ ## field == NULL) { \ - agg_instance_destroy (inst); \ - ERROR ("aggregation plugin: malloc() failed."); \ - return (NULL); \ - } \ - memset (inst->state_ ## field, 0, sizeof (*inst->state_ ## field)); \ - } \ -} while (0) - - INIT_STATE (num); - INIT_STATE (sum); - INIT_STATE (average); - INIT_STATE (min); - INIT_STATE (max); - INIT_STATE (stddev); +#define INIT_STATE(field) \ + do { \ + inst->state_##field = NULL; \ + if (agg->calc_##field) { \ + inst->state_##field = calloc(1, sizeof(*inst->state_##field)); \ + if (inst->state_##field == NULL) { \ + agg_instance_destroy(inst); \ + free(inst); \ + ERROR("aggregation plugin: calloc() failed."); \ + return NULL; \ + } \ + } \ + } while (0) + + INIT_STATE(num); + INIT_STATE(sum); + INIT_STATE(average); + INIT_STATE(min); + INIT_STATE(max); + INIT_STATE(stddev); #undef INIT_STATE - pthread_mutex_lock (&agg_instance_list_lock); + pthread_mutex_lock(&agg_instance_list_lock); inst->next = agg_instance_list_head; agg_instance_list_head = inst; - pthread_mutex_unlock (&agg_instance_list_lock); + pthread_mutex_unlock(&agg_instance_list_lock); - return (inst); + return inst; } /* }}} agg_instance_t *agg_instance_create */ /* Update the num, sum, min, max, ... fields of the aggregation instance, if * the rate of the value list is available. Value lists with more than one data * source are not supported and will return an error. Returns zero on success * and non-zero otherwise. */ -static int agg_instance_update (agg_instance_t *inst, /* {{{ */ - data_set_t const *ds, value_list_t const *vl) -{ - gauge_t *rate; - - if (ds->ds_num != 1) - { - ERROR ("aggregation plugin: The \"%s\" type (data set) has more than one " - "data source. This is currently not supported by this plugin. " - "Sorry.", ds->type); - return (EINVAL); +static int agg_instance_update(agg_instance_t *inst, /* {{{ */ + data_set_t const *ds, value_list_t const *vl) { + if (ds->ds_num != 1) { + ERROR("aggregation plugin: The \"%s\" type (data set) has more than one " + "data source. This is currently not supported by this plugin. " + "Sorry.", + ds->type); + return EINVAL; } - rate = uc_get_rate (ds, vl); - if (rate == NULL) - { + gauge_t *rate = uc_get_rate(ds, vl); + if (rate == NULL) { char ident[6 * DATA_MAX_NAME_LEN]; - FORMAT_VL (ident, sizeof (ident), vl); - ERROR ("aggregation plugin: Unable to read the current rate of \"%s\".", - ident); - return (ENOENT); + FORMAT_VL(ident, sizeof(ident), vl); + ERROR("aggregation plugin: Unable to read the current rate of \"%s\".", + ident); + return ENOENT; } - if (isnan (rate[0])) - { - sfree (rate); - return (0); + if (isnan(rate[0])) { + sfree(rate); + return 0; } - pthread_mutex_lock (&inst->lock); + pthread_mutex_lock(&inst->lock); inst->num++; inst->sum += rate[0]; inst->squares_sum += (rate[0] * rate[0]); - if (isnan (inst->min) || (inst->min > rate[0])) + if (isnan(inst->min) || (inst->min > rate[0])) inst->min = rate[0]; - if (isnan (inst->max) || (inst->max < rate[0])) + if (isnan(inst->max) || (inst->max < rate[0])) inst->max = rate[0]; - pthread_mutex_unlock (&inst->lock); + pthread_mutex_unlock(&inst->lock); - sfree (rate); - return (0); + sfree(rate); + return 0; } /* }}} int agg_instance_update */ -static int agg_instance_read_func (agg_instance_t *inst, /* {{{ */ - char const *func, gauge_t rate, rate_to_value_state_t *state, - value_list_t *vl, char const *pi_prefix, cdtime_t t) -{ - value_t v; - int status; - +static int agg_instance_read_func(agg_instance_t *inst, /* {{{ */ + char const *func, gauge_t rate, + rate_to_value_state_t *state, + value_list_t *vl, char const *pi_prefix, + cdtime_t t) { if (pi_prefix[0] != 0) - subst_string (vl->plugin_instance, sizeof (vl->plugin_instance), - pi_prefix, AGG_FUNC_PLACEHOLDER, func); + subst_string(vl->plugin_instance, sizeof(vl->plugin_instance), pi_prefix, + AGG_FUNC_PLACEHOLDER, func); else - sstrncpy (vl->plugin_instance, func, sizeof (vl->plugin_instance)); + sstrncpy(vl->plugin_instance, func, sizeof(vl->plugin_instance)); - memset (&v, 0, sizeof (v)); - status = rate_to_value (&v, rate, state, inst->ds_type, t); - if (status != 0) - { + value_t v; + + int status = rate_to_value(&v, rate, state, inst->ds_type, t); + if (status != 0) { /* If this is the first iteration and rate_to_value() was asked to return a * COUNTER or a DERIVE, it will return EAGAIN. Catch this and handle * gracefully. */ if (status == EAGAIN) - return (0); + return 0; - WARNING ("aggregation plugin: rate_to_value failed with status %i.", - status); - return (-1); + WARNING("aggregation plugin: rate_to_value failed with status %i.", status); + return -1; } vl->values = &v; vl->values_len = 1; - plugin_dispatch_values (vl); + plugin_dispatch_values(vl); vl->values = NULL; vl->values_len = 0; - return (0); + return 0; } /* }}} int agg_instance_read_func */ -static int agg_instance_read (agg_instance_t *inst, cdtime_t t) /* {{{ */ +static int agg_instance_read(agg_instance_t *inst, cdtime_t t) /* {{{ */ { value_list_t vl = VALUE_LIST_INIT; @@ -386,41 +370,41 @@ static int agg_instance_read (agg_instance_t *inst, cdtime_t t) /* {{{ */ vl.time = t; vl.interval = 0; - vl.meta = meta_data_create (); - if (vl.meta == NULL) - { - ERROR ("aggregation plugin: meta_data_create failed."); - return (-1); + vl.meta = meta_data_create(); + if (vl.meta == NULL) { + ERROR("aggregation plugin: meta_data_create failed."); + return -1; } - meta_data_add_boolean (vl.meta, "aggregation:created", 1); + meta_data_add_boolean(vl.meta, "aggregation:created", 1); - sstrncpy (vl.host, inst->ident.host, sizeof (vl.host)); - sstrncpy (vl.plugin, inst->ident.plugin, sizeof (vl.plugin)); - sstrncpy (vl.type, inst->ident.type, sizeof (vl.type)); - sstrncpy (vl.type_instance, inst->ident.type_instance, - sizeof (vl.type_instance)); + sstrncpy(vl.host, inst->ident.host, sizeof(vl.host)); + sstrncpy(vl.plugin, inst->ident.plugin, sizeof(vl.plugin)); + sstrncpy(vl.type, inst->ident.type, sizeof(vl.type)); + sstrncpy(vl.type_instance, inst->ident.type_instance, + sizeof(vl.type_instance)); -#define READ_FUNC(func, rate) do { \ - if (inst->state_ ## func != NULL) { \ - agg_instance_read_func (inst, #func, rate, \ - inst->state_ ## func, &vl, inst->ident.plugin_instance, t); \ - } \ -} while (0) +#define READ_FUNC(func, rate) \ + do { \ + if (inst->state_##func != NULL) { \ + agg_instance_read_func(inst, #func, rate, inst->state_##func, &vl, \ + inst->ident.plugin_instance, t); \ + } \ + } while (0) - pthread_mutex_lock (&inst->lock); + pthread_mutex_lock(&inst->lock); - READ_FUNC (num, (gauge_t) inst->num); + READ_FUNC(num, (gauge_t)inst->num); /* All other aggregations are only defined when there have been any values * at all. */ - if (inst->num > 0) - { - READ_FUNC (sum, inst->sum); - 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)); + if (inst->num > 0) { + READ_FUNC(sum, inst->sum); + 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)); } /* Reset internal state. */ @@ -430,41 +414,40 @@ static int agg_instance_read (agg_instance_t *inst, cdtime_t t) /* {{{ */ inst->min = NAN; inst->max = NAN; - pthread_mutex_unlock (&inst->lock); + pthread_mutex_unlock(&inst->lock); - meta_data_destroy (vl.meta); + meta_data_destroy(vl.meta); vl.meta = NULL; - return (0); + return 0; } /* }}} int agg_instance_read */ /* lookup_class_callback_t for utils_vl_lookup */ -static void *agg_lookup_class_callback ( /* {{{ */ - __attribute__((unused)) data_set_t const *ds, - value_list_t const *vl, void *user_class) -{ - return (agg_instance_create (ds, vl, (aggregation_t *) user_class)); +static void *agg_lookup_class_callback(/* {{{ */ + data_set_t const *ds, + value_list_t const *vl, + void *user_class) { + return agg_instance_create(ds, vl, (aggregation_t *)user_class); } /* }}} void *agg_class_callback */ /* lookup_obj_callback_t for utils_vl_lookup */ -static int agg_lookup_obj_callback (data_set_t const *ds, /* {{{ */ - value_list_t const *vl, - __attribute__((unused)) void *user_class, - void *user_obj) -{ - return (agg_instance_update ((agg_instance_t *) user_obj, ds, vl)); +static int agg_lookup_obj_callback(data_set_t const *ds, /* {{{ */ + value_list_t const *vl, + __attribute__((unused)) void *user_class, + void *user_obj) { + return agg_instance_update((agg_instance_t *)user_obj, ds, vl); } /* }}} int agg_lookup_obj_callback */ /* lookup_free_class_callback_t for utils_vl_lookup */ -static void agg_lookup_free_class_callback (void *user_class) /* {{{ */ +static void agg_lookup_free_class_callback(void *user_class) /* {{{ */ { - agg_destroy ((aggregation_t *) user_class); + agg_destroy((aggregation_t *)user_class); } /* }}} void agg_lookup_free_class_callback */ /* lookup_free_obj_callback_t for utils_vl_lookup */ -static void agg_lookup_free_obj_callback (void *user_obj) /* {{{ */ +static void agg_lookup_free_obj_callback(void *user_obj) /* {{{ */ { - agg_instance_destroy ((agg_instance_t *) user_obj); + agg_instance_destroy((agg_instance_t *)user_obj); } /* }}} void agg_lookup_free_obj_callback */ /* @@ -485,247 +468,225 @@ static void agg_lookup_free_obj_callback (void *user_obj) /* {{{ */ * * */ -static int agg_config_handle_group_by (oconfig_item_t const *ci, /* {{{ */ - aggregation_t *agg) -{ - int i; - - for (i = 0; i < ci->values_num; i++) - { - char const *value; - - if (ci->values[i].type != OCONFIG_TYPE_STRING) - { - ERROR ("aggregation plugin: Argument %i of the \"GroupBy\" option " - "is not a string.", i + 1); +static int agg_config_handle_group_by(oconfig_item_t const *ci, /* {{{ */ + aggregation_t *agg) { + for (int i = 0; i < ci->values_num; i++) { + if (ci->values[i].type != OCONFIG_TYPE_STRING) { + ERROR("aggregation plugin: Argument %i of the \"GroupBy\" option " + "is not a string.", + i + 1); continue; } - value = ci->values[i].value.string; + const char *value = ci->values[i].value.string; - if (strcasecmp ("Host", value) == 0) + if (strcasecmp("Host", value) == 0) agg->group_by |= LU_GROUP_BY_HOST; - else if (strcasecmp ("Plugin", value) == 0) + else if (strcasecmp("Plugin", value) == 0) agg->group_by |= LU_GROUP_BY_PLUGIN; - else if (strcasecmp ("PluginInstance", value) == 0) + else if (strcasecmp("PluginInstance", value) == 0) agg->group_by |= LU_GROUP_BY_PLUGIN_INSTANCE; - else if (strcasecmp ("TypeInstance", value) == 0) + else if (strcasecmp("TypeInstance", value) == 0) agg->group_by |= LU_GROUP_BY_TYPE_INSTANCE; - else if (strcasecmp ("Type", value) == 0) - ERROR ("aggregation plugin: Grouping by type is not supported."); + else if (strcasecmp("Type", value) == 0) + ERROR("aggregation plugin: Grouping by type is not supported."); else - WARNING ("aggregation plugin: The \"%s\" argument to the \"GroupBy\" " - "option is invalid and will be ignored.", value); + WARNING("aggregation plugin: The \"%s\" argument to the \"GroupBy\" " + "option is invalid and will be ignored.", + value); } /* for (ci->values) */ - return (0); + return 0; } /* }}} int agg_config_handle_group_by */ -static int agg_config_aggregation (oconfig_item_t *ci) /* {{{ */ +static int agg_config_aggregation(oconfig_item_t *ci) /* {{{ */ { - aggregation_t *agg; - _Bool is_valid; - int status; - int i; - - agg = malloc (sizeof (*agg)); - if (agg == NULL) - { - ERROR ("aggregation plugin: malloc failed."); - return (-1); + aggregation_t *agg = calloc(1, sizeof(*agg)); + if (agg == NULL) { + ERROR("aggregation plugin: calloc failed."); + return -1; } - memset (agg, 0, sizeof (*agg)); - sstrncpy (agg->ident.host, "/.*/", sizeof (agg->ident.host)); - sstrncpy (agg->ident.plugin, "/.*/", sizeof (agg->ident.plugin)); - sstrncpy (agg->ident.plugin_instance, "/.*/", - sizeof (agg->ident.plugin_instance)); - sstrncpy (agg->ident.type, "/.*/", sizeof (agg->ident.type)); - sstrncpy (agg->ident.type_instance, "/.*/", - sizeof (agg->ident.type_instance)); + sstrncpy(agg->ident.host, "/.*/", sizeof(agg->ident.host)); + sstrncpy(agg->ident.plugin, "/.*/", sizeof(agg->ident.plugin)); + sstrncpy(agg->ident.plugin_instance, "/.*/", + sizeof(agg->ident.plugin_instance)); + sstrncpy(agg->ident.type, "/.*/", sizeof(agg->ident.type)); + sstrncpy(agg->ident.type_instance, "/.*/", sizeof(agg->ident.type_instance)); - for (i = 0; i < ci->children_num; i++) - { + for (int i = 0; i < ci->children_num; i++) { oconfig_item_t *child = ci->children + i; - - if (strcasecmp ("Host", child->key) == 0) - cf_util_get_string_buffer (child, agg->ident.host, - sizeof (agg->ident.host)); - else if (strcasecmp ("Plugin", child->key) == 0) - cf_util_get_string_buffer (child, agg->ident.plugin, - sizeof (agg->ident.plugin)); - else if (strcasecmp ("PluginInstance", child->key) == 0) - cf_util_get_string_buffer (child, agg->ident.plugin_instance, - sizeof (agg->ident.plugin_instance)); - else if (strcasecmp ("Type", child->key) == 0) - cf_util_get_string_buffer (child, agg->ident.type, - sizeof (agg->ident.type)); - else if (strcasecmp ("TypeInstance", child->key) == 0) - cf_util_get_string_buffer (child, agg->ident.type_instance, - sizeof (agg->ident.type_instance)); - else if (strcasecmp ("SetHost", child->key) == 0) - cf_util_get_string (child, &agg->set_host); - else if (strcasecmp ("SetPlugin", child->key) == 0) - cf_util_get_string (child, &agg->set_plugin); - else if (strcasecmp ("SetPluginInstance", child->key) == 0) - cf_util_get_string (child, &agg->set_plugin_instance); - else if (strcasecmp ("SetTypeInstance", child->key) == 0) - cf_util_get_string (child, &agg->set_type_instance); - else if (strcasecmp ("GroupBy", child->key) == 0) - agg_config_handle_group_by (child, agg); - else if (strcasecmp ("CalculateNum", child->key) == 0) - cf_util_get_boolean (child, &agg->calc_num); - else if (strcasecmp ("CalculateSum", child->key) == 0) - cf_util_get_boolean (child, &agg->calc_sum); - else if (strcasecmp ("CalculateAverage", child->key) == 0) - cf_util_get_boolean (child, &agg->calc_average); - else if (strcasecmp ("CalculateMinimum", child->key) == 0) - cf_util_get_boolean (child, &agg->calc_min); - else if (strcasecmp ("CalculateMaximum", child->key) == 0) - cf_util_get_boolean (child, &agg->calc_max); - else if (strcasecmp ("CalculateStddev", child->key) == 0) - cf_util_get_boolean (child, &agg->calc_stddev); + int status = 0; + + if (strcasecmp("Host", child->key) == 0) + status = cf_util_get_string_buffer(child, agg->ident.host, + sizeof(agg->ident.host)); + else if (strcasecmp("Plugin", child->key) == 0) + status = cf_util_get_string_buffer(child, agg->ident.plugin, + sizeof(agg->ident.plugin)); + else if (strcasecmp("PluginInstance", child->key) == 0) + status = cf_util_get_string_buffer(child, agg->ident.plugin_instance, + sizeof(agg->ident.plugin_instance)); + else if (strcasecmp("Type", child->key) == 0) + status = cf_util_get_string_buffer(child, agg->ident.type, + sizeof(agg->ident.type)); + else if (strcasecmp("TypeInstance", child->key) == 0) + status = cf_util_get_string_buffer(child, agg->ident.type_instance, + sizeof(agg->ident.type_instance)); + else if (strcasecmp("SetHost", child->key) == 0) + status = cf_util_get_string(child, &agg->set_host); + else if (strcasecmp("SetPlugin", child->key) == 0) + status = cf_util_get_string(child, &agg->set_plugin); + else if (strcasecmp("SetPluginInstance", child->key) == 0) + status = cf_util_get_string(child, &agg->set_plugin_instance); + else if (strcasecmp("SetTypeInstance", child->key) == 0) + status = cf_util_get_string(child, &agg->set_type_instance); + else if (strcasecmp("GroupBy", child->key) == 0) + status = agg_config_handle_group_by(child, agg); + else if (strcasecmp("CalculateNum", child->key) == 0) + status = cf_util_get_boolean(child, &agg->calc_num); + else if (strcasecmp("CalculateSum", child->key) == 0) + status = cf_util_get_boolean(child, &agg->calc_sum); + else if (strcasecmp("CalculateAverage", child->key) == 0) + status = cf_util_get_boolean(child, &agg->calc_average); + else if (strcasecmp("CalculateMinimum", child->key) == 0) + status = cf_util_get_boolean(child, &agg->calc_min); + else if (strcasecmp("CalculateMaximum", child->key) == 0) + status = cf_util_get_boolean(child, &agg->calc_max); + else if (strcasecmp("CalculateStddev", child->key) == 0) + status = cf_util_get_boolean(child, &agg->calc_stddev); else - WARNING ("aggregation plugin: The \"%s\" key is not allowed inside " - " blocks and will be ignored.", child->key); - } + WARNING("aggregation plugin: The \"%s\" key is not allowed inside " + " blocks and will be ignored.", + child->key); - if (agg_is_regex (agg->ident.host)) + if (status != 0) { + sfree(agg); + return status; + } + } /* for (int i = 0; i < ci->children_num; i++) */ + + if (agg_is_regex(agg->ident.host)) agg->regex_fields |= LU_GROUP_BY_HOST; - if (agg_is_regex (agg->ident.plugin)) + if (agg_is_regex(agg->ident.plugin)) agg->regex_fields |= LU_GROUP_BY_PLUGIN; - if (agg_is_regex (agg->ident.plugin_instance)) + if (agg_is_regex(agg->ident.plugin_instance)) agg->regex_fields |= LU_GROUP_BY_PLUGIN_INSTANCE; - if (agg_is_regex (agg->ident.type_instance)) + if (agg_is_regex(agg->ident.type_instance)) agg->regex_fields |= LU_GROUP_BY_TYPE_INSTANCE; /* Sanity checking */ - is_valid = 1; - if (strcmp ("/.*/", agg->ident.type) == 0) /* {{{ */ - { - ERROR ("aggregation plugin: It appears you did not specify the required " - "\"Type\" option in this aggregation. " - "(Host \"%s\", Plugin \"%s\", PluginInstance \"%s\", " - "Type \"%s\", TypeInstance \"%s\")", - agg->ident.host, agg->ident.plugin, agg->ident.plugin_instance, - agg->ident.type, agg->ident.type_instance); - is_valid = 0; - } - else if (strchr (agg->ident.type, '/') != NULL) + bool is_valid = true; + if (strcmp("/.*/", agg->ident.type) == 0) /* {{{ */ { - ERROR ("aggregation plugin: The \"Type\" may not contain the '/' " - "character. Especially, it may not be a regex. The current " - "value is \"%s\".", agg->ident.type); - is_valid = 0; + ERROR("aggregation plugin: It appears you did not specify the required " + "\"Type\" option in this aggregation. " + "(Host \"%s\", Plugin \"%s\", PluginInstance \"%s\", " + "Type \"%s\", TypeInstance \"%s\")", + agg->ident.host, agg->ident.plugin, agg->ident.plugin_instance, + agg->ident.type, agg->ident.type_instance); + is_valid = false; + } else if (strchr(agg->ident.type, '/') != NULL) { + ERROR("aggregation plugin: The \"Type\" may not contain the '/' " + "character. Especially, it may not be a regex. The current " + "value is \"%s\".", + agg->ident.type); + is_valid = false; } /* }}} */ /* Check that there is at least one regex field without a grouping. {{{ */ - if ((agg->regex_fields & ~agg->group_by) == 0) - { - ERROR ("aggregation plugin: An aggregation must contain at least one " - "wildcard. This is achieved by leaving at least one of the \"Host\", " - "\"Plugin\", \"PluginInstance\" and \"TypeInstance\" options blank " - "or using a regular expression and not grouping by that field. " - "(Host \"%s\", Plugin \"%s\", PluginInstance \"%s\", " - "Type \"%s\", TypeInstance \"%s\")", - agg->ident.host, agg->ident.plugin, agg->ident.plugin_instance, - agg->ident.type, agg->ident.type_instance); - is_valid = 0; + if ((agg->regex_fields & ~agg->group_by) == 0) { + ERROR("aggregation plugin: An aggregation must contain at least one " + "wildcard. This is achieved by leaving at least one of the \"Host\", " + "\"Plugin\", \"PluginInstance\" and \"TypeInstance\" options blank " + "or using a regular expression and not grouping by that field. " + "(Host \"%s\", Plugin \"%s\", PluginInstance \"%s\", " + "Type \"%s\", TypeInstance \"%s\")", + agg->ident.host, agg->ident.plugin, agg->ident.plugin_instance, + agg->ident.type, agg->ident.type_instance); + is_valid = false; } /* }}} */ /* Check that all grouping fields are regular expressions. {{{ */ - if (agg->group_by & ~agg->regex_fields) - { - ERROR ("aggregation plugin: Only wildcard fields (fields for which a " - "regular expression is configured or which are left blank) can be " - "specified in the \"GroupBy\" option. " - "(Host \"%s\", Plugin \"%s\", PluginInstance \"%s\", " - "Type \"%s\", TypeInstance \"%s\")", - agg->ident.host, agg->ident.plugin, agg->ident.plugin_instance, - agg->ident.type, agg->ident.type_instance); - is_valid = 0; + if (agg->group_by & ~agg->regex_fields) { + ERROR("aggregation plugin: Only wildcard fields (fields for which a " + "regular expression is configured or which are left blank) can be " + "specified in the \"GroupBy\" option. " + "(Host \"%s\", Plugin \"%s\", PluginInstance \"%s\", " + "Type \"%s\", TypeInstance \"%s\")", + agg->ident.host, agg->ident.plugin, agg->ident.plugin_instance, + agg->ident.type, agg->ident.type_instance); + is_valid = false; } /* }}} */ if (!agg->calc_num && !agg->calc_sum && !agg->calc_average /* {{{ */ - && !agg->calc_min && !agg->calc_max && !agg->calc_stddev) - { - ERROR ("aggregation plugin: No aggregation function has been specified. " - "Without this, I don't know what I should be calculating. " - "(Host \"%s\", Plugin \"%s\", PluginInstance \"%s\", " - "Type \"%s\", TypeInstance \"%s\")", - agg->ident.host, agg->ident.plugin, agg->ident.plugin_instance, - agg->ident.type, agg->ident.type_instance); - is_valid = 0; + && !agg->calc_min && !agg->calc_max && !agg->calc_stddev) { + ERROR("aggregation plugin: No aggregation function has been specified. " + "Without this, I don't know what I should be calculating. " + "(Host \"%s\", Plugin \"%s\", PluginInstance \"%s\", " + "Type \"%s\", TypeInstance \"%s\")", + agg->ident.host, agg->ident.plugin, agg->ident.plugin_instance, + agg->ident.type, agg->ident.type_instance); + is_valid = false; } /* }}} */ - if (!is_valid) /* {{{ */ - { - sfree (agg); - return (-1); + if (!is_valid) { /* {{{ */ + sfree(agg); + return -1; } /* }}} */ - status = lookup_add (lookup, &agg->ident, agg->group_by, agg); - if (status != 0) - { - ERROR ("aggregation plugin: lookup_add failed with status %i.", status); - sfree (agg); - return (-1); + int status = lookup_add(lookup, &agg->ident, agg->group_by, agg); + if (status != 0) { + ERROR("aggregation plugin: lookup_add failed with status %i.", status); + sfree(agg); + return -1; } - DEBUG ("aggregation plugin: Successfully added aggregation: " - "(Host \"%s\", Plugin \"%s\", PluginInstance \"%s\", " - "Type \"%s\", TypeInstance \"%s\")", - agg->ident.host, agg->ident.plugin, agg->ident.plugin_instance, - agg->ident.type, agg->ident.type_instance); - return (0); + DEBUG("aggregation plugin: Successfully added aggregation: " + "(Host \"%s\", Plugin \"%s\", PluginInstance \"%s\", " + "Type \"%s\", TypeInstance \"%s\")", + agg->ident.host, agg->ident.plugin, agg->ident.plugin_instance, + agg->ident.type, agg->ident.type_instance); + return 0; } /* }}} int agg_config_aggregation */ -static int agg_config (oconfig_item_t *ci) /* {{{ */ +static int agg_config(oconfig_item_t *ci) /* {{{ */ { - int i; - - pthread_mutex_lock (&agg_instance_list_lock); - - if (lookup == NULL) - { - lookup = lookup_create (agg_lookup_class_callback, - agg_lookup_obj_callback, - agg_lookup_free_class_callback, - agg_lookup_free_obj_callback); - if (lookup == NULL) - { - pthread_mutex_unlock (&agg_instance_list_lock); - ERROR ("aggregation plugin: lookup_create failed."); - return (-1); + pthread_mutex_lock(&agg_instance_list_lock); + + if (lookup == NULL) { + lookup = lookup_create(agg_lookup_class_callback, agg_lookup_obj_callback, + agg_lookup_free_class_callback, + agg_lookup_free_obj_callback); + if (lookup == NULL) { + pthread_mutex_unlock(&agg_instance_list_lock); + ERROR("aggregation plugin: lookup_create failed."); + return -1; } } - for (i = 0; i < ci->children_num; i++) - { + for (int i = 0; i < ci->children_num; i++) { oconfig_item_t *child = ci->children + i; - if (strcasecmp ("Aggregation", child->key) == 0) - agg_config_aggregation (child); + if (strcasecmp("Aggregation", child->key) == 0) + agg_config_aggregation(child); else - WARNING ("aggregation plugin: The \"%s\" key is not allowed inside " - " blocks and will be ignored.", child->key); + WARNING("aggregation plugin: The \"%s\" key is not allowed inside " + " blocks and will be ignored.", + child->key); } - pthread_mutex_unlock (&agg_instance_list_lock); + pthread_mutex_unlock(&agg_instance_list_lock); - return (0); + return 0; } /* }}} int agg_config */ -static int agg_read (void) /* {{{ */ +static int agg_read(void) /* {{{ */ { - agg_instance_t *this; - cdtime_t t; - int success; - - t = cdtime (); - success = 0; + cdtime_t t = cdtime(); + int success = 0; - pthread_mutex_lock (&agg_instance_list_lock); + pthread_mutex_lock(&agg_instance_list_lock); /* agg_instance_list_head only holds data, after the "write" callback has * been called with a matching value list at least once. So on startup, @@ -733,59 +694,52 @@ static int agg_read (void) /* {{{ */ * the read() callback is called first, agg_instance_list_head is NULL and * "success" may be zero. This is expected and should not result in an error. * Therefore we need to handle this case separately. */ - if (agg_instance_list_head == NULL) - { - pthread_mutex_unlock (&agg_instance_list_lock); - return (0); + if (agg_instance_list_head == NULL) { + pthread_mutex_unlock(&agg_instance_list_lock); + return 0; } - for (this = agg_instance_list_head; this != NULL; this = this->next) - { - int status; - - status = agg_instance_read (this, t); + for (agg_instance_t *this = agg_instance_list_head; this != NULL; + this = this->next) { + int status = agg_instance_read(this, t); if (status != 0) - WARNING ("aggregation plugin: Reading an aggregation instance " - "failed with status %i.", status); + WARNING("aggregation plugin: Reading an aggregation instance " + "failed with status %i.", + status); else success++; } - pthread_mutex_unlock (&agg_instance_list_lock); + pthread_mutex_unlock(&agg_instance_list_lock); - return ((success > 0) ? 0 : -1); + return (success > 0) ? 0 : -1; } /* }}} int agg_read */ -static int agg_write (data_set_t const *ds, value_list_t const *vl, /* {{{ */ - __attribute__((unused)) user_data_t *user_data) -{ - _Bool created_by_aggregation = 0; - int status; - +static int agg_write(data_set_t const *ds, value_list_t const *vl, /* {{{ */ + __attribute__((unused)) user_data_t *user_data) { + bool created_by_aggregation = false; /* Ignore values that were created by the aggregation plugin to avoid weird * effects. */ - (void) meta_data_get_boolean (vl->meta, "aggregation:created", - &created_by_aggregation); + (void)meta_data_get_boolean(vl->meta, "aggregation:created", + &created_by_aggregation); if (created_by_aggregation) - return (0); + return 0; + + int status; if (lookup == NULL) status = ENOENT; - else - { - status = lookup_search (lookup, ds, vl); + else { + status = lookup_search(lookup, ds, vl); if (status > 0) status = 0; } - return (status); + return status; } /* }}} int agg_write */ -void module_register (void) -{ - plugin_register_complex_config ("aggregation", agg_config); - plugin_register_read ("aggregation", agg_read); - plugin_register_write ("aggregation", agg_write, /* user_data = */ NULL); +void module_register(void) { + plugin_register_complex_config("aggregation", agg_config); + plugin_register_read("aggregation", agg_read); + plugin_register_write("aggregation", agg_write, /* user_data = */ NULL); } - -/* vim: set sw=2 sts=2 tw=78 et fdm=marker : */ diff --git a/src/amqp.c b/src/amqp.c index edd4f74939..fceb40b7a9 100644 --- a/src/amqp.c +++ b/src/amqp.c @@ -23,1029 +23,1106 @@ * * Authors: * Sebastien Pahl - * Florian Forster + * Florian Forster **/ #include "collectd.h" -#include "common.h" -#include "plugin.h" -#include "utils_cmd_putval.h" -#include "utils_format_json.h" -#include "utils_format_graphite.h" -#include +#include "plugin.h" +#include "utils/cmds/putval.h" +#include "utils/common/common.h" +#include "utils/format_graphite/format_graphite.h" +#include "utils/format_json/format_json.h" +#include "utils_random.h" #include #include +#ifdef HAVE_AMQP_TCP_SOCKET_H +#include +#include +#endif +#ifdef HAVE_AMQP_SOCKET_H +#include +#endif +#ifdef HAVE_AMQP_TCP_SOCKET +#if defined HAVE_DECL_AMQP_SOCKET_CLOSE && !HAVE_DECL_AMQP_SOCKET_CLOSE +/* rabbitmq-c does not currently ship amqp_socket.h + * and, thus, does not define this function. */ +int amqp_socket_close(amqp_socket_t *); +#endif +#endif + /* Defines for the delivery mode. I have no idea why they're not defined by the * library.. */ -#define CAMQP_DM_VOLATILE 1 +#define CAMQP_DM_VOLATILE 1 #define CAMQP_DM_PERSISTENT 2 -#define CAMQP_FORMAT_COMMAND 1 -#define CAMQP_FORMAT_JSON 2 -#define CAMQP_FORMAT_GRAPHITE 3 +#define CAMQP_FORMAT_COMMAND 1 +#define CAMQP_FORMAT_JSON 2 +#define CAMQP_FORMAT_GRAPHITE 3 #define CAMQP_CHANNEL 1 /* * Data types */ -struct camqp_config_s -{ - _Bool publish; - char *name; - - char *host; - int port; - char *vhost; - char *user; - char *password; - - char *exchange; - char *routing_key; - - /* publish only */ - uint8_t delivery_mode; - _Bool store_rates; - int format; - /* publish & graphite format only */ - char *prefix; - char *postfix; - char escape_char; - unsigned int graphite_flags; - - /* subscribe only */ - char *exchange_type; - char *queue; - - amqp_connection_state_t connection; - pthread_mutex_t lock; +struct camqp_config_s { + bool publish; + char *name; + + char **hosts; + size_t hosts_count; + int port; + char *vhost; + char *user; + char *password; + + bool tls_enabled; + bool tls_verify_peer; + bool tls_verify_hostname; + char *tls_cacert; + char *tls_client_cert; + char *tls_client_key; + + char *exchange; + char *routing_key; + + /* Number of seconds to wait before connection is retried */ + int connection_retry_delay; + + /* publish only */ + uint8_t delivery_mode; + bool store_rates; + int format; + /* publish & graphite format only */ + char *prefix; + char *postfix; + char escape_char; + unsigned int graphite_flags; + + /* subscribe only */ + char *exchange_type; + char *queue; + bool queue_durable; + bool queue_auto_delete; + + amqp_connection_state_t connection; + pthread_mutex_t lock; }; typedef struct camqp_config_s camqp_config_t; /* * Global variables */ -static const char *def_host = "localhost"; -static const char *def_vhost = "/"; -static const char *def_user = "guest"; -static const char *def_password = "guest"; -static const char *def_exchange = "amq.fanout"; +static const char *def_vhost = "/"; +static const char *def_user = "guest"; +static const char *def_password = "guest"; +static const char *def_exchange = "amq.fanout"; -static pthread_t *subscriber_threads = NULL; -static size_t subscriber_threads_num = 0; -static _Bool subscriber_threads_running = 1; +static pthread_t *subscriber_threads; +static size_t subscriber_threads_num; +static bool subscriber_threads_running = true; -#define CONF(c,f) (((c)->f != NULL) ? (c)->f : def_##f) +#define CONF(c, f) (((c)->f != NULL) ? (c)->f : def_##f) /* * Functions */ -static void camqp_close_connection (camqp_config_t *conf) /* {{{ */ +static void camqp_close_connection(camqp_config_t *conf) /* {{{ */ { - int sockfd; + int sockfd; - if ((conf == NULL) || (conf->connection == NULL)) - return; + if ((conf == NULL) || (conf->connection == NULL)) + return; - sockfd = amqp_get_sockfd (conf->connection); - amqp_channel_close (conf->connection, CAMQP_CHANNEL, AMQP_REPLY_SUCCESS); - amqp_connection_close (conf->connection, AMQP_REPLY_SUCCESS); - amqp_destroy_connection (conf->connection); - close (sockfd); - conf->connection = NULL; + sockfd = amqp_get_sockfd(conf->connection); + amqp_channel_close(conf->connection, CAMQP_CHANNEL, AMQP_REPLY_SUCCESS); + amqp_connection_close(conf->connection, AMQP_REPLY_SUCCESS); + amqp_destroy_connection(conf->connection); + close(sockfd); + conf->connection = NULL; } /* }}} void camqp_close_connection */ -static void camqp_config_free (void *ptr) /* {{{ */ +static void camqp_config_free(void *ptr) /* {{{ */ { - camqp_config_t *conf = ptr; - - if (conf == NULL) - return; - - camqp_close_connection (conf); - - sfree (conf->name); - sfree (conf->host); - sfree (conf->vhost); - sfree (conf->user); - sfree (conf->password); - sfree (conf->exchange); - sfree (conf->exchange_type); - sfree (conf->queue); - sfree (conf->routing_key); - sfree (conf->prefix); - sfree (conf->postfix); - - - sfree (conf); + camqp_config_t *conf = ptr; + + if (conf == NULL) + return; + + camqp_close_connection(conf); + + sfree(conf->name); + strarray_free(conf->hosts, conf->hosts_count); + sfree(conf->vhost); + sfree(conf->user); + sfree(conf->password); + sfree(conf->tls_cacert); + sfree(conf->tls_client_cert); + sfree(conf->tls_client_key); + sfree(conf->exchange); + sfree(conf->exchange_type); + sfree(conf->queue); + sfree(conf->routing_key); + sfree(conf->prefix); + sfree(conf->postfix); + + sfree(conf); } /* }}} void camqp_config_free */ -static char *camqp_bytes_cstring (amqp_bytes_t *in) /* {{{ */ +static char *camqp_bytes_cstring(amqp_bytes_t *in) /* {{{ */ { - char *ret; + char *ret; - if ((in == NULL) || (in->bytes == NULL)) - return (NULL); + if ((in == NULL) || (in->bytes == NULL)) + return NULL; - ret = malloc (in->len + 1); - if (ret == NULL) - return (NULL); + ret = malloc(in->len + 1); + if (ret == NULL) + return NULL; - memcpy (ret, in->bytes, in->len); - ret[in->len] = 0; + memcpy(ret, in->bytes, in->len); + ret[in->len] = 0; - return (ret); + return ret; } /* }}} char *camqp_bytes_cstring */ -static _Bool camqp_is_error (camqp_config_t *conf) /* {{{ */ +static bool camqp_is_error(camqp_config_t *conf) /* {{{ */ { - amqp_rpc_reply_t r; + amqp_rpc_reply_t r; - r = amqp_get_rpc_reply (conf->connection); - if (r.reply_type == AMQP_RESPONSE_NORMAL) - return (0); + r = amqp_get_rpc_reply(conf->connection); + if (r.reply_type == AMQP_RESPONSE_NORMAL) + return false; - return (1); -} /* }}} _Bool camqp_is_error */ + return true; +} /* }}} bool camqp_is_error */ -static char *camqp_strerror (camqp_config_t *conf, /* {{{ */ - char *buffer, size_t buffer_size) -{ - amqp_rpc_reply_t r; +static char *camqp_strerror(camqp_config_t *conf, /* {{{ */ + char *buffer, size_t buffer_size) { + amqp_rpc_reply_t r; - r = amqp_get_rpc_reply (conf->connection); - switch (r.reply_type) - { - case AMQP_RESPONSE_NORMAL: - sstrncpy (buffer, "Success", sizeof (buffer)); - break; + r = amqp_get_rpc_reply(conf->connection); + switch (r.reply_type) { + case AMQP_RESPONSE_NORMAL: + sstrncpy(buffer, "Success", buffer_size); + break; - case AMQP_RESPONSE_NONE: - sstrncpy (buffer, "Missing RPC reply type", sizeof (buffer)); - break; + case AMQP_RESPONSE_NONE: + sstrncpy(buffer, "Missing RPC reply type", buffer_size); + break; - case AMQP_RESPONSE_LIBRARY_EXCEPTION: + case AMQP_RESPONSE_LIBRARY_EXCEPTION: #if HAVE_AMQP_RPC_REPLY_T_LIBRARY_ERRNO - if (r.library_errno) - return (sstrerror (r.library_errno, buffer, buffer_size)); + if (r.library_errno) + return sstrerror(r.library_errno, buffer, buffer_size); #else - if (r.library_error) - return (sstrerror (r.library_error, buffer, buffer_size)); + if (r.library_error) + return sstrerror(r.library_error, buffer, buffer_size); #endif - else - sstrncpy (buffer, "End of stream", sizeof (buffer)); - break; - - case AMQP_RESPONSE_SERVER_EXCEPTION: - if (r.reply.id == AMQP_CONNECTION_CLOSE_METHOD) - { - amqp_connection_close_t *m = r.reply.decoded; - char *tmp = camqp_bytes_cstring (&m->reply_text); - 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); - ssnprintf (buffer, buffer_size, "Server channel error %d: %s", - m->reply_code, tmp); - sfree (tmp); - } - else - { - ssnprintf (buffer, buffer_size, "Server error method %#"PRIx32, - r.reply.id); - } - break; - - default: - ssnprintf (buffer, buffer_size, "Unknown reply type %i", - (int) r.reply_type); + else + sstrncpy(buffer, "End of stream", buffer_size); + break; + + case AMQP_RESPONSE_SERVER_EXCEPTION: + if (r.reply.id == AMQP_CONNECTION_CLOSE_METHOD) { + amqp_connection_close_t *m = r.reply.decoded; + char *tmp = camqp_bytes_cstring(&m->reply_text); + 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); + ssnprintf(buffer, buffer_size, "Server channel error %d: %s", + m->reply_code, tmp); + sfree(tmp); + } else { + ssnprintf(buffer, buffer_size, "Server error method %#" PRIx32, + r.reply.id); } + break; - return (buffer); + default: + ssnprintf(buffer, buffer_size, "Unknown reply type %i", (int)r.reply_type); + } + + return buffer; } /* }}} char *camqp_strerror */ #if HAVE_AMQP_RPC_REPLY_T_LIBRARY_ERRNO -static int camqp_create_exchange (camqp_config_t *conf) /* {{{ */ +static int camqp_create_exchange(camqp_config_t *conf) /* {{{ */ { - amqp_exchange_declare_ok_t *ed_ret; - - if (conf->exchange_type == NULL) - return (0); - - ed_ret = amqp_exchange_declare (conf->connection, - /* channel = */ CAMQP_CHANNEL, - /* exchange = */ amqp_cstring_bytes (conf->exchange), - /* type = */ amqp_cstring_bytes (conf->exchange_type), - /* passive = */ 0, - /* durable = */ 0, - /* auto_delete = */ 1, - /* arguments = */ AMQP_EMPTY_TABLE); - if ((ed_ret == NULL) && camqp_is_error (conf)) - { - char errbuf[1024]; - ERROR ("amqp plugin: amqp_exchange_declare failed: %s", - camqp_strerror (conf, errbuf, sizeof (errbuf))); - camqp_close_connection (conf); - return (-1); - } - - INFO ("amqp plugin: Successfully created exchange \"%s\" " - "with type \"%s\".", - conf->exchange, conf->exchange_type); - - return (0); + amqp_exchange_declare_ok_t *ed_ret; + + if (conf->exchange_type == NULL) + return 0; + + ed_ret = amqp_exchange_declare( + conf->connection, + /* channel = */ CAMQP_CHANNEL, + /* exchange = */ amqp_cstring_bytes(conf->exchange), + /* type = */ amqp_cstring_bytes(conf->exchange_type), + /* passive = */ 0, + /* durable = */ 0, + /* auto_delete = */ 1, + /* arguments = */ AMQP_EMPTY_TABLE); + if ((ed_ret == NULL) && camqp_is_error(conf)) { + char errbuf[1024]; + ERROR("amqp plugin: amqp_exchange_declare failed: %s", + camqp_strerror(conf, errbuf, sizeof(errbuf))); + camqp_close_connection(conf); + return -1; + } + + INFO("amqp plugin: Successfully created exchange \"%s\" " + "with type \"%s\".", + conf->exchange, conf->exchange_type); + + return 0; } /* }}} int camqp_create_exchange */ #else -static int camqp_create_exchange (camqp_config_t *conf) /* {{{ */ +static int camqp_create_exchange(camqp_config_t *conf) /* {{{ */ { - amqp_exchange_declare_ok_t *ed_ret; - amqp_table_t argument_table; - struct amqp_table_entry_t_ argument_table_entries[1]; - - if (conf->exchange_type == NULL) - return (0); - - /* Valid arguments: "auto_delete", "internal" */ - argument_table.num_entries = STATIC_ARRAY_SIZE (argument_table_entries); - argument_table.entries = argument_table_entries; - argument_table_entries[0].key = amqp_cstring_bytes ("auto_delete"); - argument_table_entries[0].value.kind = AMQP_FIELD_KIND_BOOLEAN; - argument_table_entries[0].value.value.boolean = 1; - - ed_ret = amqp_exchange_declare (conf->connection, - /* channel = */ CAMQP_CHANNEL, - /* exchange = */ amqp_cstring_bytes (conf->exchange), - /* type = */ amqp_cstring_bytes (conf->exchange_type), - /* passive = */ 0, - /* durable = */ 0, - /* arguments = */ argument_table); - if ((ed_ret == NULL) && camqp_is_error (conf)) - { - char errbuf[1024]; - ERROR ("amqp plugin: amqp_exchange_declare failed: %s", - camqp_strerror (conf, errbuf, sizeof (errbuf))); - camqp_close_connection (conf); - return (-1); - } - - INFO ("amqp plugin: Successfully created exchange \"%s\" " - "with type \"%s\".", - conf->exchange, conf->exchange_type); - - return (0); + amqp_exchange_declare_ok_t *ed_ret; + amqp_table_t argument_table; + struct amqp_table_entry_t_ argument_table_entries[1]; + + if (conf->exchange_type == NULL) + return 0; + + /* Valid arguments: "auto_delete", "internal" */ + argument_table.num_entries = STATIC_ARRAY_SIZE(argument_table_entries); + argument_table.entries = argument_table_entries; + argument_table_entries[0].key = amqp_cstring_bytes("auto_delete"); + argument_table_entries[0].value.kind = AMQP_FIELD_KIND_BOOLEAN; + argument_table_entries[0].value.value.boolean = 1; + + ed_ret = amqp_exchange_declare( + conf->connection, + /* channel = */ CAMQP_CHANNEL, + /* exchange = */ amqp_cstring_bytes(conf->exchange), + /* type = */ amqp_cstring_bytes(conf->exchange_type), + /* passive = */ 0, + /* durable = */ 0, +#if defined(AMQP_VERSION) && AMQP_VERSION >= 0x00060000 + /* auto delete = */ 0, + /* internal = */ 0, +#endif + /* arguments = */ argument_table); + if ((ed_ret == NULL) && camqp_is_error(conf)) { + char errbuf[1024]; + ERROR("amqp plugin: amqp_exchange_declare failed: %s", + camqp_strerror(conf, errbuf, sizeof(errbuf))); + camqp_close_connection(conf); + return -1; + } + + INFO("amqp plugin: Successfully created exchange \"%s\" " + "with type \"%s\".", + conf->exchange, conf->exchange_type); + + return 0; } /* }}} int camqp_create_exchange */ #endif -static int camqp_setup_queue (camqp_config_t *conf) /* {{{ */ +static int camqp_setup_queue(camqp_config_t *conf) /* {{{ */ { - 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 = */ 0, - /* exclusive = */ 0, - /* auto_delete = */ 1, - /* arguments = */ AMQP_EMPTY_TABLE); - if (qd_ret == NULL) - { - ERROR ("amqp plugin: amqp_queue_declare failed."); - camqp_close_connection (conf); - return (-1); + 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); + if (qd_ret == NULL) { + ERROR("amqp plugin: amqp_queue_declare failed."); + camqp_close_connection(conf); + return -1; + } + + if (conf->queue == NULL) { + conf->queue = camqp_bytes_cstring(&qd_ret->queue); + if (conf->queue == NULL) { + ERROR("amqp plugin: camqp_bytes_cstring failed."); + camqp_close_connection(conf); + return -1; } - if (conf->queue == NULL) - { - conf->queue = camqp_bytes_cstring (&qd_ret->queue); - if (conf->queue == NULL) - { - ERROR ("amqp plugin: camqp_bytes_cstring failed."); - camqp_close_connection (conf); - return (-1); - } - - INFO ("amqp plugin: Created queue \"%s\".", conf->queue); + INFO("amqp plugin: Created queue \"%s\".", conf->queue); + } + DEBUG("amqp plugin: Successfully created queue \"%s\".", conf->queue); + + /* bind to an exchange */ + if (conf->exchange != NULL) { + 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); + if ((qb_ret == NULL) && camqp_is_error(conf)) { + char errbuf[1024]; + ERROR("amqp plugin: amqp_queue_bind failed: %s", + camqp_strerror(conf, errbuf, sizeof(errbuf))); + camqp_close_connection(conf); + return -1; } - DEBUG ("amqp plugin: Successfully created queue \"%s\".", conf->queue); - - /* bind to an exchange */ - if (conf->exchange != NULL) - { - 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); - if ((qb_ret == NULL) && camqp_is_error (conf)) - { - char errbuf[1024]; - ERROR ("amqp plugin: amqp_queue_bind failed: %s", - camqp_strerror (conf, errbuf, sizeof (errbuf))); - camqp_close_connection (conf); - return (-1); - } - DEBUG ("amqp plugin: Successfully bound queue \"%s\" to exchange \"%s\".", - conf->queue, conf->exchange); - } /* if (conf->exchange != NULL) */ - - cm_ret = amqp_basic_consume (conf->connection, - /* channel = */ CAMQP_CHANNEL, - /* queue = */ amqp_cstring_bytes (conf->queue), - /* consumer_tag = */ AMQP_EMPTY_BYTES, - /* no_local = */ 0, - /* no_ack = */ 1, - /* exclusive = */ 0, - /* arguments = */ AMQP_EMPTY_TABLE - ); - if ((cm_ret == NULL) && camqp_is_error (conf)) - { - char errbuf[1024]; - ERROR ("amqp plugin: amqp_basic_consume failed: %s", - camqp_strerror (conf, errbuf, sizeof (errbuf))); - camqp_close_connection (conf); - return (-1); - } - - return (0); + DEBUG("amqp plugin: Successfully bound queue \"%s\" to exchange \"%s\".", + conf->queue, conf->exchange); + } /* if (conf->exchange != NULL) */ + + cm_ret = + amqp_basic_consume(conf->connection, + /* channel = */ CAMQP_CHANNEL, + /* queue = */ amqp_cstring_bytes(conf->queue), + /* consumer_tag = */ AMQP_EMPTY_BYTES, + /* no_local = */ 0, + /* no_ack = */ 1, + /* exclusive = */ 0, + /* arguments = */ AMQP_EMPTY_TABLE); + if ((cm_ret == NULL) && camqp_is_error(conf)) { + char errbuf[1024]; + ERROR("amqp plugin: amqp_basic_consume failed: %s", + camqp_strerror(conf, errbuf, sizeof(errbuf))); + camqp_close_connection(conf); + return -1; + } + + return 0; } /* }}} int camqp_setup_queue */ -static int camqp_connect (camqp_config_t *conf) /* {{{ */ +static int camqp_connect(camqp_config_t *conf) /* {{{ */ { - amqp_rpc_reply_t reply; - int sockfd; - int status; - - if (conf->connection != NULL) - return (0); - - conf->connection = amqp_new_connection (); - if (conf->connection == NULL) - { - ERROR ("amqp plugin: amqp_new_connection failed."); - return (ENOMEM); + static time_t last_connect_time; + + amqp_rpc_reply_t reply; + int status; +#ifdef HAVE_AMQP_TCP_SOCKET + amqp_socket_t *socket; +#else + int sockfd; +#endif + + if (conf->connection != NULL) + return 0; + + time_t now = time(NULL); + if (now < (last_connect_time + conf->connection_retry_delay)) { + DEBUG("amqp plugin: skipping connection retry, " + "ConnectionRetryDelay: %d", + conf->connection_retry_delay); + return 1; + } else { + DEBUG("amqp plugin: retrying connection"); + last_connect_time = now; + } + + conf->connection = amqp_new_connection(); + if (conf->connection == NULL) { + ERROR("amqp plugin: amqp_new_connection failed."); + return ENOMEM; + } + + char *host = conf->hosts[cdrand_u() % conf->hosts_count]; + INFO("amqp plugin: Connecting to %s", host); + +#ifdef HAVE_AMQP_TCP_SOCKET +#define CLOSE_SOCKET() /* amqp_destroy_connection() closes the socket for us \ + */ + + if (conf->tls_enabled) { + socket = amqp_ssl_socket_new(conf->connection); + if (!socket) { + ERROR("amqp plugin: amqp_ssl_socket_new failed."); + amqp_destroy_connection(conf->connection); + conf->connection = NULL; + return ENOMEM; } - sockfd = amqp_open_socket (CONF(conf, host), conf->port); - if (sockfd < 0) - { - char errbuf[1024]; - status = (-1) * sockfd; - ERROR ("amqp plugin: amqp_open_socket failed: %s", - sstrerror (status, errbuf, sizeof (errbuf))); - amqp_destroy_connection (conf->connection); +#if AMQP_VERSION >= 0x00080000 + amqp_ssl_socket_set_verify_peer(socket, conf->tls_verify_peer); + amqp_ssl_socket_set_verify_hostname(socket, conf->tls_verify_hostname); +#endif + + if (conf->tls_cacert) { + status = amqp_ssl_socket_set_cacert(socket, conf->tls_cacert); + if (status < 0) { + ERROR("amqp plugin: amqp_ssl_socket_set_cacert failed: %s", + amqp_error_string2(status)); + amqp_destroy_connection(conf->connection); conf->connection = NULL; - return (status); + return status; + } } - amqp_set_sockfd (conf->connection, sockfd); - - reply = amqp_login (conf->connection, CONF(conf, vhost), - /* channel max = */ 0, - /* frame max = */ 131072, - /* heartbeat = */ 0, - /* authentication = */ AMQP_SASL_METHOD_PLAIN, - CONF(conf, user), CONF(conf, password)); - if (reply.reply_type != AMQP_RESPONSE_NORMAL) - { - ERROR ("amqp plugin: amqp_login (vhost = %s, user = %s) failed.", - CONF(conf, vhost), CONF(conf, user)); - amqp_destroy_connection (conf->connection); - close (sockfd); + if (conf->tls_client_cert && conf->tls_client_key) { + status = amqp_ssl_socket_set_key(socket, conf->tls_client_cert, + conf->tls_client_key); + if (status < 0) { + ERROR("amqp plugin: amqp_ssl_socket_set_key failed: %s", + amqp_error_string2(status)); + amqp_destroy_connection(conf->connection); conf->connection = NULL; - return (1); + return status; + } } - - amqp_channel_open (conf->connection, /* channel = */ 1); - /* FIXME: Is checking "reply.reply_type" really correct here? How does - * it get set? --octo */ - if (reply.reply_type != AMQP_RESPONSE_NORMAL) - { - ERROR ("amqp plugin: amqp_channel_open failed."); - amqp_connection_close (conf->connection, AMQP_REPLY_SUCCESS); - amqp_destroy_connection (conf->connection); - close(sockfd); - conf->connection = NULL; - return (1); + } else { + socket = amqp_tcp_socket_new(conf->connection); + if (!socket) { + ERROR("amqp plugin: amqp_tcp_socket_new failed."); + amqp_destroy_connection(conf->connection); + conf->connection = NULL; + return ENOMEM; } + } - INFO ("amqp plugin: Successfully opened connection to vhost \"%s\" " - "on %s:%i.", CONF(conf, vhost), CONF(conf, host), conf->port); + status = amqp_socket_open(socket, host, conf->port); + if (status < 0) { + ERROR("amqp plugin: amqp_socket_open failed: %s", + amqp_error_string2(status)); + amqp_destroy_connection(conf->connection); + conf->connection = NULL; + return status; + } +#else /* HAVE_AMQP_TCP_SOCKET */ +#define CLOSE_SOCKET() close(sockfd) + /* this interface is deprecated as of rabbitmq-c 0.4 */ + sockfd = amqp_open_socket(host, conf->port); + if (sockfd < 0) { + status = (-1) * sockfd; + ERROR("amqp plugin: amqp_open_socket failed: %s", STRERROR(status)); + amqp_destroy_connection(conf->connection); + conf->connection = NULL; + return status; + } + amqp_set_sockfd(conf->connection, sockfd); +#endif - status = camqp_create_exchange (conf); - if (status != 0) - return (status); + reply = amqp_login(conf->connection, CONF(conf, vhost), + /* channel max = */ 0, + /* frame max = */ 131072, + /* heartbeat = */ 0, + /* authentication = */ AMQP_SASL_METHOD_PLAIN, + CONF(conf, user), CONF(conf, password)); + if (reply.reply_type != AMQP_RESPONSE_NORMAL) { + ERROR("amqp plugin: amqp_login (vhost = %s, user = %s) failed.", + CONF(conf, vhost), CONF(conf, user)); + amqp_destroy_connection(conf->connection); + CLOSE_SOCKET(); + conf->connection = NULL; + return 1; + } + + amqp_channel_open(conf->connection, /* channel = */ 1); + /* FIXME: Is checking "reply.reply_type" really correct here? How does + * it get set? --octo */ + if (reply.reply_type != AMQP_RESPONSE_NORMAL) { + ERROR("amqp plugin: amqp_channel_open failed."); + amqp_connection_close(conf->connection, AMQP_REPLY_SUCCESS); + amqp_destroy_connection(conf->connection); + CLOSE_SOCKET(); + conf->connection = NULL; + return 1; + } + + INFO("amqp plugin: Successfully opened connection to vhost \"%s\" " + "on %s:%i.", + CONF(conf, vhost), host, conf->port); - if (!conf->publish) - return (camqp_setup_queue (conf)); - return (0); + status = camqp_create_exchange(conf); + if (status != 0) + return status; + + if (!conf->publish) + return camqp_setup_queue(conf); + return 0; } /* }}} int camqp_connect */ -static int camqp_shutdown (void) /* {{{ */ +static int camqp_shutdown(void) /* {{{ */ { - size_t i; - - DEBUG ("amqp plugin: Shutting down %zu subscriber threads.", - subscriber_threads_num); - - subscriber_threads_running = 0; - for (i = 0; i < subscriber_threads_num; i++) - { - /* FIXME: Sending a signal is not very elegant here. Maybe find out how - * to use a timeout in the thread and check for the variable in regular - * intervals. */ - pthread_kill (subscriber_threads[i], SIGTERM); - pthread_join (subscriber_threads[i], /* retval = */ NULL); - } + DEBUG("amqp plugin: Shutting down %" PRIsz " subscriber threads.", + subscriber_threads_num); + + subscriber_threads_running = 0; + for (size_t i = 0; i < subscriber_threads_num; i++) { + /* FIXME: Sending a signal is not very elegant here. Maybe find out how + * to use a timeout in the thread and check for the variable in regular + * intervals. */ + pthread_kill(subscriber_threads[i], SIGTERM); + pthread_join(subscriber_threads[i], /* retval = */ NULL); + } - subscriber_threads_num = 0; - sfree (subscriber_threads); + subscriber_threads_num = 0; + sfree(subscriber_threads); - DEBUG ("amqp plugin: All subscriber threads exited."); + DEBUG("amqp plugin: All subscriber threads exited."); - return (0); + return 0; } /* }}} int camqp_shutdown */ /* * Subscribing code */ -static int camqp_read_body (camqp_config_t *conf, /* {{{ */ - size_t body_size, const char *content_type) -{ - char body[body_size + 1]; - char *body_ptr; - size_t received; - amqp_frame_t frame; - int status; - - memset (body, 0, sizeof (body)); - body_ptr = &body[0]; - received = 0; - - while (received < body_size) - { - status = amqp_simple_wait_frame (conf->connection, &frame); - if (status < 0) - { - char errbuf[1024]; - status = (-1) * status; - ERROR ("amqp plugin: amqp_simple_wait_frame failed: %s", - sstrerror (status, errbuf, sizeof (errbuf))); - camqp_close_connection (conf); - return (status); - } - - if (frame.frame_type != AMQP_FRAME_BODY) - { - NOTICE ("amqp plugin: Unexpected frame type: %#"PRIx8, - frame.frame_type); - return (-1); - } - - if ((body_size - received) < frame.payload.body_fragment.len) - { - WARNING ("amqp plugin: Body is larger than indicated by header."); - return (-1); - } - - memcpy (body_ptr, frame.payload.body_fragment.bytes, - frame.payload.body_fragment.len); - body_ptr += frame.payload.body_fragment.len; - received += frame.payload.body_fragment.len; - } /* while (received < body_size) */ - - if (strcasecmp ("text/collectd", content_type) == 0) - { - status = handle_putval (stderr, body); - if (status != 0) - ERROR ("amqp plugin: handle_putval failed with status %i.", - status); - return (status); - } - else if (strcasecmp ("application/json", content_type) == 0) - { - ERROR ("amqp plugin: camqp_read_body: Parsing JSON data has not " - "been implemented yet. FIXME!"); - return (0); - } - else - { - ERROR ("amqp plugin: camqp_read_body: Unknown content type \"%s\".", - content_type); - return (EINVAL); +static int camqp_read_body(camqp_config_t *conf, /* {{{ */ + size_t body_size, const char *content_type) { + char body[body_size + 1]; + char *body_ptr; + size_t received; + amqp_frame_t frame; + int status; + + memset(body, 0, sizeof(body)); + body_ptr = &body[0]; + received = 0; + + while (received < body_size) { + status = amqp_simple_wait_frame(conf->connection, &frame); + if (status < 0) { + status = (-1) * status; + ERROR("amqp plugin: amqp_simple_wait_frame failed: %s", STRERROR(status)); + camqp_close_connection(conf); + return status; } - /* not reached */ - return (0); -} /* }}} int camqp_read_body */ - -static int camqp_read_header (camqp_config_t *conf) /* {{{ */ -{ - int status; - amqp_frame_t frame; - amqp_basic_properties_t *properties; - char *content_type; - - status = amqp_simple_wait_frame (conf->connection, &frame); - if (status < 0) - { - char errbuf[1024]; - status = (-1) * status; - ERROR ("amqp plugin: amqp_simple_wait_frame failed: %s", - sstrerror (status, errbuf, sizeof (errbuf))); - camqp_close_connection (conf); - return (status); + if (frame.frame_type != AMQP_FRAME_BODY) { + NOTICE("amqp plugin: Unexpected frame type: %#" PRIx8, frame.frame_type); + return -1; } - if (frame.frame_type != AMQP_FRAME_HEADER) - { - NOTICE ("amqp plugin: Unexpected frame type: %#"PRIx8, - frame.frame_type); - return (-1); + if ((body_size - received) < frame.payload.body_fragment.len) { + WARNING("amqp plugin: Body is larger than indicated by header."); + return -1; } - properties = frame.payload.properties.decoded; - content_type = camqp_bytes_cstring (&properties->content_type); - if (content_type == NULL) - { - ERROR ("amqp plugin: Unable to determine content type."); - return (-1); - } + memcpy(body_ptr, frame.payload.body_fragment.bytes, + frame.payload.body_fragment.len); + body_ptr += frame.payload.body_fragment.len; + received += frame.payload.body_fragment.len; + } /* while (received < body_size) */ - status = camqp_read_body (conf, - (size_t) frame.payload.properties.body_size, - content_type); + if (strcasecmp("text/collectd", content_type) == 0) { + status = cmd_handle_putval(stderr, body); + if (status != 0) + ERROR("amqp plugin: cmd_handle_putval failed with status %i.", status); + return status; + } else if (strcasecmp("application/json", content_type) == 0) { + ERROR("amqp plugin: camqp_read_body: Parsing JSON data has not " + "been implemented yet. FIXME!"); + return 0; + } else { + ERROR("amqp plugin: camqp_read_body: Unknown content type \"%s\".", + content_type); + return EINVAL; + } + + /* not reached */ + return 0; +} /* }}} int camqp_read_body */ - sfree (content_type); - return (status); +static int camqp_read_header(camqp_config_t *conf) /* {{{ */ +{ + int status; + amqp_frame_t frame; + amqp_basic_properties_t *properties; + char *content_type; + + status = amqp_simple_wait_frame(conf->connection, &frame); + if (status < 0) { + status = (-1) * status; + ERROR("amqp plugin: amqp_simple_wait_frame failed: %s", STRERROR(status)); + camqp_close_connection(conf); + return status; + } + + if (frame.frame_type != AMQP_FRAME_HEADER) { + NOTICE("amqp plugin: Unexpected frame type: %#" PRIx8, frame.frame_type); + return -1; + } + + properties = frame.payload.properties.decoded; + content_type = camqp_bytes_cstring(&properties->content_type); + if (content_type == NULL) { + ERROR("amqp plugin: Unable to determine content type."); + return -1; + } + + status = camqp_read_body(conf, (size_t)frame.payload.properties.body_size, + content_type); + + sfree(content_type); + return status; } /* }}} int camqp_read_header */ -static void *camqp_subscribe_thread (void *user_data) /* {{{ */ +static void *camqp_subscribe_thread(void *user_data) /* {{{ */ { - camqp_config_t *conf = user_data; - int status; - - cdtime_t interval = plugin_get_interval (); - - while (subscriber_threads_running) - { - amqp_frame_t frame; - - status = camqp_connect (conf); - if (status != 0) - { - struct timespec ts_interval; - ERROR ("amqp plugin: camqp_connect failed. " - "Will sleep for %.3f seconds.", - CDTIME_T_TO_DOUBLE (interval)); - CDTIME_T_TO_TIMESPEC (interval, &ts_interval); - nanosleep (&ts_interval, /* remaining = */ NULL); - continue; - } - - status = amqp_simple_wait_frame (conf->connection, &frame); - if (status < 0) - { - struct timespec ts_interval; - ERROR ("amqp plugin: amqp_simple_wait_frame failed. " - "Will sleep for %.3f seconds.", - CDTIME_T_TO_DOUBLE (interval)); - camqp_close_connection (conf); - CDTIME_T_TO_TIMESPEC (interval, &ts_interval); - nanosleep (&ts_interval, /* remaining = */ NULL); - continue; - } - - if (frame.frame_type != AMQP_FRAME_METHOD) - { - DEBUG ("amqp plugin: Unexpected frame type: %#"PRIx8, - frame.frame_type); - continue; - } + camqp_config_t *conf = user_data; + int status; - if (frame.payload.method.id != AMQP_BASIC_DELIVER_METHOD) - { - DEBUG ("amqp plugin: Unexpected method id: %#"PRIx32, - frame.payload.method.id); - continue; - } + cdtime_t interval = plugin_get_interval(); - status = camqp_read_header (conf); + while (subscriber_threads_running) { + amqp_frame_t frame; - amqp_maybe_release_buffers (conf->connection); - } /* while (subscriber_threads_running) */ + status = camqp_connect(conf); + if (status != 0) { + ERROR("amqp plugin: camqp_connect failed. " + "Will sleep for %.3f seconds.", + CDTIME_T_TO_DOUBLE(interval)); + nanosleep(&CDTIME_T_TO_TIMESPEC(interval), /* remaining = */ NULL); + continue; + } - camqp_config_free (conf); - pthread_exit (NULL); - return (NULL); -} /* }}} void *camqp_subscribe_thread */ + status = amqp_simple_wait_frame(conf->connection, &frame); + if (status < 0) { + ERROR("amqp plugin: amqp_simple_wait_frame failed. " + "Will sleep for %.3f seconds.", + CDTIME_T_TO_DOUBLE(interval)); + camqp_close_connection(conf); + nanosleep(&CDTIME_T_TO_TIMESPEC(interval), /* remaining = */ NULL); + continue; + } -static int camqp_subscribe_init (camqp_config_t *conf) /* {{{ */ -{ - int status; - pthread_t *tmp; - - tmp = realloc (subscriber_threads, - sizeof (*subscriber_threads) * (subscriber_threads_num + 1)); - if (tmp == NULL) - { - ERROR ("amqp plugin: realloc failed."); - camqp_config_free (conf); - return (ENOMEM); + if (frame.frame_type != AMQP_FRAME_METHOD) { + DEBUG("amqp plugin: Unexpected frame type: %#" PRIx8, frame.frame_type); + continue; } - subscriber_threads = tmp; - tmp = subscriber_threads + subscriber_threads_num; - memset (tmp, 0, sizeof (*tmp)); - status = plugin_thread_create (tmp, /* attr = */ NULL, - camqp_subscribe_thread, conf); - if (status != 0) - { - char errbuf[1024]; - ERROR ("amqp plugin: pthread_create failed: %s", - sstrerror (status, errbuf, sizeof (errbuf))); - camqp_config_free (conf); - return (status); + if (frame.payload.method.id != AMQP_BASIC_DELIVER_METHOD) { + DEBUG("amqp plugin: Unexpected method id: %#" PRIx32, + frame.payload.method.id); + continue; } - subscriber_threads_num++; + camqp_read_header(conf); + + amqp_maybe_release_buffers(conf->connection); + } /* while (subscriber_threads_running) */ - return (0); + camqp_config_free(conf); + pthread_exit(NULL); + return NULL; +} /* }}} void *camqp_subscribe_thread */ + +static int camqp_subscribe_init(camqp_config_t *conf) /* {{{ */ +{ + int status; + pthread_t *tmp; + + tmp = realloc(subscriber_threads, + sizeof(*subscriber_threads) * (subscriber_threads_num + 1)); + if (tmp == NULL) { + ERROR("amqp plugin: realloc failed."); + sfree(subscriber_threads); + return ENOMEM; + } + subscriber_threads = tmp; + tmp = subscriber_threads + subscriber_threads_num; + memset(tmp, 0, sizeof(*tmp)); + + status = + plugin_thread_create(tmp, camqp_subscribe_thread, conf, "amqp subscribe"); + if (status != 0) { + ERROR("amqp plugin: pthread_create failed: %s", STRERROR(status)); + return status; + } + + subscriber_threads_num++; + + return 0; } /* }}} int camqp_subscribe_init */ /* * Publishing code */ /* XXX: You must hold "conf->lock" when calling this function! */ -static int camqp_write_locked (camqp_config_t *conf, /* {{{ */ - const char *buffer, const char *routing_key) -{ - amqp_basic_properties_t props; - int status; - - status = camqp_connect (conf); - if (status != 0) - return (status); - - memset (&props, 0, sizeof (props)); - props._flags = AMQP_BASIC_CONTENT_TYPE_FLAG - | AMQP_BASIC_DELIVERY_MODE_FLAG - | AMQP_BASIC_APP_ID_FLAG; - if (conf->format == CAMQP_FORMAT_COMMAND) - props.content_type = amqp_cstring_bytes("text/collectd"); - else if (conf->format == CAMQP_FORMAT_JSON) - props.content_type = amqp_cstring_bytes("application/json"); - else if (conf->format == CAMQP_FORMAT_GRAPHITE) - props.content_type = amqp_cstring_bytes("text/graphite"); - else - assert (23 == 42); - props.delivery_mode = conf->delivery_mode; - props.app_id = amqp_cstring_bytes("collectd"); - - status = amqp_basic_publish(conf->connection, - /* channel = */ 1, - amqp_cstring_bytes(CONF(conf, exchange)), - amqp_cstring_bytes (routing_key), - /* mandatory = */ 0, - /* immediate = */ 0, - &props, - amqp_cstring_bytes(buffer)); - if (status != 0) - { - ERROR ("amqp plugin: amqp_basic_publish failed with status %i.", - status); - camqp_close_connection (conf); - } - - return (status); +static int camqp_write_locked(camqp_config_t *conf, /* {{{ */ + const char *buffer, const char *routing_key) { + int status; + + status = camqp_connect(conf); + if (status != 0) + return status; + + amqp_basic_properties_t props = {._flags = AMQP_BASIC_CONTENT_TYPE_FLAG | + AMQP_BASIC_DELIVERY_MODE_FLAG | + AMQP_BASIC_APP_ID_FLAG, + .delivery_mode = conf->delivery_mode, + .app_id = amqp_cstring_bytes("collectd")}; + + if (conf->format == CAMQP_FORMAT_COMMAND) + props.content_type = amqp_cstring_bytes("text/collectd"); + else if (conf->format == CAMQP_FORMAT_JSON) + props.content_type = amqp_cstring_bytes("application/json"); + else if (conf->format == CAMQP_FORMAT_GRAPHITE) + props.content_type = amqp_cstring_bytes("text/graphite"); + else + assert(23 == 42); + + status = amqp_basic_publish( + conf->connection, + /* channel = */ 1, amqp_cstring_bytes(CONF(conf, exchange)), + amqp_cstring_bytes(routing_key), + /* mandatory = */ 0, + /* immediate = */ 0, &props, amqp_cstring_bytes(buffer)); + if (status != 0) { + ERROR("amqp plugin: amqp_basic_publish failed with status %i.", status); + camqp_close_connection(conf); + } + + return status; } /* }}} int camqp_write_locked */ -static int camqp_write (const data_set_t *ds, const value_list_t *vl, /* {{{ */ - user_data_t *user_data) -{ - camqp_config_t *conf = user_data->data; - char routing_key[6 * DATA_MAX_NAME_LEN]; - char buffer[4096]; - int status; - - if ((ds == NULL) || (vl == NULL) || (conf == NULL)) - return (EINVAL); - - memset (buffer, 0, sizeof (buffer)); - - if (conf->routing_key != NULL) - { - sstrncpy (routing_key, conf->routing_key, sizeof (routing_key)); - } - else - { - size_t i; - ssnprintf (routing_key, sizeof (routing_key), "collectd/%s/%s/%s/%s/%s", - vl->host, - vl->plugin, vl->plugin_instance, - vl->type, vl->type_instance); - - /* Switch slashes (the only character forbidden by collectd) and dots - * (the separation character used by AMQP). */ - for (i = 0; routing_key[i] != 0; i++) - { - if (routing_key[i] == '.') - routing_key[i] = '/'; - else if (routing_key[i] == '/') - routing_key[i] = '.'; - } +static int camqp_write(const data_set_t *ds, const value_list_t *vl, /* {{{ */ + user_data_t *user_data) { + camqp_config_t *conf = user_data->data; + char routing_key[6 * DATA_MAX_NAME_LEN]; + char buffer[8192]; + int status; + + if ((ds == NULL) || (vl == NULL) || (conf == NULL)) + return EINVAL; + + if (conf->routing_key != NULL) { + sstrncpy(routing_key, conf->routing_key, sizeof(routing_key)); + } else { + 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). */ + for (size_t i = 0; routing_key[i] != 0; i++) { + if (routing_key[i] == '.') + routing_key[i] = '/'; + else if (routing_key[i] == '/') + routing_key[i] = '.'; } + } - if (conf->format == CAMQP_FORMAT_COMMAND) - { - status = create_putval (buffer, sizeof (buffer), ds, vl); - if (status != 0) - { - ERROR ("amqp plugin: create_putval failed with status %i.", - status); - return (status); - } + if (conf->format == CAMQP_FORMAT_COMMAND) { + status = cmd_create_putval(buffer, sizeof(buffer), ds, vl); + if (status != 0) { + ERROR("amqp plugin: cmd_create_putval failed with status %i.", status); + return status; } - else if (conf->format == CAMQP_FORMAT_JSON) - { - size_t bfree = sizeof (buffer); - size_t bfill = 0; - - format_json_initialize (buffer, &bfill, &bfree); - format_json_value_list (buffer, &bfill, &bfree, ds, vl, conf->store_rates); - format_json_finalize (buffer, &bfill, &bfree); - } - else if (conf->format == CAMQP_FORMAT_GRAPHITE) - { - status = format_graphite (buffer, sizeof (buffer), ds, vl, - conf->prefix, conf->postfix, conf->escape_char, - conf->graphite_flags); - if (status != 0) - { - ERROR ("amqp plugin: format_graphite failed with status %i.", - status); - return (status); - } - } - else - { - ERROR ("amqp plugin: Invalid format (%i).", conf->format); - return (-1); + } else if (conf->format == CAMQP_FORMAT_JSON) { + size_t bfree = sizeof(buffer); + size_t bfill = 0; + + format_json_initialize(buffer, &bfill, &bfree); + format_json_value_list(buffer, &bfill, &bfree, ds, vl, conf->store_rates); + format_json_finalize(buffer, &bfill, &bfree); + } else if (conf->format == CAMQP_FORMAT_GRAPHITE) { + status = + format_graphite(buffer, sizeof(buffer), ds, vl, conf->prefix, + conf->postfix, conf->escape_char, conf->graphite_flags); + if (status != 0) { + ERROR("amqp plugin: format_graphite failed with status %i.", status); + return status; } + } else { + ERROR("amqp plugin: Invalid format (%i).", conf->format); + return -1; + } - pthread_mutex_lock (&conf->lock); - status = camqp_write_locked (conf, buffer, routing_key); - pthread_mutex_unlock (&conf->lock); + pthread_mutex_lock(&conf->lock); + status = camqp_write_locked(conf, buffer, routing_key); + pthread_mutex_unlock(&conf->lock); - return (status); + return status; } /* }}} int camqp_write */ /* * Config handling */ -static int camqp_config_set_format (oconfig_item_t *ci, /* {{{ */ - camqp_config_t *conf) -{ - char *string; - int status; - - string = NULL; - status = cf_util_get_string (ci, &string); - if (status != 0) - return (status); - - assert (string != NULL); - if (strcasecmp ("Command", string) == 0) - conf->format = CAMQP_FORMAT_COMMAND; - else if (strcasecmp ("JSON", string) == 0) - conf->format = CAMQP_FORMAT_JSON; - else if (strcasecmp ("Graphite", string) == 0) - conf->format = CAMQP_FORMAT_GRAPHITE; - else - { - WARNING ("amqp plugin: Invalid format string: %s", - string); - } +static int camqp_config_set_format(oconfig_item_t *ci, /* {{{ */ + camqp_config_t *conf) { + char *string; + int status; + + string = NULL; + status = cf_util_get_string(ci, &string); + if (status != 0) + return status; + + assert(string != NULL); + if (strcasecmp("Command", string) == 0) + conf->format = CAMQP_FORMAT_COMMAND; + else if (strcasecmp("JSON", string) == 0) + conf->format = CAMQP_FORMAT_JSON; + else if (strcasecmp("Graphite", string) == 0) + conf->format = CAMQP_FORMAT_GRAPHITE; + else { + WARNING("amqp plugin: Invalid format string: %s", string); + } - free (string); + free(string); - return (0); + return 0; } /* }}} int config_set_string */ -static int camqp_config_connection (oconfig_item_t *ci, /* {{{ */ - _Bool publish) -{ - camqp_config_t *conf; - int status; - int i; - - conf = malloc (sizeof (*conf)); - if (conf == NULL) - { - ERROR ("amqp plugin: malloc failed."); - return (ENOMEM); - } - - /* Initialize "conf" {{{ */ - memset (conf, 0, sizeof (*conf)); - conf->publish = publish; - conf->name = NULL; - conf->format = CAMQP_FORMAT_COMMAND; - conf->host = NULL; - conf->port = 5672; - conf->vhost = NULL; - conf->user = NULL; - conf->password = NULL; - conf->exchange = NULL; - conf->routing_key = NULL; - /* publish only */ - conf->delivery_mode = CAMQP_DM_VOLATILE; - conf->store_rates = 0; - conf->graphite_flags = 0; - /* publish & graphite only */ - conf->prefix = NULL; - conf->postfix = NULL; - conf->escape_char = '_'; - /* subscribe only */ - conf->exchange_type = NULL; - conf->queue = NULL; - /* general */ - conf->connection = NULL; - pthread_mutex_init (&conf->lock, /* attr = */ NULL); - /* }}} */ - - status = cf_util_get_string (ci, &conf->name); - if (status != 0) - { - sfree (conf); - return (status); - } - - for (i = 0; i < ci->children_num; i++) - { - oconfig_item_t *child = ci->children + i; - - if (strcasecmp ("Host", child->key) == 0) - status = cf_util_get_string (child, &conf->host); - else if (strcasecmp ("Port", child->key) == 0) - { - status = cf_util_get_port_number (child); - if (status > 0) - { - conf->port = status; - status = 0; - } - } - else if (strcasecmp ("VHost", child->key) == 0) - status = cf_util_get_string (child, &conf->vhost); - else if (strcasecmp ("User", child->key) == 0) - status = cf_util_get_string (child, &conf->user); - else if (strcasecmp ("Password", child->key) == 0) - status = cf_util_get_string (child, &conf->password); - else if (strcasecmp ("Exchange", child->key) == 0) - status = cf_util_get_string (child, &conf->exchange); - else if ((strcasecmp ("ExchangeType", child->key) == 0) && !publish) - status = cf_util_get_string (child, &conf->exchange_type); - else if ((strcasecmp ("Queue", child->key) == 0) && !publish) - status = cf_util_get_string (child, &conf->queue); - else if (strcasecmp ("RoutingKey", child->key) == 0) - status = cf_util_get_string (child, &conf->routing_key); - else if ((strcasecmp ("Persistent", child->key) == 0) && publish) - { - _Bool tmp = 0; - status = cf_util_get_boolean (child, &tmp); - if (tmp) - conf->delivery_mode = CAMQP_DM_PERSISTENT; - else - conf->delivery_mode = CAMQP_DM_VOLATILE; - } - else if ((strcasecmp ("StoreRates", child->key) == 0) && publish) - { - status = cf_util_get_boolean (child, &conf->store_rates); - (void) cf_util_get_flag (child, &conf->graphite_flags, - GRAPHITE_STORE_RATES); - } - else if ((strcasecmp ("Format", child->key) == 0) && publish) - status = camqp_config_set_format (child, conf); - else if ((strcasecmp ("GraphiteSeparateInstances", child->key) == 0) && publish) - status = cf_util_get_flag (child, &conf->graphite_flags, - GRAPHITE_SEPARATE_INSTANCES); - else if ((strcasecmp ("GraphiteAlwaysAppendDS", child->key) == 0) && publish) - status = cf_util_get_flag (child, &conf->graphite_flags, - GRAPHITE_ALWAYS_APPEND_DS); - else if ((strcasecmp ("GraphitePrefix", child->key) == 0) && publish) - status = cf_util_get_string (child, &conf->prefix); - else if ((strcasecmp ("GraphitePostfix", child->key) == 0) && publish) - status = cf_util_get_string (child, &conf->postfix); - else if ((strcasecmp ("GraphiteEscapeChar", child->key) == 0) && publish) - { - char *tmp_buff = NULL; - status = cf_util_get_string (child, &tmp_buff); - if (strlen (tmp_buff) > 1) - WARNING ("amqp plugin: The option \"GraphiteEscapeChar\" handles " - "only one character. Others will be ignored."); - conf->escape_char = tmp_buff[0]; - sfree (tmp_buff); +static int camqp_config_connection(oconfig_item_t *ci, /* {{{ */ + bool publish) { + camqp_config_t *conf; + int status; + + conf = calloc(1, sizeof(*conf)); + if (conf == NULL) { + ERROR("amqp plugin: calloc failed."); + return ENOMEM; + } + + /* Initialize "conf" {{{ */ + conf->publish = publish; + conf->name = NULL; + conf->format = CAMQP_FORMAT_COMMAND; + conf->hosts = NULL; + conf->hosts_count = 0; + conf->port = 5672; + conf->vhost = NULL; + conf->user = NULL; + conf->password = NULL; + conf->tls_enabled = false; + conf->tls_verify_peer = true; + conf->tls_verify_hostname = true; + conf->tls_cacert = NULL; + conf->tls_client_cert = NULL; + conf->tls_client_key = NULL; + conf->exchange = NULL; + conf->routing_key = NULL; + conf->connection_retry_delay = 0; + + /* publish only */ + conf->delivery_mode = CAMQP_DM_VOLATILE; + conf->store_rates = false; + conf->graphite_flags = 0; + /* publish & graphite only */ + conf->prefix = NULL; + conf->postfix = NULL; + conf->escape_char = '_'; + /* subscribe only */ + conf->exchange_type = NULL; + conf->queue = NULL; + conf->queue_durable = false; + conf->queue_auto_delete = true; + /* general */ + conf->connection = NULL; + pthread_mutex_init(&conf->lock, /* attr = */ NULL); + /* }}} */ + + status = cf_util_get_string(ci, &conf->name); + if (status != 0) { + sfree(conf); + return status; + } + + for (int i = 0; i < ci->children_num; i++) { + oconfig_item_t *child = ci->children + i; + + if (strcasecmp("Host", child->key) == 0) { + for (int j = 0; j < child->values_num; j++) { + if (child->values[j].type != OCONFIG_TYPE_STRING) { + status = EINVAL; + ERROR("amqp plugin: Host arguments must be strings"); + break; } - else - WARNING ("amqp plugin: Ignoring unknown " - "configuration option \"%s\".", child->key); - if (status != 0) - break; - } /* for (i = 0; i < ci->children_num; i++) */ - - if ((status == 0) && (conf->exchange == NULL)) - { - if (conf->exchange_type != NULL) - WARNING ("amqp plugin: The option \"ExchangeType\" was given " - "without the \"Exchange\" option. It will be ignored."); - - if (!publish && (conf->routing_key != NULL)) - WARNING ("amqp plugin: The option \"RoutingKey\" was given " - "without the \"Exchange\" option. It will be ignored."); - - } + status = strarray_add(&conf->hosts, &conf->hosts_count, + child->values[j].value.string); + if (status) { + ERROR("amqp plugin: Host configuration failed: %d", status); + break; + } + } + } else if (strcasecmp("Port", child->key) == 0) { + status = cf_util_get_port_number(child); + if (status > 0) { + conf->port = status; + status = 0; + } + } else if (strcasecmp("VHost", child->key) == 0) + status = cf_util_get_string(child, &conf->vhost); + else if (strcasecmp("User", child->key) == 0) + status = cf_util_get_string(child, &conf->user); + else if (strcasecmp("Password", child->key) == 0) + status = cf_util_get_string(child, &conf->password); + else if (strcasecmp("TLSEnabled", child->key) == 0) + status = cf_util_get_boolean(child, &conf->tls_enabled); + else if (strcasecmp("TLSVerifyPeer", child->key) == 0) + status = cf_util_get_boolean(child, &conf->tls_verify_peer); + else if (strcasecmp("TLSVerifyHostName", child->key) == 0) + status = cf_util_get_boolean(child, &conf->tls_verify_hostname); + else if (strcasecmp("TLSCACert", child->key) == 0) + status = cf_util_get_string(child, &conf->tls_cacert); + else if (strcasecmp("TLSClientCert", child->key) == 0) + status = cf_util_get_string(child, &conf->tls_client_cert); + else if (strcasecmp("TLSClientKey", child->key) == 0) + status = cf_util_get_string(child, &conf->tls_client_key); + else if (strcasecmp("Exchange", child->key) == 0) + status = cf_util_get_string(child, &conf->exchange); + else if (strcasecmp("ExchangeType", child->key) == 0) + status = cf_util_get_string(child, &conf->exchange_type); + else if ((strcasecmp("Queue", child->key) == 0) && !publish) + status = cf_util_get_string(child, &conf->queue); + else if ((strcasecmp("QueueDurable", child->key) == 0) && !publish) + status = cf_util_get_boolean(child, &conf->queue_durable); + else if ((strcasecmp("QueueAutoDelete", child->key) == 0) && !publish) + status = cf_util_get_boolean(child, &conf->queue_auto_delete); + else if (strcasecmp("RoutingKey", child->key) == 0) + status = cf_util_get_string(child, &conf->routing_key); + else if ((strcasecmp("Persistent", child->key) == 0) && publish) { + bool tmp = 0; + status = cf_util_get_boolean(child, &tmp); + if (tmp) + conf->delivery_mode = CAMQP_DM_PERSISTENT; + else + conf->delivery_mode = CAMQP_DM_VOLATILE; + } else if ((strcasecmp("StoreRates", child->key) == 0) && publish) { + status = cf_util_get_boolean(child, &conf->store_rates); + (void)cf_util_get_flag(child, &conf->graphite_flags, + GRAPHITE_STORE_RATES); + } else if ((strcasecmp("Format", child->key) == 0) && publish) + status = camqp_config_set_format(child, conf); + else if ((strcasecmp("GraphiteSeparateInstances", child->key) == 0) && + publish) + status = cf_util_get_flag(child, &conf->graphite_flags, + GRAPHITE_SEPARATE_INSTANCES); + else if ((strcasecmp("GraphiteAlwaysAppendDS", child->key) == 0) && publish) + status = cf_util_get_flag(child, &conf->graphite_flags, + GRAPHITE_ALWAYS_APPEND_DS); + else if ((strcasecmp("GraphitePreserveSeparator", child->key) == 0) && + publish) + status = cf_util_get_flag(child, &conf->graphite_flags, + GRAPHITE_PRESERVE_SEPARATOR); + else if ((strcasecmp("GraphitePrefix", child->key) == 0) && publish) + status = cf_util_get_string(child, &conf->prefix); + else if ((strcasecmp("GraphitePostfix", child->key) == 0) && publish) + status = cf_util_get_string(child, &conf->postfix); + else if ((strcasecmp("GraphiteEscapeChar", child->key) == 0) && publish) { + char *tmp_buff = NULL; + status = cf_util_get_string(child, &tmp_buff); + if (strlen(tmp_buff) > 1) + WARNING("amqp plugin: The option \"GraphiteEscapeChar\" handles " + "only one character. Others will be ignored."); + conf->escape_char = tmp_buff[0]; + sfree(tmp_buff); + } else if (strcasecmp("ConnectionRetryDelay", child->key) == 0) + status = cf_util_get_int(child, &conf->connection_retry_delay); + else + WARNING("amqp plugin: Ignoring unknown " + "configuration option \"%s\".", + child->key); if (status != 0) - { - camqp_config_free (conf); - return (status); + break; + } /* for (i = 0; i < ci->children_num; i++) */ + + if (status == 0 && conf->hosts_count == 0) { + status = strarray_add(&conf->hosts, &conf->hosts_count, "localhost"); + if (status) + ERROR("amqp plugin: Host configuration failed: %d", status); + } + + if ((status == 0) && (conf->exchange == NULL)) { + if (conf->exchange_type != NULL) + WARNING("amqp plugin: The option \"ExchangeType\" was given " + "without the \"Exchange\" option. It will be ignored."); + + if (!publish && (conf->routing_key != NULL)) + WARNING("amqp plugin: The option \"RoutingKey\" was given " + "without the \"Exchange\" option. It will be ignored."); + } + +#if !defined(AMQP_VERSION) || AMQP_VERSION < 0x00040000 + if (status == 0 && conf->tls_enabled) { + ERROR("amqp plugin: TLSEnabled is set but not supported. " + "rebuild collectd with rabbitmq-c >= 0.4"); + status = 1; + } +#endif +#if !defined(AMQP_VERSION) || AMQP_VERSION < 0x00080000 + if (status == 0 && (!conf->tls_verify_peer || !conf->tls_verify_hostname)) { + ERROR("amqp plugin: disabling TLSVerify* is not supported. " + "rebuild collectd with rabbitmq-c >= 0.8"); + status = 1; + } +#endif + if (status == 0 && + (conf->tls_client_cert != NULL || conf->tls_client_key != NULL)) { + if (conf->tls_client_cert == NULL || conf->tls_client_key == NULL) { + ERROR("amqp plugin: only one of TLSClientCert/TLSClientKey is " + "configured. need both or neither."); + status = 1; } - - if (conf->exchange != NULL) - { - DEBUG ("amqp plugin: camqp_config_connection: exchange = %s;", - conf->exchange); + } + + if (status != 0) { + camqp_config_free(conf); + return status; + } + + if (conf->exchange != NULL) { + DEBUG("amqp plugin: camqp_config_connection: exchange = %s;", + conf->exchange); + } + + if (publish) { + char cbname[128]; + 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, + }); + if (status != 0) { + camqp_config_free(conf); + return status; } - - if (publish) - { - char cbname[128]; - user_data_t ud = { conf, camqp_config_free }; - - ssnprintf (cbname, sizeof (cbname), "amqp/%s", conf->name); - - status = plugin_register_write (cbname, camqp_write, &ud); - if (status != 0) - { - camqp_config_free (conf); - return (status); - } - } - else - { - status = camqp_subscribe_init (conf); - if (status != 0) - { - camqp_config_free (conf); - return (status); - } + } else { + status = camqp_subscribe_init(conf); + if (status != 0) { + camqp_config_free(conf); + return status; } + } - return (0); + return 0; } /* }}} int camqp_config_connection */ -static int camqp_config (oconfig_item_t *ci) /* {{{ */ +static int camqp_config(oconfig_item_t *ci) /* {{{ */ { - int i; - - for (i = 0; i < ci->children_num; i++) - { - oconfig_item_t *child = ci->children + i; - - if (strcasecmp ("Publish", child->key) == 0) - camqp_config_connection (child, /* publish = */ 1); - else if (strcasecmp ("Subscribe", child->key) == 0) - camqp_config_connection (child, /* publish = */ 0); - else - WARNING ("amqp plugin: Ignoring unknown config option \"%s\".", - child->key); - } /* for (ci->children_num) */ - - return (0); + for (int i = 0; i < ci->children_num; i++) { + oconfig_item_t *child = ci->children + i; + + if (strcasecmp("Publish", child->key) == 0) + camqp_config_connection(child, /* publish = */ true); + else if (strcasecmp("Subscribe", child->key) == 0) + camqp_config_connection(child, /* publish = */ false); + else + WARNING("amqp plugin: Ignoring unknown config option \"%s\".", + child->key); + } /* for (ci->children_num) */ + + return 0; } /* }}} int camqp_config */ -void module_register (void) -{ - plugin_register_complex_config ("amqp", camqp_config); - plugin_register_shutdown ("amqp", camqp_shutdown); +void module_register(void) { + plugin_register_complex_config("amqp", camqp_config); + plugin_register_shutdown("amqp", camqp_shutdown); } /* void module_register */ - -/* vim: set sw=4 sts=4 et fdm=marker : */ diff --git a/src/amqp1.c b/src/amqp1.c new file mode 100644 index 0000000000..c4f14d12c7 --- /dev/null +++ b/src/amqp1.c @@ -0,0 +1,790 @@ +/** + * collectd - src/amqp1.c + * Copyright(c) 2017 Red Hat Inc. + * + * 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: + * Andy Smith + */ + +#include "collectd.h" + +#include "plugin.h" +#include "utils/cmds/putval.h" +#include "utils/common/common.h" +#include "utils/deq/deq.h" +#include "utils/format_graphite/format_graphite.h" +#include "utils/format_json/format_json.h" +#include "utils_random.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#define BUFSIZE 8192 +#define AMQP1_FORMAT_JSON 0 +#define AMQP1_FORMAT_COMMAND 1 +#define AMQP1_FORMAT_GRAPHITE 2 + +typedef struct amqp1_config_transport_s { + DEQ_LINKS(struct amqp1_config_transport_s); + char *name; + char *host; + char *port; + char *user; + char *password; + char *address; + int retry_delay; + int sendq_limit; +} amqp1_config_transport_t; + +typedef struct amqp1_config_instance_s { + DEQ_LINKS(struct amqp1_config_instance_s); + char *name; + bool notify; + uint8_t format; + unsigned int graphite_flags; + bool store_rates; + char *prefix; + char *postfix; + char escape_char; + bool pre_settle; + char send_to[1024]; +} amqp1_config_instance_t; + +DEQ_DECLARE(amqp1_config_instance_t, amqp1_config_instance_list_t); + +typedef struct cd_message_s { + DEQ_LINKS(struct cd_message_s); + pn_rwbytes_t mbuf; + amqp1_config_instance_t *instance; +} cd_message_t; + +DEQ_DECLARE(cd_message_t, cd_message_list_t); + +/* + * Globals + */ +static pn_connection_t *conn; +static pn_link_t *sender; +static pn_proactor_t *proactor; +static pthread_mutex_t send_lock; +static cd_message_list_t out_messages; +static uint64_t cd_tag = 1; +static uint64_t acknowledged; +static amqp1_config_transport_t *transport; +static bool stopping; +static bool event_thread_running; +static pthread_t event_thread_id; + +/* + * Functions + */ +static void cd_message_free(cd_message_t *cdm) { + free(cdm->mbuf.start); + free(cdm); +} /* }}} void cd_message_free */ + +static int amqp1_send_out_messages(pn_link_t *link) /* {{{ */ +{ + uint64_t dtag; + cd_message_list_t to_send; + cd_message_t *cdm; + int link_credit = pn_link_credit(link); + int event_count = 0; + pn_delivery_t *dlv; + + if (stopping) { + return 0; + } + + DEQ_INIT(to_send); + + pthread_mutex_lock(&send_lock); + + if (link_credit > 0) { + dtag = cd_tag; + cdm = DEQ_HEAD(out_messages); + while (cdm) { + DEQ_REMOVE_HEAD(out_messages); + DEQ_INSERT_TAIL(to_send, cdm); + if (DEQ_SIZE(to_send) == (size_t)link_credit) + break; + cdm = DEQ_HEAD(out_messages); + } + cd_tag += DEQ_SIZE(to_send); + } + + pthread_mutex_unlock(&send_lock); + + /* message is already formatted and encoded */ + cdm = DEQ_HEAD(to_send); + while (cdm) { + DEQ_REMOVE_HEAD(to_send); + dtag++; + dlv = pn_delivery(link, pn_dtag((const char *)&dtag, sizeof(dtag))); + pn_link_send(link, cdm->mbuf.start, cdm->mbuf.size); + pn_link_advance(link); + if (cdm->instance->pre_settle == true) { + pn_delivery_settle(dlv); + } + event_count++; + cd_message_free(cdm); + cdm = DEQ_HEAD(to_send); + } + + return event_count; +} /* }}} int amqp1_send_out_messages */ + +static void check_condition(pn_event_t *e, pn_condition_t *cond) /* {{{ */ +{ + if (pn_condition_is_set(cond)) { + ERROR("amqp1 plugin: %s: %s: %s", pn_event_type_name(pn_event_type(e)), + pn_condition_get_name(cond), pn_condition_get_description(cond)); + pn_connection_close(pn_event_connection(e)); + conn = NULL; + } +} /* }}} void check_condition */ + +static bool handle(pn_event_t *event) /* {{{ */ +{ + + switch (pn_event_type(event)) { + + case PN_CONNECTION_INIT: { + conn = pn_event_connection(event); + pn_connection_set_container(conn, transport->name); + pn_connection_open(conn); + pn_session_t *ssn = pn_session(conn); + pn_session_open(ssn); + sender = pn_sender(ssn, "cd-sender"); + pn_link_set_snd_settle_mode(sender, PN_SND_MIXED); + pn_link_open(sender); + break; + } + + case PN_LINK_FLOW: { + /* peer has given us credit, send outbound messages */ + amqp1_send_out_messages(sender); + break; + } + + case PN_DELIVERY: { + /* acknowledgement from peer that a message was delivered */ + pn_delivery_t *dlv = pn_event_delivery(event); + if (pn_delivery_remote_state(dlv) == PN_ACCEPTED) { + pn_delivery_settle(dlv); + acknowledged++; + } + break; + } + + case PN_CONNECTION_WAKE: { + if (!stopping) { + amqp1_send_out_messages(sender); + } + break; + } + + case PN_TRANSPORT_CLOSED: { + check_condition(event, pn_transport_condition(pn_event_transport(event))); + break; + } + + case PN_CONNECTION_REMOTE_CLOSE: { + check_condition(event, + pn_session_remote_condition(pn_event_session(event))); + pn_connection_close(pn_event_connection(event)); + break; + } + + case PN_SESSION_REMOTE_CLOSE: { + check_condition(event, + pn_session_remote_condition(pn_event_session(event))); + pn_connection_close(pn_event_connection(event)); + break; + } + + case PN_LINK_REMOTE_CLOSE: + case PN_LINK_REMOTE_DETACH: { + check_condition(event, pn_link_remote_condition(pn_event_link(event))); + pn_connection_close(pn_event_connection(event)); + break; + } + + case PN_PROACTOR_INACTIVE: { + return false; + } + + default: + break; + } + return true; +} /* }}} bool handle */ + +static void *event_thread(void __attribute__((unused)) * arg) /* {{{ */ +{ + char addr[PN_MAX_ADDR]; + cd_message_t *cdm; + + /* setup proactor */ + proactor = pn_proactor(); + pn_proactor_addr(addr, sizeof(addr), transport->host, transport->port); + + while (!stopping) { + /* make connection */ + conn = pn_connection(); + if (transport->user != NULL) { + pn_connection_set_user(conn, transport->user); + pn_connection_set_password(conn, transport->password); + } + pn_proactor_connect(proactor, conn, addr); + + bool engine_running = true; + while (engine_running && !stopping) { + pn_event_batch_t *events = pn_proactor_wait(proactor); + pn_event_t *e; + while ((e = pn_event_batch_next(events))) { + engine_running = handle(e); + if (!engine_running) { + break; + } + } + pn_proactor_done(proactor, events); + } + + pn_proactor_release_connection(conn); + + DEBUG("amqp1 plugin: retrying connection"); + int delay = transport->retry_delay; + while (delay-- > 0 && !stopping) { + sleep(1.0); + } + } + + pn_proactor_disconnect(proactor, NULL); + + /* Free the remaining out_messages */ + cdm = DEQ_HEAD(out_messages); + while (cdm) { + DEQ_REMOVE_HEAD(out_messages); + cd_message_free(cdm); + cdm = DEQ_HEAD(out_messages); + } + + event_thread_running = false; + + return NULL; +} /* }}} void event_thread */ + +static int encqueue(cd_message_t *cdm, + amqp1_config_instance_t *instance) /* {{{ */ +{ + /* encode message */ + pn_message_t *message = pn_message(); + pn_message_set_address(message, instance->send_to); + pn_data_t *body = pn_message_body(message); + pn_data_clear(body); + pn_data_put_binary(body, pn_bytes(cdm->mbuf.size, cdm->mbuf.start)); + pn_data_exit(body); + + /* put_binary copies and stores so ok to use mbuf */ + cdm->mbuf.size = BUFSIZE; + + int status; + char *start; + while ((status = pn_message_encode(message, cdm->mbuf.start, + &cdm->mbuf.size)) == PN_OVERFLOW) { + DEBUG("amqp1 plugin: increasing message buffer size %zu", cdm->mbuf.size); + cdm->mbuf.size *= 2; + start = realloc(cdm->mbuf.start, cdm->mbuf.size); + if (start == NULL) { + status = -1; + break; + } else { + cdm->mbuf.start = start; + } + } + + if (status != 0) { + ERROR("amqp1 plugin: error encoding message: %s", + pn_error_text(pn_message_error(message))); + pn_message_free(message); + return -1; + } + + pthread_mutex_lock(&send_lock); + if (transport->sendq_limit > 0 && + DEQ_SIZE(out_messages) >= transport->sendq_limit) { + cd_message_t *evict; + + DEBUG("amqp1 plugin: dropping oldest message because sendq is full"); + evict = DEQ_HEAD(out_messages); + DEQ_REMOVE_HEAD(out_messages); + cd_message_free(evict); + } + DEQ_INSERT_TAIL(out_messages, cdm); + pthread_mutex_unlock(&send_lock); + + pn_message_free(message); + + /* activate the sender */ + if (conn) { + pn_connection_wake(conn); + } + + return 0; +} /* }}} int encqueue */ + +static int amqp1_notify(notification_t const *n, + user_data_t *user_data) /* {{{ */ +{ + int status = 0; + size_t bfree = BUFSIZE; + size_t bfill = 0; + size_t bufsize = BUFSIZE; + + if (n == NULL || user_data == NULL) + return EINVAL; + + amqp1_config_instance_t *instance = user_data->data; + + if (instance->notify != true) { + ERROR("amqp1 plugin: write notification failed"); + } + + cd_message_t *cdm = malloc(sizeof(*cdm)); + if (cdm == NULL) { + ERROR("amqp1 plugin: notify failed"); + return -1; + } + + DEQ_ITEM_INIT(cdm); + char *start = malloc(bufsize); + if (start == NULL) { + ERROR("amqp1 plugin: malloc failed"); + free(cdm); + return -1; + } + cdm->mbuf.size = bufsize; + cdm->mbuf.start = start; + cdm->instance = instance; + + switch (instance->format) { + case AMQP1_FORMAT_JSON: + format_json_initialize(cdm->mbuf.start, &bfill, &bfree); + status = format_json_notification(cdm->mbuf.start, bufsize, n); + if (status != 0) { + ERROR("amqp1 plugin: formatting notification failed"); + cd_message_free(cdm); + return status; + } + cdm->mbuf.size = strlen(cdm->mbuf.start); + if (cdm->mbuf.size >= BUFSIZE) { + ERROR("amqp1 plugin: notify format json failed"); + cd_message_free(cdm); + return -1; + } + break; + default: + ERROR("amqp1 plugin: Invalid notify format (%i).", instance->format); + cd_message_free(cdm); + return -1; + } + + /* encode message and place on outbound queue */ + status = encqueue(cdm, instance); + if (status != 0) { + ERROR("amqp1 plugin: notify enqueue failed"); + cd_message_free(cdm); + } + return status; + +} /* }}} int amqp1_notify */ + +static int amqp1_write(const data_set_t *ds, const value_list_t *vl, /* {{{ */ + user_data_t *user_data) { + int status = 0; + size_t bfree = BUFSIZE; + size_t bfill = 0; + size_t bufsize = BUFSIZE; + + if (ds == NULL || vl == NULL || transport == NULL || user_data == NULL) + return EINVAL; + + amqp1_config_instance_t *instance = user_data->data; + + if (instance->notify != false) { + ERROR("amqp1 plugin: write failed"); + } + + cd_message_t *cdm = malloc(sizeof(*cdm)); + if (cdm == NULL) { + ERROR("amqp1 plugin: malloc failed."); + return -1; + } + DEQ_ITEM_INIT(cdm); + char *start = malloc(bufsize); + if (start == NULL) { + ERROR("amqp1 plugin: malloc failed."); + free(cdm); + return -1; + } + cdm->mbuf.size = bufsize; + cdm->mbuf.start = start; + cdm->instance = instance; + + switch (instance->format) { + case AMQP1_FORMAT_COMMAND: + status = cmd_create_putval((char *)cdm->mbuf.start, bufsize, ds, vl); + if (status != 0) { + ERROR("amqp1 plugin: cmd_create_putval failed with status %i.", status); + cd_message_free(cdm); + return status; + } + cdm->mbuf.size = strlen(cdm->mbuf.start); + if (cdm->mbuf.size >= BUFSIZE) { + ERROR("amqp1 plugin: format cmd failed"); + cd_message_free(cdm); + return -1; + } + break; + case AMQP1_FORMAT_JSON: + format_json_initialize((char *)cdm->mbuf.start, &bfill, &bfree); + format_json_value_list((char *)cdm->mbuf.start, &bfill, &bfree, ds, vl, + instance->store_rates); + status = format_json_finalize((char *)cdm->mbuf.start, &bfill, &bfree); + if (status != 0) { + ERROR("amqp1 plugin: format_json_finalize failed with status %i.", + status); + cd_message_free(cdm); + return status; + } + cdm->mbuf.size = strlen(cdm->mbuf.start); + if (cdm->mbuf.size >= BUFSIZE) { + ERROR("amqp1 plugin: format json failed"); + cd_message_free(cdm); + return -1; + } + break; + case AMQP1_FORMAT_GRAPHITE: + status = format_graphite((char *)cdm->mbuf.start, bufsize, ds, vl, + instance->prefix, instance->postfix, + instance->escape_char, instance->graphite_flags); + if (status != 0) { + ERROR("amqp1 plugin: format_graphite failed with status %i.", status); + cd_message_free(cdm); + return status; + } + cdm->mbuf.size = strlen(cdm->mbuf.start); + if (cdm->mbuf.size >= BUFSIZE) { + ERROR("amqp1 plugin: format graphite failed"); + cd_message_free(cdm); + return -1; + } + break; + default: + ERROR("amqp1 plugin: Invalid write format (%i).", instance->format); + cd_message_free(cdm); + return -1; + } + + /* encode message and place on outbound queue */ + status = encqueue(cdm, instance); + if (status != 0) { + ERROR("amqp1 plugin: write enqueue failed"); + cd_message_free(cdm); + } + return status; + +} /* }}} int amqp1_write */ + +static void amqp1_config_transport_free(void *ptr) /* {{{ */ +{ + amqp1_config_transport_t *transport = ptr; + + if (transport == NULL) + return; + + sfree(transport->name); + sfree(transport->host); + sfree(transport->port); + sfree(transport->user); + sfree(transport->password); + sfree(transport->address); + + sfree(transport); +} /* }}} void amqp1_config_transport_free */ + +static void amqp1_config_instance_free(void *ptr) /* {{{ */ +{ + amqp1_config_instance_t *instance = ptr; + + if (instance == NULL) + return; + + sfree(instance->name); + sfree(instance->prefix); + sfree(instance->postfix); + + sfree(instance); +} /* }}} void amqp1_config_instance_free */ + +static int amqp1_config_instance(oconfig_item_t *ci) /* {{{ */ +{ + amqp1_config_instance_t *instance = calloc(1, sizeof(*instance)); + if (instance == NULL) { + ERROR("amqp1 plugin: calloc failed."); + return ENOMEM; + } + + int status = cf_util_get_string(ci, &instance->name); + if (status != 0) { + sfree(instance); + return status; + } + + for (int i = 0; i < ci->children_num; i++) { + oconfig_item_t *child = ci->children + i; + + if (strcasecmp("PreSettle", child->key) == 0) + status = cf_util_get_boolean(child, &instance->pre_settle); + else if (strcasecmp("Notify", child->key) == 0) + status = cf_util_get_boolean(child, &instance->notify); + else if (strcasecmp("Format", child->key) == 0) { + char *key = NULL; + status = cf_util_get_string(child, &key); + if (status != 0) { + amqp1_config_instance_free(instance); + return status; + } + assert(key != NULL); + if (strcasecmp(key, "Command") == 0) { + instance->format = AMQP1_FORMAT_COMMAND; + } else if (strcasecmp(key, "Graphite") == 0) { + instance->format = AMQP1_FORMAT_GRAPHITE; + } else if (strcasecmp(key, "JSON") == 0) { + instance->format = AMQP1_FORMAT_JSON; + } else { + WARNING("amqp1 plugin: Invalid format string: %s", key); + } + sfree(key); + } else if (strcasecmp("StoreRates", child->key) == 0) + status = cf_util_get_boolean(child, &instance->store_rates); + else if (strcasecmp("GraphiteSeparateInstances", child->key) == 0) + status = cf_util_get_flag(child, &instance->graphite_flags, + GRAPHITE_SEPARATE_INSTANCES); + else if (strcasecmp("GraphiteAlwaysAppendDS", child->key) == 0) + status = cf_util_get_flag(child, &instance->graphite_flags, + GRAPHITE_ALWAYS_APPEND_DS); + else if (strcasecmp("GraphitePreserveSeparator", child->key) == 0) + status = cf_util_get_flag(child, &instance->graphite_flags, + GRAPHITE_PRESERVE_SEPARATOR); + else if (strcasecmp("GraphitePrefix", child->key) == 0) + status = cf_util_get_string(child, &instance->prefix); + else if (strcasecmp("GraphitePostfix", child->key) == 0) + status = cf_util_get_string(child, &instance->postfix); + else if (strcasecmp("GraphiteEscapeChar", child->key) == 0) { + char *tmp_buff = NULL; + status = cf_util_get_string(child, &tmp_buff); + if (status == 0) { + if (strlen(tmp_buff) > 1) + WARNING("amqp1 plugin: The option \"GraphiteEscapeChar\" handles " + "only one character. Others will be ignored."); + instance->escape_char = tmp_buff[0]; + } + sfree(tmp_buff); + } else + WARNING("amqp1 plugin: Ignoring unknown " + "instance configuration option " + "\"%s\".", + child->key); + if (status != 0) + break; + } + + if (status != 0) { + amqp1_config_instance_free(instance); + return status; + } else { + char tpname[DATA_MAX_NAME_LEN]; + 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 = 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, + }); + } else { + status = + plugin_register_write(tpname, amqp1_write, + &(user_data_t){ + .data = instance, + .free_func = amqp1_config_instance_free, + }); + } + + if (status != 0) { + amqp1_config_instance_free(instance); + } + } + + return status; +} /* }}} int amqp1_config_instance */ + +static int amqp1_config_transport(oconfig_item_t *ci) /* {{{ */ +{ + transport = calloc(1, sizeof(*transport)); + if (transport == NULL) { + ERROR("amqp1 plugin: calloc failed."); + return ENOMEM; + } + + /* Initialize transport configuration {{{ */ + transport->retry_delay = 1; + + int status = cf_util_get_string(ci, &transport->name); + if (status != 0) { + sfree(transport); + return status; + } + + for (int i = 0; i < ci->children_num; i++) { + oconfig_item_t *child = ci->children + i; + + if (strcasecmp("Host", child->key) == 0) + status = cf_util_get_string(child, &transport->host); + else if (strcasecmp("Port", child->key) == 0) + status = cf_util_get_string(child, &transport->port); + else if (strcasecmp("User", child->key) == 0) + status = cf_util_get_string(child, &transport->user); + else if (strcasecmp("Password", child->key) == 0) + status = cf_util_get_string(child, &transport->password); + else if (strcasecmp("Address", child->key) == 0) + status = cf_util_get_string(child, &transport->address); + else if (strcasecmp("RetryDelay", child->key) == 0) + status = cf_util_get_int(child, &transport->retry_delay); + else if (strcasecmp("Instance", child->key) == 0) + amqp1_config_instance(child); + else if (strcasecmp("SendQueueLimit", child->key) == 0) + status = cf_util_get_int(child, &transport->sendq_limit); + else + WARNING("amqp1 plugin: Ignoring unknown " + "transport configuration option " + "\"%s\".", + child->key); + + if (status != 0) + break; + } + + if (status != 0) { + amqp1_config_transport_free(transport); + } + return status; +} /* }}} int amqp1_config_transport */ + +static int amqp1_config(oconfig_item_t *ci) /* {{{ */ +{ + + for (int i = 0; i < ci->children_num; i++) { + oconfig_item_t *child = ci->children + i; + + if (strcasecmp("Transport", child->key) == 0) + amqp1_config_transport(child); + else + WARNING("amqp1 plugin: Ignoring unknown config option \"%s\".", + child->key); + } + + return 0; +} /* }}} int amqp1_config */ + +static int amqp1_init(void) /* {{{ */ +{ + if (transport == NULL) { + ERROR("amqp1: init failed, no transport configured"); + return -1; + } + + if (proactor == NULL) { + pthread_mutex_init(&send_lock, /* attr = */ NULL); + /* start_thread */ + int status = plugin_thread_create(&event_thread_id, event_thread, + NULL /* no argument */, "handle"); + if (status != 0) { + ERROR("amqp1 plugin: pthread_create failed: %s", STRERRNO); + } else { + event_thread_running = true; + } + } + return 0; +} /* }}} int amqp1_init */ + +static int amqp1_shutdown(void) /* {{{ */ +{ + stopping = true; + + /* Stop the proactor thread */ + if (event_thread_running) { + DEBUG("amqp1 plugin: Shutting down proactor thread."); + pn_connection_wake(conn); + } + pthread_join(event_thread_id, NULL /* no return value */); + memset(&event_thread_id, 0, sizeof(event_thread_id)); + + DEBUG("amqp1 plugin: proactor thread exited."); + + if (transport) { + amqp1_config_transport_free(transport); + } + + return 0; +} /* }}} int amqp1_shutdown */ + +void module_register(void) { + plugin_register_complex_config("amqp1", amqp1_config); + plugin_register_init("amqp1", amqp1_init); + plugin_register_shutdown("amqp1", amqp1_shutdown); +} /* void module_register */ diff --git a/src/apache.c b/src/apache.c index 8458ce15d1..42c85ef1f1 100644 --- a/src/apache.c +++ b/src/apache.c @@ -18,143 +18,129 @@ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * * Authors: - * Florian octo Forster + * Florian octo Forster * Florent EppO Monbillard * - connections/lighttpd extension * Amit Gupta **/ #include "collectd.h" -#include "common.h" + #include "plugin.h" -#include "configfile.h" +#include "utils/common/common.h" #include -enum server_enum -{ - APACHE = 0, - LIGHTTPD -}; - -struct apache_s -{ - int server_type; - char *name; - char *host; - char *url; - char *user; - char *pass; - int verify_peer; - int verify_host; - char *cacert; - char *server; /* user specific server type */ - char *apache_buffer; - char apache_curl_error[CURL_ERROR_SIZE]; - size_t apache_buffer_size; - size_t apache_buffer_fill; - CURL *curl; +enum server_enum { APACHE = 0, LIGHTTPD }; + +struct apache_s { + int server_type; + char *name; + char *host; + char *url; + char *user; + char *pass; + bool verify_peer; + bool verify_host; + char *cacert; + char *ssl_ciphers; + char *server; /* user specific server type */ + char *apache_buffer; + char apache_curl_error[CURL_ERROR_SIZE]; + size_t apache_buffer_size; + size_t apache_buffer_fill; + int timeout; + CURL *curl; }; /* apache_s */ typedef struct apache_s apache_t; /* TODO: Remove this prototype */ -static int apache_read_host (user_data_t *user_data); - -static void apache_free (apache_t *st) -{ - if (st == NULL) - return; - - sfree (st->name); - sfree (st->host); - sfree (st->url); - sfree (st->user); - sfree (st->pass); - sfree (st->cacert); - sfree (st->server); - sfree (st->apache_buffer); - if (st->curl) { - curl_easy_cleanup(st->curl); - st->curl = NULL; - } +static int apache_read_host(user_data_t *user_data); + +static void apache_free(void *arg) { + apache_t *st = arg; + + if (st == NULL) + return; + + sfree(st->name); + sfree(st->host); + sfree(st->url); + sfree(st->user); + sfree(st->pass); + sfree(st->cacert); + sfree(st->ssl_ciphers); + sfree(st->server); + sfree(st->apache_buffer); + if (st->curl) { + curl_easy_cleanup(st->curl); + st->curl = NULL; + } + sfree(st); } /* apache_free */ -static size_t apache_curl_callback (void *buf, size_t size, size_t nmemb, - void *user_data) -{ - size_t len = size * nmemb; - apache_t *st; - - st = user_data; - if (st == NULL) - { - ERROR ("apache plugin: apache_curl_callback: " - "user_data pointer is NULL."); - return (0); - } - - if (len <= 0) - return (len); - - if ((st->apache_buffer_fill + len) >= st->apache_buffer_size) - { - char *temp; - - temp = (char *) realloc (st->apache_buffer, - st->apache_buffer_fill + len + 1); - if (temp == NULL) - { - ERROR ("apache plugin: realloc failed."); - return (0); - } - st->apache_buffer = temp; - st->apache_buffer_size = st->apache_buffer_fill + len + 1; - } - - memcpy (st->apache_buffer + st->apache_buffer_fill, (char *) buf, len); - st->apache_buffer_fill += len; - st->apache_buffer[st->apache_buffer_fill] = 0; - - return (len); +static size_t apache_curl_callback(void *buf, size_t size, size_t nmemb, + void *user_data) { + apache_t *st = user_data; + if (st == NULL) { + ERROR("apache plugin: apache_curl_callback: " + "user_data pointer is NULL."); + return 0; + } + + size_t len = size * nmemb; + if (len == 0) + return len; + + if ((st->apache_buffer_fill + len) >= st->apache_buffer_size) { + char *temp = realloc(st->apache_buffer, st->apache_buffer_fill + len + 1); + if (temp == NULL) { + ERROR("apache plugin: realloc failed."); + return 0; + } + st->apache_buffer = temp; + st->apache_buffer_size = st->apache_buffer_fill + len + 1; + } + + memcpy(st->apache_buffer + st->apache_buffer_fill, (char *)buf, len); + st->apache_buffer_fill += len; + st->apache_buffer[st->apache_buffer_fill] = 0; + + return len; } /* int apache_curl_callback */ -static size_t apache_header_callback (void *buf, size_t size, size_t nmemb, - void *user_data) -{ - size_t len = size * nmemb; - apache_t *st; - - st = user_data; - if (st == NULL) - { - ERROR ("apache plugin: apache_header_callback: " - "user_data pointer is NULL."); - return (0); - } - - if (len <= 0) - return (len); - - /* look for the Server header */ - if (strncasecmp (buf, "Server: ", strlen ("Server: ")) != 0) - return (len); - - if (strstr (buf, "Apache") != NULL) - st->server_type = APACHE; - else if (strstr (buf, "lighttpd") != NULL) - st->server_type = LIGHTTPD; - else if (strstr (buf, "IBM_HTTP_Server") != NULL) - st->server_type = APACHE; - else - { - const char *hdr = buf; - - hdr += strlen ("Server: "); - NOTICE ("apache plugin: Unknown server software: %s", hdr); - } - - return (len); +static size_t apache_header_callback(void *buf, size_t size, size_t nmemb, + void *user_data) { + apache_t *st = user_data; + if (st == NULL) { + ERROR("apache plugin: apache_header_callback: " + "user_data pointer is NULL."); + return 0; + } + + size_t len = size * nmemb; + if (len == 0) + return len; + + /* look for the Server header */ + if (strncasecmp(buf, "Server: ", strlen("Server: ")) != 0) + return len; + + if (strstr(buf, "Apache") != NULL) + st->server_type = APACHE; + else if (strstr(buf, "lighttpd") != NULL) + st->server_type = LIGHTTPD; + else if (strstr(buf, "IBM_HTTP_Server") != NULL) + st->server_type = APACHE; + else { + const char *hdr = buf; + + hdr += strlen("Server: "); + NOTICE("apache plugin: Unknown server software: %s", hdr); + } + + return len; } /* apache_header_callback */ /* Configuration handling functiions @@ -165,515 +151,415 @@ static size_t apache_header_callback (void *buf, size_t size, size_t nmemb, * URL ... * */ -static int config_set_string (char **ret_string, /* {{{ */ - oconfig_item_t *ci) -{ - char *string; - - if ((ci->values_num != 1) - || (ci->values[0].type != OCONFIG_TYPE_STRING)) - { - WARNING ("apache plugin: The `%s' config option " - "needs exactly one string argument.", ci->key); - return (-1); - } - - string = strdup (ci->values[0].value.string); - if (string == NULL) - { - ERROR ("apache plugin: strdup failed."); - return (-1); - } - - if (*ret_string != NULL) - free (*ret_string); - *ret_string = string; - - return (0); -} /* }}} int config_set_string */ - -static int config_set_boolean (int *ret_boolean, /* {{{ */ - oconfig_item_t *ci) -{ - if ((ci->values_num != 1) - || ((ci->values[0].type != OCONFIG_TYPE_BOOLEAN) - && (ci->values[0].type != OCONFIG_TYPE_STRING))) - { - WARNING ("apache plugin: The `%s' config option " - "needs exactly one boolean argument.", ci->key); - return (-1); - } - - if (ci->values[0].type == OCONFIG_TYPE_BOOLEAN) - { - if (ci->values[0].value.boolean) - *ret_boolean = 1; - else - *ret_boolean = 0; - } - else /* if (ci->values[0].type != OCONFIG_TYPE_STRING) */ - { - char *string = ci->values[0].value.string; - if (IS_TRUE (string)) - *ret_boolean = 1; - else if (IS_FALSE (string)) - *ret_boolean = 0; - else - { - ERROR ("apache plugin: Cannot parse string " - "as boolean value: %s", string); - return (-1); - } - } - - return (0); -} /* }}} int config_set_boolean */ - -static int config_add (oconfig_item_t *ci) -{ - apache_t *st; - int i; - int status; - - if ((ci->values_num != 1) - || (ci->values[0].type != OCONFIG_TYPE_STRING)) - { - WARNING ("apache plugin: The `%s' config option " - "needs exactly one string argument.", ci->key); - return (-1); - } - - st = (apache_t *) malloc (sizeof (*st)); - if (st == NULL) - { - ERROR ("apache plugin: malloc failed."); - return (-1); - } - - memset (st, 0, sizeof (*st)); - - status = config_set_string (&st->name, ci); - if (status != 0) - { - sfree (st); - return (status); - } - assert (st->name != NULL); - - for (i = 0; i < ci->children_num; i++) - { - oconfig_item_t *child = ci->children + i; - - if (strcasecmp ("URL", child->key) == 0) - status = config_set_string (&st->url, child); - else if (strcasecmp ("Host", child->key) == 0) - status = config_set_string (&st->host, child); - else if (strcasecmp ("User", child->key) == 0) - status = config_set_string (&st->user, child); - else if (strcasecmp ("Password", child->key) == 0) - status = config_set_string (&st->pass, child); - else if (strcasecmp ("VerifyPeer", child->key) == 0) - status = config_set_boolean (&st->verify_peer, child); - else if (strcasecmp ("VerifyHost", child->key) == 0) - status = config_set_boolean (&st->verify_host, child); - else if (strcasecmp ("CACert", child->key) == 0) - status = config_set_string (&st->cacert, child); - else if (strcasecmp ("Server", child->key) == 0) - status = config_set_string (&st->server, child); - else - { - WARNING ("apache plugin: Option `%s' not allowed here.", - child->key); - status = -1; - } - - if (status != 0) - break; - } - - /* Check if struct is complete.. */ - if ((status == 0) && (st->url == NULL)) - { - ERROR ("apache plugin: Instance `%s': " - "No URL has been configured.", - st->name); - status = -1; - } - - if (status == 0) - { - user_data_t ud; - char callback_name[3*DATA_MAX_NAME_LEN]; - - memset (&ud, 0, sizeof (ud)); - ud.data = st; - ud.free_func = (void *) apache_free; - - memset (callback_name, 0, sizeof (callback_name)); - ssnprintf (callback_name, sizeof (callback_name), - "apache/%s/%s", - (st->host != NULL) ? st->host : hostname_g, - (st->name != NULL) ? st->name : "default"), - - status = plugin_register_complex_read (/* group = */ NULL, - /* name = */ callback_name, - /* callback = */ apache_read_host, - /* interval = */ NULL, - /* user_data = */ &ud); - } - - if (status != 0) - { - apache_free(st); - return (-1); - } - - return (0); +static int config_add(oconfig_item_t *ci) { + apache_t *st = calloc(1, sizeof(*st)); + if (st == NULL) { + ERROR("apache plugin: calloc failed."); + return -1; + } + + st->timeout = -1; + + int status = cf_util_get_string(ci, &st->name); + if (status != 0) { + sfree(st); + return status; + } + assert(st->name != NULL); + + for (int i = 0; i < ci->children_num; i++) { + oconfig_item_t *child = ci->children + i; + + if (strcasecmp("URL", child->key) == 0) + status = cf_util_get_string(child, &st->url); + else if (strcasecmp("Host", child->key) == 0) + status = cf_util_get_string(child, &st->host); + else if (strcasecmp("User", child->key) == 0) + status = cf_util_get_string(child, &st->user); + else if (strcasecmp("Password", child->key) == 0) + status = cf_util_get_string(child, &st->pass); + else if (strcasecmp("VerifyPeer", child->key) == 0) + status = cf_util_get_boolean(child, &st->verify_peer); + else if (strcasecmp("VerifyHost", child->key) == 0) + status = cf_util_get_boolean(child, &st->verify_host); + else if (strcasecmp("CACert", child->key) == 0) + status = cf_util_get_string(child, &st->cacert); + else if (strcasecmp("SSLCiphers", child->key) == 0) + status = cf_util_get_string(child, &st->ssl_ciphers); + else if (strcasecmp("Server", child->key) == 0) + status = cf_util_get_string(child, &st->server); + else if (strcasecmp("Timeout", child->key) == 0) + status = cf_util_get_int(child, &st->timeout); + else { + WARNING("apache plugin: Option `%s' not allowed here.", child->key); + status = -1; + } + + if (status != 0) + break; + } + + /* Check if struct is complete.. */ + if ((status == 0) && (st->url == NULL)) { + ERROR("apache plugin: Instance `%s': " + "No URL has been configured.", + st->name); + status = -1; + } + + if (status != 0) { + apache_free(st); + return -1; + } + + char callback_name[3 * DATA_MAX_NAME_LEN]; + + snprintf(callback_name, sizeof(callback_name), "apache/%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 = */ apache_read_host, + /* interval = */ 0, + &(user_data_t){ + .data = st, + .free_func = apache_free, + }); } /* int config_add */ -static int config (oconfig_item_t *ci) -{ - int status = 0; - int i; - - for (i = 0; i < ci->children_num; i++) - { - oconfig_item_t *child = ci->children + i; - - if (strcasecmp ("Instance", child->key) == 0) - config_add (child); - else - WARNING ("apache plugin: The configuration option " - "\"%s\" is not allowed here. Did you " - "forget to add an block " - "around the configuration?", - child->key); - } /* for (ci->children) */ - - return (status); +static int config(oconfig_item_t *ci) { + for (int i = 0; i < ci->children_num; i++) { + oconfig_item_t *child = ci->children + i; + + if (strcasecmp("Instance", child->key) == 0) + config_add(child); + else + WARNING("apache plugin: The configuration option " + "\"%s\" is not allowed here. Did you " + "forget to add an block " + "around the configuration?", + child->key); + } /* for (ci->children) */ + + return 0; } /* int config */ /* initialize curl for each host */ -static int init_host (apache_t *st) /* {{{ */ +static int init_host(apache_t *st) /* {{{ */ { - static char credentials[1024]; - - assert (st->url != NULL); - /* (Assured by `config_add') */ - - if (st->curl != NULL) - { - curl_easy_cleanup (st->curl); - st->curl = NULL; - } - - if ((st->curl = curl_easy_init ()) == NULL) - { - ERROR ("apache plugin: init_host: `curl_easy_init' failed."); - return (-1); - } - - curl_easy_setopt (st->curl, CURLOPT_NOSIGNAL, 1L); - curl_easy_setopt (st->curl, CURLOPT_WRITEFUNCTION, apache_curl_callback); - curl_easy_setopt (st->curl, CURLOPT_WRITEDATA, st); - - /* not set as yet if the user specified string doesn't match apache or - * lighttpd, then ignore it. Headers will be parsed to find out the - * server type */ - st->server_type = -1; - - if (st->server != NULL) - { - if (strcasecmp(st->server, "apache") == 0) - st->server_type = APACHE; - else if (strcasecmp(st->server, "lighttpd") == 0) - st->server_type = LIGHTTPD; - else if (strcasecmp(st->server, "ibm_http_server") == 0) - st->server_type = APACHE; - else - WARNING ("apache plugin: Unknown `Server' setting: %s", - st->server); - } - - /* if not found register a header callback to determine the server_type */ - if (st->server_type == -1) - { - curl_easy_setopt (st->curl, CURLOPT_HEADERFUNCTION, apache_header_callback); - curl_easy_setopt (st->curl, CURLOPT_WRITEHEADER, st); - } - - curl_easy_setopt (st->curl, CURLOPT_USERAGENT, PACKAGE_NAME"/"PACKAGE_VERSION); - curl_easy_setopt (st->curl, CURLOPT_ERRORBUFFER, st->apache_curl_error); - - if (st->user != NULL) - { - int status; - - status = ssnprintf (credentials, sizeof (credentials), "%s:%s", - st->user, (st->pass == NULL) ? "" : st->pass); - if ((status < 0) || ((size_t) status >= sizeof (credentials))) - { - ERROR ("apache plugin: init_host: Returning an error " - "because the credentials have been " - "truncated."); - curl_easy_cleanup (st->curl); - st->curl = NULL; - return (-1); - } - - curl_easy_setopt (st->curl, CURLOPT_USERPWD, credentials); - } - - curl_easy_setopt (st->curl, CURLOPT_URL, st->url); - curl_easy_setopt (st->curl, CURLOPT_FOLLOWLOCATION, 1L); - curl_easy_setopt (st->curl, CURLOPT_MAXREDIRS, 50L); - - if (st->verify_peer != 0) - { - curl_easy_setopt (st->curl, CURLOPT_SSL_VERIFYPEER, 1L); - } - else - { - curl_easy_setopt (st->curl, CURLOPT_SSL_VERIFYPEER, 0L); - } - - if (st->verify_host != 0) - { - curl_easy_setopt (st->curl, CURLOPT_SSL_VERIFYHOST, 2L); - } - else - { - curl_easy_setopt (st->curl, CURLOPT_SSL_VERIFYHOST, 0L); - } - - if (st->cacert != NULL) - { - curl_easy_setopt (st->curl, CURLOPT_CAINFO, st->cacert); - } - - return (0); + assert(st->url != NULL); + /* (Assured by `config_add') */ + + if (st->curl != NULL) { + curl_easy_cleanup(st->curl); + st->curl = NULL; + } + + if ((st->curl = curl_easy_init()) == NULL) { + ERROR("apache plugin: init_host: `curl_easy_init' failed."); + return -1; + } + + curl_easy_setopt(st->curl, CURLOPT_NOSIGNAL, 1L); + curl_easy_setopt(st->curl, CURLOPT_WRITEFUNCTION, apache_curl_callback); + curl_easy_setopt(st->curl, CURLOPT_WRITEDATA, st); + + /* not set as yet if the user specified string doesn't match apache or + * lighttpd, then ignore it. Headers will be parsed to find out the + * server type */ + st->server_type = -1; + + if (st->server != NULL) { + if (strcasecmp(st->server, "apache") == 0) + st->server_type = APACHE; + else if (strcasecmp(st->server, "lighttpd") == 0) + st->server_type = LIGHTTPD; + else if (strcasecmp(st->server, "ibm_http_server") == 0) + st->server_type = APACHE; + else + WARNING("apache plugin: Unknown `Server' setting: %s", st->server); + } + + /* if not found register a header callback to determine the server_type */ + if (st->server_type == -1) { + curl_easy_setopt(st->curl, CURLOPT_HEADERFUNCTION, apache_header_callback); + curl_easy_setopt(st->curl, CURLOPT_WRITEHEADER, st); + } + + curl_easy_setopt(st->curl, CURLOPT_USERAGENT, COLLECTD_USERAGENT); + curl_easy_setopt(st->curl, CURLOPT_ERRORBUFFER, st->apache_curl_error); + + if (st->user != NULL) { +#ifdef HAVE_CURLOPT_USERNAME + curl_easy_setopt(st->curl, CURLOPT_USERNAME, st->user); + curl_easy_setopt(st->curl, CURLOPT_PASSWORD, + (st->pass == NULL) ? "" : st->pass); +#else + static char credentials[1024]; + int status = snprintf(credentials, sizeof(credentials), "%s:%s", st->user, + (st->pass == NULL) ? "" : st->pass); + if ((status < 0) || ((size_t)status >= sizeof(credentials))) { + ERROR("apache plugin: init_host: Returning an error " + "because the credentials have been " + "truncated."); + curl_easy_cleanup(st->curl); + st->curl = NULL; + return -1; + } + + curl_easy_setopt(st->curl, CURLOPT_USERPWD, credentials); +#endif + } + + curl_easy_setopt(st->curl, CURLOPT_FOLLOWLOCATION, 1L); + curl_easy_setopt(st->curl, CURLOPT_MAXREDIRS, 50L); + + curl_easy_setopt(st->curl, CURLOPT_SSL_VERIFYPEER, (long)st->verify_peer); + curl_easy_setopt(st->curl, CURLOPT_SSL_VERIFYHOST, st->verify_host ? 2L : 0L); + if (st->cacert != NULL) + curl_easy_setopt(st->curl, CURLOPT_CAINFO, st->cacert); + if (st->ssl_ciphers != NULL) + curl_easy_setopt(st->curl, CURLOPT_SSL_CIPHER_LIST, st->ssl_ciphers); + +#ifdef HAVE_CURLOPT_TIMEOUT_MS + if (st->timeout >= 0) + curl_easy_setopt(st->curl, CURLOPT_TIMEOUT_MS, (long)st->timeout); + else + curl_easy_setopt(st->curl, CURLOPT_TIMEOUT_MS, + (long)CDTIME_T_TO_MS(plugin_get_interval())); +#endif + + return 0; } /* }}} int init_host */ -static void submit_value (const char *type, const char *type_instance, - value_t value, apache_t *st) -{ - value_list_t vl = VALUE_LIST_INIT; +static void submit_value(const char *type, const char *type_instance, + value_t value, apache_t *st) { + value_list_t vl = VALUE_LIST_INIT; - vl.values = &value; - vl.values_len = 1; + vl.values = &value; + vl.values_len = 1; - sstrncpy (vl.host, (st->host != NULL) ? st->host : hostname_g, - sizeof (vl.host)); + if (st->host != NULL) + sstrncpy(vl.host, st->host, sizeof(vl.host)); - sstrncpy (vl.plugin, "apache", sizeof (vl.plugin)); - if (st->name != NULL) - sstrncpy (vl.plugin_instance, st->name, - sizeof (vl.plugin_instance)); + sstrncpy(vl.plugin, "apache", sizeof(vl.plugin)); + if (st->name != NULL) + sstrncpy(vl.plugin_instance, st->name, sizeof(vl.plugin_instance)); - sstrncpy (vl.type, type, sizeof (vl.type)); - if (type_instance != NULL) - sstrncpy (vl.type_instance, type_instance, - sizeof (vl.type_instance)); + sstrncpy(vl.type, type, sizeof(vl.type)); + if (type_instance != NULL) + sstrncpy(vl.type_instance, type_instance, sizeof(vl.type_instance)); - plugin_dispatch_values (&vl); + plugin_dispatch_values(&vl); } /* void submit_value */ -static void submit_derive (const char *type, const char *type_instance, - derive_t c, apache_t *st) -{ - value_t v; - v.derive = c; - submit_value (type, type_instance, v, st); +static void submit_derive(const char *type, const char *type_instance, + derive_t d, apache_t *st) { + submit_value(type, type_instance, (value_t){.derive = d}, st); } /* void submit_derive */ -static void submit_gauge (const char *type, const char *type_instance, - gauge_t g, apache_t *st) -{ - value_t v; - v.gauge = g; - submit_value (type, type_instance, v, st); +static void submit_gauge(const char *type, const char *type_instance, gauge_t g, + apache_t *st) { + submit_value(type, type_instance, (value_t){.gauge = g}, st); } /* void submit_gauge */ -static void submit_scoreboard (char *buf, apache_t *st) -{ - /* - * Scoreboard Key: - * "_" Waiting for Connection, "S" Starting up, - * "R" Reading Request for apache and read-POST for lighttpd, - * "W" Sending Reply, "K" Keepalive (read), "D" DNS Lookup, - * "C" Closing connection, "L" Logging, "G" Gracefully finishing, - * "I" Idle cleanup of worker, "." Open slot with no current process - * Lighttpd specific legends - - * "E" hard error, "." connect, "h" handle-request, - * "q" request-start, "Q" request-end, "s" response-start - * "S" response-end, "r" read - */ - long long open = 0LL; - long long waiting = 0LL; - long long starting = 0LL; - long long reading = 0LL; - long long sending = 0LL; - long long keepalive = 0LL; - long long dnslookup = 0LL; - long long closing = 0LL; - long long logging = 0LL; - long long finishing = 0LL; - long long idle_cleanup = 0LL; - - /* lighttpd specific */ - long long hard_error = 0LL; - long long lighttpd_read = 0LL; - long long handle_request = 0LL; - long long request_start = 0LL; - long long request_end = 0LL; - long long response_start = 0LL; - long long response_end = 0LL; - - int i; - for (i = 0; buf[i] != '\0'; i++) - { - if (buf[i] == '.') open++; - else if (buf[i] == '_') waiting++; - else if (buf[i] == 'S') starting++; - else if (buf[i] == 'R') reading++; - else if (buf[i] == 'W') sending++; - else if (buf[i] == 'K') keepalive++; - else if (buf[i] == 'D') dnslookup++; - else if (buf[i] == 'C') closing++; - else if (buf[i] == 'L') logging++; - else if (buf[i] == 'G') finishing++; - else if (buf[i] == 'I') idle_cleanup++; - else if (buf[i] == 'r') lighttpd_read++; - else if (buf[i] == 'h') handle_request++; - else if (buf[i] == 'E') hard_error++; - else if (buf[i] == 'q') request_start++; - else if (buf[i] == 'Q') request_end++; - else if (buf[i] == 's') response_start++; - else if (buf[i] == 'S') response_end++; - } - - if (st->server_type == APACHE) - { - submit_gauge ("apache_scoreboard", "open" , open, st); - submit_gauge ("apache_scoreboard", "waiting" , waiting, st); - submit_gauge ("apache_scoreboard", "starting" , starting, st); - submit_gauge ("apache_scoreboard", "reading" , reading, st); - submit_gauge ("apache_scoreboard", "sending" , sending, st); - submit_gauge ("apache_scoreboard", "keepalive", keepalive, st); - submit_gauge ("apache_scoreboard", "dnslookup", dnslookup, st); - submit_gauge ("apache_scoreboard", "closing" , closing, st); - submit_gauge ("apache_scoreboard", "logging" , logging, st); - submit_gauge ("apache_scoreboard", "finishing", finishing, st); - submit_gauge ("apache_scoreboard", "idle_cleanup", idle_cleanup, st); - } - else - { - submit_gauge ("apache_scoreboard", "connect" , open, st); - submit_gauge ("apache_scoreboard", "close" , closing, st); - submit_gauge ("apache_scoreboard", "hard_error" , hard_error, st); - submit_gauge ("apache_scoreboard", "read" , lighttpd_read, st); - submit_gauge ("apache_scoreboard", "read_post" , reading, st); - submit_gauge ("apache_scoreboard", "write" , sending, st); - submit_gauge ("apache_scoreboard", "handle_request", handle_request, st); - submit_gauge ("apache_scoreboard", "request_start" , request_start, st); - submit_gauge ("apache_scoreboard", "request_end" , request_end, st); - submit_gauge ("apache_scoreboard", "response_start", response_start, st); - submit_gauge ("apache_scoreboard", "response_end" , response_end, st); - } +static void submit_scoreboard(char *buf, apache_t *st) { + /* + * Scoreboard Key: + * "_" Waiting for Connection, "S" Starting up, + * "R" Reading Request for apache and read-POST for lighttpd, + * "W" Sending Reply, "K" Keepalive (read), "D" DNS Lookup, + * "C" Closing connection, "L" Logging, "G" Gracefully finishing, + * "I" Idle cleanup of worker, "." Open slot with no current process + * Lighttpd specific legends - + * "E" hard error, "." connect, "h" handle-request, + * "q" request-start, "Q" request-end, "s" response-start + * "S" response-end, "r" read + */ + long long open = 0LL; + long long waiting = 0LL; + long long starting = 0LL; + long long reading = 0LL; + long long sending = 0LL; + long long keepalive = 0LL; + long long dnslookup = 0LL; + long long closing = 0LL; + long long logging = 0LL; + long long finishing = 0LL; + long long idle_cleanup = 0LL; + + /* lighttpd specific */ + long long hard_error = 0LL; + long long lighttpd_read = 0LL; + long long handle_request = 0LL; + long long request_start = 0LL; + long long request_end = 0LL; + long long response_start = 0LL; + long long response_end = 0LL; + + for (int i = 0; buf[i] != '\0'; i++) { + if (buf[i] == '.') + open++; + else if (buf[i] == '_') + waiting++; + else if (buf[i] == 'S') + starting++; + else if (buf[i] == 'R') + reading++; + else if (buf[i] == 'W') + sending++; + else if (buf[i] == 'K') + keepalive++; + else if (buf[i] == 'D') + dnslookup++; + else if (buf[i] == 'C') + closing++; + else if (buf[i] == 'L') + logging++; + else if (buf[i] == 'G') + finishing++; + else if (buf[i] == 'I') + idle_cleanup++; + else if (buf[i] == 'r') + lighttpd_read++; + else if (buf[i] == 'h') + handle_request++; + else if (buf[i] == 'E') + hard_error++; + else if (buf[i] == 'q') + request_start++; + else if (buf[i] == 'Q') + request_end++; + else if (buf[i] == 's') + response_start++; + else if (buf[i] == 'S') + response_end++; + } + + if (st->server_type == APACHE) { + submit_gauge("apache_scoreboard", "open", open, st); + submit_gauge("apache_scoreboard", "waiting", waiting, st); + submit_gauge("apache_scoreboard", "starting", starting, st); + submit_gauge("apache_scoreboard", "reading", reading, st); + submit_gauge("apache_scoreboard", "sending", sending, st); + submit_gauge("apache_scoreboard", "keepalive", keepalive, st); + submit_gauge("apache_scoreboard", "dnslookup", dnslookup, st); + submit_gauge("apache_scoreboard", "closing", closing, st); + submit_gauge("apache_scoreboard", "logging", logging, st); + submit_gauge("apache_scoreboard", "finishing", finishing, st); + submit_gauge("apache_scoreboard", "idle_cleanup", idle_cleanup, st); + } else { + submit_gauge("apache_scoreboard", "connect", open, st); + submit_gauge("apache_scoreboard", "close", closing, st); + submit_gauge("apache_scoreboard", "hard_error", hard_error, st); + submit_gauge("apache_scoreboard", "read", lighttpd_read, st); + submit_gauge("apache_scoreboard", "read_post", reading, st); + submit_gauge("apache_scoreboard", "write", sending, st); + submit_gauge("apache_scoreboard", "handle_request", handle_request, st); + submit_gauge("apache_scoreboard", "request_start", request_start, st); + submit_gauge("apache_scoreboard", "request_end", request_end, st); + submit_gauge("apache_scoreboard", "response_start", response_start, st); + submit_gauge("apache_scoreboard", "response_end", response_end, st); + } } -static int apache_read_host (user_data_t *user_data) /* {{{ */ +static int apache_read_host(user_data_t *user_data) /* {{{ */ { - int i; - - char *ptr; - char *saveptr; - char *lines[16]; - int lines_num = 0; - - char *fields[4]; - int fields_num; - - apache_t *st; - - st = user_data->data; - - assert (st->url != NULL); - /* (Assured by `config_add') */ - - if (st->curl == NULL) - { - int status; - - status = init_host (st); - if (status != 0) - return (-1); - } - assert (st->curl != NULL); - - st->apache_buffer_fill = 0; - if (curl_easy_perform (st->curl) != CURLE_OK) - { - ERROR ("apache: curl_easy_perform failed: %s", - st->apache_curl_error); - return (-1); - } - - /* fallback - server_type to apache if not set at this time */ - if (st->server_type == -1) - { - WARNING ("apache plugin: Unable to determine server software " - "automatically. Will assume Apache."); - st->server_type = APACHE; - } - - ptr = st->apache_buffer; - saveptr = NULL; - while ((lines[lines_num] = strtok_r (ptr, "\n\r", &saveptr)) != NULL) - { - ptr = NULL; - lines_num++; - - if (lines_num >= 16) - break; - } - - for (i = 0; i < lines_num; i++) - { - fields_num = strsplit (lines[i], fields, 4); - - if (fields_num == 3) - { - if ((strcmp (fields[0], "Total") == 0) - && (strcmp (fields[1], "Accesses:") == 0)) - submit_derive ("apache_requests", "", - atoll (fields[2]), st); - else if ((strcmp (fields[0], "Total") == 0) - && (strcmp (fields[1], "kBytes:") == 0)) - submit_derive ("apache_bytes", "", - 1024LL * atoll (fields[2]), st); - } - else if (fields_num == 2) - { - if (strcmp (fields[0], "Scoreboard:") == 0) - submit_scoreboard (fields[1], st); - else if ((strcmp (fields[0], "BusyServers:") == 0) /* Apache 1.* */ - || (strcmp (fields[0], "BusyWorkers:") == 0) /* Apache 2.* */) - submit_gauge ("apache_connections", NULL, atol (fields[1]), st); - else if ((strcmp (fields[0], "IdleServers:") == 0) /* Apache 1.x */ - || (strcmp (fields[0], "IdleWorkers:") == 0) /* Apache 2.x */) - submit_gauge ("apache_idle_workers", NULL, atol (fields[1]), st); - } - } - - st->apache_buffer_fill = 0; - - return (0); + apache_t *st = user_data->data; + + assert(st->url != NULL); + /* (Assured by `config_add') */ + + if (st->curl == NULL) { + if (init_host(st) != 0) + return -1; + } + assert(st->curl != NULL); + + st->apache_buffer_fill = 0; + + curl_easy_setopt(st->curl, CURLOPT_URL, st->url); + + if (curl_easy_perform(st->curl) != CURLE_OK) { + ERROR("apache: curl_easy_perform failed: %s", st->apache_curl_error); + return -1; + } + + /* fallback - server_type to apache if not set at this time */ + if (st->server_type == -1) { + WARNING("apache plugin: Unable to determine server software " + "automatically. Will assume Apache."); + st->server_type = APACHE; + } + + char *content_type; + static const char *text_plain = "text/plain"; + int status = + curl_easy_getinfo(st->curl, CURLINFO_CONTENT_TYPE, &content_type); + if ((status == CURLE_OK) && (content_type != NULL) && + (strncasecmp(content_type, text_plain, strlen(text_plain)) != 0)) { + WARNING("apache plugin: `Content-Type' response header is not `%s' " + "(received: `%s'). Expecting unparseable data. Please check `URL' " + "parameter (missing `?auto' suffix ?)", + text_plain, content_type); + } + + char *ptr = st->apache_buffer; + char *saveptr = NULL; + char *line; + /* Apache http mod_status added a second set of BusyWorkers, IdleWorkers in + * https://github.com/apache/httpd/commit/6befc18 + * For Apache 2.4.35 and up we need to ensure only one key is used. + * S.a. https://bz.apache.org/bugzilla/show_bug.cgi?id=63300 + */ + int apache_connections_submitted = 0, apache_idle_workers_submitted = 0; + while ((line = strtok_r(ptr, "\n\r", &saveptr)) != NULL) { + ptr = NULL; + char *fields[4]; + + int fields_num = strsplit(line, fields, STATIC_ARRAY_SIZE(fields)); + + if (fields_num == 3) { + if ((strcmp(fields[0], "Total") == 0) && + (strcmp(fields[1], "Accesses:") == 0)) + submit_derive("apache_requests", "", atoll(fields[2]), st); + else if ((strcmp(fields[0], "Total") == 0) && + (strcmp(fields[1], "kBytes:") == 0)) + submit_derive("apache_bytes", "", 1024LL * atoll(fields[2]), st); + } else if (fields_num == 2) { + if (strcmp(fields[0], "Scoreboard:") == 0) + submit_scoreboard(fields[1], st); + else if (!apache_connections_submitted && + ((strcmp(fields[0], "BusyServers:") == 0) /* Apache 1.* */ + || (strcmp(fields[0], "BusyWorkers:") == 0)) /* Apache 2.* */) { + submit_gauge("apache_connections", NULL, atol(fields[1]), st); + apache_connections_submitted++; + } else if (!apache_idle_workers_submitted && + ((strcmp(fields[0], "IdleServers:") == 0) /* Apache 1.x */ + || + (strcmp(fields[0], "IdleWorkers:") == 0)) /* Apache 2.x */) { + submit_gauge("apache_idle_workers", NULL, atol(fields[1]), st); + apache_idle_workers_submitted++; + } + } + } + + st->apache_buffer_fill = 0; + + return 0; } /* }}} int apache_read_host */ -void module_register (void) +static int apache_init(void) /* {{{ */ { - plugin_register_complex_config ("apache", config); + /* Call this while collectd is still single-threaded to avoid + * initialization issues in libgcrypt. */ + curl_global_init(CURL_GLOBAL_SSL); + return 0; +} /* }}} int apache_init */ + +void module_register(void) { + plugin_register_complex_config("apache", config); + plugin_register_init("apache", apache_init); } /* void module_register */ - -/* vim: set sw=8 noet fdm=marker : */ diff --git a/src/apcups.c b/src/apcups.c index ee15b14f66..83a5c87a3b 100644 --- a/src/apcups.c +++ b/src/apcups.c @@ -1,6 +1,6 @@ /* * collectd - src/apcups.c - * Copyright (C) 2006-2012 Florian octo Forster + * Copyright (C) 2006-2015 Florian octo Forster * Copyright (C) 2006 Anthony Gialluca * Copyright (C) 2000-2004 Kern Sibbald * Copyright (C) 1996-1999 Andre M. Hedrick @@ -21,94 +21,86 @@ * * Authors: * Anthony Gialluca - * Florian octo Forster + * Florian octo Forster **/ #include "collectd.h" -#include "common.h" /* rrd_update_file */ -#include "plugin.h" /* plugin_register, plugin_submit */ -#include "configfile.h" /* cf_register */ + +#include "plugin.h" /* plugin_register, plugin_submit */ +#include "utils/common/common.h" /* rrd_update_file */ #if HAVE_SYS_TYPES_H -# include -#endif -#if HAVE_SYS_SOCKET_H -# include +#include #endif #if HAVE_NETDB_H -# include +#include #endif #if HAVE_NETINET_IN_H -# include +#include #endif -#define NISPORT 3551 -#define MAXSTRING 256 -#define MODULE_NAME "apcups" +#ifndef APCUPS_SERVER_TIMEOUT +#define APCUPS_SERVER_TIMEOUT 15.0 +#endif -#define APCUPS_DEFAULT_HOST "localhost" +#ifndef APCUPS_DEFAULT_NODE +#define APCUPS_DEFAULT_NODE "localhost" +#endif + +#ifndef APCUPS_DEFAULT_SERVICE +#define APCUPS_DEFAULT_SERVICE "3551" +#endif /* * Private data types */ -struct apc_detail_s -{ - double linev; - double loadpct; - double bcharge; - double timeleft; - double outputv; - double itemp; - double battv; - double linefreq; -}; +typedef struct { + gauge_t linev; + gauge_t loadpct; + gauge_t bcharge; + gauge_t timeleft; + gauge_t outputv; + gauge_t itemp; + gauge_t battv; + gauge_t linefreq; +} apc_detail_t; /* * Private variables */ /* Default values for contacting daemon */ -static char *conf_host = NULL; -static int conf_port = NISPORT; +static char *conf_node; +static char *conf_service; /* Defaults to false for backwards compatibility. */ -static _Bool conf_report_seconds = 0; +static bool conf_report_seconds; +static bool conf_persistent_conn = true; static int global_sockfd = -1; -static int count_retries = 0; -static int count_iterations = 0; -static _Bool close_socket = 0; - -static const char *config_keys[] = -{ - "Host", - "Port", - "ReportSeconds" -}; -static int config_keys_num = STATIC_ARRAY_SIZE (config_keys); +static int count_retries; +static int count_iterations; -static int net_shutdown (int *fd) -{ - uint16_t packet_size = 0; +static int net_shutdown(int *fd) { + uint16_t packet_size = 0; - if ((fd == NULL) || (*fd < 0)) - return (EINVAL); + if ((fd == NULL) || (*fd < 0)) + return EINVAL; - swrite (*fd, (void *) &packet_size, sizeof (packet_size)); - close (*fd); - *fd = -1; + (void)swrite(*fd, (void *)&packet_size, sizeof(packet_size)); + close(*fd); + *fd = -1; - return (0); + return 0; } /* int net_shutdown */ /* Close the network connection */ -static int apcups_shutdown (void) -{ - if (global_sockfd < 0) - return (0); +static int apcups_shutdown(void) { + if (global_sockfd < 0) + return 0; - net_shutdown (&global_sockfd); - return (0); + net_shutdown(&global_sockfd); + return 0; } /* int apcups_shutdown */ /* @@ -116,70 +108,52 @@ static int apcups_shutdown (void) * Returns -1 on error * Returns socket file descriptor otherwise */ -static int net_open (char *host, int port) -{ - int sd; - int status; - char port_str[8]; - struct addrinfo ai_hints; - struct addrinfo *ai_return; - struct addrinfo *ai_list; - - assert ((port > 0x00000000) && (port <= 0x0000FFFF)); - - /* Convert the port to a string */ - ssnprintf (port_str, sizeof (port_str), "%i", port); - - /* Resolve name */ - memset ((void *) &ai_hints, '\0', sizeof (ai_hints)); - ai_hints.ai_family = AF_INET; /* XXX: Change this to `AF_UNSPEC' if apcupsd can handle IPv6 */ - ai_hints.ai_socktype = SOCK_STREAM; - - status = getaddrinfo (host, port_str, &ai_hints, &ai_return); - if (status != 0) - { - char errbuf[1024]; - INFO ("getaddrinfo failed: %s", - (status == EAI_SYSTEM) - ? sstrerror (errno, errbuf, sizeof (errbuf)) - : gai_strerror (status)); - return (-1); - } - - /* Create socket */ - sd = -1; - for (ai_list = ai_return; ai_list != NULL; ai_list = ai_list->ai_next) - { - sd = socket (ai_list->ai_family, ai_list->ai_socktype, ai_list->ai_protocol); - if (sd >= 0) - break; - } - /* `ai_list' still holds the current description of the socket.. */ - - if (sd < 0) - { - DEBUG ("Unable to open a socket"); - freeaddrinfo (ai_return); - return (-1); - } - - status = connect (sd, ai_list->ai_addr, ai_list->ai_addrlen); - - freeaddrinfo (ai_return); - - if (status != 0) /* `connect(2)' failed */ - { - char errbuf[1024]; - INFO ("connect failed: %s", - sstrerror (errno, errbuf, sizeof (errbuf))); - close (sd); - return (-1); - } - - DEBUG ("Done opening a socket %i", sd); - - return (sd); -} /* int net_open (char *host, char *service, int port) */ +static int net_open(char const *node, char const *service) { + int sd; + int status; + struct addrinfo *ai_return; + struct addrinfo *ai_list; + + /* TODO: Change this to `AF_UNSPEC' if apcupsd can handle IPv6 */ + struct addrinfo ai_hints = {.ai_family = AF_INET, .ai_socktype = SOCK_STREAM}; + + status = getaddrinfo(node, service, &ai_hints, &ai_return); + if (status != 0) { + INFO("apcups plugin: getaddrinfo failed: %s", + (status == EAI_SYSTEM) ? STRERRNO : gai_strerror(status)); + return -1; + } + + /* Create socket */ + sd = -1; + for (ai_list = ai_return; ai_list != NULL; ai_list = ai_list->ai_next) { + sd = socket(ai_list->ai_family, ai_list->ai_socktype, ai_list->ai_protocol); + if (sd >= 0) + break; + } + /* `ai_list' still holds the current description of the socket.. */ + + if (sd < 0) { + DEBUG("apcups plugin: Unable to open a socket"); + freeaddrinfo(ai_return); + return -1; + } + + status = connect(sd, ai_list->ai_addr, ai_list->ai_addrlen); + + freeaddrinfo(ai_return); + + if (status != 0) /* `connect(2)' failed */ + { + INFO("apcups plugin: connect failed: %s", STRERRNO); + close(sd); + return -1; + } + + DEBUG("apcups plugin: Done opening a socket %i", sd); + + return sd; +} /* int net_open */ /* * Receive a message from the other end. Each message consists of @@ -190,41 +164,37 @@ static int net_open (char *host, int port) * Returns -1 on hard end of file (i.e. network connection close) * Returns -2 on error */ -static int net_recv (int *sockfd, char *buf, int buflen) -{ - uint16_t packet_size; - - /* get data size -- in short */ - if (sread (*sockfd, (void *) &packet_size, sizeof (packet_size)) != 0) - { - close (*sockfd); - *sockfd = -1; - return (-1); - } - - packet_size = ntohs (packet_size); - if (packet_size > buflen) - { - ERROR ("apcups plugin: Received %"PRIu16" bytes of payload " - "but have only %i bytes of buffer available.", - packet_size, buflen); - close (*sockfd); - *sockfd = -1; - return (-2); - } - - if (packet_size == 0) - return (0); - - /* now read the actual data */ - if (sread (*sockfd, (void *) buf, packet_size) != 0) - { - close (*sockfd); - *sockfd = -1; - return (-1); - } - - return ((int) packet_size); +static int net_recv(int *sockfd, char *buf, int buflen) { + uint16_t packet_size; + + /* get data size -- in short */ + if (sread(*sockfd, (void *)&packet_size, sizeof(packet_size)) != 0) { + close(*sockfd); + *sockfd = -1; + return -1; + } + + packet_size = ntohs(packet_size); + if (packet_size > buflen) { + ERROR("apcups plugin: Received %" PRIu16 " bytes of payload " + "but have only %i bytes of buffer available.", + packet_size, buflen); + close(*sockfd); + *sockfd = -1; + return -2; + } + + if (packet_size == 0) + return 0; + + /* now read the actual data */ + if (sread(*sockfd, (void *)buf, packet_size) != 0) { + close(*sockfd); + *sockfd = -1; + return -1; + } + + return (int)packet_size; } /* static int net_recv (int *sockfd, char *buf, int buflen) */ /* @@ -234,269 +204,245 @@ static int net_recv (int *sockfd, char *buf, int buflen) * Returns zero on success * Returns non-zero on error */ -static int net_send (int *sockfd, char *buff, int len) -{ - uint16_t packet_size; - - assert (len > 0); - assert (*sockfd >= 0); - - /* send short containing size of data packet */ - packet_size = htons ((uint16_t) len); - - if (swrite (*sockfd, (void *) &packet_size, sizeof (packet_size)) != 0) - { - close (*sockfd); - *sockfd = -1; - return (-1); - } - - /* send data packet */ - if (swrite (*sockfd, (void *) buff, len) != 0) - { - close (*sockfd); - *sockfd = -1; - return (-2); - } - - return (0); +static int net_send(int *sockfd, const char *buff, int len) { + uint16_t packet_size; + + assert(len > 0); + assert(*sockfd >= 0); + + /* send short containing size of data packet */ + packet_size = htons((uint16_t)len); + + if (swrite(*sockfd, (void *)&packet_size, sizeof(packet_size)) != 0) { + close(*sockfd); + *sockfd = -1; + return -1; + } + + /* send data packet */ + if (swrite(*sockfd, (void *)buff, len) != 0) { + close(*sockfd); + *sockfd = -1; + return -2; + } + + return 0; } /* Get and print status from apcupsd NIS server */ -static int apc_query_server (char *host, int port, - struct apc_detail_s *apcups_detail) -{ - int n; - char recvline[1024]; - char *tokptr; - char *toksaveptr; - char *key; - double value; - _Bool retry = 1; - int status; +static int apc_query_server(char const *node, char const *service, + apc_detail_t *apcups_detail) { + int n; + char recvline[1024]; + char *tokptr; + char *toksaveptr; + int try + = 0; + int status; #if APCMAIN -# define PRINT_VALUE(name, val) printf(" Found property: name = %s; value = %f;\n", name, val) +#define PRINT_VALUE(name, val) \ + printf(" Found property: name = %s; value = %f;\n", name, val) #else -# define PRINT_VALUE(name, val) /**/ +#define PRINT_VALUE(name, val) /**/ #endif - while (retry) - { - if (global_sockfd < 0) - { - global_sockfd = net_open (host, port); - if (global_sockfd < 0) - { - ERROR ("apcups plugin: Connecting to the " - "apcupsd failed."); - return (-1); - } - } - - - status = net_send (&global_sockfd, "status", strlen ("status")); - if (status != 0) - { - /* net_send is closing the socket on error. */ - assert (global_sockfd < 0); - if (retry) - { - retry = 0; - count_retries++; - continue; - } - - ERROR ("apcups plugin: Writing to the socket failed."); - return (-1); - } - - break; - } /* while (retry) */ - - /* When collectd's collection interval is larger than apcupsd's - * timeout, we would have to retry / re-connect each iteration. Try to - * detect this situation and shut down the socket gracefully in that - * case. Otherwise, keep the socket open to avoid overhead. */ - count_iterations++; - if ((count_iterations == 10) && (count_retries > 2)) - { - NOTICE ("apcups plugin: There have been %i retries in the " - "first %i iterations. Will close the socket " - "in future iterations.", - count_retries, count_iterations); - close_socket = 1; - } - - while ((n = net_recv (&global_sockfd, recvline, sizeof (recvline) - 1)) > 0) - { - assert ((unsigned int)n < sizeof (recvline)); - recvline[n] = '\0'; + while (1) { + if (global_sockfd < 0) { + global_sockfd = net_open(node, service); + if (global_sockfd < 0) { + ERROR("apcups plugin: Connecting to the " + "apcupsd failed."); + return -1; + } + } + + status = net_send(&global_sockfd, "status", strlen("status")); + if (status != 0) { + /* net_send closes the socket on error. */ + assert(global_sockfd < 0); + if (try == 0) { + try + ++; + count_retries++; + continue; + } + + ERROR("apcups plugin: Writing to the socket failed."); + return -1; + } + + break; + } /* while (1) */ + + /* When collectd's collection interval is larger than apcupsd's + * timeout, we would have to retry / re-connect each iteration. Try to + * detect this situation and shut down the socket gracefully in that + * case. Otherwise, keep the socket open to avoid overhead. */ + count_iterations++; + if ((count_iterations == 10) && (count_retries > 2)) { + NOTICE("apcups plugin: There have been %i retries in the " + "first %i iterations. Will close the socket " + "in future iterations.", + count_retries, count_iterations); + conf_persistent_conn = false; + } + + while ((n = net_recv(&global_sockfd, recvline, sizeof(recvline) - 1)) > 0) { + assert((size_t)n < sizeof(recvline)); + recvline[n] = 0; #if APCMAIN - printf ("net_recv = `%s';\n", recvline); + printf("net_recv = `%s';\n", recvline); #endif /* if APCMAIN */ - toksaveptr = NULL; - tokptr = strtok_r (recvline, " :\t", &toksaveptr); - while (tokptr != NULL) - { - key = tokptr; - if ((tokptr = strtok_r (NULL, " :\t", &toksaveptr)) == NULL) - continue; - value = atof (tokptr); - - PRINT_VALUE (key, value); - - if (strcmp ("LINEV", key) == 0) - apcups_detail->linev = value; - else if (strcmp ("BATTV", key) == 0) - apcups_detail->battv = value; - else if (strcmp ("ITEMP", key) == 0) - apcups_detail->itemp = value; - else if (strcmp ("LOADPCT", key) == 0) - apcups_detail->loadpct = value; - else if (strcmp ("BCHARGE", key) == 0) - apcups_detail->bcharge = value; - else if (strcmp ("OUTPUTV", key) == 0) - apcups_detail->outputv = value; - else if (strcmp ("LINEFREQ", key) == 0) - apcups_detail->linefreq = value; - else if (strcmp ("TIMELEFT", key) == 0) - { - /* Convert minutes to seconds if requested by - * the user. */ - if (conf_report_seconds) - value *= 60.0; - apcups_detail->timeleft = value; - } - - tokptr = strtok_r (NULL, ":", &toksaveptr); - } /* while (tokptr != NULL) */ - } - status = errno; /* save errno, net_shutdown() may re-set it. */ - - if (close_socket) - net_shutdown (&global_sockfd); - - if (n < 0) - { - char errbuf[1024]; - ERROR ("apcups plugin: Reading from socket failed: %s", - sstrerror (status, errbuf, sizeof (errbuf))); - return (-1); - } - - return (0); + toksaveptr = NULL; + tokptr = strtok_r(recvline, " :\t", &toksaveptr); + while (tokptr != NULL) { + char *key = tokptr; + if ((tokptr = strtok_r(NULL, " :\t", &toksaveptr)) == NULL) + continue; + + gauge_t value; + if (strtogauge(tokptr, &value) != 0) + continue; + + PRINT_VALUE(key, value); + + if (strcmp("LINEV", key) == 0) + apcups_detail->linev = value; + else if (strcmp("BATTV", key) == 0) + apcups_detail->battv = value; + else if (strcmp("ITEMP", key) == 0) + apcups_detail->itemp = value; + else if (strcmp("LOADPCT", key) == 0) + apcups_detail->loadpct = value; + else if (strcmp("BCHARGE", key) == 0) + apcups_detail->bcharge = value; + else if (strcmp("OUTPUTV", key) == 0) + apcups_detail->outputv = value; + else if (strcmp("LINEFREQ", key) == 0) + apcups_detail->linefreq = value; + else if (strcmp("TIMELEFT", key) == 0) { + /* Convert minutes to seconds if requested by + * the user. */ + if (conf_report_seconds) + value *= 60.0; + apcups_detail->timeleft = value; + } + + tokptr = strtok_r(NULL, ":", &toksaveptr); + } /* while (tokptr != NULL) */ + } + status = errno; /* save errno, net_shutdown() may re-set it. */ + + if (!conf_persistent_conn) + net_shutdown(&global_sockfd); + + if (n < 0) { + ERROR("apcups plugin: Reading from socket failed: %s", STRERROR(status)); + return -1; + } + + return 0; } -static int apcups_config (const char *key, const char *value) -{ - if (strcasecmp (key, "host") == 0) - { - if (conf_host != NULL) - { - free (conf_host); - conf_host = NULL; - } - if ((conf_host = strdup (value)) == NULL) - return (1); - } - else if (strcasecmp (key, "Port") == 0) - { - int port_tmp = atoi (value); - if (port_tmp < 1 || port_tmp > 65535) - { - WARNING ("apcups plugin: Invalid port: %i", port_tmp); - return (1); - } - conf_port = port_tmp; - } - else if (strcasecmp (key, "ReportSeconds") == 0) - { - if (IS_TRUE (value)) - conf_report_seconds = 1; - else - conf_report_seconds = 0; - } - else - { - return (-1); - } - return (0); +static int apcups_config(oconfig_item_t *ci) { + bool persistent_conn_set = false; + + for (int i = 0; i < ci->children_num; i++) { + oconfig_item_t *child = ci->children + i; + + if (strcasecmp(child->key, "Host") == 0) + cf_util_get_string(child, &conf_node); + else if (strcasecmp(child->key, "Port") == 0) + cf_util_get_service(child, &conf_service); + else if (strcasecmp(child->key, "ReportSeconds") == 0) + cf_util_get_boolean(child, &conf_report_seconds); + else if (strcasecmp(child->key, "PersistentConnection") == 0) { + cf_util_get_boolean(child, &conf_persistent_conn); + persistent_conn_set = true; + } else + ERROR("apcups plugin: Unknown config option \"%s\".", child->key); + } + + if (!persistent_conn_set) { + double interval = CDTIME_T_TO_DOUBLE(plugin_get_interval()); + if (interval > APCUPS_SERVER_TIMEOUT) { + NOTICE("apcups plugin: Plugin poll interval set to %.3f seconds. " + "Apcupsd NIS socket timeout is %.3f seconds, " + "PersistentConnection disabled by default.", + interval, APCUPS_SERVER_TIMEOUT); + conf_persistent_conn = false; + } + } + + return 0; +} /* int apcups_config */ + +static void apc_submit_generic(const char *type, const char *type_inst, + gauge_t value) { + if (isnan(value)) + return; + + value_list_t vl = VALUE_LIST_INIT; + vl.values = &(value_t){.gauge = value}; + vl.values_len = 1; + sstrncpy(vl.plugin, "apcups", sizeof(vl.plugin)); + sstrncpy(vl.type, type, sizeof(vl.type)); + sstrncpy(vl.type_instance, type_inst, sizeof(vl.type_instance)); + + plugin_dispatch_values(&vl); } -static void apc_submit_generic (char *type, char *type_inst, double value) -{ - value_t values[1]; - value_list_t vl = VALUE_LIST_INIT; - - values[0].gauge = value; +static void apc_submit(apc_detail_t const *apcups_detail) { + apc_submit_generic("voltage", "input", apcups_detail->linev); + apc_submit_generic("voltage", "output", apcups_detail->outputv); + apc_submit_generic("voltage", "battery", apcups_detail->battv); + apc_submit_generic("charge", "", apcups_detail->bcharge); + apc_submit_generic("percent", "load", apcups_detail->loadpct); + apc_submit_generic("timeleft", "", apcups_detail->timeleft); + apc_submit_generic("temperature", "", apcups_detail->itemp); + apc_submit_generic("frequency", "input", apcups_detail->linefreq); +} - vl.values = values; - vl.values_len = 1; - sstrncpy (vl.host, hostname_g, sizeof (vl.host)); - sstrncpy (vl.plugin, "apcups", sizeof (vl.plugin)); - sstrncpy (vl.plugin_instance, "", sizeof (vl.plugin_instance)); - sstrncpy (vl.type, type, sizeof (vl.type)); - sstrncpy (vl.type_instance, type_inst, sizeof (vl.type_instance)); +static int apcups_read(void) { + apc_detail_t apcups_detail = { + .linev = NAN, + .outputv = NAN, + .battv = NAN, + .loadpct = NAN, + .bcharge = NAN, + .timeleft = NAN, + .itemp = NAN, + .linefreq = NAN, + }; + + int status = apc_query_server(conf_node, conf_service, &apcups_detail); + + if (status != 0) { + DEBUG("apcups plugin: apc_query_server (\"%s\", \"%s\") = %d", conf_node, + conf_service, status); + return status; + } + + apc_submit(&apcups_detail); + + return 0; +} /* apcups_read */ - plugin_dispatch_values (&vl); -} +static int apcups_init(void) { + if (conf_node == NULL) + conf_node = APCUPS_DEFAULT_NODE; -static void apc_submit (struct apc_detail_s *apcups_detail) -{ - apc_submit_generic ("voltage", "input", apcups_detail->linev); - apc_submit_generic ("voltage", "output", apcups_detail->outputv); - apc_submit_generic ("voltage", "battery", apcups_detail->battv); - apc_submit_generic ("charge", "", apcups_detail->bcharge); - apc_submit_generic ("percent", "load", apcups_detail->loadpct); - apc_submit_generic ("timeleft", "", apcups_detail->timeleft); - apc_submit_generic ("temperature", "", apcups_detail->itemp); - apc_submit_generic ("frequency", "input", apcups_detail->linefreq); -} + if (conf_service == NULL) + conf_service = APCUPS_DEFAULT_SERVICE; -static int apcups_read (void) -{ - struct apc_detail_s apcups_detail; - int status; - - apcups_detail.linev = -1.0; - apcups_detail.outputv = -1.0; - apcups_detail.battv = -1.0; - apcups_detail.loadpct = -1.0; - apcups_detail.bcharge = -1.0; - apcups_detail.timeleft = NAN; - apcups_detail.itemp = -300.0; - apcups_detail.linefreq = -1.0; - - status = apc_query_server (conf_host == NULL - ? APCUPS_DEFAULT_HOST - : conf_host, - conf_port, &apcups_detail); - - /* - * if we did not connect then do not bother submitting - * zeros. We want rrd files to have NAN. - */ - if (status != 0) - { - DEBUG ("apc_query_server (%s, %i) = %i", - conf_host == NULL - ? APCUPS_DEFAULT_HOST - : conf_host, - conf_port, status); - return (-1); - } - - apc_submit (&apcups_detail); - - return (0); -} /* apcups_read */ + return 0; +} /* apcups_init */ -void module_register (void) -{ - plugin_register_config ("apcups", apcups_config, config_keys, - config_keys_num); - plugin_register_read ("apcups", apcups_read); - plugin_register_shutdown ("apcups", apcups_shutdown); +void module_register(void) { + plugin_register_complex_config("apcups", apcups_config); + plugin_register_init("apcups", apcups_init); + plugin_register_read("apcups", apcups_read); + plugin_register_shutdown("apcups", apcups_shutdown); } /* void module_register */ diff --git a/src/apple_sensors.c b/src/apple_sensors.c index bdba0ff852..ad6e6c039b 100644 --- a/src/apple_sensors.c +++ b/src/apple_sensors.c @@ -2,238 +2,192 @@ * collectd - src/apple_sensors.c * Copyright (C) 2006,2007 Florian octo Forster * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; only version 2 of the License is applicable. + * 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: * - * 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. + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. * - * 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 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. * * Authors: - * Florian octo Forster + * Florian octo Forster **/ #include "collectd.h" -#include "common.h" -#include "plugin.h" -#if HAVE_CTYPE_H -# include -#endif +#include "plugin.h" +#include "utils/common/common.h" #if HAVE_MACH_MACH_TYPES_H -# include +#include #endif #if HAVE_MACH_MACH_INIT_H -# include +#include #endif #if HAVE_MACH_MACH_ERROR_H -# include +#include #endif #if HAVE_MACH_MACH_PORT_H -# include +#include #endif #if HAVE_COREFOUNDATION_COREFOUNDATION_H -# include +#include #endif #if HAVE_IOKIT_IOKITLIB_H -# include +#include #endif #if HAVE_IOKIT_IOTYPES_H -# include +#include #endif static mach_port_t io_master_port = MACH_PORT_NULL; -static int as_init (void) -{ - kern_return_t status; - - if (io_master_port != MACH_PORT_NULL) - { - mach_port_deallocate (mach_task_self (), - io_master_port); - io_master_port = MACH_PORT_NULL; - } - - status = IOMasterPort (MACH_PORT_NULL, &io_master_port); - if (status != kIOReturnSuccess) - { - ERROR ("IOMasterPort failed: %s", - mach_error_string (status)); - io_master_port = MACH_PORT_NULL; - return (-1); - } - - return (0); -} +static int as_init(void) { + kern_return_t status; + + if (io_master_port != MACH_PORT_NULL) { + mach_port_deallocate(mach_task_self(), io_master_port); + io_master_port = MACH_PORT_NULL; + } -static void as_submit (const char *type, const char *type_instance, - double val) -{ - value_t values[1]; - value_list_t vl = VALUE_LIST_INIT; + status = IOMasterPort(MACH_PORT_NULL, &io_master_port); + if (status != kIOReturnSuccess) { + ERROR("IOMasterPort failed: %s", mach_error_string(status)); + io_master_port = MACH_PORT_NULL; + return -1; + } - DEBUG ("type = %s; type_instance = %s; val = %f;", - type, type_instance, val); + return 0; +} - values[0].gauge = val; +static void as_submit(const char *type, const char *type_instance, double val) { + value_list_t vl = VALUE_LIST_INIT; - vl.values = values; - vl.values_len = 1; - sstrncpy (vl.host, hostname_g, sizeof (vl.host)); - sstrncpy (vl.plugin, "apple_sensors", sizeof (vl.plugin)); - sstrncpy (vl.plugin_instance, "", sizeof (vl.plugin_instance)); - sstrncpy (vl.type, type, sizeof (vl.type)); - sstrncpy (vl.type_instance, type_instance, sizeof (vl.type_instance)); + vl.values = &(value_t){.gauge = val}; + vl.values_len = 1; + sstrncpy(vl.plugin, "apple_sensors", sizeof(vl.plugin)); + sstrncpy(vl.type, type, sizeof(vl.type)); + sstrncpy(vl.type_instance, type_instance, sizeof(vl.type_instance)); - plugin_dispatch_values (&vl); + plugin_dispatch_values(&vl); } -static int as_read (void) -{ - kern_return_t status; - io_iterator_t iterator; - io_object_t io_obj; - CFMutableDictionaryRef prop_dict; - CFTypeRef property; - - char type[128]; - char inst[128]; - int value_int; - double value_double; - int i; - - if (!io_master_port || (io_master_port == MACH_PORT_NULL)) - return (-1); - - status = IOServiceGetMatchingServices (io_master_port, - IOServiceNameMatching("IOHWSensor"), - &iterator); - if (status != kIOReturnSuccess) - { - ERROR ("IOServiceGetMatchingServices failed: %s", - mach_error_string (status)); - return (-1); - } - - while ((io_obj = IOIteratorNext (iterator))) - { - prop_dict = NULL; - status = IORegistryEntryCreateCFProperties (io_obj, - &prop_dict, - kCFAllocatorDefault, - kNilOptions); - if (status != kIOReturnSuccess) - { - DEBUG ("IORegistryEntryCreateCFProperties failed: %s", - mach_error_string (status)); - continue; - } - - /* Copy the sensor type. */ - property = NULL; - if (!CFDictionaryGetValueIfPresent (prop_dict, - CFSTR ("type"), - &property)) - continue; - if (CFGetTypeID (property) != CFStringGetTypeID ()) - continue; - if (!CFStringGetCString (property, - type, sizeof (type), - kCFStringEncodingASCII)) - continue; - type[sizeof (type) - 1] = '\0'; - - /* Copy the sensor location. This will be used as `instance'. */ - property = NULL; - if (!CFDictionaryGetValueIfPresent (prop_dict, - CFSTR ("location"), - &property)) - continue; - if (CFGetTypeID (property) != CFStringGetTypeID ()) - continue; - if (!CFStringGetCString (property, - inst, sizeof (inst), - kCFStringEncodingASCII)) - continue; - inst[sizeof (inst) - 1] = '\0'; - for (i = 0; i < 128; i++) - { - if (inst[i] == '\0') - break; - else if (isalnum (inst[i])) - inst[i] = (char) tolower (inst[i]); - else - inst[i] = '_'; - } - - /* Get the actual value. Some computation, based on the `type' - * is neccessary. */ - property = NULL; - if (!CFDictionaryGetValueIfPresent (prop_dict, - CFSTR ("current-value"), - &property)) - continue; - if (CFGetTypeID (property) != CFNumberGetTypeID ()) - continue; - if (!CFNumberGetValue (property, - kCFNumberIntType, - &value_int)) - continue; - - /* Found e.g. in the 1.5GHz PowerBooks */ - if (strcmp (type, "temperature") == 0) - { - value_double = ((double) value_int) / 65536.0; - sstrncpy (type, "temperature", sizeof (type)); - } - else if (strcmp (type, "temp") == 0) - { - value_double = ((double) value_int) / 10.0; - sstrncpy (type, "temperature", sizeof (type)); - } - else if (strcmp (type, "fanspeed") == 0) - { - value_double = ((double) value_int) / 65536.0; - sstrncpy (type, "fanspeed", sizeof (type)); - } - else if (strcmp (type, "voltage") == 0) - { - /* Leave this to the battery plugin. */ - continue; - } - else if (strcmp (type, "adc") == 0) - { - value_double = ((double) value_int) / 10.0; - sstrncpy (type, "fanspeed", sizeof (type)); - } - else - { - DEBUG ("apple_sensors: Read unknown sensor type: %s", - type); - value_double = (double) value_int; - } - - as_submit (type, inst, value_double); - - CFRelease (prop_dict); - IOObjectRelease (io_obj); - } /* while (iterator) */ - - IOObjectRelease (iterator); - - return (0); +static int as_read(void) { + kern_return_t status; + io_iterator_t iterator; + io_object_t io_obj; + CFMutableDictionaryRef prop_dict; + CFTypeRef property; + + char type[128]; + char inst[128]; + int value_int; + double value_double; + if (!io_master_port || (io_master_port == MACH_PORT_NULL)) + return -1; + + status = IOServiceGetMatchingServices( + io_master_port, IOServiceNameMatching("IOHWSensor"), &iterator); + if (status != kIOReturnSuccess) { + ERROR("IOServiceGetMatchingServices failed: %s", mach_error_string(status)); + return -1; + } + + while ((io_obj = IOIteratorNext(iterator))) { + prop_dict = NULL; + status = IORegistryEntryCreateCFProperties( + io_obj, &prop_dict, kCFAllocatorDefault, kNilOptions); + if (status != kIOReturnSuccess) { + DEBUG("IORegistryEntryCreateCFProperties failed: %s", + mach_error_string(status)); + continue; + } + + /* Copy the sensor type. */ + property = NULL; + if (!CFDictionaryGetValueIfPresent(prop_dict, CFSTR("type"), &property)) + continue; + if (CFGetTypeID(property) != CFStringGetTypeID()) + continue; + if (!CFStringGetCString(property, type, sizeof(type), + kCFStringEncodingASCII)) + continue; + type[sizeof(type) - 1] = '\0'; + + /* Copy the sensor location. This will be used as `instance'. */ + property = NULL; + if (!CFDictionaryGetValueIfPresent(prop_dict, CFSTR("location"), &property)) + continue; + if (CFGetTypeID(property) != CFStringGetTypeID()) + continue; + if (!CFStringGetCString(property, inst, sizeof(inst), + kCFStringEncodingASCII)) + continue; + inst[sizeof(inst) - 1] = '\0'; + for (int i = 0; i < 128; i++) { + if (inst[i] == '\0') + break; + else if (isalnum(inst[i])) + inst[i] = (char)tolower(inst[i]); + else + inst[i] = '_'; + } + + /* Get the actual value. Some computation, based on the `type' + * is neccessary. */ + property = NULL; + if (!CFDictionaryGetValueIfPresent(prop_dict, CFSTR("current-value"), + &property)) + continue; + if (CFGetTypeID(property) != CFNumberGetTypeID()) + continue; + if (!CFNumberGetValue(property, kCFNumberIntType, &value_int)) + continue; + + /* Found e.g. in the 1.5GHz PowerBooks */ + if (strcmp(type, "temperature") == 0) { + value_double = ((double)value_int) / 65536.0; + sstrncpy(type, "temperature", sizeof(type)); + } else if (strcmp(type, "temp") == 0) { + value_double = ((double)value_int) / 10.0; + sstrncpy(type, "temperature", sizeof(type)); + } else if (strcmp(type, "fanspeed") == 0) { + value_double = ((double)value_int) / 65536.0; + sstrncpy(type, "fanspeed", sizeof(type)); + } else if (strcmp(type, "voltage") == 0) { + /* Leave this to the battery plugin. */ + continue; + } else if (strcmp(type, "adc") == 0) { + value_double = ((double)value_int) / 10.0; + sstrncpy(type, "fanspeed", sizeof(type)); + } else { + DEBUG("apple_sensors: Read unknown sensor type: %s", type); + value_double = (double)value_int; + } + + as_submit(type, inst, value_double); + + CFRelease(prop_dict); + IOObjectRelease(io_obj); + } /* while (iterator) */ + + IOObjectRelease(iterator); + + return 0; } /* int as_read */ -void module_register (void) -{ - plugin_register_init ("apple_sensors", as_init); - plugin_register_read ("apple_sensors", as_read); +void module_register(void) { + plugin_register_init("apple_sensors", as_init); + plugin_register_read("apple_sensors", as_read); } /* void module_register */ diff --git a/src/aquaero.c b/src/aquaero.c index 84c797bcdb..61dd76db16 100644 --- a/src/aquaero.c +++ b/src/aquaero.c @@ -20,8 +20,9 @@ **/ #include "collectd.h" -#include "common.h" + #include "plugin.h" +#include "utils/common/common.h" #include @@ -29,165 +30,130 @@ * Private variables */ /* Default values for contacting daemon */ -static char *conf_device = NULL; - -static int aquaero_config (oconfig_item_t *ci) -{ - int i; - - for (i = 0; i < ci->children_num; i++) - { - oconfig_item_t *child = ci->children + i; - - if (strcasecmp ("Device", child->key)) - cf_util_get_string (child, &conf_device); - else - { - ERROR ("aquaero plugin: Unknown config option \"%s\".", - child->key); - } - } - - return (0); +static char *conf_device; + +static int aquaero_config(oconfig_item_t *ci) { + for (int i = 0; i < ci->children_num; i++) { + oconfig_item_t *child = ci->children + i; + + if (strcasecmp("Device", child->key)) + cf_util_get_string(child, &conf_device); + else { + ERROR("aquaero plugin: Unknown config option \"%s\".", child->key); + } + } + + return 0; } -static int aquaero_shutdown (void) -{ - libaquaero5_exit(); - return (0); +static int aquaero_shutdown(void) { + libaquaero5_exit(); + return 0; } /* int aquaero_shutdown */ -static void aquaero_submit (const char *type, const char *type_instance, - double value) -{ - const char *instance = conf_device?conf_device:"default"; - value_t values[1]; - value_list_t vl = VALUE_LIST_INIT; - - /* Don't report undefined values. */ - if (value == AQ5_FLOAT_UNDEF) - return; +static void aquaero_submit(const char *type, const char *type_instance, + double value) { + const char *instance = conf_device ? conf_device : "default"; + value_list_t vl = VALUE_LIST_INIT; - values[0].gauge = value; + /* Don't report undefined values. */ + if (value == AQ5_FLOAT_UNDEF) + return; - vl.values = values; - vl.values_len = 1; + vl.values = &(value_t){.gauge = value}; + vl.values_len = 1; - sstrncpy (vl.host, hostname_g, sizeof (vl.host)); - sstrncpy (vl.plugin, "aquaero", sizeof (vl.plugin)); - sstrncpy (vl.plugin_instance, instance, sizeof (vl.plugin_instance)); - sstrncpy (vl.type, type, sizeof (vl.type)); - sstrncpy (vl.type_instance, type_instance, sizeof (vl.type_instance)); + sstrncpy(vl.plugin, "aquaero", sizeof(vl.plugin)); + sstrncpy(vl.plugin_instance, instance, sizeof(vl.plugin_instance)); + sstrncpy(vl.type, type, sizeof(vl.type)); + sstrncpy(vl.type_instance, type_instance, sizeof(vl.type_instance)); - plugin_dispatch_values (&vl); + plugin_dispatch_values(&vl); } /* int aquaero_submit */ /* aquaero_submit_array submits every value of a given array of values */ -static void aquaero_submit_array (const char *type, - const char *type_instance_prefix, double *value_array, int len) -{ - char type_instance[DATA_MAX_NAME_LEN]; - int i; - - for (i = 0; i < len; i++) - { - if (value_array[i] == AQ5_FLOAT_UNDEF) - continue; - - snprintf (type_instance, sizeof (type_instance), "%s%d", - type_instance_prefix, i + 1); - aquaero_submit (type, type_instance, value_array[i]); - } +static void aquaero_submit_array(const char *type, + const char *type_instance_prefix, + double *value_array, int len) { + char type_instance[DATA_MAX_NAME_LEN]; + + for (int i = 0; i < len; i++) { + if (value_array[i] == AQ5_FLOAT_UNDEF) + continue; + + ssnprintf(type_instance, sizeof(type_instance), "%s%d", + type_instance_prefix, i + 1); + aquaero_submit(type, type_instance, value_array[i]); + } } -static int aquaero_read (void) -{ - aq5_data_t aq_data; - aq5_settings_t aq_sett; - char *err_msg = NULL; - char type_instance[DATA_MAX_NAME_LEN]; - int i; - - if (libaquaero5_poll(conf_device, &aq_data, &err_msg) < 0) - { - char errbuf[1024]; - ERROR ("aquaero plugin: Failed to poll device \"%s\": %s (%s)", - conf_device ? conf_device : "default", err_msg, - sstrerror (errno, errbuf, sizeof (errbuf))); - return (-1); - } - - if (libaquaero5_getsettings(conf_device, &aq_sett, &err_msg) < 0) - { - char errbuf[1024]; - ERROR ("aquaero plugin: Failed to get settings " - "for device \"%s\": %s (%s)", - conf_device ? conf_device : "default", err_msg, - sstrerror (errno, errbuf, sizeof (errbuf))); - return (-1); - } - - /* CPU Temperature sensor */ - aquaero_submit("temperature", "cpu", aq_data.cpu_temp[0]); - - /* Temperature sensors */ - aquaero_submit_array("temperature", "sensor", aq_data.temp, - AQ5_NUM_TEMP); - - /* Virtual temperature sensors */ - aquaero_submit_array("temperature", "virtual", aq_data.vtemp, - AQ5_NUM_VIRT_SENSORS); - - /* Software temperature sensors */ - aquaero_submit_array("temperature", "software", aq_data.stemp, - AQ5_NUM_SOFT_SENSORS); - - /* Other temperature sensors */ - aquaero_submit_array("temperature", "other", aq_data.otemp, - AQ5_NUM_OTHER_SENSORS); - - /* Fans */ - for (i = 0; i < AQ5_NUM_FAN; i++) - { - if ((aq_sett.fan_data_source[i] == NONE) - || (aq_data.fan_vrm_temp[i] != AQ5_FLOAT_UNDEF)) - continue; - - snprintf (type_instance, sizeof (type_instance), - "fan%d", i + 1); - - aquaero_submit ("fanspeed", type_instance, - aq_data.fan_rpm[i]); - aquaero_submit ("percentage", type_instance, - aq_data.fan_duty[i]); - aquaero_submit ("voltage", type_instance, - aq_data.fan_voltage[i]); - aquaero_submit ("current", type_instance, - aq_data.fan_current[i]); - - /* Report the voltage reglator module (VRM) temperature with a - * different type instance. */ - snprintf (type_instance, sizeof (type_instance), - "fan%d-vrm", i + 1); - aquaero_submit ("temperature", type_instance, - aq_data.fan_vrm_temp[i]); - } - - /* Flow sensors */ - aquaero_submit_array("flow", "sensor", aq_data.flow, AQ5_NUM_FLOW); - - /* Liquid level */ - aquaero_submit_array("percentage", "waterlevel", - aq_data.level, AQ5_NUM_LEVEL); - - return (0); +static int aquaero_read(void) { + aq5_data_t aq_data; + aq5_settings_t aq_sett; + char *err_msg = NULL; + char type_instance[DATA_MAX_NAME_LEN]; + + if (libaquaero5_poll(conf_device, &aq_data, &err_msg) < 0) { + ERROR("aquaero plugin: Failed to poll device \"%s\": %s (%s)", + conf_device ? conf_device : "default", err_msg, STRERRNO); + return -1; + } + + if (libaquaero5_getsettings(conf_device, &aq_sett, &err_msg) < 0) { + ERROR("aquaero plugin: Failed to get settings " + "for device \"%s\": %s (%s)", + conf_device ? conf_device : "default", err_msg, STRERRNO); + return -1; + } + + /* CPU Temperature sensor */ + aquaero_submit("temperature", "cpu", aq_data.cpu_temp[0]); + + /* Temperature sensors */ + aquaero_submit_array("temperature", "sensor", aq_data.temp, AQ5_NUM_TEMP); + + /* Virtual temperature sensors */ + aquaero_submit_array("temperature", "virtual", aq_data.vtemp, + AQ5_NUM_VIRT_SENSORS); + + /* Software temperature sensors */ + aquaero_submit_array("temperature", "software", aq_data.stemp, + AQ5_NUM_SOFT_SENSORS); + + /* Other temperature sensors */ + aquaero_submit_array("temperature", "other", aq_data.otemp, + AQ5_NUM_OTHER_SENSORS); + + /* Fans */ + for (int i = 0; i < AQ5_NUM_FAN; i++) { + if ((aq_sett.fan_data_source[i] == NONE) || + (aq_data.fan_vrm_temp[i] != AQ5_FLOAT_UNDEF)) + continue; + + 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]); + aquaero_submit("voltage", type_instance, aq_data.fan_voltage[i]); + aquaero_submit("current", type_instance, aq_data.fan_current[i]); + + /* Report the voltage reglator module (VRM) temperature with a + * different type instance. */ + ssnprintf(type_instance, sizeof(type_instance), "fan%d-vrm", i + 1); + aquaero_submit("temperature", type_instance, aq_data.fan_vrm_temp[i]); + } + + /* Flow sensors */ + aquaero_submit_array("flow", "sensor", aq_data.flow, AQ5_NUM_FLOW); + + /* Liquid level */ + aquaero_submit_array("percent", "waterlevel", aq_data.level, AQ5_NUM_LEVEL); + + return 0; } -void module_register (void) -{ - plugin_register_complex_config ("aquaero", aquaero_config); - plugin_register_read ("aquaero", aquaero_read); - plugin_register_shutdown ("aquaero", aquaero_shutdown); +void module_register(void) { + plugin_register_complex_config("aquaero", aquaero_config); + plugin_register_read("aquaero", aquaero_read); + plugin_register_shutdown("aquaero", aquaero_shutdown); } /* void module_register */ - -/* vim: set sw=8 sts=8 noet : */ diff --git a/src/ascent.c b/src/ascent.c index 94a39386b0..6240e31960 100644 --- a/src/ascent.c +++ b/src/ascent.c @@ -1,75 +1,71 @@ /** * collectd - src/ascent.c - * Copyright (C) 2008 Florian octo Forster + * Copyright (C) 2008 Florian octo Forster * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; only version 2 of the License is applicable. + * 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: * - * 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. + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. * - * 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 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. * * Authors: - * Florian octo Forster + * Florian octo Forster **/ #include "collectd.h" -#include "common.h" + #include "plugin.h" -#include "configfile.h" +#include "utils/common/common.h" #include #include -static char *races_list[] = /* {{{ */ -{ - NULL, - "Human", /* 1 */ - "Orc", /* 2 */ - "Dwarf", /* 3 */ - "Nightelf", /* 4 */ - "Undead", /* 5 */ - "Tauren", /* 6 */ - "Gnome", /* 7 */ - "Troll", /* 8 */ - NULL, - "Bloodelf", /* 10 */ - "Draenei" /* 11 */ -}; /* }}} */ -#define RACES_LIST_LENGTH STATIC_ARRAY_SIZE (races_list) - -static char *classes_list[] = /* {{{ */ -{ - NULL, - "Warrior", /* 1 */ - "Paladin", /* 2 */ - "Hunter", /* 3 */ - "Rogue", /* 4 */ - "Priest", /* 5 */ - NULL, - "Shaman", /* 7 */ - "Mage", /* 8 */ - "Warlock", /* 9 */ - NULL, - "Druid" /* 11 */ -}; /* }}} */ -#define CLASSES_LIST_LENGTH STATIC_ARRAY_SIZE (classes_list) - -static char *genders_list[] = /* {{{ */ -{ - "Male", - "Female" -}; /* }}} */ -#define GENDERS_LIST_LENGTH STATIC_ARRAY_SIZE (genders_list) - -struct player_stats_s -{ +static const char *races_list[] = /* {{{ */ + { + NULL, "Human", /* 1 */ + "Orc", /* 2 */ + "Dwarf", /* 3 */ + "Nightelf", /* 4 */ + "Undead", /* 5 */ + "Tauren", /* 6 */ + "Gnome", /* 7 */ + "Troll", /* 8 */ + NULL, "Bloodelf", /* 10 */ + "Draenei" /* 11 */ +}; /* }}} */ +#define RACES_LIST_LENGTH STATIC_ARRAY_SIZE(races_list) + +static const char *classes_list[] = /* {{{ */ + { + NULL, "Warrior", /* 1 */ + "Paladin", /* 2 */ + "Hunter", /* 3 */ + "Rogue", /* 4 */ + "Priest", /* 5 */ + NULL, "Shaman", /* 7 */ + "Mage", /* 8 */ + "Warlock", /* 9 */ + NULL, "Druid" /* 11 */ +}; /* }}} */ +#define CLASSES_LIST_LENGTH STATIC_ARRAY_SIZE(classes_list) + +static const char *genders_list[] = /* {{{ */ + {"Male", "Female"}; /* }}} */ +#define GENDERS_LIST_LENGTH STATIC_ARRAY_SIZE(genders_list) + +struct player_stats_s { int races[RACES_LIST_LENGTH]; int classes[CLASSES_LIST_LENGTH]; int genders[GENDERS_LIST_LENGTH]; @@ -80,8 +76,7 @@ struct player_stats_s }; typedef struct player_stats_s player_stats_t; -struct player_info_s -{ +struct player_info_s { int race; int class; int gender; @@ -89,349 +84,309 @@ struct player_info_s int latency; }; typedef struct player_info_s player_info_t; -#define PLAYER_INFO_STATIC_INIT { -1, -1, -1, -1, -1 } - -static char *url = NULL; -static char *user = NULL; -static char *pass = NULL; -static char *verify_peer = NULL; -static char *verify_host = NULL; -static char *cacert = NULL; - -static CURL *curl = NULL; - -static char *ascent_buffer = NULL; -static size_t ascent_buffer_size = 0; -static size_t ascent_buffer_fill = 0; -static char ascent_curl_error[CURL_ERROR_SIZE]; - -static const char *config_keys[] = -{ - "URL", - "User", - "Password", - "VerifyPeer", - "VerifyHost", - "CACert" +#define PLAYER_INFO_STATIC_INIT \ + { -1, -1, -1, -1, -1 } + +static char *url; +static char *user; +static char *pass; +static char *verify_peer; +static char *verify_host; +static char *cacert; +static char *timeout; + +static CURL *curl; + +static char *ascent_buffer; +static size_t ascent_buffer_size; +static size_t ascent_buffer_fill; +static char ascent_curl_error[CURL_ERROR_SIZE]; + +static const char *config_keys[] = { + "URL", "User", "Password", "VerifyPeer", "VerifyHost", "CACert", "Timeout", }; -static int config_keys_num = STATIC_ARRAY_SIZE (config_keys); +static int config_keys_num = STATIC_ARRAY_SIZE(config_keys); -static int ascent_submit_gauge (const char *plugin_instance, /* {{{ */ - const char *type, const char *type_instance, gauge_t value) -{ - value_t values[1]; +static int ascent_submit_gauge(const char *plugin_instance, /* {{{ */ + const char *type, const char *type_instance, + gauge_t value) { value_list_t vl = VALUE_LIST_INIT; - values[0].gauge = value; - - vl.values = values; + vl.values = &(value_t){.gauge = value}; vl.values_len = 1; - sstrncpy (vl.host, hostname_g, sizeof (vl.host)); - sstrncpy (vl.plugin, "ascent", sizeof (vl.plugin)); + sstrncpy(vl.plugin, "ascent", sizeof(vl.plugin)); if (plugin_instance != NULL) - sstrncpy (vl.plugin_instance, plugin_instance, - sizeof (vl.plugin_instance)); + sstrncpy(vl.plugin_instance, plugin_instance, sizeof(vl.plugin_instance)); - sstrncpy (vl.type, type, sizeof (vl.type)); + sstrncpy(vl.type, type, sizeof(vl.type)); if (type_instance != NULL) - sstrncpy (vl.type_instance, type_instance, sizeof (vl.type_instance)); + sstrncpy(vl.type_instance, type_instance, sizeof(vl.type_instance)); - plugin_dispatch_values (&vl); - return (0); + plugin_dispatch_values(&vl); + return 0; } /* }}} int ascent_submit_gauge */ -static size_t ascent_curl_callback (void *buf, size_t size, size_t nmemb, /* {{{ */ - void __attribute__((unused)) *stream) -{ +static size_t ascent_curl_callback(void *buf, size_t size, + size_t nmemb, /* {{{ */ + void __attribute__((unused)) * stream) { size_t len = size * nmemb; - if (len <= 0) - return (len); + if (len == 0) + return len; - if ((ascent_buffer_fill + len) >= ascent_buffer_size) - { + if ((ascent_buffer_fill + len) >= ascent_buffer_size) { char *temp; - temp = (char *) realloc (ascent_buffer, - ascent_buffer_fill + len + 1); - if (temp == NULL) - { - ERROR ("ascent plugin: realloc failed."); - return (0); + temp = realloc(ascent_buffer, ascent_buffer_fill + len + 1); + if (temp == NULL) { + ERROR("ascent plugin: realloc failed."); + return 0; } ascent_buffer = temp; ascent_buffer_size = ascent_buffer_fill + len + 1; } - memcpy (ascent_buffer + ascent_buffer_fill, (char *) buf, len); + memcpy(ascent_buffer + ascent_buffer_fill, (char *)buf, len); ascent_buffer_fill += len; ascent_buffer[ascent_buffer_fill] = 0; - return (len); + return len; } /* }}} size_t ascent_curl_callback */ -static int ascent_submit_players (player_stats_t *ps) /* {{{ */ +static int ascent_submit_players(player_stats_t *ps) /* {{{ */ { - size_t i; gauge_t value; - for (i = 0; i < RACES_LIST_LENGTH; i++) + for (size_t i = 0; i < RACES_LIST_LENGTH; i++) if (races_list[i] != NULL) - ascent_submit_gauge ("by-race", "players", races_list[i], - (gauge_t) ps->races[i]); + ascent_submit_gauge("by-race", "players", races_list[i], + (gauge_t)ps->races[i]); - for (i = 0; i < CLASSES_LIST_LENGTH; i++) + for (size_t i = 0; i < CLASSES_LIST_LENGTH; i++) if (classes_list[i] != NULL) - ascent_submit_gauge ("by-class", "players", classes_list[i], - (gauge_t) ps->classes[i]); + ascent_submit_gauge("by-class", "players", classes_list[i], + (gauge_t)ps->classes[i]); - for (i = 0; i < GENDERS_LIST_LENGTH; i++) + for (size_t i = 0; i < GENDERS_LIST_LENGTH; i++) if (genders_list[i] != NULL) - ascent_submit_gauge ("by-gender", "players", genders_list[i], - (gauge_t) ps->genders[i]); + ascent_submit_gauge("by-gender", "players", genders_list[i], + (gauge_t)ps->genders[i]); if (ps->level_num <= 0) value = NAN; else - value = ((double) ps->level_sum) / ((double) ps->level_num); - ascent_submit_gauge (NULL, "gauge", "avg-level", value); + value = ((double)ps->level_sum) / ((double)ps->level_num); + ascent_submit_gauge(NULL, "gauge", "avg-level", value); /* Latency is in ms, but we store seconds. */ if (ps->latency_num <= 0) value = NAN; else - value = ((double) ps->latency_sum) / (1000.0 * ((double) ps->latency_num)); - ascent_submit_gauge (NULL, "latency", "average", value); + value = ((double)ps->latency_sum) / (1000.0 * ((double)ps->latency_num)); + ascent_submit_gauge(NULL, "latency", "average", value); - return (0); + return 0; } /* }}} int ascent_submit_players */ -static int ascent_account_player (player_stats_t *ps, /* {{{ */ - player_info_t *pi) -{ - if (pi->race >= 0) - { - if (((size_t) pi->race >= RACES_LIST_LENGTH) - || (races_list[pi->race] == NULL)) - ERROR ("ascent plugin: Ignoring invalid numeric race %i.", pi->race); +static int ascent_account_player(player_stats_t *ps, /* {{{ */ + player_info_t *pi) { + if (pi->race >= 0) { + if (((size_t)pi->race >= RACES_LIST_LENGTH) || + (races_list[pi->race] == NULL)) + ERROR("ascent plugin: Ignoring invalid numeric race %i.", pi->race); else ps->races[pi->race]++; } - if (pi->class >= 0) - { - if (((size_t) pi->class >= CLASSES_LIST_LENGTH) - || (classes_list[pi->class] == NULL)) - ERROR ("ascent plugin: Ignoring invalid numeric class %i.", pi->class); + if (pi->class >= 0) { + if (((size_t)pi->class >= CLASSES_LIST_LENGTH) || + (classes_list[pi->class] == NULL)) + ERROR("ascent plugin: Ignoring invalid numeric class %i.", pi->class); else ps->classes[pi->class]++; } - if (pi->gender >= 0) - { - if (((size_t) pi->gender >= GENDERS_LIST_LENGTH) - || (genders_list[pi->gender] == NULL)) - ERROR ("ascent plugin: Ignoring invalid numeric gender %i.", - pi->gender); + if (pi->gender >= 0) { + if (((size_t)pi->gender >= GENDERS_LIST_LENGTH) || + (genders_list[pi->gender] == NULL)) + ERROR("ascent plugin: Ignoring invalid numeric gender %i.", pi->gender); else ps->genders[pi->gender]++; } - - if (pi->level > 0) - { + if (pi->level > 0) { ps->level_sum += pi->level; ps->level_num++; } - if (pi->latency >= 0) - { + if (pi->latency >= 0) { ps->latency_sum += pi->latency; ps->latency_num++; } - return (0); + return 0; } /* }}} int ascent_account_player */ -static int ascent_xml_submit_gauge (xmlDoc *doc, xmlNode *node, /* {{{ */ - const char *plugin_instance, const char *type, const char *type_instance) -{ +static int ascent_xml_submit_gauge(xmlDoc *doc, xmlNode *node, /* {{{ */ + const char *plugin_instance, + const char *type, + const char *type_instance) { char *str_ptr; gauge_t value; - str_ptr = (char *) xmlNodeListGetString (doc, node->xmlChildrenNode, 1); - if (str_ptr == NULL) - { - ERROR ("ascent plugin: ascent_xml_submit_gauge: xmlNodeListGetString failed."); - return (-1); + str_ptr = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1); + if (str_ptr == NULL) { + ERROR( + "ascent plugin: ascent_xml_submit_gauge: xmlNodeListGetString failed."); + return -1; } - if (strcasecmp ("N/A", str_ptr) == 0) + if (strcasecmp("N/A", str_ptr) == 0) value = NAN; - else - { + else { char *end_ptr = NULL; - value = strtod (str_ptr, &end_ptr); - if (str_ptr == end_ptr) - { + value = strtod(str_ptr, &end_ptr); + if (str_ptr == end_ptr) { xmlFree(str_ptr); - ERROR ("ascent plugin: ascent_xml_submit_gauge: strtod failed."); - return (-1); + ERROR("ascent plugin: ascent_xml_submit_gauge: strtod failed."); + return -1; } } xmlFree(str_ptr); - return (ascent_submit_gauge (plugin_instance, type, type_instance, value)); + return ascent_submit_gauge(plugin_instance, type, type_instance, value); } /* }}} int ascent_xml_submit_gauge */ -static int ascent_xml_read_int (xmlDoc *doc, xmlNode *node, /* {{{ */ - int *ret_value) -{ +static int ascent_xml_read_int(xmlDoc *doc, xmlNode *node, /* {{{ */ + int *ret_value) { char *str_ptr; int value; - str_ptr = (char *) xmlNodeListGetString (doc, node->xmlChildrenNode, 1); - if (str_ptr == NULL) - { - ERROR ("ascent plugin: ascent_xml_read_int: xmlNodeListGetString failed."); - return (-1); + str_ptr = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1); + if (str_ptr == NULL) { + ERROR("ascent plugin: ascent_xml_read_int: xmlNodeListGetString failed."); + return -1; } - if (strcasecmp ("N/A", str_ptr) == 0) + if (strcasecmp("N/A", str_ptr) == 0) value = -1; - else - { + else { char *end_ptr = NULL; - value = strtol (str_ptr, &end_ptr, 0); - if (str_ptr == end_ptr) - { + value = strtol(str_ptr, &end_ptr, 0); + if (str_ptr == end_ptr) { xmlFree(str_ptr); - ERROR ("ascent plugin: ascent_xml_read_int: strtol failed."); - return (-1); + ERROR("ascent plugin: ascent_xml_read_int: strtol failed."); + return -1; } } xmlFree(str_ptr); *ret_value = value; - return (0); + return 0; } /* }}} int ascent_xml_read_int */ -static int ascent_xml_sessions_plr (xmlDoc *doc, xmlNode *node, /* {{{ */ - player_info_t *pi) -{ - xmlNode *child; - - for (child = node->xmlChildrenNode; child != NULL; child = child->next) - { - if ((xmlStrcmp ((const xmlChar *) "comment", child->name) == 0) - || (xmlStrcmp ((const xmlChar *) "text", child->name) == 0)) +static int ascent_xml_sessions_plr(xmlDoc *doc, xmlNode *node, /* {{{ */ + player_info_t *pi) { + for (xmlNode *child = node->xmlChildrenNode; child != NULL; + child = child->next) { + if ((xmlStrcmp((const xmlChar *)"comment", child->name) == 0) || + (xmlStrcmp((const xmlChar *)"text", child->name) == 0)) /* ignore */; - else if (xmlStrcmp ((const xmlChar *) "race", child->name) == 0) - ascent_xml_read_int (doc, child, &pi->race); - else if (xmlStrcmp ((const xmlChar *) "class", child->name) == 0) - ascent_xml_read_int (doc, child, &pi->class); - else if (xmlStrcmp ((const xmlChar *) "gender", child->name) == 0) - ascent_xml_read_int (doc, child, &pi->gender); - else if (xmlStrcmp ((const xmlChar *) "level", child->name) == 0) - ascent_xml_read_int (doc, child, &pi->level); - else if (xmlStrcmp ((const xmlChar *) "latency", child->name) == 0) - ascent_xml_read_int (doc, child, &pi->latency); - else if ((xmlStrcmp ((const xmlChar *) "name", child->name) == 0) - || (xmlStrcmp ((const xmlChar *) "pvprank", child->name) == 0) - || (xmlStrcmp ((const xmlChar *) "map", child->name) == 0) - || (xmlStrcmp ((const xmlChar *) "areaid", child->name) == 0) - || (xmlStrcmp ((const xmlChar *) "xpos", child->name) == 0) - || (xmlStrcmp ((const xmlChar *) "ypos", child->name) == 0) - || (xmlStrcmp ((const xmlChar *) "onime", child->name) == 0)) + else if (xmlStrcmp((const xmlChar *)"race", child->name) == 0) + ascent_xml_read_int(doc, child, &pi->race); + else if (xmlStrcmp((const xmlChar *)"class", child->name) == 0) + ascent_xml_read_int(doc, child, &pi->class); + else if (xmlStrcmp((const xmlChar *)"gender", child->name) == 0) + ascent_xml_read_int(doc, child, &pi->gender); + else if (xmlStrcmp((const xmlChar *)"level", child->name) == 0) + ascent_xml_read_int(doc, child, &pi->level); + else if (xmlStrcmp((const xmlChar *)"latency", child->name) == 0) + ascent_xml_read_int(doc, child, &pi->latency); + else if ((xmlStrcmp((const xmlChar *)"name", child->name) == 0) || + (xmlStrcmp((const xmlChar *)"pvprank", child->name) == 0) || + (xmlStrcmp((const xmlChar *)"map", child->name) == 0) || + (xmlStrcmp((const xmlChar *)"areaid", child->name) == 0) || + (xmlStrcmp((const xmlChar *)"xpos", child->name) == 0) || + (xmlStrcmp((const xmlChar *)"ypos", child->name) == 0) || + (xmlStrcmp((const xmlChar *)"onime", child->name) == 0)) /* ignore */; - else - { - WARNING ("ascent plugin: ascent_xml_status: Unknown tag: %s", child->name); + else { + WARNING("ascent plugin: ascent_xml_status: Unknown tag: %s", child->name); } } /* for (child) */ - return (0); + return 0; } /* }}} int ascent_xml_sessions_plr */ -static int ascent_xml_sessions (xmlDoc *doc, xmlNode *node) /* {{{ */ +static int ascent_xml_sessions(xmlDoc *doc, xmlNode *node) /* {{{ */ { - xmlNode *child; - player_stats_t ps; + player_stats_t ps = {.level_sum = 0}; - memset (&ps, 0, sizeof (ps)); - - for (child = node->xmlChildrenNode; child != NULL; child = child->next) - { - if ((xmlStrcmp ((const xmlChar *) "comment", child->name) == 0) - || (xmlStrcmp ((const xmlChar *) "text", child->name) == 0)) + for (xmlNode *child = node->xmlChildrenNode; child != NULL; + child = child->next) { + if ((xmlStrcmp((const xmlChar *)"comment", child->name) == 0) || + (xmlStrcmp((const xmlChar *)"text", child->name) == 0)) /* ignore */; - else if (xmlStrcmp ((const xmlChar *) "plr", child->name) == 0) - { + else if (xmlStrcmp((const xmlChar *)"plr", child->name) == 0) { int status; player_info_t pi = PLAYER_INFO_STATIC_INIT; - status = ascent_xml_sessions_plr (doc, child, &pi); + status = ascent_xml_sessions_plr(doc, child, &pi); if (status == 0) - ascent_account_player (&ps, &pi); - } - else - { - WARNING ("ascent plugin: ascent_xml_status: Unknown tag: %s", child->name); + ascent_account_player(&ps, &pi); + } else { + WARNING("ascent plugin: ascent_xml_status: Unknown tag: %s", child->name); } } /* for (child) */ - ascent_submit_players (&ps); + ascent_submit_players(&ps); - return (0); + return 0; } /* }}} int ascent_xml_sessions */ -static int ascent_xml_status (xmlDoc *doc, xmlNode *node) /* {{{ */ +static int ascent_xml_status(xmlDoc *doc, xmlNode *node) /* {{{ */ { - xmlNode *child; - - for (child = node->xmlChildrenNode; child != NULL; child = child->next) - { - if ((xmlStrcmp ((const xmlChar *) "comment", child->name) == 0) - || (xmlStrcmp ((const xmlChar *) "text", child->name) == 0)) + for (xmlNode *child = node->xmlChildrenNode; child != NULL; + child = child->next) { + if ((xmlStrcmp((const xmlChar *)"comment", child->name) == 0) || + (xmlStrcmp((const xmlChar *)"text", child->name) == 0)) /* ignore */; - else if (xmlStrcmp ((const xmlChar *) "alliance", child->name) == 0) - ascent_xml_submit_gauge (doc, child, NULL, "players", "alliance"); - else if (xmlStrcmp ((const xmlChar *) "horde", child->name) == 0) - ascent_xml_submit_gauge (doc, child, NULL, "players", "horde"); - else if (xmlStrcmp ((const xmlChar *) "qplayers", child->name) == 0) - ascent_xml_submit_gauge (doc, child, NULL, "players", "queued"); - else if ((xmlStrcmp ((const xmlChar *) "acceptedconns", child->name) == 0) - || (xmlStrcmp ((const xmlChar *) "avglat", child->name) == 0) - || (xmlStrcmp ((const xmlChar *) "cdbquerysize", child->name) == 0) - || (xmlStrcmp ((const xmlChar *) "cpu", child->name) == 0) - || (xmlStrcmp ((const xmlChar *) "fthreads", child->name) == 0) - || (xmlStrcmp ((const xmlChar *) "gmcount", child->name) == 0) - || (xmlStrcmp ((const xmlChar *) "lastupdate", child->name) == 0) - || (xmlStrcmp ((const xmlChar *) "ontime", child->name) == 0) - || (xmlStrcmp ((const xmlChar *) "oplayers", child->name) == 0) - || (xmlStrcmp ((const xmlChar *) "peakcount", child->name) == 0) - || (xmlStrcmp ((const xmlChar *) "platform", child->name) == 0) - || (xmlStrcmp ((const xmlChar *) "ram", child->name) == 0) - || (xmlStrcmp ((const xmlChar *) "threads", child->name) == 0) - || (xmlStrcmp ((const xmlChar *) "uptime", child->name) == 0) - || (xmlStrcmp ((const xmlChar *) "wdbquerysize", child->name) == 0)) + else if (xmlStrcmp((const xmlChar *)"alliance", child->name) == 0) + ascent_xml_submit_gauge(doc, child, NULL, "players", "alliance"); + else if (xmlStrcmp((const xmlChar *)"horde", child->name) == 0) + ascent_xml_submit_gauge(doc, child, NULL, "players", "horde"); + else if (xmlStrcmp((const xmlChar *)"qplayers", child->name) == 0) + ascent_xml_submit_gauge(doc, child, NULL, "players", "queued"); + else if ((xmlStrcmp((const xmlChar *)"acceptedconns", child->name) == 0) || + (xmlStrcmp((const xmlChar *)"avglat", child->name) == 0) || + (xmlStrcmp((const xmlChar *)"cdbquerysize", child->name) == 0) || + (xmlStrcmp((const xmlChar *)"cpu", child->name) == 0) || + (xmlStrcmp((const xmlChar *)"fthreads", child->name) == 0) || + (xmlStrcmp((const xmlChar *)"gmcount", child->name) == 0) || + (xmlStrcmp((const xmlChar *)"lastupdate", child->name) == 0) || + (xmlStrcmp((const xmlChar *)"ontime", child->name) == 0) || + (xmlStrcmp((const xmlChar *)"oplayers", child->name) == 0) || + (xmlStrcmp((const xmlChar *)"peakcount", child->name) == 0) || + (xmlStrcmp((const xmlChar *)"platform", child->name) == 0) || + (xmlStrcmp((const xmlChar *)"ram", child->name) == 0) || + (xmlStrcmp((const xmlChar *)"threads", child->name) == 0) || + (xmlStrcmp((const xmlChar *)"uptime", child->name) == 0) || + (xmlStrcmp((const xmlChar *)"wdbquerysize", child->name) == 0)) /* ignore */; - else - { - WARNING ("ascent plugin: ascent_xml_status: Unknown tag: %s", child->name); + else { + WARNING("ascent plugin: ascent_xml_status: Unknown tag: %s", child->name); } } /* for (child) */ - return (0); + return 0; } /* }}} int ascent_xml_status */ -static int ascent_xml (const char *data) /* {{{ */ +static int ascent_xml(const char *data) /* {{{ */ { xmlDoc *doc; xmlNode *cur; - xmlNode *child; #if 0 doc = xmlParseMemory (data, strlen (data), @@ -439,183 +394,182 @@ static int ascent_xml (const char *data) /* {{{ */ /* encoding = */ NULL, /* options = */ 0); #else - doc = xmlParseMemory (data, strlen (data)); + doc = xmlParseMemory(data, strlen(data)); #endif - if (doc == NULL) - { - ERROR ("ascent plugin: xmlParseMemory failed."); - return (-1); + if (doc == NULL) { + ERROR("ascent plugin: xmlParseMemory failed."); + return -1; } - cur = xmlDocGetRootElement (doc); - if (cur == NULL) - { - ERROR ("ascent plugin: XML document is empty."); - xmlFreeDoc (doc); - return (-1); + cur = xmlDocGetRootElement(doc); + if (cur == NULL) { + ERROR("ascent plugin: XML document is empty."); + xmlFreeDoc(doc); + return -1; } - if (xmlStrcmp ((const xmlChar *) "serverpage", cur->name) != 0) - { - ERROR ("ascent plugin: XML root element is not \"serverpage\"."); - xmlFreeDoc (doc); - return (-1); + if (xmlStrcmp((const xmlChar *)"serverpage", cur->name) != 0) { + ERROR("ascent plugin: XML root element is not \"serverpage\"."); + xmlFreeDoc(doc); + return -1; } - for (child = cur->xmlChildrenNode; child != NULL; child = child->next) - { - if ((xmlStrcmp ((const xmlChar *) "comment", child->name) == 0) - || (xmlStrcmp ((const xmlChar *) "text", child->name) == 0)) + for (xmlNode *child = cur->xmlChildrenNode; child != NULL; + child = child->next) { + if ((xmlStrcmp((const xmlChar *)"comment", child->name) == 0) || + (xmlStrcmp((const xmlChar *)"text", child->name) == 0)) /* ignore */; - else if (xmlStrcmp ((const xmlChar *) "status", child->name) == 0) - ascent_xml_status (doc, child); - else if (xmlStrcmp ((const xmlChar *) "instances", child->name) == 0) + else if (xmlStrcmp((const xmlChar *)"status", child->name) == 0) + ascent_xml_status(doc, child); + else if (xmlStrcmp((const xmlChar *)"instances", child->name) == 0) /* ignore for now */; - else if (xmlStrcmp ((const xmlChar *) "gms", child->name) == 0) + else if (xmlStrcmp((const xmlChar *)"gms", child->name) == 0) /* ignore for now */; - else if (xmlStrcmp ((const xmlChar *) "sessions", child->name) == 0) - ascent_xml_sessions (doc, child); - else - { - WARNING ("ascent plugin: ascent_xml: Unknown tag: %s", child->name); + else if (xmlStrcmp((const xmlChar *)"sessions", child->name) == 0) + ascent_xml_sessions(doc, child); + else { + WARNING("ascent plugin: ascent_xml: Unknown tag: %s", child->name); } } /* for (child) */ - xmlFreeDoc (doc); - return (0); + xmlFreeDoc(doc); + return 0; } /* }}} int ascent_xml */ -static int config_set (char **var, const char *value) /* {{{ */ +static int config_set(char **var, const char *value) /* {{{ */ { - if (*var != NULL) - { - free (*var); + if (*var != NULL) { + free(*var); *var = NULL; } - if ((*var = strdup (value)) == NULL) - return (1); + if ((*var = strdup(value)) == NULL) + return 1; else - return (0); + return 0; } /* }}} int config_set */ -static int ascent_config (const char *key, const char *value) /* {{{ */ +static int ascent_config(const char *key, const char *value) /* {{{ */ { - if (strcasecmp (key, "URL") == 0) - return (config_set (&url, value)); - else if (strcasecmp (key, "User") == 0) - return (config_set (&user, value)); - else if (strcasecmp (key, "Password") == 0) - return (config_set (&pass, value)); - else if (strcasecmp (key, "VerifyPeer") == 0) - return (config_set (&verify_peer, value)); - else if (strcasecmp (key, "VerifyHost") == 0) - return (config_set (&verify_host, value)); - else if (strcasecmp (key, "CACert") == 0) - return (config_set (&cacert, value)); + if (strcasecmp(key, "URL") == 0) + return config_set(&url, value); + else if (strcasecmp(key, "User") == 0) + return config_set(&user, value); + else if (strcasecmp(key, "Password") == 0) + return config_set(&pass, value); + else if (strcasecmp(key, "VerifyPeer") == 0) + return config_set(&verify_peer, value); + else if (strcasecmp(key, "VerifyHost") == 0) + return config_set(&verify_host, value); + else if (strcasecmp(key, "CACert") == 0) + return config_set(&cacert, value); + else if (strcasecmp(key, "Timeout") == 0) + return config_set(&timeout, value); else - return (-1); + return -1; } /* }}} int ascent_config */ -static int ascent_init (void) /* {{{ */ +static int ascent_init(void) /* {{{ */ { - static char credentials[1024]; - - if (url == NULL) - { - WARNING ("ascent plugin: ascent_init: No URL configured, " - "returning an error."); - return (-1); + if (url == NULL) { + WARNING("ascent plugin: ascent_init: No URL configured, " + "returning an error."); + return -1; } - if (curl != NULL) - { - curl_easy_cleanup (curl); + if (curl != NULL) { + curl_easy_cleanup(curl); } - if ((curl = curl_easy_init ()) == NULL) - { - ERROR ("ascent plugin: ascent_init: curl_easy_init failed."); - return (-1); + if ((curl = curl_easy_init()) == NULL) { + ERROR("ascent plugin: ascent_init: curl_easy_init failed."); + return -1; } - curl_easy_setopt (curl, CURLOPT_NOSIGNAL, 1L); - curl_easy_setopt (curl, CURLOPT_WRITEFUNCTION, ascent_curl_callback); - curl_easy_setopt (curl, CURLOPT_USERAGENT, PACKAGE_NAME"/"PACKAGE_VERSION); - curl_easy_setopt (curl, CURLOPT_ERRORBUFFER, ascent_curl_error); + curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1L); + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, ascent_curl_callback); + curl_easy_setopt(curl, CURLOPT_USERAGENT, COLLECTD_USERAGENT); + curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, ascent_curl_error); - if (user != NULL) - { + if (user != NULL) { +#ifdef HAVE_CURLOPT_USERNAME + curl_easy_setopt(curl, CURLOPT_USERNAME, user); + curl_easy_setopt(curl, CURLOPT_PASSWORD, (pass == NULL) ? "" : pass); +#else + static char credentials[1024]; int status; - 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."); - return (-1); + 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."); + return -1; } - curl_easy_setopt (curl, CURLOPT_USERPWD, credentials); + curl_easy_setopt(curl, CURLOPT_USERPWD, credentials); +#endif } - curl_easy_setopt (curl, CURLOPT_URL, url); - curl_easy_setopt (curl, CURLOPT_FOLLOWLOCATION, 1L); - curl_easy_setopt (curl, CURLOPT_MAXREDIRS, 50L); + curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L); + curl_easy_setopt(curl, CURLOPT_MAXREDIRS, 50L); - if ((verify_peer == NULL) || IS_TRUE (verify_peer)) - curl_easy_setopt (curl, CURLOPT_SSL_VERIFYPEER, 1L); + if ((verify_peer == NULL) || IS_TRUE(verify_peer)) + curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 1L); else - curl_easy_setopt (curl, CURLOPT_SSL_VERIFYPEER, 0L); + curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L); - if ((verify_host == NULL) || IS_TRUE (verify_host)) - curl_easy_setopt (curl, CURLOPT_SSL_VERIFYHOST, 2L); + if ((verify_host == NULL) || IS_TRUE(verify_host)) + curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 2L); else - curl_easy_setopt (curl, CURLOPT_SSL_VERIFYHOST, 0L); + curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L); if (cacert != NULL) - curl_easy_setopt (curl, CURLOPT_CAINFO, cacert); + curl_easy_setopt(curl, CURLOPT_CAINFO, cacert); + +#ifdef HAVE_CURLOPT_TIMEOUT_MS + if (timeout != NULL) + curl_easy_setopt(curl, CURLOPT_TIMEOUT_MS, atol(timeout)); + else + curl_easy_setopt(curl, CURLOPT_TIMEOUT_MS, + (long)CDTIME_T_TO_MS(plugin_get_interval())); +#endif - return (0); + return 0; } /* }}} int ascent_init */ -static int ascent_read (void) /* {{{ */ +static int ascent_read(void) /* {{{ */ { int status; - if (curl == NULL) - { - ERROR ("ascent plugin: I don't have a CURL object."); - return (-1); + if (curl == NULL) { + ERROR("ascent plugin: I don't have a CURL object."); + return -1; } - if (url == NULL) - { - ERROR ("ascent plugin: No URL has been configured."); - return (-1); + if (url == NULL) { + ERROR("ascent plugin: No URL has been configured."); + return -1; } ascent_buffer_fill = 0; - if (curl_easy_perform (curl) != CURLE_OK) - { - ERROR ("ascent plugin: curl_easy_perform failed: %s", - ascent_curl_error); - return (-1); + + curl_easy_setopt(curl, CURLOPT_URL, url); + + if (curl_easy_perform(curl) != CURLE_OK) { + ERROR("ascent plugin: curl_easy_perform failed: %s", ascent_curl_error); + return -1; } - status = ascent_xml (ascent_buffer); + status = ascent_xml(ascent_buffer); if (status != 0) - return (-1); + return -1; else - return (0); + return 0; } /* }}} int ascent_read */ -void module_register (void) -{ - plugin_register_config ("ascent", ascent_config, config_keys, config_keys_num); - plugin_register_init ("ascent", ascent_init); - plugin_register_read ("ascent", ascent_read); +void module_register(void) { + plugin_register_config("ascent", ascent_config, config_keys, config_keys_num); + plugin_register_init("ascent", ascent_init); + plugin_register_read("ascent", ascent_read); } /* void module_register */ - -/* vim: set sw=2 sts=2 ts=8 et fdm=marker : */ diff --git a/src/barometer.c b/src/barometer.c new file mode 100644 index 0000000000..fd733b4959 --- /dev/null +++ b/src/barometer.c @@ -0,0 +1,1657 @@ +/** + * collectd - src/barometer.c + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; only version 2.1 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser 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: + * Tomas Menzl + **/ + +#include "collectd.h" + +#include "plugin.h" +#include "utils/common/common.h" +#include "utils_cache.h" + +#include +#include +#if HAVE_I2C_SMBUS_H +#include +#endif +#include +#include +#include +#include + +/* ------------ MPL115 defines ------------ */ +/* I2C address of the MPL115 sensor */ +#define MPL115_I2C_ADDRESS 0x60 + +/* register addresses */ +#define MPL115_ADDR_CONV 0x00 +#define MPL115_ADDR_COEFFS 0x04 + +/* register sizes */ +#define MPL115_NUM_CONV 4 +#define MPL115_NUM_COEFFS 12 + +/* commands / addresses */ +#define MPL115_CMD_CONVERT_PRESS 0x10 +#define MPL115_CMD_CONVERT_TEMP 0x11 +#define MPL115_CMD_CONVERT_BOTH 0x12 + +#define MPL115_CONVERSION_RETRIES 5 + +/* ------------ MPL3115 defines ------------ */ +/* MPL3115 I2C address */ +#define MPL3115_I2C_ADDRESS 0x60 + +/* register addresses (only the interesting ones) */ +#define MPL3115_REG_STATUS 0x00 +#define MPL3115_REG_OUT_P_MSB 0x01 +#define MPL3115_REG_OUT_P_CSB 0x02 +#define MPL3115_REG_OUT_P_LSB 0x03 +#define MPL3115_REG_OUT_T_MSB 0x04 +#define MPL3115_REG_OUT_T_LSB 0x05 +#define MPL3115_REG_DR_STATUS 0x06 +#define MPL3115_REG_WHO_AM_I 0x0C +#define MPL3115_REG_SYSMOD 0x11 +#define MPL3115_REG_PT_DATA_CFG 0x13 +#define MPL3115_REG_BAR_IN_MSB 0x14 +#define MPL3115_REG_BAR_IN_LSB 0x15 +#define MPL3115_REG_CTRL_REG1 0x26 +#define MPL3115_REG_CTRL_REG2 0x27 +#define MPL3115_REG_CTRL_REG3 0x28 +#define MPL3115_REG_CTRL_REG4 0x29 +#define MPL3115_REG_CTRL_REG5 0x2A +#define MPL3115_REG_OFF_P 0x2B +#define MPL3115_REG_OFF_T 0x2C +#define MPL3115_REG_OFF_H 0x2D + +/* Register values, masks */ +#define MPL3115_WHO_AM_I_RESP 0xC4 + +#define MPL3115_PT_DATA_DREM 0x04 +#define MPL3115_PT_DATA_PDEF 0x02 +#define MPL3115_PT_DATA_TDEF 0x01 + +#define MPL3115_DR_STATUS_TDR 0x02 +#define MPL3115_DR_STATUS_PDR 0x04 +#define MPL3115_DR_STATUS_PTDR 0x08 +#define MPL3115_DR_STATUS_DR \ + (MPL3115_DR_STATUS_TDR | MPL3115_DR_STATUS_PDR | MPL3115_DR_STATUS_PTDR) + +#define MPL3115_DR_STATUS_TOW 0x20 +#define MPL3115_DR_STATUS_POW 0x40 +#define MPL3115_DR_STATUS_PTOW 0x80 + +#define MPL3115_CTRL_REG1_ALT 0x80 +#define MPL3115_CTRL_REG1_RAW 0x40 +#define MPL3115_CTRL_REG1_OST_MASK 0x38 +#define MPL3115_CTRL_REG1_OST_1 0x00 +#define MPL3115_CTRL_REG1_OST_2 0x08 +#define MPL3115_CTRL_REG1_OST_4 0x10 +#define MPL3115_CTRL_REG1_OST_8 0x18 +#define MPL3115_CTRL_REG1_OST_16 0x20 +#define MPL3115_CTRL_REG1_OST_32 0x28 +#define MPL3115_CTRL_REG1_OST_64 0x30 +#define MPL3115_CTRL_REG1_OST_128 0x38 +#define MPL3115_CTRL_REG1_RST 0x04 +#define MPL3115_CTRL_REG1_OST 0x02 +#define MPL3115_CTRL_REG1_SBYB 0x01 +#define MPL3115_CTRL_REG1_SBYB_MASK 0xFE + +#define MPL3115_NUM_CONV_VALS 5 + +/* ------------ BMP085 defines ------------ */ +/* I2C address of the BMP085 sensor */ +#define BMP085_I2C_ADDRESS 0x77 + +/* register addresses */ +#define BMP085_ADDR_ID_REG 0xD0 +#define BMP085_ADDR_VERSION 0xD1 + +#define BMP085_ADDR_CONV 0xF6 + +#define BMP085_ADDR_CTRL_REG 0xF4 +#define BMP085_ADDR_COEFFS 0xAA + +/* register sizes */ +#define BMP085_NUM_COEFFS 22 + +/* commands, values */ +#define BMP085_CHIP_ID 0x55 + +#define BMP085_CMD_CONVERT_TEMP 0x2E + +#define BMP085_CMD_CONVERT_PRESS_0 0x34 +#define BMP085_CMD_CONVERT_PRESS_1 0x74 +#define BMP085_CMD_CONVERT_PRESS_2 0xB4 +#define BMP085_CMD_CONVERT_PRESS_3 0xF4 + +/* in us */ +#define BMP085_TIME_CNV_TEMP 4500 + +#define BMP085_TIME_CNV_PRESS_0 4500 +#define BMP085_TIME_CNV_PRESS_1 7500 +#define BMP085_TIME_CNV_PRESS_2 13500 +#define BMP085_TIME_CNV_PRESS_3 25500 + +/* ------------ Normalization ------------ */ +/* Mean sea level pressure normalization methods */ +#define MSLP_NONE 0 +#define MSLP_INTERNATIONAL 1 +#define MSLP_DEU_WETT 2 + +/** Temperature reference history depth for averaging. See + * #get_reference_temperature */ +#define REF_TEMP_AVG_NUM 5 + +/* ------------------------------------------ */ + +/** Supported sensor types */ +enum Sensor_type { + Sensor_none = 0, + Sensor_MPL115, + Sensor_MPL3115, + Sensor_BMP085 +}; + +static const char *config_keys[] = { + "Device", + "Oversampling", + "PressureOffset", /**< only for MPL3115 */ + "TemperatureOffset", /**< only for MPL3115 */ + "Altitude", + "Normalization", + "TemperatureSensor"}; + +static int config_keys_num = STATIC_ARRAY_SIZE(config_keys); + +static char *config_device; /**< I2C bus device */ +static int config_oversample = 1; /**< averaging window */ + +static double config_press_offset; /**< pressure offset */ +static double config_temp_offset; /**< temperature offset */ + +static double config_altitude = NAN; /**< altitude */ +static int config_normalize; /**< normalization method */ + +static bool configured; /**< the whole plugin config status */ + +static int i2c_bus_fd = -1; /**< I2C bus device FD */ + +static enum Sensor_type sensor_type = + Sensor_none; /**< detected/used sensor type */ + +static __s32 mpl3115_oversample; /**< MPL3115 CTRL1 oversample setting */ + +// BMP085 configuration +static unsigned bmp085_oversampling; /**< BMP085 oversampling (0-3) */ +static unsigned long + bmp085_timeCnvPress; /**< BMP085 conversion time for pressure in us */ +static __u8 bmp085_cmdCnvPress; /**< BMP085 pressure conversion command */ + +/* MPL115 conversion coefficients */ +static double mpl115_coeffA0; +static double mpl115_coeffB1; +static double mpl115_coeffB2; +static double mpl115_coeffC12; +static double mpl115_coeffC11; +static double mpl115_coeffC22; + +/* BMP085 conversion coefficients */ +static short bmp085_AC1; +static short bmp085_AC2; +static short bmp085_AC3; +static unsigned short bmp085_AC4; +static unsigned short bmp085_AC5; +static unsigned short bmp085_AC6; +static short bmp085_B1; +static short bmp085_B2; +static short bmp085_MB; +static short bmp085_MC; +static short bmp085_MD; + +/* ------------------------ averaging ring buffer ------------------------ */ +/* Used only for MPL115. MPL3115 supports real oversampling in the device so */ +/* no need for any postprocessing. */ + +static bool avg_initialized; /**< already initialized by real values */ + +typedef struct averaging_s { + long int *ring_buffer; + int ring_buffer_size; + long int ring_buffer_sum; + int ring_buffer_head; +} averaging_t; + +static averaging_t pressure_averaging; +static averaging_t temperature_averaging; + +/** + * Create / allocate averaging buffer + * + * The buffer is initialized with zeros. + * + * @param avg pointer to ring buffer to be allocated + * @param size requested buffer size + * + * @return Zero when successful + */ +static int averaging_create(averaging_t *avg, int size) { + avg->ring_buffer = calloc(size, sizeof(*avg->ring_buffer)); + if (avg->ring_buffer == NULL) { + ERROR("barometer: averaging_create - ring buffer allocation of size %d " + "failed", + size); + return -1; + } + + avg->ring_buffer_size = size; + avg->ring_buffer_sum = 0L; + avg->ring_buffer_head = 0; + + return 0; +} + +/** + * Delete / free existing averaging buffer + * + * @param avg pointer to the ring buffer to be deleted + */ +static void averaging_delete(averaging_t *avg) { + if (avg->ring_buffer != NULL) { + free(avg->ring_buffer); + avg->ring_buffer = NULL; + } + avg->ring_buffer_size = 0; + avg->ring_buffer_sum = 0L; + avg->ring_buffer_head = 0; +} + +/* + * Add new sample to the averaging buffer + * + * A new averaged value is returned. Note that till the buffer is full + * returned value is inaccurate as it is an average of real values and initial + * zeros. + * + * @param avg pointer to the ring buffer + * @param sample new sample value + * + * @return Averaged sample value + */ +static double averaging_add_sample(averaging_t *avg, long int sample) { + double result; + + avg->ring_buffer_sum += sample - avg->ring_buffer[avg->ring_buffer_head]; + avg->ring_buffer[avg->ring_buffer_head] = sample; + avg->ring_buffer_head = (avg->ring_buffer_head + 1) % avg->ring_buffer_size; + result = (double)(avg->ring_buffer_sum) / (double)(avg->ring_buffer_size); + + DEBUG("barometer: averaging_add_sample - added %ld, result = %lf", sample, + result); + + return result; +} + +/* ------------------------ temperature refference ------------------------ */ + +/** + * Linked list type of temperature sensor references + */ +typedef struct temperature_list_s { + char *sensor_name; /**< sensor name/reference */ + size_t num_values; /**< number of values (usually one) */ + bool initialized; /**< sensor already provides data */ + struct temperature_list_s *next; /**< next in the list */ +} temperature_list_t; + +static temperature_list_t *temp_list; + +/* + * Add new sensor to the temperature reference list + * + * @param list the list + * @param sensor reference name (as provided by the config file) + * + * @return Zero when successful + */ +static int temp_list_add(temperature_list_t *list, const char *sensor) { + temperature_list_t *new_temp; + + new_temp = malloc(sizeof(*new_temp)); + if (new_temp == NULL) + return -1; + + new_temp->sensor_name = strdup(sensor); + new_temp->initialized = 0; + new_temp->num_values = 0; + if (new_temp->sensor_name == NULL) { + free(new_temp); + return -1; + } + + new_temp->next = temp_list; + temp_list = new_temp; + return 0; +} + +/* + * Delete the whole temperature reference list + * + * @param list the list to be deleted + */ +static void temp_list_delete(temperature_list_t **list) { + temperature_list_t *tmp; + + while (*list != NULL) { + tmp = (*list); + (*list) = (*list)->next; + free(tmp->sensor_name); + free(tmp); + tmp = NULL; + } +} + +/* + * Get reference temperature value + * + * First initially uc_get_rate_by_name is tried. At the startup due to + * nondeterministic order the temperature may not be read yet (then it fails and + * first measurment gives only absolute air pressure reading which is + * acceptable). Once it succedes (should be second measurement at the latest) we + * use average of few last readings from uc_get_history_by_name. It may take few + * readings to start filling so again we use uc_get_rate_by_name as a fallback. + * The idea is to use basic "noise" filtering (history averaging) across all the + * values which given sensor provides (up to given depth). Then we get minimum + * among the sensors. + * + * @param result where the result is stored. When not available NAN is stored. + * + * @return Zero when successful + */ +static int get_reference_temperature(double *result) { + temperature_list_t *list = temp_list; + + gauge_t *values = NULL; /**< rate values */ + size_t values_num = 0; /**< number of rate values */ + + gauge_t values_history[REF_TEMP_AVG_NUM]; + + double avg_sum; /**< Value sum for computing average */ + int avg_num; /**< Number of values for computing average */ + double average; /**< Resulting value average */ + + *result = NAN; + + while (list != NULL) { + avg_sum = 0.0; + avg_num = 0; + + /* First time need to read current rate to learn how many values are + there (typically for temperature it would be just one). We do not expect + dynamic changing of number of temperarure values in runtime yet (are + there any such cases?). */ + if (!list->initialized) { + if (uc_get_rate_by_name(list->sensor_name, &values, &values_num)) { + DEBUG( + "barometer: get_reference_temperature - rate \"%s\" not found yet", + list->sensor_name); + list = list->next; + continue; + } + + DEBUG("barometer: get_reference_temperature - initialize \"%s\", %" PRIsz + " vals", + list->sensor_name, values_num); + + list->initialized = 1; + list->num_values = values_num; + + for (size_t i = 0; i < values_num; ++i) { + DEBUG("barometer: get_reference_temperature - rate %" PRIsz ": %lf **", + i, values[i]); + if (!isnan(values[i])) { + avg_sum += values[i]; + ++avg_num; + } + } + free(values); + values = NULL; + } + + /* It is OK to get here the first time as well, in the worst case + the history will full of NANs. */ + if (uc_get_history_by_name(list->sensor_name, values_history, + REF_TEMP_AVG_NUM, list->num_values)) { + ERROR("barometer: get_reference_temperature - history \"%s\" lost", + list->sensor_name); + list->initialized = 0; + list->num_values = 0; + list = list->next; + continue; + } + + for (size_t i = 0; i < REF_TEMP_AVG_NUM * list->num_values; ++i) { + DEBUG("barometer: get_reference_temperature - history %" PRIsz ": %lf", i, + values_history[i]); + if (!isnan(values_history[i])) { + avg_sum += values_history[i]; + ++avg_num; + } + } + + if (avg_num == 0) /* still no history? fallback to current */ + { + if (uc_get_rate_by_name(list->sensor_name, &values, &values_num)) { + ERROR("barometer: get_reference_temperature - rate \"%s\" lost", + list->sensor_name); + list->initialized = 0; + list->num_values = 0; + list = list->next; + continue; + } + + for (size_t i = 0; i < values_num; ++i) { + DEBUG("barometer: get_reference_temperature - rate last %" PRIsz + ": %lf **", + i, values[i]); + if (!isnan(values[i])) { + avg_sum += values[i]; + ++avg_num; + } + } + free(values); + values = NULL; + } + + if (avg_num == 0) { + ERROR("barometer: get_reference_temperature - could not read \"%s\"", + list->sensor_name); + list->initialized = 0; + list->num_values = 0; + } else { + average = avg_sum / (double)avg_num; + if (isnan(*result)) + *result = average; + else if (*result > average) + *result = average; + } + list = list->next; + } /* while sensor list */ + + if (*result == NAN) { + ERROR("barometer: get_reference_temperature - no sensor available (yet?)"); + return -1; + } + DEBUG("barometer: get_reference_temperature - temp is %lf", *result); + return 0; +} + +/* ------------------------ MPL115 access ------------------------ */ + +/** + * Detect presence of a MPL115 pressure sensor. + * + * Unfortunately there seems to be no ID register so we just try to read first + * conversion coefficient from device at MPL115 address and hope it is really + * MPL115. We should use this check as the last resort (which would be the + * typical + * case anyway since MPL115 is the least accurate sensor). + * As a sideeffect will leave set I2C slave address. + * + * @return 1 if MPL115, 0 otherwise + */ +static int MPL115_detect(void) { + __s32 res; + + if (ioctl(i2c_bus_fd, I2C_SLAVE_FORCE, MPL115_I2C_ADDRESS) < 0) { + ERROR("barometer: MPL115_detect problem setting i2c slave address to " + "0x%02X: %s", + MPL115_I2C_ADDRESS, STRERRNO); + return 0; + } + + res = i2c_smbus_read_byte_data(i2c_bus_fd, MPL115_ADDR_COEFFS); + if (res >= 0) { + DEBUG("barometer: MPL115_detect - positive detection"); + return 1; + } + + DEBUG("barometer: MPL115_detect - negative detection"); + return 0; +} + +/** + * Read the MPL115 sensor conversion coefficients. + * + * These are (device specific) constants so we can read them just once. + * + * @return Zero when successful + */ +static int MPL115_read_coeffs(void) { + uint8_t mpl115_coeffs[MPL115_NUM_COEFFS] = {0}; + int32_t res; + + int8_t sia0MSB, sia0LSB, sib1MSB, sib1LSB, sib2MSB, sib2LSB; + int8_t sic12MSB, sic12LSB, sic11MSB, sic11LSB, sic22MSB, sic22LSB; + int16_t sia0, sib1, sib2, sic12, sic11, sic22; + + res = i2c_smbus_read_i2c_block_data(i2c_bus_fd, MPL115_ADDR_COEFFS, + STATIC_ARRAY_SIZE(mpl115_coeffs), + mpl115_coeffs); + if (res < 0) { + ERROR("barometer: MPL115_read_coeffs - problem reading data: %s", STRERRNO); + return -1; + } + + /* Using perhaps less elegant/efficient code, but more readable. */ + /* a0: 16total 1sign 12int 4fract 0pad */ + sia0MSB = mpl115_coeffs[0]; + sia0LSB = mpl115_coeffs[1]; + sia0 = (int16_t)sia0MSB << 8; /* s16 type, Shift to MSB */ + sia0 += (int16_t)sia0LSB & 0x00FF; /* Add LSB to 16bit number */ + mpl115_coeffA0 = (double)(sia0); + mpl115_coeffA0 /= 8.0; /* 3 fract bits */ + + /* b1: 16total 1sign 2int 13fract 0pad */ + sib1MSB = mpl115_coeffs[2]; + sib1LSB = mpl115_coeffs[3]; + sib1 = sib1MSB << 8; /* Shift to MSB */ + sib1 += sib1LSB & 0x00FF; /* Add LSB to 16bit number */ + mpl115_coeffB1 = (double)(sib1); + mpl115_coeffB1 /= 8192.0; /* 13 fract */ + + /* b2: 16total 1sign 1int 14fract 0pad */ + sib2MSB = mpl115_coeffs[4]; + sib2LSB = mpl115_coeffs[5]; + sib2 = sib2MSB << 8; /* Shift to MSB */ + sib2 += sib2LSB & 0x00FF; /* Add LSB to 16bit number */ + mpl115_coeffB2 = (double)(sib2); + mpl115_coeffB2 /= 16384.0; /* 14 fract */ + + /* c12: 14total 1sign 0int 13fract 9pad */ + sic12MSB = mpl115_coeffs[6]; + sic12LSB = mpl115_coeffs[7]; + sic12 = sic12MSB << 8; /* Shift to MSB only by 8 for MSB */ + sic12 += sic12LSB & 0x00FF; + mpl115_coeffC12 = (double)(sic12); + mpl115_coeffC12 /= 4.0; /* 16-14=2 */ + mpl115_coeffC12 /= 4194304.0; /* 13+9=22 fract */ + + /* c11: 11total 1sign 0int 11fract 11pad */ + sic11MSB = mpl115_coeffs[8]; + sic11LSB = mpl115_coeffs[9]; + sic11 = sic11MSB << 8; /* Shift to MSB only by 8 for MSB */ + sic11 += sic11LSB & 0x00FF; + mpl115_coeffC11 = (double)(sic11); + mpl115_coeffC11 /= 32.0; /* 16-11=5 */ + mpl115_coeffC11 /= 4194304.0; /* 11+11=22 fract */ + + /* c12: 11total 1sign 0int 10fract 15pad */ + sic22MSB = mpl115_coeffs[10]; + sic22LSB = mpl115_coeffs[11]; + sic22 = sic22MSB << 8; /* Shift to MSB only by 8 for MSB */ + sic22 += sic22LSB & 0x00FF; + mpl115_coeffC22 = (double)(sic22); + mpl115_coeffC22 /= 32.0; // 16-11=5 + mpl115_coeffC22 /= 33554432.0; /* 10+15=25 fract */ + + DEBUG("barometer: MPL115_read_coeffs: a0=%lf, b1=%lf, b2=%lf, c12=%lf, " + "c11=%lf, c22=%lf", + mpl115_coeffA0, mpl115_coeffB1, mpl115_coeffB2, mpl115_coeffC12, + mpl115_coeffC11, mpl115_coeffC22); + return 0; +} + +/** + * Convert raw adc values to real data using the sensor coefficients. + * + * @param adc_pressure adc pressure value to be converted + * @param adc_temp adc temperature value to be converted + * @param pressure computed real pressure + * @param temperature computed real temperature + */ +static void MPL115_convert_adc_to_real(double adc_pressure, double adc_temp, + double *pressure, double *temperature) { + double Pcomp; + Pcomp = mpl115_coeffA0 + + (mpl115_coeffB1 + mpl115_coeffC11 * adc_pressure + + mpl115_coeffC12 * adc_temp) * + adc_pressure + + (mpl115_coeffB2 + mpl115_coeffC22 * adc_temp) * adc_temp; + + *pressure = ((1150.0 - 500.0) * Pcomp / 1023.0) + 500.0; + *temperature = (472.0 - adc_temp) / 5.35 + 25.0; + DEBUG("barometer: MPL115_convert_adc_to_real - got %lf hPa, %lf C", *pressure, + *temperature); +} + +/** + * Read sensor averegaed measurements + * + * @param pressure averaged measured pressure + * @param temperature averaged measured temperature + * + * @return Zero when successful + */ +static int MPL115_read_averaged(double *pressure, double *temperature) { + uint8_t mpl115_conv[MPL115_NUM_CONV] = {0}; + int8_t res; + int retries; + int conv_pressure; + int conv_temperature; + double adc_pressure; + double adc_temperature; + + *pressure = 0.0; + *temperature = 0.0; + + /* start conversion of both temp and presure */ + retries = MPL115_CONVERSION_RETRIES; + while (retries > 0) { + /* write 1 to start conversion */ + res = i2c_smbus_write_byte_data(i2c_bus_fd, MPL115_CMD_CONVERT_BOTH, 0x01); + if (res >= 0) + break; + + --retries; + if (retries > 0) { + ERROR("barometer: MPL115_read_averaged - requesting conversion: %s, " + "will retry at most %d more times", + STRERRNO, retries); + } else { + ERROR("barometer: MPL115_read_averaged - requesting conversion: %s, " + "too many failed retries", + STRERRNO); + return -1; + } + } + + usleep(10000); /* wait 10ms for the conversion */ + + retries = MPL115_CONVERSION_RETRIES; + while (retries > 0) { + res = i2c_smbus_read_i2c_block_data(i2c_bus_fd, MPL115_ADDR_CONV, + STATIC_ARRAY_SIZE(mpl115_conv), + mpl115_conv); + if (res >= 0) + break; + + --retries; + if (retries > 0) { + ERROR("barometer: MPL115_read_averaged - reading conversion: %s, " + "will retry at most %d more times", + STRERRNO, retries); + } else { + ERROR("barometer: MPL115_read_averaged - reading conversion: %s, " + "too many failed retries", + STRERRNO); + return -1; + } + } + + conv_pressure = ((mpl115_conv[0] << 8) | mpl115_conv[1]) >> 6; + conv_temperature = ((mpl115_conv[2] << 8) | mpl115_conv[3]) >> 6; + DEBUG("barometer: MPL115_read_averaged, raw pressure ADC value = %d, " + "raw temperature ADC value = %d", + conv_pressure, conv_temperature); + + adc_pressure = averaging_add_sample(&pressure_averaging, conv_pressure); + adc_temperature = + averaging_add_sample(&temperature_averaging, conv_temperature); + + MPL115_convert_adc_to_real(adc_pressure, adc_temperature, pressure, + temperature); + + DEBUG("barometer: MPL115_read_averaged - averaged ADC pressure = %lf / " + "temperature = %lf, " + "real pressure = %lf hPa / temperature = %lf C", + adc_pressure, adc_temperature, *pressure, *temperature); + + return 0; +} + +/* ------------------------ MPL3115 access ------------------------ */ + +/** + * Detect presence of a MPL3115 pressure sensor by checking register "WHO AM I" + * + * As a sideeffect will leave set I2C slave address. + * + * @return 1 if MPL3115, 0 otherwise + */ +static int MPL3115_detect(void) { + __s32 res; + + if (ioctl(i2c_bus_fd, I2C_SLAVE_FORCE, MPL3115_I2C_ADDRESS) < 0) { + ERROR("barometer: MPL3115_detect problem setting i2c slave address to " + "0x%02X: %s", + MPL3115_I2C_ADDRESS, STRERRNO); + return 0; + } + + res = i2c_smbus_read_byte_data(i2c_bus_fd, MPL3115_REG_WHO_AM_I); + if (res == MPL3115_WHO_AM_I_RESP) { + DEBUG("barometer: MPL3115_detect - positive detection"); + return 1; + } + + DEBUG("barometer: MPL3115_detect - negative detection"); + return 0; +} + +/** + * Adjusts oversampling to values supported by MPL3115 + * + * MPL3115 supports only power of 2 in the range 1 to 128. + */ +static void MPL3115_adjust_oversampling(void) { + int new_val = 0; + + if (config_oversample > 100) { + new_val = 128; + mpl3115_oversample = MPL3115_CTRL_REG1_OST_128; + } else if (config_oversample > 48) { + new_val = 64; + mpl3115_oversample = MPL3115_CTRL_REG1_OST_64; + } else if (config_oversample > 24) { + new_val = 32; + mpl3115_oversample = MPL3115_CTRL_REG1_OST_32; + } else if (config_oversample > 12) { + new_val = 16; + mpl3115_oversample = MPL3115_CTRL_REG1_OST_16; + } else if (config_oversample > 6) { + new_val = 8; + mpl3115_oversample = MPL3115_CTRL_REG1_OST_8; + } else if (config_oversample > 3) { + new_val = 4; + mpl3115_oversample = MPL3115_CTRL_REG1_OST_4; + } else if (config_oversample > 1) { + new_val = 2; + mpl3115_oversample = MPL3115_CTRL_REG1_OST_2; + } else { + new_val = 1; + mpl3115_oversample = MPL3115_CTRL_REG1_OST_1; + } + + DEBUG("barometer: MPL3115_adjust_oversampling - correcting oversampling from " + "%d to %d", + config_oversample, new_val); + config_oversample = new_val; +} + +/** + * Read sensor averaged measurements + * + * @param pressure averaged measured pressure + * @param temperature averaged measured temperature + * + * @return Zero when successful + */ +static int MPL3115_read(double *pressure, double *temperature) { + __s32 res; + __s32 ctrl; + __u8 data[MPL3115_NUM_CONV_VALS]; + long int tmp_value = 0; + + /* Set Active - activate the device from standby */ + res = i2c_smbus_read_byte_data(i2c_bus_fd, MPL3115_REG_CTRL_REG1); + if (res < 0) { + ERROR("barometer: MPL3115_read - cannot read CTRL_REG1: %s", STRERRNO); + return 1; + } + ctrl = res; + res = i2c_smbus_write_byte_data(i2c_bus_fd, MPL3115_REG_CTRL_REG1, + ctrl | MPL3115_CTRL_REG1_SBYB); + if (res < 0) { + ERROR("barometer: MPL3115_read - problem activating: %s", STRERRNO); + return 1; + } + + /* base sleep is 5ms x OST */ + usleep(5000 * config_oversample); + + /* check the flags/status if ready */ + res = i2c_smbus_read_byte_data(i2c_bus_fd, MPL3115_REG_STATUS); + if (res < 0) { + ERROR("barometer: MPL3115_read - cannot read status register: %s", + STRERRNO); + return 1; + } + + while ((res & MPL3115_DR_STATUS_DR) != MPL3115_DR_STATUS_DR) { + /* try some extra sleep... */ + usleep(10000); + + /* ... and repeat the check. The conversion has to finish sooner or later. + */ + res = i2c_smbus_read_byte_data(i2c_bus_fd, MPL3115_REG_STATUS); + if (res < 0) { + ERROR("barometer: MPL3115_read - cannot read status register: %s", + STRERRNO); + return 1; + } + } + + /* Now read all the data in one block. There is address autoincrement. */ + res = i2c_smbus_read_i2c_block_data(i2c_bus_fd, MPL3115_REG_OUT_P_MSB, + MPL3115_NUM_CONV_VALS, data); + if (res < 0) { + ERROR("barometer: MPL3115_read - cannot read data registers: %s", STRERRNO); + return 1; + } + + tmp_value = (data[0] << 16) | (data[1] << 8) | data[2]; + *pressure = ((double)tmp_value) / 4.0 / 16.0 / 100.0; + DEBUG("barometer: MPL3115_read - absolute pressure = %lf hPa", *pressure); + + if (data[3] > 0x7F) { + data[3] = ~data[3] + 1; + *temperature = data[3]; + *temperature = -*temperature; + } else { + *temperature = data[3]; + } + + *temperature += (double)(data[4]) / 256.0; + DEBUG("barometer: MPL3115_read - temperature = %lf C", *temperature); + + return 0; +} + +/** + * Initialize MPL3115 for barometeric measurements + * + * @return 0 if successful + */ +static int MPL3115_init_sensor(void) { + __s32 res; + __s8 offset; + + /* Reset the sensor. It will reset immediately without ACKing */ + /* the transaction, so no error handling here. */ + i2c_smbus_write_byte_data(i2c_bus_fd, MPL3115_REG_CTRL_REG1, + MPL3115_CTRL_REG1_RST); + + /* wait some time for the reset to finish */ + usleep(100000); + + /* now it should be in standby already so we can go and configure it */ + + /* Set temperature offset. */ + /* result = ADCtemp + offset [C] */ + offset = (__s8)(config_temp_offset * 16.0); + res = i2c_smbus_write_byte_data(i2c_bus_fd, MPL3115_REG_OFF_T, offset); + if (res < 0) { + ERROR("barometer: MPL3115_init_sensor - problem setting temp offset: %s", + STRERRNO); + return -1; + } + + /* Set pressure offset. */ + /* result = ADCpress + offset [hPa] */ + offset = (__s8)(config_press_offset * 100.0 / 4.0); + res = i2c_smbus_write_byte_data(i2c_bus_fd, MPL3115_REG_OFF_P, offset); + if (res < 0) { + ERROR( + "barometer: MPL3115_init_sensor - problem setting pressure offset: %s", + STRERRNO); + return -1; + } + + /* Enable Data Flags in PT_DATA_CFG - flags on both pressure and temp */ + res = i2c_smbus_write_byte_data(i2c_bus_fd, MPL3115_REG_PT_DATA_CFG, + MPL3115_PT_DATA_DREM | MPL3115_PT_DATA_PDEF | + MPL3115_PT_DATA_TDEF); + if (res < 0) { + ERROR("barometer: MPL3115_init_sensor - problem setting PT_DATA_CFG: %s", + STRERRNO); + return -1; + } + + /* Set to barometer with an OSR */ + res = i2c_smbus_write_byte_data(i2c_bus_fd, MPL3115_REG_CTRL_REG1, + mpl3115_oversample); + if (res < 0) { + ERROR("barometer: MPL3115_init_sensor - problem configuring CTRL_REG1: %s", + STRERRNO); + return -1; + } + + return 0; +} + +/* ------------------------ BMP085 access ------------------------ */ + +/** + * Detect presence of a BMP085 pressure sensor by checking its ID register + * + * As a sideeffect will leave set I2C slave address. + * + * @return 1 if BMP085, 0 otherwise + */ +static int BMP085_detect(void) { + __s32 res; + + if (ioctl(i2c_bus_fd, I2C_SLAVE_FORCE, BMP085_I2C_ADDRESS) < 0) { + ERROR("barometer: BMP085_detect - problem setting i2c slave address to " + "0x%02X: %s", + BMP085_I2C_ADDRESS, STRERRNO); + return 0; + } + + res = i2c_smbus_read_byte_data(i2c_bus_fd, BMP085_ADDR_ID_REG); + if (res == BMP085_CHIP_ID) { + DEBUG("barometer: BMP085_detect - positive detection"); + + /* get version */ + res = i2c_smbus_read_byte_data(i2c_bus_fd, BMP085_ADDR_VERSION); + if (res < 0) { + ERROR("barometer: BMP085_detect - problem checking chip version: %s", + STRERRNO); + return 0; + } + DEBUG("barometer: BMP085_detect - chip version ML:0x%02X AL:0x%02X", + res & 0x0f, (res & 0xf0) >> 4); + return 1; + } + + DEBUG("barometer: BMP085_detect - negative detection"); + return 0; +} + +/** + * Adjusts oversampling settings to values supported by BMP085 + * + * BMP085 supports only 1,2,4 or 8 samples. + */ +static void BMP085_adjust_oversampling(void) { + int new_val = 0; + + if (config_oversample > 6) /* 8 */ + { + new_val = 8; + bmp085_oversampling = 3; + bmp085_cmdCnvPress = BMP085_CMD_CONVERT_PRESS_3; + bmp085_timeCnvPress = BMP085_TIME_CNV_PRESS_3; + } else if (config_oversample > 3) /* 4 */ + { + new_val = 4; + bmp085_oversampling = 2; + bmp085_cmdCnvPress = BMP085_CMD_CONVERT_PRESS_2; + bmp085_timeCnvPress = BMP085_TIME_CNV_PRESS_2; + } else if (config_oversample > 1) /* 2 */ + { + new_val = 2; + bmp085_oversampling = 1; + bmp085_cmdCnvPress = BMP085_CMD_CONVERT_PRESS_1; + bmp085_timeCnvPress = BMP085_TIME_CNV_PRESS_1; + } else /* 1 */ + { + new_val = 1; + bmp085_oversampling = 0; + bmp085_cmdCnvPress = BMP085_CMD_CONVERT_PRESS_0; + bmp085_timeCnvPress = BMP085_TIME_CNV_PRESS_0; + } + + DEBUG("barometer: BMP085_adjust_oversampling - correcting oversampling from " + "%d to %d", + config_oversample, new_val); + config_oversample = new_val; +} + +/** + * Read the BMP085 sensor conversion coefficients. + * + * These are (device specific) constants so we can read them just once. + * + * @return Zero when successful + */ +static int BMP085_read_coeffs(void) { + __s32 res; + __u8 coeffs[BMP085_NUM_COEFFS]; + + res = i2c_smbus_read_i2c_block_data(i2c_bus_fd, BMP085_ADDR_COEFFS, + BMP085_NUM_COEFFS, coeffs); + if (res < 0) { + ERROR("barometer: BMP085_read_coeffs - problem reading data: %s", STRERRNO); + return -1; + } + + bmp085_AC1 = ((int16_t)coeffs[0] << 8) | (int16_t)coeffs[1]; + bmp085_AC2 = ((int16_t)coeffs[2] << 8) | (int16_t)coeffs[3]; + bmp085_AC3 = ((int16_t)coeffs[4] << 8) | (int16_t)coeffs[5]; + bmp085_AC4 = ((uint16_t)coeffs[6] << 8) | (uint16_t)coeffs[7]; + bmp085_AC5 = ((uint16_t)coeffs[8] << 8) | (uint16_t)coeffs[9]; + bmp085_AC6 = ((uint16_t)coeffs[10] << 8) | (uint16_t)coeffs[11]; + bmp085_B1 = ((int16_t)coeffs[12] << 8) | (int16_t)coeffs[13]; + bmp085_B2 = ((int16_t)coeffs[14] << 8) | (int16_t)coeffs[15]; + bmp085_MB = ((int16_t)coeffs[16] << 8) | (int16_t)coeffs[17]; + bmp085_MC = ((int16_t)coeffs[18] << 8) | (int16_t)coeffs[19]; + bmp085_MD = ((int16_t)coeffs[20] << 8) | (int16_t)coeffs[21]; + + DEBUG("barometer: BMP085_read_coeffs - AC1=%d, AC2=%d, AC3=%d, AC4=%u," + " AC5=%u, AC6=%u, B1=%d, B2=%d, MB=%d, MC=%d, MD=%d", + bmp085_AC1, bmp085_AC2, bmp085_AC3, bmp085_AC4, bmp085_AC5, bmp085_AC6, + bmp085_B1, bmp085_B2, bmp085_MB, bmp085_MC, bmp085_MD); + + return 0; +} + +/** + * Convert raw BMP085 adc values to real data using the sensor coefficients. + * + * @param adc_pressure adc pressure value to be converted + * @param adc_temp adc temperature value to be converted + * @param pressure computed real pressure + * @param temperature computed real temperature + */ +static void BMP085_convert_adc_to_real(long adc_pressure, long adc_temperature, + double *pressure, double *temperature) + +{ + long X1, X2, X3; + long B3, B5, B6; + unsigned long B4, B7; + + long T; + long P; + + /* calculate real temperature */ + X1 = ((adc_temperature - bmp085_AC6) * bmp085_AC5) >> 15; + X2 = (bmp085_MC << 11) / (X1 + bmp085_MD); + + /* B5, T */ + B5 = X1 + X2; + T = (B5 + 8) >> 4; + *temperature = (double)T * 0.1; + + /* calculate real pressure */ + /* in general X1, X2, X3 are recycled while values of B3, B4, B5, B6 are kept + */ + + /* B6, B3 */ + B6 = B5 - 4000; + X1 = ((bmp085_B2 * ((B6 * B6) >> 12)) >> 11); + X2 = (((long)bmp085_AC2 * B6) >> 11); + X3 = X1 + X2; + B3 = (((((long)bmp085_AC1 * 4) + X3) << bmp085_oversampling) + 2) >> 2; + + /* B4 */ + X1 = (((long)bmp085_AC3 * B6) >> 13); + X2 = (bmp085_B1 * ((B6 * B6) >> 12)) >> 16; + X3 = ((X1 + X2) + 2) >> 2; + B4 = ((long)bmp085_AC4 * (unsigned long)(X3 + 32768)) >> 15; + + /* B7, P */ + B7 = (unsigned long)(adc_pressure - B3) * (50000 >> bmp085_oversampling); + if (B7 < 0x80000000) { + P = (B7 << 1) / B4; + } else { + P = (B7 / B4) << 1; + } + X1 = (P >> 8) * (P >> 8); + X1 = (X1 * 3038) >> 16; + X2 = ((-7357) * P) >> 16; + P = P + ((X1 + X2 + 3791) >> 4); + + *pressure = P / 100.0; // in [hPa] + DEBUG("barometer: BMP085_convert_adc_to_real - got %lf hPa, %lf C", *pressure, + *temperature); +} + +/** + * Read compensated sensor measurements + * + * @param pressure averaged measured pressure + * @param temperature averaged measured temperature + * + * @return Zero when successful + */ +static int BMP085_read(double *pressure, double *temperature) { + __s32 res; + __u8 measBuff[3]; + + long adc_pressure; + long adc_temperature; + + /* start conversion of temperature */ + res = i2c_smbus_write_byte_data(i2c_bus_fd, BMP085_ADDR_CTRL_REG, + BMP085_CMD_CONVERT_TEMP); + if (res < 0) { + ERROR("barometer: BMP085_read - problem requesting temperature conversion: " + "%s", + STRERRNO); + return 1; + } + + usleep(BMP085_TIME_CNV_TEMP); /* wait for the conversion */ + + res = + i2c_smbus_read_i2c_block_data(i2c_bus_fd, BMP085_ADDR_CONV, 2, measBuff); + if (res < 0) { + ERROR("barometer: BMP085_read - problem reading temperature data: %s", + STRERRNO); + return 1; + } + + adc_temperature = ((unsigned short)measBuff[0] << 8) + measBuff[1]; + + /* get presure */ + res = i2c_smbus_write_byte_data(i2c_bus_fd, BMP085_ADDR_CTRL_REG, + bmp085_cmdCnvPress); + if (res < 0) { + ERROR("barometer: BMP085_read - problem requesting pressure conversion: %s", + STRERRNO); + return 1; + } + + usleep(bmp085_timeCnvPress); /* wait for the conversion */ + + res = + i2c_smbus_read_i2c_block_data(i2c_bus_fd, BMP085_ADDR_CONV, 3, measBuff); + if (res < 0) { + ERROR("barometer: BMP085_read - problem reading pressure data: %s", + STRERRNO); + return 1; + } + + adc_pressure = (long)((((ulong)measBuff[0] << 16) | + ((ulong)measBuff[1] << 8) | (ulong)measBuff[2]) >> + (8 - bmp085_oversampling)); + + DEBUG("barometer: BMP085_read - raw pressure ADC value = %ld, " + "raw temperature ADC value = %ld", + adc_pressure, adc_temperature); + + BMP085_convert_adc_to_real(adc_pressure, adc_temperature, pressure, + temperature); + + return 0; +} + +/* ------------------------ Sensor detection ------------------------ */ +/** + * Detect presence of a supported sensor. + * + * As a sideeffect will leave set I2C slave address. + * The detection is done in the order BMP085, MPL3115, MPL115 and stops after + * first sensor beeing found. + * + * @return detected sensor type + */ +static enum Sensor_type detect_sensor_type(void) { + if (BMP085_detect()) + return Sensor_BMP085; + + else if (MPL3115_detect()) + return Sensor_MPL3115; + + else if (MPL115_detect()) + return Sensor_MPL115; + + return Sensor_none; +} + +/* ------------------------ Common functionality ------------------------ */ + +/** + * Convert absolute pressure (in hPa) to mean sea level pressure + * + * Implemented methods are: + * - MSLP_NONE - no converions, returns absolute pressure + * + * - MSLP_INTERNATIONAL - see + * http://en.wikipedia.org/wiki/Atmospheric_pressure#Altitude_atmospheric_pressure_variation + * Requires #config_altitude + * + * - MSLP_DEU_WETT - formula as recommended by the Deutsche Wetterdienst. See + * http://de.wikipedia.org/wiki/Barometrische_H%C3%B6henformel#Theorie + * Requires both #config_altitude and temperature reference(s). + * + * @param abs_pressure absloute pressure to be converted + * + * @return mean sea level pressure if successful, NAN otherwise + */ +static double abs_to_mean_sea_level_pressure(double abs_pressure) { + double mean = -1.0; + double temp = 0.0; + int result = 0; + + if (config_normalize >= MSLP_DEU_WETT) { + result = get_reference_temperature(&temp); + if (result) { + return NAN; + } + } + + switch (config_normalize) { + case MSLP_NONE: + mean = abs_pressure; + break; + + case MSLP_INTERNATIONAL: + mean = abs_pressure / pow(1.0 - 0.0065 * config_altitude / 288.15, + 9.80665 * 0.0289644 / (8.31447 * 0.0065)); + break; + + case MSLP_DEU_WETT: { + double E; /* humidity */ + double x; + if (temp < 9.1) + E = 5.6402 * (-0.0916 + exp(0.06 * temp)); + else + E = 18.2194 * (1.0463 - exp(-0.0666 * temp)); + x = 9.80665 / + (287.05 * (temp + 273.15 + 0.12 * E + 0.0065 * config_altitude / 2)) * + config_altitude; + mean = abs_pressure * exp(x); + } break; + + default: + ERROR( + "barometer: abs_to_mean_sea_level_pressure: wrong conversion method %d", + config_normalize); + mean = abs_pressure; + break; + } + + DEBUG("barometer: abs_to_mean_sea_level_pressure: absPressure = %lf hPa, " + "method = %d, meanPressure = %lf hPa", + abs_pressure, config_normalize, mean); + + return mean; +} + +/* ------------------------ main plugin callbacks ------------------------ */ + +/** + * Main plugin configuration callback (using simple config) + * + * @param key configuration key we should process + * @param value configuration value we should process + * + * @return Zero when successful. + */ +static int collectd_barometer_config(const char *key, const char *value) { + DEBUG("barometer: collectd_barometer_config"); + + if (strcasecmp(key, "Device") == 0) { + sfree(config_device); + config_device = strdup(value); + } else if (strcasecmp(key, "Oversampling") == 0) { + int oversampling_tmp = atoi(value); + if (oversampling_tmp < 1 || oversampling_tmp > 1024) { + WARNING("barometer: collectd_barometer_config: invalid oversampling: %d." + " Allowed values are 1 to 1024 (for MPL115) or 1 to 128 (for " + "MPL3115) or 1 to 8 (for BMP085).", + oversampling_tmp); + return 1; + } + config_oversample = oversampling_tmp; + } else if (strcasecmp(key, "Altitude") == 0) { + config_altitude = atof(value); + } else if (strcasecmp(key, "Normalization") == 0) { + int normalize_tmp = atoi(value); + if (normalize_tmp < 0 || normalize_tmp > 2) { + ERROR("barometer: collectd_barometer_config: invalid normalization: %d", + normalize_tmp); + return 1; + } + config_normalize = normalize_tmp; + } else if (strcasecmp(key, "TemperatureSensor") == 0) { + if (temp_list_add(temp_list, value)) { + return -1; + } + } else if (strcasecmp(key, "PressureOffset") == 0) { + config_press_offset = atof(value); + } else if (strcasecmp(key, "TemperatureOffset") == 0) { + config_temp_offset = atof(value); + } else { + return -1; + } + + return 0; +} + +/** + * Shutdown callback. + * + * Close I2C and delete all the buffers. + * + * @return Zero when successful (at the moment the only possible outcome) + */ +static int collectd_barometer_shutdown(void) { + DEBUG("barometer: collectd_barometer_shutdown"); + + if (sensor_type == Sensor_MPL115) { + averaging_delete(&pressure_averaging); + averaging_delete(&temperature_averaging); + + temp_list_delete(&temp_list); + } + + if (i2c_bus_fd > 0) { + close(i2c_bus_fd); + i2c_bus_fd = -1; + sfree(config_device); + } + + return 0; +} + +/** + * Plugin read callback for MPL115. + * + * Dispatching will create values: + * - /barometer-mpl115/pressure-normalized + * - /barometer-mpl115/pressure-absolute + * - /barometer-mpl115/temperature + * + * @return Zero when successful. + */ +static int MPL115_collectd_barometer_read(void) { + int result = 0; + + double pressure = 0.0; + double temperature = 0.0; + double norm_pressure = 0.0; + + value_list_t vl = VALUE_LIST_INIT; + value_t values[1]; + + DEBUG("barometer: MPL115_collectd_barometer_read"); + + if (!configured) { + return -1; + } + + /* Rather than delaying init, we will intitialize during first read. This + way at least we have a better chance to have the reference temperature + already available. */ + if (!avg_initialized) { + for (int i = 0; i < config_oversample - 1; ++i) { + result = MPL115_read_averaged(&pressure, &temperature); + if (result) { + ERROR("barometer: MPL115_collectd_barometer_read - mpl115 read, " + "ignored during init"); + } + DEBUG("barometer: MPL115_collectd_barometer_read - init %d / %d", i + 1, + config_oversample - 1); + usleep(20000); + } + avg_initialized = true; + } + + result = MPL115_read_averaged(&pressure, &temperature); + if (result) + return result; + + norm_pressure = abs_to_mean_sea_level_pressure(pressure); + + sstrncpy(vl.plugin, "barometer", sizeof(vl.plugin)); + sstrncpy(vl.plugin_instance, "mpl115", sizeof(vl.plugin_instance)); + + vl.values_len = 1; + vl.values = values; + + /* dispatch normalized air pressure */ + sstrncpy(vl.type, "pressure", sizeof(vl.type)); + sstrncpy(vl.type_instance, "normalized", sizeof(vl.type_instance)); + values[0].gauge = norm_pressure; + plugin_dispatch_values(&vl); + + /* dispatch absolute air pressure */ + sstrncpy(vl.type, "pressure", sizeof(vl.type)); + sstrncpy(vl.type_instance, "absolute", sizeof(vl.type_instance)); + values[0].gauge = pressure; + plugin_dispatch_values(&vl); + + /* dispatch sensor temperature */ + sstrncpy(vl.type, "temperature", sizeof(vl.type)); + sstrncpy(vl.type_instance, "", sizeof(vl.type_instance)); + values[0].gauge = temperature; + plugin_dispatch_values(&vl); + + return 0; +} + +/** + * Plugin read callback for MPL3115. + * + * Dispatching will create values: + * - /barometer-mpl3115/pressure-normalized + * - /barometer-mpl3115/pressure-absolute + * - /barometer-mpl3115/temperature + * + * @return Zero when successful. + */ +static int MPL3115_collectd_barometer_read(void) { + int result = 0; + + double pressure = 0.0; + double temperature = 0.0; + double norm_pressure = 0.0; + + value_list_t vl = VALUE_LIST_INIT; + value_t values[1]; + + DEBUG("barometer: MPL3115_collectd_barometer_read"); + + if (!configured) { + return -1; + } + + result = MPL3115_read(&pressure, &temperature); + if (result) + return result; + + norm_pressure = abs_to_mean_sea_level_pressure(pressure); + + sstrncpy(vl.plugin, "barometer", sizeof(vl.plugin)); + sstrncpy(vl.plugin_instance, "mpl3115", sizeof(vl.plugin_instance)); + + vl.values_len = 1; + vl.values = values; + + /* dispatch normalized air pressure */ + sstrncpy(vl.type, "pressure", sizeof(vl.type)); + sstrncpy(vl.type_instance, "normalized", sizeof(vl.type_instance)); + values[0].gauge = norm_pressure; + plugin_dispatch_values(&vl); + + /* dispatch absolute air pressure */ + sstrncpy(vl.type, "pressure", sizeof(vl.type)); + sstrncpy(vl.type_instance, "absolute", sizeof(vl.type_instance)); + values[0].gauge = pressure; + plugin_dispatch_values(&vl); + + /* dispatch sensor temperature */ + sstrncpy(vl.type, "temperature", sizeof(vl.type)); + sstrncpy(vl.type_instance, "", sizeof(vl.type_instance)); + values[0].gauge = temperature; + plugin_dispatch_values(&vl); + + return 0; +} + +/** + * Plugin read callback for BMP085. + * + * Dispatching will create values: + * - /barometer-bmp085/pressure-normalized + * - /barometer-bmp085/pressure-absolute + * - /barometer-bmp085/temperature + * + * @return Zero when successful. + */ +static int BMP085_collectd_barometer_read(void) { + int result = 0; + + double pressure = 0.0; + double temperature = 0.0; + double norm_pressure = 0.0; + + value_list_t vl = VALUE_LIST_INIT; + value_t values[1]; + + DEBUG("barometer: BMP085_collectd_barometer_read"); + + if (!configured) { + return -1; + } + + result = BMP085_read(&pressure, &temperature); + if (result) + return result; + + norm_pressure = abs_to_mean_sea_level_pressure(pressure); + + sstrncpy(vl.plugin, "barometer", sizeof(vl.plugin)); + sstrncpy(vl.plugin_instance, "bmp085", sizeof(vl.plugin_instance)); + + vl.values_len = 1; + vl.values = values; + + /* dispatch normalized air pressure */ + sstrncpy(vl.type, "pressure", sizeof(vl.type)); + sstrncpy(vl.type_instance, "normalized", sizeof(vl.type_instance)); + values[0].gauge = norm_pressure; + plugin_dispatch_values(&vl); + + /* dispatch absolute air pressure */ + sstrncpy(vl.type, "pressure", sizeof(vl.type)); + sstrncpy(vl.type_instance, "absolute", sizeof(vl.type_instance)); + values[0].gauge = pressure; + plugin_dispatch_values(&vl); + + /* dispatch sensor temperature */ + sstrncpy(vl.type, "temperature", sizeof(vl.type)); + sstrncpy(vl.type_instance, "", sizeof(vl.type_instance)); + values[0].gauge = temperature; + plugin_dispatch_values(&vl); + + return 0; +} + +/** + * Initialization callback + * + * Check config, initialize I2C bus access, conversion coefficients and + * averaging + * ring buffers + * + * @return Zero when successful. + */ +static int collectd_barometer_init(void) { + + DEBUG("barometer: collectd_barometer_init"); + + if (config_device == NULL) { + ERROR("barometer: collectd_barometer_init I2C bus device not configured"); + return -1; + } + + if (config_normalize >= MSLP_INTERNATIONAL && isnan(config_altitude)) { + ERROR("barometer: collectd_barometer_init no altitude configured " + "for mean sea level pressure normalization."); + return -1; + } + + if (config_normalize == MSLP_DEU_WETT && temp_list == NULL) { + ERROR("barometer: collectd_barometer_init no temperature reference " + "configured for mean sea level pressure normalization."); + return -1; + } + + i2c_bus_fd = open(config_device, O_RDWR); + if (i2c_bus_fd < 0) { + ERROR("barometer: collectd_barometer_init problem opening I2C bus device " + "\"%s\": %s (is loaded mod i2c-dev?)", + config_device, STRERRNO); + return -1; + } + + /* detect sensor type - this will also set slave address */ + sensor_type = detect_sensor_type(); + + /* init correct sensor type */ + switch (sensor_type) { + /* MPL3115 */ + case Sensor_MPL3115: { + MPL3115_adjust_oversampling(); + + if (MPL3115_init_sensor()) + return -1; + + plugin_register_read("barometer", MPL3115_collectd_barometer_read); + } break; + + /* MPL115 */ + case Sensor_MPL115: { + if (averaging_create(&pressure_averaging, config_oversample)) { + ERROR( + "barometer: collectd_barometer_init pressure averaging init failed"); + return -1; + } + + if (averaging_create(&temperature_averaging, config_oversample)) { + ERROR("barometer: collectd_barometer_init temperature averaging init " + "failed"); + return -1; + } + + if (MPL115_read_coeffs() < 0) + return -1; + + plugin_register_read("barometer", MPL115_collectd_barometer_read); + } break; + + /* BMP085 */ + case Sensor_BMP085: { + BMP085_adjust_oversampling(); + + if (BMP085_read_coeffs() < 0) + return -1; + + plugin_register_read("barometer", BMP085_collectd_barometer_read); + } break; + + /* anything else -> error */ + default: + ERROR("barometer: collectd_barometer_init - no supported sensor found"); + return -1; + } + + configured = true; + return 0; +} + +/* ------------------------ plugin register / entry point + * ------------------------ */ + +/** + * Plugin "entry" - register all callback. + * + */ +void module_register(void) { + plugin_register_config("barometer", collectd_barometer_config, config_keys, + config_keys_num); + plugin_register_init("barometer", collectd_barometer_init); + plugin_register_shutdown("barometer", collectd_barometer_shutdown); +} diff --git a/src/battery.c b/src/battery.c index 4178d8b514..578f248fc1 100644 --- a/src/battery.c +++ b/src/battery.c @@ -1,7 +1,8 @@ /** * collectd - src/battery.c - * Copyright (C) 2006,2007 Florian octo Forster + * Copyright (C) 2006-2014 Florian octo Forster * Copyright (C) 2008 Michał Mirosław + * Copyright (C) 2014 Andy Parkins * * 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 @@ -17,521 +18,759 @@ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * * Authors: - * Florian octo Forster + * Florian octo Forster * Michał Mirosław + * Andy Parkins **/ #include "collectd.h" -#include "common.h" -#include "plugin.h" -#include "utils_complain.h" +#include "plugin.h" +#include "utils/common/common.h" #if HAVE_MACH_MACH_TYPES_H -# include +#include #endif #if HAVE_MACH_MACH_INIT_H -# include +#include #endif #if HAVE_MACH_MACH_ERROR_H -# include +#include #endif #if HAVE_COREFOUNDATION_COREFOUNDATION_H -# include +#include #endif #if HAVE_IOKIT_IOKITLIB_H -# include +#include #endif #if HAVE_IOKIT_IOTYPES_H -# include +#include #endif #if HAVE_IOKIT_PS_IOPOWERSOURCES_H -# include +#include #endif #if HAVE_IOKIT_PS_IOPSKEYS_H -# include +#include #endif #if !HAVE_IOKIT_IOKITLIB_H && !HAVE_IOKIT_PS_IOPOWERSOURCES_H && !KERNEL_LINUX -# error "No applicable input method." +#error "No applicable input method." #endif -#define INVALID_VALUE 47841.29 - #if HAVE_IOKIT_IOKITLIB_H || HAVE_IOKIT_PS_IOPOWERSOURCES_H - /* No global variables */ +/* No global variables */ /* #endif HAVE_IOKIT_IOKITLIB_H || HAVE_IOKIT_PS_IOPOWERSOURCES_H */ #elif KERNEL_LINUX -static int battery_pmu_num = 0; -static char *battery_pmu_file = "/proc/pmu/battery_%i"; -static const char *battery_acpi_dir = "/proc/acpi/battery"; +#define PROC_PMU_PATH_FORMAT "/proc/pmu/battery_%i" +#define PROC_ACPI_PATH "/proc/acpi/battery" +#define PROC_ACPI_FACTOR 0.001 +#define SYSFS_PATH "/sys/class/power_supply" +#define SYSFS_FACTOR 0.000001 #endif /* KERNEL_LINUX */ -static int battery_init (void) -{ -#if HAVE_IOKIT_IOKITLIB_H || HAVE_IOKIT_PS_IOPOWERSOURCES_H - /* No init neccessary */ -/* #endif HAVE_IOKIT_IOKITLIB_H || HAVE_IOKIT_PS_IOPOWERSOURCES_H */ - -#elif KERNEL_LINUX - int len; - char filename[128]; - - for (battery_pmu_num = 0; ; battery_pmu_num++) - { - len = ssnprintf (filename, sizeof (filename), battery_pmu_file, battery_pmu_num); - - if ((len < 0) || ((unsigned int)len >= sizeof (filename))) - break; - - if (access (filename, R_OK)) - break; - } -#endif /* KERNEL_LINUX */ - - return (0); -} - -static void battery_submit (const char *plugin_instance, const char *type, double value) -{ - value_t values[1]; - value_list_t vl = VALUE_LIST_INIT; - - values[0].gauge = value; - - vl.values = values; - vl.values_len = 1; - sstrncpy (vl.host, hostname_g, sizeof (vl.host)); - sstrncpy (vl.plugin, "battery", sizeof (vl.plugin)); - sstrncpy (vl.plugin_instance, plugin_instance, sizeof (vl.plugin_instance)); - sstrncpy (vl.type, type, sizeof (vl.type)); - - plugin_dispatch_values (&vl); -} /* void battery_submit */ +int battery_read_statefs( + void); /* defined in battery_statefs; used by StateFS backend */ + +static bool report_percent; +static bool report_degraded; +static bool query_statefs; + +static void battery_submit2(char const *plugin_instance, /* {{{ */ + char const *type, char const *type_instance, + gauge_t value) { + value_list_t vl = VALUE_LIST_INIT; + + vl.values = &(value_t){.gauge = value}; + vl.values_len = 1; + sstrncpy(vl.plugin, "battery", sizeof(vl.plugin)); + sstrncpy(vl.plugin_instance, plugin_instance, sizeof(vl.plugin_instance)); + sstrncpy(vl.type, type, sizeof(vl.type)); + if (type_instance != NULL) + sstrncpy(vl.type_instance, type_instance, sizeof(vl.type_instance)); + + plugin_dispatch_values(&vl); +} /* }}} void battery_submit2 */ + +static void battery_submit(char const *plugin_instance, /* {{{ */ + char const *type, gauge_t value) { + battery_submit2(plugin_instance, type, NULL, value); +} /* }}} void battery_submit */ + +static void submit_capacity(char const *plugin_instance, /* {{{ */ + gauge_t capacity_charged, gauge_t capacity_full, + gauge_t capacity_design) { + if (report_percent && (capacity_charged > capacity_full)) + return; + if (report_degraded && (capacity_full > capacity_design)) + return; + + if (report_percent) { + gauge_t capacity_max; + + if (report_degraded) + capacity_max = capacity_design; + else + capacity_max = capacity_full; + + battery_submit2(plugin_instance, "percent", "charged", + 100.0 * capacity_charged / capacity_max); + battery_submit2(plugin_instance, "percent", "discharged", + 100.0 * (capacity_full - capacity_charged) / capacity_max); + + if (report_degraded) + battery_submit2(plugin_instance, "percent", "degraded", + 100.0 * (capacity_design - capacity_full) / capacity_max); + } else if (report_degraded) /* && !report_percent */ + { + battery_submit2(plugin_instance, "capacity", "charged", capacity_charged); + battery_submit2(plugin_instance, "capacity", "discharged", + (capacity_full - capacity_charged)); + battery_submit2(plugin_instance, "capacity", "degraded", + (capacity_design - capacity_full)); + } else /* !report_percent && !report_degraded */ + { + battery_submit(plugin_instance, "capacity", capacity_charged); + } +} /* }}} void submit_capacity */ #if HAVE_IOKIT_PS_IOPOWERSOURCES_H || HAVE_IOKIT_IOKITLIB_H -double dict_get_double (CFDictionaryRef dict, char *key_string) +static double dict_get_double(CFDictionaryRef dict, + const char *key_string) /* {{{ */ { - double val_double; - long long val_int; - CFNumberRef val_obj; - CFStringRef key_obj; - - key_obj = CFStringCreateWithCString (kCFAllocatorDefault, key_string, - kCFStringEncodingASCII); - if (key_obj == NULL) - { - DEBUG ("CFStringCreateWithCString (%s) failed.\n", key_string); - return (INVALID_VALUE); - } - - if ((val_obj = CFDictionaryGetValue (dict, key_obj)) == NULL) - { - DEBUG ("CFDictionaryGetValue (%s) failed.", key_string); - CFRelease (key_obj); - return (INVALID_VALUE); - } - CFRelease (key_obj); - - if (CFGetTypeID (val_obj) == CFNumberGetTypeID ()) - { - if (CFNumberIsFloatType (val_obj)) - { - CFNumberGetValue (val_obj, - kCFNumberDoubleType, - &val_double); - } - else - { - CFNumberGetValue (val_obj, - kCFNumberLongLongType, - &val_int); - val_double = val_int; - } - } - else - { - DEBUG ("CFGetTypeID (val_obj) = %i", (int) CFGetTypeID (val_obj)); - return (INVALID_VALUE); - } - - return (val_double); -} -#endif /* HAVE_IOKIT_PS_IOPOWERSOURCES_H || HAVE_IOKIT_IOKITLIB_H */ + double val_double; + long long val_int; + CFNumberRef val_obj; + CFStringRef key_obj; + + key_obj = CFStringCreateWithCString(kCFAllocatorDefault, key_string, + kCFStringEncodingASCII); + if (key_obj == NULL) { + DEBUG("CFStringCreateWithCString (%s) failed.\n", key_string); + return NAN; + } + + if ((val_obj = CFDictionaryGetValue(dict, key_obj)) == NULL) { + DEBUG("CFDictionaryGetValue (%s) failed.", key_string); + CFRelease(key_obj); + return NAN; + } + CFRelease(key_obj); + + if (CFGetTypeID(val_obj) == CFNumberGetTypeID()) { + if (CFNumberIsFloatType(val_obj)) { + CFNumberGetValue(val_obj, kCFNumberDoubleType, &val_double); + } else { + CFNumberGetValue(val_obj, kCFNumberLongLongType, &val_int); + val_double = val_int; + } + } else { + DEBUG("CFGetTypeID (val_obj) = %i", (int)CFGetTypeID(val_obj)); + return NAN; + } + + return val_double; +} /* }}} double dict_get_double */ #if HAVE_IOKIT_PS_IOPOWERSOURCES_H -static void get_via_io_power_sources (double *ret_charge, - double *ret_current, - double *ret_voltage) -{ - CFTypeRef ps_raw; - CFArrayRef ps_array; - int ps_array_len; - CFDictionaryRef ps_dict; - CFTypeRef ps_obj; - - double temp_double; - int i; - - ps_raw = IOPSCopyPowerSourcesInfo (); - ps_array = IOPSCopyPowerSourcesList (ps_raw); - ps_array_len = CFArrayGetCount (ps_array); - - DEBUG ("ps_array_len == %i", ps_array_len); - - for (i = 0; i < ps_array_len; i++) - { - ps_obj = CFArrayGetValueAtIndex (ps_array, i); - ps_dict = IOPSGetPowerSourceDescription (ps_raw, ps_obj); - - if (ps_dict == NULL) - { - DEBUG ("IOPSGetPowerSourceDescription failed."); - continue; - } - - if (CFGetTypeID (ps_dict) != CFDictionaryGetTypeID ()) - { - DEBUG ("IOPSGetPowerSourceDescription did not return a CFDictionaryRef"); - continue; - } - - /* FIXME: Check if this is really an internal battery */ - - if (*ret_charge == INVALID_VALUE) - { - /* This is the charge in percent. */ - temp_double = dict_get_double (ps_dict, - kIOPSCurrentCapacityKey); - if ((temp_double != INVALID_VALUE) - && (temp_double >= 0.0) - && (temp_double <= 100.0)) - *ret_charge = temp_double; - } - - if (*ret_current == INVALID_VALUE) - { - temp_double = dict_get_double (ps_dict, - kIOPSCurrentKey); - if (temp_double != INVALID_VALUE) - *ret_current = temp_double / 1000.0; - } - - if (*ret_voltage == INVALID_VALUE) - { - temp_double = dict_get_double (ps_dict, - kIOPSVoltageKey); - if (temp_double != INVALID_VALUE) - *ret_voltage = temp_double / 1000.0; - } - } - - CFRelease(ps_array); - CFRelease(ps_raw); -} +static void get_via_io_power_sources(double *ret_charge, /* {{{ */ + double *ret_current, double *ret_voltage) { + CFTypeRef ps_raw; + CFArrayRef ps_array; + int ps_array_len; + CFDictionaryRef ps_dict; + CFTypeRef ps_obj; + + double temp_double; + + ps_raw = IOPSCopyPowerSourcesInfo(); + ps_array = IOPSCopyPowerSourcesList(ps_raw); + ps_array_len = CFArrayGetCount(ps_array); + + DEBUG("ps_array_len == %i", ps_array_len); + + for (int i = 0; i < ps_array_len; i++) { + ps_obj = CFArrayGetValueAtIndex(ps_array, i); + ps_dict = IOPSGetPowerSourceDescription(ps_raw, ps_obj); + + if (ps_dict == NULL) { + DEBUG("IOPSGetPowerSourceDescription failed."); + continue; + } + + if (CFGetTypeID(ps_dict) != CFDictionaryGetTypeID()) { + DEBUG("IOPSGetPowerSourceDescription did not return a CFDictionaryRef"); + continue; + } + + /* FIXME: Check if this is really an internal battery */ + + if (isnan(*ret_charge)) { + /* This is the charge in percent. */ + temp_double = dict_get_double(ps_dict, kIOPSCurrentCapacityKey); + if (!isnan((temp_double)) && (temp_double >= 0.0) && + (temp_double <= 100.0)) + *ret_charge = temp_double; + } + + if (isnan(*ret_current)) { + temp_double = dict_get_double(ps_dict, kIOPSCurrentKey); + if (!isnan(temp_double)) + *ret_current = temp_double / 1000.0; + } + + if (isnan(*ret_voltage)) { + temp_double = dict_get_double(ps_dict, kIOPSVoltageKey); + if (!isnan(temp_double)) + *ret_voltage = temp_double / 1000.0; + } + } + + CFRelease(ps_array); + CFRelease(ps_raw); +} /* }}} void get_via_io_power_sources */ #endif /* HAVE_IOKIT_PS_IOPOWERSOURCES_H */ #if HAVE_IOKIT_IOKITLIB_H -static void get_via_generic_iokit (double *ret_charge, - double *ret_current, - double *ret_voltage) -{ - kern_return_t status; - io_iterator_t iterator; - io_object_t io_obj; - - CFDictionaryRef bat_root_dict; - CFArrayRef bat_info_arry; - CFIndex bat_info_arry_len; - CFIndex bat_info_arry_pos; - CFDictionaryRef bat_info_dict; - - double temp_double; - - status = IOServiceGetMatchingServices (kIOMasterPortDefault, - IOServiceNameMatching ("battery"), - &iterator); - if (status != kIOReturnSuccess) - { - DEBUG ("IOServiceGetMatchingServices failed."); - return; - } - - while ((io_obj = IOIteratorNext (iterator))) - { - status = IORegistryEntryCreateCFProperties (io_obj, - (CFMutableDictionaryRef *) &bat_root_dict, - kCFAllocatorDefault, - kNilOptions); - if (status != kIOReturnSuccess) - { - DEBUG ("IORegistryEntryCreateCFProperties failed."); - continue; - } - - bat_info_arry = (CFArrayRef) CFDictionaryGetValue (bat_root_dict, - CFSTR ("IOBatteryInfo")); - if (bat_info_arry == NULL) - { - CFRelease (bat_root_dict); - continue; - } - bat_info_arry_len = CFArrayGetCount (bat_info_arry); - - for (bat_info_arry_pos = 0; - bat_info_arry_pos < bat_info_arry_len; - bat_info_arry_pos++) - { - bat_info_dict = (CFDictionaryRef) CFArrayGetValueAtIndex (bat_info_arry, bat_info_arry_pos); - - if (*ret_charge == INVALID_VALUE) - { - temp_double = dict_get_double (bat_info_dict, - "Capacity"); - if (temp_double != INVALID_VALUE) - *ret_charge = temp_double / 1000.0; - } - - if (*ret_current == INVALID_VALUE) - { - temp_double = dict_get_double (bat_info_dict, - "Current"); - if (temp_double != INVALID_VALUE) - *ret_current = temp_double / 1000.0; - } - - if (*ret_voltage == INVALID_VALUE) - { - temp_double = dict_get_double (bat_info_dict, - "Voltage"); - if (temp_double != INVALID_VALUE) - *ret_voltage = temp_double / 1000.0; - } - } - - CFRelease (bat_root_dict); - } - - IOObjectRelease (iterator); -} +static void get_via_generic_iokit(double *ret_capacity_full, /* {{{ */ + double *ret_capacity_design, + double *ret_current, double *ret_voltage) { + kern_return_t status; + io_iterator_t iterator; + io_object_t io_obj; + + CFDictionaryRef bat_root_dict; + CFArrayRef bat_info_arry; + CFIndex bat_info_arry_len; + CFDictionaryRef bat_info_dict; + + double temp_double; + + status = IOServiceGetMatchingServices( + kIOMasterPortDefault, IOServiceNameMatching("battery"), &iterator); + if (status != kIOReturnSuccess) { + DEBUG("IOServiceGetMatchingServices failed."); + return; + } + + while ((io_obj = IOIteratorNext(iterator))) { + status = IORegistryEntryCreateCFProperties( + io_obj, (CFMutableDictionaryRef *)&bat_root_dict, kCFAllocatorDefault, + kNilOptions); + if (status != kIOReturnSuccess) { + DEBUG("IORegistryEntryCreateCFProperties failed."); + continue; + } + + bat_info_arry = + (CFArrayRef)CFDictionaryGetValue(bat_root_dict, CFSTR("IOBatteryInfo")); + if (bat_info_arry == NULL) { + CFRelease(bat_root_dict); + continue; + } + bat_info_arry_len = CFArrayGetCount(bat_info_arry); + + for (CFIndex bat_info_arry_pos = 0; bat_info_arry_pos < bat_info_arry_len; + bat_info_arry_pos++) { + bat_info_dict = (CFDictionaryRef)CFArrayGetValueAtIndex( + bat_info_arry, bat_info_arry_pos); + + if (isnan(*ret_capacity_full)) { + temp_double = dict_get_double(bat_info_dict, "Capacity"); + *ret_capacity_full = temp_double / 1000.0; + } + + if (isnan(*ret_capacity_design)) { + temp_double = dict_get_double(bat_info_dict, "AbsoluteMaxCapacity"); + *ret_capacity_design = temp_double / 1000.0; + } + + if (isnan(*ret_current)) { + temp_double = dict_get_double(bat_info_dict, "Current"); + *ret_current = temp_double / 1000.0; + } + + if (isnan(*ret_voltage)) { + temp_double = dict_get_double(bat_info_dict, "Voltage"); + *ret_voltage = temp_double / 1000.0; + } + } + + CFRelease(bat_root_dict); + } + + IOObjectRelease(iterator); +} /* }}} void get_via_generic_iokit */ #endif /* HAVE_IOKIT_IOKITLIB_H */ -#if KERNEL_LINUX -static int battery_read_acpi (const char __attribute__((unused)) *dir, - const char *name, void __attribute__((unused)) *user_data) +static int battery_read(void) /* {{{ */ { - double current = INVALID_VALUE; - double voltage = INVALID_VALUE; - double charge = INVALID_VALUE; - double *valptr = NULL; - int charging = 0; - - char filename[256]; - FILE *fh; - - char buffer[1024]; - char *fields[8]; - int numfields; - char *endptr; - int len; - - len = ssnprintf (filename, sizeof (filename), "%s/%s/state", battery_acpi_dir, name); - - if ((len < 0) || ((unsigned int)len >= sizeof (filename))) - return -1; - - if ((fh = fopen (filename, "r")) == NULL) { - char errbuf[1024]; - ERROR ("Cannot open `%s': %s", filename, - sstrerror (errno, errbuf, sizeof (errbuf))); - return -1; - } - - /* - * [11:00] <@tokkee> $ cat /proc/acpi/battery/BAT1/state - * [11:00] <@tokkee> present: yes - * [11:00] <@tokkee> capacity state: ok - * [11:00] <@tokkee> charging state: charging - * [11:00] <@tokkee> present rate: 1724 mA - * [11:00] <@tokkee> remaining capacity: 4136 mAh - * [11:00] <@tokkee> present voltage: 12428 mV - */ - while (fgets (buffer, sizeof (buffer), fh) != NULL) - { - numfields = strsplit (buffer, fields, 8); - - if (numfields < 3) - continue; - - if ((strcmp (fields[0], "charging") == 0) - && (strcmp (fields[1], "state:") == 0)) - { - if (strcmp (fields[2], "charging") == 0) - charging = 1; - else - charging = 0; - continue; - } - - if ((strcmp (fields[0], "present") == 0) - && (strcmp (fields[1], "rate:") == 0)) - valptr = ¤t; - else if ((strcmp (fields[0], "remaining") == 0) - && (strcmp (fields[1], "capacity:") == 0)) - valptr = &charge; - else if ((strcmp (fields[0], "present") == 0) - && (strcmp (fields[1], "voltage:") == 0)) - valptr = &voltage; - else - continue; - - endptr = NULL; - errno = 0; - *valptr = strtod (fields[2], &endptr) / 1000.0; - - if ((fields[2] == endptr) || (errno != 0)) - *valptr = INVALID_VALUE; - } /* while (fgets (buffer, sizeof (buffer), fh) != NULL) */ - - fclose (fh); - - if ((current != INVALID_VALUE) && (charging == 0)) - current *= -1; - - if (charge != INVALID_VALUE) - battery_submit ("0", "charge", charge); - if (current != INVALID_VALUE) - battery_submit ("0", "current", current); - if (voltage != INVALID_VALUE) - battery_submit ("0", "voltage", voltage); - - return 0; -} -#endif /* KERNEL_LINUX */ + gauge_t current = NAN; /* Current in A */ + gauge_t voltage = NAN; /* Voltage in V */ + /* We only get the charged capacity as a percentage from + * IOPowerSources. IOKit, on the other hand, only reports the full + * capacity. We use the two to calculate the current charged capacity. */ + gauge_t charge_rel = NAN; /* Current charge in percent */ + gauge_t capacity_charged; /* Charged capacity */ + gauge_t capacity_full = NAN; /* Total capacity */ + gauge_t capacity_design = NAN; /* Full design capacity */ -static int battery_read (void) -{ -#if HAVE_IOKIT_IOKITLIB_H || HAVE_IOKIT_PS_IOPOWERSOURCES_H - double charge = INVALID_VALUE; /* Current charge in Ah */ - double current = INVALID_VALUE; /* Current in A */ - double voltage = INVALID_VALUE; /* Voltage in V */ - - double charge_rel = INVALID_VALUE; /* Current charge in percent */ - double charge_abs = INVALID_VALUE; /* Total capacity */ + if (query_statefs) + return battery_read_statefs(); #if HAVE_IOKIT_PS_IOPOWERSOURCES_H - get_via_io_power_sources (&charge_rel, ¤t, &voltage); + get_via_io_power_sources(&charge_rel, ¤t, &voltage); #endif #if HAVE_IOKIT_IOKITLIB_H - get_via_generic_iokit (&charge_abs, ¤t, &voltage); + get_via_generic_iokit(&capacity_full, &capacity_design, ¤t, &voltage); #endif - if ((charge_rel != INVALID_VALUE) && (charge_abs != INVALID_VALUE)) - charge = charge_abs * charge_rel / 100.0; + capacity_charged = charge_rel * capacity_full / 100.0; + submit_capacity("0", capacity_charged, capacity_full, capacity_design); - if (charge != INVALID_VALUE) - battery_submit ("0", "charge", charge); - if (current != INVALID_VALUE) - battery_submit ("0", "current", current); - if (voltage != INVALID_VALUE) - battery_submit ("0", "voltage", voltage); -/* #endif HAVE_IOKIT_IOKITLIB_H || HAVE_IOKIT_PS_IOPOWERSOURCES_H */ + if (!isnan(current)) + battery_submit("0", "current", current); + if (!isnan(voltage)) + battery_submit("0", "voltage", voltage); + + return 0; +} /* }}} int battery_read */ + /* #endif HAVE_IOKIT_IOKITLIB_H || HAVE_IOKIT_PS_IOPOWERSOURCES_H */ #elif KERNEL_LINUX - static c_complain_t acpi_dir_complaint = C_COMPLAIN_INIT_STATIC; - - FILE *fh; - char buffer[1024]; - char filename[256]; - - char *fields[8]; - int numfields; - - int i; - int len; - - for (i = 0; i < battery_pmu_num; i++) - { - char batnum_str[256]; - double current = INVALID_VALUE; - double voltage = INVALID_VALUE; - double charge = INVALID_VALUE; - double *valptr = NULL; - - len = ssnprintf (filename, sizeof (filename), battery_pmu_file, i); - if ((len < 0) || ((unsigned int)len >= sizeof (filename))) - continue; - - len = ssnprintf (batnum_str, sizeof (batnum_str), "%i", i); - if ((len < 0) || ((unsigned int)len >= sizeof (batnum_str))) - continue; - - if ((fh = fopen (filename, "r")) == NULL) - continue; - - while (fgets (buffer, sizeof (buffer), fh) != NULL) - { - numfields = strsplit (buffer, fields, 8); - - if (numfields < 3) - continue; - - if (strcmp ("current", fields[0]) == 0) - valptr = ¤t; - else if (strcmp ("voltage", fields[0]) == 0) - valptr = &voltage; - else if (strcmp ("charge", fields[0]) == 0) - valptr = &charge; - else - valptr = NULL; - - if (valptr != NULL) - { - char *endptr; - - endptr = NULL; - errno = 0; - - *valptr = strtod (fields[2], &endptr) / 1000.0; - - if ((fields[2] == endptr) || (errno != 0)) - *valptr = INVALID_VALUE; - } - } - - fclose (fh); - fh = NULL; - - if (charge != INVALID_VALUE) - battery_submit ("0", "charge", charge); - if (current != INVALID_VALUE) - battery_submit ("0", "current", current); - if (voltage != INVALID_VALUE) - battery_submit ("0", "voltage", voltage); - } - - if (0 == access (battery_acpi_dir, R_OK)) - walk_directory (battery_acpi_dir, battery_read_acpi, - /* user_data = */ NULL, - /* include hidden */ 0); - else - { - char errbuf[1024]; - c_complain_once (LOG_WARNING, &acpi_dir_complaint, - "battery plugin: Failed to access `%s': %s", - battery_acpi_dir, - sstrerror (errno, errbuf, sizeof (errbuf))); - } +/* Reads a file which contains only a number (and optionally a trailing + * newline) and parses that number. */ +static int sysfs_file_to_buffer(char const *dir, /* {{{ */ + char const *power_supply, char const *basename, + char *buffer, size_t buffer_size) { + char filename[PATH_MAX]; + int status; + + snprintf(filename, sizeof(filename), "%s/%s/%s", dir, power_supply, basename); + + status = (int)read_text_file_contents(filename, buffer, buffer_size); + if (status < 0) + return status; + + strstripnewline(buffer); + return 0; +} /* }}} int sysfs_file_to_buffer */ + +/* Reads a file which contains only a number (and optionally a trailing + * newline) and parses that number. */ +static int sysfs_file_to_gauge(char const *dir, /* {{{ */ + char const *power_supply, char const *basename, + gauge_t *ret_value) { + int status; + char buffer[32]; + + status = + sysfs_file_to_buffer(dir, power_supply, basename, buffer, sizeof(buffer)); + if (status != 0) + return status; + + return strtogauge(buffer, ret_value); +} /* }}} sysfs_file_to_gauge */ + +static int read_sysfs_capacity(char const *dir, /* {{{ */ + char const *power_supply, + char const *plugin_instance) { + gauge_t capacity_charged = NAN; + gauge_t capacity_full = NAN; + gauge_t capacity_design = NAN; + int status; + + status = + sysfs_file_to_gauge(dir, power_supply, "energy_now", &capacity_charged); + if (status != 0) + return status; + + status = + sysfs_file_to_gauge(dir, power_supply, "energy_full", &capacity_full); + if (status != 0) + return status; + + status = sysfs_file_to_gauge(dir, power_supply, "energy_full_design", + &capacity_design); + if (status != 0) + return status; + + submit_capacity(plugin_instance, capacity_charged * SYSFS_FACTOR, + capacity_full * SYSFS_FACTOR, capacity_design * SYSFS_FACTOR); + return 0; +} /* }}} int read_sysfs_capacity */ + +static int read_sysfs_capacity_from_charge(char const *dir, /* {{{ */ + char const *power_supply, + char const *plugin_instance) { + gauge_t capacity_charged = NAN; + gauge_t capacity_full = NAN; + gauge_t capacity_design = NAN; + gauge_t voltage_min_design = NAN; + int status; + + status = sysfs_file_to_gauge(dir, power_supply, "voltage_min_design", + &voltage_min_design); + if (status != 0) + return status; + voltage_min_design *= SYSFS_FACTOR; + + status = + sysfs_file_to_gauge(dir, power_supply, "charge_now", &capacity_charged); + if (status != 0) + return status; + capacity_charged *= voltage_min_design; + + status = + sysfs_file_to_gauge(dir, power_supply, "charge_full", &capacity_full); + if (status != 0) + return status; + capacity_full *= voltage_min_design; + + status = sysfs_file_to_gauge(dir, power_supply, "charge_full_design", + &capacity_design); + if (status != 0) + return status; + capacity_design *= voltage_min_design; + + submit_capacity(plugin_instance, capacity_charged * SYSFS_FACTOR, + capacity_full * SYSFS_FACTOR, capacity_design * SYSFS_FACTOR); + return 0; +} /* }}} int read_sysfs_capacity_from_charge */ + +static int read_sysfs_callback(char const *dir, /* {{{ */ + char const *power_supply, void *user_data) { + int *battery_index = user_data; + + char const *plugin_instance; + char buffer[32]; + gauge_t v = NAN; + bool discharging = false; + int status; + + /* Ignore non-battery directories, such as AC power. */ + status = + sysfs_file_to_buffer(dir, power_supply, "type", buffer, sizeof(buffer)); + if (status != 0) + return 0; + if (strcasecmp("Battery", buffer) != 0) + return 0; + + (void)sysfs_file_to_buffer(dir, power_supply, "status", buffer, + sizeof(buffer)); + if (strcasecmp("Discharging", buffer) == 0) + discharging = true; + + /* FIXME: This is a dirty hack for backwards compatibility: The battery + * plugin, for a very long time, has had the plugin_instance + * hard-coded to "0". So, to keep backwards compatibility, we'll use + * "0" for the first battery we find and the power_supply name for all + * following. This should be reverted in a future major version. */ + plugin_instance = (*battery_index == 0) ? "0" : power_supply; + (*battery_index)++; + + if (sysfs_file_to_gauge(dir, power_supply, "energy_now", &v) == 0) + read_sysfs_capacity(dir, power_supply, plugin_instance); + else + read_sysfs_capacity_from_charge(dir, power_supply, plugin_instance); + + if (sysfs_file_to_gauge(dir, power_supply, "power_now", &v) == 0) { + if (discharging) + v *= -1.0; + battery_submit(plugin_instance, "power", v * SYSFS_FACTOR); + } + if (sysfs_file_to_gauge(dir, power_supply, "current_now", &v) == 0) { + if (discharging) + v *= -1.0; + battery_submit(plugin_instance, "current", v * SYSFS_FACTOR); + } + + if (sysfs_file_to_gauge(dir, power_supply, "voltage_now", &v) == 0) + battery_submit(plugin_instance, "voltage", v * SYSFS_FACTOR); + + return 0; +} /* }}} int read_sysfs_callback */ + +static int read_sysfs(void) /* {{{ */ +{ + int status; + int battery_counter = 0; -#endif /* KERNEL_LINUX */ + if (access(SYSFS_PATH, R_OK) != 0) + return ENOENT; + + status = walk_directory(SYSFS_PATH, read_sysfs_callback, + /* user_data = */ &battery_counter, + /* include hidden */ 0); + return status; +} /* }}} int read_sysfs */ - return (0); -} +static int read_acpi_full_capacity(char const *dir, /* {{{ */ + char const *power_supply, + gauge_t *ret_capacity_full, + gauge_t *ret_capacity_design) -void module_register (void) { - plugin_register_init ("battery", battery_init); - plugin_register_read ("battery", battery_read); + char filename[PATH_MAX]; + char buffer[1024]; + + FILE *fh; + + snprintf(filename, sizeof(filename), "%s/%s/info", dir, power_supply); + fh = fopen(filename, "r"); + if (fh == NULL) + return errno; + + /* last full capacity: 40090 mWh */ + while (fgets(buffer, sizeof(buffer), fh) != NULL) { + gauge_t *value_ptr; + int fields_num; + char *fields[8]; + int index; + + if (strncmp("last full capacity:", buffer, strlen("last full capacity:")) == + 0) { + value_ptr = ret_capacity_full; + index = 3; + } else if (strncmp("design capacity:", buffer, + strlen("design capacity:")) == 0) { + value_ptr = ret_capacity_design; + index = 2; + } else { + continue; + } + + fields_num = strsplit(buffer, fields, STATIC_ARRAY_SIZE(fields)); + if (fields_num <= index) + continue; + + strtogauge(fields[index], value_ptr); + } + + fclose(fh); + return 0; +} /* }}} int read_acpi_full_capacity */ + +static int read_acpi_callback(char const *dir, /* {{{ */ + char const *power_supply, void *user_data) { + int *battery_index = user_data; + + gauge_t power = NAN; + gauge_t voltage = NAN; + gauge_t capacity_charged = NAN; + gauge_t capacity_full = NAN; + gauge_t capacity_design = NAN; + bool charging = false; + bool is_current = false; + + char const *plugin_instance; + char filename[PATH_MAX]; + char buffer[1024]; + + FILE *fh; + + snprintf(filename, sizeof(filename), "%s/%s/state", dir, power_supply); + fh = fopen(filename, "r"); + if (fh == NULL) { + if ((errno == EAGAIN) || (errno == EINTR) || (errno == ENOENT)) + return 0; + else + return errno; + } + + /* + * [11:00] <@tokkee> $ cat /proc/acpi/battery/BAT1/state + * [11:00] <@tokkee> present: yes + * [11:00] <@tokkee> capacity state: ok + * [11:00] <@tokkee> charging state: charging + * [11:00] <@tokkee> present rate: 1724 mA + * [11:00] <@tokkee> remaining capacity: 4136 mAh + * [11:00] <@tokkee> present voltage: 12428 mV + */ + while (fgets(buffer, sizeof(buffer), fh) != NULL) { + char *fields[8]; + int numfields; + + numfields = strsplit(buffer, fields, STATIC_ARRAY_SIZE(fields)); + if (numfields < 3) + continue; + + if ((strcmp(fields[0], "charging") == 0) && + (strcmp(fields[1], "state:") == 0)) { + if (strcmp(fields[2], "charging") == 0) + charging = true; + else + charging = false; + continue; + } + + /* The unit of "present rate" depends on the battery. Modern + * batteries export power (watts), older batteries (used to) + * export current (amperes). We check the fourth column and try + * to find old batteries this way. */ + if ((strcmp(fields[0], "present") == 0) && + (strcmp(fields[1], "rate:") == 0)) { + strtogauge(fields[2], &power); + + if ((numfields >= 4) && (strcmp("mA", fields[3]) == 0)) + is_current = true; + } else if ((strcmp(fields[0], "remaining") == 0) && + (strcmp(fields[1], "capacity:") == 0)) + strtogauge(fields[2], &capacity_charged); + else if ((strcmp(fields[0], "present") == 0) && + (strcmp(fields[1], "voltage:") == 0)) + strtogauge(fields[2], &voltage); + } /* while (fgets (buffer, sizeof (buffer), fh) != NULL) */ + + fclose(fh); + + if (!charging) + power *= -1.0; + + /* FIXME: This is a dirty hack for backwards compatibility: The battery + * plugin, for a very long time, has had the plugin_instance + * hard-coded to "0". So, to keep backwards compatibility, we'll use + * "0" for the first battery we find and the power_supply name for all + * following. This should be reverted in a future major version. */ + plugin_instance = (*battery_index == 0) ? "0" : power_supply; + (*battery_index)++; + + read_acpi_full_capacity(dir, power_supply, &capacity_full, &capacity_design); + + submit_capacity(plugin_instance, capacity_charged * PROC_ACPI_FACTOR, + capacity_full * PROC_ACPI_FACTOR, + capacity_design * PROC_ACPI_FACTOR); + + battery_submit(plugin_instance, is_current ? "current" : "power", + power * PROC_ACPI_FACTOR); + battery_submit(plugin_instance, "voltage", voltage * PROC_ACPI_FACTOR); + + return 0; +} /* }}} int read_acpi_callback */ + +static int read_acpi(void) /* {{{ */ +{ + int status; + int battery_counter = 0; + + if (access(PROC_ACPI_PATH, R_OK) != 0) + return ENOENT; + + status = walk_directory(PROC_ACPI_PATH, read_acpi_callback, + /* user_data = */ &battery_counter, + /* include hidden */ 0); + return status; +} /* }}} int read_acpi */ + +static int read_pmu(void) /* {{{ */ +{ + int i = 0; + /* The upper limit here is just a safeguard. If there is a system with + * more than 100 batteries, this can easily be increased. */ + for (; i < 100; i++) { + FILE *fh; + + char buffer[1024]; + char filename[PATH_MAX]; + char plugin_instance[DATA_MAX_NAME_LEN]; + + gauge_t current = NAN; + gauge_t voltage = NAN; + gauge_t charge = NAN; + + snprintf(filename, sizeof(filename), PROC_PMU_PATH_FORMAT, i); + if (access(filename, R_OK) != 0) + break; + + snprintf(plugin_instance, sizeof(plugin_instance), "%i", i); + + fh = fopen(filename, "r"); + if (fh == NULL) { + if (errno == ENOENT) + break; + else if ((errno == EAGAIN) || (errno == EINTR)) + continue; + else + return errno; + } + + while (fgets(buffer, sizeof(buffer), fh) != NULL) { + char *fields[8]; + int numfields; + + numfields = strsplit(buffer, fields, STATIC_ARRAY_SIZE(fields)); + if (numfields < 3) + continue; + + if (strcmp("current", fields[0]) == 0) + strtogauge(fields[2], ¤t); + else if (strcmp("voltage", fields[0]) == 0) + strtogauge(fields[2], &voltage); + else if (strcmp("charge", fields[0]) == 0) + strtogauge(fields[2], &charge); + } + + fclose(fh); + fh = NULL; + + battery_submit(plugin_instance, "charge", charge / 1000.0); + battery_submit(plugin_instance, "current", current / 1000.0); + battery_submit(plugin_instance, "voltage", voltage / 1000.0); + } + + if (i == 0) + return ENOENT; + return 0; +} /* }}} int read_pmu */ + +static int battery_read(void) /* {{{ */ +{ + int status; + + if (query_statefs) + return battery_read_statefs(); + + DEBUG("battery plugin: Trying sysfs ..."); + status = read_sysfs(); + if (status == 0) + return 0; + + DEBUG("battery plugin: Trying acpi ..."); + status = read_acpi(); + if (status == 0) + return 0; + + DEBUG("battery plugin: Trying pmu ..."); + status = read_pmu(); + if (status == 0) + return 0; + + ERROR("battery plugin: All available input methods failed."); + return -1; +} /* }}} int battery_read */ +#endif /* KERNEL_LINUX */ + +static int battery_config(oconfig_item_t *ci) { + for (int i = 0; i < ci->children_num; i++) { + oconfig_item_t *child = ci->children + i; + + if (strcasecmp("ValuesPercentage", child->key) == 0) + cf_util_get_boolean(child, &report_percent); + else if (strcasecmp("ReportDegraded", child->key) == 0) + cf_util_get_boolean(child, &report_degraded); + else if (strcasecmp("QueryStateFS", child->key) == 0) + cf_util_get_boolean(child, &query_statefs); + else + WARNING("battery plugin: Ignoring unknown " + "configuration option \"%s\".", + child->key); + } + + return 0; +} /* }}} int battery_config */ + +void module_register(void) { + plugin_register_complex_config("battery", battery_config); + plugin_register_read("battery", battery_read); } /* void module_register */ diff --git a/src/battery_statefs.c b/src/battery_statefs.c new file mode 100644 index 0000000000..d2c1ed9d62 --- /dev/null +++ b/src/battery_statefs.c @@ -0,0 +1,122 @@ +/** + * collectd - src/statefs_battery.c + * Copyright (C) 2016 rinigus + * + * +The MIT License (MIT) + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + + * Authors: + * rinigus + + Battery stats are collected from StateFS Battery namespace. Reported + units are as follows: + + capacity % + charge % + current A + energy Wh + power W + temperature C + timefull and timelow seconds + voltage V + + Provider at + https://git.merproject.org/mer-core/statefs-providers/blob/master/src/power_udev/provider_power_udev.cpp + + **/ + +#include "collectd.h" +#include "plugin.h" +#include "utils/common/common.h" + +#include + +#define STATEFS_ROOT "/run/state/namespaces/Battery/" + +static void battery_submit(const char *type, gauge_t value, + const char *type_instance) { + value_list_t vl = VALUE_LIST_INIT; + + vl.values = &(value_t){.gauge = value}; + vl.values_len = 1; + sstrncpy(vl.plugin, "battery", sizeof(vl.plugin)); + /* statefs supports 1 battery at present */ + sstrncpy(vl.plugin_instance, "0", sizeof(vl.plugin_instance)); + sstrncpy(vl.type, type, sizeof(vl.type)); + if (type_instance != NULL) + sstrncpy(vl.type_instance, type_instance, sizeof(vl.type_instance)); + plugin_dispatch_values(&vl); +} + +/* cannot be static, is referred to from battery.c */ +int battery_read_statefs(void) { + value_t v; + int success = 0; + + if (parse_value_file(STATEFS_ROOT "ChargePercentage", &v, DS_TYPE_GAUGE) == + 0) { + battery_submit("charge", v.gauge, NULL); + success++; + } else if (parse_value_file(STATEFS_ROOT "Capacity", &v, DS_TYPE_GAUGE) == + 0) { + // Use capacity as a charge estimate if ChargePercentage is not available + battery_submit("charge", v.gauge, NULL); + success++; + } else { + WARNING("battery plugin: Neither \"" STATEFS_ROOT "ChargePercentage\" " + "nor \"" STATEFS_ROOT "Capacity\" could be read."); + } + + struct { + const char *path; + const char *type; + const char *type_instance; + gauge_t factor; + } metrics[] = { + {STATEFS_ROOT "Current", "current", NULL, 1e-6}, // from uA to A + {STATEFS_ROOT "Energy", "energy_wh", NULL, 1e-6}, // from uWh to Wh + {STATEFS_ROOT "Power", "power", NULL, 1e-6}, // from uW to W + {STATEFS_ROOT "Temperature", "temperature", NULL, 0.1}, // from 10xC to C + {STATEFS_ROOT "TimeUntilFull", "duration", "full", 1.0}, + {STATEFS_ROOT "TimeUntilLow", "duration", "low", 1.0}, + {STATEFS_ROOT "Voltage", "voltage", NULL, 1e-6}, // from uV to V + }; + + for (size_t i = 0; i < STATIC_ARRAY_SIZE(metrics); i++) { + if (parse_value_file(metrics[i].path, &v, DS_TYPE_GAUGE) != 0) { + WARNING("battery plugin: Reading \"%s\" failed.", metrics[i].path); + continue; + } + + battery_submit(metrics[i].type, v.gauge * metrics[i].factor, + metrics[i].type_instance); + success++; + } + + if (success == 0) { + ERROR("battery plugin: statefs backend: none of the statistics are " + "available"); + return -1; + } + + return 0; +} diff --git a/src/bind.c b/src/bind.c index ddde840a48..a246f1aacf 100644 --- a/src/bind.c +++ b/src/bind.c @@ -24,26 +24,34 @@ #include "config.h" #if STRPTIME_NEEDS_STANDARDS -# ifndef _ISOC99_SOURCE -# define _ISOC99_SOURCE 1 -# endif -# ifndef _POSIX_C_SOURCE -# define _POSIX_C_SOURCE 200112L -# endif -# ifndef _XOPEN_SOURCE -# define _XOPEN_SOURCE 500 -# endif +#ifndef _ISOC99_SOURCE +#define _ISOC99_SOURCE 1 +#endif +#ifndef _POSIX_C_SOURCE +#define _POSIX_C_SOURCE 200112L +#endif +#ifndef _XOPEN_SOURCE +#define _XOPEN_SOURCE 500 +#endif #endif /* STRPTIME_NEEDS_STANDARDS */ +#if TIMEGM_NEEDS_BSD +#ifndef _BSD_SOURCE +#define _BSD_SOURCE 1 +#endif +#endif /* TIMEGM_NEEDS_BSD */ + #include "collectd.h" -#include "common.h" + #include "plugin.h" -#include "configfile.h" +#include "utils/common/common.h" + +#include /* Some versions of libcurl don't include this themselves and then don't have * fd_set available. */ #if HAVE_SYS_SELECT_H -# include +#include #endif #include @@ -51,48 +59,44 @@ #include #ifndef BIND_DEFAULT_URL -# define BIND_DEFAULT_URL "http://localhost:8053/" +#define BIND_DEFAULT_URL "http://localhost:8053/" #endif -/* +/* * Some types used for the callback functions. `translation_table_ptr_t' and * `list_info_ptr_t' are passed to the callbacks in the `void *user_data' * pointer. */ -typedef int (*list_callback_t) (const char *name, value_t value, - time_t current_time, void *user_data); +typedef int (*list_callback_t)(const char *name, value_t value, + time_t current_time, void *user_data); -struct cb_view_s -{ +struct cb_view_s { char *name; - int qtypes; - int resolver_stats; - int cacherrsets; + _Bool qtypes; + _Bool resolver_stats; + _Bool cacherrsets; char **zones; size_t zones_num; }; typedef struct cb_view_s cb_view_t; -struct translation_info_s -{ +struct translation_info_s { const char *xml_name; const char *type; const char *type_instance; }; typedef struct translation_info_s translation_info_t; -struct translation_table_ptr_s -{ +struct translation_table_ptr_s { const translation_info_t *table; size_t table_length; const char *plugin_instance; }; typedef struct translation_table_ptr_s translation_table_ptr_t; -struct list_info_ptr_s -{ +struct list_info_ptr_s { const char *plugin_instance; const char *type; }; @@ -100,378 +104,351 @@ typedef struct list_info_ptr_s list_info_ptr_t; /* FIXME: Enabled by default for backwards compatibility. */ /* TODO: Remove time parsing code. */ -static _Bool config_parse_time = 1; +static bool config_parse_time = true; -static char *url = NULL; -static int global_opcodes = 1; -static int global_qtypes = 1; -static int global_server_stats = 1; -static int global_zone_maint_stats = 1; -static int global_resolver_stats = 0; -static int global_memory_stats = 1; +static char *url; +static _Bool global_opcodes = 1; +static _Bool global_qtypes = 1; +static _Bool global_server_stats = 1; +static _Bool global_zone_maint_stats = 1; +static _Bool global_resolver_stats; +static _Bool global_memory_stats = 1; +static int timeout = -1; -static cb_view_t *views = NULL; -static size_t views_num = 0; +static cb_view_t *views; +static size_t views_num; -static CURL *curl = NULL; +static CURL *curl; -static char *bind_buffer = NULL; -static size_t bind_buffer_size = 0; -static size_t bind_buffer_fill = 0; -static char bind_curl_error[CURL_ERROR_SIZE]; +static char *bind_buffer; +static size_t bind_buffer_size; +static size_t bind_buffer_fill; +static char bind_curl_error[CURL_ERROR_SIZE]; /* Translation table for the `nsstats' values. */ static const translation_info_t nsstats_translation_table[] = /* {{{ */ -{ - /* Requests */ - { "Requestv4", "dns_request", "IPv4" }, - { "Requestv6", "dns_request", "IPv6" }, - { "ReqEdns0", "dns_request", "EDNS0" }, - { "ReqBadEDNSVer", "dns_request", "BadEDNSVer" }, - { "ReqTSIG", "dns_request", "TSIG" }, - { "ReqSIG0", "dns_request", "SIG0" }, - { "ReqBadSIG", "dns_request", "BadSIG" }, - { "ReqTCP", "dns_request", "TCP" }, - /* Rejects */ - { "AuthQryRej", "dns_reject", "authorative" }, - { "RecQryRej", "dns_reject", "recursive" }, - { "XfrRej", "dns_reject", "transfer" }, - { "UpdateRej", "dns_reject", "update" }, - /* Responses */ - { "Response", "dns_response", "normal" }, - { "TruncatedResp", "dns_response", "truncated" }, - { "RespEDNS0", "dns_response", "EDNS0" }, - { "RespTSIG", "dns_response", "TSIG" }, - { "RespSIG0", "dns_response", "SIG0" }, - /* Queries */ - { "QryAuthAns", "dns_query", "authorative" }, - { "QryNoauthAns", "dns_query", "nonauth" }, - { "QryReferral", "dns_query", "referral" }, - { "QryRecursion", "dns_query", "recursion" }, - { "QryDuplicate", "dns_query", "dupliate" }, - { "QryDropped", "dns_query", "dropped" }, - { "QryFailure", "dns_query", "failure" }, - /* Response codes */ - { "QrySuccess", "dns_rcode", "tx-NOERROR" }, - { "QryNxrrset", "dns_rcode", "tx-NXRRSET" }, - { "QrySERVFAIL", "dns_rcode", "tx-SERVFAIL" }, - { "QryFORMERR", "dns_rcode", "tx-FORMERR" }, - { "QryNXDOMAIN", "dns_rcode", "tx-NXDOMAIN" } + { + /* Requests */ + {"Requestv4", "dns_request", "IPv4"}, + {"Requestv6", "dns_request", "IPv6"}, + {"ReqEdns0", "dns_request", "EDNS0"}, + {"ReqBadEDNSVer", "dns_request", "BadEDNSVer"}, + {"ReqTSIG", "dns_request", "TSIG"}, + {"ReqSIG0", "dns_request", "SIG0"}, + {"ReqBadSIG", "dns_request", "BadSIG"}, + {"ReqTCP", "dns_request", "TCP"}, + /* Rejects */ + {"AuthQryRej", "dns_reject", "authoritative"}, + {"RecQryRej", "dns_reject", "recursive"}, + {"XfrRej", "dns_reject", "transfer"}, + {"UpdateRej", "dns_reject", "update"}, + /* Responses */ + {"Response", "dns_response", "normal"}, + {"TruncatedResp", "dns_response", "truncated"}, + {"RespEDNS0", "dns_response", "EDNS0"}, + {"RespTSIG", "dns_response", "TSIG"}, + {"RespSIG0", "dns_response", "SIG0"}, + /* Queries */ + {"QryAuthAns", "dns_query", "authoritative"}, + {"QryNoauthAns", "dns_query", "nonauth"}, + {"QryReferral", "dns_query", "referral"}, + {"QryRecursion", "dns_query", "recursion"}, + {"QryDuplicate", "dns_query", "duplicate"}, + {"QryDropped", "dns_query", "dropped"}, + {"QryFailure", "dns_query", "failure"}, + /* Response codes */ + {"QrySuccess", "dns_rcode", "tx-NOERROR"}, + {"QryNxrrset", "dns_rcode", "tx-NXRRSET"}, + {"QrySERVFAIL", "dns_rcode", "tx-SERVFAIL"}, + {"QryFORMERR", "dns_rcode", "tx-FORMERR"}, + {"QryNXDOMAIN", "dns_rcode", "tx-NXDOMAIN"} #if 0 - { "XfrReqDone", "type", "type_instance" }, - { "UpdateReqFwd", "type", "type_instance" }, - { "UpdateRespFwd", "type", "type_instance" }, - { "UpdateFwdFail", "type", "type_instance" }, - { "UpdateDone", "type", "type_instance" }, - { "UpdateFail", "type", "type_instance" }, - { "UpdateBadPrereq", "type", "type_instance" }, + { "XfrReqDone", "type", "type_instance" }, + { "UpdateReqFwd", "type", "type_instance" }, + { "UpdateRespFwd", "type", "type_instance" }, + { "UpdateFwdFail", "type", "type_instance" }, + { "UpdateDone", "type", "type_instance" }, + { "UpdateFail", "type", "type_instance" }, + { "UpdateBadPrereq", "type", "type_instance" }, #endif }; static int nsstats_translation_table_length = - STATIC_ARRAY_SIZE (nsstats_translation_table); + STATIC_ARRAY_SIZE(nsstats_translation_table); /* }}} */ /* Translation table for the `zonestats' values. */ static const translation_info_t zonestats_translation_table[] = /* {{{ */ -{ - /* Notify's */ - { "NotifyOutv4", "dns_notify", "tx-IPv4" }, - { "NotifyOutv6", "dns_notify", "tx-IPv6" }, - { "NotifyInv4", "dns_notify", "rx-IPv4" }, - { "NotifyInv6", "dns_notify", "rx-IPv6" }, - { "NotifyRej", "dns_notify", "rejected" }, - /* SOA/AXFS/IXFS requests */ - { "SOAOutv4", "dns_opcode", "SOA-IPv4" }, - { "SOAOutv6", "dns_opcode", "SOA-IPv6" }, - { "AXFRReqv4", "dns_opcode", "AXFR-IPv4" }, - { "AXFRReqv6", "dns_opcode", "AXFR-IPv6" }, - { "IXFRReqv4", "dns_opcode", "IXFR-IPv4" }, - { "IXFRReqv6", "dns_opcode", "IXFR-IPv6" }, - /* Domain transfers */ - { "XfrSuccess", "dns_transfer", "success" }, - { "XfrFail", "dns_transfer", "failure" } -}; + { + /* Notify's */ + {"NotifyOutv4", "dns_notify", "tx-IPv4"}, + {"NotifyOutv6", "dns_notify", "tx-IPv6"}, + {"NotifyInv4", "dns_notify", "rx-IPv4"}, + {"NotifyInv6", "dns_notify", "rx-IPv6"}, + {"NotifyRej", "dns_notify", "rejected"}, + /* SOA/AXFS/IXFS requests */ + {"SOAOutv4", "dns_opcode", "SOA-IPv4"}, + {"SOAOutv6", "dns_opcode", "SOA-IPv6"}, + {"AXFRReqv4", "dns_opcode", "AXFR-IPv4"}, + {"AXFRReqv6", "dns_opcode", "AXFR-IPv6"}, + {"IXFRReqv4", "dns_opcode", "IXFR-IPv4"}, + {"IXFRReqv6", "dns_opcode", "IXFR-IPv6"}, + /* Domain transfers */ + {"XfrSuccess", "dns_transfer", "success"}, + {"XfrFail", "dns_transfer", "failure"}}; static int zonestats_translation_table_length = - STATIC_ARRAY_SIZE (zonestats_translation_table); + STATIC_ARRAY_SIZE(zonestats_translation_table); /* }}} */ /* Translation table for the `resstats' values. */ static const translation_info_t resstats_translation_table[] = /* {{{ */ -{ - /* Generic resolver information */ - { "Queryv4", "dns_query", "IPv4" }, - { "Queryv6", "dns_query", "IPv6" }, - { "Responsev4", "dns_response", "IPv4" }, - { "Responsev6", "dns_response", "IPv6" }, - /* Received response codes */ - { "NXDOMAIN", "dns_rcode", "rx-NXDOMAIN" }, - { "SERVFAIL", "dns_rcode", "rx-SERVFAIL" }, - { "FORMERR", "dns_rcode", "rx-FORMERR" }, - { "OtherError", "dns_rcode", "rx-OTHER" }, - { "EDNS0Fail", "dns_rcode", "rx-EDNS0Fail"}, - /* Received responses */ - { "Mismatch", "dns_response", "mismatch" }, - { "Truncated", "dns_response", "truncated" }, - { "Lame", "dns_response", "lame" }, - { "Retry", "dns_query", "retry" }, + { + /* Generic resolver information */ + {"Queryv4", "dns_query", "IPv4"}, + {"Queryv6", "dns_query", "IPv6"}, + {"Responsev4", "dns_response", "IPv4"}, + {"Responsev6", "dns_response", "IPv6"}, + /* Received response codes */ + {"NXDOMAIN", "dns_rcode", "rx-NXDOMAIN"}, + {"SERVFAIL", "dns_rcode", "rx-SERVFAIL"}, + {"FORMERR", "dns_rcode", "rx-FORMERR"}, + {"OtherError", "dns_rcode", "rx-OTHER"}, + {"EDNS0Fail", "dns_rcode", "rx-EDNS0Fail"}, + /* Received responses */ + {"Mismatch", "dns_response", "mismatch"}, + {"Truncated", "dns_response", "truncated"}, + {"Lame", "dns_response", "lame"}, + {"Retry", "dns_query", "retry"}, #if 0 { "GlueFetchv4", "type", "type_instance" }, { "GlueFetchv6", "type", "type_instance" }, { "GlueFetchv4Fail", "type", "type_instance" }, { "GlueFetchv6Fail", "type", "type_instance" }, #endif - /* DNSSEC information */ - { "ValAttempt", "dns_resolver", "DNSSEC-attempt" }, - { "ValOk", "dns_resolver", "DNSSEC-okay" }, - { "ValNegOk", "dns_resolver", "DNSSEC-negokay" }, - { "ValFail", "dns_resolver", "DNSSEC-fail" } -}; + /* DNSSEC information */ + {"ValAttempt", "dns_resolver", "DNSSEC-attempt"}, + {"ValOk", "dns_resolver", "DNSSEC-okay"}, + {"ValNegOk", "dns_resolver", "DNSSEC-negokay"}, + {"ValFail", "dns_resolver", "DNSSEC-fail"}}; static int resstats_translation_table_length = - STATIC_ARRAY_SIZE (resstats_translation_table); + STATIC_ARRAY_SIZE(resstats_translation_table); /* }}} */ /* Translation table for the `memory/summary' values. */ static const translation_info_t memsummary_translation_table[] = /* {{{ */ -{ - { "TotalUse", "memory", "TotalUse" }, - { "InUse", "memory", "InUse" }, - { "BlockSize", "memory", "BlockSize" }, - { "ContextSize", "memory", "ContextSize" }, - { "Lost", "memory", "Lost" } -}; + {{"TotalUse", "memory", "TotalUse"}, + {"InUse", "memory", "InUse"}, + {"BlockSize", "memory", "BlockSize"}, + {"ContextSize", "memory", "ContextSize"}, + {"Lost", "memory", "Lost"}}; static int memsummary_translation_table_length = - STATIC_ARRAY_SIZE (memsummary_translation_table); + STATIC_ARRAY_SIZE(memsummary_translation_table); /* }}} */ -static void submit (time_t ts, const char *plugin_instance, /* {{{ */ - const char *type, const char *type_instance, value_t value) -{ - value_t values[1]; +static void submit(time_t ts, const char *plugin_instance, /* {{{ */ + const char *type, const char *type_instance, value_t value) { value_list_t vl = VALUE_LIST_INIT; - values[0] = value; - - vl.values = values; + vl.values = &value; vl.values_len = 1; if (config_parse_time) - vl.time = TIME_T_TO_CDTIME_T (ts); - sstrncpy(vl.host, hostname_g, sizeof(vl.host)); + vl.time = TIME_T_TO_CDTIME_T(ts); sstrncpy(vl.plugin, "bind", sizeof(vl.plugin)); if (plugin_instance) { - sstrncpy(vl.plugin_instance, plugin_instance, - sizeof(vl.plugin_instance)); - replace_special (vl.plugin_instance, sizeof (vl.plugin_instance)); + sstrncpy(vl.plugin_instance, plugin_instance, sizeof(vl.plugin_instance)); + replace_special(vl.plugin_instance, sizeof(vl.plugin_instance)); } sstrncpy(vl.type, type, sizeof(vl.type)); if (type_instance) { - sstrncpy(vl.type_instance, type_instance, - sizeof(vl.type_instance)); - replace_special (vl.plugin_instance, sizeof (vl.plugin_instance)); + sstrncpy(vl.type_instance, type_instance, sizeof(vl.type_instance)); + replace_special(vl.type_instance, sizeof(vl.type_instance)); } plugin_dispatch_values(&vl); } /* }}} void submit */ -static size_t bind_curl_callback (void *buf, size_t size, /* {{{ */ - size_t nmemb, void __attribute__((unused)) *stream) -{ +static size_t bind_curl_callback(void *buf, size_t size, /* {{{ */ + size_t nmemb, + void __attribute__((unused)) * stream) { size_t len = size * nmemb; - if (len <= 0) - return (len); + if (len == 0) + return len; - if ((bind_buffer_fill + len) >= bind_buffer_size) - { - char *temp; - - temp = realloc(bind_buffer, bind_buffer_fill + len + 1); - if (temp == NULL) - { - ERROR ("bind plugin: realloc failed."); - return (0); + if ((bind_buffer_fill + len) >= bind_buffer_size) { + char *temp = realloc(bind_buffer, bind_buffer_fill + len + 1); + if (temp == NULL) { + ERROR("bind plugin: realloc failed."); + return 0; } bind_buffer = temp; bind_buffer_size = bind_buffer_fill + len + 1; } - memcpy (bind_buffer + bind_buffer_fill, (char *) buf, len); + memcpy(bind_buffer + bind_buffer_fill, (char *)buf, len); bind_buffer_fill += len; bind_buffer[bind_buffer_fill] = 0; - return (len); + return len; } /* }}} size_t bind_curl_callback */ /* * Callback, that's called with a translation table. * (Plugin instance is fixed, type and type instance come from lookup table.) */ -static int bind_xml_table_callback (const char *name, value_t value, /* {{{ */ - time_t current_time, void *user_data) -{ - translation_table_ptr_t *table = (translation_table_ptr_t *) user_data; - size_t i; +static int bind_xml_table_callback(const char *name, value_t value, /* {{{ */ + time_t current_time, void *user_data) { + translation_table_ptr_t *table = (translation_table_ptr_t *)user_data; if (table == NULL) - return (-1); + return -1; - for (i = 0; i < table->table_length; i++) - { - if (strcmp (table->table[i].xml_name, name) != 0) + for (size_t i = 0; i < table->table_length; i++) { + if (strcmp(table->table[i].xml_name, name) != 0) continue; - submit (current_time, - table->plugin_instance, - table->table[i].type, - table->table[i].type_instance, - value); + submit(current_time, table->plugin_instance, table->table[i].type, + table->table[i].type_instance, value); break; } - return (0); + return 0; } /* }}} int bind_xml_table_callback */ /* * Callback, that's used for lists. * (Plugin instance and type are fixed, xml name is used as type instance.) */ -static int bind_xml_list_callback (const char *name, /* {{{ */ - value_t value, time_t current_time, void *user_data) -{ - list_info_ptr_t *list_info = (list_info_ptr_t *) user_data; +static int bind_xml_list_callback(const char *name, /* {{{ */ + value_t value, time_t current_time, + void *user_data) { + list_info_ptr_t *list_info = (list_info_ptr_t *)user_data; if (list_info == NULL) - return (-1); + return -1; - submit (current_time, - list_info->plugin_instance, - list_info->type, - /* type instance = */ name, - value); + submit(current_time, list_info->plugin_instance, list_info->type, + /* type instance = */ name, value); - return (0); + return 0; } /* }}} int bind_xml_list_callback */ -static int bind_xml_read_derive (xmlDoc *doc, xmlNode *node, /* {{{ */ - derive_t *ret_value) -{ - char *str_ptr; - value_t value; - int status; - - str_ptr = (char *) xmlNodeListGetString (doc, node->xmlChildrenNode, 1); - if (str_ptr == NULL) - { - ERROR ("bind plugin: bind_xml_read_derive: xmlNodeListGetString failed."); - return (-1); +static int bind_xml_read_derive(xmlDoc *doc, xmlNode *node, /* {{{ */ + derive_t *ret_value) { + char *str_ptr = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1); + if (str_ptr == NULL) { + ERROR("bind plugin: bind_xml_read_derive: xmlNodeListGetString failed."); + return -1; } - status = parse_value (str_ptr, &value, DS_TYPE_DERIVE); - if (status != 0) - { - ERROR ("bind plugin: Parsing string \"%s\" to derive value failed.", - str_ptr); - return (-1); + value_t value; + + int status = parse_value(str_ptr, &value, DS_TYPE_DERIVE); + if (status != 0) { + xmlFree(str_ptr); + return -1; } + xmlFree(str_ptr); *ret_value = value.derive; - return (0); + return 0; } /* }}} int bind_xml_read_derive */ -static int bind_xml_read_gauge (xmlDoc *doc, xmlNode *node, /* {{{ */ - gauge_t *ret_value) -{ - char *str_ptr, *end_ptr; - double value; - - str_ptr = (char *) xmlNodeListGetString (doc, node->xmlChildrenNode, 1); - if (str_ptr == NULL) - { - ERROR ("bind plugin: bind_xml_read_gauge: xmlNodeListGetString failed."); - return (-1); +static int bind_xml_read_gauge(xmlDoc *doc, xmlNode *node, /* {{{ */ + gauge_t *ret_value) { + char *str_ptr = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1); + if (str_ptr == NULL) { + ERROR("bind plugin: bind_xml_read_gauge: xmlNodeListGetString failed."); + return -1; } + char *end_ptr; errno = 0; - value = strtod (str_ptr, &end_ptr); + double value = strtod(str_ptr, &end_ptr); xmlFree(str_ptr); - if (str_ptr == end_ptr || errno) - { + if (str_ptr == end_ptr || errno) { if (errno && (value < 0)) - ERROR ("bind plugin: bind_xml_read_gauge: strtod failed with underflow."); + ERROR("bind plugin: bind_xml_read_gauge: strtod failed with underflow."); else if (errno && (value > 0)) - ERROR ("bind plugin: bind_xml_read_gauge: strtod failed with overflow."); + ERROR("bind plugin: bind_xml_read_gauge: strtod failed with overflow."); else - ERROR ("bind plugin: bind_xml_read_gauge: strtod failed."); - return (-1); + ERROR("bind plugin: bind_xml_read_gauge: strtod failed."); + return -1; } - *ret_value = (gauge_t) value; - return (0); + *ret_value = (gauge_t)value; + return 0; } /* }}} int bind_xml_read_gauge */ -static int bind_xml_read_timestamp (const char *xpath_expression, /* {{{ */ - xmlDoc *doc, xmlXPathContext *xpathCtx, time_t *ret_value) -{ - xmlXPathObject *xpathObj = NULL; - xmlNode *node; - char *str_ptr; - char *tmp; - struct tm tm; - - xpathObj = xmlXPathEvalExpression (BAD_CAST xpath_expression, xpathCtx); - if (xpathObj == NULL) - { - ERROR ("bind plugin: Unable to evaluate XPath expression `%s'.", - xpath_expression); - return (-1); +static int bind_xml_read_timestamp(const char *xpath_expression, /* {{{ */ + xmlDoc *doc, xmlXPathContext *xpathCtx, + time_t *ret_value) { + xmlXPathObject *xpathObj = + xmlXPathEvalExpression(BAD_CAST xpath_expression, xpathCtx); + if (xpathObj == NULL) { + ERROR("bind plugin: Unable to evaluate XPath expression `%s'.", + xpath_expression); + return -1; } - if ((xpathObj->nodesetval == NULL) || (xpathObj->nodesetval->nodeNr < 1)) - { - xmlXPathFreeObject (xpathObj); - return (-1); + if ((xpathObj->nodesetval == NULL) || (xpathObj->nodesetval->nodeNr < 1)) { + xmlXPathFreeObject(xpathObj); + return -1; } - if (xpathObj->nodesetval->nodeNr != 1) - { - NOTICE ("bind plugin: Evaluating the XPath expression `%s' returned " - "%i nodes. Only handling the first one.", - xpath_expression, xpathObj->nodesetval->nodeNr); + if (xpathObj->nodesetval->nodeNr != 1) { + NOTICE("bind plugin: Evaluating the XPath expression `%s' returned " + "%i nodes. Only handling the first one.", + xpath_expression, xpathObj->nodesetval->nodeNr); } - node = xpathObj->nodesetval->nodeTab[0]; + xmlNode *node = xpathObj->nodesetval->nodeTab[0]; - if (node->xmlChildrenNode == NULL) - { - ERROR ("bind plugin: bind_xml_read_timestamp: " - "node->xmlChildrenNode == NULL"); - xmlXPathFreeObject (xpathObj); - return (-1); + if (node->xmlChildrenNode == NULL) { + ERROR("bind plugin: bind_xml_read_timestamp: " + "node->xmlChildrenNode == NULL"); + xmlXPathFreeObject(xpathObj); + return -1; } - str_ptr = (char *) xmlNodeListGetString (doc, node->xmlChildrenNode, 1); - if (str_ptr == NULL) - { - ERROR ("bind plugin: bind_xml_read_timestamp: xmlNodeListGetString failed."); - xmlXPathFreeObject (xpathObj); - return (-1); + char *str_ptr = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1); + if (str_ptr == NULL) { + ERROR("bind plugin: bind_xml_read_timestamp: xmlNodeListGetString failed."); + xmlXPathFreeObject(xpathObj); + return -1; } - memset (&tm, 0, sizeof(tm)); - tmp = strptime (str_ptr, "%Y-%m-%dT%T", &tm); + struct tm tm = {0}; + char *tmp = strptime(str_ptr, "%Y-%m-%dT%T", &tm); xmlFree(str_ptr); - if (tmp == NULL) - { - ERROR ("bind plugin: bind_xml_read_timestamp: strptime failed."); - xmlXPathFreeObject (xpathObj); - return (-1); + if (tmp == NULL) { + ERROR("bind plugin: bind_xml_read_timestamp: strptime failed."); + xmlXPathFreeObject(xpathObj); + return -1; } - *ret_value = mktime(&tm); +#if HAVE_TIMEGM + time_t t = timegm(&tm); + if (t == ((time_t)-1)) { + ERROR("bind plugin: timegm() failed: %s", STRERRNO); + return -1; + } + *ret_value = t; +#else + time_t t = mktime(&tm); + if (t == ((time_t)-1)) { + ERROR("bind plugin: mktime() failed: %s", STRERRNO); + return -1; + } + /* mktime assumes that tm is local time. Luckily, it also sets timezone to + * the offset used for the conversion, and we undo the conversion to convert + * back to UTC. */ + *ret_value = t - timezone; +#endif - xmlXPathFreeObject (xpathObj); - return (0); + xmlXPathFreeObject(xpathObj); + return 0; } /* }}} int bind_xml_read_timestamp */ -/* +/* * bind_parse_generic_name_value * * Reads statistics in the form: @@ -480,83 +457,75 @@ static int bind_xml_read_timestamp (const char *xpath_expression, /* {{{ */ * 123 * */ -static int bind_parse_generic_name_value (const char *xpath_expression, /* {{{ */ - list_callback_t list_callback, - void *user_data, - xmlDoc *doc, xmlXPathContext *xpathCtx, - time_t current_time, int ds_type) -{ - xmlXPathObject *xpathObj = NULL; - int num_entries; - int i; - - xpathObj = xmlXPathEvalExpression(BAD_CAST xpath_expression, xpathCtx); - if (xpathObj == NULL) - { +static int bind_parse_generic_name_value(const char *xpath_expression, /* {{{ */ + list_callback_t list_callback, + void *user_data, xmlDoc *doc, + xmlXPathContext *xpathCtx, + time_t current_time, int ds_type) { + xmlXPathObject *xpathObj = + xmlXPathEvalExpression(BAD_CAST xpath_expression, xpathCtx); + if (xpathObj == NULL) { ERROR("bind plugin: Unable to evaluate XPath expression `%s'.", - xpath_expression); - return (-1); + xpath_expression); + return -1; } - num_entries = 0; + int num_entries = 0; /* Iterate over all matching nodes. */ - for (i = 0; xpathObj->nodesetval && (i < xpathObj->nodesetval->nodeNr); i++) - { + for (int i = 0; xpathObj->nodesetval && (i < xpathObj->nodesetval->nodeNr); + i++) { + xmlNode *name_node = NULL; xmlNode *counter = NULL; - xmlNode *parent; - xmlNode *child; - parent = xpathObj->nodesetval->nodeTab[i]; - DEBUG ("bind plugin: bind_parse_generic_name_value: parent->name = %s;", - (char *) parent->name); + xmlNode *parent = xpathObj->nodesetval->nodeTab[i]; + DEBUG("bind plugin: bind_parse_generic_name_value: parent->name = %s;", + (char *)parent->name); /* Iterate over all child nodes. */ - for (child = parent->xmlChildrenNode; - child != NULL; - child = child->next) - { + for (xmlNode *child = parent->xmlChildrenNode; child != NULL; + child = child->next) { if (child->type != XML_ELEMENT_NODE) continue; - if (xmlStrcmp (BAD_CAST "name", child->name) == 0) + if (xmlStrcmp(BAD_CAST "name", child->name) == 0) name_node = child; - else if (xmlStrcmp (BAD_CAST "counter", child->name) == 0) + else if (xmlStrcmp(BAD_CAST "counter", child->name) == 0) counter = child; } - if ((name_node != NULL) && (counter != NULL)) - { - char *name = (char *) xmlNodeListGetString (doc, - name_node->xmlChildrenNode, 1); + if ((name_node != NULL) && (counter != NULL)) { + char *name = + (char *)xmlNodeListGetString(doc, name_node->xmlChildrenNode, 1); value_t value; int status; if (ds_type == DS_TYPE_GAUGE) - status = bind_xml_read_gauge (doc, counter, &value.gauge); + status = bind_xml_read_gauge(doc, counter, &value.gauge); else - status = bind_xml_read_derive (doc, counter, &value.derive); - if (status != 0) + status = bind_xml_read_derive(doc, counter, &value.derive); + if (status != 0) { + xmlFree(name); continue; + } - status = (*list_callback) (name, value, current_time, user_data); + status = (*list_callback)(name, value, current_time, user_data); if (status == 0) num_entries++; - xmlFree (name); + xmlFree(name); } } - DEBUG ("bind plugin: Found %d %s for XPath expression `%s'", - num_entries, (num_entries == 1) ? "entry" : "entries", - xpath_expression); + DEBUG("bind plugin: Found %d %s for XPath expression `%s'", num_entries, + (num_entries == 1) ? "entry" : "entries", xpath_expression); xmlXPathFreeObject(xpathObj); - return (0); + return 0; } /* }}} int bind_parse_generic_name_value */ -/* +/* * bind_parse_generic_value_list * * Reads statistics in the form: @@ -567,403 +536,568 @@ static int bind_parse_generic_name_value (const char *xpath_expression, /* {{{ * * : * */ -static int bind_parse_generic_value_list (const char *xpath_expression, /* {{{ */ - list_callback_t list_callback, - void *user_data, - xmlDoc *doc, xmlXPathContext *xpathCtx, - time_t current_time, int ds_type) -{ - xmlXPathObject *xpathObj = NULL; - int num_entries; - int i; - - xpathObj = xmlXPathEvalExpression(BAD_CAST xpath_expression, xpathCtx); - if (xpathObj == NULL) - { +static int bind_parse_generic_value_list(const char *xpath_expression, /* {{{ */ + list_callback_t list_callback, + void *user_data, xmlDoc *doc, + xmlXPathContext *xpathCtx, + time_t current_time, int ds_type) { + xmlXPathObject *xpathObj = + xmlXPathEvalExpression(BAD_CAST xpath_expression, xpathCtx); + if (xpathObj == NULL) { ERROR("bind plugin: Unable to evaluate XPath expression `%s'.", - xpath_expression); - return (-1); + xpath_expression); + return -1; } - num_entries = 0; + int num_entries = 0; /* Iterate over all matching nodes. */ - for (i = 0; xpathObj->nodesetval && (i < xpathObj->nodesetval->nodeNr); i++) - { - xmlNode *child; - + for (int i = 0; xpathObj->nodesetval && (i < xpathObj->nodesetval->nodeNr); + i++) { /* Iterate over all child nodes. */ - for (child = xpathObj->nodesetval->nodeTab[i]->xmlChildrenNode; - child != NULL; - child = child->next) - { - char *node_name; - value_t value; - int status; + for (xmlNode *child = xpathObj->nodesetval->nodeTab[i]->xmlChildrenNode; + child != NULL; child = child->next) { if (child->type != XML_ELEMENT_NODE) continue; - node_name = (char *) child->name; + char *node_name = (char *)child->name; + value_t value; + int status; if (ds_type == DS_TYPE_GAUGE) - status = bind_xml_read_gauge (doc, child, &value.gauge); + status = bind_xml_read_gauge(doc, child, &value.gauge); else - status = bind_xml_read_derive (doc, child, &value.derive); + status = bind_xml_read_derive(doc, child, &value.derive); if (status != 0) continue; - status = (*list_callback) (node_name, value, current_time, user_data); + status = (*list_callback)(node_name, value, current_time, user_data); if (status == 0) num_entries++; } } - DEBUG ("bind plugin: Found %d %s for XPath expression `%s'", - num_entries, (num_entries == 1) ? "entry" : "entries", - xpath_expression); + DEBUG("bind plugin: Found %d %s for XPath expression `%s'", num_entries, + (num_entries == 1) ? "entry" : "entries", xpath_expression); xmlXPathFreeObject(xpathObj); - return (0); + return 0; } /* }}} int bind_parse_generic_value_list */ -static int bind_xml_stats_handle_zone (int version, xmlDoc *doc, /* {{{ */ - xmlXPathContext *path_ctx, xmlNode *node, cb_view_t *view, - time_t current_time) -{ - xmlXPathObject *path_obj; - char *zone_name = NULL; - int i; - size_t j; +/* + * bind_parse_generic_name_attr_value_list + * + * Reads statistics in the form: + * + * 123 + * 234 + * 345 + * : + * + */ +static int bind_parse_generic_name_attr_value_list( + const char *xpath_expression, /* {{{ */ + list_callback_t list_callback, void *user_data, xmlDoc *doc, + xmlXPathContext *xpathCtx, time_t current_time, int ds_type) { + + xmlXPathObject *xpathObj = + xmlXPathEvalExpression(BAD_CAST xpath_expression, xpathCtx); + if (xpathObj == NULL) { + ERROR("bind plugin: Unable to evaluate XPath expression `%s'.", + xpath_expression); + return -1; + } - path_obj = xmlXPathEvalExpression (BAD_CAST "name", path_ctx); - if (path_obj == NULL) - { - ERROR ("bind plugin: xmlXPathEvalExpression failed."); - return (-1); + int num_entries = 0; + /* Iterate over all matching nodes. */ + for (int i = 0; xpathObj->nodesetval && (i < xpathObj->nodesetval->nodeNr); + i++) { + /* Iterate over all child nodes. */ + for (xmlNode *child = xpathObj->nodesetval->nodeTab[i]->xmlChildrenNode; + child != NULL; child = child->next) { + if (child->type != XML_ELEMENT_NODE) + continue; + + if (strncmp("counter", (char *)child->name, strlen("counter")) != 0) + continue; + + char *attr_name = (char *)xmlGetProp(child, BAD_CAST "name"); + if (attr_name == NULL) { + DEBUG("bind plugin: found without name."); + continue; + } + + value_t value; + int status; + + if (ds_type == DS_TYPE_GAUGE) + status = bind_xml_read_gauge(doc, child, &value.gauge); + else + status = bind_xml_read_derive(doc, child, &value.derive); + if (status != 0) { + xmlFree(attr_name); + continue; + } + + status = (*list_callback)(attr_name, value, current_time, user_data); + if (status == 0) + num_entries++; + + xmlFree(attr_name); + } } - for (i = 0; path_obj->nodesetval && (i < path_obj->nodesetval->nodeNr); i++) - { - zone_name = (char *) xmlNodeListGetString (doc, - path_obj->nodesetval->nodeTab[i]->xmlChildrenNode, 1); - if (zone_name != NULL) - break; + DEBUG("bind plugin: Found %d %s for XPath expression `%s'", num_entries, + (num_entries == 1) ? "entry" : "entries", xpath_expression); + + xmlXPathFreeObject(xpathObj); + + return 0; +} /* }}} int bind_parse_generic_name_attr_value_list */ + +static int bind_xml_stats_handle_zone(int version, xmlDoc *doc, /* {{{ */ + xmlXPathContext *path_ctx, xmlNode *node, + cb_view_t *view, time_t current_time) { + char *zone_name = NULL; + + if (version >= 3) { + char *n = (char *)xmlGetProp(node, BAD_CAST "name"); + char *c = (char *)xmlGetProp(node, BAD_CAST "rdataclass"); + if (n && c) { + zone_name = (char *)xmlMalloc(strlen(n) + strlen(c) + 2); + snprintf(zone_name, strlen(n) + strlen(c) + 2, "%s/%s", n, c); + } + xmlFree(n); + xmlFree(c); + } else { + xmlXPathObject *path_obj = + xmlXPathEvalExpression(BAD_CAST "name", path_ctx); + if (path_obj == NULL) { + ERROR("bind plugin: xmlXPathEvalExpression failed."); + return -1; + } + + for (int i = 0; path_obj->nodesetval && (i < path_obj->nodesetval->nodeNr); + i++) { + zone_name = (char *)xmlNodeListGetString( + doc, path_obj->nodesetval->nodeTab[i]->xmlChildrenNode, 1); + if (zone_name != NULL) + break; + } + xmlXPathFreeObject(path_obj); } - if (zone_name == NULL) - { - ERROR ("bind plugin: Could not determine zone name."); - xmlXPathFreeObject (path_obj); - return (-1); + if (zone_name == NULL) { + ERROR("bind plugin: Could not determine zone name."); + return -1; } - for (j = 0; j < view->zones_num; j++) - { - if (strcasecmp (zone_name, view->zones[j]) == 0) + size_t j; + for (j = 0; j < view->zones_num; j++) { + if (strcasecmp(zone_name, view->zones[j]) == 0) break; } - xmlFree (zone_name); - zone_name = NULL; + xmlFree(zone_name); - if (j >= views_num) - { - xmlXPathFreeObject (path_obj); - return (0); - } + if (j >= view->zones_num) + return 0; zone_name = view->zones[j]; - DEBUG ("bind plugin: bind_xml_stats_handle_zone: Found zone `%s'.", - zone_name); + DEBUG("bind plugin: bind_xml_stats_handle_zone: Found zone `%s'.", zone_name); { /* Parse the tag {{{ */ char plugin_instance[DATA_MAX_NAME_LEN]; - translation_table_ptr_t table_ptr = - { - nsstats_translation_table, - nsstats_translation_table_length, - plugin_instance - }; - - ssnprintf (plugin_instance, sizeof (plugin_instance), "%s-zone-%s", - view->name, zone_name); - - bind_parse_generic_value_list (/* xpath = */ "counters", - /* callback = */ bind_xml_table_callback, - /* user_data = */ &table_ptr, - doc, path_ctx, current_time, DS_TYPE_COUNTER); + translation_table_ptr_t table_ptr = {nsstats_translation_table, + nsstats_translation_table_length, + plugin_instance}; + + snprintf(plugin_instance, sizeof(plugin_instance), "%s-zone-%s", view->name, + zone_name); + + if (version == 3) { + list_info_ptr_t list_info = {plugin_instance, + /* type = */ "dns_qtype"}; + bind_parse_generic_name_attr_value_list( + /* xpath = */ "counters[@type='rcode']", + /* callback = */ bind_xml_table_callback, + /* user_data = */ &table_ptr, doc, path_ctx, current_time, + DS_TYPE_COUNTER); + bind_parse_generic_name_attr_value_list( + /* xpath = */ "counters[@type='qtype']", + /* callback = */ bind_xml_list_callback, + /* user_data = */ &list_info, doc, path_ctx, current_time, + DS_TYPE_COUNTER); + } else { + bind_parse_generic_value_list(/* xpath = */ "counters", + /* callback = */ bind_xml_table_callback, + /* user_data = */ &table_ptr, doc, path_ctx, + current_time, DS_TYPE_COUNTER); + } } /* }}} */ - xmlXPathFreeObject (path_obj); - - return (0); + return 0; } /* }}} int bind_xml_stats_handle_zone */ -static int bind_xml_stats_search_zones (int version, xmlDoc *doc, /* {{{ */ - xmlXPathContext *path_ctx, xmlNode *node, cb_view_t *view, - time_t current_time) -{ - xmlXPathObject *zone_nodes = NULL; - xmlXPathContext *zone_path_context; - int i; - - zone_path_context = xmlXPathNewContext (doc); - if (zone_path_context == NULL) - { - ERROR ("bind plugin: xmlXPathNewContext failed."); - return (-1); +static int bind_xml_stats_search_zones(int version, xmlDoc *doc, /* {{{ */ + xmlXPathContext *path_ctx, xmlNode *node, + cb_view_t *view, time_t current_time) { + xmlXPathContext *zone_path_context = xmlXPathNewContext(doc); + if (zone_path_context == NULL) { + ERROR("bind plugin: xmlXPathNewContext failed."); + return -1; } - zone_nodes = xmlXPathEvalExpression (BAD_CAST "zones/zone", path_ctx); - if (zone_nodes == NULL) - { - ERROR ("bind plugin: Cannot find any tags."); - xmlXPathFreeContext (zone_path_context); - return (-1); + xmlXPathObject *zone_nodes = + xmlXPathEvalExpression(BAD_CAST "zones/zone", path_ctx); + if (zone_nodes == NULL) { + ERROR("bind plugin: Cannot find any tags."); + xmlXPathFreeContext(zone_path_context); + return -1; } - for (i = 0; i < zone_nodes->nodesetval->nodeNr; i++) - { - xmlNode *node; - + for (int i = 0; i < zone_nodes->nodesetval->nodeNr; i++) { node = zone_nodes->nodesetval->nodeTab[i]; - assert (node != NULL); + assert(node != NULL); zone_path_context->node = node; - bind_xml_stats_handle_zone (version, doc, zone_path_context, node, view, - current_time); + bind_xml_stats_handle_zone(version, doc, zone_path_context, node, view, + current_time); } - xmlXPathFreeObject (zone_nodes); - xmlXPathFreeContext (zone_path_context); - return (0); + xmlXPathFreeObject(zone_nodes); + xmlXPathFreeContext(zone_path_context); + return 0; } /* }}} int bind_xml_stats_search_zones */ -static int bind_xml_stats_handle_view (int version, xmlDoc *doc, /* {{{ */ - xmlXPathContext *path_ctx, xmlNode *node, time_t current_time) -{ - xmlXPathObject *path_obj; +static int bind_xml_stats_handle_view(int version, xmlDoc *doc, /* {{{ */ + xmlXPathContext *path_ctx, xmlNode *node, + time_t current_time) { char *view_name = NULL; cb_view_t *view; - int i; size_t j; - path_obj = xmlXPathEvalExpression (BAD_CAST "name", path_ctx); - if (path_obj == NULL) - { - ERROR ("bind plugin: xmlXPathEvalExpression failed."); - return (-1); - } + if (version == 3) { + view_name = (char *)xmlGetProp(node, BAD_CAST "name"); - for (i = 0; path_obj->nodesetval && (i < path_obj->nodesetval->nodeNr); i++) - { - view_name = (char *) xmlNodeListGetString (doc, - path_obj->nodesetval->nodeTab[i]->xmlChildrenNode, 1); - if (view_name != NULL) - break; - } + if (view_name == NULL) { + ERROR("bind plugin: Could not determine view name."); + return -1; + } - if (view_name == NULL) - { - ERROR ("bind plugin: Could not determine view name."); - xmlXPathFreeObject (path_obj); - return (-1); - } + for (j = 0; j < views_num; j++) { + if (strcasecmp(view_name, views[j].name) == 0) + break; + } - for (j = 0; j < views_num; j++) - { - if (strcasecmp (view_name, views[j].name) == 0) - break; - } + xmlFree(view_name); + view_name = NULL; + } else { + xmlXPathObject *path_obj = + xmlXPathEvalExpression(BAD_CAST "name", path_ctx); + if (path_obj == NULL) { + ERROR("bind plugin: xmlXPathEvalExpression failed."); + return -1; + } + + for (int i = 0; path_obj->nodesetval && (i < path_obj->nodesetval->nodeNr); + i++) { + view_name = (char *)xmlNodeListGetString( + doc, path_obj->nodesetval->nodeTab[i]->xmlChildrenNode, 1); + if (view_name != NULL) + break; + } - xmlFree (view_name); - xmlXPathFreeObject (path_obj); + if (view_name == NULL) { + ERROR("bind plugin: Could not determine view name."); + xmlXPathFreeObject(path_obj); + return -1; + } - view_name = NULL; - path_obj = NULL; + for (j = 0; j < views_num; j++) { + if (strcasecmp(view_name, views[j].name) == 0) + break; + } + + xmlFree(view_name); + xmlXPathFreeObject(path_obj); + + view_name = NULL; + path_obj = NULL; + } if (j >= views_num) - return (0); + return 0; view = views + j; - DEBUG ("bind plugin: bind_xml_stats_handle_view: Found view `%s'.", - view->name); + DEBUG("bind plugin: bind_xml_stats_handle_view: Found view `%s'.", + view->name); if (view->qtypes != 0) /* {{{ */ { char plugin_instance[DATA_MAX_NAME_LEN]; - list_info_ptr_t list_info = - { - plugin_instance, - /* type = */ "dns_qtype" - }; - - ssnprintf (plugin_instance, sizeof (plugin_instance), "%s-qtypes", - view->name); - - bind_parse_generic_name_value (/* xpath = */ "rdtype", - /* callback = */ bind_xml_list_callback, - /* user_data = */ &list_info, - doc, path_ctx, current_time, DS_TYPE_COUNTER); + list_info_ptr_t list_info = {plugin_instance, + /* type = */ "dns_qtype"}; + + snprintf(plugin_instance, sizeof(plugin_instance), "%s-qtypes", view->name); + if (version == 3) { + bind_parse_generic_name_attr_value_list( + /* xpath = */ "counters[@type='resqtype']", + /* callback = */ bind_xml_list_callback, + /* user_data = */ &list_info, doc, path_ctx, current_time, + DS_TYPE_COUNTER); + } else { + bind_parse_generic_name_value(/* xpath = */ "rdtype", + /* callback = */ bind_xml_list_callback, + /* user_data = */ &list_info, doc, path_ctx, + current_time, DS_TYPE_COUNTER); + } } /* }}} */ if (view->resolver_stats != 0) /* {{{ */ { char plugin_instance[DATA_MAX_NAME_LEN]; - translation_table_ptr_t table_ptr = - { - resstats_translation_table, - resstats_translation_table_length, - plugin_instance - }; - - ssnprintf (plugin_instance, sizeof (plugin_instance), - "%s-resolver_stats", view->name); - - bind_parse_generic_name_value ("resstat", - /* callback = */ bind_xml_table_callback, - /* user_data = */ &table_ptr, - doc, path_ctx, current_time, DS_TYPE_COUNTER); + translation_table_ptr_t table_ptr = {resstats_translation_table, + resstats_translation_table_length, + plugin_instance}; + + snprintf(plugin_instance, sizeof(plugin_instance), "%s-resolver_stats", + view->name); + if (version == 3) { + bind_parse_generic_name_attr_value_list( + "counters[@type='resstats']", + /* callback = */ bind_xml_table_callback, + /* user_data = */ &table_ptr, doc, path_ctx, current_time, + DS_TYPE_COUNTER); + } else { + bind_parse_generic_name_value("resstat", + /* callback = */ bind_xml_table_callback, + /* user_data = */ &table_ptr, doc, path_ctx, + current_time, DS_TYPE_COUNTER); + } } /* }}} */ /* Record types in the cache */ if (view->cacherrsets != 0) /* {{{ */ { char plugin_instance[DATA_MAX_NAME_LEN]; - list_info_ptr_t list_info = - { - plugin_instance, - /* type = */ "dns_qtype_cached" - }; + list_info_ptr_t list_info = {plugin_instance, + /* type = */ "dns_qtype_cached"}; - ssnprintf (plugin_instance, sizeof (plugin_instance), "%s-cache_rr_sets", - view->name); + snprintf(plugin_instance, sizeof(plugin_instance), "%s-cache_rr_sets", + view->name); - bind_parse_generic_name_value (/* xpath = */ "cache/rrset", - /* callback = */ bind_xml_list_callback, - /* user_data = */ &list_info, - doc, path_ctx, current_time, DS_TYPE_GAUGE); + bind_parse_generic_name_value(/* xpath = */ "cache/rrset", + /* callback = */ bind_xml_list_callback, + /* user_data = */ &list_info, doc, path_ctx, + current_time, DS_TYPE_GAUGE); } /* }}} */ if (view->zones_num > 0) - bind_xml_stats_search_zones (version, doc, path_ctx, node, view, - current_time); + bind_xml_stats_search_zones(version, doc, path_ctx, node, view, + current_time); - return (0); + return 0; } /* }}} int bind_xml_stats_handle_view */ -static int bind_xml_stats_search_views (int version, xmlDoc *doc, /* {{{ */ - xmlXPathContext *xpathCtx, xmlNode *statsnode, time_t current_time) -{ - xmlXPathObject *view_nodes = NULL; - xmlXPathContext *view_path_context; - int i; - - view_path_context = xmlXPathNewContext (doc); - if (view_path_context == NULL) - { - ERROR ("bind plugin: xmlXPathNewContext failed."); - return (-1); +static int bind_xml_stats_search_views(int version, xmlDoc *doc, /* {{{ */ + xmlXPathContext *xpathCtx, + time_t current_time) { + xmlXPathContext *view_path_context = xmlXPathNewContext(doc); + if (view_path_context == NULL) { + ERROR("bind plugin: xmlXPathNewContext failed."); + return -1; } - view_nodes = xmlXPathEvalExpression (BAD_CAST "views/view", xpathCtx); - if (view_nodes == NULL) - { - ERROR ("bind plugin: Cannot find any tags."); - xmlXPathFreeContext (view_path_context); - return (-1); + xmlXPathObject *view_nodes = + xmlXPathEvalExpression(BAD_CAST "views/view", xpathCtx); + if (view_nodes == NULL) { + ERROR("bind plugin: Cannot find any tags."); + xmlXPathFreeContext(view_path_context); + return -1; } - for (i = 0; i < view_nodes->nodesetval->nodeNr; i++) - { - xmlNode *node; - - node = view_nodes->nodesetval->nodeTab[i]; - assert (node != NULL); + for (int i = 0; i < view_nodes->nodesetval->nodeNr; i++) { + xmlNode *node = view_nodes->nodesetval->nodeTab[i]; + assert(node != NULL); view_path_context->node = node; - bind_xml_stats_handle_view (version, doc, view_path_context, node, - current_time); + bind_xml_stats_handle_view(version, doc, view_path_context, node, + current_time); } - xmlXPathFreeObject (view_nodes); - xmlXPathFreeContext (view_path_context); - return (0); + xmlXPathFreeObject(view_nodes); + xmlXPathFreeContext(view_path_context); + return 0; } /* }}} int bind_xml_stats_search_views */ -static int bind_xml_stats (int version, xmlDoc *doc, /* {{{ */ - xmlXPathContext *xpathCtx, xmlNode *statsnode) -{ - time_t current_time = 0; - int status; +static void bind_xml_stats_v3(xmlDoc *doc, /* {{{ */ + xmlXPathContext *xpathCtx, time_t current_time) { + /* XPath: server/counters[@type='opcode'] + * Variables: QUERY, IQUERY, NOTIFY, UPDATE, ... + * Layout v3: + * + * 1 + * : + * + */ + if (global_opcodes != 0) { + list_info_ptr_t list_info = {/* plugin instance = */ "global-opcodes", + /* type = */ "dns_opcode"}; + bind_parse_generic_name_attr_value_list( + /* xpath = */ "server/counters[@type='opcode']", + /* callback = */ bind_xml_list_callback, + /* user_data = */ &list_info, doc, xpathCtx, current_time, + DS_TYPE_COUNTER); + } - xpathCtx->node = statsnode; + /* XPath: server/counters[@type='qtype'] + * Variables: RESERVED0, A, NS, CNAME, SOA, MR, PTR, HINFO, MX, TXT, RP, + * X25, PX, AAAA, LOC, SRV, NAPTR, A6, DS, RRSIG, NSEC, DNSKEY, + * SPF, TKEY, IXFR, AXFR, ANY, ..., Others + * Layout v3: + * + * 1 + * : + * + */ + if (global_qtypes != 0) { + list_info_ptr_t list_info = {/* plugin instance = */ "global-qtypes", + /* type = */ "dns_qtype"}; - /* TODO: Check `server/boot-time' to recognize server restarts. */ + bind_parse_generic_name_attr_value_list( + /* xpath = */ "server/counters[@type='qtype']", + /* callback = */ bind_xml_list_callback, + /* user_data = */ &list_info, doc, xpathCtx, current_time, + DS_TYPE_COUNTER); + } - status = bind_xml_read_timestamp ("server/current-time", - doc, xpathCtx, ¤t_time); - if (status != 0) - { - ERROR ("bind plugin: Reading `server/current-time' failed."); - return (-1); + /* XPath: server/counters[@type='nsstat'] + * Variables: Requestv4, Requestv6, ReqEdns0, ReqBadEDNSVer, ReqTSIG, + * ReqSIG0, ReqBadSIG, ReqTCP, AuthQryRej, RecQryRej, XfrRej, + * UpdateRej, Response, TruncatedResp, RespEDNS0, RespTSIG, + * RespSIG0, QrySuccess, QryAuthAns, QryNoauthAns, QryReferral, + * QryNxrrset, QrySERVFAIL, QryFORMERR, QryNXDOMAIN, QryRecursion, + * QryDuplicate, QryDropped, QryFailure, XfrReqDone, UpdateReqFwd, + * UpdateRespFwd, UpdateFwdFail, UpdateDone, UpdateFail, + * UpdateBadPrereq + * Layout v3: + * 1 + * 0 + * : + * + */ + if (global_server_stats) { + translation_table_ptr_t table_ptr = { + nsstats_translation_table, nsstats_translation_table_length, + /* plugin_instance = */ "global-server_stats"}; + + bind_parse_generic_name_attr_value_list( + "server/counters[@type='nsstat']", + /* callback = */ bind_xml_table_callback, + /* user_data = */ &table_ptr, doc, xpathCtx, current_time, + DS_TYPE_COUNTER); + } + + /* XPath: server/zonestats, server/zonestat, + * server/counters[@type='zonestat'] + * Variables: NotifyOutv4, NotifyOutv6, NotifyInv4, NotifyInv6, NotifyRej, + * SOAOutv4, SOAOutv6, AXFRReqv4, AXFRReqv6, IXFRReqv4, IXFRReqv6, + * XfrSuccess, XfrFail + * Layout v3: + * 0 + * 0 + * : + * + */ + if (global_zone_maint_stats) { + translation_table_ptr_t table_ptr = { + zonestats_translation_table, zonestats_translation_table_length, + /* plugin_instance = */ "global-zone_maint_stats"}; + + bind_parse_generic_name_attr_value_list( + "server/counters[@type='zonestat']", + /* callback = */ bind_xml_table_callback, + /* user_data = */ &table_ptr, doc, xpathCtx, current_time, + DS_TYPE_COUNTER); + } + + /* XPath: server/resstats, server/counters[@type='resstat'] + * Variables: Queryv4, Queryv6, Responsev4, Responsev6, NXDOMAIN, SERVFAIL, + * FORMERR, OtherError, EDNS0Fail, Mismatch, Truncated, Lame, + * Retry, GlueFetchv4, GlueFetchv6, GlueFetchv4Fail, + * GlueFetchv6Fail, ValAttempt, ValOk, ValNegOk, ValFail + * Layout v3: + * 0 + * 0 + * : + * + */ + if (global_resolver_stats != 0) { + translation_table_ptr_t table_ptr = { + resstats_translation_table, resstats_translation_table_length, + /* plugin_instance = */ "global-resolver_stats"}; + + bind_parse_generic_name_attr_value_list( + "server/counters[@type='resstat']", + /* callback = */ bind_xml_table_callback, + /* user_data = */ &table_ptr, doc, xpathCtx, current_time, + DS_TYPE_COUNTER); } - DEBUG ("bind plugin: Current server time is %i.", (int) current_time); +} /* }}} bind_xml_stats_v3 */ - /* XPath: server/requests/opcode +static void bind_xml_stats_v1_v2(int version, xmlDoc *doc, /* {{{ */ + xmlXPathContext *xpathCtx, + time_t current_time) { + /* XPath: server/requests/opcode, server/counters[@type='opcode'] * Variables: QUERY, IQUERY, NOTIFY, UPDATE, ... - * Layout: + * Layout V1 and V2: * * A * 1 * * : */ - if (global_opcodes != 0) - { - list_info_ptr_t list_info = - { - /* plugin instance = */ "global-opcodes", - /* type = */ "dns_opcode" - }; - - bind_parse_generic_name_value (/* xpath = */ "server/requests/opcode", - /* callback = */ bind_xml_list_callback, - /* user_data = */ &list_info, - doc, xpathCtx, current_time, DS_TYPE_COUNTER); + if (global_opcodes != 0) { + list_info_ptr_t list_info = {/* plugin instance = */ "global-opcodes", + /* type = */ "dns_opcode"}; + + bind_parse_generic_name_value(/* xpath = */ "server/requests/opcode", + /* callback = */ bind_xml_list_callback, + /* user_data = */ &list_info, doc, xpathCtx, + current_time, DS_TYPE_COUNTER); } - /* XPath: server/queries-in/rdtype + /* XPath: server/queries-in/rdtype, server/counters[@type='qtype'] * Variables: RESERVED0, A, NS, CNAME, SOA, MR, PTR, HINFO, MX, TXT, RP, * X25, PX, AAAA, LOC, SRV, NAPTR, A6, DS, RRSIG, NSEC, DNSKEY, * SPF, TKEY, IXFR, AXFR, ANY, ..., Others - * Layout: + * Layout v1 or v2: * * A * 1 * * : */ - if (global_qtypes != 0) - { - list_info_ptr_t list_info = - { - /* plugin instance = */ "global-qtypes", - /* type = */ "dns_qtype" - }; - - bind_parse_generic_name_value (/* xpath = */ "server/queries-in/rdtype", - /* callback = */ bind_xml_list_callback, - /* user_data = */ &list_info, - doc, xpathCtx, current_time, DS_TYPE_COUNTER); + if (global_qtypes != 0) { + list_info_ptr_t list_info = {/* plugin instance = */ "global-qtypes", + /* type = */ "dns_qtype"}; + + bind_parse_generic_name_value(/* xpath = */ "server/queries-in/rdtype", + /* callback = */ bind_xml_list_callback, + /* user_data = */ &list_info, doc, xpathCtx, + current_time, DS_TYPE_COUNTER); } - - /* XPath: server/nsstats, server/nsstat + + /* XPath: server/nsstats, server/nsstat, server/counters[@type='nsstat'] * Variables: Requestv4, Requestv6, ReqEdns0, ReqBadEDNSVer, ReqTSIG, * ReqSIG0, ReqBadSIG, ReqTCP, AuthQryRej, RecQryRej, XfrRej, * UpdateRej, Response, TruncatedResp, RespEDNS0, RespTSIG, @@ -989,32 +1123,26 @@ static int bind_xml_stats (int version, xmlDoc *doc, /* {{{ */ * * : */ - if (global_server_stats) - { - translation_table_ptr_t table_ptr = - { - nsstats_translation_table, - nsstats_translation_table_length, - /* plugin_instance = */ "global-server_stats" - }; - - if (version == 1) - { - bind_parse_generic_value_list ("server/nsstats", - /* callback = */ bind_xml_table_callback, - /* user_data = */ &table_ptr, - doc, xpathCtx, current_time, DS_TYPE_COUNTER); - } - else - { - bind_parse_generic_name_value ("server/nsstat", - /* callback = */ bind_xml_table_callback, - /* user_data = */ &table_ptr, - doc, xpathCtx, current_time, DS_TYPE_COUNTER); + if (global_server_stats) { + translation_table_ptr_t table_ptr = { + nsstats_translation_table, nsstats_translation_table_length, + /* plugin_instance = */ "global-server_stats"}; + + if (version == 1) { + bind_parse_generic_value_list("server/nsstats", + /* callback = */ bind_xml_table_callback, + /* user_data = */ &table_ptr, doc, xpathCtx, + current_time, DS_TYPE_COUNTER); + } else { + bind_parse_generic_name_value("server/nsstat", + /* callback = */ bind_xml_table_callback, + /* user_data = */ &table_ptr, doc, xpathCtx, + current_time, DS_TYPE_COUNTER); } } - /* XPath: server/zonestats, server/zonestat + /* XPath: server/zonestats, server/zonestat, + * server/counters[@type='zonestat'] * Variables: NotifyOutv4, NotifyOutv6, NotifyInv4, NotifyInv6, NotifyRej, * SOAOutv4, SOAOutv6, AXFRReqv4, AXFRReqv6, IXFRReqv4, IXFRReqv6, * XfrSuccess, XfrFail @@ -1035,32 +1163,25 @@ static int bind_xml_stats (int version, xmlDoc *doc, /* {{{ */ * * : */ - if (global_zone_maint_stats) - { - translation_table_ptr_t table_ptr = - { - zonestats_translation_table, - zonestats_translation_table_length, - /* plugin_instance = */ "global-zone_maint_stats" - }; - - if (version == 1) - { - bind_parse_generic_value_list ("server/zonestats", - /* callback = */ bind_xml_table_callback, - /* user_data = */ &table_ptr, - doc, xpathCtx, current_time, DS_TYPE_COUNTER); - } - else - { - bind_parse_generic_name_value ("server/zonestat", - /* callback = */ bind_xml_table_callback, - /* user_data = */ &table_ptr, - doc, xpathCtx, current_time, DS_TYPE_COUNTER); + if (global_zone_maint_stats) { + translation_table_ptr_t table_ptr = { + zonestats_translation_table, zonestats_translation_table_length, + /* plugin_instance = */ "global-zone_maint_stats"}; + + if (version == 1) { + bind_parse_generic_value_list("server/zonestats", + /* callback = */ bind_xml_table_callback, + /* user_data = */ &table_ptr, doc, xpathCtx, + current_time, DS_TYPE_COUNTER); + } else { + bind_parse_generic_name_value("server/zonestat", + /* callback = */ bind_xml_table_callback, + /* user_data = */ &table_ptr, doc, xpathCtx, + current_time, DS_TYPE_COUNTER); } } - /* XPath: server/resstats + /* XPath: server/resstats, server/counters[@type='resstat'] * Variables: Queryv4, Queryv6, Responsev4, Responsev6, NXDOMAIN, SERVFAIL, * FORMERR, OtherError, EDNS0Fail, Mismatch, Truncated, Lame, * Retry, GlueFetchv4, GlueFetchv6, GlueFetchv4Fail, @@ -1082,34 +1203,50 @@ static int bind_xml_stats (int version, xmlDoc *doc, /* {{{ */ * * : */ - if (global_resolver_stats != 0) - { - translation_table_ptr_t table_ptr = - { - resstats_translation_table, - resstats_translation_table_length, - /* plugin_instance = */ "global-resolver_stats" - }; - - if (version == 1) - { - bind_parse_generic_value_list ("server/resstats", - /* callback = */ bind_xml_table_callback, - /* user_data = */ &table_ptr, - doc, xpathCtx, current_time, DS_TYPE_COUNTER); - } - else - { - bind_parse_generic_name_value ("server/resstat", - /* callback = */ bind_xml_table_callback, - /* user_data = */ &table_ptr, - doc, xpathCtx, current_time, DS_TYPE_COUNTER); + if (global_resolver_stats != 0) { + translation_table_ptr_t table_ptr = { + resstats_translation_table, resstats_translation_table_length, + /* plugin_instance = */ "global-resolver_stats"}; + + if (version == 1) { + bind_parse_generic_value_list("server/resstats", + /* callback = */ bind_xml_table_callback, + /* user_data = */ &table_ptr, doc, xpathCtx, + current_time, DS_TYPE_COUNTER); + } else { + bind_parse_generic_name_value("server/resstat", + /* callback = */ bind_xml_table_callback, + /* user_data = */ &table_ptr, doc, xpathCtx, + current_time, DS_TYPE_COUNTER); } } +} /* }}} bind_xml_stats_v1_v2 */ + +static int bind_xml_stats(int version, xmlDoc *doc, /* {{{ */ + xmlXPathContext *xpathCtx, xmlNode *statsnode) { + time_t current_time = 0; + + xpathCtx->node = statsnode; + + /* TODO: Check `server/boot-time' to recognize server restarts. */ + + int status = bind_xml_read_timestamp("server/current-time", doc, xpathCtx, + ¤t_time); + if (status != 0) { + ERROR("bind plugin: Reading `server/current-time' failed."); + return -1; + } + DEBUG("bind plugin: Current server time is %i.", (int)current_time); + + if (version == 3) { + bind_xml_stats_v3(doc, xpathCtx, current_time); + } else { + bind_xml_stats_v1_v2(version, doc, xpathCtx, current_time); + } /* XPath: memory/summary * Variables: TotalUse, InUse, BlockSize, ContextSize, Lost - * Layout: v2: + * Layout: v2 and v3: * * 6587096 * 1345424 @@ -1118,334 +1255,333 @@ static int bind_xml_stats (int version, xmlDoc *doc, /* {{{ */ * 0 * */ - if (global_memory_stats != 0) - { - translation_table_ptr_t table_ptr = - { - memsummary_translation_table, - memsummary_translation_table_length, - /* plugin_instance = */ "global-memory_stats" - }; - - bind_parse_generic_value_list ("memory/summary", - /* callback = */ bind_xml_table_callback, - /* user_data = */ &table_ptr, - doc, xpathCtx, current_time, DS_TYPE_GAUGE); + if (global_memory_stats != 0) { + translation_table_ptr_t table_ptr = { + memsummary_translation_table, memsummary_translation_table_length, + /* plugin_instance = */ "global-memory_stats"}; + + bind_parse_generic_value_list("memory/summary", + /* callback = */ bind_xml_table_callback, + /* user_data = */ &table_ptr, doc, xpathCtx, + current_time, DS_TYPE_GAUGE); } if (views_num > 0) - bind_xml_stats_search_views (version, doc, xpathCtx, statsnode, - current_time); + bind_xml_stats_search_views(version, doc, xpathCtx, current_time); return 0; } /* }}} int bind_xml_stats */ -static int bind_xml (const char *data) /* {{{ */ +static int bind_xml(const char *data) /* {{{ */ { - xmlDoc *doc = NULL; - xmlXPathContext *xpathCtx = NULL; - xmlXPathObject *xpathObj = NULL; int ret = -1; - int i; - doc = xmlParseMemory (data, strlen (data)); - if (doc == NULL) - { - ERROR ("bind plugin: xmlParseMemory failed."); - return (-1); + xmlDoc *doc = xmlParseMemory(data, strlen(data)); + if (doc == NULL) { + ERROR("bind plugin: xmlParseMemory failed."); + return -1; } - xpathCtx = xmlXPathNewContext (doc); - if (xpathCtx == NULL) - { - ERROR ("bind plugin: xmlXPathNewContext failed."); - xmlFreeDoc (doc); - return (-1); + xmlXPathContext *xpathCtx = xmlXPathNewContext(doc); + if (xpathCtx == NULL) { + ERROR("bind plugin: xmlXPathNewContext failed."); + xmlFreeDoc(doc); + return -1; } - xpathObj = xmlXPathEvalExpression (BAD_CAST "/isc/bind/statistics", xpathCtx); - if (xpathObj == NULL) - { - ERROR ("bind plugin: Cannot find the tag."); - xmlXPathFreeContext (xpathCtx); - xmlFreeDoc (doc); - return (-1); + // + // version 3.* of statistics XML (since BIND9.9) + // + + xmlXPathObject *xpathObj = + xmlXPathEvalExpression(BAD_CAST "/statistics", xpathCtx); + if (xpathObj == NULL || xpathObj->nodesetval == NULL || + xpathObj->nodesetval->nodeNr == 0) { + DEBUG("bind plugin: Statistics appears not to be v3"); + // we will fallback to v1 or v2 detection + if (xpathObj != NULL) { + xmlXPathFreeObject(xpathObj); + } + } else { + for (int i = 0; i < xpathObj->nodesetval->nodeNr; i++) { + xmlNode *node; + char *attr_version; + + node = xpathObj->nodesetval->nodeTab[i]; + assert(node != NULL); + + attr_version = (char *)xmlGetProp(node, BAD_CAST "version"); + if (attr_version == NULL) { + NOTICE("bind plugin: Found tag doesn't have a " + "`version' attribute."); + continue; + } + DEBUG("bind plugin: Found: ", attr_version); + + if (strncmp("3.", attr_version, strlen("3.")) != 0) { + /* TODO: Use the complaint mechanism here. */ + NOTICE("bind plugin: Found tag with version `%s'. " + "Unfortunately I have no clue how to parse that. " + "Please open a bug report for this.", + attr_version); + xmlFree(attr_version); + continue; + } + ret = bind_xml_stats(3, doc, xpathCtx, node); + + xmlFree(attr_version); + /* One node ought to be enough. */ + break; + } + + // we are finished, early-return + xmlXPathFreeObject(xpathObj); + xmlXPathFreeContext(xpathCtx); + xmlFreeDoc(doc); + + return ret; } - else if (xpathObj->nodesetval == NULL) - { - ERROR ("bind plugin: xmlXPathEvalExpression failed."); - xmlXPathFreeObject (xpathObj); - xmlXPathFreeContext (xpathCtx); - xmlFreeDoc (doc); - return (-1); + + // + // versions 1.* or 2.* of statistics XML + // + + xpathObj = xmlXPathEvalExpression(BAD_CAST "/isc/bind/statistics", xpathCtx); + if (xpathObj == NULL) { + ERROR("bind plugin: Cannot find the tag."); + xmlXPathFreeContext(xpathCtx); + xmlFreeDoc(doc); + return -1; + } else if (xpathObj->nodesetval == NULL) { + ERROR("bind plugin: xmlXPathEvalExpression failed."); + xmlXPathFreeObject(xpathObj); + xmlXPathFreeContext(xpathCtx); + xmlFreeDoc(doc); + return -1; } - for (i = 0; i < xpathObj->nodesetval->nodeNr; i++) - { + for (int i = 0; i < xpathObj->nodesetval->nodeNr; i++) { xmlNode *node; char *attr_version; int parsed_version = 0; node = xpathObj->nodesetval->nodeTab[i]; - assert (node != NULL); + assert(node != NULL); - attr_version = (char *) xmlGetProp (node, BAD_CAST "version"); - if (attr_version == NULL) - { - NOTICE ("bind plugin: Found tag doesn't have a " - "`version' attribute."); + attr_version = (char *)xmlGetProp(node, BAD_CAST "version"); + if (attr_version == NULL) { + NOTICE("bind plugin: Found tag doesn't have a " + "`version' attribute."); continue; } - DEBUG ("bind plugin: Found: ", attr_version); + DEBUG("bind plugin: Found: ", attr_version); /* At the time this plugin was written, version "1.0" was used by * BIND 9.5.0, version "2.0" was used by BIND 9.5.1 and 9.6.0. We assume * that "1.*" and "2.*" don't introduce structural changes, so we just * check for the first two characters here. */ - if (strncmp ("1.", attr_version, strlen ("1.")) == 0) + if (strncmp("1.", attr_version, strlen("1.")) == 0) parsed_version = 1; - else if (strncmp ("2.", attr_version, strlen ("2.")) == 0) + else if (strncmp("2.", attr_version, strlen("2.")) == 0) parsed_version = 2; - else - { + else { /* TODO: Use the complaint mechanism here. */ - NOTICE ("bind plugin: Found tag with version `%s'. " - "Unfortunately I have no clue how to parse that. " - "Please open a bug report for this.", attr_version); - xmlFree (attr_version); + NOTICE("bind plugin: Found tag with version `%s'. " + "Unfortunately I have no clue how to parse that. " + "Please open a bug report for this.", + attr_version); + xmlFree(attr_version); continue; } - ret = bind_xml_stats (parsed_version, - doc, xpathCtx, node); + ret = bind_xml_stats(parsed_version, doc, xpathCtx, node); - xmlFree (attr_version); + xmlFree(attr_version); /* One node ought to be enough. */ break; } - xmlXPathFreeObject (xpathObj); - xmlXPathFreeContext (xpathCtx); - xmlFreeDoc (doc); + xmlXPathFreeObject(xpathObj); + xmlXPathFreeContext(xpathCtx); + xmlFreeDoc(doc); - return (ret); + return ret; } /* }}} int bind_xml */ -static int bind_config_set_bool (const char *name, int *var, /* {{{ */ - oconfig_item_t *ci) -{ - if ((ci->values_num != 1) || ( ci->values[0].type != OCONFIG_TYPE_BOOLEAN)) - { - WARNING ("bind plugin: The `%s' option needs " - "exactly one boolean argument.", name); - return (-1); - } - - if (ci->values[0].value.boolean) - *var = 1; - else - *var = 0; - return 0; -} /* }}} int bind_config_set_bool */ - -static int bind_config_add_view_zone (cb_view_t *view, /* {{{ */ - oconfig_item_t *ci) -{ - char **tmp; - - if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING)) - { - WARNING ("bind plugin: The `Zone' option needs " - "exactly one string argument."); - return (-1); +static int bind_config_add_view_zone(cb_view_t *view, /* {{{ */ + oconfig_item_t *ci) { + if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING)) { + WARNING("bind plugin: The `Zone' option needs " + "exactly one string argument."); + return -1; } - tmp = (char **) realloc (view->zones, - sizeof (char *) * (view->zones_num + 1)); - if (tmp == NULL) - { - ERROR ("bind plugin: realloc failed."); - return (-1); + char **tmp = realloc(view->zones, sizeof(char *) * (view->zones_num + 1)); + if (tmp == NULL) { + ERROR("bind plugin: realloc failed."); + return -1; } view->zones = tmp; - view->zones[view->zones_num] = strdup (ci->values[0].value.string); - if (view->zones[view->zones_num] == NULL) - { - ERROR ("bind plugin: strdup failed."); - return (-1); + view->zones[view->zones_num] = strdup(ci->values[0].value.string); + if (view->zones[view->zones_num] == NULL) { + ERROR("bind plugin: strdup failed."); + return -1; } view->zones_num++; - return (0); + return 0; } /* }}} int bind_config_add_view_zone */ -static int bind_config_add_view (oconfig_item_t *ci) /* {{{ */ +static int bind_config_add_view(oconfig_item_t *ci) /* {{{ */ { - cb_view_t *tmp; - int i; - - if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING)) - { - WARNING ("bind plugin: `View' blocks need exactly one string argument."); - return (-1); + if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING)) { + WARNING("bind plugin: `View' blocks need exactly one string argument."); + return -1; } - tmp = (cb_view_t *) realloc (views, sizeof (*views) * (views_num + 1)); - if (tmp == NULL) - { - ERROR ("bind plugin: realloc failed."); - return (-1); + cb_view_t *tmp = realloc(views, sizeof(*views) * (views_num + 1)); + if (tmp == NULL) { + ERROR("bind plugin: realloc failed."); + return -1; } views = tmp; tmp = views + views_num; - memset (tmp, 0, sizeof (*tmp)); + memset(tmp, 0, sizeof(*tmp)); tmp->qtypes = 1; tmp->resolver_stats = 1; tmp->cacherrsets = 1; tmp->zones = NULL; tmp->zones_num = 0; - tmp->name = strdup (ci->values[0].value.string); - if (tmp->name == NULL) - { - ERROR ("bind plugin: strdup failed."); - free (tmp); - return (-1); + tmp->name = strdup(ci->values[0].value.string); + if (tmp->name == NULL) { + ERROR("bind plugin: strdup failed."); + sfree(views); + return -1; } - for (i = 0; i < ci->children_num; i++) - { + for (int i = 0; i < ci->children_num; i++) { oconfig_item_t *child = ci->children + i; - if (strcasecmp ("QTypes", child->key) == 0) - bind_config_set_bool ("QTypes", &tmp->qtypes, child); - else if (strcasecmp ("ResolverStats", child->key) == 0) - bind_config_set_bool ("ResolverStats", &tmp->resolver_stats, child); - else if (strcasecmp ("CacheRRSets", child->key) == 0) - bind_config_set_bool ("CacheRRSets", &tmp->cacherrsets, child); - else if (strcasecmp ("Zone", child->key) == 0) - bind_config_add_view_zone (tmp, child); - else - { - WARNING ("bind plugin: Unknown configuration option " - "`%s' in view `%s' will be ignored.", child->key, tmp->name); + if (strcasecmp("QTypes", child->key) == 0) + cf_util_get_boolean(child, &tmp->qtypes); + else if (strcasecmp("ResolverStats", child->key) == 0) + cf_util_get_boolean(child, &tmp->resolver_stats); + else if (strcasecmp("CacheRRSets", child->key) == 0) + cf_util_get_boolean(child, &tmp->cacherrsets); + else if (strcasecmp("Zone", child->key) == 0) + bind_config_add_view_zone(tmp, child); + else { + WARNING("bind plugin: Unknown configuration option " + "`%s' in view `%s' will be ignored.", + child->key, tmp->name); } } /* for (i = 0; i < ci->children_num; i++) */ views_num++; - return (0); + return 0; } /* }}} int bind_config_add_view */ -static int bind_config (oconfig_item_t *ci) /* {{{ */ +static int bind_config(oconfig_item_t *ci) /* {{{ */ { - int i; - - for (i = 0; i < ci->children_num; i++) - { + for (int i = 0; i < ci->children_num; i++) { oconfig_item_t *child = ci->children + i; - if (strcasecmp ("Url", child->key) == 0) { - if ((child->values_num != 1) || (child->values[0].type != OCONFIG_TYPE_STRING)) - { - WARNING ("bind plugin: The `Url' option needs " - "exactly one string argument."); - return (-1); - } - - url = strdup (child->values[0].value.string); - } else if (strcasecmp ("OpCodes", child->key) == 0) - bind_config_set_bool ("OpCodes", &global_opcodes, child); - else if (strcasecmp ("QTypes", child->key) == 0) - bind_config_set_bool ("QTypes", &global_qtypes, child); - else if (strcasecmp ("ServerStats", child->key) == 0) - bind_config_set_bool ("ServerStats", &global_server_stats, child); - else if (strcasecmp ("ZoneMaintStats", child->key) == 0) - bind_config_set_bool ("ZoneMaintStats", &global_zone_maint_stats, child); - else if (strcasecmp ("ResolverStats", child->key) == 0) - bind_config_set_bool ("ResolverStats", &global_resolver_stats, child); - else if (strcasecmp ("MemoryStats", child->key) == 0) - bind_config_set_bool ("MemoryStats", &global_memory_stats, child); - else if (strcasecmp ("View", child->key) == 0) - bind_config_add_view (child); - else if (strcasecmp ("ParseTime", child->key) == 0) - cf_util_get_boolean (child, &config_parse_time); - else - { - WARNING ("bind plugin: Unknown configuration option " - "`%s' will be ignored.", child->key); + if (strcasecmp("Url", child->key) == 0) { + cf_util_get_string(child, &url); + } else if (strcasecmp("OpCodes", child->key) == 0) + cf_util_get_boolean(child, &global_opcodes); + else if (strcasecmp("QTypes", child->key) == 0) + cf_util_get_boolean(child, &global_qtypes); + else if (strcasecmp("ServerStats", child->key) == 0) + cf_util_get_boolean(child, &global_server_stats); + else if (strcasecmp("ZoneMaintStats", child->key) == 0) + cf_util_get_boolean(child, &global_zone_maint_stats); + else if (strcasecmp("ResolverStats", child->key) == 0) + cf_util_get_boolean(child, &global_resolver_stats); + else if (strcasecmp("MemoryStats", child->key) == 0) + cf_util_get_boolean(child, &global_memory_stats); + else if (strcasecmp("View", child->key) == 0) + bind_config_add_view(child); + else if (strcasecmp("ParseTime", child->key) == 0) + cf_util_get_boolean(child, &config_parse_time); + else if (strcasecmp("Timeout", child->key) == 0) + cf_util_get_int(child, &timeout); + else { + WARNING("bind plugin: Unknown configuration option " + "`%s' will be ignored.", + child->key); } } - return (0); + return 0; } /* }}} int bind_config */ -static int bind_init (void) /* {{{ */ +static int bind_init(void) /* {{{ */ { if (curl != NULL) - return (0); + return 0; - curl = curl_easy_init (); - if (curl == NULL) - { - ERROR ("bind plugin: bind_init: curl_easy_init failed."); - return (-1); + curl = curl_easy_init(); + if (curl == NULL) { + ERROR("bind plugin: bind_init: curl_easy_init failed."); + return -1; } - curl_easy_setopt (curl, CURLOPT_NOSIGNAL, 1L); - curl_easy_setopt (curl, CURLOPT_WRITEFUNCTION, bind_curl_callback); - curl_easy_setopt (curl, CURLOPT_USERAGENT, PACKAGE_NAME"/"PACKAGE_VERSION); - curl_easy_setopt (curl, CURLOPT_ERRORBUFFER, bind_curl_error); - curl_easy_setopt (curl, CURLOPT_URL, (url != NULL) ? url : BIND_DEFAULT_URL); - curl_easy_setopt (curl, CURLOPT_FOLLOWLOCATION, 1L); - curl_easy_setopt (curl, CURLOPT_MAXREDIRS, 50L); + curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1L); + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, bind_curl_callback); + curl_easy_setopt(curl, CURLOPT_USERAGENT, COLLECTD_USERAGENT); + curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, bind_curl_error); + curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L); + 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())); +#endif - return (0); + return 0; } /* }}} int bind_init */ -static int bind_read (void) /* {{{ */ +static int bind_read(void) /* {{{ */ { - int status; - - if (curl == NULL) - { - ERROR ("bind plugin: I don't have a CURL object."); - return (-1); + if (curl == NULL) { + ERROR("bind plugin: I don't have a CURL object."); + return -1; } bind_buffer_fill = 0; - if (curl_easy_perform (curl) != CURLE_OK) - { - ERROR ("bind plugin: curl_easy_perform failed: %s", - bind_curl_error); - return (-1); + + curl_easy_setopt(curl, CURLOPT_URL, (url != NULL) ? url : BIND_DEFAULT_URL); + + if (curl_easy_perform(curl) != CURLE_OK) { + ERROR("bind plugin: curl_easy_perform failed: %s", bind_curl_error); + return -1; } - status = bind_xml (bind_buffer); + int status = bind_xml(bind_buffer); if (status != 0) - return (-1); + return -1; else - return (0); + return 0; } /* }}} int bind_read */ -static int bind_shutdown (void) /* {{{ */ +static int bind_shutdown(void) /* {{{ */ { - if (curl != NULL) - { - curl_easy_cleanup (curl); + if (curl != NULL) { + curl_easy_cleanup(curl); curl = NULL; } - return (0); + return 0; } /* }}} int bind_shutdown */ -void module_register (void) -{ - plugin_register_complex_config ("bind", bind_config); - plugin_register_init ("bind", bind_init); - plugin_register_read ("bind", bind_read); - plugin_register_shutdown ("bind", bind_shutdown); +void module_register(void) { + plugin_register_complex_config("bind", bind_config); + plugin_register_init("bind", bind_init); + plugin_register_read("bind", bind_read); + plugin_register_shutdown("bind", bind_shutdown); } /* void module_register */ - -/* vim: set sw=2 sts=2 ts=8 et fdm=marker : */ diff --git a/src/buddyinfo.c b/src/buddyinfo.c new file mode 100644 index 0000000000..26e593fbf7 --- /dev/null +++ b/src/buddyinfo.c @@ -0,0 +1,134 @@ +/** + * collectd - src/buddyinfo.c + * Copyright (C) 2019 Asaf Kahlon + * + * 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: + * Asaf Kahlon + **/ + +#include "collectd.h" + +#include "plugin.h" +#include "utils/common/common.h" +#include "utils/ignorelist/ignorelist.h" + +#if !KERNEL_LINUX +#error "No applicable input method." +#endif + +#include + +#define MAX_ORDER 11 +#define BUDDYINFO_FIELDS \ + MAX_ORDER + 4 // "Node" + node_num + "zone" + Name + (MAX_ORDER entries) +#define NUM_OF_KB(pagesize, order) ((pagesize) / 1024) * (1 << (order)) + +static const char *config_keys[] = {"Zone"}; +static int config_keys_num = STATIC_ARRAY_SIZE(config_keys); + +static ignorelist_t *ignorelist; + +static int buddyinfo_config(const char *key, const char *value) { + if (ignorelist == NULL) { + ignorelist = ignorelist_create(1); + if (ignorelist == NULL) { + ERROR("buddyinfo plugin: ignorelist_create failed"); + return -ENOMEM; + } + } + + if (strcasecmp(key, "Zone") == 0) { + if (ignorelist_add(ignorelist, value)) { + ERROR("buddyinfo plugin: cannot add value to ignorelist"); + return -1; + } + } else { + ERROR("buddyinfo plugin: invalid option: %s", key); + return -1; + } + + return 0; +} + +static void buddyinfo_submit(const char *zone_fullname, const char *zone, + const char *size, const int freepages) { + value_list_t vl = VALUE_LIST_INIT; + value_t value = {.gauge = freepages}; + + if (ignorelist_match(ignorelist, zone) != 0) + return; + + vl.values = &value; + vl.values_len = 1; + sstrncpy(vl.plugin, "buddyinfo", sizeof(vl.plugin)); + sstrncpy(vl.plugin_instance, zone_fullname, sizeof(vl.plugin_instance)); + sstrncpy(vl.type, "freepages", sizeof(vl.type)); + sstrncpy(vl.type_instance, size, sizeof(vl.type_instance)); + + plugin_dispatch_values(&vl); +} + +static int buddyinfo_read(void) { + FILE *fh; + char buffer[1024], pagesize_kb[8], zone_fullname[16]; + char *dummy, *zone; + char *fields[BUDDYINFO_FIELDS]; + int node_num, numfields, pagesize = getpagesize(); + + if ((fh = fopen("/proc/buddyinfo", "r")) == NULL) { + WARNING("buddyinfo plugin: fopen: %s", STRERRNO); + return -1; + } + + while (fgets(buffer, sizeof(buffer), fh) != NULL) { + if (!(dummy = strstr(buffer, "Node"))) + continue; + + numfields = strsplit(dummy, fields, BUDDYINFO_FIELDS); + if (numfields != BUDDYINFO_FIELDS) { + WARNING("line %s doesn't contain %d orders, skipping...", buffer, + MAX_ORDER); + continue; + } + + node_num = atoi(fields[1]); + zone = fields[3]; + ssnprintf(zone_fullname, sizeof(zone_fullname), "Node%d/%s", node_num, + zone); + for (int i = 1; i <= MAX_ORDER; i++) { + ssnprintf(pagesize_kb, sizeof(pagesize_kb), "%dKB", + NUM_OF_KB(pagesize, i - 1)); + buddyinfo_submit(zone_fullname, zone, pagesize_kb, atoi(fields[i + 3])); + } + } + + fclose(fh); + return 0; +} + +static int buddyinfo_shutdown(void) { + ignorelist_free(ignorelist); + + return 0; +} + +void module_register(void) { + + plugin_register_config("buddyinfo", buddyinfo_config, config_keys, + config_keys_num); + plugin_register_read("buddyinfo", buddyinfo_read); + plugin_register_shutdown("buddy", buddyinfo_shutdown); +} diff --git a/src/capabilities.c b/src/capabilities.c new file mode 100644 index 0000000000..5c27e6a3a1 --- /dev/null +++ b/src/capabilities.c @@ -0,0 +1,413 @@ +/* + * MIT License + * + * Copyright(c) 2019 Intel Corporation. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * Authors: + * Kamil Wiatrowski + * + */ + +#include "collectd.h" + +#include "plugin.h" +#include "utils/common/common.h" +#include "utils/dmi/dmi.h" + +#include + +#include +#include + +#define CAP_PLUGIN "capabilities" +#define CONTENT_TYPE_JSON "application/json" +#define LISTEN_BACKLOG 16 + +typedef struct dmi_type_name_s { + dmi_type type; + const char *name; +} dmi_type_name_t; + +static char *g_cap_json = NULL; +static char *httpd_host = NULL; +static unsigned short httpd_port = 9104; +static struct MHD_Daemon *httpd; + +static dmi_type_name_t types_list[] = { + {BIOS, "BIOS"}, + {SYSTEM, "SYSTEM"}, + {BASEBOARD, "BASEBOARD"}, + {PROCESSOR, "PROCESSORS"}, + {CACHE, "CACHE"}, + {PHYSICAL_MEMORY_ARRAY, "PHYSICAL MEMORY ARRAYS"}, + {MEMORY_DEVICE, "MEMORY DEVICES"}, + {IPMI_DEVICE, "IPMI DEVICE"}, + {ONBOARD_DEVICES_EXTENDED_INFORMATION, + "ONBOARD DEVICES EXTENDED INFORMATION"}}; + +static int cap_get_dmi_variables(json_t *parent, const dmi_type type, + const char *json_name) { + DEBUG(CAP_PLUGIN ": cap_get_dmi_variables: %d/%s.", type, json_name); + dmi_reader_t reader; + if (dmi_reader_init(&reader, type) != DMI_OK) { + ERROR(CAP_PLUGIN ": dmi_reader_init failed."); + return -1; + } + + json_t *section = NULL; + json_t *entries = NULL; + json_t *attributes = NULL; + json_t *arr = json_array(); + if (arr == NULL) { + ERROR(CAP_PLUGIN ": Failed to allocate json array."); + dmi_reader_clean(&reader); + return -1; + } + if (json_object_set_new(parent, json_name, arr)) { + ERROR(CAP_PLUGIN ": Failed to set array to parent."); + dmi_reader_clean(&reader); + return -1; + } + + while (reader.current_type != DMI_ENTRY_END) { + int status = dmi_read_next(&reader); + if (status != DMI_OK) { + ERROR(CAP_PLUGIN ": dmi_read_next failed."); + return -1; + } + + switch (reader.current_type) { + + case DMI_ENTRY_NAME: + DEBUG("%s", reader.name); + attributes = NULL; + section = json_object(); + if (section == NULL) { + ERROR(CAP_PLUGIN ": Failed to allocate json object."); + dmi_reader_clean(&reader); + return -1; + } + if (json_array_append_new(arr, section)) { + ERROR(CAP_PLUGIN ": Failed to append json entry."); + dmi_reader_clean(&reader); + return -1; + } + entries = json_object(); + if (entries == NULL) { + ERROR(CAP_PLUGIN ": Failed to allocate json object."); + dmi_reader_clean(&reader); + return -1; + } + if (json_object_set_new(section, reader.name, entries)) { + ERROR(CAP_PLUGIN ": Failed to set json entry."); + dmi_reader_clean(&reader); + return -1; + } + break; + + case DMI_ENTRY_MAP: + DEBUG(" %s:%s", reader.name, reader.value); + attributes = NULL; + if (entries == NULL) { + ERROR(CAP_PLUGIN ": unexpected dmi output format."); + dmi_reader_clean(&reader); + return -1; + } + if (json_object_set_new(entries, reader.name, + json_string(reader.value))) { + ERROR(CAP_PLUGIN ": Failed to set json object for entries."); + dmi_reader_clean(&reader); + return -1; + } + break; + + case DMI_ENTRY_LIST_NAME: + DEBUG(" %s:", reader.name); + if (entries == NULL) { + ERROR(CAP_PLUGIN ": unexpected dmi output format."); + dmi_reader_clean(&reader); + return -1; + } + attributes = json_array(); + if (attributes == NULL) { + ERROR(CAP_PLUGIN ": Failed to allocate json array for attributes."); + dmi_reader_clean(&reader); + return -1; + } + if (json_object_set_new(entries, reader.name, attributes)) { + ERROR(CAP_PLUGIN ": Failed to set json object for entry %s.", + reader.name); + dmi_reader_clean(&reader); + return -1; + } + break; + + case DMI_ENTRY_LIST_VALUE: + DEBUG(" %s", reader.value); + if (attributes == NULL) { + ERROR(CAP_PLUGIN ": unexpected dmi output format"); + dmi_reader_clean(&reader); + return -1; + } + if (json_array_append_new(attributes, json_string(reader.value))) { + ERROR(CAP_PLUGIN ": Failed to append json attribute."); + dmi_reader_clean(&reader); + return -1; + } + break; + + default: + section = NULL; + entries = NULL; + attributes = NULL; + break; + } + } + + return 0; +} + +/* http_handler is the callback called by the microhttpd library. It essentially + * handles all HTTP request aspects and creates an HTTP response. */ +static int cap_http_handler(void *cls, struct MHD_Connection *connection, + const char *url, const char *method, + const char *version, const char *upload_data, + size_t *upload_data_size, void **connection_state) { + if (strcmp(method, MHD_HTTP_METHOD_GET) != 0) { + return MHD_NO; + } + + /* On the first call for each connection, return without anything further. + * The first time only the headers are valid, do not respond in the first + * round. The docs are not very specific on the issue. */ + if (*connection_state == NULL) { + /* set to a random non-NULL pointer. */ + *connection_state = &(int){44}; + return MHD_YES; + } + DEBUG(CAP_PLUGIN ": formatted response: %s", g_cap_json); + +#if defined(MHD_VERSION) && MHD_VERSION >= 0x00090500 + struct MHD_Response *res = MHD_create_response_from_buffer( + strlen(g_cap_json), g_cap_json, MHD_RESPMEM_PERSISTENT); +#else + struct MHD_Response *res = + MHD_create_response_from_data(strlen(g_cap_json), g_cap_json, 0, 0); +#endif + if (res == NULL) { + ERROR(CAP_PLUGIN ": MHD create response failed."); + return MHD_NO; + } + + MHD_add_response_header(res, MHD_HTTP_HEADER_CONTENT_TYPE, CONTENT_TYPE_JSON); + int status = MHD_queue_response(connection, MHD_HTTP_OK, res); + + MHD_destroy_response(res); + + return status; +} + +static void cap_logger(__attribute__((unused)) void *arg, char const *fmt, + va_list ap) { + char errbuf[1024]; + vsnprintf(errbuf, sizeof(errbuf), fmt, ap); + + ERROR(CAP_PLUGIN ": libmicrohttpd: %s", errbuf); +} + +#if defined(MHD_VERSION) && MHD_VERSION >= 0x00090000 +static int cap_open_socket() { + char service[NI_MAXSERV]; + snprintf(service, sizeof(service), "%hu", httpd_port); + + struct addrinfo *res; + int status = getaddrinfo(httpd_host, service, + &(struct addrinfo){ + .ai_flags = AI_PASSIVE | AI_ADDRCONFIG, + .ai_family = PF_INET, + .ai_socktype = SOCK_STREAM, + }, + &res); + if (status != 0) { + return -1; + } + + int fd = -1; + for (struct addrinfo *ai = res; ai != NULL; ai = ai->ai_next) { + int flags = ai->ai_socktype; +#ifdef SOCK_CLOEXEC + flags |= SOCK_CLOEXEC; +#endif + + fd = socket(ai->ai_family, flags, 0); + if (fd == -1) + continue; + + if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &(int){1}, sizeof(int)) != 0) { + WARNING(CAP_PLUGIN ": setsockopt(SO_REUSEADDR) failed: %s", STRERRNO); + close(fd); + fd = -1; + continue; + } + + if (bind(fd, ai->ai_addr, ai->ai_addrlen) != 0) { + INFO(CAP_PLUGIN ": bind failed: %s", STRERRNO); + close(fd); + fd = -1; + continue; + } + + if (listen(fd, LISTEN_BACKLOG) != 0) { + INFO(CAP_PLUGIN ": listen failed: %s", STRERRNO); + close(fd); + fd = -1; + continue; + } + + char str_node[NI_MAXHOST]; + char str_service[NI_MAXSERV]; + + getnameinfo(ai->ai_addr, ai->ai_addrlen, str_node, sizeof(str_node), + str_service, sizeof(str_service), + NI_NUMERICHOST | NI_NUMERICSERV); + + INFO(CAP_PLUGIN ": Listening on [%s]:%s.", str_node, str_service); + break; + } + + freeaddrinfo(res); + + return fd; +} +#endif + +static struct MHD_Daemon *cap_start_daemon() { +#if defined(MHD_VERSION) && MHD_VERSION >= 0x00090000 + int fd = cap_open_socket(); + if (fd == -1) { + ERROR(CAP_PLUGIN ": Opening a listening socket for [%s]:%hu failed.", + (httpd_host != NULL) ? httpd_host : "0.0.0.0", httpd_port); + return NULL; + } +#endif + unsigned int flags = MHD_USE_THREAD_PER_CONNECTION | MHD_USE_DEBUG; +#if defined(MHD_VERSION) && MHD_VERSION >= 0x00095300 + flags |= MHD_USE_POLL_INTERNAL_THREAD; +#endif + + struct MHD_Daemon *d = MHD_start_daemon( + flags, httpd_port, NULL, NULL, cap_http_handler, NULL, +#if defined(MHD_VERSION) && MHD_VERSION >= 0x00090000 + MHD_OPTION_LISTEN_SOCKET, fd, +#endif + MHD_OPTION_EXTERNAL_LOGGER, cap_logger, NULL, MHD_OPTION_END); + + if (d == NULL) + ERROR(CAP_PLUGIN ": MHD_start_daemon() failed."); + + return d; +} + +static int cap_config(oconfig_item_t *ci) { + int status = 0; + for (int i = 0; i < ci->children_num; i++) { + oconfig_item_t *child = ci->children + i; + + if (strcasecmp("Host", child->key) == 0) { +#if defined(MHD_VERSION) && MHD_VERSION >= 0x00090000 + status = cf_util_get_string(child, &httpd_host); +#else + ERROR(CAP_PLUGIN ": Option `Host' not supported. Please upgrade " + "libmicrohttpd to at least 0.9.0"); + status = -1; +#endif + } else if (strcasecmp("Port", child->key) == 0) { + int port = cf_util_get_port_number(child); + if (port > 0) + httpd_port = (unsigned short)port; + else { + ERROR(CAP_PLUGIN ": Wrong port number, correct range is 1-65535."); + status = -1; + } + } else { + ERROR(CAP_PLUGIN ": Unknown configuration option \"%s\".", child->key); + status = -1; + } + + if (status) { + ERROR(CAP_PLUGIN ": Invalid configuration parameter \"%s\".", child->key); + sfree(httpd_host); + break; + } + } + + return status; +} + +static int cap_shutdown() { + if (httpd != NULL) { + MHD_stop_daemon(httpd); + httpd = NULL; + } + + sfree(httpd_host); + sfree(g_cap_json); + return 0; +} + +static int cap_init(void) { + json_t *root = json_object(); + if (root == NULL) { + ERROR(CAP_PLUGIN ": Failed to allocate json root."); + cap_shutdown(); + return -1; + } + + for (int i = 0; i < STATIC_ARRAY_SIZE(types_list); i++) + if (cap_get_dmi_variables(root, types_list[i].type, types_list[i].name)) { + json_decref(root); + cap_shutdown(); + return -1; + } + + g_cap_json = json_dumps(root, JSON_COMPACT); + json_decref(root); + + if (g_cap_json == NULL) { + ERROR(CAP_PLUGIN ": json_dumps() failed."); + cap_shutdown(); + return -1; + } + + httpd = cap_start_daemon(); + if (httpd == NULL) { + cap_shutdown(); + return -1; + } + + return 0; +} + +void module_register(void) { + plugin_register_complex_config(CAP_PLUGIN, cap_config); + plugin_register_init(CAP_PLUGIN, cap_init); + plugin_register_shutdown(CAP_PLUGIN, cap_shutdown); +} diff --git a/src/capabilities_test.c b/src/capabilities_test.c new file mode 100644 index 0000000000..16061d294a --- /dev/null +++ b/src/capabilities_test.c @@ -0,0 +1,283 @@ +/* + * collectd - src/capabilities_test.c + * + * Copyright(c) 2019 Intel Corporation. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * Authors: + * Kamil Wiatrowski + */ + +#include "capabilities.c" /* sic */ +#include "testing.h" + +#define RESULT_STRING_JSON \ + "{\"TEST_TYPE\":[{\"Name\":{\"MapName1\":\"MapValue1\",\"ListName1\":[" \ + "\"ListValue1\",\"ListValue2\"],\"MapName2\":\"MapValue2\"}},{\"Name\":{" \ + "\"MapName1\":\"MapValue1\"}}]}" + +static int idx = 0; +static char *test_dmi[][2] = {{NULL, NULL}, + {"Name", NULL}, + {"MapName1", "MapValue1"}, + {"ListName1", NULL}, + {NULL, "ListValue1"}, + {NULL, "ListValue2"}, + {"MapName2", "MapValue2"}, + {NULL, NULL}, + {"Name", NULL}, + {"MapName1", "MapValue1"}, + {NULL, NULL}}; +static entry_type entry[] = { + DMI_ENTRY_NONE, DMI_ENTRY_NAME, DMI_ENTRY_MAP, + DMI_ENTRY_LIST_NAME, DMI_ENTRY_LIST_VALUE, DMI_ENTRY_LIST_VALUE, + DMI_ENTRY_MAP, DMI_ENTRY_NONE, DMI_ENTRY_NAME, + DMI_ENTRY_MAP, DMI_ENTRY_END}; +static size_t len = STATIC_ARRAY_SIZE(entry); + +static struct MHD_Response *mhd_res = NULL; + +/* mock functions */ +int dmi_reader_init(dmi_reader_t *reader, const dmi_type type) { + reader->current_type = DMI_ENTRY_NONE; + return DMI_OK; +} + +void dmi_reader_clean(dmi_reader_t *reader) {} + +int dmi_read_next(dmi_reader_t *reader) { + if (idx >= len) + return DMI_ERROR; + reader->current_type = entry[idx]; + reader->name = test_dmi[idx][0]; + reader->value = test_dmi[idx][1]; + idx++; + return DMI_OK; +} + +struct MHD_Daemon *MHD_start_daemon(unsigned int flags, unsigned short port, + MHD_AcceptPolicyCallback apc, void *apc_cls, + MHD_AccessHandlerCallback dh, void *dh_cls, + ...) { + return NULL; +} + +void MHD_stop_daemon(struct MHD_Daemon *daemon) {} + +struct MHD_Response * +MHD_create_response_from_buffer(size_t size, void *data, + enum MHD_ResponseMemoryMode mode) { + return mhd_res; +} + +struct MHD_Response *MHD_create_response_from_data(size_t size, void *data, + int must_free, + int must_copy) { + return mhd_res; +} + +int MHD_add_response_header(struct MHD_Response *response, const char *header, + const char *content) { + return 0; +} + +int MHD_queue_response(struct MHD_Connection *connection, + unsigned int status_code, + struct MHD_Response *response) { + return MHD_HTTP_OK; +} + +void MHD_destroy_response(struct MHD_Response *response) {} +/* end mock functions */ + +DEF_TEST(plugin_config) { + oconfig_item_t test_cfg_parent = {"capabilities", NULL, 0, NULL, NULL, 0}; + char value_buff[256] = "1234"; + char key_buff[256] = "port"; + oconfig_value_t test_cfg_value = {{value_buff}, OCONFIG_TYPE_STRING}; + oconfig_item_t test_cfg = { + key_buff, &test_cfg_value, 1, &test_cfg_parent, NULL, 0}; + + test_cfg_parent.children = &test_cfg; + test_cfg_parent.children_num = 1; + + int ret = cap_config(&test_cfg_parent); + EXPECT_EQ_INT(0, ret); + EXPECT_EQ_INT(1234, httpd_port); + OK(NULL == httpd_host); + + strncpy(value_buff, "1", STATIC_ARRAY_SIZE(value_buff)); + ret = cap_config(&test_cfg_parent); + EXPECT_EQ_INT(0, ret); + EXPECT_EQ_INT(1, httpd_port); + + strncpy(value_buff, "65535", STATIC_ARRAY_SIZE(value_buff)); + ret = cap_config(&test_cfg_parent); + EXPECT_EQ_INT(0, ret); + EXPECT_EQ_INT(65535, httpd_port); + +#if defined(MHD_VERSION) && MHD_VERSION >= 0x00090000 + strncpy(value_buff, "127.0.0.1", STATIC_ARRAY_SIZE(value_buff)); + strncpy(key_buff, "host", STATIC_ARRAY_SIZE(key_buff)); + + ret = cap_config(&test_cfg_parent); + EXPECT_EQ_INT(0, ret); + EXPECT_EQ_STR("127.0.0.1", httpd_host); + EXPECT_EQ_INT(65535, httpd_port); + + free(httpd_host); + strncpy(key_buff, "port", STATIC_ARRAY_SIZE(key_buff)); +#endif + + double port_value = 65535; + oconfig_value_t test_cfg_value2 = {{.number = port_value}, + OCONFIG_TYPE_NUMBER}; + test_cfg.values = &test_cfg_value2; + ret = cap_config(&test_cfg_parent); + EXPECT_EQ_INT(0, ret); + EXPECT_EQ_INT(65535, httpd_port); + + return 0; +} + +DEF_TEST(plugin_config_fail) { + oconfig_item_t test_cfg_parent = {"capabilities", NULL, 0, NULL, NULL, 0}; + char value_buff[256] = "1"; + char key_buff[256] = "aport"; + oconfig_value_t test_cfg_value = {{value_buff}, OCONFIG_TYPE_STRING}; + oconfig_item_t test_cfg = { + key_buff, &test_cfg_value, 1, &test_cfg_parent, NULL, 0}; + + test_cfg_parent.children = &test_cfg; + test_cfg_parent.children_num = 1; + + unsigned short default_port = httpd_port; + int ret = cap_config(&test_cfg_parent); + EXPECT_EQ_INT(-1, ret); + EXPECT_EQ_INT(default_port, httpd_port); + OK(NULL == httpd_host); + + /* Correct port range is 1 - 65535 */ + strncpy(key_buff, "port", STATIC_ARRAY_SIZE(key_buff)); + strncpy(value_buff, "-1", STATIC_ARRAY_SIZE(value_buff)); + ret = cap_config(&test_cfg_parent); + EXPECT_EQ_INT(-1, ret); + EXPECT_EQ_INT(default_port, httpd_port); + OK(NULL == httpd_host); + + strncpy(value_buff, "65536", STATIC_ARRAY_SIZE(value_buff)); + ret = cap_config(&test_cfg_parent); + EXPECT_EQ_INT(-1, ret); + EXPECT_EQ_INT(default_port, httpd_port); + OK(NULL == httpd_host); + +#if defined(MHD_VERSION) && MHD_VERSION >= 0x00090000 + strncpy(value_buff, "127.0.0.1", STATIC_ARRAY_SIZE(value_buff)); + strncpy(key_buff, "host", STATIC_ARRAY_SIZE(key_buff)); + test_cfg_value.type = OCONFIG_TYPE_NUMBER; + ret = cap_config(&test_cfg_parent); + EXPECT_EQ_INT(-1, ret); + EXPECT_EQ_INT(default_port, httpd_port); + OK(NULL == httpd_host); + + strncpy(key_buff, "port", STATIC_ARRAY_SIZE(key_buff)); +#endif + + double port_value = 65536; + oconfig_value_t test_cfg_value2 = {{.number = port_value}, + OCONFIG_TYPE_NUMBER}; + test_cfg.values = &test_cfg_value2; + ret = cap_config(&test_cfg_parent); + EXPECT_EQ_INT(-1, ret); + EXPECT_EQ_INT(default_port, httpd_port); + OK(NULL == httpd_host); + + return 0; +} + +DEF_TEST(http_handler) { + void *state = NULL; + g_cap_json = "TEST"; + int ret = cap_http_handler(NULL, NULL, NULL, MHD_HTTP_METHOD_PUT, NULL, NULL, + NULL, &state); + EXPECT_EQ_INT(MHD_NO, ret); + OK(NULL == state); + + ret = cap_http_handler(NULL, NULL, NULL, MHD_HTTP_METHOD_GET, NULL, NULL, + NULL, &state); + EXPECT_EQ_INT(MHD_YES, ret); + CHECK_NOT_NULL(state); + + ret = cap_http_handler(NULL, NULL, NULL, MHD_HTTP_METHOD_GET, NULL, NULL, + NULL, &state); + EXPECT_EQ_INT(MHD_NO, ret); + CHECK_NOT_NULL(state); + + /* mock not NULL pointer */ + mhd_res = (struct MHD_Response *)&(int){0}; + ret = cap_http_handler(NULL, NULL, NULL, MHD_HTTP_METHOD_GET, NULL, NULL, + NULL, &state); + EXPECT_EQ_INT(MHD_HTTP_OK, ret); + CHECK_NOT_NULL(state); + + g_cap_json = NULL; + mhd_res = NULL; + + return 0; +} + +DEF_TEST(get_dmi_variables) { + json_t *root = json_object(); + CHECK_NOT_NULL(root); + + int ret = cap_get_dmi_variables(root, 0, "TEST_TYPE"); + EXPECT_EQ_INT(0, ret); + + char *test_str = json_dumps(root, JSON_COMPACT | JSON_PRESERVE_ORDER); + CHECK_NOT_NULL(test_str); + json_decref(root); + EXPECT_EQ_STR(RESULT_STRING_JSON, test_str); + + free(test_str); + + root = json_object(); + CHECK_NOT_NULL(root); + ret = cap_get_dmi_variables(root, 1, "TEST_TYPE2"); + EXPECT_EQ_INT(-1, ret); + + test_str = json_dumps(root, JSON_COMPACT | JSON_PRESERVE_ORDER); + CHECK_NOT_NULL(test_str); + json_decref(root); + EXPECT_EQ_STR("{\"TEST_TYPE2\":[]}", test_str); + + free(test_str); + + return 0; +} + +int main(void) { + RUN_TEST(plugin_config_fail); + RUN_TEST(plugin_config); + + RUN_TEST(http_handler); + RUN_TEST(get_dmi_variables); + + END_TEST; +} diff --git a/src/ceph.c b/src/ceph.c new file mode 100644 index 0000000000..8048f5ddcf --- /dev/null +++ b/src/ceph.c @@ -0,0 +1,1459 @@ +/** + * collectd - src/ceph.c + * Copyright (C) 2011 New Dream Network + * Copyright (C) 2015 Florian octo Forster + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; only version 2 of the License is applicable. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * Authors: + * Colin McCabe + * Dennis Zou + * Dan Ryder + * Florian octo Forster + **/ + +#define _DEFAULT_SOURCE +#define _BSD_SOURCE + +#include "collectd.h" + +#include "plugin.h" +#include "utils/common/common.h" + +#include +#include +#include +#include +#if HAVE_YAJL_YAJL_VERSION_H +#include +#endif +#ifdef HAVE_SYS_CAPABILITY_H +#include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define RETRY_AVGCOUNT -1 + +#if defined(YAJL_MAJOR) && (YAJL_MAJOR > 1) +#define HAVE_YAJL_V2 1 +#endif + +#define RETRY_ON_EINTR(ret, expr) \ + while (1) { \ + ret = expr; \ + if (ret >= 0) \ + break; \ + ret = -errno; \ + if (ret != -EINTR) \ + break; \ + } + +/** Timeout interval in seconds */ +#define CEPH_TIMEOUT_INTERVAL 1 + +/** Maximum path length for a UNIX domain socket on this system */ +#define UNIX_DOMAIN_SOCK_PATH_MAX (sizeof(((struct sockaddr_un *)0)->sun_path)) + +/** Yajl callback returns */ +#define CEPH_CB_CONTINUE 1 +#define CEPH_CB_ABORT 0 + +#if HAVE_YAJL_V2 +typedef size_t yajl_len_t; +#else +typedef unsigned int yajl_len_t; +#endif + +/** Number of types for ceph defined in types.db */ +#define CEPH_DSET_TYPES_NUM 3 +/** ceph types enum */ +enum ceph_dset_type_d { + DSET_LATENCY = 0, + DSET_BYTES = 1, + DSET_RATE = 2, + DSET_TYPE_UNFOUND = 1000 +}; + +/** Valid types for ceph defined in types.db */ +static const char *const ceph_dset_types[CEPH_DSET_TYPES_NUM] = { + "ceph_latency", "ceph_bytes", "ceph_rate"}; + +/******* ceph_daemon *******/ +struct ceph_daemon { + /** Version of the admin_socket interface */ + uint32_t version; + /** daemon name **/ + char name[DATA_MAX_NAME_LEN]; + + /** Path to the socket that we use to talk to the ceph daemon */ + char asok_path[UNIX_DOMAIN_SOCK_PATH_MAX]; + + /** Number of counters */ + int ds_num; + /** Track ds types */ + uint32_t *ds_types; + /** Track ds names to match with types */ + char **ds_names; + + /** + * Keep track of last data for latency values so we can calculate rate + * since last poll. + */ + struct last_data **last_poll_data; + /** index of last poll data */ + int last_idx; +}; + +/******* JSON parsing *******/ +typedef int (*node_handler_t)(void *, const char *, const char *); + +/** Track state and handler while parsing JSON */ +struct yajl_struct { + node_handler_t handler; + void *handler_arg; + + char *key; + char *stack[YAJL_MAX_DEPTH]; + size_t depth; +}; +typedef struct yajl_struct yajl_struct; + +enum perfcounter_type_d { + PERFCOUNTER_LATENCY = 0x4, + PERFCOUNTER_DERIVE = 0x8, +}; + +/** Give user option to use default (long run = since daemon started) avg */ +static int long_run_latency_avg; + +/** + * Give user option to use default type for special cases - + * filestore.journal_wr_bytes is currently only metric here. Ceph reports the + * type as a sum/count pair and will calculate it the same as a latency value. + * All other "bytes" metrics (excluding the used/capacity bytes for the OSD) + * use the DERIVE type. Unless user specifies to use given type, convert this + * metric to use DERIVE. + */ +static int convert_special_metrics = 1; + +/** Array of daemons to monitor */ +static struct ceph_daemon **g_daemons; + +/** Number of elements in g_daemons */ +static size_t g_num_daemons; + +/** + * A set of data that we build up in memory while parsing the JSON. + */ +struct values_tmp { + /** ceph daemon we are processing data for*/ + struct ceph_daemon *d; + /** track avgcount across counters for avgcount/sum latency pairs */ + uint64_t avgcount; + /** current index of counters - used to get type of counter */ + int index; + /** + * similar to index, but current index of latency type counters - + * used to get last poll data of counter + */ + int latency_index; + /** + * values list - maintain across counters since + * host/plugin/plugin instance are always the same + */ + value_list_t vlist; +}; + +/** + * A set of count/sum pairs to keep track of latency types and get difference + * between this poll data and last poll data. + */ +struct last_data { + char ds_name[DATA_MAX_NAME_LEN]; + double last_sum; + uint64_t last_count; +}; + +/******* network I/O *******/ +enum cstate_t { + CSTATE_UNCONNECTED = 0, + CSTATE_WRITE_REQUEST, + CSTATE_READ_VERSION, + CSTATE_READ_AMT, + CSTATE_READ_JSON, +}; + +enum request_type_t { + ASOK_REQ_VERSION = 0, + ASOK_REQ_DATA = 1, + ASOK_REQ_SCHEMA = 2, + ASOK_REQ_NONE = 1000, +}; + +struct cconn { + /** The Ceph daemon that we're talking to */ + struct ceph_daemon *d; + + /** Request type */ + uint32_t request_type; + + /** The connection state */ + enum cstate_t state; + + /** The socket we use to talk to this daemon */ + int asok; + + /** The amount of data remaining to read / write. */ + uint32_t amt; + + /** Length of the JSON to read */ + uint32_t json_len; + + /** Buffer containing JSON data */ + unsigned char *json; + + /** Keep data important to yajl processing */ + struct yajl_struct yajl; +}; + +static int ceph_cb_null(void *ctx) { return CEPH_CB_CONTINUE; } + +static int ceph_cb_boolean(void *ctx, int bool_val) { return CEPH_CB_CONTINUE; } + +#define BUFFER_ADD(dest, src) \ + do { \ + size_t dest_size = sizeof(dest); \ + size_t dest_len = strlen(dest); \ + if (dest_size > dest_len) { \ + sstrncpy((dest) + dest_len, (src), dest_size - dest_len); \ + } \ + (dest)[dest_size - 1] = '\0'; \ + } while (0) + +static int ceph_cb_number(void *ctx, const char *number_val, + yajl_len_t number_len) { + yajl_struct *state = (yajl_struct *)ctx; + char buffer[number_len + 1]; + char key[2 * DATA_MAX_NAME_LEN] = {0}; + int status; + + memcpy(buffer, number_val, number_len); + buffer[sizeof(buffer) - 1] = '\0'; + + for (size_t i = 0; i < state->depth; i++) { + if (state->stack[i] == NULL) + continue; + + if (strlen(key) != 0) + BUFFER_ADD(key, "."); + BUFFER_ADD(key, state->stack[i]); + } + + /* Super-special case for filestore.journal_wr_bytes.avgcount: For + * some reason, Ceph schema encodes this as a count/sum pair while all + * other "Bytes" data (excluding used/capacity bytes for OSD space) uses + * a single "Derive" type. To spare further confusion, keep this KPI as + * the same type of other "Bytes". Instead of keeping an "average" or + * "rate", use the "sum" in the pair and assign that to the derive + * value. */ + if (convert_special_metrics && (state->depth > 2) && + state->stack[state->depth - 2] && + (strcmp("filestore", state->stack[state->depth - 2]) == 0) && + state->stack[state->depth - 1] && + (strcmp("journal_wr_bytes", state->stack[state->depth - 1]) == 0) && + (strcmp("avgcount", state->key) == 0)) { + DEBUG("ceph plugin: Skipping avgcount for filestore.JournalWrBytes"); + return CEPH_CB_CONTINUE; + } + + BUFFER_ADD(key, "."); + BUFFER_ADD(key, state->key); + + status = state->handler(state->handler_arg, buffer, key); + + if (status != 0) { + ERROR("ceph plugin: JSON handler failed with status %d.", status); + return CEPH_CB_ABORT; + } + + return CEPH_CB_CONTINUE; +} + +static int ceph_cb_string(void *ctx, const unsigned char *string_val, + yajl_len_t string_len) { + return CEPH_CB_CONTINUE; +} + +static int ceph_cb_start_map(void *ctx) { + yajl_struct *state = (yajl_struct *)ctx; + + /* Push key to the stack */ + if (state->depth == YAJL_MAX_DEPTH) + return CEPH_CB_ABORT; + + state->stack[state->depth] = state->key; + state->depth++; + state->key = NULL; + + return CEPH_CB_CONTINUE; +} + +static int ceph_cb_end_map(void *ctx) { + yajl_struct *state = (yajl_struct *)ctx; + + /* Pop key from the stack */ + if (state->depth == 0) + return CEPH_CB_ABORT; + + sfree(state->key); + state->depth--; + state->key = state->stack[state->depth]; + state->stack[state->depth] = NULL; + + return CEPH_CB_CONTINUE; +} + +static int ceph_cb_map_key(void *ctx, const unsigned char *key, + yajl_len_t string_len) { + yajl_struct *state = (yajl_struct *)ctx; + size_t sz = ((size_t)string_len) + 1; + + sfree(state->key); + state->key = malloc(sz); + if (state->key == NULL) { + ERROR("ceph plugin: malloc failed."); + return CEPH_CB_ABORT; + } + + memmove(state->key, key, sz - 1); + state->key[sz - 1] = '\0'; + + return CEPH_CB_CONTINUE; +} + +static int ceph_cb_start_array(void *ctx) { return CEPH_CB_CONTINUE; } + +static int ceph_cb_end_array(void *ctx) { return CEPH_CB_CONTINUE; } + +static yajl_callbacks callbacks = {ceph_cb_null, + ceph_cb_boolean, + NULL, + NULL, + ceph_cb_number, + ceph_cb_string, + ceph_cb_start_map, + ceph_cb_map_key, + ceph_cb_end_map, + ceph_cb_start_array, + ceph_cb_end_array}; + +static void ceph_daemon_print(const struct ceph_daemon *d) { + DEBUG("ceph plugin: name=%s, asok_path=%s", d->name, d->asok_path); +} + +static void ceph_daemons_print(void) { + for (size_t i = 0; i < g_num_daemons; ++i) { + ceph_daemon_print(g_daemons[i]); + } +} + +static void ceph_daemon_free(struct ceph_daemon *d) { + for (int i = 0; i < d->last_idx; i++) { + sfree(d->last_poll_data[i]); + } + sfree(d->last_poll_data); + d->last_poll_data = NULL; + d->last_idx = 0; + + for (int i = 0; i < d->ds_num; i++) { + sfree(d->ds_names[i]); + } + sfree(d->ds_types); + sfree(d->ds_names); + sfree(d); +} + +/* compact_ds_name removed the special characters ":", "_", "-" and "+" from the + * input string. Characters following these special characters are capitalized. + * Trailing "+" and "-" characters are replaces with the strings "Plus" and + * "Minus". */ +static int compact_ds_name(char *buffer, size_t buffer_size, char const *src) { + char *src_copy; + size_t src_len; + char *ptr = buffer; + size_t ptr_size = buffer_size; + bool append_plus = false; + bool append_minus = false; + + if ((buffer == NULL) || (buffer_size <= strlen("Minus")) || (src == NULL)) + return EINVAL; + + src_copy = strdup(src); + src_len = strlen(src); + + /* Remove trailing "+" and "-". */ + if (src_copy[src_len - 1] == '+') { + append_plus = true; + src_len--; + src_copy[src_len] = 0; + } else if (src_copy[src_len - 1] == '-') { + append_minus = true; + src_len--; + src_copy[src_len] = 0; + } + + /* Split at special chars, capitalize first character, append to buffer. */ + char *dummy = src_copy; + char *token; + char *save_ptr = NULL; + while ((token = strtok_r(dummy, ":_-+", &save_ptr)) != NULL) { + size_t len; + + dummy = NULL; + + token[0] = toupper((int)token[0]); + + assert(ptr_size > 1); + + len = strlen(token); + if (len >= ptr_size) + len = ptr_size - 1; + + assert(len > 0); + assert(len < ptr_size); + + sstrncpy(ptr, token, len + 1); + ptr += len; + ptr_size -= len; + + assert(*ptr == 0); + if (ptr_size <= 1) + break; + } + + /* Append "Plus" or "Minus" if "+" or "-" has been stripped above. */ + if (append_plus || append_minus) { + char const *append = "Plus"; + if (append_minus) + append = "Minus"; + + size_t offset = buffer_size - (strlen(append) + 1); + if (offset > strlen(buffer)) + offset = strlen(buffer); + + sstrncpy(buffer + offset, append, buffer_size - offset); + } + + sfree(src_copy); + return 0; +} + +static bool has_suffix(char const *str, char const *suffix) { + size_t str_len = strlen(str); + size_t suffix_len = strlen(suffix); + size_t offset; + + if (suffix_len > str_len) + return false; + offset = str_len - suffix_len; + + if (strcmp(str + offset, suffix) == 0) + return true; + + return false; +} + +static void cut_suffix(char *buffer, size_t buffer_size, char const *str, + char const *suffix) { + + size_t str_len = strlen(str); + size_t suffix_len = strlen(suffix); + + size_t offset = str_len - suffix_len + 1; + + if (offset > buffer_size) { + offset = buffer_size; + } + + sstrncpy(buffer, str, offset); +} + +/* count_parts returns the number of elements a "foo.bar.baz" style key has. */ +static size_t count_parts(char const *key) { + size_t parts_num = 0; + + for (const char *ptr = key; ptr != NULL; ptr = strchr(ptr + 1, '.')) + parts_num++; + + return parts_num; +} + +/** + * Parse key to remove "type" if this is for schema and initiate compaction + */ +static int parse_keys(char *buffer, size_t buffer_size, const char *key_str) { + char tmp[2 * buffer_size]; + size_t tmp_size = sizeof(tmp); + const char *cut_suffixes[] = {".type", ".avgcount", ".sum", ".avgtime"}; + + if (buffer == NULL || buffer_size == 0 || key_str == NULL || + strlen(key_str) == 0) + return EINVAL; + + sstrncpy(tmp, key_str, tmp_size); + + /* Strip suffix if it is ".type" or one of latency metric suffix. */ + if (count_parts(key_str) > 2) { + for (size_t i = 0; i < STATIC_ARRAY_SIZE(cut_suffixes); i++) { + if (has_suffix(key_str, cut_suffixes[i])) { + cut_suffix(tmp, tmp_size, key_str, cut_suffixes[i]); + break; + } + } + } + + return compact_ds_name(buffer, buffer_size, tmp); +} + +/** + * while parsing ceph admin socket schema, save counter name and type for later + * data processing + */ +static int ceph_daemon_add_ds_entry(struct ceph_daemon *d, const char *name, + int pc_type) { + uint32_t type; + char ds_name[DATA_MAX_NAME_LEN]; + + if (convert_special_metrics) { + /** + * Special case for filestore:JournalWrBytes. For some reason, Ceph + * schema encodes this as a count/sum pair while all other "Bytes" data + * (excluding used/capacity bytes for OSD space) uses a single "Derive" + * type. To spare further confusion, keep this KPI as the same type of + * other "Bytes". Instead of keeping an "average" or "rate", use the + * "sum" in the pair and assign that to the derive value. + */ + if ((strcmp(name, "filestore.journal_wr_bytes.type") == 0)) { + pc_type = 10; + } + } + + d->ds_names = realloc(d->ds_names, sizeof(char *) * (d->ds_num + 1)); + if (!d->ds_names) { + return -ENOMEM; + } + + d->ds_types = realloc(d->ds_types, sizeof(uint32_t) * (d->ds_num + 1)); + if (!d->ds_types) { + return -ENOMEM; + } + + d->ds_names[d->ds_num] = malloc(DATA_MAX_NAME_LEN); + if (!d->ds_names[d->ds_num]) { + return -ENOMEM; + } + + type = (pc_type & PERFCOUNTER_DERIVE) + ? DSET_RATE + : ((pc_type & PERFCOUNTER_LATENCY) ? DSET_LATENCY : DSET_BYTES); + d->ds_types[d->ds_num] = type; + + if (parse_keys(ds_name, sizeof(ds_name), name)) { + return 1; + } + + sstrncpy(d->ds_names[d->ds_num], ds_name, DATA_MAX_NAME_LEN - 1); + d->ds_num = (d->ds_num + 1); + + return 0; +} + +/******* ceph_config *******/ +static int cc_handle_str(struct oconfig_item_s *item, char *dest, + int dest_len) { + const char *val; + if (item->values_num != 1) { + return -ENOTSUP; + } + if (item->values[0].type != OCONFIG_TYPE_STRING) { + return -ENOTSUP; + } + val = item->values[0].value.string; + if (snprintf(dest, dest_len, "%s", val) > (dest_len - 1)) { + ERROR("ceph plugin: configuration parameter '%s' is too long.\n", + item->key); + return -ENAMETOOLONG; + } + return 0; +} + +static int cc_handle_bool(struct oconfig_item_s *item, int *dest) { + if (item->values_num != 1) { + return -ENOTSUP; + } + + if (item->values[0].type != OCONFIG_TYPE_BOOLEAN) { + return -ENOTSUP; + } + + *dest = (item->values[0].value.boolean) ? 1 : 0; + return 0; +} + +static int cc_add_daemon_config(oconfig_item_t *ci) { + int ret; + struct ceph_daemon *nd, cd = {0}; + struct ceph_daemon **tmp; + + if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING)) { + WARNING("ceph plugin: `Daemon' blocks need exactly one string " + "argument."); + return -1; + } + + ret = cc_handle_str(ci, cd.name, DATA_MAX_NAME_LEN); + if (ret) { + return ret; + } + + for (int i = 0; i < ci->children_num; i++) { + oconfig_item_t *child = ci->children + i; + + if (strcasecmp("SocketPath", child->key) == 0) { + ret = cc_handle_str(child, cd.asok_path, sizeof(cd.asok_path)); + if (ret) { + return ret; + } + } else { + WARNING("ceph plugin: ignoring unknown option %s", child->key); + } + } + if (cd.name[0] == '\0') { + ERROR("ceph plugin: you must configure a daemon name.\n"); + return -EINVAL; + } else if (cd.asok_path[0] == '\0') { + ERROR("ceph plugin(name=%s): you must configure an administrative " + "socket path.\n", + cd.name); + return -EINVAL; + } else if (!((cd.asok_path[0] == '/') || + (cd.asok_path[0] == '.' && cd.asok_path[1] == '/'))) { + ERROR("ceph plugin(name=%s): administrative socket paths must begin " + "with '/' or './' Can't parse: '%s'\n", + cd.name, cd.asok_path); + return -EINVAL; + } + + tmp = realloc(g_daemons, (g_num_daemons + 1) * sizeof(*g_daemons)); + if (tmp == NULL) { + /* The positive return value here indicates that this is a + * runtime error, not a configuration error. */ + return ENOMEM; + } + g_daemons = tmp; + + nd = malloc(sizeof(*nd)); + if (!nd) { + return ENOMEM; + } + memcpy(nd, &cd, sizeof(*nd)); + g_daemons[g_num_daemons] = nd; + g_num_daemons++; + return 0; +} + +static int ceph_config(oconfig_item_t *ci) { + int ret; + + for (int i = 0; i < ci->children_num; ++i) { + oconfig_item_t *child = ci->children + i; + if (strcasecmp("Daemon", child->key) == 0) { + ret = cc_add_daemon_config(child); + if (ret == ENOMEM) { + ERROR("ceph plugin: Couldn't allocate memory"); + return ret; + } else if (ret) { + // process other daemons and ignore this one + continue; + } + } else if (strcasecmp("LongRunAvgLatency", child->key) == 0) { + ret = cc_handle_bool(child, &long_run_latency_avg); + if (ret) { + return ret; + } + } else if (strcasecmp("ConvertSpecialMetricTypes", child->key) == 0) { + ret = cc_handle_bool(child, &convert_special_metrics); + if (ret) { + return ret; + } + } else { + WARNING("ceph plugin: ignoring unknown option %s", child->key); + } + } + return 0; +} + +/** + * Parse JSON and get error message if present + */ +static int traverse_json(const unsigned char *json, uint32_t json_len, + yajl_handle hand) { + yajl_status status = yajl_parse(hand, json, json_len); + unsigned char *msg; + + switch (status) { + case yajl_status_error: + msg = yajl_get_error(hand, /* verbose = */ 1, + /* jsonText = */ (unsigned char *)json, + (unsigned int)json_len); + ERROR("ceph plugin: yajl_parse failed: %s", msg); + yajl_free_error(hand, msg); + return 1; + case yajl_status_client_canceled: + return 1; + default: + return 0; + } +} + +/** + * Add entry for each counter while parsing schema + */ +static int node_handler_define_schema(void *arg, const char *val, + const char *key) { + struct ceph_daemon *d = (struct ceph_daemon *)arg; + int pc_type; + pc_type = atoi(val); + return ceph_daemon_add_ds_entry(d, key, pc_type); +} + +/** + * Latency counter does not yet have an entry in last poll data - add it. + */ +static int add_last(struct ceph_daemon *d, const char *ds_n, double cur_sum, + uint64_t cur_count) { + d->last_poll_data[d->last_idx] = + malloc(sizeof(*d->last_poll_data[d->last_idx])); + if (!d->last_poll_data[d->last_idx]) { + return -ENOMEM; + } + sstrncpy(d->last_poll_data[d->last_idx]->ds_name, ds_n, + sizeof(d->last_poll_data[d->last_idx]->ds_name)); + d->last_poll_data[d->last_idx]->last_sum = cur_sum; + d->last_poll_data[d->last_idx]->last_count = cur_count; + d->last_idx = (d->last_idx + 1); + return 0; +} + +/** + * Update latency counter or add new entry if it doesn't exist + */ +static int update_last(struct ceph_daemon *d, const char *ds_n, int index, + double cur_sum, uint64_t cur_count) { + if ((d->last_idx > index) && + (strcmp(d->last_poll_data[index]->ds_name, ds_n) == 0)) { + d->last_poll_data[index]->last_sum = cur_sum; + d->last_poll_data[index]->last_count = cur_count; + return 0; + } + + if (!d->last_poll_data) { + d->last_poll_data = malloc(sizeof(*d->last_poll_data)); + if (!d->last_poll_data) { + return -ENOMEM; + } + } else { + struct last_data **tmp_last = realloc( + d->last_poll_data, ((d->last_idx + 1) * sizeof(struct last_data *))); + if (!tmp_last) { + return -ENOMEM; + } + d->last_poll_data = tmp_last; + } + return add_last(d, ds_n, cur_sum, cur_count); +} + +/** + * If using index guess failed (shouldn't happen, but possible if counters + * get rearranged), resort to searching for counter name + */ +static int backup_search_for_last_avg(struct ceph_daemon *d, const char *ds_n) { + for (int i = 0; i < d->last_idx; i++) { + if (strcmp(d->last_poll_data[i]->ds_name, ds_n) == 0) { + return i; + } + } + return -1; +} + +/** + * Calculate average b/t current data and last poll data + * if last poll data exists + */ +static double get_last_avg(struct ceph_daemon *d, const char *ds_n, int index, + double cur_sum, uint64_t cur_count) { + double result = -1.1, sum_delt = 0.0; + uint64_t count_delt = 0; + int tmp_index = 0; + if (d->last_idx > index) { + if (strcmp(d->last_poll_data[index]->ds_name, ds_n) == 0) { + tmp_index = index; + } + // test previous index + else if ((index > 0) && + (strcmp(d->last_poll_data[index - 1]->ds_name, ds_n) == 0)) { + tmp_index = (index - 1); + } else { + tmp_index = backup_search_for_last_avg(d, ds_n); + } + + if ((tmp_index > -1) && + (cur_count > d->last_poll_data[tmp_index]->last_count)) { + sum_delt = (cur_sum - d->last_poll_data[tmp_index]->last_sum); + count_delt = (cur_count - d->last_poll_data[tmp_index]->last_count); + result = (sum_delt / count_delt); + } + } + + if (result == -1.1) { + result = NAN; + } + if (update_last(d, ds_n, tmp_index, cur_sum, cur_count) == -ENOMEM) { + return -ENOMEM; + } + return result; +} + +/** + * If using index guess failed, resort to searching for counter name + */ +static uint32_t backup_search_for_type(struct ceph_daemon *d, char *ds_name) { + for (int i = 0; i < d->ds_num; i++) { + if (strcmp(d->ds_names[i], ds_name) == 0) { + return d->ds_types[i]; + } + } + return DSET_TYPE_UNFOUND; +} + +/** + * Process counter data and dispatch values + */ +static int node_handler_fetch_data(void *arg, const char *val, + const char *key) { + value_t uv; + double tmp_d; + uint64_t tmp_u; + struct values_tmp *vtmp = (struct values_tmp *)arg; + uint32_t type = DSET_TYPE_UNFOUND; + int index = vtmp->index; + + char ds_name[DATA_MAX_NAME_LEN]; + + if (parse_keys(ds_name, sizeof(ds_name), key)) { + return 1; + } + + if (index >= vtmp->d->ds_num) { + // don't overflow bounds of array + index = (vtmp->d->ds_num - 1); + } + + /** + * counters should remain in same order we parsed schema... we maintain the + * index variable to keep track of current point in list of counters. first + * use index to guess point in array for retrieving type. if that doesn't + * work, use the old way to get the counter type + */ + if (strcmp(ds_name, vtmp->d->ds_names[index]) == 0) { + // found match + type = vtmp->d->ds_types[index]; + } else if ((index > 0) && + (strcmp(ds_name, vtmp->d->ds_names[index - 1]) == 0)) { + // try previous key + type = vtmp->d->ds_types[index - 1]; + } + + if (type == DSET_TYPE_UNFOUND) { + // couldn't find right type by guessing, check the old way + type = backup_search_for_type(vtmp->d, ds_name); + } + + switch (type) { + case DSET_LATENCY: + if (has_suffix(key, ".avgcount")) { + sscanf(val, "%" PRIu64, &vtmp->avgcount); + // return after saving avgcount - don't dispatch value + // until latency calculation + return 0; + } else if (has_suffix(key, ".sum")) { + if (vtmp->avgcount == 0) { + vtmp->avgcount = 1; + } + // user wants latency values as long run avg + // skip this step + if (long_run_latency_avg) { + return 0; + } + double sum, result; + sscanf(val, "%lf", &sum); + result = get_last_avg(vtmp->d, ds_name, vtmp->latency_index, sum, + vtmp->avgcount); + if (result == -ENOMEM) { + return -ENOMEM; + } + uv.gauge = result; + vtmp->latency_index = (vtmp->latency_index + 1); + } else if (has_suffix(key, ".avgtime")) { + + /* The "avgtime" metric reports ("sum" / "avgcount"), i.e. the average + * time per request since the start of the Ceph daemon. Report this only + * when the user has configured "long running average". Otherwise, use the + * rate of "sum" and "avgcount" to calculate the current latency. + */ + + if (!long_run_latency_avg) { + return 0; + } + double result; + sscanf(val, "%lf", &result); + uv.gauge = result; + vtmp->latency_index = (vtmp->latency_index + 1); + } else { + WARNING("ceph plugin: ignoring unknown latency metric: %s", key); + return 0; + } + break; + case DSET_BYTES: + sscanf(val, "%lf", &tmp_d); + uv.gauge = tmp_d; + break; + case DSET_RATE: + sscanf(val, "%" PRIu64, &tmp_u); + uv.derive = tmp_u; + break; + case DSET_TYPE_UNFOUND: + default: + ERROR("ceph plugin: ds %s was not properly initialized.", ds_name); + return -1; + } + + sstrncpy(vtmp->vlist.type, ceph_dset_types[type], sizeof(vtmp->vlist.type)); + sstrncpy(vtmp->vlist.type_instance, ds_name, + sizeof(vtmp->vlist.type_instance)); + vtmp->vlist.values = &uv; + vtmp->vlist.values_len = 1; + + vtmp->index = (vtmp->index + 1); + plugin_dispatch_values(&vtmp->vlist); + + return 0; +} + +static int cconn_connect(struct cconn *io) { + struct sockaddr_un address = {0}; + int flags, fd, err; + if (io->state != CSTATE_UNCONNECTED) { + ERROR("ceph plugin: cconn_connect: io->state != CSTATE_UNCONNECTED"); + return -EDOM; + } + fd = socket(PF_UNIX, SOCK_STREAM, 0); + if (fd < 0) { + err = -errno; + ERROR("ceph plugin: cconn_connect: socket(PF_UNIX, SOCK_STREAM, 0) " + "failed: error %d", + err); + return err; + } + address.sun_family = AF_UNIX; + 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) { + ERROR("ceph plugin: cconn_connect: connect(%d) failed: error %d", fd, err); + close(fd); + return err; + } + + flags = fcntl(fd, F_GETFL, 0); + if (fcntl(fd, F_SETFL, flags | O_NONBLOCK) != 0) { + err = -errno; + ERROR("ceph plugin: cconn_connect: fcntl(%d, O_NONBLOCK) error %d", fd, + err); + close(fd); + return err; + } + io->asok = fd; + io->state = CSTATE_WRITE_REQUEST; + io->amt = 0; + io->json_len = 0; + io->json = NULL; + return 0; +} + +static void cconn_close(struct cconn *io) { + io->state = CSTATE_UNCONNECTED; + if (io->asok != -1) { + int res; + RETRY_ON_EINTR(res, close(io->asok)); + } + io->asok = -1; + io->amt = 0; + io->json_len = 0; + sfree(io->json); + io->json = NULL; +} + +/* Process incoming JSON counter data */ +static int cconn_process_data(struct cconn *io, yajl_struct *yajl, + yajl_handle hand) { + int ret; + struct values_tmp *vtmp = calloc(1, sizeof(*vtmp)); + if (!vtmp) { + return -ENOMEM; + } + + vtmp->vlist = (value_list_t)VALUE_LIST_INIT; + sstrncpy(vtmp->vlist.plugin, "ceph", sizeof(vtmp->vlist.plugin)); + sstrncpy(vtmp->vlist.plugin_instance, io->d->name, + sizeof(vtmp->vlist.plugin_instance)); + + vtmp->d = io->d; + vtmp->latency_index = 0; + vtmp->index = 0; + yajl->handler_arg = vtmp; + ret = traverse_json(io->json, io->json_len, hand); + sfree(vtmp); + return ret; +} + +/** + * Initiate JSON parsing and print error if one occurs + */ +static int cconn_process_json(struct cconn *io) { + if ((io->request_type != ASOK_REQ_DATA) && + (io->request_type != ASOK_REQ_SCHEMA)) { + return -EDOM; + } + + int result = 1; + yajl_handle hand; + yajl_status status; + + hand = yajl_alloc(&callbacks, +#if HAVE_YAJL_V2 + /* alloc funcs = */ NULL, +#else + /* alloc funcs = */ NULL, NULL, +#endif + /* context = */ (void *)(&io->yajl)); + + if (!hand) { + ERROR("ceph plugin: yajl_alloc failed."); + return ENOMEM; + } + + io->yajl.depth = 0; + + switch (io->request_type) { + case ASOK_REQ_DATA: + io->yajl.handler = node_handler_fetch_data; + result = cconn_process_data(io, &io->yajl, hand); + break; + case ASOK_REQ_SCHEMA: + // init daemon specific variables + io->d->ds_num = 0; + io->d->last_idx = 0; + io->d->last_poll_data = NULL; + io->yajl.handler = node_handler_define_schema; + io->yajl.handler_arg = io->d; + result = traverse_json(io->json, io->json_len, hand); + break; + } + + if (result) { + goto done; + } + +#if HAVE_YAJL_V2 + status = yajl_complete_parse(hand); +#else + status = yajl_parse_complete(hand); +#endif + + if (status != yajl_status_ok) { + unsigned char *errmsg = + yajl_get_error(hand, /* verbose = */ 0, + /* jsonText = */ NULL, /* jsonTextLen = */ 0); + ERROR("ceph plugin: yajl_parse_complete failed: %s", (char *)errmsg); + yajl_free_error(hand, errmsg); + yajl_free(hand); + return 1; + } + +done: + yajl_free(hand); + return result; +} + +static int cconn_validate_revents(struct cconn *io, int revents) { + if (revents & POLLERR) { + ERROR("ceph plugin: cconn_validate_revents(name=%s): got POLLERR", + io->d->name); + return -EIO; + } + switch (io->state) { + case CSTATE_WRITE_REQUEST: + return (revents & POLLOUT) ? 0 : -EINVAL; + case CSTATE_READ_VERSION: + case CSTATE_READ_AMT: + case CSTATE_READ_JSON: + return (revents & POLLIN) ? 0 : -EINVAL; + default: + ERROR("ceph plugin: cconn_validate_revents(name=%s) got to " + "illegal state on line %d", + io->d->name, __LINE__); + return -EDOM; + } +} + +/** Handle a network event for a connection */ +static ssize_t cconn_handle_event(struct cconn *io) { + ssize_t ret; + switch (io->state) { + case CSTATE_UNCONNECTED: + ERROR("ceph plugin: cconn_handle_event(name=%s) got to illegal " + "state on line %d", + io->d->name, __LINE__); + + return -EDOM; + case CSTATE_WRITE_REQUEST: { + char cmd[32]; + 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)); + DEBUG("ceph plugin: cconn_handle_event(name=%s,state=%d,amt=%d,ret=%zd)", + io->d->name, io->state, io->amt, ret); + if (ret < 0) { + return ret; + } + io->amt += ret; + if (io->amt >= cmd_len) { + io->amt = 0; + switch (io->request_type) { + case ASOK_REQ_VERSION: + io->state = CSTATE_READ_VERSION; + break; + default: + io->state = CSTATE_READ_AMT; + break; + } + } + return 0; + } + case CSTATE_READ_VERSION: { + RETRY_ON_EINTR(ret, read(io->asok, ((char *)(&io->d->version)) + io->amt, + sizeof(io->d->version) - io->amt)); + DEBUG("ceph plugin: cconn_handle_event(name=%s,state=%d,ret=%zd)", + io->d->name, io->state, ret); + if (ret < 0) { + return ret; + } + io->amt += ret; + if (io->amt >= sizeof(io->d->version)) { + io->d->version = ntohl(io->d->version); + if (io->d->version != 1) { + ERROR("ceph plugin: cconn_handle_event(name=%s) not " + "expecting version %d!", + io->d->name, io->d->version); + return -ENOTSUP; + } + DEBUG("ceph plugin: cconn_handle_event(name=%s): identified as " + "version %d", + io->d->name, io->d->version); + io->amt = 0; + cconn_close(io); + io->request_type = ASOK_REQ_SCHEMA; + } + return 0; + } + case CSTATE_READ_AMT: { + RETRY_ON_EINTR(ret, read(io->asok, ((char *)(&io->json_len)) + io->amt, + sizeof(io->json_len) - io->amt)); + DEBUG("ceph plugin: cconn_handle_event(name=%s,state=%d,ret=%zd)", + io->d->name, io->state, ret); + if (ret < 0) { + return ret; + } + io->amt += ret; + if (io->amt >= sizeof(io->json_len)) { + io->json_len = ntohl(io->json_len); + io->amt = 0; + io->state = CSTATE_READ_JSON; + io->json = calloc(1, io->json_len + 1); + if (!io->json) { + ERROR("ceph plugin: error callocing io->json"); + return -ENOMEM; + } + } + return 0; + } + case CSTATE_READ_JSON: { + RETRY_ON_EINTR(ret, + read(io->asok, io->json + io->amt, io->json_len - io->amt)); + DEBUG("ceph plugin: cconn_handle_event(name=%s,state=%d,ret=%zd)", + io->d->name, io->state, ret); + if (ret < 0) { + return ret; + } + io->amt += ret; + if (io->amt >= io->json_len) { + ret = cconn_process_json(io); + if (ret) { + return ret; + } + cconn_close(io); + io->request_type = ASOK_REQ_NONE; + } + return 0; + } + default: + ERROR("ceph plugin: cconn_handle_event(name=%s) got to illegal " + "state on line %d", + io->d->name, __LINE__); + return -EDOM; + } +} + +static int cconn_prepare(struct cconn *io, struct pollfd *fds) { + int ret; + if (io->request_type == ASOK_REQ_NONE) { + /* The request has already been serviced. */ + return 0; + } else if ((io->request_type == ASOK_REQ_DATA) && (io->d->ds_num == 0)) { + /* If there are no counters to report on, don't bother + * connecting */ + return 0; + } + + switch (io->state) { + case CSTATE_UNCONNECTED: + ret = cconn_connect(io); + if (ret > 0) { + return -ret; + } else if (ret < 0) { + return ret; + } + fds->fd = io->asok; + fds->events = POLLOUT; + return 1; + case CSTATE_WRITE_REQUEST: + fds->fd = io->asok; + fds->events = POLLOUT; + return 1; + case CSTATE_READ_VERSION: + case CSTATE_READ_AMT: + case CSTATE_READ_JSON: + fds->fd = io->asok; + fds->events = POLLIN; + return 1; + default: + ERROR("ceph plugin: cconn_prepare(name=%s) got to illegal state " + "on line %d", + io->d->name, __LINE__); + return -EDOM; + } +} + +/** Returns the difference between two struct timevals in milliseconds. + * On overflow, we return max/min int. + */ +static int milli_diff(const struct timeval *t1, const struct timeval *t2) { + int64_t ret; + long sec_diff = t1->tv_sec - t2->tv_sec; + long usec_diff = t1->tv_usec - t2->tv_usec; + ret = usec_diff / 1000; + ret += (sec_diff * 1000); + return (ret > INT_MAX) ? INT_MAX : ((ret < INT_MIN) ? INT_MIN : (int)ret); +} + +/** This handles the actual network I/O to talk to the Ceph daemons. + */ +static ssize_t cconn_main_loop(uint32_t request_type) { + int some_unreachable = 0; + ssize_t ret; + struct timeval end_tv; + struct cconn io_array[g_num_daemons]; + + DEBUG("ceph plugin: entering cconn_main_loop(request_type = %" PRIu32 ")", + request_type); + + if (g_num_daemons < 1) { + ERROR("ceph plugin: No daemons configured. See the \"Daemon\" config " + "option."); + return ENOENT; + } + + /* create cconn array */ + for (size_t i = 0; i < g_num_daemons; i++) { + io_array[i] = (struct cconn){ + .d = g_daemons[i], + .request_type = request_type, + .state = CSTATE_UNCONNECTED, + }; + } + + /** Calculate the time at which we should give up */ + gettimeofday(&end_tv, NULL); + end_tv.tv_sec += CEPH_TIMEOUT_INTERVAL; + + while (1) { + int nfds, diff; + struct timeval tv; + struct cconn *polled_io_array[g_num_daemons]; + struct pollfd fds[g_num_daemons]; + memset(fds, 0, sizeof(fds)); + nfds = 0; + for (size_t i = 0; i < g_num_daemons; ++i) { + struct cconn *io = io_array + i; + ret = cconn_prepare(io, fds + nfds); + if (ret < 0) { + WARNING("ceph plugin: cconn_prepare(name=%s,i=%" PRIsz ",st=%d)=%zd", + io->d->name, i, io->state, ret); + cconn_close(io); + io->request_type = ASOK_REQ_NONE; + some_unreachable = 1; + } else if (ret == 1) { + polled_io_array[nfds++] = io_array + i; + } + } + if (nfds == 0) { + /* finished */ + ret = 0; + goto done; + } + gettimeofday(&tv, NULL); + diff = milli_diff(&end_tv, &tv); + if (diff <= 0) { + /* Timed out */ + ret = -ETIMEDOUT; + WARNING("ceph plugin: cconn_main_loop: timed out."); + goto done; + } + RETRY_ON_EINTR(ret, poll(fds, nfds, diff)); + if (ret < 0) { + ERROR("ceph plugin: poll(2) error: %zd", ret); + goto done; + } + for (int i = 0; i < nfds; ++i) { + struct cconn *io = polled_io_array[i]; + int revents = fds[i].revents; + if (revents == 0) { + /* do nothing */ + continue; + } else if (cconn_validate_revents(io, revents)) { + WARNING("ceph plugin: cconn(name=%s,i=%d,st=%d): " + "revents validation error: " + "revents=0x%08x", + io->d->name, i, io->state, revents); + cconn_close(io); + io->request_type = ASOK_REQ_NONE; + some_unreachable = 1; + } else { + ret = cconn_handle_event(io); + if (ret) { + WARNING("ceph plugin: cconn_handle_event(name=%s," + "i=%d,st=%d): error %zd", + io->d->name, i, io->state, ret); + cconn_close(io); + io->request_type = ASOK_REQ_NONE; + some_unreachable = 1; + } + } + } + } +done: + for (size_t i = 0; i < g_num_daemons; ++i) { + cconn_close(io_array + i); + } + if (some_unreachable) { + DEBUG("ceph plugin: cconn_main_loop: some Ceph daemons were unreachable."); + } else { + DEBUG("ceph plugin: cconn_main_loop: reached all Ceph daemons :)"); + } + return ret; +} + +static int ceph_read(void) { return (int)cconn_main_loop(ASOK_REQ_DATA); } + +/******* lifecycle *******/ +static int ceph_init(void) { +#if defined(HAVE_SYS_CAPABILITY_H) && defined(CAP_DAC_OVERRIDE) + if (check_capability(CAP_DAC_OVERRIDE) != 0) { + if (getuid() == 0) + WARNING("ceph plugin: Running collectd as root, but the " + "CAP_DAC_OVERRIDE capability is missing. The plugin's read " + "function will probably fail. Is your init system dropping " + "capabilities?"); + else + WARNING( + "ceph plugin: collectd doesn't have the CAP_DAC_OVERRIDE " + "capability. If you don't want to run collectd as root, try running " + "\"setcap cap_dac_override=ep\" on the collectd binary."); + } +#endif + + ceph_daemons_print(); + + if (g_num_daemons < 1) { + ERROR("ceph plugin: No daemons configured. See the \"Daemon\" config " + "option."); + return ENOENT; + } + + return (int)cconn_main_loop(ASOK_REQ_VERSION); +} + +static int ceph_shutdown(void) { + for (size_t i = 0; i < g_num_daemons; ++i) { + ceph_daemon_free(g_daemons[i]); + } + sfree(g_daemons); + g_daemons = NULL; + g_num_daemons = 0; + DEBUG("ceph plugin: finished ceph_shutdown"); + return 0; +} + +void module_register(void) { + plugin_register_complex_config("ceph", ceph_config); + plugin_register_init("ceph", ceph_init); + plugin_register_read("ceph", ceph_read); + plugin_register_shutdown("ceph", ceph_shutdown); +} diff --git a/src/ceph_test.c b/src/ceph_test.c new file mode 100644 index 0000000000..e403292942 --- /dev/null +++ b/src/ceph_test.c @@ -0,0 +1,189 @@ +/** + * collectd - src/ceph_test.c + * Copyright (C) 2015 Florian octo Forster + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; only version 2 of the License is applicable. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * Authors: + * Florian octo Forster + **/ + +#include "ceph.c" /* sic */ +#include "testing.h" + +struct case_s { + const char *key; + const char *value; +}; +typedef struct case_s case_t; + +struct test_s { + case_t *cases; + size_t cases_num; +}; +typedef struct test_s test_t; + +static int test_handler(void *user, char const *val, char const *key) { + test_t *t = user; + size_t i; + + char status[1024]; + bool ok; + + /* special case for latency metrics. */ + if (strcmp("filestore.example_latency", key) == 0) + return RETRY_AVGCOUNT; + + snprintf(status, sizeof(status), + "unexpected call: test_handler(\"%s\") = \"%s\"", key, val); + ok = false; + + for (i = 0; i < t->cases_num; i++) { + if (strcmp(key, t->cases[i].key) != 0) + continue; + + if (strcmp(val, t->cases[i].value) != 0) { + snprintf(status, sizeof(status), + "test_handler(\"%s\") = \"%s\", want \"%s\"", key, val, + t->cases[i].value); + ok = false; + break; + } + + snprintf(status, sizeof(status), "test_handler(\"%s\") = \"%s\"", key, val); + ok = true; + break; + } + + OK1(ok, status); + return ok ? 0 : -1; +} + +DEF_TEST(traverse_json) { + char const *json = + "{\n" + " \"WBThrottle\": {\n" + " \"bytes_dirtied\": {\n" + " \"type\": 2,\n" + " \"description\": \"Dirty data\",\n" + " \"nick\": \"\"\n" + " },\n" + " \"bytes_wb\": {\n" + " \"type\": 2,\n" + " \"description\": \"Written data\",\n" + " \"nick\": \"\"\n" + " },\n" + " \"ios_dirtied\": {\n" + " \"type\": 2,\n" + " \"description\": \"Dirty operations\",\n" + " \"nick\": \"\"\n" + " },\n" + " \"ios_wb\": {\n" + " \"type\": 2,\n" + " \"description\": \"Written operations\",\n" + " \"nick\": \"\"\n" + " },\n" + " \"inodes_dirtied\": {\n" + " \"type\": 2,\n" + " \"description\": \"Entries waiting for write\",\n" + " \"nick\": \"\"\n" + " },\n" + " \"inodes_wb\": {\n" + " \"type\": 10,\n" + " \"description\": \"Written entries\",\n" + " \"nick\": \"\"\n" + " }\n" + " },\n" + " \"filestore\": {\n" + " \"journal_wr_bytes\": {\n" + " \"avgcount\": 23,\n" + " \"sum\": 3117\n" + " },\n" + " \"example_latency\": {\n" + " \"avgcount\": 42,\n" + " \"sum\": 4711\n" + " }\n" + " }\n" + "}\n"; + case_t cases[] = { + {"WBThrottle.bytes_dirtied.type", "2"}, + {"WBThrottle.bytes_wb.type", "2"}, + {"WBThrottle.ios_dirtied.type", "2"}, + {"WBThrottle.ios_wb.type", "2"}, + {"WBThrottle.inodes_dirtied.type", "2"}, + {"WBThrottle.inodes_wb.type", "10"}, + {"filestore.journal_wr_bytes.sum", "3117"}, + {"filestore.example_latency.avgcount", "42"}, + {"filestore.example_latency.sum", "4711"}, + }; + test_t t = {cases, STATIC_ARRAY_SIZE(cases)}; + + yajl_struct ctx = {test_handler, &t}; + + yajl_handle hndl; +#if HAVE_YAJL_V2 + hndl = yajl_alloc(&callbacks, NULL, &ctx); + CHECK_ZERO( + traverse_json((const unsigned char *)json, (uint32_t)strlen(json), hndl)); + CHECK_ZERO(yajl_complete_parse(hndl)); +#else + hndl = yajl_alloc(&callbacks, NULL, NULL, &ctx); + CHECK_ZERO( + traverse_json((const unsigned char *)json, (uint32_t)strlen(json), hndl)); + CHECK_ZERO(yajl_parse_complete(hndl)); +#endif + + yajl_free(hndl); + return 0; +} + +DEF_TEST(parse_keys) { + struct { + const char *str; + const char *want; + } cases[] = { + {"WBThrottle.bytes_dirtied.description.bytes_wb.description.ios_dirtied." + "description.ios_wb.type", + "WBThrottle.bytesDirtied.description.bytesWb.description.iosDirt"}, + {"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:" + "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", + "Aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"}, + {"foo:bar", "FooBar"}, + {"foo:bar+", "FooBarPlus"}, + {"foo:bar-", "FooBarMinus"}, + {"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+", + "AaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaPlus"}, + {"aa.bb.cc.dd.ee.ff", "Aa.bb.cc.dd.ee.ff"}, + {"aa.bb.cc.dd.ee.ff.type", "Aa.bb.cc.dd.ee.ff"}, + {"aa.type", "Aa.type"}, + {"WBThrottle.bytes_dirtied.type", "WBThrottle.bytesDirtied"}, + }; + size_t i; + + for (i = 0; i < STATIC_ARRAY_SIZE(cases); i++) { + char got[64]; + + CHECK_ZERO(parse_keys(got, sizeof(got), cases[i].str)); + EXPECT_EQ_STR(cases[i].want, got); + } + + return 0; +} + +int main(void) { + RUN_TEST(traverse_json); + RUN_TEST(parse_keys); + + END_TEST; +} diff --git a/src/cgroups.c b/src/cgroups.c index ffb1740a98..8925239848 100644 --- a/src/cgroups.c +++ b/src/cgroups.c @@ -22,230 +22,203 @@ **/ #include "collectd.h" -#include "common.h" + #include "plugin.h" -#include "configfile.h" -#include "utils_mount.h" -#include "utils_ignorelist.h" - -static char const *config_keys[] = -{ - "CGroup", - "IgnoreSelected" -}; -static int config_keys_num = STATIC_ARRAY_SIZE (config_keys); - -static ignorelist_t *il_cgroup = NULL; - -__attribute__ ((nonnull(1))) -__attribute__ ((nonnull(2))) -static void cgroups_submit_one (char const *plugin_instance, - char const *type_instance, value_t value) -{ - value_list_t vl = VALUE_LIST_INIT; - - vl.values = &value; - vl.values_len = 1; - sstrncpy (vl.host, hostname_g, sizeof (vl.host)); - sstrncpy (vl.plugin, "cgroups", sizeof (vl.plugin)); - sstrncpy (vl.plugin_instance, plugin_instance, - sizeof (vl.plugin_instance)); - sstrncpy (vl.type, "cpu", sizeof (vl.type)); - sstrncpy (vl.type_instance, type_instance, - sizeof (vl.type_instance)); - - plugin_dispatch_values (&vl); +#include "utils/common/common.h" +#include "utils/ignorelist/ignorelist.h" +#include "utils/mount/mount.h" + +static char const *config_keys[] = {"CGroup", "IgnoreSelected"}; +static int config_keys_num = STATIC_ARRAY_SIZE(config_keys); + +static ignorelist_t *il_cgroup; + +__attribute__((nonnull(1))) __attribute__((nonnull(2))) static void +cgroups_submit_one(char const *plugin_instance, char const *type_instance, + value_t value) { + value_list_t vl = VALUE_LIST_INIT; + + vl.values = &value; + vl.values_len = 1; + sstrncpy(vl.plugin, "cgroups", sizeof(vl.plugin)); + sstrncpy(vl.plugin_instance, plugin_instance, sizeof(vl.plugin_instance)); + sstrncpy(vl.type, "cpu", sizeof(vl.type)); + sstrncpy(vl.type_instance, type_instance, sizeof(vl.type_instance)); + + plugin_dispatch_values(&vl); } /* void cgroups_submit_one */ /* * This callback reads the user/system CPU time for each cgroup. */ -static int read_cpuacct_procs (const char *dirname, char const *cgroup_name, - void *user_data) -{ - char abs_path[PATH_MAX]; - struct stat statbuf; - char buf[1024]; - int status; - - FILE *fh; - - if (ignorelist_match (il_cgroup, cgroup_name)) - return (0); - - ssnprintf (abs_path, sizeof (abs_path), "%s/%s", dirname, cgroup_name); - - status = lstat (abs_path, &statbuf); - if (status != 0) - { - ERROR ("cgroups plugin: stat (\"%s\") failed.", - abs_path); - return (-1); - } - - /* We are only interested in directories, so skip everything else. */ - if (!S_ISDIR (statbuf.st_mode)) - return (0); - - ssnprintf (abs_path, sizeof (abs_path), "%s/%s/cpuacct.stat", - dirname, cgroup_name); - fh = fopen (abs_path, "r"); - if (fh == NULL) - { - char errbuf[1024]; - ERROR ("cgroups pluign: fopen (\"%s\") failed: %s", - abs_path, - sstrerror (errno, errbuf, sizeof (errbuf))); - return (-1); - } - - while (fgets (buf, sizeof (buf), fh) != NULL) - { - char *fields[8]; - int numfields = 0; - char *key; - size_t key_len; - value_t value; - - /* Expected format: - * - * user: 12345 - * system: 23456 - */ - strstripnewline (buf); - numfields = strsplit (buf, fields, STATIC_ARRAY_SIZE (fields)); - if (numfields != 2) - continue; - - key = fields[0]; - key_len = strlen (key); - if (key_len < 2) - continue; - - /* Strip colon off the first column */ - if (key[key_len - 1] != ':') - continue; - key[key_len - 1] = 0; - - status = parse_value (fields[1], &value, DS_TYPE_DERIVE); - if (status != 0) - continue; - - cgroups_submit_one (cgroup_name, key, value); - } - - fclose (fh); - return (0); +static int read_cpuacct_procs(const char *dirname, char const *cgroup_name, + void *user_data) { + char abs_path[PATH_MAX]; + struct stat statbuf; + char buf[1024]; + int status; + + FILE *fh; + + if (ignorelist_match(il_cgroup, cgroup_name)) + return 0; + + snprintf(abs_path, sizeof(abs_path), "%s/%s", dirname, cgroup_name); + + status = lstat(abs_path, &statbuf); + if (status != 0) { + ERROR("cgroups plugin: stat (\"%s\") failed.", abs_path); + return -1; + } + + /* We are only interested in directories, so skip everything else. */ + if (!S_ISDIR(statbuf.st_mode)) + return 0; + + snprintf(abs_path, sizeof(abs_path), "%s/%s/cpuacct.stat", dirname, + cgroup_name); + fh = fopen(abs_path, "r"); + if (fh == NULL) { + ERROR("cgroups plugin: fopen (\"%s\") failed: %s", abs_path, STRERRNO); + return -1; + } + + while (fgets(buf, sizeof(buf), fh) != NULL) { + char *fields[8]; + int numfields = 0; + char *key; + size_t key_len; + value_t value; + + /* Expected format: + * + * user: 12345 + * system: 23456 + * + * Or: + * + * user 12345 + * system 23456 + */ + strstripnewline(buf); + numfields = strsplit(buf, fields, STATIC_ARRAY_SIZE(fields)); + if (numfields != 2) + continue; + + key = fields[0]; + key_len = strlen(key); + if (key_len < 2) + continue; + + /* Strip colon off the first column, if found */ + if (key[key_len - 1] == ':') + key[key_len - 1] = '\0'; + + status = parse_value(fields[1], &value, DS_TYPE_DERIVE); + if (status != 0) + continue; + + cgroups_submit_one(cgroup_name, key, value); + } + + fclose(fh); + return 0; } /* int read_cpuacct_procs */ /* * Gets called for every file/folder in /sys/fs/cgroup/cpu,cpuacct (or - * whereever cpuacct is mounted on the system). Calls walk_directory with the + * wherever cpuacct is mounted on the system). Calls walk_directory with the * read_cpuacct_procs callback on every folder it finds, such as "system". */ -static int read_cpuacct_root (const char *dirname, const char *filename, - void *user_data) -{ - char abs_path[PATH_MAX]; - struct stat statbuf; - int status; - - ssnprintf (abs_path, sizeof (abs_path), "%s/%s", dirname, filename); - - status = lstat (abs_path, &statbuf); - if (status != 0) - { - ERROR ("cgroups plugin: stat (%s) failed.", abs_path); - return (-1); - } - - if (S_ISDIR (statbuf.st_mode)) - { - status = walk_directory (abs_path, read_cpuacct_procs, - /* user_data = */ NULL, - /* include_hidden = */ 0); - return (status); - } - - return (0); +static int read_cpuacct_root(const char *dirname, const char *filename, + void *user_data) { + char abs_path[PATH_MAX]; + struct stat statbuf; + int status; + + snprintf(abs_path, sizeof(abs_path), "%s/%s", dirname, filename); + + status = lstat(abs_path, &statbuf); + if (status != 0) { + ERROR("cgroups plugin: stat (%s) failed.", abs_path); + return -1; + } + + if (S_ISDIR(statbuf.st_mode)) { + status = walk_directory(abs_path, read_cpuacct_procs, + /* user_data = */ NULL, + /* include_hidden = */ 0); + return status; + } + + return 0; } -static int cgroups_init (void) -{ - if (il_cgroup == NULL) - il_cgroup = ignorelist_create (1); +static int cgroups_init(void) { + if (il_cgroup == NULL) + il_cgroup = ignorelist_create(1); - return (0); + return 0; } -static int cgroups_config (const char *key, const char *value) -{ - cgroups_init (); - - if (strcasecmp (key, "CGroup") == 0) - { - if (ignorelist_add (il_cgroup, value)) - return (1); - return (0); - } - else if (strcasecmp (key, "IgnoreSelected") == 0) - { - if (IS_TRUE (value)) - ignorelist_set_invert (il_cgroup, 0); - else - ignorelist_set_invert (il_cgroup, 1); - return (0); - } - - return (-1); +static int cgroups_config(const char *key, const char *value) { + cgroups_init(); + + if (strcasecmp(key, "CGroup") == 0) { + if (ignorelist_add(il_cgroup, value)) + return 1; + return 0; + } else if (strcasecmp(key, "IgnoreSelected") == 0) { + if (IS_TRUE(value)) + ignorelist_set_invert(il_cgroup, 0); + else + ignorelist_set_invert(il_cgroup, 1); + return 0; + } + + return -1; } -static int cgroups_read (void) -{ - cu_mount_t *mnt_list; - cu_mount_t *mnt_ptr; - _Bool cgroup_found = 0; - - mnt_list = NULL; - if (cu_mount_getlist (&mnt_list) == NULL) - { - ERROR ("cgroups plugin: cu_mount_getlist failed."); - return (-1); - } - - for (mnt_ptr = mnt_list; mnt_ptr != NULL; mnt_ptr = mnt_ptr->next) - { - /* Find the cgroup mountpoint which contains the cpuacct - * controller. */ - if (strcmp(mnt_ptr->type, "cgroup") != 0 || - !cu_mount_getoptionvalue(mnt_ptr->options, "cpuacct")) - continue; - - walk_directory (mnt_ptr->dir, read_cpuacct_root, - /* user_data = */ NULL, - /* include_hidden = */ 0); - cgroup_found = 1; - /* It doesn't make sense to check other cpuacct mount-points - * (if any), they contain the same data. */ - break; - } - - cu_mount_freelist (mnt_list); - - if (!cgroup_found) - { - WARNING ("cgroups plugin: Unable to find cgroup " - "mount-point with the \"cpuacct\" option."); - return (-1); - } - - return (0); +static int cgroups_read(void) { + cu_mount_t *mnt_list = NULL; + bool cgroup_found = false; + + if (cu_mount_getlist(&mnt_list) == NULL) { + ERROR("cgroups plugin: cu_mount_getlist failed."); + return -1; + } + + for (cu_mount_t *mnt_ptr = mnt_list; mnt_ptr != NULL; + mnt_ptr = mnt_ptr->next) { + /* Find the cgroup mountpoint which contains the cpuacct + * controller. */ + if ((strcmp(mnt_ptr->type, "cgroup") != 0) || + !cu_mount_checkoption(mnt_ptr->options, "cpuacct", /* full = */ 1)) + continue; + + walk_directory(mnt_ptr->dir, read_cpuacct_root, + /* user_data = */ NULL, + /* include_hidden = */ 0); + cgroup_found = true; + /* It doesn't make sense to check other cpuacct mount-points + * (if any), they contain the same data. */ + break; + } + + cu_mount_freelist(mnt_list); + + if (!cgroup_found) { + WARNING("cgroups plugin: Unable to find cgroup " + "mount-point with the \"cpuacct\" option."); + return -1; + } + + return 0; } /* int cgroup_read */ -void module_register (void) -{ - plugin_register_config ("cgroups", cgroups_config, - config_keys, config_keys_num); - plugin_register_init ("cgroups", cgroups_init); - plugin_register_read ("cgroups", cgroups_read); +void module_register(void) { + plugin_register_config("cgroups", cgroups_config, config_keys, + config_keys_num); + plugin_register_init("cgroups", cgroups_init); + plugin_register_read("cgroups", cgroups_read); } /* void module_register */ diff --git a/src/check_uptime.c b/src/check_uptime.c new file mode 100644 index 0000000000..33363b54f5 --- /dev/null +++ b/src/check_uptime.c @@ -0,0 +1,273 @@ +/** + * 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 + * Pavel Rochnyak + **/ + +#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); +} diff --git a/src/chrony.c b/src/chrony.c new file mode 100644 index 0000000000..079a335700 --- /dev/null +++ b/src/chrony.c @@ -0,0 +1,1038 @@ +/* chrony plugin for collectd (monitoring of chrony time server daemon) + ********************************************************************** + * Copyright (C) Claudius M Zingerli, ZSeng, 2015-2016 + * + * Internals roughly based on the ntpd plugin + * Some functions copied from chronyd/web (as marked) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * 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 Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * TODO: + * - More robust udp parsing (using offsets instead of structs?) + * -> Currently chrony parses its data the same way as we do (using + *structs) + * - Plausibility checks on values received + * -> Done at higher levels + */ + +#include "collectd.h" + +#include "plugin.h" /* plugin_register_*, plugin_dispatch_values */ +#include "utils/common/common.h" /* auxiliary functions */ + +#if HAVE_NETDB_H +#include /* struct addrinfo */ +#endif +#if HAVE_ARPA_INET_H +#include /* ntohs/ntohl */ +#endif + +/* AIX doesn't have MSG_DONTWAIT */ +#ifndef MSG_DONTWAIT +#define MSG_DONTWAIT MSG_NONBLOCK +#endif + +#define CONFIG_KEY_HOST "Host" +#define CONFIG_KEY_PORT "Port" +#define CONFIG_KEY_TIMEOUT "Timeout" + +#define URAND_DEVICE_PATH \ + "/dev/urandom" /* Used to initialize seq nr generator */ +#define RAND_DEVICE_PATH \ + "/dev/random" /* Used to initialize seq nr generator (fall back) */ + +static const char *g_config_keys[] = {CONFIG_KEY_HOST, CONFIG_KEY_PORT, + CONFIG_KEY_TIMEOUT}; + +static int g_config_keys_num = STATIC_ARRAY_SIZE(g_config_keys); +static int g_chrony_is_connected; +static int g_chrony_socket = -1; +static time_t g_chrony_timeout = -1; +static char *g_chrony_plugin_instance; +static char *g_chrony_host; +static char *g_chrony_port; +static uint32_t g_chrony_rand = 1; +static uint32_t g_chrony_seq_is_initialized; + +#define PLUGIN_NAME_SHORT "chrony" +#define PLUGIN_NAME PLUGIN_NAME_SHORT " plugin" +#define DAEMON_NAME PLUGIN_NAME_SHORT +#define CHRONY_DEFAULT_HOST "localhost" +#define CHRONY_DEFAULT_PORT "323" +#define CHRONY_DEFAULT_TIMEOUT 2 + +/* Return codes (collectd expects non-zero on errors) */ +#define CHRONY_RC_OK 0 +#define CHRONY_RC_FAIL 1 + +/* Chronyd command packet variables adapted from chrony/candm.h (GPL2) */ +#define PROTO_VERSION_NUMBER 6 +#define IPADDR_UNSPEC 0 +#define IPADDR_INET4 1 +#define IPADDR_INET6 2 +#define IPV6_STR_MAX_SIZE (8 * 4 + 7 + 1) +#define MODE_REFCLOCK 2 + +typedef enum { PKT_TYPE_CMD_REQUEST = 1, PKT_TYPE_CMD_REPLY = 2 } ePacketType; + +typedef enum { + REQ_N_SOURCES = 14, + REQ_SOURCE_DATA = 15, + REQ_TRACKING = 33, + REQ_SOURCE_STATS = 34 +} eDaemonRequests; + +typedef enum { + RPY_NULL = 1, + RPY_N_SOURCES = 2, + RPY_SOURCE_DATA = 3, + RPY_MANUAL_TIMESTAMP = 4, + RPY_TRACKING = 5, + RPY_SOURCE_STATS = 6, + RPY_RTC = 7 +} eDaemonReplies; + +#if defined(__GNUC__) || defined(__SUNPRO_C) || defined(lint) +#/* extension to enforce struct packing. */ +#define ATTRIB_PACKED __attribute__((packed)) +#else +#error Not defining packed attribute (unknown compiler) +#define ATTRIB_PACKED +#endif + +typedef struct ATTRIB_PACKED { + int32_t value; +} tFloat; + +typedef struct ATTRIB_PACKED { + uint32_t tv_sec_high; + uint32_t tv_sec_low; + uint32_t tv_nsec; +} tTimeval; + +typedef enum { + STT_SUCCESS = 0, + STT_FAILED = 1, + STT_UNAUTH = 2, + STT_INVALID = 3, + STT_NOSUCHSOURCE = 4, + STT_INVALIDTS = 5, + STT_NOTENABLED = 6, + STT_BADSUBNET = 7, + STT_ACCESSALLOWED = 8, + STT_ACCESSDENIED = 9, + STT_NOHOSTACCESS = 10, + STT_SOURCEALREADYKNOWN = 11, + STT_TOOMANYSOURCES = 12, + STT_NORTC = 13, + STT_BADRTCFILE = 14, + STT_INACTIVE = 15, + STT_BADSAMPLE = 16, + STT_INVALIDAF = 17, + STT_BADPKTVERSION = 18, + STT_BADPKTLENGTH = 19 +} eChrony_Status; + +/* Chrony client request packets */ +typedef struct ATTRIB_PACKED { + uint8_t f_dummy0[80]; /* Chrony expects 80bytes dummy data (Avoiding UDP + Amplification) */ +} tChrony_Req_Tracking; + +typedef struct ATTRIB_PACKED { + uint32_t f_n_sources; +} tChrony_Req_N_Sources; + +typedef struct ATTRIB_PACKED { + int32_t f_index; + uint8_t f_dummy0[44]; +} tChrony_Req_Source_data; + +typedef struct ATTRIB_PACKED { + int32_t f_index; + uint8_t f_dummy0[56]; +} tChrony_Req_Source_stats; + +typedef struct ATTRIB_PACKED { + struct { + uint8_t f_version; + uint8_t f_type; + uint8_t f_dummy0; + uint8_t f_dummy1; + uint16_t f_cmd; + uint16_t f_cmd_try; + uint32_t f_seq; + + uint32_t f_dummy2; + uint32_t f_dummy3; + } header; /* Packed: 20Bytes */ + union { + tChrony_Req_N_Sources n_sources; + tChrony_Req_Source_data source_data; + tChrony_Req_Source_stats source_stats; + tChrony_Req_Tracking tracking; + } body; + uint8_t padding[4 + 16]; /* Padding to match minimal response size */ +} tChrony_Request; + +/* Chrony daemon response packets */ +typedef struct ATTRIB_PACKED { + uint32_t f_n_sources; +} tChrony_Resp_N_Sources; + +typedef struct ATTRIB_PACKED { + union { + uint32_t ip4; + uint8_t ip6[16]; + } addr; + uint16_t f_family; + uint16_t padding; +} tChrony_IPAddr; + +typedef struct ATTRIB_PACKED { + tChrony_IPAddr addr; + int16_t f_poll; /* 2^f_poll = Time between polls (s) */ + uint16_t f_stratum; /* Remote clock stratum */ + uint16_t f_state; /* 0 = RPY_SD_ST_SYNC, 1 = RPY_SD_ST_UNREACH, 2 = + RPY_SD_ST_FALSETICKER */ + /* 3 = RPY_SD_ST_JITTERY, 4 = RPY_SD_ST_CANDIDATE, 5 = RPY_SD_ST_OUTLIER */ + uint16_t f_mode; /* 0 = RPY_SD_MD_CLIENT, 1 = RPY_SD_MD_PEER, 2 = + RPY_SD_MD_REF */ + uint16_t f_flags; /* unused */ + uint16_t + f_reachability; /* Bit mask of successfull tries to reach the source */ + + uint32_t f_since_sample; /* Time since last sample (s) */ + tFloat f_origin_latest_meas; /* */ + tFloat f_latest_meas; /* */ + tFloat f_latest_meas_err; /* */ +} tChrony_Resp_Source_data; + +typedef struct ATTRIB_PACKED { + uint32_t f_ref_id; + tChrony_IPAddr addr; + uint32_t f_n_samples; /* Number of measurements done */ + uint32_t f_n_runs; /* How many measurements to come */ + uint32_t f_span_seconds; /* For how long we're measuring */ + tFloat f_rtc_seconds_fast; /* ??? */ + tFloat f_rtc_gain_rate_ppm; /* Estimated relative frequency error */ + tFloat f_skew_ppm; /* Clock skew (ppm) (worst case freq est error (skew: + peak2peak)) */ + tFloat f_est_offset; /* Estimated offset of source */ + tFloat f_est_offset_err; /* Error of estimation */ +} tChrony_Resp_Source_stats; + +typedef struct ATTRIB_PACKED { + uint32_t f_ref_id; + tChrony_IPAddr addr; + uint16_t f_stratum; + uint16_t f_leap_status; + tTimeval f_ref_time; + tFloat f_current_correction; + tFloat f_last_offset; + tFloat f_rms_offset; + tFloat f_freq_ppm; + tFloat f_resid_freq_ppm; + tFloat f_skew_ppm; + tFloat f_root_delay; + tFloat f_root_dispersion; + tFloat f_last_update_interval; +} tChrony_Resp_Tracking; + +typedef struct ATTRIB_PACKED { + struct { + uint8_t f_version; + uint8_t f_type; + uint8_t f_dummy0; + uint8_t f_dummy1; + uint16_t f_cmd; + uint16_t f_reply; + uint16_t f_status; + uint16_t f_dummy2; + uint16_t f_dummy3; + uint16_t f_dummy4; + uint32_t f_seq; + uint32_t f_dummy5; + uint32_t f_dummy6; + } header; /* Packed: 28 Bytes */ + + union { + tChrony_Resp_N_Sources n_sources; + tChrony_Resp_Source_data source_data; + tChrony_Resp_Source_stats source_stats; + tChrony_Resp_Tracking tracking; + } body; + + uint8_t padding[1024]; +} tChrony_Response; + +/*****************************************************************************/ +/* Internal functions */ +/*****************************************************************************/ + +/* connect_client code adapted from: + * http://long.ccaba.upc.edu/long/045Guidelines/eva/ipv6.html#daytimeClient6 */ +/* License granted by Eva M Castro via e-mail on 2016-02-18 under the terms of + * GPLv3 */ +static int connect_client(const char *p_hostname, const char *p_service, + int p_family, int p_socktype) { + struct addrinfo *res, *ressave; + int n, sockfd; + + struct addrinfo ai_hints = {.ai_family = p_family, .ai_socktype = p_socktype}; + + n = getaddrinfo(p_hostname, p_service, &ai_hints, &res); + + if (n < 0) { + ERROR(PLUGIN_NAME ": getaddrinfo error:: [%s]", gai_strerror(n)); + return -1; + } + + ressave = res; + + sockfd = -1; + while (res) { + sockfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol); + + if (!(sockfd < 0)) { + if (connect(sockfd, res->ai_addr, res->ai_addrlen) == 0) { + /* Success */ + break; + } + + close(sockfd); + sockfd = -1; + } + res = res->ai_next; + } + + freeaddrinfo(ressave); + return sockfd; +} + +/* niptoha code originally from: + * git://git.tuxfamily.org/gitroot/chrony/chrony.git:util.c */ +/* Original code licensed as GPLv2, by Richard P. Purnow, Miroslav Lichvar */ +/* Original name: char * UTI_IPToString(IPAddr *addr)*/ +static char *niptoha(const tChrony_IPAddr *addr, char *p_buf, + size_t p_buf_size) { + int rc = 1; + unsigned long a, b, c, d, ip; + + switch (ntohs(addr->f_family)) { + case IPADDR_UNSPEC: + rc = snprintf(p_buf, p_buf_size, "[UNSPEC]"); + break; + case IPADDR_INET4: + ip = ntohl(addr->addr.ip4); + a = (ip >> 24) & 0xff; + b = (ip >> 16) & 0xff; + c = (ip >> 8) & 0xff; + d = (ip >> 0) & 0xff; + rc = snprintf(p_buf, p_buf_size, "%ld.%ld.%ld.%ld", a, b, c, d); + break; + case IPADDR_INET6: { + const char *rp = inet_ntop(AF_INET6, addr->addr.ip6, p_buf, p_buf_size); + if (rp == NULL) { + ERROR(PLUGIN_NAME ": Error converting ipv6 address to string. Errno = %d", + errno); + rc = snprintf(p_buf, p_buf_size, "[UNKNOWN]"); + } + break; + } + default: + rc = snprintf(p_buf, p_buf_size, "[UNKNOWN]"); + } + assert(rc > 0); + return p_buf; +} + +static void nreftostr(uint32_t nrefid, char *p_buf, size_t p_buf_size) { + size_t j = 0; + + for (int i = 0; i < 4; i++) { + int c = ntohl(nrefid) << i * 8 >> 24; + if (!isalnum(c) || j + 1 >= p_buf_size) + continue; + p_buf[j++] = c; + } + if (j < p_buf_size) + p_buf[j] = '\0'; +} + +static int chrony_set_timeout(void) { + /* Set the socket's timeout to g_chrony_timeout; a value of 0 signals + * infinite timeout */ + /* Returns 0 on success, !0 on error (check errno) */ + + struct timeval tv; + tv.tv_sec = g_chrony_timeout; + tv.tv_usec = 0; + + assert(g_chrony_socket >= 0); + if (setsockopt(g_chrony_socket, SOL_SOCKET, SO_RCVTIMEO, (char *)&tv, + sizeof(struct timeval)) < 0) { + return CHRONY_RC_FAIL; + } + return CHRONY_RC_OK; +} + +static int chrony_connect(void) { + /* Connects to the chrony daemon */ + /* Returns 0 on success, !0 on error (check errno) */ + int socket; + + if (g_chrony_host == NULL) { + g_chrony_host = strdup(CHRONY_DEFAULT_HOST); + if (g_chrony_host == NULL) { + ERROR(PLUGIN_NAME ": Error duplicating chrony host name"); + return CHRONY_RC_FAIL; + } + } + if (g_chrony_port == NULL) { + g_chrony_port = strdup(CHRONY_DEFAULT_PORT); + if (g_chrony_port == NULL) { + ERROR(PLUGIN_NAME ": Error duplicating chrony port string"); + return CHRONY_RC_FAIL; + } + } + if (g_chrony_timeout < 0) { + g_chrony_timeout = CHRONY_DEFAULT_TIMEOUT; + assert(g_chrony_timeout >= 0); + } + + DEBUG(PLUGIN_NAME ": Connecting to %s:%s", g_chrony_host, g_chrony_port); + socket = connect_client(g_chrony_host, g_chrony_port, AF_UNSPEC, SOCK_DGRAM); + if (socket < 0) { + ERROR(PLUGIN_NAME ": Error connecting to daemon. Errno = %d", errno); + return CHRONY_RC_FAIL; + } + DEBUG(PLUGIN_NAME ": Connected"); + g_chrony_socket = socket; + + if (chrony_set_timeout()) { + ERROR(PLUGIN_NAME ": Error setting timeout to %llds. Errno = %d", + (long long)g_chrony_timeout, errno); + return CHRONY_RC_FAIL; + } + return CHRONY_RC_OK; +} + +static int chrony_send_request(const tChrony_Request *p_req, + size_t p_req_size) { + if (send(g_chrony_socket, p_req, p_req_size, 0) < 0) { + ERROR(PLUGIN_NAME ": Error sending packet. Errno = %d", errno); + return CHRONY_RC_FAIL; + } + return CHRONY_RC_OK; +} + +static int chrony_recv_response(tChrony_Response *p_resp, + size_t p_resp_max_size, size_t *p_resp_size) { + ssize_t rc = recv(g_chrony_socket, p_resp, p_resp_max_size, 0); + if (rc <= 0) { + ERROR(PLUGIN_NAME ": Error receiving packet: %s (%d)", strerror(errno), + errno); + return CHRONY_RC_FAIL; + } else { + *p_resp_size = rc; + return CHRONY_RC_OK; + } +} + +static void chrony_flush_recv_queue(void) { + char buf[1]; + + if (g_chrony_is_connected) { + while (recv(g_chrony_socket, buf, sizeof(buf), MSG_DONTWAIT) > 0) + ; + } +} + +static int chrony_query(const int p_command, tChrony_Request *p_req, + tChrony_Response *p_resp, size_t *p_resp_size) { + /* Check connection. We simply perform one try as collectd already handles + * retries */ + assert(p_req); + assert(p_resp); + assert(p_resp_size); + + if (g_chrony_is_connected == 0) { + if (chrony_connect() == CHRONY_RC_OK) { + g_chrony_is_connected = 1; + } else { + ERROR(PLUGIN_NAME ": Unable to connect. Errno = %d", errno); + return CHRONY_RC_FAIL; + } + } + + do { + int valid_command = 0; + size_t req_size = sizeof(p_req->header) + sizeof(p_req->padding); + size_t resp_size = sizeof(p_resp->header); + uint16_t resp_code = RPY_NULL; + switch (p_command) { + case REQ_TRACKING: + req_size += sizeof(p_req->body.tracking); + resp_size += sizeof(p_resp->body.tracking); + resp_code = RPY_TRACKING; + valid_command = 1; + break; + case REQ_N_SOURCES: + req_size += sizeof(p_req->body.n_sources); + resp_size += sizeof(p_resp->body.n_sources); + resp_code = RPY_N_SOURCES; + valid_command = 1; + break; + case REQ_SOURCE_DATA: + req_size += sizeof(p_req->body.source_data); + resp_size += sizeof(p_resp->body.source_data); + resp_code = RPY_SOURCE_DATA; + valid_command = 1; + break; + case REQ_SOURCE_STATS: + req_size += sizeof(p_req->body.source_stats); + resp_size += sizeof(p_resp->body.source_stats); + resp_code = RPY_SOURCE_STATS; + valid_command = 1; + break; + default: + ERROR(PLUGIN_NAME ": Unknown request command (Was: %d)", p_command); + break; + } + + if (valid_command == 0) + break; + + uint32_t seq_nr = rand_r(&g_chrony_rand); + p_req->header.f_cmd = htons(p_command); + p_req->header.f_cmd_try = 0; + p_req->header.f_seq = seq_nr; + + DEBUG(PLUGIN_NAME ": Sending request (.cmd = %d, .seq = %d)", p_command, + seq_nr); + if (chrony_send_request(p_req, req_size) != 0) + break; + + DEBUG(PLUGIN_NAME ": Waiting for response"); + if (chrony_recv_response(p_resp, resp_size, p_resp_size) != 0) + break; + + DEBUG(PLUGIN_NAME ": Received response: .version = %u, .type = %u, .cmd = " + "%u, .reply = %u, .status = %u, .seq = %u", + p_resp->header.f_version, p_resp->header.f_type, + ntohs(p_resp->header.f_cmd), ntohs(p_resp->header.f_reply), + ntohs(p_resp->header.f_status), p_resp->header.f_seq); + + if (p_resp->header.f_version != p_req->header.f_version) { + ERROR(PLUGIN_NAME ": Wrong protocol version (Was: %d, expected: %d)", + p_resp->header.f_version, p_req->header.f_version); + return CHRONY_RC_FAIL; + } + if (p_resp->header.f_type != PKT_TYPE_CMD_REPLY) { + ERROR(PLUGIN_NAME ": Wrong packet type (Was: %d, expected: %d)", + p_resp->header.f_type, PKT_TYPE_CMD_REPLY); + return CHRONY_RC_FAIL; + } + if (p_resp->header.f_seq != seq_nr) { + /* FIXME: Implement sequence number handling */ + ERROR(PLUGIN_NAME ": Unexpected sequence number (Was: %d, expected: %d)", + p_resp->header.f_seq, p_req->header.f_seq); + return CHRONY_RC_FAIL; + } + if (p_resp->header.f_cmd != p_req->header.f_cmd) { + ERROR(PLUGIN_NAME ": Wrong reply command (Was: %d, expected: %d)", + p_resp->header.f_cmd, p_req->header.f_cmd); + return CHRONY_RC_FAIL; + } + + if (ntohs(p_resp->header.f_reply) != resp_code) { + ERROR(PLUGIN_NAME ": Wrong reply code (Was: %d, expected: %d)", + ntohs(p_resp->header.f_reply), resp_code); + return CHRONY_RC_FAIL; + } + + switch (p_resp->header.f_status) { + case STT_SUCCESS: + DEBUG(PLUGIN_NAME ": Reply packet status STT_SUCCESS"); + break; + default: + ERROR(PLUGIN_NAME + ": Reply packet contains error status: %d (expected: %d)", + p_resp->header.f_status, STT_SUCCESS); + return CHRONY_RC_FAIL; + } + + /* Good result */ + return CHRONY_RC_OK; + } while (0); + + /* Some error occured */ + return CHRONY_RC_FAIL; +} + +static void chrony_init_req(tChrony_Request *p_req) { + memset(p_req, 0, sizeof(*p_req)); + p_req->header.f_version = PROTO_VERSION_NUMBER; + p_req->header.f_type = PKT_TYPE_CMD_REQUEST; + p_req->header.f_dummy0 = 0; + p_req->header.f_dummy1 = 0; + p_req->header.f_dummy2 = 0; + p_req->header.f_dummy3 = 0; +} + +/* ntohf code originally from: + * git://git.tuxfamily.org/gitroot/chrony/chrony.git:util.c */ +/* Original code licensed as GPLv2, by Richard P. Purnow, Miroslav Lichvar */ +/* Original name: double UTI_tFloatNetworkToHost(tFloat f) */ +static double ntohf(tFloat p_float) { +/* Convert tFloat in Network-bit-order to double in host-bit-order */ + +#define FLOAT_EXP_BITS 7 +#define FLOAT_EXP_MIN (-(1 << (FLOAT_EXP_BITS - 1))) +#define FLOAT_EXP_MAX (-FLOAT_EXP_MIN - 1) +#define FLOAT_COEF_BITS ((int)sizeof(int32_t) * 8 - FLOAT_EXP_BITS) +#define FLOAT_COEF_MIN (-(1 << (FLOAT_COEF_BITS - 1))) +#define FLOAT_COEF_MAX (-FLOAT_COEF_MIN - 1) + + int32_t exp, coef; + uint32_t uval; + + uval = ntohl(p_float.value); + exp = (uval >> FLOAT_COEF_BITS); + if (exp >= 1 << (FLOAT_EXP_BITS - 1)) + exp -= 1 << FLOAT_EXP_BITS; + exp -= FLOAT_COEF_BITS; + + /* coef = (x << FLOAT_EXP_BITS) >> FLOAT_EXP_BITS; */ + coef = uval % (1U << FLOAT_COEF_BITS); + if (coef >= 1 << (FLOAT_COEF_BITS - 1)) + coef -= 1 << FLOAT_COEF_BITS; + + return coef * pow(2.0, exp); +} + +static void chrony_push_data(const char *p_type, const char *p_type_inst, + double p_value) { + value_list_t vl = VALUE_LIST_INIT; + + vl.values = &(value_t){.gauge = p_value}; + vl.values_len = 1; + + /* XXX: Shall g_chrony_host/g_chrony_port be reflected in the plugin's output? + */ + sstrncpy(vl.plugin, PLUGIN_NAME_SHORT, sizeof(vl.plugin)); + if (g_chrony_plugin_instance != NULL) { + sstrncpy(vl.plugin_instance, g_chrony_plugin_instance, + sizeof(vl.plugin_instance)); + } + if (p_type != NULL) + sstrncpy(vl.type, p_type, sizeof(vl.type)); + + if (p_type_inst != NULL) + sstrncpy(vl.type_instance, p_type_inst, sizeof(vl.type_instance)); + + plugin_dispatch_values(&vl); +} + +static void chrony_push_data_valid(const char *p_type, const char *p_type_inst, + const int p_is_valid, double p_value) { + /* Push real value if p_is_valid is true, push NAN if p_is_valid is not true + * (idea from ntp plugin) */ + if (p_is_valid == 0) + p_value = NAN; + + chrony_push_data(p_type, p_type_inst, p_value); +} + +static int chrony_init_seq(void) { + /* Initialize the sequence number generator from /dev/urandom */ + /* Fallbacks: /dev/random and time(NULL) */ + + int fh; + + /* Try urandom */ + fh = open(URAND_DEVICE_PATH, O_RDONLY); + if (fh >= 0) { + ssize_t rc = read(fh, &g_chrony_rand, sizeof(g_chrony_rand)); + if (rc != sizeof(g_chrony_rand)) { + ERROR(PLUGIN_NAME ": Reading from random source \'%s\'failed: %s (%d)", + URAND_DEVICE_PATH, strerror(errno), errno); + close(fh); + return CHRONY_RC_FAIL; + } + close(fh); + DEBUG(PLUGIN_NAME ": Seeding RNG from " URAND_DEVICE_PATH); + } else { + if (errno == ENOENT) { + /* URAND_DEVICE_PATH device not found. Try RAND_DEVICE_PATH as fall-back + */ + fh = open(RAND_DEVICE_PATH, O_RDONLY); + if (fh >= 0) { + ssize_t rc = read(fh, &g_chrony_rand, sizeof(g_chrony_rand)); + if (rc != sizeof(g_chrony_rand)) { + ERROR(PLUGIN_NAME + ": Reading from random source \'%s\'failed: %s (%d)", + RAND_DEVICE_PATH, strerror(errno), errno); + close(fh); + return CHRONY_RC_FAIL; + } + close(fh); + DEBUG(PLUGIN_NAME ": Seeding RNG from " RAND_DEVICE_PATH); + } else { + /* Error opening RAND_DEVICE_PATH. Try time(NULL) as fall-back */ + DEBUG(PLUGIN_NAME ": Seeding RNG from time(NULL)"); + g_chrony_rand = time(NULL) ^ getpid(); + } + } else { + ERROR(PLUGIN_NAME ": Opening random source \'%s\' failed: %s (%d)", + URAND_DEVICE_PATH, strerror(errno), errno); + return CHRONY_RC_FAIL; + } + } + + return CHRONY_RC_OK; +} + +/*****************************************************************************/ +/* Exported functions */ +/*****************************************************************************/ +static int chrony_config(const char *p_key, const char *p_value) { + assert(p_key); + assert(p_value); + + /* Parse config variables */ + if (strcasecmp(p_key, CONFIG_KEY_HOST) == 0) { + if (g_chrony_host != NULL) + free(g_chrony_host); + + if ((g_chrony_host = strdup(p_value)) == NULL) { + ERROR(PLUGIN_NAME ": Error duplicating host name"); + return CHRONY_RC_FAIL; + } + } else { + if (strcasecmp(p_key, CONFIG_KEY_PORT) == 0) { + if (g_chrony_port != NULL) + free(g_chrony_port); + + if ((g_chrony_port = strdup(p_value)) == NULL) { + ERROR(PLUGIN_NAME ": Error duplicating port name"); + return CHRONY_RC_FAIL; + } + } else { + if (strcasecmp(p_key, CONFIG_KEY_TIMEOUT) == 0) { + time_t tosec = strtol(p_value, NULL, 0); + g_chrony_timeout = tosec; + } else { + WARNING(PLUGIN_NAME ": Unknown configuration variable: %s %s", p_key, + p_value); + return CHRONY_RC_FAIL; + } + } + } + /* XXX: We could set g_chrony_plugin_instance here to + * "g_chrony_host-g_chrony_port", but as multiple instances aren't yet + * supported, we skip this for now */ + + return CHRONY_RC_OK; +} + +static int chrony_request_daemon_stats(void) { + /* Perform Tracking request */ + int rc; + size_t chrony_resp_size; + tChrony_Request chrony_req; + tChrony_Response chrony_resp; + + chrony_init_req(&chrony_req); + rc = chrony_query(REQ_TRACKING, &chrony_req, &chrony_resp, &chrony_resp_size); + if (rc != 0) { + ERROR(PLUGIN_NAME ": chrony_query (REQ_TRACKING) failed with status %i", + rc); + return rc; + } +#if COLLECT_DEBUG + { + char src_addr[IPV6_STR_MAX_SIZE] = {0}; + niptoha(&chrony_resp.body.tracking.addr, src_addr, sizeof(src_addr)); + DEBUG(PLUGIN_NAME + ": Daemon stat: .addr = %s, .ref_id= %u, .stratum = %u, .leap_status " + "= %u, .ref_time = %u:%u:%u, .current_correction = %f, .last_offset " + "= %f, .rms_offset = %f, .freq_ppm = %f, .skew_ppm = %f, .root_delay " + "= %f, .root_dispersion = %f, .last_update_interval = %f", + src_addr, ntohs(chrony_resp.body.tracking.f_ref_id), + ntohs(chrony_resp.body.tracking.f_stratum), + ntohs(chrony_resp.body.tracking.f_leap_status), + ntohl(chrony_resp.body.tracking.f_ref_time.tv_sec_high), + ntohl(chrony_resp.body.tracking.f_ref_time.tv_sec_low), + ntohl(chrony_resp.body.tracking.f_ref_time.tv_nsec), + ntohf(chrony_resp.body.tracking.f_current_correction), + ntohf(chrony_resp.body.tracking.f_last_offset), + ntohf(chrony_resp.body.tracking.f_rms_offset), + ntohf(chrony_resp.body.tracking.f_freq_ppm), + ntohf(chrony_resp.body.tracking.f_skew_ppm), + ntohf(chrony_resp.body.tracking.f_root_delay), + ntohf(chrony_resp.body.tracking.f_root_dispersion), + ntohf(chrony_resp.body.tracking.f_last_update_interval)); + } +#endif + + double time_ref = ntohl(chrony_resp.body.tracking.f_ref_time.tv_nsec); + time_ref /= 1000000000.0; + time_ref += ntohl(chrony_resp.body.tracking.f_ref_time.tv_sec_low); + if (chrony_resp.body.tracking.f_ref_time.tv_sec_high) { + double secs_high = ntohl(chrony_resp.body.tracking.f_ref_time.tv_sec_high); + secs_high *= 4294967296.0; + time_ref += secs_high; + } + + /* Forward results to collectd-daemon */ + /* Type_instance is always 'chrony' to tag daemon-wide data */ + /* Type Type_instan Value */ + chrony_push_data("clock_stratum", DAEMON_NAME, + ntohs(chrony_resp.body.tracking.f_stratum)); + chrony_push_data("time_ref", DAEMON_NAME, time_ref); /* unit: s */ + chrony_push_data( + "time_offset_ntp", DAEMON_NAME, + ntohf(chrony_resp.body.tracking.f_current_correction)); /* Offset between + system time and + NTP, unit: s */ + chrony_push_data( + "time_offset", DAEMON_NAME, + ntohf( + chrony_resp.body.tracking + .f_last_offset)); /* Estimated Offset of the NTP time, unit: s */ + chrony_push_data( + "time_offset_rms", DAEMON_NAME, + ntohf(chrony_resp.body.tracking + .f_rms_offset)); /* averaged value of the above, unit: s */ + chrony_push_data( + "frequency_error", DAEMON_NAME, + ntohf(chrony_resp.body.tracking + .f_freq_ppm)); /* Frequency error of the local osc, unit: ppm */ + chrony_push_data("clock_skew_ppm", DAEMON_NAME, + ntohf(chrony_resp.body.tracking.f_skew_ppm)); + chrony_push_data( + "root_delay", DAEMON_NAME, + ntohf(chrony_resp.body.tracking.f_root_delay)); /* Network latency between + local daemon and the + current source */ + chrony_push_data("root_dispersion", DAEMON_NAME, + ntohf(chrony_resp.body.tracking.f_root_dispersion)); + chrony_push_data("clock_last_update", DAEMON_NAME, + ntohf(chrony_resp.body.tracking.f_last_update_interval)); + + return CHRONY_RC_OK; +} + +static int chrony_request_sources_count(unsigned int *p_count) { + /* Requests the number of time sources from the chrony daemon */ + int rc; + size_t chrony_resp_size; + tChrony_Request chrony_req; + tChrony_Response chrony_resp; + + DEBUG(PLUGIN_NAME ": Requesting data"); + chrony_init_req(&chrony_req); + rc = + chrony_query(REQ_N_SOURCES, &chrony_req, &chrony_resp, &chrony_resp_size); + if (rc != 0) { + ERROR(PLUGIN_NAME ": chrony_query (REQ_N_SOURCES) failed with status %i", + rc); + return rc; + } + + *p_count = ntohl(chrony_resp.body.n_sources.f_n_sources); + DEBUG(PLUGIN_NAME ": Getting data of %d clock sources", *p_count); + + return CHRONY_RC_OK; +} + +static int chrony_request_source_data(int p_src_idx, char *src_addr, + size_t addr_size, int *p_is_reachable) { + /* Perform Source data request for source #p_src_idx */ + int rc; + size_t chrony_resp_size; + tChrony_Request chrony_req; + tChrony_Response chrony_resp; + + chrony_init_req(&chrony_req); + chrony_req.body.source_data.f_index = htonl(p_src_idx); + rc = chrony_query(REQ_SOURCE_DATA, &chrony_req, &chrony_resp, + &chrony_resp_size); + if (rc != 0) { + ERROR(PLUGIN_NAME ": chrony_query (REQ_SOURCE_DATA) failed with status %i", + rc); + return rc; + } + + if (ntohs(chrony_resp.body.source_data.f_mode) == MODE_REFCLOCK) + nreftostr(chrony_resp.body.source_data.addr.addr.ip4, src_addr, addr_size); + else + niptoha(&chrony_resp.body.source_data.addr, src_addr, addr_size); + + DEBUG(PLUGIN_NAME ": Source[%d] data: .addr = %s, .poll = %u, .stratum = %u, " + ".state = %u, .mode = %u, .flags = %u, .reach = %u, " + ".latest_meas_ago = %u, .orig_latest_meas = %f, " + ".latest_meas = %f, .latest_meas_err = %f", + p_src_idx, src_addr, ntohs(chrony_resp.body.source_data.f_poll), + ntohs(chrony_resp.body.source_data.f_stratum), + ntohs(chrony_resp.body.source_data.f_state), + ntohs(chrony_resp.body.source_data.f_mode), + ntohs(chrony_resp.body.source_data.f_flags), + ntohs(chrony_resp.body.source_data.f_reachability), + ntohl(chrony_resp.body.source_data.f_since_sample), + ntohf(chrony_resp.body.source_data.f_origin_latest_meas), + ntohf(chrony_resp.body.source_data.f_latest_meas), + ntohf(chrony_resp.body.source_data.f_latest_meas_err)); + + /* Push NaN if source is currently not reachable */ + int is_reachable = ntohs(chrony_resp.body.source_data.f_reachability) & 0x01; + *p_is_reachable = is_reachable; + + /* Forward results to collectd-daemon */ + chrony_push_data_valid("clock_stratum", src_addr, is_reachable, + ntohs(chrony_resp.body.source_data.f_stratum)); + chrony_push_data_valid("clock_state", src_addr, is_reachable, + ntohs(chrony_resp.body.source_data.f_state)); + chrony_push_data_valid("clock_mode", src_addr, is_reachable, + ntohs(chrony_resp.body.source_data.f_mode)); + chrony_push_data_valid("clock_reachability", src_addr, is_reachable, + ntohs(chrony_resp.body.source_data.f_reachability)); + chrony_push_data_valid("clock_last_meas", src_addr, is_reachable, + ntohl(chrony_resp.body.source_data.f_since_sample)); + chrony_push_data_valid( + "time_offset", src_addr, is_reachable, + ntohf(chrony_resp.body.source_data.f_origin_latest_meas)); + + return CHRONY_RC_OK; +} + +static int chrony_request_source_stats(int p_src_idx, const char *src_addr, + const int *p_is_reachable) { + /* Perform Source stats request for source #p_src_idx */ + int rc; + size_t chrony_resp_size; + tChrony_Request chrony_req; + tChrony_Response chrony_resp; + double skew_ppm, frequency_error; + + if (*p_is_reachable == 0) { + skew_ppm = 0; + frequency_error = 0; + } else { + chrony_init_req(&chrony_req); + chrony_req.body.source_stats.f_index = htonl(p_src_idx); + rc = chrony_query(REQ_SOURCE_STATS, &chrony_req, &chrony_resp, + &chrony_resp_size); + if (rc != 0) { + ERROR(PLUGIN_NAME + ": chrony_query (REQ_SOURCE_STATS) failed with status %i", + rc); + return rc; + } + + skew_ppm = ntohf(chrony_resp.body.source_stats.f_skew_ppm); + frequency_error = ntohf(chrony_resp.body.source_stats.f_rtc_gain_rate_ppm); + + DEBUG(PLUGIN_NAME + ": Source[%d] stat: .addr = %s, .ref_id= %u, .n_samples = %u, " + ".n_runs = %u, .span_seconds = %u, .rtc_seconds_fast = %f, " + ".rtc_gain_rate_ppm = %f, .skew_ppm= %f, .est_offset = %f, " + ".est_offset_err = %f", + p_src_idx, src_addr, ntohl(chrony_resp.body.source_stats.f_ref_id), + ntohl(chrony_resp.body.source_stats.f_n_samples), + ntohl(chrony_resp.body.source_stats.f_n_runs), + ntohl(chrony_resp.body.source_stats.f_span_seconds), + ntohf(chrony_resp.body.source_stats.f_rtc_seconds_fast), + frequency_error, skew_ppm, + ntohf(chrony_resp.body.source_stats.f_est_offset), + ntohf(chrony_resp.body.source_stats.f_est_offset_err)); + + } /* if (*is_reachable) */ + + /* Forward results to collectd-daemon */ + chrony_push_data_valid("clock_skew_ppm", src_addr, *p_is_reachable, skew_ppm); + chrony_push_data_valid("frequency_error", src_addr, *p_is_reachable, + frequency_error); /* unit: ppm */ + + return CHRONY_RC_OK; +} + +static int chrony_read(void) { + /* collectd read callback: Perform data acquisition */ + int rc; + unsigned int n_sources; + + if (g_chrony_seq_is_initialized == 0) { + /* Seed RNG for sequence number generation */ + rc = chrony_init_seq(); + if (rc != CHRONY_RC_OK) + return rc; + + g_chrony_seq_is_initialized = 1; + } + + /* Ignore late responses that may have been received */ + chrony_flush_recv_queue(); + + /* Get daemon stats */ + rc = chrony_request_daemon_stats(); + if (rc != CHRONY_RC_OK) + return rc; + + /* Get number of time sources, then check every source for status */ + rc = chrony_request_sources_count(&n_sources); + if (rc != CHRONY_RC_OK) + return rc; + + for (unsigned int now_src = 0; now_src < n_sources; ++now_src) { + char src_addr[IPV6_STR_MAX_SIZE] = {0}; + int is_reachable; + rc = chrony_request_source_data(now_src, src_addr, sizeof(src_addr), + &is_reachable); + if (rc != CHRONY_RC_OK) + return rc; + + rc = chrony_request_source_stats(now_src, src_addr, &is_reachable); + if (rc != CHRONY_RC_OK) + return rc; + } + return CHRONY_RC_OK; +} + +static int chrony_shutdown(void) { + /* Collectd shutdown callback: Free mem */ + if (g_chrony_is_connected != 0) { + close(g_chrony_socket); + g_chrony_is_connected = 0; + } + if (g_chrony_host != NULL) + sfree(g_chrony_host); + + if (g_chrony_port != NULL) + sfree(g_chrony_port); + + if (g_chrony_plugin_instance != NULL) + sfree(g_chrony_plugin_instance); + + return CHRONY_RC_OK; +} + +void module_register(void) { + plugin_register_config(PLUGIN_NAME_SHORT, chrony_config, g_config_keys, + g_config_keys_num); + plugin_register_read(PLUGIN_NAME_SHORT, chrony_read); + plugin_register_shutdown(PLUGIN_NAME_SHORT, chrony_shutdown); +} diff --git a/src/collectd-email.pod b/src/collectd-email.pod index 6f58542784..20375e2cd9 100644 --- a/src/collectd-email.pod +++ b/src/collectd-email.pod @@ -33,7 +33,7 @@ with the plugin: =over 4 -=item +=item * E-Mail type (e.g. "ham", "spam", "virus", ...) and size (bytes): @@ -41,13 +41,13 @@ E-Mail type (e.g. "ham", "spam", "virus", ...) and size (bytes): If C is less than or equal to zero, C is ignored. -=item +=item * Spam score: s: -=item +=item * Successful spam checks (e.g. "BAYES_99", "SUBJECT_DRUG_GAP_C", ...): @@ -69,6 +69,6 @@ The C has been written by Sebastian Harl EshEatEto The SpamAssassin-plugin has been written by Alexander Wirt EformorerEatEformorer.deE. -This manpage has been written by Florian Forster EoctoEatEverplant.orgE. +This manpage has been written by Florian Forster EoctoEatEcollectd.orgE. =cut diff --git a/src/collectd-exec.pod b/src/collectd-exec.pod index 2c5963025a..dc79e37e4b 100644 --- a/src/collectd-exec.pod +++ b/src/collectd-exec.pod @@ -17,7 +17,7 @@ collectd-exec - Documentation of collectd's C =head1 DESCRIPTION -The C forks of an executable either to receive values or to +The C forks off an executable either to receive values or to dispatch notifications to the outside world. The syntax of the configuration is explained in L but summarized in the above synopsis. @@ -42,7 +42,7 @@ time and continuously write values to C. See L below for a description of the output format expected from these programs. -B If the executable only writes one value and then exits I will be +B If the executable only writes one value and then exits it will be executed every I seconds. If I is short (the default is 10 seconds) this may result in serious system load. @@ -73,7 +73,7 @@ Each line beginning with a C<#> (hash mark) is ignored. =item B I [I] I Submits one or more values (identified by I, see below) to the -daemon which will dispatch it to all it's write-plugins. +daemon which will dispatch it to all its write-plugins. An I is of the form CBIB<->IBIB<->I> with both @@ -94,7 +94,7 @@ I is a colon-separated list of the time and the values, each either an integer if the data-source is a counter, or a double if the data-source is of type "gauge". You can submit an undefined gauge-value by using B. When submitting B to a counter the behavior is undefined. The time is given as -epoch (i.Ee. standard UNIX time). +epoch (i.Ee. standard UNIX time) or B to use the current time. You can mix options and values, but the order is important: Options only effect following values, so specifying an option as last field is allowed, but @@ -110,6 +110,10 @@ The currently defined B are: Gives the interval in which the data identified by I is being collected. +=item meta:B=I + +Add meta data with the key B and the value I. + =back Please note that this is the same format as used in the B, see @@ -169,6 +173,19 @@ table. All the options are optional, but B without B or B without B doesn't make much sense and should be avoided. +=item BI + +Sets user defined meta information. The B key is a single character +defining the type of the meta information. + +The current supported types are: + +=over 8 + +=item B A string passed as-is. + +=back + =back =back @@ -188,13 +205,13 @@ The data is passed to the executables over C in a format very similar to HTTP: At first there is a "header" with one line per field. Every line consists of a field name, ended by a colon, and the associated value until end-of-line. The "header" is ended by two newlines immediately following another, -i.Ee. an empty line. The rest, basically the "body", is the message of -the notification. +i.e. an empty line. The rest, basically the "body", is the message of the +notification. The following is an example notification passed to a program: Severity: FAILURE - Time: 1200928930 + Time: 1200928930.515 Host: myhost.mydomain.org \n This is a test notification to demonstrate the format @@ -210,7 +227,9 @@ Severity of the notification. May either be B, B, or B. =item B