share/collection.conf: Add graph for "swap_io".
[collection4.git] / src / action_list_graphs.c
1 #include <stdlib.h>
2 #include <stdio.h>
3 #include <string.h>
4 #include <errno.h>
5
6 #include "action_list_graphs.h"
7 #include "common.h"
8 #include "graph.h"
9 #include "graph_ident.h"
10 #include "graph_instance.h"
11 #include "graph_list.h"
12 #include "utils_cgi.h"
13
14 #include <fcgiapp.h>
15 #include <fcgi_stdio.h>
16
17 #define RESULT_LIMIT 50
18
19 struct callback_data_s
20 {
21   graph_config_t *cfg;
22   int graph_index;
23   int graph_limit;
24   _Bool graph_more;
25   int inst_index;
26   int inst_limit;
27   _Bool inst_more;
28 };
29 typedef struct callback_data_s callback_data_t;
30
31 static int print_graph_inst_html (graph_config_t *cfg, /* {{{ */
32     graph_instance_t *inst,
33     void *user_data)
34 {
35   callback_data_t *data = user_data;
36   char params[1024];
37   char desc[1024];
38
39   if (data->cfg != cfg)
40   {
41     data->graph_index++;
42     if (data->graph_index >= data->graph_limit)
43     {
44       data->graph_more = 1;
45       return (1);
46     }
47
48     if (data->cfg != NULL)
49       printf ("  </ul></li>\n");
50
51     memset (desc, 0, sizeof (desc));
52     graph_get_title (cfg, desc, sizeof (desc));
53     html_escape_buffer (desc, sizeof (desc));
54
55     printf ("  <li class=\"graph\">%s\n"
56         "  <ul class=\"instance_list\">\n", desc);
57
58     data->cfg = cfg;
59     data->inst_index = -1;
60     data->inst_more = 0;
61   }
62
63   data->inst_index++;
64   if (data->inst_index >= data->inst_limit)
65   {
66     if (!data->inst_more)
67     {
68       printf ("    <li class=\"instance more\">More ...</li>\n");
69       data->inst_more = 1;
70     }
71     return (0);
72   }
73
74   memset (params, 0, sizeof (params));
75   inst_get_params (cfg, inst, params, sizeof (params));
76   html_escape_buffer (params, sizeof (params));
77
78   memset (desc, 0, sizeof (desc));
79   inst_describe (cfg, inst, desc, sizeof (desc));
80   html_escape_buffer (desc, sizeof (desc));
81
82   printf ("    <li class=\"instance\"><a href=\"%s?action=show_graph;%s\">%s</a></li>\n",
83       script_name (), params, desc);
84
85   return (0);
86 } /* }}} int print_graph_inst_html */
87
88 struct page_data_s
89 {
90   const char *search_term;
91 };
92 typedef struct page_data_s page_data_t;
93
94 static int print_search_result (void *user_data) /* {{{ */
95 {
96   page_data_t *pg_data = user_data;
97   callback_data_t cb_data = { /* cfg = */ NULL,
98     /* graph_index = */ -1, /* graph_limit = */ 20, /* graph_more = */ 0,
99     /* inst_index = */  -1, /* inst_limit = */   5, /* inst more = */  0 };
100
101   if (pg_data->search_term != NULL)
102   {
103     char *search_term_html = html_escape (pg_data->search_term);
104     printf ("    <h2>Search results for &quot;%s&quot;</h2>\n",
105         search_term_html);
106     free (search_term_html);
107   }
108
109   printf ("    <ul id=\"search-output\" class=\"graph_list\">\n");
110   if (pg_data->search_term == NULL)
111     gl_instance_get_all (print_graph_inst_html, /* user_data = */ &cb_data);
112   else
113   {
114     char *term_lc = strtolower_copy (pg_data->search_term);
115
116     if (strncmp ("host:", term_lc, strlen ("host:")) == 0)
117       gl_search_field (GIF_HOST, term_lc + strlen ("host:"),
118           print_graph_inst_html, /* user_data = */ &cb_data);
119     else if (strncmp ("plugin:", term_lc, strlen ("plugin:")) == 0)
120       gl_search_field (GIF_PLUGIN, term_lc + strlen ("plugin:"),
121           print_graph_inst_html, /* user_data = */ &cb_data);
122     else if (strncmp ("type:", term_lc, strlen ("type:")) == 0)
123       gl_search_field (GIF_TYPE, term_lc + strlen ("type:"),
124           print_graph_inst_html, /* user_data = */ &cb_data);
125     else
126       gl_search (term_lc,
127           print_graph_inst_html, /* user_data = */ &cb_data);
128
129     free (term_lc);
130   }
131
132   if (cb_data.cfg != NULL)
133     printf ("      </ul></li>\n");
134
135   if (cb_data.graph_more)
136   {
137     printf ("    <li class=\"graph more\">More ...</li>\n");
138   }
139
140   printf ("    </ul>\n");
141
142   return (0);
143 } /* }}} int print_search_result */
144
145 struct print_host_list_data_s
146 {
147   str_array_t *array;
148   char *last_host;
149 };
150 typedef struct print_host_list_data_s print_host_list_data_t;
151
152 static int print_host_list_callback (graph_config_t *cfg, /* {{{ */
153     graph_instance_t *inst, void *user_data)
154 {
155   print_host_list_data_t *data = user_data;
156   graph_ident_t *ident;
157   const char *host;
158
159   /* make compiler happy */
160   cfg = NULL;
161
162   ident = inst_get_selector (inst);
163   if (ident == NULL)
164     return (-1);
165
166   host = ident_get_host (ident);
167   if (host == NULL)
168   {
169     ident_destroy (ident);
170     return (-1);
171   }
172
173   if (IS_ALL (host))
174     return (0);
175
176   if ((data->last_host != NULL)
177       && (strcmp (data->last_host, host) == 0))
178   {
179     ident_destroy (ident);
180     return (0);
181   }
182
183   free (data->last_host);
184   data->last_host = strdup (host);
185
186   array_append (data->array, host);
187
188   ident_destroy (ident);
189   return (0);
190 } /* }}} int print_host_list_callback */
191
192 static int print_host_list (__attribute__((unused)) void *user_data) /* {{{ */
193 {
194   print_host_list_data_t data;
195   int hosts_argc;
196   char **hosts_argv;
197   int i;
198
199   data.array = array_create ();
200   data.last_host = NULL;
201
202   gl_instance_get_all (print_host_list_callback, &data);
203
204   free (data.last_host);
205   data.last_host = NULL;
206
207   array_sort (data.array);
208
209   hosts_argc = array_argc (data.array);
210   hosts_argv = array_argv (data.array);
211
212   if (hosts_argc < 1)
213   {
214     array_destroy (data.array);
215     return (0);
216   }
217
218   printf ("<div><h3>List of hosts</h3>\n"
219       "<ul id=\"host-list\">\n");
220   for (i = 0; i < hosts_argc; i++)
221   {
222     char *host = hosts_argv[i];
223     char *host_html;
224
225     if ((data.last_host != NULL) && (strcmp (data.last_host, host) == 0))
226       continue;
227     data.last_host = host;
228
229     host_html = html_escape (host);
230
231     printf ("  <li><a href=\"%s?action=list_graphs&q=host:%s\">%s</a></li>\n",
232         script_name (), host_html, host_html);
233
234     free (host_html);
235   }
236   printf ("</ul></div>\n");
237
238   array_destroy (data.array);
239
240   return (0);
241 } /* }}} int print_host_list */
242
243 static int list_graphs_html (const char *term) /* {{{ */
244 {
245   page_data_t pg_data;
246   page_callbacks_t pg_callbacks = PAGE_CALLBACKS_INIT;
247   char title[512];
248
249   if (term != NULL)
250     snprintf (title, sizeof (title), "c4: Graphs matching \"%s\"", term);
251   else
252     strncpy (title, "c4: List of all graphs", sizeof (title));
253   title[sizeof (title) - 1] = 0;
254
255   memset (&pg_data, 0, sizeof (pg_data));
256   pg_data.search_term = term;
257
258   pg_callbacks.top_right = html_print_search_box;
259   pg_callbacks.middle_left = print_host_list;
260   pg_callbacks.middle_center = print_search_result;
261
262   html_print_page (title, &pg_callbacks, &pg_data);
263
264   return (0);
265 } /* }}} int list_graphs_html */
266
267 int action_list_graphs (void) /* {{{ */
268 {
269   char *search;
270   int status;
271
272   gl_update ();
273
274   search = strtolower_copy (param ("q"));
275   status = list_graphs_html (search);
276   free (search);
277
278   return (status);
279 } /* }}} int action_list_graphs */
280
281 /* vim: set sw=2 sts=2 et fdm=marker : */