Merge remote-tracking branch 'github/master'
authorFlorian Forster <octo@verplant.org>
Tue, 5 Jun 2012 15:05:34 +0000 (17:05 +0200)
committerFlorian Forster <octo@verplant.org>
Tue, 5 Jun 2012 15:05:34 +0000 (17:05 +0200)
15 files changed:
configure.ac
share/collection.js
share/style.css
src/Makefile.am
src/action_instance_data_json.c
src/action_list_graphs_json.c [new file with mode: 0644]
src/action_list_graphs_json.h [new file with mode: 0644]
src/action_list_hosts_json.c [new file with mode: 0644]
src/action_list_hosts_json.h [new file with mode: 0644]
src/data_provider.c
src/graph_ident.c
src/graph_ident.h
src/graph_instance.c
src/graph_instance.h
src/main.c

index ebbc6c6..e27fd54 100644 (file)
@@ -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)
index 158a36e..e1764ac 100644 (file)
 
 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 ("<ul id=\"search-suggest\" class=\"graph_list\"></ul>"); */
     $("#search-form").append ("<ul id=\"search-suggest\" class=\"graph_list\"></ul>");
@@ -694,6 +720,8 @@ $(document).ready(function() {
         );
     });
 
+    graph_recalc_width ();
+
     var i;
     for (i = 0; i < c4.instances.length; i++)
     {
index d1db941..fbcd163 100644 (file)
@@ -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
index 766331f..adfa023 100644 (file)
@@ -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)
index 53823f3..a2de10e 100644 (file)
@@ -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 (file)
index 0000000..f8485ce
--- /dev/null
@@ -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 <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 : */
diff --git a/src/action_list_graphs_json.h b/src/action_list_graphs_json.h
new file mode 100644 (file)
index 0000000..ff65e34
--- /dev/null
@@ -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 <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 : */
diff --git a/src/action_list_hosts_json.c b/src/action_list_hosts_json.c
new file mode 100644 (file)
index 0000000..419d44c
--- /dev/null
@@ -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 <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 : */
diff --git a/src/action_list_hosts_json.h b/src/action_list_hosts_json.h
new file mode 100644 (file)
index 0000000..a96abd5
--- /dev/null
@@ -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 <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 : */
index 0236443..73630f2 100644 (file)
@@ -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
  **/
 
 #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. */
@@ -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 */
index 02e1aaa..5c513ec 100644 (file)
@@ -33,6 +33,7 @@
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <math.h>
+#include <assert.h>
 
 #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 */
index 5f7b2d4..9cbd08a 100644 (file)
@@ -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,
index 2249cc0..f2bb3ba 100644 (file)
@@ -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);
index 5685853..37c6b69 100644 (file)
@@ -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,
index 0722403..896a612 100644 (file)
@@ -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);