config.log
config.status
libtool
-src/.deps
src/collectd.conf
src/config.h
src/libcollectdclient/libcollectdclient.pc
*.lo
*.o
.libs/
-src/collectd
+.deps/
src/collectd-nagios
src/collectd-tg
src/collectdctl
# python stuff
*.pyc
-# tag stuff
-src/tags
-
# backup stuff
*~
-# tests stuff
-src/tests/.deps/
-src/tests/mock/.deps/
-src/tests/.dirstamp
-src/tests/mock/.dirstamp
-test*.log
+# Unit tests
+src/tests/
+test_*
-# new daemon repo
-src/daemon/.deps/
-src/daemon/.dirstamp
+# src/daemon/...
src/daemon/collectd
--- /dev/null
+sudo: required
+dist: trusty
+compiler:
+ - gcc
+ - clang
+language: c
+before_install:
+ - sudo apt-get update -qq
+ - sudo apt-get install -qq --no-install-recommends
+ iptables-dev
+ libatasmart-dev
+ libcap-dev
+ libcurl4-gnutls-dev
+ libdbi0-dev
+ libesmtp-dev
+ libganglia1-dev
+ libgcrypt11-dev
+ libglib2.0-dev
+ libhiredis-dev
+ libi2c-dev
+ libldap2-dev
+ libltdl-dev
+ liblvm2-dev
+ libmemcached-dev
+ libmnl-dev
+ libmodbus-dev
+ libmosquitto0-dev
+ libmysqlclient-dev
+ libnotify-dev
+ libopenipmi-dev
+ liboping-dev
+ libow-dev
+ libpcap-dev
+ libperl-dev
+ libpq-dev
+ libprotobuf-c0-dev
+ librabbitmq-dev
+ librdkafka-dev
+ librrd-dev
+ libsensors4-dev
+ libsigrok-dev
+ libsnmp-dev
+ libstatgrab-dev
+ libtokyocabinet-dev
+ libtokyotyrant-dev
+ libudev-dev
+ libupsclient-dev
+ libvarnish-dev
+ libvirt-dev
+ libxml2-dev
+ libyajl-dev
+ linux-libc-dev
+ perl
+ protobuf-c-compiler
+ python-dev
+script: sh build.sh && ./configure --with-python=/usr/bin/python && make distcheck DISTCHECK_CONFIGURE_FLAGS="--with-python=/usr/bin/python"
Cyril Feraudet <cyril at feraudet.com>
- ethstat plugin.
+Dagobert Michelsen <dam at opencsw.org>
+ - zone plugin.
+
Dan Berrange <berrange at redhat.com>
- uuid plugin.
- ip6tables support in the iptables plugin.
- openvpn plugin (support for more status file formats)
+Mathijs Möhlmann <collectd at mmrc.nl>
+ - zone plugin.
+
Michael Hanselmann <public at hansmi.ch>
- md plugin.
--- /dev/null
+# Thanks !
+
+Thanks for your feedback & contributions to the
+[collectd project](https://collectd.org/) !
+
+## Need help using collectd ?
+
+Please use the
+[collectd mailing list](http://mailman.verplant.org/listinfo/collectd) or the
+[#collectd IRC channel](https://webchat.freenode.net/?channels=#collectd).
+We'd like to keep the github issue tracker for bugreports and patch reviews.
+
+## Found a bug ?
+
+Please mention the exact collectd version you're using, how it was installed
+(built from source, or installed from packages. Where was it downloaded
+from). Which operating system/architecture, distribution and version are you
+running collectd on.
+
+If collectd crashes, try to get a
+[stack trace](https://collectd.org/wiki/index.php/Core_file).
+
+## Fixed a bug ? Want to add a feature ?
+
+Using git/github to submit changes is not mandatory. Sending patches to the
+[mailing-list](http://mailman.verplant.org/listinfo/collectd) is also fine.
+In both cases, take a quick look at the
+[submission guidelines](https://collectd.org/wiki/index.php/Submitting_patches)
+and the [coding style recommendations](https://collectd.org/wiki/index.php/Coding_style).
+
+Please try to submit **bugfixes** to the
+[oldest release branch](https://github.com/collectd/collectd/milestones) on
+which the bug is found, so that it gets included in every future **bugfix
+release**.
+
+Please try to submit **new features** to the master branch (which will become
+the next **feature release**).
+
Reads values from Modbus/TCP enabled devices. Supports reading values
from multiple "slaves" so gateway devices can be used.
+ - mqtt
+ Publishes and subscribes to MQTT topics.
+
- multimeter
Information provided by serial multimeters, such as the `Metex
M-4650CR'.
- 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.
* libprotobuf-c, protoc-c (optional)
Used by the `pinba' plugin to generate a parser for the network packets
- sent by the Pinba PHP extension, and by the `write_riemann' plugin to
- generate events to be sent to a Riemann server.
+ sent by the Pinba PHP extension.
<http://code.google.com/p/protobuf-c/>
* libpython (optional)
`varnish' plugin.
<http://varnish-cache.org>
+ * riemann-c-client (optional)
+ For the `write_riemann' plugin.
+ <https://github.com/algernon/riemann-c-client>
+
Configuring / Compiling / Installing
------------------------------------
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:
+ 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 the JAVA_LDFLAGS is done automatically, you don't have to
+ Adding "-ljvm" to JAVA_LIBS is done automatically, you don't have to
do that.
Generating the configure script
- bison
- libtool
- libtool-ltdl
+- pkg-config
The `build.sh' script takes no arguments.
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<GenericJMXConfMBean> _mbeans = null;
/*
return Collectd.getHostname();
} /* }}} String getHost */
-private void connect () /* {{{ */
-{
- JMXServiceURL service_url;
- JMXConnector connector;
- Map environment;
+ private void connect () /* {{{ */
+ {
+ JMXServiceURL service_url;
+ Map<String,Object> 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.put(JMXConnectorFactory.PROTOCOL_PROVIDER_CLASS_LOADER, this.getClass().getClassLoader());
- }
+ environment = new HashMap<String,Object> ();
+ 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
- *
- * <Connection>
- * Host "tomcat0.mycompany"
- * ServiceURL "service:jmx:rmi:///jndi/rmi://localhost:17264/jmxrmi"
- * Collect "java.lang:type=GarbageCollector,name=Copy"
- * Collect "java.lang:type=Memory"
- * </Connection>
- *
- */
+ this._jmx_connector = null;
+ this._mbean_connection = null;
+ } /* }}} void disconnect */
+
+ /*
+ * public methods
+ *
+ * <Connection>
+ * Host "tomcat0.mycompany"
+ * ServiceURL "service:jmx:rmi:///jndi/rmi://localhost:17264/jmxrmi"
+ * Collect "java.lang:type=GarbageCollector,name=Copy"
+ * Collect "java.lang:type=Memory"
+ * </Connection>
+ *
+ */
public GenericJMXConfConnection (OConfigItem ci) /* {{{ */
throws IllegalArgumentException
{
{
PluginData pd;
+ // try to connect
connect ();
- if (this._jmx_connection == null)
+ if (this._mbean_connection == null)
return;
Collectd.logDebug ("GenericJMXConfConnection.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 */
import java.util.Arrays;
import java.util.List;
+import java.util.Collection;
import java.util.Set;
import java.util.Iterator;
import java.util.ArrayList;
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;
private List<String> _attributes;
private String _instance_prefix;
private List<String> _instance_from;
+ private String _plugin_name;
private boolean _is_table;
/**
{
if (value instanceof CompositeData)
return (queryAttributeRecursive ((CompositeData) value, attrName));
+ else if (value instanceof TabularData)
+ return (queryAttributeRecursive ((TabularData) value, attrName));
+ else
+ return (null);
+ }
+ } /* }}} queryAttributeRecursive */
+
+ private Object queryAttributeRecursive (TabularData parent, /* {{{ */
+ List<String> attrName)
+ {
+ String key;
+ Object value = null;
+
+ key = attrName.remove (0);
+
+ TabularData tabularData = (TabularData) parent;
+ Collection<CompositeData> table =
+ (Collection<CompositeData>)tabularData.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));
+ else if (value instanceof TabularData)
+ return (queryAttributeRecursive ((TabularData) value, attrName));
else
return (null);
}
{
if (value instanceof CompositeData)
return (queryAttributeRecursive((CompositeData) value, attrNameList));
+ else if (value instanceof TabularData)
+ return (queryAttributeRecursive((TabularData) value, attrNameList));
else if (value instanceof OpenType)
{
OpenType ot = (OpenType) value;
else
{
Collectd.logError ("GenericJMXConfValue: Received object of "
- + "unknown class.");
+ + "unknown class. " + attrName + " " + ((value == null)?"null":value.getClass().getName()));
return (null);
}
}
this._attributes = new ArrayList<String> ();
this._instance_prefix = null;
this._instance_from = new ArrayList<String> ();
+ this._plugin_name = null;
this._is_table = false;
/*
if (tmp != null)
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 ()));
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
sub _escape_argument
{
- local $_ = shift;
+ my $arg = shift;
- return $_ if /^\w+$/;
+ return $arg if $arg =~ /^\w+$/;
- s#\\#\\\\#g;
- s#"#\\"#g;
- return "\"$_\"";
+ $arg =~ s#\\#\\\\#g;
+ $arg =~ s#"#\\"#g;
+ return "\"$arg\"";
}
# Send a command on a socket, including any required argument escaping.
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";
+ $fh->print($msg);
+
+ $msg = <$fh>;
+ chomp ($msg);
+ _debug "<- $msg\n";
+
+ my ($status, $error) = split / /, $msg, 2;
+ return 1 if $status == 0;
+
+ $self->{error} = $error;
+ return;
+}
=head1 PUBLIC METHODS
. _escape_argument ($identifier)
. $interval
. ' ' . _escape_argument ($values) . "\n";
- _debug "-> $msg";
- $fh->print($msg);
- $msg = <$fh>;
- chomp $msg;
- _debug "<- $msg\n";
-
- ($status, $msg) = split / /, $msg, 2;
- return 1 if $status == 0;
-
- $self->{error} = $msg;
- return;
+ return $self->_send_message($msg);
} # putval
=item I<$res> = I<$self>-E<gt>B<listval_filter> ( C<%identifier> )
. join (' ', map { $_ . '=' . _escape_argument ($args{$_}) } keys %args)
. "\n";
- _debug "-> $msg";
- $fh->print($msg);
-
- $msg = <$fh>;
- chomp $msg;
- _debug "<- $msg\n";
-
- ($status, $msg) = split / /, $msg, 2;
- return 1 if $status == 0;
-
- $self->{error} = $msg;
- return;
+ return $self->_send_message($msg);
} # putnotif
=item I<$self>-E<gt>B<flush> (B<timeout> =E<gt> I<$timeout>, B<plugins> =E<gt> [...], B<identifier> =E<gt> [...]);
my $fh = $self->{sock} or confess;
- my $status = 0;
my $msg = "FLUSH";
$msg .= " timeout=$args{timeout}" if defined $args{timeout};
if ($args{identifier})
{
+ my $pre = $msg;
for my $identifier (@{$args{identifier}})
{
my $ident_str;
}
$ident_str = _create_identifier ($identifier) or return;
- $msg .= ' identifier=' . _escape_argument ($ident_str);
+ $ident_str = ' identifier=' . _escape_argument ($ident_str);
+
+ if (length($msg)+length($ident_str) >= 1023) { #1024 - 1 byte for \n
+ $self->_send_message($msg) or return;
+ $msg = $pre;
+ }
+
+ $msg .= $ident_str;
}
}
-
- $msg .= "\n";
-
- _debug "-> $msg";
- $fh->print($msg);
-
- $msg = <$fh>;
- chomp ($msg);
- _debug "<- $msg\n";
-
- ($status, $msg) = split / /, $msg, 2;
- return 1 if $status == 0;
-
- $self->{error} = $msg;
- return;
+
+ return $self->_send_message($msg);
}
sub error
my ($nresults, $resultdata) = @$results;
my $r = $s->getval(%{Collectd::Unixsock::_parse_identifier($attr)});
is(ref $r, 'HASH', "Got a result for $attr");
- is(scalar keys $r, $nresults, "$nresults result result for $attr");
+ is(scalar keys %$r, $nresults, "$nresults result result for $attr");
is_deeply($r, $resultdata, "Data or $attr matches");
}
done
}
-check_for_application lex yacc autoheader aclocal automake autoconf
+check_for_application lex bison autoheader aclocal automake autoconf
# Actually we don't need the pkg-config executable, but we need the M4 macros.
# We check for `pkg-config' here and hope that M4 macros will then be
dnl Process this file with autoconf to produce a configure script.
AC_INIT([collectd],[m4_esyscmd(./version-gen.sh)])
-AC_CONFIG_SRCDIR(src/)
+AC_CONFIG_SRCDIR(src/target_set.c)
AC_CONFIG_HEADERS(src/config.h)
AC_CONFIG_AUX_DIR([libltdl/config])
AM_CONDITIONAL([BUILD_INCLUDED_LTDL], [test "x$LTDLDEPS" != "x"])
-AM_INIT_AUTOMAKE([tar-pax dist-bzip2 foreign])
+AM_INIT_AUTOMAKE([subdir-objects tar-pax dist-bzip2 foreign])
m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
AC_LANG(C)
AC_DEFINE([KERNEL_OPENBSD], 1, [True if program is to be compiled for an OpenBSD kernel])
ac_system="OpenBSD"
;;
+ *netbsd*)
+ AC_DEFINE([KERNEL_NETBSD], 1, [True if program is to be compiled for a NetBSD kernel])
+ ac_system="NetBSD"
+ ;;
*aix*)
AC_DEFINE([KERNEL_AIX], 1, [True if program is to be compiled for a AIX kernel])
ac_system="AIX"
AC_CHECK_HEADERS(stdio.h errno.h math.h stdarg.h syslog.h fcntl.h signal.h assert.h sys/types.h sys/socket.h sys/select.h poll.h netdb.h arpa/inet.h sys/resource.h sys/param.h kstat.h regex.h sys/ioctl.h endian.h sys/isa_defs.h fnmatch.h libgen.h)
+# For entropy plugin on newer NetBSD
+AC_CHECK_HEADERS(sys/rndio.h, [], [],
+[#if HAVE_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+#if HAVE_SYS_IOCTL_H
+# include <sys/ioctl.h>
+#endif
+#if HAVE_SYS_PARAM_H
+# include <sys/param.h>
+#endif
+])
+
# For ping library
AC_CHECK_HEADERS(netinet/in_systm.h, [], [],
[#if HAVE_STDINT_H
AC_MSG_CHECKING([for sysctl kern.cp_times])
if test -x /sbin/sysctl
then
- /sbin/sysctl kern.cp_times 2>/dev/null
+ /sbin/sysctl kern.cp_times >/dev/null 2>&1
if test $? -eq 0
then
AC_MSG_RESULT([yes])
AC_MSG_RESULT([no])
fi
+AC_MSG_CHECKING([for sysctl kern.cp_time])
+if test -x /sbin/sysctl
+then
+ /sbin/sysctl kern.cp_time >/dev/null 2>&1
+ if test $? -eq 0
+ then
+ AC_MSG_RESULT([yes])
+ AC_DEFINE(HAVE_SYSCTL_KERN_CP_TIME, 1,
+ [Define if sysctl supports kern.cp_time])
+ else
+ AC_MSG_RESULT([no])
+ fi
+else
+ AC_MSG_RESULT([no])
+fi
+
# For hddtemp module
AC_CHECK_HEADERS(linux/major.h)
have_linux_raid_md_u_h="no"
fi
-# For the swap module
+# For the wireless module
have_linux_wireless_h="no"
if test "x$ac_system" = "xLinux"
then
#endif
])
-AC_CHECK_HEADERS(netinet/ip_compat.h)
-
have_net_pfvar_h="no"
AC_CHECK_HEADERS(net/pfvar.h,
[have_net_pfvar_h="yes"],
# Checks for typedefs, structures, and compiler characteristics.
#
AC_C_CONST
-AC_C_INLINE
-AC_TYPE_OFF_T
AC_TYPE_PID_T
AC_TYPE_SIZE_T
-AC_TYPE_SSIZE_T
AC_TYPE_UID_T
-AC_TYPE_UINT32_T
AC_HEADER_TIME
#
if test "x$have_clock_gettime" = "xyes"
then
AC_DEFINE(HAVE_CLOCK_GETTIME, 1, [Define if the clock_gettime(2) function is available.])
-else
- AC_MSG_WARN(cannot find clock_gettime)
fi
nanosleep_needs_rt="no"
#include <kvm.h>
])
+
+AC_CHECK_MEMBERS([struct kinfo_proc2.p_pid, struct kinfo_proc2.p_uru_maxrss],
+ [
+ AC_DEFINE(HAVE_STRUCT_KINFO_PROC2_NETBSD, 1,
+ [Define if struct kinfo_proc2 exists in the NetBSD variant.])
+ have_struct_kinfo_proc2_netbsd="yes"
+ ],
+ [
+ have_struct_kinfo_proc2_netbsd="no"
+ ],
+ [
+#include <sys/param.h>
+#include <sys/sysctl.h>
+#include <kvm.h>
+ ])
+
+
+
AC_CHECK_MEMBERS([struct udphdr.uh_dport, struct udphdr.uh_sport], [], [],
[#define _BSD_SOURCE
#define _DEFAULT_SOURCE
fi
fi
+# --with-libpthread {{{
+AC_ARG_WITH(libpthread, [AS_HELP_STRING([--with-libpthread=@<:@=PREFIX@:>@], [Path to libpthread.])],
+[ if test "x$withval" != "xno" \
+ && test "x$withval" != "xyes"
+ then
+ LDFLAGS="$LDFLAGS -L$withval/lib"
+ CPPFLAGS="$CPPFLAGS -I$withval/include"
+ with_libpthread="yes"
+ else
+ if test "x$withval" = "xno"
+ then
+ with_libpthread="no (disabled)"
+ fi
+ fi
+], [with_libpthread="yes"])
+
+AC_SUBST([PTHREAD_LIBS])
+if test "x$with_libpthread" = "xyes"
+then
+ SAVE_LIBS="$LIBS"
+ AC_CHECK_LIB(pthread, pthread_create, [], [with_libpthread="no (Symbol 'pthread_create' not found)"], [])
+ PTHREAD_LIBS="$LIBS"
+ LIBS="$SAVE_LIBS"
+fi
+
+if test "x$with_libpthread" = "xyes"
+then
+ AC_CHECK_HEADERS(pthread.h,, [with_libpthread="no (pthread.h not found)"])
+fi
+if test "x$with_libpthread" = "xyes"
+then
+ collect_pthread=1
+else
+ collect_pthread=0
+fi
+AC_DEFINE_UNQUOTED(HAVE_LIBPTHREAD, [$collect_pthread],
+ [Wether or not to use pthread (POSIX threads) library])
+AM_CONDITIONAL(BUILD_WITH_LIBPTHREAD, test "x$with_libpthread" = "xyes")
+# }}}
+
m4_divert_once([HELP_WITH], [
collectd additional packages:])
AC_CHECK_LIB(gcrypt, gcry_md_hash_buffer,
[with_libgcrypt="yes"],
[with_libgcrypt="no (symbol gcry_md_hash_buffer not found)"])
-
- if test "$with_libgcrypt" != "no"; then
- m4_ifdef([AM_PATH_LIBGCRYPT],[AM_PATH_LIBGCRYPT(1:1.2.0,,with_libgcrypt="no (version 1.2.0+ required)")])
- GCRYPT_CPPFLAGS="$LIBGCRYPT_CPPFLAGS $LIBGCRYPT_CFLAGS"
- GCRYPT_LIBS="$LIBGCRYPT_LIBS"
- fi
fi
CPPFLAGS="$SAVE_CPPFLAGS"
then
with_java_home="/usr/lib/jvm"
fi
-with_java_vmtype="client"
-with_java_cflags=""
-with_java_libs=""
JAVAC="$JAVAC"
JAR="$JAR"
AC_ARG_WITH(java, [AS_HELP_STRING([--with-java@<:@=PREFIX@:>@], [Path to Java home.])],
then
AC_MSG_NOTICE([Building with JAVA_LDFLAGS set to: $JAVA_LDFLAGS])
fi
+if test "x$JAVA_LIBS" != "x"
+then
+ AC_MSG_NOTICE([Building with JAVA_LIBS set to: $JAVA_LIBS])
+fi
if test "x$JAVAC" = "x"
then
with_javac_path="$PATH"
SAVE_CPPFLAGS="$CPPFLAGS"
SAVE_CFLAGS="$CFLAGS"
SAVE_LDFLAGS="$LDFLAGS"
+SAVE_LIBS="$LIBS"
CPPFLAGS="$CPPFLAGS $JAVA_CPPFLAGS"
CFLAGS="$CFLAGS $JAVA_CFLAGS"
LDFLAGS="$LDFLAGS $JAVA_LDFLAGS"
+LIBS="$LIBS $JAVA_LIBS"
if test "x$with_java" = "xyes"
then
then
AC_CHECK_LIB(jvm, JNI_CreateJavaVM,
[with_java="yes"],
- [with_java="no (libjvm not found)"],
- [$JAVA_LIBS])
+ [with_java="no (Symbol 'JNI_CreateJavaVM' not found)"],
+ [$JAVA_LIBS $PTHREAD_LIBS])
fi
if test "x$with_java" = "xyes"
then
CPPFLAGS="$SAVE_CPPFLAGS"
CFLAGS="$SAVE_CFLAGS"
LDFLAGS="$SAVE_LDFLAGS"
+LIBS="$SAVE_LIBS"
AC_SUBST(JAVA_CPPFLAGS)
AC_SUBST(JAVA_CFLAGS)
with_liblvm2app_ldflags=""
AC_ARG_WITH(liblvm2app, [AS_HELP_STRING([--with-liblvm2app@<:@=PREFIX@:>@], [Path to liblvm2app.])],
[
- if test "x$withval" != "xno" && test "x$withval" != "xyes"
- then
- with_liblvm2app_cppflags="-I$withval/include"
- with_liblvm2app_ldflags="-L$withval/lib"
- with_liblvm2app="yes"
- else
- with_liblvm2app="$withval"
+ if test "x$withval" = "xno"
+ then
+ with_liblvm2app="no"
+ else
+ with_liblvm2app="yes"
+ if test "x$withval" != "xyes"
+ then
+ with_liblvm2app_cppflags="-I$withval/include"
+ with_liblvm2app_ldflags="-L$withval/lib"
+ fi
fi
],
[
- with_liblvm2app="yes"
+ if test "x$ac_system" = "xLinux"
+ then
+ with_liblvm2app="yes"
+ else
+ with_liblvm2app="no (Linux only library)"
+ fi
])
if test "x$with_liblvm2app" = "xyes"
then
AM_CONDITIONAL(BUILD_WITH_LIBMONGOC, test "x$with_libmongoc" = "xyes")
# }}}
+# --with-libmosquitto {{{
+with_libmosquitto_cppflags=""
+with_libmosquitto_ldflags=""
+AC_ARG_WITH(libmosquitto, [AS_HELP_STRING([--with-libmosquitto@<:@=PREFIX@:>@], [Path to libmosquitto.])],
+[
+ if test "x$withval" != "xno" && test "x$withval" != "xyes"
+ then
+ with_libmosquitto_cppflags="-I$withval/include"
+ with_libmosquitto_ldflags="-L$withval/lib"
+ with_libmosquitto="yes"
+ else
+ with_libmosquitto="$withval"
+ fi
+],
+[
+ with_libmosquitto="yes"
+])
+if test "x$with_libmosquitto" = "xyes"
+then
+ SAVE_CPPFLAGS="$CPPFLAGS"
+ CPPFLAGS="$CPPFLAGS $with_libmosquitto_cppflags"
+
+ AC_CHECK_HEADERS(mosquitto.h, [with_libmosquitto="yes"], [with_libmosquitto="no (mosquitto.h not found)"])
+
+ CPPFLAGS="$SAVE_CPPFLAGS"
+fi
+if test "x$with_libmosquitto" = "xyes"
+then
+ SAVE_LDFLAGS="$LDFLAGS"
+ SAVE_CPPFLAGS="$CPPFLAGS"
+ LDFLAGS="$LDFLAGS $with_libmosquitto_ldflags"
+ CPPFLAGS="$CPPFLAGS $with_libmosquitto_cppflags"
+
+ AC_CHECK_LIB(mosquitto, mosquitto_connect, [with_libmosquitto="yes"], [with_libmosquitto="no (libmosquitto not found)"])
+
+ LDFLAGS="$SAVE_LDFLAGS"
+ CPPFLAGS="$SAVE_CPPFLAGS"
+fi
+if test "x$with_libmosquitto" = "xyes"
+then
+ BUILD_WITH_LIBMOSQUITTO_CPPFLAGS="$with_libmosquitto_cppflags"
+ BUILD_WITH_LIBMOSQUITTO_LDFLAGS="$with_libmosquitto_ldflags"
+ BUILD_WITH_LIBMOSQUITTO_LIBS="-lmosquitto"
+ AC_SUBST(BUILD_WITH_LIBMOSQUITTO_CPPFLAGS)
+ AC_SUBST(BUILD_WITH_LIBMOSQUITTO_LDFLAGS)
+ AC_SUBST(BUILD_WITH_LIBMOSQUITTO_LIBS)
+fi
+# }}}
+
# --with-libmysql {{{
with_mysql_config="mysql_config"
with_mysql_cflags=""
if test "x$LIBNETAPP_LIBS" = "x"
then
- LIBNETAPP_LIBS="-lpthread -lxml -ladt -lssl -lm -lcrypto -lz"
+ LIBNETAPP_LIBS="$PTHREAD_LIBS -lxml -ladt -lssl -lm -lcrypto -lz"
fi
AC_MSG_NOTICE([netapp LIBS: $LIBNETAPP_LIBS])
# --with-libowcapi {{{
with_libowcapi_cppflags=""
-with_libowcapi_libs="-lowcapi"
+with_libowcapi_ldflags=""
AC_ARG_WITH(libowcapi, [AS_HELP_STRING([--with-libowcapi@<:@=PREFIX@:>@], [Path to libowcapi.])],
[
if test "x$withval" != "xno" && test "x$withval" != "xyes"
then
with_libowcapi_cppflags="-I$withval/include"
- with_libowcapi_libs="-L$withval/lib -lowcapi"
+ with_libowcapi_ldflags="-L$withval/lib"
with_libowcapi="yes"
else
with_libowcapi="$withval"
if test "x$with_libowcapi" = "xyes"
then
SAVE_CPPFLAGS="$CPPFLAGS"
- CPPFLAGS="$with_libowcapi_cppflags"
+ CPPFLAGS="$CPPFLAGS $with_libowcapi_cppflags"
AC_CHECK_HEADERS(owcapi.h, [with_libowcapi="yes"], [with_libowcapi="no (owcapi.h not found)"])
then
SAVE_LDFLAGS="$LDFLAGS"
SAVE_CPPFLAGS="$CPPFLAGS"
- LDFLAGS="$with_libowcapi_libs"
+ LDFLAGS="$LDFLAGS $with_libowcapi_ldflags"
CPPFLAGS="$with_libowcapi_cppflags"
AC_CHECK_LIB(owcapi, OW_get, [with_libowcapi="yes"], [with_libowcapi="no (libowcapi not found)"])
if test "x$with_libowcapi" = "xyes"
then
BUILD_WITH_LIBOWCAPI_CPPFLAGS="$with_libowcapi_cppflags"
- BUILD_WITH_LIBOWCAPI_LIBS="$with_libowcapi_libs"
+ BUILD_WITH_LIBOWCAPI_LDFLAGS="$with_libowcapi_ldflags"
+ BUILD_WITH_LIBOWCAPI_LIBS="-lowcapi"
AC_SUBST(BUILD_WITH_LIBOWCAPI_CPPFLAGS)
+ AC_SUBST(BUILD_WITH_LIBOWCAPI_LDFLAGS)
AC_SUBST(BUILD_WITH_LIBOWCAPI_LIBS)
fi
# }}}
AM_CONDITIONAL(BUILD_WITH_LIBPQ, test "x$with_libpq" = "xyes")
# }}}
-# --with-libpthread {{{
-AC_ARG_WITH(libpthread, [AS_HELP_STRING([--with-libpthread=@<:@=PREFIX@:>@], [Path to libpthread.])],
-[ if test "x$withval" != "xno" \
- && test "x$withval" != "xyes"
- then
- LDFLAGS="$LDFLAGS -L$withval/lib"
- CPPFLAGS="$CPPFLAGS -I$withval/include"
- with_libpthread="yes"
- else
- if test "x$withval" = "xno"
- then
- with_libpthread="no (disabled)"
- fi
- fi
-], [with_libpthread="yes"])
-if test "x$with_libpthread" = "xyes"
-then
- AC_CHECK_LIB(pthread, pthread_create, [with_libpthread="yes"], [with_libpthread="no (libpthread not found)"], [])
-fi
-
-if test "x$with_libpthread" = "xyes"
-then
- AC_CHECK_HEADERS(pthread.h,, [with_libpthread="no (pthread.h not found)"])
-fi
-if test "x$with_libpthread" = "xyes"
-then
- collect_pthread=1
-else
- collect_pthread=0
-fi
-AC_DEFINE_UNQUOTED(HAVE_LIBPTHREAD, [$collect_pthread],
- [Wether or not to use pthread (POSIX threads) library])
-AM_CONDITIONAL(BUILD_WITH_LIBPTHREAD, test "x$with_libpthread" = "xyes")
-# }}}
-
# --with-python {{{
with_python_prog=""
with_python_path="$PATH"
SAVE_CPPFLAGS="$CPPFLAGS"
CPPFLAGS="$CPPFLAGS $with_sensors_cflags"
-# AC_CHECK_HEADERS(sensors/sensors.h,
-# [
-# AC_DEFINE(HAVE_SENSORS_SENSORS_H, 1, [Define to 1 if you have the <sensors/sensors.h> header file.])
-# ],
-# [with_libsensors="no (sensors/sensors.h not found)"])
AC_CHECK_HEADERS(sensors/sensors.h, [], [with_libsensors="no (sensors/sensors.h not found)"])
CPPFLAGS="$SAVE_CPPFLAGS"
if test "x$with_libstatgrab" = "xyes"
then
SAVE_CFLAGS="$CFLAGS"
+ SAVE_LDFLAGS="$LDFLAGS"
SAVE_LIBS="$LIBS"
CFLAGS="$CFLAGS $with_libstatgrab_cflags"
fi
# }}}
+# --with-libxenctrl {{{
+with_libxenctrl_cppflags=""
+with_libxenctrl_ldflags=""
+AC_ARG_WITH(libxenctrl, [AS_HELP_STRING([--with-libxenctrl@<:@=PREFIX@:>@], [Path to libxenctrl.])],
+[
+ if test "x$withval" != "xno" && test "x$withval" != "xyes"
+ then
+ with_libxenctrl_cppflags="-I$withval/include"
+ with_libxenctrl_ldflags="-L$withval/lib"
+ with_libxenctrl="yes"
+ else
+ with_libxenctrl="$withval"
+ fi
+],
+[
+ with_libxenctrl="yes"
+])
+if test "x$with_libxenctrl" = "xyes"
+then
+ SAVE_CPPFLAGS="$CPPFLAGS"
+ CPPFLAGS="$CPPFLAGS $with_libxenctrl_cppflags"
+
+ AC_CHECK_HEADERS(xenctrl.h, [with_libxenctrl="yes"], [with_libxenctrl="no (xenctrl.h not found)"])
+
+ CPPFLAGS="$SAVE_CPPFLAGS"
+fi
+if test "x$with_libxenctrl" = "xyes"
+then
+ SAVE_CPPFLAGS="$CPPFLAGS"
+ SAVE_LDFLAGS="$LDFLAGS"
+ CPPFLAGS="$CPPFLAGS $with_libxenctrl_cppflags"
+ LDFLAGS="$LDFLAGS $with_libxenctrl_ldflags"
+
+ #Xen versions older than 3.4 has no xc_getcpuinfo()
+ AC_CHECK_LIB(xenctrl, xc_getcpuinfo, [with_libxenctrl="yes"], [with_libxenctrl="no (symbol 'xc_getcpuinfo' not found)"], [])
+
+ CPPFLAGS="$SAVE_CPPFLAGS"
+ LDFLAGS="$SAVE_LDFLAGS"
+fi
+
# --with-libxmms {{{
with_xmms_config="xmms-config"
with_xmms_cflags=""
AC_MSG_NOTICE([Not checking for Intel Mic: Manually configured])
with_mic_cflags="-I$withval/include"
with_mic_ldpath="-L$withval/lib/Linux"
- with_mic_libs="-lMicAccessSDK -lscif -lpthread"
+ with_mic_libs="$PTHREAD_LIBS -lMicAccessSDK -lscif"
with_mic="yes"
fi; fi; fi
],
AC_CHECK_LIB(MicAccessSDK, MicInitAPI,
[with_mic_ldpath="$with_mic_ldpath"
- with_mic_libs="-lMicAccessSDK -lscif -lpthread"],
- [with_mic="no (symbol MicInitAPI not found)"],[-lscif -lpthread])
+ with_mic_libs="$PTHREAD_LIBS -lMicAccessSDK -lscif"],
+ [with_mic="no (symbol MicInitAPI not found)"],[$PTHREAD_LIBS -lscif])
CPPFLAGS="$SAVE_CPPFLAGS"
LDFLAGS="$SAVE_LDFLAGS"
PKG_CHECK_MODULES([LIBNOTIFY], [libnotify],
[with_libnotify="yes"],
- [if test "x$LIBNOTIFY_PKG_ERRORS" = "x"; then
- with_libnotify="no"
- else
- with_libnotify="no ($LIBNOTIFY_PKG_ERRORS)"
- fi])
+ [with_libnotify="no (pkg-config doesn't know libnotify)"]
+)
+
+PKG_CHECK_MODULES([LIBRIEMANN_CLIENT], [riemann-client >= 1.8.0],
+ [with_libriemann_client="yes"],
+ [with_libriemann_client="no (pkg-config doesn't know libriemann-client)"])
# Check for enabled/disabled features
#
AC_COLLECTD([debug], [enable], [feature], [debugging])
AC_COLLECTD([daemon], [disable], [feature], [daemon mode])
AC_COLLECTD([getifaddrs],[enable], [feature], [getifaddrs under Linux])
+AC_COLLECTD([werror], [disable], [feature], [building with -Werror])
dependency_warning="no"
dependency_error="no"
plugin_vmem="no"
plugin_vserver="no"
plugin_wireless="no"
+plugin_xencpu="no"
plugin_zfs_arc="no"
+plugin_zone="no"
plugin_zookeeper="no"
# Linux
if test "x$ac_system" = "xLinux"
then
plugin_battery="yes"
+ plugin_cgroups="yes"
plugin_conntrack="yes"
plugin_contextswitch="yes"
- plugin_cgroups="yes"
plugin_cpu="yes"
plugin_cpufreq="yes"
plugin_disk="yes"
plugin_tcpconns="yes"
fi
+if test "x$ac_system" = "xNetBSD"
+then
+ plugin_disk="yes"
+ plugin_entropy="yes"
+ plugin_irq="yes"
+ plugin_processes="yes"
+fi
+
# Mac OS X devices
if test "x$with_libiokit" = "xyes"
then
if test "x$ac_system" = "xAIX"
then
- plugin_tcpconns="yes"
plugin_ipc="yes"
+ plugin_tcpconns="yes"
fi
# FreeBSD
if test "x$ac_system" = "xFreeBSD"
then
+ plugin_disk="yes"
plugin_zfs_arc="yes"
fi
if test "x$with_perfstat" = "xyes"
then
- plugin_cpu="yes"
plugin_contextswitch="yes"
+ plugin_cpu="yes"
plugin_disk="yes"
- plugin_memory="yes"
- plugin_swap="yes"
plugin_interface="yes"
plugin_load="yes"
+ plugin_memory="yes"
+ plugin_swap="yes"
plugin_uptime="yes"
fi
plugin_processes="yes"
plugin_uptime="yes"
plugin_zfs_arc="yes"
+ plugin_zone="yes"
fi
if test "x$with_devinfo$with_kstat" = "xyesyes"
fi
# libi2c-dev
-with_libi2c="no"
if test "x$ac_system" = "xLinux"
then
AC_CHECK_DECL(i2c_smbus_read_i2c_block_data,
[with_libi2c="no (symbol i2c_smbus_read_i2c_block_data not found - have you installed libi2c-dev ?)"],
[[#include <stdlib.h>
#include <linux/i2c-dev.h>]])
+else
+ with_libi2c="no (Linux only)"
fi
if test "x$with_libi2c" = "xyes"
plugin_swap="yes"
fi
+if test "x$have_swapctl" = "xyes" && test "x$c_cv_have_swapctl_three_args" = "xyes"
+then
+ plugin_swap="yes"
+fi
+
if test "x$with_kvm_openfiles$with_kvm_nlist" = "xyesyes"
then
plugin_tcpconns="yes"
plugin_virt="yes"
fi
+if test "x$with_libxenctrl" = "xyes"
+then
+ plugin_xencpu="yes"
+fi
m4_divert_once([HELP_ENABLE], [
collectd plugins:])
m4_divert_once([HELP_ENABLE], [])
-AC_PLUGIN([aggregation], [yes], [Aggregation plugin])
-AC_PLUGIN([amqp], [$with_librabbitmq], [AMQP output plugin])
-AC_PLUGIN([apache], [$with_libcurl], [Apache httpd statistics])
-AC_PLUGIN([apcups], [yes], [Statistics of UPSes by APC])
-AC_PLUGIN([apple_sensors], [$with_libiokit], [Apple's hardware sensors])
-AC_PLUGIN([aquaero], [$with_libaquaero5], [Aquaero's hardware sensors])
-AC_PLUGIN([ascent], [$plugin_ascent], [AscentEmu player statistics])
-AC_PLUGIN([barometer], [$plugin_barometer], [Barometer sensor on I2C])
-AC_PLUGIN([battery], [$plugin_battery], [Battery statistics])
-AC_PLUGIN([bind], [$plugin_bind], [ISC Bind nameserver statistics])
-AC_PLUGIN([ceph], [$plugin_ceph], [Ceph daemon statistics])
-AC_PLUGIN([conntrack], [$plugin_conntrack], [nf_conntrack statistics])
-AC_PLUGIN([contextswitch], [$plugin_contextswitch], [context switch statistics])
-AC_PLUGIN([cpufreq], [$plugin_cpufreq], [CPU frequency statistics])
-AC_PLUGIN([cpu], [$plugin_cpu], [CPU usage statistics])
-AC_PLUGIN([csv], [yes], [CSV output plugin])
-AC_PLUGIN([curl], [$with_libcurl], [CURL generic web statistics])
-AC_PLUGIN([curl_json], [$plugin_curl_json], [CouchDB statistics])
-AC_PLUGIN([curl_xml], [$plugin_curl_xml], [CURL generic xml statistics])
-AC_PLUGIN([cgroups], [$plugin_cgroups], [CGroups CPU usage accounting])
-AC_PLUGIN([dbi], [$with_libdbi], [General database statistics])
-AC_PLUGIN([df], [$plugin_df], [Filesystem usage statistics])
-AC_PLUGIN([disk], [$plugin_disk], [Disk usage statistics])
-AC_PLUGIN([drbd], [$plugin_drbd], [DRBD statistics])
-AC_PLUGIN([dns], [$with_libpcap], [DNS traffic analysis])
-AC_PLUGIN([email], [yes], [EMail statistics])
-AC_PLUGIN([entropy], [$plugin_entropy], [Entropy statistics])
-AC_PLUGIN([ethstat], [$plugin_ethstat], [Stats from NIC driver])
-AC_PLUGIN([exec], [yes], [Execution of external programs])
-AC_PLUGIN([fhcount], [$plugin_fhcount], [File handles statistics])
-AC_PLUGIN([filecount], [yes], [Count files in directories])
-AC_PLUGIN([fscache], [$plugin_fscache], [fscache statistics])
-AC_PLUGIN([gmond], [$with_libganglia], [Ganglia plugin])
-AC_PLUGIN([hddtemp], [yes], [Query hddtempd])
-AC_PLUGIN([interface], [$plugin_interface], [Interface traffic statistics])
-AC_PLUGIN([ipc], [$plugin_ipc], [IPC statistics])
-AC_PLUGIN([ipmi], [$plugin_ipmi], [IPMI sensor statistics])
-AC_PLUGIN([iptables], [$with_libiptc], [IPTables rule counters])
-AC_PLUGIN([ipvs], [$plugin_ipvs], [IPVS connection statistics])
-AC_PLUGIN([irq], [$plugin_irq], [IRQ statistics])
-AC_PLUGIN([java], [$with_java], [Embed the Java Virtual Machine])
-AC_PLUGIN([load], [$plugin_load], [System load])
-AC_PLUGIN([logfile], [yes], [File logging plugin])
-AC_PLUGIN([log_logstash], [$plugin_log_logstash], [Logstash json_event compatible logging])
-AC_PLUGIN([lpar], [$with_perfstat], [AIX logical partitions statistics])
-AC_PLUGIN([lvm], [$with_liblvm2app], [LVM statistics])
-AC_PLUGIN([madwifi], [$have_linux_wireless_h], [Madwifi wireless statistics])
-AC_PLUGIN([match_empty_counter], [yes], [The empty counter match])
-AC_PLUGIN([match_hashed], [yes], [The hashed match])
-AC_PLUGIN([match_regex], [yes], [The regex match])
-AC_PLUGIN([match_timediff], [yes], [The timediff match])
-AC_PLUGIN([match_value], [yes], [The value match])
-AC_PLUGIN([mbmon], [yes], [Query mbmond])
-AC_PLUGIN([md], [$have_linux_raid_md_u_h], [md (Linux software RAID) devices])
-AC_PLUGIN([memcachec], [$with_libmemcached], [memcachec statistics])
-AC_PLUGIN([memcached], [yes], [memcached statistics])
-AC_PLUGIN([memory], [$plugin_memory], [Memory usage])
-AC_PLUGIN([mic], [$with_mic], [Intel Many Integrated Core stats])
-AC_PLUGIN([modbus], [$with_libmodbus], [Modbus plugin])
-AC_PLUGIN([multimeter], [$plugin_multimeter], [Read multimeter values])
-AC_PLUGIN([mysql], [$with_libmysql], [MySQL statistics])
-AC_PLUGIN([netapp], [$with_libnetapp], [NetApp plugin])
-AC_PLUGIN([netlink], [$with_libmnl], [Enhanced Linux network statistics])
-AC_PLUGIN([network], [yes], [Network communication plugin])
-AC_PLUGIN([nfs], [$plugin_nfs], [NFS statistics])
-AC_PLUGIN([nginx], [$with_libcurl], [nginx statistics])
-AC_PLUGIN([notify_desktop], [$with_libnotify], [Desktop notifications])
-AC_PLUGIN([notify_email], [$with_libesmtp], [Email notifier])
-AC_PLUGIN([ntpd], [yes], [NTPd statistics])
-AC_PLUGIN([numa], [$plugin_numa], [NUMA virtual memory statistics])
-AC_PLUGIN([nut], [$with_libupsclient], [Network UPS tools statistics])
-AC_PLUGIN([olsrd], [yes], [olsrd statistics])
-AC_PLUGIN([onewire], [$with_libowcapi], [OneWire sensor statistics])
-AC_PLUGIN([openldap], [$with_libldap], [OpenLDAP statistics])
-AC_PLUGIN([openvpn], [yes], [OpenVPN client statistics])
-AC_PLUGIN([oracle], [$with_oracle], [Oracle plugin])
-AC_PLUGIN([perl], [$plugin_perl], [Embed a Perl interpreter])
-AC_PLUGIN([pf], [$have_net_pfvar_h], [BSD packet filter (PF) statistics])
+AC_PLUGIN([aggregation], [yes], [Aggregation plugin])
+AC_PLUGIN([amqp], [$with_librabbitmq], [AMQP output plugin])
+AC_PLUGIN([apache], [$with_libcurl], [Apache httpd statistics])
+AC_PLUGIN([apcups], [yes], [Statistics of UPSes by APC])
+AC_PLUGIN([apple_sensors], [$with_libiokit], [Apple hardware sensors])
+AC_PLUGIN([aquaero], [$with_libaquaero5], [Aquaero hardware sensors])
+AC_PLUGIN([ascent], [$plugin_ascent], [AscentEmu player statistics])
+AC_PLUGIN([barometer], [$plugin_barometer], [Barometer sensor on I2C])
+AC_PLUGIN([battery], [$plugin_battery], [Battery statistics])
+AC_PLUGIN([bind], [$plugin_bind], [ISC Bind nameserver statistics])
+AC_PLUGIN([ceph], [$plugin_ceph], [Ceph daemon statistics])
+AC_PLUGIN([cgroups], [$plugin_cgroups], [CGroups CPU usage accounting])
+AC_PLUGIN([conntrack], [$plugin_conntrack], [nf_conntrack statistics])
+AC_PLUGIN([contextswitch], [$plugin_contextswitch], [context switch statistics])
+AC_PLUGIN([cpu], [$plugin_cpu], [CPU usage statistics])
+AC_PLUGIN([cpufreq], [$plugin_cpufreq], [CPU frequency statistics])
+AC_PLUGIN([csv], [yes], [CSV output plugin])
+AC_PLUGIN([curl], [$with_libcurl], [CURL generic web statistics])
+AC_PLUGIN([curl_json], [$plugin_curl_json], [CouchDB statistics])
+AC_PLUGIN([curl_xml], [$plugin_curl_xml], [CURL generic xml statistics])
+AC_PLUGIN([dbi], [$with_libdbi], [General database statistics])
+AC_PLUGIN([df], [$plugin_df], [Filesystem usage statistics])
+AC_PLUGIN([disk], [$plugin_disk], [Disk usage statistics])
+AC_PLUGIN([dns], [$with_libpcap], [DNS traffic analysis])
+AC_PLUGIN([drbd], [$plugin_drbd], [DRBD statistics])
+AC_PLUGIN([email], [yes], [EMail statistics])
+AC_PLUGIN([entropy], [$plugin_entropy], [Entropy statistics])
+AC_PLUGIN([ethstat], [$plugin_ethstat], [Stats from NIC driver])
+AC_PLUGIN([exec], [yes], [Execution of external programs])
+AC_PLUGIN([fhcount], [$plugin_fhcount], [File handles statistics])
+AC_PLUGIN([filecount], [yes], [Count files in directories])
+AC_PLUGIN([fscache], [$plugin_fscache], [fscache statistics])
+AC_PLUGIN([gmond], [$with_libganglia], [Ganglia plugin])
+AC_PLUGIN([hddtemp], [yes], [Query hddtempd])
+AC_PLUGIN([interface], [$plugin_interface], [Interface traffic statistics])
+AC_PLUGIN([ipc], [$plugin_ipc], [IPC statistics])
+AC_PLUGIN([ipmi], [$plugin_ipmi], [IPMI sensor statistics])
+AC_PLUGIN([iptables], [$with_libiptc], [IPTables rule counters])
+AC_PLUGIN([ipvs], [$plugin_ipvs], [IPVS connection statistics])
+AC_PLUGIN([irq], [$plugin_irq], [IRQ statistics])
+AC_PLUGIN([java], [$with_java], [Embed the Java Virtual Machine])
+AC_PLUGIN([load], [$plugin_load], [System load])
+AC_PLUGIN([log_logstash], [$plugin_log_logstash], [Logstash json_event compatible logging])
+AC_PLUGIN([logfile], [yes], [File logging plugin])
+AC_PLUGIN([lpar], [$with_perfstat], [AIX logical partitions statistics])
+AC_PLUGIN([lvm], [$with_liblvm2app], [LVM statistics])
+AC_PLUGIN([madwifi], [$have_linux_wireless_h], [Madwifi wireless statistics])
+AC_PLUGIN([match_empty_counter], [yes], [The empty counter match])
+AC_PLUGIN([match_hashed], [yes], [The hashed match])
+AC_PLUGIN([match_regex], [yes], [The regex match])
+AC_PLUGIN([match_timediff], [yes], [The timediff match])
+AC_PLUGIN([match_value], [yes], [The value match])
+AC_PLUGIN([mbmon], [yes], [Query mbmond])
+AC_PLUGIN([md], [$have_linux_raid_md_u_h], [md (Linux software RAID) devices])
+AC_PLUGIN([memcachec], [$with_libmemcached], [memcachec statistics])
+AC_PLUGIN([memcached], [yes], [memcached statistics])
+AC_PLUGIN([memory], [$plugin_memory], [Memory usage])
+AC_PLUGIN([mic], [$with_mic], [Intel Many Integrated Core stats])
+AC_PLUGIN([modbus], [$with_libmodbus], [Modbus plugin])
+AC_PLUGIN([mqtt], [$with_libmosquitto], [MQTT output plugin])
+AC_PLUGIN([multimeter], [$plugin_multimeter], [Read multimeter values])
+AC_PLUGIN([mysql], [$with_libmysql], [MySQL statistics])
+AC_PLUGIN([netapp], [$with_libnetapp], [NetApp plugin])
+AC_PLUGIN([netlink], [$with_libmnl], [Enhanced Linux network statistics])
+AC_PLUGIN([network], [yes], [Network communication plugin])
+AC_PLUGIN([nfs], [$plugin_nfs], [NFS statistics])
+AC_PLUGIN([nginx], [$with_libcurl], [nginx statistics])
+AC_PLUGIN([notify_desktop], [$with_libnotify], [Desktop notifications])
+AC_PLUGIN([notify_email], [$with_libesmtp], [Email notifier])
+AC_PLUGIN([notify_nagios], [yes], [Nagios notification plugin])
+AC_PLUGIN([ntpd], [yes], [NTPd statistics])
+AC_PLUGIN([numa], [$plugin_numa], [NUMA virtual memory statistics])
+AC_PLUGIN([nut], [$with_libupsclient], [Network UPS tools statistics])
+AC_PLUGIN([olsrd], [yes], [olsrd statistics])
+AC_PLUGIN([onewire], [$with_libowcapi], [OneWire sensor statistics])
+AC_PLUGIN([openldap], [$with_libldap], [OpenLDAP statistics])
+AC_PLUGIN([openvpn], [yes], [OpenVPN client statistics])
+AC_PLUGIN([oracle], [$with_oracle], [Oracle plugin])
+AC_PLUGIN([perl], [$plugin_perl], [Embed a Perl interpreter])
+AC_PLUGIN([pf], [$have_net_pfvar_h], [BSD packet filter (PF) statistics])
# FIXME: Check for libevent, too.
-AC_PLUGIN([pinba], [$have_protoc_c], [Pinba statistics])
-AC_PLUGIN([ping], [$with_liboping], [Network latency statistics])
-AC_PLUGIN([postgresql], [$with_libpq], [PostgreSQL database statistics])
-AC_PLUGIN([powerdns], [yes], [PowerDNS statistics])
-AC_PLUGIN([processes], [$plugin_processes], [Process statistics])
-AC_PLUGIN([protocols], [$plugin_protocols], [Protocol (IP, TCP, ...) statistics])
-AC_PLUGIN([python], [$with_python], [Embed a Python interpreter])
-AC_PLUGIN([redis], [$with_libhiredis], [Redis plugin])
-AC_PLUGIN([routeros], [$with_librouteros], [RouterOS plugin])
-AC_PLUGIN([rrdcached], [$librrd_rrdc_update], [RRDTool output plugin])
-AC_PLUGIN([rrdtool], [$with_librrd], [RRDTool output plugin])
-AC_PLUGIN([sensors], [$with_libsensors], [lm_sensors statistics])
-AC_PLUGIN([serial], [$plugin_serial], [serial port traffic])
-AC_PLUGIN([sigrok], [$with_libsigrok], [sigrok acquisition sources])
-AC_PLUGIN([smart], [$plugin_smart], [SMART statistics])
-AC_PLUGIN([snmp], [$with_libnetsnmp], [SNMP querying plugin])
-AC_PLUGIN([statsd], [yes], [StatsD plugin])
-AC_PLUGIN([swap], [$plugin_swap], [Swap usage statistics])
-AC_PLUGIN([syslog], [$have_syslog], [Syslog logging plugin])
-AC_PLUGIN([table], [yes], [Parsing of tabular data])
-AC_PLUGIN([tail], [yes], [Parsing of logfiles])
-AC_PLUGIN([tail_csv], [yes], [Parsing of CSV files])
-AC_PLUGIN([tape], [$plugin_tape], [Tape drive statistics])
-AC_PLUGIN([target_notification], [yes], [The notification target])
-AC_PLUGIN([target_replace], [yes], [The replace target])
-AC_PLUGIN([target_scale],[yes], [The scale target])
-AC_PLUGIN([target_set], [yes], [The set target])
-AC_PLUGIN([target_v5upgrade], [yes], [The v5upgrade target])
-AC_PLUGIN([tcpconns], [$plugin_tcpconns], [TCP connection statistics])
-AC_PLUGIN([teamspeak2], [yes], [TeamSpeak2 server statistics])
-AC_PLUGIN([ted], [$plugin_ted], [Read The Energy Detective values])
-AC_PLUGIN([thermal], [$plugin_thermal], [Linux ACPI thermal zone statistics])
-AC_PLUGIN([threshold], [yes], [Threshold checking plugin])
-AC_PLUGIN([tokyotyrant], [$with_libtokyotyrant], [TokyoTyrant database statistics])
-AC_PLUGIN([turbostat], [$plugin_turbostat], [Advanced statistic on Intel cpu states])
-AC_PLUGIN([unixsock], [yes], [Unixsock communication plugin])
-AC_PLUGIN([uptime], [$plugin_uptime], [Uptime statistics])
-AC_PLUGIN([users], [$plugin_users], [User statistics])
-AC_PLUGIN([uuid], [yes], [UUID as hostname plugin])
-AC_PLUGIN([varnish], [$with_libvarnish], [Varnish cache statistics])
-AC_PLUGIN([virt], [$plugin_virt], [Virtual machine statistics])
-AC_PLUGIN([vmem], [$plugin_vmem], [Virtual memory statistics])
-AC_PLUGIN([vserver], [$plugin_vserver], [Linux VServer statistics])
-AC_PLUGIN([wireless], [$plugin_wireless], [Wireless statistics])
-AC_PLUGIN([write_graphite], [yes], [Graphite / Carbon output plugin])
-AC_PLUGIN([write_http], [$with_libcurl], [HTTP output plugin])
-AC_PLUGIN([write_kafka], [$with_librdkafka], [Kafka output plugin])
-AC_PLUGIN([write_log], [yes], [Log output plugin])
-AC_PLUGIN([write_mongodb], [$with_libmongoc], [MongoDB output plugin])
-AC_PLUGIN([write_redis], [$with_libhiredis], [Redis output plugin])
-AC_PLUGIN([write_riemann], [$have_protoc_c], [Riemann output plugin])
-AC_PLUGIN([write_sensu], [yes], [Sensu output plugin])
-AC_PLUGIN([write_tsdb], [yes], [TSDB output plugin])
-AC_PLUGIN([xmms], [$with_libxmms], [XMMS statistics])
-AC_PLUGIN([zfs_arc], [$plugin_zfs_arc], [ZFS ARC statistics])
-AC_PLUGIN([zookeeper], [yes], [Zookeeper statistics])
+AC_PLUGIN([pinba], [$have_protoc_c], [Pinba statistics])
+AC_PLUGIN([ping], [$with_liboping], [Network latency statistics])
+AC_PLUGIN([postgresql], [$with_libpq], [PostgreSQL database statistics])
+AC_PLUGIN([powerdns], [yes], [PowerDNS statistics])
+AC_PLUGIN([processes], [$plugin_processes], [Process statistics])
+AC_PLUGIN([protocols], [$plugin_protocols], [Protocol (IP, TCP, ...) statistics])
+AC_PLUGIN([python], [$with_python], [Embed a Python interpreter])
+AC_PLUGIN([redis], [$with_libhiredis], [Redis plugin])
+AC_PLUGIN([routeros], [$with_librouteros], [RouterOS plugin])
+AC_PLUGIN([rrdcached], [$librrd_rrdc_update], [RRDTool output plugin])
+AC_PLUGIN([rrdtool], [$with_librrd], [RRDTool output plugin])
+AC_PLUGIN([sensors], [$with_libsensors], [lm_sensors statistics])
+AC_PLUGIN([serial], [$plugin_serial], [serial port traffic])
+AC_PLUGIN([sigrok], [$with_libsigrok], [sigrok acquisition sources])
+AC_PLUGIN([smart], [$plugin_smart], [SMART statistics])
+AC_PLUGIN([snmp], [$with_libnetsnmp], [SNMP querying plugin])
+AC_PLUGIN([statsd], [yes], [StatsD plugin])
+AC_PLUGIN([swap], [$plugin_swap], [Swap usage statistics])
+AC_PLUGIN([syslog], [$have_syslog], [Syslog logging plugin])
+AC_PLUGIN([table], [yes], [Parsing of tabular data])
+AC_PLUGIN([tail], [yes], [Parsing of logfiles])
+AC_PLUGIN([tail_csv], [yes], [Parsing of CSV files])
+AC_PLUGIN([tape], [$plugin_tape], [Tape drive statistics])
+AC_PLUGIN([target_notification], [yes], [The notification target])
+AC_PLUGIN([target_replace], [yes], [The replace target])
+AC_PLUGIN([target_scale], [yes], [The scale target])
+AC_PLUGIN([target_set], [yes], [The set target])
+AC_PLUGIN([target_v5upgrade], [yes], [The v5upgrade target])
+AC_PLUGIN([tcpconns], [$plugin_tcpconns], [TCP connection statistics])
+AC_PLUGIN([teamspeak2], [yes], [TeamSpeak2 server statistics])
+AC_PLUGIN([ted], [$plugin_ted], [Read The Energy Detective values])
+AC_PLUGIN([thermal], [$plugin_thermal], [Linux ACPI thermal zone statistics])
+AC_PLUGIN([threshold], [yes], [Threshold checking plugin])
+AC_PLUGIN([tokyotyrant], [$with_libtokyotyrant], [TokyoTyrant database statistics])
+AC_PLUGIN([turbostat], [$plugin_turbostat], [Advanced statistic on Intel cpu states])
+AC_PLUGIN([unixsock], [yes], [Unixsock communication plugin])
+AC_PLUGIN([uptime], [$plugin_uptime], [Uptime statistics])
+AC_PLUGIN([users], [$plugin_users], [User statistics])
+AC_PLUGIN([uuid], [yes], [UUID as hostname plugin])
+AC_PLUGIN([varnish], [$with_libvarnish], [Varnish cache statistics])
+AC_PLUGIN([virt], [$plugin_virt], [Virtual machine statistics])
+AC_PLUGIN([vmem], [$plugin_vmem], [Virtual memory statistics])
+AC_PLUGIN([vserver], [$plugin_vserver], [Linux VServer statistics])
+AC_PLUGIN([wireless], [$plugin_wireless], [Wireless statistics])
+AC_PLUGIN([write_graphite], [yes], [Graphite / Carbon output plugin])
+AC_PLUGIN([write_http], [$with_libcurl], [HTTP output plugin])
+AC_PLUGIN([write_kafka], [$with_librdkafka], [Kafka output plugin])
+AC_PLUGIN([write_log], [yes], [Log output plugin])
+AC_PLUGIN([write_mongodb], [$with_libmongoc], [MongoDB output plugin])
+AC_PLUGIN([write_redis], [$with_libhiredis], [Redis output plugin])
+AC_PLUGIN([write_riemann], [$with_libriemann_client], [Riemann output plugin])
+AC_PLUGIN([write_sensu], [yes], [Sensu output plugin])
+AC_PLUGIN([write_tsdb], [yes], [TSDB output plugin])
+AC_PLUGIN([xencpu], [$plugin_xencpu], [Xen Host CPU usage])
+AC_PLUGIN([xmms], [$with_libxmms], [XMMS statistics])
+AC_PLUGIN([zfs_arc], [$plugin_zfs_arc], [ZFS ARC statistics])
+AC_PLUGIN([zone], [$plugin_zone], [Solaris container statistics])
+AC_PLUGIN([zookeeper], [yes], [Zookeeper statistics])
dnl Default configuration file
# Load either syslog or logfile
AC_CONFIG_FILES(src/libcollectdclient/collectd/lcc_features.h)
+AM_CFLAGS="-Wall"
+if test "x$enable_werror" != "xno"
+then
+ AM_CFLAGS="$AM_CFLAGS -Werror"
+fi
+AC_SUBST([AM_CFLAGS])
+
AC_CONFIG_FILES([Makefile src/Makefile src/daemon/Makefile src/collectd.conf src/libcollectdclient/Makefile src/libcollectdclient/libcollectdclient.pc src/liboconfig/Makefile bindings/Makefile bindings/java/Makefile])
AC_OUTPUT
cat <<EOF;
Configuration:
+ Build:
+ Platform . . . . . . $ac_system
+ CC . . . . . . . . . $CC
+ CFLAGS . . . . . . . $AM_CFLAGS $CFLAGS
+ CPP . . . . . . . . . $CPP
+ CPPFLAGS . . . . . . $CPPFLAGS
+ LD . . . . . . . . . $LD
+ LDFLAGS . . . . . . . $LDFLAGS
+ YACC . . . . . . . . $YACC
+ YFLAGS . . . . . . . $YFLAGS
+
Libraries:
intel mic . . . . . . $with_mic
libaquaero5 . . . . . $with_libaquaero5
libmnl . . . . . . . $with_libmnl
libmodbus . . . . . . $with_libmodbus
libmongoc . . . . . . $with_libmongoc
+ libmosquitto . . . . $with_libmosquitto
libmysql . . . . . . $with_libmysql
libnetapp . . . . . . $with_libnetapp
libnetsnmp . . . . . $with_libnetsnmp
libpq . . . . . . . . $with_libpq
libpthread . . . . . $with_libpthread
librabbitmq . . . . . $with_librabbitmq
+ libriemann-client . . $with_libriemann_client
librdkafka . . . . . $with_librdkafka
librouteros . . . . . $with_librouteros
librrd . . . . . . . $with_librrd
libupsclient . . . . $with_libupsclient
libvarnish . . . . . $with_libvarnish
libvirt . . . . . . . $with_libvirt
+ libxenctrl . . . . . $with_libxenctrl
libxml2 . . . . . . . $with_libxml2
libxmms . . . . . . . $with_libxmms
libyajl . . . . . . . $with_libyajl
memory . . . . . . . $enable_memory
mic . . . . . . . . . $enable_mic
modbus . . . . . . . $enable_modbus
+ mqtt . . . . . . . . $enable_mqtt
multimeter . . . . . $enable_multimeter
mysql . . . . . . . . $enable_mysql
netapp . . . . . . . $enable_netapp
nginx . . . . . . . . $enable_nginx
notify_desktop . . . $enable_notify_desktop
notify_email . . . . $enable_notify_email
+ notify_nagios . . . . $enable_notify_nagios
ntpd . . . . . . . . $enable_ntpd
numa . . . . . . . . $enable_numa
nut . . . . . . . . . $enable_nut
write_riemann . . . . $enable_write_riemann
write_sensu . . . . . $enable_write_sensu
write_tsdb . . . . . $enable_write_tsdb
+ xencpu . . . . . . . $enable_xencpu
xmms . . . . . . . . $enable_xmms
zfs_arc . . . . . . . $enable_zfs_arc
+ zone . . . . . . . . $enable_zone
zookeeper . . . . . . $enable_zookeeper
EOF
RRD-file that should have been in multiple RRD-files instead. Is is used by
`migrate-3-4.px' to split up the cpu-, nfs-, swap-files and possibly others.
-fedora/
--------
- Init-script and Spec-file that can be used when creating RPM-packages for
-Fedora.
-
GenericJMX.conf
---------------
Example configuration file for the ‘GenericJMX’ Java plugin. Please read the
+++ /dev/null
-[Unit]
-Description=statistics collection daemon
-Documentation=man:collectd(1)
-After=local-fs.target network.target
-Requires=local-fs.target network.target
-
-[Service]
-ExecStart=/usr/sbin/collectd -C /etc/collectd/collectd.conf -f
-Restart=always
-RestartSec=10
-StandardOutput=syslog
-StandardError=syslog
-
-[Install]
-WantedBy=multi-user.target
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}))
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);
+++ /dev/null
-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 <octo@verplant.org>
-Vendor: Florian octo Forster <octo@verplant.org>
-
-%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 <iain@bricbrac.de> 4.2.0
-- New major release
-- Changes to support 4.2.0 (ie. contrib/collection.conf)
-
-* Mon Aug 06 2007 Kjell Randa <Kjell.Randa@broadpark.no> 4.0.6
-- New upstream version
-
-* Wed Jul 25 2007 Kjell Randa <Kjell.Randa@broadpark.no> 4.0.5
-- New major release
-- Changes to support 4.0.5
-
-* Wed Jan 11 2007 Iain Lea <iain@bricbrac.de> 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 <octo@verplant.org> 3.10.0-1
-- New upstream version
-
-* Tue Jun 25 2006 Florian octo Forster <octo@verplant.org> 3.9.4-1
-- New upstream version
-
-* Tue Jun 01 2006 Florian octo Forster <octo@verplant.org> 3.9.3-1
-- New upstream version
-
-* Tue May 09 2006 Florian octo Forster <octo@verplant.org> 3.9.2-1
-- New upstream version
-
-* Tue May 09 2006 Florian octo Forster <octo@verplant.org> 3.8.5-1
-- New upstream version
-
-* Fri Apr 21 2006 Florian octo Forster <octo@verplant.org> 3.9.1-1
-- New upstream version
-
-* Fri Apr 14 2006 Florian octo Forster <octo@verplant.org> 3.9.0-1
-- New upstream version
-- Added the `apache' package.
-
-* Thu Mar 14 2006 Florian octo Forster <octo@verplant.org> 3.8.2-1
-- New upstream version
-
-* Thu Mar 13 2006 Florian octo Forster <octo@verplant.org> 3.8.1-1
-- New upstream version
-
-* Thu Mar 09 2006 Florian octo Forster <octo@verplant.org> 3.8.0-1
-- New upstream version
-
-* Sat Feb 18 2006 Florian octo Forster <octo@verplant.org> 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 <octo@verplant.org> 3.7.1-1
-- New upstream version
-
-* Mon Jan 30 2006 Florian octo Forster <octo@verplant.org> 3.7.0-1
-- New upstream version
-- Removed the extra `hddtemp' package
-
-* Tue Jan 24 2006 Florian octo Forster <octo@verplant.org> 3.6.2-1
-- New upstream version
-
-* Fri Jan 20 2006 Florian octo Forster <octo@verplant.org> 3.6.1-1
-- New upstream version
-
-* Fri Jan 20 2006 Florian octo Forster <octo@verplant.org> 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 <octo@verplant.org> 3.5.0-1
-- New upstream version
-
-* Sat Nov 26 2005 Florian octo Forster <octo@verplant.org> 3.4.0-1
-- New upstream version
-
-* Sat Nov 05 2005 Florian octo Forster <octo@verplant.org> 3.3.0-1
-- New upstream version
-
-* Tue Oct 26 2005 Florian octo Forster <octo@verplant.org> 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 <octo@verplant.org> 3.1.0-1
-- New upstream version
-- Added package `collectd-hddtemp'
-
-* Fri Sep 30 2005 Florian octo Forster <octo@verplant.org> 3.0.0-1
-- New upstream version
-- Split the package into `collectd' and `collectd-sensors'
-
-* Fri Sep 16 2005 Florian octo Forster <octo@verplant.org> 2.1.0-1
-- New upstream version
-
-* Mon Sep 10 2005 Florian octo Forster <octo@verplant.org> 2.0.0-1
-- New upstream version
-
-* Mon Aug 29 2005 Florian octo Forster <octo@verplant.org> 1.8.0-1
-- New upstream version
-
-* Sun Aug 25 2005 Florian octo Forster <octo@verplant.org> 1.7.0-1
-- New upstream version
-
-* Sun Aug 21 2005 Florian octo Forster <octo@verplant.org> 1.6.0-1
-- New upstream version
-
-* Sun Jul 17 2005 Florian octo Forster <octo@verplant.org> 1.5.1-1
-- New upstream version
-
-* Sun Jul 17 2005 Florian octo Forster <octo@verplant.org> 1.5-1
-- New upstream version
-
-* Mon Jul 11 2005 Florian octo Forster <octo@verplant.org> 1.4.2-1
-- New upstream version
-
-* Sat Jul 09 2005 Florian octo Forster <octo@verplant.org> 1.4-1
-- Built on RedHat 7.3
+++ /dev/null
-#!/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
%{?el7:%global _has_atasmart 1}
%{?el7:%global _has_hiredis 1}
%{?el7:%global _has_asm_msr_index 1}
+%{?el7:%global _has_libmosquitto 1}
%{?el7:%global _has_libmodbus 1}
%{?el7:%global _has_xmms 1}
%define with_memory 0%{!?_without_memory:1}
%define with_multimeter 0%{!?_without_multimeter:1}
%define with_modbus 0%{!?_without_modbus:0%{?_has_libmodbus}}
+%define with_mqtt 0%{!?_without_mqtt:0%{?_has_libmosquitto}}
%define with_mysql 0%{!?_without_mysql:1}
%define with_netlink 0%{!?_without_netlink:0%{?_has_iproute}}
%define with_network 0%{!?_without_network: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_write_http 0%{!?_without_write_http:1}
%define with_write_log 0%{!?_without_write_log:1}
%define with_write_redis 0%{!?_without_write_redis:0%{?_has_hiredis}}
-%define with_write_riemann 0%{!?_without_write_riemann:1}
+%define with_write_riemann 0%{!?_without_write_riemann:0%{?_has_recent_riemann_c_client}}
%define with_write_sensu 0%{!?_without_write_sensu:1}
%define with_write_tsdb 0%{!?_without_write_tsdb:1}
%define with_xmms 0%{!?_without_xmms:0%{?_has_xmms}}
%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 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}
Summary: statistics collection and monitoring daemon
Name: collectd
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
The riemann plugin submits values to Riemann, an event stream processor.
%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
%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
%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}
%define _with_ntpd --enable-ntpd
%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
%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
%{?_with_mic} \
%{?_with_modbus} \
%{?_with_multimeter} \
+ %{?_with_mqtt} \
%{?_with_mysql} \
%{?_with_netapp} \
%{?_with_netlink} \
%{?_with_write_kafka} \
%{?_with_write_mongodb} \
%{?_with_write_redis} \
+ %{?_with_xencpu} \
%{?_with_xmms} \
%{?_with_zfs_arc} \
+ %{?_with_zone} \
%{?_with_zookeeper} \
%{?_with_irq} \
%{?_with_load} \
%{?_with_memory} \
%{?_with_network} \
%{?_with_nfs} \
+ %{?_with_notify_nagios} \
%{?_with_ntpd} \
%{?_with_numa} \
%{?_with_olsrd} \
%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
%{_libdir}/%{name}/modbus.so
%endif
+%if %{with_mqtt}
+%files mqtt
+%{_libdir}/%{name}/mqtt.so
+%endif
+
%if %{with_mysql}
%files mysql
%{_libdir}/%{name}/mysql.so
%{_libdir}/%{name}/write_riemann.so
%endif
+%if %{with_xencpu}
+%files xencpu
+%{_libdir}/%{name}/xencpu.so
+%endif
+
%if %{with_xmms}
%files xmms
%{_libdir}/%{name}/xmms.so
%doc contrib/
%changelog
+#* TODO: next feature release changelog
+#- New upstream version
+#- New plugins enabled by default: mqtt, notify_nagios
+#- New plugins disabled by default: zone, xencpu
+#
* Wed May 27 2015 Marc Fournier <marc.fournier@camptocamp.com> 5.5.0-1
- New upstream version
- New plugins enabled by default: ceph, drbd, log_logstash, write_tsdb, smart,
[Unit]
-Description=Collectd
-After=local-fs.target network.target
-Requires=local-fs.target network.target
+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
# socket once the daemon is ready. See systemd.service(5) for more details.
Type=notify
-# Restart the collectd daemon after a 10 seconds delay, in case it crashes.
+# Restart the collectd daemon when it fails.
Restart=on-failure
[Install]
PLUGIN_LDFLAGS = -module -avoid-version -export-symbols-regex '\<module_register\>'
-if COMPILER_IS_GCC
-AM_CFLAGS = -Wall -Werror
-endif
-
AM_CPPFLAGS = -I$(srcdir)/daemon
AM_CPPFLAGS += -DPREFIX='"${prefix}"'
AM_CPPFLAGS += -DCONFIGFILE='"${sysconfdir}/${PACKAGE_NAME}.conf"'
AM_CPPFLAGS += -DPLUGINDIR='"${pkglibdir}"'
AM_CPPFLAGS += -DPKGDATADIR='"${pkgdatadir}"'
-AUTOMAKE_OPTIONS = subdir-objects
+noinst_LTLIBRARIES =
+check_PROGRAMS =
+TESTS =
-noinst_LTLIBRARIES = libmount.la liblookup.la
-
-libmount_la_SOURCES = utils_mount.c utils_mount.h
-libmount_la_LIBADD = daemon/libcommon.la
+noinst_LTLIBRARIES += liblatency.la
+liblatency_la_SOURCES = utils_latency.c utils_latency.h
+check_PROGRAMS += test_utils_latency
+TESTS += test_utils_latency
+test_utils_latency_SOURCES = utils_latency_test.c testing.h
+test_utils_latency_LDADD = liblatency.la daemon/libplugin_mock.la -lm
+noinst_LTLIBRARIES += liblookup.la
liblookup_la_SOURCES = utils_vl_lookup.c utils_vl_lookup.h
-liblookup_la_LIBADD = daemon/libavltree.la daemon/libcommon.la
+liblookup_la_LIBADD = daemon/libavltree.la
+check_PROGRAMS += test_utils_vl_lookup
+TESTS += test_utils_vl_lookup
+test_utils_vl_lookup_SOURCES = utils_vl_lookup_test.c testing.h
+test_utils_vl_lookup_LDADD = liblookup.la daemon/libplugin_mock.la
+if BUILD_WITH_LIBKSTAT
+test_utils_vl_lookup_LDADD += -lkstat
+endif
+
+noinst_LTLIBRARIES += libmount.la
+libmount_la_SOURCES = utils_mount.c utils_mount.h
+check_PROGRAMS += test_utils_mount
+TESTS += test_utils_mount
+test_utils_mount_SOURCES = utils_mount_test.c testing.h
+test_utils_mount_LDADD = libmount.la daemon/libplugin_mock.la
+if BUILD_WITH_LIBKSTAT
+test_utils_mount_LDADD += -lkstat
+endif
sbin_PROGRAMS = collectdmon
bin_PROGRAMS = collectd-nagios collectdctl collectd-tg
collectd_tg_LDADD += -lm
endif
if BUILD_WITH_LIBPTHREAD
-collectd_tg_LDADD += -lpthread
+collectd_tg_LDADD += $(PTHREAD_LIBS)
endif
collectd_tg_LDADD += libcollectdclient/libcollectdclient.la
collectd_tg_DEPENDENCIES = libcollectdclient/libcollectdclient.la
pkglib_LTLIBRARIES += amqp.la
amqp_la_SOURCES = amqp.c \
utils_cmd_putval.c utils_cmd_putval.h \
- utils_parse_option.c utils_parse_option.h \
+ utils_parse_option.c utils_parse_option.h \
utils_format_graphite.c utils_format_graphite.h \
utils_format_json.c utils_format_json.h
amqp_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_LIBRABBITMQ_LDFLAGS)
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
pkglib_LTLIBRARIES += dns.la
dns_la_SOURCES = dns.c utils_dns.c utils_dns.h
dns_la_LDFLAGS = $(PLUGIN_LDFLAGS)
-dns_la_LIBADD = -lpcap -lpthread
+dns_la_LIBADD = $(PTHREAD_LIBS) -lpcap
endif
if BUILD_PLUGIN_DRBD
pkglib_LTLIBRARIES += drbd.la
drbd_la_SOURCES = drbd.c
drbd_la_LDFLAGS = $(PLUGIN_LDFLAGS)
-drbd_la_LIBADD = -lpthread
endif
if BUILD_PLUGIN_EMAIL
pkglib_LTLIBRARIES += email.la
email_la_SOURCES = email.c
email_la_LDFLAGS = $(PLUGIN_LDFLAGS)
-email_la_LIBADD = -lpthread
+email_la_LIBADD = $(PTHREAD_LIBS)
endif
if BUILD_PLUGIN_ENTROPY
utils_cmd_putval.c utils_cmd_putval.h \
utils_parse_option.h utils_parse_option.c
exec_la_LDFLAGS = $(PLUGIN_LDFLAGS)
-exec_la_LIBADD = -lpthread
+exec_la_LIBADD = $(PTHREAD_LIBS)
endif
if BUILD_PLUGIN_ETHSTAT
ipvs_la_SOURCES = ipvs.c
if IP_VS_H_NEEDS_KERNEL_CFLAGS
ipvs_la_CFLAGS = $(AM_CFLAGS) $(KERNEL_CFLAGS)
+else
+ipvs_la_CFLAGS = $(AM_CFLAGS)
endif
ipvs_la_LDFLAGS = $(PLUGIN_LDFLAGS)
endif
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)
+java_la_LIBADD = $(PTHREAD_LIBS) $(JAVA_LIBS)
endif
if BUILD_PLUGIN_LOAD
modbus_la_LIBADD = $(BUILD_WITH_LIBMODBUS_LIBS)
endif
+if BUILD_PLUGIN_MQTT
+pkglib_LTLIBRARIES += mqtt.la
+mqtt_la_SOURCES = 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 = multimeter.c
utils_fbhash.c utils_fbhash.h
network_la_CPPFLAGS = $(AM_CPPFLAGS)
network_la_LDFLAGS = $(PLUGIN_LDFLAGS)
-network_la_LIBADD = -lpthread
+network_la_LIBADD = $(PTHREAD_LIBS)
if BUILD_WITH_LIBSOCKET
network_la_LIBADD += -lsocket
endif
pkglib_LTLIBRARIES += notify_email.la
notify_email_la_SOURCES = notify_email.c
notify_email_la_LDFLAGS = $(PLUGIN_LDFLAGS)
-notify_email_la_LIBADD = -lesmtp -lssl -lcrypto -lpthread
+notify_email_la_LIBADD = $(PTHREAD_LIBS) -lesmtp -lssl -lcrypto
+endif
+
+if BUILD_PLUGIN_NOTIFY_NAGIOS
+pkglib_LTLIBRARIES += notify_nagios.la
+notify_nagios_la_SOURCES = notify_nagios.c
+notify_nagios_la_LDFLAGS = $(PLUGIN_LDFLAGS)
endif
if BUILD_PLUGIN_NTPD
nut_la_SOURCES = nut.c
nut_la_CFLAGS = $(AM_CFLAGS) $(BUILD_WITH_LIBUPSCLIENT_CFLAGS)
nut_la_LDFLAGS = $(PLUGIN_LDFLAGS)
-nut_la_LIBADD = -lpthread $(BUILD_WITH_LIBUPSCLIENT_LIBS)
+nut_la_LIBADD = $(PTHREAD_LIBS) $(BUILD_WITH_LIBUPSCLIENT_LIBS)
endif
if BUILD_PLUGIN_OLSRD
onewire_la_CFLAGS = $(AM_CFLAGS)
onewire_la_CPPFLAGS = $(AM_CPPFLAGS) $(BUILD_WITH_LIBOWCAPI_CPPFLAGS)
onewire_la_LIBADD = $(BUILD_WITH_LIBOWCAPI_LIBS)
-onewire_la_LDFLAGS = $(PLUGIN_LDFLAGS)
+onewire_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_LIBOWCAPI_LDFLAGS)
endif
if BUILD_PLUGIN_OPENLDAP
snmp_la_LIBADD += $(BUILD_WITH_LIBSNMP_LIBS)
endif
if BUILD_WITH_LIBPTHREAD
-snmp_la_LIBADD += -lpthread
+snmp_la_LIBADD += $(PTHREAD_LIBS)
endif
endif
if BUILD_PLUGIN_STATSD
pkglib_LTLIBRARIES += statsd.la
-statsd_la_SOURCES = statsd.c \
- utils_latency.h utils_latency.c
+statsd_la_SOURCES = statsd.c
statsd_la_LDFLAGS = $(PLUGIN_LDFLAGS)
-statsd_la_LIBADD = -lpthread -lm
+statsd_la_LIBADD = $(PTHREAD_LIBS) liblatency.la -lm
endif
if BUILD_PLUGIN_SWAP
utils_cmd_putnotif.h utils_cmd_putnotif.c \
utils_parse_option.h utils_parse_option.c
unixsock_la_LDFLAGS = $(PLUGIN_LDFLAGS)
-unixsock_la_LIBADD = -lpthread
+unixsock_la_LIBADD = $(PTHREAD_LIBS)
endif
if BUILD_PLUGIN_UPTIME
if BUILD_PLUGIN_WRITE_RIEMANN
pkglib_LTLIBRARIES += write_riemann.la
write_riemann_la_SOURCES = write_riemann.c write_riemann_threshold.c write_riemann_threshold.h
-nodist_write_riemann_la_SOURCES = riemann.pb-c.c riemann.pb-c.h
-write_riemann_la_LDFLAGS = $(PLUGIN_LDFLAGS)
-write_riemann_la_LIBADD = -lprotobuf-c
+write_riemann_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(LIBRIEMANN_CLIENT_LIBS)
+write_riemann_la_CFLAGS = $(AM_CFLAGS) $(LIBRIEMANN_CLIENT_CFLAGS)
endif
if BUILD_PLUGIN_WRITE_SENSU
write_tsdb_la_LDFLAGS = $(PLUGIN_LDFLAGS)
endif
+if BUILD_PLUGIN_XENCPU
+pkglib_LTLIBRARIES += xencpu.la
+xencpu_la_SOURCES = xencpu.c
+xencpu_la_LDFLAGS = $(PLUGIN_LDFLAGS)
+xencpu_la_LIBADD = -lxenctrl
+endif
+
if BUILD_PLUGIN_XMMS
pkglib_LTLIBRARIES += xmms.la
xmms_la_SOURCES = xmms.c
BUILT_SOURCES += $(dist_man_MANS)
+if BUILD_PLUGIN_ZONE
+pkglib_LTLIBRARIES += zone.la
+zone_la_SOURCES = zone.c
+zone_la_CFLAGS = $(AM_CFLAGS)
+zone_la_LDFLAGS = $(PLUGIN_LDFLAGS)
+endif
+
dist_man_MANS = collectd.1 \
collectd.conf.5 \
collectd-email.5 \
$(AM_V_PROTOC_C)protoc-c -I$(srcdir) --c_out . $(srcdir)/pinba.proto
endif
-# Protocol buffer for the "write_riemann" plugin.
-EXTRA_DIST += riemann.proto
-if BUILD_PLUGIN_WRITE_RIEMANN
-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
- $(AM_V_PROTOC_C)protoc-c -I$(srcdir) --c_out . $(srcdir)/riemann.proto
-endif
-
install-exec-hook:
$(mkinstalldirs) $(DESTDIR)$(sysconfdir)
if test -e $(DESTDIR)$(sysconfdir)/collectd.conf; \
rm -f $(DESTDIR)$(sysconfdir)/collectd.conf
rm -f $(DESTDIR)$(pkgdatadir)/postgresql_default.conf;
-check_PROGRAMS = test_utils_mount test_utils_vl_lookup
-
-test_utils_mount_SOURCES = utils_mount_test.c testing.h
-test_utils_mount_LDADD = libmount.la daemon/libplugin_mock.la
-if BUILD_WITH_LIBKSTAT
-test_utils_mount_LDADD += -lkstat
-endif
-
-test_utils_vl_lookup_SOURCES = utils_vl_lookup_test.c testing.h
-test_utils_vl_lookup_LDADD = liblookup.la daemon/libplugin_mock.la
-if BUILD_WITH_LIBKSTAT
-test_utils_vl_lookup_LDADD += -lkstat
-endif
-
-TESTS = test_utils_mount test_utils_vl_lookup
-
if BUILD_PLUGIN_CEPH
test_plugin_ceph_SOURCES = 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 = daemon/libcommon.la daemon/libplugin_mock.la $(BUILD_WITH_LIBYAJL_LIBS)
+test_plugin_ceph_LDADD = daemon/libplugin_mock.la $(BUILD_WITH_LIBYAJL_LIBS)
check_PROGRAMS += test_plugin_ceph
TESTS += test_plugin_ceph
endif
DEBUG ("aggregation plugin: Creating new instance.");
- inst = malloc (sizeof (*inst));
+ inst = calloc (1, sizeof (*inst));
if (inst == NULL)
{
- ERROR ("aggregation plugin: malloc() failed.");
+ ERROR ("aggregation plugin: calloc() failed.");
return (NULL);
}
- memset (inst, 0, sizeof (*inst));
pthread_mutex_init (&inst->lock, /* attr = */ NULL);
inst->ds_type = ds->ds[0].type;
#define INIT_STATE(field) do { \
inst->state_ ## field = NULL; \
if (agg->calc_ ## field) { \
- inst->state_ ## field = malloc (sizeof (*inst->state_ ## field)); \
+ inst->state_ ## field = calloc (1, sizeof (*inst->state_ ## field)); \
if (inst->state_ ## field == NULL) { \
agg_instance_destroy (inst); \
free (inst); \
- ERROR ("aggregation plugin: malloc() failed."); \
+ ERROR ("aggregation plugin: calloc() failed."); \
return (NULL); \
} \
- memset (inst->state_ ## field, 0, sizeof (*inst->state_ ## field)); \
} \
} while (0)
int status;
int i;
- agg = malloc (sizeof (*agg));
+ agg = calloc (1, sizeof (*agg));
if (agg == NULL)
{
- ERROR ("aggregation plugin: malloc failed.");
+ 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));
if (tmp == NULL)
{
ERROR ("amqp plugin: realloc failed.");
- camqp_config_free (conf);
+ sfree (subscriber_threads);
return (ENOMEM);
}
subscriber_threads = tmp;
char errbuf[1024];
ERROR ("amqp plugin: pthread_create failed: %s",
sstrerror (status, errbuf, sizeof (errbuf)));
- camqp_config_free (conf);
return (status);
}
int status;
int i;
- conf = malloc (sizeof (*conf));
+ conf = calloc (1, sizeof (*conf));
if (conf == NULL)
{
- ERROR ("amqp plugin: malloc failed.");
+ ERROR ("amqp plugin: calloc failed.");
return (ENOMEM);
}
/* Initialize "conf" {{{ */
- memset (conf, 0, sizeof (*conf));
conf->publish = publish;
conf->name = NULL;
conf->format = CAMQP_FORMAT_COMMAND;
return (0);
}
- if (len <= 0)
+ if (len == 0)
return (len);
if ((st->apache_buffer_fill + len) >= st->apache_buffer_size)
{
char *temp;
- temp = (char *) realloc (st->apache_buffer,
+ temp = realloc (st->apache_buffer,
st->apache_buffer_fill + len + 1);
if (temp == NULL)
{
return (0);
}
- if (len <= 0)
+ if (len == 0)
return (len);
/* look for the Server header */
int i;
int status;
- st = malloc (sizeof (*st));
+ st = calloc (1, sizeof (*st));
if (st == NULL)
{
- ERROR ("apache plugin: malloc failed.");
+ ERROR ("apache plugin: calloc failed.");
return (-1);
}
- memset (st, 0, sizeof (*st));
st->timeout = -1;
status = plugin_register_complex_read (/* group = */ NULL,
/* name = */ callback_name,
/* callback = */ apache_read_host,
- /* interval = */ NULL,
+ /* interval = */ 0,
/* user_data = */ &ud);
}
if (st->timeout >= 0)
curl_easy_setopt (st->curl, CURLOPT_TIMEOUT_MS, (long) st->timeout);
else
- curl_easy_setopt (st->curl, CURLOPT_TIMEOUT_MS,
- CDTIME_T_TO_MS(plugin_get_interval()));
+ curl_easy_setopt (st->curl, CURLOPT_TIMEOUT_MS, (long) CDTIME_T_TO_MS(plugin_get_interval()));
#endif
return (0);
/*
* collectd - src/apcups.c
- * Copyright (C) 2006-2012 Florian octo Forster
+ * Copyright (C) 2006-2015 Florian octo Forster
* Copyright (C) 2006 Anthony Gialluca <tonyabg at charter.net>
* Copyright (C) 2000-2004 Kern Sibbald
* Copyright (C) 1996-1999 Andre M. Hedrick <andre at suse.com>
#if HAVE_SYS_TYPES_H
# include <sys/types.h>
#endif
-#if HAVE_SYS_SOCKET_H
-# include <sys/socket.h>
-#endif
#if HAVE_NETDB_H
# include <netdb.h>
#endif
# include <netinet/in.h>
#endif
-#define NISPORT 3551
-#define MAXSTRING 256
-#define MODULE_NAME "apcups"
+#ifndef APCUPS_SERVER_TIMEOUT
+# define APCUPS_SERVER_TIMEOUT 15.0
+#endif
+
+#ifndef APCUPS_DEFAULT_NODE
+# define APCUPS_DEFAULT_NODE "localhost"
+#endif
-#define APCUPS_DEFAULT_HOST "localhost"
+#ifndef APCUPS_DEFAULT_SERVICE
+# define APCUPS_DEFAULT_SERVICE "3551"
+#endif
/*
* Private data types
* Private variables
*/
/* Default values for contacting daemon */
-static char *conf_host = NULL;
-static int conf_port = NISPORT;
+static char *conf_node = NULL;
+static char *conf_service = NULL;
/* Defaults to false for backwards compatibility. */
static _Bool conf_report_seconds = 0;
+static _Bool conf_persistent_conn = 1;
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 net_shutdown (int *fd)
{
* Returns -1 on error
* Returns socket file descriptor otherwise
*/
-static int net_open (char *host, int port)
+static int net_open (char const *node, char const *service)
{
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 */
+ memset (&ai_hints, 0, sizeof (ai_hints));
+ /* TODO: Change this to `AF_UNSPEC' if apcupsd can handle IPv6 */
+ ai_hints.ai_family = AF_INET;
ai_hints.ai_socktype = SOCK_STREAM;
- status = getaddrinfo (host, port_str, &ai_hints, &ai_return);
+ status = getaddrinfo (node, service, &ai_hints, &ai_return);
if (status != 0)
{
char errbuf[1024];
DEBUG ("apcups plugin: Done opening a socket %i", sd);
return (sd);
-} /* int net_open (char *host, char *service, int port) */
+} /* int net_open */
/*
* Receive a message from the other end. Each message consists of
* Returns zero on success
* Returns non-zero on error
*/
-static int net_send (int *sockfd, char *buff, int len)
+static int net_send (int *sockfd, const char *buff, int len)
{
uint16_t packet_size;
}
/* Get and print status from apcupsd NIS server */
-static int apc_query_server (char *host, int port,
+static int apc_query_server (char const *node, char const *service,
struct apc_detail_s *apcups_detail)
{
int n;
{
if (global_sockfd < 0)
{
- global_sockfd = net_open (host, port);
+ global_sockfd = net_open (node, service);
if (global_sockfd < 0)
{
ERROR ("apcups plugin: Connecting to the "
"first %i iterations. Will close the socket "
"in future iterations.",
count_retries, count_iterations);
- close_socket = 1;
+ conf_persistent_conn = 0;
}
while ((n = net_recv (&global_sockfd, recvline, sizeof (recvline) - 1)) > 0)
{
- assert ((unsigned int)n < sizeof (recvline));
- recvline[n] = '\0';
+ assert ((size_t)n < sizeof (recvline));
+ recvline[n] = 0;
#if APCMAIN
printf ("net_recv = `%s';\n", recvline);
#endif /* if APCMAIN */
}
status = errno; /* save errno, net_shutdown() may re-set it. */
- if (close_socket)
+ if (!conf_persistent_conn)
net_shutdown (&global_sockfd);
if (n < 0)
return (0);
}
-static int apcups_config (const char *key, const char *value)
+static int apcups_config (oconfig_item_t *ci)
{
- 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 i;
+ _Bool persistent_conn_set = 0;
+
+ for (i = 0; i < ci->children_num; i++)
{
- int port_tmp = atoi (value);
- if (port_tmp < 1 || port_tmp > 65535)
- {
- WARNING ("apcups plugin: Invalid port: %i", port_tmp);
- return (1);
+ 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 = 1;
}
- conf_port = port_tmp;
- }
- else if (strcasecmp (key, "ReportSeconds") == 0)
- {
- if (IS_TRUE (value))
- conf_report_seconds = 1;
else
- conf_report_seconds = 0;
+ ERROR ("apcups plugin: Unknown config option \"%s\".", child->key);
}
- else
- {
- return (-1);
+
+ 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 = 0;
+ }
}
+
return (0);
-}
+} /* int apcups_config */
-static void apc_submit_generic (char *type, char *type_inst, double value)
+static void apc_submit_generic (const char *type, const char *type_inst, double value)
{
value_t values[1];
value_list_t vl = VALUE_LIST_INIT;
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);
+ status = apc_query_server ((conf_node == NULL) ? APCUPS_DEFAULT_NODE : conf_node,
+ (conf_service == NULL) ? APCUPS_DEFAULT_SERVICE : conf_service,
+ &apcups_detail);
/*
* if we did not connect then do not bother submitting
*/
if (status != 0)
{
- DEBUG ("apcups plugin: apc_query_server (%s, %i) = %i",
- conf_host == NULL
- ? APCUPS_DEFAULT_HOST
- : conf_host,
- conf_port, status);
+ DEBUG ("apcups plugin: apc_query_server (%s, %s) = %i",
+ (conf_node == NULL) ? APCUPS_DEFAULT_NODE : conf_node,
+ (conf_service == NULL) ? APCUPS_DEFAULT_SERVICE : conf_service,
+ status);
return (-1);
}
void module_register (void)
{
- plugin_register_config ("apcups", apcups_config, config_keys,
- config_keys_num);
+ plugin_register_complex_config ("apcups", apcups_config);
plugin_register_read ("apcups", apcups_read);
plugin_register_shutdown ("apcups", apcups_shutdown);
} /* void module_register */
static int as_init (void)
{
kern_return_t status;
-
+
if (io_master_port != MACH_PORT_NULL)
{
mach_port_deallocate (mach_task_self (),
#include <curl/curl.h>
#include <libxml/parser.h>
-static char *races_list[] = /* {{{ */
+static const char *races_list[] = /* {{{ */
{
NULL,
"Human", /* 1 */
}; /* }}} */
#define RACES_LIST_LENGTH STATIC_ARRAY_SIZE (races_list)
-static char *classes_list[] = /* {{{ */
+static const char *classes_list[] = /* {{{ */
{
NULL,
"Warrior", /* 1 */
}; /* }}} */
#define CLASSES_LIST_LENGTH STATIC_ARRAY_SIZE (classes_list)
-static char *genders_list[] = /* {{{ */
+static const char *genders_list[] = /* {{{ */
{
"Male",
"Female"
{
size_t len = size * nmemb;
- if (len <= 0)
+ if (len == 0)
return (len);
if ((ascent_buffer_fill + len) >= ascent_buffer_size)
{
char *temp;
- temp = (char *) realloc (ascent_buffer,
+ temp = realloc (ascent_buffer,
ascent_buffer_fill + len + 1);
if (temp == NULL)
{
if (timeout != NULL)
curl_easy_setopt (curl, CURLOPT_TIMEOUT_MS, atol(timeout));
else
- curl_easy_setopt (curl, CURLOPT_TIMEOUT_MS,
- CDTIME_T_TO_MS(plugin_get_interval()));
+ curl_easy_setopt (curl, CURLOPT_TIMEOUT_MS, (long) CDTIME_T_TO_MS(plugin_get_interval()));
#endif
return (0);
*/
static int temp_list_add(temperature_list_t * list, const char * sensor)
{
- temperature_list_t * new_temp;
+ temperature_list_t *new_temp;
- new_temp = (temperature_list_t *) malloc(sizeof(*new_temp));
+ new_temp = malloc(sizeof (*new_temp));
if(new_temp == NULL)
return -1;
gauge_t * values = NULL; /**< rate values */
size_t values_num = 0; /**< number of rate values */
- int i;
+ size_t i;
gauge_t values_history[REF_TEMP_AVG_NUM];
for(i=0; i<values_num; ++i)
{
- DEBUG ("barometer: get_reference_temperature - rate %d: %lf **",
- i,
- values[i]);
+ DEBUG ("barometer: get_reference_temperature - rate %zu: %lf **",
+ i, values[i]);
if(!isnan(values[i]))
{
avg_sum += values[i];
for(i=0; i<REF_TEMP_AVG_NUM*list->num_values; ++i)
{
- DEBUG ("barometer: get_reference_temperature - history %d: %lf",
- i,
- values_history[i]);
+ DEBUG ("barometer: get_reference_temperature - history %zu: %lf",
+ i, values_history[i]);
if(!isnan(values_history[i]))
{
avg_sum += values_history[i];
for(i=0; i<values_num; ++i)
{
- DEBUG ("barometer: get_reference_temperature - rate last %d: %lf **",
- i,
- values[i]);
+ DEBUG ("barometer: get_reference_temperature - rate last %zu: %lf **",
+ i, values[i]);
if(!isnan(values[i]))
{
avg_sum += values[i];
} /* }}} void submit_capacity */
#if HAVE_IOKIT_PS_IOPOWERSOURCES_H || HAVE_IOKIT_IOKITLIB_H
-static 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;
*ret_voltage = temp_double / 1000.0;
}
}
-
+
CFRelease (bat_root_dict);
}
* 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 = NAN; /* Charged capacity */
+ gauge_t capacity_charged; /* Charged capacity */
gauge_t capacity_full = NAN; /* Total capacity */
gauge_t capacity_design = NAN; /* Full design capacity */
# 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.
{
size_t len = size * nmemb;
- if (len <= 0)
+ if (len == 0)
return (len);
if ((bind_buffer_fill + len) >= bind_buffer_size)
{
char *temp;
- temp = realloc(bind_buffer, bind_buffer_fill + len + 1);
+ temp = realloc (bind_buffer, bind_buffer_fill + len + 1);
if (temp == NULL)
{
ERROR ("bind plugin: realloc failed.");
return (0);
} /* }}} int bind_xml_read_timestamp */
-/*
+/*
* bind_parse_generic_name_value
*
* Reads statistics in the form:
return (0);
} /* }}} int bind_parse_generic_name_value */
-/*
+/*
* bind_parse_generic_value_list
*
* Reads statistics in the form:
{ /* Parse the <counters> tag {{{ */
char plugin_instance[DATA_MAX_NAME_LEN];
translation_table_ptr_t table_ptr =
- {
+ {
nsstats_translation_table,
nsstats_translation_table_length,
plugin_instance
{
char plugin_instance[DATA_MAX_NAME_LEN];
translation_table_ptr_t table_ptr =
- {
+ {
resstats_translation_table,
resstats_translation_table_length,
plugin_instance
return (-1);
}
- tmp = (char **) realloc (view->zones,
+ tmp = realloc (view->zones,
sizeof (char *) * (view->zones_num + 1));
if (tmp == NULL)
{
return (-1);
}
- tmp = (cb_view_t *) realloc (views, sizeof (*views) * (views_num + 1));
+ tmp = realloc (views, sizeof (*views) * (views_num + 1));
if (tmp == NULL)
{
ERROR ("bind plugin: realloc failed.");
curl_easy_setopt (curl, CURLOPT_MAXREDIRS, 50L);
#ifdef HAVE_CURLOPT_TIMEOUT_MS
curl_easy_setopt (curl, CURLOPT_TIMEOUT_MS, (timeout >= 0) ?
- (long) timeout : CDTIME_T_TO_MS(plugin_get_interval()));
+ (long) timeout : (long) CDTIME_T_TO_MS(plugin_get_interval()));
#endif
#include <stdlib.h>
#include <string.h>
#include <strings.h>
-#include <sys/socket.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/un.h>
};
/** Valid types for ceph defined in types.db */
-const char * ceph_dset_types [CEPH_DSET_TYPES_NUM] =
+static const char * const ceph_dset_types [CEPH_DSET_TYPES_NUM] =
{"ceph_latency", "ceph_bytes", "ceph_rate"};
/******* ceph_daemon *******/
return -ENOMEM;
}
- d->ds_names[d->ds_num] = malloc(sizeof(char) * DATA_MAX_NAME_LEN);
+ d->ds_names[d->ds_num] = malloc(DATA_MAX_NAME_LEN);
if(!d->ds_names[d->ds_num])
{
return -ENOMEM;
}
g_daemons = tmp;
- nd = malloc(sizeof(*nd));
+ nd = malloc(sizeof (*nd));
if(!nd)
{
return ENOMEM;
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(1 * sizeof(struct last_data));
+ 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;
if(!d->last_poll_data)
{
- d->last_poll_data = malloc(1 * sizeof(struct last_data *));
+ d->last_poll_data = malloc(sizeof (*d->last_poll_data));
if(!d->last_poll_data)
{
return -ENOMEM;
struct case_s
{
- char *key;
- char *value;
+ const char *key;
+ const char *value;
};
typedef struct case_s case_t;
yajl_handle hndl;
#if HAVE_YAJL_V2
hndl = yajl_alloc (&callbacks, NULL, &ctx);
- CHECK_ZERO (traverse_json ((unsigned char *) json, (uint32_t) strlen (json), hndl));
+ 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 ((unsigned char *) json, (uint32_t) strlen (json), hndl));
+ CHECK_ZERO (traverse_json ((const unsigned char *) json, (uint32_t) strlen (json), hndl));
CHECK_ZERO (yajl_parse_complete (hndl));
#endif
DEF_TEST(parse_keys)
{
struct {
- char *str;
- char *want;
+ 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"},
{
char got[DATA_MAX_NAME_LEN];
- memset (got, 0, sizeof (got));
-
CHECK_ZERO (parse_keys (got, sizeof (got), cases[i].str));
-
- CHECK_ZERO (strcmp (got, cases[i].want));
+ EXPECT_EQ_STR (cases[i].want, got);
}
return 0;
Works like the option of the same name directly beneath the I<MBean> block, but
sets the type instance instead. I<(optional)>
+=item B<PluginName> I<name>
+
+When set, overrides the default setting for the I<plugin> field
+(C<GenericJMX>).
+
=item B<Table> B<true>|B<false>
Set this to true if the returned attribute is a I<composite type>. If set to
static _Bool nan_is_error_g = 0;
static char **match_ds_g = NULL;
-static int match_ds_num_g = 0;
+static size_t match_ds_num_g = 0;
/* `strdup' is an XSI extension. I don't want to pull in all of XSI just for
* that, so here's an own implementation.. It's easy enough. The GCC attributes
new_values = (gauge_t *)calloc (match_ds_num_g, sizeof (*new_values));
if (new_values == NULL)
{
- fprintf (stderr, "malloc failed: %s\n", strerror (errno));
+ fprintf (stderr, "calloc failed: %s\n", strerror (errno));
return (RET_UNKNOWN);
}
new_names = (char **)calloc (match_ds_num_g, sizeof (*new_names));
if (new_names == NULL)
{
- fprintf (stderr, "malloc failed: %s\n", strerror (errno));
+ fprintf (stderr, "calloc failed: %s\n", strerror (errno));
free (new_values);
return (RET_UNKNOWN);
}
- for (i = 0; i < (size_t) match_ds_num_g; i++)
+ for (i = 0; i < match_ds_num_g; i++)
{
size_t j;
return (((ret - range->invert) == 0) ? 0 : 1);
} /* int match_range */
+__attribute__((noreturn))
static void usage (const char *name)
{
fprintf (stderr, "Usage: %s <-s socket> <-n value_spec> <-H hostname> [options]\n"
case 'd':
{
char **tmp;
- tmp = (char **) realloc (match_ds_g,
+ tmp = realloc (match_ds_g,
(match_ds_num_g + 1)
* sizeof (char *));
if (tmp == NULL)
#include <time.h>
#include <signal.h>
#include <errno.h>
+#include <math.h>
+#include <sys/time.h>
#include "utils_heap.h"
loop = 0;
} /* }}} void signal_handler */
+#if HAVE_CLOCK_GETTIME
+static double dtime (void) /* {{{ */
+{
+ struct timespec ts = { 0 };
+
+ if (clock_gettime (CLOCK_MONOTONIC, &ts) != 0)
+ perror ("clock_gettime");
+
+ return ((double) ts.tv_sec) + (((double) ts.tv_nsec) / 1e9);
+} /* }}} double dtime */
+#else
+/* Work around for Mac OS X which doesn't have clock_gettime(2). *sigh* */
+static double dtime (void) /* {{{ */
+{
+ struct timeval tv = { 0 };
+
+ if (gettimeofday (&tv, /* timezone = */ NULL) != 0)
+ perror ("gettimeofday");
+
+ return ((double) tv.tv_sec) + (((double) tv.tv_usec) / 1e6);
+} /* }}} double dtime */
+#endif
+
static int compare_time (const void *v0, const void *v1) /* {{{ */
{
const lcc_value_list_t *vl0 = v0;
lcc_value_list_t *vl;
int host_num;
- vl = malloc (sizeof (*vl));
+ vl = calloc (1, sizeof (*vl));
if (vl == NULL)
{
- fprintf (stderr, "malloc failed.\n");
+ fprintf (stderr, "calloc failed.\n");
return (NULL);
}
- memset (vl, 0, sizeof (*vl));
vl->values = calloc (/* nmemb = */ 1, sizeof (*vl->values));
if (vl->values == NULL)
host_num = get_boundet_random (0, conf_num_hosts);
vl->interval = conf_interval;
- vl->time = 1.0 + time (NULL)
+ vl->time = 1.0 + dtime ()
+ (host_num % (1 + (int) vl->interval));
if (get_boundet_random (0, 2) == 0)
if (vl->values_types[0] == LCC_TYPE_GAUGE)
vl->values[0].gauge = 100.0 * ((gauge_t) random ()) / (((gauge_t) RAND_MAX) + 1.0);
else
- vl->values[0].derive += get_boundet_random (0, 100);
+ vl->values[0].derive += (derive_t) get_boundet_random (0, 100);
status = lcc_network_values_send (net, vl);
if (status != 0)
int main (int argc, char **argv) /* {{{ */
{
int i;
- time_t last_time;
+ double last_time;
int values_sent = 0;
read_options (argc, argv);
else
{
lcc_server_t *srv;
-
+
srv = lcc_server_create (net, conf_destination, conf_service);
if (srv == NULL)
{
printf ("%i values have been sent.\n", values_sent);
/* Check if we need to sleep */
- time_t now = time (NULL);
+ double now = dtime ();
while (now < vl->time)
{
/* 1 / 100 second */
struct timespec ts = { 0, 10000000 };
+
+ ts.tv_sec = (time_t) now;
+ ts.tv_nsec = (long) ((now - ((double) ts.tv_sec)) * 1e9);
+
nanosleep (&ts, /* remaining = */ NULL);
- now = time (NULL);
+ now = dtime ();
if (!loop)
break;
@BUILD_PLUGIN_MEMORY_TRUE@@BUILD_PLUGIN_MEMORY_TRUE@LoadPlugin memory
#@BUILD_PLUGIN_MIC_TRUE@LoadPlugin mic
#@BUILD_PLUGIN_MODBUS_TRUE@LoadPlugin modbus
+#@BUILD_PLUGIN_MQTT_TRUE@LoadPlugin mqtt
#@BUILD_PLUGIN_MULTIMETER_TRUE@LoadPlugin multimeter
#@BUILD_PLUGIN_MYSQL_TRUE@LoadPlugin mysql
#@BUILD_PLUGIN_NETAPP_TRUE@LoadPlugin netapp
#@BUILD_PLUGIN_NGINX_TRUE@LoadPlugin nginx
#@BUILD_PLUGIN_NOTIFY_DESKTOP_TRUE@LoadPlugin notify_desktop
#@BUILD_PLUGIN_NOTIFY_EMAIL_TRUE@LoadPlugin notify_email
+#@BUILD_PLUGIN_NOTIFY_NAGIOS_TRUE@LoadPlugin notify_nagios
#@BUILD_PLUGIN_NTPD_TRUE@LoadPlugin ntpd
#@BUILD_PLUGIN_NUMA_TRUE@LoadPlugin numa
#@BUILD_PLUGIN_NUT_TRUE@LoadPlugin nut
#@BUILD_PLUGIN_WRITE_RIEMANN_TRUE@LoadPlugin write_riemann
#@BUILD_PLUGIN_WRITE_SENSU_TRUE@LoadPlugin write_sensu
#@BUILD_PLUGIN_WRITE_TSDB_TRUE@LoadPlugin write_tsdb
+#@BUILD_PLUGIN_XENCPU_TRUE@LoadPlugin xencpu
#@BUILD_PLUGIN_XMMS_TRUE@LoadPlugin xmms
#@BUILD_PLUGIN_ZFS_ARC_TRUE@LoadPlugin zfs_arc
+#@BUILD_PLUGIN_ZONE_TRUE@LoadPlugin zone
#@BUILD_PLUGIN_ZOOKEEPER_TRUE@LoadPlugin zookeeper
##############################################################################
# Host "localhost"
# Port "3551"
# ReportSeconds true
+# PersistentConnection true
#</Plugin>
#<Plugin aquaero>
#<Plugin interface>
# Interface "eth0"
# IgnoreSelected false
+# UniqueName false
#</Plugin>
#<Plugin ipmi>
# </Host>
#</Plugin>
+#<Plugin mqtt>
+# <Publish "name">
+# Host "localhost"
+# Port 1883
+# ClientId "localhost"
+# User "user"
+# Password "secret"
+# QoS 0
+# Prefix "collectd"
+# StoreRates true
+# Retain false
+# CACert "/etc/ssl/ca.crt"
+# CertificateFile "/etc/ssl/client.crt"
+# CertificateKeyFile "/etc/ssl/client.pem"
+# TLSProtocol "tlsv1.2"
+# CipherSuite "ciphers"
+# </Publish>
+# <Subscribe "name">
+# Host "localhost"
+# Port 1883
+# ClientId "localhost"
+# User "user"
+# Password "secret"
+# QoS 2
+# Topic "collectd/#"
+# CleanSession true
+# </Subscribe>
+#</Plugin>
+
#<Plugin mysql>
# <Database db_name>
# Host "database.serv.er"
# Recipient "email2@domain2.com"
#</Plugin>
+#<Plugin notify_nagios>
+# CommandFile "/usr/local/nagios/var/rw/nagios.cmd"
+#</Plugin>
+
#<Plugin ntpd>
# Host "localhost"
# Port 123
# DeleteTimers false
# DeleteGauges false
# DeleteSets false
+# CounterSum false
# TimerPercentile 90.0
# TimerPercentile 95.0
# TimerPercentile 99.0
## None of the following option should be set manually
## This plugin automatically detect most optimal options
## Only set values here if:
-## - The module ask you to
+## - The module asks you to
## - You want to disable the collection of some data
-## - Your (intel) CPU is not supported (yet) by the module
-## - The module generate a lot of errors 'MSR offset 0x... read failed'
+## - Your (Intel) CPU is not supported (yet) by the module
+## - The module generates a lot of errors 'MSR offset 0x... read failed'
## In the last two cases, please open a bug request
#
# TCCActivationTemp "100"
# Host "localhost"
# Port "2003"
# Protocol "tcp"
+# ReconnectInterval 0
# LogSendErrors true
# Prefix "collectd"
# Postfix "collectd"
# ClientKey "/etc/ssl/client.pem"
# ClientCert "/etc/ssl/client.crt"
# ClientKeyPass "secret"
+# Header "X-Custom-Header: custom_value"
# SSLVersion "TLSv1"
# Format "Command"
# StoreRates false
# Host "localhost"
# Port "6379"
# Timeout 1000
+# Prefix "collectd/"
# </Node>
#</Plugin>
The syntax of this config file is similar to the config file of the famous
I<Apache> webserver. Each line contains either an option (a key and a list of
one or more values) or a section-start or -end. Empty lines and everything
-after a non-quoted hash-symbol (C<#>) is ignored. I<Keys> are unquoted
+after a non-quoted hash-symbol (C<#>) are ignored. I<Keys> are unquoted
strings, consisting only of alphanumeric characters and the underscore (C<_>)
character. Keys are handled case insensitive by I<collectd> itself and all
plugins included with it. I<Values> can either be an I<unquoted string>, a
=item B<BaseDir> I<Directory>
-Sets the base directory. This is the directory beneath all RRD-files are
+Sets the base directory. This is the directory beneath which all RRD-files are
created. Possibly more subdirectories are created. This is also the working
directory for the daemon.
Only the first B<LoadPlugin> statement or block for a given plugin name has any
effect. This is useful when you want to split up the configuration into smaller
files and want each file to be "self contained", i.e. it contains a B<Plugin>
-block I<and> then appropriate B<LoadPlugin> statement. The downside is that if
+block I<and> the appropriate B<LoadPlugin> statement. The downside is that if
you have multiple conflicting B<LoadPlugin> blocks, e.g. when they specify
different intervals, only one of them (the first one encountered) will take
effect and all others will be silently ignored.
=item B<Interval> I<Seconds>
Sets a plugin-specific interval for collecting metrics. This overrides the
-global B<Interval> setting. If a plugin provides own support for specifying an
-interval, that setting will take precedence.
+global B<Interval> setting. If a plugin provides its own support for specifying
+an interval, that setting will take precedence.
+
+=item B<FlushInterval> I<Seconds>
+
+Specifies the interval, in seconds, to call the flush callback if it's
+defined in this plugin. By default, this is disabled.
+
+=item B<FlushTimeout> I<Seconds>
+
+Specifies the value of the timeout argument of the flush callback.
=back
=back
-If more than one files are included by a single B<Include> option, the files
+If more than one file is included by a single B<Include> option, the files
will be included in lexicographical order (as defined by the C<strcmp>
function). Thus, you can e.E<nbsp>g. use numbered prefixes to specify the
order in which the files are loaded.
=item B<MaxReadInterval> I<Seconds>
-Read plugin doubles interval between queries after each failed attempt
+A read plugin doubles the interval between queries after each failed attempt
to get data.
This options limits the maximum value of the interval. The default value is
The I<AMQP plugin> can be used to communicate with other instances of
I<collectd> or third party applications using an AMQP message broker. Values
are sent to or received from the broker, which handles routing, queueing and
-possibly filtering or messages.
+possibly filtering out messages.
+
+B<Synopsis:>
<Plugin "amqp">
# Send values to an AMQP broker
TCP-Port to connect to. Defaults to B<3551>.
-=item B<ReportSeconds> B<true|false>
+=item B<ReportSeconds> B<true>|B<false>
If set to B<true>, the time reported in the C<timeleft> metric will be
converted to seconds. This is the recommended setting. If set to B<false>, the
default for backwards compatibility, the time will be reported in minutes.
+=item B<PersistentConnection> B<true>|B<false>
+
+The plugin is designed to keep the connection to I<apcupsd> open between reads.
+If plugin poll interval is greater than 15 seconds (hardcoded socket close
+timeout in I<apcupsd> NIS), then this option is B<false> by default.
+
+You can instruct the plugin to close the connection after each read by setting
+this option to B<false> or force keeping the connection by setting it to B<true>.
+
+If I<apcupsd> appears to close the connection due to inactivity quite quickly,
+the plugin will try to detect this problem and switch to an open-read-close mode.
+
=back
=head2 Plugin C<aquaero>
</Query>
<Database "product_information">
Driver "mysql"
+ Interval 120
DriverOption "host" "localhost"
DriverOption "username" "collectd"
DriverOption "password" "aZo6daiw"
=over 4
+=item B<Interval> I<Interval>
+
+Sets the interval (in seconds) in which the values will be collected from this
+database. By default the global B<Interval> setting will be used.
+
=item B<Driver> I<Driver>
Specifies the driver to use to connect to the database. In many cases those
at least one digit.
+=item B<UniqueName> I<true>|I<false>
+
+Interface name is not unique on Solaris (KSTAT), interface name is unique
+only within a module/instance. Following tuple is considered unique:
+ (ks_module, ks_instance, ks_name)
+If this option is set to true, interface name contains above three fields
+separated by an underscore. For more info on KSTAT, visit
+L<http://docs.oracle.com/cd/E23824_01/html/821-1468/kstat-3kstat.html#REFMAN3Ekstat-3kstat>
+
+This option is only available on Solaris.
+
=back
=head2 Plugin C<ipmi>
=back
+=head2 Plugin C<mqtt>
+
+The I<MQTT plugin> can send metrics to MQTT (B<Publish> blocks) and receive
+values from MQTT (B<Subscribe> blocks).
+
+B<Synopsis:>
+
+ <Plugin mqtt>
+ <Publish "name">
+ Host "mqtt.example.com"
+ Prefix "collectd"
+ </Publish>
+ <Subscribe "name">
+ Host "mqtt.example.com"
+ Topic "collectd/#"
+ </Subscribe>
+ </Plugin>
+
+The plugin's configuration is in B<Publish> and/or B<Subscribe> blocks,
+configuring the sending and receiving direction respectively. The plugin will
+register a write callback named C<mqtt/I<name>> where I<name> is the string
+argument given to the B<Publish> block. Both types of blocks share many but not
+all of the following options. If an option is valid in only one of the blocks,
+it will be mentioned explicitly.
+
+B<Options:>
+
+=over 4
+
+=item B<Host> I<Hostname>
+
+Hostname of the MQTT broker to connect to.
+
+=item B<Port> I<Service>
+
+Port number or service name of the MQTT broker to connect to.
+
+=item B<User> I<UserName>
+
+Username used when authenticating to the MQTT broker.
+
+=item B<Password> I<Password>
+
+Password used when authenticating to the MQTT broker.
+
+=item B<ClientId> I<ClientId>
+
+MQTT client ID to use. Defaults to the hostname used by I<collectd>.
+
+=item B<QoS> [B<0>-B<2>]
+
+Sets the I<Quality of Service>, with the values C<0>, C<1> and C<2> meaning:
+
+=over 4
+
+=item B<0>
+
+At most once
+
+=item B<1>
+
+At least once
+
+=item B<2>
+
+Exactly once
+
+=back
+
+In B<Publish> blocks, this option determines the QoS flag set on outgoing
+messages and defaults to B<0>. In B<Subscribe> blocks, determines the maximum
+QoS setting the client is going to accept and defaults to B<2>. If the QoS flag
+on a message is larger than the maximum accepted QoS of a subscriber, the
+message's QoS will be downgraded.
+
+=item B<Prefix> I<Prefix> (Publish only)
+
+This plugin will use one topic per I<value list> which will looks like a path.
+I<Prefix> is used as the first path element and defaults to B<collectd>.
+
+An example topic name would be:
+
+ collectd/cpu-0/cpu-user
+
+=item B<Retain> B<false>|B<true> (Publish only)
+
+Controls whether the MQTT broker will retain (keep a copy of) the last message
+sent to each topic and deliver it to new subscribers. Defaults to B<false>.
+
+=item B<StoreRates> B<true>|B<false> (Publish only)
+
+Controls whether C<DERIVE> and C<COUNTER> metrics are converted to a I<rate>
+before sending. Defaults to B<true>.
+
+=item B<CleanSession> B<true>|B<false> (Subscribe only)
+
+Controls whether the MQTT "cleans" the session up after the subscriber
+disconnects or if it maintains the subscriber's subscriptions and all messages
+that arrive while the subscriber is disconnected. Defaults to B<true>.
+
+=item B<Topic> I<TopicName> (Subscribe only)
+
+Configures the topic(s) to subscribe to. You can use the single level C<+> and
+multi level C<#> wildcards. Defaults to B<collectd/#>, i.e. all topics beneath
+the B<collectd> branch.
+
+=item B<CACert> I<file>
+
+Path to the PEM-encoded CA certificate file. Setting this option enables TLS
+communication with the MQTT broker, and as such, B<Port> should be the TLS-enabled
+port of the MQTT broker.
+A valid TLS configuration requires B<CACert>, B<CertificateFile> and B<CertificateKeyFile>.
+
+=item B<CertificateFile> I<file>
+
+Path to the PEM-encoded certificate file to use as client certificate when
+connecting to the MQTT broker.
+A valid TLS configuration requires B<CACert>, B<CertificateFile> and B<CertificateKeyFile>.
+
+=item B<CertificateKeyFile> I<file>
+
+Path to the unencrypted PEM-encoded key file corresponding to B<CertificateFile>.
+A valid TLS configuration requires B<CACert>, B<CertificateFile> and B<CertificateKeyFile>.
+
+=item B<TLSProtocol> I<protocol>
+
+If configured, this specifies the string protocol version (e.g. C<tlsv1>,
+C<tlsv1.2>) to use for the TLS connection to the broker. If not set a default
+version is used which depends on the version of OpenSSL the Mosquitto library
+was linked against.
+
+=item B<CipherSuite> I<ciphersuite>
+
+A string describing the ciphers available for use. See L<ciphers(1)> and the
+C<openssl ciphers> utility for more information. If unset, the default ciphers
+will be used.
+
+
+=back
+
=head2 Plugin C<mysql>
The C<mysql plugin> requires B<mysqlclient> to be installed. It connects to
=back
+=head2 Plugin C<notify_nagios>
+
+The I<notify_nagios> plugin writes notifications to Nagios' I<command file> as
+a I<passive service check result>.
+
+Available configuration options:
+
+=over 4
+
+=item B<CommandFile> I<Path>
+
+Sets the I<command file> to write to. Defaults to F</usr/local/nagios/var/rw/nagios.cmd>.
+
+=back
+
=head2 Plugin C<ntpd>
The C<ntpd> plugin collects per-peer ntpd data such as time offset and time
Sets the URL to use to connect to the I<OpenLDAP> server. This option is
I<mandatory>.
+=item B<BindDN> I<BindDN>
+
+Name in the form of an LDAP distinguished name intended to be used for
+authentication. Defaults to empty string to establish an anonymous authorization.
+
+=item B<Password> I<Password>
+
+Password for simple bind authentication. If this option is not set,
+unauthenticated bind operation is used.
+
=item B<StartTLS> B<true|false>
Defines whether TLS must be used when connecting to the I<OpenLDAP> server.
=item B<Timeout> I<Seconds>
-Sets the timeout value for ldap operations. Defaults to B<-1> which results in
-an infinite timeout.
+Sets the timeout value for ldap operations, in seconds. By default, the
+configured B<Interval> is used to set the timeout. Use B<-1> to disable
+(infinite timeout).
=item B<Version> I<Version>
Sets the Time-To-Live of generated ICMP packets.
+=item B<Size> I<size>
+
+Sets the size of the data payload in ICMP packet to specified I<size> (it
+will be filled with regular ASCII pattern). If not set, default 56 byte
+long string is used so that the packet size of an ICMPv4 packet is exactly
+64 bytes, similar to the behaviour of normal ping(1) command.
+
=item B<SourceAddress> I<host>
Sets the source address to use. I<host> may either be a numerical network
allows to "group" several processes together. I<name> must not contain
slashes.
+=item B<CollectContextSwitch> I<Boolean>
+
+Collect context switch of the process.
+
=back
=head2 Plugin C<protocols>
I<true> the effect of B<Sensor> is inverted: All selected sensors are ignored
and all other sensors are collected.
+=item B<UseLabels> I<true>|I<false>
+
+Configures how sensor readings are reported. When set to I<true>, sensor
+readings are reported using their descriptive label (e.g. "VCore"). When set to
+I<false> (the default) the sensor name is used ("in0").
+
=back
=head2 Plugin C<sigrok>
are unchanged. If set to B<True>, the such metrics are not dispatched and
removed from the internal cache.
+=item B<CounterSum> B<false>|B<true>
+
+When enabled, creates a C<count> metric which reports the change since the last
+read. This option primarily exists for compatibility with the I<statsd>
+implementation by Etsy.
+
=item B<TimerPercentile> I<Percent>
Calculate and dispatch the configured percentile, i.e. compute the latency, so
=item B<DigitalTemperatureSensor> I<true>|I<false>
Boolean enabling the collection of the temperature of each core.
-This option should only be used if the automated detectionfails or
+This option should only be used if the automated detectionfails or
if you want to disable this feature.
=item B<DigitalTemperatureSensor> I<true>|I<false>
Boolean enabling the collection of the temperature of each package.
-This option should only be used if the automated detectionfails or
+This option should only be used if the automated detectionfails or
if you want to disable this feature.
=item B<TCCActivationTemp> I<Temperature>
B<address> means use the interface's mac address. This is useful since the
interface path might change between reboots of a guest or across migrations.
-=item B<PluginInstanceFormat> B<name|uuid>
+=item B<PluginInstanceFormat> B<name|uuid|none>
When the virt plugin logs data, it sets the plugin_instance of the collected
-data according to this setting. The default is to use the guest name as provided
-by the hypervisor, which is equal to setting B<name>.
+data according to this setting. The default is to not set the plugin_instance.
+B<name> means use the guest's name as provided by the hypervisor.
B<uuid> means use the guest's UUID.
-You can also specify combinations of these fields. For example B<name uuid>
-means to concatenate the guest name and UUID (with a literal colon character
-between, thus I<"foo:1234-1234-1234-1234">).
+You can also specify combinations of the B<name> and B<uuid> fields.
+For example B<name uuid> means to concatenate the guest name and UUID
+(with a literal colon character between, thus I<"foo:1234-1234-1234-1234">).
=back
Protocol to use when connecting to I<Graphite>. Defaults to C<tcp>.
+=item B<ReconnectInterval> I<Seconds>
+
+When set to non-zero, forces the connection to the Graphite backend to be
+closed and re-opend periodically. This behavior is desirable in environments
+where the connection to the Graphite backend is done through load balancers,
+for example. When set to zero, the default, the connetion is kept open for as
+long as possible.
+
=item B<LogSendErrors> B<false>|B<true>
If set to B<true> (the default), logs errors when sending data to I<Graphite>.
Password required to load the private key in B<ClientKey>.
+=item B<Header> I<Header>
+
+A HTTP header to add to the request. Multiple headers are added if this option is specified more than once. Example:
+
+ Header "X-Custom-Header: custom_value"
+
=item B<SSLVersion> B<SSLv2>|B<SSLv3>|B<TLSv1>|B<TLSv1_0>|B<TLSv1_1>|B<TLSv1_2>
Define which SSL protocol version must be used. By default C<libcurl> will
all the data in the current send buffer will probably be lost. Defaults to 0,
which means the connection never times out.
+=item B<LogHttpError> B<false>|B<true>
+
+Enables printing of HTTP error code to log. Turned off by default.
+
The C<write_http> plugin regularly submits the collected values to the HTTP
server. How frequently this happens depends on how much data you are collecting
and the size of B<BufferSize>. The optimal value to set B<Timeout> to is
Host "localhost"
Port "6379"
Timeout 1000
+ Prefix "collectd/"
+ Database 1
+ MaxSetSize -1
+ StoreRates true
</Node>
</Plugin>
Values are submitted to I<Sorted Sets>, using the metric name as the key, and
the timestamp as the score. Retrieving a date range can then be done using the
C<ZRANGEBYSCORE> I<Redis> command. Additionally, all the identifiers of these
-I<Sorted Sets> are kept in a I<Set> called C<collectd/values> and can be
-retrieved using the C<SMEMBERS> I<Redis> command. See
+I<Sorted Sets> are kept in a I<Set> called C<collectd/values> (or
+C<${prefix}/values> if the B<Prefix> option was specified) and can be retrieved
+using the C<SMEMBERS> I<Redis> command. You can specify the database to use
+with the B<Database> parameter (default is C<0>). See
L<http://redis.io/commands#sorted_set> and L<http://redis.io/commands#set> for
details.
The B<Timeout> option sets the socket connection timeout, in milliseconds.
+=item B<Prefix> I<Prefix>
+
+Prefix used when constructing the name of the I<Sorted Sets> and the I<Set>
+containing all metrics. Defaults to C<collectd/>, so metrics will have names
+like C<collectd/cpu-0/cpu-user>. When setting this to something different, it
+is recommended but not required to include a trailing slash in I<Prefix>.
+
+=item B<Database> I<Index>
+
+This index selects the redis database to use for writing operations. Defaults
+to C<0>.
+
+=item B<MaxSetSize> I<Items>
+
+The B<MaxSetSize> option limits the number of items that the I<Sorted Sets> can
+hold. Negative values for I<Items> sets no limit, which is the default behavior.
+
+=item B<StoreRates> B<true>|B<false>
+
+If set to B<true> (the default), convert counter values to rates. If set to
+B<false> counter values are stored as is, i.e. as an increasing integer number.
+
=back
=head2 Plugin C<write_riemann>
Service name or port number to connect to. Defaults to C<5555>.
-=item B<Protocol> B<UDP>|B<TCP>
+=item B<Protocol> B<UDP>|B<TCP>|B<TLS>
Specify the protocol to use when communicating with I<Riemann>. Defaults to
B<TCP>.
+=item B<TLSCertFile> I<Path>
+
+When using the B<TLS> protocol, path to a PEM certificate to present
+to remote host.
+
+=item B<TLSCAFile> I<Path>
+
+When using the B<TLS> protocol, path to a PEM CA certificate to
+use to validate the remote hosts's identity.
+
+=item B<TLSKeyFile> I<Path>
+
+When using the B<TLS> protocol, path to a PEM private key associated
+with the certificate defined by B<TLSCertFile>.
+
=item B<Batch> B<true>|B<false>
If set to B<true> and B<Protocol> is set to B<TCP>,
Maximum payload size for a riemann packet. Defaults to 8192
+=item B<BatchFlushTimeout> I<seconds>
+
+Maximum amount of seconds to wait in between to batch flushes.
+No timeout by default.
+
=item B<StoreRates> B<true>|B<false>
If set to B<true> (the default), convert counter values to rates. If set to
=back
+=head2 Plugin C<xencpu>
+
+This plugin collects metrics of hardware CPU load for machine running Xen
+hypervisor. Load is calculated from 'idle time' value, provided by Xen.
+Result is reported using the C<percent> type, for each CPU (core).
+
+This plugin doesn't have any options (yet).
+
=head2 Plugin C<zookeeper>
The I<zookeeper plugin> will collect statistics from a I<Zookeeper> server
=item B<TypeInstance> I<String>
+=item B<MetaDataSet> I<String> I<String>
+
Set the appropriate field to the given string. The strings for plugin instance
and type instance may be empty, the strings for host and plugin may not be
empty. It's currently not possible to set the type of a value this way.
extern char *optarg;
extern int optind;
+__attribute__((noreturn))
static void exit_usage (const char *name, int status) {
fprintf ((status == 0) ? stdout : stderr,
"Usage: %s [options] <command> [cmd options]\n\n"
return count;
} /* count_chars */
-static int array_grow (void **array, int *array_len, size_t elem_size)
+static int array_grow (void **array, size_t *array_len, size_t elem_size)
{
void *tmp;
int timeout = -1;
lcc_identifier_t *identifiers = NULL;
- int identifiers_num = 0;
+ size_t identifiers_num = 0;
char **plugins = NULL;
- int plugins_num = 0;
+ size_t plugins_num = 0;
int status;
int i;
values_len = 0;
value = tmp;
- while (value != 0) {
+ while (value != NULL) {
char *dot, *endptr;
tmp = strchr (value, (int)':');
values_types[values_len] = LCC_TYPE_GAUGE;
}
else { /* integer */
- values[values_len].counter = strtol (value, &endptr, 0);
+ values[values_len].counter = (counter_t) strtoull (value, &endptr, 0);
values_types[values_len] = LCC_TYPE_COUNTER;
}
++values_len;
int status;
while (42) {
- int n;
+ int opt;
- n = getopt (argc, argv, "s:h");
+ opt = getopt (argc, argv, "s:h");
- if (n == -1)
+ if (opt == -1)
break;
- switch (n) {
+ switch (opt) {
case 's':
snprintf (address, sizeof (address), "unix:%s", optarg);
address[sizeof (address) - 1] = '\0';
static int loop = 0;
static int restart = 0;
-static char *pidfile = NULL;
-static pid_t collectd_pid = 0;
+static const char *pidfile = NULL;
+static pid_t collectd_pid = 0;
-static void exit_usage (char *name)
+__attribute__((noreturn))
+static void exit_usage (const char *name)
{
printf ("Usage: %s <options> [-- <collectd options>]\n"
static int daemonize (void)
{
struct rlimit rl;
+ int dev_null;
pid_t pid = 0;
int i = 0;
for (i = 0; i < (int)rl.rlim_max; ++i)
close (i);
- errno = 0;
- if (open ("/dev/null", O_RDWR) != 0) {
- syslog (LOG_ERR, "Error: couldn't connect STDIN to /dev/null: %s",
- strerror (errno));
+ dev_null = open ("/dev/null", O_RDWR);
+ if (dev_null == -1) {
+ syslog (LOG_ERR, "Error: couldn't open /dev/null: %s", strerror (errno));
return -1;
}
- errno = 0;
- if (dup (0) != 1) {
- syslog (LOG_ERR, "Error: couldn't connect STDOUT to /dev/null: %s",
- strerror (errno));
+ if (dup2 (dev_null, STDIN_FILENO) == -1) {
+ close (dev_null);
+ syslog (LOG_ERR, "Error: couldn't connect STDIN to /dev/null: %s", strerror (errno));
return -1;
}
- errno = 0;
- if (dup (0) != 2) {
- syslog (LOG_ERR, "Error: couldn't connect STDERR to /dev/null: %s",
- strerror (errno));
+ if (dup2 (dev_null, STDOUT_FILENO) == -1) {
+ close (dev_null);
+ syslog (LOG_ERR, "Error: couldn't connect STDOUT to /dev/null: %s", strerror (errno));
return -1;
}
+
+ if (dup2 (dev_null, STDERR_FILENO) == -1) {
+ close (dev_null);
+ syslog (LOG_ERR, "Error: couldn't connect STDERR to /dev/null: %s", strerror (errno));
+ return -1;
+ }
+
+ if ((dev_null != STDIN_FILENO) && (dev_null != STDOUT_FILENO) && (dev_null != STDERR_FILENO))
+ close (dev_null);
+
return 0;
} /* daemonize */
/* Adds a derive value to the internal state. This should be used by each read
* function for each state. At the end of the iteration, the read function
* should call cpu_commit(). */
-static int cpu_stage (size_t cpu_num, size_t state, derive_t value, cdtime_t now) /* {{{ */
+static int cpu_stage (size_t cpu_num, size_t state, derive_t d, cdtime_t now) /* {{{ */
{
int status;
cpu_state_t *s;
- value_t v;
+ gauge_t rate = NAN;
+ value_t val = {.derive = d};
if (state >= COLLECTD_CPU_STATE_ACTIVE)
return (EINVAL);
s = get_cpu_state (cpu_num, state);
- v.gauge = NAN;
- status = value_to_rate (&v, value, &s->conv, DS_TYPE_DERIVE, now);
+ status = value_to_rate (&rate, val, DS_TYPE_DERIVE, now, &s->conv);
if (status != 0)
return (status);
- s->rate = v.gauge;
+ s->rate = rate;
s->has_value = 1;
return (0);
} /* }}} int cpu_stage */
if (pnumcpu != numcpu || perfcpu == NULL)
{
- if (perfcpu != NULL)
- free(perfcpu);
+ free(perfcpu);
perfcpu = malloc(numcpu * sizeof(perfstat_cpu_t));
}
pnumcpu = numcpu;
* DEALINGS IN THE SOFTWARE.
*
* Authors:
- * Sven Trenkel <collectd at semidefinite.de>
+ * Sven Trenkel <collectd at semidefinite.de>
**/
/* Some python versions don't include this by default. */
} while (0)
static inline void CPY_STRCAT(PyObject **a, PyObject *b) {
PyObject *ret;
-
+
if (!a || !*a)
return;
-
+
ret = PyUnicode_Concat(*a, b);
Py_DECREF(*a);
*a = ret;
return PyBytes_FromString(buf);
#else
return PyString_FromString(buf);
-#endif
+#endif
}
void cpy_log_exception(const char *context);
{
int offset;
int status;
- int i;
+ size_t i;
gauge_t *rates = NULL;
assert (0 == strcmp (ds->type, vl->type));
static int csv_create_file (const char *filename, const data_set_t *ds)
{
FILE *csv;
- int i;
+ size_t i;
if (check_create_dir (filename))
return (-1);
size_t len;
len = size * nmemb;
- if (len <= 0)
+ if (len == 0)
return (len);
wp = user_data;
size_t temp_size;
temp_size = wp->buffer_fill + len + 1;
- temp = (char *) realloc (wp->buffer, temp_size);
+ temp = realloc (wp->buffer, temp_size);
if (temp == NULL)
{
ERROR ("curl plugin: realloc failed.");
WARNING ("curl plugin: Ignoring arguments for the `Match' block.");
}
- match = (web_match_t *) malloc (sizeof (*match));
+ match = calloc (1, sizeof (*match));
if (match == NULL)
{
- ERROR ("curl plugin: malloc failed.");
+ ERROR ("curl plugin: calloc failed.");
return (-1);
}
- memset (match, 0, sizeof (*match));
status = 0;
for (i = 0; i < ci->children_num; i++)
if (wp->pass != NULL)
credentials_size += strlen (wp->pass);
- wp->credentials = (char *) malloc (credentials_size);
+ wp->credentials = malloc (credentials_size);
if (wp->credentials == NULL)
{
ERROR ("curl plugin: malloc failed.");
if (wp->timeout >= 0)
curl_easy_setopt (wp->curl, CURLOPT_TIMEOUT_MS, (long) wp->timeout);
else
- curl_easy_setopt (wp->curl, CURLOPT_TIMEOUT_MS,
- CDTIME_T_TO_MS(plugin_get_interval()));
+ curl_easy_setopt (wp->curl, CURLOPT_TIMEOUT_MS, (long) CDTIME_T_TO_MS(plugin_get_interval()));
#endif
return (0);
return (-1);
}
- page = (web_page_t *) malloc (sizeof (*page));
+ page = calloc (1, sizeof (*page));
if (page == NULL)
{
- ERROR ("curl plugin: malloc failed.");
+ ERROR ("curl plugin: calloc failed.");
return (-1);
}
- memset (page, 0, sizeof (*page));
page->url = NULL;
page->user = NULL;
page->pass = NULL;
web_page_t *prev;
prev = pages_g;
- while ((prev != NULL) && (prev->next != NULL))
+ while (prev->next != NULL)
prev = prev->next;
prev->next = page;
}
#include "utils_avltree.h"
#include "utils_complain.h"
-#include <sys/socket.h>
#include <sys/types.h>
#include <sys/un.h>
len = size * nmemb;
- if (len <= 0)
+ if (len == 0)
return (len);
db = user_data;
return (-1);
}
- key = (cj_key_t *) malloc (sizeof (*key));
+ key = calloc (1, sizeof (*key));
if (key == NULL)
{
- ERROR ("curl_json plugin: malloc failed.");
+ ERROR ("curl_json plugin: calloc failed.");
return (-1);
}
- memset (key, 0, sizeof (*key));
key->magic = CJ_KEY_MAGIC;
if (strcasecmp ("Key", ci->key) == 0)
if (db->pass != NULL)
credentials_size += strlen (db->pass);
- db->credentials = (char *) malloc (credentials_size);
+ db->credentials = malloc (credentials_size);
if (db->credentials == NULL)
{
ERROR ("curl_json plugin: malloc failed.");
if (db->timeout >= 0)
curl_easy_setopt (db->curl, CURLOPT_TIMEOUT_MS, (long) db->timeout);
else if (db->interval > 0)
- curl_easy_setopt (db->curl, CURLOPT_TIMEOUT_MS,
- CDTIME_T_TO_MS(db->timeout));
+ curl_easy_setopt (db->curl, CURLOPT_TIMEOUT_MS, (long) CDTIME_T_TO_MS(db->timeout));
else
- curl_easy_setopt (db->curl, CURLOPT_TIMEOUT_MS,
- CDTIME_T_TO_MS(plugin_get_interval()));
+ curl_easy_setopt (db->curl, CURLOPT_TIMEOUT_MS, (long) CDTIME_T_TO_MS(plugin_get_interval()));
#endif
return (0);
return (-1);
}
- db = (cj_t *) malloc (sizeof (*db));
+ db = calloc (1, sizeof (*db));
if (db == NULL)
{
- ERROR ("curl_json plugin: malloc failed.");
+ ERROR ("curl_json plugin: calloc failed.");
return (-1);
}
- memset (db, 0, sizeof (*db));
db->timeout = -1;
{
user_data_t ud;
char *cb_name;
- struct timespec interval = { 0, 0 };
-
- CDTIME_T_TO_TIMESPEC (db->interval, &interval);
if (db->instance == NULL)
db->instance = strdup("default");
db->instance, db->url ? db->url : db->sock);
plugin_register_complex_read (/* group = */ NULL, cb_name, cj_read,
- /* interval = */ (db->interval > 0) ? &interval : NULL,
+ /* interval = */ db->interval,
&ud);
sfree (cb_name);
}
static int cj_sock_perform (cj_t *db) /* {{{ */
{
char errbuf[1024];
- struct sockaddr_un sa_unix = {};
+ struct sockaddr_un sa_unix = { 0 };
sa_unix.sun_family = AF_UNIX;
sstrncpy (sa_unix.sun_path, db->sock, sizeof (sa_unix.sun_path));
char *path;
char *type;
cx_values_t *values;
- int values_len;
+ size_t values_len;
char *instance_prefix;
char *instance;
int is_table;
return (0);
}
- if (len <= 0)
+ if (len == 0)
return (len);
if ((db->buffer_fill + len) >= db->buffer_size)
{
char *temp;
- temp = (char *) realloc (db->buffer,
+ temp = realloc (db->buffer,
db->buffer_fill + len + 1);
if (temp == NULL)
{
}
llist_destroy (list);
- list = NULL;
} /* }}} void cx_list_free */
static void cx_free (void *arg) /* {{{ */
if (ds->ds_num != xpath->values_len)
{
- WARNING ("curl_xml plugin: DataSet `%s' requires %i values, but config talks about %i",
+ WARNING ("curl_xml plugin: DataSet `%s' requires %zu values, but config talks about %zu",
xpath->type, ds->ds_num, xpath->values_len);
return (-1);
}
return (0);
} /* }}} cx_check_type */
-static xmlXPathObjectPtr cx_evaluate_xpath (xmlXPathContextPtr xpath_ctx, /* {{{ */
+static xmlXPathObjectPtr cx_evaluate_xpath (xmlXPathContextPtr xpath_ctx, /* {{{ */
xmlChar *expr)
{
xmlXPathObjectPtr xpath_obj;
{
WARNING ("curl_xml plugin: "
"relative xpath expression \"%s\" is expected to return "
- "only text/attribute node which is not the case. Skipping...",
+ "only text/attribute node which is not the case. Skipping...",
xpath->values[index].path);
xmlXPathFreeObject (values_node_obj);
return (-1);
vl->values[index].absolute = (absolute_t) strtoull (node_value,
/* endptr = */ NULL, /* base = */ 0);
break;
- case DS_TYPE_GAUGE:
+ case DS_TYPE_GAUGE:
vl->values[index].gauge = (gauge_t) strtod (node_value,
/* endptr = */ NULL);
}
{
value_t values[xpath->values_len];
int status;
- int i;
+ size_t i;
assert (xpath->values_len > 0);
assert (xpath->values_len == vl->values_len);
static int cx_handle_base_xpath (char const *plugin_instance, /* {{{ */
char const *host,
- xmlXPathContextPtr xpath_ctx, const data_set_t *ds,
+ xmlXPathContextPtr xpath_ctx, const data_set_t *ds,
char *base_xpath, cx_xpath_t *xpath)
{
int total_nodes;
value_list_t vl = VALUE_LIST_INIT;
- base_node_obj = cx_evaluate_xpath (xpath_ctx, BAD_CAST base_xpath);
+ base_node_obj = cx_evaluate_xpath (xpath_ctx, BAD_CAST base_xpath);
if (base_node_obj == NULL)
return -1; /* error is logged already */
}
/* If base_xpath returned multiple results, then */
- /* Instance in the xpath block is required */
+ /* Instance in the xpath block is required */
if (total_nodes > 1 && xpath->instance == NULL)
{
ERROR ("curl_xml plugin: "
sstrncpy (vl.plugin, "curl_xml", sizeof (vl.plugin));
sstrncpy (vl.host, (host != NULL) ? host : hostname_g, sizeof (vl.host));
if (plugin_instance != NULL)
- sstrncpy (vl.plugin_instance, plugin_instance, sizeof (vl.plugin_instance));
+ sstrncpy (vl.plugin_instance, plugin_instance, sizeof (vl.plugin_instance));
for (i = 0; i < total_nodes; i++)
{
} /* for (i = 0; i < total_nodes; i++) */
/* free up the allocated memory */
- xmlXPathFreeObject (base_node_obj);
+ xmlXPathFreeObject (base_node_obj);
- return (0);
+ return (0);
} /* }}} cx_handle_base_xpath */
-static int cx_handle_parsed_xml(xmlDocPtr doc, /* {{{ */
+static int cx_handle_parsed_xml(xmlDocPtr doc, /* {{{ */
xmlXPathContextPtr xpath_ctx, cx_t *db)
{
llentry_t *le;
const data_set_t *ds;
cx_xpath_t *xpath;
int status=-1;
-
+
le = llist_head (db->list);
while (le != NULL)
char *url;
url = db->url;
- db->buffer_fill = 0;
+ db->buffer_fill = 0;
status = curl_easy_perform (curl);
if (status != CURLE_OK)
{
sfree (xpath->values);
xpath->values_len = 0;
- xpath->values = (cx_values_t *) malloc (sizeof (cx_values_t) * ci->values_num);
+ xpath->values = malloc (sizeof (cx_values_t) * ci->values_num);
if (xpath->values == NULL)
return (-1);
- xpath->values_len = ci->values_num;
+ xpath->values_len = (size_t) ci->values_num;
/* populate cx_values_t structure */
for (i = 0; i < ci->values_num; i++)
int status;
int i;
- xpath = malloc (sizeof (*xpath));
+ xpath = calloc (1, sizeof (*xpath));
if (xpath == NULL)
{
- ERROR ("curl_xml plugin: malloc failed.");
+ ERROR ("curl_xml plugin: calloc failed.");
return (-1);
}
- memset (xpath, 0, sizeof (*xpath));
status = cf_util_get_string (ci, &xpath->path);
if (status != 0)
if (db->pass != NULL)
credentials_size += strlen (db->pass);
- db->credentials = (char *) malloc (credentials_size);
+ db->credentials = malloc (credentials_size);
if (db->credentials == NULL)
{
ERROR ("curl_xml plugin: malloc failed.");
if (db->timeout >= 0)
curl_easy_setopt (db->curl, CURLOPT_TIMEOUT_MS, (long) db->timeout);
else
- curl_easy_setopt (db->curl, CURLOPT_TIMEOUT_MS,
- CDTIME_T_TO_MS(plugin_get_interval()));
+ curl_easy_setopt (db->curl, CURLOPT_TIMEOUT_MS, (long) CDTIME_T_TO_MS(plugin_get_interval()));
#endif
return (0);
return (-1);
}
- db = (cx_t *) malloc (sizeof (*db));
+ db = calloc (1, sizeof (*db));
if (db == NULL)
{
- ERROR ("curl_xml plugin: malloc failed.");
+ ERROR ("curl_xml plugin: calloc failed.");
return (-1);
}
- memset (db, 0, sizeof (*db));
db->timeout = -1;
cb_name = ssnprintf_alloc ("curl_xml-%s-%s", db->instance, db->url);
plugin_register_complex_read (/* group = */ "curl_xml", cb_name, cx_read,
- /* interval = */ NULL, &ud);
+ /* interval = */ 0, &ud);
sfree (cb_name);
}
else
-if COMPILER_IS_GCC
-AM_CFLAGS = -Wall -Werror
-endif
-
AM_CPPFLAGS = -I$(top_srcdir)/src
AM_CPPFLAGS += -DPREFIX='"${prefix}"'
AM_CPPFLAGS += -DCONFIGFILE='"${sysconfdir}/${PACKAGE_NAME}.conf"'
COMMON_LIBS += -ldevinfo
endif
-AUTOMAKE_OPTIONS = subdir-objects
-
sbin_PROGRAMS = collectd
-noinst_LTLIBRARIES = libavltree.la libcommon.la libheap.la libplugin_mock.la
+noinst_LTLIBRARIES = libavltree.la libcommon.la libheap.la libmetadata.la libplugin_mock.la
libavltree_la_SOURCES = utils_avltree.c utils_avltree.h
libheap_la_SOURCES = utils_heap.c utils_heap.h
-libplugin_mock_la_SOURCES = plugin_mock.c utils_cache_mock.c utils_time_mock.c
-libplugin_mock_la_LIBADD = $(COMMON_LIBS)
+libmetadata_la_SOURCES = meta_data.c meta_data.h
+
+libplugin_mock_la_SOURCES = plugin_mock.c utils_cache_mock.c \
+ utils_time.c utils_time.h
+libplugin_mock_la_CPPFLAGS = $(AM_CPPFLAGS) -DMOCK_TIME
+libplugin_mock_la_LIBADD = $(COMMON_LIBS) libcommon.la
collectd_SOURCES = collectd.c collectd.h \
configfile.c configfile.h \
collectd_CFLAGS = $(AM_CFLAGS)
collectd_LDFLAGS = -export-dynamic
collectd_LDADD = libavltree.la libcommon.la libheap.la -lm $(COMMON_LIBS)
-collectd_DEPENDENCIES = libavltree.la libcommon.la libheap.la
+collectd_DEPENDENCIES = libavltree.la libcommon.la libheap.la libmetadata.la
# The daemon needs to call sg_init, so we need to link it against libstatgrab,
# too. -octo
collectd_LDADD += -loconfig
endif
-check_PROGRAMS = test_common test_utils_avltree test_utils_heap
-TESTS = test_common test_utils_avltree test_utils_heap
+check_PROGRAMS = test_common test_meta_data test_utils_avltree test_utils_heap test_utils_time test_utils_subst
+TESTS = test_common test_meta_data test_utils_avltree test_utils_heap test_utils_time test_utils_subst
test_common_SOURCES = common_test.c ../testing.h
-test_common_LDADD = libcommon.la libplugin_mock.la $(COMMON_LIBS)
+test_common_LDADD = libplugin_mock.la
+
+test_meta_data_SOURCES = meta_data_test.c ../testing.h
+test_meta_data_LDADD = libmetadata.la libplugin_mock.la
test_utils_avltree_SOURCES = utils_avltree_test.c ../testing.h
test_utils_avltree_LDADD = libavltree.la $(COMMON_LIBS)
test_utils_heap_SOURCES = utils_heap_test.c ../testing.h
test_utils_heap_LDADD = libheap.la $(COMMON_LIBS)
+
+test_utils_time_SOURCES = utils_time_test.c ../testing.h
+
+test_utils_subst_SOURCES = utils_subst_test.c ../testing.h \
+ utils_subst.c utils_subst.h
+test_utils_subst_LDADD = libplugin_mock.la
#include "configfile.h"
#include <sys/types.h>
-#include <sys/socket.h>
#include <sys/un.h>
#include <netdb.h>
while ((dirlen > 0) && (dir[dirlen - 1] == '/'))
dir[--dirlen] = '\0';
- if (dirlen <= 0) {
+ if (dirlen == 0) {
free (dir);
return (-1);
}
/* TODO
* Remove all settings but `-f' and `-C'
*/
+__attribute__((noreturn))
static void exit_usage (int status)
{
printf ("Usage: "PACKAGE_NAME" [OPTIONS]\n\n"
}
#endif
- plugin_init_all ();
-
- return (0);
+ return plugin_init_all ();
} /* int do_init () */
static int do_shutdown (void)
{
- plugin_shutdown_all ();
- return (0);
+ return plugin_shutdown_all ();
} /* int do_shutdown */
#if COLLECT_DAEMON
#ifdef KERNEL_LINUX
static int notify_upstart (void)
{
- const char *upstart_job = getenv("UPSTART_JOB");
+ char const *upstart_job = getenv("UPSTART_JOB");
if (upstart_job == NULL)
return 0;
if (strcmp(upstart_job, "collectd") != 0)
+ {
+ WARNING ("Environment specifies unexpected UPSTART_JOB=\"%s\", expected \"collectd\". Ignoring the variable.", upstart_job);
return 0;
+ }
- WARNING ("supervised by upstart, will stop to signal readyness");
+ NOTICE("Upstart detected, stopping now to signal readyness.");
raise(SIGSTOP);
unsetenv("UPSTART_JOB");
static int notify_systemd (void)
{
- int fd = -1;
- const char *notifysocket = getenv("NOTIFY_SOCKET");
+ int fd;
+ const char *notifysocket;
struct sockaddr_un su;
- struct iovec iov;
- struct msghdr hdr;
+ size_t su_size;
+ char buffer[] = "READY=1\n";
+ notifysocket = getenv ("NOTIFY_SOCKET");
if (notifysocket == NULL)
return 0;
- if ((strchr("@/", notifysocket[0])) == NULL ||
- strlen(notifysocket) < 2)
+ if ((strlen (notifysocket) < 2)
+ || ((notifysocket[0] != '@') && (notifysocket[0] != '/')))
+ {
+ ERROR ("invalid notification socket NOTIFY_SOCKET=\"%s\": path must be absolute", notifysocket);
return 0;
+ }
+ NOTICE ("Systemd detected, trying to signal readyness.");
+
+ unsetenv ("NOTIFY_SOCKET");
- WARNING ("supervised by systemd, will signal readyness");
- if ((fd = socket(AF_UNIX, SOCK_DGRAM, 0)) < 0) {
- WARNING ("cannot contact systemd socket %s", notifysocket);
+#if defined(SOCK_CLOEXEC)
+ fd = socket (AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC, /* protocol = */ 0);
+#else
+ fd = socket (AF_UNIX, SOCK_DGRAM, /* protocol = */ 0);
+#endif
+ if (fd < 0) {
+ char errbuf[1024];
+ ERROR ("creating UNIX socket failed: %s",
+ sstrerror (errno, errbuf, sizeof (errbuf)));
return 0;
}
- bzero(&su, sizeof(su));
+ memset (&su, 0, sizeof (su));
su.sun_family = AF_UNIX;
- sstrncpy (su.sun_path, notifysocket, sizeof(su.sun_path));
-
- if (notifysocket[0] == '@')
+ if (notifysocket[0] != '@')
+ {
+ /* regular UNIX socket */
+ sstrncpy (su.sun_path, notifysocket, sizeof (su.sun_path));
+ su_size = sizeof (su);
+ }
+ else
+ {
+ /* Linux abstract namespace socket: specify address as "\0foo", i.e.
+ * start with a null byte. Since null bytes have no special meaning in
+ * that case, we have to set su_size correctly to cover only the bytes
+ * that are part of the address. */
+ sstrncpy (su.sun_path, notifysocket, sizeof (su.sun_path));
su.sun_path[0] = 0;
+ su_size = sizeof (sa_family_t) + strlen (notifysocket);
+ if (su_size > sizeof (su))
+ su_size = sizeof (su);
+ }
- bzero(&iov, sizeof(iov));
- iov.iov_base = "READY=1";
- iov.iov_len = strlen("READY=1");
-
- bzero(&hdr, sizeof(hdr));
- hdr.msg_name = &su;
- hdr.msg_namelen = offsetof(struct sockaddr_un, sun_path) +
- strlen(notifysocket);
- hdr.msg_iov = &iov;
- hdr.msg_iovlen = 1;
-
- unsetenv("NOTIFY_SOCKET");
- if (sendmsg(fd, &hdr, MSG_NOSIGNAL) < 0) {
- WARNING ("cannot send notification to systemd");
+ if (sendto (fd, buffer, strlen (buffer), MSG_NOSIGNAL, (void *) &su, (socklen_t) su_size) < 0)
+ {
+ char errbuf[1024];
+ ERROR ("sendto(\"%s\") failed: %s", notifysocket,
+ sstrerror (errno, errbuf, sizeof (errbuf)));
close(fd);
return 0;
}
+
+ unsetenv ("NOTIFY_SOCKET");
close(fd);
return 1;
}
struct sigaction sig_term_action;
struct sigaction sig_usr1_action;
struct sigaction sig_pipe_action;
- char *configfile = CONFIGFILE;
+ const char *configfile = CONFIGFILE;
int test_config = 0;
int test_readall = 0;
const char *basedir;
#endif
)
{
+ int status;
+
if ((pid = fork ()) == -1)
{
/* error */
close (1);
close (0);
- if (open ("/dev/null", O_RDWR) != 0)
+ status = open ("/dev/null", O_RDWR);
+ if (status != 0)
{
- ERROR ("Error: Could not connect `STDIN' to `/dev/null'");
+ ERROR ("Error: Could not connect `STDIN' to `/dev/null' (status %d)", status);
return (1);
}
- if (dup (0) != 1)
+
+ status = dup (0);
+ if (status != 1)
{
- ERROR ("Error: Could not connect `STDOUT' to `/dev/null'");
+ ERROR ("Error: Could not connect `STDOUT' to `/dev/null' (status %d)", status);
return (1);
}
- if (dup (0) != 2)
+
+ status = dup (0);
+ if (status != 2)
{
- ERROR ("Error: Could not connect `STDERR' to `/dev/null'");
+ ERROR ("Error: Could not connect `STDERR' to `/dev/null', (status %d)", status);
return (1);
}
} /* if (daemonize) */
/*
* run the actual loops
*/
- do_init ();
+ if (do_init () != 0)
+ {
+ ERROR ("Error: one or more plugin init callbacks failed.");
+ exit_status = 1;
+ }
if (test_readall)
{
if (plugin_read_all_once () != 0)
+ {
+ ERROR ("Error: one or more plugin read callbacks failed.");
exit_status = 1;
+ }
}
else
{
/* close syslog */
INFO ("Exiting normally.");
- do_shutdown ();
+ if (do_shutdown () != 0)
+ {
+ ERROR ("Error: one or more plugin shutdown callbacks failed.");
+ exit_status = 1;
+ }
#if COLLECT_DAEMON
if (daemonize)
# include <time.h>
# endif
#endif
+#if HAVE_SYS_SOCKET_H
+# include <sys/socket.h>
+#endif
#if HAVE_ASSERT_H
# include <assert.h>
# pragma GCC poison strcpy strcat strtok
#endif
-/*
+/*
* Special hack for the perl plugin: Because the later included perl.h defines
* a macro which is never used, but contains `sprintf', we cannot poison that
* identifies just yet. The parl plugin will do that itself once perl.h is
/* for getaddrinfo */
#include <sys/types.h>
-#include <sys/socket.h>
#include <netdb.h>
#include <poll.h>
return (strdup (static_buffer));
/* Allocate a buffer large enough to hold the string. */
- alloc_buffer = malloc (alloc_buffer_size);
+ alloc_buffer = calloc (1, alloc_buffer_size);
if (alloc_buffer == NULL)
return (NULL);
- memset (alloc_buffer, 0, alloc_buffer_size);
/* Print again into this new buffer. */
va_start (ap, format);
/* Do not use `strdup' here, because it's not specified in POSIX. It's
* ``only'' an XSI extension. */
sz = strlen (s) + 1;
- r = (char *) malloc (sizeof (char) * sz);
+ r = malloc (sz);
if (r == NULL)
{
ERROR ("sstrdup: Out of memory.");
assert ((0 > status) || (nleft >= (size_t)status));
- nleft = nleft - status;
- ptr = ptr + status;
+ nleft = nleft - ((size_t) status);
+ ptr = ptr + ((size_t) status);
}
return (0);
if (status < 0)
return (status);
- nleft = nleft - status;
- ptr = ptr + status;
+ nleft = nleft - ((size_t) status);
+ ptr = ptr + ((size_t) status);
}
return (0);
size_t sep_len;
size_t i;
- if ((buffer_size < 1) || (fields_num <= 0))
+ if ((buffer_size < 1) || (fields_num == 0))
return (-1);
memset (buffer, 0, buffer_size);
}
assert (buffer[buffer_size - 1] == 0);
- return (strlen (buffer));
+ return ((int) strlen (buffer));
}
-int strsubstitute (char *str, char c_from, char c_to)
-{
- int ret;
-
- if (str == NULL)
- return (-1);
-
- ret = 0;
- while (*str != '\0')
- {
- if (*str == c_from)
- {
- *str = c_to;
- ret++;
- }
- str++;
- }
-
- return (ret);
-} /* int strsubstitute */
-
int escape_string (char *buffer, size_t buffer_size)
{
char *temp;
if (buffer_size < 3)
return (EINVAL);
- temp = (char *) malloc (buffer_size);
+ temp = calloc (1, buffer_size);
if (temp == NULL)
return (ENOMEM);
- memset (temp, 0, buffer_size);
temp[0] = '"';
j = 1;
int escape_slashes (char *buffer, size_t buffer_size)
{
- int i;
size_t buffer_len;
+ size_t i;
buffer_len = strlen (buffer);
* Join the components together again
*/
dir[0] = '/';
- if (strjoin (dir + path_is_absolute, dir_len - path_is_absolute,
- fields, i + 1, "/") < 0)
+ if (strjoin (dir + path_is_absolute, (size_t) (dir_len - path_is_absolute),
+ fields, (size_t) (i + 1), "/") < 0)
{
ERROR ("strjoin failed: `%s', component #%i", file_orig, i);
return (-1);
{
size_t offset = 0;
int status;
- int i;
+ size_t i;
gauge_t *rates = NULL;
assert (0 == strcmp (ds->type, vl->type));
int parse_values (char *buffer, value_list_t *vl, const data_set_t *ds)
{
- int i;
+ size_t i;
char *dummy;
char *ptr;
char *saveptr;
if ((buffer == NULL) || (vl == NULL) || (ds == NULL))
return EINVAL;
- i = -1;
+ i = 0;
dummy = buffer;
saveptr = NULL;
+ vl->time = 0;
while ((ptr = strtok_r (dummy, ":", &saveptr)) != NULL)
{
dummy = NULL;
if (i >= vl->values_len)
{
/* Make sure i is invalid. */
- i = vl->values_len + 1;
+ i = 0;
break;
}
- if (i == -1)
+ if (vl->time == 0)
{
if (strcmp ("N", ptr) == 0)
vl->time = cdtime ();
vl->time = DOUBLE_TO_CDTIME_T (tmp);
}
- }
- else
- {
- if ((strcmp ("U", ptr) == 0) && (ds->ds[i].type == DS_TYPE_GAUGE))
- vl->values[i].gauge = NAN;
- else if (0 != parse_value (ptr, &vl->values[i], ds->ds[i].type))
- return -1;
+
+ continue;
}
+ if ((strcmp ("U", ptr) == 0) && (ds->ds[i].type == DS_TYPE_GAUGE))
+ vl->values[i].gauge = NAN;
+ else if (0 != parse_value (ptr, &vl->values[i], ds->ds[i].type))
+ return -1;
+
i++;
} /* while (strtok_r) */
- if ((ptr != NULL) || (i != vl->values_len))
+ if ((ptr != NULL) || (i == 0))
return (-1);
return (0);
} /* int parse_values */
if (old_value > new_value)
{
if (old_value <= 4294967295U)
- diff = (4294967295U - old_value) + new_value;
+ diff = (4294967295U - old_value) + new_value + 1;
else
- diff = (18446744073709551615ULL - old_value)
- + new_value;
+ diff = (18446744073709551615ULL - old_value) + new_value + 1;
}
else
{
return (0);
} /* }}} value_t rate_to_value */
-int value_to_rate (value_t *ret_rate, derive_t value, /* {{{ */
- value_to_rate_state_t *state,
- int ds_type, cdtime_t t)
+int value_to_rate (gauge_t *ret_rate, /* {{{ */
+ value_t value, int ds_type, cdtime_t t, value_to_rate_state_t *state)
{
- double interval;
+ gauge_t interval;
/* Another invalid state: The time is not increasing. */
if (t <= state->last_time)
interval = CDTIME_T_TO_DOUBLE(t - state->last_time);
/* Previous value is invalid. */
- if (state->last_time == 0) /* {{{ */
+ if (state->last_time == 0)
{
- if (ds_type == DS_TYPE_DERIVE)
- {
- state->last_value.derive = value;
- }
- else if (ds_type == DS_TYPE_COUNTER)
- {
- state->last_value.counter = (counter_t) value;
- }
- else if (ds_type == DS_TYPE_ABSOLUTE)
- {
- state->last_value.absolute = (absolute_t) value;
- }
- else
- {
- assert (23 == 42);
- }
-
+ state->last_value = value;
state->last_time = t;
return (EAGAIN);
- } /* }}} */
+ }
- if (ds_type == DS_TYPE_DERIVE)
- {
- ret_rate->gauge = (value - state->last_value.derive) / interval;
- state->last_value.derive = value;
+ switch (ds_type) {
+ case DS_TYPE_DERIVE: {
+ derive_t diff = value.derive - state->last_value.derive;
+ *ret_rate = ((gauge_t) diff) / ((gauge_t) interval);
+ break;
}
- else if (ds_type == DS_TYPE_COUNTER)
- {
- ret_rate->gauge = (((counter_t)value) - state->last_value.counter) / interval;
- state->last_value.counter = (counter_t) value;
+ case DS_TYPE_GAUGE: {
+ *ret_rate = value.gauge;
+ break;
}
- else if (ds_type == DS_TYPE_ABSOLUTE)
- {
- ret_rate->gauge = (((absolute_t)value) - state->last_value.absolute) / interval;
- state->last_value.absolute = (absolute_t) value;
+ case DS_TYPE_COUNTER: {
+ counter_t diff = counter_diff (state->last_value.counter, value.counter);
+ *ret_rate = ((gauge_t) diff) / ((gauge_t) interval);
+ break;
}
- else
- {
- assert (23 == 42);
+ case DS_TYPE_ABSOLUTE: {
+ absolute_t diff = value.absolute;
+ *ret_rate = ((gauge_t) diff) / ((gauge_t) interval);
+ break;
+ }
+ default:
+ return EINVAL;
}
- state->last_time = t;
+ state->last_value = value;
+ state->last_time = t;
return (0);
} /* }}} value_t rate_to_value */
#define sfree(ptr) \
do { \
- if((ptr) != NULL) { \
- free(ptr); \
- } \
+ free(ptr); \
(ptr) = NULL; \
} while (0)
*/
void replace_special (char *buffer, size_t buffer_size);
-int strsubstitute (char *str, char c_from, char c_to);
-
/*
* NAME
* strunescape
int rate_to_value (value_t *ret_value, gauge_t rate,
rate_to_value_state_t *state, int ds_type, cdtime_t t);
-int value_to_rate (value_t *ret_rate, derive_t value,
- value_to_rate_state_t *state, int ds_type, cdtime_t t);
+int value_to_rate (gauge_t *ret_rate, value_t value, int ds_type, cdtime_t t,
+ value_to_rate_state_t *state);
/* Converts a service name (a string) to a port number
* (in the range [1-65535]). Returns less than zero on error. */
* Florian octo Forster <octo at collectd.org>
*/
-#include "testing.h"
#include "common.h"
+#include "testing.h"
#if HAVE_LIBKSTAT
kstat_ctl_t *kc;
ret = sstrncpy (ptr, "foobar", 8);
OK(ret == ptr);
- STREQ ("foobar", ptr);
+ EXPECT_EQ_STR ("foobar", ptr);
OK(buffer[3] == buffer[12]);
ret = sstrncpy (ptr, "abc", 8);
OK(ret == ptr);
- STREQ ("abc", ptr);
+ EXPECT_EQ_STR ("abc", ptr);
OK(buffer[3] == buffer[12]);
ret = sstrncpy (ptr, "collectd", 8);
OK(ret == ptr);
OK(ptr[7] == 0);
- STREQ ("collect", ptr);
+ EXPECT_EQ_STR ("collect", ptr);
OK(buffer[3] == buffer[12]);
return (0);
status = ssnprintf (ptr, 8, "%i", 1337);
OK(status == 4);
- STREQ ("1337", ptr);
+ EXPECT_EQ_STR ("1337", ptr);
status = ssnprintf (ptr, 8, "%s", "collectd");
OK(status == 8);
OK(ptr[7] == 0);
- STREQ ("collect", ptr);
+ EXPECT_EQ_STR ("collect", ptr);
OK(buffer[3] == buffer[12]);
return (0);
ptr = sstrdup ("collectd");
OK(ptr != NULL);
- STREQ ("collectd", ptr);
+ EXPECT_EQ_STR ("collectd", ptr);
sfree(ptr);
- OK(ptr == NULL);
ptr = sstrdup (NULL);
OK(ptr == NULL);
strncpy (buffer, "foo bar", sizeof (buffer));
status = strsplit (buffer, fields, 8);
OK(status == 2);
- STREQ ("foo", fields[0]);
- STREQ ("bar", fields[1]);
+ EXPECT_EQ_STR ("foo", fields[0]);
+ EXPECT_EQ_STR ("bar", fields[1]);
strncpy (buffer, "foo \t bar", sizeof (buffer));
status = strsplit (buffer, fields, 8);
OK(status == 2);
- STREQ ("foo", fields[0]);
- STREQ ("bar", fields[1]);
+ EXPECT_EQ_STR ("foo", fields[0]);
+ EXPECT_EQ_STR ("bar", fields[1]);
strncpy (buffer, "one two\tthree\rfour\nfive", sizeof (buffer));
status = strsplit (buffer, fields, 8);
OK(status == 5);
- STREQ ("one", fields[0]);
- STREQ ("two", fields[1]);
- STREQ ("three", fields[2]);
- STREQ ("four", fields[3]);
- STREQ ("five", fields[4]);
+ EXPECT_EQ_STR ("one", fields[0]);
+ EXPECT_EQ_STR ("two", fields[1]);
+ EXPECT_EQ_STR ("three", fields[2]);
+ EXPECT_EQ_STR ("four", fields[3]);
+ EXPECT_EQ_STR ("five", fields[4]);
strncpy (buffer, "\twith trailing\n", sizeof (buffer));
status = strsplit (buffer, fields, 8);
OK(status == 2);
- STREQ ("with", fields[0]);
- STREQ ("trailing", fields[1]);
+ EXPECT_EQ_STR ("with", fields[0]);
+ EXPECT_EQ_STR ("trailing", fields[1]);
strncpy (buffer, "1 2 3 4 5 6 7 8 9 10 11 12 13", sizeof (buffer));
status = strsplit (buffer, fields, 8);
OK(status == 8);
- STREQ ("7", fields[6]);
- STREQ ("8", fields[7]);
+ EXPECT_EQ_STR ("7", fields[6]);
+ EXPECT_EQ_STR ("8", fields[7]);
strncpy (buffer, "single", sizeof (buffer));
status = strsplit (buffer, fields, 8);
OK(status == 1);
- STREQ ("single", fields[0]);
+ EXPECT_EQ_STR ("single", fields[0]);
strncpy (buffer, "", sizeof (buffer));
status = strsplit (buffer, fields, 8);
status = strjoin (buffer, sizeof (buffer), fields, 2, "!");
OK(status == 7);
- STREQ ("foo!bar", buffer);
+ EXPECT_EQ_STR ("foo!bar", buffer);
status = strjoin (buffer, sizeof (buffer), fields, 1, "!");
OK(status == 3);
- STREQ ("foo", buffer);
+ EXPECT_EQ_STR ("foo", buffer);
status = strjoin (buffer, sizeof (buffer), fields, 0, "!");
OK(status < 0);
status = strjoin (buffer, sizeof (buffer), fields, 2, "rcht");
OK(status == 10);
- STREQ ("foorchtbar", buffer);
+ EXPECT_EQ_STR ("foorchtbar", buffer);
status = strjoin (buffer, sizeof (buffer), fields, 4, "");
OK(status == 12);
- STREQ ("foobarbazqux", buffer);
+ EXPECT_EQ_STR ("foobarbazqux", buffer);
status = strjoin (buffer, sizeof (buffer), fields, 4, "!");
OK(status == 15);
- STREQ ("foo!bar!baz!qux", buffer);
+ EXPECT_EQ_STR ("foo!bar!baz!qux", buffer);
fields[0] = "0123";
fields[1] = "4567";
return (0);
}
+DEF_TEST(escape_slashes)
+{
+ struct {
+ char *str;
+ char *want;
+ } cases[] = {
+ {"foo/bar/baz", "foo_bar_baz"},
+ {"/like/a/path", "like_a_path"},
+ {"trailing/slash/", "trailing_slash_"},
+ {"foo//bar", "foo__bar"},
+ };
+ size_t i;
+
+ for (i = 0; i < STATIC_ARRAY_SIZE (cases); i++) {
+ char buffer[32];
+
+ strncpy (buffer, cases[i].str, sizeof (buffer));
+ OK(escape_slashes (buffer, sizeof (buffer)) == 0);
+ EXPECT_EQ_STR(cases[i].want, buffer);
+ }
+
+ return 0;
+}
+
+DEF_TEST(escape_string)
+{
+ struct {
+ char *str;
+ char *want;
+ } cases[] = {
+ {"foobar", "foobar"},
+ {"f00bar", "f00bar"},
+ {"foo bar", "\"foo bar\""},
+ {"foo \"bar\"", "\"foo \\\"bar\\\"\""},
+ {"012345678901234", "012345678901234"},
+ {"012345 78901234", "\"012345 789012\""},
+ {"012345 78901\"34", "\"012345 78901\""},
+ };
+ size_t i;
+
+ for (i = 0; i < STATIC_ARRAY_SIZE (cases); i++) {
+ char buffer[16];
+
+ strncpy (buffer, cases[i].str, sizeof (buffer));
+ OK(escape_string (buffer, sizeof (buffer)) == 0);
+ EXPECT_EQ_STR(cases[i].want, buffer);
+ }
+
+ return 0;
+}
+
DEF_TEST(strunescape)
{
char buffer[16];
strncpy (buffer, "foo\\tbar", sizeof (buffer));
status = strunescape (buffer, sizeof (buffer));
OK(status == 0);
- STREQ ("foo\tbar", buffer);
+ EXPECT_EQ_STR ("foo\tbar", buffer);
strncpy (buffer, "\\tfoo\\r\\n", sizeof (buffer));
status = strunescape (buffer, sizeof (buffer));
OK(status == 0);
- STREQ ("\tfoo\r\n", buffer);
+ EXPECT_EQ_STR ("\tfoo\r\n", buffer);
strncpy (buffer, "With \\\"quotes\\\"", sizeof (buffer));
status = strunescape (buffer, sizeof (buffer));
OK(status == 0);
- STREQ ("With \"quotes\"", buffer);
+ EXPECT_EQ_STR ("With \"quotes\"", buffer);
/* Backslash before null byte */
strncpy (buffer, "\\tbackslash end\\", sizeof (buffer));
status = strunescape (buffer, sizeof (buffer));
OK(status != 0);
- STREQ ("\tbackslash end", buffer);
+ EXPECT_EQ_STR ("\tbackslash end", buffer);
return (0);
/* Backslash at buffer end */
return (0);
}
+DEF_TEST(parse_values)
+{
+ struct {
+ char buffer[64];
+ int status;
+ gauge_t value;
+ } cases[] = {
+ {"1435044576:42", 0, 42.0},
+ {"1435044576:42:23", -1, NAN},
+ {"1435044576:U", 0, NAN},
+ {"N:12.3", 0, 12.3},
+ {"N:42.0:23", -1, NAN},
+ {"N:U", 0, NAN},
+ {"T:42.0", -1, NAN},
+ };
+
+ size_t i;
+ for (i = 0; i < STATIC_ARRAY_SIZE (cases); i++)
+ {
+ data_source_t dsrc = {
+ .name = "value",
+ .type = DS_TYPE_GAUGE,
+ .min = 0.0,
+ .max = NAN,
+ };
+ data_set_t ds = {
+ .type = "example",
+ .ds_num = 1,
+ .ds = &dsrc,
+ };
+
+ value_t v = {
+ .gauge = NAN,
+ };
+ value_list_t vl = {
+ .values = &v,
+ .values_len = 1,
+ .time = 0,
+ .interval = 0,
+ .host = "example.com",
+ .plugin = "common_test",
+ .type = "example",
+ .meta = NULL,
+ };
+
+ int status = parse_values (cases[i].buffer, &vl, &ds);
+ EXPECT_EQ_INT (cases[i].status, status);
+ if (status != 0)
+ continue;
+
+ EXPECT_EQ_DOUBLE (cases[i].value, vl.values[0].gauge);
+ }
+
+ return (0);
+}
+
+DEF_TEST(value_to_rate)
+{
+ struct {
+ time_t t0;
+ time_t t1;
+ int ds_type;
+ value_t v0;
+ value_t v1;
+ gauge_t want;
+ } cases[] = {
+ { 0, 10, DS_TYPE_DERIVE, {.derive = 0}, {.derive = 1000}, NAN},
+ {10, 20, DS_TYPE_DERIVE, {.derive = 1000}, {.derive = 2000}, 100.0},
+ {20, 30, DS_TYPE_DERIVE, {.derive = 2000}, {.derive = 1800}, -20.0},
+ { 0, 10, DS_TYPE_COUNTER, {.counter = 0}, {.counter = 1000}, NAN},
+ {10, 20, DS_TYPE_COUNTER, {.counter = 1000}, {.counter = 5000}, 400.0},
+ /* 32bit wrap-around. */
+ {20, 30, DS_TYPE_COUNTER, {.counter = 4294967238ULL}, {.counter = 42}, 10.0},
+ /* 64bit wrap-around. */
+ {30, 40, DS_TYPE_COUNTER, {.counter = 18446744073709551558ULL}, {.counter = 42}, 10.0},
+ };
+ size_t i;
+
+ for (i = 0; i < STATIC_ARRAY_SIZE (cases); i++) {
+ value_to_rate_state_t state = { cases[i].v0, TIME_T_TO_CDTIME_T (cases[i].t0) };
+ gauge_t got;
+
+ if (cases[i].t0 == 0) {
+ OK(value_to_rate (&got, cases[i].v1, cases[i].ds_type, TIME_T_TO_CDTIME_T(cases[i].t1), &state) == EAGAIN);
+ continue;
+ }
+
+ OK(value_to_rate (&got, cases[i].v1, cases[i].ds_type, TIME_T_TO_CDTIME_T(cases[i].t1), &state) == 0);
+ EXPECT_EQ_DOUBLE(cases[i].want, got);
+ }
+
+ return 0;
+}
+
int main (void)
{
RUN_TEST(sstrncpy);
RUN_TEST(sstrdup);
RUN_TEST(strsplit);
RUN_TEST(strjoin);
+ RUN_TEST(escape_slashes);
+ RUN_TEST(escape_string);
RUN_TEST(strunescape);
+ RUN_TEST(parse_values);
+ RUN_TEST(value_to_rate);
END_TEST;
}
typedef struct cf_value_map_s
{
- char *key;
+ const char *key;
int (*func) (oconfig_item_t *);
} cf_value_map_t;
typedef struct cf_global_option_s
{
- char *key;
+ const char *key;
char *value;
- char *def;
+ const char *def;
} cf_global_option_t;
/*
static int dispatch_value_plugindir (oconfig_item_t *ci)
{
assert (strcasecmp (ci->key, "PluginDir") == 0);
-
+
if (ci->values_num != 1)
return (-1);
if (ci->values[0].type != OCONFIG_TYPE_STRING)
/* default to the global interval set before loading this plugin */
memset (&ctx, 0, sizeof (ctx));
ctx.interval = cf_get_default_interval ();
+ ctx.flush_interval = 0;
+ ctx.flush_timeout = 0;
- for (i = 0; i < ci->children_num; ++i) {
- if (strcasecmp("Globals", ci->children[i].key) == 0)
- cf_util_get_flag (ci->children + i, &flags, PLUGIN_FLAGS_GLOBAL);
- else if (strcasecmp ("Interval", ci->children[i].key) == 0) {
- if (cf_util_get_cdtime (ci->children + i, &ctx.interval) != 0) {
- /* cf_util_get_cdtime will log an error */
- continue;
- }
- }
+ for (i = 0; i < ci->children_num; ++i)
+ {
+ oconfig_item_t *child = ci->children + i;
+
+ if (strcasecmp("Globals", child->key) == 0)
+ cf_util_get_flag (child, &flags, PLUGIN_FLAGS_GLOBAL);
+ else if (strcasecmp ("Interval", child->key) == 0)
+ cf_util_get_cdtime (child, &ctx.interval);
+ else if (strcasecmp ("FlushInterval", child->key) == 0)
+ cf_util_get_cdtime (child, &ctx.flush_interval);
+ else if (strcasecmp ("FlushTimeout", child->key) == 0)
+ cf_util_get_cdtime (child, &ctx.flush_timeout);
else {
WARNING("Ignoring unknown LoadPlugin option \"%s\" "
"for plugin \"%s\"",
- ci->children[i].key, ci->values[0].value.string);
+ child->key, ci->values[0].value.string);
}
}
static int dispatch_value (oconfig_item_t *ci)
{
- int ret = -2;
+ int ret = 0;
int i;
for (i = 0; i < cf_value_map_num; i++)
static int dispatch_block_plugin (oconfig_item_t *ci)
{
int i;
- char *name;
+ const char *name;
cf_complex_callback_t *cb;
return (0);
}
- temp = (oconfig_item_t *) realloc (dst->children,
+ temp = realloc (dst->children,
sizeof (oconfig_item_t)
* (dst->children_num + src->children_num - 1));
if (temp == NULL)
if ((src == NULL) || (src->children_num == 0))
return (0);
- temp = (oconfig_item_t *) realloc (dst->children,
+ temp = realloc (dst->children,
sizeof (oconfig_item_t)
* (dst->children_num + src->children_num));
if (temp == NULL)
return (NULL);
}
- root = (oconfig_item_t *) malloc (sizeof (oconfig_item_t));
+ root = calloc (1, sizeof (*root));
if (root == NULL)
{
- ERROR ("configfile: malloc failed.");
+ ERROR ("configfile: calloc failed.");
closedir (dh);
return (NULL);
}
- memset (root, 0, sizeof (oconfig_item_t));
while ((de = readdir (dh)) != NULL)
{
}
++filenames_num;
- tmp = (char **) realloc (filenames,
+ tmp = realloc (filenames,
filenames_num * sizeof (*filenames));
if (tmp == NULL) {
ERROR ("configfile: realloc failed.");
return (NULL);
}
- root = (oconfig_item_t *) malloc (sizeof (oconfig_item_t));
+ root = calloc (1, sizeof (*root));
if (root == NULL)
{
- ERROR ("configfile: malloc failed.");
+ ERROR ("configfile: calloc failed.");
return (NULL);
}
- memset (root, '\0', sizeof (oconfig_item_t));
/* wordexp() might return a sorted list already. That's not
* documented though, so let's make sure we get what we want. */
} /* oconfig_item_t *cf_read_generic */
#endif /* !HAVE_WORDEXP_H */
-/*
+/*
* Public functions
*/
int global_option_set (const char *option, const char *value)
if (i >= cf_global_options_num)
return (NULL);
-
+
return ((cf_global_options[i].value != NULL)
? cf_global_options[i].value
: cf_global_options[i].def);
cf_unregister (type);
/* This pointer will be free'd in `cf_unregister' */
- if ((cf_cb = (cf_callback_t *) malloc (sizeof (cf_callback_t))) == NULL)
+ if ((cf_cb = malloc (sizeof (*cf_cb))) == NULL)
return;
cf_cb->type = type;
{
cf_complex_callback_t *new;
- new = (cf_complex_callback_t *) malloc (sizeof (cf_complex_callback_t));
+ new = malloc (sizeof (*new));
if (new == NULL)
return (-1);
return (0);
} /* int cf_register_complex */
-int cf_read (char *filename)
+int cf_read (const char *filename)
{
oconfig_item_t *conf;
int i;
+ int ret = 0;
conf = cf_read_generic (filename, /* pattern = */ NULL, /* depth = */ 0);
if (conf == NULL)
for (i = 0; i < conf->children_num; i++)
{
if (conf->children[i].children == NULL)
- dispatch_value (conf->children + i);
+ {
+ if (dispatch_value (conf->children + i) != 0)
+ ret = -1;
+ }
else
- dispatch_block (conf->children + i);
+ {
+ if (dispatch_block (conf->children + i) != 0)
+ ret = -1;
+ }
}
oconfig_free (conf);
/* Read the default types.db if no `TypesDB' option was given. */
if (cf_default_typesdb)
- read_types_list (PKGDATADIR"/types.db");
+ {
+ if (read_types_list (PKGDATADIR"/types.db") != 0)
+ ret = -1;
+ }
- return (0);
+ return ret;
} /* int cf_read */
/* Assures the config option is a string, duplicates it and returns the copy in
/*
* DESCRIPTION
* Remove a registered plugin from the internal data structures.
- *
+ *
* PARAMETERS
* `type' Name of the plugin (must be the same as passed to
* `plugin_register'
* Returns zero upon success and non-zero otherwise. A error-message will have
* been printed in this case.
*/
-int cf_read (char *filename);
+int cf_read (const char *filename);
int global_option_set (const char *option, const char *value);
const char *global_option_get (const char *option);
return (NULL);
sz = strlen (orig) + 1;
- dest = (char *) malloc (sz);
+ dest = malloc (sz);
if (dest == NULL)
return (NULL);
return (-1);
}
- m = (fc_match_t *) malloc (sizeof (*m));
+ m = calloc (1, sizeof (*m));
if (m == NULL)
{
- ERROR ("fc_config_add_match: malloc failed.");
+ ERROR ("fc_config_add_match: calloc failed.");
return (-1);
}
- memset (m, 0, sizeof (*m));
sstrncpy (m->name, ptr->name, sizeof (m->name));
memcpy (&m->proc, &ptr->proc, sizeof (m->proc));
return (-1);
}
- t = (fc_target_t *) malloc (sizeof (*t));
+ t = calloc (1, sizeof (*t));
if (t == NULL)
{
- ERROR ("fc_config_add_target: malloc failed.");
+ ERROR ("fc_config_add_target: calloc failed.");
return (-1);
}
- memset (t, 0, sizeof (*t));
sstrncpy (t->name, ptr->name, sizeof (t->name));
memcpy (&t->proc, &ptr->proc, sizeof (t->proc));
{
t->user_data = NULL;
}
-
+
if (*targets_head != NULL)
{
ptr = *targets_head;
return (-1);
}
- rule = (fc_rule_t *) malloc (sizeof (*rule));
+ rule = calloc (1, sizeof (*rule));
if (rule == NULL)
{
- ERROR ("fc_config_add_rule: malloc failed.");
+ ERROR ("fc_config_add_rule: calloc failed.");
return (-1);
}
- memset (rule, 0, sizeof (*rule));
- rule->next = NULL;
if (ci->values_num == 1)
{
if (chain == NULL)
{
- chain = (fc_chain_t *) malloc (sizeof (*chain));
+ chain = calloc (1, sizeof (*chain));
if (chain == NULL)
{
- ERROR ("fc_config_add_chain: malloc failed.");
+ ERROR ("fc_config_add_chain: calloc failed.");
return (-1);
}
- memset (chain, 0, sizeof (*chain));
sstrncpy (chain->name, ci->values[0].value.string, sizeof (chain->name));
- chain->rules = NULL;
- chain->targets = NULL;
- chain->next = NULL;
}
for (i = 0; i < ci->children_num; i++)
}
plugin = child->values[j].value.string;
- temp = (fc_writer_t *) realloc (plugin_list, (plugin_list_len + 2)
+ temp = realloc (plugin_list, (plugin_list_len + 2)
* (sizeof (*plugin_list)));
if (temp == NULL)
{
DEBUG ("fc_register_match (%s);", name);
- m = (fc_match_t *) malloc (sizeof (*m));
+ m = calloc (1, sizeof (*m));
if (m == NULL)
return (-ENOMEM);
- memset (m, 0, sizeof (*m));
sstrncpy (m->name, name, sizeof (m->name));
memcpy (&m->proc, &proc, sizeof (m->proc));
- m->next = NULL;
if (match_list_head == NULL)
{
DEBUG ("fc_register_target (%s);", name);
- t = (fc_target_t *) malloc (sizeof (*t));
+ t = calloc (1, sizeof (*t));
if (t == NULL)
return (-ENOMEM);
- memset (t, 0, sizeof (*t));
sstrncpy (t->name, name, sizeof (t->name));
memcpy (&t->proc, &proc, sizeof (t->proc));
- t->next = NULL;
if (target_list_head == NULL)
{
int fc_default_action (const data_set_t *ds, value_list_t *vl);
-/*
+/*
* Shortcut for global configuration
*/
int fc_configure (const oconfig_item_t *ci);
return (NULL);
sz = strlen (orig) + 1;
- dest = (char *) malloc (sz);
+ dest = malloc (sz);
if (dest == NULL)
return (NULL);
{
meta_entry_t *e;
- e = (meta_entry_t *) malloc (sizeof (*e));
+ e = calloc (1, sizeof (*e));
if (e == NULL)
{
- ERROR ("md_entry_alloc: malloc failed.");
+ ERROR ("md_entry_alloc: calloc failed.");
return (NULL);
}
- memset (e, 0, sizeof (*e));
e->key = md_strdup (key);
if (e->key == NULL)
return (e);
} /* }}} meta_entry_t *md_entry_alloc */
-static meta_entry_t *md_entry_clone (const meta_entry_t *orig) /* {{{ */
+/* XXX: The lock on md must be held while calling this function! */
+static meta_entry_t *md_entry_clone_contents (const meta_entry_t *orig) /* {{{ */
{
meta_entry_t *copy;
- if (orig == NULL)
- return (NULL);
+ /* WARNINGS :
+ * - we do not check that orig != NULL here. You should have done it before.
+ * - we do not set copy->next. DO NOT FORGET TO SET copy->next IN YOUR FUNCTION
+ */
copy = md_entry_alloc (orig->key);
if (copy == NULL)
else
copy->value = orig->value;
+ return (copy);
+} /* }}} meta_entry_t *md_entry_clone_contents */
+
+static meta_entry_t *md_entry_clone (const meta_entry_t *orig) /* {{{ */
+{
+ meta_entry_t *copy;
+
+ if (orig == NULL)
+ return (NULL);
+
+ copy = md_entry_clone_contents(orig);
+
copy->next = md_entry_clone (orig->next);
return (copy);
} /* }}} meta_entry_t *md_entry_clone */
} /* }}} int md_entry_insert */
/* XXX: The lock on md must be held while calling this function! */
+static int md_entry_insert_clone (meta_data_t *md, meta_entry_t *orig) /* {{{ */
+{
+ meta_entry_t *e;
+ meta_entry_t *this;
+ meta_entry_t *prev;
+
+ /* WARNINGS :
+ * - we do not check that md and e != NULL here. You should have done it before.
+ * - we do not use the lock. You should have set it before.
+ */
+
+ e = md_entry_clone_contents(orig);
+
+ prev = NULL;
+ this = md->head;
+ while (this != NULL)
+ {
+ if (strcasecmp (e->key, this->key) == 0)
+ break;
+
+ prev = this;
+ this = this->next;
+ }
+
+ if (this == NULL)
+ {
+ /* This key does not exist yet. */
+ if (md->head == NULL)
+ md->head = e;
+ else
+ {
+ assert (prev != NULL);
+ prev->next = e;
+ }
+
+ e->next = NULL;
+ }
+ else /* (this != NULL) */
+ {
+ if (prev == NULL)
+ md->head = e;
+ else
+ prev->next = e;
+
+ e->next = this->next;
+ }
+
+ if (this != NULL)
+ {
+ this->next = NULL;
+ md_entry_free (this);
+ }
+
+ return (0);
+} /* }}} int md_entry_insert_clone */
+
+/* XXX: The lock on md must be held while calling this function! */
static meta_entry_t *md_entry_lookup (meta_data_t *md, /* {{{ */
const char *key)
{
{
meta_data_t *md;
- md = (meta_data_t *) malloc (sizeof (*md));
+ md = calloc (1, sizeof (*md));
if (md == NULL)
{
- ERROR ("meta_data_create: malloc failed.");
+ ERROR ("meta_data_create: calloc failed.");
return (NULL);
}
- memset (md, 0, sizeof (*md));
- md->head = NULL;
pthread_mutex_init (&md->lock, /* attr = */ NULL);
return (md);
return (copy);
} /* }}} meta_data_t *meta_data_clone */
+int meta_data_clone_merge (meta_data_t **dest, meta_data_t *orig) /* {{{ */
+{
+ meta_entry_t *e;
+
+ if (orig == NULL)
+ return (0);
+
+ if (*dest == NULL) {
+ *dest = meta_data_clone(orig);
+ return(0);
+ }
+
+ pthread_mutex_lock (&orig->lock);
+ for (e=orig->head; e != NULL; e = e->next)
+ {
+ md_entry_insert_clone((*dest), e);
+ }
+ pthread_mutex_unlock (&orig->lock);
+
+ return (0);
+} /* }}} int meta_data_clone_merge */
+
void meta_data_destroy (meta_data_t *md) /* {{{ */
{
if (md == NULL)
pthread_mutex_lock (&md->lock);
for (e = md->head; e != NULL; e = e->next)
- ++count;
+ ++count;
if (count == 0)
{
*toc = calloc(count, sizeof(**toc));
for (e = md->head; e != NULL; e = e->next)
(*toc)[i++] = strdup(e->key);
-
+
pthread_mutex_unlock (&md->lock);
return count;
} /* }}} int meta_data_toc */
ERROR ("meta_data_get_string: md_strdup failed.");
return (-ENOMEM);
}
-
+
pthread_mutex_unlock (&md->lock);
*value = temp;
meta_data_t *meta_data_create (void);
meta_data_t *meta_data_clone (meta_data_t *orig);
+int meta_data_clone_merge (meta_data_t **dest, meta_data_t *orig);
void meta_data_destroy (meta_data_t *md);
int meta_data_exists (meta_data_t *md, const char *key);
--- /dev/null
+/**
+ * collectd - src/daemon/meta_data_test.c
+ * Copyright (C) 2015 Florian octo Forster
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ * Florian octo Forster <octo at collectd.org>
+ */
+
+#include "common.h" /* for STATIC_ARRAY_SIZE */
+#include "collectd.h"
+#include "testing.h"
+#include "meta_data.h"
+
+DEF_TEST(base)
+{
+ meta_data_t *m;
+
+ char *s;
+ int64_t si;
+ uint64_t ui;
+ double d;
+ _Bool b;
+
+ CHECK_NOT_NULL (m = meta_data_create ());
+
+ /* all of these are absent */
+ OK(meta_data_get_string (m, "string", &s) != 0);
+ OK(meta_data_get_signed_int (m, "signed_int", &si) != 0);
+ OK(meta_data_get_unsigned_int (m, "unsigned_int", &ui) != 0);
+ OK(meta_data_get_double (m, "double", &d) != 0);
+ OK(meta_data_get_boolean (m, "boolean", &b) != 0);
+
+ /* populate structure */
+ CHECK_ZERO (meta_data_add_string (m, "string", "foobar"));
+ OK(meta_data_exists (m, "string"));
+ OK(meta_data_type (m, "string") == MD_TYPE_STRING);
+
+ CHECK_ZERO (meta_data_add_signed_int (m, "signed_int", -1));
+ OK(meta_data_exists (m, "signed_int"));
+ OK(meta_data_type (m, "signed_int") == MD_TYPE_SIGNED_INT);
+
+ CHECK_ZERO (meta_data_add_unsigned_int (m, "unsigned_int", 1));
+ OK(meta_data_exists (m, "unsigned_int"));
+ OK(meta_data_type (m, "unsigned_int") == MD_TYPE_UNSIGNED_INT);
+
+ CHECK_ZERO (meta_data_add_double (m, "double", 47.11));
+ OK(meta_data_exists (m, "double"));
+ OK(meta_data_type (m, "double") == MD_TYPE_DOUBLE);
+
+ CHECK_ZERO (meta_data_add_boolean (m, "boolean", 1));
+ OK(meta_data_exists (m, "boolean"));
+ OK(meta_data_type (m, "boolean") == MD_TYPE_BOOLEAN);
+
+ /* retrieve and check all values */
+ CHECK_ZERO (meta_data_get_string (m, "string", &s));
+ EXPECT_EQ_STR ("foobar", s);
+ sfree (s);
+
+ CHECK_ZERO (meta_data_get_signed_int (m, "signed_int", &si));
+ EXPECT_EQ_INT (-1, (int) si);
+
+ CHECK_ZERO (meta_data_get_unsigned_int (m, "unsigned_int", &ui));
+ EXPECT_EQ_INT (1, (int) ui);
+
+ CHECK_ZERO (meta_data_get_double (m, "double", &d));
+ EXPECT_EQ_DOUBLE (47.11, d);
+
+ CHECK_ZERO (meta_data_get_boolean (m, "boolean", &b));
+ OK1 (b, "b evaluates to true");
+
+ /* retrieving the wrong type always fails */
+ EXPECT_EQ_INT (-2, meta_data_get_boolean (m, "string", &b));
+ EXPECT_EQ_INT (-2, meta_data_get_string (m, "signed_int", &s));
+ EXPECT_EQ_INT (-2, meta_data_get_string (m, "unsigned_int", &s));
+ EXPECT_EQ_INT (-2, meta_data_get_string (m, "double", &s));
+ EXPECT_EQ_INT (-2, meta_data_get_string (m, "boolean", &s));
+
+ /* replace existing keys */
+ CHECK_ZERO (meta_data_add_signed_int (m, "string", 666));
+ OK(meta_data_type (m, "string") == MD_TYPE_SIGNED_INT);
+
+ CHECK_ZERO (meta_data_add_signed_int (m, "signed_int", 666));
+ CHECK_ZERO (meta_data_get_signed_int (m, "signed_int", &si));
+ EXPECT_EQ_INT (666, (int) si);
+
+ /* deleting keys */
+ CHECK_ZERO (meta_data_delete (m, "signed_int"));
+ EXPECT_EQ_INT (-2, meta_data_delete (m, "doesnt exist"));
+
+ meta_data_destroy (m);
+ return 0;
+}
+
+int main (void)
+{
+ RUN_TEST(base);
+
+ END_TEST;
+}
+
+/* vim: set sw=2 sts=2 et : */
write_queue_t *next;
};
+struct flush_callback_s {
+ char *name;
+ cdtime_t timeout;
+};
+typedef struct flush_callback_s flush_callback_t;
+
/*
* Private variables
*/
{
ERROR ("plugin: register_callback: "
"llentry_create failed.");
- free (key);
+ sfree (key);
destroy_callback (cf);
return (-1);
}
*str = '\0';
strjoin(str, len, keys, n, "', '");
INFO("%s ['%s']", comment, str);
- free(str);
+ sfree (str);
}
- free(keys);
+ sfree (keys);
} /* }}} void log_list_callbacks */
static int create_register_callback (llist_t **list, /* {{{ */
{
callback_func_t *cf;
- cf = (callback_func_t *) malloc (sizeof (*cf));
+ cf = calloc (1, sizeof (*cf));
if (cf == NULL)
{
- ERROR ("plugin: create_register_callback: malloc failed.");
+ ERROR ("plugin: create_register_callback: calloc failed.");
return (-1);
}
- memset (cf, 0, sizeof (*cf));
cf->cf_callback = callback;
if (ud == NULL)
{
read_func_t *rf;
plugin_ctx_t old_ctx;
+ cdtime_t start;
cdtime_t now;
+ cdtime_t elapsed;
int status;
int rf_type;
int rc;
DEBUG ("plugin_read_thread: Handling `%s'.", rf->rf_name);
+ start = cdtime ();
+
old_ctx = plugin_set_ctx (rf->rf_ctx);
if (rf_type == RF_SIMPLE)
/* update the ``next read due'' field */
now = cdtime ();
+ /* calculate the time spent in the read function */
+ elapsed = (now - start);
+
+ if (elapsed > rf->rf_effective_interval)
+ WARNING ("plugin_read_thread: read-function of the `%s' plugin took %.3f "
+ "seconds, which is above its read interval (%.3f seconds). You might "
+ "want to adjust the `Interval' or `ReadThreads' settings.",
+ rf->rf_name, CDTIME_T_TO_DOUBLE(elapsed),
+ CDTIME_T_TO_DOUBLE(rf->rf_effective_interval));
+
+ DEBUG ("plugin_read_thread: read-function of the `%s' plugin took "
+ "%.6f seconds.",
+ rf->rf_name, CDTIME_T_TO_DOUBLE(elapsed));
+
DEBUG ("plugin_read_thread: Effective interval of the "
- "%s plugin is %.3f seconds.",
+ "`%s' plugin is %.3f seconds.",
rf->rf_name,
CDTIME_T_TO_DOUBLE (rf->rf_effective_interval));
rf->rf_next_read = now;
}
- DEBUG ("plugin_read_thread: Next read of the %s plugin at %.3f.",
+ DEBUG ("plugin_read_thread: Next read of the `%s' plugin at %.3f.",
rf->rf_name,
CDTIME_T_TO_DOUBLE (rf->rf_next_read));
static void stop_write_threads (void) /* {{{ */
{
write_queue_t *q;
- int i;
+ size_t i;
if (write_threads == NULL)
return;
if (i > 0)
{
- WARNING ("plugin: %i value list%s left after shutting down "
+ WARNING ("plugin: %zu value list%s left after shutting down "
"the write threads.",
i, (i == 1) ? " was" : "s were");
}
*/
void plugin_set_dir (const char *dir)
{
- if (plugindir != NULL)
- free (plugindir);
+ sfree (plugindir);
if (dir == NULL)
- plugindir = NULL;
- else if ((plugindir = strdup (dir)) == NULL)
{
- char errbuf[1024];
- ERROR ("strdup failed: %s",
- sstrerror (errno, errbuf, sizeof (errbuf)));
+ plugindir = NULL;
+ return;
}
+
+ plugindir = strdup (dir);
+ if (plugindir == NULL)
+ ERROR ("plugin_set_dir: strdup(\"%s\") failed", dir);
}
static _Bool plugin_is_loaded (char const *name)
/* success */
plugin_mark_loaded (plugin_name);
ret = 0;
+ INFO ("plugin_load: plugin \"%s\" successfully loaded.", plugin_name);
break;
}
else
read_func_t *rf;
int status;
- rf = malloc (sizeof (*rf));
+ rf = calloc (1, sizeof (*rf));
if (rf == NULL)
{
- ERROR ("plugin_register_read: malloc failed.");
+ ERROR ("plugin_register_read: calloc failed.");
return (ENOMEM);
}
- memset (rf, 0, sizeof (read_func_t));
rf->rf_callback = (void *) callback;
rf->rf_udata.data = NULL;
rf->rf_udata.free_func = NULL;
int plugin_register_complex_read (const char *group, const char *name,
plugin_read_cb callback,
- const struct timespec *interval,
+ cdtime_t interval,
user_data_t *user_data)
{
read_func_t *rf;
int status;
- rf = malloc (sizeof (*rf));
+ rf = calloc (1,sizeof (*rf));
if (rf == NULL)
{
- ERROR ("plugin_register_complex_read: malloc failed.");
+ ERROR ("plugin_register_complex_read: calloc failed.");
return (ENOMEM);
}
- memset (rf, 0, sizeof (read_func_t));
rf->rf_callback = (void *) callback;
if (group != NULL)
sstrncpy (rf->rf_group, group, sizeof (rf->rf_group));
rf->rf_group[0] = '\0';
rf->rf_name = strdup (name);
rf->rf_type = RF_COMPLEX;
- if (interval != NULL)
- rf->rf_interval = TIMESPEC_TO_CDTIME_T (interval);
- else
- rf->rf_interval = plugin_get_interval ();
+ rf->rf_interval = (interval != 0) ? interval : plugin_get_interval ();
/* Set user data */
if (user_data == NULL)
(void *) callback, ud));
} /* int plugin_register_write */
+static int plugin_flush_timeout_callback (user_data_t *ud)
+{
+ flush_callback_t *cb = ud->data;
+
+ return plugin_flush (cb->name, cb->timeout, /* identifier = */ NULL);
+} /* static int plugin_flush_callback */
+
+static void plugin_flush_timeout_callback_free (void *data)
+{
+ flush_callback_t *cb = data;
+
+ if (cb == NULL) return;
+
+ sfree (cb->name);
+ sfree (cb);
+} /* static void plugin_flush_callback_free */
+
+static char *plugin_flush_callback_name (const char *name)
+{
+ const char *flush_prefix = "flush/";
+ size_t prefix_size;
+ char *flush_name;
+ size_t name_size;
+
+ prefix_size = strlen(flush_prefix);
+ name_size = strlen(name);
+
+ flush_name = malloc (name_size + prefix_size + 1);
+ if (flush_name == NULL)
+ {
+ ERROR ("plugin_flush_callback_name: malloc failed.");
+ return (NULL);
+ }
+
+ sstrncpy (flush_name, flush_prefix, prefix_size + 1);
+ sstrncpy (flush_name + prefix_size, name, name_size + 1);
+
+ return flush_name;
+} /* static char *plugin_flush_callback_name */
+
int plugin_register_flush (const char *name,
plugin_flush_cb callback, user_data_t *ud)
{
- return (create_register_callback (&list_flush, name,
- (void *) callback, ud));
+ int status;
+ plugin_ctx_t ctx = plugin_get_ctx ();
+
+ status = create_register_callback (&list_flush, name,
+ (void *) callback, ud);
+ if (status != 0)
+ return status;
+
+ if (ctx.flush_interval != 0)
+ {
+ char *flush_name;
+ flush_callback_t *cb;
+
+ flush_name = plugin_flush_callback_name (name);
+ if (flush_name == NULL)
+ return (-1);
+
+ cb = malloc(sizeof (*cb));
+ if (cb == NULL)
+ {
+ ERROR ("plugin_register_flush: malloc failed.");
+ sfree (flush_name);
+ return (-1);
+ }
+
+ cb->name = strdup (name);
+ if (cb->name == NULL)
+ {
+ ERROR ("plugin_register_flush: strdup failed.");
+ sfree (cb);
+ sfree (flush_name);
+ return (-1);
+ }
+ cb->timeout = ctx.flush_timeout;
+
+ ud->data = cb;
+ ud->free_func = plugin_flush_timeout_callback_free;
+
+ status = plugin_register_complex_read (
+ /* group = */ "flush",
+ /* name = */ flush_name,
+ /* callback = */ plugin_flush_timeout_callback,
+ /* interval = */ ctx.flush_interval,
+ /* user data = */ ud);
+
+ sfree (flush_name);
+ if (status != 0)
+ {
+ sfree (cb->name);
+ sfree (cb);
+ return status;
+ }
+ }
+
+ return 0;
} /* int plugin_register_flush */
int plugin_register_missing (const char *name,
int plugin_register_data_set (const data_set_t *ds)
{
data_set_t *ds_copy;
- int i;
+ size_t i;
if ((data_sets != NULL)
&& (c_avl_get (data_sets, ds->type, NULL) == 0))
return (-1);
}
- ds_copy = (data_set_t *) malloc (sizeof (data_set_t));
+ ds_copy = malloc (sizeof (*ds_copy));
if (ds_copy == NULL)
return (-1);
memcpy(ds_copy, ds, sizeof (data_set_t));
- ds_copy->ds = (data_source_t *) malloc (sizeof (data_source_t)
+ ds_copy->ds = malloc (sizeof (*ds_copy->ds)
* ds->ds_num);
if (ds_copy->ds == NULL)
{
- free (ds_copy);
+ sfree (ds_copy);
return (-1);
}
int plugin_unregister_flush (const char *name)
{
- return (plugin_unregister (list_flush, name));
+ plugin_ctx_t ctx = plugin_get_ctx ();
+
+ if (ctx.flush_interval != 0)
+ {
+ char *flush_name;
+
+ flush_name = plugin_flush_callback_name (name);
+ if (flush_name != NULL)
+ {
+ plugin_unregister_read(flush_name);
+ sfree (flush_name);
+ }
+ }
+
+ return plugin_unregister (list_flush, name);
}
int plugin_unregister_missing (const char *name)
return (plugin_unregister (list_notification, name));
}
-void plugin_init_all (void)
+int plugin_init_all (void)
{
char const *chain_name;
llentry_t *le;
int status;
+ int ret = 0;
/* Init the value cache */
uc_init ();
}
if ((list_init == NULL) && (read_heap == NULL))
- return;
+ return ret;
/* Calling all init callbacks before checking if read callbacks
* are available allows the init callbacks to register the read
* handling themselves. */
/* FIXME: Unload _all_ functions */
plugin_unregister_read (le->key);
+ ret = -1;
}
le = le->next;
if (num != -1)
start_read_threads ((num > 0) ? num : 5);
}
+ return ret;
} /* void plugin_init_all */
/* TODO: Rename this function. */
return (0);
} /* int plugin_flush */
-void plugin_shutdown_all (void)
+int plugin_shutdown_all (void)
{
llentry_t *le;
+ int ret = 0; // Assume success.
stop_read_threads ();
* after callback returns. */
le = le->next;
- (*callback) ();
+ if ((*callback) () != 0)
+ ret = -1;
plugin_set_ctx (old_ctx);
}
plugin_free_loaded ();
plugin_free_data_sets ();
+ return (ret);
} /* void plugin_shutdown_all */
int plugin_dispatch_missing (const value_list_t *vl) /* {{{ */
int free_meta_data = 0;
- if ((vl == NULL) || (vl->type[0] == 0)
- || (vl->values == NULL) || (vl->values_len < 1))
+ assert(vl);
+ assert(vl->plugin);
+
+ if (vl->type[0] == 0 || vl->values == NULL || vl->values_len < 1)
{
ERROR ("plugin_dispatch_values: Invalid value list "
"from plugin %s.", vl->plugin);
if (ds->ds_num != vl->values_len)
{
ERROR ("plugin_dispatch_values: ds->type = %s: "
- "(ds->ds_num = %i) != "
- "(vl->values_len = %i)",
+ "(ds->ds_num = %zu) != "
+ "(vl->values_len = %zu)",
ds->type, ds->ds_num, vl->values_len);
return (-1);
}
* don't get confused.. */
if (saved_values != NULL)
{
- free (vl->values);
+ sfree (vl->values);
vl->values = saved_values;
vl->values_len = saved_values_len;
}
* confused.. */
if (saved_values != NULL)
{
- free (vl->values);
+ sfree (vl->values);
vl->values = saved_values;
vl->values_len = saved_values_len;
}
assert (template->values_len == 1);
- /* Calculate sum for Gauge to calculate percent if needed */
+ /* Calculate sum for Gauge to calculate percent if needed */
if (DS_TYPE_GAUGE == store_type) {
va_start (ap, store_type);
while (42)
return (-1);
}
- meta = (notification_meta_t *) malloc (sizeof (notification_meta_t));
+ meta = calloc (1, sizeof (*meta));
if (meta == NULL)
{
- ERROR ("plugin_notification_meta_add: malloc failed.");
+ ERROR ("plugin_notification_meta_add: calloc failed.");
return (-1);
}
- memset (meta, 0, sizeof (notification_meta_t));
sstrncpy (meta->name, name, sizeof (meta->name));
meta->type = type;
if (this->type == NM_TYPE_STRING)
{
- free ((char *)this->nm_value.nm_string);
+ /* Assign to a temporary variable to work around nm_string's const
+ * modifier. */
+ void *tmp = (void *) this->nm_value.nm_string;
+
+ sfree (tmp);
this->nm_value.nm_string = NULL;
}
sfree (this);
plugin_set_ctx (plugin_thread->ctx);
- free (plugin_thread);
+ sfree (plugin_thread);
return start_routine (plugin_arg);
} /* void *plugin_thread_start */
/**
- * collectd - src/plugin.h
+ * collectd - src/daemon/plugin.h
* Copyright (C) 2005-2014 Florian octo Forster
*
* Permission is hereby granted, free of charge, to any person obtaining a
#define PLUGIN_FLAGS_GLOBAL 0x0001
-#define DATA_MAX_NAME_LEN 64
+#ifndef DATA_MAX_NAME_LEN
+# define DATA_MAX_NAME_LEN 64
+#endif
#define DS_TYPE_COUNTER 0
#define DS_TYPE_GAUGE 1
struct value_list_s
{
value_t *values;
- int values_len;
+ size_t values_len;
cdtime_t time;
cdtime_t interval;
char host[DATA_MAX_NAME_LEN];
struct data_set_s
{
char type[DATA_MAX_NAME_LEN];
- int ds_num;
+ size_t ds_num;
data_source_t *ds;
};
typedef struct data_set_s data_set_t;
struct plugin_ctx_s
{
cdtime_t interval;
+ cdtime_t flush_interval;
+ cdtime_t flush_timeout;
};
typedef struct plugin_ctx_s plugin_ctx_t;
*/
int plugin_load (const char *name, uint32_t flags);
-void plugin_init_all (void);
+int plugin_init_all (void);
void plugin_read_all (void);
int plugin_read_all_once (void);
-void plugin_shutdown_all (void);
+int plugin_shutdown_all (void);
/*
* NAME
* "plugin_register_complex_read" returns an error (non-zero). */
int plugin_register_complex_read (const char *group, const char *name,
plugin_read_cb callback,
- const struct timespec *interval,
+ cdtime_t interval,
user_data_t *user_data);
int plugin_register_write (const char *name,
plugin_write_cb callback, user_data_t *user_data);
char *fields[64];
size_t fields_num;
data_set_t *ds;
- int i;
+ size_t i;
fields_num = strsplit (buf, fields, 64);
if (fields_num < 2)
if (fields[0][0] == '#')
return;
- ds = (data_set_t *) malloc (sizeof (data_set_t));
+ ds = calloc (1, sizeof (*ds));
if (ds == NULL)
return;
- memset (ds, '\0', sizeof (data_set_t));
-
sstrncpy (ds->type, fields[0], sizeof (ds->type));
ds->ds_num = fields_num - 1;
ds->ds = (data_source_t *) calloc (ds->ds_num, sizeof (data_source_t));
if (ds->ds == NULL)
+ {
+ sfree (ds);
return;
+ }
for (i = 0; i < ds->ds_num; i++)
if (parse_ds (ds->ds + i, fields[i + 1], strlen (fields[i + 1])) != 0)
{
- sfree (ds->ds);
- ERROR ("types_list: parse_line: Cannot parse data source #%i "
+ ERROR ("types_list: parse_line: Cannot parse data source #%zu "
"of data set %s", i, ds->type);
+ sfree (ds->ds);
+ sfree (ds);
return;
}
if (compare == NULL)
return (NULL);
- if ((t = (c_avl_tree_t *) malloc (sizeof (c_avl_tree_t))) == NULL)
+ if ((t = malloc (sizeof (*t))) == NULL)
return (NULL);
t->root = NULL;
c_avl_node_t *nptr;
int cmp;
- if ((new = (c_avl_node_t *) malloc (sizeof (c_avl_node_t))) == NULL)
+ if ((new = malloc (sizeof (*new))) == NULL)
return (-1);
new->key = key;
if (t == NULL)
return (NULL);
- iter = (c_avl_iterator_t *) malloc (sizeof (c_avl_iterator_t));
+ iter = calloc (1, sizeof (*iter));
if (iter == NULL)
return (NULL);
- memset (iter, '\0', sizeof (c_avl_iterator_t));
iter->tree = t;
return (iter);
* Florian octo Forster <octo at collectd.org>
*/
-#include "testing.h"
+#include "common.h" /* STATIC_ARRAY_SIZE */
#include "collectd.h"
+#include "testing.h"
#include "utils_avltree.h"
static int compare_total_count = 0;
DEF_TEST(success)
{
+ struct {
+ char *key;
+ char *value;
+ } cases[] = {
+ {"Eeph7chu", "vai1reiV"},
+ {"igh3Paiz", "teegh1Ee"},
+ {"caip6Uu8", "ooteQu8n"},
+ {"Aech6vah", "AijeeT0l"},
+ {"Xah0et2L", "gah8Taep"},
+ {"BocaeB8n", "oGaig8io"},
+ {"thai8AhM", "ohjeFo3f"},
+ {"ohth6ieC", "hoo8ieWo"},
+ {"aej7Woow", "phahuC2s"},
+ {"Hai8ier2", "Yie6eimi"},
+ {"phuXi3Li", "JaiF7ieb"},
+ {"Shaig5ef", "aihi5Zai"},
+ {"voh6Aith", "Oozaeto0"},
+ {"zaiP5kie", "seep5veM"},
+ {"pae7ba7D", "chie8Ojo"},
+ {"Gou2ril3", "ouVoo0ha"},
+ {"lo3Thee3", "ahDu4Zuj"},
+ {"Rah8kohv", "ieShoc7E"},
+ {"ieN5engi", "Aevou1ah"},
+ {"ooTe4OhP", "aingai5Y"},
+ };
+
c_avl_tree_t *t;
- char key_orig[] = "foo";
- char value_orig[] = "bar";
- char *key_ret = NULL;
- char *value_ret = NULL;
+ size_t i;
RESET_COUNTS ();
- t = c_avl_create (compare_callback);
- OK (t != NULL);
+ CHECK_NOT_NULL (t = c_avl_create (compare_callback));
+
+ /* insert */
+ for (i = 0; i < STATIC_ARRAY_SIZE (cases); i++)
+ {
+ char *key;
+ char *value;
- OK (c_avl_insert (t, key_orig, value_orig) == 0);
- OK (c_avl_size (t) == 1);
+ CHECK_NOT_NULL (key = strdup (cases[i].key));
+ CHECK_NOT_NULL (value = strdup (cases[i].value));
+
+ CHECK_ZERO (c_avl_insert (t, key, value));
+ EXPECT_EQ_INT ((int) (i + 1), c_avl_size (t));
+ }
/* Key already exists. */
- OK (c_avl_insert (t, "foo", "qux") > 0);
+ for (i = 0; i < STATIC_ARRAY_SIZE (cases); i++)
+ EXPECT_EQ_INT (1, c_avl_insert (t, cases[i].key, cases[i].value));
+
+ /* get */
+ for (i = 0; i < STATIC_ARRAY_SIZE (cases); i++)
+ {
+ char *value_ret = NULL;
+
+ CHECK_ZERO (c_avl_get (t, cases[i].key, (void *) &value_ret));
+ EXPECT_EQ_STR (cases[i].value, value_ret);
+ }
+
+ /* remove half */
+ for (i = 0; i < STATIC_ARRAY_SIZE (cases) / 2; i++)
+ {
+ char *key = NULL;
+ char *value = NULL;
+
+ int expected_size = (int) (STATIC_ARRAY_SIZE (cases) - (i + 1));
+
+ CHECK_ZERO (c_avl_remove (t, cases[i].key, (void *) &key, (void *) &value));
+
+ EXPECT_EQ_STR (cases[i].key, key);
+ EXPECT_EQ_STR (cases[i].value, value);
+
+ free (key);
+ free (value);
+
+ EXPECT_EQ_INT (expected_size, c_avl_size (t));
+ }
+
+ /* pick the other half */
+ for (i = STATIC_ARRAY_SIZE (cases) / 2; i < STATIC_ARRAY_SIZE (cases); i++)
+ {
+ char *key = NULL;
+ char *value = NULL;
+
+ int expected_size = (int) (STATIC_ARRAY_SIZE (cases) - (i + 1));
+
+ EXPECT_EQ_INT (expected_size + 1, c_avl_size (t));
+ EXPECT_EQ_INT (0, c_avl_pick (t, (void *) &key, (void *) &value));
- OK (c_avl_get (t, "foo", (void *) &value_ret) == 0);
- OK (value_ret == &value_orig[0]);
+ free (key);
+ free (value);
- key_ret = value_ret = NULL;
- OK (c_avl_remove (t, "foo", (void *) &key_ret, (void *) &value_ret) == 0);
- OK (key_ret == &key_orig[0]);
- OK (value_ret == &value_orig[0]);
- OK (c_avl_size (t) == 0);
+ EXPECT_EQ_INT (expected_size, c_avl_size (t));
+ }
c_avl_destroy (t);
typedef struct cache_entry_s
{
char name[6 * DATA_MAX_NAME_LEN];
- int values_num;
+ size_t values_num;
gauge_t *values_gauge;
value_t *values_raw;
/* Time contained in the package
return (strcmp (a->name, b->name));
} /* int cache_compare */
-static cache_entry_t *cache_alloc (int values_num)
+static cache_entry_t *cache_alloc (size_t values_num)
{
cache_entry_t *ce;
- ce = (cache_entry_t *) malloc (sizeof (cache_entry_t));
+ ce = calloc (1, sizeof (*ce));
if (ce == NULL)
{
- ERROR ("utils_cache: cache_alloc: malloc failed.");
+ ERROR ("utils_cache: cache_alloc: calloc failed.");
return (NULL);
}
- memset (ce, '\0', sizeof (cache_entry_t));
ce->values_num = values_num;
ce->values_gauge = calloc (values_num, sizeof (*ce->values_gauge));
static void uc_check_range (const data_set_t *ds, cache_entry_t *ce)
{
- int i;
+ size_t i;
for (i = 0; i < ds->ds_num; i++)
{
static int uc_insert (const data_set_t *ds, const value_list_t *vl,
const char *key)
{
- int i;
char *key_copy;
cache_entry_t *ce;
+ size_t i;
/* `cache_lock' has been locked by `uc_update' */
if (ce == NULL)
{
sfree (key_copy);
- ERROR ("uc_insert: cache_alloc (%i) failed.", ds->ds_num);
+ ERROR ("uc_insert: cache_alloc (%zu) failed.", ds->ds_num);
return (-1);
}
int status;
int i;
-
+
pthread_mutex_lock (&cache_lock);
now = cdtime ();
continue;
/* If entry has not been updated, add to `keys' array */
- tmp = (char **) realloc ((void *) keys,
+ tmp = realloc ((void *) keys,
(keys_len + 1) * sizeof (char *));
if (tmp == NULL)
{
char name[6 * DATA_MAX_NAME_LEN];
cache_entry_t *ce = NULL;
int status;
- int i;
+ size_t i;
if (FORMAT_VL (name, sizeof (name), vl) != 0)
{
{
case DS_TYPE_COUNTER:
{
- counter_t diff;
-
- /* check if the counter has wrapped around */
- if (vl->values[i].counter < ce->values_raw[i].counter)
- {
- if (ce->values_raw[i].counter <= 4294967295U)
- diff = (4294967295U - ce->values_raw[i].counter)
- + vl->values[i].counter;
- else
- diff = (18446744073709551615ULL - ce->values_raw[i].counter)
- + vl->values[i].counter;
- }
- else /* counter has NOT wrapped around */
- {
- diff = vl->values[i].counter - ce->values_raw[i].counter;
- }
-
+ counter_t diff = counter_diff (ce->values_raw[i].counter, vl->values[i].counter);
ce->values_gauge[i] = ((double) diff)
/ (CDTIME_T_TO_DOUBLE (vl->time - ce->last_time));
ce->values_raw[i].counter = vl->values[i].counter;
case DS_TYPE_DERIVE:
{
- derive_t diff;
-
- diff = vl->values[i].derive - ce->values_raw[i].derive;
+ derive_t diff = vl->values[i].derive - ce->values_raw[i].derive;
ce->values_gauge[i] = ((double) diff)
/ (CDTIME_T_TO_DOUBLE (vl->time - ce->last_time));
return (-1);
} /* switch (ds->ds[i].type) */
- DEBUG ("uc_update: %s: ds[%i] = %lf", name, i, ce->values_gauge[i]);
+ DEBUG ("uc_update: %s: ds[%zu] = %lf", name, i, ce->values_gauge[i]);
} /* for (i) */
/* Update the history if it exists. */
else
{
ret_num = ce->values_num;
- ret = (gauge_t *) malloc (ret_num * sizeof (gauge_t));
+ ret = malloc (ret_num * sizeof (*ret));
if (ret == NULL)
{
ERROR ("utils_cache: uc_get_rate_by_name: malloc failed.");
* values are returned. */
if (ret_num != (size_t) ds->ds_num)
{
- ERROR ("utils_cache: uc_get_rate: ds[%s] has %i values, "
+ ERROR ("utils_cache: uc_get_rate: ds[%s] has %zu values, "
"but uc_get_rate_by_name returned %zu.",
ds->type, ds->ds_num, ret_num);
sfree (ret);
#include "utils_cache.h"
-gauge_t *uc_get_rate (const data_set_t *ds, const value_list_t *vl)
+gauge_t *uc_get_rate (__attribute((unused)) data_set_t const *ds,
+ __attribute((unused)) value_list_t const *vl)
{
return (NULL);
}
} /* c_release */
/* vim: set sw=4 ts=4 tw=78 noexpandtab : */
-
* `c' Identifier for the complaint.
* `format' Message format - see the documentation of printf(3).
*/
+__attribute__ ((format(printf,3,4)))
void c_complain (int level, c_complain_t *c, const char *format, ...);
/*
*
* See `c_complain' for further details and a description of the parameters.
*/
+__attribute__ ((format(printf,3,4)))
void c_complain_once (int level, c_complain_t *c, const char *format, ...);
/*
*
* See `c_complain' for a description of the parameters.
*/
+__attribute__ ((format(printf,3,4)))
void c_do_release (int level, c_complain_t *c, const char *format, ...);
#define c_release(level, c, ...) \
do { \
if (compare == NULL)
return (NULL);
- h = malloc (sizeof (*h));
+ h = calloc (1, sizeof (*h));
if (h == NULL)
return (NULL);
- memset (h, 0, sizeof (*h));
pthread_mutex_init (&h->lock, /* attr = */ NULL);
h->compare = compare;
-
+
h->list = NULL;
h->list_len = 0;
h->list_size = 0;
/* Reorganize the heap from bottom up. */
reheap (h, /* parent of this node = */ (index - 1) / 2, DIR_UP);
-
+
pthread_mutex_unlock (&h->lock);
return (0);
} /* int c_heap_insert */
* Florian octo Forster <octo at collectd.org>
*/
-#include "testing.h"
#include "collectd.h"
+#include "testing.h"
#include "utils_heap.h"
static int compare (void const *v0, void const *v1)
**/
/**
* Usage:
- *
+ *
* Define plugin's global pointer variable of type ignorelist_t:
* ignorelist_t *myconfig_ignore;
* If you know the state of the global ignore (IgnoreSelected),
}
#if HAVE_REGEX_H
-static int ignorelist_append_regex(ignorelist_t *il, const char *entry)
+static int ignorelist_append_regex(ignorelist_t *il, const char *re_str)
{
regex_t *re;
- ignorelist_item_t *item;
+ ignorelist_item_t *entry;
int status;
- /* create buffer */
- re = malloc (sizeof (*re));
+ re = calloc (1, sizeof (*re));
if (re == NULL)
{
- ERROR ("ignorelist_append_regex: malloc failed.");
- return ENOMEM;
+ ERROR ("ignorelist_append_regex: calloc failed.");
+ return (ENOMEM);
}
- memset (re, 0, sizeof (*re));
- /* compile regex */
- status = regcomp (re, entry, REG_EXTENDED);
+ status = regcomp (re, re_str, REG_EXTENDED);
if (status != 0)
{
char errbuf[1024];
-
(void) regerror (status, re, errbuf, sizeof (errbuf));
- ERROR ("ignorelist_append_regex: Compiling regular expression \"%s\" failed: %s", entry, errbuf);
+ ERROR ("utils_ignorelist: regcomp failed: %s", errbuf);
+ ERROR ("ignorelist_append_regex: Compiling regular expression \"%s\" failed: %s", re_str, errbuf);
sfree (re);
- return status;
+ return (status);
}
- /* create new entry */
- item = malloc (sizeof (*item));
- if (item == NULL)
+ entry = calloc (1, sizeof (*entry));
+ if (entry == NULL)
{
- ERROR ("ignorelist_append_regex: malloc failed.");
+ ERROR ("ignorelist_append_regex: calloc failed.");
regfree (re);
sfree (re);
- return ENOMEM;
+ return (ENOMEM);
}
- memset (item, 0, sizeof (*item));
- item->rmatch = re;
-
- /* append new entry */
- ignorelist_append (il, item);
+ entry->rmatch = re;
+ ignorelist_append (il, entry);
return (0);
-} /* int ignorelist_append_regex(ignorelist_t *il, const char *entry) */
+} /* int ignorelist_append_regex */
#endif
static int ignorelist_append_string(ignorelist_t *il, const char *entry)
ignorelist_item_t *new;
/* create new entry */
- if ((new = malloc(sizeof(ignorelist_item_t))) == NULL )
+ if ((new = calloc(1, sizeof (*new))) == NULL )
{
ERROR ("cannot allocate new entry");
return (1);
}
- memset (new, '\0', sizeof(ignorelist_item_t));
new->smatch = sstrdup(entry);
/* append new entry */
{
ignorelist_t *il;
- il = malloc (sizeof (*il));
+ il = calloc (1, sizeof (*il));
if (il == NULL)
return NULL;
- memset (il, 0, sizeof (*il));
/*
* ->ignore == 0 => collect
}
sfree (il);
- il = NULL;
} /* void ignorelist_destroy (ignorelist_t *il) */
/*
/*
* append entry into ignorelist_t
- * return 1 for success
+ * return 0 for success
*/
int ignorelist_add (ignorelist_t *il, const char *entry)
{
{
llist_t *ret;
- ret = (llist_t *) malloc (sizeof (llist_t));
+ ret = calloc (1, sizeof (*ret));
if (ret == NULL)
return (NULL);
- memset (ret, '\0', sizeof (llist_t));
-
return (ret);
}
{
llentry_t *e;
- e = (llentry_t *) malloc (sizeof (llentry_t));
+ e = malloc (sizeof (*e));
if (e)
{
e->key = key;
}
ret_len = end - begin;
- ret = (char *) malloc (sizeof (char) * (ret_len + 1));
+ ret = malloc (ret_len + 1);
if (ret == NULL)
{
ERROR ("utils_match: match_substr: malloc failed.");
DEBUG ("utils_match: match_create_callback: regex = %s, excluderegex = %s",
regex, excluderegex);
- obj = (cu_match_t *) malloc (sizeof (cu_match_t));
+ obj = calloc (1, sizeof (*obj));
if (obj == NULL)
return (NULL);
- memset (obj, '\0', sizeof (cu_match_t));
status = regcomp (&obj->regex, regex, REG_EXTENDED | REG_NEWLINE);
if (status != 0)
cu_match_value_t *user_data;
cu_match_t *obj;
- user_data = (cu_match_value_t *) malloc (sizeof (cu_match_value_t));
+ user_data = calloc (1, sizeof (*user_data));
if (user_data == NULL)
return (NULL);
- memset (user_data, '\0', sizeof (cu_match_value_t));
user_data->ds_type = match_ds_type;
obj = match_create_callback (regex, excluderegex,
#include "common.h"
#include "utils_subst.h"
-char *subst (char *buf, size_t buflen, const char *string, int off1, int off2,
+char *subst (char *buf, size_t buflen, const char *string, size_t off1, size_t off2,
const char *replacement)
{
- char *buf_ptr = buf;
- size_t len = buflen;
+ char *out = buf;
- if ((NULL == buf) || (0 >= buflen) || (NULL == string)
- || (0 > off1) || (0 > off2) || (off1 > off2)
- || (NULL == replacement))
+ char const *front;
+ char const *back;
+ size_t front_len;
+ size_t replacement_len;
+ size_t back_len;
+
+ if ((NULL == buf) || (0 == buflen) || (NULL == string) || (NULL == replacement))
return NULL;
- sstrncpy (buf_ptr, string,
- ((size_t)off1 + 1 > buflen) ? buflen : (size_t)off1 + 1);
- buf_ptr += off1;
- len -= off1;
+ size_t string_len = strlen (string);
+ if ((off1 > string_len) || (off2 > string_len) || (off1 > off2))
+ return NULL;
- if (0 >= len)
- return buf;
+ front = string;
+ back = string + off2;
+ front_len = off1;
+ replacement_len = strlen (replacement);
+ back_len = strlen (back);
+
+ if (front_len >= buflen) {
+ front_len = buflen - 1;
+ replacement_len = 0;
+ back_len = 0;
+ } else if ((front_len + replacement_len) >= buflen) {
+ replacement_len = buflen - (front_len + 1);
+ back_len = 0;
+ } else if ((front_len + replacement_len + back_len) >= buflen) {
+ back_len = buflen - (front_len + replacement_len + 1);
+ } else {
+ buflen = front_len + replacement_len + back_len + 1;
+ }
+ assert ((front_len + replacement_len + back_len) == (buflen - 1));
- sstrncpy (buf_ptr, replacement, len);
- buf_ptr += strlen (replacement);
- len -= strlen (replacement);
+ if (front_len != 0) {
+ sstrncpy (out, front, front_len + 1);
+ out += front_len;
+ }
- if (0 >= len)
- return buf;
+ if (replacement_len != 0) {
+ sstrncpy (out, replacement, replacement_len + 1);
+ out += replacement_len;
+ }
- sstrncpy (buf_ptr, string + off2, len);
+ if (back_len != 0) {
+ sstrncpy (out, back, back_len + 1);
+ out += back_len;
+ }
+
+ out[0] = 0;
return buf;
} /* subst */
len = off1 + strlen (replacement) + strlen (string) - off2 + 1;
- buf = (char *)malloc (len);
+ buf = malloc (len);
if (NULL == buf)
return NULL;
char *subst_string (char *buf, size_t buflen, const char *string,
const char *needle, const char *replacement)
{
- char *temp;
size_t needle_len;
size_t i;
|| (needle == NULL) || (replacement == NULL))
return (NULL);
- temp = (char *) malloc (buflen);
- if (temp == NULL)
- {
- ERROR ("subst_string: malloc failed.");
- return (NULL);
- }
-
needle_len = strlen (needle);
- strncpy (buf, string, buflen);
+ sstrncpy (buf, string, buflen);
/* Limit the loop to prevent endless loops. */
for (i = 0; i < buflen; i++)
{
+ char temp[buflen];
char *begin_ptr;
size_t begin;
i, string, needle, replacement);
}
- sfree (temp);
return (buf);
} /* char *subst_string */
*
* The function returns 'buf' on success, NULL else.
*/
-char *subst (char *buf, size_t buflen, const char *string, int off1, int off2,
+char *subst (char *buf, size_t buflen, const char *string, size_t off1, size_t off2,
const char *replacement);
/*
--- /dev/null
+/**
+ * collectd - src/daemon/utils_subst_test.c
+ * Copyright (C) 2015 Florian octo Forster
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ * Florian octo Forster <octo at collectd.org>
+ */
+
+#include "common.h" /* for STATIC_ARRAY_SIZE */
+#include "collectd.h"
+#include "testing.h"
+#include "utils_subst.h"
+
+#if HAVE_LIBKSTAT
+kstat_ctl_t *kc;
+#endif /* HAVE_LIBKSTAT */
+
+DEF_TEST(subst)
+{
+ struct {
+ const char *str;
+ int off1;
+ int off2;
+ const char *rplmt;
+ const char *want;
+ } cases[] = {
+ {"foo_____bar", 3, 8, " - ", "foo - bar"}, /* documentation example */
+ {"foo bar", 0, 2, "m", "mo bar"}, /* beginning, shorten */
+ {"foo bar", 0, 1, "m", "moo bar"}, /* beginning, same length */
+ {"foo bar", 0, 3, "milk", "milk bar"}, /* beginning, extend */
+ {"foo bar", 3, 6, "de", "fooder"}, /* center, shorten */
+ {"foo bar", 2, 6, "rste", "forster"}, /* center, same length */
+ {"foo bar", 1, 3, "ish", "fish bar"}, /* center, extend */
+ {"foo bar", 2, 7, "ul", "foul"}, /* end, shorten */
+ {"foo bar", 3, 7, "lish", "foolish"}, /* end, same length */
+ {"foo bar", 3, 7, "dwear", "foodwear"}, /* end, extend */
+ /* truncation (buffer is 16 chars) */
+ {"01234567890123", 8, 8, "", "01234567890123"},
+ {"01234567890123", 8, 8, "*", "01234567*890123"},
+ {"01234567890123", 8, 8, "**", "01234567**89012"},
+ /* input > buffer */
+ {"012345678901234----", 0, 0, "", "012345678901234"},
+ {"012345678901234----", 17, 18, "", "012345678901234"},
+ {"012345678901234----", 0, 3, "", "345678901234---"},
+ {"012345678901234----", 0, 4, "", "45678901234----"},
+ {"012345678901234----", 0, 5, "", "5678901234----"},
+ {"012345678901234----", 8, 8, "#", "01234567#890123"},
+ {"012345678901234----", 12, 12, "##", "012345678901##2"},
+ {"012345678901234----", 13, 13, "##", "0123456789012##"},
+ {"012345678901234----", 14, 14, "##", "01234567890123#"},
+ {"012345678901234----", 15, 15, "##", "012345678901234"},
+ {"012345678901234----", 16, 16, "##", "012345678901234"},
+ /* error cases */
+ {NULL, 3, 4, "_", NULL}, /* no input */
+ {"foo bar", 3, 10, "_", NULL}, /* offset exceeds input */
+ {"foo bar", 10, 13, "_", NULL}, /* offset exceeds input */
+ {"foo bar", 4, 3, "_", NULL}, /* off1 > off2 */
+ {"foo bar", 3, 4, NULL, NULL}, /* no replacement */
+ };
+ size_t i;
+
+ for (i = 0; i < STATIC_ARRAY_SIZE (cases); i++) {
+ char buffer[16] = "!!!!!!!!!!!!!!!";
+
+ if (cases[i].want == NULL) {
+ OK(subst (buffer, sizeof (buffer), cases[i].str, cases[i].off1, cases[i].off2, cases[i].rplmt) == NULL);
+ continue;
+ }
+
+ OK(subst (buffer, sizeof (buffer), cases[i].str, cases[i].off1, cases[i].off2, cases[i].rplmt) == &buffer[0]);
+ EXPECT_EQ_STR(cases[i].want, buffer);
+ }
+
+ return 0;
+}
+
+DEF_TEST(subst_string)
+{
+ struct {
+ const char *str;
+ const char *srch;
+ const char *rplmt;
+ const char *want;
+ } cases[] = {
+ {"Hello %{name}", "%{name}", "world", "Hello world"},
+ {"abcccccc", "abc", "cab", "ccccccab"},
+ {"(((()(())))())", "()", "", ""},
+ {"food booth", "oo", "ee", "feed beeth"},
+ {"foo bar", "baz", "qux", "foo bar"},
+ {"foo bar", "oo", "oo", "foo bar"},
+ {"sixteen chars", "chars", "characters", "sixteen charact"},
+ };
+ size_t i;
+
+ for (i = 0; i < STATIC_ARRAY_SIZE (cases); i++) {
+ char buffer[16];
+
+ if (cases[i].want == NULL) {
+ OK(subst_string (buffer, sizeof (buffer), cases[i].str, cases[i].srch, cases[i].rplmt) == NULL);
+ continue;
+ }
+
+ OK(subst_string (buffer, sizeof (buffer), cases[i].str, cases[i].srch, cases[i].rplmt) == buffer);
+ EXPECT_EQ_STR(cases[i].want, buffer);
+ }
+
+ return 0;
+}
+
+int main (void)
+{
+ RUN_TEST(subst);
+ RUN_TEST(subst_string);
+
+ END_TEST;
+}
+
+/* vim: set sw=2 sts=2 et : */
{
cu_tail_t *obj;
- obj = (cu_tail_t *) malloc (sizeof (cu_tail_t));
+ obj = calloc (1, sizeof (*obj));
if (obj == NULL)
return (NULL);
- memset (obj, '\0', sizeof (cu_tail_t));
obj->file = strdup (file);
if (obj->file == NULL)
{
cu_tail_match_t *obj;
- obj = (cu_tail_match_t *) malloc (sizeof (cu_tail_match_t));
+ obj = calloc (1, sizeof (*obj));
if (obj == NULL)
return (NULL);
- memset (obj, '\0', sizeof (cu_tail_match_t));
obj->tail = cu_tail_create (filename);
if (obj->tail == NULL)
{
cu_tail_match_match_t *temp;
- temp = (cu_tail_match_match_t *) realloc (obj->matches,
+ temp = realloc (obj->matches,
sizeof (cu_tail_match_match_t) * (obj->matches_num + 1));
if (temp == NULL)
return (-1);
if (match == NULL)
return (-1);
- user_data = (cu_tail_match_simple_t *) malloc (sizeof (cu_tail_match_simple_t));
+ user_data = calloc (1, sizeof (*user_data));
if (user_data == NULL)
{
match_destroy (match);
return (-1);
}
- memset (user_data, '\0', sizeof (cu_tail_match_simple_t));
sstrncpy (user_data->plugin, plugin, sizeof (user_data->plugin));
if (plugin_instance != NULL)
threshold_t *threshold_search (const value_list_t *vl);
-int ut_search_threshold (const value_list_t *vl,
+int ut_search_threshold (const value_list_t *vl,
threshold_t *ret_threshold);
#endif /* UTILS_THRESHOLD_H */
/**
* collectd - src/utils_time.c
- * Copyright (C) 2010 Florian octo Forster
+ * Copyright (C) 2010-2015 Florian octo Forster
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* DEALINGS IN THE SOFTWARE.
*
* Authors:
- * Florian octo Forster <ff at octo.it>
+ * Florian octo Forster <octo at collectd.org>
**/
#include "collectd.h"
#include "plugin.h"
#include "common.h"
-#if HAVE_CLOCK_GETTIME
+#ifndef DEFAULT_MOCK_TIME
+# define DEFAULT_MOCK_TIME 1542455354518929408ULL
+#endif
+
+#ifdef MOCK_TIME
+cdtime_t cdtime_mock = (cdtime_t) MOCK_TIME;
+
+cdtime_t cdtime (void)
+{
+ return cdtime_mock;
+}
+#else /* !MOCK_TIME */
+# if HAVE_CLOCK_GETTIME
cdtime_t cdtime (void) /* {{{ */
{
int status;
return (TIMESPEC_TO_CDTIME_T (&ts));
} /* }}} cdtime_t cdtime */
-#else
+# else /* !HAVE_CLOCK_GETTIME */
/* Work around for Mac OS X which doesn't have clock_gettime(2). *sigh* */
cdtime_t cdtime (void) /* {{{ */
{
return (TIMEVAL_TO_CDTIME_T (&tv));
} /* }}} cdtime_t cdtime */
+# endif
#endif
-size_t cdtime_to_iso8601 (char *s, size_t max, cdtime_t t) /* {{{ */
+/* format_zone reads time zone information from "extern long timezone", exported
+ * by <time.h>, and formats it according to RFC 3339. This differs from
+ * strftime()'s "%z" format by including a colon between hour and minute. */
+static int format_zone (char *buffer, size_t buffer_size, struct tm const *tm) /* {{{ */
+{
+ char tmp[7];
+ size_t sz;
+
+ if ((buffer == NULL) || (buffer_size < 7))
+ return EINVAL;
+
+ sz = strftime (tmp, sizeof (tmp), "%z", tm);
+ if (sz == 0)
+ return ENOMEM;
+ if (sz != 5)
+ {
+ DEBUG ("format_zone: strftime(\"%%z\") = \"%s\", want \"+hhmm\"", tmp);
+ sstrncpy (buffer, tmp, buffer_size);
+ return 0;
+ }
+
+ buffer[0] = tmp[0];
+ buffer[1] = tmp[1];
+ buffer[2] = tmp[2];
+ buffer[3] = ':';
+ buffer[4] = tmp[3];
+ buffer[5] = tmp[4];
+ buffer[6] = 0;
+
+ return 0;
+} /* }}} int format_zone */
+
+static int format_rfc3339 (char *buffer, size_t buffer_size, cdtime_t t, _Bool print_nano) /* {{{ */
{
struct timespec t_spec;
struct tm t_tm;
-
+ char base[20]; /* 2006-01-02T15:04:05 */
+ char nano[11]; /* .999999999 */
+ char zone[7]; /* +00:00 */
+ char *fields[] = {base, nano, zone};
size_t len;
+ int status;
CDTIME_T_TO_TIMESPEC (t, &t_spec);
NORMALIZE_TIMESPEC (t_spec);
- if (localtime_r ((time_t *)&t_spec.tv_sec, &t_tm) == NULL) {
+ if (localtime_r (&t_spec.tv_sec, &t_tm) == NULL) {
char errbuf[1024];
- ERROR ("cdtime_to_iso8601: localtime_r failed: %s",
- sstrerror (errno, errbuf, sizeof (errbuf)));
- return (0);
+ status = errno;
+ ERROR ("format_rfc3339: localtime_r failed: %s",
+ sstrerror (status, errbuf, sizeof (errbuf)));
+ return (status);
}
- len = strftime (s, max, "%Y-%m-%dT%H:%M:%S", &t_tm);
+ len = strftime (base, sizeof (base), "%Y-%m-%dT%H:%M:%S", &t_tm);
if (len == 0)
- return 0;
+ return ENOMEM;
- if (max - len > 2) {
- int n = snprintf (s + len, max - len, ".%09i", (int)t_spec.tv_nsec);
- len += (n < max - len) ? n : max - len;
- }
+ if (print_nano)
+ ssnprintf (nano, sizeof (nano), ".%09ld", (long) t_spec.tv_nsec);
+ else
+ sstrncpy (nano, "", sizeof (nano));
- if (max - len > 3) {
- int n = strftime (s + len, max - len, "%z", &t_tm);
- len += (n < max - len) ? n : max - len;
- }
+ status = format_zone (zone, sizeof (zone), &t_tm);
+ if (status != 0)
+ return status;
+
+ if (strjoin (buffer, buffer_size, fields, STATIC_ARRAY_SIZE (fields), "") < 0)
+ return ENOMEM;
+ return 0;
+} /* }}} int format_rfc3339 */
+
+int rfc3339 (char *buffer, size_t buffer_size, cdtime_t t) /* {{{ */
+{
+ if (buffer_size < RFC3339_SIZE)
+ return ENOMEM;
+
+ return format_rfc3339 (buffer, buffer_size, t, 0);
+} /* }}} size_t cdtime_to_rfc3339 */
+
+int rfc3339nano (char *buffer, size_t buffer_size, cdtime_t t) /* {{{ */
+{
+ if (buffer_size < RFC3339NANO_SIZE)
+ return ENOMEM;
- s[max - 1] = '\0';
- return len;
-} /* }}} size_t cdtime_to_iso8601 */
+ return format_rfc3339 (buffer, buffer_size, t, 1);
+} /* }}} size_t cdtime_to_rfc3339nano */
/* vim: set sw=2 sts=2 et fdm=marker : */
/**
- * collectd - src/utils_time.h
- * Copyright (C) 2010 Florian octo Forster
+ * collectd - src/daemon/utils_time.h
+ * Copyright (C) 2010-2015 Florian octo Forster
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* DEALINGS IN THE SOFTWARE.
*
* Authors:
- * Florian octo Forster <ff at octo.it>
+ * Florian octo Forster <octo at collectd.org>
**/
#ifndef UTILS_TIME_H
#include "collectd.h"
+#ifdef TESTING_H
+/* cdtime_mock is the time returned by cdtime() when build with
+ * -DMOCK_TIME */
+extern cdtime_t cdtime_mock;
+#endif
+
/*
* "cdtime_t" is a 64bit unsigned integer. The time is stored at a 2^-30 second
* resolution, i.e. the most significant 34 bit are used to store the time in
* manner is that comparing times and calculating differences is as simple as
* it is with "time_t", i.e. a simple integer comparison / subtraction works.
*/
-/*
+/*
* cdtime_t is defined in "collectd.h" */
/* typedef uint64_t cdtime_t; */
/* 2^30 = 1073741824 */
-#define TIME_T_TO_CDTIME_T(t) (((cdtime_t) (t)) * 1073741824)
-#define CDTIME_T_TO_TIME_T(t) ((time_t) ((t) / 1073741824))
+#define TIME_T_TO_CDTIME_T(t) (((cdtime_t) (t)) << 30)
+
+#define MS_TO_CDTIME_T(ms) (((((cdtime_t) (ms)) / 1000) << 30) | \
+ ((((((cdtime_t) (ms)) % 1000) << 30) + 500) / 1000))
+#define US_TO_CDTIME_T(us) (((((cdtime_t) (us)) / 1000000) << 30) | \
+ ((((((cdtime_t) (us)) % 1000000) << 30) + 500000) / 1000000))
+#define NS_TO_CDTIME_T(ns) (((((cdtime_t) (ns)) / 1000000000) << 30) | \
+ ((((((cdtime_t) (ns)) % 1000000000) << 30) + 500000000) / 1000000000))
+
+#define CDTIME_T_TO_TIME_T(t) ((time_t) (((t) + (1 << 29)) >> 30))
+#define CDTIME_T_TO_MS(t) ((uint64_t) ((((t) >> 30) * 1000) + \
+ ((((t) & 0x3fffffff) * 1000 + (1 << 29)) >> 30)))
+#define CDTIME_T_TO_US(t) ((uint64_t) ((((t) >> 30) * 1000000) + \
+ ((((t) & 0x3fffffff) * 1000000 + (1 << 29)) >> 30)))
+#define CDTIME_T_TO_NS(t) ((uint64_t) ((((t) >> 30) * 1000000000) + \
+ ((((t) & 0x3fffffff) * 1000000000 + (1 << 29)) >> 30)))
#define CDTIME_T_TO_DOUBLE(t) (((double) (t)) / 1073741824.0)
#define DOUBLE_TO_CDTIME_T(d) ((cdtime_t) ((d) * 1073741824.0))
-#define MS_TO_CDTIME_T(ms) ((cdtime_t) (((double) (ms)) * 1073741.824))
-#define CDTIME_T_TO_MS(t) ((long) (((double) (t)) / 1073741.824))
-#define US_TO_CDTIME_T(us) ((cdtime_t) (((double) (us)) * 1073.741824))
-#define CDTIME_T_TO_US(t) ((suseconds_t) (((double) (t)) / 1073.741824))
-#define NS_TO_CDTIME_T(ns) ((cdtime_t) (((double) (ns)) * 1.073741824))
-#define CDTIME_T_TO_NS(t) ((long) (((double) (t)) / 1.073741824))
-
-#define CDTIME_T_TO_TIMEVAL(cdt,tvp) do { \
- (tvp)->tv_sec = CDTIME_T_TO_TIME_T (cdt); \
- (tvp)->tv_usec = CDTIME_T_TO_US ((cdt) % 1073741824); \
+#define CDTIME_T_TO_TIMEVAL(cdt,tvp) do { \
+ (tvp)->tv_sec = (time_t) ((cdt) >> 30); \
+ (tvp)->tv_usec = (suseconds_t) ((((cdt) & 0x3fffffff) * 1000000 + (1 << 29)) >> 30); \
} while (0)
-#define TIMEVAL_TO_CDTIME_T(tv) (TIME_T_TO_CDTIME_T ((tv)->tv_sec) \
- + US_TO_CDTIME_T ((tv)->tv_usec))
+#define TIMEVAL_TO_CDTIME_T(tv) US_TO_CDTIME_T(1000000 * (tv)->tv_sec + (tv)->tv_usec)
-#define CDTIME_T_TO_TIMESPEC(cdt,tsp) do { \
- (tsp)->tv_sec = CDTIME_T_TO_TIME_T (cdt); \
- (tsp)->tv_nsec = CDTIME_T_TO_NS ((cdt) % 1073741824); \
+#define CDTIME_T_TO_TIMESPEC(cdt,tsp) do { \
+ (tsp)->tv_sec = (time_t) ((cdt) >> 30); \
+ (tsp)->tv_nsec = (long) ((((cdt) & 0x3fffffff) * 1000000000 + (1 << 29)) >> 30); \
} while (0)
-#define TIMESPEC_TO_CDTIME_T(ts) (TIME_T_TO_CDTIME_T ((ts)->tv_sec) \
- + NS_TO_CDTIME_T ((ts)->tv_nsec))
+#define TIMESPEC_TO_CDTIME_T(ts) NS_TO_CDTIME_T(1000000000ULL * (ts)->tv_sec + (ts)->tv_nsec)
cdtime_t cdtime (void);
-/* format a cdtime_t value in ISO 8601 format:
- * returns the number of characters written to the string (not including the
- * terminating null byte or 0 on error; the function ensures that the string
- * is null terminated */
-size_t cdtime_to_iso8601 (char *s, size_t max, cdtime_t t);
+#define RFC3339_SIZE 26
+#define RFC3339NANO_SIZE 36
+
+/* rfc3339 formats a cdtime_t time in RFC 3339 format with second precision. */
+int rfc3339 (char *buffer, size_t buffer_size, cdtime_t t);
+
+/* rfc3339nano formats a cdtime_t time in RFC 3339 format with nanosecond
+ * precision. */
+int rfc3339nano (char *buffer, size_t buffer_size, cdtime_t t);
#endif /* UTILS_TIME_H */
/* vim: set sw=2 sts=2 et : */
+++ /dev/null
-/**
- * collectd - src/tests/mock/utils_time.c
- * Copyright (C) 2013 Florian octo Forster
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- * Authors:
- * Florian octo Forster <octo at collectd.org>
- */
-
-#include "utils_time.h"
-
-cdtime_t cdtime (void)
-{
- return (0);
-}
-
--- /dev/null
+/**
+ * collectd - src/daemon/utils_time_test.c
+ * Copyright (C) 2015 Florian octo Forster
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ * Florian octo Forster <octo at collectd.org>
+ */
+
+#define DBL_PRECISION 1e-3
+
+#include "collectd.h"
+#include "testing.h"
+#include "utils_time.h"
+
+DEF_TEST(conversion)
+{
+ struct {
+ cdtime_t t;
+ double d;
+ time_t tt;
+ uint64_t ms;
+ struct timeval tv;
+ struct timespec ts;
+ } cases[] = {
+ /* cdtime double time_t milliseconds timeval timespec */
+ { 0, 0.0 , 0, 0, { 0, 0}, { 0, 0}},
+ { 10737418240ULL, 10.0 , 10, 10000, { 10, 0}, { 10, 0}},
+ {1542908534771941376ULL, 1436945549.0 , 1436945549, 1436945549000ULL, {1436945549, 0}, {1436945549, 0}},
+ {1542908535540740522ULL, 1436945549.716, 1436945550, 1436945549716ULL, {1436945549, 716000}, {1436945549, 716000000}},
+ // 1426076671.123 * 2^30 = 1531238166015458148.352
+ {1531238166015458148ULL, 1426076671.123, 1426076671, 1426076671123ULL, {1426076671, 123000}, {1426076671, 123000000}},
+ // 1426076681.234 * 2^30 = 1531238176872061730.816
+ {1531238176872061731ULL, 1426076681.234, 1426076681, 1426076681234ULL, {1426076681, 234000}, {1426076681, 234000000}},
+ // 1426083986.314 * 2^30 = 1531246020641985396.736
+ {1531246020641985397ULL, 1426083986.314, 1426083986, 1426083986314ULL, {1426083986, 314000}, {1426083986, 314000000}},
+ // 1426083986.494142531 * 2^30 = 1531246020835411966.5
+ {1531246020835411967ULL, 1426083986.494, 1426083986, 1426083986494ULL, {1426083986, 494143}, {1426083986, 494142531}},
+ // 1426083986.987410814 * 2^30 = 1531246021365054752.4
+ {1531246021365054752ULL, 1426083986.987, 1426083987, 1426083986987ULL, {1426083986, 987411}, {1426083986, 987410814}},
+
+ /* These cases test the cdtime_t -> ns conversion rounds correctly. */
+ // 1546167635576736987 / 2^30 = 1439980823.1524536265...
+ {1546167635576736987ULL, 1439980823.152, 1439980823, 1439980823152ULL, {1439980823, 152454}, {1439980823, 152453627}},
+ // 1546167831554815222 / 2^30 = 1439981005.6712620165...
+ {1546167831554815222ULL, 1439981005.671, 1439981006, 1439981005671ULL, {1439981005, 671262}, {1439981005, 671262017}},
+ // 1546167986577716567 / 2^30 = 1439981150.0475896215...
+ {1546167986577716567ULL, 1439981150.048, 1439981150, 1439981150048ULL, {1439981150, 47590}, {1439981150, 47589622}},
+ };
+ size_t i;
+
+ for (i = 0; i < (sizeof (cases) / sizeof (cases[0])); i++) {
+ struct timeval tv;
+ struct timespec ts;
+
+ // cdtime -> s
+ EXPECT_EQ_UINT64 (cases[i].tt, CDTIME_T_TO_TIME_T (cases[i].t));
+
+ // cdtime -> ms
+ EXPECT_EQ_UINT64(cases[i].ms, CDTIME_T_TO_MS (cases[i].t));
+
+ // cdtime -> us
+ CDTIME_T_TO_TIMEVAL (cases[i].t, &tv);
+ EXPECT_EQ_UINT64 (cases[i].tv.tv_sec, tv.tv_sec);
+ EXPECT_EQ_UINT64 (cases[i].tv.tv_usec, tv.tv_usec);
+
+ // cdtime -> ns
+ CDTIME_T_TO_TIMESPEC (cases[i].t, &ts);
+ EXPECT_EQ_UINT64 (cases[i].ts.tv_sec, ts.tv_sec);
+ EXPECT_EQ_UINT64 (cases[i].ts.tv_nsec, ts.tv_nsec);
+
+ // cdtime -> double
+ EXPECT_EQ_DOUBLE (cases[i].d, CDTIME_T_TO_DOUBLE (cases[i].t));
+ }
+
+ return 0;
+}
+
+/* These cases test the ns -> cdtime_t conversion rounds correctly. */
+DEF_TEST(ns_to_cdtime)
+{
+ struct {
+ uint64_t ns;
+ cdtime_t want;
+ } cases[] = {
+ // 1439981652801860766 * 2^30 / 10^9 = 1546168526406004689.4
+ {1439981652801860766ULL, 1546168526406004689ULL},
+ // 1439981836985281914 * 2^30 / 10^9 = 1546168724171447263.4
+ {1439981836985281914ULL, 1546168724171447263ULL},
+ // 1439981880053705608 * 2^30 / 10^9 = 1546168770415815077.4
+ {1439981880053705608ULL, 1546168770415815077ULL},
+ };
+ size_t i;
+
+ for (i = 0; i < (sizeof (cases) / sizeof (cases[0])); i++) {
+ EXPECT_EQ_UINT64 (cases[i].want, NS_TO_CDTIME_T (cases[i].ns));
+ }
+
+ return 0;
+}
+
+int main (void)
+{
+ RUN_TEST(conversion);
+ RUN_TEST(ns_to_cdtime);
+
+ END_TEST;
+}
+
+/* vim: set sw=2 sts=2 et : */
char *name;
char *select_db;
+ cdtime_t interval;
+
char *driver;
char *host;
cdbi_driver_option_t *driver_options;
else if (src_type == DBI_TYPE_STRING)
{
const char *value;
-
+
value = dbi_result_get_string_idx (res, index);
if (value == NULL)
sstrncpy (buffer, "", buffer_size);
* </Result>
* ...
* </Query>
- *
+ *
* <Database "plugin_instance1">
* Driver "mysql"
+ * Interval 120
* DriverOption "hostname" "localhost"
* ...
* Query "plugin_instance0"
return (-1);
}
- option = (cdbi_driver_option_t *) realloc (db->driver_options,
+ option = realloc (db->driver_options,
sizeof (*option) * (db->driver_options_num + 1));
if (option == NULL)
{
return (-1);
}
- db = (cdbi_database_t *) malloc (sizeof (*db));
+ db = calloc (1, sizeof (*db));
if (db == NULL)
{
- ERROR ("dbi plugin: malloc failed.");
+ ERROR ("dbi plugin: calloc failed.");
return (-1);
}
- memset (db, 0, sizeof (*db));
status = cf_util_get_string (ci, &db->name);
if (status != 0)
&db->queries, &db->queries_num);
else if (strcasecmp ("Host", child->key) == 0)
status = cf_util_get_string (child, &db->host);
+ else if (strcasecmp ("Interval", child->key) == 0)
+ status = cf_util_get_cdtime(child, &db->interval);
else
{
WARNING ("dbi plugin: Option `%s' not allowed here.", child->key);
while ((status == 0) && (db->queries_num > 0))
{
- db->q_prep_areas = (udb_query_preparation_area_t **) calloc (
- db->queries_num, sizeof (*db->q_prep_areas));
+ size_t j;
+ db->q_prep_areas = calloc (db->queries_num, sizeof (*db->q_prep_areas));
if (db->q_prep_areas == NULL)
{
- WARNING ("dbi plugin: malloc failed");
+ WARNING ("dbi plugin: calloc failed");
status = -1;
break;
}
- for (i = 0; i < db->queries_num; ++i)
+ for (j = 0; j < db->queries_num; ++j)
{
- db->q_prep_areas[i]
- = udb_query_allocate_preparation_area (db->queries[i]);
+ db->q_prep_areas[j]
+ = udb_query_allocate_preparation_area (db->queries[j]);
- if (db->q_prep_areas[i] == NULL)
+ if (db->q_prep_areas[j] == NULL)
{
WARNING ("dbi plugin: udb_query_allocate_preparation_area failed");
status = -1;
{
cdbi_database_t **temp;
- temp = (cdbi_database_t **) realloc (databases,
+ temp = realloc (databases,
sizeof (*databases) * (databases_num + 1));
if (temp == NULL)
{
plugin_register_complex_read (/* group = */ NULL,
/* name = */ name ? name : db->name,
/* callback = */ cdbi_read_database,
- /* interval = */ NULL,
+ /* interval = */ (db->interval > 0) ? db->interval : 0,
/* user_data = */ &ud);
free (name);
}
column_names = NULL;
column_values = NULL;
- res = NULL;
statement = udb_query_get_statement (q);
assert (statement != NULL);
}
/* Allocate `column_names' and `column_values'. {{{ */
- column_names = (char **) calloc (column_num, sizeof (char *));
+ column_names = calloc (column_num, sizeof (*column_names));
if (column_names == NULL)
{
- ERROR ("dbi plugin: malloc failed.");
+ ERROR ("dbi plugin: calloc failed.");
BAIL_OUT (-1);
}
- column_names[0] = (char *) calloc (column_num,
- DATA_MAX_NAME_LEN * sizeof (char));
+ column_names[0] = calloc (column_num, DATA_MAX_NAME_LEN);
if (column_names[0] == NULL)
{
- ERROR ("dbi plugin: malloc failed.");
+ ERROR ("dbi plugin: calloc failed.");
BAIL_OUT (-1);
}
for (i = 1; i < column_num; i++)
column_names[i] = column_names[i - 1] + DATA_MAX_NAME_LEN;
- column_values = (char **) calloc (column_num, sizeof (char *));
+ column_values = calloc (column_num, sizeof (*column_values));
if (column_values == NULL)
{
- ERROR ("dbi plugin: malloc failed.");
+ ERROR ("dbi plugin: calloc failed.");
BAIL_OUT (-1);
}
- column_values[0] = (char *) calloc (column_num,
- DATA_MAX_NAME_LEN * sizeof (char));
+ column_values[0] = calloc (column_num, DATA_MAX_NAME_LEN);
if (column_values[0] == NULL)
{
- ERROR ("dbi plugin: malloc failed.");
+ ERROR ("dbi plugin: calloc failed.");
BAIL_OUT (-1);
}
for (i = 1; i < column_num; i++)
udb_query_prepare_result (q, prep_area, (db->host ? db->host : hostname_g),
/* plugin = */ "dbi", db->name,
- column_names, column_num, /* interval = */ 0);
+ column_names, column_num, /* interval = */ (db->interval > 0) ? db->interval : 0);
/* 0 = error; 1 = success; */
status = dbi_result_first_row (res); /* {{{ */
#if HAVE_IOKIT_IOBSD_H
# include <IOKit/IOBSD.h>
#endif
+#if KERNEL_FREEBSD
+#include <devstat.h>
+#include <libgeom.h>
+#endif
#if HAVE_LIMITS_H
# include <limits.h>
derive_t avg_read_time;
derive_t avg_write_time;
+ _Bool has_merged;
+ _Bool has_in_progress;
+ _Bool has_io_time;
+
struct diskstats *next;
} diskstats_t;
static diskstats_t *disklist;
/* #endif KERNEL_LINUX */
+#elif KERNEL_FREEBSD
+static struct gmesh geom_tree;
+/* #endif KERNEL_FREEBSD */
#elif HAVE_LIBKSTAT
#define MAX_NUMDISK 1024
/* #endif HAVE_IOKIT_IOKITLIB_H */
#elif KERNEL_LINUX
- /* do nothing */
+#if HAVE_LIBUDEV
+ if (conf_udev_name_attr != NULL)
+ {
+ handle_udev = udev_new();
+ if (handle_udev == NULL) {
+ ERROR ("disk plugin: udev_new() failed!");
+ return (-1);
+ }
+ }
+#endif /* HAVE_LIBUDEV */
/* #endif KERNEL_LINUX */
+#elif KERNEL_FREEBSD
+ int rv;
+
+ rv = geom_gettree(&geom_tree);
+ if (rv != 0) {
+ ERROR ("geom_gettree() failed, returned %d", rv);
+ return (-1);
+ }
+ rv = geom_stats_open();
+ if (rv != 0) {
+ ERROR ("geom_stats_open() failed, returned %d", rv);
+ return (-1);
+ }
+/* #endif KERNEL_FREEBSD */
+
#elif HAVE_LIBKSTAT
kstat_t *ksp_chain;
return (0);
} /* int disk_init */
+static int disk_shutdown (void)
+{
+#if KERNEL_LINUX
+#if HAVE_LIBUDEV
+ if (handle_udev != NULL)
+ udev_unref(handle_udev);
+#endif /* HAVE_LIBUDEV */
+#endif /* KERNEL_LINUX */
+ return (0);
+} /* int disk_shutdown */
+
static void disk_submit (const char *plugin_instance,
const char *type,
derive_t read, derive_t write)
value_t values[2];
value_list_t vl = VALUE_LIST_INIT;
- /* Both `ignorelist' and `plugin_instance' may be NULL. */
- if (ignorelist_match (ignorelist, plugin_instance) != 0)
- return;
-
values[0].derive = read;
values[1].derive = write;
plugin_dispatch_values (&vl);
} /* void disk_submit */
-#if KERNEL_LINUX
-static void submit_in_progress (char const *disk_name, gauge_t in_progress)
+#if KERNEL_FREEBSD || KERNEL_LINUX
+static void submit_io_time (char const *plugin_instance, derive_t io_time, derive_t weighted_time)
{
- value_t v;
+ value_t values[2];
value_list_t vl = VALUE_LIST_INIT;
- if (ignorelist_match (ignorelist, disk_name) != 0)
- return;
-
- v.gauge = in_progress;
+ values[0].derive = io_time;
+ values[1].derive = weighted_time;
- vl.values = &v;
- vl.values_len = 1;
+ vl.values = values;
+ vl.values_len = 2;
sstrncpy (vl.host, hostname_g, sizeof (vl.host));
sstrncpy (vl.plugin, "disk", sizeof (vl.plugin));
- sstrncpy (vl.plugin_instance, disk_name, sizeof (vl.plugin_instance));
- sstrncpy (vl.type, "pending_operations", sizeof (vl.type));
+ sstrncpy (vl.plugin_instance, plugin_instance, sizeof (vl.plugin_instance));
+ sstrncpy (vl.type, "disk_io_time", sizeof (vl.type));
plugin_dispatch_values (&vl);
-}
+} /* void submit_io_time */
+#endif /* KERNEL_FREEBSD || KERNEL_LINUX */
-static void submit_io_time (char const *plugin_instance, derive_t io_time, derive_t weighted_time)
+#if KERNEL_LINUX
+static void submit_in_progress (char const *disk_name, gauge_t in_progress)
{
- value_t values[2];
+ value_t v;
value_list_t vl = VALUE_LIST_INIT;
- if (ignorelist_match (ignorelist, plugin_instance) != 0)
- return;
-
- values[0].derive = io_time;
- values[1].derive = weighted_time;
+ v.gauge = in_progress;
- vl.values = values;
- vl.values_len = 2;
+ vl.values = &v;
+ vl.values_len = 1;
sstrncpy (vl.host, hostname_g, sizeof (vl.host));
sstrncpy (vl.plugin, "disk", sizeof (vl.plugin));
- sstrncpy (vl.plugin_instance, plugin_instance, sizeof (vl.plugin_instance));
- sstrncpy (vl.type, "disk_io_time", sizeof (vl.type));
+ sstrncpy (vl.plugin_instance, disk_name, sizeof (vl.plugin_instance));
+ sstrncpy (vl.type, "pending_operations", sizeof (vl.type));
plugin_dispatch_values (&vl);
}
DEBUG ("CFStringCreateWithCString (%s) failed.", key);
return (-1LL);
}
-
+
/* get => we don't need to release (== free) the object */
val_obj = (CFNumberRef) CFDictionaryGetValue (dict, key_obj);
else
ssnprintf (disk_name, sizeof (disk_name), "%i-%i", disk_major, disk_minor);
+ DEBUG ("disk plugin: disk_name = \"%s\"", disk_name);
+
+ /* check the name against ignore list */
+ if (ignorelist_match (ignorelist, disk_name) != 0) {
+ CFRelease (props_dict);
+ IOObjectRelease (disk);
+ continue;
+ }
+
/* extract the stats */
read_ops = dict_get_value (stats_dict, kIOBlockStorageDriverStatisticsReadsKey);
read_byt = dict_get_value (stats_dict, kIOBlockStorageDriverStatisticsBytesReadKey);
IOObjectRelease (disk);
/* and submit */
- DEBUG ("disk plugin: disk_name = \"%s\"", disk_name);
if ((read_byt != -1LL) || (write_byt != -1LL))
disk_submit (disk_name, "disk_octets", read_byt, write_byt);
if ((read_ops != -1LL) || (write_ops != -1LL))
IOObjectRelease (disk_list);
/* #endif HAVE_IOKIT_IOKITLIB_H */
+#elif KERNEL_FREEBSD
+ int retry, dirty;
+
+ void *snap = NULL;
+ struct devstat *snap_iter;
+
+ struct gident *geom_id;
+
+ const char *disk_name;
+ long double read_time, write_time, busy_time, total_duration;
+
+ for (retry = 0, dirty = 1; retry < 5 && dirty == 1; retry++) {
+ if (snap != NULL)
+ geom_stats_snapshot_free(snap);
+
+ /* Get a fresh copy of stats snapshot */
+ snap = geom_stats_snapshot_get();
+ if (snap == NULL) {
+ ERROR("disk plugin: geom_stats_snapshot_get() failed.");
+ return (-1);
+ }
+
+ /* Check if we have dirty read from this snapshot */
+ dirty = 0;
+ geom_stats_snapshot_reset(snap);
+ while ((snap_iter = geom_stats_snapshot_next(snap)) != NULL) {
+ if (snap_iter->id == NULL)
+ continue;
+ geom_id = geom_lookupid(&geom_tree, snap_iter->id);
+
+ /* New device? refresh GEOM tree */
+ if (geom_id == NULL) {
+ geom_deletetree(&geom_tree);
+ if (geom_gettree(&geom_tree) != 0) {
+ ERROR("disk plugin: geom_gettree() failed");
+ geom_stats_snapshot_free(snap);
+ return (-1);
+ }
+ geom_id = geom_lookupid(&geom_tree, snap_iter->id);
+ }
+ /*
+ * This should be rare: the device come right before we take the
+ * snapshot and went away right after it. We will handle this
+ * case later, so don't mark dirty but silently ignore it.
+ */
+ if (geom_id == NULL)
+ continue;
+
+ /* Only collect PROVIDER data */
+ if (geom_id->lg_what != ISPROVIDER)
+ continue;
+
+ /* Only collect data when rank is 1 (physical devices) */
+ if (((struct gprovider *)(geom_id->lg_ptr))->lg_geom->lg_rank != 1)
+ continue;
+
+ /* Check if this is a dirty read quit for another try */
+ if (snap_iter->sequence0 != snap_iter->sequence1) {
+ dirty = 1;
+ break;
+ }
+ }
+ }
+
+ /* Reset iterator */
+ geom_stats_snapshot_reset(snap);
+ for (;;) {
+ snap_iter = geom_stats_snapshot_next(snap);
+ if (snap_iter == NULL)
+ break;
+
+ if (snap_iter->id == NULL)
+ continue;
+ geom_id = geom_lookupid(&geom_tree, snap_iter->id);
+ if (geom_id == NULL)
+ continue;
+ if (geom_id->lg_what != ISPROVIDER)
+ continue;
+ if (((struct gprovider *)(geom_id->lg_ptr))->lg_geom->lg_rank != 1)
+ continue;
+ /* Skip dirty reads, if present */
+ if (dirty && (snap_iter->sequence0 != snap_iter->sequence1))
+ continue;
+
+ disk_name = ((struct gprovider *)geom_id->lg_ptr)->lg_name;
+
+ if (ignorelist_match (ignorelist, disk_name) != 0)
+ continue;
+
+ if ((snap_iter->bytes[DEVSTAT_READ] != 0) || (snap_iter->bytes[DEVSTAT_WRITE] != 0)) {
+ disk_submit(disk_name, "disk_octets",
+ (derive_t)snap_iter->bytes[DEVSTAT_READ],
+ (derive_t)snap_iter->bytes[DEVSTAT_WRITE]);
+ }
+
+ if ((snap_iter->operations[DEVSTAT_READ] != 0) || (snap_iter->operations[DEVSTAT_WRITE] != 0)) {
+ disk_submit(disk_name, "disk_ops",
+ (derive_t)snap_iter->operations[DEVSTAT_READ],
+ (derive_t)snap_iter->operations[DEVSTAT_WRITE]);
+ }
+
+ read_time = devstat_compute_etime(&snap_iter->duration[DEVSTAT_READ], NULL);
+ write_time = devstat_compute_etime(&snap_iter->duration[DEVSTAT_WRITE], NULL);
+ if ((read_time != 0) || (write_time != 0)) {
+ disk_submit (disk_name, "disk_time",
+ (derive_t)(read_time*1000), (derive_t)(write_time*1000));
+ }
+ if (devstat_compute_statistics(snap_iter, NULL, 1.0,
+ DSM_TOTAL_BUSY_TIME, &busy_time,
+ DSM_TOTAL_DURATION, &total_duration,
+ DSM_NONE) != 0) {
+ WARNING("%s", devstat_errbuf);
+ }
+ else
+ {
+ submit_io_time(disk_name, busy_time, total_duration);
+ }
+ }
+ geom_stats_snapshot_free(snap);
+
#elif KERNEL_LINUX
FILE *fh;
char buffer[1024];
-
+
char *fields[32];
int numfields;
int fieldshift = 0;
fieldshift = 1;
}
-#if HAVE_LIBUDEV
- handle_udev = udev_new();
-#endif
-
while (fgets (buffer, sizeof (buffer), fh) != NULL)
{
char *disk_name;
char *output_name;
- char *alt_name;
numfields = strsplit (buffer, fields, 32);
ds->read_time = read_time;
ds->write_ops = write_ops;
ds->write_time = write_time;
+
+ if (read_merged || write_merged)
+ ds->has_merged = 1;
+
+ if (in_progress)
+ ds->has_in_progress = 1;
+
+ if (io_time)
+ ds->has_io_time = 1;
+
} /* if (is_disk) */
/* Don't write to the RRDs if we've just started.. */
output_name = disk_name;
#if HAVE_LIBUDEV
- alt_name = disk_udev_attr_name (handle_udev, disk_name,
- conf_udev_name_attr);
-#else
- alt_name = NULL;
+ char *alt_name = NULL;
+ if (conf_udev_name_attr != NULL)
+ {
+ alt_name = disk_udev_attr_name (handle_udev, disk_name, conf_udev_name_attr);
+ if (alt_name != NULL)
+ output_name = alt_name;
+ }
#endif
- if (alt_name != NULL)
- output_name = alt_name;
+
+ if (ignorelist_match (ignorelist, output_name) != 0)
+ continue;
if ((ds->read_bytes != 0) || (ds->write_bytes != 0))
disk_submit (output_name, "disk_octets",
if (is_disk)
{
- disk_submit (output_name, "disk_merged",
+ if (ds->has_merged)
+ disk_submit (output_name, "disk_merged",
read_merged, write_merged);
- submit_in_progress (output_name, in_progress);
- submit_io_time (output_name, io_time, weighted_time);
+ if (ds->has_in_progress)
+ submit_in_progress (output_name, in_progress);
+ if (ds->has_io_time)
+ submit_io_time (output_name, io_time, weighted_time);
} /* if (is_disk) */
+#if HAVE_LIBUDEV
/* release udev-based alternate name, if allocated */
- free(alt_name);
+ sfree (alt_name);
+#endif
} /* while (fgets (buffer, sizeof (buffer), fh) != NULL) */
-#if HAVE_LIBUDEV
- udev_unref(handle_udev);
-#endif
fclose (fh);
/* #endif defined(KERNEL_LINUX) */
if (strncmp (ksp[i]->ks_class, "disk", 4) == 0)
{
+ if (ignorelist_match (ignorelist, ksp[i]->ks_name) != 0)
+ continue;
+
disk_submit (ksp[i]->ks_name, "disk_octets",
kio.KIO_ROCTETS, kio.KIO_WOCTETS);
disk_submit (ksp[i]->ks_name, "disk_ops",
}
else if (strncmp (ksp[i]->ks_class, "partition", 9) == 0)
{
+ if (ignorelist_match (ignorelist, ksp[i]->ks_name) != 0)
+ continue;
+
disk_submit (ksp[i]->ks_name, "disk_octets",
kio.KIO_ROCTETS, kio.KIO_WOCTETS);
disk_submit (ksp[i]->ks_name, "disk_ops",
#endif
int counter;
char name[DATA_MAX_NAME_LEN];
-
+
if ((ds = sg_get_disk_io_stats(&disks)) == NULL)
return (0);
-
+
for (counter=0; counter < disks; counter++) {
strncpy(name, ds->disk_name, sizeof(name));
name[sizeof(name)-1] = '\0'; /* strncpy doesn't terminate longer strings */
+
+ if (ignorelist_match (ignorelist, name) != 0) {
+ ds++;
+ continue;
+ }
+
disk_submit (name, "disk_octets", ds->read_bytes, ds->write_bytes);
ds++;
}
int rnumdisk;
int i;
- if ((numdisk = perfstat_disk(NULL, NULL, sizeof(perfstat_disk_t), 0)) < 0)
+ if ((numdisk = perfstat_disk(NULL, NULL, sizeof(perfstat_disk_t), 0)) < 0)
{
char errbuf[1024];
WARNING ("disk plugin: perfstat_disk: %s",
}
if (numdisk != pnumdisk || stat_disk==NULL) {
- if (stat_disk!=NULL)
+ if (stat_disk!=NULL)
free(stat_disk);
stat_disk = (perfstat_disk_t *)calloc(numdisk, sizeof(perfstat_disk_t));
- }
+ }
pnumdisk = numdisk;
firstpath.name[0]='\0';
- if ((rnumdisk = perfstat_disk(&firstpath, stat_disk, sizeof(perfstat_disk_t), numdisk)) < 0)
+ if ((rnumdisk = perfstat_disk(&firstpath, stat_disk, sizeof(perfstat_disk_t), numdisk)) < 0)
{
char errbuf[1024];
WARNING ("disk plugin: perfstat_disk : %s",
return (-1);
}
- for (i = 0; i < rnumdisk; i++)
+ for (i = 0; i < rnumdisk; i++)
{
+ if (ignorelist_match (ignorelist, stat_disk[i].name) != 0)
+ continue;
+
read_sectors = stat_disk[i].rblks*stat_disk[i].bsize;
write_sectors = stat_disk[i].wblks*stat_disk[i].bsize;
disk_submit (stat_disk[i].name, "disk_octets", read_sectors, write_sectors);
plugin_register_config ("disk", disk_config,
config_keys, config_keys_num);
plugin_register_init ("disk", disk_init);
+ plugin_register_shutdown ("disk", disk_shutdown);
plugin_register_read ("disk", disk_read);
} /* void module_register */
{
counter_list_t *entry;
- entry = (counter_list_t *) malloc (sizeof (counter_list_t));
+ entry = calloc (1, sizeof (*entry));
if (entry == NULL)
return (NULL);
- memset (entry, 0, sizeof (counter_list_t));
entry->key = key;
entry->value = value;
See: http://www.drbd.org/users-guide/ch-admin.html#s-performance-indicators
version: 8.3.11 (api:88/proto:86-96)
- srcversion: 71955441799F513ACA6DA60
+ srcversion: 71955441799F513ACA6DA60
0: cs:Connected ro:Primary/Secondary ds:UpToDate/UpToDate B r-----
ns:64363752 nr:0 dw:357799284 dr:846902273 al:34987022 bm:18062 lo:0 \
pe:0 ua:0 ap:0 ep:1 wo:f oos:0
# include <pthread.h>
#endif
-#include <sys/socket.h>
#include <sys/un.h>
#include <sys/select.h>
static void type_list_incr (type_list_t *list, char *name, int incr)
{
if (NULL == list->head) {
- list->head = (type_t *)smalloc (sizeof (type_t));
+ list->head = smalloc (sizeof (*list->head));
list->head->name = sstrdup (name);
list->head->value = incr;
}
if (NULL == ptr) {
- list->tail->next = (type_t *)smalloc (sizeof (type_t));
+ list->tail->next = smalloc (sizeof (*list->tail->next));
list->tail = list->tail->next;
list->tail->name = sstrdup (name);
{
struct sockaddr_un addr;
- char *path = (NULL == sock_file) ? SOCK_PATH : sock_file;
- char *group = (NULL == sock_group) ? COLLECTD_GRP_NAME : sock_group;
+ const char *path = (NULL == sock_file) ? SOCK_PATH : sock_file;
+ const char *group = (NULL == sock_group) ? COLLECTD_GRP_NAME : sock_group;
/* create UNIX socket */
errno = 0;
available_collectors = max_conns;
collectors =
- (collector_t **)smalloc (max_conns * sizeof (collector_t *));
+ smalloc (max_conns * sizeof (*collectors));
for (i = 0; i < max_conns; ++i) {
- collectors[i] = (collector_t *)smalloc (sizeof (collector_t));
+ collectors[i] = smalloc (sizeof (*collectors[i]));
collectors[i]->socket = NULL;
if (0 != (err = plugin_thread_create (&collectors[i]->thread,
break;
}
- connection = malloc (sizeof (*connection));
+ connection = calloc (1, sizeof (*connection));
if (connection == NULL)
{
close (remote);
continue;
}
- memset (connection, 0, sizeof (*connection));
connection->socket = fdopen (remote, "r");
connection->next = NULL;
for (ptr1 = l1->head, ptr2 = l2->head; NULL != ptr1;
ptr1 = ptr1->next, last = ptr2, ptr2 = ptr2->next) {
if (NULL == ptr2) {
- ptr2 = (type_t *)smalloc (sizeof (type_t));
+ ptr2 = smalloc (sizeof (*ptr2));
ptr2->name = NULL;
ptr2->next = NULL;
return (ENOMEM);
}
- map = malloc (sizeof (*map));
+ map = calloc (1, sizeof (*map));
if (map == NULL)
{
sfree (key);
- ERROR ("ethstat plugin: malloc(3) failed.");
+ ERROR ("ethstat plugin: calloc failed.");
return (ENOMEM);
}
- memset (map, 0, sizeof (*map));
sstrncpy (map->type, ci->values[1].value.string, sizeof (map->type));
if (ci->values_num == 3)
close (fd);
sfree (strings);
sfree (stats);
- ERROR("ethstat plugin: malloc(3) failed.");
+ ERROR("ethstat plugin: malloc failed.");
return (-1);
}
return (-1);
}
- pl = (program_list_t *) malloc (sizeof (program_list_t));
+ pl = calloc (1, sizeof (*pl));
if (pl == NULL)
{
- ERROR ("exec plugin: malloc failed.");
+ ERROR ("exec plugin: calloc failed.");
return (-1);
}
- memset (pl, '\0', sizeof (program_list_t));
if (strcasecmp ("NotificationExec", ci->key) == 0)
pl->flags |= PL_NOTIF_ACTION;
return (-1);
}
- pl->argv = (char **) malloc (ci->values_num * sizeof (char *));
+ pl->argv = calloc (ci->values_num, sizeof (*pl->argv));
if (pl->argv == NULL)
{
- ERROR ("exec plugin: malloc failed.");
+ ERROR ("exec plugin: calloc failed.");
sfree (pl->exec);
sfree (pl->user);
sfree (pl);
return (-1);
}
- memset (pl->argv, '\0', ci->values_num * sizeof (char *));
{
char *tmp = strrchr (ci->values[1].value.string, '/');
pl->argv[0] = strdup (buffer);
if (pl->argv[0] == NULL)
{
- ERROR ("exec plugin: malloc failed.");
+ ERROR ("exec plugin: strdup failed.");
sfree (pl->argv);
sfree (pl->exec);
sfree (pl->user);
if (pl->pid != 0)
continue;
- pln = (program_list_and_notification_t *) malloc (sizeof
- (program_list_and_notification_t));
+ pln = malloc (sizeof (*pln));
if (pln == NULL)
{
ERROR ("exec plugin: malloc failed.");
#include "collectd.h"
#include "common.h"
-#include "plugin.h"
+#include "plugin.h"
#include <sys/types.h>
#include <sys/stat.h>
}
/* Initialize `dir' */
- dir = (fc_directory_conf_t *) malloc (sizeof (*dir));
+ dir = calloc (1, sizeof (*dir));
if (dir == NULL)
{
- ERROR ("filecount plugin: malloc failed.");
+ ERROR ("filecount plugin: calloc failed.");
return (-1);
}
- memset (dir, 0, sizeof (*dir));
dir->path = strdup (ci->values[0].value.string);
if (dir->path == NULL)
{
fc_directory_conf_t **temp;
- temp = (fc_directory_conf_t **) realloc (directories,
+ temp = realloc (directories,
sizeof (*directories) * (directories_num + 1));
if (temp == NULL)
{
if (dir->mtime != 0)
dir->now = time (NULL);
-
+
status = walk_directory (dir->path, fc_read_dir_callback, dir,
/* include hidden */ (dir->options & FC_HIDDEN) ? 1 : 0);
if (status != 0)
#if HAVE_PTHREAD_H
# include <pthread.h>
#endif
-#if HAVE_SYS_SOCKET_H
-# include <sys/socket.h>
-#endif
#if HAVE_NETDB_H
# include <netdb.h>
#endif
struct metric_map_s
{
- char *ganglia_name;
- char *type;
- char *type_instance;
- char *ds_name;
- int ds_type;
- int ds_index;
+ char *ganglia_name;
+ char *type;
+ char *type_instance;
+ char *ds_name;
+ int ds_type;
+ size_t ds_index;
};
typedef struct metric_map_s metric_map_t;
return (NULL);
/* Look up the DS type and ds_index. */
- if ((map[i].ds_type < 0) || (map[i].ds_index < 0)) /* {{{ */
+ if (map[i].ds_type < 0) /* {{{ */
{
const data_set_t *ds;
}
else
{
- int j;
+ size_t j;
for (j = 0; j < ds->ds_num; j++)
if (strcasecmp (ds->ds[j].name, map[i].ds_name) == 0)
}
loop = 1;
- setsockopt (sockets[sockets_num].fd, IPPROTO_IP, IP_MULTICAST_LOOP,
+ status = setsockopt (sockets[sockets_num].fd, IPPROTO_IP, IP_MULTICAST_LOOP,
(void *) &loop, sizeof (loop));
+ if (status != 0)
+ {
+ char errbuf[1024];
+ WARNING ("gmond plugin: setsockopt(2) failed: %s",
+ sstrerror (errno, errbuf, sizeof (errbuf)));
+ }
memset (&mreq, 0, sizeof (mreq));
mreq.imr_multiaddr.s_addr = addr->sin_addr.s_addr;
mreq.imr_interface.s_addr = htonl (INADDR_ANY);
- setsockopt (sockets[sockets_num].fd, IPPROTO_IP, IP_ADD_MEMBERSHIP,
+
+ status = setsockopt (sockets[sockets_num].fd, IPPROTO_IP, IP_ADD_MEMBERSHIP,
(void *) &mreq, sizeof (mreq));
+ if (status != 0)
+ {
+ char errbuf[1024];
+ WARNING ("gmond plugin: setsockopt(2) failed: %s",
+ sstrerror (errno, errbuf, sizeof (errbuf)));
+ }
} /* if (ai_ptr->ai_family == AF_INET) */
else if (ai_ptr->ai_family == AF_INET6)
{
}
loop = 1;
- setsockopt (sockets[sockets_num].fd, IPPROTO_IPV6, IPV6_MULTICAST_LOOP,
+ status = setsockopt (sockets[sockets_num].fd, IPPROTO_IPV6, IPV6_MULTICAST_LOOP,
(void *) &loop, sizeof (loop));
+ if (status != 0)
+ {
+ char errbuf[1024];
+ WARNING ("gmond plugin: setsockopt(2) failed: %s",
+ sstrerror (errno, errbuf, sizeof (errbuf)));
+ }
memset (&mreq, 0, sizeof (mreq));
memcpy (&mreq.ipv6mr_multiaddr,
&addr->sin6_addr, sizeof (addr->sin6_addr));
mreq.ipv6mr_interface = 0; /* any */
- setsockopt (sockets[sockets_num].fd, IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP,
+ status = setsockopt (sockets[sockets_num].fd, IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP,
(void *) &mreq, sizeof (mreq));
+ if (status != 0)
+ {
+ char errbuf[1024];
+ WARNING ("gmond plugin: setsockopt(2) failed: %s",
+ sstrerror (errno, errbuf, sizeof (errbuf)));
+ }
} /* if (ai_ptr->ai_family == AF_INET6) */
sockets_num++;
return (se);
/* insert new entry */
- se = (staging_entry_t *) malloc (sizeof (*se));
+ se = calloc (1, sizeof (*se));
if (se == NULL)
return (NULL);
- memset (se, 0, sizeof (*se));
sstrncpy (se->key, key, sizeof (se->key));
se->flags = 0;
static int staging_entry_update (const char *host, const char *name, /* {{{ */
const char *type, const char *type_instance,
- int ds_index, int ds_type, value_t value)
+ size_t ds_index, int ds_type, value_t value)
{
const data_set_t *ds;
staging_entry_t *se;
if (ds->ds_num <= ds_index)
{
- ERROR ("gmond plugin: Invalid index %i: %s has only %i data source(s).",
+ ERROR ("gmond plugin: Invalid index %zu: %s has only %zu data source(s).",
ds_index, ds->type, ds->ds_num);
return (-1);
}
return (0);
} /* }}} int mc_receive_thread_stop */
-/*
+/*
* Config:
*
* <Plugin gmond>
#include "configfile.h"
# include <netdb.h>
-# include <sys/socket.h>
# include <netinet/in.h>
# include <netinet/tcp.h>
# include <libgen.h> /* for basename */
#if HAVE_SYS_TYPES_H
# include <sys/types.h>
#endif
-#if HAVE_SYS_SOCKET_H
-# include <sys/socket.h>
-#endif
/* One cannot include both. This sucks. */
#if HAVE_LINUX_IF_H
extern kstat_ctl_t *kc;
static kstat_t *ksp[MAX_NUMIF];
static int numif = 0;
+static _Bool unique_name = 0;
#endif /* HAVE_LIBKSTAT */
static int interface_config (const char *key, const char *value)
invert = 0;
ignorelist_set_invert (ignorelist, invert);
}
+ else if (strcasecmp (key, "UniqueName") == 0)
+ {
+ #ifdef HAVE_LIBKSTAT
+ if (IS_TRUE (value))
+ unique_name = 1;
+ #else
+ WARNING ("interface plugin: the \"UniqueName\" option is only valid on Solaris.");
+ #endif /* HAVE_LIBKSTAT */
+ }
else
{
return (-1);
struct ifaddrs *if_list;
struct ifaddrs *if_ptr;
-/* Darin/Mac OS X and possible other *BSDs */
+/* Darwin/Mac OS X and possible other *BSDs */
#if HAVE_STRUCT_IF_DATA
# define IFA_DATA if_data
# define IFA_RX_BYTES ifi_ibytes
incoming = atoll (fields[2]);
outgoing = atoll (fields[10]);
if_submit (device, "if_errors", incoming, outgoing);
+
+ incoming = atoll (fields[3]);
+ outgoing = atoll (fields[11]);
+ if_submit (device, "if_dropped", incoming, outgoing);
}
fclose (fh);
int i;
derive_t rx;
derive_t tx;
+ char iname[DATA_MAX_NAME_LEN];
if (kc == NULL)
return (-1);
if (kstat_read (kc, ksp[i], NULL) == -1)
continue;
+ if (unique_name)
+ ssnprintf(iname, sizeof(iname), "%s_%d_%s", ksp[i]->ks_module, ksp[i]->ks_instance, ksp[i]->ks_name);
+ else
+ sstrncpy(iname, ksp[i]->ks_name, sizeof(iname));
+
/* try to get 64bit counters */
rx = get_kstat_value (ksp[i], "rbytes64");
tx = get_kstat_value (ksp[i], "obytes64");
if (tx == -1LL)
tx = get_kstat_value (ksp[i], "obytes");
if ((rx != -1LL) || (tx != -1LL))
- if_submit (ksp[i]->ks_name, "if_octets", rx, tx);
+ if_submit (iname, "if_octets", rx, tx);
/* try to get 64bit counters */
rx = get_kstat_value (ksp[i], "ipackets64");
if (tx == -1LL)
tx = get_kstat_value (ksp[i], "opackets");
if ((rx != -1LL) || (tx != -1LL))
- if_submit (ksp[i]->ks_name, "if_packets", rx, tx);
+ if_submit (iname, "if_packets", rx, tx);
/* no 64bit error counters yet */
rx = get_kstat_value (ksp[i], "ierrors");
tx = get_kstat_value (ksp[i], "oerrors");
if ((rx != -1LL) || (tx != -1LL))
- if_submit (ksp[i]->ks_name, "if_errors", rx, tx);
+ if_submit (iname, "if_errors", rx, tx);
}
/* #endif HAVE_LIBKSTAT */
if (pnif != nif || ifstat == NULL)
{
- if (ifstat != NULL)
- free(ifstat);
- ifstat = malloc(nif * sizeof(perfstat_netinterface_t));
+ free(ifstat);
+ ifstat = malloc(nif * sizeof (*ifstat));
}
pnif = nif;
*nmemb = size / stsize;
- buff = (caddr_t)malloc (size);
+ buff = malloc (size);
if (buff == NULL) {
ERROR ("ipc plugin: ipc_get_info malloc failed.");
return (NULL);
msg_alloc_queues++;
msg_used_space += ipcinfo_msg[i].msg_cbytes;
msg_qnum += ipcinfo_msg[i].msg_qnum;
-
+ }
free(ipcinfo_msg);
ipc_submit_g("msg", "count", "queues", msg_alloc_queues);
{
/* `sensor_id_ptr' now points to "(123)". */
ssnprintf (sensor_name, sizeof (sensor_name),
- "%s %s", sensor_name_ptr, sensor_id_ptr);
+ "%s %s", sensor_name_ptr, sensor_id_ptr);
}
/* else: don't touch sensor_name. */
}
#include "plugin.h"
#include "configfile.h"
-#include <sys/socket.h>
-
#include <libiptc/libiptc.h>
#include <libiptc/libip6tc.h>
*/
static const char *config_keys[] =
{
- "Chain",
- "Chain6"
+ "Chain",
+ "Chain6"
};
static int config_keys_num = STATIC_ARRAY_SIZE (config_keys);
-/*
- Each table/chain combo that will be queried goes into this list
-*/
-
enum protocol_version_e
{
IPV4,
};
typedef enum protocol_version_e protocol_version_t;
+/*
+ * Each table/chain combo that will be queried goes into this list
+ */
#ifndef XT_TABLE_MAXNAMELEN
# define XT_TABLE_MAXNAMELEN 32
#endif
char chain[XT_TABLE_MAXNAMELEN];
union
{
- int num;
- char *comment;
+ int num;
+ char *comment;
} rule;
enum
{
- RTYPE_NUM,
- RTYPE_COMMENT,
- RTYPE_COMMENT_ALL
+ RTYPE_NUM,
+ RTYPE_COMMENT,
+ RTYPE_COMMENT_ALL
} rule_type;
char name[64];
} ip_chain_t;
static int iptables_config (const char *key, const char *value)
{
- /* int ip_value; */
- protocol_version_t ip_version = 0;
-
- if (strcasecmp (key, "Chain") == 0)
- ip_version = IPV4;
- else if (strcasecmp (key, "Chain6") == 0)
- ip_version = IPV6;
- else
- return (1);
-
- ip_chain_t temp, *final, **list;
- char *table;
- int table_len;
- char *chain;
- int chain_len;
-
- char *value_copy;
- char *fields[4];
- int fields_num;
-
- memset (&temp, 0, sizeof (temp));
-
- value_copy = strdup (value);
- if (value_copy == NULL)
- {
- char errbuf[1024];
- ERROR ("strdup failed: %s",
- sstrerror (errno, errbuf, sizeof (errbuf)));
- return (1);
- }
-
- /*
- * Time to fill the temp element
- * Examine value string, it should look like:
- * Chain[6] <table> <chain> [<comment|num> [name]]
- */
-
- /* set IPv4 or IPv6 */
- temp.ip_version = ip_version;
-
- /* Chain <table> <chain> [<comment|num> [name]] */
- fields_num = strsplit (value_copy, fields, 4);
- if (fields_num < 2)
- {
- free (value_copy);
- return (1);
- }
-
- table = fields[0];
- chain = fields[1];
-
- table_len = strlen (table) + 1;
- if ((unsigned int)table_len > sizeof(temp.table))
- {
- ERROR ("Table `%s' too long.", table);
- free (value_copy);
- return (1);
- }
- sstrncpy (temp.table, table, table_len);
-
- chain_len = strlen (chain) + 1;
- if ((unsigned int)chain_len > sizeof(temp.chain))
- {
- ERROR ("Chain `%s' too long.", chain);
- free (value_copy);
- return (1);
- }
- sstrncpy (temp.chain, chain, chain_len);
-
- if (fields_num >= 3)
- {
- char *comment = fields[2];
- int rule = atoi (comment);
-
- if (rule)
- {
- temp.rule.num = rule;
- temp.rule_type = RTYPE_NUM;
- }
- else
- {
- temp.rule.comment = strdup (comment);
- if (temp.rule.comment == NULL)
- {
- free (value_copy);
- return (1);
- }
- temp.rule_type = RTYPE_COMMENT;
- }
- }
- else
- {
- temp.rule_type = RTYPE_COMMENT_ALL;
- }
-
- if (fields_num >= 4)
- sstrncpy (temp.name, fields[3], sizeof (temp.name));
-
- free (value_copy);
- value_copy = NULL;
- table = NULL;
- chain = NULL;
-
- list = (ip_chain_t **) realloc (chain_list, (chain_num + 1) * sizeof (ip_chain_t *));
- if (list == NULL)
- {
- char errbuf[1024];
- ERROR ("realloc failed: %s",
- sstrerror (errno, errbuf, sizeof (errbuf)));
- sfree (temp.rule.comment);
- return (1);
- }
-
- chain_list = list;
- final = (ip_chain_t *) malloc( sizeof(temp) );
- if (final == NULL)
- {
- char errbuf[1024];
- ERROR ("malloc failed: %s",
- sstrerror (errno, errbuf, sizeof (errbuf)));
- sfree (temp.rule.comment);
- return (1);
- }
- memcpy (final, &temp, sizeof (temp));
- chain_list[chain_num] = final;
- chain_num++;
-
- DEBUG ("Chain #%i: table = %s; chain = %s;", chain_num, final->table, final->chain);
-
- return (0);
+ /* int ip_value; */
+ protocol_version_t ip_version = 0;
+
+ if (strcasecmp (key, "Chain") == 0)
+ ip_version = IPV4;
+ else if (strcasecmp (key, "Chain6") == 0)
+ ip_version = IPV6;
+ else
+ return (1);
+
+ ip_chain_t temp, *final, **list;
+ char *table;
+ int table_len;
+ char *chain;
+ int chain_len;
+
+ char *value_copy;
+ char *fields[4];
+ int fields_num;
+
+ memset (&temp, 0, sizeof (temp));
+
+ value_copy = strdup (value);
+ if (value_copy == NULL)
+ {
+ char errbuf[1024];
+ ERROR ("strdup failed: %s",
+ sstrerror (errno, errbuf, sizeof (errbuf)));
+ return (1);
+ }
+
+ /*
+ * Time to fill the temp element
+ * Examine value string, it should look like:
+ * Chain[6] <table> <chain> [<comment|num> [name]]
+ */
+
+ /* set IPv4 or IPv6 */
+ temp.ip_version = ip_version;
+
+ /* Chain <table> <chain> [<comment|num> [name]] */
+ fields_num = strsplit (value_copy, fields, 4);
+ if (fields_num < 2)
+ {
+ free (value_copy);
+ return (1);
+ }
+
+ table = fields[0];
+ chain = fields[1];
+
+ table_len = strlen (table) + 1;
+ if ((unsigned int)table_len > sizeof(temp.table))
+ {
+ ERROR ("Table `%s' too long.", table);
+ free (value_copy);
+ return (1);
+ }
+ sstrncpy (temp.table, table, table_len);
+
+ chain_len = strlen (chain) + 1;
+ if ((unsigned int)chain_len > sizeof(temp.chain))
+ {
+ ERROR ("Chain `%s' too long.", chain);
+ free (value_copy);
+ return (1);
+ }
+ sstrncpy (temp.chain, chain, chain_len);
+
+ if (fields_num >= 3)
+ {
+ char *comment = fields[2];
+ int rule = atoi (comment);
+
+ if (rule)
+ {
+ temp.rule.num = rule;
+ temp.rule_type = RTYPE_NUM;
+ }
+ else
+ {
+ temp.rule.comment = strdup (comment);
+ if (temp.rule.comment == NULL)
+ {
+ free (value_copy);
+ return (1);
+ }
+ temp.rule_type = RTYPE_COMMENT;
+ }
+ }
+ else
+ {
+ temp.rule_type = RTYPE_COMMENT_ALL;
+ }
+
+ if (fields_num >= 4)
+ sstrncpy (temp.name, fields[3], sizeof (temp.name));
+
+ free (value_copy);
+ value_copy = NULL;
+ table = NULL;
+ chain = NULL;
+
+ list = realloc (chain_list, (chain_num + 1) * sizeof (ip_chain_t *));
+ if (list == NULL)
+ {
+ char errbuf[1024];
+ ERROR ("realloc failed: %s",
+ sstrerror (errno, errbuf, sizeof (errbuf)));
+ sfree (temp.rule.comment);
+ return (1);
+ }
+
+ chain_list = list;
+ final = malloc(sizeof (*final));
+ if (final == NULL)
+ {
+ char errbuf[1024];
+ ERROR ("malloc failed: %s",
+ sstrerror (errno, errbuf, sizeof (errbuf)));
+ sfree (temp.rule.comment);
+ return (1);
+ }
+ memcpy (final, &temp, sizeof (temp));
+ chain_list[chain_num] = final;
+ chain_num++;
+
+ DEBUG ("Chain #%i: table = %s; chain = %s;", chain_num, final->table, final->chain);
+
+ return (0);
} /* int iptables_config */
static int submit6_match (const struct ip6t_entry_match *match,
- const struct ip6t_entry *entry,
- const ip_chain_t *chain,
- int rule_num)
+ const struct ip6t_entry *entry,
+ const ip_chain_t *chain,
+ int rule_num)
{
int status;
value_t values[1];
if (strcmp (match->u.user.name, "comment") != 0)
return (0);
if ((chain->rule_type == RTYPE_COMMENT)
- && (strcmp (chain->rule.comment, (char *) match->data) != 0))
+ && (strcmp (chain->rule.comment, (char *) match->data) != 0))
return (0);
}
sstrncpy (vl.plugin, "ip6tables", sizeof (vl.plugin));
status = ssnprintf (vl.plugin_instance, sizeof (vl.plugin_instance),
- "%s-%s", chain->table, chain->chain);
+ "%s-%s", chain->table, chain->chain);
if ((status < 1) || ((unsigned int)status >= sizeof (vl.plugin_instance)))
return (0);
{
if (chain->rule_type == RTYPE_NUM)
ssnprintf (vl.type_instance, sizeof (vl.type_instance),
- "%i", chain->rule.num);
+ "%i", chain->rule.num);
else
sstrncpy (vl.type_instance, (char *) match->data,
- sizeof (vl.type_instance));
+ sizeof (vl.type_instance));
}
sstrncpy (vl.type, "ipt_bytes", sizeof (vl.type));
/* This needs to return `int' for IPT_MATCH_ITERATE to work. */
static int submit_match (const struct ipt_entry_match *match,
- const struct ipt_entry *entry,
- const ip_chain_t *chain,
- int rule_num)
+ const struct ipt_entry *entry,
+ const ip_chain_t *chain,
+ int rule_num)
{
int status;
value_t values[1];
/* Select the rules to collect */
if (chain->rule_type == RTYPE_NUM)
{
- if (chain->rule.num != rule_num)
- return (0);
+ if (chain->rule.num != rule_num)
+ return (0);
}
else
{
- if (strcmp (match->u.user.name, "comment") != 0)
- return (0);
- if ((chain->rule_type == RTYPE_COMMENT)
- && (strcmp (chain->rule.comment, (char *) match->data) != 0))
- return (0);
+ if (strcmp (match->u.user.name, "comment") != 0)
+ return (0);
+ if ((chain->rule_type == RTYPE_COMMENT)
+ && (strcmp (chain->rule.comment, (char *) match->data) != 0))
+ return (0);
}
vl.values = values;
sstrncpy (vl.plugin, "iptables", sizeof (vl.plugin));
status = ssnprintf (vl.plugin_instance, sizeof (vl.plugin_instance),
- "%s-%s", chain->table, chain->chain);
+ "%s-%s", chain->table, chain->chain);
if ((status < 1) || ((unsigned int)status >= sizeof (vl.plugin_instance)))
- return (0);
+ return (0);
if (chain->name[0] != '\0')
{
- sstrncpy (vl.type_instance, chain->name, sizeof (vl.type_instance));
+ sstrncpy (vl.type_instance, chain->name, sizeof (vl.type_instance));
}
else
{
- if (chain->rule_type == RTYPE_NUM)
- ssnprintf (vl.type_instance, sizeof (vl.type_instance),
- "%i", chain->rule.num);
- else
- sstrncpy (vl.type_instance, (char *) match->data,
- sizeof (vl.type_instance));
+ if (chain->rule_type == RTYPE_NUM)
+ ssnprintf (vl.type_instance, sizeof (vl.type_instance),
+ "%i", chain->rule.num);
+ else
+ sstrncpy (vl.type_instance, (char *) match->data,
+ sizeof (vl.type_instance));
}
sstrncpy (vl.type, "ipt_bytes", sizeof (vl.type));
/* ipv6 submit_chain */
-static void submit6_chain( ip6tc_handle_t *handle, ip_chain_t *chain )
+static void submit6_chain (ip6tc_handle_t *handle, ip_chain_t *chain)
{
const struct ip6t_entry *entry;
int rule_num;
/* ipv4 submit_chain */
-static void submit_chain( iptc_handle_t *handle, ip_chain_t *chain )
+static void submit_chain (iptc_handle_t *handle, ip_chain_t *chain)
{
const struct ipt_entry *entry;
int rule_num;
- /* Find first rule for chain and use the iterate macro */
+ /* Find first rule for chain and use the iterate macro */
entry = iptc_first_rule( chain->chain, handle );
if (entry == NULL)
{
- DEBUG ("iptc_first_rule failed: %s", iptc_strerror (errno));
- return;
+ DEBUG ("iptc_first_rule failed: %s", iptc_strerror (errno));
+ return;
}
rule_num = 1;
while (entry)
{
- if (chain->rule_type == RTYPE_NUM)
- {
- submit_match (NULL, entry, chain, rule_num);
- }
- else
- {
- IPT_MATCH_ITERATE( entry, submit_match, entry, chain, rule_num );
- }
-
- entry = iptc_next_rule( entry, handle );
- rule_num++;
+ if (chain->rule_type == RTYPE_NUM)
+ {
+ submit_match (NULL, entry, chain, rule_num);
+ }
+ else
+ {
+ IPT_MATCH_ITERATE( entry, submit_match, entry, chain, rule_num );
+ }
+
+ entry = iptc_next_rule( entry, handle );
+ rule_num++;
} /* while (entry) */
}
int num_failures = 0;
ip_chain_t *chain;
- /* Init the iptc handle structure and query the correct table */
+ /* Init the iptc handle structure and query the correct table */
for (i = 0; i < chain_num; i++)
{
- chain = chain_list[i];
-
- if (!chain)
- {
- DEBUG ("iptables plugin: chain == NULL");
- continue;
- }
-
- if ( chain->ip_version == IPV4 )
+ chain = chain_list[i];
+
+ if (!chain)
+ {
+ DEBUG ("iptables plugin: chain == NULL");
+ continue;
+ }
+
+ if ( chain->ip_version == IPV4 )
{
#ifdef HAVE_IPTC_HANDLE_T
- iptc_handle_t _handle;
- iptc_handle_t *handle = &_handle;
+ iptc_handle_t _handle;
+ iptc_handle_t *handle = &_handle;
- *handle = iptc_init (chain->table);
+ *handle = iptc_init (chain->table);
#else
- iptc_handle_t *handle;
- handle = iptc_init (chain->table);
+ iptc_handle_t *handle;
+ handle = iptc_init (chain->table);
#endif
- if (!handle)
- {
- ERROR ("iptables plugin: iptc_init (%s) failed: %s",
- chain->table, iptc_strerror (errno));
- num_failures++;
- continue;
- }
+ if (!handle)
+ {
+ ERROR ("iptables plugin: iptc_init (%s) failed: %s",
+ chain->table, iptc_strerror (errno));
+ num_failures++;
+ continue;
+ }
- submit_chain (handle, chain);
- iptc_free (handle);
+ submit_chain (handle, chain);
+ iptc_free (handle);
}
else if ( chain->ip_version == IPV6 )
{
#ifdef HAVE_IP6TC_HANDLE_T
- ip6tc_handle_t _handle;
- ip6tc_handle_t *handle = &_handle;
+ ip6tc_handle_t _handle;
+ ip6tc_handle_t *handle = &_handle;
- *handle = ip6tc_init (chain->table);
+ *handle = ip6tc_init (chain->table);
#else
- ip6tc_handle_t *handle;
- handle = ip6tc_init (chain->table);
+ ip6tc_handle_t *handle;
+ handle = ip6tc_init (chain->table);
#endif
-
- if (!handle)
- {
- ERROR ("iptables plugin: ip6tc_init (%s) failed: %s",
- chain->table, ip6tc_strerror (errno));
- num_failures++;
- continue;
- }
-
- submit6_chain (handle, chain);
- ip6tc_free (handle);
+ if (!handle)
+ {
+ ERROR ("iptables plugin: ip6tc_init (%s) failed: %s",
+ chain->table, ip6tc_strerror (errno));
+ num_failures++;
+ continue;
+ }
+
+ submit6_chain (handle, chain);
+ ip6tc_free (handle);
}
- else num_failures++;
-
+ else
+ num_failures++;
} /* for (i = 0 .. chain_num) */
return ((num_failures < chain_num) ? 0 : -1);
for (i = 0; i < chain_num; i++)
{
- if ((chain_list[i] != NULL) && (chain_list[i]->rule_type == RTYPE_COMMENT))
- {
- sfree (chain_list[i]->rule.comment);
- }
- sfree (chain_list[i]);
+ if ((chain_list[i] != NULL) && (chain_list[i]->rule_type == RTYPE_COMMENT))
+ sfree (chain_list[i]->rule.comment);
+ sfree (chain_list[i]);
}
sfree (chain_list);
void module_register (void)
{
plugin_register_config ("iptables", iptables_config,
- config_keys, config_keys_num);
+ config_keys, config_keys_num);
plugin_register_read ("iptables", iptables_read);
plugin_register_shutdown ("iptables", iptables_shutdown);
} /* void module_register */
-/*
- * vim:shiftwidth=4:softtabstop=4:tabstop=8
- */
#if HAVE_ARPA_INET_H
# include <arpa/inet.h>
#endif /* HAVE_ARPA_INET_H */
-#if HAVE_SYS_SOCKET_H
-# include <sys/socket.h>
-#endif /* HAVE_SYS_SOCKET_H */
#if HAVE_NETINET_IN_H
# include <netinet/in.h>
#endif /* HAVE_NETINET_IN_H */
(se->protocol == IPPROTO_TCP) ? "TCP" : "UDP",
ntohs (se->port));
- if ((0 > len) || (size <= len)) {
+ if ((0 > len) || (size <= ((size_t) len))) {
log_err ("plugin instance truncated: %s", pi);
return -1;
}
len = ssnprintf (ti, size, "%s_%u", inet_ntoa (addr),
ntohs (de->port));
- if ((0 > len) || (size <= len)) {
+ if ((0 > len) || (size <= ((size_t) len))) {
log_err ("type instance truncated: %s", ti);
return -1;
}
return 0;
} /* get_ti */
-static void cipvs_submit_connections (char *pi, char *ti, derive_t value)
+static void cipvs_submit_connections (const char *pi, const char *ti,
+ derive_t value)
{
value_t values[1];
value_list_t vl = VALUE_LIST_INIT;
return;
} /* cipvs_submit_connections */
-static void cipvs_submit_if (char *pi, char *t, char *ti,
+static void cipvs_submit_if (const char *pi, const char *t, const char *ti,
derive_t rx, derive_t tx)
{
value_t values[2];
return;
} /* cipvs_submit_if */
-static void cipvs_submit_dest (char *pi, struct ip_vs_dest_entry *de) {
+static void cipvs_submit_dest (const char *pi, struct ip_vs_dest_entry *de)
+{
struct ip_vs_stats_user stats = de->stats;
char ti[DATA_MAX_NAME_LEN];
char pi[DATA_MAX_NAME_LEN];
- int i = 0;
+ size_t i;
if (0 != get_pi (se, pi, sizeof (pi)))
{
static int cipvs_read (void)
{
struct ip_vs_get_services *services = NULL;
- int i = 0;
+ size_t i;
if (sockfd < 0)
return (-1);
jmethodID m_add;
jobject o_type;
jobject o_dataset;
- int i;
+ size_t i;
/* Look up the org/collectd/api/DataSet class */
c_dataset = (*jvm_env)->FindClass (jvm_env, "org/collectd/api/DataSet");
jmethodID m_valuelist_constructor;
jobject o_valuelist;
int status;
- int i;
+ size_t i;
/* First, create a new ValueList instance..
* Look up the class.. */
ud.free_func = cjni_callback_info_destroy;
plugin_register_complex_read (/* group = */ NULL, cbi->name, cjni_read,
- /* interval = */ NULL, &ud);
+ /* interval = */ 0, &ud);
(*jvm_env)->DeleteLocalRef (jvm_env, o_read);
return (NULL);
}
- cbi = (cjni_callback_info_t *) malloc (sizeof (*cbi));
+ cbi = calloc (1, sizeof (*cbi));
if (cbi == NULL)
{
- ERROR ("java plugin: cjni_callback_info_create: malloc failed.");
+ ERROR ("java plugin: cjni_callback_info_create: calloc failed.");
(*jvm_env)->ReleaseStringUTFChars (jvm_env, o_name, c_name);
return (NULL);
}
- memset (cbi, 0, sizeof (*cbi));
cbi->type = type;
cbi->name = strdup (c_name);
pthread_mutex_lock (&java_callbacks_lock);
- tmp = (cjni_callback_info_t *) realloc (java_callbacks,
+ tmp = realloc (java_callbacks,
(java_callbacks_num + 1) * sizeof (*java_callbacks));
if (tmp == NULL)
{
if (cjni_env == NULL)
{
/* This pointer is free'd in `cjni_jvm_env_destroy'. */
- cjni_env = (cjni_jvm_env_t *) malloc (sizeof (*cjni_env));
+ cjni_env = calloc (1, sizeof (*cjni_env));
if (cjni_env == NULL)
{
- ERROR ("java plugin: cjni_thread_attach: malloc failed.");
+ ERROR ("java plugin: cjni_thread_attach: calloc failed.");
return (NULL);
}
- memset (cjni_env, 0, sizeof (*cjni_env));
cjni_env->reference_counter = 0;
cjni_env->jvm_env = NULL;
return (-1);
}
- tmp = (char **) realloc (jvm_argv, sizeof (char *) * (jvm_argc + 1));
+ tmp = realloc (jvm_argv, sizeof (char *) * (jvm_argc + 1));
if (tmp == NULL)
{
ERROR ("java plugin: realloc failed.");
if (jvm_env == NULL)
return (-1);
- class = (java_plugin_class_t *) realloc (java_classes_list,
+ class = realloc (java_classes_list,
(java_classes_list_len + 1) * sizeof (*java_classes_list));
if (class == NULL)
{
/* Allocate a new callback info structure. This is going to be our user_data
* pointer. */
- cbi_ret = (cjni_callback_info_t *) malloc (sizeof (*cbi_ret));
+ cbi_ret = calloc (1, sizeof (*cbi_ret));
if (cbi_ret == NULL)
{
- ERROR ("java plugin: cjni_match_target_create: malloc failed.");
+ ERROR ("java plugin: cjni_match_target_create: calloc failed.");
BAIL_OUT (-1);
}
- memset (cbi_ret, 0, sizeof (*cbi_ret));
+
cbi_ret->object = NULL;
cbi_ret->type = type;
AUTOMAKE_OPTIONS = foreign no-dependencies
-if COMPILER_IS_GCC
-AM_CFLAGS = -Wall -Werror
-endif
-
pkginclude_HEADERS = collectd/client.h collectd/network.h collectd/network_buffer.h collectd/lcc_features.h
lib_LTLIBRARIES = libcollectdclient.la
nodist_pkgconfig_DATA = libcollectdclient.pc
* beginning of the message. */
ptr = NULL;
errno = 0;
- res.status = strtol (buffer, &ptr, 0);
+ res.status = (int) strtol (buffer, &ptr, 0);
if ((errno != 0) || (ptr == &buffer[0]))
{
lcc_set_errno (c, errno);
/* Allocate space for the char-pointers */
res.lines_num = (size_t) res.status;
res.status = 0;
- res.lines = (char **) malloc (res.lines_num * sizeof (char *));
+ res.lines = malloc (res.lines_num * sizeof (*res.lines));
if (res.lines == NULL)
{
lcc_set_errno (c, ENOMEM);
if (ret_con == NULL)
return (-1);
- c = (lcc_connection_t *) malloc (sizeof (*c));
+ c = calloc (1, sizeof (*c));
if (c == NULL)
return (-1);
- memset (c, 0, sizeof (*c));
status = lcc_open_socket (c, address);
if (status != 0)
/* Allocate space for the values */
if (ret_values != NULL)
{
- values = (gauge_t *) malloc (values_num * sizeof (*values));
+ values = malloc (values_num * sizeof (*values));
if (values == NULL)
BAIL_OUT (ENOMEM);
}
}
ident_num = res.lines_num;
- ident = (lcc_identifier_t *) malloc (ident_num * sizeof (*ident));
+ ident = malloc (ident_num * sizeof (*ident));
if (ident == NULL)
{
lcc_response_free (&res);
lcc_network_t *lcc_network_create (void);
void lcc_network_destroy (lcc_network_t *net);
-/*
+/*
* Add servers
*/
lcc_server_t *lcc_server_create (lcc_network_t *net,
{
lcc_network_t *net;
- net = malloc (sizeof (*net));
+ net = calloc (1, sizeof (*net));
if (net == NULL)
return (NULL);
- memset (net, 0, sizeof (*net));
net->servers = NULL;
if (service == NULL)
service = NET_DEFAULT_PORT;
- srv = malloc (sizeof (*srv));
+ srv = calloc (1, sizeof (*srv));
if (srv == NULL)
return (NULL);
- memset (srv, 0, sizeof (*srv));
srv->fd = -1;
srv->security_level = NONE;
int lcc_server_set_interface (lcc_server_t *srv, char const *interface) /* {{{ */
{
- int if_index;
+ unsigned int if_index;
int status;
if ((srv == NULL) || (interface == NULL))
memset (&mreq, 0, sizeof (mreq));
mreq.imr_multiaddr.s_addr = addr->sin_addr.s_addr;
mreq.imr_address.s_addr = ntohl (INADDR_ANY);
- mreq.imr_ifindex = if_index;
+ mreq.imr_ifindex = (int) if_index;
#else
struct ip_mreq mreq;
/* else: Not a multicast interface. */
#if defined(SO_BINDTODEVICE)
- status = setsockopt (srv->fd, SOL_SOCKET, SO_BINDTODEVICE,
- interface, strlen (interface) + 1);
+ status = setsockopt (srv->fd, SOL_SOCKET, SO_BINDTODEVICE, interface,
+ (socklen_t) (strlen (interface) + 1));
if (status != 0)
return (-1);
#endif
return (NULL);
}
- nb = malloc (sizeof (*nb));
+ nb = calloc (1, sizeof (*nb));
if (nb == NULL)
return (NULL);
- memset (nb, 0, sizeof (*nb));
nb->size = size;
- nb->buffer = malloc (nb->size);
+ nb->buffer = calloc (1, nb->size);
if (nb->buffer == NULL)
{
free (nb);
return (NULL);
}
- memset (nb->buffer, 0, nb->size);
nb->ptr = nb->buffer;
nb->free = nb->size;
-AUTOMAKE_OPTIONS = foreign no-dependencies
-
BUILT_SOURCES = parser.h
#CLEANFILES = parser.[ch] scanner.c
AM_YFLAGS = -d
if (NULL == c_file) {
status = snprintf (file, sizeof (file), "<fd#%d>", fileno (fh));
- if ((status < 0) || (status >= sizeof (file))) {
+ if ((status < 0) || (((size_t) status) >= sizeof (file))) {
c_file = "<unknown>";
}
else {
{
oconfig_item_t *ci_copy;
- ci_copy = (oconfig_item_t *) malloc (sizeof (*ci_copy));
+ ci_copy = calloc (1, sizeof (*ci_copy));
if (ci_copy == NULL)
{
- fprintf (stderr, "malloc failed.\n");
+ fprintf (stderr, "calloc failed.\n");
return (NULL);
}
- memset (ci_copy, 0, sizeof (*ci_copy));
ci_copy->values = NULL;
ci_copy->parent = NULL;
ci_copy->children = NULL;
{
int i;
- ci_copy->values = (oconfig_value_t *) calloc (ci_orig->values_num,
- sizeof (*ci_copy->values));
+ ci_copy->values = (oconfig_value_t *) calloc ((size_t) ci_orig->values_num,
+ sizeof (*ci_copy->values));
if (ci_copy->values == NULL)
{
fprintf (stderr, "calloc failed.\n");
ci_copy->values[i].type = ci_orig->values[i].type;
if (ci_copy->values[i].type == OCONFIG_TYPE_STRING)
{
- ci_copy->values[i].value.string
- = strdup (ci_orig->values[i].value.string);
- if (ci_copy->values[i].value.string == NULL)
- {
- fprintf (stderr, "strdup failed.\n");
- oconfig_free (ci_copy);
- return (NULL);
- }
+ ci_copy->values[i].value.string = strdup (ci_orig->values[i].value.string);
+ if (ci_copy->values[i].value.string == NULL)
+ {
+ fprintf (stderr, "strdup failed.\n");
+ oconfig_free (ci_copy);
+ return (NULL);
+ }
}
else /* ci_copy->values[i].type != OCONFIG_TYPE_STRING) */
{
- ci_copy->values[i].value = ci_orig->values[i].value;
+ ci_copy->values[i].value = ci_orig->values[i].value;
}
}
} /* }}} if (ci_orig->values_num > 0) */
{
int i;
- ci_copy->children = (oconfig_item_t *) calloc (ci_orig->children_num,
- sizeof (*ci_copy->children));
+ ci_copy->children = (oconfig_item_t *) calloc ((size_t) ci_orig->children_num,
+ sizeof (*ci_copy->children));
if (ci_copy->children == NULL)
{
fprintf (stderr, "calloc failed.\n");
for (i = 0; i < ci_copy->children_num; i++)
{
oconfig_item_t *child;
-
+
child = oconfig_clone (ci_orig->children + i);
if (child == NULL)
{
{
oconfig_free_all (ci);
free (ci);
- ci = NULL;
}
/*
entire_file:
statement_list
{
- ci_root = malloc (sizeof (oconfig_item_t));
- memset (ci_root, '\0', sizeof (oconfig_item_t));
+ ci_root = calloc (1, sizeof (*ci_root));
ci_root->children = $1.statement;
ci_root->children_num = $1.statement_num;
}
| /* epsilon */
{
- ci_root = malloc (sizeof (oconfig_item_t));
- memset (ci_root, '\0', sizeof (oconfig_item_t));
+ ci_root = calloc (1, sizeof (*ci_root));
ci_root->children = NULL;
ci_root->children_num = 0;
}
%%
static int yyerror (const char *s)
{
- char *text;
+ const char *text;
if (*yytext == '\n')
text = "<newline>";
if (ml_free <= len) {
ml_len += len - ml_free + 1;
- ml_buffer = (char *)realloc (ml_buffer, ml_len);
+ ml_buffer = realloc (ml_buffer, ml_len);
if (NULL == ml_buffer)
YY_FATAL_ERROR ("out of dynamic memory in ml_append");
}
/**
- * There are several data streams provided by Madwifi plugin, some are
+ * There are several data streams provided by Madwifi plugin, some are
* connected to network interface, some are connected to each node
* associated to that interface. Nodes represents other sides in
* wireless communication, for example on network interface in AP mode,
* node_stat Node statistic counters
*
* Both statistic counters have type instances for each counter returned
- * by Madwifi. See madwifi.h for content of ieee80211_nodestats,
+ * by Madwifi. See madwifi.h for content of ieee80211_nodestats,
* ieee80211_stats and ath_stats structures. Type instances use the same
* name as fields in these structures (like ns_rx_dup). Some fields are
* not reported, because they are not counters (like ns_tx_deauth_code
* or ast_tx_rssi). Fields ns_rx_bytes and ns_tx_bytes are reported as
* node_octets data stream instead of type instance of node_stat.
* Statistics are not logged when they are zero.
- *
+ *
* There are two sets of these counters - the first 'WatchList' is a
* set of counters that are individually logged. The second 'MiscList'
* is a set of counters that are summed together and the sum is logged.
- * By default, the most important statistics are in the WatchList and
+ * By default, the most important statistics are in the WatchList and
* many error statistics are in MiscList. There are also many statistics
* that are not in any of these sets, so they are not monitored by default.
* It is possible to alter these lists using configuration options:
#include <dirent.h>
#include <sys/ioctl.h>
-#include <sys/socket.h>
#if !KERNEL_LINUX
# error "No applicable input method."
static inline int item_watched(int i)
{
assert (i >= 0);
- assert (i < ((STATIC_ARRAY_SIZE (watch_items) + 1) * 32));
+ assert (((size_t) i) < ((STATIC_ARRAY_SIZE (watch_items) + 1) * 32));
return watch_items[i / 32] & FLAG (i);
}
static inline int item_summed(int i)
{
assert (i >= 0);
- assert (i < ((STATIC_ARRAY_SIZE (misc_items) + 1) * 32));
+ assert (((size_t) i) < ((STATIC_ARRAY_SIZE (misc_items) + 1) * 32));
return misc_items[i / 32] & FLAG (i);
}
static int madwifi_real_init (void)
{
- int max = STATIC_ARRAY_SIZE (specs);
- int i;
+ size_t max = STATIC_ARRAY_SIZE (specs);
+ size_t i;
for (i = 0; i < STATIC_ARRAY_SIZE (bounds); i++)
bounds[i] = 0;
int i;
assert (which >= 1);
- assert (which < STATIC_ARRAY_SIZE (bounds));
+ assert (((size_t) which) < STATIC_ARRAY_SIZE (bounds));
for (i = bounds[which - 1]; i < bounds[which]; i++)
{
if (item_summed (i))
misc += val;
}
-
+
if (misc != 0)
submit_derive (dev, type_name, misc_name, mac, misc);
uint8_t buf[24*1024];
struct iwreq iwr;
uint8_t *cp;
- int len, nodes;
+ int nodes;
+ size_t len;
int status;
memset (&iwr, 0, sizeof (iwr));
int status;
int num_success;
int num_fail;
-
+
if ((fh = fopen ("/proc/net/dev", "r")) == NULL)
{
WARNING ("madwifi plugin: opening /proc/net/dev failed");
/* procfs iteration is not safe because it does not check whether given
interface is madwifi interface and there are private ioctls used, which
- may do something completely different on non-madwifi devices.
+ may do something completely different on non-madwifi devices.
Therefore, it is not used unless explicitly enabled (and should be used
together with ignorelist). */
{
mec_match_t *m;
- m = (mec_match_t *) malloc (sizeof (*m));
+ m = calloc (1, sizeof (*m));
if (m == NULL)
{
- ERROR ("mec_create: malloc failed.");
+ ERROR ("mec_create: calloc failed.");
return (-ENOMEM);
}
- memset (m, 0, sizeof (*m));
if (ci->children_num != 0)
{
{
int num_counters;
int num_empty;
- int i;
+ size_t i;
if ((user_data == NULL) || (*user_data == NULL))
return (-1);
mh_match_t *m;
int i;
- m = (mh_match_t *) malloc (sizeof (*m));
+ m = calloc (1, sizeof (*m));
if (m == NULL)
{
- ERROR ("mh_create: malloc failed.");
+ ERROR ("mh_create: calloc failed.");
return (-ENOMEM);
}
- memset (m, 0, sizeof (*m));
for (i = 0; i < ci->children_num; i++)
{
return (-1);
}
- re = (mr_regex_t *) malloc (sizeof (*re));
+ re = calloc (1, sizeof (*re));
if (re == NULL)
{
- log_err ("mr_config_add_regex: malloc failed.");
+ log_err ("mr_config_add_regex: calloc failed.");
return (-1);
}
- memset (re, 0, sizeof (*re));
re->next = NULL;
re->re_str = strdup (ci->values[0].value.string);
char errmsg[1024];
regerror (status, &re->re, errmsg, sizeof (errmsg));
errmsg[sizeof (errmsg) - 1] = 0;
- log_err ("Compiling regex `%s' for `%s' failed: %s.",
+ log_err ("Compiling regex `%s' for `%s' failed: %s.",
re->re_str, ci->key, errmsg);
free (re->re_str);
free (re);
int status;
int i;
- m = (mr_match_t *) malloc (sizeof (*m));
+ m = calloc (1, sizeof (*m));
if (m == NULL)
{
- log_err ("mr_create: malloc failed.");
+ log_err ("mr_create: calloc failed.");
return (-ENOMEM);
}
- memset (m, 0, sizeof (*m));
-
+
m->invert = 0;
status = 0;
int status;
int i;
- m = (mt_match_t *) malloc (sizeof (*m));
+ m = calloc (1, sizeof (*m));
if (m == NULL)
{
- ERROR ("mt_create: malloc failed.");
+ ERROR ("mt_create: calloc failed.");
return (-ENOMEM);
}
- memset (m, 0, sizeof (*m));
m->future = 0;
m->past = 0;
*/
static void mv_free_match (mv_match_t *m) /* {{{ */
{
- int i;
-
+ size_t i;
+
if (m == NULL)
return;
free(m->data_sources[i]);
free(m->data_sources);
}
-
+
free (m);
} /* }}} void mv_free_match */
/* Allocate space for the char pointers */
new_data_sources_num = m->data_sources_num + ((size_t) ci->values_num);
- temp = (char **) realloc (m->data_sources,
+ temp = realloc (m->data_sources,
new_data_sources_num * sizeof (char *));
if (temp == NULL)
{
int status;
int i;
- m = (mv_match_t *) malloc (sizeof (*m));
+ m = calloc (1, sizeof (*m));
if (m == NULL)
{
- ERROR ("mv_create: malloc failed.");
+ ERROR ("mv_create: calloc failed.");
return (-ENOMEM);
}
- memset (m, 0, sizeof (*m));
m->min = NAN;
m->max = NAN;
mv_match_t *m;
gauge_t *values;
int status;
- int i;
+ size_t i;
if ((user_data == NULL) || (*user_data == NULL))
return (-1);
if (m->satisfy == SATISFY_ANY)
break;
}
- else if (value_matches == 0)
+ else
{
status = FC_MATCH_NO_MATCH;
if (m->satisfy == SATISFY_ALL)
#include "configfile.h"
#include <netdb.h>
-#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
double value;
char *nextc;
- char *type;
- char *inst;
+ const char *type;
+ const char *inst;
*t++ = '\0';
trim_spaces (s);
WARNING ("memcachec plugin: Ignoring arguments for the `Match' block.");
}
- match = (web_match_t *) malloc (sizeof (*match));
+ match = calloc (1, sizeof (*match));
if (match == NULL)
{
- ERROR ("memcachec plugin: malloc failed.");
+ ERROR ("memcachec plugin: calloc failed.");
return (-1);
}
- memset (match, 0, sizeof (*match));
status = 0;
for (i = 0; i < ci->children_num; i++)
return (-1);
}
- page = (web_page_t *) malloc (sizeof (*page));
+ page = calloc (1, sizeof (*page));
if (page == NULL)
{
- ERROR ("memcachec plugin: malloc failed.");
+ ERROR ("memcachec plugin: calloc failed.");
return (-1);
}
- memset (page, 0, sizeof (*page));
page->server = NULL;
page->key = NULL;
web_page_t *prev;
prev = pages_g;
- while ((prev != NULL) && (prev->next != NULL))
+ while (prev->next != NULL)
prev = prev->next;
prev->next = page;
}
#include "configfile.h"
#include <netdb.h>
-#include <sys/socket.h>
#include <sys/un.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
static int memcached_connect_inet (memcached_t *st)
{
- char *host;
- char *port;
+ const char *host;
+ const char *port;
struct addrinfo ai_hints;
struct addrinfo *ai_list, *ai_ptr;
static int memcached_query_daemon (char *buffer, size_t buffer_size, memcached_t *st)
{
- int fd = -1;
- int status;
+ int fd, status;
size_t buffer_fill;
fd = memcached_connect (st);
status = plugin_register_complex_read (/* group = */ "memcached",
/* name = */ callback_name,
/* callback = */ memcached_read,
- /* interval = */ NULL,
+ /* interval = */ 0,
/* user_data = */ &ud);
return (status);
} /* int memcached_add_read_callback */
/* Disable automatic generation of default instance in the init callback. */
memcached_have_instances = 1;
- st = malloc (sizeof (*st));
+ st = calloc (1, sizeof (*st));
if (st == NULL)
{
- ERROR ("memcached plugin: malloc failed.");
+ ERROR ("memcached plugin: calloc failed.");
return (-1);
}
- memset (st, 0, sizeof (*st));
st->name = NULL;
st->socket = NULL;
st->host = NULL;
return (0);
/* No instances were configured, lets start a default instance. */
- st = malloc (sizeof (*st));
+ st = calloc (1, sizeof (*st));
if (st == NULL)
return (ENOMEM);
- memset (st, 0, sizeof (*st));
st->name = sstrdup ("__legacy__");
st->socket = NULL;
st->host = NULL;
#elif HAVE_LIBKSTAT
static int pagesize;
static kstat_t *ksp;
+static kstat_t *ksz;
/* #endif HAVE_LIBKSTAT */
#elif HAVE_SYSCTL
ksp = NULL;
return (-1);
}
+ if (get_kstat (&ksz, "zfs", 0, "arcstats") != 0)
+ {
+ ksz = NULL;
+ return (-1);
+ }
+
/* #endif HAVE_LIBKSTAT */
#elif HAVE_SYSCTL
* vm.stats.vm.v_inactive_count: 113730
* vm.stats.vm.v_cache_count: 10809
*/
- char *sysctl_keys[8] =
+ const char *sysctl_keys[8] =
{
"vm.stats.vm.v_page_size",
"vm.stats.vm.v_page_count",
long long mem_lock;
long long mem_kern;
long long mem_unus;
+ long long arcsize;
+
long long pp_kernel;
long long physmem;
if (ksp == NULL)
return (-1);
+ if (ksz == NULL)
+ return (-1);
mem_used = get_kstat_value (ksp, "pagestotal");
mem_free = get_kstat_value (ksp, "pagesfree");
mem_lock = get_kstat_value (ksp, "pageslocked");
- mem_kern = 0;
- mem_unus = 0;
-
+ arcsize = get_kstat_value (ksz, "size");
pp_kernel = get_kstat_value (ksp, "pp_kernel");
physmem = get_kstat_value (ksp, "physmem");
availrmem = get_kstat_value (ksp, "availrmem");
+ mem_kern = 0;
+ mem_unus = 0;
+
if ((mem_used < 0LL) || (mem_free < 0LL) || (mem_lock < 0LL))
{
WARNING ("memory plugin: one of used, free or locked is negative.");
mem_lock *= pagesize; /* some? ;) */
mem_kern *= pagesize; /* it's 2011 RAM is cheap */
mem_unus *= pagesize;
+ mem_kern -= arcsize;
+
MEMORY_SUBMIT ("used", (gauge_t) mem_used,
"free", (gauge_t) mem_free,
"locked", (gauge_t) mem_lock,
"kernel", (gauge_t) mem_kern,
+ "arc", (gauge_t) arcsize,
"unusable", (gauge_t) mem_unus);
/* #endif HAVE_LIBKSTAT */
REG_TYPE_UINT32,
REG_TYPE_FLOAT
}; /* }}} */
-enum mb_mreg_type_e /* {{{ */
+enum mb_mreg_type_e /* {{{ */
{
MREG_HOLDING,
MREG_INPUT
if (ds->ds_num != 1)
{
- ERROR ("Modbus plugin: The type \"%s\" has %i data sources. "
+ ERROR ("Modbus plugin: The type \"%s\" has %zu data sources. "
"I can only handle data sets with only one data source.",
data->type, ds->ds_num);
return (-1);
modbus_free (host->connection);
#endif
}
-
+
#if LEGACY_LIBMODBUS
/* Version 2.0.3: Pass the connection struct as a pointer and pass the slave
* id to each call of "read_holding_registers". */
int status;
int i;
- host = malloc (sizeof (*host));
+ host = calloc (1, sizeof (*host));
if (host == NULL)
return (ENOMEM);
- memset (host, 0, sizeof (*host));
host->slaves = NULL;
status = cf_util_get_string_buffer (ci, host->host, sizeof (host->host));
{
user_data_t ud;
char name[1024];
- struct timespec interval = { 0, 0 };
ud.data = host;
ud.free_func = host_free;
ssnprintf (name, sizeof (name), "modbus-%s", host->host);
- CDTIME_T_TO_TIMESPEC (host->interval, &interval);
-
plugin_register_complex_read (/* group = */ NULL, name,
/* callback = */ mb_read,
- /* interval = */ (host->interval > 0) ? &interval : NULL,
+ /* interval = */ host->interval,
&ud);
}
else
--- /dev/null
+/**
+ * collectd - src/mqtt.c
+ * Copyright (C) 2014 Marc Falzon
+ * Copyright (C) 2014,2015 Florian octo Forster
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ * Marc Falzon <marc at baha dot mu>
+ * Florian octo Forster <octo at collectd.org>
+ * Jan-Piet Mens <jpmens at gmail.com>
+ **/
+
+// Reference: http://mosquitto.org/api/files/mosquitto-h.html
+
+
+#include "collectd.h"
+#include "common.h"
+#include "plugin.h"
+#include "utils_cache.h"
+#include "utils_complain.h"
+
+#include <pthread.h>
+
+#include <mosquitto.h>
+
+#define MQTT_MAX_TOPIC_SIZE 1024
+#define MQTT_MAX_MESSAGE_SIZE MQTT_MAX_TOPIC_SIZE + 1024
+#define MQTT_DEFAULT_HOST "localhost"
+#define MQTT_DEFAULT_PORT 1883
+#define MQTT_DEFAULT_TOPIC_PREFIX "collectd"
+#define MQTT_DEFAULT_TOPIC "collectd/#"
+#ifndef MQTT_KEEPALIVE
+# define MQTT_KEEPALIVE 60
+#endif
+#ifndef SSL_VERIFY_PEER
+# define SSL_VERIFY_PEER 1
+#endif
+
+
+/*
+ * Data types
+ */
+struct mqtt_client_conf
+{
+ _Bool publish;
+ char *name;
+
+ struct mosquitto *mosq;
+ _Bool connected;
+
+ char *host;
+ int port;
+ char *client_id;
+ char *username;
+ char *password;
+ int qos;
+ char *cacertificatefile;
+ char *certificatefile;
+ char *certificatekeyfile;
+ char *tlsprotocol;
+ char *ciphersuite;
+
+ /* For publishing */
+ char *topic_prefix;
+ _Bool store_rates;
+ _Bool retain;
+
+ /* For subscribing */
+ pthread_t thread;
+ _Bool loop;
+ char *topic;
+ _Bool clean_session;
+
+ c_complain_t complaint_cantpublish;
+ pthread_mutex_t lock;
+};
+typedef struct mqtt_client_conf mqtt_client_conf_t;
+
+static mqtt_client_conf_t **subscribers = NULL;
+static size_t subscribers_num = 0;
+
+/*
+ * Functions
+ */
+#if LIBMOSQUITTO_MAJOR == 0
+static char const *mosquitto_strerror (int code)
+{
+ switch (code)
+ {
+ case MOSQ_ERR_SUCCESS: return "MOSQ_ERR_SUCCESS";
+ case MOSQ_ERR_NOMEM: return "MOSQ_ERR_NOMEM";
+ case MOSQ_ERR_PROTOCOL: return "MOSQ_ERR_PROTOCOL";
+ case MOSQ_ERR_INVAL: return "MOSQ_ERR_INVAL";
+ case MOSQ_ERR_NO_CONN: return "MOSQ_ERR_NO_CONN";
+ case MOSQ_ERR_CONN_REFUSED: return "MOSQ_ERR_CONN_REFUSED";
+ case MOSQ_ERR_NOT_FOUND: return "MOSQ_ERR_NOT_FOUND";
+ case MOSQ_ERR_CONN_LOST: return "MOSQ_ERR_CONN_LOST";
+ case MOSQ_ERR_SSL: return "MOSQ_ERR_SSL";
+ case MOSQ_ERR_PAYLOAD_SIZE: return "MOSQ_ERR_PAYLOAD_SIZE";
+ case MOSQ_ERR_NOT_SUPPORTED: return "MOSQ_ERR_NOT_SUPPORTED";
+ case MOSQ_ERR_AUTH: return "MOSQ_ERR_AUTH";
+ case MOSQ_ERR_ACL_DENIED: return "MOSQ_ERR_ACL_DENIED";
+ case MOSQ_ERR_UNKNOWN: return "MOSQ_ERR_UNKNOWN";
+ case MOSQ_ERR_ERRNO: return "MOSQ_ERR_ERRNO";
+ }
+
+ return "UNKNOWN ERROR CODE";
+}
+#else
+/* provided by libmosquitto */
+#endif
+
+static void mqtt_free (mqtt_client_conf_t *conf)
+{
+ if (conf == NULL)
+ return;
+
+ if (conf->connected)
+ (void) mosquitto_disconnect (conf->mosq);
+ conf->connected = 0;
+ (void) mosquitto_destroy (conf->mosq);
+
+ sfree (conf->host);
+ sfree (conf->username);
+ sfree (conf->password);
+ sfree (conf->client_id);
+ sfree (conf->topic_prefix);
+ sfree (conf);
+}
+
+static char *strip_prefix (char *topic)
+{
+ size_t num;
+ size_t i;
+
+ num = 0;
+ for (i = 0; topic[i] != 0; i++)
+ if (topic[i] == '/')
+ num++;
+
+ if (num < 2)
+ return (NULL);
+
+ while (num > 2)
+ {
+ char *tmp = strchr (topic, '/');
+ if (tmp == NULL)
+ return (NULL);
+ topic = tmp + 1;
+ num--;
+ }
+
+ return (topic);
+}
+
+static void on_message (
+#if LIBMOSQUITTO_MAJOR == 0
+#else
+ __attribute__((unused)) struct mosquitto *m,
+#endif
+ __attribute__((unused)) void *arg,
+ const struct mosquitto_message *msg)
+{
+ value_list_t vl = VALUE_LIST_INIT;
+ data_set_t const *ds;
+ char *topic;
+ char *name;
+ char *payload;
+ int status;
+
+ if (msg->payloadlen <= 0) {
+ DEBUG ("mqtt plugin: message has empty payload");
+ return;
+ }
+
+ topic = strdup (msg->topic);
+ name = strip_prefix (topic);
+
+ status = parse_identifier_vl (name, &vl);
+ if (status != 0)
+ {
+ ERROR ("mqtt plugin: Unable to parse topic \"%s\".", topic);
+ sfree (topic);
+ return;
+ }
+ sfree (topic);
+
+ ds = plugin_get_ds (vl.type);
+ if (ds == NULL)
+ {
+ ERROR ("mqtt plugin: Unknown type: \"%s\".", vl.type);
+ return;
+ }
+
+ vl.values = calloc (ds->ds_num, sizeof (*vl.values));
+ if (vl.values == NULL)
+ {
+ ERROR ("mqtt plugin: calloc failed.");
+ return;
+ }
+ vl.values_len = ds->ds_num;
+
+ payload = malloc (msg->payloadlen+1);
+ if (payload == NULL)
+ {
+ ERROR ("mqtt plugin: malloc for payload buffer failed.");
+ sfree (vl.values);
+ return;
+ }
+ memmove (payload, msg->payload, msg->payloadlen);
+ payload[msg->payloadlen] = 0;
+
+ DEBUG ("mqtt plugin: payload = \"%s\"", payload);
+ status = parse_values (payload, &vl, ds);
+ if (status != 0)
+ {
+ ERROR ("mqtt plugin: Unable to parse payload \"%s\".", payload);
+ sfree (payload);
+ sfree (vl.values);
+ return;
+ }
+ sfree (payload);
+
+ plugin_dispatch_values (&vl);
+ sfree (vl.values);
+} /* void on_message */
+
+/* must hold conf->lock when calling. */
+static int mqtt_reconnect (mqtt_client_conf_t *conf)
+{
+ int status;
+
+ if (conf->connected)
+ return (0);
+
+ status = mosquitto_reconnect (conf->mosq);
+ if (status != MOSQ_ERR_SUCCESS)
+ {
+ char errbuf[1024];
+ ERROR ("mqtt_connect_broker: mosquitto_connect failed: %s",
+ (status == MOSQ_ERR_ERRNO)
+ ? sstrerror(errno, errbuf, sizeof (errbuf))
+ : mosquitto_strerror (status));
+ return (-1);
+ }
+
+ conf->connected = 1;
+
+ c_release (LOG_INFO,
+ &conf->complaint_cantpublish,
+ "mqtt plugin: successfully reconnected to broker \"%s:%d\"",
+ conf->host, conf->port);
+
+ return (0);
+} /* mqtt_reconnect */
+
+/* must hold conf->lock when calling. */
+static int mqtt_connect (mqtt_client_conf_t *conf)
+{
+ char const *client_id;
+ int status;
+
+ if (conf->mosq != NULL)
+ return mqtt_reconnect (conf);
+
+ if (conf->client_id)
+ client_id = conf->client_id;
+ else
+ client_id = hostname_g;
+
+#if LIBMOSQUITTO_MAJOR == 0
+ conf->mosq = mosquitto_new (client_id, /* user data = */ conf);
+#else
+ conf->mosq = mosquitto_new (client_id, conf->clean_session, /* user data = */ conf);
+#endif
+ if (conf->mosq == NULL)
+ {
+ ERROR ("mqtt plugin: mosquitto_new failed");
+ return (-1);
+ }
+
+#if LIBMOSQUITTO_MAJOR != 0
+ if (conf->cacertificatefile) {
+ status = mosquitto_tls_set(conf->mosq, conf->cacertificatefile, NULL,
+ conf->certificatefile, conf->certificatekeyfile, /* pw_callback */NULL);
+ if (status != MOSQ_ERR_SUCCESS) {
+ ERROR ("mqtt plugin: cannot mosquitto_tls_set: %s", mosquitto_strerror(status));
+ mosquitto_destroy (conf->mosq);
+ conf->mosq = NULL;
+ return (-1);
+ }
+
+ status = mosquitto_tls_opts_set(conf->mosq, SSL_VERIFY_PEER, conf->tlsprotocol, conf->ciphersuite);
+ if (status != MOSQ_ERR_SUCCESS) {
+ ERROR ("mqtt plugin: cannot mosquitto_tls_opts_set: %s", mosquitto_strerror(status));
+ mosquitto_destroy (conf->mosq);
+ conf->mosq = NULL;
+ return (-1);
+ }
+
+ status = mosquitto_tls_insecure_set(conf->mosq, false);
+ if (status != MOSQ_ERR_SUCCESS) {
+ ERROR ("mqtt plugin: cannot mosquitto_tls_insecure_set: %s", mosquitto_strerror(status));
+ mosquitto_destroy (conf->mosq);
+ conf->mosq = NULL;
+ return (-1);
+ }
+ }
+#endif
+
+ if (conf->username && conf->password)
+ {
+ status = mosquitto_username_pw_set (conf->mosq, conf->username, conf->password);
+ if (status != MOSQ_ERR_SUCCESS)
+ {
+ char errbuf[1024];
+ ERROR ("mqtt plugin: mosquitto_username_pw_set failed: %s",
+ (status == MOSQ_ERR_ERRNO)
+ ? sstrerror (errno, errbuf, sizeof (errbuf))
+ : mosquitto_strerror (status));
+
+ mosquitto_destroy (conf->mosq);
+ conf->mosq = NULL;
+ return (-1);
+ }
+ }
+
+#if LIBMOSQUITTO_MAJOR == 0
+ status = mosquitto_connect (conf->mosq, conf->host, conf->port,
+ /* keepalive = */ MQTT_KEEPALIVE, /* clean session = */ conf->clean_session);
+#else
+ status = mosquitto_connect (conf->mosq, conf->host, conf->port, MQTT_KEEPALIVE);
+#endif
+ if (status != MOSQ_ERR_SUCCESS)
+ {
+ char errbuf[1024];
+ ERROR ("mqtt plugin: mosquitto_connect failed: %s",
+ (status == MOSQ_ERR_ERRNO)
+ ? sstrerror (errno, errbuf, sizeof (errbuf))
+ : mosquitto_strerror (status));
+
+ mosquitto_destroy (conf->mosq);
+ conf->mosq = NULL;
+ return (-1);
+ }
+
+ if (!conf->publish)
+ {
+ mosquitto_message_callback_set (conf->mosq, on_message);
+
+ status = mosquitto_subscribe (conf->mosq,
+ /* message_id = */ NULL,
+ conf->topic, conf->qos);
+ if (status != MOSQ_ERR_SUCCESS)
+ {
+ ERROR ("mqtt plugin: Subscribing to \"%s\" failed: %s",
+ conf->topic, mosquitto_strerror (status));
+
+ mosquitto_disconnect (conf->mosq);
+ mosquitto_destroy (conf->mosq);
+ conf->mosq = NULL;
+ return (-1);
+ }
+ }
+
+ conf->connected = 1;
+ return (0);
+} /* mqtt_connect */
+
+static void *subscribers_thread (void *arg)
+{
+ mqtt_client_conf_t *conf = arg;
+ int status;
+
+ conf->loop = 1;
+
+ while (conf->loop)
+ {
+ status = mqtt_connect (conf);
+ if (status != 0)
+ {
+ sleep (1);
+ continue;
+ }
+
+ /* The documentation says "0" would map to the default (1000ms), but
+ * that does not work on some versions. */
+#if LIBMOSQUITTO_MAJOR == 0
+ status = mosquitto_loop (conf->mosq, /* timeout = */ 1000 /* ms */);
+#else
+ status = mosquitto_loop (conf->mosq,
+ /* timeout[ms] = */ 1000,
+ /* max_packets = */ 100);
+#endif
+ if (status == MOSQ_ERR_CONN_LOST)
+ {
+ conf->connected = 0;
+ continue;
+ }
+ else if (status != MOSQ_ERR_SUCCESS)
+ {
+ ERROR ("mqtt plugin: mosquitto_loop failed: %s",
+ mosquitto_strerror (status));
+ mosquitto_destroy (conf->mosq);
+ conf->mosq = NULL;
+ conf->connected = 0;
+ continue;
+ }
+
+ DEBUG ("mqtt plugin: mosquitto_loop succeeded.");
+ } /* while (conf->loop) */
+
+ pthread_exit (0);
+} /* void *subscribers_thread */
+
+static int publish (mqtt_client_conf_t *conf, char const *topic,
+ void const *payload, size_t payload_len)
+{
+ int status;
+
+ pthread_mutex_lock (&conf->lock);
+
+ status = mqtt_connect (conf);
+ if (status != 0) {
+ pthread_mutex_unlock (&conf->lock);
+ ERROR ("mqtt plugin: unable to reconnect to broker");
+ return (status);
+ }
+
+ status = mosquitto_publish(conf->mosq, /* message_id */ NULL, topic,
+#if LIBMOSQUITTO_MAJOR == 0
+ (uint32_t) payload_len, payload,
+#else
+ (int) payload_len, payload,
+#endif
+ conf->qos, conf->retain);
+ if (status != MOSQ_ERR_SUCCESS)
+ {
+ char errbuf[1024];
+ c_complain (LOG_ERR,
+ &conf->complaint_cantpublish,
+ "mqtt plugin: mosquitto_publish failed: %s",
+ (status == MOSQ_ERR_ERRNO)
+ ? sstrerror(errno, errbuf, sizeof (errbuf))
+ : mosquitto_strerror(status));
+ /* Mark our connection "down" regardless of the error as a safety
+ * measure; we will try to reconnect the next time we have to publish a
+ * message */
+ conf->connected = 0;
+
+ pthread_mutex_unlock (&conf->lock);
+ return (-1);
+ }
+
+ pthread_mutex_unlock (&conf->lock);
+ return (0);
+} /* int publish */
+
+static int format_topic (char *buf, size_t buf_len,
+ data_set_t const *ds, value_list_t const *vl,
+ mqtt_client_conf_t *conf)
+{
+ char name[MQTT_MAX_TOPIC_SIZE];
+ int status;
+
+ if ((conf->topic_prefix == NULL) || (conf->topic_prefix[0] == 0))
+ return (FORMAT_VL (buf, buf_len, vl));
+
+ status = FORMAT_VL (name, sizeof (name), vl);
+ if (status != 0)
+ return (status);
+
+ status = ssnprintf (buf, buf_len, "%s/%s", conf->topic_prefix, name);
+ if ((status < 0) || (((size_t) status) >= buf_len))
+ return (ENOMEM);
+
+ return (0);
+} /* int format_topic */
+
+static int mqtt_write (const data_set_t *ds, const value_list_t *vl,
+ user_data_t *user_data)
+{
+ mqtt_client_conf_t *conf;
+ char topic[MQTT_MAX_TOPIC_SIZE];
+ char payload[MQTT_MAX_MESSAGE_SIZE];
+ int status = 0;
+
+ if ((user_data == NULL) || (user_data->data == NULL))
+ return (EINVAL);
+ conf = user_data->data;
+
+ status = format_topic (topic, sizeof (topic), ds, vl, conf);
+ if (status != 0)
+ {
+ ERROR ("mqtt plugin: format_topic failed with status %d.", status);
+ return (status);
+ }
+
+ status = format_values (payload, sizeof (payload),
+ ds, vl, conf->store_rates);
+ if (status != 0)
+ {
+ ERROR ("mqtt plugin: format_values failed with status %d.", status);
+ return (status);
+ }
+
+ status = publish (conf, topic, payload, strlen (payload) + 1);
+ if (status != 0)
+ {
+ ERROR ("mqtt plugin: publish failed: %s", mosquitto_strerror (status));
+ return (status);
+ }
+
+ return (status);
+} /* mqtt_write */
+
+/*
+ * <Publish "name">
+ * Host "example.com"
+ * Port 1883
+ * ClientId "collectd"
+ * User "guest"
+ * Password "secret"
+ * Prefix "collectd"
+ * StoreRates true
+ * Retain false
+ * QoS 0
+ * CACert "ca.pem" Enables TLS if set
+ * CertificateFile "client-cert.pem" optional
+ * CertificateKeyFile "client-key.pem" optional
+ * TLSProtocol "tlsv1.2" optional
+ * </Publish>
+ */
+static int mqtt_config_publisher (oconfig_item_t *ci)
+{
+ mqtt_client_conf_t *conf;
+ char cb_name[1024];
+ user_data_t user_data;
+ int status;
+ int i;
+
+ conf = calloc (1, sizeof (*conf));
+ if (conf == NULL)
+ {
+ ERROR ("mqtt plugin: calloc failed.");
+ return (-1);
+ }
+ conf->publish = 1;
+
+ conf->name = NULL;
+ status = cf_util_get_string (ci, &conf->name);
+ if (status != 0)
+ {
+ mqtt_free (conf);
+ return (status);
+ }
+
+ conf->host = strdup (MQTT_DEFAULT_HOST);
+ conf->port = MQTT_DEFAULT_PORT;
+ conf->client_id = NULL;
+ conf->qos = 0;
+ conf->topic_prefix = strdup (MQTT_DEFAULT_TOPIC_PREFIX);
+ conf->store_rates = 1;
+
+ status = pthread_mutex_init (&conf->lock, NULL);
+ if (status != 0)
+ {
+ mqtt_free (conf);
+ return (status);
+ }
+
+ C_COMPLAIN_INIT (&conf->complaint_cantpublish);
+
+ for (i = 0; i < ci->children_num; i++)
+ {
+ oconfig_item_t *child = ci->children + i;
+ if (strcasecmp ("Host", child->key) == 0)
+ cf_util_get_string (child, &conf->host);
+ else if (strcasecmp ("Port", child->key) == 0)
+ {
+ int tmp = cf_util_get_port_number (child);
+ if (tmp < 0)
+ ERROR ("mqtt plugin: Invalid port number.");
+ else
+ conf->port = tmp;
+ }
+ else if (strcasecmp ("ClientId", child->key) == 0)
+ cf_util_get_string (child, &conf->client_id);
+ else if (strcasecmp ("User", child->key) == 0)
+ cf_util_get_string (child, &conf->username);
+ else if (strcasecmp ("Password", child->key) == 0)
+ cf_util_get_string (child, &conf->password);
+ else if (strcasecmp ("QoS", child->key) == 0)
+ {
+ int tmp = -1;
+ status = cf_util_get_int (child, &tmp);
+ if ((status != 0) || (tmp < 0) || (tmp > 2))
+ ERROR ("mqtt plugin: Not a valid QoS setting.");
+ else
+ conf->qos = tmp;
+ }
+ else if (strcasecmp ("Prefix", child->key) == 0)
+ cf_util_get_string (child, &conf->topic_prefix);
+ else if (strcasecmp ("StoreRates", child->key) == 0)
+ cf_util_get_boolean (child, &conf->store_rates);
+ else if (strcasecmp ("Retain", child->key) == 0)
+ cf_util_get_boolean (child, &conf->retain);
+ else if (strcasecmp ("CACert", child->key) == 0)
+ cf_util_get_string (child, &conf->cacertificatefile);
+ else if (strcasecmp ("CertificateFile", child->key) == 0)
+ cf_util_get_string (child, &conf->certificatefile);
+ else if (strcasecmp ("CertificateKeyFile", child->key) == 0)
+ cf_util_get_string (child, &conf->certificatekeyfile);
+ else if (strcasecmp ("TLSProtocol", child->key) == 0)
+ cf_util_get_string (child, &conf->tlsprotocol);
+ else if (strcasecmp ("CipherSuite", child->key) == 0)
+ cf_util_get_string (child, &conf->ciphersuite);
+ else
+ ERROR ("mqtt plugin: Unknown config option: %s", child->key);
+ }
+
+ ssnprintf (cb_name, sizeof (cb_name), "mqtt/%s", conf->name);
+ memset (&user_data, 0, sizeof (user_data));
+ user_data.data = conf;
+
+ plugin_register_write (cb_name, mqtt_write, &user_data);
+ return (0);
+} /* mqtt_config_publisher */
+
+/*
+ * <Subscribe "name">
+ * Host "example.com"
+ * Port 1883
+ * ClientId "collectd"
+ * User "guest"
+ * Password "secret"
+ * Topic "collectd/#"
+ * </Subscribe>
+ */
+static int mqtt_config_subscriber (oconfig_item_t *ci)
+{
+ mqtt_client_conf_t **tmp;
+ mqtt_client_conf_t *conf;
+ int status;
+ int i;
+
+ conf = calloc (1, sizeof (*conf));
+ if (conf == NULL)
+ {
+ ERROR ("mqtt plugin: calloc failed.");
+ return (-1);
+ }
+ conf->publish = 0;
+
+ conf->name = NULL;
+ status = cf_util_get_string (ci, &conf->name);
+ if (status != 0)
+ {
+ mqtt_free (conf);
+ return (status);
+ }
+
+ conf->host = strdup (MQTT_DEFAULT_HOST);
+ conf->port = MQTT_DEFAULT_PORT;
+ conf->client_id = NULL;
+ conf->qos = 2;
+ conf->topic = strdup (MQTT_DEFAULT_TOPIC);
+ conf->clean_session = 1;
+
+ status = pthread_mutex_init (&conf->lock, NULL);
+ if (status != 0)
+ {
+ mqtt_free (conf);
+ return (status);
+ }
+
+ C_COMPLAIN_INIT (&conf->complaint_cantpublish);
+
+ for (i = 0; i < ci->children_num; i++)
+ {
+ oconfig_item_t *child = ci->children + i;
+ if (strcasecmp ("Host", child->key) == 0)
+ cf_util_get_string (child, &conf->host);
+ else if (strcasecmp ("Port", child->key) == 0)
+ {
+ status = cf_util_get_port_number (child);
+ if (status < 0)
+ ERROR ("mqtt plugin: Invalid port number.");
+ else
+ conf->port = status;
+ }
+ else if (strcasecmp ("ClientId", child->key) == 0)
+ cf_util_get_string (child, &conf->client_id);
+ else if (strcasecmp ("User", child->key) == 0)
+ cf_util_get_string (child, &conf->username);
+ else if (strcasecmp ("Password", child->key) == 0)
+ cf_util_get_string (child, &conf->password);
+ else if (strcasecmp ("QoS", child->key) == 0)
+ {
+ int qos = -1;
+ status = cf_util_get_int (child, &qos);
+ if ((status != 0) || (qos < 0) || (qos > 2))
+ ERROR ("mqtt plugin: Not a valid QoS setting.");
+ else
+ conf->qos = qos;
+ }
+ else if (strcasecmp ("Topic", child->key) == 0)
+ cf_util_get_string (child, &conf->topic);
+ else if (strcasecmp ("CleanSession", child->key) == 0)
+ cf_util_get_boolean (child, &conf->clean_session);
+ else
+ ERROR ("mqtt plugin: Unknown config option: %s", child->key);
+ }
+
+ tmp = realloc (subscribers, sizeof (*subscribers) * (subscribers_num + 1) );
+ if (tmp == NULL)
+ {
+ ERROR ("mqtt plugin: realloc failed.");
+ mqtt_free (conf);
+ return (-1);
+ }
+ subscribers = tmp;
+ subscribers[subscribers_num] = conf;
+ subscribers_num++;
+
+ return (0);
+} /* mqtt_config_subscriber */
+
+/*
+ * <Plugin mqtt>
+ * <Publish "name">
+ * # ...
+ * </Publish>
+ * <Subscribe "name">
+ * # ...
+ * </Subscribe>
+ * </Plugin>
+ */
+static int mqtt_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)
+ mqtt_config_publisher (child);
+ else if (strcasecmp ("Subscribe", child->key) == 0)
+ mqtt_config_subscriber (child);
+ else
+ ERROR ("mqtt plugin: Unknown config option: %s", child->key);
+ }
+
+ return (0);
+} /* int mqtt_config */
+
+static int mqtt_init (void)
+{
+ size_t i;
+
+ mosquitto_lib_init ();
+
+ for (i = 0; i < subscribers_num; i++)
+ {
+ int status;
+
+ if (subscribers[i]->loop)
+ continue;
+
+ status = plugin_thread_create (&subscribers[i]->thread,
+ /* attrs = */ NULL,
+ /* func = */ subscribers_thread,
+ /* args = */ subscribers[i]);
+ if (status != 0)
+ {
+ char errbuf[1024];
+ ERROR ("mqtt plugin: pthread_create failed: %s",
+ sstrerror (errno, errbuf, sizeof (errbuf)));
+ continue;
+ }
+ }
+
+ return (0);
+} /* mqtt_init */
+
+void module_register (void)
+{
+ plugin_register_complex_config ("mqtt", mqtt_config);
+ plugin_register_init ("mqtt", mqtt_init);
+} /* void module_register */
+
+/* vim: set sw=4 sts=4 et fdm=marker : */
return (-1);
}
- db = (mysql_database_t *) malloc (sizeof (*db));
+ db = calloc (1, sizeof (*db));
if (db == NULL)
{
- ERROR ("mysql plugin: malloc failed.");
+ ERROR ("mysql plugin: calloc failed.");
return (-1);
}
- memset (db, 0, sizeof (*db));
/* initialize all the pointers */
db->alias = NULL;
plugin_register_complex_read (/* group = */ NULL, cb_name,
mysql_read,
- /* interval = */ NULL, &ud);
+ /* interval = */ 0, &ud);
}
else
{
MYSQL_RES *res;
MYSQL_ROW row;
- char *query;
- int field_num;
+ const char *query;
+ int field_num;
unsigned long long position;
query = "SHOW MASTER STATUS";
MYSQL_RES *res;
MYSQL_ROW row;
- char *query;
- int field_num;
+ const char *query;
+ int field_num;
/* WTF? libmysqlclient does not seem to provide any means to
* translate a column name to a column index ... :-/ */
MYSQL_RES *res;
MYSQL_ROW row;
- char *query;
- struct {
- char *key;
- char *type;
- int ds_type;
- } metrics[] = {
- { "metadata_mem_pool_size", "bytes", DS_TYPE_GAUGE },
- { "lock_deadlocks", "mysql_locks", DS_TYPE_DERIVE },
- { "lock_timeouts", "mysql_locks", DS_TYPE_DERIVE },
- { "lock_row_lock_current_waits", "mysql_locks", DS_TYPE_DERIVE },
- { "buffer_pool_size", "bytes", DS_TYPE_GAUGE },
-
- { "buffer_pool_reads", "operations", DS_TYPE_DERIVE },
- { "buffer_pool_read_requests", "operations", DS_TYPE_DERIVE },
- { "buffer_pool_write_requests", "operations", DS_TYPE_DERIVE },
- { "buffer_pool_wait_free", "operations", DS_TYPE_DERIVE },
- { "buffer_pool_read_ahead", "operations", DS_TYPE_DERIVE },
- { "buffer_pool_read_ahead_evicted", "operations", DS_TYPE_DERIVE },
-
- { "buffer_pool_pages_total", "gauge", DS_TYPE_GAUGE },
- { "buffer_pool_pages_misc", "gauge", DS_TYPE_GAUGE },
- { "buffer_pool_pages_data", "gauge", DS_TYPE_GAUGE },
- { "buffer_pool_bytes_data", "gauge", DS_TYPE_GAUGE },
- { "buffer_pool_pages_dirty", "gauge", DS_TYPE_GAUGE },
- { "buffer_pool_bytes_dirty", "gauge", DS_TYPE_GAUGE },
- { "buffer_pool_pages_free", "gauge", DS_TYPE_GAUGE },
-
- { "buffer_pages_created", "operations", DS_TYPE_DERIVE },
- { "buffer_pages_written", "operations", DS_TYPE_DERIVE },
- { "buffer_pages_read", "operations", DS_TYPE_DERIVE },
- { "buffer_data_reads", "operations", DS_TYPE_DERIVE },
- { "buffer_data_written", "operations", DS_TYPE_DERIVE },
-
- { "os_data_reads", "operations", DS_TYPE_DERIVE },
- { "os_data_writes", "operations", DS_TYPE_DERIVE },
- { "os_data_fsyncs", "operations", DS_TYPE_DERIVE },
- { "os_log_bytes_written", "operations", DS_TYPE_DERIVE },
- { "os_log_fsyncs", "operations", DS_TYPE_DERIVE },
- { "os_log_pending_fsyncs", "operations", DS_TYPE_DERIVE },
- { "os_log_pending_writes", "operations", DS_TYPE_DERIVE },
-
- { "trx_rseg_history_len", "gauge", DS_TYPE_GAUGE },
-
- { "log_waits", "operations", DS_TYPE_DERIVE },
- { "log_write_requests", "operations", DS_TYPE_DERIVE },
- { "log_writes", "operations", DS_TYPE_DERIVE },
- { "adaptive_hash_searches", "operations", DS_TYPE_DERIVE },
-
- { "file_num_open_files", "gauge", DS_TYPE_GAUGE },
-
- { "ibuf_merges_insert", "operations", DS_TYPE_DERIVE },
- { "ibuf_merges_delete_mark", "operations", DS_TYPE_DERIVE },
- { "ibuf_merges_delete", "operations", DS_TYPE_DERIVE },
- { "ibuf_merges_discard_insert", "operations", DS_TYPE_DERIVE },
- { "ibuf_merges_discard_delete_mark","operations", DS_TYPE_DERIVE },
- { "ibuf_merges_discard_delete", "operations", DS_TYPE_DERIVE },
- { "ibuf_merges_discard_merges", "operations", DS_TYPE_DERIVE },
- { "ibuf_size", "bytes", DS_TYPE_GAUGE },
-
- { "innodb_activity_count", "gauge", DS_TYPE_GAUGE },
- { "innodb_dblwr_writes", "operations", DS_TYPE_DERIVE },
- { "innodb_dblwr_pages_written", "operations", DS_TYPE_DERIVE },
- { "innodb_dblwr_page_size", "gauge", DS_TYPE_GAUGE },
-
- { "innodb_rwlock_s_spin_waits", "operations", DS_TYPE_DERIVE },
- { "innodb_rwlock_x_spin_waits", "operations", DS_TYPE_DERIVE },
- { "innodb_rwlock_s_spin_rounds", "operations", DS_TYPE_DERIVE },
- { "innodb_rwlock_x_spin_rounds", "operations", DS_TYPE_DERIVE },
- { "innodb_rwlock_s_os_waits", "operations", DS_TYPE_DERIVE },
- { "innodb_rwlock_x_os_waits", "operations", DS_TYPE_DERIVE },
-
- { "dml_reads", "operations", DS_TYPE_DERIVE },
- { "dml_inserts", "operations", DS_TYPE_DERIVE },
- { "dml_deletes", "operations", DS_TYPE_DERIVE },
- { "dml_updates", "operations", DS_TYPE_DERIVE },
-
- { NULL, NULL, 0}
- };
+ const char *query;
+ struct {
+ const char *key;
+ const char *type;
+ int ds_type;
+ } metrics[] = {
+ { "metadata_mem_pool_size", "bytes", DS_TYPE_GAUGE },
+ { "lock_deadlocks", "mysql_locks", DS_TYPE_DERIVE },
+ { "lock_timeouts", "mysql_locks", DS_TYPE_DERIVE },
+ { "lock_row_lock_current_waits", "mysql_locks", DS_TYPE_DERIVE },
+ { "buffer_pool_size", "bytes", DS_TYPE_GAUGE },
+
+ { "buffer_pool_reads", "operations", DS_TYPE_DERIVE },
+ { "buffer_pool_read_requests", "operations", DS_TYPE_DERIVE },
+ { "buffer_pool_write_requests", "operations", DS_TYPE_DERIVE },
+ { "buffer_pool_wait_free", "operations", DS_TYPE_DERIVE },
+ { "buffer_pool_read_ahead", "operations", DS_TYPE_DERIVE },
+ { "buffer_pool_read_ahead_evicted", "operations", DS_TYPE_DERIVE },
+
+ { "buffer_pool_pages_total", "gauge", DS_TYPE_GAUGE },
+ { "buffer_pool_pages_misc", "gauge", DS_TYPE_GAUGE },
+ { "buffer_pool_pages_data", "gauge", DS_TYPE_GAUGE },
+ { "buffer_pool_bytes_data", "gauge", DS_TYPE_GAUGE },
+ { "buffer_pool_pages_dirty", "gauge", DS_TYPE_GAUGE },
+ { "buffer_pool_bytes_dirty", "gauge", DS_TYPE_GAUGE },
+ { "buffer_pool_pages_free", "gauge", DS_TYPE_GAUGE },
+
+ { "buffer_pages_created", "operations", DS_TYPE_DERIVE },
+ { "buffer_pages_written", "operations", DS_TYPE_DERIVE },
+ { "buffer_pages_read", "operations", DS_TYPE_DERIVE },
+ { "buffer_data_reads", "operations", DS_TYPE_DERIVE },
+ { "buffer_data_written", "operations", DS_TYPE_DERIVE },
+
+ { "os_data_reads", "operations", DS_TYPE_DERIVE },
+ { "os_data_writes", "operations", DS_TYPE_DERIVE },
+ { "os_data_fsyncs", "operations", DS_TYPE_DERIVE },
+ { "os_log_bytes_written", "operations", DS_TYPE_DERIVE },
+ { "os_log_fsyncs", "operations", DS_TYPE_DERIVE },
+ { "os_log_pending_fsyncs", "operations", DS_TYPE_DERIVE },
+ { "os_log_pending_writes", "operations", DS_TYPE_DERIVE },
+
+ { "trx_rseg_history_len", "gauge", DS_TYPE_GAUGE },
+
+ { "log_waits", "operations", DS_TYPE_DERIVE },
+ { "log_write_requests", "operations", DS_TYPE_DERIVE },
+ { "log_writes", "operations", DS_TYPE_DERIVE },
+ { "adaptive_hash_searches", "operations", DS_TYPE_DERIVE },
+
+ { "file_num_open_files", "gauge", DS_TYPE_GAUGE },
+
+ { "ibuf_merges_insert", "operations", DS_TYPE_DERIVE },
+ { "ibuf_merges_delete_mark", "operations", DS_TYPE_DERIVE },
+ { "ibuf_merges_delete", "operations", DS_TYPE_DERIVE },
+ { "ibuf_merges_discard_insert", "operations", DS_TYPE_DERIVE },
+ { "ibuf_merges_discard_delete_mark", "operations", DS_TYPE_DERIVE },
+ { "ibuf_merges_discard_delete", "operations", DS_TYPE_DERIVE },
+ { "ibuf_merges_discard_merges", "operations", DS_TYPE_DERIVE },
+ { "ibuf_size", "bytes", DS_TYPE_GAUGE },
+
+ { "innodb_activity_count", "gauge", DS_TYPE_GAUGE },
+ { "innodb_dblwr_writes", "operations", DS_TYPE_DERIVE },
+ { "innodb_dblwr_pages_written", "operations", DS_TYPE_DERIVE },
+ { "innodb_dblwr_page_size", "gauge", DS_TYPE_GAUGE },
+
+ { "innodb_rwlock_s_spin_waits", "operations", DS_TYPE_DERIVE },
+ { "innodb_rwlock_x_spin_waits", "operations", DS_TYPE_DERIVE },
+ { "innodb_rwlock_s_spin_rounds", "operations", DS_TYPE_DERIVE },
+ { "innodb_rwlock_x_spin_rounds", "operations", DS_TYPE_DERIVE },
+ { "innodb_rwlock_s_os_waits", "operations", DS_TYPE_DERIVE },
+ { "innodb_rwlock_x_os_waits", "operations", DS_TYPE_DERIVE },
+
+ { "dml_reads", "operations", DS_TYPE_DERIVE },
+ { "dml_inserts", "operations", DS_TYPE_DERIVE },
+ { "dml_deletes", "operations", DS_TYPE_DERIVE },
+ { "dml_updates", "operations", DS_TYPE_DERIVE },
+
+ { NULL, NULL, 0}
+ };
query = "SELECT name, count, type FROM information_schema.innodb_metrics WHERE status = 'enabled'";
while ((row = mysql_fetch_row (res)))
{
- int i;
+ int i;
char *key;
unsigned long long val;
key = row[0];
val = atoll (row[1]);
- for (i = 0;
- metrics[i].key != NULL && strcmp(metrics[i].key, key) != 0;
- i++)
- ;
-
- if (metrics[i].key == NULL)
- continue;
-
- switch (metrics[i].ds_type) {
- case DS_TYPE_COUNTER:
- counter_submit(metrics[i].type, key, (counter_t)val, db);
- break;
- case DS_TYPE_GAUGE:
- gauge_submit(metrics[i].type, key, (gauge_t)val, db);
- break;
- case DS_TYPE_DERIVE:
- derive_submit(metrics[i].type, key, (derive_t)val, db);
- break;
- }
- }
-
- mysql_free_result(res);
- return (0);
+ for (i = 0; metrics[i].key != NULL && strcmp(metrics[i].key, key) != 0; i++)
+ ;
+
+ if (metrics[i].key == NULL)
+ continue;
+
+ switch (metrics[i].ds_type) {
+ case DS_TYPE_COUNTER:
+ counter_submit(metrics[i].type, key, (counter_t)val, db);
+ break;
+ case DS_TYPE_GAUGE:
+ gauge_submit(metrics[i].type, key, (gauge_t)val, db);
+ break;
+ case DS_TYPE_DERIVE:
+ derive_submit(metrics[i].type, key, (derive_t)val, db);
+ break;
+ }
+ }
+
+ mysql_free_result(res);
+ return (0);
}
static int mysql_read (user_data_t *ud)
{
mysql_database_t *db;
- MYSQL *con;
- MYSQL_RES *res;
- MYSQL_ROW row;
- char *query;
+ MYSQL *con;
+ MYSQL_RES *res;
+ MYSQL_ROW row;
+ const char *query;
derive_t qcache_hits = 0;
derive_t qcache_inserts = 0;
unsigned long long traffic_incoming = 0ULL;
unsigned long long traffic_outgoing = 0ULL;
- unsigned long mysql_version = 0ULL;
+ unsigned long mysql_version = 0ULL;
if ((ud == NULL) || (ud->data == NULL))
{
if ((con = getconnection (db)) == NULL)
return (-1);
- mysql_version = mysql_get_server_version(con);
+ mysql_version = mysql_get_server_version(con);
query = "SHOW STATUS";
if (mysql_version >= 50002)
key = row[0];
val = atoll (row[1]);
- if (strncmp (key, "Com_",
+ if (strncmp (key, "Com_",
strlen ("Com_")) == 0)
{
if (val == 0ULL)
/* Ignore `prepared statements' */
if (strncmp (key, "Com_stmt_", strlen ("Com_stmt_")) != 0)
- counter_submit ("mysql_commands",
- key + strlen ("Com_"),
+ counter_submit ("mysql_commands",
+ key + strlen ("Com_"),
val, db);
}
- else if (strncmp (key, "Handler_",
+ else if (strncmp (key, "Handler_",
strlen ("Handler_")) == 0)
{
if (val == 0ULL)
continue;
- counter_submit ("mysql_handler",
- key + strlen ("Handler_"),
+ counter_submit ("mysql_handler",
+ key + strlen ("Handler_"),
val, db);
}
else if (strncmp (key, "Qcache_",
else if (strcmp (key, "Qcache_queries_in_cache") == 0)
qcache_queries_in_cache = (gauge_t) val;
}
- else if (strncmp (key, "Bytes_",
+ else if (strncmp (key, "Bytes_",
strlen ("Bytes_")) == 0)
{
if (strcmp (key, "Bytes_received") == 0)
else if (strcmp (key, "Bytes_sent") == 0)
traffic_outgoing += val;
}
- else if (strncmp (key, "Threads_",
+ else if (strncmp (key, "Threads_",
strlen ("Threads_")) == 0)
{
if (strcmp (key, "Threads_running") == 0)
}
else if (strncmp (key, "Sort_", strlen ("Sort_")) == 0)
{
- counter_submit ("mysql_sort", key + strlen ("Sort_"),
- val, db);
+ if (strcmp (key, "Sort_merge_passes") == 0)
+ counter_submit ("mysql_sort_merge_passes", NULL, val, db);
+ else if (strcmp (key, "Sort_rows") == 0)
+ counter_submit ("mysql_sort_rows", NULL, val, db);
+ else if (strcmp (key, "Sort_range") == 0)
+ counter_submit ("mysql_sort", "range", val, db);
+ else if (strcmp (key, "Sort_scan") == 0)
+ counter_submit ("mysql_sort", "scan", val, db);
+
}
}
mysql_free_result (res); res = NULL;
traffic_submit (traffic_incoming, traffic_outgoing, db);
if (mysql_version >= 50600 && db->innodb_stats)
- mysql_read_innodb_stats (db, con);
+ mysql_read_innodb_stats (db, con);
if (db->master_stats)
mysql_read_master_stats (db, con);
return d;
}
- d = malloc(sizeof(*d));
+ d = calloc (1, sizeof (*d));
if (d == NULL)
return (NULL);
- memset (d, 0, sizeof (*d));
d->next = NULL;
d->name = strdup(name);
return (NULL);
/* Not found: allocate. */
- new = malloc (sizeof (*new));
+ new = calloc (1, sizeof (*new));
if (new == NULL)
return (NULL);
- memset (new, 0, sizeof (*new));
new->next = NULL;
new->name = strdup (name);
return (NULL);
/* Not found: allocate. */
- new = malloc (sizeof (*new));
+ new = calloc (1, sizeof (*new));
if (new == NULL)
return (NULL);
- memset (new, 0, sizeof (*new));
new->next = NULL;
new->name = strdup (name);
} /* }}} cdtime_t cna_child_get_cdtime */
-/*
+/*
* Query functions
*
* These functions are called with appropriate data returned by the libnetapp
na_elem_iter_t counter_iter;
memset (&perf_data, 0, sizeof (perf_data));
-
+
perf_data.timestamp = cna_child_get_cdtime (data);
instances = na_elem_child(na_elem_child (data, "instances"), "instance-data");
if ((cfg_disk == NULL) || (data == NULL))
return (EINVAL);
-
+
timestamp = cna_child_get_cdtime (data);
instances = na_elem_child (data, "instances");
na_elem_t *elem_instances;
na_elem_iter_t iter_instances;
na_elem_t *elem_instance;
-
+
timestamp = cna_child_get_cdtime (data);
elem_instances = na_elem_child(data, "instances");
if ((v->flags & CFG_VOLUME_USAGE_SNAP) != 0)
cna_handle_volume_snap_usage(host, v);
-
+
if ((v->flags & CFG_VOLUME_USAGE_DF) == 0)
continue;
const char *instance;
cdtime_t timestamp;
-
+
timestamp = cna_child_get_cdtime (data);
instances = na_elem_child(na_elem_child (data, "instances"), "instance-data");
&& (HAS_ALL_FLAGS (counter_flags, 0x01 | 0x02)))
submit_two_derive (hostname, instance, "disk_octets", NULL,
disk_read, disk_written, timestamp, interval);
-
+
if ((cfg_system->flags & CFG_SYSTEM_NET)
&& (HAS_ALL_FLAGS (counter_flags, 0x04 | 0x08)))
submit_two_derive (hostname, instance, "if_octets", NULL,
if (host->cfg_volume_perf == NULL)
{
- cfg_volume_perf = malloc (sizeof (*cfg_volume_perf));
+ cfg_volume_perf = calloc (1, sizeof (*cfg_volume_perf));
if (cfg_volume_perf == NULL)
return (ENOMEM);
- memset (cfg_volume_perf, 0, sizeof (*cfg_volume_perf));
/* Set default flags */
cfg_volume_perf->query = NULL;
host->cfg_volume_perf = cfg_volume_perf;
}
cfg_volume_perf = host->cfg_volume_perf;
-
+
for (i = 0; i < ci->children_num; ++i) {
oconfig_item_t *item = ci->children + i;
-
+
/* if (!item || !item->key || !*item->key) continue; */
if (strcasecmp(item->key, "Interval") == 0)
cna_config_get_interval (item, &cfg_volume_perf->interval);
if (host->cfg_quota == NULL)
{
- cfg_quota = malloc (sizeof (*cfg_quota));
+ cfg_quota = calloc (1, sizeof (*cfg_quota));
if (cfg_quota == NULL)
return (ENOMEM);
- memset (cfg_quota, 0, sizeof (*cfg_quota));
cfg_quota->query = NULL;
host->cfg_quota = cfg_quota;
if (host->cfg_disk == NULL)
{
- cfg_disk = malloc (sizeof (*cfg_disk));
+ cfg_disk = calloc (1, sizeof (*cfg_disk));
if (cfg_disk == NULL)
return (ENOMEM);
- memset (cfg_disk, 0, sizeof (*cfg_disk));
/* Set default flags */
cfg_disk->flags = CFG_DISK_ALL;
host->cfg_disk = cfg_disk;
}
cfg_disk = host->cfg_disk;
-
+
for (i = 0; i < ci->children_num; ++i) {
oconfig_item_t *item = ci->children + i;
-
+
/* if (!item || !item->key || !*item->key) continue; */
if (strcasecmp(item->key, "Interval") == 0)
cna_config_get_interval (item, &cfg_disk->interval);
if (host->cfg_wafl == NULL)
{
- cfg_wafl = malloc (sizeof (*cfg_wafl));
+ cfg_wafl = calloc (1, sizeof (*cfg_wafl));
if (cfg_wafl == NULL)
return (ENOMEM);
- memset (cfg_wafl, 0, sizeof (*cfg_wafl));
/* Set default flags */
cfg_wafl->flags = CFG_WAFL_ALL;
for (i = 0; i < ci->children_num; ++i) {
oconfig_item_t *item = ci->children + i;
-
+
if (strcasecmp(item->key, "Interval") == 0)
cna_config_get_interval (item, &cfg_wafl->interval);
else if (!strcasecmp(item->key, "GetNameCache"))
if (host->cfg_volume_usage == NULL)
{
- cfg_volume_usage = malloc (sizeof (*cfg_volume_usage));
+ cfg_volume_usage = calloc (1, sizeof (*cfg_volume_usage));
if (cfg_volume_usage == NULL)
return (ENOMEM);
- memset (cfg_volume_usage, 0, sizeof (*cfg_volume_usage));
/* Set default flags */
cfg_volume_usage->query = NULL;
host->cfg_volume_usage = cfg_volume_usage;
}
cfg_volume_usage = host->cfg_volume_usage;
-
+
for (i = 0; i < ci->children_num; ++i) {
oconfig_item_t *item = ci->children + i;
-
+
/* if (!item || !item->key || !*item->key) continue; */
if (strcasecmp(item->key, "Interval") == 0)
cna_config_get_interval (item, &cfg_volume_usage->interval);
if (host->cfg_snapvault == NULL)
{
- cfg_snapvault = malloc (sizeof (*cfg_snapvault));
+ cfg_snapvault = calloc (1, sizeof (*cfg_snapvault));
if (cfg_snapvault == NULL)
return ENOMEM;
- memset (cfg_snapvault, 0, sizeof (*cfg_snapvault));
cfg_snapvault->query = NULL;
host->cfg_snapvault = cfg_snapvault;
{
cfg_system_t *cfg_system;
int i;
-
+
if ((host == NULL) || (ci == NULL))
return (EINVAL);
if (host->cfg_system == NULL)
{
- cfg_system = malloc (sizeof (*cfg_system));
+ cfg_system = calloc (1, sizeof (*cfg_system));
if (cfg_system == NULL)
return (ENOMEM);
- memset (cfg_system, 0, sizeof (*cfg_system));
/* Set default flags */
cfg_system->flags = CFG_SYSTEM_ALL;
{
host_config_t *host;
- host = malloc(sizeof(*host));
- if (! host)
+ host = calloc (1, sizeof (*host));
+ if (host == NULL)
return (NULL);
- memset (host, 0, sizeof (*host));
host->name = NULL;
host->protocol = NA_SERVER_TRANSPORT_HTTPS;
static int cna_register_host (host_config_t *host) /* {{{ */
{
char cb_name[256];
- struct timespec interval;
user_data_t ud;
if (host->vfiler)
else
ssnprintf (cb_name, sizeof (cb_name), "netapp-%s", host->name);
- CDTIME_T_TO_TIMESPEC (host->interval, &interval);
-
memset (&ud, 0, sizeof (ud));
ud.data = host;
ud.free_func = (void (*) (void *)) free_host_config;
plugin_register_complex_read (/* group = */ NULL, cb_name,
/* callback = */ cna_read,
- /* interval = */ (host->interval > 0) ? &interval : NULL,
+ /* interval = */ host->interval,
/* user data = */ &ud);
return (0);
#include "common.h"
#include <asm/types.h>
-#include <sys/socket.h>
#include <linux/netlink.h>
#include <linux/rtnetlink.h>
{
ir_ignorelist_t *entry;
- entry = (ir_ignorelist_t *) malloc (sizeof (ir_ignorelist_t));
+ entry = calloc (1, sizeof (*entry));
if (entry == NULL)
return (-1);
- memset (entry, '\0', sizeof (ir_ignorelist_t));
-
if (strcasecmp (dev, "All") != 0)
{
entry->device = strdup (dev);
{
char **temp;
- temp = (char **) realloc (iflist, (msg->ifi_index + 1) * sizeof (char *));
+ temp = realloc (iflist, (msg->ifi_index + 1) * sizeof (char *));
if (temp == NULL)
{
ERROR ("netlink plugin: update_iflist: realloc failed.");
const char *kind = NULL;
/* char *type_instance; */
- char *tc_type;
+ const char *tc_type;
char tc_inst[DATA_MAX_NAME_LEN];
_Bool stats_submitted = 0;
#if HAVE_PTHREAD_H
# include <pthread.h>
#endif
-#if HAVE_SYS_SOCKET_H
-# include <sys/socket.h>
-#endif
#if HAVE_NETDB_H
# include <netdb.h>
#endif
static int network_config_ttl = 0;
/* Ethernet - (IPv6 + UDP) = 1500 - (40 + 8) = 1452 */
static size_t network_config_packet_size = 1452;
-static int network_config_forward = 0;
-static int network_config_stats = 0;
+static _Bool network_config_forward = 0;
+static _Bool network_config_stats = 0;
static sockent_t *sending_sockets = NULL;
static char *send_buffer;
static char *send_buffer_ptr;
static int send_buffer_fill;
+static cdtime_t send_buffer_last_update;
static value_list_t send_buffer_vl = VALUE_LIST_STATIC;
static pthread_mutex_t send_buffer_lock = PTHREAD_MUTEX_INITIALIZER;
_Bool received = 0;
int status;
- if (network_config_forward != 0)
+ if (network_config_forward)
return (1);
if (vl->meta == NULL)
if (*ret_buffer_len < packet_len)
return (-1);
- pkg_values_types = (uint8_t *) malloc (num_values * sizeof (uint8_t));
+ pkg_values_types = malloc (num_values * sizeof (*pkg_values_types));
if (pkg_values_types == NULL)
{
ERROR ("network plugin: write_part_values: malloc failed.");
return (-1);
}
- pkg_values = (value_t *) malloc (num_values * sizeof (value_t));
+ pkg_values = malloc (num_values * sizeof (*pkg_values));
if (pkg_values == NULL)
{
free (pkg_values_types);
} /* int write_part_string */
static int parse_part_values (void **ret_buffer, size_t *ret_buffer_len,
- value_t **ret_values, int *ret_num_values)
+ value_t **ret_values, size_t *ret_num_values)
{
char *buffer = *ret_buffer;
size_t buffer_len = *ret_buffer_len;
uint16_t tmp16;
size_t exp_size;
- int i;
+ size_t i;
uint16_t pkg_length;
uint16_t pkg_type;
- uint16_t pkg_numval;
+ size_t pkg_numval;
uint8_t *pkg_types;
value_t *pkg_values;
memcpy ((void *) &tmp16, buffer, sizeof (tmp16));
buffer += sizeof (tmp16);
- pkg_numval = ntohs (tmp16);
+ pkg_numval = (size_t) ntohs (tmp16);
assert (pkg_type == TYPE_VALUES);
exp_size, buffer_len);
return (-1);
}
+ assert (pkg_numval <= ((buffer_len - 6) / 9));
if (pkg_length != exp_size)
{
return (-1);
}
- pkg_types = (uint8_t *) malloc (pkg_numval * sizeof (uint8_t));
- pkg_values = (value_t *) malloc (pkg_numval * sizeof (value_t));
+ pkg_types = calloc (pkg_numval, sizeof (*pkg_types));
+ pkg_values = calloc (pkg_numval, sizeof (*pkg_values));
if ((pkg_types == NULL) || (pkg_values == NULL))
{
sfree (pkg_types);
sfree (pkg_values);
- ERROR ("network plugin: parse_part_values: malloc failed.");
+ ERROR ("network plugin: parse_part_values: calloc failed.");
return (-1);
}
- memcpy ((void *) pkg_types, (void *) buffer, pkg_numval * sizeof (uint8_t));
- buffer += pkg_numval * sizeof (uint8_t);
- memcpy ((void *) pkg_values, (void *) buffer, pkg_numval * sizeof (value_t));
- buffer += pkg_numval * sizeof (value_t);
+ memcpy (pkg_types, buffer, pkg_numval * sizeof (*pkg_types));
+ buffer += pkg_numval * sizeof (*pkg_types);
+ memcpy (pkg_values, buffer, pkg_numval * sizeof (*pkg_values));
+ buffer += pkg_numval * sizeof (*pkg_values);
for (i = 0; i < pkg_numval; i++)
{
uint16_t pkg_length;
size_t payload_size;
- if (output_len <= 0)
+ if (output_len == 0)
return (EINVAL);
if (buffer_len < header_size)
warning_has_been_printed = 1;
}
- *ret_buffer += ph_length;
+ *ret_buffer = (void *) (((char *) *ret_buffer) + ph_length);
*ret_buffer_size -= ph_length;
return (0);
(void *) buffer,
sizeof (pkg_type));
memcpy ((void *) &pkg_length,
- (void *) (buffer + sizeof (pkg_type)),
+ (void *) (((char *) buffer) + sizeof (pkg_type)),
sizeof (pkg_length));
pkg_length = ntohs (pkg_length);
if ((type != SOCKENT_TYPE_CLIENT) && (type != SOCKENT_TYPE_SERVER))
return (NULL);
- se = malloc (sizeof (*se));
+ se = calloc (1, sizeof (*se));
if (se == NULL)
return (NULL);
- memset (se, 0, sizeof (*se));
se->type = type;
se->node = NULL;
continue;
}
- client->addr = malloc (sizeof (*client->addr));
+ client->addr = calloc (1, sizeof (*client->addr));
if (client->addr == NULL)
{
- ERROR ("network plugin: malloc failed.");
+ ERROR ("network plugin: calloc failed.");
close (client->fd);
client->fd = -1;
continue;
}
- memset (client->addr, 0, sizeof (*client->addr));
assert (sizeof (*client->addr) >= ai_ptr->ai_addrlen);
memcpy (client->addr, ai_ptr->ai_addr, ai_ptr->ai_addrlen);
client->addrlen = ai_ptr->ai_addrlen;
freeaddrinfo (ai_list);
- if (se->data.server.fd_num <= 0)
+ if (se->data.server.fd_num == 0)
return (-1);
return (0);
} /* }}} int sockent_server_listen */
char buffer[network_config_packet_size];
int buffer_len;
- int i;
+ size_t i;
int status = 0;
receive_list_entry_t *private_list_head;
* these entries in the dispatch thread but put them in
* another list, so we don't have to allocate more and
* more of these structures. */
- ent = malloc (sizeof (receive_list_entry_t));
+ ent = calloc (1, sizeof (*ent));
if (ent == NULL)
{
- ERROR ("network plugin: malloc failed.");
+ ERROR ("network plugin: calloc failed.");
status = ENOMEM;
break;
}
- memset (ent, 0, sizeof (receive_list_entry_t));
+
ent->data = malloc (network_config_packet_size);
if (ent->data == NULL)
{
memset (send_buffer, 0, network_config_packet_size);
send_buffer_ptr = send_buffer;
send_buffer_fill = 0;
+ send_buffer_last_update = 0;
memset (&send_buffer_vl, 0, sizeof (send_buffer_vl));
} /* int network_init_buffer */
-static void networt_send_buffer_plain (sockent_t *se, /* {{{ */
+static void network_send_buffer_plain (sockent_t *se, /* {{{ */
const char *buffer, size_t buffer_size)
{
int status;
break;
} /* while (42) */
-} /* }}} void networt_send_buffer_plain */
+} /* }}} void network_send_buffer_plain */
#if HAVE_LIBGCRYPT
#define BUFFER_ADD(p,s) do { \
buffer_offset += (s); \
} while (0)
-static void networt_send_buffer_signed (sockent_t *se, /* {{{ */
+static void network_send_buffer_signed (sockent_t *se, /* {{{ */
const char *in_buffer, size_t in_buffer_size)
{
part_signature_sha256_t ps;
hd = NULL;
buffer_offset = PART_SIGNATURE_SHA256_SIZE + username_len + in_buffer_size;
- networt_send_buffer_plain (se, buffer, buffer_offset);
-} /* }}} void networt_send_buffer_signed */
+ network_send_buffer_plain (se, buffer, buffer_offset);
+} /* }}} void network_send_buffer_signed */
-static void networt_send_buffer_encrypted (sockent_t *se, /* {{{ */
+static void network_send_buffer_encrypted (sockent_t *se, /* {{{ */
const char *in_buffer, size_t in_buffer_size)
{
part_encryption_aes256_t pea;
- sizeof (pea.hash);
assert (buffer_size <= sizeof (buffer));
- DEBUG ("network plugin: networt_send_buffer_encrypted: "
+ DEBUG ("network plugin: network_send_buffer_encrypted: "
"buffer_size = %zu;", buffer_size);
pea.head.length = htons ((uint16_t) (PART_ENCRYPTION_AES256_SIZE
}
/* Send it out without further modifications */
- networt_send_buffer_plain (se, buffer, buffer_size);
-} /* }}} void networt_send_buffer_encrypted */
+ network_send_buffer_plain (se, buffer, buffer_size);
+} /* }}} void network_send_buffer_encrypted */
#undef BUFFER_ADD
#endif /* HAVE_LIBGCRYPT */
{
#if HAVE_LIBGCRYPT
if (se->data.client.security_level == SECURITY_LEVEL_ENCRYPT)
- networt_send_buffer_encrypted (se, buffer, buffer_len);
+ network_send_buffer_encrypted (se, buffer, buffer_len);
else if (se->data.client.security_level == SECURITY_LEVEL_SIGN)
- networt_send_buffer_signed (se, buffer, buffer_len);
+ network_send_buffer_signed (se, buffer, buffer_len);
else /* if (se->data.client.security_level == SECURITY_LEVEL_NONE) */
#endif /* HAVE_LIBGCRYPT */
- networt_send_buffer_plain (se, buffer, buffer_len);
+ network_send_buffer_plain (se, buffer, buffer_len);
} /* for (sending_sockets) */
} /* }}} void network_send_buffer */
/* status == bytes added to the buffer */
send_buffer_fill += status;
send_buffer_ptr += status;
+ send_buffer_last_update = cdtime();
stats_values_sent++;
}
return ((status < 0) ? -1 : 0);
} /* int network_write */
-static int network_config_set_boolean (const oconfig_item_t *ci, /* {{{ */
- int *retval)
-{
- if ((ci->values_num != 1)
- || ((ci->values[0].type != OCONFIG_TYPE_BOOLEAN)
- && (ci->values[0].type != OCONFIG_TYPE_STRING)))
- {
- ERROR ("network 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)
- *retval = 1;
- else
- *retval = 0;
- }
- else
- {
- char *str = ci->values[0].value.string;
-
- if (IS_TRUE (str))
- *retval = 1;
- else if (IS_FALSE (str))
- *retval = 0;
- else
- {
- ERROR ("network plugin: Cannot parse string value `%s' of the `%s' "
- "option as boolean value.",
- str, ci->key);
- return (-1);
- }
- }
-
- return (0);
-} /* }}} int network_config_set_boolean */
-
static int network_config_set_ttl (const oconfig_item_t *ci) /* {{{ */
{
- int tmp;
- if ((ci->values_num != 1)
- || (ci->values[0].type != OCONFIG_TYPE_NUMBER))
- {
- WARNING ("network plugin: The `TimeToLive' config option needs exactly "
- "one numeric argument.");
- return (-1);
- }
+ int tmp = 0;
- tmp = (int) ci->values[0].value.number;
- if ((tmp > 0) && (tmp <= 255))
+ if (cf_util_get_int (ci, &tmp) != 0)
+ return (-1);
+ else if ((tmp > 0) && (tmp <= 255))
network_config_ttl = tmp;
else {
WARNING ("network plugin: The `TimeToLive' must be between 1 and 255.");
static int network_config_set_interface (const oconfig_item_t *ci, /* {{{ */
int *interface)
{
- if ((ci->values_num != 1)
- || (ci->values[0].type != OCONFIG_TYPE_STRING))
- {
- WARNING ("network plugin: The `Interface' config option needs exactly "
- "one string argument.");
- return (-1);
- }
+ char if_name[256];
- if (interface == NULL)
+ if (cf_util_get_string_buffer (ci, if_name, sizeof (if_name)) != 0)
return (-1);
- *interface = if_nametoindex (ci->values[0].value.string);
-
+ *interface = if_nametoindex (if_name);
return (0);
} /* }}} int network_config_set_interface */
static int network_config_set_buffer_size (const oconfig_item_t *ci) /* {{{ */
{
- int tmp;
- if ((ci->values_num != 1)
- || (ci->values[0].type != OCONFIG_TYPE_NUMBER))
- {
- WARNING ("network plugin: The `MaxPacketSize' config option needs exactly "
- "one numeric argument.");
- return (-1);
- }
+ int tmp = 0;
- tmp = (int) ci->values[0].value.number;
- if ((tmp >= 1024) && (tmp <= 65535))
+ if (cf_util_get_int (ci, &tmp) != 0)
+ return (-1);
+ else if ((tmp >= 1024) && (tmp <= 65535))
network_config_packet_size = tmp;
-
- return (0);
-} /* }}} int network_config_set_buffer_size */
-
-#if HAVE_LIBGCRYPT
-static int network_config_set_string (const oconfig_item_t *ci, /* {{{ */
- char **ret_string)
-{
- char *tmp;
- if ((ci->values_num != 1)
- || (ci->values[0].type != OCONFIG_TYPE_STRING))
- {
- WARNING ("network plugin: The `%s' config option needs exactly "
- "one string argument.", ci->key);
+ else {
+ WARNING ("network plugin: The `MaxPacketSize' must be between 1024 and 65535.");
return (-1);
}
- tmp = strdup (ci->values[0].value.string);
- if (tmp == NULL)
- return (-1);
-
- sfree (*ret_string);
- *ret_string = tmp;
-
return (0);
-} /* }}} int network_config_set_string */
-#endif /* HAVE_LIBGCRYPT */
+} /* }}} int network_config_set_buffer_size */
#if HAVE_LIBGCRYPT
static int network_config_set_security_level (oconfig_item_t *ci, /* {{{ */
#if HAVE_LIBGCRYPT
if (strcasecmp ("AuthFile", child->key) == 0)
- network_config_set_string (child, &se->data.server.auth_file);
+ cf_util_get_string (child, &se->data.server.auth_file);
else if (strcasecmp ("SecurityLevel", child->key) == 0)
network_config_set_security_level (child,
&se->data.server.security_level);
else
#endif /* HAVE_LIBGCRYPT */
if (strcasecmp ("Interface", child->key) == 0)
- network_config_set_interface (child,
- &se->interface);
+ network_config_set_interface (child, &se->interface);
else
{
WARNING ("network plugin: Option `%s' is not allowed here.",
status = sockent_server_listen (se);
if (status != 0)
{
- ERROR ("network plugin: network_config_add_server: sockent_server_listen failed.");
+ ERROR ("network plugin: network_config_add_listen: sockent_server_listen failed.");
sockent_destroy (se);
return (-1);
}
#if HAVE_LIBGCRYPT
if (strcasecmp ("Username", child->key) == 0)
- network_config_set_string (child, &se->data.client.username);
+ cf_util_get_string (child, &se->data.client.username);
else if (strcasecmp ("Password", child->key) == 0)
- network_config_set_string (child, &se->data.client.password);
+ cf_util_get_string (child, &se->data.client.password);
else if (strcasecmp ("SecurityLevel", child->key) == 0)
network_config_set_security_level (child,
&se->data.client.security_level);
else
#endif /* HAVE_LIBGCRYPT */
if (strcasecmp ("Interface", child->key) == 0)
- network_config_set_interface (child,
- &se->interface);
- else if (strcasecmp ("ResolveInterval", child->key) == 0)
- cf_util_get_cdtime(child, &se->data.client.resolve_interval);
+ network_config_set_interface (child, &se->interface);
+ else if (strcasecmp ("ResolveInterval", child->key) == 0)
+ cf_util_get_cdtime(child, &se->data.client.resolve_interval);
else
{
WARNING ("network plugin: Option `%s' is not allowed here.",
}
/* No call to sockent_client_connect() here -- it is called from
- * networt_send_buffer_plain(). */
+ * network_send_buffer_plain(). */
status = sockent_add (se);
if (status != 0)
else if (strcasecmp ("MaxPacketSize", child->key) == 0)
network_config_set_buffer_size (child);
else if (strcasecmp ("Forward", child->key) == 0)
- network_config_set_boolean (child, &network_config_forward);
+ cf_util_get_boolean (child, &network_config_forward);
else if (strcasecmp ("ReportStats", child->key) == 0)
- network_config_set_boolean (child, &network_config_stats);
+ cf_util_get_boolean (child, &network_config_stats);
else
{
WARNING ("network plugin: Option `%s' is not allowed here.",
network_init_gcrypt ();
#endif
- if (network_config_stats != 0)
+ if (network_config_stats)
plugin_register_read ("network", network_stats_read);
plugin_register_shutdown ("network", network_shutdown);
* just send the buffer if `flush' is called - if the requested value was in
* there, good. If not, well, then there is nothing to flush.. -octo
*/
-static int network_flush (__attribute__((unused)) cdtime_t timeout,
+static int network_flush (cdtime_t timeout,
__attribute__((unused)) const char *identifier,
__attribute__((unused)) user_data_t *user_data)
{
pthread_mutex_lock (&send_buffer_lock);
if (send_buffer_fill > 0)
- flush_buffer ();
-
+ {
+ if (timeout > 0)
+ {
+ cdtime_t now = cdtime ();
+ if ((send_buffer_last_update + timeout) > now)
+ {
+ pthread_mutex_unlock (&send_buffer_lock);
+ return (0);
+ }
+ }
+ flush_buffer ();
+ }
pthread_mutex_unlock (&send_buffer_lock);
return (0);
static const char *nfs4_server41_procedures_names[] =
{
"backchannel_ctl",
- "bind_conn_to_session",
+ "bind_conn_to_session",
"exchange_id",
"create_session",
"destroy_session",
} /* void nfs_procedures_submit */
#if KERNEL_LINUX
-static void nfs_submit_fields (int nfs_version, const char *instance,
+static void nfs_submit_fields (int nfs_version, const char *instance,
char **fields, size_t fields_num, const char **proc_names)
{
char plugin_instance[DATA_MAX_NAME_LEN];
return (EINVAL);
}
- nfs_submit_fields (nfs_version, instance, fields, fields_num,
+ nfs_submit_fields (nfs_version, instance, fields, fields_num,
proc_names);
return (0);
}
-static int nfs_submit_nfs4_server (const char *instance, char **fields,
+static int nfs_submit_nfs4_server (const char *instance, char **fields,
size_t fields_num)
{
static int suppress_warning = 0;
if (fields_num != NFS4_SERVER40_NUM_PROC &&
- fields_num != NFS4_SERVER41_NUM_PROC)
+ fields_num != NFS4_SERVER41_NUM_PROC)
{
if (!suppress_warning)
{
}
}
- nfs_submit_fields (4, instance, fields,
+ nfs_submit_fields (4, instance, fields,
nfs4_server40_procedures_names_num,
nfs4_server40_procedures_names);
{
fields += nfs4_server40_procedures_names_num;
- nfs_submit_fields (4, instance, fields,
- nfs4_server41_procedures_names_num,
+ nfs_submit_fields (4, instance, fields,
+ nfs4_server41_procedures_names_num,
nfs4_server41_procedures_names);
}
return (0);
}
-static int nfs_submit_nfs4_client (const char *instance, char **fields,
+static int nfs_submit_nfs4_client (const char *instance, char **fields,
size_t fields_num)
{
size_t proc40_names_num, proc41_names_num;
return (0);
}
-static void nfs_read_linux (FILE *fh, char *inst)
+static void nfs_read_linux (FILE *fh, const char *inst)
{
char buffer[1024];
else if (strcmp (fields[0], "proc4ops") == 0)
{
if (inst[0] == 's')
- nfs_submit_nfs4_server (inst, fields + 2,
+ nfs_submit_nfs4_server (inst, fields + 2,
(size_t) (fields_num - 2));
}
else if (strcmp (fields[0], "proc4") == 0)
{
if (inst[0] == 'c')
nfs_submit_nfs4_client (inst, fields + 2,
- (size_t) (fields_num - 2));
+ (size_t) (fields_num - 2));
}
} /* while (fgets) */
} /* void nfs_read_linux */
#endif /* KERNEL_LINUX */
#if HAVE_LIBKSTAT
-static int nfs_read_kstat (kstat_t *ksp, int nfs_version, char *inst,
+static int nfs_read_kstat (kstat_t *ksp, int nfs_version, const char *inst,
char const **proc_names, size_t proc_names_num)
{
char plugin_instance[DATA_MAX_NAME_LEN];
len = (sizeof (nginx_buffer) - 1) - nginx_buffer_len;
}
- if (len <= 0)
+ if (len == 0)
return (len);
memcpy (&nginx_buffer[nginx_buffer_len], buf, len);
}
else
{
- curl_easy_setopt (curl, CURLOPT_TIMEOUT_MS,
- CDTIME_T_TO_MS(plugin_get_interval()));
+ curl_easy_setopt (curl, CURLOPT_TIMEOUT_MS, (long) CDTIME_T_TO_MS(plugin_get_interval()));
}
#endif
return (0);
} /* void init */
-static void submit (char *type, char *inst, long long value)
+static void submit (const char *type, const char *inst, long long value)
{
value_t values[1];
value_list_t vl = VALUE_LIST_INIT;
/* Callback to get username and password */
static int authinteract (auth_client_request_t request, char **result,
int fields, void __attribute__((unused)) *arg)
-{
+{
int i;
for (i = 0; i < fields; i++)
{
if ( !smtp_auth_set_context (session, authctx)) {
pthread_mutex_unlock (&session_lock);
ERROR ("notify_email plugin: cannot set SMTP auth context");
- return (-1);
+ return (-1);
}
pthread_mutex_unlock (&session_lock);
{
char **tmp;
- tmp = (char **) realloc ((void *) recipients, (recipients_len + 1) * sizeof (char *));
+ tmp = realloc (recipients, (recipients_len + 1) * sizeof (char *));
if (tmp == NULL) {
ERROR ("notify_email: realloc failed.");
return (-1);
if (!(message = smtp_add_message (session))) {
pthread_mutex_unlock (&session_lock);
ERROR ("notify_email plugin: cannot set SMTP message");
- return (-1);
+ return (-1);
}
smtp_set_reverse_path (message, email_from);
smtp_set_header (message, "To", NULL, NULL);
--- /dev/null
+/**
+ * collectd - src/notify_nagios.c
+ * Copyright (C) 2015 Florian octo Forster
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ * Florian octo Forster <octo at collectd.org>
+ */
+
+#include "collectd.h"
+#include "plugin.h"
+#include "common.h"
+#include "configfile.h"
+
+#define NAGIOS_OK 0
+#define NAGIOS_WARNING 1
+#define NAGIOS_CRITICAL 2
+#define NAGIOS_UNKNOWN 3
+
+#ifndef NAGIOS_COMMAND_FILE
+# define NAGIOS_COMMAND_FILE "/usr/local/nagios/var/rw/nagios.cmd"
+#endif
+
+static char *nagios_command_file;
+
+static int nagios_config (oconfig_item_t *ci) /* {{{ */
+{
+ int i;
+
+ for (i = 0; i < ci->children_num; i++)
+ {
+ oconfig_item_t *child = ci->children + i;
+
+ if (strcasecmp ("CommandFile", child->key) == 0)
+ cf_util_get_string (child, &nagios_command_file);
+ else
+ WARNING ("notify_nagios plugin: Ignoring unknown config option \"%s\".",
+ child->key);
+ }
+
+ return 0;
+} /* }}} nagios_config */
+
+static int nagios_print (char const *buffer) /* {{{ */
+{
+ char const *file = NAGIOS_COMMAND_FILE;
+ int fd;
+ int status;
+ struct flock lock;
+
+ if (nagios_command_file != NULL)
+ file = nagios_command_file;
+
+ fd = open (file, O_WRONLY | O_APPEND);
+ if (fd < 0)
+ {
+ char errbuf[1024];
+ status = errno;
+ ERROR ("notify_nagios plugin: Opening \"%s\" failed: %s",
+ file, sstrerror (status, errbuf, sizeof (errbuf)));
+ return status;
+ }
+
+ memset (&lock, 0, sizeof (lock));
+ lock.l_type = F_WRLCK;
+ lock.l_whence = SEEK_END;
+ lock.l_start = 0;
+ lock.l_len = 0; /* to end of file */
+
+ status = fcntl (fd, F_GETLK, &lock);
+ if (status != 0)
+ {
+ char errbuf[1024];
+ status = errno;
+ ERROR ("notify_nagios plugin: Failed to acquire write lock on \"%s\": %s",
+ file, sstrerror (status, errbuf, sizeof (errbuf)));
+ close (fd);
+ return status;
+ }
+
+ status = (int) lseek (fd, 0, SEEK_END);
+ if (status == -1)
+ {
+ char errbuf[1024];
+ status = errno;
+ ERROR ("notify_nagios plugin: Seeking to end of \"%s\" failed: %s",
+ file, sstrerror (status, errbuf, sizeof (errbuf)));
+ close (fd);
+ return status;
+ }
+
+ status = (int) swrite (fd, buffer, strlen (buffer));
+ if (status != 0)
+ {
+ char errbuf[1024];
+ status = errno;
+ ERROR ("notify_nagios plugin: Writing to \"%s\" failed: %s",
+ file, sstrerror (status, errbuf, sizeof (errbuf)));
+ close (fd);
+ return status;
+ }
+
+ close (fd);
+ return status;
+} /* }}} int nagios_print */
+
+static int nagios_notify (const notification_t *n, /* {{{ */
+ __attribute__((unused)) user_data_t *user_data)
+{
+ char svc_description[4 * DATA_MAX_NAME_LEN];
+ char buffer[4096];
+ int code;
+ int status;
+
+ status = format_name (svc_description, (int) sizeof (svc_description),
+ /* host */ "", n->plugin, n->plugin_instance, n->type, n->type_instance);
+ if (status != 0)
+ {
+ ERROR ("notify_nagios plugin: Formatting service name failed.");
+ return status;
+ }
+
+ switch (n->severity)
+ {
+ case NOTIF_OKAY:
+ code = NAGIOS_OK;
+ break;
+ case NOTIF_WARNING:
+ code = NAGIOS_WARNING;
+ break;
+ case NOTIF_FAILURE:
+ code = NAGIOS_CRITICAL;
+ break;
+ default:
+ code = NAGIOS_UNKNOWN;
+ break;
+ }
+
+ ssnprintf (buffer, sizeof (buffer),
+ "[%.0f] PROCESS_SERVICE_CHECK_RESULT;%s;%s;%d;%s\n",
+ CDTIME_T_TO_DOUBLE (n->time), n->host, &svc_description[1], code,
+ n->message);
+
+ return nagios_print (buffer);
+} /* }}} int nagios_notify */
+
+void module_register (void)
+{
+ plugin_register_complex_config ("notify_nagios", nagios_config);
+ plugin_register_notification ("notify_nagios", nagios_notify, NULL);
+} /* void module_register (void) */
+
+/* vim: set sw=2 sts=2 ts=8 et : */
#if HAVE_NETDB_H
# include <netdb.h>
#endif
-#if HAVE_SYS_SOCKET_H
-# include <sys/socket.h>
-#endif
#if HAVE_NETINET_IN_H
# include <netinet/in.h>
#endif
};
/* List of reference clock names */
-static char *refclock_names[] =
+static const char *refclock_names[] =
{
"UNKNOWN", "LOCAL", "GPS_TRAK", "WWV_PST", /* 0- 3 */
"SPECTRACOM", "TRUETIME", "IRIG_AUDIO", "CHU_AUDIO", /* 4- 7 */
"JJY", "TT_IRIG", "GPS_ZYFER", "GPS_RIPENCC", /* 40-43 */
"NEOCLK4X" /* 44 */
};
-static int refclock_names_num = STATIC_ARRAY_SIZE (refclock_names);
+static size_t refclock_names_num = STATIC_ARRAY_SIZE (refclock_names);
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* End of the copied stuff.. *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
return (0);
}
-static void ntpd_submit (char *type, char *type_inst, gauge_t value)
+static void ntpd_submit (const char *type, const char *type_inst, gauge_t value)
{
value_t values[1];
value_list_t vl = VALUE_LIST_INIT;
/* Each time a peer is polled, ntpd shifts the reach register to the left and
* sets the LSB based on whether the peer was reachable. If the LSB is zero,
* the values are out of date. */
-static void ntpd_submit_reach (char *type, char *type_inst, uint8_t reach,
- gauge_t value)
+static void ntpd_submit_reach (const char *type, const char *type_inst,
+ uint8_t reach, gauge_t value)
{
if (!(reach & 1))
value = NAN;
static int ntpd_connect (void)
{
- char *host;
- char *port;
+ const char *host;
+ const char *port;
struct addrinfo ai_hints;
struct addrinfo *ai_list;
*/
DEBUG ("realloc (%p, %zu)", (void *) *res_data,
(items_num + pkt_item_num) * res_item_size);
- items = realloc ((void *) *res_data,
+ items = realloc (*res_data,
(items_num + pkt_item_num) * res_item_size);
if (items == NULL)
{
uint32_t refclock_id = ntpd_get_refclock_id (peer_info);
uint32_t unit_id = ntohl (peer_info->srcadr) & 0x00FF;
- if (refclock_id >= refclock_names_num)
+ if (((size_t) refclock_id) >= refclock_names_num)
return (ntpd_get_name_from_address (buffer, buffer_size,
peer_info,
/* do_reverse_lookup = */ 0));
DEBUG ("nut plugin: nut_add_ups (name = %s);", name);
- ups = (nut_ups_t *) malloc (sizeof (nut_ups_t));
+ ups = calloc (1, sizeof (*ups));
if (ups == NULL)
{
- ERROR ("nut plugin: nut_add_ups: malloc failed.");
+ ERROR ("nut plugin: nut_add_ups: calloc failed.");
return (1);
}
- memset (ups, '\0', sizeof (nut_ups_t));
status = upscli_splitname (name, &ups->upsname, &ups->hostname,
&ups->port);
/* (Re-)Connect if we have no connection */
if (ups->conn == NULL)
{
- ups->conn = (collectd_upsconn_t *) malloc (sizeof (collectd_upsconn_t));
+ ups->conn = malloc (sizeof (*ups->conn));
if (ups->conn == NULL)
{
ERROR ("nut plugin: malloc failed.");
#include <sys/types.h>
#include <netdb.h>
-#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
{
/* An empty line ends the table. */
buffer_len = strchomp (buffer);
- if (buffer_len <= 0)
+ if (buffer_len == 0)
{
(*callback) (lineno, /* fields_num = */ 0, /* fields = */ NULL);
break;
(*callback) (lineno, fields_num, fields);
lineno++;
} /* while (fgets) */
-
+
return (0);
} /* }}} int olsrd_read_table */
while (fgets (buffer, sizeof (buffer), fh) != NULL)
{
buffer_len = strchomp (buffer);
- if (buffer_len <= 0)
+ if (buffer_len == 0)
continue;
-
+
if (strcmp ("Table: Links", buffer) == 0)
olsrd_read_table (fh, olsrd_cb_links);
else if (strcmp ("Table: Neighbors", buffer) == 0)
} /* while (fgets) */
fclose (fh);
-
+
return (0);
} /* }}} int olsrd_read */
{
regmatch_t pmatch[3];
size_t nmatch = 3;
- direct_access_element_t *element = NULL;
+ direct_access_element_t *element;
DEBUG ("onewire plugin: direct_list_insert <%s>", config);
- element = (direct_access_element_t *) malloc (sizeof(*element));
+ element = malloc (sizeof (*element));
if (element == NULL)
{
ERROR ("onewire plugin: direct_list_insert - cannot allocate element");
int status;
status = ssnprintf (subpath, sizeof (subpath), "%s/main", path);
- if ((status > 0) && (status < sizeof (subpath)))
+ if ((status > 0) && (status < (int) sizeof (subpath)))
cow_read_bus (subpath);
status = ssnprintf (subpath, sizeof (subpath), "%s/aux", path);
- if ((status > 0) && (status < sizeof (subpath)))
+ if ((status > 0) && (status < (int) sizeof (subpath)))
cow_read_bus (subpath);
return (0);
else
status = ssnprintf (subpath, sizeof (subpath), "%s/%s",
path, buffer_ptr);
- if ((status <= 0) || (status >= sizeof (subpath)))
+ if ((status <= 0) || (status >= (int) sizeof (subpath)))
continue;
for (i = 0; i < ow_family_features_num; i++)
static int cow_init (void)
{
int status;
- struct timespec cb_interval;
if (device_g == NULL)
{
return (1);
}
- CDTIME_T_TO_TIMESPEC (ow_interval, &cb_interval);
-
plugin_register_complex_read (/* group = */ NULL, "onewire", cow_read,
- (ow_interval != 0) ? &cb_interval : NULL,
- /* user data = */ NULL);
+ ow_interval, /* user data = */ NULL);
plugin_register_shutdown ("onewire", cow_shutdown);
return (0);
/**
* collectd - src/openldap.c
* Copyright (C) 2011 Kimo Rosenbaum
- * Copyright (C) 2014 Marc Fournier
+ * Copyright (C) 2014-2015 Marc Fournier
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
{
char *name;
+ char *binddn;
+ char *password;
char *cacert;
char *host;
int state;
};
typedef struct cldap_s cldap_t; /* }}} */
+static cldap_t **databases = NULL;
+static size_t databases_num = 0;
+
static void cldap_free (cldap_t *st) /* {{{ */
{
if (st == NULL)
return;
+ sfree (st->binddn);
+ sfree (st->password);
sfree (st->cacert);
sfree (st->host);
sfree (st->name);
{
LDAP *ld;
int rc;
+
+ if (st->state && st->ld)
+ {
+ DEBUG ("openldap plugin: Already connected to %s", st->url);
+ return (0);
+ }
+
rc = ldap_initialize (&ld, st->url);
if (rc != LDAP_SUCCESS)
{
ldap_set_option (st->ld, LDAP_OPT_TIMEOUT,
&(const struct timeval){st->timeout, 0});
+ ldap_set_option (st->ld, LDAP_OPT_RESTART, LDAP_OPT_ON);
+
if (st->cacert != NULL)
ldap_set_option (st->ld, LDAP_OPT_X_TLS_CACERTFILE, st->cacert);
}
struct berval cred;
- cred.bv_val = "";
- cred.bv_len = 0;
+ if (st->password != NULL)
+ {
+ cred.bv_val = st->password;
+ cred.bv_len = strlen (st->password);
+ }
+ else
+ {
+ cred.bv_val = "";
+ cred.bv_len = 0;
+ }
- rc = ldap_sasl_bind_s (st->ld, NULL, NULL, &cred, NULL, NULL, NULL);
+ rc = ldap_sasl_bind_s (st->ld, st->binddn, LDAP_SASL_SIMPLE, &cred,
+ NULL, NULL, NULL);
if (rc != LDAP_SUCCESS)
{
ERROR ("openldap plugin: Failed to bind to %s: %s",
if ((st->host == NULL)
|| (strcmp ("", st->host) == 0)
|| (strcmp ("localhost", st->host) == 0))
- {
sstrncpy (vl.host, hostname_g, sizeof (vl.host));
- }
else
- {
sstrncpy (vl.host, st->host, sizeof (vl.host));
- }
sstrncpy (vl.plugin, "openldap", sizeof (vl.plugin));
if (st->name != NULL)
ERROR ("openldap plugin: Failed to execute search: %s",
ldap_err2string (rc));
ldap_msgfree (result);
+ st->state = 0;
ldap_unbind_ext_s (st->ld, NULL, NULL);
return (-1);
}
}
ldap_msgfree (result);
- ldap_unbind_ext_s (st->ld, NULL, NULL);
return (0);
} /* }}} int cldap_read_host */
int i;
int status;
- st = malloc (sizeof (*st));
+ st = calloc (1, sizeof (*st));
if (st == NULL)
{
- ERROR ("openldap plugin: malloc failed.");
+ ERROR ("openldap plugin: calloc failed.");
return (-1);
}
- memset (st, 0, sizeof (*st));
status = cf_util_get_string (ci, &st->name);
if (status != 0)
}
st->starttls = 0;
- st->timeout = -1;
+ st->timeout = (long) (CDTIME_T_TO_MS(plugin_get_interval()) / 1000);
st->verifyhost = 1;
st->version = LDAP_VERSION3;
{
oconfig_item_t *child = ci->children + i;
- if (strcasecmp ("CACert", child->key) == 0)
+ if (strcasecmp ("BindDN", child->key) == 0)
+ status = cf_util_get_string (child, &st->binddn);
+ else if (strcasecmp ("Password", child->key) == 0)
+ status = cf_util_get_string (child, &st->password);
+ else if (strcasecmp ("CACert", child->key) == 0)
status = cf_util_get_string (child, &st->cacert);
else if (strcasecmp ("StartTLS", child->key) == 0)
status = cf_util_get_boolean (child, &st->starttls);
}
if ((status == 0) && (ludpp->lud_host != NULL))
- {
st->host = strdup (ludpp->lud_host);
- }
ldap_free_urldesc (ludpp);
}
if (status == 0)
{
- user_data_t ud;
- char callback_name[3*DATA_MAX_NAME_LEN];
-
- memset (&ud, 0, sizeof (ud));
- ud.data = st;
-
- memset (callback_name, 0, sizeof (callback_name));
- ssnprintf (callback_name, sizeof (callback_name),
- "openldap/%s/%s",
- (st->host != NULL) ? st->host : hostname_g,
- (st->name != NULL) ? st->name : "default"),
-
- status = plugin_register_complex_read (/* group = */ NULL,
- /* name = */ callback_name,
- /* callback = */ cldap_read_host,
- /* interval = */ NULL,
- /* user_data = */ &ud);
+ cldap_t **temp;
+
+ temp = (cldap_t **) realloc (databases,
+ sizeof (*databases) * (databases_num + 1));
+
+ if (temp == NULL)
+ {
+ ERROR ("openldap plugin: realloc failed");
+ status = -1;
+ }
+ else
+ {
+ user_data_t ud;
+ char callback_name[3*DATA_MAX_NAME_LEN];
+
+ databases = temp;
+ databases[databases_num] = st;
+ databases_num++;
+
+ memset (&ud, 0, sizeof (ud));
+ ud.data = st;
+
+ memset (callback_name, 0, sizeof (callback_name));
+ ssnprintf (callback_name, sizeof (callback_name),
+ "openldap/%s/%s",
+ (st->host != NULL) ? st->host : hostname_g,
+ (st->name != NULL) ? st->name : "default"),
+
+ status = plugin_register_complex_read (/* group = */ NULL,
+ /* name = */ callback_name,
+ /* callback = */ cldap_read_host,
+ /* interval = */ 0,
+ /* user_data = */ &ud);
+ }
}
if (status != 0)
return (0);
} /* }}} int cldap_init */
+static int cldap_shutdown (void) /* {{{ */
+{
+ size_t i;
+
+ for (i = 0; i < databases_num; i++)
+ if (databases[i]->ld != NULL)
+ ldap_unbind_ext_s (databases[i]->ld, NULL, NULL);
+ sfree (databases);
+ databases_num = 0;
+
+ return (0);
+} /* }}} int cldap_shutdown */
+
void module_register (void) /* {{{ */
{
plugin_register_complex_config ("openldap", cldap_config);
plugin_register_init ("openldap", cldap_init);
+ plugin_register_shutdown ("openldap", cldap_shutdown);
} /* }}} void module_register */
#if defined(__APPLE__)
} /* int openvpn_strsplit */
/* dispatches number of users */
-static void numusers_submit (char *pinst, char *tinst, gauge_t value)
+static void numusers_submit (const char *pinst, const char *tinst,
+ gauge_t value)
{
value_t values[1];
value_list_t vl = VALUE_LIST_INIT;
plugin_dispatch_values (&vl);
} /* void numusers_submit */
-/* dispatches stats about traffic (TCP or UDP) generated by the tunnel per single endpoint */
-static void iostats_submit (char *pinst, char *tinst, derive_t rx, derive_t tx)
+/* dispatches stats about traffic (TCP or UDP) generated by the tunnel
+ * per single endpoint */
+static void iostats_submit (const char *pinst, const char *tinst,
+ derive_t rx, derive_t tx)
{
value_t values[2];
value_list_t vl = VALUE_LIST_INIT;
} /* void traffic_submit */
/* dispatches stats about data compression shown when in single mode */
-static void compression_submit (char *pinst, char *tinst,
+static void compression_submit (const char *pinst, const char *tinst,
derive_t uncompressed, derive_t compressed)
{
value_t values[2];
plugin_dispatch_values (&vl);
} /* void compression_submit */
-static int single_read (char *name, FILE *fh)
+static int single_read (const char *name, FILE *fh)
{
char buffer[1024];
char *fields[4];
} /* int single_read */
/* for reading status version 1 */
-static int multi1_read (char *name, FILE *fh)
+static int multi1_read (const char *name, FILE *fh)
{
char buffer[1024];
char *fields[10];
} /* int multi1_read */
/* for reading status version 2 */
-static int multi2_read (char *name, FILE *fh)
+static int multi2_read (const char *name, FILE *fh)
{
char buffer[1024];
char *fields[10];
} /* int multi2_read */
/* for reading status version 3 */
-static int multi3_read (char *name, FILE *fh)
+static int multi3_read (const char *name, FILE *fh)
{
char buffer[1024];
char *fields[15];
} /* int multi3_read */
/* for reading status version 4 */
-static int multi4_read (char *name, FILE *fh)
+static int multi4_read (const char *name, FILE *fh)
{
char buffer[1024];
char *fields[11];
}
/* create a new vpn element since file, version and name are ok */
- temp = (vpn_status_t *) malloc (sizeof (vpn_status_t));
+ temp = malloc (sizeof (*temp));
if (temp == NULL)
{
char errbuf[1024];
temp->version = status_version;
temp->name = status_name;
- vpn_list = (vpn_status_t **) realloc (vpn_list, (vpn_num + 1) * sizeof (vpn_status_t *));
- if (vpn_list == NULL)
+ vpn_status_t **tmp_list = realloc (vpn_list, (vpn_num + 1) * sizeof (*vpn_list));
+ if (tmp_list == NULL)
{
char errbuf[1024];
ERROR ("openvpn plugin: realloc failed: %s",
sstrerror (errno, errbuf, sizeof (errbuf)));
+ sfree (vpn_list);
sfree (temp->file);
sfree (temp);
return (1);
}
+ vpn_list = tmp_list;
vpn_list[vpn_num] = temp;
vpn_num++;
* ValuesFrom "value"
* </Result>
* </Query>
- *
+ *
* <Database "plugin_instance1">
* ConnectID "db01"
* Username "oracle"
return (-1);
}
- db = (o_database_t *) malloc (sizeof (*db));
+ db = calloc (1, sizeof (*db));
if (db == NULL)
{
- ERROR ("oracle plugin: malloc failed.");
+ ERROR ("oracle plugin: calloc failed.");
return (-1);
}
- memset (db, 0, sizeof (*db));
db->name = NULL;
db->host = NULL;
db->connect_id = NULL;
if (db->q_prep_areas == NULL)
{
- WARNING ("oracle plugin: malloc failed");
+ WARNING ("oracle plugin: calloc failed");
status = -1;
break;
}
{
o_database_t **temp;
- temp = (o_database_t **) realloc (databases,
+ temp = realloc (databases,
sizeof (*databases) * (databases_num + 1));
if (temp == NULL)
{
{
ub4 param_counter = 0;
status = OCIAttrGet (oci_statement, OCI_HTYPE_STMT, /* {{{ */
- ¶m_counter, /* size pointer = */ NULL,
+ ¶m_counter, /* size pointer = */ NULL,
OCI_ATTR_PARAM_COUNT, oci_error);
if (status != OCI_SUCCESS)
{
} while (0); /* }}} */
/* Allocate the following buffers:
- *
+ *
* +---------------+-----------------------------------+
* ! Name ! Size !
* +---------------+-----------------------------------+
#define ALLOC_OR_FAIL(ptr, ptr_size) \
do { \
size_t alloc_size = (size_t) ((ptr_size)); \
- (ptr) = malloc (alloc_size); \
+ (ptr) = calloc (1, alloc_size); \
if ((ptr) == NULL) { \
FREE_ALL; \
- ERROR ("oracle plugin: o_read_database_query: malloc failed."); \
+ ERROR ("oracle plugin: o_read_database_query: calloc failed."); \
return (-1); \
} \
- memset ((ptr), 0, alloc_size); \
} while (0)
/* Initialize everything to NULL so the above works. */
ub4 connection_status;
server_handle = NULL;
- status = OCIAttrGet ((void *) db->oci_service_context, OCI_HTYPE_SVCCTX,
+ status = OCIAttrGet ((void *) db->oci_service_context, OCI_HTYPE_SVCCTX,
(void *) &server_handle, /* size pointer = */ NULL,
OCI_ATTR_SERVER, oci_error);
if (status != OCI_SUCCESS)
OCIHandleFree (databases[i]->oci_service_context, OCI_HTYPE_SVCCTX);
databases[i]->oci_service_context = NULL;
}
-
+
for (i = 0; i < queries_num; i++)
{
OCIStmt *oci_statement;
udb_query_set_user_data (queries[i], NULL);
}
}
-
+
OCIHandleFree (oci_env, OCI_HTYPE_ENV);
oci_env = NULL;
return 0;
} /* static int hv2data_source (HV *, data_source_t *) */
-static int av2value (pTHX_ char *name, AV *array, value_t *value, int len)
+/* av2value converts at most "len" elements from "array" to "value". Returns the
+ * number of elements converted or zero on error. */
+static size_t av2value (pTHX_ char *name, AV *array, value_t *value, size_t array_len)
{
const data_set_t *ds;
+ size_t i;
- int i = 0;
-
- if ((NULL == name) || (NULL == array) || (NULL == value))
- return -1;
-
- if (av_len (array) < len - 1)
- len = av_len (array) + 1;
-
- if (0 >= len)
- return -1;
+ if ((NULL == name) || (NULL == array) || (NULL == value) || (array_len == 0))
+ return 0;
ds = plugin_get_ds (name);
if (NULL == ds) {
log_err ("av2value: Unknown dataset \"%s\"", name);
- return -1;
+ return 0;
}
- if (ds->ds_num < len) {
- log_warn ("av2value: Value length exceeds data set length.");
- len = ds->ds_num;
+ if (array_len < ds->ds_num) {
+ log_warn ("av2value: array does not contain enough elements for type \"%s\": got %zu, want %zu",
+ name, array_len, ds->ds_num);
+ return 0;
+ } else if (array_len > ds->ds_num) {
+ log_warn ("av2value: array contains excess elements for type \"%s\": got %zu, want %zu",
+ name, array_len, ds->ds_num);
}
- for (i = 0; i < len; ++i) {
+ for (i = 0; i < ds->ds_num; ++i) {
SV **tmp = av_fetch (array, i, 0);
if (NULL != tmp) {
value[i].absolute = SvIV (*tmp);
}
else {
- return -1;
+ return 0;
}
}
- return len;
-} /* static int av2value (char *, AV *, value_t *, int) */
+
+ return ds->ds_num;
+} /* static size_t av2value (char *, AV *, value_t *, size_t) */
/*
* value list:
{
AV *array = (AV *)SvRV (*tmp);
- int len = av_len (array) + 1;
-
- if (len <= 0)
+ /* av_len returns the highest index, not the actual length. */
+ size_t array_len = (size_t) (av_len (array) + 1);
+ if (array_len == 0)
return -1;
- vl->values = (value_t *)smalloc (len * sizeof (value_t));
- vl->values_len = av2value (aTHX_ vl->type, (AV *)SvRV (*tmp),
- vl->values, len);
-
- if (-1 == vl->values_len) {
+ vl->values = calloc (array_len, sizeof (*vl->values));
+ vl->values_len = av2value (aTHX_ vl->type, (AV *)SvRV (*tmp), vl->values, array_len);
+ if (vl->values_len == 0) {
sfree (vl->values);
return -1;
}
return -1;
}
- ds->ds = (data_source_t *)smalloc ((len + 1) * sizeof (data_source_t));
+ ds->ds = smalloc ((len + 1) * sizeof (*ds->ds));
ds->ds_num = len + 1;
for (i = 0; i <= len; ++i) {
hash = (HV *)SvRV (*tmp);
- *m = (notification_meta_t *)smalloc (sizeof (**m));
+ *m = smalloc (sizeof (**m));
if (NULL == (tmp = hv_fetch (hash, "name", 4, 0))) {
log_warn ("av2notification_meta: Skipping invalid "
static int data_set2av (pTHX_ data_set_t *ds, AV *array)
{
- int i = 0;
+ size_t i;
if ((NULL == ds) || (NULL == array))
return -1;
static int value_list2hv (pTHX_ value_list_t *vl, data_set_t *ds, HV *hash)
{
AV *values = NULL;
-
- int i = 0;
- int len = 0;
+ size_t i;
if ((NULL == vl) || (NULL == ds) || (NULL == hash))
return -1;
- len = vl->values_len;
-
- if (ds->ds_num < len) {
- log_warn ("value2av: Value length exceeds data set length.");
- len = ds->ds_num;
- }
-
values = newAV ();
- av_extend (values, len - 1);
+ /* av_extend takes the last *index* to which the array should be extended. */
+ av_extend (values, vl->values_len - 1);
- for (i = 0; i < len; ++i) {
+ assert (ds->ds_num == vl->values_len);
+ for (i = 0; i < vl->values_len; ++i) {
SV *val = NULL;
if (DS_TYPE_COUNTER == ds->ds[i].type)
assert (NULL != perl_threads);
- t = (c_ithread_t *)smalloc (sizeof (c_ithread_t));
+ t = smalloc (sizeof (*t));
memset (t, 0, sizeof (c_ithread_t));
t->interp = (NULL == base)
return -1;
}
- data = (pfc_user_data_t *)smalloc (sizeof (*data));
+ data = smalloc (sizeof (*data));
data->name = sstrdup (ci->values[0].value.string);
data->user_data = newSV (0);
static int perl_shutdown (void)
{
- c_ithread_t *t = NULL;
-
- int ret = 0;
+ c_ithread_t *t;
+ int ret;
dTHX;
return 0;
if (NULL == aTHX) {
- t = NULL;
-
pthread_mutex_lock (&perl_threads->mutex);
t = c_ithread_create (perl_threads->head->interp);
pthread_mutex_unlock (&perl_threads->mutex);
#endif
PERL_SYS_INIT3 (&argc, &argv, &environ);
- perl_threads = (c_ithread_list_t *)smalloc (sizeof (c_ithread_list_t));
+ perl_threads = smalloc (sizeof (*perl_threads));
memset (perl_threads, 0, sizeof (c_ithread_list_t));
pthread_mutex_init (&perl_threads->mutex, NULL);
value = ci->values[0].value.string;
- perl_argv = (char **)realloc (perl_argv,
+ perl_argv = realloc (perl_argv,
(++perl_argc + 1) * sizeof (char *));
if (NULL == perl_argv) {
perl_argv[perl_argc - 1] = "-d";
}
else {
- perl_argv[perl_argc - 1] = (char *)smalloc (strlen (value) + 4);
+ perl_argv[perl_argc - 1] = smalloc (strlen (value) + 4);
sstrncpy (perl_argv[perl_argc - 1], "-d:", 4);
sstrncpy (perl_argv[perl_argc - 1] + 3, value, strlen (value) + 1);
}
value = ci->values[0].value.string;
if (NULL == aTHX) {
- perl_argv = (char **)realloc (perl_argv,
+ perl_argv = realloc (perl_argv,
(++perl_argc + 1) * sizeof (char *));
if (NULL == perl_argv) {
exit (3);
}
- perl_argv[perl_argc - 1] = (char *)smalloc (strlen (value) + 3);
+ perl_argv[perl_argc - 1] = smalloc (strlen (value) + 3);
sstrncpy(perl_argv[perl_argc - 1], "-I", 3);
sstrncpy(perl_argv[perl_argc - 1] + 2, value, strlen (value) + 1);
void module_register (void)
{
perl_argc = 4;
- perl_argv = (char **)smalloc ((perl_argc + 1) * sizeof (char *));
+ perl_argv = smalloc ((perl_argc + 1) * sizeof (*perl_argv));
/* default options for the Perl interpreter */
perl_argv[0] = "";
#if HAVE_SYS_IOCTL_H
# include <sys/ioctl.h>
#endif
-#if HAVE_SYS_SOCKET_H
-# include <sys/socket.h>
-#endif
#if HAVE_NET_IF_H
# include <net/if.h>
#endif
}
close (fd);
- fd = -1;
if (!state.running)
{
#include "configfile.h"
#include <pthread.h>
-#include <sys/socket.h>
#include <netdb.h>
#include <poll.h>
const char *script)
{
pinba_statnode_t *node;
-
+
node = realloc (stat_nodes,
sizeof (*stat_nodes) * (stat_nodes_num + 1));
if (node == NULL)
node = stat_nodes + stat_nodes_num;
memset (node, 0, sizeof (*node));
-
+
/* reset strings */
node->name = NULL;
node->host = NULL;
node->script = NULL;
node->mem_peak = NAN;
-
+
/* fill query data */
strset (&node->name, name);
strset (&node->host, host);
strset (&node->server, server);
strset (&node->script, script);
-
+
/* increment counter */
stat_nodes_num++;
} /* }}} void service_statnode_add */
unsigned int index)
{
pinba_statnode_t *node;
-
+
if (stat_nodes_num == 0)
return 0;
-
+
/* begin collecting */
if (index == 0)
pthread_mutex_lock (&stat_nodes_lock);
-
+
/* end collecting */
if (index >= stat_nodes_num)
{
/* reset node */
node->mem_peak = NAN;
-
+
return (index + 1);
} /* }}} unsigned int service_statnode_collect */
unsigned int i;
pthread_mutex_lock (&stat_nodes_lock);
-
+
for (i = 0; i < stat_nodes_num; i++)
{
if ((stat_nodes[i].host != NULL)
service_statnode_process(&stat_nodes[i], request);
}
-
+
pthread_mutex_unlock(&stat_nodes_lock);
} /* }}} void service_process_request */
}
assert (ai_list != NULL);
- s = malloc (sizeof (*s));
+ s = calloc (1, sizeof (*s));
if (s == NULL)
{
freeaddrinfo (ai_list);
- ERROR ("pinba plugin: malloc failed.");
+ ERROR ("pinba plugin: calloc failed.");
return (NULL);
}
- memset (s, 0, sizeof (*s));
for (ai_ptr = ai_list; ai_ptr != NULL; ai_ptr = ai_ptr->ai_next)
{
if (status != 0)
break;
} /* for (ai_list) */
-
+
freeaddrinfo (ai_list);
if (s->fd_num < 1)
if (!socket)
return;
-
+
for (i = 0; i < socket->fd_num; i++)
{
if (socket->fd[i].fd < 0)
close (socket->fd[i].fd);
socket->fd[i].fd = -1;
}
-
+
sfree(socket);
} /* }}} void pinba_socket_free */
static int pinba_process_stats_packet (const uint8_t *buffer, /* {{{ */
size_t buffer_size)
{
- Pinba__Request *request;
-
+ Pinba__Request *request;
+
request = pinba__request__unpack (NULL, buffer_size, buffer);
-
+
if (!request)
return (-1);
service_process_request(request);
pinba__request__free_unpacked (request, NULL);
-
+
return (0);
} /* }}} int pinba_process_stats_packet */
static int plugin_config (oconfig_item_t *ci) /* {{{ */
{
int i;
-
+
/* The lock should not be necessary in the config callback, but let's be
* sure.. */
pthread_mutex_lock (&stat_nodes_lock);
}
pthread_mutex_unlock(&stat_nodes_lock);
-
+
return (0);
} /* }}} int pinba_config */
{
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_instance, res->name, sizeof (vl.plugin_instance));
value.derive = res->req_count;
- sstrncpy (vl.type, "total_requests", sizeof (vl.type));
+ sstrncpy (vl.type, "total_requests", sizeof (vl.type));
plugin_dispatch_values (&vl);
value.derive = float_counter_get (&res->req_time, /* factor = */ 1000);
- sstrncpy (vl.type, "total_time_in_ms", sizeof (vl.type));
+ sstrncpy (vl.type, "total_time_in_ms", sizeof (vl.type));
plugin_dispatch_values (&vl);
value.derive = res->doc_size;
- sstrncpy (vl.type, "total_bytes", sizeof (vl.type));
+ sstrncpy (vl.type, "total_bytes", sizeof (vl.type));
plugin_dispatch_values (&vl);
value.derive = float_counter_get (&res->ru_utime, /* factor = */ 100);
{
unsigned int i=0;
pinba_statnode_t data;
-
+
while ((i = service_statnode_collect (&data, i)) != 0)
{
plugin_submit (&data);
}
-
+
return 0;
} /* }}} int plugin_read */
#ifdef HAVE_OPING_1_3
static char *ping_device = NULL;
#endif
+static char *ping_data = NULL;
static int ping_ttl = PING_DEF_TTL;
static double ping_interval = 1.0;
static double ping_timeout = 0.9;
#ifdef HAVE_OPING_1_3
"Device",
#endif
+ "Size",
"TTL",
"Interval",
"Timeout",
hl->pkg_missed++;
/* if the host did not answer our last N packages, trigger a resolv. */
- if (ping_max_missed >= 0 && hl->pkg_missed >= ping_max_missed)
+ if ((ping_max_missed >= 0)
+ && (hl->pkg_missed >= ((uint32_t) ping_max_missed)))
{ /* {{{ */
/* we reset the missed package counter here, since we only want to
* trigger a resolv every N packages and not every package _AFTER_ N
ping_setopt (pingobj, PING_OPT_TIMEOUT, (void *) &ping_timeout);
ping_setopt (pingobj, PING_OPT_TTL, (void *) &ping_ttl);
+ if (ping_data != NULL)
+ ping_setopt (pingobj, PING_OPT_DATA, (void *) ping_data);
+
/* Add all the hosts to the ping object. */
count = 0;
for (hl = hostlist_head; hl != NULL; hl = hl->next)
pthread_mutex_unlock (&ping_lock);
return (-1);
}
-
+
pthread_mutex_unlock (&ping_lock);
return (0);
} /* }}} int start_thread */
hostlist_t *hl;
char *host;
- hl = (hostlist_t *) malloc (sizeof (hostlist_t));
+ hl = malloc (sizeof (*hl));
if (hl == NULL)
{
char errbuf[1024];
WARNING ("ping plugin: Ignoring invalid interval %g (%s)",
tmp, value);
}
+ else if (strcasecmp (key, "Size") == 0) {
+ size_t size = (size_t) atoi (value);
+
+ /* Max IP packet size - (IPv6 + ICMP) = 65535 - (40 + 8) = 65487 */
+ if (size <= 65487)
+ {
+ size_t i;
+
+ sfree (ping_data);
+ ping_data = malloc (size + 1);
+ if (ping_data == NULL)
+ {
+ ERROR ("ping plugin: malloc failed.");
+ return (1);
+ }
+
+ /* Note: By default oping is using constant string
+ * "liboping -- ICMP ping library <http://octo.it/liboping/>"
+ * which is exactly 56 bytes.
+ *
+ * Optimally we would follow the ping(1) behaviour, but we
+ * cannot use byte 00 or start data payload at exactly same
+ * location, due to oping library limitations. */
+ for (i = 0; i < size; i++) /* {{{ */
+ {
+ /* This restricts data pattern to be only composed of easily
+ * printable characters, and not NUL character. */
+ ping_data[i] = ('0' + i % 64);
+ } /* }}} for (i = 0; i < size; i++) */
+ ping_data[size] = 0;
+ } else
+ WARNING ("ping plugin: Ignoring invalid Size %zu.", size);
+ }
else if (strcasecmp (key, "Timeout") == 0)
{
double tmp;
hl = hl_next;
}
+ if (ping_data != NULL) {
+ free (ping_data);
+ ping_data = NULL;
+ }
+
return (0);
} /* }}} int ping_shutdown */
int ref_cnt;
} c_psql_database_t;
-static char *def_queries[] = {
+static const char *const def_queries[] = {
"backends",
"transactions",
"queries",
c_psql_database_t **tmp;
c_psql_database_t *db;
- db = (c_psql_database_t *)malloc (sizeof(*db));
+ db = malloc (sizeof(*db));
if (NULL == db) {
log_err ("Out of memory.");
return NULL;
}
- tmp = (c_psql_database_t **)realloc (databases,
+ tmp = realloc (databases,
(databases_num + 1) * sizeof (*databases));
if (NULL == tmp) {
log_err ("Out of memory.");
static PGresult *c_psql_exec_query_params (c_psql_database_t *db,
udb_query_t *q, c_psql_user_data_t *data)
{
- char *params[db->max_params_num];
- char interval[64];
- int i;
+ const char *params[db->max_params_num];
+ char interval[64];
+ int i;
if ((data == NULL) || (data->params_num == 0))
return (c_psql_exec_query_noparams (db, q));
log_err ("calloc failed.");
BAIL_OUT (-1);
}
-
+
for (col = 0; col < column_num; ++col) {
/* Pointers returned by `PQfname' are freed by `PQclear' via
* `BAIL_OUT'. */
c_psql_database_t *db;
int success = 0;
- int i;
+ size_t i;
if ((ud == NULL) || (ud->data == NULL)) {
log_err ("c_psql_read: Invalid user data.");
{
char *str_ptr;
size_t str_len;
-
- int i;
+ size_t i;
str_ptr = string;
str_len = string_len;
{
char *str_ptr;
size_t str_len;
-
- int i;
+ size_t i;
str_ptr = string;
str_len = string_len;
size_t str_len;
gauge_t *rates = NULL;
-
- int i;
+ size_t i;
str_ptr = string;
str_len = string_len;
{
c_psql_database_t *db;
- char time_str[32];
+ char time_str[RFC3339NANO_SIZE];
char values_name_str[1024];
char values_type_str[1024];
char values_str[1024];
const char *params[9];
int success = 0;
- int i;
+ size_t i;
if ((ud == NULL) || (ud->data == NULL)) {
log_err ("c_psql_write: Invalid user data.");
assert (db->database != NULL);
assert (db->writers != NULL);
- if (cdtime_to_iso8601 (time_str, sizeof (time_str), vl->time) == 0) {
- log_err ("c_psql_write: Failed to convert time to ISO 8601 format");
+ if (rfc3339nano (time_str, sizeof (time_str), vl->time) != 0) {
+ log_err ("c_psql_write: Failed to convert time to RFC 3339 format");
return -1;
}
#undef VALUE_OR_NULL
if( db->expire_delay > 0 && vl->time < (cdtime() - vl->interval - db->expire_delay) ) {
- log_info ("c_psql_write: Skipped expired value @ %s - %s/%s-%s/%s-%s/%s",
+ log_info ("c_psql_write: Skipped expired value @ %s - %s/%s-%s/%s-%s/%s",
params[0], params[1], params[2], params[3], params[4], params[5], params[6] );
return 0;
}
data = udb_query_get_user_data (q);
if (NULL == data) {
- data = malloc (sizeof (*data));
+ data = calloc (1, sizeof (*data));
if (NULL == data) {
log_err ("Out of memory.");
return -1;
}
- memset (data, 0, sizeof (*data));
data->params = NULL;
data->params_num = 0;
if (strcasecmp (name, src_writers[i].name) != 0)
continue;
- tmp = (c_psql_writer_t **)realloc (*dst_writers,
+ tmp = realloc (*dst_writers,
sizeof (**dst_writers) * (*dst_writers_num + 1));
if (tmp == NULL) {
log_err ("Out of memory.");
return 1;
}
- tmp = (c_psql_writer_t *)realloc (writers,
+ tmp = realloc (writers,
sizeof (*writers) * (writers_num + 1));
if (tmp == NULL) {
log_err ("Out of memory.");
c_psql_database_t *db;
char cb_name[DATA_MAX_NAME_LEN];
- struct timespec cb_interval = { 0, 0 };
user_data_t ud;
static _Bool have_flush = 0;
ssnprintf (cb_name, sizeof (cb_name), "postgresql-%s", db->instance);
if (db->queries_num > 0) {
- CDTIME_T_TO_TIMESPEC (db->interval, &cb_interval);
-
++db->ref_cnt;
plugin_register_complex_read ("postgresql", cb_name, c_psql_read,
- /* interval = */ (db->interval > 0) ? &cb_interval : NULL,
- &ud);
+ /* interval = */ db->interval, &ud);
}
if (db->writers_num > 0) {
++db->ref_cnt;
#include <string.h>
#include <errno.h>
#include <sys/types.h>
-#include <sys/socket.h>
#include <sys/un.h>
#ifndef UNIX_PATH_MAX
struct statname_lookup_s
{
- char *name;
- char *type;
- char *type_instance;
+ const char *name;
+ const char *type;
+ const char *type_instance;
};
typedef struct statname_lookup_s statname_lookup_t;
/* Description of statistics returned by the recursor: {{{
-all-outqueries counts the number of outgoing UDP queries since starting
-answers0-1 counts the number of queries answered within 1 millisecond
-answers100-1000 counts the number of queries answered within 1 second
-answers10-100 counts the number of queries answered within 100 milliseconds
-answers1-10 counts the number of queries answered within 10 milliseconds
-answers-slow counts the number of queries answered after 1 second
-cache-entries shows the number of entries in the cache
-cache-hits counts the number of cache hits since starting
-cache-misses counts the number of cache misses since starting
-chain-resends number of queries chained to existing outstanding query
-client-parse-errors counts number of client packets that could not be parsed
-concurrent-queries shows the number of MThreads currently running
-dlg-only-drops number of records dropped because of delegation only setting
-negcache-entries shows the number of entries in the Negative answer cache
-noerror-answers counts the number of times it answered NOERROR since starting
-nsspeeds-entries shows the number of entries in the NS speeds map
-nsset-invalidations number of times an nsset was dropped because it no longer worked
-nxdomain-answers counts the number of times it answered NXDOMAIN since starting
-outgoing-timeouts counts the number of timeouts on outgoing UDP queries since starting
-qa-latency shows the current latency average
-questions counts all End-user initiated queries with the RD bit set
-resource-limits counts number of queries that could not be performed because of resource limits
-server-parse-errors counts number of server replied packets that could not be parsed
-servfail-answers counts the number of times it answered SERVFAIL since starting
-spoof-prevents number of times PowerDNS considered itself spoofed, and dropped the data
-sys-msec number of CPU milliseconds spent in 'system' mode
-tcp-client-overflow number of times an IP address was denied TCP access because it already had too many connections
-tcp-outqueries counts the number of outgoing TCP queries since starting
-tcp-questions counts all incoming TCP queries (since starting)
-throttled-out counts the number of throttled outgoing UDP queries since starting
-throttle-entries shows the number of entries in the throttle map
-unauthorized-tcp number of TCP questions denied because of allow-from restrictions
-unauthorized-udp number of UDP questions denied because of allow-from restrictions
-unexpected-packets number of answers from remote servers that were unexpected (might point to spoofing)
-uptime number of seconds process has been running (since 3.1.5)
-user-msec number of CPU milliseconds spent in 'user' mode
+all-outqueries counts the number of outgoing UDP queries since starting
+answers-slow counts the number of queries answered after 1 second
+answers0-1 counts the number of queries answered within 1 millisecond
+answers1-10 counts the number of queries answered within 10 milliseconds
+answers10-100 counts the number of queries answered within 100 milliseconds
+answers100-1000 counts the number of queries answered within 1 second
+cache-bytes size of the cache in bytes (since 3.3.1)
+cache-entries shows the number of entries in the cache
+cache-hits counts the number of cache hits since starting, this does not include hits that got answered from the packet-cache
+cache-misses counts the number of cache misses since starting
+case-mismatches counts the number of mismatches in character case since starting
+chain-resends number of queries chained to existing outstanding query
+client-parse-errors counts number of client packets that could not be parsed
+concurrent-queries shows the number of MThreads currently running
+dlg-only-drops number of records dropped because of delegation only setting
+dont-outqueries number of outgoing queries dropped because of 'dont-query' setting (since 3.3)
+edns-ping-matches number of servers that sent a valid EDNS PING respons
+edns-ping-mismatches number of servers that sent an invalid EDNS PING response
+failed-host-entries number of servers that failed to resolve
+ipv6-outqueries number of outgoing queries over IPv6
+ipv6-questions counts all End-user initiated queries with the RD bit set, received over IPv6 UDP
+malloc-bytes returns the number of bytes allocated by the process (broken, always returns 0)
+max-mthread-stack maximum amount of thread stack ever used
+negcache-entries shows the number of entries in the Negative answer cache
+no-packet-error number of errorneous received packets
+noedns-outqueries number of queries sent out without EDNS
+noerror-answers counts the number of times it answered NOERROR since starting
+noping-outqueries number of queries sent out without ENDS PING
+nsset-invalidations number of times an nsset was dropped because it no longer worked
+nsspeeds-entries shows the number of entries in the NS speeds map
+nxdomain-answers counts the number of times it answered NXDOMAIN since starting
+outgoing-timeouts counts the number of timeouts on outgoing UDP queries since starting
+over-capacity-drops questions dropped because over maximum concurrent query limit (since 3.2)
+packetcache-bytes size of the packet cache in bytes (since 3.3.1)
+packetcache-entries size of packet cache (since 3.2)
+packetcache-hits packet cache hits (since 3.2)
+packetcache-misses packet cache misses (since 3.2)
+policy-drops packets dropped because of (Lua) policy decision
+qa-latency shows the current latency average
+questions counts all end-user initiated queries with the RD bit set
+resource-limits counts number of queries that could not be performed because of resource limits
+security-status security status based on security polling
+server-parse-errors counts number of server replied packets that could not be parsed
+servfail-answers counts the number of times it answered SERVFAIL since starting
+spoof-prevents number of times PowerDNS considered itself spoofed, and dropped the data
+sys-msec number of CPU milliseconds spent in 'system' mode
+tcp-client-overflow number of times an IP address was denied TCP access because it already had too many connections
+tcp-clients counts the number of currently active TCP/IP clients
+tcp-outqueries counts the number of outgoing TCP queries since starting
+tcp-questions counts all incoming TCP queries (since starting)
+throttle-entries shows the number of entries in the throttle map
+throttled-out counts the number of throttled outgoing UDP queries since starting
+throttled-outqueries idem to throttled-out
+unauthorized-tcp number of TCP questions denied because of allow-from restrictions
+unauthorized-udp number of UDP questions denied because of allow-from restrictions
+unexpected-packets number of answers from remote servers that were unexpected (might point to spoofing)
+unreachables number of times nameservers were unreachable since starting
+uptime number of seconds process has been running (since 3.1.5)
+user-msec number of CPU milliseconds spent in 'user' mode
}}} */
-const char* const default_server_fields[] = /* {{{ */
+static const char* const default_server_fields[] = /* {{{ */
{
"latency",
"packetcache-hit",
"udp-answers",
"udp-queries",
}; /* }}} */
-int default_server_fields_num = STATIC_ARRAY_SIZE (default_server_fields);
+static int default_server_fields_num = STATIC_ARRAY_SIZE (default_server_fields);
-statname_lookup_t lookup_table[] = /* {{{ */
+static statname_lookup_t lookup_table[] = /* {{{ */
{
/*********************
* Server statistics *
{"udp-answers-bytes", "total_bytes", "udp-answers-bytes"},
/* Cache stuff */
+ {"cache-bytes", "cache_size", "cache-bytes"},
+ {"packetcache-bytes", "cache_size", "packet-bytes"},
+ {"packetcache-entries", "cache_size", "packet-entries"},
{"packetcache-hit", "cache_result", "packet-hit"},
+ {"packetcache-hits", "cache_result", "packet-hit"},
{"packetcache-miss", "cache_result", "packet-miss"},
+ {"packetcache-misses", "cache_result", "packet-miss"},
{"packetcache-size", "cache_size", "packet"},
{"key-cache-size", "cache_size", "key"},
{"meta-cache-size", "cache_size", "meta"},
{"corrupt-packets", "ipt_packets", "corrupt"},
{"deferred-cache-inserts", "counter", "cache-deferred_insert"},
{"deferred-cache-lookup", "counter", "cache-deferred_lookup"},
+ {"dont-outqueries", "dns_question", "dont-outqueries"},
{"qsize-a", "cache_size", "answers"},
{"qsize-q", "cache_size", "questions"},
{"servfail-packets", "ipt_packets", "servfail"},
* Recursor statistics *
***********************/
/* Answers by return code */
- {"noerror-answers", "dns_rcode", "NOERROR"},
- {"nxdomain-answers", "dns_rcode", "NXDOMAIN"},
- {"servfail-answers", "dns_rcode", "SERVFAIL"},
+ {"noerror-answers", "dns_rcode", "NOERROR"},
+ {"nxdomain-answers", "dns_rcode", "NXDOMAIN"},
+ {"servfail-answers", "dns_rcode", "SERVFAIL"},
/* CPU utilization */
- {"sys-msec", "cpu", "system"},
- {"user-msec", "cpu", "user"},
+ {"sys-msec", "cpu", "system"},
+ {"user-msec", "cpu", "user"},
/* Question-to-answer latency */
- {"qa-latency", "latency", NULL},
+ {"qa-latency", "latency", NULL},
/* Cache */
- {"cache-entries", "cache_size", NULL},
- {"cache-hits", "cache_result", "hit"},
- {"cache-misses", "cache_result", "miss"},
+ {"cache-entries", "cache_size", NULL},
+ {"cache-hits", "cache_result", "hit"},
+ {"cache-misses", "cache_result", "miss"},
/* Total number of questions.. */
- {"questions", "dns_qtype", "total"},
+ {"questions", "dns_qtype", "total"},
/* All the other stuff.. */
- {"all-outqueries", "dns_question", "outgoing"},
- {"answers0-1", "dns_answer", "0_1"},
- {"answers1-10", "dns_answer", "1_10"},
- {"answers10-100", "dns_answer", "10_100"},
- {"answers100-1000", "dns_answer", "100_1000"},
- {"answers-slow", "dns_answer", "slow"},
- {"chain-resends", "dns_question", "chained"},
- {"client-parse-errors", "counter", "drops-client_parse_error"},
- {"concurrent-queries", "dns_question", "concurrent"},
- {"dlg-only-drops", "counter", "drops-delegation_only"},
- {"negcache-entries", "cache_size", "negative"},
- {"nsspeeds-entries", "gauge", "entries-ns_speeds"},
- {"nsset-invalidations", "counter", "ns_set_invalidation"},
- {"outgoing-timeouts", "counter", "drops-timeout_outgoing"},
- {"resource-limits", "counter", "drops-resource_limit"},
- {"server-parse-errors", "counter", "drops-server_parse_error"},
- {"spoof-prevents", "counter", "drops-spoofed"},
- {"tcp-client-overflow", "counter", "denied-client_overflow_tcp"},
- {"tcp-outqueries", "dns_question", "outgoing-tcp"},
- {"tcp-questions", "dns_question", "incoming-tcp"},
- {"throttled-out", "dns_question", "outgoing-throttled"},
- {"throttle-entries", "gauge", "entries-throttle"},
- {"unauthorized-tcp", "counter", "denied-unauthorized_tcp"},
- {"unauthorized-udp", "counter", "denied-unauthorized_udp"},
- {"unexpected-packets", "dns_answer", "unexpected"},
- {"uptime", "uptime", NULL}
+ {"all-outqueries", "dns_question", "outgoing"},
+ {"answers0-1", "dns_answer", "0_1"},
+ {"answers1-10", "dns_answer", "1_10"},
+ {"answers10-100", "dns_answer", "10_100"},
+ {"answers100-1000", "dns_answer", "100_1000"},
+ {"answers-slow", "dns_answer", "slow"},
+ {"case-mismatches", "counter", "case_mismatches"},
+ {"chain-resends", "dns_question", "chained"},
+ {"client-parse-errors", "counter", "drops-client_parse_error"},
+ {"concurrent-queries", "dns_question", "concurrent"},
+ {"dlg-only-drops", "counter", "drops-delegation_only"},
+ {"edns-ping-matches", "counter", "edns-ping_matches"},
+ {"edns-ping-mismatches", "counter", "edns-ping_mismatches"},
+ {"failed-host-entries", "counter", "entries-failed_host"},
+ {"ipv6-outqueries", "dns_question", "outgoing-ipv6"},
+ {"ipv6-questions", "dns_question", "incoming-ipv6"},
+ {"malloc-bytes", "gauge", "malloc_bytes"},
+ {"max-mthread-stack", "gauge", "max_mthread_stack"},
+ {"no-packet-error", "gauge", "no_packet_error"},
+ {"noedns-outqueries", "dns_question", "outgoing-noedns"},
+ {"noping-outqueries", "dns_question", "outgoing-noping"},
+ {"over-capacity-drops", "dns_question", "incoming-over_capacity"},
+ {"negcache-entries", "cache_size", "negative"},
+ {"nsspeeds-entries", "gauge", "entries-ns_speeds"},
+ {"nsset-invalidations", "counter", "ns_set_invalidation"},
+ {"outgoing-timeouts", "counter", "drops-timeout_outgoing"},
+ {"policy-drops", "counter", "drops-policy"},
+ {"resource-limits", "counter", "drops-resource_limit"},
+ {"server-parse-errors", "counter", "drops-server_parse_error"},
+ {"spoof-prevents", "counter", "drops-spoofed"},
+ {"tcp-client-overflow", "counter", "denied-client_overflow_tcp"},
+ {"tcp-clients", "gauge", "clients-tcp"},
+ {"tcp-outqueries", "dns_question", "outgoing-tcp"},
+ {"tcp-questions", "dns_question", "incoming-tcp"},
+ {"throttled-out", "dns_question", "outgoing-throttled"},
+ {"throttle-entries", "gauge", "entries-throttle"},
+ {"throttled-outqueries", "dns_question", "outgoing-throttle"},
+ {"unauthorized-tcp", "counter", "denied-unauthorized_tcp"},
+ {"unauthorized-udp", "counter", "denied-unauthorized_udp"},
+ {"unexpected-packets", "dns_answer", "unexpected"},
+ {"uptime", "uptime", NULL}
}; /* }}} */
-int lookup_table_length = STATIC_ARRAY_SIZE (lookup_table);
+static int lookup_table_length = STATIC_ARRAY_SIZE (lookup_table);
static llist_t *list = NULL;
static char *local_sockpath = NULL;
/* TODO: Do this before 4.4:
- * - Recursor:
- * - Complete list of known pdns -> collectd mappings.
* - Update the collectd.conf(5) manpage.
*
* -octo
*/
-/* <http://doc.powerdns.com/recursor-stats.html> */
+/* <https://doc.powerdns.com/md/recursor/stats/> */
static void submit (const char *plugin_instance, /* {{{ */
const char *pdns_type, const char *value)
{
if (ds->ds_num != 1)
{
- ERROR ("powerdns plugin: type `%s' has %i data sources, "
+ ERROR ("powerdns plugin: type `%s' has %zu data sources, "
"but I can only handle one.",
type, ds->ds_num);
return;
return (-1);
assert (buffer_size > 0);
- buffer = (char *) malloc (buffer_size);
+ buffer = malloc (buffer_size);
if (buffer == NULL)
{
FUNC_ERROR ("malloc");
else if (status == 0)
break;
- buffer_new = (char *) realloc (buffer, buffer_size + status + 1);
+ buffer_new = realloc (buffer, buffer_size + status + 1);
if (buffer_new == NULL)
{
FUNC_ERROR ("realloc");
return (-1);
}
buffer[sizeof (buffer) - 1] = 0;
- int i = strlen (buffer);
- if (i < sizeof (buffer) - 2)
+ size_t len = strlen (buffer);
+ if (len < sizeof (buffer) - 2)
{
- buffer[i++] = ' ';
- buffer[i++] = '\n';
- buffer[i++] = '\0';
+ buffer[len++] = ' ';
+ buffer[len++] = '\n';
+ buffer[len++] = '\0';
}
}
return (-1);
}
- temp = (char **) realloc (li->fields,
+ temp = realloc (li->fields,
sizeof (char *) * (li->fields_num + ci->values_num));
if (temp == NULL)
{
return (-1);
}
- item = (list_item_t *) malloc (sizeof (list_item_t));
+ item = calloc (1, sizeof (*item));
if (item == NULL)
{
- ERROR ("powerdns plugin: malloc failed.");
+ ERROR ("powerdns plugin: calloc failed.");
return (-1);
}
- memset (item, '\0', sizeof (list_item_t));
item->instance = strdup (ci->values[0].value.string);
if (item->instance == NULL)
derive_t io_syscr;
derive_t io_syscw;
+ derive_t cswitch_vol;
+ derive_t cswitch_invol;
+
struct procstat_entry_s *next;
} procstat_entry_t;
derive_t io_syscr;
derive_t io_syscw;
+ derive_t cswitch_vol;
+ derive_t cswitch_invol;
+
struct procstat *next;
struct procstat_entry_s *instances;
} procstat_t;
static procstat_t *list_head_g = NULL;
+static _Bool report_ctx_switch = 0;
+
#if HAVE_THREAD_INFO
static mach_port_t port_host_self;
static mach_port_t port_task_self;
procstat_t *ptr;
int status;
- new = (procstat_t *) malloc (sizeof (procstat_t));
+ new = calloc (1, sizeof (*new));
if (new == NULL)
{
- ERROR ("processes plugin: ps_list_register: malloc failed.");
+ ERROR ("processes plugin: ps_list_register: calloc failed.");
return;
}
- memset (new, 0, sizeof (procstat_t));
sstrncpy (new->name, name, sizeof (new->name));
#if HAVE_REGEX_H
if (regexp != NULL)
{
DEBUG ("ProcessMatch: adding \"%s\" as criteria to process %s.", regexp, name);
- new->re = (regex_t *) malloc (sizeof (regex_t));
+ new->re = malloc (sizeof (*new->re));
if (new->re == NULL)
{
ERROR ("processes plugin: ps_list_register: malloc failed.");
if (status != 0)
{
DEBUG ("ProcessMatch: compiling the regular expression \"%s\" failed.", regexp);
- sfree(new->re);
- sfree(new);
+ sfree (new->re);
+ sfree (new);
return;
}
}
return (0);
} /* int ps_list_match */
+static void ps_update_counter (
+ _Bool init,
+ derive_t *group_counter,
+ derive_t *curr_counter, unsigned long *curr_value,
+ derive_t new_counter, unsigned long new_value) {
+ if (init)
+ {
+ *curr_value = new_value;
+ *curr_counter += new_value;
+ *group_counter += new_value;
+ return;
+ }
+
+ if (new_counter < *curr_counter)
+ {
+ *curr_value = new_counter + (ULONG_MAX - *curr_counter);
+ }
+ else
+ {
+ *curr_value = new_counter - *curr_counter;
+ }
+ *curr_counter = new_counter;
+ *group_counter += *curr_value;
+}
+
/* add process entry to 'instances' of process 'name' (or refresh it) */
static void ps_list_add (const char *name, const char *cmdline, procstat_entry_t *entry)
{
for (ps = list_head_g; ps != NULL; ps = ps->next)
{
+ _Bool want_init;
+
if ((ps_list_match (name, cmdline, ps)) == 0)
continue;
{
procstat_entry_t *new;
- new = (procstat_entry_t *) malloc (sizeof (procstat_entry_t));
+ new = calloc (1, sizeof (*new));
if (new == NULL)
return;
- memset (new, 0, sizeof (procstat_entry_t));
new->id = entry->id;
if (pse == NULL)
pse->io_wchar = entry->io_wchar;
pse->io_syscr = entry->io_syscr;
pse->io_syscw = entry->io_syscw;
+ pse->cswitch_vol = entry->cswitch_vol;
+ pse->cswitch_invol = entry->cswitch_invol;
ps->num_proc += pse->num_proc;
ps->num_lwp += pse->num_lwp;
ps->io_syscr += ((pse->io_syscr == -1)?0:pse->io_syscr);
ps->io_syscw += ((pse->io_syscw == -1)?0:pse->io_syscw);
- if ((entry->vmem_minflt_counter == 0)
- && (entry->vmem_majflt_counter == 0))
- {
- pse->vmem_minflt_counter += entry->vmem_minflt;
- pse->vmem_minflt = entry->vmem_minflt;
-
- pse->vmem_majflt_counter += entry->vmem_majflt;
- pse->vmem_majflt = entry->vmem_majflt;
- }
- else
- {
- if (entry->vmem_minflt_counter < pse->vmem_minflt_counter)
- {
- pse->vmem_minflt = entry->vmem_minflt_counter
- + (ULONG_MAX - pse->vmem_minflt_counter);
- }
- else
- {
- pse->vmem_minflt = entry->vmem_minflt_counter - pse->vmem_minflt_counter;
- }
- pse->vmem_minflt_counter = entry->vmem_minflt_counter;
-
- if (entry->vmem_majflt_counter < pse->vmem_majflt_counter)
- {
- pse->vmem_majflt = entry->vmem_majflt_counter
- + (ULONG_MAX - pse->vmem_majflt_counter);
- }
- else
- {
- pse->vmem_majflt = entry->vmem_majflt_counter - pse->vmem_majflt_counter;
- }
- pse->vmem_majflt_counter = entry->vmem_majflt_counter;
- }
-
- ps->vmem_minflt_counter += pse->vmem_minflt;
- ps->vmem_majflt_counter += pse->vmem_majflt;
-
- if ((entry->cpu_user_counter == 0)
- && (entry->cpu_system_counter == 0))
- {
- pse->cpu_user_counter += entry->cpu_user;
- pse->cpu_user = entry->cpu_user;
-
- pse->cpu_system_counter += entry->cpu_system;
- pse->cpu_system = entry->cpu_system;
- }
- else
- {
- if (entry->cpu_user_counter < pse->cpu_user_counter)
- {
- pse->cpu_user = entry->cpu_user_counter
- + (ULONG_MAX - pse->cpu_user_counter);
- }
- else
- {
- pse->cpu_user = entry->cpu_user_counter - pse->cpu_user_counter;
- }
- pse->cpu_user_counter = entry->cpu_user_counter;
-
- if (entry->cpu_system_counter < pse->cpu_system_counter)
- {
- pse->cpu_system = entry->cpu_system_counter
- + (ULONG_MAX - pse->cpu_system_counter);
- }
- else
- {
- pse->cpu_system = entry->cpu_system_counter - pse->cpu_system_counter;
- }
- pse->cpu_system_counter = entry->cpu_system_counter;
- }
-
- ps->cpu_user_counter += pse->cpu_user;
- ps->cpu_system_counter += pse->cpu_system;
+ ps->cswitch_vol += ((pse->cswitch_vol == -1)?0:pse->cswitch_vol);
+ ps->cswitch_invol += ((pse->cswitch_invol == -1)?0:pse->cswitch_invol);
+
+ want_init = (entry->vmem_minflt_counter == 0)
+ && (entry->vmem_majflt_counter == 0);
+ ps_update_counter (want_init,
+ &ps->vmem_minflt_counter,
+ &pse->vmem_minflt_counter, &pse->vmem_minflt,
+ entry->vmem_minflt_counter, entry->vmem_minflt);
+ ps_update_counter (want_init,
+ &ps->vmem_majflt_counter,
+ &pse->vmem_majflt_counter, &pse->vmem_majflt,
+ entry->vmem_majflt_counter, entry->vmem_majflt);
+
+ want_init = (entry->cpu_user_counter == 0)
+ && (entry->cpu_system_counter == 0);
+ ps_update_counter (want_init,
+ &ps->cpu_user_counter,
+ &pse->cpu_user_counter, &pse->cpu_user,
+ entry->cpu_user_counter, entry->cpu_user);
+ ps_update_counter (want_init,
+ &ps->cpu_system_counter,
+ &pse->cpu_system_counter, &pse->cpu_system,
+ entry->cpu_system_counter, entry->cpu_system);
}
}
ps->io_wchar = -1;
ps->io_syscr = -1;
ps->io_syscw = -1;
+ ps->cswitch_vol = -1;
+ ps->cswitch_invol = -1;
pse_prev = NULL;
pse = ps->instances;
ps_list_register (c->values[0].value.string,
c->values[1].value.string);
}
+ else if (strcasecmp (c->key, "CollectContextSwitch") == 0)
+ {
+ cf_util_get_boolean (c, &report_ctx_switch);
+ }
else
{
ERROR ("processes plugin: The `%s' configuration option is not "
plugin_dispatch_values (&vl);
}
+ if ( report_ctx_switch )
+ {
+ sstrncpy (vl.type, "contextswitch", sizeof (vl.type));
+ sstrncpy (vl.type_instance, "voluntary", sizeof (vl.type_instance));
+ vl.values[0].derive = ps->cswitch_vol;
+ vl.values_len = 1;
+ plugin_dispatch_values (&vl);
+
+ sstrncpy (vl.type, "contextswitch", sizeof (vl.type));
+ sstrncpy (vl.type_instance, "involuntary", sizeof (vl.type_instance));
+ vl.values[0].derive = ps->cswitch_invol;
+ vl.values_len = 1;
+ plugin_dispatch_values (&vl);
+ }
+
DEBUG ("name = %s; num_proc = %lu; num_lwp = %lu; "
"vmem_size = %lu; vmem_rss = %lu; vmem_data = %lu; "
"vmem_code = %lu; "
"vmem_minflt_counter = %"PRIi64"; vmem_majflt_counter = %"PRIi64"; "
"cpu_user_counter = %"PRIi64"; cpu_system_counter = %"PRIi64"; "
"io_rchar = %"PRIi64"; io_wchar = %"PRIi64"; "
- "io_syscr = %"PRIi64"; io_syscw = %"PRIi64";",
+ "io_syscr = %"PRIi64"; io_syscw = %"PRIi64"; "
+ "cswitch_vol = %"PRIi64"; cswitch_invol = %"PRIi64";",
ps->name, ps->num_proc, ps->num_lwp,
ps->vmem_size, ps->vmem_rss,
ps->vmem_data, ps->vmem_code,
ps->vmem_minflt_counter, ps->vmem_majflt_counter,
ps->cpu_user_counter, ps->cpu_system_counter,
- ps->io_rchar, ps->io_wchar, ps->io_syscr, ps->io_syscw);
+ ps->io_rchar, ps->io_wchar, ps->io_syscr, ps->io_syscw,
+ ps->cswitch_vol, ps->cswitch_invol);
} /* void ps_submit_proc_list */
#if KERNEL_LINUX || KERNEL_SOLARIS
/* ------- additional functions for KERNEL_LINUX/HAVE_THREAD_INFO ------- */
#if KERNEL_LINUX
-static int ps_read_tasks (long pid)
+static procstat_t *ps_read_tasks_status (long pid, procstat_t *ps)
{
char dirname[64];
DIR *dh;
+ char filename[64];
+ FILE *fh;
struct dirent *ent;
- int count = 0;
+ derive_t cswitch_vol = 0;
+ derive_t cswitch_invol = 0;
+ char buffer[1024];
+ char *fields[8];
+ int numfields;
ssnprintf (dirname, sizeof (dirname), "/proc/%li/task", pid);
if ((dh = opendir (dirname)) == NULL)
{
DEBUG ("Failed to open directory `%s'", dirname);
- return (-1);
+ return (NULL);
}
while ((ent = readdir (dh)) != NULL)
{
+ char *tpid;
+
if (!isdigit ((int) ent->d_name[0]))
continue;
- else
- count++;
+
+ tpid = ent->d_name;
+
+ ssnprintf (filename, sizeof (filename), "/proc/%li/task/%s/status", pid, tpid);
+ if ((fh = fopen (filename, "r")) == NULL)
+ {
+ DEBUG ("Failed to open file `%s'", filename);
+ continue;
+ }
+
+ while (fgets (buffer, sizeof(buffer), fh) != NULL)
+ {
+ derive_t tmp;
+ char *endptr;
+
+ if (strncmp (buffer, "voluntary_ctxt_switches", 23) != 0
+ && strncmp (buffer, "nonvoluntary_ctxt_switches", 26) != 0)
+ continue;
+
+ numfields = strsplit (buffer, fields,
+ STATIC_ARRAY_SIZE (fields));
+
+ if (numfields < 2)
+ continue;
+
+ errno = 0;
+ endptr = NULL;
+ tmp = (derive_t) strtoll (fields[1], &endptr, /* base = */ 10);
+ if ((errno == 0) && (endptr != fields[1]))
+ {
+ if (strncmp (buffer, "voluntary_ctxt_switches", 23) == 0)
+ {
+ cswitch_vol += tmp;
+ }
+ else if (strncmp (buffer, "nonvoluntary_ctxt_switches", 26) == 0)
+ {
+ cswitch_invol += tmp;
+ }
+ }
+ } /* while (fgets) */
+
+ if (fclose (fh))
+ {
+ char errbuf[1024];
+ WARNING ("processes: fclose: %s",
+ sstrerror (errno, errbuf, sizeof (errbuf)));
+ }
}
closedir (dh);
- return ((count >= 1) ? count : 1);
-} /* int *ps_read_tasks */
+ ps->cswitch_vol = cswitch_vol;
+ ps->cswitch_invol = cswitch_invol;
-/* Read advanced virtual memory data from /proc/pid/status */
-static procstat_t *ps_read_vmem (long pid, procstat_t *ps)
+ return (ps);
+} /* int *ps_read_tasks_status */
+
+/* Read data from /proc/pid/status */
+static procstat_t *ps_read_status (long pid, procstat_t *ps)
{
FILE *fh;
char buffer[1024];
char filename[64];
- unsigned long long lib = 0;
- unsigned long long exe = 0;
- unsigned long long data = 0;
+ unsigned long lib = 0;
+ unsigned long exe = 0;
+ unsigned long data = 0;
+ unsigned long threads = 0;
char *fields[8];
int numfields;
while (fgets (buffer, sizeof(buffer), fh) != NULL)
{
- long long tmp;
+ unsigned long tmp;
char *endptr;
- if (strncmp (buffer, "Vm", 2) != 0)
+ if (strncmp (buffer, "Vm", 2) != 0
+ && strncmp (buffer, "Threads", 7) != 0)
continue;
numfields = strsplit (buffer, fields,
errno = 0;
endptr = NULL;
- tmp = strtoll (fields[1], &endptr, /* base = */ 10);
+ tmp = strtoul (fields[1], &endptr, /* base = */ 10);
if ((errno == 0) && (endptr != fields[1]))
{
if (strncmp (buffer, "VmData", 6) == 0)
{
exe = tmp;
}
+ else if (strncmp(buffer, "Threads", 7) == 0)
+ {
+ threads = tmp;
+ }
}
} /* while (fgets) */
ps->vmem_data = data * 1024;
ps->vmem_code = (exe + lib) * 1024;
+ if (threads != 0)
+ ps->num_lwp = threads;
return (ps);
} /* procstat_t *ps_read_vmem */
char *fields[64];
char fields_len;
- int buffer_len;
+ size_t buffer_len;
- char *buffer_ptr;
+ char *buffer_ptr;
size_t name_start_pos;
size_t name_end_pos;
size_t name_len;
long long unsigned vmem_rss;
long long unsigned stack_size;
+ ssize_t status;
+
memset (ps, 0, sizeof (procstat_t));
ssnprintf (filename, sizeof (filename), "/proc/%li/stat", pid);
- buffer_len = read_file_contents (filename,
- buffer, sizeof(buffer) - 1);
- if (buffer_len <= 0)
+ status = read_file_contents (filename, buffer, sizeof(buffer) - 1);
+ if (status <= 0)
return (-1);
+ buffer_len = (size_t) status;
buffer[buffer_len] = 0;
/* The name of the process is enclosed in parens. Since the name can
* strchr(3) and strrchr(3) to avoid pointer arithmetic which would
* otherwise be required to determine name_len. */
name_start_pos = 0;
- while ((buffer[name_start_pos] != '(')
- && (name_start_pos < buffer_len))
+ while (name_start_pos < buffer_len && buffer[name_start_pos] != '(')
name_start_pos++;
name_end_pos = buffer_len;
- while ((buffer[name_end_pos] != ')')
- && (name_end_pos > 0))
+ while (name_end_pos > 0 && buffer[name_end_pos] != ')')
name_end_pos--;
/* Either '(' or ')' is not found or they are in the wrong order.
}
else
{
- if ( (ps->num_lwp = ps_read_tasks (pid)) == -1 )
+ ps->num_lwp = strtoul (fields[17], /* endptr = */ NULL, /* base = */ 10);
+ if ((ps_read_status(pid, ps)) == NULL)
{
- /* returns -1 => kernel 2.4 */
- ps->num_lwp = 1;
+ /* No VMem data */
+ ps->vmem_data = -1;
+ ps->vmem_code = -1;
+ DEBUG("ps_read_process: did not get vmem data for pid %li", pid);
}
+ if (ps->num_lwp == 0)
+ ps->num_lwp = 1;
ps->num_proc = 1;
}
cpu_system_counter = cpu_system_counter * 1000000 / CONFIG_HZ;
vmem_rss = vmem_rss * pagesize_g;
- if ( (ps_read_vmem(pid, ps)) == NULL)
- {
- /* No VMem data */
- ps->vmem_data = -1;
- ps->vmem_code = -1;
- DEBUG("ps_read_process: did not get vmem data for pid %li", pid);
- }
-
ps->cpu_user_counter = cpu_user_counter;
ps->cpu_system_counter = cpu_system_counter;
ps->vmem_size = (unsigned long) vmem_size;
DEBUG("ps_read_process: not get io data for pid %li", pid);
}
+ if ( report_ctx_switch )
+ {
+ if ( (ps_read_tasks_status(pid, ps)) == NULL)
+ {
+ ps->cswitch_vol = -1;
+ ps->cswitch_invol = -1;
+
+ DEBUG("ps_read_tasks_status: not get context "
+ "switch data for pid %li", pid);
+ }
+ }
+
/* success */
return (0);
} /* int ps_read_process (...) */
buf_ptr += status;
len -= status;
- if (len <= 0)
+ if (len == 0)
break;
}
{
char path[PATH_MAX];
psinfo_t info;
- int status;
+ ssize_t status;
snprintf(path, sizeof (path), "/proc/%li/psinfo", pid);
status = read_file_contents (path, (void *) &info, sizeof (info));
- if (status != sizeof (info))
+ if ((status < 0) || (((size_t) status) != sizeof (info)))
{
ERROR ("processes plugin: Unexpected return value "
"while reading \"%s\": "
- "Returned %i but expected %zu.",
+ "Returned %zd but expected %zu.",
path, status, buffer_size);
return (NULL);
}
snprintf(f_usage, sizeof (f_usage), "/proc/%li/usage", pid);
- buffer = malloc(sizeof (pstatus_t));
- memset(buffer, 0, sizeof (pstatus_t));
+ buffer = calloc(1, sizeof (pstatus_t));
read_file_contents(filename, buffer, sizeof (pstatus_t));
myStatus = (pstatus_t *) buffer;
- buffer = malloc(sizeof (psinfo_t));
- memset(buffer, 0, sizeof(psinfo_t));
+ buffer = calloc(1, sizeof (psinfo_t));
read_file_contents(f_psinfo, buffer, sizeof (psinfo_t));
myInfo = (psinfo_t *) buffer;
- buffer = malloc(sizeof (prusage_t));
- memset(buffer, 0, sizeof(prusage_t));
+ buffer = calloc(1, sizeof (prusage_t));
read_file_contents(f_usage, buffer, sizeof (prusage_t));
myUsage = (prusage_t *) buffer;
ps->io_syscr = myUsage->pr_sysc;
ps->io_syscw = myUsage->pr_sysc;
+ /*
+ * TODO: context switch counters for Solaris
+ */
+ ps->cswitch_vol = -1;
+ ps->cswitch_invol = -1;
+
/*
* TODO: Find way of setting BLOCKED and PAGING status
* are retrieved from kstat (module cpu, name sys, class misc, stat nthreads).
* The result is the sum for all the threads created on each cpu
*/
-static int read_fork_rate()
+static int read_fork_rate (void)
{
extern kstat_ctl_t *kc;
kstat_t *ksp_chain = NULL;
pse.cpu_user_counter = task_absolutetime_info.total_user;
pse.cpu_system_counter = task_absolutetime_info.total_system;
+
+ /* context switch counters not implemented */
+ pse.cswitch_vol = -1;
+ pse.cswitch_invol = -1;
}
status = task_threads (task_list[task], &thread_list,
pse.io_syscr = ps.io_syscr;
pse.io_syscw = ps.io_syscw;
+ pse.cswitch_vol = ps.cswitch_vol;
+ pse.cswitch_invol = ps.cswitch_invol;
+
switch (state)
{
case 'R': running++; break;
pse.io_syscr = -1;
pse.io_syscw = -1;
+ /* context switch counters not implemented */
+ pse.cswitch_vol = -1;
+ pse.cswitch_invol = -1;
+
ps_list_add (procs[i].ki_comm, have_cmdline ? cmdline : NULL, &pse);
switch (procs[i].ki_stat)
pse.io_syscr = -1;
pse.io_syscw = -1;
+ /* context switch counters not implemented */
+ pse.cswitch_vol = -1;
+ pse.cswitch_invol = -1;
+
ps_list_add (procs[i].p_comm, have_cmdline ? cmdline : NULL, &pse);
switch (procs[i].p_stat)
pse.io_syscr = -1;
pse.io_syscw = -1;
+ pse.cswitch_vol = -1;
+ pse.cswitch_invol = -1;
+
ps_list_add (cmdline, cargs, &pse);
} /* for (i = 0 .. nprocs) */
pse.io_syscr = ps.io_syscr;
pse.io_syscw = ps.io_syscw;
+ pse.cswitch_vol = -1;
+ pse.cswitch_invol = -1;
+
switch (state)
{
case 'R': running++; break;
static ignorelist_t *values_list = NULL;
-/*
+/*
* Functions
*/
static void submit (const char *protocol_name,
* DEALINGS IN THE SOFTWARE.
*
* Authors:
- * Sven Trenkel <collectd at semidefinite.de>
+ * Sven Trenkel <collectd at semidefinite.de>
**/
#include <Python.h>
static PyObject *Config_new(PyTypeObject *type, PyObject *args, PyObject *kwds) {
Config *self;
-
+
self = (Config *) type->tp_alloc(type, 0);
if (self == NULL)
return NULL;
-
+
self->parent = NULL;
self->key = NULL;
self->values = NULL;
PyObject *key = NULL, *parent = NULL, *values = NULL, *children = NULL, *tmp;
Config *self = (Config *) s;
static char *kwlist[] = {"key", "parent", "values", "children", NULL};
-
+
if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|OOO", kwlist,
&key, &parent, &values, &children))
return -1;
-
+
if (!IS_BYTES_OR_UNICODE(key)) {
PyErr_SetString(PyExc_TypeError, "argument 1 must be str");
Py_XDECREF(parent);
Config *self = (Config *) s;
PyObject *ret = NULL;
static PyObject *node_prefix = NULL, *root_prefix = NULL, *ending = NULL;
-
+
/* This is ok because we have the GIL, so this is thread-save by default. */
if (node_prefix == NULL)
node_prefix = cpy_string_to_unicode_or_bytes("<collectd.Config node ");
ending = cpy_string_to_unicode_or_bytes(">");
if (node_prefix == NULL || root_prefix == NULL || ending == NULL)
return NULL;
-
+
ret = PyObject_Str(self->key);
CPY_SUBSTITUTE(PyObject_Repr, ret, ret);
if (self->parent == NULL || self->parent == Py_None)
else
CPY_STRCAT(&ret, node_prefix);
CPY_STRCAT(&ret, ending);
-
+
return ret;
}
* DEALINGS IN THE SOFTWARE.
*
* Authors:
- * Sven Trenkel <collectd at semidefinite.de>
+ * Sven Trenkel <collectd at semidefinite.de>
**/
#include <Python.h>
static void cpy_build_name(char *buf, size_t size, PyObject *callback, const char *name) {
const char *module = NULL;
PyObject *mod = NULL;
-
+
if (name != NULL) {
snprintf(buf, size, "python.%s", name);
return;
}
-
+
mod = PyObject_GetAttrString(callback, "__module__"); /* New reference. */
if (mod != NULL)
module = cpy_unicode_or_bytes_to_string(&mod);
-
+
if (module != NULL) {
snprintf(buf, size, "python.%s", module);
Py_XDECREF(mod);
return;
}
Py_XDECREF(mod);
-
+
snprintf(buf, size, "python.%p", callback);
PyErr_Clear();
}
int l = 0, i;
const char *typename = NULL, *message = NULL;
PyObject *type, *value, *traceback, *tn, *m, *list;
-
+
PyErr_Fetch(&type, &value, &traceback);
PyErr_NormalizeException(&type, &value, &traceback);
if (type == NULL) return;
}
static int cpy_write_callback(const data_set_t *ds, const value_list_t *value_list, user_data_t *data) {
- int i;
+ size_t i;
cpy_callback_t *c = data->data;
PyObject *ret, *list, *temp, *dict = NULL;
Values *v;
}
for (i = 0; i < value_list->values_len; ++i) {
if (ds->ds[i].type == DS_TYPE_COUNTER) {
- if ((long) value_list->values[i].counter == value_list->values[i].counter)
- PyList_SetItem(list, i, PyInt_FromLong(value_list->values[i].counter));
- else
- PyList_SetItem(list, i, PyLong_FromUnsignedLongLong(value_list->values[i].counter));
+ PyList_SetItem(list, i, PyLong_FromUnsignedLongLong(value_list->values[i].counter));
} else if (ds->ds[i].type == DS_TYPE_GAUGE) {
PyList_SetItem(list, i, PyFloat_FromDouble(value_list->values[i].gauge));
} else if (ds->ds[i].type == DS_TYPE_DERIVE) {
- if ((long) value_list->values[i].derive == value_list->values[i].derive)
- PyList_SetItem(list, i, PyInt_FromLong(value_list->values[i].derive));
- else
- PyList_SetItem(list, i, PyLong_FromLongLong(value_list->values[i].derive));
+ PyList_SetItem(list, i, PyLong_FromLongLong(value_list->values[i].derive));
} else if (ds->ds[i].type == DS_TYPE_ABSOLUTE) {
- if ((long) value_list->values[i].absolute == value_list->values[i].absolute)
- PyList_SetItem(list, i, PyInt_FromLong(value_list->values[i].absolute));
- else
- PyList_SetItem(list, i, PyLong_FromUnsignedLongLong(value_list->values[i].absolute));
+ PyList_SetItem(list, i, PyLong_FromUnsignedLongLong(value_list->values[i].absolute));
} else {
Py_BEGIN_ALLOW_THREADS
ERROR("cpy_write_callback: Unknown value type %d.", ds->ds[i].type);
uint64_t ui;
double d;
_Bool b;
-
+
type = meta_data_type(meta, table[i]);
if (type == MD_TYPE_STRING) {
if (meta_data_get_string(meta, table[i], &string))
char *name = NULL;
PyObject *callback = NULL, *data = NULL, *mod = NULL;
static char *kwlist[] = {"callback", "data", "name", NULL};
-
+
if (PyArg_ParseTupleAndKeywords(args, kwds, "O|Oet", kwlist, &callback, &data, NULL, &name) == 0) return NULL;
if (PyCallable_Check(callback) == 0) {
PyMem_Free(name);
Py_INCREF(callback);
Py_XINCREF(data);
- c = malloc(sizeof(*c));
+ c = calloc(1, sizeof(*c));
if (c == NULL)
return NULL;
- memset (c, 0, sizeof (*c));
c->name = strdup(buf);
c->callback = callback;
}
static PyObject *cpy_get_dataset(PyObject *self, PyObject *args) {
- int i;
+ size_t i;
char *name;
const data_set_t *ds;
PyObject *list, *tuple;
int timeout = -1;
char *plugin = NULL, *identifier = NULL;
static char *kwlist[] = {"plugin", "timeout", "identifier", NULL};
-
+
if (PyArg_ParseTupleAndKeywords(args, kwds, "|etiet", kwlist, NULL, &plugin, &timeout, NULL, &identifier) == 0) return NULL;
Py_BEGIN_ALLOW_THREADS
plugin_flush(plugin, timeout, identifier);
char *name = NULL;
PyObject *callback = NULL, *data = NULL;
static char *kwlist[] = {"callback", "data", "name", NULL};
-
+
if (PyArg_ParseTupleAndKeywords(args, kwds, "O|Oet", kwlist, &callback, &data, NULL, &name) == 0) return NULL;
if (PyCallable_Check(callback) == 0) {
PyMem_Free(name);
}
cpy_build_name(buf, sizeof(buf), callback, name);
PyMem_Free(name);
-
+
Py_INCREF(callback);
Py_XINCREF(data);
- c = malloc(sizeof(*c));
+ c = calloc(1, sizeof(*c));
if (c == NULL)
return NULL;
- memset (c, 0, sizeof (*c));
c->name = strdup(buf);
c->callback = callback;
double interval = 0;
char *name = NULL;
PyObject *callback = NULL, *data = NULL;
- struct timespec ts;
static char *kwlist[] = {"callback", "interval", "data", "name", NULL};
-
+
if (PyArg_ParseTupleAndKeywords(args, kwds, "O|dOet", kwlist, &callback, &interval, &data, NULL, &name) == 0) return NULL;
if (PyCallable_Check(callback) == 0) {
PyMem_Free(name);
}
cpy_build_name(buf, sizeof(buf), callback, name);
PyMem_Free(name);
-
+
Py_INCREF(callback);
Py_XINCREF(data);
- c = malloc(sizeof(*c));
+ c = calloc(1, sizeof(*c));
if (c == NULL)
return NULL;
- memset (c, 0, sizeof (*c));
c->name = strdup(buf);
c->callback = callback;
user_data.free_func = cpy_destroy_user_data;
user_data.data = c;
- ts.tv_sec = interval;
- ts.tv_nsec = (interval - ts.tv_sec) * 1000000000;
plugin_register_complex_read(/* group = */ "python", buf,
- cpy_read_callback, &ts, &user_data);
-
+ cpy_read_callback, DOUBLE_TO_CDTIME_T (interval), &user_data);
return cpy_string_to_unicode_or_bytes(buf);
}
static int cpy_shutdown(void) {
cpy_callback_t *c;
PyObject *ret;
-
+
/* This can happen if the module was loaded but not configured. */
if (state != NULL)
PyEval_RestoreThread(state);
static void *cpy_interactive(void *data) {
sigset_t sigset;
struct sigaction sig_int_action, old;
-
+
/* Signal handler in a plugin? Bad stuff, but the best way to
* handle it I guess. In an interactive session people will
* press Ctrl+C at some time, which will generate a SIGINT.
* This will cause collectd to shutdown, thus killing the
* interactive interpreter, and leaving the terminal in a
* mess. Chances are, this isn't what the user wanted to do.
- *
+ *
* So this is the plan:
* 1. Block SIGINT in the main thread.
* 2. Install our own signal handler that does nothing.
memset (&sig_int_action, '\0', sizeof (sig_int_action));
sig_int_action.sa_handler = cpy_int_handler;
sigaction (SIGINT, &sig_int_action, &old);
-
+
sigemptyset(&sigset);
sigaddset(&sigset, SIGINT);
pthread_sigmask(SIG_UNBLOCK, &sigset, NULL);
PyObject *ret;
static pthread_t thread;
sigset_t sigset;
-
+
if (!Py_IsInitialized()) {
WARNING("python: Plugin loaded but not configured.");
plugin_unregister_shutdown("python");
static PyObject *cpy_oconfig_to_pyconfig(oconfig_item_t *ci, PyObject *parent) {
int i;
PyObject *item, *values, *children, *tmp;
-
+
if (parent == NULL)
parent = Py_None;
-
+
values = PyTuple_New(ci->values_num); /* New reference. */
for (i = 0; i < ci->values_num; ++i) {
if (ci->values[i].type == OCONFIG_TYPE_STRING) {
PyTuple_SET_ITEM(values, i, PyBool_FromLong(ci->values[i].value.boolean));
}
}
-
+
tmp = cpy_string_to_unicode_or_bytes(ci->key);
item = PyObject_CallFunction((void *) &ConfigType, "NONO", tmp, parent, values, Py_None);
if (item == NULL)
#else
char *argv = "";
#endif
-
+
Py_Initialize();
-
+
PyType_Ready(&ConfigType);
PyType_Ready(&PluginDataType);
ValuesType.tp_base = &PluginDataType;
for (i = 0; i < ci->children_num; ++i) {
oconfig_item_t *item = ci->children + i;
-
+
if (strcasecmp(item->key, "Interactive") == 0) {
if (item->values_num != 1 || item->values[0].type != OCONFIG_TYPE_BOOLEAN)
continue;
} else if (strcasecmp(item->key, "ModulePath") == 0) {
char *dir = NULL;
PyObject *dir_object;
-
- if (cf_util_get_string(item, &dir) != 0)
+
+ if (cf_util_get_string(item, &dir) != 0)
continue;
dir_object = cpy_string_to_unicode_or_bytes(dir); /* New reference. */
if (dir_object == NULL) {
} else if (strcasecmp(item->key, "Import") == 0) {
char *module_name = NULL;
PyObject *module;
-
- if (cf_util_get_string(item, &module_name) != 0)
+
+ if (cf_util_get_string(item, &module_name) != 0)
continue;
module = PyImport_ImportModule(module_name); /* New reference. */
if (module == NULL) {
char *name = NULL;
cpy_callback_t *c;
PyObject *ret;
-
+
if (cf_util_get_string(item, &name) != 0)
continue;
for (c = cpy_config_callbacks; c; c = c->next) {
* DEALINGS IN THE SOFTWARE.
*
* Authors:
- * Sven Trenkel <collectd at semidefinite.de>
+ * Sven Trenkel <collectd at semidefinite.de>
**/
#include <Python.h>
static PyObject *l_type = NULL, *l_type_instance = NULL, *l_plugin = NULL, *l_plugin_instance = NULL;
static PyObject *l_host = NULL, *l_time = NULL;
PluginData *self = (PluginData *) s;
-
+
if (l_type == NULL)
l_type = cpy_string_to_unicode_or_bytes("(type=");
if (l_type_instance == NULL)
l_host = cpy_string_to_unicode_or_bytes(",host=");
if (l_time == NULL)
l_time = cpy_string_to_unicode_or_bytes(",time=");
-
+
if (!l_type || !l_type_instance || !l_plugin || !l_plugin_instance || !l_host || !l_time)
return NULL;
-
+
ret = cpy_string_to_unicode_or_bytes(s->ob_type->tp_name);
CPY_STRCAT(&ret, l_type);
return ret;
}
-static char time_doc[] = "This is the Unix timestap of the time this value was read.\n"
+static char time_doc[] = "This is the Unix timestamp of the time this value was read.\n"
"For dispatching values this can be set to 0 which means \"now\".\n"
"This means the time the value is actually dispatched, not the time\n"
"it was set to 0.";
static char host_doc[] = "The hostname of the host this value was read from.\n"
"For dispatching this can be set to an empty string which means\n"
- "the local hostname as defined in the collectd.conf.";
+ "the local hostname as defined in collectd.conf.";
static char type_doc[] = "The type of this value. This type has to be defined\n"
- "in your types.db. Attempting to set it to any other value will\n"
- "raise a TypeError exception.\n"
- "Assigning a type is mandetory, calling dispatch without doing\n"
+ "in the types.db file. Attempting to set it to any other value\n"
+ "will raise a TypeError exception.\n"
+ "Assigning a type is mandatory, calling dispatch without doing\n"
"so will raise a RuntimeError exception.";
static char type_instance_doc[] = "";
static char plugin_instance_doc[] = "";
static char PluginData_doc[] = "This is an internal class that is the base for Values\n"
- "and Notification. It is pretty useless by itself and was therefore not\n"
+ "and Notification. It is pretty useless by itself and is therefore not\n"
"exported to the collectd module.";
static PyObject *PluginData_new(PyTypeObject *type, PyObject *args, PyObject *kwds) {
PluginData *self;
-
+
self = (PluginData *) type->tp_alloc(type, 0);
if (self == NULL)
return NULL;
-
+
self->time = 0;
self->host[0] = 0;
self->plugin[0] = 0;
char *type = NULL, *plugin_instance = NULL, *type_instance = NULL, *plugin = NULL, *host = NULL;
static char *kwlist[] = {"type", "plugin_instance", "type_instance",
"plugin", "host", "time", NULL};
-
+
if (!PyArg_ParseTupleAndKeywords(args, kwds, "|etetetetetd", kwlist, NULL, &type,
NULL, &plugin_instance, NULL, &type_instance, NULL, &plugin, NULL, &host, &time))
return -1;
-
+
if (type && plugin_get_ds(type) == NULL) {
PyErr_Format(PyExc_TypeError, "Dataset %s not found", type);
FreeAll();
static PyObject *PluginData_repr(PyObject *s) {
PyObject *ret;
static PyObject *l_closing = NULL;
-
+
if (l_closing == NULL)
l_closing = cpy_string_to_unicode_or_bytes(")");
-
+
if (l_closing == NULL)
return NULL;
-
+
ret = cpy_common_repr(s);
CPY_STRCAT(&ret, l_closing);
return ret;
static PyObject *PluginData_getstring(PyObject *self, void *data) {
const char *value = ((char *) self) + (intptr_t) data;
-
+
return cpy_string_to_unicode_or_bytes(value);
}
static int PluginData_setstring(PyObject *self, PyObject *value, void *data) {
char *old;
const char *new;
-
+
if (value == NULL) {
PyErr_SetString(PyExc_TypeError, "Cannot delete this attribute");
return -1;
static int PluginData_settype(PyObject *self, PyObject *value, void *data) {
char *old;
const char *new;
-
+
if (value == NULL) {
PyErr_SetString(PyExc_TypeError, "Cannot delete this attribute");
return -1;
static char values_doc[] = "These are the actual values that get dispatched to collectd.\n"
"It has to be a sequence (a tuple or list) of numbers.\n"
"The size of the sequence and the type of its content depend on the type\n"
- "member your types.db file. For more information on this read the types.db\n"
- "man page.\n"
+ "member in the types.db file. For more information on this read the\n"
+ "types.db man page.\n"
"\n"
"If the sequence does not have the correct size upon dispatch a RuntimeError\n"
"exception will be raised. If the content of the sequence is not a number,\n"
static char meta_doc[] = "These are the meta data for this Value object.\n"
"It has to be a dictionary of numbers, strings or bools. All keys must be\n"
"strings. int and long objects will be dispatched as signed integers unless\n"
- "they are between 2**63 and 2**64-1, which will result in a unsigned integer.\n"
+ "they are between 2**63 and 2**64-1, which will result in an unsigned integer.\n"
"You can force one of these storage classes by using the classes\n"
"collectd.Signed and collectd.Unsigned. A meta object received by a write\n"
"callback will always contain Signed or Unsigned objects.";
static char write_doc[] = "write([destination][, type][, values][, plugin_instance][, type_instance]"
"[, plugin][, host][, time][, interval]) -> None. Dispatch a value list.\n"
"\n"
- "Write this instance to a single plugin or all plugins if 'destination' is obmitted.\n"
+ "Write this instance to a single plugin or all plugins if 'destination' is omitted.\n"
"This will bypass the main collectd process and all filtering and caching.\n"
"Other than that it works similar to 'dispatch'. In most cases 'dispatch' should be\n"
"used instead of 'write'.\n";
static PyObject *Values_new(PyTypeObject *type, PyObject *args, PyObject *kwds) {
Values *self;
-
+
self = (Values *) PluginData_new(type, args, kwds);
if (self == NULL)
return NULL;
-
+
self->values = PyList_New(0);
self->meta = PyDict_New();
self->interval = 0;
char *type = NULL, *plugin_instance = NULL, *type_instance = NULL, *plugin = NULL, *host = NULL;
static char *kwlist[] = {"type", "values", "plugin_instance", "type_instance",
"plugin", "host", "time", "interval", "meta", NULL};
-
+
if (!PyArg_ParseTupleAndKeywords(args, kwds, "|etOetetetetddO", kwlist,
NULL, &type, &values, NULL, &plugin_instance, NULL, &type_instance,
NULL, &plugin, NULL, &host, &time, &interval, &meta))
return -1;
-
+
if (type && plugin_get_ds(type) == NULL) {
PyErr_Format(PyExc_TypeError, "Dataset %s not found", type);
FreeAll();
} else {
Py_INCREF(values);
}
-
+
if (meta == NULL) {
meta = PyDict_New();
PyErr_Clear();
} else {
Py_INCREF(meta);
}
-
+
tmp = self->values;
self->values = values;
Py_XDECREF(tmp);
-
+
tmp = self->meta;
self->meta = meta;
Py_XDECREF(tmp);
int i, s;
meta_data_t *m = NULL;
PyObject *l;
-
+
if ((meta == NULL) || (meta == Py_None))
return NULL;
for (i = 0; i < s; ++i) {
const char *string, *keystring;
PyObject *key, *value, *item, *tmp;
-
+
item = PyList_GET_ITEM(l, i);
key = PyTuple_GET_ITEM(item, 0);
Py_INCREF(key);
}
static PyObject *Values_dispatch(Values *self, PyObject *args, PyObject *kwds) {
- int i, ret;
+ int ret;
const data_set_t *ds;
- int size;
+ size_t size, i;
value_t *value;
value_list_t value_list = VALUE_LIST_INIT;
PyObject *values = self->values, *meta = self->meta;
double time = self->data.time, interval = self->interval;
char *host = NULL, *plugin = NULL, *plugin_instance = NULL, *type = NULL, *type_instance = NULL;
-
+
static char *kwlist[] = {"type", "values", "plugin_instance", "type_instance",
"plugin", "host", "time", "interval", "meta", NULL};
if (!PyArg_ParseTupleAndKeywords(args, kwds, "|etOetetetetddO", kwlist,
PyErr_Format(PyExc_TypeError, "meta must be a dict");
return NULL;
}
- size = (int) PySequence_Length(values);
+ size = (size_t) PySequence_Length(values);
if (size != ds->ds_num) {
- PyErr_Format(PyExc_RuntimeError, "type %s needs %d values, got %i", value_list.type, ds->ds_num, size);
+ PyErr_Format(PyExc_RuntimeError, "type %s needs %zu values, got %zu", value_list.type, ds->ds_num, size);
return NULL;
}
- value = malloc(size * sizeof(*value));
+ value = calloc(size, sizeof(*value));
for (i = 0; i < size; ++i) {
PyObject *item, *num;
- item = PySequence_Fast_GET_ITEM(values, i); /* Borrowed reference. */
+ item = PySequence_Fast_GET_ITEM(values, (int) i); /* Borrowed reference. */
if (ds->ds->type == DS_TYPE_COUNTER) {
num = PyNumber_Long(item); /* New reference. */
if (num != NULL) {
}
static PyObject *Values_write(Values *self, PyObject *args, PyObject *kwds) {
- int i, ret;
+ int ret;
const data_set_t *ds;
- int size;
+ size_t size, i;
value_t *value;
value_list_t value_list = VALUE_LIST_INIT;
PyObject *values = self->values, *meta = self->meta;
double time = self->data.time, interval = self->interval;
char *host = NULL, *plugin = NULL, *plugin_instance = NULL, *type = NULL, *type_instance = NULL, *dest = NULL;
-
+
static char *kwlist[] = {"destination", "type", "values", "plugin_instance", "type_instance",
"plugin", "host", "time", "interval", "meta", NULL};
if (!PyArg_ParseTupleAndKeywords(args, kwds, "et|etOetetetetdiO", kwlist, NULL, &dest,
PyErr_Format(PyExc_TypeError, "values must be list or tuple");
return NULL;
}
- size = (int) PySequence_Length(values);
+ size = (size_t) PySequence_Length(values);
if (size != ds->ds_num) {
- PyErr_Format(PyExc_RuntimeError, "type %s needs %d values, got %i", value_list.type, ds->ds_num, size);
+ PyErr_Format(PyExc_RuntimeError, "type %s needs %zu values, got %zu", value_list.type, ds->ds_num, size);
return NULL;
}
- value = malloc(size * sizeof(*value));
+ value = calloc(size, sizeof(*value));
for (i = 0; i < size; ++i) {
PyObject *item, *num;
item = PySequence_Fast_GET_ITEM(values, i); /* Borrowed reference. */
value_list.values_len = size;
value_list.time = DOUBLE_TO_CDTIME_T(time);
value_list.interval = DOUBLE_TO_CDTIME_T(interval);
- value_list.meta = cpy_build_meta(meta);;
+ value_list.meta = cpy_build_meta(meta);
if (value_list.host[0] == 0)
sstrncpy(value_list.host, hostname_g, sizeof(value_list.host));
if (value_list.plugin[0] == 0)
PyObject *ret, *tmp;
static PyObject *l_interval = NULL, *l_values = NULL, *l_meta = NULL, *l_closing = NULL;
Values *self = (Values *) s;
-
+
if (l_interval == NULL)
l_interval = cpy_string_to_unicode_or_bytes(",interval=");
if (l_values == NULL)
l_meta = cpy_string_to_unicode_or_bytes(",meta=");
if (l_closing == NULL)
l_closing = cpy_string_to_unicode_or_bytes(")");
-
+
if (l_interval == NULL || l_values == NULL || l_meta == NULL || l_closing == NULL)
return NULL;
-
+
ret = cpy_common_repr(s);
if (self->interval != 0) {
CPY_STRCAT(&ret, l_interval);
char *type = NULL, *plugin_instance = NULL, *type_instance = NULL, *plugin = NULL, *host = NULL;
static char *kwlist[] = {"type", "message", "plugin_instance", "type_instance",
"plugin", "host", "time", "severity", NULL};
-
+
if (!PyArg_ParseTupleAndKeywords(args, kwds, "|etetetetetetdi", kwlist,
NULL, &type, NULL, &message, NULL, &plugin_instance, NULL, &type_instance,
NULL, &plugin, NULL, &host, &time, &severity))
return -1;
-
+
if (type && plugin_get_ds(type) == NULL) {
PyErr_Format(PyExc_TypeError, "Dataset %s not found", type);
FreeAll();
int severity = self->severity;
char *host = NULL, *plugin = NULL, *plugin_instance = NULL, *type = NULL, *type_instance = NULL;
char *message = NULL;
-
+
static char *kwlist[] = {"type", "message", "plugin_instance", "type_instance",
"plugin", "host", "time", "severity", NULL};
if (!PyArg_ParseTupleAndKeywords(args, kwds, "|etetetetetetdi", kwlist,
static PyObject *Notification_new(PyTypeObject *type, PyObject *args, PyObject *kwds) {
Notification *self;
-
+
self = (Notification *) PluginData_new(type, args, kwds);
if (self == NULL)
return NULL;
-
+
self->message[0] = 0;
self->severity = 0;
return (PyObject *) self;
static int Notification_setstring(PyObject *self, PyObject *value, void *data) {
char *old;
const char *new;
-
+
if (value == NULL) {
PyErr_SetString(PyExc_TypeError, "Cannot delete this attribute");
return -1;
PyObject *ret, *tmp;
static PyObject *l_severity = NULL, *l_message = NULL, *l_closing = NULL;
Notification *self = (Notification *) s;
-
+
if (l_severity == NULL)
l_severity = cpy_string_to_unicode_or_bytes(",severity=");
if (l_message == NULL)
l_message = cpy_string_to_unicode_or_bytes(",message=");
if (l_closing == NULL)
l_closing = cpy_string_to_unicode_or_bytes(")");
-
+
if (l_severity == NULL || l_message == NULL || l_closing == NULL)
return NULL;
-
+
ret = cpy_common_repr(s);
if (self->severity != 0) {
CPY_STRCAT(&ret, l_severity);
rq = calloc(1, sizeof(*rq));
if (rq == NULL) {
- ERROR("redis plugin: calloca failed adding redis_query.");
+ ERROR("redis plugin: calloc failed adding redis_query.");
return NULL;
}
status = cf_util_get_string_buffer(ci, rq->query, sizeof(rq->query));
int i;
str += strlen (field_name) + 1; /* also skip the ':' */
- for(i=0;(*str && (isdigit(*str) || *str == '.'));i++,str++)
+ for(i=0;(*str && (isdigit((unsigned char)*str) || *str == '.'));i++,str++)
buf[i] = *str;
buf[i] ='\0';
redis_handle_info (rn->name, rr->str, "total_connections", NULL, "total_connections_received", DS_TYPE_DERIVE);
redis_handle_info (rn->name, rr->str, "total_operations", NULL, "total_commands_processed", DS_TYPE_DERIVE);
redis_handle_info (rn->name, rr->str, "expired_keys", NULL, "expired_keys", DS_TYPE_DERIVE);
+ redis_handle_info (rn->name, rr->str, "evicted_keys", NULL, "evicted_keys", DS_TYPE_DERIVE);
redis_handle_info (rn->name, rr->str, "pubsub", "channels", "pubsub_channels", DS_TYPE_GAUGE);
redis_handle_info (rn->name, rr->str, "pubsub", "patterns", "pubsub_patterns", DS_TYPE_GAUGE);
redis_handle_info (rn->name, rr->str, "current_connections", "slaves", "connected_slaves", DS_TYPE_GAUGE);
+ redis_handle_info (rn->name, rr->str, "cache_result", "hits", "keyspace_hits", DS_TYPE_DERIVE);
+ redis_handle_info (rn->name, rr->str, "cache_result", "misses", "keyspace_misses", DS_TYPE_DERIVE);
+ redis_handle_info (rn->name, rr->str, "total_bytes", "input", "total_net_input_bytes", DS_TYPE_DERIVE);
+ redis_handle_info (rn->name, rr->str, "total_bytes", "output", "total_net_output_bytes", DS_TYPE_DERIVE);
for (rq = rn->queries; rq != NULL; rq = rq->next)
redis_handle_query(rh, rn, rq);
+++ /dev/null
-option java_package = "com.aphyr.riemann";
-option java_outer_classname = "Proto";
-
-message State {
- optional int64 time = 1;
- optional string state = 2;
- optional string service = 3;
- optional string host = 4;
- optional string description = 5;
- optional bool once = 6;
- repeated string tags = 7;
- optional float ttl = 8;
-}
-
-message Event {
- optional int64 time = 1;
- optional string state = 2;
- optional string service = 3;
- optional string host = 4;
- optional string description = 5;
- repeated string tags = 7;
- optional float ttl = 8;
- repeated Attribute attributes = 9;
-
- optional sint64 metric_sint64 = 13;
- optional double metric_d = 14;
- optional float metric_f = 15;
-}
-
-message Query {
- optional string string = 1;
-}
-
-message Msg {
- optional bool ok = 2;
- optional string error = 3;
- repeated State states = 4;
- optional Query query = 5;
- repeated Event events = 6;
-}
-
-message Attribute {
- required string key = 1;
- optional string value = 2;
-}
int status;
int i;
- router_data = malloc (sizeof (*router_data));
+ router_data = calloc (1, sizeof (*router_data));
if (router_data == NULL)
return (-1);
- memset (router_data, 0, sizeof (*router_data));
router_data->connection = NULL;
router_data->node = NULL;
router_data->service = NULL;
user_data.free_func = (void *) cr_free_data;
if (status == 0)
status = plugin_register_complex_read (/* group = */ NULL, read_name,
- cr_read, /* interval = */ NULL, &user_data);
+ cr_read, /* interval = */ 0, &user_data);
if (status != 0)
cr_free_data (router_data);
{
int offset;
int status;
- int i;
+ size_t i;
time_t t;
assert (0 == strcmp (ds->type, vl->type));
status = ssnprintf (buffer + offset, buffer_len - offset,
":%llu", vl->values[i].counter);
}
- else if (ds->ds[i].type == DS_TYPE_GAUGE)
+ else if (ds->ds[i].type == DS_TYPE_GAUGE)
{
status = ssnprintf (buffer + offset, buffer_len - offset,
":%f", vl->values[i].gauge);
else /* if (ds->ds[i].type == DS_TYPE_ABSOLUTE) */ {
status = ssnprintf (buffer + offset, buffer_len - offset,
":%"PRIu64, vl->values[i].absolute);
-
+
}
if ((status < 1) || (status >= (buffer_len - offset)))
assert (template == NULL);
new_argc = 2 + argc;
- new_argv = (char **) malloc ((new_argc + 1) * sizeof (char *));
+ new_argv = malloc ((new_argc + 1) * sizeof (*new_argv));
if (new_argv == NULL)
{
ERROR ("rrdtool plugin: malloc failed.");
int offset;
int status;
time_t tt;
- int i;
+ size_t i;
memset (buffer, '\0', buffer_len);
}
/* Update `tv_next_update' */
- if (write_rate > 0.0)
+ if (write_rate > 0.0)
{
gettimeofday (&tv_now, /* timezone = */ NULL);
tv_next_update.tv_sec = tv_now.tv_sec;
{
rrd_queue_t *queue_entry;
- queue_entry = (rrd_queue_t *) malloc (sizeof (rrd_queue_t));
+ queue_entry = malloc (sizeof (*queue_entry));
if (queue_entry == NULL)
return (-1);
{
if (strcmp (this->filename, filename) == 0)
break;
-
+
prev = this;
this = this->next;
}
}
else /* ancient and no values -> waste of memory */
{
- char **tmp = (char **) realloc ((void *) keys,
+ char **tmp = realloc (keys,
(keys_num + 1) * sizeof (char *));
if (tmp == NULL)
{
}
} /* while (c_avl_iterator_next) */
c_avl_iterator_destroy (iter);
-
+
for (i = 0; i < keys_num; i++)
{
if (c_avl_remove (cache, keys[i], (void *) &key, (void *) &rc) != 0)
return (-1);
}
- values_new = (char **) realloc ((void *) rc->values,
+ values_new = realloc ((void *) rc->values,
(rc->values_num + 1) * sizeof (char *));
if (values_new == NULL)
{
while ((ptr = strtok_r (dummy, ", \t", &saveptr)) != NULL)
{
dummy = NULL;
-
+
tmp_alloc = realloc (rrdcreate_config.timespans,
sizeof (int) * (rrdcreate_config.timespans_num + 1));
if (tmp_alloc == NULL)
*
* Authors:
* Florian octo Forster <octo at collectd.org>
- *
+ *
* Lubos Stanek <lubek at users.sourceforge.net> Wed Oct 27, 2006
* - config ExtendedSensorNaming option
* - precise sensor feature selection (chip-bus-address/type-feature)
typedef struct sensors_labeltypes_s sensors_labeltypes_t;
/* finite list of known labels extracted from lm_sensors */
-static sensors_labeltypes_t known_features[] =
+static sensors_labeltypes_t known_features[] =
{
{ "fan1", SENSOR_TYPE_FANSPEED },
{ "fan2", SENSOR_TYPE_FANSPEED },
{
"Sensor",
"IgnoreSelected",
- "SensorConfigFile"
+ "SensorConfigFile",
+ "UseLabels"
};
static int config_keys_num = STATIC_ARRAY_SIZE (config_keys);
} featurelist_t;
static char *conffile = NULL;
+static _Bool use_labels = 0;
/* #endif (SENSORS_API_VERSION >= 0x400) && (SENSORS_API_VERSION < 0x500) */
#else /* if SENSORS_API_VERSION >= 0x500 */
"as bug."
#endif
-featurelist_t *first_feature = NULL;
+static featurelist_t *first_feature = NULL;
static ignorelist_t *sensor_list;
#if SENSORS_API_VERSION < 0x400
if (IS_TRUE (value))
ignorelist_set_invert (sensor_list, 0);
}
+#if (SENSORS_API_VERSION >= 0x400) && (SENSORS_API_VERSION < 0x500)
+ else if (strcasecmp (key, "UseLabels") == 0)
+ {
+ use_labels = IS_TRUE (value) ? 1 : 0;
+ }
+#endif
else
{
return (-1);
FILE *fh = NULL;
featurelist_t *last_feature = NULL;
-
+
const sensors_chip_name *chip;
int chip_num;
continue;
}
- fl = (featurelist_t *) malloc (sizeof (featurelist_t));
+ fl = calloc (1, sizeof (*fl));
if (fl == NULL)
{
- ERROR ("sensors plugin: malloc failed.");
+ ERROR ("sensors plugin: calloc failed.");
continue;
}
- memset (fl, '\0', sizeof (featurelist_t));
fl->chip = chip;
fl->data = feature;
&& (subfeature->type != SENSORS_SUBFEATURE_POWER_INPUT))
continue;
- fl = (featurelist_t *) malloc (sizeof (featurelist_t));
+ fl = calloc (1, sizeof (*fl));
if (fl == NULL)
{
- ERROR ("sensors plugin: malloc failed.");
+ ERROR ("sensors plugin: calloc failed.");
continue;
}
- memset (fl, '\0', sizeof (featurelist_t));
fl->chip = chip;
fl->feature = feature;
int status;
char plugin_instance[DATA_MAX_NAME_LEN];
char type_instance[DATA_MAX_NAME_LEN];
+ char *sensor_label;
const char *type;
status = sensors_get_value (fl->chip,
if (status < 0)
continue;
- sstrncpy (type_instance, fl->feature->name,
- sizeof (type_instance));
+ if (use_labels)
+ {
+ sensor_label = sensors_get_label (fl->chip, fl->feature);
+ sstrncpy (type_instance, sensor_label, sizeof (type_instance));
+ free (sensor_label);
+ }
+ else
+ {
+ sstrncpy (type_instance, fl->feature->name,
+ sizeof (type_instance));
+ }
if (fl->feature->type == SENSORS_FEATURE_IN)
type = "voltage";
FILE *fh;
char buffer[1024];
- derive_t rx = 0;
- derive_t tx = 0;
-
- char *fields[16];
- int i, numfields;
- int len;
-
/* there are a variety of names for the serial device */
if ((fh = fopen ("/proc/tty/driver/serial", "r")) == NULL &&
(fh = fopen ("/proc/tty/driver/ttyS", "r")) == NULL)
while (fgets (buffer, sizeof (buffer), fh) != NULL)
{
- int have_rx = 0, have_tx = 0;
+ derive_t rx = 0;
+ derive_t tx = 0;
+ _Bool have_rx = 0, have_tx = 0;
+ size_t len;
- numfields = strsplit (buffer, fields, 16);
+ char *fields[16];
+ int numfields;
+ int i;
+ numfields = strsplit (buffer, fields, STATIC_ARRAY_SIZE (fields));
if (numfields < 6)
continue;
* 0: uart:16550A port:000003F8 irq:4 tx:0 rx:0
* 1: uart:16550A port:000002F8 irq:3 tx:0 rx:0
*/
- len = strlen (fields[0]) - 1;
- if (len < 1)
+ len = strlen (fields[0]);
+ if (len < 2)
continue;
- if (fields[0][len] != ':')
+ if (fields[0][len - 1] != ':')
continue;
- fields[0][len] = '\0';
+ fields[0][len - 1] = 0;
for (i = 1; i < numfields; i++)
{
if (strncmp (fields[i], "tx:", 3) == 0)
{
- tx = atoll (fields[i] + 3);
- have_tx++;
+ if (strtoderive (fields[i] + 3, &tx) == 0)
+ have_tx = 1;
}
else if (strncmp (fields[i], "rx:", 3) == 0)
{
- rx = atoll (fields[i] + 3);
- have_rx++;
+ if (strtoderive (fields[i] + 3, &rx) == 0)
+ have_rx = 1;
}
}
- if ((have_rx == 0) || (have_tx == 0))
- continue;
-
- serial_submit (fields[0], rx, tx);
+ if (have_rx && have_tx)
+ serial_submit (fields[0], rx, tx);
}
fclose (fh);
struct config_device *cfdev;
int i;
- if (!(cfdev = malloc(sizeof(struct config_device)))) {
- ERROR("sigrok plugin: malloc() failed.");
+ if (!(cfdev = calloc(1, sizeof(*cfdev)))) {
+ ERROR("sigrok plugin: calloc failed.");
return -1;
}
- memset(cfdev, 0, sizeof(*cfdev));
if (cf_util_get_string(ci, &cfdev->name)) {
free(cfdev);
WARNING("sigrok plugin: Invalid device name.");
return 0;
}
-static char *sigrok_value_type(const struct sr_datafeed_analog *analog)
+static const char *sigrok_value_type(const struct sr_datafeed_analog *analog)
{
- char *s;
+ const char *s;
if (analog->mq == SR_MQ_VOLTAGE)
s = "voltage";
drvopts = NULL;
if (cfdev->conn) {
- if (!(src = malloc(sizeof(struct sr_config))))
+ if (!(src = malloc(sizeof(*src))))
return -1;
src->key = SR_CONF_CONN;
src->data = g_variant_new_string(cfdev->conn);
drvopts = g_slist_append(drvopts, src);
}
if (cfdev->serialcomm) {
- if (!(src = malloc(sizeof(struct sr_config))))
+ if (!(src = malloc(sizeof(*src))))
return -1;
src->key = SR_CONF_SERIALCOMM;
src->data = g_variant_new_string(cfdev->serialcomm);
return (0);
} /* int smart_config */
-static void smart_submit (const char *dev, char *type, char *type_inst, double value)
+static void smart_submit (const char *dev, const char *type,
+ const char *type_inst, double value)
{
value_t values[1];
value_list_t vl = VALUE_LIST_INIT;
instance_t instance;
char *instance_prefix;
oid_t *values;
- int values_len;
+ size_t values_len;
double scale;
double shift;
struct data_definition_s *next;
sfree (dd->values);
dd->values_len = 0;
- dd->values = (oid_t *) malloc (sizeof (oid_t) * ci->values_num);
+ dd->values = malloc (sizeof (*dd->values) * ci->values_num);
if (dd->values == NULL)
return (-1);
- dd->values_len = ci->values_num;
+ dd->values_len = (size_t) ci->values_num;
for (i = 0; i < ci->values_num; i++)
{
int status = 0;
int i;
- dd = (data_definition_t *) malloc (sizeof (data_definition_t));
+ dd = calloc (1, sizeof (*dd));
if (dd == NULL)
return (-1);
- memset (dd, '\0', sizeof (data_definition_t));
status = cf_util_get_string(ci, &dd->name);
if (status != 0)
return (-1);
}
- DEBUG ("snmp plugin: dd = { name = %s, type = %s, is_table = %s, values_len = %i }",
+ DEBUG ("snmp plugin: dd = { name = %s, type = %s, is_table = %s, values_len = %zu }",
dd->name, dd->type, (dd->is_table != 0) ? "true" : "false", dd->values_len);
if (data_head == NULL)
}
data_list_len = host->data_list_len + ci->values_num;
- data_list = (data_definition_t **) realloc (host->data_list,
+ data_list = realloc (host->data_list,
sizeof (data_definition_t *) * data_list_len);
if (data_list == NULL)
return (-1);
/* Registration stuff. */
char cb_name[DATA_MAX_NAME_LEN];
user_data_t cb_data;
- struct timespec cb_interval;
- hd = (host_definition_t *) malloc (sizeof (host_definition_t));
+ hd = calloc (1, sizeof (*hd));
if (hd == NULL)
return (-1);
- memset (hd, '\0', sizeof (host_definition_t));
hd->version = 2;
C_COMPLAIN_INIT (&hd->complaint);
cb_data.data = hd;
cb_data.free_func = csnmp_host_definition_destroy;
- CDTIME_T_TO_TIMESPEC (hd->interval, &cb_interval);
-
status = plugin_register_complex_read (/* group = */ NULL, cb_name,
- csnmp_read_host, /* interval = */ &cb_interval,
- /* user_data = */ &cb_data);
+ csnmp_read_host, hd->interval, /* user_data = */ &cb_data);
if (status != 0)
{
ERROR ("snmp plugin: Registering complex read function failed.");
return (ret);
} /* value_t csnmp_value_list_to_value */
+/* csnmp_strvbcopy_hexstring converts the bit string contained in "vb" to a hex
+ * representation and writes it to dst. Returns zero on success and ENOMEM if
+ * dst is not large enough to hold the string. dst is guaranteed to be
+ * nul-terminated. */
static int csnmp_strvbcopy_hexstring (char *dst, /* {{{ */
const struct variable_list *vb, size_t dst_size)
{
size_t buffer_free;
size_t i;
+ dst[0] = 0;
+
buffer_ptr = dst;
buffer_free = dst_size;
status = snprintf (buffer_ptr, buffer_free,
(i == 0) ? "%02x" : ":%02x", (unsigned int) vb->val.bitstring[i]);
+ assert (status >= 0);
- if (status >= buffer_free)
+ if (((size_t) status) >= buffer_free) /* truncated */
{
- buffer_ptr += (buffer_free - 1);
- *buffer_ptr = 0;
- return (dst_size + (buffer_free - status));
+ dst[dst_size - 1] = 0;
+ return ENOMEM;
}
else /* if (status < buffer_free) */
{
- buffer_ptr += status;
- buffer_free -= status;
+ buffer_ptr += (size_t) status;
+ buffer_free -= (size_t) status;
}
}
- return ((int) (dst_size - buffer_free));
+ return 0;
} /* }}} int csnmp_strvbcopy_hexstring */
+/* csnmp_strvbcopy copies the octet string or bit string contained in vb to
+ * dst. If non-printable characters are detected, it will switch to a hex
+ * representation of the string. Returns zero on success, EINVAL if vb does not
+ * contain a string and ENOMEM if dst is not large enough to contain the
+ * string. */
static int csnmp_strvbcopy (char *dst, /* {{{ */
const struct variable_list *vb, size_t dst_size)
{
src = (char *) vb->val.string;
else if (vb->type == ASN_BIT_STR)
src = (char *) vb->val.bitstring;
+ else if (vb->type == ASN_IPADDRESS)
+ {
+ return ssnprintf (dst, dst_size, "%"PRIu8".%"PRIu8".%"PRIu8".%"PRIu8"",
+ (uint8_t) vb->val.string[0],
+ (uint8_t) vb->val.string[1],
+ (uint8_t) vb->val.string[2],
+ (uint8_t) vb->val.string[3]);
+ }
else
{
dst[0] = 0;
dst[i] = src[i];
}
dst[num_chars] = 0;
+ dst[dst_size - 1] = 0;
+
+ if (dst_size <= vb->val_len)
+ return ENOMEM;
- return ((int) vb->val_len);
+ return 0;
} /* }}} int csnmp_strvbcopy */
static int csnmp_instance_list_add (csnmp_list_instances_t **head,
csnmp_oid_init (&vb_name, vb->name, vb->name_length);
- il = malloc (sizeof (*il));
+ il = calloc (1, sizeof (*il));
if (il == NULL)
{
- ERROR ("snmp plugin: malloc failed.");
+ ERROR ("snmp plugin: calloc failed.");
return (-1);
}
- memset (il, 0, sizeof (*il));
il->next = NULL;
status = csnmp_oid_suffix (&il->suffix, &vb_name, &dd->instance.oid);
}
/* Get instance name */
- if ((vb->type == ASN_OCTET_STR) || (vb->type == ASN_BIT_STR))
+ if ((vb->type == ASN_OCTET_STR) || (vb->type == ASN_BIT_STR) || (vb->type == ASN_IPADDRESS))
{
char *ptr;
csnmp_list_instances_t *instance_list_ptr;
csnmp_table_values_t **value_table_ptr;
- int i;
+ size_t i;
_Bool have_more;
oid_t current_suffix;
instance_list_ptr = instance_list;
- value_table_ptr = calloc ((size_t) data->values_len, sizeof (*value_table_ptr));
+ value_table_ptr = calloc (data->values_len, sizeof (*value_table_ptr));
if (value_table_ptr == NULL)
return (-1);
for (i = 0; i < data->values_len; i++)
const data_set_t *ds;
- uint32_t oid_list_len = (uint32_t) (data->values_len + 1);
+ size_t oid_list_len = data->values_len + 1;
/* Holds the last OID returned by the device. We use this in the GETNEXT
* request to proceed. */
oid_t oid_list[oid_list_len];
_Bool oid_list_todo[oid_list_len];
int status;
- int i;
- uint32_t j;
+ size_t i;
/* `value_list_head' and `value_list_tail' implement a linked list for each
* value. `instance_list_head' and `instance_list_tail' implement a linked list of
if (ds->ds_num != data->values_len)
{
- ERROR ("snmp plugin: DataSet `%s' requires %i values, but config talks about %i",
+ ERROR ("snmp plugin: DataSet `%s' requires %zu values, but config talks about %zu",
data->type, ds->ds_num, data->values_len);
return (-1);
}
else /* no InstanceFrom option specified. */
oid_list_len--;
- for (j = 0; j < oid_list_len; j++)
- oid_list_todo[j] = 1;
+ for (i = 0; i < oid_list_len; i++)
+ oid_list_todo[i] = 1;
/* We're going to construct n linked lists, one for each "value".
* value_list_head will contain pointers to the heads of these linked lists,
}
oid_list_todo_num = 0;
- for (j = 0; j < oid_list_len; j++)
+ for (i = 0; i < oid_list_len; i++)
{
/* Do not rerequest already finished OIDs */
- if (!oid_list_todo[j])
+ if (!oid_list_todo[i])
continue;
oid_list_todo_num++;
- snmp_add_null_var (req, oid_list[j].oid, oid_list[j].oid_len);
+ snmp_add_null_var (req, oid_list[i].oid, oid_list[i].oid_len);
}
if (oid_list_todo_num == 0)
ret = csnmp_oid_suffix (&suffix, &vb_name, data->values + i);
if (ret != 0)
{
- DEBUG ("snmp plugin: host = %s; data = %s; i = %i; "
+ DEBUG ("snmp plugin: host = %s; data = %s; i = %zu; "
"Value probably left its subtree.",
host->name, data->name, i);
oid_list_todo[i] = 0;
if ((value_list_tail[i] != NULL)
&& (csnmp_oid_compare (&suffix, &value_list_tail[i]->suffix) <= 0))
{
- DEBUG ("snmp plugin: host = %s; data = %s; i = %i; "
+ DEBUG ("snmp plugin: host = %s; data = %s; i = %zu; "
"Suffix is not increasing.",
host->name, data->name, i);
oid_list_todo[i] = 0;
continue;
}
- vt = malloc (sizeof (*vt));
+ vt = calloc (1, sizeof (*vt));
if (vt == NULL)
{
- ERROR ("snmp plugin: malloc failed.");
+ ERROR ("snmp plugin: calloc failed.");
status = -1;
break;
}
- memset (vt, 0, sizeof (*vt));
vt->value = csnmp_value_list_to_value (vb, ds->ds[i].type,
data->scale, data->shift, host->name, data->name);
static int csnmp_read_value (host_definition_t *host, data_definition_t *data)
{
struct snmp_pdu *req;
- struct snmp_pdu *res;
+ struct snmp_pdu *res = NULL;
struct variable_list *vb;
const data_set_t *ds;
value_list_t vl = VALUE_LIST_INIT;
int status;
- int i;
+ size_t i;
DEBUG ("snmp plugin: csnmp_read_value (host = %s, data = %s)",
host->name, data->name);
if (ds->ds_num != data->values_len)
{
- ERROR ("snmp plugin: DataSet `%s' requires %i values, but config talks about %i",
+ ERROR ("snmp plugin: DataSet `%s' requires %zu values, but config talks about %zu",
data->type, ds->ds_num, data->values_len);
return (-1);
}
vl.values_len = ds->ds_num;
- vl.values = (value_t *) malloc (sizeof (value_t) * vl.values_len);
+ vl.values = malloc (sizeof (*vl.values) * vl.values_len);
if (vl.values == NULL)
return (-1);
for (i = 0; i < vl.values_len; i++)
for (i = 0; i < data->values_len; i++)
snmp_add_null_var (req, data->values[i].oid, data->values[i].oid_len);
- res = NULL;
status = snmp_sess_synch_response (host->sess_handle, req, &res);
if ((status != STAT_SUCCESS) || (res == NULL))
if (res != NULL)
snmp_free_pdu (res);
- res = NULL;
sfree (errstr);
sfree (vl.values);
data->scale, data->shift, host->name, data->name);
} /* for (res->variables) */
- if (res != NULL)
- snmp_free_pdu (res);
- res = NULL;
+ snmp_free_pdu (res);
DEBUG ("snmp plugin: -> plugin_dispatch_values (&vl);");
plugin_dispatch_values (&vl);
static int csnmp_read_host (user_data_t *ud)
{
host_definition_t *host;
- cdtime_t time_start;
- cdtime_t time_end;
int status;
int success;
int i;
if (host->interval == 0)
host->interval = plugin_get_interval ();
- time_start = cdtime ();
-
if (host->sess_handle == NULL)
csnmp_host_open_session (host);
success++;
}
- time_end = cdtime ();
- if ((time_end - time_start) > host->interval)
- {
- WARNING ("snmp plugin: Host `%s' should be queried every %.3f "
- "seconds, but reading all values takes %.3f seconds.",
- host->name,
- CDTIME_T_TO_DOUBLE (host->interval),
- CDTIME_T_TO_DOUBLE (time_end - time_start));
- }
-
if (success == 0)
return (-1);
#include <pthread.h>
#include <sys/types.h>
-#include <sys/socket.h>
#include <netdb.h>
#include <poll.h>
{
metric_type_t type;
double value;
+ derive_t counter;
latency_counter_t *latency;
c_avl_tree_t *set;
unsigned long updates_num;
static double *conf_timer_percentile = NULL;
static size_t conf_timer_percentile_num = 0;
+static _Bool conf_counter_sum = 0;
static _Bool conf_timer_lower = 0;
static _Bool conf_timer_upper = 0;
static _Bool conf_timer_sum = 0;
return (NULL);
}
- metric = malloc (sizeof (*metric));
+ metric = calloc (1, sizeof (*metric));
if (metric == NULL)
{
- ERROR ("statsd plugin: malloc failed.");
+ ERROR ("statsd plugin: calloc failed.");
sfree (key_copy);
return (NULL);
}
- memset (metric, 0, sizeof (*metric));
metric->type = type;
metric->latency = NULL;
if (status != 0)
return (status);
+ /* Changes to the counter are added to (statsd_metric_t*)->value. ->counter is
+ * only updated in statsd_metric_submit_unsafe(). */
return (statsd_metric_add (name, (double) (value.gauge / scale.gauge),
STATSD_COUNTER));
} /* }}} int statsd_handle_counter */
cf_util_get_boolean (child, &conf_delete_gauges);
else if (strcasecmp ("DeleteSets", child->key) == 0)
cf_util_get_boolean (child, &conf_delete_sets);
+ else if (strcasecmp ("CounterSum", child->key) == 0)
+ cf_util_get_boolean (child, &conf_counter_sum);
else if (strcasecmp ("TimerLower", child->key) == 0)
cf_util_get_boolean (child, &conf_timer_lower);
else if (strcasecmp ("TimerUpper", child->key) == 0)
} /* }}} int statsd_metric_clear_set_unsafe */
/* Must hold metrics_lock when calling this function. */
-static int statsd_metric_submit_unsafe (char const *name, /* {{{ */
- statsd_metric_t const *metric)
+static int statsd_metric_submit_unsafe (char const *name, statsd_metric_t *metric) /* {{{ */
{
value_t values[1];
value_list_t vl = VALUE_LIST_INIT;
values[0].gauge = (gauge_t) c_avl_size (metric->set);
}
else { /* STATSD_COUNTER */
- /*
- * Expand a single value to two metrics:
- *
- * - The absolute counter, as a gauge
- * - A derived rate for this counter
- */
- values[0].derive = (derive_t) metric->value;
- plugin_dispatch_values(&vl);
-
- sstrncpy(vl.type, "gauge", sizeof (vl.type));
- values[0].gauge = (gauge_t) metric->value;
+ gauge_t delta = nearbyint (metric->value);
+
+ /* Etsy's statsd writes counters as two metrics: a rate and the change since
+ * the last write. Since collectd does not reset its DERIVE metrics to zero,
+ * this makes little sense, but we're dispatching a "count" metric here
+ * anyway - if requested by the user - for compatibility reasons. */
+ if (conf_counter_sum)
+ {
+ sstrncpy (vl.type, "count", sizeof (vl.type));
+ values[0].gauge = delta;
+ plugin_dispatch_values (&vl);
+
+ /* restore vl.type */
+ sstrncpy (vl.type, "derive", sizeof (vl.type));
+ }
+
+ /* Rather than resetting value to zero, subtract delta so we correctly keep
+ * track of residuals. */
+ metric->value -= delta;
+ metric->counter += (derive_t) delta;
+
+ values[0].derive = metric->counter;
}
return (plugin_dispatch_values (&vl));
static _Bool report_by_device = 0;
/* #endif HAVE_SWAPCTL && HAVE_SWAPCTL_TWO_ARGS */
+#elif HAVE_SWAPCTL && HAVE_SWAPCTL_THREE_ARGS
+/* No global variables */
+/* #endif HAVE_SWAPCTL && HAVE_SWAPCTL_THREE_ARGS */
+
#elif defined(VM_SWAPUSAGE)
/* No global variables */
/* #endif defined(VM_SWAPUSAGE) */
char buf[1024] = "";
size_t offset = 0;
int log_severity;
- char *severity_string;
+ const char *severity_string;
int status;
if (n->severity > notif_severity)
*/
typedef struct {
- char *type;
- char *instance_prefix;
- int *instances;
- size_t instances_num;
- int *values;
- size_t values_num;
+ char *type;
+ char *instance_prefix;
+ size_t *instances;
+ size_t instances_num;
+ size_t *values;
+ size_t values_num;
const data_set_t *ds;
} tbl_result_t;
return 0;
} /* tbl_config_set_separator */
-static int tbl_config_append_array_i (char *name, int **var, size_t *len,
+static int tbl_config_append_array_i (char *name, size_t **var, size_t *len,
oconfig_item_t *ci)
{
- int *tmp;
-
+ size_t *tmp;
+ size_t num;
size_t i;
if (1 > ci->values_num) {
return 1;
}
- for (i = 0; i < ci->values_num; ++i) {
+ num = (size_t) ci->values_num;
+ for (i = 0; i < num; ++i) {
if (OCONFIG_TYPE_NUMBER != ci->values[i].type) {
log_err ("\"%s\" expects numerical arguments only.", name);
return 1;
}
}
- *len += ci->values_num;
- tmp = (int *)realloc (*var, *len * sizeof (**var));
+ tmp = realloc (*var, ((*len) + num) * sizeof (**var));
if (NULL == tmp) {
char errbuf[1024];
log_err ("realloc failed: %s.",
sstrerror (errno, errbuf, sizeof (errbuf)));
return -1;
}
-
*var = tmp;
- for (i = *len - ci->values_num; i < *len; ++i)
- (*var)[i] = (int)ci->values[i].value.number;
+ for (i = 0; i < num; ++i) {
+ (*var)[*len] = (size_t) ci->values[i].value.number;
+ (*len)++;
+ }
+
return 0;
} /* tbl_config_append_array_s */
tbl_result_t *res;
int status = 0;
- size_t i;
+ int i;
if (0 != ci->values_num) {
log_err ("<Result> does not expect any arguments.");
return 1;
}
- res = (tbl_result_t *)realloc (tbl->results,
+ res = realloc (tbl->results,
(tbl->results_num + 1) * sizeof (*tbl->results));
if (res == NULL) {
char errbuf[1024];
return 1;
}
- tbl = (tbl_t *)realloc (tables, (tables_num + 1) * sizeof (*tables));
+ tbl = realloc (tables, (tables_num + 1) * sizeof (*tables));
if (NULL == tbl) {
char errbuf[1024];
log_err ("realloc failed: %s.",
tbl = tables + tables_num - 1;
tbl_setup (tbl, ci->values[0].value.string);
- for (i = 0; i < ci->children_num; ++i) {
+ for (i = 0; i < ((size_t) ci->children_num); ++i) {
oconfig_item_t *c = ci->children + i;
if (0 == strcasecmp (c->key, "Separator"))
static int tbl_config (oconfig_item_t *ci)
{
- size_t i;
+ int i;
for (i = 0; i < ci->children_num; ++i) {
oconfig_item_t *c = ci->children + i;
return -1;
}
- if (res->values_num != (size_t)res->ds->ds_num) {
+ if (res->values_num != res->ds->ds_num) {
log_err ("Invalid type \"%s\". Expected %zu data source%s, "
- "got %i.", res->type, res->values_num,
+ "got %zu.", res->type, res->values_num,
(1 == res->values_num) ? "" : "s",
res->ds->ds_num);
return -1;
}
if (i <= tbl->max_colnum) {
- log_err ("Not enough columns in line "
+ log_warn ("Not enough columns in line "
"(expected at least %zu, got %zu).",
tbl->max_colnum + 1, i);
return -1;
while (NULL != fgets (buf, sizeof (buf), fh)) {
if ('\0' != buf[sizeof (buf) - 1]) {
buf[sizeof (buf) - 1] = '\0';
- log_err ("Table %s: Truncated line: %s", tbl->file, buf);
+ log_warn ("Table %s: Truncated line: %s", tbl->file, buf);
}
if (0 != tbl_parse_line (tbl, buf, sizeof (buf))) {
- log_err ("Table %s: Failed to parse line: %s", tbl->file, buf);
+ log_warn ("Table %s: Failed to parse line: %s", tbl->file, buf);
continue;
}
}
};
typedef struct ctail_config_match_s ctail_config_match_t;
-cu_tail_match_t **tail_match_list = NULL;
-size_t tail_match_list_num = 0;
-cdtime_t tail_match_list_intervals[255];
+static cu_tail_match_t **tail_match_list = NULL;
+static size_t tail_match_list_num = 0;
+static cdtime_t tail_match_list_intervals[255];
static int ctail_config_add_match_dstype (ctail_config_match_t *cm,
oconfig_item_t *ci)
{
cu_tail_match_t **temp;
- temp = (cu_tail_match_t **) realloc (tail_match_list,
+ temp = realloc (tail_match_list,
sizeof (cu_tail_match_t *) * (tail_match_list_num + 1));
if (temp == NULL)
{
static int ctail_init (void)
{
- struct timespec cb_interval;
char str[255];
user_data_t ud;
size_t i;
{
ud.data = (void *)tail_match_list[i];
ssnprintf(str, sizeof(str), "tail-%zu", i);
- CDTIME_T_TO_TIMESPEC (tail_match_list_intervals[i], &cb_interval);
- plugin_register_complex_read (NULL, str, ctail_read, &cb_interval, &ud);
+ plugin_register_complex_read (NULL, str, ctail_read, tail_match_list_intervals[i], &ud);
}
return (0);
#include <string.h>
struct metric_definition_s {
- char *name;
- char *type;
- char *instance;
- int data_source_type;
- int value_from;
+ char *name;
+ char *type;
+ char *instance;
+ int data_source_type;
+ ssize_t value_from;
struct metric_definition_s *next;
};
typedef struct metric_definition_s metric_definition_t;
struct instance_definition_s {
- char *instance;
- char *path;
- cu_tail_t *tail;
+ char *instance;
+ char *path;
+ cu_tail_t *tail;
metric_definition_t **metric_list;
- size_t metric_list_len;
- cdtime_t interval;
- int time_from;
+ size_t metric_list_len;
+ cdtime_t interval;
+ ssize_t time_from;
struct instance_definition_s *next;
};
typedef struct instance_definition_s instance_definition_t;
static cdtime_t parse_time (char const *tbuf)
{
double t;
- char *endptr = 0;
+ char *endptr = NULL;
errno = 0;
t = strtod (tbuf, &endptr);
char **fields, size_t fields_num)
{
value_t v;
- cdtime_t t;
+ cdtime_t t = 0;
int status;
if (md->data_source_type == -1)
return (EINVAL);
- if (md->value_from >= fields_num)
+ assert (md->value_from >= 0);
+ if (((size_t) md->value_from) >= fields_num)
return (EINVAL);
- if (id->time_from >= 0 && (id->time_from >= fields_num))
- return (EINVAL);
-
- t = 0;
- if (id->time_from >= 0)
- t = parse_time (fields[id->time_from]);
-
status = parse_value (fields[md->value_from], &v, md->data_source_type);
if (status != 0)
return (status);
+ if (id->time_from >= 0) {
+ if (((size_t) id->time_from) >= fields_num)
+ return (EINVAL);
+ t = parse_time (fields[id->time_from]);
+ }
+
return (tcsv_submit (id, md, v, t));
}
-static _Bool tcsv_check_index (int index, size_t fields_num, char const *name)
+static _Bool tcsv_check_index (ssize_t index, size_t fields_num, char const *name)
{
if (index < 0)
return 1;
else if (((size_t) index) < fields_num)
return 1;
- ERROR ("tail_csv plugin: Metric \"%s\": Request for index %i when "
+ ERROR ("tail_csv plugin: Metric \"%s\": Request for index %zd when "
"only %zu fields are available.",
name, index, fields_num);
return (0);
tcsv_metric_definition_destroy (next);
}
-static int tcsv_config_get_index(oconfig_item_t *ci, int *ret_index) {
- int index;
-
+static int tcsv_config_get_index(oconfig_item_t *ci, ssize_t *ret_index) {
if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_NUMBER)){
WARNING("tail_csv plugin: The \"%s\" config option needs exactly one "
"integer argument.", ci->key);
return (-1);
}
- index = (int) ci->values[0].value.number;
- if (index < 0) {
+ if (ci->values[0].value.number < 0) {
WARNING("tail_csv plugin: The \"%s\" config option must be positive "
"(or zero).", ci->key);
return (-1);
}
- *ret_index = index;
+ *ret_index = (ssize_t) ci->values[0].value.number;
return (0);
}
/* Parse metric */
static int tcsv_config_add_metric(oconfig_item_t *ci){
metric_definition_t *md;
- int status = 0;
+ int status;
int i;
- md = (metric_definition_t *)malloc(sizeof(*md));
+ md = calloc(1, sizeof(*md));
if (md == NULL)
return (-1);
- memset(md, 0, sizeof(*md));
md->name = NULL;
md->type = NULL;
md->instance = NULL;
/* Registration variables */
char cb_name[DATA_MAX_NAME_LEN];
user_data_t cb_data;
- struct timespec cb_interval;
- id = malloc(sizeof(*id));
+ id = calloc(1, sizeof(*id));
if (id == NULL)
return (-1);
- memset(id, 0, sizeof(*id));
id->instance = NULL;
id->path = NULL;
id->metric_list = NULL;
memset(&cb_data, 0, sizeof(cb_data));
cb_data.data = id;
cb_data.free_func = tcsv_instance_definition_destroy;
- CDTIME_T_TO_TIMESPEC(id->interval, &cb_interval);
- status = plugin_register_complex_read(NULL, cb_name, tcsv_read, &cb_interval, &cb_data);
+ status = plugin_register_complex_read(NULL, cb_name, tcsv_read, id->interval, &cb_data);
if (status != 0){
ERROR("tail_csv plugin: Registering complex read function failed.");
}
else if (ds->ds_num != 1)
{
- ERROR ("tail_csv plugin: The type \"%s\" has %i data sources. "
+ ERROR ("tail_csv plugin: The type \"%s\" has %zu data sources. "
"Only types with a single data soure are supported.",
ds->type, ds->ds_num);
continue;
int status;
int i;
- data = (tn_data_t *) malloc (sizeof (*data));
+ data = calloc (1, sizeof (*data));
if (data == NULL)
{
- ERROR ("tn_create: malloc failed.");
+ ERROR ("tn_create: calloc failed.");
return (-ENOMEM);
}
- memset (data, 0, sizeof (*data));
data->message = NULL;
data->severity = 0;
gauge_t *rates;
int rates_failed;
- int i;
+ size_t i;
if ((ds == NULL) || (vl == NULL) || (user_data == NULL))
return (-EINVAL);
return (NULL);
sz = strlen (orig) + 1;
- dest = (char *) malloc (sz);
+ dest = malloc (sz);
if (dest == NULL)
return (NULL);
return (-1);
}
- act = (tr_action_t *) malloc (sizeof (*act));
+ act = calloc (1, sizeof (*act));
if (act == NULL)
{
- ERROR ("tr_config_add_action: malloc failed.");
+ ERROR ("tr_config_add_action: calloc failed.");
return (-ENOMEM);
}
- memset (act, 0, sizeof (*act));
act->replacement = NULL;
act->may_be_empty = may_be_empty;
}
subst_status = subst (temp, sizeof (temp), buffer,
- matches[0].rm_so, matches[0].rm_eo, act->replacement);
+ (size_t) matches[0].rm_so, (size_t) matches[0].rm_eo, act->replacement);
if (subst_status == NULL)
{
ERROR ("Target `replace': subst (buffer = %s, start = %zu, end = %zu, "
int status;
int i;
- data = (tr_data_t *) malloc (sizeof (*data));
+ data = calloc (1, sizeof (*data));
if (data == NULL)
{
- ERROR ("tr_create: malloc failed.");
+ ERROR ("tr_create: calloc failed.");
return (-ENOMEM);
}
- memset (data, 0, sizeof (*data));
data->host = NULL;
data->plugin = NULL;
if (failure == 0)
{
- uint64_t difference;
+ uint64_t diff;
double rate;
- /* Calcualte the rate */
- if (prev_counter > curr_counter) /* => counter overflow */
- {
- if (prev_counter <= 4294967295UL) /* 32 bit overflow */
- difference = (4294967295UL - prev_counter) + curr_counter;
- else /* 64 bit overflow */
- difference = (18446744073709551615ULL - prev_counter) + curr_counter;
- }
- else /* no overflow */
- {
- difference = curr_counter - prev_counter;
- }
- rate = ((double) difference) / CDTIME_T_TO_DOUBLE (vl->interval);
+ diff = (uint64_t) counter_diff (prev_counter, curr_counter);
+ rate = ((double) diff) / CDTIME_T_TO_DOUBLE (vl->interval);
/* Modify the rate. */
if (!isnan (data->factor))
/* Calculate the internal counter. */
int_fraction += (rate * CDTIME_T_TO_DOUBLE (vl->interval));
- difference = (uint64_t) int_fraction;
- int_fraction -= ((double) difference);
- int_counter += difference;
+ diff = (uint64_t) int_fraction;
+ int_fraction -= ((double) diff);
+ int_counter += diff;
assert (int_fraction >= 0.0);
assert (int_fraction < 1.0);
/* Allocate space for the char pointers */
new_data_sources_num = data->data_sources_num + ((size_t) ci->values_num);
- temp = (char **) realloc (data->data_sources,
+ temp = realloc (data->data_sources,
new_data_sources_num * sizeof (char *));
if (temp == NULL)
{
int status;
int i;
- data = (ts_data_t *) malloc (sizeof (*data));
+ data = calloc (1, sizeof (*data));
if (data == NULL)
{
- ERROR ("ts_create: malloc failed.");
+ ERROR ("ts_create: calloc failed.");
return (-ENOMEM);
}
- memset (data, 0, sizeof (*data));
data->factor = NAN;
data->offset = NAN;
notification_meta_t __attribute__((unused)) **meta, void **user_data)
{
ts_data_t *data;
- int i;
+ size_t i;
if ((ds == NULL) || (vl == NULL) || (user_data == NULL))
return (-EINVAL);
char *plugin_instance;
/* char *type; */
char *type_instance;
+ meta_data_t *meta;
};
typedef struct ts_data_s ts_data_t;
+static int ts_util_get_key_and_string_wo_strdup (const oconfig_item_t *ci, char **ret_key, char **ret_string) /* {{{ */
+{
+ if ((ci->values_num != 2)
+ || (ci->values[0].type != OCONFIG_TYPE_STRING)
+ || (ci->values[1].type != OCONFIG_TYPE_STRING))
+ {
+ ERROR ("ts_util_get_key_and_string_wo_strdup: The %s option requires "
+ "exactly two string argument.", ci->key);
+ return (-1);
+ }
+
+ *ret_key = ci->values[0].value.string;
+ *ret_string = ci->values[1].value.string;
+
+ return (0);
+} /* }}} int ts_util_get_key_and_string_wo_strdup */
+
static int ts_config_add_string (char **dest, /* {{{ */
const oconfig_item_t *ci, int may_be_empty)
{
return (0);
} /* }}} int ts_config_add_string */
+static int ts_config_add_meta (meta_data_t **dest, /* {{{ */
+ const oconfig_item_t *ci, int may_be_empty)
+{
+ char *key = NULL;
+ char *string = NULL;
+ int status;
+
+ status = ts_util_get_key_and_string_wo_strdup (ci, &key, &string);
+ if (status != 0)
+ return (status);
+
+ if (strlen (key) == 0)
+ {
+ ERROR ("Target `set': The `%s' option does not accept empty string as first argument.",
+ ci->key);
+ return (-1);
+ }
+
+ if (!may_be_empty && (strlen (string) == 0))
+ {
+ ERROR ("Target `set': The `%s' option does not accept empty string as second argument.",
+ ci->key);
+ return (-1);
+ }
+
+ if ((*dest) == NULL)
+ {
+ // Create a new meta_data_t
+ if ((*dest = meta_data_create()) == NULL)
+ {
+ ERROR ("Target `set': failed to create a meta data for `%s'.", ci->key);
+ return (-1);
+ }
+ }
+
+ return (meta_data_add_string (*dest, key, string));
+} /* }}} int ts_config_add_meta */
+
static int ts_destroy (void **user_data) /* {{{ */
{
ts_data_t *data;
free (data->plugin_instance);
/* free (data->type); */
free (data->type_instance);
+ meta_data_destroy(data->meta);
free (data);
return (0);
int status;
int i;
- data = (ts_data_t *) malloc (sizeof (*data));
+ data = calloc (1, sizeof (*data));
if (data == NULL)
{
- ERROR ("ts_create: malloc failed.");
+ ERROR ("ts_create: calloc failed.");
return (-ENOMEM);
}
- memset (data, 0, sizeof (*data));
data->host = NULL;
data->plugin = NULL;
data->plugin_instance = NULL;
/* data->type = NULL; */
data->type_instance = NULL;
+ data->meta = NULL;
status = 0;
for (i = 0; i < ci->children_num; i++)
else if (strcasecmp ("TypeInstance", child->key) == 0)
status = ts_config_add_string (&data->type_instance, child,
/* may be empty = */ 1);
+ else if (strcasecmp ("MetaDataSet", child->key) == 0)
+ status = ts_config_add_meta (&data->meta, child,
+ /* may be empty = */ 1);
else
{
ERROR ("Target `set': The `%s' configuration option is not understood "
&& (data->plugin == NULL)
&& (data->plugin_instance == NULL)
/* && (data->type == NULL) */
- && (data->type_instance == NULL))
+ && (data->type_instance == NULL)
+ && (data->meta == NULL))
{
ERROR ("Target `set': You need to set at least one of `Host', "
- "`Plugin', `PluginInstance' or `TypeInstance'.");
+ "`Plugin', `PluginInstance', `TypeInstance', "
+ "`MetaDataSet' or `MetaDataEval'.");
status = -1;
}
return (-EINVAL);
}
+ if (data->meta != NULL)
+ {
+ meta_data_clone_merge(&(vl->meta), data->meta);
+ }
+
#define SET_FIELD(f) if (data->f != NULL) { sstrncpy (vl->f, data->f, sizeof (vl->f)); }
SET_FIELD (host);
SET_FIELD (plugin);
#if KERNEL_LINUX
# include <asm/types.h>
-/* sys/socket.h is necessary to compile when using netlink on older systems. */
-# include <sys/socket.h>
# include <linux/netlink.h>
#if HAVE_LINUX_INET_DIAG_H
# include <linux/inet_diag.h>
#endif
-# include <sys/socket.h>
# include <arpa/inet.h>
/* #endif KERNEL_LINUX */
#if HAVE_SYS_TYPES_H
# include <sys/types.h>
#endif
-#if HAVE_SYS_SOCKET_H
-# include <sys/socket.h>
-#endif
#if HAVE_NET_IF_H
# include <net/if.h>
#endif
/* This is for OpenBSD and NetBSD. */
#elif HAVE_LIBKVM_NLIST
# include <sys/queue.h>
-# include <sys/socket.h>
# include <net/route.h>
# include <netinet/in.h>
# include <netinet/in_systm.h>
static uint32_t sequence_number = 0;
#endif
-enum
+static enum
{
SRC_DUNNO,
SRC_NETLINK,
if ((ret == NULL) && (create != 0))
{
- ret = (port_entry_t *) malloc (sizeof (port_entry_t));
+ ret = calloc (1, sizeof (*ret));
if (ret == NULL)
return (NULL);
- memset (ret, '\0', sizeof (port_entry_t));
ret->port = port;
ret->next = port_list_head;
return (-1);
}
- buffer = (char *) malloc (buffer_len);
+ buffer = malloc (buffer_len);
if (buffer == NULL)
{
ERROR ("tcpconns plugin: malloc failed.");
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/types.h>
-#include <sys/socket.h>
#include <netdb.h>
/*
}
/* Allocate memory */
- entry = (vserver_list_t *) malloc (sizeof (vserver_list_t));
+ entry = calloc (1, sizeof (*entry));
if (entry == NULL)
{
- ERROR ("teamspeak2 plugin: malloc failed.");
+ ERROR ("teamspeak2 plugin: calloc failed.");
return (-1);
}
- memset (entry, 0, sizeof (vserver_list_t));
/* Save data */
entry->port = vserver_port;
if (type_instance != NULL)
sstrncpy (vl.type_instance, type_instance,
sizeof (vl.type_instance));
-
+
plugin_dispatch_values (&vl);
} /* void tss2_submit_gauge */
* Receive a single line from the given file object
*/
char *temp;
-
+
/*
* fgets is blocking but much easier then doing anything else
* TODO: Non-blocking Version would be safer
char buffer[4096];
char *value;
char *endptr = NULL;
-
+
status = tss2_receive_line (read_fh, buffer, sizeof (buffer));
if (status != 0)
{
return (-1);
}
buffer[sizeof (buffer) - 1] = 0;
-
+
if (strncmp ("average_packet_loss=", buffer,
strlen ("average_packet_loss=")) == 0)
{
}
value++;
}
-
+
value = &buffer[20];
-
+
packet_loss = strtod (value, &endptr);
if (value == endptr)
{
buffer);
}
}
-
+
*ret_value = packet_loss;
return (0);
} /* int tss2_vserver_gapl */
char *key;
char *value;
char *endptr = NULL;
-
+
/* Read one line of the server's answer */
status = tss2_receive_line (read_fh, buffer, sizeof (buffer));
if (status != 0)
{
/* Server variable found */
int status;
-
+
status = tss2_add_vserver (atoi (value));
if (status != 0)
return (1);
continue;
}
}
-
+
if (success == 0)
return (-1);
return (0);
/* Get rid of the configuration */
sfree (config_host);
sfree (config_port);
-
+
return (0);
} /* int tss2_shutdown */
WARNING ("ted plugin: Received EOF from file descriptor.");
return (-1);
}
- else if (receive_buffer_length > sizeof (receive_buffer))
+ else if (((size_t) receive_buffer_length) > sizeof (receive_buffer))
{
ERROR ("ted plugin: read(2) returned invalid value %zi.",
receive_buffer_length);
return (0);
} /* int ted_open_device */
-static void ted_submit (char *type, double value)
+static void ted_submit (const char *type, double value)
{
value_t values[1];
value_list_t vl = VALUE_LIST_INIT;
/**
* collectd - src/tests/macros.h
- * Copyright (C) 2013 Florian octo Forster
+ * Copyright (C) 2013-2015 Florian octo Forster
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* Florian octo Forster <octo at collectd.org>
*/
+#ifndef TESTING_H
+#define TESTING_H 1
+
+#include <inttypes.h>
+
static int fail_count__ = 0;
static int check_count__ = 0;
-#define DEF_TEST(func) static int test_##func ()
+#ifndef DBL_PRECISION
+# define DBL_PRECISION 1e-12
+#endif
+
+#define DEF_TEST(func) static int test_##func (void)
#define RUN_TEST(func) do { \
int status; \
#define OK1(cond, text) do { \
_Bool result = (cond); \
printf ("%s %i - %s\n", result ? "ok" : "not ok", ++check_count__, text); \
+ if (!result) { return -1; } \
} while (0)
#define OK(cond) OK1(cond, #cond)
-#define STREQ(expect, actual) do { \
+#define EXPECT_EQ_STR(expect, actual) do { \
if (strcmp (expect, actual) != 0) { \
- printf ("not ok %i - %s incorrect: expected \"%s\", got \"%s\"\n", \
- ++check_count__, #actual, expect, actual); \
+ printf ("not ok %i - %s = \"%s\", want \"%s\"\n", \
+ ++check_count__, #actual, actual, expect); \
return (-1); \
} \
- printf ("ok %i - %s evaluates to \"%s\"\n", ++check_count__, #actual, expect); \
+ printf ("ok %i - %s = \"%s\"\n", ++check_count__, #actual, actual); \
+} while (0)
+
+#define EXPECT_EQ_INT(expect, actual) do { \
+ int want__ = (int) expect; \
+ int got__ = (int) actual; \
+ if (got__ != want__) { \
+ printf ("not ok %i - %s = %d, want %d\n", \
+ ++check_count__, #actual, got__, want__); \
+ return (-1); \
+ } \
+ printf ("ok %i - %s = %d\n", ++check_count__, #actual, got__); \
+} while (0)
+
+#define EXPECT_EQ_UINT64(expect, actual) do { \
+ uint64_t want__ = (uint64_t) expect; \
+ uint64_t got__ = (uint64_t) actual; \
+ if (got__ != want__) { \
+ printf ("not ok %i - %s = %"PRIu64", want %"PRIu64"\n", \
+ ++check_count__, #actual, got__, want__); \
+ return (-1); \
+ } \
+ printf ("ok %i - %s = %"PRIu64"\n", ++check_count__, #actual, got__); \
+} while (0)
+
+#define EXPECT_EQ_DOUBLE(expect, actual) do { \
+ double want__ = (double) expect; \
+ double got__ = (double) actual; \
+ if (isnan (want__) && !isnan (got__)) { \
+ printf ("not ok %i - %s = %.15g, want %.15g\n", \
+ ++check_count__, #actual, got__, want__); \
+ return (-1); \
+ } else if (!isnan (want__) && (((want__-got__) < -DBL_PRECISION) || ((want__-got__) > DBL_PRECISION))) { \
+ printf ("not ok %i - %s = %.15g, want %.15g\n", \
+ ++check_count__, #actual, got__, want__); \
+ return (-1); \
+ } \
+ printf ("ok %i - %s = %.15g\n", ++check_count__, #actual, got__); \
} while (0)
#define CHECK_NOT_NULL(expr) do { \
status_ = (long) (expr); \
OK1(status_ == 0L, #expr); \
} while (0)
+
+#endif /* TESTING_H */
"ForceUseProcfs"
};
-const char *const dirname_sysfs = "/sys/class/thermal";
-const char *const dirname_procfs = "/proc/acpi/thermal_zone";
+static const char *const dirname_sysfs = "/sys/class/thermal";
+static const char *const dirname_procfs = "/proc/acpi/thermal_zone";
static _Bool force_procfs = 0;
static ignorelist_t *device_list;
return (-1);
}
- th_copy = (threshold_t *) malloc (sizeof (threshold_t));
+ th_copy = malloc (sizeof (*th_copy));
if (th_copy == NULL)
{
sfree (name_copy);
return (-1);
}
memcpy (th_copy, th, sizeof (threshold_t));
- th_ptr = NULL;
DEBUG ("ut_threshold_add: Adding entry `%s'", name);
{
gauge_t value;
gauge_t sum;
- int i;
+ size_t i;
sum = 0.0;
for (i = 0; i < vl->values_len; i++)
{ /* {{{ */
int ret = -1;
int ds_index = -1;
- int i;
+ size_t i;
gauge_t values_copy[ds->ds_num];
memcpy (values_copy, values, sizeof (values_copy));
static void tt_open_db (void)
{
- char* host = NULL;
- int port = DEFAULT_PORT;
+ const char *host;
+ int port = DEFAULT_PORT;
if (rdb != NULL)
return;
CPU_FREE(cpu_present_set);
cpu_present_set = NULL;
- cpu_present_set = 0;
+ cpu_present_setsize = 0;
CPU_FREE(cpu_affinity_set);
cpu_affinity_set = NULL;
-absolute value:ABSOLUTE:0:U
-apache_bytes value:DERIVE:0:U
-apache_connections value:GAUGE:0:65535
-apache_idle_workers value:GAUGE:0:65535
-apache_requests value:DERIVE:0:U
-apache_scoreboard value:GAUGE:0:65535
-ath_nodes value:GAUGE:0:65535
-ath_stat value:DERIVE:0:U
-backends value:GAUGE:0:65535
-bitrate value:GAUGE:0:4294967295
-blocked_clients value:GAUGE:0:U
-bytes value:GAUGE:0:U
-cache_eviction value:DERIVE:0:U
-cache_operation value:DERIVE:0:U
-cache_ratio value:GAUGE:0:100
-cache_result value:DERIVE:0:U
-cache_size value:GAUGE:0:U
-capacity value:GAUGE:0:U
-ceph_bytes value:GAUGE:U:U
-ceph_latency value:GAUGE:U:U
-ceph_rate value:DERIVE:0:U
-changes_since_last_save value:GAUGE:0:U
-charge value:GAUGE:0:U
-compression_ratio value:GAUGE:0:2
-compression uncompressed:DERIVE:0:U, compressed:DERIVE:0:U
-connections value:DERIVE:0:U
-conntrack value:GAUGE:0:4294967295
-contextswitch value:DERIVE:0:U
-count value:GAUGE:0:U
-counter value:COUNTER:U:U
-cpufreq value:GAUGE:0:U
-cpu value:DERIVE:0:U
-current_connections value:GAUGE:0:U
-current_sessions value:GAUGE:0:U
-current value:GAUGE:U:U
-delay value:GAUGE:-1000000:1000000
-derive value:DERIVE:0:U
-df_complex value:GAUGE:0:U
-df_inodes value:GAUGE:0:U
-df used:GAUGE:0:1125899906842623, free:GAUGE:0:1125899906842623
-disk_latency read:GAUGE:0:U, write:GAUGE:0:U
-disk_merged read:DERIVE:0:U, write:DERIVE:0:U
-disk_octets read:DERIVE:0:U, write:DERIVE:0:U
-disk_ops_complex value:DERIVE:0:U
-disk_ops read:DERIVE:0:U, write:DERIVE:0:U
-disk_time read:DERIVE:0:U, write:DERIVE:0:U
-disk_io_time io_time:DERIVE:0:U, weighted_io_time:DERIVE:0:U
-dns_answer value:DERIVE:0:U
-dns_notify value:DERIVE:0:U
-dns_octets queries:DERIVE:0:U, responses:DERIVE:0:U
-dns_opcode value:DERIVE:0:U
-dns_qtype_cached value:GAUGE:0:4294967295
-dns_qtype value:DERIVE:0:U
-dns_query value:DERIVE:0:U
-dns_question value:DERIVE:0:U
-dns_rcode value:DERIVE:0:U
-dns_reject value:DERIVE:0:U
-dns_request value:DERIVE:0:U
-dns_resolver value:DERIVE:0:U
-dns_response value:DERIVE:0:U
-dns_transfer value:DERIVE:0:U
-dns_update value:DERIVE:0:U
-dns_zops value:DERIVE:0:U
-drbd_resource value:DERIVE:0:U
-duration seconds:GAUGE:0:U
-email_check value:GAUGE:0:U
-email_count value:GAUGE:0:U
-email_size value:GAUGE:0:U
-entropy value:GAUGE:0:4294967295
-expired_keys value:DERIVE:0:U
-fanspeed value:GAUGE:0:U
-file_handles value:GAUGE:0:U
-file_size value:GAUGE:0:U
-files value:GAUGE:0:U
-flow value:GAUGE:0:U
-fork_rate value:DERIVE:0:U
-frequency_offset value:GAUGE:-1000000:1000000
-frequency value:GAUGE:0:U
-fscache_stat value:DERIVE:0:U
-gauge value:GAUGE:U:U
-hash_collisions value:DERIVE:0:U
-http_request_methods value:DERIVE:0:U
-http_requests value:DERIVE:0:U
-http_response_codes value:DERIVE:0:U
-humidity value:GAUGE:0:100
-if_collisions value:DERIVE:0:U
-if_dropped rx:DERIVE:0:U, tx:DERIVE:0:U
-if_errors rx:DERIVE:0:U, tx:DERIVE:0:U
-if_multicast value:DERIVE:0:U
-if_octets rx:DERIVE:0:U, tx:DERIVE:0:U
-if_packets rx:DERIVE:0:U, tx:DERIVE:0:U
-if_rx_errors value:DERIVE:0:U
-if_rx_octets value:DERIVE:0:U
-if_tx_errors value:DERIVE:0:U
-if_tx_octets value:DERIVE:0:U
-invocations value:DERIVE:0:U
-io_octets rx:DERIVE:0:U, tx:DERIVE:0:U
-io_packets rx:DERIVE:0:U, tx:DERIVE:0:U
-ipt_bytes value:DERIVE:0:U
-ipt_packets value:DERIVE:0:U
-irq value:DERIVE:0:U
-latency value:GAUGE:0:U
-links value:GAUGE:0:U
-load shortterm:GAUGE:0:5000, midterm:GAUGE:0:5000, longterm:GAUGE:0:5000
-md_disks value:GAUGE:0:U
-memcached_command value:DERIVE:0:U
-memcached_connections value:GAUGE:0:U
-memcached_items value:GAUGE:0:U
-memcached_octets rx:DERIVE:0:U, tx:DERIVE:0:U
-memcached_ops value:DERIVE:0:U
-memory value:GAUGE:0:281474976710656
-memory_lua value:GAUGE:0:281474976710656
-multimeter value:GAUGE:U:U
-mutex_operations value:DERIVE:0:U
-mysql_commands value:DERIVE:0:U
-mysql_handler value:DERIVE:0:U
-mysql_locks value:DERIVE:0:U
-mysql_log_position value:DERIVE:0:U
-mysql_octets rx:DERIVE:0:U, tx:DERIVE:0:U
-mysql_bpool_pages value:GAUGE:0:U
-mysql_bpool_bytes value:GAUGE:0:U
-mysql_bpool_counters value:DERIVE:0:U
-mysql_innodb_data value:DERIVE:0:U
-mysql_innodb_dblwr value:DERIVE:0:U
-mysql_innodb_log value:DERIVE:0:U
-mysql_innodb_pages value:DERIVE:0:U
-mysql_innodb_row_lock value:DERIVE:0:U
-mysql_innodb_rows value:DERIVE:0:U
-mysql_select value:DERIVE:0:U
-mysql_sort value:DERIVE:0:U
-nfs_procedure value:DERIVE:0:U
-nginx_connections value:GAUGE:0:U
-nginx_requests value:DERIVE:0:U
-node_octets rx:DERIVE:0:U, tx:DERIVE:0:U
-node_rssi value:GAUGE:0:255
-node_stat value:DERIVE:0:U
-node_tx_rate value:GAUGE:0:127
-objects value:GAUGE:0:U
-operations value:DERIVE:0:U
-packets value:DERIVE:0:U
-pending_operations value:GAUGE:0:U
-percent value:GAUGE:0:100.1
-percent_bytes value:GAUGE:0:100.1
-percent_inodes value:GAUGE:0:100.1
-pf_counters value:DERIVE:0:U
-pf_limits value:DERIVE:0:U
-pf_source value:DERIVE:0:U
-pf_states value:GAUGE:0:U
-pf_state value:DERIVE:0:U
-pg_blks value:DERIVE:0:U
-pg_db_size value:GAUGE:0:U
-pg_n_tup_c value:DERIVE:0:U
-pg_n_tup_g value:GAUGE:0:U
-pg_numbackends value:GAUGE:0:U
-pg_scan value:DERIVE:0:U
-pg_xact value:DERIVE:0:U
-ping_droprate value:GAUGE:0:100
-ping_stddev value:GAUGE:0:65535
-ping value:GAUGE:0:65535
-players value:GAUGE:0:1000000
-power value:GAUGE:0:U
-pressure value:GAUGE:0:U
-protocol_counter value:DERIVE:0:U
-ps_code value:GAUGE:0:9223372036854775807
-ps_count processes:GAUGE:0:1000000, threads:GAUGE:0:1000000
-ps_cputime user:DERIVE:0:U, syst:DERIVE:0:U
-ps_data value:GAUGE:0:9223372036854775807
-ps_disk_octets read:DERIVE:0:U, write:DERIVE:0:U
-ps_disk_ops read:DERIVE:0:U, write:DERIVE:0:U
-ps_pagefaults minflt:DERIVE:0:U, majflt:DERIVE:0:U
-ps_rss value:GAUGE:0:9223372036854775807
-ps_stacksize value:GAUGE:0:9223372036854775807
-ps_state value:GAUGE:0:65535
-ps_vm value:GAUGE:0:9223372036854775807
-pubsub value:GAUGE:0:U
-queue_length value:GAUGE:0:U
-records value:GAUGE:0:U
-requests value:GAUGE:0:U
-response_time value:GAUGE:0:U
-response_code value:GAUGE:0:U
-route_etx value:GAUGE:0:U
-route_metric value:GAUGE:0:U
-routes value:GAUGE:0:U
-segments value:GAUGE:0:65535
-serial_octets rx:DERIVE:0:U, tx:DERIVE:0:U
-signal_noise value:GAUGE:U:0
-signal_power value:GAUGE:U:0
-signal_quality value:GAUGE:0:U
-smart_poweron value:GAUGE:0:U
-smart_powercycles value:GAUGE:0:U
-smart_badsectors value:GAUGE:0:U
-smart_temperature value:GAUGE:-300:300
+absolute value:ABSOLUTE:0:U
+apache_bytes value:DERIVE:0:U
+apache_connections value:GAUGE:0:65535
+apache_idle_workers value:GAUGE:0:65535
+apache_requests value:DERIVE:0:U
+apache_scoreboard value:GAUGE:0:65535
+ath_nodes value:GAUGE:0:65535
+ath_stat value:DERIVE:0:U
+backends value:GAUGE:0:65535
+bitrate value:GAUGE:0:4294967295
+blocked_clients value:GAUGE:0:U
+bytes value:GAUGE:0:U
+cache_eviction value:DERIVE:0:U
+cache_operation value:DERIVE:0:U
+cache_ratio value:GAUGE:0:100
+cache_result value:DERIVE:0:U
+cache_size value:GAUGE:0:1125899906842623
+capacity value:GAUGE:0:U
+ceph_bytes value:GAUGE:U:U
+ceph_latency value:GAUGE:U:U
+ceph_rate value:DERIVE:0:U
+changes_since_last_save value:GAUGE:0:U
+charge value:GAUGE:0:U
+compression uncompressed:DERIVE:0:U, compressed:DERIVE:0:U
+compression_ratio value:GAUGE:0:2
+connections value:DERIVE:0:U
+conntrack value:GAUGE:0:4294967295
+contextswitch value:DERIVE:0:U
+count value:GAUGE:0:U
+counter value:COUNTER:U:U
+cpu value:DERIVE:0:U
+cpufreq value:GAUGE:0:U
+current value:GAUGE:U:U
+current_connections value:GAUGE:0:U
+current_sessions value:GAUGE:0:U
+delay value:GAUGE:-1000000:1000000
+derive value:DERIVE:0:U
+df used:GAUGE:0:1125899906842623, free:GAUGE:0:1125899906842623
+df_complex value:GAUGE:0:U
+df_inodes value:GAUGE:0:U
+disk_io_time io_time:DERIVE:0:U, weighted_io_time:DERIVE:0:U
+disk_latency read:GAUGE:0:U, write:GAUGE:0:U
+disk_merged read:DERIVE:0:U, write:DERIVE:0:U
+disk_octets read:DERIVE:0:U, write:DERIVE:0:U
+disk_ops read:DERIVE:0:U, write:DERIVE:0:U
+disk_ops_complex value:DERIVE:0:U
+disk_time read:DERIVE:0:U, write:DERIVE:0:U
+dns_answer value:DERIVE:0:U
+dns_notify value:DERIVE:0:U
+dns_octets queries:DERIVE:0:U, responses:DERIVE:0:U
+dns_opcode value:DERIVE:0:U
+dns_qtype value:DERIVE:0:U
+dns_qtype_cached value:GAUGE:0:4294967295
+dns_query value:DERIVE:0:U
+dns_question value:DERIVE:0:U
+dns_rcode value:DERIVE:0:U
+dns_reject value:DERIVE:0:U
+dns_request value:DERIVE:0:U
+dns_resolver value:DERIVE:0:U
+dns_response value:DERIVE:0:U
+dns_transfer value:DERIVE:0:U
+dns_update value:DERIVE:0:U
+dns_zops value:DERIVE:0:U
+drbd_resource value:DERIVE:0:U
+duration seconds:GAUGE:0:U
+email_check value:GAUGE:0:U
+email_count value:GAUGE:0:U
+email_size value:GAUGE:0:U
+entropy value:GAUGE:0:4294967295
+evicted_keys value:DERIVE:0:U
+expired_keys value:DERIVE:0:U
+fanspeed value:GAUGE:0:U
+file_handles value:GAUGE:0:U
+file_size value:GAUGE:0:U
+files value:GAUGE:0:U
+flow value:GAUGE:0:U
+fork_rate value:DERIVE:0:U
+frequency value:GAUGE:0:U
+frequency_offset value:GAUGE:-1000000:1000000
+fscache_stat value:DERIVE:0:U
+gauge value:GAUGE:U:U
+hash_collisions value:DERIVE:0:U
+http_request_methods value:DERIVE:0:U
+http_requests value:DERIVE:0:U
+http_response_codes value:DERIVE:0:U
+humidity value:GAUGE:0:100
+if_collisions value:DERIVE:0:U
+if_dropped rx:DERIVE:0:U, tx:DERIVE:0:U
+if_errors rx:DERIVE:0:U, tx:DERIVE:0:U
+if_multicast value:DERIVE:0:U
+if_octets rx:DERIVE:0:U, tx:DERIVE:0:U
+if_packets rx:DERIVE:0:U, tx:DERIVE:0:U
+if_rx_errors value:DERIVE:0:U
+if_rx_octets value:DERIVE:0:U
+if_tx_errors value:DERIVE:0:U
+if_tx_octets value:DERIVE:0:U
+invocations value:DERIVE:0:U
+io_octets rx:DERIVE:0:U, tx:DERIVE:0:U
+io_packets rx:DERIVE:0:U, tx:DERIVE:0:U
+ipt_bytes value:DERIVE:0:U
+ipt_packets value:DERIVE:0:U
+irq value:DERIVE:0:U
+latency value:GAUGE:0:U
+links value:GAUGE:0:U
+load shortterm:GAUGE:0:5000, midterm:GAUGE:0:5000, longterm:GAUGE:0:5000
+md_disks value:GAUGE:0:U
+memcached_command value:DERIVE:0:U
+memcached_connections value:GAUGE:0:U
+memcached_items value:GAUGE:0:U
+memcached_octets rx:DERIVE:0:U, tx:DERIVE:0:U
+memcached_ops value:DERIVE:0:U
+memory value:GAUGE:0:281474976710656
+memory_lua value:GAUGE:0:281474976710656
+memory_throttle_count value:DERIVE:0:U
+multimeter value:GAUGE:U:U
+mutex_operations value:DERIVE:0:U
+mysql_bpool_bytes value:GAUGE:0:U
+mysql_bpool_counters value:DERIVE:0:U
+mysql_bpool_pages value:GAUGE:0:U
+mysql_commands value:DERIVE:0:U
+mysql_handler value:DERIVE:0:U
+mysql_innodb_data value:DERIVE:0:U
+mysql_innodb_dblwr value:DERIVE:0:U
+mysql_innodb_log value:DERIVE:0:U
+mysql_innodb_pages value:DERIVE:0:U
+mysql_innodb_row_lock value:DERIVE:0:U
+mysql_innodb_rows value:DERIVE:0:U
+mysql_locks value:DERIVE:0:U
+mysql_log_position value:DERIVE:0:U
+mysql_octets rx:DERIVE:0:U, tx:DERIVE:0:U
+mysql_select value:DERIVE:0:U
+mysql_sort value:DERIVE:0:U
+mysql_sort_merge_passes value:DERIVE:0:U
+mysql_sort_rows value:DERIVE:0:U
+nfs_procedure value:DERIVE:0:U
+nginx_connections value:GAUGE:0:U
+nginx_requests value:DERIVE:0:U
+node_octets rx:DERIVE:0:U, tx:DERIVE:0:U
+node_rssi value:GAUGE:0:255
+node_stat value:DERIVE:0:U
+node_tx_rate value:GAUGE:0:127
+objects value:GAUGE:0:U
+operations value:DERIVE:0:U
+packets value:DERIVE:0:U
+pending_operations value:GAUGE:0:U
+percent value:GAUGE:0:100.1
+percent_bytes value:GAUGE:0:100.1
+percent_inodes value:GAUGE:0:100.1
+pf_counters value:DERIVE:0:U
+pf_limits value:DERIVE:0:U
+pf_source value:DERIVE:0:U
+pf_state value:DERIVE:0:U
+pf_states value:GAUGE:0:U
+pg_blks value:DERIVE:0:U
+pg_db_size value:GAUGE:0:U
+pg_n_tup_c value:DERIVE:0:U
+pg_n_tup_g value:GAUGE:0:U
+pg_numbackends value:GAUGE:0:U
+pg_scan value:DERIVE:0:U
+pg_xact value:DERIVE:0:U
+ping value:GAUGE:0:65535
+ping_droprate value:GAUGE:0:100
+ping_stddev value:GAUGE:0:65535
+players value:GAUGE:0:1000000
+power value:GAUGE:0:U
+pressure value:GAUGE:0:U
+protocol_counter value:DERIVE:0:U
+ps_code value:GAUGE:0:9223372036854775807
+ps_count processes:GAUGE:0:1000000, threads:GAUGE:0:1000000
+ps_cputime user:DERIVE:0:U, syst:DERIVE:0:U
+ps_data value:GAUGE:0:9223372036854775807
+ps_disk_octets read:DERIVE:0:U, write:DERIVE:0:U
+ps_disk_ops read:DERIVE:0:U, write:DERIVE:0:U
+ps_pagefaults minflt:DERIVE:0:U, majflt:DERIVE:0:U
+ps_rss value:GAUGE:0:9223372036854775807
+ps_stacksize value:GAUGE:0:9223372036854775807
+ps_state value:GAUGE:0:65535
+ps_vm value:GAUGE:0:9223372036854775807
+pubsub value:GAUGE:0:U
+queue_length value:GAUGE:0:U
+records value:GAUGE:0:U
+requests value:GAUGE:0:U
+response_code value:GAUGE:0:U
+response_time value:GAUGE:0:U
+route_etx value:GAUGE:0:U
+route_metric value:GAUGE:0:U
+routes value:GAUGE:0:U
+segments value:GAUGE:0:65535
+serial_octets rx:DERIVE:0:U, tx:DERIVE:0:U
+signal_noise value:GAUGE:U:0
+signal_power value:GAUGE:U:0
+signal_quality value:GAUGE:0:U
smart_attribute current:GAUGE:0:255, worst:GAUGE:0:255, threshold:GAUGE:0:255, pretty:GAUGE:0:U
-snr value:GAUGE:0:U
-spam_check value:GAUGE:0:U
-spam_score value:GAUGE:U:U
-spl value:GAUGE:U:U
-swap_io value:DERIVE:0:U
-swap value:GAUGE:0:1099511627776
-tcp_connections value:GAUGE:0:4294967295
-temperature value:GAUGE:U:U
-threads value:GAUGE:0:U
-time_dispersion value:GAUGE:-1000000:1000000
-timeleft value:GAUGE:0:U
-time_offset value:GAUGE:-1000000:1000000
-total_bytes value:DERIVE:0:U
-total_connections value:DERIVE:0:U
-total_objects value:DERIVE:0:U
-total_operations value:DERIVE:0:U
-total_requests value:DERIVE:0:U
-total_sessions value:DERIVE:0:U
-total_threads value:DERIVE:0:U
-total_time_in_ms value:DERIVE:0:U
-total_values value:DERIVE:0:U
-uptime value:GAUGE:0:4294967295
-users value:GAUGE:0:65535
-vcl value:GAUGE:0:65535
-vcpu value:GAUGE:0:U
-virt_cpu_total value:DERIVE:0:U
-virt_vcpu value:DERIVE:0:U
-vmpage_action value:DERIVE:0:U
-vmpage_faults minflt:DERIVE:0:U, majflt:DERIVE:0:U
-vmpage_io in:DERIVE:0:U, out:DERIVE:0:U
-vmpage_number value:GAUGE:0:4294967295
-volatile_changes value:GAUGE:0:U
-voltage_threshold value:GAUGE:U:U, threshold:GAUGE:U:U
-voltage value:GAUGE:U:U
-vs_memory value:GAUGE:0:9223372036854775807
-vs_processes value:GAUGE:0:65535
-vs_threads value:GAUGE:0:65535
+smart_badsectors value:GAUGE:0:U
+smart_powercycles value:GAUGE:0:U
+smart_poweron value:GAUGE:0:U
+smart_temperature value:GAUGE:-300:300
+snr value:GAUGE:0:U
+spam_check value:GAUGE:0:U
+spam_score value:GAUGE:U:U
+spl value:GAUGE:U:U
+swap value:GAUGE:0:1099511627776
+swap_io value:DERIVE:0:U
+tcp_connections value:GAUGE:0:4294967295
+temperature value:GAUGE:U:U
+threads value:GAUGE:0:U
+time_dispersion value:GAUGE:-1000000:1000000
+time_offset value:GAUGE:-1000000:1000000
+timeleft value:GAUGE:0:U
+total_bytes value:DERIVE:0:U
+total_connections value:DERIVE:0:U
+total_objects value:DERIVE:0:U
+total_operations value:DERIVE:0:U
+total_requests value:DERIVE:0:U
+total_sessions value:DERIVE:0:U
+total_threads value:DERIVE:0:U
+total_time_in_ms value:DERIVE:0:U
+total_values value:DERIVE:0:U
+uptime value:GAUGE:0:4294967295
+users value:GAUGE:0:65535
+vcl value:GAUGE:0:65535
+vcpu value:GAUGE:0:U
+virt_cpu_total value:DERIVE:0:U
+virt_vcpu value:DERIVE:0:U
+vmpage_action value:DERIVE:0:U
+vmpage_faults minflt:DERIVE:0:U, majflt:DERIVE:0:U
+vmpage_io in:DERIVE:0:U, out:DERIVE:0:U
+vmpage_number value:GAUGE:0:4294967295
+volatile_changes value:GAUGE:0:U
+voltage value:GAUGE:U:U
+voltage_threshold value:GAUGE:U:U, threshold:GAUGE:U:U
+vs_memory value:GAUGE:0:9223372036854775807
+vs_processes value:GAUGE:0:65535
+vs_threads value:GAUGE:0:65535
#
# Legacy types
# (required for the v5 upgrade target)
#
-arc_counts demand_data:COUNTER:0:U, demand_metadata:COUNTER:0:U, prefetch_data:COUNTER:0:U, prefetch_metadata:COUNTER:0:U
-arc_l2_bytes read:COUNTER:0:U, write:COUNTER:0:U
-arc_l2_size value:GAUGE:0:U
-arc_ratio value:GAUGE:0:U
-arc_size current:GAUGE:0:U, target:GAUGE:0:U, minlimit:GAUGE:0:U, maxlimit:GAUGE:0:U
-mysql_qcache hits:COUNTER:0:U, inserts:COUNTER:0:U, not_cached:COUNTER:0:U, lowmem_prunes:COUNTER:0:U, queries_in_cache:GAUGE:0:U
-mysql_threads running:GAUGE:0:U, connected:GAUGE:0:U, cached:GAUGE:0:U, created:COUNTER:0:U
+arc_counts demand_data:COUNTER:0:U, demand_metadata:COUNTER:0:U, prefetch_data:COUNTER:0:U, prefetch_metadata:COUNTER:0:U
+arc_l2_bytes read:COUNTER:0:U, write:COUNTER:0:U
+arc_l2_size value:GAUGE:0:U
+arc_ratio value:GAUGE:0:U
+arc_size current:GAUGE:0:U, target:GAUGE:0:U, minlimit:GAUGE:0:U, maxlimit:GAUGE:0:U
+mysql_qcache hits:COUNTER:0:U, inserts:COUNTER:0:U, not_cached:COUNTER:0:U, lowmem_prunes:COUNTER:0:U, queries_in_cache:GAUGE:0:U
+mysql_threads running:GAUGE:0:U, connected:GAUGE:0:U, cached:GAUGE:0:U, created:COUNTER:0:U
/* Folks without pthread will need to disable this plugin. */
#include <pthread.h>
-#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/un.h>
do
{
- char *grpname;
+ const char *grpname;
struct group *g;
struct group sg;
char grbuf[2048];
pthread_exit ((void *) 1);
}
- remote_fd = (int *) malloc (sizeof (int));
+ remote_fd = malloc (sizeof (*remote_fd));
if (remote_fd == NULL)
{
char errbuf[1024];
* Copyright (C) 2005-2007 Sebastian Harl
* Copyright (C) 2005 Niki W. Waibel
* Copyright (C) 2005-2007 Florian octo Forster
- * Copyright (C) 2008 Oleg King
+ * Copyright (C) 2008 Oleg King
*
* 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
users_submit (users);
/* #endif HAVE_GETUTXENT */
-
+
#elif HAVE_GETUTENT
unsigned int users = 0;
struct utmp *entry = NULL;
us = sg_get_user_stats ();
# endif
if (us == NULL)
- return (-1);
+ return (-1);
users_submit ((gauge_t)
# if HAVE_LIBSTATGRAB_0_90
for (i = 0; (i == 0) || (i < plugins_num); i++)
{
char *plugin = NULL;
- int j;
+ size_t j;
if (plugins_num != 0)
plugin = plugins[i];
return (-1);
}
- if ((size_t) ds->ds_num != values_num)
+ if (ds->ds_num != values_num)
{
- ERROR ("ds[%s]->ds_num = %i, "
- "but uc_get_rate_by_name returned %u values.",
- ds->type, ds->ds_num, (unsigned int) values_num);
+ ERROR ("ds[%s]->ds_num = %zu, "
+ "but uc_get_rate_by_name returned %zu values.",
+ ds->type, ds->ds_num, values_num);
print_to_socket (fh, "-1 Error reading value from cache.\n");
sfree (values);
sfree (identifier_copy);
return (-1);
}
- print_to_socket (fh, "%u Value%s found\n", (unsigned int) values_num,
+ print_to_socket (fh, "%zu Value%s found\n", values_num,
(values_num == 1) ? "" : "s");
for (i = 0; i < values_num; i++)
{
sfree (identifier_copy);
vl.values_len = ds->ds_num;
- vl.values = (value_t *) malloc (vl.values_len * sizeof (value_t));
+ vl.values = malloc (vl.values_len * sizeof (*vl.values));
if (vl.values == NULL)
{
print_to_socket (fh, "-1 malloc failed.\n");
} /* while (*buffer != 0) */
/* Done parsing the options. */
- print_to_socket (fh, "0 Success: %i %s been dispatched.\n",
+ if (fh!=stdout)
+ print_to_socket (fh, "0 Success: %i %s been dispatched.\n",
values_submitted,
(values_submitted == 1) ? "value has" : "values have");
}
array_len = *ret_array_len;
- array = (char **) realloc (*ret_array,
+ array = realloc (*ret_array,
sizeof (char *) * (array_len + ci->values_num));
if (array == NULL)
{
assert (((size_t) r_area->ds->ds_num) == r->values_num);
assert (r->values_num > 0);
- vl.values = (value_t *) calloc (r->values_num, sizeof (value_t));
+ vl.values = calloc (r->values_num, sizeof (*vl.values));
if (vl.values == NULL)
{
- ERROR ("db query utils: malloc failed.");
+ ERROR ("db query utils: calloc failed.");
return (-1);
}
vl.values_len = r_area->ds->ds_num;
ERROR ("db query utils: udb_result_submit: Parsing `%s' as %s failed.",
value_str, DS_TYPE_TO_STRING (r_area->ds->ds[i].type));
errno = EINVAL;
+ free (vl.values);
return (-1);
}
}
sstrncpy (vl.type, r->type, sizeof (vl.type));
/* Set vl.type_instance {{{ */
- if (r->instances_num <= 0)
+ if (r->instances_num == 0)
{
if (r->instance_prefix == NULL)
vl.type_instance[0] = 0;
BAIL_OUT (-1);
}
- if (((size_t) prep_area->ds->ds_num) != r->values_num)
+ if (prep_area->ds->ds_num != r->values_num)
{
ERROR ("db query utils: udb_result_prepare_result: The type `%s' "
- "requires exactly %i value%s, but the configuration specifies %zu.",
+ "requires exactly %zu value%s, but the configuration specifies %zu.",
r->type,
prep_area->ds->ds_num, (prep_area->ds->ds_num == 1) ? "" : "s",
r->values_num);
= (size_t *) calloc (r->instances_num, sizeof (size_t));
if (prep_area->instances_pos == NULL)
{
- ERROR ("db query utils: udb_result_prepare_result: malloc failed.");
+ ERROR ("db query utils: udb_result_prepare_result: calloc failed.");
BAIL_OUT (-ENOMEM);
}
= (char **) calloc (r->instances_num, sizeof (char *));
if (prep_area->instances_buffer == NULL)
{
- ERROR ("db query utils: udb_result_prepare_result: malloc failed.");
+ ERROR ("db query utils: udb_result_prepare_result: calloc failed.");
BAIL_OUT (-ENOMEM);
}
} /* if (r->instances_num > 0) */
= (size_t *) calloc (r->values_num, sizeof (size_t));
if (prep_area->values_pos == NULL)
{
- ERROR ("db query utils: udb_result_prepare_result: malloc failed.");
+ ERROR ("db query utils: udb_result_prepare_result: calloc failed.");
BAIL_OUT (-ENOMEM);
}
= (char **) calloc (r->values_num, sizeof (char *));
if (prep_area->values_buffer == NULL)
{
- ERROR ("db query utils: udb_result_prepare_result: malloc failed.");
+ ERROR ("db query utils: udb_result_prepare_result: calloc failed.");
BAIL_OUT (-ENOMEM);
}
= (size_t *) calloc (r->metadata_num, sizeof (size_t));
if (prep_area->metadata_pos == NULL)
{
- ERROR ("db query utils: udb_result_prepare_result: malloc failed.");
+ ERROR ("db query utils: udb_result_prepare_result: calloc failed.");
BAIL_OUT (-ENOMEM);
}
= (char **) calloc (r->metadata_num, sizeof (char *));
if (prep_area->metadata_buffer == NULL)
{
- ERROR ("db query utils: udb_result_prepare_result: malloc failed.");
+ ERROR ("db query utils: udb_result_prepare_result: calloc failed.");
BAIL_OUT (-ENOMEM);
}
ci->values_num, (ci->values_num == 1) ? "" : "s");
}
- r = (udb_result_t *) malloc (sizeof (*r));
+ r = calloc (1, sizeof (*r));
if (r == NULL)
{
- ERROR ("db query utils: malloc failed.");
+ ERROR ("db query utils: calloc failed.");
return (-1);
}
- memset (r, 0, sizeof (*r));
r->type = NULL;
r->instance_prefix = NULL;
r->instances = NULL;
return (-1);
}
- q = (udb_query_t *) malloc (sizeof (*q));
+ q = calloc (1, sizeof (*q));
if (q == NULL)
{
- ERROR ("db query utils: malloc failed.");
+ ERROR ("db query utils: calloc failed.");
return (-1);
}
- memset (q, 0, sizeof (*q));
q->min_version = 0;
q->max_version = UINT_MAX;
{
udb_query_t **temp;
- temp = (udb_query_t **) realloc (query_list,
+ temp = realloc (query_list,
sizeof (*query_list) * (query_list_len + 1));
if (temp == NULL)
{
continue;
tmp_list_len = *dst_list_len;
- tmp_list = (udb_query_t **) realloc (*dst_list, (tmp_list_len + 1)
+ tmp_list = realloc (*dst_list, (tmp_list_len + 1)
* sizeof (udb_query_t *));
if (tmp_list == NULL)
{
udb_result_preparation_area_t **next_r_area;
udb_result_t *r;
- q_area = malloc (sizeof (*q_area));
+ q_area = calloc (1, sizeof (*q_area));
if (q_area == NULL)
return NULL;
- memset (q_area, 0, sizeof (*q_area));
next_r_area = &q_area->result_prep_areas;
for (r = q->results; r != NULL; r = r->next)
{
udb_result_preparation_area_t *r_area;
- r_area = malloc (sizeof (*r_area));
+ r_area = calloc (1, sizeof (*r_area));
if (r_area == NULL)
{
udb_result_preparation_area_t *a = q_area->result_prep_areas;
return NULL;
}
- memset (r_area, 0, sizeof (*r_area));
-
*next_r_area = r_area;
next_r_area = &r_area->next;
}
typedef int (*udb_query_create_callback_t) (udb_query_t *q,
oconfig_item_t *ci);
-/*
+/*
* Public functions
*/
int udb_query_create (udb_query_t ***ret_query_list,
void udb_query_set_user_data (udb_query_t *q, void *user_data);
void *udb_query_get_user_data (udb_query_t *q);
-/*
+/*
* udb_query_check_version
*
* Returns 0 if the query is NOT suitable for `version' and >0 if the
#include "plugin.h"
#include "common.h"
-#if HAVE_SYS_SOCKET_H
-# include <sys/socket.h>
-#endif
-
#if HAVE_NET_IF_ARP_H
# include <net/if_arp.h>
#endif
#if HAVE_NETINET_IP6_H
# include <netinet/ip6.h>
#endif
-#if HAVE_NETINET_IP_COMPAT_H
-# include <netinet/ip_compat.h>
-#endif
#if HAVE_NETINET_IF_ETHER_H
# include <netinet/if_ether.h>
#endif
/*
* Global variables
*/
-int qtype_counts[T_MAX];
-int opcode_counts[OP_MAX];
-int qclass_counts[C_MAX];
#if HAVE_PCAP_H
static pcap_t *pcap_obj = NULL;
if (ignore_list_match (addr) != 0)
return;
- new = malloc (sizeof (ip_list_t));
+ new = malloc (sizeof (*new));
if (new == NULL)
{
perror ("malloc");
if (ns <= 0)
return 4; /* probably compression loop */
do {
- if ((*off) >= sz)
+ if ((*off) >= ((off_t) sz))
break;
c = *(buf + (*off));
if (c > 191) {
s = ntohs(s);
(*off) += sizeof(s);
/* Sanity check */
- if ((*off) >= sz)
+ if ((*off) >= ((off_t) sz))
return 1; /* message too short */
ptr = s & 0x3FFF;
/* Make sure the pointer is inside this message */
- if (ptr >= sz)
+ if (ptr >= ((off_t) sz))
return 2; /* bad compression ptr */
if (ptr < DNS_MSG_HDR_SZ)
return 2; /* bad compression ptr */
if (no > 0)
*(name + no - 1) = '\0';
/* make sure we didn't allow someone to overflow the name buffer */
- assert(no <= ns);
+ assert(no <= ((off_t) ns));
return 0;
}
qh.length = (uint16_t) len;
- /* gather stats */
- qtype_counts[qh.qtype]++;
- qclass_counts[qh.qclass]++;
- opcode_counts[qh.opcode]++;
-
if (Callback != NULL)
Callback (&qh);
* Copyright (C) 2006 Florian octo Forster
* Copyright (C) 2002 The Measurement Factory, Inc.
* All rights reserved.
- *
+ *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
- *
+ *
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
#define DNS_MSG_HDR_SZ 12
#define T_MAX 65536
-#define OP_MAX 16
-#define C_MAX 65536
#define MAX_QNAME_SZ 512
struct rfc1035_header_s {
};
typedef struct rfc1035_header_s rfc1035_header_t;
-extern int qtype_counts[T_MAX];
-extern int opcode_counts[OP_MAX];
-extern int qclass_counts[C_MAX];
-
#if HAVE_PCAP_H
void dnstop_set_pcap_obj (pcap_t *po);
#endif
if (file == NULL)
return (NULL);
- h = malloc (sizeof (*h));
+ h = calloc (1, sizeof (*h));
if (h == NULL)
return (NULL);
- memset (h, 0, sizeof (*h));
h->filename = strdup (file);
if (h->filename == NULL)
unsigned int flags)
{
int status = 0;
- int i;
+ size_t i;
int buffer_pos = 0;
gauge_t *rates = NULL;
const data_set_t *ds, const value_list_t *vl, int store_rates)
{
size_t offset = 0;
- int i;
+ size_t i;
gauge_t *rates = NULL;
memset (buffer, 0, buffer_size);
const data_set_t *ds)
{
size_t offset = 0;
- int i;
+ size_t i;
memset (buffer, 0, buffer_size);
const data_set_t *ds)
{
size_t offset = 0;
- int i;
+ size_t i;
memset (buffer, 0, buffer_size);
}
} /* for (keys) */
- if (offset <= 0)
+ if (offset == 0)
return (ENOENT);
buffer[0] = '{'; /* replace leading ',' */
{
latency_counter_t *lc;
- lc = malloc (sizeof (*lc));
+ lc = calloc (1, sizeof (*lc));
if (lc == NULL)
return (NULL);
- memset (lc, 0, sizeof (*lc));
latency_counter_reset (lc);
lc->bin_width = HISTOGRAM_DEFAULT_BIN_WIDTH;
--- /dev/null
+/**
+ * collectd - src/utils_latency_test.c
+ * Copyright (C) 2015 Florian octo Forster
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ * Florian octo Forster <octo at collectd.org>
+ */
+
+#define DBL_PRECISION 1e-9
+
+#include "common.h" /* for STATIC_ARRAY_SIZE */
+#include "collectd.h"
+#include "testing.h"
+#include "utils_time.h"
+#include "utils_latency.h"
+
+DEF_TEST(simple)
+{
+ struct {
+ double val;
+ double min;
+ double max;
+ double sum;
+ double avg;
+ } cases[] = {
+ /* val min max sum avg */
+ {0.5, 0.5, 0.5, 0.5, 0.5},
+ {0.3, 0.3, 0.5, 0.8, 0.4},
+ {0.7, 0.3, 0.7, 1.5, 0.5},
+ {2.5, 0.3, 2.5, 4.0, 1.0},
+ { 99, 0.3, 99, 103, 20.6},
+ /* { -1, 0.3, 99, 103, 20.6}, see issue #1139 */
+ };
+ size_t i;
+ latency_counter_t *l;
+
+ CHECK_NOT_NULL (l = latency_counter_create ());
+
+ for (i = 0; i < STATIC_ARRAY_SIZE (cases); i++) {
+ printf ("# case %zu: DOUBLE_TO_CDTIME_T(%g) = %"PRIu64"\n",
+ i, cases[i].val, DOUBLE_TO_CDTIME_T (cases[i].val));
+ latency_counter_add (l, DOUBLE_TO_CDTIME_T (cases[i].val));
+
+ EXPECT_EQ_DOUBLE (cases[i].min, CDTIME_T_TO_DOUBLE (latency_counter_get_min (l)));
+ EXPECT_EQ_DOUBLE (cases[i].max, CDTIME_T_TO_DOUBLE (latency_counter_get_max (l)));
+ EXPECT_EQ_DOUBLE (cases[i].sum, CDTIME_T_TO_DOUBLE (latency_counter_get_sum (l)));
+ EXPECT_EQ_DOUBLE (cases[i].avg, CDTIME_T_TO_DOUBLE (latency_counter_get_average (l)));
+ }
+
+ latency_counter_destroy (l);
+ return 0;
+}
+
+DEF_TEST(percentile)
+{
+ size_t i;
+ latency_counter_t *l;
+
+ CHECK_NOT_NULL (l = latency_counter_create ());
+
+ for (i = 0; i < 100; i++) {
+ latency_counter_add (l, TIME_T_TO_CDTIME_T (((time_t) i) + 1));
+ }
+
+ EXPECT_EQ_DOUBLE ( 1.0, CDTIME_T_TO_DOUBLE (latency_counter_get_min (l)));
+ EXPECT_EQ_DOUBLE (100.0, CDTIME_T_TO_DOUBLE (latency_counter_get_max (l)));
+ EXPECT_EQ_DOUBLE (100.0 * 101.0 / 2.0, CDTIME_T_TO_DOUBLE (latency_counter_get_sum (l)));
+ EXPECT_EQ_DOUBLE ( 50.5, CDTIME_T_TO_DOUBLE (latency_counter_get_average (l)));
+
+ EXPECT_EQ_DOUBLE (50.0, CDTIME_T_TO_DOUBLE (latency_counter_get_percentile (l, 50.0)));
+ EXPECT_EQ_DOUBLE (80.0, CDTIME_T_TO_DOUBLE (latency_counter_get_percentile (l, 80.0)));
+ EXPECT_EQ_DOUBLE (95.0, CDTIME_T_TO_DOUBLE (latency_counter_get_percentile (l, 95.0)));
+ EXPECT_EQ_DOUBLE (99.0, CDTIME_T_TO_DOUBLE (latency_counter_get_percentile (l, 99.0)));
+
+ CHECK_ZERO (latency_counter_get_percentile (l, -1.0));
+ CHECK_ZERO (latency_counter_get_percentile (l, 101.0));
+
+ latency_counter_destroy (l);
+ return 0;
+}
+
+int main (void)
+{
+ RUN_TEST(simple);
+ RUN_TEST(percentile);
+
+ END_TEST;
+}
+
+/* vim: set sw=2 sts=2 et : */
return (NULL);
}
- if ((buf = (STRUCT_STATFS *) malloc (bufsize * sizeof (STRUCT_STATFS)))
- == NULL)
+ if ((buf = calloc (bufsize, sizeof (*buf))) == NULL)
return (NULL);
- memset (buf, '\0', bufsize * sizeof (STRUCT_STATFS));
/* The bufsize needs to be passed in bytes. Really. This is not in the
* manpage.. -octo */
for (i = 0; i < num; i++)
{
- if ((new = malloc (sizeof (cu_mount_t))) == NULL)
+ if ((new = calloc (1, sizeof (*new))) == NULL)
break;
- memset (new, '\0', sizeof (cu_mount_t));
-
+
/* Copy values from `struct mnttab' */
new->dir = sstrdup (buf[i].f_mntonname);
new->spec_device = sstrdup (buf[i].f_mntfromname);
while (getmntent (fp, &mt) == 0)
{
- if ((new = malloc (sizeof (cu_mount_t))) == NULL)
+ if ((new = calloc (1, sizeof (*new))) == NULL)
break;
- memset (new, '\0', sizeof (cu_mount_t));
-
+
/* Copy values from `struct mnttab' */
new->dir = sstrdup (mt.mnt_mountp);
new->spec_device = sstrdup (mt.mnt_special);
while (getmntent_r (fp, &me, mntbuf, sizeof (mntbuf) ))
{
- if ((new = malloc (sizeof (cu_mount_t))) == NULL)
+ if ((new = calloc (1, sizeof (*new))) == NULL)
break;
- memset (new, '\0', sizeof (cu_mount_t));
/* Copy values from `struct mntent *' */
new->dir = sstrdup (me.mnt_dir);
while ((me = getmntent (fp)) != NULL)
{
- if ((new = malloc (sizeof (cu_mount_t))) == NULL)
+ if ((new = calloc (1, sizeof (*new))) == NULL)
break;
- memset (new, '\0', sizeof (cu_mount_t));
-
+
/* Copy values from `struct mntent *' */
new->dir = sstrdup (me->mnt_dir);
new->spec_device = sstrdup (me->mnt_fsname);
} /* void cu_mount_freelist(cu_mount_t *list) */
char *
-cu_mount_checkoption(char *line, char *keyword, int full)
+cu_mount_checkoption(char *line, const char *keyword, int full)
{
char *line2, *l2, *p1, *p2;
int l;
} /* char *cu_mount_checkoption(char *line, char *keyword, int full) */
char *
-cu_mount_getoptionvalue(char *line, char *keyword)
+cu_mount_getoptionvalue(char *line, const char *keyword)
{
char *r;
if((p-r) == 1) {
return NULL;
}
- m = (char *)smalloc(p-r+1);
+ m = smalloc(p-r+1);
sstrncpy(m, r, p-r+1);
return m;
}
}
return r;
-} /* char *cu_mount_getoptionvalue(char *line, char *keyword) */
+} /* char *cu_mount_getoptionvalue(char *line, const char *keyword) */
int
cu_mount_type(const char *type)
allocated by *list and *list itself as well.
*/
-char *cu_mount_checkoption(char *line, char *keyword, int full);
+char *cu_mount_checkoption(char *line, const char *keyword, int full);
/*
DESCRIPTION
The cu_mount_checkoption() function is a replacement of
maybe you might want to try cu_mount_getoptionvalue()...
*/
-char *cu_mount_getoptionvalue(char *line, char *keyword);
+char *cu_mount_getoptionvalue(char *line, const char *keyword);
/*
DESCRIPTION
The cu_mount_getoptionvalue() function can be used to grab
* Florian octo Forster <octo at collectd.org>
*/
-#include "testing.h"
#include "collectd.h"
+#include "testing.h"
#include "utils_mount.h"
#if HAVE_LIBKSTAT
char line_opts[] = "foo=one,bar=two,qux=three";
char line_bool[] = "one,two,three";
- STREQ ("one", cu_mount_getoptionvalue (line_opts, "foo="));
- STREQ ("two", cu_mount_getoptionvalue (line_opts, "bar="));
- STREQ ("three", cu_mount_getoptionvalue (line_opts, "qux="));
+ EXPECT_EQ_STR ("one", cu_mount_getoptionvalue (line_opts, "foo="));
+ EXPECT_EQ_STR ("two", cu_mount_getoptionvalue (line_opts, "bar="));
+ EXPECT_EQ_STR ("three", cu_mount_getoptionvalue (line_opts, "qux="));
OK (NULL == cu_mount_getoptionvalue (line_opts, "unknown="));
- STREQ ("", cu_mount_getoptionvalue (line_bool, "one"));
- STREQ ("", cu_mount_getoptionvalue (line_bool, "two"));
- STREQ ("", cu_mount_getoptionvalue (line_bool, "three"));
+ EXPECT_EQ_STR ("", cu_mount_getoptionvalue (line_bool, "one"));
+ EXPECT_EQ_STR ("", cu_mount_getoptionvalue (line_bool, "two"));
+ EXPECT_EQ_STR ("", cu_mount_getoptionvalue (line_bool, "three"));
OK (NULL == cu_mount_getoptionvalue (line_bool, "four"));
return (0);
buffer++;
}
}
-
+
/* Eat up trailing spaces */
while (isspace ((int) *buffer))
buffer++;
};
static int rra_timespans_num = STATIC_ARRAY_SIZE (rra_timespans);
-static char *rra_types[] =
+static const char *const rra_types[] =
{
"AVERAGE",
"MIN",
};
static int rra_types_num = STATIC_ARRAY_SIZE (rra_types);
-#if !defined(HAVE_THREADSAFE_LIBRRD) || !HAVE_THREADSAFE_LIBRRD
+#if !defined(HAVE_THREADSAFE_LIBRRD)
static pthread_mutex_t librrd_lock = PTHREAD_MUTEX_INITIALIZER;
#endif
{
srrd_create_args_t *args;
- args = malloc (sizeof (*args));
+ args = calloc (1, sizeof (*args));
if (args == NULL)
{
- ERROR ("srrd_create_args_create: malloc failed.");
+ ERROR ("srrd_create_args_create: calloc failed.");
return (NULL);
}
- memset (args, 0, sizeof (*args));
args->filename = NULL;
args->pdp_step = pdp_step;
args->last_up = last_up;
rra_max = rts_num * rra_types_num;
assert (rra_max > 0);
- if ((rra_def = malloc ((rra_max + 1) * sizeof (*rra_def))) == NULL)
+ if ((rra_def = calloc (rra_max + 1, sizeof (*rra_def))) == NULL)
return (-1);
- memset (rra_def, 0, (rra_max + 1) * sizeof (*rra_def));
rra_num = 0;
cdp_len = 0;
const rrdcreate_config_t *cfg)
{
char **ds_def;
- int ds_num;
+ size_t ds_num;
char min[32];
char max[32];
assert (ds->ds_num > 0);
- ds_def = malloc (ds->ds_num * sizeof (*ds_def));
+ ds_def = calloc (ds->ds_num, sizeof (*ds_def));
if (ds_def == NULL)
{
char errbuf[1024];
- ERROR ("rrdtool plugin: malloc failed: %s",
+ ERROR ("rrdtool plugin: calloc failed: %s",
sstrerror (errno, errbuf, sizeof (errbuf)));
return (-1);
}
- memset (ds_def, 0, ds->ds_num * sizeof (*ds_def));
for (ds_num = 0; ds_num < ds->ds_num; ds_num++)
{
data_source_t *d = ds->ds + ds_num;
- char *type;
+ const char *type;
int status;
ds_def[ds_num] = NULL;
return (-1);
}
- if (ds_num <= 0)
+ if (ds_num == 0)
{
sfree (ds_def);
return (0);
char last_up_str[16];
new_argc = 6 + argc;
- new_argv = (char **) malloc ((new_argc + 1) * sizeof (char *));
+ new_argv = malloc ((new_argc + 1) * sizeof (*new_argv));
if (new_argv == NULL)
{
ERROR ("rrdtool plugin: malloc failed.");
argc = ds_num + rra_num;
- if ((argv = (char **) malloc (sizeof (char *) * (argc + 1))) == NULL)
+ if ((argv = malloc (sizeof (*argv) * (argc + 1))) == NULL)
{
char errbuf[1024];
ERROR ("cu_rrd_create_file failed: %s",
assert (sizeof (match_part->str) > len);
/* strip trailing slash */
match_part->str[len - 2] = 0;
-
+
status = regcomp (&match_part->regex, match_part->str,
/* flags = */ REG_EXTENDED);
if (status != 0)
return (EINVAL);
}
match_part->is_regex = 1;
-
+
return (0);
} /* }}} int lu_copy_ident_to_match_part */
{
user_obj_t *user_obj;
- user_obj = malloc (sizeof (*user_obj));
+ user_obj = calloc (1, sizeof (*user_obj));
if (user_obj == NULL)
{
- ERROR ("utils_vl_lookup: malloc failed.");
+ ERROR ("utils_vl_lookup: calloc failed.");
return (NULL);
}
- memset (user_obj, 0, sizeof (*user_obj));
user_obj->next = NULL;
user_obj->user_obj = obj->cb_user_class (ds, vl, user_class->user_class);
{
user_class_list_t *ptr;
int retval = 0;
-
+
for (ptr = user_class_list; ptr != NULL; ptr = ptr->next)
{
int status;
return (NULL);
}
- by_type = malloc (sizeof (*by_type));
+ by_type = calloc (1, sizeof (*by_type));
if (by_type == NULL)
{
- ERROR ("utils_vl_lookup: malloc failed.");
+ ERROR ("utils_vl_lookup: calloc failed.");
sfree (type_copy);
return (NULL);
}
- memset (by_type, 0, sizeof (*by_type));
by_type->wildcard_plugin_list = NULL;
-
+
by_type->by_plugin_tree = c_avl_create ((void *) strcmp);
if (by_type->by_plugin_tree == NULL)
{
sfree (type_copy);
return (NULL);
}
-
+
return (by_type);
} /* }}} by_type_entry_t *lu_search_by_type */
static void lu_destroy_by_type (lookup_t *obj, /* {{{ */
by_type_entry_t *by_type)
{
-
+
while (42)
{
char *plugin = NULL;
lookup_free_class_callback_t cb_free_class,
lookup_free_obj_callback_t cb_free_obj)
{
- lookup_t *obj = malloc (sizeof (*obj));
+ lookup_t *obj = calloc (1, sizeof (*obj));
if (obj == NULL)
{
- ERROR ("utils_vl_lookup: malloc failed.");
+ ERROR ("utils_vl_lookup: calloc failed.");
return (NULL);
}
- memset (obj, 0, sizeof (*obj));
obj->by_type_tree = c_avl_create ((void *) strcmp);
if (obj->by_type_tree == NULL)
if (by_type == NULL)
return (-1);
- user_class_obj = malloc (sizeof (*user_class_obj));
+ user_class_obj = calloc (1, sizeof (*user_class_obj));
if (user_class_obj == NULL)
{
- ERROR ("utils_vl_lookup: malloc failed.");
+ ERROR ("utils_vl_lookup: calloc failed.");
return (ENOMEM);
}
- memset (user_class_obj, 0, sizeof (*user_class_obj));
pthread_mutex_init (&user_class_obj->entry.lock, /* attr = */ NULL);
user_class_obj->entry.user_class = user_class;
lu_copy_ident_to_match (&user_class_obj->entry.match, ident, group_by);
return (status);
retval += status;
}
-
+
return (retval);
} /* }}} lookup_search */
* Florian Forster <octo at collectd.org>
**/
-#include "testing.h"
#include "collectd.h"
+#include "testing.h"
#include "utils_vl_lookup.h"
static _Bool expect_new_obj = 0;
identifier_t *class = user_class;
identifier_t *obj;
- OK(expect_new_obj);
+ assert (expect_new_obj);
memcpy (&last_class_ident, class, sizeof (last_class_ident));
-
+
obj = malloc (sizeof (*obj));
strncpy (obj->host, vl->host, sizeof (obj->host));
strncpy (obj->plugin, vl->plugin, sizeof (obj->plugin));
return ((void *) obj);
}
-static void checked_lookup_add (lookup_t *obj, /* {{{ */
+static int checked_lookup_add (lookup_t *obj, /* {{{ */
char const *host,
char const *plugin, char const *plugin_instance,
char const *type, char const *type_instance,
memmove (user_class, &ident, sizeof (ident));
OK(lookup_add (obj, &ident, group_by, user_class) == 0);
-} /* }}} void test_add */
+ return 0;
+} /* }}} int checked_lookup_add */
static int checked_lookup_search (lookup_t *obj,
char const *host,
return (status);
}
-static lookup_t *checked_lookup_create (void)
-{
- lookup_t *obj = lookup_create (
- lookup_class_callback,
- lookup_obj_callback,
- (void *) free,
- (void *) free);
- OK(obj != NULL);
- return (obj);
-}
-
DEF_TEST(group_by_specific_host)
{
- lookup_t *obj = checked_lookup_create ();
+ lookup_t *obj;
+ CHECK_NOT_NULL (obj = lookup_create (
+ lookup_class_callback, lookup_obj_callback, (void *) free, (void *) free));
checked_lookup_add (obj, "/.*/", "test", "", "test", "/.*/", LU_GROUP_BY_HOST);
checked_lookup_search (obj, "host0", "test", "", "test", "0",
DEF_TEST(group_by_any_host)
{
- lookup_t *obj = checked_lookup_create ();
+ lookup_t *obj;
+ CHECK_NOT_NULL (obj = lookup_create (
+ lookup_class_callback, lookup_obj_callback, (void *) free, (void *) free));
checked_lookup_add (obj, "/.*/", "/.*/", "/.*/", "test", "/.*/", LU_GROUP_BY_HOST);
checked_lookup_search (obj, "host0", "plugin0", "", "test", "0",
DEF_TEST(multiple_lookups)
{
- lookup_t *obj = checked_lookup_create ();
+ lookup_t *obj;
int status;
+ CHECK_NOT_NULL (obj = lookup_create (
+ lookup_class_callback, lookup_obj_callback, (void *) free, (void *) free));
+
checked_lookup_add (obj, "/.*/", "plugin0", "", "test", "/.*/", LU_GROUP_BY_HOST);
checked_lookup_add (obj, "/.*/", "/.*/", "", "test", "ti0", LU_GROUP_BY_HOST);
DEF_TEST(regex)
{
- lookup_t *obj = checked_lookup_create ();
+ lookup_t *obj;
+ CHECK_NOT_NULL (obj = lookup_create (
+ lookup_class_callback, lookup_obj_callback, (void *) free, (void *) free));
checked_lookup_add (obj, "/^db[0-9]\\./", "cpu", "/.*/", "cpu", "/.*/",
LU_GROUP_BY_TYPE_INSTANCE);
if (!dmidecode) {
return NULL;
}
-
+
uuid = uuid_parse_dmidecode(dmidecode);
pclose(dmidecode);
{
struct VSM_data *vd;
const c_varnish_stats_t *stats;
+ _Bool ok;
user_config_t *conf;
}
#if HAVE_VARNISH_V3
- if (VSC_Open (vd, /* diag = */ 1))
+ ok = (VSC_Open (vd, /* diag = */ 1) == 0);
#else /* if HAVE_VARNISH_V4 */
- if (VSM_Open (vd))
+ ok = (VSM_Open (vd) == 0);
#endif
+ if (!ok)
{
VSM_Delete (vd);
ERROR ("varnish plugin: Unable to open connection.");
if (have_instance)
return (0);
- conf = malloc (sizeof (*conf));
+ conf = calloc (1, sizeof (*conf));
if (conf == NULL)
return (ENOMEM);
- memset (conf, 0, sizeof (*conf));
/* Default settings: */
conf->instance = NULL;
plugin_register_complex_read (/* group = */ "varnish",
/* name = */ "varnish/localhost",
/* callback = */ varnish_read,
- /* interval = */ NULL,
+ /* interval = */ 0,
/* user data = */ &ud);
return (0);
char callback_name[DATA_MAX_NAME_LEN];
int i;
- conf = malloc (sizeof (*conf));
+ conf = calloc (1, sizeof (*conf));
if (conf == NULL)
return (ENOMEM);
- memset (conf, 0, sizeof (*conf));
conf->instance = NULL;
varnish_config_apply_default (conf);
plugin_register_complex_read (/* group = */ "varnish",
/* name = */ callback_name,
/* callback = */ varnish_read,
- /* interval = */ NULL,
+ /* interval = */ 0,
/* user data = */ &ud);
have_instance = 1;
};
static enum plginst_field plugin_instance_format[PLGINST_MAX_FIELDS] =
- { plginst_name };
+ { plginst_none };
/* InterfaceFormat. */
enum if_field {
}
for (i = 0; i < n; ++i) {
- if (strcasecmp (fields[i], "name") == 0)
+ if (strcasecmp (fields[i], "none") == 0) {
+ plugin_instance_format[i] = plginst_none;
+ break;
+ } else if (strcasecmp (fields[i], "name") == 0)
plugin_instance_format[i] = plginst_name;
else if (strcasecmp (fields[i], "uuid") == 0)
plugin_instance_format[i] = plginst_uuid;
int *domids;
/* Get list of domains. */
- domids = malloc (sizeof (int) * n);
- if (domids == 0) {
+ domids = malloc (sizeof (*domids) * n);
+ if (domids == NULL) {
ERROR (PLUGIN_NAME " plugin: malloc failed.");
return -1;
}
}
static void
-free_domains ()
+free_domains (void)
{
int i;
}
static void
-free_block_devices ()
+free_block_devices (void)
{
int i;
}
static void
-free_interface_devices ()
+free_interface_devices (void)
{
int i;
if (fields[1] == endptr)
continue;
- /*
+ /*
* Number of pages
*
* The total number of {inst} pages, e. g dirty pages.
}
}
- /*
+ /*
* Page in and page outs. For memory and swap.
*/
else if (strcmp ("pgpgin", key) == 0)
if (proc == NULL)
{
char errbuf[1024];
- ERROR ("vserver plugin: fopen (%s): %s", PROCDIR,
+ ERROR ("vserver plugin: fopen (%s): %s", PROCDIR,
sstrerror (errno, errbuf, sizeof (errbuf)));
return (-1);
}
len = ssnprintf (file, sizeof (file), PROCDIR "/%s", dent->d_name);
if ((len < 0) || (len >= BUFSIZE))
continue;
-
+
status = stat (file, &statbuf);
if (status != 0)
{
file, sstrerror (errno, errbuf, sizeof (errbuf)));
continue;
}
-
+
if (!S_ISDIR (statbuf.st_mode))
continue;
{
derive_t rx;
derive_t tx;
- char *type_instance;
+ const char *type_instance;
if (strsplit (buffer, cols, 4) < 4)
continue;
if (2 == n)
{
- char *type_instance;
+ const char *type_instance;
gauge_t value;
if (0 == strcmp (cols[0], "nr_threads:"))
while ((fh != NULL) && (NULL != fgets (buffer, BUFSIZE, fh)))
{
- char *type = "vs_memory";
- char *type_instance;
+ const char *type = "vs_memory";
+ const char *type_instance;
gauge_t value;
if (strsplit (buffer, cols, 2) < 2)
/*
* dbm = 10 * log_{10} (1000 * power / W)
- * power = 10^(dbm/10) * W/1000
+ * power = 10^(dbm/10) * W/1000
*/
watt = pow (10.0, (dbm / 10.0)) / 1000.0;
double quality;
double power;
double noise;
-
+
char *fields[8];
int numfields;
/* Folks without pthread will need to disable this plugin. */
#include <pthread.h>
-#include <sys/socket.h>
#include <netdb.h>
-#ifndef WG_DEFAULT_NODE
-# define WG_DEFAULT_NODE "localhost"
-#endif
-
-#ifndef WG_DEFAULT_SERVICE
-# define WG_DEFAULT_SERVICE "2003"
-#endif
-
-#ifndef WG_DEFAULT_PROTOCOL
-# define WG_DEFAULT_PROTOCOL "tcp"
-#endif
-
-#ifndef WG_DEFAULT_LOG_SEND_ERRORS
-# define WG_DEFAULT_LOG_SEND_ERRORS 1
-#endif
-
-#ifndef WG_DEFAULT_ESCAPE
-# define WG_DEFAULT_ESCAPE '_'
-#endif
+#define WG_DEFAULT_NODE "localhost"
+#define WG_DEFAULT_SERVICE "2003"
+#define WG_DEFAULT_PROTOCOL "tcp"
+#define WG_DEFAULT_LOG_SEND_ERRORS 1
+#define WG_DEFAULT_ESCAPE '_'
/* Ethernet - (IPv6 + TCP) = 1500 - (40 + 32) = 1428 */
-#ifndef WG_SEND_BUF_SIZE
-# define WG_SEND_BUF_SIZE 1428
-#endif
+#define WG_SEND_BUF_SIZE 1428
-#ifndef WG_MIN_RECONNECT_INTERVAL
-# define WG_MIN_RECONNECT_INTERVAL TIME_T_TO_CDTIME_T (1)
-#endif
+#define WG_MIN_RECONNECT_INTERVAL TIME_T_TO_CDTIME_T (1)
/*
* Private variables
pthread_mutex_t send_lock;
c_complain_t init_complaint;
cdtime_t last_connect_time;
+
+ /* Force reconnect useful for load balanced environments */
+ cdtime_t last_reconnect_time;
+ cdtime_t reconnect_interval;
+ _Bool reconnect_interval_reached;
};
+/* wg_force_reconnect_check closes cb->sock_fd when it was open for longer
+ * than cb->reconnect_interval. Must hold cb->send_lock when calling. */
+static void wg_force_reconnect_check (struct wg_callback *cb)
+{
+ cdtime_t now;
+
+ if (cb->reconnect_interval == 0)
+ return;
+
+ /* check if address changes if addr_timeout */
+ now = cdtime ();
+ if ((now - cb->last_reconnect_time) < cb->reconnect_interval)
+ return;
+
+ /* here we should close connection on next */
+ close (cb->sock_fd);
+ cb->sock_fd = -1;
+ cb->last_reconnect_time = now;
+ cb->reconnect_interval_reached = 1;
+
+ INFO ("write_graphite plugin: Connection closed after %.3f seconds.",
+ CDTIME_T_TO_DOUBLE (now - cb->last_reconnect_time));
+}
/*
* Functions
status = swrite (cb->sock_fd, cb->send_buf, strlen (cb->send_buf));
if (status != 0)
{
- const char *protocol = cb->protocol ? cb->protocol : WG_DEFAULT_PROTOCOL;
-
if (cb->log_send_errors)
{
char errbuf[1024];
ERROR ("write_graphite plugin: send to %s:%s (%s) failed with status %zi (%s)",
- cb->node, cb->service, protocol,
+ cb->node, cb->service, cb->protocol,
status, sstrerror (errno, errbuf, sizeof (errbuf)));
}
return (0);
}
- if (cb->send_buf_fill <= 0)
+ if (cb->send_buf_fill == 0)
{
cb->send_buf_init_time = cdtime ();
return (0);
cdtime_t now;
int status;
- const char *node = cb->node ? cb->node : WG_DEFAULT_NODE;
- const char *service = cb->service ? cb->service : WG_DEFAULT_SERVICE;
- const char *protocol = cb->protocol ? cb->protocol : WG_DEFAULT_PROTOCOL;
-
char connerr[1024] = "";
if (cb->sock_fd > 0)
#endif
ai_hints.ai_family = AF_UNSPEC;
- if (0 == strcasecmp ("tcp", protocol))
+ if (0 == strcasecmp ("tcp", cb->protocol))
ai_hints.ai_socktype = SOCK_STREAM;
else
ai_hints.ai_socktype = SOCK_DGRAM;
ai_list = NULL;
- status = getaddrinfo (node, service, &ai_hints, &ai_list);
+ status = getaddrinfo (cb->node, cb->service, &ai_hints, &ai_list);
if (status != 0)
{
ERROR ("write_graphite plugin: getaddrinfo (%s, %s, %s) failed: %s",
- node, service, protocol, gai_strerror (status));
+ cb->node, cb->service, cb->protocol, gai_strerror (status));
return (-1);
}
sstrerror (errno, connerr, sizeof (connerr));
c_complain (LOG_ERR, &cb->init_complaint,
"write_graphite plugin: Connecting to %s:%s via %s failed. "
- "The last error was: %s", node, service, protocol, connerr);
+ "The last error was: %s", cb->node, cb->service, cb->protocol, connerr);
return (-1);
}
else
{
c_release (LOG_INFO, &cb->init_complaint,
"write_graphite plugin: Successfully connected to %s:%s via %s.",
- node, service, protocol);
+ cb->node, cb->service, cb->protocol);
}
- wg_reset_buffer (cb);
+ /* wg_force_reconnect_check does not flush the buffer before closing a
+ * sending socket, so only call wg_reset_buffer() if the socket was closed
+ * for a different reason (tracked in cb->reconnect_interval_reached). */
+ if (!cb->reconnect_interval_reached || (cb->send_buf_free == 0))
+ wg_reset_buffer (cb);
+ else
+ cb->reconnect_interval_reached = 0;
return (0);
}
pthread_mutex_lock (&cb->send_lock);
+ wg_force_reconnect_check (cb);
+
if (cb->sock_fd < 0)
{
status = wg_callback_init (cb);
cb->send_buf_free -= message_len;
DEBUG ("write_graphite plugin: [%s]:%s (%s) buf %zu/%zu (%.1f %%) \"%s\"",
- cb->node,
- cb->service,
- cb->protocol,
+ cb->node, cb->service, cb->protocol,
cb->send_buf_fill, sizeof (cb->send_buf),
100.0 * ((double) cb->send_buf_fill) / ((double) sizeof (cb->send_buf)),
message);
int i;
int status = 0;
- cb = malloc (sizeof (*cb));
+ cb = calloc (1, sizeof (*cb));
if (cb == NULL)
{
- ERROR ("write_graphite plugin: malloc failed.");
+ ERROR ("write_graphite plugin: calloc failed.");
return (-1);
}
- memset (cb, 0, sizeof (*cb));
cb->sock_fd = -1;
cb->name = NULL;
- cb->node = NULL;
- cb->service = NULL;
- cb->protocol = NULL;
+ cb->node = strdup (WG_DEFAULT_NODE);
+ cb->service = strdup (WG_DEFAULT_SERVICE);
+ cb->protocol = strdup (WG_DEFAULT_PROTOCOL);
+ cb->last_reconnect_time = cdtime();
+ cb->reconnect_interval = 0;
+ cb->reconnect_interval_reached = 0;
cb->log_send_errors = WG_DEFAULT_LOG_SEND_ERRORS;
cb->prefix = NULL;
cb->postfix = NULL;
status = -1;
}
}
+ else if (strcasecmp ("ReconnectInterval", child->key) == 0)
+ cf_util_get_cdtime (child, &cb->reconnect_interval);
else if (strcasecmp ("LogSendErrors", child->key) == 0)
cf_util_get_boolean (child, &cb->log_send_errors);
else if (strcasecmp ("Prefix", child->key) == 0)
/* FIXME: Legacy configuration syntax. */
if (cb->name == NULL)
ssnprintf (callback_name, sizeof (callback_name), "write_graphite/%s/%s/%s",
- cb->node != NULL ? cb->node : WG_DEFAULT_NODE,
- cb->service != NULL ? cb->service : WG_DEFAULT_SERVICE,
- cb->protocol != NULL ? cb->protocol : WG_DEFAULT_PROTOCOL);
+ cb->node, cb->service, cb->protocol);
else
ssnprintf (callback_name, sizeof (callback_name), "write_graphite/%s",
cb->name);
char *clientkeypass;
long sslversion;
_Bool store_rates;
+ _Bool log_http_error;
int low_speed_limit;
time_t low_speed_time;
int timeout;
};
typedef struct wh_callback_s wh_callback_t;
+static void wh_log_http_error (wh_callback_t *cb)
+{
+ if (!cb->log_http_error)
+ return;
+
+ long http_code = 0;
+
+ curl_easy_getinfo (cb->curl, CURLINFO_RESPONSE_CODE, &http_code);
+
+ if (http_code != 200)
+ INFO ("write_http plugin: HTTP Error code: %lu", http_code);
+}
+
static void wh_reset_buffer (wh_callback_t *cb) /* {{{ */
{
memset (cb->send_buffer, 0, cb->send_buffer_size);
curl_easy_setopt (cb->curl, CURLOPT_POSTFIELDS, cb->send_buffer);
status = curl_easy_perform (cb->curl);
+
+ wh_log_http_error (cb);
+
if (status != CURLE_OK)
{
ERROR ("write_http plugin: curl_easy_perform failed with "
curl_easy_setopt (cb->curl, CURLOPT_NOSIGNAL, 1L);
curl_easy_setopt (cb->curl, CURLOPT_USERAGENT, COLLECTD_USERAGENT);
- cb->headers = NULL;
cb->headers = curl_slist_append (cb->headers, "Accept: */*");
if (cb->format == WH_FORMAT_JSON)
cb->headers = curl_slist_append (cb->headers, "Content-Type: application/json");
if (cb->pass != NULL)
credentials_size += strlen (cb->pass);
- cb->credentials = (char *) malloc (credentials_size);
+ cb->credentials = malloc (credentials_size);
if (cb->credentials == NULL)
{
ERROR ("curl plugin: malloc failed.");
if (cb->format == WH_FORMAT_COMMAND)
{
- if (cb->send_buffer_fill <= 0)
+ if (cb->send_buffer_fill == 0)
{
cb->send_buffer_init_time = cdtime ();
return (0);
return (0);
} /* }}} int config_set_format */
+static int wh_config_append_string (const char *name, struct curl_slist **dest, /* {{{ */
+ oconfig_item_t *ci)
+{
+ struct curl_slist *temp = NULL;
+ if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING))
+ {
+ WARNING ("write_http plugin: `%s' needs exactly one string argument.", name);
+ return (-1);
+ }
+
+ temp = curl_slist_append(*dest, ci->values[0].value.string);
+ if (temp == NULL)
+ return (-1);
+
+ *dest = temp;
+
+ return (0);
+} /* }}} int wh_config_append_string */
+
static int wh_config_node (oconfig_item_t *ci) /* {{{ */
{
wh_callback_t *cb;
int buffer_size = 0;
user_data_t user_data;
char callback_name[DATA_MAX_NAME_LEN];
+ int status = 0;
int i;
- cb = malloc (sizeof (*cb));
+ cb = calloc (1, sizeof (*cb));
if (cb == NULL)
{
- ERROR ("write_http plugin: malloc failed.");
+ ERROR ("write_http plugin: calloc failed.");
return (-1);
}
- memset (cb, 0, sizeof (*cb));
cb->verify_peer = 1;
cb->verify_host = 1;
cb->format = WH_FORMAT_COMMAND;
cb->sslversion = CURL_SSLVERSION_DEFAULT;
cb->low_speed_limit = 0;
cb->timeout = 0;
+ cb->log_http_error = 0;
cb->headers = NULL;
+
pthread_mutex_init (&cb->send_lock, /* attr = */ NULL);
cf_util_get_string (ci, &cb->name);
oconfig_item_t *child = ci->children + i;
if (strcasecmp ("URL", child->key) == 0)
- cf_util_get_string (child, &cb->location);
+ status = cf_util_get_string (child, &cb->location);
else if (strcasecmp ("User", child->key) == 0)
- cf_util_get_string (child, &cb->user);
+ status = cf_util_get_string (child, &cb->user);
else if (strcasecmp ("Password", child->key) == 0)
- cf_util_get_string (child, &cb->pass);
+ status = cf_util_get_string (child, &cb->pass);
else if (strcasecmp ("VerifyPeer", child->key) == 0)
- cf_util_get_boolean (child, &cb->verify_peer);
+ status = cf_util_get_boolean (child, &cb->verify_peer);
else if (strcasecmp ("VerifyHost", child->key) == 0)
- cf_util_get_boolean (child, &cb->verify_host);
+ status = cf_util_get_boolean (child, &cb->verify_host);
else if (strcasecmp ("CACert", child->key) == 0)
- cf_util_get_string (child, &cb->cacert);
+ status = cf_util_get_string (child, &cb->cacert);
else if (strcasecmp ("CAPath", child->key) == 0)
- cf_util_get_string (child, &cb->capath);
+ status = cf_util_get_string (child, &cb->capath);
else if (strcasecmp ("ClientKey", child->key) == 0)
- cf_util_get_string (child, &cb->clientkey);
+ status = cf_util_get_string (child, &cb->clientkey);
else if (strcasecmp ("ClientCert", child->key) == 0)
- cf_util_get_string (child, &cb->clientcert);
+ status = cf_util_get_string (child, &cb->clientcert);
else if (strcasecmp ("ClientKeyPass", child->key) == 0)
- cf_util_get_string (child, &cb->clientkeypass);
+ status = cf_util_get_string (child, &cb->clientkeypass);
else if (strcasecmp ("SSLVersion", child->key) == 0)
{
char *value = NULL;
- cf_util_get_string (child, &value);
+ status = cf_util_get_string (child, &value);
+ if (status != 0)
+ break;
if (value == NULL || strcasecmp ("default", value) == 0)
cb->sslversion = CURL_SSLVERSION_DEFAULT;
cb->sslversion = CURL_SSLVERSION_TLSv1_2;
#endif
else
+ {
ERROR ("write_http plugin: Invalid SSLVersion "
"option: %s.", value);
+ status = EINVAL;
+ }
sfree(value);
}
else if (strcasecmp ("Format", child->key) == 0)
- config_set_format (cb, child);
+ status = config_set_format (cb, child);
else if (strcasecmp ("StoreRates", child->key) == 0)
- cf_util_get_boolean (child, &cb->store_rates);
+ status = cf_util_get_boolean (child, &cb->store_rates);
else if (strcasecmp ("BufferSize", child->key) == 0)
- cf_util_get_int (child, &buffer_size);
+ status = cf_util_get_int (child, &buffer_size);
else if (strcasecmp ("LowSpeedLimit", child->key) == 0)
- cf_util_get_int (child, &cb->low_speed_limit);
+ status = cf_util_get_int (child, &cb->low_speed_limit);
else if (strcasecmp ("Timeout", child->key) == 0)
- cf_util_get_int (child, &cb->timeout);
+ status = cf_util_get_int (child, &cb->timeout);
+ else if (strcasecmp ("LogHttpError", child->key) == 0)
+ status = cf_util_get_boolean (child, &cb->log_http_error);
+ else if (strcasecmp ("Header", child->key) == 0)
+ status = wh_config_append_string ("Header", &cb->headers, child);
else
{
ERROR ("write_http plugin: Invalid configuration "
"option: %s.", child->key);
+ status = EINVAL;
}
+
+ if (status != 0)
+ break;
+ }
+
+ if (status != 0)
+ {
+ wh_callback_free (cb);
+ return (status);
}
if (cb->location == NULL)
#define KAFKA_FORMAT_JSON 0
#define KAFKA_FORMAT_COMMAND 1
#define KAFKA_FORMAT_GRAPHITE 2
- uint8_t format;
+ uint8_t format;
unsigned int graphite_flags;
_Bool store_rates;
rd_kafka_topic_conf_t *conf;
rd_kafka_topic_t *topic;
rd_kafka_conf_t *kafka_conf;
rd_kafka_t *kafka;
- int has_key;
- uint32_t key;
+ char *key;
char *prefix;
char *postfix;
char escape_char;
char *topic_name;
- pthread_mutex_t lock;
+ pthread_mutex_t lock;
};
static int kafka_handle(struct kafka_topic_context *);
{
uint32_t key = *((uint32_t *)keydata );
uint32_t target = key % partition_cnt;
- int32_t i = partition_cnt;
+ int32_t i = partition_cnt;
while (--i > 0 && !rd_kafka_topic_partition_available(rkt, target)) {
target = (target + 1) % partition_cnt;
if ((ctx->kafka = rd_kafka_new(RD_KAFKA_PRODUCER, conf,
errbuf, sizeof(errbuf))) == NULL) {
- ERROR("write_kafka plugin: cannot create kafka handle.");
- return 1;
+ ERROR("write_kafka plugin: cannot create kafka handle.");
+ return 1;
}
- rd_kafka_conf_destroy(ctx->kafka_conf);
- ctx->kafka_conf = NULL;
+ rd_kafka_conf_destroy(ctx->kafka_conf);
+ ctx->kafka_conf = NULL;
- INFO ("write_kafka plugin: created KAFKA handle : %s", rd_kafka_name(ctx->kafka));
+ INFO ("write_kafka plugin: created KAFKA handle : %s", rd_kafka_name(ctx->kafka));
-#ifdef HAVE_LIBRDKAFKA_LOGGER
- rd_kafka_set_logger(ctx->kafka, kafka_log);
+#if defined(HAVE_LIBRDKAFKA_LOGGER) && !defined(HAVE_LIBRDKAFKA_LOG_CB)
+ rd_kafka_set_logger(ctx->kafka, kafka_log);
#endif
}
if (ctx->topic == NULL ) {
- if ((topic_conf = rd_kafka_topic_conf_dup(ctx->conf)) == NULL) {
+ if ((topic_conf = rd_kafka_topic_conf_dup(ctx->conf)) == NULL) {
ERROR("write_kafka plugin: cannot duplicate kafka topic config");
return 1;
- }
+ }
- if ((ctx->topic = rd_kafka_topic_new(ctx->kafka, ctx->topic_name,
- topic_conf)) == NULL) {
- ERROR("write_kafka plugin: cannot create topic : %s\n",
- rd_kafka_err2str(rd_kafka_errno2err(errno)));
- return errno;
- }
+ if ((ctx->topic = rd_kafka_topic_new(ctx->kafka, ctx->topic_name,
+ topic_conf)) == NULL) {
+ ERROR("write_kafka plugin: cannot create topic : %s\n",
+ rd_kafka_err2str(rd_kafka_errno2err(errno)));
+ return errno;
+ }
- rd_kafka_topic_conf_destroy(ctx->conf);
- ctx->conf = NULL;
+ rd_kafka_topic_conf_destroy(ctx->conf);
+ ctx->conf = NULL;
- INFO ("write_kafka plugin: handle created for topic : %s", rd_kafka_topic_name(ctx->topic));
+ INFO ("write_kafka plugin: handle created for topic : %s", rd_kafka_topic_name(ctx->topic));
}
return(0);
} /* }}} int kafka_handle */
static int kafka_write(const data_set_t *ds, /* {{{ */
- const value_list_t *vl,
- user_data_t *ud)
+ const value_list_t *vl,
+ user_data_t *ud)
{
- int status = 0;
- uint32_t key;
- char buffer[8192];
- size_t bfree = sizeof(buffer);
- size_t bfill = 0;
- size_t blen = 0;
- struct kafka_topic_context *ctx = ud->data;
+ int status = 0;
+ void *key;
+ size_t keylen = 0;
+ char buffer[8192];
+ size_t bfree = sizeof(buffer);
+ size_t bfill = 0;
+ size_t blen = 0;
+ struct kafka_topic_context *ctx = ud->data;
if ((ds == NULL) || (vl == NULL) || (ctx == NULL))
return EINVAL;
blen = strlen(buffer);
break;
case KAFKA_FORMAT_JSON:
-
format_json_initialize(buffer, &bfill, &bfree);
format_json_value_list(buffer, &bfill, &bfree, ds, vl,
ctx->store_rates);
return -1;
}
- /*
- * We partition our stream by metric name
- */
- if (ctx->has_key)
- key = ctx->key;
+ key = ctx->key;
+ if (key != NULL)
+ keylen = strlen (key);
else
- key = rand();
+ keylen = 0;
rd_kafka_produce(ctx->topic, RD_KAFKA_PARTITION_UA,
RD_KAFKA_MSG_F_COPY, buffer, blen,
- &key, sizeof(key), NULL);
+ key, keylen, NULL);
- return status;
+ return status;
} /* }}} int kafka_write */
static void kafka_topic_context_free(void *p) /* {{{ */
{
- struct kafka_topic_context *ctx = p;
+ struct kafka_topic_context *ctx = p;
- if (ctx == NULL)
- return;
+ if (ctx == NULL)
+ return;
if (ctx->topic_name != NULL)
sfree(ctx->topic_name);
char callback_name[DATA_MAX_NAME_LEN];
char errbuf[1024];
user_data_t ud;
- oconfig_item_t *child;
+ oconfig_item_t *child;
rd_kafka_conf_res_t ret;
- if ((tctx = calloc(1, sizeof (*tctx))) == NULL) {
- ERROR ("write_kafka plugin: calloc failed.");
+ if ((tctx = calloc(1, sizeof (*tctx))) == NULL) {
+ ERROR ("write_kafka plugin: calloc failed.");
return;
- }
+ }
tctx->escape_char = '.';
tctx->store_rates = 1;
tctx->format = KAFKA_FORMAT_JSON;
+ tctx->key = NULL;
if ((tctx->kafka_conf = rd_kafka_conf_dup(conf)) == NULL) {
sfree(tctx);
goto errout;
}
- for (i = 0; i < ci->children_num; i++) {
- /*
- * The code here could be simplified but makes room
- * for easy adding of new options later on.
- */
- child = &ci->children[i];
- status = 0;
-
- if (strcasecmp ("Property", child->key) == 0) {
- if (child->values_num != 2) {
- WARNING("kafka properties need both a key and a value.");
+ for (i = 0; i < ci->children_num; i++) {
+ /*
+ * The code here could be simplified but makes room
+ * for easy adding of new options later on.
+ */
+ child = &ci->children[i];
+ status = 0;
+
+ if (strcasecmp ("Property", child->key) == 0) {
+ if (child->values_num != 2) {
+ WARNING("kafka properties need both a key and a value.");
goto errout;
- }
- if (child->values[0].type != OCONFIG_TYPE_STRING ||
- child->values[1].type != OCONFIG_TYPE_STRING) {
- WARNING("kafka properties needs string arguments.");
+ }
+ if (child->values[0].type != OCONFIG_TYPE_STRING ||
+ child->values[1].type != OCONFIG_TYPE_STRING) {
+ WARNING("kafka properties needs string arguments.");
goto errout;
- }
+ }
key = child->values[0].value.string;
val = child->values[1].value.string;
ret = rd_kafka_topic_conf_set(tctx->conf,key, val,
errbuf, sizeof(errbuf));
if (ret != RD_KAFKA_CONF_OK) {
- WARNING("cannot set kafka topic property %s to %s: %s.",
+ WARNING("cannot set kafka topic property %s to %s: %s.",
key, val, errbuf);
goto errout;
- }
-
- } else if (strcasecmp ("Key", child->key) == 0) {
- char *tmp_buf = NULL;
- status = cf_util_get_string(child, &tmp_buf);
- if (status != 0) {
- WARNING("write_kafka plugin: invalid key supplied");
- break;
- }
-
- if (strcasecmp(tmp_buf, "Random") != 0) {
- tctx->has_key = 1;
- tctx->key = crc32_buffer((u_char *)tmp_buf, strlen(tmp_buf));
}
- sfree(tmp_buf);
+ } else if (strcasecmp ("Key", child->key) == 0) {
+ cf_util_get_string (child, &tctx->key);
+ assert (tctx->key != NULL);
} else if (strcasecmp ("Format", child->key) == 0) {
status = cf_util_get_string(child, &key);
if (status != 0)
ud.data = tctx;
ud.free_func = kafka_topic_context_free;
- status = plugin_register_write (callback_name, kafka_write, &ud);
- if (status != 0) {
- WARNING ("write_kafka plugin: plugin_register_write (\"%s\") "
- "failed with status %i.",
- callback_name, status);
+ status = plugin_register_write (callback_name, kafka_write, &ud);
+ if (status != 0) {
+ WARNING ("write_kafka plugin: plugin_register_write (\"%s\") "
+ "failed with status %i.",
+ callback_name, status);
goto errout;
}
if (tctx->conf != NULL)
rd_kafka_topic_conf_destroy(tctx->conf);
if (tctx->kafka_conf != NULL)
- rd_kafka_conf_destroy(tctx->kafka_conf);
+ rd_kafka_conf_destroy(tctx->kafka_conf);
sfree(tctx);
} /* }}} int kafka_config_topic */
static int kafka_config(oconfig_item_t *ci) /* {{{ */
{
- int i;
- oconfig_item_t *child;
+ int i;
+ oconfig_item_t *child;
rd_kafka_conf_t *conf;
rd_kafka_conf_res_t ret;
char errbuf[1024];
WARNING("cannot allocate kafka configuration.");
return -1;
}
- for (i = 0; i < ci->children_num; i++) {
- child = &ci->children[i];
+ for (i = 0; i < ci->children_num; i++) {
+ child = &ci->children[i];
- if (strcasecmp("Topic", child->key) == 0) {
- kafka_config_topic (conf, child);
- } else if (strcasecmp(child->key, "Property") == 0) {
- char *key = NULL;
- char *val = NULL;
+ if (strcasecmp("Topic", child->key) == 0) {
+ kafka_config_topic (conf, child);
+ } else if (strcasecmp(child->key, "Property") == 0) {
+ char *key = NULL;
+ char *val = NULL;
- if (child->values_num != 2) {
- WARNING("kafka properties need both a key and a value.");
+ if (child->values_num != 2) {
+ WARNING("kafka properties need both a key and a value.");
goto errout;
- }
- if (child->values[0].type != OCONFIG_TYPE_STRING ||
- child->values[1].type != OCONFIG_TYPE_STRING) {
- WARNING("kafka properties needs string arguments.");
+ }
+ if (child->values[0].type != OCONFIG_TYPE_STRING ||
+ child->values[1].type != OCONFIG_TYPE_STRING) {
+ WARNING("kafka properties needs string arguments.");
goto errout;
- }
- if ((key = strdup(child->values[0].value.string)) == NULL) {
- WARNING("cannot allocate memory for attribute key.");
+ }
+ if ((key = strdup(child->values[0].value.string)) == NULL) {
+ WARNING("cannot allocate memory for attribute key.");
goto errout;
- }
- if ((val = strdup(child->values[1].value.string)) == NULL) {
- WARNING("cannot allocate memory for attribute value.");
+ }
+ if ((val = strdup(child->values[1].value.string)) == NULL) {
+ WARNING("cannot allocate memory for attribute value.");
+ sfree(key);
goto errout;
- }
+ }
ret = rd_kafka_conf_set(conf, key, val, errbuf, sizeof(errbuf));
if (ret != RD_KAFKA_CONF_OK) {
WARNING("cannot set kafka property %s to %s: %s",
key, val, errbuf);
+ sfree(key);
+ sfree(val);
goto errout;
}
- sfree(key);
- sfree(val);
- } else {
- WARNING ("write_kafka plugin: Ignoring unknown "
- "configuration option \"%s\" at top level.",
- child->key);
- }
- }
+ sfree(key);
+ sfree(val);
+ } else {
+ WARNING ("write_kafka plugin: Ignoring unknown "
+ "configuration option \"%s\" at top level.",
+ child->key);
+ }
+ }
if (conf != NULL)
rd_kafka_conf_destroy(conf);
- return (0);
+ return (0);
errout:
if (conf != NULL)
rd_kafka_conf_destroy(conf);
void module_register(void)
{
- plugin_register_complex_config ("write_kafka", kafka_config);
+ plugin_register_complex_config ("write_kafka", kafka_config);
}
-
-/* vim: set sw=8 sts=8 ts=8 noet : */
/* Folks without pthread will need to disable this plugin. */
#include <pthread.h>
-#include <sys/socket.h>
#include <netdb.h>
#define WL_BUF_SIZE 8192
int status;
int i;
- node = malloc (sizeof (*node));
+ node = calloc (1, sizeof (*node));
if (node == NULL)
return (ENOMEM);
- memset (node, 0, sizeof (*node));
mongo_init (node->conn);
node->host = NULL;
node->store_rates = 1;
/**
* collectd - src/write_redis.c
- * Copyright (C) 2010 Florian Forster
+ * Copyright (C) 2010-2015 Florian Forster
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
#include <sys/time.h>
#include <hiredis/hiredis.h>
+#ifndef REDIS_DEFAULT_PREFIX
+# define REDIS_DEFAULT_PREFIX "collectd/"
+#endif
+
struct wr_node_s
{
char name[DATA_MAX_NAME_LEN];
char *host;
int port;
struct timeval timeout;
+ char *prefix;
+ int database;
+ int max_set_size;
+ _Bool store_rates;
redisContext *conn;
pthread_mutex_t lock;
status = FORMAT_VL (ident, sizeof (ident), vl);
if (status != 0)
return (status);
- ssnprintf (key, sizeof (key), "collectd/%s", ident);
+ ssnprintf (key, sizeof (key), "%s%s",
+ (node->prefix != NULL) ? node->prefix : REDIS_DEFAULT_PREFIX,
+ ident);
ssnprintf (time, sizeof (time), "%.9f", CDTIME_T_TO_DOUBLE(vl->time));
memset (value, 0, sizeof (value));
value_size = sizeof (value);
value_ptr = &value[0];
- status = format_values (value_ptr, value_size, ds, vl, /* store rates = */ 0);
+ status = format_values (value_ptr, value_size, ds, vl, node->store_rates);
if (status != 0)
return (status);
pthread_mutex_unlock (&node->lock);
return (-1);
}
+
+ rr = redisCommand(node->conn, "SELECT %d", node->database);
+ if (rr == NULL)
+ WARNING("SELECT command error. database:%d message:%s", node->database, node->conn->errstr);
+ else
+ freeReplyObject (rr);
}
rr = redisCommand (node->conn, "ZADD %s %s %s", key, time, value);
else
freeReplyObject (rr);
+ if (node->max_set_size >= 0)
+ {
+ rr = redisCommand (node->conn, "ZREMRANGEBYRANK %s %d %d", key, 0, (-1 * node->max_set_size) - 1);
+ if (rr == NULL)
+ WARNING("ZREMRANGEBYRANK command error. key:%s message:%s", key, node->conn->errstr);
+ else
+ freeReplyObject (rr);
+ }
+
/* TODO(octo): This is more overhead than necessary. Use the cache and
* metadata to determine if it is a new metric and call SADD only once for
* each metric. */
- rr = redisCommand (node->conn, "SADD collectd/values %s", ident);
+ rr = redisCommand (node->conn, "SADD %svalues %s",
+ (node->prefix != NULL) ? node->prefix : REDIS_DEFAULT_PREFIX,
+ ident);
if (rr==NULL)
WARNING("SADD command error. ident:%s message:%s", ident, node->conn->errstr);
else
int status;
int i;
- node = malloc (sizeof (*node));
+ node = calloc (1, sizeof (*node));
if (node == NULL)
return (ENOMEM);
- memset (node, 0, sizeof (*node));
node->host = NULL;
node->port = 0;
node->timeout.tv_sec = 0;
node->timeout.tv_usec = 1000;
node->conn = NULL;
+ node->prefix = NULL;
+ node->database = 0;
+ node->max_set_size = -1;
+ node->store_rates = 1;
pthread_mutex_init (&node->lock, /* attr = */ NULL);
status = cf_util_get_string_buffer (ci, node->name, sizeof (node->name));
status = cf_util_get_int (child, &timeout);
if (status == 0) node->timeout.tv_usec = timeout;
}
+ else if (strcasecmp ("Prefix", child->key) == 0) {
+ status = cf_util_get_string (child, &node->prefix);
+ }
+ else if (strcasecmp ("Database", child->key) == 0) {
+ status = cf_util_get_int (child, &node->database);
+ }
+ else if (strcasecmp ("MaxSetSize", child->key) == 0) {
+ status = cf_util_get_int (child, &node->max_set_size);
+ }
+ else if (strcasecmp ("StoreRates", child->key) == 0) {
+ status = cf_util_get_boolean (child, &node->store_rates);
+ }
else
WARNING ("write_redis plugin: Ignoring unknown config option \"%s\".",
child->key);
* collectd - src/write_riemann.c
* Copyright (C) 2012,2013 Pierre-Yves Ritschard
* Copyright (C) 2013 Florian octo Forster
+ * Copyright (C) 2015,2016 Gergely Nagy
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* Authors:
* Pierre-Yves Ritschard <pyr at spootnik.org>
* Florian octo Forster <octo at collectd.org>
+ * Gergely Nagy <algernon at madhouse-project.org>
*/
-#include <sys/socket.h>
-#include <arpa/inet.h>
+#include <riemann/riemann-client.h>
#include <errno.h>
-#include <netdb.h>
-#include <inttypes.h>
#include <pthread.h>
#include "collectd.h"
#include "common.h"
#include "configfile.h"
#include "utils_cache.h"
-#include "riemann.pb-c.h"
+#include "utils_complain.h"
#include "write_riemann_threshold.h"
#define RIEMANN_HOST "localhost"
-#define RIEMANN_PORT "5555"
+#define RIEMANN_PORT 5555
#define RIEMANN_TTL_FACTOR 2.0
#define RIEMANN_BATCH_MAX 8192
struct riemann_host {
+ c_complain_t init_complaint;
char *name;
char *event_service_prefix;
-#define F_CONNECT 0x01
- uint8_t flags;
pthread_mutex_t lock;
_Bool batch_mode;
_Bool notifications;
_Bool store_rates;
_Bool always_append_ds;
char *node;
- char *service;
- _Bool use_tcp;
- int s;
+ int port;
+ riemann_client_type_t client_type;
+ riemann_client_t *client;
double ttl_factor;
- Msg *batch_msg;
cdtime_t batch_init;
int batch_max;
+ int batch_timeout;
int reference_count;
+ riemann_message_t *batch_msg;
+ char *tls_ca_file;
+ char *tls_cert_file;
+ char *tls_key_file;
+ struct timeval timeout;
};
static char **riemann_tags;
static char **riemann_attrs;
static size_t riemann_attrs_num;
-static void riemann_event_protobuf_free (Event *event) /* {{{ */
-{
- size_t i;
-
- if (event == NULL)
- return;
-
- sfree (event->state);
- sfree (event->service);
- sfree (event->host);
- sfree (event->description);
-
- strarray_free (event->tags, event->n_tags);
- event->tags = NULL;
- event->n_tags = 0;
-
- for (i = 0; i < event->n_attributes; i++)
- {
- sfree (event->attributes[i]->key);
- sfree (event->attributes[i]->value);
- sfree (event->attributes[i]);
- }
- sfree (event->attributes);
- event->n_attributes = 0;
-
- sfree (event);
-} /* }}} void riemann_event_protobuf_free */
-
-static void riemann_msg_protobuf_free(Msg *msg) /* {{{ */
-{
- size_t i;
-
- if (msg == NULL)
- return;
-
- for (i = 0; i < msg->n_events; i++)
- {
- riemann_event_protobuf_free (msg->events[i]);
- msg->events[i] = NULL;
- }
-
- sfree (msg->events);
- msg->n_events = 0;
-
- sfree (msg);
-} /* }}} void riemann_msg_protobuf_free */
-
/* host->lock must be held when calling this function. */
-static int riemann_connect(struct riemann_host *host) /* {{{ */
+static int wrr_connect(struct riemann_host *host) /* {{{ */
{
- int e;
- struct addrinfo *ai, *res, hints;
char const *node;
- char const *service;
+ int port;
- if (host->flags & F_CONNECT)
+ if (host->client)
return 0;
- memset(&hints, 0, sizeof(hints));
- memset(&service, 0, sizeof(service));
- hints.ai_family = AF_UNSPEC;
- hints.ai_socktype = host->use_tcp ? SOCK_STREAM : SOCK_DGRAM;
-#ifdef AI_ADDRCONFIG
- hints.ai_flags |= AI_ADDRCONFIG;
-#endif
-
node = (host->node != NULL) ? host->node : RIEMANN_HOST;
- service = (host->service != NULL) ? host->service : RIEMANN_PORT;
-
- if ((e = getaddrinfo(node, service, &hints, &res)) != 0) {
- ERROR ("write_riemann plugin: Unable to resolve host \"%s\": %s",
- node, gai_strerror(e));
+ port = (host->port) ? host->port : RIEMANN_PORT;
+
+ host->client = NULL;
+
+ host->client = riemann_client_create(host->client_type, node, port,
+ RIEMANN_CLIENT_OPTION_TLS_CA_FILE, host->tls_ca_file,
+ RIEMANN_CLIENT_OPTION_TLS_CERT_FILE, host->tls_cert_file,
+ RIEMANN_CLIENT_OPTION_TLS_KEY_FILE, host->tls_key_file,
+ RIEMANN_CLIENT_OPTION_NONE);
+ if (host->client == NULL) {
+ c_complain (LOG_ERR, &host->init_complaint,
+ "write_riemann plugin: Unable to connect to Riemann at %s:%d",
+ node, port);
return -1;
}
-
- host->s = -1;
- for (ai = res; ai != NULL; ai = ai->ai_next) {
- if ((host->s = socket(ai->ai_family,
- ai->ai_socktype,
- ai->ai_protocol)) == -1) {
- continue;
+ if (host->timeout.tv_sec != 0) {
+ if (riemann_client_set_timeout(host->client, &host->timeout) != 0) {
+ riemann_client_free(host->client);
+ host->client = NULL;
+ c_complain (LOG_ERR, &host->init_complaint,
+ "write_riemann plugin: Unable to connect to Riemann at %s:%d",
+ node, port);
+ return -1;
}
-
- if (connect(host->s, ai->ai_addr, ai->ai_addrlen) != 0) {
- close(host->s);
- host->s = -1;
- continue;
- }
-
- host->flags |= F_CONNECT;
- DEBUG("write_riemann plugin: got a successful connection for: %s:%s",
- node, service);
- break;
}
- freeaddrinfo(res);
+ c_release (LOG_INFO, &host->init_complaint,
+ "write_riemann plugin: Successfully connected to %s:%d",
+ node, port);
- if (host->s < 0) {
- WARNING("write_riemann plugin: Unable to connect to Riemann at %s:%s",
- node, service);
- return -1;
- }
return 0;
-} /* }}} int riemann_connect */
+} /* }}} int wrr_connect */
/* host->lock must be held when calling this function. */
-static int riemann_disconnect (struct riemann_host *host) /* {{{ */
+static int wrr_disconnect(struct riemann_host *host) /* {{{ */
{
- if ((host->flags & F_CONNECT) == 0)
+ if (!host->client)
return (0);
- close (host->s);
- host->s = -1;
- host->flags &= ~F_CONNECT;
+ riemann_client_free(host->client);
+ host->client = NULL;
return (0);
-} /* }}} int riemann_disconnect */
-
-static int riemann_send_msg (struct riemann_host *host, const Msg *msg) /* {{{ */
-{
- int status = 0;
- u_char *buffer = NULL;
- size_t buffer_len;
-
- status = riemann_connect (host);
- if (status != 0)
- return status;
-
- buffer_len = msg__get_packed_size(msg);
-
- if (host->use_tcp)
- buffer_len += 4;
-
- buffer = malloc (buffer_len);
- if (buffer == NULL) {
- ERROR ("write_riemann plugin: malloc failed.");
- return ENOMEM;
- }
- memset (buffer, 0, buffer_len);
-
- if (host->use_tcp)
- {
- uint32_t length = htonl ((uint32_t) (buffer_len - 4));
- memcpy (buffer, &length, 4);
- msg__pack(msg, buffer + 4);
- }
- else
- {
- msg__pack(msg, buffer);
- }
-
- status = (int) swrite (host->s, buffer, buffer_len);
- if (status != 0)
- {
- char errbuf[1024];
- ERROR ("write_riemann plugin: Sending to Riemann at %s:%s failed: %s",
- (host->node != NULL) ? host->node : RIEMANN_HOST,
- (host->service != NULL) ? host->service : RIEMANN_PORT,
- sstrerror (errno, errbuf, sizeof (errbuf)));
- sfree (buffer);
- return -1;
- }
-
- sfree (buffer);
- return 0;
-} /* }}} int riemann_send_msg */
-
-static int riemann_recv_ack(struct riemann_host *host) /* {{{ */
-{
- int status = 0;
- Msg *msg = NULL;
- uint32_t header;
-
- status = (int) sread (host->s, &header, 4);
-
- if (status != 0)
- return -1;
-
- size_t size = ntohl(header);
-
- // Buffer on the stack since acknowledges are typically small.
- u_char buffer[size];
- memset (buffer, 0, size);
-
- status = (int) sread (host->s, buffer, size);
-
- if (status != 0)
- return status;
-
- msg = msg__unpack (NULL, size, buffer);
-
- if (msg == NULL)
- return -1;
-
- if (!msg->ok)
- {
- ERROR ("write_riemann plugin: Sending to Riemann at %s:%s acknowledgement message reported error: %s",
- (host->node != NULL) ? host->node : RIEMANN_HOST,
- (host->service != NULL) ? host->service : RIEMANN_PORT,
- msg->error);
-
- msg__free_unpacked(msg, NULL);
- return -1;
- }
-
- msg__free_unpacked (msg, NULL);
- return 0;
-} /* }}} int riemann_recv_ack */
+} /* }}} int wrr_disconnect */
/**
- * Function to send messages (Msg) to riemann.
+ * Function to send messages to riemann.
*
* Acquires the host lock, disconnects on errors.
*/
-static int riemann_send(struct riemann_host *host, Msg const *msg) /* {{{ */
+static int wrr_send_nolock(struct riemann_host *host, riemann_message_t *msg) /* {{{ */
{
int status = 0;
- pthread_mutex_lock (&host->lock);
- status = riemann_send_msg(host, msg);
+ status = wrr_connect(host);
+ if (status != 0) {
+ return status;
+ }
+
+ status = riemann_client_send_message(host->client, msg);
if (status != 0) {
- riemann_disconnect (host);
- pthread_mutex_unlock (&host->lock);
+ wrr_disconnect(host);
return status;
}
/*
* For TCP we need to receive message acknowledgemenent.
*/
- if (host->use_tcp)
+ if (host->client_type != RIEMANN_CLIENT_UDP)
{
- status = riemann_recv_ack(host);
+ riemann_message_t *response;
+
+ response = riemann_client_recv_message(host->client);
- if (status != 0)
+ if (response == NULL)
{
- riemann_disconnect (host);
- pthread_mutex_unlock (&host->lock);
- return status;
+ wrr_disconnect(host);
+ return errno;
}
+ riemann_message_free(response);
}
- pthread_mutex_unlock (&host->lock);
return 0;
-} /* }}} int riemann_send */
-
-static int riemann_event_add_tag (Event *event, char const *tag) /* {{{ */
-{
- return (strarray_add (&event->tags, &event->n_tags, tag));
-} /* }}} int riemann_event_add_tag */
+} /* }}} int wrr_send */
-static int riemann_event_add_attribute(Event *event, /* {{{ */
- char const *key, char const *value)
+static int wrr_send(struct riemann_host *host, riemann_message_t *msg)
{
- Attribute **new_attributes;
- Attribute *a;
+ int status = 0;
- new_attributes = realloc (event->attributes,
- sizeof (*event->attributes) * (event->n_attributes + 1));
- if (new_attributes == NULL)
- {
- ERROR ("write_riemann plugin: realloc failed.");
- return (ENOMEM);
- }
- event->attributes = new_attributes;
-
- a = malloc (sizeof (*a));
- if (a == NULL)
- {
- ERROR ("write_riemann plugin: malloc failed.");
- return (ENOMEM);
- }
- attribute__init (a);
-
- a->key = strdup (key);
- if (value != NULL)
- a->value = strdup (value);
-
- event->attributes[event->n_attributes] = a;
- event->n_attributes++;
-
- return (0);
-} /* }}} int riemann_event_add_attribute */
+ pthread_mutex_lock (&host->lock);
+ status = wrr_send_nolock(host, msg);
+ pthread_mutex_unlock (&host->lock);
+ return status;
+}
-static Msg *riemann_notification_to_protobuf(struct riemann_host *host, /* {{{ */
+static riemann_message_t *wrr_notification_to_message(struct riemann_host *host, /* {{{ */
notification_t const *n)
{
- Msg *msg;
- Event *event;
+ riemann_message_t *msg;
+ riemann_event_t *event;
char service_buffer[6 * DATA_MAX_NAME_LEN];
char const *severity;
notification_meta_t *meta;
- int i;
-
- msg = malloc (sizeof (*msg));
- if (msg == NULL)
- {
- ERROR ("write_riemann plugin: malloc failed.");
- return (NULL);
- }
- memset (msg, 0, sizeof (*msg));
- msg__init (msg);
-
- msg->events = malloc (sizeof (*msg->events));
- if (msg->events == NULL)
- {
- ERROR ("write_riemann plugin: malloc failed.");
- sfree (msg);
- return (NULL);
- }
-
- event = malloc (sizeof (*event));
- if (event == NULL)
- {
- ERROR ("write_riemann plugin: malloc failed.");
- sfree (msg->events);
- sfree (msg);
- return (NULL);
- }
- memset (event, 0, sizeof (*event));
- event__init (event);
-
- msg->events[0] = event;
- msg->n_events = 1;
-
- event->host = strdup (n->host);
- event->time = CDTIME_T_TO_TIME_T (n->time);
- event->has_time = 1;
+ size_t i;
switch (n->severity)
{
case NOTIF_FAILURE: severity = "critical"; break;
default: severity = "unknown";
}
- event->state = strdup (severity);
- riemann_event_add_tag (event, "notification");
+ format_name(service_buffer, sizeof(service_buffer),
+ /* host = */ "", n->plugin, n->plugin_instance,
+ n->type, n->type_instance);
+
+ event = riemann_event_create(RIEMANN_EVENT_FIELD_HOST, n->host,
+ RIEMANN_EVENT_FIELD_TIME, (int64_t) CDTIME_T_TO_TIME_T(n->time),
+ RIEMANN_EVENT_FIELD_TAGS, "notification", NULL,
+ RIEMANN_EVENT_FIELD_STATE, severity,
+ RIEMANN_EVENT_FIELD_SERVICE, &service_buffer[1],
+ RIEMANN_EVENT_FIELD_NONE);
+
if (n->host[0] != 0)
- riemann_event_add_attribute (event, "host", n->host);
+ riemann_event_string_attribute_add(event, "host", n->host);
if (n->plugin[0] != 0)
- riemann_event_add_attribute (event, "plugin", n->plugin);
+ riemann_event_string_attribute_add(event, "plugin", n->plugin);
if (n->plugin_instance[0] != 0)
- riemann_event_add_attribute (event, "plugin_instance",
- n->plugin_instance);
+ riemann_event_string_attribute_add(event, "plugin_instance", n->plugin_instance);
if (n->type[0] != 0)
- riemann_event_add_attribute (event, "type", n->type);
+ riemann_event_string_attribute_add(event, "type", n->type);
if (n->type_instance[0] != 0)
- riemann_event_add_attribute (event, "type_instance",
- n->type_instance);
+ riemann_event_string_attribute_add(event, "type_instance", n->type_instance);
for (i = 0; i < riemann_attrs_num; i += 2)
- riemann_event_add_attribute(event,
- riemann_attrs[i],
- riemann_attrs[i +1]);
+ riemann_event_string_attribute_add(event, riemann_attrs[i], riemann_attrs[i+1]);
for (i = 0; i < riemann_tags_num; i++)
- riemann_event_add_tag (event, riemann_tags[i]);
-
- format_name (service_buffer, sizeof (service_buffer),
- /* host = */ "", n->plugin, n->plugin_instance,
- n->type, n->type_instance);
- event->service = strdup (&service_buffer[1]);
+ riemann_event_tag_add(event, riemann_tags[i]);
if (n->message[0] != 0)
- riemann_event_add_attribute (event, "description", n->message);
+ riemann_event_string_attribute_add(event, "description", n->message);
/* Pull in values from threshold and add extra attributes */
for (meta = n->meta; meta != NULL; meta = meta->next)
{
- if (strcasecmp ("CurrentValue", meta->name) == 0 && meta->type == NM_TYPE_DOUBLE)
+ if (strcasecmp("CurrentValue", meta->name) == 0 && meta->type == NM_TYPE_DOUBLE)
{
- event->metric_d = meta->nm_value.nm_double;
- event->has_metric_d = 1;
+ riemann_event_set(event,
+ RIEMANN_EVENT_FIELD_METRIC_D,
+ (double) meta->nm_value.nm_double,
+ RIEMANN_EVENT_FIELD_NONE);
continue;
}
if (meta->type == NM_TYPE_STRING) {
- riemann_event_add_attribute (event, meta->name, meta->nm_value.nm_string);
+ riemann_event_string_attribute_add(event, meta->name, meta->nm_value.nm_string);
continue;
}
}
- DEBUG ("write_riemann plugin: Successfully created protobuf for notification: "
- "host = \"%s\", service = \"%s\", state = \"%s\"",
- event->host, event->service, event->state);
+ msg = riemann_message_create_with_events(event, NULL);
+ if (msg == NULL)
+ {
+ ERROR("write_riemann plugin: riemann_message_create_with_events() failed.");
+ riemann_event_free (event);
+ return (NULL);
+ }
+
+ DEBUG("write_riemann plugin: Successfully created message for notification: "
+ "host = \"%s\", service = \"%s\", state = \"%s\"",
+ event->host, event->service, event->state);
return (msg);
-} /* }}} Msg *riemann_notification_to_protobuf */
+} /* }}} riemann_message_t *wrr_notification_to_message */
-static Event *riemann_value_to_protobuf(struct riemann_host const *host, /* {{{ */
- data_set_t const *ds,
- value_list_t const *vl, size_t index,
- gauge_t const *rates,
- int status)
+static riemann_event_t *wrr_value_to_event(struct riemann_host const *host, /* {{{ */
+ data_set_t const *ds,
+ value_list_t const *vl, size_t index,
+ gauge_t const *rates,
+ int status)
{
- Event *event;
+ riemann_event_t *event;
char name_buffer[5 * DATA_MAX_NAME_LEN];
char service_buffer[6 * DATA_MAX_NAME_LEN];
- double ttl;
- int i;
+ size_t i;
- event = malloc (sizeof (*event));
+ event = riemann_event_new();
if (event == NULL)
{
- ERROR ("write_riemann plugin: malloc failed.");
+ ERROR("write_riemann plugin: riemann_event_new() failed.");
return (NULL);
}
- memset (event, 0, sizeof (*event));
- event__init (event);
- event->host = strdup (vl->host);
- event->time = CDTIME_T_TO_TIME_T (vl->time);
- event->has_time = 1;
+ format_name(name_buffer, sizeof(name_buffer),
+ /* host = */ "", vl->plugin, vl->plugin_instance,
+ vl->type, vl->type_instance);
+ if (host->always_append_ds || (ds->ds_num > 1))
+ {
+ if (host->event_service_prefix == NULL)
+ ssnprintf(service_buffer, sizeof(service_buffer), "%s/%s",
+ &name_buffer[1], ds->ds[index].name);
+ else
+ ssnprintf(service_buffer, sizeof(service_buffer), "%s%s/%s",
+ host->event_service_prefix, &name_buffer[1], ds->ds[index].name);
+ }
+ else
+ {
+ if (host->event_service_prefix == NULL)
+ sstrncpy(service_buffer, &name_buffer[1], sizeof(service_buffer));
+ else
+ ssnprintf(service_buffer, sizeof(service_buffer), "%s%s",
+ host->event_service_prefix, &name_buffer[1]);
+ }
+
+ riemann_event_set(event,
+ RIEMANN_EVENT_FIELD_HOST, vl->host,
+ RIEMANN_EVENT_FIELD_TIME, (int64_t) CDTIME_T_TO_TIME_T(vl->time),
+ RIEMANN_EVENT_FIELD_TTL, (float) CDTIME_T_TO_DOUBLE(vl->interval) * host->ttl_factor,
+ RIEMANN_EVENT_FIELD_STRING_ATTRIBUTES,
+ "plugin", vl->plugin,
+ "type", vl->type,
+ "ds_name", ds->ds[index].name,
+ NULL,
+ RIEMANN_EVENT_FIELD_SERVICE, service_buffer,
+ RIEMANN_EVENT_FIELD_NONE);
if (host->check_thresholds) {
+ const char *state = NULL;
+
switch (status) {
case STATE_OKAY:
- event->state = strdup("ok");
+ state = "ok";
break;
case STATE_ERROR:
- event->state = strdup("critical");
+ state = "critical";
break;
case STATE_WARNING:
- event->state = strdup("warning");
+ state = "warning";
break;
case STATE_MISSING:
- event->state = strdup("unknown");
+ state = "unknown";
break;
}
+ if (state)
+ riemann_event_set(event, RIEMANN_EVENT_FIELD_STATE, state,
+ RIEMANN_EVENT_FIELD_NONE);
}
- ttl = CDTIME_T_TO_DOUBLE (vl->interval) * host->ttl_factor;
- event->ttl = (float) ttl;
- event->has_ttl = 1;
-
- riemann_event_add_attribute (event, "plugin", vl->plugin);
if (vl->plugin_instance[0] != 0)
- riemann_event_add_attribute (event, "plugin_instance",
- vl->plugin_instance);
-
- riemann_event_add_attribute (event, "type", vl->type);
+ riemann_event_string_attribute_add(event, "plugin_instance", vl->plugin_instance);
if (vl->type_instance[0] != 0)
- riemann_event_add_attribute (event, "type_instance",
- vl->type_instance);
+ riemann_event_string_attribute_add(event, "type_instance", vl->type_instance);
if ((ds->ds[index].type != DS_TYPE_GAUGE) && (rates != NULL))
{
char ds_type[DATA_MAX_NAME_LEN];
- ssnprintf (ds_type, sizeof (ds_type), "%s:rate",
- DS_TYPE_TO_STRING(ds->ds[index].type));
- riemann_event_add_attribute (event, "ds_type", ds_type);
+ ssnprintf(ds_type, sizeof(ds_type), "%s:rate",
+ DS_TYPE_TO_STRING(ds->ds[index].type));
+ riemann_event_string_attribute_add(event, "ds_type", ds_type);
}
else
{
- riemann_event_add_attribute (event, "ds_type",
- DS_TYPE_TO_STRING(ds->ds[index].type));
+ riemann_event_string_attribute_add(event, "ds_type",
+ DS_TYPE_TO_STRING(ds->ds[index].type));
}
- riemann_event_add_attribute (event, "ds_name", ds->ds[index].name);
+
{
char ds_index[DATA_MAX_NAME_LEN];
- ssnprintf (ds_index, sizeof (ds_index), "%zu", index);
- riemann_event_add_attribute (event, "ds_index", ds_index);
+ ssnprintf(ds_index, sizeof(ds_index), "%zu", index);
+ riemann_event_string_attribute_add(event, "ds_index", ds_index);
}
for (i = 0; i < riemann_attrs_num; i += 2)
- riemann_event_add_attribute(event,
- riemann_attrs[i],
- riemann_attrs[i +1]);
+ riemann_event_string_attribute_add(event, riemann_attrs[i], riemann_attrs[i +1]);
for (i = 0; i < riemann_tags_num; i++)
- riemann_event_add_tag (event, riemann_tags[i]);
+ riemann_event_tag_add(event, riemann_tags[i]);
if (ds->ds[index].type == DS_TYPE_GAUGE)
{
- event->has_metric_d = 1;
- event->metric_d = (double) vl->values[index].gauge;
+ riemann_event_set(event,
+ RIEMANN_EVENT_FIELD_METRIC_D,
+ (double) vl->values[index].gauge,
+ RIEMANN_EVENT_FIELD_NONE);
}
else if (rates != NULL)
{
- event->has_metric_d = 1;
- event->metric_d = (double) rates[index];
+ riemann_event_set(event,
+ RIEMANN_EVENT_FIELD_METRIC_D,
+ (double) rates[index],
+ RIEMANN_EVENT_FIELD_NONE);
}
else
{
- event->has_metric_sint64 = 1;
+ int64_t metric;
+
if (ds->ds[index].type == DS_TYPE_DERIVE)
- event->metric_sint64 = (int64_t) vl->values[index].derive;
+ metric = (int64_t) vl->values[index].derive;
else if (ds->ds[index].type == DS_TYPE_ABSOLUTE)
- event->metric_sint64 = (int64_t) vl->values[index].absolute;
+ metric = (int64_t) vl->values[index].absolute;
else
- event->metric_sint64 = (int64_t) vl->values[index].counter;
- }
+ metric = (int64_t) vl->values[index].counter;
- format_name (name_buffer, sizeof (name_buffer),
- /* host = */ "", vl->plugin, vl->plugin_instance,
- vl->type, vl->type_instance);
- if (host->always_append_ds || (ds->ds_num > 1))
- {
- if (host->event_service_prefix == NULL)
- ssnprintf (service_buffer, sizeof (service_buffer), "%s/%s",
- &name_buffer[1], ds->ds[index].name);
- else
- ssnprintf (service_buffer, sizeof (service_buffer), "%s%s/%s",
- host->event_service_prefix, &name_buffer[1], ds->ds[index].name);
+ riemann_event_set(event,
+ RIEMANN_EVENT_FIELD_METRIC_S64,
+ (int64_t) metric,
+ RIEMANN_EVENT_FIELD_NONE);
}
- else
- {
- if (host->event_service_prefix == NULL)
- sstrncpy (service_buffer, &name_buffer[1], sizeof (service_buffer));
- else
- ssnprintf (service_buffer, sizeof (service_buffer), "%s%s",
- host->event_service_prefix, &name_buffer[1]);
- }
-
- event->service = strdup (service_buffer);
- DEBUG ("write_riemann plugin: Successfully created protobuf for metric: "
- "host = \"%s\", service = \"%s\"",
- event->host, event->service);
+ DEBUG("write_riemann plugin: Successfully created message for metric: "
+ "host = \"%s\", service = \"%s\"",
+ event->host, event->service);
return (event);
-} /* }}} Event *riemann_value_to_protobuf */
+} /* }}} riemann_event_t *wrr_value_to_event */
-static Msg *riemann_value_list_to_protobuf (struct riemann_host const *host, /* {{{ */
- data_set_t const *ds,
- value_list_t const *vl,
- int *statuses)
+static riemann_message_t *wrr_value_list_to_message(struct riemann_host const *host, /* {{{ */
+ data_set_t const *ds,
+ value_list_t const *vl,
+ int *statuses)
{
- Msg *msg;
+ riemann_message_t *msg;
size_t i;
gauge_t *rates = NULL;
/* Initialize the Msg structure. */
- msg = malloc (sizeof (*msg));
+ msg = riemann_message_new();
if (msg == NULL)
{
- ERROR ("write_riemann plugin: malloc failed.");
- return (NULL);
- }
- memset (msg, 0, sizeof (*msg));
- msg__init (msg);
-
- /* Set up events. First, the list of pointers. */
- msg->n_events = (size_t) vl->values_len;
- msg->events = calloc (msg->n_events, sizeof (*msg->events));
- if (msg->events == NULL)
- {
- ERROR ("write_riemann plugin: calloc failed.");
- riemann_msg_protobuf_free (msg);
+ ERROR ("write_riemann plugin: riemann_message_new failed.");
return (NULL);
}
if (host->store_rates)
{
- rates = uc_get_rate (ds, vl);
+ rates = uc_get_rate(ds, vl);
if (rates == NULL)
{
- ERROR ("write_riemann plugin: uc_get_rate failed.");
- riemann_msg_protobuf_free (msg);
+ ERROR("write_riemann plugin: uc_get_rate failed.");
+ riemann_message_free(msg);
return (NULL);
}
}
- for (i = 0; i < msg->n_events; i++)
+ for (i = 0; i < vl->values_len; i++)
{
- msg->events[i] = riemann_value_to_protobuf (host, ds, vl,
- (int) i, rates, statuses[i]);
- if (msg->events[i] == NULL)
+ riemann_event_t *event;
+
+ event = wrr_value_to_event(host, ds, vl,
+ (int) i, rates, statuses[i]);
+ if (event == NULL)
{
- riemann_msg_protobuf_free (msg);
- sfree (rates);
+ riemann_message_free(msg);
+ sfree(rates);
return (NULL);
}
+ riemann_message_append_events(msg, event, NULL);
}
- sfree (rates);
+ sfree(rates);
return (msg);
-} /* }}} Msg *riemann_value_list_to_protobuf */
-
+} /* }}} riemann_message_t *wrr_value_list_to_message */
/*
* Always call while holding host->lock !
*/
-static int riemann_batch_flush_nolock (cdtime_t timeout,
- struct riemann_host *host)
+static int wrr_batch_flush_nolock(cdtime_t timeout,
+ struct riemann_host *host)
{
- cdtime_t now;
- int status = 0;
-
- if (timeout > 0) {
- now = cdtime ();
- if ((host->batch_init + timeout) > now)
- return status;
- }
- riemann_send_msg(host, host->batch_msg);
- riemann_msg_protobuf_free(host->batch_msg);
+ cdtime_t now;
+ int status = 0;
- if (host->use_tcp && ((status = riemann_recv_ack(host)) != 0))
- riemann_disconnect (host);
+ now = cdtime();
+ if (timeout > 0) {
+ if ((host->batch_init + timeout) > now) {
+ return status;
+ }
+ }
+ wrr_send_nolock(host, host->batch_msg);
+ riemann_message_free(host->batch_msg);
- host->batch_init = cdtime();
- host->batch_msg = NULL;
- return status;
+ host->batch_init = now;
+ host->batch_msg = NULL;
+ return status;
}
-static int riemann_batch_flush (cdtime_t timeout,
+static int wrr_batch_flush(cdtime_t timeout,
const char *identifier __attribute__((unused)),
user_data_t *user_data)
{
- struct riemann_host *host;
- int status;
+ struct riemann_host *host;
+ int status;
- if (user_data == NULL)
- return (-EINVAL);
+ if (user_data == NULL)
+ return (-EINVAL);
- host = user_data->data;
- pthread_mutex_lock (&host->lock);
- status = riemann_batch_flush_nolock (timeout, host);
- if (status != 0)
- ERROR ("write_riemann plugin: riemann_send failed with status %i",
- status);
+ host = user_data->data;
+ pthread_mutex_lock(&host->lock);
+ status = wrr_batch_flush_nolock(timeout, host);
+ if (status != 0)
+ c_complain (LOG_ERR, &host->init_complaint,
+ "write_riemann plugin: riemann_client_send failed with status %i",
+ status);
+ else
+ c_release (LOG_DEBUG, &host->init_complaint, "write_riemann plugin: batch sent.");
- pthread_mutex_unlock(&host->lock);
- return status;
+ pthread_mutex_unlock(&host->lock);
+ return status;
}
-static int riemann_batch_add_value_list (struct riemann_host *host, /* {{{ */
- data_set_t const *ds,
- value_list_t const *vl,
- int *statuses)
+static int wrr_batch_add_value_list(struct riemann_host *host, /* {{{ */
+ data_set_t const *ds,
+ value_list_t const *vl,
+ int *statuses)
{
- size_t i;
- Event **events;
- Msg *msg;
- size_t len;
- int ret;
+ riemann_message_t *msg;
+ size_t len;
+ int ret;
+ cdtime_t timeout;
- msg = riemann_value_list_to_protobuf (host, ds, vl, statuses);
- if (msg == NULL)
- return -1;
+ msg = wrr_value_list_to_message(host, ds, vl, statuses);
+ if (msg == NULL)
+ return -1;
- pthread_mutex_lock(&host->lock);
+ pthread_mutex_lock(&host->lock);
- if (host->batch_msg == NULL) {
- host->batch_msg = msg;
- } else {
- len = msg->n_events + host->batch_msg->n_events;
- events = realloc(host->batch_msg->events,
- (len * sizeof(*host->batch_msg->events)));
- if (events == NULL) {
- pthread_mutex_unlock(&host->lock);
- ERROR ("write_riemann plugin: out of memory");
- riemann_msg_protobuf_free (msg);
- return -1;
- }
- host->batch_msg->events = events;
+ if (host->batch_msg == NULL) {
+ host->batch_msg = msg;
+ } else {
+ int status;
- for (i = host->batch_msg->n_events; i < len; i++)
- host->batch_msg->events[i] = msg->events[i - host->batch_msg->n_events];
+ status = riemann_message_append_events_n(host->batch_msg,
+ msg->n_events,
+ msg->events);
+ msg->n_events = 0;
+ msg->events = NULL;
- host->batch_msg->n_events = len;
- sfree (msg->events);
- msg->n_events = 0;
- sfree (msg);
- }
+ riemann_message_free(msg);
- len = msg__get_packed_size(host->batch_msg);
- ret = 0;
- if (len >= host->batch_max) {
- ret = riemann_batch_flush_nolock(0, host);
+ if (status != 0) {
+ pthread_mutex_unlock(&host->lock);
+ ERROR("write_riemann plugin: out of memory");
+ return -1;
+ }
+ }
+
+ len = riemann_message_get_packed_size(host->batch_msg);
+ ret = 0;
+ if ((host->batch_max < 0) || (((size_t) host->batch_max) <= len)) {
+ ret = wrr_batch_flush_nolock(0, host);
+ } else {
+ if (host->batch_timeout > 0) {
+ timeout = TIME_T_TO_CDTIME_T((time_t)host->batch_timeout);
+ ret = wrr_batch_flush_nolock(timeout, host);
+ }
}
- pthread_mutex_unlock(&host->lock);
- return ret;
-} /* }}} Msg *riemann_batch_add_value_list */
+ pthread_mutex_unlock(&host->lock);
+ return ret;
+} /* }}} riemann_message_t *wrr_batch_add_value_list */
-static int riemann_notification(const notification_t *n, user_data_t *ud) /* {{{ */
+static int wrr_notification(const notification_t *n, user_data_t *ud) /* {{{ */
{
int status;
struct riemann_host *host = ud->data;
- Msg *msg;
+ riemann_message_t *msg;
if (!host->notifications)
return 0;
/*
* Never batch for notifications, send them ASAP
*/
- msg = riemann_notification_to_protobuf (host, n);
+ msg = wrr_notification_to_message(host, n);
if (msg == NULL)
return (-1);
- status = riemann_send (host, msg);
+ status = wrr_send(host, msg);
if (status != 0)
- ERROR ("write_riemann plugin: riemann_send failed with status %i",
- status);
-
- riemann_msg_protobuf_free (msg);
+ c_complain (LOG_ERR, &host->init_complaint,
+ "write_riemann plugin: riemann_client_send failed with status %i",
+ status);
+ else
+ c_release (LOG_DEBUG, &host->init_complaint,
+ "write_riemann plugin: riemann_client_send succeeded");
+
+ riemann_message_free(msg);
return (status);
-} /* }}} int riemann_notification */
+} /* }}} int wrr_notification */
-static int riemann_write(const data_set_t *ds, /* {{{ */
+static int wrr_write(const data_set_t *ds, /* {{{ */
const value_list_t *vl,
user_data_t *ud)
{
int status = 0;
int statuses[vl->values_len];
struct riemann_host *host = ud->data;
- Msg *msg;
-
- if (host->check_thresholds)
- write_riemann_threshold_check(ds, vl, statuses);
-
- if (host->use_tcp == 1 && host->batch_mode) {
-
- riemann_batch_add_value_list (host, ds, vl, statuses);
+ riemann_message_t *msg;
+ if (host->check_thresholds) {
+ status = write_riemann_threshold_check(ds, vl, statuses);
+ if (status != 0)
+ return status;
+ } else {
+ memset (statuses, 0, sizeof (statuses));
+ }
+
+ if (host->client_type != RIEMANN_CLIENT_UDP && host->batch_mode) {
+ wrr_batch_add_value_list(host, ds, vl, statuses);
+ } else {
+ msg = wrr_value_list_to_message(host, ds, vl, statuses);
+ if (msg == NULL)
+ return (-1);
- } else {
-
- msg = riemann_value_list_to_protobuf (host, ds, vl, statuses);
- if (msg == NULL)
- return (-1);
-
- status = riemann_send (host, msg);
- if (status != 0)
- ERROR ("write_riemann plugin: riemann_send failed with status %i",
- status);
+ status = wrr_send(host, msg);
- riemann_msg_protobuf_free (msg);
- }
- return status;
-} /* }}} int riemann_write */
+ riemann_message_free(msg);
+ }
+ return status;
+} /* }}} int wrr_write */
-static void riemann_free(void *p) /* {{{ */
+static void wrr_free(void *p) /* {{{ */
{
- struct riemann_host *host = p;
+ struct riemann_host *host = p;
- if (host == NULL)
- return;
+ if (host == NULL)
+ return;
- pthread_mutex_lock (&host->lock);
+ pthread_mutex_lock(&host->lock);
- host->reference_count--;
- if (host->reference_count > 0)
- {
- pthread_mutex_unlock (&host->lock);
- return;
- }
+ host->reference_count--;
+ if (host->reference_count > 0)
+ {
+ pthread_mutex_unlock(&host->lock);
+ return;
+ }
- riemann_disconnect (host);
+ wrr_disconnect(host);
- sfree(host->service);
- pthread_mutex_destroy (&host->lock);
- sfree(host);
-} /* }}} void riemann_free */
+ pthread_mutex_destroy(&host->lock);
+ sfree(host);
+} /* }}} void wrr_free */
-static int riemann_config_node(oconfig_item_t *ci) /* {{{ */
+static int wrr_config_node(oconfig_item_t *ci) /* {{{ */
{
- struct riemann_host *host = NULL;
- int status = 0;
- int i;
- oconfig_item_t *child;
- char callback_name[DATA_MAX_NAME_LEN];
- user_data_t ud;
-
- if ((host = calloc(1, sizeof (*host))) == NULL) {
- ERROR ("write_riemann plugin: calloc failed.");
- return ENOMEM;
- }
- pthread_mutex_init (&host->lock, NULL);
- host->reference_count = 1;
- host->node = NULL;
- host->service = NULL;
- host->notifications = 1;
- host->check_thresholds = 0;
- host->store_rates = 1;
- host->always_append_ds = 0;
- host->use_tcp = 1;
- host->batch_mode = 1;
- host->batch_max = RIEMANN_BATCH_MAX; /* typical MSS */
- host->batch_init = cdtime();
- host->ttl_factor = RIEMANN_TTL_FACTOR;
-
- status = cf_util_get_string (ci, &host->name);
- if (status != 0) {
- WARNING("write_riemann plugin: Required host name is missing.");
- riemann_free (host);
- return -1;
- }
-
- for (i = 0; i < ci->children_num; i++) {
- /*
- * The code here could be simplified but makes room
- * for easy adding of new options later on.
- */
- child = &ci->children[i];
- status = 0;
-
- if (strcasecmp ("Host", child->key) == 0) {
- status = cf_util_get_string (child, &host->node);
- if (status != 0)
- break;
- } else if (strcasecmp ("Notifications", child->key) == 0) {
- status = cf_util_get_boolean(child, &host->notifications);
- if (status != 0)
- break;
- } else if (strcasecmp ("EventServicePrefix", child->key) == 0) {
- status = cf_util_get_string (child, &host->event_service_prefix);
- if (status != 0)
- break;
- } else if (strcasecmp ("CheckThresholds", child->key) == 0) {
- status = cf_util_get_boolean(child, &host->check_thresholds);
- if (status != 0)
- break;
- } else if (strcasecmp ("Batch", child->key) == 0) {
- status = cf_util_get_boolean(child, &host->batch_mode);
- if (status != 0)
- break;
- } else if (strcasecmp("BatchMaxSize", child->key) == 0) {
- status = cf_util_get_int(child, &host->batch_max);
- if (status != 0)
- break;
- } else if (strcasecmp ("Port", child->key) == 0) {
- status = cf_util_get_service (child, &host->service);
- if (status != 0) {
- ERROR ("write_riemann plugin: Invalid argument "
- "configured for the \"Port\" "
- "option.");
- break;
- }
- } else if (strcasecmp ("Protocol", child->key) == 0) {
- char tmp[16];
- status = cf_util_get_string_buffer (child,
- tmp, sizeof (tmp));
- if (status != 0)
- {
- ERROR ("write_riemann plugin: cf_util_get_"
- "string_buffer failed with "
- "status %i.", status);
- break;
- }
-
- if (strcasecmp ("UDP", tmp) == 0)
- host->use_tcp = 0;
- else if (strcasecmp ("TCP", tmp) == 0)
- host->use_tcp = 1;
- else
- WARNING ("write_riemann plugin: The value "
- "\"%s\" is not valid for the "
- "\"Protocol\" option. Use "
- "either \"UDP\" or \"TCP\".",
- tmp);
- } else if (strcasecmp ("StoreRates", child->key) == 0) {
- status = cf_util_get_boolean (child, &host->store_rates);
- if (status != 0)
- break;
- } else if (strcasecmp ("AlwaysAppendDS", child->key) == 0) {
- status = cf_util_get_boolean (child,
- &host->always_append_ds);
- if (status != 0)
- break;
- } else if (strcasecmp ("TTLFactor", child->key) == 0) {
- double tmp = NAN;
- status = cf_util_get_double (child, &tmp);
- if (status != 0)
- break;
- if (tmp >= 2.0) {
- host->ttl_factor = tmp;
- } else if (tmp >= 1.0) {
- NOTICE ("write_riemann plugin: The configured "
- "TTLFactor is very small "
- "(%.1f). A value of 2.0 or "
- "greater is recommended.",
- tmp);
- host->ttl_factor = tmp;
- } else if (tmp > 0.0) {
- WARNING ("write_riemann plugin: The configured "
- "TTLFactor is too small to be "
- "useful (%.1f). I'll use it "
- "since the user knows best, "
- "but under protest.",
- tmp);
- host->ttl_factor = tmp;
- } else { /* zero, negative and NAN */
- ERROR ("write_riemann plugin: The configured "
- "TTLFactor is invalid (%.1f).",
- tmp);
- }
- } else {
- WARNING("write_riemann plugin: ignoring unknown config "
- "option: \"%s\"", child->key);
- }
- }
- if (status != 0) {
- riemann_free (host);
- return status;
- }
-
- ssnprintf (callback_name, sizeof (callback_name), "write_riemann/%s",
- host->name);
- ud.data = host;
- ud.free_func = riemann_free;
-
- pthread_mutex_lock (&host->lock);
-
- status = plugin_register_write (callback_name, riemann_write, &ud);
+ struct riemann_host *host = NULL;
+ int status = 0;
+ int i;
+ oconfig_item_t *child;
+ char callback_name[DATA_MAX_NAME_LEN];
+ user_data_t ud;
+
+ if ((host = calloc(1, sizeof(*host))) == NULL) {
+ ERROR ("write_riemann plugin: calloc failed.");
+ return ENOMEM;
+ }
+ pthread_mutex_init(&host->lock, NULL);
+ C_COMPLAIN_INIT (&host->init_complaint);
+ host->reference_count = 1;
+ host->node = NULL;
+ host->port = 0;
+ host->notifications = 1;
+ host->check_thresholds = 0;
+ host->store_rates = 1;
+ host->always_append_ds = 0;
+ host->batch_mode = 1;
+ host->batch_max = RIEMANN_BATCH_MAX; /* typical MSS */
+ host->batch_init = cdtime();
+ host->batch_timeout = 0;
+ host->ttl_factor = RIEMANN_TTL_FACTOR;
+ host->client = NULL;
+ host->client_type = RIEMANN_CLIENT_TCP;
+ host->timeout.tv_sec = 0;
+ host->timeout.tv_usec = 0;
+
+ status = cf_util_get_string(ci, &host->name);
+ if (status != 0) {
+ WARNING("write_riemann plugin: Required host name is missing.");
+ wrr_free(host);
+ return -1;
+ }
+
+ for (i = 0; i < ci->children_num; i++) {
+ /*
+ * The code here could be simplified but makes room
+ * for easy adding of new options later on.
+ */
+ child = &ci->children[i];
+ status = 0;
+
+ if (strcasecmp("Host", child->key) == 0) {
+ status = cf_util_get_string(child, &host->node);
+ if (status != 0)
+ break;
+ } else if (strcasecmp("Notifications", child->key) == 0) {
+ status = cf_util_get_boolean(child, &host->notifications);
+ if (status != 0)
+ break;
+ } else if (strcasecmp("EventServicePrefix", child->key) == 0) {
+ status = cf_util_get_string(child, &host->event_service_prefix);
+ if (status != 0)
+ break;
+ } else if (strcasecmp("CheckThresholds", child->key) == 0) {
+ status = cf_util_get_boolean(child, &host->check_thresholds);
+ if (status != 0)
+ break;
+ } else if (strcasecmp("Batch", child->key) == 0) {
+ status = cf_util_get_boolean(child, &host->batch_mode);
+ if (status != 0)
+ break;
+ } else if (strcasecmp("BatchMaxSize", child->key) == 0) {
+ status = cf_util_get_int(child, &host->batch_max);
+ if (status != 0)
+ break;
+ } else if (strcasecmp("BatchFlushTimeout", child->key) == 0) {
+ status = cf_util_get_int(child, &host->batch_timeout);
+ if (status != 0)
+ break;
+ } else if (strcasecmp("Timeout", child->key) == 0) {
+ status = cf_util_get_int(child, (int *)&host->timeout.tv_sec);
+ if (status != 0)
+ break;
+ } else if (strcasecmp("Port", child->key) == 0) {
+ host->port = cf_util_get_port_number(child);
+ if (host->port == -1) {
+ ERROR("write_riemann plugin: Invalid argument "
+ "configured for the \"Port\" "
+ "option.");
+ break;
+ }
+ } else if (strcasecmp("Protocol", child->key) == 0) {
+ char tmp[16];
+ status = cf_util_get_string_buffer(child,
+ tmp, sizeof(tmp));
+ if (status != 0)
+ {
+ ERROR("write_riemann plugin: cf_util_get_"
+ "string_buffer failed with "
+ "status %i.", status);
+ break;
+ }
- if (host->use_tcp == 1 && host->batch_mode) {
- ud.free_func = NULL;
- plugin_register_flush(callback_name, riemann_batch_flush, &ud);
+ if (strcasecmp("UDP", tmp) == 0)
+ host->client_type = RIEMANN_CLIENT_UDP;
+ else if (strcasecmp("TCP", tmp) == 0)
+ host->client_type = RIEMANN_CLIENT_TCP;
+ else if (strcasecmp("TLS", tmp) == 0)
+ host->client_type = RIEMANN_CLIENT_TLS;
+ else
+ WARNING("write_riemann plugin: The value "
+ "\"%s\" is not valid for the "
+ "\"Protocol\" option. Use "
+ "either \"UDP\", \"TCP\" or \"TLS\".",
+ tmp);
+ } else if (strcasecmp("TLSCAFile", child->key) == 0) {
+ status = cf_util_get_string(child, &host->tls_ca_file);
+ if (status != 0)
+ {
+ ERROR("write_riemann plugin: cf_util_get_"
+ "string_buffer failed with "
+ "status %i.", status);
+ break;
+ }
+ } else if (strcasecmp("TLSCertFile", child->key) == 0) {
+ status = cf_util_get_string(child, &host->tls_cert_file);
+ if (status != 0)
+ {
+ ERROR("write_riemann plugin: cf_util_get_"
+ "string_buffer failed with "
+ "status %i.", status);
+ break;
+ }
+ } else if (strcasecmp("TLSKeyFile", child->key) == 0) {
+ status = cf_util_get_string(child, &host->tls_key_file);
+ if (status != 0)
+ {
+ ERROR("write_riemann plugin: cf_util_get_"
+ "string_buffer failed with "
+ "status %i.", status);
+ break;
+ }
+ } else if (strcasecmp("StoreRates", child->key) == 0) {
+ status = cf_util_get_boolean(child, &host->store_rates);
+ if (status != 0)
+ break;
+ } else if (strcasecmp("AlwaysAppendDS", child->key) == 0) {
+ status = cf_util_get_boolean(child,
+ &host->always_append_ds);
+ if (status != 0)
+ break;
+ } else if (strcasecmp("TTLFactor", child->key) == 0) {
+ double tmp = NAN;
+ status = cf_util_get_double(child, &tmp);
+ if (status != 0)
+ break;
+ if (tmp >= 2.0) {
+ host->ttl_factor = tmp;
+ } else if (tmp >= 1.0) {
+ NOTICE("write_riemann plugin: The configured "
+ "TTLFactor is very small "
+ "(%.1f). A value of 2.0 or "
+ "greater is recommended.",
+ tmp);
+ host->ttl_factor = tmp;
+ } else if (tmp > 0.0) {
+ WARNING("write_riemann plugin: The configured "
+ "TTLFactor is too small to be "
+ "useful (%.1f). I'll use it "
+ "since the user knows best, "
+ "but under protest.",
+ tmp);
+ host->ttl_factor = tmp;
+ } else { /* zero, negative and NAN */
+ ERROR("write_riemann plugin: The configured "
+ "TTLFactor is invalid (%.1f).",
+ tmp);
+ }
+ } else {
+ WARNING("write_riemann plugin: ignoring unknown config "
+ "option: \"%s\"", child->key);
+ }
+ }
+ if (status != 0) {
+ wrr_free(host);
+ return status;
+ }
+
+ ssnprintf(callback_name, sizeof(callback_name), "write_riemann/%s",
+ host->name);
+ ud.data = host;
+ ud.free_func = wrr_free;
+
+ pthread_mutex_lock(&host->lock);
+
+ status = plugin_register_write(callback_name, wrr_write, &ud);
+
+ if (host->client_type != RIEMANN_CLIENT_UDP && host->batch_mode) {
+ ud.free_func = NULL;
+ plugin_register_flush(callback_name, wrr_batch_flush, &ud);
+ }
+ if (status != 0)
+ WARNING("write_riemann plugin: plugin_register_write (\"%s\") "
+ "failed with status %i.",
+ callback_name, status);
+ else /* success */
+ host->reference_count++;
+
+ status = plugin_register_notification(callback_name,
+ wrr_notification, &ud);
+ if (status != 0)
+ WARNING("write_riemann plugin: plugin_register_notification (\"%s\") "
+ "failed with status %i.",
+ callback_name, status);
+ else /* success */
+ host->reference_count++;
+
+ if (host->reference_count <= 1)
+ {
+ /* Both callbacks failed => free memory.
+ * We need to unlock here, because riemann_free() will lock.
+ * This is not a race condition, because we're the only one
+ * holding a reference. */
+ pthread_mutex_unlock(&host->lock);
+ wrr_free(host);
+ return (-1);
}
- if (status != 0)
- WARNING ("write_riemann plugin: plugin_register_write (\"%s\") "
- "failed with status %i.",
- callback_name, status);
- else /* success */
- host->reference_count++;
-
- status = plugin_register_notification (callback_name,
- riemann_notification, &ud);
- if (status != 0)
- WARNING ("write_riemann plugin: plugin_register_notification (\"%s\") "
- "failed with status %i.",
- callback_name, status);
- else /* success */
- host->reference_count++;
-
- if (host->reference_count <= 1)
- {
- /* Both callbacks failed => free memory.
- * We need to unlock here, because riemann_free() will lock.
- * This is not a race condition, because we're the only one
- * holding a reference. */
- pthread_mutex_unlock (&host->lock);
- riemann_free (host);
- return (-1);
- }
- host->reference_count--;
- pthread_mutex_unlock (&host->lock);
+ host->reference_count--;
+ pthread_mutex_unlock(&host->lock);
- return status;
-} /* }}} int riemann_config_node */
+ return status;
+} /* }}} int wrr_config_node */
-static int riemann_config(oconfig_item_t *ci) /* {{{ */
+static int wrr_config(oconfig_item_t *ci) /* {{{ */
{
- int i;
- oconfig_item_t *child;
- int status;
-
- for (i = 0; i < ci->children_num; i++) {
- child = &ci->children[i];
-
- if (strcasecmp("Node", child->key) == 0) {
- riemann_config_node (child);
- } else if (strcasecmp(child->key, "attribute") == 0) {
- char *key = NULL;
- char *val = NULL;
-
- if (child->values_num != 2) {
- WARNING("riemann attributes need both a key and a value.");
- return (-1);
- }
- if (child->values[0].type != OCONFIG_TYPE_STRING ||
- child->values[1].type != OCONFIG_TYPE_STRING) {
- WARNING("riemann attribute needs string arguments.");
- return (-1);
- }
- if ((key = strdup(child->values[0].value.string)) == NULL) {
- WARNING("cannot allocate memory for attribute key.");
- return (-1);
- }
- if ((val = strdup(child->values[1].value.string)) == NULL) {
- WARNING("cannot allocate memory for attribute value.");
- sfree (key);
- return (-1);
- }
- strarray_add(&riemann_attrs, &riemann_attrs_num, key);
- strarray_add(&riemann_attrs, &riemann_attrs_num, val);
- DEBUG("write_riemann: got attr: %s => %s", key, val);
- sfree(key);
- sfree(val);
- } else if (strcasecmp(child->key, "tag") == 0) {
- char *tmp = NULL;
- status = cf_util_get_string(child, &tmp);
- if (status != 0)
- continue;
-
- strarray_add (&riemann_tags, &riemann_tags_num, tmp);
- DEBUG("write_riemann plugin: Got tag: %s", tmp);
- sfree (tmp);
- } else {
- WARNING ("write_riemann plugin: Ignoring unknown "
- "configuration option \"%s\" at top level.",
- child->key);
- }
- }
- return (0);
-} /* }}} int riemann_config */
+ int i;
+ oconfig_item_t *child;
+ int status;
+
+ for (i = 0; i < ci->children_num; i++) {
+ child = &ci->children[i];
+
+ if (strcasecmp("Node", child->key) == 0) {
+ wrr_config_node (child);
+ } else if (strcasecmp(child->key, "attribute") == 0) {
+ char *key = NULL;
+ char *val = NULL;
+
+ if (child->values_num != 2) {
+ WARNING("riemann attributes need both a key and a value.");
+ return (-1);
+ }
+ if (child->values[0].type != OCONFIG_TYPE_STRING ||
+ child->values[1].type != OCONFIG_TYPE_STRING) {
+ WARNING("riemann attribute needs string arguments.");
+ return (-1);
+ }
+ if ((key = strdup(child->values[0].value.string)) == NULL) {
+ WARNING("cannot allocate memory for attribute key.");
+ return (-1);
+ }
+ if ((val = strdup(child->values[1].value.string)) == NULL) {
+ WARNING("cannot allocate memory for attribute value.");
+ sfree(key);
+ return (-1);
+ }
+ strarray_add(&riemann_attrs, &riemann_attrs_num, key);
+ strarray_add(&riemann_attrs, &riemann_attrs_num, val);
+ DEBUG("write_riemann: got attr: %s => %s", key, val);
+ sfree(key);
+ sfree(val);
+ } else if (strcasecmp(child->key, "tag") == 0) {
+ char *tmp = NULL;
+ status = cf_util_get_string(child, &tmp);
+ if (status != 0)
+ continue;
+
+ strarray_add(&riemann_tags, &riemann_tags_num, tmp);
+ DEBUG("write_riemann plugin: Got tag: %s", tmp);
+ sfree(tmp);
+ } else {
+ WARNING("write_riemann plugin: Ignoring unknown "
+ "configuration option \"%s\" at top level.",
+ child->key);
+ }
+ }
+ return (0);
+} /* }}} int wrr_config */
void module_register(void)
{
- plugin_register_complex_config ("write_riemann", riemann_config);
+ plugin_register_complex_config("write_riemann", wrr_config);
}
/* vim: set sw=8 sts=8 ts=8 noet : */
int *statuses)
{ /* {{{ */
int ret = -1;
- int i;
+ size_t i;
int status;
gauge_t values_copy[ds->ds_num];
gauge_t *values;
int status;
+ assert (vl->values_len > 0);
memset(statuses, 0, vl->values_len * sizeof(*statuses));
+
if (threshold_tree == NULL)
return 0;
#include "common.h"
#include "configfile.h"
#include "utils_cache.h"
-#include <sys/socket.h>
#include <arpa/inet.h>
#include <errno.h>
#include <netdb.h>
static char *build_json_str_list(const char *tag, struct str_list const *list) /* {{{ */
{
int res;
- char *ret_str;
+ char *ret_str = NULL;
char *temp_str;
int i;
if (list->nb_strs == 0) {
res = asprintf(&temp_str, "\"%s\": [\"%s\"", tag, list->strs[0]);
if (res == -1) {
ERROR("write_sensu plugin: Unable to alloc memory");
+ free(ret_str);
return NULL;
}
for (i=1; i<list->nb_strs; i++) {
{
char name_buffer[5 * DATA_MAX_NAME_LEN];
char service_buffer[6 * DATA_MAX_NAME_LEN];
- int i;
+ size_t i;
char *ret_str;
char *temp_str;
char *value_str;
} else
retlen = strlen(str);
- ret = malloc(retlen + 1);
+ ret = calloc(1, retlen + 1);
if (ret == NULL)
return NULL;
// added to original: not optimized, but keeps valgrind happy.
- memset(ret, 0, retlen + 1);
r = ret;
p = str;
char *ret_str;
char *temp_str;
int status;
- int i;
+ size_t i;
int res;
// add the severity/status
switch (n->severity) {
int statuses[vl->values_len];
struct sensu_host *host = ud->data;
gauge_t *rates = NULL;
- int i;
+ size_t i;
char *msg;
pthread_mutex_lock(&host->lock);
return -1;
}
}
- for (i = 0; i < (size_t) vl->values_len; i++) {
+ for (i = 0; i < vl->values_len; i++) {
msg = sensu_value_to_json(host, ds, vl, (int) i, rates, statuses[i]);
if (msg == NULL) {
sfree(rates);
#include "utils_cache.h"
#include <pthread.h>
-#include <sys/socket.h>
#include <netdb.h>
#ifndef WT_DEFAULT_NODE
return 0;
}
- if (cb->send_buf_fill <= 0)
+ if (cb->send_buf_fill == 0)
{
cb->send_buf_init_time = cdtime();
return 0;
{
int status;
char *temp = NULL;
- char *prefix = "";
+ const char *prefix = "";
const char *meta_prefix = "tsdb_prefix";
if (vl->meta) {
const char* host, meta_data_t *md)
{
int status;
- int message_len;
+ size_t message_len;
char *temp = NULL;
- char *tags = "";
+ const char *tags = "";
char message[1024];
- char *host_tags = cb->host_tags ? cb->host_tags : "";
+ const char *host_tags = cb->host_tags ? cb->host_tags : "";
const char *meta_tsdb = "tsdb_tags";
/* skip if value is NaN */
}
}
- message_len = ssnprintf (message,
+ status = ssnprintf (message,
sizeof(message),
"put %s %.0f %s fqdn=%s %s %s\r\n",
key,
host,
tags,
host_tags);
-
sfree(temp);
+ if (status < 0)
+ return -1;
+ message_len = (size_t) status;
if (message_len >= sizeof(message)) {
ERROR("write_tsdb plugin: message buffer too small: "
- "Need %d bytes.", message_len + 1);
+ "Need %zu bytes.", message_len + 1);
return -1;
}
char key[10*DATA_MAX_NAME_LEN];
char values[512];
- int status, i;
+ int status;
+ size_t i;
if (0 != strcmp(ds->type, vl->type))
{
char callback_name[DATA_MAX_NAME_LEN];
int i;
- cb = malloc(sizeof(*cb));
+ cb = calloc(1, sizeof(*cb));
if (cb == NULL)
{
- ERROR("write_tsdb plugin: malloc failed.");
+ ERROR("write_tsdb plugin: calloc failed.");
return -1;
}
- memset(cb, 0, sizeof(*cb));
cb->sock_fd = -1;
cb->node = NULL;
cb->service = NULL;
--- /dev/null
+/**
+ * collectd - src/xencpu.c
+ * Copyright (C) 2016 Pavel Rochnyak
+ *
+ * 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:
+ * Pavel Rochnyak <pavel2000 ngs.ru>
+ **/
+
+#include "collectd.h"
+#include "common.h"
+#include "plugin.h"
+
+#include <xenctrl.h>
+
+#ifdef XENCTRL_HAS_XC_INTERFACE
+
+//Xen-4.1+
+#define XC_INTERFACE_INIT_ARGS NULL,NULL,0
+xc_interface *xc_handle;
+
+#else /* XENCTRL_HAS_XC_INTERFACE */
+
+//For xen-3.4/xen-4.0
+#include <string.h>
+#define xc_strerror(xc_interface, errcode) strerror(errcode)
+#define XC_INTERFACE_INIT_ARGS
+typedef int xc_interface;
+xc_interface xc_handle = 0;
+
+#endif /* XENCTRL_HAS_XC_INTERFACE */
+
+uint32_t num_cpus = 0;
+xc_cpuinfo_t *cpu_info;
+static value_to_rate_state_t *cpu_states;
+
+static int xencpu_init (void)
+{
+ xc_handle = xc_interface_open(XC_INTERFACE_INIT_ARGS);
+ if (!xc_handle)
+ {
+ ERROR ("xencpu: xc_interface_open() failed");
+ return (-1);
+ };
+
+ xc_physinfo_t *physinfo;
+
+ physinfo = calloc(1, sizeof(xc_physinfo_t));
+ if (physinfo == NULL)
+ {
+ ERROR ("xencpu plugin: calloc() for physinfo failed.");
+ xc_interface_close(xc_handle);
+ return (ENOMEM);
+ }
+
+ if (xc_physinfo(xc_handle, physinfo) < 0)
+ {
+ ERROR ("xencpu plugin: xc_physinfo() failed");
+ xc_interface_close(xc_handle);
+ free(physinfo);
+ return (-1);
+ };
+
+ num_cpus = physinfo->nr_cpus;
+ free(physinfo);
+
+ INFO ("xencpu plugin: Found %"PRIu32" processors.", num_cpus);
+
+ cpu_info = calloc(num_cpus, sizeof(xc_cpuinfo_t));
+ if (cpu_info == NULL)
+ {
+ ERROR ("xencpu plugin: calloc() for num_cpus failed.");
+ xc_interface_close(xc_handle);
+ return (ENOMEM);
+ }
+
+ cpu_states = calloc (num_cpus, sizeof (value_to_rate_state_t));
+ if (cpu_states == NULL)
+ {
+ ERROR ("xencpu plugin: calloc() for cpu_states failed.");
+ xc_interface_close(xc_handle);
+ free(cpu_info);
+ return (ENOMEM);
+ }
+
+ return (0);
+} /* static int xencpu_init */
+
+static int xencpu_shutdown (void)
+{
+ free(cpu_states);
+ free(cpu_info);
+ xc_interface_close(xc_handle);
+
+ return 0;
+} /* static int xencpu_shutdown */
+
+static void submit_value (int cpu_num, gauge_t percent)
+{
+ value_t values[1];
+ value_list_t vl = VALUE_LIST_INIT;
+
+ values[0].gauge = percent;
+
+ vl.values = values;
+ vl.values_len = 1;
+
+ sstrncpy (vl.host, hostname_g, sizeof (vl.host));
+ sstrncpy (vl.plugin, "xencpu", sizeof (vl.plugin));
+ sstrncpy (vl.type, "percent", sizeof (vl.type));
+ sstrncpy (vl.type_instance, "load", sizeof (vl.type_instance));
+
+ if (cpu_num >= 0) {
+ ssnprintf (vl.plugin_instance, sizeof (vl.plugin_instance),
+ "%i", cpu_num);
+ }
+ plugin_dispatch_values (&vl);
+} /* static void submit_value */
+
+static int xencpu_read (void)
+{
+ cdtime_t now = cdtime ();
+
+ int rc, nr_cpus;
+
+ rc = xc_getcpuinfo(xc_handle, num_cpus, cpu_info, &nr_cpus);
+ if (rc < 0) {
+ ERROR ("xencpu: xc_getcpuinfo() Failed: %d %s\n", rc, xc_strerror(xc_handle,errno));
+ return (-1);
+ }
+
+ int cpu, status;
+ for (cpu = 0; cpu < nr_cpus; cpu++) {
+ gauge_t rate = NAN;
+ value_t value = {.derive = cpu_info[cpu].idletime};
+
+ status = value_to_rate (&rate, value, DS_TYPE_DERIVE, now, &cpu_states[cpu]);
+ if (status == 0) {
+ submit_value(cpu, 100 - rate/10000000);
+ }
+ }
+
+ return (0);
+} /* static int xencpu_read */
+
+void module_register (void)
+{
+ plugin_register_init ("xencpu", xencpu_init);
+ plugin_register_read ("xencpu", xencpu_read);
+ plugin_register_shutdown ("xencpu", xencpu_shutdown);
+} /* void module_register */
typedef llist_t kstat_t;
-static long long get_zfs_value(kstat_t *zfs_stats __attribute__((unused)),
- char *name)
+static int put_zfs_value (kstat_t *ksp, char const *k, value_t v)
{
llentry_t *e;
+ char *k_copy;
+ value_t *v_copy;
- e = llist_search (zfs_stats, name);
+ k_copy = strdup (k);
+ if (k_copy == NULL)
+ return ENOMEM;
+
+ v_copy = malloc (sizeof (*v_copy));
+ if (v_copy == NULL)
+ {
+ sfree (k_copy);
+ return ENOMEM;
+ }
+ *v_copy = v;
+
+ e = llentry_create (k_copy, v_copy);
+ if (e == NULL)
+ {
+ sfree (v_copy);
+ sfree (k_copy);
+ return ENOMEM;
+ }
+
+ llist_append (ksp, e);
+ return 0;
+}
+
+static long long get_zfs_value(kstat_t *ksp, const char *key)
+{
+ llentry_t *e;
+ value_t *v;
+
+ e = llist_search (ksp, key);
if (e == NULL)
{
- ERROR ("zfs_arc plugin: `llist_search` failed for key: '%s'.", name);
+ ERROR ("zfs_arc plugin: `llist_search` failed for key: '%s'.", key);
return (-1);
}
- return (*(long long int*)e->value);
+ v = e->value;
+ return ((long long) v->derive);
+}
+
+static void free_zfs_values (kstat_t *ksp)
+{
+ llentry_t *e;
+
+ if (ksp == NULL)
+ return;
+
+ for (e = llist_head (ksp); e != NULL; e = e->next)
+ {
+ sfree (e->key);
+ sfree (e->value);
+ }
+
+ llist_destroy (ksp);
}
-#elif !defined(__FreeBSD__) // Solaris
+#elif defined(KERNEL_SOLARIS)
extern kstat_ctl_t *kc;
static long long get_zfs_value(kstat_t *ksp, char *name)
return (get_kstat_value(ksp, name));
}
-#else // FreeBSD
+#elif defined(KERNEL_FREEBSD)
#include <sys/types.h>
#include <sys/sysctl.h>
value_t l2_io[2];
kstat_t *ksp = NULL;
-#if KERNEL_LINUX
- long long int *llvalues = NULL;
- char file_contents[1024 * 10];
- char *fields[3];
- int numfields;
- ssize_t len;
+#if defined(KERNEL_LINUX)
+ FILE *fh;
+ char buffer[1024];
+
+ fh = fopen (ZOL_ARCSTATS_FILE, "r");
+ if (fh == NULL)
+ {
+ char errbuf[1024];
+ ERROR ("zfs_arc plugin: Opening \"%s\" failed: %s", ZOL_ARCSTATS_FILE,
+ sstrerror (errno, errbuf, sizeof (errbuf)));
+ return (-1);
+ }
ksp = llist_create ();
if (ksp == NULL)
{
ERROR ("zfs_arc plugin: `llist_create' failed.");
+ fclose (fh);
return (-1);
}
- len = read_file_contents (ZOL_ARCSTATS_FILE, file_contents, sizeof(file_contents) - 1);
- if (len > 1)
+ while (fgets (buffer, sizeof (buffer), fh) != NULL)
{
+ char *fields[3];
+ value_t v;
+ int status;
+
+ status = strsplit (buffer, fields, STATIC_ARRAY_SIZE (fields));
+ if (status != 3)
+ continue;
+
+ status = parse_value (fields[2], &v, DS_TYPE_DERIVE);
+ if (status != 0)
+ continue;
- int i=0;
- char *pnl = file_contents;
- char *pnnl;
-
- file_contents[len] = '\0';
-
- while (pnl != NULL)
- {
- pnl = strchr(pnl, '\n');
- i++;
- if (pnl && (*pnl != '\0'))
- pnl++;
- }
-
- if (i > 0)
- {
- llentry_t *e;
- llvalues = malloc(sizeof(long long int) * i);
- if (llvalues == NULL)
- {
- ERROR ("zfs_arc plugin: `malloc' failed.");
- llist_destroy (ksp);
- return (-1);
- }
- int j = 0;
-
- pnl = file_contents;
- while (pnl != NULL)
- {
- pnnl = strchr(pnl, '\n');
- if (pnnl != NULL)
- *pnnl = '\0';
-
- numfields = strsplit (pnl, fields, 4);
- if (numfields == 3)
- {
- llvalues[j] = atoll (fields[2]);
-
- e = llentry_create (fields[0], &llvalues[j]);
- if (e == NULL)
- {
- ERROR ("zfs_arc plugin: `llentry_create' failed.");
- }
- else
- {
- llist_append (ksp, e);
- }
- j++;
- }
- pnl = pnnl;
- if (pnl != NULL)
- pnl ++;
- }
- }
+ put_zfs_value (ksp, fields[0], v);
}
-#elif !defined(__FreeBSD__) // Solaris
+ fclose (fh);
+
+#elif defined(KERNEL_SOLARIS)
get_kstat (&ksp, "zfs", 0, "arcstats");
if (ksp == NULL)
{
#endif
/* Sizes */
- za_read_gauge (ksp, "size", "cache_size", "arc");
+ za_read_gauge (ksp, "anon_size", "cache_size", "anon_size");
+ za_read_gauge (ksp, "c", "cache_size", "c");
+ za_read_gauge (ksp, "c_max", "cache_size", "c_max");
+ za_read_gauge (ksp, "c_min", "cache_size", "c_min");
+ za_read_gauge (ksp, "hdr_size", "cache_size", "hdr_size");
+ za_read_gauge (ksp, "metadata_size", "cache_size", "metadata_size");
+ za_read_gauge (ksp, "mfu_ghost_size", "cache_size", "mfu_ghost_size");
+ za_read_gauge (ksp, "mfu_size", "cache_size", "mfu_size");
+ za_read_gauge (ksp, "mru_ghost_size", "cache_size", "mru_ghost_size");
+ za_read_gauge (ksp, "mru_size", "cache_size", "mru_size");
+ za_read_gauge (ksp, "other_size", "cache_size", "other_size");
+ za_read_gauge (ksp, "p", "cache_size", "p");
+ za_read_gauge (ksp, "size", "cache_size", "arc");
/* The "l2_size" value has disappeared from Solaris some time in
* early 2013, and has only reappeared recently in Solaris 11.2.
/* Operations */
za_read_derive (ksp, "deleted", "cache_operation", "deleted");
-#if __FreeBSD__
+#if defined(KERNEL_FREEBSD)
za_read_derive (ksp, "allocated","cache_operation", "allocated");
-#if defined(__FreeBSD_version) && (__FreeBSD_version < 1002501)
+#if __FreeBSD_version < 1002501
/* stolen removed from sysctl kstat.zfs.misc.arcstats on FreeBSD 10.2+ */
za_read_derive (ksp, "stolen", "cache_operation", "stolen");
#endif
/* Issue indicators */
za_read_derive (ksp, "mutex_miss", "mutex_operations", "miss");
za_read_derive (ksp, "hash_collisions", "hash_collisions", "");
+ za_read_derive (ksp, "memory_throttle_count", "memory_throttle_count", "");
/* Evictions */
za_read_derive (ksp, "evict_l2_cached", "cache_eviction", "cached");
za_read_derive (ksp, "demand_metadata_misses", "cache_result", "demand_metadata-miss");
za_read_derive (ksp, "prefetch_data_misses", "cache_result", "prefetch_data-miss");
za_read_derive (ksp, "prefetch_metadata_misses", "cache_result", "prefetch_metadata-miss");
+ za_read_derive (ksp, "mfu_hits", "cache_result", "mfu-hit");
+ za_read_derive (ksp, "mfu_ghost_hits", "cache_result", "mfu_ghost-hit");
+ za_read_derive (ksp, "mru_hits", "cache_result", "mru-hit");
+ za_read_derive (ksp, "mru_ghost_hits", "cache_result", "mru_ghost-hit");
+ za_read_derive (ksp, "prefetch_metadata_misses", "cache_result", "prefetch_metadata-miss");
/* Ratios */
arc_hits = (gauge_t) get_zfs_value(ksp, "hits");
za_submit ("io_octets", "L2", l2_io, /* num values = */ 2);
#if defined(KERNEL_LINUX)
- if (llvalues != NULL)
- {
- free(llvalues);
- }
- if (ksp != NULL)
- {
- llist_destroy (ksp);
- }
+ free_zfs_values (ksp);
#endif
return (0);
static int za_init (void) /* {{{ */
{
-#if !defined(__FreeBSD__) && !defined(KERNEL_LINUX) // Solaris
+#if defined(KERNEL_SOLARIS)
/* kstats chain already opened by update_kstat (using *kc), verify everything went fine. */
if (kc == NULL)
{
--- /dev/null
+/**
+ * collectd - src/zone.c
+ * Copyright (C) 2011 Mathijs Mohlmann
+ *
+ * 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:
+ * Mathijs Mohlmann
+ * Dagobert Michelsen (forward-porting)
+ **/
+
+#if HAVE_CONFIG_H
+# include "config.h"
+# undef HAVE_CONFIG_H
+#endif
+/* avoid procfs.h error "Cannot use procfs in the large file compilation environment" */
+#if !defined(_LP64) && _FILE_OFFSET_BITS == 64
+# undef _FILE_OFFSET_BITS
+# undef _LARGEFILE64_SOURCE
+#endif
+
+#include "collectd.h"
+#include "common.h"
+#include "plugin.h"
+
+#include <sys/types.h>
+#include <sys/vm_usage.h>
+#include <procfs.h>
+#include <zone.h>
+
+#include "utils_avltree.h"
+
+#define MAX_PROCFS_PATH 40
+#define FRC2PCT(pp)(((float)(pp))/0x8000*100)
+
+typedef struct zone_stats {
+ ushort_t pctcpu;
+ ushort_t pctmem;
+} zone_stats_t;
+
+static long pagesize;
+
+static int zone_init (void)
+{
+ pagesize = sysconf(_SC_PAGESIZE);
+ return (0);
+}
+
+static int
+zone_compare(const zoneid_t *a, const zoneid_t *b)
+{
+ if (*a == *b)
+ return(0);
+ if (*a < *b)
+ return(-1);
+ return(1);
+}
+
+static int
+zone_read_procfile(char const *pidstr, char const *name, void *buf, size_t bufsize)
+{
+ int fd;
+
+ char procfile[MAX_PROCFS_PATH];
+ (void)snprintf(procfile, sizeof(procfile), "/proc/%s/%s", pidstr, name);
+ if ((fd = open(procfile, O_RDONLY)) == -1) {
+ return (1);
+ }
+
+ if (sread(fd, buf, bufsize) != 0) {
+ char errbuf[1024];
+ ERROR ("zone plugin: Reading \"%s\" failed: %s", procfile,
+ sstrerror (errno, errbuf, sizeof (errbuf)));
+ close(fd);
+ return (1);
+ }
+
+ close(fd);
+ return (0);
+}
+
+static int
+zone_submit_value(char *zone, gauge_t value)
+{
+ value_list_t vl = VALUE_LIST_INIT;
+ value_t values[1];
+
+ values[0].gauge = value;
+
+ vl.values = values;
+ vl.values_len = 1; /*STATIC_ARRAY_SIZE (values);*/
+ sstrncpy (vl.host, hostname_g, sizeof (vl.host));
+ sstrncpy (vl.plugin, "zone", sizeof (vl.plugin));
+ sstrncpy (vl.type, "percent", sizeof (vl.type));
+ sstrncpy (vl.type_instance, zone, sizeof (vl.type_instance));
+
+ return(plugin_dispatch_values (&vl));
+}
+
+static zone_stats_t *
+zone_find_stats(c_avl_tree_t *tree, zoneid_t zoneid)
+{
+ zone_stats_t *ret = NULL;
+ zoneid_t *key = NULL;
+
+ if (c_avl_get(tree, (void **)&zoneid, (void **)&ret)) {
+ if (!(ret = malloc(sizeof(*ret)))) {
+ WARNING("zone plugin: no memory");
+ return(NULL);
+ }
+ if (!(key = malloc(sizeof(*key)))) {
+ WARNING("zone plugin: no memory");
+ free(ret);
+ return(NULL);
+ }
+ *key = zoneid;
+ if (c_avl_insert(tree, key, ret)) {
+ WARNING("zone plugin: error inserting into tree");
+ return(NULL);
+ }
+ }
+ return(ret);
+}
+
+static void
+zone_submit_values(c_avl_tree_t *tree)
+{
+ char zonename[ZONENAME_MAX];
+ zoneid_t *zoneid = NULL;
+ zone_stats_t *stats = NULL;
+
+ while (c_avl_pick (tree, (void **)&zoneid, (void **)&stats) == 0)
+ {
+ if (getzonenamebyid(*zoneid, zonename, sizeof( zonename )) == -1) {
+ WARNING("zone plugin: error retreiving zonename");
+ } else {
+ zone_submit_value(zonename, (gauge_t)FRC2PCT(stats->pctcpu));
+ }
+ free(stats);
+ free(zoneid);
+ }
+ c_avl_destroy(tree);
+}
+
+static c_avl_tree_t *
+zone_scandir(DIR *procdir)
+{
+ pid_t pid;
+ dirent_t *direntp;
+ psinfo_t psinfo;
+ c_avl_tree_t *tree;
+ zone_stats_t *stats;
+
+ if (!(tree=c_avl_create((void *) zone_compare))) {
+ WARNING("zone plugin: Failed to create tree");
+ return(NULL);
+ }
+
+ rewinddir(procdir);
+ while ((direntp = readdir(procdir))) {
+ char const *pidstr = direntp->d_name;
+ if (pidstr[0] == '.') /* skip "." and ".." */
+ continue;
+
+ pid = atoi(pidstr);
+ if (pid == 0 || pid == 2 || pid == 3)
+ continue; /* skip sched, pageout and fsflush */
+
+ if (zone_read_procfile(pidstr, "psinfo", &psinfo, sizeof(psinfo_t)) != 0)
+ continue;
+
+ stats = zone_find_stats(tree, psinfo.pr_zoneid);
+ if( stats ) {
+ stats->pctcpu += psinfo.pr_pctcpu;
+ stats->pctmem += psinfo.pr_pctmem;
+ }
+ }
+ return(tree);
+}
+
+static int zone_read (void)
+{
+ DIR *procdir;
+ c_avl_tree_t *tree;
+
+ if ((procdir = opendir("/proc")) == NULL) {
+ ERROR("zone plugin: cannot open /proc directory\n");
+ return (-1);
+ }
+
+ tree=zone_scandir(procdir);
+ closedir(procdir);
+ if (tree == NULL) {
+ return (-1);
+ }
+ zone_submit_values(tree); /* this also frees tree */
+ return (0);
+}
+
+void module_register (void)
+{
+ plugin_register_init ("zone", zone_init);
+ plugin_register_read ("zone", zone_read);
+} /* void module_register */
#include "plugin.h"
#include <netdb.h>
-#include <sys/socket.h>
#include <sys/un.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
struct addrinfo ai_hints;
struct addrinfo *ai;
struct addrinfo *ai_list;
- char *host;
- char *port;
+ const char *host;
+ const char *port;
memset ((void *) &ai_hints, '\0', sizeof (ai_hints));
ai_hints.ai_family = AF_UNSPEC;
static int zookeeper_query (char *buffer, size_t buffer_size)
{
- int sk = -1;
- int status;
+ int sk, status;
size_t buffer_fill;
sk = zookeeper_connect();
DEFAULT_VERSION="5.5.1.git"
-VERSION="`git describe 2> /dev/null | grep collectd | sed -e 's/^collectd-//'`"
+if [ -d .git ]; then
+ VERSION="`git describe --dirty=+ --abbrev=7 2> /dev/null | grep collectd | sed -e 's/^collectd-//' -e 's/-/./g'`"
+fi
if test -z "$VERSION"; then
VERSION="$DEFAULT_VERSION"
fi
-VERSION="`echo \"$VERSION\" | sed -e 's/-/./g'`"
-
printf "%s" "$VERSION"