Merge branch 'collectd-4.5'
[collectd.git] / contrib / collection.cgi
index 159d9e6..7de8bcc 100755 (executable)
@@ -209,8 +209,8 @@ sub _find_plugins
     for (@tmp)
     {
       my ($plugin, $instance) = split (m/-/, $_, 2);
-      $plugins{$plugin} = [] if (!$plugins{$plugin});
-      push (@{$plugins{$plugin}}, $instance) if (defined ($instance));
+      $plugins{$plugin} = [] if (!exists $plugins{$plugin});
+      push (@{$plugins{$plugin}}, $instance);
     }
   } # for (@DataDirs)
 
@@ -267,9 +267,11 @@ sub _find_files_for_host
 
     for (@$plugin_instances)
     {
-      my $plugin_instance = $_;
+      my $plugin_instance = defined ($_) ? $_ : '-';
       my %types = _find_types ($host, $plugin,
-       ($plugin_instance ne '-') ? $plugin_instance : undef);
+       ($plugin_instance ne '-')
+       ? $plugin_instance
+       : undef);
 
       $ret->{$plugin}{$plugin_instance} = {};
 
@@ -411,6 +413,64 @@ sub _get_random_color
   return ([$r, $g, $b]);
 } # _get_random_color
 
+sub _get_n_colors
+{
+       my $instances = shift;
+       my $num = scalar @$instances;
+       my $ret = {};
+
+       for (my $i = 0; $i < $num; $i++)
+       {
+               my $pos = 6 * $i / $num;
+               my $n = int ($pos);
+               my $p = $pos - $n;
+               my $q = 1 - $p;
+
+               my $red   = 0;
+               my $green = 0;
+               my $blue  = 0;
+
+               my $color;
+
+               if ($n == 0)
+               {
+                       $red  = 255;
+                       $blue = 255 * $p;
+               }
+               elsif ($n == 1)
+               {
+                       $red  = 255 * $q;
+                       $blue = 255;
+               }
+               elsif ($n == 2)
+               {
+                       $green = 255 * $p;
+                       $blue  = 255;
+               }
+               elsif ($n == 3)
+               {
+                       $green = 255;
+                       $blue  = 255 * $q;
+               }
+               elsif ($n == 4)
+               {
+                       $red   = 255 * $p;
+                       $green = 255;
+               }
+               elsif ($n == 5)
+               {
+                       $red   = 255;
+                       $green = 255 * $q;
+               }
+               else { die; }
+
+               $color = sprintf ("%02x%02x%02x", $red, $green, $blue);
+               $ret->{$instances->[$i]} = $color;
+       }
+
+       return ($ret);
+} # _get_n_colors
+
 sub _get_faded_color
 {
   my $fg = shift;
@@ -459,86 +519,139 @@ sub action_show_host
   my @hosts = _get_param_host ();
   @hosts = sort (@hosts);
 
-  my $all_plugins = {};
-  my $plugins_per_host = {};
+  my $timespan = _get_param_timespan ();
+  my $all_plugins = _find_files_for_hosts (@hosts);
+
+  my $url_prefix = script_name () . '?action=show_plugin'
+  . join ('', map { ';host=' . uri_escape ($_) } (@hosts))
+  . ';timespan=' . uri_escape ($timespan);
+
+  print qq(    <div><a href="${\script_name ()}?action=overview">Back to list of hosts</a></div>\n);
+
+  print "    <p>Available plugins:</p>\n"
+  . "    <ul>\n";
+  for (sort (keys %$all_plugins))
+  {
+    my $plugin = $_;
+    my $plugin_html = encode_entities ($plugin);
+    my $url_plugin = $url_prefix . ';plugin=' . uri_escape ($plugin);
+    print qq(      <li><a href="$url_plugin">$plugin_html</a></li>\n);
+  }
+  print "   </ul>\n";
+} # action_show_host
 
