From c38671738c68028dbb3fd67c9aedc87a6ca4952b Mon Sep 17 00:00:00 2001 From: Quentin Garnier Date: Tue, 28 Oct 2014 16:04:05 +0100 Subject: [PATCH] Refs #7246 WIP (near the end) --- connectors/vmware/centreon_esx_client.pl | 22 -- .../src/centreon/esxd/cmddatastoreio.pm | 145 +++++++---- .../src/centreon/esxd/cmddatastoreiops.pm | 213 ++++++++-------- .../src/centreon/esxd/cmddatastoreusage.pm | 230 ++++++++---------- connectors/vmware/src/centreon/esxd/common.pm | 22 +- 5 files changed, 323 insertions(+), 309 deletions(-) diff --git a/connectors/vmware/centreon_esx_client.pl b/connectors/vmware/centreon_esx_client.pl index de3dae11a..66cadc59d 100644 --- a/connectors/vmware/centreon_esx_client.pl +++ b/connectors/vmware/centreon_esx_client.pl @@ -113,15 +113,6 @@ sub print_usage () { print " --vsphere vsphere name (default: none)\n"; print " -u (--usage) What to check. The list and args (required)\n"; print "\n"; - print "'datastore-usage':\n"; - print " --datastore Datastore name to check (required)\n"; - print " -w (--warning) Warning Threshold (default 80)\n"; - print " -c (--critical) Critical Threshold (default 90)\n"; - print " --units Threshold units: %, MB (default is MB)\n"; - print " --free Threshold is for free size\n"; - print " --filter Use regexp for --datastore option (can check multiples datastores at once)\n"; - print " --skip-errors Status OK if a datastore is not accessible (when you checks multiples)\n"; - print "\n"; print "'datastore-iops':\n"; print " --datastore Datastore name to check (required)\n"; print " -w (--warning) Warning Threshold (default none)\n"; @@ -130,11 +121,6 @@ sub print_usage () { print " --skip-errors Status OK if a datastore is not accessible (when you checks multiples)\n"; print " --details-value Only display VMs with iops higher than the following value (permits to see VMs with high values) (default 50)\n"; print "\n"; - print "'datastore-io':\n"; - print " --datastore Datastore name to check (required)\n"; - print " -w (--warning) Warning Threshold in kBps (default none)\n"; - print " -c (--critical) Critical Threshold in kBps (default none)\n"; - print "\n"; print "'datastore-snapshots':\n"; print " --datastore Datastore name to check (required)\n"; print " -w (--warning) Warning Threshold in bytes for all snapshots (default none)\n"; @@ -156,14 +142,6 @@ sub print_usage () { print " -w (--warning) Warning Threshold in IOPS (default none)\n"; print " -c (--critical) Critical Threshold in IOPS (default none)\n"; print "\n"; - print "'thinprovisioningvm':\n"; - print " --vm VM to check (required)\n"; - print " --filter Use regexp for --vm option (can check multiples vm at once)\n"; - print " --on Warn or critical if thinprovisioning set\n"; - print " --crit Critical\n"; - print " --warn Warn\n"; - print " --skip-errors Status OK if vms are disconnected (when you checks multiples)\n"; - print "\n"; } sub print_help () { diff --git a/connectors/vmware/src/centreon/esxd/cmddatastoreio.pm b/connectors/vmware/src/centreon/esxd/cmddatastoreio.pm index 5b7e3e73e..71550a0bc 100644 --- a/connectors/vmware/src/centreon/esxd/cmddatastoreio.pm +++ b/connectors/vmware/src/centreon/esxd/cmddatastoreio.pm @@ -9,8 +9,7 @@ sub new { my $class = shift; my $self = {}; $self->{logger} = shift; - $self->{obj_esxd} = shift; - $self->{commandName} = 'datastore-io'; + $self->{commandName} = 'datastoreio'; bless $self, $class; return $self; @@ -22,79 +21,131 @@ sub getCommandName { } sub checkArgs { - my $self = shift; - my ($ds, $warn, $crit) = @_; + my ($self, %options) = @_; - if (!defined($ds) || $ds eq "") { - $self->{logger}->writeLogError("ARGS error: need datastore name"); + if (defined($options{arguments}->{datastore_name}) && $options{arguments}->{datastore_name} eq "") { + $options{manager}->{output}->output_add(severity => 'UNKNOWN', + short_msg => "Argument error: datastore name cannot be null"); return 1; } - if (defined($warn) && $warn ne "" && $warn !~ /^-?(?:\d+\.?|\.\d)\d*\z/) { - $self->{logger}->writeLogError("ARGS error: warn threshold must be a positive number"); + if (defined($options{arguments}->{disconnect_status}) && + $options{manager}->{output}->is_litteral_status(status => $options{arguments}->{disconnect_status}) == 0) { + $options{manager}->{output}->output_add(severity => 'UNKNOWN', + short_msg => "Argument error: wrong value for disconnect status '" . $options{arguments}->{disconnect_status} . "'"); return 1; } - if (defined($crit) && $crit ne "" && $crit !~ /^-?(?:\d+\.?|\.\d)\d*\z/) { - $self->{logger}->writeLogError("ARGS error: crit threshold must be a positive number"); - return 1; - } - if (defined($warn) && defined($crit) && $warn ne "" && $crit ne "" && $warn > $crit) { - $self->{logger}->writeLogError("ARGS error: warn threshold must be lower than crit threshold"); - return 1; + foreach my $label (('warning', 'critical')) { + if (($options{manager}->{perfdata}->threshold_validate(label => $label, value => $options{arguments}->{$label})) == 0) { + $options{manager}->{output}->output_add(severity => 'UNKNOWN', + short_msg => "Argument error: wrong value for $label value '" . $options{arguments}->{$label} . "'."); + return 1; + } } return 0; } sub initArgs { - my $self = shift; - $self->{ds} = $_[0]; - $self->{warn} = (defined($_[1]) ? $_[1] : ''); - $self->{crit} = (defined($_[2]) ? $_[2] : ''); + my ($self, %options) = @_; + + foreach (keys %{$options{arguments}}) { + $self->{$_} = $options{arguments}->{$_}; + } + $self->{manager} = centreon::esxd::common::init_response(); + $self->{manager}->{output}->{plugin} = $options{arguments}->{identity}; + foreach my $label (('warning', 'critical')) { + $self->{manager}->{perfdata}->threshold_validate(label => $label, value => $options{arguments}->{$label}); + } +} + +sub set_connector { + my ($self, %options) = @_; + + $self->{obj_esxd} = $options{connector}; } sub run { my $self = shift; if (!($self->{obj_esxd}->{perfcounter_speriod} > 0)) { - my $status = centreon::esxd::common::errors_mask(0, 'UNKNOWN'); - $self->{obj_esxd}->print_response(centreon::esxd::common::get_status($status) . "|Can't retrieve perf counters.\n"); - return ; - } - - my %filters = ('summary.name' => $self->{ds}); - my @properties = ('summary.name', 'summary.accessible'); - my $result = centreon::esxd::common::get_entities_host($self->{obj_esxd}, 'Datastore', \%filters, \@properties); - if (!defined($result)) { + $self->{manager}->{output}->output_add(severity => 'UNKNOWN', + short_msg => "Can't retrieve perf counters"); return ; } - return if (centreon::esxd::common::datastore_state($self->{obj_esxd}, $self->{ds}, $$result[0]->{'summary.accessible'}) == 0); - + my %filters = (); + my $multiple = 0; + if (defined($self->{datastore_name}) && !defined($self->{filter})) { + $filters{name} = qr/^\Q$self->{datastore_name}\E$/; + } elsif (!defined($self->{datastore_name})) { + $filters{name} = qr/.*/; + } else { + $filters{name} = qr/$self->{datastore_name}/; + } + my @properties = ('summary.name', 'summary.accessible'); + + my $result = centreon::esxd::common::get_entities_host($self->{obj_esxd}, 'Datastore', \%filters, \@properties); + return if (!defined($result)); + my $values = centreon::esxd::common::generic_performance_values_historic($self->{obj_esxd}, $result, [{'label' => 'datastore.read.average', 'instances' => ['']}, {'label' => 'datastore.write.average', 'instances' => ['']}], - $self->{obj_esxd}->{perfcounter_speriod}); + $self->{obj_esxd}->{perfcounter_speriod}, + skip_undef_counter => 1, multiples => 1, multiples_result_by_entity => 1); return if (centreon::esxd::common::performance_errors($self->{obj_esxd}, $values) == 1); - - my $read_counter = centreon::esxd::common::simplify_number(centreon::esxd::common::convert_number($values->{$self->{obj_esxd}->{perfcounter_cache}->{'datastore.read.average'}->{'key'} . ":"}[0])); - my $write_counter = centreon::esxd::common::simplify_number(centreon::esxd::common::convert_number($values->{$self->{obj_esxd}->{perfcounter_cache}->{'datastore.write.average'}->{'key'} . ":"}[0])); - - my $status = 0; # OK - my $output = ''; - if ((defined($self->{warn}) && $self->{warn} ne "") && - ($read_counter >= $self->{warn} || $write_counter >= $self->{warn})) { - $status = centreon::esxd::common::errors_mask($status, 'WARNING'); + if (scalar(@$result) > 1) { + $multiple = 1; } - if ((defined($self->{crit}) && $self->{crit} ne "") && - ($read_counter >= $self->{crit} || $write_counter >= $self->{crit})) { - $status = centreon::esxd::common::errors_mask($status, 'CRITICAL'); + if ($multiple == 1) { + $self->{manager}->{output}->output_add(severity => 'OK', + short_msg => sprintf("All datastore rates are ok")); } + + foreach my $entity_view (@$result) { + next if (centreon::esxd::common::datastore_state(connector => $self->{obj_esxd}, + name => $entity_view->{'summary.name'}, + state => $entity_view->{'summary.accessible'}, + status => $self->{disconnect_status}, + multiple => $multiple) == 0); + my $entity_value = $entity_view->{mo_ref}->{value}; + + # in KBps + my $read_counter = centreon::esxd::common::simplify_number(centreon::esxd::common::convert_number($values->{$entity_value}->{$self->{obj_esxd}->{perfcounter_cache}->{'datastore.read.average'}->{'key'} . ":"}[0])) * 1024; + my $write_counter = centreon::esxd::common::simplify_number(centreon::esxd::common::convert_number($values->{$entity_value}->{$self->{obj_esxd}->{perfcounter_cache}->{'datastore.write.average'}->{'key'} . ":"}[0])) * 1024; - $output = "Rate of reading data : " . centreon::esxd::common::simplify_number($read_counter / 1024 * 8) . " Mb/s, Rate of writing data : " . centreon::esxd::common::simplify_number($write_counter / 1024 * 8) . " Mb/s"; - $output .= "|read_rate=" . ($read_counter * 1024 * 8) . "b/s write_rate=" . (($write_counter * 1024 * 8)) . "b/s"; - - $self->{obj_esxd}->print_response(centreon::esxd::common::get_status($status) . "|$output\n"); + my $exit1 = $self->{manager}->{perfdata}->threshold_check(value => $read_counter, threshold => [ { label => 'critical', 'exit_litteral' => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]); + my $exit2 = $self->{manager}->{perfdata}->threshold_check(value => $write_counter, threshold => [ { label => 'critical', 'exit_litteral' => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]); + my $exit = $self->{manager}->{output}->get_most_critical(status => [ $exit1, $exit2 ]); + my ($read_value, $read_unit) = $self->{manager}->{perfdata}->change_bytes(value => $read_counter); + my ($write_value, $write_unit) = $self->{manager}->{perfdata}->change_bytes(value => $write_counter); + + $self->{manager}->{output}->output_add(long_msg => sprintf("'%s' Rate of reading data: %s Rate of writing data: %s", + $entity_view->{'summary.name'}, + $read_value . " " . $read_unit . "/s", + $write_value . " " . $write_unit . "/s")); + if ($multiple == 0 || + !$self->{manager}->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { + $self->{manager}->{output}->output_add(severity => $exit, + short_msg => sprintf("'%s' Rate of reading data: %s Rate of writing data: %s", + $entity_view->{'summary.name'}, + $read_value . " " . $read_unit . "/s", + $write_value . " " . $write_unit . "/s")); + } + + my $extra_label = ''; + $extra_label = '_' . $entity_view->{'summary.name'} if ($multiple == 1); + $self->{manager}->{output}->perfdata_add(label => 'read_rate' . $extra_label, unit => 'B/s', + value => $read_counter, + warning => $self->{manager}->{perfdata}->get_perfdata_for_output(label => 'warning'), + critical => $self->{manager}->{perfdata}->get_perfdata_for_output(label => 'critical'), + min => 0); + $self->{manager}->{output}->perfdata_add(label => 'write_rate' . $extra_label, unit => 'B/s', + value => $write_counter, + warning => $self->{manager}->{perfdata}->get_perfdata_for_output(label => 'warning'), + critical => $self->{manager}->{perfdata}->get_perfdata_for_output(label => 'critical'), + min => 0); + } } 1; diff --git a/connectors/vmware/src/centreon/esxd/cmddatastoreiops.pm b/connectors/vmware/src/centreon/esxd/cmddatastoreiops.pm index 37eeabd2b..cae46986a 100644 --- a/connectors/vmware/src/centreon/esxd/cmddatastoreiops.pm +++ b/connectors/vmware/src/centreon/esxd/cmddatastoreiops.pm @@ -9,8 +9,7 @@ sub new { my $class = shift; my $self = {}; $self->{logger} = shift; - $self->{obj_esxd} = shift; - $self->{commandName} = 'datastore-iops'; + $self->{commandName} = 'datastoreiops'; bless $self, $class; return $self; @@ -22,87 +21,87 @@ sub getCommandName { } sub checkArgs { - my $self = shift; - my ($ds, $filter, $warn, $crit, $details_value) = @_; + my ($self, %options) = @_; - if (!defined($ds) || $ds eq "") { - $self->{logger}->writeLogError("ARGS error: need datastore name"); + if (defined($options{arguments}->{datastore_name}) && $options{arguments}->{datastore_name} eq "") { + $options{manager}->{output}->output_add(severity => 'UNKNOWN', + short_msg => "Argument error: datastore name cannot be null"); return 1; } - if (defined($details_value) && $details_value ne "" && $details_value !~ /^-?(?:\d+\.?|\.\d)\d*\z/) { - $self->{logger}->writeLogError("ARGS error: details-value must be a positive number"); + if (defined($options{arguments}->{disconnect_status}) && + $options{manager}->{output}->is_litteral_status(status => $options{arguments}->{disconnect_status}) == 0) { + $options{manager}->{output}->output_add(severity => 'UNKNOWN', + short_msg => "Argument error: wrong value for disconnect status '" . $options{arguments}->{disconnect_status} . "'"); return 1; } - if (defined($warn) && $warn ne "" && $warn !~ /^-?(?:\d+\.?|\.\d)\d*\z/) { - $self->{logger}->writeLogError("ARGS error: warn threshold must be a positive number"); - return 1; - } - if (defined($crit) && $crit ne "" && $crit !~ /^-?(?:\d+\.?|\.\d)\d*\z/) { - $self->{logger}->writeLogError("ARGS error: crit threshold must be a positive number"); - return 1; - } - if (defined($warn) && defined($crit) && $warn ne "" && $crit ne "" && $warn > $crit) { - $self->{logger}->writeLogError("ARGS error: warn threshold must be lower than crit threshold"); - return 1; + foreach my $label (('warning', 'critical')) { + if (($options{manager}->{perfdata}->threshold_validate(label => $label, value => $options{arguments}->{$label})) == 0) { + $options{manager}->{output}->output_add(severity => 'UNKNOWN', + short_msg => "Argument error: wrong value for $label value '" . $options{arguments}->{$label} . "'."); + return 1; + } } return 0; } sub initArgs { - my $self = shift; - $self->{ds} = $_[0]; - $self->{filter} = (defined($_[1]) && $_[1] == 1) ? 1 : 0; - $self->{warn} = (defined($_[2]) ? $_[2] : ''); - $self->{crit} = (defined($_[3]) ? $_[3] : ''); - $self->{details_value} = (defined($_[4]) ? $_[4] : 50); - $self->{skip_errors} = (defined($_[5]) && $_[5] == 1) ? 1 : 0; + my ($self, %options) = @_; + + foreach (keys %{$options{arguments}}) { + $self->{$_} = $options{arguments}->{$_}; + } + $self->{manager} = centreon::esxd::common::init_response(); + $self->{manager}->{output}->{plugin} = $options{arguments}->{identity}; + foreach my $label (('warning', 'critical')) { + $self->{manager}->{perfdata}->threshold_validate(label => $label, value => $options{arguments}->{$label}); + } +} + +sub set_connector { + my ($self, %options) = @_; + + $self->{obj_esxd} = $options{connector}; } sub run { my $self = shift; - my $status = 0; # OK - my $output = ''; - my $output_append = ''; - my $output_warning = ''; - my $output_warning_append = ''; - my $output_critical = ''; - my $output_critical_append = ''; - my $output_unknown = ''; - my $output_unknown_append = ''; - my $perfdata = ''; - if (!($self->{obj_esxd}->{perfcounter_speriod} > 0)) { - $status = centreon::esxd::common::errors_mask(0, 'UNKNOWN'); - $self->{obj_esxd}->print_response(centreon::esxd::common::get_status($status) . "|Can't retrieve perf counters.\n"); + $self->{manager}->{output}->output_add(severity => 'UNKNOWN', + short_msg => "Can't retrieve perf counters"); return ; } my %filters = (); - if ($self->{filter} == 0) { - $filters{name} = qr/^\Q$self->{ds}\E$/; + my $multiple = 0; + if (defined($self->{datastore_name}) && !defined($self->{filter})) { + $filters{name} = qr/^\Q$self->{datastore_name}\E$/; + } elsif (!defined($self->{datastore_name})) { + $filters{name} = qr/.*/; } else { - $filters{name} = qr/$self->{ds}/; + $filters{name} = qr/$self->{datastore_name}/; } - my @properties = ('summary.accessible', 'summary.name', 'vm', 'info'); my $result = centreon::esxd::common::get_entities_host($self->{obj_esxd}, 'Datastore', \%filters, \@properties); - if (!defined($result)) { - return ; + return if (!defined($result)); + + if (scalar(@$result) > 1) { + $multiple = 1; + } + if ($multiple == 1) { + $self->{manager}->{output}->output_add(severity => 'OK', + short_msg => sprintf("All Datastore IOPS counters are ok")); } #my %uuid_list = (); my %disk_name = (); my %datastore_lun = (); foreach (@$result) { - if (!centreon::esxd::common::is_accessible($_->{'summary.accessible'})) { - if ($self->{skip_errors} == 0 || $self->{filter} == 0) { - $status = centreon::esxd::common::errors_mask($status, 'UNKNOWN'); - centreon::esxd::common::output_add(\$output_unknown, \$output_unknown_append, ", ", - "'" . $_->{'summary.name'} . "' not accessible. Can be disconnected"); - } - next; - } + next if (centreon::esxd::common::datastore_state(connector => $self->{obj_esxd}, + name => $_->{'summary.name'}, + state => $_->{'summary.accessible'}, + status => $self->{disconnect_status}, + multiple => $multiple) == 0); if ($_->info->isa('VmfsDatastoreInfo')) { #$uuid_list{$_->volume->uuid} = $_->volume->name; @@ -133,15 +132,13 @@ sub run { @properties = ('name', 'runtime.connectionState', 'runtime.powerState'); my $result2 = centreon::esxd::common::get_views($self->{obj_esxd}, \@vm_array, \@properties); - if (!defined($result2)) { - return ; - } + return if (!defined($result2)); # Remove disconnected or not running vm my %ref_ids_vm = (); for(my $i = $#{$result2}; $i >= 0; --$i) { - if (!centreon::esxd::common::is_connected(${$result2}[$i]->{'runtime.connectionState'}->val) || - !centreon::esxd::common::is_running(${$result2}[$i]->{'runtime.powerState'}->val)) { + if (!centreon::esxd::common::is_connected(state => ${$result2}[$i]->{'runtime.connectionState'}->val) || + !centreon::esxd::common::is_running(power => ${$result2}[$i]->{'runtime.powerState'}->val)) { splice @$result2, $i, 1; next; } @@ -153,7 +150,8 @@ sub run { $result2, [{'label' => 'disk.numberRead.summation', 'instances' => ['*']}, {'label' => 'disk.numberWrite.summation', 'instances' => ['*']}], - $self->{obj_esxd}->{perfcounter_speriod}, 1, 1); + $self->{obj_esxd}->{perfcounter_speriod}, + skip_undef_counter => 1, multiples => 1); return if (centreon::esxd::common::performance_errors($self->{obj_esxd}, $values) == 1); @@ -161,9 +159,7 @@ sub run { my ($vm_id, $id, $disk_name) = split(/:/); # RDM Disk. We skip. Don't know how to manage it right now. - if (!defined($disk_name{$disk_name})) { - next; - } + next if (!defined($disk_name{$disk_name})); my $tmp_value = centreon::esxd::common::simplify_number(centreon::esxd::common::convert_number($values->{$_}[0] / $self->{obj_esxd}->{perfcounter_speriod})); $datastore_lun{$disk_name{$disk_name}}{$self->{obj_esxd}->{perfcounter_cache_reverse}->{$id}} += $tmp_value; @@ -178,62 +174,65 @@ sub run { my $total_read_counter = $datastore_lun{$_}{'disk.numberRead.summation'}; my $total_write_counter = $datastore_lun{$_}{'disk.numberWrite.summation'}; - if (defined($self->{crit}) && $self->{crit} ne "" && ($total_read_counter >= $self->{crit})) { - centreon::esxd::common::output_add(\$output_critical, \$output_critical_append, ", ", - "'$total_read_counter' read iops on '" . $_ . "'" . $self->vm_iops_details('disk.numberRead.summation', $datastore_lun{$_}, \%ref_ids_vm)); - $status = centreon::esxd::common::errors_mask($status, 'CRITICAL'); - } elsif (defined($self->{warn}) && $self->{warn} ne "" && ($total_read_counter >= $self->{warn})) { - centreon::esxd::common::output_add(\$output_warning, \$output_warning_append, ", ", - "'$total_read_counter' read on '" . $_ . "'" . $self->vm_iops_details('disk.numberRead.summation', $datastore_lun{$_}, \%ref_ids_vm)); - $status = centreon::esxd::common::errors_mask($status, 'WARNING'); + my $exit = $self->{manager}->{perfdata}->threshold_check(value => $total_read_counter, threshold => [ { label => 'critical', 'exit_litteral' => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]); + $self->{manager}->{output}->output_add(long_msg => sprintf("'%s' read iops on '%s'", + $total_read_counter, $_)); + if ($multiple == 0 || + !$self->{manager}->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { + $self->{manager}->{output}->output_add(severity => $exit, + short_msg => sprintf("'%s' read iops on '%s'", + $total_read_counter, $_)); + $self->vm_iops_details(label => 'disk.numberRead.summation', + type => 'read', + detail => $datastore_lun{$_}, + ref_vm => \%ref_ids_vm); } - if (defined($self->{crit}) && $self->{crit} ne "" && ($total_write_counter >= $self->{crit})) { - centreon::esxd::common::output_add(\$output_critical, \$output_critical_append, ", ", - "'$total_write_counter' write iops on '" . $_ . "'" . $self->vm_iops_details('disk.numberWrite.summation', $datastore_lun{$_}, \%ref_ids_vm)); - $status = centreon::esxd::common::errors_mask($status, 'CRITICAL'); - } elsif (defined($self->{warn}) && $self->{warn} ne "" && ($total_write_counter >= $self->{warn})) { - centreon::esxd::common::output_add(\$output_warning, \$output_warning_append, ", ", - "'$total_write_counter' write iops on '" . $_ . "'" . $self->vm_iops_details('disk.numberWrite.summation', $datastore_lun{$_}, \%ref_ids_vm)); - $status = centreon::esxd::common::errors_mask($status, 'WARNING'); + $exit = $self->{manager}->{perfdata}->threshold_check(value => $total_write_counter, threshold => [ { label => 'critical', 'exit_litteral' => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]); + $self->{manager}->{output}->output_add(long_msg => sprintf("'%s' write iops on '%s'", + $total_write_counter, $_)); + if ($multiple == 0 || + !$self->{manager}->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { + $self->{manager}->{output}->output_add(severity => $exit, + short_msg => sprintf("'%s' write iops on '%s'", + $total_write_counter, $_)); + $self->vm_iops_details(label => 'disk.numberWrite.summation', + type => 'write', + detail => $datastore_lun{$_}, + ref_vm => \%ref_ids_vm) } - if ($self->{filter} == 1) { - $perfdata .= " 'riops_" . $_ . "'=" . $total_read_counter . "iops;$self->{warn};$self->{crit};0; 'wiops_" . $_ . "'=" . $total_write_counter . "iops;$self->{warn};$self->{crit};0;"; - } else { - $perfdata .= " 'riops=" . $total_read_counter . "iops;$self->{warn};$self->{crit};0; wiops=" . $total_write_counter . "iops;$self->{warn};$self->{crit};0;"; - } + my $extra_label = ''; + $extra_label = '_' . $_ if ($multiple == 1); + $self->{manager}->{output}->perfdata_add(label => 'riops' . $extra_label, unit => 'iops', + value => $total_read_counter, + warning => $self->{manager}->{perfdata}->get_perfdata_for_output(label => 'warning'), + critical => $self->{manager}->{perfdata}->get_perfdata_for_output(label => 'critical'), + min => 0); + $self->{manager}->{output}->perfdata_add(label => 'wiops' . $extra_label, unit => 'iops', + value => $total_write_counter, + warning => $self->{manager}->{perfdata}->get_perfdata_for_output(label => 'warning'), + critical => $self->{manager}->{perfdata}->get_perfdata_for_output(label => 'critical'), + min => 0); } - - if ($output_unknown ne "") { - $output .= $output_append . "UNKNOWN - $output_unknown"; - $output_append = ". "; - } - if ($output_critical ne "") { - $output .= $output_append . "CRITICAL - $output_critical"; - $output_append = ". "; - } - if ($output_warning ne "") { - $output .= $output_append . "WARNING - $output_warning"; - } - if ($status == 0) { - $output = "All Datastore IOPS counters are ok"; - } - $self->{obj_esxd}->print_response(centreon::esxd::common::get_status($status) . "|$output|$perfdata\n"); } sub vm_iops_details { - my ($self, $label, $ds_details, $ref_ids_vm) = @_; - my $details = ''; + my ($self, %options) = @_; - foreach my $value (keys %$ds_details) { - # Dont need to display vm with iops < 1 - if ($value =~ /^vm.*?$label$/ && $ds_details->{$value} >= $self->{details_value}) { - my ($vm_ids) = split(/_/, $value); - $details .= " ['" . $ref_ids_vm->{$vm_ids} . "' " . $ds_details->{$value} . ']'; + $self->{manager}->{output}->output_add(long_msg => sprintf(" VM IOPs details: ")); + my $num = 0; + foreach my $value (keys %{$options{detail}}) { + # display only for high iops + if ($value =~ /^vm.*?$options{label}$/ && $options{detail}->{$value} >= $self->{detail_iops_min}) { + my ($vm_id) = split(/_/, $value); + $num++; + $self->{manager}->{output}->output_add(long_msg => sprintf(" '%s' %s iops", $options{ref_vm}->{$vm_id}, $options{detail}->{$value})); } } - return $details; + if ($num == 0) { + $self->{manager}->{output}->output_add(long_msg => sprintf(" no vm with iops >= %s", $self->{detail_iops_min})); + } } 1; diff --git a/connectors/vmware/src/centreon/esxd/cmddatastoreusage.pm b/connectors/vmware/src/centreon/esxd/cmddatastoreusage.pm index fd328f23c..e2e3bf440 100644 --- a/connectors/vmware/src/centreon/esxd/cmddatastoreusage.pm +++ b/connectors/vmware/src/centreon/esxd/cmddatastoreusage.pm @@ -9,8 +9,7 @@ sub new { my $class = shift; my $self = {}; $self->{logger} = shift; - $self->{obj_esxd} = shift; - $self->{commandName} = 'datastore-usage'; + $self->{commandName} = 'datastoreusage'; bless $self, $class; return $self; @@ -22,162 +21,145 @@ sub getCommandName { } sub checkArgs { - my $self = shift; - my ($ds, $filter, $warn, $crit, $free, $units) = @_; + my ($self, %options) = @_; - if (!defined($ds) || $ds eq "") { - $self->{logger}->writeLogError("ARGS error: need datastore name."); + if (defined($options{arguments}->{datastore_name}) && $options{arguments}->{datastore_name} eq "") { + $options{manager}->{output}->output_add(severity => 'UNKNOWN', + short_msg => "Argument error: datastore name cannot be null"); return 1; } - if (defined($warn) && $warn !~ /^-?(?:\d+\.?|\.\d)\d*\z/) { - $self->{logger}->writeLogError("ARGS error: warn threshold must be a positive number."); - return 1; - } - if (defined($crit) && $crit !~ /^-?(?:\d+\.?|\.\d)\d*\z/) { - $self->{logger}->writeLogError("ARGS error: crit threshold must be a positive number."); + if (defined($options{arguments}->{disconnect_status}) && + $options{manager}->{output}->is_litteral_status(status => $options{arguments}->{disconnect_status}) == 0) { + $options{manager}->{output}->output_add(severity => 'UNKNOWN', + short_msg => "Argument error: wrong value for disconnect status '" . $options{arguments}->{disconnect_status} . "'"); return 1; } - if (defined($warn) && defined($crit) && (!defined($free) || $free != 1) && $warn > $crit) { - $self->{logger}->writeLogError("ARGS error: warn threshold must be lower than crit threshold."); - return 1; + if (!defined($options{arguments}->{units}) || $options{arguments}->{units} !~ /^(%|B)$/) { + $self->{output}->add_option_msg(short_msg => "Wrong units option '" . (defined($options{arguments}->{units}) ? $options{arguments}->{units} : 'null') . "'."); + $self->{output}->option_exit(); } - if (defined($warn) && defined($crit) && defined($free) && $free == 1 && $warn < $crit) { - $self->{logger}->writeLogError("ARGS error: warn threshold must be higher than crit threshold."); - return 1; - } - if (defined($units) && ($units !~ /^(%|MB)/)) { - $self->{logger}->writeLogError("ARGS error: units should be '%' or 'MB'."); - return 1; + foreach my $label (('warning', 'critical')) { + if (($options{manager}->{perfdata}->threshold_validate(label => $label, value => $options{arguments}->{$label})) == 0) { + $options{manager}->{output}->output_add(severity => 'UNKNOWN', + short_msg => "Argument error: wrong value for $label value '" . $options{arguments}->{$label} . "'."); + return 1; + } } return 0; } sub initArgs { - my $self = shift; - $self->{ds} = $_[0]; - $self->{filter} = (defined($_[1]) && $_[1] == 1) ? 1 : 0; - $self->{free} = (defined($_[4]) && $_[4] == 1) ? 1 : 0; - $self->{warn} = (defined($_[2]) ? $_[2] : (($self->{free} == 1) ? 20 : 80)); - $self->{crit} = (defined($_[3]) ? $_[3] : (($self->{free} == 1) ? 10 : 90)); - $self->{units} = (defined($_[5])) ? $_[5] : '%'; - $self->{skip_errors} = (defined($_[6]) && $_[6] == 1) ? 1 : 0; + my ($self, %options) = @_; + + foreach (keys %{$options{arguments}}) { + $self->{$_} = $options{arguments}->{$_}; + } + $self->{manager} = centreon::esxd::common::init_response(); + $self->{manager}->{output}->{plugin} = $options{arguments}->{identity}; + foreach my $label (('warning', 'critical')) { + $self->{manager}->{perfdata}->threshold_validate(label => $label, value => $options{arguments}->{$label}); + } +} + +sub set_connector { + my ($self, %options) = @_; + + $self->{obj_esxd} = $options{connector}; } sub run { my $self = shift; - my %filters = (); - if ($self->{filter} == 0) { - $filters{name} = qr/^\Q$self->{ds}\E$/; + my %filters = (); + my $multiple = 0; + if (defined($self->{datastore_name}) && !defined($self->{filter})) { + $filters{name} = qr/^\Q$self->{datastore_name}\E$/; + } elsif (!defined($self->{datastore_name})) { + $filters{name} = qr/.*/; } else { - $filters{name} = qr/$self->{ds}/; + $filters{name} = qr/$self->{datastore_name}/; } my @properties = ('summary'); my $result = centreon::esxd::common::get_entities_host($self->{obj_esxd}, 'Datastore', \%filters, \@properties); - if (!defined($result)) { - return ; + return if (!defined($result)); + + if (scalar(@$result) > 1) { + $multiple = 1; + } + if ($multiple == 1) { + $self->{manager}->{output}->output_add(severity => 'OK', + short_msg => sprintf("All Datastore usages are ok")); } - my $status = 0; # OK - my $output = ""; - my $output_append = ''; - my $output_warning = ''; - my $output_warning_append = ''; - my $output_critical = ''; - my $output_critical_append = ''; - my $output_unknown = ''; - my $output_unknown_append = ''; - my $output_ok_unit = ''; - my $perfdata = ''; - my ($warn_threshold, $crit_threshold); - my ($pctwarn_threshold, $pctcrit_threshold) = ($self->{warn}, $self->{crit}); - - if ($self->{units} eq '%' && $self->{free} == 1) { - $pctwarn_threshold = 100 - $self->{warn}; - $pctcrit_threshold = 100 - $self->{crit}; - } - - foreach my $ds (@$result) { - if (!centreon::esxd::common::is_accessible($ds->summary->accessible)) { - if ($self->{skip_errors} == 0 || $self->{filter} == 0) { - $status = centreon::esxd::common::errors_mask($status, 'UNKNOWN'); - centreon::esxd::common::output_add(\$output_unknown, \$output_unknown_append, ", ", - "'" . $ds->summary->name . "' not accessible. Can be disconnected"); + foreach my $entity_view (@$result) { + next if (centreon::esxd::common::datastore_state(connector => $self->{obj_esxd}, + name => $entity_view->summary->name, + state => $entity_view->summary->accessible, + status => $self->{disconnect_status}, + multiple => $multiple) == 0); + + # capacity 0... + if ($entity_view->summary->capacity <= 0) { + if ($multiple == 0) { + $self->{manager}->{output}->output_add(severity => 'OK', + short_msg => sprintf("datastore size is 0")); } next; } - - # capacity 0... - next if ($ds->summary->capacity <= 0); - my $dsName = $ds->summary->name; - my $capacity = $ds->summary->capacity; - my $free = $ds->summary->freeSpace; + # in Bytes + my $name_storage = $entity_view->summary->name; + my $total_size = $entity_view->summary->capacity; + my $total_free = $entity_view->summary->freeSpace; + my $total_used = $total_size - $total_free; + my $prct_used = $total_used * 100 / $total_size; + my $prct_free = 100 - $prct_used; - if ($self->{units} eq 'MB' && $self->{free} == 1) { - $warn_threshold = $capacity - ($self->{warn} * 1024 * 1024); - $crit_threshold = $capacity - ($self->{crit} * 1024 * 1024); - } elsif ($self->{units} eq 'MB' && $self->{free} == 0) { - $warn_threshold = $self->{warn} * 1024 * 1024; - $crit_threshold = $self->{crit} * 1024 * 1024; - } else { - $warn_threshold = ($capacity * $pctwarn_threshold) / 100; - $crit_threshold = ($capacity * $pctcrit_threshold) / 100; - } - - my $pct = ($capacity - $free) / $capacity * 100; + my ($exit, $threshold_value); + $threshold_value = $total_used; + $threshold_value = $total_free if (defined($self->{free})); + if ($self->{units} eq '%') { + $threshold_value = $prct_used; + $threshold_value = $prct_free if (defined($self->{free})); + } + $exit = $self->{manager}->{perfdata}->threshold_check(value => $threshold_value, threshold => [ { label => 'critical', 'exit_litteral' => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]); - my $usedD = ($capacity - $free) / 1024 / 1024 / 1024; - my $sizeD = $capacity / 1024 / 1024 / 1024; + my ($total_size_value, $total_size_unit) = $self->{manager}->{perfdata}->change_bytes(value => $total_size); + my ($total_used_value, $total_used_unit) = $self->{manager}->{perfdata}->change_bytes(value => $total_used); + my ($total_free_value, $total_free_unit) = $self->{manager}->{perfdata}->change_bytes(value => $total_free); - $output_ok_unit = "Datastore $dsName - used ".sprintf("%.2f", $usedD)." Go / ".sprintf("%.2f", $sizeD)." Go (".sprintf("%.2f", $pct)." %)"; - - if ($self->{units} eq '%' && $pct >= $pctcrit_threshold) { - centreon::esxd::common::output_add(\$output_critical, \$output_critical_append, ", ", - "'$dsName' used ".sprintf("%.2f", $usedD)." Go / ".sprintf("%.2f", $sizeD)." Go (".sprintf("%.2f", $pct)." %)"); - $status = centreon::esxd::common::errors_mask($status, 'CRITICAL'); - } elsif ($self->{units} eq '%' && $pct >= $pctwarn_threshold) { - centreon::esxd::common::output_add(\$output_warning, \$output_warning_append, ", ", - "'$dsName' used ".sprintf("%.2f", $usedD)." Go / ".sprintf("%.2f", $sizeD)." Go (".sprintf("%.2f", $pct)." %)"); - $status = centreon::esxd::common::errors_mask($status, 'WARNING'); - } elsif ($self->{units} eq 'MB' && ($capacity - $free) >= $crit_threshold) { - centreon::esxd::common::output_add(\$output_critical, \$output_critical_append, ", ", - "'$dsName' used ".sprintf("%.2f", $usedD)." Go / ".sprintf("%.2f", $sizeD)." Go (".sprintf("%.2f", $pct)." %)"); - $status = centreon::esxd::common::errors_mask($status, 'CRITICAL'); - } elsif ($self->{units} eq 'MB' && ($capacity - $free) >= $warn_threshold) { - centreon::esxd::common::output_add(\$output_warning, \$output_warning_append, ", ", - "'$dsName' used ".sprintf("%.2f", $usedD)." Go / ".sprintf("%.2f", $sizeD)." Go (".sprintf("%.2f", $pct)." %)"); - $status = centreon::esxd::common::errors_mask($status, 'WARNING'); - } + $self->{manager}->{output}->output_add(long_msg => sprintf("Datastore '%s' Total: %s Used: %s (%.2f%%) Free: %s (%.2f%%)", $name_storage, + $total_size_value . " " . $total_size_unit, + $total_used_value . " " . $total_used_unit, $prct_used, + $total_free_value . " " . $total_free_unit, $prct_free)); + if (!$self->{manager}->{output}->is_status(value => $exit, compare => 'ok', litteral => 1) || $multiple == 0) { + $self->{manager}->{output}->output_add(severity => $exit, + short_msg => sprintf("Datastore '%s' Total: %s Used: %s (%.2f%%) Free: %s (%.2f%%)", $name_storage, + $total_size_value . " " . $total_size_unit, + $total_used_value . " " . $total_used_unit, $prct_used, + $total_free_value . " " . $total_free_unit, $prct_free)); + } - if ($self->{filter} == 1) { - $perfdata .= " 'used_" . $dsName . "'=".($capacity - $free)."o;" . $warn_threshold . ";" . $crit_threshold . ";0;" . $capacity; - } else { - $perfdata .= " used=".($capacity - $free)."o;" . $warn_threshold . ";" . $crit_threshold . ";0;" . $capacity; + my $label = 'used'; + my $value_perf = $total_used; + if (defined($self->{free})) { + $label = 'free'; + $value_perf = $total_free; } - } - - if ($output_unknown ne "") { - $output .= $output_append . "UNKNOWN - $output_unknown"; - $output_append = ". "; - } - if ($output_critical ne "") { - $output .= $output_append . "CRITICAL - Datastore(s): $output_critical"; - $output_append = ". "; - } - if ($output_warning ne "") { - $output .= $output_append . "WARNING - Datastore(s): $output_warning"; - } - if ($status == 0) { - if ($self->{filter} == 1) { - $output .= $output_append . "All Datastore usages are ok"; - } else { - $output .= $output_append . $output_ok_unit; + my $extra_label = ''; + $extra_label = '_' . $name_storage if ($multiple == 1); + my %total_options = (); + if ($self->{units} eq '%') { + $total_options{total} = $total_size; + $total_options{cast_int} = 1; } + $self->{manager}->{output}->perfdata_add(label => $label . $extra_label, unit => 'B', + value => $value_perf, + warning => $self->{manager}->{perfdata}->get_perfdata_for_output(label => 'warning', %total_options), + critical => $self->{manager}->{perfdata}->get_perfdata_for_output(label => 'critical', %total_options), + min => 0, max => $total_size); } - - $self->{obj_esxd}->print_response(centreon::esxd::common::get_status($status) . "|$output|$perfdata\n"); } 1; diff --git a/connectors/vmware/src/centreon/esxd/common.pm b/connectors/vmware/src/centreon/esxd/common.pm index 5ff2ee8ea..93fabc79f 100644 --- a/connectors/vmware/src/centreon/esxd/common.pm +++ b/connectors/vmware/src/centreon/esxd/common.pm @@ -388,18 +388,18 @@ sub performance_errors { } sub is_accessible { - my ($accessible) = @_; + my (%options) = @_; - if ($accessible !~ /^true|1$/) { + if ($options{accessible} !~ /^true|1$/) { return 0; } return 1; } sub is_connected { - my ($connection_state) = @_; + my (%options) = @_; - if ($connection_state !~ /^connected$/i) { + if ($options{state} !~ /^connected$/i) { return 0; } return 1; @@ -415,12 +415,16 @@ sub is_running { } sub datastore_state { - my ($obj_esxd, $ds, $accessible) = @_; + my (%options) = @_; + my $status = defined($options{status}) ? $options{status} : $options{connector}->{centreonesxd_config}->{datastore_state_error}; - if ($accessible !~ /^true|1$/) { - my $output = "Datastore '" . $ds . "' not accessible. Can be disconnected."; - my $status = errors_mask(0, $obj_esxd->{centreonesxd_config}->{datastore_state_error}); - $obj_esxd->print_response(get_status($status) . "|$output\n"); + if ($options{state} !~ /^true|1$/) { + my $output = "Datastore '" . $options{name} . "' not accessible. Current connection state: '$options{state}'."; + if ($options{multiple} == 0 || + !$manager_display->{output}->is_status(value => $status, compare => 'ok', litteral => 1)) { + $manager_display->{output}->output_add(severity => $status, + short_msg => $output); + } return 0; }