Code

store: Store "data-store" information alongside metrics.
authorSebastian Harl <sh@tokkee.org>
Sat, 16 Aug 2014 10:08:16 +0000 (12:08 +0200)
committerSebastian Harl <sh@tokkee.org>
Sat, 16 Aug 2014 10:08:16 +0000 (12:08 +0200)
A metric data-store describes how to access data (e.g. time-series) of a
metric.

src/core/store-private.h
src/core/store.c
src/include/core/store.h
t/integration/mock_plugin.c
t/unit/core/store_lookup_test.c
t/unit/core/store_test.c

index 3c23ebbb5ad102cdff7794f285a508d4be14b741..6dc68c0c1fe6f837a55c61b1c92b5208d342cf58 100644 (file)
@@ -82,6 +82,10 @@ typedef struct {
        sdb_store_obj_t super;
 
        sdb_avltree_t *attributes;
+       struct {
+               char *type;
+               char *id;
+       } store;
 } sdb_metric_t;
 #define METRIC(obj) ((sdb_metric_t *)(obj))
 
index 44e696cccf6549ec49707022d30c58a4f387da64..2565eca4c27feadab488efecec8e2921c7bfd434 100644 (file)
@@ -174,6 +174,8 @@ sdb_metric_init(sdb_object_t *obj, va_list ap)
        sobj->attributes = sdb_avltree_create();
        if (! sobj->attributes)
                return -1;
+
+       sobj->store.type = sobj->store.id = NULL;
        return 0;
 } /* sdb_metric_init */
 
@@ -187,6 +189,11 @@ sdb_metric_destroy(sdb_object_t *obj)
 
        if (sobj->attributes)
                sdb_avltree_destroy(sobj->attributes);
+
+       if (sobj->store.type)
+               free(sobj->store.type);
+       if (sobj->store.id)
+               free(sobj->store.id);
 } /* sdb_metric_destroy */
 
 static int
@@ -678,14 +685,19 @@ sdb_store_service_attr(const char *hostname, const char *service,
 
 int
 sdb_store_metric(const char *hostname, const char *name,
-               sdb_time_t last_update)
+               sdb_metric_store_t *store, sdb_time_t last_update)
 {
+       sdb_store_obj_t *obj = NULL;
+       sdb_metric_t *metric;
+
        sdb_avltree_t *metrics;
 
        int status = 0;
 
        if ((! hostname) || (! name))
                return -1;
+       if (store && ((! store->type) || (! store->id)))
+               return -1;
 
        pthread_rwlock_wrlock(&host_lock);
        metrics = get_host_children(hostname, SDB_METRIC);
@@ -696,7 +708,35 @@ sdb_store_metric(const char *hostname, const char *name,
        }
 
        if (! status)
-               status = store_obj(metrics, SDB_METRIC, name, last_update, NULL);
+               status = store_obj(metrics, SDB_METRIC, name, last_update, &obj);
+
+       if (status || (! store)) {
+               pthread_rwlock_unlock(&host_lock);
+               return status;
+       }
+
+       assert(obj);
+       metric = METRIC(obj);
+
+       if ((! metric->store.type) || strcasecmp(metric->store.type, store->type)) {
+               if (metric->store.type)
+                       free(metric->store.type);
+               metric->store.type = strdup(store->type);
+       }
+       if ((! metric->store.id) || strcasecmp(metric->store.id, store->id)) {
+               if (metric->store.id)
+                       free(metric->store.id);
+               metric->store.id = strdup(store->id);
+       }
+
+       if ((! metric->store.type) || (! metric->store.id)) {
+               if (metric->store.type)
+                       free(metric->store.type);
+               if (metric->store.id)
+                       free(metric->store.id);
+               metric->store.type = metric->store.id = NULL;
+               status = -1;
+       }
        pthread_rwlock_unlock(&host_lock);
        return status;
 } /* sdb_store_metric */
index 169d1128ac03d1fcef4c809f47984ef57f61317b..2d3d707161e73e851e68bcd5bbcc722f0b3d9a46 100644 (file)
@@ -174,6 +174,14 @@ int
 sdb_store_service_attr(const char *hostname, const char *service,
                const char *key, const sdb_data_t *value, sdb_time_t last_update);
 
