X-Git-Url: https://git.octo.it/?a=blobdiff_plain;f=bindings%2Fperl%2Flib%2FCollectd%2FPlugins%2FOpenVZ.pm;h=66359da12f1b416980b95cf0d56e1fb52771f1fb;hb=master;hp=ea3cee99e16deeedb75b3de3efee0fe1592f15c2;hpb=967685afeaff2cb4f7e4f733f17df95363727c4f;p=collectd.git diff --git a/bindings/perl/lib/Collectd/Plugins/OpenVZ.pm b/bindings/perl/lib/Collectd/Plugins/OpenVZ.pm index ea3cee99..66359da1 100644 --- a/bindings/perl/lib/Collectd/Plugins/OpenVZ.pm +++ b/bindings/perl/lib/Collectd/Plugins/OpenVZ.pm @@ -27,162 +27,219 @@ use warnings; use Collectd qw( :all ); -my @cpu_instances = ('user', 'nice', 'system', 'idle', 'wait', 'interrupt', 'softirq', 'steal'); -my @if_instances = ('if_octets', 'if_packets', 'if_errors'); my $vzctl = '/usr/sbin/vzctl'; my $vzlist = '/usr/sbin/vzlist'; -my $last_stat = {}; +# Since OpenVZ is container based, all guests see all the host's CPUs, +# and would report the same data. So we disable CPU by default. +my $enable_interface = 1; +my $enable_cpu = 0; +my $enable_df = 1; +my $enable_load = 1; +my $enable_processes = 1; +my $enable_users = 1; -sub openvz_read -{ - my %v = (time => time(), interval => plugin_get_interval()); - my (@veids, $veid, $name, $key, $val, $i, @lines, @parts, @counters); +# We probably don't care about loopback transfer +my @ignored_interfaces = ( "lo" ); - @veids = map { s/ //g; $_; } split(/\n/, `$vzlist -Ho veid`); +sub interface_read { + my ($veid, $name) = @_; + my @rx_fields = qw(if_octets if_packets if_errors drop fifo frame compressed multicast); + my @tx_fields = qw(if_octets if_packets if_errors drop fifo frame compressed); + my %v = _build_report_hash($name); - foreach $veid (@veids) - { - ($name = `$vzlist -Ho name $veid`) =~ s/^\s*(.*?)\s*$/$1/; - $name = $veid if ($name =~ /^-$/); + my @lines = `$vzctl exec $veid cat /proc/net/dev`; - $v{'host'} = $name; + for my $line (@lines) { + # skip explanatory text + next if $line !~ /:/; - ##################################################################### - # interface + $line =~ s/^\s+|\s+$//g; - $v{'plugin'} = 'interface'; - delete $v{'plugin_instance'}; + my ($iface, %rx, %tx); - @lines = split(/\n/, `$vzctl exec $veid cat /proc/net/dev`); - foreach (@lines) - { - next if (!/:/); + # read /proc/net/dev fields + ($iface, @rx{@rx_fields}, @tx{@tx_fields}) = split /[: ]+/, $line; - @parts = split(/:/); - ($key = $parts[0]) =~ s/^\s*(.*?)\s*$/$1/; - ($val = $parts[1]) =~ s/^\s*(.*?)\s*$/$1/; - @counters = split(/ +/, $val); + # Skip this interface if it is in the ignored list + next if grep { $iface eq $_ } @ignored_interfaces; - $v{'type_instance'} = $key; - for ($key = 0; $key <= $#if_instances; ++$key) - { - $v{'type'} = $if_instances[$key]; - $v{'values'} = [ $counters[$key], $counters[$key + 8] ]; - plugin_dispatch_values(\%v); - } + for my $instance (qw(if_octets if_packets if_errors)) { + plugin_dispatch_values({ + 'plugin' => 'interface', + 'plugin_instance' => $iface, + 'type' => $instance, + 'values' => [ $rx{$instance}, $tx{$instance} ], + %v, + }); } + } +} - ##################################################################### - # cpu - - $v{'plugin'} = 'cpu'; - $v{'type'} = 'cpu'; - - $i = 0; - @lines = split(/\n/, `$vzctl exec $veid cat /proc/stat`); - foreach (@lines) - { - next if (!/^cpu[0-9]/); - - @counters = split(/ +/); - shift(@counters); - - # Remove once OpenVZ bug 1376 is resolved - if (48485 == $counters[3]) - { - $counters[3] = $last_stat->{"$veid-$i-idle"}; - $counters[4] = $last_stat->{"$veid-$i-wait"}; - } - else - { - $last_stat->{"$veid-$i-idle"} = $counters[3]; - $last_stat->{"$veid-$i-wait"} = $counters[4]; - } - - $v{'plugin_instance'} = $i++; - for ($key = 0; $key <= $#counters; ++$key) - { - $v{'type_instance'} = $cpu_instances[$key]; - $v{'values'} = [ $counters[$key] ]; - plugin_dispatch_values(\%v); - } +sub cpu_read { + my $veid = shift; + my $name = shift; + my ($key, $val, $i, @lines, @counters); + my @cpu_instances = ('user', 'nice', 'system', 'idle', 'wait', 'interrupt', 'softirq', 'steal'); + my $last_stat = {}; + my %v = _build_report_hash($name); + + $v{'plugin'} = 'cpu'; + $v{'type'} = 'cpu'; + + $i = 0; + @lines = split(/\n/, `$vzctl exec $veid cat /proc/stat`); + foreach (@lines) { + next if (!/^cpu[0-9]/); + + @counters = split(/ +/); + shift(@counters); + + # Remove once OpenVZ bug 1376 is resolved + if (48485 == $counters[3]) { + $counters[3] = $last_stat->{"$veid-$i-idle"}; + $counters[4] = $last_stat->{"$veid-$i-wait"}; + } + else { + $last_stat->{"$veid-$i-idle"} = $counters[3]; + $last_stat->{"$veid-$i-wait"} = $counters[4]; } - ##################################################################### - # df + $v{'plugin_instance'} = $i++; + for ($key = 0; $key <= $#counters; ++$key) { + $v{'type_instance'} = $cpu_instances[$key]; + $v{'values'} = [ $counters[$key] ]; + plugin_dispatch_values(\%v); + } + } +} - $v{'plugin'} = 'df'; - delete $v{'plugin_instance'}; - $v{'type'} = 'df'; +sub df_read { + my $veid = shift; + my $name = shift; + my ($key, $val, @lines, @parts); + my %v = _build_report_hash($name); - $val = join(' ', map { (split)[1] } split(/\n/, `$vzctl exec $veid cat /proc/mounts`)); - @lines = split(/\n/, `$vzctl exec $veid stat -tf $val`); - foreach (@lines) - { - @parts = split(/ /); - next if (0 == $parts[7]); + $v{'plugin'} = 'df'; + delete $v{'plugin_instance'}; + $v{'type'} = 'df'; - $val = substr($parts[0], 1); - $val = 'root' if ($val =~ /^$/); - $val =~ s#/#-#g; + $val = join(' ', map { (split)[1] } split(/\n/, `$vzctl exec $veid cat /proc/mounts`)); + @lines = split(/\n/, `$vzctl exec $veid stat -tf $val`); + foreach (@lines) { + @parts = split(/ /); + next if (0 == $parts[7]); - $v{'type_instance'} = $val; - $v{'values'} = [ $parts[5] * ($parts[6] - $parts[7]), $parts[5] * $parts[7] ]; - plugin_dispatch_values(\%v); - } + $val = substr($parts[0], 1); + $val = 'root' if ($val =~ /^$/); + $val =~ s#/#-#g; + + $v{'type_instance'} = $val; + $v{'values'} = [ $parts[5] * ($parts[6] - $parts[7]), $parts[5] * $parts[7] ]; + plugin_dispatch_values(\%v); + } +} - ##################################################################### - # load +sub load_read { + my $veid = shift; + my $name = shift; + my ($key, $val, @lines, @parts); + my %v = _build_report_hash($name); - $v{'plugin'} = 'load'; - delete $v{'plugin_instance'}; - $v{'type'} = 'load'; - delete $v{'type_instance'}; + $v{'plugin'} = 'load'; + delete $v{'plugin_instance'}; + $v{'type'} = 'load'; + delete $v{'type_instance'}; - @parts = split(/ +/, `$vzctl exec $veid cat /proc/loadavg`); - $v{'values'} = [ $parts[0], $parts[1], $parts[2] ]; + @parts = split(/ +/, `$vzctl exec $veid cat /proc/loadavg`); + $v{'values'} = [ $parts[0], $parts[1], $parts[2] ]; + plugin_dispatch_values(\%v); +} + +sub processes_read { + my $veid = shift; + my $name = shift; + my ($key, $val, @lines); + my %v = _build_report_hash($name); + + my $ps_states = { 'paging' => 0, 'blocked' => 0, 'zombies' => 0, 'stopped' => 0, + 'running' => 0, 'sleeping' => 0 }; + my $state_map = { 'R' => 'running', 'S' => 'sleeping', 'D' => 'blocked', + 'Z' => 'zombies', 'T' => 'stopped', 'W' => 'paging' }; + + $v{'plugin'} = 'processes'; + delete $v{'plugin_instance'}; + $v{'type'} = 'ps_state'; + + @lines = map { (split)[2] } split(/\n/, `$vzctl exec $veid cat '/proc/[0-9]*/stat'`); + foreach $key (@lines) { + ++$ps_states->{$state_map->{$key}}; + } + + foreach $key (keys %{$ps_states}) { + $v{'type_instance'} = $key; + $v{'values'} = [ $ps_states->{$key} ]; plugin_dispatch_values(\%v); + } +} - ##################################################################### - # processes +sub users_read { + my $veid = shift; + my $name = shift; + my ($key, $val, @lines); + my %v = _build_report_hash($name); - my $ps_states = { 'paging' => 0, 'blocked' => 0, 'zombies' => 0, 'stopped' => 0, - 'running' => 0, 'sleeping' => 0 }; - my $state_map = { 'R' => 'running', 'S' => 'sleeping', 'D' => 'blocked', - 'Z' => 'zombies', 'T' => 'stopped', 'W' => 'paging' }; + $v{'plugin'} = 'users'; + delete $v{'plugin_instance'}; + $v{'type'} = 'users'; + delete $v{'type_instance'}; - $v{'plugin'} = 'processes'; - delete $v{'plugin_instance'}; - $v{'type'} = 'ps_state'; + @lines = split(/\n/, `$vzctl exec $veid w -h`); + $v{'values'} = [ scalar(@lines) ]; + plugin_dispatch_values(\%v); +} + +sub _build_report_hash { + my $name = shift; + return (time => time(), interval => plugin_get_interval(), host => $name); +} - @lines = map { (split)[2] } split(/\n/, `$vzctl exec $veid cat '/proc/[0-9]*/stat'`); - foreach $key (@lines) - { - ++$ps_states->{$state_map->{$key}}; +sub openvz_read { + my (@veids, $veid, $name); + + @veids = map { s/ //g; $_; } split(/\n/, `$vzlist -Ho veid`); + + foreach $veid (@veids) { + ($name = `$vzlist -Ho name $veid`) =~ s/^\s*(.*?)\s*$/$1/; + ($name = `$vzlist -Ho hostname $veid`) =~ s/^\s*(.*?)\s*$/$1/ if($name =~ /^-$/); + $name = $veid if ($name =~ /^-$/); + + if($enable_interface) { + interface_read($veid, $name); } - foreach $key (keys %{$ps_states}) - { - $v{'type_instance'} = $key; - $v{'values'} = [ $ps_states->{$key} ]; - plugin_dispatch_values(\%v); + if($enable_cpu) { + cpu_read($veid, $name); } - ##################################################################### - # users + if($enable_df) { + df_read($veid, $name); + } - $v{'plugin'} = 'users'; - delete $v{'plugin_instance'}; - $v{'type'} = 'users'; - delete $v{'type_instance'}; + if($enable_load) { + load_read($veid, $name); + } - @lines = split(/\n/, `$vzctl exec $veid w -h`); - $v{'values'} = [ scalar(@lines) ]; - plugin_dispatch_values(\%v); - } + if($enable_processes) { + processes_read($veid, $name); + } - return 1; + if($enable_users) { + users_read($veid, $name); + } + + return 1; + } } plugin_register(TYPE_READ, 'OpenVZ', 'openvz_read');