+sub action_show_plugin
+{
+  my @hosts = _get_param_host ();
+  my $plugin = shift;
+  my $plugin_instance = shift;
   my $timespan = _get_param_timespan ();
 
+  my $hosts_url = join (';', map { 'host=' . uri_escape ($_) } (@hosts));
+  my $url_prefix = script_name () . "?$hosts_url";
+
+  my $all_plugins = {};
+  my $plugins_per_host = {};
+  my $selected_plugins = {};
+
   for (my $i = 0; $i < @hosts; $i++)
   {
     $plugins_per_host->{$hosts[$i]} = _find_files_for_host ($hosts[$i]);
     _files_union ($all_plugins, $plugins_per_host->{$hosts[$i]});
   }
 
-  my $param_host = join (";", map { "host=" . encode_entities ($_) } (@hosts));
-
-  print '<!-- ', Data::Dumper->Dump ([$all_plugins], ['all_plugins']), " -->\n";
-
-  my @plugins = sort (keys %$all_plugins);
+  for (param ('plugin'))
+  {
+    if (defined ($all_plugins->{$_}))
+    {
+      $selected_plugins->{$_} = 1;
+    }
+  }
 
-  print qq(    <div><a href="${\script_name ()}?action=overview">Back to list of hosts</a></div>\n);
+  print qq(    <div><a href="${\script_name ()}?action=show_host;$hosts_url">Back to list of plugins</a></div>\n);
 
+  # Print table header
   print <<HTML;
     <table class="graphs">
       <tr>
-       <th>Plugin</th>
+        <th>Plugins</th>
 HTML
-  for (my $i = 0; $i < @hosts; $i++)
+  for (@hosts)
   {
-    print "\t<th>", encode_entities ($hosts[$i]), "</th>\n";
+    print "\t<th>", encode_entities ($_), "</th>\n";
   }
   print "      </tr>\n";
-  for (my $i = 0; $i < @plugins; $i++)
-  {
-    my $plugin = $plugins[$i];
-    my $plugin_esc = encode_entities ($plugins[$i]);
 
-    my @pinsts = sort (keys %{$all_plugins->{$plugin}});
+  for (sort (keys %$selected_plugins))
+  {
+    my $plugin = $_;
+    my $plugin_html = encode_entities ($plugin);
+    my $plugin_url = "$url_prefix;plugin=" . uri_escape ($plugin);
+    my $all_pinst = $all_plugins->{$plugin};
 
-    for (my $j = 0; $j < @pinsts; $j++)
+    for (sort (keys %$all_pinst))
     {
-      my $pinst = $pinsts[$j];
-      my $pinst_esc = encode_entities ($pinst);
-      my $title = $plugin . ($pinst ne '-' ? " ($pinst)" : '');
-      my $title_esc = encode_entities ($title);
+      my $pinst = $_;
+      my $pinst_html = '';
+      my $pinst_url = $plugin_url;
 
-      my $param_plugin = "plugin=$plugin_esc";
       if ($pinst ne '-')
       {
-       $param_plugin .= ";plugin_instance=$pinst_esc";
+       $pinst_html = encode_entities ($pinst);
+       $pinst_url .= ';plugin_instance=' . uri_escape ($pinst);
       }
 
       my $files_printed = 0;
-      my $files_num = _files_plugin_inst_count ($all_plugins->{$plugin}{$pinst});
-      next if (!$files_num);
-
+      my $files_num = _files_plugin_inst_count ($all_pinst->{$pinst});
+      if ($files_num < 1)
+      {
+       next;
+      }
       my $rowspan = ($files_num == 1) ? '' : qq( rowspan="$files_num");
 
       for (sort (keys %{$all_plugins->{$plugin}{$pinst}}))
       {
        my $type = $_;
-       my $type_esc = encode_entities ($type);
+       my $type_html = encode_entities ($type);
+       my $type_url = "$pinst_url;type=" . uri_escape ($type);
+
+       if ($files_printed == 0)
+       {
+         my $title = $plugin_html;
+         if ($pinst ne '-')
+         {
+           $title .= " ($pinst_html)";
+         }
+         print "      <tr>\n";
+         print "\t<td$rowspan>$title</td>\n";
+       }
 
        if (exists ($MetaGraphDefs->{$type}))
        {
-         my $param_type = "type=$type_esc";
+         my $graph_url = script_name () . '?action=show_graph'
+         . ';plugin=' . uri_escape ($plugin)
+         . ';type=' . uri_escape ($type)
+         . ';timespan=' . uri_escape ($timespan);
+         if ($pinst ne '-')
+         {
+           $graph_url .= ';plugin_instance=' . uri_escape ($pinst);
+         }
 
-         print "      <tr>\n";
-         if ($files_printed == 0)
+         if ($files_printed != 0)
          {
-           print "\t<td$rowspan>$title_esc</td>\n";
+           print "      <tr>\n";
          }
 
-         for (my $k = 0; $k < @hosts; $k++)
+         for (@hosts)
          {
-           my $host = $hosts[$k];
-           my $host_esc = encode_entities ($host);
+           my $host = $_;
+           my $host_graph_url = $graph_url . ';host=' . uri_escape ($host);
 
            print "\t<td>";
            if (exists $plugins_per_host->{$host}{$plugin}{$pinst}{$type})
            {
-             #print qq(<img src="${\script_name ()}?action=show_graph;host=$host_esc;$param_plugin;$param_type;timespan=$timespan" />);
-             print encode_entities (qq(<img src="${\script_name ()}?action=show_graph;host=$host_esc;$param_plugin;$param_type;timespan=$timespan" />));
+             print qq(<img src="$host_graph_url" />);
+             #print encode_entities (qq(<img src="${\script_name ()}?action=show_graph;host=$host_esc;$param_plugin;$param_type;timespan=$timespan" />));
            }
            print "</td>\n";
          } # for (my $k = 0; $k < @hosts; $k++)
@@ -547,35 +660,40 @@ HTML
 
          $files_printed++;
          next; # pinst
-       }
+       } # if (exists ($MetaGraphDefs->{$type}))
 
        for (sort (keys %{$all_plugins->{$plugin}{$pinst}{$type}}))
        {
          my $tinst = $_;
          my $tinst_esc = encode_entities ($tinst);
-
-         my $param_type = "type=$type_esc";
+         my $graph_url = script_name () . '?action=show_graph'
+         . ';plugin=' . uri_escape ($plugin)
+         . ';type=' . uri_escape ($type)
+         . ';timespan=' . uri_escape ($timespan);
+         if ($pinst ne '-')
+         {
+           $graph_url .= ';plugin_instance=' . uri_escape ($pinst);
+         }
          if ($tinst ne '-')
          {
-           $param_type .= ";type_instance=$tinst_esc";
+           $graph_url .= ';type_instance=' . uri_escape ($tinst);
          }
 
-         print "      <tr>\n";
-         if ($files_printed == 0)
+         if ($files_printed != 0)
          {
-           print "\t<td$rowspan>$title_esc</td>\n";
+           print "      <tr>\n";
          }
 
          for (my $k = 0; $k < @hosts; $k++)
          {
            my $host = $hosts[$k];
-           my $host_esc = encode_entities ($host);
+           my $host_graph_url = $graph_url . ';host=' . uri_escape ($host);
 
            print "\t<td>";
            if ($plugins_per_host->{$host}{$plugin}{$pinst}{$type}{$tinst})
            {
-             #print qq(<img src="${\script_name ()}?action=show_graph;host=$host_esc;$param_plugin;$param_type;timespan=$timespan" />);
-             print encode_entities (qq(<img src="${\script_name ()}?action=show_graph;host=$host_esc;$param_plugin;$param_type;timespan=$timespan" />));
+             print qq(<img src="$host_graph_url" />);
+             #print encode_entities (qq(<img src="${\script_name ()}?action=show_graph;host=$host_esc;$param_plugin;$param_type;timespan=$timespan" />));
            }
            print "</td>\n";
          } # for (my $k = 0; $k < @hosts; $k++)
@@ -585,147 +703,8 @@ HTML
          $files_printed++;
        } # for ($tinst)
       } # for ($type)
-    } # for (my $j = 0; $j < @pinsts; $j++)
-  } # for (my $i = 0; $i < @plugins; $i++)
-  print "   </table>\n";
-} # action_show_host
-
-sub action_show_plugin
-{
-  my @hosts = _get_param_host ();
-  my $plugin = shift;
-  my $plugin_instance = shift;
-  my $timespan = _get_param_timespan ();
-
-  my $hosts_url = join (';', map { 'host=' . uri_escape ($_) } (@hosts));
-  my $plugin_esc = encode_entities ($plugin);
-  my $plugin_url = uri_escape ($plugin);
-  my $plugin_instance_url = defined ($plugin_instance) ? uri_escape ($plugin_instance) : undef;
-
-  my $all_plugins = {};
-  my $plugins_per_host = {};
-
-  for (my $i = 0; $i < @hosts; $i++)
-  {
-    $plugins_per_host->{$hosts[$i]} = _find_files_for_host ($hosts[$i]);
-    _files_union ($all_plugins, $plugins_per_host->{$hosts[$i]});
-  }
-
-  my $url_prefix = script_name () . "?$hosts_url;plugin=$plugin_url";
-  $url_prefix .= ";plugin_instance=$plugin_instance_url" if (defined ($plugin_instance));
-
-  print qq(    <div><a href="${\script_name ()}?action=show_host;$hosts_url">Back to list of plugins</a></div>\n);
-
-  if (!defined ($all_plugins->{$plugin}))
-  {
-    print qq(    <div class="error">Plugin &quot;${\encode_entities ($plugin)}&quot; not found for host &quot;${\encode_entities (@hosts)}&quot;.</div>\n);
-    return;
-  }
-
-  my @pinsts = sort (keys %{$all_plugins->{$plugin}});
-
-  print <<HTML;
-    <table class="graphs">
-      <tr>
-       <th>Plugin</th>
-HTML
-  for (my $i = 0; $i < @hosts; $i++)
-  {
-    print "\t<th>", encode_entities ($hosts[$i]), "</th>\n";
-  }
-  print "      </tr>\n";
-
-  for (my $j = 0; $j < @pinsts; $j++)
-  {
-    my $pinst = $pinsts[$j];
-    my $pinst_esc = encode_entities ($pinst);
-    my $title = $plugin . ($pinst ne '-' ? " ($pinst)" : '');
-    my $title_esc = encode_entities ($title);
-
-    my $param_plugin = "plugin=$plugin_esc";
-    if ($pinst ne '-')
-    {
-      $param_plugin .= ";plugin_instance=$pinst_esc";
-    }
-
-    my $files_printed = 0;
-    my $files_num = _files_plugin_inst_count ($all_plugins->{$plugin}{$pinst});
-    next if (!$files_num);
-
-    my $rowspan = ($files_num == 1) ? '' : qq( rowspan="$files_num");
-
-    for (sort (keys %{$all_plugins->{$plugin}{$pinst}}))
-    {
-      my $type = $_;
-      my $type_esc = encode_entities ($type);
-
-      if (exists ($MetaGraphDefs->{$type}))
-      {
-       my $param_type = "type=$type_esc";
-
-       print "      <tr>\n";
-       if ($files_printed == 0)
-       {
-         print "\t<td$rowspan>$title_esc</td>\n";
-       }
-
-       for (my $k = 0; $k < @hosts; $k++)
-       {
-         my $host = $hosts[$k];
-         my $host_esc = encode_entities ($host);
-
-         print "\t<td>";
-         if (exists $plugins_per_host->{$host}{$plugin}{$pinst}{$type})
-         {
-           print qq(<img src="${\script_name ()}?action=show_graph;host=$host_esc;$param_plugin;$param_type;timespan=$timespan" />);
-           #print encode_entities (qq(<img src="${\script_name ()}?action=show_graph;host=$host_esc;$param_plugin;$param_type;timespan=$timespan" />));
-         }
-         print "</td>\n";
-       } # for (my $k = 0; $k < @hosts; $k++)
-
-       print "      </tr>\n";
-
-       $files_printed++;
-       next; # pinst
-      }
-
-      for (sort (keys %{$all_plugins->{$plugin}{$pinst}{$type}}))
-      {
-       my $tinst = $_;
-       my $tinst_esc = encode_entities ($tinst);
-
-       my $param_type = "type=$type_esc";
-       if ($tinst ne '-')
-       {
-         $param_type .= ";type_instance=$tinst_esc";
-       }
-
-       print "      <tr>\n";
-       if ($files_printed == 0)
-       {
-         print "\t<td$rowspan>$title_esc</td>\n";
-       }
-
-       for (my $k = 0; $k < @hosts; $k++)
-       {
-         my $host = $hosts[$k];
-         my $host_esc = encode_entities ($host);
-
-         print "\t<td>";
-         if ($plugins_per_host->{$host}{$plugin}{$pinst}{$type}{$tinst})
-         {
-           print qq(<img src="${\script_name ()}?action=show_graph;host=$host_esc;$param_plugin;$param_type;timespan=$timespan" />);
-           #print encode_entities (qq(<img src="${\script_name ()}?action=show_graph;host=$host_esc;$param_plugin;$param_type;timespan=$timespan" />));
-         }
-         print "</td>\n";
-       } # for (my $k = 0; $k < @hosts; $k++)
-
-       print "      </tr>\n";
-
-       $files_printed++;
-      } # for ($tinst)
-    } # for ($type)
-  } # for (my $j = 0; $j < @pinsts; $j++)
+    } # for ($pinst)
+  } # for ($plugin)
   print "   </table>\n";
 } # action_show_plugin
 
