Our Sys. Admin team down in Melbourne, Australia uses collectd
extensively and we've recently started using collection3 for graphing.
Part of our implementation of collection3 involved a few modifications
and additions to it's code which we'd like provide back to the project
for inclusion as it see's fit. The updates were to version 4.10.1 of
the code.
This first submission is for a graphing module which allows the stacking
of multiple type instances in the one graph. The module is a
modification of another one that Florian octo Forster made.
As an example if it was used to graph the interfaces "if_octets" data,
depending on your system, you'd end up with "lo", "eth1", "eth2", ...
stacking on top of each other. You get one graph per data source. The
data source(s) used are what get specified in it's definition (in
collection.conf). In the below example we get two graphs for
"if_octets", one for "rx" and the other for "tx".
<Type if_octets>
Module TypeStacked
DataSources rx tx
DSName rx RX
DSName tx TX
RRDTitle "Interface Traffic ({hostname})"
RRDVerticalLabel "Bytes per second"
RRDFormat "%5.1lf%s"
Color lo 000000
Color sit0 333333
Scale 8
</Type>
Best regards,
Neil McCoy
diff -purN collectd-4.10.1/contrib/collection3/lib/Collectd/Graph/Type/TypeStacked.pm collectd-4.10.1-mine/contrib/collection3/lib/Collectd/Graph/Type/TypeStacked.pm
--- collectd-4.10.1/contrib/collection3/lib/Collectd/Graph/Type/TypeStacked.pm 1970-01-01 10:00:00.000000000 +1000
+++ collectd-4.10.1-mine/contrib/collection3/lib/Collectd/Graph/Type/TypeStacked.pm 2010-09-13 17:10:45.000000000 +1000
@@ -0,0 +1,231 @@
+package Collectd::Graph::Type::TypeStacked;
+
+# Copyright (C) 2008,2009 Florian octo Forster <octo at verplant.org>
+#
+# This program is free software; you can redistribute it and/or modify it under
+# the terms of the GNU General Public License as published by the Free Software
+# Foundation; only version 2 of the License is applicable.
+#
+# This program is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+# details.
+#
+# You should have received a copy of the GNU General Public License along with
+# this program; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+use strict;
+use warnings;
+use base ('Collectd::Graph::Type');
+
+use Carp ('confess');
+
+use Collectd::Graph::Common (qw($ColorCanvas $ColorFullBlue $ColorHalfBlue
+ group_files_by_plugin_instance ident_to_filename sanitize_type_instance
+ get_faded_color sort_idents_by_type_instance));
+
+return (1);
+
+sub getGraphsNum
+{
+ my $obj = shift;
+ my $group = group_files_by_plugin_instance (@{$obj->{'files'}});
+ my $ds = $obj->getDataSources ();
+
+ return ( scalar (keys %$group) * @$ds );
+}
+
+sub getRRDArgs
+{
+ my $obj = shift;
+ my $index = shift;
+
+ my $group = group_files_by_plugin_instance (@{$obj->{'files'}});
+ my @group = sort (keys %$group);
+
+ my $rrd_opts = $obj->{'rrd_opts'} || [];
+ my $format = $obj->{'rrd_format'} || '%5.1lf';
+
+ my $idents = $group->{$group[$index % scalar (keys %$group)]};
+ my $ds_name_len = 0;
+
+ my $ds = $obj->getDataSources ();
+ if (!$ds)
+ {
+ confess ("obj->getDataSources failed.");
+ }
+ my $data_source = $ds->[ $index % @$ds ];
+
+ my $rrd_title = $obj->getTitle ($idents->[0]);
+
+ my $colors = $obj->{'rrd_colors'} || {};
+ my @colours = ("00F000", "0000F0", "E9E900", "E900E9", "00E9E9", "AA5555", "99FFFF", "009000", "000090", "F03030");
+
+ my @ret = ('-t', $rrd_title, @$rrd_opts);
+
+ my $ignore_unknown = $obj->{'ignore_unknown'} || 0;
+ if ($ignore_unknown)
+ {
+ if ($ignore_unknown =~ m/^(1|yes|true|on)$/i)
+ {
+ $ignore_unknown = 1;
+ }
+ else
+ {
+ $ignore_unknown = 0;
+ }
+ }
+
+ my $stacking = $obj->{'stacking'};
+ if ($stacking)
+ {
+ if ($stacking =~ m/^(0|no|false|off|none)$/i)
+ {
+ $stacking = 0;
+ }
+ else
+ {
+ $stacking = 1;
+ }
+ }
+ else # if (!$stacking)
+ {
+ $stacking = 1;
+ }
+
+ if (defined $obj->{'rrd_vertical'})
+ {
+ push (@ret, '-v', $obj->{'rrd_vertical'} . " " . $data_source);
+ }
+
+ if ($obj->{'custom_order'})
+ {
+ sort_idents_by_type_instance ($idents, $obj->{'custom_order'});
+ }
+
+ if ($ignore_unknown)
+ {
+ my $new_idents = [];
+ for (@$idents)
+ {
+ if (exists ($obj->{'ds_names'}{$_->{'type_instance'}}))
+ {
+ push (@$new_idents, $_);
+ }
+ }
+
+ if (@$new_idents)
+ {
+ $idents = $new_idents;
+ }
+ }
+
+ $obj->{'ds_names'} ||= {};
+ my @names = map { $obj->{'ds_names'}{$_->{'type_instance'}} || $_->{'type_instance'} } (@$idents);
+
+ for (my $i = 0; $i < @$idents; $i++)
+ {
+ my $ident = $idents->[$i];
+ my $filename = ident_to_filename ($ident);
+
+ if ($ds_name_len < length ($names[$i]))
+ {
+ $ds_name_len = length ($names[$i]);
+ }
+
+ # Escape colons _after_ the length has been checked.
+ $names[$i] =~ s/:/\\:/g;
+
+ push (@ret,
+ "DEF:min${i}=${filename}:${data_source}:MIN",
+ "DEF:avg${i}=${filename}:${data_source}:AVERAGE",
+ "DEF:max${i}=${filename}:${data_source}:MAX");
+ }
+
+ if ($stacking)
+ {
+ for (my $i = @$idents - 1; $i >= 0; $i--)
+ {
+ if ($i == (@$idents - 1))
+ {
+ push (@ret,
+ "CDEF:cdef${i}=avg${i},UN,0,avg${i},IF");
+ }
+ else
+ {
+ my $j = $i + 1;
+ push (@ret,
+ "CDEF:cdef${i}=avg${i},UN,0,avg${i},IF,cdef${j},+");
+ }
+ }
+
+ for (my $i = 0; $i < @$idents; $i++)
+ {
+ my $type_instance = $idents->[$i]{'type_instance'};
+ my $color = ${colours[$i % $#colours]};
+ if (exists $colors->{$type_instance})
+ {
+ $color = $colors->{$type_instance};
+ }
+
+ $color = get_faded_color ($color);
+
+ push (@ret,
+ "AREA:cdef${i}#${color}");
+ }
+ }
+ else # if (!$stacking)
+ {
+ for (my $i = @$idents - 1; $i >= 0; $i--)
+ {
+ push (@ret,
+ "CDEF:cdef${i}=avg${i}");
+ }
+ }
+
+ for (my $i = 0; $i < @$idents; $i++)
+ {
+ my $type_instance = $idents->[$i]{'type_instance'};
+ my $ds_name = sprintf ("%-*s", $ds_name_len, $names[$i]);
+ my $color = ${colours[$i % $#colours]};
+ if (exists $colors->{$type_instance})
+ {
+ $color = $colors->{$type_instance};
+ }
+ push (@ret,
+ "LINE1:cdef${i}#${color}:${ds_name}",
+ "GPRINT:min${i}:MIN:${format} Min,",
+ "GPRINT:avg${i}:AVERAGE:${format} Avg,",
+ "GPRINT:max${i}:MAX:${format} Max,",
+ "GPRINT:avg${i}:LAST:${format} Last\\l");
+ }
+
+ return (\...@ret);
+}
+
+sub getGraphArgs
+{
+ my $obj = shift;
+ my $index = shift;
+
+ my $group = group_files_by_plugin_instance (@{$obj->{'files'}});
+ my @group = sort (keys %$group);
+
+ my $idents = $group->{$group[$index % scalar (keys %$group)]};
+
+ my @args = ();
+ push (@args, "index" . '=' . $index);
+ for (qw(hostname plugin plugin_instance type))
+ {
+ if (defined ($idents->[0]{$_}))
+ {
+ push (@args, $_ . '=' . $idents->[0]{$_});
+ }
+ }
+
+ return (join (';', @args));
+} # getGraphArgs
+
+
+# vim: set shiftwidth=2 softtabstop=2 tabstop=8 :
_______________________________________________
collectd mailing list
[email protected]
http://mailman.verplant.org/listinfo/collectd