AC_PROG_INSTALL
AC_PROG_LEX
AC_PROG_YACC
+PKG_PROG_PKG_CONFIG
AM_CONDITIONAL(COMPILER_IS_GCC, test "x$GCC" = "xyes")
#
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)
var c4 =
{
- instances: []
+ instances: new Array (),
+ config:
+ {
+ width: 324,
+ height: 200
+ }
};
function value_to_string (value) /* {{{ */
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)
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 ("<ul id=\"search-suggest\" class=\"graph_list\"></ul>"); */
$("#search-form").append ("<ul id=\"search-suggest\" class=\"graph_list\"></ul>");
);
});
+ graph_recalc_width ();
+
var i;
for (i = 0; i < c4.instances.length; i++)
{
.graph-json
{
clear: both;
- width: 600px;
- height: 300px;
+ width: 324px;
+ height: 200px;
}
div.footer
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 \
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)
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;
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;
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 = " ";
printf ("\n");
status = inst_data_to_json (inst,
- dp_begin, dp_end, handler);
+ dp_begin, dp_end, dp_resolution, handler);
yajl_gen_free (handler);
--- /dev/null
+/**
+ * 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 <ff at octo.it>
+ **/
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+
+#include "action_list_graphs_json.h"
+#include "common.h"
+#include "graph.h"
+#include "graph_list.h"
+#include "utils_cgi.h"
+
+#include <fcgiapp.h>
+#include <fcgi_stdio.h>
+
+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 : */
--- /dev/null
+/**
+ * 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 <ff at octo.it>
+ **/
+
+#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 : */
--- /dev/null
+/**
+ * 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 <ff at octo.it>
+ **/
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+
+#include "action_list_hosts_json.h"
+#include "common.h"
+#include "graph.h"
+#include "graph_list.h"
+#include "utils_cgi.h"
+
+#include <fcgiapp.h>
+#include <fcgi_stdio.h>
+
+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 : */
--- /dev/null
+/**
+ * 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 <ff at octo.it>
+ **/
+
+#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 : */
/**
* 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
**/
#include <stdlib.h>
+#include <string.h>
#include <errno.h>
+#include <assert.h>
#include "data_provider.h"
#include "dp_rrdtool.h"
+#include "graph_ident.h"
#include <fcgiapp.h>
#include <fcgi_stdio.h>
+#include <collectd/client.h>
+
/* 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. */
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 */
#include <sys/types.h>
#include <sys/stat.h>
#include <math.h>
+#include <assert.h>
#include "graph_ident.h"
#include "common.h"
{
char buffer[PATH_MAX];
+ if (ident == NULL)
+ return (NULL);
+
buffer[0] = 0;
strlcat (buffer, ident->host, sizeof (buffer));
{
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;
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)
{
} /* }}} 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;
data.begin = begin;
data.end = end;
+ data.interval = res;
data.handler = handler;
/* Iterate over all DS names */
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,
} /* }}} 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);
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,
#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"
{ "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 },
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);