+/*
+ * A metric store describes how to access a metric's data.
+ */
+typedef struct {
+       const char *type;
+       const char *id;
+} sdb_metric_store_t;
+
 /*
  * sdb_store_metric:
  * Add/update a metric in the store. If the metric, identified by its name,
@@ -183,6 +191,8 @@ sdb_store_service_attr(const char *hostname, const char *service,
  * memory required for storing the entry will be allocated an managed by the
  * store itself.
  *
+ * If specified, the metric store describes where to access the metric's data.
+ *
  * Returns:
  *  - 0 on success
  *  - a positive value if the new entry is older than the currently stored
@@ -191,7 +201,7 @@ sdb_store_service_attr(const char *hostname, const char *service,
  */
 int
 sdb_store_metric(const char *hostname, const char *name,
-               sdb_time_t last_update);
+               sdb_metric_store_t *store, sdb_time_t last_update);
 
 /*
  * sdb_store_metric_attr:
index 8c161943617f58db39f195df1b87b7589941bc3b..1fb59fc1f39dbca0b248cbf3ab28ef236c92c3c5 100644 (file)
@@ -54,15 +54,24 @@ static const char *hostnames[] = {
 static struct {
        const char *hostname;
        const char *metric;
+       sdb_metric_store_t store;
 } metrics[] = {
-       { "some.host.name", "foo/bar/qux" },
-       { "some.host.name", "foo/bar/baz" },
-       { "some.host.name", "foo2/bar/qux" },
-       { "some.host.name", "foo2/bar/baz" },
-       { "other.host.name", "foo/bar/qux" },
-       { "other.host.name", "foo/bar/baz" },
-       { "other.host.name", "foo2/bar/qux" },
-       { "other.host.name", "foo2/bar/baz" },
+       { "some.host.name", "foo/bar/qux",
+               { "dummy", "/var/lib/collectd/rrd/foo/bar/qux.rrd" } },
+       { "some.host.name", "foo/bar/baz",
+               { "dummy", "/var/lib/collectd/rrd/foo/bar/baz.rrd" } },
+       { "some.host.name", "foo2/bar/qux",
+               { "dummy", "/var/lib/collectd/rrd/foo2/bar/qux.rrd" } },
+       { "some.host.name", "foo2/bar/baz",
+               { "dummy", "/var/lib/collectd/rrd/foo2/bar/baz.rrd" } },
+       { "other.host.name", "foo/bar/qux",
+               { "dummy", "/var/lib/collectd/rrd/foo/bar/qux.rrd" } },
+       { "other.host.name", "foo/bar/baz",
+               { "dummy", "/var/lib/collectd/rrd/foo/bar/baz.rrd" } },
+       { "other.host.name", "foo2/bar/qux",
+               { "dummy", "/var/lib/collectd/rrd/foo2/bar/qux.rrd" } },
+       { "other.host.name", "foo2/bar/baz",
+               { "dummy", "/var/lib/collectd/rrd/foo2/bar/baz.rrd" } },
 };
 
 static struct {
@@ -152,7 +161,8 @@ mock_collect(sdb_object_t *user_data)
        }
        for (i = 0; i < SDB_STATIC_ARRAY_LEN(metrics); ++i) {
                if ((check = sdb_store_metric(metrics[i].hostname,
-                                               metrics[i].metric, sdb_gettime()))) {
+                                               metrics[i].metric, &metrics[i].store,
+                                               sdb_gettime()))) {
                        sdb_log(SDB_LOG_ERR, "mock::plugin: Failed to store metric: "
                                        "status %d", check);
                        exit(1);
index d1dc82f3664783862ed84386ad309e4675066c4c..b356fa0dd7b95858bddc93767a26ce4890136d23 100644 (file)
@@ -77,9 +77,9 @@ populate(void)
 
        for (i = 0; i < SDB_STATIC_ARRAY_LEN(metrics); ++i) {
                int status = sdb_store_metric(metrics[i].host,
-                               metrics[i].metric, 1);
+                               metrics[i].metric, /* store */ NULL, 1);
                fail_unless(status == 0,
-                               "sdb_store_metric(%s, %s, 1) = %d; expected: 0",
+                               "sdb_store_metric(%s, %s, NULL, 1) = %d; expected: 0",
                                metrics[i].host, metrics[i].metric, status);
        }
 
