if test "x$ac_system" = "xSolaris"
then
- CPPFLAGS="$CPPFLAGS -D_POSIX_PTHREAD_SEMANTICS"
+ AC_DEFINE(_POSIX_PTHREAD_SEMANTICS, 1, [Define to enforce POSIX thread semantics under Solaris.])
fi
# Where to install .pc files.
pkgconfigdir="${libdir}/pkgconfig"
AC_SUBST(pkgconfigdir)
+# Check for standards compliance mode
+AC_ARG_ENABLE(standards,
+ AS_HELP_STRING([--enable-standards], [Enable standards compliance mode]),
+ [enable_standards="$enableval"],
+ [enable_standards="no"])
+if test "x$enable_standards" = "xyes"
+then
+ AC_DEFINE(_ISOC99_SOURCE, 1, [Define to enforce ISO C99 compliance.])
+ AC_DEFINE(_POSIX_C_SOURCE, 200112L, [Define to enforce POSIX.1-2001 compliance.])
+ AC_DEFINE(_XOPEN_SOURCE, 600, [Define to enforce X/Open 6 (XSI) compliance.])
+ AC_DEFINE(_REENTRANT, 1, [Define to enable reentrancy interfaces.])
+fi
+AM_CONDITIONAL(BUILD_FEATURE_STANDARDS, test "x$enable_standards" = "xyes")
+
#
# Checks for header files.
#
#endif
])
-AC_CHECK_HEADERS(pwd.h grp.h sys/un.h ctype.h limits.h sys/quota.h xfs/xqm.h fs_info.h fshelp.h paths.h mntent.h mnttab.h sys/fstyp.h sys/fs_types.h sys/mntent.h sys/mnttab.h sys/statfs.h sys/statvfs.h sys/vfs.h sys/vfstab.h kvm.h wordexp.h)
+AC_CHECK_HEADERS(pwd.h grp.h sys/un.h ctype.h limits.h xfs/xqm.h fs_info.h fshelp.h paths.h mntent.h mnttab.h sys/fstyp.h sys/fs_types.h sys/mntent.h sys/mnttab.h sys/statfs.h sys/statvfs.h sys/vfs.h sys/vfstab.h kvm.h wordexp.h)
# For the dns plugin
AC_CHECK_HEADERS(arpa/nameser.h)
])
AC_CHECK_MEMBERS([struct udphdr.uh_dport, struct udphdr.uh_sport], [], [],
-[#if HAVE_STDINT_H
+[#define _BSD_SOURCE
+#if HAVE_STDINT_H
# include <stdint.h>
#endif
#if HAVE_SYS_TYPES_H
#endif
])
AC_CHECK_MEMBERS([struct udphdr.dest, struct udphdr.source], [], [],
-[#if HAVE_STDINT_H
+[#define _BSD_SOURCE
+#if HAVE_STDINT_H
# include <stdint.h>
#endif
#if HAVE_SYS_TYPES_H
AM_CONDITIONAL(BUILD_WITH_LIBESMTP, test "x$with_libesmtp" = "xyes")
# }}}
+# --with-libganglia {{{
+AC_ARG_WITH(libganglia, [AS_HELP_STRING([--with-libganglia@<:@=PREFIX@:>@], [Path to libganglia.])],
+[
+ if test -f "$withval" && test -x "$withval"
+ then
+ with_libganglia_config="$withval"
+ with_libganglia="yes"
+ else if test -f "$withval/bin/ganglia-config" && test -x "$withval/bin/ganglia-config"
+ then
+ with_libganglia_config="$withval/bin/ganglia-config"
+ with_libganglia="yes"
+ else if test -d "$withval"
+ then
+ GANGLIA_CPPFLAGS="-I$withval/include"
+ 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"
+then
+ 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_LIBS" = "x"
+ then
+ GANGLIA_LIBS=`"$with_libganglia_config" --libs 2>/dev/null`
+ fi
+fi
+
+SAVE_CPPFLAGS="$CPPFLAGS"
+SAVE_LDFLAGS="$LDFLAGS"
+CPPFLAGS="$CPPFLAGS $GANGLIA_CPPFLAGS"
+LDFLAGS="$LDFLAGS $GANGLIA_LDFLAGS"
+
+if test "x$with_libganglia" = "xyes"
+then
+ AC_CHECK_HEADERS(gm_protocol.h,
+ [
+ AC_DEFINE(HAVE_GM_PROTOCOL_H, 1,
+ [Define to 1 if you have the <gm_protocol.h> header file.])
+ ], [with_libganglia="no (gm_protocol.h not found)"])
+fi
+
+if test "x$with_libganglia" = "xyes"
+then
+ AC_CHECK_LIB(ganglia, xdr_Ganglia_value_msg,
+ [
+ AC_DEFINE(HAVE_LIBGANGLIA, 1,
+ [Define to 1 if you have the ganglia library (-lganglia).])
+ ], [with_libganglia="no (symbol xdr_Ganglia_value_msg not found)"])
+fi
+
+CPPFLAGS="$SAVE_CPPFLAGS"
+LDFLAGS="$SAVE_LDFLAGS"
+
+AC_SUBST(GANGLIA_CPPFLAGS)
+AC_SUBST(GANGLIA_LDFLAGS)
+AC_SUBST(GANGLIA_LIBS)
+AM_CONDITIONAL(BUILD_WITH_LIBGANGLIA, test "x$with_libganglia" = "xyes")
+# }}}
+
+# --with-libgcrypt {{{
+GCRYPT_CPPFLAGS="$GCRYPT_CPPFLAGS"
+GCRYPT_LDFLAGS="$GCRYPT_LDFLAGS"
+GCRYPT_LIBS="$GCRYPT_LIBS"
+AC_ARG_WITH(libgcrypt, [AS_HELP_STRING([--with-libgcrypt@<:@=PREFIX@:>@], [Path to libgcrypt.])],
+[
+ if test -f "$withval" && test -x "$withval"
+ then
+ with_libgcrypt_config="$withval"
+ with_libgcrypt="yes"
+ else if test -f "$withval/bin/gcrypt-config" && test -x "$withval/bin/gcrypt-config"
+ then
+ with_libgcrypt_config="$withval/bin/gcrypt-config"
+ with_libgcrypt="yes"
+ else if test -d "$withval"
+ then
+ GCRYPT_CPPFLAGS="$GCRYPT_CPPFLAGS -I$withval/include"
+ GCRYPT_LDFLAGS="$GCRYPT_LDFLAGS -L$withval/lib"
+ with_libgcrypt="yes"
+ else
+ with_libgcrypt_config="gcrypt-config"
+ with_libgcrypt="$withval"
+ fi; fi; fi
+],
+[
+ with_libgcrypt_config="libgcrypt-config"
+ with_libgcrypt="yes"
+])
+
+if test "x$with_libgcrypt" = "xyes" && test "x$with_libgcrypt_config" != "x"
+then
+ if test "x$GCRYPT_CPPFLAGS" = "x"
+ then
+ 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`
+ fi
+fi
+
+SAVE_CPPFLAGS="$CPPFLAGS"
+SAVE_LDFLAGS="$LDFLAGS"
+CPPFLAGS="$CPPFLAGS $GCRYPT_CPPFLAGS"
+LDFLAGS="$LDFLAGS $GCRYPT_LDFLAGS"
+
+if test "x$with_libgcrypt" = "xyes"
+then
+ if test "x$GCRYPT_CPPFLAGS" != "x"
+ then
+ AC_MSG_NOTICE([gcrypt CPPFLAGS: $GCRYPT_CPPFLAGS])
+ fi
+ AC_CHECK_HEADERS(gcrypt.h,
+ [with_libgcrypt="yes"],
+ [with_libgcrypt="no (gcrypt.h not found)"])
+fi
+
+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
+ AM_PATH_LIBGCRYPT(1:1.2.0,,with_libgcrypt="no (version 1.2.0+ required)")
+ fi
+fi
+
+CPPFLAGS="$SAVE_CPPFLAGS"
+LDFLAGS="$SAVE_LDFLAGS"
+
+if test "x$with_libgcrypt" = "xyes"
+then
+ AC_DEFINE(HAVE_LIBGCRYPT, 1, [Define to 1 if you have the gcrypt library (-lgcrypt).])
+fi
+
+AC_SUBST(GCRYPT_CPPFLAGS)
+AC_SUBST(GCRYPT_LDFLAGS)
+AC_SUBST(GCRYPT_LIBS)
+AM_CONDITIONAL(BUILD_WITH_LIBGCRYPT, test "x$with_libgcrypt" = "xyes")
+# }}}
+
# --with-libiptc {{{
with_own_libiptc="no"
AC_ARG_WITH(libiptc, [AS_HELP_STRING([--with-libiptc@<:@=PREFIX@:>@], [Path to libiptc.])],
fi
# }}}
+# --with-java {{{
+with_java_home="$JAVA_HOME"
+with_java_vmtype="client"
+with_java_cflags=""
+with_java_libs=""
+JAVAC="$JAVAC"
+AC_ARG_WITH(java, [AS_HELP_STRING([--with-java@<:@=PREFIX@:>@], [Path to Java home.])],
+[
+ if test "x$withval" = "xno"
+ then
+ with_java="no"
+ else if test "x$withval" = "xyes"
+ then
+ with_java="yes"
+ else
+ with_java_home="$withval"
+ with_java="yes"
+ fi; fi
+],
+[with_java="yes"])
+if test "x$with_java" = "xyes"
+then
+ if test -d "$with_java_home"
+ then
+ AC_MSG_CHECKING([for jni.h])
+ TMPDIR=`find -L "$with_java_home" -name jni.h -type f -exec 'dirname' '{}' ';' | head -n 1`
+ if test "x$TMPDIR" != "x"
+ then
+ AC_MSG_RESULT([found in $TMPDIR])
+ JAVA_CPPFLAGS="$JAVA_CPPFLAGS -I$TMPDIR"
+ else
+ AC_MSG_RESULT([not found])
+ fi
+
+ AC_MSG_CHECKING([for jni_md.h])
+ TMPDIR=`find -L "$with_java_home" -name jni_md.h -type f -exec 'dirname' '{}' ';' | head -n 1`
+ if test "x$TMPDIR" != "x"
+ then
+ AC_MSG_RESULT([found in $TMPDIR])
+ JAVA_CPPFLAGS="$JAVA_CPPFLAGS -I$TMPDIR"
+ else
+ AC_MSG_RESULT([not found])
+ fi
+
+ AC_MSG_CHECKING([for libjvm.so])
+ TMPDIR=`find -L "$with_java_home" -name libjvm.so -type f -exec 'dirname' '{}' ';' | head -n 1`
+ if test "x$TMPDIR" != "x"
+ then
+ AC_MSG_RESULT([found in $TMPDIR])
+ JAVA_LDFLAGS="$JAVA_LDFLAGS -L$TMPDIR"
+ else
+ AC_MSG_RESULT([not found])
+ fi
+
+ if test "x$JAVAC" = "x"
+ then
+ AC_MSG_CHECKING([for javac])
+ TMPDIR=`find -L "$with_java_home" -name javac -type f | head -n 1`
+ if test "x$TMPDIR" != "x"
+ then
+ JAVAC="$TMPDIR"
+ AC_MSG_RESULT([$JAVAC])
+ else
+ AC_MSG_RESULT([not found])
+ fi
+ fi
+ else if test "x$with_java_home" != "x"
+ then
+ AC_MSG_WARN([JAVA_HOME: No such directory: $with_java_home])
+ fi; fi
+fi
+
+if test "x$JAVA_CPPFLAGS" != "x"
+then
+ AC_MSG_NOTICE([Building with JAVA_CPPFLAGS set to: $JAVA_CPPFLAGS])
+fi
+if test "x$JAVA_CFLAGS" != "x"
+then
+ AC_MSG_NOTICE([Building with JAVA_CFLAGS set to: $JAVA_CFLAGS])
+fi
+if test "x$JAVA_LDFLAGS" != "x"
+then
+ AC_MSG_NOTICE([Building with JAVA_LDFLAGS set to: $JAVA_LDFLAGS])
+fi
+if test "x$JAVAC" = "x"
+then
+ with_javac_path="$PATH"
+ if test "x$with_java_home" != "x"
+ then
+ with_javac_path="$with_java_home:with_javac_path"
+ if test -d "$with_java_home/bin"
+ then
+ with_javac_path="$with_java_home/bin:with_javac_path"
+ fi
+ fi
+
+ AC_PATH_PROG(JAVAC, javac, [], "$with_javac_path")
+fi
+if test "x$JAVAC" = "x"
+then
+ with_java="no (javac not found)"
+fi
+
+SAVE_CPPFLAGS="$CPPFLAGS"
+SAVE_CFLAGS="$CFLAGS"
+SAVE_LDFLAGS="$LDFLAGS"
+CPPFLAGS="$CPPFLAGS $JAVA_CPPFLAGS"
+CFLAGS="$CFLAGS $JAVA_CFLAGS"
+LDFLAGS="$LDFLAGS $JAVA_LDFLAGS"
+
+if test "x$with_java" = "xyes"
+then
+ AC_CHECK_HEADERS(jni.h, [], [with_java="no (jni.h not found)"])
+fi
+if test "x$with_java" = "xyes"
+then
+ AC_CHECK_LIB(jvm, JNI_CreateJavaVM,
+ [with_java="yes"],
+ [with_java="no (libjvm not found)"],
+ [$JAVA_LIBS])
+fi
+if test "x$with_java" = "xyes"
+then
+ JAVA_LIBS="$JAVA_LIBS -ljvm"
+ AC_MSG_NOTICE([Building with JAVA_LIBS set to: $JAVA_LIBS])
+fi
+
+CPPFLAGS="$SAVE_CPPFLAGS"
+CFLAGS="$SAVE_CFLAGS"
+LDFLAGS="$SAVE_LDFLAGS"
+
+AC_SUBST(JAVA_CPPFLAGS)
+AC_SUBST(JAVA_CFLAGS)
+AC_SUBST(JAVA_LDFLAGS)
+AC_SUBST(JAVA_LIBS)
+AM_CONDITIONAL(BUILD_WITH_JAVA, test "x$with_java" = "xyes")
+# }}}
+
+# --with-libmemcached {{{
+with_libmemcached_cppflags=""
+with_libmemcached_ldflags=""
+AC_ARG_WITH(libmemcached, [AS_HELP_STRING([--with-libmemcached@<:@=PREFIX@:>@], [Path to libmemcached.])],
+[
+ if test "x$withval" != "xno" && test "x$withval" != "xyes"
+ then
+ with_libmemcached_cppflags="-I$withval/include"
+ with_libmemcached_ldflags="-L$withval/lib"
+ with_libmemcached="yes"
+ else
+ with_libmemcached="$withval"
+ fi
+],
+[
+ with_libmemcached="yes"
+])
+if test "x$with_libmemcached" = "xyes"
+then
+ SAVE_CPPFLAGS="$CPPFLAGS"
+ CPPFLAGS="$CPPFLAGS $with_libmemcached_cppflags"
+
+ AC_CHECK_HEADERS(libmemcached/memcached.h, [with_libmemcached="yes"], [with_libmemcached="no (libmemcached/memcached.h not found)"])
+
+ CPPFLAGS="$SAVE_CPPFLAGS"
+fi
+if test "x$with_libmemcached" = "xyes"
+then
+ SAVE_CPPFLAGS="$CPPFLAGS"
+ SAVE_LDFLAGS="$LDFLAGS"
+ CPPFLAGS="$CPPFLAGS $with_libmemcached_cppflags"
+ LDFLAGS="$LDFLAGS $with_libmemcached_ldflags"
+
+ AC_CHECK_LIB(memcached, memcached_create, [with_libmemcached="yes"], [with_libmemcached="no (Symbol 'memcached_create' not found)"])
+
+ CPPFLAGS="$SAVE_CPPFLAGS"
+ LDFLAGS="$SAVE_LDFLAGS"
+fi
+if test "x$with_libmemcached" = "xyes"
+then
+ BUILD_WITH_LIBMEMCACHED_CPPFLAGS="$with_libmemcached_cppflags"
+ BUILD_WITH_LIBMEMCACHED_LDFLAGS="$with_libmemcached_ldflags"
+ BUILD_WITH_LIBMEMCACHED_LIBS="-lmemcached"
+ AC_SUBST(BUILD_WITH_LIBMEMCACHED_CPPFLAGS)
+ AC_SUBST(BUILD_WITH_LIBMEMCACHED_LDFLAGS)
+ AC_SUBST(BUILD_WITH_LIBMEMCACHED_LIBS)
+ AC_DEFINE(HAVE_LIBMEMCACHED, 1, [Define if libmemcached is present and usable.])
+fi
+AM_CONDITIONAL(BUILD_WITH_LIBMEMCACHED, test "x$with_libmemcached" = "xyes")
+# }}}
+
# --with-libmysql {{{
with_mysql_config="mysql_config"
with_mysql_cflags=""
# }}}
# --with-liboping {{{
-with_own_liboping="no"
-liboping_LDFLAGS="$LDFLAGS"
-liboping_CPPFLAGS="$CPPFLAGS"
AC_ARG_WITH(liboping, [AS_HELP_STRING([--with-liboping@<:@=PREFIX@:>@], [Path to liboping.])],
[
- if test "x$withval" != "xno" && test "x$withval" != "xyes"
+ if test "x$withval" = "xyes"
+ then
+ with_liboping="yes"
+ else if test "x$withval" = "xno"
+ then
+ with_liboping="no"
+ else
+ with_liboping="yes"
+ LIBOPING_CPPFLAGS="$LIBOPING_CPPFLAGS -I$withval/include"
+ LIBOPING_LDFLAGS="$LIBOPING_LDFLAGS -L$withval/lib"
+ fi; fi
+],
+[with_liboping="yes"])
+
+SAVE_CPPFLAGS="$CPPFLAGS"
+SAVE_LDFLAGS="$LDFLAGS"
+
+CPPFLAGS="$CPPFLAGS $LIBOPING_CPPFLAGS"
+LDFLAGS="$LDFLAGS $LIBOPING_LDFLAGS"
+
+if test "x$with_liboping" = "xyes"
+then
+ if test "x$LIBOPING_CPPFLAGS" != "x"
then
- if test -d "$withval/lib"
- then
- liboping_LDFLAGS="$LDFLAGS -L$withval/lib"
- fi
- if test -d "$withval/include"
- then
- liboping_CPPFLAGS="$CPPFLAGS -I$withval/include"
- fi
+ AC_MSG_NOTICE([liboping CPPFLAGS: $LIBOPING_CPPFLAGS])
fi
- if test "x$withval" = "xno"
- then
- with_liboping="no"
- with_own_liboping="no"
- else if test "x$withval" = "xyes"
+ AC_CHECK_HEADERS(oping.h,
+ [with_liboping="yes"],
+ [with_liboping="no ('oping.h' not found)"])
+fi
+if test "x$with_liboping" = "xyes"
+then
+ if test "x$LIBOPING_LDFLAGS" != "x"
then
- with_liboping="yes"
- fi; fi
-],
-[
- with_liboping="yes"
-])
+ AC_MSG_NOTICE([liboping LDFLAGS: $LIBOPING_LDFLAGS])
+ fi
+ AC_CHECK_LIB(oping, ping_construct,
+ [with_liboping="yes"],
+ [with_liboping="no (symbol 'ping_construct' not found)"])
+fi
+
+CPPFLAGS="$SAVE_CPPFLAGS"
+LDFLAGS="$SAVE_LDFLAGS"
if test "x$with_liboping" = "xyes"
then
- save_LDFLAGS="$LDFLAGS"
- save_CPPFLAGS="$CPPFLAGS"
- LDFLAGS="$liboping_LDFLAGS"
- CPPFLAGS="$liboping_CPPFLAGS"
- AC_CHECK_LIB(oping, ping_construct,
- [
- with_liboping="yes"
- with_own_liboping="no"
- ],
- [
- with_liboping="yes"
- with_own_liboping="yes"
- LDFLAGS="$save_LDFLAGS"
- CPPFLAGS="$save_CPPFLAGS"
- ])
+ BUILD_WITH_LIBOPING_CPPFLAGS="$LIBOPING_CPPFLAGS"
+ BUILD_WITH_LIBOPING_LDFLAGS="$LIBOPING_LDFLAGS"
+ AC_SUBST(BUILD_WITH_LIBOPING_CPPFLAGS)
+ AC_SUBST(BUILD_WITH_LIBOPING_LDFLAGS)
fi
AM_CONDITIONAL(BUILD_WITH_LIBOPING, test "x$with_liboping" = "xyes")
-AM_CONDITIONAL(BUILD_WITH_OWN_LIBOPING, test "x$with_own_liboping" = "xyes")
# }}}
# --with-oracle {{{
LDFLAGS=$SAVE_LDFLAGS
fi
-c_cv_have_broken_perl_load_module="no"
if test "x$with_libperl" = "xyes"
then
SAVE_CFLAGS=$CFLAGS
[with_libpq="yes"],
[with_libpq="no (symbol 'PQconnectdb' not found)"])
+ AC_CHECK_LIB(pq, PQserverVersion,
+ [with_libpq="yes"],
+ [with_libpq="no (symbol 'PQserverVersion' not found)"])
+
LDFLAGS="$SAVE_LDFLAGS"
fi
if test "x$with_libpq" = "xyes"
[AC_PLUGIN],
[
enable_plugin="no"
+ force="no"
AC_ARG_ENABLE([$1], AC_HELP_STRING([--enable-$1], [$3]),
[
if test "x$enableval" = "xyes"
then
enable_plugin="yes"
- else
- enable_plugin="no"
- fi
- ],
- [
- if test "x$2" = "xyes"
+ else if test "x$enableval" = "xforce"
then
enable_plugin="yes"
+ force="yes"
else
enable_plugin="no"
- fi
+ fi; fi
+ ],
+ [
+ if test "x$enable_all_plugins" = "xauto"
+ then
+ if test "x$2" = "xyes"
+ then
+ enable_plugin="yes"
+ else
+ enable_plugin="no"
+ fi
+ else
+ enable_plugin="$enable_all_plugins"
+ fi
])
if test "x$enable_plugin" = "xyes"
then
- if test "x$2" = "xyes"
+ if test "x$2" = "xyes" || test "x$force" = "xyes"
then
AC_DEFINE([HAVE_PLUGIN_]my_toupper([$1]), 1, [Define to 1 if the $1 plugin is enabled.])
+ if test "x$2" != "xyes"
+ then
+ dependency_warning="yes"
+ fi
else # User passed "yes" but dependency checking yielded "no" => Dependency problem.
dependency_error="yes"
enable_plugin="no (dependency error)"
AC_COLLECTD([daemon], [disable], [feature], [daemon mode])
AC_COLLECTD([getifaddrs],[enable], [feature], [getifaddrs under Linux])
+dependency_warning="no"
dependency_error="no"
+
plugin_ascent="no"
plugin_battery="no"
plugin_bind="no"
+plugin_conntrack="no"
plugin_cpu="no"
plugin_cpufreq="no"
plugin_df="no"
plugin_memory="no"
plugin_multimeter="no"
plugin_nfs="no"
+plugin_fscache="no"
plugin_perl="no"
plugin_processes="no"
+plugin_protocols="no"
plugin_serial="no"
plugin_swap="no"
plugin_tape="no"
plugin_tcpconns="no"
+plugin_ted="no"
plugin_thermal="no"
plugin_users="no"
+plugin_uptime="no"
plugin_vmem="no"
plugin_vserver="no"
plugin_wireless="no"
if test "x$ac_system" = "xLinux"
then
plugin_battery="yes"
+ plugin_conntrack="yes"
plugin_cpu="yes"
plugin_cpufreq="yes"
plugin_disk="yes"
plugin_load="yes"
plugin_memory="yes"
plugin_nfs="yes"
+ plugin_fscache="yes"
plugin_processes="yes"
+ plugin_protocols="yes"
plugin_serial="yes"
plugin_swap="yes"
plugin_tcpconns="yes"
plugin_thermal="yes"
+ plugin_uptime="yes"
plugin_vmem="yes"
plugin_vserver="yes"
plugin_wireless="yes"
fi
# Solaris
+if test "x$with_kstat" = "xyes"
+then
+ plugin_uptime="yes"
+fi
+
if test "x$with_devinfo$with_kstat" = "xyesyes"
then
plugin_cpu="yes"
if test "x$have_sysctl" = "xyes"
then
plugin_cpu="yes"
+ plugin_memory="yes"
plugin_swap="yes"
+ plugin_uptime="yes"
fi
if test "x$have_sysctlbyname" = "xyes"
then
if test "x$have_termios_h" = "xyes"
then
plugin_multimeter="yes"
+ plugin_ted="yes"
fi
if test "x$have_thread_info" = "xyes"
m4_divert_once([HELP_ENABLE], [
collectd plugins:])
+AC_ARG_ENABLE([all-plugins],
+ AC_HELP_STRING([--enable-all-plugins],
+ [enable all plugins (auto by def)]),
+ [
+ if test "x$enableval" = "xyes"
+ then
+ enable_all_plugins="yes"
+ else if test "x$enableval" = "xauto"
+ then
+ enable_all_plugins="auto"
+ else
+ enable_all_plugins="no"
+ fi; fi
+ ],
+ [enable_all_plugins="auto"])
+
+m4_divert_once([HELP_ENABLE], [])
+
AC_PLUGIN([apache], [$with_libcurl], [Apache httpd statistics])
AC_PLUGIN([apcups], [yes], [Statistics of UPSes by APC])
AC_PLUGIN([apple_sensors], [$with_libiokit], [Apple's hardware sensors])
AC_PLUGIN([ascent], [$plugin_ascent], [AscentEmu player statistics])
AC_PLUGIN([battery], [$plugin_battery], [Battery statistics])
AC_PLUGIN([bind], [$plugin_bind], [ISC Bind nameserver statistics])
+AC_PLUGIN([conntrack], [$plugin_conntrack], [nf_conntrack statistics])
AC_PLUGIN([cpufreq], [$plugin_cpufreq], [CPU frequency statistics])
AC_PLUGIN([cpu], [$plugin_cpu], [CPU usage statistics])
AC_PLUGIN([csv], [yes], [CSV output plugin])
AC_PLUGIN([entropy], [$plugin_entropy], [Entropy statistics])
AC_PLUGIN([exec], [yes], [Execution of external programs])
AC_PLUGIN([filecount], [yes], [Count files in directories])
+AC_PLUGIN([fscache], [$plugin_fscache], [fscache statistics])
+AC_PLUGIN([gmond], [$with_libganglia], [Ganglia plugin])
AC_PLUGIN([hddtemp], [yes], [Query hddtempd])
AC_PLUGIN([interface], [$plugin_interface], [Interface traffic statistics])
AC_PLUGIN([ipmi], [$plugin_ipmi], [IPMI sensor statistics])
AC_PLUGIN([iptables], [$with_libiptc], [IPTables rule counters])
AC_PLUGIN([ipvs], [$plugin_ipvs], [IPVS connection statistics])
AC_PLUGIN([irq], [$plugin_irq], [IRQ statistics])
+AC_PLUGIN([java], [$with_java], [Embed the Java Virtual Machine])
AC_PLUGIN([libvirt], [$plugin_libvirt], [Virtual machine statistics])
AC_PLUGIN([load], [$plugin_load], [System load])
AC_PLUGIN([logfile], [yes], [File logging plugin])
AC_PLUGIN([match_timediff], [yes], [The timediff match])
AC_PLUGIN([match_value], [yes], [The value match])
AC_PLUGIN([mbmon], [yes], [Query mbmond])
+AC_PLUGIN([memcachec], [$with_libmemcached], [memcachec statistics])
AC_PLUGIN([memcached], [yes], [memcached statistics])
AC_PLUGIN([memory], [$plugin_memory], [Memory usage])
AC_PLUGIN([multimeter], [$plugin_multimeter], [Read multimeter values])
AC_PLUGIN([postgresql], [$with_libpq], [PostgreSQL database statistics])
AC_PLUGIN([powerdns], [yes], [PowerDNS statistics])
AC_PLUGIN([processes], [$plugin_processes], [Process statistics])
+AC_PLUGIN([protocols], [$plugin_protocols], [Protocol (IP, TCP, ...) statistics])
AC_PLUGIN([rrdcached], [$librrd_rrdc_update], [RRDTool output plugin])
AC_PLUGIN([rrdtool], [$with_librrd], [RRDTool output plugin])
AC_PLUGIN([sensors], [$with_libsensors], [lm_sensors statistics])
AC_PLUGIN([snmp], [$with_libnetsnmp], [SNMP querying plugin])
AC_PLUGIN([swap], [$plugin_swap], [Swap usage statistics])
AC_PLUGIN([syslog], [$have_syslog], [Syslog logging plugin])
+AC_PLUGIN([table], [yes], [Parsing of tabular data])
AC_PLUGIN([tail], [yes], [Parsing of logfiles])
AC_PLUGIN([tape], [$plugin_tape], [Tape drive statistics])
AC_PLUGIN([target_notification], [yes], [The notification target])
AC_PLUGIN([target_set], [yes], [The set target])
AC_PLUGIN([tcpconns], [$plugin_tcpconns], [TCP connection statistics])
AC_PLUGIN([teamspeak2], [yes], [TeamSpeak2 server statistics])
+AC_PLUGIN([ted], [$plugin_ted], [Read The Energy Detective values])
AC_PLUGIN([thermal], [$plugin_thermal], [Linux ACPI thermal zone statistics])
AC_PLUGIN([unixsock], [yes], [Unixsock communication plugin])
+AC_PLUGIN([uptime], [$plugin_uptime], [Uptime statistics])
AC_PLUGIN([users], [$plugin_users], [User statistics])
AC_PLUGIN([uuid], [yes], [UUID as hostname plugin])
AC_PLUGIN([vmem], [$plugin_vmem], [Virtual memory statistics])
AC_PLUGIN([wireless], [$plugin_wireless], [Wireless statistics])
AC_PLUGIN([xmms], [$with_libxmms], [XMMS statistics])
+dnl Default configuration file
+# Load either syslog or logfile
+LOAD_PLUGIN_SYSLOG=""
+LOAD_PLUGIN_LOGFILE=""
+
+AC_MSG_CHECKING([which default log plugin to load])
+default_log_plugin="none"
+if test "x$enable_syslog" = "xyes"
+then
+ default_log_plugin="syslog"
+else
+ LOAD_PLUGIN_SYSLOG="##"
+fi
+
+if test "x$enable_logfile" = "xyes"
+then
+ if test "x$default_log_plugin" = "xnone"
+ then
+ default_log_plugin="logfile"
+ else
+ LOAD_PLUGIN_LOGFILE="#"
+ fi
+else
+ LOAD_PLUGIN_LOGFILE="##"
+fi
+AC_MSG_RESULT([$default_log_plugin])
+
+AC_SUBST(LOAD_PLUGIN_SYSLOG)
+AC_SUBST(LOAD_PLUGIN_LOGFILE)
+
+DEFAULT_LOG_LEVEL="info"
+if test "x$enable_debug" = "xyes"
+then
+ DEFAULT_LOG_LEVEL="debug"
+fi
+AC_SUBST(DEFAULT_LOG_LEVEL)
+
+# Load only one of rrdtool, network, csv in the default config.
+LOAD_PLUGIN_RRDTOOL=""
+LOAD_PLUGIN_NETWORK=""
+LOAD_PLUGIN_CSV=""
+
+AC_MSG_CHECKING([which default write plugin to load])
+default_write_plugin="none"
+if test "x$enable_rrdtool" = "xyes"
+then
+ default_write_plugin="rrdtool"
+else
+ LOAD_PLUGIN_RRDTOOL="##"
+fi
+
+if test "x$enable_network" = "xyes"
+then
+ if test "x$default_write_plugin" = "xnone"
+ then
+ default_write_plugin="network"
+ else
+ LOAD_PLUGIN_NETWORK="#"
+ fi
+else
+ LOAD_PLUGIN_NETWORK="##"
+fi
+
+if test "x$enable_csv" = "xyes"
+then
+ if test "x$default_write_plugin" = "xnone"
+ then
+ default_write_plugin="csv"
+ else
+ LOAD_PLUGIN_CSV="#"
+ fi
+else
+ LOAD_PLUGIN_CSV="##"
+fi
+AC_MSG_RESULT([$default_write_plugin])
+
+AC_SUBST(LOAD_PLUGIN_RRDTOOL)
+AC_SUBST(LOAD_PLUGIN_NETWORK)
+AC_SUBST(LOAD_PLUGIN_CSV)
+
dnl ip_vs.h
if test "x$ac_system" = "xLinux" \
&& test "x$have_net_ip_vs_h$have_ip_vs_h" = "xnono"
AC_CONFIG_FILES(src/libcollectdclient/lcc_features.h)
-AC_OUTPUT(Makefile src/Makefile src/collectd.conf src/libiptc/Makefile src/libcollectdclient/Makefile src/libcollectdclient/libcollectdclient.pc src/liboconfig/Makefile src/liboping/Makefile bindings/Makefile)
+AC_OUTPUT(Makefile src/Makefile src/collectd.conf src/libiptc/Makefile src/libcollectdclient/Makefile src/libcollectdclient/libcollectdclient.pc src/liboconfig/Makefile bindings/Makefile bindings/java/Makefile)
if test "x$with_librrd" = "xyes" \
&& test "x$librrd_threadsafe" != "xyes"
with_librrd="yes (warning: librrd is not thread-safe)"
fi
-if test "x$with_liboping" = "xyes" \
- && test "x$with_own_liboping" = "xyes"
-then
- with_liboping="yes (shipped version)"
-fi
-
if test "x$with_libiptc" = "xyes" -a "x$with_own_libiptc" = "xyes"
then
with_libiptc="yes (shipped version)"
enable_perl="no (needs libperl)"
fi
+ if test "x$enable_perl" = "xno" && test "x$c_cv_have_perl_ithreads" = "xno"
+ then
+ enable_perl="no (libperl doesn't support ithreads)"
+ fi
+
if test "x$with_perl_bindings" = "xyes" \
&& test "x$PERL_BINDINGS_OPTIONS" != "x"
then
libcurl . . . . . . . $with_libcurl
libdbi . . . . . . . $with_libdbi
libesmtp . . . . . . $with_libesmtp
+ libgcrypt . . . . . . $with_libgcrypt
libiokit . . . . . . $with_libiokit
libiptc . . . . . . . $with_libiptc
+ libjvm . . . . . . . $with_java
libkstat . . . . . . $with_kstat
libkvm . . . . . . . $with_libkvm
libmysql . . . . . . $with_libmysql
ascent . . . . . . . $enable_ascent
battery . . . . . . . $enable_battery
bind . . . . . . . . $enable_bind
+ conntrack . . . . . . $enable_conntrack
cpu . . . . . . . . . $enable_cpu
cpufreq . . . . . . . $enable_cpufreq
csv . . . . . . . . . $enable_csv
entropy . . . . . . . $enable_entropy
exec . . . . . . . . $enable_exec
filecount . . . . . . $enable_filecount
+ fscache . . . . . . . $enable_fscache
+ gmond . . . . . . . . $enable_gmond
hddtemp . . . . . . . $enable_hddtemp
interface . . . . . . $enable_interface
ipmi . . . . . . . . $enable_ipmi
iptables . . . . . . $enable_iptables
ipvs . . . . . . . . $enable_ipvs
irq . . . . . . . . . $enable_irq
+ java . . . . . . . . $enable_java
libvirt . . . . . . . $enable_libvirt
load . . . . . . . . $enable_load
logfile . . . . . . . $enable_logfile
match_timediff . . . $enable_match_timediff
match_value . . . . . $enable_match_value
mbmon . . . . . . . . $enable_mbmon
+ memcachec . . . . . . $enable_memcachec
memcached . . . . . . $enable_memcached
memory . . . . . . . $enable_memory
multimeter . . . . . $enable_multimeter
postgresql . . . . . $enable_postgresql
powerdns . . . . . . $enable_powerdns
processes . . . . . . $enable_processes
+ protocols . . . . . . $enable_protocols
rrdcached . . . . . . $enable_rrdcached
rrdtool . . . . . . . $enable_rrdtool
sensors . . . . . . . $enable_sensors
snmp . . . . . . . . $enable_snmp
swap . . . . . . . . $enable_swap
syslog . . . . . . . $enable_syslog
+ table . . . . . . . . $enable_table
tail . . . . . . . . $enable_tail
tape . . . . . . . . $enable_tape
target_notification . $enable_target_notification
target_set . . . . . $enable_target_set
tcpconns . . . . . . $enable_tcpconns
teamspeak2 . . . . . $enable_teamspeak2
+ ted . . . . . . . . . $enable_ted
thermal . . . . . . . $enable_thermal
unixsock . . . . . . $enable_unixsock
+ uptime . . . . . . . $enable_uptime
users . . . . . . . . $enable_users
uuid . . . . . . . . $enable_uuid
vmem . . . . . . . . $enable_vmem
EOF
if test "x$dependency_error" = "xyes"; then
- AC_MSG_ERROR("Some plugins are missing dependencies - see above summary for details")
+ AC_MSG_ERROR("Some plugins are missing dependencies - see the summary above for details")
+fi
+
+if test "x$dependency_warning" = "xyes"; then
+ AC_MSG_WARN("Some plugins seem to have missing dependencies but have been enabled forcibly - see the summary above for details")
fi
# vim: set fdm=marker :
#include "configfile.h"
#include "utils_avltree.h"
#include "utils_llist.h"
+#include "utils_heap.h"
#include "utils_cache.h"
#include "utils_threshold.h"
#include "filter_chain.h"
/*
* Private structures
*/
+struct callback_func_s
+{
+ void *cf_callback;
+ user_data_t cf_udata;
+};
+typedef struct callback_func_s callback_func_t;
+
+#define RF_SIMPLE 0
+#define RF_COMPLEX 1
struct read_func_s
{
- int wait_time;
- int wait_left;
- int (*callback) (void);
- enum { DONE = 0, TODO = 1, ACTIVE = 2 } needs_read;
+ /* `read_func_t' "inherits" from `callback_func_t'.
+ * The `rf_super' member MUST be the first one in this structure! */
+#define rf_callback rf_super.cf_callback
+#define rf_udata rf_super.cf_udata
+ callback_func_t rf_super;
+ char rf_name[DATA_MAX_NAME_LEN];
+ int rf_type;
+ struct timespec rf_interval;
+ struct timespec rf_effective_interval;
+ struct timespec rf_next_read;
};
typedef struct read_func_s read_func_t;
* Private variables
*/
static llist_t *list_init;
-static llist_t *list_read;
static llist_t *list_write;
static llist_t *list_flush;
static llist_t *list_shutdown;
static char *plugindir = NULL;
+static c_heap_t *read_heap = NULL;
static int read_loop = 1;
static pthread_mutex_t read_lock = PTHREAD_MUTEX_INITIALIZER;
static pthread_cond_t read_cond = PTHREAD_COND_INITIALIZER;
return (plugindir);
}
-static int register_callback (llist_t **list, const char *name, void *callback)
+static void destroy_callback (callback_func_t *cf) /* {{{ */
+{
+ if (cf == NULL)
+ return;
+
+ if ((cf->cf_udata.data != NULL) && (cf->cf_udata.free_func != NULL))
+ {
+ cf->cf_udata.free_func (cf->cf_udata.data);
+ cf->cf_udata.data = NULL;
+ cf->cf_udata.free_func = NULL;
+ }
+ sfree (cf);
+} /* }}} void destroy_callback */
+
+static void destroy_all_callbacks (llist_t **list) /* {{{ */
+{
+ llentry_t *le;
+
+ if (*list == NULL)
+ return;
+
+ le = llist_head (*list);
+ while (le != NULL)
+ {
+ llentry_t *le_next;
+
+ le_next = le->next;
+
+ sfree (le->key);
+ destroy_callback (le->value);
+ le->value = NULL;
+
+ le = le_next;
+ }
+
+ llist_destroy (*list);
+ *list = NULL;
+} /* }}} void destroy_all_callbacks */
+
+static void destroy_read_heap (void) /* {{{ */
+{
+ if (read_heap == NULL)
+ return;
+
+ while (42)
+ {
+ callback_func_t *cf;
+
+ cf = c_head_get_root (read_heap);
+ if (cf == NULL)
+ break;
+
+ destroy_callback (cf);
+ }
+
+ c_heap_destroy (read_heap);
+ read_heap = NULL;
+} /* }}} void destroy_read_heap */
+
+static int register_callback (llist_t **list, /* {{{ */
+ const char *name, callback_func_t *cf)
{
llentry_t *le;
char *key;
- if ((*list == NULL)
- && ((*list = llist_create ()) == NULL))
+ if (*list == NULL)
+ {
+ *list = llist_create ();
+ if (*list == NULL)
+ {
+ ERROR ("plugin: create_register_callback: "
+ "llist_create failed.");
+ destroy_callback (cf);
+ return (-1);
+ }
+ }
+
+ key = strdup (name);
+ if (key == NULL)
+ {
+ ERROR ("plugin: create_register_callback: strdup failed.");
+ destroy_callback (cf);
return (-1);
+ }
le = llist_search (*list, name);
if (le == NULL)
{
- key = strdup (name);
- if (key == NULL)
- return (-1);
-
- le = llentry_create (key, callback);
+ le = llentry_create (key, cf);
if (le == NULL)
{
+ ERROR ("plugin: create_register_callback: "
+ "llentry_create failed.");
free (key);
+ destroy_callback (cf);
return (-1);
}
}
else
{
- le->value = callback;
+ callback_func_t *old_cf;
+
+ old_cf = le->value;
+ le->value = cf;
+
+ destroy_callback (old_cf);
+ sfree (key);
}
return (0);
-} /* int register_callback */
+} /* }}} int register_callback */
-static int plugin_unregister (llist_t *list, const char *name)
+static int create_register_callback (llist_t **list, /* {{{ */
+ const char *name, void *callback, user_data_t *ud)
+{
+ callback_func_t *cf;
+
+ cf = (callback_func_t *) malloc (sizeof (*cf));
+ if (cf == NULL)
+ {
+ ERROR ("plugin: create_register_callback: malloc failed.");
+ return (-1);
+ }
+ memset (cf, 0, sizeof (*cf));
+
+ cf->cf_callback = callback;
+ if (ud == NULL)
+ {
+ cf->cf_udata.data = NULL;
+ cf->cf_udata.free_func = NULL;
+ }
+ else
+ {
+ cf->cf_udata = *ud;
+ }
+
+ return (register_callback (list, name, cf));
+} /* }}} int create_register_callback */
+
+static int plugin_unregister (llist_t *list, const char *name) /* {{{ */
{
llentry_t *e;
- e = llist_search (list, name);
+ if (list == NULL)
+ return (-1);
+ e = llist_search (list, name);
if (e == NULL)
return (-1);
llist_remove (list, e);
- free (e->key);
+
+ sfree (e->key);
+ destroy_callback (e->value);
+
llentry_destroy (e);
return (0);
-} /* int plugin_unregister */
+} /* }}} int plugin_unregister */
/*
* (Try to) load the shared object `file'. Won't complain if it isn't a shared
static void *plugin_read_thread (void __attribute__((unused)) *args)
{
- llentry_t *le;
- read_func_t *rf;
- int status;
- int done;
-
- pthread_mutex_lock (&read_lock);
-
while (read_loop != 0)
{
- le = llist_head (list_read);
- done = 0;
+ read_func_t *rf;
+ struct timeval now;
+ int status;
- while ((read_loop != 0) && (le != NULL))
+ /* Get the read function that needs to be read next. */
+ rf = c_head_get_root (read_heap);
+ if (rf == NULL)
{
- rf = (read_func_t *) le->value;
+ struct timespec abstime;
- if (rf->needs_read != TODO)
- {
- le = le->next;
- continue;
- }
+ gettimeofday (&now, /* timezone = */ NULL);
- /* We will do this read function */
- rf->needs_read = ACTIVE;
+ abstime.tv_sec = now.tv_sec + interval_g;
+ abstime.tv_nsec = 1000 * now.tv_usec;
- DEBUG ("[thread #%5lu] plugin: plugin_read_thread: Handling %s",
- (unsigned long int) pthread_self (), le->key);
+ pthread_mutex_lock (&read_lock);
+ pthread_cond_timedwait (&read_cond, &read_lock,
+ &abstime);
pthread_mutex_unlock (&read_lock);
+ continue;
+ }
- status = rf->callback ();
- done++;
+ if ((rf->rf_interval.tv_sec == 0) && (rf->rf_interval.tv_nsec == 0))
+ {
+ gettimeofday (&now, /* timezone = */ NULL);
- if (status != 0)
- {
- if (rf->wait_time < interval_g)
- rf->wait_time = interval_g;
- rf->wait_left = rf->wait_time;
- rf->wait_time = rf->wait_time * 2;
- if (rf->wait_time > 86400)
- rf->wait_time = 86400;
-
- NOTICE ("read-function of plugin `%s' "
- "failed. Will suspend it for %i "
- "seconds.", le->key, rf->wait_left);
- }
- else
+ rf->rf_interval.tv_sec = interval_g;
+ rf->rf_interval.tv_nsec = 0;
+
+ rf->rf_effective_interval = rf->rf_interval;
+
+ rf->rf_next_read.tv_sec = now.tv_sec;
+ rf->rf_next_read.tv_nsec = 1000 * now.tv_usec;
+ }
+
+ /* sleep until this entry is due,
+ * using pthread_cond_timedwait */
+ pthread_mutex_lock (&read_lock);
+ pthread_cond_timedwait (&read_cond, &read_lock,
+ &rf->rf_next_read);
+ pthread_mutex_unlock (&read_lock);
+
+ /* Check if we're supposed to stop.. This may have interrupted
+ * the sleep, too. */
+ if (read_loop == 0)
+ {
+ /* Insert `rf' again, so it can be free'd correctly */
+ c_heap_insert (read_heap, rf);
+ break;
+ }
+
+ DEBUG ("plugin_read_thread: Handling `%s'.", rf->rf_name);
+
+ if (rf->rf_type == RF_SIMPLE)
+ {
+ int (*callback) (void);
+
+ callback = rf->rf_callback;
+ status = (*callback) ();
+ }
+ else
+ {
+ plugin_read_cb callback;
+
+ callback = rf->rf_callback;
+ status = (*callback) (&rf->rf_udata);
+ }
+
+ /* If the function signals failure, we will increase the
+ * intervals in which it will be called. */
+ if (status != 0)
+ {
+ rf->rf_effective_interval.tv_sec *= 2;
+ rf->rf_effective_interval.tv_nsec *= 2;
+ NORMALIZE_TIMESPEC (rf->rf_effective_interval);
+
+ if (rf->rf_effective_interval.tv_sec >= 86400)
{
- rf->wait_left = 0;
- rf->wait_time = interval_g;
+ rf->rf_effective_interval.tv_sec = 86400;
+ rf->rf_effective_interval.tv_nsec = 0;
}
- pthread_mutex_lock (&read_lock);
-
- rf->needs_read = DONE;
- le = le->next;
- } /* while (le != NULL) */
+ NOTICE ("read-function of plugin `%s' failed. "
+ "Will suspend it for %i seconds.",
+ rf->rf_name,
+ (int) rf->rf_effective_interval.tv_sec);
+ }
+ else
+ {
+ /* Success: Restore the interval, if it was changed. */
+ rf->rf_effective_interval = rf->rf_interval;
+ }
- if ((read_loop != 0) && (done == 0))
+ /* update the ``next read due'' field */
+ gettimeofday (&now, /* timezone = */ NULL);
+
+ DEBUG ("plugin_read_thread: Effective interval of the "
+ "%s plugin is %i.%09i.",
+ rf->rf_name,
+ (int) rf->rf_effective_interval.tv_sec,
+ (int) rf->rf_effective_interval.tv_nsec);
+
+ /* Calculate the next (absolute) time at which this function
+ * should be called. */
+ rf->rf_next_read.tv_sec = rf->rf_next_read.tv_sec
+ + rf->rf_effective_interval.tv_sec;
+ rf->rf_next_read.tv_nsec = rf->rf_next_read.tv_nsec
+ + rf->rf_effective_interval.tv_nsec;
+ NORMALIZE_TIMESPEC (rf->rf_next_read);
+
+ /* Check, if `rf_next_read' is in the past. */
+ if ((rf->rf_next_read.tv_sec < now.tv_sec)
+ || ((rf->rf_next_read.tv_sec == now.tv_sec)
+ && (rf->rf_next_read.tv_nsec < (1000 * now.tv_usec))))
{
- DEBUG ("[thread #%5lu] plugin: plugin_read_thread: Waiting on read_cond.",
- (unsigned long int) pthread_self ());
- pthread_cond_wait (&read_cond, &read_lock);
+ /* `rf_next_read' is in the past. Insert `now'
+ * so this value doesn't trail off into the
+ * past too much. */
+ rf->rf_next_read.tv_sec = now.tv_sec;
+ rf->rf_next_read.tv_nsec = 1000 * now.tv_usec;
}
- } /* while (read_loop) */
- pthread_mutex_unlock (&read_lock);
+ DEBUG ("plugin_read_thread: Next read of the %s plugin at %i.%09i.",
+ rf->rf_name,
+ (int) rf->rf_next_read.tv_sec,
+ (int) rf->rf_next_read.tv_nsec);
+
+ /* Re-insert this read function into the heap again. */
+ c_heap_insert (read_heap, rf);
+ } /* while (read_loop) */
pthread_exit (NULL);
return ((void *) 0);
} /* void *plugin_read_thread */
-static void start_threads (int num)
+static void start_read_threads (int num)
{
int i;
read_threads = (pthread_t *) calloc (num, sizeof (pthread_t));
if (read_threads == NULL)
{
- ERROR ("plugin: start_threads: calloc failed.");
+ ERROR ("plugin: start_read_threads: calloc failed.");
return;
}
}
else
{
- ERROR ("plugin: start_threads: pthread_create failed.");
+ ERROR ("plugin: start_read_threads: pthread_create failed.");
return;
}
} /* for (i) */
-} /* void start_threads */
+} /* void start_read_threads */
-static void stop_threads (void)
+static void stop_read_threads (void)
{
int i;
if (read_threads == NULL)
return;
+ INFO ("collectd: Stopping %i read threads.", read_threads_num);
+
pthread_mutex_lock (&read_lock);
read_loop = 0;
- DEBUG ("plugin: stop_threads: Signalling `read_cond'");
+ DEBUG ("plugin: stop_read_threads: Signalling `read_cond'");
pthread_cond_broadcast (&read_cond);
pthread_mutex_unlock (&read_lock);
{
if (pthread_join (read_threads[i], NULL) != 0)
{
- ERROR ("plugin: stop_threads: pthread_join failed.");
+ ERROR ("plugin: stop_read_threads: pthread_join failed.");
}
read_threads[i] = (pthread_t) 0;
}
sfree (read_threads);
read_threads_num = 0;
-} /* void stop_threads */
+} /* void stop_read_threads */
/*
* Public functions
int plugin_register_init (const char *name,
int (*callback) (void))
{
- return (register_callback (&list_init, name, (void *) callback));
+ return (create_register_callback (&list_init, name, (void *) callback,
+ /* user_data = */ NULL));
} /* plugin_register_init */
+static int plugin_compare_read_func (const void *arg0, const void *arg1)
+{
+ const read_func_t *rf0;
+ const read_func_t *rf1;
+
+ rf0 = arg0;
+ rf1 = arg1;
+
+ if (rf0->rf_next_read.tv_sec < rf1->rf_next_read.tv_sec)
+ return (-1);
+ else if (rf0->rf_next_read.tv_sec > rf1->rf_next_read.tv_sec)
+ return (1);
+ else if (rf0->rf_next_read.tv_nsec < rf1->rf_next_read.tv_nsec)
+ return (-1);
+ else if (rf0->rf_next_read.tv_nsec > rf1->rf_next_read.tv_nsec)
+ return (1);
+ else
+ return (0);
+} /* int plugin_compare_read_func */
+
int plugin_register_read (const char *name,
int (*callback) (void))
{
read_func_t *rf;
+ if (read_heap == NULL)
+ {
+ read_heap = c_heap_create (plugin_compare_read_func);
+ if (read_heap == NULL)
+ {
+ ERROR ("plugin_register_read: "
+ "c_heap_create failed.");
+ return (-1);
+ }
+ }
+
rf = (read_func_t *) malloc (sizeof (read_func_t));
if (rf == NULL)
{
return (-1);
}
- memset (rf, '\0', sizeof (read_func_t));
- rf->wait_time = interval_g;
- rf->wait_left = 0;
- rf->callback = callback;
- rf->needs_read = DONE;
-
- return (register_callback (&list_read, name, (void *) rf));
+ memset (rf, 0, sizeof (read_func_t));
+ rf->rf_callback = (void *) callback;
+ rf->rf_udata.data = NULL;
+ rf->rf_udata.free_func = NULL;
+ sstrncpy (rf->rf_name, name, sizeof (rf->rf_name));
+ rf->rf_type = RF_SIMPLE;
+ rf->rf_interval.tv_sec = 0;
+ rf->rf_interval.tv_nsec = 0;
+ rf->rf_effective_interval = rf->rf_interval;
+
+ return (c_heap_insert (read_heap, rf));
} /* int plugin_register_read */
+int plugin_register_complex_read (const char *name,
+ plugin_read_cb callback,
+ const struct timespec *interval,
+ user_data_t *user_data)
+{
+ read_func_t *rf;
+
+ if (read_heap == NULL)
+ {
+ read_heap = c_heap_create (plugin_compare_read_func);
+ if (read_heap == NULL)
+ {
+ ERROR ("plugin_register_read: c_heap_create failed.");
+ return (-1);
+ }
+ }
+
+ rf = (read_func_t *) malloc (sizeof (read_func_t));
+ if (rf == NULL)
+ {
+ ERROR ("plugin_register_complex_read: malloc failed.");
+ return (-1);
+ }
+
+ memset (rf, 0, sizeof (read_func_t));
+ rf->rf_callback = (void *) callback;
+ sstrncpy (rf->rf_name, name, sizeof (rf->rf_name));
+ rf->rf_type = RF_COMPLEX;
+ if (interval != NULL)
+ {
+ rf->rf_interval = *interval;
+ }
+ rf->rf_effective_interval = rf->rf_interval;
+
+ /* Set user data */
+ if (user_data == NULL)
+ {
+ rf->rf_udata.data = NULL;
+ rf->rf_udata.free_func = NULL;
+ }
+ else
+ {
+ rf->rf_udata = *user_data;
+ }
+
+ return (c_heap_insert (read_heap, rf));
+} /* int plugin_register_complex_read */
+
int plugin_register_write (const char *name,
- int (*callback) (const data_set_t *ds, const value_list_t *vl))
+ plugin_write_cb callback, user_data_t *ud)
{
- return (register_callback (&list_write, name, (void *) callback));
+ return (create_register_callback (&list_write, name,
+ (void *) callback, ud));
} /* int plugin_register_write */
int plugin_register_flush (const char *name,
- int (*callback) (const int timeout, const char *identifier))
+ plugin_flush_cb callback, user_data_t *ud)
{
- return (register_callback (&list_flush, name, (void *) callback));
+ return (create_register_callback (&list_flush, name,
+ (void *) callback, ud));
} /* int plugin_register_flush */
int plugin_register_shutdown (char *name,
int (*callback) (void))
{
- return (register_callback (&list_shutdown, name, (void *) callback));
+ return (create_register_callback (&list_shutdown, name,
+ (void *) callback, /* user_data = */ NULL));
} /* int plugin_register_shutdown */
int plugin_register_data_set (const data_set_t *ds)
return (c_avl_insert (data_sets, (void *) ds_copy->type, (void *) ds_copy));
} /* int plugin_register_data_set */
-int plugin_register_log (char *name,
- void (*callback) (int priority, const char *msg))
+int plugin_register_log (const char *name,
+ plugin_log_cb callback, user_data_t *ud)
{
- return (register_callback (&list_log, name, (void *) callback));
+ return (create_register_callback (&list_log, name,
+ (void *) callback, ud));
} /* int plugin_register_log */
int plugin_register_notification (const char *name,
- int (*callback) (const notification_t *notif))
+ plugin_notification_cb callback, user_data_t *ud)
{
- return (register_callback (&list_notification, name, (void *) callback));
+ return (create_register_callback (&list_notification, name,
+ (void *) callback, ud));
} /* int plugin_register_log */
int plugin_unregister_config (const char *name)
int plugin_unregister_read (const char *name)
{
- llentry_t *e;
-
- e = llist_search (list_read, name);
-
- if (e == NULL)
- return (-1);
-
- llist_remove (list_read, e);
- free (e->value);
- free (e->key);
- llentry_destroy (e);
-
- return (0);
+ /* TODO: Implement removal of a specific key from the heap. */
+ assert (0);
+ return (-1);
}
int plugin_unregister_write (const char *name)
void plugin_init_all (void)
{
const char *chain_name;
- int (*callback) (void);
llentry_t *le;
int status;
post_cache_chain = fc_chain_get_by_name (chain_name);
- if ((list_init == NULL) && (list_read == NULL))
+ if ((list_init == NULL) && (read_heap == NULL))
return;
/* Calling all init callbacks before checking if read callbacks
le = llist_head (list_init);
while (le != NULL)
{
- callback = (int (*) (void)) le->value;
+ callback_func_t *cf;
+ plugin_init_cb callback;
+
+ cf = le->value;
+ callback = cf->cf_callback;
status = (*callback) ();
if (status != 0)
}
/* Start read-threads */
- if (list_read != NULL)
+ if (read_heap != NULL)
{
const char *rt;
int num;
rt = global_option_get ("ReadThreads");
num = atoi (rt);
if (num != -1)
- start_threads ((num > 0) ? num : 5);
+ start_read_threads ((num > 0) ? num : 5);
}
} /* void plugin_init_all */
+/* TODO: Rename this function. */
void plugin_read_all (void)
{
- llentry_t *le;
- read_func_t *rf;
-
uc_check_timeout ();
- if (list_read == NULL)
- return;
-
- pthread_mutex_lock (&read_lock);
-
- le = llist_head (list_read);
- while (le != NULL)
- {
- rf = (read_func_t *) le->value;
-
- if (rf->needs_read != DONE)
- {
- le = le->next;
- continue;
- }
-
- if (rf->wait_left > 0)
- rf->wait_left -= interval_g;
-
- if (rf->wait_left <= 0)
- {
- rf->needs_read = TODO;
- }
-
- le = le->next;
- }
-
- DEBUG ("plugin: plugin_read_all: Signalling `read_cond'");
- pthread_cond_broadcast (&read_cond);
- pthread_mutex_unlock (&read_lock);
+ return;
} /* void plugin_read_all */
/* Read function called when the `-T' command line argument is given. */
int plugin_read_all_once (void)
{
- llentry_t *le;
- read_func_t *rf;
int status;
int return_status = 0;
- if (list_read == NULL)
+ if (read_heap == NULL)
{
NOTICE ("No read-functions are registered.");
return (0);
}
- for (le = llist_head (list_read);
- le != NULL;
- le = le->next)
+ while (42)
{
- rf = (read_func_t *) le->value;
- status = rf->callback ();
+ read_func_t *rf;
+
+ rf = c_head_get_root (read_heap);
+ if (rf == NULL)
+ break;
+
+ if (rf->rf_type == RF_SIMPLE)
+ {
+ int (*callback) (void);
+
+ callback = rf->rf_callback;
+ status = (*callback) ();
+ }
+ else
+ {
+ plugin_read_cb callback;
+
+ callback = rf->rf_callback;
+ status = (*callback) (&rf->rf_udata);
+ }
+
if (status != 0)
{
NOTICE ("read-function of plugin `%s' failed.",
- le->key);
+ rf->rf_name);
return_status = -1;
}
+
+ destroy_callback ((void *) rf);
}
return (return_status);
int plugin_write (const char *plugin, /* {{{ */
const data_set_t *ds, const value_list_t *vl)
{
- int (*callback) (const data_set_t *ds, const value_list_t *vl);
llentry_t *le;
int status;
le = llist_head (list_write);
while (le != NULL)
{
- callback = le->value;
- status = (*callback) (ds, vl);
+ callback_func_t *cf = le->value;
+ plugin_write_cb callback;
+
+ DEBUG ("plugin: plugin_write: Writing values via %s.", le->key);
+ callback = cf->cf_callback;
+ status = (*callback) (ds, vl, &cf->cf_udata);
if (status != 0)
failure++;
else
}
else /* plugin != NULL */
{
+ callback_func_t *cf;
+ plugin_write_cb callback;
+
le = llist_head (list_write);
while (le != NULL)
{
if (le == NULL)
return (ENOENT);
- callback = le->value;
- status = (*callback) (ds, vl);
+ cf = le->value;
+
+ DEBUG ("plugin: plugin_write: Writing values via %s.", le->key);
+ callback = cf->cf_callback;
+ status = (*callback) (ds, vl, &cf->cf_udata);
}
return (status);
int plugin_flush (const char *plugin, int timeout, const char *identifier)
{
- int (*callback) (int timeout, const char *identifier);
llentry_t *le;
if (list_flush == NULL)
le = llist_head (list_flush);
while (le != NULL)
{
+ callback_func_t *cf;
+ plugin_flush_cb callback;
+
if ((plugin != NULL)
&& (strcmp (plugin, le->key) != 0))
{
continue;
}
- callback = (int (*) (int, const char *)) le->value;
- (*callback) (timeout, identifier);
+ cf = le->value;
+ callback = cf->cf_callback;
+
+ (*callback) (timeout, identifier, &cf->cf_udata);
le = le->next;
}
void plugin_shutdown_all (void)
{
- int (*callback) (void);
llentry_t *le;
- stop_threads ();
+ stop_read_threads ();
- if (list_shutdown == NULL)
- return;
+ destroy_all_callbacks (&list_init);
+ destroy_read_heap ();
+
+ plugin_flush (/* plugin = */ NULL, /* timeout = */ -1,
+ /* identifier = */ NULL);
+
+ le = NULL;
+ if (list_shutdown != NULL)
+ le = llist_head (list_shutdown);
- le = llist_head (list_shutdown);
while (le != NULL)
{
- callback = (int (*) (void)) le->value;
+ callback_func_t *cf;
+ plugin_shutdown_cb callback;
+
+ cf = le->value;
+ callback = cf->cf_callback;
/* Advance the pointer before calling the callback allows
* shutdown functions to unregister themselves. If done the
(*callback) ();
}
+
+ destroy_all_callbacks (&list_write);
+ destroy_all_callbacks (&list_flush);
+ destroy_all_callbacks (&list_notification);
+ destroy_all_callbacks (&list_shutdown);
+ destroy_all_callbacks (&list_log);
} /* void plugin_shutdown_all */
int plugin_dispatch_values (value_list_t *vl)
if (vl->time == 0)
vl->time = time (NULL);
+ if (vl->interval <= 0)
+ vl->interval = interval_g;
+
DEBUG ("plugin_dispatch_values: time = %u; interval = %i; "
"host = %s; "
"plugin = %s; plugin_instance = %s; "
/* Update the value cache */
uc_update (ds, vl);
+ /* Initiate threshold checking */
+ ut_check_threshold (ds, vl);
+
if (post_cache_chain != NULL)
{
status = fc_process_chain (ds, vl, post_cache_chain);
int plugin_dispatch_notification (const notification_t *notif)
{
- int (*callback) (const notification_t *);
llentry_t *le;
/* Possible TODO: Add flap detection here */
le = llist_head (list_notification);
while (le != NULL)
{
- callback = (int (*) (const notification_t *)) le->value;
- (*callback) (notif);
+ callback_func_t *cf;
+ plugin_notification_cb callback;
+ int status;
+
+ cf = le->value;
+ callback = cf->cf_callback;
+ status = (*callback) (notif, &cf->cf_udata);
+ if (status != 0)
+ {
+ WARNING ("plugin_dispatch_notification: Notification "
+ "callback %s returned %i.",
+ le->key, status);
+ }
le = le->next;
}
{
char msg[1024];
va_list ap;
-
- void (*callback) (int, const char *);
llentry_t *le;
if (list_log == NULL)
le = llist_head (list_log);
while (le != NULL)
{
- callback = (void (*) (int, const char *)) le->value;
- (*callback) (level, msg);
+ callback_func_t *cf;
+ plugin_log_cb callback;
+
+ cf = le->value;
+ callback = cf->cf_callback;
+
+ (*callback) (level, msg, &cf->cf_udata);
le = le->next;
}
return (0);
} /* int plugin_notification_meta_free */
+
+/* vim: set sw=8 ts=8 noet fdm=marker : */