+
+sub meta_graph_generic_stack
+{
+ confess ("Wrong number of arguments") if (@_ != 2);
+
+ my $opts = shift;
+ my $sources = shift;
+ my $i;
+
+ my $timespan_str = _get_param_timespan ();
+ my $timespan_int = (-1) * $ValidTimespan->{$timespan_str};
+
+ $opts->{'title'} ||= 'Unknown title';
+ $opts->{'rrd_opts'} ||= [];
+ $opts->{'colors'} ||= {};
+
+ my @cmd = ('-', '-a', 'PNG', '-s', $timespan_int,
+ '-t', $opts->{'title'} || 'Unknown title',
+ @RRDDefaultArgs, @{$opts->{'rrd_opts'}});
+
+ my $max_inst_name = 0;
+
+ for ($i = 0; $i < @$sources; $i++)
+ {
+ my $inst_data = $sources->[$i];
+ my $inst_name = $inst_data->{'name'} || confess;
+ my $file = $inst_data->{'file'} || confess;
+
+ if (length ($inst_name) > $max_inst_name)
+ {
+ $max_inst_name = length ($inst_name);
+ }
+
+ 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#);
+ }
+
+ for (my $i = 0; $i < @$sources; $i++)
+ {
+ my $inst_data0 = $sources->[@$sources - (1 + $i)];
+ my $inst_data1 = $sources->[@$sources - (($i == 0) ? 1 : $i)];
+
+ my $inst_name0 = $inst_data0->{'name'};
+ my $inst_name1 = $inst_data1->{'name'};
+
+ my $cdef_name = ($i == 0) ? 'nnl' : 'stk';
+
+ push (@cmd, qq#CDEF:${inst_name0}_stk=${inst_name0}_nnl,${inst_name1}_${cdef_name},+#);
+ }
+
+ for (my $i = 0; $i < @$sources; $i++)
+ {
+ my $inst_data = $sources->[$i];
+ my $inst_name = $inst_data->{'name'};
+
+ my $legend = sprintf ('%-*s', $max_inst_name, $inst_name);
+
+ my $line_color;
+ my $area_color;
+
+ my $number_format = $opts->{'number_format'} || '%6.1lf';
+
+ if (exists ($opts->{'colors'}{$inst_name}))
+ {
+ $line_color = $opts->{'colors'}{$inst_name};
+ $area_color = _string_to_color ($line_color);
+ }
+ else
+ {
+ $area_color = _get_random_color ();
+ $line_color = _color_to_string ($area_color);
+ }
+ $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),
+ );
+ }
+
+ RRDs::graph (@cmd);
+ if (my $errmsg = RRDs::error ())
+ {
+ confess ("RRDs::graph: $errmsg");
+ }
+} # meta_graph_generic_stack
+
+sub meta_graph_cpu
+{
+ 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";
+
+ my @files = ();
+
+ $opts->{'colors'} =
+ {
+ 'idle' => 'ffffff',
+ 'nice' => '00e000',
+ 'user' => '0000ff',
+ 'wait' => 'ffb000',
+ 'system' => 'ff0000',
+ 'softirq' => 'ff00ff',
+ 'interrupt' => 'a000a0',
+ 'steal' => '000000'
+ };
+
+ _custom_sort_arrayref ($type_instances,
+ [qw(idle nice user wait system softirq interrupt 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_cpu
+
+sub meta_graph_memory
+{
+ 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'} = ['-b', '1024'];
+
+ my @files = ();
+
+ $opts->{'colors'} =
+ {
+ 'free' => '00e000',
+ 'cached' => '0000ff',
+ 'buffered' => 'ffb000',
+ 'used' => 'ff0000'
+ };
+
+ _custom_sort_arrayref ($type_instances,
+ [qw(free cached buffered 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 => $inst,
+ file => $file
+ }
+ );
+ } # for (@$type_instances)
+
+ return (meta_graph_generic_stack ($opts, $sources));
+} # meta_graph_cpu
+