summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: 5ba97a2)
raw | patch | inline | side by side (parent: 5ba97a2)
author | Sebastian Harl <sh@tokkee.org> | |
Thu, 28 Aug 2014 23:42:34 +0000 (16:42 -0700) | ||
committer | Sebastian Harl <sh@tokkee.org> | |
Thu, 28 Aug 2014 23:44:24 +0000 (16:44 -0700) |
After enabling RRDCacheD support, the plugin supports an additional
time-series fetcher callback which may be used to flush outstanding updates to
an RRD file before fetching data from it.
time-series fetcher callback which may be used to flush outstanding updates to
an RRD file before fetching data from it.
configure.ac | patch | blob | history | |
doc/sysdbd-timeseries-rrdtool.5.txt | patch | blob | history | |
src/plugins/timeseries/rrdtool.c | patch | blob | history |
diff --git a/configure.ac b/configure.ac
index ef6868e7bab7509c129a75fde51afcf83028b2f3..37d77ff9dcb18f202ffe40aab8b4af50aeee6ffa 100644 (file)
--- a/configure.ac
+++ b/configure.ac
AC_MSG_ERROR([Invalid value for option --with-librrd=$with_librrd (expected "yes", "no", or "auto")])
fi; fi
+if test "x$have_librrd" = "xyes"; then
+ AC_CHECK_HEADERS([rrd_client.h])
+fi
+
dnl Feature checks.
build_documentation="yes"
index 693caadcbe960bc707ee38c5566b24baf7d8b399..b36a177c5c1c95b7cb60ab03e2b7b86ea4940471 100644 (file)
CONFIGURATION
-------------
-*timeseries::rrdtool* does not currently accept any configuration options. It
-registers a time-series fetcher callback called *rrdtool*.
+*timeseries::rrdtool* accepts the following configuration options. In addition
+to any configuration, the plugin always registers a time-series fetcher
+callback called *rrdtool* which may be used to access RRD files on local disk.
+
+*RRDCacheD* '<addr>'::
+ Enable support for RRDCacheD. When using this option, an additional
+ time-series fetcher callback called *rrdcached* is made available. It will
+ flush cached updates for an RRD file before fetching data from it.
+ Currently, local connections through a UNIX socket are supported only.
SEE ALSO
--------
index 572c033e0361bf13b49be6500d0287fcf768fabd..db24903f5513785852a22748f05de88b1a4b0f91 100644 (file)
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif /* HAVE_CONFIG_H */
+
#include "sysdb.h"
#include "core/plugin.h"
#include "utils/error.h"
+#include "liboconfig/utils.h"
+
#include <errno.h>
+#include <stdlib.h>
#include <rrd.h>
+#ifdef HAVE_RRD_CLIENT_H
+# include <rrd_client.h>
+#endif
SDB_PLUGIN_MAGIC;
+/* Current versions of RRDtool do not support multiple RRDCacheD client
+ * connections. Use this to guard against multiple configured RRDCacheD
+ * instances. */
+static _Bool rrdcached_in_use = 0;
+
/*
* plugin API
*/
static sdb_timeseries_t *
sdb_rrd_fetch(const char *id, sdb_timeseries_opts_t *opts,
- sdb_object_t __attribute__((unused)) *user_data)
+ sdb_object_t *user_data)
{
sdb_timeseries_t *ts;
char **ds_namv = NULL;
rrd_value_t *data = NULL, *data_ptr;
+ if (user_data) {
+#ifdef HAVE_RRD_CLIENT_H
+ /* -> use RRDCacheD */
+ char *addr = SDB_OBJ_WRAPPER(user_data)->data;
+
+ rrd_clear_error();
+ if (! rrdc_is_connected(addr)) {
+ if (rrdc_connect(addr)) {
+ sdb_log(SDB_LOG_ERR, "timeseries::rrdtool: Failed to "
+ "connectd to RRDCacheD at %s: %s",
+ addr, rrd_get_error());
+ return NULL;
+ }
+ }
+
+ if (rrdc_flush(id)) {
+ sdb_log(SDB_LOG_ERR, "timeseries::rrdtool: Failed to flush "
+ "'%s' through RRDCacheD: %s", id, rrd_get_error());
+ return NULL;
+ }
+#else
+ sdb_log(SDB_LOG_ERR, "timeseries::rrdtool: Callback called with "
+ "RRDCacheD address but your build of SysDB does not support "
+ "that");
+ return NULL;
+#endif
+ }
+
#define FREE_RRD_DATA() \
do { \
size_t i; \
return ts;
} /* sdb_rrd_fetch */
+static int
+sdb_rrdcached_shutdown(sdb_object_t __attribute__((unused)) *user_data)
+{
+#ifdef HAVE_RRD_CLIENT_H
+ rrdc_disconnect();
+#endif
+ return 0;
+} /* sdb_rrdcached_shutdown */
+
+static int
+sdb_rrd_config_rrdcached(oconfig_item_t *ci)
+{
+ sdb_object_t *ud;
+ char *addr = NULL;
+
+ if (rrdcached_in_use) {
+ sdb_log(SDB_LOG_ERR, "timeseries::rrdtool: RRDCacheD does "
+ "not support multiple connections");
+ return -1;
+ }
+
+#ifndef HAVE_RRD_CLIENT_H
+ sdb_log(SDB_LOG_ERR, "timeseries::rrdtool: RRDCacheD client "
+ "support not available in your SysDB build");
+ return -1;
+#else
+ if (oconfig_get_string(ci, &addr)) {
+ sdb_log(SDB_LOG_ERR, "timeseries::unixsock: RRDCacheD requires "
+ "a single string argument\n\tUsage <RRDCacheD ADDR>");
+ return -1;
+ }
+ if ((*addr != '/') && strncmp(addr, "unix:", strlen("unix:"))) {
+ /* XXX: add (optional) support for rrdc_fetch if available */
+ sdb_log(SDB_LOG_ERR, "timeseries::unixsock: RRDCacheD only "
+ "supports local (UNIX socket) addresses");
+ return -1;
+ }
+
+ addr = strdup(addr);
+ if (! addr) {
+ char errbuf[1024];
+ sdb_log(SDB_LOG_ERR, "timeseries::unixsock: Failed to duplicate "
+ "string: %s", sdb_strerror(errno, errbuf, sizeof(errbuf)));
+ return -1;
+ }
+ if (ci->children_num)
+ sdb_log(SDB_LOG_WARNING, "timeseries::unixsock: RRDCacheD does "
+ "not support any child config options");
+
+ ud = sdb_object_create_wrapper("rrdcached-addr", addr, free);
+ if (! ud) {
+ char errbuf[1024];
+ sdb_log(SDB_LOG_ERR, "timeseries::unixsock: Failed to create "
+ "user-data object: %s",
+ sdb_strerror(errno, errbuf, sizeof(errbuf)));
+ free(addr);
+ return -1;
+ }
+
+ sdb_plugin_register_ts_fetcher("rrdcached", sdb_rrd_fetch, ud);
+ sdb_plugin_register_shutdown("rrdcached", sdb_rrdcached_shutdown, NULL);
+ sdb_object_deref(ud);
+ rrdcached_in_use = 1;
+ return 0;
+#endif
+} /* sdb_rrd_config_rrdcached */
+
+static int
+sdb_rrd_config(oconfig_item_t *ci)
+{
+ int i;
+
+ if (! ci) { /* reconfigure */
+ rrdcached_in_use = 0;
+ return 0;
+ }
+
+ for (i = 0; i < ci->children_num; ++i) {
+ oconfig_item_t *child = ci->children + i;
+
+ if (! strcasecmp(child->key, "RRDCacheD"))
+ sdb_rrd_config_rrdcached(child);
+ else
+ sdb_log(SDB_LOG_WARNING, "timeseries::rrdtool: Ignoring "
+ "unknown config option '%s'.", child->key);
+ }
+ return 0;
+} /* sdb_rrd_config */
+
int
sdb_module_init(sdb_plugin_info_t *info)
{
sdb_plugin_set_info(info, SDB_PLUGIN_INFO_PLUGIN_VERSION, SDB_VERSION);
sdb_plugin_register_ts_fetcher("rrdtool", sdb_rrd_fetch, NULL);
+ sdb_plugin_register_config(sdb_rrd_config);
return 0;
} /* sdb_module_init */