our $Debug = param ('debug');
our $Begin = param ('begin');
our $End = param ('end');
+our $GraphWidth = param ('width');
if ($Debug)
{
HTTP
}
-tl_read_config ("$RealBin/../etc/collection3.conf");
+tl_read_config ("$RealBin/../etc/collection.conf");
{ # Sanitize begin and end times
$End ||= 0;
}
my $expires = time ();
+# IF (End is `now')
+# OR (Begin is before `now' AND End is after `now')
if (($End == 0) || (($Begin <= $expires) && ($End >= $expires)))
{
# 400 == width in pixels
- my $timespan = $expires - $Begin;
- $expires += int ($timespan / 400);
+ my $timespan;
+
+ if ($End == 0)
+ {
+ $timespan = $expires - $Begin;
+ }
+ else
+ {
+ $timespan = $End - $Begin;
+ }
+ $expires += int ($timespan / 400.0);
}
+# IF (End is not `now')
+# AND (End is before `now')
+# ==> Graph will never change again!
elsif (($End > 0) && ($End < $expires))
{
- $expires += 366 * 86400;
+ $expires += (366 * 86400);
}
elsif ($Begin > $expires)
{
-Last_Modified => epoch_to_rfc1123 ($obj->getLastModified ()),
-Expires => epoch_to_rfc1123 ($expires));
+if ($Debug)
+{
+ print "\$expires = $expires;\n";
+}
+
my $args = $obj->getRRDArgs (0);
if ($Debug)
exit 1;
}
-tl_read_config ("$RealBin/../etc/collection3.conf");
+tl_read_config ("$RealBin/../etc/collection.conf");
$Actions{$action}->();
exit (0);
{
return if ($html_started);
+ my $end;
+ my $begin;
+ my $timespan;
+
+ $end = time ();
+ $timespan = get_timespan_selection ();
+ $begin = $end - $timespan;
+
if (can_handle_xhtml ())
{
print <<HTML;
<title>collection.cgi, Version 3</title>
<link rel="icon" href="../share/shortcut-icon.png" type="image/png" />
<link rel="stylesheet" href="../share/style.css" type="text/css" />
+ <script type="text/javascript" src="../share/navigate.js" />
</head>
- <body>
+ <body onload="nav_init ($begin, $end);">
HTML
$html_started = 1;
}}
<input type="hidden" name="action" value="show_selection" />
<input type="submit" name="ok_button" value="OK" />
</fieldset>
+ <fieldset>
+ <legend>Move all graphs</legend>
+ <input type="button" name="earlier" value="←" title="Earlier"
+ onclick="nav_move_earlier ('*');" />
+ <input type="button" name="zoom_out" value="-" title="Zoom out"
+ onclick="nav_zoom_out ('*');" />
+ <input type="button" name="zoom_in" value="+" title="Zoom in"
+ onclick="nav_zoom_in ('*');" />
+ <input type="button" name="later" value="→" title="Later"
+ onclick="nav_move_later ('*');" />
+ </fieldset>
</form>
HTML
} # show_selector
my $all_files;
my $types = {};
+ my $id_counter = 0;
+
$all_files = get_selected_files ();
if ($Debug)
{
my $args = $types->{$type}->getGraphArgs ($i);
my $url = encode_entities ("graph.cgi?$args;begin=-$timespan");
+ my $id = sprintf ("graph%04i", $id_counter++);
print " <tr>\n";
print " <td rowspan=\"$graphs_num\">$type</td>\n" if ($i == 0);
-
- print qq# <td><img src="$url" /></td>\n#;
+ print <<EOF;
+ <td>
+ <div class="graph_canvas">
+ <div class="graph_float">
+ <img id="${id}" class="graph_image"
+ alt="A graph"
+ src="$url" />
+ <div class="controls zoom">
+ <div title="Earlier"
+ onclick="nav_move_earlier ('${id}');">←</div>
+ <div title="Zoom out"
+ onclick="nav_zoom_out ('${id}');">-</div>
+ <div title="Zoom in"
+ onclick="nav_zoom_in ('${id}');">+</div>
+ <div title="Later"
+ onclick="nav_move_later ('${id}');">→</div>
+ </div>
+ <div class="controls preset">
+ <div title="Show current hour"
+ onclick="nav_time_reset ('${id}', 3600);">H</div>
+ <div title="Show current day"
+ onclick="nav_time_reset ('${id}', 86400);">D</div>
+ <div title="Show current week"
+ onclick="nav_time_reset ('${id}', 7 * 86400);">W</div>
+ <div title="Show current month"
+ onclick="nav_time_reset ('${id}', 31 * 86400);">M</div>
+ <div title="Show current year"
+ onclick="nav_time_reset ('${id}', 366 * 86400);">Y</div>
+ </div>
+ </div>
+ </div>
+ </td>
+EOF
+ # print qq# <td><img src="$url" /></td>\n#;
print " </tr>\n";
}
}
+<Type apache_scoreboard>
+ Module GenericStacked
+ DataSources count
+ RRDTitle "Apache scoreboard on {hostname}"
+ RRDVerticalLabel "Slots"
+ RRDFormat "%6.2lf"
+ DSName closing Closing
+ DSName dnslookup DNS lookup
+ DSName finishing Finishing
+ DSName idle_cleanup Idle cleanup
+ DSName keepalive Keep alive
+ DSName logging Logging
+ DSName open Open (empty)
+ DSName reading Reading
+ DSName sending Sending
+ DSName starting Starting
+ DSName waiting Waiting
+ Order open closing dnslookup finishing idle_cleanup keepalive logging open reading sending starting waiting
+ Color closing 000080
+ Color dnslookup ff0000
+ Color finishing 008080
+ Color idle_cleanup ffff00
+ Color keepalive 0080ff
+ Color logging a000a0
+ Color open e0e0e0
+ Color reading 0000ff
+ Color sending 00e000
+ Color starting ff00ff
+ Color waiting ffb000
+</Type>
<Type cpu>
Module GenericStacked
DataSources value
my $idents = $group->{$group[$index]};
my $ds_name_len = 0;
+ my $ds = $obj->getDataSources ();
+ if (!$ds)
+ {
+ confess ("obj->getDataSources failed.");
+ }
+ if (@$ds != 1)
+ {
+ confess ("I can only work with RRD files that have "
+ . "exactly one data source!");
+ }
+ my $data_source = $ds->[0];
+
my $rrd_title = $obj->getTitle ($idents->[0]);
my $colors = $obj->{'rrd_colors'} || {};
$names[$i] =~ s/:/\\:/g;
push (@ret,
- "DEF:min${i}=${filename}:value:MIN",
- "DEF:avg${i}=${filename}:value:AVERAGE",
- "DEF:max${i}=${filename}:value:MAX");
+ "DEF:min${i}=${filename}:${data_source}:MIN",
+ "DEF:avg${i}=${filename}:${data_source}:AVERAGE",
+ "DEF:max${i}=${filename}:${data_source}:MAX");
}
for (my $i = @$idents - 1; $i >= 0; $i--)
--- /dev/null
+function nav_init (time_begin, time_end)
+{
+ var all_images;
+ var i;
+
+ all_images = document.getElementsByTagName ("img");
+ for (i = 0; i < all_images.length; i++)
+ {
+ if (all_images[i].className != "graph_image")
+ continue;
+
+ all_images[i].navTimeBegin = new Number (time_begin);
+ all_images[i].navTimeEnd = new Number (time_end);
+
+ all_images[i].navBaseURL = all_images[i].src.replace (/;(begin|end)=[^;]*/g, '');
+ }
+
+ return (true);
+} /* nav_init */
+
+function nav_time_reset (img_id ,diff)
+{
+ var img;
+
+ img = document.getElementById (img_id);
+ if (!img)
+ return (false);
+
+ img.navTimeEnd = new Number ((new Date ()).getTime () / 1000);
+ img.navTimeBegin = new Number (img.navTimeEnd - diff);
+
+ img.src = img.navBaseURL + ";"
+ + "begin=" + img.navTimeBegin.toFixed (0) + ";"
+ + "end=" + img.navTimeEnd.toFixed (0);
+
+ return (true);
+}
+
+function nav_time_change_obj (img, factor_begin, factor_end)
+{
+ var diff;
+
+ if (!img)
+ return (false);
+
+ if (!img.navTimeEnd || !img.navTimeBegin)
+ return (false);
+
+ diff = img.navTimeEnd - img.navTimeBegin;
+ if (diff <= 300)
+ return (true);
+
+ img.navTimeBegin += (diff * factor_begin);
+ img.navTimeEnd += (diff * factor_end);
+
+ img.src = img.navBaseURL + ";"
+ + "begin=" + img.navTimeBegin.toFixed (0) + ";"
+ + "end=" + img.navTimeEnd.toFixed (0);
+
+ return (true);
+} /* nav_time_change */
+
+function nav_time_change (img_id, factor_begin, factor_end)
+{
+ var diff;
+
+ if (img_id == '*')
+ {
+ var all_images;
+
+ all_images = document.getElementsByTagName ("img");
+ for (i = 0; i < all_images.length; i++)
+ {
+ if (all_images[i].className != "graph_image")
+ continue;
+
+ nav_time_change_obj (all_images[i], factor_begin, factor_end);
+ }
+ }
+ else
+ {
+ var img;
+
+ img = document.getElementById (img_id);
+ if (!img)
+ return (false);
+
+ nav_time_change_obj (img, factor_begin, factor_end);
+ }
+
+ return (true);
+} /* nav_time_change */
+
+function nav_move_earlier (img_id)
+{
+ return (nav_time_change (img_id, -0.2, -0.2));
+} /* nav_move_earlier */
+
+function nav_move_later (img_id)
+{
+ return (nav_time_change (img_id, +0.2, +0.2));
+} /* nav_move_later */
+
+function nav_zoom_in (img_id)
+{
+ return (nav_time_change (img_id, +0.2, -0.2));
+} /* nav_zoom_in */
+
+function nav_zoom_out (img_id)
+{
+ return (nav_time_change (img_id, (-1.0 / 3.0), (1.0 / 3.0)));
+}
+/* vim: set sw=2 sts=2 et : */
+div.graph
+{
+}
+
+div.graph_canvas div.graph_float
+{
+ float: left;
+ position: relative;
+}
+
+div.graph_float div.controls
+{
+ display: none;
+ position: absolute;
+}
+
+div.graph_float:hover div.controls
+{
+ display: block;
+}
+
+div.graph_float div.controls.zoom
+{
+ right: 5px;
+ bottom: 10px;
+}
+
+div.graph_float div.controls.preset
+{
+ right: 5px;
+ top: 5px;
+}
+
+div.graph_float div.controls div
+{
+ display: block;
+
+ color: gray;
+ background: white;
+
+ text-decoration: none;
+ text-align: center;
+ font-size: small;
+
+ cursor: pointer;
+
+ border: 1px solid gray;
+ width: 1em;
+ height: 1em;
+ padding: 1px;
+ margin: 0px;
+}
+
+div.graph_float div.controls div:hover
+{
+ color: black;
+ border-color: black;
+}
+
+div.graph_float div.controls.preset div
+{
+ margin: 1px 0px 1px 0px;
+}
+
+div.graph_float div.controls.zoom div
+{
+ float: left;
+ margin: 0px 1px 0px 1px;
+}
+
table
{
border-collapse: collapse;