[collectd] Updated collection.cgi

Mirko Buffoni briareos at eswat.org
Sat Nov 15 13:25:43 CET 2008


Hi friends,

I have updated collection.cgi to be more usable (at least to me)
and took the opportunity to update it for vmem support too.

Forgive some copy-paste here and there, as I don't speak PERL-ish.

Here is what I've done:

- Improved selection window so to be always visible.  At first I
   thought to change the behavior, but I realized that multiselect
   can be useful and quite general purpose, so I left it in and
   positioned the window top-right fixed.
- This way graphs can scroll on the left giving a better visibility
   and ability to switch from one plugin to another

   (Tested with Opera, Firefox and K-Meleon.  I left bugged Internet 
Explorer to brave fellows)

- I introduced metagraphs for vmpage_number, vmpage_action
   I invite the author of vmem plugin to update colors to reflect
   the correct importance.  I'm not too much into vmem pages mess.
   I also do not have sufficient data to see if current colors are
   bad for readability
- I also added vmpage_io graphs.  Some tweaking may be required,
   because my text values often go out of graph (scaling adjustment
   perhaps?)

- Finally, I've added a timestamp parameter to img src requests.
   This takes care of refreshing always with fresh content, and avoiding
   browser cache problem.

I've worked on collection.cgi present in collectd-4.5.1 archive.
I'm attaching the DIFF file because I don't know if there is any
limit to attachments for this list.

I didn't touch collection.cgi Version number.  Feel free to update
it if you think this is a major/minor improvement.

Feedbacks and opinions are welcome as usual.

Mirko
-------------- next part --------------
--- collection.cgi	2008-10-16 22:14:28.000000000 +0200
+++ /var/www/html/collection.cgi	2008-11-15 13:04:50.000000000 +0100
@@ -629,6 +629,7 @@
 	if (exists ($MetaGraphDefs->{$type}))
 	{
 	  my $graph_url = script_name () . '?action=show_graph'
+	  . ';ts=' . time
 	  . ';plugin=' . uri_escape ($plugin)
 	  . ';type=' . uri_escape ($type)
 	  . ';timespan=' . uri_escape ($timespan);
@@ -667,6 +668,7 @@
 	  my $tinst = $_;
 	  my $tinst_esc = encode_entities ($tinst);
 	  my $graph_url = script_name () . '?action=show_graph'
+	  . ';ts=' . time
 	  . ';plugin=' . uri_escape ($plugin)
 	  . ';type=' . uri_escape ($type)
 	  . ';timespan=' . uri_escape ($timespan);
@@ -795,8 +797,10 @@
 
   print <<HTML;
     <form action="${\script_name ()}" method="get">
-      <fieldset>
+      <fieldset style="background:#fff;position:fixed;top:0;z-index:1;right:0;width:300px;margin: 0 0 0 20px;">
 	<legend>Selector</legend>
+	<table><tr valign="top">
+	<td>
 	<select name="host" multiple="multiple" size="10">
 HTML
   for (my $i = 0; $i < @hosts; $i++)
@@ -805,14 +809,14 @@
     my $selected = defined ($selected_hosts{$hosts[$i]}) ? ' selected="selected"' : '';
     print qq(\t  <option value="$host"$selected>$host</option>\n);
   }
-  print "\t</select>\n";
+  print "\t</select></td>\n";
 
   if (keys %selected_hosts)
   {
     my $all_plugins = _find_files_for_hosts (keys %selected_hosts);
     my %selected_plugins = map { $_ => 1 } (param ('plugin'));
 
-    print qq(\t<select name="plugin" multiple="multiple" size="10">\n);
+    print qq(\t<td><select name="plugin" multiple="multiple" size="10">\n);
     for (sort (keys %$all_plugins))
     {
       my $plugin = $_;
@@ -821,10 +825,10 @@
 	? ' selected="selected"' : '');
       print qq(\t  <option value="$plugin_html"$selected>$plugin</option>\n);
     }
-    print "</select>\n";
+    print "</select></td>\n";
   } # if (keys %selected_hosts)
 
-  print qq(\t<select name="timespan">\n);
+  print qq(\t<td><select name="timespan">\n);
   for (qw(Hour Day Week Month Year))
   {
     my $timespan_uc = $_;
@@ -834,8 +838,9 @@
     print qq(\t  <option value="$timespan_lc"$selected>$timespan_uc</option>\n);
   }
   print <<HTML;
-	</select>
-	<input type="submit" name="button" value="Ok" />
+	</select></td>
+	<td><input type="submit" name="button" value="Ok" /></td>
+	</tr></table>
       </fieldset>
     </form>
 HTML
@@ -855,6 +860,7 @@
   <head>
     <title>collection.cgi, Version 2</title>
     <style type="text/css">
