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)
109 {
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 : */