WIP (near the end)
This commit is contained in:
Quentin Garnier 2014-10-28 16:04:05 +01:00
parent c7a5416ab2
commit c38671738c
5 changed files with 323 additions and 309 deletions

View File

@ -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 () {

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;
}