+      body, td { font: 12px Arial, Helvetica, sans-serif; }
       img
       {
 	border: none;
@@ -2544,11 +2550,81 @@
     'GPRINT:max:MAX:%5.1lf Max,',
     'GPRINT:avg:LAST:%5.1lf Last\l',
     ],
+    vmpage_number => ['-v', 'Pages',
+    'DEF:avg={file}:value:AVERAGE',
+    'DEF:min={file}:value:MIN',
+    'DEF:max={file}:value:MAX',
+    "AREA:max#$HalfBlue",
+    "AREA:min#$Canvas",
+    "LINE1:avg#$FullBlue:Number",
+    'GPRINT:min:MIN:%4.1lf Min,',
+    'GPRINT:avg:AVERAGE:%4.1lf Avg,',
+    'GPRINT:max:MAX:%4.1lf Max,',
+    'GPRINT:avg:LAST:%4.1lf Last\l'
+    ],
+    vmpage_faults => [
+    "DEF:minf_avg={file}:minflt:AVERAGE",
+    "DEF:minf_min={file}:minflt:MIN",
+    "DEF:minf_max={file}:minflt:MAX",
+    "DEF:majf_avg={file}:majflt:AVERAGE",
+    "DEF:majf_min={file}:majflt:MIN",
+    "DEF:majf_max={file}:majflt:MAX",
+    'CDEF:overlap=majf_avg,minf_avg,GT,minf_avg,majf_avg,IF',
+    "AREA:majf_avg#$HalfGreen",
+    "AREA:minf_avg#$HalfBlue",
+    "AREA:overlap#$HalfBlueGreen",
+    "LINE1:majf_avg#$FullGreen:Major",
+    'GPRINT:majf_min:MIN:%5.1lf%s Min,',
+    'GPRINT:majf_avg:AVERAGE:%5.1lf%s Avg,',
+    'GPRINT:majf_max:MAX:%5.1lf%s Max,',
+    'GPRINT:majf_avg:LAST:%5.1lf%s Last\l',
+    "LINE1:minf_avg#$FullBlue:Minor",
+    'GPRINT:minf_min:MIN:%5.1lf%s Min,',
+    'GPRINT:minf_avg:AVERAGE:%5.1lf%s Avg,',
+    'GPRINT:minf_max:MAX:%5.1lf%s Max,',
+    'GPRINT:minf_avg:LAST:%5.1lf%s Last\l'
+    ],
+    vmpage_io => [
+    "DEF:rpag_avg={file}:in:AVERAGE",
+    "DEF:rpag_min={file}:in:MIN",
+    "DEF:rpag_max={file}:in:MAX",
+    "DEF:wpag_avg={file}:out:AVERAGE",
+    "DEF:wpag_min={file}:out:MIN",
+    "DEF:wpag_max={file}:out:MAX",
+    'CDEF:overlap=wpag_avg,rpag_avg,GT,rpag_avg,wpag_avg,IF',
+    "AREA:wpag_avg#$HalfGreen",
+    "AREA:rpag_avg#$HalfBlue",
+    "AREA:overlap#$HalfBlueGreen",
+    "LINE1:wpag_avg#$FullGreen:OUT",
+    'GPRINT:wpag_min:MIN:%5.1lf%s Min,',
+    'GPRINT:wpag_avg:AVERAGE:%5.1lf%s Avg,',
+    'GPRINT:wpag_max:MAX:%5.1lf%s Max,',
+    'GPRINT:wpag_avg:LAST:%5.1lf%s Last\l',
+    "LINE1:rpag_avg#$FullBlue:IN ",
+    'GPRINT:rpag_min:MIN:%5.1lf%s Min,',
+    'GPRINT:rpag_avg:AVERAGE:%5.1lf%s Avg,',
+    'GPRINT:rpag_max:MAX:%5.1lf%s Max,',
+    'GPRINT:rpag_avg:LAST:%5.1lf%s Last\l'
+    ],
+    vmpage_action => ['-v', 'Pages',
+    'DEF:avg={file}:value:AVERAGE',
+    'DEF:min={file}:value:MIN',
+    'DEF:max={file}:value:MAX',
+    "AREA:max#$HalfBlue",
+    "AREA:min#$Canvas",
+    "LINE1:avg#$FullBlue:Number",
+    'GPRINT:min:MIN:%4.1lf Min,',
+    'GPRINT:avg:AVERAGE:%4.1lf Avg,',
+    'GPRINT:max:MAX:%4.1lf Max,',
+    'GPRINT:avg:LAST:%4.1lf Last\l'
+    ],
   };
   $GraphDefs->{'if_multicast'} = $GraphDefs->{'ipt_packets'};
   $GraphDefs->{'if_tx_errors'} = $GraphDefs->{'if_rx_errors'};
   $GraphDefs->{'dns_qtype'} = $GraphDefs->{'dns_opcode'};
   $GraphDefs->{'dns_rcode'} = $GraphDefs->{'dns_opcode'};
