From 1bde17786b9a0b342daae5faa46a54b3eeab6558 Mon Sep 17 00:00:00 2001 From: Sebastian Harl Date: Sun, 4 Sep 2016 12:53:29 -0400 Subject: [PATCH] Store a separate last_update timestamp for metric stores. 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 | 1 + src/core/memstore.c | 12 +++++++++++- src/core/plugin.c | 3 +++ src/frontend/query.c | 5 ++++- src/include/core/store.h | 3 ++- src/plugins/backend/collectd/unixsock.c | 2 +- t/integration/mock_plugin.c | 16 ++++++++-------- t/unit/core/store_test.c | 14 ++++++++++++-- 8 files changed, 42 insertions(+), 14 deletions(-) diff --git a/src/core/memstore-private.h b/src/core/memstore-private.h index cd0152d..1afb66a 100644 --- a/src/core/memstore-private.h +++ b/src/core/memstore-private.h @@ -87,6 +87,7 @@ typedef struct { struct { char *type; char *id; + sdb_time_t last_update; } store; } metric_t; #define METRIC(obj) ((metric_t *)(obj)) diff --git a/src/core/memstore.c b/src/core/memstore.c index 05c879b..317a176 100644 --- a/src/core/memstore.c +++ b/src/core/memstore.c @@ -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; + 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; @@ -428,6 +433,7 @@ store_metric_store(metric_t *metric, sdb_store_metric_t *m) free(metric->store.id); metric->store.id = id; } + metric->store.last_update = m->store.last_update; 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 = { - 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; + metric.store.last_update = metric_store->last_update; } 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.last_update, }, obj->last_update, obj->interval, diff --git a/src/core/plugin.c b/src/core/plugin.c index 76b0b1e..92fa886 100644 --- a/src/core/plugin.c +++ b/src/core/plugin.c @@ -1733,8 +1733,11 @@ sdb_plugin_store_metric(const char *hostname, const char *name, 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.last_update = store->last_update; } metric.last_update = last_update ? last_update : sdb_gettime(); if (get_interval(SDB_METRIC, cname, -1, NULL, name, diff --git a/src/frontend/query.c b/src/frontend/query.c index f8d6a1f..5d00636 100644 --- a/src/frontend/query.c +++ b/src/frontend/query.c @@ -51,6 +51,7 @@ typedef struct { char *type; char *id; + sdb_time_t last_update; } 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->last_update = metric->store.last_update; 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; + metric_store.last_update = st->last_update; 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) { - 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 }; diff --git a/src/include/core/store.h b/src/include/core/store.h index 7a9a209..e432cab 100644 --- a/src/include/core/store.h +++ b/src/include/core/store.h @@ -125,6 +125,7 @@ typedef struct { typedef struct { const char *type; const char *id; + sdb_time_t last_update; } sdb_metric_store_t; /* @@ -140,7 +141,7 @@ typedef struct { 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. diff --git a/src/plugins/backend/collectd/unixsock.c b/src/plugins/backend/collectd/unixsock.c index 73bca12..54df202 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 }; + sdb_metric_store_t store = { ud->ts_type, metric_id, 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 87c86a8..fa48728 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" } }, + { "mock", "/var/lib/collectd/rrd/foo/bar/qux.rrd", 0 } }, { "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", - { "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", - { "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", - { "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", - { "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", - { "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", - { "mock", "/var/lib/collectd/rrd/foo2/bar/baz.rrd" } }, + { "mock", "/var/lib/collectd/rrd/foo2/bar/baz.rrd", 0 } }, }; static struct { diff --git a/t/unit/core/store_test.c b/t/unit/core/store_test.c index 50d041e..96ac0c1 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" }; - 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; @@ -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); + + 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 -- 2.30.2