summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: fb7eb9c)
raw | patch | inline | side by side (parent: fb7eb9c)
author | Sebastian Harl <sh@tokkee.org> | |
Sat, 16 Aug 2014 17:11:45 +0000 (19:11 +0200) | ||
committer | Sebastian Harl <sh@tokkee.org> | |
Sat, 16 Aug 2014 17:11:45 +0000 (19:11 +0200) |
The function fetches a time-series for a specified host's metric and
serializes it into a JSON buffer.
serializes it into a JSON buffer.
src/core/store.c | patch | blob | history | |
src/include/core/store.h | patch | blob | history |
diff --git a/src/core/store.c b/src/core/store.c
index 2565eca4c27feadab488efecec8e2921c7bfd434..c778c52d7dd4a234890b381bea8fb5434a4bab0a 100644 (file)
--- a/src/core/store.c
+++ b/src/core/store.c
char interval_str[64];
size_t i;
+ /* TODO: make time and interval formats configurable */
if (! sdb_strftime(time_str, sizeof(time_str),
"%F %T %z", obj->last_update))
snprintf(time_str, sizeof(time_str), "<error>");
sdb_strbuf_append(buf, "]");
} /* store_obj_tojson */
+/*
+ * ts_tojson serializes a time-series to JSON.
+ *
+ * The function never returns an error. Rather, an error message will be part
+ * of the serialized data.
+ */
+static void
+ts_tojson(sdb_timeseries_t *ts, sdb_strbuf_t *buf)
+{
+ char start_str[64];
+ char end_str[64];
+
+ size_t i;
+
+ /* TODO: make time format configurable */
+ if (! sdb_strftime(start_str, sizeof(start_str),
+ "%F %T %z", ts->start))
+ snprintf(start_str, sizeof(start_str), "<error>");
+ start_str[sizeof(start_str) - 1] = '\0';
+ if (! sdb_strftime(end_str, sizeof(end_str),
+ "%F %T %z", ts->start))
+ snprintf(end_str, sizeof(end_str), "<error>");
+ end_str[sizeof(end_str) - 1] = '\0';
+
+ sdb_strbuf_append(buf, "{\"start\": \"%s\", \"end\": \"%s\", {",
+ start_str, end_str);
+
+ for (i = 0; i < ts->data_names_len; ++i) {
+ size_t j;
+ sdb_strbuf_append(buf, "\"%s\": [", ts->data_names[i]);
+
+ for (j = 0; j < ts->data_len; ++j) {
+ char time_str[64];
+
+ if (! sdb_strftime(time_str, sizeof(time_str),
+ "%F %T %z", ts->data[i][j].timestamp))
+ snprintf(time_str, sizeof(time_str), "<error>");
+ time_str[sizeof(time_str) - 1] = '\0';
+
+ sdb_strbuf_append(buf, "{\"timestamp\": \"%s\", "
+ "\"value\": \"%s\"}", time_str, ts->data[i][j].value);
+
+ if (j < ts->data_len - 1)
+ sdb_strbuf_append(buf, ",");
+ }
+
+ if (i < ts->data_names_len - 1)
+ sdb_strbuf_append(buf, "],");
+ else
+ sdb_strbuf_append(buf, "]");
+ }
+ sdb_strbuf_append(buf, "}}");
+} /* ts_tojson */
+
/*
* public API
*/
metrics = get_host_children(hostname, SDB_METRIC);
if (! metrics) {
sdb_log(SDB_LOG_ERR, "store: Failed to store attribute '%s' "
- "for metric '%s' - host '%ss' not found",
+ "for metric '%s' - host '%s' not found",
key, metric, hostname);
pthread_rwlock_unlock(&host_lock);
return -1;
return status;
} /* sdb_store_metric_attr */
+int
+sdb_store_fetch_timeseries(const char *hostname, const char *metric,
+ sdb_timeseries_opts_t *opts, sdb_strbuf_t *buf)
+{
+ sdb_avltree_t *metrics;
+ sdb_metric_t *m;
+
+ sdb_timeseries_t *ts;
+
+ if ((! hostname) || (! metric) || (! opts) || (! buf))
+ return -1;
+
+ pthread_rwlock_rdlock(&host_lock);
+ metrics = get_host_children(hostname, SDB_METRIC);
+ if (! metrics) {
+ sdb_log(SDB_LOG_ERR, "store: Failed to fetch time-series '%s/%s' "
+ "- host '%s' not found", hostname, metric, hostname);
+ pthread_rwlock_unlock(&host_lock);
+ return -1;
+ }
+
+ m = METRIC(sdb_avltree_lookup(metrics, metric));
+ if (! m) {
+ sdb_log(SDB_LOG_ERR, "store: Failed to fetch time-series '%s/%s' "
+ "- metric '%s' not found", hostname, metric, metric);
+ pthread_rwlock_unlock(&host_lock);
+ return -1;
+ }
+
+ if ((! m->store.type) || (! m->store.id)) {
+ sdb_log(SDB_LOG_ERR, "store: Failed to fetch time-series '%s/%s' "
+ "- no data-store configured for the stored metric",
+ hostname, metric);
+ pthread_rwlock_unlock(&host_lock);
+ return -1;
+ }
+
+ {
+ char type[strlen(m->store.type) + 1];
+ char id[strlen(m->store.id) + 1];
+
+ strncpy(type, m->store.type, sizeof(type));
+ strncpy(id, m->store.id, sizeof(id));
+ pthread_rwlock_unlock(&host_lock);
+
+ ts = sdb_plugin_fetch_timeseries(type, id, opts);
+ if (! ts) {
+ sdb_log(SDB_LOG_ERR, "store: Failed to fetch time-series '%s/%s' "
+ "- %s fetcher callback returned no data for '%s'",
+ hostname, metric, type, id);
+ return -1;
+ }
+ }
+
+ ts_tojson(ts, buf);
+ sdb_timeseries_destroy(ts);
+ return 0;
+} /* sdb_store_fetch_timeseries */
+
int
sdb_store_get_field(sdb_store_obj_t *obj, int field, sdb_data_t *res)
{
index 2d3d707161e73e851e68bcd5bbcc722f0b3d9a46..7c94a974297d46cb4107df7ea8773e036343a8d8 100644 (file)
--- a/src/include/core/store.h
+++ b/src/include/core/store.h
#include "core/object.h"
#include "core/data.h"
#include "core/time.h"
+#include "core/timeseries.h"
#include "utils/strbuf.h"
#include <stdio.h>
sdb_store_metric_attr(const char *hostname, const char *metric,
const char *key, const sdb_data_t *value, sdb_time_t last_update);
+/*
+ * sdb_store_fetch_timeseries:
+ * Fetch the time-series described by the specified host's metric and
+ * serialize it as JSON into the provided string buffer.
+ *
+ * Returns:
+ * - 0 on success
+ * - a negative value else
+ */
+int
+sdb_store_fetch_timeseries(const char *hostname, const char *metric,
+ sdb_timeseries_opts_t *opts, sdb_strbuf_t *buf);
+
/*
* sdb_store_get_field:
* Get the value of a stored object's queryable field. The caller is