+  $GraphDefs->{'vmpage_io-memory'} = $GraphDefs->{'vmpage_io'};
+  $GraphDefs->{'vmpage_io-swap'} = $GraphDefs->{'vmpage_io'};
 
   $MetaGraphDefs->{'cpu'} = \&meta_graph_cpu;
   $MetaGraphDefs->{'dns_qtype'} = \&meta_graph_dns;
@@ -2562,6 +2638,8 @@
   $MetaGraphDefs->{'mysql_commands'} = \&meta_graph_mysql_commands;
   $MetaGraphDefs->{'mysql_handler'} = \&meta_graph_mysql_commands;
   $MetaGraphDefs->{'tcp_connections'} = \&meta_graph_tcp_connections;
+  $MetaGraphDefs->{'vmpage_number'} = \&meta_graph_vmpage_number;
+  $MetaGraphDefs->{'vmpage_action'} = \&meta_graph_vmpage_action;
 } # load_graph_definitions
 
 sub meta_graph_generic_stack
@@ -3163,4 +3241,131 @@
 
   return (meta_graph_generic_stack ($opts, $sources));
 } # meta_graph_tcp_connections
+
+sub meta_graph_vmpage_number
+{
+  confess ("Wrong number of arguments") if (@_ != 5);
+
+  my $host = shift;
+  my $plugin = shift;
+  my $plugin_instance = shift;
+  my $type = shift;
+  my $type_instances = shift;
+
+  my $opts = {};
+  my $sources = [];
+
+  $opts->{'title'} = "$host/$plugin"
+  . (defined ($plugin_instance) ? "-$plugin_instance" : '') . "/$type";
+  $opts->{'number_format'} = '%6.2lf';
+
+  $opts->{'rrd_opts'} = ['-v', 'Pages'];
+
+  my @files = ();
+
+  $opts->{'colors'} =
+  {
+    anon_pages	  => '00e000',
+    bounce	  => '00e0ff',
+    dirty	  => '00e0a0',
+    file_pages	  => 'f000f0',
+    mapped	  => 'f000a0',
+    page_table_pages	  => 'ffb000',
+    slab	  => '0000f0',
+    unstable	  => '0000a0',
+    writeback	  => 'ff0000',
+  };
+
+  _custom_sort_arrayref ($type_instances,
+    [reverse qw(anon_pages bounce dirty file_pages mapped page_table_pages slab unstable writeback)]);
+
+  for (@$type_instances)
+  {
+    my $inst = $_;
+    my $file = '';
+    my $title = $opts->{'title'};
+
+    for (@DataDirs)
+    {
+      if (-e "$_/$title-$inst.rrd")
+      {
+	$file = "$_/$title-$inst.rrd";
+	last;
+      }
+    }
+    confess ("No file found for $title") if ($file eq '');
+
+    push (@$sources,
+      {
+	name => $inst,
+	file => $file
+      }
+    );
+  } # for (@$type_instances)
+
+  return (meta_graph_generic_stack ($opts, $sources));
+} # meta_graph_vmpage_number
+
+sub meta_graph_vmpage_action
+{
+  confess ("Wrong number of arguments") if (@_ != 5);
+
+  my $host = shift;
+  my $plugin = shift;
+  my $plugin_instance = shift;
+  my $type = shift;
+  my $type_instances = shift;
+
+  my $opts = {};
+  my $sources = [];
+
+  $opts->{'title'} = "$host/$plugin"
+  . (defined ($plugin_instance) ? "-$plugin_instance" : '') . "/$type";
+  $opts->{'number_format'} = '%6.2lf';
+
+  $opts->{'rrd_opts'} = ['-v', 'Pages'];
+
+  my @files = ();
+
+  $opts->{'colors'} =
+  {
+    activate	  => '00e000',
+    deactivate	  => '00e0ff',
+    free	  => '00e0a0',
+    alloc	  => 'f000f0',
+    refill	  => 'f000a0',
+    scan_direct	  => 'ffb000',
+    scan_kswapd	  => '0000f0',
+    steal	  => '0000a0',
+  };
+
+  _custom_sort_arrayref ($type_instances,
+    [reverse qw(activate deactivate alloc free refill scan_direct scan_kswapd steal)]);
+
+  for (@$type_instances)
+  {
+    my $inst = $_;
+    my $file = '';
+    my $title = $opts->{'title'};
+
+    for (@DataDirs)
+    {
+      if (-e "$_/$title-$inst.rrd")
+      {
+	$file = "$_/$title-$inst.rrd";
+	last;
+      }
+    }
+    confess ("No file found for $title") if ($file eq '');
+
+    push (@$sources,
+      {
+	name => $inst,
+	file => $file
+      }
+    );
+  } # for (@$type_instances)
+
+  return (meta_graph_generic_stack ($opts, $sources));
+} # meta_graph_vmpage_action
 # vim: shiftwidth=2:softtabstop=2:tabstop=8


More information about the collectd mailing list