2 * collection4 - data_provider.h
3 * Copyright (C) 2010 Florian octo Forster
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 * Boston, MA 02110-1301 USA
21 * Florian octo Forster <ff at octo.it>
35 #include "graph_types.h"
36 #include "graph_ident.h"
37 #include "data_provider.h"
38 #include "filesystem.h"
43 #include <fcgi_stdio.h>
49 typedef struct dp_rrdtool_s dp_rrdtool_t;
51 struct dp_get_idents_data_s
54 dp_get_idents_callback callback;
57 typedef struct dp_get_idents_data_s dp_get_idents_data_t;
59 static int scan_type_cb (__attribute__((unused)) const char *base_dir,
60 const char *file, void *ud)
62 dp_get_idents_data_t *data = ud;
68 file_len = strlen (file);
72 /* Ignore files that don't end in ".rrd". */
73 if (strcasecmp (".rrd", file + (file_len - 4)) != 0)
76 strncpy (type_copy, file, sizeof (type_copy));
77 type_copy_len = file_len - 4;
78 if (type_copy_len > (sizeof (type_copy) - 1))
79 type_copy_len = sizeof (type_copy) - 1;
80 type_copy[type_copy_len] = 0;
82 type_inst = strchr (type_copy, '-');
83 if (type_inst != NULL)
93 ident_set_type (data->ident, type_copy);
94 ident_set_type_instance (data->ident, type_inst);
96 return (data->callback (data->ident, data->user_data));
97 } /* }}} int scan_type_cb */
99 static int scan_plugin_cb (const char *base_dir,
100 const char *sub_dir, void *ud)
102 char plugin_copy[1024];
105 dp_get_idents_data_t *data = ud;
106 char abs_dir[PATH_MAX + 1];
108 strncpy (plugin_copy, sub_dir, sizeof (plugin_copy));
109 plugin_copy[sizeof (plugin_copy) - 1] = 0;
111 plugin_inst = strchr (plugin_copy, '-');
112 if (plugin_inst != NULL)
122 ident_set_plugin (data->ident, plugin_copy);
123 ident_set_plugin_instance (data->ident, plugin_inst);
125 snprintf (abs_dir, sizeof (abs_dir), "%s/%s", base_dir, sub_dir);
126 abs_dir[sizeof (abs_dir) - 1] = 0;
128 return (fs_foreach_file (abs_dir, scan_type_cb, data));
129 } /* }}} int scan_host_cb */
131 static int scan_host_cb (const char *base_dir,
132 const char *sub_dir, void *ud)
134 dp_get_idents_data_t *data = ud;
135 char abs_dir[PATH_MAX + 1];
137 ident_set_host (data->ident, sub_dir);
139 snprintf (abs_dir, sizeof (abs_dir), "%s/%s", base_dir, sub_dir);
140 abs_dir[sizeof (abs_dir) - 1] = 0;
142 return (fs_foreach_dir (abs_dir, scan_plugin_cb, data));
143 } /* }}} int scan_host_cb */
145 static int ident_to_rrdfile (const graph_ident_t *ident, /* {{{ */
146 dp_rrdtool_t *config,
147 char *buffer, size_t buffer_size)
149 const char *plugin_instance;
150 const char *type_instance;
152 plugin_instance = ident_get_plugin_instance (ident);
153 if ((plugin_instance != NULL) && (plugin_instance[0] == 0))
154 plugin_instance = NULL;
156 type_instance = ident_get_type_instance (ident);
157 if ((type_instance != NULL) && (type_instance[0] == 0))
158 type_instance = NULL;
162 strlcat (buffer, config->data_dir, buffer_size);
163 strlcat (buffer, "/", buffer_size);
165 strlcat (buffer, ident_get_host (ident), buffer_size);
166 strlcat (buffer, "/", buffer_size);
167 strlcat (buffer, ident_get_plugin (ident), buffer_size);
168 if (plugin_instance != NULL)
170 strlcat (buffer, "-", buffer_size);
171 strlcat (buffer, plugin_instance, buffer_size);
173 strlcat (buffer, "/", buffer_size);
174 strlcat (buffer, ident_get_type (ident), buffer_size);
175 if (type_instance != NULL)
177 strlcat (buffer, "-", buffer_size);
178 strlcat (buffer, type_instance, buffer_size);
181 strlcat (buffer, ".rrd", buffer_size);
184 } /* }}} int ident_to_rrdfile */
189 static int get_idents (void *priv,
190 dp_get_idents_callback cb, void *ud)
192 dp_rrdtool_t *config = priv;
193 dp_get_idents_data_t data;
196 data.ident = ident_create ("", "", "", "", "");
197 if (data.ident == NULL)
202 status = fs_foreach_dir (config->data_dir, scan_host_cb, &data);
204 ident_destroy (data.ident);
206 } /* }}} int get_idents */
208 static int get_ident_ds_names (void *priv, graph_ident_t *ident,
209 dp_list_get_ident_ds_names_callback cb, void *ud)
211 dp_rrdtool_t *config = priv;
212 char file[PATH_MAX + 1];
215 char *rrd_argv[] = { "info", file, NULL };
216 int rrd_argc = (sizeof (rrd_argv) / sizeof (rrd_argv[0])) - 1;
221 memset (file, 0, sizeof (file));
222 status = ident_to_rrdfile (ident, config, file, sizeof (file));
226 info = rrd_info (rrd_argc, rrd_argv);
229 fprintf (stderr, "%s: rrd_info (%s) failed.\n", __func__, file);
234 for (ptr = info; ptr != NULL; ptr = ptr->next)
240 if (ptr->key[0] != 'd')
243 if (strncmp ("ds[", ptr->key, strlen ("ds[")) != 0)
246 keylen = strlen (ptr->key);
247 if (keylen < strlen ("ds[?].type"))
250 dslen = keylen - strlen ("ds[].type");
253 if (strcmp ("].type", ptr->key + (strlen ("ds[") + dslen)) != 0)
256 ds = malloc (dslen + 1);
260 memcpy (ds, ptr->key + strlen ("ds["), dslen);
263 status = (*cb) (ident, ds, ud);
271 rrd_info_free (info);
274 } /* }}} int get_ident_ds_names */
276 static int get_ident_data (void *priv,
277 graph_ident_t *ident, const char *ds_name,
278 dp_time_t begin, dp_time_t end,
279 dp_get_ident_data_callback cb, void *ud)
281 dp_rrdtool_t *config = priv;
283 char filename[PATH_MAX + 1];
284 const char *cf = "AVERAGE"; /* FIXME */
288 unsigned long ds_count;
293 unsigned long ds_index;
294 unsigned long data_index;
295 unsigned long data_length;
297 dp_data_point_t *dp = NULL;
300 status = ident_to_rrdfile (ident, config, filename, sizeof (filename));
304 rrd_start = (time_t) begin.tv_sec;
305 rrd_end = (time_t) end.tv_sec;
311 status = rrd_fetch_r (filename, cf,
312 &rrd_start, &rrd_end,
313 &step, &ds_count, &ds_namv,
318 #define BAIL_OUT(ret_status) do { \
320 for (i = 0; i < ds_count; i++) \
325 return (ret_status); \
328 for (ds_index = 0; ds_index < ds_count; ds_index++)
329 if (strcmp (ds_name, ds_namv[ds_index]) == 0)
332 if (ds_index >= ds_count)
335 /* Number of data points returned. */
336 data_length = (rrd_end - rrd_start) / step;
338 dp_num = (size_t) data_length;
339 dp = calloc (dp_num, sizeof (*dp));
343 for (data_index = 0; data_index < data_length; data_index++)
345 unsigned long index = (ds_count * data_index) + ds_index;
347 dp[data_index].time.tv_sec = rrd_start + (data_index * step);
348 dp[data_index].time.tv_nsec = 0;
349 dp[data_index].value = (double) data[index];
352 status = (*cb) (ident, ds_name, dp, dp_num, ud);
358 } /* }}} int get_ident_data */
360 static int print_graph (void *priv,
361 graph_config_t *cfg, graph_instance_t *inst)
368 } /* }}} int print_graph */
370 int dp_rrdtool_config (const oconfig_item_t *ci)
380 /* private_data = */ NULL
383 /* FIXME: Actuelly do config parsing here. */
384 ci = NULL; /* FIXME */
385 conf = malloc (sizeof (dp_rrdtool_t));
386 conf->data_dir = strdup ("/var/lib/collectd/rrd");
388 dp.private_data = conf;
390 data_provider_register ("rrdtool", &dp);
393 } /* }}} int dp_rrdtool_config */
395 /* vim: set sw=2 sts=2 et fdm=marker : */