1 package Collectd::Graph::Type::GenericStacked;
3 # Copyright (C) 2008,2009 Florian octo Forster <octo at verplant.org>
4 #
5 # This program is free software; you can redistribute it and/or modify it under
6 # the terms of the GNU General Public License as published by the Free Software
7 # Foundation; only version 2 of the License is applicable.
8 #
9 # This program is distributed in the hope that it will be useful, but WITHOUT
10 # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11 # FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
12 # details.
13 #
14 # You should have received a copy of the GNU General Public License along with
15 # this program; if not, write to the Free Software Foundation, Inc.,
16 # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 use strict;
19 use warnings;
20 use base ('Collectd::Graph::Type');
22 use Collectd::Graph::Common (qw($ColorCanvas $ColorFullBlue $ColorHalfBlue
23 group_files_by_plugin_instance ident_to_filename sanitize_type_instance
24 get_faded_color sort_idents_by_type_instance));
26 return (1);
28 sub getGraphsNum
29 {
30 my $obj = shift;
31 my $group = group_files_by_plugin_instance (@{$obj->{'files'}});
33 return (scalar (keys %$group));
34 }
36 sub getRRDArgs
37 {
38 my $obj = shift;
39 my $index = shift;
41 my $group = group_files_by_plugin_instance (@{$obj->{'files'}});
42 my @group = sort (keys %$group);
44 my $rrd_opts = $obj->{'rrd_opts'} || [];
45 my $format = $obj->{'rrd_format'} || '%5.1lf';
47 my $idents = $group->{$group[$index]};
48 my $ds_name_len = 0;
50 my $ds = $obj->getDataSources ();
51 if (!$ds)
52 {
53 confess ("obj->getDataSources failed.");
54 }
55 if (@$ds != 1)
56 {
57 confess ("I can only work with RRD files that have "
58 . "exactly one data source!");
59 }
60 my $data_source = $ds->[0];
62 my $rrd_title = $obj->getTitle ($idents->[0]);
64 my $colors = $obj->{'rrd_colors'} || {};
65 my @ret = ('-t', $rrd_title, @$rrd_opts);
67 my $ignore_unknown = $obj->{'ignore_unknown'} || 0;
68 if ($ignore_unknown)
69 {
70 if ($ignore_unknown =~ m/^(yes|true|on)$/i)
71 {
72 $ignore_unknown = 1;
73 }
74 else
75 {
76 $ignore_unknown = 0;
77 }
78 }
80 my $stacking = $obj->{'stacking'};
81 if ($stacking)
82 {
83 if ($stacking =~ m/^(no|false|off|none)$/i)
84 {
85 $stacking = 0;
86 }
87 else
88 {
89 $stacking = 1;
90 }
91 }
92 else # if (!$stacking)
93 {
94 $stacking = 1;
95 }
97 if (defined $obj->{'rrd_vertical'})
98 {
99 push (@ret, '-v', $obj->{'rrd_vertical'});
100 }
102 if ($obj->{'custom_order'})
103 {
104 sort_idents_by_type_instance ($idents, $obj->{'custom_order'});
105 }
107 if ($ignore_unknown)
108 {
109 my $new_idents = [];
110 for (@$idents)
111 {
112 if (exists ($obj->{'ds_names'}{$_->{'type_instance'}}))
113 {
114 push (@$new_idents, $_);
115 }
116 }
118 if (@$new_idents)
119 {
120 $idents = $new_idents;
121 }
122 }
124 $obj->{'ds_names'} ||= {};
125 my @names = map { $obj->{'ds_names'}{$_->{'type_instance'}} || $_->{'type_instance'} } (@$idents);
127 for (my $i = 0; $i < @$idents; $i++)
128 {
129 my $ident = $idents->[$i];
130 my $filename = ident_to_filename ($ident);
132 if ($ds_name_len < length ($names[$i]))
133 {
134 $ds_name_len = length ($names[$i]);
135 }
137 # Escape colons _after_ the length has been checked.
138 $names[$i] =~ s/:/\\:/g;
140 push (@ret,
141 "DEF:min${i}=${filename}:${data_source}:MIN",
142 "DEF:avg${i}=${filename}:${data_source}:AVERAGE",
143 "DEF:max${i}=${filename}:${data_source}:MAX");
144 }
146 if ($stacking)
147 {
148 for (my $i = @$idents - 1; $i >= 0; $i--)
149 {
150 if ($i == (@$idents - 1))
151 {
152 push (@ret,
153 "CDEF:cdef${i}=avg${i},UN,0,avg${i},IF");
154 }
155 else
156 {
157 my $j = $i + 1;
158 push (@ret,
159 "CDEF:cdef${i}=avg${i},UN,0,avg${i},IF,cdef${j},+");
160 }
161 }
163 for (my $i = 0; $i < @$idents; $i++)
164 {
165 my $type_instance = $idents->[$i]{'type_instance'};
166 my $color = '000000';
167 if (exists $colors->{$type_instance})
168 {
169 $color = $colors->{$type_instance};
170 }
172 $color = get_faded_color ($color);
174 push (@ret,
175 "AREA:cdef${i}#${color}");
176 }
177 }
178 else # if (!$stacking)
179 {
180 for (my $i = @$idents - 1; $i >= 0; $i--)
181 {
182 push (@ret,
183 "CDEF:cdef${i}=avg${i}");
184 }
185 }
187 for (my $i = 0; $i < @$idents; $i++)
188 {
189 my $type_instance = $idents->[$i]{'type_instance'};
190 my $ds_name = sprintf ("%-*s", $ds_name_len, $names[$i]);
191 my $color = '000000';
192 if (exists $colors->{$type_instance})
193 {
194 $color = $colors->{$type_instance};
195 }
196 push (@ret,
197 "LINE1:cdef${i}#${color}:${ds_name}",
198 "GPRINT:min${i}:MIN:${format} Min,",
199 "GPRINT:avg${i}:AVERAGE:${format} Avg,",
200 "GPRINT:max${i}:MAX:${format} Max,",
201 "GPRINT:avg${i}:LAST:${format} Last\\l");
202 }
204 return (\@ret);
205 }
207 sub getGraphArgs
208 {
209 my $obj = shift;
210 my $index = shift;
212 my $group = group_files_by_plugin_instance (@{$obj->{'files'}});
213 my @group = sort (keys %$group);
215 my $idents = $group->{$group[$index]};
217 my @args = ();
218 for (qw(hostname plugin plugin_instance type))
219 {
220 if (defined ($idents->[0]{$_}))
221 {
222 push (@args, $_ . '=' . $idents->[0]{$_});
223 }
224 }
226 return (join (';', @args));
227 } # getGraphArgs
230 # vim: set shiftwidth=2 softtabstop=2 tabstop=8 :