@@ -830,7 +809,7 @@ HTML
 
   if (keys %selected_hosts)
   {
-    my $all_plugins = _find_files_for_hosts (@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);
@@ -1025,10 +1004,10 @@ sub load_graph_definitions
     'GPRINT:max:MAX:%5.1lf%s Max,',
     'GPRINT:avg:LAST:%5.1lf%s Last\l'
     ],
-    charge => [
-    'DEF:avg={file}:charge:AVERAGE',
-    'DEF:min={file}:charge:MIN',
-    'DEF:max={file}:charge:MAX',
+    charge => ['-v', 'Ah',
+    'DEF:avg={file}:value:AVERAGE',
+    'DEF:min={file}:value:MIN',
+    'DEF:max={file}:value:MAX',
     "AREA:max#$HalfBlue",
     "AREA:min#$Canvas",
     "LINE1:avg#$FullBlue:Charge",
@@ -1037,17 +1016,17 @@ sub load_graph_definitions
     'GPRINT:max:MAX:%5.1lf%sAh Max,',
     'GPRINT:avg:LAST:%5.1lf%sAh Last\l'
     ],
-    charge_percent => [
-    'DEF:avg={file}:percent:AVERAGE',
-    'DEF:min={file}:percent:MIN',
-    'DEF:max={file}:percent:MAX',
+    connections => ['-v', 'Connections',
+    'DEF:avg={file}:value:AVERAGE',
+    'DEF:min={file}:value:MIN',
+    'DEF:max={file}:value:MAX',
     "AREA:max#$HalfBlue",
     "AREA:min#$Canvas",
-    "LINE1:avg#$FullBlue:Charge",
-    'GPRINT:min:MIN:%5.1lf%s%% Min,',
-    'GPRINT:avg:AVERAGE:%5.1lf%s%% Avg,',
-    'GPRINT:max:MAX:%5.1lf%s%% Max,',
-    'GPRINT:avg:LAST:%5.1lf%s%% Last\l'
+    "LINE1:avg#$FullBlue:Connections",
+    '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'
     ],
     cpu => ['-v', 'CPU load',
     'DEF:avg={file}:value:AVERAGE',
@@ -1061,10 +1040,10 @@ sub load_graph_definitions
     'GPRINT:max:MAX:%6.2lf%% Max,',
     'GPRINT:avg:LAST:%6.2lf%% Last\l'
     ],
-    current => [
-    'DEF:avg={file}:current:AVERAGE',
-    'DEF:min={file}:current:MIN',
-    'DEF:max={file}:current:MAX',
+    current => ['-v', 'Ampere',
+    'DEF:avg={file}:value:AVERAGE',
+    'DEF:min={file}:value:MIN',
+    'DEF:max={file}:value:MAX',
     "AREA:max#$HalfBlue",
     "AREA:min#$Canvas",
     "LINE1:avg#$FullBlue:Current",
@@ -1227,7 +1206,7 @@ sub load_graph_definitions
     'GPRINT:inc_max:MAX:%5.1lf%ss Max,',
     'GPRINT:inc_avg:LAST:%5.1lf%ss Last\l'
     ],
-    dns_traffic => ['DEF:rsp_min_raw={file}:responses:MIN',
+    dns_octets => ['DEF:rsp_min_raw={file}:responses:MIN',
     'DEF:rsp_avg_raw={file}:responses:AVERAGE',
     'DEF:rsp_max_raw={file}:responses:MAX',
     'DEF:qry_min_raw={file}:queries:MIN',
@@ -1262,6 +1241,18 @@ sub load_graph_definitions
     'GPRINT:qry_avg:LAST:%5.1lf%s Last',
     'GPRINT:qry_avg_sum:LAST:(ca. %5.1lf%sB Total)\l'
     ],
+    dns_opcode => [
+    'DEF:avg={file}:value:AVERAGE',
+    'DEF:min={file}:value:MIN',
+    'DEF:max={file}:value:MAX',
+    "AREA:max#$HalfBlue",
+    "AREA:min#$Canvas",
+    "LINE1:avg#$FullBlue:Queries/s",
+    'GPRINT:min:MIN:%9.3lf Min,',
+    'GPRINT:avg:AVERAGE:%9.3lf Average,',
+    'GPRINT:max:MAX:%9.3lf Max,',
+    'GPRINT:avg:LAST:%9.3lf Last\l'
+    ],
     email_count => ['-v', 'Mails',
     'DEF:avg={file}:value:AVERAGE',
     'DEF:min={file}:value:MIN',
@@ -1382,6 +1373,18 @@ sub load_graph_definitions
     'GPRINT:temp_max:MAX:%4.1lf Max,',
     'GPRINT:temp_avg:LAST:%4.1lf Last\l'
     ],
+    humidity => ['-v', 'Percent',
+    'DEF:temp_avg={file}:value:AVERAGE',
+    'DEF:temp_min={file}:value:MIN',
+    'DEF:temp_max={file}:value:MAX',
+    "AREA:temp_max#$HalfGreen",
+    "AREA:temp_min#$Canvas",
+    "LINE1:temp_avg#$FullGreen:Temperature",
+    'GPRINT:temp_min:MIN:%4.1lf%% Min,',
+    'GPRINT:temp_avg:AVERAGE:%4.1lf%% Avg,',
+    'GPRINT:temp_max:MAX:%4.1lf%% Max,',
+    'GPRINT:temp_avg:LAST:%4.1lf%% Last\l'
+    ],
     if_errors => ['-v', 'Errors/s',
     'DEF:tx_min={file}:tx:MIN',
     'DEF:tx_avg={file}:tx:AVERAGE',
@@ -1608,6 +1611,89 @@ sub load_graph_definitions
     'GPRINT:spam:LAST:%4.1lf Last',
     'HRULE:0#000000'
     ],
+    memcached_command => ['-v', 'Commands',
+    'DEF:avg={file}:value:AVERAGE',
+    'DEF:min={file}:value:MIN',
+    'DEF:max={file}:value:MAX',
+    "AREA:max#$HalfBlue",
+    "AREA:min#$Canvas",
+    "LINE1:avg#$FullBlue:Commands",
+    'GPRINT:min:MIN:%5.1lf%s Min,',
+    'GPRINT:avg:AVERAGE:%5.1lf Avg,',
+    'GPRINT:max:MAX:%5.1lf Max,',
+    'GPRINT:avg:LAST:%5.1lf Last\l'
+    ],
+    memcached_connections => ['-v', 'Connections',
+    'DEF:avg={file}:value:AVERAGE',
+    'DEF:min={file}:value:MIN',
+    'DEF:max={file}:value:MAX',
+    "AREA:max#$HalfBlue",
+    "AREA:min#$Canvas",
+    "LINE1:avg#$FullBlue:Connections",
+    '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'
+    ],
+    memcached_items => ['-v', 'Items',
+    'DEF:avg={file}:value:AVERAGE',
+    'DEF:min={file}:value:MIN',
+    'DEF:max={file}:value:MAX',
+    "AREA:max#$HalfBlue",
+    "AREA:min#$Canvas",
+    "LINE1:avg#$FullBlue:Items",
+    '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'
+    ],
+    memcached_octets => ['-v', 'Bits/s',
+    'DEF:out_min={file}:tx:MIN',
+    'DEF:out_avg={file}:tx:AVERAGE',
+    'DEF:out_max={file}:tx:MAX',
+    'DEF:inc_min={file}:rx:MIN',
+    'DEF:inc_avg={file}:rx:AVERAGE',
+    'DEF:inc_max={file}:rx:MAX',
+    'CDEF:mytime=out_avg,TIME,TIME,IF',
+    'CDEF:sample_len_raw=mytime,PREV(mytime),-',
+    'CDEF:sample_len=sample_len_raw,UN,0,sample_len_raw,IF',
+    'CDEF:out_avg_sample=out_avg,UN,0,out_avg,IF,sample_len,*',
+    'CDEF:out_avg_sum=PREV,UN,0,PREV,IF,out_avg_sample,+',
+    'CDEF:inc_avg_sample=inc_avg,UN,0,inc_avg,IF,sample_len,*',
+    'CDEF:inc_avg_sum=PREV,UN,0,PREV,IF,inc_avg_sample,+',
+    'CDEF:out_bit_min=out_min,8,*',
+    'CDEF:out_bit_avg=out_avg,8,*',
+    'CDEF:out_bit_max=out_max,8,*',
+    'CDEF:inc_bit_min=inc_min,8,*',
+    'CDEF:inc_bit_avg=inc_avg,8,*',
+    'CDEF:inc_bit_max=inc_max,8,*',
+    'CDEF:overlap=out_bit_avg,inc_bit_avg,GT,inc_bit_avg,out_bit_avg,IF',
+    "AREA:out_bit_avg#$HalfGreen",
+    "AREA:inc_bit_avg#$HalfBlue",
+    "AREA:overlap#$HalfBlueGreen",
+    "LINE1:out_bit_avg#$FullGreen:Written",
+    'GPRINT:out_bit_avg:AVERAGE:%5.1lf%s Avg,',
+    'GPRINT:out_bit_max:MAX:%5.1lf%s Max,',
+    'GPRINT:out_bit_avg:LAST:%5.1lf%s Last',
+    'GPRINT:out_avg_sum:LAST:(ca. %5.1lf%sB Total)\l',
+    "LINE1:inc_bit_avg#$FullBlue:Read   ",
+    'GPRINT:inc_bit_avg:AVERAGE:%5.1lf%s Avg,',
+    'GPRINT:inc_bit_max:MAX:%5.1lf%s Max,',
+    'GPRINT:inc_bit_avg:LAST:%5.1lf%s Last',
+    'GPRINT:inc_avg_sum:LAST:(ca. %5.1lf%sB Total)\l'
+    ],
+    memcached_ops => ['-v', 'Ops',
+    'DEF:avg={file}:value:AVERAGE',
+    'DEF:min={file}:value:MIN',
+    'DEF:max={file}:value:MAX',
+    "AREA:max#$HalfBlue",
+    "AREA:min#$Canvas",
+    "LINE1:avg#$FullBlue:Ops",
+    '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'
+    ],
     memory => ['-b', '1024', '-v', 'Bytes',
     'DEF:avg={file}:value:AVERAGE',
     'DEF:min={file}:value:MIN',
@@ -1669,7 +1755,7 @@ sub load_graph_definitions
     "DEF:val_max={file}:value:MAX",
     "AREA:val_max#$HalfBlue",
     "AREA:val_min#$Canvas",
-    "LINE1:val_avg#$FullBlue:{inst}",
+    "LINE1:val_avg#$FullBlue:Issues/s",
     'GPRINT:val_min:MIN:%5.2lf Min,',
     'GPRINT:val_avg:AVERAGE:%5.2lf Avg,',
     'GPRINT:val_max:MAX:%5.2lf Max,',
@@ -1681,20 +1767,19 @@ sub load_graph_definitions
     "DEF:val_max={file}:value:MAX",
     "AREA:val_max#$HalfBlue",
     "AREA:val_min#$Canvas",
-    "LINE1:val_avg#$FullBlue:{inst}",
+    "LINE1:val_avg#$FullBlue:Issues/s",
     'GPRINT:val_min:MIN:%5.2lf Min,',
     'GPRINT:val_avg:AVERAGE:%5.2lf Avg,',
     'GPRINT:val_max:MAX:%5.2lf Max,',
     'GPRINT:val_avg:LAST:%5.2lf Last'
     ],
-    mysql_octets => ['-v', 'Bytes/s',
+    mysql_octets => ['-v', 'Bits/s',
     'DEF:out_min={file}:tx:MIN',
     'DEF:out_avg={file}:tx:AVERAGE',
     'DEF:out_max={file}:tx:MAX',
     'DEF:inc_min={file}:rx:MIN',
     'DEF:inc_avg={file}:rx:AVERAGE',
     'DEF:inc_max={file}:rx:MAX',
-    'CDEF:overlap=out_avg,inc_avg,GT,inc_avg,out_avg,IF',
     'CDEF:mytime=out_avg,TIME,TIME,IF',
     'CDEF:sample_len_raw=mytime,PREV(mytime),-',
     'CDEF:sample_len=sample_len_raw,UN,0,sample_len_raw,IF',
@@ -1702,18 +1787,25 @@ sub load_graph_definitions
     'CDEF:out_avg_sum=PREV,UN,0,PREV,IF,out_avg_sample,+',
     'CDEF:inc_avg_sample=inc_avg,UN,0,inc_avg,IF,sample_len,*',
     'CDEF:inc_avg_sum=PREV,UN,0,PREV,IF,inc_avg_sample,+',
-    "AREA:out_avg#$HalfGreen",
-    "AREA:inc_avg#$HalfBlue",
+    'CDEF:out_bit_min=out_min,8,*',
+    'CDEF:out_bit_avg=out_avg,8,*',
+    'CDEF:out_bit_max=out_max,8,*',
+    'CDEF:inc_bit_min=inc_min,8,*',
+    'CDEF:inc_bit_avg=inc_avg,8,*',
+    'CDEF:inc_bit_max=inc_max,8,*',
+    'CDEF:overlap=out_bit_avg,inc_bit_avg,GT,inc_bit_avg,out_bit_avg,IF',
+    "AREA:out_bit_avg#$HalfGreen",
+    "AREA:inc_bit_avg#$HalfBlue",
     "AREA:overlap#$HalfBlueGreen",
-    "LINE1:out_avg#$FullGreen:Written",
-    'GPRINT:out_avg:AVERAGE:%5.1lf%s Avg,',
-    'GPRINT:out_max:MAX:%5.1lf%s Max,',
-    'GPRINT:out_avg:LAST:%5.1lf%s Last',
+    "LINE1:out_bit_avg#$FullGreen:Written",
+    'GPRINT:out_bit_avg:AVERAGE:%5.1lf%s Avg,',
+    'GPRINT:out_bit_max:MAX:%5.1lf%s Max,',
+    'GPRINT:out_bit_avg:LAST:%5.1lf%s Last',
     'GPRINT:out_avg_sum:LAST:(ca. %5.1lf%sB Total)\l',
-    "LINE1:inc_avg#$FullBlue:Read   ",
-    'GPRINT:inc_avg:AVERAGE:%5.1lf%s Avg,',
-    'GPRINT:inc_max:MAX:%5.1lf%s Max,',
-    'GPRINT:inc_avg:LAST:%5.1lf%s Last',
+    "LINE1:inc_bit_avg#$FullBlue:Read   ",
+    'GPRINT:inc_bit_avg:AVERAGE:%5.1lf%s Avg,',
+    'GPRINT:inc_bit_max:MAX:%5.1lf%s Max,',
+    'GPRINT:inc_bit_avg:LAST:%5.1lf%s Last',
     'GPRINT:inc_avg_sum:LAST:(ca. %5.1lf%sB Total)\l'
     ],
     mysql_qcache => ['-v', 'Queries/s',
@@ -1912,18 +2004,6 @@ sub load_graph_definitions
     'GPRINT:read_avg:AVERAGE:%5.1lf Avg,',
     'GPRINT:read_avg:LAST:%5.1lf Last\l'
     ],
-    opcode => [
-    'DEF:avg={file}:value:AVERAGE',
-    'DEF:min={file}:value:MIN',
-    'DEF:max={file}:value:MAX',
-    "AREA:max#$HalfBlue",
-    "AREA:min#$Canvas",
-    "LINE1:avg#$FullBlue:Queries/s",
-    'GPRINT:min:MIN:%9.3lf Min,',
-    'GPRINT:avg:AVERAGE:%9.3lf Average,',
-    'GPRINT:max:MAX:%9.3lf Max,',
-    'GPRINT:avg:LAST:%9.3lf Last\l'
-    ],
     partition => [
     "DEF:rbyte_avg={file}:rbytes:AVERAGE",
     "DEF:rbyte_min={file}:rbytes:MIN",
@@ -1968,6 +2048,88 @@ sub load_graph_definitions
     'GPRINT:ping_avg:AVERAGE:%4.1lf ms Avg,',
     'GPRINT:ping_max:MAX:%4.1lf ms Max,',
     'GPRINT:ping_avg:LAST:%4.1lf ms Last'],
+    pg_blks => ['DEF:pg_blks_avg={file}:value:AVERAGE',
+    'DEF:pg_blks_min={file}:value:MIN',
+    'DEF:pg_blks_max={file}:value:MAX',
+    "AREA:pg_blks_max#$HalfBlue",
+    "AREA:pg_blks_min#$Canvas",
+    "LINE1:pg_blks_avg#$FullBlue:Blocks",
+    'GPRINT:pg_blks_min:MIN:%4.1lf%s Min,',
+    'GPRINT:pg_blks_avg:AVERAGE:%4.1lf%s Avg,',
+    'GPRINT:pg_blks_max:MAX:%4.1lf%s Max,',
+    'GPRINT:pg_blks_avg:LAST:%4.1lf%s Last'],
+    pg_db_size => ['DEF:pg_db_size_avg={file}:value:AVERAGE',
+    'DEF:pg_db_size_min={file}:value:MIN',
+    'DEF:pg_db_size_max={file}:value:MAX',
+    "AREA:pg_db_size_max#$HalfBlue",
+    "AREA:pg_db_size_min#$Canvas",
+    "LINE1:pg_db_size_avg#$FullBlue:Bytes",
+    'GPRINT:pg_db_size_min:MIN:%4.1lf%s Min,',
+    'GPRINT:pg_db_size_avg:AVERAGE:%4.1lf%s Avg,',
+    'GPRINT:pg_db_size_max:MAX:%4.1lf%s Max,',
+    'GPRINT:pg_db_size_avg:LAST:%4.1lf%s Last'],
+    pg_n_tup_c => ['DEF:pg_n_tup_avg={file}:value:AVERAGE',
+    'DEF:pg_n_tup_min={file}:value:MIN',
+    'DEF:pg_n_tup_max={file}:value:MAX',
+    "AREA:pg_n_tup_max#$HalfBlue",
+    "AREA:pg_n_tup_min#$Canvas",
+    "LINE1:pg_n_tup_avg#$FullBlue:Tuples",
+    'GPRINT:pg_n_tup_min:MIN:%4.1lf%s Min,',
+    'GPRINT:pg_n_tup_avg:AVERAGE:%4.1lf%s Avg,',
+    'GPRINT:pg_n_tup_max:MAX:%4.1lf%s Max,',
+    'GPRINT:pg_n_tup_avg:LAST:%4.1lf%s Last'],
+    pg_n_tup_g => ['DEF:pg_n_tup_avg={file}:value:AVERAGE',
+    'DEF:pg_n_tup_min={file}:value:MIN',
+    'DEF:pg_n_tup_max={file}:value:MAX',
+    "AREA:pg_n_tup_max#$HalfBlue",
+    "AREA:pg_n_tup_min#$Canvas",
+    "LINE1:pg_n_tup_avg#$FullBlue:Tuples",
+    'GPRINT:pg_n_tup_min:MIN:%4.1lf%s Min,',
+    'GPRINT:pg_n_tup_avg:AVERAGE:%4.1lf%s Avg,',
+    'GPRINT:pg_n_tup_max:MAX:%4.1lf%s Max,',
+    'GPRINT:pg_n_tup_avg:LAST:%4.1lf%s Last'],
+    pg_numbackends => ['DEF:pg_numbackends_avg={file}:value:AVERAGE',
+    'DEF:pg_numbackends_min={file}:value:MIN',
+    'DEF:pg_numbackends_max={file}:value:MAX',
+    "AREA:pg_numbackends_max#$HalfBlue",
+    "AREA:pg_numbackends_min#$Canvas",
+    "LINE1:pg_numbackends_avg#$FullBlue:Backends",
+    'GPRINT:pg_numbackends_min:MIN:%4.1lf%s Min,',
+    'GPRINT:pg_numbackends_avg:AVERAGE:%4.1lf%s Avg,',
+    'GPRINT:pg_numbackends_max:MAX:%4.1lf%s Max,',
+    'GPRINT:pg_numbackends_avg:LAST:%4.1lf%s Last'],
+    pg_scan => ['DEF:pg_scan_avg={file}:value:AVERAGE',
+    'DEF:pg_scan_min={file}:value:MIN',
+    'DEF:pg_scan_max={file}:value:MAX',
+    "AREA:pg_scan_max#$HalfBlue",
+    "AREA:pg_scan_min#$Canvas",
+    "LINE1:pg_scan_avg#$FullBlue:Scans",
+    'GPRINT:pg_scan_min:MIN:%4.1lf%s Min,',
+    'GPRINT:pg_scan_avg:AVERAGE:%4.1lf%s Avg,',
+    'GPRINT:pg_scan_max:MAX:%4.1lf%s Max,',
+    'GPRINT:pg_scan_avg:LAST:%4.1lf%s Last'],
+    pg_xact => ['DEF:pg_xact_avg={file}:value:AVERAGE',
+    'DEF:pg_xact_min={file}:value:MIN',
+    'DEF:pg_xact_max={file}:value:MAX',
+    "AREA:pg_xact_max#$HalfBlue",
+    "AREA:pg_xact_min#$Canvas",
+    "LINE1:pg_xact_avg#$FullBlue:Transactions",
+    'GPRINT:pg_xact_min:MIN:%4.1lf%s Min,',
+    'GPRINT:pg_xact_avg:AVERAGE:%4.1lf%s Avg,',
+    'GPRINT:pg_xact_max:MAX:%4.1lf%s Max,',
+    'GPRINT:pg_xact_avg:LAST:%4.1lf%s Last'],
+    power => ['-v', 'Watt',
+    'DEF:avg={file}:value:AVERAGE',
+    'DEF:min={file}:value:MIN',
+    'DEF:max={file}:value:MAX',
+    "AREA:max#$HalfBlue",
+    "AREA:min#$Canvas",
+    "LINE1:avg#$FullBlue:Watt",
+    'GPRINT:min:MIN:%5.1lf%sW Min,',
+    'GPRINT:avg:AVERAGE:%5.1lf%sW Avg,',
+    'GPRINT:max:MAX:%5.1lf%sW Max,',
+    'GPRINT:avg:LAST:%5.1lf%sW Last\l'
+    ],
     processes => [
     "DEF:running_avg={file}:running:AVERAGE",
     "DEF:running_min={file}:running:MIN",
@@ -2030,18 +2192,27 @@ sub load_graph_definitions
     'GPRINT:sleeping_max:MAX:%5.1lf Max,',
     'GPRINT:sleeping_avg:LAST:%5.1lf Last\l'
     ],
-    ps_rss => [
-    'DEF:avg={file}:byte:AVERAGE',
-    'DEF:min={file}:byte:MIN',
-    'DEF:max={file}:byte:MAX',
-    "AREA:avg#$HalfBlue",
-    "LINE1:avg#$FullBlue:RSS",
-    'GPRINT:min:MIN:%5.1lf%s Min,',
-    'GPRINT:avg:AVERAGE:%5.1lf%s Avg,',
-    'GPRINT:max:MAX:%5.1lf%s Max,',
-    'GPRINT:avg:LAST:%5.1lf%s Last\l'
+    ps_count => ['-v', 'Processes',
+    'DEF:procs_avg={file}:processes:AVERAGE',
+    'DEF:procs_min={file}:processes:MIN',
+    'DEF:procs_max={file}:processes:MAX',
+    'DEF:thrds_avg={file}:threads:AVERAGE',
+    'DEF:thrds_min={file}:threads:MIN',
+    'DEF:thrds_max={file}:threads:MAX',
+    "AREA:thrds_avg#$HalfBlue",
+    "AREA:procs_avg#$HalfRed",
+    "LINE1:thrds_avg#$FullBlue:Threads  ",
+    'GPRINT:thrds_min:MIN:%5.1lf Min,',
+    'GPRINT:thrds_avg:AVERAGE:%5.1lf Avg,',
+    'GPRINT:thrds_max:MAX:%5.1lf Max,',
+    'GPRINT:thrds_avg:LAST:%5.1lf Last\l',
+    "LINE1:procs_avg#$FullRed:Processes",
+    'GPRINT:procs_min:MIN:%5.1lf Min,',
+    'GPRINT:procs_avg:AVERAGE:%5.1lf Avg,',
+    'GPRINT:procs_max:MAX:%5.1lf Max,',
+    'GPRINT:procs_avg:LAST:%5.1lf Last\l'
     ],
-    ps_cputime => [
+    ps_cputime => ['-v', 'Jiffies',
     'DEF:user_avg_raw={file}:user:AVERAGE',
     'DEF:user_min_raw={file}:user:MIN',
     'DEF:user_max_raw={file}:user:MAX',
@@ -2068,27 +2239,7 @@ sub load_graph_definitions
     'GPRINT:syst_max:MAX:%5.1lf%s Max,',
     'GPRINT:syst_avg:LAST:%5.1lf%s Last\l'
     ],
-    ps_count => [
-    'DEF:procs_avg={file}:processes:AVERAGE',
-    'DEF:procs_min={file}:processes:MIN',
-    'DEF:procs_max={file}:processes:MAX',
-    'DEF:thrds_avg={file}:threads:AVERAGE',
-    'DEF:thrds_min={file}:threads:MIN',
-    'DEF:thrds_max={file}:threads:MAX',
-    "AREA:thrds_avg#$HalfBlue",
-    "AREA:procs_avg#$HalfRed",
-    "LINE1:thrds_avg#$FullBlue:Threads  ",
-    'GPRINT:thrds_min:MIN:%5.1lf Min,',
-    'GPRINT:thrds_avg:AVERAGE:%5.1lf Avg,',
-    'GPRINT:thrds_max:MAX:%5.1lf Max,',
-    'GPRINT:thrds_avg:LAST:%5.1lf Last\l',
-    "LINE1:procs_avg#$FullRed:Processes",
-    'GPRINT:procs_min:MIN:%5.1lf Min,',
-    'GPRINT:procs_avg:AVERAGE:%5.1lf Avg,',
-    'GPRINT:procs_max:MAX:%5.1lf Max,',
-    'GPRINT:procs_avg:LAST:%5.1lf Last\l'
-    ],
-    ps_pagefaults => [
+    ps_pagefaults => ['-v', 'Pagefaults/s',
     'DEF:minor_avg={file}:minflt:AVERAGE',
     'DEF:minor_min={file}:minflt:MIN',
     'DEF:minor_max={file}:minflt:MAX',
@@ -2109,6 +2260,17 @@ sub load_graph_definitions
     'GPRINT:major_max:MAX:%5.1lf%s Max,',
     'GPRINT:major_avg:LAST:%5.1lf%s Last\l'
     ],
+    ps_rss => ['-v', 'Bytes',
+    'DEF:avg={file}:value:AVERAGE',
+    'DEF:min={file}:value:MIN',
+    'DEF:max={file}:value:MAX',
+    "AREA:avg#$HalfBlue",
+    "LINE1:avg#$FullBlue:RSS",
+    'GPRINT:min:MIN:%5.1lf%s Min,',
+    'GPRINT:avg:AVERAGE:%5.1lf%s Avg,',
+    'GPRINT:max:MAX:%5.1lf%s Max,',
+    'GPRINT:avg:LAST:%5.1lf%s Last\l'
+    ],
     ps_state => ['-v', 'Processes',
     'DEF:avg={file}:value:AVERAGE',
     'DEF:min={file}:value:MIN',
@@ -2121,29 +2283,41 @@ sub load_graph_definitions
     'GPRINT:max:MAX:%6.2lf Max,',
     'GPRINT:avg:LAST:%6.2lf Last\l'
     ],
-    qtype => [
+    signal_noise => ['-v', 'dBm',
     'DEF:avg={file}:value:AVERAGE',
     'DEF:min={file}:value:MIN',
     'DEF:max={file}:value:MAX',
     "AREA:max#$HalfBlue",
     "AREA:min#$Canvas",
-    "LINE1:avg#$FullBlue:Queries/s",
-    'GPRINT:min:MIN:%9.3lf Min,',
-    'GPRINT:avg:AVERAGE:%9.3lf Average,',
-    'GPRINT:max:MAX:%9.3lf Max,',
-    'GPRINT:avg:LAST:%9.3lf Last\l'
+    "LINE1:avg#$FullBlue:Noise",
+    'GPRINT:min:MIN:%5.1lf%sdBm Min,',
+    'GPRINT:avg:AVERAGE:%5.1lf%sdBm Avg,',
+    'GPRINT:max:MAX:%5.1lf%sdBm Max,',
+    'GPRINT:avg:LAST:%5.1lf%sdBm Last\l'
     ],
-    rcode => [
+    signal_power => ['-v', 'dBm',
     'DEF:avg={file}:value:AVERAGE',
     'DEF:min={file}:value:MIN',
     'DEF:max={file}:value:MAX',
     "AREA:max#$HalfBlue",
     "AREA:min#$Canvas",
-    "LINE1:avg#$FullBlue:Queries/s",
-    'GPRINT:min:MIN:%9.3lf Min,',
-    'GPRINT:avg:AVERAGE:%9.3lf Average,',
-    'GPRINT:max:MAX:%9.3lf Max,',
-    'GPRINT:avg:LAST:%9.3lf Last\l'
+    "LINE1:avg#$FullBlue:Power",
+    'GPRINT:min:MIN:%5.1lf%sdBm Min,',
+    'GPRINT:avg:AVERAGE:%5.1lf%sdBm Avg,',
+    'GPRINT:max:MAX:%5.1lf%sdBm Max,',
+    'GPRINT:avg:LAST:%5.1lf%sdBm Last\l'
+    ],
+    signal_quality => ['-v', '%',
+    'DEF:avg={file}:value:AVERAGE',
+    'DEF:min={file}:value:MIN',
+    'DEF:max={file}:value:MAX',
+    "AREA:max#$HalfBlue",
+    "AREA:min#$Canvas",
+    "LINE1:avg#$FullBlue:Quality",
+    'GPRINT:min:MIN:%5.1lf%s%% Min,',
+    'GPRINT:avg:AVERAGE:%5.1lf%s%% Avg,',
+    'GPRINT:max:MAX:%5.1lf%s%% Max,',
+    'GPRINT:avg:LAST:%5.1lf%s%% Last\l'
     ],
     swap => ['-v', 'Bytes', '-b', '1024',
     'DEF:avg={file}:value:AVERAGE',
@@ -2157,7 +2331,7 @@ sub load_graph_definitions
     'GPRINT:max:MAX:%6.2lf%sByte Max,',
     'GPRINT:avg:LAST:%6.2lf%sByte Last\l'
     ],
-    ols_swap => [
+    old_swap => [
     'DEF:used_avg={file}:used:AVERAGE',
     'DEF:used_min={file}:used:MIN',
     'DEF:used_max={file}:used:MAX',
@@ -2201,26 +2375,32 @@ sub load_graph_definitions
     'GPRINT:used_max:MAX:%5.1lf%s Max,',
     'GPRINT:used_avg:LAST:%5.1lf%s Last\l'
     ],
+    tcp_connections => ['-v', 'Connections',
+    'DEF:avg={file}:value:AVERAGE',
+    'DEF:min={file}:value:MIN',
+    'DEF:max={file}:value:MAX',
+    "AREA:max#$HalfBlue",
+    "AREA:min#$Canvas",
+    "LINE1:avg#$FullBlue:Connections",
+    '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'
+    ],
     temperature => ['-v', 'Celsius',
     'DEF:temp_avg={file}:value:AVERAGE',
     'DEF:temp_min={file}:value:MIN',
     'DEF:temp_max={file}:value:MAX',
     'CDEF:average=temp_avg,0.2,*,PREV,UN,temp_avg,PREV,IF,0.8,*,+',
-    'CDEF:derivative=PREV(average),average,-',
-    'CDEF:rising=derivative,-0.01,LT,INF,UNKN,IF',
-    'CDEF:falling=derivative,0.01,GT,INF,UNKN,IF',
-    "AREA:rising#f0fff0",
-    "AREA:falling#fff0f0",
     "AREA:temp_max#$HalfRed",
     "AREA:temp_min#$Canvas",
-    #"LINE1:average#000000",
     "LINE1:temp_avg#$FullRed:Temperature",
     'GPRINT:temp_min:MIN:%4.1lf Min,',
     'GPRINT:temp_avg:AVERAGE:%4.1lf Avg,',
     'GPRINT:temp_max:MAX:%4.1lf Max,',
     'GPRINT:temp_avg:LAST:%4.1lf Last\l'
     ],
-    timeleft => [
+    timeleft => ['-v', 'Minutes',
     'DEF:avg={file}:timeleft:AVERAGE',
     'DEF:min={file}:timeleft:MIN',
     'DEF:max={file}:timeleft:MAX',
@@ -2304,7 +2484,7 @@ sub load_graph_definitions
     'GPRINT:multimeter_max:MAX:%4.1lf Max,',
     'GPRINT:multimeter_avg:LAST:%4.1lf Last\l'
     ],
-    users => [
+    users => ['-v', 'Users',
     'DEF:users_avg={file}:users:AVERAGE',
     'DEF:users_min={file}:users:MIN',
     'DEF:users_max={file}:users:MAX',
@@ -2329,91 +2509,59 @@ sub load_graph_definitions
     'GPRINT:avg:LAST:%5.1lf%sV Last\l'
     ],
     vs_threads => [
-    "DEF:total_avg={file}:total:AVERAGE",
-    "DEF:total_min={file}:total:MIN",
-    "DEF:total_max={file}:total:MAX",
-    "DEF:running_avg={file}:running:AVERAGE",
-    "DEF:running_min={file}:running:MIN",
-    "DEF:running_max={file}:running:MAX",
-    "DEF:uninterruptible_avg={file}:uninterruptible:AVERAGE",
-    "DEF:uninterruptible_min={file}:uninterruptible:MIN",
-    "DEF:uninterruptible_max={file}:uninterruptible:MAX",
-    "DEF:onhold_avg={file}:onhold:AVERAGE",
-    "DEF:onhold_min={file}:onhold:MIN",
-    "DEF:onhold_max={file}:onhold:MAX",
-    "LINE1:total_avg#$FullYellow:Total   ",
-    'GPRINT:total_min:MIN:%5.1lf Min,',
-    'GPRINT:total_avg:AVERAGE:%5.1lf Avg.,',
-    'GPRINT:total_max:MAX:%5.1lf Max,',
-    'GPRINT:total_avg:LAST:%5.1lf Last\l',
-    "LINE1:running_avg#$FullRed:Running ",
-    'GPRINT:running_min:MIN:%5.1lf Min,',
-    'GPRINT:running_avg:AVERAGE:%5.1lf Avg.,',          
-    'GPRINT:running_max:MAX:%5.1lf Max,',
-    'GPRINT:running_avg:LAST:%5.1lf Last\l',
-    "LINE1:uninterruptible_avg#$FullGreen:Unintr  ",
-    'GPRINT:uninterruptible_min:MIN:%5.1lf Min,',
-    'GPRINT:uninterruptible_avg:AVERAGE:%5.1lf Avg.,',
-    'GPRINT:uninterruptible_max:MAX:%5.1lf Max,',
-    'GPRINT:uninterruptible_avg:LAST:%5.1lf Last\l',
-    "LINE1:onhold_avg#$FullBlue:Onhold  ",
-    'GPRINT:onhold_min:MIN:%5.1lf Min,',
-    'GPRINT:onhold_avg:AVERAGE:%5.1lf Avg.,',
-    'GPRINT:onhold_max:MAX:%5.1lf Max,',
-    'GPRINT:onhold_avg:LAST:%5.1lf Last\l'
-    ],
-    vs_memory => [
-    'DEF:vm_avg={file}:vm:AVERAGE',
-    'DEF:vm_min={file}:vm:MIN',
-    'DEF:vm_max={file}:vm:MAX',
-    'DEF:vml_avg={file}:vml:AVERAGE',
-    'DEF:vml_min={file}:vml:MIN',
-    'DEF:vml_max={file}:vml:MAX',
-    'DEF:rss_avg={file}:rss:AVERAGE',
-    'DEF:rss_min={file}:rss:MIN',
-    'DEF:rss_max={file}:rss:MAX',
-    'DEF:anon_avg={file}:anon:AVERAGE',
-    'DEF:anon_min={file}:anon:MIN',
-    'DEF:anon_max={file}:anon:MAX',
-    "LINE1:vm_avg#$FullYellow:VM     ",
-    'GPRINT:vm_min:MIN:%5.1lf%s Min,',
-    'GPRINT:vm_avg:AVERAGE:%5.1lf%s Avg.,',
-    'GPRINT:vm_max:MAX:%5.1lf%s Avg.,',
-    'GPRINT:vm_avg:LAST:%5.1lf%s Last\l',
-    "LINE1:vml_avg#$FullRed:Locked ",
-    'GPRINT:vml_min:MIN:%5.1lf%s Min,',
-    'GPRINT:vml_avg:AVERAGE:%5.1lf%s Avg.,',
-    'GPRINT:vml_max:MAX:%5.1lf%s Avg.,',
-    'GPRINT:vml_avg:LAST:%5.1lf%s Last\l',
-    "LINE1:rss_avg#$FullGreen:RSS    ",
-    'GPRINT:rss_min:MIN:%5.1lf%s Min,',
-    'GPRINT:rss_avg:AVERAGE:%5.1lf%s Avg.,',
-    'GPRINT:rss_max:MAX:%5.1lf%s Avg.,',
-    'GPRINT:rss_avg:LAST:%5.1lf%s Last\l',
-    "LINE1:anon_avg#$FullBlue:Anon.  ",
-    'GPRINT:anon_min:MIN:%5.1lf%s Min,',
-    'GPRINT:anon_avg:AVERAGE:%5.1lf%s Avg.,',
-    'GPRINT:anon_max:MAX:%5.1lf%s Avg.,',
-    'GPRINT:anon_avg:LAST:%5.1lf%s Last\l',
+    "DEF:avg={file}:value:AVERAGE",
+    "DEF:min={file}:value:MIN",
+    "DEF:max={file}:value:MAX",
+    "AREA:max#$HalfBlue",
+    "AREA:min#$Canvas",
+    "LINE1:avg#$FullBlue:Threads",
+    'GPRINT:min:MIN:%5.1lf Min,',
+    'GPRINT:avg:AVERAGE:%5.1lf Avg.,',
+    'GPRINT:max:MAX:%5.1lf Max,',
+    'GPRINT:avg:LAST:%5.1lf Last\l',
+    ],
+    vs_memory => ['-b', '1024', '-v', 'Bytes',
+    "DEF:avg={file}:value:AVERAGE",
+    "DEF:min={file}:value:MIN",
+    "DEF:max={file}:value:MAX",
+    "AREA:max#$HalfBlue",
+    "AREA:min#$Canvas",
+    "LINE1:avg#$FullBlue:",
+    'GPRINT:min:MIN:%5.1lf%sbytes Min,',
+    'GPRINT:avg:AVERAGE:%5.1lf%sbytes Avg.,',
+    'GPRINT:max:MAX:%5.1lf%sbytes Max,',
+    'GPRINT:avg:LAST:%5.1lf%sbytes Last\l',
     ],
     vs_processes => [
-    'DEF:proc_avg={file}:total:AVERAGE',
-    'DEF:proc_min={file}:total:MIN',
-    'DEF:proc_max={file}:total:MAX',
-    "AREA:proc_max#$HalfBlue",
-    "AREA:proc_min#$Canvas",
-    "LINE1:proc_avg#$FullBlue:Processes",
-    'GPRINT:proc_min:MIN:%4.1lf Min,',
-    'GPRINT:proc_avg:AVERAGE:%4.1lf Avg.,',
-    'GPRINT:proc_max:MAX:%4.1lf Max,',
-    'GPRINT:proc_avg:LAST:%4.1lf Last\l'
+    "DEF:avg={file}:value:AVERAGE",
+    "DEF:min={file}:value:MIN",
+    "DEF:max={file}:value:MAX",
+    "AREA:max#$HalfBlue",
+    "AREA:min#$Canvas",
+    "LINE1:avg#$FullBlue:Processes",
+    'GPRINT:min:MIN:%5.1lf Min,',
+    'GPRINT:avg:AVERAGE:%5.1lf Avg.,',
+    'GPRINT:max:MAX:%5.1lf Max,',
+    'GPRINT:avg:LAST:%5.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'};
 
   $MetaGraphDefs->{'cpu'} = \&meta_graph_cpu;
+  $MetaGraphDefs->{'dns_qtype'} = \&meta_graph_dns;
+  $MetaGraphDefs->{'dns_rcode'} = \&meta_graph_dns;
+  $MetaGraphDefs->{'if_rx_errors'} = \&meta_graph_if_rx_errors;
+  $MetaGraphDefs->{'if_tx_errors'} = \&meta_graph_if_rx_errors;
   $MetaGraphDefs->{'memory'} = \&meta_graph_memory;
+  $MetaGraphDefs->{'nfs_procedure'} = \&meta_graph_nfs_procedure;
+  $MetaGraphDefs->{'ps_state'} = \&meta_graph_ps_state;
+  $MetaGraphDefs->{'swap'} = \&meta_graph_swap;
+  $MetaGraphDefs->{'mysql_commands'} = \&meta_graph_mysql_commands;
+  $MetaGraphDefs->{'mysql_handler'} = \&meta_graph_mysql_commands;
+  $MetaGraphDefs->{'tcp_connections'} = \&meta_graph_tcp_connections;
 } # load_graph_definitions
 
 sub meta_graph_generic_stack
@@ -2436,12 +2584,21 @@ sub meta_graph_generic_stack
     @RRDDefaultArgs, @{$opts->{'rrd_opts'}});
 
   my $max_inst_name = 0;
+  my @vnames = ();
+
+  for ($i = 0; $i < @$sources; $i++)
+  {
+    my $tmp = $sources->[$i]->{'name'};
+    $tmp =~ tr/A-Za-z0-9\-_/_/c;
+    $vnames[$i] = $i . $tmp;
+  }
 
   for ($i = 0; $i < @$sources; $i++)
   {
     my $inst_data = $sources->[$i];
     my $inst_name = $inst_data->{'name'} || confess;
     my $file = $inst_data->{'file'} || confess;
+    my $vname = $vnames[$i];
 
     if (length ($inst_name) > $max_inst_name)
     {
@@ -2451,23 +2608,23 @@ sub meta_graph_generic_stack
     confess ("No such file: $file") if (!-e $file);
 
     push (@cmd,
-      qq#DEF:${inst_name}_min=$file:value:MIN#,
-      qq#DEF:${inst_name}_avg=$file:value:AVERAGE#,
-      qq#DEF:${inst_name}_max=$file:value:MAX#,
-      qq#CDEF:${inst_name}_nnl=${inst_name}_avg,UN,0,${inst_name}_avg,IF#);
+      qq#DEF:${vname}_min=$file:value:MIN#,
+      qq#DEF:${vname}_avg=$file:value:AVERAGE#,
+      qq#DEF:${vname}_max=$file:value:MAX#,
+      qq#CDEF:${vname}_nnl=${vname}_avg,UN,0,${vname}_avg,IF#);
   }
 
-  for (my $i = 0; $i < @$sources; $i++)
   {
-    my $inst_data0 = $sources->[@$sources - (1 + $i)];
-    my $inst_data1 = $sources->[@$sources - (($i == 0) ? 1 : $i)];
+    my $vname = $vnames[@vnames - 1];
 
-    my $inst_name0 = $inst_data0->{'name'};
-    my $inst_name1 = $inst_data1->{'name'};
-
-    my $cdef_name = ($i == 0) ? 'nnl' : 'stk';
+    push (@cmd, qq#CDEF:${vname}_stk=${vname}_nnl#);
+  }
+  for (my $i = 1; $i < @$sources; $i++)
+  {
+    my $vname0 = $vnames[@vnames - ($i + 1)];
+    my $vname1 = $vnames[@vnames - $i];
 
-    push (@cmd, qq#CDEF:${inst_name0}_stk=${inst_name0}_nnl,${inst_name1}_${cdef_name},+#);
+    push (@cmd, qq#CDEF:${vname0}_stk=${vname0}_nnl,${vname1}_stk,+#);
   }
 
   for (my $i = 0; $i < @$sources; $i++)
@@ -2475,6 +2632,8 @@ sub meta_graph_generic_stack
     my $inst_data = $sources->[$i];
     my $inst_name = $inst_data->{'name'};
 
+    my $vname = $vnames[$i];
+
     my $legend = sprintf ('%-*s', $max_inst_name, $inst_name);
 
     my $line_color;
@@ -2494,12 +2653,12 @@ sub meta_graph_generic_stack
     }
     $area_color = _color_to_string (_get_faded_color ($area_color));
 
-    push (@cmd, qq(AREA:${inst_name}_stk#$area_color),
-      qq(LINE1:${inst_name}_stk#$line_color:$legend),
-      qq(GPRINT:${inst_name}_min:MIN:$number_format Min,),
-      qq(GPRINT:${inst_name}_avg:AVERAGE:$number_format Avg,),
-      qq(GPRINT:${inst_name}_max:MAX:$number_format Max,),
-      qq(GPRINT:${inst_name}_avg:LAST:$number_format Last\l),
+    push (@cmd, qq(AREA:${vname}_stk#$area_color),
+      qq(LINE1:${vname}_stk#$line_color:$legend),
+      qq(GPRINT:${vname}_min:MIN:$number_format Min,),
+      qq(GPRINT:${vname}_avg:AVERAGE:$number_format Avg,),
+      qq(GPRINT:${vname}_max:MAX:$number_format Max,),
+      qq(GPRINT:${vname}_avg:LAST:$number_format Last\\l),
     );
   }
 
@@ -2526,6 +2685,8 @@ sub meta_graph_cpu
   $opts->{'title'} = "$host/$plugin"
   . (defined ($plugin_instance) ? "-$plugin_instance" : '') . "/$type";
 
+  $opts->{'rrd_opts'} = ['-v', 'Percent'];
+
   my @files = ();
 
   $opts->{'colors'} =
@@ -2570,6 +2731,57 @@ sub meta_graph_cpu
   return (meta_graph_generic_stack ($opts, $sources));
 } # meta_graph_cpu
 
+sub meta_graph_dns
+{
+  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->{'rrd_opts'} = ['-v', 'Queries/s'];
+
+  my @files = ();
+
+  @$type_instances = sort @$type_instances;
+
+  $opts->{'colors'} = _get_n_colors ($type_instances);
+
+  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_dns
+
 sub meta_graph_memory
 {
   confess ("Wrong number of arguments") if (@_ != 5);
@@ -2587,7 +2799,7 @@ sub meta_graph_memory
   . (defined ($plugin_instance) ? "-$plugin_instance" : '') . "/$type";
   $opts->{'number_format'} = '%5.1lf%s';
 
-  $opts->{'rrd_opts'} = ['-b', '1024'];
+  $opts->{'rrd_opts'} = ['-b', '1024', '-v', 'Bytes'];
 
   my @files = ();
 
@@ -2627,6 +2839,328 @@ sub meta_graph_memory
   } # for (@$type_instances)
 
   return (meta_graph_generic_stack ($opts, $sources));
-} # meta_graph_cpu
+} # meta_graph_memory
+
+sub meta_graph_if_rx_errors
+{
+  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'} = '%5.2lf';
+  $opts->{'rrd_opts'} = ['-v', 'Errors/s'];
+
+  my @files = ();
+
+  for (sort @$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_if_rx_errors
+
+sub meta_graph_mysql_commands
+{
+  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'} = '%5.2lf';
+
+  my @files = ();
+
+  for (sort @$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_mysql_commands
+
+sub meta_graph_nfs_procedure
+{
+  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'} = '%5.1lf%s';
+
+  my @files = ();
+
+  for (sort @$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_nfs_procedure
+
+sub meta_graph_ps_state
+{
+  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->{'rrd_opts'} = ['-v', 'Processes'];
+
+  my @files = ();
+
+  $opts->{'colors'} =
+  {
+    'Running'      => '00e000',
+    'Sleeping'  => '0000ff',
+    'Paging'      => 'ffb000',
+    'Zombies'   => 'ff0000',
+    'Blocked'   => 'ff00ff',
+    'Stopped' => 'a000a0'
+  };
+
+  _custom_sort_arrayref ($type_instances,
+    [qw(paging blocked zombies stopped running sleeping)]);
+
+  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 => ucfirst ($inst),
+       file => $file
+      }
+    );
+  } # for (@$type_instances)
+
+  return (meta_graph_generic_stack ($opts, $sources));
+} # meta_graph_ps_state
+
+sub meta_graph_swap
+{
+  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'} = '%5.1lf%s';
+  $opts->{'rrd_opts'} = ['-v', 'Bytes'];
+
+  my @files = ();
+
+  $opts->{'colors'} =
+  {
+    'Free'     => '00e000',
+    'Cached'   => '0000ff',
+    'Reserved' => 'ffb000',
+    'Used'     => 'ff0000'
+  };
+
+  _custom_sort_arrayref ($type_instances,
+    [qw(free cached reserved used)]);
+
+  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 => ucfirst ($inst),
+       file => $file
+      }
+    );
+  } # for (@$type_instances)
+
+  return (meta_graph_generic_stack ($opts, $sources));
+} # meta_graph_swap
+
+sub meta_graph_tcp_connections
+{
+  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', 'Connections'];
+
+  my @files = ();
+
+  $opts->{'colors'} =
+  {
+    ESTABLISHED          => '00e000',
+    SYN_SENT     => '00e0ff',
+    SYN_RECV     => '00e0a0',
+    FIN_WAIT1    => 'f000f0',
+    FIN_WAIT2    => 'f000a0',
+    TIME_WAIT    => 'ffb000',
+    CLOSE        => '0000f0',
+    CLOSE_WAIT   => '0000a0',
+    LAST_ACK     => '000080',
+    LISTEN       => 'ff0000',
+    CLOSING      => '000000'
+  };
+
+  _custom_sort_arrayref ($type_instances,
+    [reverse qw(ESTABLISHED SYN_SENT SYN_RECV FIN_WAIT1 FIN_WAIT2 TIME_WAIT CLOSE
+    CLOSE_WAIT LAST_ACK CLOSING LISTEN)]);
+
+  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_tcp_connections
 # vim: shiftwidth=2:softtabstop=2:tabstop=8