Code

timeseries::rrdtool: Added a plugin to fetch time-series from RRD files.
[sysdb.git] / src / plugins / timeseries / rrdtool.c
1 /*
2  * SysDB - src/plugins/timeseries/rrdtool.c
3  * Copyright (C) 2014 Sebastian 'tokkee' Harl <sh@tokkee.org>
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
17  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
18  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR
19  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
20  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
22  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
23  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
24  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
25  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26  */
28 #include "sysdb.h"
29 #include "core/plugin.h"
30 #include "utils/error.h"
32 #include <errno.h>
33 #include <rrd.h>
35 SDB_PLUGIN_MAGIC;
37 /*
38  * plugin API
39  */
41 static sdb_timeseries_t *
42 sdb_rrd_fetch(const char *id, sdb_timeseries_opts_t *opts,
43                 sdb_object_t __attribute__((unused)) *user_data)
44 {
45         sdb_timeseries_t *ts;
47         time_t start = (time_t)SDB_TIME_TO_SECS(opts->start);
48         time_t end = (time_t)SDB_TIME_TO_SECS(opts->end);
49         time_t t;
51         unsigned long step = 0;
52         unsigned long ds_cnt = 0;
53         unsigned long val_cnt = 0;
54         char **ds_namv = NULL;
55         rrd_value_t *data = NULL, *data_ptr;
57 #define FREE_RRD_DATA() \
58         do { \
59                 size_t i; \
60                 for (i = 0; i < ds_cnt; ++i) \
61                         rrd_freemem(ds_namv[i]); \
62                 rrd_freemem(ds_namv); \
63                 rrd_freemem(data); \
64         } while (0)
66         if (rrd_fetch_r(id, "AVERAGE", &start, &end, &step,
67                                 &ds_cnt, &ds_namv, &data)) {
68                 char errbuf[1024];
69                 sdb_strerror(errno, errbuf, sizeof(errbuf));
70                 sdb_log(SDB_LOG_ERR, "rrdtool plugin: Failed to fetch data "
71                                 "from %s: %s", id, errbuf);
72                 return NULL;
73         }
75         val_cnt = (unsigned long)(end - start) / step;
77         ts = sdb_timeseries_create(ds_cnt, (const char * const *)ds_namv, val_cnt);
78         if (! ts) {
79                 char errbuf[1024];
80                 sdb_strerror(errno, errbuf, sizeof(errbuf));
81                 sdb_log(SDB_LOG_ERR, "rrdtool plugin: Failed to allocate "
82                                 "time-series object: %s", errbuf);
83                 FREE_RRD_DATA();
84                 return NULL;
85         }
87         ts->start = SECS_TO_SDB_TIME(start + (time_t)step);
88         ts->end = SECS_TO_SDB_TIME(end);
90         data_ptr = data;
91         for (t = start + (time_t)step; t <= end; t += (time_t)step) {
92                 unsigned long i, j;
94                 i = (unsigned long)(t - start) / step - 1;
96                 for (j = 0; j < ds_cnt; ++j) {
97                         ts->data[j][i].timestamp = SECS_TO_SDB_TIME(t);
98                         ts->data[j][i].value = *data_ptr;
99                         ++data_ptr;
100                 }
101         }
103         FREE_RRD_DATA();
104         return ts;
105 } /* sdb_rrd_fetch */
107 int
108 sdb_module_init(sdb_plugin_info_t *info)
110         sdb_plugin_set_info(info, SDB_PLUGIN_INFO_DESC,
111                         "fetch time-series from RRD files");
112         sdb_plugin_set_info(info, SDB_PLUGIN_INFO_COPYRIGHT,
113                         "Copyright (C) 2014 Sebastian 'tokkee' Harl <sh@tokkee.org>");
114         sdb_plugin_set_info(info, SDB_PLUGIN_INFO_LICENSE, "BSD");
115         sdb_plugin_set_info(info, SDB_PLUGIN_INFO_VERSION, SDB_VERSION);
116         sdb_plugin_set_info(info, SDB_PLUGIN_INFO_PLUGIN_VERSION, SDB_VERSION);
118         sdb_plugin_register_ts_fetcher("rrdtool", sdb_rrd_fetch, NULL);
119         return 0;
120 } /* sdb_module_init */
122 /* vim: set tw=78 sw=4 ts=4 noexpandtab : */