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
-src/test_utils_latency
-src/test_utils_mount
-src/test_utils_vl_lookup
-test*.log
-*.trs
+# Unit tests
+src/tests/
+test_*
-# new daemon repo
-src/daemon/.deps/
-src/daemon/.dirstamp
+# src/daemon/...
src/daemon/collectd
-src/daemon/test_common
-src/daemon/test_meta_data
-src/daemon/test_utils_avltree
-src/daemon/test_utils_heap
-src/daemon/test_utils_subst
-sudo: false
+sudo: required
+dist: trusty
compiler:
- gcc
- clang
-addons:
- apt:
- packages:
- - iptables-dev
- - libcap-dev
- - libdbi-dev
- - libhiredis-dev
- - libnfnetlink-dev
- - libnotify-dev
- - libpcap-dev
- - libperl-dev
- - libprotobuf-c0-dev
- - librrd-dev
- - libsnmp-dev
- - libudev-dev
- - libvarnishapi-dev
- - libyajl-dev
- - linux-libc-dev
- - protobuf-c-compiler
language: c
+before_install:
+ - sudo apt-get update -qq
+ - sudo apt-get install -qq --no-install-recommends
+ 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 && make distcheck
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
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
+ {
+ 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
$self->_socket_chat($msg, sub {
local $_ = shift;
my $ret = shift;
- /^\s*([^:]+):\s*(.*)/ and do {
- $1 =~ s/\s*$//;
- $ret->{$1} = $2;
- };
+ my ( $key, $val );
+ ( $key, $val ) = /^\s*([^:]+):\s*(.*)/ and do {
+ $key =~ s/\s*$//;
+ $ret->{$key} = $val;
+ };
}, $ret
);
return $ret;
AC_PROG_LIBTOOL
AC_PROG_LEX
AC_PROG_YACC
+
+# Warn when pkg.m4 is missing
+m4_pattern_forbid([^_?PKG_[A-Z_]+$],[*** pkg.m4 missing, please install pkg-config])
+
PKG_PROG_PKG_CONFIG
AC_CHECK_PROG([have_protoc_c], [protoc-c], [yes], [no])
-AC_CHECK_HEADERS([google/protobuf-c/protobuf-c.h],
- [have_protobuf_c_h="yes"],
- [have_protobuf_c_h="no"])
-if test "x$have_protoc_c" = "xyes" && test "x$have_protobuf_c_h" != "xyes"
+if test "x$have_protoc_c" = "xno"
+then
+ have_protoc_c="no (protoc-c compiler not found)"
+fi
+
+if test "x$have_protoc_c" = "xyes"
+then
+ AC_CHECK_HEADERS([protobuf-c/protobuf-c.h google/protobuf-c/protobuf-c.h],
+ [have_protoc_c="yes"; break],
+ [have_protoc_c="no (<google/protobuf-c/protobuf-c.h> not found)"])
+fi
+if test "x$have_protoc_c" = "xyes"
then
- have_protoc_c="no (unable to find <google/protobuf-c/protobuf-c.h>)"
+ AC_CHECK_LIB([protobuf-c], [protobuf_c_message_pack],
+ [have_protoc_c="yes"],
+ [have_protoc_c="no (libprotobuf-c not found)"])
+
fi
AM_CONDITIONAL(HAVE_PROTOC_C, test "x$have_protoc_c" = "xyes")
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])
#endif
])
-AC_CHECK_HEADERS(netinet/ip_compat.h)
-
have_net_pfvar_h="no"
AC_CHECK_HEADERS(net/pfvar.h,
[have_net_pfvar_h="yes"],
AC_CHECK_FUNCS(getvfsstat, [have_getvfsstat="yes"])
have_listmntent="no"
AC_CHECK_FUNCS(listmntent, [have_listmntent="yes"])
+have_getmntent_r="no"
+AC_CHECK_FUNCS(getmntent_r, [have_getmntent_r="yes"])
have_getmntent="no"
AC_CHECK_FUNCS(getmntent, [have_getmntent="c"])
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:])
GANGLIA_LDFLAGS="-L$withval/lib"
with_libganglia="yes"
else
- with_libganglia_config="ganglia-config"
with_libganglia="$withval"
fi; fi; fi
],
[
- with_libganglia_config="ganglia-config"
with_libganglia="yes"
])
-if test "x$with_libganglia" = "xyes" && test "x$with_libganglia_config" != "x"
+if test "x$with_libganglia" = "xyes"
then
- if test "x$GANGLIA_CPPFLAGS" = "x"
+ if test "x$with_libganglia_config" != "x"
then
- GANGLIA_CPPFLAGS=`"$with_libganglia_config" --cflags 2>/dev/null`
- fi
+ if test "x$GANGLIA_CPPFLAGS" = "x"
+ then
+ GANGLIA_CPPFLAGS=`"$with_libganglia_config" --cflags 2>/dev/null`
+ fi
- if test "x$GANGLIA_LDFLAGS" = "x"
- then
- GANGLIA_LDFLAGS=`"$with_libganglia_config" --ldflags 2>/dev/null`
- fi
+ if test "x$GANGLIA_LDFLAGS" = "x"
+ then
+ GANGLIA_LDFLAGS=`"$with_libganglia_config" --ldflags 2>/dev/null`
+ fi
- if test "x$GANGLIA_LIBS" = "x"
- then
- GANGLIA_LIBS=`"$with_libganglia_config" --libs 2>/dev/null`
+ if test "x$GANGLIA_LIBS" = "x"
+ then
+ GANGLIA_LIBS=`"$with_libganglia_config" --libs 2>/dev/null`
+ fi
+ else
+ GANGLIA_LIBS="-lganglia"
fi
fi
GCRYPT_CPPFLAGS=`"$with_libgcrypt_config" --cflags 2>/dev/null`
fi
- if test "x$GCRYPT_LDFLAGS" = "x"
- then
- gcrypt_exec_prefix=`"$with_libgcrypt_config" --exec-prefix 2>/dev/null`
- GCRYPT_LDFLAGS="-L$gcrypt_exec_prefix/lib"
- fi
-
if test "x$GCRYPT_LIBS" = "x"
then
GCRYPT_LIBS=`"$with_libgcrypt_config" --libs 2>/dev/null`
SAVE_CPPFLAGS="$CPPFLAGS"
SAVE_LDFLAGS="$LDFLAGS"
+SAVE_LIBS="$LIBS"
CPPFLAGS="$CPPFLAGS $GCRYPT_CPPFLAGS"
LDFLAGS="$LDFLAGS $GCRYPT_LDFLAGS"
+LIBS="$LIBS $GCRYPT_LIBS"
if test "x$with_libgcrypt" = "xyes"
then
if test "x$with_libgcrypt" = "xyes"
then
- if test "x$GCRYPT_LDFLAGS" != "x"
- then
- AC_MSG_NOTICE([gcrypt LDFLAGS: $GCRYPT_LDFLAGS])
- fi
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"
LDFLAGS="$SAVE_LDFLAGS"
+LIBS="$SAVE_LIBS"
if test "x$with_libgcrypt" = "xyes"
then
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.])],
fi
AC_MSG_CHECKING([for libjvm.so])
- TMPVAR=`find -L "$with_java_home" -name libjvm.so -type f -exec 'dirname' '{}' ';' 2>/dev/null | head -n 1`
+ TMPVAR=`find -L "$with_java_home" -type f \( -name libjvm.so -o -name libjvm.dylib \) -exec 'dirname' '{}' ';' 2>/dev/null | head -n 1`
if test "x$TMPVAR" != "x"
then
AC_MSG_RESULT([found in $TMPVAR])
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
# --with-libmosquitto {{{
with_libmosquitto_cppflags=""
-with_libmosquitto_libs="-lmosquitto"
+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_libs="-L$withval/lib -lmosquitto"
+ with_libmosquitto_ldflags="-L$withval/lib"
with_libmosquitto="yes"
else
with_libmosquitto="$withval"
if test "x$with_libmosquitto" = "xyes"
then
SAVE_CPPFLAGS="$CPPFLAGS"
- CPPFLAGS="$with_libmosquitto_cppflags"
+ CPPFLAGS="$CPPFLAGS $with_libmosquitto_cppflags"
AC_CHECK_HEADERS(mosquitto.h, [with_libmosquitto="yes"], [with_libmosquitto="no (mosquitto.h not found)"])
then
SAVE_LDFLAGS="$LDFLAGS"
SAVE_CPPFLAGS="$CPPFLAGS"
- LDFLAGS="$with_libmosquitto_libs"
- CPPFLAGS="$with_libmosquitto_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)"])
if test "x$with_libmosquitto" = "xyes"
then
BUILD_WITH_LIBMOSQUITTO_CPPFLAGS="$with_libmosquitto_cppflags"
- BUILD_WITH_LIBMOSQUITTO_LIBS="$with_libmosquitto_libs"
+ 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
# }}}
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"
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)"]
+)
# Check for enabled/disabled features
#
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_df="yes"
fi
+if test "x$c_cv_have_getmntent_r" = "xyes"
+then
+ plugin_df="yes"
+fi
+
# Df plugin: Check if we have either `statfs' or `statvfs' second.
if test "x$plugin_df" = "xyes"
then
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])
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
%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_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
%{?_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
%changelog
#* TODO: next feature release changelog
#- New upstream version
-#- New plugins enabled by default: mqtt
+#- New plugins enabled by default: mqtt, notify_nagios
#- New plugins disabled by default: zone
#
* Wed May 27 2015 Marc Fournier <marc.fournier@camptocamp.com> 5.5.0-1
ExecStart=/usr/sbin/collectd
EnvironmentFile=-/etc/sysconfig/collectd
EnvironmentFile=-/etc/default/collectd
+ProtectSystem=full
+ProtectHome=true
+
+# drop all capabilities:
+CapabilityBoundingSet=
+# use this instead if you use the dns or ping plugin
+#CapabilityBoundingSet=CAP_NET_RAW
+# turn this on if you use the iptables next to the dns or ping plugin
+#CapabilityBoundingSet=CAP_NET_RAW CAP_NET_ADMIN
+
+NoNewPrivileges=true
# Tell systemd it will receive a notification from collectd over it's control
# socket once the daemon is ready. See systemd.service(5) for more details.
Type=notify
-NotifyAccess=main
# Restart the collectd daemon after a 10 seconds delay, in case it crashes.
-Restart=always
-RestartSec=10
-
-# Send all console messages to syslog.
-StandardOutput=syslog
-StandardError=syslog
+Restart=on-failure
[Install]
WantedBy=multi-user.target
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/libcommon.la daemon/libplugin_mock.la -lm
+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
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/libcommon.la daemon/libplugin_mock.la
+test_utils_vl_lookup_LDADD = liblookup.la daemon/libplugin_mock.la
if BUILD_WITH_LIBKSTAT
test_utils_vl_lookup_LDADD += -lkstat
endif
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/libcommon.la daemon/libplugin_mock.la
+test_utils_mount_LDADD = libmount.la daemon/libplugin_mock.la
if BUILD_WITH_LIBKSTAT
test_utils_mount_LDADD += -lkstat
endif
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
if BUILD_PLUGIN_CGROUPS
pkglib_LTLIBRARIES += cgroups.la
-cgroups_la_SOURCES = cgroups.c \
- utils_ignorelist.c utils_ignorelist.h
+cgroups_la_SOURCES = cgroups.c
cgroups_la_LDFLAGS = $(PLUGIN_LDFLAGS)
cgroups_la_LIBADD = libmount.la
endif
if BUILD_PLUGIN_DF
pkglib_LTLIBRARIES += df.la
-df_la_SOURCES = df.c \
- utils_ignorelist.c utils_ignorelist.h
+df_la_SOURCES = df.c
df_la_LDFLAGS = $(PLUGIN_LDFLAGS)
df_la_LIBADD = libmount.la
endif
if BUILD_PLUGIN_DISK
pkglib_LTLIBRARIES += disk.la
-disk_la_SOURCES = disk.c \
- utils_ignorelist.c utils_ignorelist.h
+disk_la_SOURCES = disk.c
disk_la_CFLAGS = $(AM_CFLAGS)
disk_la_LDFLAGS = $(PLUGIN_LDFLAGS)
disk_la_LIBADD =
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
if BUILD_PLUGIN_INTERFACE
pkglib_LTLIBRARIES += interface.la
-interface_la_SOURCES = interface.c \
- utils_ignorelist.c utils_ignorelist.h
+interface_la_SOURCES = interface.c
interface_la_CFLAGS = $(AM_CFLAGS)
interface_la_LDFLAGS = $(PLUGIN_LDFLAGS)
interface_la_LIBADD =
if BUILD_PLUGIN_IPMI
pkglib_LTLIBRARIES += ipmi.la
-ipmi_la_SOURCES = ipmi.c \
- utils_ignorelist.c utils_ignorelist.h
+ipmi_la_SOURCES = ipmi.c
ipmi_la_CFLAGS = $(AM_CFLAGS) $(BUILD_WITH_OPENIPMI_CFLAGS)
ipmi_la_LDFLAGS = $(PLUGIN_LDFLAGS)
ipmi_la_LIBADD = $(BUILD_WITH_OPENIPMI_LIBS)
if BUILD_PLUGIN_IRQ
pkglib_LTLIBRARIES += irq.la
-irq_la_SOURCES = irq.c \
- utils_ignorelist.c utils_ignorelist.h
+irq_la_SOURCES = irq.c
irq_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
if BUILD_PLUGIN_MADWIFI
pkglib_LTLIBRARIES += madwifi.la
-madwifi_la_SOURCES = madwifi.c madwifi.h \
- utils_ignorelist.c utils_ignorelist.h
+madwifi_la_SOURCES = madwifi.c madwifi.h
madwifi_la_LDFLAGS = $(PLUGIN_LDFLAGS)
endif
if BUILD_PLUGIN_MD
pkglib_LTLIBRARIES += md.la
-md_la_SOURCES = md.c \
- utils_ignorelist.c utils_ignorelist.h
+md_la_SOURCES = md.c
md_la_LDFLAGS = $(PLUGIN_LDFLAGS)
endif
if BUILD_PLUGIN_MIC
pkglib_LTLIBRARIES += mic.la
-mic_la_SOURCES = mic.c \
- utils_ignorelist.c utils_ignorelist.h
+mic_la_SOURCES = mic.c
mic_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_MIC_LIBPATH)
mic_la_CFLAGS = $(AM_CFLAGS) $(BUILD_WITH_MIC_CPPFLAGS)
mic_la_LIBADD = $(BUILD_WITH_MIC_LDADD)
if BUILD_PLUGIN_MQTT
pkglib_LTLIBRARIES += mqtt.la
mqtt_la_SOURCES = mqtt.c
-mqtt_la_LDFLAGS = $(PLUGIN_LDFLAGS)
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_NETAPP
pkglib_LTLIBRARIES += netapp.la
-netapp_la_SOURCES = netapp.c \
- utils_ignorelist.c utils_ignorelist.h
+netapp_la_SOURCES = netapp.c
netapp_la_CPPFLAGS = $(AM_CPPFLAGS) $(LIBNETAPP_CPPFLAGS)
netapp_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(LIBNETAPP_LDFLAGS)
netapp_la_LIBADD = $(LIBNETAPP_LIBS)
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
if BUILD_PLUGIN_ONEWIRE
pkglib_LTLIBRARIES += onewire.la
-onewire_la_SOURCES = onewire.c \
- utils_ignorelist.c utils_ignorelist.h
+onewire_la_SOURCES = onewire.c
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
if BUILD_PLUGIN_PROTOCOLS
pkglib_LTLIBRARIES += protocols.la
-protocols_la_SOURCES = protocols.c \
- utils_ignorelist.c utils_ignorelist.h
+protocols_la_SOURCES = protocols.c
protocols_la_LDFLAGS = $(PLUGIN_LDFLAGS)
endif
if BUILD_PLUGIN_SENSORS
pkglib_LTLIBRARIES += sensors.la
-sensors_la_SOURCES = sensors.c \
- utils_ignorelist.c utils_ignorelist.h
+sensors_la_SOURCES = sensors.c
sensors_la_CFLAGS = $(AM_CFLAGS) $(BUILD_WITH_LIBSENSORS_CFLAGS)
sensors_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_LIBSENSORS_LDFLAGS)
sensors_la_LIBADD = -lsensors
if BUILD_PLUGIN_SMART
if BUILD_WITH_LIBUDEV
pkglib_LTLIBRARIES += smart.la
-smart_la_SOURCES = smart.c \
- utils_ignorelist.c utils_ignorelist.h
+smart_la_SOURCES = smart.c
smart_la_CFLAGS = $(AM_CFLAGS) $(BUILD_WITH_LIBATASMART_CPPFLAGS)
smart_la_LDFLAGS = $(PLUGIN_LDFLAGS) $(BUILD_WITH_LIBATASMART_LDFLAGS)
smart_la_LIBADD = $(BUILD_WITH_LIBATASMART_LIBS) -ludev
snmp_la_LIBADD += $(BUILD_WITH_LIBSNMP_LIBS)
endif
if BUILD_WITH_LIBPTHREAD
-snmp_la_LIBADD += -lpthread
+snmp_la_LIBADD += $(PTHREAD_LIBS)
endif
endif
pkglib_LTLIBRARIES += statsd.la
statsd_la_SOURCES = statsd.c
statsd_la_LDFLAGS = $(PLUGIN_LDFLAGS)
-statsd_la_LIBADD = liblatency.la -lpthread -lm
+statsd_la_LIBADD = $(PTHREAD_LIBS) liblatency.la -lm
endif
if BUILD_PLUGIN_SWAP
if BUILD_PLUGIN_THERMAL
pkglib_LTLIBRARIES += thermal.la
-thermal_la_SOURCES = thermal.c \
- utils_ignorelist.c utils_ignorelist.h
+thermal_la_SOURCES = thermal.c
thermal_la_LDFLAGS = $(PLUGIN_LDFLAGS)
endif
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_VIRT
pkglib_LTLIBRARIES += virt.la
-virt_la_SOURCES = virt.c \
- utils_ignorelist.c utils_ignorelist.h
+virt_la_SOURCES = virt.c
virt_la_CFLAGS = $(AM_CFLAGS) \
$(BUILD_WITH_LIBVIRT_CFLAGS) $(BUILD_WITH_LIBXML2_CFLAGS)
virt_la_LIBADD = $(BUILD_WITH_LIBVIRT_LIBS) $(BUILD_WITH_LIBXML2_LIBS)
echo "$@ has some POD errors!"; false; \
fi
+AM_V_PROTOC_C = $(am__v_PROTOC_C_@AM_V@)
+am__v_PROTOC_C_ = $(am__v_PROTOC_C_@AM_DEFAULT_V@)
+am__v_PROTOC_C_0 = @echo " PROTOC-C " $@;
+am__v_PROTOC_C_1 =
+
# Protocol buffer for the "pinba" plugin.
EXTRA_DIST += pinba.proto
-if HAVE_PROTOC_C
+if BUILD_PLUGIN_PINBA
CLEANFILES += pinba.pb-c.c pinba.pb-c.h
BUILT_SOURCES += pinba.pb-c.c pinba.pb-c.h
pinba.pb-c.c pinba.pb-c.h: pinba.proto
- protoc-c -I$(srcdir) --c_out . $(srcdir)/pinba.proto
+ $(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 HAVE_PROTOC_C
+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
- protoc-c -I$(srcdir) --c_out . $(srcdir)/riemann.proto
+ $(AM_V_PROTOC_C)protoc-c -I$(srcdir) --c_out . $(srcdir)/riemann.proto
endif
install-exec-hook:
rm -f $(DESTDIR)$(sysconfdir)/collectd.conf
rm -f $(DESTDIR)$(pkgdatadir)/postgresql_default.conf;
-
+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)
+check_PROGRAMS += test_plugin_ceph
+TESTS += test_plugin_ceph
+endif
inst->state_ ## field = malloc (sizeof (*inst->state_ ## field)); \
if (inst->state_ ## field == NULL) { \
agg_instance_destroy (inst); \
+ free (inst); \
ERROR ("aggregation plugin: malloc() failed."); \
return (NULL); \
} \
switch (r.reply_type)
{
case AMQP_RESPONSE_NORMAL:
- sstrncpy (buffer, "Success", sizeof (buffer));
+ sstrncpy (buffer, "Success", buffer_size);
break;
case AMQP_RESPONSE_NONE:
- sstrncpy (buffer, "Missing RPC reply type", sizeof (buffer));
+ sstrncpy (buffer, "Missing RPC reply type", buffer_size);
break;
case AMQP_RESPONSE_LIBRARY_EXCEPTION:
return (sstrerror (r.library_error, buffer, buffer_size));
#endif
else
- sstrncpy (buffer, "End of stream", sizeof (buffer));
+ sstrncpy (buffer, "End of stream", buffer_size);
break;
case AMQP_RESPONSE_SERVER_EXCEPTION:
static int apache_read_host (user_data_t *user_data) /* {{{ */
{
- int i;
-
char *ptr;
char *saveptr;
- char *lines[16];
- int lines_num = 0;
+ char *line;
char *fields[4];
int fields_num;
ptr = st->apache_buffer;
saveptr = NULL;
- while ((lines[lines_num] = strtok_r (ptr, "\n\r", &saveptr)) != NULL)
+ while ((line = strtok_r (ptr, "\n\r", &saveptr)) != NULL)
{
ptr = NULL;
- lines_num++;
-
- if (lines_num >= 16)
- break;
- }
-
- for (i = 0; i < lines_num; i++)
- {
- fields_num = strsplit (lines[i], fields, 4);
+ fields_num = strsplit (line, fields, STATIC_ARRAY_SIZE (fields));
if (fields_num == 3)
{
- if ((strcmp (fields[0], "Total") == 0)
- && (strcmp (fields[1], "Accesses:") == 0))
- submit_derive ("apache_requests", "",
- atoll (fields[2]), st);
- else if ((strcmp (fields[0], "Total") == 0)
- && (strcmp (fields[1], "kBytes:") == 0))
- submit_derive ("apache_bytes", "",
- 1024LL * atoll (fields[2]), st);
+ if ((strcmp (fields[0], "Total") == 0) && (strcmp (fields[1], "Accesses:") == 0))
+ submit_derive ("apache_requests", "", atoll (fields[2]), st);
+ else if ((strcmp (fields[0], "Total") == 0) && (strcmp (fields[1], "kBytes:") == 0))
+ submit_derive ("apache_bytes", "", 1024LL * atoll (fields[2]), st);
}
else if (fields_num == 2)
{
if (status != 0)
{
char errbuf[1024];
- INFO ("getaddrinfo failed: %s",
+ INFO ("apcups plugin: getaddrinfo failed: %s",
(status == EAI_SYSTEM)
? sstrerror (errno, errbuf, sizeof (errbuf))
: gai_strerror (status));
if (sd < 0)
{
- DEBUG ("Unable to open a socket");
+ DEBUG ("apcups plugin: Unable to open a socket");
freeaddrinfo (ai_return);
return (-1);
}
if (status != 0) /* `connect(2)' failed */
{
char errbuf[1024];
- INFO ("connect failed: %s",
+ INFO ("apcups plugin: connect failed: %s",
sstrerror (errno, errbuf, sizeof (errbuf)));
close (sd);
return (-1);
}
- DEBUG ("Done opening a socket %i", sd);
+ DEBUG ("apcups plugin: Done opening a socket %i", sd);
return (sd);
} /* int net_open */
*/
if (status != 0)
{
- DEBUG ("apc_query_server (%s, %s) = %i",
+ 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);
/* ------------ MPL115 defines ------------ */
/* I2C address of the MPL115 sensor */
#define MPL115_I2C_ADDRESS 0x60
-
-/* register addresses */
+
+/* register addresses */
#define MPL115_ADDR_CONV 0x00
#define MPL115_ADDR_COEFFS 0x04
-
-/* register sizes */
+
+/* register sizes */
#define MPL115_NUM_CONV 4
#define MPL115_NUM_COEFFS 12
-
-/* commands / addresses */
+
+/* commands / addresses */
#define MPL115_CMD_CONVERT_PRESS 0x10
#define MPL115_CMD_CONVERT_TEMP 0x11
#define MPL115_CMD_CONVERT_BOTH 0x12
-
+
#define MPL115_CONVERSION_RETRIES 5
#define MPL3115_PT_DATA_DREM 0x04
#define MPL3115_PT_DATA_PDEF 0x02
#define MPL3115_PT_DATA_TDEF 0x01
-
+
#define MPL3115_DR_STATUS_TDR 0x02
#define MPL3115_DR_STATUS_PDR 0x04
#define MPL3115_DR_STATUS_PTDR 0x08
#define MPL3115_DR_STATUS_DR (MPL3115_DR_STATUS_TDR | MPL3115_DR_STATUS_PDR | MPL3115_DR_STATUS_PTDR)
-
+
#define MPL3115_DR_STATUS_TOW 0x20
#define MPL3115_DR_STATUS_POW 0x40
#define MPL3115_DR_STATUS_PTOW 0x80
/* I2C address of the BMP085 sensor */
#define BMP085_I2C_ADDRESS 0x77
-/* register addresses */
+/* register addresses */
#define BMP085_ADDR_ID_REG 0xD0
#define BMP085_ADDR_VERSION 0xD1
#define BMP085_ADDR_CTRL_REG 0xF4
#define BMP085_ADDR_COEFFS 0xAA
-/* register sizes */
+/* register sizes */
#define BMP085_NUM_COEFFS 22
/* commands, values */
};
static int config_keys_num = STATIC_ARRAY_SIZE(config_keys);
-
+
static char * config_device = NULL; /**< I2C bus device */
static int config_oversample = 1; /**< averaging window */
static double config_altitude = NAN; /**< altitude */
static int config_normalize = 0; /**< normalization method */
-
+
static _Bool configured = 0; /**< the whole plugin config status */
-
+
static int i2c_bus_fd = -1; /**< I2C bus device FD */
static enum Sensor_type sensor_type = Sensor_none; /**< detected/used sensor type */
static averaging_t temperature_averaging = { NULL, 0, 0L, 0 };
-/**
+/**
* Create / allocate averaging buffer
*
* The buffer is initialized with zeros.
avg->ring_buffer[avg->ring_buffer_head] = sample;
avg->ring_buffer_head = (avg->ring_buffer_head+1) % avg->ring_buffer_size;
result = (double)(avg->ring_buffer_sum) / (double)(avg->ring_buffer_size);
-
- DEBUG ("barometer: averaging_add_sample - added %ld, result = %lf",
- sample,
+
+ DEBUG ("barometer: averaging_add_sample - added %ld, result = %lf",
+ sample,
result);
return result;
list = list->next;
continue;
}
-
+
for(i=0; i<REF_TEMP_AVG_NUM*list->num_values; ++i)
{
DEBUG ("barometer: get_reference_temperature - history %zu: %lf",
}
list = list->next;
} /* while sensor list */
-
+
if(*result == NAN)
{
ERROR("barometer: get_reference_temperature - no sensor available (yet?)");
/* ------------------------ MPL115 access ------------------------ */
-/**
+/**
* Detect presence of a MPL115 pressure sensor.
*
* Unfortunately there seems to be no ID register so we just try to read first
* MPL115. We should use this check as the last resort (which would be the typical
* case anyway since MPL115 is the least accurate sensor).
* As a sideeffect will leave set I2C slave address.
- *
+ *
* @return 1 if MPL115, 0 otherwise
*/
static int MPL115_detect(void)
Pcomp = mpl115_coeffA0 + \
(mpl115_coeffB1 + mpl115_coeffC11*adc_pressure + mpl115_coeffC12*adc_temp) * adc_pressure + \
(mpl115_coeffB2 + mpl115_coeffC22*adc_temp) * adc_temp;
-
+
*pressure = ((1150.0-500.0) * Pcomp / 1023.0) + 500.0;
*temperature = (472.0 - adc_temp) / 5.35 + 25.0;
DEBUG ("barometer: MPL115_convert_adc_to_real - got %lf hPa, %lf C",
/* ------------------------ MPL3115 access ------------------------ */
-/**
+/**
* Detect presence of a MPL3115 pressure sensor by checking register "WHO AM I"
*
* As a sideeffect will leave set I2C slave address.
- *
+ *
* @return 1 if MPL3115, 0 otherwise
*/
static int MPL3115_detect(void)
return 0;
}
-/**
+/**
* Adjusts oversampling to values supported by MPL3115
*
- * MPL3115 supports only power of 2 in the range 1 to 128.
+ * MPL3115 supports only power of 2 in the range 1 to 128.
*/
static void MPL3115_adjust_oversampling(void)
{
}
DEBUG("barometer: MPL3115_adjust_oversampling - correcting oversampling from %d to %d",
- config_oversample,
+ config_oversample,
new_val);
config_oversample = new_val;
}
-/**
- * Read sensor averegaed measurements
+/**
+ * Read sensor averaged measurements
*
* @param pressure averaged measured pressure
* @param temperature averaged measured temperature
__u8 data[MPL3115_NUM_CONV_VALS];
long int tmp_value = 0;
char errbuf[1024];
-
+
/* Set Active - activate the device from standby */
res = i2c_smbus_read_byte_data(i2c_bus_fd, MPL3115_REG_CTRL_REG1);
if (res < 0)
return 1;
}
ctrl = res;
- res = i2c_smbus_write_byte_data(i2c_bus_fd,
- MPL3115_REG_CTRL_REG1,
+ res = i2c_smbus_write_byte_data(i2c_bus_fd,
+ MPL3115_REG_CTRL_REG1,
ctrl | MPL3115_CTRL_REG1_SBYB);
if (res < 0)
{
sstrerror (errno, errbuf, sizeof (errbuf)));
return 1;
}
-
+
/* base sleep is 5ms x OST */
usleep(5000 * config_oversample);
-
+
/* check the flags/status if ready */
res = i2c_smbus_read_byte_data(i2c_bus_fd, MPL3115_REG_STATUS);
if (res < 0)
sstrerror (errno, errbuf, sizeof (errbuf)));
return 1;
}
-
+
while ((res & MPL3115_DR_STATUS_DR) != MPL3115_DR_STATUS_DR)
{
/* try some extra sleep... */
usleep(10000);
-
+
/* ... and repeat the check. The conversion has to finish sooner or later. */
res = i2c_smbus_read_byte_data(i2c_bus_fd, MPL3115_REG_STATUS);
if (res < 0)
return 1;
}
}
-
+
/* Now read all the data in one block. There is address autoincrement. */
- res = i2c_smbus_read_i2c_block_data(i2c_bus_fd,
- MPL3115_REG_OUT_P_MSB,
+ res = i2c_smbus_read_i2c_block_data(i2c_bus_fd,
+ MPL3115_REG_OUT_P_MSB,
MPL3115_NUM_CONV_VALS,
data);
if (res < 0)
sstrerror (errno, errbuf, sizeof (errbuf)));
return 1;
}
-
+
tmp_value = (data[0] << 16) | (data[1] << 8) | data[2];
*pressure = ((double) tmp_value) / 4.0 / 16.0 / 100.0;
DEBUG ("barometer: MPL3115_read - absolute pressure = %lf hPa", *pressure);
-
+
if(data[3] > 0x7F)
{
data[3] = ~data[3] + 1;
{
*temperature = data[3];
}
-
+
*temperature += (double)(data[4]) / 256.0;
DEBUG ("barometer: MPL3115_read - temperature = %lf C", *temperature);
-
+
return 0;
}
-/**
+/**
* Initialize MPL3115 for barometeric measurements
- *
+ *
* @return 0 if successful
*/
static int MPL3115_init_sensor(void)
__s32 res;
__s8 offset;
char errbuf[1024];
-
+
/* Reset the sensor. It will reset immediately without ACKing */
/* the transaction, so no error handling here. */
- i2c_smbus_write_byte_data(i2c_bus_fd,
- MPL3115_REG_CTRL_REG1,
+ i2c_smbus_write_byte_data(i2c_bus_fd,
+ MPL3115_REG_CTRL_REG1,
MPL3115_CTRL_REG1_RST);
-
+
/* wait some time for the reset to finish */
usleep(100000);
/* now it should be in standby already so we can go and configure it */
-
+
/* Set temperature offset. */
/* result = ADCtemp + offset [C] */
offset = (__s8) (config_temp_offset * 16.0);
sstrerror (errno, errbuf, sizeof (errbuf)));
return -1;
}
-
+
/* Set pressure offset. */
/* result = ADCpress + offset [hPa] */
offset = (__s8) (config_press_offset * 100.0 / 4.0);
}
/* Enable Data Flags in PT_DATA_CFG - flags on both pressure and temp */
- res = i2c_smbus_write_byte_data(i2c_bus_fd,
+ res = i2c_smbus_write_byte_data(i2c_bus_fd,
MPL3115_REG_PT_DATA_CFG,
MPL3115_PT_DATA_DREM \
| MPL3115_PT_DATA_PDEF \
return -1;
}
- /* Set to barometer with an OSR */
- res = i2c_smbus_write_byte_data(i2c_bus_fd,
- MPL3115_REG_CTRL_REG1,
+ /* Set to barometer with an OSR */
+ res = i2c_smbus_write_byte_data(i2c_bus_fd,
+ MPL3115_REG_CTRL_REG1,
mpl3115_oversample);
if (res < 0)
{
/* ------------------------ BMP085 access ------------------------ */
-/**
+/**
* Detect presence of a BMP085 pressure sensor by checking its ID register
*
* As a sideeffect will leave set I2C slave address.
- *
+ *
* @return 1 if BMP085, 0 otherwise
*/
static int BMP085_detect(void)
}
-/**
+/**
* Adjusts oversampling settings to values supported by BMP085
*
- * BMP085 supports only 1,2,4 or 8 samples.
+ * BMP085 supports only 1,2,4 or 8 samples.
*/
static void BMP085_adjust_oversampling(void)
{
}
DEBUG("barometer: BMP085_adjust_oversampling - correcting oversampling from %d to %d",
- config_oversample,
+ config_oversample,
new_val);
config_oversample = new_val;
}
-/**
+/**
* Read the BMP085 sensor conversion coefficients.
*
* These are (device specific) constants so we can read them just once.
static int BMP085_read_coeffs(void)
{
__s32 res;
- __u8 coeffs[BMP085_NUM_COEFFS];
+ __u8 coeffs[BMP085_NUM_COEFFS];
char errbuf[1024];
- res = i2c_smbus_read_i2c_block_data(i2c_bus_fd,
+ res = i2c_smbus_read_i2c_block_data(i2c_bus_fd,
BMP085_ADDR_COEFFS,
- BMP085_NUM_COEFFS,
+ BMP085_NUM_COEFFS,
coeffs);
if (res < 0)
{
sstrerror (errno, errbuf, sizeof (errbuf)));
return -1;
}
-
+
bmp085_AC1 = ((int16_t) coeffs[0] <<8) | (int16_t) coeffs[1];
bmp085_AC2 = ((int16_t) coeffs[2] <<8) | (int16_t) coeffs[3];
bmp085_AC3 = ((int16_t) coeffs[4] <<8) | (int16_t) coeffs[5];
X2 = (((long)bmp085_AC2 * B6) >> 11);
X3 = X1 + X2;
B3 = (((((long)bmp085_AC1 * 4) + X3) << bmp085_oversampling) + 2) >> 2;
-
+
/* B4 */
X1 = (((long)bmp085_AC3*B6) >> 13);
X2 = (bmp085_B1*((B6*B6) >> 12) ) >> 16;
X3 = ((X1 + X2) + 2 ) >> 2;
B4 = ((long)bmp085_AC4* (unsigned long)(X3 + 32768)) >> 15;
-
+
/* B7, P */
B7 = (unsigned long)(adc_pressure - B3)*(50000>>bmp085_oversampling);
if( B7 < 0x80000000 )
X1 = (X1 * 3038) >> 16;
X2 = ((-7357) * P) >> 16;
P = P + ( ( X1 + X2 + 3791 ) >> 4);
-
- *pressure = P / 100.0; // in [hPa]
+
+ *pressure = P / 100.0; // in [hPa]
DEBUG ("barometer: BMP085_convert_adc_to_real - got %lf hPa, %lf C",
*pressure,
*temperature);
}
-
-/**
+
+/**
* Read compensated sensor measurements
*
* @param pressure averaged measured pressure
usleep(BMP085_TIME_CNV_TEMP); /* wait for the conversion */
res = i2c_smbus_read_i2c_block_data( i2c_bus_fd,
- BMP085_ADDR_CONV,
+ BMP085_ADDR_CONV,
2,
- measBuff);
+ measBuff);
if (res < 0)
{
ERROR ("barometer: BMP085_read - problem reading temperature data: %s",
return 1;
}
- adc_temperature = ( (unsigned short)measBuff[0] << 8 ) + measBuff[1];
-
+ adc_temperature = ( (unsigned short)measBuff[0] << 8 ) + measBuff[1];
+
/* get presure */
res = i2c_smbus_write_byte_data( i2c_bus_fd,
- BMP085_ADDR_CTRL_REG,
+ BMP085_ADDR_CTRL_REG,
bmp085_cmdCnvPress );
if (res < 0)
{
usleep(bmp085_timeCnvPress); /* wait for the conversion */
res = i2c_smbus_read_i2c_block_data( i2c_bus_fd,
- BMP085_ADDR_CONV,
+ BMP085_ADDR_CONV,
3,
measBuff );
if (res < 0)
}
adc_pressure = (long)((((ulong)measBuff[0]<<16) | ((ulong)measBuff[1]<<8) | (ulong)measBuff[2] ) >> (8 - bmp085_oversampling));
-
+
DEBUG ("barometer: BMP085_read - raw pressure ADC value = %ld, " \
"raw temperature ADC value = %ld",
/* ------------------------ Sensor detection ------------------------ */
-/**
+/**
* Detect presence of a supported sensor.
*
* As a sideeffect will leave set I2C slave address.
* The detection is done in the order BMP085, MPL3115, MPL115 and stops after
* first sensor beeing found.
- *
+ *
* @return detected sensor type
*/
enum Sensor_type Detect_sensor_type(void)
* - MSLP_INTERNATIONAL - see http://en.wikipedia.org/wiki/Atmospheric_pressure#Altitude_atmospheric_pressure_variation
* Requires #config_altitude
*
- * - MSLP_DEU_WETT - formula as recommended by the Deutsche Wetterdienst. See
+ * - MSLP_DEU_WETT - formula as recommended by the Deutsche Wetterdienst. See
* http://de.wikipedia.org/wiki/Barometrische_H%C3%B6henformel#Theorie
* Requires both #config_altitude and temperature reference(s).
*
case MSLP_NONE:
mean = abs_pressure;
break;
-
+
case MSLP_INTERNATIONAL:
mean = abs_pressure / \
pow(1.0 - 0.0065*config_altitude/288.15, 9.80665*0.0289644/(8.31447*0.0065));
break;
-
+
case MSLP_DEU_WETT:
{
double E; /* humidity */
break;
default:
- ERROR ("barometer: abs_to_mean_sea_level_pressure: wrong conversion method %d",
+ ERROR ("barometer: abs_to_mean_sea_level_pressure: wrong conversion method %d",
config_normalize);
mean = abs_pressure;
break;
config_normalize,
mean);
- return mean;
+ return mean;
}
/* ------------------------ main plugin callbacks ------------------------ */
-/**
+/**
* Main plugin configuration callback (using simple config)
- *
+ *
* @param key configuration key we should process
* @param value configuration value we should process
- *
+ *
* @return Zero when successful.
*/
static int collectd_barometer_config (const char *key, const char *value)
{
config_temp_offset = atof(value);
}
- else
+ else
{
return -1;
}
}
-/**
+/**
* Shutdown callback.
- *
+ *
* Close I2C and delete all the buffers.
- *
+ *
* @return Zero when successful (at the moment the only possible outcome)
*/
static int collectd_barometer_shutdown(void)
}
-/**
+/**
* Plugin read callback for MPL115.
- *
+ *
* Dispatching will create values:
* - <hostname>/barometer-mpl115/pressure-normalized
* - <hostname>/barometer-mpl115/pressure-absolute
value_list_t vl = VALUE_LIST_INIT;
value_t values[1];
-
+
DEBUG("barometer: MPL115_collectd_barometer_read");
if (!configured)
}
-/**
+/**
* Plugin read callback for MPL3115.
- *
+ *
* Dispatching will create values:
* - <hostname>/barometer-mpl3115/pressure-normalized
* - <hostname>/barometer-mpl3115/pressure-absolute
static int MPL3115_collectd_barometer_read (void)
{
int result = 0;
-
+
double pressure = 0.0;
double temperature = 0.0;
double norm_pressure = 0.0;
-
+
value_list_t vl = VALUE_LIST_INIT;
value_t values[1];
-
+
DEBUG("barometer: MPL3115_collectd_barometer_read");
-
+
if (!configured)
{
return -1;
}
-
+
result = MPL3115_read(&pressure, &temperature);
if(result)
return result;
}
-/**
+/**
* Plugin read callback for BMP085.
- *
+ *
* Dispatching will create values:
* - <hostname>/barometer-bmp085/pressure-normalized
* - <hostname>/barometer-bmp085/pressure-absolute
static int BMP085_collectd_barometer_read (void)
{
int result = 0;
-
+
double pressure = 0.0;
double temperature = 0.0;
double norm_pressure = 0.0;
-
+
value_list_t vl = VALUE_LIST_INIT;
value_t values[1];
-
+
DEBUG("barometer: BMP085_collectd_barometer_read");
-
+
if (!configured)
{
return -1;
}
-
+
result = BMP085_read(&pressure, &temperature);
if(result)
return result;
}
-/**
+/**
* Initialization callback
- *
+ *
* Check config, initialize I2C bus access, conversion coefficients and averaging
* ring buffers
- *
+ *
* @return Zero when successful.
*/
static int collectd_barometer_init (void)
case Sensor_MPL3115:
{
MPL3115_adjust_oversampling();
-
+
if(MPL3115_init_sensor())
return -1;
-
+
plugin_register_read ("barometer", MPL3115_collectd_barometer_read);
}
break;
ERROR("barometer: collectd_barometer_init pressure averaging init failed");
return -1;
}
-
+
if (averaging_create (&temperature_averaging, config_oversample))
{
ERROR("barometer: collectd_barometer_init temperature averaging init failed");
return -1;
}
-
+
if (MPL115_read_coeffs() < 0)
return -1;
-
+
plugin_register_read ("barometer", MPL115_collectd_barometer_read);
}
break;
ERROR("barometer: collectd_barometer_init - no supported sensor found");
return -1;
}
-
+
configured = 1;
return 0;
/* ------------------------ plugin register / entry point ------------------------ */
-/**
+/**
* Plugin "entry" - register all callback.
- *
+ *
*/
void module_register (void)
{
- plugin_register_config ("barometer",
- collectd_barometer_config,
- config_keys,
+ plugin_register_config ("barometer",
+ collectd_barometer_config,
+ config_keys,
config_keys_num);
plugin_register_init ("barometer", collectd_barometer_init);
plugin_register_shutdown ("barometer", collectd_barometer_shutdown);
if (tmp->name == NULL)
{
ERROR ("bind plugin: strdup failed.");
- free (tmp);
+ sfree (views);
return (-1);
}
return (-1);
}
+ sfree (url);
url = strdup (child->values[0].value.string);
} else if (strcasecmp ("OpCodes", child->key) == 0)
bind_config_set_bool ("OpCodes", &global_opcodes, child);
/**
* collectd - src/ceph.c
* Copyright (C) 2011 New Dream Network
+ * Copyright (C) 2015 Florian octo Forster
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
* Authors:
- * Colin McCabe <cmccabe@alumni.cmu.edu>
- * Dennis Zou <yunzou@cisco.com>
- * Dan Ryder <daryder@cisco.com>
+ * Colin McCabe <cmccabe at alumni.cmu.edu>
+ * Dennis Zou <yunzou at cisco.com>
+ * Dan Ryder <daryder at cisco.com>
+ * Florian octo Forster <octo at collectd.org>
**/
#define _DEFAULT_SOURCE
{
node_handler_t handler;
void * handler_arg;
- struct {
- char key[DATA_MAX_NAME_LEN];
- int key_len;
- } state[YAJL_MAX_DEPTH];
- int depth;
+
+ char *key;
+ char *stack[YAJL_MAX_DEPTH];
+ size_t depth;
};
typedef struct yajl_struct yajl_struct;
return CEPH_CB_CONTINUE;
}
+#define BUFFER_ADD(dest, src) do { \
+ size_t dest_size = sizeof (dest); \
+ strncat ((dest), (src), dest_size - strlen (dest)); \
+ (dest)[dest_size - 1] = 0; \
+} while (0)
+
static int
ceph_cb_number(void *ctx, const char *number_val, yajl_len_t number_len)
{
- yajl_struct *yajl = (yajl_struct*)ctx;
+ yajl_struct *state = (yajl_struct*) ctx;
char buffer[number_len+1];
- int i, latency_type = 0, result;
- char key[128];
+ char key[2 * DATA_MAX_NAME_LEN];
+ _Bool latency_type = 0;
+ size_t i;
+ int status;
memcpy(buffer, number_val, number_len);
buffer[sizeof(buffer) - 1] = 0;
- ssnprintf(key, yajl->state[0].key_len, "%s", yajl->state[0].key);
- for(i = 1; i < yajl->depth; i++)
+ memset (key, 0, sizeof (key));
+ for (i = 0; i < state->depth; i++)
+ {
+ if (state->stack[i] == NULL)
+ continue;
+
+ if (strlen (key) != 0)
+ BUFFER_ADD (key, ".");
+ BUFFER_ADD (key, state->stack[i]);
+ }
+
+ /* Special case for latency metrics. */
+ if ((strcmp ("avgcount", state->key) == 0)
+ || (strcmp ("sum", state->key) == 0))
{
- if((i == yajl->depth-1) && ((strcmp(yajl->state[i].key,"avgcount") == 0)
- || (strcmp(yajl->state[i].key,"sum") == 0)))
+ latency_type = 1;
+
+ /* Super-special case for filestore.journal_wr_bytes.avgcount: For
+ * some reason, Ceph schema encodes this as a count/sum pair while all
+ * other "Bytes" data (excluding used/capacity bytes for OSD space) uses
+ * a single "Derive" type. To spare further confusion, keep this KPI as
+ * the same type of other "Bytes". Instead of keeping an "average" or
+ * "rate", use the "sum" in the pair and assign that to the derive
+ * value. */
+ if (convert_special_metrics && (state->depth >= 2)
+ && (strcmp("filestore", state->stack[state->depth - 2]) == 0)
+ && (strcmp("journal_wr_bytes", state->stack[state->depth - 1]) == 0)
+ && (strcmp("avgcount", state->key) == 0))
{
- if(convert_special_metrics)
- {
- /**
- * Special case for filestore:JournalWrBytes. For some reason,
- * Ceph schema encodes this as a count/sum pair while all
- * other "Bytes" data (excluding used/capacity bytes for OSD
- * space) uses a single "Derive" type. To spare further
- * confusion, keep this KPI as the same type of other "Bytes".
- * Instead of keeping an "average" or "rate", use the "sum" in
- * the pair and assign that to the derive value.
- */
- if((strcmp(yajl->state[i-1].key, "journal_wr_bytes") == 0) &&
- (strcmp(yajl->state[i-2].key,"filestore") == 0) &&
- (strcmp(yajl->state[i].key,"avgcount") == 0))
- {
- DEBUG("ceph plugin: Skipping avgcount for filestore.JournalWrBytes");
- yajl->depth = (yajl->depth - 1);
- return CEPH_CB_CONTINUE;
- }
- }
- //probably a avgcount/sum pair. if not - we'll try full key later
- latency_type = 1;
- break;
+ DEBUG("ceph plugin: Skipping avgcount for filestore.JournalWrBytes");
+ return CEPH_CB_CONTINUE;
}
- strncat(key, ".", 1);
- strncat(key, yajl->state[i].key, yajl->state[i].key_len+1);
+ }
+ else /* not a latency type */
+ {
+ BUFFER_ADD (key, ".");
+ BUFFER_ADD (key, state->key);
}
- result = yajl->handler(yajl->handler_arg, buffer, key);
-
- if((result == RETRY_AVGCOUNT) && latency_type)
+ status = state->handler(state->handler_arg, buffer, key);
+ if((status == RETRY_AVGCOUNT) && latency_type)
{
- strncat(key, ".", 1);
- strncat(key, yajl->state[yajl->depth-1].key,
- yajl->state[yajl->depth-1].key_len+1);
- result = yajl->handler(yajl->handler_arg, buffer, key);
+ /* Add previously skipped part of the key, either "avgcount" or "sum",
+ * and try again. */
+ BUFFER_ADD (key, ".");
+ BUFFER_ADD (key, state->key);
+
+ status = state->handler(state->handler_arg, buffer, key);
}
- if(result == -ENOMEM)
+ if (status != 0)
{
- ERROR("ceph plugin: memory allocation failed");
+ ERROR("ceph plugin: JSON handler failed with status %d.", status);
return CEPH_CB_ABORT;
}
- yajl->depth = (yajl->depth - 1);
return CEPH_CB_CONTINUE;
}
static int ceph_cb_start_map(void *ctx)
{
+ yajl_struct *state = (yajl_struct*) ctx;
+
+ /* Push key to the stack */
+ if (state->depth == YAJL_MAX_DEPTH)
+ return CEPH_CB_ABORT;
+
+ state->stack[state->depth] = state->key;
+ state->depth++;
+ state->key = NULL;
+
return CEPH_CB_CONTINUE;
}
-static int
-ceph_cb_map_key(void *ctx, const unsigned char *key, yajl_len_t string_len)
+static int ceph_cb_end_map(void *ctx)
{
- yajl_struct *yajl = (yajl_struct*)ctx;
+ yajl_struct *state = (yajl_struct*) ctx;
- if((yajl->depth+1) >= YAJL_MAX_DEPTH)
- {
- ERROR("ceph plugin: depth exceeds max, aborting.");
+ /* Pop key from the stack */
+ if (state->depth == 0)
return CEPH_CB_ABORT;
- }
-
- char buffer[string_len+1];
-
- memcpy(buffer, key, string_len);
- buffer[sizeof(buffer) - 1] = 0;
- snprintf(yajl->state[yajl->depth].key, sizeof(buffer), "%s", buffer);
- yajl->state[yajl->depth].key_len = sizeof(buffer);
- yajl->depth = (yajl->depth + 1);
+ sfree (state->key);
+ state->depth--;
+ state->key = state->stack[state->depth];
+ state->stack[state->depth] = NULL;
return CEPH_CB_CONTINUE;
}
-static int ceph_cb_end_map(void *ctx)
+static int
+ceph_cb_map_key(void *ctx, const unsigned char *key, yajl_len_t string_len)
{
- yajl_struct *yajl = (yajl_struct*)ctx;
+ yajl_struct *state = (yajl_struct*) ctx;
+ size_t sz = ((size_t) string_len) + 1;
+
+ sfree (state->key);
+ state->key = malloc (sz);
+ if (state->key == NULL)
+ {
+ ERROR ("ceph plugin: malloc failed.");
+ return CEPH_CB_ABORT;
+ }
+
+ memmove (state->key, key, sz - 1);
+ state->key[sz - 1] = 0;
- yajl->depth = (yajl->depth - 1);
return CEPH_CB_CONTINUE;
}
sfree(d);
}
-/**
- * Compact ds name by removing special characters and trimming length to
- * DATA_MAX_NAME_LEN if necessary
- */
-static void compact_ds_name(char *source, char *dest)
+/* compact_ds_name removed the special characters ":", "_", "-" and "+" from the
+ * intput string. Characters following these special characters are capitalized.
+ * Trailing "+" and "-" characters are replaces with the strings "Plus" and
+ * "Minus". */
+static int compact_ds_name (char *buffer, size_t buffer_size, char const *src)
{
- int keys_num = 0, i;
- char *save_ptr = NULL, *tmp_ptr = source;
- char *keys[16];
- char len_str[3];
- char tmp[DATA_MAX_NAME_LEN];
- size_t key_chars_remaining = (DATA_MAX_NAME_LEN-1);
- int reserved = 0;
- int offset = 0;
- memset(tmp, 0, sizeof(tmp));
- if(source == NULL || dest == NULL || source[0] == '\0' || dest[0] != '\0')
- {
- return;
- }
- size_t src_len = strlen(source);
- snprintf(len_str, sizeof(len_str), "%zu", src_len);
- unsigned char append_status = 0x0;
- append_status |= (source[src_len - 1] == '-') ? 0x1 : 0x0;
- append_status |= (source[src_len - 1] == '+') ? 0x2 : 0x0;
- while ((keys[keys_num] = strtok_r(tmp_ptr, ":_-+", &save_ptr)) != NULL)
- {
- tmp_ptr = NULL;
- /** capitalize 1st char **/
- keys[keys_num][0] = toupper(keys[keys_num][0]);
- keys_num++;
- if(keys_num >= 16)
- {
- break;
- }
- }
- /** concatenate each part of source string **/
- for(i = 0; i < keys_num; i++)
+ char *src_copy;
+ size_t src_len;
+ char *ptr = buffer;
+ size_t ptr_size = buffer_size;
+ _Bool append_plus = 0;
+ _Bool append_minus = 0;
+
+ if ((buffer == NULL) || (buffer_size <= strlen ("Minus")) || (src == NULL))
+ return EINVAL;
+
+ src_copy = strdup (src);
+ src_len = strlen(src);
+
+ /* Remove trailing "+" and "-". */
+ if (src_copy[src_len - 1] == '+')
{
- strncat(tmp, keys[i], key_chars_remaining);
- key_chars_remaining -= strlen(keys[i]);
+ append_plus = 1;
+ src_len--;
+ src_copy[src_len] = 0;
}
- tmp[DATA_MAX_NAME_LEN - 1] = '\0';
- /** to coordinate limitation of length of type_instance
- * we will truncate ds_name
- * when the its length is more than
- * DATA_MAX_NAME_LEN
- */
- if(strlen(tmp) > DATA_MAX_NAME_LEN - 1)
+ else if (src_copy[src_len - 1] == '-')
{
- append_status |= 0x4;
- /** we should reserve space for
- * len_str
- */
- reserved += 2;
+ append_minus = 1;
+ src_len--;
+ src_copy[src_len] = 0;
}
- if(append_status & 0x1)
- {
- /** we should reserve space for
- * "Minus"
- */
- reserved += 5;
- }
- if(append_status & 0x2)
+
+ /* Split at special chars, capitalize first character, append to buffer. */
+ char *dummy = src_copy;
+ char *token;
+ char *save_ptr = NULL;
+ while ((token = strtok_r (dummy, ":_-+", &save_ptr)) != NULL)
{
- /** we should reserve space for
- * "Plus"
- */
- reserved += 4;
+ size_t len;
+
+ dummy = NULL;
+
+ token[0] = toupper ((int) token[0]);
+
+ assert (ptr_size > 1);
+
+ len = strlen (token);
+ if (len >= ptr_size)
+ len = ptr_size - 1;
+
+ assert (len > 0);
+ assert (len < ptr_size);
+
+ sstrncpy (ptr, token, len + 1);
+ ptr += len;
+ ptr_size -= len;
+
+ assert (*ptr == 0);
+ if (ptr_size <= 1)
+ break;
}
- snprintf(dest, DATA_MAX_NAME_LEN - reserved, "%s", tmp);
- offset = strlen(dest);
- switch (append_status)
+
+ /* Append "Plus" or "Minus" if "+" or "-" has been stripped above. */
+ if (append_plus || append_minus)
{
- case 0x1:
- memcpy(dest + offset, "Minus", 5);
- break;
- case 0x2:
- memcpy(dest + offset, "Plus", 5);
- break;
- case 0x4:
- memcpy(dest + offset, len_str, 2);
- break;
- case 0x5:
- memcpy(dest + offset, "Minus", 5);
- memcpy(dest + offset + 5, len_str, 2);
- break;
- case 0x6:
- memcpy(dest + offset, "Plus", 4);
- memcpy(dest + offset + 4, len_str, 2);
- break;
- default:
- break;
+ char const *append = "Plus";
+ if (append_minus)
+ append = "Minus";
+
+ size_t offset = buffer_size - (strlen (append) + 1);
+ if (offset > strlen (buffer))
+ offset = strlen (buffer);
+
+ sstrncpy (buffer + offset, append, buffer_size - offset);
}
+
+ sfree (src_copy);
+ return 0;
+}
+
+static _Bool has_suffix (char const *str, char const *suffix)
+{
+ size_t str_len = strlen (str);
+ size_t suffix_len = strlen (suffix);
+ size_t offset;
+
+ if (suffix_len > str_len)
+ return 0;
+ offset = str_len - suffix_len;
+
+ if (strcmp (str + offset, suffix) == 0)
+ return 1;
+
+ return 0;
+}
+
+/* count_parts returns the number of elements a "foo.bar.baz" style key has. */
+static size_t count_parts (char const *key)
+{
+ char const *ptr;
+ size_t parts_num = 0;
+
+ for (ptr = key; ptr != NULL; ptr = strchr (ptr + 1, '.'))
+ parts_num++;
+
+ return parts_num;
}
/**
* Parse key to remove "type" if this is for schema and initiate compaction
*/
-static int parse_keys(const char *key_str, char *ds_name)
+static int parse_keys (char *buffer, size_t buffer_size, const char *key_str)
{
- char *ptr, *rptr;
- size_t ds_name_len = 0;
- /**
- * allow up to 100 characters before compaction - compact_ds_name will not
- * allow more than DATA_MAX_NAME_LEN chars
- */
- int max_str_len = 100;
- char tmp_ds_name[max_str_len];
- memset(tmp_ds_name, 0, sizeof(tmp_ds_name));
- if(ds_name == NULL || key_str == NULL || key_str[0] == '\0' ||
- ds_name[0] != '\0')
- {
- return -1;
- }
- if((ptr = strchr(key_str, '.')) == NULL
- || (rptr = strrchr(key_str, '.')) == NULL)
+ char tmp[2 * buffer_size];
+
+ if (buffer == NULL || buffer_size == 0 || key_str == NULL || strlen (key_str) == 0)
+ return EINVAL;
+
+ if ((count_parts (key_str) > 2) && has_suffix (key_str, ".type"))
{
- memcpy(tmp_ds_name, key_str, max_str_len - 1);
- goto compact;
- }
+ /* strip ".type" suffix iff the key has more than two parts. */
+ size_t sz = strlen (key_str) - strlen (".type") + 1;
- ds_name_len = (rptr - ptr) > max_str_len ? max_str_len : (rptr - ptr);
- if((ds_name_len == 0) || strncmp(rptr + 1, "type", 4))
- { /** copy whole key **/
- memcpy(tmp_ds_name, key_str, max_str_len - 1);
+ if (sz > sizeof (tmp))
+ sz = sizeof (tmp);
+ sstrncpy (tmp, key_str, sz);
}
else
- {/** more than two keys **/
- memcpy(tmp_ds_name, key_str, ((rptr - key_str) > (max_str_len - 1) ?
- (max_str_len - 1) : (rptr - key_str)));
+ {
+ sstrncpy (tmp, key_str, sizeof (tmp));
}
- compact: compact_ds_name(tmp_ds_name, ds_name);
- return 0;
+ return compact_ds_name (buffer, buffer_size, tmp);
}
/**
((pc_type & PERFCOUNTER_LATENCY) ? DSET_LATENCY : DSET_BYTES);
d->ds_types[d->ds_num] = type;
- if(parse_keys(name, ds_name))
+ if (parse_keys(ds_name, sizeof (ds_name), name))
{
return 1;
}
char ds_name[DATA_MAX_NAME_LEN];
memset(ds_name, 0, sizeof(ds_name));
- if(parse_keys(key, ds_name))
+ if (parse_keys (ds_name, sizeof (ds_name), key))
{
return 1;
}
{
ERROR("ceph plugin: cconn_connect: connect(%d) failed: error %d",
fd, err);
+ close(fd);
return err;
}
err = -errno;
ERROR("ceph plugin: cconn_connect: fcntl(%d, O_NONBLOCK) error %d",
fd, err);
+ close(fd);
return err;
}
io->asok = fd;
plugin_register_read("ceph", ceph_read);
plugin_register_shutdown("ceph", ceph_shutdown);
}
+/* vim: set sw=4 sts=4 et : */
--- /dev/null
+/**
+ * collectd - src/ceph_test.c
+ * Copyright (C) 2015 Florian octo Forster
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; only version 2 of the License is applicable.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Authors:
+ * Florian octo Forster <octo at collectd.org>
+ **/
+
+#include "ceph.c" /* sic */
+#include "testing.h"
+
+struct case_s
+{
+ char *key;
+ char *value;
+};
+typedef struct case_s case_t;
+
+struct test_s
+{
+ case_t *cases;
+ size_t cases_num;
+};
+typedef struct test_s test_t;
+
+static int test_handler(void *user, char const *val, char const *key)
+{
+ test_t *t = user;
+ size_t i;
+
+ char status[1024];
+ _Bool ok;
+
+ /* special case for latency metrics. */
+ if (strcmp ("filestore.example_latency", key) == 0)
+ return RETRY_AVGCOUNT;
+
+ snprintf (status, sizeof (status), "unexpected call: test_handler(\"%s\") = \"%s\"", key, val);
+ ok = 0;
+
+ for (i = 0; i < t->cases_num; i++)
+ {
+ if (strcmp (key, t->cases[i].key) != 0)
+ continue;
+
+ if (strcmp (val, t->cases[i].value) != 0)
+ {
+ snprintf (status, sizeof (status), "test_handler(\"%s\") = \"%s\", want \"%s\"", key, val, t->cases[i].value);
+ ok = 0;
+ break;
+ }
+
+ snprintf (status, sizeof (status), "test_handler(\"%s\") = \"%s\"", key, val);
+ ok = 1;
+ break;
+ }
+
+ OK1(ok, status);
+ return ok ? 0 : -1;
+}
+
+DEF_TEST(traverse_json)
+{
+ char const *json = "{\n"
+ " \"WBThrottle\": {\n"
+ " \"bytes_dirtied\": {\n"
+ " \"type\": 2,\n"
+ " \"description\": \"Dirty data\",\n"
+ " \"nick\": \"\"\n"
+ " },\n"
+ " \"bytes_wb\": {\n"
+ " \"type\": 2,\n"
+ " \"description\": \"Written data\",\n"
+ " \"nick\": \"\"\n"
+ " },\n"
+ " \"ios_dirtied\": {\n"
+ " \"type\": 2,\n"
+ " \"description\": \"Dirty operations\",\n"
+ " \"nick\": \"\"\n"
+ " },\n"
+ " \"ios_wb\": {\n"
+ " \"type\": 2,\n"
+ " \"description\": \"Written operations\",\n"
+ " \"nick\": \"\"\n"
+ " },\n"
+ " \"inodes_dirtied\": {\n"
+ " \"type\": 2,\n"
+ " \"description\": \"Entries waiting for write\",\n"
+ " \"nick\": \"\"\n"
+ " },\n"
+ " \"inodes_wb\": {\n"
+ " \"type\": 10,\n"
+ " \"description\": \"Written entries\",\n"
+ " \"nick\": \"\"\n"
+ " }\n"
+ " },\n"
+ " \"filestore\": {\n"
+ " \"journal_wr_bytes\": {\n"
+ " \"avgcount\": 23,\n"
+ " \"sum\": 3117\n"
+ " },\n"
+ " \"example_latency\": {\n"
+ " \"avgcount\": 42,\n"
+ " \"sum\": 4711\n"
+ " }\n"
+ " }\n"
+ "}\n";
+ case_t cases[] = {
+ {"WBThrottle.bytes_dirtied.type", "2"},
+ {"WBThrottle.bytes_wb.type", "2"},
+ {"WBThrottle.ios_dirtied.type", "2"},
+ {"WBThrottle.ios_wb.type", "2"},
+ {"WBThrottle.inodes_dirtied.type", "2"},
+ {"WBThrottle.inodes_wb.type", "10"},
+ {"filestore.journal_wr_bytes", "3117"},
+ {"filestore.example_latency.avgcount", "42"},
+ {"filestore.example_latency.sum", "4711"},
+ };
+ test_t t = {cases, STATIC_ARRAY_SIZE (cases)};
+
+ yajl_struct ctx = {test_handler, &t};
+
+ yajl_handle hndl;
+#if HAVE_YAJL_V2
+ hndl = yajl_alloc (&callbacks, NULL, &ctx);
+ CHECK_ZERO (traverse_json ((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 (yajl_parse_complete (hndl));
+#endif
+
+ return 0;
+}
+
+DEF_TEST(parse_keys)
+{
+ struct {
+ char *str;
+ char *want;
+ } cases[] = {
+ {"WBThrottle.bytes_dirtied.description.bytes_wb.description.ios_dirtied.description.ios_wb.type", "WBThrottle.bytesDirtied.description.bytesWb.description.iosDirt"},
+ {"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", "Aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"},
+ {"foo:bar", "FooBar"},
+ {"foo:bar+", "FooBarPlus"},
+ {"foo:bar-", "FooBarMinus"},
+ {"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+", "AaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaPlus"},
+ {"aa.bb.cc.dd.ee.ff", "Aa.bb.cc.dd.ee.ff"},
+ {"aa.bb.cc.dd.ee.ff.type", "Aa.bb.cc.dd.ee.ff"},
+ {"aa.type", "Aa.type"},
+ {"WBThrottle.bytes_dirtied.type", "WBThrottle.bytesDirtied"},
+ };
+ size_t i;
+
+ for (i = 0; i < STATIC_ARRAY_SIZE (cases); i++)
+ {
+ char got[DATA_MAX_NAME_LEN];
+
+ CHECK_ZERO (parse_keys (got, sizeof (got), cases[i].str));
+ EXPECT_EQ_STR (cases[i].want, got);
+ }
+
+ return 0;
+}
+
+int main (void)
+{
+ RUN_TEST(traverse_json);
+ RUN_TEST(parse_keys);
+
+ END_TEST;
+}
+
+/* vim: set sw=2 sts=2 et : */
=head1 DESCRIPTION
-The C<exec plugin> forks of an executable either to receive values or to
+The C<exec plugin> forks off an executable either to receive values or to
dispatch notifications to the outside world. The syntax of the configuration is
explained in L<collectd.conf(5)> but summarized in the above synopsis.
See L<EXEC DATA FORMAT> below for a description of the output format expected
from these programs.
-B<Warning:> If the executable only writes one value and then exits I will be
+B<Warning:> If the executable only writes one value and then exits it will be
executed every I<Interval> seconds. If I<Interval> is short (the default is 10
seconds) this may result in serious system load.
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
strncpy (vl->identifier.type,
(vl->values_types[0] == LCC_TYPE_GAUGE) ? "gauge" : "derive",
sizeof (vl->identifier.type));
+ vl->identifier.type[sizeof (vl->identifier.type) - 1] = 0;
snprintf (vl->identifier.type_instance, sizeof (vl->identifier.type_instance),
"ti%li", random ());
#@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
#<Plugin "battery">
# ValuesPercentage false
-# ReportDegraded
+# ReportDegraded false
#</Plugin>
#<Plugin "bind">
#<Plugin interface>
# Interface "eth0"
# IgnoreSelected false
+# UniqueName false
#</Plugin>
#<Plugin ipmi>
# 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"
# 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
# Host "localhost"
# Port "2003"
# Protocol "tcp"
+# ReconnectInterval 0
# LogSendErrors true
# Prefix "collectd"
# Postfix "collectd"
When set to B<true>, various statistics about the I<collectd> daemon will be
collected, with "collectd" as the I<plugin name>. Defaults to B<false>.
-The "write_queue" I<plugin instance> reports the number of elements currently
-queued and the number of elements dropped off the queue by the
-B<WriteQueueLimitLow>/B<WriteQueueLimitHigh> mechanism.
+The following metrics are reported:
-The "cache" I<plugin instance> reports the number of elements in the value list
-cache (the cache you can interact with using L<collectd-unixsock(5)>).
+=over 4
+
+=item C<collectd-write_queue/queue_length>
+
+The number of metrics currently in the write queue. You can limit the queue
+length with the B<WriteQueueLimitLow> and B<WriteQueueLimitHigh> options.
+
+=item C<collectd-write_queue/derive-dropped>
+
+The number of metrics dropped due to a queue length limitation.
+If this value is non-zero, your system can't handle all incoming metrics and
+protects itself against overload by dropping metrics.
+
+=item C<collectd-cache/cache_size>
+
+The number of elements in the metric cache (the cache you can interact with
+using L<collectd-unixsock(5)>).
+
+=back
=item B<Include> I<Path> [I<pattern>]
B<Interface> is inverted: All selected interfaces are ignored and all
other interfaces are collected.
+=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>
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>
=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>
=over 4
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
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, create a C<count> metric which reports the change since the last
+read. This option primarily exists for compatibility with the I<statsd>
+impelemtation by Etsy.
+
=item B<TimerPercentile> I<Percent>
Calculate and dispatch the configured percentile, i.e. compute the latency, so
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>.
Timeout 1000
Prefix "collectd/"
Database 1
+ MaxSetSize -1
+ StoreRates true
</Node>
</Plugin>
C<ZRANGEBYSCORE> I<Redis> command. Additionally, all the identifiers of these
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
+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.
=item B<Database> I<Index>
-This index selects the redis database to use for writing operations. Defaults to C<0>.
+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
=item B<AlwaysAppendDS> B<false>|B<true>
-If set the B<true>, append the name of the I<Data Source> (DS) to the
+If set to B<true>, append the name of the I<Data Source> (DS) to the
"service", i.e. the field that, together with the "host" field, uniquely
identifies a metric in I<Riemann>. If set to B<false> (the default), this is
only done when there is more than one DS.
static int daemonize (void)
{
struct rlimit rl;
+ int status;
pid_t pid = 0;
int i = 0;
close (i);
errno = 0;
- if (open ("/dev/null", O_RDWR) != 0) {
+ status = open ("/dev/null", O_RDWR);
+ if (status != 0) {
syslog (LOG_ERR, "Error: couldn't connect STDIN to /dev/null: %s",
strerror (errno));
return -1;
}
errno = 0;
- if (dup (0) != 1) {
+ status = dup (0);
+ if (status != 1) {
syslog (LOG_ERR, "Error: couldn't connect STDOUT to /dev/null: %s",
strerror (errno));
return -1;
}
errno = 0;
- if (dup (0) != 2) {
+ status = dup (0);
+ if (status != 2) {
syslog (LOG_ERR, "Error: couldn't connect STDERR to /dev/null: %s",
strerror (errno));
return -1;
port_host = mach_host_self ();
- /* FIXME: Free `cpu_list' if it's not NULL */
- if ((status = host_processors (port_host, &cpu_list, &cpu_list_len)) != KERN_SUCCESS)
+ status = host_processors (port_host, &cpu_list, &cpu_list_len);
+ if (status == KERN_INVALID_ARGUMENT)
{
- ERROR ("cpu plugin: host_processors returned %i", (int) status);
+ ERROR ("cpu plugin: Don't have a privileged host control port. "
+ "The most common cause for this problem is "
+ "that collectd is running without root "
+ "privileges, which are required to read CPU "
+ "load information. "
+ "<https://collectd.org/bugs/22>");
+ cpu_list_len = 0;
+ return (-1);
+ }
+ if (status != KERN_SUCCESS)
+ {
+ ERROR ("cpu plugin: host_processors() failed with status %d.", (int) status);
cpu_list_len = 0;
return (-1);
}
- DEBUG ("host_processors returned %i %s", (int) cpu_list_len, cpu_list_len == 1 ? "processor" : "processors");
INFO ("cpu plugin: Found %i processor%s.", (int) cpu_list_len, cpu_list_len == 1 ? "" : "s");
/* #endif PROCESSOR_CPU_LOAD_INFO */
&& (ds->ds[i].type != DS_TYPE_GAUGE)
&& (ds->ds[i].type != DS_TYPE_DERIVE)
&& (ds->ds[i].type != DS_TYPE_ABSOLUTE))
+ {
+ sfree (rates);
return (-1);
+ }
- if (ds->ds[i].type == DS_TYPE_GAUGE)
+ if (ds->ds[i].type == DS_TYPE_GAUGE)
{
status = ssnprintf (buffer + offset, buffer_len - offset,
",%lf", vl->values[i].gauge);
- }
+ }
else if (store_rates != 0)
{
if (rates == NULL)
return (len);
#endif
- if (status != yajl_status_ok)
- {
- unsigned char *msg =
- yajl_get_error(db->yajl, /* verbose = */ 1,
- /* jsonText = */ (unsigned char *) buf, (unsigned int) len);
- ERROR ("curl_json plugin: yajl_parse failed: %s", msg);
- yajl_free_error(db->yajl, msg);
- return (0); /* abort write callback */
- }
-
- return (len);
+ unsigned char *msg = yajl_get_error(db->yajl, /* verbose = */ 1,
+ /* jsonText = */ (unsigned char *) buf, (unsigned int) len);
+ ERROR ("curl_json plugin: yajl_parse failed: %s", msg);
+ yajl_free_error(db->yajl, msg);
+ return (0); /* abort write callback */
} /* }}} size_t cj_curl_callback */
static int cj_get_type (cj_key_t *key)
break;
} /* for (i = 0; i < ci->children_num; i++) */
- while (status == 0)
+ if (status != 0)
{
- if (key->type == NULL)
- {
- WARNING ("curl_json plugin: `Type' missing in `Key' block.");
- status = -1;
- }
+ cj_key_free (key);
+ return (-1);
+ }
- break;
- } /* while (status == 0) */
+ if (key->type == NULL)
+ {
+ WARNING ("curl_json plugin: `Type' missing in `Key' block.");
+ cj_key_free (key);
+ return (-1);
+ }
/* store path in a tree that will match the json map structure, example:
* "httpd/requests/count",
* "httpd/requests/current" ->
* { "httpd": { "requests": { "count": $key, "current": $key } } }
*/
- if (status == 0)
+ char *ptr;
+ char *name;
+ c_avl_tree_t *tree;
+
+ if (db->tree == NULL)
+ db->tree = cj_avl_create();
+
+ tree = db->tree;
+ ptr = key->path;
+ if (*ptr == '/')
+ ++ptr;
+
+ name = ptr;
+ while ((ptr = strchr (name, '/')) != NULL)
{
- char *ptr;
- char *name;
char ent[PATH_MAX];
- c_avl_tree_t *tree;
+ c_avl_tree_t *value;
+ size_t len;
- if (db->tree == NULL)
- db->tree = cj_avl_create();
+ len = ptr - name;
+ if (len == 0)
+ break;
- tree = db->tree;
- ptr = key->path;
- if (*ptr == '/')
- ++ptr;
+ len = COUCH_MIN(len, sizeof (ent)-1);
+ sstrncpy (ent, name, len+1);
- name = ptr;
- while (*ptr)
+ if (c_avl_get (tree, ent, (void *) &value) != 0)
{
- if (*ptr == '/')
- {
- c_avl_tree_t *value;
- size_t len;
-
- len = ptr-name;
- if (len == 0)
- break;
- len = COUCH_MIN(len, sizeof (ent)-1);
- sstrncpy (ent, name, len+1);
-
- if (c_avl_get (tree, ent, (void *) &value) != 0)
- {
- value = cj_avl_create ();
- c_avl_insert (tree, strdup (ent), value);
- }
-
- tree = value;
- name = ptr+1;
- }
- ++ptr;
- }
- if (*name)
- c_avl_insert (tree, strdup(name), key);
- else
- {
- ERROR ("curl_json plugin: invalid key: %s", key->path);
- status = -1;
+ value = cj_avl_create ();
+ c_avl_insert (tree, strdup (ent), value);
}
+
+ tree = value;
+ name = ptr + 1;
+ }
+
+ if (strlen (name) == 0)
+ {
+ ERROR ("curl_json plugin: invalid key: %s", key->path);
+ cj_key_free (key);
+ return (-1);
}
+ c_avl_insert (tree, strdup (name), key);
return (status);
} /* }}} int cj_config_add_key */
sstrncpy (xpath->values[i].path, ci->values[i].value.string, sizeof (xpath->values[i].path));
}
- return (0);
+ return (0);
} /* }}} cx_config_add_values */
-static int cx_config_add_xpath (cx_t *db, /* {{{ */
- oconfig_item_t *ci)
+static int cx_config_add_xpath (cx_t *db, oconfig_item_t *ci) /* {{{ */
{
cx_xpath_t *xpath;
+ char *name;
+ llentry_t *le;
int status;
int i;
- xpath = (cx_xpath_t *) malloc (sizeof (*xpath));
+ xpath = malloc (sizeof (*xpath));
if (xpath == NULL)
{
ERROR ("curl_xml plugin: malloc failed.");
status = cf_util_get_string (ci, &xpath->path);
if (status != 0)
{
- sfree (xpath);
+ cx_xpath_free (xpath);
return (status);
}
/* error out if xpath->path is an empty string */
- if (*xpath->path == 0)
+ if (strlen (xpath->path) == 0)
{
ERROR ("curl_xml plugin: invalid xpath. "
"xpath value can't be an empty string");
+ cx_xpath_free (xpath);
return (-1);
}
break;
} /* for (i = 0; i < ci->children_num; i++) */
- if (status == 0 && xpath->type == NULL)
+ if (status != 0)
{
- WARNING ("curl_xml plugin: `Type' missing in `xpath' block.");
- status = -1;
+ cx_xpath_free (xpath);
+ return status;
}
- if (status == 0)
+ if (xpath->type == NULL)
{
- char *name;
- llentry_t *le;
+ WARNING ("curl_xml plugin: `Type' missing in `xpath' block.");
+ cx_xpath_free (xpath);
+ return -1;
+ }
+ if (db->list == NULL)
+ {
+ db->list = llist_create();
if (db->list == NULL)
{
- db->list = llist_create();
- if (db->list == NULL)
- {
- ERROR ("curl_xml plugin: list creation failed.");
- return (-1);
- }
- }
-
- name = strdup(xpath->path);
- if (name == NULL)
- {
- ERROR ("curl_xml plugin: strdup failed.");
- return (-1);
- }
-
- le = llentry_create (name, xpath);
- if (le == NULL)
- {
- ERROR ("curl_xml plugin: llentry_create failed.");
+ ERROR ("curl_xml plugin: list creation failed.");
+ cx_xpath_free (xpath);
return (-1);
}
+ }
+
+ name = strdup (xpath->path);
+ if (name == NULL)
+ {
+ ERROR ("curl_xml plugin: strdup failed.");
+ cx_xpath_free (xpath);
+ return (-1);
+ }
- llist_append (db->list, le);
+ le = llentry_create (name, xpath);
+ if (le == NULL)
+ {
+ ERROR ("curl_xml plugin: llentry_create failed.");
+ cx_xpath_free (xpath);
+ sfree (name);
+ return (-1);
}
- return (status);
+ llist_append (db->list, le);
+ return (0);
} /* }}} int cx_config_add_xpath */
static int cx_config_add_namespace (cx_t *db, /* {{{ */
libmetadata_la_SOURCES = meta_data.c meta_data.h
-libplugin_mock_la_SOURCES = plugin_mock.c utils_cache_mock.c utils_time_mock.c
-libplugin_mock_la_LIBADD = $(COMMON_LIBS)
+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 \
plugin.c plugin.h \
utils_cache.c utils_cache.h \
utils_complain.c utils_complain.h \
+ utils_ignorelist.c utils_ignorelist.h \
utils_llist.c utils_llist.h \
utils_random.c utils_random.h \
utils_tail_match.c utils_tail_match.h \
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
+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_subst_SOURCES = utils_subst_test.c ../testing.h \
utils_subst.c utils_subst.h
-test_utils_subst_LDADD = libcommon.la libplugin_mock.la
+test_utils_subst_LDADD = libplugin_mock.la
#if HAVE_SETLOCALE
if (setlocale (LC_NUMERIC, COLLECTD_LOCALE) == NULL)
WARNING ("setlocale (\"%s\") failed.", COLLECTD_LOCALE);
+
+ /* Update the environment, so that libraries that are calling
+ * setlocale(LC_NUMERIC, "") don't accidentally revert these changes. */
+ unsetenv ("LC_ALL");
+ setenv ("LC_NUMERIC", COLLECTD_LOCALE, /* overwrite = */ 1);
#endif
#if HAVE_LIBKSTAT
unsetenv ("NOTIFY_SOCKET");
+#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",
}
else
{
-#if KERNEL_LINUX
/* 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
su_size = sizeof (sa_family_t) + strlen (notifysocket);
if (su_size > sizeof (su))
su_size = sizeof (su);
-#else
- ERROR ("Systemd socket uses Linux abstract namespace notation (\"%s\"), "
- "but I don't appear to be running on Linux.", notifysocket);
- return 0;
-#endif
}
if (sendto (fd, buffer, strlen (buffer), MSG_NOSIGNAL, (void *) &su, (socklen_t) su_size) < 0)
return 0;
}
+ unsetenv ("NOTIFY_SOCKET");
close(fd);
return 1;
}
#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) */
#include <sys/types.h>
#include <netdb.h>
+#include <poll.h>
+
#if HAVE_NETINET_IN_H
# include <netinet/in.h>
#endif
const char *ptr;
size_t nleft;
ssize_t status;
+ struct pollfd pfd;
ptr = (const char *) buf;
nleft = count;
+
+ /* checking for closed peer connection */
+ pfd.fd = fd;
+ pfd.events = POLLIN | POLLHUP;
+ pfd.revents = 0;
+ if (poll(&pfd, 1, 0) > 0) {
+ char buffer[32];
+ if (recv(fd, buffer, sizeof(buffer), MSG_PEEK | MSG_DONTWAIT) == 0) {
+ // if recv returns zero (even though poll() said there is data to be read),
+ // that means the connection has been closed
+ return -1;
+ }
+ }
while (nleft > 0)
{
char *ptr;
char *saveptr;
+ if ((buffer == NULL) || (vl == NULL) || (ds == NULL))
+ return EINVAL;
+
i = 0;
dummy = buffer;
saveptr = NULL;
* Florian octo Forster <octo at collectd.org>
*/
-#include "testing.h"
#include "common.h"
+#include "testing.h"
#if HAVE_LIBKSTAT
kstat_ctl_t *kc;
if (root == NULL)
{
ERROR ("configfile: malloc failed.");
+ closedir (dh);
return (NULL);
}
memset (root, 0, sizeof (oconfig_item_t));
ERROR ("configfile: Not including `%s/%s' because its"
" name is too long.",
dir, de->d_name);
+ closedir (dh);
for (i = 0; i < filenames_num; ++i)
free (filenames[i]);
free (filenames);
filenames_num * sizeof (*filenames));
if (tmp == NULL) {
ERROR ("configfile: realloc failed.");
+ closedir (dh);
for (i = 0; i < filenames_num - 1; ++i)
free (filenames[i]);
free (filenames);
}
if (filenames == NULL)
+ {
+ closedir (dh);
return (root);
+ }
qsort ((void *) filenames, filenames_num, sizeof (*filenames),
cf_compare_string);
free (name);
}
+ closedir (dh);
free(filenames);
return (root);
} /* oconfig_item_t *cf_read_dir */
-/*
+/*
* cf_read_generic
*
* Path is stat'ed and either cf_read_file or cf_read_dir is called
{
fc_rule_t *rule;
fc_target_t *target;
- int status;
+ int status = FC_TARGET_CONTINUE;
if (chain == NULL)
return (-1);
DEBUG ("fc_process_chain (chain = %s);", chain->name);
- status = FC_TARGET_CONTINUE;
for (rule = chain->rules; rule != NULL; rule = rule->next)
{
fc_match_t *match;
+ status = FC_TARGET_CONTINUE;
if (rule->name[0] != 0)
{
}
}
- if ((status == FC_TARGET_STOP)
- || (status == FC_TARGET_RETURN))
+ if ((status == FC_TARGET_STOP) || (status == FC_TARGET_RETURN))
{
if (rule->name[0] != 0)
{
}
break;
}
- else
- {
- status = FC_TARGET_CONTINUE;
- }
} /* for (rule) */
- if (status == FC_TARGET_STOP)
- return (FC_TARGET_STOP);
- else if (status == FC_TARGET_RETURN)
- return (FC_TARGET_CONTINUE);
-
- /* for-loop has been aborted: A target returned `FC_TARGET_STOP' */
- if (rule != NULL)
- return (FC_TARGET_CONTINUE);
+ if ((status == FC_TARGET_STOP) || (status == FC_TARGET_RETURN))
+ return (status);
DEBUG ("fc_process_chain (%s): Executing the default targets.",
chain->name);
return (NULL);
copy = md_entry_alloc (orig->key);
+ if (copy == NULL)
+ return (NULL);
copy->type = orig->type;
if (copy->type == MD_TYPE_STRING)
copy->value.mv_string = strdup (orig->value.mv_string);
if (md == NULL)
return;
- pthread_mutex_destroy(&md->lock);
md_entry_free (md->head);
pthread_mutex_destroy (&md->lock);
free (md);
* Florian octo Forster <octo at collectd.org>
*/
-#include "testing.h"
-#include "collectd.h"
#include "common.h" /* for STATIC_ARRAY_SIZE */
+#include "collectd.h"
+#include "testing.h"
#include "meta_data.h"
DEF_TEST(base)
{
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, /* {{{ */
{
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));
*/
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)
if (cb == NULL) return;
- sfree(cb->name);
- sfree(cb);
+ sfree (cb->name);
+ sfree (cb);
} /* static void plugin_flush_callback_free */
static char *plugin_flush_callback_name (const char *name)
if (cb == NULL)
{
ERROR ("plugin_register_flush: malloc failed.");
- sfree(flush_name);
+ sfree (flush_name);
return (-1);
}
if (cb->name == NULL)
{
ERROR ("plugin_register_flush: strdup failed.");
- sfree(cb);
- sfree(flush_name);
+ sfree (cb);
+ sfree (flush_name);
return (-1);
}
cb->timeout = ctx.flush_timeout;
/* interval = */ ctx.flush_interval,
/* user data = */ &ud);
- sfree(flush_name);
+ sfree (flush_name);
if (status != 0)
{
- sfree(cb->name);
- sfree(cb);
+ sfree (cb->name);
+ sfree (cb);
return status;
}
}
* ds->ds_num);
if (ds_copy->ds == NULL)
{
- free (ds_copy);
+ sfree (ds_copy);
return (-1);
}
if (flush_name != NULL)
{
plugin_unregister_read(flush_name);
- sfree(flush_name);
+ sfree (flush_name);
}
}
write_threads_num = 5;
}
- start_write_threads ((size_t) write_threads_num);
-
if ((list_init == NULL) && (read_heap == NULL))
return;
le = le->next;
}
+ start_write_threads ((size_t) write_threads_num);
+
max_read_interval = global_option_get_time ("MaxReadInterval",
DEFAULT_MAX_READ_INTERVAL);
* 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;
}
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 */
kstat_ctl_t *kc = NULL;
#endif /* HAVE_LIBKSTAT */
+char hostname_g[] = "example.com";
+
+int plugin_register_complex_config (const char *type, int (*callback) (oconfig_item_t *))
+{
+ return ENOTSUP;
+}
+
+int plugin_register_init (const char *name, plugin_init_cb callback)
+{
+ return ENOTSUP;
+}
+
+int plugin_register_read (const char *name, int (*callback) (void))
+{
+ return ENOTSUP;
+}
+
+int plugin_register_shutdown (const char *name, int (*callback) (void))
+{
+ return ENOTSUP;
+}
+
+int plugin_dispatch_values (value_list_t const *vl)
+{
+ return ENOTSUP;
+}
+
void plugin_log (int level, char const *format, ...)
{
char buffer[1024];
printf ("plugin_log (%i, \"%s\");\n", level, buffer);
}
+cdtime_t plugin_get_interval (void)
+{
+ return TIME_T_TO_CDTIME_T (10);
+}
+
/* vim: set sw=2 sts=2 et : */
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 #%zu "
"of data set %s", i, ds->type);
+ sfree (ds->ds);
+ sfree (ds);
return;
}
*value = n->value;
free_node (n);
+ --t->size;
rebalance (t, p);
return (0);
* 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);
/ CDTIME_T_TO_DOUBLE (vl->interval);
ce->values_raw[i].absolute = vl->values[i].absolute;
break;
-
+
default:
/* This shouldn't happen. */
ERROR ("uc_insert: Don't know how to handle data source type %i.",
ds->ds[i].type);
sfree (key_copy);
+ cache_free (ce);
return (-1);
} /* switch (ds->ds[i].type) */
} /* for (i) */
* 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)
--- /dev/null
+/**
+ * collectd - src/utils_ignorelist.c
+ * Copyright (C) 2006 Lubos Stanek <lubek at users.sourceforge.net>
+ * Copyright (C) 2008 Florian Forster <octo at collectd.org>
+ *
+ * This program is free software; you can redistribute it and/
+ * or modify it under the terms of the GNU General Public Li-
+ * cence as published by the Free Software Foundation; either
+ * version 2 of the Licence, or any later version.
+ *
+ * This program is distributed in the hope that it will be use-
+ * ful, but WITHOUT ANY WARRANTY; without even the implied war-
+ * ranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public Licence for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * Licence along with this program; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139,
+ * USA.
+ *
+ * Authors:
+ * Lubos Stanek <lubek at users.sourceforge.net>
+ * Florian Forster <octo at collectd.org>
+ **/
+/**
+ * ignorelist handles plugin's list of configured collectable
+ * entries with global ignore action
+ **/
+/**
+ * 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),
+ * allocate the variable with:
+ * myconfig_ignore = ignorelist_create (YourKnownIgnore);
+ * If you do not know the state of the global ignore,
+ * initialize the global variable and set the ignore flag later:
+ * myconfig_ignore = ignorelist_init ();
+ * Append single entries in your cf_register'ed callback function:
+ * ignorelist_add (myconfig_ignore, newentry);
+ * When you hit the IgnoreSelected config option,
+ * offer it to the list:
+ * ignorelist_ignore (myconfig_ignore, instantly_got_value_of_ignore);
+ * That is all for the ignorelist initialization.
+ * Later during read and write (plugin's registered functions) get
+ * the information whether this entry would be collected or not:
+ * if (ignorelist_match (myconfig_ignore, thisentry))
+ * return;
+ **/
+
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include "common.h"
+#include "plugin.h"
+#include "utils_ignorelist.h"
+
+/*
+ * private prototypes
+ */
+struct ignorelist_item_s
+{
+#if HAVE_REGEX_H
+ regex_t *rmatch; /* regular expression entry identification */
+#endif
+ char *smatch; /* string entry identification */
+ struct ignorelist_item_s *next;
+};
+typedef struct ignorelist_item_s ignorelist_item_t;
+
+struct ignorelist_s
+{
+ int ignore; /* ignore entries */
+ ignorelist_item_t *head; /* pointer to the first entry */
+};
+
+/* *** *** *** ********************************************* *** *** *** */
+/* *** *** *** *** *** *** private functions *** *** *** *** *** *** */
+/* *** *** *** ********************************************* *** *** *** */
+
+static inline void ignorelist_append (ignorelist_t *il, ignorelist_item_t *item)
+{
+ assert ((il != NULL) && (item != NULL));
+
+ item->next = il->head;
+ il->head = item;
+}
+
+#if HAVE_REGEX_H
+static int ignorelist_append_regex(ignorelist_t *il, const char *re_str)
+{
+ regex_t *re;
+ ignorelist_item_t *entry;
+ int status;
+
+ re = malloc (sizeof (*re));
+ if (re == NULL)
+ {
+ ERROR ("ignorelist_append_regex: malloc failed.");
+ return (ENOMEM);
+ }
+ memset (re, 0, sizeof (*re));
+
+ status = regcomp (re, re_str, REG_EXTENDED);
+ if (status != 0)
+ {
+ char errbuf[1024];
+ (void) regerror (status, re, errbuf, sizeof (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);
+ }
+
+ entry = malloc (sizeof (*entry));
+ if (entry == NULL)
+ {
+ ERROR ("ignorelist_append_regex: malloc failed.");
+ regfree (re);
+ sfree (re);
+ return (ENOMEM);
+ }
+ memset (entry, 0, sizeof (*entry));
+ entry->rmatch = re;
+
+ ignorelist_append (il, entry);
+ return (0);
+} /* 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 )
+ {
+ ERROR ("cannot allocate new entry");
+ return (1);
+ }
+ memset (new, '\0', sizeof(ignorelist_item_t));
+ new->smatch = sstrdup(entry);
+
+ /* append new entry */
+ ignorelist_append (il, new);
+
+ return (0);
+} /* int ignorelist_append_string(ignorelist_t *il, const char *entry) */
+
+#if HAVE_REGEX_H
+/*
+ * check list for entry regex match
+ * return 1 if found
+ */
+static int ignorelist_match_regex (ignorelist_item_t *item, const char *entry)
+{
+ assert ((item != NULL) && (item->rmatch != NULL)
+ && (entry != NULL) && (strlen (entry) > 0));
+
+ /* match regex */
+ if (regexec (item->rmatch, entry, 0, NULL, 0) == 0)
+ return (1);
+
+ return (0);
+} /* int ignorelist_match_regex (ignorelist_item_t *item, const char *entry) */
+#endif
+
+/*
+ * check list for entry string match
+ * return 1 if found
+ */
+static int ignorelist_match_string (ignorelist_item_t *item, const char *entry)
+{
+ assert ((item != NULL) && (item->smatch != NULL)
+ && (entry != NULL) && (strlen (entry) > 0));
+
+ if (strcmp (entry, item->smatch) == 0)
+ return (1);
+
+ return (0);
+} /* int ignorelist_match_string (ignorelist_item_t *item, const char *entry) */
+
+
+/* *** *** *** ******************************************** *** *** *** */
+/* *** *** *** *** *** *** public functions *** *** *** *** *** *** */
+/* *** *** *** ******************************************** *** *** *** */
+
+/*
+ * create the ignorelist_t with known ignore state
+ * return pointer to ignorelist_t
+ */
+ignorelist_t *ignorelist_create (int invert)
+{
+ ignorelist_t *il;
+
+ il = malloc (sizeof (*il));
+ if (il == NULL)
+ return NULL;
+ memset (il, 0, sizeof (*il));
+
+ /*
+ * ->ignore == 0 => collect
+ * ->ignore == 1 => ignore
+ */
+ il->ignore = invert ? 0 : 1;
+
+ return (il);
+} /* ignorelist_t *ignorelist_create (int ignore) */
+
+/*
+ * free memory used by ignorelist_t
+ */
+void ignorelist_free (ignorelist_t *il)
+{
+ ignorelist_item_t *this;
+ ignorelist_item_t *next;
+
+ if (il == NULL)
+ return;
+
+ for (this = il->head; this != NULL; this = next)
+ {
+ next = this->next;
+#if HAVE_REGEX_H
+ if (this->rmatch != NULL)
+ {
+ regfree (this->rmatch);
+ sfree (this->rmatch);
+ this->rmatch = NULL;
+ }
+#endif
+ if (this->smatch != NULL)
+ {
+ sfree (this->smatch);
+ this->smatch = NULL;
+ }
+ sfree (this);
+ }
+
+ sfree (il);
+ il = NULL;
+} /* void ignorelist_destroy (ignorelist_t *il) */
+
+/*
+ * set ignore state of the ignorelist_t
+ */
+void ignorelist_set_invert (ignorelist_t *il, int invert)
+{
+ if (il == NULL)
+ {
+ DEBUG("ignore call with ignorelist_t == NULL");
+ return;
+ }
+
+ il->ignore = invert ? 0 : 1;
+} /* void ignorelist_set_invert (ignorelist_t *il, int ignore) */
+
+/*
+ * append entry into ignorelist_t
+ * return 0 for success
+ */
+int ignorelist_add (ignorelist_t *il, const char *entry)
+{
+ size_t len;
+
+ if (il == NULL)
+ {
+ DEBUG ("add called with ignorelist_t == NULL");
+ return (1);
+ }
+
+ len = strlen (entry);
+
+ /* append nothing */
+ if (len == 0)
+ {
+ DEBUG("not appending: empty entry");
+ return (1);
+ }
+
+#if HAVE_REGEX_H
+ /* regex string is enclosed in "/.../" */
+ if ((len > 2) && (entry[0] == '/') && entry[len - 1] == '/')
+ {
+ char *copy;
+ int status;
+
+ /* skip leading slash */
+ copy = strdup (entry + 1);
+ if (copy == NULL)
+ return ENOMEM;
+
+ /* trim trailing slash */
+ copy[strlen (copy) - 1] = 0;
+
+ status = ignorelist_append_regex (il, copy);
+ sfree (copy);
+ return status;
+ }
+#endif
+
+ return ignorelist_append_string(il, entry);
+} /* int ignorelist_add (ignorelist_t *il, const char *entry) */
+
+/*
+ * check list for entry
+ * return 1 for ignored entry
+ */
+int ignorelist_match (ignorelist_t *il, const char *entry)
+{
+ ignorelist_item_t *traverse;
+
+ /* if no entries, collect all */
+ if ((il == NULL) || (il->head == NULL))
+ return (0);
+
+ if ((entry == NULL) || (strlen (entry) == 0))
+ return (0);
+
+ /* traverse list and check entries */
+ for (traverse = il->head; traverse != NULL; traverse = traverse->next)
+ {
+#if HAVE_REGEX_H
+ if (traverse->rmatch != NULL)
+ {
+ if (ignorelist_match_regex (traverse, entry))
+ return (il->ignore);
+ }
+ else
+#endif
+ {
+ if (ignorelist_match_string (traverse, entry))
+ return (il->ignore);
+ }
+ } /* for traverse */
+
+ return (1 - il->ignore);
+} /* int ignorelist_match (ignorelist_t *il, const char *entry) */
+
--- /dev/null
+/**
+ * collectd - src/utils_ignorelist.h
+ * Copyright (C) 2006 Lubos Stanek <lubek at users.sourceforge.net>
+ *
+ * This program is free software; you can redistribute it and/
+ * or modify it under the terms of the GNU General Public Li-
+ * cence as published by the Free Software Foundation; either
+ * version 2 of the Licence, or any later version.
+ *
+ * This program is distributed in the hope that it will be use-
+ * ful, but WITHOUT ANY WARRANTY; without even the implied war-
+ * ranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public Licence for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * Licence along with this program; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139,
+ * USA.
+ *
+ * Authors:
+ * Lubos Stanek <lubek at users.sourceforge.net>
+ **/
+/**
+ * ignorelist handles plugin's list of configured collectable
+ * entries with global ignore action
+ **/
+
+#ifndef UTILS_IGNORELIST_H
+#define UTILS_IGNORELIST_H 1
+
+#include "collectd.h"
+
+#if HAVE_REGEX_H
+# include <regex.h>
+#endif
+
+/* public prototypes */
+
+struct ignorelist_s;
+typedef struct ignorelist_s ignorelist_t;
+
+/*
+ * create the ignorelist_t with known ignore state
+ * return pointer to ignorelist_t
+ */
+ignorelist_t *ignorelist_create (int invert);
+
+/*
+ * free memory used by ignorelist_t
+ */
+void ignorelist_free (ignorelist_t *il);
+
+/*
+ * set ignore state of the ignorelist_t
+ */
+void ignorelist_set_invert (ignorelist_t *il, int invert);
+
+/*
+ * append entry to ignorelist_t
+ * returns zero on success, non-zero upon failure.
+ */
+int ignorelist_add (ignorelist_t *il, const char *entry);
+
+/*
+ * check list for entry
+ * return 1 for ignored entry
+ */
+int ignorelist_match (ignorelist_t *il, const char *entry);
+
+#endif /* UTILS_IGNORELIST_H */
* Florian octo Forster <octo at collectd.org>
*/
-#include "testing.h"
-#include "collectd.h"
#include "common.h" /* for STATIC_ARRAY_SIZE */
+#include "collectd.h"
+#include "testing.h"
#include "utils_subst.h"
#if HAVE_LIBKSTAT
/**
* 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);
+ int 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 < 0) ? 0
- : (((size_t) n) < (max - len)) ? ((size_t) 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) {
- size_t 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 : */
#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
#define CDTIME_T_TO_DOUBLE(t) (((double) (t)) / 1073741824.0)
#define DOUBLE_TO_CDTIME_T(d) ((cdtime_t) ((d) * 1073741824.0))
-#define CDTIME_T_TO_TIMEVAL(cdt,tvp) do { \
- (tvp)->tv_sec = CDTIME_T_TO_TIME_T (cdt); \
- (tvp)->tv_usec = (suseconds_t) CDTIME_T_TO_US ((cdt) & 0x3fffffff); \
+#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) 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 = (long) CDTIME_T_TO_NS ((cdt) & 0x3fffffff); \
+#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) NS_TO_CDTIME_T(1000000000 * (ts)->tv_sec + (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 ((cdtime_t) 1542455354518929408ULL);
-}
-
#define DBL_PRECISION 1e-3
-#include "testing.h"
#include "collectd.h"
+#include "testing.h"
#include "utils_time.h"
DEF_TEST(conversion)
// 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}, {1439981005, 47589622}},
+ {1546167986577716567ULL, 1439981150.048, 1439981150, 1439981150048ULL, {1439981150, 47590}, {1439981150, 47589622}},
};
size_t i;
// 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
{
unsigned long long blocksize;
char disk_name[256];
+ cu_mount_t *dup_ptr;
uint64_t blk_free;
uint64_t blk_reserved;
uint64_t blk_used;
if (ignorelist_match (il_fstype, mnt_ptr->type))
continue;
+ /* search for duplicates *in front of* the current mnt_ptr. */
+ for (dup_ptr = mnt_list; dup_ptr != NULL; dup_ptr = dup_ptr->next)
+ {
+ /* No duplicate found: mnt_ptr is the first of its kind. */
+ if (dup_ptr == mnt_ptr)
+ {
+ dup_ptr = NULL;
+ break;
+ }
+
+ /* Duplicate found: leave non-NULL dup_ptr. */
+ if (by_device && (strcmp (mnt_ptr->spec_device, dup_ptr->spec_device) == 0))
+ break;
+ else if (!by_device && (strcmp (mnt_ptr->dir, dup_ptr->dir) == 0))
+ break;
+ }
+
+ /* ignore duplicates */
+ if (dup_ptr != NULL)
+ continue;
+
if (STATANYFS (mnt_ptr->dir, &statbuf) < 0)
{
char errbuf[1024];
{
char *disk_name;
char *output_name;
- char *alt_name;
numfields = strsplit (buffer, fields, 32);
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;
-#endif
+ char *alt_name = disk_udev_attr_name (handle_udev, disk_name, conf_udev_name_attr);
if (alt_name != NULL)
output_name = alt_name;
+#endif
if ((ds->read_bytes != 0) || (ds->write_bytes != 0))
disk_submit (output_name, "disk_octets",
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
break;
continue;
}
+ if (len < 3) { /* [a-z] ':' '\n' */
+ continue;
+ }
- line[len - 1] = '\0';
+ line[len - 1] = 0;
log_debug ("collect: line = '%s'", line);
bytes = atoi (tmp);
pthread_mutex_lock (&count_mutex);
- type_list_incr (&list_count, type, 1);
+ type_list_incr (&list_count, type, /* increment = */ 1);
pthread_mutex_unlock (&count_mutex);
if (bytes > 0) {
pthread_mutex_lock (&size_mutex);
- type_list_incr (&list_size, type, bytes);
+ type_list_incr (&list_size, type, /* increment = */ bytes);
pthread_mutex_unlock (&size_mutex);
}
}
pthread_mutex_unlock (&score_mutex);
}
else if ('c' == line[0]) { /* c:<type1>[,<type2>,...] */
- char *ptr = NULL;
- char *type = strtok_r (line + 2, ",", &ptr);
-
- do {
- pthread_mutex_lock (&check_mutex);
- type_list_incr (&list_check, type, 1);
- pthread_mutex_unlock (&check_mutex);
- } while (NULL != (type = strtok_r (NULL, ",", &ptr)));
+ char *dummy = line + 2;
+ char *endptr = NULL;
+ char *type;
+
+ pthread_mutex_lock (&check_mutex);
+ while ((type = strtok_r (dummy, ",", &endptr)) != NULL)
+ {
+ dummy = NULL;
+ type_list_incr (&list_check, type, /* increment = */ 1);
+ }
+ pthread_mutex_unlock (&check_mutex);
}
else {
log_err ("collect: unknown type '%c'", line[0]);
pthread_mutex_unlock (&available_mutex);
- do {
+ while (42) {
errno = 0;
- if (-1 == (remote = accept (connector_socket, NULL, NULL))) {
- if (EINTR != errno) {
- char errbuf[1024];
- disabled = 1;
- close (connector_socket);
- connector_socket = -1;
- log_err ("accept() failed: %s",
- sstrerror (errno, errbuf, sizeof (errbuf)));
- pthread_exit ((void *)1);
- }
+
+ remote = accept (connector_socket, NULL, NULL);
+ if (remote == -1) {
+ char errbuf[1024];
+
+ if (errno == EINTR)
+ continue;
+
+ disabled = 1;
+ close (connector_socket);
+ connector_socket = -1;
+ log_err ("accept() failed: %s",
+ sstrerror (errno, errbuf, sizeof (errbuf)));
+ pthread_exit ((void *)1);
}
- } while (EINTR == errno);
- connection = (conn_t *)smalloc (sizeof (conn_t));
+ /* access() succeeded. */
+ break;
+ }
+
+ connection = malloc (sizeof (*connection));
+ if (connection == NULL)
+ {
+ close (remote);
+ continue;
+ }
+ memset (connection, 0, sizeof (*connection));
connection->socket = fdopen (remote, "r");
connection->next = NULL;
if (NULL == connection->socket) {
close (remote);
+ sfree (connection);
continue;
}
}
if (fgets(buffer, buffer_len, fp) == NULL) {
ERROR("fhcount: fgets: %s", sstrerror(errno, errbuf, sizeof(errbuf)));
+ fclose(fp);
return(EXIT_FAILURE);
}
fclose(fp);
if (dir->path == NULL)
{
ERROR ("filecount plugin: strdup failed.");
+ sfree (dir);
return (-1);
}
/**
* collectd - src/gmond.c
- * Copyright (C) 2009,2010 Florian octo Forster
+ * Copyright (C) 2009-2015 Florian octo Forster
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
{
int yes = 1;
- setsockopt (sockets[sockets_num].fd, SOL_SOCKET, SO_REUSEADDR,
+ status = setsockopt (sockets[sockets_num].fd, SOL_SOCKET, SO_REUSEADDR,
(void *) &yes, sizeof (yes));
+ if (status != 0)
+ {
+ char errbuf[1024];
+ WARNING ("gmond plugin: setsockopt(2) failed: %s",
+ sstrerror (errno, errbuf, sizeof (errbuf)));
+ }
}
status = bind (sockets[sockets_num].fd, ai_ptr->ai_addr, ai_ptr->ai_addrlen);
pthread_mutex_lock (&mc_send_sockets_lock);
for (i = 0; i < mc_send_sockets_num; i++)
- sendto (mc_send_sockets[i].fd, buffer, (size_t) buffer_size,
+ {
+ ssize_t status = sendto (mc_send_sockets[i].fd, buffer, (size_t) buffer_size,
/* flags = */ 0,
(struct sockaddr *) &mc_send_sockets[i].addr,
mc_send_sockets[i].addrlen);
+ if (status == -1)
+ {
+ char errbuf[1024];
+ ERROR ("gmond plugin: sendto(2) failed: %s",
+ sstrerror (errno, errbuf, sizeof (errbuf)));
+ continue;
+ }
+ }
pthread_mutex_unlock (&mc_send_sockets_lock);
sfree (msg.Ganglia_metadata_msg_u.grequest.metric_id.host);
return (se);
} /* }}} staging_entry_t *staging_entry_get */
-static int staging_entry_submit (const char *host, const char *name, /* {{{ */
- staging_entry_t *se)
-{
- value_list_t vl;
- value_t values[se->vl.values_len];
-
- if (se->vl.interval == 0)
- {
- /* No meta data has been received for this metric yet. */
- se->flags = 0;
- pthread_mutex_unlock (&staging_lock);
- request_meta_data (host, name);
- return (0);
- }
-
- se->flags = 0;
-
- memcpy (values, se->vl.values, sizeof (values));
- memcpy (&vl, &se->vl, sizeof (vl));
-
- /* Unlock before calling `plugin_dispatch_values'.. */
- pthread_mutex_unlock (&staging_lock);
-
- vl.values = values;
-
- plugin_dispatch_values (&vl);
-
- return (0);
-} /* }}} int staging_entry_submit */
-
static int staging_entry_update (const char *host, const char *name, /* {{{ */
const char *type, const char *type_instance,
size_t ds_index, int ds_type, value_t value)
se->flags |= (0x01 << ds_index);
- /* Check if all values have been set and submit if so. */
- if (se->flags == ((0x01 << se->vl.values_len) - 1))
+ /* Check if all data sources have been set. If not, return here. */
+ if (se->flags != ((0x01 << se->vl.values_len) - 1))
{
- /* `staging_lock' is unlocked in `staging_entry_submit'. */
- staging_entry_submit (host, name, se);
+ pthread_mutex_unlock (&staging_lock);
+ return (0);
}
- else
+
+ /* Check if the interval of this metric is known. If not, request meta data
+ * and return. */
+ if (se->vl.interval == 0)
{
+ /* No meta data has been received for this metric yet. */
+ se->flags = 0;
pthread_mutex_unlock (&staging_lock);
+
+ request_meta_data (host, name);
+ return (0);
}
+ plugin_dispatch_values (&se->vl);
+
+ se->flags = 0;
+ pthread_mutex_unlock (&staging_lock);
+
return (0);
} /* }}} int staging_entry_update */
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);
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 */
*/
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;
-
- if (( ip_version == IPV4 ) || ( ip_version == IPV6 ))
- {
- 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);
- }
- else
- {
- return (-1);
- }
-
- 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 = (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 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
- */
} else {
ERROR ("irq plugin: unable to get CPU count from first line "
"of /proc/interrupts");
+ fclose (fh);
return (-1);
}
if (status != 0)
{
lcc_set_errno (c, status);
+ freeaddrinfo (ai_res);
return (-1);
}
+ freeaddrinfo (ai_res);
return (0);
} /* }}} int lcc_open_netsocket */
return (0);
close (srv->fd);
+ srv->fd = -1;
free (srv->sa);
srv->sa = NULL;
srv->sa_len = 0;
next = srv->next;
- if (srv->fd >= 0)
- {
- close (srv->fd);
- srv->fd = -1;
- }
-
free (srv->node);
free (srv->service);
free (srv->username);
if (ai_ptr->ai_family == AF_INET)
{
-
struct sockaddr_in *addr = (struct sockaddr_in *) ai_ptr->ai_addr;
int optname;
else
optname = IP_TTL;
- setsockopt (srv->fd, IPPROTO_IP, optname,
- &srv->ttl,
- sizeof (srv->ttl));
+ status = setsockopt (srv->fd, IPPROTO_IP, optname,
+ &srv->ttl, sizeof (srv->ttl));
}
else if (ai_ptr->ai_family == AF_INET6)
{
else
optname = IPV6_UNICAST_HOPS;
- setsockopt (srv->fd, IPPROTO_IPV6, optname,
- &srv->ttl,
- sizeof (srv->ttl));
+ status = setsockopt (srv->fd, IPPROTO_IPV6, optname,
+ &srv->ttl, sizeof (srv->ttl));
+ }
+ if (status != 0)
+ {
+ /* setsockopt failed. */
+ close (srv->fd);
+ srv->fd = -1;
+ continue;
}
srv->sa = malloc (ai_ptr->ai_addrlen);
* format time as a UTC ISO 8601 compliant string
*/
strftime (timestamp_str, sizeof (timestamp_str),
- "%Y-%m-%d %H:%M:%SZ", ×tamp_tm);
+ "%Y-%m-%dT%H:%M:%SZ", ×tamp_tm);
timestamp_str[sizeof (timestamp_str) - 1] = '\0';
if (yajl_gen_string(g, (u_char *)timestamp_str,
if (dev[0] == '.')
return 0;
-
+
ssnprintf (buf, sizeof (buf), "/sys/class/net/%s/device/driver", dev);
- buf[sizeof (buf) - 1] = 0;
+ buf[sizeof (buf) - 1] = '\0';
- memset (buf2, 0, sizeof (buf2));
i = readlink (buf, buf2, sizeof (buf2) - 1);
if (i < 0)
return 0;
+ buf2[i] = '\0';
+
if (strstr (buf2, "/drivers/ath_") == NULL)
return 0;
return 1;
}
else if (FIELD_IS ("listen_disabled_num"))
{
- submit_derive ("memcached_connections", "listen_disabled", atof (fields[2]), st);
+ submit_derive ("connections", "listen_disabled", atof (fields[2]), st);
}
/*
status = cf_util_get_string_buffer (ci, host->host, sizeof (host->host));
if (status != 0)
+ {
+ sfree (host);
return (status);
+ }
if (host->host[0] == 0)
+ {
+ sfree (host);
return (EINVAL);
+ }
for (i = 0; i < ci->children_num; i++)
{
* 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
#ifndef MQTT_KEEPALIVE
# define MQTT_KEEPALIVE 60
#endif
+#ifndef SSL_VERIFY_PEER
+# define SSL_VERIFY_PEER 1
+#endif
/*
char *username;
char *password;
int qos;
+ char *cacertificatefile;
+ char *certificatefile;
+ char *certificatekeyfile;
+ char *tlsprotocol;
+ char *ciphersuite;
/* For publishing */
char *topic_prefix;
char *payload;
int status;
- if ((msg->payloadlen <= 0)
- || (((uint8_t *) msg->payload)[msg->payloadlen - 1] != 0))
+ if (msg->payloadlen <= 0) {
+ DEBUG ("mqtt plugin: message has empty payload");
return;
+ }
topic = strdup (msg->topic);
name = strip_prefix (topic);
}
vl.values_len = ds->ds_num;
- payload = strdup ((void *) msg->payload);
+ 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)
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);
* 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)
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);
}
* User "guest"
* Password "secret"
* Topic "collectd/#"
- * </Publish>
+ * </Subscribe>
*/
static int mqtt_config_subscriber (oconfig_item_t *ci)
{
ERROR ("mqtt plugin: Unknown config option: %s", child->key);
}
- tmp = realloc (subscribers, sizeof (*subscribers) * subscribers_num);
+ tmp = realloc (subscribers, sizeof (*subscribers) * (subscribers_num + 1) );
if (tmp == NULL)
{
ERROR ("mqtt plugin: realloc failed.");
for (i = 0; i < 10; i++)
{
- device[strlen(device)-1] = i + '0';
+ device[strlen(device)-1] = i + '0';
- if ((fd = open(device, O_RDWR | O_NOCTTY)) > 0)
+ if ((fd = open(device, O_RDWR | O_NOCTTY)) != -1)
{
struct termios tios;
int rts = TIOCM_RTS;
double value;
+ memset (&tios, 0, sizeof (tios));
tios.c_cflag = B1200 | CS7 | CSTOPB | CREAD | CLOCAL;
tios.c_iflag = IGNBRK | IGNPAR;
- tios.c_oflag = 0;
+ tios.c_oflag = 0;
tios.c_lflag = 0;
tios.c_cc[VTIME] = 3;
tios.c_cc[VMIN] = LINE_LENGTH;
tcflush(fd, TCIFLUSH);
tcsetattr(fd, TCSANOW, &tios);
ioctl(fd, TIOCMBIC, &rts);
-
+
if (multimeter_read_value (&value) < -1)
{
close (fd);
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++)
{
*ret_buffer = buffer;
*ret_buffer_len = buffer_len - pkg_length;
- *ret_num_values = (size_t) pkg_numval;
+ *ret_num_values = pkg_numval;
*ret_values = pkg_values;
sfree (pkg_types);
--- /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 : */
return (0);
}
-static void ntpd_submit (char *type, char *type_inst, double value)
+static void ntpd_submit (char *type, char *type_inst, gauge_t value)
{
value_t values[1];
value_list_t vl = VALUE_LIST_INIT;
* 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,
- double value)
+ gauge_t value)
{
if (!(reach & 1))
value = NAN;
int ps_num;
int ps_size;
+ gauge_t offset_loop;
+ gauge_t freq_loop;
+ gauge_t offset_error;
+
int status;
int i;
+ /* On Linux, if the STA_NANO bit is set in ik->status, then ik->offset
+ * is is nanoseconds, otherwise it's microseconds.
+ * TODO(octo): STA_NANO is defined in the Linux specific <sys/timex.h> header. */
+ double scale_loop = 1e-6;
+ double scale_error = 1e-6;
+
ik = NULL;
ik_num = 0;
ik_size = 0;
}
/* kerninfo -> estimated error */
+ offset_loop = scale_loop * ((gauge_t) ntohl (ik->offset));
+ freq_loop = ntpd_read_fp (ik->freq);
+ offset_error = scale_error * ((gauge_t) ntohl (ik->esterror));
DEBUG ("info_kernel:\n"
- " pll offset = %.8f\n"
- " pll frequency = %.8f\n" /* drift compensation */
- " est error = %.8f\n",
- ntpd_read_fp (ik->offset),
- ntpd_read_fp (ik->freq),
- ntpd_read_fp (ik->esterror));
-
- ntpd_submit ("frequency_offset", "loop", ntpd_read_fp (ik->freq));
- ntpd_submit ("time_offset", "loop", ntpd_read_fp (ik->offset));
- ntpd_submit ("time_offset", "error", ntpd_read_fp (ik->esterror));
+ " pll offset = %.8g\n"
+ " pll frequency = %.8g\n" /* drift compensation */
+ " est error = %.8g\n",
+ offset_loop, freq_loop, offset_error);
+
+ ntpd_submit ("frequency_offset", "loop", freq_loop);
+ ntpd_submit ("time_offset", "loop", offset_loop);
+ ntpd_submit ("time_offset", "error", offset_error);
free (ik);
ik = NULL;
/* create a new vpn element since file, version and name are ok */
temp = (vpn_status_t *) malloc (sizeof (vpn_status_t));
+ if (temp == NULL)
+ {
+ char errbuf[1024];
+ ERROR ("openvpn plugin: malloc failed: %s",
+ sstrerror (errno, errbuf, sizeof (errbuf)));
+ sfree (status_file);
+ return (1);
+ }
temp->file = status_file;
temp->version = status_version;
temp->name = status_name;
if (vpn_list == NULL)
{
char errbuf[1024];
- ERROR ("openvpn plugin: malloc failed: %s",
+ ERROR ("openvpn plugin: realloc failed: %s",
sstrerror (errno, errbuf, sizeof (errbuf)));
sfree (temp->file);
/* the ithread no longer exists */
if (NULL == t)
+ {
+ pthread_mutex_unlock (&perl_threads->mutex);
return;
+ }
c_ithread_destroy (ithread);
values = ST (/* stack index = */ 0);
+ if (NULL == values)
+ XSRETURN_EMPTY;
+
/* Make sure the argument is a hash reference. */
if (! (SvROK (values) && (SVt_PVHV == SvTYPE (SvRV (values))))) {
log_err ("Collectd::plugin_dispatch_values: Invalid values.");
XSRETURN_EMPTY;
}
- if (NULL == values)
- XSRETURN_EMPTY;
-
ret = pplugin_dispatch_values (aTHX_ (HV *)SvRV (values));
if (0 == ret)
int current_status = 0;
if (NULL != perl_threads)
- aTHX = PERL_GET_CONTEXT;
+ {
+ if ((aTHX = PERL_GET_CONTEXT) == NULL)
+ return -1;
+ }
if (0 == strcasecmp (c->key, "LoadPlugin"))
current_status = perl_config_loadplugin (aTHX_ c);
char errbuf[1024];
ERROR ("pinba plugin: bind(2) failed: %s",
sstrerror (errno, errbuf, sizeof (errbuf)));
+ close (fd);
return (0);
}
#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",
static void *ping_thread (void *arg) /* {{{ */
{
- static pingobj_t *pingobj = NULL;
+ pingobj_t *pingobj = NULL;
struct timeval tv_begin;
struct timeval tv_end;
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)
status = -1;
}
+ pthread_mutex_lock (&ping_lock);
memset (&ping_thread_id, 0, sizeof (ping_thread_id));
ping_thread_error = 0;
+ pthread_mutex_unlock (&ping_lock);
return (status);
} /* }}} int stop_thread */
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 */
{
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];
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;
}
data = udb_query_get_user_data (q);
if (NULL == data) {
- data = (c_psql_user_data_t *) smalloc (sizeof (*data));
+ data = malloc (sizeof (*data));
if (NULL == data) {
log_err ("Out of memory.");
return -1;
}
memset (data, 0, sizeof (*data));
data->params = NULL;
+ data->params_num = 0;
+
+ udb_query_set_user_data (q, data);
}
- tmp = (c_psql_param_t *) realloc (data->params,
- (data->params_num + 1) * sizeof (c_psql_param_t));
+ tmp = realloc (data->params, (data->params_num + 1) * sizeof (*data->params));
if (NULL == tmp) {
log_err ("Out of memory.");
return -1;
}
data->params_num++;
- udb_query_set_user_data (q, data);
-
return (0);
} /* config_query_param_add */
writers = tmp;
writer = writers + writers_num;
- ++writers_num;
+ memset (writer, 0, sizeof (*writer));
writer->name = sstrdup (ci->values[0].value.string);
writer->statement = NULL;
if (status != 0) {
sfree (writer->statement);
sfree (writer->name);
- sfree (writer);
return status;
}
+ ++writers_num;
return 0;
} /* c_psql_config_writer */
const char* const default_server_fields[] = /* {{{ */
{
- "latency"
+ "latency",
"packetcache-hit",
"packetcache-miss",
"packetcache-size",
if (status != 0)
{
DEBUG ("ProcessMatch: compiling the regular expression \"%s\" failed.", regexp);
- sfree(new->re);
+ sfree (new->re);
+ sfree (new);
return;
}
}
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
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 = -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);
- } /* if ((proc_ptr == NULL) || (proc_ptr->ki_pid != procs[i].ki_pid)) */
- switch (procs[i].ki_stat)
- {
- case SSTOP: stopped++; break;
- case SSLEEP: sleeping++; break;
- case SRUN: running++; break;
- case SIDL: idle++; break;
- case SWAIT: wait++; break;
- case SLOCK: blocked++; break;
- case SZOMB: zombies++; break;
- }
+ switch (procs[i].ki_stat)
+ {
+ case SSTOP: stopped++; break;
+ case SSLEEP: sleeping++; break;
+ case SRUN: running++; break;
+ case SIDL: idle++; break;
+ case SWAIT: wait++; break;
+ case SLOCK: blocked++; break;
+ case SZOMB: zombies++; break;
+ }
+ } /* if ((proc_ptr == NULL) || (proc_ptr->ki_pid != procs[i].ki_pid)) */
}
kvm_close(kd);
pse.io_syscr = -1;
pse.io_syscw = -1;
- pse.cswitch_vol = -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);
- } /* if ((proc_ptr == NULL) || (proc_ptr->p_pid != procs[i].p_pid)) */
- switch (procs[i].p_stat)
- {
- case SSTOP: stopped++; break;
- case SSLEEP: sleeping++; break;
- case SRUN: running++; break;
- case SIDL: idle++; break;
- case SONPROC: onproc++; break;
- case SDEAD: dead++; break;
- case SZOMB: zombies++; break;
- }
+ switch (procs[i].p_stat)
+ {
+ case SSTOP: stopped++; break;
+ case SSLEEP: sleeping++; break;
+ case SRUN: running++; break;
+ case SIDL: idle++; break;
+ case SONPROC: onproc++; break;
+ case SDEAD: dead++; break;
+ case SZOMB: zombies++; break;
+ }
+ } /* if ((proc_ptr == NULL) || (proc_ptr->p_pid != procs[i].p_pid)) */
}
kvm_close(kd);
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) */
Py_XDECREF(traceback);
return;
}
- list = PyObject_CallFunction(cpy_format_exception, "NNN", type, value, traceback); /* New reference. */
+ list = PyObject_CallFunction(cpy_format_exception, "NNN", type, value, traceback); /* New reference. Steals references from "type", "value" and "traceback". */
if (list)
l = PyObject_Length(list);
+
for (i = 0; i < l; ++i) {
- char *s;
PyObject *line;
-
+ char const *msg;
+ char *cpy;
+
line = PyList_GET_ITEM(list, i); /* Borrowed reference. */
Py_INCREF(line);
- s = strdup(cpy_unicode_or_bytes_to_string(&line));
+
+ msg = cpy_unicode_or_bytes_to_string(&line);
Py_DECREF(line);
- if (s[strlen(s) - 1] == '\n')
- s[strlen(s) - 1] = 0;
+ if (msg == NULL)
+ continue;
+
+ cpy = strdup(msg);
+ if (cpy == NULL)
+ continue;
+
+ if (cpy[strlen(cpy) - 1] == '\n')
+ cpy[strlen(cpy) - 1] = 0;
+
Py_BEGIN_ALLOW_THREADS
- ERROR("%s", s);
+ ERROR("%s", cpy);
Py_END_ALLOW_THREADS
- free(s);
+
+ free(cpy);
}
+
Py_XDECREF(list);
PyErr_Clear();
- Py_DECREF(type);
- Py_XDECREF(value);
- Py_XDECREF(traceback);
}
static int cpy_read_callback(user_data_t *data) {
Py_INCREF(callback);
Py_XINCREF(data);
+
c = malloc(sizeof(*c));
+ if (c == NULL)
+ return NULL;
+ memset (c, 0, sizeof (*c));
+
c->name = strdup(buf);
c->callback = callback;
c->data = data;
char buf[512];
reg_function_t *register_function = (reg_function_t *) reg;
cpy_callback_t *c = NULL;
- user_data_t *user_data = NULL;
+ user_data_t user_data;
char *name = NULL;
PyObject *callback = NULL, *data = NULL;
static char *kwlist[] = {"callback", "data", "name", NULL};
Py_INCREF(callback);
Py_XINCREF(data);
+
c = malloc(sizeof(*c));
+ if (c == NULL)
+ return NULL;
+ memset (c, 0, sizeof (*c));
+
c->name = strdup(buf);
c->callback = callback;
c->data = data;
c->next = NULL;
- user_data = malloc(sizeof(*user_data));
- user_data->free_func = cpy_destroy_user_data;
- user_data->data = c;
- register_function(buf, handler, user_data);
+
+ memset (&user_data, 0, sizeof (user_data));
+ user_data.free_func = cpy_destroy_user_data;
+ user_data.data = c;
+
+ register_function(buf, handler, &user_data);
return cpy_string_to_unicode_or_bytes(buf);
}
static PyObject *cpy_register_read(PyObject *self, PyObject *args, PyObject *kwds) {
char buf[512];
cpy_callback_t *c = NULL;
- user_data_t *user_data = NULL;
+ user_data_t user_data;
double interval = 0;
char *name = NULL;
PyObject *callback = NULL, *data = NULL;
Py_INCREF(callback);
Py_XINCREF(data);
+
c = malloc(sizeof(*c));
+ if (c == NULL)
+ return NULL;
+ memset (c, 0, sizeof (*c));
+
c->name = strdup(buf);
c->callback = callback;
c->data = data;
c->next = NULL;
- user_data = malloc(sizeof(*user_data));
- user_data->free_func = cpy_destroy_user_data;
- user_data->data = c;
- plugin_register_complex_read(/* group = */ NULL, buf,
- cpy_read_callback, DOUBLE_TO_CDTIME_T (interval), user_data);
+
+ memset (&user_data, 0, sizeof (user_data));
+ user_data.free_func = cpy_destroy_user_data;
+ user_data.data = c;
+
+ plugin_register_complex_read(/* group = */ "python", buf,
+ cpy_read_callback, DOUBLE_TO_CDTIME_T (interval), &user_data);
return cpy_string_to_unicode_or_bytes(buf);
}
for (tmp = *list_head; tmp; prev = tmp, tmp = tmp->next)
if (strcmp(name, tmp->name) == 0)
break;
-
+
Py_DECREF(arg);
if (tmp == NULL) {
PyErr_Format(PyExc_RuntimeError, "Unable to unregister %s callback '%s'.", desc, name);
* Default to a gauge type.
*/
(void)strncpy(rq->type, "gauge", sizeof(rq->type));
- (void)strncpy(rq->instance, rq->query, sizeof(rq->instance));
+ (void)sstrncpy(rq->instance, rq->query, sizeof(rq->instance));
replace_special(rq->instance, sizeof(rq->instance));
for (i = 0; i < ci->children_num; i++) {
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';
{
rc = malloc (sizeof (*rc));
if (rc == NULL)
+ {
+ pthread_mutex_unlock (&cache_lock);
return (-1);
+ }
rc->values_num = 0;
rc->values = NULL;
rc->first_value = 0;
}
else if (strcasecmp ("DataDir", key) == 0)
{
- if (datadir != NULL)
- free (datadir);
- datadir = strdup (value);
- if (datadir != NULL)
+ char *tmp;
+ size_t len;
+
+ tmp = strdup (value);
+ if (tmp == NULL)
{
- int len = strlen (datadir);
- while ((len > 0) && (datadir[len - 1] == '/'))
- {
- len--;
- datadir[len] = '\0';
- }
- if (len <= 0)
- {
- free (datadir);
- datadir = NULL;
- }
+ ERROR ("rrdtool plugin: strdup failed.");
+ return (1);
}
+
+ len = strlen (datadir);
+ while ((len > 0) && (datadir[len - 1] == '/'))
+ {
+ len--;
+ datadir[len] = 0;
+ }
+
+ if (len == 0)
+ {
+ ERROR ("rrdtool plugin: Invalid \"DataDir\" option.");
+ sfree (tmp);
+ return (1);
+ }
+
+ sfree (datadir);
+ datadir = tmp;
}
else if (strcasecmp ("StepSize", key) == 0)
{
cache = c_avl_create ((int (*) (const void *, const void *)) strcmp);
if (cache == NULL)
{
+ pthread_mutex_unlock (&cache_lock);
ERROR ("rrdtool plugin: c_avl_create failed.");
return (-1);
}
return -1;
}
- if ((status = plugin_thread_create(&sr_thread, NULL, sigrok_read_thread,
- NULL)) != 0) {
+ status = plugin_thread_create(&sr_thread, NULL, sigrok_read_thread,
+ NULL);
+ if (status != 0)
+ {
+ char errbuf[1024];
ERROR("sigrok plugin: Failed to create thread: %s.",
- strerror(status));
+ sstrerror (errno, errbuf, sizeof (errbuf)));
return -1;
}
sr_thread_running = TRUE;
status = cf_util_get_string(ci, &hd->name);
if (status != 0)
+ {
+ sfree (hd);
return status;
+ }
hd->sess_handle = NULL;
hd->interval = 0;
tmp_unsigned = (uint32_t) *vl->val.integer;
tmp_signed = (int32_t) *vl->val.integer;
- if ((vl->type == ASN_INTEGER)
- || (vl->type == ASN_GAUGE))
+ if (vl->type == ASN_INTEGER)
prefer_signed = 1;
DEBUG ("snmp plugin: Parsed int32 value is %"PRIu64".", tmp_unsigned);
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;
}
/* 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;
static int csnmp_read_table (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;
res = NULL;
sfree (errstr);
+ sfree (vl.values);
csnmp_host_close_session (host);
return (-1);
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);
{
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;
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 */
if (tmp == NULL)
{
ERROR ("statsd plugin: realloc failed.");
+ close (fd);
continue;
}
fds = tmp;
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;
else
values[0].gauge = (gauge_t) c_avl_size (metric->set);
}
- else
- values[0].derive = (derive_t) metric->value;
+ else { /* STATSD_COUNTER */
+ 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));
} /* }}} int statsd_metric_submit_unsafe */
while (c_avl_pick (metrics_tree, &key, &value) == 0)
{
sfree (key);
- sfree (value);
+ statsd_metric_free (value);
}
c_avl_destroy (metrics_tree);
metrics_tree = NULL;
return (0);
/* Allocate and initialize the swaptbl_t structure */
- s = (swaptbl_t *) smalloc (swap_num * sizeof (swapent_t) + sizeof (struct swaptable));
+ s = malloc (swap_num * sizeof (swapent_t) + sizeof (struct swaptable));
if (s == NULL)
{
- ERROR ("swap plugin: smalloc failed.");
+ ERROR ("swap plugin: malloc failed.");
return (-1);
}
s_paths = calloc (swap_num, PATH_MAX);
if (s_paths == NULL)
{
- ERROR ("swap plugin: malloc failed.");
+ ERROR ("swap plugin: calloc failed.");
sfree (s);
return (-1);
}
res = (tbl_result_t *)realloc (tbl->results,
(tbl->results_num + 1) * sizeof (*tbl->results));
- if (NULL == tbl) {
+ if (res == NULL) {
char errbuf[1024];
log_err ("realloc failed: %s.",
sstrerror (errno, errbuf, sizeof (errbuf)));
}
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;
}
}
if (tm == NULL)
{
ERROR ("tail plugin: tail_match_create (%s) failed.",
- ci->values[0].value.string);
+ ci->values[0].value.string);
return (-1);
}
{
status = ctail_config_add_match (tm, plugin_instance, option, interval);
if (status == 0)
- num_matches++;
+ num_matches++;
/* Be mild with failed matches.. */
status = 0;
}
break;
} /* for (i = 0; i < ci->children_num; i++) */
+ sfree (plugin_instance);
+
if (num_matches == 0)
{
ERROR ("tail plugin: No (valid) matches found for file `%s'.",
- ci->values[0].value.string);
+ ci->values[0].value.string);
tail_match_destroy (tm);
return (-1);
}
cu_tail_match_t **temp;
temp = (cu_tail_match_t **) realloc (tail_match_list,
- sizeof (cu_tail_match_t *) * (tail_match_list_num + 1));
+ sizeof (cu_tail_match_t *) * (tail_match_list_num + 1));
if (temp == NULL)
{
ERROR ("tail plugin: realloc failed.");
WARNING ("teamspeak2 plugin: connect failed: %s",
sstrerror (errno, errbuf, sizeof (errbuf)));
close (sd);
+ sd = -1;
continue;
}
* Florian octo Forster <octo at collectd.org>
*/
+#ifndef TESTING_H
+#define TESTING_H 1
+
#include <inttypes.h>
static int fail_count__ = 0;
status_ = (long) (expr); \
OK1(status_ == 0L, #expr); \
} while (0)
+
+#endif /* TESTING_H */
{ /* {{{ */
int i;
int status = 0;
+ int old_size = c_avl_size (threshold_tree);
threshold_t th;
break;
}
- if (c_avl_size (threshold_tree) > 0) {
+ /* register callbacks if this is the first time we see a valid config */
+ if ((old_size == 0) && (c_avl_size (threshold_tree) > 0))
+ {
plugin_register_missing ("threshold", ut_missing,
/* user data = */ NULL);
plugin_register_write ("threshold", ut_check_threshold,
}
if (fscanf(filep, "%d", &value) != 1) {
ERROR("turbostat plugin: Failed to parse number from '%s'", path);
+ fclose(filep);
return -1;
}
fclose(filep);
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
return (-1);
}
- chmod (sa.sun_path, sock_perms);
+ status = chmod (sa.sun_path, sock_perms);
+ if (status == -1)
+ {
+ char errbuf[1024];
+ ERROR ("unixsock plugin: chmod failed: %s",
+ sstrerror (errno, errbuf, sizeof (errbuf)));
+ close (sock_fd);
+ sock_fd = -1;
+ return (-1);
+ }
status = listen (sock_fd, 8);
if (status != 0)
#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
c_avl_tree_t *tree;
};
-/*
+/*
* Private functions
*/
static void fbh_free_tree (c_avl_tree_t *tree) /* {{{ */
return (status);
} /* }}} int fbh_check_file */
-/*
+/*
* Public functions
*/
fbhash_t *fbh_create (const char *file) /* {{{ */
if (status != 0)
{
fbh_destroy (h);
+ free (h);
return (NULL);
}
return (0);
} /* }}} int dsnames_to_json */
-static int meta_data_to_json (char *buffer, size_t buffer_size, /* {{{ */
- meta_data_t *meta)
+static int meta_data_keys_to_json (char *buffer, size_t buffer_size, /* {{{ */
+ meta_data_t *meta, char **keys, size_t keys_num)
{
size_t offset = 0;
- char **keys = NULL;
- int keys_num;
int status;
- int i;
+ size_t i;
buffer[0] = 0;
- if (meta == NULL)
- return (EINVAL);
-
#define BUFFER_ADD(...) do { \
status = ssnprintf (buffer + offset, buffer_size - offset, \
__VA_ARGS__); \
offset += ((size_t) status); \
} while (0)
- keys_num = meta_data_toc (meta, &keys);
- if (keys_num == 0)
- {
- sfree (keys);
- return (0);
- }
-
for (i = 0; i < keys_num; ++i)
{
int type;
if (meta_data_get_string (meta, key, &value) == 0)
{
char temp[512] = "";
- json_escape_string (temp, sizeof (temp), value);
+
+ status = json_escape_string (temp, sizeof (temp), value);
sfree (value);
+ if (status != 0)
+ return status;
+
BUFFER_ADD (",\"%s\":%s", key, temp);
}
}
if (meta_data_get_boolean (meta, key, &value) == 0)
BUFFER_ADD (",\"%s\":%s", key, value ? "true" : "false");
}
-
- free (key);
} /* for (keys) */
- free (keys);
if (offset <= 0)
return (ENOENT);
#undef BUFFER_ADD
return (0);
+} /* }}} int meta_data_keys_to_json */
+
+static int meta_data_to_json (char *buffer, size_t buffer_size, /* {{{ */
+ meta_data_t *meta)
+{
+ char **keys = NULL;
+ size_t keys_num;
+ int status;
+ size_t i;
+
+ if ((buffer == NULL) || (buffer_size == 0) || (meta == NULL))
+ return (EINVAL);
+
+ status = meta_data_toc (meta, &keys);
+ if (status <= 0)
+ return (status);
+ keys_num = (size_t) status;
+
+ status = meta_data_keys_to_json (buffer, buffer_size, meta, keys, keys_num);
+
+ for (i = 0; i < keys_num; ++i)
+ sfree (keys[i]);
+ sfree (keys);
+
+ return status;
} /* }}} int meta_data_to_json */
static int value_list_to_json (char *buffer, size_t buffer_size, /* {{{ */
+++ /dev/null
-/**
- * collectd - src/utils_ignorelist.c
- * Copyright (C) 2006 Lubos Stanek <lubek at users.sourceforge.net>
- * Copyright (C) 2008 Florian Forster <octo at collectd.org>
- *
- * This program is free software; you can redistribute it and/
- * or modify it under the terms of the GNU General Public Li-
- * cence as published by the Free Software Foundation; either
- * version 2 of the Licence, or any later version.
- *
- * This program is distributed in the hope that it will be use-
- * ful, but WITHOUT ANY WARRANTY; without even the implied war-
- * ranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- * See the GNU General Public Licence for more details.
- *
- * You should have received a copy of the GNU General Public
- * Licence along with this program; if not, write to the Free
- * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139,
- * USA.
- *
- * Authors:
- * Lubos Stanek <lubek at users.sourceforge.net>
- * Florian Forster <octo at collectd.org>
- **/
-/**
- * ignorelist handles plugin's list of configured collectable
- * entries with global ignore action
- **/
-/**
- * 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),
- * allocate the variable with:
- * myconfig_ignore = ignorelist_create (YourKnownIgnore);
- * If you do not know the state of the global ignore,
- * initialize the global variable and set the ignore flag later:
- * myconfig_ignore = ignorelist_init ();
- * Append single entries in your cf_register'ed callback function:
- * ignorelist_add (myconfig_ignore, newentry);
- * When you hit the IgnoreSelected config option,
- * offer it to the list:
- * ignorelist_ignore (myconfig_ignore, instantly_got_value_of_ignore);
- * That is all for the ignorelist initialization.
- * Later during read and write (plugin's registered functions) get
- * the information whether this entry would be collected or not:
- * if (ignorelist_match (myconfig_ignore, thisentry))
- * return;
- **/
-
-#if HAVE_CONFIG_H
-# include "config.h"
-#endif
-
-#include "common.h"
-#include "plugin.h"
-#include "utils_ignorelist.h"
-
-/*
- * private prototypes
- */
-struct ignorelist_item_s
-{
-#if HAVE_REGEX_H
- regex_t *rmatch; /* regular expression entry identification */
-#endif
- char *smatch; /* string entry identification */
- struct ignorelist_item_s *next;
-};
-typedef struct ignorelist_item_s ignorelist_item_t;
-
-struct ignorelist_s
-{
- int ignore; /* ignore entries */
- ignorelist_item_t *head; /* pointer to the first entry */
-};
-
-/* *** *** *** ********************************************* *** *** *** */
-/* *** *** *** *** *** *** private functions *** *** *** *** *** *** */
-/* *** *** *** ********************************************* *** *** *** */
-
-static inline void ignorelist_append (ignorelist_t *il, ignorelist_item_t *item)
-{
- assert ((il != NULL) && (item != NULL));
-
- item->next = il->head;
- il->head = item;
-}
-
-#if HAVE_REGEX_H
-static int ignorelist_append_regex(ignorelist_t *il, const char *re_str)
-{
- regex_t *re;
- ignorelist_item_t *entry;
- int status;
-
- re = malloc (sizeof (*re));
- if (re == NULL)
- {
- ERROR ("utils_ignorelist: malloc failed");
- return (ENOMEM);
- }
- memset (re, 0, sizeof (*re));
-
- status = regcomp (re, re_str, REG_EXTENDED);
- if (status != 0)
- {
- char errbuf[1024] = "";
- regerror (status, re, errbuf, sizeof (errbuf));
- ERROR ("utils_ignorelist: regcomp failed: %s", errbuf);
- regfree (re);
- sfree (re);
- return (status);
- }
-
- entry = malloc (sizeof (*entry));
- if (entry == NULL)
- {
- ERROR ("utils_ignorelist: malloc failed");
- regfree (re);
- sfree (re);
- return (ENOMEM);
- }
- memset (entry, 0, sizeof (*entry));
- entry->rmatch = re;
-
- ignorelist_append (il, entry);
- return (0);
-} /* 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 )
- {
- ERROR ("cannot allocate new entry");
- return (1);
- }
- memset (new, '\0', sizeof(ignorelist_item_t));
- new->smatch = sstrdup(entry);
-
- /* append new entry */
- ignorelist_append (il, new);
-
- return (0);
-} /* int ignorelist_append_string(ignorelist_t *il, const char *entry) */
-
-#if HAVE_REGEX_H
-/*
- * check list for entry regex match
- * return 1 if found
- */
-static int ignorelist_match_regex (ignorelist_item_t *item, const char *entry)
-{
- assert ((item != NULL) && (item->rmatch != NULL)
- && (entry != NULL) && (strlen (entry) > 0));
-
- /* match regex */
- if (regexec (item->rmatch, entry, 0, NULL, 0) == 0)
- return (1);
-
- return (0);
-} /* int ignorelist_match_regex (ignorelist_item_t *item, const char *entry) */
-#endif
-
-/*
- * check list for entry string match
- * return 1 if found
- */
-static int ignorelist_match_string (ignorelist_item_t *item, const char *entry)
-{
- assert ((item != NULL) && (item->smatch != NULL)
- && (entry != NULL) && (strlen (entry) > 0));
-
- if (strcmp (entry, item->smatch) == 0)
- return (1);
-
- return (0);
-} /* int ignorelist_match_string (ignorelist_item_t *item, const char *entry) */
-
-
-/* *** *** *** ******************************************** *** *** *** */
-/* *** *** *** *** *** *** public functions *** *** *** *** *** *** */
-/* *** *** *** ******************************************** *** *** *** */
-
-/*
- * create the ignorelist_t with known ignore state
- * return pointer to ignorelist_t
- */
-ignorelist_t *ignorelist_create (int invert)
-{
- ignorelist_t *il;
-
- /* smalloc exits if it failes */
- il = (ignorelist_t *) smalloc (sizeof (ignorelist_t));
- memset (il, '\0', sizeof (ignorelist_t));
-
- /*
- * ->ignore == 0 => collect
- * ->ignore == 1 => ignore
- */
- il->ignore = invert ? 0 : 1;
-
- return (il);
-} /* ignorelist_t *ignorelist_create (int ignore) */
-
-/*
- * free memory used by ignorelist_t
- */
-void ignorelist_free (ignorelist_t *il)
-{
- ignorelist_item_t *this;
- ignorelist_item_t *next;
-
- if (il == NULL)
- return;
-
- for (this = il->head; this != NULL; this = next)
- {
- next = this->next;
-#if HAVE_REGEX_H
- if (this->rmatch != NULL)
- {
- regfree (this->rmatch);
- sfree (this->rmatch);
- this->rmatch = NULL;
- }
-#endif
- if (this->smatch != NULL)
- {
- sfree (this->smatch);
- this->smatch = NULL;
- }
- sfree (this);
- }
-
- sfree (il);
- il = NULL;
-} /* void ignorelist_destroy (ignorelist_t *il) */
-
-/*
- * set ignore state of the ignorelist_t
- */
-void ignorelist_set_invert (ignorelist_t *il, int invert)
-{
- if (il == NULL)
- {
- DEBUG("ignore call with ignorelist_t == NULL");
- return;
- }
-
- il->ignore = invert ? 0 : 1;
-} /* void ignorelist_set_invert (ignorelist_t *il, int ignore) */
-
-/*
- * append entry into ignorelist_t
- * return 0 for success
- */
-int ignorelist_add (ignorelist_t *il, const char *entry)
-{
- size_t entry_len;
-
- if (il == NULL)
- {
- DEBUG ("add called with ignorelist_t == NULL");
- return (1);
- }
-
- entry_len = strlen (entry);
-
- /* append nothing */
- if (entry_len == 0)
- {
- DEBUG("not appending: empty entry");
- return (1);
- }
-
-#if HAVE_REGEX_H
- /* regex string is enclosed in "/.../" */
- if ((entry_len > 2) && (entry[0] == '/') && entry[entry_len - 1] == '/')
- {
- char *entry_copy;
- size_t entry_copy_size;
- int status;
-
- /* We need to copy `entry' since it's const */
- entry_copy_size = entry_len - 1;
- entry_copy = smalloc (entry_copy_size);
- sstrncpy (entry_copy, entry + 1, entry_copy_size);
-
- status = ignorelist_append_regex(il, entry_copy);
- sfree (entry_copy);
- return status;
- }
-#endif
-
- return ignorelist_append_string(il, entry);
-} /* int ignorelist_add (ignorelist_t *il, const char *entry) */
-
-/*
- * check list for entry
- * return 1 for ignored entry
- */
-int ignorelist_match (ignorelist_t *il, const char *entry)
-{
- ignorelist_item_t *traverse;
-
- /* if no entries, collect all */
- if ((il == NULL) || (il->head == NULL))
- return (0);
-
- if ((entry == NULL) || (strlen (entry) == 0))
- return (0);
-
- /* traverse list and check entries */
- for (traverse = il->head; traverse != NULL; traverse = traverse->next)
- {
-#if HAVE_REGEX_H
- if (traverse->rmatch != NULL)
- {
- if (ignorelist_match_regex (traverse, entry))
- return (il->ignore);
- }
- else
-#endif
- {
- if (ignorelist_match_string (traverse, entry))
- return (il->ignore);
- }
- } /* for traverse */
-
- return (1 - il->ignore);
-} /* int ignorelist_match (ignorelist_t *il, const char *entry) */
-
+++ /dev/null
-/**
- * collectd - src/utils_ignorelist.h
- * Copyright (C) 2006 Lubos Stanek <lubek at users.sourceforge.net>
- *
- * This program is free software; you can redistribute it and/
- * or modify it under the terms of the GNU General Public Li-
- * cence as published by the Free Software Foundation; either
- * version 2 of the Licence, or any later version.
- *
- * This program is distributed in the hope that it will be use-
- * ful, but WITHOUT ANY WARRANTY; without even the implied war-
- * ranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- * See the GNU General Public Licence for more details.
- *
- * You should have received a copy of the GNU General Public
- * Licence along with this program; if not, write to the Free
- * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139,
- * USA.
- *
- * Authors:
- * Lubos Stanek <lubek at users.sourceforge.net>
- **/
-/**
- * ignorelist handles plugin's list of configured collectable
- * entries with global ignore action
- **/
-
-#ifndef UTILS_IGNORELIST_H
-#define UTILS_IGNORELIST_H 1
-
-#include "collectd.h"
-
-#if HAVE_REGEX_H
-# include <regex.h>
-#endif
-
-/* public prototypes */
-
-struct ignorelist_s;
-typedef struct ignorelist_s ignorelist_t;
-
-/*
- * create the ignorelist_t with known ignore state
- * return pointer to ignorelist_t
- */
-ignorelist_t *ignorelist_create (int invert);
-
-/*
- * free memory used by ignorelist_t
- */
-void ignorelist_free (ignorelist_t *il);
-
-/*
- * set ignore state of the ignorelist_t
- */
-void ignorelist_set_invert (ignorelist_t *il, int invert);
-
-/*
- * append entry to ignorelist_t
- * returns zero on success, non-zero upon failure.
- */
-int ignorelist_add (ignorelist_t *il, const char *entry);
-
-/*
- * check list for entry
- * return 1 for ignored entry
- */
-int ignorelist_match (ignorelist_t *il, const char *entry);
-
-#endif /* UTILS_IGNORELIST_H */
#define DBL_PRECISION 1e-9
-#include "testing.h"
-#include "collectd.h"
#include "common.h" /* for STATIC_ARRAY_SIZE */
+#include "collectd.h"
+#include "testing.h"
#include "utils_time.h"
#include "utils_latency.h"
#warn "This version of `getmntent' hat not yet been implemented!"
/* #endif HAVE_SEQ_GETMNTENT */
+#elif HAVE_GETMNTENT_R
+static cu_mount_t *cu_mount_getmntent (void)
+{
+ FILE *fp;
+ struct mntent me;
+ char mntbuf[1024];
+
+ cu_mount_t *first = NULL;
+ cu_mount_t *last = NULL;
+ cu_mount_t *new = NULL;
+
+ DEBUG ("utils_mount: (void); COLLECTD_MNTTAB = %s", COLLECTD_MNTTAB);
+
+ if ((fp = setmntent (COLLECTD_MNTTAB, "r")) == NULL)
+ {
+ char errbuf[1024];
+ ERROR ("setmntent (%s): %s", COLLECTD_MNTTAB,
+ sstrerror (errno, errbuf, sizeof (errbuf)));
+ return (NULL);
+ }
+
+ while (getmntent_r (fp, &me, mntbuf, sizeof (mntbuf) ))
+ {
+ if ((new = malloc (sizeof (cu_mount_t))) == 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);
+ new->type = sstrdup (me.mnt_type);
+ new->options = sstrdup (me.mnt_opts);
+ new->device = get_device_name (new->options);
+ new->next = NULL;
+
+ DEBUG ("utils_mount: new = {dir = %s, spec_device = %s, type = %s, options = %s, device = %s}",
+ new->dir, new->spec_device, new->type, new->options, new->device);
+
+ /* Append to list */
+ if (first == NULL)
+ {
+ first = new;
+ last = new;
+ }
+ else
+ {
+ last->next = new;
+ last = new;
+ }
+ }
+
+ endmntent (fp);
+
+ DEBUG ("utils_mount: return (0x%p)", (void *) first);
+
+ return (first);
+} /* HAVE_GETMNTENT_R */
+
#elif HAVE_ONE_GETMNTENT
static cu_mount_t *cu_mount_getmntent (void)
{
char *
cu_mount_checkoption(char *line, char *keyword, int full)
{
- char *line2, *l2;
- int l = strlen(keyword);
- char *p1, *p2;
+ char *line2, *l2, *p1, *p2;
+ int l;
if(line == NULL || keyword == NULL) {
return NULL;
}
+
if(full != 0) {
full = 1;
}
l2++;
}
+ l = strlen(keyword);
p1 = line - 1;
p2 = strchr(line, ',');
do {
* Florian octo Forster <octo at collectd.org>
*/
-#include "testing.h"
#include "collectd.h"
+#include "testing.h"
#include "utils_mount.h"
#if HAVE_LIBKSTAT
* 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;
return (varnish_submit (plugin_instance, category, type, type_instance, value));
} /* }}} int varnish_submit_derive */
+#if HAVE_VARNISH_V3 || HAVE_VARNISH_V4
+static int varnish_monitor (void *priv, const struct VSC_point * const pt) /* {{{ */
+{
+ uint64_t val;
+ const user_config_t *conf;
+ const char *class;
+ const char *name;
+
+ if (pt == NULL)
+ return (0);
+
+ conf = priv;
+
+#if HAVE_VARNISH_V4
+ class = pt->section->fantom->type;
+ name = pt->desc->name;
+
+ if (strcmp(class, "MAIN") != 0)
+ return (0);
+
+#elif HAVE_VARNISH_V3
+ class = pt->class;
+ name = pt->name;
+
+ if (strcmp(class, "") != 0)
+ return (0);
+#endif
+
+ val = *(const volatile uint64_t*) pt->ptr;
+
+ if (conf->collect_cache)
+ {
+ if (strcmp(name, "cache_hit") == 0)
+ return varnish_submit_derive (conf->instance, "cache", "cache_result", "hit", val);
+ else if (strcmp(name, "cache_miss") == 0)
+ return varnish_submit_derive (conf->instance, "cache", "cache_result", "miss", val);
+ else if (strcmp(name, "cache_hitpass") == 0)
+ return varnish_submit_derive (conf->instance, "cache", "cache_result", "hitpass", val);
+ }
+
+ if (conf->collect_connections)
+ {
+ if (strcmp(name, "client_conn") == 0)
+ return varnish_submit_derive (conf->instance, "connections", "connections", "accepted", val);
+ else if (strcmp(name, "client_drop") == 0)
+ return varnish_submit_derive (conf->instance, "connections", "connections", "dropped" , val);
+ else if (strcmp(name, "client_req") == 0)
+ return varnish_submit_derive (conf->instance, "connections", "connections", "received", val);
+ }
+
+#ifdef HAVE_VARNISH_V3
+ if (conf->collect_dirdns)
+ {
+ if (strcmp(name, "dir_dns_lookups") == 0)
+ return varnish_submit_derive (conf->instance, "dirdns", "cache_operation", "lookups", val);
+ else if (strcmp(name, "dir_dns_failed") == 0)
+ return varnish_submit_derive (conf->instance, "dirdns", "cache_result", "failed", val);
+ else if (strcmp(name, "dir_dns_hit") == 0)
+ return varnish_submit_derive (conf->instance, "dirdns", "cache_result", "hits", val);
+ else if (strcmp(name, "dir_dns_cache_full") == 0)
+ return varnish_submit_derive (conf->instance, "dirdns", "cache_result", "cache_full", val);
+ }
+#endif
+
+ if (conf->collect_esi)
+ {
+ if (strcmp(name, "esi_errors") == 0)
+ return varnish_submit_derive (conf->instance, "esi", "total_operations", "error", val);
+ else if (strcmp(name, "esi_parse") == 0)
+ return varnish_submit_derive (conf->instance, "esi", "total_operations", "parsed", val);
+ else if (strcmp(name, "esi_warnings") == 0)
+ return varnish_submit_derive (conf->instance, "esi", "total_operations", "warning", val);
+ }
+
+ if (conf->collect_backend)
+ {
+ if (strcmp(name, "backend_conn") == 0)
+ return varnish_submit_derive (conf->instance, "backend", "connections", "success", val);
+ else if (strcmp(name, "backend_unhealthy") == 0)
+ return varnish_submit_derive (conf->instance, "backend", "connections", "not-attempted", val);
+ else if (strcmp(name, "backend_busy") == 0)
+ return varnish_submit_derive (conf->instance, "backend", "connections", "too-many", val);
+ else if (strcmp(name, "backend_fail") == 0)
+ return varnish_submit_derive (conf->instance, "backend", "connections", "failures", val);
+ else if (strcmp(name, "backend_reuse") == 0)
+ return varnish_submit_derive (conf->instance, "backend", "connections", "reuses", val);
+ else if (strcmp(name, "backend_toolate") == 0)
+ return varnish_submit_derive (conf->instance, "backend", "connections", "was-closed", val);
+ else if (strcmp(name, "backend_recycle") == 0)
+ return varnish_submit_derive (conf->instance, "backend", "connections", "recycled", val);
+ else if (strcmp(name, "backend_unused") == 0)
+ return varnish_submit_derive (conf->instance, "backend", "connections", "unused", val);
+ else if (strcmp(name, "backend_retry") == 0)
+ return varnish_submit_derive (conf->instance, "backend", "connections", "retries", val);
+ else if (strcmp(name, "backend_req") == 0)
+ return varnish_submit_derive (conf->instance, "backend", "http_requests", "requests", val);
+ else if (strcmp(name, "n_backend") == 0)
+ return varnish_submit_gauge (conf->instance, "backend", "backends", "n_backends", val);
+ }
+
+ if (conf->collect_fetch)
+ {
+ if (strcmp(name, "fetch_head") == 0)
+ return varnish_submit_derive (conf->instance, "fetch", "http_requests", "head", val);
+ else if (strcmp(name, "fetch_length") == 0)
+ return varnish_submit_derive (conf->instance, "fetch", "http_requests", "length", val);
+ else if (strcmp(name, "fetch_chunked") == 0)
+ return varnish_submit_derive (conf->instance, "fetch", "http_requests", "chunked", val);
+ else if (strcmp(name, "fetch_eof") == 0)
+ return varnish_submit_derive (conf->instance, "fetch", "http_requests", "eof", val);
+ else if (strcmp(name, "fetch_bad") == 0)
+ return varnish_submit_derive (conf->instance, "fetch", "http_requests", "bad_headers", val);
+ else if (strcmp(name, "fetch_close") == 0)
+ return varnish_submit_derive (conf->instance, "fetch", "http_requests", "close", val);
+ else if (strcmp(name, "fetch_oldhttp") == 0)
+ return varnish_submit_derive (conf->instance, "fetch", "http_requests", "oldhttp", val);
+ else if (strcmp(name, "fetch_zero") == 0)
+ return varnish_submit_derive (conf->instance, "fetch", "http_requests", "zero", val);
+ else if (strcmp(name, "fetch_failed") == 0)
+ return varnish_submit_derive (conf->instance, "fetch", "http_requests", "failed", val);
+ else if (strcmp(name, "fetch_1xx") == 0)
+ return varnish_submit_derive (conf->instance, "fetch", "http_requests", "no_body_1xx", val);
+ else if (strcmp(name, "fetch_204") == 0)
+ return varnish_submit_derive (conf->instance, "fetch", "http_requests", "no_body_204", val);
+ else if (strcmp(name, "fetch_304") == 0)
+ return varnish_submit_derive (conf->instance, "fetch", "http_requests", "no_body_304", val);
+ }
+
+ if (conf->collect_hcb)
+ {
+ if (strcmp(name, "hcb_nolock") == 0)
+ return varnish_submit_derive (conf->instance, "hcb", "cache_operation", "lookup_nolock", val);
+ else if (strcmp(name, "hcb_lock") == 0)
+ return varnish_submit_derive (conf->instance, "hcb", "cache_operation", "lookup_lock", val);
+ else if (strcmp(name, "hcb_insert") == 0)
+ return varnish_submit_derive (conf->instance, "hcb", "cache_operation", "insert", val);
+ }
+
+ if (conf->collect_objects)
+ {
+ if (strcmp(name, "n_expired") == 0)
+ return varnish_submit_derive (conf->instance, "objects", "total_objects", "expired", val);
+ else if (strcmp(name, "n_lru_nuked") == 0)
+ return varnish_submit_derive (conf->instance, "objects", "total_objects", "lru_nuked", val);
+ else if (strcmp(name, "n_lru_saved") == 0)
+ return varnish_submit_derive (conf->instance, "objects", "total_objects", "lru_saved", val);
+ else if (strcmp(name, "n_lru_moved") == 0)
+ return varnish_submit_derive (conf->instance, "objects", "total_objects", "lru_moved", val);
+ else if (strcmp(name, "n_deathrow") == 0)
+ return varnish_submit_derive (conf->instance, "objects", "total_objects", "deathrow", val);
+ else if (strcmp(name, "losthdr") == 0)
+ return varnish_submit_derive (conf->instance, "objects", "total_objects", "header_overflow", val);
+ else if (strcmp(name, "n_obj_purged") == 0)
+ return varnish_submit_derive (conf->instance, "objects", "total_objects", "purged", val);
+ else if (strcmp(name, "n_objsendfile") == 0)
+ return varnish_submit_derive (conf->instance, "objects", "total_objects", "sent_sendfile", val);
+ else if (strcmp(name, "n_objwrite") == 0)
+ return varnish_submit_derive (conf->instance, "objects", "total_objects", "sent_write", val);
+ else if (strcmp(name, "n_objoverflow") == 0)
+ return varnish_submit_derive (conf->instance, "objects", "total_objects", "workspace_overflow", val);
+ }
+
+#if HAVE_VARNISH_V3
+ if (conf->collect_ban)
+ {
+ if (strcmp(name, "n_ban") == 0)
+ return varnish_submit_derive (conf->instance, "ban", "total_operations", "total", val);
+ else if (strcmp(name, "n_ban_add") == 0)
+ return varnish_submit_derive (conf->instance, "ban", "total_operations", "added", val);
+ else if (strcmp(name, "n_ban_retire") == 0)
+ return varnish_submit_derive (conf->instance, "ban", "total_operations", "deleted", val);
+ else if (strcmp(name, "n_ban_obj_test") == 0)
+ return varnish_submit_derive (conf->instance, "ban", "total_operations", "objects_tested", val);
+ else if (strcmp(name, "n_ban_re_test") == 0)
+ return varnish_submit_derive (conf->instance, "ban", "total_operations", "regexps_tested", val);
+ else if (strcmp(name, "n_ban_dups") == 0)
+ return varnish_submit_derive (conf->instance, "ban", "total_operations", "duplicate", val);
+ }
+#endif
+#if HAVE_VARNISH_V4
+ if (conf->collect_ban)
+ {
+ if (strcmp(name, "bans") == 0)
+ return varnish_submit_derive (conf->instance, "ban", "total_operations", "total", val);
+ else if (strcmp(name, "bans_added") == 0)
+ return varnish_submit_derive (conf->instance, "ban", "total_operations", "added", val);
+ else if (strcmp(name, "bans_obj") == 0)
+ return varnish_submit_derive (conf->instance, "ban", "total_operations", "obj", val);
+ else if (strcmp(name, "bans_req") == 0)
+ return varnish_submit_derive (conf->instance, "ban", "total_operations", "req", val);
+ else if (strcmp(name, "bans_completed") == 0)
+ return varnish_submit_derive (conf->instance, "ban", "total_operations", "completed", val);
+ else if (strcmp(name, "bans_deleted") == 0)
+ return varnish_submit_derive (conf->instance, "ban", "total_operations", "deleted", val);
+ else if (strcmp(name, "bans_tested") == 0)
+ return varnish_submit_derive (conf->instance, "ban", "total_operations", "tested", val);
+ else if (strcmp(name, "bans_dups") == 0)
+ return varnish_submit_derive (conf->instance, "ban", "total_operations", "duplicate", val);
+ }
+#endif
+
+ if (conf->collect_session)
+ {
+ if (strcmp(name, "sess_closed") == 0)
+ return varnish_submit_derive (conf->instance, "session", "total_operations", "closed", val);
+ else if (strcmp(name, "sess_pipeline") == 0)
+ return varnish_submit_derive (conf->instance, "session", "total_operations", "pipeline", val);
+ else if (strcmp(name, "sess_readahead") == 0)
+ return varnish_submit_derive (conf->instance, "session", "total_operations", "readahead", val);
+ else if (strcmp(name, "sess_conn") == 0)
+ return varnish_submit_derive (conf->instance, "session", "total_operations", "accepted", val);
+ else if (strcmp(name, "sess_drop") == 0)
+ return varnish_submit_derive (conf->instance, "session", "total_operations", "dropped", val);
+ else if (strcmp(name, "sess_fail") == 0)
+ return varnish_submit_derive (conf->instance, "session", "total_operations", "failed", val);
+ else if (strcmp(name, "sess_pipe_overflow") == 0)
+ return varnish_submit_derive (conf->instance, "session", "total_operations", "overflow", val);
+ else if (strcmp(name, "sess_queued") == 0)
+ return varnish_submit_derive (conf->instance, "session", "total_operations", "queued", val);
+ else if (strcmp(name, "sess_linger") == 0)
+ return varnish_submit_derive (conf->instance, "session", "total_operations", "linger", val);
+ else if (strcmp(name, "sess_herd") == 0)
+ return varnish_submit_derive (conf->instance, "session", "total_operations", "herd", val);
+ }
+
+ if (conf->collect_shm)
+ {
+ if (strcmp(name, "shm_records") == 0)
+ return varnish_submit_derive (conf->instance, "shm", "total_operations", "records", val);
+ else if (strcmp(name, "shm_writes") == 0)
+ return varnish_submit_derive (conf->instance, "shm", "total_operations", "writes", val);
+ else if (strcmp(name, "shm_flushes") == 0)
+ return varnish_submit_derive (conf->instance, "shm", "total_operations", "flushes", val);
+ else if (strcmp(name, "shm_cont") == 0)
+ return varnish_submit_derive (conf->instance, "shm", "total_operations", "contention", val);
+ else if (strcmp(name, "shm_cycles") == 0)
+ return varnish_submit_derive (conf->instance, "shm", "total_operations", "cycles", val);
+ }
+
+ if (conf->collect_sms)
+ {
+ if (strcmp(name, "sms_nreq") == 0)
+ return varnish_submit_derive (conf->instance, "sms", "total_requests", "allocator", val);
+ else if (strcmp(name, "sms_nobj") == 0)
+ return varnish_submit_gauge (conf->instance, "sms", "requests", "outstanding", val);
+ else if (strcmp(name, "sms_nbytes") == 0)
+ return varnish_submit_gauge (conf->instance, "sms", "bytes", "outstanding", val);
+ else if (strcmp(name, "sms_balloc") == 0)
+ return varnish_submit_derive (conf->instance, "sms", "total_bytes", "allocated", val);
+ else if (strcmp(name, "sms_bfree") == 0)
+ return varnish_submit_derive (conf->instance, "sms", "total_bytes", "free", val);
+ }
+
+ if (conf->collect_struct)
+ {
+ if (strcmp(name, "n_sess_mem") == 0)
+ return varnish_submit_gauge (conf->instance, "struct", "current_sessions", "sess_mem", val);
+ else if (strcmp(name, "n_sess") == 0)
+ return varnish_submit_gauge (conf->instance, "struct", "current_sessions", "sess", val);
+ else if (strcmp(name, "n_object") == 0)
+ return varnish_submit_gauge (conf->instance, "struct", "objects", "object", val);
+ else if (strcmp(name, "n_vampireobject") == 0)
+ return varnish_submit_gauge (conf->instance, "struct", "objects", "vampireobject", val);
+ else if (strcmp(name, "n_objectcore") == 0)
+ return varnish_submit_gauge (conf->instance, "struct", "objects", "objectcore", val);
+ else if (strcmp(name, "n_waitinglist") == 0)
+ return varnish_submit_gauge (conf->instance, "struct", "objects", "waitinglist", val);
+ else if (strcmp(name, "n_objecthead") == 0)
+ return varnish_submit_gauge (conf->instance, "struct", "objects", "objecthead", val);
+ else if (strcmp(name, "n_smf") == 0)
+ return varnish_submit_gauge (conf->instance, "struct", "objects", "smf", val);
+ else if (strcmp(name, "n_smf_frag") == 0)
+ return varnish_submit_gauge (conf->instance, "struct", "objects", "smf_frag", val);
+ else if (strcmp(name, "n_smf_large") == 0)
+ return varnish_submit_gauge (conf->instance, "struct", "objects", "smf_large", val);
+ else if (strcmp(name, "n_vbe_conn") == 0)
+ return varnish_submit_gauge (conf->instance, "struct", "objects", "vbe_conn", val);
+ }
+
+ if (conf->collect_totals)
+ {
+ if (strcmp(name, "s_sess") == 0)
+ return varnish_submit_derive (conf->instance, "totals", "total_sessions", "sessions", val);
+ else if (strcmp(name, "s_req") == 0)
+ return varnish_submit_derive (conf->instance, "totals", "total_requests", "requests", val);
+ else if (strcmp(name, "s_pipe") == 0)
+ return varnish_submit_derive (conf->instance, "totals", "total_operations", "pipe", val);
+ else if (strcmp(name, "s_pass") == 0)
+ return varnish_submit_derive (conf->instance, "totals", "total_operations", "pass", val);
+ else if (strcmp(name, "s_fetch") == 0)
+ return varnish_submit_derive (conf->instance, "totals", "total_operations", "fetches", val);
+ else if (strcmp(name, "s_synth") == 0)
+ return varnish_submit_derive (conf->instance, "totals", "total_bytes", "synth", val);
+ else if (strcmp(name, "s_req_hdrbytes") == 0)
+ return varnish_submit_derive (conf->instance, "totals", "total_bytes", "req_header", val);
+ else if (strcmp(name, "s_req_bodybytes") == 0)
+ return varnish_submit_derive (conf->instance, "totals", "total_bytes", "req_body", val);
+ else if (strcmp(name, "s_resp_hdrbytes") == 0)
+ return varnish_submit_derive (conf->instance, "totals", "total_bytes", "resp_header", val);
+ else if (strcmp(name, "s_resp_bodybytes") == 0)
+ return varnish_submit_derive (conf->instance, "totals", "total_bytes", "resp_body", val);
+ else if (strcmp(name, "s_pipe_hdrbytes") == 0)
+ return varnish_submit_derive (conf->instance, "totals", "total_bytes", "pipe_header", val);
+ else if (strcmp(name, "s_pipe_in") == 0)
+ return varnish_submit_derive (conf->instance, "totals", "total_bytes", "pipe_in", val);
+ else if (strcmp(name, "s_pipe_out") == 0)
+ return varnish_submit_derive (conf->instance, "totals", "total_bytes", "pipe_out", val);
+ else if (strcmp(name, "n_purges") == 0)
+ return varnish_submit_derive (conf->instance, "totals", "total_operations", "purges", val);
+ else if (strcmp(name, "s_hdrbytes") == 0)
+ return varnish_submit_derive (conf->instance, "totals", "total_bytes", "header-bytes", val);
+ else if (strcmp(name, "s_bodybytes") == 0)
+ return varnish_submit_derive (conf->instance, "totals", "total_bytes", "body-bytes", val);
+ else if (strcmp(name, "n_gzip") == 0)
+ return varnish_submit_derive (conf->instance, "totals", "total_operations", "gzip", val);
+ else if (strcmp(name, "n_gunzip") == 0)
+ return varnish_submit_derive (conf->instance, "totals", "total_operations", "gunzip", val);
+ }
+
+ if (conf->collect_uptime)
+ {
+ if (strcmp(name, "uptime") == 0)
+ return varnish_submit_gauge (conf->instance, "uptime", "uptime", "client_uptime", val);
+ }
+
+ if (conf->collect_vcl)
+ {
+ if (strcmp(name, "n_vcl") == 0)
+ return varnish_submit_gauge (conf->instance, "vcl", "vcl", "total_vcl", val);
+ else if (strcmp(name, "n_vcl_avail") == 0)
+ return varnish_submit_gauge (conf->instance, "vcl", "vcl", "avail_vcl", val);
+ else if (strcmp(name, "n_vcl_discard") == 0)
+ return varnish_submit_gauge (conf->instance, "vcl", "vcl", "discarded_vcl", val);
+ else if (strcmp(name, "vmods") == 0)
+ return varnish_submit_gauge (conf->instance, "vcl", "objects", "vmod", val);
+ }
+
+ if (conf->collect_workers)
+ {
+ if (strcmp(name, "threads") == 0)
+ return varnish_submit_gauge (conf->instance, "workers", "threads", "worker", val);
+ else if (strcmp(name, "threads_created") == 0)
+ return varnish_submit_derive (conf->instance, "workers", "total_threads", "created", val);
+ else if (strcmp(name, "threads_failed") == 0)
+ return varnish_submit_derive (conf->instance, "workers", "total_threads", "failed", val);
+ else if (strcmp(name, "threads_limited") == 0)
+ return varnish_submit_derive (conf->instance, "workers", "total_threads", "limited", val);
+ else if (strcmp(name, "threads_destroyed") == 0)
+ return varnish_submit_derive (conf->instance, "workers", "total_threads", "dropped", val);
+ else if (strcmp(name, "thread_queue_len") == 0)
+ return varnish_submit_derive (conf->instance, "workers", "queue_length", "threads", val);
+ else if (strcmp(name, "n_wrk") == 0)
+ return varnish_submit_gauge (conf->instance, "workers", "threads", "worker", val);
+ else if (strcmp(name, "n_wrk_create") == 0)
+ return varnish_submit_derive (conf->instance, "workers", "total_threads", "created", val);
+ else if (strcmp(name, "n_wrk_failed") == 0)
+ return varnish_submit_derive (conf->instance, "workers", "total_threads", "failed", val);
+ else if (strcmp(name, "n_wrk_max") == 0)
+ return varnish_submit_derive (conf->instance, "workers", "total_threads", "limited", val);
+ else if (strcmp(name, "n_wrk_drop") == 0)
+ return varnish_submit_derive (conf->instance, "workers", "total_threads", "dropped", val);
+ else if (strcmp(name, "n_wrk_queue") == 0)
+ return varnish_submit_derive (conf->instance, "workers", "total_requests", "queued", val);
+ else if (strcmp(name, "n_wrk_overflow") == 0)
+ return varnish_submit_derive (conf->instance, "workers", "total_requests", "overflowed", val);
+ else if (strcmp(name, "n_wrk_queued") == 0)
+ return varnish_submit_derive (conf->instance, "workers", "total_requests", "queued", val);
+ else if (strcmp(name, "n_wrk_lqueue") == 0)
+ return varnish_submit_derive (conf->instance, "workers", "total_requests", "queue_length", val);
+ }
+
+#if HAVE_VARNISH_V4
+ if (conf->collect_vsm)
+ {
+ if (strcmp(name, "vsm_free") == 0)
+ return varnish_submit_gauge (conf->instance, "vsm", "bytes", "free", val);
+ else if (strcmp(name, "vsm_used") == 0)
+ return varnish_submit_gauge (conf->instance, "vsm", "bytes", "used", val);
+ else if (strcmp(name, "vsm_cooling") == 0)
+ return varnish_submit_gauge (conf->instance, "vsm", "bytes", "cooling", val);
+ else if (strcmp(name, "vsm_overflow") == 0)
+ return varnish_submit_gauge (conf->instance, "vsm", "bytes", "overflow", val);
+ else if (strcmp(name, "vsm_overflowed") == 0)
+ return varnish_submit_derive (conf->instance, "vsm", "total_bytes", "overflowed", val);
+ }
+#endif
+
+ return (0);
+
+} /* }}} static int varnish_monitor */
+#else /* if HAVE_VARNISH_V2 */
static void varnish_monitor (const user_config_t *conf, /* {{{ */
const c_varnish_stats_t *stats)
{
if (conf->collect_connections)
{
-#ifndef HAVE_VARNISH_V4
/* Client connections accepted */
varnish_submit_derive (conf->instance, "connections", "connections", "accepted", stats->client_conn);
/* Connection dropped, no sess */
varnish_submit_derive (conf->instance, "connections", "connections", "dropped" , stats->client_drop);
-#endif
/* Client requests received */
varnish_submit_derive (conf->instance, "connections", "connections", "received", stats->client_req);
}
-#ifdef HAVE_VARNISH_V3
- if (conf->collect_dirdns)
- {
- /* DNS director lookups */
- varnish_submit_derive (conf->instance, "dirdns", "cache_operation", "lookups", stats->dir_dns_lookups);
- /* DNS director failed lookups */
- varnish_submit_derive (conf->instance, "dirdns", "cache_result", "failed", stats->dir_dns_failed);
- /* DNS director cached lookups hit */
- varnish_submit_derive (conf->instance, "dirdns", "cache_result", "hits", stats->dir_dns_hit);
- /* DNS director full dnscache */
- varnish_submit_derive (conf->instance, "dirdns", "cache_result", "cache_full", stats->dir_dns_cache_full);
- }
-#endif
-
if (conf->collect_esi)
{
/* ESI parse errors (unlock) */
varnish_submit_derive (conf->instance, "esi", "total_operations", "error", stats->esi_errors);
-#if HAVE_VARNISH_V2
/* Objects ESI parsed (unlock) */
varnish_submit_derive (conf->instance, "esi", "total_operations", "parsed", stats->esi_parse);
-#else
- /* ESI parse warnings (unlock) */
- varnish_submit_derive (conf->instance, "esi", "total_operations", "warning", stats->esi_warnings);
-#endif
}
if (conf->collect_backend)
varnish_submit_derive (conf->instance, "backend", "connections", "was-closed" , stats->backend_toolate);
/* Backend conn. recycles */
varnish_submit_derive (conf->instance, "backend", "connections", "recycled" , stats->backend_recycle);
-#if HAVE_VARNISH_V2
/* Backend conn. unused */
varnish_submit_derive (conf->instance, "backend", "connections", "unused" , stats->backend_unused);
-#else
- /* Backend conn. retry */
- varnish_submit_derive (conf->instance, "backend", "connections", "retries" , stats->backend_retry);
-#endif
/* Backend requests mades */
varnish_submit_derive (conf->instance, "backend", "http_requests", "requests" , stats->backend_req);
/* N backends */
varnish_submit_derive (conf->instance, "fetch", "http_requests", "zero" , stats->fetch_zero);
/* Fetch failed */
varnish_submit_derive (conf->instance, "fetch", "http_requests", "failed" , stats->fetch_failed);
-#if HAVE_VARNISH_V3 || HAVE_VARNISH_V4
- /* Fetch no body (1xx) */
- varnish_submit_derive (conf->instance, "fetch", "http_requests", "no_body_1xx", stats->fetch_1xx);
- /* Fetch no body (204) */
- varnish_submit_derive (conf->instance, "fetch", "http_requests", "no_body_204", stats->fetch_204);
- /* Fetch no body (304) */
- varnish_submit_derive (conf->instance, "fetch", "http_requests", "no_body_304", stats->fetch_304);
-#endif
}
if (conf->collect_hcb)
varnish_submit_derive (conf->instance, "objects", "total_objects", "expired", stats->n_expired);
/* N LRU nuked objects */
varnish_submit_derive (conf->instance, "objects", "total_objects", "lru_nuked", stats->n_lru_nuked);
-#if HAVE_VARNISH_V2
/* N LRU saved objects */
varnish_submit_derive (conf->instance, "objects", "total_objects", "lru_saved", stats->n_lru_saved);
-#endif
/* N LRU moved objects */
varnish_submit_derive (conf->instance, "objects", "total_objects", "lru_moved", stats->n_lru_moved);
-#if HAVE_VARNISH_V2
/* N objects on deathrow */
varnish_submit_derive (conf->instance, "objects", "total_objects", "deathrow", stats->n_deathrow);
-#endif
/* HTTP header overflows */
varnish_submit_derive (conf->instance, "objects", "total_objects", "header_overflow", stats->losthdr);
-#if HAVE_VARNISH_V4
- /* N purged objects */
- varnish_submit_derive (conf->instance, "objects", "total_objects", "purged", stats->n_obj_purged);
-#else
/* Objects sent with sendfile */
varnish_submit_derive (conf->instance, "objects", "total_objects", "sent_sendfile", stats->n_objsendfile);
/* Objects sent with write */
varnish_submit_derive (conf->instance, "objects", "total_objects", "sent_write", stats->n_objwrite);
/* Objects overflowing workspace */
varnish_submit_derive (conf->instance, "objects", "total_objects", "workspace_overflow", stats->n_objoverflow);
-#endif
}
-#if HAVE_VARNISH_V2
if (conf->collect_purge)
{
/* N total active purges */
/* N duplicate purges removed */
varnish_submit_derive (conf->instance, "purge", "total_operations", "duplicate", stats->n_purge_dups);
}
-#endif
-#if HAVE_VARNISH_V3
- if (conf->collect_ban)
- {
- /* N total active bans */
- varnish_submit_derive (conf->instance, "ban", "total_operations", "total", stats->n_ban);
- /* N new bans added */
- varnish_submit_derive (conf->instance, "ban", "total_operations", "added", stats->n_ban_add);
- /* N old bans deleted */
- varnish_submit_derive (conf->instance, "ban", "total_operations", "deleted", stats->n_ban_retire);
- /* N objects tested */
- varnish_submit_derive (conf->instance, "ban", "total_operations", "objects_tested", stats->n_ban_obj_test);
- /* N regexps tested against */
- varnish_submit_derive (conf->instance, "ban", "total_operations", "regexps_tested", stats->n_ban_re_test);
- /* N duplicate bans removed */
- varnish_submit_derive (conf->instance, "ban", "total_operations", "duplicate", stats->n_ban_dups);
- }
-#endif
-#if HAVE_VARNISH_V4
- if (conf->collect_ban)
- {
- /* N total active bans */
- varnish_submit_derive (conf->instance, "ban", "total_operations", "total", stats->bans);
- /* N new bans added */
- varnish_submit_derive (conf->instance, "ban", "total_operations", "added", stats->bans_added);
- /* N bans using obj */
- varnish_submit_derive (conf->instance, "ban", "total_operations", "obj", stats->bans_obj);
- /* N bans using req */
- varnish_submit_derive (conf->instance, "ban", "total_operations", "req", stats->bans_req);
- /* N new bans completed */
- varnish_submit_derive (conf->instance, "ban", "total_operations", "completed", stats->bans_completed);
- /* N old bans deleted */
- varnish_submit_derive (conf->instance, "ban", "total_operations", "deleted", stats->bans_deleted);
- /* N objects tested */
- varnish_submit_derive (conf->instance, "ban", "total_operations", "tested", stats->bans_tested);
- /* N duplicate bans removed */
- varnish_submit_derive (conf->instance, "ban", "total_operations", "duplicate", stats->bans_dups);
- }
-#endif
if (conf->collect_session)
{
varnish_submit_derive (conf->instance, "session", "total_operations", "pipeline", stats->sess_pipeline);
/* Session Read Ahead */
varnish_submit_derive (conf->instance, "session", "total_operations", "readahead", stats->sess_readahead);
-#if HAVE_VARNISH_V4
- /* Sessions accepted */
- varnish_submit_derive (conf->instance, "session", "total_operations", "accepted", stats->sess_conn);
- /* Sessions dropped for thread */
- varnish_submit_derive (conf->instance, "session", "total_operations", "dropped", stats->sess_drop);
- /* Sessions accept failure */
- varnish_submit_derive (conf->instance, "session", "total_operations", "failed", stats->sess_fail);
- /* Sessions pipe overflow */
- varnish_submit_derive (conf->instance, "session", "total_operations", "overflow", stats->sess_pipe_overflow);
- /* Sessions queued for thread */
- varnish_submit_derive (conf->instance, "session", "total_operations", "queued", stats->sess_queued);
-#else
/* Session Linger */
varnish_submit_derive (conf->instance, "session", "total_operations", "linger", stats->sess_linger);
-#endif
/* Session herd */
varnish_submit_derive (conf->instance, "session", "total_operations", "herd", stats->sess_herd);
}
varnish_submit_derive (conf->instance, "shm", "total_operations", "cycles" , stats->shm_cycles);
}
-#if HAVE_VARNISH_V2
if (conf->collect_sm)
{
/* allocator requests */
/* SMA bytes free */
varnish_submit_derive (conf->instance, "sma", "total_bytes", "free" , stats->sma_bfree);
}
-#endif
if (conf->collect_sms)
{
if (conf->collect_struct)
{
-#if !HAVE_VARNISH_V4
/* N struct sess_mem */
varnish_submit_gauge (conf->instance, "struct", "current_sessions", "sess_mem", stats->n_sess_mem);
/* N struct sess */
varnish_submit_gauge (conf->instance, "struct", "current_sessions", "sess", stats->n_sess);
-#endif
/* N struct object */
varnish_submit_gauge (conf->instance, "struct", "objects", "object", stats->n_object);
-#if HAVE_VARNISH_V3 || HAVE_VARNISH_V4
- /* N unresurrected objects */
- varnish_submit_gauge (conf->instance, "struct", "objects", "vampireobject", stats->n_vampireobject);
- /* N struct objectcore */
- varnish_submit_gauge (conf->instance, "struct", "objects", "objectcore", stats->n_objectcore);
- /* N struct waitinglist */
- varnish_submit_gauge (conf->instance, "struct", "objects", "waitinglist", stats->n_waitinglist);
-#endif
/* N struct objecthead */
varnish_submit_gauge (conf->instance, "struct", "objects", "objecthead", stats->n_objecthead);
-#ifdef HAVE_VARNISH_V2
/* N struct smf */
varnish_submit_gauge (conf->instance, "struct", "objects", "smf", stats->n_smf);
/* N small free smf */
varnish_submit_gauge (conf->instance, "struct", "objects", "smf_large", stats->n_smf_large);
/* N struct vbe_conn */
varnish_submit_gauge (conf->instance, "struct", "objects", "vbe_conn", stats->n_vbe_conn);
-#endif
}
if (conf->collect_totals)
varnish_submit_derive (conf->instance, "totals", "total_operations", "pass", stats->s_pass);
/* Total fetch */
varnish_submit_derive (conf->instance, "totals", "total_operations", "fetches", stats->s_fetch);
-#if HAVE_VARNISH_V4
- /* Total synth */
- varnish_submit_derive (conf->instance, "totals", "total_bytes", "synth", stats->s_synth);
- /* Request header bytes */
- varnish_submit_derive (conf->instance, "totals", "total_bytes", "req_header", stats->s_req_hdrbytes);
- /* Request body byte */
- varnish_submit_derive (conf->instance, "totals", "total_bytes", "req_body", stats->s_req_bodybytes);
- /* Response header bytes */
- varnish_submit_derive (conf->instance, "totals", "total_bytes", "resp_header", stats->s_resp_hdrbytes);
- /* Response body byte */
- varnish_submit_derive (conf->instance, "totals", "total_bytes", "resp_body", stats->s_resp_bodybytes);
- /* Pipe request header bytes */
- varnish_submit_derive (conf->instance, "totals", "total_bytes", "pipe_header", stats->s_pipe_hdrbytes);
- /* Piped bytes from client */
- varnish_submit_derive (conf->instance, "totals", "total_bytes", "pipe_in", stats->s_pipe_in);
- /* Piped bytes to client */
- varnish_submit_derive (conf->instance, "totals", "total_bytes", "pipe_out", stats->s_pipe_out);
- /* Number of purge operations */
- varnish_submit_derive (conf->instance, "totals", "total_operations", "purges", stats->n_purges);
-#else
/* Total header bytes */
varnish_submit_derive (conf->instance, "totals", "total_bytes", "header-bytes", stats->s_hdrbytes);
/* Total body byte */
varnish_submit_derive (conf->instance, "totals", "total_bytes", "body-bytes", stats->s_bodybytes);
-#endif
-#if HAVE_VARNISH_V3 || HAVE_VARNISH_V4
- /* Gzip operations */
- varnish_submit_derive (conf->instance, "totals", "total_operations", "gzip", stats->n_gzip);
- /* Gunzip operations */
- varnish_submit_derive (conf->instance, "totals", "total_operations", "gunzip", stats->n_gunzip);
-#endif
}
-#if HAVE_VARNISH_V3 || HAVE_VARNISH_V4
- if (conf->collect_uptime)
- {
- /* Client uptime */
- varnish_submit_gauge (conf->instance, "uptime", "uptime", "client_uptime", stats->uptime);
- }
-#endif
-
if (conf->collect_vcl)
{
/* N vcl total */
varnish_submit_gauge (conf->instance, "vcl", "vcl", "avail_vcl", stats->n_vcl_avail);
/* N vcl discarded */
varnish_submit_gauge (conf->instance, "vcl", "vcl", "discarded_vcl", stats->n_vcl_discard);
-#if HAVE_VARNISH_V3 || HAVE_VARNISH_V4
- /* Loaded VMODs */
- varnish_submit_gauge (conf->instance, "vcl", "objects", "vmod", stats->vmods);
-#endif
}
if (conf->collect_workers)
{
-#ifdef HAVE_VARNISH_V4
- /* total number of threads */
- varnish_submit_gauge (conf->instance, "workers", "threads", "worker", stats->threads);
- /* threads created */
- varnish_submit_derive (conf->instance, "workers", "total_threads", "created", stats->threads_created);
- /* thread creation failed */
- varnish_submit_derive (conf->instance, "workers", "total_threads", "failed", stats->threads_failed);
- /* threads hit max */
- varnish_submit_derive (conf->instance, "workers", "total_threads", "limited", stats->threads_limited);
- /* threads destroyed */
- varnish_submit_derive (conf->instance, "workers", "total_threads", "dropped", stats->threads_destroyed);
- /* length of session queue */
- varnish_submit_derive (conf->instance, "workers", "queue_length", "threads", stats->thread_queue_len);
-#else
/* worker threads */
varnish_submit_gauge (conf->instance, "workers", "threads", "worker", stats->n_wrk);
/* worker threads created */
varnish_submit_derive (conf->instance, "workers", "total_threads", "limited", stats->n_wrk_max);
/* dropped work requests */
varnish_submit_derive (conf->instance, "workers", "total_threads", "dropped", stats->n_wrk_drop);
-#ifdef HAVE_VARNISH_V2
/* queued work requests */
varnish_submit_derive (conf->instance, "workers", "total_requests", "queued", stats->n_wrk_queue);
/* overflowed work requests */
varnish_submit_derive (conf->instance, "workers", "total_requests", "overflowed", stats->n_wrk_overflow);
-#else /* HAVE_VARNISH_V3 */
- /* queued work requests */
- varnish_submit_derive (conf->instance, "workers", "total_requests", "queued", stats->n_wrk_queued);
- /* work request queue length */
- varnish_submit_derive (conf->instance, "workers", "total_requests", "queue_length", stats->n_wrk_lqueue);
-#endif
-#endif
}
-#if HAVE_VARNISH_V4
- if (conf->collect_vsm)
- {
- /* Free VSM space */
- varnish_submit_gauge (conf->instance, "vsm", "bytes", "free", stats->vsm_free);
- /* Used VSM space */
- varnish_submit_gauge (conf->instance, "vsm", "bytes", "used", stats->vsm_used);
- /* Cooling VSM space */
- varnish_submit_gauge (conf->instance, "vsm", "bytes", "cooling", stats->vsm_cooling);
- /* Overflow VSM space */
- varnish_submit_gauge (conf->instance, "vsm", "bytes", "overflow", stats->vsm_overflow);
- /* Total overflowed VSM space */
- varnish_submit_derive (conf->instance, "vsm", "total_bytes", "overflowed", stats->vsm_overflowed);
- }
-#endif
-
} /* }}} void varnish_monitor */
+#endif
#if HAVE_VARNISH_V3 || HAVE_VARNISH_V4
static int varnish_read (user_data_t *ud) /* {{{ */
{
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.");
return (-1);
}
-
- varnish_monitor (conf, stats);
+#if HAVE_VARNISH_V3
+ VSC_Iter (vd, varnish_monitor, conf);
+#else /* if HAVE_VARNISH_V4 */
+ VSC_Iter (vd, NULL, varnish_monitor, conf);
+#endif
VSM_Delete (vd);
return (0);
{
WARNING ("Varnish plugin: \"Instance\" blocks accept only "
"one argument.");
+ sfree (conf);
return (EINVAL);
}
WARNING ("Varnish plugin: No metric has been configured for "
"instance \"%s\". Disabling this instance.",
(conf->instance == NULL) ? "localhost" : conf->instance);
+ sfree (conf);
return (EINVAL);
}
value_t value = { .derive = counter };
submit_one (inst, "vmpage_action", "refill", value);
}
+ else if (strncmp ("pgsteal_kswapd_", key, strlen ("pgsteal_kswapd_")) == 0)
+ {
+ char *inst = key + strlen ("pgsteal_kswapd_");
+ value_t value = { .derive = counter };
+ submit_one (inst, "vmpage_action", "steal_kswapd", value);
+ }
+ else if (strncmp ("pgsteal_direct_", key, strlen ("pgsteal_direct_")) == 0)
+ {
+ char *inst = key + strlen ("pgsteal_direct_");
+ value_t value = { .derive = counter };
+ submit_one (inst, "vmpage_action", "steal_direct", value);
+ }
+ /* For backwards compatibility (somewhen before 4.2.3) */
else if (strncmp ("pgsteal_", key, strlen ("pgsteal_")) == 0)
{
char *inst = key + strlen ("pgsteal_");
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
ssize_t status = 0;
status = swrite (cb->sock_fd, cb->send_buf, strlen (cb->send_buf));
- if (status < 0)
+ if (status != 0)
{
if (cb->log_send_errors)
{
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->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)
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));
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)
- cf_util_get_boolean (child, &cb->log_http_error);
+ status = cf_util_get_boolean (child, &cb->log_http_error);
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);
+ 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;
- else
- key = rand();
+ key = ctx->key;
+ if (key != NULL)
+ keylen = strlen (key);
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;
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);
} 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 : */
struct timeval timeout;
char *prefix;
int database;
+ int max_set_size;
+ _Bool store_rates;
redisContext *conn;
pthread_mutex_t lock;
char *value_ptr;
int status;
redisReply *rr;
- int i;
status = FORMAT_VL (ident, sizeof (ident), vl);
if (status != 0)
memset (value, 0, sizeof (value));
value_size = sizeof (value);
value_ptr = &value[0];
-
-#define APPEND(...) do { \
- status = snprintf (value_ptr, value_size, __VA_ARGS__); \
- if (((size_t) status) > value_size) \
- { \
- value_ptr += value_size; \
- value_size = 0; \
- } \
- else \
- { \
- value_ptr += status; \
- value_size -= status; \
- } \
-} while (0)
-
- APPEND ("%s:", time);
-
- for (i = 0; i < ds->ds_num; i++)
- {
- if (ds->ds[i].type == DS_TYPE_COUNTER)
- APPEND ("%llu", vl->values[i].counter);
- else if (ds->ds[i].type == DS_TYPE_GAUGE)
- APPEND (GAUGE_FORMAT, vl->values[i].gauge);
- else if (ds->ds[i].type == DS_TYPE_DERIVE)
- APPEND ("%"PRIi64, vl->values[i].derive);
- else if (ds->ds[i].type == DS_TYPE_ABSOLUTE)
- APPEND ("%"PRIu64, vl->values[i].absolute);
- else
- assert (23 == 42);
- }
-
-#undef APPEND
-
- status = format_values (value_ptr, value_size, ds, vl, /* store rates = */ 0);
- pthread_mutex_lock (&node->lock);
+ status = format_values (value_ptr, value_size, ds, vl, node->store_rates);
if (status != 0)
return (status);
+ pthread_mutex_lock (&node->lock);
+
if (node->conn == NULL)
{
node->conn = redisConnectWithTimeout ((char *)node->host, node->port, node->timeout);
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);
+ 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. */
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));
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);
}
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);
#include "utils_threshold.h"
#include <assert.h>
-#include <ltdl.h>
#include <pthread.h>
/*
char *handlers_str = build_json_str_list("handlers", &(host->notification_handlers));
if (handlers_str == NULL) {
ERROR("write_sensu plugin: Unable to alloc memory");
+ free(ret_str);
return NULL;
}
// incorporate the handlers
char *msg = replace_json_reserved(n->message);
if (msg == NULL) {
ERROR("write_sensu plugin: Unable to alloc memory");
+ free(ret_str);
return NULL;
}
res = asprintf(&temp_str, "%s, \"output\": \"%s - %s\"", ret_str, severity, msg);
ERROR("write_tsdb plugin: Connecting to %s:%s failed. "
"The last error was: %s", node, service,
sstrerror (errno, errbuf, sizeof(errbuf)));
- close(cb->sock_fd);
return -1;
}
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)
{
- ERROR ("zfs_arc plugin: `llist_search` failed for key: '%s'.", name);
+ sfree (v_copy);
+ sfree (k_copy);
+ return ENOMEM;
+ }
+
+ llist_append (ksp, e);
+ return 0;
+}
+
+static long long get_zfs_value(kstat_t *ksp, 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'.", 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
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;
+ 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));
- 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;
- 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);
- 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 ++;
- }
- }
+ status = parse_value (fields[2], &v, DS_TYPE_DERIVE);
+ if (status != 0)
+ continue;
+
+ put_zfs_value (ksp, fields[0], v);
}
+ fclose (fh);
+
#elif !defined(__FreeBSD__) // Solaris
get_kstat (&ksp, "zfs", 0, "arcstats");
if (ksp == NULL)
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);
}
buffer_fill += (size_t) status;
- if (status == 0)
- {
- /* done reading from the socket */
- break;
- }
} /* while (recv) */
status = 0;
DEFAULT_VERSION="5.5.0.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"