From 1f99d1a0d8a7e923dede7c938340c26061b8398b Mon Sep 17 00:00:00 2001 From: Sebastian Harl Date: Sat, 10 Sep 2016 19:23:14 -0400 Subject: [PATCH] Let the JSON formatter include a metric's data_names. For that purpose, let the metric store provide a reference to the timeseries information object (to be populated on read). The JSON formatter compiles a list of unique data_names and outputs that alongside the other metric metadata. --- src/core/memstore.c | 1 + src/core/store_json.c | 48 ++++++++++++++++++++++--- src/include/core/store.h | 2 ++ src/plugins/backend/collectd/unixsock.c | 2 +- t/integration/mock_plugin.c | 16 ++++----- t/unit/core/store_test.c | 4 +-- 6 files changed, 57 insertions(+), 16 deletions(-) diff --git a/src/core/memstore.c b/src/core/memstore.c index 87f9512..9ae8369 100644 --- a/src/core/memstore.c +++ b/src/core/memstore.c @@ -784,6 +784,7 @@ sdb_memstore_metric(sdb_memstore_t *store, const char *hostname, const char *nam metric.stores = &(const sdb_metric_store_t){ metric_store->type, metric_store->id, + NULL, metric_store->last_update, }; metric.stores_num = 1; diff --git a/src/core/store_json.c b/src/core/store_json.c index 56baa46..256fdea 100644 --- a/src/core/store_json.c +++ b/src/core/store_json.c @@ -36,6 +36,7 @@ #include "sysdb.h" #include "core/store.h" #include "utils/error.h" +#include "utils/strings.h" #include @@ -103,6 +104,8 @@ typedef struct { * 0: false * 1: true */ int timeseries; + char **data_names; + size_t data_names_len; /* generic meta-data */ sdb_time_t last_update; @@ -235,6 +238,18 @@ json_emit(sdb_store_json_formatter_t *f, obj_t *obj) sdb_strbuf_append(f->buf, "\"timeseries\": true, "); else sdb_strbuf_append(f->buf, "\"timeseries\": false, "); + + if (obj->data_names_len > 0) { + sdb_strbuf_append(f->buf, "\"data_names\": ["); + for (i = 0; i < obj->data_names_len; i++) { + char dn[2 * strlen(obj->data_names[i]) + 3]; + escape_string(obj->data_names[i], dn); + sdb_strbuf_append(f->buf, "%s", dn); + if (i < obj->data_names_len - 1) + sdb_strbuf_append(f->buf, ", "); + } + sdb_strbuf_append(f->buf, "], "); + } } /* TODO: make time and interval formats configurable */ @@ -274,7 +289,7 @@ emit_host(sdb_store_host_t *host, sdb_object_t *user_data) host->name, /* value */ NULL, - /* timeseries */ -1, + /* timeseries */ -1, NULL, 0, host->last_update, host->interval, @@ -300,7 +315,7 @@ emit_service(sdb_store_service_t *service, sdb_object_t *user_data) service->name, /* value */ NULL, - /* timeseries */ -1, + /* timeseries */ -1, NULL, 0, service->last_update, service->interval, @@ -316,6 +331,8 @@ static int emit_metric(sdb_store_metric_t *metric, sdb_object_t *user_data) { sdb_store_json_formatter_t *f = F(user_data); + int status; + size_t i; if ((! metric) || (! user_data)) return -1; @@ -326,7 +343,7 @@ emit_metric(sdb_store_metric_t *metric, sdb_object_t *user_data) metric->name, /* value */ NULL, - /* timeseries */ metric->stores_num > 0, + /* timeseries */ metric->stores_num > 0, NULL, 0, metric->last_update, metric->interval, @@ -334,7 +351,28 @@ emit_metric(sdb_store_metric_t *metric, sdb_object_t *user_data) (const char * const *)metric->backends, }; - return json_emit(f, &o); + for (i = 0; i < metric->stores_num; i++) { + const sdb_metric_store_t *s = metric->stores + i; + size_t j; + + if (! s->info) + continue; + + if (! o.data_names) { + stringv_copy(&o.data_names, &o.data_names_len, + (const char * const *)s->info->data_names, + s->info->data_names_len); + continue; + } + + for (j = 0; j < s->info->data_names_len; j++) + stringv_append_if_missing(&o.data_names, &o.data_names_len, + s->info->data_names[j]); + } + + status = json_emit(f, &o); + stringv_free(&o.data_names, &o.data_names_len); + return status; } } /* emit_metric */ @@ -352,7 +390,7 @@ emit_attribute(sdb_store_attribute_t *attr, sdb_object_t *user_data) attr->key, /* value */ &attr->value, - /* timeseries */ -1, + /* timeseries */ -1, NULL, 0, attr->last_update, attr->interval, diff --git a/src/include/core/store.h b/src/include/core/store.h index 3f20429..f0fc0c7 100644 --- a/src/include/core/store.h +++ b/src/include/core/store.h @@ -32,6 +32,7 @@ #include "core/object.h" #include "core/data.h" #include "core/time.h" +#include "core/timeseries.h" #include "parser/ast.h" #include "utils/strbuf.h" @@ -125,6 +126,7 @@ typedef struct { typedef struct { const char *type; const char *id; + const sdb_timeseries_info_t *info; sdb_time_t last_update; } sdb_metric_store_t; diff --git a/src/plugins/backend/collectd/unixsock.c b/src/plugins/backend/collectd/unixsock.c index 54df202..73d0dc6 100644 --- a/src/plugins/backend/collectd/unixsock.c +++ b/src/plugins/backend/collectd/unixsock.c @@ -151,7 +151,7 @@ add_metrics(const char *hostname, char *plugin, char *type, char metric_id[(ud->ts_base ? strlen(ud->ts_base) : 0) + strlen(hostname) + sizeof(name) + 7]; - sdb_metric_store_t store = { ud->ts_type, metric_id, last_update }; + sdb_metric_store_t store = { ud->ts_type, metric_id, NULL, last_update }; sdb_data_t data = { SDB_TYPE_STRING, { .string = NULL } }; diff --git a/t/integration/mock_plugin.c b/t/integration/mock_plugin.c index fa48728..0724ce1 100644 --- a/t/integration/mock_plugin.c +++ b/t/integration/mock_plugin.c @@ -57,21 +57,21 @@ static struct { sdb_metric_store_t store; } metrics[] = { { "some.host.name", "foo/bar/qux", - { "mock", "/var/lib/collectd/rrd/foo/bar/qux.rrd", 0 } }, + { "mock", "/var/lib/collectd/rrd/foo/bar/qux.rrd", NULL, 0 } }, { "some.host.name", "foo/bar/baz", - { "mock", "/var/lib/collectd/rrd/foo/bar/baz.rrd", 0 } }, + { "mock", "/var/lib/collectd/rrd/foo/bar/baz.rrd", NULL, 0 } }, { "some.host.name", "foo2/bar/qux", - { "mock", "/var/lib/collectd/rrd/foo2/bar/qux.rrd", 0 } }, + { "mock", "/var/lib/collectd/rrd/foo2/bar/qux.rrd", NULL, 0 } }, { "some.host.name", "foo2/bar/baz", - { "mock", "/var/lib/collectd/rrd/foo2/bar/baz.rrd", 0 } }, + { "mock", "/var/lib/collectd/rrd/foo2/bar/baz.rrd", NULL, 0 } }, { "other.host.name", "foo/bar/qux", - { "mock", "/var/lib/collectd/rrd/foo/bar/qux.rrd", 0 } }, + { "mock", "/var/lib/collectd/rrd/foo/bar/qux.rrd", NULL, 0 } }, { "other.host.name", "foo/bar/baz", - { "mock", "/var/lib/collectd/rrd/foo/bar/baz.rrd", 0 } }, + { "mock", "/var/lib/collectd/rrd/foo/bar/baz.rrd", NULL, 0 } }, { "other.host.name", "foo2/bar/qux", - { "mock", "/var/lib/collectd/rrd/foo2/bar/qux.rrd", 0 } }, + { "mock", "/var/lib/collectd/rrd/foo2/bar/qux.rrd", NULL, 0 } }, { "other.host.name", "foo2/bar/baz", - { "mock", "/var/lib/collectd/rrd/foo2/bar/baz.rrd", 0 } }, + { "mock", "/var/lib/collectd/rrd/foo2/bar/baz.rrd", NULL, 0 } }, }; static struct { diff --git a/t/unit/core/store_test.c b/t/unit/core/store_test.c index d6a44e0..3fef343 100644 --- a/t/unit/core/store_test.c +++ b/t/unit/core/store_test.c @@ -239,8 +239,8 @@ END_TEST START_TEST(test_store_metric) { - sdb_metric_store_t store1 = { "dummy-type1", "dummy-id1", 0 }; - sdb_metric_store_t store2 = { "dummy-type2", "dummy-id2", 0 }; + sdb_metric_store_t store1 = { "dummy-type1", "dummy-id1", NULL, 0 }; + sdb_metric_store_t store2 = { "dummy-type2", "dummy-id2", NULL, 0 }; struct { const char *host; -- 2.30.2