Code

Store a separate last_update timestamp for metric stores.
authorSebastian Harl <sh@tokkee.org>
Sun, 4 Sep 2016 16:53:29 +0000 (12:53 -0400)
committerSebastian Harl <sh@tokkee.org>
Sun, 4 Sep 2016 16:53:29 +0000 (12:53 -0400)
Currently, it is (at least) the same as the metric's last_update timestamp.
We'll need this later when supporting multiple metric stores.

src/core/memstore-private.h
src/core/memstore.c
src/core/plugin.c
src/frontend/query.c
src/include/core/store.h
src/plugins/backend/collectd/unixsock.c
t/integration/mock_plugin.c
t/unit/core/store_test.c

index cd0152d618c6adc1470ab05fe5b32f437fd1ee36..1afb66ad736668038b0794a525ecc7657e595a34 100644 (file)
@@ -87,6 +87,7 @@ typedef struct {
        struct {
                char *type;
                char *id;
        struct {
                char *type;
                char *id;
+               sdb_time_t last_update;
        } store;
 } metric_t;
 #define METRIC(obj) ((metric_t *)(obj))
        } store;
 } metric_t;
 #define METRIC(obj) ((metric_t *)(obj))
index 05c879bf8e14abf0456d368a59689fde3cf04316..317a1761491486cdb6295862383fab4fd6520a1d 100644 (file)
@@ -406,6 +406,11 @@ store_metric_store(metric_t *metric, sdb_store_metric_t *m)
        char *type = metric->store.type;
        char *id = metric->store.id;
 
        char *type = metric->store.type;
        char *id = metric->store.id;
 
+       if (! m->store.last_update)
+               m->store.last_update = metric->store.last_update;
+       else if (m->store.last_update < metric->store.last_update)
+               return 0;
+
        if ((! metric->store.type) || strcasecmp(metric->store.type, m->store.type)) {
                if (! (type = strdup(m->store.type)))
                        return -1;
        if ((! metric->store.type) || strcasecmp(metric->store.type, m->store.type)) {
                if (! (type = strdup(m->store.type)))
                        return -1;
@@ -428,6 +433,7 @@ store_metric_store(metric_t *metric, sdb_store_metric_t *m)
                        free(metric->store.id);
                metric->store.id = id;
        }
                        free(metric->store.id);
                metric->store.id = id;
        }
+       metric->store.last_update = m->store.last_update;
        return 0;
 } /* store_metric_store */
 
        return 0;
 } /* store_metric_store */
 
@@ -721,11 +727,14 @@ sdb_memstore_metric(sdb_memstore_t *store, const char *hostname, const char *nam
                sdb_time_t last_update, sdb_time_t interval)
 {
        sdb_store_metric_t metric = {
                sdb_time_t last_update, sdb_time_t interval)
 {
        sdb_store_metric_t metric = {
-               hostname, name, { NULL, NULL }, last_update, interval, NULL, 0,
+               hostname, name,
+               { NULL, NULL, 0 },
+               last_update, interval, NULL, 0,
        };
        if (metric_store) {
                metric.store.type = metric_store->type;
                metric.store.id = metric_store->id;
        };
        if (metric_store) {
                metric.store.type = metric_store->type;
                metric.store.id = metric_store->id;
+               metric.store.last_update = metric_store->last_update;
        }
        return store_metric(&metric, SDB_OBJ(store));
 } /* sdb_memstore_metric */
        }
        return store_metric(&metric, SDB_OBJ(store));
 } /* sdb_memstore_metric */
