X-Git-Url: https://git.octo.it/?a=blobdiff_plain;f=contrib%2Fcollection.cgi;h=cab7543f0e844d32b1c60861bd19ce893d180f97;hb=92445ff3363441d0f515de4a3ab92a504cfc0366;hp=155653ddd9e6356ace82863f8fceb5f7d52b59bd;hpb=ae38cebfd9385bba1047c6ea430485b61dab1b99;p=collectd.git diff --git a/contrib/collection.cgi b/contrib/collection.cgi index 155653dd..cab7543f 100755 --- a/contrib/collection.cgi +++ b/contrib/collection.cgi @@ -15,11 +15,21 @@ our $Config = "/etc/collection.conf"; our @DataDirs = (); our $LibDir; -our @RRDDefaultArgs = ('-w', '800'); +our $ValidTimespan = +{ + hour => 3600, + day => 86400, + week => 7 * 86400, + month => 31 * 86400, + year => 366 * 86400 +}; + +our @RRDDefaultArgs = ('-w', '400'); our $Args = {}; our $GraphDefs; +our $MetaGraphDefs = {}; load_graph_definitions (); for (qw(action host plugin plugin_instance type type_instance timespan)) @@ -76,128 +86,6 @@ sub read_config close ($fh); } # read_config -#sub validate_args -#{ -# if (!$Args->{'host'} || ($Args->{'host'} =~ m#/#) -# || !$Args->{'plugin'} || ($Args->{'plugin'} =~ m#/#) -# || (defined ($Args->{'plugin_instance'}) && ($Args->{'plugin_instance'} =~ m#/#)) -# || !$Args->{'type'} || ($Args->{'type'} =~ m#/#) -# || (defined ($Args->{'type_instance'}) && ($Args->{'type_instance'} =~ m#/#))) -# { -# delete ($Args->{'host'}); -# delete ($Args->{'plugin'}); -# delete ($Args->{'plugin_instance'}); -# delete ($Args->{'type'}); -# delete ($Args->{'type_instance'}); -# } -# elsif ($Args->{'type_instance'} eq '*') -# { -# my $subdir = $Args->{'host'} . '/' -# . $Args->{'plugin'} . (defined ($Args->{'plugin_instance'}) ? ('-' . $Args->{'plugin_instance'}) : ''); -# my %type_instances = (); -# my $regex_str = '^' . quotemeta ($Args->{'type'}) . '-(.*)\.rrd'; -# my $regex = qr/$regex_str/; -# my $mtime = 0; -# -# for (my $i = 0; $i < @DataDirs; $i++) -# { -# my $dh; -# my @files = (); -# opendir ($dh, $DataDirs[$i] . '/' . $subdir) or next; -# for (readdir ($dh)) -# { -# my $file = $_; -# if ($file =~ $regex) -# { -# my $tmp_mtime; -# my $type_instance = $1; -# my $filename = $DataDirs[$i] . '/' . $subdir . '/' . $Args->{'type'} . '-' . $type_instance . '.rrd'; -# -# $type_instances{$type_instance} = [] if (!exists ($type_instances{$type_instance})); -# $tmp_mtime = (stat ($filename))[9]; -# next if (!$tmp_mtime); -# -# push (@{$type_instances{$type_instance}}, $filename); -# $mtime = $tmp_mtime if ($mtime < $tmp_mtime); -# } -# } -# closedir ($dh); -# } -# -# if (!keys %type_instances) -# { -# print STDOUT header (-Status => '404 File not found', -Content_Type => 'text/plain'); -# print STDOUT <{'files'} = \%type_instances; -# $Args->{'mtime'} = $mtime; -# } -# else -# { -# my $filename = $Args->{'host'} . '/' -# . $Args->{'plugin'} . (defined ($Args->{'plugin_instance'}) ? ('-' . $Args->{'plugin_instance'}) : '') . '/' -# . $Args->{'type'} . (defined ($Args->{'type_instance'}) ? ('-' . $Args->{'type_instance'}) : '') . '.rrd'; -# my @files = (); -# my $mtime = 0; -# -# for (my $i = 0; $i < @DataDirs; $i++) -# { -# my $tmp_file; -# my $tmp_mtime; -# $tmp_file = $DataDirs[$i] . '/' . $filename; -# next if (!-e $tmp_file); -# $tmp_mtime = (stat ($tmp_file))[9]; -# next if (!$tmp_mtime); -# -# push (@files, $tmp_file); -# $mtime = $tmp_mtime if ($mtime < $tmp_mtime); -# } -# -# if (!@files) -# { -# print STDOUT header (-Status => '404 File not found', -Content_Type => 'text/plain'); -# print STDOUT <{'files'} = \@files; -# $Args->{'mtime'} = $mtime; -# } -# -# if ($Args->{'timespan'}) -# { -# if ($Args->{'timespan'} =~ m/^([0-9]+)$/) -# { -# $Args->{'timespan'} = (-1) * $1; -# } -# elsif ($Args->{'timespan'} =~ m/^(hour|day|week|month|year)$/) -# { -# my %map = -# ( -# hour => -3600, -# day => -86400, -# week => 7 * -86400, -# month => 31 * -86400, -# year => 366 * -86400 -# ); -# $Args->{'timespan'} = $map{$1}; -# } -# else -# { -# $Args->{'timespan'} = -86400; -# } -# } -#} # validate_args - sub validate_args { if ($Args->{'action'} && ($Args->{'action'} =~ m/^(overview|show_host|show_plugin|show_type|show_graph)$/)) @@ -247,24 +135,61 @@ sub validate_args } } # validate_args -sub _find_hosts { - my %hosts = (); + my $hosts; + sub _find_hosts + { + if (defined ($hosts)) + { + return (keys %$hosts); + } - for (my $i = 0; $i < @DataDirs; $i++) + $hosts = {}; + + for (my $i = 0; $i < @DataDirs; $i++) + { + my @tmp; + my $dh; + + opendir ($dh, $DataDirs[$i]) or next; + @tmp = grep { ($_ !~ m/^\./) && (-d $DataDirs[$i] . '/' . $_) } (readdir ($dh)); + closedir ($dh); + + $hosts->{$_} = 1 for (@tmp); + } # for (@DataDirs) + + return (keys %$hosts); + } # _find_hosts +} + +sub _get_param_host +{ + my %all_hosts = map { $_ => 1 } (_find_hosts ()); + my @selected_hosts = (); + for (param ('host')) { - my @tmp; - my $dh; + if (defined ($all_hosts{$_})) + { + push (@selected_hosts, "$_"); + } + } + return (@selected_hosts); +} # _get_param_host - opendir ($dh, $DataDirs[$i]) or next; - @tmp = grep { ($_ !~ m/^\./) && (-d $DataDirs[$i] . '/' . $_) } (readdir ($dh)); - closedir ($dh); +sub _get_param_timespan +{ + my $timespan = param ('timespan'); - $hosts{$_} = 1 for (@tmp); - } # for (@DataDirs) + $timespan ||= 'day'; + $timespan = lc ($timespan); + + if (!defined ($ValidTimespan->{$timespan})) + { + $timespan = 'day'; + } - return (keys %hosts); -} # _find_hosts + return ($timespan); +} # _get_param_timespan sub _find_plugins { @@ -284,13 +209,13 @@ 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) return (%plugins); -} # _find_hosts +} # _find_plugins sub _find_types { @@ -322,85 +247,119 @@ sub _find_types return (%types); } # _find_types -# sub _find_files_plugin -# { -# my $host = shift; -# my $plugin = shift; -# my $plugin_instance = shift; -# my $type = shift; -# my $type_instance = shift; -# -# my @plugins = (); -# my %files = (); -# -# if (!$plugin || ($plugin eq '*')) -# { -# } -# else -# { -# @plugins = ($plugin); -# } -# } # _find_files_plugin -# -# sub _find_files_host -# { -# my $host = shift; -# my $plugin = shift; -# my $plugin_instance = shift; -# my $type = shift; -# my $type_instance = shift; -# -# my @hosts = (); -# my %files = (); -# -# if (!$host || ($host eq '*')) -# { -# my %hosts; -# for (my $i = 0; $i < @DataDirs; $i++) -# { -# my @tmp; -# my $dh; -# -# opendir ($dh, $DataDirs[$i]) or next; -# @tmp = grep { ($_ !~ m/^\./) && (-d $_) } (readdir ($dh)); -# closedir ($dh); -# -# $hosts{$_} = 1 for (@tmp); -# } # for (@DataDirs) -# @hosts = keys %hosts; -# } -# else -# { -# @hosts = ($host); -# } -# -# for (my $i = 0; $i < @hosts; $i++) -# { -# my @files = _find_files_plugin ($hosts[$i], $plugin, -# $plugin_instance, $type, $type_instance); -# $files{$_} = 1 for (@files); -# } -# -# return (wantarray () ? keys %files : [keys %files]); -# } # _find_files_host -# -# sub _find_files -# { -# my $host = shift; -# my $plugin = shift; -# my $plugin_instance = shift; -# my $type = shift; -# my $type_instance = shift; -# -# if ($host eq '*') -# { -# my @hosts = _find_all_hosts (); -# -# for (my $i = 0; $i < @DataDirs; $i++) -# { -# -# } # for (i) -# } # _find_files +sub _find_files_for_host +{ + my $host = shift; + my $ret = {}; + + my %plugins = _find_plugins ($host); + for (keys %plugins) + { + my $plugin = $_; + my $plugin_instances = $plugins{$plugin}; + + if (!$plugin_instances || !@$plugin_instances) + { + $plugin_instances = ['-']; + } + + $ret->{$plugin} = {}; + + for (@$plugin_instances) + { + my $plugin_instance = defined ($_) ? $_ : '-'; + my %types = _find_types ($host, $plugin, + ($plugin_instance ne '-') + ? $plugin_instance + : undef); + + $ret->{$plugin}{$plugin_instance} = {}; + + for (keys %types) + { + my $type = $_; + my $type_instances = $types{$type}; + + $ret->{$plugin}{$plugin_instance}{$type} = {}; + + for (@$type_instances) + { + $ret->{$plugin}{$plugin_instance}{$type}{$_} = 1; + } + + if (!@$type_instances) + { + $ret->{$plugin}{$plugin_instance}{$type}{'-'} = 1; + } + } # for (keys %types) + } # for (@$plugin_instances) + } # for (keys %plugins) + + return ($ret); +} # _find_files_for_host + +sub _find_files_for_hosts +{ + my @hosts = @_; + my $all_plugins = {}; + + for (my $i = 0; $i < @hosts; $i++) + { + my $tmp = _find_files_for_host ($hosts[$i]); + _files_union ($all_plugins, $tmp); + } + + return ($all_plugins); +} # _find_files_for_hosts + +sub _files_union +{ + my $dest = shift; + my $src = shift; + + for (keys %$src) + { + my $plugin = $_; + $dest->{$plugin} ||= {}; + + for (keys %{$src->{$plugin}}) + { + my $pinst = $_; + $dest->{$plugin}{$pinst} ||= {}; + + for (keys %{$src->{$plugin}{$pinst}}) + { + my $type = $_; + $dest->{$plugin}{$pinst}{$type} ||= {}; + + for (keys %{$src->{$plugin}{$pinst}{$type}}) + { + my $tinst = $_; + $dest->{$plugin}{$pinst}{$type}{$tinst} = 1; + } + } + } + } +} # _files_union + +sub _files_plugin_inst_count +{ + my $src = shift; + my $i = 0; + + for (keys %$src) + { + if (exists ($MetaGraphDefs->{$_})) + { + $i++; + } + else + { + $i = $i + keys %{$src->{$_}}; + } + } + return ($i); +} # _files_plugin_count sub list_hosts { @@ -418,81 +377,335 @@ sub list_hosts print "\n"; } # list_hosts +sub _string_to_color +{ + my $color = shift; + if ($color =~ m/([0-9A-Fa-f][0-9A-Fa-f])([0-9A-Fa-f][0-9A-Fa-f])([0-9A-Fa-f][0-9A-Fa-f])/) + { + return ([hex ($1) / 255.0, hex ($2) / 255.0, hex ($3) / 255.0]); + } + return; +} # _string_to_color + +sub _color_to_string +{ + confess ("Wrong number of arguments") if (@_ != 1); + return (sprintf ('%02hx%02hx%02hx', map { int (255.0 * $_) } @{$_[0]})); +} # _color_to_string + +sub _get_random_color +{ + my ($r, $g, $b) = (rand (), rand ()); + my $min = 0.0; + my $max = 1.0; + + if (($r + $g) < 1.0) + { + $min = 1.0 - ($r + $g); + } + else + { + $max = 2.0 - ($r + $g); + } + + $b = $min + (rand () * ($max - $min)); + + 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; + my $bg; + my %opts = @_; + my $ret = [undef, undef, undef]; + + $opts{'background'} ||= [1.0, 1.0, 1.0]; + $opts{'alpha'} ||= 0.25; + + if (!ref ($opts{'background'})) + { + $opts{'background'} = _string_to_color ($opts{'background'}) + or confess ("Cannot parse background color " . $opts{'background'}); + } + $bg = $opts{'background'}; + + for (my $i = 0; $i < 3; $i++) + { + $ret->[$i] = ($opts{'alpha'} * $fg->[$i]) + + ((1.0 - $opts{'alpha'}) * $bg->[$i]); + } + + return ($ret); +} # _get_faded_color + +sub _custom_sort_arrayref +{ + my $array_ref = shift; + my $array_sort = shift; + + my %elements = map { $_ => 1 } (@$array_ref); + splice (@$array_ref, 0); + + for (@$array_sort) + { + next if (!exists ($elements{$_})); + push (@$array_ref, $_); + delete ($elements{$_}); + } + push (@$array_ref, sort (keys %elements)); +} # _custom_sort_arrayref + sub action_show_host { - my $host = shift; - my $host_url = uri_escape ($host); - my %plugins = _find_plugins ($host); + my @hosts = _get_param_host (); + @hosts = sort (@hosts); + + 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(
Back to list of hosts
\n); - print "\n"; } # action_show_host sub action_show_plugin { - my $host = shift; + my @hosts = _get_param_host (); my $plugin = shift; my $plugin_instance = shift; + my $timespan = _get_param_timespan (); - my $host_url = uri_escape ($host); - my $plugin_url = uri_escape ($plugin); - my $plugin_instance_url = defined ($plugin_instance) ? uri_escape ($plugin_instance) : undef; - - my %types = _find_types ($host, $plugin, $plugin_instance); - - my $url_prefix = script_name () . "?host=$host_url;plugin=$plugin_url"; - $url_prefix .= ";plugin_instance=$plugin_instance_url" if (defined ($plugin_instance)); + my $hosts_url = join (';', map { 'host=' . uri_escape ($_) } (@hosts)); + my $url_prefix = script_name () . "?$hosts_url"; - print qq(
Back to list of plugins
\n); + my $all_plugins = {}; + my $plugins_per_host = {}; + my $selected_plugins = {}; - for (sort (keys %types)) + for (my $i = 0; $i < @hosts; $i++) { - my $type = $_; - my $type_html = encode_entities ($type); - my $type_url = uri_escape ($type); + $plugins_per_host->{$hosts[$i]} = _find_files_for_host ($hosts[$i]); + _files_union ($all_plugins, $plugins_per_host->{$hosts[$i]}); + } - if (!defined ($GraphDefs->{$type})) + for (param ('plugin')) + { + if (defined ($all_plugins->{$_})) { - print qq#
Unknown type "$type_html"
\n#; - next; + $selected_plugins->{$_} = 1; } + } - for (@{$types{$type}}) - { - my $instance = $_; - my $instance_html = encode_entities ($instance); - my $instance_url = uri_escape ($instance); + print qq(
Back to list of plugins
\n); - print qq#
\n#; - } + # Print table header + print < + + Plugins +HTML + for (@hosts) + { + print "\t", encode_entities ($_), "\n"; + } + print " \n"; + + 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}; - if (!@{$types{$type}}) + for (sort (keys %$all_pinst)) { - print qq#
\n#; - } - } + my $pinst = $_; + my $pinst_html = ''; + my $pinst_url = $plugin_url; + + if ($pinst ne '-') + { + $pinst_html = encode_entities ($pinst); + $pinst_url .= ';plugin_instance=' . uri_escape ($pinst); + } + + my $files_printed = 0; + 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_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 " \n"; + print "\t$title\n"; + } + + if (exists ($MetaGraphDefs->{$type})) + { + 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 ($files_printed != 0) + { + print " \n"; + } + + for (@hosts) + { + my $host = $_; + my $host_graph_url = $graph_url . ';host=' . uri_escape ($host); + + print "\t"; + if (exists $plugins_per_host->{$host}{$plugin}{$pinst}{$type}) + { + print qq(); + #print encode_entities (qq()); + } + print "\n"; + } # for (my $k = 0; $k < @hosts; $k++) + + print " \n"; + + $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 $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 '-') + { + $graph_url .= ';type_instance=' . uri_escape ($tinst); + } + + if ($files_printed != 0) + { + print " \n"; + } + + for (my $k = 0; $k < @hosts; $k++) + { + my $host = $hosts[$k]; + my $host_graph_url = $graph_url . ';host=' . uri_escape ($host); + + print "\t"; + if ($plugins_per_host->{$host}{$plugin}{$pinst}{$type}{$tinst}) + { + print qq(); + #print encode_entities (qq()); + } + print "\n"; + } # for (my $k = 0; $k < @hosts; $k++) + + print " \n"; + + $files_printed++; + } # for ($tinst) + } # for ($type) + } # for ($pinst) + } # for ($plugin) + print " \n"; } # action_show_plugin sub action_show_type @@ -543,6 +756,13 @@ sub action_show_graph #print STDERR Data::Dumper->Dump ([$Args], ['Args']); + # FIXME + if (exists ($MetaGraphDefs->{$type})) + { + my %types = _find_types ($host, $plugin, $plugin_instance); + return $MetaGraphDefs->{$type}->($host, $plugin, $plugin_instance, $type, $types{$type}); + } + return if (!defined ($GraphDefs->{$type})); @rrd_args = @{$GraphDefs->{$type}}; @@ -554,6 +774,7 @@ sub action_show_graph my $file = $DataDirs[$i] . "/$title.rrd"; next if (!-f $file); + $file =~ s/:/\\:/g; s/{file}/$file/ for (@rrd_args); RRDs::graph ('-', '-a', 'PNG', '-s', $start_time, '-t', $title, @RRDDefaultArgs, @rrd_args); @@ -564,6 +785,62 @@ sub action_show_graph } } # action_show_graph +sub print_selector +{ + my @hosts = _find_hosts (); + @hosts = sort (@hosts); + + my %selected_hosts = map { $_ => 1 } (_get_param_host ()); + my $timespan_selected = _get_param_timespan (); + + print < +
+ Selector + \n"; + + if (keys %selected_hosts) + { + my $all_plugins = _find_files_for_hosts (keys %selected_hosts); + my %selected_plugins = map { $_ => 1 } (param ('plugin')); + + print qq(\t\n"; + } # if (keys %selected_hosts) + + print qq(\t +
+ +HTML +} + sub print_header { print < HEAD + print_selector (); } # print_header sub print_footer @@ -627,8 +915,7 @@ sub main } elsif (!$Args->{'type'}) { - action_show_plugin ($Args->{'host'}, - $Args->{'plugin'}, $Args->{'plugin_instance'}); + action_show_plugin ($Args->{'plugin'}, $Args->{'plugin_instance'}); } else { @@ -686,10 +973,8 @@ sub load_graph_definitions apache_requests => ['DEF:min={file}:count:MIN', 'DEF:avg={file}:count:AVERAGE', 'DEF:max={file}:count:MAX', - 'CDEF:moving_average=PREV,UN,avg,PREV,IF,0.8,*,avg,0.2,*,+', "AREA:max#$HalfBlue", "AREA:min#$Canvas", - 'LINE1:moving_average#000000', "LINE1:avg#$FullBlue:Requests/s", 'GPRINT:min:MIN:%6.2lf Min,', 'GPRINT:avg:AVERAGE:%6.2lf Avg,', @@ -707,10 +992,22 @@ sub load_graph_definitions 'GPRINT:max:MAX:%6.2lf Max,', 'GPRINT:avg:LAST:%6.2lf Last' ], - charge => [ - 'DEF:avg={file}:charge:AVERAGE', - 'DEF:min={file}:charge:MIN', - 'DEF:max={file}:charge:MAX', + bitrate => ['-v', 'Bits/s', + 'DEF:avg={file}:value:AVERAGE', + 'DEF:min={file}:value:MIN', + 'DEF:max={file}:value:MAX', + "AREA:max#$HalfBlue", + "AREA:min#$Canvas", + "LINE1:avg#$FullBlue:Bits/s", + 'GPRINT:min:MIN:%5.1lf%s Min,', + 'GPRINT:avg:AVERAGE:%5.1lf%s Average,', + 'GPRINT:max:MAX:%5.1lf%s Max,', + 'GPRINT:avg:LAST:%5.1lf%s Last\l' + ], + 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", @@ -719,18 +1016,6 @@ 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', - "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' - ], cpu => ['-v', 'CPU load', 'DEF:avg={file}:value:AVERAGE', 'DEF:min={file}:value:MIN', @@ -743,10 +1028,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", @@ -755,7 +1040,7 @@ sub load_graph_definitions 'GPRINT:max:MAX:%5.1lf%sA Max,', 'GPRINT:avg:LAST:%5.1lf%sA Last\l' ], - df => ['-v', 'Percent', + df => ['-v', 'Percent', '-l', '0', 'DEF:free_avg={file}:free:AVERAGE', 'DEF:free_min={file}:free:MIN', 'DEF:free_max={file}:free:MAX', @@ -909,7 +1194,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', @@ -944,10 +1229,22 @@ sub load_graph_definitions 'GPRINT:qry_avg:LAST:%5.1lf%s Last', 'GPRINT:qry_avg_sum:LAST:(ca. %5.1lf%sB Total)\l' ], - email => [ - 'DEF:avg={file}:count:AVERAGE', - 'DEF:min={file}:count:MIN', - 'DEF:max={file}:count:MAX', + 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', + 'DEF:max={file}:value:MAX', "AREA:max#$HalfMagenta", "AREA:min#$Canvas", "LINE1:avg#$FullMagenta:Count ", @@ -956,10 +1253,10 @@ sub load_graph_definitions 'GPRINT:max:MAX:%4.1lf Max,', 'GPRINT:avg:LAST:%4.1lf Last\l' ], - email_size => [ - 'DEF:avg={file}:size:AVERAGE', - 'DEF:min={file}:size:MIN', - 'DEF:max={file}:size:MAX', + email_size => ['-v', 'Bytes', + 'DEF:avg={file}:value:AVERAGE', + 'DEF:min={file}:value:MIN', + 'DEF:max={file}:value:MAX', "AREA:max#$HalfMagenta", "AREA:min#$Canvas", "LINE1:avg#$FullMagenta:Count ", @@ -992,7 +1289,8 @@ sub load_graph_definitions 'GPRINT:max:MAX:%4.1lf Max,', 'GPRINT:avg:LAST:%4.1lf Last\l' ], - entropy => ['DEF:avg={file}:entropy:AVERAGE', + entropy => ['-v', 'Bits', + 'DEF:avg={file}:entropy:AVERAGE', 'DEF:min={file}:entropy:MIN', 'DEF:max={file}:entropy:MAX', "AREA:max#$HalfBlue", @@ -1039,11 +1337,23 @@ sub load_graph_definitions 'GPRINT:ppm_max:MAX:%5.2lf Max,', 'GPRINT:ppm_avg:LAST:%5.2lf Last' ], - hddtemp => [ + gauge => ['-v', 'Exec value', 'DEF:temp_avg={file}:value:AVERAGE', 'DEF:temp_min={file}:value:MIN', 'DEF:temp_max={file}:value:MAX', - "AREA:temp_max#$HalfRed", + "AREA:temp_max#$HalfBlue", + "AREA:temp_min#$Canvas", + "LINE1:temp_avg#$FullBlue:Exec value", + 'GPRINT:temp_min:MIN:%6.2lf Min,', + 'GPRINT:temp_avg:AVERAGE:%6.2lf Avg,', + 'GPRINT:temp_max:MAX:%6.2lf Max,', + 'GPRINT:temp_avg:LAST:%6.2lf Last\l' + ], + hddtemp => [ + 'DEF:temp_avg={file}:value:AVERAGE', + 'DEF:temp_min={file}:value:MIN', + 'DEF:temp_max={file}:value:MAX', + "AREA:temp_max#$HalfRed", "AREA:temp_min#$Canvas", "LINE1:temp_avg#$FullRed:Temperature", 'GPRINT:temp_min:MIN:%4.1lf Min,', @@ -1051,6 +1361,93 @@ 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', + 'DEF:tx_max={file}:tx:MAX', + 'DEF:rx_min={file}:rx:MIN', + 'DEF:rx_avg={file}:rx:AVERAGE', + 'DEF:rx_max={file}:rx:MAX', + 'CDEF:overlap=tx_avg,rx_avg,GT,rx_avg,tx_avg,IF', + 'CDEF:mytime=tx_avg,TIME,TIME,IF', + 'CDEF:sample_len_raw=mytime,PREV(mytime),-', + 'CDEF:sample_len=sample_len_raw,UN,0,sample_len_raw,IF', + 'CDEF:tx_avg_sample=tx_avg,UN,0,tx_avg,IF,sample_len,*', + 'CDEF:tx_avg_sum=PREV,UN,0,PREV,IF,tx_avg_sample,+', + 'CDEF:rx_avg_sample=rx_avg,UN,0,rx_avg,IF,sample_len,*', + 'CDEF:rx_avg_sum=PREV,UN,0,PREV,IF,rx_avg_sample,+', + "AREA:tx_avg#$HalfGreen", + "AREA:rx_avg#$HalfBlue", + "AREA:overlap#$HalfBlueGreen", + "LINE1:tx_avg#$FullGreen:TX", + 'GPRINT:tx_avg:AVERAGE:%5.1lf%s Avg,', + 'GPRINT:tx_max:MAX:%5.1lf%s Max,', + 'GPRINT:tx_avg:LAST:%5.1lf%s Last', + 'GPRINT:tx_avg_sum:LAST:(ca. %4.0lf%s Total)\l', + "LINE1:rx_avg#$FullBlue:RX", + #'GPRINT:rx_min:MIN:%5.1lf %s Min,', + 'GPRINT:rx_avg:AVERAGE:%5.1lf%s Avg,', + 'GPRINT:rx_max:MAX:%5.1lf%s Max,', + 'GPRINT:rx_avg:LAST:%5.1lf%s Last', + 'GPRINT:rx_avg_sum:LAST:(ca. %4.0lf%s Total)\l' + ], + if_collisions => ['-v', 'Collisions/s', + 'DEF:min_raw={file}:value:MIN', + 'DEF:avg_raw={file}:value:AVERAGE', + 'DEF:max_raw={file}:value:MAX', + 'CDEF:min=min_raw,8,*', + 'CDEF:avg=avg_raw,8,*', + 'CDEF:max=max_raw,8,*', + "AREA:max#$HalfBlue", + "AREA:min#$Canvas", + "LINE1:avg#$FullBlue:Collisions/s", + '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' + ], + if_dropped => ['-v', 'Packets/s', + 'DEF:tx_min={file}:tx:MIN', + 'DEF:tx_avg={file}:tx:AVERAGE', + 'DEF:tx_max={file}:tx:MAX', + 'DEF:rx_min={file}:rx:MIN', + 'DEF:rx_avg={file}:rx:AVERAGE', + 'DEF:rx_max={file}:rx:MAX', + 'CDEF:overlap=tx_avg,rx_avg,GT,rx_avg,tx_avg,IF', + 'CDEF:mytime=tx_avg,TIME,TIME,IF', + 'CDEF:sample_len_raw=mytime,PREV(mytime),-', + 'CDEF:sample_len=sample_len_raw,UN,0,sample_len_raw,IF', + 'CDEF:tx_avg_sample=tx_avg,UN,0,tx_avg,IF,sample_len,*', + 'CDEF:tx_avg_sum=PREV,UN,0,PREV,IF,tx_avg_sample,+', + 'CDEF:rx_avg_sample=rx_avg,UN,0,rx_avg,IF,sample_len,*', + 'CDEF:rx_avg_sum=PREV,UN,0,PREV,IF,rx_avg_sample,+', + "AREA:tx_avg#$HalfGreen", + "AREA:rx_avg#$HalfBlue", + "AREA:overlap#$HalfBlueGreen", + "LINE1:tx_avg#$FullGreen:TX", + 'GPRINT:tx_avg:AVERAGE:%5.1lf%s Avg,', + 'GPRINT:tx_max:MAX:%5.1lf%s Max,', + 'GPRINT:tx_avg:LAST:%5.1lf%s Last', + 'GPRINT:tx_avg_sum:LAST:(ca. %4.0lf%s Total)\l', + "LINE1:rx_avg#$FullBlue:RX", + #'GPRINT:rx_min:MIN:%5.1lf %s Min,', + 'GPRINT:rx_avg:AVERAGE:%5.1lf%s Avg,', + 'GPRINT:rx_max:MAX:%5.1lf%s Max,', + 'GPRINT:rx_avg:LAST:%5.1lf%s Last', + 'GPRINT:rx_avg_sum:LAST:(ca. %4.0lf%s Total)\l' + ], if_packets => ['-v', 'Packets/s', 'DEF:tx_min={file}:tx:MIN', 'DEF:tx_avg={file}:tx:AVERAGE', @@ -1081,6 +1478,58 @@ sub load_graph_definitions 'GPRINT:rx_avg:LAST:%5.1lf%s Last', 'GPRINT:rx_avg_sum:LAST:(ca. %4.0lf%s Total)\l' ], + if_rx_errors => ['-v', 'Errors/s', + 'DEF:min={file}:value:MIN', + 'DEF:avg={file}:value:AVERAGE', + 'DEF:max={file}:value:MAX', + 'CDEF:mytime=avg,TIME,TIME,IF', + 'CDEF:sample_len_raw=mytime,PREV(mytime),-', + 'CDEF:sample_len=sample_len_raw,UN,0,sample_len_raw,IF', + 'CDEF:avg_sample=avg,UN,0,avg,IF,sample_len,*', + 'CDEF:avg_sum=PREV,UN,0,PREV,IF,avg_sample,+', + "AREA:avg#$HalfBlue", + "LINE1:avg#$FullBlue:Errors/s", + 'GPRINT:avg:AVERAGE:%3.1lf%s Avg,', + 'GPRINT:max:MAX:%3.1lf%s Max,', + 'GPRINT:avg:LAST:%3.1lf%s Last', + 'GPRINT:avg_sum:LAST:(ca. %2.0lf%s Total)\l' + ], + ipt_bytes => ['-v', 'Bits/s', + 'DEF:min_raw={file}:value:MIN', + 'DEF:avg_raw={file}:value:AVERAGE', + 'DEF:max_raw={file}:value:MAX', + 'CDEF:min=min_raw,8,*', + 'CDEF:avg=avg_raw,8,*', + 'CDEF:max=max_raw,8,*', + 'CDEF:mytime=avg_raw,TIME,TIME,IF', + 'CDEF:sample_len_raw=mytime,PREV(mytime),-', + 'CDEF:sample_len=sample_len_raw,UN,0,sample_len_raw,IF', + 'CDEF:avg_sample=avg_raw,UN,0,avg_raw,IF,sample_len,*', + 'CDEF:avg_sum=PREV,UN,0,PREV,IF,avg_sample,+', + "AREA:max#$HalfBlue", + "AREA:min#$Canvas", + "LINE1:avg#$FullBlue:Bits/s", + #'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', + 'GPRINT:avg_sum:LAST:(ca. %5.1lf%sB Total)\l' + ], + ipt_packets => ['-v', 'Packets/s', + 'DEF:min_raw={file}:value:MIN', + 'DEF:avg_raw={file}:value:AVERAGE', + 'DEF:max_raw={file}:value:MAX', + 'CDEF:min=min_raw,8,*', + 'CDEF:avg=avg_raw,8,*', + 'CDEF:max=max_raw,8,*', + "AREA:max#$HalfBlue", + "AREA:min#$Canvas", + "LINE1:avg#$FullBlue:Packets/s", + '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' + ], irq => ['-v', 'Issues/s', 'DEF:avg={file}:value:AVERAGE', 'DEF:min={file}:value:MIN', @@ -1093,7 +1542,8 @@ sub load_graph_definitions 'GPRINT:max:MAX:%6.2lf Max,', 'GPRINT:avg:LAST:%6.2lf Last\l' ], - load => ['DEF:s_avg={file}:shortterm:AVERAGE', + load => ['-v', 'System load', + 'DEF:s_avg={file}:shortterm:AVERAGE', 'DEF:s_min={file}:shortterm:MIN', 'DEF:s_max={file}:shortterm:MAX', 'DEF:m_avg={file}:midterm:AVERAGE', @@ -1210,7 +1660,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,', @@ -1222,20 +1672,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', @@ -1243,18 +1692,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', @@ -1453,18 +1909,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", @@ -1509,6 +1953,78 @@ 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_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", @@ -1571,18 +2087,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', @@ -1609,27 +2134,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', @@ -1650,6 +2155,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', @@ -1662,29 +2178,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', @@ -1698,7 +2226,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', @@ -1742,10 +2270,23 @@ 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,*,+', "AREA:temp_max#$HalfRed", "AREA:temp_min#$Canvas", "LINE1:temp_avg#$FullRed:Temperature", @@ -1754,7 +2295,7 @@ sub load_graph_definitions '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', @@ -1778,7 +2319,7 @@ sub load_graph_definitions 'GPRINT:s_max:MAX:%7.3lf%s Max,', 'GPRINT:s_avg:LAST:%7.3lf%s Last' ], - if_octets => ['-v', 'Bits/s', + if_octets => ['-v', 'Bits/s', '-l', '0', 'DEF:out_min_raw={file}:tx:MIN', 'DEF:out_avg_raw={file}:tx:AVERAGE', 'DEF:out_max_raw={file}:tx:MAX', @@ -1838,7 +2379,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', @@ -1863,85 +2404,658 @@ 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 +{ + 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; + 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) + { + $max_inst_name = length ($inst_name); + } + + confess ("No such file: $file") if (!-e $file); + + push (@cmd, + 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#); + } + + { + my $vname = $vnames[@vnames - 1]; + + 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:${vname0}_stk=${vname0}_nnl,${vname1}_stk,+#); + } + + for (my $i = 0; $i < @$sources; $i++) + { + 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; + 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:${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), + ); + } + + 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"; + + $opts->{'rrd_opts'} = ['-v', 'Percent']; + + 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_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); + + 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', '-v', 'Bytes']; + + 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_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