index c056ac7c6d23e132f4a32d83a82ac2dc61173952..e8c77c7b04dc0c649fdc7cb0a00985f2fd760354 100644 (file)
@@ -53,8 +53,8 @@ populate(void)
        sdb_store_attribute("h1", "k2", &datum, 1);
        sdb_store_attribute("h1", "k3", &datum, 2);
 
-       sdb_store_metric("h1", "m1", 2);
-       sdb_store_metric("h1", "m2", 1);
+       sdb_store_metric("h1", "m1", /* store */ NULL, 2);
+       sdb_store_metric("h1", "m2", /* store */ NULL, 1);
 
        sdb_store_service("h2", "s1", 1);
        sdb_store_service("h2", "s2", 2);
@@ -228,20 +228,32 @@ END_TEST
 
 START_TEST(test_store_metric)
 {
+       sdb_metric_store_t store1 = { "dummy-type1", "dummy-id1" };
+       sdb_metric_store_t store2 = { "dummy-type2", "dummy-id2" };
+
        struct {
                const char *host;
                const char *metric;
+               sdb_metric_store_t *store;
                sdb_time_t  last_update;
                int         expected;
        } golden_data[] = {
-               { "k", "m",  1, -1 },
-               { "k", "m",  1, -1 }, /* retry to ensure the host is not created */
-               { "l", "m1", 1,  0 },
-               { "l", "m1", 2,  0 },
-               { "l", "m1", 2,  1 },
-               { "l", "m2", 1,  0 },
-               { "m", "m",  1,  0 },
-               { "m", "m",  1,  1 },
+               { "k", "m",  NULL,    1, -1 },
+               { "k", "m",  NULL,    1, -1 }, /* retry to ensure the host is not created */
+               { "k", "m",  &store1, 1, -1 },
+               { "l", "m1", NULL,    1,  0 },
+               { "l", "m1", &store1, 2,  0 },
+               { "l", "m1", &store1, 3,  0 },
+               { "l", "m1", NULL,    3,  1 },
+               { "l", "m2", &store1, 1,  0 },
+               { "l", "m2", &store2, 2,  0 },
+               { "l", "m2", NULL,    3,  0 },
+               { "m", "m",  &store1, 1,  0 },
+               { "m", "m",  NULL,    2,  0 },
+               { "m", "m",  NULL,    2,  1 },
+               { "m", "m",  &store1, 3,  0 },
+               { "m", "m",  &store2, 4,  0 },
+               { "m", "m",  NULL,    5,  0 },
        };
 
        size_t i;
@@ -252,11 +264,13 @@ START_TEST(test_store_metric)
                int status;
 
                status = sdb_store_metric(golden_data[i].host,
-                               golden_data[i].metric, golden_data[i].last_update);
+                               golden_data[i].metric, golden_data[i].store,
+                               golden_data[i].last_update);
                fail_unless(status == golden_data[i].expected,
-                               "sdb_store_metric(%s, %s, %d) = %d; expected: %d",
+                               "sdb_store_metric(%s, %s, %p, %d) = %d; expected: %d",
                                golden_data[i].host, golden_data[i].metric,
-                               golden_data[i].last_update, status, golden_data[i].expected);
+                               golden_data[i].store, golden_data[i].last_update,
+                               status, golden_data[i].expected);
        }
 }
 END_TEST
@@ -290,9 +304,9 @@ START_TEST(test_store_metric_attr)
 
        sdb_store_host("m", 1);
        sdb_store_host("l", 1);
-       sdb_store_metric("m", "m1", 1);
-       sdb_store_metric("l", "m1", 1);
-       sdb_store_metric("l", "m2", 1);
+       sdb_store_metric("m", "m1", NULL, 1);
+       sdb_store_metric("l", "m1", NULL, 1);
+       sdb_store_metric("l", "m2", NULL, 1);
 
        for (i = 0; i < SDB_STATIC_ARRAY_LEN(golden_data); ++i) {
                int status;