@@ -999,6 +1008,7 @@ sdb_memstore_emit(sdb_memstore_obj_t *obj, sdb_store_writer_t *w, sdb_object_t *
                                {
                                        METRIC(obj)->store.type,
                                        METRIC(obj)->store.id,
                                {
                                        METRIC(obj)->store.type,
                                        METRIC(obj)->store.id,
+                                       METRIC(obj)->store.last_update,
                                },
                                obj->last_update,
                                obj->interval,
                                },
                                obj->last_update,
                                obj->interval,
index 76b0b1e45b656a6416bb8aa526581cd311ac5921..92fa8866981f6e5b4623100498c04d7e5567f0d8 100644 (file)
@@ -1733,8 +1733,11 @@ sdb_plugin_store_metric(const char *hostname, const char *name,
        metric.hostname = cname;
        metric.name = name;
        if (store) {
        metric.hostname = cname;
        metric.name = name;
        if (store) {
+               if (store->last_update < last_update)
+                       store->last_update = last_update;
                metric.store.type = store->type;
                metric.store.id = store->id;
                metric.store.type = store->type;
                metric.store.id = store->id;
+               metric.store.last_update = store->last_update;
        }
        metric.last_update = last_update ? last_update : sdb_gettime();
        if (get_interval(SDB_METRIC, cname, -1, NULL, name,
        }
        metric.last_update = last_update ? last_update : sdb_gettime();
        if (get_interval(SDB_METRIC, cname, -1, NULL, name,
index f8d6a1f2dc8e518ca3843752794789f94361b3d4..5d00636dd99e77219303c645bdf019f8ac59bfeb 100644 (file)
@@ -51,6 +51,7 @@
 typedef struct {
        char *type;
        char *id;
 typedef struct {
        char *type;
        char *id;
+       sdb_time_t last_update;
 } metric_store_t;
 
 static int
 } metric_store_t;
 
 static int
@@ -70,6 +71,7 @@ metric_fetcher_metric(sdb_store_metric_t *metric, sdb_object_t *user_data)
 
        st->type = strdup(metric->store.type);
        st->id = strdup(metric->store.id);
 
        st->type = strdup(metric->store.type);
        st->id = strdup(metric->store.id);
+       st->last_update = metric->store.last_update;
        if ((! st->type) || (! st->id))
                return -1;
        return 0;
        if ((! st->type) || (! st->id))
                return -1;
        return 0;
@@ -156,6 +158,7 @@ exec_store(sdb_ast_store_t *st, sdb_strbuf_t *buf, sdb_strbuf_t *errbuf)
                snprintf(name, sizeof(name), "%s.%s", st->hostname, st->name);
                metric_store.type = st->store_type;
                metric_store.id = st->store_id;
                snprintf(name, sizeof(name), "%s.%s", st->hostname, st->name);
                metric_store.type = st->store_type;
                metric_store.id = st->store_id;
+               metric_store.last_update = st->last_update;
                status = sdb_plugin_store_metric(st->hostname, st->name,
                                &metric_store, st->last_update);
                break;
                status = sdb_plugin_store_metric(st->hostname, st->name,
                                &metric_store, st->last_update);
                break;
@@ -222,7 +225,7 @@ exec_store(sdb_ast_store_t *st, sdb_strbuf_t *buf, sdb_strbuf_t *errbuf)
 static int
 exec_timeseries(sdb_ast_timeseries_t *ts, sdb_strbuf_t *buf, sdb_strbuf_t *errbuf)
 {
 static int
 exec_timeseries(sdb_ast_timeseries_t *ts, sdb_strbuf_t *buf, sdb_strbuf_t *errbuf)
 {
-       metric_store_t st = { NULL, NULL };
+       metric_store_t st = { NULL, NULL, 0 };
        sdb_object_wrapper_t obj = SDB_OBJECT_WRAPPER_STATIC(&st);
        sdb_ast_fetch_t fetch = SDB_AST_FETCH_INIT;
        sdb_timeseries_opts_t opts = { 0, 0 };
        sdb_object_wrapper_t obj = SDB_OBJECT_WRAPPER_STATIC(&st);
        sdb_ast_fetch_t fetch = SDB_AST_FETCH_INIT;
        sdb_timeseries_opts_t opts = { 0, 0 };
index 7a9a209b788d0f2d9c616ff3550e66eb09fb4f3d..e432cab428130252e517b72b0855fc210468c5c7 100644 (file)
@@ -125,6 +125,7 @@ typedef struct {
 typedef struct {
        const char *type;
        const char *id;
 typedef struct {
        const char *type;
        const char *id;
+       sdb_time_t last_update;
 } sdb_metric_store_t;
 
 /*
 } sdb_metric_store_t;
 
 /*
@@ -140,7 +141,7 @@ typedef struct {
        const char * const *backends;
        size_t backends_num;
 } sdb_store_metric_t;
        const char * const *backends;
        size_t backends_num;
 } sdb_store_metric_t;
-#define SDB_STORE_METRIC_INIT { NULL, NULL, { NULL, NULL }, 0, 0, NULL, 0 }
+#define SDB_STORE_METRIC_INIT { NULL, NULL, { NULL, NULL, 0 }, 0, 0, NULL, 0 }
 
 /*
  * sdb_store_attribute_t represents a stored attribute.
 
 /*
  * sdb_store_attribute_t represents a stored attribute.
index 73bca12e0c8691e939b9dcc3e4018216bfdf9dc1..54df202fbecaa32aad705b32fe5b52440aa85dac 100644 (file)
@@ -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];
 
        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 };
+       sdb_metric_store_t store = { ud->ts_type, metric_id, last_update };
 
        sdb_data_t data = { SDB_TYPE_STRING, { .string = NULL } };
 
 
        sdb_data_t data = { SDB_TYPE_STRING, { .string = NULL } };
 
index 87c86a84f08d4f896ca50d79cc6c38d7879b8367..fa48728120b611efa075081a1571696b88499fde 100644 (file)
@@ -57,21 +57,21 @@ static struct {
        sdb_metric_store_t store;
 } metrics[] = {
        { "some.host.name", "foo/bar/qux",
        sdb_metric_store_t store;
 } metrics[] = {
        { "some.host.name", "foo/bar/qux",
-               { "mock", "/var/lib/collectd/rrd/foo/bar/qux.rrd" } },
+               { "mock", "/var/lib/collectd/rrd/foo/bar/qux.rrd", 0 } },
        { "some.host.name", "foo/bar/baz",
        { "some.host.name", "foo/bar/baz",
-               { "mock", "/var/lib/collectd/rrd/foo/bar/baz.rrd" } },
+               { "mock", "/var/lib/collectd/rrd/foo/bar/baz.rrd", 0 } },
        { "some.host.name", "foo2/bar/qux",
        { "some.host.name", "foo2/bar/qux",
-               { "mock", "/var/lib/collectd/rrd/foo2/bar/qux.rrd" } },
+               { "mock", "/var/lib/collectd/rrd/foo2/bar/qux.rrd", 0 } },
        { "some.host.name", "foo2/bar/baz",
        { "some.host.name", "foo2/bar/baz",
-               { "mock", "/var/lib/collectd/rrd/foo2/bar/baz.rrd" } },
+               { "mock", "/var/lib/collectd/rrd/foo2/bar/baz.rrd", 0 } },
        { "other.host.name", "foo/bar/qux",
        { "other.host.name", "foo/bar/qux",
-               { "mock", "/var/lib/collectd/rrd/foo/bar/qux.rrd" } },
+               { "mock", "/var/lib/collectd/rrd/foo/bar/qux.rrd", 0 } },
        { "other.host.name", "foo/bar/baz",
        { "other.host.name", "foo/bar/baz",
-               { "mock", "/var/lib/collectd/rrd/foo/bar/baz.rrd" } },
+               { "mock", "/var/lib/collectd/rrd/foo/bar/baz.rrd", 0 } },
        { "other.host.name", "foo2/bar/qux",
        { "other.host.name", "foo2/bar/qux",
-               { "mock", "/var/lib/collectd/rrd/foo2/bar/qux.rrd" } },
+               { "mock", "/var/lib/collectd/rrd/foo2/bar/qux.rrd", 0 } },
        { "other.host.name", "foo2/bar/baz",
        { "other.host.name", "foo2/bar/baz",
-               { "mock", "/var/lib/collectd/rrd/foo2/bar/baz.rrd" } },
+               { "mock", "/var/lib/collectd/rrd/foo2/bar/baz.rrd", 0 } },
 };
 
 static struct {
 };
 
 static struct {
index 50d041ece884464501cd1768c2b6a990216a3662..96ac0c1d67356eabbb59d885a75d2be6f1b48398 100644 (file)
@@ -239,8 +239,8 @@ END_TEST
 
 START_TEST(test_store_metric)
 {
 
 START_TEST(test_store_metric)
 {
-       sdb_metric_store_t store1 = { "dummy-type1", "dummy-id1" };
-       sdb_metric_store_t store2 = { "dummy-type2", "dummy-id2" };
+       sdb_metric_store_t store1 = { "dummy-type1", "dummy-id1", 0 };
+       sdb_metric_store_t store2 = { "dummy-type2", "dummy-id2", 0 };
 
        struct {
                const char *host;
 
        struct {
                const char *host;
@@ -280,6 +280,16 @@ START_TEST(test_store_metric)
                                golden_data[i].host, golden_data[i].metric,
                                golden_data[i].store, golden_data[i].last_update,
                                status, golden_data[i].expected);
                                golden_data[i].host, golden_data[i].metric,
                                golden_data[i].store, golden_data[i].last_update,
                                status, golden_data[i].expected);
+
+               if (status < 0)
+                       continue;
+
+               if (golden_data[i].store != NULL)
+                       fail_unless(golden_data[i].store->last_update > 0,
+                                       "sdb_memstore_metric(%s, %s, %p, %d, 0) did not update "
+                                       "store->last_update",
+                                       golden_data[i].host, golden_data[i].metric,
+                                       golden_data[i].store, golden_data[i].last_update);
        }
 }
 END_TEST
        }
 }
 END_TEST