3 # Copyright (C) 2008 Florian octo Forster <octo at verplant.org>
5 # This program is free software; you can redistribute it and/or modify it under
6 # the terms of the GNU General Public License as published by the Free Software
7 # Foundation; only version 2 of the License is applicable.
9 # This program is distributed in the hope that it will be useful, but WITHOUT
10 # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11 # FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
14 # You should have received a copy of the GNU General Public License along with
15 # this program; if not, write to the Free Software Foundation, Inc.,
16 # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
23 use FindBin ('$RealBin');
25 use CGI::Carp ('fatalsToBrowser');
26 use HTML::Entities ('encode_entities');
30 use Collectd::Graph::TypeLoader (qw(tl_read_config tl_load_type));
31 use Collectd::Graph::Common (qw(get_files_from_directory get_all_hosts
32 get_timespan_selection get_selected_files get_host_selection
33 get_plugin_selection));
34 use Collectd::Graph::Type ();
36 our $Debug = param ('debug') ? 1 : 0;
47 my $action = param ('action') || 'list_hosts';
50 list_hosts => \&action_list_hosts,
51 show_selection => \&action_show_selection
54 if (!exists ($Actions{$action}))
56 print STDERR "No such action: $action\n";
60 tl_read_config ("$RealBin/../etc/collection3.conf");
62 $Actions{$action}->();
69 if (!defined $ENV{'HTTP_ACCEPT'})
74 for (split (',', $ENV{'HTTP_ACCEPT'}))
79 if ($type =~ m#^([^;]+);q=([0-9\.]+)$#)
87 if (!defined ($types{'application/xhtml+xml'}))
91 elsif (!defined ($types{'text/html'}))
95 elsif ($types{'application/xhtml+xml'} < $types{'text/html'})
108 return if ($html_started);
110 if (can_handle_xhtml ())
113 Content-Type: application/xhtml+xml; charset=UTF-8
115 <?xml version="1.0" encoding="UTF-8"?>
116 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
117 "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
118 <html xmlns="http://www.w3.org/1999/xhtml"
119 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
120 xsi:schemaLocation="http://www.w3.org/MarkUp/SCHEMA/xhtml11.xsd"
127 Content-Type: text/html; charset=UTF-8
129 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
130 "http://www.w3.org/TR/html4/strict.dtd">
136 <title>collection.cgi, Version 3</title>
137 <link rel="icon" href="../share/shortcut-icon.png" type="image/png" />
138 <link rel="stylesheet" href="../share/style.css" type="text/css" />
155 my $timespan_selection = get_timespan_selection ();
156 my $host_selection = get_host_selection ();
157 my $plugin_selection = get_plugin_selection ();
160 <form action="${\script_name ()}" method="get">
162 <legend>Data selection</legend>
163 <select name="hostname" multiple="multiple" size="15">
165 for (sort (keys %$host_selection))
167 my $host = encode_entities ($_);
168 my $selected = $host_selection->{$_}
169 ? ' selected="selected"'
171 print qq# <option value="$host"$selected>$host</option>\n#;
175 <select name="plugin" multiple="multiple" size="15">
177 for (sort (keys %$plugin_selection))
179 my $plugin = encode_entities ($_);
180 my $selected = $plugin_selection->{$_}
181 ? ' selected="selected"'
183 print qq# <option value="$plugin"$selected>$plugin</option>\n#;
187 <select name="timespan">
189 for (sort { $TimeSpans->{$a} <=> $TimeSpans->{$b} } (keys (%$TimeSpans)))
191 my $name = encode_entities ($_);
192 my $value = $TimeSpans->{$_};
193 my $selected = ($value == $timespan_selection)
194 ? ' selected="selected"'
196 print qq# <option value="$value"$selected>$name</option>\n#;
200 <input type="hidden" name="action" value="show_selection" />
201 <input type="submit" name="ok_button" value="OK" />
207 sub action_list_hosts
212 my @hosts = get_all_hosts ();
216 my $url = encode_entities (script_name () . "?action=show_selection;hostname=$_");
217 my $name = encode_entities ($_);
218 print qq# <li><a href="$url">$name</a></li>\n#;
223 } # action_list_hosts
225 =head1 MODULE LOADING
227 This script makes use of the various B<Collectd::Graph::Type::*> modules. If a
228 file like C<foo.rrd> is encountered it tries to load the
229 B<Collectd::Graph::Type::Foo> module and, if that fails, falls back to the
230 B<Collectd::Graph::Type> base class.
232 If you want to create a specialized graph for a certain type, you have to
233 create a new module which inherits from the B<Collectd::Graph::Type> base
234 class. A description of provided (and used) methods can be found in the inline
235 documentation of the B<Collectd::Graph::Type> module.
237 There are other, more specialized, "abstract" classes that possibly better fit
238 your need. Unfortunately they are not yet documented.
242 =item B<Collectd::Graph::Type::GenericStacked>
244 Specialized class that groups files by their plugin instance and stacks them on
245 top of each other. Example types that inherit from this class are
246 B<Collectd::Graph::Type::Cpu> and B<Collectd::Graph::Type::Memory>.
248 =item B<Collectd::Graph::Type::GenericIO>
250 Specialized class for input/output graphs. This class can only handle files
251 with exactly two data sources, input and output. Example types that inherit
252 from this class are B<Collectd::Graph::Type::DiskOctets> and
253 B<Collectd::Graph::Type::IfOctets>.
259 sub action_show_selection
269 $all_files = get_selected_files ();
273 print "<pre>", Data::Dumper->Dump ([$all_files], ['all_files']), "</pre>\n";
279 my $type = ucfirst (lc ($file->{'type'}));
281 $type =~ s/[^A-Za-z_]//g;
282 $type =~ s/_([A-Za-z])/\U$1\E/g;
284 if (!defined ($types->{$type}))
286 $types->{$type} = tl_load_type ($file->{'type'});
287 if (!$types->{$type})
289 cluck ("tl_load_type (" . $file->{'type'} . ") failed");
294 $types->{$type}->addFiles ($file);
296 #print STDOUT Data::Dumper->Dump ([$types], ['types']);
298 print qq# <table>\n#;
299 for (sort (keys %$types))
302 my $graphs_num = $types->{$type}->getGraphsNum ();
304 my $timespan = get_timespan_selection ();
306 for (my $i = 0; $i < $graphs_num; $i++)
308 my $args = $types->{$type}->getGraphArgs ($i);
309 my $url = encode_entities ("graph.cgi?$args;begin=-$timespan");
312 print " <td rowspan=\"$graphs_num\">$type</td>\n" if ($i == 0);
314 print qq# <td><img src="$url" /></td>\n#;
325 L<Collectd::Graph::Type>
327 =head1 AUTHOR AND LICENSE
329 Copyright (c) 2008 by Florian Forster
330 E<lt>octoE<nbsp>atE<nbsp>verplant.orgE<gt>. Licensed under the terms of the GNU
331 General Public License, VersionE<nbsp>2 (GPLv2).
335 # vim: set shiftwidth=2 softtabstop=2 tabstop=8 :