--- /dev/null
+package Collectd::Graph::Type::TableSize;
+
+# 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 Collectd::Graph::Common (qw($ColorCanvas $ColorFullBlue $ColorHalfBlue
+ ident_to_filename sanitize_type_instance
+ get_random_color sort_idents_by_type_instance));
+
+use RRDs ();
+
+return (1);
+
+sub _get_last_value
+{
+ my $ident = shift;
+ my $value = undef;
+ my $filename = ident_to_filename ($ident);
+ my ($start ,$step ,$names ,$data) = RRDs::fetch ($filename, 'AVERAGE', '-s', '-3600');
+ if (my $errmsg = RRDs::error ())
+ {
+ print STDERR "RRDs::fetch ($filename) failed: $errmsg\n";
+ return;
+ }
+
+ for (@$data)
+ {
+ my $line = $_;
+
+ for (@$line)
+ {
+ my $ds = $_;
+
+ if (defined ($ds))
+ {
+ $value = $ds;
+ }
+ }
+ } # for (@$data)
+
+ return ($value);
+} # _get_last_value
+
+sub getLastValues
+{
+ my $obj = shift;
+ my $last_value = {};
+
+ if (exists ($obj->{'last_value'}))
+ {
+ return ($obj->{'last_value'});
+ }
+
+ for (@{$obj->{'files'}})
+ {
+ my $file = $_;
+
+ $last_value->{$file} = _get_last_value ($file);
+ }
+ $obj->{'last_value'} = $last_value;
+ return ($obj->{'last_value'});
+} # getLastValues
+
+sub _group_files
+{
+ my $obj = shift;
+ my $data = [];
+ my @files;
+ my $last_values
+
+ $last_values = $obj->getLastValues ();
+
+ @files = sort
+ {
+ if (!defined ($last_values->{$a}) && !defined ($last_values->{$b}))
+ {
+ return (0);
+ }
+ elsif (!defined ($last_values->{$a}))
+ {
+ return (1);
+ }
+ elsif (!defined ($last_values->{$b}))
+ {
+ return (-1);
+ }
+ else
+ {
+ return ($last_values->{$a} <=> $last_values->{$b});
+ }
+ } (@{$obj->{'files'}});
+
+ for (my $i = 0; $i < @files; $i++)
+ {
+ my $file = $files[$i];
+ my $j = int ($i / 10);
+
+ $data->[$j] ||= [];
+ push (@{$data->[$j]}, $file);
+ }
+
+ return ($data);
+} # _group_files
+
+sub getGraphsNum
+{
+ my $obj = shift;
+ my $group = _group_files ($obj);
+
+ return (0 + @$group);
+}
+
+sub getRRDArgs
+{
+ my $obj = shift;
+ my $index = shift;
+
+ my $group = _group_files ($obj);
+
+ my $rrd_opts = $obj->{'rrd_opts'} || [];
+ my $format = $obj->{'rrd_format'} || '%5.1lf';
+
+ my $idents = $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'} || {};
+ my @ret = ('-t', $rrd_title, @$rrd_opts);
+
+ if (defined $obj->{'rrd_vertical'})
+ {
+ push (@ret, '-v', $obj->{'rrd_vertical'});
+ }
+
+ if ($obj->{'custom_order'})
+ {
+ sort_idents_by_type_instance ($idents, $obj->{'custom_order'});
+ }
+
+ $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");
+ }
+
+ 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 = '000000';
+ if (exists $colors->{$type_instance})
+ {
+ $color = $colors->{$type_instance};
+ }
+ else
+ {
+ $color = get_random_color ();
+ }
+ push (@ret,
+ "LINE1:avg${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 ($obj);
+ my $idents = $group->[$index];
+
+ my @args = ();
+ for (qw(hostname plugin plugin_instance type))
+ {
+ if (defined ($idents->[0]{$_}))
+ {
+ push (@args, $_ . '=' . $idents->[0]{$_});
+ }
+ }
+ push (@args, "index=$index");
+
+ return (join (';', @args));
+} # getGraphArgs
+
+# vim: set shiftwidth=2 softtabstop=2 tabstop=8 :