From bfb15e4d9372ecc91250019c6fc1f3b6db6ce152 Mon Sep 17 00:00:00 2001 From: Quentin Garnier Date: Wed, 22 Oct 2014 14:57:15 +0200 Subject: [PATCH] Refs #7246 First command with perfdata --- connectors/vmware/centreon_esx_client.pl | 27 +--- .../vmware/src/centreon/esxd/cmdcpuhost.pm | 147 ++++++++++++------ .../vmware/src/centreon/esxd/cmdstatushost.pm | 98 +++++++----- connectors/vmware/src/centreon/esxd/common.pm | 43 ++--- .../vmware/src/centreon/esxd/connector.pm | 4 +- .../src/centreon/script/centreonesxd.pm | 10 +- 6 files changed, 196 insertions(+), 133 deletions(-) diff --git a/connectors/vmware/centreon_esx_client.pl b/connectors/vmware/centreon_esx_client.pl index dc76dca10..ef1646a95 100644 --- a/connectors/vmware/centreon_esx_client.pl +++ b/connectors/vmware/centreon_esx_client.pl @@ -113,16 +113,7 @@ 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 "'healthhost':\n"; - print " -e (--esx-host) Esx Host to check (required)\n"; - print " --storage-status Check storage of ESX\n"; - print "\n"; - print "'maintenancehost':\n"; - print " -e (--esx-host) Esx Host to check (required)\n"; - print "\n"; - print "'statushost':\n"; - print " -e (--esx-host) Esx Host to check (required)\n"; - print "\n"; + print "'datastore-usage':\n"; print " --datastore Datastore name to check (required)\n"; print " -w (--warning) Warning Threshold (default 80)\n"; @@ -248,21 +239,7 @@ sub print_usage () { print " --warn Warn\n"; print " --skip-errors Status OK if vms are disconnected (when you checks multiples)\n"; print "\n"; - print "'listhost':\n"; - print " None\n"; - print "\n"; - print "'listdatastore':\n"; - print " --xml centreon-autodiscovery xml format\n"; - print " --show-attributes centreon-autodiscovery attributes xml display\n"; - print "\n"; - print "'listnichost':\n"; - print " -e (--esx-host) Esx Host to check (required)\n"; - print " --xml centreon-autodiscovery xml format\n"; - print " --show-attributes centreon-autodiscovery attributes xml display\n"; - print "\n"; - print "'getmap':\n"; - print " -e (--esx-host) Esx Host to check\n"; - print "\n"; + print "'stats':\n"; print " -w (--warning) Warning Threshold in total client connections (default none)\n"; print " -c (--critical) Critical Threshold in total client connections (default none)\n"; diff --git a/connectors/vmware/src/centreon/esxd/cmdcpuhost.pm b/connectors/vmware/src/centreon/esxd/cmdcpuhost.pm index dca0a7241..a4907fa6e 100644 --- a/connectors/vmware/src/centreon/esxd/cmdcpuhost.pm +++ b/connectors/vmware/src/centreon/esxd/cmdcpuhost.pm @@ -9,7 +9,6 @@ sub new { my $class = shift; my $self = {}; $self->{logger} = shift; - $self->{obj_esxd} = shift; $self->{commandName} = 'cpuhost'; bless $self, $class; @@ -21,86 +20,132 @@ sub getCommandName { return $self->{commandName}; } -sub checkArgs { - my $self = shift; - my ($host, $warn, $crit, $light_perfdata) = @_; - if (!defined($host) || $host eq "") { - $self->{logger}->writeLogError("ARGS error: need hostname"); +sub checkArgs { + my ($self, %options) = @_; + + if (defined($options{arguments}->{esx_hostname}) && $options{arguments}->{esx_hostname} eq "") { + $options{manager}->{output}->output_add(severity => 'UNKNOWN', + short_msg => "Argument error: esx hostname 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) && $warn > $crit) { - $self->{logger}->writeLogError("ARGS error: warn threshold must be lower than crit threshold"); - return 1; + if (($options{manager}->{perfdata}->threshold_validate(label => 'warning', value => $options{arguments}->{warning})) == 0) { + $options{manager}->{output}->output_add(severity => 'UNKNOWN', + short_msg => "Argument error: wrong value for warning value '" . $options{arguments}->{warning} . "'."); + return 1; + } + if (($options{manager}->{perfdata}->threshold_validate(label => 'critical', value => $options{arguments}->{critical})) == 0) { + $options{manager}->{output}->output_add(severity => 'UNKNOWN', + short_msg => "Argument error: wrong value for critical value '" . $options{arguments}->{critical} . "'."); + return 1; } return 0; } sub initArgs { - my $self = shift; - $self->{lhost} = $_[0]; - $self->{warn} = (defined($_[1]) ? $_[1] : 80); - $self->{crit} = (defined($_[2]) ? $_[2] : 90); - $self->{light_perfdata} = (defined($_[3]) ? $_[3] : 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}; + $self->{manager}->{perfdata}->threshold_validate(label => 'warning', value => $options{arguments}->{warning}); + $self->{manager}->{perfdata}->threshold_validate(label => 'critical', value => $options{arguments}->{critical}); +} + +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"); + $self->{manager}->{output}->output_add(severity => 'UNKNOWN', + short_msg => "Can't retrieve perf counters"); return ; } - my %filters = ('name' => $self->{lhost}); + my %filters = (); + my $multiple = 0; + if (defined($self->{esx_hostname}) && !defined($self->{filter})) { + $filters{name} = qr/^\Q$self->{esx_hostname}\E$/; + } elsif (!defined($self->{esx_hostname})) { + $filters{name} = qr/.*/; + } else { + $filters{name} = qr/$self->{esx_hostname}/; + } + my @properties = ('name', 'runtime.connectionState'); my $result = centreon::esxd::common::get_entities_host($self->{obj_esxd}, 'HostSystem', \%filters, \@properties); return if (!defined($result)); - return if (centreon::esxd::common::host_state($self->{obj_esxd}, $self->{lhost}, - $$result[0]->{'runtime.connectionState'}->val) == 0); - + if (scalar(@$result) > 1) { + $multiple = 1; + } my @instances = ('*'); - my $values = centreon::esxd::common::generic_performance_values_historic($self->{obj_esxd}, - $result, - [{'label' => 'cpu.usage.average', 'instances' => \@instances}], - $self->{obj_esxd}->{perfcounter_speriod}); + $result, + [{'label' => 'cpu.usage.average', 'instances' => \@instances}], + $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 $status = 0; # OK - my $output = ''; - my $total_cpu_average = centreon::esxd::common::simplify_number(centreon::esxd::common::convert_number($values->{$self->{obj_esxd}->{perfcounter_cache}->{'cpu.usage.average'}->{'key'} . ":"}[0] * 0.01)); - - if ($total_cpu_average >= $self->{warn}) { - $status = centreon::esxd::common::errors_mask($status, 'WARNING'); - } - if ($total_cpu_average >= $self->{crit}) { - $status = centreon::esxd::common::errors_mask($status, 'CRITICAL'); - } - $output = "Total Average CPU usage '$total_cpu_average%' on last " . int($self->{obj_esxd}->{perfcounter_speriod} / 60) . "min | cpu_total=$total_cpu_average%;$self->{warn};$self->{crit};0;100"; + if ($multiple == 1) { + $self->{manager}->{output}->output_add(severity => 'OK', + short_msg => sprintf("All Total Average CPU usages are ok")); + } + foreach my $entity_view (@$result) { + next if (centreon::esxd::common::host_state(connector => $self->{obj_esxd}, + hostname => $entity_view->{name}, + state => $entity_view->{'runtime.connectionState'}->val, + status => $self->{disconnect_status}, + multiple => $multiple) == 0); + my $entity_value = $entity_view->{mo_ref}->{value}; + my $total_cpu_average = centreon::esxd::common::simplify_number(centreon::esxd::common::convert_number($values->{$entity_value}->{$self->{obj_esxd}->{perfcounter_cache}->{'cpu.usage.average'}->{'key'} . ":"}[0] * 0.01)); + + my $exit = $self->{manager}->{perfdata}->threshold_check(value => $total_cpu_average, + threshold => [ { label => 'critical', exit_litteral => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]); + + $self->{manager}->{output}->output_add(long_msg => sprintf("'%s' Total Average CPU usage '%s%%' on last %s min", + $entity_view->{name}, $total_cpu_average, int($self->{obj_esxd}->{perfcounter_speriod} / 60))); + 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' Total Average CPU usage '%s%%' on last %s min", + $entity_view->{name}, $total_cpu_average, int($self->{obj_esxd}->{perfcounter_speriod} / 60))); + } - foreach my $id (sort { my ($cida, $cia) = split /:/, $a; - my ($cidb, $cib) = split /:/, $b; - $cia = -1 if (!defined($cia) || $cia eq ""); - $cib = -1 if (!defined($cib) || $cib eq ""); - $cia <=> $cib} keys %$values) { - my ($counter_id, $instance) = split /:/, $id; - if ($instance ne "" and $self->{light_perfdata} != 1) { - $output .= " cpu$instance=" . centreon::esxd::common::simplify_number(centreon::esxd::common::convert_number($values->{$id}[0]) * 0.01) . "%;;0;100"; + my $extra_label = ''; + $extra_label = '_' . $entity_view->{name} if ($multiple == 1); + $self->{manager}->{output}->perfdata_add(label => 'cpu_total' . $extra_label, unit => '%', + value => $total_cpu_average, + warning => $self->{manager}->{perfdata}->get_perfdata_for_output(label => 'warning'), + critical => $self->{manager}->{perfdata}->get_perfdata_for_output(label => 'critical'), + min => 0, max => 100); + + foreach my $id (sort { my ($cida, $cia) = split /:/, $a; + my ($cidb, $cib) = split /:/, $b; + $cia = -1 if (!defined($cia) || $cia eq ""); + $cib = -1 if (!defined($cib) || $cib eq ""); + $cia <=> $cib} keys %{$values->{$entity_value}}) { + my ($counter_id, $instance) = split /:/, $id; + if ($instance ne "") { + $self->{manager}->{output}->perfdata_add(label => 'cpu' . $instance . $extra_label, unit => '%', + value => centreon::esxd::common::simplify_number(centreon::esxd::common::convert_number($values->{$entity_value}->{$id}[0]) * 0.01), + min => 0, max => 100); + } } } - $self->{obj_esxd}->print_response(centreon::esxd::common::get_status($status) . "|$output\n"); } 1; diff --git a/connectors/vmware/src/centreon/esxd/cmdstatushost.pm b/connectors/vmware/src/centreon/esxd/cmdstatushost.pm index 7757110c9..021b2bff6 100644 --- a/connectors/vmware/src/centreon/esxd/cmdstatushost.pm +++ b/connectors/vmware/src/centreon/esxd/cmdstatushost.pm @@ -9,7 +9,6 @@ sub new { my $class = shift; my $self = {}; $self->{logger} = shift; - $self->{obj_esxd} = shift; $self->{commandName} = 'statushost'; bless $self, $class; @@ -22,63 +21,92 @@ sub getCommandName { } sub checkArgs { - my $self = shift; - my ($host) = @_; + my ($self, %options) = @_; - if (!defined($host) || $host eq "") { - $self->{logger}->writeLogError("ARGS error: need hostname"); + if (defined($options{arguments}->{esx_hostname}) && $options{arguments}->{esx_hostname} eq "") { + $options{manager}->{output}->output_add(severity => 'UNKNOWN', + short_msg => "Argument error: esx hostname cannot be null"); + return 1; + } + 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; } return 0; } sub initArgs { - my $self = shift; - $self->{lhost} = $_[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}; +} + +sub set_connector { + my ($self, %options) = @_; + + $self->{obj_esxd} = $options{connector}; } sub run { my $self = shift; - my %filters = ('name' => $self->{lhost}); - my @properties = ('summary.overallStatus', 'runtime.connectionState'); - my $result = centreon::esxd::common::get_entities_host($self->{obj_esxd}, 'HostSystem', \%filters, \@properties); - if (!defined($result)) { - return ; - } + my %filters = (); + my $multiple = 0; - return if (centreon::esxd::common::host_state($self->{obj_esxd}, $self->{lhost}, - $$result[0]->{'runtime.connectionState'}->val) == 0); - - my $status = 0; # OK - my $output = ''; + if (defined($self->{esx_hostname}) && !defined($self->{filter})) { + $filters{name} = qr/^\Q$self->{esx_hostname}\E$/; + } elsif (!defined($self->{esx_hostname})) { + $filters{name} = qr/.*/; + } else { + $filters{name} = qr/$self->{esx_hostname}/; + } + my @properties = ('name', 'summary.overallStatus', 'runtime.connectionState'); + my $result = centreon::esxd::common::get_entities_host($self->{obj_esxd}, 'HostSystem', \%filters, \@properties); + return if (!defined($result)); + if (scalar(@$result) > 1) { + $multiple = 1; + } my %overallStatus = ( - 'gray' => 'status is unknown', - 'green' => 'is OK', - 'red' => 'has a problem', - 'yellow' => 'might have a problem', + 'gray' => 'status is unknown', + 'green' => 'is OK', + 'red' => 'has a problem', + 'yellow' => 'might have a problem', ); my %overallStatusReturn = ( - 'gray' => 'UNKNOWN', - 'green' => 'OK', - 'red' => 'CRITICAL', - 'yellow' => 'WARNING' + 'gray' => 'UNKNOWN', + 'green' => 'OK', + 'red' => 'CRITICAL', + 'yellow' => 'WARNING' ); + if ($multiple == 1) { + $self->{manager}->{output}->output_add(severity => 'OK', + short_msg => sprintf("All ESX are ok")); + } + foreach my $entity_view (@$result) { + next if (centreon::esxd::common::host_state(connector => $self->{obj_esxd}, + hostname => $entity_view->{name}, + state => $entity_view->{'runtime.connectionState'}->val, + status => $self->{disconnect_status}, + multiple => $multiple) == 0); + my $status_esx = $entity_view->{'summary.overallStatus'}->val; - - if (defined($status) && $overallStatus{$status_esx}) { - $output = "The Server '" . $self->{lhost} . "' " . $overallStatus{$status_esx}; - $status = centreon::esxd::common::errors_mask($status, $overallStatusReturn{$status_esx}); - } else { - $output = "Can't interpret data..."; - $status = centreon::esxd::common::errors_mask($status, 'UNKNOWN'); + $self->{manager}->{output}->output_add(long_msg => sprintf("'%s' %s", $entity_view->{name}, $overallStatus{$status_esx})); + + if ($multiple == 0 || + !$self->{manager}->{output}->is_status(value => $overallStatusReturn{$status_esx}, compare => 'ok', litteral => 1)) { + $self->{manager}->{output}->output_add(severity => $overallStatusReturn{$status_esx}, + short_msg => sprintf("'%s' %s", $entity_view->{name}, $overallStatus{$status_esx})); } } - - $self->{obj_esxd}->print_response(centreon::esxd::common::get_status($status) . "|$output\n"); } 1; diff --git a/connectors/vmware/src/centreon/esxd/common.pm b/connectors/vmware/src/centreon/esxd/common.pm index 3db0d33e5..afd589270 100644 --- a/connectors/vmware/src/centreon/esxd/common.pm +++ b/connectors/vmware/src/centreon/esxd/common.pm @@ -171,7 +171,8 @@ sub get_perf_metric_ids { } } else { $obj_esxd->{logger}->writeLogError("Metric '" . $_->{'label'} . "' unavailable."); - $obj_esxd->print_response("-3|Error: Counter doesn't exist. VMware version can be too old.\n"); + $manager_display->{output}->output_add(severity => 'UNKNOWN', + short_msg => "Counter doesn't exist. VMware version can be too old."); return undef; } } @@ -179,7 +180,7 @@ sub get_perf_metric_ids { } sub generic_performance_values_historic { - my ($obj_esxd, $views, $perfs, $interval, $skip_undef_counter, $multiples) = @_; + my ($obj_esxd, $views, $perfs, $interval, %options) = @_; my $counter = 0; my %results; @@ -225,7 +226,7 @@ sub generic_performance_values_historic { } foreach my $val (@$perfdata) { foreach (@{$val->{value}}) { - if (defined($skip_undef_counter) && $skip_undef_counter == 1 && !defined($_->value)) { + if (defined($options{skip_undef_counter}) && $options{skip_undef_counter} == 1 && !defined($_->value)) { $results{$_->id->counterId . ":" . (defined($_->id->instance) ? $_->id->instance : "")} = undef; next; } elsif (!defined($_->value)) { @@ -234,8 +235,13 @@ sub generic_performance_values_historic { return undef; } - if (defined($multiples) && $multiples == 1) { - $results{$val->{entity}->{value} . ":" . $_->id->counterId . ":" . (defined($_->id->instance) ? $_->id->instance : "")} = $_->value; + if (defined($options{multiples}) && $options{multiples} == 1) { + if (defined($options{multiples_result_by_entity}) && $options{multiples_result_by_entity} == 1) { + $results{$val->{entity}->{value}} = {} if (!defined($results{$val->{entity}->{value}})); + $results{$val->{entity}->{value}}->{$_->id->counterId . ":" . (defined($_->id->instance) ? $_->id->instance : "")} = $_->value; + } else { + $results{$val->{entity}->{value} . ":" . $_->id->counterId . ":" . (defined($_->id->instance) ? $_->id->instance : "")} = $_->value; + } } else { $results{$_->id->counterId . ":" . (defined($_->id->instance) ? $_->id->instance : "")} = $_->value; } @@ -402,21 +408,20 @@ sub host_state { } sub stats_info { - my ($obj_esxd, $rh, $current_fileno, $args) = @_; - my $output; - my $status = 0; - - $$args[0] ='' if (!defined($$args[0])); - $$args[1] = '' if (!defined($$args[1])); - - my $num_connection = scalar(keys(%{$obj_esxd->{sockets}})); - $output = "'$num_connection' total client connections | connection=$num_connection;$$args[0];$$args[1];0; requests=" . $obj_esxd->{counter}; - if ($$args[1] ne '' and $num_connection >= $$args[1]) { - $status = errors_mask($status, 'CRITICAL'); - } elsif ($$args[0] ne '' and $num_connection >= $$args[0]) { - $status = errors_mask($status, 'WARNING'); + my (%options) = @_; + + my $total = 0; + foreach my $container (keys %{$options{counters}}) { + $total += $options{counters}->{$container}; + $options{manager}->{output}->perfdata_add(label => 'c[requests_' . $container . ']', + value => $options{counters}->{$container}, + min => 0); } - #response_client1($obj_esxd, $rh, $current_fileno, get_status($status) . "|$output\n"); + $options{manager}->{output}->perfdata_add(label => 'c[requests]', + value => $total, + min => 0); + $options{manager}->{output}->output_add(severity => 'OK', + short_msg => sprintf("'%s' total requests", $total)); } 1; diff --git a/connectors/vmware/src/centreon/esxd/connector.pm b/connectors/vmware/src/centreon/esxd/connector.pm index 85456ed7c..d429ef04b 100644 --- a/connectors/vmware/src/centreon/esxd/connector.pm +++ b/connectors/vmware/src/centreon/esxd/connector.pm @@ -97,7 +97,7 @@ sub handle_CHLD { my $child_pid; while (($child_pid = waitpid(-1, &WNOHANG)) > 0) { - $self->{return_child}{$child_pid} = {status => 1, rtime => time()}; + $self->{return_child}->{$child_pid} = {status => 1, rtime => time()}; } $SIG{CHLD} = \&class_handle_CHLD; } @@ -120,7 +120,7 @@ sub verify_child { foreach (keys %{$self->{child_proc}}) { # Check ctime if (defined($self->{return_child}->{$self->{child_proc}->{$_}->{pid}})) { - delete $self->{return_child}->{$_}; + delete $self->{return_child}->{$self->{child_proc}->{$_}->{pid}}; delete $self->{child_proc}->{$_}; } elsif (time() - $self->{child_proc}->{$_}->{ctime} > $self->{config_child_timeout}) { $self->response_router(severity => 'UNKNOWN', msg => 'Timeout process', diff --git a/connectors/vmware/src/centreon/script/centreonesxd.pm b/connectors/vmware/src/centreon/script/centreonesxd.pm index 329e5a85e..491e61759 100644 --- a/connectors/vmware/src/centreon/script/centreonesxd.pm +++ b/connectors/vmware/src/centreon/script/centreonesxd.pm @@ -93,7 +93,7 @@ sub new { $self->{return_child} = {}; $self->{stop} = 0; $self->{childs_vpshere_pid} = {}; - $self->{counter} = 0; + $self->{counter_stats} = {}; $self->{whoaim} = undef; # to know which vsphere to connect $self->{module_date_parse_loaded} = 0; $self->{modules_registry} = {}; @@ -272,6 +272,12 @@ sub request { centreon::esxd::common::response(token => 'RESPSERVER', endpoint => $frontend, identity => $options{identity}); return ; } + if ($result->{command} eq 'stats') { + centreon::esxd::common::stats_info(manager => $options{manager}, + counters => $self->{counter_stats}); + centreon::esxd::common::response(token => 'RESPSERVER', endpoint => $frontend, identity => $options{identity}); + return ; + } if (!defined($self->{modules_registry}->{$result->{command}})) { $options{manager}->{output}->output_add(severity => 'UNKNOWN', short_msg => "Unknown method name '$result->{command}'"); @@ -290,6 +296,7 @@ sub request { return ; } + $self->{counter_stats}->{$result->{container}}++; my $flag = ZMQ_NOBLOCK | ZMQ_SNDMORE; zmq_sendmsg($frontend, "server-" . $result->{container}, $flag); zmq_sendmsg($frontend, 'REQCLIENT ' . $options{data}, ZMQ_NOBLOCK); @@ -384,6 +391,7 @@ sub run { } foreach (keys %{$centreonesxd->{centreonesxd_config}->{vsphere_server}}) { + $centreonesxd->{counter_stats}->{$_} = 0; $centreonesxd->create_vsphere_child(vsphere_name => $_); }