From e7f963be66a9ee9bae65a11bd7f66d52d465271f Mon Sep 17 00:00:00 2001 From: Florian Forster Date: Sun, 2 May 2010 10:41:09 +0200 Subject: [PATCH] action graph: Added some code to determine the DS names from RRD files. --- Makefile | 2 +- action_graph.c | 201 ++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 201 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 54c269a..7bc84aa 100644 --- a/Makefile +++ b/Makefile @@ -21,7 +21,7 @@ action_list_graphs.o: action_list_graphs.c action_list_graphs.h test: test.c utils_params.o -test.fcgi: LDLIBS = -lfcgi +test.fcgi: LDLIBS = -lfcgi -lrrd test.fcgi: test.fcgi.c common.o graph_list.o utils_params.o action_graph.o action_list_graphs.o .PHONY: clean diff --git a/action_graph.c b/action_graph.c index afad488..38b1ec9 100644 --- a/action_graph.c +++ b/action_graph.c @@ -2,18 +2,217 @@ #include #include #include +#include +#include +#include /* for PATH_MAX */ +#include #include #include +#include + +#include "common.h" #include "action_graph.h" #include "graph_list.h" #include "utils_params.h" -int action_graph (void) +struct data_source_s +{ + char *file; + char *name; + char *legend; + double scale; + _Bool nan_to_zero; + _Bool draw_area; + uint32_t color; +}; +typedef struct data_source_s data_source_t; + +struct graph_def_s +{ + data_source_t *data_sources; + size_t data_sources_num; + + _Bool stack; +}; +typedef struct graph_def_s graph_def_t; + +static int graph_def_add_ds (graph_def_t *gd, /* {{{ */ + const char *file, + const char *in_ds_name, size_t ds_name_len) +{ + char ds_name[ds_name_len + 1]; + data_source_t *ds; + + strncpy (ds_name, in_ds_name, sizeof (ds_name)); + ds_name[sizeof (ds_name) - 1] = 0; + + ds = realloc (gd->data_sources, sizeof (*ds) * (gd->data_sources_num + 1)); + if (ds == NULL) + return (ENOMEM); + gd->data_sources = ds; + + ds = gd->data_sources + gd->data_sources_num; + memset (ds, 0, sizeof (*ds)); + + ds->file = strdup (file); + if (ds->file == NULL) + return (ENOMEM); + + ds->name = strdup (ds_name); + if (ds->name == NULL) + { + free (ds->file); + return (ENOMEM); + } + + ds->legend = NULL; + ds->color = 0xff0000; + + gd->data_sources_num++; + + return (0); +} /* }}} int graph_def_add_ds */ + +static graph_def_t *graph_def_from_rrd_file (char *file) /* {{{ */ +{ + char *rrd_argv[] = { "info", file, NULL }; + int rrd_argc = (sizeof (rrd_argv) / sizeof (rrd_argv[0])) - 1; + rrd_info_t *info; + rrd_info_t *ptr; + graph_def_t *gd; + + gd = malloc (sizeof (*gd)); + if (gd == NULL) + return (NULL); + memset (gd, 0, sizeof (*gd)); + + gd->data_sources = NULL; + + info = rrd_info (rrd_argc, rrd_argv); + if (info == NULL) + { + printf ("%s: rrd_info (%s) failed.\n", __func__, file); + free (gd); + return (NULL); + } + + for (ptr = info; ptr != NULL; ptr = ptr->next) + { + size_t keylen; + size_t dslen; + + if (strncmp ("ds[", ptr->key, strlen ("ds[")) != 0) + continue; + + keylen = strlen (ptr->key); + if (keylen < strlen ("ds[?].index")) + continue; + + dslen = keylen - strlen ("ds[].index"); + assert (dslen >= 1); + + if (strcmp ("].index", ptr->key + (strlen ("ds[") + dslen)) != 0) + continue; + + graph_def_add_ds (gd, file, ptr->key + strlen ("ds["), dslen); + } + + rrd_info_free (info); + + return (gd); +} /* }}} graph_def_t *graph_def_from_rrd_file */ + +static graph_def_t *graph_def_from_gl (const graph_list_t *gl) /* {{{ */ +{ + char rrd_file[PATH_MAX]; + + if ((gl->plugin_instance == NULL) && (gl->type_instance == NULL)) + snprintf (rrd_file, sizeof (rrd_file), "%s/%s/%s/%s.rrd", + DATA_DIR, gl->host, gl->plugin, gl->type); + else if (gl->type_instance == NULL) + snprintf (rrd_file, sizeof (rrd_file), "%s/%s/%s-%s/%s.rrd", + DATA_DIR, gl->host, gl->plugin, gl->plugin_instance, gl->type); + else if (gl->plugin_instance == NULL) + snprintf (rrd_file, sizeof (rrd_file), "%s/%s/%s/%s-%s.rrd", + DATA_DIR, gl->host, gl->plugin, gl->type, gl->type_instance); + else + snprintf (rrd_file, sizeof (rrd_file), "%s/%s/%s-%s/%s-%s.rrd", + DATA_DIR, gl->host, gl->plugin, gl->plugin_instance, + gl->type, gl->type_instance); + rrd_file[sizeof (rrd_file) - 1] = 0; + + printf ("rrd_file = %s;\n", rrd_file); + + return (graph_def_from_rrd_file (rrd_file)); +} /* }}} graph_def_t *graph_def_from_gl */ + +static int init_gl (graph_list_t *gl) /* {{{ */ +{ + gl->host = param ("host"); + gl->plugin = param ("plugin"); + gl->plugin_instance = param ("plugin_instance"); + gl->type = param ("type"); + gl->type_instance = param ("type_instance"); + + if ((gl->host == NULL) + || (gl->plugin == NULL) + || (gl->type == NULL)) + return (EINVAL); + + if ((gl->host[0] == 0) || (gl->host[0] == '.') + || (gl->plugin[0] == 0) || (gl->plugin[0] == '.') + || (gl->type[0] == 0) || (gl->type[0] == '.')) + return (EINVAL); + + if ((strchr (gl->plugin, '-') != NULL) + || (strchr (gl->type, '-') != NULL)) + return (EINVAL); + + if ((gl->plugin_instance != NULL) + && (gl->plugin_instance[0] == 0)) + gl->plugin_instance = NULL; + + if ((gl->type_instance != NULL) + && (gl->type_instance[0] == 0)) + gl->type_instance = NULL; + + return (0); +} /* }}} int init_gl */ + +int action_graph (void) /* {{{ */ { + graph_list_t gl; + graph_def_t *gd; + int status; + size_t i; + + memset (&gl, 0, sizeof (gl)); + status = init_gl (&gl); + if (status != 0) + { + printf ("Content-Type: text/plain\n\n" + "init_gl failed with status %i.\n", status); + return (status); + } + printf ("Content-Type: text/plain\n\n" "Hello, this is %s\n", __func__); + gd = graph_def_from_gl (&gl); + if (gd == NULL) + { + printf ("graph_def_from_gl failed.\n"); + return (0); + } + + for (i = 0; i < gd->data_sources_num; i++) + { + printf ("data source %lu: %s @ %s\n", + (unsigned long) i, gd->data_sources[i].name, gd->data_sources[i].file); + } + + /* FIXME: Free gd */ return (0); } /* }}} int action_graph */ -- 2.30.2