AC_HEADER_DIRENT
AC_HEADER_STDBOOL
-AC_CHECK_HEADERS(stdio.h errno.h math.h stdarg.h syslog.h fcntl.h signal.h assert.h sys/types.h sys/socket.h sys/select.h poll.h netdb.h arpa/inet.h sys/resource.h sys/param.h kstat.h regex.h sys/ioctl.h endian.h sys/isa_defs.h fnmatch.h libgen.h)
+AC_CHECK_HEADERS([ \
+ arpa/inet.h \
+ assert.h \
+ ctype.h \
+ endian.h \
+ errno.h \
+ fcntl.h \
+ fnmatch.h \
+ fs_info.h \
+ fshelp.h \
+ grp.h \
+ kstat.h \
+ kvm.h \
+ libgen.h \
+ limits.h \
+ locale.h \
+ math.h \
+ mntent.h \
+ mnttab.h \
+ netdb.h \
+ paths.h \
+ poll.h \
+ pthread_np.h \
+ pwd.h \
+ regex.h \
+ signal.h \
+ stdarg.h \
+ stdio.h \
+ sys/fs_types.h \
+ sys/fstyp.h \
+ sys/ioctl.h \
+ sys/isa_defs.h \
+ sys/mntent.h \
+ sys/mnttab.h \
+ sys/param.h \
+ sys/resource.h \
+ sys/select.h \
+ sys/socket.h \
+ sys/statfs.h \
+ sys/statvfs.h \
+ sys/types.h \
+ sys/un.h \
+ sys/vfs.h \
+ sys/vfstab.h \
+ sys/vmmeter.h \
+ syslog.h \
+ wordexp.h \
+])
# For entropy plugin on newer NetBSD
AC_CHECK_HEADERS(sys/rndio.h, [], [],
#endif
])
-AC_CHECK_HEADERS([ \
- ctype.h \
- fs_info.h \
- fshelp.h \
- grp.h \
- kvm.h \
- limits.h \
- locale.h \
- mntent.h \
- mnttab.h \
- paths.h \
- pwd.h \
- sys/fs_types.h \
- sys/fstyp.h \
- sys/mntent.h \
- sys/mnttab.h \
- sys/statfs.h \
- sys/statvfs.h \
- sys/un.h \
- sys/vfs.h \
- sys/vfstab.h \
- sys/vmmeter.h \
- wordexp.h \
-])
-
# --enable-xfs {{{
AC_ARG_ENABLE([xfs],
[AS_HELP_STRING([--enable-xfs], [xfs support in df plugin @<:@default=yes@:>@])],
#endif
])
+# check for pthread_setname_np
+SAVE_LDFLAGS="$LDFLAGS"
+LDFLAGS="$LDFLAGS -lpthread"
+
+AC_MSG_CHECKING([for pthread_setname_np])
+ have_pthread_setname_np="no"
+ AC_LINK_IFELSE([AC_LANG_PROGRAM(
+[[
+#define _GNU_SOURCE
+#include <pthread.h>
+]],
+[[
+ pthread_setname_np((pthread_t) {0}, "conftest");
+]]
+ )], [
+ have_pthread_setname_np="yes"
+ AC_DEFINE(HAVE_PTHREAD_SETNAME_NP, 1, [pthread_setname_np() is available.])
+ ])
+
+AC_MSG_RESULT([$have_pthread_setname_np])
+
+# check for pthread_set_name_np(3) (FreeBSD)
+AC_MSG_CHECKING([for pthread_set_name_np])
+ have_pthread_set_name_np="no"
+ AC_LINK_IFELSE([AC_LANG_PROGRAM(
+[[
+#include <pthread_np.h>
+]],
+[[
+ pthread_set_name_np((pthread_t) {0}, "conftest");
+]]
+ )], [
+ have_pthread_set_name_np="yes"
+ AC_DEFINE(HAVE_PTHREAD_SET_NAME_NP, 1, [pthread_set_name_np() is available.])
+ ])
+AC_MSG_RESULT([$have_pthread_set_name_np])
+
+LDFLAGS="$SAVE_LDFLAGS"
+
#
# Checks for libraries begin here
#
fi
# }}}
+# --with-libdpdk {{{
+LIBDPDK_CPPFLAGS="-I/usr/include/dpdk"
+LIBDPDK_LDFLAGS=""
+AC_ARG_VAR([LIBDPDK_CPPFLAGS], [Preprocessor flags for libdpdk])
+AC_ARG_VAR([LIBDPDK_LDFLAGS], [Linker flags for libdpdk])
+
+AC_ARG_WITH([libdpdk], [AS_HELP_STRING([--without-libdpdk], [Disable libdpdk.])])
+
+if test "x$with_libdpdk" != "xno"
+then
+ SAVE_CPPFLAGS="$CPPFLAGS"
+ CPPFLAGS="$LIBDPDK_CPPFLAGS $CPPFLAGS"
+ AC_CHECK_HEADERS([rte_config.h],
+ [with_libdpdk="yes"],
+ [with_libdpdk="no (rte_config.h not found)"]
+ )
+ CPPFLAGS="$SAVE_CPPFLAGS"
+fi
+
+if test "x$with_libdpdk" = "xyes"
+then
+ SAVE_LDFLAGS="$LDFLAGS"
+ LDFLAGS="$LIBDPDK_LDFLAGS $LDFLAGS"
+ AC_CHECK_LIB([dpdk], [rte_eal_init],
+ [with_libdpkd="yes"],
+ [with_libdpdk="no (symbol 'rte_eal_init' not found)"]
+ )
+ LDFLAGS="$SAVE_LDFLAGS"
+fi
+
+# }}}
+
# --with-java {{{
with_java_home="$JAVA_HOME"
if test "x$with_java_home" = "x"
if test "x$with_liblua" = "xyes"
then
- SAVE_CFLAGS="$CFLAGS"
- CFLAGS="$CFLAGS $LUA_CFLAGS"
+ SAVE_CPPFLAGS="$CPPFLAGS"
+ CPPFLAGS="$CPPFLAGS $LUA_CFLAGS"
AC_CHECK_HEADERS([lua.h lauxlib.h lualib.h],
[with_liblua="yes"],
[with_liblua="no (header not found)"]
)
- CFLAGS="$SAVE_CFLAGS"
+ CPPFLAGS="$SAVE_CPPFLAGS"
fi
if test "x$with_liblua" = "xyes"
AM_CONDITIONAL(BUILD_WITH_LIBMEMCACHED, test "x$with_libmemcached" = "xyes")
# }}}
+# --with-libmicrohttpd {{{
+with_libmicrohttpd_cppflags=""
+with_libmicrohttpd_ldflags=""
+AC_ARG_WITH([libmicrohttpd], [AS_HELP_STRING([--with-libmicrohttpd@<:@=PREFIX@:>@], [Path to libmicrohttpd.])],
+ [
+ if test "x$withval" != "xno" && test "x$withval" != "xyes"
+ then
+ with_libmicrohttpd_cppflags="-I$withval/include"
+ with_libmicrohttpd_ldflags="-L$withval/lib"
+ with_libmicrohttpd="yes"
+ fi
+ if test "x$withval" = "xno"
+ then
+ with_libmicrohttpd="no (disabled on command line)"
+ fi
+ ],
+ [withval="yes"]
+)
+if test "x$withval" = "xyes"
+then
+PKG_CHECK_MODULES([MICROHTTPD], [libmicrohttpd],
+ [with_libmicrohttpd="yes"],
+ [with_libmicrohttpd="no (pkg-config could not find libmicrohttpd)"]
+)
+fi
+
+if test "x$MICROHTTPD_LIBS" = "x"
+then
+ MICROHTTPD_LIBS="-lmicrohttpd"
+fi
+
+SAVE_CPPFLAGS="$CPPFLAGS"
+SAVE_LDFLAGS="$LDFLAGS"
+SAVE_LIBS="$LIBS"
+CPPFLAGS="$with_libmicrohttpd_cppflags $MICROHTTPD_CFLAGS"
+LDFLAGS="$with_libmicrohttpd_ldflags $LDFLAGS"
+LIBS="$LIBS $MICROHTTPD_LIBS"
+
+if test "x$with_libmicrohttpd" = "xyes"
+then
+ AC_CHECK_HEADERS([microhttpd.h],
+ [with_libmicrohttpd="yes"],
+ [with_libmicrohttpd="no (<microhttpd.h> not found)"])
+fi
+
+if test "x$with_libmicrohttpd" = "xyes"
+then
+ AC_CHECK_LIB([microhttpd], [MHD_start_daemon],
+ [with_libmicrohttpd="yes"],
+ [with_libmicrohttpd="no (libmicrohttpd not found)"])
+fi
+
+CPPFLAGS="$SAVE_CPPFLAGS"
+LDFLAGS="$SAVE_LDFLAGS"
+LIBS="$SAVE_LIBS"
+
+BUILD_WITH_LIBMICROHTTPD_CPPFLAGS="$with_libmicrohttpd_cppflags $MICROHTTPD_CFLAGS"
+BUILD_WITH_LIBMICROHTTPD_LDFLAGS="$with_libmicrohttpd_ldflags"
+BUILD_WITH_LIBMICROHTTPD_LIBS="$MICROHTTPD_LIBS"
+AC_SUBST([BUILD_WITH_LIBMICROHTTPD_CPPFLAGS])
+AC_SUBST([BUILD_WITH_LIBMICROHTTPD_LDFLAGS])
+AC_SUBST([BUILD_WITH_LIBMICROHTTPD_LIBS])
+# }}}
+
# --with-libmodbus {{{
with_libmodbus_config=""
with_libmodbus_cflags=""
AM_CONDITIONAL(BUILD_WITH_LIBPQ, test "x$with_libpq" = "xyes")
# }}}
+# --with-libpqos {{{
+with_libpqos_cppflags=""
+with_libpqos_ldflags=""
+AC_ARG_WITH(libpqos, [AS_HELP_STRING([--with-libpqos@<:@=PREFIX@:>@], [Path to libpqos.])],
+[
+ if test "x$withval" != "xno" && test "x$withval" != "xyes"
+ then
+ with_libpqos_cppflags="-I$withval/include"
+ with_libpqos_ldflags="-L$withval/lib"
+ with_libpqos="yes"
+ else
+ with_libpqos="$withval"
+ fi
+],
+[
+ with_libpqos="yes"
+])
+if test "x$with_libpqos" = "xyes"
+then
+ SAVE_CPPFLAGS="$CPPFLAGS"
+ CPPFLAGS="$CPPFLAGS $with_libpqos_cppflags"
+
+ AC_CHECK_HEADERS(pqos.h, [with_libpqos="yes"], [with_libpqos="no (pqos.h not found)"])
+
+ CPPFLAGS="$SAVE_CPPFLAGS"
+fi
+if test "x$with_libpqos" = "xyes"
+then
+ SAVE_CPPFLAGS="$CPPFLAGS"
+ SAVE_LDFLAGS="$LDFLAGS"
+ CPPFLAGS="$CPPFLAGS $with_libpqos_cppflags"
+ LDFLAGS="$LDFLAGS $with_libpqos_ldflags"
+
+ AC_CHECK_LIB(pqos, pqos_init, [with_libpqos="yes"], [with_libpqos="no (Can't find libpqos)"])
+
+ CPPFLAGS="$SAVE_CPPFLAGS"
+ LDFLAGS="$SAVE_LDFLAGS"
+fi
+if test "x$with_libpqos" = "xyes"
+then
+ BUILD_WITH_LIBPQOS_CPPFLAGS="$with_libpqos_cppflags"
+ BUILD_WITH_LIBPQOS_LDFLAGS="$with_libpqos_ldflags"
+ BUILD_WITH_LIBPQOS_LIBS="-lpqos"
+ AC_SUBST(BUILD_WITH_LIBPQOS_CPPFLAGS)
+ AC_SUBST(BUILD_WITH_LIBPQOS_LDFLAGS)
+ AC_SUBST(BUILD_WITH_LIBPQOS_LIBS)
+fi
+# }}}
+
# --with-libprotobuf {{{
with_libprotobuf_cppflags=""
with_libprotobuf_ldflags=""
plugin_df="no"
plugin_disk="no"
plugin_drbd="no"
+plugin_dpdkstat="no"
plugin_entropy="no"
plugin_ethstat="no"
plugin_fhcount="no"
plugin_fscache="no"
plugin_gps="no"
plugin_grpc="no"
+plugin_hugepages="no"
+plugin_intel_rdt="no"
plugin_interface="no"
plugin_ipmi="no"
plugin_ipvs="no"
plugin_vmem="no"
plugin_vserver="no"
plugin_wireless="no"
+plugin_write_prometheus="no"
plugin_xencpu="no"
plugin_zfs_arc="no"
plugin_zone="no"
plugin_entropy="yes"
plugin_fhcount="yes"
plugin_fscache="yes"
+ plugin_hugepages="yes"
plugin_interface="yes"
plugin_ipc="yes"
plugin_irq="yes"
if test "x$have_protoc_c" = "xyes" && test "x$with_libprotobuf_c" = "xyes"
then
plugin_pinba="yes"
+ if test "x$with_libmicrohttpd" = "xyes"
+ then
+ plugin_write_prometheus="yes"
+ fi
fi
# Mac OS X memory interface
plugin_xencpu="yes"
fi
+if test "x$with_libdpkd" = "xyes"
+then
+ plugin_dpdkstat="yes"
+fi
+
m4_divert_once([HELP_ENABLE], [
collectd plugins:])
AC_PLUGIN([df], [$plugin_df], [Filesystem usage statistics])
AC_PLUGIN([disk], [$plugin_disk], [Disk usage statistics])
AC_PLUGIN([dns], [$with_libpcap], [DNS traffic analysis])
+AC_PLUGIN([dpdkstat], [$plugin_dpdkstat], [Stats & Status from DPDK])
AC_PLUGIN([drbd], [$plugin_drbd], [DRBD statistics])
AC_PLUGIN([email], [yes], [EMail statistics])
AC_PLUGIN([entropy], [$plugin_entropy], [Entropy statistics])
AC_PLUGIN([gps], [$plugin_gps], [GPS plugin])
AC_PLUGIN([grpc], [$plugin_grpc], [gRPC plugin])
AC_PLUGIN([hddtemp], [yes], [Query hddtempd])
+AC_PLUGIN([hugepages], [$plugin_hugepages], [Hugepages statistics])
+AC_PLUGIN([intel_rdt], [$with_libpqos], [Intel RDT monitor plugin])
AC_PLUGIN([interface], [$plugin_interface], [Interface traffic statistics])
AC_PLUGIN([ipc], [$plugin_ipc], [IPC statistics])
AC_PLUGIN([ipmi], [$plugin_ipmi], [IPMI sensor statistics])
AC_PLUGIN([write_kafka], [$with_librdkafka], [Kafka output plugin])
AC_PLUGIN([write_log], [yes], [Log output plugin])
AC_PLUGIN([write_mongodb], [$with_libmongoc], [MongoDB output plugin])
+AC_PLUGIN([write_prometheus], [$plugin_write_prometheus], [Prometheus write plugin])
AC_PLUGIN([write_redis], [$with_libhiredis], [Redis output plugin])
AC_PLUGIN([write_riemann], [$with_libriemann_client], [Riemann output plugin])
AC_PLUGIN([write_sensu], [yes], [Sensu output plugin])
AC_MSG_RESULT([ libatasmart . . . . . $with_libatasmart])
AC_MSG_RESULT([ libcurl . . . . . . . $with_libcurl])
AC_MSG_RESULT([ libdbi . . . . . . . $with_libdbi])
+AC_MSG_RESULT([ libdpdk . . . . . . . $with_libdpdk])
AC_MSG_RESULT([ libesmtp . . . . . . $with_libesmtp])
AC_MSG_RESULT([ libganglia . . . . . $with_libganglia])
AC_MSG_RESULT([ libgcrypt . . . . . . $with_libgcrypt])
AC_MSG_RESULT([ liblua . . . . . . . $with_liblua])
AC_MSG_RESULT([ liblvm2app . . . . . $with_liblvm2app])
AC_MSG_RESULT([ libmemcached . . . . $with_libmemcached])
+AC_MSG_RESULT([ libmicrohttpd . . . . $with_libmicrohttpd])
AC_MSG_RESULT([ libmnl . . . . . . . $with_libmnl])
AC_MSG_RESULT([ libmodbus . . . . . . $with_libmodbus])
AC_MSG_RESULT([ libmongoc . . . . . . $with_libmongoc])
AC_MSG_RESULT([ libperfstat . . . . . $with_perfstat])
AC_MSG_RESULT([ libperl . . . . . . . $with_libperl])
AC_MSG_RESULT([ libpq . . . . . . . . $with_libpq])
+AC_MSG_RESULT([ libpqos . . . . . . . $with_libpqos])
AC_MSG_RESULT([ libprotobuf . . . . . $with_libprotobuf])
AC_MSG_RESULT([ libprotobuf-c . . . . $with_libprotobuf_c])
AC_MSG_RESULT([ libpython . . . . . . $with_libpython])
AC_MSG_RESULT([ df . . . . . . . . . $enable_df])
AC_MSG_RESULT([ disk . . . . . . . . $enable_disk])
AC_MSG_RESULT([ dns . . . . . . . . . $enable_dns])
+AC_MSG_RESULT([ dpdkstat . . . . . . $enable_dpdkstat])
AC_MSG_RESULT([ drbd . . . . . . . . $enable_drbd])
AC_MSG_RESULT([ email . . . . . . . . $enable_email])
AC_MSG_RESULT([ entropy . . . . . . . $enable_entropy])
AC_MSG_RESULT([ gps . . . . . . . . . $enable_gps])
AC_MSG_RESULT([ grpc . . . . . . . . $enable_grpc])
AC_MSG_RESULT([ hddtemp . . . . . . . $enable_hddtemp])
+AC_MSG_RESULT([ hugepages . . . . . . $enable_hugepages])
+AC_MSG_RESULT([ intel_rdt. . . . . . $enable_intel_rdt])
AC_MSG_RESULT([ interface . . . . . . $enable_interface])
AC_MSG_RESULT([ ipc . . . . . . . . . $enable_ipc])
AC_MSG_RESULT([ ipmi . . . . . . . . $enable_ipmi])
AC_MSG_RESULT([ write_kafka . . . . . $enable_write_kafka])
AC_MSG_RESULT([ write_log . . . . . . $enable_write_log])
AC_MSG_RESULT([ write_mongodb . . . . $enable_write_mongodb])
+AC_MSG_RESULT([ write_prometheus. . . $enable_write_prometheus])
AC_MSG_RESULT([ write_redis . . . . . $enable_write_redis])
AC_MSG_RESULT([ write_riemann . . . . $enable_write_riemann])
AC_MSG_RESULT([ write_sensu . . . . . $enable_write_sensu])
* Get reference temperature value
*
* First initially uc_get_rate_by_name is tried. At the startup due to
- * nondeterministic
- * order the temperature may not be read yet (then it fails and first measurment
- * gives
- * only absolute air pressure reading which is acceptable). Once it succedes
- * (should be
- * second measurement at the latest) we use average of few last readings from
- * uc_get_history_by_name. It may take few readings to start filling so again we
- * use
- * uc_get_rate_by_name as a fallback.
+ * nondeterministic order the temperature may not be read yet (then it fails and
+ * first measurment gives only absolute air pressure reading which is
+ * acceptable). Once it succedes (should be second measurement at the latest) we
+ * use average of few last readings from uc_get_history_by_name. It may take few
+ * readings to start filling so again we use uc_get_rate_by_name as a fallback.
* The idea is to use basic "noise" filtering (history averaging) across all the
- * values
- * which given sensor provides (up to given depth). Then we get minimum among
- * the sensors.
+ * values which given sensor provides (up to given depth). Then we get minimum
+ * among the sensors.
*
* @param result where the result is stored. When not available NAN is stored.
*
avg_num = 0;
/* First time need to read current rate to learn how many values are
- there (typically for temperature it would be just one).
- We do not expect dynamic changing of number of temperarure values
- in runtime yet (are there any such cases?). */
+ there (typically for temperature it would be just one). We do not expect
+ dynamic changing of number of temperarure values in runtime yet (are
+ there any such cases?). */
if (!list->initialized) {
if (uc_get_rate_by_name(list->sensor_name, &values, &values_num)) {
DEBUG(
norm_pressure = abs_to_mean_sea_level_pressure(pressure);
- sstrncpy(vl.host, hostname_g, sizeof(vl.host));
sstrncpy(vl.plugin, "barometer", sizeof(vl.plugin));
sstrncpy(vl.plugin_instance, "mpl115", sizeof(vl.plugin_instance));
norm_pressure = abs_to_mean_sea_level_pressure(pressure);
- sstrncpy(vl.host, hostname_g, sizeof(vl.host));
sstrncpy(vl.plugin, "barometer", sizeof(vl.plugin));
sstrncpy(vl.plugin_instance, "mpl3115", sizeof(vl.plugin_instance));
norm_pressure = abs_to_mean_sea_level_pressure(pressure);
- sstrncpy(vl.host, hostname_g, sizeof(vl.host));
sstrncpy(vl.plugin, "barometer", sizeof(vl.plugin));
sstrncpy(vl.plugin_instance, "bmp085", sizeof(vl.plugin_instance));
/**
* collectd - src/utils_cmd_flush.h
- * Copyright (C) 2008 Sebastian Harl
+ * Copyright (C) 2008, 2016 Sebastian Harl
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
#include <stdio.h>
-int handle_flush(FILE *fh, char *buffer);
+#include "utils_cmds.h"
+
- cmd_status_t cmd_parse_flush (size_t argc, char **argv,
- cmd_flush_t *ret_flush, const cmd_options_t *opts,
- cmd_error_handler_t *err);
++cmd_status_t cmd_parse_flush(size_t argc, char **argv, cmd_flush_t *ret_flush,
++ const cmd_options_t *opts,
++ cmd_error_handler_t *err);
+
- cmd_status_t cmd_handle_flush (FILE *fh, char *buffer);
++cmd_status_t cmd_handle_flush(FILE *fh, char *buffer);
+
- void cmd_destroy_flush (cmd_flush_t *flush);
++void cmd_destroy_flush(cmd_flush_t *flush);
#endif /* UTILS_CMD_FLUSH_H */
/* vim: set sw=4 ts=4 tw=78 noexpandtab : */
-
#include "plugin.h"
#include "utils_avltree.h"
- #include "utils_threshold.h"
- #include "utils_parse_option.h" /* for `parse_string' */
#include "utils_cmd_getthreshold.h"
+ #include "utils_parse_option.h" /* for `parse_string' */
+ #include "utils_threshold.h"
- #define print_to_socket(fh, ...) \
- if (fprintf (fh, __VA_ARGS__) < 0) { \
- char errbuf[1024]; \
- WARNING ("handle_getthreshold: failed to write to socket #%i: %s", \
- fileno (fh), sstrerror (errno, errbuf, sizeof (errbuf))); \
- return -1; \
+ #define print_to_socket(fh, ...) \
+ if (fprintf(fh, __VA_ARGS__) < 0) { \
+ char errbuf[1024]; \
+ WARNING("handle_getthreshold: failed to write to socket #%i: %s", \
+ fileno(fh), sstrerror(errno, errbuf, sizeof(errbuf))); \
+ return -1; \
}
- int handle_getthreshold (FILE *fh, char *buffer)
- {
+ int handle_getthreshold(FILE *fh, char *buffer) {
char *command;
char *identifier;
char *identifier_copy;
threshold_t threshold;
- int status;
+ int status;
size_t i;
if ((fh == NULL) || (buffer == NULL))
return (-1);
- DEBUG ("utils_cmd_getthreshold: handle_getthreshold (fh = %p, buffer = %s);",
- (void *) fh, buffer);
+ DEBUG("utils_cmd_getthreshold: handle_getthreshold (fh = %p, buffer = %s);",
+ (void *)fh, buffer);
command = NULL;
- status = parse_string (&buffer, &command);
- if (status != 0)
- {
- print_to_socket (fh, "-1 Cannot parse command.\n");
+ status = parse_string(&buffer, &command);
+ if (status != 0) {
+ print_to_socket(fh, "-1 Cannot parse command.\n");
return (-1);
}
- assert (command != NULL);
+ assert(command != NULL);
- if (strcasecmp ("GETTHRESHOLD", command) != 0)
- {
- print_to_socket (fh, "-1 Unexpected command: `%s'.\n", command);
+ if (strcasecmp("GETTHRESHOLD", command) != 0) {
+ print_to_socket(fh, "-1 Unexpected command: `%s'.\n", command);
return (-1);
}
identifier = NULL;
- status = parse_string (&buffer, &identifier);
- if (status != 0)
- {
- print_to_socket (fh, "-1 Cannot parse identifier.\n");
+ status = parse_string(&buffer, &identifier);
+ if (status != 0) {
+ print_to_socket(fh, "-1 Cannot parse identifier.\n");
return (-1);
}
- assert (identifier != NULL);
+ assert(identifier != NULL);
- if (*buffer != 0)
- {
- print_to_socket (fh, "-1 Garbage after end of command: %s\n", buffer);
+ if (*buffer != 0) {
+ print_to_socket(fh, "-1 Garbage after end of command: %s\n", buffer);
return (-1);
}
/* parse_identifier() modifies its first argument,
* returning pointers into it */
- identifier_copy = sstrdup (identifier);
-
- status = parse_identifier (identifier_copy, &host,
- &plugin, &plugin_instance,
- &type, &type_instance,
- /* default_host = */ NULL);
- if (status != 0)
- {
- DEBUG ("handle_getthreshold: Cannot parse identifier `%s'.", identifier);
- print_to_socket (fh, "-1 Cannot parse identifier `%s'.\n", identifier);
- sfree (identifier_copy);
+ identifier_copy = sstrdup(identifier);
+
+ status = parse_identifier(identifier_copy, &host, &plugin, &plugin_instance,
- &type, &type_instance);
++ &type, &type_instance,
++ /* default_host = */ NULL);
+ if (status != 0) {
+ DEBUG("handle_getthreshold: Cannot parse identifier `%s'.", identifier);
+ print_to_socket(fh, "-1 Cannot parse identifier `%s'.\n", identifier);
+ sfree(identifier_copy);
return (-1);
}
- value_list_t vl = {
- .values = NULL
- };
- sstrncpy (vl.host, host, sizeof (vl.host));
- sstrncpy (vl.plugin, plugin, sizeof (vl.plugin));
+ value_list_t vl = {.values = NULL};
+ sstrncpy(vl.host, host, sizeof(vl.host));
+ sstrncpy(vl.plugin, plugin, sizeof(vl.plugin));
if (plugin_instance != NULL)
- sstrncpy (vl.plugin_instance, plugin_instance, sizeof (vl.plugin_instance));
- sstrncpy (vl.type, type, sizeof (vl.type));
+ sstrncpy(vl.plugin_instance, plugin_instance, sizeof(vl.plugin_instance));
+ sstrncpy(vl.type, type, sizeof(vl.type));
if (type_instance != NULL)
- sstrncpy (vl.type_instance, type_instance, sizeof (vl.type_instance));
- sfree (identifier_copy);
-
- status = ut_search_threshold (&vl, &threshold);
- if (status == ENOENT)
- {
- print_to_socket (fh, "-1 No threshold found for identifier %s\n",
- identifier);
+ sstrncpy(vl.type_instance, type_instance, sizeof(vl.type_instance));
+ sfree(identifier_copy);
+
+ status = ut_search_threshold(&vl, &threshold);
+ if (status == ENOENT) {
+ print_to_socket(fh, "-1 No threshold found for identifier %s\n",
+ identifier);
return (0);
- }
- else if (status != 0)
- {
- print_to_socket (fh, "-1 Error while looking up threshold: %i\n",
- status);
+ } else if (status != 0) {
+ print_to_socket(fh, "-1 Error while looking up threshold: %i\n", status);
return (-1);
}
/* Lets count the number of lines we'll return. */
i = 0;
- if (threshold.host[0] != 0) i++;
- if (threshold.plugin[0] != 0) i++;
- if (threshold.plugin_instance[0] != 0) i++;
- if (threshold.type[0] != 0) i++;
- if (threshold.type_instance[0] != 0) i++;
- if (threshold.data_source[0] != 0) i++;
- if (!isnan (threshold.warning_min)) i++;
- if (!isnan (threshold.warning_max)) i++;
- if (!isnan (threshold.failure_min)) i++;
- if (!isnan (threshold.failure_max)) i++;
- if (threshold.hysteresis > 0.0) i++;
- if (threshold.hits > 1) i++;
-
- /* Print the response */
- print_to_socket (fh, "%zu Threshold found\n", i);
-
if (threshold.host[0] != 0)
- print_to_socket (fh, "Host: %s\n", threshold.host)
+ i++;
if (threshold.plugin[0] != 0)
- print_to_socket (fh, "Plugin: %s\n", threshold.plugin)
+ i++;
if (threshold.plugin_instance[0] != 0)
- print_to_socket (fh, "Plugin Instance: %s\n", threshold.plugin_instance)
+ i++;
if (threshold.type[0] != 0)
- print_to_socket (fh, "Type: %s\n", threshold.type)
+ i++;
if (threshold.type_instance[0] != 0)
- print_to_socket (fh, "Type Instance: %s\n", threshold.type_instance)
+ i++;
if (threshold.data_source[0] != 0)
- print_to_socket (fh, "Data Source: %s\n", threshold.data_source)
- if (!isnan (threshold.warning_min))
- print_to_socket (fh, "Warning Min: %g\n", threshold.warning_min)
- if (!isnan (threshold.warning_max))
- print_to_socket (fh, "Warning Max: %g\n", threshold.warning_max)
- if (!isnan (threshold.failure_min))
- print_to_socket (fh, "Failure Min: %g\n", threshold.failure_min)
- if (!isnan (threshold.failure_max))
- print_to_socket (fh, "Failure Max: %g\n", threshold.failure_max)
+ i++;
+ if (!isnan(threshold.warning_min))
+ i++;
+ if (!isnan(threshold.warning_max))
+ i++;
+ if (!isnan(threshold.failure_min))
+ i++;
+ if (!isnan(threshold.failure_max))
+ i++;
if (threshold.hysteresis > 0.0)
- print_to_socket (fh, "Hysteresis: %g\n", threshold.hysteresis)
+ i++;
if (threshold.hits > 1)
- print_to_socket (fh, "Hits: %i\n", threshold.hits)
+ i++;
- return (0);
+ /* Print the response */
+ print_to_socket(fh, "%zu Threshold found\n", i);
+
+ if (threshold.host[0] != 0)
+ print_to_socket(fh, "Host: %s\n", threshold.host) if (
+ threshold.plugin[0] !=
+ 0) print_to_socket(fh, "Plugin: %s\n",
+ threshold.plugin) if (threshold.plugin_instance[0] !=
+ 0)
+ print_to_socket(fh, "Plugin Instance: %s\n",
+ threshold.plugin_instance) if (threshold.type[0] != 0)
+ print_to_socket(fh, "Type: %s\n", threshold.type) if (
+ threshold.type_instance[0] !=
+ 0) print_to_socket(fh, "Type Instance: %s\n",
+ threshold
+ .type_instance) if (threshold.data_source
+ [0] != 0)
+ print_to_socket(
+ fh, "Data Source: %s\n",
+ threshold.data_source) if (!isnan(threshold.warning_min))
+ print_to_socket(
+ fh, "Warning Min: %g\n",
+ threshold
+ .warning_min) if (!isnan(threshold.warning_max))
+ print_to_socket(
+ fh, "Warning Max: %g\n",
+ threshold
+ .warning_max) if (!isnan(threshold.failure_min))
+ print_to_socket(
+ fh, "Failure Min: %g\n",
+ threshold
+ .failure_min) if (!isnan(threshold
+ .failure_max))
+ print_to_socket(
+ fh, "Failure Max: %g\n",
+ threshold.failure_max) if (threshold
+ .hysteresis >
+ 0.0)
+ print_to_socket(
+ fh, "Hysteresis: %g\n",
+ threshold.hysteresis) if (threshold
+ .hits > 1)
+ print_to_socket(fh, "Hits: %i\n",
+ threshold.hits)
+
+ return (0);
} /* int handle_getthreshold */
/* vim: set sw=2 sts=2 ts=8 et : */
#include "plugin.h"
#include "utils_cache.h"
- #include "utils_parse_option.h"
#include "utils_cmd_getval.h"
+ #include "utils_parse_option.h"
- cmd_status_t cmd_parse_getval (size_t argc, char **argv,
- cmd_getval_t *ret_getval, const cmd_options_t *opts,
- cmd_error_handler_t *err)
- {
++cmd_status_t cmd_parse_getval(size_t argc, char **argv,
++ cmd_getval_t *ret_getval,
++ const cmd_options_t *opts,
++ cmd_error_handler_t *err) {
+ char *identifier_copy;
+ int status;
+
- if ((ret_getval == NULL) || (opts == NULL))
- {
++ if ((ret_getval == NULL) || (opts == NULL)) {
+ errno = EINVAL;
- cmd_error (CMD_ERROR, err, "Invalid arguments to cmd_parse_getval.");
++ cmd_error(CMD_ERROR, err, "Invalid arguments to cmd_parse_getval.");
+ return (CMD_ERROR);
+ }
+
- if (argc != 1)
- {
++ if (argc != 1) {
+ if (argc == 0)
- cmd_error (CMD_PARSE_ERROR, err, "Missing identifier.");
++ cmd_error(CMD_PARSE_ERROR, err, "Missing identifier.");
+ else
- cmd_error (CMD_PARSE_ERROR, err,
- "Garbage after identifier: `%s'.", argv[1]);
++ cmd_error(CMD_PARSE_ERROR, err, "Garbage after identifier: `%s'.",
++ argv[1]);
+ return (CMD_PARSE_ERROR);
+ }
+
+ /* parse_identifier() modifies its first argument,
+ * returning pointers into it */
- identifier_copy = sstrdup (argv[0]);
-
- status = parse_identifier (argv[0], &ret_getval->identifier.host,
- &ret_getval->identifier.plugin, &ret_getval->identifier.plugin_instance,
- &ret_getval->identifier.type, &ret_getval->identifier.type_instance,
- opts->identifier_default_host);
- if (status != 0)
- {
- DEBUG ("cmd_parse_getval: Cannot parse identifier `%s'.", identifier_copy);
- cmd_error (CMD_PARSE_ERROR, err,
- "Cannot parse identifier `%s'.", identifier_copy);
- sfree (identifier_copy);
++ identifier_copy = sstrdup(argv[0]);
++
++ status = parse_identifier(
++ argv[0], &ret_getval->identifier.host, &ret_getval->identifier.plugin,
++ &ret_getval->identifier.plugin_instance, &ret_getval->identifier.type,
++ &ret_getval->identifier.type_instance, opts->identifier_default_host);
++ if (status != 0) {
++ DEBUG("cmd_parse_getval: Cannot parse identifier `%s'.", identifier_copy);
++ cmd_error(CMD_PARSE_ERROR, err, "Cannot parse identifier `%s'.",
++ identifier_copy);
++ sfree(identifier_copy);
+ return (CMD_PARSE_ERROR);
+ }
+
+ ret_getval->raw_identifier = identifier_copy;
+ return (CMD_OK);
+} /* cmd_status_t cmd_parse_getval */
+
- #define print_to_socket(fh, ...) \
- do { \
- if (fprintf (fh, __VA_ARGS__) < 0) { \
- char errbuf[1024]; \
- WARNING ("cmd_handle_getval: failed to write to socket #%i: %s", \
- fileno (fh), sstrerror (errno, errbuf, sizeof (errbuf))); \
- return -1; \
- } \
- fflush(fh); \
+ #define print_to_socket(fh, ...) \
+ do { \
+ if (fprintf(fh, __VA_ARGS__) < 0) { \
+ char errbuf[1024]; \
- WARNING("handle_getval: failed to write to socket #%i: %s", fileno(fh), \
- sstrerror(errno, errbuf, sizeof(errbuf))); \
++ WARNING("cmd_handle_getval: failed to write to socket #%i: %s", \
++ fileno(fh), sstrerror(errno, errbuf, sizeof(errbuf))); \
+ return -1; \
+ } \
+ fflush(fh); \
} while (0)
- cmd_status_t cmd_handle_getval (FILE *fh, char *buffer)
- {
- cmd_error_handler_t err = { cmd_error_fh, fh };
-int handle_getval(FILE *fh, char *buffer) {
- char *command;
- char *identifier;
- char *identifier_copy;
++cmd_status_t cmd_handle_getval(FILE *fh, char *buffer) {
++ cmd_error_handler_t err = {cmd_error_fh, fh};
+ cmd_status_t status;
+ cmd_t cmd;
- char *hostname;
- char *plugin;
- char *plugin_instance;
- char *type;
- char *type_instance;
gauge_t *values;
size_t values_num;
const data_set_t *ds;
- int status;
--
if ((fh == NULL) || (buffer == NULL))
return (-1);
- DEBUG ("utils_cmd_getval: cmd_handle_getval (fh = %p, buffer = %s);",
- (void *) fh, buffer);
- DEBUG("utils_cmd_getval: handle_getval (fh = %p, buffer = %s);", (void *)fh,
- buffer);
++ DEBUG("utils_cmd_getval: cmd_handle_getval (fh = %p, buffer = %s);",
++ (void *)fh, buffer);
- if ((status = cmd_parse (buffer, &cmd, NULL, &err)) != CMD_OK)
- command = NULL;
- status = parse_string(&buffer, &command);
- if (status != 0) {
- print_to_socket(fh, "-1 Cannot parse command.\n");
- return (-1);
- }
- assert(command != NULL);
-
- if (strcasecmp("GETVAL", command) != 0) {
- print_to_socket(fh, "-1 Unexpected command: `%s'.\n", command);
- return (-1);
++ if ((status = cmd_parse(buffer, &cmd, NULL, &err)) != CMD_OK)
+ return (status);
- if (cmd.type != CMD_GETVAL)
- {
- cmd_error (CMD_UNKNOWN_COMMAND, &err,
- "Unexpected command: `%s'.", CMD_TO_STRING (cmd.type));
- cmd_destroy (&cmd);
++ if (cmd.type != CMD_GETVAL) {
++ cmd_error(CMD_UNKNOWN_COMMAND, &err, "Unexpected command: `%s'.",
++ CMD_TO_STRING(cmd.type));
++ cmd_destroy(&cmd);
+ return (CMD_UNKNOWN_COMMAND);
}
- ds = plugin_get_ds (cmd.cmd.getval.identifier.type);
- if (ds == NULL)
- {
- DEBUG ("cmd_handle_getval: plugin_get_ds (%s) == NULL;",
- cmd.cmd.getval.identifier.type);
- cmd_error (CMD_ERROR, &err, "Type `%s' is unknown.\n",
- cmd.cmd.getval.identifier.type);
- cmd_destroy (&cmd);
- identifier = NULL;
- status = parse_string(&buffer, &identifier);
- if (status != 0) {
- print_to_socket(fh, "-1 Cannot parse identifier.\n");
- return (-1);
- }
- assert(identifier != NULL);
-
- if (*buffer != 0) {
- print_to_socket(fh, "-1 Garbage after end of command: %s\n", buffer);
- return (-1);
- }
-
- /* parse_identifier() modifies its first argument,
- * returning pointers into it */
- identifier_copy = sstrdup(identifier);
-
- status = parse_identifier(identifier_copy, &hostname, &plugin,
- &plugin_instance, &type, &type_instance);
- if (status != 0) {
- DEBUG("handle_getval: Cannot parse identifier `%s'.", identifier);
- print_to_socket(fh, "-1 Cannot parse identifier `%s'.\n", identifier);
- sfree(identifier_copy);
- return (-1);
- }
-
- ds = plugin_get_ds(type);
++ ds = plugin_get_ds(cmd.cmd.getval.identifier.type);
+ if (ds == NULL) {
- DEBUG("handle_getval: plugin_get_ds (%s) == NULL;", type);
- print_to_socket(fh, "-1 Type `%s' is unknown.\n", type);
- sfree(identifier_copy);
++ DEBUG("cmd_handle_getval: plugin_get_ds (%s) == NULL;",
++ cmd.cmd.getval.identifier.type);
++ cmd_error(CMD_ERROR, &err, "Type `%s' is unknown.\n",
++ cmd.cmd.getval.identifier.type);
++ cmd_destroy(&cmd);
return (-1);
}
values = NULL;
values_num = 0;
- status = uc_get_rate_by_name (cmd.cmd.getval.raw_identifier, &values, &values_num);
- if (status != 0)
- {
- cmd_error (CMD_ERROR, &err, "No such value.");
- cmd_destroy (&cmd);
- status = uc_get_rate_by_name(identifier, &values, &values_num);
++ status =
++ uc_get_rate_by_name(cmd.cmd.getval.raw_identifier, &values, &values_num);
+ if (status != 0) {
- print_to_socket(fh, "-1 No such value\n");
- sfree(identifier_copy);
- return (-1);
++ cmd_error(CMD_ERROR, &err, "No such value.");
++ cmd_destroy(&cmd);
+ return (CMD_ERROR);
}
- if (ds->ds_num != values_num)
- {
- ERROR ("ds[%s]->ds_num = %zu, "
- "but uc_get_rate_by_name returned %zu values.",
- ds->type, ds->ds_num, values_num);
- cmd_error (CMD_ERROR, &err, "Error reading value from cache.");
- sfree (values);
- cmd_destroy (&cmd);
+ if (ds->ds_num != values_num) {
+ ERROR("ds[%s]->ds_num = %zu, "
+ "but uc_get_rate_by_name returned %zu values.",
+ ds->type, ds->ds_num, values_num);
- print_to_socket(fh, "-1 Error reading value from cache.\n");
++ cmd_error(CMD_ERROR, &err, "Error reading value from cache.");
+ sfree(values);
- sfree(identifier_copy);
- return (-1);
++ cmd_destroy(&cmd);
+ return (CMD_ERROR);
}
- print_to_socket (fh, "%zu Value%s found\n", values_num,
- (values_num == 1) ? "" : "s");
- for (size_t i = 0; i < values_num; i++)
- {
- print_to_socket (fh, "%s=", ds->ds[i].name);
- if (isnan (values[i]))
- {
- print_to_socket (fh, "NaN\n");
- }
- else
- {
- print_to_socket (fh, "%12e\n", values[i]);
+ print_to_socket(fh, "%zu Value%s found\n", values_num,
+ (values_num == 1) ? "" : "s");
+ for (size_t i = 0; i < values_num; i++) {
+ print_to_socket(fh, "%s=", ds->ds[i].name);
+ if (isnan(values[i])) {
+ print_to_socket(fh, "NaN\n");
+ } else {
+ print_to_socket(fh, "%12e\n", values[i]);
}
}
- sfree (values);
- cmd_destroy (&cmd);
+ sfree(values);
- sfree(identifier_copy);
++ cmd_destroy(&cmd);
+
+ return (CMD_OK);
+} /* cmd_status_t cmd_handle_getval */
+
- void cmd_destroy_getval (cmd_getval_t *getval)
- {
++void cmd_destroy_getval(cmd_getval_t *getval) {
+ if (getval == NULL)
+ return;
- sfree (getval->raw_identifier);
- return (0);
-} /* int handle_getval */
++ sfree(getval->raw_identifier);
+} /* void cmd_destroy_getval */
/* vim: set sw=2 sts=2 ts=8 : */
#include <stdio.h>
-int handle_getval(FILE *fh, char *buffer);
+#include "utils_cmds.h"
+
- cmd_status_t cmd_parse_getval (size_t argc, char **argv,
- cmd_getval_t *ret_getval, const cmd_options_t *opts,
- cmd_error_handler_t *err);
++cmd_status_t cmd_parse_getval(size_t argc, char **argv,
++ cmd_getval_t *ret_getval,
++ const cmd_options_t *opts,
++ cmd_error_handler_t *err);
+
- cmd_status_t cmd_handle_getval (FILE *fh, char *buffer);
++cmd_status_t cmd_handle_getval(FILE *fh, char *buffer);
+
- void cmd_destroy_getval (cmd_getval_t *getval);
++void cmd_destroy_getval(cmd_getval_t *getval);
#endif /* UTILS_CMD_GETVAL_H */
#include "common.h"
#include "plugin.h"
- #include "utils_cmd_listval.h"
#include "utils_cache.h"
+ #include "utils_cmd_listval.h"
#include "utils_parse_option.h"
- cmd_status_t cmd_parse_listval (size_t argc, char **argv,
- cmd_listval_t *ret_listval __attribute__((unused)),
- const cmd_options_t *opts __attribute__((unused)),
- cmd_error_handler_t *err)
- {
- if (argc != 0)
- {
- cmd_error (CMD_PARSE_ERROR, err,
- "Garbage after end of command: `%s'.", argv[0]);
++cmd_status_t cmd_parse_listval(size_t argc, char **argv,
++ cmd_listval_t *ret_listval
++ __attribute__((unused)),
++ const cmd_options_t *opts
++ __attribute__((unused)),
++ cmd_error_handler_t *err) {
++ if (argc != 0) {
++ cmd_error(CMD_PARSE_ERROR, err, "Garbage after end of command: `%s'.",
++ argv[0]);
+ return (CMD_PARSE_ERROR);
+ }
+
+ return (CMD_OK);
+} /* cmd_status_t cmd_parse_listval */
+
- #define free_everything_and_return(status) do { \
- for (size_t j = 0; j < number; j++) { \
- sfree(names[j]); \
- names[j] = NULL; \
- } \
- sfree(names); \
- sfree(times); \
- return (status); \
+ #define free_everything_and_return(status) \
+ do { \
+ for (size_t j = 0; j < number; j++) { \
+ sfree(names[j]); \
+ names[j] = NULL; \
+ } \
+ sfree(names); \
+ sfree(times); \
+ return (status); \
} while (0)
- #define print_to_socket(fh, ...) \
- do { \
- if (fprintf (fh, __VA_ARGS__) < 0) { \
- char errbuf[1024]; \
- WARNING ("handle_listval: failed to write to socket #%i: %s", \
- fileno (fh), sstrerror (errno, errbuf, sizeof (errbuf))); \
- free_everything_and_return (CMD_ERROR); \
- } \
- fflush(fh); \
+ #define print_to_socket(fh, ...) \
+ do { \
+ if (fprintf(fh, __VA_ARGS__) < 0) { \
+ char errbuf[1024]; \
+ WARNING("handle_listval: failed to write to socket #%i: %s", fileno(fh), \
+ sstrerror(errno, errbuf, sizeof(errbuf))); \
- free_everything_and_return(-1); \
++ free_everything_and_return(CMD_ERROR); \
+ } \
+ fflush(fh); \
} while (0)
- cmd_status_t cmd_handle_listval (FILE *fh, char *buffer)
- {
- cmd_error_handler_t err = { cmd_error_fh, fh };
-int handle_listval(FILE *fh, char *buffer) {
- char *command;
++cmd_status_t cmd_handle_listval(FILE *fh, char *buffer) {
++ cmd_error_handler_t err = {cmd_error_fh, fh};
+ cmd_status_t status;
+ cmd_t cmd;
+
char **names = NULL;
cdtime_t *times = NULL;
size_t number = 0;
- int status;
- DEBUG ("utils_cmd_listval: handle_listval (fh = %p, buffer = %s);",
- (void *) fh, buffer);
+ DEBUG("utils_cmd_listval: handle_listval (fh = %p, buffer = %s);", (void *)fh,
+ buffer);
- if ((status = cmd_parse (buffer, &cmd, NULL, &err)) != CMD_OK)
- command = NULL;
- status = parse_string(&buffer, &command);
- if (status != 0) {
- print_to_socket(fh, "-1 Cannot parse command.\n");
- free_everything_and_return(-1);
- }
- assert(command != NULL);
-
- if (strcasecmp("LISTVAL", command) != 0) {
- print_to_socket(fh, "-1 Unexpected command: `%s'.\n", command);
- free_everything_and_return(-1);
- }
-
- if (*buffer != 0) {
- print_to_socket(fh, "-1 Garbage after end of command: %s\n", buffer);
- free_everything_and_return(-1);
++ if ((status = cmd_parse(buffer, &cmd, NULL, &err)) != CMD_OK)
+ return (status);
- if (cmd.type != CMD_LISTVAL)
- {
- cmd_error (CMD_UNKNOWN_COMMAND, &err,
- "Unexpected command: `%s'.", CMD_TO_STRING (cmd.type));
- free_everything_and_return (CMD_UNKNOWN_COMMAND);
++ if (cmd.type != CMD_LISTVAL) {
++ cmd_error(CMD_UNKNOWN_COMMAND, &err, "Unexpected command: `%s'.",
++ CMD_TO_STRING(cmd.type));
++ free_everything_and_return(CMD_UNKNOWN_COMMAND);
}
- status = uc_get_names (&names, ×, &number);
- if (status != 0)
- {
- DEBUG ("command listval: uc_get_names failed with status %i", status);
- cmd_error (CMD_ERROR, &err, "uc_get_names failed.");
- free_everything_and_return (CMD_ERROR);
+ status = uc_get_names(&names, ×, &number);
+ if (status != 0) {
+ DEBUG("command listval: uc_get_names failed with status %i", status);
- print_to_socket(fh, "-1 uc_get_names failed.\n");
- free_everything_and_return(-1);
++ cmd_error(CMD_ERROR, &err, "uc_get_names failed.");
++ free_everything_and_return(CMD_ERROR);
}
- print_to_socket (fh, "%i Value%s found\n",
- (int) number, (number == 1) ? "" : "s");
+ print_to_socket(fh, "%i Value%s found\n", (int)number,
+ (number == 1) ? "" : "s");
for (size_t i = 0; i < number; i++)
- print_to_socket (fh, "%.3f %s\n", CDTIME_T_TO_DOUBLE (times[i]),
- names[i]);
+ print_to_socket(fh, "%.3f %s\n", CDTIME_T_TO_DOUBLE(times[i]), names[i]);
- free_everything_and_return (CMD_OK);
- free_everything_and_return(0);
-} /* int handle_listval */
++ free_everything_and_return(CMD_OK);
+} /* cmd_status_t cmd_handle_listval */
+
- void cmd_destroy_listval (cmd_listval_t *listval __attribute__((unused)))
- {
++void cmd_destroy_listval(cmd_listval_t *listval __attribute__((unused))) {
+ /* nothing to do */
+} /* void cmd_destroy_listval */
/* vim: set sw=2 sts=2 ts=8 : */
#include <stdio.h>
-int handle_listval(FILE *fh, char *buffer);
+#include "utils_cmds.h"
+
- cmd_status_t cmd_parse_listval (size_t argc, char **argv,
- cmd_listval_t *ret_listval, const cmd_options_t *opts,
- cmd_error_handler_t *err);
++cmd_status_t cmd_parse_listval(size_t argc, char **argv,
++ cmd_listval_t *ret_listval,
++ const cmd_options_t *opts,
++ cmd_error_handler_t *err);
+
- cmd_status_t cmd_handle_listval (FILE *fh, char *buffer);
++cmd_status_t cmd_handle_listval(FILE *fh, char *buffer);
+
- void cmd_destroy_listval (cmd_listval_t *listval);
++void cmd_destroy_listval(cmd_listval_t *listval);
#endif /* UTILS_CMD_LISTVAL_H */
/**
* collectd - src/utils_cmd_putval.c
* Copyright (C) 2007-2009 Florian octo Forster
+ * Copyright (C) 2016 Sebastian tokkee Harl
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
*
* Authors:
* Florian octo Forster <octo at collectd.org>
+ * Sebastian tokkee Harl <sh at tokkee.org>
**/
#include "collectd.h"
#include "common.h"
#include "plugin.h"
- #include "utils_cmds.h"
#include "utils_cmd_putval.h"
- #include "utils_parse_option.h"
+#include "utils_cmd_putval.h"
++#include "utils_cmds.h"
+ #include "utils_parse_option.h"
-#define print_to_socket(fh, ...) \
- do { \
- if (fprintf(fh, __VA_ARGS__) < 0) { \
- char errbuf[1024]; \
- WARNING("handle_putval: failed to write to socket #%i: %s", fileno(fh), \
- sstrerror(errno, errbuf, sizeof(errbuf))); \
- sfree(vl.values); \
- return -1; \
- } \
- fflush(fh); \
- } while (0)
+/*
+ * private helper functions
+ */
- static int set_option (value_list_t *vl, const char *key, const char *value)
- {
- if ((vl == NULL) || (key == NULL) || (value == NULL))
- return (-1);
+ static int set_option(value_list_t *vl, const char *key, const char *value) {
+ if ((vl == NULL) || (key == NULL) || (value == NULL))
+ return (-1);
- if (strcasecmp ("interval", key) == 0)
- {
- double tmp;
- char *endptr;
+ if (strcasecmp("interval", key) == 0) {
+ double tmp;
+ char *endptr;
- endptr = NULL;
- errno = 0;
- tmp = strtod (value, &endptr);
+ endptr = NULL;
+ errno = 0;
+ tmp = strtod(value, &endptr);
- if ((errno == 0) && (endptr != NULL)
- && (endptr != value) && (tmp > 0.0))
- vl->interval = DOUBLE_TO_CDTIME_T (tmp);
- }
- else
- return (1);
+ if ((errno == 0) && (endptr != NULL) && (endptr != value) && (tmp > 0.0))
+ vl->interval = DOUBLE_TO_CDTIME_T(tmp);
+ } else
+ return (1);
- return (0);
+ return (0);
-} /* int parse_option */
+} /* int set_option */
+
+/*
+ * public API
+ */
+
- cmd_status_t cmd_parse_putval (size_t argc, char **argv,
- cmd_putval_t *ret_putval, const cmd_options_t *opts,
- cmd_error_handler_t *err)
- {
- cmd_status_t result;
-
- char *identifier;
- char *hostname;
- char *plugin;
- char *plugin_instance;
- char *type;
- char *type_instance;
- int status;
-
- char *identifier_copy;
-
- const data_set_t *ds;
- value_list_t vl = VALUE_LIST_INIT;
-
- if ((ret_putval == NULL) || (opts == NULL))
- {
- errno = EINVAL;
- cmd_error (CMD_ERROR, err, "Invalid arguments to cmd_parse_putval.");
- return (CMD_ERROR);
- }
-
- if (argc < 2)
- {
- cmd_error (CMD_PARSE_ERROR, err,
- "Missing identifier and/or value-list.");
- return (CMD_PARSE_ERROR);
- }
-
- identifier = argv[0];
-
- /* parse_identifier() modifies its first argument, returning pointers into
- * it; retain the old value for later. */
- identifier_copy = sstrdup (identifier);
-
- status = parse_identifier (identifier, &hostname,
- &plugin, &plugin_instance,
- &type, &type_instance,
- opts->identifier_default_host);
- if (status != 0)
- {
- DEBUG ("cmd_handle_putval: Cannot parse identifier `%s'.",
- identifier_copy);
- cmd_error (CMD_PARSE_ERROR, err, "Cannot parse identifier `%s'.",
- identifier_copy);
- sfree (identifier_copy);
- return (CMD_PARSE_ERROR);
- }
-
- if ((strlen (hostname) >= sizeof (vl.host))
- || (strlen (plugin) >= sizeof (vl.plugin))
- || ((plugin_instance != NULL)
- && (strlen (plugin_instance) >= sizeof (vl.plugin_instance)))
- || ((type_instance != NULL)
- && (strlen (type_instance) >= sizeof (vl.type_instance))))
- {
- cmd_error (CMD_PARSE_ERROR, err, "Identifier too long.");
- sfree (identifier_copy);
- return (CMD_PARSE_ERROR);
- }
-
- sstrncpy (vl.host, hostname, sizeof (vl.host));
- sstrncpy (vl.plugin, plugin, sizeof (vl.plugin));
- sstrncpy (vl.type, type, sizeof (vl.type));
- if (plugin_instance != NULL)
- sstrncpy (vl.plugin_instance, plugin_instance, sizeof (vl.plugin_instance));
- if (type_instance != NULL)
- sstrncpy (vl.type_instance, type_instance, sizeof (vl.type_instance));
-
- ds = plugin_get_ds (type);
- if (ds == NULL)
- {
- cmd_error (CMD_PARSE_ERROR, err, "1 Type `%s' isn't defined.", type);
- sfree (identifier_copy);
- return (CMD_PARSE_ERROR);
- }
-
- hostname = NULL;
- plugin = NULL; plugin_instance = NULL;
- type = NULL; type_instance = NULL;
-
- vl.values_len = ds->ds_num;
- vl.values = malloc (vl.values_len * sizeof (*vl.values));
- if (vl.values == NULL)
- {
- cmd_error (CMD_ERROR, err, "malloc failed.");
- sfree (identifier_copy);
- return (CMD_ERROR);
- }
-
- ret_putval->raw_identifier = identifier_copy;
- if (ret_putval->raw_identifier == NULL)
- {
- cmd_error (CMD_ERROR, err, "malloc failed.");
- cmd_destroy_putval (ret_putval);
- sfree (vl.values);
- return (CMD_ERROR);
- }
-
- /* All the remaining fields are part of the option list. */
- result = CMD_OK;
- for (size_t i = 1; i < argc; ++i)
- {
- value_list_t *tmp;
-
- char *key = NULL;
- char *value = NULL;
-
- status = cmd_parse_option (argv[i], &key, &value, err);
- if (status == CMD_OK)
- {
- assert (key != NULL);
- assert (value != NULL);
- set_option (&vl, key, value);
- continue;
- }
- else if (status != CMD_NO_OPTION)
- {
- /* parse_option failed, buffer has been modified.
- * => we need to abort */
- result = status;
- break;
- }
- /* else: cmd_parse_option did not find an option; treat this as a
- * value list. */
-
- status = parse_values (argv[i], &vl, ds);
- if (status != 0)
- {
- cmd_error (CMD_PARSE_ERROR, err, "Parsing the values string failed.");
- result = CMD_PARSE_ERROR;
- break;
- }
-
- tmp = (value_list_t *) realloc (ret_putval->vl,
- (ret_putval->vl_num + 1) * sizeof(*ret_putval->vl));
- if (tmp == NULL)
- {
- cmd_error (CMD_ERROR, err, "realloc failed.");
- cmd_destroy_putval (ret_putval);
- result = CMD_ERROR;
- break;
- }
-
- ret_putval->vl = tmp;
- ret_putval->vl_num++;
- memcpy (&ret_putval->vl[ret_putval->vl_num - 1], &vl, sizeof (vl));
- } /* while (*buffer != 0) */
- /* Done parsing the options. */
-
- if (result != CMD_OK)
- {
- if (ret_putval->vl_num == 0)
- sfree (vl.values);
- cmd_destroy_putval (ret_putval);
- }
-
- return (result);
++cmd_status_t cmd_parse_putval(size_t argc, char **argv,
++ cmd_putval_t *ret_putval,
++ const cmd_options_t *opts,
++ cmd_error_handler_t *err) {
++ cmd_status_t result;
+
-int handle_putval(FILE *fh, char *buffer) {
- char *command;
+ char *identifier;
+ char *hostname;
+ char *plugin;
+ char *plugin_instance;
+ char *type;
+ char *type_instance;
+ int status;
- int values_submitted;
+
+ char *identifier_copy;
+
+ const data_set_t *ds;
+ value_list_t vl = VALUE_LIST_INIT;
- vl.values = NULL;
+
- DEBUG("utils_cmd_putval: handle_putval (fh = %p, buffer = %s);", (void *)fh,
- buffer);
-
- command = NULL;
- status = parse_string(&buffer, &command);
- if (status != 0) {
- print_to_socket(fh, "-1 Cannot parse command.\n");
- return (-1);
++ if ((ret_putval == NULL) || (opts == NULL)) {
++ errno = EINVAL;
++ cmd_error(CMD_ERROR, err, "Invalid arguments to cmd_parse_putval.");
++ return (CMD_ERROR);
+ }
- assert(command != NULL);
+
- if (strcasecmp("PUTVAL", command) != 0) {
- print_to_socket(fh, "-1 Unexpected command: `%s'.\n", command);
- return (-1);
++ if (argc < 2) {
++ cmd_error(CMD_PARSE_ERROR, err, "Missing identifier and/or value-list.");
++ return (CMD_PARSE_ERROR);
+ }
+
- identifier = NULL;
- status = parse_string(&buffer, &identifier);
- if (status != 0) {
- print_to_socket(fh, "-1 Cannot parse identifier.\n");
- return (-1);
- }
- assert(identifier != NULL);
++ identifier = argv[0];
+
- /* parse_identifier() modifies its first argument,
- * returning pointers into it */
++ /* parse_identifier() modifies its first argument, returning pointers into
++ * it; retain the old value for later. */
+ identifier_copy = sstrdup(identifier);
+
- status = parse_identifier(identifier_copy, &hostname, &plugin,
- &plugin_instance, &type, &type_instance);
++ status =
++ parse_identifier(identifier, &hostname, &plugin, &plugin_instance, &type,
++ &type_instance, opts->identifier_default_host);
+ if (status != 0) {
- DEBUG("handle_putval: Cannot parse identifier `%s'.", identifier);
- print_to_socket(fh, "-1 Cannot parse identifier `%s'.\n", identifier);
++ DEBUG("cmd_handle_putval: Cannot parse identifier `%s'.", identifier_copy);
++ cmd_error(CMD_PARSE_ERROR, err, "Cannot parse identifier `%s'.",
++ identifier_copy);
+ sfree(identifier_copy);
- return (-1);
++ return (CMD_PARSE_ERROR);
+ }
+
+ if ((strlen(hostname) >= sizeof(vl.host)) ||
+ (strlen(plugin) >= sizeof(vl.plugin)) ||
+ ((plugin_instance != NULL) &&
+ (strlen(plugin_instance) >= sizeof(vl.plugin_instance))) ||
+ ((type_instance != NULL) &&
+ (strlen(type_instance) >= sizeof(vl.type_instance)))) {
- print_to_socket(fh, "-1 Identifier too long.\n");
++ cmd_error(CMD_PARSE_ERROR, err, "Identifier too long.");
+ sfree(identifier_copy);
- return (-1);
++ return (CMD_PARSE_ERROR);
+ }
+
+ sstrncpy(vl.host, hostname, sizeof(vl.host));
+ sstrncpy(vl.plugin, plugin, sizeof(vl.plugin));
+ sstrncpy(vl.type, type, sizeof(vl.type));
+ if (plugin_instance != NULL)
+ sstrncpy(vl.plugin_instance, plugin_instance, sizeof(vl.plugin_instance));
+ if (type_instance != NULL)
+ sstrncpy(vl.type_instance, type_instance, sizeof(vl.type_instance));
+
+ ds = plugin_get_ds(type);
+ if (ds == NULL) {
- print_to_socket(fh, "-1 Type `%s' isn't defined.\n", type);
++ cmd_error(CMD_PARSE_ERROR, err, "1 Type `%s' isn't defined.", type);
+ sfree(identifier_copy);
- return (-1);
++ return (CMD_PARSE_ERROR);
+ }
+
- /* Free identifier_copy */
+ hostname = NULL;
+ plugin = NULL;
+ plugin_instance = NULL;
+ type = NULL;
+ type_instance = NULL;
- sfree(identifier_copy);
+
+ vl.values_len = ds->ds_num;
+ vl.values = malloc(vl.values_len * sizeof(*vl.values));
+ if (vl.values == NULL) {
- print_to_socket(fh, "-1 malloc failed.\n");
- return (-1);
++ cmd_error(CMD_ERROR, err, "malloc failed.");
++ sfree(identifier_copy);
++ return (CMD_ERROR);
++ }
++
++ ret_putval->raw_identifier = identifier_copy;
++ if (ret_putval->raw_identifier == NULL) {
++ cmd_error(CMD_ERROR, err, "malloc failed.");
++ cmd_destroy_putval(ret_putval);
++ sfree(vl.values);
++ return (CMD_ERROR);
+ }
+
- /* All the remaining fields are part of the optionlist. */
- values_submitted = 0;
- while (*buffer != 0) {
- char *string = NULL;
++ /* All the remaining fields are part of the option list. */
++ result = CMD_OK;
++ for (size_t i = 1; i < argc; ++i) {
++ value_list_t *tmp;
++
++ char *key = NULL;
+ char *value = NULL;
+
- status = parse_option(&buffer, &string, &value);
- if (status < 0) {
- /* parse_option failed, buffer has been modified.
- * => we need to abort */
- print_to_socket(fh, "-1 Misformatted option.\n");
- sfree(vl.values);
- return (-1);
- } else if (status == 0) {
- assert(string != NULL);
++ status = cmd_parse_option(argv[i], &key, &value, err);
++ if (status == CMD_OK) {
++ assert(key != NULL);
+ assert(value != NULL);
- set_option(&vl, string, value);
++ set_option(&vl, key, value);
+ continue;
++ } else if (status != CMD_NO_OPTION) {
++ /* parse_option failed, buffer has been modified.
++ * => we need to abort */
++ result = status;
++ break;
+ }
- /* else: parse_option but buffer has not been modified. This is
- * the default if no `=' is found.. */
++ /* else: cmd_parse_option did not find an option; treat this as a
++ * value list. */
+
- status = parse_string(&buffer, &string);
++ status = parse_values(argv[i], &vl, ds);
+ if (status != 0) {
- print_to_socket(fh, "-1 Misformatted value.\n");
- sfree(vl.values);
- return (-1);
++ cmd_error(CMD_PARSE_ERROR, err, "Parsing the values string failed.");
++ result = CMD_PARSE_ERROR;
++ break;
+ }
- assert(string != NULL);
+
- status = parse_values(string, &vl, ds);
- if (status != 0) {
- print_to_socket(fh, "-1 Parsing the values string failed.\n");
- sfree(vl.values);
- return (-1);
++ tmp = (value_list_t *)realloc(ret_putval->vl, (ret_putval->vl_num + 1) *
++ sizeof(*ret_putval->vl));
++ if (tmp == NULL) {
++ cmd_error(CMD_ERROR, err, "realloc failed.");
++ cmd_destroy_putval(ret_putval);
++ result = CMD_ERROR;
++ break;
+ }
+
- plugin_dispatch_values(&vl);
- values_submitted++;
++ ret_putval->vl = tmp;
++ ret_putval->vl_num++;
++ memcpy(&ret_putval->vl[ret_putval->vl_num - 1], &vl, sizeof(vl));
+ } /* while (*buffer != 0) */
+ /* Done parsing the options. */
+
++ if (result != CMD_OK) {
++ if (ret_putval->vl_num == 0)
++ sfree(vl.values);
++ cmd_destroy_putval(ret_putval);
++ }
++
++ return (result);
+} /* cmd_status_t cmd_parse_putval */
+
- void cmd_destroy_putval (cmd_putval_t *putval)
- {
- if (putval == NULL)
- return;
-
- sfree (putval->raw_identifier);
-
- for (size_t i = 0; i < putval->vl_num; ++i)
- {
- if (i == 0) /* values is shared between all entries */
- sfree (putval->vl[i].values);
- meta_data_destroy (putval->vl[i].meta);
- putval->vl[i].meta = NULL;
- }
- sfree (putval->vl);
- putval->vl = NULL;
- putval->vl_num = 0;
++void cmd_destroy_putval(cmd_putval_t *putval) {
++ if (putval == NULL)
++ return;
++
++ sfree(putval->raw_identifier);
++
++ for (size_t i = 0; i < putval->vl_num; ++i) {
++ if (i == 0) /* values is shared between all entries */
++ sfree(putval->vl[i].values);
++ meta_data_destroy(putval->vl[i].meta);
++ putval->vl[i].meta = NULL;
++ }
++ sfree(putval->vl);
++ putval->vl = NULL;
++ putval->vl_num = 0;
+} /* void cmd_destroy_putval */
+
- cmd_status_t cmd_handle_putval (FILE *fh, char *buffer)
- {
- cmd_error_handler_t err = { cmd_error_fh, fh };
- cmd_t cmd;
++cmd_status_t cmd_handle_putval(FILE *fh, char *buffer) {
++ cmd_error_handler_t err = {cmd_error_fh, fh};
++ cmd_t cmd;
+
- int status;
++ int status;
+
- DEBUG ("utils_cmd_putval: cmd_handle_putval (fh = %p, buffer = %s);",
- (void *) fh, buffer);
++ DEBUG("utils_cmd_putval: cmd_handle_putval (fh = %p, buffer = %s);",
++ (void *)fh, buffer);
+
- if ((status = cmd_parse (buffer, &cmd, NULL, &err)) != CMD_OK)
- return (status);
- if (cmd.type != CMD_PUTVAL)
- {
- cmd_error (CMD_UNKNOWN_COMMAND, &err, "Unexpected command: `%s'.",
- CMD_TO_STRING (cmd.type));
- cmd_destroy (&cmd);
- return (CMD_UNKNOWN_COMMAND);
- }
++ if ((status = cmd_parse(buffer, &cmd, NULL, &err)) != CMD_OK)
++ return (status);
++ if (cmd.type != CMD_PUTVAL) {
++ cmd_error(CMD_UNKNOWN_COMMAND, &err, "Unexpected command: `%s'.",
++ CMD_TO_STRING(cmd.type));
++ cmd_destroy(&cmd);
++ return (CMD_UNKNOWN_COMMAND);
++ }
+
- for (size_t i = 0; i < cmd.cmd.putval.vl_num; ++i)
- plugin_dispatch_values (&cmd.cmd.putval.vl[i]);
++ for (size_t i = 0; i < cmd.cmd.putval.vl_num; ++i)
++ plugin_dispatch_values(&cmd.cmd.putval.vl[i]);
+
- if (fh != stdout)
- cmd_error (CMD_OK, &err, "Success: %i %s been dispatched.",
- (int)cmd.cmd.putval.vl_num,
- (cmd.cmd.putval.vl_num == 1) ? "value has" : "values have");
+ if (fh != stdout)
- print_to_socket(fh, "0 Success: %i %s been dispatched.\n", values_submitted,
- (values_submitted == 1) ? "value has" : "values have");
++ cmd_error(CMD_OK, &err, "Success: %i %s been dispatched.",
++ (int)cmd.cmd.putval.vl_num,
++ (cmd.cmd.putval.vl_num == 1) ? "value has" : "values have");
- cmd_destroy (&cmd);
- return (CMD_OK);
- sfree(vl.values);
- return (0);
-} /* int handle_putval */
++ cmd_destroy(&cmd);
++ return (CMD_OK);
+} /* int cmd_handle_putval */
- int cmd_create_putval (char *ret, size_t ret_len, /* {{{ */
- const data_set_t *ds, const value_list_t *vl)
- {
- char buffer_ident[6 * DATA_MAX_NAME_LEN];
- char buffer_values[1024];
- int status;
-
- status = FORMAT_VL (buffer_ident, sizeof (buffer_ident), vl);
- if (status != 0)
- return (status);
- escape_string (buffer_ident, sizeof (buffer_ident));
-
- status = format_values (buffer_values, sizeof (buffer_values),
- ds, vl, /* store rates = */ 0);
- if (status != 0)
- return (status);
- escape_string (buffer_values, sizeof (buffer_values));
-
- ssnprintf (ret, ret_len,
- "PUTVAL %s interval=%.3f %s",
- buffer_ident,
- (vl->interval > 0)
- ? CDTIME_T_TO_DOUBLE (vl->interval)
- : CDTIME_T_TO_DOUBLE (plugin_get_interval ()),
- buffer_values);
-
- return (0);
-int create_putval(char *ret, size_t ret_len, /* {{{ */
- const data_set_t *ds, const value_list_t *vl) {
++int cmd_create_putval(char *ret, size_t ret_len, /* {{{ */
++ const data_set_t *ds, const value_list_t *vl) {
+ char buffer_ident[6 * DATA_MAX_NAME_LEN];
+ char buffer_values[1024];
+ int status;
+
+ status = FORMAT_VL(buffer_ident, sizeof(buffer_ident), vl);
+ if (status != 0)
+ return (status);
+ escape_string(buffer_ident, sizeof(buffer_ident));
+
+ status = format_values(buffer_values, sizeof(buffer_values), ds, vl,
+ /* store rates = */ 0);
+ if (status != 0)
+ return (status);
+ escape_string(buffer_values, sizeof(buffer_values));
+
+ ssnprintf(ret, ret_len, "PUTVAL %s interval=%.3f %s", buffer_ident,
+ (vl->interval > 0) ? CDTIME_T_TO_DOUBLE(vl->interval)
+ : CDTIME_T_TO_DOUBLE(plugin_get_interval()),
+ buffer_values);
+
+ return (0);
-} /* }}} int create_putval */
+} /* }}} int cmd_create_putval */
#include <stdio.h>
#include "plugin.h"
+#include "utils_cmds.h"
- cmd_status_t cmd_parse_putval (size_t argc, char **argv,
- cmd_putval_t *ret_putval, const cmd_options_t *opts,
- cmd_error_handler_t *err);
-int handle_putval(FILE *fh, char *buffer);
++cmd_status_t cmd_parse_putval(size_t argc, char **argv,
++ cmd_putval_t *ret_putval,
++ const cmd_options_t *opts,
++ cmd_error_handler_t *err);
- cmd_status_t cmd_handle_putval (FILE *fh, char *buffer);
-int create_putval(char *ret, size_t ret_len, const data_set_t *ds,
- const value_list_t *vl);
++cmd_status_t cmd_handle_putval(FILE *fh, char *buffer);
+
- void cmd_destroy_putval (cmd_putval_t *putval);
++void cmd_destroy_putval(cmd_putval_t *putval);
+
- int cmd_create_putval (char *ret, size_t ret_len,
- const data_set_t *ds, const value_list_t *vl);
++int cmd_create_putval(char *ret, size_t ret_len, const data_set_t *ds,
++ const value_list_t *vl);
#endif /* UTILS_CMD_PUTVAL_H */
#include "collectd.h"
- #include "plugin.h"
#include "common.h"
+ #include "plugin.h"
- #include "utils_format_graphite.h"
#include "utils_cache.h"
+ #include "utils_format_graphite.h"
#define GRAPHITE_FORBIDDEN " \t\"\\:!/()\n\r"
/* Utils functions to format data sets in graphite format.
* Largely taken from write_graphite.c as it remains the same formatting */
- static int gr_format_values (char *ret, size_t ret_len,
- int ds_num, const data_set_t *ds, const value_list_t *vl,
- gauge_t const *rates)
- {
- size_t offset = 0;
- int status;
-
- assert (0 == strcmp (ds->type, vl->type));
-
- memset (ret, 0, ret_len);
-
- #define BUFFER_ADD(...) do { \
- status = ssnprintf (ret + offset, ret_len - offset, \
- __VA_ARGS__); \
- if (status < 1) \
- { \
- return (-1); \
- } \
- else if (((size_t) status) >= (ret_len - offset)) \
- { \
- return (-1); \
- } \
- else \
- offset += ((size_t) status); \
- } while (0)
-
- if (ds->ds[ds_num].type == DS_TYPE_GAUGE)
- BUFFER_ADD (GAUGE_FORMAT, vl->values[ds_num].gauge);
- else if (rates != NULL)
- BUFFER_ADD ("%f", rates[ds_num]);
- else if (ds->ds[ds_num].type == DS_TYPE_COUNTER)
- BUFFER_ADD ("%llu", vl->values[ds_num].counter);
- else if (ds->ds[ds_num].type == DS_TYPE_DERIVE)
- BUFFER_ADD ("%"PRIi64, vl->values[ds_num].derive);
- else if (ds->ds[ds_num].type == DS_TYPE_ABSOLUTE)
- BUFFER_ADD ("%"PRIu64, vl->values[ds_num].absolute);
- else
- {
- ERROR ("gr_format_values plugin: Unknown data source type: %i",
- ds->ds[ds_num].type);
- return (-1);
- }
+ static int gr_format_values(char *ret, size_t ret_len, int ds_num,
+ const data_set_t *ds, const value_list_t *vl,
+ gauge_t const *rates) {
+ size_t offset = 0;
+ int status;
+
+ assert(0 == strcmp(ds->type, vl->type));
+
+ memset(ret, 0, ret_len);
+
+ #define BUFFER_ADD(...) \
+ do { \
+ status = ssnprintf(ret + offset, ret_len - offset, __VA_ARGS__); \
+ if (status < 1) { \
+ return (-1); \
+ } else if (((size_t)status) >= (ret_len - offset)) { \
+ return (-1); \
+ } else \
+ offset += ((size_t)status); \
+ } while (0)
+
+ if (ds->ds[ds_num].type == DS_TYPE_GAUGE)
+ BUFFER_ADD(GAUGE_FORMAT, vl->values[ds_num].gauge);
+ else if (rates != NULL)
+ BUFFER_ADD("%f", rates[ds_num]);
+ else if (ds->ds[ds_num].type == DS_TYPE_COUNTER)
+ BUFFER_ADD("%llu", vl->values[ds_num].counter);
+ else if (ds->ds[ds_num].type == DS_TYPE_DERIVE)
+ BUFFER_ADD("%" PRIi64, vl->values[ds_num].derive);
+ else if (ds->ds[ds_num].type == DS_TYPE_ABSOLUTE)
+ BUFFER_ADD("%" PRIu64, vl->values[ds_num].absolute);
+ else {
+ ERROR("gr_format_values plugin: Unknown data source type: %i",
+ ds->ds[ds_num].type);
+ return (-1);
+ }
#undef BUFFER_ADD
- return (0);
+ return (0);
}
- static void gr_copy_escape_part (char *dst, const char *src, size_t dst_len,
- char escape_char, _Bool preserve_separator)
- {
- memset (dst, 0, dst_len);
-
- if (src == NULL)
- return;
-
- for (size_t i = 0; i < dst_len; i++)
- {
- if (src[i] == 0)
- {
- dst[i] = 0;
- break;
- }
-
- if ((!preserve_separator && (src[i] == '.'))
- || isspace ((int) src[i])
- || iscntrl ((int) src[i]))
- dst[i] = escape_char;
- else
- dst[i] = src[i];
+ static void gr_copy_escape_part(char *dst, const char *src, size_t dst_len,
- char escape_char) {
++ char escape_char, _Bool preserve_separator) {
+ memset(dst, 0, dst_len);
+
+ if (src == NULL)
+ return;
+
+ for (size_t i = 0; i < dst_len; i++) {
+ if (src[i] == 0) {
+ dst[i] = 0;
+ break;
}
- if ((src[i] == '.') || isspace((int)src[i]) || iscntrl((int)src[i]))
+
++ if ((!preserve_separator && (src[i] == '.')) || isspace((int)src[i]) ||
++ iscntrl((int)src[i]))
+ dst[i] = escape_char;
+ else
+ dst[i] = src[i];
+ }
}
- static int gr_format_name (char *ret, int ret_len,
- value_list_t const *vl,
- char const *ds_name,
- char const *prefix,
- char const *postfix,
- char const escape_char,
- unsigned int flags)
- {
- char n_host[DATA_MAX_NAME_LEN];
- char n_plugin[DATA_MAX_NAME_LEN];
- char n_plugin_instance[DATA_MAX_NAME_LEN];
- char n_type[DATA_MAX_NAME_LEN];
- char n_type_instance[DATA_MAX_NAME_LEN];
-
- char tmp_plugin[2 * DATA_MAX_NAME_LEN + 1];
- char tmp_type[2 * DATA_MAX_NAME_LEN + 1];
-
- if (prefix == NULL)
- prefix = "";
-
- if (postfix == NULL)
- postfix = "";
-
- _Bool preserve_separator = (flags & GRAPHITE_PRESERVE_SEPARATOR) ? 1 : 0;
-
- gr_copy_escape_part (n_host, vl->host,
- sizeof (n_host), escape_char, preserve_separator);
- gr_copy_escape_part (n_plugin, vl->plugin,
- sizeof (n_plugin), escape_char, preserve_separator);
- gr_copy_escape_part (n_plugin_instance, vl->plugin_instance,
- sizeof (n_plugin_instance), escape_char, preserve_separator);
- gr_copy_escape_part (n_type, vl->type,
- sizeof (n_type), escape_char, preserve_separator);
- gr_copy_escape_part (n_type_instance, vl->type_instance,
- sizeof (n_type_instance), escape_char, preserve_separator);
-
- if (n_plugin_instance[0] != '\0')
- ssnprintf (tmp_plugin, sizeof (tmp_plugin), "%s%c%s",
- n_plugin,
- (flags & GRAPHITE_SEPARATE_INSTANCES) ? '.' : '-',
- n_plugin_instance);
+ static int gr_format_name(char *ret, int ret_len, value_list_t const *vl,
+ char const *ds_name, char const *prefix,
+ char const *postfix, char const escape_char,
+ unsigned int flags) {
+ char n_host[DATA_MAX_NAME_LEN];
+ char n_plugin[DATA_MAX_NAME_LEN];
+ char n_plugin_instance[DATA_MAX_NAME_LEN];
+ char n_type[DATA_MAX_NAME_LEN];
+ char n_type_instance[DATA_MAX_NAME_LEN];
+
+ char tmp_plugin[2 * DATA_MAX_NAME_LEN + 1];
+ char tmp_type[2 * DATA_MAX_NAME_LEN + 1];
+
+ if (prefix == NULL)
+ prefix = "";
+
+ if (postfix == NULL)
+ postfix = "";
+
- gr_copy_escape_part(n_host, vl->host, sizeof(n_host), escape_char);
- gr_copy_escape_part(n_plugin, vl->plugin, sizeof(n_plugin), escape_char);
++ _Bool preserve_separator = (flags & GRAPHITE_PRESERVE_SEPARATOR) ? 1 : 0;
++
++ gr_copy_escape_part(n_host, vl->host, sizeof(n_host), escape_char,
++ preserve_separator);
++ gr_copy_escape_part(n_plugin, vl->plugin, sizeof(n_plugin), escape_char,
++ preserve_separator);
+ gr_copy_escape_part(n_plugin_instance, vl->plugin_instance,
- sizeof(n_plugin_instance), escape_char);
- gr_copy_escape_part(n_type, vl->type, sizeof(n_type), escape_char);
++ sizeof(n_plugin_instance), escape_char,
++ preserve_separator);
++ gr_copy_escape_part(n_type, vl->type, sizeof(n_type), escape_char,
++ preserve_separator);
+ gr_copy_escape_part(n_type_instance, vl->type_instance,
- sizeof(n_type_instance), escape_char);
++ sizeof(n_type_instance), escape_char, preserve_separator);
+
+ if (n_plugin_instance[0] != '\0')
+ ssnprintf(tmp_plugin, sizeof(tmp_plugin), "%s%c%s", n_plugin,
+ (flags & GRAPHITE_SEPARATE_INSTANCES) ? '.' : '-',
+ n_plugin_instance);
+ else
+ sstrncpy(tmp_plugin, n_plugin, sizeof(tmp_plugin));
+
- if (n_type_instance[0] != '\0')
- ssnprintf(tmp_type, sizeof(tmp_type), "%s%c%s", n_type,
- (flags & GRAPHITE_SEPARATE_INSTANCES) ? '.' : '-',
- n_type_instance);
- else
++ if (n_type_instance[0] != '\0') {
++ if ((flags & GRAPHITE_DROP_DUPE_FIELDS) && strcmp(n_plugin, n_type) == 0)
++ sstrncpy(tmp_type, n_type_instance, sizeof(tmp_type));
+ else
- sstrncpy (tmp_plugin, n_plugin, sizeof (tmp_plugin));
-
- if (n_type_instance[0] != '\0')
- {
- if ((flags & GRAPHITE_DROP_DUPE_FIELDS) && strcmp(n_plugin, n_type) == 0)
- sstrncpy (tmp_type, n_type_instance, sizeof (tmp_type));
- else
- ssnprintf (tmp_type, sizeof (tmp_type), "%s%c%s",
- n_type,
++ ssnprintf(tmp_type, sizeof(tmp_type), "%s%c%s", n_type,
+ (flags & GRAPHITE_SEPARATE_INSTANCES) ? '.' : '-',
+ n_type_instance);
- }
- else
- sstrncpy (tmp_type, n_type, sizeof (tmp_type));
-
- /* Assert always_append_ds -> ds_name */
- assert (!(flags & GRAPHITE_ALWAYS_APPEND_DS) || (ds_name != NULL));
- if (ds_name != NULL)
- {
- if ((flags & GRAPHITE_DROP_DUPE_FIELDS) && strcmp(tmp_plugin, tmp_type) == 0)
- ssnprintf (ret, ret_len, "%s%s%s.%s.%s",
- prefix, n_host, postfix, tmp_plugin, ds_name);
- else
- ssnprintf (ret, ret_len, "%s%s%s.%s.%s.%s",
- prefix, n_host, postfix, tmp_plugin, tmp_type, ds_name);
- }
++ } else
+ sstrncpy(tmp_type, n_type, sizeof(tmp_type));
+
+ /* Assert always_append_ds -> ds_name */
+ assert(!(flags & GRAPHITE_ALWAYS_APPEND_DS) || (ds_name != NULL));
- if (ds_name != NULL)
- ssnprintf(ret, ret_len, "%s%s%s.%s.%s.%s", prefix, n_host, postfix,
- tmp_plugin, tmp_type, ds_name);
- else
++ if (ds_name != NULL) {
++ if ((flags & GRAPHITE_DROP_DUPE_FIELDS) &&
++ strcmp(tmp_plugin, tmp_type) == 0)
++ ssnprintf(ret, ret_len, "%s%s%s.%s.%s", prefix, n_host, postfix,
++ tmp_plugin, ds_name);
+ else
- ssnprintf (ret, ret_len, "%s%s%s.%s.%s",
- prefix, n_host, postfix, tmp_plugin, tmp_type);
++ ssnprintf(ret, ret_len, "%s%s%s.%s.%s.%s", prefix, n_host, postfix,
++ tmp_plugin, tmp_type, ds_name);
++ } else
+ ssnprintf(ret, ret_len, "%s%s%s.%s.%s", prefix, n_host, postfix, tmp_plugin,
+ tmp_type);
- return (0);
+ return (0);
}
- static void escape_graphite_string (char *buffer, char escape_char)
- {
- assert (strchr(GRAPHITE_FORBIDDEN, escape_char) == NULL);
+ static void escape_graphite_string(char *buffer, char escape_char) {
+ assert(strchr(GRAPHITE_FORBIDDEN, escape_char) == NULL);
- for (char *head = buffer + strcspn(buffer, GRAPHITE_FORBIDDEN);
- *head != '\0';
- head += strcspn(head, GRAPHITE_FORBIDDEN))
- *head = escape_char;
+ for (char *head = buffer + strcspn(buffer, GRAPHITE_FORBIDDEN); *head != '\0';
+ head += strcspn(head, GRAPHITE_FORBIDDEN))
+ *head = escape_char;
}
- int format_graphite (char *buffer, size_t buffer_size,
- data_set_t const *ds, value_list_t const *vl,
- char const *prefix, char const *postfix, char const escape_char,
- unsigned int flags)
- {
- int status = 0;
- int buffer_pos = 0;
-
- gauge_t *rates = NULL;
- if (flags & GRAPHITE_STORE_RATES)
- rates = uc_get_rate (ds, vl);
-
- for (size_t i = 0; i < ds->ds_num; i++)
- {
- char const *ds_name = NULL;
- char key[10*DATA_MAX_NAME_LEN];
- char values[512];
- size_t message_len;
- char message[1024];
-
- if ((flags & GRAPHITE_ALWAYS_APPEND_DS)
- || (ds->ds_num > 1))
- ds_name = ds->ds[i].name;
-
- /* Copy the identifier to `key' and escape it. */
- status = gr_format_name (key, sizeof (key), vl, ds_name,
- prefix, postfix, escape_char, flags);
- if (status != 0)
- {
- ERROR ("format_graphite: error with gr_format_name");
- sfree (rates);
- return (status);
- }
-
- escape_graphite_string (key, escape_char);
- /* Convert the values to an ASCII representation and put that into
- * `values'. */
- status = gr_format_values (values, sizeof (values), i, ds, vl, rates);
- if (status != 0)
- {
- ERROR ("format_graphite: error with gr_format_values");
- sfree (rates);
- return (status);
- }
-
- /* Compute the graphite command */
- message_len = (size_t) ssnprintf (message, sizeof (message),
- "%s %s %u\r\n",
- key,
- values,
- (unsigned int) CDTIME_T_TO_TIME_T (vl->time));
- if (message_len >= sizeof (message)) {
- ERROR ("format_graphite: message buffer too small: "
- "Need %zu bytes.", message_len + 1);
- sfree (rates);
- return (-ENOMEM);
- }
-
- /* Append it in case we got multiple data set */
- if ((buffer_pos + message_len) >= buffer_size)
- {
- ERROR ("format_graphite: target buffer too small");
- sfree (rates);
- return (-ENOMEM);
- }
- memcpy((void *) (buffer + buffer_pos), message, message_len);
- buffer_pos += message_len;
- buffer[buffer_pos] = '\0';
+ int format_graphite(char *buffer, size_t buffer_size, data_set_t const *ds,
+ value_list_t const *vl, char const *prefix,
+ char const *postfix, char const escape_char,
+ unsigned int flags) {
+ int status = 0;
+ int buffer_pos = 0;
+
+ gauge_t *rates = NULL;
+ if (flags & GRAPHITE_STORE_RATES)
+ rates = uc_get_rate(ds, vl);
+
+ for (size_t i = 0; i < ds->ds_num; i++) {
+ char const *ds_name = NULL;
+ char key[10 * DATA_MAX_NAME_LEN];
+ char values[512];
+ size_t message_len;
+ char message[1024];
+
+ if ((flags & GRAPHITE_ALWAYS_APPEND_DS) || (ds->ds_num > 1))
+ ds_name = ds->ds[i].name;
+
+ /* Copy the identifier to `key' and escape it. */
+ status = gr_format_name(key, sizeof(key), vl, ds_name, prefix, postfix,
+ escape_char, flags);
+ if (status != 0) {
+ ERROR("format_graphite: error with gr_format_name");
+ sfree(rates);
+ return (status);
+ }
+
+ escape_graphite_string(key, escape_char);
+ /* Convert the values to an ASCII representation and put that into
+ * `values'. */
+ status = gr_format_values(values, sizeof(values), i, ds, vl, rates);
+ if (status != 0) {
+ ERROR("format_graphite: error with gr_format_values");
+ sfree(rates);
+ return (status);
+ }
+
+ /* Compute the graphite command */
+ message_len =
+ (size_t)ssnprintf(message, sizeof(message), "%s %s %u\r\n", key, values,
+ (unsigned int)CDTIME_T_TO_TIME_T(vl->time));
+ if (message_len >= sizeof(message)) {
+ ERROR("format_graphite: message buffer too small: "
+ "Need %zu bytes.",
+ message_len + 1);
+ sfree(rates);
+ return (-ENOMEM);
+ }
+
+ /* Append it in case we got multiple data set */
+ if ((buffer_pos + message_len) >= buffer_size) {
+ ERROR("format_graphite: target buffer too small");
+ sfree(rates);
+ return (-ENOMEM);
}
- sfree (rates);
- return (status);
+ memcpy((void *)(buffer + buffer_pos), message, message_len);
+ buffer_pos += message_len;
+ buffer[buffer_pos] = '\0';
+ }
+ sfree(rates);
+ return (status);
} /* int format_graphite */
/* vim: set sw=2 sts=2 et fdm=marker : */
#include "plugin.h"
- #define GRAPHITE_STORE_RATES 0x01
+ #define GRAPHITE_STORE_RATES 0x01
#define GRAPHITE_SEPARATE_INSTANCES 0x02
- #define GRAPHITE_ALWAYS_APPEND_DS 0x04
- #define GRAPHITE_DROP_DUPE_FIELDS 0x08
+ #define GRAPHITE_ALWAYS_APPEND_DS 0x04
++#define GRAPHITE_DROP_DUPE_FIELDS 0x08
+#define GRAPHITE_PRESERVE_SEPARATOR 0x10
- int format_graphite (char *buffer,
- size_t buffer_size, const data_set_t *ds,
- const value_list_t *vl, const char *prefix,
- const char *postfix, const char escape_char,
- unsigned int flags);
+ int format_graphite(char *buffer, size_t buffer_size, const data_set_t *ds,
+ const value_list_t *vl, const char *prefix,
+ const char *postfix, const char escape_char,
+ unsigned int flags);
#endif /* UTILS_FORMAT_GRAPHITE_H */
#include "collectd.h"
+ #include "common.h"
#include "plugin.h"
#include "utils_latency.h"
- #include "common.h"
- #include <math.h>
#include <limits.h>
+ #include <math.h>
#ifndef LLONG_MAX
- # define LLONG_MAX 9223372036854775807LL
+ #define LLONG_MAX 9223372036854775807LL
#endif
-#ifndef HISTOGRAM_NUM_BINS
-#define HISTOGRAM_NUM_BINS 1000
-#endif
-
#ifndef HISTOGRAM_DEFAULT_BIN_WIDTH
/* 1048576 = 2^20 ^= 1/1024 s */
- # define HISTOGRAM_DEFAULT_BIN_WIDTH 1048576
+ #define HISTOGRAM_DEFAULT_BIN_WIDTH 1048576
#endif
- struct latency_counter_s
- {
+ struct latency_counter_s {
cdtime_t start_time;
cdtime_t sum;
* So, if the required bin width is 300, then new bin width will be 512 as it is
* the next nearest power of 2.
*/
- static void change_bin_width (latency_counter_t *lc, cdtime_t latency) /* {{{ */
+ static void change_bin_width(latency_counter_t *lc, cdtime_t latency) /* {{{ */
{
/* This function is called because the new value is above histogram's range.
* First find the required bin width:
* then get the next nearest power of 2
* newBinWidth = 2^(ceil(log2(requiredBinWidth)))
*/
- double required_bin_width = ((double) (latency + 1)) / ((double) HISTOGRAM_NUM_BINS);
- double required_bin_width_logbase2 = log (required_bin_width) / log (2.0);
- cdtime_t new_bin_width = (cdtime_t) (pow (2.0, ceil (required_bin_width_logbase2)) + .5);
+ double required_bin_width =
+ ((double)(latency + 1)) / ((double)HISTOGRAM_NUM_BINS);
+ double required_bin_width_logbase2 = log(required_bin_width) / log(2.0);
+ cdtime_t new_bin_width =
+ (cdtime_t)(pow(2.0, ceil(required_bin_width_logbase2)) + .5);
cdtime_t old_bin_width = lc->bin_width;
lc->bin_width = new_bin_width;
* old bin's count to new bin. */
if (lc->num > 0) // if the histogram has data then iterate else skip
{
- double width_change_ratio = ((double) old_bin_width) / ((double) new_bin_width);
-
- for (size_t i = 0; i < HISTOGRAM_NUM_BINS; i++)
- {
- size_t new_bin = (size_t) (((double) i) * width_change_ratio);
- if (i == new_bin)
- continue;
- assert (new_bin < i);
-
- lc->histogram[new_bin] += lc->histogram[i];
- lc->histogram[i] = 0;
- }
+ double width_change_ratio =
+ ((double)old_bin_width) / ((double)new_bin_width);
+
+ for (size_t i = 0; i < HISTOGRAM_NUM_BINS; i++) {
+ size_t new_bin = (size_t)(((double)i) * width_change_ratio);
+ if (i == new_bin)
+ continue;
+ assert(new_bin < i);
+
+ lc->histogram[new_bin] += lc->histogram[i];
+ lc->histogram[i] = 0;
+ }
}
DEBUG("utils_latency: change_bin_width: latency = %.3f; "
- "old_bin_width = %.3f; new_bin_width = %.3f;",
- CDTIME_T_TO_DOUBLE (latency),
- CDTIME_T_TO_DOUBLE (old_bin_width),
- CDTIME_T_TO_DOUBLE (new_bin_width));
+ "old_bin_width = %.3f; new_bin_width = %.3f;",
+ CDTIME_T_TO_DOUBLE(latency), CDTIME_T_TO_DOUBLE(old_bin_width),
+ CDTIME_T_TO_DOUBLE(new_bin_width));
} /* }}} void change_bin_width */
- latency_counter_t *latency_counter_create (void) /* {{{ */
+ latency_counter_t *latency_counter_create(void) /* {{{ */
{
latency_counter_t *lc;
- lc = calloc (1, sizeof (*lc));
+ lc = calloc(1, sizeof(*lc));
if (lc == NULL)
return (NULL);
lc->bin_width = HISTOGRAM_DEFAULT_BIN_WIDTH;
- latency_counter_reset (lc);
+ latency_counter_reset(lc);
return (lc);
} /* }}} latency_counter_t *latency_counter_create */
- void latency_counter_destroy (latency_counter_t *lc) /* {{{ */
+ void latency_counter_destroy(latency_counter_t *lc) /* {{{ */
{
- sfree (lc);
+ sfree(lc);
} /* }}} void latency_counter_destroy */
- void latency_counter_add (latency_counter_t *lc, cdtime_t latency) /* {{{ */
+ void latency_counter_add(latency_counter_t *lc, cdtime_t latency) /* {{{ */
{
cdtime_t bin;
- if ((lc == NULL) || (latency == 0) || (latency > ((cdtime_t) LLONG_MAX)))
+ if ((lc == NULL) || (latency == 0) || (latency > ((cdtime_t)LLONG_MAX)))
return;
lc->sum += latency;
if (lc->max < latency)
lc->max = latency;
- /* A latency of _exactly_ 1.0 ms should be stored in the buffer 0, so
+ /* A latency of _exactly_ 1.0 ms is stored in the buffer 0, so
* subtract one from the cdtime_t value so that exactly 1.0 ms get sorted
* accordingly. */
bin = (latency - 1) / lc->bin_width;
- if (bin >= HISTOGRAM_NUM_BINS)
- {
- change_bin_width (lc, latency);
- bin = (latency - 1) / lc->bin_width;
- if (bin >= HISTOGRAM_NUM_BINS)
- {
- ERROR ("utils_latency: latency_counter_add: Invalid bin: %"PRIu64, bin);
- return;
- }
+ if (bin >= HISTOGRAM_NUM_BINS) {
+ change_bin_width(lc, latency);
+ bin = (latency - 1) / lc->bin_width;
+ if (bin >= HISTOGRAM_NUM_BINS) {
+ ERROR("utils_latency: latency_counter_add: Invalid bin: %" PRIu64, bin);
+ return;
+ }
}
lc->histogram[bin]++;
} /* }}} void latency_counter_add */
- void latency_counter_reset (latency_counter_t *lc) /* {{{ */
+ void latency_counter_reset(latency_counter_t *lc) /* {{{ */
{
if (lc == NULL)
return;
Value of 4 is selected to reduce frequent changes of bin width.
*/
#define REDUCE_THRESHOLD 4
- if ((lc->num > 0) && (lc->bin_width >= HISTOGRAM_DEFAULT_BIN_WIDTH * 2)
- && (max_bin < HISTOGRAM_NUM_BINS / REDUCE_THRESHOLD))
- {
+ if ((lc->num > 0) && (lc->bin_width >= HISTOGRAM_DEFAULT_BIN_WIDTH * 2) &&
+ (max_bin < HISTOGRAM_NUM_BINS / REDUCE_THRESHOLD)) {
/* new bin width will be the previous power of 2 */
bin_width = bin_width / 2;
DEBUG("utils_latency: latency_counter_reset: max_latency = %.3f; "
- "max_bin = %"PRIu64"; old_bin_width = %.3f; new_bin_width = %.3f;",
- CDTIME_T_TO_DOUBLE (lc->max),
- max_bin,
- CDTIME_T_TO_DOUBLE (lc->bin_width),
- CDTIME_T_TO_DOUBLE (bin_width));
+ "max_bin = %" PRIu64 "; old_bin_width = %.3f; new_bin_width = %.3f;",
+ CDTIME_T_TO_DOUBLE(lc->max), max_bin,
+ CDTIME_T_TO_DOUBLE(lc->bin_width), CDTIME_T_TO_DOUBLE(bin_width));
}
- memset (lc, 0, sizeof (*lc));
+ memset(lc, 0, sizeof(*lc));
/* preserve bin width */
lc->bin_width = bin_width;
- lc->start_time = cdtime ();
+ lc->start_time = cdtime();
} /* }}} void latency_counter_reset */
- cdtime_t latency_counter_get_min (latency_counter_t *lc) /* {{{ */
+ cdtime_t latency_counter_get_min(latency_counter_t *lc) /* {{{ */
{
if (lc == NULL)
return (0);
return (lc->min);
} /* }}} cdtime_t latency_counter_get_min */
- cdtime_t latency_counter_get_max (latency_counter_t *lc) /* {{{ */
+ cdtime_t latency_counter_get_max(latency_counter_t *lc) /* {{{ */
{
if (lc == NULL)
return (0);
return (lc->max);
} /* }}} cdtime_t latency_counter_get_max */
- cdtime_t latency_counter_get_sum (latency_counter_t *lc) /* {{{ */
+ cdtime_t latency_counter_get_sum(latency_counter_t *lc) /* {{{ */
{
if (lc == NULL)
return (0);
return (lc->sum);
} /* }}} cdtime_t latency_counter_get_sum */
- size_t latency_counter_get_num (latency_counter_t *lc) /* {{{ */
+ size_t latency_counter_get_num(latency_counter_t *lc) /* {{{ */
{
if (lc == NULL)
return (0);
return (lc->num);
} /* }}} size_t latency_counter_get_num */
- cdtime_t latency_counter_get_average (latency_counter_t *lc) /* {{{ */
+ cdtime_t latency_counter_get_average(latency_counter_t *lc) /* {{{ */
{
double average;
if ((lc == NULL) || (lc->num == 0))
return (0);
- average = CDTIME_T_TO_DOUBLE (lc->sum) / ((double) lc->num);
- return (DOUBLE_TO_CDTIME_T (average));
+ average = CDTIME_T_TO_DOUBLE(lc->sum) / ((double)lc->num);
+ return (DOUBLE_TO_CDTIME_T(average));
} /* }}} cdtime_t latency_counter_get_average */
- cdtime_t latency_counter_get_percentile (latency_counter_t *lc, /* {{{ */
- double percent)
- {
+ cdtime_t latency_counter_get_percentile(latency_counter_t *lc, /* {{{ */
+ double percent) {
double percent_upper;
double percent_lower;
double p;
percent_upper = 0.0;
percent_lower = 0.0;
sum = 0;
- for (i = 0; i < HISTOGRAM_NUM_BINS; i++)
- {
+ for (i = 0; i < HISTOGRAM_NUM_BINS; i++) {
percent_lower = percent_upper;
sum += lc->histogram[i];
if (sum == 0)
percent_upper = 0.0;
else
- percent_upper = 100.0 * ((double) sum) / ((double) lc->num);
+ percent_upper = 100.0 * ((double)sum) / ((double)lc->num);
if (percent_upper >= percent)
break;
if (i >= HISTOGRAM_NUM_BINS)
return (0);
- assert (percent_upper >= percent);
- assert (percent_lower < percent);
+ assert(percent_upper >= percent);
+ assert(percent_lower < percent);
if (i == 0)
return (lc->bin_width);
- latency_lower = ((cdtime_t) i) * lc->bin_width;
+ latency_lower = ((cdtime_t)i) * lc->bin_width;
p = (percent - percent_lower) / (percent_upper - percent_lower);
- latency_interpolated = latency_lower
- + DOUBLE_TO_CDTIME_T (p * CDTIME_T_TO_DOUBLE (lc->bin_width));
+ latency_interpolated =
+ latency_lower + DOUBLE_TO_CDTIME_T(p * CDTIME_T_TO_DOUBLE(lc->bin_width));
- DEBUG ("latency_counter_get_percentile: latency_interpolated = %.3f",
- CDTIME_T_TO_DOUBLE (latency_interpolated));
+ DEBUG("latency_counter_get_percentile: latency_interpolated = %.3f",
+ CDTIME_T_TO_DOUBLE(latency_interpolated));
return (latency_interpolated);
} /* }}} cdtime_t latency_counter_get_percentile */
+double latency_counter_get_rate(const latency_counter_t *lc, /* {{{ */
+ cdtime_t lower, cdtime_t upper,
+ const cdtime_t now) {
+ if ((lc == NULL) || (lc->num == 0))
+ return (NAN);
+
+ if (upper && (upper < lower))
+ return (NAN);
+ if (lower == upper)
+ return (0);
+
+ /* Buckets have an exclusive lower bound and an inclusive upper bound. That
+ * means that the first bucket, index 0, represents (0-bin_width]. That means
+ * that latency==bin_width needs to result in bin=0, that's why we need to
+ * subtract one before dividing by bin_width. */
+ cdtime_t lower_bin = 0;
+ if (lower)
+ /* lower is *exclusive* => determine bucket for lower+1 */
+ lower_bin = ((lower + 1) - 1) / lc->bin_width;
+
+ /* lower is greater than the longest latency observed => rate is zero. */
+ if (lower_bin >= HISTOGRAM_NUM_BINS)
+ return (0);
+
+ cdtime_t upper_bin = HISTOGRAM_NUM_BINS - 1;
+ if (upper)
+ upper_bin = (upper - 1) / lc->bin_width;
+
+ if (upper_bin >= HISTOGRAM_NUM_BINS) {
+ upper_bin = HISTOGRAM_NUM_BINS - 1;
+ upper = 0;
+ }
+
+ double sum = 0;
+ for (size_t i = lower_bin; i <= upper_bin; i++)
+ sum += lc->histogram[i];
+
+ if (lower) {
+ /* Approximate ratio of requests in lower_bin, that fall between
+ * lower_bin_boundary and lower. This ratio is then subtracted from sum to
+ * increase accuracy. */
+ cdtime_t lower_bin_boundary = lower_bin * lc->bin_width;
+ assert(lower >= lower_bin_boundary);
+ double lower_ratio =
+ (double)(lower - lower_bin_boundary) / ((double)lc->bin_width);
+ sum -= lower_ratio * lc->histogram[lower_bin];
+ }
+
+ if (upper) {
+ /* As above: approximate ratio of requests in upper_bin, that fall between
+ * upper and upper_bin_boundary. */
+ cdtime_t upper_bin_boundary = (upper_bin + 1) * lc->bin_width;
+ assert(upper <= upper_bin_boundary);
+ double ratio = (double)(upper_bin_boundary - upper) / (double)lc->bin_width;
+ sum -= ratio * lc->histogram[upper_bin];
+ }
+
+ return sum / (CDTIME_T_TO_DOUBLE(now - lc->start_time));
+} /* }}} double latency_counter_get_rate */
+
/* vim: set sw=2 sts=2 et fdm=marker : */
#include "utils_time.h"
- # define HISTOGRAM_NUM_BINS 1000
+#ifndef HISTOGRAM_NUM_BINS
++#define HISTOGRAM_NUM_BINS 1000
+#endif
+
struct latency_counter_s;
typedef struct latency_counter_s latency_counter_t;
- latency_counter_t *latency_counter_create (void);
- void latency_counter_destroy (latency_counter_t *lc);
+ latency_counter_t *latency_counter_create(void);
+ void latency_counter_destroy(latency_counter_t *lc);
- void latency_counter_add (latency_counter_t *lc, cdtime_t latency);
- void latency_counter_reset (latency_counter_t *lc);
+ void latency_counter_add(latency_counter_t *lc, cdtime_t latency);
+ void latency_counter_reset(latency_counter_t *lc);
- cdtime_t latency_counter_get_min (latency_counter_t *lc);
- cdtime_t latency_counter_get_max (latency_counter_t *lc);
- cdtime_t latency_counter_get_sum (latency_counter_t *lc);
- size_t latency_counter_get_num (latency_counter_t *lc);
- cdtime_t latency_counter_get_average (latency_counter_t *lc);
- cdtime_t latency_counter_get_percentile (latency_counter_t *lc,
- double percent);
+ cdtime_t latency_counter_get_min(latency_counter_t *lc);
+ cdtime_t latency_counter_get_max(latency_counter_t *lc);
+ cdtime_t latency_counter_get_sum(latency_counter_t *lc);
+ size_t latency_counter_get_num(latency_counter_t *lc);
+ cdtime_t latency_counter_get_average(latency_counter_t *lc);
+ cdtime_t latency_counter_get_percentile(latency_counter_t *lc, double percent);
- double latency_counter_get_rate (const latency_counter_t *lc,
- cdtime_t lower, cdtime_t upper, const cdtime_t now);
+/*
+ * NAME
+ * latency_counter_get_rate(counter,lower,upper,now)
+ *
+ * DESCRIPTION
+ * Calculates rate of latency values fall within requested interval.
+ * Interval specified as (lower,upper], i.e. the lower boundary is exclusive,
+ * the upper boundary is inclusive.
+ * When lower is zero, then the interval is (0, upper].
+ * When upper is zero, then the interval is (lower, infinity).
+ */
++double latency_counter_get_rate(const latency_counter_t *lc, cdtime_t lower,
++ cdtime_t upper, const cdtime_t now);
+
/* vim: set sw=2 sts=2 et : */
* Florian octo Forster <octo at collectd.org>
*/
-#define DBL_PRECISION 1e-9
+#define DBL_PRECISION 1e-6
#include "common.h" /* for STATIC_ARRAY_SIZE */
#include "collectd.h"
#include "testing.h"
- #include "utils_time.h"
#include "utils_latency.h"
+ #include "utils_time.h"
- DEF_TEST(simple)
- {
+ DEF_TEST(simple) {
struct {
double val;
double min;
double sum;
double avg;
} cases[] = {
- /* val min max sum avg */
- {0.5, 0.5, 0.5, 0.5, 0.5},
- {0.3, 0.3, 0.5, 0.8, 0.4},
- {0.7, 0.3, 0.7, 1.5, 0.5},
- {2.5, 0.3, 2.5, 4.0, 1.0},
- { 99, 0.3, 99, 103, 20.6},
- /* { -1, 0.3, 99, 103, 20.6}, see issue #1139 */
+ /* val min max sum avg */
+ {0.5, 0.5, 0.5, 0.5, 0.5}, {0.3, 0.3, 0.5, 0.8, 0.4},
+ {0.7, 0.3, 0.7, 1.5, 0.5}, {2.5, 0.3, 2.5, 4.0, 1.0},
+ {99, 0.3, 99, 103, 20.6},
+ /* { -1, 0.3, 99, 103, 20.6}, see issue #1139 */
};
latency_counter_t *l;
- CHECK_NOT_NULL (l = latency_counter_create ());
+ CHECK_NOT_NULL(l = latency_counter_create());
- for (size_t i = 0; i < STATIC_ARRAY_SIZE (cases); i++) {
- printf ("# case %zu: DOUBLE_TO_CDTIME_T(%g) = %"PRIu64"\n",
- i, cases[i].val, DOUBLE_TO_CDTIME_T (cases[i].val));
- latency_counter_add (l, DOUBLE_TO_CDTIME_T (cases[i].val));
-
- EXPECT_EQ_DOUBLE (cases[i].min, CDTIME_T_TO_DOUBLE (latency_counter_get_min (l)));
- EXPECT_EQ_DOUBLE (cases[i].max, CDTIME_T_TO_DOUBLE (latency_counter_get_max (l)));
- EXPECT_EQ_DOUBLE (cases[i].sum, CDTIME_T_TO_DOUBLE (latency_counter_get_sum (l)));
- EXPECT_EQ_DOUBLE (cases[i].avg, CDTIME_T_TO_DOUBLE (latency_counter_get_average (l)));
+ for (size_t i = 0; i < STATIC_ARRAY_SIZE(cases); i++) {
+ printf("# case %zu: DOUBLE_TO_CDTIME_T(%g) = %" PRIu64 "\n", i,
+ cases[i].val, DOUBLE_TO_CDTIME_T(cases[i].val));
+ latency_counter_add(l, DOUBLE_TO_CDTIME_T(cases[i].val));
+
+ EXPECT_EQ_DOUBLE(cases[i].min,
+ CDTIME_T_TO_DOUBLE(latency_counter_get_min(l)));
+ EXPECT_EQ_DOUBLE(cases[i].max,
+ CDTIME_T_TO_DOUBLE(latency_counter_get_max(l)));
+ EXPECT_EQ_DOUBLE(cases[i].sum,
+ CDTIME_T_TO_DOUBLE(latency_counter_get_sum(l)));
+ EXPECT_EQ_DOUBLE(cases[i].avg,
+ CDTIME_T_TO_DOUBLE(latency_counter_get_average(l)));
}
- latency_counter_destroy (l);
+ latency_counter_destroy(l);
return 0;
}
- DEF_TEST(percentile)
- {
+ DEF_TEST(percentile) {
latency_counter_t *l;
- CHECK_NOT_NULL (l = latency_counter_create ());
+ CHECK_NOT_NULL(l = latency_counter_create());
for (size_t i = 0; i < 100; i++) {
- latency_counter_add (l, TIME_T_TO_CDTIME_T (((time_t) i) + 1));
+ latency_counter_add(l, TIME_T_TO_CDTIME_T(((time_t)i) + 1));
}
- EXPECT_EQ_DOUBLE ( 1.0, CDTIME_T_TO_DOUBLE (latency_counter_get_min (l)));
- EXPECT_EQ_DOUBLE (100.0, CDTIME_T_TO_DOUBLE (latency_counter_get_max (l)));
- EXPECT_EQ_DOUBLE (100.0 * 101.0 / 2.0, CDTIME_T_TO_DOUBLE (latency_counter_get_sum (l)));
- EXPECT_EQ_DOUBLE ( 50.5, CDTIME_T_TO_DOUBLE (latency_counter_get_average (l)));
-
- EXPECT_EQ_DOUBLE (50.0, CDTIME_T_TO_DOUBLE (latency_counter_get_percentile (l, 50.0)));
- EXPECT_EQ_DOUBLE (80.0, CDTIME_T_TO_DOUBLE (latency_counter_get_percentile (l, 80.0)));
- EXPECT_EQ_DOUBLE (95.0, CDTIME_T_TO_DOUBLE (latency_counter_get_percentile (l, 95.0)));
- EXPECT_EQ_DOUBLE (99.0, CDTIME_T_TO_DOUBLE (latency_counter_get_percentile (l, 99.0)));
-
- CHECK_ZERO (latency_counter_get_percentile (l, -1.0));
- CHECK_ZERO (latency_counter_get_percentile (l, 101.0));
-
- latency_counter_destroy (l);
+ EXPECT_EQ_DOUBLE(1.0, CDTIME_T_TO_DOUBLE(latency_counter_get_min(l)));
+ EXPECT_EQ_DOUBLE(100.0, CDTIME_T_TO_DOUBLE(latency_counter_get_max(l)));
+ EXPECT_EQ_DOUBLE(100.0 * 101.0 / 2.0,
+ CDTIME_T_TO_DOUBLE(latency_counter_get_sum(l)));
+ EXPECT_EQ_DOUBLE(50.5, CDTIME_T_TO_DOUBLE(latency_counter_get_average(l)));
+
+ EXPECT_EQ_DOUBLE(50.0,
+ CDTIME_T_TO_DOUBLE(latency_counter_get_percentile(l, 50.0)));
+ EXPECT_EQ_DOUBLE(80.0,
+ CDTIME_T_TO_DOUBLE(latency_counter_get_percentile(l, 80.0)));
+ EXPECT_EQ_DOUBLE(95.0,
+ CDTIME_T_TO_DOUBLE(latency_counter_get_percentile(l, 95.0)));
+ EXPECT_EQ_DOUBLE(99.0,
+ CDTIME_T_TO_DOUBLE(latency_counter_get_percentile(l, 99.0)));
+
+ CHECK_ZERO(latency_counter_get_percentile(l, -1.0));
+ CHECK_ZERO(latency_counter_get_percentile(l, 101.0));
+
+ latency_counter_destroy(l);
return 0;
}
- DEF_TEST (get_rate) {
++DEF_TEST(get_rate) {
+ /* We re-declare the struct here so we can inspect its content. */
+ struct {
+ cdtime_t start_time;
+ cdtime_t sum;
+ size_t num;
+ cdtime_t min;
+ cdtime_t max;
+ cdtime_t bin_width;
+ int histogram[HISTOGRAM_NUM_BINS];
- } *peek;
++ } * peek;
+ latency_counter_t *l;
+
- CHECK_NOT_NULL (l = latency_counter_create ());
- peek = (void *) l;
++ CHECK_NOT_NULL(l = latency_counter_create());
++ peek = (void *)l;
+
+ for (time_t i = 1; i <= 125; i++) {
- latency_counter_add (l, TIME_T_TO_CDTIME_T(i));
++ latency_counter_add(l, TIME_T_TO_CDTIME_T(i));
+ }
+
+ /* We expect a bucket width of 125ms. */
- EXPECT_EQ_UINT64 (DOUBLE_TO_CDTIME_T(0.125), peek->bin_width);
++ EXPECT_EQ_UINT64(DOUBLE_TO_CDTIME_T(0.125), peek->bin_width);
+
+ struct {
+ size_t index;
+ int want;
+ } bucket_cases[] = {
- { 0, 0}, /* (0.000-0.125] */
- { 1, 0}, /* (0.125-0.250] */
- { 2, 0}, /* (0.250-0.375] */
- { 3, 0}, /* (0.375-0.500] */
- { 4, 0}, /* (0.500-0.625] */
- { 5, 0}, /* (0.625-0.750] */
- { 6, 0}, /* (0.750-0.875] */
- { 7, 1}, /* (0.875-1.000] */
- { 8, 0}, /* (1.000-1.125] */
- { 9, 0}, /* (1.125-1.250] */
- {10, 0}, /* (1.250-1.375] */
- {11, 0}, /* (1.375-1.500] */
- {12, 0}, /* (1.500-1.625] */
- {13, 0}, /* (1.625-1.750] */
- {14, 0}, /* (1.750-1.875] */
- {15, 1}, /* (1.875-2.000] */
- {16, 0}, /* (2.000-2.125] */
++ {0, 0}, /* (0.000-0.125] */
++ {1, 0}, /* (0.125-0.250] */
++ {2, 0}, /* (0.250-0.375] */
++ {3, 0}, /* (0.375-0.500] */
++ {4, 0}, /* (0.500-0.625] */
++ {5, 0}, /* (0.625-0.750] */
++ {6, 0}, /* (0.750-0.875] */
++ {7, 1}, /* (0.875-1.000] */
++ {8, 0}, /* (1.000-1.125] */
++ {9, 0}, /* (1.125-1.250] */
++ {10, 0}, /* (1.250-1.375] */
++ {11, 0}, /* (1.375-1.500] */
++ {12, 0}, /* (1.500-1.625] */
++ {13, 0}, /* (1.625-1.750] */
++ {14, 0}, /* (1.750-1.875] */
++ {15, 1}, /* (1.875-2.000] */
++ {16, 0}, /* (2.000-2.125] */
+ };
+
+ for (size_t i = 0; i < STATIC_ARRAY_SIZE(bucket_cases); i++) {
+ size_t index = bucket_cases[i].index;
+ EXPECT_EQ_INT(bucket_cases[i].want, peek->histogram[index]);
+ }
+
+ struct {
+ cdtime_t lower_bound;
+ cdtime_t upper_bound;
+ double want;
+ } cases[] = {
- { // bucket 6 is zero
- DOUBLE_TO_CDTIME_T_STATIC(0.750),
- DOUBLE_TO_CDTIME_T_STATIC(0.875),
- 0.00,
- },
- { // bucket 7 contains the t=1 update
- DOUBLE_TO_CDTIME_T_STATIC(0.875),
- DOUBLE_TO_CDTIME_T_STATIC(1.000),
- 1.00,
- },
- { // range: bucket 7 - bucket 15; contains the t=1 and t=2 updates
- DOUBLE_TO_CDTIME_T_STATIC(0.875),
- DOUBLE_TO_CDTIME_T_STATIC(2.000),
- 2.00,
- },
- { // lower bucket is only partially applied
- DOUBLE_TO_CDTIME_T_STATIC(0.875 + (0.125 / 4)),
- DOUBLE_TO_CDTIME_T_STATIC(2.000),
- 1.75,
- },
- { // upper bucket is only partially applied
- DOUBLE_TO_CDTIME_T_STATIC(0.875),
- DOUBLE_TO_CDTIME_T_STATIC(2.000 - (0.125 / 4)),
- 1.75,
- },
- { // both buckets are only partially applied
- DOUBLE_TO_CDTIME_T_STATIC(0.875 + (0.125 / 4)),
- DOUBLE_TO_CDTIME_T_STATIC(2.000 - (0.125 / 4)),
- 1.50,
- },
- { // lower bound is unspecified
- 0,
- DOUBLE_TO_CDTIME_T_STATIC(2.000),
- 2.00,
- },
- { // upper bound is unspecified
- DOUBLE_TO_CDTIME_T_STATIC(125.000 - 0.125),
- 0,
- 1.00,
- },
- { // overflow test: upper >> longest latency
- DOUBLE_TO_CDTIME_T_STATIC(1.000),
- DOUBLE_TO_CDTIME_T_STATIC(999999),
- 124.00,
- },
- { // overflow test: lower > longest latency
- DOUBLE_TO_CDTIME_T_STATIC(130),
- 0,
- 0.00,
- },
- { // lower > upper => error
- DOUBLE_TO_CDTIME_T_STATIC(10),
- DOUBLE_TO_CDTIME_T_STATIC(9),
- NAN,
- },
- { // lower == upper => zero
- DOUBLE_TO_CDTIME_T_STATIC(9),
- DOUBLE_TO_CDTIME_T_STATIC(9),
- 0.00,
- },
++ {
++ // bucket 6 is zero
++ DOUBLE_TO_CDTIME_T_STATIC(0.750), DOUBLE_TO_CDTIME_T_STATIC(0.875),
++ 0.00,
++ },
++ {
++ // bucket 7 contains the t=1 update
++ DOUBLE_TO_CDTIME_T_STATIC(0.875), DOUBLE_TO_CDTIME_T_STATIC(1.000),
++ 1.00,
++ },
++ {
++ // range: bucket 7 - bucket 15; contains the t=1 and t=2 updates
++ DOUBLE_TO_CDTIME_T_STATIC(0.875), DOUBLE_TO_CDTIME_T_STATIC(2.000),
++ 2.00,
++ },
++ {
++ // lower bucket is only partially applied
++ DOUBLE_TO_CDTIME_T_STATIC(0.875 + (0.125 / 4)),
++ DOUBLE_TO_CDTIME_T_STATIC(2.000), 1.75,
++ },
++ {
++ // upper bucket is only partially applied
++ DOUBLE_TO_CDTIME_T_STATIC(0.875),
++ DOUBLE_TO_CDTIME_T_STATIC(2.000 - (0.125 / 4)), 1.75,
++ },
++ {
++ // both buckets are only partially applied
++ DOUBLE_TO_CDTIME_T_STATIC(0.875 + (0.125 / 4)),
++ DOUBLE_TO_CDTIME_T_STATIC(2.000 - (0.125 / 4)), 1.50,
++ },
++ {
++ // lower bound is unspecified
++ 0, DOUBLE_TO_CDTIME_T_STATIC(2.000), 2.00,
++ },
++ {
++ // upper bound is unspecified
++ DOUBLE_TO_CDTIME_T_STATIC(125.000 - 0.125), 0, 1.00,
++ },
++ {
++ // overflow test: upper >> longest latency
++ DOUBLE_TO_CDTIME_T_STATIC(1.000), DOUBLE_TO_CDTIME_T_STATIC(999999),
++ 124.00,
++ },
++ {
++ // overflow test: lower > longest latency
++ DOUBLE_TO_CDTIME_T_STATIC(130), 0, 0.00,
++ },
++ {
++ // lower > upper => error
++ DOUBLE_TO_CDTIME_T_STATIC(10), DOUBLE_TO_CDTIME_T_STATIC(9), NAN,
++ },
++ {
++ // lower == upper => zero
++ DOUBLE_TO_CDTIME_T_STATIC(9), DOUBLE_TO_CDTIME_T_STATIC(9), 0.00,
++ },
+ };
+
+ for (size_t i = 0; i < STATIC_ARRAY_SIZE(cases); i++) {
+ cdtime_t now = peek->start_time + TIME_T_TO_CDTIME_T(1);
- EXPECT_EQ_DOUBLE (cases[i].want,
- latency_counter_get_rate (l, cases[i].lower_bound, cases[i].upper_bound, now));
++ EXPECT_EQ_DOUBLE(cases[i].want,
++ latency_counter_get_rate(l, cases[i].lower_bound,
++ cases[i].upper_bound, now));
+ }
+
- latency_counter_destroy (l);
++ latency_counter_destroy(l);
+ return 0;
+}
+
- int main (void)
- {
+ int main(void) {
RUN_TEST(simple);
RUN_TEST(percentile);
+ RUN_TEST(get_rate);
END_TEST;
}