diff --git a/apps/biztalk/sql/mode/rlocationdisabled.pm b/apps/biztalk/sql/mode/rlocationdisabled.pm new file mode 100644 index 000000000..12d10e16a --- /dev/null +++ b/apps/biztalk/sql/mode/rlocationdisabled.pm @@ -0,0 +1,132 @@ +# +# Copyright 2015 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +package apps::biztalk::sql::mode::rlocationdisabled; + +use base qw(centreon::plugins::mode); + +use strict; +use warnings; + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => + { + "warning:s" => { name => 'warning' }, + "critical:s" => { name => 'critical' }, + "filter-location:s" => { name => 'filter_location' }, + "filter-application:s" => { name => 'filter_application' }, + }); + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::init(%options); + + if (($self->{perfdata}->threshold_validate(label => 'warning', value => $self->{option_results}->{warning})) == 0) { + $self->{output}->add_option_msg(short_msg => "Wrong warning threshold '" . $self->{option_results}->{warning} . "'."); + $self->{output}->option_exit(); + } + if (($self->{perfdata}->threshold_validate(label => 'critical', value => $self->{option_results}->{critical})) == 0) { + $self->{output}->add_option_msg(short_msg => "Wrong critical threshold '" . $self->{option_results}->{critical}. "'."); + $self->{output}->option_exit(); + } +} + +sub run { + my ($self, %options) = @_; + # $options{sql} = sqlmode object + $self->{sql} = $options{sql}; + + my $query = q{ + SELECT RL.Name, RL.Disabled, APP.nvcName + FROM BizTalkMgmtDb.dbo.adm_ReceiveLocation AS RL WITH(NOLOCK) + INNER JOIN BizTalkMgmtDb.dbo.bts_receiveport AS RP WITH(NOLOCK) + ON RL.ReceivePortId = RP.nID + INNER JOIN BizTalkMgmtDb.dbo.bts_application AS APP WITH(NOLOCK) + ON RP.nApplicationID = APP.nID WHERE RL.[Disabled] = -1 + }; + $self->{sql}->connect(); + $self->{sql}->query(query => $query); + + my $count = 0; + while ((my $row = $self->{sql}->fetchrow_hashref())) { + if (defined($self->{option_results}->{filter_location}) && $self->{option_results}->{filter_location} ne '' && + $row->{Name} !~ /$self->{option_results}->{filter_location}/) { + $self->{output}->output_add(long_msg => "Skipping '" . $row->{Name} . "': no matching filter location.", debug => 1); + next; + } + if (defined($self->{option_results}->{filter_application}) && $self->{option_results}->{filter_application} ne '' && + $row->{nvcName} !~ /$self->{option_results}->{filter_application}/) { + $self->{output}->output_add(long_msg => "Skipping '" . $row->{nvcName} . "': no matching filter application.", debug => 1); + next; + } + $self->{output}->output_add(long_msg => "'" . $row->{Name} . "' of application '" . $row->{nvcName} . "'"); + $count++; + } + + my $exit = $self->{perfdata}->threshold_check(value => $count, threshold => [ { label => 'critical', exit_litteral => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]); + $self->{output}->output_add(severity => $exit, + short_msg => sprintf("%d receive locations are disabled", $count)); + $self->{output}->perfdata_add(label => 'count', + value => $count, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning'), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical'), + min => 0); + + $self->{output}->display(); + $self->{output}->exit(); +} + +1; + +__END__ + +=head1 MODE + +Check the number of biztalk received locations disabled. +The mode should be used with mssql plugin and dyn-mode option. + +=over 8 + +=item B<--warning> + +Threshold warning. + +=item B<--critical> + +Threshold critical. + +=item B<--filter-location> + +Filter by location (regexp can be used). + +=item B<--filter-application> + +Filter by application (regexp can be used). + +=back + +=cut diff --git a/apps/centreon/map/jmx/mode/eventqueue.pm b/apps/centreon/map/jmx/mode/eventqueue.pm index ecab5277e..9cd6a8e00 100644 --- a/apps/centreon/map/jmx/mode/eventqueue.pm +++ b/apps/centreon/map/jmx/mode/eventqueue.pm @@ -59,20 +59,20 @@ sub run { $self->{connector} = $options{custom}; $self->{request} = [ - { mbean => "com.merethis.studio:name=statistics,type=session" } + { mbean => "com.centreon.studio:name=statistics,type=session" } ]; my $result = $self->{connector}->get_attributes(request => $self->{request}, nothing_quit => 0); - my $exit = $self->{perfdata}->threshold_check(value => $result->{"com.merethis.studio:name=statistics,type=session"}->{AverageEventQueueSize}, + my $exit = $self->{perfdata}->threshold_check(value => $result->{"com.centreon.studio:name=statistics,type=session"}->{AverageEventQueueSize}, threshold => [ { label => 'critical', exit_litteral => 'critical' }, { label => 'warning', exit_litteral => 'warning'} ]); $self->{output}->output_add(severity => $exit, short_msg => sprintf("Average event queue size : %d", - $result->{"com.merethis.studio:name=statistics,type=session"}->{AverageEventQueueSize})); + $result->{"com.centreon.studio:name=statistics,type=session"}->{AverageEventQueueSize})); $self->{output}->perfdata_add(label => 'events', - value => $result->{"com.merethis.studio:name=statistics,type=session"}->{AverageEventQueueSize}, + value => $result->{"com.centreon.studio:name=statistics,type=session"}->{AverageEventQueueSize}, warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning'), critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical'), min => 0); diff --git a/apps/centreon/map/jmx/mode/eventstatistics.pm b/apps/centreon/map/jmx/mode/eventstatistics.pm index 80ce73119..494fb186d 100644 --- a/apps/centreon/map/jmx/mode/eventstatistics.pm +++ b/apps/centreon/map/jmx/mode/eventstatistics.pm @@ -78,7 +78,7 @@ sub run { $self->{connector} = $options{custom}; $self->{request} = [ - { mbean => "com.merethis.studio:name=statistics,type=whatsup" } + { mbean => "com.centreon.studio.map:name=statistics,type=whatsup" } ]; my $result = $self->{connector}->get_attributes(request => $self->{request}, nothing_quit => 0); @@ -94,10 +94,10 @@ sub run { } foreach my $type ('EventCount', 'EventTypeCreate', 'EventTypeUpdate', 'EventTypeRemove') { - $new_datas->{$type} = $result->{"com.merethis.studio:name=statistics,type=whatsup"}->{$type}->{andIncrement}; + $new_datas->{$type} = $result->{"com.centreon.studio.map:name=statistics,type=whatsup"}->{$type}->{andIncrement}; my $old_val = $self->{statefile_cache}->get(name => $type); - next if (!defined($old_val) || $result->{"com.merethis.studio:name=statistics,type=whatsup"}->{$type}->{andIncrement} < $old_val); - my $value = int(($result->{"com.merethis.studio:name=statistics,type=whatsup"}->{$type}->{andIncrement} - $old_val) / ($new_datas->{last_timestamp} - $old_timestamp)); + next if (!defined($old_val) || $result->{"com.centreon.studio.map:name=statistics,type=whatsup"}->{$type}->{andIncrement} < $old_val); + my $value = int(($result->{"com.centreon.studio.map:name=statistics,type=whatsup"}->{$type}->{andIncrement} - $old_val) / ($new_datas->{last_timestamp} - $old_timestamp)); $self->{output}->perfdata_add(label => $type, value => $value, diff --git a/apps/centreon/map/jmx/mode/gates.pm b/apps/centreon/map/jmx/mode/gates.pm index f9346482b..27d855c15 100644 --- a/apps/centreon/map/jmx/mode/gates.pm +++ b/apps/centreon/map/jmx/mode/gates.pm @@ -59,22 +59,22 @@ sub run { $self->{connector} = $options{custom}; $self->{request} = [ - { mbean => "com.merethis.map:name=BusinessGate,type=repo" } + { mbean => "com.centreon.studio.map:name=BusinessGate,type=repo" } ]; my $result = $self->{connector}->get_attributes(request => $self->{request}, nothing_quit => 1); - my $gates = $result->{"com.merethis.map:name=BusinessGate,type=repo"}->{LoadedModelCount}; + my $gates = $result->{"com.centreon.studio.map:name=BusinessGate,type=repo"}->{LoadedModelCount}; my $exit = $self->{perfdata}->threshold_check(value => $gates, threshold => [ { label => 'critical', exit_litteral => 'critical' }, { label => 'warning', exit_litteral => 'warning'} ]); $self->{output}->output_add(severity => $exit, short_msg => sprintf("Business gates opened : %d", - $result->{"com.merethis.map:name=BusinessGate,type=repo"}->{LoadedModelCount})); + $result->{"com.centreon.studio.map:name=BusinessGate,type=repo"}->{LoadedModelCount})); $self->{output}->perfdata_add(label => 'gates', - value => $result->{"com.merethis.map:name=BusinessGate,type=repo"}->{LoadedModelCount}, + value => $result->{"com.centreon.studio.map:name=BusinessGate,type=repo"}->{LoadedModelCount}, warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning'), critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical'), min => 0); diff --git a/apps/centreon/map/jmx/mode/sessions.pm b/apps/centreon/map/jmx/mode/sessions.pm index 70749bb51..443bde899 100644 --- a/apps/centreon/map/jmx/mode/sessions.pm +++ b/apps/centreon/map/jmx/mode/sessions.pm @@ -59,20 +59,20 @@ sub run { $self->{connector} = $options{custom}; $self->{request} = [ - { mbean => "com.merethis.studio:name=statistics,type=session" } + { mbean => "com.centreon.studio:name=statistics,type=session" } ]; my $result = $self->{connector}->get_attributes(request => $self->{request}, nothing_quit => 0); - my $exit = $self->{perfdata}->threshold_check(value => $result->{"com.merethis.studio:name=statistics,type=session"}->{SessionCount}, + my $exit = $self->{perfdata}->threshold_check(value => $result->{"com.centreon.studio:name=statistics,type=session"}->{SessionCount}, threshold => [ { label => 'critical', exit_litteral => 'critical' }, { label => 'warning', exit_litteral => 'warning'} ]); $self->{output}->output_add(severity => $exit, short_msg => sprintf("Current sessions : %d", - $result->{"com.merethis.studio:name=statistics,type=session"}->{SessionCount})); + $result->{"com.centreon.studio:name=statistics,type=session"}->{SessionCount})); $self->{output}->perfdata_add(label => 'sessions', - value => $result->{"com.merethis.studio:name=statistics,type=session"}->{SessionCount}, + value => $result->{"com.centreon.studio:name=statistics,type=session"}->{SessionCount}, warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning'), critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical'), min => 0); diff --git a/apps/protocols/bgp/4/mode/bgppeerstate.pm b/apps/protocols/bgp/4/mode/bgppeerstate.pm index 4c5604953..1cbbe37ec 100644 --- a/apps/protocols/bgp/4/mode/bgppeerstate.pm +++ b/apps/protocols/bgp/4/mode/bgppeerstate.pm @@ -50,29 +50,6 @@ my $thresholds = { ], }; -sub get_severity { - my ($self, %options) = @_; - my $status = 'UNKNOWN'; # default - - if (defined($self->{overload_th}->{$options{section}})) { - foreach (@{$self->{overload_th}->{$options{section}}}) { - if ($options{value} =~ /$_->{filter}/i) { - $status = $_->{status}; - return $status; - } - } - } - foreach (@{$thresholds->{$options{section}}}) { - if ($options{value} =~ /$$_[0]/i) { - $status = $$_[1]; - return $status; - } - } - - return $status; -} - - sub new { my ($class, %options) = @_; my $self = $class->SUPER::new(package => __PACKAGE__, %options); @@ -127,8 +104,7 @@ sub run { my $result = $self->{snmp}->get_table(oid => $oid_bgpPeerTable, nothing_quit => 1); - if (defined $self->{option_results}->{peer}) { - + if (defined($self->{option_results}->{peer})) { my $bgpPeerState = $result->{$oid_bgpPeerState . '.' . $self->{option_results}->{peer}}; my $bgpPeerAdminStatus = $result->{$oid_bgpPeerAdminStatus . '.' . $self->{option_results}->{peer}}; my $bgpPeerRemoteAs = $result->{$oid_bgpPeerRemoteAs . '.' . $self->{option_results}->{peer}}; @@ -136,29 +112,28 @@ sub run { my $bgpLocalInfos = $result->{$oid_bgpPeerLocalAddr . '.' . $self->{option_results}->{peer}} . ':' . $result->{$oid_bgpPeerLocalPort . '.' . $self->{option_results}->{peer}}; my $bgpRemoteInfos = $result->{$oid_bgpPeerRemoteAddr. '.' . $self->{option_results}->{peer}} . ':' . $result->{$oid_bgpPeerRemotePort . '.' . $self->{option_results}->{peer}}; - $self->{output}->output_add(severity => 'OK', - short_msg => sprintf("Peer %s AdminState=%s Connection=%s [Remote Addr:%s AS:%d] [Last Update %d s]", $self->{option_results}->{peer}, $map_admin_state{$bgpPeerAdminStatus}, $map_peer_state{$bgpPeerState} , $bgpRemoteInfos, $bgpPeerRemoteAs, $bgpPeerInUpdateElpasedTime)); - + short_msg => sprintf("Peer %s AdminState=%s Connection=%s [Remote Addr:%s AS:%d] [Last Update %d s]", + $self->{option_results}->{peer}, $map_admin_state{$bgpPeerAdminStatus}, $map_peer_state{$bgpPeerState}, + $bgpRemoteInfos, $bgpPeerRemoteAs, $bgpPeerInUpdateElpasedTime)); if ($bgpPeerAdminStatus < 2) { $self->{output}->output_add(severity => 'CRITICAL', short_msg => sprintf("Peer '%s' AdminState is '%s' Remote AS: %s Remote Addr: %s", $self->{option_results}->{peer}, $map_admin_state{$bgpPeerAdminStatus}, $bgpPeerRemoteAs, $bgpRemoteInfos) ); - } elsif ($bgpPeerState != 6) { + } else { my $exit = $self->get_severity(section => 'peers', value => $map_peer_state{$bgpPeerState}); - $self->{output}->output_add(severity => $exit, - short_msg => sprintf("Peer %s AdminState=%s Connection=%s [Remote Addr:%s AS:%d] [Last Update %d s]", $self->{option_results}->{peer}, $map_admin_state{$bgpPeerAdminStatus}, $map_peer_state{$bgpPeerState}, $bgpRemoteInfos, $bgpPeerRemoteAs, $bgpPeerInUpdateElpasedTime)); - - } - + if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { + $self->{output}->output_add(severity => $exit, + short_msg => sprintf("Peer %s AdminState=%s Connection=%s [Remote Addr:%s AS:%d] [Last Update %d s]", + $self->{option_results}->{peer}, $map_admin_state{$bgpPeerAdminStatus}, $map_peer_state{$bgpPeerState}, $bgpRemoteInfos, $bgpPeerRemoteAs, $bgpPeerInUpdateElpasedTime)); + } + } } else { - $self->{output}->output_add(severity => 'OK', short_msg => sprintf("All BGP peers are in an OK state")); foreach my $key ($self->{snmp}->oid_lex_sort(keys %$result)) { - next if ($key !~ /^$oid_bgpPeerState\.(.*)$/); my $instance = $1; next if ($instance eq '0.0.0.0'); @@ -171,28 +146,50 @@ sub run { my $bgpRemoteInfos = $result->{$oid_bgpPeerRemoteAddr. '.' . $instance} . ':' . $result->{$oid_bgpPeerRemotePort . '.' . $instance}; if ($bgpPeerAdminStatus < 2) { - $self->{output}->output_add(severity => 'CRITICAL', - short_msg => sprintf("Peer '%s' AdminState is '%s' Remote AS: %s Remote Addr: %s \n", + $self->{output}->output_add(severity => 'CRITICAL', + short_msg => sprintf("Peer '%s' AdminState is '%s' Remote AS: %s Remote Addr: %s", $instance, $map_admin_state{$bgpPeerAdminStatus}, $bgpPeerRemoteAs, - $bgpRemoteInfos)); - } elsif ($bgpPeerState != 6) { + $bgpRemoteInfos)); + } else { my $exit = $self->get_severity(section => 'peers', value => $map_peer_state{$bgpPeerState}); - $self->{output}->output_add(severity => $exit, - short_msg => sprintf("Peer %s AdminState=%s Connection=%s [Remote Addr:%s AS:%d] [Last Update %d s] \n", $instance, $map_admin_state{$bgpPeerAdminStatus}, $map_peer_state{$bgpPeerState}, $bgpRemoteInfos, $bgpPeerRemoteAs, $bgpPeerInUpdateElpasedTime)); - + if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { + $self->{output}->output_add(severity => $exit, + short_msg => sprintf("Peer %s AdminState=%s Connection=%s [Remote Addr:%s AS:%d] [Last Update %d s]", + $instance, $map_admin_state{$bgpPeerAdminStatus}, $map_peer_state{$bgpPeerState}, $bgpRemoteInfos, $bgpPeerRemoteAs, $bgpPeerInUpdateElpasedTime)); + } } - $self->{output}->output_add(long_msg => sprintf("Peer:%s Local:%s Remote:%s AS:%d AdminState:'%s' Connection:'%s' Last Update:%d sec \n", $instance, $bgpLocalInfos, $bgpRemoteInfos, $bgpPeerRemoteAs, $map_admin_state{$bgpPeerAdminStatus}, $map_peer_state{$bgpPeerState}, $bgpPeerInUpdateElpasedTime)); - - + $self->{output}->output_add(long_msg => sprintf("Peer:%s Local:%s Remote:%s AS:%d AdminState:'%s' Connection:'%s' Last Update:%d sec", + $instance, $bgpLocalInfos, $bgpRemoteInfos, $bgpPeerRemoteAs, $map_admin_state{$bgpPeerAdminStatus}, $map_peer_state{$bgpPeerState}, $bgpPeerInUpdateElpasedTime)); } - } $self->{output}->display(); $self->{output}->exit(); } +sub get_severity { + my ($self, %options) = @_; + my $status = 'UNKNOWN'; # default + + if (defined($self->{overload_th}->{$options{section}})) { + foreach (@{$self->{overload_th}->{$options{section}}}) { + if ($options{value} =~ /$_->{filter}/i) { + $status = $_->{status}; + return $status; + } + } + } + foreach (@{$thresholds->{$options{section}}}) { + if ($options{value} =~ /$$_[0]/i) { + $status = $$_[1]; + return $status; + } + } + + return $status; +} + 1; __END__ diff --git a/apps/protocols/ldap/mode/search.pm b/apps/protocols/ldap/mode/search.pm index a295d65d2..fbbcc94b7 100644 --- a/apps/protocols/ldap/mode/search.pm +++ b/apps/protocols/ldap/mode/search.pm @@ -98,8 +98,12 @@ sub run { $self->{output}->perfdata_add(label => "time", unit => 's', value => sprintf('%.3f', $timeelapsed), + min => 0); + $self->{output}->perfdata_add(label => "entries", + value => $num_entries, warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning'), - critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical')); + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical'), + min => 0); $self->{output}->display(); $self->{output}->exit(); diff --git a/apps/protocols/ntp/mode/offset.pm b/apps/protocols/ntp/mode/offset.pm new file mode 100644 index 000000000..6314e96b2 --- /dev/null +++ b/apps/protocols/ntp/mode/offset.pm @@ -0,0 +1,129 @@ +# +# Copyright 2015 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +package apps::protocols::ntp::mode::offset; + +use base qw(centreon::plugins::mode); + +use strict; +use warnings; +use Net::NTP; + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => + { + "ntp-host:s" => { name => 'ntp_host' }, + "port:s" => { name => 'port', default => 123 }, + "warning:s" => { name => 'warning' }, + "critical:s" => { name => 'critical' }, + "timeout:s" => { name => 'timeout', default => 30 }, + }); + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::init(%options); + + if (($self->{perfdata}->threshold_validate(label => 'warning', value => $self->{option_results}->{warning})) == 0) { + $self->{output}->add_option_msg(short_msg => "Wrong warning threshold '" . $self->{option_results}->{warning} . "'."); + $self->{output}->option_exit(); + } + if (($self->{perfdata}->threshold_validate(label => 'critical', value => $self->{option_results}->{critical})) == 0) { + $self->{output}->add_option_msg(short_msg => "Wrong critical threshold '" . $self->{option_results}->{critical} . "'."); + $self->{output}->option_exit(); + } + if (!defined($self->{option_results}->{ntp_host})) { + $self->{output}->add_option_msg(short_msg => "Please set the ntp-host option"); + $self->{output}->option_exit(); + } +} + +sub run { + my ($self, %options) = @_; + + my %ntp; + eval { + $Net::NTP::TIMEOUT = $self->{option_results}->{timeout}; + %ntp = get_ntp_response($self->{option_results}->{ntp_host}, $self->{option_results}->{port}); + }; + if ($@) { + $self->{output}->output_add(severity => 'CRITICAL', + short_msg => "Couldn't connect to ntp server: " . $@); + $self->{output}->display(); + $self->{output}->exit(); + } + + my $localtime = time(); + my $offset = ($ntp{'Receive Timestamp'} - $ntp{'Originate Timestamp'}) + ($ntp{'Transmit Timestamp'} - $localtime) / 2); + + my $exit = $self->{perfdata}->threshold_check(value => $offset, + threshold => [ { label => 'critical', exit_litteral => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]); + $self->{output}->output_add(severity => $exit, + short_msg => sprintf("Offset: %.3fs", $offset)); + $self->{output}->output_add(long_msg => sprintf("Host has an offset of %.5fs with its time server reference %s", $offset, $self->{option_results}->{ntp_host})); + + $self->{output}->perfdata_add(label => "time", unit => 's', + value => sprintf('%.3f', $offset), + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning'), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical')); + + $self->{output}->display(); + $self->{output}->exit(); +} + +1; + +__END__ + +=head1 MODE + +Check Ntp server response. + +=over 8 + +=item B<--ntp-host> + +Ntp server address or FQDN + +=item B<--port> + +Port used (Default: 123) + +=item B<--timeout> + +Threshold for NTP timeout + +=item B<--warning> + +Threshold warning in seconds + +=item B<--critical> + +Threshold critical in seconds (e.g @10:10 means CRITICAL if offset is not between -10 and +10 seconds) + +=back + +=cut diff --git a/apps/protocols/ntp/plugin.pm b/apps/protocols/ntp/plugin.pm index 9147f005e..650aff220 100644 --- a/apps/protocols/ntp/plugin.pm +++ b/apps/protocols/ntp/plugin.pm @@ -32,7 +32,8 @@ sub new { $self->{version} = '0.1'; %{$self->{modes}} = ( - 'response-time' => 'apps::protocols::ntp::mode::responsetime', + 'response-time' => 'apps::protocols::ntp::mode::responsetime', + 'offset' => 'apps::protocols::ntp::mode::offset', ); return $self; diff --git a/apps/protocols/x509/mode/validity.pm b/apps/protocols/x509/mode/validity.pm index c4c124ebb..754aa220e 100644 --- a/apps/protocols/x509/mode/validity.pm +++ b/apps/protocols/x509/mode/validity.pm @@ -208,11 +208,11 @@ Threshold warning in days (Days before expiration, eg: '60:' for 60 days before) Threshold critical in days (Days before expiration, eg: '30:' for 30 days before) -=item B<--subject> +=item B<--subjectname> Subject Name pattern -=item B<--issuer> +=item B<--issuername> Issuer Name pattern diff --git a/apps/vmware/connector/custom/connector.pm b/apps/vmware/connector/custom/connector.pm index 4b560ad06..fb9dde9d2 100644 --- a/apps/vmware/connector/custom/connector.pm +++ b/apps/vmware/connector/custom/connector.pm @@ -54,7 +54,9 @@ sub new { "vsphere-username:s@" => { name => 'vsphere_username' }, "vsphere-password:s@" => { name => 'vsphere_password' }, "container:s@" => { name => 'container' }, - "timeout:s@" => { name => 'timeout' }, + "timeout:s@" => { name => 'timeout' }, + "sampling-period:s@" => { name => 'sampling_period' }, + "time-shift:s@" => { name => 'time_shift' }, }); } $options{options}->add_help(package => __PACKAGE__, sections => 'CONNECTOR OPTIONS', once => 1); @@ -105,7 +107,9 @@ sub check_options { $self->{vsphere_address} = (defined($self->{option_results}->{vsphere_address})) ? shift(@{$self->{option_results}->{vsphere_address}}) : undef; $self->{vsphere_username} = (defined($self->{option_results}->{vsphere_username})) ? shift(@{$self->{option_results}->{vsphere_username}}) : undef; $self->{vsphere_password} = (defined($self->{option_results}->{vsphere_password})) ? shift(@{$self->{option_results}->{vsphere_password}}) : undef; - + $self->{sampling_period} = (defined($self->{option_results}->{sampling_period})) ? shift(@{$self->{option_results}->{sampling_period}}) : undef; + $self->{time_shift} = (defined($self->{option_results}->{sampling_period})) ? shift(@{$self->{option_results}->{time_shift}}) : 0; + $self->{connector_port} = 5700 if ($self->{connector_port} eq ''); $self->{container} = 'default' if ($self->{container} eq ''); if (!defined($self->{connector_hostname}) || $self->{connector_hostname} eq '') { @@ -198,6 +202,8 @@ sub run { $self->{json_send}->{vsphere_address} = $self->{vsphere_address}; $self->{json_send}->{vsphere_username} = $self->{vsphere_username}; $self->{json_send}->{vsphere_password} = $self->{vsphere_password}; + $self->{json_send}->{sampling_period} = $self->{sampling_period}; + $self->{json_send}->{time_shift} = $self->{time_shift}; # Init my $context = zmq_init(); @@ -288,6 +294,15 @@ Password of vpshere/ESX connection (with --vsphere-address). Set global execution timeout (Default: 50) +=item B<--sampling-period> + +Choose the sampling period (can change the default sampling for counters). +Should be not different than 300 or 20. + +=item B<--time-shift> + +Can shift the time. We the following option you can average X counters values (default: 0). + =back =head1 DESCRIPTION diff --git a/centreon/common/airespace/snmp/mode/apstatus.pm b/centreon/common/airespace/snmp/mode/apstatus.pm index 53f421367..c3e230234 100644 --- a/centreon/common/airespace/snmp/mode/apstatus.pm +++ b/centreon/common/airespace/snmp/mode/apstatus.pm @@ -161,7 +161,7 @@ sub run { $self->manage_selection(); my $multiple = 1; - if (scalar(keys %{$self->{ap_selected}}) == 1) { + if (scalar(keys %{$self->{ap_selected}}) <= 1) { $multiple = 0; } @@ -234,15 +234,19 @@ my $mapping3 = { bsnAPAdminStatus => { oid => '.1.3.6.1.4.1.14179.2.2.1.1.37', map => \%map_admin_status }, }; +my $oid_agentInventoryMachineModel = '.1.3.6.1.4.1.14179.1.1.1.3'; + sub manage_selection { my ($self, %options) = @_; $self->{ap_selected} = {}; - $self->{results} = $self->{snmp}->get_multiple_table(oids => [ { oid => $mapping->{bsnAPName}->{oid} }, + $self->{results} = $self->{snmp}->get_multiple_table(oids => [ { oid => $oid_agentInventoryMachineModel }, + { oid => $mapping->{bsnAPName}->{oid} }, { oid => $mapping2->{bsnAPOperationStatus}->{oid} }, { oid => $mapping3->{bsnAPAdminStatus}->{oid} }, ], nothing_quit => 1); + $self->{output}->output_add(long_msg => "Model: " . $self->{results}->{$oid_agentInventoryMachineModel}->{$oid_agentInventoryMachineModel . '.0'}); foreach my $oid (keys %{$self->{results}->{ $mapping->{bsnAPName}->{oid} }}) { $oid =~ /^$mapping->{bsnAPName}->{oid}\.(.*)$/; my $instance = $1; @@ -251,7 +255,7 @@ sub manage_selection { my $result3 = $self->{snmp}->map_instance(mapping => $mapping3, results => $self->{results}->{ $mapping3->{bsnAPAdminStatus}->{oid} }, instance => $instance); if (defined($self->{option_results}->{filter_name}) && $self->{option_results}->{filter_name} ne '' && $result->{bsnAPName} !~ /$self->{option_results}->{filter_name}/) { - $self->{output}->output_add(long_msg => "Skipping '" . $result->{bsnAPName} . "': no matching filter."); + $self->{output}->output_add(long_msg => "Skipping '" . $result->{bsnAPName} . "': no matching filter.", debug => 1); next; } @@ -260,8 +264,8 @@ sub manage_selection { } if (scalar(keys %{$self->{ap_selected}}) <= 0) { - $self->{output}->add_option_msg(short_msg => "No entry found."); - $self->{output}->option_exit(); + $self->{output}->output_add(severity => 'OK', + short_msg => 'No AP associated (can be: slave wireless controller or your filter)'); } } diff --git a/centreon/common/airespace/snmp/mode/apusers.pm b/centreon/common/airespace/snmp/mode/apusers.pm index b7ec0e16e..63834926b 100644 --- a/centreon/common/airespace/snmp/mode/apusers.pm +++ b/centreon/common/airespace/snmp/mode/apusers.pm @@ -221,16 +221,20 @@ my $mapping2 = { bsnMobileStationSsid => { oid => '.1.3.6.1.4.1.14179.2.1.4.1.7' }, }; +my $oid_agentInventoryMachineModel = '.1.3.6.1.4.1.14179.1.1.1.3'; + sub manage_selection { my ($self, %options) = @_; $self->{global} = { total => 0, total_idle => 0, total_aaapending => 0, total_authenticated => 0, total_associated => 0, total_powersave => 0, total_disassociated => 0, total_tobedeleted => 0, total_probing => 0, total_blacklisted => 0}; - $self->{results} = $self->{snmp}->get_multiple_table(oids => [ { oid => $mapping->{bsnMobileStationStatus}->{oid} }, + $self->{results} = $self->{snmp}->get_multiple_table(oids => [ { oid => $oid_agentInventoryMachineModel }, + { oid => $mapping->{bsnMobileStationStatus}->{oid} }, { oid => $mapping2->{bsnMobileStationSsid}->{oid} }, ], nothing_quit => 1); + $self->{output}->output_add(long_msg => "Model: " . $self->{results}->{$oid_agentInventoryMachineModel}->{$oid_agentInventoryMachineModel . '.0'}); foreach my $oid (keys %{$self->{results}->{ $mapping->{bsnMobileStationStatus}->{oid} }}) { $oid =~ /^$mapping->{bsnMobileStationStatus}->{oid}\.(.*)$/; my $instance = $1; diff --git a/centreon/common/aruba/snmp/mode/apconnections.pm b/centreon/common/aruba/snmp/mode/apconnections.pm index 3db216373..ebb58bb18 100644 --- a/centreon/common/aruba/snmp/mode/apconnections.pm +++ b/centreon/common/aruba/snmp/mode/apconnections.pm @@ -55,11 +55,11 @@ my $maps_counters = { ], } }, - '003_nsr' => { set => { + '003_snr' => { set => { key_values => [ { name => 'apSignalToNoiseRatio' }, { name => 'bssid' }, ], output_template => 'Signal to noise ratio : %d', perfdatas => [ - { label => 'nsr', value => 'apSignalToNoiseRatio_absolute', template => '%d', + { label => 'snr', value => 'apSignalToNoiseRatio_absolute', template => '%d', label_extra_instance => 1, instance_use => 'bssid_absolute' }, ], } diff --git a/centreon/common/aruba/snmp/mode/apusers.pm b/centreon/common/aruba/snmp/mode/apusers.pm index 621e99e34..1e5933fb4 100644 --- a/centreon/common/aruba/snmp/mode/apusers.pm +++ b/centreon/common/aruba/snmp/mode/apusers.pm @@ -396,7 +396,7 @@ sub manage_selection { my $total_timeticks = 0; foreach my $oid (keys %{$self->{results}->{$oid_wlsxUserEntry}}) { - $oid =~ /^$mapping->{nUserAuthenticationMethod}->{oid}\.(.*)$/; + next if ($oid !~ /^$mapping->{nUserAuthenticationMethod}->{oid}\.(.*)$/); my $instance = $1; my $result = $self->{snmp}->map_instance(mapping => $mapping, results => $self->{results}->{$oid_wlsxUserEntry}, instance => $instance); my $result2 = $self->{snmp}->map_instance(mapping => $mapping2, results => $self->{results}->{$mapping2->{nUserApBSSID}->{oid}}, instance => $instance); diff --git a/centreon/common/cisco/standard/snmp/mode/components/voltage.pm b/centreon/common/cisco/standard/snmp/mode/components/voltage.pm index 0b8cddeb1..33530f526 100644 --- a/centreon/common/cisco/standard/snmp/mode/components/voltage.pm +++ b/centreon/common/cisco/standard/snmp/mode/components/voltage.pm @@ -72,11 +72,13 @@ sub check { short_msg => sprintf("Voltage '%s' status is %s", $result->{ciscoEnvMonVoltageStatusDescr}, $result->{ciscoEnvMonVoltageState})); } - + + $result->{ciscoEnvMonVoltageStatusValue} = $result->{ciscoEnvMonVoltageStatusValue} / 1000; my ($exit2, $warn, $crit, $checked) = $self->get_severity_numeric(section => 'voltage', instance => $instance, value => $result->{ciscoEnvMonVoltageStatusValue}); if ($checked == 0) { my $warn_th = undef; - my $crit_th = $result->{ciscoEnvMonVoltageThresholdLow} . ':' . $result->{ciscoEnvMonVoltageThresholdHigh}; + my $crit_th = (defined($result->{ciscoEnvMonVoltageThresholdLow}) ? sprintf("%.3f", $result->{ciscoEnvMonVoltageThresholdLow}) : 0) . ':' . + (defined($result->{ciscoEnvMonVoltageThresholdHigh}) ? sprintf("%.3f", $result->{ciscoEnvMonVoltageThresholdHigh}) : ''); $self->{perfdata}->threshold_validate(label => 'warning-voltage-instance-' . $instance, value => $warn_th); $self->{perfdata}->threshold_validate(label => 'critical-voltage-instance-' . $instance, value => $crit_th); $warn = $self->{perfdata}->get_perfdata_for_output(label => 'warning-voltage-instance-' . $instance); @@ -84,10 +86,10 @@ sub check { } if (!$self->{output}->is_status(value => $exit2, compare => 'ok', litteral => 1)) { $self->{output}->output_add(severity => $exit2, - short_msg => sprintf("Voltage '%s' is %s V", $result->{ciscoEnvMonVoltageStatusDescr}, $result->{ciscoEnvMonVoltageStatusValue})); + short_msg => sprintf("Voltage '%s' is %.3f V", $result->{ciscoEnvMonVoltageStatusDescr}, $result->{ciscoEnvMonVoltageStatusValue})); } $self->{output}->perfdata_add(label => "voltage_" . $result->{ciscoEnvMonVoltageStatusDescr}, unit => 'V', - value => $result->{ciscoEnvMonVoltageStatusValue}, + value => sprintf("%.3f", $result->{ciscoEnvMonVoltageStatusValue}), warning => $warn, critical => $crit); } diff --git a/centreon/common/cisco/standard/snmp/mode/cpu.pm b/centreon/common/cisco/standard/snmp/mode/cpu.pm index 6ecaa5c09..a4870c11c 100644 --- a/centreon/common/cisco/standard/snmp/mode/cpu.pm +++ b/centreon/common/cisco/standard/snmp/mode/cpu.pm @@ -73,6 +73,26 @@ sub check_options { } } +sub check_nexus_cpu { + my ($self, %options) = @_; + + if (!defined($self->{results}->{$options{oid}}->{$options{oid} . '.0'})) { + return 0; + } + + my $cpu = $self->{results}->{$options{oid}}->{$options{oid} . '.0'}; + my $exit = $self->{perfdata}->threshold_check(value => $cpu, + threshold => [ { label => 'crit5m', exit_litteral => 'critical' }, { label => 'warn5m', exit_litteral => 'warning' } ]); + $self->{output}->output_add(severity => $exit, + short_msg => sprintf("CPU Usage : %s %%", $cpu)); + $self->{output}->perfdata_add(label => "cpu", unit => '%', + value => $cpu, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warn5m'), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'crit5m'), + min => 0, max => 100); + return 1; +} + sub check_table_cpu { my ($self, %options) = @_; @@ -113,21 +133,21 @@ sub check_table_cpu { } if (defined($cpu5sec)) { - $self->{output}->perfdata_add(label => "cpu_" . $instance . "_5s", + $self->{output}->perfdata_add(label => "cpu_" . $instance . "_5s", unit => '%', value => $cpu5sec, warning => $self->{perfdata}->get_perfdata_for_output(label => 'warn5s'), critical => $self->{perfdata}->get_perfdata_for_output(label => 'crit5s'), min => 0, max => 100); } if (defined($cpu1min)) { - $self->{output}->perfdata_add(label => "cpu_" . $instance . "_1m", + $self->{output}->perfdata_add(label => "cpu_" . $instance . "_1m", unit => '%', value => $cpu1min, warning => $self->{perfdata}->get_perfdata_for_output(label => 'warn1m'), critical => $self->{perfdata}->get_perfdata_for_output(label => 'crit1m'), min => 0, max => 100); } if (defined($cpu5min)) { - $self->{output}->perfdata_add(label => "cpu_" . $instance . "_5m", + $self->{output}->perfdata_add(label => "cpu_" . $instance . "_5m", unit => '%', value => $cpu5min, warning => $self->{perfdata}->get_perfdata_for_output(label => 'warn5m'), critical => $self->{perfdata}->get_perfdata_for_output(label => 'crit5m'), @@ -157,14 +177,18 @@ sub run { my $oid_busyPer = '.1.3.6.1.4.1.9.2.1.56'; # .0 in reality my $oid_avgBusy1 = '.1.3.6.1.4.1.9.2.1.57'; # .0 in reality my $oid_avgBusy5 = '.1.3.6.1.4.1.9.2.1.58'; # .0 in reality + # Cisco Nexus + my $oid_cseSysCPUUtilization = '.1.3.6.1.4.1.9.9.305.1.1.1'; # .0 in reality $self->{results} = $self->{snmp}->get_multiple_table(oids => [ { oid => $oid_cpmCPUTotalEntry, start => $oid_cpmCPUTotal5sec, end => $oid_cpmCPUTotal5minRev }, { oid => $oid_lcpu, - start => $oid_busyPer, end => $oid_avgBusy5 }], - nothing_quit => 1); + start => $oid_busyPer, end => $oid_avgBusy5 }, + { oid => $oid_cseSysCPUUtilization }, + ], + nothing_quit => 1); $self->{output}->output_add(severity => 'OK', short_msg => 'All CPUs are ok.'); @@ -173,8 +197,10 @@ sub run { && !$self->check_table_cpu(entry => $oid_cpmCPUTotalEntry, sec5 => $oid_cpmCPUTotal5sec, min1 => $oid_cpmCPUTotal1min, min5 => $oid_cpmCPUTotal5min) && !$self->check_table_cpu(entry => $oid_lcpu, sec5 => $oid_busyPer, min1 => $oid_avgBusy1, min5 => $oid_avgBusy5) ) { - $self->{output}->output_add(severity => 'UNKNOWN', - short_msg => sprintf("Cannot find CPU informations.")); + if (!$self->check_nexus_cpu(oid => $oid_cseSysCPUUtilization)) { + $self->{output}->output_add(severity => 'UNKNOWN', + short_msg => sprintf("Cannot find CPU informations.")); + } } $self->{output}->display(); @@ -187,17 +213,19 @@ __END__ =head1 MODE -Check cpu usage (CISCO-PROCESS-MIB). +Check cpu usage (CISCO-PROCESS-MIB and CISCO-SYSTEM-EXT-MIB). =over 8 =item B<--warning> Threshold warning in percent (5s,1min,5min). +Used 5min threshold when you have only 'cpu' metric. =item B<--critical> Threshold critical in percent (5s,1min,5min). +Used 5min threshold when you have only 'cpu' metric. =back diff --git a/centreon/plugins/script.pm b/centreon/plugins/script.pm index 81df96169..7cf310f13 100644 --- a/centreon/plugins/script.pm +++ b/centreon/plugins/script.pm @@ -29,7 +29,9 @@ use FindBin; use Pod::Usage; use Pod::Find qw(pod_where); -my %handlers = ('DIE' => {}); +my %handlers = (DIE => {}); + +my $global_version = 20151110; sub new { my $class = shift; @@ -242,6 +244,10 @@ sub run { $self->{output}->option_exit(); } if (!defined($self->{plugin}) || $self->{plugin} eq '') { + if (defined($self->{version})) { + $self->{output}->add_option_msg(short_msg => "Global Version: " . $global_version); + $self->{output}->option_exit(nolabel => 1); + } $self->{output}->add_option_msg(short_msg => "Need to specify '--plugin' option."); $self->{output}->option_exit(); } @@ -285,7 +291,7 @@ Print available plugins. =item B<--version> -Print plugin version. +Print global version. =item B<--help> diff --git a/centreon/plugins/script_custom.pm b/centreon/plugins/script_custom.pm index 4ca7765f0..38650e334 100644 --- a/centreon/plugins/script_custom.pm +++ b/centreon/plugins/script_custom.pm @@ -42,7 +42,7 @@ sub new { 'custommode:s' => { name => 'custommode_name' }, 'list-custommode' => { name => 'list_custommode' }, 'multiple' => { name => 'multiple' }, - 'sanity-options' => { name => 'sanity_options' }, + 'sanity-options' => { name => 'sanity_options' }, # keep it for 6 month before remove it } ); $self->{version} = '1.0'; @@ -66,6 +66,15 @@ sub new { return $self; } +sub load_custom_mode { + my ($self, %options) = @_; + + $self->is_custommode(custommode => $self->{custommode_name}); + centreon::plugins::misc::mymodule_load(output => $self->{output}, module => $self->{custom_modes}{$self->{custommode_name}}, + error_msg => "Cannot load module --custommode."); + $self->{custommode_current} = $self->{custom_modes}{$self->{custommode_name}}->new(options => $self->{options}, output => $self->{output}, mode => $self->{custommode_name}); +} + sub init { my ($self, %options) = @_; # $options{version} = string version @@ -84,18 +93,16 @@ sub init { if (defined($self->{list_custommode})) { $self->list_custommode(); } - if (defined($self->{sanity_options})) { - $self->{options}->set_sanity(); - } + $self->{options}->set_sanity(); # Output HELP $self->{options}->add_help(package => 'centreon::plugins::output', sections => 'OUTPUT OPTIONS'); if (defined($self->{custommode_name}) && $self->{custommode_name} ne '') { - $self->is_custommode(custommode => $self->{custommode_name}); - centreon::plugins::misc::mymodule_load(output => $self->{output}, module => $self->{custom_modes}{$self->{custommode_name}}, - error_msg => "Cannot load module --custommode."); - $self->{custommode_current} = $self->{custom_modes}{$self->{custommode_name}}->new(options => $self->{options}, output => $self->{output}, mode => $self->{custommode_name}); + $self->load_custom_mode(); + } elsif (scalar(keys %{$self->{custom_modes}}) == 1) { + $self->{custommode_name} = (keys(%{$self->{custom_modes}}))[0]; + $self->load_custom_mode(); } else { $self->{output}->add_option_msg(short_msg => "Need to specify '--custommode'."); $self->{output}->option_exit(); @@ -255,10 +262,6 @@ Check minimal version of mode. If not, unknown error. Display plugin version. -=item B<--sanity-options> - -Check unknown options (for debug purpose). - =item B<--custommode> Choose a custom mode. diff --git a/centreon/plugins/script_simple.pm b/centreon/plugins/script_simple.pm index fa6543593..5a6a994e8 100644 --- a/centreon/plugins/script_simple.pm +++ b/centreon/plugins/script_simple.pm @@ -39,7 +39,7 @@ sub new { 'dyn-mode:s' => { name => 'dynmode_name' }, 'list-mode' => { name => 'list_mode' }, 'mode-version:s' => { name => 'mode_version' }, - 'sanity-options' => { name => 'sanity_options' }, + 'sanity-options' => { name => 'sanity_options' }, # keep it for 6 month before remove it } ); $self->{version} = '1.0'; @@ -74,9 +74,7 @@ sub init { if (defined($self->{list_mode})) { $self->list_mode(); } - if (defined($self->{sanity_options})) { - $self->{options}->set_sanity(); - } + $self->{options}->set_sanity(); # Output HELP $self->{options}->add_help(package => 'centreon::plugins::output', sections => 'OUTPUT OPTIONS'); @@ -200,10 +198,6 @@ Check minimal version of mode. If not, unknown error. Display plugin version. -=item B<--sanity-options> - -Check unknown options (for debug purpose). - =back =head1 DESCRIPTION diff --git a/centreon/plugins/script_snmp.pm b/centreon/plugins/script_snmp.pm index 7c8cfbaaa..2a4567629 100644 --- a/centreon/plugins/script_snmp.pm +++ b/centreon/plugins/script_snmp.pm @@ -41,7 +41,7 @@ sub new { 'dyn-mode:s' => { name => 'dynmode_name' }, 'list-mode' => { name => 'list_mode' }, 'mode-version:s' => { name => 'mode_version' }, - 'sanity-options' => { name => 'sanity_options' }, + 'sanity-options' => { name => 'sanity_options' }, # keep it for 6 month before remove it } ); $self->{version} = '1.0'; @@ -76,9 +76,7 @@ sub init { if (defined($self->{list_mode})) { $self->list_mode(); } - if (defined($self->{sanity_options})) { - $self->{options}->set_sanity(); - } + $self->{options}->set_sanity(); # Output HELP $self->{options}->add_help(package => 'centreon::plugins::output', sections => 'OUTPUT OPTIONS'); @@ -208,10 +206,6 @@ Check minimal version of mode. If not, unknown error. Display plugin version. -=item B<--sanity-options> - -Check unknown options (for debug purpose). - =back =head1 DESCRIPTION diff --git a/centreon/plugins/script_sql.pm b/centreon/plugins/script_sql.pm index 7a21220f0..c82cf1778 100644 --- a/centreon/plugins/script_sql.pm +++ b/centreon/plugins/script_sql.pm @@ -43,7 +43,7 @@ sub new { 'sqlmode:s' => { name => 'sqlmode_name', default => 'dbi' }, 'list-sqlmode' => { name => 'list_sqlmode' }, 'multiple' => { name => 'multiple' }, - 'sanity-options' => { name => 'sanity_options' }, + 'sanity-options' => { name => 'sanity_options' }, # keep it for 6 month before remove it } ); $self->{version} = '1.0'; @@ -85,9 +85,7 @@ sub init { if (defined($self->{list_sqlmode})) { $self->list_sqlmode(); } - if (defined($self->{sanity_options})) { - $self->{options}->set_sanity(); - } + $self->{options}->set_sanity(); # Output HELP $self->{options}->add_help(package => 'centreon::plugins::output', sections => 'OUTPUT OPTIONS'); @@ -261,10 +259,6 @@ Check minimal version of mode. If not, unknown error. Display plugin version. -=item B<--sanity-options> - -Check unknown options (for debug purpose). - =item B<--sqlmode> Choose a sql mode (Default: "dbi"). diff --git a/centreon/plugins/script_wsman.pm b/centreon/plugins/script_wsman.pm index d7f38d0c5..789747149 100644 --- a/centreon/plugins/script_wsman.pm +++ b/centreon/plugins/script_wsman.pm @@ -41,7 +41,7 @@ sub new { 'dyn-mode:s' => { name => 'dynmode_name' }, 'list-mode' => { name => 'list_mode' }, 'mode-version:s' => { name => 'mode_version' }, - 'sanity-options' => { name => 'sanity_options' }, + 'sanity-options' => { name => 'sanity_options' }, # keep it for 6 month before remove it } ); $self->{version} = '1.0'; @@ -76,9 +76,7 @@ sub init { if (defined($self->{list_mode})) { $self->list_mode(); } - if (defined($self->{sanity_options})) { - $self->{options}->set_sanity(); - } + $self->{options}->set_sanity(); # Output HELP $self->{options}->add_help(package => 'centreon::plugins::output', sections => 'OUTPUT OPTIONS'); @@ -204,10 +202,6 @@ Check minimal version of mode. If not, unknown error. Display plugin version. -=item B<--sanity-options> - -Check unknown options (for debug purpose). - =back =head1 DESCRIPTION diff --git a/cloud/aws/custom/awscli.pm b/cloud/aws/custom/awscli.pm index 3e43ea54b..4ed939bbe 100644 --- a/cloud/aws/custom/awscli.pm +++ b/cloud/aws/custom/awscli.pm @@ -23,7 +23,6 @@ package cloud::aws::custom::awscli; use strict; use warnings; use JSON; -use Data::Dumper; use centreon::plugins::misc; sub new { @@ -53,15 +52,10 @@ sub new { "sudo" => { name => 'sudo' }, } ); } - $options{options}->add_help( - package => __PACKAGE__, - sections => 'AWSCLI OPTIONS', - once => 1 - ); + $options{options}->add_help(package => __PACKAGE__, sections => 'AWSCLI OPTIONS', once => 1); $self->{output} = $options{output}; $self->{mode} = $options{mode}; - return $self; } @@ -78,8 +72,6 @@ sub set_options { sub set_defaults { my ( $self, %options ) = @_; - # options{default} - # Manage default value foreach ( keys %{ $options{default} } ) { if ( $_ eq $self->{mode} ) { @@ -96,30 +88,30 @@ sub set_defaults { } sub check_options { - my ( $self, %options ) = @_; + my ($self, %options) = @_; return 0; } sub execReq { - my ( $self, $options ) = @_; + my ($self, $options) = @_; my $jsoncontent; - if ( !defined( $options->{output} ) ) { + if (!defined($options->{output})) { $options->{output} = 'json'; } my $json = JSON->new; my $json_encoded = $options->{command} . " " . $options->{subcommand}; - if ( defined( $self->{option_results}->{region} ) ) { + if (defined($self->{option_results}->{region})) { $json_encoded = $json_encoded . " --region '". $self->{option_results}->{region} . "'"; } - if ( defined( $options->{json} ) ) { + if (defined($options->{json})) { $json_encoded = $json_encoded . " --cli-input-json '" . $json->encode( $options->{json} ) . "'"; } $self->{option_results}->{timeout} = 30; - if ( $options->{output} eq 'text' ) { + if ($options->{output} eq 'text') { $self->{stdout} = centreon::plugins::misc::execute( output => $self->{output}, options => $self->{option_results}, @@ -130,8 +122,7 @@ sub execReq { ); my @return = split /\n/, $self->{stdout}; $jsoncontent = $json->encode( [@return] ); - } - else { + } else { $jsoncontent = centreon::plugins::misc::execute( output => $self->{output}, options => $self->{option_results}, @@ -141,7 +132,7 @@ sub execReq { command_options => $json_encoded ); } - if ( $? > 0 ) { + if ($? > 0) { $self->{output}->add_option_msg( short_msg => "Cannot run aws" ); $self->{output}->option_exit(); } diff --git a/cloud/aws/mode/cloudwatch.pm b/cloud/aws/mode/cloudwatch.pm index d5dbe724f..9278d44f0 100644 --- a/cloud/aws/mode/cloudwatch.pm +++ b/cloud/aws/mode/cloudwatch.pm @@ -25,18 +25,17 @@ use base qw(centreon::plugins::mode); use strict; use warnings; use centreon::plugins::misc; -use Data::Dumper; use POSIX; use JSON; use Module::Load; my $CloudwatchMetrics = { - 'cpu' => "cloud::aws::mode::metrics::ec2instancecpu", - 'traffic' => "cloud::aws::mode::metrics::ec2instancenetwork", - 'cpucreditusage' => "cloud::aws::mode::metrics::ec2instancecpucreditusage", - 'cpucreditbalance' => "cloud::aws::mode::metrics::ec2instancecpucreditbalance", - 'bucketsize' => "cloud::aws::mode::metrics::s3bucketsize", - 'rdscpu' => "cloud::aws::mode::metrics::rdsinstancecpu", + cpu => "cloud::aws::mode::metrics::ec2instancecpu", + traffic => "cloud::aws::mode::metrics::ec2instancenetwork", + cpucreditusage => "cloud::aws::mode::metrics::ec2instancecpucreditusage", + cpucreditbalance => "cloud::aws::mode::metrics::ec2instancecpucreditbalance", + bucketsize => "cloud::aws::mode::metrics::s3bucketsize", + rdscpu => "cloud::aws::mode::metrics::rdsinstancecpu", }; my $StatisticsType = "Average,Minimum,Maximum,Sum,SampleCount"; diff --git a/cloud/aws/mode/instancestate.pm b/cloud/aws/mode/instancestate.pm index b7304a607..966d68565 100644 --- a/cloud/aws/mode/instancestate.pm +++ b/cloud/aws/mode/instancestate.pm @@ -51,7 +51,7 @@ sub new { $options{options}->add_options( arguments => { - "state:s" => { name => 'state', default => 'all' }, + "state:s" => { name => 'state', default => 'all' }, "no-includeallinstances" => { name => 'includeallinstances' }, "exclude:s" => { name => 'exclude' }, "instanceid:s" => { name => 'instanceid' } @@ -62,45 +62,43 @@ sub new { } sub check_options { - my ( $self, %options ) = @_; + my ($self, %options) = @_; $self->SUPER::init(%options); } sub manage_selection { - my ( $self, %options ) = @_; + my ($self, %options) = @_; - my ( @result, $awsapi ); + my (@result, $awsapi); # Getting some parameters # includeallinstances - if ( defined( $self->{option_results}->{includeallinstances} ) ) { - $self->{option_results}->{includeallinstances} = JSON::false; - } - else { + if (defined($self->{option_results}->{includeallinstances})) { + $self->{option_results}->{includeallinstances} = JSON::false; + } else { $self->{option_results}->{includeallinstances} = JSON::true; } # states - if ( $self->{option_results}->{state} eq 'all' ) { - @{ $self->{option_results}->{statetab} } = keys(%EC2_instance_states); - } - else { - @{ $self->{option_results}->{statetab} } = split( /,/, $self->{option_results}->{state} ); - foreach my $curstate ( @{ $self->{option_results}->{statetab} } ) { - if ( !grep { /^$curstate$/ } keys(%EC2_instance_states) ) { - $self->{output}->add_option_msg( severity => 'UNKNOWN', short_msg => "The state doesn't exist." ); + if ($self->{option_results}->{state} eq 'all') { + @{$self->{option_results}->{statetab} } = keys %EC2_instance_states; + } else { + @{$self->{option_results}->{statetab}} = split /,/, $self->{option_results}->{state}; + foreach my $curstate (@{$self->{option_results}->{statetab}}) { + if (!grep { /^$curstate$/ } keys(%EC2_instance_states)) { + $self->{output}->add_option_msg(severity => 'UNKNOWN', short_msg => "The state doesn't exist."); $self->{output}->option_exit(); } } } # exclusions - if ( defined( $self->{option_results}->{exclude} ) ) { - my @excludetab = split( /,/, $self->{option_results}->{exclude} ); + if (defined($self->{option_results}->{exclude})) { + my @excludetab = split /,/, $self->{option_results}->{exclude}; my %array1 = map { $_ => 1 } @excludetab; - @{ $self->{option_results}->{statetab} } = grep { not $array1{$_} } @{ $self->{option_results}->{statetab} }; + @{$self->{option_results}->{statetab}} = grep { not $array1{$_} } @{$self->{option_results}->{statetab}}; } - my $states = join(',',@{ $self->{option_results}->{statetab} }); + my $states = join(',',@{$self->{option_results}->{statetab}}); # Getting data from AWS # Building JSON @@ -114,9 +112,9 @@ sub manage_selection { }], }; # InstanceIds - if ( defined( $self->{option_results}->{instanceid} ) ) { - my @InstanceIds = split(/,/,$self->{option_results}->{instanceid}); - @{$apiRequest->{json}{'InstanceIds'}} = @InstanceIds; + if (defined($self->{option_results}->{instanceid})) { + my @InstanceIds = split(/,/, $self->{option_results}->{instanceid}); + @{$apiRequest->{json}{InstanceIds}} = @InstanceIds; } # Requesting API @@ -124,22 +122,22 @@ sub manage_selection { $self->{command_return} = $awsapi->execReq($apiRequest); # Compute data - $self->{option_results}->{instancecount}->{'total'} = '0'; - foreach my $curstate ( @{ $self->{option_results}->{statetab} } ) { - $self->{option_results}->{instancecount}->{$curstate} = '0'; + $self->{option_results}->{instancecount}->{total} = 0; + foreach my $curstate (@{$self->{option_results}->{statetab}}) { + $self->{option_results}->{instancecount}->{$curstate} = 0; } - foreach my $l ( @{ $self->{command_return}->{InstanceStatuses} } ) { - $self->{result}->{instance}->{ $l->{InstanceId} } = $l->{InstanceState}->{Name}; + foreach my $l (@{$self->{command_return}->{InstanceStatuses}}) { + $self->{result}->{instance}->{$l->{InstanceId}} = $l->{InstanceState}->{Name}; # long output for each instance - $self->{output}->output_add( long_msg => "'" . $l->{InstanceId} . "' [state = " . $l->{InstanceState}->{Name} . ']' ); + $self->{output}->output_add(long_msg => "'" . $l->{InstanceId} . "' [state = " . $l->{InstanceState}->{Name} . ']'); - foreach my $curstate ( @{ $self->{option_results}->{statetab} } ) { - if ( $l->{InstanceState}->{Name} eq $curstate ) { + foreach my $curstate (@{$self->{option_results}->{statetab}}) { + if ($l->{InstanceState}->{Name} eq $curstate) { $self->{option_results}->{instancecount}->{$curstate}++; } } - $self->{option_results}->{instancecount}->{'total'}++; + $self->{option_results}->{instancecount}->{total}++; } } @@ -158,16 +156,16 @@ sub run { value => $self->{option_results}->{instancecount}->{'total'}, ); - foreach my $curstate ( @{ $self->{option_results}->{statetab} } ) { + foreach my $curstate (@{$self->{option_results}->{statetab}}) { $self->{output}->perfdata_add( label => $curstate, value => $self->{option_results}->{instancecount}->{$curstate}, ); # Most critical state - if ( $self->{option_results}->{instancecount}->{$curstate} != '0' ) { + if ($self->{option_results}->{instancecount}->{$curstate} != 0) { $exit_code = $EC2_instance_states{$curstate}; - $exit_code = $self->{output}->get_most_critical( status => [ $exit_code, $old_status ] ); + $exit_code = $self->{output}->get_most_critical(status => [ $exit_code, $old_status ]); $old_status = $exit_code; } } @@ -175,7 +173,7 @@ sub run { # Output message $self->{output}->output_add( severity => $exit_code, - short_msg => sprintf( "Total instances: %s", $self->{option_results}->{instancecount}->{'total'} ) + short_msg => sprintf("Total instances: %s", $self->{option_results}->{instancecount}->{total}) ); $self->{output}->display(); diff --git a/cloud/aws/mode/list.pm b/cloud/aws/mode/list.pm index 5de4eeacf..7099611a0 100644 --- a/cloud/aws/mode/list.pm +++ b/cloud/aws/mode/list.pm @@ -46,35 +46,25 @@ sub new return $self; } -sub check_options -{ +sub check_options { my ($self, %options) = @_; $self->SUPER::init(%options); } -sub api_request -{ +sub api_request { my ($self, %options) = @_; - @{$self->{option_results}->{servicetab}} = - split(/,/, $self->{option_results}->{service}); - foreach my $service (@{$self->{option_results}->{servicetab}}) - { - $self->{result}->{count}->{$service} = '0'; - if ($service eq 'EC2') - { + + @{$self->{option_results}->{servicetab}} = split( /,/, $self->{option_results}->{service} ); + foreach my $service (@{$self->{option_results}->{servicetab}}) { + $self->{result}->{count}->{$service} = 0; + if ($service eq 'EC2') { $self->EC2(%options); - } - elsif ($service eq 'S3') - { + } elsif ($service eq 'S3') { $self->S3(%options); - } - elsif ($service eq 'RDS') - { + } elsif ($service eq 'RDS') { $self->RDS(%options); - } - else - { - $self->{output}->add_option_msg(short_msg => "Service $service doesn't exists"); + } else { + $self->{output}->add_option_msg(short_msg => "Service $service doesn't exists" ); $self->{output}->option_exit(); } } @@ -104,19 +94,18 @@ sub EC2 $self->{command_return} = $awsapi->execReq($apiRequest); # Compute data - foreach my $instance (@{$self->{command_return}->{Reservations}}) - { - foreach my $tags (@{$instance->{Instances}[0]->{Tags}}) - { - if ($tags->{Key} eq 'Name') - { + foreach my $instance (@{$self->{command_return}->{Reservations}}) { + foreach my $tags (@{$instance->{Instances}[0]->{Tags}}) { + if ($tags->{Key} eq 'Name') { $instance->{Instances}[0]->{Name} = $tags->{Value}; } } - $self->{result}->{'EC2'}->{$instance->{Instances}[0]->{InstanceId}} = { - 'State' => $instance->{Instances}[0]->{State}->{Name}, - 'Name' => $instance->{Instances}[0]->{Name} - }; + $self->{result}->{'EC2'}->{$instance->{Instances}[0]->{InstanceId}} = + { + State => $instance->{Instances}[0]->{State}->{Name}, + Name => $instance->{Instances}[0]->{Name} + }; + $self->{result}->{count}->{'EC2'}++; } } @@ -136,11 +125,10 @@ sub S3 $self->{command_return} = $awsapi->execReq($apiRequest); # Exec command - foreach my $line (@{$self->{command_return}}) - { - my ($date, $time, $name) = split(/ /, $line); + foreach my $line (@{$self->{command_return}}) { + my ($date, $time, $name) = split / /, $line; my $creationdate = $date . " " . $time; - push(@buckets, {Name => $name, CreationDate => $creationdate}); + push(@buckets, { Name => $name, CreationDate => $creationdate }); } # Compute data @@ -165,31 +153,28 @@ sub RDS $self->{command_return} = $awsapi->execReq($apiRequest); # Compute data - foreach my $dbinstance (@{$self->{command_return}->{DBInstances}}) - { + foreach my $dbinstance (@{$self->{command_return}->{DBInstances}}) { $self->{result}->{'RDS'}->{$dbinstance->{DBInstanceIdentifier}} = { - 'State' => $dbinstance->{DBInstanceStatus}, - 'Name' => $dbinstance->{DBInstanceIdentifier} + State => $dbinstance->{DBInstanceStatus}, + Name => $dbinstance->{DBInstanceIdentifier} }; - $self->{result}->{count}->{'RDS'}++; + $self->{result}->{count}->{RDS}++; } } -sub disco_format -{ +sub disco_format { my ($self, %options) = @_; - my $names = ['name', 'id', 'state', 'service']; - $self->{output}->add_disco_format(elements => $names); + + my $names = [ 'name', 'id', 'state', 'service' ]; + $self->{output}->add_disco_format( elements => $names ); } sub disco_show { my ($self, %options) = @_; $self->api_request(%options); - foreach my $service (@Disco_service_tab) - { - foreach my $device (keys %{$self->{result}->{$service}}) - { + foreach my $service (@Disco_service_tab) { + foreach my $device (keys %{$self->{result}->{$service}}) { $self->{output}->add_disco_entry( name => $self->{result}->{$service}->{$device}->{Name}, id => $device, @@ -206,15 +191,15 @@ sub run $self->api_request(%options); # Send formated data to Centreon - foreach my $service (@{$self->{option_results}->{servicetab}}) - { + foreach my $service (@{$self->{option_results}->{servicetab}}) { $self->{output}->output_add(long_msg => sprintf("AWS service: %s", $service)); - foreach my $device (keys %{$self->{result}->{$service}}) - { + foreach my $device (keys %{$self->{result}->{$service}}) { my $output = $device . " ["; - foreach my $value (sort(keys %{$self->{result}->{$service}->{$device}})) - { - $output = $output . $value . " = " . $self->{result}->{$service}->{$device}->{$value} . ", "; + foreach my $value (sort(keys %{$self->{result}->{$service}->{$device}})) { + $output = + $output + . $value . " = " + . $self->{result}->{$service}->{$device}->{$value} . ", "; } $output =~ s/, $//; $output = $output . "]"; diff --git a/database/oracle/mode/rmanbackupage.pm b/database/oracle/mode/rmanbackupage.pm index 55b1f4785..fef424a8f 100644 --- a/database/oracle/mode/rmanbackupage.pm +++ b/database/oracle/mode/rmanbackupage.pm @@ -85,7 +85,7 @@ sub run { $self->{sql}->connect(); my $query; if (defined($self->{option_results}->{incremental_level})) { - $query = q{SELECT v$rman_status.object_type, + $query = q{SELECT v$rman_status.object_type, ((max(v$rman_status.start_time) - date '1970-01-01')*24*60*60) as last_time, NVL(v$backup_set_details.incremental_level, 0) FROM v$rman_status LEFT JOIN v$backup_set_details ON v$rman_status.session_recid = v$backup_set_details.session_recid @@ -115,7 +115,7 @@ sub run { next if (defined($already_checked->{$$row[0]})); - if (defined($self->{option_results}->{incremental_level})) { + if (defined($self->{option_results}->{incremental_level})) { # db incr with incremental level 0 = DB FULL if (/db full/ && $$row[0] =~ /db incr/i && defined($$row[2]) && $$row[2] == 0) { # it's a full. we get $$row[0] = 'DB FULL'; diff --git a/docs/en/user/guide.rst b/docs/en/user/guide.rst index 96191a3e7..60ff97ab4 100644 --- a/docs/en/user/guide.rst +++ b/docs/en/user/guide.rst @@ -557,15 +557,6 @@ The mapping between 'snmpwalk' options and "centreon-plugins" options: Miscellaneous ------------- -I use an option but it doesn't seem to work -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -Before opening a ticket on the github, please use the option ``--sanity-options``. It checks if you have misspell an option: -:: - - $ perl centreon_plugins.pl --plugin=os::linux::snmp::plugin --mode=traffic --hostname=127.0.0.1 --snmp-version=2c --snmp-community=public --interface='.*' --name --regex --verbose --skip --skip-speed0 --sanity-options - Unknown option: regex - I get the error: "UNKNOWN: Need to specify '--custommode'." ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/docs/fr/user/guide.rst b/docs/fr/user/guide.rst index dc1701fb3..df9d7da3b 100644 --- a/docs/fr/user/guide.rst +++ b/docs/fr/user/guide.rst @@ -557,15 +557,6 @@ L'association entre les options 'snmpwalk' et les options "centreon-plugins" : Divers ------ -J'utilise une options mais il semblerait qu'elle ne fonctionne pas -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -Avant d'ouvrir un ticket sur github, utilisez l'option ``--sanity-options``. Cela vérifie si vous avez mal orthographié une option : -:: - - $ perl centreon_plugins.pl --plugin=os::linux::snmp::plugin --mode=traffic --hostname=127.0.0.1 --snmp-version=2c --snmp-community=public --interface='.*' --name --regex --verbose --skip --skip-speed0 --sanity-options - Unknown option: regex - J'ai l'erreur: "UNKNOWN: Need to specify '--custommode'." ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/hardware/server/dell/openmanage/snmp/mode/components/cachebattery.pm b/hardware/server/dell/openmanage/snmp/mode/components/cachebattery.pm index 0b74c11ca..a453fda48 100644 --- a/hardware/server/dell/openmanage/snmp/mode/components/cachebattery.pm +++ b/hardware/server/dell/openmanage/snmp/mode/components/cachebattery.pm @@ -93,6 +93,7 @@ sub check { my $result3 = $self->{snmp}->map_instance(mapping => $mapping3, results => $self->{results}->{$mapping3->{batteryPredictedCapicity}->{oid}}, instance => $instance); my $result4 = $self->{snmp}->map_instance(mapping => $mapping4, results => $self->{results}->{$mapping4->{batteryLearnState}->{oid}}, instance => $instance); $result4->{batteryLearnState} = defined($result4->{batteryLearnState}) ? $result4->{batteryLearnState} : '-'; + $result3->{batteryPredictedCapicity} = defined($result3->{batteryPredictedCapicity}) ? $result3->{batteryPredictedCapicity} : '-'; next if ($self->check_exclude(section => 'cachebattery', instance => $instance)); diff --git a/hardware/server/dell/openmanage/snmp/mode/components/connector.pm b/hardware/server/dell/openmanage/snmp/mode/components/connector.pm index 9a56d7d27..34eede51f 100644 --- a/hardware/server/dell/openmanage/snmp/mode/components/connector.pm +++ b/hardware/server/dell/openmanage/snmp/mode/components/connector.pm @@ -83,7 +83,8 @@ sub check { my $result = $self->{snmp}->map_instance(mapping => $mapping, results => $self->{results}->{$oid_channelEntry}, instance => $instance); my $result2 = $self->{snmp}->map_instance(mapping => $mapping2, results => $self->{results}->{$mapping2->{channelComponentStatus}->{oid}}, instance => $instance); my $result3 = $self->{snmp}->map_instance(mapping => $mapping3, results => $self->{results}->{$mapping3->{channelBusType}->{oid}}, instance => $instance); - + $result3->{channelBusType} = defined($result3->{channelBusType}) ? $result3->{channelBusType} : '-'; + next if ($self->check_exclude(section => 'connector', instance => $instance)); $self->{components}->{connector}->{total}++; diff --git a/hardware/server/dell/openmanage/snmp/mode/components/cpu.pm b/hardware/server/dell/openmanage/snmp/mode/components/cpu.pm index 2a8bce470..28dc2eb23 100644 --- a/hardware/server/dell/openmanage/snmp/mode/components/cpu.pm +++ b/hardware/server/dell/openmanage/snmp/mode/components/cpu.pm @@ -85,7 +85,8 @@ sub check { $self->{output}->output_add(long_msg => sprintf("Cpu '%s' status is '%s' [instance: %s, manufacturer name: %s, brand name: %s, state: %s, speed: %s]", $instance, $result->{processorDeviceStatus}, $instance, - $result2->{processorDeviceManufacturerName}, $result4->{processorDeviceBrandName}, + $result2->{processorDeviceManufacturerName}, + defined($result4->{processorDeviceBrandName}) ? $result4->{processorDeviceBrandName} : '-', $result2->{processorDeviceStatusState}, $result3->{processorDeviceCurrentSpeed} )); my $exit = $self->get_severity(section => 'cpu', value => $result->{processorDeviceStatus}); diff --git a/hardware/server/dell/openmanage/snmp/mode/components/physicaldisk.pm b/hardware/server/dell/openmanage/snmp/mode/components/physicaldisk.pm index b956ae89a..f5a812909 100644 --- a/hardware/server/dell/openmanage/snmp/mode/components/physicaldisk.pm +++ b/hardware/server/dell/openmanage/snmp/mode/components/physicaldisk.pm @@ -107,7 +107,8 @@ sub check { $self->{output}->output_add(long_msg => sprintf("Physical Disk '%s' status is '%s' [instance: %s, state: %s, spare state: %s, smart alert: %s]", $result->{arrayDiskName}, $result4->{arrayDiskComponentStatus}, $instance, - $result2->{arrayDiskState}, $result3->{arrayDiskSpareState}, $result5->{arrayDiskSmartAlertIndication} + $result2->{arrayDiskState}, $result3->{arrayDiskSpareState}, + defined($result5->{arrayDiskSmartAlertIndication}) ? $result5->{arrayDiskSmartAlertIndication} : '-' )); my $exit = $self->get_severity(section => 'physicaldisk', value => $result4->{arrayDiskComponentStatus}); if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { @@ -116,11 +117,13 @@ sub check { $result->{arrayDiskName}, $result4->{arrayDiskComponentStatus})); } - $exit = $self->get_severity(section => 'physicaldisk_smartalert', value => $result5->{arrayDiskSmartAlertIndication}); - if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { - $self->{output}->output_add(severity => $exit, - short_msg => sprintf("physical disk '%s' has received a predictive failure alert", - $result->{arrayDiskName})); + if (defined($result5->{arrayDiskSmartAlertIndication})) { + $exit = $self->get_severity(section => 'physicaldisk_smartalert', value => $result5->{arrayDiskSmartAlertIndication}); + if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { + $self->{output}->output_add(severity => $exit, + short_msg => sprintf("physical disk '%s' has received a predictive failure alert", + $result->{arrayDiskName})); + } } } } diff --git a/hardware/server/dell/openmanage/snmp/mode/components/psu.pm b/hardware/server/dell/openmanage/snmp/mode/components/psu.pm index 276d22528..18aaf5856 100644 --- a/hardware/server/dell/openmanage/snmp/mode/components/psu.pm +++ b/hardware/server/dell/openmanage/snmp/mode/components/psu.pm @@ -100,7 +100,8 @@ sub check { $self->{output}->output_add(long_msg => sprintf("Power supply '%s' status is '%s' [instance: %s, location: %s, type: %s, output watts: %s, state: %s, configuration error: %s]", $instance, $result->{powerSupplyStatus}, $instance, - $result->{powerSupplyLocationName}, $result->{powerSupplyType}, $result->{powerSupplyOutputWatts}, + $result->{powerSupplyLocationName}, $result->{powerSupplyType}, + defined($result->{powerSupplyOutputWatts}) ? $result->{powerSupplyOutputWatts} : '-', $result2->{powerSupplySensorState}, $result2->{powerSupplyConfigurationErrorType} )); my $exit = $self->get_severity(section => 'psu', value => $result->{powerSupplyStatus}); diff --git a/hardware/server/ibm/bladecenter/snmp/mode/components/ambient.pm b/hardware/server/ibm/bladecenter/snmp/mode/components/ambient.pm index d30d61822..eabf896d3 100644 --- a/hardware/server/ibm/bladecenter/snmp/mode/components/ambient.pm +++ b/hardware/server/ibm/bladecenter/snmp/mode/components/ambient.pm @@ -23,18 +23,26 @@ package hardware::server::ibm::bladecenter::snmp::mode::components::ambient; use strict; use warnings; -# In MIB 'mmblade.mib' + my $oid_temperature = '.1.3.6.1.4.1.2.3.51.2.2.1'; +my $oid_end = '.1.3.6.1.4.1.2.3.51.2.2.1.5'; +my $oid_rearLEDCardTempMax = '.1.3.6.1.4.1.2.3.51.2.2.1.5.3.0'; +# In MIB 'mmblade.mib' and 'cme.mib' my $oids = { - mm => '.1.3.6.1.4.1.2.3.51.2.2.1.1.2.0', - frontpanel => '.1.3.6.1.4.1.2.3.51.2.2.1.5.1.0', - frontpanel2 => '.1.3.6.1.4.1.2.3.51.2.2.1.5.2.0', + bladecenter => { + mm => '.1.3.6.1.4.1.2.3.51.2.2.1.1.2.0', + frontpanel => '.1.3.6.1.4.1.2.3.51.2.2.1.5.1.0', + frontpanel2 => '.1.3.6.1.4.1.2.3.51.2.2.1.5.2.0', + }, + pureflex => { + ambient => '.1.3.6.1.4.1.2.3.51.2.2.1.5.1.0', # rearLEDCardTempAvg + } }; sub load { my (%options) = @_; - push @{$options{request}}, { oid => $oid_temperature }; + push @{$options{request}}, { oid => $oid_temperature, end => $oid_end }; } sub check { @@ -44,9 +52,16 @@ sub check { $self->{components}->{ambient} = {name => 'ambient', total => 0, skip => 0}; return if ($self->check_exclude(section => 'ambient')); - foreach my $temp (('mm', 'frontpanel', 'frontpanel2')) { - if (!defined($self->{results}->{$oid_temperature}->{$oids->{$temp}}) || - $self->{results}->{$oid_temperature}->{$oids->{$temp}} !~ /([0-9\.]+)/) { + my @sensors = ('mm', 'frontpanel', 'frontpanel2'); + my $label = 'bladecenter'; + if (defined($self->{results}->{$oid_temperature}->{$oid_rearLEDCardTempMax})) { + @sensors = ('ambient'); + $label = 'pureflex'; + } + + foreach my $temp (@sensors) { + if (!defined($self->{results}->{$oid_temperature}->{$oids->{$label}->{$temp}}) || + $self->{results}->{$oid_temperature}->{$oids->{$label}->{$temp}} !~ /([0-9\.]+)/) { $self->{output}->output_add(long_msg => sprintf("skip ambient '%s': no values", $temp)); next; diff --git a/hardware/server/ibm/bladecenter/snmp/mode/components/blade.pm b/hardware/server/ibm/bladecenter/snmp/mode/components/blade.pm index ee0b5e5c6..2f020405a 100644 --- a/hardware/server/ibm/bladecenter/snmp/mode/components/blade.pm +++ b/hardware/server/ibm/bladecenter/snmp/mode/components/blade.pm @@ -48,7 +48,7 @@ my %map_blade_power_state = ( 4 => 'hibernate', ); -# In MIB 'CPQSTDEQ-MIB.mib' +# In MIB 'mmblade.mib' and 'cme.mib' my $mapping = { bladeId => { oid => '.1.3.6.1.4.1.2.3.51.2.22.1.5.1.1.2' }, bladeExists => { oid => '.1.3.6.1.4.1.2.3.51.2.22.1.5.1.1.3', map => \%map_blade_exists }, @@ -77,8 +77,10 @@ sub check { my $result = $self->{snmp}->map_instance(mapping => $mapping, results => $self->{results}->{$oid_bladeSystemStatusEntry}, instance => $instance); next if ($self->check_exclude(section => 'blade', instance => $result->{bladeId})); - next if ($result->{bladeExists} =~ /No/i && - $self->absent_problem(section => 'blade', instance => $result->{bladeId})); + if ($result->{bladeExists} =~ /false/i) { + $self->{output}->output_add(long_msg => "skipping blade '" . $instance . "' : not exits"); + next; + } $self->{components}->{blade}->{total}++; if ($result->{bladePowerState} =~ /off/) { diff --git a/hardware/server/ibm/bladecenter/snmp/mode/components/chassisfan.pm b/hardware/server/ibm/bladecenter/snmp/mode/components/chassisfan.pm new file mode 100644 index 000000000..a3c90d7a2 --- /dev/null +++ b/hardware/server/ibm/bladecenter/snmp/mode/components/chassisfan.pm @@ -0,0 +1,86 @@ +# +# Copyright 2015 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +package hardware::server::ibm::bladecenter::snmp::mode::components::chassisfan; + +use strict; +use warnings; + +my %map_state = ( + 0 => 'unknown', + 1 => 'good', + 2 => 'warning', + 3 => 'bad', +); + +# In MIB 'mmblade.mib' and 'cme.mib' +my $mapping = { + chassisFanState => { oid => '.1.3.6.1.4.1.2.3.51.2.2.3.50.1.4', map => \%map_state }, + chassisFanSpeedRPM => { oid => '.1.3.6.1.4.1.2.3.51.2.2.3.50.1.5' }, +}; +my $oid_chassisFansEntry = '.1.3.6.1.4.1.2.3.51.2.2.3.50.1'; + +sub load { + my (%options) = @_; + + push @{$options{request}}, { oid => $oid_chassisFansEntry }; +} + +sub check { + my ($self) = @_; + + $self->{output}->output_add(long_msg => "Checking chassis fan"); + $self->{components}->{chassisfan} = {name => 'chassis fan', total => 0, skip => 0}; + return if ($self->check_exclude(section => 'chassisfan')); + + foreach my $oid ($self->{snmp}->oid_lex_sort(keys %{$self->{results}->{$oid_chassisFansEntry}})) { + next if ($oid !~ /^$mapping->{chassisFanState}->{oid}\.(.*)$/); + my $instance = $1; + my $result = $self->{snmp}->map_instance(mapping => $mapping, results => $self->{results}->{$oid_chassisFansEntry}, instance => $instance); + + next if ($self->check_exclude(section => 'chassisfan', instance => $instance)); + $self->{components}->{chassisfan}->{total}++; + + $self->{output}->output_add(long_msg => sprintf("Chassis fan '%s' is %s rpm [status: %s, instance: %s]", + $instance, $result->{chassisFanSpeedRPM}, $result->{chassisFanState}, + $instance)); + my $exit = $self->get_severity(section => 'chassisfan', value => $result->{chassisFanState}); + if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { + $self->{output}->output_add(severity => $exit, + short_msg => sprintf("Chassis fan '%s' status is %s", + $instance, $result->{chassisFanState})); + } + + if (defined($result->{chassisFanSpeedRPM}) && $result->{chassisFanSpeedRPM} =~ /[0-9]/) { + my ($exit2, $warn, $crit, $checked) = $self->get_severity_numeric(section => 'chassisfan', instance => $instance, value => $result->{chassisFanSpeedRPM}); + if (!$self->{output}->is_status(value => $exit2, compare => 'ok', litteral => 1)) { + $self->{output}->output_add(severity => $exit2, + short_msg => sprintf("Chassis fan '%s' speed is %s rpm", $instance, $result->{chassisFanSpeedRPM})); + } + $self->{output}->perfdata_add(label => "chassisfan_" . $instance, unit => 'rpm', + value => $result->{chassisFanSpeedRPM}, + warning => $warn, + critical => $crit, + min => 0); + } + } +} + +1; \ No newline at end of file diff --git a/hardware/server/ibm/bladecenter/snmp/mode/components/chassisstatus.pm b/hardware/server/ibm/bladecenter/snmp/mode/components/chassisstatus.pm index 3a2537aae..db8b4a56a 100644 --- a/hardware/server/ibm/bladecenter/snmp/mode/components/chassisstatus.pm +++ b/hardware/server/ibm/bladecenter/snmp/mode/components/chassisstatus.pm @@ -23,7 +23,7 @@ package hardware::server::ibm::bladecenter::snmp::mode::components::chassisstatu use strict; use warnings; -# In MIB 'mmblade.mib' +# In MIB 'mmblade.mib' and 'cme.mib' my $oid_mmBistAndChassisStatus = '.1.3.6.1.4.1.2.3.51.2.2.5.2'; my $oid_bistLogicalNetworkLink = '.1.3.6.1.4.1.2.3.51.2.2.5.2.30.0'; my $oids = { diff --git a/hardware/server/ibm/bladecenter/snmp/mode/components/fanpack.pm b/hardware/server/ibm/bladecenter/snmp/mode/components/fanpack.pm new file mode 100644 index 000000000..918cd655a --- /dev/null +++ b/hardware/server/ibm/bladecenter/snmp/mode/components/fanpack.pm @@ -0,0 +1,95 @@ +# +# Copyright 2015 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +package hardware::server::ibm::bladecenter::snmp::mode::components::fanpack; + +use strict; +use warnings; + +my %map_state = ( + 0 => 'unknown', + 1 => 'good', + 2 => 'warning', + 3 => 'bad', +); +my %map_exists = ( + 0 => 'false', + 1 => 'true', +); + +# In MIB 'mmblade.mib' and 'cme.mib' +my $mapping = { + fanPackExists => { oid => '.1.3.6.1.4.1.2.3.51.2.2.6.1.1.2', map => \%map_exists }, + fanPackState => { oid => '.1.3.6.1.4.1.2.3.51.2.2.6.1.1.3', map => \%map_state }, + fanPackAverageSpeedRPM => { oid => '.1.3.6.1.4.1.2.3.51.2.2.6.1.1.6' }, +}; +my $oid_fanPackEntry = '.1.3.6.1.4.1.2.3.51.2.2.6.1.1'; + +sub load { + my (%options) = @_; + + push @{$options{request}}, { oid => $oid_fanPackEntry }; +} + +sub check { + my ($self) = @_; + + $self->{output}->output_add(long_msg => "Checking fanpack"); + $self->{components}->{fanpack} = {name => 'fanpacks', total => 0, skip => 0}; + return if ($self->check_exclude(section => 'fanpack')); + + foreach my $oid ($self->{snmp}->oid_lex_sort(keys %{$self->{results}->{$oid_fanPackEntry}})) { + next if ($oid !~ /^$mapping->{fanPackState}->{oid}\.(.*)$/); + my $instance = $1; + my $result = $self->{snmp}->map_instance(mapping => $mapping, results => $self->{results}->{$oid_fanPackEntry}, instance => $instance); + + if ($result->{fanPackExists} =~ /false/i) { + $self->{output}->output_add(long_msg => "skipping fanpack '" . $instance . "' : not exits"); + next; + } + next if ($self->check_exclude(section => 'fanpack', instance => $instance)); + $self->{components}->{fanpack}->{total}++; + + $self->{output}->output_add(long_msg => sprintf("Fanpack '%s' is %s rpm [status: %s, instance: %s]", + $instance, $result->{fanPackAverageSpeedRPM}, $result->{fanPackState}, + $instance)); + my $exit = $self->get_severity(section => 'fanpack', value => $result->{fanPackState}); + if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { + $self->{output}->output_add(severity => $exit, + short_msg => sprintf("Fanpack '%s' status is %s", + $instance, $result->{fanPackState})); + } + + if (defined($result->{fanPackAverageSpeedRPM}) && $result->{fanPackAverageSpeedRPM} =~ /[0-9]/) { + my ($exit2, $warn, $crit, $checked) = $self->get_severity_numeric(section => 'fanpack', instance => $instance, value => $result->{fanPackAverageSpeedRPM}); + if (!$self->{output}->is_status(value => $exit2, compare => 'ok', litteral => 1)) { + $self->{output}->output_add(severity => $exit2, + short_msg => sprintf("Fanpack '%s' speed is %s rpm", $instance, $result->{fanPackAverageSpeedRPM})); + } + $self->{output}->perfdata_add(label => "fanpack_" . $instance, unit => 'rpm', + value => $result->{fanPackAverageSpeedRPM}, + warning => $warn, + critical => $crit, + min => 0); + } + } +} + +1; \ No newline at end of file diff --git a/hardware/server/ibm/bladecenter/snmp/mode/components/powermodule.pm b/hardware/server/ibm/bladecenter/snmp/mode/components/powermodule.pm index 577608191..dd4fd6135 100644 --- a/hardware/server/ibm/bladecenter/snmp/mode/components/powermodule.pm +++ b/hardware/server/ibm/bladecenter/snmp/mode/components/powermodule.pm @@ -35,7 +35,7 @@ my %map_pw_exists = ( 1 => 'true', ); -# In MIB 'CPQSTDEQ-MIB.mib' +# In MIB 'mmblade.mib' and 'cme.mib' my $mapping = { powerModuleExists => { oid => '.1.3.6.1.4.1.2.3.51.2.2.4.1.1.2', map => \%map_pw_exists }, powerModuleState => { oid => '.1.3.6.1.4.1.2.3.51.2.2.4.1.1.3', map => \%map_pw_state }, diff --git a/hardware/server/ibm/bladecenter/snmp/mode/components/switchmodule.pm b/hardware/server/ibm/bladecenter/snmp/mode/components/switchmodule.pm new file mode 100644 index 000000000..3d6c6b3f2 --- /dev/null +++ b/hardware/server/ibm/bladecenter/snmp/mode/components/switchmodule.pm @@ -0,0 +1,71 @@ +# +# Copyright 2015 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +package hardware::server::ibm::bladecenter::snmp::mode::components::switchmodule; + +use strict; +use warnings; + +my %map_state = ( + 0 => 'unknown', + 1 => 'good', + 2 => 'warning', + 3 => 'bad', +); + +# In MIB 'mmblade.mib' and 'cme.mib' +my $mapping = { + smHealthState => { oid => '.1.3.6.1.4.1.2.3.51.2.22.3.1.1.1.15', map => \%map_state }, +}; + +sub load { + my (%options) = @_; + + push @{$options{request}}, { oid => $mapping->{smHealthState}->{oid} }; +} + +sub check { + my ($self) = @_; + + $self->{output}->output_add(long_msg => "Checking switch module"); + $self->{components}->{switchmodule} = {name => 'switch modules', total => 0, skip => 0}; + return if ($self->check_exclude(section => 'switchmodule')); + + foreach my $oid ($self->{snmp}->oid_lex_sort(keys %{$self->{results}->{$mapping->{smHealthState}->{oid}}})) { + $oid =~ /^$mapping->{smHealthState}->{oid}\.(.*)/; + my $instance = $1; + my $result = $self->{snmp}->map_instance(mapping => $mapping, results => $self->{results}->{$mapping->{smHealthState}->{oid}}, instance => $instance); + + next if ($self->check_exclude(section => 'switchmodule', instance => $instance)); + $self->{components}->{switchmodule}->{total}++; + + $self->{output}->output_add(long_msg => sprintf("Switch module '%s' status is %s [instance: %s]", + $instance, $result->{smHealthState}, + $instance)); + my $exit = $self->get_severity(section => 'switchmodule', value => $result->{smHealthState}); + if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { + $self->{output}->output_add(severity => $exit, + short_msg => sprintf("Switch module '%s' status is %s", + $instance, $result->{smHealthState})); + } + } +} + +1; \ No newline at end of file diff --git a/hardware/server/ibm/bladecenter/snmp/mode/components/systemhealth.pm b/hardware/server/ibm/bladecenter/snmp/mode/components/systemhealth.pm index 88097db74..4f4958292 100644 --- a/hardware/server/ibm/bladecenter/snmp/mode/components/systemhealth.pm +++ b/hardware/server/ibm/bladecenter/snmp/mode/components/systemhealth.pm @@ -23,7 +23,7 @@ package hardware::server::ibm::bladecenter::snmp::mode::components::systemhealth use strict; use warnings; -# In MIB 'mmblade.mib' +# In MIB 'mmblade.mib' and 'cme.mib' my $oid_systemHealthStat = '.1.3.6.1.4.1.2.3.51.2.2.7.1'; my %map_systemhealth_state = ( diff --git a/hardware/server/ibm/bladecenter/snmp/mode/hardware.pm b/hardware/server/ibm/bladecenter/snmp/mode/hardware.pm index 8faa14976..1d939c6e7 100644 --- a/hardware/server/ibm/bladecenter/snmp/mode/hardware.pm +++ b/hardware/server/ibm/bladecenter/snmp/mode/hardware.pm @@ -42,12 +42,30 @@ my $thresholds = { ['warning', 'WARNING'], ['notAvailable', 'UNKNOWN'], ], - blower => [ + fanpack => [ + ['unknown', 'UNKNOWN'], + ['good', 'OK'], + ['warning', 'WARNING'], + ['bad', 'CRITICAL'], + ], + chassisfan => [ ['unknown', 'UNKNOWN'], ['good', 'OK'], ['warning', 'WARNING'], ['bad', 'CRITICAL'], ], + blower => [ + ['unknown', 'UNKNOWN'], + ['good', 'OK'], + ['warning', 'WARNING'], + ['bad', 'CRITICAL'], + ], + switchmodule => [ + ['unknown', 'UNKNOWN'], + ['good', 'OK'], + ['warning', 'WARNING'], + ['bad', 'CRITICAL'], + ], blowerctrl => [ ['unknown', 'UNKNOWN'], ['operational', 'OK'], @@ -132,8 +150,8 @@ sub check_options { $self->{output}->option_exit(); } my ($section, $regexp, $value) = ($1, $2, $3); - if ($section !~ /(blower|ambient)/) { - $self->{output}->add_option_msg(short_msg => "Wrong $option option '" . $val . "' (type must be: blower or ambient)."); + if ($section !~ /(blower|ambient|fanpack|chassisfan)/) { + $self->{output}->add_option_msg(short_msg => "Wrong $option option '" . $val . "' (type must be: blower, fanpack, chassisfan or ambient)."); $self->{output}->option_exit(); } my $position = 0; @@ -156,7 +174,7 @@ sub run { $self->{snmp} = $options{snmp}; my $snmp_request = []; - my @components = ('ambient', 'powermodule', 'blade', 'blower', 'systemhealth', 'chassisstatus'); + my @components = ('ambient', 'powermodule', 'blade', 'blower', 'fanpack', 'chassisfan', 'systemhealth', 'chassisstatus', 'switchmodule'); foreach (@components) { if (/$self->{option_results}->{component}/) { my $mod_name = "hardware::server::ibm::bladecenter::snmp::mode::components::$_"; @@ -289,14 +307,15 @@ __END__ =head1 MODE -Check Hardware (Ambient temperatures, Blowers, Power modules, Blades, System Health, Chassis status). +Check Hardware (Ambient temperatures, Blowers, Power modules, Blades, System Health, Chassis status, Fanpack). =over 8 =item B<--component> Which component to check (Default: 'all'). -Can be: 'ambient', 'powermodule', 'blower', 'blade', 'systemhealth', 'chassisstatus'. +Can be: 'ambient', 'powermodule', 'fanpack', 'chassisfan', +'blower', 'blade', 'systemhealth', 'chassisstatus', 'switchmodule'. =item B<--exclude> diff --git a/hardware/server/ibm/bladecenter/snmp/plugin.pm b/hardware/server/ibm/bladecenter/snmp/plugin.pm index 324ec3c75..0842efad6 100644 --- a/hardware/server/ibm/bladecenter/snmp/plugin.pm +++ b/hardware/server/ibm/bladecenter/snmp/plugin.pm @@ -44,6 +44,6 @@ __END__ =head1 PLUGIN DESCRIPTION -Check IBM Chassis BladeCenter (H, HT, T) in SNMP. +Check IBM Chassis BladeCenter (H, HT, T, Pureflex) in SNMP. =cut diff --git a/network/3com/snmp/mode/components/fan.pm b/network/3com/snmp/mode/components/fan.pm new file mode 100644 index 000000000..0c91df2cf --- /dev/null +++ b/network/3com/snmp/mode/components/fan.pm @@ -0,0 +1,74 @@ +# +# Copyright 2015 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +package network::3com::snmp::mode::components::fan; + +use strict; +use warnings; + +my %map_status = ( + 1 => 'active', + 2 => 'deactive', + 3 => 'not-install', + 4 => 'unsupport', +); + +# In MIB 'a3com-huawei-splat-devm' +my $mapping = { + hwDevMFanStatus => { oid => '.1.3.6.1.4.1.43.45.1.2.23.1.9.1.1.1.2', map => \%map_status }, +}; +my $oid_hwdevMFanStatusEntry = '.1.3.6.1.4.1.43.45.1.2.23.1.9.1.1.1'; + +sub load { + my (%options) = @_; + + push @{$options{request}}, { oid => $oid_hwdevMFanStatusEntry }; +} + +sub check { + my ($self) = @_; + + $self->{output}->output_add(long_msg => "Checking fans"); + $self->{components}->{fan} = {name => 'fans', total => 0, skip => 0}; + return if ($self->check_filter(section => 'fan')); + + foreach my $oid ($self->{snmp}->oid_lex_sort(keys %{$self->{results}->{$oid_hwdevMFanStatusEntry}})) { + next if ($oid !~ /^$mapping->{hwDevMFanStatus}->{oid}\.(.*)$/); + my $instance = $1; + my $result = $self->{snmp}->map_instance(mapping => $mapping, results => $self->{results}->{$oid_hwdevMFanStatusEntry}, instance => $instance); + + next if ($result->{hwDevMFanStatus} =~ /not-install/i && + $self->absent_problem(section => 'fan', instance => $instance)); + next if ($self->check_filter(section => 'fan', instance => $instance)); + $self->{components}->{fan}->{total}++; + + $self->{output}->output_add(long_msg => sprintf("Fan '%s' status is '%s' [instance: %s]", + $instance, $result->{hwDevMFanStatus}, + $instance)); + my $exit = $self->get_severity(section => 'fan', value => $result->{hwDevMFanStatus}); + if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { + $self->{output}->output_add(severity => $exit, + short_msg => sprintf("Fan '%s' status is %s", + $instance, $result->{hwDevMFanStatus})); + } + } +} + +1; \ No newline at end of file diff --git a/network/3com/snmp/mode/components/psu.pm b/network/3com/snmp/mode/components/psu.pm new file mode 100644 index 000000000..9fda71e7b --- /dev/null +++ b/network/3com/snmp/mode/components/psu.pm @@ -0,0 +1,74 @@ +# +# Copyright 2015 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +package network::3com::snmp::mode::components::psu; + +use strict; +use warnings; + +my %map_status = ( + 1 => 'active', + 2 => 'deactive', + 3 => 'not-install', + 4 => 'unsupport', +); + +# In MIB 'a3com-huawei-splat-devm' +my $mapping = { + hwDevMPowerStatus => { oid => '.1.3.6.1.4.1.43.45.1.2.23.1.9.1.2.1.2', map => \%map_status }, +}; +my $oid_hwdevMPowerStatusEntry = '.1.3.6.1.4.1.43.45.1.2.23.1.9.1.2.1'; + +sub load { + my (%options) = @_; + + push @{$options{request}}, { oid => $oid_hwdevMPowerStatusEntry }; +} + +sub check { + my ($self) = @_; + + $self->{output}->output_add(long_msg => "Checking power supplies"); + $self->{components}->{psu} = {name => 'psus', total => 0, skip => 0}; + return if ($self->check_filter(section => 'psu')); + + foreach my $oid ($self->{snmp}->oid_lex_sort(keys %{$self->{results}->{$oid_hwdevMPowerStatusEntry}})) { + next if ($oid !~ /^$mapping->{hwDevMPowerStatus}->{oid}\.(.*)$/); + my $instance = $1; + my $result = $self->{snmp}->map_instance(mapping => $mapping, results => $self->{results}->{$oid_hwdevMPowerStatusEntry}, instance => $instance); + + next if ($result->{hwDevMPowerStatus} =~ /not-install/i && + $self->absent_problem(section => 'psu', instance => $instance)); + next if ($self->check_filter(section => 'psu', instance => $instance)); + $self->{components}->{psu}->{total}++; + + $self->{output}->output_add(long_msg => sprintf("Power supply '%s' status is '%s' [instance: %s]", + $instance, $result->{hwDevMPowerStatus}, + $instance)); + my $exit = $self->get_severity(section => 'psu', value => $result->{hwDevMPowerStatus}); + if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { + $self->{output}->output_add(severity => $exit, + short_msg => sprintf("Power supply '%s' status is %s", + $instance, $result->{hwDevMPowerStatus})); + } + } +} + +1; \ No newline at end of file diff --git a/network/3com/snmp/mode/cpu.pm b/network/3com/snmp/mode/cpu.pm new file mode 100644 index 000000000..71e7df6fe --- /dev/null +++ b/network/3com/snmp/mode/cpu.pm @@ -0,0 +1,229 @@ +# +# Copyright 2015 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +package network::3com::snmp::mode::cpu; + +use base qw(centreon::plugins::mode); + +use strict; +use warnings; +use centreon::plugins::values; + +my $instance_mode; + +my $maps_counters = { + cpu => { + '000_5s' => { + set => { + key_values => [ { name => 'usage_5s' }, { name => 'display' } ], + output_template => '%s %% (5sec)', output_error_template => "%s (5sec)", + perfdatas => [ + { label => 'cpu_5s', value => 'usage_5s_absolute', template => '%d', + unit => '%', min => 0, max => 100 }, + ], + }, + }, + '001_1m' => { + set => { + key_values => [ { name => 'usage_1m' }, { name => 'display' } ], + output_template => '%s %% (1m)', output_error_template => "%s (1min)", + perfdatas => [ + { label => 'cpu_1m', value => 'usage_1m_absolute', template => '%d', + unit => '%', min => 0, max => 100 }, + ], + }, + }, + '002_5m' => { + set => { + key_values => [ { name => 'usage_5m' }, { name => 'display' } ], + output_template => '%s %% (5min)', output_error_template => "%s (5min)", + perfdatas => [ + { label => 'cpu_5m', value => 'usage_5m_absolute', template => '%d', + unit => '%', min => 0, max => 100 }, + ], + }, + }, + } +}; + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => + { + }); + + foreach my $key (('cpu')) { + foreach (keys %{$maps_counters->{$key}}) { + my ($id, $name) = split /_/; + if (!defined($maps_counters->{$key}->{$_}->{threshold}) || $maps_counters->{$key}->{$_}->{threshold} != 0) { + $options{options}->add_options(arguments => { + 'warning-' . $name . ':s' => { name => 'warning-' . $name }, + 'critical-' . $name . ':s' => { name => 'critical-' . $name }, + }); + } + $maps_counters->{$key}->{$_}->{obj} = centreon::plugins::values->new(output => $self->{output}, perfdata => $self->{perfdata}, + label => $name); + $maps_counters->{$key}->{$_}->{obj}->set(%{$maps_counters->{$key}->{$_}->{set}}); + } + } + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::init(%options); + + foreach my $key (('cpu')) { + foreach (keys %{$maps_counters->{$key}}) { + $maps_counters->{$key}->{$_}->{obj}->init(option_results => $self->{option_results}); + } + } + $instance_mode = $self; +} + +sub run_instances { + my ($self, %options) = @_; + + my $multiple = 1; + if (scalar(keys %{$self->{cpu}}) == 1) { + $multiple = 0; + } + + if ($multiple == 1) { + $self->{output}->output_add(severity => 'OK', + short_msg => 'All CPU usages are ok'); + } + + foreach my $id (sort keys %{$self->{cpu}}) { + my ($short_msg, $short_msg_append, $long_msg, $long_msg_append) = ('', '', '', ''); + my @exits = (); + foreach (sort keys %{$maps_counters->{cpu}}) { + my $obj = $maps_counters->{cpu}->{$_}->{obj}; + $obj->set(instance => $id); + + my ($value_check) = $obj->execute(values => $self->{cpu}->{$id}); + + if ($value_check != 0) { + $long_msg .= $long_msg_append . $obj->output_error(); + $long_msg_append = ', '; + next; + } + my $exit2 = $obj->threshold_check(); + push @exits, $exit2; + + my $output = $obj->output(); + $long_msg .= $long_msg_append . $output; + $long_msg_append = ', '; + + if (!$self->{output}->is_status(litteral => 1, value => $exit2, compare => 'ok')) { + $short_msg .= $short_msg_append . $output; + $short_msg_append = ', '; + } + + $obj->perfdata(extra_instance => $multiple); + } + + my $prefix = "CPU Usage "; + if ($multiple == 1) { + $prefix = sprintf("CPU '%s' Usage ", $self->{cpu}->{$id}->{display}); + } + $self->{output}->output_add(long_msg => "${prefix}$long_msg"); + my $exit = $self->{output}->get_most_critical(status => [ @exits ]); + if (!$self->{output}->is_status(litteral => 1, value => $exit, compare => 'ok')) { + $self->{output}->output_add(severity => $exit, + short_msg => "${prefix}$short_msg" + ); + } + + if ($multiple == 0) { + $self->{output}->output_add(short_msg => "${prefix}$long_msg"); + } + } +} + +sub run { + my ($self, %options) = @_; + + $self->manage_selection(%options); + $self->run_instances(); + + $self->{output}->display(); + $self->{output}->exit(); +} + +my $mapping = { + hwCpuCostRate => { oid => '.1.3.6.1.4.1.43.45.1.6.1.1.1.2' }, + hwCpuCostRatePer1Min => { oid => '.1.3.6.1.4.1.43.45.1.6.1.1.1.3' }, + hwCpuCostRatePer5Min => { oid => '.1.3.6.1.4.1.43.45.1.6.1.1.1.4' }, +}; + +sub manage_selection { + my ($self, %options) = @_; + + # a3com-huawei-splat-devm.mib + my $oid_hwCpuEntry = '.1.3.6.1.4.1.43.45.1.6.1.1.1'; + my $results = $options{snmp}->get_table(oid => $oid_hwCpuEntry, nothing_quit => 1); + $self->{cpu} = {}; + foreach my $oid (keys %{$results}) { + next if ($oid !~ /^$mapping->{hwCpuCostRatePer5Min}->{oid}\.(.*)/); + my $instance = $1; + my $result = $options{snmp}->map_instance(mapping => $mapping, results => $results, instance => $instance); + + $self->{cpu}->{$instance} = { display => $instance, + usage_5s => $result->{hwCpuCostRate}, + usage_1m => $result->{hwCpuCostRatePer1Min}, + usage_5m => $result->{hwCpuCostRatePer5Min}, + }; + } + + if (scalar(keys %{$self->{cpu}}) <= 0) { + $self->{output}->add_option_msg(short_msg => "No entry found."); + $self->{output}->option_exit(); + } +} + +1; + +__END__ + +=head1 MODE + +Check cpu usages. + +=over 8 + +=item B<--warning-*> + +Threshold warning. +Can be: '5s', '1m', '5m'. + +=item B<--critical-*> + +Threshold critical. +Can be: '5s', '1m', '5m'. + +=back + +=cut diff --git a/network/3com/snmp/mode/hardware.pm b/network/3com/snmp/mode/hardware.pm new file mode 100644 index 000000000..a4bb080b3 --- /dev/null +++ b/network/3com/snmp/mode/hardware.pm @@ -0,0 +1,275 @@ +# +# Copyright 2015 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +package network::3com::snmp::mode::hardware; + +use base qw(centreon::plugins::mode); + +use strict; +use warnings; +use centreon::plugins::misc; + +my $thresholds = { + fan => [ + ['active', 'OK'], + ['deactive', 'CRITICAL'], + ['not-install', 'OK'], + ['unsupport', 'WARNING'], + ], + psu => [ + ['active', 'OK'], + ['deactive', 'CRITICAL'], + ['not-install', 'OK'], + ['unsupport', 'WARNING'], + ], +}; + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => + { + "filter:s@" => { name => 'filter' }, + "absent-problem:s@" => { name => 'absent_problem' }, + "component:s" => { name => 'component', default => '.*' }, + "no-component:s" => { name => 'no_component' }, + "threshold-overload:s@" => { name => 'threshold_overload' }, + }); + + $self->{components} = {}; + $self->{no_components} = undef; + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::init(%options); + + if (defined($self->{option_results}->{no_component})) { + if ($self->{option_results}->{no_component} ne '') { + $self->{no_components} = $self->{option_results}->{no_component}; + } else { + $self->{no_components} = 'critical'; + } + } + + $self->{filter} = []; + foreach my $val (@{$self->{option_results}->{filter}}) { + next if (!defined($val) || $val eq ''); + my @values = split (/,/, $val); + push @{$self->{filter}}, { filter => $values[0], instance => $values[1] }; + } + + $self->{absent_problem} = []; + foreach my $val (@{$self->{option_results}->{absent_problem}}) { + next if (!defined($val) || $val eq ''); + my @values = split (/,/, $val); + push @{$self->{absent_problem}}, { filter => $values[0], instance => $values[1] }; + } + + $self->{overload_th} = {}; + foreach my $val (@{$self->{option_results}->{threshold_overload}}) { + next if (!defined($val) || $val eq ''); + my @values = split (/,/, $val); + if (scalar(@values) < 3) { + $self->{output}->add_option_msg(short_msg => "Wrong threshold-overload option '" . $val . "'."); + $self->{output}->option_exit(); + } + my ($section, $instance, $status, $filter); + if (scalar(@values) == 3) { + ($section, $status, $filter) = @values; + $instance = '.*'; + } else { + ($section, $instance, $status, $filter) = @values; + } + if ($section !~ /^psu|fan$/) { + $self->{output}->add_option_msg(short_msg => "Wrong threshold-overload section '" . $val . "'."); + $self->{output}->option_exit(); + } + if ($self->{output}->is_litteral_status(status => $status) == 0) { + $self->{output}->add_option_msg(short_msg => "Wrong threshold-overload status '" . $val . "'."); + $self->{output}->option_exit(); + } + $self->{overload_th}->{$section} = [] if (!defined($self->{overload_th}->{$section})); + push @{$self->{overload_th}->{$section}}, {filter => $filter, status => $status, instance => $instance }; + } +} + +sub run { + my ($self, %options) = @_; + $self->{snmp} = $options{snmp}; + + my $snmp_request = []; + my @components = ('psu', 'fan'); + foreach (@components) { + if (/$self->{option_results}->{component}/) { + my $mod_name = "network::3com::snmp::mode::components::$_"; + centreon::plugins::misc::mymodule_load(output => $self->{output}, module => $mod_name, + error_msg => "Cannot load module '$mod_name'."); + my $func = $mod_name->can('load'); + $func->(request => $snmp_request); + } + } + + if (scalar(@{$snmp_request}) == 0) { + $self->{output}->add_option_msg(short_msg => "Wrong option. Cannot find component '" . $self->{option_results}->{component} . "'."); + $self->{output}->option_exit(); + } + $self->{results} = $self->{snmp}->get_multiple_table(oids => $snmp_request); + + foreach (@components) { + if (/$self->{option_results}->{component}/) { + my $mod_name = "network::3com::snmp::mode::components::$_"; + my $func = $mod_name->can('check'); + $func->($self); + } + } + + my $total_components = 0; + my $display_by_component = ''; + my $display_by_component_append = ''; + foreach my $comp (sort(keys %{$self->{components}})) { + # Skipping short msg when no components + next if ($self->{components}->{$comp}->{total} == 0 && $self->{components}->{$comp}->{skip} == 0); + $total_components += $self->{components}->{$comp}->{total} + $self->{components}->{$comp}->{skip}; + my $count_by_components = $self->{components}->{$comp}->{total} + $self->{components}->{$comp}->{skip}; + $display_by_component .= $display_by_component_append . $self->{components}->{$comp}->{total} . '/' . $count_by_components . ' ' . $self->{components}->{$comp}->{name}; + $display_by_component_append = ', '; + } + + $self->{output}->output_add(severity => 'OK', + short_msg => sprintf("All %s components are ok [%s].", + $total_components, + $display_by_component) + ); + + if (defined($self->{option_results}->{no_component}) && $total_components == 0) { + $self->{output}->output_add(severity => $self->{no_components}, + short_msg => 'No components are checked.'); + } + + $self->{output}->display(); + $self->{output}->exit(); +} + +sub absent_problem { + my ($self, %options) = @_; + + foreach (@{$self->{absent_problem}}) { + if ($options{section} =~ /$_->{filter}/) { + if (!defined($_->{instance}) || $options{instance} =~ /$_->{instance}/) { + $self->{output}->output_add(severity => 'CRITICAL', + short_msg => sprintf("Component '%s' instance '%s' is not present", + $options{section}, $options{instance})); + $self->{output}->output_add(long_msg => sprintf("Skipping $options{section} section $options{instance} instance (not present)")); + $self->{components}->{$options{section}}->{skip}++; + return 1; + } + } + } + + return 0; +} + +sub check_filter { + my ($self, %options) = @_; + + foreach (@{$self->{filter}}) { + if ($options{section} =~ /$_->{filter}/) { + if (!defined($options{instance}) && !defined($_->{instance})) { + $self->{output}->output_add(long_msg => sprintf("Skipping $options{section} section.")); + return 1; + } elsif (defined($options{instance}) && $options{instance} =~ /$_->{instance}/) { + $self->{output}->output_add(long_msg => sprintf("Skipping $options{section} section $options{instance} instance.")); + return 1; + } + } + } + + return 0; +} + +sub get_severity { + my ($self, %options) = @_; + my $status = 'UNKNOWN'; # default + + if (defined($self->{overload_th}->{$options{section}})) { + foreach (@{$self->{overload_th}->{$options{section}}}) { + if ($options{value} =~ /$_->{filter}/i && + (!defined($options{instance}) || $options{instance} =~ /$_->{instance}/)) { + $status = $_->{status}; + return $status; + } + } + } + my $label = defined($options{label}) ? $options{label} : $options{section}; + foreach (@{$thresholds->{$label}}) { + if ($options{value} =~ /$$_[0]/i) { + $status = $$_[1]; + return $status; + } + } + + return $status; +} + +1; + +__END__ + +=head1 MODE + +Check Hardware (Power Supply, Fan). + +=over 8 + +=item B<--component> + +Which component to check (Default: '.*'). +Can be: 'fan', 'psu'. + +=item B<--filter> + +Exclude some parts (comma seperated list) (Example: --filter=fan) +Can also exclude specific instance: --filter=fan,1 + +=item B<--absent-problem> + +Return an error if an entity is not 'present' (default is skipping) (comma seperated list) +Can be specific or global: --absent-problem=fan,2 + +=item B<--no-component> + +Return an error if no compenents are checked. +If total (with skipped) is 0. (Default: 'critical' returns). + +=item B<--threshold-overload> + +Set to overload default threshold values (syntax: section,[instance,]status,regexp) +It used before default thresholds (order stays). +Example: --threshold-overload='fan,CRITICAL,^(?!(active)$)' + +=back + +=cut \ No newline at end of file diff --git a/network/3com/snmp/mode/memory.pm b/network/3com/snmp/mode/memory.pm new file mode 100644 index 000000000..d0e92264b --- /dev/null +++ b/network/3com/snmp/mode/memory.pm @@ -0,0 +1,250 @@ +# +# Copyright 2015 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +package network::3com::snmp::mode::memory; + +use base qw(centreon::plugins::mode); + +use strict; +use warnings; +use centreon::plugins::values; + +my $instance_mode; + +my $maps_counters = { + mem => { + '000_usage' => { + set => { + key_values => [ { name => 'display' }, { name => 'total' }, { name => 'used' } ], + closure_custom_calc => \&custom_usage_calc, + closure_custom_output => \&custom_usage_output, + closure_custom_perfdata => \&custom_usage_perfdata, + closure_custom_threshold_check => \&custom_usage_threshold, + }, + }, + } +}; + +sub custom_usage_perfdata { + my ($self, %options) = @_; + + my $extra_label = ''; + if (!defined($options{extra_instance}) || $options{extra_instance} != 0) { + $extra_label .= '_' . $self->{result_values}->{display}; + } + $self->{output}->perfdata_add(label => 'used' . $extra_label, unit => 'B', + value => $self->{result_values}->{used}, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{label}, total => $self->{result_values}->{total}, cast_int => 1), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{label}, total => $self->{result_values}->{total}, cast_int => 1), + min => 0, max => $self->{result_values}->{total}); +} + +sub custom_usage_threshold { + my ($self, %options) = @_; + + my $exit = $self->{perfdata}->threshold_check(value => $self->{result_values}->{prct_used}, threshold => [ { label => 'critical-' . $self->{label}, exit_litteral => 'critical' }, { label => 'warning-' . $self->{label}, exit_litteral => 'warning' } ]); + return $exit; +} + +sub custom_usage_output { + my ($self, %options) = @_; + + my ($total_size_value, $total_size_unit) = $self->{perfdata}->change_bytes(value => $self->{result_values}->{total}); + my ($total_used_value, $total_used_unit) = $self->{perfdata}->change_bytes(value => $self->{result_values}->{used}); + my ($total_free_value, $total_free_unit) = $self->{perfdata}->change_bytes(value => $self->{result_values}->{free}); + + my $msg = sprintf("Total: %s Used: %s (%.2f%%) Free: %s (%.2f%%)", + $total_size_value . " " . $total_size_unit, + $total_used_value . " " . $total_used_unit, $self->{result_values}->{prct_used}, + $total_free_value . " " . $total_free_unit, $self->{result_values}->{prct_free}); + return $msg; +} + +sub custom_usage_calc { + my ($self, %options) = @_; + + $self->{result_values}->{display} = $options{new_datas}->{$self->{instance} . '_display'}; + $self->{result_values}->{total} = $options{new_datas}->{$self->{instance} . '_total'}; + $self->{result_values}->{used} = $options{new_datas}->{$self->{instance} . '_used'}; + $self->{result_values}->{free} = $self->{result_values}->{total} - $self->{result_values}->{used}; + $self->{result_values}->{prct_free} = $self->{result_values}->{free} * 100 / $self->{result_values}->{total}; + $self->{result_values}->{prct_used} = $self->{result_values}->{used} * 100 / $self->{result_values}->{total}; + return 0; +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => + { + }); + + foreach my $key (('mem')) { + foreach (keys %{$maps_counters->{$key}}) { + my ($id, $name) = split /_/; + if (!defined($maps_counters->{$key}->{$_}->{threshold}) || $maps_counters->{$key}->{$_}->{threshold} != 0) { + $options{options}->add_options(arguments => { + 'warning-' . $name . ':s' => { name => 'warning-' . $name }, + 'critical-' . $name . ':s' => { name => 'critical-' . $name }, + }); + } + $maps_counters->{$key}->{$_}->{obj} = centreon::plugins::values->new(output => $self->{output}, perfdata => $self->{perfdata}, + label => $name); + $maps_counters->{$key}->{$_}->{obj}->set(%{$maps_counters->{$key}->{$_}->{set}}); + } + } + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::init(%options); + + foreach my $key (('mem')) { + foreach (keys %{$maps_counters->{$key}}) { + $maps_counters->{$key}->{$_}->{obj}->init(option_results => $self->{option_results}); + } + } + $instance_mode = $self; +} + +sub run_instances { + my ($self, %options) = @_; + + my $multiple = 1; + if (scalar(keys %{$self->{mem}}) == 1) { + $multiple = 0; + } + + if ($multiple == 1) { + $self->{output}->output_add(severity => 'OK', + short_msg => 'All memory usages are ok'); + } + + foreach my $id (sort keys %{$self->{mem}}) { + my ($short_msg, $short_msg_append, $long_msg, $long_msg_append) = ('', '', '', ''); + my @exits = (); + foreach (sort keys %{$maps_counters->{mem}}) { + my $obj = $maps_counters->{mem}->{$_}->{obj}; + $obj->set(instance => $id); + + my ($value_check) = $obj->execute(values => $self->{mem}->{$id}); + + if ($value_check != 0) { + $long_msg .= $long_msg_append . $obj->output_error(); + $long_msg_append = ', '; + next; + } + my $exit2 = $obj->threshold_check(); + push @exits, $exit2; + + my $output = $obj->output(); + $long_msg .= $long_msg_append . $output; + $long_msg_append = ', '; + + if (!$self->{output}->is_status(litteral => 1, value => $exit2, compare => 'ok')) { + $short_msg .= $short_msg_append . $output; + $short_msg_append = ', '; + } + + $obj->perfdata(extra_instance => $multiple); + } + + my $prefix = ''; + if ($multiple == 1) { + $prefix = sprintf("Memory '%s' ", $self->{mem}->{$id}->{display}); + } + $self->{output}->output_add(long_msg => "${prefix}$long_msg"); + my $exit = $self->{output}->get_most_critical(status => [ @exits ]); + if (!$self->{output}->is_status(litteral => 1, value => $exit, compare => 'ok')) { + $self->{output}->output_add(severity => $exit, + short_msg => "${prefix}$short_msg" + ); + } + + if ($multiple == 0) { + $self->{output}->output_add(short_msg => "${prefix}$long_msg"); + } + } +} + +sub run { + my ($self, %options) = @_; + + $self->manage_selection(%options); + $self->run_instances(); + + $self->{output}->display(); + $self->{output}->exit(); +} + +my $mapping = { + hwMemSize => { oid => '.1.3.6.1.4.1.43.45.1.6.1.2.1.1.2' }, + hwMemFree => { oid => '.1.3.6.1.4.1.43.45.1.6.1.2.1.1.3' }, +}; + +sub manage_selection { + my ($self, %options) = @_; + + # a3com-huawei-splat-devm.mib + my $oid_hwMemEntry = '.1.3.6.1.4.1.43.45.1.6.1.2.1.1'; + my $results = $options{snmp}->get_table(oid => $oid_hwMemEntry, nothing_quit => 1); + $self->{mem} = {}; + foreach my $oid (keys %{$results}) { + next if ($oid !~ /^$mapping->{hwMemSize}->{oid}\.(.*)/); + my $instance = $1; + my $result = $options{snmp}->map_instance(mapping => $mapping, results => $results, instance => $instance); + + my $total = $result->{hwMemSize}; + my $used = $result->{hwMemSize} - $result->{hwMemFree}; + $self->{mem}->{$instance} = { display => $instance, used => $used, total => $total }; + } + + if (scalar(keys %{$self->{mem}}) <= 0) { + $self->{output}->add_option_msg(short_msg => "No entry found."); + $self->{output}->option_exit(); + } +} + +1; + +__END__ + +=head1 MODE + +Check memory usages. + +=over 8 + +=item B<--warning-usage> + +Threshold warning (in percent). + +=item B<--critical-usage> + +Threshold critical (in percent). + +=back + +=cut diff --git a/network/3com/snmp/plugin.pm b/network/3com/snmp/plugin.pm new file mode 100644 index 000000000..132c0a2ff --- /dev/null +++ b/network/3com/snmp/plugin.pm @@ -0,0 +1,52 @@ +# +# Copyright 2015 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +package network::3com::snmp::plugin; + +use strict; +use warnings; +use base qw(centreon::plugins::script_snmp); + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $self->{version} = '1.0'; + %{$self->{modes}} = ( + 'cpu' => 'network::3com::snmp::mode::cpu', + 'hardware' => 'network::3com::snmp::mode::hardware', + 'interfaces' => 'snmp_standard::mode::interfaces', + 'list-interfaces' => 'snmp_standard::mode::listinterfaces', + 'memory' => 'network::3com::snmp::mode::memory', + ); + + return $self; +} + +1; + +__END__ + +=head1 PLUGIN DESCRIPTION + +Check 3com equipment (old legacy. Maybe you should use 'network::h3c' plugin) in SNMP. + +=cut diff --git a/network/alcatel/common/mode/hardware.pm b/network/alcatel/common/mode/hardware.pm index 50cd3fe8e..182c0794e 100644 --- a/network/alcatel/common/mode/hardware.pm +++ b/network/alcatel/common/mode/hardware.pm @@ -118,7 +118,8 @@ sub component { # Skipping short msg when no components next if ($self->{components}->{$comp}->{total} == 0 && $self->{components}->{$comp}->{skip} == 0); $total_components += $self->{components}->{$comp}->{total} + $self->{components}->{$comp}->{skip}; - $display_by_component .= $display_by_component_append . $self->{components}->{$comp}->{total} . '/' . $self->{components}->{$comp}->{skip} . ' ' . $self->{components}->{$comp}->{name}; + my $count_by_components = $self->{components}->{$comp}->{total} + $self->{components}->{$comp}->{skip}; + $display_by_component .= $display_by_component_append . $self->{components}->{$comp}->{total} . '/' . $count_by_components . ' ' . $self->{components}->{$comp}->{name}; $display_by_component_append = ', '; } @@ -199,4 +200,4 @@ If total (with skipped) is 0. (Default: 'critical' returns). =back -=cut \ No newline at end of file +=cut diff --git a/network/bluecoat/snmp/mode/components/disk.pm b/network/bluecoat/snmp/mode/components/disk.pm index c8f429993..bf0127b44 100644 --- a/network/bluecoat/snmp/mode/components/disk.pm +++ b/network/bluecoat/snmp/mode/components/disk.pm @@ -61,7 +61,7 @@ sub check { my $instance = $1; my $result = $self->{snmp}->map_instance(mapping => $mapping, results => $self->{results}->{$oid_deviceDiskValueEntry}, instance => $instance); - next if ($result->{deviceDiskStatus} !~ /notpresent/i && + next if ($result->{deviceDiskStatus} =~ /notpresent/i && $self->absent_problem(section => 'disk', instance => $instance)); next if ($self->check_filter(section => 'disk', instance => $instance)); $self->{components}->{disk}->{total}++; @@ -72,7 +72,7 @@ sub check { my $exit = $self->get_severity(section => 'disk', value => $result->{deviceDiskStatus}); if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { $self->{output}->output_add(severity => $exit, - short_msg => sprintf("Sensor '%s' operational status is %s", + short_msg => sprintf("Disk '%s' status is %s", $result->{deviceDiskSerialN}, $result->{deviceDiskStatus})); } } diff --git a/network/citrix/netscaler/common/mode/connections.pm b/network/citrix/netscaler/common/mode/connections.pm new file mode 100644 index 000000000..91e250130 --- /dev/null +++ b/network/citrix/netscaler/common/mode/connections.pm @@ -0,0 +1,189 @@ +# +# Copyright 2015 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +package network::citrix::netscaler::common::mode::connections; + +use base qw(centreon::plugins::mode); + +use strict; +use warnings; +use centreon::plugins::values; + +my $maps_counters = { + global => { + '000_active' => { set => { + key_values => [ { name => 'active' } ], + output_template => 'Active Server TCP connections : %s', + perfdatas => [ + { label => 'active_server', value => 'active_absolute', template => '%s', + unit => 'con', min => 0 }, + ], + } + }, + '001_server' => { set => { + key_values => [ { name => 'server' } ], + output_template => 'Server TCP connections : %s', + perfdatas => [ + { label => 'server', value => 'server_absolute', template => '%s', + unit => 'con', min => 0 }, + ], + } + }, + '002_client' => { set => { + key_values => [ { name => 'client' } ], + output_template => 'Client TCP connections : %s', + perfdatas => [ + { label => 'client', value => 'client_absolute', template => '%s', + unit => 'con', min => 0 }, + ], + } + }, + }, +}; + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => + { + }); + + foreach my $key (('global')) { + foreach (keys %{$maps_counters->{$key}}) { + my ($id, $name) = split /_/; + if (!defined($maps_counters->{$key}->{$_}->{threshold}) || $maps_counters->{$key}->{$_}->{threshold} != 0) { + $options{options}->add_options(arguments => { + 'warning-' . $name . ':s' => { name => 'warning-' . $name }, + 'critical-' . $name . ':s' => { name => 'critical-' . $name }, + }); + } + $maps_counters->{$key}->{$_}->{obj} = centreon::plugins::values->new(output => $self->{output}, + perfdata => $self->{perfdata}, + label => $name); + $maps_counters->{$key}->{$_}->{obj}->set(%{$maps_counters->{$key}->{$_}->{set}}); + } + } + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::init(%options); + + foreach my $key (('global')) { + foreach (keys %{$maps_counters->{$key}}) { + $maps_counters->{$key}->{$_}->{obj}->init(option_results => $self->{option_results}); + } + } +} + +sub run_global { + my ($self, %options) = @_; + + my ($short_msg, $short_msg_append, $long_msg, $long_msg_append) = ('', '', '', ''); + my @exits; + foreach (sort keys %{$maps_counters->{global}}) { + my $obj = $maps_counters->{global}->{$_}->{obj}; + + $obj->set(instance => 'global'); + + my ($value_check) = $obj->execute(values => $self->{global}); + + if ($value_check != 0) { + $long_msg .= $long_msg_append . $obj->output_error(); + $long_msg_append = ', '; + next; + } + my $exit2 = $obj->threshold_check(); + push @exits, $exit2; + + my $output = $obj->output(); + $long_msg .= $long_msg_append . $output; + $long_msg_append = ', '; + + if (!$self->{output}->is_status(litteral => 1, value => $exit2, compare => 'ok')) { + $short_msg .= $short_msg_append . $output; + $short_msg_append = ', '; + } + + $obj->perfdata(); + } + + my $exit = $self->{output}->get_most_critical(status => [ @exits ]); + if (!$self->{output}->is_status(litteral => 1, value => $exit, compare => 'ok')) { + $self->{output}->output_add(severity => $exit, + short_msg => "$short_msg" + ); + } else { + $self->{output}->output_add(short_msg => "$long_msg"); + } +} + +sub run { + my ($self, %options) = @_; + $self->{snmp} = $options{snmp}; + + $self->manage_selection(); + $self->run_global(); + + $self->{output}->display(); + $self->{output}->exit(); +} + +sub manage_selection { + my ($self, %options) = @_; + + $self->{global} = { client => 0, server => 0, active => 0 }; + my $oid_tcpCurServerConn = '.1.3.6.1.4.1.5951.4.1.1.46.1.0'; + my $oid_tcpCurClientConn = '.1.3.6.1.4.1.5951.4.1.1.46.2.0'; + my $oid_tcpActiveServerConn = '.1.3.6.1.4.1.5951.4.1.1.46.8.0'; + my $result = $self->{snmp}->get_leef(oids => [$oid_tcpCurServerConn, $oid_tcpCurClientConn, $oid_tcpActiveServerConn ], nothing_quit => 1); + $self->{global}->{client} = $result->{$oid_tcpCurClientConn}; + $self->{global}->{server} = $result->{$oid_tcpCurServerConn}; + $self->{global}->{active} = $result->{$oid_tcpActiveServerConn}; +} + +1; + +__END__ + +=head1 MODE + +Check connections usage (Client, Server, ActiveServer) (NS-ROOT-MIBv2). + +=over 8 + +=item B<--warning-*> + +Threshold warning. +Can be: 'server', 'active', 'client'. + +=item B<--critical-*> + +Threshold critical. +Can be: 'server', 'active', 'client'. + +=back + +=cut \ No newline at end of file diff --git a/network/citrix/netscaler/mpx8000/plugin.pm b/network/citrix/netscaler/mpx8000/plugin.pm index 960a164c3..4cb21ae51 100644 --- a/network/citrix/netscaler/mpx8000/plugin.pm +++ b/network/citrix/netscaler/mpx8000/plugin.pm @@ -42,6 +42,7 @@ sub new { 'list-vservers' => 'network::citrix::netscaler::common::mode::listvservers', 'vserver-status' => 'network::citrix::netscaler::common::mode::vserverstatus', 'memory' => 'network::citrix::netscaler::common::mode::memory', + 'connections' => 'network::citrix::netscaler::common::mode::connections', ); return $self; diff --git a/network/digi/portserverts/snmp/mode/cpu.pm b/network/digi/portserverts/snmp/mode/cpu.pm new file mode 100644 index 000000000..00929cd18 --- /dev/null +++ b/network/digi/portserverts/snmp/mode/cpu.pm @@ -0,0 +1,100 @@ +# +# Copyright 2015 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +package network::digi::portserverts::snmp::mode::cpu; + +use base qw(centreon::plugins::mode); + +use strict; +use warnings; + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => + { + "warning:s" => { name => 'warning' }, + "critical:s" => { name => 'critical' }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::init(%options); + + if (($self->{perfdata}->threshold_validate(label => 'warning', value => $self->{option_results}->{warning})) == 0) { + $self->{output}->add_option_msg(short_msg => "Wrong warning threshold '" . $self->{option_results}->{warning} . "'."); + $self->{output}->option_exit(); + } + if (($self->{perfdata}->threshold_validate(label => 'critical', value => $self->{option_results}->{critical})) == 0) { + $self->{output}->add_option_msg(short_msg => "Wrong critical threshold '" . $self->{option_results}->{critical} . "'."); + $self->{output}->option_exit(); + } +} + +sub run { + my ($self, %options) = @_; + $self->{snmp} = $options{snmp}; + + # Between 0 and 255 (don't know why you can value over 100) + my $oid_processorCurrentUtilization = '.1.3.6.1.4.1.332.11.5.3.3.21.11.0'; + my $result = $self->{snmp}->get_leef(oids => [$oid_processorCurrentUtilization], nothing_quit => 1); + + my $exit = $self->{perfdata}->threshold_check(value => $result->{$oid_processorCurrentUtilization}, + threshold => [ { label => 'critical', exit_litteral => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]); + $self->{output}->output_add(severity => $exit, + short_msg => sprintf("CPU Usage : %.2f", $result->{$oid_processorCurrentUtilization})); + $self->{output}->perfdata_add(label => "cpu", + value => $result->{$oid_processorCurrentUtilization}, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning'), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical'), + min => 0); + + $self->{output}->display(); + $self->{output}->exit(); +} + +1; + +__END__ + +=head1 MODE + +Check current processor usage. + +=over 8 + +=item B<--warning> + +Threshold warning. + +=item B<--critical> + +Threshold critical. + +=back + +=cut + \ No newline at end of file diff --git a/network/digi/portserverts/snmp/mode/memory.pm b/network/digi/portserverts/snmp/mode/memory.pm new file mode 100644 index 000000000..b04a2172c --- /dev/null +++ b/network/digi/portserverts/snmp/mode/memory.pm @@ -0,0 +1,204 @@ +# +# Copyright 2015 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +package network::digi::portserverts::snmp::mode::memory; + +use base qw(centreon::plugins::mode); + +use strict; +use warnings; +use centreon::plugins::values; + +my $maps_counters = { + global => { + '000_usage' => { set => { + key_values => [ { name => 'free' }, { name => 'total' } ], + closure_custom_calc => \&custom_usage_calc, + closure_custom_output => \&custom_usage_output, + closure_custom_perfdata => \&custom_usage_perfdata, + closure_custom_threshold_check => \&custom_usage_threshold, + } + }, + }, +}; + +sub custom_usage_perfdata { + my ($self, %options) = @_; + + $self->{output}->perfdata_add(label => 'used', unit => 'B', + value => $self->{result_values}->{used}, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{label}, total => $self->{result_values}->{total}, cast_int => 1), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{label}, total => $self->{result_values}->{total}, cast_int => 1), + min => 0, max => $self->{result_values}->{total}); +} + +sub custom_usage_threshold { + my ($self, %options) = @_; + + my $exit = $self->{perfdata}->threshold_check(value => $self->{result_values}->{prct_used}, threshold => [ { label => 'critical-' . $self->{label}, exit_litteral => 'critical' }, { label => 'warning-' . $self->{label}, exit_litteral => 'warning' } ]); + return $exit; +} + +sub custom_usage_output { + my ($self, %options) = @_; + + my ($total_size_value, $total_size_unit) = $self->{perfdata}->change_bytes(value => $self->{result_values}->{total}); + my ($total_used_value, $total_used_unit) = $self->{perfdata}->change_bytes(value => $self->{result_values}->{used}); + my ($total_free_value, $total_free_unit) = $self->{perfdata}->change_bytes(value => $self->{result_values}->{free}); + + my $msg = sprintf("Memory Usage Total: %s Used: %s (%.2f%%) Free: %s (%.2f%%)", + $total_size_value . " " . $total_size_unit, + $total_used_value . " " . $total_used_unit, $self->{result_values}->{prct_used}, + $total_free_value . " " . $total_free_unit, $self->{result_values}->{prct_free}); + return $msg; +} + +sub custom_usage_calc { + my ($self, %options) = @_; + + $self->{result_values}->{total} = $options{new_datas}->{$self->{instance} . '_total'}; + $self->{result_values}->{used} = $options{new_datas}->{$self->{instance} . '_total'} - $options{new_datas}->{$self->{instance} . '_free'}; + $self->{result_values}->{free} = $options{new_datas}->{$self->{instance} . '_free'}; + $self->{result_values}->{prct_free} = $self->{result_values}->{free} * 100 / $self->{result_values}->{total}; + $self->{result_values}->{prct_used} = $self->{result_values}->{used} * 100 / $self->{result_values}->{total}; + return 0; +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => + { + }); + + foreach my $key (('global')) { + foreach (keys %{$maps_counters->{$key}}) { + my ($id, $name) = split /_/; + if (!defined($maps_counters->{$key}->{$_}->{threshold}) || $maps_counters->{$key}->{$_}->{threshold} != 0) { + $options{options}->add_options(arguments => { + 'warning-' . $name . ':s' => { name => 'warning-' . $name }, + 'critical-' . $name . ':s' => { name => 'critical-' . $name }, + }); + } + $maps_counters->{$key}->{$_}->{obj} = centreon::plugins::values->new(output => $self->{output}, perfdata => $self->{perfdata}, + label => $name); + $maps_counters->{$key}->{$_}->{obj}->set(%{$maps_counters->{$key}->{$_}->{set}}); + } + } + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::init(%options); + + foreach my $key (('global')) { + foreach (keys %{$maps_counters->{$key}}) { + $maps_counters->{$key}->{$_}->{obj}->init(option_results => $self->{option_results}); + } + } +} + +sub run { + my ($self, %options) = @_; + $self->{snmp} = $options{snmp}; + + $self->manage_selection(); + + my ($short_msg, $short_msg_append, $long_msg, $long_msg_append) = ('', '', '', ''); + my @exits; + + foreach (sort keys %{$maps_counters->{global}}) { + my $obj = $maps_counters->{global}->{$_}->{obj}; + + use Data::Dumper; + Data::Dumper::Dumper($obj); + $obj->set(instance => 'global'); + + my ($value_check) = $obj->execute(values => $self->{global}); + + if ($value_check != 0) { + $long_msg .= $long_msg_append . $obj->output_error(); + $long_msg_append = ', '; + next; + } + my $exit2 = $obj->threshold_check(); + push @exits, $exit2; + + my $output = $obj->output(); + $long_msg .= $long_msg_append . $output; + $long_msg_append = ', '; + + if (!$self->{output}->is_status(litteral => 1, value => $exit2, compare => 'ok')) { + $short_msg .= $short_msg_append . $output; + $short_msg_append = ', '; + } + + $obj->perfdata(); + } + + my $exit = $self->{output}->get_most_critical(status => [ @exits ]); + if (!$self->{output}->is_status(litteral => 1, value => $exit, compare => 'ok')) { + $self->{output}->output_add(severity => $exit, + short_msg => "$short_msg" + ); + } else { + $self->{output}->output_add(short_msg => "$long_msg"); + } + + $self->{output}->display(); + $self->{output}->exit(); +} + +sub manage_selection { + my ($self, %options) = @_; + + my $oid_memoryTotalMemory = '.1.3.6.1.4.1.332.11.5.3.3.22.11.0'; + my $oid_memoryAvailable = '.1.3.6.1.4.1.332.11.5.3.3.22.12.0'; + my $result = $self->{snmp}->get_leef(oids => [$oid_memoryTotalMemory, $oid_memoryAvailable], + nothing_quit => 1); + $self->{global} = { free => $result->{$oid_memoryAvailable}, total => $result->{$oid_memoryTotalMemory} }; +} + +1; + +__END__ + +=head1 MODE + +Check memory usage. + +=over 8 + +=item B<--warning-usage> + +Threshold warning (in percent). + +=item B<--critical-usage> + +Threshold critical (in percent). + +=back + +=cut \ No newline at end of file diff --git a/network/digi/portserverts/snmp/plugin.pm b/network/digi/portserverts/snmp/plugin.pm new file mode 100644 index 000000000..bb2442365 --- /dev/null +++ b/network/digi/portserverts/snmp/plugin.pm @@ -0,0 +1,52 @@ +# +# Copyright 2015 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +package network::digi::portserverts::snmp::plugin; + +use strict; +use warnings; +use base qw(centreon::plugins::script_snmp); + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + # $options->{options} = options object + + $self->{version} = '1.0'; + %{$self->{modes}} = ( + 'cpu' => 'network::digi::portserverts::snmp::mode::cpu', + 'interfaces' => 'snmp_standard::mode::interfaces', + 'list-interfaces' => 'snmp_standard::mode::listinterfaces', + 'memory' => 'network::digi::portserverts::snmp::mode::memory', + ); + + return $self; +} + +1; + +__END__ + +=head1 PLUGIN DESCRIPTION + +Check Digi PortServer TS equipments in SNMP. + +=cut diff --git a/network/extreme/snmp/mode/cpu.pm b/network/extreme/snmp/mode/cpu.pm index 94311459b..bd8925471 100644 --- a/network/extreme/snmp/mode/cpu.pm +++ b/network/extreme/snmp/mode/cpu.pm @@ -48,7 +48,7 @@ my $maps_counters = { }, '002_30secs' => { set => { key_values => [ { name => 'extremeCpuMonitorSystemUtilization30secs' }, { name => 'num' }, ], - output_template => '10 seconds : %.2f %%', + output_template => '30 seconds : %.2f %%', perfdatas => [ { label => 'cpu_30secs', value => 'extremeCpuMonitorSystemUtilization30secs_absolute', template => '%.2f', min => 0, max => 100, unit => '%', label_extra_instance => 1, instance_use => 'num_absolute' }, @@ -57,7 +57,7 @@ my $maps_counters = { }, '003_1min' => { set => { key_values => [ { name => 'extremeCpuMonitorSystemUtilization1min' }, { name => 'num' }, ], - output_template => '10 seconds : %.2f %%', + output_template => '1 minute : %.2f %%', perfdatas => [ { label => 'cpu_1min', value => 'extremeCpuMonitorSystemUtilization1min_absolute', template => '%.2f', min => 0, max => 100, unit => '%', label_extra_instance => 1, instance_use => 'num_absolute' }, @@ -66,7 +66,7 @@ my $maps_counters = { }, '004_5min' => { set => { key_values => [ { name => 'extremeCpuMonitorSystemUtilization5mins' }, { name => 'num' }, ], - output_template => '10 seconds : %.2f %%', + output_template => '5 minutes : %.2f %%', perfdatas => [ { label => 'cpu_5min', value => 'extremeCpuMonitorSystemUtilization5mins_absolute', template => '%.2f', min => 0, max => 100, unit => '%', label_extra_instance => 1, instance_use => 'num_absolute' }, diff --git a/network/f5/bigip/mode/virtualserverstatus.pm b/network/f5/bigip/mode/virtualserverstatus.pm index 86c5116fd..390af87c1 100644 --- a/network/f5/bigip/mode/virtualserverstatus.pm +++ b/network/f5/bigip/mode/virtualserverstatus.pm @@ -52,7 +52,6 @@ my $maps_counters = { }, }; - sub custom_threshold_output { my ($self, %options) = @_; diff --git a/network/h3c/snmp/mode/components/default.pm b/network/h3c/snmp/mode/components/default.pm index 325208b3c..6be93e67d 100644 --- a/network/h3c/snmp/mode/components/default.pm +++ b/network/h3c/snmp/mode/components/default.pm @@ -57,6 +57,7 @@ sub check { foreach my $instance (sort $self->get_instance_class(class => { $options{component_class} => 1 })) { my $result = $self->{snmp}->map_instance(mapping => $mapping, results => $self->{results}->{$self->{branch} . '.19'}, instance => $instance); + next if (!defined($result->{EntityExtErrorStatus})); next if ($self->check_exclude(section => $options{component}, instance => $instance)); if ($result->{EntityExtErrorStatus} =~ /entityAbsent/i) { $self->absent_problem(section => $options{component}, instance => $instance); diff --git a/network/h3c/snmp/mode/components/fan.pm b/network/h3c/snmp/mode/components/fan.pm index 352d70cf8..a4e2b1cfb 100644 --- a/network/h3c/snmp/mode/components/fan.pm +++ b/network/h3c/snmp/mode/components/fan.pm @@ -45,6 +45,7 @@ sub check { foreach my $instance (sort $self->get_instance_class(class => { 7 => 1 })) { my $result = $self->{snmp}->map_instance(mapping => $mapping, results => $self->{results}->{$self->{branch} . '.19'}, instance => $instance); + next if (!defined($result->{EntityExtErrorStatus})); next if ($self->check_exclude(section => 'fan', instance => $instance)); if ($result->{EntityExtErrorStatus} =~ /entityAbsent/i) { $self->absent_problem(section => 'fan', instance => $instance); diff --git a/network/h3c/snmp/mode/components/psu.pm b/network/h3c/snmp/mode/components/psu.pm index d89fd0dd1..aa963bf58 100644 --- a/network/h3c/snmp/mode/components/psu.pm +++ b/network/h3c/snmp/mode/components/psu.pm @@ -45,6 +45,7 @@ sub check { foreach my $instance (sort $self->get_instance_class(class => { 6 => 1 }) ) { my $result = $self->{snmp}->map_instance(mapping => $mapping, results => $self->{results}->{$self->{branch} . '.19'}, instance => $instance); + next if (!defined($result->{EntityExtErrorStatus})); next if ($self->check_exclude(section => 'psu', instance => $instance)); if ($result->{EntityExtErrorStatus} =~ /entityAbsent/i) { $self->absent_problem(section => 'psu', instance => $instance); diff --git a/network/h3c/snmp/mode/components/sensor.pm b/network/h3c/snmp/mode/components/sensor.pm index 542dcb4fd..f6f5735c5 100644 --- a/network/h3c/snmp/mode/components/sensor.pm +++ b/network/h3c/snmp/mode/components/sensor.pm @@ -58,6 +58,7 @@ sub check { my $result = $self->{snmp}->map_instance(mapping => $mapping, results => $self->{results}->{$self->{branch} . '.19'}, instance => $instance); my $result2 = $self->{snmp}->map_instance(mapping => $mapping2, results => $results, instance => $instance); + next if (!defined($result->{EntityExtErrorStatus})); next if ($self->check_exclude(section => 'sensor', instance => $instance)); if ($result->{EntityExtErrorStatus} =~ /entityAbsent/i) { $self->absent_problem(section => 'sensor', instance => $instance); diff --git a/network/juniper/common/screenos/mode/sessions.pm b/network/juniper/common/screenos/mode/sessions.pm index 50df6a763..b529e1922 100644 --- a/network/juniper/common/screenos/mode/sessions.pm +++ b/network/juniper/common/screenos/mode/sessions.pm @@ -34,7 +34,9 @@ sub new { $options{options}->add_options(arguments => { "warning:s" => { name => 'warning', }, + "warning-failed:s" => { name => 'warning_failed', }, "critical:s" => { name => 'critical', }, + "critical-failed:s" => { name => 'critical_failed', }, }); return $self; @@ -52,6 +54,14 @@ sub check_options { $self->{output}->add_option_msg(short_msg => "Wrong critical threshold '" . $self->{option_results}->{critical} . "'."); $self->{output}->option_exit(); } + if (($self->{perfdata}->threshold_validate(label => 'warning-failed', value => $self->{option_results}->{warning_failed})) == 0) { + $self->{output}->add_option_msg(short_msg => "Wrong warning-failed threshold '" . $self->{option_results}->{warning_failed} . "'."); + $self->{output}->option_exit(); + } + if (($self->{perfdata}->threshold_validate(label => 'critical-failed', value => $self->{option_results}->{critical_failed})) == 0) { + $self->{output}->add_option_msg(short_msg => "Wrong critical-failed threshold '" . $self->{option_results}->{critical_failed} . "'."); + $self->{output}->option_exit(); + } } sub run { @@ -61,26 +71,40 @@ sub run { my $oid_nsResSessAllocate = '.1.3.6.1.4.1.3224.16.3.2.0'; my $oid_nsResSessMaxium = '.1.3.6.1.4.1.3224.16.3.3.0'; + my $oid_nsResSessFailed = '.1.3.6.1.4.1.3224.16.3.4.0'; - my $result = $self->{snmp}->get_leef(oids => [$oid_nsResSessAllocate, $oid_nsResSessMaxium], nothing_quit => 1); + my $result = $self->{snmp}->get_leef(oids => [$oid_nsResSessAllocate, $oid_nsResSessMaxium, $oid_nsResSessFailed], nothing_quit => 1); my $spu_done = 0; my $cp_total = $result->{$oid_nsResSessMaxium}; my $cp_used = $result->{$oid_nsResSessAllocate}; - + my $cp_failed = $result->{$oid_nsResSessFailed}; my $prct_used = $cp_used * 100 / $cp_total; - + my $prct_failed = $cp_failed * 100 / $cp_total; $spu_done = 1; - my $exit_code = $self->{perfdata}->threshold_check(value => $prct_used, + + my $exit_used = $self->{perfdata}->threshold_check(value => $prct_used, threshold => [ { label => 'critical', 'exit_litteral' => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]); - $self->{output}->output_add(severity => $exit_code, + my $exit_failed = $self->{perfdata}->threshold_check(value => $prct_failed, + threshold => [ { label => 'critical-failed', 'exit_litteral' => 'critical' }, { label => 'warning-failed', exit_litteral => 'warning' } ]); + + $self->{output}->output_add(severity => $exit_used, short_msg => sprintf("%.2f%% of the sessions limit reached (%d of max. %d)", $prct_used, $cp_used, $cp_total)); + $self->{output}->output_add(severity => $exit_failed, + short_msg => sprintf("%.2f%% of failed sessions (%d of max. %d)", + $prct_failed, $cp_failed, $cp_total)); + $self->{output}->perfdata_add(label => 'sessions', value => $cp_used, warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning', total => $cp_total, cast_int => 1), critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical', total => $cp_total, cast_int => 1), min => 0, max => $cp_total); + $self->{output}->perfdata_add(label => 'sessions_failed', + value => $cp_failed, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-failed', total => $cp_total, cast_int => 1), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-failed', total => $cp_total, cast_int => 1), + min => 0, max => $cp_total); if ($spu_done == 0) { $self->{output}->add_option_msg(short_msg => "Cannot check sessions usage (no total values)."); @@ -95,19 +119,25 @@ sub run { __END__ -=head1 MODE - -Check Juniper sessions usage (NETSCREEN-RESOURCE-MIB). +Check Juniper sessions usage and failed sessions (NETSCREEN-RESOURCE-MIB). =over 8 =item B<--warning> -Threshold warning in percent. +Threshold warning (percentage). =item B<--critical> -Threshold critical in percent. +Threshold critical (percentage). + +=item B<--warning-failed> + +Threshold warning on failed sessions (percentage). + +=item B<--critical-failed> + +Threshold critical in failed sessions (percentage). =back diff --git a/os/aix/local/mode/errpt.pm b/os/aix/local/mode/errpt.pm index d81522a55..12b4e7be6 100644 --- a/os/aix/local/mode/errpt.pm +++ b/os/aix/local/mode/errpt.pm @@ -46,10 +46,13 @@ sub new { "command-options:s" => { name => 'command_options', default => '' }, "error-type:s" => { name => 'error_type' }, "error-class:s" => { name => 'error_class' }, + "error-id:s" => { name => 'error_id' }, "retention:s" => { name => 'retention' }, "timezone:s" => { name => 'timezone' }, "description" => { name => 'description' }, - "filter-resource:s" => { name => 'filter_resource' }, + "filter-resource:s" => { name => 'filter_resource' }, + "filter-id:s" => { name => 'filter_id' }, + "exclude-id:s" => { name => 'exclude_id' }, }); $self->{result} = {}; return $self; @@ -58,6 +61,11 @@ sub new { sub check_options { my ($self, %options) = @_; $self->SUPER::init(%options); + + if (defined($self->{option_results}->{exclude_id}) && defined($self->{option_results}->{error_id})) { + $self->{output}->add_option_msg(short_msg => "Please use --error-id OR --exclude-id, these options are mutually exclusives"); + $self->{output}->option_exit(); + } } sub manage_selection { @@ -70,6 +78,12 @@ sub manage_selection { if (defined($self->{option_results}->{error_class})){ $extra_options .= ' -d '.$self->{option_results}->{error_class}; } + if (defined($self->{option_results}->{error_id}) && $self->{option_results}->{error_id} ne ''){ + $extra_options.= ' -j '.$self->{option_results}->{error_id}; + } + if (defined($self->{option_results}->{exclude_id}) && $self->{option_results}->{exclude_id} ne ''){ + $extra_options.= ' -k '.$self->{option_results}->{exclude_id}; + } if (defined($self->{option_results}->{retention}) && $self->{option_results}->{retention} ne ''){ my $retention = time() - $self->{option_results}->{retention}; if (defined($self->{option_results}->{timezone})){ @@ -126,7 +140,7 @@ sub run { $self->manage_selection(); $self->{output}->output_add(severity => 'OK', - short_msg => sprintf("No error found since %s seconds%s.", $extra_message)); + short_msg => sprintf("No error found%s.", $extra_message)); my $total_error = 0; foreach my $errpt_error (sort(keys %{$self->{result}})) { @@ -138,7 +152,8 @@ sub run { next if (defined($self->{option_results}->{filter_resource}) && $self->{option_results}->{filter_resource} ne '' && $resource_name !~ /$self->{option_results}->{filter_resource}/); - + next if (defined($self->{option_results}->{filter_id}) && $self->{option_results}->{filter_id} ne '' && + $identifier !~ /$self->{option_results}->{filter_id}/); $total_error++; if (defined($self->{option_results}->{description})) { $self->{output}->output_add(long_msg => sprintf("Error '%s' Date: %s ResourceName: %s Description: %s", $identifier, @@ -213,19 +228,29 @@ Filter error type separated by a coma (INFO, PEND, PERF, PERM, TEMP, UNKN). Filter error class ('H' for hardware, 'S' for software, '0' for errlogger, 'U' for undetermined). +=item B<--error-id> + +Filter specific error code (can be a comma separated list). + =item B<--retention> Retention time of errors in seconds. -=item B<--description> +=item B<--verbose> -Print error description in output. +Print error description in long output. [ Error 'CODE' Date: Timestamp ResourceName: RsrcName Description: Desc ] =item B<--filter-resource> Filter resource (can use a regexp). -Set +=item B<--filter-id> + +Filter error code (can use a regexp). + +=item B<--exclude-id> + +Filter on specific error code (can be a comma separated list). =back diff --git a/snmp_standard/mode/diskio.pm b/snmp_standard/mode/diskio.pm index 76d1c1746..ad93f7ea9 100644 --- a/snmp_standard/mode/diskio.pm +++ b/snmp_standard/mode/diskio.pm @@ -115,6 +115,29 @@ my $maps_counters = { unit => 'iops', min => 0 }, ], } + }, + }, + sum => { + '000_sum-read-write' => { set => { + key_values => [ { name => 'sum_read_write', diff => 1 } ], + per_second => 1, + output_template => 'R+W I/O : %s %s/s', output_error_template => "R+W I/O : %s", + output_change_bytes => 1, + perfdatas => [ + { label => 'sum_read_write', value => 'sum_read_write_per_second', template => '%d', + unit => 'B/s', min => 0 }, + ], + } + }, + '001_sum-read-write-iops' => { set => { + key_values => [ { name => 'sum_read_write_iops', diff => 1 } ], + per_second => 1, + output_template => 'R+W IOPs : %.2f', output_error_template => "R+W IOPs : %s", + perfdatas => [ + { label => 'sum_read_write_iops', value => 'sum_read_write_iops_per_second', template => '%.2f', + unit => 'iops', min => 0 }, + ], + } }, }, }; @@ -141,8 +164,8 @@ sub new { $self->{device_id_selected} = {}; $self->{statefile_value} = centreon::plugins::statefile->new(%options); - - foreach my $key (('total', 'disk')) { + + foreach my $key (('total', 'disk', 'sum')) { foreach (keys %{$maps_counters->{$key}}) { my ($id, $name) = split /_/; if (!defined($maps_counters->{$key}->{$_}->{threshold}) || $maps_counters->{$key}->{$_}->{threshold} != 0) { @@ -165,7 +188,7 @@ sub check_options { my ($self, %options) = @_; $self->SUPER::init(%options); - foreach my $key (('total', 'disk')) { + foreach my $key (('total', 'disk', 'sum')) { foreach (keys %{$maps_counters->{$key}}) { $maps_counters->{$key}->{$_}->{obj}->init(option_results => $self->{option_results}); } @@ -193,7 +216,7 @@ sub check_total { } my $exit2 = $obj->threshold_check(); push @exits, $exit2; - + my $output = $obj->output(); $long_msg .= $long_msg_append . $output; $long_msg_append = ', '; @@ -208,17 +231,58 @@ sub check_total { my $exit = $self->{output}->get_most_critical(status => [ @exits ]); if (!$self->{output}->is_status(litteral => 1, value => $exit, compare => 'ok')) { - $self->{output}->output_add(severity => $exit, - short_msg => "Total $short_msg" + $self->{output}->output_add(severity => $exit, + short_msg => "All devices [$short_msg]" ); } else { - $self->{output}->output_add(short_msg => "Total $long_msg"); + $self->{output}->output_add(short_msg => "All devices [$long_msg]"); + } +} + +sub check_sum { + my ($self, %options) = @_; + + my ($short_msg, $short_msg_append, $long_msg, $long_msg_append) = ('', '', '', ''); + my @exits = (); + foreach (sort keys %{$maps_counters->{sum}}) { + my $obj = $maps_counters->{sum}->{$_}->{obj}; + $obj->set(instance => 'sum'); + + my ($value_check) = $obj->execute(values => $self->{sum_global}, + new_datas => $self->{new_datas}); + + if ($value_check != 0) { + $long_msg .= $long_msg_append . $obj->output_error(); + $long_msg_append = ', '; + next; + } + my $exit2 = $obj->threshold_check(); + push @exits, $exit2; + + my $output = $obj->output(); + + $long_msg .= $long_msg_append . $output; + $long_msg_append = ', '; + if (!$self->{output}->is_status(litteral => 1, value => $exit2, compare => 'ok')) { + $short_msg .= $short_msg_append . $output; + $short_msg_append = ', '; + } + + $obj->perfdata(); + } + + my $exit = $self->{output}->get_most_critical(status => [ @exits ]); + if (!$self->{output}->is_status(litteral => 1, value => $exit, compare => 'ok')) { + $self->{output}->output_add(severity => $exit, + short_msg => "Server overall [$short_msg]" + ); + } else { + $self->{output}->output_add(short_msg => "Server overall [$long_msg]"); } } sub run { my ($self, %options) = @_; - # $options{snmp} = snmp object $self->{snmp} = $options{snmp}; $self->{hostname} = $self->{snmp}->get_hostname(); $self->{snmp_port} = $self->{snmp}->get_port(); @@ -241,6 +305,7 @@ sub run { if ($multiple == 1) { $self->check_total(); + $self->check_sum(); $self->{output}->output_add(severity => 'OK', short_msg => 'All devices are ok.'); } @@ -250,7 +315,7 @@ sub run { my @exits; foreach (sort keys %{$maps_counters->{disk}}) { my $obj = $maps_counters->{disk}->{$_}->{obj}; - + $obj->set(instance => $id); my ($value_check) = $obj->execute(values => $self->{device_id_selected}->{$id}, new_datas => $self->{new_datas}); @@ -287,7 +352,8 @@ sub run { $self->{output}->output_add(short_msg => "Device '" . $self->{device_id_selected}->{$id}->{display} . "' $long_msg"); } } - + + $self->{statefile_value}->write(data => $self->{new_datas}); $self->{output}->display(); $self->{output}->exit(); @@ -314,12 +380,20 @@ sub add_result { $self->{device_id_selected}->{$options{instance}}->{write_iops} = $self->{results}->{$oid_diskIOWrites}->{$oid_diskIOWrites . '.' . $options{instance}}; $self->{global}->{total_write_iops} += $self->{device_id_selected}->{$options{instance}}->{write_iops}; } + + if ($self->{global}->{total_read} && $self->{global}->{total_write}) { + $self->{sum_global}->{sum_read_write} = $self->{global}->{total_read} + $self->{global}->{total_write}; + } + if ($self->{global}->{total_read_iops} && $self->{global}->{total_write_iops}) { + $self->{sum_global}->{sum_read_write_iops} = $self->{global}->{total_read_iops} + $self->{global}->{total_write_iops}; + } } sub manage_selection { my ($self, %options) = @_; $self->{global} = { total_read => 0, total_write => 0, total_read_iops => 0, total_write_iops => 0 }; + $self->{sum_global} = { sum_read_write => 0, sum_read_write_iops => 0 }; $self->{results} = $self->{snmp}->get_multiple_table(oids => [ { oid => $oid_diskIODevice }, { oid => $oid_diskIOReads }, @@ -340,7 +414,7 @@ sub manage_selection { $oid =~ /\.(\d+)$/; my $instance = $1; my $filter_name = $self->{results}->{$oid_diskIODevice}->{$oid}; - if (!defined($self->{option_results}->{device})) { + if (!defined($self->{option_results}->{device}) || $self->{option_results}->{device} eq '') { $self->add_result(instance => $instance); next; } @@ -400,13 +474,15 @@ Check read/write I/O disks (bytes per secondes, IOPs). Threshold warning. Can be: 'read', 'write', 'read-iops', 'write-iops', -'total-read', 'total-write', 'total-read-iops', 'total-write-iops'. +'total-read', 'total-write', 'total-read-iops', 'total-write-iops', +'sum-read-write', 'sum-read-write-iops'. =item B<--critical-*> Threshold critical. Can be: 'read', 'write', 'read-iops', 'write-iops', -'total-read', 'total-write', 'total-read-iops', 'total-write-iops'. +'total-read', 'total-write', 'total-read-iops', 'total-write-iops', +'sum-read-write', 'sum-read-write-iops'. =item B<--device> diff --git a/snmp_standard/plugin.pm b/snmp_standard/plugin.pm index ccb417939..ea21277bf 100644 --- a/snmp_standard/plugin.pm +++ b/snmp_standard/plugin.pm @@ -35,6 +35,7 @@ sub new { 'numeric-value' => 'snmp_standard::mode::numericvalue', 'string-value' => 'snmp_standard::mode::stringvalue', 'dynamic-command' => 'snmp_standard::mode::dynamiccommand', + 'uptime' => 'snmp_standard::mode::uptime', ); return $self; @@ -46,6 +47,6 @@ __END__ =head1 PLUGIN DESCRIPTION -Check SNMP values (string, numeric or execute commands). +Check SNMP values (string, numeric or execute commands) or standard (uptime). =cut diff --git a/storage/emc/xtremio/restapi/custom/xtremioapi.pm b/storage/emc/xtremio/restapi/custom/xtremioapi.pm new file mode 100644 index 000000000..b766cb827 --- /dev/null +++ b/storage/emc/xtremio/restapi/custom/xtremioapi.pm @@ -0,0 +1,231 @@ +# +# Copyright 2015 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +package storage::emc::xtremio::restapi::custom::xtremioapi; + +use strict; +use warnings; +use centreon::plugins::http; +use JSON; + +sub new { + my ($class, %options) = @_; + my $self = {}; + bless $self, $class; + # $options{options} = options object + # $options{output} = output object + # $options{exit_value} = integer + # $options{noptions} = integer + + if (!defined($options{output})) { + print "Class Custom: Need to specify 'output' argument.\n"; + exit 3; + } + if (!defined($options{options})) { + $options{output}->add_option_msg(short_msg => "Class Custom: Need to specify 'options' argument."); + $options{output}->option_exit(); + } + + if (!defined($options{noptions})) { + $options{options}->add_options(arguments => + { + "hostname:s@" => { name => 'hostname', }, + "xtremio-username:s@" => { name => 'xtremio_username', }, + "xtremio-password:s@" => { name => 'xtremio_password', }, + "proxyurl:s@" => { name => 'proxyurl', }, + "timeout:s@" => { name => 'timeout', }, + }); + } + $options{options}->add_help(package => __PACKAGE__, sections => 'REST API OPTIONS', once => 1); + + $self->{output} = $options{output}; + $self->{mode} = $options{mode}; + $self->{http} = centreon::plugins::http->new(output => $self->{output}); + + return $self; + +} + +# Method to manage multiples +sub set_options { + my ($self, %options) = @_; + # options{options_result} + + $self->{option_results} = $options{option_results}; +} + +# Method to manage multiples +sub set_defaults { + my ($self, %options) = @_; + # options{default} + + # Manage default value + foreach (keys %{$options{default}}) { + if ($_ eq $self->{mode}) { + for (my $i = 0; $i < scalar(@{$options{default}->{$_}}); $i++) { + foreach my $opt (keys %{$options{default}->{$_}[$i]}) { + if (!defined($self->{option_results}->{$opt}[$i])) { + $self->{option_results}->{$opt}[$i] = $options{default}->{$_}[$i]->{$opt}; + } + } + } + } + } +} + +sub check_options { + my ($self, %options) = @_; +# # return 1 = ok still hostname +# # return 0 = no hostname left + + $self->{hostname} = (defined($self->{option_results}->{hostname})) ? shift(@{$self->{option_results}->{hostname}}) : undef; + $self->{xtremio_username} = (defined($self->{option_results}->{xtremio_username})) ? shift(@{$self->{option_results}->{xtremio_username}}) : ''; + $self->{xtremio_password} = (defined($self->{option_results}->{xtremio_password})) ? shift(@{$self->{option_results}->{xtremio_password}}) : ''; + $self->{timeout} = (defined($self->{option_results}->{timeout})) ? shift(@{$self->{option_results}->{timeout}}) : 10; + $self->{proxyurl} = (defined($self->{option_results}->{proxyurl})) ? shift(@{$self->{option_results}->{proxyurl}}) : undef; + + if (!defined($self->{hostname})) { + $self->{output}->add_option_msg(short_msg => "Need to specify hostname option."); + $self->{output}->option_exit(); + } + + if (!defined($self->{xtremio_username}) || !defined($self->{xtremio_password})) { + $self->{output}->add_option_msg(short_msg => "Need to specify --xtremio-username and --xtremio-password options."); + $self->{output}->option_exit(); + } + + if (!defined($self->{hostname}) || + scalar(@{$self->{option_results}->{hostname}}) == 0) { + return 0; + } + return 1; +} + + +sub build_options_for_httplib { + my ($self, %options) = @_; + + $self->{option_results}->{hostname} = $self->{xtremio_username}.':'.$self->{xtremio_password}.'@'.$self->{hostname}; + $self->{option_results}->{timeout} = $self->{timeout}; + $self->{option_results}->{port} = 443; + $self->{option_results}->{proto} = 'https'; + $self->{option_results}->{proxyurl} = $self->{proxyurl}; +} + +sub settings { + my ($self, %options) = @_; + + $self->build_options_for_httplib(); + $self->{http}->set_options(%{$self->{option_results}}); +} + +sub get_items { + my ($self, %options) = @_; + + $self->settings(); + + if (defined($options{obj}) && $options{obj} ne '') { + $options{url} .= $options{obj} . '/'; + } + + my $response = $self->{http}->request(url_path => $options{url}); + my $decoded; + eval { + $decoded = decode_json($response); + }; + if ($@) { + $self->{output}->add_option_msg(short_msg => "Cannot decode json response"); + $self->{output}->option_exit(); + } + + my @items; + foreach my $context (@{$decoded->{$options{obj}}}) { + push @items,$context->{name}; + } + + return @items; +} + +sub get_details { + my ($self, %options) = @_; + + $self->settings(); + + if ((defined($options{obj}) && $options{obj} ne '') && (defined($options{name}) && $options{name} ne '')) { + $options{url} .= $options{obj} . '/?name=' . $options{name} ; + } + + my $response = $self->{http}->request(url_path => $options{url}); + my $decoded; + eval { + $decoded = decode_json($response); + }; + if ($@) { + $self->{output}->add_option_msg(short_msg => "Cannot decode json response"); + $self->{output}->option_exit(); + } + + return $decoded->{content}; + +} + +1; + +__END__ + +=head1 NAME + +XREMIO REST API + +=head1 SYNOPSIS + +Xtremio Rest API custom mode + +=head1 REST API OPTIONS + +=over 8 + +=item B<--hostname> + +Xtremio hostname. + +=item B<--xtremio-username> + +Xtremio username. + +=item B<--xtremio-password> + +Xtremio password. + +=item B<--proxyurl> + +Proxy URL if any + +=item B<--timeout> + +Set HTTP timeout + +=back + +=head1 DESCRIPTION + +B. + +=cut diff --git a/storage/emc/xtremio/restapi/mode/clusterhealth.pm b/storage/emc/xtremio/restapi/mode/clusterhealth.pm new file mode 100644 index 000000000..c9bceb96a --- /dev/null +++ b/storage/emc/xtremio/restapi/mode/clusterhealth.pm @@ -0,0 +1,216 @@ +# +# Copyright 2015 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +package storage::emc::xtremio::restapi::mode::clusterhealth; + +use base qw(centreon::plugins::mode); + +use strict; +use warnings; + +my $thresholds = { + 'consistency-state' => [ + ['healthy', 'OK'], + ['.*', 'CRITICAL'], + ], + 'free-ud-ssd-space-level' => [ + ['healthy', 'OK'], + ['.*', 'CRITICAL'], + ], + 'shared-memory-efficiency-level' => [ + ['healthy', 'OK'], + ['.*', 'CRITICAL'], + ], + 'free-ud-ssd-space-level' => [ + ['healthy', 'OK'], + ['.*', 'CRITICAL'], + ], + 'vaai-tp-limit-crossing' => [ + ['healthy', 'OK'], + ['.*', 'CRITICAL'], + ], + 'shared-memory-in-use-ratio-level' => [ + ['healthy', 'OK'], + ['.*', 'CRITICAL'], + ], + 'sys-health-state' => [ + ['healthy', 'OK'], + ['.*', 'CRITICAL'], + ], +}; + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $self->{version} = '1.1'; + $options{options}->add_options(arguments => + { + "filter:s@" => { name => 'filter' }, + "threshold-overload:s@" => { name => 'threshold_overload' }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::init(%options); + + $self->{filter} = []; + foreach my $val (@{$self->{option_results}->{filter}}) { + next if (!defined($val) || $val eq ''); + my @values = split (/,/, $val); + push @{$self->{filter}}, { filter => $values[0], instance => $values[1] }; + } + + $self->{overload_th} = {}; + foreach my $val (@{$self->{option_results}->{threshold_overload}}) { + next if (!defined($val) || $val eq ''); + my @values = split (/,/, $val); + if (scalar(@values) < 3) { + $self->{output}->add_option_msg(short_msg => "Wrong threshold-overload option '" . $val . "'."); + $self->{output}->option_exit(); + } + my ($section, $instance, $status, $filter); + if (scalar(@values) == 3) { + ($section, $status, $filter) = @values; + $instance = '.*'; + } else { + ($section, $instance, $status, $filter) = @values; + } + if (!defined $thresholds->{$section}) { + $self->{output}->add_option_msg(short_msg => "Wrong threshold-overload section '" . $val . "'."); + $self->{output}->option_exit(); + } + if ($self->{output}->is_litteral_status(status => $status) == 0) { + $self->{output}->add_option_msg(short_msg => "Wrong threshold-overload status '" . $val . "'."); + $self->{output}->option_exit(); + } + $self->{overload_th}->{$section} = [] if (!defined($self->{overload_th}->{$section})); + push @{$self->{overload_th}->{$section}}, {filter => $filter, status => $status, instance => $instance }; + } +} + +sub run { + my ($self, %options) = @_; + my $xtremio = $options{custom}; + + my $urlbase = '/api/json/types/'; + my @items = $xtremio->get_items(url => $urlbase, + obj => 'clusters'); + + my @sensors = ('consistency-state','shared-memory-efficiency-level','free-ud-ssd-space-level', + 'vaai-tp-limit-crossing', 'shared-memory-in-use-ratio-level', 'sys-health-state'); + + $self->{output}->output_add(severity => 'OK', + short_msg => 'Health is OK'); + + foreach my $item (@items) { + next if ($self->check_filter(section => 'cluster', instance => $item)); + my $details = $xtremio->get_details(url => $urlbase, + obj => 'clusters', + name => $item); + + foreach my $sensor (@sensors) { + $self->{output}->output_add(long_msg => sprintf("Sensor '%s' state is '%s'", + $sensor, $details->{$sensor})); + + my $exit = $self->get_severity(section => $sensor, value => $details->{$sensor}); + if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { + $self->{output}->output_add(severity => $exit, + short_msg => sprintf("Sensor '%s' state is '%s'", + $sensor, $details->{$sensor})); + } + + } + + } + + $self->{output}->display(); + $self->{output}->exit(); +} + +sub check_filter { + my ($self, %options) = @_; + + foreach (@{$self->{filter}}) { + if ($options{section} =~ /$_->{filter}/) { + if (!defined($options{instance}) && !defined($_->{instance})) { + $self->{output}->output_add(long_msg => sprintf("Skipping $options{section} section.")); + return 1; + } elsif (defined($options{instance}) && $options{instance} =~ /$_->{instance}/) { + $self->{output}->output_add(long_msg => sprintf("Skipping $options{section} section $options{instance} instance.")); + return 1; + } + } + } + + return 0; +} + +sub get_severity { + my ($self, %options) = @_; + my $status = 'UNKNOWN'; # default + + if (defined($self->{overload_th}->{$options{section}})) { + foreach (@{$self->{overload_th}->{$options{section}}}) { + if ($options{value} =~ /$_->{filter}/i && + (!defined($options{instance}) || $options{instance} =~ /$_->{instance}/)) { + $status = $_->{status}; + return $status; + } + } + } + my $label = defined($options{label}) ? $options{label} : $options{section}; + foreach (@{$thresholds->{$label}}) { + if ($options{value} =~ /$$_[0]/i) { + $status = $$_[1]; + return $status; + } + } + + return $status; +} + + +1; + +__END__ + +=head1 MODE + +Check cluster health indicators ('consistency-state','shared-memory-efficiency-level','free-ud-ssd-space-level', 'vaai-tp-limit-crossing', 'shared-memory-in-use-ratio-level', 'sys-health-state'); + +=over 8 + +=item B<--filter> + +Filter some parts (comma seperated list) +Can also exclude specific instance: --filter=cluster,CLUSTER-NAME + +=item B<--threshold-overload> + +Overload a specific threshold, e.g --threshold-overload="consistency-state,Xtremio,CRITICAL,healthy" + +=back + +=cut diff --git a/storage/emc/xtremio/restapi/mode/ssdendurance.pm b/storage/emc/xtremio/restapi/mode/ssdendurance.pm new file mode 100644 index 000000000..1e1680a28 --- /dev/null +++ b/storage/emc/xtremio/restapi/mode/ssdendurance.pm @@ -0,0 +1,148 @@ +# +# Copyright 2015 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +package storage::emc::xtremio::restapi::mode::ssdendurance; + +use base qw(centreon::plugins::mode); + +use strict; +use warnings; + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $self->{version} = '1.1'; + $options{options}->add_options(arguments => + { + "filter:s@" => { name => 'filter' }, + "warning:s" => { name => 'warning' }, + "critical:s" => { name => 'critical' }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::init(%options); + + $self->{filter} = []; + foreach my $val (@{$self->{option_results}->{filter}}) { + next if (!defined($val) || $val eq ''); + my @values = split (/,/, $val); + push @{$self->{filter}}, { filter => $values[0], instance => $values[1] }; + } + + if (($self->{perfdata}->threshold_validate(label => 'warning', value => $self->{option_results}->{warning})) == 0) { + $self->{output}->add_option_msg(short_msg => "Wrong warning threshold '" . $self->{option_results}->{warning} . "'."); + $self->{output}->option_exit(); + } + if (($self->{perfdata}->threshold_validate(label => 'critical', value => $self->{option_results}->{critical})) == 0) { + $self->{output}->add_option_msg(short_msg => "Wrong critical threshold '" . $self->{option_results}->{critical} . "'."); + $self->{output}->option_exit(); + } +} + +sub run { + my ($self, %options) = @_; + my $xtremio = $options{custom}; + + my $urlbase = '/api/json/types/'; + my @items = $xtremio->get_items(url => $urlbase, + obj => 'ssds'); + + $self->{output}->output_add(severity => 'OK', + short_msg => 'All SSDs Endurance are OK'); + + foreach my $item (@items) { + next if ($self->check_filter(section => 'ssds', instance => $item)); + my $details = $xtremio->get_details(url => $urlbase, + obj => 'ssds', + name => $item); + + $self->{output}->output_add(long_msg => sprintf("SSD '%s' endurance remaining is %i%%", + $item, $details->{'percent-endurance-remaining'})); + + + my $exit = $self->{perfdata}->threshold_check(value => $details->{'percent-endurance-remaining'}, + threshold => [ { label => 'warning', exit_litteral => 'warning' }, { label => 'critical', exit_litteral => 'critical' } ]); + if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { + $self->{output}->output_add(severity => $exit, + short_msg => sprintf("SSD '%s' endurance is %i%%", + $item, $details->{'percent-endurance-remaining'})); + } + $self->{output}->perfdata_add(label => $item . "_endurance", unit => '%', + value => $details->{'percent-endurance-remaining'}, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning'), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical'), + min => 0, max => 100); + } + + $self->{output}->display(); + $self->{output}->exit(); + +} + +sub check_filter { + my ($self, %options) = @_; + + foreach (@{$self->{filter}}) { + if ($options{section} =~ /$_->{filter}/) { + if (!defined($options{instance}) && !defined($_->{instance})) { + $self->{output}->output_add(long_msg => sprintf("Skipping $options{section} section.")); + return 1; + } elsif (defined($options{instance}) && $options{instance} =~ /$_->{instance}/) { + $self->{output}->output_add(long_msg => sprintf("Skipping $options{section} section $options{instance} instance.")); + return 1; + } + } + } + + return 0; +} + +1; + +__END__ + +=head1 MODE + +Check SSDs endurance level (100% is the best value) + +=over 8 + +=item B<--filter> + +Filter some parts (comma seperated list) +Can also exclude specific instance: --filter=ssds,SSD-NAME-NUMBER + +=item B<--warning> + +Warning trigger for SSD endurance + +=item B<--critical> + +Critical trigger for SSD endurance + +=back + +=cut diff --git a/storage/emc/xtremio/restapi/mode/ssdiops.pm b/storage/emc/xtremio/restapi/mode/ssdiops.pm new file mode 100644 index 000000000..2096ffd0c --- /dev/null +++ b/storage/emc/xtremio/restapi/mode/ssdiops.pm @@ -0,0 +1,217 @@ +# +# Copyright 2015 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +package storage::emc::xtremio::restapi::mode::ssdiops; + +use base qw(centreon::plugins::mode); + +use strict; +use warnings; +use centreon::plugins::values; + +my $maps_counters = { + ssd => { + '000_global' => { set => { + key_values => [ { name => 'global_iops' }, { name => 'display' }, ], + output_template => 'Global IOPs : %s', + perfdatas => [ + { label => 'global_iops', value => 'global_iops_absolute', template => '%s', + min => 0, unit => 'iops', label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + '001_read' => { set => { + key_values => [ { name => 'read_iops' }, { name => 'display' }, ], + output_template => 'Read IOPs : %s', + perfdatas => [ + { label => 'read_iops', value => 'read_iops_absolute', template => '%s', + min => 0, unit => 'iops', label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + '002_write' => { set => { + key_values => [ { name => 'write_iops' }, { name => 'display' }, ], + output_template => 'Write IOPs : %s', + perfdatas => [ + { label => 'write_iops', value => 'write_iops_absolute', template => '%s', + min => 0, unit => 'iops', label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + }, +}; + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => + { + "filter-name:s" => { name => 'filter_name' }, + }); + + foreach my $key (('ssd')) { + foreach (keys %{$maps_counters->{$key}}) { + my ($id, $name) = split /_/; + if (!defined($maps_counters->{$key}->{$_}->{threshold}) || $maps_counters->{$key}->{$_}->{threshold} != 0) { + $options{options}->add_options(arguments => { + 'warning-' . $name . ':s' => { name => 'warning-' . $name }, + 'critical-' . $name . ':s' => { name => 'critical-' . $name }, + }); + } + $maps_counters->{$key}->{$_}->{obj} = centreon::plugins::values->new(output => $self->{output}, perfdata => $self->{perfdata}, + label => $name); + $maps_counters->{$key}->{$_}->{obj}->set(%{$maps_counters->{$key}->{$_}->{set}}); + } + } + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::init(%options); + + foreach my $key (('ssd')) { + foreach (keys %{$maps_counters->{$key}}) { + $maps_counters->{$key}->{$_}->{obj}->init(option_results => $self->{option_results}); + } + } +} + +sub run { + my ($self, %options) = @_; + $self->{xtremio} = $options{custom}; + + $self->manage_selection(); + + my $multiple = 1; + if (scalar(keys %{$self->{ssd}}) == 1) { + $multiple = 0; + } + + if ($multiple == 1) { + $self->{output}->output_add(severity => 'OK', + short_msg => 'All SSDs usages are ok'); + } + + foreach my $id (sort keys %{$self->{ssd}}) { + my ($short_msg, $short_msg_append, $long_msg, $long_msg_append) = ('', '', '', ''); + my @exits = (); + foreach (sort keys %{$maps_counters->{ssd}}) { + my $obj = $maps_counters->{ssd}->{$_}->{obj}; + $obj->set(instance => $id); + + my ($value_check) = $obj->execute(values => $self->{ssd}->{$id}); + + if ($value_check != 0) { + $long_msg .= $long_msg_append . $obj->output_error(); + $long_msg_append = ', '; + next; + } + my $exit2 = $obj->threshold_check(); + push @exits, $exit2; + + my $output = $obj->output(); + $long_msg .= $long_msg_append . $output; + $long_msg_append = ', '; + + if (!$self->{output}->is_status(litteral => 1, value => $exit2, compare => 'ok')) { + $short_msg .= $short_msg_append . $output; + $short_msg_append = ', '; + } + + $obj->perfdata(extra_instance => $multiple); + } + + $self->{output}->output_add(long_msg => "SSD '" . $self->{ssd}->{$id}->{display} . "' Usage $long_msg"); + my $exit = $self->{output}->get_most_critical(status => [ @exits ]); + if (!$self->{output}->is_status(litteral => 1, value => $exit, compare => 'ok')) { + $self->{output}->output_add(severity => $exit, + short_msg => "SSD '" . $self->{ssd}->{$id}->{display} . "' Usage $short_msg" + ); + } + + if ($multiple == 0) { + $self->{output}->output_add(short_msg => "SSD '" . $self->{ssd}->{$id}->{display} . "' Usage $long_msg"); + } + } + + $self->{output}->display(); + $self->{output}->exit(); +} + +sub manage_selection { + my ($self, %options) = @_; + + $self->{ssd} = {}; + my $urlbase = '/api/json/types/'; + my @items = $self->{xtremio}->get_items(url => $urlbase, + obj => 'ssds'); + foreach my $item (@items) { + if (defined($self->{option_results}->{filter_name}) && $self->{option_results}->{filter_name} ne '' && + $item !~ /$self->{option_results}->{filter_name}/) { + $self->{output}->output_add(long_msg => "Skipping '" . $item . "': no matching name.", debug => 1); + next; + } + + my $details = $self->{xtremio}->get_details(url => $urlbase, + obj => 'ssds', + name => $item); + + $self->{ssd}->{$item} = { display => $item, global_iops => $details->{iops}, + read_iops => $details->{'rd-iops'}, write_iops => $details->{'wr-iops'} }; + } + + if (scalar(keys %{$self->{ssd}}) <= 0) { + $self->{output}->add_option_msg(short_msg => "No entry found."); + $self->{output}->option_exit(); + } +} + +1; + +__END__ + +=head1 MODE + +Check IOPS (Global, Read, Write) on each SSDs. + +=over 8 + +=item B<--warning-*> + +Threshold warning. +Can be: 'global' (%), 'read' (%), 'write' (%). + +=item B<--critical-*> + +Threshold critical. +Can be: 'global' (%), 'read' (%), 'write' (%). + +=item B<--filter-name> + +Filter SSD name (can be a regexp). + +=back + +=cut diff --git a/storage/emc/xtremio/restapi/mode/xenvscpu.pm b/storage/emc/xtremio/restapi/mode/xenvscpu.pm new file mode 100644 index 000000000..2ead76f0d --- /dev/null +++ b/storage/emc/xtremio/restapi/mode/xenvscpu.pm @@ -0,0 +1,149 @@ +# +# Copyright 2015 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +package storage::emc::xtremio::restapi::mode::xenvscpu; + +use base qw(centreon::plugins::mode); + +use strict; +use warnings; + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $self->{version} = '1.1'; + $options{options}->add_options(arguments => + { + "filter:s@" => { name => 'filter' }, + "warning:s" => { name => 'warning' }, + "critical:s" => { name => 'critical' }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::init(%options); + + $self->{filter} = []; + foreach my $val (@{$self->{option_results}->{filter}}) { + next if (!defined($val) || $val eq ''); + my @values = split (/,/, $val); + push @{$self->{filter}}, { filter => $values[0], instance => $values[1] }; + } + + if (($self->{perfdata}->threshold_validate(label => 'warning', value => $self->{option_results}->{warning})) == 0) { + $self->{output}->add_option_msg(short_msg => "Wrong warning threshold '" . $self->{option_results}->{warning} . "'."); + $self->{output}->option_exit(); + } + if (($self->{perfdata}->threshold_validate(label => 'critical', value => $self->{option_results}->{critical})) == 0) { + $self->{output}->add_option_msg(short_msg => "Wrong critical threshold '" . $self->{option_results}->{critical} . "'."); + $self->{output}->option_exit(); + } +} + +sub run { + my ($self, %options) = @_; + my $xtremio = $options{custom}; + + my $urlbase = '/api/json/types/'; + my @items = $xtremio->get_items(url => $urlbase, + obj => 'xenvs'); + + $self->{output}->output_add(severity => 'OK', + short_msg => 'All Xenvs CPU Usage are OK'); + + foreach my $item (@items) { + next if ($self->check_filter(section => 'cpu', instance => $item)); + my $details = $xtremio->get_details(url => $urlbase, + obj => 'xenvs', + name => $item); + + $self->{output}->output_add(long_msg => sprintf("Xenvs '%s' CPU Usage is %i%%", + $item, + $details->{'cpu-usage'})); + + + my $exit = $self->{perfdata}->threshold_check(value => $details->{'cpu-usage'}, threshold => [ { label => 'warning', 'exit_litteral' => 'warning' }, { label => 'critical', exit_litteral => 'critical' } ]); + if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { + $self->{output}->output_add(severity => $exit, + short_msg => sprintf("Xenvs '%s' cpu-Usage is %i%%", + $item, + $details->{'cpu-usage'})); + } + $self->{output}->perfdata_add(label => 'cpu_' . $item, unit => '%', + value => $details->{'cpu-usage'}, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning'), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical'), + min => 0, max => 100); + } + + $self->{output}->display(); + $self->{output}->exit(); + +} + +sub check_filter { + my ($self, %options) = @_; + + foreach (@{$self->{filter}}) { + if ($options{section} =~ /$_->{filter}/) { + if (!defined($options{instance}) && !defined($_->{instance})) { + $self->{output}->output_add(long_msg => sprintf("Skipping $options{section} section.")); + return 1; + } elsif (defined($options{instance}) && $options{instance} =~ /$_->{instance}/) { + $self->{output}->output_add(long_msg => sprintf("Skipping $options{section} section $options{instance} instance.")); + return 1; + } + } + } + + return 0; +} + +1; + +__END__ + +=head1 MODE + +Check Xenvs CPU usage + +=over 8 + +=item B<--filter> + +Filter some parts (comma seperated list) +Can also exclude specific instance: --filter=cpu,XENVS-NAME-NUMBER + +=item B<--warning> + +Value to trigger a warning alarm on CPU usage + +=item B<--critical> + +Value to trigger a critical alarm on CPU usage + +=back + +=cut diff --git a/storage/emc/xtremio/restapi/mode/xenvsstate.pm b/storage/emc/xtremio/restapi/mode/xenvsstate.pm new file mode 100644 index 000000000..2e9a959d4 --- /dev/null +++ b/storage/emc/xtremio/restapi/mode/xenvsstate.pm @@ -0,0 +1,188 @@ +# +# Copyright 2015 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +package storage::emc::xtremio::restapi::mode::xenvsstate; + +use base qw(centreon::plugins::mode); + +use strict; +use warnings; + +my $thresholds = { + xenvs_state => [ + ['active', 'OK'], + ['.*', 'CRITICAL'], + ], +}; + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $self->{version} = '1.1'; + $options{options}->add_options(arguments => + { + "filter:s@" => { name => 'filter' }, + "threshold-overload:s@" => { name => 'threshold_overload' }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::init(%options); + + $self->{filter} = []; + foreach my $val (@{$self->{option_results}->{filter}}) { + next if (!defined($val) || $val eq ''); + my @values = split (/,/, $val); + push @{$self->{filter}}, { filter => $values[0], instance => $values[1] }; + } + + $self->{overload_th} = {}; + foreach my $val (@{$self->{option_results}->{threshold_overload}}) { + next if (!defined($val) || $val eq ''); + my @values = split (/,/, $val); + if (scalar(@values) < 3) { + $self->{output}->add_option_msg(short_msg => "Wrong threshold-overload option '" . $val . "'."); + $self->{output}->option_exit(); + } + my ($section, $instance, $status, $filter); + if (scalar(@values) == 3) { + ($section, $status, $filter) = @values; + $instance = '.*'; + } else { + ($section, $instance, $status, $filter) = @values; + } + if (!defined $thresholds->{$section}) { + $self->{output}->add_option_msg(short_msg => "Wrong threshold-overload section '" . $val . "'."); + $self->{output}->option_exit(); + } + if ($self->{output}->is_litteral_status(status => $status) == 0) { + $self->{output}->add_option_msg(short_msg => "Wrong threshold-overload status '" . $val . "'."); + $self->{output}->option_exit(); + } + $self->{overload_th}->{$section} = [] if (!defined($self->{overload_th}->{$section})); + push @{$self->{overload_th}->{$section}}, {filter => $filter, status => $status, instance => $instance }; + } +} + +sub run { + my ($self, %options) = @_; + my $xtremio = $options{custom}; + + my $urlbase = '/api/json/types/'; + my @items = $xtremio->get_items(url => $urlbase, + obj => 'xenvs'); + + $self->{output}->output_add(severity => 'OK', + short_msg => 'All Xenvs states are active'); + + foreach my $item (@items) { + next if ($self->check_filter(section => 'state', instance => $item)); + my $details = $xtremio->get_details(url => $urlbase, + obj => 'xenvs', + name => $item); + + $self->{output}->output_add(long_msg => sprintf("Xenvs '%s' state is '%s'", + $item, + $details->{'xenv-state'})); + + my $exit = $self->get_severity(section => 'xenvs_state', instance => $item, value => $details->{'xenv-state'}); + if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { + $self->{output}->output_add(severity => $exit, + short_msg => sprintf("Xenvs '%s' state is '%s'", + $item, $details->{'xenv-state'})); + } + + } + + $self->{output}->display(); + $self->{output}->exit(); +} + +sub check_filter { + my ($self, %options) = @_; + + foreach (@{$self->{filter}}) { + if ($options{section} =~ /$_->{filter}/) { + if (!defined($options{instance}) && !defined($_->{instance})) { + $self->{output}->output_add(long_msg => sprintf("Skipping $options{section} section.")); + return 1; + } elsif (defined($options{instance}) && $options{instance} =~ /$_->{instance}/) { + $self->{output}->output_add(long_msg => sprintf("Skipping $options{section} section $options{instance} instance.")); + return 1; + } + } + } + + return 0; +} + +sub get_severity { + my ($self, %options) = @_; + my $status = 'UNKNOWN'; # default + + if (defined($self->{overload_th}->{$options{section}})) { + foreach (@{$self->{overload_th}->{$options{section}}}) { + if ($options{value} =~ /$_->{filter}/i && + (!defined($options{instance}) || $options{instance} =~ /$_->{instance}/)) { + $status = $_->{status}; + return $status; + } + } + } + my $label = defined($options{label}) ? $options{label} : $options{section}; + foreach (@{$thresholds->{$label}}) { + if ($options{value} =~ /$$_[0]/i) { + $status = $$_[1]; + return $status; + } + } + + return $status; +} + +1; + +__END__ + +=head1 MODE + +Check Xenvs state + +=over 8 + +=item B<--filter> + +Filter some parts (comma seperated list) +Can also exclude specific instance: --filter=device,cluster-1_xxxx + +=item B<--threshold-overload> + +Set to overload default threshold values (syntax: section,[instance,]status,regexp) +It used before default thresholds (order stays). +Example: --threshold-overload='xenvs_state,CRITICAL,^(?!(ok)$)' + +=back + +=cut diff --git a/storage/emc/xtremio/restapi/plugin.pm b/storage/emc/xtremio/restapi/plugin.pm new file mode 100644 index 000000000..55e37a12a --- /dev/null +++ b/storage/emc/xtremio/restapi/plugin.pm @@ -0,0 +1,58 @@ +# +# Copyright 2015 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +package storage::emc::xtremio::restapi::plugin; + +use strict; +use warnings; +use base qw(centreon::plugins::script_custom); + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + # $options->{options} = options object + + $self->{version} = '1.0'; + %{$self->{modes}} = ( + 'xenvs-cpu' => 'storage::emc::xtremio::restapi::mode::xenvscpu', + 'xenvs-state' => 'storage::emc::xtremio::restapi::mode::xenvsstate', + 'ssds-endurance' => 'storage::emc::xtremio::restapi::mode::ssdendurance', + 'ssds-iops' => 'storage::emc::xtremio::restapi::mode::ssdiops', + 'cluster-health' => 'storage::emc::xtremio::restapi::mode::clusterhealth', + ); + + $self->{custom_modes}{xtremioapi} = 'storage::emc::xtremio::restapi::custom::xtremioapi'; + return $self; +} + +sub init { + my ($self, %options) = @_; + + $self->SUPER::init(%options); +} + +1; + +__END__ + +=head1 PLUGIN DESCRIPTION + +Check EMC Xtremio through HTTP/REST API. diff --git a/storage/ibm/TS3100/mode/globalstatus.pm b/storage/ibm/TS3100/mode/globalstatus.pm index c75b97cac..a56a6d665 100644 --- a/storage/ibm/TS3100/mode/globalstatus.pm +++ b/storage/ibm/TS3100/mode/globalstatus.pm @@ -117,4 +117,4 @@ Example: --threshold-overload='(unknown|non critical)=critical' =back =cut - \ No newline at end of file + diff --git a/storage/ibm/TS3200/mode/globalstatus.pm b/storage/ibm/TS3200/mode/globalstatus.pm index 78e14ac80..1f4a916d8 100644 --- a/storage/ibm/TS3200/mode/globalstatus.pm +++ b/storage/ibm/TS3200/mode/globalstatus.pm @@ -87,14 +87,13 @@ sub run { my ($self, %options) = @_; # $options{snmp} = snmp object $self->{snmp} = $options{snmp}; - + my $oid_ibm3200StatusGlobalStatus = '.1.3.6.1.4.1.2.6.211.2.1.0'; my $result = $self->{snmp}->get_leef(oids => [$oid_ibm3200StatusGlobalStatus], nothing_quit => 1); $self->{output}->output_add(severity => $self->get_severity(value => $result->{$oid_ibm3200StatusGlobalStatus}), short_msg => sprintf("Overall global status is '%s'.", ${$states{$result->{$oid_ibm3200StatusGlobalStatus}}}[0])); - $self->{output}->display(); $self->{output}->exit(); } @@ -117,4 +116,4 @@ Example: --threshold-overload='(unknown|non critical)=critical' =back =cut - \ No newline at end of file + diff --git a/storage/nimble/snmp/mode/globalstats.pm b/storage/nimble/snmp/mode/globalstats.pm new file mode 100644 index 000000000..636013b7f --- /dev/null +++ b/storage/nimble/snmp/mode/globalstats.pm @@ -0,0 +1,264 @@ +# +# Copyright 2015 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +package storage::nimble::snmp::mode::globalstats; + +use base qw(centreon::plugins::mode); + +use strict; +use warnings; +use Digest::MD5 qw(md5_hex); +use centreon::plugins::values; +use centreon::plugins::statefile; + +my $maps_counters = { + global => { + '000_read' => { set => { + key_values => [ { name => 'read', diff => 1 } ], + per_second => 1, + output_template => 'Read I/O : %s %s/s', output_error_template => "Read I/O : %s", + output_change_bytes => 1, + perfdatas => [ + { label => 'read', value => 'read_per_second', template => '%d', + unit => 'B/s' }, + ], + } + }, + '001_write' => { set => { + key_values => [ { name => 'write', diff => 1 } ], + per_second => 1, + output_template => 'Write I/O : %s %s/s', output_error_template => "Write I/O : %s", + output_change_bytes => 1, + perfdatas => [ + { label => 'write', value => 'write_per_second', template => '%d', + unit => 'B/s', min => 0 }, + ], + } + }, + '002_read-iops' => { set => { + key_values => [ { name => 'read_iops', diff => 1 } ], + per_second => 1, + output_template => 'Read IOPs : %.2f', output_error_template => "Read IOPs : %s", + perfdatas => [ + { label => 'read_iops', value => 'read_iops_per_second', template => '%.2f', + unit => 'iops', min => 0 }, + ], + } + }, + '003_write-iops' => { set => { + key_values => [ { name => 'write_iops', diff => 1 } ], + per_second => 1, + output_template => 'Write IOPs : %.2f', output_error_template => "Write IOPs : %s", + perfdatas => [ + { label => 'write_iops', value => 'write_iops_per_second', template => '%.2f', + unit => 'iops', min => 0 }, + ], + } + }, + '004_read-time' => { set => { + key_values => [ { name => 'read_time', diff => 1 } ], + output_template => 'Read Time : %.3f s', output_error_template => "Read Time : %s", + perfdatas => [ + { label => 'read_time', value => 'read_time_absolute', template => '%.3f', + unit => 's', min => 0 }, + ], + } + }, + '005_write-time' => { set => { + key_values => [ { name => 'write_time', diff => 1 } ], + output_template => 'Write Time : %.3f s', output_error_template => "Write Time : %s", + perfdatas => [ + { label => 'write_time', value => 'write_time_absolute', template => '%.3f', + unit => 's', min => 0 }, + ], + } + }, + }, +}; + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => + { + "filter-counters:s" => { name => 'filter_counters' }, + }); + $self->{statefile_value} = centreon::plugins::statefile->new(%options); + + foreach my $key (('global')) { + foreach (keys %{$maps_counters->{$key}}) { + my ($id, $name) = split /_/; + if (!defined($maps_counters->{$key}->{$_}->{threshold}) || $maps_counters->{$key}->{$_}->{threshold} != 0) { + $options{options}->add_options(arguments => { + 'warning-' . $name . ':s' => { name => 'warning-' . $name }, + 'critical-' . $name . ':s' => { name => 'critical-' . $name }, + }); + } + $maps_counters->{$key}->{$_}->{obj} = centreon::plugins::values->new(statefile => $self->{statefile_value}, + output => $self->{output}, + perfdata => $self->{perfdata}, + label => $name); + $maps_counters->{$key}->{$_}->{obj}->set(%{$maps_counters->{$key}->{$_}->{set}}); + } + } + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::init(%options); + + foreach my $key (('global')) { + foreach (keys %{$maps_counters->{$key}}) { + $maps_counters->{$key}->{$_}->{obj}->init(option_results => $self->{option_results}); + } + } + + $self->{statefile_value}->check_options(%options); +} + +sub run_global { + my ($self, %options) = @_; + + my ($short_msg, $short_msg_append, $long_msg, $long_msg_append) = ('', '', '', ''); + my @exits; + foreach (sort keys %{$maps_counters->{global}}) { + if (defined($self->{option_results}->{filter_counters}) && $self->{option_results}->{filter_counters} ne '' && + $_ !~ /$self->{option_results}->{filter_counters}/) { + $self->{output}->output_add(long_msg => "skipping counter $_", debug => 1); + next; + } + + my $obj = $maps_counters->{global}->{$_}->{obj}; + + $obj->set(instance => 'global'); + + my ($value_check) = $obj->execute(new_datas => $self->{new_datas}, + values => $self->{global}); + + if ($value_check != 0) { + $long_msg .= $long_msg_append . $obj->output_error(); + $long_msg_append = ', '; + next; + } + my $exit2 = $obj->threshold_check(); + push @exits, $exit2; + + my $output = $obj->output(); + $long_msg .= $long_msg_append . $output; + $long_msg_append = ', '; + + if (!$self->{output}->is_status(litteral => 1, value => $exit2, compare => 'ok')) { + $short_msg .= $short_msg_append . $output; + $short_msg_append = ', '; + } + + $obj->perfdata(); + } + + my $exit = $self->{output}->get_most_critical(status => [ @exits ]); + if (!$self->{output}->is_status(litteral => 1, value => $exit, compare => 'ok')) { + $self->{output}->output_add(severity => $exit, + short_msg => "$short_msg" + ); + } else { + $self->{output}->output_add(short_msg => "$long_msg"); + } +} + +sub run { + my ($self, %options) = @_; + + $self->manage_selection(%options); + + $self->{new_datas} = {}; + $self->{statefile_value}->read(statefile => $self->{cache_name}); + $self->{new_datas}->{last_timestamp} = time(); + + $self->run_global(); + + $self->{statefile_value}->write(data => $self->{new_datas}); + $self->{output}->display(); + $self->{output}->exit(); +} + +sub manage_selection { + my ($self, %options) = @_; + + if ($options{snmp}->is_snmpv1()) { + $self->{output}->add_option_msg(short_msg => "Need to use SNMP v2c or v3."); + $self->{output}->option_exit(); + } + + $self->{cache_name} = "nimble_" . $options{snmp}->get_hostname() . '_' . $options{snmp}->get_port() . '_' . $self->{mode} . '_' . + (defined($self->{option_results}->{filter_counters}) ? md5_hex($self->{option_results}->{filter_counters}) : md5_hex('all')); + + $self->{global} = {}; + my $oid_globalStats = '.1.3.6.1.4.1.37447.1.3'; + my $oid_ioReads = '.1.3.6.1.4.1.37447.1.3.2.0'; + my $oid_ioReadBytes = '.1.3.6.1.4.1.37447.1.3.8.0'; + my $oid_ioReadTimeMicrosec = '.1.3.6.1.4.1.37447.1.3.6.0'; + my $oid_ioWrites = '.1.3.6.1.4.1.37447.1.3.4.0'; + my $oid_ioWriteBytes = '.1.3.6.1.4.1.37447.1.3.10.0'; + my $oid_ioWriteTimeMicrosec = '.1.3.6.1.4.1.37447.1.3.7.0'; + my $result = $options{snmp}->get_table(oid => $oid_globalStats, + nothing_quit => 1); + $self->{global}->{read} = defined($result->{$oid_ioReadBytes}) ? $result->{$oid_ioReadBytes} : undef; + $self->{global}->{read_iops} = defined($result->{$oid_ioReads}) ? $result->{$oid_ioReads} : undef; + $self->{global}->{read_time} = defined($result->{$oid_ioReadTimeMicrosec}) ? $result->{$oid_ioReadTimeMicrosec} / 1000000 : undef; + $self->{global}->{write} = defined($result->{$oid_ioWriteBytes}) ? $result->{$oid_ioWriteBytes} : undef; + $self->{global}->{write_iops} = defined($result->{$oid_ioWrites}) ? $result->{$oid_ioWrites} : undef; + $self->{global}->{write_time} = defined($result->{$oid_ioWriteTimeMicrosec}) ? $result->{$oid_ioWriteTimeMicrosec} / 1000000: undef; +} + +1; + +__END__ + +=head1 MODE + +Check global statistics of storage. + +=over 8 + +=item B<--warning-*> + +Threshold warning. +Can be: 'read', 'read-iops', 'write', 'write-iops', +'read-time', 'write-time'. + +=item B<--critical-*> + +Threshold critical. +Can be: 'read', 'read-iops', 'write', 'write-iops', +'read-time', 'write-time'. + +=item B<--filter-counters> + +Only display some counters (regexp can be used). +Example: --filter-counters='-iops$' + +=back + +=cut diff --git a/storage/nimble/snmp/mode/volumeusage.pm b/storage/nimble/snmp/mode/volumeusage.pm new file mode 100644 index 000000000..d2f59bbad --- /dev/null +++ b/storage/nimble/snmp/mode/volumeusage.pm @@ -0,0 +1,259 @@ +# +# Copyright 2015 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +package storage::nimble::snmp::mode::volumeusage; + +use base qw(centreon::plugins::mode); + +use strict; +use warnings; +use centreon::plugins::values; + +my $instance_mode; + +my $maps_counters = { + vol => { + '000_usage' => { + set => { + key_values => [ { name => 'display' }, { name => 'total' }, { name => 'used' } ], + closure_custom_calc => \&custom_usage_calc, + closure_custom_output => \&custom_usage_output, + closure_custom_perfdata => \&custom_usage_perfdata, + closure_custom_threshold_check => \&custom_usage_threshold, + }, + }, + } +}; + +sub custom_usage_perfdata { + my ($self, %options) = @_; + + my $extra_label = ''; + if (!defined($options{extra_instance}) || $options{extra_instance} != 0) { + $extra_label .= '_' . $self->{result_values}->{display}; + } + $self->{output}->perfdata_add(label => 'used' . $extra_label, unit => 'B', + value => $self->{result_values}->{used}, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{label}, total => $self->{result_values}->{total}, cast_int => 1), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{label}, total => $self->{result_values}->{total}, cast_int => 1), + min => 0, max => $self->{result_values}->{total}); +} + +sub custom_usage_threshold { + my ($self, %options) = @_; + + my $exit = $self->{perfdata}->threshold_check(value => $self->{result_values}->{prct_used}, threshold => [ { label => 'critical-' . $self->{label}, exit_litteral => 'critical' }, { label => 'warning-' . $self->{label}, exit_litteral => 'warning' } ]); + return $exit; +} + +sub custom_usage_output { + my ($self, %options) = @_; + + my ($total_size_value, $total_size_unit) = $self->{perfdata}->change_bytes(value => $self->{result_values}->{total}); + my ($total_used_value, $total_used_unit) = $self->{perfdata}->change_bytes(value => $self->{result_values}->{used}); + my ($total_free_value, $total_free_unit) = $self->{perfdata}->change_bytes(value => $self->{result_values}->{free}); + + my $msg = sprintf("Total: %s Used: %s (%.2f%%) Free: %s (%.2f%%)", + $total_size_value . " " . $total_size_unit, + $total_used_value . " " . $total_used_unit, $self->{result_values}->{prct_used}, + $total_free_value . " " . $total_free_unit, $self->{result_values}->{prct_free}); + return $msg; +} + +sub custom_usage_calc { + my ($self, %options) = @_; + + $self->{result_values}->{display} = $options{new_datas}->{$self->{instance} . '_display'}; + $self->{result_values}->{total} = $options{new_datas}->{$self->{instance} . '_total'}; + $self->{result_values}->{used} = $options{new_datas}->{$self->{instance} . '_used'}; + $self->{result_values}->{free} = $self->{result_values}->{total} - $self->{result_values}->{used}; + $self->{result_values}->{prct_free} = $self->{result_values}->{free} * 100 / $self->{result_values}->{total}; + $self->{result_values}->{prct_used} = $self->{result_values}->{used} * 100 / $self->{result_values}->{total}; + return 0; +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => + { + "filter-name:s" => { name => 'filter_name' }, + }); + + foreach my $key (('vol')) { + foreach (keys %{$maps_counters->{$key}}) { + my ($id, $name) = split /_/; + if (!defined($maps_counters->{$key}->{$_}->{threshold}) || $maps_counters->{$key}->{$_}->{threshold} != 0) { + $options{options}->add_options(arguments => { + 'warning-' . $name . ':s' => { name => 'warning-' . $name }, + 'critical-' . $name . ':s' => { name => 'critical-' . $name }, + }); + } + $maps_counters->{$key}->{$_}->{obj} = centreon::plugins::values->new(output => $self->{output}, perfdata => $self->{perfdata}, + label => $name); + $maps_counters->{$key}->{$_}->{obj}->set(%{$maps_counters->{$key}->{$_}->{set}}); + } + } + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::init(%options); + + foreach my $key (('vol')) { + foreach (keys %{$maps_counters->{$key}}) { + $maps_counters->{$key}->{$_}->{obj}->init(option_results => $self->{option_results}); + } + } + $instance_mode = $self; +} + +sub run_instances { + my ($self, %options) = @_; + + my $multiple = 1; + if (scalar(keys %{$self->{vol}}) == 1) { + $multiple = 0; + } + + if ($multiple == 1) { + $self->{output}->output_add(severity => 'OK', + short_msg => 'All volume usages are ok'); + } + + foreach my $id (sort keys %{$self->{vol}}) { + my ($short_msg, $short_msg_append, $long_msg, $long_msg_append) = ('', '', '', ''); + my @exits = (); + foreach (sort keys %{$maps_counters->{vol}}) { + my $obj = $maps_counters->{vol}->{$_}->{obj}; + $obj->set(instance => $id); + + my ($value_check) = $obj->execute(values => $self->{vol}->{$id}); + + if ($value_check != 0) { + $long_msg .= $long_msg_append . $obj->output_error(); + $long_msg_append = ', '; + next; + } + my $exit2 = $obj->threshold_check(); + push @exits, $exit2; + + my $output = $obj->output(); + $long_msg .= $long_msg_append . $output; + $long_msg_append = ', '; + + if (!$self->{output}->is_status(litteral => 1, value => $exit2, compare => 'ok')) { + $short_msg .= $short_msg_append . $output; + $short_msg_append = ', '; + } + + $obj->perfdata(extra_instance => $multiple); + } + + $self->{output}->output_add(long_msg => "Volume '$self->{vol}->{$id}->{display}' $long_msg"); + my $exit = $self->{output}->get_most_critical(status => [ @exits ]); + if (!$self->{output}->is_status(litteral => 1, value => $exit, compare => 'ok')) { + $self->{output}->output_add(severity => $exit, + short_msg => "Volume '$self->{vol}->{$id}->{display}' $short_msg" + ); + } + + if ($multiple == 0) { + $self->{output}->output_add(short_msg => "Volume '$self->{vol}->{$id}->{display}' $long_msg"); + } + } +} + +sub run { + my ($self, %options) = @_; + + $self->manage_selection(%options); + $self->run_instances(); + + $self->{output}->display(); + $self->{output}->exit(); +} + +my $mapping = { + volName => { oid => '.1.3.6.1.4.1.37447.1.2.1.3' }, + volSizeLow => { oid => '.1.3.6.1.4.1.37447.1.2.1.4' }, # seems in MB + volSizeHigh => { oid => '.1.3.6.1.4.1.37447.1.2.1.5' }, # seems in MB + volUsageLow => { oid => '.1.3.6.1.4.1.37447.1.2.1.6' }, # seems in MB + volUsageHigh => { oid => '.1.3.6.1.4.1.37447.1.2.1.7' }, # seems in MB +}; + +sub manage_selection { + my ($self, %options) = @_; + + my $oid_volEntry = '.1.3.6.1.4.1.37447.1.2.1'; + my $results = $options{snmp}->get_table(oid => $oid_volEntry, nothing_quit => 1); + $self->{vol} = {}; + foreach my $oid (keys %{$results}) { + next if ($oid !~ /^$mapping->{volName}->{oid}\.(.*)/); + my $instance = $1; + my $result = $options{snmp}->map_instance(mapping => $mapping, results => $results, instance => $instance); + + if (defined($self->{option_results}->{filter_name}) && $self->{option_results}->{filter_name} ne '' && + $result->{volName} !~ /$self->{option_results}->{filter_name}/) { + $self->{output}->output_add(long_msg => "Skipping '" . $result->{volName} . "': no matching vserver name.", debug => 1); + next; + } + + my $total = (($result->{volSizeHigh} << 32) + $result->{volSizeLow}) * 1024 * 1024; + my $used = (($result->{volUsageHigh} << 32) + $result->{volUsageLow}) * 1024 * 1024; + $self->{vol}->{$instance} = { display => $result->{volName}, used => $used, total => $total }; + } + + if (scalar(keys %{$self->{vol}}) <= 0) { + $self->{output}->add_option_msg(short_msg => "No entry found."); + $self->{output}->option_exit(); + } +} + +1; + +__END__ + +=head1 MODE + +Check volume usages. + +=over 8 + +=item B<--filter-name> + +Filter by name (regexp can be used). + +=item B<--warning-usage> + +Threshold warning (in percent). + +=item B<--critical-usage> + +Threshold critical (in percent). + +=back + +=cut diff --git a/storage/nimble/snmp/plugin.pm b/storage/nimble/snmp/plugin.pm new file mode 100644 index 000000000..1d7d9bfd3 --- /dev/null +++ b/storage/nimble/snmp/plugin.pm @@ -0,0 +1,49 @@ +# +# Copyright 2015 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +package storage::nimble::snmp::plugin; + +use strict; +use warnings; +use base qw(centreon::plugins::script_snmp); + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $self->{version} = '1.0'; + %{$self->{modes}} = ( + 'volume-usage' => 'storage::nimble::snmp::mode::volumeusage', + 'global-stats' => 'storage::nimble::snmp::mode::globalstats', + ); + + return $self; +} + +1; + +__END__ + +=head1 PLUGIN DESCRIPTION + +Check nimble storage in SNMP. + +=cut