From: Florian Forster Date: Tue, 5 Jun 2012 15:05:34 +0000 (+0200) Subject: Merge remote-tracking branch 'github/master' X-Git-Url: https://git.octo.it/?p=collection4.git;a=commitdiff_plain;h=a7babc69db47718d5e0cc1af48bafaf8eea7c3d1;hp=4b4a4c4848832b5aec34d01bcf11415302281dc1 Merge remote-tracking branch 'github/master' --- diff --git a/configure.ac b/configure.ac index ebbc6c6..e27fd54 100644 --- a/configure.ac +++ b/configure.ac @@ -14,6 +14,7 @@ AC_PROG_CPP AC_PROG_INSTALL AC_PROG_LEX AC_PROG_YACC +PKG_PROG_PKG_CONFIG AM_CONDITIONAL(COMPILER_IS_GCC, test "x$GCC" = "xyes") # @@ -32,4 +33,8 @@ AC_CHECK_LIB(rrd_th, rrd_graph_v, [], AC_CHECK_LIB(yajl, yajl_gen_alloc, [], [AC_MSG_ERROR(cannot find libyajl.)]) +PKG_CHECK_MODULES([libcollectdclient], [libcollectdclient], + [with_libcollectdclient="yes"], + [with_libcollectdclient="no"]) + AC_OUTPUT(Makefile share/Makefile src/Makefile) diff --git a/share/collection.js b/share/collection.js index 158a36e..e1764ac 100644 --- a/share/collection.js +++ b/share/collection.js @@ -23,7 +23,12 @@ var c4 = { - instances: [] + instances: new Array (), + config: + { + width: 324, + height: 200 + } }; function value_to_string (value) /* {{{ */ @@ -423,6 +428,7 @@ function inst_fetch_data (inst, begin, end) /* {{{ */ params.action = "instance_data_json"; params.begin = begin || inst.begin; params.end = end || inst.end; + params.resolution = (params.end - params.begin) / c4.config.width; $.getJSON ("collection.fcgi", params, function (data) @@ -630,6 +636,26 @@ function zoom_out (graph_id) /* {{{ */ return (zoom_relative (graph_id, (-1.0 / 3.0), (1.0 / 3.0))); } /* }}} function zoom_earlier */ +function graph_recalc_width () /* {{{ */ +{ + var tmp; + + tmp = $("#layout-middle-center").width (); + if (!tmp) + return; + + if (tmp < 324) + tmp = 324; + + c4.config.width = tmp; + c4.config.height = Math.round (tmp / 1.61803398874989484820); + $(".graph-json").each (function () + { + $(this).width (c4.config.width); + $(this).height (c4.config.height); + }); +} /* }}} function graph_recalc_width */ + $(document).ready(function() { /* $("#layout-middle-right").html (""); */ $("#search-form").append (""); @@ -694,6 +720,8 @@ $(document).ready(function() { ); }); + graph_recalc_width (); + var i; for (i = 0; i < c4.instances.length; i++) { diff --git a/share/style.css b/share/style.css index d1db941..fbcd163 100644 --- a/share/style.css +++ b/share/style.css @@ -238,8 +238,8 @@ div.graph-img:hover div.graph-buttons .graph-json { clear: both; - width: 600px; - height: 300px; + width: 324px; + height: 200px; } div.footer diff --git a/src/Makefile.am b/src/Makefile.am index 766331f..adfa023 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -19,7 +19,9 @@ collection_fcgi_SOURCES = main.c \ action_instance_data_json.c action_instance_data_json.h \ action_graph_def_json.c action_graph_def_json.h \ action_list_graphs.c action_list_graphs.h \ + action_list_graphs_json.c action_list_graphs_json.h \ action_list_hosts.c action_list_hosts.h \ + action_list_hosts_json.c action_list_hosts_json.h \ action_search.c action_search.h \ action_search_json.c action_search_json.h \ action_show_graph.c action_show_graph.h \ @@ -40,3 +42,5 @@ collection_fcgi_SOURCES = main.c \ utils_array.c utils_array.h \ utils_cgi.c utils_cgi.h \ utils_search.c utils_search.h +collection_fcgi_CFLAGS = $(AM_CFLAGS) $(libcollectdclient_CFLAGS) +collection_fcgi_LDADD = $(libcollectdclient_LIBS) diff --git a/src/action_instance_data_json.c b/src/action_instance_data_json.c index 53823f3..a2de10e 100644 --- a/src/action_instance_data_json.c +++ b/src/action_instance_data_json.c @@ -48,6 +48,29 @@ static void write_callback (__attribute__((unused)) void *ctx, /* {{{ */ fwrite ((void *) str, /* size = */ len, /* nmemb = */ 1, stdout); } /* }}} void write_callback */ +static int param_get_resolution (dp_time_t *resolution) /* {{{ */ +{ + const char *tmp; + char *endptr; + double value; + + tmp = param ("resolution"); + if (tmp == NULL) + return (ENOENT); + + errno = 0; + endptr = NULL; + value = strtod (tmp, &endptr); + if (errno != 0) + return (errno); + else if ((value <= 0.0) || (endptr == tmp)) + return (EINVAL); + + resolution->tv_sec = (time_t) value; + resolution->tv_nsec = (long) ((value - ((double) resolution->tv_sec)) * 1000000000.0); + return (0); +} /* }}} int param_get_resolution */ + int action_instance_data_json (void) /* {{{ */ { graph_config_t *cfg; @@ -59,6 +82,7 @@ int action_instance_data_json (void) /* {{{ */ dp_time_t dp_begin = { 0, 0 }; dp_time_t dp_end = { 0, 0 }; + dp_time_t dp_resolution = { 0, 0 }; yajl_gen_config handler_config; yajl_gen handler; @@ -86,6 +110,9 @@ int action_instance_data_json (void) /* {{{ */ dp_end.tv_sec = tt_end; dp_end.tv_nsec = 0; + dp_resolution.tv_sec = (tt_end - tt_begin) / 324; + param_get_resolution (&dp_resolution); + memset (&handler_config, 0, sizeof (handler_config)); handler_config.beautify = 0; handler_config.indentString = " "; @@ -114,7 +141,7 @@ int action_instance_data_json (void) /* {{{ */ printf ("\n"); status = inst_data_to_json (inst, - dp_begin, dp_end, handler); + dp_begin, dp_end, dp_resolution, handler); yajl_gen_free (handler); diff --git a/src/action_list_graphs_json.c b/src/action_list_graphs_json.c new file mode 100644 index 0000000..f8485ce --- /dev/null +++ b/src/action_list_graphs_json.c @@ -0,0 +1,152 @@ +/** + * collection4 - action_list_graphs_json.c + * Copyright (C) 2010,2011 Florian octo Forster + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + * + * Authors: + * Florian octo Forster + **/ + +#include +#include +#include +#include + +#include "action_list_graphs_json.h" +#include "common.h" +#include "graph.h" +#include "graph_list.h" +#include "utils_cgi.h" + +#include +#include + +static void write_callback (__attribute__((unused)) void *ctx, /* {{{ */ + const char *str, unsigned int len) +{ + fwrite ((void *) str, /* size = */ len, /* nmemb = */ 1, stdout); +} /* }}} void write_callback */ + +static int print_one_graph (graph_config_t *cfg, /* {{{ */ + void *user_data) +{ + char title[1024]; + size_t num_instances; + graph_ident_t *selector; + + yajl_gen handler = user_data; + + num_instances = graph_num_instances (cfg); + if (num_instances < 1) + return (0); + + selector = graph_get_selector (cfg); + if (selector == NULL) + { + /* TODO: Print error. */ + return (0); + } + + yajl_gen_map_open (handler); + + memset (title, 0, sizeof (title)); + graph_get_title (cfg, title, sizeof (title)); + + yajl_gen_string (handler, + (unsigned char *) "title", + (unsigned int) strlen ("title")); + yajl_gen_string (handler, + (unsigned char *) title, + (unsigned int) strlen (title)); + + yajl_gen_string (handler, + (unsigned char *) "selector", + (unsigned int) strlen ("selector")); + ident_to_json (selector, handler); + + yajl_gen_string (handler, + (unsigned char *) "num_instances", + (unsigned int) strlen ("num_instances")); + yajl_gen_integer (handler, (long int) num_instances); + + yajl_gen_map_close (handler); + + ident_destroy (selector); + + return (0); +} /* }}} int print_one_graph */ + +static int print_all_graphs (yajl_gen handler) /* {{{ */ +{ + const char *dynamic; + _Bool include_dynamic = 0; + + dynamic = param ("dynamic"); + if ((dynamic != NULL) + && (strcmp ("true", dynamic) == 0)) + include_dynamic = 1; + + yajl_gen_array_open (handler); + + gl_graph_get_all (include_dynamic, print_one_graph, + /* user_data = */ handler); + + yajl_gen_array_close (handler); + + return (0); +} /* }}} int print_all_graphs */ + +int action_list_graphs_json (void) /* {{{ */ +{ + graph_config_t *cfg; + + yajl_gen_config handler_config; + yajl_gen handler; + + time_t now; + char time_buffer[128]; + int status; + + memset (&handler_config, 0, sizeof (handler_config)); + handler_config.beautify = 1; + handler_config.indentString = " "; + + handler = yajl_gen_alloc2 (write_callback, + &handler_config, + /* alloc functions = */ NULL, + /* context = */ NULL); + if (handler == NULL) + return (-1); + + printf ("Content-Type: application/json\n"); + + now = time (NULL); + status = time_to_rfc1123 (now + 300, time_buffer, sizeof (time_buffer)); + if (status == 0) + printf ("Expires: %s\n" + "Cache-Control: public\n", + time_buffer); + printf ("\n"); + + print_all_graphs (handler); + + yajl_gen_free (handler); + + return (status); +} /* }}} int action_list_graphs_json */ + +/* vim: set sw=2 sts=2 et fdm=marker : */ diff --git a/src/action_list_graphs_json.h b/src/action_list_graphs_json.h new file mode 100644 index 0000000..ff65e34 --- /dev/null +++ b/src/action_list_graphs_json.h @@ -0,0 +1,30 @@ +/** + * collection4 - action_list_graphs_json.h + * Copyright (C) 2010,2011 Florian octo Forster + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + * + * Authors: + * Florian octo Forster + **/ + +#ifndef ACTION_LIST_GRAPHS_JSON_H +#define ACTION_LIST_GRAPHS_JSON_H 1 + +int action_list_graphs_json (void); + +#endif /* ACTION_LIST_GRAPHS_JSON_H */ +/* vim: set sw=2 sts=2 et fdm=marker : */ diff --git a/src/action_list_hosts_json.c b/src/action_list_hosts_json.c new file mode 100644 index 0000000..419d44c --- /dev/null +++ b/src/action_list_hosts_json.c @@ -0,0 +1,109 @@ +/** + * collection4 - action_list_hosts_json.c + * Copyright (C) 2010,2011 Florian octo Forster + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + * + * Authors: + * Florian octo Forster + **/ + +#include +#include +#include +#include + +#include "action_list_hosts_json.h" +#include "common.h" +#include "graph.h" +#include "graph_list.h" +#include "utils_cgi.h" + +#include +#include + +static void write_callback (__attribute__((unused)) void *ctx, /* {{{ */ + const char *str, unsigned int len) +{ + fwrite ((void *) str, /* size = */ len, /* nmemb = */ 1, stdout); +} /* }}} void write_callback */ + +static int print_one_host (const char *host, /* {{{ */ + void *user_data) +{ + yajl_gen handler = user_data; + + yajl_gen_map_open (handler); + + yajl_gen_string (handler, + (unsigned char *) "host", + (unsigned int) strlen ("host")); + yajl_gen_string (handler, + (unsigned char *) host, + (unsigned int) strlen (host)); + + yajl_gen_map_close (handler); + + return (0); +} /* }}} int print_one_host */ + +static int print_all_hosts (yajl_gen handler) /* {{{ */ +{ + yajl_gen_array_open (handler); + gl_foreach_host (print_one_host, /* user_data = */ handler); + yajl_gen_array_close (handler); + + return (0); +} /* }}} int print_all_hosts */ + +int action_list_hosts_json (void) /* {{{ */ +{ + yajl_gen_config handler_config; + yajl_gen handler; + + time_t now; + char time_buffer[128]; + int status; + + memset (&handler_config, 0, sizeof (handler_config)); + handler_config.beautify = 1; + handler_config.indentString = " "; + + handler = yajl_gen_alloc2 (write_callback, + &handler_config, + /* alloc functions = */ NULL, + /* context = */ NULL); + if (handler == NULL) + return (-1); + + printf ("Content-Type: application/json\n"); + + now = time (NULL); + status = time_to_rfc1123 (now + 300, time_buffer, sizeof (time_buffer)); + if (status == 0) + printf ("Expires: %s\n" + "Cache-Control: public\n", + time_buffer); + printf ("\n"); + + print_all_hosts (handler); + + yajl_gen_free (handler); + + return (status); +} /* }}} int action_list_hosts_json */ + +/* vim: set sw=2 sts=2 et fdm=marker : */ diff --git a/src/action_list_hosts_json.h b/src/action_list_hosts_json.h new file mode 100644 index 0000000..a96abd5 --- /dev/null +++ b/src/action_list_hosts_json.h @@ -0,0 +1,30 @@ +/** + * collection4 - action_list_hosts_json.h + * Copyright (C) 2010,2011 Florian octo Forster + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + * + * Authors: + * Florian octo Forster + **/ + +#ifndef ACTION_LIST_HOSTS_JSON_H +#define ACTION_LIST_HOSTS_JSON_H 1 + +int action_list_hosts_json (void); + +#endif /* ACTION_LIST_HOSTS_JSON_H */ +/* vim: set sw=2 sts=2 et fdm=marker : */ diff --git a/src/data_provider.c b/src/data_provider.c index 0236443..73630f2 100644 --- a/src/data_provider.c +++ b/src/data_provider.c @@ -1,6 +1,7 @@ /** * collection4 - data_provider.c * Copyright (C) 2010 Florian octo Forster + * Copyright (C) 2011 noris network AG * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -22,17 +23,85 @@ **/ #include +#include #include +#include #include "data_provider.h" #include "dp_rrdtool.h" +#include "graph_ident.h" #include #include +#include + /* TODO: Turn this into an array for multiple data providers. */ static data_provider_t *data_provider = NULL; +static lcc_connection_t *collectd_connection = NULL; + +static int data_provider_ident_flush (const graph_ident_t *ident) /* {{{ */ +{ + char *ident_str; + lcc_identifier_t ident_lcc; + int status; + + if (ident == NULL) + return (EINVAL); + + ident_str = ident_to_string (ident); + if (ident_str == NULL) + return (ENOMEM); + + if (collectd_connection == NULL) + { + /* TODO: Make socket path configurable */ + status = lcc_connect (/* path = */ "/var/run/collectd-unixsock", + &collectd_connection); + if (status != 0) + { + assert (collectd_connection == NULL); + fprintf (stderr, "data_provider_ident_flush: lcc_connect failed " + "with status %i.\n", status); + return (status); + } + assert (collectd_connection != NULL); + } + + memset (&ident_lcc, 0, sizeof (ident_lcc)); + status = lcc_string_to_identifier (collectd_connection, + &ident_lcc, ident_str); + if (status != 0) + { + fprintf (stderr, "data_provider_ident_flush: lcc_string_to_identifier " + "failed: %s (%i)\n", + lcc_strerror (collectd_connection), status); + free (ident_str); + return (status); + } + + status = lcc_flush (collectd_connection, + /* write-plugin = */ NULL, + /* identifier = */ &ident_lcc, + /* timeout = */ -1); + if (status != 0) + { + fprintf (stderr, "data_provider_ident_flush: lcc_flush (\"%s\") failed: %s (%i)\n", + ident_str, lcc_strerror (collectd_connection), status); + free (ident_str); + + lcc_disconnect (collectd_connection); + collectd_connection = NULL; + + return (status); + } + + /* fprintf (stderr, "data_provider_ident_flush: lcc_flush (\"%s\") succeeded.\n", ident_str); */ + free (ident_str); + return (0); +} /* }}} int data_provider_ident_flush */ + int data_provider_config (const oconfig_item_t *ci) /* {{{ */ { /* FIXME: Actually determine which data provider to call. */ @@ -87,6 +156,8 @@ int data_provider_get_ident_data (graph_ident_t *ident, /* {{{ */ if (data_provider == NULL) return (EINVAL); + data_provider_ident_flush (ident); + return (data_provider->get_ident_data (data_provider->private_data, ident, ds_name, begin, end, callback, user_data)); } /* }}} int data_provider_get_ident_data */ diff --git a/src/graph_ident.c b/src/graph_ident.c index 02e1aaa..5c513ec 100644 --- a/src/graph_ident.c +++ b/src/graph_ident.c @@ -33,6 +33,7 @@ #include #include #include +#include #include "graph_ident.h" #include "common.h" @@ -455,6 +456,9 @@ char *ident_to_string (const graph_ident_t *ident) /* {{{ */ { char buffer[PATH_MAX]; + if (ident == NULL) + return (NULL); + buffer[0] = 0; strlcat (buffer, ident->host, sizeof (buffer)); @@ -545,6 +549,7 @@ struct ident_data_to_json__data_s { dp_time_t begin; dp_time_t end; + dp_time_t interval; yajl_gen handler; }; typedef struct ident_data_to_json__data_s ident_data_to_json__data_t; @@ -564,21 +569,21 @@ static int ident_data_to_json__get_ident_data ( double first_value_time_double; double interval_double; - - /* TODO: Make points_num_limit configurable. */ - /* points_num_limit: The number of data-points to send at least. */ - size_t points_num_limit = 400; + double interval_requested; size_t points_consolidate; first_value_time_double = ((double) first_value_time.tv_sec) + (((double) first_value_time.tv_nsec) / 1000000000.0); interval_double = ((double) interval.tv_sec) + (((double) interval.tv_nsec) / 1000000000.0); + interval_requested = ((double) data->interval.tv_sec) + + (((double) data->interval.tv_nsec) / 1000000000.0); - if (data_points_num <= points_num_limit) + if (interval_requested < (2.0 * interval_double)) points_consolidate = 1; else - points_consolidate = data_points_num / points_num_limit; + points_consolidate = (size_t) (interval_requested / interval_double); + assert (points_consolidate >= 1); if (points_consolidate > 1) { @@ -654,7 +659,7 @@ static int ident_data_to_json__get_ds_name (graph_ident_t *ident, /* {{{ */ } /* }}} int ident_data_to_json__get_ds_name */ int ident_data_to_json (graph_ident_t *ident, /* {{{ */ - dp_time_t begin, dp_time_t end, + dp_time_t begin, dp_time_t end, dp_time_t res, yajl_gen handler) { ident_data_to_json__data_t data; @@ -662,6 +667,7 @@ int ident_data_to_json (graph_ident_t *ident, /* {{{ */ data.begin = begin; data.end = end; + data.interval = res; data.handler = handler; /* Iterate over all DS names */ diff --git a/src/graph_ident.h b/src/graph_ident.h index 5f7b2d4..9cbd08a 100644 --- a/src/graph_ident.h +++ b/src/graph_ident.h @@ -93,7 +93,7 @@ char *ident_to_file (const graph_ident_t *ident); int ident_to_json (const graph_ident_t *ident, yajl_gen handler); int ident_data_to_json (graph_ident_t *ident, - dp_time_t begin, dp_time_t end, + dp_time_t begin, dp_time_t end, dp_time_t interval, yajl_gen handler); int ident_describe (const graph_ident_t *ident, const graph_ident_t *selector, diff --git a/src/graph_instance.c b/src/graph_instance.c index 2249cc0..f2bb3ba 100644 --- a/src/graph_instance.c +++ b/src/graph_instance.c @@ -605,14 +605,14 @@ int inst_to_json (const graph_instance_t *inst, /* {{{ */ } /* }}} int inst_to_json */ int inst_data_to_json (const graph_instance_t *inst, /* {{{ */ - dp_time_t begin, dp_time_t end, + dp_time_t begin, dp_time_t end, dp_time_t res, yajl_gen handler) { size_t i; yajl_gen_array_open (handler); for (i = 0; i < inst->files_num; i++) - ident_data_to_json (inst->files[i], begin, end, handler); + ident_data_to_json (inst->files[i], begin, end, res, handler); yajl_gen_array_close (handler); return (0); diff --git a/src/graph_instance.h b/src/graph_instance.h index 5685853..37c6b69 100644 --- a/src/graph_instance.h +++ b/src/graph_instance.h @@ -86,7 +86,7 @@ _Bool inst_matches_field (graph_instance_t *inst, int inst_to_json (const graph_instance_t *inst, yajl_gen handler); int inst_data_to_json (const graph_instance_t *inst, - dp_time_t begin, dp_time_t end, + dp_time_t begin, dp_time_t end, dp_time_t res, yajl_gen handler); int inst_describe (graph_config_t *cfg, graph_instance_t *inst, diff --git a/src/main.c b/src/main.c index 0722403..896a612 100644 --- a/src/main.c +++ b/src/main.c @@ -40,7 +40,9 @@ #include "action_instance_data_json.h" #include "action_graph_def_json.h" #include "action_list_graphs.h" +#include "action_list_graphs_json.h" #include "action_list_hosts.h" +#include "action_list_hosts_json.h" #include "action_search.h" #include "action_search_json.h" #include "action_show_graph.h" @@ -67,7 +69,9 @@ static const action_t actions[] = { "instance_data_json", action_instance_data_json }, { "graph_def_json", action_graph_def_json }, { "list_graphs", action_list_graphs }, + { "list_graphs_json", action_list_graphs_json }, { "list_hosts", action_list_hosts }, + { "list_hosts_json", action_list_hosts_json }, { "search", action_search }, { "search_json", action_search_json }, { "show_graph", action_show_graph }, @@ -127,8 +131,9 @@ static int handle_request (void) /* {{{ */ if (i >= actions_num) status = action_usage (); - fflush (stdout); - fclose (stdout); + /* Call finish before updating the graph list, so clients don't wait for + * the update to finish. */ + FCGI_Finish (); gl_update (/* request_served = */ 1);