diff --git a/centreon-plugins/apps/backup/veeam/local/mode/jobstatus.pm b/centreon-plugins/apps/backup/veeam/local/mode/jobstatus.pm new file mode 100644 index 000000000..9c606aa30 --- /dev/null +++ b/centreon-plugins/apps/backup/veeam/local/mode/jobstatus.pm @@ -0,0 +1,367 @@ +# +# Copyright 2017 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::backup::veeam::local::mode::jobstatus; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; +use centreon::common::powershell::veeam::jobstatus; +use centreon::plugins::misc; + +my $instance_mode; + +sub custom_status_threshold { + my ($self, %options) = @_; + my $status = 'ok'; + my $message; + + eval { + local $SIG{__WARN__} = sub { $message = $_[0]; }; + local $SIG{__DIE__} = sub { $message = $_[0]; }; + + # To exclude some OK + if (defined($instance_mode->{option_results}->{ok_status}) && $instance_mode->{option_results}->{ok_status} ne '' && + eval "$instance_mode->{option_results}->{ok_status}") { + $status = 'ok'; + } elsif (defined($instance_mode->{option_results}->{critical_status}) && $instance_mode->{option_results}->{critical_status} ne '' && + eval "$instance_mode->{option_results}->{critical_status}") { + $status = 'critical'; + } elsif (defined($instance_mode->{option_results}->{warning_status}) && $instance_mode->{option_results}->{warning_status} ne '' && + eval "$instance_mode->{option_results}->{warning_status}") { + $status = 'warning'; + } + }; + if (defined($message)) { + $self->{output}->output_add(long_msg => 'filter status issue: ' . $message); + } + + return $status; +} + +sub custom_status_output { + my ($self, %options) = @_; + my $msg = 'status : ' . $self->{result_values}->{status} . ' [type: ' . $self->{result_values}->{type} . ']'; + + return $msg; +} + +sub custom_status_calc { + my ($self, %options) = @_; + + $self->{result_values}->{status} = $options{new_datas}->{$self->{instance} . '_status'}; + $self->{result_values}->{display} = $options{new_datas}->{$self->{instance} . '_display'}; + $self->{result_values}->{type} = $options{new_datas}->{$self->{instance} . '_type'}; + $self->{result_values}->{is_running} = $options{new_datas}->{$self->{instance} . '_is_running'}; + return 0; +} + +sub custom_long_threshold { + my ($self, %options) = @_; + my $status = 'ok'; + my $message; + + eval { + local $SIG{__WARN__} = sub { $message = $_[0]; }; + local $SIG{__DIE__} = sub { $message = $_[0]; }; + + if (defined($instance_mode->{option_results}->{critical_long}) && $instance_mode->{option_results}->{critical_long} ne '' && + eval "$instance_mode->{option_results}->{critical_long}") { + $status = 'critical'; + } elsif (defined($instance_mode->{option_results}->{warning_long}) && $instance_mode->{option_results}->{warning_long} ne '' && + eval "$instance_mode->{option_results}->{warning_long}") { + $status = 'warning'; + } + }; + if (defined($message)) { + $self->{output}->output_add(long_msg => 'filter status issue: ' . $message); + } + + return $status; +} + +sub custom_long_output { + my ($self, %options) = @_; + my $msg = 'started since : ' . centreon::plugins::misc::change_seconds(value => $self->{result_values}->{elapsed}); + + return $msg; +} + +sub custom_long_calc { + my ($self, %options) = @_; + + $self->{result_values}->{status} = $options{new_datas}->{$self->{instance} . '_status'}; + $self->{result_values}->{display} = $options{new_datas}->{$self->{instance} . '_display'}; + $self->{result_values}->{elapsed} = $options{new_datas}->{$self->{instance} . '_elapsed'}; + $self->{result_values}->{type} = $options{new_datas}->{$self->{instance} . '_type'}; + $self->{result_values}->{is_running} = $options{new_datas}->{$self->{instance} . '_is_running'}; + + return -11 if ($self->{result_values}->{is_running} != 1); + + return 0; +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'global', type => 0 }, + { name => 'job', type => 1, cb_prefix_output => 'prefix_job_output', message_multiple => 'All jobs are ok', skipped_code => { -11 => 1, -10 => 1 } }, + ]; + + $self->{maps_counters}->{global} = [ + { label => 'total', set => { + key_values => [ { name => 'total' } ], + output_template => 'Total Jobs : %s', + perfdatas => [ + { label => 'total', value => 'total_absolute', template => '%s', min => 0 }, + ], + } + }, + ]; + + $self->{maps_counters}->{job} = [ + { label => 'status', threshold => 0, set => { + key_values => [ { name => 'status' }, { name => 'display' }, { name => 'type' }, { name => 'is_running' } ], + closure_custom_calc => $self->can('custom_status_calc'), + closure_custom_output => $self->can('custom_status_output'), + closure_custom_perfdata => sub { return 0; }, + closure_custom_threshold_check => $self->can('custom_status_threshold'), + } + }, + { label => 'long', threshold => 0, set => { + key_values => [ { name => 'status' }, { name => 'display' }, { name => 'elapsed' }, { name => 'type' }, { name => 'is_running' } ], + closure_custom_calc => $self->can('custom_long_calc'), + closure_custom_output => $self->can('custom_long_output'), + closure_custom_perfdata => sub { return 0; }, + closure_custom_threshold_check => $self->can('custom_long_threshold'), + } + }, + ]; +} + +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 => + { + "timeout:s" => { name => 'timeout', default => 50 }, + "command:s" => { name => 'command', default => 'powershell.exe' }, + "command-path:s" => { name => 'command_path' }, + "command-options:s" => { name => 'command_options', default => '-InputFormat none -NoLogo -EncodedCommand' }, + "no-ps" => { name => 'no_ps' }, + "ps-exec-only" => { name => 'ps_exec_only' }, + "filter-name:s" => { name => 'filter_name' }, + "filter-type:s" => { name => 'filter_type' }, + "filter-end-time:s" => { name => 'filter_end_time', default => 86400 }, + "filter-start-time:s" => { name => 'filter_start_time' }, + "ok-status:s" => { name => 'ok_status', default => '' }, + "warning-status:s" => { name => 'warning_status', default => '' }, + "critical-status:s" => { name => 'critical_status', default => '%{is_running} == 0 and not %{status} =~ /Success/i' }, + "warning-long:s" => { name => 'warning_long' }, + "critical-long:s" => { name => 'critical_long' }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::check_options(%options); + + $instance_mode = $self; + $self->change_macros(); +} + +sub prefix_job_output { + my ($self, %options) = @_; + + return "Job '" . $options{instance_value}->{display} . "' "; +} + +sub change_macros { + my ($self, %options) = @_; + + foreach (('ok_status', 'warning_status', 'critical_status', 'warning_long', 'critical_long')) { + if (defined($self->{option_results}->{$_})) { + $self->{option_results}->{$_} =~ s/%\{(.*?)\}/\$self->{result_values}->{$1}/g; + } + } +} + +sub manage_selection { + my ($self, %options) = @_; + + my $ps = centreon::common::powershell::veeam::jobstatus::get_powershell( + no_ps => $self->{option_results}->{no_ps}); + + $self->{option_results}->{command_options} .= " " . $ps; + my ($stdout) = centreon::plugins::misc::execute(output => $self->{output}, + options => $self->{option_results}, + command => $self->{option_results}->{command}, + command_path => $self->{option_results}->{command_path}, + command_options => $self->{option_results}->{command_options}); + if (defined($self->{option_results}->{ps_exec_only})) { + $self->{output}->output_add(severity => 'OK', + short_msg => $stdout); + $self->{output}->display(nolabel => 1, force_ignore_perfdata => 1, force_long_output => 1); + $self->{output}->exit(); + } + + #[name = xxxx ][type = Backup ][isrunning = False ][result = Success ][creationTimeUTC = 1512875246.2 ][endTimeUTC = 1512883615.377 ] + #[name = xxxx ][type = Backup ][isrunning = False ][result = ][creationTimeUTC = ][endTimeUTC = ] + #[name = xxxx ][type = BackupSync ][isrunning = True ][result = None ][creationTimeUTC = 1513060425.027 ][endTimeUTC = -2208992400 ] + + #is_running = 2 (never running) + $self->{global} = { total => 0 }; + $self->{job} = {}; + my $current_time = time(); + foreach my $line (split /\n/, $stdout) { + next if ($line !~ /^\[name\s*=(.*?)\]\[type\s*=(.*?)\]\[isrunning\s*=(.*?)\]\[result\s*=(.*?)\]\[creationTimeUTC\s*=(.*?)\]\[endTimeUTC\s*=(.*?)\]/i); + + my ($name, $type, $is_running, $result, $start_time, $end_time) = (centreon::plugins::misc::trim($1), + centreon::plugins::misc::trim($2), centreon::plugins::misc::trim($3), centreon::plugins::misc::trim($4), + centreon::plugins::misc::trim($5), centreon::plugins::misc::trim($6)); + + if (defined($self->{option_results}->{filter_name}) && $self->{option_results}->{filter_name} ne '' && + $name !~ /$self->{option_results}->{filter_name}/) { + $self->{output}->output_add(long_msg => "skipping job '" . $name . "': no matching filter.", debug => 1); + next; + } + if (defined($self->{option_results}->{filter_type}) && $self->{option_results}->{filter_type} ne '' && + $type !~ /$self->{option_results}->{filter_type}/) { + $self->{output}->output_add(long_msg => "skipping job '" . $name . "': no matching filter type.", debug => 1); + next; + } + if (defined($self->{option_results}->{filter_end_time}) && $self->{option_results}->{filter_end_time} =~ /[0-9]+/ && + defined($end_time) && $end_time =~ /[0-9]+/ && $end_time < $current_time - $self->{option_results}->{filter_end_time}) { + $self->{output}->output_add(long_msg => "skipping job '" . $name . "': end time too old.", debug => 1); + next; + } + if (defined($self->{option_results}->{filter_start_time}) && $self->{option_results}->{filter_start_time} =~ /[0-9]+/ && + defined($start_time) && $start_time =~ /[0-9]+/ && $start_time < $current_time - $self->{option_results}->{filter_start_time}) { + $self->{output}->output_add(long_msg => "skipping job '" . $name . "': start time too old.", debug => 1); + next; + } + + my $elapsed_time; + $elapsed_time = $current_time - $start_time if ($start_time =~ /[0-9]/); + $self->{job}->{$name} = { + display => $name, + elapsed => $elapsed_time, + type => $type, + is_running => ($is_running =~ /True/) ? 1 : ($start_time !~ /[0-9]/ ? 2 : 0), + status => $result ne '' ? $result : '-', + }; + $self->{global}->{total}++; + } +} + +1; + +__END__ + +=head1 MODE + +Check job status. + +=over 8 + +=item B<--timeout> + +Set timeout time for command execution (Default: 50 sec) + +=item B<--no-ps> + +Don't encode powershell. To be used with --command and 'type' command. + +=item B<--command> + +Command to get information (Default: 'powershell.exe'). +Can be changed if you have output in a file. To be used with --no-ps option!!! + +=item B<--command-path> + +Command path (Default: none). + +=item B<--command-options> + +Command options (Default: '-InputFormat none -NoLogo -EncodedCommand'). + +=item B<--ps-exec-only> + +Print powershell output. + +=item B<--filter-name> + +Filter job name (can be a regexp). + +=item B<--filter-type> + +Filter job type (can be a regexp). + +=item B<--filter-start-time> + +Filter job with start time greater than current time less value in seconds. + +=item B<--filter-end-time> + +Filter job with end time greater than current time less value in seconds (Default: 86400). + +=item B<--ok-status> + +Set ok threshold for status (Default: '') +Can used special variables like: %{display}, %{status}, %{type}, %{is_running}. + +=item B<--warning-status> + +Set warning threshold for status (Default: '') +Can used special variables like: %{display}, %{status}, %{type}, %{is_running}. + +=item B<--critical-status> + +Set critical threshold for status (Default: '%{is_running} == 0 and not %{status} =~ /Success/i'). +Can used special variables like: %{display}, %{status}, %{type}, %{is_running}. + +=item B<--warning-long> + +Set warning threshold for long jobs (Default: none) +Can used special variables like: %{display}, %{status}, %{type}, %{elapsed}. + +=item B<--critical-long> + +Set critical threshold for long jobs (Default: none). +Can used special variables like: %{display}, %{status}, %{type}, %{elapsed}. + +=item B<--warning-total> + +Set warning threshold for total jobs. + +=item B<--critical-total> + +Set critical threshold for total jobs. + +=back + +=cut diff --git a/centreon-plugins/apps/backup/veeam/local/mode/listjobs.pm b/centreon-plugins/apps/backup/veeam/local/mode/listjobs.pm new file mode 100644 index 000000000..7cf5a2860 --- /dev/null +++ b/centreon-plugins/apps/backup/veeam/local/mode/listjobs.pm @@ -0,0 +1,163 @@ +# +# Copyright 2017 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::backup::veeam::local::mode::listjobs; + +use base qw(centreon::plugins::mode); + +use strict; +use warnings; +use centreon::common::powershell::veeam::listjobs; +use centreon::plugins::misc; + +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 => + { + "timeout:s" => { name => 'timeout', default => 50 }, + "command:s" => { name => 'command', default => 'powershell.exe' }, + "command-path:s" => { name => 'command_path' }, + "command-options:s" => { name => 'command_options', default => '-InputFormat none -NoLogo -EncodedCommand' }, + "no-ps" => { name => 'no_ps' }, + "ps-exec-only" => { name => 'ps_exec_only' }, + "filter-name:s" => { name => 'filter_name' }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::init(%options); +} + +sub run { + my ($self, %options) = @_; + + $self->manage_selection(%options); + foreach (sort keys %{$self->{jobs}}) { + $self->{output}->output_add(long_msg => "'" . $_ . "' [type = " . $self->{jobs}->{$_}->{type} . "]"); + } + + $self->{output}->output_add(severity => 'OK', + short_msg => 'List jobs:'); + $self->{output}->display(nolabel => 1, force_ignore_perfdata => 1, force_long_output => 1); + $self->{output}->exit(); +} + +sub disco_format { + my ($self, %options) = @_; + + $self->{output}->add_disco_format(elements => ['name', 'type']); +} + +sub disco_show { + my ($self, %options) = @_; + + $self->manage_selection(%options); + foreach (sort keys %{$self->{jobs}}) { + $self->{output}->add_disco_entry( + name => $_, + type => $self->{jobs}->{$_}->{type}, + ); + } +} + +sub manage_selection { + my ($self, %options) = @_; + + my $ps = centreon::common::powershell::veeam::listjobs::get_powershell( + no_ps => $self->{option_results}->{no_ps}); + + $self->{option_results}->{command_options} .= " " . $ps; + my ($stdout) = centreon::plugins::misc::execute(output => $self->{output}, + options => $self->{option_results}, + command => $self->{option_results}->{command}, + command_path => $self->{option_results}->{command_path}, + command_options => $self->{option_results}->{command_options}); + if (defined($self->{option_results}->{ps_exec_only})) { + $self->{output}->output_add(severity => 'OK', + short_msg => $stdout); + $self->{output}->display(nolabel => 1, force_ignore_perfdata => 1, force_long_output => 1); + $self->{output}->exit(); + } + + $self->{jobs} = {}; + my @lines = split /\n/, $stdout; + foreach my $line (@lines) { + next if ($line !~ /^\[name\s*=(.*?)\]\[type\s*=(.*?)\]/i); + my ($name, $type) = (centreon::plugins::misc::trim($1), centreon::plugins::misc::trim($2)); + + if (defined($self->{option_results}->{filter_name}) && $self->{option_results}->{filter_name} ne '' && + $name !~ /$self->{option_results}->{filter_name}/i) { + $self->{output}->output_add(long_msg => "skipping job '" . $name . "': no type or no matching filter type", debug => 1); + next; + } + + $self->{jobs}->{$name} = { type => $type }; + } +} + +1; + +__END__ + +=head1 MODE + +List jobs. + +=over 8 + +=item B<--timeout> + +Set timeout time for command execution (Default: 50 sec) + +=item B<--no-ps> + +Don't encode powershell. To be used with --command and 'type' command. + +=item B<--command> + +Command to get information (Default: 'powershell.exe'). +Can be changed if you have output in a file. To be used with --no-ps option!!! + +=item B<--command-path> + +Command path (Default: none). + +=item B<--command-options> + +Command options (Default: '-InputFormat none -NoLogo -EncodedCommand'). + +=item B<--ps-exec-only> + +Print powershell output. + +=item B<--filter-name> + +Filter job name (can be a regexp). + +=back + +=cut diff --git a/centreon-plugins/apps/voip/asterisk/remote/plugin.pm b/centreon-plugins/apps/backup/veeam/local/plugin.pm similarity index 66% rename from centreon-plugins/apps/voip/asterisk/remote/plugin.pm rename to centreon-plugins/apps/backup/veeam/local/plugin.pm index 40a94a11a..2d59c721f 100644 --- a/centreon-plugins/apps/voip/asterisk/remote/plugin.pm +++ b/centreon-plugins/apps/backup/veeam/local/plugin.pm @@ -18,7 +18,7 @@ # limitations under the License. # -package apps::voip::asterisk::remote::plugin; +package apps::backup::veeam::local::plugin; use strict; use warnings; @@ -26,28 +26,24 @@ use base qw(centreon::plugins::script_simple); sub new { my ($class, %options) = @_; - my $self = $class->SUPER::new(package => __PACKAGE__, %options); bless $self, $class; - $self->{version} = '1.1'; + $self->{version} = '0.1'; %{$self->{modes}} = ( - 'showpeers' => 'apps::voip::asterisk::remote::mode::showpeers', - 'dahdistatus' => 'apps::voip::asterisk::remote::mode::dahdistatus', - 'activecalls' => 'apps::voip::asterisk::remote::mode::activecalls', - 'externalcalls' => 'apps::voip::asterisk::remote::mode::externalcalls', - ); + 'job-status' => 'apps::backup::veeam::local::mode::jobstatus', + 'list-jobs' => 'apps::backup::veeam::local::mode::listjobs', + ); return $self; } - 1; __END__ =head1 PLUGIN DESCRIPTION -Check Asterisk through AMI interface (AMI socket; telnet perl module required) +Check Veeam through powershell. =cut diff --git a/centreon-plugins/apps/centreon/local/mode/retentionbroker.pm b/centreon-plugins/apps/centreon/local/mode/retentionbroker.pm index 25f499963..cbb69293d 100644 --- a/centreon-plugins/apps/centreon/local/mode/retentionbroker.pm +++ b/centreon-plugins/apps/centreon/local/mode/retentionbroker.pm @@ -98,20 +98,20 @@ sub run { short_msg => "'$config': cannot parse xml"); next; } - my %failover_finded = (); - my %file_finded = (); + my %failover_found = (); + my %file_found = (); my $temporary; foreach my $node ($xml->findnodes('/centreonBroker/output')) { my %load = (); foreach my $element ($node->getChildrenByTagName('*')) { if ($element->nodeName eq 'failover') { - $failover_finded{$element->textContent} = 1; + $failover_found{$element->textContent} = 1; } elsif ($element->nodeName =~ /^(name|type|path)$/) { $load{$element->nodeName} = $element->textContent; } } if (defined($load{type}) && $load{type} eq 'file') { - $file_finded{$load{name}} = {%load}; + $file_found{$load{name}} = {%load}; } } @@ -123,10 +123,10 @@ sub run { # Check failovers my $current_total = 0; - foreach my $failover (sort keys %failover_finded) { - next if (!defined($file_finded{$failover})); + foreach my $failover (sort keys %failover_found) { + next if (!defined($file_found{$failover})); - my ($status, $total, $size) = $self->check_directory(config => $config, path => $file_finded{$failover}->{path}); + my ($status, $total, $size) = $self->check_directory(config => $config, path => $file_found{$failover}->{path}); next if (!$status); $current_total += $total; diff --git a/centreon-plugins/apps/centreon/sql/mode/multiservices.pm b/centreon-plugins/apps/centreon/sql/mode/multiservices.pm index b05aed885..185154088 100644 --- a/centreon-plugins/apps/centreon/sql/mode/multiservices.pm +++ b/centreon-plugins/apps/centreon/sql/mode/multiservices.pm @@ -1,4 +1,5 @@ -# Copyright 2016 Centreon (http://www.centreon.com/) +# +# Copyright 2017 Centreon (http://www.centreon.com/) # # Centreon is a full-fledged industry-strength solution that meets # the needs in IT infrastructure and application monitoring for diff --git a/centreon-plugins/apps/centreon/sql/mode/virtualservice.pm b/centreon-plugins/apps/centreon/sql/mode/virtualservice.pm index a84ec2ec4..765caf67e 100644 --- a/centreon-plugins/apps/centreon/sql/mode/virtualservice.pm +++ b/centreon-plugins/apps/centreon/sql/mode/virtualservice.pm @@ -1,5 +1,5 @@ # -# Copyright 2016 Centreon (http://www.centreon.com/) +# Copyright 2017 Centreon (http://www.centreon.com/) # # Centreon is a full-fledged industry-strength solution that meets # the needs in IT infrastructure and application monitoring for diff --git a/centreon-plugins/apps/haproxy/snmp/mode/backendusage.pm b/centreon-plugins/apps/haproxy/snmp/mode/backendusage.pm new file mode 100644 index 000000000..56e941b34 --- /dev/null +++ b/centreon-plugins/apps/haproxy/snmp/mode/backendusage.pm @@ -0,0 +1,278 @@ +# +# Copyright 2017 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::haproxy::snmp::mode::backendusage; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; +use Digest::MD5 qw(md5_hex); + +my $instance_mode; + +sub custom_status_threshold { + my ($self, %options) = @_; + my $status = 'ok'; + my $message; + + eval { + local $SIG{__WARN__} = sub { $message = $_[0]; }; + local $SIG{__DIE__} = sub { $message = $_[0]; }; + + if (defined($instance_mode->{option_results}->{critical_status}) && $instance_mode->{option_results}->{critical_status} ne '' && + eval "$instance_mode->{option_results}->{critical_status}") { + $status = 'critical'; + } elsif (defined($instance_mode->{option_results}->{warning_status}) && $instance_mode->{option_results}->{warning_status} ne '' && + eval "$instance_mode->{option_results}->{warning_status}") { + $status = 'warning'; + } + }; + if (defined($message)) { + $self->{output}->output_add(long_msg => 'filter status issue: ' . $message); + } + + return $status; +} + +sub custom_status_output { + my ($self, %options) = @_; + + my $msg = 'status : ' . $self->{result_values}->{status}; + return $msg; +} + +sub custom_status_calc { + my ($self, %options) = @_; + + $self->{result_values}->{status} = $options{new_datas}->{$self->{instance} . '_alBackendStatus'}; + $self->{result_values}->{display} = $options{new_datas}->{$self->{instance} . '_display'}; + return 0; +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'backend', type => 1, cb_prefix_output => 'prefix_backend_output', message_multiple => 'All backends are ok' }, + ]; + + $self->{maps_counters}->{backend} = [ + { label => 'status', threshold => 0, set => { + key_values => [ { name => 'alBackendStatus' }, { name => 'display' } ], + closure_custom_calc => $self->can('custom_status_calc'), + closure_custom_output => $self->can('custom_status_output'), + closure_custom_perfdata => sub { return 0; }, + closure_custom_threshold_check => $self->can('custom_status_threshold'), + } + }, + { label => 'current-queue', set => { + key_values => [ { name => 'alBackendQueueCur' }, { name => 'display' } ], + output_template => 'Current queue : %s', + perfdatas => [ + { label => 'current_queue', value => 'alBackendQueueCur_absolute', template => '%s', + min => 0, label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + { label => 'current-sessions', set => { + key_values => [ { name => 'alBackendSessionCur' }, { name => 'display' } ], + output_template => 'Current sessions : %s', + perfdatas => [ + { label => 'current_sessions', value => 'alBackendSessionCur_absolute', template => '%s', + min => 0, label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + { label => 'total-sessions', set => { + key_values => [ { name => 'alBackendSessionTotal', diff => 1 }, { name => 'display' } ], + output_template => 'Total sessions : %s', + perfdatas => [ + { label => 'total_connections', value => 'alBackendSessionTotal_absolute', template => '%s', + min => 0, label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + { label => 'traffic-in', set => { + key_values => [ { name => 'alBackendBytesIN', diff => 1 }, { name => 'display' } ], + output_template => 'Traffic In : %s %s/s', + per_second => 1, output_change_bytes => 2, + perfdatas => [ + { label => 'traffic_in', value => 'alBackendBytesIN_per_second', template => '%.2f', + min => 0, unit => 'b/s', label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + { label => 'traffic-out', set => { + key_values => [ { name => 'alBackendBytesOUT', diff => 1 }, { name => 'display' } ], + output_template => 'Traffic Out : %s %s/s', + per_second => 1, output_change_bytes => 2, + perfdatas => [ + { label => 'traffic_out', value => 'alBackendBytesOUT_per_second', template => '%.2f', + min => 0, unit => 'b/s', label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + ]; +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options, statefile => 1); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => + { + "filter-name:s" => { name => 'filter_name' }, + "warning-status:s" => { name => 'warning_status', default => '' }, + "critical-status:s" => { name => 'critical_status', default => '%{status} !~ /UP/i' }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::check_options(%options); + + $instance_mode = $self; + $self->change_macros(); +} + +sub prefix_backend_output { + my ($self, %options) = @_; + + return "Backend '" . $options{instance_value}->{display} . "' "; +} + +sub change_macros { + my ($self, %options) = @_; + + foreach (('warning_status', 'critical_status')) { + if (defined($self->{option_results}->{$_})) { + $self->{option_results}->{$_} =~ s/%\{(.*?)\}/\$self->{result_values}->{$1}/g; + } + } +} + +my $mapping = { + alBackendName => { oid => '.1.3.6.1.4.1.23263.4.2.1.3.3.1.3' }, + alBackendQueueCur => { oid => '.1.3.6.1.4.1.23263.4.2.1.3.3.1.4' }, + alBackendSessionCur => { oid => '.1.3.6.1.4.1.23263.4.2.1.3.3.1.7' }, + alBackendSessionTotal => { oid => '.1.3.6.1.4.1.23263.4.2.1.3.3.1.10' }, + alBackendBytesIN => { oid => '.1.3.6.1.4.1.23263.4.2.1.3.3.1.12' }, + alBackendBytesOUT => { oid => '.1.3.6.1.4.1.23263.4.2.1.3.3.1.13' }, + alBackendStatus => { oid => '.1.3.6.1.4.1.23263.4.2.1.3.3.1.20' }, +}; + +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->{backend} = {}; + my $snmp_result = $options{snmp}->get_multiple_table( + oids => [ + { oid => $mapping->{alBackendName}->{oid} }, + { oid => $mapping->{alBackendQueueCur}->{oid} }, + { oid => $mapping->{alBackendSessionCur}->{oid} }, + { oid => $mapping->{alBackendSessionTotal}->{oid} }, + { oid => $mapping->{alBackendBytesIN}->{oid} }, + { oid => $mapping->{alBackendBytesOUT}->{oid} }, + { oid => $mapping->{alBackendStatus}->{oid} }, + ], + return_type => 1, nothing_quit => 1); + + foreach my $oid (keys %{$snmp_result}) { + next if ($oid !~ /^$mapping->{alBackendName}->{oid}\.(.*)$/); + my $instance = $1; + my $result = $options{snmp}->map_instance(mapping => $mapping, results => $snmp_result, instance => $instance); + + if (defined($self->{option_results}->{filter_name}) && $self->{option_results}->{filter_name} ne '' && + $result->{alBackendName} !~ /$self->{option_results}->{filter_name}/) { + $self->{output}->output_add(long_msg => "skipping '" . $result->{wgPolicyName} . "': no matching filter.", debug => 1); + next; + } + + $result->{alBackendBytesIN} *= 8; + $result->{alBackendBytesOUT} *= 8; + $self->{backend}->{$instance} = { display => $result->{alBackendName}, + %$result + }; + } + + if (scalar(keys %{$self->{backend}}) <= 0) { + $self->{output}->add_option_msg(short_msg => "No backend found."); + $self->{output}->option_exit(); + } + + $self->{cache_name} = "haproxy_" . $self->{mode} . '_' . $options{snmp}->get_hostname() . '_' . $options{snmp}->get_port() . '_' . + (defined($self->{option_results}->{filter_counters}) ? md5_hex($self->{option_results}->{filter_counters}) : md5_hex('all')) . '_' . + (defined($self->{option_results}->{filter_name}) ? md5_hex($self->{option_results}->{filter_name}) : md5_hex('all')); +} + +1; + +__END__ + +=head1 MODE + +Check backend usage. + +=over 8 + +=item B<--filter-counters> + +Only display some counters (regexp can be used). +Example: --filter-counters='^total-sessions$' + +=item B<--filter-name> + +Filter backend name (can be a regexp). + +=item B<--warning-status> + +Set warning threshold for status. +Can used special variables like: %{status}, %{display} + +=item B<--critical-status> + +Set critical threshold for status (Default: '%{status} !~ /UP/i'). +Can used special variables like: %{status}, %{display} + +=item B<--warning-*> + +Threshold warning. +Can be: 'total-sessions', 'current-sessions', 'current-queue', +'traffic-in' (b/s), 'traffic-out' (b/s). + +=item B<--critical-*> + +Threshold critical. +Can be: 'total-sessions', 'current-sessions', 'current-queue', +'traffic-in' (b/s), 'traffic-out' (b/s). + +=back + +=cut diff --git a/centreon-plugins/apps/haproxy/snmp/mode/frontendusage.pm b/centreon-plugins/apps/haproxy/snmp/mode/frontendusage.pm new file mode 100644 index 000000000..5e40acd57 --- /dev/null +++ b/centreon-plugins/apps/haproxy/snmp/mode/frontendusage.pm @@ -0,0 +1,267 @@ +# +# Copyright 2017 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::haproxy::snmp::mode::frontendusage; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; +use Digest::MD5 qw(md5_hex); + +my $instance_mode; + +sub custom_status_threshold { + my ($self, %options) = @_; + my $status = 'ok'; + my $message; + + eval { + local $SIG{__WARN__} = sub { $message = $_[0]; }; + local $SIG{__DIE__} = sub { $message = $_[0]; }; + + if (defined($instance_mode->{option_results}->{critical_status}) && $instance_mode->{option_results}->{critical_status} ne '' && + eval "$instance_mode->{option_results}->{critical_status}") { + $status = 'critical'; + } elsif (defined($instance_mode->{option_results}->{warning_status}) && $instance_mode->{option_results}->{warning_status} ne '' && + eval "$instance_mode->{option_results}->{warning_status}") { + $status = 'warning'; + } + }; + if (defined($message)) { + $self->{output}->output_add(long_msg => 'filter status issue: ' . $message); + } + + return $status; +} + +sub custom_status_output { + my ($self, %options) = @_; + + my $msg = 'status : ' . $self->{result_values}->{status}; + return $msg; +} + +sub custom_status_calc { + my ($self, %options) = @_; + + $self->{result_values}->{status} = $options{new_datas}->{$self->{instance} . '_alFrontendStatus'}; + $self->{result_values}->{display} = $options{new_datas}->{$self->{instance} . '_display'}; + return 0; +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'frontend', type => 1, cb_prefix_output => 'prefix_frontend_output', message_multiple => 'All frontends are ok' }, + ]; + + $self->{maps_counters}->{frontend} = [ + { label => 'status', threshold => 0, set => { + key_values => [ { name => 'alFrontendStatus' }, { name => 'display' } ], + closure_custom_calc => $self->can('custom_status_calc'), + closure_custom_output => $self->can('custom_status_output'), + closure_custom_perfdata => sub { return 0; }, + closure_custom_threshold_check => $self->can('custom_status_threshold'), + } + }, + { label => 'current-sessions', set => { + key_values => [ { name => 'alFrontendSessionCur' }, { name => 'display' } ], + output_template => 'Current sessions : %s', + perfdatas => [ + { label => 'current_sessions', value => 'alFrontendSessionCur_absolute', template => '%s', + min => 0, label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + { label => 'total-sessions', set => { + key_values => [ { name => 'alFrontendSessionTotal', diff => 1 }, { name => 'display' } ], + output_template => 'Total sessions : %s', + perfdatas => [ + { label => 'total_connections', value => 'alFrontendSessionTotal_absolute', template => '%s', + min => 0, label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + { label => 'traffic-in', set => { + key_values => [ { name => 'alFrontendBytesIN', diff => 1 }, { name => 'display' } ], + output_template => 'Traffic In : %s %s/s', + per_second => 1, output_change_bytes => 2, + perfdatas => [ + { label => 'traffic_in', value => 'alFrontendBytesIN_per_second', template => '%.2f', + min => 0, unit => 'b/s', label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + { label => 'traffic-out', set => { + key_values => [ { name => 'alFrontendBytesOUT', diff => 1 }, { name => 'display' } ], + output_template => 'Traffic Out : %s %s/s', + per_second => 1, output_change_bytes => 2, + perfdatas => [ + { label => 'traffic_out', value => 'alFrontendBytesOUT_per_second', template => '%.2f', + min => 0, unit => 'b/s', label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + ]; +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options, statefile => 1); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => + { + "filter-name:s" => { name => 'filter_name' }, + "warning-status:s" => { name => 'warning_status', default => '' }, + "critical-status:s" => { name => 'critical_status', default => '%{status} !~ /OPEN/i' }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::check_options(%options); + + $instance_mode = $self; + $self->change_macros(); +} + +sub prefix_frontend_output { + my ($self, %options) = @_; + + return "Frontend '" . $options{instance_value}->{display} . "' "; +} + +sub change_macros { + my ($self, %options) = @_; + + foreach (('warning_status', 'critical_status')) { + if (defined($self->{option_results}->{$_})) { + $self->{option_results}->{$_} =~ s/%\{(.*?)\}/\$self->{result_values}->{$1}/g; + } + } +} + +my $mapping = { + alFrontendName => { oid => '.1.3.6.1.4.1.23263.4.2.1.3.2.1.3' }, + alFrontendSessionCur => { oid => '.1.3.6.1.4.1.23263.4.2.1.3.2.1.4' }, + alFrontendSessionTotal => { oid => '.1.3.6.1.4.1.23263.4.2.1.3.2.1.7' }, + alFrontendBytesIN => { oid => '.1.3.6.1.4.1.23263.4.2.1.3.2.1.8' }, + alFrontendBytesOUT => { oid => '.1.3.6.1.4.1.23263.4.2.1.3.2.1.9' }, + alFrontendStatus => { oid => '.1.3.6.1.4.1.23263.4.2.1.3.2.1.13' }, +}; + +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->{frontend} = {}; + my $snmp_result = $options{snmp}->get_multiple_table( + oids => [ + { oid => $mapping->{alFrontendName}->{oid} }, + { oid => $mapping->{alFrontendSessionCur}->{oid} }, + { oid => $mapping->{alFrontendSessionTotal}->{oid} }, + { oid => $mapping->{alFrontendBytesIN}->{oid} }, + { oid => $mapping->{alFrontendBytesOUT}->{oid} }, + { oid => $mapping->{alFrontendStatus}->{oid} }, + ], + return_type => 1, nothing_quit => 1); + + foreach my $oid (keys %{$snmp_result}) { + next if ($oid !~ /^$mapping->{alFrontendName}->{oid}\.(.*)$/); + my $instance = $1; + my $result = $options{snmp}->map_instance(mapping => $mapping, results => $snmp_result, instance => $instance); + + if (defined($self->{option_results}->{filter_name}) && $self->{option_results}->{filter_name} ne '' && + $result->{alFrontendName} !~ /$self->{option_results}->{filter_name}/) { + $self->{output}->output_add(long_msg => "skipping '" . $result->{wgPolicyName} . "': no matching filter.", debug => 1); + next; + } + + $result->{alFrontendBytesIN} *= 8; + $result->{alFrontendBytesOUT} *= 8; + $self->{frontend}->{$instance} = { display => $result->{alFrontendName}, + %$result + }; + } + + if (scalar(keys %{$self->{frontend}}) <= 0) { + $self->{output}->add_option_msg(short_msg => "No frontend found."); + $self->{output}->option_exit(); + } + + $self->{cache_name} = "haproxy_" . $self->{mode} . '_' . $options{snmp}->get_hostname() . '_' . $options{snmp}->get_port() . '_' . + (defined($self->{option_results}->{filter_counters}) ? md5_hex($self->{option_results}->{filter_counters}) : md5_hex('all')) . '_' . + (defined($self->{option_results}->{filter_name}) ? md5_hex($self->{option_results}->{filter_name}) : md5_hex('all')); +} + +1; + +__END__ + +=head1 MODE + +Check frontend usage. + +=over 8 + +=item B<--filter-counters> + +Only display some counters (regexp can be used). +Example: --filter-counters='^total-connections$' + +=item B<--filter-name> + +Filter backend name (can be a regexp). + +=item B<--warning-status> + +Set warning threshold for status. +Can used special variables like: %{status}, %{display} + +=item B<--critical-status> + +Set critical threshold for status (Default: '%{status} !~ /OPEN/i'). +Can used special variables like: %{status}, %{display} + +=item B<--warning-*> + +Threshold warning. +Can be: 'total-sessions', 'current-sessions', +'traffic-in' (b/s), 'traffic-out' (b/s). + +=item B<--critical-*> + +Threshold critical. +Can be: 'total-sessions', 'current-sessions', +'traffic-in' (b/s), 'traffic-out' (b/s). + +=back + +=cut diff --git a/centreon-plugins/apps/haproxy/snmp/plugin.pm b/centreon-plugins/apps/haproxy/snmp/plugin.pm new file mode 100644 index 000000000..53237ade7 --- /dev/null +++ b/centreon-plugins/apps/haproxy/snmp/plugin.pm @@ -0,0 +1,49 @@ +# +# Copyright 2017 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::haproxy::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}} = ( + 'backend-usage' => 'apps::haproxy::snmp::mode::backendusage', + 'frontend-usage' => 'apps::haproxy::snmp::mode::frontendusage', + ); + + return $self; +} + +1; + +__END__ + +=head1 PLUGIN DESCRIPTION + +Check haproxy software in SNMP. + +=cut diff --git a/centreon-plugins/apps/hyperv/2012/local/mode/scvmmintegrationservice.pm b/centreon-plugins/apps/hyperv/2012/local/mode/scvmmintegrationservice.pm index 3c5267d4f..2a3842597 100644 --- a/centreon-plugins/apps/hyperv/2012/local/mode/scvmmintegrationservice.pm +++ b/centreon-plugins/apps/hyperv/2012/local/mode/scvmmintegrationservice.pm @@ -38,11 +38,13 @@ sub custom_status_threshold { local $SIG{__WARN__} = sub { $message = $_[0]; }; local $SIG{__DIE__} = sub { $message = $_[0]; }; - if (defined($instance_mode->{option_results}->{critical_status}) && $instance_mode->{option_results}->{critical_status} ne '' && - eval "$instance_mode->{option_results}->{critical_status}") { + my $label = $self->{label}; + $label =~ s/-/_/g; + if (defined($instance_mode->{option_results}->{'critical_' . $label}) && $instance_mode->{option_results}->{'critical_' . $label} ne '' && + eval "$instance_mode->{option_results}->{'critical_' . $label}") { $status = 'critical'; - } elsif (defined($instance_mode->{option_results}->{warning_status}) && $instance_mode->{option_results}->{warning_status} ne '' && - eval "$instance_mode->{option_results}->{warning_status}") { + } elsif (defined($instance_mode->{option_results}->{'warning_' . $label}) && $instance_mode->{option_results}->{'warning_' . $label} ne '' && + eval "$instance_mode->{option_results}->{'warning_' . $label}") { $status = 'warning'; } }; @@ -74,6 +76,23 @@ sub custom_status_calc { return 0; } +sub custom_integrationservice_output { + my ($self, %options) = @_; + my $msg = $self->{result_values}->{output_label} . ' : ' . $self->{result_values}->{service_status}; + + return $msg; +} + +sub custom_integrationservice_calc { + my ($self, %options) = @_; + + $self->{result_values}->{output_label} = $options{extra_options}->{output_label}; + $self->{result_values}->{service_status} = $options{new_datas}->{$self->{instance} . '_' . $options{extra_options}->{name_status}}; + $self->{result_values}->{vm} = $options{new_datas}->{$self->{instance} . '_vm'}; + $self->{result_values}->{status} = $options{new_datas}->{$self->{instance} . '_status'}; + return 0; +} + sub set_counters { my ($self, %options) = @_; @@ -91,6 +110,51 @@ sub set_counters { closure_custom_threshold_check => $self->can('custom_status_threshold'), } }, + { label => 'osshutdown-status', threshold => 0, set => { + key_values => [ { name => 'status' }, { name => 'vm' }, { name => 'operatingsystemshutdownenabled' } ], + closure_custom_calc => $self->can('custom_integrationservice_calc'), + closure_custom_calc_extra_options => { output_label => 'Operating System Shutdown', name_status => 'operatingsystemshutdownenabled' }, + closure_custom_output => $self->can('custom_integrationservice_output'), + closure_custom_perfdata => sub { return 0; }, + closure_custom_threshold_check => $self->can('custom_status_threshold'), + } + }, + { label => 'timesync-status', threshold => 0, set => { + key_values => [ { name => 'status' }, { name => 'vm' }, { name => 'timesynchronizationenabled' } ], + closure_custom_calc => $self->can('custom_integrationservice_calc'), + closure_custom_calc_extra_options => { output_label => 'Time Synchronization', name_status => 'timesynchronizationenabled' }, + closure_custom_output => $self->can('custom_integrationservice_output'), + closure_custom_perfdata => sub { return 0; }, + closure_custom_threshold_check => $self->can('custom_status_threshold'), + } + }, + { label => 'dataexchange-status', threshold => 0, set => { + key_values => [ { name => 'status' }, { name => 'vm' }, { name => 'dataexchangeenabled' } ], + closure_custom_calc => $self->can('custom_integrationservice_calc'), + closure_custom_calc_extra_options => { output_label => 'Data Exchange', name_status => 'dataexchangeenabled' }, + closure_custom_output => $self->can('custom_integrationservice_output'), + closure_custom_perfdata => sub { return 0; }, + closure_custom_threshold_check => $self->can('custom_status_threshold'), + } + }, + { label => 'heartbeat-status', threshold => 0, set => { + key_values => [ { name => 'status' }, { name => 'vm' }, { name => 'heartbeatenabled' } ], + closure_custom_calc => $self->can('custom_integrationservice_calc'), + closure_custom_calc_extra_options => { output_label => 'Heartbeat', name_status => 'heartbeatenabled' }, + closure_custom_output => $self->can('custom_integrationservice_output'), + closure_custom_perfdata => sub { return 0; }, + closure_custom_threshold_check => $self->can('custom_status_threshold'), + } + }, + { label => 'backup-status', threshold => 0, set => { + key_values => [ { name => 'status' }, { name => 'vm' }, { name => 'backupenabled' } ], + closure_custom_calc => $self->can('custom_integrationservice_calc'), + closure_custom_calc_extra_options => { output_label => 'Backup', name_status => 'backupenabled' }, + closure_custom_output => $self->can('custom_integrationservice_output'), + closure_custom_perfdata => sub { return 0; }, + closure_custom_threshold_check => $self->can('custom_status_threshold'), + } + }, ]; } @@ -124,6 +188,16 @@ sub new { "filter-status:s" => { name => 'filter_status' }, "warning-status:s" => { name => 'warning_status', default => '' }, "critical-status:s" => { name => 'critical_status', default => '%{vmaddition} =~ /not detected/i' }, + "warning-osshutdown-status:s" => { name => 'warning_osshutdown_status', default => '' }, + "critical-osshutdown-status:s" => { name => 'critical_osshutdown_status', default => '' }, + "warning-timesync-status:s" => { name => 'warning_timesync_status', default => '' }, + "critical-timesync-status:s" => { name => 'critical_timesync_status', default => '' }, + "warning-dataexchange-status:s" => { name => 'warning_dataexchange_status', default => '' }, + "critical-dataexchange-status:s" => { name => 'critical_dataexchange_status', default => '' }, + "warning-heartbeat-status:s" => { name => 'warning_heartbeat_status', default => '' }, + "critical-heartbeat-status:s" => { name => 'critical_heartbeat_status', default => '' }, + "warning-backup-status:s" => { name => 'warning_backup_status', default => '' }, + "critical-backup-status:s" => { name => 'critical_backup_status', default => '' }, }); return $self; } @@ -148,7 +222,9 @@ sub check_options { sub change_macros { my ($self, %options) = @_; - foreach (('warning_status', 'critical_status')) { + foreach (('warning_status', 'critical_status', 'warning_osshutdown_status', 'critical_osshutdown_status', + 'warning_timesync_status', 'critical_timesync_status', 'warning_dataexchange_status', 'critical_dataexchange_status', + 'warning_heartbeat_status', 'critical_heartbeat_status', 'warning_backup_status', 'critical_backup_status')) { if (defined($self->{option_results}->{$_})) { $self->{option_results}->{$_} =~ s/%\{(.*?)\}/\$self->{result_values}->{$1}/g; } diff --git a/centreon-plugins/apps/inin/ig/snmp/mode/stats.pm b/centreon-plugins/apps/inin/ig/snmp/mode/stats.pm index 5ef9add9f..ca8b7767a 100644 --- a/centreon-plugins/apps/inin/ig/snmp/mode/stats.pm +++ b/centreon-plugins/apps/inin/ig/snmp/mode/stats.pm @@ -98,7 +98,7 @@ sub manage_selection { my ($self, %options) = @_; $self->{cg} = {}; - my $snmp_result = $options{snmp}->get_table(oid => $oid_i3IgInfo, start => $oid_i3IgSipActiveCallsCount, end => , + my $snmp_result = $options{snmp}->get_table(oid => $oid_i3IgInfo, start => $oid_i3IgSipActiveCallsCount, nothing_quit => 1); foreach my $oid (keys %{$snmp_result}) { diff --git a/centreon-plugins/apps/java/hibernate/jmx/mode/stats.pm b/centreon-plugins/apps/java/hibernate/jmx/mode/stats.pm index fad0cd08f..52a67d7b3 100644 --- a/centreon-plugins/apps/java/hibernate/jmx/mode/stats.pm +++ b/centreon-plugins/apps/java/hibernate/jmx/mode/stats.pm @@ -148,7 +148,7 @@ sub manage_selection { $self->{output}->option_exit(); } - $self->{cache_name} = "hibernate_" . $self->{mode} . '_' . md5_hex($options{custom}->{url}) . '_' . + $self->{cache_name} = "hibernate_" . $self->{mode} . '_' . md5_hex($options{custom}->get_connection_info()) . '_' . (defined($self->{option_results}->{filter_counters}) ? md5_hex($self->{option_results}->{filter_counters}) : md5_hex('all')) . '_' . (defined($self->{option_results}->{filter_name}) ? md5_hex($self->{option_results}->{filter_name}) : md5_hex('all')); } diff --git a/centreon-plugins/apps/java/jboss/jmx/mode/datasourceusage.pm b/centreon-plugins/apps/java/jboss/jmx/mode/datasourceusage.pm new file mode 100644 index 000000000..7888a1869 --- /dev/null +++ b/centreon-plugins/apps/java/jboss/jmx/mode/datasourceusage.pm @@ -0,0 +1,164 @@ +# +# Copyright 2017 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::java::jboss::jmx::mode::datasourceusage; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; +use Digest::MD5 qw(md5_hex); + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'datasource', type => 1, cb_prefix_output => 'prefix_ds_output', message_multiple => 'All datasources are ok' }, + ]; + + $self->{maps_counters}->{datasource} = [ + { label => 'active-con', set => { + key_values => [ { name => 'ActiveCount' }, { name => 'display' } ], + output_template => 'Current Active Connections : %s', + perfdatas => [ + { label => 'active_con', value => 'ActiveCount_absolute', template => '%s', min => 0, + label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + { label => 'available-con', set => { + key_values => [ { name => 'AvailableCount' }, { name => 'display' } ], + output_template => 'Current Available Connections : %s', + perfdatas => [ + { label => 'available_con', value => 'AvailableCount_absolute', template => '%s', min => 0, + label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + { label => 'in-use-con', set => { + key_values => [ { name => 'InUseCount' }, { name => 'display' } ], + output_template => 'Current In Use Connections : %s', + perfdatas => [ + { label => 'in_use_con', value => 'InUseCount_absolute', template => '%s', min => 0, + label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + { label => 'created-con', set => { + key_values => [ { name => 'CreatedCount', diff => 1 }, { name => 'display' } ], + output_template => 'Created Connections : %s', + perfdatas => [ + { label => 'created_con', value => 'CreatedCount_absolute', template => '%s', min => 0, + label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + ]; +} + +sub prefix_ds_output { + my ($self, %options) = @_; + + return "Datasource '" . $options{instance_value}->{display} . "' "; +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options, statefile => 1); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => + { + "filter-name:s" => { name => 'filter_name' }, + }); + return $self; +} + +sub manage_selection { + my ($self, %options) = @_; + + my $request = [ + { mbean => "jboss.jca:name=*,service=ManagedConnectionPool", attributes => + [ { name => 'AvailableConnectionCount' }, { name => 'ConnectionCount' }, { name => 'ConnectionCreatedCount' }, { name => 'InUseConnectionCount' } ] }, + { mbean => "jboss.as:data-source=*,statistics=pool,subsystem=datasources", attributes => + [ { name => 'AvailableCount' }, { name => 'ActiveCount' }, { name => 'CreatedCount' }, { name => 'InUseCount' } ] }, + ]; + + my $result = $options{custom}->get_attributes(request => $request, nothing_quit => 1); + + $self->{datasource} = {}; + foreach my $key (keys %$result) { + $key =~ /(?:[:,])(?:name|data-source)=(.*?)(?:,|$)/; + my $ds_name = $1; + $ds_name =~ s/^"(.*)"$/$1/; + + if (defined($self->{option_results}->{filter_name}) && $self->{option_results}->{filter_name} ne '' && + $ds_name !~ /$self->{option_results}->{filter_name}/) { + $self->{output}->output_add(long_msg => "skipping '" . $ds_name . "': no matching filter.", debug => 1); + next; + } + + $self->{datasource}->{$ds_name} = { + display => $ds_name, + AvailableCount => defined($result->{$key}->{AvailableConnectionCount}) ? $result->{$key}->{AvailableConnectionCount} : $result->{$key}->{AvailableCount}, + ActiveCount => defined($result->{$key}->{ConnectionCount}) ? $result->{$key}->{ConnectionCount} : $result->{$key}->{ActiveCount}, + CreatedCount => defined($result->{$key}->{ConnectionCreatedCount}) ? $result->{$key}->{ConnectionCreatedCount} : $result->{$key}->{CreatedCount}, + InUseCount => defined($result->{$key}->{InUseConnectionCount}) ? $result->{$key}->{InUseConnectionCount} : $result->{$key}->{InUseCount}, + }; + } + + $self->{cache_name} = "jboss_" . $self->{mode} . '_' . md5_hex($options{custom}->get_connection_info()) . '_' . + (defined($self->{option_results}->{filter_counters}) ? md5_hex($self->{option_results}->{filter_counters}) : md5_hex('all')) . '_' . + (defined($self->{option_results}->{filter_name}) ? md5_hex($self->{option_results}->{filter_name}) : md5_hex('all')); +} + +1; + +__END__ + +=head1 MODE + +Check data sources usage. + +=over 8 + +=item B<--filter-counters> + +Only display some counters (regexp can be used). +Example: --filter-counters='num-active' + +=item B<--filter-name> + +Filter datasource name (can be a regexp). + +=item B<--warning-*> + +Threshold warning. +Can be: 'active-con', 'available-con', 'created-con', 'in-use-con'. + +=item B<--critical-*> + +Threshold critical. +Can be: 'active-con', 'available-con', 'created-con', 'in-use-con'. + +=back + +=cut diff --git a/centreon-plugins/apps/java/jboss/jmx/mode/listdatasources.pm b/centreon-plugins/apps/java/jboss/jmx/mode/listdatasources.pm new file mode 100644 index 000000000..74c828e0b --- /dev/null +++ b/centreon-plugins/apps/java/jboss/jmx/mode/listdatasources.pm @@ -0,0 +1,123 @@ +# +# Copyright 2017 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::java::jboss::jmx::mode::listdatasources; + +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 => + { + "filter-name:s" => { name => 'filter_name' }, + }); + $self->{ds} = {}; + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::init(%options); +} + +sub manage_selection { + my ($self, %options) = @_; + + my $request = [ + { mbean => "jboss.jca:name=*,service=ManagedConnectionPool", attributes => + [ { name => 'ConnectionCount' } ] }, + { mbean => "jboss.as:data-source=*,statistics=pool,subsystem=datasources", attributes => + [ { name => 'ActiveCount' } ] }, + ]; + my $result = $options{custom}->get_attributes(request => $request); + + foreach my $mbean (keys %{$result}) { + $mbean =~ /(?:[:,])(?:data-source|name)=(.*?)(?:,|$)/; + my $name = $1; + $name =~ s/^"(.*)"$/$1/; + + if (defined($self->{option_results}->{filter_name}) && $self->{option_results}->{filter_name} ne '' && + $name !~ /$self->{option_results}->{filter_name}/) { + $self->{output}->output_add(long_msg => "skipping '" . $name . "': no matching filter.", debug => 1); + next; + } + + $self->{ds}->{$name} = { + name => $name, + }; + } +} + +sub run { + my ($self, %options) = @_; + + $self->manage_selection(%options); + foreach my $instance (sort keys %{$self->{ds}}) { + $self->{output}->output_add(long_msg => '[name = ' . $self->{ds}->{$instance}->{name} . "]"); + } + + $self->{output}->output_add(severity => 'OK', + short_msg => 'List data sources:'); + $self->{output}->display(nolabel => 1, force_ignore_perfdata => 1, force_long_output => 1); + $self->{output}->exit(); +} + +sub disco_format { + my ($self, %options) = @_; + + $self->{output}->add_disco_format(elements => ['name']); +} + +sub disco_show { + my ($self, %options) = @_; + + $self->manage_selection(%options); + foreach my $instance (sort keys %{$self->{ds}}) { + $self->{output}->add_disco_entry( + %{$self->{ds}->{$instance}} + ); + } +} + +1; + +__END__ + +=head1 MODE + +List data sources. + +=over 8 + +=item B<--filter-name> + +Filter by name (can be a regexp). + +=back + +=cut + diff --git a/centreon-plugins/apps/java/jboss/jmx/plugin.pm b/centreon-plugins/apps/java/jboss/jmx/plugin.pm new file mode 100644 index 000000000..d37cc2ef3 --- /dev/null +++ b/centreon-plugins/apps/java/jboss/jmx/plugin.pm @@ -0,0 +1,54 @@ +# +# Copyright 2017 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::java::jboss::jmx::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; + + $self->{version} = '0.1'; + %{$self->{modes}} = ( + 'class-count' => 'centreon::common::jvm::mode::classcount', + 'datasource-usage' => 'apps::java::jboss::jmx::mode::datasourceusage', + 'list-datasources' => 'apps::java::jboss::jmx::mode::listdatasources', + 'memory' => 'centreon::common::jvm::mode::memory', + 'memory-detailed' => 'centreon::common::jvm::mode::memorydetailed', + 'threads' => 'centreon::common::jvm::mode::threads', + ); + + $self->{custom_modes}{jolokia} = 'centreon::common::protocols::jmx::custom::jolokia'; + return $self; +} + +1; + +__END__ + +=head1 PLUGIN DESCRIPTION + +Check Jboss in JMX. Need Jolokia agent. + +=cut diff --git a/centreon-plugins/apps/java/solr/jmx/mode/cacheusage.pm b/centreon-plugins/apps/java/solr/jmx/mode/cacheusage.pm index 0f8a1fe05..acbb09e12 100644 --- a/centreon-plugins/apps/java/solr/jmx/mode/cacheusage.pm +++ b/centreon-plugins/apps/java/solr/jmx/mode/cacheusage.pm @@ -131,7 +131,7 @@ sub manage_selection { $self->{output}->option_exit(); } - $self->{cache_name} = "solr_" . $self->{mode} . '_' . md5_hex($options{custom}->{url}) . '_' . + $self->{cache_name} = "solr_" . $self->{mode} . '_' . md5_hex($options{custom}->get_connection_info()) . '_' . (defined($self->{option_results}->{filter_counters}) ? md5_hex($self->{option_results}->{filter_counters}) : md5_hex('all')) . '_' . (defined($self->{option_results}->{filter_name}) ? md5_hex($self->{option_results}->{filter_name}) : md5_hex('all')); } diff --git a/centreon-plugins/apps/java/solr/jmx/mode/requesthandlerusage.pm b/centreon-plugins/apps/java/solr/jmx/mode/requesthandlerusage.pm index 30f0cd6be..9f6814e7f 100644 --- a/centreon-plugins/apps/java/solr/jmx/mode/requesthandlerusage.pm +++ b/centreon-plugins/apps/java/solr/jmx/mode/requesthandlerusage.pm @@ -128,7 +128,7 @@ sub manage_selection { $self->{output}->option_exit(); } - $self->{cache_name} = "solr_" . $self->{mode} . '_' . md5_hex($options{custom}->{url}) . '_' . + $self->{cache_name} = "solr_" . $self->{mode} . '_' . md5_hex($options{custom}->get_connection_info()) . '_' . (defined($self->{option_results}->{filter_counters}) ? md5_hex($self->{option_results}->{filter_counters}) : md5_hex('all')) . '_' . (defined($self->{option_results}->{filter_name}) ? md5_hex($self->{option_results}->{filter_name}) : md5_hex('all')); } diff --git a/centreon-plugins/apps/java/zookeeper/jmx/mode/stats.pm b/centreon-plugins/apps/java/zookeeper/jmx/mode/stats.pm index 812dd2ee2..6b98b318e 100644 --- a/centreon-plugins/apps/java/zookeeper/jmx/mode/stats.pm +++ b/centreon-plugins/apps/java/zookeeper/jmx/mode/stats.pm @@ -141,7 +141,7 @@ sub manage_selection { $self->{output}->option_exit(); } - $self->{cache_name} = "zookeeper_" . $self->{mode} . '_' . md5_hex($options{custom}->{url}) . '_' . + $self->{cache_name} = "zookeeper_" . $self->{mode} . '_' . md5_hex($options{custom}->get_connection_info()) . '_' . (defined($self->{option_results}->{filter_counters}) ? md5_hex($self->{option_results}->{filter_counters}) : md5_hex('all')); } diff --git a/centreon-plugins/apps/kingdee/eas/custom/api.pm b/centreon-plugins/apps/kingdee/eas/custom/api.pm new file mode 100644 index 000000000..08b2c238a --- /dev/null +++ b/centreon-plugins/apps/kingdee/eas/custom/api.pm @@ -0,0 +1,184 @@ +# +# Copyright 2017 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::kingdee::eas::custom::api; + +use strict; +use warnings; +use centreon::plugins::http; + +sub new { + my ($class, %options) = @_; + my $self = {}; + bless $self, $class; + + 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', }, + "proto:s@" => { name => 'proto' }, + "port:s@" => { name => 'port', }, + "username:s@" => { name => 'username', }, + "password:s@" => { name => '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; + +} + +sub set_options { + my ($self, %options) = @_; + + $self->{option_results} = $options{option_results}; +} + +sub set_defaults { + my ($self, %options) = @_; + + 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) = @_; + + $self->{hostname} = (defined($self->{option_results}->{hostname})) ? shift(@{$self->{option_results}->{hostname}}) : undef; + $self->{username} = (defined($self->{option_results}->{username})) ? shift(@{$self->{option_results}->{username}}) : ''; + $self->{password} = (defined($self->{option_results}->{password})) ? shift(@{$self->{option_results}->{password}}) : ''; + $self->{proto} = (defined($self->{option_results}->{proto})) ? shift(@{$self->{option_results}->{proto}}) : 'http'; + $self->{port} = (defined($self->{option_results}->{port})) ? shift(@{$self->{option_results}->{port}}) : 80; + $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->{hostname}) || + scalar(@{$self->{option_results}->{hostname}}) == 0) { + return 0; + } + return 1; +} + +sub build_options_for_httplib { + my ($self, %options) = @_; + + $self->{option_results}->{hostname} = $self->{hostname}; + $self->{option_results}->{timeout} = $self->{timeout}; + $self->{option_results}->{port} = $self->{port}; + $self->{option_results}->{proto} = $self->{proto}; + $self->{option_results}->{proxyurl} = $self->{proxyurl}; + $self->{option_results}->{credentials} = 1; + $self->{option_results}->{username} = $self->{username}; + $self->{option_results}->{password} = $self->{password}; +} + +sub settings { + my ($self, %options) = @_; + + $self->build_options_for_httplib(); + $self->{http}->set_options(%{$self->{option_results}}); +} + +sub request { + my ($self, %options) = @_; + + $self->settings(); + my $content = $self->{http}->request(url_path => $options{path}); + $content =~ s/^\s|\s+$//g; + + return $content; +} + +1; + +__END__ + +=head1 NAME + +KINGDEE REST API + +=head1 SYNOPSIS + +KINGDEE Rest API custom mode + +=head1 REST API OPTIONS + +=over 8 + +=item B<--hostname> + +Kingdee hostname. + +=item B<--proto> + +Specify https if needed. + +=item B<--username> + +Kingdee username. + +=item B<--password> + +Kingdee password. + +=item B<--proxyurl> + +Proxy URL if any. + +=item B<--timeout> + +Set HTTP timeout in seconds (Default: '10'). + +=back + +=head1 DESCRIPTION + +B. + +=cut diff --git a/centreon-plugins/apps/kingdee/eas/mode/activeusers.pm b/centreon-plugins/apps/kingdee/eas/mode/activeusers.pm new file mode 100644 index 000000000..6968190b7 --- /dev/null +++ b/centreon-plugins/apps/kingdee/eas/mode/activeusers.pm @@ -0,0 +1,111 @@ +# +# Copyright 2017 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. +# +# Author : CHEN JUN , aladdin.china@gmail.com + +package apps::kingdee::eas::mode::activeusers; + +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 => + { + "urlpath:s" => { name => 'url_path', default => "/easportal/tools/nagios/checkactiveusers.jsp" }, + "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) = @_; + + my $webcontent = $options{custom}->request(path => $self->{option_results}->{url_path}); + + if ($webcontent !~ /.*ActiveUsers_1m=.*/i) { + $self->{output}->output_add( + severity => 'UNKNOWN', + short_msg => "Cannot find eas actvie users info." + ); + $self->{output}->option_exit(); + } + + my @activeusers = split(" ",$webcontent); + + my $info; + foreach $info (@activeusers) { + if ($info =~ /(.*)=(.*)/) { + my ($counttype, $num) = ($1, $2); + $self->{output}->output_add(severity => "ok", short_msg => $info); + $self->{output}->perfdata_add(label => $counttype, unit => '',value => $num); + } + } + $self->{output}->display(); + $self->{output}->exit(); + +} + +1; + +__END__ + +=head1 MODE + +Check eas active users info. + +=over 8 + +=item B<--urlpath> + +Set path to get status page. (Default: '/easportal/tools/nagios/checkclassloading.jsp') + +=item B<--warning> + +Warning Threshold. + +=item B<--critical> + +Critical Threshold. + +=back + +=cut diff --git a/centreon-plugins/apps/kingdee/eas/mode/classloading.pm b/centreon-plugins/apps/kingdee/eas/mode/classloading.pm new file mode 100644 index 000000000..046964fdd --- /dev/null +++ b/centreon-plugins/apps/kingdee/eas/mode/classloading.pm @@ -0,0 +1,126 @@ +# +# Copyright 2017 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. +# +# Author : CHEN JUN , aladdin.china@gmail.com + +package apps::kingdee::eas::mode::classloading; + +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 => + { + "urlpath:s" => { name => 'url_path', default => "/easportal/tools/nagios/checkclassloading.jsp" }, + "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) = @_; + + my $webcontent = $options{custom}->request(path => $self->{option_results}->{url_path}); + + if ($webcontent !~ /(LoadedClassCount|UnloadedClassCount)/i) { + $self->{output}->output_add( + severity => 'UNKNOWN', + short_msg => "Cannot find classloading status." + ); + $self->{output}->option_exit(); + } + + my ($loadedclasscount, $unloadedclasscount) = (0, 0); + + if ($webcontent =~ /LoadedClassCount=\s*(\d+)/mi) { + $loadedclasscount = $1; + } + if ($webcontent =~ /UnloadedClassCount=\s*(\d+)/mi) { + $unloadedclasscount = $1; + } + + my $exit = $self->{perfdata}->threshold_check(value => $loadedclasscount, + threshold => [ { label => 'critical', 'exit_litteral' => 'critical' }, + { label => 'warning', 'exit_litteral' => 'warning' } ]); + + $self->{output}->output_add(severity => $exit, short_msg => sprintf("ClassLoaded: %d", $loadedclasscount)); + $self->{output}->output_add(severity => $exit, short_msg => sprintf("ClassUnloaded: %d", $unloadedclasscount)); + + $self->{output}->perfdata_add(label => "LoadedClassCount", unit => '', + value => sprintf("%d", $loadedclasscount), + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning'), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical'), + ); + $self->{output}->perfdata_add(label => "c[UnloadedClassCount]", unit => '', + value => sprintf("%d", $unloadedclasscount), + ); + + $self->{output}->display(); + $self->{output}->exit(); + +} + +1; + +__END__ + +=head1 MODE + +Check EAS application classLoading status. + +=over 8 + +=item B<--urlpath> + +Set path to get status page. (Default: '/easportal/tools/nagios/checkclassloading.jsp') + +=item B<--warning> + +Warning Threshold for class loaded + +=item B<--critical> + +Critical Threshold for class unloaded + +=back + +=cut diff --git a/centreon-plugins/apps/kingdee/eas/mode/datasource.pm b/centreon-plugins/apps/kingdee/eas/mode/datasource.pm new file mode 100644 index 000000000..4d8ba561a --- /dev/null +++ b/centreon-plugins/apps/kingdee/eas/mode/datasource.pm @@ -0,0 +1,174 @@ +# +# Copyright 2017 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. +# +# Author : CHEN JUN , aladdin.china@gmail.com + +package apps::kingdee::eas::mode::datasource; + +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 => + { + "urlpath:s" => { name => 'url_path', default => "/easportal/tools/nagios/checkdatasources.jsp" }, + "datasource:s" => { name => 'datasource' }, + "warning:s" => { name => 'warning' }, + "critical:s" => { name => 'critical' }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::init(%options); + + if (!defined($self->{option_results}->{datasource}) || $self->{option_results}->{datasource} eq "") { + $self->{output}->add_option_msg(short_msg => "Missing datasource name."); + $self->{output}->option_exit(); + } + $self->{option_results}->{url_path} .= "?ds=" . $self->{option_results}->{datasource}; + + 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 $webcontent = $options{custom}->request(path => $self->{option_results}->{url_path}); + + if ($webcontent !~ /^Name=/i) { + $self->{output}->output_add( + severity => 'UNKNOWN', + short_msg => "Cannot find datasource \'" . $self->{option_results}->{datasource} . "\' status." + ); + } + + my $init_pool_size = -1; + my $max_pool_size = -1; + my $idle_timeout = -1; + my $cur_conn_count = -1; + my $cur_avail_conn_count = -1; + my $max_conn_count = -1; + my $create_count = -1; + my $close_count = -1; + + $init_pool_size = $1 if $webcontent =~ /InitialPoolSize=(\d+)\s/i; + $max_pool_size = $1 if $webcontent =~ /MaxPoolSize=(\d+)\s/i; + $idle_timeout = $1 if $webcontent =~ /IdleTimeout=(\d+)\s/i; + $cur_conn_count = $1 if $webcontent =~ /CurrentConnectionCount=(\d+)\s/i; + $cur_avail_conn_count = $1 if $webcontent =~ /CurrentAvailableConnectionCount=(\d+)\s/i; + $max_conn_count = $1 if $webcontent =~ /MaxConnectionCount=(\d+)\s/i; + $create_count = $1 if $webcontent =~ /CreateCount=(\d+)\s/i; + $close_count = $1 if $webcontent =~ /CloseCount=(\d+)\s/i; + + my $active_conn_count = $cur_conn_count - $cur_avail_conn_count; + + $self->{output}->output_add(severity => "ok", short_msg => sprintf("InitialPoolSize: %d", $init_pool_size)); + $self->{output}->output_add(severity => "ok", short_msg => sprintf("MaxPoolSize: %d", $max_pool_size)); + $self->{output}->output_add(severity => "ok", short_msg => sprintf("IdleTimeout: %d", $idle_timeout)); + + my $exit = $self->{perfdata}->threshold_check(value => $active_conn_count, threshold => [ { label => 'critical', exit_litteral => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]); + $self->{output}->output_add(severity => $exit, short_msg => sprintf("ActiveConnectionCount: %d", $active_conn_count)); + + $self->{output}->output_add(severity => "ok", short_msg => sprintf("CurrentConnectionCount: %d", $cur_conn_count)); + #$self->{output}->output_add(severity => "ok", short_msg => sprintf("CurrentAvailableConnectionCount: %d", $cur_avail_conn_count)); + $self->{output}->output_add(severity => "ok", short_msg => sprintf("MaxConnectionCount: %d", $max_conn_count)); + $self->{output}->output_add(severity => "ok", short_msg => sprintf("CreateCount: %d", $create_count)); + $self->{output}->output_add(severity => "ok", short_msg => sprintf("CloseCount: %d", $close_count)); + + $self->{output}->perfdata_add(label => "InitPoolSize", unit => '', + value => sprintf("%d", $init_pool_size), + ); + $self->{output}->perfdata_add(label => "MaxPoolSize", unit => '', + value => sprintf("%d", $max_pool_size), + ); + $self->{output}->perfdata_add(label => "IdleTimeout", unit => '', + value => sprintf("%d", $idle_timeout), + ); + + $self->{output}->perfdata_add(label => "ActiveConnectionCount", unit => '', + value => sprintf("%d", $active_conn_count), + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning'), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical'), + ); + $self->{output}->perfdata_add(label => "CurrentConnectionCount", unit => '', + value => sprintf("%d", $cur_conn_count), + ); + #$self->{output}->perfdata_add(label => "CurrentAvailableConnectionCount", unit => '', + # value => sprintf("%d", $cur_avail_conn_count), + # ); + $self->{output}->perfdata_add(label => "MaxConnectionCount", unit => '', + value => sprintf("%d", $max_conn_count), + ); + $self->{output}->perfdata_add(label => "c[CreateCount]", unit => '', + value => sprintf("%d", $create_count), + ); + $self->{output}->perfdata_add(label => "c[CloseCount]", unit => '', + value => sprintf("%d", $close_count), + ); + + $self->{output}->display(); + $self->{output}->exit(); +} + +1; + +__END__ + +=head1 MODE + +Check EAS application datasource status. + +=over 8 + +=item B<--urlpath> + +Specify path to get status page. (Default: '/easportal/tools/nagios/checkdatasources.jsp') + +=item B<--datasource> + +Specify the datasource name. + +=item B<--warning> + +Warning Threshold for active connection count. + +=item B<--critical> + +Critical Threshold for active connection count. + +=back + +=cut diff --git a/centreon-plugins/apps/kingdee/eas/mode/easlicense.pm b/centreon-plugins/apps/kingdee/eas/mode/easlicense.pm new file mode 100644 index 000000000..0dd1d0153 --- /dev/null +++ b/centreon-plugins/apps/kingdee/eas/mode/easlicense.pm @@ -0,0 +1,108 @@ +# +# Copyright 2017 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. +# +# Author : CHEN JUN , aladdin.china@gmail.com + +package apps::kingdee::eas::mode::easlicense; + +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 => + { + "urlpath:s" => { name => 'url_path', default => "/easportal/tools/nagios/checkeaslicense.jsp" }, + "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) = @_; + + my $webcontent = $options{custom}->request(path => $self->{option_results}->{url_path}); + if ($webcontent !~ /.*BOS=.*/i) { + $self->{output}->output_add(severity => 'UNKNOWN', + short_msg => "Cannot find eas license usage info."); + $self->{output}->option_exit(); + } + + my @licenseinfo = split(" ",$webcontent); + + my $info; + foreach $info (@licenseinfo) { + if ($info =~ /(.*)=(.*)/) { + my ($modname, $num) = ($1, $2); + $self->{output}->output_add(severity => "ok", short_msg => $info); + $self->{output}->perfdata_add(label => $modname, unit => '',value => $num); + } + } + $self->{output}->display(); + $self->{output}->exit(); + +} + +1; + +__END__ + +=head1 MODE + +Check eas license usage info. + +=over 8 + +=item B<--urlpath> + +Set path to get status page. (Default: '/easportal/tools/nagios/checkclassloading.jsp') + +=item B<--warning> + +Warning Threshold. + +=item B<--critical> + +Critical Threshold. + +=back + +=cut diff --git a/centreon-plugins/apps/kingdee/eas/mode/httphandler.pm b/centreon-plugins/apps/kingdee/eas/mode/httphandler.pm new file mode 100644 index 000000000..7983689cb --- /dev/null +++ b/centreon-plugins/apps/kingdee/eas/mode/httphandler.pm @@ -0,0 +1,186 @@ +# +# Copyright 2017 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. +# +# Author : CHEN JUN , aladdin.china@gmail.com + +package apps::kingdee::eas::mode::httphandler; + +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 => { + "urlpath:s" => { name => 'url_path', default => "/easportal/tools/nagios/checkhttphandler.jsp" }, + "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) = @_; + + my $webcontent = $options{custom}->request(path => $self->{option_results}->{url_path}); + + if ($webcontent !~ /MaxThreads=\d+/i) { + $self->{output}->output_add( + severity => 'UNKNOWN', + short_msg => "Cannot find httphandler status in response: '" . $webcontent . "'" + ); + $self->{output}->option_exit(); + } + + my ($maxthreads, $minsparethreads, $maxsparethreads, $maxqueuesize, $idletimeout, $processedcount) = (0, 0, 0, 0, 0, 0); + my ($currentthreadcount, $availablethreadcount, $busythreadcount, $maxavailablethreadcount, $maxbusythreadcount) = (0, 0, 0, 0, 0); + my ($maxprocessedtime, $createcount, $destroycount) = (0, 0, 0); + + $maxthreads = $1 if $webcontent =~ /MaxThreads=(\d+)/mi ; + $minsparethreads = $1 if $webcontent =~ /MinSpareThreads=(\d+)/mi ; + $maxsparethreads = $1 if $webcontent =~ /MaxSpareThreads=(\d+)/mi ; + $maxqueuesize = $1 if $webcontent =~ /MaxQueueSize=(\d+)/mi ; + $idletimeout = $1 if $webcontent =~ /IdleTimeout=(\d+)/mi ; + $processedcount = $1 if $webcontent =~ /ProcessedCount=(\d+)/mi ; + $currentthreadcount = $1 if $webcontent =~ /CurrentThreadCount=(\d+)/mi ; + $availablethreadcount = $1 if $webcontent =~ /AvailableThreadCount=(\d+)/mi ; + $busythreadcount = $1 if $webcontent =~ /BusyThreadCount=(\d+)/mi ; + $maxavailablethreadcount = $1 if $webcontent =~ /MaxAvailableThreadCount=(\d+)/mi ; + $maxbusythreadcount = $1 if $webcontent =~ /MaxBusyThreadCount=(\d+)/mi ; + $maxprocessedtime = $1 if $webcontent =~ /MaxProcessedTime=(\d+)/mi ; + $createcount = $1 if $webcontent =~ /CreateCount=(\d+)/mi ; + $destroycount = $1 if $webcontent =~ /DestroyCount=(\d+)/mi ; + + $self->{output}->output_add(severity => "ok", short_msg => sprintf("MaxThreads: %d", $maxthreads)); + $self->{output}->output_add(severity => "ok", short_msg => sprintf("MinSpareThreads: %d", $minsparethreads)); + $self->{output}->output_add(severity => "ok", short_msg => sprintf("MaxSpareThreads: %d", $maxsparethreads)); + $self->{output}->output_add(severity => "ok", short_msg => sprintf("MaxQueueSize: %d", $maxqueuesize)); + $self->{output}->output_add(severity => "ok", short_msg => sprintf("IdleTimeout: %ds", $idletimeout)); + $self->{output}->output_add(severity => "ok", short_msg => sprintf("ProcessedCount: %d", $processedcount)); + $self->{output}->output_add(severity => "ok", short_msg => sprintf("CurrentThreadCount: %d", $currentthreadcount)); + $self->{output}->output_add(severity => "ok", short_msg => sprintf("AvailableThreadCount: %d", $availablethreadcount)); + + my $exit = $self->{perfdata}->threshold_check(value => $busythreadcount, threshold => [ { label => 'critical', exit_litteral => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]); + $self->{output}->output_add(severity => $exit, short_msg => sprintf("BusyThreadCount: %d", $busythreadcount)); + + $self->{output}->output_add(severity => "ok", short_msg => sprintf("MaxAvailableThreadCount: %d", $maxavailablethreadcount)); + $self->{output}->output_add(severity => "ok", short_msg => sprintf("MaxBusyThreadCount: %d", $maxbusythreadcount)); + $self->{output}->output_add(severity => "ok", short_msg => sprintf("MaxProcessedTime: %dms", $maxprocessedtime)); + $self->{output}->output_add(severity => "ok", short_msg => sprintf("CreateCount: %d", $createcount)); + $self->{output}->output_add(severity => "ok", short_msg => sprintf("DestroyCount: %d", $destroycount)); + + $self->{output}->perfdata_add(label => "MaxThreads", unit => '', + value => sprintf("%d", $maxthreads), + ); + $self->{output}->perfdata_add(label => "MinSpareThreads", unit => '', + value => sprintf("%d", $minsparethreads), + ); + $self->{output}->perfdata_add(label => "MaxSpareThreads", unit => '', + value => sprintf("%d", $maxsparethreads), + ); + $self->{output}->perfdata_add(label => "MaxQueueSize", unit => '', + value => sprintf("%d", $maxqueuesize), + ); + $self->{output}->perfdata_add(label => "IdleTimeout", unit => 's', + value => sprintf("%d", $idletimeout), + ); + $self->{output}->perfdata_add(label => "c[ProcessedCount]", unit => '', + value => sprintf("%d", $processedcount), + ); + $self->{output}->perfdata_add(label => "CurrentThreadCount", unit => '', + value => sprintf("%d", $currentthreadcount), + ); + $self->{output}->perfdata_add(label => "AvailableThreadCount", unit => '', + value => sprintf("%d", $availablethreadcount), + ); + + $self->{output}->perfdata_add(label => "BusyThreadCount", unit => '', + value => sprintf("%d", $busythreadcount), + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning'), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical'), + ); + + $self->{output}->perfdata_add(label => "MaxAvailableThreadCount", unit => '', + value => sprintf("%d", $maxavailablethreadcount), + ); + $self->{output}->perfdata_add(label => "MaxBusyThreadCount", unit => '', + value => sprintf("%d", $maxbusythreadcount), + ); + $self->{output}->perfdata_add(label => "MaxProcessedTime", unit => 'ms', + value => sprintf("%d", $maxprocessedtime), + ); + $self->{output}->perfdata_add(label => "c[CreateCount]", unit => '', + value => sprintf("%d", $createcount), + ); + $self->{output}->perfdata_add(label => "c[DestroyCount]", unit => '', + value => sprintf("%d", $destroycount), + ); + + $self->{output}->display(); + $self->{output}->exit(); +} + +1; + +__END__ + +=head1 MODE + +Check EAS instance httphandler(Apusic) threads pool status. + +=over 8 + +=item B<--urlpath> + +Set path to get status page. (Default: '/easportal/tools/nagios/checkhttphandler.jsp') + +=item B<--warning> + +Warning Threshold for busy thread count. + +=item B<--critical> + +Critical Threshold for busy thread count. + +=back + +=cut diff --git a/centreon-plugins/apps/kingdee/eas/mode/ibmjvmgc.pm b/centreon-plugins/apps/kingdee/eas/mode/ibmjvmgc.pm new file mode 100644 index 000000000..c62b8d1db --- /dev/null +++ b/centreon-plugins/apps/kingdee/eas/mode/ibmjvmgc.pm @@ -0,0 +1,115 @@ +# +# Copyright 2017 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. +# +# Author : CHEN JUN , aladdin.china@gmail.com + +package apps::kingdee::eas::mode::ibmjvmgc; + +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 => + { + "urlpath:s" => { name => 'url_path', default => "/easportal/tools/nagios/checkgc_j9gen.jsp" }, + "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) = @_; + + my $webcontent = $options{custom}->request(path => $self->{option_results}->{url_path}); + + if ($webcontent !~ /CollectionCount=\d+/mi) { + $self->{output}->output_add( + severity => 'UNKNOWN', + short_msg => "Cannot find ibm jdk j9 gc status." + ); + $self->{output}->option_exit(); + } + + my ($collectioncount, $collectiontime) = (0, 0); + + ($collectioncount, $collectiontime) = ($1, $2) if ($webcontent =~ /CollectionCount=(\d+)\sCollectionTime=(\d+)/mi); + + $self->{output}->output_add(severity => "ok", short_msg => sprintf("CollectionCount: %d", $collectioncount)); + $self->{output}->output_add(severity => "ok", short_msg => sprintf("CollectionTime: %dms", $collectiontime)); + + $self->{output}->perfdata_add(label => "c[CollectionCount]", unit => '', + value => sprintf("%d", $collectioncount), + ); + $self->{output}->perfdata_add(label => "c[CollectionTime]", unit => 'ms', + value => sprintf("%d", $collectiontime), + ); + + $self->{output}->display(); + $self->{output}->exit(); + +} + +1; + +__END__ + +=head1 MODE + +Check EAS application jvm gc status. + +=over 8 + +=item B<--urlpath> + +Set path to get status page. (Default: '/easportal/tools/nagios/checkgc_j9.jsp') + +=item B<--warning> + +Warning Threshold for class loaded + +=item B<--critical> + +Critical Threshold for class unloaded + +=back + +=cut diff --git a/centreon-plugins/apps/kingdee/eas/mode/javaruntime.pm b/centreon-plugins/apps/kingdee/eas/mode/javaruntime.pm new file mode 100644 index 000000000..932e11386 --- /dev/null +++ b/centreon-plugins/apps/kingdee/eas/mode/javaruntime.pm @@ -0,0 +1,129 @@ +# +# Copyright 2017 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. +# +# Author : CHEN JUN , aladdin.china@gmail.com + +package apps::kingdee::eas::mode::javaruntime; + +use base qw(centreon::plugins::mode); + +use strict; +use warnings; +use POSIX; +use centreon::plugins::misc; + +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 => + { + "urlpath:s" => { name => 'url_path', default => "/easportal/tools/nagios/checkjavaruntime.jsp" }, + "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) = @_; + + my $webcontent = $options{custom}->request(path => $self->{option_results}->{url_path}); + + if ($webcontent !~ /VmName=/mi) { + $self->{output}->output_add( + severity => 'UNKNOWN', + short_msg => "Cannot find java runtime status." + ); + $self->{output}->option_exit(); + } + + my $vmname = $1 if $webcontent =~ /VmName=\'(.*?)\'/i; + my $specversion = $1 if $webcontent =~ /SpecVersion=([\d\.]+)/i; + my $vmversion = $1 if $webcontent =~ /VmVersion=(.*?)\s/i; + my $vender = $1 if $webcontent =~ /VmVendor=\'(.*?)\'/i; + my $uptime = $1 if $webcontent =~ /Uptime=(\d*)/i; #unit:ms + my $startime = $1 if $webcontent =~ /StartTime=(\d*)/i; + + my $exit = $self->{perfdata}->threshold_check(value => $uptime / 1000, threshold => [ + { label => 'critical', 'exit_litteral' => 'critical' }, + { label => 'warning', exit_litteral => 'warning' } ]); + $self->{output}->output_add(severity => $exit, short_msg => sprintf("Uptime: %s", + centreon::plugins::misc::change_seconds(value => floor($uptime / 1000), start => 'd')) + ); + $self->{output}->output_add(severity => $exit, short_msg => sprintf("%s %s (build %s), %s", + $vmname ,$specversion, $vmversion,$vender) + ); + + $self->{output}->perfdata_add(label => "Uptime", unit => 's', + value => sprintf("%d", floor($uptime / 1000)), + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning'), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical'), + ); + $self->{output}->perfdata_add(label => "SpecVersion", unit => '', + value => sprintf("%s", $specversion), + ); + + $self->{output}->display(); + $self->{output}->exit(); + +} + +1; + +__END__ + +=head1 MODE + +Check EAS application java runtime status. + +=over 8 + +=item B<--urlpath> + +Set path to get status page. (Default: '/easportal/tools/nagios/checkjavaruntime.jsp') + +=item B<--warning> + +Warning Threshold for uptime (sec) + +=item B<--critical> + +Critical Threshold for uptime (sec) + +=back + +=cut diff --git a/centreon-plugins/apps/kingdee/eas/mode/memory.pm b/centreon-plugins/apps/kingdee/eas/mode/memory.pm new file mode 100644 index 000000000..e08f12123 --- /dev/null +++ b/centreon-plugins/apps/kingdee/eas/mode/memory.pm @@ -0,0 +1,322 @@ +# +# Copyright 2017 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. +# +# Author : CHEN JUN , aladdin.china@gmail.com + +package apps::kingdee::eas::mode::memory; + +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 => { + "urlpath:s" => { name => 'url_path', default => "/easportal/tools/nagios/checkmemory.jsp" }, + "warning-heap:s" => { name => 'warning-heap' , default => ",,,"}, + "warning-nonheap:s" => { name => 'warning-nonheap' , default => ",,,"}, + "critical-heap:s" => { name => 'critical-heap' , default => ",,,"}, + "critical-nonheap:s" => { name => 'critical-nonheap' , default => ",,,"}, + } + ); + + return $self; +} + +sub check_options { + my ( $self, %options ) = @_; + $self->SUPER::init(%options); + + ($self->{warn_init_heap}, $self->{warn_max_heap}, $self->{warn_used_heap}, $self->{warn_committed_heap}) + = split /,/, $self->{option_results}->{"warning-heap"}; + ($self->{warn_init_nonheap}, $self->{warn_max_nonheap}, $self->{warn_used_nonheap}, $self->{warn_committed_nonheap}) + = split /,/, $self->{option_results}->{"warning-nonheap"}; + ($self->{crit_init_heap}, $self->{crit_max_heap}, $self->{crit_used_heap}, $self->{crit_committed_heap}) + = split /,/, $self->{option_results}->{"critical-heap"}; + ($self->{crit_init_nonheap}, $self->{crit_max_nonheap}, $self->{crit_used_nonheap}, $self->{crit_committed_nonheap}) + = split /,/, $self->{option_results}->{"critical-nonheap"}; + + # warning-heap + if (($self->{perfdata}->threshold_validate(label => 'warn_init_heap', value => $self->{warn_init_heap})) == 0) { + $self->{output}->add_option_msg(short_msg => "Wrong warning-heap init threshold '" . $self->{warn_init_heap} . "'."); + $self->{output}->option_exit(); + } + if (($self->{perfdata}->threshold_validate(label => 'warn_max_heap', value => $self->{warn_max_heap})) == 0) { + $self->{output}->add_option_msg(short_msg => "Wrong warning-heap max threshold '" . $self->{warn_max_heap} . "'."); + $self->{output}->option_exit(); + } + if (($self->{perfdata}->threshold_validate(label => 'warn_used_heap', value => $self->{warn_used_heap})) == 0) { + $self->{output}->add_option_msg(short_msg => "Wrong warning-heap used threshold '" . $self->{warn_used_heap} . "'."); + $self->{output}->option_exit(); + } + if (($self->{perfdata}->threshold_validate(label => 'warn_committed_heap', value => $self->{warn_committed_heap})) == 0) { + $self->{output}->add_option_msg(short_msg => "Wrong warning-heap committed threshold '" . $self->{warn_committed_heap} . "'."); + $self->{output}->option_exit(); + } + + # waring-nonheap + if (($self->{perfdata}->threshold_validate(label => 'warn_init_nonheap', value => $self->{warn_init_nonheap})) == 0) { + $self->{output}->add_option_msg(short_msg => "Wrong warning-nonheap init threshold '" . $self->{warn_init_nonheap} . "'."); + $self->{output}->option_exit(); + } + if (($self->{perfdata}->threshold_validate(label => 'warn_max_nonheap', value => $self->{warn_max_nonheap})) == 0) { + $self->{output}->add_option_msg(short_msg => "Wrong warning-nonheap max threshold '" . $self->{warn_max_nonheap} . "'."); + $self->{output}->option_exit(); + } + if (($self->{perfdata}->threshold_validate(label => 'warn_used_nonheap', value => $self->{warn_used_nonheap})) == 0) { + $self->{output}->add_option_msg(short_msg => "Wrong warning-nonheap used threshold '" . $self->{warn_used_nonheap} . "'."); + $self->{output}->option_exit(); + } + if (($self->{perfdata}->threshold_validate(label => 'warn_committed_nonheap', value => $self->{warn_committed_nonheap})) == 0) { + $self->{output}->add_option_msg(short_msg => "Wrong warning-nonheap committed threshold '" . $self->{warn_committed_nonheap} . "'."); + $self->{output}->option_exit(); + } + + # critical-heap + if (($self->{perfdata}->threshold_validate(label => 'crit_init_heap', value => $self->{crit_init_heap})) == 0) { + $self->{output}->add_option_msg(short_msg => "Wrong critical-heap init threshold '" . $self->{crit_init_heap} . "'."); + $self->{output}->option_exit(); + } + if (($self->{perfdata}->threshold_validate(label => 'crit_max_heap', value => $self->{crit_max_heap})) == 0) { + $self->{output}->add_option_msg(short_msg => "Wrong critical-heap max threshold '" . $self->{crit_max_heap} . "'."); + $self->{output}->option_exit(); + } + if (($self->{perfdata}->threshold_validate(label => 'crit_used_heap', value => $self->{crit_used_heap})) == 0) { + $self->{output}->add_option_msg(short_msg => "Wrong critical-heap used threshold '" . $self->{crit_used_heap} . "'."); + $self->{output}->option_exit(); + } + if (($self->{perfdata}->threshold_validate(label => 'crit_committed_heap', value => $self->{crit_committed_heap})) == 0) { + $self->{output}->add_option_msg(short_msg => "Wrong critical-heap committed threshold '" . $self->{crit_committed_heap} . "'."); + $self->{output}->option_exit(); + } + + # critical-nonheap + if (($self->{perfdata}->threshold_validate(label => 'crit_init_nonheap', value => $self->{crit_init_nonheap})) == 0) { + $self->{output}->add_option_msg(short_msg => "Wrong critical-nonheap init threshold '" . $self->{crit_init_nonheap} . "'."); + $self->{output}->option_exit(); + } + if (($self->{perfdata}->threshold_validate(label => 'crit_max_nonheap', value => $self->{crit_max_nonheap})) == 0) { + $self->{output}->add_option_msg(short_msg => "Wrong critical-nonheap max threshold '" . $self->{crit_max_nonheap} . "'."); + $self->{output}->option_exit(); + } + if (($self->{perfdata}->threshold_validate(label => 'crit_used_nonheap', value => $self->{crit_used_nonheap})) == 0) { + $self->{output}->add_option_msg(short_msg => "Wrong critical-nonheap used threshold '" . $self->{crit_used_nonheap} . "'."); + $self->{output}->option_exit(); + } + if (($self->{perfdata}->threshold_validate(label => 'crit_committed_nonheap', value => $self->{crit_committed_nonheap})) == 0) { + $self->{output}->add_option_msg(short_msg => "Wrong critical-nonheap committed threshold '" . $self->{crit_committed_nonheap} . "'."); + $self->{output}->option_exit(); + } +} + +sub run { + my ( $self, %options ) = @_; + + my $webcontent = $options{custom}->request(path => $self->{option_results}->{url_path}); + + if ($webcontent !~ /(^Type=HeapMemoryUsage|^Type=NonHeapMemoryUsage)/mi) { + $self->{output}->output_add( + severity => 'UNKNOWN', + short_msg => "Cannot find heap or nonheap memory usage status." + ); + $self->{output}->option_exit(); + } + + my ( $init_heap, $max_heap, $used_heap, $committed_heap ) = ( 0, 0, 0, 0 ); + my ( $init_nonheap, $max_nonheap, $used_nonheap, $committed_nonheap ) = ( 0, 0, 0, 0 ); + if ( $webcontent =~ /^Type=HeapMemoryUsage\sinit=(\d+)\smax=(\d+)\sused=(\d+)\scommitted=(\d+)/mi ){ + ( $init_heap, $max_heap, $used_heap, $committed_heap ) = ( $1, $2, $3, $4 ); + $self->{output}->output_add( + severity => 'ok', + short_msg => sprintf( + "Heap Memory: init %d , max %d ,used %d ,commited %d", + $init_heap, $max_heap, $used_heap, $committed_heap + ) + ); + } + if ( $webcontent =~ /^Type=NonHeapMemoryUsage\sinit=(\d+)\smax=(-{0,1}\d+)\sused=(\d+)\scommitted=(\d+)/mi ){ + ( $init_nonheap, $max_nonheap, $used_nonheap, $committed_nonheap ) = ( $1, $2, $3, $4 ); + $self->{output}->output_add( + severity => 'ok', + short_msg => sprintf( + "NonHeap Memory: init %d , max %d ,used %d ,commited %d", + $init_nonheap, $max_nonheap, + $used_nonheap, $committed_nonheap + ) + ); + } + + my $exit = $self->{perfdata}->threshold_check(value => $init_heap, + threshold => [ { label => 'crit_init_heap', 'exit_litteral' => 'critical' }, + { label => 'warn_init_heap', 'exit_litteral' => 'warning' } ]); + if ($exit ne "ok"){ + $self->{output}->output_add( + severity => $exit, + short_msg => sprintf("Init Heap: %d", $init_heap) + ); + } + $exit = $self->{perfdata}->threshold_check(value => $max_heap, + threshold => [ { label => 'crit_max_heap', 'exit_litteral' => 'critical' }, + { label => 'warn_max_heap', 'exit_litteral' => 'warning' } ]); + if ($exit ne "ok"){ + $self->{output}->output_add( + severity => $exit, + short_msg => sprintf("Max Heap: %d", $max_heap) + ); + } + $exit = $self->{perfdata}->threshold_check(value => $used_heap, + threshold => [ { label => 'crit_used_heap', 'exit_litteral' => 'critical' }, + { label => 'warn_used_heap', 'exit_litteral' => 'warning' } ]); + if ($exit ne "ok"){ + $self->{output}->output_add( + severity => $exit, + short_msg => sprintf("Used Heap: %d", $used_heap) + ); + } + $exit = $self->{perfdata}->threshold_check(value => $committed_heap, + threshold => [ { label => 'crit_committed_heap', 'exit_litteral' => 'critical' }, + { label => 'warn_committed_heap', 'exit_litteral' => 'warning' } ]); + if ($exit ne "ok"){ + $self->{output}->output_add( + severity => $exit, + short_msg => sprintf("Committed Heap: %d", $committed_heap) + ); + } + + $exit = $self->{perfdata}->threshold_check(value => $init_nonheap, + threshold => [ { label => 'crit_init_nonheap', 'exit_litteral' => 'critical' }, + { label => 'warn_init_nonheap', 'exit_litteral' => 'warning' } ]); + if ($exit ne "ok"){ + $self->{output}->output_add( + severity => $exit, + short_msg => sprintf("Init NonHeap: %d", $init_nonheap) + ); + } + $exit = $self->{perfdata}->threshold_check(value => $max_nonheap, + threshold => [ { label => 'crit_max_nonheap', 'exit_litteral' => 'critical' }, + { label => 'warn_max_nonheap', 'exit_litteral' => 'warning' } ]); + if ($exit ne "ok"){ + $self->{output}->output_add( + severity => $exit, + short_msg => sprintf("Max NonHeap: %d", $max_nonheap) + ); + } + $exit = $self->{perfdata}->threshold_check(value => $used_nonheap, + threshold => [ { label => 'crit_used_nonheap', 'exit_litteral' => 'critical' }, + { label => 'warn_used_nonheap', 'exit_litteral' => 'warning' } ]); + if ($exit ne "ok"){ + $self->{output}->output_add( + severity => $exit, + short_msg => sprintf("Used NonHeap: %d", $used_nonheap) + ); + } + $exit = $self->{perfdata}->threshold_check(value => $committed_nonheap, + threshold => [ { label => 'crit_committed_nonheap', 'exit_litteral' => 'critical' }, + { label => 'warn_committed_nonheap', 'exit_litteral' => 'warning' } ]); + if ($exit ne "ok"){ + $self->{output}->output_add( + severity => $exit, + short_msg => sprintf("Committed NonHeap: %d", $committed_nonheap) + ); + } + + $self->{output}->perfdata_add( + label => "init_heap", + value => $init_heap, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warn_init_heap'), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'crit_init_heap'), + ); + $self->{output}->perfdata_add( + label => "max_heap", + value => $max_heap, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warn_max_heap'), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'crit_max_heap'), + ); + $self->{output}->perfdata_add( + label => "used_heap", + value => $used_heap, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warn_used_heap'), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'crit_used_heap'), + ); + $self->{output}->perfdata_add( + label => "committed_heap", + value => $committed_heap, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warn_committed_heap'), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'crit_committed_heap'), + ); + $self->{output}->perfdata_add( + label => "init_nonheap", + value => $init_nonheap, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warn_init_nonheap'), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'crit_init_nonheap'), + ); + $self->{output}->perfdata_add( + label => "max_nonheap", + value => $max_nonheap, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warn_max_nonheap'), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'crit_max_nonheap'), + ); + $self->{output}->perfdata_add( + label => "used_nonheap", + value => $used_nonheap, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warn_used_nonheap'), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'crit_used_nonheap'), + ); + $self->{output}->perfdata_add( + label => "committed_nonheap", + value => $committed_nonheap, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warn_committed_nonheap'), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'crit_committed_nonheap'), + ); + + $self->{output}->display(); + $self->{output}->exit(); +} + +1; + +__END__ + +=head1 MODE + +Check EAS instance heap & nonheap memory usage. + +=over 8 + +=item B<--urlpath> + +Set path to get status page. (Default: '/easportal/tools/nagios/checkmemory.jsp') + +=item B<--warning-*> + +Warning Threshold (init,max,used,committed), '*' Can be: 'heap', 'nonheap'. + +=item B<--critical-*> + +Critical Threshold (init,max,used,committed), '*' Can be: 'heap', 'nonheap'. + +=back + +=cut diff --git a/centreon-plugins/apps/kingdee/eas/mode/muxhandler.pm b/centreon-plugins/apps/kingdee/eas/mode/muxhandler.pm new file mode 100644 index 000000000..680820a9e --- /dev/null +++ b/centreon-plugins/apps/kingdee/eas/mode/muxhandler.pm @@ -0,0 +1,185 @@ +# +# Copyright 2017 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. +# +# Author : CHEN JUN , aladdin.china@gmail.com + +package apps::kingdee::eas::mode::muxhandler; + +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 => { + "urlpath:s" => { name => 'url_path', default => "/easportal/tools/nagios/checkmuxhandler.jsp" }, + "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 ) = @_; + + my $webcontent = $options{custom}->request(path => $self->{option_results}->{url_path}); + + if ($webcontent !~ /MaxThreads=\d+/i) { + $self->{output}->output_add( + severity => 'UNKNOWN', + short_msg => "Cannot find httphandler status in response: '" . $webcontent . "'" + ); + $self->{output}->option_exit(); + } + + my ($maxthreads, $minsparethreads, $maxsparethreads, $maxqueuesize, $idletimeout, $processedcount) = (0, 0, 0, 0, 0, 0); + my ($currentthreadcount, $availablethreadcount, $busythreadcount, $maxavailablethreadcount, $maxbusythreadcount) = (0, 0, 0, 0, 0); + my ($maxprocessedtime, $createcount, $destroycount) = (0, 0, 0); + + $maxthreads = $1 if $webcontent =~ /MaxThreads=(\d+)/mi ; + $minsparethreads = $1 if $webcontent =~ /MinSpareThreads=(\d+)/mi ; + $maxsparethreads = $1 if $webcontent =~ /MaxSpareThreads=(\d+)/mi ; + $maxqueuesize = $1 if $webcontent =~ /MaxQueueSize=(\d+)/mi ; + $idletimeout = $1 if $webcontent =~ /IdleTimeout=(\d+)/mi ; + $processedcount = $1 if $webcontent =~ /ProcessedCount=(\d+)/mi ; + $currentthreadcount = $1 if $webcontent =~ /CurrentThreadCount=(\d+)/mi ; + $availablethreadcount = $1 if $webcontent =~ /AvailableThreadCount=(\d+)/mi ; + $busythreadcount = $1 if $webcontent =~ /BusyThreadCount=(\d+)/mi ; + $maxavailablethreadcount = $1 if $webcontent =~ /MaxAvailableThreadCount=(\d+)/mi ; + $maxbusythreadcount = $1 if $webcontent =~ /MaxBusyThreadCount=(\d+)/mi ; + $maxprocessedtime = $1 if $webcontent =~ /MaxProcessedTime=(\d+)/mi ; + $createcount = $1 if $webcontent =~ /CreateCount=(\d+)/mi ; + $destroycount = $1 if $webcontent =~ /DestroyCount=(\d+)/mi ; + + $self->{output}->output_add(severity => "ok", short_msg => sprintf("MaxThreads: %d", $maxthreads)); + $self->{output}->output_add(severity => "ok", short_msg => sprintf("MinSpareThreads: %d", $minsparethreads)); + $self->{output}->output_add(severity => "ok", short_msg => sprintf("MaxSpareThreads: %d", $maxsparethreads)); + $self->{output}->output_add(severity => "ok", short_msg => sprintf("MaxQueueSize: %d", $maxqueuesize)); + $self->{output}->output_add(severity => "ok", short_msg => sprintf("IdleTimeout: %ds", $idletimeout)); + $self->{output}->output_add(severity => "ok", short_msg => sprintf("ProcessedCount: %d", $processedcount)); + $self->{output}->output_add(severity => "ok", short_msg => sprintf("CurrentThreadCount: %d", $currentthreadcount)); + $self->{output}->output_add(severity => "ok", short_msg => sprintf("AvailableThreadCount: %d", $availablethreadcount)); + + my $exit = $self->{perfdata}->threshold_check(value => $busythreadcount, threshold => [ { label => 'critical', exit_litteral => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]); + $self->{output}->output_add(severity => $exit, short_msg => sprintf("BusyThreadCount: %d", $busythreadcount)); + + $self->{output}->output_add(severity => "ok", short_msg => sprintf("MaxAvailableThreadCount: %d", $maxavailablethreadcount)); + $self->{output}->output_add(severity => "ok", short_msg => sprintf("MaxBusyThreadCount: %d", $maxbusythreadcount)); + $self->{output}->output_add(severity => "ok", short_msg => sprintf("MaxProcessedTime: %dms", $maxprocessedtime)); + $self->{output}->output_add(severity => "ok", short_msg => sprintf("CreateCount: %d", $createcount)); + $self->{output}->output_add(severity => "ok", short_msg => sprintf("DestroyCount: %d", $destroycount)); + + $self->{output}->perfdata_add(label => "MaxThreads", unit => '', + value => sprintf("%d", $maxthreads), + ); + $self->{output}->perfdata_add(label => "MinSpareThreads", unit => '', + value => sprintf("%d", $minsparethreads), + ); + $self->{output}->perfdata_add(label => "MaxSpareThreads", unit => '', + value => sprintf("%d", $maxsparethreads), + ); + $self->{output}->perfdata_add(label => "MaxQueueSize", unit => '', + value => sprintf("%d", $maxqueuesize), + ); + $self->{output}->perfdata_add(label => "IdleTimeout", unit => 's', + value => sprintf("%d", $idletimeout), + ); + $self->{output}->perfdata_add(label => "c[ProcessedCount]", unit => '', + value => sprintf("%d", $processedcount), + ); + $self->{output}->perfdata_add(label => "CurrentThreadCount", unit => '', + value => sprintf("%d", $currentthreadcount), + ); + $self->{output}->perfdata_add(label => "AvailableThreadCount", unit => '', + value => sprintf("%d", $availablethreadcount), + ); + + $self->{output}->perfdata_add(label => "BusyThreadCount", unit => '', + value => sprintf("%d", $busythreadcount), + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning'), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical'), + ); + + $self->{output}->perfdata_add(label => "MaxAvailableThreadCount", unit => '', + value => sprintf("%d", $maxavailablethreadcount), + ); + $self->{output}->perfdata_add(label => "MaxBusyThreadCount", unit => '', + value => sprintf("%d", $maxbusythreadcount), + ); + $self->{output}->perfdata_add(label => "MaxProcessedTime", unit => 'ms', + value => sprintf("%d", $maxprocessedtime), + ); + $self->{output}->perfdata_add(label => "c[CreateCount]", unit => '', + value => sprintf("%d", $createcount), + ); + $self->{output}->perfdata_add(label => "c[DestroyCount]", unit => '', + value => sprintf("%d", $destroycount), + ); + + $self->{output}->display(); + $self->{output}->exit(); +} + +1; + +__END__ + +=head1 MODE + +Check EAS instance muxhandler(Apusic) threads pool status. + +=over 8 + +=item B<--urlpath> + +Set path to get status page. (Default: '/easportal/tools/nagios/checkmuxhandler.jsp') + +=item B<--warning> + +Warning Threshold for busy thread count. + +=item B<--critical> + +Critical Threshold for busy thread count. + +=back + +=cut diff --git a/centreon-plugins/apps/kingdee/eas/mode/oraclejvmgc.pm b/centreon-plugins/apps/kingdee/eas/mode/oraclejvmgc.pm new file mode 100644 index 000000000..7a9f1f871 --- /dev/null +++ b/centreon-plugins/apps/kingdee/eas/mode/oraclejvmgc.pm @@ -0,0 +1,123 @@ +# +# Copyright 2017 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. +# +# Author : CHEN JUN , aladdin.china@gmail.com + +package apps::kingdee::eas::mode::oraclejvmgc; + +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 => + { + "urlpath:s" => { name => 'url_path', default => "/easportal/tools/nagios/checkgc_ps.jsp" }, + "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) = @_; + + my $webcontent = $options{custom}->request(path => $self->{option_results}->{url_path}); + + if ( $webcontent !~ /MinorGCCount=\d+/mi ) { + $self->{output}->output_add( + severity => 'UNKNOWN', + short_msg => "Cannot find jvm gc status." + ); + $self->{output}->option_exit(); + } + + my ($minorgccount, $minorgctime, $fullgccount, $fullgctime) = (0, 0, 0, 0); + + ($minorgccount, $minorgctime, $fullgccount, $fullgctime) = ($1, $2, $3, $4) if ($webcontent =~ /MinorGCCount=(\d+)\sMinorGCTime=(\d+)\sFullGCCount=(\d+)\sFullGCTime=(\d+)/mi); + + $self->{output}->output_add(severity => "ok", short_msg => sprintf("MinorGCCount: %d", $minorgccount)); + $self->{output}->output_add(severity => "ok", short_msg => sprintf("MinorGCTime: %dms", $minorgctime)); + $self->{output}->output_add(severity => "ok", short_msg => sprintf("FullGCCount: %d", $fullgccount)); + $self->{output}->output_add(severity => "ok", short_msg => sprintf("FullGCTime: %dms", $fullgctime)); + + $self->{output}->perfdata_add(label => "c[MinorGCCount]", unit => '', + value => sprintf("%d", $minorgccount), + ); + $self->{output}->perfdata_add(label => "c[MinorGCTime]", unit => 'ms', + value => sprintf("%d", $minorgctime), + ); + $self->{output}->perfdata_add(label => "c[FullGCCount]", unit => '', + value => sprintf("%d", $fullgccount), + ); + $self->{output}->perfdata_add(label => "c[FullGCTime]", unit => 'ms', + value => sprintf("%d", $fullgctime), + ); + + $self->{output}->display(); + $self->{output}->exit(); + +} + +1; + +__END__ + +=head1 MODE + +Check EAS application jvm gc status. + +=over 8 + +=item B<--urlpath> + +Set path to get status page. (Default: '/easportal/tools/nagios/checkgc_ps.jsp') + +=item B<--warning> + +Warning Threshold for class loaded + +=item B<--critical> + +Critical Threshold for class unloaded + +=back + +=cut diff --git a/centreon-plugins/apps/kingdee/eas/mode/oracleksqltemptable.pm b/centreon-plugins/apps/kingdee/eas/mode/oracleksqltemptable.pm new file mode 100644 index 000000000..ed97ca5b0 --- /dev/null +++ b/centreon-plugins/apps/kingdee/eas/mode/oracleksqltemptable.pm @@ -0,0 +1,125 @@ +# +# Copyright 2017 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. +# +# Author : CHEN JUN , aladdin.china@gmail.com + +package apps::kingdee::eas::mode::oracleksqltemptable; + +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 => + { + "urlpath:s" => { name => 'url_path', default => "/easportal/tools/nagios/checkoraclevt.jsp" }, + "datasource:s" => { name => 'datasource' }, + "warning:s" => { name => 'warning' }, + "critical:s" => { name => 'critical' }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::init(%options); + + if (!defined($self->{option_results}->{datasource}) || $self->{option_results}->{datasource} eq "") { + $self->{output}->add_option_msg(short_msg => "Missing datasource name."); + $self->{output}->option_exit(); + } + $self->{option_results}->{url_path} .= "?ds=" . $self->{option_results}->{datasource}; + + 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 $webcontent = $options{custom}->request(path => $self->{option_results}->{url_path}); + + if ($webcontent !~ /^COUNT.*?=\d+/i) { + $self->{output}->output_add( + severity => 'UNKNOWN', + short_msg => "Cannot find ksql temptable status." + ); + $self->{output}->option_exit(); + } + + my $count = $1 if $webcontent =~ /^COUNT.*?=(\d+)/i; + + 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("KSQLTempTableCount: %d", $count)); + + $self->{output}->perfdata_add(label => "KSQLTempTableCount", unit => '', + value => sprintf("%d", $count), + 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 ksql temp table count for specify datasource. + +=over 8 + +=item B<--urlpath> + +Set path to get status page. (Default: '/easportal/tools/nagios/checkoraclevt.jsp') + +=item B<--datasource> + +Specify the datasource name. + +=item B<--warning> + +Warning Threshold. + +=item B<--critical> + +Critical Threshold. + +=back + +=cut diff --git a/centreon-plugins/apps/kingdee/eas/mode/oraclerecyclebin.pm b/centreon-plugins/apps/kingdee/eas/mode/oraclerecyclebin.pm new file mode 100644 index 000000000..1cbb63078 --- /dev/null +++ b/centreon-plugins/apps/kingdee/eas/mode/oraclerecyclebin.pm @@ -0,0 +1,125 @@ +# +# Copyright 2017 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. +# +# Author : CHEN JUN , aladdin.china@gmail.com + +package apps::kingdee::eas::mode::oraclerecyclebin; + +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 => + { + "urlpath:s" => { name => 'url_path', default => "/easportal/tools/nagios/checkoraclerecyclebin.jsp" }, + "datasource:s" => { name => 'datasource' }, + "warning:s" => { name => 'warning' }, + "critical:s" => { name => 'critical' }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::init(%options); + + if (!defined($self->{option_results}->{datasource}) || $self->{option_results}->{datasource} eq "") { + $self->{output}->add_option_msg(short_msg => "Missing datasource name."); + $self->{output}->option_exit(); + } + $self->{option_results}->{url_path} .= "?ds=" . $self->{option_results}->{datasource}; + + 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 $webcontent = $options{custom}->request(path => $self->{option_results}->{url_path}); + + if ( $webcontent !~ /^COUNT.*?=\d+/i ) { + $self->{output}->output_add( + severity => 'UNKNOWN', + short_msg => "Cannot find oracle recyclebin status." + ); + $self->{output}->option_exit(); + } + + my $count = $1 if $webcontent =~ /^COUNT.*?=(\d+)/i; + + 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("RecyclebinTableCount: %d", $count)); + + $self->{output}->perfdata_add(label => "RecyclebinTableCount", unit => '', + value => sprintf("%d", $count), + 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 oracle recyclebin table count for specify datasource. + +=over 8 + +=item B<--urlpath> + +Set path to get status page. (Default: '/easportal/tools/nagios/checkoraclerecyclebin.jsp') + +=item B<--datasource> + +Specify the datasource name. + +=item B<--warning> + +Warning Threshold. + +=item B<--critical> + +Critical Threshold. + +=back + +=cut diff --git a/centreon-plugins/apps/kingdee/eas/mode/oracleredolog.pm b/centreon-plugins/apps/kingdee/eas/mode/oracleredolog.pm new file mode 100644 index 000000000..21d50d0fa --- /dev/null +++ b/centreon-plugins/apps/kingdee/eas/mode/oracleredolog.pm @@ -0,0 +1,133 @@ +# +# Copyright 2017 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure 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 +# limitations under the License. +# +# Author : CHEN JUN , aladdin.china@gmail.com + +package apps::kingdee::eas::mode::oracleredolog; + +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 => + { + "urlpath:s" => { name => 'url_path', default => "/easportal/tools/nagios/checkoracleredolog.jsp" }, + "datasource:s" => { name => 'datasource' }, + "warning:s" => { name => 'warning' }, + "critical:s" => { name => 'critical' }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::init(%options); + + if (!defined($self->{option_results}->{datasource}) || $self->{option_results}->{datasource} eq "") { + $self->{output}->add_option_msg(short_msg => "Missing datasource name."); + $self->{output}->option_exit(); + } + $self->{option_results}->{url_path} .= "?ds=" . $self->{option_results}->{datasource}; + + 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 $webcontent = $options{custom}->request(path => $self->{option_results}->{url_path}); + if ($webcontent !~ /^STATUS=CURRENT/mi) { + $self->{output}->output_add( + severity => 'UNKNOWN', + short_msg => "Cannot find oracle redolog status." + ); + $self->{output}->option_exit(); + } + + my ($activecount, $inactivecount, $currentcount) = (0, 0, 0); + $activecount = $1 if $webcontent =~ /^STATUS=ACTIVE\sCOUNT=(\d+)/mi ; + $inactivecount = $1 if $webcontent =~ /^STATUS=INACTIVE\sCOUNT=(\d+)/mi ; + $currentcount = $1 if $webcontent =~ /^STATUS=CURRENT\sCOUNT=(\d+)/mi ; + + my $exit = $self->{perfdata}->threshold_check(value => $inactivecount, threshold => [ + { label => 'critical', 'exit_litteral' => 'critical' }, + { label => 'warning', exit_litteral => 'warning' } ]); + $self->{output}->output_add(severity => $exit, short_msg => sprintf("InactiveCount: %d", $inactivecount)); + $self->{output}->output_add(severity => "ok", short_msg => sprintf("ActiveCount: %d", $activecount)); + $self->{output}->output_add(severity => "ok", short_msg => sprintf("CurrentCount: %d", $currentcount)); + + $self->{output}->perfdata_add(label => "InactiveCount", unit => '', + value => sprintf("%d", $inactivecount), + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning'), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical'), + ); + $self->{output}->perfdata_add(label => "ActiveCount", unit => '', + value => sprintf("%d", $activecount)); + $self->{output}->perfdata_add(label => "CurrentCount", unit => '', + value => sprintf("%d", $currentcount)); + + $self->{output}->display(); + $self->{output}->exit(); + +} + +1; + +__END__ + +=head1 MODE + +Check oracle redolog status . + +=over 8 + +=item B<--urlpath> + +Set path to get status page. (Default: '/easportal/tools/nagios/checkoracleredolog.jsp') + +=item B<--datasource> + +Specify the datasource name. + +=item B<--warning> + +Warning Threshold for INACTIVE count. + +=item B<--critical> + +Critical Threshold for INACTIVE count. + +=back + +=cut diff --git a/centreon-plugins/apps/kingdee/eas/mode/oraclesession.pm b/centreon-plugins/apps/kingdee/eas/mode/oraclesession.pm new file mode 100644 index 000000000..fbf7bac23 --- /dev/null +++ b/centreon-plugins/apps/kingdee/eas/mode/oraclesession.pm @@ -0,0 +1,199 @@ +# +# Copyright 2017 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure 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 +# limitations under the License. +# +# Author : CHEN JUN , aladdin.china@gmail.com + +package apps::kingdee::eas::mode::oraclesession; + +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 => + { + "urlpath:s" => { name => 'url_path', default => "/easportal/tools/nagios/checkoraclesession.jsp" }, + "datasource:s" => { name => 'datasource' }, + "warning:s" => { name => 'warning', default => "," }, + "critical:s" => { name => 'critical', default => "," }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::init(%options); + + if (!defined($self->{option_results}->{datasource}) || $self->{option_results}->{datasource} eq "") { + $self->{output}->add_option_msg(short_msg => "Missing datasource name."); + $self->{output}->option_exit(); + } + $self->{option_results}->{url_path} .= "?ds=" . $self->{option_results}->{datasource}; + + ($self->{warn_activecount}, $self->{warn_totalcount}) = split /,/, $self->{option_results}->{"warning"}; + ($self->{crit_activecount}, $self->{crit_totalcount}) = split /,/, $self->{option_results}->{"critical"}; + + # warning + if (($self->{perfdata}->threshold_validate(label => 'warn_activecount', value => $self->{warn_activecount})) == 0) { + $self->{output}->add_option_msg(short_msg => "Wrong warning activecount threshold '" . $self->{warn_activecount} . "'."); + $self->{output}->option_exit(); + } + if (($self->{perfdata}->threshold_validate(label => 'warn_totalcount', value => $self->{warn_totalcount})) == 0) { + $self->{output}->add_option_msg(short_msg => "Wrong warning totalcount threshold '" . $self->{warn_totalcount} . "'."); + $self->{output}->option_exit(); + } + # critical + if (($self->{perfdata}->threshold_validate(label => 'crit_activecount', value => $self->{crit_activecount})) == 0) { + $self->{output}->add_option_msg(short_msg => "Wrong critical activecount threshold '" . $self->{crit_activecount} . "'."); + $self->{output}->option_exit(); + } + if (($self->{perfdata}->threshold_validate(label => 'crit_totalcount', value => $self->{crit_totalcount})) == 0) { + $self->{output}->add_option_msg(short_msg => "Wrong critical totalcount threshold '" . $self->{crit_totalcount} . "'."); + $self->{output}->option_exit(); + } +} + +sub run { + my ($self, %options) = @_; + + my $webcontent = $options{custom}->request(path => $self->{option_results}->{url_path} . '&groupby=status'); + if ($webcontent !~ /^STATUS=ACTIVE/mi) { + $self->{output}->output_add( + severity => 'UNKNOWN', + short_msg => "Cannot find oracle session info." + ); + $self->{output}->option_exit(); + } + + my ($activecount, $inactivecount, $totalcount) = (0, 0, 0); + $activecount = $1 if $webcontent =~ /^STATUS=ACTIVE\sCOUNT=(\d+)/mi ; + $inactivecount = $1 if $webcontent =~ /^STATUS=INACTIVE\sCOUNT=(\d+)/mi ; + $totalcount = $activecount + $inactivecount; + + $webcontent = $options{custom}->request(path => $self->{option_results}->{url_path} . '&groupby=wait_class&status=ACTIVE'); + if ($webcontent !~ /^WAIT_CLASS=.*?COUNT=\d+/i) { + $self->{output}->output_add( + severity => 'UNKNOWN', + short_msg => "Cannot find oracle session info." + ); + $self->{output}->option_exit(); + } + + my ($other, $queueing, $network, $administrative, $configuation, $commit) = (0, 0, 0, 0, 0, 0); + my ($application, $concurrency, $systemio, $userio, $scheduler, $idle) = (0, 0, 0, 0, 0, 0); + + $other = $1 if $webcontent =~ /^WAIT_CLASS=Other\sCOUNT=(\d+)/mi; + $queueing = $1 if $webcontent =~ /^WAIT_CLASS=Queueing\sCOUNT=(\d+)/mi; + $network = $1 if $webcontent =~ /^WAIT_CLASS=Network\sCOUNT=(\d+)/mi; + $administrative = $1 if $webcontent =~ /^WAIT_CLASS=Administrative\sCOUNT=(\d+)/mi; + $configuation = $1 if $webcontent =~ /^WAIT_CLASS=Configuration\sCOUNT=(\d+)/mi; + $commit = $1 if $webcontent =~ /^WAIT_CLASS=Commit\sCOUNT=(\d+)/mi; + $application = $1 if $webcontent =~ /^WAIT_CLASS=Application\sCOUNT=(\d+)/mi; + $concurrency = $1 if $webcontent =~ /^WAIT_CLASS=Concurrency\sCOUNT=(\d+)/mi; + $systemio = $1 if $webcontent =~ /^WAIT_CLASS=\'System\sI\/O\'\sCOUNT=(\d+)/mi; + $userio = $1 if $webcontent =~ /^WAIT_CLASS='User\sI\/O\'\sCOUNT=(\d+)/mi; + $scheduler = $1 if $webcontent =~ /^WAIT_CLASS=Scheduler\sCOUNT=(\d+)/mi; + $idle = $1 if $webcontent =~ /^WAIT_CLASS=Idle\sCOUNT=(\d+)/mi; + + my $cpuandwait = $idle + $network; + + $self->{output}->output_add(severity => "ok", short_msg => sprintf("Other: %d", $other)); + $self->{output}->output_add(severity => "ok", short_msg => sprintf("Queueing: %d", $queueing)); + $self->{output}->output_add(severity => "ok", short_msg => sprintf("Administrative: %d", $administrative)); + $self->{output}->output_add(severity => "ok", short_msg => sprintf("Configuration: %d", $configuation)); + $self->{output}->output_add(severity => "ok", short_msg => sprintf("Commit: %d", $commit)); + $self->{output}->output_add(severity => "ok", short_msg => sprintf("Application: %d", $application)); + $self->{output}->output_add(severity => "ok", short_msg => sprintf("Concurrency: %d", $concurrency)); + $self->{output}->output_add(severity => "ok", short_msg => sprintf("System I/O: %d", $systemio)); + $self->{output}->output_add(severity => "ok", short_msg => sprintf("User I/O: %d", $userio)); + $self->{output}->output_add(severity => "ok", short_msg => sprintf("Scheduler: %d", $scheduler)); + $self->{output}->output_add(severity => "ok", short_msg => sprintf("CPU + CPU Wait: %d", $cpuandwait)); + + my $exit = $self->{perfdata}->threshold_check(value => $activecount, threshold => [ { label => 'crit_activecount', exit_litteral => 'critical' }, + { label => 'warn_activecount', exit_litteral => 'warning' } ]); + $self->{output}->output_add(severity => $exit, short_msg => sprintf("ActiveCount: %d", $activecount)); + + $exit = $self->{perfdata}->threshold_check(value => $totalcount, threshold => [ { label => 'crit_totalcount', exit_litteral => 'critical' }, + { label => 'warn_totalcount', exit_litteral => 'warning' } ]); + $self->{output}->output_add(severity => $exit, short_msg => sprintf("TotalCount: %d", $totalcount)); + + $self->{output}->perfdata_add(label => "Other", unit => '', value => sprintf("%d", $other)); + $self->{output}->perfdata_add(label => "Queueing", unit => '', value => sprintf("%d", $queueing)); + $self->{output}->perfdata_add(label => "Administrative", unit => '', value => sprintf("%d", $administrative)); + $self->{output}->perfdata_add(label => "Configuration", unit => '', value => sprintf("%d", $configuation)); + $self->{output}->perfdata_add(label => "Commit", unit => '', value => sprintf("%d", $commit)); + $self->{output}->perfdata_add(label => "Application", unit => '', value => sprintf("%d", $application)); + $self->{output}->perfdata_add(label => "Concurrency", unit => '', value => sprintf("%d", $concurrency)); + $self->{output}->perfdata_add(label => "System I/O", unit => '', value => sprintf("%d", $systemio)); + $self->{output}->perfdata_add(label => "User I/O", unit => '', value => sprintf("%d", $userio)); + $self->{output}->perfdata_add(label => "Scheduler", unit => '', value => sprintf("%d", $scheduler)); + $self->{output}->perfdata_add(label => "CPU + CPU Wait", unit => '', value => sprintf("%d", $cpuandwait)); + + $self->{output}->perfdata_add(label => "ActiveCount", unit => '', + value => sprintf("%d", $activecount), + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warn_activecount'), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'crit_activecount'), + ); + $self->{output}->perfdata_add(label => "TotalCount", unit => '', + value => sprintf("%d", $totalcount), + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warn_totalcount'), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'crit_totalcount'), + ); + + $self->{output}->display(); + $self->{output}->exit(); + +} + +1; + +__END__ + +=head1 MODE + +Check oracle database session status. + +=over 8 + +=item B<--urlpath> + +Set path to get status page. (Default: '/easportal/tools/nagios/checkoraclesession.jsp') + +=item B<--datasource> + +Specify the datasource name. + +=item B<--warning> + +Warning Threshold. (activecount,totalcount) for example: --warning=50,200 + +=item B<--critical> + +Critical Threshold. (activecount,totalcount) for example: --critical=100,300 + +=back + +=cut diff --git a/centreon-plugins/apps/kingdee/eas/mode/oracletable.pm b/centreon-plugins/apps/kingdee/eas/mode/oracletable.pm new file mode 100644 index 000000000..ad0053158 --- /dev/null +++ b/centreon-plugins/apps/kingdee/eas/mode/oracletable.pm @@ -0,0 +1,156 @@ +# +# Copyright 2017 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure 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 +# limitations under the License. +# +# Author : CHEN JUN , aladdin.china@gmail.com + +package apps::kingdee::eas::mode::oracletable; + +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 => + { + "urlpath:s" => { name => 'url_path', default => "/easportal/tools/nagios/checkoracletable.jsp" }, + "datasource:s" => { name => 'datasource' }, + "tablename:s" => { name => 'tablename' , default => "T_GL_VOUCHER"}, + "actualrows:s" => { name => 'actualrows', default => "false" }, + "warning:s" => { name => 'warning' }, + "critical:s" => { name => 'critical' }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::init(%options); + + if (!defined($self->{option_results}->{datasource}) || $self->{option_results}->{datasource} eq "") { + $self->{output}->add_option_msg(short_msg => "Missing datasource name."); + $self->{output}->option_exit(); + } + $self->{option_results}->{url_path} .= "?ds=" . $self->{option_results}->{datasource} + . "\&tablename=" . $self->{option_results}->{tablename} + . "\&actual=" . $self->{option_results}->{actualrows}; + + 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 $webcontent = $options{custom}->request(path => $self->{option_results}->{url_path}); + if ($webcontent !~ /^TABLE_NAME=\w+/i) { + $self->{output}->output_add( + severity => 'UNKNOWN', + short_msg => "Cannot find oracle table status. \n" . $webcontent + ); + $self->{output}->option_exit(); + } + + my ($num_rows, $actual_num_rows) = (-1, -1); + $num_rows = $1 if $webcontent =~ /NUM_ROWS=(\d+)/i; + $actual_num_rows = $1 if $webcontent =~ /ACTUAL_NUM_ROWS=(\d+)/i; + + my $exit; + if ($actual_num_rows == -1) { + $exit = $self->{perfdata}->threshold_check(value => $num_rows, threshold => [ + { label => 'critical', 'exit_litteral' => 'critical' }, + { label => 'warning', exit_litteral => 'warning' } ] + ); + $self->{output}->output_add(severity => $exit, short_msg => sprintf("NUM_ROWS: %d", $num_rows)); + + $self->{output}->perfdata_add(label => "NUM_ROWS", unit => '', + value => sprintf("%d", $num_rows), + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning'), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical'), + ); + } else { + $self->{output}->perfdata_add(label => "NUM_ROWS", unit => '', value => sprintf("%d", $num_rows)); + $exit = $self->{perfdata}->threshold_check(value => $actual_num_rows, threshold => [ + { label => 'critical', 'exit_litteral' => 'critical' }, + { label => 'warning', exit_litteral => 'warning' } ] + ); + $self->{output}->output_add(severity => $exit, short_msg => sprintf("ACTUAL_NUM_ROWS: %d", $actual_num_rows)); + + $self->{output}->perfdata_add(label => "ACTUAL_NUM_ROWS", unit => '', + value => sprintf("%d", $actual_num_rows), + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning'), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical'), + ); + } + $self->{output}->output_add(severity => $exit, short_msg => $webcontent); + + $self->{output}->display(); + $self->{output}->exit(); +} + +1; + +__END__ + +=head1 MODE + +Check oracle table info for specify datasource. + +=over 8 + +=item B<--urlpath> + +Set path to get status page. (Default: '/easportal/tools/nagios/checkoracletable.jsp') + +=item B<--datasource> + +Specify the datasource name. + +=item B<--tablename> + +Specify the table name , MUST BE uppercase. + +=item B<--actualrows> + +Specify whether check actual rows of table or not , true or false. +MAY have performance problem for large table if specify true. + +=item B<--warning> + +Warning Threshold for num_rows , or actual_num_rows if actualrows is true. + +=item B<--critical> + +Critical Threshold for num_rows , or actual_num_rows if actualrows is true. + +=back + +=cut diff --git a/centreon-plugins/apps/kingdee/eas/mode/oracleversion.pm b/centreon-plugins/apps/kingdee/eas/mode/oracleversion.pm new file mode 100644 index 000000000..a4ce4a70e --- /dev/null +++ b/centreon-plugins/apps/kingdee/eas/mode/oracleversion.pm @@ -0,0 +1,115 @@ +# +# Copyright 2017 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure 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 +# limitations under the License. +# +# Author : CHEN JUN , aladdin.china@gmail.com + +package apps::kingdee::eas::mode::oracleversion; + +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 => + { + "urlpath:s" => { name => 'url_path', default => "/easportal/tools/nagios/checkoracleversion.jsp" }, + "datasource:s" => { name => 'datasource' }, + "warning:s" => { name => 'warning' }, + "critical:s" => { name => 'critical' }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::init(%options); + + if (!defined($self->{option_results}->{datasource}) || $self->{option_results}->{datasource} eq "") { + $self->{output}->add_option_msg(short_msg => "Missing datasource name."); + $self->{output}->option_exit(); + } + $self->{option_results}->{url_path} .= "?ds=" . $self->{option_results}->{datasource}; + + 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 $webcontent = $options{custom}->request(path => $self->{option_results}->{url_path}); + if ($webcontent !~ /^BANNER=/i) { + $self->{output}->output_add( + severity => 'UNKNOWN', + short_msg => "Cannot find oracle version info." + ); + $self->{output}->option_exit(); + } + + my $banner = $1 if $webcontent =~ /^BANNER=\'(.*?)\'/i; + + $self->{output}->output_add(severity => "ok", short_msg => $banner); + + $self->{output}->display(); + $self->{output}->exit(); + +} + +1; + +__END__ + +=head1 MODE + +Check oracle database version. + +=over 8 + +=item B<--urlpath> + +Set path to get status page. (Default: '/easportal/tools/nagios/checkoracleversion.jsp') + +=item B<--datasource> + +Specify the datasource name. + +=item B<--warning> + +Warning Threshold. + +=item B<--critical> + +Critical Threshold. + +=back + +=cut diff --git a/centreon-plugins/apps/kingdee/eas/mode/ormrpc.pm b/centreon-plugins/apps/kingdee/eas/mode/ormrpc.pm new file mode 100644 index 000000000..d483a7260 --- /dev/null +++ b/centreon-plugins/apps/kingdee/eas/mode/ormrpc.pm @@ -0,0 +1,269 @@ +# +# Copyright 2017 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. +# +# Author : CHEN JUN , aladdin.china@gmail.com + +package apps::kingdee::eas::mode::ormrpc; + +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 => { + "urlpath:s" => { name => 'url_path', default => "/easportal/tools/nagios/checkrpc.jsp" }, + "warning:s" => { name => 'warning' , default => ",,,,,,"}, + "critical:s" => { name => 'critical' , default => ",,,,,,"}, + } + ); + + return $self; +} + +sub check_options { + my ( $self, %options ) = @_; + $self->SUPER::init(%options); + + ($self->{warn_activethreadcount}, $self->{warn_stubcount}, $self->{warn_proxycount}, $self->{warn_clientsessioncount} ,$self->{warn_serversessioncount} ,$self->{warn_invokecountpermin} ,$self->{warn_servicecountpermin}) + = split /,/, $self->{option_results}->{"warning"}; + ($self->{crit_activethreadcount}, $self->{crit_stubcount}, $self->{crit_proxycount}, $self->{crit_clientsessioncount} ,$self->{crit_serversessioncount} ,$self->{crit_invokecountpermin} ,$self->{crit_servicecountpermin}) + = split /,/, $self->{option_results}->{"critical"}; + + # warning + if (($self->{perfdata}->threshold_validate(label => 'warn_activethreadcount', value => $self->{warn_activethreadcount})) == 0) { + $self->{output}->add_option_msg(short_msg => "Wrong warning activethreadcount threshold '" . $self->{warn_activethreadcount} . "'."); + $self->{output}->option_exit(); + } + if (($self->{perfdata}->threshold_validate(label => 'warn_stubcount', value => $self->{warn_stubcount})) == 0) { + $self->{output}->add_option_msg(short_msg => "Wrong warning stubcount threshold '" . $self->{warn_stubcount} . "'."); + $self->{output}->option_exit(); + } + if (($self->{perfdata}->threshold_validate(label => 'warn_proxycount', value => $self->{warn_proxycount})) == 0) { + $self->{output}->add_option_msg(short_msg => "Wrong warning proxycount threshold '" . $self->{warn_proxycount} . "'."); + $self->{output}->option_exit(); + } + if (($self->{perfdata}->threshold_validate(label => 'warn_clientsessioncount', value => $self->{warn_clientsessioncount})) == 0) { + $self->{output}->add_option_msg(short_msg => "Wrong warning clientsessioncount threshold '" . $self->{warn_clientsessioncount} . "'."); + $self->{output}->option_exit(); + } + if (($self->{perfdata}->threshold_validate(label => 'warn_serversessioncount', value => $self->{warn_serversessioncount})) == 0) { + $self->{output}->add_option_msg(short_msg => "Wrong warning serversessioncount threshold '" . $self->{warn_serversessioncount} . "'."); + $self->{output}->option_exit(); + } + if (($self->{perfdata}->threshold_validate(label => 'warn_invokecountpermin', value => $self->{warn_invokecountpermin})) == 0) { + $self->{output}->add_option_msg(short_msg => "Wrong warning invokecountpermin threshold '" . $self->{warn_invokecountpermin} . "'."); + $self->{output}->option_exit(); + } + if (($self->{perfdata}->threshold_validate(label => 'warn_servicecountpermin', value => $self->{warn_servicecountpermin})) == 0) { + $self->{output}->add_option_msg(short_msg => "Wrong warning servicecountpermin threshold '" . $self->{warn_servicecountpermin} . "'."); + $self->{output}->option_exit(); + } + + # critical + if (($self->{perfdata}->threshold_validate(label => 'crit_activethreadcount', value => $self->{crit_activethreadcount})) == 0) { + $self->{output}->add_option_msg(short_msg => "Wrong critical activethreadcount threshold '" . $self->{crit_activethreadcount} . "'."); + $self->{output}->option_exit(); + } + if (($self->{perfdata}->threshold_validate(label => 'crit_stubcount', value => $self->{crit_stubcount})) == 0) { + $self->{output}->add_option_msg(short_msg => "Wrong critical stubcount threshold '" . $self->{crit_stubcount} . "'."); + $self->{output}->option_exit(); + } + if (($self->{perfdata}->threshold_validate(label => 'crit_proxycount', value => $self->{crit_proxycount})) == 0) { + $self->{output}->add_option_msg(short_msg => "Wrong critical proxycount threshold '" . $self->{crit_proxycount} . "'."); + $self->{output}->option_exit(); + } + if (($self->{perfdata}->threshold_validate(label => 'crit_clientsessioncount', value => $self->{crit_clientsessioncount})) == 0) { + $self->{output}->add_option_msg(short_msg => "Wrong critical clientsessioncount threshold '" . $self->{crit_clientsessioncount} . "'."); + $self->{output}->option_exit(); + } + if (($self->{perfdata}->threshold_validate(label => 'crit_serversessioncount', value => $self->{crit_serversessioncount})) == 0) { + $self->{output}->add_option_msg(short_msg => "Wrong critical serversessioncount threshold '" . $self->{crit_serversessioncount} . "'."); + $self->{output}->option_exit(); + } + if (($self->{perfdata}->threshold_validate(label => 'crit_invokecountpermin', value => $self->{crit_invokecountpermin})) == 0) { + $self->{output}->add_option_msg(short_msg => "Wrong critical invokecountpermin threshold '" . $self->{crit_invokecountpermin} . "'."); + $self->{output}->option_exit(); + } + if (($self->{perfdata}->threshold_validate(label => 'crit_servicecountpermin', value => $self->{crit_servicecountpermin})) == 0) { + $self->{output}->add_option_msg(short_msg => "Wrong critical servicecountpermin threshold '" . $self->{crit_servicecountpermin} . "'."); + $self->{output}->option_exit(); + } +} + +sub run { + my ( $self, %options ) = @_; + + my $webcontent = $options{custom}->request(path => $self->{option_results}->{url_path}); + if ($webcontent !~ /ActiveThreadCount=\d+/i) { + $self->{output}->output_add( + severity => 'UNKNOWN', + short_msg => "Cannot find ormrpc status in response: \'" . $webcontent . "\'" + ); + $self->{output}->option_exit(); + } + + my ($activethreadcount, $stubcount, $proxycount, $clientsessioncount, $serversessioncount, $invokecountpermin, $servicecountpermin, $invokecount, $servicecount) = (0, 0, 0, 0, 0, 0, 0, 0, 0); + + $activethreadcount = $1 if $webcontent =~ /ActiveThreadCount=(\d+)/mi ; + $stubcount = $1 if $webcontent =~ /StubCount=(\d+)/mi ; + $proxycount = $1 if $webcontent =~ /ProxyCount=(\d+)/mi ; + $clientsessioncount = $1 if $webcontent =~ /ClientSessionCount=(\d+)/mi ; + $serversessioncount = $1 if $webcontent =~ /ServerSessionCount=(\d+)/mi ; + $invokecountpermin = $1 if $webcontent =~ /ClientInvokeCountPerMinute=(\d+)/mi ; + $servicecountpermin = $1 if $webcontent =~ /ProcessedServiceCountPerMinute=(\d+)/mi ; + $invokecount = $1 if $webcontent =~ /ClientInvokeCount=(\d+)/mi ; + $servicecount = $1 if $webcontent =~ /ProcessedServiceCount=(\d+)/mi ; + + my $exit = $self->{perfdata}->threshold_check(value => $activethreadcount, + threshold => [ { label => 'crit_activethreadcount', 'exit_litteral' => 'critical' }, + { label => 'warn_activethreadcount', 'exit_litteral' => 'warning' } ]); + $self->{output}->output_add( + severity => $exit, + short_msg => sprintf("ActiveTrheadCount: %d", $activethreadcount) + ); + $exit = $self->{perfdata}->threshold_check(value => $stubcount, + threshold => [ { label => 'crit_stubcount', 'exit_litteral' => 'critical' }, + { label => 'warn_stubcount', 'exit_litteral' => 'warning' } ]); + $self->{output}->output_add( + severity => $exit, + short_msg => sprintf("StubCount: %d", $stubcount) + ); + $exit = $self->{perfdata}->threshold_check(value => $proxycount, + threshold => [ { label => 'crit_proxycount', 'exit_litteral' => 'critical' }, + { label => 'warn_proxycount', 'exit_litteral' => 'warning' } ]); + $self->{output}->output_add( + severity => $exit, + short_msg => sprintf("ProxyCount: %d", $proxycount) + ); + $exit = $self->{perfdata}->threshold_check(value => $clientsessioncount, + threshold => [ { label => 'crit_clientsessioncount', 'exit_litteral' => 'critical' }, + { label => 'warn_clientsessioncount', 'exit_litteral' => 'warning' } ]); + $self->{output}->output_add( + severity => $exit, + short_msg => sprintf("ClientSessionCount: %d", $clientsessioncount) + ); + $exit = $self->{perfdata}->threshold_check(value => $serversessioncount, + threshold => [ { label => 'crit_serversessioncount', 'exit_litteral' => 'critical' }, + { label => 'warn_serversessioncount', 'exit_litteral' => 'warning' } ]); + $self->{output}->output_add( + severity => $exit, + short_msg => sprintf("ServerSessionCount: %d", $serversessioncount) + ); + $exit = $self->{perfdata}->threshold_check(value => $invokecountpermin, + threshold => [ { label => 'crit_invokecountpermin', 'exit_litteral' => 'critical' }, + { label => 'warn_invokecountpermin', 'exit_litteral' => 'warning' } ]); + $self->{output}->output_add( + severity => $exit, + short_msg => sprintf("InvokeCountPerMinute: %d", $invokecountpermin) + ); + $exit = $self->{perfdata}->threshold_check(value => $servicecountpermin, + threshold => [ { label => 'crit_servicecountpermin', 'exit_litteral' => 'critical' }, + { label => 'warn_servicecountpermin', 'exit_litteral' => 'warning' } ]); + $self->{output}->output_add( + severity => $exit, + short_msg => sprintf("ServiceCountPerMinute: %d", $servicecountpermin) + ); + + $self->{output}->perfdata_add( + label => "ActiveTrheadCount", + value => $activethreadcount, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warn_activethreadcount'), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'crit_activethreadcount'), + ); + $self->{output}->perfdata_add( + label => "StubCount", + value => $stubcount, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warn_stubcount'), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'crit_stubcount'), + ); + $self->{output}->perfdata_add( + label => "ProxyCount", + value => $proxycount, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warn_proxycount'), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'crit_proxycount'), + ); + $self->{output}->perfdata_add( + label => "ClientSessionCount", + value => $clientsessioncount, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warn_clientsessioncount'), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'crit_clientsessioncount'), + ); + $self->{output}->perfdata_add( + label => "ServerSessionCount", + value => $serversessioncount, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warn_serversessioncount'), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'crit_serversessioncount'), + ); + $self->{output}->perfdata_add( + label => "InvokeCount /min", + value => $invokecountpermin, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warn_invokecountpermin'), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'crit_invokecountpermin'), + ); + $self->{output}->perfdata_add( + label => "ServiceCount /min", + value => $servicecountpermin, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warn_servicecountpermin'), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'crit_servicecountpermin'), + ); + $self->{output}->perfdata_add( + label => "c[InvokeCount]", + value => $invokecount, + ); + $self->{output}->perfdata_add( + label => "c[ServiceCount]", + value => $servicecount, + ); + + $self->{output}->display(); + $self->{output}->exit(); +} + +1; + +__END__ + +=head1 MODE + +Check EAS instance orm rpc status. + +=over 8 + +=item B<--urlpath> + +Set path to get status page. (Default: '/easportal/tools/nagios/checkrpc.jsp') + +=item B<--warning> + +Warning Threshold (activethreadcount,stubcount,proxycount,clientsessioncount,serversessioncount,invokecountpermin,servicecountpermin). + +=item B<--critical> + +Critical Threshold (activethreadcount,stubcount,proxycount,clientsessioncount,serversessioncount,invokecountpermin,servicecountpermin). + +=back + +=cut diff --git a/centreon-plugins/apps/kingdee/eas/mode/transaction.pm b/centreon-plugins/apps/kingdee/eas/mode/transaction.pm new file mode 100644 index 000000000..5c542c813 --- /dev/null +++ b/centreon-plugins/apps/kingdee/eas/mode/transaction.pm @@ -0,0 +1,170 @@ +# +# Copyright 2017 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. +# +# Author : CHEN JUN , aladdin.china@gmail.com + +package apps::kingdee::eas::mode::transaction; + +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 => + { + "urlpath:s" => { name => 'url_path', default => "/easportal/tools/nagios/checktransaction.jsp" }, + "datasource:s" => { name => 'datasource' }, + "warning:s" => { name => 'warning', default => "," }, + "critical:s" => { name => 'critical', default => "," }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::init(%options); + + ($self->{warn_activecount}, $self->{warn_timeoutcount}) + = split /,/, $self->{option_results}->{"warning"}; + ($self->{crit_activecount}, $self->{crit_timeoutcount}) + = split /,/, $self->{option_results}->{"critical"}; + + # warning + if (($self->{perfdata}->threshold_validate(label => 'warn_activecount', value => $self->{warn_activecount})) == 0) { + $self->{output}->add_option_msg(short_msg => "Wrong warning activecount threshold '" . $self->{warn_activecount} . "'."); + $self->{output}->option_exit(); + } + if (($self->{perfdata}->threshold_validate(label => 'warn_timeoutcount', value => $self->{warn_timeoutcount})) == 0) { + $self->{output}->add_option_msg(short_msg => "Wrong warning timeoutcount threshold '" . $self->{warn_timeoutcount} . "'."); + $self->{output}->option_exit(); + } + # critical + if (($self->{perfdata}->threshold_validate(label => 'crit_activecount', value => $self->{crit_activecount})) == 0) { + $self->{output}->add_option_msg(short_msg => "Wrong critical activecount threshold '" . $self->{crit_activecount} . "'."); + $self->{output}->option_exit(); + } + if (($self->{perfdata}->threshold_validate(label => 'crit_timeoutcount', value => $self->{crit_timeoutcount})) == 0) { + $self->{output}->add_option_msg(short_msg => "Wrong critical timeoutcount threshold '" . $self->{crit_timeoutcount} . "'."); + $self->{output}->option_exit(); + } +} + +sub run { + my ($self, %options) = @_; + + my $webcontent = $options{custom}->request(path => $self->{option_results}->{url_path}); + if ($webcontent !~ /TransactionCount=\d+/i) { + $self->{output}->output_add( + severity => 'UNKNOWN', + short_msg => "Cannot find transaction status." + ); + } + + my ($transactioncount, $totaltransactiontime, $committedcount, $rolledbackcount, $activecount, $maxtransactiontime, $defaulttimeout, $timeoutcount) = (0, 0, 0, 0, 0, 0, 0, 0); + + $transactioncount = $1 if $webcontent =~ /TransactionCount=(\d+)\s/i; + $totaltransactiontime = $1 if $webcontent =~ /TotalTransactionTime=(\d+)\s/i; + $committedcount = $1 if $webcontent =~ /CommittedCount=(\d+)\s/i; + $rolledbackcount = $1 if $webcontent =~ /RolledbackCount=(\d+)\s/i; + $activecount = $1 if $webcontent =~ /ActiveCount=(\d+)\s/i; + $maxtransactiontime = $1 if $webcontent =~ /MaxTransactionTime=(\d+)\s/i; + $defaulttimeout = $1 if $webcontent =~ /DefaultTimeout=(\d+)\s/i; + $timeoutcount = $1 if $webcontent =~ /TimedOutCount=(\d+)\s/i; + + my $exit = $self->{perfdata}->threshold_check(value => $activecount, threshold => [ { label => 'crit_activecount', exit_litteral => 'critical' }, + { label => 'warn_activecount', exit_litteral => 'warning' } ]); + $self->{output}->output_add(severity => $exit, short_msg => sprintf("ActiveCount: %d", $activecount)); + + $exit = $self->{perfdata}->threshold_check(value => $timeoutcount, threshold => [ { label => 'crit_timeoutcount', exit_litteral => 'critical' }, + { label => 'warn_timeoutcount', exit_litteral => 'warning' } ]); + $self->{output}->output_add(severity => $exit, short_msg => sprintf("TimedOutCount: %d", $timeoutcount)); + + $self->{output}->output_add(severity => "ok", short_msg => sprintf("CommittedCount: %d", $committedcount)); + $self->{output}->output_add(severity => "ok", short_msg => sprintf("RolledbackCount: %d", $rolledbackcount)); + $self->{output}->output_add(severity => "ok", short_msg => sprintf("TransactionCount: %d", $transactioncount)); + $self->{output}->output_add(severity => "ok", short_msg => sprintf("TotalTransactionTime: %dms", $totaltransactiontime)); + $self->{output}->output_add(severity => "ok", short_msg => sprintf("MaxTransactionTime: %dms", $maxtransactiontime)); + $self->{output}->output_add(severity => "ok", short_msg => sprintf("DefaultTimeout: %ds", $defaulttimeout)); + + + $self->{output}->perfdata_add(label => "ActiveCount", unit => '', + value => sprintf("%d", $activecount), + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warn_activecount'), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'crit_activecount'), + ); + $self->{output}->perfdata_add(label => "TimedOutCount", unit => '', + value => sprintf("%d", $timeoutcount), + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warn_timeoutcount'), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'crit_timeoutcount'), + ); + $self->{output}->perfdata_add(label => "c[CommittedCount]", unit => '', + value => sprintf("%d", $committedcount), + ); + $self->{output}->perfdata_add(label => "c[RolledbackCount]", unit => '', + value => sprintf("%d", $rolledbackcount), + ); + $self->{output}->perfdata_add(label => "c[TransactionCount]", unit => '', + value => sprintf("%d", $transactioncount), + ); + $self->{output}->perfdata_add(label => "c[TotalTransactionTime]", unit => 'ms', + value => sprintf("%d", $totaltransactiontime), + ); + $self->{output}->perfdata_add(label => "MaxTransactionTime", unit => 'ms', + value => sprintf("%d", $maxtransactiontime), + ); + $self->{output}->perfdata_add(label => "DefaultTimeout", unit => 's', + value => sprintf("%d", $defaulttimeout), + ); + + $self->{output}->display(); + $self->{output}->exit(); +} + +1; + +__END__ + +=head1 MODE + +Check EAS application EJB transaction status. + +=over 8 + +=item B<--urlpath> + +Set path to get status page. (Default: '/easportal/tools/nagios/checktransaction.jsp') + +=item B<--warning> + +Warning Threshold for (activecount,timeoutcount). for example : --warning=100,1 + +=item B<--critical> + +Critical Threshold for (activecount,timeoutcount). for example : --critical=100,1 + +=back + +=cut diff --git a/centreon-plugins/apps/kingdee/eas/plugin.pm b/centreon-plugins/apps/kingdee/eas/plugin.pm new file mode 100644 index 000000000..ce1fe69c4 --- /dev/null +++ b/centreon-plugins/apps/kingdee/eas/plugin.pm @@ -0,0 +1,66 @@ +# +# Copyright 2017 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::kingdee::eas::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; + + $self->{version} = '1.0'; + %{$self->{modes}} = ( + 'classloading' => 'apps::kingdee::eas::mode::classloading', + 'memory' => 'apps::kingdee::eas::mode::memory', + 'javaruntime' => 'apps::kingdee::eas::mode::javaruntime', + 'datasource' => 'apps::kingdee::eas::mode::datasource', + 'httphandler' => 'apps::kingdee::eas::mode::httphandler', + 'muxhandler' => 'apps::kingdee::eas::mode::muxhandler', + 'transaction' => 'apps::kingdee::eas::mode::transaction', + 'oraclejvmgc' => 'apps::kingdee::eas::mode::oraclejvmgc', + 'ibmjvmgc' => 'apps::kingdee::eas::mode::ibmjvmgc', + 'ormrpc' => 'apps::kingdee::eas::mode::ormrpc', + 'easlicense' => 'apps::kingdee::eas::mode::easlicense', + 'activeusers' => 'apps::kingdee::eas::mode::activeusers', + 'oracleversion' => 'apps::kingdee::eas::mode::oracleversion', + 'oraclesession' => 'apps::kingdee::eas::mode::oraclesession', + 'oracletable' => 'apps::kingdee::eas::mode::oracletable', + 'oraclerecyclebin' => 'apps::kingdee::eas::mode::oraclerecyclebin', + 'oracleksqltemptable' => 'apps::kingdee::eas::mode::oracleksqltemptable', + 'oracleredolog' => 'apps::kingdee::eas::mode::oracleredolog', + ); + + $self->{custom_modes}{api} = 'apps::kingdee::eas::custom::api'; + return $self; +} + +1; + +__END__ + +=head1 PLUGIN DESCRIPTION + +Check Kingdee EAS Application & DB Server Status . + +=cut diff --git a/centreon-plugins/apps/nsclient/restapi/mode/query.pm b/centreon-plugins/apps/nsclient/restapi/mode/query.pm new file mode 100644 index 000000000..97388e281 --- /dev/null +++ b/centreon-plugins/apps/nsclient/restapi/mode/query.pm @@ -0,0 +1,249 @@ +# +# Copyright 2017 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::nsclient::restapi::mode::query; + +use base qw(centreon::plugins::mode); + +use strict; +use warnings; +use centreon::plugins::http; +use JSON; +use URI::Encode; + +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 => + { + "hostname:s" => { name => 'hostname' }, + "http-peer-addr:s" => { name => 'http_peer_addr' }, + "port:s" => { name => 'port', default => 8443 }, + "proto:s" => { name => 'proto', default => 'https' }, + "credentials" => { name => 'credentials' }, + "username:s" => { name => 'username' }, + "password:s" => { name => 'password' }, + "legacy-password:s" => { name => 'legacy_password' }, + "proxyurl:s" => { name => 'proxyurl' }, + "proxypac:s" => { name => 'proxypac' }, + "timeout:s" => { name => 'timeout' }, + "ssl-opt:s@" => { name => 'ssl_opt' }, + "ssl:s" => { name => 'ssl' }, + "command:s" => { name => 'command' }, + "arg:s@" => { name => 'arg' }, + "unknown-status:s" => { name => 'unknown_status', default => '%{http_code} < 200 or %{http_code} >= 300' }, + "warning-status:s" => { name => 'warning_status' }, + "critical-status:s" => { name => 'critical_status', default => '' }, + }); + + $self->{http} = centreon::plugins::http->new(output => $self->{output}); + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::init(%options); + + if (!defined($self->{option_results}->{command}) || $self->{option_results}->{command} eq '') { + $self->{output}->add_option_msg(short_msg => "Please set command option"); + $self->{output}->option_exit(); + } + if (defined($self->{option_results}->{legacy_password}) && $self->{option_results}->{legacy_password} ne '') { + $self->{http}->add_header(key => 'password', value => $self->{option_results}->{legacy_password}); + } + $self->{http}->set_options(%{$self->{option_results}}); +} + +# Two kind of outputs. +# 1- +# {"header":{"source_id":""},"payload":[{"command":"check_centreon_plugins","lines":[{"message":"OK: Reboot Pending : False | 'value1'=10;;;; 'value2'=10;;;;\r\nlong1\r\nlong2"}],"result":"OK"}]} +# 2- Can be also "int_value". +# { "header":{"source_id":""}, +# "payload": [ +# {"command":"check_drivesize", +# "lines": [ +# {"message":"OK All 1 drive(s) are ok", +# "perf":[ +# {"alias":"C:\\ used", +# "float_value": { +# "critical":44.690621566027403, +# "maximum":49.656246185302734, +# "minimum":0.00000000000000000, +# "unit":"GB", +# "value":21.684593200683594, +# "warning":39.724996947683394} +# }, +# {"alias":"C:\\ used %","float_value":{"critical":90.000000000000000,"maximum":100.00000000000000,"minimum":0.00000000000000000,"unit":"%","value":44.000000000000000,"warning":80.000000000000000}}]}], +# "result":"OK"}]} + +sub nscp_output_perf { + my ($self, %options) = @_; + + $self->{output}->output_add(severity => $options{result}, + short_msg => $options{data}->{message}); + foreach (@{$options{data}->{perf}}) { + my $perf = defined($_->{float_value}) ? $_->{float_value} : $_->{int_value}; + my $printf_format = '%d'; + $printf_format = '%.3f' if (defined($_->{float_value})); + + $self->{output}->perfdata_add(label => $_->{alias}, unit => $perf->{unit}, + value => sprintf($printf_format, $perf->{value}), + warning => defined($perf->{warning}) ? sprintf($printf_format, $perf->{warning}) : undef, + critical => defined($perf->{critical}) ? sprintf($printf_format, $perf->{critical}) : undef, + min => defined($perf->{minimum}) ? sprintf($printf_format, $perf->{minimum}) : undef, + max => defined($perf->{maximum}) ? sprintf($printf_format, $perf->{maximum}) : undef, + ); + } +} + +sub nscp_output_noperf { + my ($self, %options) = @_; + + $self->{output}->output_add(severity => $options{result}, + short_msg => $options{data}->{message}); +} + +sub check_nscp_result { + my ($self, %options) = @_; + + my $decoded; + eval { + $decoded = decode_json($options{content}); + }; + if ($@) { + $self->{output}->add_option_msg(short_msg => "Cannot decode json response: $@"); + $self->{output}->option_exit(); + } + + my $entry = $decoded->{payload}->[0]; + $entry->{lines}->[0]->{message} =~ s/\r//msg; + if (defined($entry->{lines}->[0]->{perf})) { + $self->nscp_output_perf(result => $entry->{result}, data => $entry->{lines}->[0]); + $self->{output}->display(nolabel => 1); + } else { + $self->nscp_output_noperf(result => $entry->{result}, data => $entry->{lines}->[0]); + $self->{output}->display(nolabel => 1, force_ignore_perfdata => 1, force_long_output => 1); + } +} + +sub run { + my ($self, %options) = @_; + + my $uri = URI::Encode->new({encode_reserved => 1}); + my ($encoded_args, $append) = ('', ''); + if (defined($self->{option_results}->{arg})) { + foreach (@{$self->{option_results}->{arg}}) { + $encoded_args .= $append . $uri->encode($_); + $append = '&'; + } + } + + my ($content) = $self->{http}->request(url_path => '/query/' . $self->{option_results}->{command} . '?' . $encoded_args); + $self->{output}->output_add(long_msg => "nsclient return = " . $content, debug => 1); + $self->check_nscp_result(content => $content); + + $self->{output}->exit(); +} + +1; + +__END__ + +=head1 MODE + +Query NSClient Rest API. + +=over 8 + +=item B<--hostname> + +IP Addr/FQDN of the host + +=item B<--http-peer-addr> + +Set the address you want to connect (Useful if hostname is only a vhost. no ip resolve) + +=item B<--port> + +Port used (Default: 8443) + +=item B<--proto> + +Specify https if needed (Default: 'https') + +=item B<--credentials> + +Specify this option if you access webpage over basic authentification + +=item B<--username> + +Specify username for basic authentification (Mandatory if --credentials is specidied) + +=item B<--password> + +Specify password for basic authentification (Mandatory if --credentials is specidied) + +=item B<--legacy-password> + +Specify password for old authentification system. + +=item B<--proxyurl> + +Proxy URL + +=item B<--proxypac> + +Proxy pac file (can be an url or local file) + +=item B<--timeout> + +Threshold for HTTP timeout (Default: 5) + +=item B<--ssl-opt> + +Set SSL Options (--ssl-opt="SSL_version => TLSv1" --ssl-opt="SSL_verify_mode => SSL_VERIFY_NONE"). + +=item B<--command> + +Set command. + +=item B<--arg> + +Set arguments (Multiple option. Example: --arg='arg1') + +=item B<--unknown-status> + +Threshold warning for http response code. +(Default: '%{http_code} < 200 or %{http_code} >= 300') + +=item B<--warning-status> + +Threshold warning for http response code. + +=item B<--critical-status> + +Threshold critical for http response code. + +=back + +=cut diff --git a/centreon-plugins/cloud/aws/mode/metrics/ec2instancecpu.pm b/centreon-plugins/apps/nsclient/restapi/plugin.pm similarity index 57% rename from centreon-plugins/cloud/aws/mode/metrics/ec2instancecpu.pm rename to centreon-plugins/apps/nsclient/restapi/plugin.pm index 0fbd0276b..90a770dcc 100644 --- a/centreon-plugins/cloud/aws/mode/metrics/ec2instancecpu.pm +++ b/centreon-plugins/apps/nsclient/restapi/plugin.pm @@ -18,34 +18,31 @@ # limitations under the License. # -package cloud::aws::mode::metrics::ec2instancecpu; +package apps::nsclient::restapi::plugin; use strict; use warnings; -use Exporter; -our @ISA = qw(Exporter); -our @EXPORT = qw(&cloudwatchCheck); +use base qw(centreon::plugins::script_simple); -my @Param; +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; -$Param[0] = { - 'NameSpace' => 'AWS/EC2', - 'MetricName' => 'CPUUtilization', - 'ObjectName' => 'InstanceId', - 'Unit' => 'Percent', - 'Labels' => { - 'ShortOutput' => "CPU Usage is %.2f%%", - 'LongOutput' => "CPU Usage is %.2f%%", - 'PerfData' => 'cpu', - 'Unit' => '%', - 'Value' => "%.2f", - } -}; + $self->{version} = '0.1'; + %{$self->{modes}} = ( + 'query' => 'apps::nsclient::restapi::mode::query', + ); -sub cloudwatchCheck { - my ($self) = @_; - - @{ $self->{metric} } = @Param; + return $self; } 1; + +__END__ + +=head1 PLUGIN DESCRIPTION + +Check nsclient Rest API. + +=cut diff --git a/centreon-plugins/apps/pacemaker/local/mode/clustat.pm b/centreon-plugins/apps/pacemaker/local/mode/clustat.pm index b26984e79..2b092c11d 100644 --- a/centreon-plugins/apps/pacemaker/local/mode/clustat.pm +++ b/centreon-plugins/apps/pacemaker/local/mode/clustat.pm @@ -1,5 +1,5 @@ # -# Copyright 2016 Centreon (http://www.centreon.com/) +# Copyright 2017 Centreon (http://www.centreon.com/) # # Centreon is a full-fledged industry-strength solution that meets # the needs in IT infrastructure and application monitoring for diff --git a/centreon-plugins/apps/protocols/http/mode/expectedcontent.pm b/centreon-plugins/apps/protocols/http/mode/expectedcontent.pm index a573f75df..610eb8449 100644 --- a/centreon-plugins/apps/protocols/http/mode/expectedcontent.pm +++ b/centreon-plugins/apps/protocols/http/mode/expectedcontent.pm @@ -51,6 +51,7 @@ sub new { "timeout:s" => { name => 'timeout' }, "no-follow" => { name => 'no_follow', }, "ssl:s" => { name => 'ssl', }, + "ssl-opt:s@" => { name => 'ssl_opt' }, "cert-file:s" => { name => 'cert_file' }, "key-file:s" => { name => 'key_file' }, "cacert-file:s" => { name => 'cacert_file' }, @@ -216,9 +217,9 @@ Threshold for HTTP timeout (Default: 5) Do not follow http redirect -=item B<--ssl> +=item B<--ssl-opt> -Specify SSL version (example : 'sslv3', 'tlsv1'...) +Set SSL Options (--ssl-opt="SSL_version => TLSv1" --ssl-opt="SSL_verify_mode => SSL_VERIFY_NONE"). =item B<--cert-file> diff --git a/centreon-plugins/apps/protocols/http/mode/jsoncontent.pm b/centreon-plugins/apps/protocols/http/mode/jsoncontent.pm index b9354c1e3..88f70d817 100644 --- a/centreon-plugins/apps/protocols/http/mode/jsoncontent.pm +++ b/centreon-plugins/apps/protocols/http/mode/jsoncontent.pm @@ -54,6 +54,7 @@ sub new { "header:s@" => { name => 'header' }, "get-param:s@" => { name => 'get_param' }, "timeout:s" => { name => 'timeout', default => 10 }, + "ssl-opt:s@" => { name => 'ssl_opt' }, "ssl:s" => { name => 'ssl', }, "cert-file:s" => { name => 'cert_file' }, "key-file:s" => { name => 'key_file' }, @@ -409,9 +410,9 @@ Specify password for basic authentification (Mandatory if --credentials is speci Threshold for HTTP timeout (Default: 10) -=item B<--ssl> +=item B<--ssl-opt> -Specify SSL version (example : 'sslv3', 'tlsv1'...) +Set SSL Options (--ssl-opt="SSL_version => TLSv1" --ssl-opt="SSL_verify_mode => SSL_VERIFY_NONE"). =item B<--cert-file> diff --git a/centreon-plugins/apps/protocols/http/mode/response.pm b/centreon-plugins/apps/protocols/http/mode/response.pm index 16f2ea2f3..fb0f8fe77 100644 --- a/centreon-plugins/apps/protocols/http/mode/response.pm +++ b/centreon-plugins/apps/protocols/http/mode/response.pm @@ -49,7 +49,8 @@ sub new { "proxypac:s" => { name => 'proxypac' }, "timeout:s" => { name => 'timeout' }, "no-follow" => { name => 'no_follow', }, - "ssl:s" => { name => 'ssl' }, + "ssl:s" => { name => 'ssl' }, + "ssl-opt:s@" => { name => 'ssl_opt' }, "cert-file:s" => { name => 'cert_file' }, "key-file:s" => { name => 'key_file' }, "cacert-file:s" => { name => 'cacert_file' }, @@ -202,9 +203,9 @@ Threshold for HTTP timeout (Default: 5) Do not follow http redirect -=item B<--ssl> +=item B<--ssl-opt> -Specify SSL version (example : 'sslv3', 'tlsv1'...) +Set SSL Options (--ssl-opt="SSL_version => TLSv1" --ssl-opt="SSL_verify_mode => SSL_VERIFY_NONE"). =item B<--cert-file> diff --git a/centreon-plugins/apps/protocols/http/mode/soapcontent.pm b/centreon-plugins/apps/protocols/http/mode/soapcontent.pm index 01ebd87f0..b10cfb79a 100644 --- a/centreon-plugins/apps/protocols/http/mode/soapcontent.pm +++ b/centreon-plugins/apps/protocols/http/mode/soapcontent.pm @@ -53,6 +53,7 @@ sub new { "proxypac:s" => { name => 'proxypac' }, "header:s@" => { name => 'header' }, "timeout:s" => { name => 'timeout', default => 10 }, + "ssl-opt:s@" => { name => 'ssl_opt' }, "ssl:s" => { name => 'ssl', }, "cert-file:s" => { name => 'cert_file' }, "key-file:s" => { name => 'key_file' }, @@ -436,9 +437,9 @@ Specify password for basic authentification (Mandatory if --credentials is speci Threshold for HTTP timeout (Default: 10) -=item B<--ssl> +=item B<--ssl-opt> -Specify SSL version (example : 'sslv3', 'tlsv1'...) +Set SSL Options (--ssl-opt="SSL_version => TLSv1" --ssl-opt="SSL_verify_mode => SSL_VERIFY_NONE"). =item B<--cert-file> diff --git a/centreon-plugins/apps/protocols/jmx/mode/numericvalue.pm b/centreon-plugins/apps/protocols/jmx/mode/numericvalue.pm index 45f1e3ffb..9e48b2c8f 100644 --- a/centreon-plugins/apps/protocols/jmx/mode/numericvalue.pm +++ b/centreon-plugins/apps/protocols/jmx/mode/numericvalue.pm @@ -142,7 +142,7 @@ sub check_value { if ($self->{attributes}->{type} =~ /^counter$/i) { if (!defined($self->{datas})) { $self->{datas} = {}; - $self->{statefile_cache}->read(statefile => "jmxstandard_" . $self->{mode} . '_' . md5_hex($self->{connector}->{url} . ' ' . $self->{option_results}->{mbean_pattern})); + $self->{statefile_cache}->read(statefile => "jmxstandard_" . $self->{mode} . '_' . md5_hex($self->{connector}->get_connection_info() . ' ' . $self->{option_results}->{mbean_pattern})); } my $old_timestamp = $self->{statefile_cache}->get(name => 'timestamp'); diff --git a/centreon-plugins/apps/protocols/modbus/mode/numericvalue.pm b/centreon-plugins/apps/protocols/modbus/mode/numericvalue.pm index c8c50a5a7..db895021f 100644 --- a/centreon-plugins/apps/protocols/modbus/mode/numericvalue.pm +++ b/centreon-plugins/apps/protocols/modbus/mode/numericvalue.pm @@ -1,5 +1,5 @@ # -# Copyright 2016 Centreon (http://www.centreon.com/) +# Copyright 2017 Centreon (http://www.centreon.com/) # # Centreon is a full-fledged industry-strength solution that meets # the needs in IT infrastructure and application monitoring for diff --git a/centreon-plugins/snmp_standard/plugin.pm b/centreon-plugins/apps/protocols/snmp/plugin.pm similarity index 69% rename from centreon-plugins/snmp_standard/plugin.pm rename to centreon-plugins/apps/protocols/snmp/plugin.pm index 2438cdf33..1e6460ab3 100644 --- a/centreon-plugins/snmp_standard/plugin.pm +++ b/centreon-plugins/apps/protocols/snmp/plugin.pm @@ -18,7 +18,7 @@ # limitations under the License. # -package snmp_standard::plugin; +package apps::protocols::snmp::plugin; use strict; use warnings; @@ -31,11 +31,11 @@ sub new { $self->{version} = '0.1'; %{$self->{modes}} = ( - 'numeric-value' => 'snmp_standard::mode::numericvalue', - 'string-value' => 'snmp_standard::mode::stringvalue', - 'dynamic-command' => 'snmp_standard::mode::dynamiccommand', - 'uptime' => 'snmp_standard::mode::uptime', - ); + 'dynamic-command' => 'snmp_standard::mode::dynamiccommand', + 'numeric-value' => 'snmp_standard::mode::numericvalue', + 'string-value' => 'snmp_standard::mode::stringvalue', + 'uptime' => 'snmp_standard::mode::uptime', + ); return $self; } @@ -46,6 +46,6 @@ __END__ =head1 PLUGIN DESCRIPTION -Check SNMP values (string, numeric or execute commands) or standard (uptime). +Check SNMP values (string, numeric or execute commands). =cut diff --git a/centreon-plugins/apps/redis/cli/custom/rediscli.pm b/centreon-plugins/apps/redis/cli/custom/rediscli.pm new file mode 100644 index 000000000..d3226c96c --- /dev/null +++ b/centreon-plugins/apps/redis/cli/custom/rediscli.pm @@ -0,0 +1,158 @@ +# +# Copyright 2017 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::redis::cli::custom::rediscli; + +use strict; +use warnings; +use Redis; + +sub new { + my ($class, %options) = @_; + my $self = {}; + bless $self, $class; + + 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' }, + "port:s" => { name => 'port' }, + "password:s" => { name => 'password' }, + }); + } + $options{options}->add_help(package => __PACKAGE__, sections => 'REDIS CLI OPTIONS', once => 1); + + $self->{output} = $options{output}; + $self->{mode} = $options{mode}; + + return $self; +} + +sub set_options { + my ($self, %options) = @_; + + $self->{option_results} = $options{option_results}; +} + +sub set_defaults { + my ($self, %options) = @_; + + 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) = @_; + + $self->{hostname} = $self->{option_results}->{hostname}; + $self->{port} = $self->{option_results}->{port}; + $self->{password} = $self->{option_results}->{password}; + + if (!defined($self->{hostname})) { + $self->{output}->add_option_msg(short_msg => "Need to specify hostname argument."); + $self->{output}->option_exit(); + } + if (!defined($self->{port})) { + $self->{output}->add_option_msg(short_msg => "Need to specify port argument."); + $self->{output}->option_exit(); + } + + return 0; +} + +sub get_connection_info { + my ($self, %options) = @_; + + return $self->{hostname} . ":" . $self->{port}; +} + +sub get_info { + my ($self, %options) = @_; + + $self->{redis} = Redis->new(server => $self->{hostname} . ":" . $self->{port}); + if (defined($self->{password})) { + $self->{redis}->auth($self->{password}); + } + + my $response = $self->{redis}->info; + my $items; + foreach my $attributes (keys %{$response}) { + $items->{$attributes} = $response->{$attributes}; + } + + $self->{redis}->quit(); + + return $items; +} + +1; + +__END__ + +=head1 NAME + +REDIS CLI + +=head1 SYNOPSIS + +Redis Cli custom mode + +=head1 REDIS CLI OPTIONS + +=over 8 + +=item B<--hostname> + +Redis hostname. + +=item B<--port> + +Redis port. + +=item B<--password> + +Redis password + +=back + +=head1 DESCRIPTION + +B. + +=cut diff --git a/centreon-plugins/apps/redis/cli/mode/clients.pm b/centreon-plugins/apps/redis/cli/mode/clients.pm new file mode 100644 index 000000000..21a4cd312 --- /dev/null +++ b/centreon-plugins/apps/redis/cli/mode/clients.pm @@ -0,0 +1,141 @@ +# +# Copyright 2017 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::redis::cli::mode::clients; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'global', type => 0 }, + ]; + + $self->{maps_counters}->{global} = [ + { label => 'connected-clients', set => { + key_values => [ { name => 'connected_clients' } ], + output_template => 'Connected clients: %s', + perfdatas => [ + { label => 'connected_clients', value => 'connected_clients_absolute', template => '%s', min => 0 }, + ], + }, + }, + { label => 'blocked-clients', set => { + key_values => [ { name => 'blocked_clients' } ], + output_template => 'Blocked clients: %s', + perfdatas => [ + { label => 'blocked_clients', value => 'blocked_clients_absolute', template => '%s', min => 0 }, + ], + }, + }, + { label => 'client-longest-output-list', set => { + key_values => [ { name => 'client_longest_output_list' } ], + output_template => 'Client longest output list: %s', + perfdatas => [ + { label => 'client_longest_output_list', value => 'client_longest_output_list_absolute', template => '%s', min => 0 }, + ], + }, + }, + { label => 'client-biggest-input-buf', set => { + key_values => [ { name => 'client_biggest_input_buf' } ], + output_template => 'Client biggest input buffer: %s', + perfdatas => [ + { label => 'client_biggest_input_buf', value => 'client_biggest_input_buf_absolute', template => '%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 => + { + }); + + return $self; +} + +sub manage_selection { + my ($self, %options) = @_; + + my $results = $options{custom}->get_info(); + $self->{global} = { + connected_clients => $results->{connected_clients}, + blocked_clients => $results->{blocked_clients}, + client_longest_output_list => $results->{client_longest_output_list}, + client_biggest_input_buf => $results->{client_biggest_input_buf}, + }; +} + +1; + +__END__ + +=head1 MODE + +Check number of connected and blocked clients + +=over 8 + +=item B<--warning-connected-clients> + +Warning threshold for number of connected clients + +=item B<--critical-connected-clients> + +Critical threshold for number of connected clients + +=item B<--warning-blocked-clients> + +Warning threshold for number of blocked clients + +=item B<--critical-blocked-clients> + +Critical threshold for number of blocked clients + +=item B<--warning-client-longest-output-list> + +Warning threshold for longest output list among current client connections + +=item B<--critical-client-longest-output-list> + +Critical threshold for longest output list among current client connections + +=item B<--warning-client-biggest-input-buf> + +Warning threshold for biggest input buffer among current client connections + +=item B<--critical-client-biggest-input-buf> + +Critical threshold for biggest input buffer among current client connections + +=back + +=cut diff --git a/centreon-plugins/apps/redis/cli/mode/commands.pm b/centreon-plugins/apps/redis/cli/mode/commands.pm new file mode 100644 index 000000000..0ceeab764 --- /dev/null +++ b/centreon-plugins/apps/redis/cli/mode/commands.pm @@ -0,0 +1,117 @@ +# +# Copyright 2017 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::redis::cli::mode::commands; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; +use Digest::MD5 qw(md5_hex); + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'global', type => 0, cb_prefix_output => 'prefix_output' }, + ]; + + $self->{maps_counters}->{global} = [ + { label => 'processed-commands', set => { + key_values => [ { name => 'total_commands_processed', diff => 1 } ], + output_template => 'Processed: %s', + perfdatas => [ + { label => 'processed_commands', value => 'total_commands_processed_absolute', template => '%s', min => 0 }, + ], + }, + }, + { label => 'ops-per-sec', set => { + key_values => [ { name => 'instantaneous_ops_per_sec' } ], + output_template => 'Processed per sec: %s', + perfdatas => [ + { label => 'ops_per_sec', value => 'instantaneous_ops_per_sec_absolute', template => '%s', min => 0, unit => 'ops/s' }, + ], + }, + }, + ]; +} + +sub prefix_output { + my ($self, %options) = @_; + + return "Number of commands: "; +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options, statefile => 1); + bless $self, $class; + + $self->{version} = '1.0'; + + $options{options}->add_options(arguments => + { + }); + + return $self; +} + +sub manage_selection { + my ($self, %options) = @_; + + $self->{cache_name} = "redis_" . $self->{mode} . '_' . $options{custom}->get_connection_info() . '_' . + (defined($self->{option_results}->{filter_counters}) ? md5_hex($self->{option_results}->{filter_counters}) : md5_hex('all')); + + my $results = $options{custom}->get_info(); + $self->{global} = { + total_commands_processed => $results->{total_commands_processed}, + instantaneous_ops_per_sec => $results->{instantaneous_ops_per_sec}, + }; +} + +1; + +__END__ + +=head1 MODE + +Check commands number + +=over 8 + +=item B<--warning-processed-commands> + +Warning threshold for number of commands processed by the server + +=item B<--critical-processed-commands> + +Critical threshold for number of commands processed by the server + +=item B<--warning-ops-per-sec> + +Warning threshold for number of commands processed per second + +=item B<--critical-ops-per-sec> + +Critical threshold for number of commands processed per second + +=back + +=cut diff --git a/centreon-plugins/apps/redis/cli/mode/connections.pm b/centreon-plugins/apps/redis/cli/mode/connections.pm new file mode 100644 index 000000000..40032ba64 --- /dev/null +++ b/centreon-plugins/apps/redis/cli/mode/connections.pm @@ -0,0 +1,167 @@ +# +# Copyright 2017 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::redis::cli::mode::connections; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; +use Digest::MD5 qw(md5_hex); + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'connections', type => 0, cb_prefix_output => 'prefix_connections_output' }, + { name => 'traffic', type => 0, cb_prefix_output => 'prefix_traffic_output' }, + ]; + + $self->{maps_counters}->{connections} = [ + { label => 'received-connections', set => { + key_values => [ { name => 'total_connections_received', diff => 1 } ], + output_template => 'Received: %s', + perfdatas => [ + { label => 'received_connections', value => 'total_connections_received_absolute', template => '%s', min => 0 }, + ], + }, + }, + { label => 'rejected-connections', set => { + key_values => [ { name => 'rejected_connections', diff => 1 } ], + output_template => 'Rejected: %s', + perfdatas => [ + { label => 'rejected_connections', value => 'rejected_connections_absolute', template => '%s', min => 0 }, + ], + }, + }, + ]; + + $self->{maps_counters}->{traffic} = [ + { label => 'traffic-in', set => { + key_values => [ { name => 'total_net_input_bytes', diff => 1 } ], + output_template => 'Traffic In: %s %s/s', + per_second => 1, output_change_bytes => 2, + perfdatas => [ + { label => 'traffic_in', value => 'total_net_input_bytes_per_second', template => '%d', min => 0, unit => 'b/s' }, + ], + }, + }, + { label => 'traffic-out', set => { + key_values => [ { name => 'total_net_output_bytes', diff => 1 } ], + output_template => 'Traffic Out: %s %s/s', + per_second => 1, output_change_bytes => 2, + perfdatas => [ + { label => 'traffic_out', value => 'total_net_output_bytes_per_second', template => '%d', min => 0, unit => 'b/s' }, + ], + }, + }, + ]; +} + +sub prefix_connections_output { + my ($self, %options) = @_; + + return "Number of connections: "; +} + +sub prefix_traffic_output { + my ($self, %options) = @_; + + return "Network usage: "; +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options, statefile => 1); + bless $self, $class; + + $self->{version} = '1.0'; + + $options{options}->add_options(arguments => + { + }); + + return $self; +} + +sub manage_selection { + my ($self, %options) = @_; + + $self->{cache_name} = "redis_" . $self->{mode} . '_' . $options{custom}->get_connection_info() . '_' . + (defined($self->{option_results}->{filter_counters}) ? md5_hex($self->{option_results}->{filter_counters}) : md5_hex('all')); + + my $results = $options{custom}->get_info(); + + $self->{connections} = { + total_connections_received => $results->{total_connections_received}, + rejected_connections => $results->{rejected_connections}, + }; + + $self->{traffic} = { + total_net_input_bytes => $results->{total_net_input_bytes} * 8, + total_net_output_bytes => $results->{total_net_output_bytes} * 8, + }; +} + +1; + +__END__ + +=head1 MODE + +Check connections number and network usage + +=over 8 + +=item B<--warning-received-connections> + +Warning threshold for received connections + +=item B<--critical-received-connections> + +Critical threshold for received connections + +=item B<--warning-rejected-connections> + +Warning threshold for rejected connections + +=item B<--critical-rejected-connections> + +Critical threshold for rejected connections + +=item B<--warning-traffic-in> + +Warning threshold for inbound traffic (b/s) + +=item B<--critical-traffic-in> + +Critical threshold for inbound traffic (b/s) + +=item B<--warning-traffic-out> + +Warning threshold for outbound traffic (b/s) + +=item B<--critical-traffic-out> + +Critical thresholdfor outbound traffic (b/s) + +=back + +=cut diff --git a/centreon-plugins/apps/redis/cli/mode/cpu.pm b/centreon-plugins/apps/redis/cli/mode/cpu.pm new file mode 100644 index 000000000..8317d9527 --- /dev/null +++ b/centreon-plugins/apps/redis/cli/mode/cpu.pm @@ -0,0 +1,169 @@ +# +# Copyright 2017 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::redis::cli::mode::cpu; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; +use Digest::MD5 qw(md5_hex); + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'global', type => 0, cb_prefix_output => 'prefix_output' } + ]; + + $self->{maps_counters}->{global} = [ + { label => 'sys', set => { + key_values => [ { name => 'used_cpu_sys', diff => 1 } ], + closure_custom_calc => $self->can('custom_usage_calc'), closure_custom_calc_extra_options => { label_ref => 'used_cpu_sys' }, + output_template => 'System: %.2f %%', output_use => 'used_delta', threshold_use => 'used_delta', + per_second => 1, + perfdatas => [ + { label => 'sys', value => 'used_delta', template => '%.2f', min => 0, max => 100, unit => '%' }, + ], + } + }, + { label => 'user', set => { + key_values => [ { name => 'used_cpu_user', diff => 1 } ], + closure_custom_calc => $self->can('custom_usage_calc'), closure_custom_calc_extra_options => { label_ref => 'used_cpu_user' }, + output_template => 'User: %.2f %%', output_use => 'used_delta', threshold_use => 'used_delta', + per_second => 1, + perfdatas => [ + { label => 'user', value => 'used_delta', template => '%.2f', min => 0, max => 100, unit => '%' }, + ], + } + }, + { label => 'sys-children', set => { + key_values => [ { name => 'used_cpu_sys_children', diff => 1 } ], + closure_custom_calc => $self->can('custom_usage_calc'), closure_custom_calc_extra_options => { label_ref => 'used_cpu_sys_children' }, + output_template => 'System children: %.2f %%', output_use => 'used_delta', threshold_use => 'used_delta', + per_second => 1, + perfdatas => [ + { label => 'sys_children', value => 'used_delta', template => '%.2f', min => 0, max => 100, unit => '%' }, + ], + } + }, + { label => 'user-children', set => { + key_values => [ { name => 'used_cpu_user_children', diff => 1 } ], + closure_custom_calc => $self->can('custom_usage_calc'), closure_custom_calc_extra_options => { label_ref => 'used_cpu_user_children' }, + output_template => 'User children: %.2f %%', output_use => 'used_delta', threshold_use => 'used_delta', + per_second => 1, + perfdatas => [ + { label => 'user_children', value => 'used_delta', template => '%.2f', min => 0, max => 100, unit => '%' }, + ], + } + }, + ]; +} + +sub prefix_output { + my ($self, %options) = @_; + + return "CPU usage: "; +} + +sub custom_usage_calc { + my ($self, %options) = @_; + + my $delta_total = $options{new_datas}->{$self->{instance} . '_' . $options{extra_options}->{label_ref}} - $options{old_datas}->{$self->{instance} . '_' . $options{extra_options}->{label_ref}}; + $self->{result_values}->{used_delta} = 100 * $delta_total / $options{delta_time}; + + return 0; +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options, statefile => 1); + bless $self, $class; + + $self->{version} = '1.0'; + + $options{options}->add_options(arguments => + { + }); + + return $self; +} + +sub manage_selection { + my ($self, %options) = @_; + + $self->{cache_name} = "redis_" . $self->{mode} . '_' . $options{custom}->get_connection_info() . '_' . + (defined($self->{option_results}->{filter_counters}) ? md5_hex($self->{option_results}->{filter_counters}) : md5_hex('all')); + + my $results = $options{custom}->get_info(); + + $self->{global} = { + used_cpu_sys => $results->{used_cpu_sys}, + used_cpu_user => $results->{used_cpu_user}, + used_cpu_sys_children => $results->{used_cpu_sys_children}, + used_cpu_user_children => $results->{used_cpu_user_children}, + }; +} + +1; + +__END__ + +=head1 MODE + +Check CPU utilization. + +=over 8 + +=item B<--warning-sys> + +Warning threshold for Sys CPU utilization + +=item B<--critical-sys> + +Critical threshold for Sys CPU utilization + +=item B<--warning-user> + +Warning threshold for User CPU utilization + +=item B<--critical-user> + +Critical threshold for User CPU utilization + +=item B<--warning-sys-children> + +Warning threshold for Sys Children CPU utilization + +=item B<--critical-sys-children> + +Critical threshold for Sys Children CPU utilization + +=item B<--warning-user-children> + +Warning threshold for User Children CPU utilization + +=item B<--critical-user-children> + +Critical threshold for User Children CPU utilization + +=back + +=cut diff --git a/centreon-plugins/apps/redis/cli/mode/memory.pm b/centreon-plugins/apps/redis/cli/mode/memory.pm new file mode 100644 index 000000000..6aef79436 --- /dev/null +++ b/centreon-plugins/apps/redis/cli/mode/memory.pm @@ -0,0 +1,356 @@ +# +# Copyright 2017 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::redis::cli::mode::memory; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; + +my $instance_mode; + +sub custom_usage_perfdata { + my ($self, %options) = @_; + + $self->{output}->perfdata_add(label => $self->{result_values}->{label}, unit => 'B', + value => $self->{result_values}->{used}, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{result_values}->{label}, total => $self->{result_values}->{total}, cast_int => 1), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{result_values}->{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, $threshold_value); + $threshold_value = $self->{result_values}->{used}; + $threshold_value = $self->{result_values}->{free} if (defined($instance_mode->{option_results}->{free})); + if ($instance_mode->{option_results}->{units} eq '%') { + $threshold_value = $self->{result_values}->{prct_used}; + $threshold_value = $self->{result_values}->{prct_free} if (defined($instance_mode->{option_results}->{free})); + } + $exit = $self->{perfdata}->threshold_check(value => $threshold_value, threshold => [ { label => 'critical-' . $self->{result_values}->{label}, exit_litteral => 'critical' }, { label => 'warning-' . $self->{result_values}->{label}, exit_litteral => 'warning' } ]); + return $exit; +} + +sub custom_usage_output { + my ($self, %options) = @_; + + my ($total_used_value, $total_used_unit) = $self->{perfdata}->change_bytes(value => $self->{result_values}->{used}); + + my $msg = sprintf($self->{result_values}->{display}.": %s (%.2f%%)", + $total_used_value . " " . $total_used_unit, $self->{result_values}->{prct_used}); + return $msg; +} + +sub custom_usage_calc { + my ($self, %options) = @_; + + $self->{result_values}->{display} = $options{new_datas}->{$self->{instance} . '_display'}; + $self->{result_values}->{label} = $options{new_datas}->{$self->{instance} . '_label'}; + $self->{result_values}->{used} = $options{new_datas}->{$self->{instance} . '_used'}; + $self->{result_values}->{total} = $options{new_datas}->{$self->{instance} . '_total'}; + $self->{result_values}->{free} = $self->{result_values}->{total} - $self->{result_values}->{used}; + $self->{result_values}->{prct_used} = $self->{result_values}->{used} * 100 / $self->{result_values}->{total}; + $self->{result_values}->{prct_free} = 100 - $self->{result_values}->{prct_used}; + + return 0; +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'used', type => 0 }, + { name => 'rss', type => 0, skipped_code => { -10 => 1 } }, + { name => 'peak', type => 0, skipped_code => { -10 => 1 } }, + { name => 'overhead', type => 0, skipped_code => { -10 => 1 } }, + { name => 'startup', type => 0, skipped_code => { -10 => 1 } }, + { name => 'dataset', type => 0, skipped_code => { -10 => 1 } }, + { name => 'lua', type => 0, skipped_code => { -10 => 1 } }, + { name => 'stats', type => 0, cb_prefix_output => 'prefix_stats_output', skipped_code => { -10 => 1 } }, + ]; + + $self->{maps_counters}->{used} = [ + { label => 'used', set => { + key_values => [ { name => 'display' }, { name => 'label' }, { name => 'used' }, { name => 'total' } ], + closure_custom_calc => $self->can('custom_usage_calc'), + closure_custom_output => $self->can('custom_usage_output'), + closure_custom_perfdata => $self->can('custom_usage_perfdata'), + closure_custom_threshold_check => $self->can('custom_usage_threshold'), + } + }, + ]; + + $self->{maps_counters}->{rss} = [ + { label => 'rss', set => { + key_values => [ { name => 'display' }, { name => 'label' }, { name => 'used' }, { name => 'total' } ], + closure_custom_calc => $self->can('custom_usage_calc'), + closure_custom_output => $self->can('custom_usage_output'), + closure_custom_perfdata => $self->can('custom_usage_perfdata'), + closure_custom_threshold_check => $self->can('custom_usage_threshold'), + } + }, + ]; + + $self->{maps_counters}->{peak} = [ + { label => 'peak', set => { + key_values => [ { name => 'display' }, { name => 'label' }, { name => 'used' }, { name => 'total' } ], + closure_custom_calc => $self->can('custom_usage_calc'), + closure_custom_output => $self->can('custom_usage_output'), + closure_custom_perfdata => $self->can('custom_usage_perfdata'), + closure_custom_threshold_check => $self->can('custom_usage_threshold'), + } + }, + ]; + + $self->{maps_counters}->{overhead} = [ + { label => 'overhead', set => { + key_values => [ { name => 'display' }, { name => 'label' }, { name => 'used' }, { name => 'total' } ], + closure_custom_calc => $self->can('custom_usage_calc'), + closure_custom_output => $self->can('custom_usage_output'), + closure_custom_perfdata => $self->can('custom_usage_perfdata'), + closure_custom_threshold_check => $self->can('custom_usage_threshold'), + } + }, + ]; + + $self->{maps_counters}->{startup} = [ + { label => 'startup', set => { + key_values => [ { name => 'display' }, { name => 'label' }, { name => 'used' }, { name => 'total' } ], + closure_custom_calc => $self->can('custom_usage_calc'), + closure_custom_output => $self->can('custom_usage_output'), + closure_custom_perfdata => $self->can('custom_usage_perfdata'), + closure_custom_threshold_check => $self->can('custom_usage_threshold'), + } + }, + ]; + + $self->{maps_counters}->{dataset} = [ + { label => 'dataset', set => { + key_values => [ { name => 'display' }, { name => 'label' }, { name => 'used' }, { name => 'total' } ], + closure_custom_calc => $self->can('custom_usage_calc'), + closure_custom_output => $self->can('custom_usage_output'), + closure_custom_perfdata => $self->can('custom_usage_perfdata'), + closure_custom_threshold_check => $self->can('custom_usage_threshold'), + } + }, + ]; + + $self->{maps_counters}->{lua} = [ + { label => 'lua', set => { + key_values => [ { name => 'display' }, { name => 'label' }, { name => 'used' }, { name => 'total' } ], + closure_custom_calc => $self->can('custom_usage_calc'), + closure_custom_output => $self->can('custom_usage_output'), + closure_custom_perfdata => $self->can('custom_usage_perfdata'), + closure_custom_threshold_check => $self->can('custom_usage_threshold'), + } + }, + ]; + + $self->{maps_counters}->{stats} = [ + { label => 'fragmentation-ratio', set => { + key_values => [ { name => 'mem_fragmentation_ratio' } ], + output_template => 'Fragmentation ratio: %s', + perfdatas => [ + { label => 'fragmentation_ratio', value => 'mem_fragmentation_ratio_absolute', template => '%s', min => 0 }, + ], + }, + }, + { label => 'defrag-running', set => { + key_values => [ { name => 'active_defrag_running' } ], + output_template => 'Defragmentation running: %s', + perfdatas => [ + { label => 'defrag_running', value => 'active_defrag_running_absolute', template => '%s', min => 0 }, + ], + }, + }, + { label => 'lazyfree-pending-objects', set => { + key_values => [ { name => 'lazyfree_pending_objects' } ], + output_template => 'Lazyfree pending objects: %s', + perfdatas => [ + { label => 'lazyfree_pending_objects', value => 'lazyfree_pending_objects_absolute', template => '%s', min => 0 }, + ], + }, + }, + ]; +} + +sub prefix_stats_output { + my ($self, %options) = @_; + + return "Statistics: "; +} + + +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 => + { + "units:s" => { name => 'units', default => '%' }, + "free" => { name => 'free' }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::check_options(%options); + + $instance_mode = $self; +} + +my $metrics = { + used_memory => { label => 'used', display => 'Used' }, + used_memory_rss => { label => 'rss', display => 'Rss' }, + used_memory_peak => { label => 'peak', display => 'Peak' }, + used_memory_overhead => { label => 'overhead', display => 'Overhead' }, + used_memory_startup => { label => 'startup', display => 'Startup' }, + used_memory_dataset => { label => 'dataset', display => 'Dataset' }, + used_memory_lua => { label => 'lua', display => 'Lua' }, +}; + +sub manage_selection { + my ($self, %options) = @_; + + my $results = $options{custom}->get_info(); + foreach my $type (keys %$metrics) { + next if (!defined($results->{$type})); + $self->{$metrics->{$type}->{label}} = { display => $metrics->{$type}->{display}, + label => $metrics->{$type}->{label}, + used => $results->{$type}, + total => $results->{total_system_memory} }; + } + + $self->{stats} = { + mem_fragmentation_ratio => $results->{mem_fragmentation_ratio}, + active_defrag_running => $results->{active_defrag_running}, + lazyfree_pending_objects => $results->{lazyfree_pending_objects}, + }; +} + +1; + +__END__ + +=head1 MODE + +Check memory utilization + +=over 8 + +=item B<--units> + +Units of thresholds (Default: '%') ('%', 'B'). + +=item B<--free> + +Thresholds are on free space left. + +=item B<--warning-used> + +Warning threshold for Used memory utilization + +=item B<--critical-used> + +Critical threshold for Used memory utilization + +=item B<--warning-rss> + +Warning threshold for Rss memory utilization + +=item B<--critical-rss> + +Critical threshold for Rss memory utilization + +=item B<--warning-peak> + +Warning threshold for Peak memory utilization + +=item B<--critical-peak> + +Critical threshold for Peak memory utilization + +=item B<--warning-overhead> + +Warning threshold for Overhead memory utilization + +=item B<--critical-overhead> + +Critical threshold for Overhead memory utilization + +=item B<--warning-startup> + +Warning threshold for Startup memory utilization + +=item B<--critical-startup> + +Critical threshold for Startup memory utilization + +=item B<--warning-dataset> + +Warning threshold for Dataset memory utilization + +=item B<--critical-dataset> + +Critical threshold for Dataset memory utilization + +=item B<--warning-lua> + +Warning threshold for Lua memory utilization + +=item B<--critical-lua> + +Critical threshold for Lua memory utilization + +=item B<--warning-fragmentation-ratio> + +Warning threshold for Fragmentation Ratio + +=item B<--critical-fragmentation-ratio> + +Critical threshold for Fragmentation Ratio + +=item B<--warning-defrag-running> + +Warning threshold for Running Defragmentation + +=item B<--critical-defrag-running> + +Critical threshold for Running Defragmentation + +=item B<--warning-lazyfree-pending-objects> + +Warning threshold for Lazyfree Pending Objects + +=item B<--critical-lazyfree-pending-objects> + +Critical threshold for Lazyfree Pending Objects + +=back + +=cut diff --git a/centreon-plugins/apps/redis/cli/mode/persistence.pm b/centreon-plugins/apps/redis/cli/mode/persistence.pm new file mode 100644 index 000000000..db141d38c --- /dev/null +++ b/centreon-plugins/apps/redis/cli/mode/persistence.pm @@ -0,0 +1,218 @@ +# +# Copyright 2017 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::redis::cli::mode::persistence; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; + +my $instance_mode; + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'global', type => 0, skipped_code => { -10 => 1 } }, + ]; + + $self->{maps_counters}->{global} = [ + { label => 'status', threshold => 0, set => { + key_values => [ { name => 'status' }, { name => 'progress_status' } ], + closure_custom_calc => $self->can('custom_status_calc'), + closure_custom_output => $self->can('custom_status_output'), + closure_custom_perfdata => sub { return 0; }, + closure_custom_threshold_check => $self->can('custom_status_threshold'), + } + }, + { label => 'changes', set => { + key_values => [ { name => 'rdb_changes_since_last_save' } ], + output_template => 'Number of changes since the last dump: %s', + perfdatas => [ + { label => 'changes', value => 'rdb_changes_since_last_save_absolute', template => '%s', min => 0 }, + ], + }, + }, + { label => 'last-save', set => { + key_values => [ { name => 'rdb_last_save_time' }, { name => 'rdb_last_save_time_sec' } ], + output_template => 'Time since last successful save: %s', + perfdatas => [ + { label => 'last_save', value => 'rdb_last_save_time_sec_absolute', template => '%s', min => 0, unit => 's' }, + ], + }, + }, + { label => 'save-size', set => { + key_values => [ { name => 'rdb_last_cow_size' } ], + output_template => 'Size of last save: %s %s', + output_change_bytes => 1, + perfdatas => [ + { label => 'save_size', value => 'rdb_last_cow_size_absolute', template => '%s', min => 0, unit => 'B' }, + ], + }, + }, + { label => 'last-save-duration', set => { + key_values => [ { name => 'rdb_last_bgsave_time' } ], + output_template => 'Duration of last save: %s s', + perfdatas => [ + { label => 'last_save_duration', value => 'rdb_last_bgsave_time_absolute', template => '%s', min => 0, unit => 's' }, + ], + }, + }, + { label => 'current-save-duration', set => { + key_values => [ { name => 'rdb_current_bgsave_time' } ], + output_template => 'Duration of current save: %s s', + perfdatas => [ + { label => 'current_save_duration', value => 'rdb_current_bgsave_time_absolute', template => '%s', min => 0, unit => 's' }, + ], + }, + }, + ]; +} + +sub custom_status_threshold { + my ($self, %options) = @_; + my $status = 'ok'; + my $message; + + eval { + local $SIG{__WARN__} = sub { $message = $_[0]; }; + local $SIG{__DIE__} = sub { $message = $_[0]; }; + + if (defined($instance_mode->{option_results}->{critical_status}) && $instance_mode->{option_results}->{critical_status} ne '' && + eval "$instance_mode->{option_results}->{critical_status}") { + $status = 'critical'; + } elsif (defined($instance_mode->{option_results}->{warning_status}) && $instance_mode->{option_results}->{warning_status} ne '' && + eval "$instance_mode->{option_results}->{warning_status}") { + $status = 'warning'; + } + }; + if (defined($message)) { + $self->{output}->output_add(long_msg => 'filter status issue: ' . $message); + } + + return $status; +} + +sub custom_status_output { + my ($self, %options) = @_; + + my $msg = sprintf("RDB save status is '%s' [progress status: %s]", $self->{result_values}->{status}, $self->{result_values}->{progress_status}); + return $msg; +} + +sub custom_status_calc { + my ($self, %options) = @_; + + $self->{result_values}->{status} = $options{new_datas}->{$self->{instance} . '_status'}; + $self->{result_values}->{progress_status} = $options{new_datas}->{$self->{instance} . '_progress_status'}; + 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 => + { + "warning-status:s" => { name => 'warning_status', default => '%{sync_status} =~ /in progress/i' }, + "critical-status:s" => { name => 'critical_status', default => '%{link_status} =~ /down/i' }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::check_options(%options); + + $instance_mode = $self; + $self->change_macros(); +} + +sub change_macros { + my ($self, %options) = @_; + + foreach (('warning_status', 'critical_status')) { + if (defined($self->{option_results}->{$_})) { + $self->{option_results}->{$_} =~ s/%\{(.*?)\}/\$self->{result_values}->{$1}/g; + } + } +} + +my %map_status = ( + 0 => 'stopped', + 1 => 'in progress', +); + +sub manage_selection { + my ($self, %options) = @_; + + my $results = $options{custom}->get_info(); + $self->{global} = { + status => $results->{rdb_last_bgsave_status}, + progress_status => $map_status{$results->{rdb_bgsave_in_progress}}, + rdb_changes_since_last_save => $results->{rdb_changes_since_last_save}, + rdb_last_save_time => centreon::plugins::misc::change_seconds(value => time() - $results->{rdb_last_save_time}), + rdb_last_save_time_sec => time() - $results->{rdb_last_save_time}, + rdb_last_cow_size => $results->{rdb_last_cow_size}, + rdb_last_bgsave_time => $results->{rdb_last_bgsave_time_sec}, + rdb_current_bgsave_time => $results->{rdb_current_bgsave_time_sec} + }; +} + +1; + +__END__ + +=head1 MODE + +Check RDB persistence status. + +=over 8 + +=item B<--warning-status> + +Set warning threshold for status (Default: '%{progress_status} =~ /in progress/i'). +Can used special variables like: %{progress_status}, %{status} + +=item B<--critical-status> + +Set critical threshold for status (Default: '%{status} =~ /fail/i'). +Can used special variables like: %{progress_status}, %{status} + +=item B<--warning-*> + +Threshold warning. +Can be: 'changes', 'last-save', 'save-size', +'last-save-duration', 'current-save-duration'. + +=item B<--critical-*> + +Threshold critical. +Can be: 'changes', 'last-save', 'save-size', +'last-save-duration', 'current-save-duration'. + +=back + +=cut diff --git a/centreon-plugins/apps/redis/cli/mode/replication.pm b/centreon-plugins/apps/redis/cli/mode/replication.pm new file mode 100644 index 000000000..515d80518 --- /dev/null +++ b/centreon-plugins/apps/redis/cli/mode/replication.pm @@ -0,0 +1,250 @@ +# +# Copyright 2017 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::redis::cli::mode::replication; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; + +my $instance_mode; + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'global', type => 0, skipped_code => { -10 => 1 } }, + { name => 'master', type => 0, skipped_code => { -10 => 1 } }, + { name => 'slave', type => 0, skipped_code => { -10 => 1 } }, + ]; + + $self->{maps_counters}->{global} = [ + { label => 'status', threshold => 0, set => { + key_values => [ { name => 'link_status' }, { name => 'sync_status' }, { name => 'role' }, { name => 'cluster_state' } ], + closure_custom_calc => $self->can('custom_status_calc'), + closure_custom_output => $self->can('custom_status_output'), + closure_custom_perfdata => sub { return 0; }, + closure_custom_threshold_check => $self->can('custom_status_threshold'), + } + }, + { label => 'connected-slaves', set => { + key_values => [ { name => 'connected_slaves' } ], + output_template => 'Number of connected slaves: %s', + perfdatas => [ + { label => 'connected_slaves', value => 'connected_slaves_absolute', template => '%s', min => 0 }, + ], + }, + }, + ]; + + $self->{maps_counters}->{master} = [ + { label => 'master-repl-offset', set => { + key_values => [ { name => 'master_repl_offset' } ], + output_template => 'Master replication offset: %s s', + perfdatas => [ + { label => 'master_repl_offset', value => 'master_repl_offset_absolute', template => '%s', min => 0, unit => 's' }, + ], + }, + }, + ]; + + $self->{maps_counters}->{slave} = [ + { label => 'master-last-io', set => { + key_values => [ { name => 'master_last_io_seconds_ago' } ], + output_template => 'Last interaction with master: %s s', + perfdatas => [ + { label => 'master_last_io', value => 'master_last_io_seconds_ago_absolute', template => '%s', min => 0, unit => 's' }, + ], + }, + }, + { label => 'slave-repl-offset', set => { + key_values => [ { name => 'slave_repl_offset' } ], + output_template => 'Slave replication offset: %s s', + perfdatas => [ + { label => 'slave_repl_offset', value => 'slave_repl_offset_absolute', template => '%s', min => 0, unit => 's' }, + ], + }, + }, + { label => 'slave-priority', set => { + key_values => [ { name => 'slave_priority' } ], + output_template => 'Slave replication offset: %s s', + perfdatas => [ + { label => 'slave_priority', value => 'slave_priority_absolute', template => '%s' }, + ], + }, + }, + { label => 'slave-read-only', set => { + key_values => [ { name => 'slave_read_only' } ], + output_template => 'Slave replication offset: %s s', + perfdatas => [ + { label => 'slave_read_only', value => 'slave_read_only_absolute', template => '%s' }, + ], + }, + }, + ]; +} + +sub custom_status_threshold { + my ($self, %options) = @_; + my $status = 'ok'; + my $message; + + eval { + local $SIG{__WARN__} = sub { $message = $_[0]; }; + local $SIG{__DIE__} = sub { $message = $_[0]; }; + + if (defined($instance_mode->{option_results}->{critical_status}) && $instance_mode->{option_results}->{critical_status} ne '' && + eval "$instance_mode->{option_results}->{critical_status}") { + $status = 'critical'; + } elsif (defined($instance_mode->{option_results}->{warning_status}) && $instance_mode->{option_results}->{warning_status} ne '' && + eval "$instance_mode->{option_results}->{warning_status}") { + $status = 'warning'; + } + }; + if (defined($message)) { + $self->{output}->output_add(long_msg => 'filter status issue: ' . $message); + } + + return $status; +} + +sub custom_status_output { + my ($self, %options) = @_; + + my $msg = sprintf("Node role is '%s' [cluster: %s]", $self->{result_values}->{role}, $self->{result_values}->{cluster_state}); + if ($self->{result_values}->{role} eq 'slave') { + $msg .= sprintf(" [link status: %s] [sync status: %s]", + $self->{result_values}->{link_status}, $self->{result_values}->{sync_status}); + } + return $msg; +} + +sub custom_status_calc { + my ($self, %options) = @_; + + $self->{result_values}->{role} = $options{new_datas}->{$self->{instance} . '_role'}; + $self->{result_values}->{sync_status} = $options{new_datas}->{$self->{instance} . '_sync_status'}; + $self->{result_values}->{link_status} = $options{new_datas}->{$self->{instance} . '_link_status'}; + $self->{result_values}->{cluster_state} = $options{new_datas}->{$self->{instance} . '_cluster_state'}; + 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 => + { + "warning-status:s" => { name => 'warning_status', default => '%{sync_status} =~ /in progress/i' }, + "critical-status:s" => { name => 'critical_status', default => '%{link_status} =~ /down/i' }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::check_options(%options); + + $instance_mode = $self; + $self->change_macros(); +} + +sub change_macros { + my ($self, %options) = @_; + + foreach (('warning_status', 'critical_status')) { + if (defined($self->{option_results}->{$_})) { + $self->{option_results}->{$_} =~ s/%\{(.*?)\}/\$self->{result_values}->{$1}/g; + } + } +} + +my %map_sync = ( + 0 => 'stopped', + 1 => 'in progress', +); + +my %map_cluster_state = ( + 0 => 'disabled', + 1 => 'enabled', +); + +sub manage_selection { + my ($self, %options) = @_; + + my $results = $options{custom}->get_info(); + + $self->{global} = { + connected_slaves => $results->{connected_slaves}, + role => $results->{role}, + cluster_state => defined($results->{cluster_enabled}) ? $map_cluster_state{$results->{cluster_enabled}} : '-', + link_status => defined($results->{master_link_status}) ? $results->{master_link_status} : '-', + sync_status => defined($results->{master_sync_in_progress}) ? $map_sync{$results->{master_sync_in_progress}} : '-', + }; + + $self->{master} = { master_repl_offset => $results->{master_repl_offset} }; + $self->{slave} = { + master_last_io_seconds_ago => $results->{master_last_io_seconds_ago}, + slave_repl_offset => $results->{slave_repl_offset}, + slave_priority => $results->{slave_priority}, + slave_read_only => $results->{slave_read_only}, + }; +} + +1; + +__END__ + +=head1 MODE + +Check replication status. + +=over 8 + +=item B<--warning-status> + +Set warning threshold for status (Default: '%{sync_status} =~ /in progress/i'). +Can used special variables like: %{sync_status}, %{link_status}, %{cluster_state} + +=item B<--critical-status> + +Set critical threshold for status (Default: '%{link_status} =~ /down/i'). +Can used special variables like: %{sync_status}, %{link_status}, %{cluster_state} + +=item B<--warning-*> + +Threshold warning. +Can be: 'connected-slaves', 'master-repl-offset', +'master-last-io', 'slave-priority', 'slave-read-only'. + +=item B<--critical-*> + +Threshold critical. +Can be: 'connected-slaves', 'master-repl-offset', +'master-last-io', 'slave-priority', 'slave-read-only'. + +=back + +=cut diff --git a/centreon-plugins/apps/redis/cli/plugin.pm b/centreon-plugins/apps/redis/cli/plugin.pm new file mode 100644 index 000000000..a11ad34e1 --- /dev/null +++ b/centreon-plugins/apps/redis/cli/plugin.pm @@ -0,0 +1,59 @@ +# +# Copyright 2017 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::redis::cli::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; + + $self->{version} = '1.0'; + %{$self->{modes}} = ( + 'clients' => 'apps::redis::cli::mode::clients', + 'commands' => 'apps::redis::cli::mode::commands', + 'connections' => 'apps::redis::cli::mode::connections', + 'cpu' => 'apps::redis::cli::mode::cpu', + 'memory' => 'apps::redis::cli::mode::memory', + 'persistence' => 'apps::redis::cli::mode::persistence', + 'replication' => 'apps::redis::cli::mode::replication', + ); + + $self->{custom_modes}{rediscli} = 'apps::redis::cli::custom::rediscli'; + return $self; +} + +sub init { + my ($self, %options) = @_; + + $self->SUPER::init(%options); +} + +1; + +__END__ + +=head1 PLUGIN DESCRIPTION + +Check Redis server through Perl Cli binding library. diff --git a/centreon-plugins/apps/redis/restapi/custom/api.pm b/centreon-plugins/apps/redis/restapi/custom/api.pm new file mode 100644 index 000000000..6056977b2 --- /dev/null +++ b/centreon-plugins/apps/redis/restapi/custom/api.pm @@ -0,0 +1,245 @@ +# +# Copyright 2017 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::redis::restapi::custom::api; + +use strict; +use warnings; +use centreon::plugins::http; +use JSON::XS; + +sub new { + my ($class, %options) = @_; + my $self = {}; + bless $self, $class; + + 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 => + { + "interval:s@" => { name => 'interval' }, + "hostname:s@" => { name => 'hostname' }, + "port:s@" => { name => 'port' }, + "proto:s@" => { name => 'proto' }, + "username:s@" => { name => 'username' }, + "password:s@" => { name => 'password' }, + "proxyurl:s@" => { name => 'proxyurl' }, + "timeout:s@" => { name => 'timeout' }, + "ssl:s@" => { name => 'ssl' }, + }); + } + $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; + +} + +sub set_options { + my ($self, %options) = @_; + + $self->{option_results} = $options{option_results}; +} + +sub set_defaults { + my ($self, %options) = @_; + + 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) = @_; + + $self->{hostname} = (defined($self->{option_results}->{hostname})) ? shift(@{$self->{option_results}->{hostname}}) : undef; + $self->{port} = (defined($self->{option_results}->{port})) ? shift(@{$self->{option_results}->{port}}) : 9443; + $self->{proto} = (defined($self->{option_results}->{proto})) ? shift(@{$self->{option_results}->{proto}}) : 'https'; + $self->{username} = (defined($self->{option_results}->{username})) ? shift(@{$self->{option_results}->{username}}) : ''; + $self->{password} = (defined($self->{option_results}->{password})) ? shift(@{$self->{option_results}->{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; + $self->{ssl} = (defined($self->{option_results}->{ssl})) ? shift(@{$self->{option_results}->{ssl}}) : 'tlsv1'; + $self->{interval} = (defined($self->{option_results}->{interval})) ? shift(@{$self->{option_results}->{interval}}) : '15min'; + + if (!defined($self->{hostname})) { + $self->{output}->add_option_msg(short_msg => "Need to specify hostname option."); + $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->{hostname}; + $self->{option_results}->{timeout} = $self->{timeout}; + $self->{option_results}->{port} = $self->{port}; + $self->{option_results}->{proto} = $self->{proto}; + $self->{option_results}->{proxyurl} = $self->{proxyurl}; + $self->{option_results}->{credentials} = 1; + $self->{option_results}->{username} = $self->{username}; + $self->{option_results}->{password} = $self->{password}; + $self->{option_results}->{ssl} = $self->{ssl}; + $self->{option_results}->{warning_status} = ''; + $self->{option_results}->{critical_status} = ''; +} + +sub settings { + my ($self, %options) = @_; + + $self->build_options_for_httplib(); + $self->{http}->set_options(%{$self->{option_results}}); +} + +sub get_connection_info { + my ($self, %options) = @_; + + return $self->{hostname} . ":" . $self->{port}; +} + +sub get_interval { + my ($self, %options) = @_; + + return $self->{interval}; +} + +sub get { + my ($self, %options) = @_; + + $self->settings(); + + my $response = $self->{http}->request(url_path => $options{path}); + + my $content; + eval { + $content = JSON::XS->new->utf8->decode($response); + }; + if ($@) { + $self->{output}->add_option_msg(short_msg => "Cannot decode json response: $@"); + $self->{output}->option_exit(); + } + + my $return; + if (ref($content) eq 'ARRAY') { + foreach my $uid (@$content) { + if (defined($uid->{errmsg})) { + $self->{output}->add_option_msg(short_msg => "Cannot get data: " . $uid->{errmsg}); + $self->{output}->option_exit(); + } + $return->{$uid->{uid}} = $uid; + } + } else { + if (defined($content->{errmsg})) { + $self->{output}->add_option_msg(short_msg => "Cannot get data: " . $content->{errmsg}); + $self->{output}->option_exit(); + } + $return = $content; + } + + return $return; +} + +1; + +__END__ + +=head1 NAME + +RedisLabs Enterprise Cluster REST API + +=head1 SYNOPSIS + +RedisLabs Enterprise Cluster Rest API custom mode + +=head1 REST API OPTIONS + +=over 8 + +=item B<--interval> + +Time interval from which to retrieve statistics (Default: '15min'). +Can be : '1sec', '10sec', '5min', '15min', +'1hour', '12hour', '1week'. + +=item B<--hostname> + +Cluster hostname. + +=item B<--port> + +Port used (Default: 9443) + +=item B<--proto> + +Specify https if needed (Default: 'https') + +=item B<--username> + +Cluster username. + +=item B<--password> + +Cluster password. + +=item B<--proxyurl> + +Proxy URL if any + +=item B<--timeout> + +Set HTTP timeout + +=item B<--ssl> + +SSL version (Default: tlsv1) + +=back + +=head1 DESCRIPTION + +B. + +=cut diff --git a/centreon-plugins/apps/redis/restapi/mode/clusterstats.pm b/centreon-plugins/apps/redis/restapi/mode/clusterstats.pm new file mode 100644 index 000000000..e722cb9b6 --- /dev/null +++ b/centreon-plugins/apps/redis/restapi/mode/clusterstats.pm @@ -0,0 +1,334 @@ +# +# Copyright 2017 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::redis::restapi::mode::clusterstats; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; +use Digest::MD5 qw(md5_hex); + +my $instance_mode; + +sub custom_usage_perfdata { + my ($self, %options) = @_; + + $self->{output}->perfdata_add(label => $self->{result_values}->{perf}, unit => 'B', + value => $self->{result_values}->{used}, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{result_values}->{label}, total => $self->{result_values}->{total}, cast_int => 1), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{result_values}->{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, $threshold_value); + $threshold_value = $self->{result_values}->{used}; + $threshold_value = $self->{result_values}->{free} if (defined($instance_mode->{option_results}->{free})); + if ($instance_mode->{option_results}->{units} eq '%') { + $threshold_value = $self->{result_values}->{prct_used}; + $threshold_value = $self->{result_values}->{prct_free} if (defined($instance_mode->{option_results}->{free})); + } + $exit = $self->{perfdata}->threshold_check(value => $threshold_value, threshold => [ { label => 'critical-' . $self->{result_values}->{label}, exit_litteral => 'critical' }, { label => 'warning-' . $self->{result_values}->{label}, exit_litteral => 'warning' } ]); + return $exit; +} + +sub custom_usage_output { + my ($self, %options) = @_; + + my ($used_value, $used_unit) = $self->{perfdata}->change_bytes(value => $self->{result_values}->{used}); + my ($free_value, $free_unit) = $self->{perfdata}->change_bytes(value => $self->{result_values}->{free}); + my ($total_value, $total_unit) = $self->{perfdata}->change_bytes(value => $self->{result_values}->{total}); + + my $msg = sprintf("%s usage: Total: %s Used: %s (%.2f%%) Free: %s (%.2f%%)", $self->{result_values}->{display}, + $total_value . " " . $total_unit, + $used_value . " " . $used_unit, $self->{result_values}->{prct_used}, + $free_value . " " . $free_unit, $self->{result_values}->{prct_free}); + return $msg; +} + +sub custom_usage_calc { + my ($self, %options) = @_; + + $self->{result_values}->{label} = $options{extra_options}->{label}; + $self->{result_values}->{perf} = $options{extra_options}->{perf}; + $self->{result_values}->{display} = $options{extra_options}->{display}; + $self->{result_values}->{free} = $options{new_datas}->{$self->{instance} . '_' . $options{extra_options}->{free}}; + $self->{result_values}->{total} = $options{new_datas}->{$self->{instance} . '_' . $options{extra_options}->{total}}; + + if ($self->{result_values}->{total} != 0) { + $self->{result_values}->{used} = $self->{result_values}->{total} - $self->{result_values}->{free}; + $self->{result_values}->{prct_used} = $self->{result_values}->{used} * 100 / $self->{result_values}->{total}; + $self->{result_values}->{prct_free} = 100 - $self->{result_values}->{prct_used}; + } else { + $self->{result_values}->{used} = '0'; + $self->{result_values}->{prct_used} = '0'; + $self->{result_values}->{prct_free} = '0'; + } + + return 0; +} + +sub prefix_output { + my ($self, %options) = @_; + + return "Cluster '" . $options{instance_value}->{name} . "' "; +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'cluster', type => 1, cb_prefix_output => 'prefix_output', message_multiple => 'All cluster counters are ok' }, + ]; + + $self->{maps_counters}->{cluster} = [ + { label => 'cpu-system', set => { + key_values => [ { name => 'cpu_system' } ], + output_template => 'Cpu system: %.2f %%', + perfdatas => [ + { label => 'cpu_system', value => 'cpu_system_absolute', template => '%.2f', + min => 0, max => 100, unit => '%' }, + ], + } + }, + { label => 'cpu-user', set => { + key_values => [ { name => 'cpu_user' } ], + output_template => 'Cpu user: %.2f %%', + perfdatas => [ + { label => 'cpu_user', value => 'cpu_user_absolute', template => '%.2f', + min => 0, max => 100, unit => '%' }, + ], + } + }, + { label => 'memory', set => { + key_values => [ { name => 'free_memory' }, { name => 'total_memory' } ], + closure_custom_calc => $self->can('custom_usage_calc'), + closure_custom_calc_extra_options => { display => 'Ram', label => 'memory', perf => 'memory', + free => 'free_memory', total => 'total_memory' }, + closure_custom_output => $self->can('custom_usage_output'), + closure_custom_perfdata => $self->can('custom_usage_perfdata'), + closure_custom_threshold_check => $self->can('custom_usage_threshold'), + } + }, + { label => 'persistent-storage', set => { + key_values => [ { name => 'persistent_storage_free' }, { name => 'persistent_storage_size' } ], + closure_custom_calc => $self->can('custom_usage_calc'), + closure_custom_calc_extra_options => { display => 'Persistent storage', label => 'persistent-storage', perf => 'persistent_storage', + free => 'persistent_storage_free', total => 'persistent_storage_size' }, + closure_custom_output => $self->can('custom_usage_output'), + closure_custom_perfdata => $self->can('custom_usage_perfdata'), + closure_custom_threshold_check => $self->can('custom_usage_threshold'), + } + }, + { label => 'ephemeral-storage', set => { + key_values => [ { name => 'ephemeral_storage_free' }, { name => 'ephemeral_storage_size' } ], + closure_custom_calc => $self->can('custom_usage_calc'), + closure_custom_calc_extra_options => { display => 'Ephemeral storage', label => 'ephemeral-storage', perf => 'ephemeral_storage', + free => 'ephemeral_storage_free', total => 'ephemeral_storage_size' }, + closure_custom_output => $self->can('custom_usage_output'), + closure_custom_perfdata => $self->can('custom_usage_perfdata'), + closure_custom_threshold_check => $self->can('custom_usage_threshold'), + } + }, + { label => 'flash-storage', set => { + key_values => [ { name => 'bigstore_free' }, { name => 'bigstore_size' } ], + closure_custom_calc => $self->can('custom_usage_calc'), + closure_custom_calc_extra_options => { display => 'Flash storage', label => 'flash-storage', perf => 'flash_storage', + free => 'bigstore_free', total => 'bigstore_size' }, + closure_custom_output => $self->can('custom_usage_output'), + closure_custom_perfdata => $self->can('custom_usage_perfdata'), + closure_custom_threshold_check => $self->can('custom_usage_threshold'), + } + }, + { label => 'flash-iops', set => { + key_values => [ { name => 'bigstore_iops' } ], + output_template => 'Flash IOPS: %s ops/s', + perfdatas => [ + { label => 'flash_iops', value => 'bigstore_iops_absolute', template => '%s', + min => 0, unit => 'ops/s' }, + ], + } + }, + { label => 'flash-throughput', set => { + key_values => [ { name => 'bigstore_throughput' } ], + output_template => 'Flash throughput: %s %s/s', + output_change_bytes => 1, + perfdatas => [ + { label => 'flash_throughput', value => 'bigstore_throughput_absolute', template => '%s', + min => 0, unit => 'B/s' }, + ], + } + }, + { label => 'connections', set => { + key_values => [ { name => 'conns' } ], + output_template => 'Connections: %s', + perfdatas => [ + { label => 'connections', value => 'conns_absolute', template => '%s', + min => 0 }, + ], + } + }, + { label => 'requests', set => { + key_values => [ { name => 'total_req' } ], + output_template => 'Requests rate: %s ops/s', + perfdatas => [ + { label => 'requests', value => 'total_req_absolute', template => '%s', + min => 0, unit => 'ops/s' }, + ], + } + }, + { label => 'traffic-in', set => { + key_values => [ { name => 'ingress' } ], + output_template => 'Traffic In: %s %s/s', + output_change_bytes => 2, + perfdatas => [ + { label => 'traffic_in', value => 'ingress_absolute', template => '%d', min => 0, unit => 'b/s' }, + ], + }, + }, + { label => 'traffic-out', set => { + key_values => [ { name => 'egress' } ], + output_template => 'Traffic Out: %s %s/s', + output_change_bytes => 2, + perfdatas => [ + { label => 'traffic_out', value => 'egress_absolute', template => '%d', min => 0, unit => 'b/s' }, + ], + }, + }, + ]; +} + +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 => + { + "units:s" => { name => 'units', default => '%' }, + "free" => { name => 'free' }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::check_options(%options); + + $instance_mode = $self; +} + +sub manage_selection { + my ($self, %options) = @_; + + my $result = $options{custom}->get(path => '/v1/cluster/stats/last?interval='.$options{custom}->get_interval()); + my $result2 = $options{custom}->get(path => '/v1/cluster'); + my $result3 = $options{custom}->get(path => '/v1/nodes'); + + my $total_memory = 0; + my $persistent_storage_size = 0; + my $ephemeral_storage_size = 0; + my $bigstore_size = 0; + foreach my $node (keys $result3) { + if (defined($result3->{$node}->{total_memory})) { + $total_memory = $total_memory + $result3->{$node}->{total_memory}; + } + if (defined($result3->{$node}->{persistent_storage_size})) { + $persistent_storage_size = $persistent_storage_size + $result3->{$node}->{persistent_storage_size}; + } + if (defined($result3->{$node}->{ephemeral_storage_size})) { + $ephemeral_storage_size = $ephemeral_storage_size + $result3->{$node}->{ephemeral_storage_size}; + } + if (defined($result3->{$node}->{bigstore_size})) { + $bigstore_size = $bigstore_size + $result3->{$node}->{bigstore_size}; + } + } + + $self->{cluster}->{$result2->{name}} = { + name => $result2->{name}, + cpu_system => $result->{cpu_system} * 100, + cpu_user => $result->{cpu_user} * 100, + free_memory => $result->{free_memory}, + total_memory => $total_memory, + persistent_storage_free => $result->{persistent_storage_free}, + persistent_storage_size => $persistent_storage_size, + ephemeral_storage_free => $result->{ephemeral_storage_free}, + ephemeral_storage_size => $ephemeral_storage_size, + bigstore_free => $result->{bigstore_free}, + bigstore_size => $bigstore_size, + bigstore_iops => $result->{bigstore_iops}, + bigstore_kv_ops => $result->{bigstore_kv_ops}, + bigstore_throughput => $result->{bigstore_throughput}, + conns => $result->{conns}, + total_req => $result->{total_req}, + ingress => $result->{ingress_bytes} * 8, + egress => $result->{egress_bytes} * 8, + }; +} + +1; + +__END__ + +=head1 MODE + +Check RedisLabs Enterprise Cluster statistics. + +=over 8 + +=item B<--filter-counters> + +Only display some counters (regexp can be used). +Example: --filter-counters='^cpu' + +=item B<--units> + +Units of thresholds (Default: '%') ('%', 'B'). + +=item B<--free> + +Thresholds are on free space left. + +=item B<--warning-*> + +Threshold warning. +Can be: 'cpu-system', 'cpu-user', +'requests', 'memory', 'flash-storage', +'persistent-storage', 'ephemeral-storage', +'flash-iops', 'flash-throughput', 'connections', +'traffic-in', 'traffic-out'. + +=item B<--critical-*> + +Threshold critical. +Can be: 'cpu-system', 'cpu-user', +'requests', 'memory', 'flash-storage', +'persistent-storage', 'ephemeral-storage', +'flash-iops', 'flash-throughput', 'connections', +'traffic-in', 'traffic-out'. + +=back + +=cut diff --git a/centreon-plugins/apps/redis/restapi/mode/databasesstats.pm b/centreon-plugins/apps/redis/restapi/mode/databasesstats.pm new file mode 100644 index 000000000..c271338c3 --- /dev/null +++ b/centreon-plugins/apps/redis/restapi/mode/databasesstats.pm @@ -0,0 +1,610 @@ +# +# Copyright 2017 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::redis::restapi::mode::databasesstats; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; +use Digest::MD5 qw(md5_hex); + +my $instance_mode; + +sub custom_usage_perfdata { + my ($self, %options) = @_; + + $self->{output}->perfdata_add(label => $self->{result_values}->{perf}, unit => 'B', + value => $self->{result_values}->{used}, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{result_values}->{label}, total => $self->{result_values}->{total}, cast_int => 1), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{result_values}->{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, $threshold_value); + $threshold_value = $self->{result_values}->{used}; + $threshold_value = $self->{result_values}->{free} if (defined($instance_mode->{option_results}->{free})); + if ($instance_mode->{option_results}->{units} eq '%') { + $threshold_value = $self->{result_values}->{prct_used}; + $threshold_value = $self->{result_values}->{prct_free} if (defined($instance_mode->{option_results}->{free})); + } + $exit = $self->{perfdata}->threshold_check(value => $threshold_value, threshold => [ { label => 'critical-' . $self->{result_values}->{label}, exit_litteral => 'critical' }, { label => 'warning-' . $self->{result_values}->{label}, exit_litteral => 'warning' } ]); + return $exit; +} + +sub custom_usage_output { + my ($self, %options) = @_; + + my ($used_value, $used_unit) = $self->{perfdata}->change_bytes(value => $self->{result_values}->{used}); + my ($free_value, $free_unit) = $self->{perfdata}->change_bytes(value => $self->{result_values}->{free}); + my ($total_value, $total_unit) = $self->{perfdata}->change_bytes(value => $self->{result_values}->{total}); + + my $msg = sprintf("%s usage: Total: %s Used: %s (%.2f%%) Free: %s (%.2f%%)", $self->{result_values}->{display}, + $total_value . " " . $total_unit, + $used_value . " " . $used_unit, $self->{result_values}->{prct_used}, + $free_value . " " . $free_unit, $self->{result_values}->{prct_free}); + return $msg; +} + +sub custom_usage_calc { + my ($self, %options) = @_; + + $self->{result_values}->{label} = $options{extra_options}->{label}; + $self->{result_values}->{perf} = $options{extra_options}->{perf}; + $self->{result_values}->{display} = $options{extra_options}->{display}; + $self->{result_values}->{used} = $options{new_datas}->{$self->{instance} . '_' . $options{extra_options}->{used}}; + $self->{result_values}->{total} = $options{new_datas}->{$self->{instance} . '_' . $options{extra_options}->{total}}; + + if ($self->{result_values}->{total} != 0) { + $self->{result_values}->{free} = $self->{result_values}->{total} - $self->{result_values}->{used}; + $self->{result_values}->{prct_used} = $self->{result_values}->{used} * 100 / $self->{result_values}->{total}; + $self->{result_values}->{prct_free} = 100 - $self->{result_values}->{prct_used}; + } else { + $self->{result_values}->{used} = '0'; + $self->{result_values}->{prct_used} = '0'; + $self->{result_values}->{prct_free} = '0'; + } + + return 0; +} + +sub custom_status_threshold { + my ($self, %options) = @_; + my $status = 'ok'; + my $message; + + eval { + local $SIG{__WARN__} = sub { $message = $_[0]; }; + local $SIG{__DIE__} = sub { $message = $_[0]; }; + + if (defined($instance_mode->{option_results}->{critical_status}) && $instance_mode->{option_results}->{critical_status} ne '' && + eval "$instance_mode->{option_results}->{critical_status}") { + $status = 'critical'; + } elsif (defined($instance_mode->{option_results}->{warning_status}) && $instance_mode->{option_results}->{warning_status} ne '' && + eval "$instance_mode->{option_results}->{warning_status}") { + $status = 'warning'; + } + }; + if (defined($message)) { + $self->{output}->output_add(long_msg => 'filter status issue: ' . $message); + } + + return $status; +} + +sub custom_status_output { + my ($self, %options) = @_; + + my $msg = sprintf("Status is '%s' [type: %s] [shard list: %s] [backup status: %s] [export status: %s] [import status: %s]", + $self->{result_values}->{status}, + $self->{result_values}->{type}, + $self->{result_values}->{shard_list}, + $self->{result_values}->{backup_status}, + $self->{result_values}->{export_status}, + $self->{result_values}->{import_status}); + return $msg; +} + +sub custom_status_calc { + my ($self, %options) = @_; + + $self->{result_values}->{type} = $options{new_datas}->{$self->{instance} . '_type'}; + $self->{result_values}->{status} = $options{new_datas}->{$self->{instance} . '_status'}; + $self->{result_values}->{backup_status} = $options{new_datas}->{$self->{instance} . '_backup_status'}; + $self->{result_values}->{export_status} = $options{new_datas}->{$self->{instance} . '_export_status'}; + $self->{result_values}->{import_status} = $options{new_datas}->{$self->{instance} . '_import_status'}; + $self->{result_values}->{shard_list} = $options{new_datas}->{$self->{instance} . '_shard_list'}; + $self->{result_values}->{display} = $options{new_datas}->{$self->{instance} . '_display'}; + return 0; +} + +sub custom_cpu_output { + my ($self, %options) = @_; + + my $msg = sprintf("%s CPU usage (user/system): %s/%s %%", + $self->{result_values}->{cpu}, + $self->{result_values}->{user}, + $self->{result_values}->{system}); + return $msg; +} + +sub custom_cpu_calc { + my ($self, %options) = @_; + + $self->{result_values}->{display} = $options{new_datas}->{$self->{instance} . '_' . $options{extra_options}->{display}}; + $self->{result_values}->{cpu} = $options{extra_options}->{cpu}; + $self->{result_values}->{user} = $options{new_datas}->{$self->{instance} . '_' . $options{extra_options}->{user}}; + $self->{result_values}->{system} = $options{new_datas}->{$self->{instance} . '_' . $options{extra_options}->{system}}; + return 0; +} + +sub custom_operations_output { + my ($self, %options) = @_; + + my $msg = sprintf("%s operations rates (hits/misses/requests/responses): %s/%s/%s/%s ops/s", + $self->{result_values}->{operation}, + $self->{result_values}->{hits}, + $self->{result_values}->{misses}, + $self->{result_values}->{req}, + $self->{result_values}->{res}); + return $msg; +} + +sub custom_operations_calc { + my ($self, %options) = @_; + + $self->{result_values}->{display} = $options{new_datas}->{$self->{instance} . '_' . $options{extra_options}->{display}}; + $self->{result_values}->{operation} = $options{extra_options}->{operation}; + $self->{result_values}->{hits} = $options{new_datas}->{$self->{instance} . '_' . $options{extra_options}->{hits}}; + $self->{result_values}->{misses} = $options{new_datas}->{$self->{instance} . '_' . $options{extra_options}->{misses}}; + $self->{result_values}->{req} = $options{new_datas}->{$self->{instance} . '_' . $options{extra_options}->{req}}; + $self->{result_values}->{res} = $options{new_datas}->{$self->{instance} . '_' . $options{extra_options}->{res}}; + return 0; +} + +sub prefix_output { + my ($self, %options) = @_; + + return "Database '" . $options{instance_value}->{display} . "' "; +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'databases', type => 1, cb_prefix_output => 'prefix_output', message_multiple => 'All databases counters are ok' }, + ]; + + $self->{maps_counters}->{databases} = [ + { label => 'status', threshold => 0, set => { + key_values => [ { name => 'status' }, { name => 'type' }, { name => 'backup_status' }, + { name => 'export_status' }, { name => 'import_status' }, { name => 'shard_list' }, { name => 'display' } ], + closure_custom_calc => $self->can('custom_status_calc'), + closure_custom_output => $self->can('custom_status_output'), + closure_custom_perfdata => sub { return 0; }, + closure_custom_threshold_check => $self->can('custom_status_threshold'), + } + }, + { label => 'total-cpu', set => { + key_values => [ { name => 'shard_cpu_user' }, { name => 'shard_cpu_system' }, { name => 'display' } ], + closure_custom_calc => $self->can('custom_cpu_calc'), + closure_custom_calc_extra_options => { cpu => 'Total', user => 'shard_cpu_user', + system => 'shard_cpu_system', display => 'display' }, + closure_custom_output => $self->can('custom_cpu_output'), + perfdatas => [ + { label => 'total_cpu_user', value => 'user', template => '%s', + min => 0, max => 100, unit => '%', label_extra_instance => 1, instance_use => 'display' }, + { label => 'total_cpu_system', value => 'system', template => '%s', + min => 0, max => 100, unit => '%', label_extra_instance => 1, instance_use => 'display' }, + ], + } + }, + { label => 'fork-cpu', set => { + key_values => [ { name => 'fork_cpu_user' }, { name => 'fork_cpu_system' }, { name => 'display' } ], + closure_custom_calc => $self->can('custom_cpu_calc'), + closure_custom_calc_extra_options => { cpu => 'Fork', user => 'fork_cpu_user', + system => 'fork_cpu_system', display => 'display' }, + closure_custom_output => $self->can('custom_cpu_output'), + perfdatas => [ + { label => 'fork_cpu_user', value => 'user', template => '%s', + min => 0, max => 100, unit => '%', label_extra_instance => 1, instance_use => 'display' }, + { label => 'fork_cpu_system', value => 'system', template => '%s', + min => 0, max => 100, unit => '%', label_extra_instance => 1, instance_use => 'display' }, + ], + } + }, + { label => 'main-thread-cpu', set => { + key_values => [ { name => 'main_thread_cpu_user' }, { name => 'main_thread_cpu_system' }, { name => 'display' } ], + closure_custom_calc => $self->can('custom_cpu_calc'), + closure_custom_calc_extra_options => { cpu => 'Main thread', user => 'main_thread_cpu_user', + system => 'main_thread_cpu_system', display => 'display' }, + closure_custom_output => $self->can('custom_cpu_output'), + perfdatas => [ + { label => 'main_thread_cpu_user', value => 'user', template => '%s', + min => 0, max => 100, unit => '%', label_extra_instance => 1, instance_use => 'display' }, + { label => 'main_thread_cpu_system', value => 'system', template => '%s', + min => 0, max => 100, unit => '%', label_extra_instance => 1, instance_use => 'display' }, + ], + } + }, + { label => 'memory', set => { + key_values => [ { name => 'used_memory' }, { name => 'memory_size' } ], + closure_custom_calc => $self->can('custom_usage_calc'), + closure_custom_calc_extra_options => { display => 'Memory', label => 'memory', perf => 'memory', + used => 'used_memory', total => 'memory_size' }, + closure_custom_output => $self->can('custom_usage_output'), + closure_custom_perfdata => $self->can('custom_usage_perfdata'), + closure_custom_threshold_check => $self->can('custom_usage_threshold'), + } + }, + { label => 'mem-frag-ratio', set => { + key_values => [ { name => 'mem_frag_ratio' }, { name => 'display' } ], + output_template => 'Memory fragmentation ratio: %s', + perfdatas => [ + { label => 'mem_frag_ratio', value => 'mem_frag_ratio_absolute', template => '%s', + min => 0, label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + { label => 'connections', set => { + key_values => [ { name => 'conns' }, { name => 'display' } ], + output_template => 'Connections: %s', + perfdatas => [ + { label => 'connections', value => 'conns_absolute', template => '%s', + min => 0, label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + { label => 'total-rates', set => { + key_values => [ { name => 'total_hits' }, { name => 'total_misses' }, + { name => 'total_req' }, { name => 'total_res' }, { name => 'display' } ], + closure_custom_calc => $self->can('custom_operations_calc'), + closure_custom_calc_extra_options => { operation => 'Total', hits => 'total_hits', misses => 'total_misses', + req => 'total_req', res => 'total_res', display => 'display' }, + closure_custom_output => $self->can('custom_operations_output'), + perfdatas => [ + { label => 'total_hits', value => 'hits', template => '%s', + min => 0, unit => 'ops/s', label_extra_instance => 1, instance_use => 'display' }, + { label => 'total_misses', value => 'misses', template => '%s', + min => 0, unit => 'ops/s', label_extra_instance => 1, instance_use => 'display' }, + { label => 'total_req', value => 'req', template => '%s', + min => 0, unit => 'ops/s', label_extra_instance => 1, instance_use => 'display' }, + { label => 'total_res', value => 'res', template => '%s', + min => 0, unit => 'ops/s', label_extra_instance => 1, instance_use => 'display' }, + ], + } + }, + { label => 'latency', set => { + key_values => [ { name => 'avg_latency' }, { name => 'display' } ], + output_template => 'Average latency: %.2f ms', + perfdatas => [ + { label => 'latency', value => 'avg_latency_absolute', template => '%.2f', + min => 0, unit => 'ms', label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + { label => 'other-rates', set => { + key_values => [ { name => 'other_hits' }, { name => 'other_misses' }, + { name => 'other_req' }, { name => 'other_res' }, { name => 'display' } ], + closure_custom_calc => $self->can('custom_operations_calc'), + closure_custom_calc_extra_options => { operation => 'Other', hits => 'other_hits', misses => 'other_misses', + req => 'other_req', res => 'other_res', display => 'display' }, + closure_custom_output => $self->can('custom_operations_output'), + perfdatas => [ + { label => 'other_req', value => 'req', template => '%s', + min => 0, unit => 'ops/s', label_extra_instance => 1, instance_use => 'display' }, + { label => 'other_res', value => 'res', template => '%s', + min => 0, unit => 'ops/s', label_extra_instance => 1, instance_use => 'display' }, + ], + } + }, + { label => 'other-latency', set => { + key_values => [ { name => 'avg_other_latency' }, { name => 'display' } ], + output_template => 'Other latency: %.2f ms', + perfdatas => [ + { label => 'other_latency', value => 'avg_other_latency_absolute', template => '%.2f', + min => 0, unit => 'ms', label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + { label => 'keys', set => { + key_values => [ { name => 'no_of_keys' }, { name => 'display' } ], + output_template => 'Total keys: %s', + perfdatas => [ + { label => 'keys', value => 'no_of_keys_absolute', template => '%s', + min => 0, label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + { label => 'evicted-objects', set => { + key_values => [ { name => 'evicted_objects' }, { name => 'display' } ], + output_template => 'Evicted objects rate: %s evictions/sec', + perfdatas => [ + { label => 'evicted_objects', value => 'evicted_objects_absolute', template => '%s', + min => 0, unit => 'evictions/sec', label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + { label => 'expired-objects', set => { + key_values => [ { name => 'expired_objects' }, { name => 'display' } ], + output_template => 'Expired objects rate: %s expirations/sec', + perfdatas => [ + { label => 'expired_objects', value => 'expired_objects_absolute', template => '%s', + min => 0, unit => 'expirations/sec', label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + { label => 'read-rates', set => { + key_values => [ { name => 'read_hits' }, { name => 'read_misses' }, + { name => 'read_req' }, { name => 'read_res' }, { name => 'display' } ], + closure_custom_calc => $self->can('custom_operations_calc'), + closure_custom_calc_extra_options => { operation => 'Read', hits => 'read_hits', misses => 'read_misses', + req => 'read_req', res => 'read_res', display => 'display' }, + closure_custom_output => $self->can('custom_operations_output'), + perfdatas => [ + { label => 'read_hits', value => 'hits', template => '%s', + min => 0, unit => 'ops/s', label_extra_instance => 1, instance_use => 'display' }, + { label => 'read_misses', value => 'misses', template => '%s', + min => 0, unit => 'ops/s', label_extra_instance => 1, instance_use => 'display' }, + { label => 'read_req', value => 'req', template => '%s', + min => 0, unit => 'ops/s', label_extra_instance => 1, instance_use => 'display' }, + { label => 'read_res', value => 'res', template => '%s', + min => 0, unit => 'ops/s', label_extra_instance => 1, instance_use => 'display' }, + ], + } + }, + { label => 'read-latency', set => { + key_values => [ { name => 'avg_read_latency' }, { name => 'display' } ], + output_template => 'Read latency: %.2f ms', + perfdatas => [ + { label => 'read_latency', value => 'avg_read_latency_absolute', template => '%.2f', + min => 0, unit => 'ms', label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + { label => 'write-rates', set => { + key_values => [ { name => 'write_hits' }, { name => 'write_misses' }, + { name => 'write_req' }, { name => 'write_res' }, { name => 'display' } ], + closure_custom_calc => $self->can('custom_operations_calc'), + closure_custom_calc_extra_options => { operation => 'Write', hits => 'write_hits', misses => 'write_misses', + req => 'write_req', res => 'write_res', display => 'display' }, + closure_custom_output => $self->can('custom_operations_output'), + perfdatas => [ + { label => 'write_hits', value => 'hits', template => '%s', + min => 0, unit => 'ops/s', label_extra_instance => 1, instance_use => 'display' }, + { label => 'write_misses', value => 'misses', template => '%s', + min => 0, unit => 'ops/s', label_extra_instance => 1, instance_use => 'display' }, + { label => 'write_req', value => 'req', template => '%s', + min => 0, unit => 'ops/s', label_extra_instance => 1, instance_use => 'display' }, + { label => 'write_res', value => 'res', template => '%s', + min => 0, unit => 'ops/s', label_extra_instance => 1, instance_use => 'display' }, + ], + } + }, + { label => 'write-latency', set => { + key_values => [ { name => 'avg_write_latency' }, { name => 'display' } ], + output_template => 'Write latency: %.2f ms', + perfdatas => [ + { label => 'write_latency', value => 'avg_write_latency_absolute', template => '%.2f', + min => 0, unit => 'ms', label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + { label => 'traffic-in', set => { + key_values => [ { name => 'ingress' }, { name => 'display' } ], + output_template => 'Traffic In: %s %s/s', + output_change_bytes => 2, + perfdatas => [ + { label => 'traffic_in', value => 'ingress_absolute', template => '%d', + min => 0, unit => 'b/s', label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + }, + }, + { label => 'traffic-out', set => { + key_values => [ { name => 'egress' }, { name => 'display' } ], + output_template => 'Traffic Out: %s %s/s', + output_change_bytes => 2, + perfdatas => [ + { label => 'traffic_out', value => 'egress_absolute', template => '%d', + min => 0, unit => 'b/s', 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-database:s" => { name => 'filter_database' }, + "units:s" => { name => 'units', default => '%' }, + "free" => { name => 'free' }, + "warning-status:s" => { name => 'warning_status', default => '' }, + "critical-status:s" => { name => 'critical_status', default => '%{status} =~ /creation-failed/i | %{backup_status} =~ /failed/i | + %{export_status} =~ /failed/i | %{import_status} =~ /failed/i' }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::check_options(%options); + + $instance_mode = $self; + $self->change_macros(); +} + +sub change_macros { + my ($self, %options) = @_; + + foreach (('warning_status', 'critical_status')) { + if (defined($self->{option_results}->{$_})) { + $self->{option_results}->{$_} =~ s/%\{(.*?)\}/\$self->{result_values}->{$1}/g; + } + } +} + +sub manage_selection { + my ($self, %options) = @_; + + my $result = $options{custom}->get(path => '/v1/bdbs/stats/last?interval='.$options{custom}->get_interval()); + my $result2 = $options{custom}->get(path => '/v1/bdbs'); + + foreach my $database (keys $result) { + if (defined($self->{option_results}->{filter_database}) && $self->{option_results}->{filter_database} ne '' && + $database !~ /$self->{option_results}->{filter_database}/) { + $self->{output}->output_add(long_msg => "skipping database '" . $database . "': no matching filter.", debug => 1); + next; + } + + my $shard_list = '-'; + if (@{$result2->{$database}->{shard_list}}) { + $shard_list = join(", ", @{$result2->{$database}->{shard_list}}); + } + + $self->{databases}->{$database} = { + display => $result2->{$database}->{name}, + status => defined($result2->{$database}->{status}) ? $result2->{$database}->{status} : '-', + type => defined($result2->{$database}->{type}) ? $result2->{$database}->{type} : '-', + backup_status => defined($result2->{$database}->{backup_status}) ? $result2->{$database}->{backup_status} : '-', + export_status => defined($result2->{$database}->{export_status}) ? $result2->{$database}->{export_status} : '-', + import_status => defined($result2->{$database}->{import_status}) ? $result2->{$database}->{import_status} : '-', + shard_list => $shard_list, + shard_cpu_user => $result->{$database}->{shard_cpu_user} * 100, + shard_cpu_system => $result->{$database}->{shard_cpu_system} * 100, + main_thread_cpu_user => $result->{$database}->{main_thread_cpu_user} * 100, + main_thread_cpu_system => $result->{$database}->{main_thread_cpu_system} * 100, + fork_cpu_user => $result->{$database}->{fork_cpu_user} * 100, + fork_cpu_system => $result->{$database}->{fork_cpu_system} * 100, + used_memory => $result->{$database}->{used_memory}, + memory_size => $result2->{$database}->{memory_size}, + mem_frag_ratio => $result->{$database}->{mem_frag_ratio}, + conns => $result->{$database}->{conns}, + total_req => defined($result->{$database}->{total_req}) ? $result->{$database}->{total_req} : $result->{$database}->{instantaneous_ops_per_sec}, + total_res => $result->{$database}->{total_res}, + total_hits => $result->{$database}->{read_hits} + $result->{$database}->{write_hits}, + total_misses => $result->{$database}->{read_misses} + $result->{$database}->{write_misses}, + avg_latency => defined($result2->{$database}->{avg_latency}) ? $result->{$database}->{avg_latency} * 1000 : '0', + other_req => $result->{$database}->{other_req}, + other_res => $result->{$database}->{other_res}, + other_hits => '-', + other_misses => '-', + avg_other_latency => defined($result2->{$database}->{avg_other_latency}) ? $result->{$database}->{avg_other_latency} * 1000 : '0', + no_of_keys => $result->{$database}->{no_of_keys}, + evicted_objects => $result->{$database}->{evicted_objects}, + expired_objects => $result->{$database}->{expired_objects}, + read_hits => $result->{$database}->{read_hits}, + read_misses => $result->{$database}->{read_misses}, + read_req => $result->{$database}->{read_req}, + read_res => $result->{$database}->{read_res}, + write_hits => $result->{$database}->{write_hits}, + write_misses => $result->{$database}->{write_misses}, + write_req => $result->{$database}->{write_req}, + write_res => $result->{$database}->{write_res}, + avg_read_latency => defined($result2->{$database}->{avg_read_latency}) ? $result->{$database}->{avg_read_latency} * 1000 : '0', + avg_write_latency => defined($result2->{$database}->{avg_write_latency}) ? $result->{$database}->{avg_write_latency} * 1000 : '0', + ingress => $result->{$database}->{ingress_bytes} * 8, + egress => $result->{$database}->{egress_bytes} * 8, + }; + + if (scalar(keys %{$self->{databases}}) <= 0) { + $self->{output}->add_option_msg(short_msg => 'No databases detected, check your filter ? '); + $self->{output}->option_exit(); + } + } +} + +1; + +__END__ + +=head1 MODE + +Check RedisLabs Enterprise Cluster databases statistics. + +=over 8 + +=item B<--filter-counters> + +Only display some counters (regexp can be used). +Example: --filter-counters='rate|latency' + +=item B<--warning-status> + +Set warning threshold for status. +Can used special variables like: %{status}, %{type}, +%{backup_status}, %{export_status}, %{shard_list}. +'status' can be: 'pending', 'active', 'active-change-pending', +'delete-pending', 'import-pending', 'creation-failed', 'recovery'. +'type' can be: 'redis', 'memcached'. +'backup_status' can be: 'exporting', 'succeeded', 'failed'. +'export_status' can be: 'exporting', 'succeeded', 'failed'. +'import_status' can be: 'idle', 'initializing', 'importing', +'succeeded', 'failed'. + +=item B<--critical-status> + +Set critical threshold for status (Default: '%{status} =~ /creation-failed/i | +%{backup_status} =~ /failed/i | %{export_status} =~ /failed/i | +%{import_status} =~ /failed/i'). +Can used special variables like: %{status}, %{type}, +%{backup_status}, %{export_status}, %{shard_list}. +'status' can be: 'pending', 'active', 'active-change-pending', +'delete-pending', 'import-pending', 'creation-failed', 'recovery'. +'type' can be: 'redis', 'memcached'. +'backup_status' can be: 'exporting', 'succeeded', 'failed'. +'' can be: 'exporting', 'succeeded', 'failed'. +'import_status' can be: 'idle', 'initializing', 'importing', +'succeeded', 'failed'. + +=item B<--warning-*> + +Threshold warning. +Can be: 'total-cpu', 'fork-cpu', 'main-thread-cpu', +'memory', 'mem-frag-ratio', 'connections', +'total-rates', 'latency', 'other-rates', 'other-latency', +'keys', 'evicted-objects', 'expired-objects', +'read-rates', 'read-latency', +'write-rates', 'write-latency', +'traffic-in', 'traffic-out'. + +=item B<--critical-*> + +Threshold critical. +Can be: 'total-cpu', 'fork-cpu', 'main-thread-cpu', +'memory', 'mem-frag-ratio', 'connections', +'total-rates', 'latency', 'other-rates', 'other-latency', +'keys', 'evicted-objects', 'expired-objects', +'read-rates', 'read-latency', +'write-rates', 'write-latency', +'traffic-in', 'traffic-out'. + +=back + +=cut diff --git a/centreon-plugins/apps/redis/restapi/mode/listdatabases.pm b/centreon-plugins/apps/redis/restapi/mode/listdatabases.pm new file mode 100644 index 000000000..1b9bfd2a3 --- /dev/null +++ b/centreon-plugins/apps/redis/restapi/mode/listdatabases.pm @@ -0,0 +1,99 @@ +# +# Copyright 2017 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::redis::restapi::mode::listdatabases; + +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 => + { + }); + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::init(%options); +} + +sub manage_selection { + my ($self, %options) = @_; + + $self->{databases} = $options{custom}->get(path => '/v1/bdbs'); +} + +sub run { + my ($self, %options) = @_; + + $self->manage_selection(%options); + foreach my $database_uid (sort keys %{$self->{databases}}) { + $self->{output}->output_add(long_msg => '[uid = ' . $database_uid . "] [name = '" . $self->{databases}->{$database_uid}->{name} . "']" . + " [type = '" . $self->{databases}->{$database_uid}->{type} . "']" . + " [status = '" . $self->{databases}->{$database_uid}->{status} . "']" + ); + } + + $self->{output}->output_add(severity => 'OK', + short_msg => 'List databases:'); + $self->{output}->display(nolabel => 1, force_ignore_perfdata => 1, force_long_output => 1); + $self->{output}->exit(); +} + +sub disco_format { + my ($self, %options) = @_; + + $self->{output}->add_disco_format(elements => ['uid', 'name', 'type', 'status']); +} + +sub disco_show { + my ($self, %options) = @_; + + $self->manage_selection(%options); + foreach my $database_uid (sort keys %{$self->{databases}}) { + $self->{output}->add_disco_entry(name => $self->{databases}->{$database_uid}->{name}, + type => $self->{databases}->{$database_uid}->{type}, + status => $self->{databases}->{$database_uid}->{status}, + uid => $database_uid, + ); + } +} + +1; + +__END__ + +=head1 MODE + +List databases. + +=over 8 + +=back + +=cut diff --git a/centreon-plugins/apps/redis/restapi/mode/listnodes.pm b/centreon-plugins/apps/redis/restapi/mode/listnodes.pm new file mode 100644 index 000000000..0600a44ec --- /dev/null +++ b/centreon-plugins/apps/redis/restapi/mode/listnodes.pm @@ -0,0 +1,94 @@ +# +# Copyright 2017 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::redis::restapi::mode::listnodes; + +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 => + { + }); + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::init(%options); +} + +sub manage_selection { + my ($self, %options) = @_; + + $self->{nodes} = $options{custom}->get(path => '/v1/nodes'); +} + +sub run { + my ($self, %options) = @_; + + $self->manage_selection(%options); + foreach my $node_uid (sort keys %{$self->{nodes}}) { + $self->{output}->output_add(long_msg => '[uid = ' . $node_uid . "] [status = '" . $self->{nodes}->{$node_uid}->{status} . "']"); + } + + $self->{output}->output_add(severity => 'OK', + short_msg => 'List nodes:'); + $self->{output}->display(nolabel => 1, force_ignore_perfdata => 1, force_long_output => 1); + $self->{output}->exit(); +} + +sub disco_format { + my ($self, %options) = @_; + + $self->{output}->add_disco_format(elements => ['uid', 'status']); +} + +sub disco_show { + my ($self, %options) = @_; + + $self->manage_selection(%options); + foreach my $node_uid (sort keys %{$self->{nodes}}) { + $self->{output}->add_disco_entry(status => $self->{nodes}->{$node_uid}->{status}, + uid => $node_uid, + ); + } +} + +1; + +__END__ + +=head1 MODE + +List nodes. + +=over 8 + +=back + +=cut diff --git a/centreon-plugins/apps/redis/restapi/mode/listshards.pm b/centreon-plugins/apps/redis/restapi/mode/listshards.pm new file mode 100644 index 000000000..ee6813734 --- /dev/null +++ b/centreon-plugins/apps/redis/restapi/mode/listshards.pm @@ -0,0 +1,99 @@ +# +# Copyright 2017 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::redis::restapi::mode::listshards; + +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 => + { + }); + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::init(%options); +} + +sub manage_selection { + my ($self, %options) = @_; + + $self->{shards} = $options{custom}->get(path => '/v1/shards'); +} + +sub run { + my ($self, %options) = @_; + + $self->manage_selection(%options); + foreach my $shard_uid (sort keys %{$self->{shards}}) { + $self->{output}->output_add(long_msg => '[uid = ' . $shard_uid . "] [role = '" . $self->{shards}->{$shard_uid}->{role} . "']" . + " [detailed_status = '" . $self->{shards}->{$shard_uid}->{detailed_status} . "']" . + " [status = '" . $self->{shards}->{$shard_uid}->{status} . "']" + ); + } + + $self->{output}->output_add(severity => 'OK', + short_msg => 'List shards:'); + $self->{output}->display(nolabel => 1, force_ignore_perfdata => 1, force_long_output => 1); + $self->{output}->exit(); +} + +sub disco_format { + my ($self, %options) = @_; + + $self->{output}->add_disco_format(elements => ['uid', 'role', 'detailed_status', 'status']); +} + +sub disco_show { + my ($self, %options) = @_; + + $self->manage_selection(%options); + foreach my $shard_uid (sort keys %{$self->{shards}}) { + $self->{output}->add_disco_entry(role => $self->{shards}->{$shard_uid}->{role}, + detailed_status => $self->{shards}->{$shard_uid}->{detailed_status}, + status => $self->{shards}->{$shard_uid}->{status}, + uid => $shard_uid, + ); + } +} + +1; + +__END__ + +=head1 MODE + +List shards. + +=over 8 + +=back + +=cut diff --git a/centreon-plugins/apps/redis/restapi/mode/nodesstats.pm b/centreon-plugins/apps/redis/restapi/mode/nodesstats.pm new file mode 100644 index 000000000..ebff496a7 --- /dev/null +++ b/centreon-plugins/apps/redis/restapi/mode/nodesstats.pm @@ -0,0 +1,445 @@ +# +# Copyright 2017 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::redis::restapi::mode::nodesstats; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; +use Digest::MD5 qw(md5_hex); + +my $instance_mode; + +sub custom_usage_perfdata { + my ($self, %options) = @_; + + $self->{output}->perfdata_add(label => $self->{result_values}->{perf}, unit => 'B', + value => $self->{result_values}->{used}, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{result_values}->{label}, total => $self->{result_values}->{total}, cast_int => 1), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{result_values}->{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, $threshold_value); + $threshold_value = $self->{result_values}->{used}; + $threshold_value = $self->{result_values}->{free} if (defined($instance_mode->{option_results}->{free})); + if ($instance_mode->{option_results}->{units} eq '%') { + $threshold_value = $self->{result_values}->{prct_used}; + $threshold_value = $self->{result_values}->{prct_free} if (defined($instance_mode->{option_results}->{free})); + } + $exit = $self->{perfdata}->threshold_check(value => $threshold_value, threshold => [ { label => 'critical-' . $self->{result_values}->{label}, exit_litteral => 'critical' }, { label => 'warning-' . $self->{result_values}->{label}, exit_litteral => 'warning' } ]); + return $exit; +} + +sub custom_usage_output { + my ($self, %options) = @_; + + my ($used_value, $used_unit) = $self->{perfdata}->change_bytes(value => $self->{result_values}->{used}); + my ($free_value, $free_unit) = $self->{perfdata}->change_bytes(value => $self->{result_values}->{free}); + my ($total_value, $total_unit) = $self->{perfdata}->change_bytes(value => $self->{result_values}->{total}); + + my $msg = sprintf("%s usage: Total: %s Used: %s (%.2f%%) Free: %s (%.2f%%)", $self->{result_values}->{display}, + $total_value . " " . $total_unit, + $used_value . " " . $used_unit, $self->{result_values}->{prct_used}, + $free_value . " " . $free_unit, $self->{result_values}->{prct_free}); + return $msg; +} + +sub custom_usage_calc { + my ($self, %options) = @_; + + $self->{result_values}->{label} = $options{extra_options}->{label}; + $self->{result_values}->{perf} = $options{extra_options}->{perf}; + $self->{result_values}->{display} = $options{extra_options}->{display}; + $self->{result_values}->{free} = $options{new_datas}->{$self->{instance} . '_' . $options{extra_options}->{free}}; + $self->{result_values}->{total} = $options{new_datas}->{$self->{instance} . '_' . $options{extra_options}->{total}}; + + if ($self->{result_values}->{total} != 0) { + $self->{result_values}->{used} = $self->{result_values}->{total} - $self->{result_values}->{free}; + $self->{result_values}->{prct_used} = $self->{result_values}->{used} * 100 / $self->{result_values}->{total}; + $self->{result_values}->{prct_free} = 100 - $self->{result_values}->{prct_used}; + } else { + $self->{result_values}->{used} = '0'; + $self->{result_values}->{prct_used} = '0'; + $self->{result_values}->{prct_free} = '0'; + } + + return 0; +} + +sub custom_status_threshold { + my ($self, %options) = @_; + my $status = 'ok'; + my $message; + + eval { + local $SIG{__WARN__} = sub { $message = $_[0]; }; + local $SIG{__DIE__} = sub { $message = $_[0]; }; + + if (defined($instance_mode->{option_results}->{critical_status}) && $instance_mode->{option_results}->{critical_status} ne '' && + eval "$instance_mode->{option_results}->{critical_status}") { + $status = 'critical'; + } elsif (defined($instance_mode->{option_results}->{warning_status}) && $instance_mode->{option_results}->{warning_status} ne '' && + eval "$instance_mode->{option_results}->{warning_status}") { + $status = 'warning'; + } + }; + if (defined($message)) { + $self->{output}->output_add(long_msg => 'filter status issue: ' . $message); + } + + return $status; +} + +sub custom_status_output { + my ($self, %options) = @_; + + my $msg = sprintf("Status is '%s' [shard list: %s] [int addr: %s] [ext addr: %s]", + $self->{result_values}->{status}, + $self->{result_values}->{shard_list}, + $self->{result_values}->{int_addr}, + $self->{result_values}->{ext_addr}); + return $msg; +} + +sub custom_status_calc { + my ($self, %options) = @_; + + $self->{result_values}->{status} = $options{new_datas}->{$self->{instance} . '_status'}; + $self->{result_values}->{shard_list} = $options{new_datas}->{$self->{instance} . '_shard_list'}; + $self->{result_values}->{int_addr} = $options{new_datas}->{$self->{instance} . '_int_addr'}; + $self->{result_values}->{ext_addr} = $options{new_datas}->{$self->{instance} . '_ext_addr'}; + return 0; +} + +sub prefix_output { + my ($self, %options) = @_; + + return "Node '" . $options{instance_value}->{display} . "' "; +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'nodes', type => 1, cb_prefix_output => 'prefix_output', message_separator => ', ', message_multiple => 'All nodes counters are ok' }, + ]; + + $self->{maps_counters}->{nodes} = [ + { label => 'status', threshold => 0, set => { + key_values => [ { name => 'status' }, { name => 'shard_list' }, { name => 'int_addr' }, { name => 'ext_addr' } ], + closure_custom_calc => $self->can('custom_status_calc'), + closure_custom_output => $self->can('custom_status_output'), + closure_custom_perfdata => sub { return 0; }, + closure_custom_threshold_check => $self->can('custom_status_threshold'), + } + }, + { label => 'shard-count', set => { + key_values => [ { name => 'shard_count' }, { name => 'display' } ], + output_template => 'Shard count: %d', + perfdatas => [ + { label => 'shard_count', value => 'shard_count_absolute', template => '%d', + min => 0, label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + }, + }, + { label => 'uptime', set => { + key_values => [ { name => 'uptime' }, { name => 'uptime_sec' }, { name => 'display' } ], + output_template => 'Uptime: %s', + perfdatas => [ + { label => 'uptime', value => 'uptime_sec_absolute', template => '%d', + min => 0, unit => 's', label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + }, + }, + { label => 'cpu-system', set => { + key_values => [ { name => 'cpu_system' }, { name => 'display' } ], + output_template => 'Cpu system: %.2f %%', + perfdatas => [ + { label => 'cpu_system', value => 'cpu_system_absolute', template => '%.2f', + min => 0, max => 100, unit => '%', label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + { label => 'cpu-user', set => { + key_values => [ { name => 'cpu_user' }, { name => 'display' } ], + output_template => 'Cpu user: %.2f %%', + perfdatas => [ + { label => 'cpu_user', value => 'cpu_user_absolute', template => '%.2f', + min => 0, max => 100, unit => '%', label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + { label => 'memory', set => { + key_values => [ { name => 'free_memory' }, { name => 'total_memory' } ], + closure_custom_calc => $self->can('custom_usage_calc'), + closure_custom_calc_extra_options => { display => 'Ram', label => 'memory', perf => 'memory', + free => 'free_memory', total => 'total_memory' }, + closure_custom_output => $self->can('custom_usage_output'), + closure_custom_perfdata => $self->can('custom_usage_perfdata'), + closure_custom_threshold_check => $self->can('custom_usage_threshold'), + } + }, + { label => 'persistent-storage', set => { + key_values => [ { name => 'persistent_storage_free' }, { name => 'persistent_storage_size' } ], + closure_custom_calc => $self->can('custom_usage_calc'), + closure_custom_calc_extra_options => { display => 'Persistent storage', label => 'persistent-storage', perf => 'persistent_storage', + free => 'persistent_storage_free', total => 'persistent_storage_size' }, + closure_custom_output => $self->can('custom_usage_output'), + closure_custom_perfdata => $self->can('custom_usage_perfdata'), + closure_custom_threshold_check => $self->can('custom_usage_threshold'), + } + }, + { label => 'ephemeral-storage', set => { + key_values => [ { name => 'ephemeral_storage_free' }, { name => 'ephemeral_storage_size' } ], + closure_custom_calc => $self->can('custom_usage_calc'), + closure_custom_calc_extra_options => { display => 'Ephemeral storage', label => 'ephemeral-storage', perf => 'ephemeral_storage', + free => 'ephemeral_storage_free', total => 'ephemeral_storage_size' }, + closure_custom_output => $self->can('custom_usage_output'), + closure_custom_perfdata => $self->can('custom_usage_perfdata'), + closure_custom_threshold_check => $self->can('custom_usage_threshold'), + } + }, + { label => 'flash-storage', set => { + key_values => [ { name => 'bigstore_free' }, { name => 'bigstore_size' } ], + closure_custom_calc => $self->can('custom_usage_calc'), + closure_custom_calc_extra_options => { display => 'Flash storage', label => 'flash-storage', perf => 'flash_storage', + free => 'bigstore_free', total => 'bigstore_size' }, + closure_custom_output => $self->can('custom_usage_output'), + closure_custom_perfdata => $self->can('custom_usage_perfdata'), + closure_custom_threshold_check => $self->can('custom_usage_threshold'), + } + }, + { label => 'flash-iops', set => { + key_values => [ { name => 'bigstore_iops' }, { name => 'display' } ], + output_template => 'Flash IOPS: %s ops/s', + perfdatas => [ + { label => 'flash_iops', value => 'bigstore_iops_absolute', template => '%s', + min => 0, unit => 'ops/s', label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + { label => 'flash-throughput', set => { + key_values => [ { name => 'bigstore_throughput' }, { name => 'display' } ], + output_template => 'Flash throughput: %s %s/s', + output_change_bytes => 1, + perfdatas => [ + { label => 'flash_throughput', value => 'bigstore_throughput_absolute', template => '%s', + min => 0, unit => 'B/s', label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + { label => 'connections', set => { + key_values => [ { name => 'conns' }, { name => 'display' } ], + output_template => 'Connections: %s', + perfdatas => [ + { label => 'connections', value => 'conns_absolute', template => '%s', + min => 0, label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + { label => 'requests', set => { + key_values => [ { name => 'total_req' } ], + output_template => 'Requests rate: %s ops/s', + perfdatas => [ + { label => 'requests', value => 'total_req_absolute', template => '%s', + min => 0, unit => 'ops/s' }, + ], + } + }, + { label => 'traffic-in', set => { + key_values => [ { name => 'ingress' }, { name => 'display' } ], + output_template => 'Traffic In: %s %s/s', + output_change_bytes => 2, + perfdatas => [ + { label => 'traffic_in', value => 'ingress_absolute', template => '%d', + min => 0, unit => 'b/s', label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + }, + }, + { label => 'traffic-out', set => { + key_values => [ { name => 'egress' }, { name => 'display' } ], + output_template => 'Traffic Out: %s %s/s', + output_change_bytes => 2, + perfdatas => [ + { label => 'traffic_out', value => 'egress_absolute', template => '%d', + min => 0, unit => 'b/s', 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-node:s" => { name => 'filter_node' }, + "units:s" => { name => 'units', default => '%' }, + "free" => { name => 'free' }, + "warning-status:s" => { name => 'warning_status', default => '' }, + "critical-status:s" => { name => 'critical_status', default => '%{status} =~ /down/i' }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::check_options(%options); + + $instance_mode = $self; + $self->change_macros(); +} + +sub change_macros { + my ($self, %options) = @_; + + foreach (('warning_status', 'critical_status')) { + if (defined($self->{option_results}->{$_})) { + $self->{option_results}->{$_} =~ s/%\{(.*?)\}/\$self->{result_values}->{$1}/g; + } + } +} + +sub manage_selection { + my ($self, %options) = @_; + + my $result = $options{custom}->get(path => '/v1/nodes/stats/last?interval='.$options{custom}->get_interval()); + my $result2 = $options{custom}->get(path => '/v1/nodes'); + + foreach my $node (keys $result) { + if (defined($self->{option_results}->{filter_node}) && $self->{option_results}->{filter_node} ne '' && + $node !~ /$self->{option_results}->{filter_node}/) { + $self->{output}->output_add(long_msg => "skipping node '" . $node . "': no matching filter.", debug => 1); + next; + } + + my $shard_list = '-'; + if (@{$result2->{$node}->{shard_list}}) { + $shard_list = join(", ", @{$result2->{$node}->{shard_list}}); + } + my $ext_addr = '-'; + if (@{$result2->{$node}->{external_addr}}) { + $ext_addr = join(", ", @{$result2->{$node}->{external_addr}}); + } + + $self->{nodes}->{$node} = { + display => $node, + status => defined($result2->{$node}->{status}) ? $result2->{$node}->{status} : '-', + shard_list => $shard_list, + shard_count => $result2->{$node}->{shard_count}, + int_addr => $result2->{$node}->{addr}, + ext_addr => $ext_addr, + uptime => centreon::plugins::misc::change_seconds(value => $result2->{$node}->{uptime}), + uptime_sec => $result2->{$node}->{uptime}, + cpu_system => $result->{$node}->{cpu_system} * 100, + cpu_user => $result->{$node}->{cpu_user} * 100, + free_memory => $result->{$node}->{free_memory}, + total_memory => $result2->{$node}->{total_memory}, + persistent_storage_free => $result->{$node}->{persistent_storage_free}, + persistent_storage_size => $result2->{$node}->{persistent_storage_size}, + ephemeral_storage_free => $result->{$node}->{ephemeral_storage_free}, + ephemeral_storage_size => $result2->{$node}->{ephemeral_storage_size}, + bigstore_free => $result->{$node}->{bigstore_free}, + bigstore_size => $result2->{$node}->{bigstore_size}, + bigstore_iops => $result->{$node}->{bigstore_iops}, + bigstore_throughput => $result->{$node}->{bigstore_throughput}, + conns => $result->{$node}->{conns}, + total_req => $result->{$node}->{total_req}, + ingress => $result->{$node}->{ingress_bytes} * 8, + egress => $result->{$node}->{egress_bytes} * 8, + }; + + if (scalar(keys %{$self->{nodes}}) <= 0) { + $self->{output}->add_option_msg(short_msg => 'No nodes detected, check your filter ? '); + $self->{output}->option_exit(); + } + } +} + +1; + +__END__ + +=head1 MODE + +Check RedisLabs Enterprise Cluster nodes statistics. + +=over 8 + +=item B<--filter-counters> + +Only display some counters (regexp can be used). +Example: --filter-counters='^cpu' + +=item B<--units> + +Units of thresholds (Default: '%') ('%', 'B'). + +=item B<--free> + +Thresholds are on free space left. + +=item B<--warning-status> + +Set warning threshold for status. +Can used special variables like: %{status}, %{shard_list}, +%{int_addr}, %{ext_addr}. +'status' can be: 'active', 'going_offline', 'offline', +'provisioning', 'decommissioning', 'down'. + +=item B<--critical-status> + +Set critical threshold for status (Default: '%{status} =~ /down/i'). +Can used special variables like: %{status}, %{shard_list}, +%{int_addr}, %{ext_addr}. +'status' can be: 'active', 'going_offline', 'offline', +'provisioning', 'decommissioning', 'down'. + +=item B<--warning-*> + +Threshold warning. +Can be: 'cpu-system', 'cpu-user', +'requests', 'memory', 'flash-storage', +'persistent-storage', 'ephemeral-storage', +'flash-iops', 'flash-throughput', 'connections', +'traffic-in', 'traffic-out', 'shard-count', 'uptime'. + +=item B<--critical-*> + +Threshold critical. +Can be: 'cpu-system', 'cpu-user', +'requests', 'memory', 'flash-storage', +'persistent-storage', 'ephemeral-storage', +'flash-iops', 'flash-throughput', 'connections', +'traffic-in', 'traffic-out', 'shard-count', 'uptime'. + +=back + +=cut diff --git a/centreon-plugins/apps/redis/restapi/mode/shardsstats.pm b/centreon-plugins/apps/redis/restapi/mode/shardsstats.pm new file mode 100644 index 000000000..cff2cb218 --- /dev/null +++ b/centreon-plugins/apps/redis/restapi/mode/shardsstats.pm @@ -0,0 +1,472 @@ +# +# Copyright 2017 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::redis::restapi::mode::shardsstats; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; +use Digest::MD5 qw(md5_hex); + +my $instance_mode; + +sub custom_status_threshold { + my ($self, %options) = @_; + my $status = 'ok'; + my $message; + + eval { + local $SIG{__WARN__} = sub { $message = $_[0]; }; + local $SIG{__DIE__} = sub { $message = $_[0]; }; + + if (defined($instance_mode->{option_results}->{critical_status}) && $instance_mode->{option_results}->{critical_status} ne '' && + eval "$instance_mode->{option_results}->{critical_status}") { + $status = 'critical'; + } elsif (defined($instance_mode->{option_results}->{warning_status}) && $instance_mode->{option_results}->{warning_status} ne '' && + eval "$instance_mode->{option_results}->{warning_status}") { + $status = 'warning'; + } + }; + if (defined($message)) { + $self->{output}->output_add(long_msg => 'filter status issue: ' . $message); + } + + return $status; +} + +sub custom_status_output { + my ($self, %options) = @_; + + my $msg = sprintf("Status is '%s' (%s) [role: %s] [loading status: %s] [backup status: %s]", + $self->{result_values}->{status}, + $self->{result_values}->{detailed_status}, + $self->{result_values}->{role}, + $self->{result_values}->{loading}, + $self->{result_values}->{backup}); + if ($self->{result_values}->{role} eq 'slave') { + $msg .= sprintf(" [sync status: %s]", + $self->{result_values}->{sync}); + } + return $msg; +} + +sub custom_status_calc { + my ($self, %options) = @_; + + $self->{result_values}->{role} = $options{new_datas}->{$self->{instance} . '_role'}; + $self->{result_values}->{status} = $options{new_datas}->{$self->{instance} . '_status'}; + $self->{result_values}->{detailed_status} = $options{new_datas}->{$self->{instance} . '_detailed_status'}; + $self->{result_values}->{loading} = $options{new_datas}->{$self->{instance} . '_loading'}; + $self->{result_values}->{sync} = $options{new_datas}->{$self->{instance} . '_sync'}; + $self->{result_values}->{backup} = $options{new_datas}->{$self->{instance} . '_backup'}; + return 0; +} + +sub custom_operations_output { + my ($self, %options) = @_; + + my $msg = sprintf("%s operations rates (hits/misses): %s/%s ops/s", + $self->{result_values}->{operation}, + $self->{result_values}->{hits}, + $self->{result_values}->{misses}); + return $msg; +} + +sub custom_operations_calc { + my ($self, %options) = @_; + + $self->{result_values}->{display} = $options{new_datas}->{$self->{instance} . '_' . $options{extra_options}->{display}}; + $self->{result_values}->{operation} = $options{extra_options}->{operation}; + $self->{result_values}->{hits} = $options{new_datas}->{$self->{instance} . '_' . $options{extra_options}->{hits}}; + $self->{result_values}->{misses} = $options{new_datas}->{$self->{instance} . '_' . $options{extra_options}->{misses}}; + return 0; +} + +sub custom_cpu_output { + my ($self, %options) = @_; + + my $msg = sprintf("%s CPU usage (user/system): %s/%s %%", + $self->{result_values}->{cpu}, + $self->{result_values}->{user}, + $self->{result_values}->{system}); + return $msg; +} + +sub custom_cpu_calc { + my ($self, %options) = @_; + + $self->{result_values}->{display} = $options{new_datas}->{$self->{instance} . '_' . $options{extra_options}->{display}}; + $self->{result_values}->{cpu} = $options{extra_options}->{cpu}; + $self->{result_values}->{user} = $options{new_datas}->{$self->{instance} . '_' . $options{extra_options}->{user}}; + $self->{result_values}->{system} = $options{new_datas}->{$self->{instance} . '_' . $options{extra_options}->{system}}; + return 0; +} + +sub prefix_output { + my ($self, %options) = @_; + + return "Shard '" . $options{instance_value}->{display} . "' "; +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'shards', type => 1, cb_prefix_output => 'prefix_output', message_multiple => 'All shards counters are ok' }, + ]; + + $self->{maps_counters}->{shards} = [ + { label => 'status', threshold => 0, set => { + key_values => [ { name => 'status' }, { name => 'detailed_status' }, { name => 'role' }, + { name => 'loading' }, { name => 'sync' }, { name => 'backup' } ], + closure_custom_calc => $self->can('custom_status_calc'), + closure_custom_output => $self->can('custom_status_output'), + closure_custom_perfdata => sub { return 0; }, + closure_custom_threshold_check => $self->can('custom_status_threshold'), + } + }, + { label => 'total-cpu', set => { + key_values => [ { name => 'shard_cpu_user' }, { name => 'shard_cpu_system' }, { name => 'display' } ], + closure_custom_calc => $self->can('custom_cpu_calc'), + closure_custom_calc_extra_options => { cpu => 'Total', user => 'shard_cpu_user', + system => 'shard_cpu_system', display => 'display' }, + closure_custom_output => $self->can('custom_cpu_output'), + perfdatas => [ + { label => 'total_cpu_user', value => 'user', template => '%s', + min => 0, max => 100, unit => '%', label_extra_instance => 1, instance_use => 'display' }, + { label => 'total_cpu_system', value => 'system', template => '%s', + min => 0, max => 100, unit => '%', label_extra_instance => 1, instance_use => 'display' }, + ], + } + }, + { label => 'fork-cpu', set => { + key_values => [ { name => 'fork_cpu_user' }, { name => 'fork_cpu_system' }, { name => 'display' } ], + closure_custom_calc => $self->can('custom_cpu_calc'), + closure_custom_calc_extra_options => { cpu => 'Fork', user => 'fork_cpu_user', + system => 'fork_cpu_system', display => 'display' }, + closure_custom_output => $self->can('custom_cpu_output'), + perfdatas => [ + { label => 'fork_cpu_user', value => 'user', template => '%s', + min => 0, max => 100, unit => '%', label_extra_instance => 1, instance_use => 'display' }, + { label => 'fork_cpu_system', value => 'system', template => '%s', + min => 0, max => 100, unit => '%', label_extra_instance => 1, instance_use => 'display' }, + ], + } + }, + { label => 'main-thread-cpu', set => { + key_values => [ { name => 'main_thread_cpu_user' }, { name => 'main_thread_cpu_system' }, { name => 'display' } ], + closure_custom_calc => $self->can('custom_cpu_calc'), + closure_custom_calc_extra_options => { cpu => 'Main thread', user => 'main_thread_cpu_user', + system => 'main_thread_cpu_system', display => 'display' }, + closure_custom_output => $self->can('custom_cpu_output'), + perfdatas => [ + { label => 'main_thread_cpu_user', value => 'user', template => '%s', + min => 0, max => 100, unit => '%', label_extra_instance => 1, instance_use => 'display' }, + { label => 'main_thread_cpu_system', value => 'system', template => '%s', + min => 0, max => 100, unit => '%', label_extra_instance => 1, instance_use => 'display' }, + ], + } + }, + { label => 'memory', set => { + key_values => [ { name => 'used_memory' }, { name => 'display' } ], + output_template => 'Memory used: %s %s', + output_change_bytes => 1, + perfdatas => [ + { label => 'memory', value => 'used_memory_absolute', template => '%s', + min => 0, unit => 'B', label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + { label => 'mem-frag-ratio', set => { + key_values => [ { name => 'mem_frag_ratio' }, { name => 'display' } ], + output_template => 'Memory fragmentation ratio: %s', + perfdatas => [ + { label => 'mem_frag_ratio', value => 'mem_frag_ratio_absolute', template => '%s', + min => 0, label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + { label => 'connected-clients', set => { + key_values => [ { name => 'connected_clients' }, { name => 'display' } ], + output_template => 'Connected clients: %s', + perfdatas => [ + { label => 'connected_clients', value => 'connected_clients_absolute', template => '%s', + min => 0, label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + { label => 'blocked-clients', set => { + key_values => [ { name => 'blocked_clients' }, { name => 'display' } ], + output_template => 'Blocked clients: %s', + perfdatas => [ + { label => 'blocked_clients', value => 'blocked_clients_absolute', template => '%s', + min => 0, label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + { label => 'requests', set => { + key_values => [ { name => 'total_req'}, { name => 'display' }], + output_template => 'Requests rate: %s ops/s', + perfdatas => [ + { label => 'requests', value => 'total_req_absolute', template => '%s', + min => 0, unit => 'ops/s', label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + { label => 'keys', set => { + key_values => [ { name => 'no_of_keys' }, { name => 'display' } ], + output_template => 'Total keys: %s', + perfdatas => [ + { label => 'keys', value => 'no_of_keys_absolute', template => '%s', + min => 0, label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + { label => 'volatile-keys', set => { + key_values => [ { name => 'no_of_expires' }, { name => 'display' } ], + output_template => 'Volatile keys: %s', + perfdatas => [ + { label => 'volatile_keys', value => 'no_of_expires_absolute', template => '%s', + min => 0, label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + { label => 'evicted-objects', set => { + key_values => [ { name => 'evicted_objects' }, { name => 'display' } ], + output_template => 'Evicted objects rate: %s evictions/sec', + perfdatas => [ + { label => 'evicted_objects', value => 'evicted_objects_absolute', template => '%s', + min => 0, unit => 'evictions/sec', label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + { label => 'expired-objects', set => { + key_values => [ { name => 'expired_objects' }, { name => 'display' } ], + output_template => 'Expired objects rate: %s expirations/sec', + perfdatas => [ + { label => 'expired_objects', value => 'expired_objects_absolute', template => '%s', + min => 0, unit => 'expirations/sec', label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + { label => 'read-rates', set => { + key_values => [ { name => 'read_hits' }, { name => 'read_misses' }, { name => 'display' } ], + closure_custom_calc => $self->can('custom_operations_calc'), + closure_custom_calc_extra_options => { operation => 'Read', hits => 'read_hits', + misses => 'read_misses', display => 'display' }, + closure_custom_output => $self->can('custom_operations_output'), + perfdatas => [ + { label => 'read_hits', value => 'hits', template => '%s', + min => 0, unit => 'ops/s', label_extra_instance => 1, instance_use => 'display' }, + { label => 'read_misses', value => 'misses', template => '%s', + min => 0, unit => 'ops/s', label_extra_instance => 1, instance_use => 'display' }, + ], + } + }, + { label => 'write-rates', set => { + key_values => [ { name => 'write_hits' }, { name => 'write_misses' }, { name => 'display' } ], + closure_custom_calc => $self->can('custom_operations_calc'), + closure_custom_calc_extra_options => { operation => 'Write', hits => 'write_hits', + misses => 'write_misses', display => 'display' }, + closure_custom_output => $self->can('custom_operations_output'), + perfdatas => [ + { label => 'write_hits', value => 'hits', template => '%s', + min => 0, unit => 'ops/s', label_extra_instance => 1, instance_use => 'display' }, + { label => 'write_misses', value => 'misses', template => '%s', + min => 0, unit => 'ops/s', label_extra_instance => 1, instance_use => 'display' }, + ], + } + }, + { label => 'rdb-changes-since-last-save', set => { + key_values => [ { name => 'rdb_changes_since_last_save' }, { name => 'display' } ], + output_template => 'Rdb changes since last save: %s', + perfdatas => [ + { label => 'rdb_changes_since_last_save', value => 'rdb_changes_since_last_save_absolute', template => '%s', + min => 0, label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + { label => 'last-save-time', set => { + key_values => [ { name => 'last_save_time' }, { name => 'last_save_time_sec' }, { name => 'display' } ], + output_template => 'Last same time: %s', + perfdatas => [ + { label => 'last_save_time', value => 'last_save_time_sec_absolute', template => '%s', + min => 0, unit => 's', 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-shard:s" => { name => 'filter_shard' }, + "warning-status:s" => { name => 'warning_status', default => '' }, + "critical-status:s" => { name => 'critical_status', default => '%{status} =~ /inactive/i | %{backup} =~ /failed/i | + %{sync} =~ /link_down/i' }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::check_options(%options); + + $instance_mode = $self; + $self->change_macros(); +} + +sub change_macros { + my ($self, %options) = @_; + + foreach (('warning_status', 'critical_status')) { + if (defined($self->{option_results}->{$_})) { + $self->{option_results}->{$_} =~ s/%\{(.*?)\}/\$self->{result_values}->{$1}/g; + } + } +} + +sub manage_selection { + my ($self, %options) = @_; + + my $result = $options{custom}->get(path => '/v1/shards/stats/last?interval='.$options{custom}->get_interval()); + my $result2 = $options{custom}->get(path => '/v1/shards'); + + foreach my $shard (keys $result) { + if (defined($self->{option_results}->{filter_shard}) && $self->{option_results}->{filter_shard} ne '' && + $shard !~ /$self->{option_results}->{filter_shard}/) { + $self->{output}->output_add(long_msg => "skipping shard '" . $shard . "': no matching filter.", debug => 1); + next; + } + + $self->{shards}->{$shard} = { + display => $shard, + status => defined($result2->{$shard}->{status}) ? $result2->{$shard}->{status} : '-', + detailed_status => defined($result2->{$shard}->{detailed_status}) ? $result2->{$shard}->{detailed_status} : '-', + role => defined($result2->{$shard}->{role}) ? $result2->{$shard}->{role} : '-', + loading => defined($result2->{$shard}->{loading}->{status}) ? $result2->{$shard}->{loading}->{status} : '-', + sync => defined($result2->{$shard}->{sync}->{status}) ? $result2->{$shard}->{sync}->{status} : '-', + backup => defined($result2->{$shard}->{backup}->{status}) ? $result2->{$shard}->{backup}->{status} : '-', + used_memory => $result->{$shard}->{used_memory}, + mem_frag_ratio => $result->{$shard}->{mem_frag_ratio}, + shard_cpu_user => $result->{$shard}->{shard_cpu_user} * 100, + shard_cpu_system => $result->{$shard}->{shard_cpu_system} * 100, + main_thread_cpu_user => $result->{$shard}->{main_thread_cpu_user} * 100, + main_thread_cpu_system => $result->{$shard}->{main_thread_cpu_system} * 100, + fork_cpu_user => $result->{$shard}->{fork_cpu_user} * 100, + fork_cpu_system => $result->{$shard}->{fork_cpu_system} * 100, + connected_clients => $result->{$shard}->{connected_clients}, + blocked_clients => $result->{$shard}->{blocked_clients}, + total_req => defined($result->{$shard}->{total_req}) ? $result->{$shard}->{total_req} : $result->{$shard}->{instantaneous_ops_per_sec}, + no_of_keys => $result->{$shard}->{no_of_keys}, + no_of_expires => $result->{$shard}->{no_of_expires}, + evicted_objects => $result->{$shard}->{evicted_objects}, + expired_objects => $result->{$shard}->{expired_objects}, + read_hits => $result->{$shard}->{read_hits}, + read_misses => $result->{$shard}->{read_misses}, + write_hits => $result->{$shard}->{write_hits}, + write_misses => $result->{$shard}->{write_misses}, + rdb_changes_since_last_save => $result->{$shard}->{rdb_changes_since_last_save}, + last_save_time => centreon::plugins::misc::change_seconds(value => time() - $result->{$shard}->{last_save_time}), + last_save_time_sec => time() - $result->{$shard}->{last_save_time}, + }; + + if (scalar(keys %{$self->{shards}}) <= 0) { + $self->{output}->add_option_msg(short_msg => 'No shards detected, check your filter ? '); + $self->{output}->option_exit(); + } + } +} + +1; + +__END__ + +=head1 MODE + +Check RedisLabs Enterprise Cluster shards statistics. + +=over 8 + +=item B<--filter-counters> + +Only display some counters (regexp can be used). +Example: --filter-counters='clients' + +=item B<--warning-status> + +Set warning threshold for status. +Can used special variables like: %{status}, %{detailed_status}, +%{role}, %{loading}, %{sync}, %{backup}. +'status' can be: 'active', 'inactive', 'trimming'. +'detailed_status' can be: 'ok', 'importing', 'timeout', +'loading', 'busy', 'down', 'trimming', 'unknown'. +'role' can be: 'slave', 'master'. +'loading' can be: 'in_progress', 'idle'. +'sync' can be: 'in_progress', 'idle', 'link_down'. +'backup' can be: 'exporting', 'succeeded', 'failed'. + +=item B<--critical-status> + +Set critical threshold for status (Default: '%{status} =~ /inactive/i | +%{backup} =~ /failed/i | %{sync} =~ /link_down/i'). +Can used special variables like: %{status}, %{detailed_status}, +%{role}, %{loading}, %{sync}, %{backup}. +'status' can be: 'active', 'inactive', 'trimming'. +'detailed_status' can be: 'ok', 'importing', 'timeout', +'loading', 'busy', 'down', 'trimming', 'unknown'. +'role' can be: 'slave', 'master'. +'loading' can be: 'in_progress', 'idle'. +'sync' can be: 'in_progress', 'idle', 'link_down'. +'backup' can be: 'exporting', 'succeeded', 'failed'. + +=item B<--warning-*> + +Threshold warning. +Can be: 'total-cpu', 'fork-cpu', 'main-thread-cpu', +'memory', 'mem-frag-ratio', +'connected-clients', 'blocked-clients', +'request', 'keys', +'evicted-objects', 'expired-objects', +'read-rates', 'write-rates', +'rdb-changes-since-last-save', 'last-save-time', + +=item B<--critical-*> + +Threshold critical. +Can be: 'total-cpu', 'fork-cpu', 'main-thread-cpu', +'memory', 'mem-frag-ratio', +'connected-clients', 'blocked-clients', +'request', 'keys', +'evicted-objects', 'expired-objects', +'read-rates', 'write-rates', +'rdb-changes-since-last-save', 'last-save-time', + +=back + +=cut diff --git a/centreon-plugins/apps/redis/restapi/plugin.pm b/centreon-plugins/apps/redis/restapi/plugin.pm new file mode 100644 index 000000000..2d94ada50 --- /dev/null +++ b/centreon-plugins/apps/redis/restapi/plugin.pm @@ -0,0 +1,54 @@ +# +# Copyright 2017 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::redis::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; + + $self->{version} = '0.1'; + %{$self->{modes}} = ( + 'databases-stats' => 'apps::redis::restapi::mode::databasesstats', + 'cluster-stats' => 'apps::redis::restapi::mode::clusterstats', + 'list-databases' => 'apps::redis::restapi::mode::listdatabases', + 'list-nodes' => 'apps::redis::restapi::mode::listnodes', + 'list-shards' => 'apps::redis::restapi::mode::listshards', + 'nodes-stats' => 'apps::redis::restapi::mode::nodesstats', + 'shards-stats' => 'apps::redis::restapi::mode::shardsstats', + ); + $self->{custom_modes}{api} = 'apps::redis::restapi::custom::api'; + return $self; +} + +1; + +__END__ + +=head1 PLUGIN DESCRIPTION + +Check RedisLabs Enterprise Cluster through HTTP/REST API. + +=cut diff --git a/centreon-plugins/apps/tomcat/jmx/mode/connectorusage.pm b/centreon-plugins/apps/tomcat/jmx/mode/connectorusage.pm index cea015621..4ab1dedbc 100644 --- a/centreon-plugins/apps/tomcat/jmx/mode/connectorusage.pm +++ b/centreon-plugins/apps/tomcat/jmx/mode/connectorusage.pm @@ -197,7 +197,8 @@ sub manage_selection { $self->{tomcatconnector} = {}; foreach my $key (keys %$result) { $key =~ /name=(.*?),type=(.*)/; - my ($connector, $type) = ($1, $2); + my ($connector, $type) = ($1, $2); # double quote nivo du name si existe + $connector =~ s/^"(.*)"$/$1/g; if (defined($self->{option_results}->{filter_name}) && $self->{option_results}->{filter_name} ne '' && $connector !~ /$self->{option_results}->{filter_name}/) { @@ -212,7 +213,7 @@ sub manage_selection { $self->{tomcatconnector}->{$connector} = { %{$self->{tomcatconnector}->{$connector}}, %{$result->{$key}} }; } - $self->{cache_name} = "tomcat_" . $self->{mode} . '_' . md5_hex($options{custom}->{url}) . '_' . + $self->{cache_name} = "tomcat_" . $self->{mode} . '_' . md5_hex($options{custom}->get_connection_info()) . '_' . (defined($self->{option_results}->{filter_counters}) ? md5_hex($self->{option_results}->{filter_counters}) : md5_hex('all')) . '_' . (defined($self->{option_results}->{filter_name}) ? md5_hex($self->{option_results}->{filter_name}) : md5_hex('all')); } diff --git a/centreon-plugins/apps/tomcat/jmx/mode/datasourceusage.pm b/centreon-plugins/apps/tomcat/jmx/mode/datasourceusage.pm new file mode 100644 index 000000000..e43485452 --- /dev/null +++ b/centreon-plugins/apps/tomcat/jmx/mode/datasourceusage.pm @@ -0,0 +1,234 @@ +# +# Copyright 2017 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::tomcat::jmx::mode::datasourceusage; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; +use Digest::MD5 qw(md5_hex); + +my $instance_mode; + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'datasource', type => 1, cb_prefix_output => 'prefix_ds_output', message_multiple => 'All datasources are ok' }, + ]; + + $self->{maps_counters}->{datasource} = [ + { label => 'num-active', set => { + key_values => [ { name => 'numActive' }, { name => 'maxActive' }, { name => 'display' } ], + closure_custom_calc => $self->can('custom_usage_calc'), + closure_custom_calc_extra_options => { label_ref => 'Active', message => 'Current Num Active' }, + closure_custom_output => $self->can('custom_usage_output'), + closure_custom_threshold_check => $self->can('custom_usage_threshold'), + closure_custom_perfdata => $self->can('custom_usage_perfdata'), + } + }, + { label => 'num-idle', set => { + key_values => [ { name => 'numIdle' }, { name => 'maxIdle' }, { name => 'display' } ], + closure_custom_calc => $self->can('custom_usage_calc'), + closure_custom_calc_extra_options => { label_ref => 'Idle', message => 'Current Num Idle' }, + closure_custom_output => $self->can('custom_usage_output'), + closure_custom_threshold_check => $self->can('custom_usage_threshold'), + closure_custom_perfdata => $self->can('custom_usage_perfdata'), + } + }, + ]; +} + +sub custom_usage_perfdata { + my ($self, %options) = @_; + + my $use_th = 1; + $use_th = 0 if ($instance_mode->{option_results}->{units} eq '%' && $self->{result_values}->{max} <= 0); + + my $extra_label = ''; + $extra_label = '_' . $self->{result_values}->{display} if (!defined($options{extra_instance}) || $options{extra_instance} != 0); + + my $value_perf = $self->{result_values}->{used}; + my %total_options = (); + if ($instance_mode->{option_results}->{units} eq '%' && $self->{result_values}->{max} > 0) { + $total_options{total} = $self->{result_values}->{max}; + $total_options{cast_int} = 1; + } + + my $label = $self->{label}; + $label =~ s/-/_/g; + $self->{output}->perfdata_add(label => $label . $extra_label, + value => $value_perf, + warning => $use_th == 1 ? $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{label}, %total_options) : undef, + critical => $use_th == 1 ? $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{label}, %total_options) : undef, + min => 0, max => $self->{result_values}->{max} > 0 ? $self->{result_values}->{max} : undef); +} + +sub custom_usage_threshold { + my ($self, %options) = @_; + + # Cannot use percent without total + return 'ok' if ($self->{result_values}->{max} <= 0 && $instance_mode->{option_results}->{units} eq '%'); + my ($exit, $threshold_value); + $threshold_value = $self->{result_values}->{used}; + if ($instance_mode->{option_results}->{units} eq '%') { + $threshold_value = $self->{result_values}->{prct_used}; + } + $exit = $self->{perfdata}->threshold_check(value => $threshold_value, 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 $msg; + if ($self->{result_values}->{max} > 0) { + $msg = sprintf("%s Total: %s Used: %s (%.2f%%) Free: %s (%.2f%%)", + $self->{result_values}->{message}, $self->{result_values}->{max}, + $self->{result_values}->{used}, $self->{result_values}->{prct_used}, + $self->{result_values}->{max} - $self->{result_values}->{used}, 100 - $self->{result_values}->{prct_used}); + } else { + $msg = sprintf("%s : %s", $self->{result_values}->{message}, $self->{result_values}->{used}); + } + return $msg; +} + +sub custom_usage_calc { + my ($self, %options) = @_; + + $self->{result_values}->{display} = $options{new_datas}->{$self->{instance} . '_display'}; + $self->{result_values}->{message} = $options{extra_options}->{message}; + $self->{result_values}->{max} = $options{new_datas}->{$self->{instance} . '_max' . $options{extra_options}->{label_ref}}; + $self->{result_values}->{used} = $options{new_datas}->{$self->{instance} . '_num' . $options{extra_options}->{label_ref}}; + if ($self->{result_values}->{max} > 0) { + $self->{result_values}->{prct_used} = $self->{result_values}->{used} * 100 / $self->{result_values}->{max}; + } + + return 0; +} + +sub prefix_ds_output { + my ($self, %options) = @_; + + return "Datasource '" . $options{instance_value}->{display} . "' "; +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options, statefile => 1); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => + { + "filter-name:s" => { name => 'filter_name' }, + "units:s" => { name => 'units', default => '%' }, + }); + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::check_options(%options); + + $instance_mode = $self; +} + +sub manage_selection { + my ($self, %options) = @_; + + # maxActive or maxTotal + $self->{request} = [ + { mbean => "*:type=DataSource,class=*,context=*,host=*,name=*", attributes => + [ { name => 'numActive' }, { name => 'numIdle' }, { name => 'maxIdle' }, { name => 'maxTotal' }, { name => 'maxActive' } ] }, + { mbean => "*:type=DataSource,class=*,path=*,host=*,name=*", attributes => + [ { name => 'numActive' }, { name => 'numIdle' }, { name => 'maxIdle' }, { name => 'maxTotal' }, { name => 'maxActive' } ] }, + ]; + + my $result = $options{custom}->get_attributes(request => $self->{request}, nothing_quit => 1); + + $self->{datasource} = {}; + foreach my $key (keys %$result) { + $key =~ /(?:[:,])host=(.*?)(?:,|$)/; + my $ds_name = $1; + $key =~ /(?:[:,])(?:path|context)=(.*?)(?:,|$)/; + $ds_name .= '.' . $1; + $key =~ /(?:[:,])name=(.*?)(?:,|$)/; # double quote a virer + my $tmp_name = $1; + $tmp_name =~ s/^"(.*)"$/$1/; + $ds_name .= '.' . $tmp_name; + + if (defined($self->{option_results}->{filter_name}) && $self->{option_results}->{filter_name} ne '' && + $ds_name !~ /$self->{option_results}->{filter_name}/) { + $self->{output}->output_add(long_msg => "skipping '" . $ds_name . "': no matching filter.", debug => 1); + next; + } + + $self->{datasource}->{$ds_name} = { + display => $ds_name, + numActive => $result->{$key}->{numActive}, + maxActive => defined($result->{$key}->{maxTotal}) ? $result->{$key}->{maxTotal} : $result->{$key}->{maxActive}, + numIdle => $result->{$key}->{numIdle}, + maxIdle => $result->{$key}->{maxIdle}, + }; + } + + $self->{cache_name} = "tomcat_" . $self->{mode} . '_' . md5_hex($options{custom}->get_connection_info()) . '_' . + (defined($self->{option_results}->{filter_counters}) ? md5_hex($self->{option_results}->{filter_counters}) : md5_hex('all')) . '_' . + (defined($self->{option_results}->{filter_name}) ? md5_hex($self->{option_results}->{filter_name}) : md5_hex('all')); +} + +1; + +__END__ + +=head1 MODE + +Check data sources usage. + +=over 8 + +=item B<--filter-counters> + +Only display some counters (regexp can be used). +Example: --filter-counters='num-active' + +=item B<--filter-name> + +Filter datasource name (can be a regexp). + +=item B<--warning-*> + +Threshold warning. +Can be: 'num-active', 'num-idle'. + +=item B<--critical-*> + +Threshold critical. +Can be: 'num-active', 'num-idle'. + +=item B<--units> + +Units of thresholds (Default: '%') ('%', 'absolute'). + +=back + +=cut diff --git a/centreon-plugins/apps/tomcat/jmx/mode/listdatasources.pm b/centreon-plugins/apps/tomcat/jmx/mode/listdatasources.pm new file mode 100644 index 000000000..babbeec93 --- /dev/null +++ b/centreon-plugins/apps/tomcat/jmx/mode/listdatasources.pm @@ -0,0 +1,138 @@ +# +# Copyright 2017 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::tomcat::jmx::mode::listdatasources; + +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 => + { + "filter-host:s" => { name => 'filter_host' }, + "filter-path:s" => { name => 'filter_path' }, + }); + $self->{ds} = {}; + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::init(%options); +} + +sub manage_selection { + my ($self, %options) = @_; + + $self->{request} = [ + { mbean => "*:type=DataSource,class=*,context=*,host=*,name=*", attributes => + [ { name => 'numActive' } ] }, + ]; + my $result = $options{custom}->get_attributes(request => $self->{request}); + + foreach my $mbean (keys %{$result}) { + $mbean =~ /(?:[:,])host=(.*?)(?:,|$)/; + my $host = $1; + $mbean =~ /(?:[:,])(?:path|context)=(.*?)(?:,|$)/; + my $path = $1; + $mbean =~ /(?:[:,])name=(.*?)(?:,|$)/; + my $name = $1; + $name =~ s/^"(.*)"$/$1/; + + if (defined($self->{option_results}->{filter_host}) && $self->{option_results}->{filter_host} ne '' && + $host !~ /$self->{option_results}->{filter_host}/) { + $self->{output}->output_add(long_msg => "skipping '" . $host . "': no matching filter.", debug => 1); + next; + } + if (defined($self->{option_results}->{filter_path}) && $self->{option_results}->{filter_path} ne '' && + $path !~ /$self->{option_results}->{filter_path}/) { + $self->{output}->output_add(long_msg => "skipping '" . $path . "': no matching filter.", debug => 1); + next; + } + + $self->{ds}->{$host . '.' . $path} = { + host => $host, path => $path, name => $name, + }; + } +} + +sub run { + my ($self, %options) = @_; + + $self->manage_selection(%options); + foreach my $instance (sort keys %{$self->{ds}}) { + $self->{output}->output_add(long_msg => '[host = ' . $self->{ds}->{$instance}->{host} . "]" . + " [path = '" . $self->{ds}->{$instance}->{path} . "']" . + " [name = '" . $self->{ds}->{$instance}->{name} . "']" + ); + } + + $self->{output}->output_add(severity => 'OK', + short_msg => 'List data sources:'); + $self->{output}->display(nolabel => 1, force_ignore_perfdata => 1, force_long_output => 1); + $self->{output}->exit(); +} + +sub disco_format { + my ($self, %options) = @_; + + $self->{output}->add_disco_format(elements => ['host', 'path', 'name']); +} + +sub disco_show { + my ($self, %options) = @_; + + $self->manage_selection(%options); + foreach my $instance (sort keys %{$self->{ds}}) { + $self->{output}->add_disco_entry( + %{$self->{ds}->{$instance}} + ); + } +} + +1; + +__END__ + +=head1 MODE + +List data sources. + +=over 8 + +=item B<--filter-host> + +Filter by virtual host name (can be a regexp). + +=item B<--filter-path> + +Filter by application name (can be a regexp). + +=back + +=cut + diff --git a/centreon-plugins/apps/tomcat/jmx/mode/listwebapps.pm b/centreon-plugins/apps/tomcat/jmx/mode/listwebapps.pm new file mode 100644 index 000000000..d42afc749 --- /dev/null +++ b/centreon-plugins/apps/tomcat/jmx/mode/listwebapps.pm @@ -0,0 +1,134 @@ +# +# Copyright 2017 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::tomcat::jmx::mode::listwebapps; + +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 => + { + "filter-host:s" => { name => 'filter_host' }, + "filter-path:s" => { name => 'filter_path' }, + }); + $self->{webapps} = {}; + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::init(%options); +} + +sub manage_selection { + my ($self, %options) = @_; + + $self->{request} = [ + { mbean => "*:context=*,host=*,type=Manager", attributes => [ { name => 'activeSessions' } ] }, + { mbean => "*:path=*,host=*,type=Manager", attributes => [ { name => 'activeSessions' } ] }, + ]; + my $result = $options{custom}->get_attributes(request => $self->{request}); + + foreach my $mbean (keys %{$result}) { + $mbean =~ /(?:[:,])host=(.*?)(?:,|$)/; + my $host = $1; + $mbean =~ /(?:[:,])(?:path|context)=(.*?)(?:,|$)/; + my $path = $1; + + if (defined($self->{option_results}->{filter_host}) && $self->{option_results}->{filter_host} ne '' && + $host !~ /$self->{option_results}->{filter_host}/) { + $self->{output}->output_add(long_msg => "skipping '" . $host . "': no matching filter.", debug => 1); + next; + } + if (defined($self->{option_results}->{filter_path}) && $self->{option_results}->{filter_path} ne '' && + $path !~ /$self->{option_results}->{filter_path}/) { + $self->{output}->output_add(long_msg => "skipping '" . $path . "': no matching filter.", debug => 1); + next; + } + + $self->{webapps}->{$host . '.' . $path} = { + host => $host, path => $path, + }; + } +} + +sub run { + my ($self, %options) = @_; + + $self->manage_selection(%options); + foreach my $instance (sort keys %{$self->{webapps}}) { + $self->{output}->output_add(long_msg => '[host = ' . $self->{webapps}->{$instance}->{host} . "]" . + " [path = '" . $self->{webapps}->{$instance}->{path} . "']" + ); + } + + $self->{output}->output_add(severity => 'OK', + short_msg => 'List webapps:'); + $self->{output}->display(nolabel => 1, force_ignore_perfdata => 1, force_long_output => 1); + $self->{output}->exit(); +} + +sub disco_format { + my ($self, %options) = @_; + + $self->{output}->add_disco_format(elements => ['host', 'path']); +} + +sub disco_show { + my ($self, %options) = @_; + + $self->manage_selection(%options); + foreach my $instance (sort keys %{$self->{webapps}}) { + $self->{output}->add_disco_entry( + %{$self->{webapps}->{$instance}} + ); + } +} + +1; + +__END__ + +=head1 MODE + +List webapps. + +=over 8 + +=item B<--filter-host> + +Filter by virtual host name (can be a regexp). + +=item B<--filter-path> + +Filter by application name (can be a regexp). + +=back + +=cut + diff --git a/centreon-plugins/apps/tomcat/jmx/mode/webappssessions.pm b/centreon-plugins/apps/tomcat/jmx/mode/webappssessions.pm new file mode 100644 index 000000000..165826a02 --- /dev/null +++ b/centreon-plugins/apps/tomcat/jmx/mode/webappssessions.pm @@ -0,0 +1,227 @@ +# +# Copyright 2017 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::tomcat::jmx::mode::webappssessions; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; +use Digest::MD5 qw(md5_hex); + +my $instance_mode; + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'webapps', type => 1, cb_prefix_output => 'prefix_webapps_output', message_multiple => 'All webapp sessions are ok' }, + ]; + + $self->{maps_counters}->{webapps} = [ + { label => 'sessions-active', set => { + key_values => [ { name => 'activeSessions' }, { name => 'maxActiveSessions' }, { name => 'display' } ], + closure_custom_calc => $self->can('custom_usage_calc'), + closure_custom_calc_extra_options => { label_ref => 'currentThreadCount', message => 'Current Threads' }, + closure_custom_output => $self->can('custom_usage_output'), + closure_custom_threshold_check => $self->can('custom_usage_threshold'), + closure_custom_perfdata => $self->can('custom_usage_perfdata'), + } + }, + { label => 'sessions-count', set => { + key_values => [ { name => 'sessionCounter', diff => 1 }, { name => 'display' } ], + output_template => 'Sessions Count : %s', + perfdatas => [ + { label => 'sessions_count', value => 'sessionCounter_absolute', template => '%s', + min => 0, label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + ]; +} + +sub custom_usage_perfdata { + my ($self, %options) = @_; + + my $use_th = 1; + $use_th = 0 if ($instance_mode->{option_results}->{units} eq '%' && $self->{result_values}->{max} <= 0); + + my $extra_label = ''; + $extra_label = '_' . $self->{result_values}->{display} if (!defined($options{extra_instance}) || $options{extra_instance} != 0); + + my $value_perf = $self->{result_values}->{used}; + my %total_options = (); + if ($instance_mode->{option_results}->{units} eq '%' && $self->{result_values}->{max} > 0) { + $total_options{total} = $self->{result_values}->{max}; + $total_options{cast_int} = 1; + } + + my $label = $self->{label}; + $label =~ s/-/_/g; + $self->{output}->perfdata_add(label => $label . $extra_label, + value => $value_perf, + warning => $use_th == 1 ? $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{label}, %total_options) : undef, + critical => $use_th == 1 ? $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{label}, %total_options) : undef, + min => 0, max => $self->{result_values}->{max} > 0 ? $self->{result_values}->{max} : undef); +} + +sub custom_usage_threshold { + my ($self, %options) = @_; + + # Cannot use percent without total + return 'ok' if ($self->{result_values}->{max} <= 0 && $instance_mode->{option_results}->{units} eq '%'); + my ($exit, $threshold_value); + $threshold_value = $self->{result_values}->{used}; + if ($instance_mode->{option_results}->{units} eq '%') { + $threshold_value = $self->{result_values}->{prct_used}; + } + $exit = $self->{perfdata}->threshold_check(value => $threshold_value, 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 $msg; + if ($self->{result_values}->{max} > 0) { + $msg = sprintf("Current Active Sessions Total: %s Used: %s (%.2f%%) Free: %s (%.2f%%)", + $self->{result_values}->{max}, + $self->{result_values}->{used}, $self->{result_values}->{prct_used}, + $self->{result_values}->{max} - $self->{result_values}->{used}, 100 - $self->{result_values}->{prct_used}); + } else { + $msg = sprintf("Current Active Sessions : %s", $self->{result_values}->{used}); + } + return $msg; +} + +sub custom_usage_calc { + my ($self, %options) = @_; + + $self->{result_values}->{display} = $options{new_datas}->{$self->{instance} . '_display'}; + $self->{result_values}->{max} = $options{new_datas}->{$self->{instance} . '_maxActiveSessions'}; + $self->{result_values}->{used} = $options{new_datas}->{$self->{instance} . '_activeSessions'}; + if ($self->{result_values}->{max} > 0) { + $self->{result_values}->{prct_used} = $self->{result_values}->{used} * 100 / $self->{result_values}->{max}; + } + + return 0; +} + +sub prefix_webapps_output { + my ($self, %options) = @_; + + return "Webapp '" . $options{instance_value}->{display} . "' "; +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options, statefile => 1); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => + { + "filter-name:s" => { name => 'filter_name' }, + "units:s" => { name => 'units', default => '%' }, + }); + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::check_options(%options); + + $instance_mode = $self; +} + +sub manage_selection { + my ($self, %options) = @_; + + # can be path or context + # Tomcat: Catalina:context=/xxxxx,host=localhost,type=Manager + # Jboss: jboss.web:host=localhost,path=/invoker,type=Manager + # maxActiveSessions = -1 (no limit) + $self->{request} = [ + { mbean => "*:context=*,host=*,type=Manager", attributes => [ { name => 'activeSessions' }, { name => 'sessionCounter' }, { name => 'maxActiveSessions' } ] }, + { mbean => "*:path=*,host=*,type=Manager", attributes => [ { name => 'activeSessions' }, { name => 'sessionCounter' }, { name => 'maxActiveSessions' } ] }, + ]; + + my $result = $options{custom}->get_attributes(request => $self->{request}, nothing_quit => 1); + + $self->{webapps} = {}; + foreach my $key (keys %$result) { + $key =~ /(?:[:,])host=(.*?)(?:,|$)/; + my $webapps = $1; + $key =~ /(?:[:,])(?:path|context)=(.*?)(?:,|$)/; + $webapps .= '.' . $1; + + if (defined($self->{option_results}->{filter_name}) && $self->{option_results}->{filter_name} ne '' && + $webapps !~ /$self->{option_results}->{filter_name}/) { + $self->{output}->output_add(long_msg => "skipping '" . $webapps . "': no matching filter.", debug => 1); + next; + } + + $self->{webapps}->{$webapps} = { + display => $webapps, + %{$result->{$key}} + }; + } + + $self->{cache_name} = "tomcat_" . $self->{mode} . '_' . md5_hex($options{custom}->get_connection_info()) . '_' . + (defined($self->{option_results}->{filter_counters}) ? md5_hex($self->{option_results}->{filter_counters}) : md5_hex('all')) . '_' . + (defined($self->{option_results}->{filter_name}) ? md5_hex($self->{option_results}->{filter_name}) : md5_hex('all')); +} + +1; + +__END__ + +=head1 MODE + +Check webapps session usage. + +=over 8 + +=item B<--filter-counters> + +Only display some counters (regexp can be used). +Example: --filter-counters='sessions-active' + +=item B<--filter-name> + +Filter webapps name (can be a regexp). + +=item B<--warning-*> + +Threshold warning. +Can be: 'sessions-count', 'sessions-active'. + +=item B<--critical-*> + +Threshold critical. +Can be: 'sessions-count', 'sessions-active'. + +=item B<--units> + +Units of thresholds (Default: '%') ('%', 'absolute'). + +=back + +=cut diff --git a/centreon-plugins/apps/tomcat/jmx/plugin.pm b/centreon-plugins/apps/tomcat/jmx/plugin.pm index 25a5c57a6..2d732e713 100644 --- a/centreon-plugins/apps/tomcat/jmx/plugin.pm +++ b/centreon-plugins/apps/tomcat/jmx/plugin.pm @@ -34,12 +34,16 @@ sub new { 'class-count' => 'centreon::common::jvm::mode::classcount', 'connector-usage' => 'apps::tomcat::jmx::mode::connectorusage', 'cpu-load' => 'centreon::common::jvm::mode::cpuload', + 'datasource-usage' => 'apps::tomcat::jmx::mode::datasourceusage', 'fd-usage' => 'centreon::common::jvm::mode::fdusage', 'gc-usage' => 'centreon::common::jvm::mode::gcusage', + 'list-datasources' => 'apps::tomcat::jmx::mode::listdatasources', + 'list-webapps' => 'apps::tomcat::jmx::mode::listwebapps', 'load-average' => 'centreon::common::jvm::mode::loadaverage', 'memory' => 'centreon::common::jvm::mode::memory', 'memory-detailed' => 'centreon::common::jvm::mode::memorydetailed', 'threads' => 'centreon::common::jvm::mode::threads', + 'webapps-sessions' => 'apps::tomcat::jmx::mode::webappssessions', ); $self->{custom_modes}{jolokia} = 'centreon::common::protocols::jmx::custom::jolokia'; diff --git a/centreon-plugins/apps/varnish/local/mode/backend.pm b/centreon-plugins/apps/varnish/local/mode/backend.pm index 5b34647a4..13e3d0985 100644 --- a/centreon-plugins/apps/varnish/local/mode/backend.pm +++ b/centreon-plugins/apps/varnish/local/mode/backend.pm @@ -1,5 +1,5 @@ # -# Copyright 2016 Centreon (http://www.centreon.com/) +# Copyright 2017 Centreon (http://www.centreon.com/) # # Centreon is a full-fledged industry-strength solution that meets # the needs in IT infrastructure and application monitoring for diff --git a/centreon-plugins/apps/varnish/local/mode/cache.pm b/centreon-plugins/apps/varnish/local/mode/cache.pm index 9582f4c06..219a6c6db 100644 --- a/centreon-plugins/apps/varnish/local/mode/cache.pm +++ b/centreon-plugins/apps/varnish/local/mode/cache.pm @@ -1,5 +1,5 @@ # -# Copyright 2016 Centreon (http://www.centreon.com/) +# Copyright 2017 Centreon (http://www.centreon.com/) # # Centreon is a full-fledged industry-strength solution that meets # the needs in IT infrastructure and application monitoring for diff --git a/centreon-plugins/apps/varnish/local/mode/clients.pm b/centreon-plugins/apps/varnish/local/mode/clients.pm index e9b701143..ec7d3d086 100644 --- a/centreon-plugins/apps/varnish/local/mode/clients.pm +++ b/centreon-plugins/apps/varnish/local/mode/clients.pm @@ -1,5 +1,5 @@ # -# Copyright 2016 Centreon (http://www.centreon.com/) +# Copyright 2017 Centreon (http://www.centreon.com/) # # Centreon is a full-fledged industry-strength solution that meets # the needs in IT infrastructure and application monitoring for diff --git a/centreon-plugins/apps/varnish/local/mode/sessions.pm b/centreon-plugins/apps/varnish/local/mode/sessions.pm index 46224d2aa..c7a74c2a7 100644 --- a/centreon-plugins/apps/varnish/local/mode/sessions.pm +++ b/centreon-plugins/apps/varnish/local/mode/sessions.pm @@ -1,5 +1,5 @@ # -# Copyright 2016 Centreon (http://www.centreon.com/) +# Copyright 2017 Centreon (http://www.centreon.com/) # # Centreon is a full-fledged industry-strength solution that meets # the needs in IT infrastructure and application monitoring for diff --git a/centreon-plugins/apps/varnish/local/mode/shm.pm b/centreon-plugins/apps/varnish/local/mode/shm.pm index 28e510120..552d85592 100644 --- a/centreon-plugins/apps/varnish/local/mode/shm.pm +++ b/centreon-plugins/apps/varnish/local/mode/shm.pm @@ -1,5 +1,5 @@ # -# Copyright 2016 Centreon (http://www.centreon.com/) +# Copyright 2017 Centreon (http://www.centreon.com/) # # Centreon is a full-fledged industry-strength solution that meets # the needs in IT infrastructure and application monitoring for diff --git a/centreon-plugins/apps/varnish/local/mode/threads.pm b/centreon-plugins/apps/varnish/local/mode/threads.pm index c867f9509..fb72a38f1 100644 --- a/centreon-plugins/apps/varnish/local/mode/threads.pm +++ b/centreon-plugins/apps/varnish/local/mode/threads.pm @@ -1,5 +1,5 @@ # -# Copyright 2016 Centreon (http://www.centreon.com/) +# Copyright 2017 Centreon (http://www.centreon.com/) # # Centreon is a full-fledged industry-strength solution that meets # the needs in IT infrastructure and application monitoring for diff --git a/centreon-plugins/apps/vmware/connector/mode/nethost.pm b/centreon-plugins/apps/vmware/connector/mode/nethost.pm index 43223b75d..20871363c 100644 --- a/centreon-plugins/apps/vmware/connector/mode/nethost.pm +++ b/centreon-plugins/apps/vmware/connector/mode/nethost.pm @@ -44,6 +44,10 @@ sub new { "critical-in:s" => { name => 'critical_in', }, "warning-out:s" => { name => 'warning_out', }, "critical-out:s" => { name => 'critical_out', }, + "warning-dropped-in:s" => { name => 'warning_dropped_in', }, + "critical-dropped-in:s" => { name => 'critical_dropped_in', }, + "warning-dropped-out:s" => { name => 'warning_dropped_out', }, + "critical-dropped-out:s" => { name => 'critical_dropped_out', }, "link-down-status:s" => { name => 'link_down_status', default => 'critical' }, "no-proxyswitch" => { name => 'no_proxyswitch' }, }); @@ -54,7 +58,8 @@ sub check_options { my ($self, %options) = @_; $self->SUPER::init(%options); - foreach my $label (('warning_in', 'critical_in', 'warning_out', 'critical_out')) { + foreach my $label (('warning_in', 'critical_in', 'warning_out', 'critical_out', + 'warning_dropped_in', 'critical_dropped_in', 'warning_dropped_out', 'critical_dropped_out')) { if (($self->{perfdata}->threshold_validate(label => $label, value => $self->{option_results}->{$label})) == 0) { my ($label_opt) = $label; $label_opt =~ tr/_/-/; @@ -141,6 +146,22 @@ Threshold warning traffic out (percent). Threshold critical traffic out (percent). +=item B<--warning-dropped-in> + +Threshold warning packets in dropped (percent). + +=item B<--critical-dropped-in> + +Threshold critical packets in dropped (percent). + +=item B<--warning-dropped-out> + +Threshold warning packets out dropped (percent). + +=item B<--critical-dropped-out> + +Threshold critical packets out dropped (percent). + =item B<--no-proxyswitch> Use the following option if you are checking an ESX 3.x version (it's mandatory). diff --git a/centreon-plugins/apps/voip/asterisk/ami/custom/api.pm b/centreon-plugins/apps/voip/asterisk/ami/custom/api.pm new file mode 100644 index 000000000..0db61b7e2 --- /dev/null +++ b/centreon-plugins/apps/voip/asterisk/ami/custom/api.pm @@ -0,0 +1,278 @@ +# +# Copyright 2017 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::voip::asterisk::ami::custom::api; + +use strict; +use warnings; +use IO::Socket::INET; +use IO::Select; + +sub new { + my ($class, %options) = @_; + my $self = {}; + bless $self, $class; + + 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 => + { + "ami-hostname:s@" => { name => 'ami_hostname' }, + "ami-port:s@" => { name => 'ami_port' }, + "ami-username:s@" => { name => 'ami_username' }, + "ami-password:s@" => { name => 'ami_password' }, + "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->{cnx_ami} = undef; + + return $self; + +} + +sub set_options { + my ($self, %options) = @_; + + $self->{option_results} = $options{option_results}; +} + +sub set_defaults { + my ($self, %options) = @_; + + 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) = @_; + + $self->{ami_hostname} = (defined($self->{option_results}->{ami_hostname})) ? shift(@{$self->{option_results}->{ami_hostname}}) : undef; + $self->{ami_username} = (defined($self->{option_results}->{ami_username})) ? shift(@{$self->{option_results}->{ami_username}}) : undef; + $self->{ami_password} = (defined($self->{option_results}->{ami_password})) ? shift(@{$self->{option_results}->{ami_password}}) : undef; + $self->{ami_port} = (defined($self->{option_results}->{ami_port})) ? shift(@{$self->{option_results}->{ami_port}}) : 5038; + $self->{timeout} = (defined($self->{option_results}->{timeout})) ? shift(@{$self->{option_results}->{timeout}}) : 10; + + if (!defined($self->{ami_hostname})) { + $self->{output}->add_option_msg(short_msg => "Need to specify --ami-hostname option."); + $self->{output}->option_exit(); + } + if (!defined($self->{ami_username})) { + $self->{output}->add_option_msg(short_msg => "Need to specify --ami-username option."); + $self->{output}->option_exit(); + } + if (!defined($self->{ami_password})) { + $self->{output}->add_option_msg(short_msg => "Need to specify --ami-password option."); + $self->{output}->option_exit(); + } + + if (!defined($self->{ami_hostname}) || + scalar(@{$self->{option_results}->{ami_hostname}}) == 0) { + return 0; + } + + return 1; +} + +sub get_connect_info { + my ($self, %options) = @_; + + return $self->{ami_hostname} . '_' . $self->{ami_port}; +} + +sub read_ami_protocol_end { + my ($self, %options) = @_; + + if (defined($options{response})) { + if ($options{response} eq 'Follows') { + return 1 if ($options{message} =~ /^--END COMMAND--/ms); + } else { + return 1 if ($options{message} =~ /^Message: (.*)(\r\n)/ms); + } + } + + return 0; +} + +sub read_ami_protocol { + my ($self, %options) = @_; + + my $select = IO::Select->new($self->{cnx_ami}); + # Two types of message: + # Response: Error + # Message: Authentication failed + # + # Response: Follows + # ... + # --END COMMAND-- + + my ($response, $read_msg); + my $message = ''; + while (1) { + if (!$select->can_read(10)) { + $response = 'Timeout'; + last; + } + + my $status = $self->{cnx_ami}->recv($read_msg, 4096); + if (!defined($response)) { + next if ($read_msg !~ /^Response: (.*?)(?:\r\n|\n)(.*)/ms); + ($response, $message) = ($1, $2); + } else { + $message .= $read_msg; + } + + last if ($self->read_ami_protocol_end(response => $response, message => $message)); + } + + $message =~ s/\r//msg; + if ($response !~ /Success|Follows/) { + $message =~ s/\n+$//msg; + $message =~ s/\n/ -- /msg; + $self->{output}->add_option_msg(short_msg => "Communication issue [" . $message . "]"); + $self->{output}->option_exit(); + } + + $self->{output}->output_add(long_msg => $message, debug => 1); + return $message; +} + +sub write_ami_protocol { + my ($self, %options) = @_; + + $self->{cnx_ami}->send($options{cmd}); +} + +sub login { + my ($self, %options) = @_; + + $self->write_ami_protocol(cmd => "Action:login +Username:$self->{ami_username} +Secret:$self->{ami_password} +Events: off + +"); + # don't need to get it. If it comes, it's success :) + $self->read_ami_protocol(); +} + +sub connect { + my ($self, %options) = @_; + + $self->{cnx_ami} = IO::Socket::INET->new( + PeerAddr => $self->{ami_hostname}, + PeerPort => $self->{ami_port}, + Proto => 'tcp', + Timeout => $self->{timeout}, + ); + if (!defined($self->{cnx_ami})) { + $self->{output}->add_option_msg(short_msg => "Can't bind : $@"); + $self->{output}->option_exit(); + } + + $self->{cnx_ami}->autoflush(1); + $self->login(); +} + +sub command { + my ($self, %options) = @_; + + if (!defined($self->{cnx_ami})) { + $self->connect(); + } + + $self->write_ami_protocol(cmd => "Action:command +Command:$options{cmd} + +"); + return $self->read_ami_protocol(); +} + +sub DESTROY { + my $self = shift; + + if (defined($self->{cnx_ami})) { + $self->{cnx_ami}->close(); + } +} + +1; + +__END__ + +=head1 NAME + +Asterisk AMI + +=head1 SYNOPSIS + +Asterisk AMI custom mode + +=head1 AMI API OPTIONS + +=over 8 + +=item B<--ami-hostname> + +AMI hostname (Required). + +=item B<--ami-port> + +AMI port (Default: 5038). + +=item B<--ami-username> + +AMI username. + +=item B<--ami-password> + +AMI password. + +=item B<--timeout> + +Set TCP timeout + +=back + +=head1 DESCRIPTION + +B. + +=cut diff --git a/centreon-plugins/apps/voip/asterisk/ami/mode/channelusage.pm b/centreon-plugins/apps/voip/asterisk/ami/mode/channelusage.pm new file mode 100644 index 000000000..e3f2b4e2a --- /dev/null +++ b/centreon-plugins/apps/voip/asterisk/ami/mode/channelusage.pm @@ -0,0 +1,132 @@ +# +# Copyright 2017 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::voip::asterisk::ami::mode::channelusage; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; +use Digest::MD5 qw(md5_hex); + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'global', type => 0 }, + ]; + + $self->{maps_counters}->{global} = [ + { label => 'channels-active', set => { + key_values => [ { name => 'channels_active' } ], + output_template => 'Channels Active: %s', + perfdatas => [ + { label => 'channels_active', value => 'channels_active_absolute', template => '%s', min => 0 }, + ], + } + }, + { label => 'calls-active', set => { + key_values => [ { name => 'calls_active' } ], + output_template => 'Calls Active: %s', + perfdatas => [ + { label => 'calls_active', value => 'calls_active_absolute', template => '%s', min => 0 }, + ], + } + }, + { label => 'extcalls-active', set => { + key_values => [ { name => 'extcalls_active' } ], + output_template => 'External Calls Active: %s', + perfdatas => [ + { label => 'extcalls_active', value => 'extcalls_active_absolute', template => '%s', min => 0 }, + ], + } + }, + { label => 'calls-count', set => { + key_values => [ { name => 'calls_count', diff => 1 } ], + output_template => 'Calls Count: %s', + perfdatas => [ + { label => 'calls_count', value => 'calls_count_absolute', template => '%s', min => 0 }, + ], + } + }, + ]; +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options, statefile => 1); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => + { + }); + + return $self; +} + +sub manage_selection { + my ($self, %options) = @_; + + my $result = $options{custom}->command(cmd => 'core show channels'); + $self->{global} = { channels_active => 0, calls_active => 0, + calls_count => undef, extcalls_active => 0 }; + + $self->{global}->{channels_active} = $1 + if ($result =~ /^(\d+)\s+active\s+channels/ms); + $self->{global}->{calls_active} = $1 + if ($result =~ /^(\d+)\s+active\s+calls/ms); + $self->{global}->{calls_count} = $1 + if ($result =~ /^(\d+)\s+calls\s+processed/ms); + + my $count = 0; + $count++ while ($result =~ /Outgoing\s+Line/msig); + $self->{global}->{extcalls_active} = $count; + + $self->{cache_name} = "asterisk_" . '_' . $self->{mode} . '_' . $options{custom}->get_connect_info() . '_' . + (defined($self->{option_results}->{filter_counters}) ? md5_hex($self->{option_results}->{filter_counters}) : md5_hex('all')) . '_' . + (defined($self->{option_results}->{filter_name}) ? md5_hex($self->{option_results}->{filter_name}) : md5_hex('all')); +} + +1; + +__END__ + +=head1 MODE + +Check channel usage: active calls, external calls. + +=over 8 + +=item B<--warning-*> + +Threshold warning. +Can be: 'channels-active', 'calls-active', 'extcalls-active', +'calls-count'. + +=item B<--critical-*> + +Threshold critical. +Can be: 'channels-active', 'calls-active', 'extcalls-active', +'calls-count'. + +=back + +=cut diff --git a/centreon-plugins/apps/voip/asterisk/ami/mode/dahdistatus.pm b/centreon-plugins/apps/voip/asterisk/ami/mode/dahdistatus.pm new file mode 100644 index 000000000..9c48d8ae8 --- /dev/null +++ b/centreon-plugins/apps/voip/asterisk/ami/mode/dahdistatus.pm @@ -0,0 +1,192 @@ +# +# Copyright 2017 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::voip::asterisk::ami::mode::dahdistatus; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; + +my $instance_mode; + +sub custom_status_threshold { + my ($self, %options) = @_; + my $status = 'ok'; + my $message; + + eval { + local $SIG{__WARN__} = sub { $message = $_[0]; }; + local $SIG{__DIE__} = sub { $message = $_[0]; }; + + my $label = $self->{label}; + $label =~ s/-/_/g; + if (defined($instance_mode->{option_results}->{'critical_' . $label}) && $instance_mode->{option_results}->{'critical_' . $label} ne '' && + eval "$instance_mode->{option_results}->{'critical_' . $label}") { + $status = 'critical'; + } elsif (defined($instance_mode->{option_results}->{'warning_' . $label}) && $instance_mode->{option_results}->{'warning_' . $label} ne '' && + eval "$instance_mode->{option_results}->{'warning_' . $label}") { + $status = 'warning'; + } + }; + if (defined($message)) { + $self->{output}->output_add(long_msg => 'filter status issue: ' . $message); + } + + return $status; +} + +sub custom_status_output { + my ($self, %options) = @_; + + my $msg = sprintf('status : %s', $self->{result_values}->{status}); + return $msg; +} + +sub custom_status_calc { + my ($self, %options) = @_; + + $self->{result_values}->{status} = $options{new_datas}->{$self->{instance} . '_status'}; + $self->{result_values}->{description} = $options{new_datas}->{$self->{instance} . '_description'}; + return 0; +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'dahdi', type => 1, cb_prefix_output => 'prefix_dahdi_output', message_multiple => 'All dahdi lines are ok' }, + ]; + + $self->{maps_counters}->{dahdi} = [ + { label => 'status', threshold => 0, set => { + key_values => [ { name => 'description' }, { name => 'status' } ], + closure_custom_calc => $self->can('custom_status_calc'), + closure_custom_output => $self->can('custom_status_output'), + closure_custom_perfdata => sub { return 0; }, + closure_custom_threshold_check => $self->can('custom_status_threshold'), + } + }, + ]; +} + +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-description:s" => { name => 'filter_description' }, + "warning-status:s" => { name => 'warning_status', default => '%{status} =~ /UNCONFIGURED|YEL|BLU/i' }, + "critical-status:s" => { name => 'critical_status', default => '%{status} =~ /RED/i' }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::check_options(%options); + + $instance_mode = $self; + $self->change_macros(); +} + +sub prefix_dahdi_output { + my ($self, %options) = @_; + + return "Line '" . $options{instance_value}->{description} . "' "; +} + +sub change_macros { + my ($self, %options) = @_; + + foreach (('warning_status', 'critical_status')) { + if (defined($self->{option_results}->{$_})) { + $self->{option_results}->{$_} =~ s/%\{(.*?)\}/\$self->{result_values}->{$1}/g; + } + } +} + +sub manage_selection { + my ($self, %options) = @_; + + # Status can be: OK, UNCONFIGURED, BLU, YEL, RED, REC (recover), NOP (notopen), UUU + + #Description Alarms IRQ bpviol CRC4 + #Wildcard TDM410P Board 1 OK 0 0 0 + #Wildcard TDM800P Board 2 OK 0 0 0 + + #Description Alarms IRQ bpviol CRC Fra Codi Options LBO + #Wildcard TE131/TE133 Card 0 BLU/RED 0 0 0 CCS HDB3 0 db (CSU)/0-133 feet (DSX-1) + my $result = $options{custom}->command(cmd => 'dahdi show status'); + + $self->{dahdi} = {}; + foreach my $line (split /\n/, $result) { + if ($line =~ /^(.*?)\s+((?:OK|UNCONFIGURED|BLU|YEL|RED|REC|NOP|UUU)[^\s]*)\s+/msg) { + my ($description, $status) = ($1, $2); + if (defined($self->{option_results}->{filter_description}) && $self->{option_results}->{filter_description} ne '' && + $description !~ /$self->{option_results}->{filter_description}/) { + $self->{output}->output_add(long_msg => "skipping '" . $description . "': no matching filter.", debug => 1); + next; + } + + $self->{dahdi}->{$description} = { + description => $description, + status => $status, + }; + } + } + + if (scalar(keys %{$self->{dahdi}}) <= 0) { + $self->{output}->add_option_msg(short_msg => "No dahdi lines found."); + $self->{output}->option_exit(); + } +} + +1; + +__END__ + +=head1 MODE + +Check status of dahdi lines. + +=over 8 + +=item B<--filter-description> + +Filter dahdi description (can be a regexp). + +=item B<--warning-status> + +Set warning threshold for status (Default: '%{status} =~ /UNCONFIGURED|YEL|BLU/i'). +Can used special variables like: %{description}, %{status} + +=item B<--critical-status> + +Set critical threshold for status (Default: '%{status} =~ /RED/i'). +Can used special variables like: %{description}, %{status} + +=back + +=cut diff --git a/centreon-plugins/apps/voip/asterisk/ami/mode/sippeersusage.pm b/centreon-plugins/apps/voip/asterisk/ami/mode/sippeersusage.pm new file mode 100644 index 000000000..c926ceeb3 --- /dev/null +++ b/centreon-plugins/apps/voip/asterisk/ami/mode/sippeersusage.pm @@ -0,0 +1,252 @@ +# +# Copyright 2017 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::voip::asterisk::ami::mode::sippeersusage; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; + +my $instance_mode; + +sub custom_status_threshold { + my ($self, %options) = @_; + my $status = 'ok'; + my $message; + + eval { + local $SIG{__WARN__} = sub { $message = $_[0]; }; + local $SIG{__DIE__} = sub { $message = $_[0]; }; + + my $label = $self->{label}; + $label =~ s/-/_/g; + if (defined($instance_mode->{option_results}->{'critical_' . $label}) && $instance_mode->{option_results}->{'critical_' . $label} ne '' && + eval "$instance_mode->{option_results}->{'critical_' . $label}") { + $status = 'critical'; + } elsif (defined($instance_mode->{option_results}->{'warning_' . $label}) && $instance_mode->{option_results}->{'warning_' . $label} ne '' && + eval "$instance_mode->{option_results}->{'warning_' . $label}") { + $status = 'warning'; + } + }; + if (defined($message)) { + $self->{output}->output_add(long_msg => 'filter status issue: ' . $message); + } + + return $status; +} + +sub custom_status_output { + my ($self, %options) = @_; + + my $msg = sprintf('status : %s', $self->{result_values}->{status}); + return $msg; +} + +sub custom_status_calc { + my ($self, %options) = @_; + + $self->{result_values}->{status} = $options{new_datas}->{$self->{instance} . '_status'}; + $self->{result_values}->{name} = $options{new_datas}->{$self->{instance} . '_name'}; + return 0; +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'global', type => 0 }, + { name => 'sip', type => 1, cb_prefix_output => 'prefix_sip_output', message_multiple => 'All SIP peers are ok' }, + ]; + + $self->{maps_counters}->{global} = [ + { label => 'total-peers', set => { + key_values => [ { name => 'total_peers' } ], + output_template => 'Total Peers: %s', + perfdatas => [ + { label => 'total_peers', value => 'total_peers_absolute', template => '%s', min => 0 }, + ], + } + }, + { label => 'monitor-online-peers', set => { + key_values => [ { name => 'monitor_online_peers' } ], + output_template => 'Monitor Online Peers: %s', + perfdatas => [ + { label => 'monitor_online_peers', value => 'monitor_online_peers_absolute', template => '%s', min => 0 }, + ], + } + }, + { label => 'monitor-offline-peers', set => { + key_values => [ { name => 'monitor_offline_peers' } ], + output_template => 'Monitor Offline Peers: %s', + perfdatas => [ + { label => 'monitor_offline_peers', value => 'monitor_offline_peers_absolute', template => '%s', min => 0 }, + ], + } + }, + { label => 'unmonitor-online-peers', set => { + key_values => [ { name => 'unmonitor_online_peers' } ], + output_template => 'Unmonitor Online Peers: %s', + perfdatas => [ + { label => 'unmonitor_online_peers', value => 'unmonitor_online_peers_absolute', template => '%s', min => 0 }, + ], + } + }, + { label => 'unmonitor-offline-peers', set => { + key_values => [ { name => 'unmonitor_offline_peers' } ], + output_template => 'Unmonitor Offline Peers: %s', + perfdatas => [ + { label => 'unmonitor_offline_peers', value => 'unmonitor_offline_peers_absolute', template => '%s', min => 0 }, + ], + } + }, + ]; + $self->{maps_counters}->{sip} = [ + { label => 'status', threshold => 0, set => { + key_values => [ { name => 'name' }, { name => 'status' } ], + closure_custom_calc => $self->can('custom_status_calc'), + closure_custom_output => $self->can('custom_status_output'), + closure_custom_perfdata => sub { return 0; }, + closure_custom_threshold_check => $self->can('custom_status_threshold'), + } + }, + ]; +} + +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' }, + "warning-status:s" => { name => 'warning_status', default => '%{status} =~ /LAGGED|UNKNOWN/i' }, + "critical-status:s" => { name => 'critical_status', default => '%{status} =~ /UNREACHABLE/i' }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::check_options(%options); + + $instance_mode = $self; + $self->change_macros(); +} + +sub prefix_sip_output { + my ($self, %options) = @_; + + return "Peer '" . $options{instance_value}->{name} . "' "; +} + +sub change_macros { + my ($self, %options) = @_; + + foreach (('warning_status', 'critical_status')) { + if (defined($self->{option_results}->{$_})) { + $self->{option_results}->{$_} =~ s/%\{(.*?)\}/\$self->{result_values}->{$1}/g; + } + } +} + +sub manage_selection { + my ($self, %options) = @_; + + # Status can be: UNREACHABLE, LAGGED (%d ms), OK (%d ms), UNKNOWN, Unmonitored + + #Name/username Host Dyn Forcerport Comedia ACL Port Status Description + #02l44k/02l44k 10.9.0.61 D No No 5060 Unmonitored + #0rafkw/0rafkw 10.9.0.28 D No No 5060 Unmonitored + #... + #55 sip peers [Monitored: 0 online, 0 offline Unmonitored: 43 online, 12 offline] + my $result = $options{custom}->command(cmd => 'sip show peers'); + + $self->{sip} = {}; + foreach my $line (split /\n/, $result) { + if ($line =~ /^(.*?)\s+.*(UNREACHABLE|LAGGED|OK|UNKNOWN|Unmonitored)\s/msg) { + my ($name, $status) = ($1, $2); + if (defined($self->{option_results}->{filter_name}) && $self->{option_results}->{filter_name} ne '' && + $name !~ /$self->{option_results}->{filter_name}/) { + $self->{output}->output_add(long_msg => "skipping '" . $name . "': no matching filter.", debug => 1); + next; + } + + $self->{sip}->{$name} = { + name => $name, + status => $status, + }; + } + } + + $self->{global} = { + total_peers => $1, + monitor_online_peers => $2, monitor_offline_peers => $3, + unmonitor_online_peers => $4, unmonitor_offline_peers => $5, + } if ($result =~ /(\d+) sip peers \[Monitored: (\d+) online, (\d+) offline Unmonitored: (\d+) online, (\d+) offline]/msi); + + if (scalar(keys %{$self->{sip}}) <= 0) { + $self->{output}->add_option_msg(short_msg => "No sip peers found."); + $self->{output}->option_exit(); + } +} + +1; + +__END__ + +=head1 MODE + +Check SIP peers usage. + +=over 8 + +=item B<--filter-name> + +Filter sip peer name (can be a regexp). + +=item B<--warning-status> + +Set warning threshold for status (Default: '%{status} =~ /LAGGED|UNKNOWN/i'). +Can used special variables like: %{name}, %{status} + +=item B<--critical-status> + +Set critical threshold for status (Default: '%{status} =~ /UNREACHABLE/i'). +Can used special variables like: %{name}, %{status} + +=item B<--warning-*> + +Threshold warning. +Can be: 'total-peers', 'monitor-online-peers', 'monitor-offline-peers', +'unmonitor-online-peers', 'unmonitor-offline-peers'. + +=item B<--critical-*> + +Threshold critical. +Can be: 'total-peers', 'monitor-online-peers', 'monitor-offline-peers', +'unmonitor-online-peers', 'unmonitor-offline-peers'. + +=back + +=cut diff --git a/centreon-plugins/apps/voip/asterisk/ami/plugin.pm b/centreon-plugins/apps/voip/asterisk/ami/plugin.pm new file mode 100644 index 000000000..543256fa8 --- /dev/null +++ b/centreon-plugins/apps/voip/asterisk/ami/plugin.pm @@ -0,0 +1,51 @@ +# +# Copyright 2017 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::voip::asterisk::ami::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; + + $self->{version} = '1.0'; + %{$self->{modes}} = ( + 'channel-usage' => 'apps::voip::asterisk::ami::mode::channelusage', + 'dahdi-status' => 'apps::voip::asterisk::ami::mode::dahdistatus', + 'sip-peers-usage' => 'apps::voip::asterisk::ami::mode::sippeersusage', + ); + + $self->{custom_modes}{api} = 'apps::voip::asterisk::ami::custom::api'; + return $self; +} + +1; + +__END__ + +=head1 PLUGIN DESCRIPTION + +Check Asterisk through AMI interface. + +=cut diff --git a/centreon-plugins/apps/voip/asterisk/remote/lib/ami.pm b/centreon-plugins/apps/voip/asterisk/remote/lib/ami.pm deleted file mode 100644 index afc346116..000000000 --- a/centreon-plugins/apps/voip/asterisk/remote/lib/ami.pm +++ /dev/null @@ -1,103 +0,0 @@ -# -# Copyright 2017 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::voip::asterisk::remote::lib::ami; - -use strict; -use warnings; -use Net::Telnet; - -my $ami_handle; -my $line; -my @lines; -my @result; - -sub quit { - $ami_handle->print("Action: logoff"); - $ami_handle->print(""); - $ami_handle->close(); -} - -sub connect { - my ($self, %options) = @_; - - my $connection_exit = defined($options{connection_exit}) ? $options{connection_exit} : 'unknown'; - - $ami_handle = new Net::Telnet (Telnetmode => 0, - Timeout => $self->{option_results}->{timeout}, - Errmode => 'return', - ); - - $ami_handle->open(Host => $self->{option_results}->{hostname}, - Port => $self->{option_results}->{port}, - ); - - if ($ami_handle->errmsg) { - $self->{output}->output_add(severity => $connection_exit, - short_msg => 'Unable to connect to AMI: ' . $ami_handle->errmsg); - $self->{output}->display(); - $self->{output}->exit(); - } - - # Check connection message. - $line = $ami_handle->getline; - if ($line !~ /^Asterisk/) { - $self->{output}->output_add(severity => $connection_exit, - short_msg => 'Unable to connect to AMI: ' . $line); - $self->{output}->display(); - $self->{output}->exit(); - } - - # Authentication. - $ami_handle->print("Action: login"); - $ami_handle->print("Username: $self->{option_results}->{username}"); - $ami_handle->print("Secret: $self->{option_results}->{password}"); - $ami_handle->print("Events: off"); - $ami_handle->print(""); - - # Check authentication message (second message). - $line = $ami_handle->getline; - $line = $ami_handle->getline; - if ($line !~ /^Message: Authentication accepted/) { - $self->{output}->output_add(severity => $connection_exit, - short_msg => 'Unable to connect to AMI: ' . $line); - $self->{output}->display(); - $self->{output}->exit(); - } - -} - -sub action { - my ($self) = @_; - - $ami_handle->print("Action: command"); - $ami_handle->print("Command: $self->{asterisk_command}"); - $ami_handle->print(""); - - - my @return; - while (my $line = $ami_handle->getline(Timeout => 1)) { - push(@return,$line); - next if ($line !~ /END COMMAND/o); - } - return @return; -} - -1; diff --git a/centreon-plugins/apps/voip/asterisk/remote/mode/activecalls.pm b/centreon-plugins/apps/voip/asterisk/remote/mode/activecalls.pm deleted file mode 100644 index 9fc86dece..000000000 --- a/centreon-plugins/apps/voip/asterisk/remote/mode/activecalls.pm +++ /dev/null @@ -1,223 +0,0 @@ -# -# Copyright 2017 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::voip::asterisk::remote::mode::activecalls; - -use base qw(centreon::plugins::mode); - -use strict; -use warnings; -use centreon::plugins::misc; -use apps::voip::asterisk::remote::lib::ami; - -sub new { - my ($class, %options) = @_; - my $self = $class->SUPER::new(package => __PACKAGE__, %options); - bless $self, $class; - - $self->{version} = '0.2'; - - $options{options}->add_options(arguments => - { - "hostname:s" => { name => 'hostname' }, - "port:s" => { name => 'port', default => 5038 }, - "username:s" => { name => 'username' }, - "password:s" => { name => 'password' }, - "remote:s" => { name => 'remote', default => 'ssh' }, - "ssh-option:s@" => { name => 'ssh_option' }, - "ssh-path:s" => { name => 'ssh_path' }, - "ssh-command:s" => { name => 'ssh_command', default => 'ssh' }, - "timeout:s" => { name => 'timeout', default => 30 }, - "command:s" => { name => 'command', default => 'asterisk_sendcommand.pm' }, - "command-path:s" => { name => 'command_path', default => '/home/centreon/bin' }, - "protocol:s" => { name => 'protocol', }, - "warning:s" => { name => 'warning', }, - "critical:s" => { name => 'critical', }, - }); - $self->{result} = {}; - return $self; -} - -sub check_options { - my ($self, %options) = @_; - $self->SUPER::init(%options); - - if (!defined($self->{option_results}->{hostname})) { - $self->{output}->add_option_msg(short_msg => "Please set the --hostname option"); - $self->{output}->option_exit(); - } - - if ($self->{option_results}->{remote} eq 'ami') - { - if (!defined($self->{option_results}->{username})) { - $self->{output}->add_option_msg(short_msg => "Please set the --username option"); - $self->{output}->option_exit(); - } - - if (!defined($self->{option_results}->{password})) { - $self->{output}->add_option_msg(short_msg => "Please set the --password option"); - $self->{output}->option_exit(); - } - } - - 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 manage_selection { - my ($self, %options) = @_; - my @result; - - $self->{asterisk_command} = 'core show channels'; - - if ($self->{option_results}->{remote} eq 'ami') - { - apps::voip::asterisk::remote::lib::ami::connect($self); - @result = apps::voip::asterisk::remote::lib::ami::action($self); - apps::voip::asterisk::remote::lib::ami::quit(); - } - else - { - my $stdout = centreon::plugins::misc::execute(output => $self->{output}, - options => $self->{option_results}, - command => $self->{option_results}->{command}, - command_path => $self->{option_results}->{command_path}, - command_options => "'".$self->{asterisk_command}."'", - ); - @result = split /\n/, $stdout; - } - - # Compute data - foreach my $line (@result) { - if ($line =~ /^(\d*) active call/) - { - $self->{result}->{activecalls} = {value => $1, status => '1'}; - } - elsif ($line =~ /^Unable to connect .*/) - { - $self->{result}->{activecalls} = {value => $line, status => '0'}; - } - } -} - -sub run { - my ($self, %options) = @_; - - my $msg; - my $old_status = 'ok'; - - $self->manage_selection(); - - # Send formated data to Centreon - if ($self->{result}->{activecalls}->{status} eq '0') - { - $self->{output}->output_add(severity => $self->{result}->{activecalls}->{status}, - short_msg => $self->{result}->{activecalls}->{value}); - $self->{output}->display(); - $self->{output}->exit(); - } - my $exit_code = $self->{perfdata}->threshold_check(value => $self->{result}->{activecalls}->{value}, - threshold => [ { label => 'critical', 'exit_litteral' => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]); - $self->{output}->perfdata_add(label => 'Active Calls', - value => $self->{result}->{activecalls}->{value}, - warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning'), - critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical'), - min => 0); - - $self->{output}->output_add(severity => $exit_code, - short_msg => sprintf("Current active calls: %s", $self->{result}->{activecalls}->{value}) - ); - - $self->{output}->display(); - $self->{output}->exit(); -} - -1; - -__END__ - -=head1 MODE - -Show number of current active calls - -=over 8 - -=item B<--warning> - -Threshold warning. - -=item B<--critical> - -Threshold critical. - -=item B<--remote> - -Execute command remotely; can be 'ami' or 'ssh' (default: ssh). - -=item B<--hostname> - -Hostname to query (need --remote option). - -=item B<--port> - -AMI remote port (default: 5038). - -=item B<--username> - -AMI username. - -=item B<--password> - -AMI password. - -=item B<--ssh-option> - -Specify multiple options like the user (example: --ssh-option='-l=centreon-engine' --ssh-option='-p=52'). - -=item B<--ssh-path> - -Specify ssh command path (default: none) - -=item B<--ssh-command> - -Specify ssh command (default: 'ssh'). Useful to use 'plink'. - -=item B<--timeout> - -Timeout in seconds for the command (Default: 30). - -=item B<--command> - -Command to get information (Default: 'asterisk_sendcommand.pm'). -Can be changed if you have output in a file. - -=item B<--command-path> - -Command path (Default: /home/centreon/bin). - -=back - -=cut diff --git a/centreon-plugins/apps/voip/asterisk/remote/mode/dahdistatus.pm b/centreon-plugins/apps/voip/asterisk/remote/mode/dahdistatus.pm deleted file mode 100644 index 027b5b886..000000000 --- a/centreon-plugins/apps/voip/asterisk/remote/mode/dahdistatus.pm +++ /dev/null @@ -1,230 +0,0 @@ -# -# Copyright 2017 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::voip::asterisk::remote::mode::dahdistatus; - -use base qw(centreon::plugins::mode); - -use strict; -use warnings; -use centreon::plugins::misc; -use apps::voip::asterisk::remote::lib::ami; - -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 => - { - "hostname:s" => { name => 'hostname' }, - "port:s" => { name => 'port', default => 5038 }, - "username:s" => { name => 'username' }, - "password:s" => { name => 'password' }, - "remote:s" => { name => 'remote', default => 'ssh' }, - "ssh-option:s@" => { name => 'ssh_option' }, - "ssh-path:s" => { name => 'ssh_path' }, - "ssh-command:s" => { name => 'ssh_command', default => 'ssh' }, - "timeout:s" => { name => 'timeout', default => 30 }, - "command:s" => { name => 'command', default => 'asterisk_sendcommand.pm' }, - "command-path:s" => { name => 'command_path', default => '/home/centreon/bin' }, - "filter-name:s" => { name => 'filter_name', }, - }); - $self->{result} = {}; - return $self; -} - -sub check_options { - my ($self, %options) = @_; - $self->SUPER::init(%options); - - if (!defined($self->{option_results}->{hostname})) { - $self->{output}->add_option_msg(short_msg => "Please set the --hostname option"); - $self->{output}->option_exit(); - } - - if ($self->{option_results}->{remote} eq 'ami') - { - if (!defined($self->{option_results}->{username})) { - $self->{output}->add_option_msg(short_msg => "Please set the --username option"); - $self->{output}->option_exit(); - } - - if (!defined($self->{option_results}->{password})) { - $self->{output}->add_option_msg(short_msg => "Please set the --password option"); - $self->{output}->option_exit(); - } - } -} - -sub manage_selection { - my ($self, %options) = @_; - my @result; - - $self->{asterisk_command} = 'dahdi show status'; - - if ($self->{option_results}->{remote} eq 'ami') - { - apps::voip::asterisk::remote::lib::ami::connect($self); - @result = apps::voip::asterisk::remote::lib::ami::action($self); - apps::voip::asterisk::remote::lib::ami::quit(); - } - else - { - my $stdout = centreon::plugins::misc::execute(output => $self->{output}, - options => $self->{option_results}, - command => $self->{option_results}->{command}, - command_path => $self->{option_results}->{command_path}, - command_options => "'".$self->{asterisk_command}."'", - ); - @result = split /\n/, $stdout; - } - - # Compute data - foreach my $line (@result) { - if ($line =~ /^Description /) - { - next; - } - if ($line =~ /^(.{41})(\w*).*/) - { - my $status; - my ($trunkname, $trunkstatus) = ($1, $2); - $trunkname =~ s/^\s+|\s+$//g; - if (defined($self->{option_results}->{filter_name}) && $self->{option_results}->{filter_name} ne '' && - $trunkname !~ /$self->{option_results}->{filter_name}/) - { - $self->{output}->output_add(long_msg => "Skipping trunk '" . $trunkname . "': no matching filter name"); - next; - } - if ($trunkstatus eq 'Red' | $trunkstatus eq 'Yel' | $trunkstatus eq 'Blu') - { - $status = 'CRITICAL'; - } - elsif ($trunkstatus eq 'Unconfi') - { - $status = 'WARNING'; - } - $self->{result}->{$trunkname} = {name => $trunkname, status => $status, realstatus => $trunkstatus}; - } - elsif ($line =~ /^Unable to connect .*/) - { - $self->{result}->{$line} = {name => $line, status => 'CRITICAL'}; - } - } -} - -sub run { - my ($self, %options) = @_; - - my $msg; - my $old_status = 'ok'; - - $self->manage_selection(); - - # Send formated data to Centreon - if (scalar keys %{$self->{result}} >= 1) - { - $self->{output}->output_add(severity => 'OK', - short_msg => 'Everything is OK'); - } - else - { - $self->{output}->output_add(severity => 'Unknown', - short_msg => 'Nothing to be monitored'); - } - - foreach my $name (sort(keys %{$self->{result}})) { - if (!$self->{output}->is_status(value => $self->{result}->{$name}->{status}, compare => 'ok', litteral => 1)) - { - $msg = sprintf("Trunk: %s", $self->{result}->{$name}->{name}); - $self->{output}->output_add(severity => $self->{result}->{$name}->{status}, - short_msg => $msg); - } - $self->{output}->output_add(long_msg => sprintf("%s : %s", $self->{result}->{$name}->{name}, $self->{result}->{$name}->{realstatus})); - } - $self->{output}->display(); - $self->{output}->exit(); -} - -1; - -__END__ - -=head1 MODE - -Show status of dahdi lines. - -=over 8 - -=item B<--remote> - -Execute command remotely; can be 'ami' or 'ssh' (default: ssh). - -=item B<--hostname> - -Hostname to query (need --remote option). - -=item B<--port> - -AMI remote port (default: 5038). - -=item B<--username> - -AMI username. - -=item B<--password> - -AMI password. - -=item B<--ssh-option> - -Specify multiple options like the user (example: --ssh-option='-l=centreon-engine' --ssh-option='-p=52'). - -=item B<--ssh-path> - -Specify ssh command path (default: none) - -=item B<--ssh-command> - -Specify ssh command (default: 'ssh'). Useful to use 'plink'. - -=item B<--timeout> - -Timeout in seconds for the command (Default: 30). - -=item B<--command> - -Command to get information (Default: 'asterisk_sendcommand.pm'). -Can be changed if you have output in a file. - -=item B<--command-path> - -Command path (Default: /home/centreon/bin). - -=item B<--filter-name> - -Filter on trunkname (regexp can be used). - -=back - -=cut \ No newline at end of file diff --git a/centreon-plugins/apps/voip/asterisk/remote/mode/externalcalls.pm b/centreon-plugins/apps/voip/asterisk/remote/mode/externalcalls.pm deleted file mode 100644 index 6144885af..000000000 --- a/centreon-plugins/apps/voip/asterisk/remote/mode/externalcalls.pm +++ /dev/null @@ -1,213 +0,0 @@ -# -# Copyright 2017 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::voip::asterisk::remote::mode::externalcalls; - -use base qw(centreon::plugins::mode); - -use strict; -use warnings; -use centreon::plugins::misc; -use apps::voip::asterisk::remote::lib::ami; - -sub new { - my ($class, %options) = @_; - my $self = $class->SUPER::new(package => __PACKAGE__, %options); - bless $self, $class; - - $self->{version} = '0.1'; - - $options{options}->add_options(arguments => - { - "hostname:s" => { name => 'hostname' }, - "port:s" => { name => 'port', default => 5038 }, - "username:s" => { name => 'username' }, - "password:s" => { name => 'password' }, - "remote:s" => { name => 'remote', default => 'ssh' }, - "ssh-option:s@" => { name => 'ssh_option' }, - "ssh-path:s" => { name => 'ssh_path' }, - "ssh-command:s" => { name => 'ssh_command', default => 'ssh' }, - "timeout:s" => { name => 'timeout', default => 30 }, - "command:s" => { name => 'command', default => 'asterisk_sendcommand.pm' }, - "command-path:s" => { name => 'command_path', default => '/home/centreon/bin' }, - "protocol:s" => { name => 'protocol', }, - "warning:s" => { name => 'warning', }, - "critical:s" => { name => 'critical', }, - }); - $self->{result} = {}; - return $self; -} - -sub check_options { - my ($self, %options) = @_; - $self->SUPER::init(%options); - - if (!defined($self->{option_results}->{hostname})) { - $self->{output}->add_option_msg(short_msg => "Please set the --hostname option"); - $self->{output}->option_exit(); - } - - if ($self->{option_results}->{remote} eq 'ami') - { - if (!defined($self->{option_results}->{username})) { - $self->{output}->add_option_msg(short_msg => "Please set the --username option"); - $self->{output}->option_exit(); - } - - if (!defined($self->{option_results}->{password})) { - $self->{output}->add_option_msg(short_msg => "Please set the --password option"); - $self->{output}->option_exit(); - } - } - - 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 manage_selection { - my ($self, %options) = @_; - my @result; - - $self->{asterisk_command} = 'core show channels'; - - if ($self->{option_results}->{remote} eq 'ami') - { - apps::voip::asterisk::remote::lib::ami::connect($self); - @result = apps::voip::asterisk::remote::lib::ami::action($self); - apps::voip::asterisk::remote::lib::ami::quit(); - } - else - { - my $stdout = centreon::plugins::misc::execute(output => $self->{output}, - options => $self->{option_results}, - command => $self->{option_results}->{command}, - command_path => $self->{option_results}->{command_path}, - command_options => "'".$self->{asterisk_command}."'", - ); - @result = split /\n/, $stdout; - } - - # Compute data - $self->{option_results}->{extcallcounter} = '0'; - foreach my $line (@result) { - if ($line =~ /Outgoing Line/m) - { - $self->{option_results}->{extcallcounter}++; - } - } -} - -sub run { - my ($self, %options) = @_; - - my $msg; - my $old_status = 'ok'; - - $self->manage_selection(); - - # Send formated data to Centreon - my $exit_code = $self->{perfdata}->threshold_check(value => $self->{option_results}->{extcallcounter}, - threshold => [ { label => 'critical', 'exit_litteral' => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]); - $self->{output}->perfdata_add(label => 'External Calls', - value => $self->{option_results}->{extcallcounter}, - warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning'), - critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical'), - min => 0); - - $self->{output}->output_add(severity => $exit_code, - short_msg => sprintf("Current external calls: %s", $self->{option_results}->{extcallcounter}) - ); - - $self->{output}->display(); - $self->{output}->exit(); -} - -1; - -__END__ - -=head1 MODE - -Show number of current external calls - -=over 8 - -=item B<--warning> - -Threshold warning. - -=item B<--critical> - -Threshold critical. - -=item B<--remote> - -Execute command remotely; can be 'ami' or 'ssh' (default: ssh). - -=item B<--hostname> - -Hostname to query (need --remote option). - -=item B<--port> - -AMI remote port (default: 5038). - -=item B<--username> - -AMI username. - -=item B<--password> - -AMI password. - -=item B<--ssh-option> - -Specify multiple options like the user (example: --ssh-option='-l=centreon-engine' --ssh-option='-p=52'). - -=item B<--ssh-path> - -Specify ssh command path (default: none) - -=item B<--ssh-command> - -Specify ssh command (default: 'ssh'). Useful to use 'plink'. - -=item B<--timeout> - -Timeout in seconds for the command (Default: 30). - -=item B<--command> - -Command to get information (Default: 'asterisk_sendcommand.pm'). -Can be changed if you have output in a file. - -=item B<--command-path> - -Command path (Default: /home/centreon/bin). - -=back - -=cut diff --git a/centreon-plugins/apps/voip/asterisk/remote/mode/showpeers.pm b/centreon-plugins/apps/voip/asterisk/remote/mode/showpeers.pm deleted file mode 100644 index 6d92077c7..000000000 --- a/centreon-plugins/apps/voip/asterisk/remote/mode/showpeers.pm +++ /dev/null @@ -1,277 +0,0 @@ -# -# Copyright 2017 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::voip::asterisk::remote::mode::showpeers; - -use base qw(centreon::plugins::mode); - -use strict; -use warnings; -use centreon::plugins::misc; -use apps::voip::asterisk::remote::lib::ami; - -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 => - { - "hostname:s" => { name => 'hostname' }, - "port:s" => { name => 'port', default => 5038 }, - "username:s" => { name => 'username' }, - "password:s" => { name => 'password' }, - "remote:s" => { name => 'remote', default => 'ssh' }, - "ssh-option:s@" => { name => 'ssh_option' }, - "ssh-path:s" => { name => 'ssh_path' }, - "ssh-command:s" => { name => 'ssh_command', default => 'ssh' }, - "timeout:s" => { name => 'timeout', default => 30 }, - "command:s" => { name => 'command', default => 'asterisk_sendcommand.pm' }, - "command-path:s" => { name => 'command_path', default => '/home/centreon/bin' }, - "protocol:s" => { name => 'protocol', }, - "filter-name:s" => { name => 'filter_name', }, - "warning:s" => { name => 'warning', }, - "critical:s" => { name => 'critical', }, - }); - $self->{result} = {}; - return $self; -} - -sub check_options { - my ($self, %options) = @_; - $self->SUPER::init(%options); - - if (!defined($self->{option_results}->{hostname})) { - $self->{output}->add_option_msg(short_msg => "Please set the --hostname option"); - $self->{output}->option_exit(); - } - - if ($self->{option_results}->{remote} eq 'ami') - { - if (!defined($self->{option_results}->{username})) { - $self->{output}->add_option_msg(short_msg => "Please set the --username option"); - $self->{output}->option_exit(); - } - - if (!defined($self->{option_results}->{password})) { - $self->{output}->add_option_msg(short_msg => "Please set the --password option"); - $self->{output}->option_exit(); - } - } - - 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 manage_selection { - my ($self, %options) = @_; - my @result; - - if ($self->{option_results}->{protocol} eq 'sip' || $self->{option_results}->{protocol} eq 'SIP') - { - $self->{asterisk_command} = 'sip show peers'; - } - elsif ($self->{option_results}->{protocol} eq 'iax' || $self->{option_results}->{protocol} eq 'IAX') - { - $self->{asterisk_command} = 'iax2 show peers'; - } - - if ($self->{option_results}->{remote} eq 'ami') - { - apps::voip::asterisk::remote::lib::ami::connect($self); - @result = apps::voip::asterisk::remote::lib::ami::action($self); - apps::voip::asterisk::remote::lib::ami::quit(); - } - else - { - my $stdout = centreon::plugins::misc::execute(output => $self->{output}, - options => $self->{option_results}, - command => $self->{option_results}->{command}, - command_path => $self->{option_results}->{command_path}, - command_options => "'".$self->{asterisk_command}."'", - ); - @result = split /\n/, $stdout; - } - - # Compute data - foreach my $line (@result) { - if ($line =~ /^([\w\-\/]*) *\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3} .* (OK) \((.*) (.*)\)/) - { - my ($trunkname, $trunkstatus, $trunkvalue, $trunkunit) = ($1, $2, $3, $4); - - if (defined($self->{option_results}->{filter_name}) && $self->{option_results}->{filter_name} ne '' && - $trunkname !~ /$self->{option_results}->{filter_name}/) - { - $self->{output}->output_add(long_msg => "Skipping trunk '" . $trunkname . "': no matching filter name"); - next; - } - - $self->{result}->{$trunkname} = {name => $trunkname, status => 'OK', - realstatus => $trunkstatus, - value => $trunkvalue, - unit => $trunkunit}; - } - elsif ($line =~ /^([\w\-\/]*) *\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3} .* (Unreachable)/) - { - my ($trunkname, $trunkstatus) = ($1, $2); - $self->{result}->{$trunkname} = {name => $trunkname, status => 'CRITICAL', realstatus => $trunkstatus}; - } - elsif ($line =~ /^Unable to connect .*/) - { - $self->{result}->{$line} = {name => $line, status => 'CRITICAL', realstatus => 'Unreachable'}; - } - } -} - -sub run { - my ($self, %options) = @_; - - my $msg; - my $old_status = 'ok'; - - $self->manage_selection(); - - # Send formated data to Centreon - if (scalar keys %{$self->{result}} >= 1) - { - $self->{output}->output_add(severity => 'OK', - short_msg => 'Everything is OK'); - } - else - { - $self->{output}->output_add(severity => 'Unknown', - short_msg => 'Nothing to be monitored'); - } - - foreach my $name (sort(keys %{$self->{result}})) { - if (defined($self->{result}->{$name}->{value}) && defined($self->{result}->{$name}->{unit})) - { - $self->{result}->{$name}->{status} = $self->{perfdata}->threshold_check(value => $self->{result}->{$name}->{value}, - threshold => [{ label => 'critical', exit_litteral => 'critical' }, - { label => 'warning', exit_litteral => 'warning' }]); - $self->{output}->perfdata_add(label => $self->{result}->{$name}->{name}, - value => $self->{result}->{$name}->{value}.$self->{result}->{$name}->{unit}, - warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning'), - critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical'), - min => 0); - } - - if (!$self->{output}->is_status(value => $self->{result}->{$name}->{status}, compare => 'ok', litteral => 1)) - { - $msg = sprintf("Trunk: %s", $self->{result}->{$name}->{name}); - $self->{output}->output_add(severity => $self->{result}->{$name}->{status}, - short_msg => $msg); - if ($self->{result}->{$name}->{realstatus} eq 'Unreachable') - { - $self->{output}->output_add(long_msg => sprintf("%s : %s", $self->{result}->{$name}->{name}, $self->{result}->{$name}->{realstatus})); - } - else - { - $self->{output}->output_add(long_msg => sprintf("%s : %s", $self->{result}->{$name}->{name}, $self->{result}->{$name}->{value})); - } - } - } - - $self->{output}->display(); - $self->{output}->exit(); -} - -1; - -__END__ - -=head1 MODE - -Show peers for different protocols. - -=over 8 - -=item B<--warning> - -Threshold warning. - -=item B<--critical> - -Threshold critical. - -=item B<--remote> - -Execute command remotely; can be 'ami' or 'ssh' (default: ssh). - -=item B<--hostname> - -Hostname to query (need --remote option). - -=item B<--port> - -AMI remote port (default: 5038). - -=item B<--username> - -AMI username. - -=item B<--password> - -AMI password. - -=item B<--ssh-option> - -Specify multiple options like the user (example: --ssh-option='-l=centreon-engine' --ssh-option='-p=52'). - -=item B<--ssh-path> - -Specify ssh command path (default: none) - -=item B<--ssh-command> - -Specify ssh command (default: 'ssh'). Useful to use 'plink'. - -=item B<--timeout> - -Timeout in seconds for the command (Default: 30). - -=item B<--command> - -Command to get information (Default: 'asterisk_sendcommand.pm'). -Can be changed if you have output in a file. - -=item B<--command-path> - -Command path (Default: /home/centreon/bin). - -=item B<--filter-name> - -Filter on trunkname (regexp can be used). - -=item B<--protocol> - -show peer for the choosen protocol (sip or iax). - -=back - -=cut \ No newline at end of file diff --git a/centreon-plugins/apps/voip/asterisk/remote/remote-script/asterisk_centreon.conf b/centreon-plugins/apps/voip/asterisk/remote/remote-script/asterisk_centreon.conf deleted file mode 100644 index 0d3576665..000000000 --- a/centreon-plugins/apps/voip/asterisk/remote/remote-script/asterisk_centreon.conf +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/centreon-plugins/apps/voip/asterisk/remote/remote-script/asterisk_sendcommand.pm b/centreon-plugins/apps/voip/asterisk/remote/remote-script/asterisk_sendcommand.pm deleted file mode 100755 index 0b30a7050..000000000 --- a/centreon-plugins/apps/voip/asterisk/remote/remote-script/asterisk_sendcommand.pm +++ /dev/null @@ -1,114 +0,0 @@ -#!/usr/bin/perl -w -# -# Copyright (C) 2005 Rodolphe Quiedeville -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; version 2 dated June, -# 1991. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -# -# If you improve this script please send your version to my email address -# with the copyright notice upgrade with your name. -# -# -# $Log$ -# Revision 1.0 2015/01/16 11:15 David Sabatie -# Release based on already existing munin script -# -# Parameters mandatory: -# -# username -# secret -# -#%# family=asterisk -#%# capabilities=autoconf - -use strict; -use File::Basename; - -my $ret = undef; -if (! eval "require Net::Telnet;") -{ - $ret = "Net::Telnet not found"; -} - -my $DIRNAME=dirname($0); -my $conffile=$DIRNAME."/asterisk_centreon.conf"; - -my $command; -if ( (defined($ARGV[0])) && ($ARGV[0] ne '') ) -{ - $command = $ARGV[0]; -} -else -{ - print 'No command to send'; - exit; -} - -my $host = exists $ENV{'host'} ? $ENV{'host'} : "127.0.0.1"; -my $port = exists $ENV{'port'} ? $ENV{'port'} : "5038"; - -#[asterisk_*] -#env.username xivo_centreon_user -#env.secret secretpass - -my ($username, $secret); - -open FILE, $conffile or die $!; -while (my $confline = ) -{ - ($username, $secret) = split(' ', $confline); -} -close(FILE); - -my $pop = new Net::Telnet (Telnetmode => 0); -$pop->open(Host => $host, - Port => $port); - -## Read connection message. -my $line = $pop->getline; -die $line unless $line =~ /^Asterisk/; - -## Send user name. -$pop->print("Action: login"); -$pop->print("Username: $username"); -$pop->print("Secret: $secret"); -$pop->print("Events: off"); -$pop->print(""); - -#Response: Success -#Message: Authentication accepted - -$line = $pop->getline; -$line = $pop->getline; -if ($line !~ /^Message: Authentication accepted/) { - print 'Unable to connect to AMI: ' . $line; - exit; -} - -## Request status of messages. -$pop->print("Action: command"); -$pop->print("Command: ".$command); -$pop->print(""); -$line = $pop->getline; -$line = $pop->getline; -$line = $pop->getline; -while (($line = $pop->getline) and ($line !~ /END COMMAND/o)) -{ - print $line; -} -$pop->print("Action: logoff"); -$pop->print(""); -$pop->close(); - -# vim:syntax=perl diff --git a/centreon-plugins/apps/voip/asterisk/snmp/mode/activecalls.pm b/centreon-plugins/apps/voip/asterisk/snmp/mode/activecalls.pm deleted file mode 100644 index c9cf8fe06..000000000 --- a/centreon-plugins/apps/voip/asterisk/snmp/mode/activecalls.pm +++ /dev/null @@ -1,127 +0,0 @@ -# -# Copyright 2017 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::voip::asterisk::snmp::mode::activecalls; - -use base qw(centreon::plugins::mode); - -use strict; -use warnings; -use centreon::plugins::statefile; - -my $oid_astBase = '.1.3.6.1.4.1.22736'; -my $oid_astConfigCallsActive = $oid_astBase.'.1.2.5.0'; -#my $oid_AsteriskConfigCallsProcessed = $oid_AsteriskBase.'.1.2.6.0'; - -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 => - { - "warning:s" => { name => 'warning', }, - "critical:s" => { name => 'critical', }, - "force-oid:s" => { name => 'force_oid', }, - }); - $self->{statefile_value} = centreon::plugins::statefile->new(%options); - 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(); - } - - $self->{statefile_value}->check_options(%options); -} - -sub run { - my ($self, %options) = @_; - $self->{snmp} = $options{snmp}; - - my ($result, $value); - - if (defined($self->{option_results}->{force_oid})) { - $result = $self->{snmp}->get_leef(oids => [ $self->{option_results}->{force_oid} ], nothing_quit => 1); - $value = $result->{$self->{option_results}->{force_oid}}; - } else { - $result = $self->{snmp}->get_leef(oids => [ $oid_astConfigCallsActive ], nothing_quit => 1); - $value = $result->{$oid_astConfigCallsActive}; - } - - if (!defined($value)) { - $self->{output}->output_add(severity => 'Unknown', - short_msg => sprintf("No information available for active channel") - ); - $self->{output}->display(); - $self->{output}->exit(); - } - - my $exit_code = $self->{perfdata}->threshold_check(value => $value, - threshold => [ { label => 'critical', 'exit_litteral' => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]); - $self->{output}->perfdata_add(label => 'Calls', - value => $value, - warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning'), - critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical'), - min => 0); - - $self->{output}->output_add(severity => $exit_code, - short_msg => sprintf("Current active calls: %s", $value) - ); - - $self->{output}->display(); - $self->{output}->exit(); -} - -1; - -__END__ - -=head1 MODE - -Check number of active calls. - -=over 8 - -=item B<--warning> - -Threshold warning. - -=item B<--critical> - -Threshold critical. - -=item B<--force-oid> - -Can choose your oid (numeric format only). - -=back - -=cut diff --git a/centreon-plugins/apps/voip/asterisk/snmp/mode/channelusage.pm b/centreon-plugins/apps/voip/asterisk/snmp/mode/channelusage.pm new file mode 100644 index 000000000..1fb70b503 --- /dev/null +++ b/centreon-plugins/apps/voip/asterisk/snmp/mode/channelusage.pm @@ -0,0 +1,121 @@ +# +# Copyright 2017 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::voip::asterisk::snmp::mode::channelusage; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; +use Digest::MD5 qw(md5_hex); + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'global', type => 0 }, + ]; + $self->{maps_counters}->{global} = [ + { label => 'channels-active', set => { + key_values => [ { name => 'channels_active' } ], + output_template => 'Channels Active: %s', + perfdatas => [ + { label => 'channels_active', value => 'channels_active_absolute', template => '%s', min => 0 }, + ], + } + }, + { label => 'calls-active', set => { + key_values => [ { name => 'calls_active' } ], + output_template => 'Calls Active: %s', + perfdatas => [ + { label => 'calls_active', value => 'calls_active_absolute', template => '%s', min => 0 }, + ], + } + }, + { label => 'calls-count', set => { + key_values => [ { name => 'calls_count', diff => 1 } ], + output_template => 'Calls Count: %s', + perfdatas => [ + { label => 'calls_count', value => 'calls_count_absolute', template => '%s', min => 0 }, + ], + } + }, + ]; +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options, statefile => 1); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => + { + }); + + return $self; +} + +sub manage_selection { + my ($self, %options) = @_; + + my $oid_astConfigCallsActive = '.1.3.6.1.4.1.22736.1.2.5.0'; + my $oid_astConfigCallsProcessed = '.1.3.6.1.4.1.22736.1.2.6.0'; + my $oid_astNumChannels = '.1.3.6.1.4.1.22736.1.5.1.0'; + my $result = $options{snmp}->get_leef(oids => [$oid_astConfigCallsActive, $oid_astConfigCallsProcessed, $oid_astNumChannels], nothing_quit => 1); + + $self->{cache_name} = "asterisk_" . $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} = { + calls_active => $result->{$oid_astConfigCallsActive}, + calls_count => $result->{$oid_astConfigCallsProcessed}, + channels_active => $result->{$oid_astNumChannels}, + }; +} + +1; + +__END__ + +=head1 MODE + +Check channel usage. + +=over 8 + +=item B<--filter-counters> + +Only display some counters (regexp can be used). +Example: --filter-counters='calls-active' + +=item B<--warning-*> + +Threshold warning. +Can be: 'channels-active', 'calls-active', 'calls-count'. + +=item B<--critical-*> + +Threshold critical. +Can be: 'channels-active', 'calls-active', 'calls-count'. + +=back + +=cut diff --git a/centreon-plugins/apps/voip/asterisk/snmp/mode/externalcalls.pm b/centreon-plugins/apps/voip/asterisk/snmp/mode/externalcalls.pm deleted file mode 100644 index 31748c3f8..000000000 --- a/centreon-plugins/apps/voip/asterisk/snmp/mode/externalcalls.pm +++ /dev/null @@ -1,224 +0,0 @@ -# -# Copyright 2017 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::voip::asterisk::snmp::mode::externalcalls; - -use base qw(centreon::plugins::mode); - -use strict; -use warnings; -use centreon::plugins::statefile; - -my $oid_astBase = '.1.3.6.1.4.1.22736'; -my $oid_astConfigCallsActive = $oid_astBase.'.1.2.5.0'; -my $oid_astChanName = $oid_astBase.'.1.5.2.1.2'; # need an index at the end -my $oid_astChanIndex = $oid_astBase.'.1.5.2.1.1'; # need an index at the end -my $oid_astNumChannels = $oid_astBase.'.1.5.1.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 => - { - "warning:s" => { name => 'warning', }, - "critical:s" => { name => 'critical', }, - "warnontrunk:s" => { name => 'warnontrunk', }, - "critontrunk:s" => { name => 'critontrunk', }, - "force-oid:s" => { name => 'force_oid', }, - "trunkusernamelist:s" => { name => 'trunkusernamelist', }, - "filter-name" => { name => 'filter-name' }, - }); - $self->{statefile_value} = centreon::plugins::statefile->new(%options); - 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 (($self->{perfdata}->threshold_validate(label => 'warnontrunk', value => $self->{option_results}->{warnontrunk})) == 0) { - $self->{output}->add_option_msg(short_msg => "Wrong warning threshold '" . $self->{option_results}->{warnontrunk} . "'."); - $self->{output}->option_exit(); - } - if (($self->{perfdata}->threshold_validate(label => 'critontrunk', value => $self->{option_results}->{critontrunk})) == 0) { - $self->{output}->add_option_msg(short_msg => "Wrong critical threshold '" . $self->{option_results}->{critontrunk} . "'."); - $self->{output}->option_exit(); - } - if (!defined($self->{option_results}->{trunkusernamelist})) { - $self->{output}->add_option_msg(short_msg => "trunkusernamelist must be defined."); - $self->{output}->option_exit(); - } - - $self->{statefile_value}->check_options(%options); -} - -sub run { - my ($self, %options) = @_; - $self->{snmp} = $options{snmp}; - - my ($result, $value); - my (@callsbytrunk, @error_msg, @msg); - - # explode trunk list - my @trunkusernamelist = split(',',$self->{option_results}->{trunkusernamelist}); - foreach my $trunk (@trunkusernamelist) - { - if (defined($self->{option_results}->{filter_name}) && $self->{option_results}->{filter_name} ne '' && - $trunk !~ /$self->{option_results}->{filter_name}/) { - $self->{output}->output_add(long_msg => "Skipping trunk '" . $trunk . "': no matching filter name"); - next; - } - push @callsbytrunk , { trunk => $trunk, num => 0}; - } - # get chanName and sum calls for each - $result = $self->{snmp}->get_leef(oids => [ $oid_astNumChannels ], nothing_quit => 1); - my $astNumChannels = $result->{$oid_astNumChannels}; - my $astConfigCallsActive = 0; - foreach my $i (1..$astNumChannels) { - $result = $self->{snmp}->get_leef(oids => [ $oid_astChanName.'.'.$i ], nothing_quit => 1); - $value = $result->{$oid_astChanName.'.'.$i}; - $value =~ /^(.*)\/(.*)-.*/; - my ($protocol, $trunkname) = ($1, $2); - foreach my $val (@callsbytrunk) - { - if ( $val->{trunk} eq $trunkname ) - { - $val->{num} = $val->{num}+1; - $astConfigCallsActive = $astConfigCallsActive+1; - } - } - } - - # compute status based on total number of active calls - my $exit_code = $self->{perfdata}->threshold_check(value => $astConfigCallsActive, - threshold => [ { label => 'critical', exit_litteral => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]); - push @msg, {msg => sprintf("Current external calls: %s", $astConfigCallsActive)}; - - # Perfdata on all active calls - $self->{output}->perfdata_add(label => 'Total calls', - value => $astConfigCallsActive, - warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning'), - critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical'), - min => 0); - - # Perfdata on number of calls for each trunk - my ($temp_exit, $exit_msg); - my (@trunk_msg, @out_msg); - my $trunk_exit_code = 'ok'; - foreach $value (@callsbytrunk) - { - $temp_exit = $self->{perfdata}->threshold_check(value => $value->{num}, - threshold => [ { label => 'critontrunk', exit_litteral => 'critical' }, { label => 'warnontrunk', exit_litteral => 'warning' } ]); - $self->{output}->perfdata_add(label => $value->{trunk}, - value => $value->{num}, - warning => $self->{perfdata}->get_perfdata_for_output(label => 'warnontrunk'), - critical => $self->{perfdata}->get_perfdata_for_output(label => 'critontrunk'), - min => 0); - $self->{output}->output_add(long_msg => sprintf("%s : %s", $value->{trunk}, $value->{num})); - - $trunk_exit_code = $self->{output}->get_most_critical(status => [ $temp_exit, $trunk_exit_code ]); - # create msg for most critical data .... - if ($self->{output}->is_status(value => $temp_exit, compare => $trunk_exit_code, litteral => 1)) - { - push @trunk_msg, {msg => sprintf("'%s': %s", $value->{trunk}, $value->{num})}; - } - } - if (!$self->{output}->is_status(value => $exit_code, compare => 'ok', litteral => 1) && !$self->{output}->is_status(value => $trunk_exit_code, compare => 'ok', litteral => 1)) - { - unshift @trunk_msg, @msg; - $exit_code = $self->{output}->get_most_critical(status => [ $exit_code, $trunk_exit_code ]); - } - if (!$self->{output}->is_status(value => $trunk_exit_code, compare => 'ok', litteral => 1)) - { - @out_msg=@trunk_msg; - $exit_code = $trunk_exit_code ; - } - else - { - push @out_msg, @msg; - } - - $exit_msg = ''; - my $separator = ''; - foreach my $out (@out_msg) - { - $exit_msg .= $separator.$out->{msg}; - $separator = ', '; - } - $self->{output}->output_add(severity => $exit_code, - short_msg => $exit_msg - ); - - $self->{output}->display(); - $self->{output}->exit(); -} - -1; - -__END__ - -=head1 MODE - -Check number of external calls (total and by trunk) - -=over 8 - -=item B<--warning> - -Threshold warning for total number of external calls. - -=item B<--critical> - -Threshold critical for total number of external calls. - -=item B<--warnontrunk> - -Threshold warning for trunks. - -=item B<--critontrunk> - -Threshold critical for trunks. - -=item B<--force-oid> - -Can choose your oid (numeric format only). - -=item B<--trunkusernamelist> - -List of outgoing trunks' username. - -=item B<--filter-name> - -Filter on trunk's username (regexp can be used). - -=back - -=cut \ No newline at end of file diff --git a/centreon-plugins/apps/voip/asterisk/snmp/plugin.pm b/centreon-plugins/apps/voip/asterisk/snmp/plugin.pm index d6811d6f3..61a0bb3b5 100644 --- a/centreon-plugins/apps/voip/asterisk/snmp/plugin.pm +++ b/centreon-plugins/apps/voip/asterisk/snmp/plugin.pm @@ -32,9 +32,8 @@ sub new { $self->{version} = '0.1'; %{$self->{modes}} = ( - 'activecalls' => 'apps::voip::asterisk::snmp::mode::activecalls', - 'externalcalls' => 'apps::voip::asterisk::snmp::mode::externalcalls', - ); + 'channel-usage' => 'apps::voip::asterisk::snmp::mode::channelusage', + ); return $self; } diff --git a/centreon-plugins/centreon/common/bluearc/snmp/mode/hardware.pm b/centreon-plugins/centreon/common/bluearc/snmp/mode/hardware.pm index 65d823a85..4a951e44e 100644 --- a/centreon-plugins/centreon/common/bluearc/snmp/mode/hardware.pm +++ b/centreon-plugins/centreon/common/bluearc/snmp/mode/hardware.pm @@ -1,5 +1,5 @@ # -# Copyright 2016 Centreon (http://www.centreon.com/) +# Copyright 2017 Centreon (http://www.centreon.com/) # # Centreon is a full-fledged industry-strength solution that meets # the needs in IT infrastructure and application monitoring for diff --git a/centreon-plugins/centreon/common/broadcom/fastpath/snmp/mode/components/fan.pm b/centreon-plugins/centreon/common/broadcom/fastpath/snmp/mode/components/fan.pm new file mode 100644 index 000000000..ab37053e9 --- /dev/null +++ b/centreon-plugins/centreon/common/broadcom/fastpath/snmp/mode/components/fan.pm @@ -0,0 +1,86 @@ +# +# Copyright 2017 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 centreon::common::broadcom::fastpath::snmp::mode::components::fan; + +use strict; +use warnings; + +my %map_fan_status = ( + 1 => 'notpresent', 2 => 'operational', 3 => 'failed', 4 => 'powering', + 5 => 'nopower', 6 => 'notpowering', 7 => 'incompatible' +); + +my $mapping = { + boxServicesFanItemState => { oid => '.1.3.6.1.4.1.4413.1.1.43.1.6.1.3', map => \%map_fan_status }, + boxServicesFanSpeed => { oid => '.1.3.6.1.4.1.4413.1.1.43.1.6.1.4' }, +}; +my $oid_boxServicesFansEntry = '.1.3.6.1.4.1.4413.1.1.43.1.6.1'; + +sub load { + my ($self) = @_; + + push @{$self->{request}}, { oid => $oid_boxServicesFansEntry, begin => $mapping->{boxServicesFanItemState}->{oid}, end => $mapping->{boxServicesFanSpeed}->{oid} }; +} + +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')); + + my ($exit, $warn, $crit, $checked); + foreach my $oid ($self->{snmp}->oid_lex_sort(keys %{$self->{results}->{$oid_boxServicesFansEntry}})) { + next if ($oid !~ /^$mapping->{boxServicesFanItemState}->{oid}\.(.*)$/); + my $instance = $1; + my $result = $self->{snmp}->map_instance(mapping => $mapping, results => $self->{results}->{$oid_boxServicesFansEntry}, instance => $instance); + + next if ($self->check_filter(section => 'fan', instance => $instance)); + if ($result->{boxServicesFanItemState} =~ /notpresent/i) { + $self->absent_problem(section => 'fan', instance => $instance); + next; + } + + $self->{components}->{fan}->{total}++; + $self->{output}->output_add(long_msg => sprintf("fan '%s' status is '%s' [instance = %s, speed = %s]", + $instance, $result->{boxServicesFanItemState}, $instance, defined($result->{boxServicesFanSpeed}) ? $result->{boxServicesFanSpeed} : 'unknown')); + $exit = $self->get_severity(label => 'default', section => 'fan', value => $result->{boxServicesFanItemState}); + 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->{boxServicesFanItemState})); + } + + next if (!defined($result->{boxServicesFanSpeed}) || $result->{boxServicesFanSpeed} !~ /[0-9]+/); + + ($exit, $warn, $crit, $checked) = $self->get_severity_numeric(section => 'fan', instance => $instance, value => $result->{boxServicesFanSpeed}); + if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { + $self->{output}->output_add(severity => $exit, + short_msg => sprintf("Fan '%s' is '%s' rpm", $instance, $result->{boxServicesFanSpeed})); + } + $self->{output}->perfdata_add(label => 'fan_' . $instance, unit => 'rpm', + value => $result->{boxServicesFanSpeed}, + warning => $warn, + critical => $crit, min => 0 + ); + } +} + +1; diff --git a/centreon-plugins/centreon/common/broadcom/fastpath/snmp/mode/components/psu.pm b/centreon-plugins/centreon/common/broadcom/fastpath/snmp/mode/components/psu.pm new file mode 100644 index 000000000..6b8767ece --- /dev/null +++ b/centreon-plugins/centreon/common/broadcom/fastpath/snmp/mode/components/psu.pm @@ -0,0 +1,71 @@ +# +# Copyright 2017 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 centreon::common::broadcom::fastpath::snmp::mode::components::psu; + +use strict; +use warnings; + +my %map_psu_status = ( + 1 => 'notpresent', 2 => 'operational', 3 => 'failed', 4 => 'powering', + 5 => 'nopower', 6 => 'notpowering', 7 => 'incompatible' +); + +my $mapping = { + boxServicesPowSupplyItemState => { oid => '.1.3.6.1.4.1.4413.1.1.43.1.7.1.3', map => \%map_psu_status }, +}; + +sub load { + my ($self) = @_; + + push @{$self->{request}}, { oid => $mapping->{boxServicesPowSupplyItemState}->{oid} }; +} + +sub check { + my ($self) = @_; + + $self->{output}->output_add(long_msg => "Checking power supplies"); + $self->{components}->{psu} = {name => 'psu', total => 0, skip => 0}; + return if ($self->check_filter(section => 'psu')); + + my ($exit, $warn, $crit, $checked); + foreach my $oid ($self->{snmp}->oid_lex_sort(keys %{$self->{results}->{$mapping->{boxServicesPowSupplyItemState}->{oid}}})) { + next if ($oid !~ /^$mapping->{boxServicesPowSupplyItemState}->{oid}\.(.*)$/); + my $instance = $1; + my $result = $self->{snmp}->map_instance(mapping => $mapping, results => $self->{results}->{$mapping->{boxServicesPowSupplyItemState}->{oid}}, instance => $instance); + + next if ($self->check_filter(section => 'psu', instance => $instance)); + if ($result->{boxServicesPowSupplyItemState} =~ /notpresent/i) { + $self->absent_problem(section => 'psu', instance => $instance); + next; + } + + $self->{components}->{psu}->{total}++; + $self->{output}->output_add(long_msg => sprintf("power supply '%s' status is '%s' [instance = %s]", + $instance, $result->{boxServicesPowSupplyItemState}, $instance)); + $exit = $self->get_severity(label => 'default', section => 'psu', value => $result->{boxServicesPowSupplyItemState}); + 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->{boxServicesPowSupplyItemState})); + } + } +} + +1; diff --git a/centreon-plugins/centreon/common/broadcom/fastpath/snmp/mode/components/temperature.pm b/centreon-plugins/centreon/common/broadcom/fastpath/snmp/mode/components/temperature.pm new file mode 100644 index 000000000..bf85207ee --- /dev/null +++ b/centreon-plugins/centreon/common/broadcom/fastpath/snmp/mode/components/temperature.pm @@ -0,0 +1,86 @@ +# +# Copyright 2017 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 centreon::common::broadcom::fastpath::snmp::mode::components::temperature; + +use strict; +use warnings; + +my %map_temp_status = ( + 0 => 'low', 1 => 'normal', 2 => 'warning', 3 => 'critical', + 4 => 'shutdown', 5 => 'notpresent', 6 => 'notoperational', +); + +my $mapping = { + boxServicesTempSensorState => { oid => '.1.3.6.1.4.1.4413.1.1.43.1.8.1.4', map => \%map_temp_status }, + boxServicesTempSensorTemperature => { oid => '.1.3.6.1.4.1.4413.1.1.43.1.8.1.5' }, +}; +my $oid_boxServicesTempSensorsEntry = '.1.3.6.1.4.1.4413.1.1.43.1.8.1'; + +sub load { + my ($self) = @_; + + push @{$self->{request}}, { oid => $oid_boxServicesTempSensorsEntry, begin => $mapping->{boxServicesTempSensorState}->{oid}, end => $mapping->{boxServicesTempSensorTemperature}->{oid} }; +} + +sub check { + my ($self) = @_; + + $self->{output}->output_add(long_msg => "Checking temperatures"); + $self->{components}->{temperature} = {name => 'temperatures', total => 0, skip => 0}; + return if ($self->check_filter(section => 'temperature')); + + my ($exit, $warn, $crit, $checked); + foreach my $oid ($self->{snmp}->oid_lex_sort(keys %{$self->{results}->{$oid_boxServicesTempSensorsEntry}})) { + next if ($oid !~ /^$mapping->{boxServicesTempSensorState}->{oid}\.(.*)$/); + my $instance = $1; + my $result = $self->{snmp}->map_instance(mapping => $mapping, results => $self->{results}->{$oid_boxServicesTempSensorsEntry}, instance => $instance); + + next if ($self->check_filter(section => 'temperature', instance => $instance)); + if ($result->{boxServicesTempSensorState} =~ /notpresent/i) { + $self->absent_problem(section => 'temperature', instance => $instance); + next; + } + + $self->{components}->{temperature}->{total}++; + $self->{output}->output_add(long_msg => sprintf("temperature '%s' status is '%s' [instance = %s, temperature = %s]", + $instance, $result->{boxServicesTempSensorState}, $instance, defined($result->{boxServicesTempSensorTemperature}) ? $result->{boxServicesTempSensorTemperature} : 'unknown')); + $exit = $self->get_severity(section => 'temperature', value => $result->{boxServicesTempSensorState}); + if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { + $self->{output}->output_add(severity => $exit, + short_msg => sprintf("Temperature '%s' status is '%s'", $instance, $result->{boxServicesTempSensorState})); + } + + next if (!defined($result->{boxServicesTempSensorTemperature}) || $result->{boxServicesTempSensorTemperature} !~ /[0-9]+/); + + ($exit, $warn, $crit, $checked) = $self->get_severity_numeric(section => 'temperature', instance => $instance, value => $result->{boxServicesTempSensorTemperature}); + if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { + $self->{output}->output_add(severity => $exit, + short_msg => sprintf("Temperature '%s' is '%s' rpm", $instance, $result->{boxServicesTempSensorTemperature})); + } + $self->{output}->perfdata_add(label => 'temp_' . $instance, unit => 'C', + value => $result->{boxServicesTempSensorTemperature}, + warning => $warn, + critical => $crit, + ); + } +} + +1; diff --git a/centreon-plugins/centreon/common/broadcom/fastpath/snmp/mode/cpu.pm b/centreon-plugins/centreon/common/broadcom/fastpath/snmp/mode/cpu.pm new file mode 100644 index 000000000..bdcde39c0 --- /dev/null +++ b/centreon-plugins/centreon/common/broadcom/fastpath/snmp/mode/cpu.pm @@ -0,0 +1,123 @@ +# +# Copyright 2017 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 centreon::common::broadcom::fastpath::snmp::mode::cpu; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'global', type => 0, cb_prefix_output => 'prefix_cpu_output' } + ]; + + $self->{maps_counters}->{global} = [ + { label => '5s', set => { + key_values => [ { name => 'usage_5s' } ], + output_template => '%.2f %% (5sec)', output_error_template => "%s (5sec)", + perfdatas => [ + { label => 'cpu_5s', value => 'usage_5s_absolute', template => '%.2f', + unit => '%', min => 0, max => 100 }, + ], + } + }, + { label => '1m', set => { + key_values => [ { name => 'usage_1m' } ], + output_template => '%.2f %% (1m)', output_error_template => "%s (1min)", + perfdatas => [ + { label => 'cpu_1m', value => 'usage_1m_absolute', template => '%.2f', + unit => '%', min => 0, max => 100 }, + ], + } + }, + { label => '5m', set => { + key_values => [ { name => 'usage_5m' } ], + output_template => '%.2f %% (5min)', output_error_template => "%s (5min)", + perfdatas => [ + { label => 'cpu_5m', value => 'usage_5m_absolute', template => '%.2f', + unit => '%', min => 0, max => 100 }, + ], + } + }, + ]; +} + +sub prefix_cpu_output { + my ($self, %options) = @_; + + return "CPU "; +} + +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 => + { + }); + + return $self; +} + +sub manage_selection { + my ($self, %options) = @_; + + # STRING: " 5 Secs ( 43.2625%) 60 Secs ( 13.9157%) 300 Secs ( 8.9274%)" + my $oid_agentSwitchCpuProcessTotalUtilization = '.1.3.6.1.4.1.4413.1.1.1.1.4.9.0'; + my $snmp_result = $options{snmp}->get_leef(oids => [$oid_agentSwitchCpuProcessTotalUtilization], nothing_quit => 1); + + $snmp_result->{$oid_agentSwitchCpuProcessTotalUtilization} =~ /\s*5\s*Secs\s*\(\s*(.*?)%\s*\)\s*60\s*Secs\s*\(\s*(.*?)%\s*\)\s*300\s*Secs\s*\(\s*(.*?)%\s*\)/i; + $self->{global} = { usage_5s => $1, usage_1m => $2, usage_5m => $3 }; +} + +1; + +__END__ + +=head1 MODE + +Check CPU usage. + +=over 8 + +=item B<--filter-counters> + +Only display some counters (regexp can be used). +Example: --filter-counters='5m' + +=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/centreon-plugins/centreon/common/broadcom/fastpath/snmp/mode/hardware.pm b/centreon-plugins/centreon/common/broadcom/fastpath/snmp/mode/hardware.pm new file mode 100644 index 000000000..6257ea940 --- /dev/null +++ b/centreon-plugins/centreon/common/broadcom/fastpath/snmp/mode/hardware.pm @@ -0,0 +1,129 @@ +# +# Copyright 2017 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 centreon::common::broadcom::fastpath::snmp::mode::hardware; + +use base qw(centreon::plugins::templates::hardware); + +use strict; +use warnings; + +sub set_system { + my ($self, %options) = @_; + + $self->{regexp_threshold_overload_check_section_option} = '^(temperature|fan|psu)$'; + $self->{regexp_threshold_numeric_check_section_option} = '^(temperature|fan)$'; + + $self->{cb_hook2} = 'snmp_execute'; + + $self->{thresholds} = { + default => [ + ['notPresent', 'OK'], + ['operational', 'OK'], + ['failed', 'CRITICAL'], + ['notpowering', 'WARNING'], + ['powering', 'OK'], + ['nopower', 'OK'], + ['incompatible', 'WARNING'], + ], + temperature => [ + ['low', 'OK'], + ['normal', 'OK'], + ['warning', 'WARNING'], + ['critical', 'CRITICAL'], + ['notpresent', 'OK'], + ['shutdown', 'OK'], + ['notoperational', 'WARNING'], + ], + }; + + $self->{components_path} = 'centreon::common::broadcom::fastpath::snmp::mode::components'; + $self->{components_module} = ['fan', 'psu', 'temperature']; +} + +sub snmp_execute { + my ($self, %options) = @_; + + $self->{snmp} = $options{snmp}; + $self->{results} = $self->{snmp}->get_multiple_table(oids => $self->{request}); +} + +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 => + { + }); + + return $self; +} + +1; + +__END__ + +=head1 MODE + +Check hardware. + +=over 8 + +=item B<--component> + +Which component to check (Default: '.*'). +Can be: 'fan', 'psu', 'temperature'. + +=item B<--filter> + +Exclude some parts (comma seperated list) (Example: --filter=fan --filter=psu) +Can also exclude specific instance: --filter=fan,1.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,1 + +=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='psu,CRITICAL,^(?!(operational)$)' + +=item B<--warning> + +Set warning threshold for 'temperature', 'fan' (syntax: type,regexp,threshold) +Example: --warning='temperature,.*,40' + +=item B<--critical> + +Set critical threshold for 'temperature', 'fan' (syntax: type,regexp,threshold) +Example: --critical='temperature,.*,50' + +=back + +=cut diff --git a/centreon-plugins/centreon/common/broadcom/fastpath/snmp/mode/memory.pm b/centreon-plugins/centreon/common/broadcom/fastpath/snmp/mode/memory.pm new file mode 100644 index 000000000..3bee13503 --- /dev/null +++ b/centreon-plugins/centreon/common/broadcom/fastpath/snmp/mode/memory.pm @@ -0,0 +1,138 @@ +# +# Copyright 2017 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 centreon::common::broadcom::fastpath::snmp::mode::memory; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; + +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 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}->{prct_used} = $options{new_datas}->{$self->{instance} . '_prct_used'}; + + $self->{result_values}->{used} = int($self->{result_values}->{prct_used} * $self->{result_values}->{total} / 100); + $self->{result_values}->{free} = $self->{result_values}->{total} - $self->{result_values}->{used}; + $self->{result_values}->{prct_free} = 100 - $self->{result_values}->{prct_used}; + + return 0; +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'memory', type => 0 } + ]; + + $self->{maps_counters}->{memory} = [ + { label => 'usage', set => { + key_values => [ { name => 'prct_used' }, { name => 'total' } ], + closure_custom_calc => $self->can('custom_usage_calc'), + closure_custom_output => $self->can('custom_usage_output'), + closure_custom_perfdata => $self->can('custom_usage_perfdata'), + closure_custom_threshold_check => $self->can('custom_usage_threshold'), + } + }, + ]; +} + +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 => + { + }); + + return $self; +} + +sub manage_selection { + my ($self, %options) = @_; + + my $oid_agentSwitchCpuProcessMemFree = '.1.3.6.1.4.1.4413.1.1.1.1.4.1.0'; # KB + my $oid_agentSwitchCpuProcessMemAvailable = '.1.3.6.1.4.1.4413.1.1.1.1.4.2.0'; # KB + my $snmp_result = $options{snmp}->get_leef(oids => [$oid_agentSwitchCpuProcessMemFree, $oid_agentSwitchCpuProcessMemAvailable], nothing_quit => 1); + + my $total = $snmp_result->{$oid_agentSwitchCpuProcessMemAvailable} * 1024; + $self->{memory} = { + prct_used => ($total - $snmp_result->{$oid_agentSwitchCpuProcessMemFree} * 1024) * 100 / $total, + total => $total, + }; +} + +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 diff --git a/centreon-plugins/centreon/common/fastpath/mode/components/fan.pm b/centreon-plugins/centreon/common/dell/fastpath/snmp/mode/components/fan.pm similarity index 98% rename from centreon-plugins/centreon/common/fastpath/mode/components/fan.pm rename to centreon-plugins/centreon/common/dell/fastpath/snmp/mode/components/fan.pm index 1017e753f..564834bf9 100644 --- a/centreon-plugins/centreon/common/fastpath/mode/components/fan.pm +++ b/centreon-plugins/centreon/common/dell/fastpath/snmp/mode/components/fan.pm @@ -18,7 +18,7 @@ # limitations under the License. # -package centreon::common::fastpath::mode::components::fan; +package centreon::common::dell::fastpath::snmp::mode::components::fan; use strict; use warnings; @@ -87,4 +87,4 @@ sub check { } } -1; \ No newline at end of file +1; diff --git a/centreon-plugins/centreon/common/fastpath/mode/components/psu.pm b/centreon-plugins/centreon/common/dell/fastpath/snmp/mode/components/psu.pm similarity index 97% rename from centreon-plugins/centreon/common/fastpath/mode/components/psu.pm rename to centreon-plugins/centreon/common/dell/fastpath/snmp/mode/components/psu.pm index 0882fa895..e5b675f6b 100644 --- a/centreon-plugins/centreon/common/fastpath/mode/components/psu.pm +++ b/centreon-plugins/centreon/common/dell/fastpath/snmp/mode/components/psu.pm @@ -18,7 +18,7 @@ # limitations under the License. # -package centreon::common::fastpath::mode::components::psu; +package centreon::common::dell::fastpath::snmp::mode::components::psu; use strict; use warnings; @@ -75,4 +75,4 @@ sub check { } } -1; \ No newline at end of file +1; diff --git a/centreon-plugins/centreon/common/fastpath/mode/components/temperature.pm b/centreon-plugins/centreon/common/dell/fastpath/snmp/mode/components/temperature.pm similarity index 98% rename from centreon-plugins/centreon/common/fastpath/mode/components/temperature.pm rename to centreon-plugins/centreon/common/dell/fastpath/snmp/mode/components/temperature.pm index 6f9c999aa..d72626baa 100644 --- a/centreon-plugins/centreon/common/fastpath/mode/components/temperature.pm +++ b/centreon-plugins/centreon/common/dell/fastpath/snmp/mode/components/temperature.pm @@ -18,7 +18,7 @@ # limitations under the License. # -package centreon::common::fastpath::mode::components::temperature; +package centreon::common::dell::fastpath::snmp::mode::components::temperature; use strict; use warnings; @@ -96,4 +96,4 @@ sub check { } } -1; \ No newline at end of file +1; diff --git a/centreon-plugins/centreon/common/fastpath/mode/cpu.pm b/centreon-plugins/centreon/common/dell/fastpath/snmp/mode/cpu.pm similarity index 99% rename from centreon-plugins/centreon/common/fastpath/mode/cpu.pm rename to centreon-plugins/centreon/common/dell/fastpath/snmp/mode/cpu.pm index ac99e514d..8a61c0251 100644 --- a/centreon-plugins/centreon/common/fastpath/mode/cpu.pm +++ b/centreon-plugins/centreon/common/dell/fastpath/snmp/mode/cpu.pm @@ -18,7 +18,7 @@ # limitations under the License. # -package centreon::common::fastpath::mode::cpu; +package centreon::common::dell::fastpath::snmp::mode::cpu; use base qw(centreon::plugins::mode); diff --git a/centreon-plugins/centreon/common/fastpath/mode/environment.pm b/centreon-plugins/centreon/common/dell/fastpath/snmp/mode/environment.pm similarity index 95% rename from centreon-plugins/centreon/common/fastpath/mode/environment.pm rename to centreon-plugins/centreon/common/dell/fastpath/snmp/mode/environment.pm index 5957b2a36..569c85100 100644 --- a/centreon-plugins/centreon/common/fastpath/mode/environment.pm +++ b/centreon-plugins/centreon/common/dell/fastpath/snmp/mode/environment.pm @@ -18,7 +18,7 @@ # limitations under the License. # -package centreon::common::fastpath::mode::environment; +package centreon::common::dell::fastpath::snmp::mode::environment; use base qw(centreon::plugins::templates::hardware); @@ -54,7 +54,7 @@ sub set_system { ], }; - $self->{components_path} = 'centreon::common::fastpath::mode::components'; + $self->{components_path} = 'centreon::common::dell::fastpath::snmp::mode::components'; $self->{components_module} = ['fan', 'psu', 'temperature']; } @@ -126,4 +126,4 @@ Example: --critical='fan,.*,2000' =back -=cut \ No newline at end of file +=cut diff --git a/centreon-plugins/centreon/common/fastpath/mode/memory.pm b/centreon-plugins/centreon/common/dell/fastpath/snmp/mode/memory.pm similarity index 98% rename from centreon-plugins/centreon/common/fastpath/mode/memory.pm rename to centreon-plugins/centreon/common/dell/fastpath/snmp/mode/memory.pm index c643a841f..43d53bd20 100644 --- a/centreon-plugins/centreon/common/fastpath/mode/memory.pm +++ b/centreon-plugins/centreon/common/dell/fastpath/snmp/mode/memory.pm @@ -18,7 +18,7 @@ # limitations under the License. # -package centreon::common::fastpath::mode::memory; +package centreon::common::dell::fastpath::snmp::mode::memory; use base qw(centreon::plugins::mode); diff --git a/centreon-plugins/centreon/common/fortinet/fortigate/mode/sessions.pm b/centreon-plugins/centreon/common/fortinet/fortigate/mode/sessions.pm index 2cd0f0d25..625919fe1 100644 --- a/centreon-plugins/centreon/common/fortinet/fortigate/mode/sessions.pm +++ b/centreon-plugins/centreon/common/fortinet/fortigate/mode/sessions.pm @@ -124,7 +124,7 @@ sub run { threshold => [ { label => 'crit60', exit_litteral => 'critical' }, { label => 'warn60', exit_litteral => 'warning' } ]); $exit = $self->{output}->get_most_critical(status => [ $exit1, $exit2, $exit3, $exit4 ]); $self->{output}->output_add(severity => $exit, - short_msg => sprintf("Averate session setup rate: %s, %s, %s, %s (1min, 10min, 30min, 60min)", + short_msg => sprintf("Average session setup rate: %s, %s, %s, %s (1min, 10min, 30min, 60min)", $result->{$oid_fgSysSesRate1}, $result->{$oid_fgSysSesRate10}, $result->{$oid_fgSysSesRate30}, $result->{$oid_fgSysSesRate60})); @@ -182,4 +182,4 @@ Threshold critical of average setup rate (1min,10min,30min,60min). =back =cut - \ No newline at end of file + diff --git a/centreon-plugins/centreon/common/jvm/mode/classcount.pm b/centreon-plugins/centreon/common/jvm/mode/classcount.pm index 9558c4260..9282f35c5 100644 --- a/centreon-plugins/centreon/common/jvm/mode/classcount.pm +++ b/centreon-plugins/centreon/common/jvm/mode/classcount.pm @@ -20,168 +20,79 @@ package centreon::common::jvm::mode::classcount; -use base qw(centreon::plugins::mode); +use base qw(centreon::plugins::templates::counter); use strict; use warnings; -use centreon::plugins::values; -use centreon::plugins::statefile; use Digest::MD5 qw(md5_hex); -my $instance_mode; +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'global', type => 0, cb_prefix_output => 'prefix_global_output', skipped_code => { -10 => 1 } }, + ]; -my $maps_counters = { - class => { - '000_current' => { set => { key_values => [ { name => 'current' } ], - output_template => 'Current : %s', - perfdatas => [ - { label => 'current', value => 'current_absolute', template => '%s', min => 0 }, - ], - } - }, - '001_loaded' => { set => { key_values => [ { name => 'loaded', diff => 1 } ], - output_template => 'Loaded : %s', - perfdatas => [ - { label => 'loaded', value => 'loaded_absolute', template => '%s', min => 0 }, - ], - } - }, - '003_unloaded' => { set => { key_values => [ { name => 'unloaded', diff => 1 } ], - output_template => 'Unloaded : %s', - perfdatas => [ - { label => 'unloaded', value => 'unloaded_absolute', template => '%s', min => 0 }, - ], - } - }, + $self->{maps_counters}->{global} = [ + { label => 'current', set => { + key_values => [ { name => 'LoadedClassCount' } ], + output_template => 'Current : %s', + perfdatas => [ + { label => 'current', value => 'LoadedClassCount_absolute', template => '%s', min => 0 }, + ], + } }, -}; + { label => 'loaded', set => { + key_values => [ { name => 'TotalLoadedClassCount', diff => 1 } ], + output_template => 'Loaded : %s', + perfdatas => [ + { label => 'loaded', value => 'TotalLoadedClassCount_absolute', template => '%s', min => 0 }, + ], + } + }, + { label => 'unloaded', set => { + key_values => [ { name => 'UnloadedClassCount', diff => 1 } ], + output_template => 'Unloaded : %s', + perfdatas => [ + { label => 'unloaded', value => 'UnloadedClassCount_absolute', template => '%s', min => 0 }, + ], + } + }, + ]; +} + +sub prefix_global_output { + my ($self, %options) = @_; + + return "Class "; +} sub new { my ($class, %options) = @_; - my $self = $class->SUPER::new(package => __PACKAGE__, %options); + my $self = $class->SUPER::new(package => __PACKAGE__, %options, statefile => 1); bless $self, $class; $self->{version} = '1.0'; $options{options}->add_options(arguments => { }); - $self->{statefile_value} = centreon::plugins::statefile->new(%options); - - foreach my $key (('class')) { - 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 (('class')) { - foreach (keys %{$maps_counters->{$key}}) { - $maps_counters->{$key}->{$_}->{obj}->init(option_results => $self->{option_results}); - } - } - - $self->{statefile_value}->check_options(%options); - $instance_mode = $self; - - $self->{overload_th} = {}; - foreach my $val (@{$self->{option_results}->{threshold_overload}}) { - if ($val !~ /^(.*?),(.*?),(.*)$/) { - $self->{output}->add_option_msg(short_msg => "Wrong threshold-overload option '" . $val . "'."); - $self->{output}->option_exit(); - } - my ($section, $status, $filter) = ($1, $2, $3); - 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}; - } -} - -sub run { - my ($self, %options) = @_; - $self->{connector} = $options{custom}; - - $self->manage_selection(); - - $self->{new_datas} = {}; - $self->{statefile_value}->read(statefile => "jvm_standard_" . $self->{mode} . '_' . md5_hex($self->{connector}->{url})); - $self->{new_datas}->{last_timestamp} = time(); - - my ($short_msg, $short_msg_append, $long_msg, $long_msg_append) = ('', '', '', ''); - my @exits; - foreach (sort keys %{$maps_counters->{class}}) { - my $obj = $maps_counters->{class}->{$_}->{obj}; - $obj->set(instance => 'global'); - - my ($value_check) = $obj->execute(values => $self->{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 => "Class $short_msg" - ); - } else { - $self->{output}->output_add(short_msg => "Class $long_msg"); - } - - $self->{statefile_value}->write(data => $self->{new_datas}); - $self->{output}->display(); - $self->{output}->exit(); -} - sub manage_selection { my ($self, %options) = @_; my $mbean = 'java.lang:type=ClassLoading'; - $self->{request} = [ + my $request = [ { mbean => $mbean, attributes => [ { name => 'UnloadedClassCount' }, { name => 'LoadedClassCount' }, { name => 'TotalLoadedClassCount' } ] }, ]; - my $result = $self->{connector}->get_attributes(request => $self->{request}, nothing_quit => 1); + my $result = $options{custom}->get_attributes(request => $request, nothing_quit => 1); + + $self->{global} = { %{$result->{$mbean}} }; - $self->{global} = {}; - $self->{global}->{unloaded} = $result->{$mbean}->{UnloadedClassCount} if (defined($result->{$mbean}->{UnloadedClassCount})); - $self->{global}->{loaded} = $result->{$mbean}->{TotalLoadedClassCount} if (defined($result->{$mbean}->{TotalLoadedClassCount})); - $self->{global}->{current} = $result->{$mbean}->{LoadedClassCount} if (defined($result->{$mbean}->{LoadedClassCount})); + $self->{cache_name} = "jvm_standard_" . $self->{mode} . '_' . md5_hex($options{custom}->get_connection_info()) . '_' . + (defined($self->{option_results}->{filter_counters}) ? md5_hex($self->{option_results}->{filter_counters}) : md5_hex('all')); } 1; @@ -194,6 +105,11 @@ Check Java Class Loading Mbean. =over 8 +=item B<--filter-counters> + +Only display some counters (regexp can be used). +Example: --filter-counters='current' + =item B<--warning-*> Threshold warning. @@ -206,4 +122,4 @@ Can be: 'unloaded', 'loaded', 'current'. =back -=cut \ No newline at end of file +=cut diff --git a/centreon-plugins/centreon/common/jvm/mode/gcusage.pm b/centreon-plugins/centreon/common/jvm/mode/gcusage.pm index 129f2f2f3..786add013 100644 --- a/centreon-plugins/centreon/common/jvm/mode/gcusage.pm +++ b/centreon-plugins/centreon/common/jvm/mode/gcusage.pm @@ -100,7 +100,7 @@ sub manage_selection { $self->{output}->option_exit(); } - $self->{cache_name} = "jvm_standard_" . $self->{mode} . '_' . md5_hex($options{custom}->{url}) . '_' . + $self->{cache_name} = "jvm_standard_" . $self->{mode} . '_' . md5_hex($options{custom}->get_connection_info()) . '_' . (defined($self->{option_results}->{filter_counters}) ? md5_hex($self->{option_results}->{filter_counters}) : md5_hex('all')) . '_' . (defined($self->{option_results}->{filter_name}) ? md5_hex($self->{option_results}->{filter_name}) : md5_hex('all')); } @@ -136,4 +136,4 @@ Can be: 'count', 'time' (ms). =back -=cut \ No newline at end of file +=cut diff --git a/centreon-plugins/centreon/common/jvm/mode/memorydetailed.pm b/centreon-plugins/centreon/common/jvm/mode/memorydetailed.pm index c9817e8e4..044f18df0 100644 --- a/centreon-plugins/centreon/common/jvm/mode/memorydetailed.pm +++ b/centreon-plugins/centreon/common/jvm/mode/memorydetailed.pm @@ -36,7 +36,9 @@ my %mapping_memory = ( 'PS Perm Gen' => 'permanent', 'Perm Gen' => 'permanent', 'Metaspace' => 'permanent', + 'JIT data cache' => 'permanent', 'Code Cache' => 'code', + 'JIT Code Cache' => 'code', 'CMS Old Gen' => 'tenured', 'PS Old Gen' => 'tenured', 'Tenured Gen' => 'tenured', @@ -199,8 +201,8 @@ sub manage_selection { my $result = $options{custom}->get_attributes(request => $self->{request}, nothing_quit => 1); $self->{mem} = {}; - foreach my $key (keys %$result) { - $key =~ /name=(.*?),type/; + foreach my $key (keys %$result) { + $key =~ /(?:[:,])name=(.*?)(?:,|$)/; my $memtype = $1; if (!defined($mapping_memory{$memtype})) { diff --git a/centreon-plugins/centreon/common/jvm/mode/threads.pm b/centreon-plugins/centreon/common/jvm/mode/threads.pm index c5e913ffa..544f0d21e 100644 --- a/centreon-plugins/centreon/common/jvm/mode/threads.pm +++ b/centreon-plugins/centreon/common/jvm/mode/threads.pm @@ -20,168 +20,79 @@ package centreon::common::jvm::mode::threads; -use base qw(centreon::plugins::mode); +use base qw(centreon::plugins::templates::counter); use strict; use warnings; -use centreon::plugins::values; -use centreon::plugins::statefile; use Digest::MD5 qw(md5_hex); -my $instance_mode; +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'global', type => 0, cb_prefix_output => 'prefix_global_output', skipped_code => { -10 => 1 } }, + ]; -my $maps_counters = { - threads => { - '000_active' => { set => { key_values => [ { name => 'active' } ], - output_template => 'Active : %s', - perfdatas => [ - { label => 'active', value => 'active_absolute', template => '%s', min => 0 }, - ], - } - }, - '001_started' => { set => { key_values => [ { name => 'started', diff => 1 } ], - output_template => 'Started : %s', - perfdatas => [ - { label => 'started', value => 'started_absolute', template => '%s', min => 0 }, - ], - } - }, - '003_daemon' => { set => { key_values => [ { name => 'daemon' } ], - output_template => 'Daemon : %s', - perfdatas => [ - { label => 'daemon', value => 'daemon_absolute', template => '%s', min => 0 }, - ], - } - }, + $self->{maps_counters}->{global} = [ + { label => 'active', set => { + key_values => [ { name => 'ThreadCount' } ], + output_template => 'Active : %s', + perfdatas => [ + { label => 'active', value => 'ThreadCount_absolute', template => '%s', min => 0 }, + ], + } }, -}; + { label => 'started', set => { + key_values => [ { name => 'TotalStartedThreadCount', diff => 1 } ], + output_template => 'Started : %s', + perfdatas => [ + { label => 'started', value => 'TotalStartedThreadCount_absolute', template => '%s', min => 0 }, + ], + } + }, + { label => 'daemon', set => { + key_values => [ { name => 'DaemonThreadCount' } ], + output_template => 'Daemon : %s', + perfdatas => [ + { label => 'daemon', value => 'DaemonThreadCount_absolute', template => '%s', min => 0 }, + ], + } + }, + ]; +} + +sub prefix_global_output { + my ($self, %options) = @_; + + return "Threads "; +} sub new { my ($class, %options) = @_; - my $self = $class->SUPER::new(package => __PACKAGE__, %options); + my $self = $class->SUPER::new(package => __PACKAGE__, %options, statefile => 1); bless $self, $class; $self->{version} = '1.0'; $options{options}->add_options(arguments => { }); - $self->{statefile_value} = centreon::plugins::statefile->new(%options); - - foreach my $key (('threads')) { - 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 (('threads')) { - foreach (keys %{$maps_counters->{$key}}) { - $maps_counters->{$key}->{$_}->{obj}->init(option_results => $self->{option_results}); - } - } - - $self->{statefile_value}->check_options(%options); - $instance_mode = $self; - - $self->{overload_th} = {}; - foreach my $val (@{$self->{option_results}->{threshold_overload}}) { - if ($val !~ /^(.*?),(.*?),(.*)$/) { - $self->{output}->add_option_msg(short_msg => "Wrong threshold-overload option '" . $val . "'."); - $self->{output}->option_exit(); - } - my ($section, $status, $filter) = ($1, $2, $3); - 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}; - } -} - -sub run { - my ($self, %options) = @_; - $self->{connector} = $options{custom}; - - $self->manage_selection(); - - $self->{new_datas} = {}; - $self->{statefile_value}->read(statefile => "jvm_standard_" . $self->{mode} . '_' . md5_hex($self->{connector}->{url})); - $self->{new_datas}->{last_timestamp} = time(); - - my ($short_msg, $short_msg_append, $long_msg, $long_msg_append) = ('', '', '', ''); - my @exits; - foreach (sort keys %{$maps_counters->{threads}}) { - my $obj = $maps_counters->{threads}->{$_}->{obj}; - $obj->set(instance => 'global'); - - my ($value_check) = $obj->execute(values => $self->{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 => "Threads $short_msg" - ); - } else { - $self->{output}->output_add(short_msg => "Threads $long_msg"); - } - - $self->{statefile_value}->write(data => $self->{new_datas}); - $self->{output}->display(); - $self->{output}->exit(); -} - sub manage_selection { my ($self, %options) = @_; my $mbean = 'java.lang:type=Threading'; - $self->{request} = [ - { mbean => $mbean, attributes => [ { name => 'TotalStartedThreadCount' }, { name => 'ThreadCount' }, { name => 'DaemonThreadCount' } ] }, + my $request = [ + { mbean => $mbean, attributes => [ { name => 'TotalStartedThreadCount' }, { name => 'ThreadCount' }, { name => 'DaemonThreadCount' } ] }, ]; - my $result = $self->{connector}->get_attributes(request => $self->{request}, nothing_quit => 1); + my $result = $options{custom}->get_attributes(request => $request, nothing_quit => 1); + + $self->{global} = { %{$result->{$mbean}} }; - $self->{global} = {}; - $self->{global}->{started} = $result->{$mbean}->{TotalStartedThreadCount} if (defined($result->{$mbean}->{TotalStartedThreadCount})); - $self->{global}->{active} = $result->{$mbean}->{ThreadCount} if (defined($result->{$mbean}->{ThreadCount})); - $self->{global}->{daemon} = $result->{$mbean}->{DaemonThreadCount} if (defined($result->{$mbean}->{DaemonThreadCount})); + $self->{cache_name} = "jvm_standard_" . $self->{mode} . '_' . md5_hex($options{custom}->get_connection_info()) . '_' . + (defined($self->{option_results}->{filter_counters}) ? md5_hex($self->{option_results}->{filter_counters}) : md5_hex('all')); } 1; @@ -206,4 +117,4 @@ Can be: 'active', 'started', 'daemon'. =back -=cut \ No newline at end of file +=cut diff --git a/centreon-plugins/centreon/common/powershell/hyperv/2012/nodevmstatus.pm b/centreon-plugins/centreon/common/powershell/hyperv/2012/nodevmstatus.pm index 23ac2ced5..4a4a792db 100644 --- a/centreon-plugins/centreon/common/powershell/hyperv/2012/nodevmstatus.pm +++ b/centreon-plugins/centreon/common/powershell/hyperv/2012/nodevmstatus.pm @@ -39,10 +39,21 @@ Try { $ErrorActionPreference = "Stop" $vms = Get-VM + $node_is_clustered = 0 + Try { + If (@(Get-ClusterNode -ea Ignore).Count -ne 0) { + $node_is_clustered = 1 + } + } Catch { + } Foreach ($vm in $vms) { $note = $vm.Notes -replace "\r","" $note = $note -replace "\n"," - " - Write-Host "[name=" $vm.VMName "][state=" $vm.State "][status=" $vm.Status "][IsClustered=" $vm.IsClustered "][note=" $note "]" + $isClustered = $vm.IsClustered + if ($node_is_clustered -eq 0) { + $isClustered = "nodeNotClustered" + } + Write-Host "[name=" $vm.VMName "][state=" $vm.State "][status=" $vm.Status "][IsClustered=" $isClustered "][note=" $note "]" } } Catch { Write-Host $Error[0].Exception @@ -63,4 +74,4 @@ __END__ Method to get hyper-v informations. -=cut \ No newline at end of file +=cut diff --git a/centreon-plugins/centreon/common/powershell/veeam/jobstatus.pm b/centreon-plugins/centreon/common/powershell/veeam/jobstatus.pm new file mode 100644 index 000000000..bec074b0f --- /dev/null +++ b/centreon-plugins/centreon/common/powershell/veeam/jobstatus.pm @@ -0,0 +1,89 @@ +# +# Copyright 2017 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 centreon::common::powershell::veeam::jobstatus; + +use strict; +use warnings; +use centreon::plugins::misc; + +sub get_powershell { + my (%options) = @_; + my $no_ps = (defined($options{no_ps})) ? 1 : 0; + + return '' if ($no_ps == 1); + + my $ps = ' +$culture = new-object "System.Globalization.CultureInfo" "en-us" +[System.Threading.Thread]::CurrentThread.CurrentUICulture = $culture + +If (@(Get-PSSnapin -Registered | Where-Object {$_.Name -Match "VeeamPSSnapin"} ).count -gt 0) { + If (@(Get-PSSnapin | Where-Object {$_.Name -Match "VeeamPSSnapin"} ).count -eq 0) { + Try { + Get-PSSnapin -Registered | Where-Object {$_.Name -Match "VeeamPSSnapin"} | Add-PSSnapin -ErrorAction STOP + } Catch { + Write-Host $Error[0].Exception + exit 1 + } + } +} else { + Write-Host "Snap-In Veeam no present or not registered" + exit 1 +} + +$ProgressPreference = "SilentlyContinue" + +Try { + $ErrorActionPreference = "Stop" + + $jobs = Get-VBRJob + foreach ($job in $jobs) { + Write-Host "[name = " $job.Name "]" -NoNewline + Write-Host "[type = " $job.JobType "]" -NoNewline + Write-Host "[isrunning = " $job.isRunning "]" -NoNewline + $lastsession = $job.findlastsession() + if ($lastsession) { + Write-Host "[result = " $lastsession.Result "]" -NoNewline + Write-Host "[creationTimeUTC = " (get-date -date $lastsession.creationTime.ToUniversalTime() -Uformat ' . "'%s'" . ') "]" -NoNewline + Write-Host "[endTimeUTC = " (get-date -date $lastsession.EndTime.ToUniversalTime() -Uformat ' . "'%s'" . ') "]" + } else { + Write-Host "[result = ][creationTimeUTC = ][endTimeUTC = ]" + } + } +} Catch { + Write-Host $Error[0].Exception + exit 1 +} + +exit 0 +'; + + return centreon::plugins::misc::powershell_encoded($ps); +} + +1; + +__END__ + +=head1 DESCRIPTION + +Method to get veeam job status informations. + +=cut diff --git a/centreon-plugins/centreon/common/powershell/veeam/listjobs.pm b/centreon-plugins/centreon/common/powershell/veeam/listjobs.pm new file mode 100644 index 000000000..678f18f92 --- /dev/null +++ b/centreon-plugins/centreon/common/powershell/veeam/listjobs.pm @@ -0,0 +1,80 @@ +# +# Copyright 2017 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 centreon::common::powershell::veeam::listjobs; + +use strict; +use warnings; +use centreon::plugins::misc; + +sub get_powershell { + my (%options) = @_; + my $no_ps = (defined($options{no_ps})) ? 1 : 0; + + return '' if ($no_ps == 1); + + my $ps = ' +$culture = new-object "System.Globalization.CultureInfo" "en-us" +[System.Threading.Thread]::CurrentThread.CurrentUICulture = $culture + +If (@(Get-PSSnapin -Registered | Where-Object {$_.Name -Match "VeeamPSSnapin"} ).count -gt 0) { + If (@(Get-PSSnapin | Where-Object {$_.Name -Match "VeeamPSSnapin"} ).count -eq 0) { + Try { + Get-PSSnapin -Registered | Where-Object {$_.Name -Match "VeeamPSSnapin"} | Add-PSSnapin -ErrorAction STOP + } Catch { + Write-Host $Error[0].Exception + exit 1 + } + } +} else { + Write-Host "Snap-In Veeam no present or not registered" + exit 1 +} + +$ProgressPreference = "SilentlyContinue" + +Try { + $ErrorActionPreference = "Stop" + + $jobs = Get-VBRJob + foreach ($job in $jobs) { + Write-Host "[name = " $job.Name "]" -NoNewline + Write-Host "[type = " $job.JobType "]" + } +} Catch { + Write-Host $Error[0].Exception + exit 1 +} + +exit 0 +'; + + return centreon::plugins::misc::powershell_encoded($ps); +} + +1; + +__END__ + +=head1 DESCRIPTION + +Method to get veeam jobs. + +=cut diff --git a/centreon-plugins/centreon/common/protocols/jmx/custom/jolokia.pm b/centreon-plugins/centreon/common/protocols/jmx/custom/jolokia.pm index fb1f83915..2d1a96b9d 100644 --- a/centreon-plugins/centreon/common/protocols/jmx/custom/jolokia.pm +++ b/centreon-plugins/centreon/common/protocols/jmx/custom/jolokia.pm @@ -146,6 +146,14 @@ sub check_options { return 1; } +sub get_connection_info { + my ($self, %options) = @_; + + my $connection_info = $self->{url}; + $connection_info .= '_' . $self->{proxy_url} if (defined($self->{proxy_url})); + return $connection_info; +} + sub connect { my ($self, %options) = @_; diff --git a/centreon-plugins/centreon/common/protocols/sql/mode/sqlstring.pm b/centreon-plugins/centreon/common/protocols/sql/mode/sqlstring.pm new file mode 100644 index 000000000..827c99918 --- /dev/null +++ b/centreon-plugins/centreon/common/protocols/sql/mode/sqlstring.pm @@ -0,0 +1,217 @@ +# +# Copyright 2017 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 centreon::common::protocols::sql::mode::sqlstring; + +use base qw(centreon::plugins::templates::counter); +use strict; +use warnings; + +my $instance_mode; + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'rows', type => 1, message_multiple => "SQL Query is OK" }, + ]; + + $self->{maps_counters}->{rows} = [ + { label => 'string', threshold => 0, set => { + key_values => [ { name => 'key_field' }, { name => 'value_field' } ], + closure_custom_calc => $self->can('custom_string_calc'), + closure_custom_output => $self->can('custom_string_output'), + closure_custom_threshold_check => $self->can('custom_string_threshold'), + closure_custom_perfdata => sub { return 0; }, + } + }, + ]; +} + +sub custom_string_calc { + my ($self, %options) = @_; + + $self->{result_values}->{key_field} = $options{new_datas}->{$self->{instance} . '_key_field'}; + $self->{result_values}->{value_field} = $options{new_datas}->{$self->{instance} . '_value_field'}; + + return 0; +} + +sub custom_string_output { + my ($self, %options) = @_; + + my $msg; + my $message; + + if (defined($instance_mode->{option_results}->{printf_format}) && $instance_mode->{option_results}->{printf_format} ne '') { + eval { + local $SIG{__WARN__} = sub { $message = $_[0]; }; + local $SIG{__DIE__} = sub { $message = $_[0]; }; + $msg = sprintf("$instance_mode->{option_results}->{printf_format}", eval $instance_mode->{option_results}->{printf_value}); + }; + } else { + $msg = sprintf("'%s'", $self->{result_values}->{value_field}); + } + + if (defined($message)) { + $self->{output}->output_add(long_msg => 'output value issue: ' . $message); + } + return $msg; +} + +sub custom_string_threshold { + my ($self, %options) = @_; + my $status = 'ok'; + my $message; + + eval { + local $SIG{__WARN__} = sub { $message = $_[0]; }; + local $SIG{__DIE__} = sub { $message = $_[0]; }; + + if (defined($instance_mode->{option_results}->{critical_string}) && $instance_mode->{option_results}->{critical_string} ne '' && + eval "$instance_mode->{option_results}->{critical_string}") { + $status = 'critical'; + } elsif (defined($instance_mode->{option_results}->{warning_string}) && $instance_mode->{option_results}->{warning_string} ne '' && + eval "$instance_mode->{option_results}->{warning_string}") { + $status = 'warning'; + } + }; + + if (defined($message)) { + $self->{output}->output_add(long_msg => 'threshold regex issue: ' . $message); + } + + return $status; +} + +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 => + { + "sql-statement:s" => { name => 'sql_statement' }, + "key-column:s" => { name => 'key_column' }, + "value-column:s" => { name => 'value_column' }, + "warning-string:s" => { name => 'warning_string', default => '' }, + "critical-string:s" => { name => 'critical_string', default => '' }, + "printf-format:s" => { name => 'printf_format' }, + "printf-value:s" => { name => 'printf_value' }, + }); + return $self; +} + +sub check_options { + my ($self, %options) = @_; + #$self->SUPER::init(%options); + $self->SUPER::check_options(%options); + $instance_mode = $self; + + if (!defined($instance_mode->{option_results}->{sql_statement}) || $instance_mode->{option_results}->{sql_statement} eq '') { + $instance_mode->{output}->add_option_msg(short_msg => "Need to specify '--sql-statement' option."); + $instance_mode->{output}->option_exit(); + } + + $instance_mode->change_macros(); +} + +sub change_macros { + my ($self, %options) = @_; + foreach (('warning_string', 'critical_string')) { + if (defined($self->{option_results}->{$_})) { + $self->{option_results}->{$_} =~ s/%\{(.*?)\}/\$self->{result_values}->{$1}/g; + } + } +} + +sub manage_selection { + my ($self, %options) = @_; + $self->{sql} = $options{sql}; + $self->{sql}->connect(); + $self->{sql}->query(query => $self->{option_results}->{sql_statement}); + $self->{rows} = {}; + my $row_count = 0; + + while (my $row = $self->{sql}->fetchrow_hashref()) { + if (!defined($self->{option_results}->{key_column})) { + $self->{rows}->{$self->{option_results}->{value_column} . $row_count} = { key_field => $row->{$self->{option_results}->{value_column}}, + value_field => $row->{$self->{option_results}->{value_column}}}; + $row_count++; + } else { + $self->{rows}->{$self->{option_results}->{key_column} . $row_count} = { key_field => $row->{$self->{option_results}->{key_column}}, + value_field => $row->{$self->{option_results}->{value_column}}}; + $row_count++; + } + } + + if (scalar(keys %{$self->{rows}}) <= 0) { + $self->{output}->add_option_msg(short_msg => "No row returned or --key-column/--value-column do not correctly match selected field"); + $self->{output}->option_exit(); + } + +} + +1; + +__END__ + +=head1 MODE + +Check SQL statement to query string pattern (You cannot have more than to fiels in select) + +=over 8 + +=item B<--sql-statement> + +SQL statement that returns a string. + +=item B<--key-column> + +Key column (must be one of the selected field). NOT mandatory if you select only one field + +=item B<--value-column> + +Value column (must be one of the selected field). MANDATORY + +=item B<--printf-format> + +Specify a custom output message relying on printf formatting + +=item B<--printf-value> + +Specify scalar used to replace in printf +(Can be: $self->{result_values}->{key_field}, $self->{result_values}->{value_field}) + +=item B<--warning-string> + +Set warning condition (if statement syntax) for status evaluation. +(Can be: %{key_field}, %{value_field}) +e.g --warning-string '%{key_field} eq 'Central' && %{value_field} =~ /127.0.0.1/' + +=item B<--critical-string> + +Set critical condition (if statement syntax) for status evaluation. +(Can be: %{key_field} or %{value_field}) + +=back + +=cut diff --git a/centreon-plugins/centreon/plugins/http.pm b/centreon-plugins/centreon/plugins/http.pm index 29a702476..fa6b655c6 100644 --- a/centreon-plugins/centreon/plugins/http.pm +++ b/centreon-plugins/centreon/plugins/http.pm @@ -121,6 +121,29 @@ sub check_options { $options{request}->{$_} =~ s/%\{http_code\}/\$response->code/g; } } + + $self->{ssl_context} = ''; + if (!defined($options{request}->{ssl_opt})) { + $options{request}->{ssl_opt} = []; + } + if (defined($options{request}->{ssl}) && $options{request}->{ssl} ne '') { + push @{$options{request}->{ssl_opt}}, 'SSL_version => ' . $options{request}->{ssl}; + } + if (defined($options{request}->{cert_file}) && !defined($options{request}->{cert_pkcs12})) { + push @{$options{request}->{ssl_opt}}, 'SSL_use_cert => 1'; + push @{$options{request}->{ssl_opt}}, 'SSL_cert_file => "' . $options{request}->{cert_file} . '"'; + push @{$options{request}->{ssl_opt}}, 'SSL_key_file => "' . $options{request}->{key_file} . '"' + if (defined($options{request}->{key_file})); + push @{$options{request}->{ssl_opt}}, 'SSL_ca_file => "' . $options{request}->{cacert_file} . '"' + if (defined($options{request}->{cacert_file})); + } + my $append = ''; + foreach (@{$options{request}->{ssl_opt}}) { + if ($_ ne '') { + $self->{ssl_context} .= $append . $_; + $append = ', '; + } + } } sub get_port { @@ -256,20 +279,8 @@ sub request { $ENV{HTTPS_PKCS12_PASSWORD} = $request_options->{cert_pwd}; } - my $ssl_context; - if (defined($request_options->{ssl}) && $request_options->{ssl} ne '') { - $ssl_context = { SSL_version => $request_options->{ssl} }; - } - if (defined($request_options->{cert_file}) && !defined($request_options->{cert_pkcs12})) { - $ssl_context = {} if (!defined($ssl_context)); - $ssl_context->{SSL_use_cert} = 1; - $ssl_context->{SSL_cert_file} = $request_options->{cert_file}; - $ssl_context->{SSL_key_file} = $request_options->{key_file} if (defined($request_options->{key_file})); - $ssl_context->{SSL_ca_file} = $request_options->{cacert_file} if (defined($request_options->{cacert_file})); - } - - if (defined($ssl_context)) { - my $context = new IO::Socket::SSL::SSL_Context(%{$ssl_context}); + if (defined($self->{ssl_context}) && $self->{ssl_context} ne '') { + my $context = new IO::Socket::SSL::SSL_Context(eval $self->{ssl_context}); IO::Socket::SSL::set_default_context($context); } diff --git a/centreon-plugins/centreon/plugins/script.pm b/centreon-plugins/centreon/plugins/script.pm index 9c70d54fa..75484c42e 100644 --- a/centreon-plugins/centreon/plugins/script.pm +++ b/centreon-plugins/centreon/plugins/script.pm @@ -30,7 +30,7 @@ use Pod::Find qw(pod_where); my %handlers = (DIE => {}); -my $global_version = 20170913; +my $global_version = 20171222; my $alternative_fatpacker = 0; sub new { diff --git a/centreon-plugins/centreon/plugins/snmp.pm b/centreon-plugins/centreon/plugins/snmp.pm index 786481d9d..7e42f2b50 100644 --- a/centreon-plugins/centreon/plugins/snmp.pm +++ b/centreon-plugins/centreon/plugins/snmp.pm @@ -570,10 +570,11 @@ sub set { # Get last value next if ($oid !~ /(.*)\.(\d+)([\.\s]*)$/); - my $value = $options{oids}->{$oid}; + my $value = $options{oids}->{$oid}->{value}; + my $type = $options{oids}->{$oid}->{type}; my ($oid, $instance) = ($1, $2); - push @$vars, [$oid, $instance, $value]; + push @$vars, [$oid, $instance, $value, $type]; } $self->{session}->set($vars); diff --git a/centreon-plugins/centreon/plugins/statefile.pm b/centreon-plugins/centreon/plugins/statefile.pm index 0275fa778..0915ee50a 100644 --- a/centreon-plugins/centreon/plugins/statefile.pm +++ b/centreon-plugins/centreon/plugins/statefile.pm @@ -37,6 +37,9 @@ sub new { $options{options}->add_options(arguments => { "memcached:s" => { name => 'memcached' }, + "redis-server:s" => { name => 'redis_server' }, + 'redis-attribute:s%' => { name => 'redis_attribute' }, + "memexpiration:s" => { name => 'memexpiration', default => 86400 }, "statefile-dir:s" => { name => 'statefile_dir', default => $default_dir }, "statefile-suffix:s" => { name => 'statefile_suffix', default => '' }, "statefile-concat-cwd" => { name => 'statefile_concat_cwd' }, @@ -67,6 +70,24 @@ sub check_options { $self->{memcached} = Memcached::libmemcached->new(); Memcached::libmemcached::memcached_server_add($self->{memcached}, $options{option_results}->{memcached}); } + + # Check redis + if (defined($options{option_results}->{redis_server})) { + $self->{redis_attributes} = ''; + if (defined($options{option_results}->{redis_attribute})) { + foreach (keys %{$options{option_results}->{redis_attribute}}) { + $self->{redis_attributes} .= "$_ => " . $options{option_results}->{redis_attribute}->{$_} . ", "; + } + } + + centreon::plugins::misc::mymodule_load(output => $self->{output}, module => 'Redis', + error_msg => "Cannot load module 'Redis'."); + eval { + $self->{redis_cnx} = Redis->new(server => $options{option_results}->{redis_server}, + eval $self->{redis_attributes}); + }; + } + $self->{statefile_dir} = $options{option_results}->{statefile_dir}; if ($self->{statefile_dir} ne $default_dir && defined($options{option_results}->{statefile_concat_cwd})) { centreon::plugins::misc::mymodule_load(output => $self->{output}, module => 'Cwd', @@ -79,6 +100,7 @@ sub check_options { $self->{storable} = 1; } $self->{statefile_suffix} = $options{option_results}->{statefile_suffix}; + $self->{memexpiration} = $options{option_results}->{memexpiration}; } sub error { @@ -113,6 +135,18 @@ sub read { } } + if (defined($self->{redis_cnx})) { + my $val = $self->{redis_cnx}->get($self->{statefile_dir} . "/" . $self->{statefile}); + if (defined($val)) { + eval($val); + $self->{datas} = $datas; + $datas = {}; + return 1; + } + + return 0; + } + if (! -e $self->{statefile_dir} . "/" . $self->{statefile}) { if (! -w $self->{statefile_dir}) { $self->error(1); @@ -188,11 +222,15 @@ sub write { if ($self->{memcached_ok} == 1) { Memcached::libmemcached::memcached_set($self->{memcached}, $self->{statefile_dir} . "/" . $self->{statefile}, - Data::Dumper->Dump([$options{data}], ["datas"])); + Data::Dumper->Dump([$options{data}], ["datas"]), $self->{memexpiration}); if (defined($self->{memcached}->errstr) && $self->{memcached}->errstr =~ /^SUCCESS$/i) { return ; } } + if (defined($self->{redis_cnx})) { + return if (defined($self->{redis_cnx}->set($self->{statefile_dir} . "/" . $self->{statefile}, Data::Dumper->Dump([$options{data}], ["datas"]), + 'EX', $self->{memexpiration}))); + } open FILE, ">", $self->{statefile_dir} . "/" . $self->{statefile}; if ($self->{storable} == 1) { Storable::store_fd($options{data}, *FILE); @@ -222,6 +260,18 @@ Statefile class Memcached server to use (only one server). +=item B<--redis-server> + +Redis server to use (only one server). + +=item B<--redis-attribute> + +Set Redis Options (--redis-attribute="cnx_timeout=5"). + +=item B<--memexpiration> + +Time to keep data in seconds (Default: 86400). + =item B<--statefile-dir> Directory for statefile (Default: '/var/lib/centreon/centplugins'). diff --git a/centreon-plugins/centreon/plugins/templates/hardware.pm b/centreon-plugins/centreon/plugins/templates/hardware.pm index 3223b5d27..a716f5791 100644 --- a/centreon-plugins/centreon/plugins/templates/hardware.pm +++ b/centreon-plugins/centreon/plugins/templates/hardware.pm @@ -442,4 +442,4 @@ Example: --critical='xxxxx,.*,40' =back -=cut \ No newline at end of file +=cut diff --git a/centreon-plugins/changelog b/centreon-plugins/changelog index 4ef8aaf79..0bf497195 100644 --- a/centreon-plugins/changelog +++ b/centreon-plugins/changelog @@ -1,3 +1,42 @@ +2017-12-22 Quentin Garnier + * Plugin added: Pure Storage SNMP + * Plugin added: Pure Storage Rest API + * Plugin added: Amazon AWS API + * Plugin added: Comet P8000 series SNMP + * Plugin added: Veeam local + * Plugin added: Colubris SNMP + * Plugin added: Alpha ups SNMP + * Plugin added: Infoblox SNMP + * Plugin added: Redis Rest API + * Plugin added: Cisco Call Manager SNMP + +2017-12-08 Quentin Garnier + * Plugin added: Kingdee Rest API + * Plugin added: Redis Cli + * Plugin added: Ubiquiti Edge SNMP + * Plugin added: Arista SNMP + * Plugin added: Haproxy SNMP + * Plugin added: JBoss JMX + * Plugin added: NSClient Query + * Break: Renamed Asterisk AMI + * Break: Renamed Dell n4000 + * Break: Renamed Dell 62000 + +2017-11-23 Quentin Garnier + * Plugin added: Freebox Rest API + * Plugin added: Netgear Mseries SNMP + * Plugin added: Zyxel SNMP + * Add redis support for temporary datas + +2017-10-13 Quentin Garnier + * Plugin added: Kaminario Rest API + * Plugin added: Protocol SSH + * Plugin added: Tivoli Storage Manager + * Plugin added: Toshiba Storemate + * Mode added: [windows] 'pending-reboot' + * Mode added: [storeonce] 'nas-usage' + * Mode added: [tomcat] 'connector-usage' + 2017-09-13 Quentin Garnier * Plugin added: Zookeeper JMX * Plugin added: Solr JMX diff --git a/centreon-plugins/cloud/aws/custom/awscli.pm b/centreon-plugins/cloud/aws/custom/awscli.pm index 92947b8e2..2359f553f 100644 --- a/centreon-plugins/cloud/aws/custom/awscli.pm +++ b/centreon-plugins/cloud/aws/custom/awscli.pm @@ -22,63 +22,57 @@ package cloud::aws::custom::awscli; use strict; use warnings; -use JSON; -use centreon::plugins::misc; +use DateTime; +use JSON::XS; sub new { - my ( $class, %options ) = @_; - my $self = {}; + 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} ) ) { + 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." ); + 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 => { - "region:s" => { name => 'region' }, - "command:s" => { name => 'command', default => 'aws' }, - "command-path:s" => { name => 'command_path' }, - "sudo" => { name => 'sudo' }, - } ); + + if (!defined($options{noptions})) { + $options{options}->add_options(arguments => + { + "aws-secret-key:s" => { name => 'aws_secret_key' }, + "aws-access-key:s" => { name => 'aws_access_key' }, + "timeout:s" => { name => 'timeout', default => 50 }, + "sudo" => { name => 'sudo' }, + "command:s" => { name => 'command', default => 'aws' }, + "command-path:s" => { name => 'command_path' }, + "command-options:s" => { name => 'command_options', default => '' }, + }); } - $options{options}->add_help(package => __PACKAGE__, sections => 'AWSCLI OPTIONS', once => 1); + $options{options}->add_help(package => __PACKAGE__, sections => 'AWS OPTIONS', once => 1); $self->{output} = $options{output}; - $self->{mode} = $options{mode}; + $self->{mode} = $options{mode}; + return $self; } -# Method to manage multiples sub set_options { - my ( $self, %options ) = @_; - - # options{options_result} + my ($self, %options) = @_; $self->{option_results} = $options{option_results}; } -# Method to manage multiples sub set_defaults { - my ( $self, %options ) = @_; + my ($self, %options) = @_; - # 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] ) ) { + 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}; } } @@ -89,59 +83,232 @@ sub set_defaults { sub check_options { my ($self, %options) = @_; + + if (defined($self->{option_results}->{aws_secret_key}) && $self->{option_results}->{aws_secret_key} ne '') { + $ENV{AWS_SECRET_ACCESS_KEY} = $self->{option_results}->{aws_secret_key}; + } + if (defined($self->{option_results}->{aws_access_key}) && $self->{option_results}->{aws_access_key} ne '') { + $ENV{AWS_ACCESS_KEY_ID} = $self->{option_results}->{aws_access_key}; + } + return 0; } -sub execReq { - my ($self, $options) = @_; - my $jsoncontent; - - if (!defined($options->{output})) { - $options->{output} = 'json'; - } - - my $json = JSON->new; - my $json_encoded = $options->{command} . " " . $options->{subcommand}; - if (defined($self->{option_results}->{region})) { - $json_encoded = $json_encoded . " --region '". $self->{option_results}->{region} . "'"; - } - if (defined($options->{json})) { - $json_encoded = $json_encoded . " --cli-input-json '" . $json->encode( $options->{json} ) . "'"; +sub cloudwatch_get_metrics_set_cmd { + my ($self, %options) = @_; + + return if (defined($self->{option_results}->{command_options}) && $self->{option_results}->{command_options} ne ''); + my $cmd_options = + "cloudwatch get-metric-statistics --region $options{region} --namespace $options{namespace} --metric-name '$options{metric_name}' --start-time $options{start_time} --end-time $options{end_time} --period $options{period} --statistics " . join(' ', @{$options{statistics}}) . " --output json --dimensions"; + foreach my $entry (@{$options{dimensions}}) { + $cmd_options .= " 'Name=$entry->{Name},Value=$entry->{Value}'"; } - $self->{option_results}->{timeout} = 30; + return $cmd_options; +} + +sub cloudwatch_get_metrics { + my ($self, %options) = @_; - if ($options->{output} eq 'text') { - $self->{stdout} = centreon::plugins::misc::execute( + my $metric_results = {}; + my $start_time = DateTime->now->subtract(seconds => $options{timeframe})->iso8601; + my $end_time = DateTime->now->iso8601; + + foreach my $metric_name (@{$options{metrics}}) { + my $cmd_options = $self->cloudwatch_get_metrics_set_cmd(%options, metric_name => $metric_name, start_time => $start_time, end_time => $end_time); + my ($response) = centreon::plugins::misc::execute( output => $self->{output}, options => $self->{option_results}, sudo => $self->{option_results}->{sudo}, command => $self->{option_results}->{command}, command_path => $self->{option_results}->{command_path}, - command_options => $json_encoded - ); - my @return = split /\n/, $self->{stdout}; - $jsoncontent = $json->encode( [@return] ); - } else { - $jsoncontent = centreon::plugins::misc::execute( + command_options => $cmd_options); + + my $metric_result; + eval { + $metric_result = JSON::XS->new->utf8->decode($response); + }; + if ($@) { + $self->{output}->add_option_msg(short_msg => "Cannot decode json response: $@"); + $self->{output}->option_exit(); + } + + $metric_results->{$metric_result->{Label}} = { points => 0 }; + foreach my $point (@{$metric_result->{Datapoints}}) { + if (defined($point->{Average})) { + $metric_results->{$metric_result->{Label}}->{average} = 0 if (!defined($metric_results->{$metric_result->{Label}}->{average})); + $metric_results->{$metric_result->{Label}}->{average} += $point->{Average}; + } + if (defined($point->{Minimum})) { + $metric_results->{$metric_result->{Label}}->{minimum} = $point->{Minimum} + if (!defined($metric_results->{$metric_result->{Label}}->{minimum}) || $point->{Minimum} < $metric_results->{$metric_result->{Label}}->{minimum}); + } + if (defined($point->{Maximum})) { + $metric_results->{$metric_result->{Label}}->{maximum} = $point->{Maximum} + if (!defined($metric_results->{$metric_result->{Label}}->{maximum}) || $point->{Maximum} > $metric_results->{$metric_result->{Label}}->{maximum}); + } + if (defined($point->{Sum})) { + $metric_results->{$metric_result->{Label}}->{sum} = 0 if (!defined($metric_results->{$metric_result->{Label}}->{sum})); + $metric_results->{$metric_result->{Label}}->{sum} += $point->{Sum}; + } + + $metric_results->{$metric_result->{Label}}->{points}++; + } + + if (defined($metric_results->{$metric_result->{Label}}->{average})) { + $metric_results->{$metric_result->{Label}}->{average} /= $metric_results->{$metric_result->{Label}}->{points}; + } + } + + return $metric_results; +} + +sub cloudwatch_get_alarms_set_cmd { + my ($self, %options) = @_; + + return if (defined($self->{option_results}->{command_options}) && $self->{option_results}->{command_options} ne ''); + my $cmd_options = "cloudwatch describe-alarms --region $options{region} --output json"; + return $cmd_options; +} + +sub cloudwatch_get_alarms { + my ($self, %options) = @_; + + my $cmd_options = $self->cloudwatch_get_alarms_set_cmd(%options); + my ($response) = centreon::plugins::misc::execute( output => $self->{output}, options => $self->{option_results}, sudo => $self->{option_results}->{sudo}, command => $self->{option_results}->{command}, command_path => $self->{option_results}->{command_path}, - command_options => $json_encoded - ); - } - if ($? > 0) { - $self->{output}->add_option_msg( short_msg => "Cannot run aws" ); - $self->{output}->option_exit(); - } - eval { $self->{command_return} = $json->decode($jsoncontent); }; + command_options => $cmd_options + ); + my $alarm_result; + eval { + $alarm_result = JSON::XS->new->utf8->decode($response); + }; if ($@) { - $self->{output}->add_option_msg( short_msg => "Cannot decode json answer" ); + $self->{output}->add_option_msg(short_msg => "Cannot decode json response: $@"); $self->{output}->option_exit(); } - return $self->{command_return}; + + my $alarm_results = []; + foreach my $alarm (@{$alarm_result->{MetricAlarms}}) { + push @$alarm_results, { + AlarmName => $alarm->{AlarmName}, + StateValue => $alarm->{StateValue}, + MetricName => $alarm->{MetricName}, + StateReason => $alarm->{StateReason}, + StateUpdatedTimestamp => $alarm->{StateUpdatedTimestamp}, + }; + } + return $alarm_results; +} + +sub cloudwatch_list_metrics_set_cmd { + my ($self, %options) = @_; + + return if (defined($self->{option_results}->{command_options}) && $self->{option_results}->{command_options} ne ''); + my $cmd_options = "cloudwatch list-metrics --region $options{region} --output json"; + return $cmd_options; +} + +sub cloudwatch_list_metrics { + my ($self, %options) = @_; + + my $cmd_options = $self->cloudwatch_list_metrics_set_cmd(%options); + my ($response) = centreon::plugins::misc::execute( + output => $self->{output}, + options => $self->{option_results}, + sudo => $self->{option_results}->{sudo}, + command => $self->{option_results}->{command}, + command_path => $self->{option_results}->{command_path}, + command_options => $cmd_options + ); + my $list_metrics; + eval { + $list_metrics = JSON::XS->new->utf8->decode($response); + }; + if ($@) { + $self->{output}->add_option_msg(short_msg => "Cannot decode json response: $@"); + $self->{output}->option_exit(); + } + + return $list_metrics->{Metrics}; +} + +sub ec2_get_instances_status_set_cmd { + my ($self, %options) = @_; + + return if (defined($self->{option_results}->{command_options}) && $self->{option_results}->{command_options} ne ''); + my $cmd_options = "ec2 describe-instance-status --include-all-instances --no-dry-run --region $options{region} --output json"; + return $cmd_options; +} + +sub ec2_get_instances_status { + my ($self, %options) = @_; + + my $cmd_options = $self->ec2_get_instances_status_set_cmd(%options); + my ($response) = centreon::plugins::misc::execute( + output => $self->{output}, + options => $self->{option_results}, + sudo => $self->{option_results}->{sudo}, + command => $self->{option_results}->{command}, + command_path => $self->{option_results}->{command_path}, + command_options => $cmd_options + ); + my $list_instances; + eval { + $list_instances = JSON::XS->new->utf8->decode($response); + }; + if ($@) { + $self->{output}->add_option_msg(short_msg => "Cannot decode json response: $@"); + $self->{output}->option_exit(); + } + + my $instance_results = {}; + foreach (@{$list_instances->{InstanceStatuses}}) { + $instance_results->{$_->{InstanceId}} = { state => $_->{InstanceState}->{Name} }; + } + + return $instance_results; +} + +sub rds_get_instances_status_set_cmd { + my ($self, %options) = @_; + + return if (defined($self->{option_results}->{command_options}) && $self->{option_results}->{command_options} ne ''); + my $cmd_options = "rds describe-db-instances --region $options{region} --output json"; + return $cmd_options; +} + +sub rds_get_instances_status { + my ($self, %options) = @_; + + my $cmd_options = $self->rds_get_instances_status_set_cmd(%options); + my ($response) = centreon::plugins::misc::execute( + output => $self->{output}, + options => $self->{option_results}, + sudo => $self->{option_results}->{sudo}, + command => $self->{option_results}->{command}, + command_path => $self->{option_results}->{command_path}, + command_options => $cmd_options + ); + my $list_instances; + eval { + $list_instances = JSON::XS->new->utf8->decode($response); + }; + if ($@) { + $self->{output}->add_option_msg(short_msg => "Cannot decode json response: $@"); + $self->{output}->option_exit(); + } + + my $instance_results = {}; + foreach (@{$list_instances->{DBInstances}}) { + $instance_results->{$_->{DBInstanceIdentifier}} = { state => $_->{DBInstanceStatus} }; + } + + return $instance_results; } 1; @@ -150,17 +317,27 @@ __END__ =head1 NAME -AWS CLI API +Amazon AWS =head1 SYNOPSIS -AWS cli API custom mode +Amazon AWS + +=head1 AWS OPTIONS =over 8 -=item B<--region> +=item B<--aws-secret-key> -(optional) The region to use (should be configured directly in aws). +Set AWS secret key. + +=item B<--aws-access-key> + +Set AWS access key. + +=item B<--timeout> + +Set timeout (Default: 50). =item B<--sudo> @@ -168,11 +345,16 @@ Use 'sudo' to execute the command. =item B<--command> -(optional) Command to get information (Default: 'aws'). +Command to get information (Default: 'aws'). +Can be changed if you have output in a file. =item B<--command-path> -(optional) Command path (Default: none). +Command path (Default: none). + +=item B<--command-options> + +Command options (Default: none). =back diff --git a/centreon-plugins/cloud/aws/custom/paws.pm b/centreon-plugins/cloud/aws/custom/paws.pm new file mode 100644 index 000000000..f6d00b583 --- /dev/null +++ b/centreon-plugins/cloud/aws/custom/paws.pm @@ -0,0 +1,274 @@ +# +# Copyright 2017 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 cloud::aws::custom::paws; + +use strict; +use warnings; +use Paws; +use DateTime; + +sub new { + my ($class, %options) = @_; + my $self = {}; + bless $self, $class; + + 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 => + { + "aws-secret-key:s" => { name => 'aws_secret_key' }, + "aws-access-key:s" => { name => 'aws_access_key' }, + }); + } + $options{options}->add_help(package => __PACKAGE__, sections => 'AWS OPTIONS', once => 1); + + $self->{output} = $options{output}; + $self->{mode} = $options{mode}; + + return $self; +} + +sub set_options { + my ($self, %options) = @_; + + $self->{option_results} = $options{option_results}; +} + +sub set_defaults { + my ($self, %options) = @_; + + 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) = @_; + + if (defined($self->{option_results}->{aws_secret_key}) && $self->{option_results}->{aws_secret_key} ne '') { + $ENV{AWS_SECRET_KEY} = $self->{option_results}->{aws_secret_key}; + } + if (defined($self->{option_results}->{aws_access_key}) && $self->{option_results}->{aws_access_key} ne '') { + $ENV{AWS_ACCESS_KEY} = $self->{option_results}->{aws_access_key}; + } + + return 0; +} + +sub cloudwatch_get_metrics { + my ($self, %options) = @_; + + my $metric_results = {}; + eval { + my $cw = Paws->service('CloudWatch', region => $options{region}); + my $start_time = DateTime->now->subtract(seconds => $options{timeframe})->iso8601; + my $end_time = DateTime->now->iso8601; + + foreach my $metric_name (@{$options{metrics}}) { + my $metric_result = $cw->GetMetricStatistics( + MetricName => $metric_name, + Namespace => $options{namespace}, + Statistics => $options{statistics}, + #ExtendedStatistics => ['p100'], + EndTime => $end_time, + StartTime => $start_time, + Period => $options{period}, + #Unit => $unit, + Dimensions => $options{dimensions}, + ); + + $metric_results->{$metric_result->{Label}} = { points => 0 }; + foreach my $point (@{$metric_result->{Datapoints}}) { + if (defined($point->{Average})) { + $metric_results->{$metric_result->{Label}}->{average} = 0 if (!defined($metric_results->{$metric_result->{Label}}->{average})); + $metric_results->{$metric_result->{Label}}->{average} += $point->{Average}; + } + if (defined($point->{Minimum})) { + $metric_results->{$metric_result->{Label}}->{minimum} = $point->{Minimum} + if (!defined($metric_results->{$metric_result->{Label}}->{minimum}) || $point->{Minimum} < $metric_results->{$metric_result->{Label}}->{minimum}); + } + if (defined($point->{Maximum})) { + $metric_results->{$metric_result->{Label}}->{maximum} = $point->{Maximum} + if (!defined($metric_results->{$metric_result->{Label}}->{maximum}) || $point->{Maximum} > $metric_results->{$metric_result->{Label}}->{maximum}); + } + if (defined($point->{Sum})) { + $metric_results->{$metric_result->{Label}}->{sum} = 0 if (!defined($metric_results->{$metric_result->{Label}}->{sum})); + $metric_results->{$metric_result->{Label}}->{sum} += $point->{Sum}; + } + + $metric_results->{$metric_result->{Label}}->{points}++; + } + + if (defined($metric_results->{$metric_result->{Label}}->{average})) { + $metric_results->{$metric_result->{Label}}->{average} /= $metric_results->{$metric_result->{Label}}->{points}; + } + } + }; + if ($@) { + $self->{output}->add_option_msg(short_msg => "error: $@"); + $self->{output}->option_exit(); + } + + return $metric_results; +} + +sub cloudwatch_get_alarms { + my ($self, %options) = @_; + + my $alarm_results = []; + eval { + my $cw = Paws->service('CloudWatch', region => $options{region}); + my $alarms = $cw->DescribeAlarms(); + foreach my $alarm (@{$alarms->{MetricAlarms}}) { + push @$alarm_results, { + AlarmName => $alarm->{AlarmName}, + StateValue => $alarm->{StateValue}, + MetricName => $alarm->{MetricName}, + StateReason => $alarm->{StateReason}, + StateUpdatedTimestamp => $alarm->{StateUpdatedTimestamp}, + }; + } + }; + if ($@) { + $self->{output}->add_option_msg(short_msg => "error: $@"); + $self->{output}->option_exit(); + } + return $alarm_results; +} + +sub cloudwatch_list_metrics { + my ($self, %options) = @_; + + my $metric_results = []; + eval { + my $cw = Paws->service('CloudWatch', region => $options{region}); + my %options = (); + $options{Namespace} = $options{namespace} if (defined($options{namespace})); + while ((my $list_metrics = $cw->ListMetrics(%options))) { + foreach (@{$list_metrics->{Metrics}}) { + my $dimensions = []; + foreach my $dimension (@{$_->{Dimensions}}) { + push @$dimensions, { Name => $dimension->{Name}, Value => $dimension->{Value} }; + } + push @{$metric_results}, { + Namespace => $_->{Namespace}, + MetricName => $_->{MetricName}, + Dimensions => $dimensions, + }; + } + + last if (!defined($list_metrics->{NextToken})); + $options{NextToken} = $list_metrics->{NextToken}; + } + }; + if ($@) { + $self->{output}->add_option_msg(short_msg => "error: $@"); + $self->{output}->option_exit(); + } + + return $metric_results; +} + +sub ec2_get_instances_status { + my ($self, %options) = @_; + + my $instance_results = {}; + eval { + my $ec2 = Paws->service('EC2', region => $options{region}); + my $instances = $ec2->DescribeInstanceStatus(DryRun => 0, IncludeAllInstances => 1); + foreach (@{$instances->{InstanceStatuses}}) { + $instance_results->{$_->{InstanceId}} = { state => $_->{InstanceState}->{Name} }; + } + }; + if ($@) { + $self->{output}->add_option_msg(short_msg => "error: $@"); + $self->{output}->option_exit(); + } + + return $instance_results; +} + +sub rds_get_instances_status { + my ($self, %options) = @_; + + my $instance_results = {}; + eval { + my $rds = Paws->service('RDS', region => $options{region}); + my $instances = $rds->DescribeDBInstances(); + foreach (@{$instances->{DBInstances}}) { + $instance_results->{$_->{DBInstanceIdentifier}} = { state => $_->{DBInstanceStatus} }; + } + }; + if ($@) { + $self->{output}->add_option_msg(short_msg => "error: $@"); + $self->{output}->option_exit(); + } + + return $instance_results; +} + +1; + +__END__ + +=head1 NAME + +Amazon AWS + +=head1 SYNOPSIS + +Amazon AWS + +=head1 AWS OPTIONS + +=over 8 + +=item B<--aws-secret-key> + +Set AWS secret key. + +=item B<--aws-access-key> + +Set AWS access key. + +=back + +=head1 DESCRIPTION + +B. + +=cut diff --git a/centreon-plugins/cloud/aws/mode/cloudwatch.pm b/centreon-plugins/cloud/aws/mode/cloudwatch.pm deleted file mode 100644 index 9c8822d82..000000000 --- a/centreon-plugins/cloud/aws/mode/cloudwatch.pm +++ /dev/null @@ -1,296 +0,0 @@ -# -# Copyright 2017 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 cloud::aws::mode::cloudwatch; - -use base qw(centreon::plugins::mode); - -use strict; -use warnings; -use centreon::plugins::misc; -use POSIX; -use JSON; - -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", -}; - -my $StatisticsType = "Average,Minimum,Maximum,Sum,SampleCount"; -my $def_endtime = time(); - -my $apiRequest = { - 'command' => 'cloudwatch', - 'subcommand' => 'get-metric-statistics', -}; - -sub new -{ - my ($class, %options) = @_; - my $self = $class->SUPER::new(package => __PACKAGE__, %options); - bless $self, $class; - - $self->{version} = '0.1'; - - $options{options}->add_options( - arguments => { - "metric:s" => {name => 'metric'}, - "period:s" => {name => 'period', default => 300}, - "starttime:s" => {name => 'starttime'}, - "endtime:s" => {name => 'endtime'}, - "statistics:s" => {name => 'statistics', default => 'Average'}, - "exclude-statistics:s" => {name => 'exclude-statistics'}, - "object:s" => {name => 'object'}, - "warning:s" => {name => 'warning'}, - "critical:s" => {name => 'critical'}, - } - ); - $self->{result} = {}; - - return $self; -} - -sub check_options -{ - my ($self, %options) = @_; - $self->SUPER::init(%options); - - $self->{option_results}->{def_endtime} = $def_endtime; - - 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}->{metric})) - { - $self->{output}->add_option_msg( - severity => 'UNKNOWN', - short_msg => "Please give a metric to watch (cpu, disk, ...)." - ); - $self->{output}->option_exit(); - } - - if (!defined($self->{option_results}->{object})) - { - $self->{output}->add_option_msg( - severity => 'UNKNOWN', - short_msg => "Please give the object to request (instanceid, ...)." - ); - $self->{output}->option_exit(); - } - - if (!defined($self->{option_results}->{endtime})) - { - $self->{option_results}->{endtime} = strftime("%FT%H:%M:%S.000Z", gmtime($self->{option_results}->{def_endtime})); - } - - if (!defined($self->{option_results}->{starttime})) - { - $self->{option_results}->{starttime} = strftime("%FT%H:%M:%S.000Z", gmtime($self->{option_results}->{def_endtime} - 600)); - } - - # Getting some parameters - # statistics - if ($self->{option_results}->{statistics} eq 'all') - { - @{$self->{option_results}->{statisticstab}} = split(/,/, $StatisticsType); - } - else - { - @{$self->{option_results}->{statisticstab}} = split(/,/, $self->{option_results}->{statistics}); - foreach my $curstate (@{$self->{option_results}->{statisticstab}}) - { - if (!grep { /^$curstate$/ } split(/,/, $StatisticsType)) - { - $self->{output}->add_option_msg( - severity => 'UNKNOWN', - short_msg => "The statistic $curstate doesn't exist." - ); - $self->{output}->option_exit(); - } - } - } - - # exclusions - if (defined($self->{option_results}->{'exclude-statistics'})) - { - my @excludetab = split(/,/, $self->{option_results}->{'exclude-statistics'}); - my %array1 = map { $_ => 1 } @excludetab; - @{$self->{option_results}->{statisticstab}} = grep { not $array1{$_} } @{$self->{option_results}->{statisticstab}}; - } - - # Force Average statistic - if (!grep $_ eq 'Average', @{$self->{option_results}->{statisticstab}}) - { - my $statistics = join(',', @{$self->{option_results}->{statisticstab}}); - if (!$statistics eq '') - { - $statistics = $statistics . ',Average'; - } - else - { - $statistics = 'Average'; - } - @{$self->{option_results}->{statisticstab}} = split(/,/, $statistics); - } -} - -sub manage_selection -{ - my ($self, $metric) = @_; - my @result; - - my @Dimensions = ( - { - 'Value' => $self->{option_results}->{object}, - 'Name' => $metric->{ObjectName} - } - ); - - if (defined($metric->{ExtraDimensions})) - { - push @Dimensions, $metric->{ExtraDimensions}; - } - - $apiRequest->{json} = { - 'StartTime' => $self->{option_results}->{starttime}, - 'EndTime' => $self->{option_results}->{endtime}, - 'Period' => $self->{option_results}->{period}, - 'MetricName' => $metric->{MetricName}, - 'Unit' => $metric->{Unit}, - 'Statistics' => $self->{option_results}->{statisticstab}, - 'Dimensions' => [@Dimensions], - 'Namespace' => $metric->{NameSpace} - }; -} - -sub run -{ - my ($self, %options) = @_; - - my ($msg, $exit_code, $awsapi); - - if ( defined( $CloudwatchMetrics->{ $self->{option_results}->{metric} } ) ) { - centreon::plugins::misc::mymodule_load(output => $options{output}, module => $CloudwatchMetrics->{$self->{option_results}->{metric}}, - error_msg => "Cannot load module '" . $CloudwatchMetrics->{$self->{option_results}->{metric}} . "'."); - my $func = $CloudwatchMetrics->{$self->{option_results}->{metric}}->can('cloudwatchCheck'); - $func->($self); - } else { - $self->{output}->add_option_msg( short_msg => "Wrong option. Cannot find metric '" . $self->{option_results}->{metric} . "'." ); - $self->{output}->option_exit(); - } - - foreach my $metric (@{$self->{metric}}) - { - $self->manage_selection($metric); - $awsapi = $options{custom}; - $self->{command_return} = $awsapi->execReq($apiRequest); - $self->{output}->perfdata_add( - label => sprintf($metric->{Labels}->{PerfData}, unit => $metric->{Labels}->{Unit}), - value => sprintf($metric->{Labels}->{Value}, $self->{command_return}->{Datapoints}[0]->{Average}), - warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning'), - critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical'), - - #min => 0, - #max => 100 - ); - $exit_code = $self->{perfdata}->threshold_check( - value => $self->{command_return}->{Datapoints}[0]->{Average}, - threshold => [{label => 'critical', 'exit_litteral' => 'critical'}, {label => 'warning', exit_litteral => 'warning'}] - ); - - $self->{output}->output_add(long_msg => sprintf($metric->{Labels}->{LongOutput}, $self->{command_return}->{Datapoints}[0]->{Average})); - - $self->{output}->output_add( - severity => $exit_code, - short_msg => sprintf($metric->{Labels}->{ShortOutput}, $self->{command_return}->{Datapoints}[0]->{Average}) - ); - } - - $self->{output}->display(); - $self->{output}->exit(); -} - -1; - -__END__ - -=head1 MODE - -Get cloudwatch metrics. -This doc is partly based on the official AWS CLI documentation. - -=over 8 - -=item B<--exclude-statistics> - -(optional) Statistics to exclude from the query. 'Average' can't be excluded. - -=item B<--metric> - -Metric to query. - -=item B<--period> - -(optional) The granularity, in seconds, of the returned datapoints. period must be at least 60 seconds and must be a multiple of 60. The default value is 300. - -=item B<--start-time> - -(optional) The time stamp to use for determining the first datapoint to return. The value specified is inclusive; results include datapoints with the time stamp specified. -exemple: 2014-04-09T23:18:00 - -=item B<--end-time> - -(optional) The time stamp to use for determining the last datapoint to return. The value specified is exclusive; results will include datapoints up to the time stamp specified. -exemple: 2014-04-09T23:18:00 - -=item B<--statistics> - -(optional) The metric statistics to return. For information about specific statistics returned by GetMetricStatistics, go to statistics in the Amazon CloudWatch Developer Guide. -Valid Values: Average | Sum | SampleCount | Maximum | Minimum -Average is the default and always included. -'all' for all statistics values. - -=item B<--object> - -Name of the object to request (InstanceId for an EC2 instance, for exemple). - -=item B<--warning> - -(optional) Threshold warning. - -=item B<--critical> - -(optional) Threshold critical. - -=back - -=cut diff --git a/centreon-plugins/cloud/aws/mode/cloudwatchgetalarms.pm b/centreon-plugins/cloud/aws/mode/cloudwatchgetalarms.pm new file mode 100644 index 000000000..c37a83bfa --- /dev/null +++ b/centreon-plugins/cloud/aws/mode/cloudwatchgetalarms.pm @@ -0,0 +1,223 @@ +# +# Copyright 2017 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 cloud::aws::mode::cloudwatchgetalarms; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; +use centreon::plugins::misc; +use centreon::plugins::statefile; + +my $instance_mode; + +sub custom_status_threshold { + my ($self, %options) = @_; + my $status = 'ok'; + my $message; + + eval { + local $SIG{__WARN__} = sub { $message = $_[0]; }; + local $SIG{__DIE__} = sub { $message = $_[0]; }; + + if (defined($instance_mode->{option_results}->{critical_status}) && $instance_mode->{option_results}->{critical_status} ne '' && + eval "$instance_mode->{option_results}->{critical_status}") { + $status = 'critical'; + } elsif (defined($instance_mode->{option_results}->{warning_status}) && $instance_mode->{option_results}->{warning_status} ne '' && + eval "$instance_mode->{option_results}->{warning_status}") { + $status = 'warning'; + } + }; + if (defined($message)) { + $self->{output}->output_add(long_msg => 'filter status issue: ' . $message); + } + + return $status; +} + +sub custom_status_output { + my ($self, %options) = @_; + + my $msg = sprintf("alarm [name: %s] [state: %s] [metric: %s] [reason: %s] %s", $self->{result_values}->{alarm_name}, + $self->{result_values}->{state_value}, $self->{result_values}->{metric_name}, + $self->{result_values}->{state_reason}, centreon::plugins::misc::change_seconds(value => $self->{result_values}->{last_update})); + return $msg; +} + +sub custom_status_calc { + my ($self, %options) = @_; + + $self->{result_values}->{alarm_name} = $options{new_datas}->{$self->{instance} . '_AlarmName'}; + $self->{result_values}->{state_value} = $options{new_datas}->{$self->{instance} . '_StateValue'}; + $self->{result_values}->{metric_name} = $options{new_datas}->{$self->{instance} . '_MetricName'}; + $self->{result_values}->{last_update} = $options{new_datas}->{$self->{instance} . '_LastUpdate'}; + $self->{result_values}->{state_reason} = $options{new_datas}->{$self->{instance} . '_StateReason'}; + return 0; +} + + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'alarms', type => 2, message_multiple => '0 problem(s) detected', display_counter_problem => { label => 'alerts', min => 0 }, + group => [ { name => 'alarm', skipped_code => { -11 => 1 } } ] + } + ]; + + $self->{maps_counters}->{alarm} = [ + { label => 'status', threshold => 0, set => { + key_values => [ { name => 'AlarmName' }, { name => 'StateValue' }, { name => 'MetricName' }, { name => 'StateReason' }, { name => 'LastUpdate' } ], + closure_custom_calc => $self->can('custom_status_calc'), + closure_custom_output => $self->can('custom_status_output'), + closure_custom_perfdata => sub { return 0; }, + closure_custom_threshold_check => $self->can('custom_status_threshold'), + } + }, + ]; +} + +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 => + { + "region:s" => { name => 'region' }, + "filter-alarm-name:s" => { name => 'filter_alarm_name' }, + "warning-status:s" => { name => 'warning_status', default => '%{state_value} =~ /INSUFFICIENT_DATA/i' }, + "critical-status:s" => { name => 'critical_status', default => '%{state_value} =~ /ALARM/i' }, + "memory" => { name => 'memory' }, + }); + + centreon::plugins::misc::mymodule_load(output => $self->{output}, module => 'Date::Parse', + error_msg => "Cannot load module 'Date::Parse'."); + $self->{statefile_cache} = centreon::plugins::statefile->new(%options); + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::check_options(%options); + + if (!defined($self->{option_results}->{region}) || $self->{option_results}->{region} eq '') { + $self->{output}->add_option_msg(short_msg => "Need to specify --region option."); + $self->{output}->option_exit(); + } + $instance_mode = $self; + $self->change_macros(); + + if (defined($self->{option_results}->{memory})) { + $self->{statefile_cache}->check_options(%options); + } +} + +sub change_macros { + my ($self, %options) = @_; + + foreach (('warning_status', 'critical_status')) { + if (defined($self->{option_results}->{$_})) { + $self->{option_results}->{$_} =~ s/%\{(.*?)\}/\$self->{result_values}->{$1}/g; + } + } +} + +sub manage_selection { + my ($self, %options) = @_; + + $self->{alarms}->{global} = { alarm => {} }; + my $alarm_results = $options{custom}->cloudwatch_get_alarms( + region => $self->{option_results}->{region}, + ); + + my $last_time; + if (defined($self->{option_results}->{memory})) { + $self->{statefile_cache}->read(statefile => 'cache_aws_' . $self->{mode} . '_' . $self->{option_results}->{region}); + $last_time = $self->{statefile_cache}->get(name => 'last_time'); + } + + my ($i, $current_time) = (1, time()); + foreach my $alarm (@{$alarm_results}) { + my $create_time = Date::Parse::str2time($alarm->{StateUpdatedTimestamp}); + if (!defined($create_time)) { + $self->{manager}->{output}->output_add(severity => 'UNKNOWN', + short_msg => "Can't Parse date '" . $alarm->{StateUpdatedTimestamp} . "'"); + next; + } + + next if (defined($self->{option_results}->{memory}) && defined($last_time) && $last_time > $create_time); + if (defined($self->{option_results}->{filter_alarm_name}) && $self->{option_results}->{filter_alarm_name} ne '' && + $alarm->{AlarmName} !~ /$self->{option_results}->{filter_alarm_name}/) { + $self->{output}->output_add(long_msg => "skipping '" . $alarm->{AlarmName} . "': no matching filter.", debug => 1); + next; + } + + my $diff_time = $current_time - $create_time; + + $self->{alarms}->{global}->{alarm}->{$i} = { + %$alarm, + LastUpdate => $diff_time, + }; + $i++; + } + + if (defined($self->{option_results}->{memory})) { + $self->{statefile_cache}->write(data => { last_time => $current_time }); + } +} + +1; + +__END__ + +=head1 MODE + +Check cloudwatch alarms. + +=over 8 + +=item B<--region> + +Set the region name (Required). + +=item B<--filter-alarm-name> + +Filter by alarm name (can be a regexp). + +=item B<--warning-status> + +Set warning threshold for status (Default: '%{state_value} =~ /INSUFFICIENT_DATA/i') +Can used special variables like: %{alarm_name}, %{state_value}, %{metric_name}, %{last_update} + +=item B<--critical-status> + +Set critical threshold for status (Default: '%{state_value} =~ /ALARM/i'). +Can used special variables like: %{alarm_name}, %{state_value}, %{metric_name}, %{last_update} + +=item B<--memory> + +Only check new alarms. + +=back + +=cut diff --git a/centreon-plugins/cloud/aws/mode/cloudwatchgetmetrics.pm b/centreon-plugins/cloud/aws/mode/cloudwatchgetmetrics.pm new file mode 100644 index 000000000..de9908b48 --- /dev/null +++ b/centreon-plugins/cloud/aws/mode/cloudwatchgetmetrics.pm @@ -0,0 +1,246 @@ +# +# Copyright 2017 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 cloud::aws::mode::cloudwatchgetmetrics; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; + +sub custom_metric_perfdata { + my ($self, %options) = @_; + + $self->{output}->perfdata_add(label => $self->{result_values}->{perf_label}, + value => $self->{result_values}->{value}, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-metric'), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-metric'), + ); + +} + +sub custom_metric_threshold { + my ($self, %options) = @_; + + my $exit = $self->{perfdata}->threshold_check(value => $self->{result_values}->{value}, + threshold => [ { label => 'critical-metric', exit_litteral => 'critical' }, + { label => 'warning-metric', exit_litteral => 'warning' } ]); + return $exit; +} + + +sub custom_metric_output { + my ($self, %options) = @_; + + my $msg = "Metric '" . $self->{result_values}->{display} . "' value is " . $self->{result_values}->{value}; + return $msg; +} + +sub custom_metric_calc { + my ($self, %options) = @_; + + $self->{result_values}->{value} = $options{new_datas}->{$self->{instance} . '_value'}; + $self->{result_values}->{perf_label} = $options{new_datas}->{$self->{instance} . '_perf_label'}; + $self->{result_values}->{display} = $options{new_datas}->{$self->{instance} . '_display'}; + return 0; +} + + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'metrics', type => 1, message_multiple => 'All metrics are ok' }, + ]; + + $self->{maps_counters}->{metrics} = [ + { label => 'metric', set => { + key_values => [ { name => 'value' }, { name => 'perf_label' }, { name => 'display' } ], + closure_custom_calc => $self->can('custom_metric_calc'), + closure_custom_output => $self->can('custom_metric_output'), + closure_custom_perfdata => $self->can('custom_metric_perfdata'), + closure_custom_threshold_check => $self->can('custom_metric_threshold'), + } + } + ]; +} + +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 => + { + "region:s" => { name => 'region' }, + "namespace:s" => { name => 'namespace' }, + "dimension:s%" => { name => 'dimension' }, + "metric:s@" => { name => 'metric' }, + "statistic:s@" => { name => 'statistic' }, + "timeframe:s" => { name => 'timeframe', default => 600 }, + "period:s" => { name => 'period', default => 60 }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::check_options(%options); + + if (!defined($self->{option_results}->{region}) || $self->{option_results}->{region} eq '') { + $self->{output}->add_option_msg(short_msg => "Need to specify --region option."); + $self->{output}->option_exit(); + } + if (!defined($self->{option_results}->{namespace}) || $self->{option_results}->{namespace} eq '') { + $self->{output}->add_option_msg(short_msg => "Need to specify --namespace option."); + $self->{output}->option_exit(); + } + + $self->{aws_metrics} = []; + if (defined($self->{option_results}->{metric})) { + $self->{aws_metrics} = [@{$self->{option_results}->{metric}}]; + } + if (scalar(@{$self->{aws_metrics}}) <= 0) { + $self->{output}->add_option_msg(short_msg => "Need to specify --metric option."); + $self->{output}->option_exit(); + } + + $self->{dimension_name} = ''; + my $append = ''; + $self->{aws_dimensions} = []; + if (defined($self->{option_results}->{dimension})) { + foreach (keys %{$self->{option_results}->{dimension}}) { + push @{$self->{aws_dimensions}}, { Name => $_, Value => $self->{option_results}->{dimension}->{$_} }; + $self->{dimension_name} .= $append . $_ . '.' . $self->{option_results}->{dimension}->{$_}; + $append = '-'; + } + } + if ($self->{dimension_name} eq '') { + $self->{output}->add_option_msg(short_msg => "Need to specify --dimension option."); + $self->{output}->option_exit(); + } + + $self->{aws_statistics} = ['Average']; + if (defined($self->{option_results}->{statistic})) { + $self->{aws_statistics} = []; + foreach my $stat (@{$self->{option_results}->{statistic}}) { + if ($stat ne '') { + push @{$self->{aws_statistics}}, ucfirst(lc($stat)); + } + } + } + + foreach my $metric_name ($self->{aws_metrics}) { + foreach my $statistic ($self->{aws_statistics}) { + my $entry = { label => lc($metric_name) . '-' . $statistic, set => { + key_values => [ { name => $metric_name . '_' . $statistic }, { name => 'display' } ], + output_template => $metric_name . ' ' . ucfirst($statistic) . ' : %s', + perfdatas => [ + { label => lc($metric_name) . '_' . $statistic, value => $metric_name . '_' . $statistic . '_absolute', template => '%s', + label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }; + push @{$self->{maps_counters}->{dimensions}}, $entry; + } + } +} + +sub manage_selection { + my ($self, %options) = @_; + + my $metric_results = $options{custom}->cloudwatch_get_metrics( + region => $self->{option_results}->{region}, + namespace => $self->{option_results}->{namespace}, + dimensions => $self->{aws_dimensions}, + metrics => $self->{aws_metrics}, + statistics => $self->{aws_statistics}, + timeframe => $self->{option_results}->{timeframe}, + period => $self->{option_results}->{period}, + ); + + $self->{metrics} = {}; + foreach my $label (keys %{$metric_results}) { + foreach my $stat (('minimum', 'maximum', 'average', 'sum')) { + next if (!defined($metric_results->{$label}->{$stat})); + + $self->{metrics}->{$self->{dimension_name} . '_' . $label . '_' . $stat} = { + display => $self->{dimension_name} . '_' . $label . '_' . $stat, + value => $metric_results->{$label}->{$stat}, + perf_label => $label . '_' . $stat, + }; + } + } +} + +1; + +__END__ + +=head1 MODE + +Check cloudwatch metrics (same dimension and namespace). + +Example: +perl centreon_plugins.pl --plugin=cloud::aws::plugin --custommode=paws --mode=cloudwatch-get-metrics --region=eu-west-1 --namespace=AWS/EC2 --dimension=InstanceId=i-01622936185e32a45 --metric=CPUUtilization --metric=CPUCreditUsage --statistic=average --statistic=max –-period=60 --timeframe=600 --warning-metric= --critical-metric= + +=over 8 + +=item B<--region> + +Set the region name (Required). + +=item B<--namespace> + +Set cloudwatch namespace (Required). + +=item B<--dimension> + +Set cloudwatch dimensions (Required). + +=item B<--metric> + +Set cloudwatch metrics (Required). + +=item B<--statistic> + +Set cloudwatch statistics (Default: 'average'). + +=item B<--period> + +Set period in seconds (Default: 60). + +=item B<--timeframe> + +Set timeframe in seconds (Default: 600). + +=item B<--warning-metric> + +Threshold warning. + +=item B<--critical-metric> + +Threshold critical. + +=back + +=cut diff --git a/centreon-plugins/cloud/aws/mode/cloudwatchlistmetrics.pm b/centreon-plugins/cloud/aws/mode/cloudwatchlistmetrics.pm new file mode 100644 index 000000000..b76d37802 --- /dev/null +++ b/centreon-plugins/cloud/aws/mode/cloudwatchlistmetrics.pm @@ -0,0 +1,127 @@ +# +# Copyright 2017 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 cloud::aws::mode::cloudwatchlistmetrics; + +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 => + { + "region:s" => { name => 'region' }, + "namespace:s" => { name => 'namespace' }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::init(%options); + + if (!defined($self->{option_results}->{region}) || $self->{option_results}->{region} eq '') { + $self->{output}->add_option_msg(short_msg => "Need to specify --region option."); + $self->{output}->option_exit(); + } +} + +sub manage_selection { + my ($self, %options) = @_; + + $self->{metrics} = $options{custom}->cloudwatch_list_metrics(region => $self->{option_results}->{region}, namespace => $self->{option_results}->{namespace}); +} + +sub get_dimensions_str { + my ($self, %options) = @_; + + my $dimensions = ''; + my $append = ''; + foreach (@{$options{dimensions}}) { + $dimensions .= $append . "Name=$_->{Name},Value=$_->{Value}"; + $append = ','; + } + + return $dimensions; +} + +sub run { + my ($self, %options) = @_; + + $self->manage_selection(%options); + foreach (@{$self->{metrics}}) { + $self->{output}->output_add(long_msg => sprintf("[Namespace = %s][Dimensions = %s][Metric = %s]", + $_->{Namespace}, $self->get_dimensions_str(dimensions => $_->{Dimensions}), $_->{MetricName})); + } + + $self->{output}->output_add(severity => 'OK', + short_msg => 'List metrics:'); + $self->{output}->display(nolabel => 1, force_ignore_perfdata => 1, force_long_output => 1); + $self->{output}->exit(); +} + +sub disco_format { + my ($self, %options) = @_; + + $self->{output}->add_disco_format(elements => ['namespace', 'metric', 'dimensions']); +} + +sub disco_show { + my ($self, %options) = @_; + + $self->manage_selection(%options); + foreach (@{$self->{metrics}}) { + $self->{output}->add_disco_entry( + namespace => $_->{Namespace}, + metric => $_->{MetricName}, + dimensions => $self->get_dimensions_str(dimensions => $_->{Dimensions}), + ); + } +} + +1; + +__END__ + +=head1 MODE + +List cloudwatch metrics. + +=over 8 + +=item B<--region> + +Set the region name (Required). + +=item B<--namespace> + +Set cloudwatch namespace. + +=back + +=cut + diff --git a/centreon-plugins/cloud/aws/mode/ec2instancestatus.pm b/centreon-plugins/cloud/aws/mode/ec2instancestatus.pm new file mode 100644 index 000000000..d85679aca --- /dev/null +++ b/centreon-plugins/cloud/aws/mode/ec2instancestatus.pm @@ -0,0 +1,266 @@ +# +# Copyright 2017 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 cloud::aws::mode::ec2instancestatus; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; + +my $instance_mode; + +sub custom_status_threshold { + my ($self, %options) = @_; + my $status = 'ok'; + my $message; + + eval { + local $SIG{__WARN__} = sub { $message = $_[0]; }; + local $SIG{__DIE__} = sub { $message = $_[0]; }; + + my $label = $self->{label}; + $label =~ s/-/_/g; + if (defined($instance_mode->{option_results}->{'critical_' . $label}) && $instance_mode->{option_results}->{'critical_' . $label} ne '' && + eval "$instance_mode->{option_results}->{'critical_' . $label}") { + $status = 'critical'; + } elsif (defined($instance_mode->{option_results}->{'warning_' . $label}) && $instance_mode->{option_results}->{'warning_' . $label} ne '' && + eval "$instance_mode->{option_results}->{'warning_' . $label}") { + $status = 'warning'; + } + }; + if (defined($message)) { + $self->{output}->output_add(long_msg => 'filter status issue: ' . $message); + } + + return $status; +} + +sub custom_status_output { + my ($self, %options) = @_; + + my $msg = sprintf('state : %s', + $self->{result_values}->{health}, $self->{result_values}->{replication_health}); + return $msg; +} + +sub custom_status_calc { + my ($self, %options) = @_; + + $self->{result_values}->{state} = $options{new_datas}->{$self->{instance} . '_state'}; + $self->{result_values}->{display} = $options{new_datas}->{$self->{instance} . '_display'}; + return 0; +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'global', type => 0, cb_prefix_output => 'prefix_global_output' }, + { name => 'aws_instances', type => 1, cb_prefix_output => 'prefix_awsinstance_output', message_multiple => 'All instances are ok' }, + ]; + + $self->{maps_counters}->{global} = [ + { label => 'total-pending', set => { + key_values => [ { name => 'pending' } ], + output_template => "pending : %s", + perfdatas => [ + { label => 'total_pending', value => 'pending_absolute', template => '%d', min => 0 }, + ], + } + }, + { label => 'total-running', set => { + key_values => [ { name => 'running' } ], + output_template => "running : %s", + perfdatas => [ + { label => 'total_running', value => 'running_absolute', template => '%d', min => 0 }, + ], + } + }, + { label => 'total-shutting-down', set => { + key_values => [ { name => 'shutting-down' } ], + output_template => "shutting-down : %s", + perfdatas => [ + { label => 'total_shutting_down', value => 'shutting-down_absolute', template => '%d', min => 0 }, + ], + } + }, + { label => 'total-terminated', set => { + key_values => [ { name => 'terminated' } ], + output_template => "terminated : %s", + perfdatas => [ + { label => 'total_terminated', value => 'terminated_absolute', template => '%d', min => 0 }, + ], + } + }, + { label => 'total-stopping', set => { + key_values => [ { name => 'stopping' } ], + output_template => "stopping : %s", + perfdatas => [ + { label => 'total_stopping', value => 'stopping_absolute', template => '%d', min => 0 }, + ], + } + }, + { label => 'total-stopped', set => { + key_values => [ { name => 'stopped' } ], + output_template => "stopped : %s", + perfdatas => [ + { label => 'total_stopped', value => 'stopped_absolute', template => '%d', min => 0 }, + ], + } + }, + ]; + + $self->{maps_counters}->{aws_instances} = [ + { label => 'status', threshold => 0, set => { + key_values => [ { name => 'state' }, { name => 'display' } ], + closure_custom_calc => $self->can('custom_nas_status_calc'), + closure_custom_output => $self->can('custom_nas_status_output'), + closure_custom_perfdata => sub { return 0; }, + closure_custom_threshold_check => $self->can('custom_status_threshold'), + } + }, + ]; +} + +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 => + { + "region:s" => { name => 'region' }, + "filter-instanceid:s" => { name => 'filter_instanceid' }, + "warning-status:s" => { name => 'warning_status', default => '' }, + "critical-status:s" => { name => 'critical_status', default => '' }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::check_options(%options); + + if (!defined($self->{option_results}->{region}) || $self->{option_results}->{region} eq '') { + $self->{output}->add_option_msg(short_msg => "Need to specify --region option."); + $self->{output}->option_exit(); + } + + $instance_mode = $self; + $self->change_macros(); +} + +sub prefix_global_output { + my ($self, %options) = @_; + + return "Total instances "; +} + +sub prefix_awsinstance_output { + my ($self, %options) = @_; + + return "Instance '" . $options{instance_value}->{display} . "' "; +} + +sub change_macros { + my ($self, %options) = @_; + + foreach (('warning_status', 'critical_status')) { + if (defined($self->{option_results}->{$_})) { + $self->{option_results}->{$_} =~ s/%\{(.*?)\}/\$self->{result_values}->{$1}/g; + } + } +} + +sub manage_selection { + my ($self, %options) = @_; + + $self->{global} = { + pending => 0, running => 0, 'shutting-down' => 0, terminated => 0, stopping => 0, stopped => 0, + }; + $self->{aws_instances} = {}; + my $result = $options{custom}->ec2_get_instances_status(region => $self->{option_results}->{region}); + foreach my $instance_id (keys %{$result}) { + if (defined($self->{option_results}->{filter_instanceid}) && $self->{option_results}->{filter_instanceid} ne '' && + $instance_id !~ /$self->{option_results}->{filter_instanceid}/) { + $self->{output}->output_add(long_msg => "skipping '" . $instance_id . "': no matching filter.", debug => 1); + next; + } + + $self->{aws_instances}->{$instance_id} = { + display => $instance_id, + state => $result->{$instance_id}->{state}, + }; + $self->{global}->{$result->{$instance_id}->{state}}++; + } + + if (scalar(keys %{$self->{aws_instances}}) <= 0) { + $self->{output}->add_option_msg(short_msg => "No aws instance found."); + $self->{output}->option_exit(); + } +} + +1; + +__END__ + +=head1 MODE + +Check EC2 instances status. + +=over 8 + +=item B<--filter-counters> + +Only display some counters (regexp can be used). +Example: --filter-counters='^total-running$' + +=item B<--filter-instanceid> + +Filter by instance id (can be a regexp). + +=item B<--warning-status> + +Set warning threshold for status (Default: ''). +Can used special variables like: %{state}, %{display} + +=item B<--critical-status> + +Set critical threshold for status (Default: ''). +Can used special variables like: %{state}, %{display} + +=item B<--warning-*> + +Threshold warning. +Can be: 'total-pending', 'total-running', 'total-shutting-down', +'total-terminated', 'total-stopping', 'total-stopped'. + +=item B<--critical-*> + +Threshold critical. +Can be: 'total-pending', 'total-running', 'total-shutting-down', +'total-terminated', 'total-stopping', 'total-stopped'. + +=back + +=cut diff --git a/centreon-plugins/cloud/aws/mode/instancestate.pm b/centreon-plugins/cloud/aws/mode/instancestate.pm deleted file mode 100644 index 7e4798f60..000000000 --- a/centreon-plugins/cloud/aws/mode/instancestate.pm +++ /dev/null @@ -1,207 +0,0 @@ -# -# Copyright 2017 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 cloud::aws::mode::instancestate; - -use base qw(centreon::plugins::mode); - -use strict; -use warnings; -use centreon::plugins::misc; -use Data::Dumper; -use JSON; - -my %EC2_instance_states = ( - 'pending' => 'WARNING', - 'running' => 'OK', - 'shutting-down' => 'CRITICAL', - 'terminated' => 'CRITICAL', - 'stopping' => 'CRITICAL', - 'stopped' => 'CRITICAL' -); - -my $apiRequest = { - 'command' => 'ec2', - 'subcommand' => 'describe-instance-status', -}; - -sub new { - my ( $class, %options ) = @_; - my $self = $class->SUPER::new( package => __PACKAGE__, %options ); - bless $self, $class; - - $self->{version} = '0.1'; - - $options{options}->add_options( - arguments => { - "state:s" => { name => 'state', default => 'all' }, - "no-includeallinstances" => { name => 'includeallinstances' }, - "exclude:s" => { name => 'exclude' }, - "instanceid:s" => { name => 'instanceid' } - } - ); - $self->{result} = {}; - return $self; -} - -sub check_options { - my ($self, %options) = @_; - $self->SUPER::init(%options); -} - -sub manage_selection { - my ($self, %options) = @_; - - my (@result, $awsapi); - - # Getting some parameters - # includeallinstances - 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."); - $self->{output}->option_exit(); - } - } - } - - # exclusions - 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}}; - } - my $states = join(',',@{$self->{option_results}->{statetab}}); - - # Getting data from AWS - # Building JSON - $apiRequest->{json} = { - 'DryRun' => JSON::false, - 'IncludeAllInstances' => $self->{option_results}->{includeallinstances}, - 'Filters' => [ - { - 'Name' => 'instance-state-name', - 'Values' => $self->{option_results}->{statetab}, - }], - }; - # InstanceIds - if (defined($self->{option_results}->{instanceid})) { - my @InstanceIds = split(/,/, $self->{option_results}->{instanceid}); - @{$apiRequest->{json}{InstanceIds}} = @InstanceIds; - } - - # Requesting API - $awsapi = $options{custom}; - $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; - } - 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} . ']'); - - foreach my $curstate (@{$self->{option_results}->{statetab}}) { - if ($l->{InstanceState}->{Name} eq $curstate) { - $self->{option_results}->{instancecount}->{$curstate}++; - } - } - $self->{option_results}->{instancecount}->{total}++; - } -} - -sub run { - my ( $self, %options ) = @_; - - my ( $msg, $exit_code ); - my $old_status = 'OK'; - - $self->manage_selection(%options); - - # Send formated data to Centreon - # Perf data - $self->{output}->perfdata_add( - label => 'total', - value => $self->{option_results}->{instancecount}->{'total'}, - ); - - 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) { - $exit_code = $EC2_instance_states{$curstate}; - $exit_code = $self->{output}->get_most_critical(status => [ $exit_code, $old_status ]); - $old_status = $exit_code; - } - } - - # Output message - $self->{output}->output_add( - severity => $exit_code, - short_msg => sprintf("Total instances: %s", $self->{option_results}->{instancecount}->{total}) - ); - - $self->{output}->display(); - $self->{output}->exit(); -} - -1; - -__END__ - -=head1 MODE - -Get the state of your EC2 instances (running, stopped, ...) - -=over 8 - -=item B<--state> - -(optional) Specific state to query. - -=item B<--no-includeallinstances> - -(optional) Includes the health status for running instances only. - -=item B<--exclude> - -(optional) State to exclude from the query. - -=back - -=cut diff --git a/centreon-plugins/cloud/aws/mode/list.pm b/centreon-plugins/cloud/aws/mode/list.pm deleted file mode 100644 index e21c4329d..000000000 --- a/centreon-plugins/cloud/aws/mode/list.pm +++ /dev/null @@ -1,256 +0,0 @@ -# -# Copyright 2017 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 cloud::aws::mode::list; - -use base qw(centreon::plugins::mode); -use strict; -use warnings; -use centreon::plugins::misc; -use JSON; - -my $AWSServices = 'EC2,S3,RDS'; -my @Disco_service_tab = ('EC2', 'RDS'); -my $EC2_instance_states = 'running,stopped'; -my $awsapi; - -sub new -{ - my ($class, %options) = @_; - my $self = $class->SUPER::new(package => __PACKAGE__, %options); - bless $self, $class; - $self->{version} = '0.1'; - $options{options}->add_options( - arguments => { - "service:s" => {name => 'service', default => $AWSServices}, - "exclude-service:s" => {name => 'exclude_service'}, - "ec2-state:s"=>{name=> 'ec2_state', default => $EC2_instance_states}, - "ec2-exclude-state:s" => {name => 'ec2_exclude_state'}, - } - ); - $self->{result} = {}; - return $self; -} - -sub check_options { - my ($self, %options) = @_; - $self->SUPER::init(%options); -} - -sub api_request { - my ($self, %options) = @_; - - @{$self->{option_results}->{servicetab}} = split( /,/, $self->{option_results}->{service} ); - # exclusions - if (defined($self->{option_results}->{exclude_service})) { - my @excludetab = split /,/, $self->{option_results}->{exclude_service}; - my %array1 = map { $_ => 1 } @excludetab; - @{$self->{option_results}->{servicetab}} = grep { not $array1{$_} } @{$self->{option_results}->{servicetab}}; - } - - foreach my $service (@{$self->{option_results}->{servicetab}}) { - $self->{result}->{count}->{$service} = 0; - if ($service eq 'EC2') { - $self->EC2(%options); - } elsif ($service eq 'S3') { - $self->S3(%options); - } elsif ($service eq 'RDS') { - $self->RDS(%options); - } else { - $self->{output}->add_option_msg(short_msg => "Service $service doesn't exists" ); - $self->{output}->option_exit(); - } - } -} - -sub EC2 -{ - my ($self, %options) = @_; - my $apiRequest = { - 'command' => 'ec2', - 'subcommand' => 'describe-instances', - }; - - # Building JSON - my @ec2_statestab = split(/,/, $self->{option_results}->{ec2_state}); - # exclusions - if (defined($self->{option_results}->{ec2_exclude_state})) { - my @excludetab = split /,/, $self->{option_results}->{ec2_exclude_state}; - my %array1 = map { $_ => 1 } @excludetab; - @ec2_statestab = grep { not $array1{$_} } @ec2_statestab; - } - $apiRequest->{json} = { - 'DryRun' => JSON::false, - 'Filters' => [ - { - 'Name' => 'instance-state-name', - 'Values' => [@ec2_statestab], - } - ], - }; - - # Requesting API - $awsapi = $options{custom}; - $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') { - $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}->{count}->{'EC2'}++; - } -} - -sub S3 -{ - my ($self, %options) = @_; - my (@buckets, @return) = (); - my $apiRequest = { - 'command' => 's3', - 'subcommand' => 'ls', - 'output' => 'text' - }; - - # Requesting API - $awsapi = $options{custom}; - $self->{command_return} = $awsapi->execReq($apiRequest); - - # Exec command - foreach my $line (@{$self->{command_return}}) { - my ($date, $time, $name) = split / /, $line; - my $creationdate = $date . " " . $time; - push(@buckets, { Name => $name, CreationDate => $creationdate }); - } - - # Compute data - foreach my $bucket (@buckets) { - $self->{result}->{'S3'}->{$bucket->{Name}} = - {'Creation date' => $bucket->{CreationDate}}; - $self->{result}->{count}->{'S3'}++; - } -} - -sub RDS -{ - my ($self, %options) = @_; - my $apiRequest = { - 'command' => 'rds', - 'subcommand' => 'describe-db-instances', - }; - - # Requesting API - $awsapi = $options{custom}; - $self->{command_return} = $awsapi->execReq($apiRequest); - - # Compute data - foreach my $dbinstance (@{$self->{command_return}->{DBInstances}}) { - $self->{result}->{'RDS'}->{$dbinstance->{DBInstanceIdentifier}} = { - State => $dbinstance->{DBInstanceStatus}, - Name => $dbinstance->{DBInstanceIdentifier} - }; - $self->{result}->{count}->{RDS}++; - } -} - -sub disco_format { - my ($self, %options) = @_; - - 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}}) { - $self->{output}->add_disco_entry( - name => $self->{result}->{$service}->{$device}->{Name}, - id => $device, - state => $self->{result}->{$service}->{$device}->{State}, - service => $service, - ); - } - } -} - -sub run -{ - my ($self, %options) = @_; - $self->api_request(%options); - - # Send formated data to Centreon - 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}}) { - my $output = $device . " ["; - foreach my $value (sort(keys %{$self->{result}->{$service}->{$device}})) { - $output = $output . $value . " = " . $self->{result}->{$service}->{$device}->{$value} . ", "; - } - $output =~ s/, $//; - $output = $output . "]"; - $self->{output}->output_add(long_msg => $output); - } - $self->{output}->output_add(short_msg => sprintf("%s: %s", $service, $self->{result}->{count}->{$service})); - } - $self->{output}->display( - nolabel => 1, - force_ignore_perfdata => 1, - force_long_output => 1 - ); - $self->{output}->exit(); -} -1; -__END__ - -=head1 MODE - -List your EC2, RDS instance and S3 buckets - -=over 8 - -=item B<--service> - -(optional) List one particular service. - -=item B<--exclude-service> - -(optional) Service to exclude from the scan. - -=item B<--ec2-state> - -(optional) State to request (default: 'running','stopped') - -=item B<--ec2-exclude-state> - -(optional) State to exclude from the scan. - -=back - -=cut diff --git a/centreon-plugins/cloud/aws/mode/metrics/ec2instancecpucreditbalance.pm b/centreon-plugins/cloud/aws/mode/metrics/ec2instancecpucreditbalance.pm deleted file mode 100644 index 2eccc18d2..000000000 --- a/centreon-plugins/cloud/aws/mode/metrics/ec2instancecpucreditbalance.pm +++ /dev/null @@ -1,51 +0,0 @@ -# -# Copyright 2017 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 cloud::aws::mode::metrics::ec2instancecpucreditbalance; - -use strict; -use warnings; -use Exporter; -our @ISA = qw(Exporter); -our @EXPORT = qw(&cloudwatchCheck); - -my @Param; - -$Param[0] = { - 'NameSpace' => 'AWS/EC2', - 'MetricName' => 'CPUCreditBalance', - 'ObjectName' => 'InstanceId', - 'Unit' => 'Count', - 'Labels' => { - 'ShortOutput' => "CPUCreditBalance is %.2f%%", - 'LongOutput' => "CPUCreditBalance is %.2f%%", - 'PerfData' => 'CPUCreditBalance', - 'Unit' => 'Count', - 'Value' => "%.2f", - } -}; - -sub cloudwatchCheck { - my ($self) = @_; - - @{ $self->{metric} } = @Param; -} - -1; diff --git a/centreon-plugins/cloud/aws/mode/metrics/ec2instancecpucreditusage.pm b/centreon-plugins/cloud/aws/mode/metrics/ec2instancecpucreditusage.pm deleted file mode 100644 index a98f9e083..000000000 --- a/centreon-plugins/cloud/aws/mode/metrics/ec2instancecpucreditusage.pm +++ /dev/null @@ -1,51 +0,0 @@ -# -# Copyright 2017 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 cloud::aws::mode::metrics::ec2instancecpucreditusage; - -use strict; -use warnings; -use Exporter; -our @ISA = qw(Exporter); -our @EXPORT = qw(&cloudwatchCheck); - -my @Param; - -$Param[0] = { - 'NameSpace' => 'AWS/EC2', - 'MetricName' => 'CPUCreditUsage', - 'ObjectName' => 'InstanceId', - 'Unit' => 'Count', - 'Labels' => { - 'ShortOutput' => "CPUCreditUsage is %.2f%%", - 'LongOutput' => "CPUCreditUsage is %.2f%%", - 'PerfData' => 'CPUCreditUsage', - 'Unit' => 'Count', - 'Value' => "%.2f", - } -}; - -sub cloudwatchCheck { - my ($self) = @_; - - @{ $self->{metric} } = @Param; -} - -1; diff --git a/centreon-plugins/cloud/aws/mode/metrics/ec2instancenetwork.pm b/centreon-plugins/cloud/aws/mode/metrics/ec2instancenetwork.pm deleted file mode 100644 index 394edacc2..000000000 --- a/centreon-plugins/cloud/aws/mode/metrics/ec2instancenetwork.pm +++ /dev/null @@ -1,66 +0,0 @@ -# -# Copyright 2017 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 cloud::aws::mode::metrics::ec2instancenetwork; - -use strict; -use warnings; -use Data::Dumper; -use Exporter; -our @ISA = qw(Exporter); -our @EXPORT = qw(&cloudwatchCheck); - -my @Param; - -$Param[0] = { - 'NameSpace' => 'AWS/EC2', - 'MetricName' => 'NetworkIn', - 'ObjectName' => 'InstanceId', - 'Unit' => 'Bytes', - 'Labels' => { - 'ShortOutput' => "Traffic In %s Bytes", - 'LongOutput' => "Traffic In %s Bytes", - 'PerfData' => 'traffic_in', - 'Unit' => 'B', - 'Value' => "%.2f", - } -}; - -$Param[1] = { - 'NameSpace' => 'AWS/EC2', - 'MetricName' => 'NetworkOut', - 'ObjectName' => 'InstanceId', - 'Unit' => 'Bytes', - 'Labels' => { - 'ShortOutput' => "Traffic Out %s Bytes", - 'LongOutput' => "Traffic Out %s Bytes", - 'PerfData' => 'traffic_out', - 'Unit' => 'B', - 'Value' => "%.2f", - } -}; - -sub cloudwatchCheck { - my ($self) = @_; - - @{ $self->{metric} } = @Param; -} - -1; diff --git a/centreon-plugins/cloud/aws/mode/metrics/rdsinstancecpu.pm b/centreon-plugins/cloud/aws/mode/metrics/rdsinstancecpu.pm deleted file mode 100644 index 614598b25..000000000 --- a/centreon-plugins/cloud/aws/mode/metrics/rdsinstancecpu.pm +++ /dev/null @@ -1,53 +0,0 @@ -# -# Copyright 2017 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 cloud::aws::mode::metrics::rdsinstancecpu; - -use strict; -use warnings; -use POSIX; -use Exporter; -our @ISA = qw(Exporter); -our @EXPORT = qw(&cloudwatchCheck); - -my @Param; - -$Param[0] = { - 'NameSpace' => 'AWS/RDS', - 'MetricName' => 'CPUUtilization', - 'ObjectName' => 'DBInstanceIdentifier', - 'Unit' => 'Percent', - 'Labels' => { - 'ShortOutput' => "CPU Usage is %.2f%%", - 'LongOutput' => "CPU Usage is %.2f%%", - 'PerfData' => 'cpu', - 'Unit' => '%', - 'Value' => "%.2f", - } -}; - -sub cloudwatchCheck { - my ($self) = @_; - - @{ $self->{metric} } = @Param; - $self->{option_results}->{starttime} = strftime( "%FT%H:%M:%S.000Z", gmtime( $self->{option_results}->{def_endtime} - 300 ) ); -} - -1; diff --git a/centreon-plugins/cloud/aws/mode/metrics/s3bucketsize.pm b/centreon-plugins/cloud/aws/mode/metrics/s3bucketsize.pm deleted file mode 100644 index 98c794218..000000000 --- a/centreon-plugins/cloud/aws/mode/metrics/s3bucketsize.pm +++ /dev/null @@ -1,74 +0,0 @@ -# -# Copyright 2017 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 cloud::aws::mode::metrics::s3bucketsize; - -use strict; -use warnings; -use POSIX; -use Exporter; -our @ISA = qw(Exporter); -our @EXPORT = qw(&cloudwatchCheck); - -my @Param; - -$Param[0] = { - 'NameSpace' => 'AWS/S3', - 'MetricName' => 'BucketSizeBytes', - 'ObjectName' => 'BucketName', - 'Unit' => 'Bytes', - 'ExtraDimensions' => { - 'Name' => 'StorageType', - 'Value'=> 'StandardStorage' - }, - 'Labels' => { - 'ShortOutput' => "Bucket size is %s Bytes", - 'LongOutput' => "Bucket size is %s Bytes", - 'PerfData' => 'size', - 'Unit' => 'Bytes', - 'Value' => "%s", - } -}; -$Param[1] = { - 'NameSpace' => 'AWS/S3', - 'MetricName' => 'NumberOfObjects', - 'ObjectName' => 'BucketName', - 'Unit' => 'Count', - 'ExtraDimensions' => { - 'Name' => 'StorageType', - 'Value'=> 'AllStorageTypes' - }, - 'Labels' => { - 'ShortOutput' => "Number of objects is %s", - 'LongOutput' => "Number of objects is %s", - 'PerfData' => 'number', - 'Unit' => '', - 'Value' => "%s", - } -}; - -sub cloudwatchCheck { - my ($self) = @_; - - @{ $self->{metric} } = @Param; - $self->{option_results}->{starttime} = strftime( "%FT%H:%M:%S.000Z", gmtime( $self->{option_results}->{def_endtime} - 86400 ) ); -} - -1; diff --git a/centreon-plugins/cloud/aws/mode/rdsinstancestatus.pm b/centreon-plugins/cloud/aws/mode/rdsinstancestatus.pm new file mode 100644 index 000000000..a9cbe77fa --- /dev/null +++ b/centreon-plugins/cloud/aws/mode/rdsinstancestatus.pm @@ -0,0 +1,266 @@ +# +# Copyright 2017 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 cloud::aws::mode::rdsinstancestatus; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; + +my $instance_mode; + +sub custom_status_threshold { + my ($self, %options) = @_; + my $status = 'ok'; + my $message; + + eval { + local $SIG{__WARN__} = sub { $message = $_[0]; }; + local $SIG{__DIE__} = sub { $message = $_[0]; }; + + my $label = $self->{label}; + $label =~ s/-/_/g; + if (defined($instance_mode->{option_results}->{'critical_' . $label}) && $instance_mode->{option_results}->{'critical_' . $label} ne '' && + eval "$instance_mode->{option_results}->{'critical_' . $label}") { + $status = 'critical'; + } elsif (defined($instance_mode->{option_results}->{'warning_' . $label}) && $instance_mode->{option_results}->{'warning_' . $label} ne '' && + eval "$instance_mode->{option_results}->{'warning_' . $label}") { + $status = 'warning'; + } + }; + if (defined($message)) { + $self->{output}->output_add(long_msg => 'filter status issue: ' . $message); + } + + return $status; +} + +sub custom_status_output { + my ($self, %options) = @_; + + my $msg = sprintf('state : %s', + $self->{result_values}->{health}, $self->{result_values}->{replication_health}); + return $msg; +} + +sub custom_status_calc { + my ($self, %options) = @_; + + $self->{result_values}->{state} = $options{new_datas}->{$self->{instance} . '_state'}; + $self->{result_values}->{display} = $options{new_datas}->{$self->{instance} . '_display'}; + return 0; +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'global', type => 0, cb_prefix_output => 'prefix_global_output' }, + { name => 'aws_instances', type => 1, cb_prefix_output => 'prefix_awsinstance_output', message_multiple => 'All instances are ok' }, + ]; + + $self->{maps_counters}->{global} = [ + { label => 'total-available', set => { + key_values => [ { name => 'available' } ], + output_template => "available : %s", + perfdatas => [ + { label => 'total_available', value => 'available_absolute', template => '%d', min => 0 }, + ], + } + }, + { label => 'total-failed', set => { + key_values => [ { name => 'failed' } ], + output_template => "failed : %s", + perfdatas => [ + { label => 'total_failed', value => 'failed_absolute', template => '%d', min => 0 }, + ], + } + }, + { label => 'total-backing-up', set => { + key_values => [ { name => 'backing-up' } ], + output_template => "backing-up : %s", + perfdatas => [ + { label => 'total_backing_up', value => 'backing-up_absolute', template => '%d', min => 0 }, + ], + } + }, + { label => 'total-maintenance', set => { + key_values => [ { name => 'maintenance' } ], + output_template => "maintenance : %s", + perfdatas => [ + { label => 'total_maintenance', value => 'maintenance_absolute', template => '%d', min => 0 }, + ], + } + }, + { label => 'total-stopped', set => { + key_values => [ { name => 'stopped' } ], + output_template => "stopped : %s", + perfdatas => [ + { label => 'total_stopped', value => 'stopped_absolute', template => '%d', min => 0 }, + ], + } + }, + { label => 'total-storage-full', set => { + key_values => [ { name => 'storage-full' } ], + output_template => "storage-full : %s", + perfdatas => [ + { label => 'total_storage_full', value => 'storage-full_absolute', template => '%d', min => 0 }, + ], + } + }, + ]; + + $self->{maps_counters}->{aws_instances} = [ + { label => 'status', threshold => 0, set => { + key_values => [ { name => 'state' }, { name => 'display' } ], + closure_custom_calc => $self->can('custom_nas_status_calc'), + closure_custom_output => $self->can('custom_nas_status_output'), + closure_custom_perfdata => sub { return 0; }, + closure_custom_threshold_check => $self->can('custom_status_threshold'), + } + }, + ]; +} + +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 => + { + "region:s" => { name => 'region' }, + "filter-instanceid:s" => { name => 'filter_instanceid' }, + "warning-status:s" => { name => 'warning_status', default => '' }, + "critical-status:s" => { name => 'critical_status', default => '' }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::check_options(%options); + + if (!defined($self->{option_results}->{region}) || $self->{option_results}->{region} eq '') { + $self->{output}->add_option_msg(short_msg => "Need to specify --region option."); + $self->{output}->option_exit(); + } + + $instance_mode = $self; + $self->change_macros(); +} + +sub prefix_global_output { + my ($self, %options) = @_; + + return "Total instances "; +} + +sub prefix_awsinstance_output { + my ($self, %options) = @_; + + return "Instance '" . $options{instance_value}->{display} . "' "; +} + +sub change_macros { + my ($self, %options) = @_; + + foreach (('warning_status', 'critical_status')) { + if (defined($self->{option_results}->{$_})) { + $self->{option_results}->{$_} =~ s/%\{(.*?)\}/\$self->{result_values}->{$1}/g; + } + } +} + +sub manage_selection { + my ($self, %options) = @_; + + $self->{global} = { + available => 0, 'backing-up' => 0, failed => 0, maintenance => 0, stopped => 0, 'storage-full' => 0, + }; + $self->{aws_instances} = {}; + my $result = $options{custom}->rds_get_instances_status(region => $self->{option_results}->{region}); + foreach my $instance_id (keys %{$result}) { + if (defined($self->{option_results}->{filter_instanceid}) && $self->{option_results}->{filter_instanceid} ne '' && + $instance_id !~ /$self->{option_results}->{filter_instanceid}/) { + $self->{output}->output_add(long_msg => "skipping '" . $instance_id . "': no matching filter.", debug => 1); + next; + } + + $self->{aws_instances}->{$instance_id} = { + display => $instance_id, + state => $result->{$instance_id}->{state}, + }; + $self->{global}->{$result->{$instance_id}->{state}}++ if (defined($self->{global}->{$result->{$instance_id}->{state}})); + } + + if (scalar(keys %{$self->{aws_instances}}) <= 0) { + $self->{output}->add_option_msg(short_msg => "No aws rds instance found."); + $self->{output}->option_exit(); + } +} + +1; + +__END__ + +=head1 MODE + +Check RDS instances status. + +=over 8 + +=item B<--filter-counters> + +Only display some counters (regexp can be used). +Example: --filter-counters='^total-available$' + +=item B<--filter-instanceid> + +Filter by instance id (can be a regexp). + +=item B<--warning-status> + +Set warning threshold for status (Default: ''). +Can used special variables like: %{state}, %{display} + +=item B<--critical-status> + +Set critical threshold for status (Default: ''). +Can used special variables like: %{state}, %{display} + +=item B<--warning-*> + +Threshold warning. +Can be: 'total-available', 'total-backing-up', 'total-failed', +'total-maintenance', 'total-stopped', 'total-storage-full'. + +=item B<--critical-*> + +Threshold critical. +Can be: 'total-available', 'total-backing-up', 'total-failed', +'total-maintenance', 'total-stopped', 'total-storage-full'. + +=back + +=cut diff --git a/centreon-plugins/cloud/aws/plugin.pm b/centreon-plugins/cloud/aws/plugin.pm index 40bf1da07..bf8e60d84 100644 --- a/centreon-plugins/cloud/aws/plugin.pm +++ b/centreon-plugins/cloud/aws/plugin.pm @@ -31,21 +31,18 @@ sub new { $self->{version} = '0.1'; %{ $self->{modes} } = ( - 'instancestate' => 'cloud::aws::mode::instancestate', - 'list' => 'cloud::aws::mode::list', - 'cloudwatch' => 'cloud::aws::mode::cloudwatch', + 'cloudwatch-get-alarms' => 'cloud::aws::mode::cloudwatchgetalarms', + 'cloudwatch-get-metrics' => 'cloud::aws::mode::cloudwatchgetmetrics', + 'cloudwatch-list-metrics' => 'cloud::aws::mode::cloudwatchlistmetrics', + 'ec2-instance-status' => 'cloud::aws::mode::ec2instancestatus', + 'rds-instance-status' => 'cloud::aws::mode::rdsinstancestatus', ); + $self->{custom_modes}{paws} = 'cloud::aws::custom::paws'; $self->{custom_modes}{awscli} = 'cloud::aws::custom::awscli'; return $self; } -sub init { - my ( $self, %options ) = @_; - - $self->SUPER::init(%options); -} - 1; __END__ @@ -54,13 +51,4 @@ __END__ Check Amazon AWS cloud. -=over 8 - -For this plugin to work, you have to install and configure: -awscli (http://docs.aws.amazon.com/cli/latest/userguide/installing.html#install-bundle-other-os). -perl-json -perl-Module-Load - -=back - =cut diff --git a/centreon-plugins/database/mssql/plugin.pm b/centreon-plugins/database/mssql/plugin.pm index f2e7a8761..a114cffd0 100644 --- a/centreon-plugins/database/mssql/plugin.pm +++ b/centreon-plugins/database/mssql/plugin.pm @@ -43,6 +43,7 @@ sub new { 'dead-locks' => 'database::mssql::mode::deadlocks', 'backup-age' => 'database::mssql::mode::backupage', 'sql' => 'centreon::common::protocols::sql::mode::sql', + 'sql-string' => 'centreon::common::protocols::sql::mode::sqlstring', ); return $self; diff --git a/centreon-plugins/database/mysql/mode/databasessize.pm b/centreon-plugins/database/mysql/mode/databasessize.pm index 3e809ee2f..c872fd38a 100644 --- a/centreon-plugins/database/mysql/mode/databasessize.pm +++ b/centreon-plugins/database/mysql/mode/databasessize.pm @@ -61,7 +61,7 @@ sub run { $self->{sql} = $options{sql}; $self->{sql}->connect(); - $self->{sql}->query(query => 'SELECT table_schema AS NAME, SUM(data_length+index_length) + $self->{sql}->query(query => 'SELECT table_schema AS NAME, IFNULL(SUM(data_length+index_length), 0) FROM information_schema.tables GROUP BY table_schema'); my $result = $self->{sql}->fetchall_arrayref(); diff --git a/centreon-plugins/database/mysql/mode/opentables.pm b/centreon-plugins/database/mysql/mode/opentables.pm new file mode 100644 index 000000000..09e74f1cc --- /dev/null +++ b/centreon-plugins/database/mysql/mode/opentables.pm @@ -0,0 +1,118 @@ +# +# Copyright 2017 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 database::mysql::mode::opentables; + +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) = @_; + # $options{sql} = sqlmode object + $self->{sql} = $options{sql}; + + $self->{sql}->connect(); + + if (!($self->{sql}->is_version_minimum(version => '5'))) { + $self->{output}->add_option_msg(short_msg => "MySQL version '" . $self->{sql}->{version} . "' is not supported (need version >= '5.x')."); + $self->{output}->option_exit(); + } + + $self->{sql}->query(query => q{SHOW VARIABLES LIKE 'table_open_cache'}); + my ($dummy, $open_tables_limit) = $self->{sql}->fetchrow_array(); + if (!defined($open_tables_limit)) { + $self->{output}->add_option_msg(short_msg => "Cannot get open table limit."); + $self->{output}->option_exit(); + } + $self->{sql}->query(query => q{SHOW /*!50000 global */ STATUS LIKE 'Open_tables'}); + ($dummy, my $open_tables) = $self->{sql}->fetchrow_array(); + if (!defined($open_tables)) { + $self->{output}->add_option_msg(short_msg => "Cannot get open tables."); + $self->{output}->option_exit(); + } + + my $prct_open = int(100 * $open_tables / $open_tables_limit); + my $exit_code = $self->{perfdata}->threshold_check(value => $prct_open, threshold => [ { label => 'critical', exit_litteral => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]); + + $self->{output}->output_add(severity => $exit_code, + short_msg => sprintf("%.2f%% of the open files limit reached (%d of max. %d)", + $prct_open, $open_tables, $open_tables_limit)); + $self->{output}->perfdata_add(label => 'open_tables', + value => $open_tables, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning', total => $open_tables_limit, cast_int => 1), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical', total => $open_tables_limit, cast_int => 1), + min => 0); + + $self->{output}->display(); + $self->{output}->exit(); +} + +1; + +__END__ + +=head1 MODE + +Check number of open tables. + +=over 8 + +=item B<--warning> + +Threshold warning in percent. + +=item B<--critical> + +Threshold critical in percent. + +=back + +=cut diff --git a/centreon-plugins/database/mysql/mode/tablescount.pm b/centreon-plugins/database/mysql/mode/tablescount.pm new file mode 100644 index 000000000..54d857205 --- /dev/null +++ b/centreon-plugins/database/mysql/mode/tablescount.pm @@ -0,0 +1,118 @@ +# +# Copyright 2017 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 database::mysql::mode::tablescount; + +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:s" => { name => 'filter', }, + }); + + 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}; + + $self->{sql}->connect(); + $self->{sql}->query(query => 'SELECT table_schema AS NAME, COUNT(*) + FROM information_schema.tables + GROUP BY table_schema'); + my $result = $self->{sql}->fetchall_arrayref(); + + $self->{output}->output_add(severity => 'OK', + short_msg => "All databases are ok."); + foreach my $row (@$result) { + next if (defined($self->{option_results}->{filter}) && + $$row[0] !~ /$self->{option_results}->{filter}/); + + my $exit_code = $self->{perfdata}->threshold_check(value => $$row[1], threshold => [ { label => 'critical', exit_litteral => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]); + + my $value = $$row[1]; + $self->{output}->output_add(long_msg => sprintf("DB '" . $$row[0] . "' tables count: %s", $value)); + if (!$self->{output}->is_status(value => $exit_code, compare => 'ok', litteral => 1)) { + $self->{output}->output_add(severity => $exit_code, + short_msg => sprintf("DB '" . $$row[0] . "' tables count: %s", $value)); + } + $self->{output}->perfdata_add(label => $$row[0] . '_tablescount', unit => '', + value => $$row[1], + 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 MySQL tables count by db. + +=over 8 + +=item B<--warning> + +Threshold warning. + +=item B<--critical> + +Threshold critical. + +=item B<--filter> + +Filter database to checks. + +=back + +=cut diff --git a/centreon-plugins/database/mysql/mode/tablessize.pm b/centreon-plugins/database/mysql/mode/tablessize.pm index f57998c2d..297b113b1 100644 --- a/centreon-plugins/database/mysql/mode/tablessize.pm +++ b/centreon-plugins/database/mysql/mode/tablessize.pm @@ -81,15 +81,13 @@ sub prefix_table_output { sub manage_selection { my ($self, %options) = @_; - # $options{sql} = sqlmode object - $self->{sql} = $options{sql}; - $self->{sql}->connect(); - $self->{sql}->query(query => "SELECT table_schema AS DB, table_name AS NAME, ROUND(data_length + index_length) - FROM information_schema.TABLES"); - my $result = $self->{sql}->fetchall_arrayref(); + $options{sql}->connect(); + $options{sql}->query(query => "SELECT table_schema AS DB, table_name AS NAME, ROUND(data_length + index_length) + FROM information_schema.TABLES"); + my $result = $options{sql}->fetchall_arrayref(); - if (!($self->{sql}->is_version_minimum(version => '5'))) { + if (!($options{sql}->is_version_minimum(version => '5'))) { $self->{output}->add_option_msg(short_msg => "MySQL version '" . $self->{sql}->{version} . "' is not supported."); $self->{output}->option_exit(); } @@ -101,12 +99,12 @@ sub manage_selection { next if (!defined($$row[2])); if (defined($self->{option_results}->{filter_table}) && $self->{option_results}->{filter_table} ne '' && $$row[1] !~ /$self->{option_results}->{filter_table}/) { - $self->{output}->output_add(long_msg => "Skipping '" . $$row[0].'.'.$$row[1] . "': no matching filter.", debug => 1); + $self->{output}->output_add(long_msg => "skipping '" . $$row[0].'.'.$$row[1] . "': no matching filter.", debug => 1); next; } if (defined($self->{option_results}->{filter_db}) && $self->{option_results}->{filter_db} ne '' && $$row[0] !~ /$self->{option_results}->{filter_db}/) { - $self->{output}->output_add(long_msg => "Skipping '" . $$row[0].'.'.$$row[1] . "': no matching filter.", debug => 1); + $self->{output}->output_add(long_msg => "skipping '" . $$row[0].'.'.$$row[1] . "': no matching filter.", debug => 1); next } $self->{table}->{$$row[0].'.'.$$row[1]} = { size => $$row[2], display => $$row[0].'.'.$$row[1] }; diff --git a/centreon-plugins/database/mysql/mode/threadsconnected.pm b/centreon-plugins/database/mysql/mode/threadsconnected.pm index e8741983f..6111424fe 100644 --- a/centreon-plugins/database/mysql/mode/threadsconnected.pm +++ b/centreon-plugins/database/mysql/mode/threadsconnected.pm @@ -56,26 +56,21 @@ sub check_options { sub run { my ($self, %options) = @_; - # $options{sql} = sqlmode object - $self->{sql} = $options{sql}; - $self->{sql}->connect(); + $options{sql}->connect(); - if (!($self->{sql}->is_version_minimum(version => '5'))) { + if (!($options{sql}->is_version_minimum(version => '5'))) { $self->{output}->add_option_msg(short_msg => "MySQL version '" . $self->{sql}->{version} . "' is not supported (need version >= '5.x')."); $self->{output}->option_exit(); } - $self->{sql}->query(query => q{SHOW /*!50000 global */ STATUS LIKE 'Threads_connected'}); - my ($dummy, $result) = $self->{sql}->fetchrow_array(); - if (!defined($result)) { + $options{sql}->query(query => q{SHOW /*!50000 global */ STATUS LIKE 'Threads_connected'}); + my ($name, $value) = $options{sql}->fetchrow_array(); + if (!defined($value)) { $self->{output}->add_option_msg(short_msg => "Cannot get number of open connections."); $self->{output}->option_exit(); } - - my $value = $result; - my $exit_code = $self->{perfdata}->threshold_check(value => $value, threshold => [ { label => 'critical', exit_litteral => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]); $self->{output}->output_add(severity => $exit_code, short_msg => sprintf("%d client connection threads", $value) diff --git a/centreon-plugins/database/mysql/mode/uptime.pm b/centreon-plugins/database/mysql/mode/uptime.pm index 5c0a622f6..f27c1e4a7 100644 --- a/centreon-plugins/database/mysql/mode/uptime.pm +++ b/centreon-plugins/database/mysql/mode/uptime.pm @@ -58,24 +58,19 @@ sub check_options { sub run { my ($self, %options) = @_; - # $options{sql} = sqlmode object - $self->{sql} = $options{sql}; - $self->{sql}->connect(); - - if (!($self->{sql}->is_version_minimum(version => '5'))) { + $options{sql}->connect(); + if (!($options{sql}->is_version_minimum(version => '5'))) { $self->{output}->add_option_msg(short_msg => "MySQL version '" . $self->{sql}->{version} . "' is not supported (need version >= '5.x')."); $self->{output}->option_exit(); } - $self->{sql}->query(query => q{SHOW /*!50000 global */ STATUS LIKE 'Uptime'}); - my ($dummy, $result) = $self->{sql}->fetchrow_array(); - if (!defined($result)) { + $options{sql}->query(query => q{SHOW /*!50000 global */ STATUS LIKE 'Uptime'}); + my ($name, $value) = $options{sql}->fetchrow_array(); + if (!defined($value)) { $self->{output}->add_option_msg(short_msg => "Cannot get uptime."); $self->{output}->option_exit(); } - - my $value = $result; my $exit_code = $self->{perfdata}->threshold_check(value => $value, threshold => [ { label => 'critical', exit_litteral => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]); my $msg = sprintf("database is up since %d days", floor($value / 86400)); diff --git a/centreon-plugins/database/mysql/plugin.pm b/centreon-plugins/database/mysql/plugin.pm index f9ac4003f..bd1055248 100644 --- a/centreon-plugins/database/mysql/plugin.pm +++ b/centreon-plugins/database/mysql/plugin.pm @@ -44,10 +44,12 @@ sub new { 'replication-master-master' => 'database::mysql::mode::replicationmastermaster', 'slow-queries' => 'database::mysql::mode::slowqueries', 'sql' => 'centreon::common::protocols::sql::mode::sql', + 'sql-string' => 'centreon::common::protocols::sql::mode::sqlstring', + 'tables-size' => 'database::mysql::mode::tablessize', 'threads-connected' => 'database::mysql::mode::threadsconnected', 'uptime' => 'database::mysql::mode::uptime', - 'tables-size' => 'database::mysql::mode::tablessize', - ); + ); + $self->{sql_modes}{mysqlcmd} = 'database::mysql::mysqlcmd'; return $self; diff --git a/centreon-plugins/database/oracle/mode/eventwaitsusage.pm b/centreon-plugins/database/oracle/mode/eventwaitsusage.pm index 9de9db890..6f312e169 100644 --- a/centreon-plugins/database/oracle/mode/eventwaitsusage.pm +++ b/centreon-plugins/database/oracle/mode/eventwaitsusage.pm @@ -30,10 +30,22 @@ sub set_counters { my ($self, %options) = @_; $self->{maps_counters_type} = [ - { name => 'event', type => 1, cb_prefix_output => 'prefix_event_output', message_multiple => 'All event waits are OK' }, + { name => 'event_count', type => 0 }, + { name => 'event', type => 1, cb_prefix_output => 'prefix_event_output', message_multiple => 'All event waits are OK', skipped_code => { 11 => -1 }}, ]; - $self->{maps_counters}->{event} = [ + + $self->{maps_counters}->{event_count} = [ + { label => 'event-count', set => { + key_values => [ { name => 'count' } ], + output_template => 'Event Wait Count : %d events' , output_use => 'count_absolute', + perfdatas => [ + { label => 'event_wait_count', value => 'count_absolute', template => '%d', min => 0 } + ], + } + }, + ]; + $self->{maps_counters}->{event} = [ { label => 'total-waits-sec', set => { key_values => [ { name => 'total_waits', diff => 1 }, { name => 'display' } ], per_second => 1, @@ -55,7 +67,7 @@ sub set_counters { ], } }, - ]; + ], } sub custom_usage_calc { @@ -64,7 +76,18 @@ sub custom_usage_calc { $self->{result_values}->{display} = $options{new_datas}->{$self->{instance} . '_display'}; my $delta_total = $options{new_datas}->{$self->{instance} . '_time_waited_micro'} - $options{old_datas}->{$self->{instance} . '_time_waited_micro'}; $self->{result_values}->{prct_wait} = 100 * ($delta_total / 1000000) / $options{delta_time}; - + + return 0; +} + +sub custom_count_calc { + my ($self, %options) = @_; + + $self->{result_values}->{display} = $options{new_datas}->{$self->{instance} . '_display'}; + + my $delta_total = $options{new_datas}->{$self->{instance} . '_time_waited_micro'} - $options{old_datas}->{$self->{instance} . '_time_waited_micro'}; + $self->{result_values}->{prct_wait} = 100 * ($delta_total / 1000000) / $options{delta_time}; + return 0; } @@ -77,6 +100,8 @@ sub new { $options{options}->add_options(arguments => { "filter-name:s" => { name => 'filter_name' }, + "wait-time-min:s" => { name => 'wait_time_min', default => 1000 }, + "show-details" => { name => 'show_details' } }); return $self; } @@ -93,20 +118,20 @@ sub manage_selection { $self->{sql}->connect(); my $query = q{ - SELECT e.event#, e.name, + SELECT e.event#, e.name, NVL(s.total_waits, 0), NVL(s.total_timeouts, 0), NVL(s.time_waited, 0), NVL(s.time_waited_micro, 0), NVL(s.average_wait, 0) FROM v$event_name e LEFT JOIN sys.v_$system_event s ON e.name = s.event - }; + }; if ($self->{sql}->is_version_minimum(version => '10')) { $query = q{ - SELECT e.event_id, e.name, + SELECT e.event_id, e.name, NVL(s.total_waits, 0), NVL(s.total_timeouts, 0), NVL(s.time_waited, 0), NVL(s.time_waited_micro, 0), NVL(s.average_wait, 0) FROM v$event_name e LEFT JOIN sys.v_$system_event s ON e.name = s.event }; } - + $self->{sql}->query(query => $query); my $result = $self->{sql}->fetchall_arrayref(); @@ -126,15 +151,52 @@ sub manage_selection { time_waited_micro => $time_waited_micro }; } - + + my $query_count = "SELECT count(*) as NB + FROM v\$session + WHERE WAIT_TIME_MICRO>" . $self->{option_results}->{wait_time_min} . " + AND status='ACTIVE' and WAIT_CLASS <>'Idle'"; + + $self->{sql}->query(query => $query_count); + $result = $self->{sql}->fetchrow_hashref(); + + $self->{event_count}->{count} = $result->{NB}; + + if (defined($self->{option_results}->{show_details})) { + my $query_details = "SELECT + a.username USERNAME, + a.program PROGRAM, + a.event EVENT, + round(a.WAIT_TIME_MICRO/1000000,0) SEC_WAIT, + d.sql_text SQL_TEXT + FROM + v\$session a, + v\$sqlstats d + WHERE + a.sql_id = d.sql_id + and a.status='ACTIVE' + and a.wait_class <> 'Idle' + and WAIT_TIME_MICRO>" . $self->{option_results}->{wait_time_min} . " + and a.sid not in (SELECT SID FROM V\$SESSION WHERE audsid = userenv('SESSIONID')) + ORDER BY + a.WAIT_TIME_MICRO desc"; + + $self->{sql}->query(query => $query_details ); + while (my $result = $self->{sql}->fetchrow_hashref()) { + $self->{output}->output_add(long_msg => sprintf("Username: '%s', Program: '%s' Event: '%s', Second wait: '%s's, Details: '%s'\n", + $result->{USERNAME}, $result->{PROGRAM}, $result->{EVENT}, $result->{SEC_WAIT}, $result->{SQL_TEXT})); + } + } + if (scalar(keys %{$self->{event}}) <= 0) { $self->{output}->add_option_msg(short_msg => "No event found."); $self->{output}->option_exit(); } - - $self->{cache_name} = "oracle_" . $self->{mode} . '_' . $self->{sql}->get_unique_id4save() . '_' . + + $self->{cache_name} = "oracle_" . $self->{mode} . '_' . $self->{sql}->get_unique_id4save() . '_' . (defined($self->{option_results}->{filter_counters}) ? md5_hex($self->{option_results}->{filter_counters}) : md5_hex('all')) . '_' . (defined($self->{option_results}->{filter_name}) ? md5_hex($self->{option_results}->{filter_name}) : md5_hex('all')); + } 1; @@ -150,17 +212,25 @@ Check Oracle event wait usage. =item B<--warning-*> Threshold warning. -Can be: 'total-waits-sec', 'total-waits-time'. +Can be: 'total-waits-sec', 'total-waits-time', 'count'. =item B<--critical-*> Threshold critical. -Can be: 'total-waits-sec', 'total-waits-time'. +Can be: 'total-waits-sec', 'total-waits-time', 'count'. =item B<--filter-name> Filter by event name. Can be a regex. +=item B<--wait-time-min> + +Time in ms above which we count an event as waiting + +=item B<--show-details> + +Print details of waiting events (user, query, ...) in long output + =back =cut diff --git a/centreon-plugins/database/oracle/mode/invalidobject.pm b/centreon-plugins/database/oracle/mode/invalidobject.pm new file mode 100644 index 000000000..92b198274 --- /dev/null +++ b/centreon-plugins/database/oracle/mode/invalidobject.pm @@ -0,0 +1,204 @@ +# +# Copyright 2017 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 database::oracle::mode::invalidobject; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'global', type => 0, cb_prefix_output => 'prefix_invalid_output', skipped_code => { -10 => 1 } }, + ]; + + $self->{maps_counters}->{global} = [ + { label => 'objects', set => { + key_values => [ { name => 'invalid_objects' } ], + output_template => 'objects : %s', + perfdatas => [ + { label => 'invalid_objects', value => 'invalid_objects_absolute', template => '%d', min => 0 }, + ], + } + }, + { label => 'indexes', set => { + key_values => [ { name => 'invalid_indexes' } ], + output_template => 'indexes : %s', + perfdatas => [ + { label => 'invalid_indexes', value => 'invalid_indexes_absolute', template => '%d', min => 0 }, + ], + } + }, + { label => 'ind-partitions', set => { + key_values => [ { name => 'invalid_ind_partitions' } ], + output_template => 'index partitions : %s', + perfdatas => [ + { label => 'invalid_ind_partitions', value => 'invalid_ind_partitions_absolute', template => '%d', min => 0 }, + ], + } + }, + { label => 'ind-subpartitions', set => { + key_values => [ { name => 'invalid_ind_subpartitions' } ], + output_template => 'index subpartitions : %s', + perfdatas => [ + { label => 'invalid_ind_subpartitions', value => 'invalid_ind_subpartitions_absolute', template => '%d', min => 0 }, + ], + } + }, + { label => 'registry-components', set => { + key_values => [ { name => 'invalid_registry_components' } ], + output_template => 'registry components : %s', + perfdatas => [ + { label => 'invalid_registry_components', value => 'invalid_registry_components_absolute', template => '%d', 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-message:s" => { name => 'filter_message' }, + "retention-objects:s" => { name => 'retention_objects', default => 3}, + }); + + return $self; +} + +sub prefix_invalid_output { + my ($self, %options) = @_; + + return "Invalid "; +} + +sub get_invalids { + my ($self, %options) = @_; + + $self->{global}->{$options{type}} = 0; + $options{sql}->query(query => $options{query}); + my $result = $options{sql}->fetchall_arrayref(); + foreach (@$result) { + if (defined($self->{option_results}->{filter_message}) && $self->{option_results}->{filter_message} ne '' && + $_->[0] !~ /$self->{option_results}->{filter_message}/) { + $self->{output}->output_add(long_msg => "skipping $options{type} => '" . $_->[0] . "': no matching filter.", debug => 1); + next; + } + + $self->{global}->{$options{type}}++; + } +} + +sub manage_selection { + my ($self, %options) = @_; + + $self->{global} = {}; + $options{sql}->connect(); + + $self->get_invalids(%options, type => 'invalid_objects', query => q{ + SELECT + O.object_type||' '||O.owner||'.'||O.object_name||' is '||O.status + FROM dba_objects O + LEFT OUTER JOIN DBA_MVIEW_refresh_times V ON O.object_name = V.NAME AND O.owner = V.owner + WHERE (LAST_REFRESH <= (SELECT sysdate - } . $self->{option_results}->{retention_objects} . q{ FROM dual) OR LAST_REFRESH is null) AND + STATUS = 'INVALID' AND O.object_name NOT LIKE 'BIN$%' + }); + + $self->get_invalids(%options, type => 'invalid_indexes', query => q{ + SELECT index_type||' index '||owner||'.'||index_name||' of '||table_owner||'.'||table_name||' is '||status + FROM dba_indexes + WHERE status <> 'VALID' AND status <> 'N/A' + }); + + $self->get_invalids(%options, type => 'invalid_ind_partitions', query => q{ + SELECT partition_name||' of '||index_owner||'.'||index_name||' is '||status + FROM dba_ind_partitions + WHERE status <> 'USABLE' AND status <> 'N/A' + }); + + if ($options{sql}->is_version_minimum(version => '10.x')) { + $self->get_invalids(%options, type => 'invalid_ind_subpartitions', query => q{ + SELECT subpartition_name||' of '||partition_name||' of '||index_owner||'.'||index_name||' is '||status + FROM dba_ind_subpartitions + WHERE status <> 'USABLE' AND status <> 'N/A' + }); + } + + if ($options{sql}->is_version_minimum(version => '10.x')) { + $self->get_invalids(%options, type => 'invalid_registry_components', query => q{ + SELECT namespace||'.'||comp_name||'-'||version||' is '||status + FROM dba_registry + WHERE status <> 'VALID' AND status <> 'OPTION OFF' + }); + } else { + $self->get_invalids(%options, type => 'invalid_registry_components', query => q{ + SELECT 'SCHEMA.'||comp_name||'-'||version||' is '||status + FROM dba_registry + WHERE status <> 'VALID' AND status <> 'OPTION OFF' + }); + } +} + +1; + +__END__ + +=head1 MODE + +Check faulty objects, indices, partitions. + +=over 8 + +=item B<--filter-counters> + +Only display some counters (regexp can be used). +Example: --filter-counters='^indexes$' + +=item B<--retention-objects> + +Retention in days for invalid objects (default : 3). + +=item B<--filter-message> + +Filter by message (can be a regexp). + +=item B<--warning-*> + +Threshold warning. +Can be: 'objects', 'indexes', 'ind-partitions', 'ind-subpartitions', +'registry-components'. + +=item B<--critical-*> + +Threshold critical. +Can be: 'objects', 'indexes', 'ind-partitions', 'ind-subpartitions', +'registry-components'. + +=back + +=cut diff --git a/centreon-plugins/database/oracle/mode/temptablespace.pm b/centreon-plugins/database/oracle/mode/temptablespace.pm new file mode 100644 index 000000000..97ce6eac9 --- /dev/null +++ b/centreon-plugins/database/oracle/mode/temptablespace.pm @@ -0,0 +1,202 @@ +# +# Copyright 2017 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 database::oracle::mode::temptablespace; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; +use Digest::MD5 qw(md5_hex); + +my $instance_mode; + +sub custom_usage_perfdata { + my ($self, %options) = @_; + + my $label = 'used'; + my $value_perf = $self->{result_values}->{used}; + if (defined($instance_mode->{option_results}->{free})) { + $label = 'free'; + $value_perf = $self->{result_values}->{free}; + } + + my %total_options = (); + if ($instance_mode->{option_results}->{units} eq '%') { + $total_options{total} = $self->{result_values}->{total}; + $total_options{cast_int} = 1; + } + + $self->{output}->perfdata_add(label => $label, + value => $value_perf, unit => 'B', + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{label}, %total_options), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{label}, %total_options), + min => 0, max => $self->{result_values}->{total}); +} + +sub custom_usage_threshold { + my ($self, %options) = @_; + + my ($exit, $threshold_value); + $threshold_value = $self->{result_values}->{used}; + $threshold_value = $self->{result_values}->{free} if (defined($instance_mode->{option_results}->{free})); + if ($instance_mode->{option_results}->{units} eq '%') { + $threshold_value = $self->{result_values}->{prct_used}; + $threshold_value = $self->{result_values}->{prct_free} if (defined($instance_mode->{option_results}->{free})); + } + $exit = $self->{perfdata}->threshold_check(value => $threshold_value, 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 $msg = sprintf("Total: %s%s Used: %s%s (%.2f%%) Free: %s%s (%.2f%%)", + $self->{perfdata}->change_bytes(value => $self->{result_values}->{total}), + $self->{perfdata}->change_bytes(value => $self->{result_values}->{used}), $self->{result_values}->{prct_used}, + $self->{perfdata}->change_bytes(value => $self->{result_values}->{free}), $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} . '_used'}; + $self->{result_values}->{prct_used} = $self->{result_values}->{used} * 100 / $self->{result_values}->{total}; + $self->{result_values}->{free} = $self->{result_values}->{total} - $self->{result_values}->{used}; + $self->{result_values}->{prct_free} = 100 - $self->{result_values}->{prct_used}; + + return 0; +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'tmptablespace', type => 1, cb_prefix_output => 'prefix_tablespace_output', message_multiple => 'All temporary tablespaces are OK' }, + ]; + + $self->{maps_counters}->{tmptablespace} = [ + { label => 'usage', set => { + key_values => [ { name => 'used' }, { name => 'total' }, { name => 'display' } ], + 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 prefix_tablespace_output { + my ($self, %options) = @_; + + return "Temp Tablespace '" . $options{instance_value}->{display} . "' "; +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options, statefile => 0); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => + { + "units:s" => { name => 'units', default => '%' }, + "free" => { name => 'free' }, + }); + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::check_options(%options); + + $instance_mode = $self; +} + + +sub manage_selection { + my ($self, %options) = @_; + $self->{sql} = $options{sql}; + $self->{sql}->connect(); + + my $query = q{ + WITH + TMP as + ( + SELECT + B.name, + C.block_size, + SUM (C.bytes) b_total + FROM + v$tablespace B join + v$tempfile C + using ( ts#) + GROUP BY + B.name, C.block_size + ) + SELECT + A.tablespace_name tablespace, TMP.b_total, + SUM (A.used_blocks * TMP.block_size) b_used, + TMP.b_total - SUM (A.used_blocks * TMP.block_size) / 1024 b_free + FROM + v$sort_segment A join TMP on A.tablespace_name = TMP.name + GROUP by + A.tablespace_name, TMP.b_total + }; + + $self->{sql}->query(query => $query); + + while (my $result = $self->{sql}->fetchrow_hashref()) { + $self->{tmptablespace}->{$result->{TABLESPACE}} = { used => $result->{B_USED}, total => $result->{B_TOTAL}, display => lc $result->{TABLESPACE} }; + } +} + +1; + +__END__ + +=head1 MODE + +Check Oracle TEMP tablespaces + +=over 8 + +=item B<--units> + +Unit of thresholds (Can be : '%' (default) or 'B') + +=item B<--free> + +Threshold are on free space left + +=item B<--warning-usage> + +Threshold warning. + +=item B<--critical-usage> + +Threshold critical. + +=back + +=cut diff --git a/centreon-plugins/database/oracle/mode/undotablespace.pm b/centreon-plugins/database/oracle/mode/undotablespace.pm new file mode 100644 index 000000000..7695b2317 --- /dev/null +++ b/centreon-plugins/database/oracle/mode/undotablespace.pm @@ -0,0 +1,209 @@ +# +# Copyright 2017 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 database::oracle::mode::undotablespace; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; +use Digest::MD5 qw(md5_hex); + +my $instance_mode; + +sub custom_usage_perfdata { + my ($self, %options) = @_; + + my $label = 'used'; + my $value_perf = $self->{result_values}->{used}; + if (defined($instance_mode->{option_results}->{free})) { + $label = 'free'; + $value_perf = $self->{result_values}->{free}; + } + + my %total_options = (); + if ($instance_mode->{option_results}->{units} eq '%') { + $total_options{total} = $self->{result_values}->{total}; + $total_options{cast_int} = 1; + } + + $self->{output}->perfdata_add(label => $label, + value => $value_perf, unit => 'B', + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{label}, %total_options), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{label}, %total_options), + min => 0, max => $self->{result_values}->{total}); +} + +sub custom_usage_threshold { + my ($self, %options) = @_; + + my ($exit, $threshold_value); + $threshold_value = $self->{result_values}->{used}; + $threshold_value = $self->{result_values}->{free} if (defined($instance_mode->{option_results}->{free})); + if ($instance_mode->{option_results}->{units} eq '%') { + $threshold_value = $self->{result_values}->{prct_used}; + $threshold_value = $self->{result_values}->{prct_free} if (defined($instance_mode->{option_results}->{free})); + } + $exit = $self->{perfdata}->threshold_check(value => $threshold_value, 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 $msg = sprintf("Total: %s%s Used: %s%s (%.2f%%) Free: %s%s (%.2f%%)", + $self->{perfdata}->change_bytes(value => $self->{result_values}->{total}), + $self->{perfdata}->change_bytes(value => $self->{result_values}->{used}), $self->{result_values}->{prct_used}, + $self->{perfdata}->change_bytes(value => $self->{result_values}->{free}), $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} . '_used'}; + $self->{result_values}->{prct_used} = $self->{result_values}->{used} * 100 / $self->{result_values}->{total}; + $self->{result_values}->{free} = $self->{result_values}->{total} - $self->{result_values}->{used}; + $self->{result_values}->{prct_free} = 100 - $self->{result_values}->{prct_used}; + + return 0; +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'undotablespace', type => 1, cb_prefix_output => 'prefix_tablespace_output', message_multiple => 'All undo tablespaces are OK' }, + ]; + + $self->{maps_counters}->{undotablespace} = [ + { label => 'usage', set => { + key_values => [ { name => 'used' }, { name => 'total' }, { name => 'display' } ], + 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 prefix_tablespace_output { + my ($self, %options) = @_; + + return "Undo Tablespace '" . $options{instance_value}->{display} . "' "; +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options, statefile => 0); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => + { + "units:s" => { name => 'units', default => '%' }, + "free" => { name => 'free' }, + }); + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::check_options(%options); + + $instance_mode = $self; +} + + +sub manage_selection { + my ($self, %options) = @_; + $self->{sql} = $options{sql}; + $self->{sql}->connect(); + + my $query = q{ + WITH + UND as + ( + SELECT + a.tablespace_name, + nvl(sum(bytes),0) used_bytes + FROM + dba_undo_extents a + WHERE + tablespace_name in (select upper(value) from gv$parameter where name='undo_tablespace') and status in ('ACTIVE','UNEXPIRED') +group by a.tablespace_name + ), + DF as + ( + SELECT + b.tablespace_name, + round(SUM(decode(B.maxbytes, 0, B.BYTES/(1024*1024), B.maxbytes))) total_bytes + FROM + dba_data_files b + WHERE + tablespace_name in (select upper(value) from gv$parameter where name='undo_tablespace') group by b.tablespace_name + ) + SELECT + UND.tablespace_name, + UND.used_bytes, + DF.total_bytes + FROM UND left outer join DF + on (UND.tablespace_name=DF.tablespace_name) + order by DF.tablespace_name + }; + + $self->{sql}->query(query => $query); + + while (my $result = $self->{sql}->fetchrow_hashref()) { + $self->{undotablespace}->{$result->{TABLESPACE_NAME}} = { used => $result->{USED_BYTES}, total => $result->{TOTAL_BYTES}, display => lc $result->{TABLESPACE_NAME} }; + } +} + +1; + +__END__ + +=head1 MODE + +Check Oracle UNDO tablespaces + +=over 8 + +=item B<--units> + +Unit of threshold (Can be : '%' (default) or 'B') + +=item B<--free> + +Threshold are on free space left + +=item B<--warning-usage> + +Threshold warning. + +=item B<--critical-usage> + +Threshold critical. + +=back + +=cut diff --git a/centreon-plugins/database/oracle/plugin.pm b/centreon-plugins/database/oracle/plugin.pm index ad0cb4bae..8ab60188f 100644 --- a/centreon-plugins/database/oracle/plugin.pm +++ b/centreon-plugins/database/oracle/plugin.pm @@ -39,6 +39,7 @@ sub new { 'data-files-status' => 'database::oracle::mode::datafilesstatus', 'datacache-hitratio' => 'database::oracle::mode::datacachehitratio', 'event-waits-usage' => 'database::oracle::mode::eventwaitsusage', + 'invalid-object' => 'database::oracle::mode::invalidobject', 'long-queries' => 'database::oracle::mode::longqueries', 'process-usage' => 'database::oracle::mode::processusage', 'rman-backup-problems' => 'database::oracle::mode::rmanbackupproblems', @@ -46,8 +47,11 @@ sub new { 'rman-online-backup-age' => 'database::oracle::mode::rmanonlinebackupage', 'rollback-segment-usage' => 'database::oracle::mode::rollbacksegmentusage', 'tablespace-usage' => 'database::oracle::mode::tablespaceusage', + 'temp-usage' => 'database::oracle::mode::temptablespace', + 'undo-usage' => 'database::oracle::mode::undotablespace', 'session-usage' => 'database::oracle::mode::sessionusage', 'sql' => 'centreon::common::protocols::sql::mode::sql', + 'sql-string' => 'centreon::common::protocols::sql::mode::sqlstring', 'tnsping' => 'database::oracle::mode::tnsping', ); diff --git a/centreon-plugins/docs/en/developer/guide.rst b/centreon-plugins/docs/en/developer/guide.rst index 41dc32334..a38fb50cd 100644 --- a/centreon-plugins/docs/en/developer/guide.rst +++ b/centreon-plugins/docs/en/developer/guide.rst @@ -1479,7 +1479,7 @@ Then, edit **plugin.pm** and add the following lines: .. code-block:: perl # - # Copyright 2016 Centreon (http://www.centreon.com/) + # Copyright 2017 Centreon (http://www.centreon.com/) # # Centreon is a full-fledged industry-strength solution that meets # the needs in IT infrastructure and application monitoring for @@ -1569,7 +1569,7 @@ Edit **memorydroppedpackets.pm** and add the following lines: .. code-block:: perl # - # Copyright 2016 Centreon (http://www.centreon.com/) + # Copyright 2017 Centreon (http://www.centreon.com/) # # Centreon is a full-fledged industry-strength solution that meets # the needs in IT infrastructure and application monitoring for @@ -2233,4 +2233,4 @@ The following example show 4 new attributes: Class hardware -------------- -TODO \ No newline at end of file +TODO diff --git a/centreon-plugins/docs/en/user/guide.rst b/centreon-plugins/docs/en/user/guide.rst index 992736529..e913a939b 100644 --- a/centreon-plugins/docs/en/user/guide.rst +++ b/centreon-plugins/docs/en/user/guide.rst @@ -453,7 +453,7 @@ How can i check a generic SNMP OID value ? There is a generic SNMP plugin to check it. An example to get 'SysUptime' SNMP OID: :: - $ perl centreon_plugins.pl --plugin=snmp_standard::plugin --mode=numeric-value --oid='.1.3.6.1.2.1.1.3.0' --hostname=127.0.0.1 --snmp-version=2c --snmp-community=public + $ perl centreon_plugins.pl --plugin=apps::protocols::snmp::plugin --mode=numeric-value --oid='.1.3.6.1.2.1.1.3.0' --hostname=127.0.0.1 --snmp-version=2c --snmp-community=public ---------------------------------------- How can i check ipv6 equipment in SNMP ? @@ -1119,33 +1119,44 @@ Design of configuration file Command line, output, threshold ... ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Sample command : +Sample command: :: /usr/lib/nagios/plugins/centreon_plugins.pl --plugin database::mysql::plugin --dyn-mode apps::centreon::sql::mode::multiservices --host localhost --username centreon --password c3ntreon --config-file '/root/global-services.json' --verbose -Sample output : +Sample output: :: OK: Hosts state summary [up:4][down:2][unreachable:0] - Services state summary [ok:4][warning:0][critical:2][unknown:0] - Nothing special on groups | -Perfdatas : +Perfdatas: :: 'total_host_up'=4;;;0; 'total_host_down'=2;;;0; 'total_host_unreachable'=0;;;0; 'total_host_ok'=4;;;0; 'total_host_warning'=0;;;0; 'total_host_critical'=2;;;0; 'total_host_unknown'=0;;;0; 'host_up_ESX'=4;;;0; 'host_down_ESX'=0;;;0; 'host_unreachable_ESX'=0;;;0; 'service_ok_ESX'=4;;;0; 'service_warning_ESX'=0;;;0; 'service_critical_ESX'=0;;;0; 'service_unknown_ESX'=0;;;0; 'host_up_XIVO'=0;;;0; 'host_down_XIVO'=2;;;0; 'host_unreachable_XIVO'=0;;;0; 'service_ok_XIVO'=0;;;0; 'service_warning_XIVO'=0;;;0; 'service_critical_XIVO'=2;;;0; 'service_unknown_XIVO'=0;;;0; -Verbose mode (with display details set as true) : +Verbose mode (with display details set as true): :: Group 'ESX': HOSTS: [up: 4 (clus-esx-n1.com - clus-esx-n2.com - clus-esx-n3.com - clus-esx-n4.com)][down: 0][unreachable: 0] - SERVICES: [ok: 4 (clus-esx-n1.com/Esx-Status - clus-esx-n2.com/Esx-Status - clus-esx-n3.com/Esx-Status - clus-esx-n4.com/Esx-Status)][warning: 0][critical: 0][unknown: 0] Group 'XIVO': HOSTS: [up: 0][down: 2 (srvi-xivo-n1 - srvi-xivo-n2)][unreachable: 0] - SERVICES: [ok: 0][warning: 0][critical: 2 (srvi-xivo-n1/Ping - srvi-xivo-n2/Ping)][unknown: 0] -Concerning the threshold, you can use some example below : +Concerning the threshold, you can use some example below: :: --critical-total '%{total_down} > 4' --critical-groups '%{instance} eq 'ESX' && %{unknown} > 5' + +-------- +NSClient +-------- + +You can monitor Windows/Linux system with the Rest API of NSClient. Commands and arguments are the same than NRPE (look the NSClient documentation for more informations): + +:: + + $ perl centreon_plugins.pl --plugin=apps::nsclient::restapi::plugin --mode=query --hostname="10.30.2.10" --port=443 --legacy-password=centreon --command=check_drivesize --arg="drive=*" --arg="perf-config=used(unit:B)used %(ignored:true)" --arg="filter=type = 'fixed' and name not regexp '.*yst.*'" --arg="warning=total_used>80%" --arg="critical=total_used>90%" + OK All 2 drive(s) are ok | '\\?\Volume{7cd2d555-9868-11e7-8199-806e6f6e6963}\ used'=289468416.000B;293598003.000;330297753.000;0.000;366997504.000 'C:\ used'=23285907456.000B;42654390681.000;47986189516.000;0.000;53317988352.000 diff --git a/centreon-plugins/docs/fr/developer/guide.rst b/centreon-plugins/docs/fr/developer/guide.rst index 7f54ffaa5..6a1f4cf67 100644 --- a/centreon-plugins/docs/fr/developer/guide.rst +++ b/centreon-plugins/docs/fr/developer/guide.rst @@ -1469,7 +1469,7 @@ Ensuite, éditer le fichier **plugin.pm** et ajouter les lignes suivantes : .. code-block:: perl # - # Copyright 2016 Centreon (http://www.centreon.com/) + # Copyright 2017 Centreon (http://www.centreon.com/) # # Centreon is a full-fledged industry-strength solution that meets # the needs in IT infrastructure and application monitoring for @@ -1559,7 +1559,7 @@ Editer le fichier **memorydroppedpackets.pm** et ajouter les lignes suivantes : .. code-block:: perl # - # Copyright 2016 Centreon (http://www.centreon.com/) + # Copyright 2017 Centreon (http://www.centreon.com/) # # Centreon is a full-fledged industry-strength solution that meets # the needs in IT infrastructure and application monitoring for diff --git a/centreon-plugins/docs/fr/user/guide.rst b/centreon-plugins/docs/fr/user/guide.rst index b31d74e55..4201384f1 100644 --- a/centreon-plugins/docs/fr/user/guide.rst +++ b/centreon-plugins/docs/fr/user/guide.rst @@ -461,7 +461,7 @@ Comment puis-je vérifier la valeur d'un OID SNMP générique ? Il y a un plugin SNMP générique pour vérifier cela. Voici un exemple pour obtenir l'OID SNMP 'SysUptime' : :: - $ perl centreon_plugins.pl --plugin=snmp_standard::plugin --mode=numeric-value --oid='.1.3.6.1.2.1.1.3.0' --hostname=127.0.0.1 --snmp-version=2c --snmp-community=public + $ perl centreon_plugins.pl --plugin=apps::protocols::snmp::plugin --mode=numeric-value --oid='.1.3.6.1.2.1.1.3.0' --hostname=127.0.0.1 --snmp-version=2c --snmp-community=public --------------------------------------------------------------------- Comment utiliser un serveur memcached pour la rétention des données ? @@ -1150,3 +1150,14 @@ Voici la manière de définir les seuils (total_statut pour les warning/critical :: --critical-total '%{total_down} > 4' --critical-groups '%{instance} eq 'ESX' && %{unknown} > 5' + +-------- +NSClient +-------- + +Vous pouvez superviser des systèmes Windows/Linux via l'API Rest de NSClient. Les commandes et arguments sont les mêmes que via NRPE (veuillez lire la documentation NSClient pour plus d'informations) : + +:: + + $ perl centreon_plugins.pl --plugin=apps::nsclient::restapi::plugin --mode=query --hostname="10.30.2.10" --port=443 --legacy-password=centreon --command=check_drivesize --arg="drive=*" --arg="perf-config=used(unit:B)used %(ignored:true)" --arg="filter=type = 'fixed' and name not regexp '.*yst.*'" --arg="warning=total_used>80%" --arg="critical=total_used>90%" + OK All 2 drive(s) are ok | '\\?\Volume{7cd2d555-9868-11e7-8199-806e6f6e6963}\ used'=289468416.000B;293598003.000;330297753.000;0.000;366997504.000 'C:\ used'=23285907456.000B;42654390681.000;47986189516.000;0.000;53317988352.000 diff --git a/centreon-plugins/hardware/devices/video/appeartv/snmp/mode/alarms.pm b/centreon-plugins/hardware/devices/video/appeartv/snmp/mode/alarms.pm index 7f62447a4..cadb15ed3 100644 --- a/centreon-plugins/hardware/devices/video/appeartv/snmp/mode/alarms.pm +++ b/centreon-plugins/hardware/devices/video/appeartv/snmp/mode/alarms.pm @@ -154,7 +154,7 @@ sub manage_selection { { oid => $mapping->{msgText}->{oid} }, { oid => $mapping->{msgGenerationTime}->{oid} }, { oid => $mapping->{msgSeverity}->{oid} }, - ], nothing_quit => 1, return_type => 1); + ], return_type => 1); my $last_time; if (defined($self->{option_results}->{memory})) { diff --git a/centreon-plugins/hardware/sensors/akcp/snmp/mode/components/humidity.pm b/centreon-plugins/hardware/sensors/akcp/snmp/mode/components/humidity.pm index 057961cb5..80b368429 100644 --- a/centreon-plugins/hardware/sensors/akcp/snmp/mode/components/humidity.pm +++ b/centreon-plugins/hardware/sensors/akcp/snmp/mode/components/humidity.pm @@ -25,64 +25,73 @@ use warnings; use hardware::sensors::akcp::snmp::mode::components::resources qw(%map_default1_status %map_online); my $mapping = { - hhmsSensorArrayHumidityDescription => { oid => '.1.3.6.1.4.1.3854.1.2.2.1.17.1.1' }, - hhmsSensorArrayHumidityPercent => { oid => '.1.3.6.1.4.1.3854.1.2.2.1.17.1.3' }, - hhmsSensorArrayHumidityStatus => { oid => '.1.3.6.1.4.1.3854.1.2.2.1.17.1.4', map => \%map_default1_status }, - hhmsSensorArrayHumidityOnline => { oid => '.1.3.6.1.4.1.3854.1.2.2.1.17.1.5', map => \%map_online }, - hhmsSensorArrayHumidityHighWarning => { oid => '.1.3.6.1.4.1.3854.1.2.2.1.17.1.7' }, - hhmsSensorArrayHumidityHighCritical => { oid => '.1.3.6.1.4.1.3854.1.2.2.1.17.1.8' }, - hhmsSensorArrayHumidityLowWarning => { oid => '.1.3.6.1.4.1.3854.1.2.2.1.17.1.9' }, - hhmsSensorArrayHumidityLowCritical => { oid => '.1.3.6.1.4.1.3854.1.2.2.1.17.1.10' }, + HumidityDescription => { oid => '.1.3.6.1.4.1.3854.1.2.2.1.17.1.1' }, # hhmsSensorArrayHumidityDescription + HumidityPercent => { oid => '.1.3.6.1.4.1.3854.1.2.2.1.17.1.3' }, # hhmsSensorArrayHumidityPercent + HumidityStatus => { oid => '.1.3.6.1.4.1.3854.1.2.2.1.17.1.4', map => \%map_default1_status }, # hhmsSensorArrayHumidityStatus + HumidityOnline => { oid => '.1.3.6.1.4.1.3854.1.2.2.1.17.1.5', map => \%map_online }, # hhmsSensorArrayHumidityOnline + HumidityHighWarning => { oid => '.1.3.6.1.4.1.3854.1.2.2.1.17.1.7' }, # hhmsSensorArrayHumidityHighWarning + HumidityHighCritical => { oid => '.1.3.6.1.4.1.3854.1.2.2.1.17.1.8' }, # hhmsSensorArrayHumidityHighCritical + HumidityLowWarning => { oid => '.1.3.6.1.4.1.3854.1.2.2.1.17.1.9' }, # hhmsSensorArrayHumidityLowWarning + HumidityLowCritical => { oid => '.1.3.6.1.4.1.3854.1.2.2.1.17.1.10' }, # hhmsSensorArrayHumidityLowCritical }; +my $mapping2 = { + HumidityDescription => { oid => '.1.3.6.1.4.1.3854.3.5.3.1.2' }, # humidityDescription + HumidityPercent => { oid => '.1.3.6.1.4.1.3854.3.5.3.1.4' }, # humidityPercent + HumidityStatus => { oid => '.1.3.6.1.4.1.3854.3.5.3.1.6', map => \%map_default1_status }, # humidityStatus + HumidityOnline => { oid => '.1.3.6.1.4.1.3854.3.5.3.1.8', map => \%map_online }, # humidityGoOffline + HumidityHighWarning => { oid => '.1.3.6.1.4.1.3854.3.5.3.1.11' }, # humidityHighWarning + HumidityHighCritical => { oid => '.1.3.6.1.4.1.3854.3.5.3.1.12' }, # humidityHighCritical + HumidityLowWarning => { oid => '.1.3.6.1.4.1.3854.3.5.3.1.10' }, # humidityLowWarning + HumidityLowCritical => { oid => '.1.3.6.1.4.1.3854.3.5.3.1.9' }, # humidityLowCritical +}; + my $oid_hhmsSensorArrayHumidityEntry = '.1.3.6.1.4.1.3854.1.2.2.1.17.1'; +my $oid_humidityEntry = '.1.3.6.1.4.1.3854.3.5.3.1'; sub load { my ($self) = @_; - push @{$self->{request}}, { oid => $oid_hhmsSensorArrayHumidityEntry }; + push @{$self->{request}}, { oid => $oid_hhmsSensorArrayHumidityEntry }, + { oid => $oid_humidityEntry, end => $mapping2->{HumidityHighCritical}->{oid} }; } -sub check { - my ($self) = @_; +sub check_humidity { + my ($self, %options) = @_; - $self->{output}->output_add(long_msg => "Checking humidities"); - $self->{components}->{humidity} = {name => 'humidities', total => 0, skip => 0}; - return if ($self->check_filter(section => 'humidity')); - - foreach my $oid ($self->{snmp}->oid_lex_sort(keys %{$self->{results}->{$oid_hhmsSensorArrayHumidityEntry}})) { - next if ($oid !~ /^$mapping->{hhmsSensorArrayHumidityOnline}->{oid}\.(.*)$/); + foreach my $oid ($self->{snmp}->oid_lex_sort(keys %{$self->{results}->{$options{entry}}})) { + next if ($oid !~ /^$options{mapping}->{HumidityOnline}->{oid}\.(.*)$/); my $instance = $1; - my $result = $self->{snmp}->map_instance(mapping => $mapping, results => $self->{results}->{$oid_hhmsSensorArrayHumidityEntry}, instance => $instance); + my $result = $self->{snmp}->map_instance(mapping => $options{mapping}, results => $self->{results}->{$options{entry}}, instance => $instance); next if ($self->check_filter(section => 'humidity', instance => $instance)); - if ($result->{hhmsSensorArrayHumidityOnline} eq 'offline') { - $self->{output}->output_add(long_msg => sprintf("skipping '%s': is offline", $result->{hhmsSensorArrayHumidityDescription})); + if ($result->{HumidityOnline} eq 'offline') { + $self->{output}->output_add(long_msg => sprintf("skipping '%s': is offline", $result->{HumidityDescription})); next; } $self->{components}->{humidity}->{total}++; $self->{output}->output_add(long_msg => sprintf("humidity '%s' status is '%s' [instance = %s] [value = %s]", - $result->{hhmsSensorArrayHumidityDescription}, $result->{hhmsSensorArrayHumidityStatus}, $instance, - $result->{hhmsSensorArrayHumidityPercent})); + $result->{HumidityDescription}, $result->{HumidityStatus}, $instance, + $result->{HumidityPercent})); - my $exit = $self->get_severity(label => 'default1', section => 'humidity', value => $result->{hhmsSensorArrayHumidityStatus}); + my $exit = $self->get_severity(label => 'default1', section => 'humidity', value => $result->{HumidityStatus}); if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { $self->{output}->output_add(severity => $exit, - short_msg => sprintf("Humdity '%s' status is '%s'", $result->{hhmsSensorArrayHumidityDescription}, $result->{hhmsSensorArrayHumidityStatus})); + short_msg => sprintf("Humdity '%s' status is '%s'", $result->{HumidityDescription}, $result->{HumidityStatus})); } - my ($exit2, $warn, $crit, $checked) = $self->get_severity_numeric(section => 'humidity', instance => $instance, value => $result->{hhmsSensorArrayHumidityPercent}); + my ($exit2, $warn, $crit, $checked) = $self->get_severity_numeric(section => 'humidity', instance => $instance, value => $result->{HumidityPercent}); if ($checked == 0) { - $result->{hhmsSensorArrayHumidityLowWarning} = (defined($result->{hhmsSensorArrayHumidityLowWarning}) && $result->{hhmsSensorArrayHumidityLowWarning} =~ /[0-9]/) ? - $result->{hhmsSensorArrayHumidityLowWarning} : ''; - $result->{hhmsSensorArrayHumidityLowCritical} = (defined($result->{hhmsSensorArrayHumidityLowCritical}) && $result->{hhmsSensorArrayHumidityLowCritical} =~ /[0-9]/) ? - $result->{hhmsSensorArrayHumidityLowCritical} : ''; - $result->{hhmsSensorArrayHumidityHighWarning} = (defined($result->{hhmsSensorArrayHumidityHighWarning}) && $result->{hhmsSensorArrayHumidityHighWarning} =~ /[0-9]/) ? - $result->{hhmsSensorArrayHumidityHighWarning} : ''; - $result->{hhmsSensorArrayHumidityHighCritical} = (defined($result->{hhmsSensorArrayHumidityHighCritical}) && $result->{hhmsSensorArrayHumidityHighCritical} =~ /[0-9]/) ? - $result->{hhmsSensorArrayHumidityHighCritical} : ''; - my $warn_th = $result->{hhmsSensorArrayHumidityLowWarning} . ':' . $result->{hhmsSensorArrayHumidityHighWarning}; - my $crit_th = $result->{hhmsSensorArrayHumidityLowCritical} . ':' . $result->{hhmsSensorArrayHumidityHighCritical}; + $result->{HumidityLowWarning} = (defined($result->{HumidityLowWarning}) && $result->{HumidityLowWarning} =~ /[0-9]/) ? + $result->{HumidityLowWarning} : ''; + $result->{HumidityLowCritical} = (defined($result->{HumidityLowCritical}) && $result->{HumidityLowCritical} =~ /[0-9]/) ? + $result->{HumidityLowCritical} : ''; + $result->{HumidityHighWarning} = (defined($result->{HumidityHighWarning}) && $result->{HumidityHighWarning} =~ /[0-9]/) ? + $result->{HumidityHighWarning} : ''; + $result->{HumidityHighCritical} = (defined($result->{HumidityHighCritical}) && $result->{HumidityHighCritical} =~ /[0-9]/) ? + $result->{HumidityHighCritical} : ''; + my $warn_th = $result->{HumidityLowWarning} . ':' . $result->{HumidityHighWarning}; + my $crit_th = $result->{HumidityLowCritical} . ':' . $result->{HumidityHighCritical}; $self->{perfdata}->threshold_validate(label => 'warning-humidity-instance-' . $instance, value => $warn_th); $self->{perfdata}->threshold_validate(label => 'critical-humidity-instance-' . $instance, value => $crit_th); @@ -92,14 +101,25 @@ sub check { if (!$self->{output}->is_status(value => $exit2, compare => 'ok', litteral => 1)) { $self->{output}->output_add(severity => $exit2, - short_msg => sprintf("Humdity '%s' is %s %%", $result->{hhmsSensorArrayHumidityDescription}, $result->{hhmsSensorArrayHumidityPercent})); + short_msg => sprintf("Humdity '%s' is %s %%", $result->{HumidityDescription}, $result->{HumidityPercent})); } - $self->{output}->perfdata_add(label => 'humidity_' . $result->{hhmsSensorArrayHumidityDescription}, unit => '%', - value => $result->{hhmsSensorArrayHumidityPercent}, + $self->{output}->perfdata_add(label => 'humidity_' . $result->{HumidityDescription}, unit => '%', + value => $result->{HumidityPercent}, warning => $warn, critical => $crit, min => 0, max => 100); } } -1; \ No newline at end of file +sub check { + my ($self) = @_; + + $self->{output}->output_add(long_msg => "Checking humidities"); + $self->{components}->{humidity} = {name => 'humidities', total => 0, skip => 0}; + return if ($self->check_filter(section => 'humidity')); + + check_humidity($self, entry => $oid_hhmsSensorArrayHumidityEntry, mapping => $mapping); + check_humidity($self, entry => $oid_humidityEntry, mapping => $mapping2); +} + +1; diff --git a/centreon-plugins/hardware/sensors/akcp/snmp/mode/components/resources.pm b/centreon-plugins/hardware/sensors/akcp/snmp/mode/components/resources.pm index e9b8d40e3..dd718bda4 100644 --- a/centreon-plugins/hardware/sensors/akcp/snmp/mode/components/resources.pm +++ b/centreon-plugins/hardware/sensors/akcp/snmp/mode/components/resources.pm @@ -40,6 +40,8 @@ our @EXPORT_OK = qw(%map_default1_status %map_default2_status %map_online %map_d 5 => 'lowWarning', 6 => 'lowCritical', 7 => 'sensorError', + 8 => 'relayOn', + 9 => 'relayOff', ); %map_default2_status = ( @@ -59,4 +61,4 @@ our @EXPORT_OK = qw(%map_default1_status %map_default2_status %map_online %map_d 1 => 'C', ); -1; \ No newline at end of file +1; diff --git a/centreon-plugins/hardware/sensors/akcp/snmp/mode/components/serial.pm b/centreon-plugins/hardware/sensors/akcp/snmp/mode/components/serial.pm index 5fb817352..d32b639f0 100644 --- a/centreon-plugins/hardware/sensors/akcp/snmp/mode/components/serial.pm +++ b/centreon-plugins/hardware/sensors/akcp/snmp/mode/components/serial.pm @@ -64,9 +64,8 @@ sub check { if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { $self->{output}->output_add(severity => $exit, short_msg => sprintf("Serial '%s' status is '%s'", $result->{hhmsSensorArraySerialDescription}, $result->{hhmsSensorArraySerialStatus})); - next; } } } -1; \ No newline at end of file +1; diff --git a/centreon-plugins/hardware/sensors/akcp/snmp/mode/components/switch.pm b/centreon-plugins/hardware/sensors/akcp/snmp/mode/components/switch.pm index c3ffb8c6e..25b7511f1 100644 --- a/centreon-plugins/hardware/sensors/akcp/snmp/mode/components/switch.pm +++ b/centreon-plugins/hardware/sensors/akcp/snmp/mode/components/switch.pm @@ -64,9 +64,8 @@ sub check { if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { $self->{output}->output_add(severity => $exit, short_msg => sprintf("Switch '%s' status is '%s'", $result->{hhmsSensorArraySwitchDescription}, $result->{hhmsSensorArraySwitchStatus})); - next; } } } -1; \ No newline at end of file +1; diff --git a/centreon-plugins/hardware/sensors/akcp/snmp/mode/components/temperature.pm b/centreon-plugins/hardware/sensors/akcp/snmp/mode/components/temperature.pm index 957f479eb..7cd0985ad 100644 --- a/centreon-plugins/hardware/sensors/akcp/snmp/mode/components/temperature.pm +++ b/centreon-plugins/hardware/sensors/akcp/snmp/mode/components/temperature.pm @@ -25,65 +25,75 @@ use warnings; use hardware::sensors::akcp::snmp::mode::components::resources qw(%map_default1_status %map_online %map_degree_type); my $mapping = { - hhmsSensorArrayTempDescription => { oid => '.1.3.6.1.4.1.3854.1.2.2.1.16.1.1' }, - hhmsSensorArrayTempDegree => { oid => '.1.3.6.1.4.1.3854.1.2.2.1.16.1.3' }, - hhmsSensorArrayTempStatus => { oid => '.1.3.6.1.4.1.3854.1.2.2.1.16.1.4', map => \%map_default1_status }, - hhmsSensorArrayTempOnline => { oid => '.1.3.6.1.4.1.3854.1.2.2.1.16.1.5', map => \%map_online }, - hhmsSensorArrayTempHighWarning => { oid => '.1.3.6.1.4.1.3854.1.2.2.1.16.1.7' }, - hhmsSensorArrayTempHighCritical => { oid => '.1.3.6.1.4.1.3854.1.2.2.1.16.1.8' }, - hhmsSensorArrayTempLowWarning => { oid => '.1.3.6.1.4.1.3854.1.2.2.1.16.1.9' }, - hhmsSensorArrayTempLowCritical => { oid => '.1.3.6.1.4.1.3854.1.2.2.1.16.1.10' }, - hhmsSensorArrayTempDegreeType => { oid => '.1.3.6.1.4.1.3854.1.2.2.1.16.1.12', map => \%map_degree_type }, + TempDescription => { oid => '.1.3.6.1.4.1.3854.1.2.2.1.16.1.1' }, # hhmsSensorArrayTempDescription + TempDegree => { oid => '.1.3.6.1.4.1.3854.1.2.2.1.16.1.3' }, # hhmsSensorArrayTempDegree + TempStatus => { oid => '.1.3.6.1.4.1.3854.1.2.2.1.16.1.4', map => \%map_default1_status }, # hhmsSensorArrayTempStatus + TempOnline => { oid => '.1.3.6.1.4.1.3854.1.2.2.1.16.1.5', map => \%map_online }, # hhmsSensorArrayTempOnline + TempHighWarning => { oid => '.1.3.6.1.4.1.3854.1.2.2.1.16.1.7' }, # hhmsSensorArrayTempHighWarning + TempHighCritical => { oid => '.1.3.6.1.4.1.3854.1.2.2.1.16.1.8' }, # hhmsSensorArrayTempHighCritical + TempLowWarning => { oid => '.1.3.6.1.4.1.3854.1.2.2.1.16.1.9' }, # hhmsSensorArrayTempLowWarning + TempLowCritical => { oid => '.1.3.6.1.4.1.3854.1.2.2.1.16.1.10' }, # hhmsSensorArrayTempLowCritical + TempDegreeType => { oid => '.1.3.6.1.4.1.3854.1.2.2.1.16.1.12', map => \%map_degree_type }, # hhmsSensorArrayTempDegreeType }; +my $mapping2 = { + TempDescription => { oid => '.1.3.6.1.4.1.3854.3.5.2.1.2' }, # temperatureDescription + TempDegree => { oid => '.1.3.6.1.4.1.3854.3.5.2.1.4' }, # temperatureDegree + TempStatus => { oid => '.1.3.6.1.4.1.3854.3.5.2.1.6', map => \%map_default1_status }, # temperatureStatus + TempOnline => { oid => '.1.3.6.1.4.1.3854.3.5.2.1.8', map => \%map_online }, # temperatureGoOffline + TempHighWarning => { oid => '.1.3.6.1.4.1.3854.3.5.2.1.11' }, # temperatureHighWarning + TempHighCritical => { oid => '.1.3.6.1.4.1.3854.3.5.2.1.12' }, # temperatureHighCritical + TempLowWarning => { oid => '.1.3.6.1.4.1.3854.3.5.2.1.10' }, # temperatureLowWarning + TempLowCritical => { oid => '.1.3.6.1.4.1.3854.3.5.2.1.9' }, # temperatureLowCritical + TempDegreeType => { oid => '.1.3.6.1.4.1.3854.3.5.2.1.5'}, # temperatureUnit +}; + my $oid_hhmsSensorArrayTempEntry = '.1.3.6.1.4.1.3854.1.2.2.1.16.1'; +my $oid_temperatureEntry = '.1.3.6.1.4.1.3854.3.5.2.1'; sub load { my ($self) = @_; - push @{$self->{request}}, { oid => $oid_hhmsSensorArrayTempEntry }; + push @{$self->{request}}, { oid => $oid_hhmsSensorArrayTempEntry }, + { oid => $oid_temperatureEntry, end => $mapping2->{TempHighCritical}->{oid} }; } -sub check { - my ($self) = @_; +sub check_temperature { + my ($self, %options) = @_; - $self->{output}->output_add(long_msg => "Checking temperatures"); - $self->{components}->{temperature} = {name => 'temperatures', total => 0, skip => 0}; - return if ($self->check_filter(section => 'temperature')); - - foreach my $oid ($self->{snmp}->oid_lex_sort(keys %{$self->{results}->{$oid_hhmsSensorArrayTempEntry}})) { - next if ($oid !~ /^$mapping->{hhmsSensorArrayTempOnline}->{oid}\.(.*)$/); + foreach my $oid ($self->{snmp}->oid_lex_sort(keys %{$self->{results}->{$options{entry}}})) { + next if ($oid !~ /^$options{mapping}->{TempOnline}->{oid}\.(.*)$/); my $instance = $1; - my $result = $self->{snmp}->map_instance(mapping => $mapping, results => $self->{results}->{$oid_hhmsSensorArrayTempEntry}, instance => $instance); + my $result = $self->{snmp}->map_instance(mapping => $options{mapping}, results => $self->{results}->{$options{entry}}, instance => $instance); next if ($self->check_filter(section => 'temperature', instance => $instance)); - if ($result->{hhmsSensorArrayTempOnline} eq 'offline') { - $self->{output}->output_add(long_msg => sprintf("skipping '%s': is offline", $result->{hhmsSensorArrayTempDescription})); + if ($result->{TempOnline} eq 'offline') { + $self->{output}->output_add(long_msg => sprintf("skipping '%s': is offline", $result->{TempDescription})); next; } $self->{components}->{temperature}->{total}++; $self->{output}->output_add(long_msg => sprintf("temperature '%s' status is '%s' [instance = %s] [value = %s]", - $result->{hhmsSensorArrayTempDescription}, $result->{hhmsSensorArrayTempStatus}, $instance, - $result->{hhmsSensorArrayTempDegree})); + $result->{TempDescription}, $result->{TempStatus}, $instance, + $result->{TempDegree})); - my $exit = $self->get_severity(label => 'default1', section => 'temperature', value => $result->{hhmsSensorArrayTempStatus}); + my $exit = $self->get_severity(label => 'default1', section => 'temperature', value => $result->{TempStatus}); if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { $self->{output}->output_add(severity => $exit, - short_msg => sprintf("Temperature '%s' status is '%s'", $result->{hhmsSensorArrayTempDescription}, $result->{hhmsSensorArrayTempStatus})); + short_msg => sprintf("Temperature '%s' status is '%s'", $result->{TempDescription}, $result->{TempStatus})); } - my ($exit2, $warn, $crit, $checked) = $self->get_severity_numeric(section => 'temperature', instance => $instance, value => $result->{hhmsSensorArrayTempDegree}); + my ($exit2, $warn, $crit, $checked) = $self->get_severity_numeric(section => 'temperature', instance => $instance, value => $result->{TempDegree}); if ($checked == 0) { - $result->{hhmsSensorArrayTempLowWarning} = (defined($result->{hhmsSensorArrayTempLowWarning}) && $result->{hhmsSensorArrayTempLowWarning} =~ /[0-9]/) ? - $result->{hhmsSensorArrayTempLowWarning} : ''; - $result->{hhmsSensorArrayTempLowCritical} = (defined($result->{hhmsSensorArrayTempLowCritical}) && $result->{hhmsSensorArrayTempLowCritical} =~ /[0-9]/) ? - $result->{hhmsSensorArrayTempLowCritical} : ''; - $result->{hhmsSensorArrayTempHighWarning} = (defined($result->{hhmsSensorArrayTempHighWarning}) && $result->{hhmsSensorArrayTempHighWarning} =~ /[0-9]/) ? - $result->{hhmsSensorArrayTempHighWarning} : ''; - $result->{hhmsSensorArrayTempHighCritical} = (defined($result->{hhmsSensorArrayTempHighCritical}) && $result->{hhmsSensorArrayTempHighCritical} =~ /[0-9]/) ? - $result->{hhmsSensorArrayTempHighCritical} : ''; - my $warn_th = $result->{hhmsSensorArrayTempLowWarning} . ':' . $result->{hhmsSensorArrayTempHighWarning}; - my $crit_th = $result->{hhmsSensorArrayTempLowCritical} . ':' . $result->{hhmsSensorArrayTempHighCritical}; + $result->{TempLowWarning} = (defined($result->{TempLowWarning}) && $result->{TempLowWarning} =~ /[0-9]/) ? + $result->{TempLowWarning} * $options{threshold_mult} : ''; + $result->{TempLowCritical} = (defined($result->{TempLowCritical}) && $result->{TempLowCritical} =~ /[0-9]/) ? + $result->{TempLowCritical} * $options{threshold_mult} : ''; + $result->{TempHighWarning} = (defined($result->{TempHighWarning}) && $result->{TempHighWarning} =~ /[0-9]/) ? + $result->{TempHighWarning} * $options{threshold_mult} : ''; + $result->{TempHighCritical} = (defined($result->{TempHighCritical}) && $result->{TempHighCritical} =~ /[0-9]/) ? + $result->{TempHighCritical} * $options{threshold_mult} : ''; + my $warn_th = $result->{TempLowWarning} . ':' . $result->{TempHighWarning}; + my $crit_th = $result->{TempLowCritical} . ':' . $result->{TempHighCritical}; $self->{perfdata}->threshold_validate(label => 'warning-temperature-instance-' . $instance, value => $warn_th); $self->{perfdata}->threshold_validate(label => 'critical-temperature-instance-' . $instance, value => $crit_th); @@ -93,14 +103,25 @@ sub check { if (!$self->{output}->is_status(value => $exit2, compare => 'ok', litteral => 1)) { $self->{output}->output_add(severity => $exit2, - short_msg => sprintf("Temperature '%s' is %s %s", $result->{hhmsSensorArrayTempDescription}, $result->{hhmsSensorArrayTempDegree}, $result->{hhmsSensorArrayTempDegreeType})); + short_msg => sprintf("Temperature '%s' is %s %s", $result->{TempDescription}, $result->{TempDegree}, $result->{TempDegreeType})); } - $self->{output}->perfdata_add(label => 'temperature_' . $result->{hhmsSensorArrayTempDescription}, unit => $result->{hhmsSensorArrayTempDegreeType}, - value => $result->{hhmsSensorArrayTempDegree}, + $self->{output}->perfdata_add(label => 'temperature_' . $result->{TempDescription}, unit => $result->{TempDegreeType}, + value => $result->{TempDegree}, warning => $warn, critical => $crit, ); } } -1; \ No newline at end of file +sub check { + my ($self) = @_; + + $self->{output}->output_add(long_msg => "Checking temperatures"); + $self->{components}->{temperature} = {name => 'temperatures', total => 0, skip => 0}; + return if ($self->check_filter(section => 'temperature')); + + check_temperature($self, entry => $oid_hhmsSensorArrayTempEntry, mapping => $mapping, threshold_mult => 1); + check_temperature($self, entry => $oid_temperatureEntry, mapping => $mapping2, threshold_mult => 0.1); +} + +1; diff --git a/centreon-plugins/hardware/sensors/akcp/snmp/mode/components/water.pm b/centreon-plugins/hardware/sensors/akcp/snmp/mode/components/water.pm new file mode 100644 index 000000000..b0785ce5c --- /dev/null +++ b/centreon-plugins/hardware/sensors/akcp/snmp/mode/components/water.pm @@ -0,0 +1,71 @@ +# +# Copyright 2017 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::sensors::akcp::snmp::mode::components::water; + +use strict; +use warnings; +use hardware::sensors::akcp::snmp::mode::components::resources qw(%map_default1_status %map_online); + +my $mapping = { + waterDescription => { oid => '.1.3.6.1.4.1.3854.3.5.9.1.2' }, + waterStatus => { oid => '.1.3.6.1.4.1.3854.3.5.9.1.6', map => \%map_default1_status }, + waterGoOffline => { oid => '.1.3.6.1.4.1.3854.3.5.9.1.8', map => \%map_online }, +}; +my $oid_waterEntry = '.1.3.6.1.4.1.3854.3.5.9.1'; + +sub load { + my ($self) = @_; + + push @{$self->{request}}, { oid => $oid_waterEntry, end => $mapping->{waterGoOffline}->{oid} }; +} + +sub check { + my ($self) = @_; + + $self->{output}->output_add(long_msg => "Checking waters"); + $self->{components}->{water} = {name => 'waters', total => 0, skip => 0}; + return if ($self->check_filter(section => 'water')); + + foreach my $oid ($self->{snmp}->oid_lex_sort(keys %{$self->{results}->{$oid_waterEntry}})) { + next if ($oid !~ /^$mapping->{waterGoOffline}->{oid}\.(.*)$/); + my $instance = $1; + my $result = $self->{snmp}->map_instance(mapping => $mapping, results => $self->{results}->{$oid_waterEntry}, instance => $instance); + + next if ($self->check_filter(section => 'water', instance => $instance)); + if ($result->{waterGoOffline} eq 'offline') { + $self->{output}->output_add(long_msg => sprintf("skipping '%s': is offline", $result->{waterDescription})); + next; + } + $self->{components}->{water}->{total}++; + + $self->{output}->output_add(long_msg => sprintf("water '%s' status is '%s' [instance = %s]", + $result->{waterDescription}, $result->{waterStatus}, $instance, + )); + + my $exit = $self->get_severity(label => 'default1', section => 'water', value => $result->{waterStatus}); + if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { + $self->{output}->output_add(severity => $exit, + short_msg => sprintf("Water '%s' status is '%s'", $result->{waterDescription}, $result->{waterStatus})); + } + } +} + +1; diff --git a/centreon-plugins/hardware/sensors/akcp/snmp/mode/sensors.pm b/centreon-plugins/hardware/sensors/akcp/snmp/mode/sensors.pm index c1686a883..e92391a70 100644 --- a/centreon-plugins/hardware/sensors/akcp/snmp/mode/sensors.pm +++ b/centreon-plugins/hardware/sensors/akcp/snmp/mode/sensors.pm @@ -28,7 +28,7 @@ use warnings; sub set_system { my ($self, %options) = @_; - $self->{regexp_threshold_overload_check_section_option} = '^(temperature|humidity|switch|serial)$'; + $self->{regexp_threshold_overload_check_section_option} = '^(temperature|humidity|switch|serial|water)$'; $self->{regexp_threshold_numeric_check_section_option} = '^(temperature|humidity)$'; $self->{cb_hook2} = 'snmp_execute'; @@ -42,6 +42,8 @@ sub set_system { ['lowWarning', 'WARNING'], ['lowCritical', 'CRITICAL'], ['sensorError', 'CRITICAL'], + ['relayOn', 'OK'], + ['relayOff', 'OK'], ], default2 => [ ['noStatus', 'OK'], @@ -52,7 +54,7 @@ sub set_system { }; $self->{components_path} = 'hardware::sensors::akcp::snmp::mode::components'; - $self->{components_module} = ['temperature', 'humidity', 'switch', 'serial']; + $self->{components_module} = ['temperature', 'humidity', 'switch', 'serial', 'water']; } sub snmp_execute { @@ -88,7 +90,7 @@ Check sensors. =item B<--component> Which component to check (Default: '.*'). -Can be: 'temperature', 'humidity', 'switch', 'serial'. +Can be: 'temperature', 'humidity', 'switch', 'serial', 'water'. =item B<--filter> @@ -118,4 +120,4 @@ Example: --warning='temperature,.*,50' =back -=cut \ No newline at end of file +=cut diff --git a/centreon-plugins/hardware/sensors/comet/p8000/snmp/mode/sensors.pm b/centreon-plugins/hardware/sensors/comet/p8000/snmp/mode/sensors.pm new file mode 100644 index 000000000..4879450f1 --- /dev/null +++ b/centreon-plugins/hardware/sensors/comet/p8000/snmp/mode/sensors.pm @@ -0,0 +1,197 @@ +# +# Copyright 2017 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::sensors::comet::p8000::snmp::mode::sensors; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; + +my $instance_mode; + +sub custom_temperature_perfdata { + my ($self, %options) = @_; + + my ($extra_label, $unit) = ('', 'C'); + if (!defined($options{extra_instance}) || $options{extra_instance} != 0) { + $extra_label .= '_' . $self->{result_values}->{display_absolute}; + } + $self->{output}->perfdata_add( + label => $self->{label} . $extra_label, unit => $unit, + value => $self->{result_values}->{$self->{label} . '_absolute'}, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{label} . '_' . $self->{result_values}->{display_absolute}), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{label} . '_' . $self->{result_values}->{display_absolute}), + ); +} + +sub custom_humidity_perfdata { + my ($self, %options) = @_; + + my ($extra_label, $unit) = ('', '%'); + if (!defined($options{extra_instance}) || $options{extra_instance} != 0) { + $extra_label .= '_' . $self->{result_values}->{display_absolute}; + } + $self->{output}->perfdata_add( + label => $self->{label} . $extra_label, unit => $unit, + value => $self->{result_values}->{$self->{label} . '_absolute'}, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{label} . '_' . $self->{result_values}->{display_absolute}), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{label} . '_' . $self->{result_values}->{display_absolute}), + min => 0, max => 100, + ); +} + +sub custom_sensor_threshold { + my ($self, %options) = @_; + + my $warn_limit; + if (defined($instance_mode->{option_results}->{'warning-' . $self->{label}}) && $instance_mode->{option_results}->{'warning-' . $self->{label}} ne '') { + $warn_limit = $instance_mode->{option_results}->{'warning-' . $self->{label}}; + } + $self->{perfdata}->threshold_validate(label => 'warning-' . $self->{label} . '_' . $self->{result_values}->{display_absolute}, value => $warn_limit); + + my $crit_limit = $self->{result_values}->{limit_lo_absolute} . ':' . $self->{result_values}->{limit_hi_absolute}; + if (defined($instance_mode->{option_results}->{'critical-' . $self->{label}}) && $instance_mode->{option_results}->{'critical-' . $self->{label}} ne '') { + $crit_limit = $instance_mode->{option_results}->{'critical-' . $self->{label}}; + } + $self->{perfdata}->threshold_validate(label => 'critical-' . $self->{label} . '_' . $self->{result_values}->{display_absolute}, value => $crit_limit); + + my $exit = $self->{perfdata}->threshold_check(value => $self->{result_values}->{$self->{label} . '_absolute'}, + threshold => [ { label => 'critical-' . $self->{label} . '_' . $self->{result_values}->{display_absolute}, exit_litteral => 'critical' }, + { label => 'warning-' . $self->{label} . '_' . $self->{result_values}->{display_absolute}, exit_litteral => 'warning' } ]); + return $exit; +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'channel', type => 1, cb_prefix_output => 'prefix_channel_output', message_multiple => 'All channels are ok', skipped_code => { -10 => 1 } }, + ]; + + $self->{maps_counters}->{channel} = [ + { label => 'temperature', set => { + key_values => [ { name => 'temperature' }, { name => 'limit_hi' }, { name => 'limit_lo' }, { name => 'display' } ], + output_template => 'Temperature: %.2f C', + closure_custom_perfdata => $self->can('custom_temperature_perfdata'), + closure_custom_threshold_check => $self->can('custom_sensor_threshold'), + } + }, + { label => 'humidity', set => { + key_values => [ { name => 'humidity' }, { name => 'limit_hi' }, { name => 'limit_lo' }, { name => 'display' } ], + output_template => 'Humidity: %.2f %%', + closure_custom_perfdata => $self->can('custom_humidity_perfdata'), + closure_custom_threshold_check => $self->can('custom_sensor_threshold'), + } + }, + ]; +} + +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 => + { + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::check_options(%options); + + $instance_mode = $self; +} + +sub prefix_channel_output { + my ($self, %options) = @_; + + return "Channel '" . $options{instance_value}->{display} . "' "; +} + +sub manage_selection { + my ($self, %options) = @_; + + my $oid_channels = '.1.3.6.1.4.1.22626.1.5.2'; + my $chName_suffix = '1.0'; + my $chVal_suffix = '2.0'; + my $chLimHi_suffix = '5.0'; + my $chLimLo_suffix = '6.0'; + my $chUnit_suffix = '9.0'; + + my $snmp_result = $options{snmp}->get_table(oid => $oid_channels, nothing_quit => 1); + $self->{channel} = {}; + for my $channel ((1, 2, 3, 4)) { + next if (!defined($snmp_result->{$oid_channels . '.' . $channel . '.' . $chName_suffix})); + + my $value = $snmp_result->{$oid_channels . '.' . $channel . '.' . $chVal_suffix}; + # sensor not configured (n/a) + next if ($value !~ /[0-9\.]/); + + my $name = $snmp_result->{$oid_channels . '.' . $channel . '.' . $chName_suffix}; + my $unit = $snmp_result->{$oid_channels . '.' . $channel . '.' . $chUnit_suffix}; + my $limit_hi = $snmp_result->{$oid_channels . '.' . $channel . '.' . $chLimHi_suffix}; + my $limit_lo = $snmp_result->{$oid_channels . '.' . $channel . '.' . $chLimLo_suffix}; + + $limit_hi /= 10; + $limit_lo /= 10; + if ($unit =~ /F/i) { + $value = sprintf("%.2f", ($value - 32) / 1.8); + $limit_hi = sprintf("%.2f", ($limit_hi - 32) / 1.8); + $limit_lo = sprintf("%.2f", ($limit_lo - 32) / 1.8); + } + + $self->{channel}->{$channel} = { + display => $name, + humidity => ($unit =~ /RH/) ? $value : undef, + temperature => ($unit =~ /F|C/) ? $value : undef, + limit_hi => $limit_hi, + limit_lo => $limit_lo, + }; + } +} + +1; + +__END__ + +=head1 MODE + +Check environment channels. + +=over 8 + +=item B<--warning-*> + +Threshold warning. +Can be: 'temperature', 'humidity'. + +=item B<--critical-*> + +Threshold critical. +Can be: 'temperature', 'humidity'. + +=back + +=cut diff --git a/centreon-plugins/hardware/sensors/comet/p8000/snmp/plugin.pm b/centreon-plugins/hardware/sensors/comet/p8000/snmp/plugin.pm new file mode 100644 index 000000000..a08e2f11c --- /dev/null +++ b/centreon-plugins/hardware/sensors/comet/p8000/snmp/plugin.pm @@ -0,0 +1,48 @@ +# +# Copyright 2017 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::sensors::comet::p8000::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} = '0.1'; + %{$self->{modes}} = ( + 'sensors' => 'hardware::sensors::comet::p8000::snmp::mode::sensors', + ); + + return $self; +} + +1; + +__END__ + +=head1 PLUGIN DESCRITPION + +Check Comet P8000 (P8510, P8511, P8541, P8610, P8611, p8631, P8641, P8552, P8652) sensors in SNMP. + +=cut diff --git a/centreon-plugins/hardware/sensors/hwgste/snmp/plugin.pm b/centreon-plugins/hardware/sensors/hwgste/snmp/plugin.pm index 150a42b0a..a51e73c84 100644 --- a/centreon-plugins/hardware/sensors/hwgste/snmp/plugin.pm +++ b/centreon-plugins/hardware/sensors/hwgste/snmp/plugin.pm @@ -16,8 +16,8 @@ # 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::sensors::hwgste::snmp::plugin; use strict; diff --git a/centreon-plugins/hardware/server/ibm/mgmt_cards/imm/snmp/mode/components/fan.pm b/centreon-plugins/hardware/server/ibm/mgmt_cards/imm/snmp/mode/components/fan.pm index f6e6ca03d..8f306419d 100644 --- a/centreon-plugins/hardware/server/ibm/mgmt_cards/imm/snmp/mode/components/fan.pm +++ b/centreon-plugins/hardware/server/ibm/mgmt_cards/imm/snmp/mode/components/fan.pm @@ -24,40 +24,59 @@ use strict; use warnings; use centreon::plugins::misc; +my $mapping = { + fanDescr => { oid => '.1.3.6.1.4.1.2.3.51.3.1.3.2.1.2' }, + fanSpeed => { oid => '.1.3.6.1.4.1.2.3.51.3.1.3.2.1.3' }, +}; +my $oid_fanEntry = '.1.3.6.1.4.1.2.3.51.3.1.3.2.1'; + +sub load { + my ($self) = @_; + + push @{$self->{request}}, { oid => $oid_fanEntry }; +} + sub check { my ($self) = @_; - $self->{components}->{fans} = {name => 'fans', total => 0}; $self->{output}->output_add(long_msg => "Checking fans"); - return if ($self->check_exclude('fans')); + $self->{components}->{fan} = {name => 'fans', total => 0, skip => 0}; + return if ($self->check_filter(section => 'fan')); - my $oid_fanEntry = '.1.3.6.1.4.1.2.3.51.3.1.3.2.1'; - my $oid_fanDescr = '.1.3.6.1.4.1.2.3.51.3.1.3.2.1.2'; - my $oid_fanSpeed = '.1.3.6.1.4.1.2.3.51.3.1.3.2.1.3'; - - my $result = $self->{snmp}->get_table(oid => $oid_fanEntry); - return if (scalar(keys %$result) <= 0); - - foreach my $key ($self->{snmp}->oid_lex_sort(keys %$result)) { - next if ($key !~ /^$oid_fanDescr\.(\d+)$/); + foreach my $oid ($self->{snmp}->oid_lex_sort(keys %{$self->{results}->{$oid_fanEntry}})) { + next if ($oid !~ /^$mapping->{fanSpeed}->{oid}\.(.*)$/); my $instance = $1; - - my $fan_descr = centreon::plugins::misc::trim($result->{$oid_fanDescr . '.' . $instance}); - my $fan_speed = centreon::plugins::misc::trim($result->{$oid_fanSpeed . '.' . $instance}); + my $result = $self->{snmp}->map_instance(mapping => $mapping, results => $self->{results}->{$oid_fanEntry}, instance => $instance); + $result->{fanDescr} = centreon::plugins::misc::trim($result->{fanDescr}); + $result->{fanSpeed} = centreon::plugins::misc::trim($result->{fanSpeed}); + + next if ($self->check_filter(section => 'fan', instance => $instance)); - $self->{components}->{fans}->{total}++; - $self->{output}->output_add(long_msg => sprintf("Fan '%s' speed is %s.", - $fan_descr, $fan_speed)); - if ($fan_speed =~ /offline/i) { - $self->{output}->output_add(severity => 'WARNING', - short_msg => sprintf("Fan '%s' is offline", $fan_descr)); - } else { - $fan_speed =~ /(\d+)/; - $self->{output}->perfdata_add(label => 'fan_' . $fan_descr, unit => '%', - value => $1, - min => 0, max => 100); + $self->{components}->{fan}->{total}++; + $self->{output}->output_add(long_msg => sprintf("Fan '%s' speed is '%s' [instance = %s]", + $result->{fanDescr}, $result->{fanSpeed}, $instance)); + if ($result->{fanSpeed} =~ /offline/i) { + my $exit = $self->get_severity(section => 'fan', value => $result->{fanSpeed}); + if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { + $self->{output}->output_add(severity => $exit, + short_msg => sprintf("Fan '%s' is offline", $result->{fanDescr})); + } } + + next if ($result->{fanSpeed} !~ /(\d+)/); + + my $fan_speed = $1; + my ($exit, $warn, $crit, $checked) = $self->get_severity_numeric(section => 'fan', instance => $instance, value => $fan_speed); + if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { + $self->{output}->output_add(severity => $exit, + short_msg => sprintf("Fan '%s' is '%s' %%", $result->{fanDescr}, $fan_speed)); + } + $self->{output}->perfdata_add(label => 'fan_' . $result->{fanDescr}, unit => '%', + value => $fan_speed, + warning => $warn, + critical => $crit, min => 0, max => 100 + ); } } -1; \ No newline at end of file +1; diff --git a/centreon-plugins/hardware/server/ibm/mgmt_cards/imm/snmp/mode/components/global.pm b/centreon-plugins/hardware/server/ibm/mgmt_cards/imm/snmp/mode/components/global.pm new file mode 100644 index 000000000..46e607410 --- /dev/null +++ b/centreon-plugins/hardware/server/ibm/mgmt_cards/imm/snmp/mode/components/global.pm @@ -0,0 +1,67 @@ +# +# Copyright 2017 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::mgmt_cards::imm::snmp::mode::components::global; + +use base qw(centreon::plugins::mode); + +use strict; +use warnings; + +my %map_global_status = ( + 0 => 'non recoverable', + 2 => 'critical', + 4 => 'non critical', + 255 => 'nominal', +); + +my $mapping = { + systemHealthStat => { oid => '.1.3.6.1.4.1.2.3.51.3.1.4.1', map => \%map_global_status }, +}; + +sub load { + my ($self) = @_; + + push @{$self->{request}}, { oid => $mapping->{systemHealthStat}->{oid} }; +} + +sub check { + my ($self) = @_; + + $self->{output}->output_add(long_msg => "Checking system health"); + $self->{components}->{global} = {name => 'system health', total => 0, skip => 0}; + return if ($self->check_filter(section => 'global')); + + return if (!defined($self->{results}->{$mapping->{systemHealthStat}->{oid}}) || scalar(keys %{$self->{results}->{$mapping->{systemHealthStat}->{oid}}}) <= 0); + + my $result = $self->{snmp}->map_instance(mapping => $mapping, results => $self->{results}->{$mapping->{systemHealthStat}->{oid}}, instance => '0'); + $self->{components}->{global}->{total}++; + + $self->{output}->output_add(long_msg => sprintf("system health status is '%s'", + $result->{systemHealthStat})); + my $exit = $self->get_severity(section => 'global', value => $result->{systemHealthStat}); + if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { + $self->{output}->output_add(severity => $exit, + short_msg => sprintf("System health status is '%s'.", + $result->{systemHealthStat})); + } +} + +1; diff --git a/centreon-plugins/hardware/server/ibm/mgmt_cards/imm/snmp/mode/components/globalstatus.pm b/centreon-plugins/hardware/server/ibm/mgmt_cards/imm/snmp/mode/components/globalstatus.pm deleted file mode 100644 index 6abed82cc..000000000 --- a/centreon-plugins/hardware/server/ibm/mgmt_cards/imm/snmp/mode/components/globalstatus.pm +++ /dev/null @@ -1,51 +0,0 @@ -# -# Copyright 2017 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::mgmt_cards::imm::snmp::mode::components::globalstatus; - -use base qw(centreon::plugins::mode); - -use strict; -use warnings; - -my %states = ( - 0 => ['non recoverable', 'CRITICAL'], - 2 => ['critical', 'CRITICAL'], - 4 => ['non critical', 'WARNING'], - 255 => ['nominal', 'OK'], -); - -sub check { - my ($self) = @_; - - my $oid_systemHealthStat = '.1.3.6.1.4.1.2.3.51.3.1.4.1.0'; - my $result = $self->{snmp}->get_leef(oids => [$oid_systemHealthStat], nothing_quit => 1); - - $self->{components}->{global} = {name => 'system health', total => 1}; - $self->{output}->output_add(long_msg => sprintf("System health status is '%s'.", - ${$states{$result->{$oid_systemHealthStat}}}[0])); - if (${$states{$result->{$oid_systemHealthStat}}}[1] ne 'OK') { - $self->{output}->output_add(severity => ${$states{$result->{$oid_systemHealthStat}}}[1], - short_msg => sprintf("System health status is '%s'.", - ${$states{$result->{$oid_systemHealthStat}}}[0])); - } -} - -1; \ No newline at end of file diff --git a/centreon-plugins/hardware/server/ibm/mgmt_cards/imm/snmp/mode/components/temperature.pm b/centreon-plugins/hardware/server/ibm/mgmt_cards/imm/snmp/mode/components/temperature.pm index 410cd3c0c..b632d4e3b 100644 --- a/centreon-plugins/hardware/server/ibm/mgmt_cards/imm/snmp/mode/components/temperature.pm +++ b/centreon-plugins/hardware/server/ibm/mgmt_cards/imm/snmp/mode/components/temperature.pm @@ -24,59 +24,66 @@ use strict; use warnings; use centreon::plugins::misc; +my $mapping = { + tempDescr => { oid => '.1.3.6.1.4.1.2.3.51.3.1.1.2.1.2' }, + tempReading => { oid => '.1.3.6.1.4.1.2.3.51.3.1.1.2.1.3' }, + tempCritLimitHigh => { oid => '.1.3.6.1.4.1.2.3.51.3.1.1.2.1.6' }, + tempNonCritLimitHigh => { oid => '.1.3.6.1.4.1.2.3.51.3.1.1.2.1.7' }, + tempCritLimitLow => { oid => '.1.3.6.1.4.1.2.3.51.3.1.1.2.1.9' }, + tempNonCritLimitLow => { oid => '.1.3.6.1.4.1.2.3.51.3.1.1.2.1.10' }, +}; +my $oid_tempEntry = '.1.3.6.1.4.1.2.3.51.3.1.1.2.1'; + +sub load { + my ($self) = @_; + + push @{$self->{request}}, { oid => $oid_tempEntry }; +} + sub check { my ($self) = @_; - $self->{components}->{temperatures} = {name => 'temperatures', total => 0}; $self->{output}->output_add(long_msg => "Checking temperatures"); - return if ($self->check_exclude('temperatures')); + $self->{components}->{temperature} = {name => 'temperatures', total => 0, skip => 0}; + return if ($self->check_filter(section => 'temperature')); - my $oid_tempEntry = '.1.3.6.1.4.1.2.3.51.3.1.1.2.1'; - my $oid_tempDescr = '.1.3.6.1.4.1.2.3.51.3.1.1.2.1.2'; - my $oid_tempReading = '.1.3.6.1.4.1.2.3.51.3.1.1.2.1.3'; - my $oid_tempCritLimitHigh = '.1.3.6.1.4.1.2.3.51.3.1.1.2.1.6'; - my $oid_tempNonCritLimitHigh = '.1.3.6.1.4.1.2.3.51.3.1.1.2.1.7'; - my $oid_tempCritLimitLow = '.1.3.6.1.4.1.2.3.51.3.1.1.2.1.9'; - my $oid_tempNonCritLimitLow = '.1.3.6.1.4.1.2.3.51.3.1.1.2.1.10'; - - my $result = $self->{snmp}->get_table(oid => $oid_tempEntry); - return if (scalar(keys %$result) <= 0); - - foreach my $key ($self->{snmp}->oid_lex_sort(keys %$result)) { - next if ($key !~ /^$oid_tempDescr\.(\d+)$/); + foreach my $oid ($self->{snmp}->oid_lex_sort(keys %{$self->{results}->{$oid_tempEntry}})) { + next if ($oid !~ /^$mapping->{tempDescr}->{oid}\.(.*)$/); my $instance = $1; - - my $temp_descr = centreon::plugins::misc::trim($result->{$oid_tempDescr . '.' . $instance}); - my $temp_value = $result->{$oid_tempReading . '.' . $instance}; - my $temp_crit_high = $result->{$oid_tempCritLimitHigh . '.' . $instance}; - my $temp_warn_high = $result->{$oid_tempNonCritLimitHigh . '.' . $instance}; - my $temp_crit_low = $result->{$oid_tempCritLimitLow . '.' . $instance}; - my $temp_warn_low = $result->{$oid_tempNonCritLimitLow . '.' . $instance}; + my $result = $self->{snmp}->map_instance(mapping => $mapping, results => $self->{results}->{$oid_tempEntry}, instance => $instance); + + next if ($self->check_filter(section => 'temperature', instance => $instance)); + $result->{tempDescr} = centreon::plugins::misc::trim($result->{tempDescr}); + $self->{components}->{temperature}->{total}++; + + $self->{output}->output_add(long_msg => sprintf("temperature '%s' value is %s C [instance: %s].", + $result->{tempDescr}, $result->{tempReading}, $instance)); - my $warn_threshold = ''; - $warn_threshold = $temp_warn_low . ':' . $temp_warn_high; - my $crit_threshold = ''; - $crit_threshold = $temp_crit_low . ':' . $temp_crit_high; - - $self->{perfdata}->threshold_validate(label => 'warning_' . $instance, value => $warn_threshold); - $self->{perfdata}->threshold_validate(label => 'critical_' . $instance, value => $crit_threshold); - - my $exit = $self->{perfdata}->threshold_check(value => $temp_value, threshold => [ { label => 'critical_' . $instance, 'exit_litteral' => 'critical' }, { label => 'warning_' . $instance, exit_litteral => 'warning' } ]); - - $self->{components}->{temperatures}->{total}++; - $self->{output}->output_add(long_msg => sprintf("Temperature '%s' value is %s C.", - $temp_descr, $temp_value)); - if (!$self->{output}->is_status(litteral => 1, value => $exit, compare => 'ok')) { - $self->{output}->output_add(severity => $exit, - short_msg => sprintf("Temperature '%s' value is %s C", $temp_descr, $temp_value)); + if (defined($result->{tempReading})) { + my ($exit, $warn, $crit, $checked) = $self->get_severity_numeric(section => 'temperature', instance => $instance, value => $result->{tempReading}); + if ($checked == 0) { + my $warn_th = $result->{tempNonCritLimitLow} . ':' . $result->{tempNonCritLimitHigh}; + my $crit_th = $result->{tempCritLimitLow} . ':' . $result->{tempCritLimitHigh}; + $self->{perfdata}->threshold_validate(label => 'warning-temperature-instance-' . $instance, value => $warn_th); + $self->{perfdata}->threshold_validate(label => 'critical-temperature-instance-' . $instance, value => $crit_th); + $exit = $self->{perfdata}->threshold_check( + value => $result->{tempReading}, + threshold => [ { label => 'critical-temperature-instance-' . $instance, exit_litteral => 'critical' }, + { label => 'warning-temperature-instance-' . $instance, exit_litteral => 'warning' } ]); + + $warn = $self->{perfdata}->get_perfdata_for_output(label => 'warning-temperature-instance-' . $instance); + $crit = $self->{perfdata}->get_perfdata_for_output(label => 'critical-temperature-instance-' . $instance); + } + if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { + $self->{output}->output_add(severity => $exit, + short_msg => sprintf("Temperature '%s' is %s C", $result->{tempDescr}, $result->{tempReading})); + } + $self->{output}->perfdata_add(label => "temp_" . $result->{tempDescr}, unit => 'C', + value => $result->{tempReading}, + warning => $warn, + critical => $crit); } - - $self->{output}->perfdata_add(label => 'temp_' . $temp_descr, unit => 'C', - value => $temp_value, - warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning_' . $instance), - critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical_' . $instance), - ); } } -1; \ No newline at end of file +1; diff --git a/centreon-plugins/hardware/server/ibm/mgmt_cards/imm/snmp/mode/components/voltage.pm b/centreon-plugins/hardware/server/ibm/mgmt_cards/imm/snmp/mode/components/voltage.pm index accca707f..4c3fe85c8 100644 --- a/centreon-plugins/hardware/server/ibm/mgmt_cards/imm/snmp/mode/components/voltage.pm +++ b/centreon-plugins/hardware/server/ibm/mgmt_cards/imm/snmp/mode/components/voltage.pm @@ -24,61 +24,66 @@ use strict; use warnings; use centreon::plugins::misc; +my $mapping = { + voltDescr => { oid => '.1.3.6.1.4.1.2.3.51.3.1.2.2.1.2' }, + voltReading => { oid => '.1.3.6.1.4.1.2.3.51.3.1.2.2.1.3' }, + voltCritLimitHigh => { oid => '.1.3.6.1.4.1.2.3.51.3.1.2.2.1.6' }, + voltNonCritLimitHigh => { oid => '.1.3.6.1.4.1.2.3.51.3.1.2.2.1.7' }, + voltCritLimitLow => { oid => '.1.3.6.1.4.1.2.3.51.3.1.2.2.1.9' }, + voltNonCritLimitLow => { oid => '.1.3.6.1.4.1.2.3.51.3.1.2.2.1.10' }, +}; +my $oid_voltEntry = '.1.3.6.1.4.1.2.3.51.3.1.2.2.1'; + +sub load { + my ($self) = @_; + + push @{$self->{request}}, { oid => $oid_voltEntry }; +} + sub check { my ($self) = @_; - $self->{components}->{voltages} = {name => 'voltages', total => 0}; $self->{output}->output_add(long_msg => "Checking voltages"); - return if ($self->check_exclude('voltages')); + $self->{components}->{voltage} = {name => 'voltages', total => 0, skip => 0}; + return if ($self->check_filter(section => 'voltage')); - my $oid_voltEntry = '.1.3.6.1.4.1.2.3.51.3.1.2.2.1'; - my $oid_voltDescr = '.1.3.6.1.4.1.2.3.51.3.1.2.2.1.2'; - my $oid_voltReading = '.1.3.6.1.4.1.2.3.51.3.1.2.2.1.3'; - my $oid_voltCritLimitHigh = '.1.3.6.1.4.1.2.3.51.3.1.2.2.1.6'; - my $oid_voltNonCritLimitHigh = '.1.3.6.1.4.1.2.3.51.3.1.2.2.1.7'; - my $oid_voltCritLimitLow = '.1.3.6.1.4.1.2.3.51.3.1.2.2.1.9'; - my $oid_voltNonCritLimitLow = '.1.3.6.1.4.1.2.3.51.3.1.2.2.1.10'; - - my $result = $self->{snmp}->get_table(oid => $oid_voltEntry); - return if (scalar(keys %$result) <= 0); - - foreach my $key ($self->{snmp}->oid_lex_sort(keys %$result)) { - next if ($key !~ /^$oid_voltDescr\.(\d+)$/); + foreach my $oid ($self->{snmp}->oid_lex_sort(keys %{$self->{results}->{$oid_voltEntry}})) { + next if ($oid !~ /^$mapping->{voltDescr}->{oid}\.(.*)$/); my $instance = $1; - - my $volt_descr = centreon::plugins::misc::trim($result->{$oid_voltDescr . '.' . $instance}); - my $volt_value = $result->{$oid_voltReading . '.' . $instance}; - my $volt_crit_high = $result->{$oid_voltCritLimitHigh . '.' . $instance}; - my $volt_warn_high = $result->{$oid_voltNonCritLimitHigh . '.' . $instance}; - my $volt_crit_low = $result->{$oid_voltCritLimitLow . '.' . $instance}; - my $volt_warn_low = $result->{$oid_voltNonCritLimitLow . '.' . $instance}; + my $result = $self->{snmp}->map_instance(mapping => $mapping, results => $self->{results}->{$oid_voltEntry}, instance => $instance); + + next if ($self->check_filter(section => 'voltage', instance => $instance)); + $result->{voltDescr} = centreon::plugins::misc::trim($result->{voltDescr}); + $self->{components}->{voltage}->{total}++; + + $self->{output}->output_add(long_msg => sprintf("voltage '%s' value is %s [instance: %s].", + $result->{voltDescr}, $result->{voltReading}, $instance)); - my $warn_threshold = ''; - $warn_threshold = $volt_warn_low . ':' if ($volt_warn_low != 0); - $warn_threshold .= $volt_warn_high if ($volt_warn_high != 0); - my $crit_threshold = ''; - $crit_threshold = $volt_crit_low . ':' if ($volt_crit_low != 0); - $crit_threshold .= $volt_crit_high if ($volt_crit_high != 0); - - $self->{perfdata}->threshold_validate(label => 'warning_' . $instance, value => $warn_threshold); - $self->{perfdata}->threshold_validate(label => 'critical_' . $instance, value => $crit_threshold); - - my $exit = $self->{perfdata}->threshold_check(value => $volt_value, threshold => [ { label => 'critical_' . $instance, 'exit_litteral' => 'critical' }, { label => 'warning_' . $instance, exit_litteral => 'warning' } ]); - - $self->{components}->{temperatures}->{total}++; - $self->{output}->output_add(long_msg => sprintf("Voltage '%s' value is %s.", - $volt_descr, $volt_value)); - if (!$self->{output}->is_status(litteral => 1, value => $exit, compare => 'ok')) { - $self->{output}->output_add(severity => $exit, - short_msg => sprintf("Voltage '%s' value is %s", $volt_descr, $volt_value)); + if (defined($result->{voltReading})) { + my ($exit, $warn, $crit, $checked) = $self->get_severity_numeric(section => 'voltage', instance => $instance, value => $result->{voltReading}); + if ($checked == 0) { + my $warn_th = $result->{voltNonCritLimitLow} . ':' . ($result->{voltNonCritLimitHigh} > 0 ? $result->{voltNonCritLimitHigh} : ''); + my $crit_th = $result->{voltCritLimitLow} . ':' . ($result->{voltCritLimitHigh} > 0 ? $result->{voltCritLimitHigh} : ''); + $self->{perfdata}->threshold_validate(label => 'warning-voltage-instance-' . $instance, value => $warn_th); + $self->{perfdata}->threshold_validate(label => 'critical-voltage-instance-' . $instance, value => $crit_th); + $exit = $self->{perfdata}->threshold_check( + value => $result->{voltReading}, + threshold => [ { label => 'critical-voltage-instance-' . $instance, exit_litteral => 'critical' }, + { label => 'warning-voltage-instance-' . $instance, exit_litteral => 'warning' } ]); + + $warn = $self->{perfdata}->get_perfdata_for_output(label => 'warning-voltage-instance-' . $instance); + $crit = $self->{perfdata}->get_perfdata_for_output(label => 'critical-voltage-instance-' . $instance); + } + if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { + $self->{output}->output_add(severity => $exit, + short_msg => sprintf("Voltage '%s' is %s", $result->{voltDescr}, $result->{voltReading})); + } + $self->{output}->perfdata_add(label => "volt_" . $result->{voltDescr}, + value => $result->{voltReading}, + warning => $warn, + critical => $crit); } - - $self->{output}->perfdata_add(label => 'volt_' . $volt_descr, - value => $volt_value, - warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning_' . $instance), - critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical_' . $instance), - ); } } -1; \ No newline at end of file +1; diff --git a/centreon-plugins/hardware/server/ibm/mgmt_cards/imm/snmp/mode/environment.pm b/centreon-plugins/hardware/server/ibm/mgmt_cards/imm/snmp/mode/environment.pm index bd32acdf2..81e25d826 100644 --- a/centreon-plugins/hardware/server/ibm/mgmt_cards/imm/snmp/mode/environment.pm +++ b/centreon-plugins/hardware/server/ibm/mgmt_cards/imm/snmp/mode/environment.pm @@ -20,15 +20,42 @@ package hardware::server::ibm::mgmt_cards::imm::snmp::mode::environment; -use base qw(centreon::plugins::mode); +use base qw(centreon::plugins::templates::hardware); use strict; use warnings; -use hardware::server::ibm::mgmt_cards::imm::snmp::mode::components::globalstatus; -use hardware::server::ibm::mgmt_cards::imm::snmp::mode::components::temperature; -use hardware::server::ibm::mgmt_cards::imm::snmp::mode::components::voltage; -use hardware::server::ibm::mgmt_cards::imm::snmp::mode::components::fan; +sub set_system { + my ($self, %options) = @_; + + $self->{regexp_threshold_overload_check_section_option} = '^(global|temperature|voltage|fan)$'; + $self->{regexp_threshold_numeric_check_section_option} = '^(temperature|voltage|fan)$'; + + $self->{cb_hook2} = 'snmp_execute'; + + $self->{thresholds} = { + global => [ + ['non recoverable', 'CRITICAL'], + ['non critical', 'WARNING'], + ['critical', 'CRITICAL'], + ['nominal', 'OK'], + ], + fan => [ + ['offline', 'WARNING'], + ['.*', 'OK'], + ], + }; + + $self->{components_path} = 'hardware::server::ibm::mgmt_cards::imm::snmp::mode::components'; + $self->{components_module} = ['global', 'temperature', 'voltage', 'fan']; +} + +sub snmp_execute { + my ($self, %options) = @_; + + $self->{snmp} = $options{snmp}; + $self->{results} = $self->{snmp}->get_multiple_table(oids => $self->{request}); +} sub new { my ($class, %options) = @_; @@ -38,78 +65,11 @@ sub new { $self->{version} = '1.0'; $options{options}->add_options(arguments => { - "exclude:s" => { name => 'exclude' }, - "component:s" => { name => 'component', default => 'all' }, }); - $self->{components} = {}; + return $self; } -sub check_options { - my ($self, %options) = @_; - $self->SUPER::init(%options); -} - -sub global { - my ($self, %options) = @_; - - hardware::server::ibm::mgmt_cards::imm::snmp::mode::components::globalstatus::check($self); - hardware::server::ibm::mgmt_cards::imm::snmp::mode::components::temperature::check($self); - hardware::server::ibm::mgmt_cards::imm::snmp::mode::components::voltage::check($self); - hardware::server::ibm::mgmt_cards::imm::snmp::mode::components::fan::check($self); -} - -sub run { - my ($self, %options) = @_; - $self->{snmp} = $options{snmp}; - - if ($self->{option_results}->{component} eq 'all') { - $self->global(); - } elsif ($self->{option_results}->{component} eq 'globalstatus') { - hardware::server::ibm::mgmt_cards::imm::snmp::mode::components::globalstatus::check($self); - } elsif ($self->{option_results}->{component} eq 'temperature') { - hardware::server::ibm::mgmt_cards::imm::snmp::mode::components::temperature::check($self); - } elsif ($self->{option_results}->{component} eq 'voltage') { - hardware::server::ibm::mgmt_cards::imm::snmp::mode::components::voltage::check($self); - } elsif ($self->{option_results}->{component} eq 'fan') { - hardware::server::ibm::mgmt_cards::imm::snmp::mode::components::fan::check($self); - } else { - $self->{output}->add_option_msg(short_msg => "Wrong option. Cannot find component '" . $self->{option_results}->{component} . "'."); - $self->{output}->option_exit(); - } - - 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); - $total_components += $self->{components}->{$comp}->{total}; - $display_by_component .= $display_by_component_append . $self->{components}->{$comp}->{total} . ' ' . $self->{components}->{$comp}->{name}; - $display_by_component_append = ', '; - } - - $self->{output}->output_add(severity => 'OK', - short_msg => sprintf("All %s components [%s] are ok.", - $total_components, - $display_by_component - ) - ); - - $self->{output}->display(); - $self->{output}->exit(); -} - -sub check_exclude { - my ($self, $section) = @_; - - if (defined($self->{option_results}->{exclude}) && $self->{option_results}->{exclude} =~ /(^|\s|,)$section(\s|,|$)/) { - $self->{output}->output_add(long_msg => sprintf("Skipping $section section.")); - return 1; - } - return 0; -} - 1; __END__ @@ -122,14 +82,36 @@ Check sensors (Fans, Temperatures, Voltages). =item B<--component> -Which component to check (Default: 'all'). -Can be: 'globalstatus', 'fan', 'temperature', 'voltage'. +Which component to check (Default: '.*'). +Can be: 'global', 'fan', 'temperature', 'voltage'. -=item B<--exclude> +=item B<--filter> -Exclude some parts (comma seperated list) (Example: --exclude=temperatures,fans). +Exclude some parts (comma seperated list) (Example: --filter=fan --filter=temperature) +Can also exclude specific instance: --filter=fan,1 + +=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,OK,offline' + +=item B<--warning> + +Set warning threshold for 'temperature', 'fan', 'voltage' (syntax: type,regexp,threshold) +Example: --warning='temperature,.*,30' + +=item B<--critical> + +Set critical threshold for temperature', 'fan', 'voltage' (syntax: type,regexp,threshold) +Example: --critical='temperature,.*,40' =back =cut - \ No newline at end of file + diff --git a/centreon-plugins/hardware/ups/alpha/snmp/mode/alarms.pm b/centreon-plugins/hardware/ups/alpha/snmp/mode/alarms.pm new file mode 100644 index 000000000..2c2b3a611 --- /dev/null +++ b/centreon-plugins/hardware/ups/alpha/snmp/mode/alarms.pm @@ -0,0 +1,139 @@ +# +# Copyright 2017 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::ups::alpha::snmp::mode::alarms; + +use base qw(centreon::plugins::templates::hardware); + +use strict; +use warnings; + +sub set_system { + my ($self, %options) = @_; + + $self->{regexp_threshold_overload_check_section_option} = '^(alarm)$'; + + $self->{cb_hook2} = 'snmp_execute'; + + $self->{thresholds} = { + alarm => [ + ['on', 'CRITICAL'], + ['off', 'OK'], + ], + }; + + $self->{components_path} = 'hardware::ups::alpha::snmp::mode::components'; + $self->{components_module} = ['alarm']; +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options, no_absent => 1, no_performance => 1, no_load_components => 1); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => + { + }); + + return $self; +} + +sub snmp_execute { + my ($self, %options) = @_; + + $self->{snmp} = $options{snmp}; + $self->{results} = $self->{snmp}->get_multiple_table(oids => $self->{request}); +} + +1; + +=head1 MODE + +Check alarms. + +=over 8 + +=item B<--filter> + +Exclude some parts (comma seperated list) +Can also exclude specific instance: --filter="alarm,FAN Alarm" + +=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='alarm,FAN Alarm,OK,on' + +=back + +=cut + +package hardware::ups::alpha::snmp::mode::components::alarm; + +use strict; +use warnings; + +my %map_status = (0 => 'off', 1 => 'on'); + +my $mapping = { + upsAlarmDescr => { oid => '.1.3.6.1.4.1.7309.6.1.5.2.1.2' }, + upsAlarmStatus => { oid => '.1.3.6.1.4.1.7309.6.1.5.2.1.3', map => \%map_status }, +}; +my $oid_upsAlarmEntry = '.1.3.6.1.4.1.7309.6.1.5.2.1'; + +sub load { + my ($self) = @_; + + push @{$self->{request}}, { oid => $oid_upsAlarmEntry }; +} + +sub check { + my ($self) = @_; + + $self->{output}->output_add(long_msg => "Checking alarms"); + $self->{components}->{alarm} = {name => 'alarms', total => 0, skip => 0}; + return if ($self->check_filter(section => 'alarm')); + + my ($exit, $warn, $crit, $checked); + foreach my $oid ($self->{snmp}->oid_lex_sort(keys %{$self->{results}->{$oid_upsAlarmEntry}})) { + next if ($oid !~ /^$mapping->{upsAlarmStatus}->{oid}\.(.*)$/); + my $instance = $1; + my $result = $self->{snmp}->map_instance(mapping => $mapping, results => $self->{results}->{$oid_upsAlarmEntry}, instance => $instance); + + next if ($self->check_filter(section => 'alarm', instance => $instance)); + + $self->{components}->{alarm}->{total}++; + $self->{output}->output_add(long_msg => sprintf("alarm '%s' status is '%s' [instance = %s]", + $result->{upsAlarmDescr}, $result->{upsAlarmStatus}, $result->{upsAlarmDescr})); + $exit = $self->get_severity(section => 'alarm', value => $result->{upsAlarmStatus}); + if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { + $self->{output}->output_add(severity => $exit, + short_msg => sprintf("Alarm '%s' status is '%s'", $result->{upsAlarmDescr}, $result->{upsAlarmStatus})); + } + } +} + +1; diff --git a/centreon-plugins/hardware/ups/alpha/snmp/mode/batterystatus.pm b/centreon-plugins/hardware/ups/alpha/snmp/mode/batterystatus.pm new file mode 100644 index 000000000..f9bca7635 --- /dev/null +++ b/centreon-plugins/hardware/ups/alpha/snmp/mode/batterystatus.pm @@ -0,0 +1,227 @@ +# +# Copyright 2017 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::ups::alpha::snmp::mode::batterystatus; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; + +my $instance_mode; + +sub custom_threshold_output { + my ($self, %options) = @_; + my $status = 'ok'; + my $message; + + eval { + local $SIG{__WARN__} = sub { $message = $_[0]; }; + local $SIG{__DIE__} = sub { $message = $_[0]; }; + + if (defined($instance_mode->{option_results}->{critical_status}) && $instance_mode->{option_results}->{critical_status} ne '' && + eval "$instance_mode->{option_results}->{critical_status}") { + $status = 'critical'; + } elsif (defined($instance_mode->{option_results}->{warning_status}) && $instance_mode->{option_results}->{warning_status} ne '' && + eval "$instance_mode->{option_results}->{warning_status}") { + $status = 'warning'; + } elsif (defined($instance_mode->{option_results}->{unknown_status}) && $instance_mode->{option_results}->{unknown_status} ne '' && + eval "$instance_mode->{option_results}->{unknown_status}") { + $status = 'unknown'; + } + }; + if (defined($message)) { + $self->{output}->output_add(long_msg => 'filter status issue: ' . $message); + } + + return $status; +} + +sub custom_status_output { + my ($self, %options) = @_; + + my $msg = sprintf("Battery status is '%s'", $self->{result_values}->{status}); + return $msg; +} + +sub custom_status_calc { + my ($self, %options) = @_; + + $self->{result_values}->{status} = $options{new_datas}->{$self->{instance} . '_upsBatteryStatus'}; + return 0; +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'global', type => 0 }, + ]; + + $self->{maps_counters}->{global} = [ + { label => 'status', threshold => 0, set => { + key_values => [ { name => 'upsBatteryStatus' } ], + closure_custom_calc => $self->can('custom_status_calc'), + closure_custom_output => $self->can('custom_status_output'), + closure_custom_perfdata => sub { return 0; }, + closure_custom_threshold_check => $self->can('custom_threshold_output'), + } + }, + { label => 'load', set => { + key_values => [ { name => 'upsBatteryCapacity' } ], + output_template => 'Remaining capacity : %s %%', + perfdatas => [ + { label => 'load', value => 'upsBatteryCapacity_absolute', template => '%s', + min => 0, max => 100, unit => '%' }, + ], + } + }, + { label => 'current', set => { + key_values => [ { name => 'upsBatteryChargingCurrent' } ], + output_template => 'Current : %s A', + perfdatas => [ + { label => 'current', value => 'upsBatteryChargingCurrent_absolute', template => '%s', + min => 0, unit => 'A' }, + ], + } + }, + { label => 'voltage', set => { + key_values => [ { name => 'upsBatteryVoltage' } ], + output_template => 'Voltage : %s V', + perfdatas => [ + { label => 'voltage', value => 'upsBatteryVoltage_absolute', template => '%s', + unit => 'V' }, + ], + } + }, + { label => 'temperature', set => { + key_values => [ { name => 'upsBatteryTemperature' } ], + output_template => 'Temperature : %s C', + perfdatas => [ + { label => 'temperature', value => 'upsBatteryTemperature_absolute', template => '%s', + unit => 'C'}, + ], + } + }, + ]; +} + +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 => + { + "unknown-status:s" => { name => 'unknown_status', default => '%{status} =~ /unknown/i' }, + "warning-status:s" => { name => 'warning_status', default => '%{status} =~ /batteryLow/i' }, + "critical-status:s" => { name => 'critical_status', default => '%{status} =~ /batteryDepleted/i' }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::check_options(%options); + + $instance_mode = $self; + $self->change_macros(); +} + +sub change_macros { + my ($self, %options) = @_; + + foreach (('warning_status', 'critical_status', 'unknown_status')) { + if (defined($self->{option_results}->{$_})) { + $self->{option_results}->{$_} =~ s/%\{(.*?)\}/\$self->{result_values}->{$1}/g; + } + } +} + +my %map_battery_status = ( + 1 => 'unknown', 2 => 'batteryNormal', 3 => 'batteryLow', 4 => 'batteryDepleted', +); + +my $mapping = { + upsBatteryStatus => { oid => '.1.3.6.1.4.1.7309.6.1.2.1', map => \%map_battery_status }, + upsBatteryVoltage => { oid => '.1.3.6.1.4.1.7309.6.1.2.3' }, + upsBatteryChargingCurrent => { oid => '.1.3.6.1.4.1.7309.6.1.2.4' }, + upsBatteryCapacity => { oid => '.1.3.6.1.4.1.7309.6.1.2.5' }, + upsBatteryTemperature => { oid => '.1.3.6.1.4.1.7309.6.1.2.6' }, +}; +my $oid_upsBattery = '.1.3.6.1.4.1.7309.6.1.2'; + +sub manage_selection { + my ($self, %options) = @_; + + my $snmp_result = $options{snmp}->get_table(oid => $oid_upsBattery, + nothing_quit => 1); + + my $result = $options{snmp}->map_instance(mapping => $mapping, results => $snmp_result, instance => '0'); + $result->{upsBatteryVoltage} *= 0.1; + $result->{upsBatteryChargingCurrent} *= 0.1; + $self->{global} = { %$result }; +} + +1; + +__END__ + +=head1 MODE + +Check battery status. + +=over 8 + +=item B<--filter-counters> + +Only display some counters (regexp can be used). +Example: --filter-counters='^status|load$' + +=item B<--unknown-status> + +Set warning threshold for status (Default: '%{status} =~ /unknown/i'). +Can used special variables like: %{status} + +=item B<--warning-status> + +Set warning threshold for status (Default: '%{status} =~ /batteryLow/i'). +Can used special variables like: %{status} + +=item B<--critical-status> + +Set critical threshold for status (Default: '%{status} =~ /batteryDepleted/i'). +Can used special variables like: %{status} + +=item B<--warning-*> + +Threshold warning. +Can be: 'load', 'voltage', 'current', 'temperature'. + +=item B<--critical-*> + +Threshold critical. +Can be: 'load', 'voltage', 'current', 'temperature'. + +=back + +=cut diff --git a/centreon-plugins/hardware/ups/alpha/snmp/plugin.pm b/centreon-plugins/hardware/ups/alpha/snmp/plugin.pm new file mode 100644 index 000000000..e19ef0174 --- /dev/null +++ b/centreon-plugins/hardware/ups/alpha/snmp/plugin.pm @@ -0,0 +1,47 @@ +# +# 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::ups::alpha::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} = '0.1'; + %{$self->{modes}} = ( + 'battery-status' => 'hardware::ups::alpha::snmp::mode::batterystatus', + 'alarms' => 'hardware::ups::alpha::snmp::mode::alarms', + ); + + return $self; +} + +1; + +__END__ + +=head1 PLUGIN DESCRIPTION + +Check UPS Alpha through SNMP. + +=cut diff --git a/centreon-plugins/hardware/ups/powerware/snmp/mode/batterystatus.pm b/centreon-plugins/hardware/ups/powerware/snmp/mode/batterystatus.pm index 30ec2b627..6dad01e53 100644 --- a/centreon-plugins/hardware/ups/powerware/snmp/mode/batterystatus.pm +++ b/centreon-plugins/hardware/ups/powerware/snmp/mode/batterystatus.pm @@ -28,7 +28,7 @@ use warnings; my %battery_status = ( 1 => ['batteryCharging', 'OK'], 2 => ['batteryDischarging', 'WARNING'], - 3 => ['batteryFloating', 'WARNING'], + 3 => ['batteryFloating', 'OK'], 4 => ['batteryResting', 'OK'], 5 => ['unknown', 'UNKNOWN'], ); diff --git a/centreon-plugins/network/arista/snmp/mode/memory.pm b/centreon-plugins/network/arista/snmp/mode/memory.pm new file mode 100644 index 000000000..786638057 --- /dev/null +++ b/centreon-plugins/network/arista/snmp/mode/memory.pm @@ -0,0 +1,98 @@ +# +# Copyright 2017 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::arista::snmp::mode::memory; + +use base qw(snmp_standard::mode::storage); + +use strict; +use warnings; + +sub default_storage_type { + my ($self, %options) = @_; + + return '^(hrStorageRam|hrStorageFlashMemory)'; +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + return $self; +} + +1; + +__END__ + +=head1 MODE + +Check memory. + +=over 8 + +=item B<--warning-usage> + +Threshold warning. + +=item B<--critical-usage> + +Threshold critical. + +=item B<--units> + +Units of thresholds (Default: '%') ('%', 'B'). + +=item B<--free> + +Thresholds are on free space left. + +=item B<--storage> + +Set the storage (number expected) ex: 1, 2,... (empty means 'check all storage'). + +=item B<--name> + +Allows to use storage name with option --storage instead of storage oid index. + +=item B<--regexp> + +Allows to use regexp to filter storage (with option --name). + +=item B<--regexp-isensitive> + +Allows to use regexp non case-sensitive (with --regexp). + +=item B<--reload-cache-time> + +Time in minutes before reloading cache file (default: 180). + +=item B<--show-cache> + +Display cache storage datas. + +=item B<--filter-storage-type> + +Filter storage types with a regexp (Default: '^(hrStorageRam|hrStorageFlashMemory)$'). + +=back + +=cut diff --git a/centreon-plugins/network/arista/snmp/plugin.pm b/centreon-plugins/network/arista/snmp/plugin.pm new file mode 100644 index 000000000..0f4ff1738 --- /dev/null +++ b/centreon-plugins/network/arista/snmp/plugin.pm @@ -0,0 +1,54 @@ +# +# Copyright 2017 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::arista::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' => 'snmp_standard::mode::cpu', + 'entity' => 'snmp_standard::mode::entity', + 'interfaces' => 'snmp_standard::mode::interfaces', + 'list-interfaces' => 'snmp_standard::mode::listinterfaces', + 'memory' => 'network::arista::snmp::mode::memory', + 'tcpcon' => 'snmp_standard::mode::tcpcon', + 'uptime' => 'snmp_standard::mode::uptime', + ); + + return $self; +} + +1; + +__END__ + +=head1 PLUGIN DESCRIPTION + +Check Arista equipments in SNMP. + +=cut diff --git a/centreon-plugins/network/cisco/callmanager/snmp/mode/ccmusage.pm b/centreon-plugins/network/cisco/callmanager/snmp/mode/ccmusage.pm new file mode 100644 index 000000000..99fadb87b --- /dev/null +++ b/centreon-plugins/network/cisco/callmanager/snmp/mode/ccmusage.pm @@ -0,0 +1,234 @@ +# +# Copyright 2017 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::cisco::callmanager::snmp::mode::ccmusage; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; + +my $instance_mode; + +sub custom_status_threshold { + my ($self, %options) = @_; + my $status = 'ok'; + my $message; + + eval { + local $SIG{__WARN__} = sub { $message = $_[0]; }; + local $SIG{__DIE__} = sub { $message = $_[0]; }; + + if (defined($instance_mode->{option_results}->{critical_status}) && $instance_mode->{option_results}->{critical_status} ne '' && + eval "$instance_mode->{option_results}->{critical_status}") { + $status = 'critical'; + } elsif (defined($instance_mode->{option_results}->{warning_status}) && $instance_mode->{option_results}->{warning_status} ne '' && + eval "$instance_mode->{option_results}->{warning_status}") { + $status = 'warning'; + } + }; + if (defined($message)) { + $self->{output}->output_add(long_msg => 'filter status issue: ' . $message); + } + + return $status; +} + +sub custom_status_output { + my ($self, %options) = @_; + + my $msg = 'status : ' . $self->{result_values}->{status}; + return $msg; +} + +sub custom_status_calc { + my ($self, %options) = @_; + + $self->{result_values}->{status} = $options{new_datas}->{$self->{instance} . '_ccmStatus'}; + $self->{result_values}->{display} = $options{new_datas}->{$self->{instance} . '_ccmName'}; + return 0; +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'global', type => 0 }, + { name => 'ccm', type => 1, cb_prefix_output => 'prefix_ccm_output', message_multiple => 'All CCM are ok' }, + ]; + + $self->{maps_counters}->{ccm} = [ + { label => 'status', threshold => 0, set => { + key_values => [ { name => 'ccmStatus' }, { name => 'ccmName' } ], + closure_custom_calc => $self->can('custom_status_calc'), + closure_custom_output => $self->can('custom_status_output'), + closure_custom_perfdata => sub { return 0; }, + closure_custom_threshold_check => $self->can('custom_status_threshold'), + } + }, + ]; + + my @map = ( + ['phones-registered', 'Phones Registered : %s', 'ccmRegisteredPhones'], + ['phones-unregistered', 'Phones Unregistered : %s', 'ccmUnregisteredPhones'], + ['phones-rejected', 'Phones Rejected : %s', 'ccmRejectedPhones'], + ['gateways-registered', 'Gateways Registered : %s', 'ccmRegisteredPhones'], + ['gateways-unregistered', 'Gateways Unregistered : %s', 'ccmUnregisteredGateways'], + ['gateways-rejected', 'Gateways Rejected : %s', 'ccmRejectedGateways'], + ['mediadevices-registered', 'Media Devices Registered : %s', 'ccmRegisteredMediaDevices'], + ['mediadevices-unregistered', 'Media Devices Unregistered : %s', 'ccmUnregisteredMediaDevices'], + ['mediadevices-rejected', 'Media Devices Rejected : %s', 'ccmRejectedMediaDevices'], + ); + + $self->{maps_counters}->{global} = []; + foreach (@map) { + my $label = $_->[0]; + $label =~ tr/-/_/; + push @{$self->{maps_counters}->{global}}, { label => $_->[0], set => { + key_values => [ { name => $_->[2] } ], + output_template => $_->[1], + perfdatas => [ + { label => $label, value => $_->[2] . '_absolute', template => '%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 => + { + "warning-status:s" => { name => 'warning_status', default => '' }, + "critical-status:s" => { name => 'critical_status', default => '%{status} !~ /up/' }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::check_options(%options); + + $instance_mode = $self; + $self->change_macros(); +} + +sub prefix_ccm_output { + my ($self, %options) = @_; + + return "CCM '" . $options{instance_value}->{ccmName} . "' "; +} + +sub change_macros { + my ($self, %options) = @_; + + foreach (('warning_status', 'critical_status')) { + if (defined($self->{option_results}->{$_})) { + $self->{option_results}->{$_} =~ s/%\{(.*?)\}/\$self->{result_values}->{$1}/g; + } + } +} + +my %mapping_status = (1 => 'unknown', 2 => 'up', 3 => 'down'); + +my $mapping = { + ccmRegisteredPhones => { oid => '.1.3.6.1.4.1.9.9.156.1.5.5' }, + ccmUnregisteredPhones => { oid => '.1.3.6.1.4.1.9.9.156.1.5.6' }, + ccmRejectedPhones => { oid => '.1.3.6.1.4.1.9.9.156.1.5.7' }, + ccmRegisteredGateways => { oid => '.1.3.6.1.4.1.9.9.156.1.5.8' }, + ccmUnregisteredGateways => { oid => '.1.3.6.1.4.1.9.9.156.1.5.9' }, + ccmRejectedGateways => { oid => '.1.3.6.1.4.1.9.9.156.1.5.10' }, + ccmRegisteredMediaDevices => { oid => '.1.3.6.1.4.1.9.9.156.1.5.11' }, + ccmUnregisteredMediaDevices => { oid => '.1.3.6.1.4.1.9.9.156.1.5.12' }, + ccmRejectedMediaDevices => { oid => '.1.3.6.1.4.1.9.9.156.1.5.13' }, +}; +my $mapping2 = { + ccmName => { oid => '.1.3.6.1.4.1.9.9.156.1.1.2.1.2' }, + ccmStatus => { oid => '.1.3.6.1.4.1.9.9.156.1.1.2.1.5', map => \%mapping_status }, +}; + +my $oid_ccmGlobalInfo = '.1.3.6.1.4.1.9.9.156.1.5'; +my $oid_ccmEntry = '.1.3.6.1.4.1.9.9.156.1.1.2.1'; + +sub manage_selection { + my ($self, %options) = @_; + + my $snmp_result = $options{snmp}->get_multiple_table(oids => [ + { oid => $oid_ccmGlobalInfo, end => $mapping->{ccmRejectedMediaDevices}->{oid} }, + { oid => $oid_ccmEntry, end => $mapping2->{ccmStatus}->{oid} }, + ], nothing_quit => 1); + my $result = $options{snmp}->map_instance(mapping => $mapping, results => $snmp_result->{$oid_ccmGlobalInfo}, instance => '0'); + $self->{global} = { %$result }; + + $self->{ccm} = {}; + foreach my $oid (keys %{$snmp_result->{$oid_ccmEntry}}) { + next if ($oid !~ /^$mapping2->{ccmStatus}->{oid}\.(.*)/); + my $instance = $1; + my $result = $options{snmp}->map_instance(mapping => $mapping2, results => $snmp_result->{$oid_ccmEntry}, instance => $instance); + + $self->{ccm}->{$instance} = { %$result }; + } +} + +1; + +__END__ + +=head1 MODE + +Check cisco call manager global usage. + +=over 8 + +=item B<--filter-counters> + +Only display some counters (regexp can be used). +Example: --filter-counters='phone' + +=item B<--warning-status> + +Set warning threshold for status (Default: ''). +Can used special variables like: %{status}, %{display} + +=item B<--critical-status> + +Set critical threshold for status (Default: '%{status} !~ /up/'). +Can used special variables like: %{status}, %{display} + +=item B<--warning-*> + +Threshold warning. + +=item B<--critical-*> + +Threshold critical. + +Can be: 'phones-registered', 'phones-unregistered', 'phones-rejected', +'gateways-registered', 'gateways-unregistered', 'gateways-rejected', +'mediadevices-registered', 'mediadevices-unregistered', 'mediadevices-rejected'. + +=back + +=cut diff --git a/centreon-plugins/network/cisco/callmanager/snmp/mode/gatewayusage.pm b/centreon-plugins/network/cisco/callmanager/snmp/mode/gatewayusage.pm new file mode 100644 index 000000000..57bf999a3 --- /dev/null +++ b/centreon-plugins/network/cisco/callmanager/snmp/mode/gatewayusage.pm @@ -0,0 +1,223 @@ +# +# Copyright 2017 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::cisco::callmanager::snmp::mode::gatewayusage; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; + +my $instance_mode; + +sub custom_status_threshold { + my ($self, %options) = @_; + my $status = 'ok'; + my $message; + + eval { + local $SIG{__WARN__} = sub { $message = $_[0]; }; + local $SIG{__DIE__} = sub { $message = $_[0]; }; + + if (defined($instance_mode->{option_results}->{critical_status}) && $instance_mode->{option_results}->{critical_status} ne '' && + eval "$instance_mode->{option_results}->{critical_status}") { + $status = 'critical'; + } elsif (defined($instance_mode->{option_results}->{warning_status}) && $instance_mode->{option_results}->{warning_status} ne '' && + eval "$instance_mode->{option_results}->{warning_status}") { + $status = 'warning'; + } + }; + if (defined($message)) { + $self->{output}->output_add(long_msg => 'filter status issue: ' . $message); + } + + return $status; +} + +sub custom_status_output { + my ($self, %options) = @_; + + my $msg = 'status : ' . $self->{result_values}->{status}; + return $msg; +} + +sub custom_status_calc { + my ($self, %options) = @_; + + $self->{result_values}->{status} = $options{new_datas}->{$self->{instance} . '_ccmGatewayStatus'}; + $self->{result_values}->{display} = $options{new_datas}->{$self->{instance} . '_ccmGatewayName'}; + return 0; +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'global', type => 0, cb_prefix_output => 'prefix_global_output' }, + { name => 'gateway', type => 1, cb_prefix_output => 'prefix_gateway_output', message_multiple => 'All gateways are ok' }, + ]; + + $self->{maps_counters}->{gateway} = [ + { label => 'status', threshold => 0, set => { + key_values => [ { name => 'ccmGatewayStatus' }, { name => 'ccmGatewayName' } ], + closure_custom_calc => $self->can('custom_status_calc'), + closure_custom_output => $self->can('custom_status_output'), + closure_custom_perfdata => sub { return 0; }, + closure_custom_threshold_check => $self->can('custom_status_threshold'), + } + }, + ]; + + my @map = ( + ['total-registered', 'Registered : %s', 'registered'], + ['total-unregistered', 'Unregistered : %s', 'unregistered'], + ['total-rejected', 'Rejected : %s', 'rejected'], + ['total-unknown', 'Unknown : %s', 'unknown'], + ['total-partiallyregistered', 'Partially Registered : %s', 'partiallyregistered'], + ); + + $self->{maps_counters}->{global} = []; + foreach (@map) { + my $label = $_->[0]; + $label =~ tr/-/_/; + push @{$self->{maps_counters}->{global}}, { label => $_->[0], set => { + key_values => [ { name => $_->[2] } ], + output_template => $_->[1], + perfdatas => [ + { label => $label, value => $_->[2] . '_absolute', template => '%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 => + { + "warning-status:s" => { name => 'warning_status', default => '' }, + "critical-status:s" => { name => 'critical_status', default => '%{status} !~ /^registered/' }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::check_options(%options); + + $instance_mode = $self; + $self->change_macros(); +} + +sub prefix_gateway_output { + my ($self, %options) = @_; + + return "Gateway '" . $options{instance_value}->{ccmGatewayName} . "' "; +} + +sub prefix_global_output { + my ($self, %options) = @_; + + return "Total "; +} + +sub change_macros { + my ($self, %options) = @_; + + foreach (('warning_status', 'critical_status')) { + if (defined($self->{option_results}->{$_})) { + $self->{option_results}->{$_} =~ s/%\{(.*?)\}/\$self->{result_values}->{$1}/g; + } + } +} + +my %mapping_status = ( + 1 => 'unknown', 2 => 'registered', 3 => 'unregistered', + 4 => 'rejected', 5 => 'partiallyregistered', +); + +my $mapping = { + ccmGatewayName => { oid => '.1.3.6.1.4.1.9.9.156.1.3.1.1.2' }, + ccmGatewayStatus => { oid => '.1.3.6.1.4.1.9.9.156.1.3.1.1.5', map => \%mapping_status }, +}; + +my $oid_ccmGatewayEntry = '.1.3.6.1.4.1.9.9.156.1.3.1.1'; + +sub manage_selection { + my ($self, %options) = @_; + + my $snmp_result = $options{snmp}->get_table(oid => $oid_ccmGatewayEntry, start => $mapping->{ccmGatewayName}->{oid}, end => $mapping->{ccmGatewayStatus}->{oid}, nothing_quit => 1); + + $self->{phone} = {}; + $self->{global} = { unknown => 0, registered => 0, unregistered => 0, rejected => 0, partiallyregistered => 0 }; + foreach my $oid (keys %$snmp_result) { + next if ($oid !~ /^$mapping->{ccmGatewayStatus}->{oid}\.(.*)/); + my $instance = $1; + my $result = $options{snmp}->map_instance(mapping => $mapping, results => $snmp_result, instance => $instance); + + $self->{phone}->{$instance} = { %$result }; + $self->{global}->{$result->{ccmGatewayStatus}}++; + } +} + +1; + +__END__ + +=head1 MODE + +Check gateway usage. + +=over 8 + +=item B<--filter-counters> + +Only display some counters (regexp can be used). +Example: --filter-counters='status' + +=item B<--warning-status> + +Set warning threshold for status (Default: ''). +Can used special variables like: %{status}, %{display} + +=item B<--critical-status> + +Set critical threshold for status (Default: '%{status} !~ /^registered/'). +Can used special variables like: %{status}, %{display} + +=item B<--warning-*> + +Threshold warning. + +=item B<--critical-*> + +Threshold critical. + +Can be: 'total-registered', 'total-unregistered', 'total-rejected', +'total-unknown', 'total-partiallyregistered'. + +=back + +=cut diff --git a/centreon-plugins/network/cisco/callmanager/snmp/mode/mediadeviceusage.pm b/centreon-plugins/network/cisco/callmanager/snmp/mode/mediadeviceusage.pm new file mode 100644 index 000000000..3409e5b9d --- /dev/null +++ b/centreon-plugins/network/cisco/callmanager/snmp/mode/mediadeviceusage.pm @@ -0,0 +1,223 @@ +# +# Copyright 2017 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::cisco::callmanager::snmp::mode::mediadeviceusage; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; + +my $instance_mode; + +sub custom_status_threshold { + my ($self, %options) = @_; + my $status = 'ok'; + my $message; + + eval { + local $SIG{__WARN__} = sub { $message = $_[0]; }; + local $SIG{__DIE__} = sub { $message = $_[0]; }; + + if (defined($instance_mode->{option_results}->{critical_status}) && $instance_mode->{option_results}->{critical_status} ne '' && + eval "$instance_mode->{option_results}->{critical_status}") { + $status = 'critical'; + } elsif (defined($instance_mode->{option_results}->{warning_status}) && $instance_mode->{option_results}->{warning_status} ne '' && + eval "$instance_mode->{option_results}->{warning_status}") { + $status = 'warning'; + } + }; + if (defined($message)) { + $self->{output}->output_add(long_msg => 'filter status issue: ' . $message); + } + + return $status; +} + +sub custom_status_output { + my ($self, %options) = @_; + + my $msg = 'status : ' . $self->{result_values}->{status}; + return $msg; +} + +sub custom_status_calc { + my ($self, %options) = @_; + + $self->{result_values}->{status} = $options{new_datas}->{$self->{instance} . '_ccmMediaDeviceStatus'}; + $self->{result_values}->{display} = $options{new_datas}->{$self->{instance} . '_ccmMediaDeviceName'}; + return 0; +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'global', type => 0, cb_prefix_output => 'prefix_global_output' }, + { name => 'md', type => 1, cb_prefix_output => 'prefix_md_output', message_multiple => 'All media devices are ok' }, + ]; + + $self->{maps_counters}->{md} = [ + { label => 'status', threshold => 0, set => { + key_values => [ { name => 'ccmMediaDeviceStatus' }, { name => 'ccmMediaDeviceName' } ], + closure_custom_calc => $self->can('custom_status_calc'), + closure_custom_output => $self->can('custom_status_output'), + closure_custom_perfdata => sub { return 0; }, + closure_custom_threshold_check => $self->can('custom_status_threshold'), + } + }, + ]; + + my @map = ( + ['total-registered', 'Registered : %s', 'registered'], + ['total-unregistered', 'Unregistered : %s', 'unregistered'], + ['total-rejected', 'Rejected : %s', 'rejected'], + ['total-unknown', 'Unknown : %s', 'unknown'], + ['total-partiallyregistered', 'Partially Registered : %s', 'partiallyregistered'], + ); + + $self->{maps_counters}->{global} = []; + foreach (@map) { + my $label = $_->[0]; + $label =~ tr/-/_/; + push @{$self->{maps_counters}->{global}}, { label => $_->[0], set => { + key_values => [ { name => $_->[2] } ], + output_template => $_->[1], + perfdatas => [ + { label => $label, value => $_->[2] . '_absolute', template => '%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 => + { + "warning-status:s" => { name => 'warning_status', default => '' }, + "critical-status:s" => { name => 'critical_status', default => '%{status} !~ /^registered/' }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::check_options(%options); + + $instance_mode = $self; + $self->change_macros(); +} + +sub prefix_md_output { + my ($self, %options) = @_; + + return "Media device '" . $options{instance_value}->{ccmMediaDeviceName} . "' "; +} + +sub prefix_global_output { + my ($self, %options) = @_; + + return "Total "; +} + +sub change_macros { + my ($self, %options) = @_; + + foreach (('warning_status', 'critical_status')) { + if (defined($self->{option_results}->{$_})) { + $self->{option_results}->{$_} =~ s/%\{(.*?)\}/\$self->{result_values}->{$1}/g; + } + } +} + +my %mapping_status = ( + 1 => 'unknown', 2 => 'registered', 3 => 'unregistered', + 4 => 'rejected', 5 => 'partiallyregistered', +); + +my $mapping = { + ccmMediaDeviceName => { oid => '.1.3.6.1.4.1.9.9.156.1.6.1.1.2' }, + ccmMediaDeviceStatus => { oid => '.1.3.6.1.4.1.9.9.156.1.6.1.1.5', map => \%mapping_status }, +}; + +my $oid_ccmMediaDeviceEntry = '.1.3.6.1.4.1.9.9.156.1.6.1.1'; + +sub manage_selection { + my ($self, %options) = @_; + + my $snmp_result = $options{snmp}->get_table(oid => $oid_ccmMediaDeviceEntry, start => $mapping->{ccmMediaDeviceName}->{oid}, end => $mapping->{ccmMediaDeviceStatus}->{oid}, nothing_quit => 1); + + $self->{md} = {}; + $self->{global} = { unknown => 0, registered => 0, unregistered => 0, rejected => 0, partiallyregistered => 0 }; + foreach my $oid (keys %$snmp_result) { + next if ($oid !~ /^$mapping->{ccmMediaDeviceStatus}->{oid}\.(.*)/); + my $instance = $1; + my $result = $options{snmp}->map_instance(mapping => $mapping, results => $snmp_result, instance => $instance); + + $self->{md}->{$instance} = { %$result }; + $self->{global}->{$result->{ccmMediaDeviceStatus}}++; + } +} + +1; + +__END__ + +=head1 MODE + +Check media device usage. + +=over 8 + +=item B<--filter-counters> + +Only display some counters (regexp can be used). +Example: --filter-counters='status' + +=item B<--warning-status> + +Set warning threshold for status (Default: ''). +Can used special variables like: %{status}, %{display} + +=item B<--critical-status> + +Set critical threshold for status (Default: '%{status} !~ /^registered/'). +Can used special variables like: %{status}, %{display} + +=item B<--warning-*> + +Threshold warning. + +=item B<--critical-*> + +Threshold critical. + +Can be: 'total-registered', 'total-unregistered', 'total-rejected', +'total-unknown', 'total-partiallyregistered'. + +=back + +=cut diff --git a/centreon-plugins/network/cisco/callmanager/snmp/mode/phoneusage.pm b/centreon-plugins/network/cisco/callmanager/snmp/mode/phoneusage.pm new file mode 100644 index 000000000..c72b51bf0 --- /dev/null +++ b/centreon-plugins/network/cisco/callmanager/snmp/mode/phoneusage.pm @@ -0,0 +1,223 @@ +# +# Copyright 2017 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::cisco::callmanager::snmp::mode::phoneusage; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; + +my $instance_mode; + +sub custom_status_threshold { + my ($self, %options) = @_; + my $status = 'ok'; + my $message; + + eval { + local $SIG{__WARN__} = sub { $message = $_[0]; }; + local $SIG{__DIE__} = sub { $message = $_[0]; }; + + if (defined($instance_mode->{option_results}->{critical_status}) && $instance_mode->{option_results}->{critical_status} ne '' && + eval "$instance_mode->{option_results}->{critical_status}") { + $status = 'critical'; + } elsif (defined($instance_mode->{option_results}->{warning_status}) && $instance_mode->{option_results}->{warning_status} ne '' && + eval "$instance_mode->{option_results}->{warning_status}") { + $status = 'warning'; + } + }; + if (defined($message)) { + $self->{output}->output_add(long_msg => 'filter status issue: ' . $message); + } + + return $status; +} + +sub custom_status_output { + my ($self, %options) = @_; + + my $msg = 'status : ' . $self->{result_values}->{status}; + return $msg; +} + +sub custom_status_calc { + my ($self, %options) = @_; + + $self->{result_values}->{status} = $options{new_datas}->{$self->{instance} . '_ccmPhoneStatus'}; + $self->{result_values}->{display} = $options{new_datas}->{$self->{instance} . '_ccmPhoneDescription'}; + return 0; +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'global', type => 0, cb_prefix_output => 'prefix_global_output' }, + { name => 'phone', type => 1, cb_prefix_output => 'prefix_phone_output', message_multiple => 'All phones are ok' }, + ]; + + $self->{maps_counters}->{phone} = [ + { label => 'status', threshold => 0, set => { + key_values => [ { name => 'ccmPhoneStatus' }, { name => 'ccmPhoneDescription' } ], + closure_custom_calc => $self->can('custom_status_calc'), + closure_custom_output => $self->can('custom_status_output'), + closure_custom_perfdata => sub { return 0; }, + closure_custom_threshold_check => $self->can('custom_status_threshold'), + } + }, + ]; + + my @map = ( + ['total-registered', 'Registered : %s', 'registered'], + ['total-unregistered', 'Unregistered : %s', 'unregistered'], + ['total-rejected', 'Rejected : %s', 'rejected'], + ['total-unknown', 'Unknown : %s', 'unknown'], + ['total-partiallyregistered', 'Partially Registered : %s', 'partiallyregistered'], + ); + + $self->{maps_counters}->{global} = []; + foreach (@map) { + my $label = $_->[0]; + $label =~ tr/-/_/; + push @{$self->{maps_counters}->{global}}, { label => $_->[0], set => { + key_values => [ { name => $_->[2] } ], + output_template => $_->[1], + perfdatas => [ + { label => $label, value => $_->[2] . '_absolute', template => '%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 => + { + "warning-status:s" => { name => 'warning_status', default => '' }, + "critical-status:s" => { name => 'critical_status', default => '%{status} !~ /^registered/' }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::check_options(%options); + + $instance_mode = $self; + $self->change_macros(); +} + +sub prefix_phone_output { + my ($self, %options) = @_; + + return "Phone '" . $options{instance_value}->{ccmPhoneDescription} . "' "; +} + +sub prefix_global_output { + my ($self, %options) = @_; + + return "Total "; +} + +sub change_macros { + my ($self, %options) = @_; + + foreach (('warning_status', 'critical_status')) { + if (defined($self->{option_results}->{$_})) { + $self->{option_results}->{$_} =~ s/%\{(.*?)\}/\$self->{result_values}->{$1}/g; + } + } +} + +my %mapping_status = ( + 1 => 'unknown', 2 => 'registered', 3 => 'unregistered', + 4 => 'rejected', 5 => 'partiallyregistered', +); + +my $mapping = { + ccmPhoneDescription => { oid => '.1.3.6.1.4.1.9.9.156.1.2.1.1.4' }, + ccmPhoneStatus => { oid => '.1.3.6.1.4.1.9.9.156.1.2.1.1.7', map => \%mapping_status }, +}; + +my $oid_ccmPhoneEntry = '.1.3.6.1.4.1.9.9.156.1.2.1.1'; + +sub manage_selection { + my ($self, %options) = @_; + + my $snmp_result = $options{snmp}->get_table(oid => $oid_ccmPhoneEntry, start => $mapping->{ccmPhoneDescription}->{oid}, end => $mapping->{ccmPhoneStatus}->{oid}, nothing_quit => 1); + + $self->{phone} = {}; + $self->{global} = { unknown => 0, registered => 0, unregistered => 0, rejected => 0, partiallyregistered => 0 }; + foreach my $oid (keys %$snmp_result) { + next if ($oid !~ /^$mapping->{ccmPhoneStatus}->{oid}\.(.*)/); + my $instance = $1; + my $result = $options{snmp}->map_instance(mapping => $mapping, results => $snmp_result, instance => $instance); + + $self->{phone}->{$instance} = { %$result }; + $self->{global}->{$result->{ccmPhoneStatus}}++; + } +} + +1; + +__END__ + +=head1 MODE + +Check phone usage. + +=over 8 + +=item B<--filter-counters> + +Only display some counters (regexp can be used). +Example: --filter-counters='status' + +=item B<--warning-status> + +Set warning threshold for status (Default: ''). +Can used special variables like: %{status}, %{display} + +=item B<--critical-status> + +Set critical threshold for status (Default: '%{status} !~ /^registered/'). +Can used special variables like: %{status}, %{display} + +=item B<--warning-*> + +Threshold warning. + +=item B<--critical-*> + +Threshold critical. + +Can be: 'total-registered', 'total-unregistered', 'total-rejected', +'total-unknown', 'total-partiallyregistered'. + +=back + +=cut diff --git a/centreon-plugins/network/cisco/callmanager/snmp/plugin.pm b/centreon-plugins/network/cisco/callmanager/snmp/plugin.pm new file mode 100644 index 000000000..2a943ae1d --- /dev/null +++ b/centreon-plugins/network/cisco/callmanager/snmp/plugin.pm @@ -0,0 +1,51 @@ +# +# Copyright 2017 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::cisco::callmanager::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}} = ( + 'ccm-usage' => 'network::cisco::callmanager::snmp::mode::ccmusage', + 'gateway-usage' => 'network::cisco::callmanager::snmp::mode::gatewayusage', + 'mediadevice-usage' => 'network::cisco::callmanager::snmp::mode::mediadeviceusage', + 'phone-usage' => 'network::cisco::callmanager::snmp::mode::phoneusage', + ); + + return $self; +} + +1; + +__END__ + +=head1 PLUGIN DESCRIPTION + +Check Cisco Call Manager (CCM) in SNMP. + +=cut diff --git a/centreon-plugins/network/cisco/standard/snmp/plugin.pm b/centreon-plugins/network/cisco/standard/snmp/plugin.pm index f44b873c1..fbc57a62f 100644 --- a/centreon-plugins/network/cisco/standard/snmp/plugin.pm +++ b/centreon-plugins/network/cisco/standard/snmp/plugin.pm @@ -42,6 +42,7 @@ sub new { 'qos-usage' => 'centreon::common::cisco::standard::snmp::mode::qosusage', 'spanning-tree' => 'snmp_standard::mode::spanningtree', 'stack' => 'centreon::common::cisco::standard::snmp::mode::stack', + 'uptime' => 'snmp_standard::mode::uptime', ); return $self; diff --git a/centreon-plugins/network/colubris/snmp/mode/apusage.pm b/centreon-plugins/network/colubris/snmp/mode/apusage.pm new file mode 100644 index 000000000..9ede7ddbb --- /dev/null +++ b/centreon-plugins/network/colubris/snmp/mode/apusage.pm @@ -0,0 +1,256 @@ +# +# Copyright 2017 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::colubris::snmp::mode::apusage; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; +use Digest::MD5 qw(md5_hex); + +my $instance_mode; + +sub custom_status_threshold { + my ($self, %options) = @_; + my $status = 'ok'; + my $message; + + eval { + local $SIG{__WARN__} = sub { $message = $_[0]; }; + local $SIG{__DIE__} = sub { $message = $_[0]; }; + + if (defined($instance_mode->{option_results}->{critical_ap_status}) && $instance_mode->{option_results}->{critical_ap_status} ne '' && + eval "$instance_mode->{option_results}->{critical_ap_status}") { + $status = 'critical'; + } elsif (defined($instance_mode->{option_results}->{warning_ap_status}) && $instance_mode->{option_results}->{warning_ap_status} ne '' && + eval "$instance_mode->{option_results}->{warning_ap_status}") { + $status = 'warning'; + } + }; + if (defined($message)) { + $self->{output}->output_add(long_msg => 'filter status issue: ' . $message); + } + + return $status; +} + +sub custom_status_output { + my ($self, %options) = @_; + + my $msg = 'Operational State : ' . $self->{result_values}->{state}; + return $msg; +} + +sub custom_status_calc { + my ($self, %options) = @_; + + $self->{result_values}->{state} = $options{new_datas}->{$self->{instance} . '_state'}; + $self->{result_values}->{display} = $options{new_datas}->{$self->{instance} . '_display'}; + return 0; +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'global', type => 0 }, + { name => 'ap', type => 1, cb_prefix_output => 'prefix_ap_output', message_multiple => 'All access points are OK' }, + ]; + + $self->{maps_counters}->{global} = [ + { label => 'total-ap', set => { + key_values => [ { name => 'total_ap' } ], + output_template => 'Total AP : %s', + perfdatas => [ + { label => 'total_ap', value => 'total_ap_absolute', template => '%s', min => 0 }, + ], + } + }, + { label => 'total-users', set => { + key_values => [ { name => 'total_users' } ], + output_template => 'Total Users : %s', + perfdatas => [ + { label => 'total_users', value => 'total_users_absolute', template => '%s', min => 0 }, + ], + } + }, + ]; + + $self->{maps_counters}->{ap} = [ + { label => 'ap-status', threshold => 0, set => { + key_values => [ { name => 'state' }, { name => 'display' } ], + closure_custom_calc => $self->can('custom_status_calc'), + closure_custom_output => $self->can('custom_status_output'), + closure_custom_perfdata => sub { return 0; }, + closure_custom_threshold_check => $self->can('custom_status_threshold'), + } + }, + { label => 'ap-users', set => { + key_values => [ { name => 'users' }, { name => 'display' } ], + output_template => 'Current Users: %s', + perfdatas => [ + { label => 'ap_users', value => 'users_absolute', template => '%s', + min => 0, label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + ]; +} + +sub prefix_ap_output { + my ($self, %options) = @_; + + return "AP '" . $options{instance_value}->{display} . "' "; +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options, statefile => 1); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => + { + "filter-name:s" => { name => 'filter_name' }, + "warning-ap-status:s" => { name => 'warning_ap_status', default => '' }, + "critical-ap-status:s" => { name => 'critical_ap_status', default => '%{state} eq "disconnected"' }, + }); + return $self; +} + +sub change_macros { + my ($self, %options) = @_; + + foreach (('warning_ap_status', 'critical_ap_status')) { + if (defined($self->{option_results}->{$_})) { + $self->{option_results}->{$_} =~ s/%\{(.*?)\}/\$self->{result_values}->{$1}/g; + } + } +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::check_options(%options); + + $self->change_macros(); + $instance_mode = $self; +} + +my %map_device_state = ( + 1 => 'disconnected', 2 => 'authorized', 3 => 'join', 4 => 'firmware', + 5 => 'security', 6 => 'configuration', 7 => 'running' +); + +my $mapping = { + coDevDisState => { oid => '.1.3.6.1.4.1.8744.5.23.1.2.1.1.5', map => \%map_device_state }, + coDevDisSystemName => { oid => '.1.3.6.1.4.1.8744.5.23.1.2.1.1.6' }, +}; + +my $mapping2 = { + coDevWirCliStaMACAddress => { oid => '.1.3.6.1.4.1.8744.5.25.1.7.1.1.2' }, +}; + +sub manage_selection { + my ($self, %options) = @_; + + $self->{cache_name} = "colubris_" . $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')) . '_' . + (defined($self->{option_results}->{filter_name}) ? md5_hex($self->{option_results}->{filter_name}) : md5_hex('all')); + + my $snmp_result = $options{snmp}->get_multiple_table(oids => [ + { oid => $mapping->{coDevDisState}->{oid} }, + { oid => $mapping->{coDevDisSystemName}->{oid} }, + { oid => $mapping2->{coDevWirCliStaMACAddress}->{oid} }, + ], nothing_quit => 1, return_type => 1); + + $self->{ap} = {}; + $self->{global} = { total_ap => 0, total_users => 0 }; + foreach my $oid (sort keys %{$snmp_result}) { + next if ($oid !~ /^$mapping->{coDevDisSystemName}->{oid}\.(.*)$/); + my $instance = $1; + my $result = $options{snmp}->map_instance(mapping => $mapping, results => $snmp_result, instance => $instance); + if (defined($self->{option_results}->{filter_name}) && $self->{option_results}->{filter_name} ne '' && + $result->{coDevDisSystemName} !~ /$self->{option_results}->{filter_name}/) { + $self->{output}->output_add(long_msg => "skipping '" . $result->{coDevDisSystemName} . "': no matching filter.", debug => 1); + next; + } + + $self->{global}->{total_ap}++; + $self->{ap}->{$instance} = { + display => $result->{coDevDisSystemName}, + state => $result->{coDevDisState}, + users => 0, + }; + } + + foreach my $oid (sort keys %{$snmp_result}) { + next if ($oid !~ /^$mapping2->{coDevWirCliStaMACAddress}->{oid}\.(.*?)\./); + my $instance = $1; + + next if (!defined($self->{ap}->{$instance})); + + $self->{global}->{total_users}++; + $self->{ap}->{$instance}->{users}++; + } + + if (scalar(keys %{$self->{ap}}) <= 0) { + $self->{output}->add_option_msg(short_msg => "No access point found."); + $self->{output}->option_exit(); + } +} + +1; + +__END__ + +=head1 MODE + +Check AP status and users connected. + +=over 8 + +=item B<--filter-name> + +Filter ap name with regexp. + +=item B<--warning-*> + +Threshold warning. +Can be: 'total-ap', 'total-users', 'ap-users'. + +=item B<--critical-*> + +Threshold critical. +Can be: 'total-ap', 'total-users', 'ap-users'. + +=item B<--warning-ap-status> + +Set warning threshold for status. +Can used special variables like: %{state}, %{display} + +=item B<--critical-ap-status> + +Set critical threshold for status (Default: '%{state} eq "disconnected"'). +Can used special variables like: %{state}, %{display} + +=back + +=cut diff --git a/centreon-plugins/network/colubris/snmp/mode/cpu.pm b/centreon-plugins/network/colubris/snmp/mode/cpu.pm new file mode 100644 index 000000000..d21f38f8f --- /dev/null +++ b/centreon-plugins/network/colubris/snmp/mode/cpu.pm @@ -0,0 +1,139 @@ +# +# Copyright 2017 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::colubris::snmp::mode::cpu; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'global', type => 0, cb_prefix_output => 'prefix_cpu_output' }, + ]; + + $self->{maps_counters}->{global} = [ + { label => 'current', set => { + key_values => [ { name => 'usage_now' } ], + output_template => '%.2f %% (current)', + perfdatas => [ + { label => 'cpu_current', value => 'usage_now_absolute', template => '%.2f', + unit => '%', min => 0, max => 100 }, + ], + } + }, + { label => '5s', set => { + key_values => [ { name => 'usage_5s' } ], + output_template => '%.2f %% (5sec)', + perfdatas => [ + { label => 'cpu_5s', value => 'usage_5s_absolute', template => '%.2f', + unit => '%', min => 0, max => 100 }, + ], + } + }, + { label => '10s', set => { + key_values => [ { name => 'usage_10s' } ], + output_template => '%.2f %% (10sec)', + perfdatas => [ + { label => 'cpu_10s', value => 'usage_10s_absolute', template => '%.2f', + unit => '%', min => 0, max => 100 }, + ], + } + }, + { label => '20s', set => { + key_values => [ { name => 'usage_20s' } ], + output_template => '%.2f %% (5sec)', + perfdatas => [ + { label => 'cpu_20s', value => 'usage_20s_absolute', template => '%.2f', + unit => '%', min => 0, max => 100 }, + ], + } + }, + ]; +} + +sub prefix_cpu_output { + my ($self, %options) = @_; + + return "CPU "; +} + +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 => + { + }); + + return $self; +} + +sub manage_selection { + my ($self, %options) = @_; + + my $oid_coUsInfoCpuUseNow = '.1.3.6.1.4.1.8744.5.21.1.1.5.0'; + my $oid_coUsInfoCpuUse5Sec = '.1.3.6.1.4.1.8744.5.21.1.1.6.0'; + my $oid_coUsInfoCpuUse10Sec = '.1.3.6.1.4.1.8744.5.21.1.1.7.0'; + my $oid_coUsInfoCpuUse20Sec = '.1.3.6.1.4.1.8744.5.21.1.1.8.0'; + my $snmp_result = $options{snmp}->get_leef(oids => [$oid_coUsInfoCpuUseNow, + $oid_coUsInfoCpuUse5Sec, $oid_coUsInfoCpuUse10Sec, $oid_coUsInfoCpuUse20Sec], nothing_quit => 1); + + $self->{global} = { + usage_now => $snmp_result->{$oid_coUsInfoCpuUseNow}, + usage_5s => $snmp_result->{$oid_coUsInfoCpuUse5Sec}, + usage_10s => $snmp_result->{$oid_coUsInfoCpuUse10Sec}, + usage_20s => $snmp_result->{$oid_coUsInfoCpuUse20Sec}, + }; +} + +1; + +__END__ + +=head1 MODE + +Check CPU usage. + +=over 8 + +=item B<--filter-counters> + +Only display some counters (regexp can be used). +Example: --filter-counters='20s' + +=item B<--warning-*> + +Threshold warning. +Can be: 'current', '5s', '10s', '20s'. + +=item B<--critical-*> + +Threshold critical. +Can be: 'current', '5s', '10s', '20s'. + +=back + +=cut diff --git a/centreon-plugins/network/colubris/snmp/mode/load.pm b/centreon-plugins/network/colubris/snmp/mode/load.pm new file mode 100644 index 000000000..7d75dd06f --- /dev/null +++ b/centreon-plugins/network/colubris/snmp/mode/load.pm @@ -0,0 +1,125 @@ +# +# Copyright 2017 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::colubris::snmp::mode::load; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'global', type => 0, cb_prefix_output => 'prefix_load_output' } + ]; + + $self->{maps_counters}->{global} = [ + { label => '1min', set => { + key_values => [ { name => 'load1' } ], + output_template => '%s', + perfdatas => [ + { label => 'load1', value => 'load1_absolute', template => '%s', min => 0 }, + ], + } + }, + { label => '5min', set => { + key_values => [ { name => 'load5' } ], + output_template => '%s', + perfdatas => [ + { label => 'load5', value => 'load5_absolute', template => '%s', min => 0 }, + ], + } + }, + { label => '1min', set => { + key_values => [ { name => 'load15' } ], + output_template => '%s', + perfdatas => [ + { label => 'load15', value => 'load15_absolute', template => '%s', min => 0 }, + ], + } + }, + ]; +} + +sub prefix_load_output { + my ($self, %options) = @_; + + return "Load average: "; +} + +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 => + { + }); + + return $self; +} + +sub manage_selection { + my ($self, %options) = @_; + + my $oid_coUsInfoLoadAverage1Min = '.1.3.6.1.4.1.8744.5.21.1.1.5.0'; + my $oid_coUsInfoLoadAverage5Min = '.1.3.6.1.4.1.8744.5.21.1.1.6.0'; + my $oid_coUsInfoLoadAverage15Min = '.1.3.6.1.4.1.8744.5.21.1.1.7.0'; + my $snmp_result = $options{snmp}->get_leef(oids => [$oid_coUsInfoLoadAverage1Min, + $oid_coUsInfoLoadAverage5Min, $oid_coUsInfoLoadAverage15Min], nothing_quit => 1); + + $self->{global} = { + load1 => $snmp_result->{$oid_coUsInfoLoadAverage1Min}, + load5 => $snmp_result->{$oid_coUsInfoLoadAverage5Min}, + load15 => $snmp_result->{$oid_coUsInfoLoadAverage15Min}, + }; +} + +1; + +__END__ + +=head1 MODE + +Check load-average. + +=over 8 + +=item B<--filter-counters> + +Only display some counters (regexp can be used). +Example: --filter-counters='15min' + +=item B<--warning-*> + +Threshold warning. +Can be: '1min', '5min', '15min'. + +=item B<--critical-*> + +Threshold critical. +Can be: '1min', '5min', '15min'. + +=back + +=cut diff --git a/centreon-plugins/network/colubris/snmp/mode/memory.pm b/centreon-plugins/network/colubris/snmp/mode/memory.pm new file mode 100644 index 000000000..31f7c39ff --- /dev/null +++ b/centreon-plugins/network/colubris/snmp/mode/memory.pm @@ -0,0 +1,129 @@ +# +# Copyright 2017 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::colubris::snmp::mode::memory; + +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}; + + my $oid_coUsInfoRamTotal = '.1.3.6.1.4.1.8744.5.21.1.1.9.0'; + my $oid_coUsInfoRamFree = '.1.3.6.1.4.1.8744.5.21.1.1.10.0'; + my $oid_coUsInfoRamBuffer = '.1.3.6.1.4.1.8744.5.21.1.1.11.0'; + my $oid_coUsInfoRamCached = '.1.3.6.1.4.1.8744.5.21.1.1.12.0'; + + my $result = $self->{snmp}->get_leef(oids => [ + $oid_coUsInfoRamTotal, $oid_coUsInfoRamFree, + $oid_coUsInfoRamBuffer, $oid_coUsInfoRamCached + ], nothing_quit => 1); + + my $cached_used = $result->{$oid_coUsInfoRamCached}; + my $buffer_used = $result->{$oid_coUsInfoRamBuffer}; + my $physical_used = ($result->{$oid_coUsInfoRamTotal}) - ($result->{$oid_coUsInfoRamFree}); + my $nobuf_used = $physical_used - $buffer_used - $cached_used; + + my $total_size = $result->{$oid_coUsInfoRamTotal}; + + my $prct_used = $nobuf_used * 100 / $total_size; + my $exit = $self->{perfdata}->threshold_check(value => $prct_used, threshold => [ { label => 'critical', exit_litteral => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]); + + my ($total_value, $total_unit) = $self->{perfdata}->change_bytes(value => $total_size); + my ($nobuf_value, $nobuf_unit) = $self->{perfdata}->change_bytes(value => $nobuf_used); + my ($buffer_value, $buffer_unit) = $self->{perfdata}->change_bytes(value => $buffer_used); + my ($cached_value, $cached_unit) = $self->{perfdata}->change_bytes(value => $cached_used); + + $self->{output}->output_add(severity => $exit, + short_msg => sprintf("Ram Total: %s, Used (-buffers/cache): %s (%.2f%%), Buffer: %s, Cached: %s", + $total_value . " " . $total_unit, + $nobuf_value . " " . $nobuf_unit, $prct_used, + $buffer_value . " " . $buffer_unit, + $cached_value . " " . $cached_unit)); + + $self->{output}->perfdata_add(label => "cached", unit => 'B', + value => $cached_used, + min => 0); + $self->{output}->perfdata_add(label => "buffer", unit => 'B', + value => $buffer_used, + min => 0); + $self->{output}->perfdata_add(label => "used", unit => 'B', + value => $nobuf_used, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning', total => $total_size, cast_int => 1), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical', total => $total_size, cast_int => 1), + min => 0, max => $total_size); + + $self->{output}->display(); + $self->{output}->exit(); +} + +1; + +__END__ + +=head1 MODE + +Check memory usage. + +=over 8 + +=item B<--warning> + +Threshold warning in percent. + +=item B<--critical> + +Threshold critical in percent. + +=back + +=cut diff --git a/centreon-plugins/network/colubris/snmp/mode/storage.pm b/centreon-plugins/network/colubris/snmp/mode/storage.pm new file mode 100644 index 000000000..ef6bc1774 --- /dev/null +++ b/centreon-plugins/network/colubris/snmp/mode/storage.pm @@ -0,0 +1,108 @@ +# +# Copyright 2017 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::colubris::snmp::mode::storage; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'storage', type => 0 } + ]; + + $self->{maps_counters}->{storage} = [ + { label => 'permanent-usage', set => { + key_values => [ { name => 'perm_used' } ], + output_template => 'Permanent Storage Used: %.2f%%', + perfdatas => [ + { label => 'storage_permanent_used', value => 'perm_used_absolute', template => '%.2f', + min => 0, max => 100, unit => '%' }, + ], + } + }, + { label => 'temporary-usage', set => { + key_values => [ { name => 'temp_used' } ], + output_template => 'Temporary Storage Used: %.2f%%', + perfdatas => [ + { label => 'storage_temporary_used', value => 'temp_used_absolute', template => '%.2f', + min => 0, max => 100, unit => '%' }, + ], + } + }, + ]; +} + +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 => + { + }); + + return $self; +} + +sub manage_selection { + my ($self, %options) = @_; + + my $oid_coUsInfoStorageUsePermanent = '.1.3.6.1.4.1.8744.5.21.1.1.13.0'; + my $oid_coUsInfoStorageUseTemporary = '.1.3.6.1.4.1.8744.5.21.1.1.14.0'; + my $snmp_result = $options{snmp}->get_leef(oids => [ + $oid_coUsInfoStorageUsePermanent, $oid_coUsInfoStorageUseTemporary, + ], nothing_quit => 1); + + $self->{storage} = { + perm_used => $snmp_result->{$oid_coUsInfoStorageUsePermanent}, + temp_used => $snmp_result->{$oid_coUsInfoStorageUseTemporary}, + }; +} + +1; + +__END__ + +=head1 MODE + +Check storage usage. + +=over 8 + +=item B<--warning-*> + +Threshold warning. +Can be: 'permanent-usage' (%), 'temporary-usage' (%). + +=item B<--critical-*> + +Threshold critical. +Can be: 'permanent-usage' (%), 'temporary-usage' (%). + + +=back + +=cut diff --git a/centreon-plugins/network/colubris/snmp/plugin.pm b/centreon-plugins/network/colubris/snmp/plugin.pm new file mode 100644 index 000000000..5fb8332b7 --- /dev/null +++ b/centreon-plugins/network/colubris/snmp/plugin.pm @@ -0,0 +1,54 @@ +# +# Copyright 2017 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::colubris::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}} = ( + 'ap-usage' => 'network::colubris::snmp::mode::apusage', + 'cpu' => 'network::colubris::snmp::mode::cpu', + 'interfaces' => 'snmp_standard::mode::interfaces', + 'list-interfaces' => 'snmp_standard::mode::listinterfaces', + 'load' => 'network::colubris::snmp::mode::load', + 'memory' => 'network::colubris::snmp::mode::memory', + 'storage' => 'network::colubris::snmp::mode::storage', + ); + + return $self; +} + +1; + +__END__ + +=head1 PLUGIN DESCRIPTION + +Check Colubris equipments in SNMP. + +=cut diff --git a/centreon-plugins/network/dell/6200/plugin.pm b/centreon-plugins/network/dell/6200/snmp/plugin.pm similarity index 90% rename from centreon-plugins/network/dell/6200/plugin.pm rename to centreon-plugins/network/dell/6200/snmp/plugin.pm index 198d0f68f..e321b9244 100644 --- a/centreon-plugins/network/dell/6200/plugin.pm +++ b/centreon-plugins/network/dell/6200/snmp/plugin.pm @@ -18,7 +18,7 @@ # limitations under the License. # -package network::dell::6200::plugin; +package network::dell::6200::snmp::plugin; use strict; use warnings; @@ -32,10 +32,10 @@ sub new { $self->{version} = '1.0'; %{$self->{modes}} = ( 'global-status' => 'centreon::common::dell::powerconnect3000::mode::globalstatus', - 'environment' => 'centreon::common::fastpath::mode::environment', + 'environment' => 'centreon::common::dell::fastpath::snmp::mode::environment', 'interfaces' => 'snmp_standard::mode::interfaces', - 'memory' => 'centreon::common::fastpath::mode::memory', - 'cpu' => 'centreon::common::fastpath::mode::cpu', + 'memory' => 'centreon::common::dell::fastpath::snmp::mode::memory', + 'cpu' => 'centreon::common::dell::fastpath::snmp::mode::cpu', 'list-interfaces' => 'snmp_standard::mode::listinterfaces', ); diff --git a/centreon-plugins/network/dell/n4000/plugin.pm b/centreon-plugins/network/dell/n4000/snmp/plugin.pm similarity index 90% rename from centreon-plugins/network/dell/n4000/plugin.pm rename to centreon-plugins/network/dell/n4000/snmp/plugin.pm index e5b0e53b9..c0a0ad767 100644 --- a/centreon-plugins/network/dell/n4000/plugin.pm +++ b/centreon-plugins/network/dell/n4000/snmp/plugin.pm @@ -18,7 +18,7 @@ # limitations under the License. # -package network::dell::n4000::plugin; +package network::dell::n4000::snmp::plugin; use strict; use warnings; @@ -32,10 +32,10 @@ sub new { $self->{version} = '1.0'; %{$self->{modes}} = ( 'global-status' => 'centreon::common::dell::powerconnect3000::mode::globalstatus', - 'environment' => 'centreon::common::fastpath::mode::environment', + 'environment' => 'centreon::common::dell::fastpath::snmp::mode::environment', 'interfaces' => 'snmp_standard::mode::interfaces', - 'memory' => 'centreon::common::fastpath::mode::memory', - 'cpu' => 'centreon::common::fastpath::mode::cpu', + 'memory' => 'centreon::common::dell::fastpath::snmp::mode::memory', + 'cpu' => 'centreon::common::dell::fastpath::snmp::mode::cpu', 'list-interfaces' => 'snmp_standard::mode::listinterfaces', ); diff --git a/centreon-plugins/network/f5/bigip/snmp/mode/listpools.pm b/centreon-plugins/network/f5/bigip/snmp/mode/listpools.pm index b0117b22d..c2f2ef5f3 100644 --- a/centreon-plugins/network/f5/bigip/snmp/mode/listpools.pm +++ b/centreon-plugins/network/f5/bigip/snmp/mode/listpools.pm @@ -88,7 +88,7 @@ sub run { } $self->{output}->output_add(severity => 'OK', - short_msg => 'List Nodes:'); + short_msg => 'List Pools:'); $self->{output}->display(nolabel => 1, force_ignore_perfdata => 1, force_long_output => 1); $self->{output}->exit(); } @@ -132,4 +132,4 @@ Allows to use regexp to filter pool name (with option --name). =back =cut - \ No newline at end of file + diff --git a/centreon-plugins/network/freebox/restapi/custom/api.pm b/centreon-plugins/network/freebox/restapi/custom/api.pm new file mode 100644 index 000000000..b75c9cfaa --- /dev/null +++ b/centreon-plugins/network/freebox/restapi/custom/api.pm @@ -0,0 +1,306 @@ +# +# Copyright 2017 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::freebox::restapi::custom::api; + +use strict; +use warnings; +use centreon::plugins::http; +use JSON; +use Digest::SHA qw(hmac_sha1_hex); + +sub new { + my ($class, %options) = @_; + my $self = {}; + bless $self, $class; + + 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' }, + "freebox-app-id:s@" => { name => 'freebox_app_id' }, + "freebox-app-token:s@" => { name => 'freebox_app_token' }, + "freebox-api-version:s@" => { name => 'freebox_api_version', }, + "proxyurl:s@" => { name => 'proxyurl' }, + "timeout:s@" => { name => 'timeout' }, + "resolution:s@" => { name => 'resolution' }, + }); + } + $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}); + + $self->{session_token} = undef; + + return $self; + +} + +sub set_options { + my ($self, %options) = @_; + + $self->{option_results} = $options{option_results}; +} + +sub set_defaults { + my ($self, %options) = @_; + + 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) = @_; + + $self->{hostname} = (defined($self->{option_results}->{hostname})) ? shift(@{$self->{option_results}->{hostname}}) : 'mafreebox.free.fr'; + $self->{freebox_app_id} = (defined($self->{option_results}->{freebox_app_id})) ? shift(@{$self->{option_results}->{freebox_app_id}}) : undef; + $self->{freebox_app_token} = (defined($self->{option_results}->{freebox_app_token})) ? shift(@{$self->{option_results}->{freebox_app_token}}) : undef; + $self->{freebox_api_version} = (defined($self->{option_results}->{freebox_api_version})) ? shift(@{$self->{option_results}->{freebox_api_version}}) : 'v4'; + $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; + $self->{resolution} = (defined($self->{option_results}->{resolution})) ? shift(@{$self->{option_results}->{resolution}}) : 300; + + if (!defined($self->{hostname})) { + $self->{output}->add_option_msg(short_msg => "Need to specify hostname option."); + $self->{output}->option_exit(); + } + if (!defined($self->{freebox_app_id})) { + $self->{output}->add_option_msg(short_msg => "Need to specify freebox-app-id option."); + $self->{output}->option_exit(); + } + if (!defined($self->{freebox_app_token})) { + $self->{output}->add_option_msg(short_msg => "Need to specify freebox-app-token option."); + $self->{output}->option_exit(); + } + + if (!defined($self->{option_results}->{freebox_app_id}) || + scalar(@{$self->{option_results}->{freebox_app_id}}) == 0) { + return 0; + } + return 1; +} + +sub build_options_for_httplib { + my ($self, %options) = @_; + + $self->{option_results}->{hostname} = $self->{hostname}; + $self->{option_results}->{timeout} = $self->{timeout}; + $self->{option_results}->{port} = 80; + $self->{option_results}->{proto} = 'http'; + $self->{option_results}->{proxyurl} = $self->{proxyurl}; +} + +sub settings { + my ($self, %options) = @_; + + $self->build_options_for_httplib(); + if (defined($self->{session_token})) { + $self->{http}->add_header(key => 'X-Fbx-App-Auth', value => $self->{session_token}); + } + $self->{http}->add_header(key => 'Accept', value => 'application/json'); + $self->{http}->add_header(key => 'Content-type', value => 'application/json'); + $self->{http}->set_options(%{$self->{option_results}}); +} + +sub manage_response { + my ($self, %options) = @_; + + my $response = $self->{http}->get_response(); + if ($response->code() != 200) { + $self->{output}->add_option_msg(short_msg => "Connection issue: " . $options{content}); + $self->{output}->option_exit(); + } + + my $decoded; + eval { + $decoded = decode_json($options{content}); + }; + if ($@) { + $self->{output}->add_option_msg(short_msg => "Cannot decode json response"); + $self->{output}->option_exit(); + } + + if (!$decoded->{success}) { + $self->{output}->add_option_msg(short_msg => "Unsuccessful $options{type} response"); + $self->{output}->option_exit(); + } + + return $decoded; +} + +sub get_session { + my ($self, %options) = @_; + + $self->settings(); + my $content = $self->{http}->request(url_path => '/api/' . $self->{freebox_api_version} . '/login/', + critical_status => '', warning_status => '', unknown_status => ''); + my $decoded = $self->manage_response(content => $content, type => 'login'); + my $challenge = $decoded->{result}->{challenge}; + my $password = hmac_sha1_hex($challenge, $self->{freebox_app_token}); + + my $json_request = { app_id => $self->{freebox_app_id}, password => $password }; + my $encoded; + eval { + $encoded = encode_json($json_request); + }; + if ($@) { + $self->{output}->add_option_msg(short_msg => "Cannot encode json request"); + $self->{output}->option_exit(); + } + + $content = $self->{http}->request(url_path => '/api/' . $self->{freebox_api_version} . '/login/session/', method => 'POST', + query_form_post => $encoded, critical_status => '', warning_status => '', unknown_status => ''); + $decoded = $self->manage_response(content => $content, type => 'login/session'); + + $self->{session_token} = $decoded->{result}->{session_token}; +} + +sub get_data { + my ($self, %options) = @_; + + if (!defined($self->{session_token})) { + $self->get_session(); + } + + $self->settings(); + my $content = $self->{http}->request(url_path => '/api/' . $self->{freebox_api_version} . '/' . $options{path}, + critical_status => '', warning_status => '', unknown_status => ''); + my $decoded = $self->manage_response(content => $content, type => $options{path}); + return $decoded->{result}; +} + +sub get_performance { + my ($self, %options) = @_; + + if (!defined($self->{session_token})) { + $self->get_session(); + } + + my $json_request = { db => $options{db}, date_start => time() - $self->{resolution}, precision => 100 }; + my $encoded; + eval { + $encoded = encode_json($json_request); + }; + if ($@) { + $self->{output}->add_option_msg(short_msg => "Cannot encode json request"); + $self->{output}->option_exit(); + } + + $self->settings(); + my $content = $self->{http}->request(url_path => '/api/' . $self->{freebox_api_version} . '/' . $options{path}, + method => 'POST', query_form_post => $encoded, + critical_status => '', warning_status => '', unknown_status => ''); + my $decoded = $self->manage_response(content => $content); + my ($datas, $total) = ({}, 0); + foreach my $data (@{$decoded->{result}->{data}}) { + foreach my $label (keys %$data) { + next if ($label eq 'time'); + $datas->{$label} = 0 if (!defined($datas->{$label})); + $datas->{$label} += $data->{$label}; + } + $total++; + } + + foreach (keys %$datas) { + $datas->{$_} /= $total; + } + + return $datas; +} + +sub DESTROY { + my $self = shift; + + if (defined($self->{session_token})) { + $self->{http}->request(url_path => '/api/' . $self->{freebox_api_version} . '/login/logout/', method => 'POST'); + } +} + +1; + +__END__ + +=head1 NAME + +FREEBOX REST API + +=head1 SYNOPSIS + +Freebox Rest API custom mode + +=head1 REST API OPTIONS + +=over 8 + +=item B<--hostname> + +Freebox hostname (Default: 'mafreebox.free.fr'). + +=item B<--freebox-app-id> + +Freebox App ID. + +=item B<--freebox-app-token> + +Freebox App Token. + +=item B<--freebox-api-version> + +Freebox API version (Default: 'v4'). + +=item B<--proxyurl> + +Proxy URL if any. + +=item B<--timeout> + +Set HTTP timeout in seconds (Default: '10'). + +=item B<--resolution> + +Selected data performance resolution in seconds (Default: '300'). + +=back + +=head1 DESCRIPTION + +B. + +=cut diff --git a/centreon-plugins/network/freebox/restapi/mode/dslusage.pm b/centreon-plugins/network/freebox/restapi/mode/dslusage.pm new file mode 100644 index 000000000..cc804e111 --- /dev/null +++ b/centreon-plugins/network/freebox/restapi/mode/dslusage.pm @@ -0,0 +1,128 @@ +# +# Copyright 2017 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::freebox::restapi::mode::dslusage; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'global', type => 0 }, + ]; + + $self->{maps_counters}->{global} = [ + { label => 'rate-up', set => { + key_values => [ { name => 'rate_up' } ], + output_template => 'Dsl available upload bandwidth : %.2f %s/s', + output_change_bytes => 2, + perfdatas => [ + { label => 'rate_up', value => 'rate_up_absolute', template => '%.2f', + unit => 'b/s', min => 0 }, + ], + } + }, + { label => 'rate-down', set => { + key_values => [ { name => 'rate_down' } ], + output_template => 'Dsl available download bandwidth : %.2f %s/s', + output_change_bytes => 2, + perfdatas => [ + { label => 'rate_down', value => 'rate_down_absolute', template => '%.2f', + unit => 'b/s', min => 0 }, + ], + } + }, + { label => 'snr-up', set => { + key_values => [ { name => 'snr_up' } ], + output_template => 'Dsl upload signal/noise ratio : %.2f dB', + output_change_bytes => 2, + perfdatas => [ + { label => 'snr_up', value => 'snr_up_absolute', template => '%.2f', + unit => 'dB' }, + ], + } + }, + { label => 'snr-down', set => { + key_values => [ { name => 'snr_down' } ], + output_template => 'Dsl download signal/noise ratio : %.2f dB', + output_change_bytes => 2, + perfdatas => [ + { label => 'snr_down', value => 'snr_down_absolute', template => '%.2f', + unit => 'dB' }, + ], + } + }, + ]; +} + +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 => + { + }); + + return $self; +} + +sub manage_selection { + my ($self, %options) = @_; + + my $result = $options{custom}->get_performance(db => 'dsl', path => 'rrd/'); + $result->{snr_up} *= 10 if (defined($result->{snr_up})); + $result->{snr_down} *= 10 if (defined($result->{snr_down})); + $self->{global} = { %{$result} }; +} + +1; + +__END__ + +=head1 MODE + +Check dsl usage. + +=over 8 + +=item B<--filter-counters> + +Only display some counters (regexp can be used). +Example: --filter-counters='^rate-up$' + +=item B<--warning-*> + +Threshold warning. +Can be: 'rate-up', 'rate-down', 'snr-up', 'snr-down'. + +=item B<--critical-*> + +Threshold critical. +Can be: 'rate-up', 'rate-down', 'snr-up', 'snr-down'. + +=back + +=cut diff --git a/centreon-plugins/network/freebox/restapi/mode/netusage.pm b/centreon-plugins/network/freebox/restapi/mode/netusage.pm new file mode 100644 index 000000000..f241dbfb2 --- /dev/null +++ b/centreon-plugins/network/freebox/restapi/mode/netusage.pm @@ -0,0 +1,146 @@ +# +# Copyright 2017 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::freebox::restapi::mode::netusage; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'global', type => 0, skipped_code => { -10 => 1 } }, + ]; + + $self->{maps_counters}->{global} = [ + { label => 'bw-up', set => { + key_values => [ { name => 'bw_up' } ], + output_template => 'Upload available bandwidth : %.2f %s/s', + output_change_bytes => 2, + perfdatas => [ + { label => 'bw_up', value => 'bw_up_absolute', template => '%.2f', + unit => 'b/s', min => 0 }, + ], + } + }, + { label => 'bw-down', set => { + key_values => [ { name => 'bw_down' } ], + output_template => 'Download available bandwidth : %.2f %s/s', + output_change_bytes => 2, + perfdatas => [ + { label => 'bw_down', value => 'bw_down_absolute', template => '%.2f', + unit => 'b/s', min => 0 }, + ], + } + }, + { label => 'rate-up', set => { + key_values => [ { name => 'rate_up' } ], + output_template => 'Upload rate : %.2f %s/s', + output_change_bytes => 2, + perfdatas => [ + { label => 'rate_up', value => 'rate_up_absolute', template => '%.2f', + unit => 'b/s', min => 0 }, + ], + } + }, + { label => 'rate-down', set => { + key_values => [ { name => 'rate_down' } ], + output_template => 'Download rate : %.2f %s/s', + output_change_bytes => 2, + perfdatas => [ + { label => 'rate_down', value => 'rate_down_absolute', template => '%.2f', + unit => 'b/s', min => 0 }, + ], + } + }, + { label => 'vpn-rate-up', set => { + key_values => [ { name => 'vpn_rate_up' } ], + output_template => 'Vpn client upload rate : %.2f %s/s', + output_change_bytes => 2, + perfdatas => [ + { label => 'vpn_rate_up', value => 'vpn_rate_up_absolute', template => '%.2f', + unit => 'b/s', min => 0 }, + ], + } + }, + { label => 'vpn-rate-down', set => { + key_values => [ { name => 'vpn_rate_down' } ], + output_template => 'Vpn client download rate : %.2f %s/s', + output_change_bytes => 2, + perfdatas => [ + { label => 'vpn_rate_down', value => 'vpn_rate_down_absolute', template => '%.2f', + unit => 'b/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 => + { + }); + + return $self; +} + +sub manage_selection { + my ($self, %options) = @_; + + my $result = $options{custom}->get_performance(db => 'net', path => 'rrd/'); + $self->{global} = { %{$result} }; +} + +1; + +__END__ + +=head1 MODE + +Check network usage. + +=over 8 + +=item B<--filter-counters> + +Only display some counters (regexp can be used). +Example: --filter-counters='^bw-up$' + +=item B<--warning-*> + +Threshold warning. +Can be: 'bw-up', 'bw-down', 'rate-up', 'rate-down', 'vpn-rate-up', 'vpn-rate-down'. + +=item B<--critical-*> + +Threshold critical. +Can be: 'bw-up', 'bw-down', 'rate-up', 'rate-down', 'vpn-rate-up', 'vpn-rate-down'. + +=back + +=cut diff --git a/centreon-plugins/network/freebox/restapi/mode/system.pm b/centreon-plugins/network/freebox/restapi/mode/system.pm new file mode 100644 index 000000000..4f11eb1ab --- /dev/null +++ b/centreon-plugins/network/freebox/restapi/mode/system.pm @@ -0,0 +1,252 @@ +# +# Copyright 2017 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::freebox::restapi::mode::system; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; +my $instance_mode; + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'global', type => 0 }, + { name => 'wifi', type => 1, cb_prefix_output => 'prefix_wifi_output', message_multiple => 'All wifis are ok' } + ]; + + $self->{maps_counters}->{global} = [ + { label => 'temperature-cpum', set => { + key_values => [ { name => 'temp_cpum' } ], + output_template => 'Temperature cpum : %s C', + perfdatas => [ + { label => 'temp_cpum', value => 'temp_cpum_absolute', template => '%s', + unit => 'C' }, + ], + } + }, + { label => 'temperature-cpub', set => { + key_values => [ { name => 'temp_cpub' } ], + output_template => 'Temperature cpub : %s C', + perfdatas => [ + { label => 'temp_cpub', value => 'temp_cpub_absolute', template => '%s', + unit => 'C' }, + ], + } + }, + { label => 'temperature-switch', set => { + key_values => [ { name => 'temp_sw' } ], + output_template => 'Temperature switch : %s C', + perfdatas => [ + { label => 'temp_sw', value => 'temp_sw_absolute', template => '%s', + unit => 'C' }, + ], + } + }, + { label => 'fan-speed', set => { + key_values => [ { name => 'fan_rpm' } ], + output_template => 'fan speed : %s rpm', + perfdatas => [ + { label => 'fan_rpm', value => 'fan_rpm_absolute', template => '%s', + min => 0, unit => 'rpm' }, + ], + } + }, + { label => 'disk-status', threshold => 0, set => { + key_values => [ { name => 'disk_status' } ], + closure_custom_calc => $self->can('custom_disk_status_calc'), + closure_custom_output => $self->can('custom_disk_status_output'), + closure_custom_perfdata => sub { return 0; }, + closure_custom_threshold_check => $self->can('custom_status_threshold'), + } + }, + + ]; + + $self->{maps_counters}->{wifi} = [ + { label => 'wifi-status', threshold => 0, set => { + key_values => [ { name => 'wifi_status' }, { name => 'display' } ], + closure_custom_calc => $self->can('custom_wifi_status_calc'), + closure_custom_output => $self->can('custom_wifi_status_output'), + closure_custom_perfdata => sub { return 0; }, + closure_custom_threshold_check => $self->can('custom_status_threshold'), + } + }, + ]; +} + +sub custom_status_threshold { + my ($self, %options) = @_; + my $status = 'ok'; + my $message; + + eval { + local $SIG{__WARN__} = sub { $message = $_[0]; }; + local $SIG{__DIE__} = sub { $message = $_[0]; }; + + my $label = $self->{label}; + $label =~ s/-/_/g; + if (defined($instance_mode->{option_results}->{'critical_' . $label}) && $instance_mode->{option_results}->{'critical_' . $label} ne '' && + eval "$instance_mode->{option_results}->{'critical_' . $label}") { + $status = 'critical'; + } elsif (defined($instance_mode->{option_results}->{'warning_' . $label}) && $instance_mode->{option_results}->{'warning_' . $label} ne '' && + eval "$instance_mode->{option_results}->{'warning_' . $label}") { + $status = 'warning'; + } + }; + if (defined($message)) { + $self->{output}->output_add(long_msg => 'filter status issue: ' . $message); + } + + return $status; +} + +sub custom_disk_status_output { + my ($self, %options) = @_; + my $msg = 'Disk status : ' . $self->{result_values}->{status}; + + return $msg; +} + +sub custom_disk_status_calc { + my ($self, %options) = @_; + + $self->{result_values}->{status} = $options{new_datas}->{$self->{instance} . '_disk_status'}; + return 0; +} + +sub custom_wifi_status_output { + my ($self, %options) = @_; + my $msg = "Wifi '" . $self->{result_values}->{display} . "' status : " . $self->{result_values}->{status}; + + return $msg; +} + +sub custom_wifi_status_calc { + my ($self, %options) = @_; + + $self->{result_values}->{display} = $options{new_datas}->{$self->{instance} . '_display'}; + $self->{result_values}->{status} = $options{new_datas}->{$self->{instance} . '_wifi_status'}; + 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 => + { + "warning-wifi-status:s" => { name => 'warning_wifi_status', default => '%{status} =~ /bad_param/i' }, + "critical-wifi-status:s" => { name => 'critical_wifi_status', default => '%{status} =~ /failed/i' }, + "warning-disk-status:s" => { name => 'warning_disk_status', default => '' }, + "critical-disk-status:s" => { name => 'critical_disk_status', default => '%{status} =~ /error/i' }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::check_options(%options); + + $instance_mode = $self; + $self->change_macros(); +} + +sub change_macros { + my ($self, %options) = @_; + + foreach (('warning_wifi_status', 'critical_wifi_status', 'warning_disk_status', 'critical_disk_status')) { + if (defined($self->{option_results}->{$_})) { + $self->{option_results}->{$_} =~ s/%\{(.*?)\}/\$self->{result_values}->{$1}/g; + } + } +} + +sub manage_selection { + my ($self, %options) = @_; + + my $result = $options{custom}->get_data(path => 'system/'); + $self->{global} = { %{$result} }; + + $result = $options{custom}->get_data(path => 'wifi/ap/'); + $self->{wifi} = {}; + + $result = [$result] if (ref($result) ne 'ARRAY'); + foreach (@$result) { + $self->{wifi}->{$_->{id}} = { + display => $_->{name}, + wifi_status => $_->{status}->{state}, + }; + } +} + +1; + +__END__ + +=head1 MODE + +Check system. + +=over 8 + +=item B<--filter-counters> + +Only display some counters (regexp can be used). +Example: --filter-counters='^temperature-cpum$' + +=item B<--warning-wifi-status> + +Set warning threshold for wifi status (Default: '%{status} =~ /bad_param/i'). +Can used special variables like: %{status}, %{display} + +=item B<--critical-wifi-status> + +Set critical threshold for wifi status (Default: '%{status} =~ /failed/i'). +Can used special variables like: %{status}, %{display} + +=item B<--warning-disk-status> + +Set warning threshold for disk status. +Can used special variables like: %{status} + +=item B<--critical-disk-status> + +Set critical threshold for disk status (Default: '%{status} =~ /error/i'). +Can used special variables like: %{status} + +=item B<--warning-*> + +Threshold warning. +Can be: 'temperature-cpum', 'temperature-cpub', 'temperature-switch', 'fan-speed'. + +=item B<--critical-*> + +Threshold critical. +Can be: 'temperature-cpum', 'temperature-cpub', 'temperature-switch', 'fan-speed'. + +=back + +=cut diff --git a/centreon-plugins/network/freebox/restapi/plugin.pm b/centreon-plugins/network/freebox/restapi/plugin.pm new file mode 100644 index 000000000..e88849059 --- /dev/null +++ b/centreon-plugins/network/freebox/restapi/plugin.pm @@ -0,0 +1,51 @@ +# +# Copyright 2017 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::freebox::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; + + $self->{version} = '1.0'; + %{$self->{modes}} = ( + 'dsl-usage' => 'network::freebox::restapi::mode::dslusage', + 'net-usage' => 'network::freebox::restapi::mode::netusage', + 'system' => 'network::freebox::restapi::mode::system', + ); + + $self->{custom_modes}{api} = 'network::freebox::restapi::custom::api'; + return $self; +} + +1; + +__END__ + +=head1 PLUGIN DESCRIPTION + +Check Freebox through HTTP/REST API. + +=cut diff --git a/centreon-plugins/network/hp/procurve/snmp/mode/components/fan.pm b/centreon-plugins/network/hp/procurve/snmp/mode/components/fan.pm new file mode 100644 index 000000000..7d39bde58 --- /dev/null +++ b/centreon-plugins/network/hp/procurve/snmp/mode/components/fan.pm @@ -0,0 +1,76 @@ +# +# Copyright 2017 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::hp::procurve::snmp::mode::components::fan; + +use strict; +use warnings; + +my %map_fan_status = ( + 0 => 'failed', + 1 => 'removed', + 2 => 'off', + 3 => 'underspeed', + 4 => 'overspeed', + 5 => 'ok', + 6 => 'maxstate', +); + +my $mapping = { + hpicfFanState => { oid => '.1.3.6.1.4.1.11.2.14.11.5.1.54.2.1.1.4', map => \%map_fan_status }, +}; + +sub load { + my ($self) = @_; + + push @{$self->{request}}, { oid => $mapping->{hpicfFanState}->{oid} }; +} + +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}->{$mapping->{hpicfFanState}->{oid}}})) { + next if ($oid !~ /^$mapping->{hpicfFanState}->{oid}\.(.*)$/); + my $instance = $1; + my $result = $self->{snmp}->map_instance(mapping => $mapping, results => $self->{results}->{$mapping->{hpicfFanState}->{oid}}, instance => $instance); + + next if ($self->check_filter(section => 'fan', instance => $instance)); + next if ($result->{hpicfFanState} =~ /removed/i && + $self->absent_problem(section => 'fan', instance => $instance)); + $self->{components}->{fan}->{total}++; + + $self->{output}->output_add(long_msg => sprintf("fan '%s' state is %s [instance: %s].", + $instance, $result->{hpicfFanState}, $instance + )); + my $exit = $self->get_severity(section => 'fan', value => $result->{hpicfFanState}); + if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { + $self->{output}->output_add(severity => $exit, + short_msg => sprintf("fan '%s' state is %s", + $instance, $result->{hpicfFanState})); + } + } +} + +1; diff --git a/centreon-plugins/network/hp/procurve/snmp/mode/components/psu.pm b/centreon-plugins/network/hp/procurve/snmp/mode/components/psu.pm new file mode 100644 index 000000000..223d47a47 --- /dev/null +++ b/centreon-plugins/network/hp/procurve/snmp/mode/components/psu.pm @@ -0,0 +1,78 @@ +# +# Copyright 2017 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::hp::procurve::snmp::mode::components::psu; + +use strict; +use warnings; + +my %map_psu_status = ( + 1 => 'psNotPresent', + 2 => 'psNotPlugged', + 3 => 'psPowered', + 4 => 'psFailed', + 5 => 'psPermFailure', + 6 => 'psMax', + 7 => 'psAuxFailure', + 8 => 'psNotPowered', + 9 => 'psAuxNotPowered', +); + +my $mapping = { + hpicfPsState => { oid => '.1.3.6.1.4.1.11.2.14.11.5.1.55.1.1.1.2', map => \%map_psu_status }, +}; + +sub load { + my ($self) = @_; + + push @{$self->{request}}, { oid => $mapping->{hpicfPsState}->{oid} }; +} + +sub check { + my ($self) = @_; + + + $self->{output}->output_add(long_msg => "Checking power supply"); + $self->{components}->{psu} = {name => 'psu', total => 0, skip => 0}; + return if ($self->check_filter(section => 'psu')); + + foreach my $oid ($self->{snmp}->oid_lex_sort(keys %{$self->{results}->{$mapping->{hpicfPsState}->{oid}}})) { + next if ($oid !~ /^$mapping->{hpicfPsState}->{oid}\.(.*)$/); + my $instance = $1; + my $result = $self->{snmp}->map_instance(mapping => $mapping, results => $self->{results}->{$mapping->{hpicfPsState}->{oid}}, instance => $instance); + + next if ($self->check_filter(section => 'psu', instance => $instance)); + next if ($result->{hpicfPsState} =~ /psNotPresent/i && + $self->absent_problem(section => 'psu', instance => $instance)); + $self->{components}->{psu}->{total}++; + + $self->{output}->output_add(long_msg => sprintf("power supply '%s' state is %s [instance: %s].", + $instance, $result->{hpicfPsState}, $instance + )); + my $exit = $self->get_severity(section => 'psu', value => $result->{hpicfPsState}); + if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { + $self->{output}->output_add(severity => $exit, + short_msg => sprintf("power supply '%s' state is %s", + $instance, $result->{hpicfPsState})); + } + } +} + +1; diff --git a/centreon-plugins/network/hp/procurve/mode/components/sensor.pm b/centreon-plugins/network/hp/procurve/snmp/mode/components/sensor.pm similarity index 98% rename from centreon-plugins/network/hp/procurve/mode/components/sensor.pm rename to centreon-plugins/network/hp/procurve/snmp/mode/components/sensor.pm index 49f84f802..7b0aa7990 100644 --- a/centreon-plugins/network/hp/procurve/mode/components/sensor.pm +++ b/centreon-plugins/network/hp/procurve/snmp/mode/components/sensor.pm @@ -18,7 +18,7 @@ # limitations under the License. # -package network::hp::procurve::mode::components::sensor; +package network::hp::procurve::snmp::mode::components::sensor; use strict; use warnings; @@ -81,4 +81,4 @@ sub check { } } -1; \ No newline at end of file +1; diff --git a/centreon-plugins/network/hp/procurve/mode/cpu.pm b/centreon-plugins/network/hp/procurve/snmp/mode/cpu.pm similarity index 98% rename from centreon-plugins/network/hp/procurve/mode/cpu.pm rename to centreon-plugins/network/hp/procurve/snmp/mode/cpu.pm index 31738f1d7..d3ac112a3 100644 --- a/centreon-plugins/network/hp/procurve/mode/cpu.pm +++ b/centreon-plugins/network/hp/procurve/snmp/mode/cpu.pm @@ -18,7 +18,7 @@ # limitations under the License. # -package network::hp::procurve::mode::cpu; +package network::hp::procurve::snmp::mode::cpu; use base qw(centreon::plugins::mode); @@ -97,4 +97,4 @@ Threshold critical in percent. =back =cut - \ No newline at end of file + diff --git a/centreon-plugins/network/hp/procurve/mode/environment.pm b/centreon-plugins/network/hp/procurve/snmp/mode/environment.pm similarity index 74% rename from centreon-plugins/network/hp/procurve/mode/environment.pm rename to centreon-plugins/network/hp/procurve/snmp/mode/environment.pm index a43f15a44..270bbfa37 100644 --- a/centreon-plugins/network/hp/procurve/mode/environment.pm +++ b/centreon-plugins/network/hp/procurve/snmp/mode/environment.pm @@ -18,7 +18,7 @@ # limitations under the License. # -package network::hp::procurve::mode::environment; +package network::hp::procurve::snmp::mode::environment; use base qw(centreon::plugins::templates::hardware); @@ -28,7 +28,7 @@ use warnings; sub set_system { my ($self, %options) = @_; - $self->{regexp_threshold_overload_check_section_option} = '^(sensor)$'; + $self->{regexp_threshold_overload_check_section_option} = '^(sensor|fan|psu)$'; $self->{cb_hook2} = 'snmp_execute'; @@ -40,10 +40,30 @@ sub set_system { ['good', 'OK'], ['not present', 'WARNING'], ], + psu => [ + ['psNotPresent', 'OK'], + ['psNotPlugged', 'WARNING'], + ['psPowered', 'OK'], + ['psFailed', 'CRITICAL'], + ['psPermFailure', 'CRITICAL'], + ['psMax', 'WARNING'], + ['psAuxFailure', 'CRITICAL'], + ['psNotPowered', 'WARNING'], + ['psAuxNotPowered', 'CRITICAL'], + ], + fan => [ + ['failed', 'CRITICAL'], + ['removed', 'OK'], + ['off', 'WARNING'], + ['underspeed', 'WARNING'], + ['overspeed', 'WARNING'], + ['ok', 'OK'], + ['maxstate', 'WARNING'], + ], }; - $self->{components_path} = 'network::hp::procurve::mode::components'; - $self->{components_module} = ['sensor']; + $self->{components_path} = 'network::hp::procurve::snmp::mode::components'; + $self->{components_module} = ['sensor', 'psu', 'fan']; } sub snmp_execute { @@ -79,7 +99,7 @@ Check sensors (hpicfChassis.mib). =item B<--component> Which component to check (Default: '.*'). -Can be: 'sensor'. +Can be: 'sensor', 'psu', 'fan'. =item B<--filter> @@ -105,4 +125,4 @@ Example: --threshold-overload='sensor,CRITICAL,^(?!(good)$)' =back =cut - \ No newline at end of file + diff --git a/centreon-plugins/network/hp/procurve/mode/memory.pm b/centreon-plugins/network/hp/procurve/snmp/mode/memory.pm similarity index 98% rename from centreon-plugins/network/hp/procurve/mode/memory.pm rename to centreon-plugins/network/hp/procurve/snmp/mode/memory.pm index b4b7ec8bb..f0af7150f 100644 --- a/centreon-plugins/network/hp/procurve/mode/memory.pm +++ b/centreon-plugins/network/hp/procurve/snmp/mode/memory.pm @@ -18,7 +18,7 @@ # limitations under the License. # -package network::hp::procurve::mode::memory; +package network::hp::procurve::snmp::mode::memory; use base qw(centreon::plugins::mode); @@ -127,4 +127,4 @@ Threshold critical in percent. =back =cut - \ No newline at end of file + diff --git a/centreon-plugins/network/hp/procurve/snmp/plugin.pm b/centreon-plugins/network/hp/procurve/snmp/plugin.pm new file mode 100644 index 000000000..6bc47d95e --- /dev/null +++ b/centreon-plugins/network/hp/procurve/snmp/plugin.pm @@ -0,0 +1,52 @@ +# +# Copyright 2017 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::hp::procurve::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::hp::procurve::snmp::mode::cpu', + 'environment' => 'network::hp::procurve::snmp::mode::environment', + 'interfaces' => 'snmp_standard::mode::interfaces', + 'list-interfaces' => 'snmp_standard::mode::listinterfaces', + 'memory' => 'network::hp::procurve::snmp::mode::memory', + ); + + return $self; +} + +1; + +__END__ + +=head1 PLUGIN DESCRIPTION + +Check Switch HP Procurve in SNMP. + +=cut diff --git a/centreon-plugins/network/infoblox/snmp/mode/cpu.pm b/centreon-plugins/network/infoblox/snmp/mode/cpu.pm new file mode 100644 index 000000000..f9b2e26ad --- /dev/null +++ b/centreon-plugins/network/infoblox/snmp/mode/cpu.pm @@ -0,0 +1,92 @@ +# +# Copyright 2017 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::infoblox::snmp::mode::cpu; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'global', type => 0 }, + ]; + + $self->{maps_counters}->{global} = [ + { label => 'usage', set => { + key_values => [ { name => 'cpu' } ], + output_template => 'CPU Usage : %.2f %%', + perfdatas => [ + { label => 'cpu_usage', value => 'cpu_absolute', template => '%.2f', + min => 0, max => 100, unit => '%' }, + ], + } + }, + ]; +} + +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 => + { + }); + + return $self; +} + +sub manage_selection { + my ($self, %options) = @_; + + my $oid_ibSystemMonitorCpuUsage = '.1.3.6.1.4.1.7779.3.1.1.2.1.8.1.1.0'; + my $snmp_result = $options{snmp}->get_leef(oids => [ + $oid_ibSystemMonitorCpuUsage + ], nothing_quit => 1); + + $self->{global} = { cpu => $snmp_result->{$oid_ibSystemMonitorCpuUsage} }; +} + +1; + +__END__ + +=head1 MODE + +Check CPU usage. + +=over 8 + +=item B<--warning-usage> + +Threshold warning. + +=item B<--critical-usage> + +Threshold critical. + +=back + +=cut diff --git a/centreon-plugins/network/infoblox/snmp/mode/dhcpusage.pm b/centreon-plugins/network/infoblox/snmp/mode/dhcpusage.pm new file mode 100644 index 000000000..001cf7ae2 --- /dev/null +++ b/centreon-plugins/network/infoblox/snmp/mode/dhcpusage.pm @@ -0,0 +1,193 @@ +# +# Copyright 2017 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::infoblox::snmp::mode::dhcpusage; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; +use Digest::MD5 qw(md5_hex); + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'global', type => 0, cb_prefix_output => 'prefix_global_output' }, + { name => 'dhcp', type => 1, cb_prefix_output => 'prefix_dhcp_output', message_multiple => 'All dhcp subnets are ok' }, + ]; + + my @map = ( + ['ibDhcpTotalNoOfDiscovers', 'discovers : %s', 'total-discovers'], + ['ibDhcpTotalNoOfRequests', 'requests : %s', 'total-requests'], + ['ibDhcpTotalNoOfReleases', 'releases : %s', 'total-releases'], + ['ibDhcpTotalNoOfOffers', 'offers : %s', 'total-offers'], + ['ibDhcpTotalNoOfAcks', 'acks : %s', 'total-acks'], + ['ibDhcpTotalNoOfNacks', 'nacks : %s', 'total-nacks'], + ['ibDhcpTotalNoOfDeclines', 'declines : %s', 'total-declines'], + ['ibDhcpTotalNoOfInforms', 'informs : %s', 'total-informs'], + ['ibDhcpTotalNoOfOthers', 'others : %s', 'total-others'], + ); + + $self->{maps_counters}->{global} = []; + for (my $i = 0; $i < scalar(@map); $i++) { + my $perf_label = $map[$i]->[2]; + $perf_label =~ s/-/_/g; + push @{$self->{maps_counters}->{global}}, { label => $map[$i]->[2], set => { + key_values => [ { name => $map[$i]->[0], diff => 1 } ], + output_template => $map[$i]->[1], + perfdatas => [ + { label => $perf_label, value => $map[$i]->[0] . '_absolute', template => '%s', min => 0 }, + ], + } + }; + } + + $self->{maps_counters}->{dhcp} = [ + { label => 'subnet-used', set => { + key_values => [ { name => 'ibDHCPSubnetPercentUsed' }, { name => 'display' } ], + output_template => 'Used : %.2f %%', + perfdatas => [ + { label => 'subnet_used', value => 'iibDHCPSubnetPercentUsed_absolute', template => '%.2f', + min => 0, max => 100, unit => '%', label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + ]; +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options, statefile => 1); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => + { + "filter-name:s" => { name => 'filter_name' }, + }); + + return $self; +} + +sub prefix_global_output { + my ($self, %options) = @_; + + return "Total "; +} + +sub prefix_dhcp_output { + my ($self, %options) = @_; + + return "Subnet '" . $options{instance_value}->{display} . "' "; +} + +my $mapping = { + ibDhcpTotalNoOfDiscovers => { oid => '.1.3.6.1.4.1.7779.3.1.1.4.1.3.1' }, + ibDhcpTotalNoOfRequests => { oid => '.1.3.6.1.4.1.7779.3.1.1.4.1.3.2' }, + ibDhcpTotalNoOfReleases => { oid => '.1.3.6.1.4.1.7779.3.1.1.4.1.3.3' }, + ibDhcpTotalNoOfOffers => { oid => '.1.3.6.1.4.1.7779.3.1.1.4.1.3.4' }, + ibDhcpTotalNoOfAcks => { oid => '.1.3.6.1.4.1.7779.3.1.1.4.1.3.5' }, + ibDhcpTotalNoOfNacks => { oid => '.1.3.6.1.4.1.7779.3.1.1.4.1.3.6' }, + ibDhcpTotalNoOfDeclines => { oid => '.1.3.6.1.4.1.7779.3.1.1.4.1.3.7' }, + ibDhcpTotalNoOfInforms => { oid => '.1.3.6.1.4.1.7779.3.1.1.4.1.3.8' }, + ibDhcpTotalNoOfOthers => { oid => '.1.3.6.1.4.1.7779.3.1.1.4.1.3.9' }, +}; +my $mapping2 = { + ibDHCPSubnetNetworkAddress => { oid => '.1.3.6.1.4.1.7779.3.1.1.4.1.1.1.1' }, + ibDHCPSubnetNetworkMask => { oid => '.1.3.6.1.4.1.7779.3.1.1.4.1.1.1.2' }, + ibDHCPSubnetPercentUsed => { oid => '.1.3.6.1.4.1.7779.3.1.1.4.1.1.1.3' }, +}; + +my $oid_ibDHCPStatistics = '.1.3.6.1.4.1.7779.3.1.1.4.1.3'; +my $oid_ibDHCPSubnetEntry = '.1.3.6.1.4.1.7779.3.1.1.4.1.1.1'; + +sub manage_selection { + my ($self, %options) = @_; + + my $snmp_result = $options{snmp}->get_multiple_table(oids => [ + { oid => $oid_ibDHCPStatistics }, + { oid => $oid_ibDHCPSubnetEntry }, + ], nothing_quit => 1); + + $self->{dhcp} = {}; + foreach my $oid (keys %{$snmp_result->{$oid_ibDHCPSubnetEntry}}) { + next if ($oid !~ /^$mapping2->{ibDHCPSubnetNetworkAddress}->{oid}\.(.*)$/); + my $instance = $1; + my $result = $options{snmp}->map_instance(mapping => $mapping2, results => $snmp_result->{$oid_ibDHCPSubnetEntry}, instance => $instance); + + my $name = $result->{ibDHCPSubnetNetworkAddress} . '/' . $result->{ibDHCPSubnetNetworkMask}; + if (defined($self->{option_results}->{filter_name}) && $self->{option_results}->{filter_name} ne '' && + $name !~ /$self->{option_results}->{filter_name}/) { + $self->{output}->output_add(long_msg => "skipping '" . $name . "': no matching filter.", debug => 1); + next; + } + + $self->{dhcp}->{$instance} = { display => $name, + %$result + }; + } + + my $result = $options{snmp}->map_instance(mapping => $mapping, results => $snmp_result->{$oid_ibDHCPStatistics}, instance => '0'); + $self->{global} = { %$result }; + + $self->{cache_name} = "infoblox_" . $self->{mode} . '_' . $options{snmp}->get_hostname() . '_' . $options{snmp}->get_port() . '_' . + (defined($self->{option_results}->{filter_counters}) ? md5_hex($self->{option_results}->{filter_counters}) : md5_hex('all')) . '_' . + (defined($self->{option_results}->{filter_name}) ? md5_hex($self->{option_results}->{filter_name}) : md5_hex('all')); +} + +1; + +__END__ + +=head1 MODE + +Check dhcp usage. + +=over 8 + +=item B<--filter-counters> + +Only display some counters (regexp can be used). +Example: --filter-counters='total-requests' + +=item B<--filter-name> + +Filter dhcp subnet name (can be a regexp). + +=item B<--warning-*> + +ibDhcpTotalNoOfDiscovers + +Threshold warning. +Can be: 'total-discovers', 'total-requests', 'total-releases', +'total-offers', 'total-acks', 'total-nacks', 'total-declines', +'total-informs', 'total-others', 'subnet-used' (%). + +=item B<--critical-*> + +Threshold critical. +Can be: 'total-discovers', 'total-requests', 'total-releases', +'total-offers', 'total-acks', 'total-nacks', 'total-declines', +'total-informs', 'total-others', 'subnet-used' (%). + +=back + +=cut diff --git a/centreon-plugins/network/infoblox/snmp/mode/dnsusage.pm b/centreon-plugins/network/infoblox/snmp/mode/dnsusage.pm new file mode 100644 index 000000000..8fee91ba4 --- /dev/null +++ b/centreon-plugins/network/infoblox/snmp/mode/dnsusage.pm @@ -0,0 +1,209 @@ +# +# Copyright 2017 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::infoblox::snmp::mode::dnsusage; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; +use Digest::MD5 qw(md5_hex); + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'global', type => 0 }, + { name => 'dns', type => 1, cb_prefix_output => 'prefix_dns_output', message_multiple => 'All dns zones are ok' }, + ]; + + $self->{maps_counters}->{global} = [ + { label => 'total-query-rate', set => { + key_values => [ { name => 'ibDnsQueryRate' } ], + output_template => 'Total query rate : %s', + perfdatas => [ + { label => 'total_query_rate', value => 'ibDnsQueryRate_absolute', template => '%s', + min => 0 }, + ], + } + }, + { label => 'total-hit-ratio', set => { + key_values => [ { name => 'ibDnsHitRatio' } ], + output_template => 'Total hit ratio : %.2f %%', + perfdatas => [ + { label => 'total_hit_ratio', value => 'ibDnsHitRatio_absolute', template => '%.2f', + min => 0, max => 100, unit => '%' }, + ], + } + }, + ]; + + $self->{maps_counters}->{dns} = [ + { label => 'success-count', set => { + key_values => [ { name => 'ibBindZoneSuccess', diff => 1 }, { name => 'display' } ], + output_template => 'Success responses : %s', + perfdatas => [ + { label => 'success_count', value => 'ibBindZoneSuccess_absolute', template => '%s', + min => 0, label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + { label => 'referral-count', set => { + key_values => [ { name => 'ibBindZoneReferral', diff => 1 }, { name => 'display' } ], + output_template => 'Referrals : %s', + perfdatas => [ + { label => 'referral_count', value => 'ibBindZoneReferral_absolute', template => '%s', + min => 0, label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + { label => 'nxrrset-count', set => { + key_values => [ { name => 'ibBindZoneNxRRset', diff => 1 }, { name => 'display' } ], + output_template => 'Non-existent record : %s', + perfdatas => [ + { label => 'nxrrset_count', value => 'ibBindZoneNxRRset_absolute', template => '%s', + min => 0, label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + { label => 'failure-count', set => { + key_values => [ { name => 'ibBindZoneFailure', diff => 1 }, { name => 'display' } ], + output_template => 'Failed queries : %s', + perfdatas => [ + { label => 'failure_count', value => 'ibBindZoneFailure_absolute', template => '%s', + min => 0, label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + ]; +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options, statefile => 1); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => + { + "filter-name:s" => { name => 'filter_name' }, + }); + + return $self; +} + +sub prefix_dns_output { + my ($self, %options) = @_; + + return "Zone '" . $options{instance_value}->{display} . "' "; +} + +my $mapping = { + ibBindZoneName => { oid => '.1.3.6.1.4.1.7779.3.1.1.3.1.1.1.1' }, + ibBindZoneSuccess => { oid => '.1.3.6.1.4.1.7779.3.1.1.3.1.1.1.2' }, + ibBindZoneReferral => { oid => '.1.3.6.1.4.1.7779.3.1.1.3.1.1.1.3' }, + ibBindZoneNxRRset => { oid => '.1.3.6.1.4.1.7779.3.1.1.3.1.1.1.4' }, + ibBindZoneFailure => { oid => '.1.3.6.1.4.1.7779.3.1.1.3.1.1.1.7' }, +}; +my $mapping2 = { + ibDnsHitRatio => { oid => '.1.3.6.1.4.1.7779.3.1.1.3.1.5' }, + ibDnsQueryRate => { oid => '.1.3.6.1.4.1.7779.3.1.1.3.1.6' }, +}; + +my $oid_ibZoneStatisticsEntry = '.1.3.6.1.4.1.7779.3.1.1.3.1.1.1'; +my $oid_ibDnsModule = '.1.3.6.1.4.1.7779.3.1.1.3.1'; + +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->{dns} = {}; + my $snmp_result = $options{snmp}->get_multiple_table(oids => [ + { oid => $oid_ibZoneStatisticsEntry }, + { oid => $oid_ibDnsModule, start => $mapping2->{ibDnsHitRatio}->{oid} }, + ], nothing_quit => 1); + + foreach my $oid (keys %{$snmp_result->{$oid_ibZoneStatisticsEntry}}) { + next if ($oid !~ /^$mapping->{ibBindZoneName}->{oid}\.(.*)$/); + my $instance = $1; + my $result = $options{snmp}->map_instance(mapping => $mapping, results => $snmp_result->{$oid_ibZoneStatisticsEntry}, instance => $instance); + + if (defined($self->{option_results}->{filter_name}) && $self->{option_results}->{filter_name} ne '' && + $result->{ibBindZoneName} !~ /$self->{option_results}->{filter_name}/) { + $self->{output}->output_add(long_msg => "skipping '" . $result->{ibBindZoneName} . "': no matching filter.", debug => 1); + next; + } + + $self->{dns}->{$instance} = { display => $result->{ibBindZoneName}, + %$result + }; + } + + if (scalar(keys %{$self->{dns}}) <= 0) { + $self->{output}->add_option_msg(short_msg => "No dns zone found."); + $self->{output}->option_exit(); + } + + my $result = $options{snmp}->map_instance(mapping => $mapping2, results => $snmp_result->{$oid_ibDnsModule}, instance => '0'); + $self->{global} = { %$result }; + + $self->{cache_name} = "infoblox_" . $self->{mode} . '_' . $options{snmp}->get_hostname() . '_' . $options{snmp}->get_port() . '_' . + (defined($self->{option_results}->{filter_counters}) ? md5_hex($self->{option_results}->{filter_counters}) : md5_hex('all')) . '_' . + (defined($self->{option_results}->{filter_name}) ? md5_hex($self->{option_results}->{filter_name}) : md5_hex('all')); +} + +1; + +__END__ + +=head1 MODE + +Check dns usage. + +=over 8 + +=item B<--filter-counters> + +Only display some counters (regexp can be used). +Example: --filter-counters='^success-coun$' + +=item B<--filter-name> + +Filter dns zone name (can be a regexp). + +=item B<--warning-*> + +Threshold warning. +Can be: 'total-query-rate', 'total-hit-ratio', 'success-count', 'referral-count', 'nxrrset-count', +'failure-count'. + +=item B<--critical-*> + +Threshold critical. +Can be: 'total-query-rate', 'total-hit-ratio', 'success-count', 'referral-count', 'nxrrset-count', +'failure-count'. + +=back + +=cut diff --git a/centreon-plugins/network/infoblox/snmp/mode/memory.pm b/centreon-plugins/network/infoblox/snmp/mode/memory.pm new file mode 100644 index 000000000..49996cdea --- /dev/null +++ b/centreon-plugins/network/infoblox/snmp/mode/memory.pm @@ -0,0 +1,108 @@ +# +# Copyright 2017 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::infoblox::snmp::mode::memory; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'memory', type => 0 }, + ]; + + $self->{maps_counters}->{memory} = [ + { label => 'mem-usage', set => { + key_values => [ { name => 'ram_used' } ], + output_template => 'Memory Used: %.2f%%', + perfdatas => [ + { label => 'memory_used', value => 'ram_used_absolute', template => '%.2f', + min => 0, max => 100, unit => '%' }, + ], + } + }, + { label => 'swap-usage', set => { + key_values => [ { name => 'swap_used' } ], + output_template => 'Swap Used: %.2f%%', + perfdatas => [ + { label => 'swap_used', value => 'swap_used_absolute', template => '%.2f', + min => 0, max => 100, unit => '%' }, + ], + } + }, + ]; +} + +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 => + { + }); + + return $self; +} + +sub manage_selection { + my ($self, %options) = @_; + + my $oid_ibSystemMonitorMemUsage = '.1.3.6.1.4.1.7779.3.1.1.2.1.8.2.1.0'; + my $oid_ibSystemMonitorSwapUsage = '.1.3.6.1.4.1.7779.3.1.1.2.1.8.3.1.0'; + my $snmp_result = $options{snmp}->get_leef(oids => [ + $oid_ibSystemMonitorMemUsage, $oid_ibSystemMonitorSwapUsage, + ], nothing_quit => 1); + + $self->{memory} = { + ram_used => $snmp_result->{$oid_ibSystemMonitorMemUsage}, + swap_used => $snmp_result->{$oid_ibSystemMonitorSwapUsage}, + }; +} + +1; + +__END__ + +=head1 MODE + +Check memory usage. + +=over 8 + +=item B<--warning-*> + +Threshold warning. +Can be: 'mem-usage' (%), 'swap-usage' (%). + +=item B<--critical-*> + +Threshold critical. +Can be: 'mem-usage' (%), 'swap-usage' (%). + + +=back + +=cut diff --git a/centreon-plugins/network/infoblox/snmp/mode/services.pm b/centreon-plugins/network/infoblox/snmp/mode/services.pm new file mode 100644 index 000000000..fd4ef9b09 --- /dev/null +++ b/centreon-plugins/network/infoblox/snmp/mode/services.pm @@ -0,0 +1,166 @@ +# +# Copyright 2017 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::infoblox::snmp::mode::services; + +use base qw(centreon::plugins::templates::hardware); + +use strict; +use warnings; + +sub set_system { + my ($self, %options) = @_; + + $self->{regexp_threshold_overload_check_section_option} = '^(service)$'; + + $self->{cb_hook2} = 'snmp_execute'; + + $self->{thresholds} = { + default => [ + ['unknown', 'OK'], + ['working', 'OK'], + ['inactive', 'OK'], + ['warning', 'WARNING'], + ['failed', 'CRITICAL'], + ], + }; + + $self->{components_path} = 'network::infoblox::snmp::mode::components'; + $self->{components_module} = ['service']; +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options, no_absent => 1, no_load_components => 1); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => + { + }); + + return $self; +} + +sub snmp_execute { + my ($self, %options) = @_; + + $self->{snmp} = $options{snmp}; + $self->{results} = $self->{snmp}->get_multiple_table(oids => $self->{request}); +} + +1; + +=head1 MODE + +Check physical service status. + +=over 8 + +=item B<--component> + +Which component to check (Default: '.*'). +Can be: 'service'. + +=item B<--filter> + +Exclude some parts (comma seperated list) +Can also exclude specific instance: --filter=service,fan1 + +=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='service,OK,warning' + +=back + +=cut + +package network::infoblox::snmp::mode::components::service; + +use strict; +use warnings; + +my %map_service_status = ( + 1 => 'working', 2 => 'warning', + 3 => 'failed', 4 => 'inactive', 5 => 'unknown', +); +my %map_service_name = ( + 1 => 'dhcp', 2 => 'dns', 3 => 'ntp', 4 => 'tftp', 5 => 'http-file-dist', + 6 => 'ftp', 7 => 'bloxtools-move', 8 => 'bloxtools', 9 => 'node-status', + 10 => 'disk-usage', 11 => 'enet-lan', 12 => 'enet-lan2', 13 => 'enet-ha', + 14 => 'enet-mgmt', 15 => 'lcd', 16 => 'memory', 17 => 'replication', 18 => 'db-object', + 19 => 'raid-summary', 20 => 'raid-disk1', 21 => 'raid-disk2', 22 => 'raid-disk3', + 23 => 'raid-disk4', 24 => 'raid-disk5', 25 => 'raid-disk6', 26 => 'raid-disk7', + 27 => 'raid-disk8', 28 => 'fan1', 29 => 'fan2', 30 => 'fan3', 31 => 'fan4', + 32 => 'fan5', 33 => 'fan6', 34 => 'fan7', 35 => 'fan8', 36 => 'power-supply1', + 37 => 'power-supply2', 38 => 'ntp-sync', 39 => 'cpu1-temp', 40 => 'cpu2-temp', + 41 => 'sys-temp', 42 => 'raid-battery', 43 => 'cpu-usage', 44 => 'ospf', + 45 => 'bgp', 46 => 'mgm-service', 47 => 'subgrid-conn', 48 => 'network-capacity', + 49 => 'reporting', 50 => 'dns-cache-acceleration', 51 => 'ospf6', + 52 => 'swap-usage', 53 => 'discovery-consolidator', 54 => 'discovery-collector', + 55 => 'discovery-capacity', 56 => 'threat-protection', 57 => 'cloud-api', + 58 => 'threat-analytics', 59 => 'taxii', 60 => 'bfd', 61 => 'outbound', +); + +my $mapping = { + ibNodeServiceName => { oid => '.1.3.6.1.4.1.7779.3.1.1.2.1.10.1.1', map => \%map_service_name }, + ibNodeServiceStatus => { oid => '.1.3.6.1.4.1.7779.3.1.1.2.1.10.1.2', map => \%map_service_status }, +}; +my $oid_ibMemberNodeServiceStatusEntry = '.1.3.6.1.4.1.7779.3.1.1.2.1.10.1'; + +sub load { + my ($self) = @_; + + push @{$self->{request}}, { oid => $oid_ibMemberNodeServiceStatusEntry, end => $mapping->{ibNodeServiceStatus}->{oid} }; +} + +sub check { + my ($self) = @_; + + $self->{output}->output_add(long_msg => "Checking services"); + $self->{components}->{service} = {name => 'services', total => 0, skip => 0}; + return if ($self->check_filter(section => 'service')); + + foreach my $oid ($self->{snmp}->oid_lex_sort(keys %{$self->{results}->{$oid_ibMemberNodeServiceStatusEntry}})) { + next if ($oid !~ /^$mapping->{ibNodeServiceName}->{oid}\.(.*)$/); + my $instance = $1; + my $result = $self->{snmp}->map_instance(mapping => $mapping, results => $self->{results}->{$oid_ibMemberNodeServiceStatusEntry}, instance => $instance); + + next if ($self->check_filter(section => 'service', instance => $result->{ibNodeServiceName})); + + $self->{components}->{service}->{total}++; + $self->{output}->output_add(long_msg => sprintf("service '%s' status is '%s' [instance = %s]", + $result->{ibNodeServiceName}, $result->{ibNodeServiceStatus}, $result->{ibNodeServiceName})); + my $exit = $self->get_severity(section => 'default', instance => $result->{ibNodeServiceName}, value => $result->{ibNodeServiceStatus}); + if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { + $self->{output}->output_add(severity => $exit, + short_msg => sprintf("Service '%s' status is '%s'", $result->{ibNodeServiceName}, $result->{ibNodeServiceStatus})); + } + } +} + +1; diff --git a/centreon-plugins/network/infoblox/snmp/plugin.pm b/centreon-plugins/network/infoblox/snmp/plugin.pm new file mode 100644 index 000000000..dacdb286f --- /dev/null +++ b/centreon-plugins/network/infoblox/snmp/plugin.pm @@ -0,0 +1,54 @@ +# +# Copyright 2017 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::infoblox::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::infoblox::snmp::mode::cpu', + 'dhcp-usage' => 'network::infoblox::snmp::mode::dhcpusage', + 'dns-usage' => 'network::infoblox::snmp::mode::dnsusage', + 'interfaces' => 'snmp_standard::mode::interfaces', + 'list-interfaces' => 'snmp_standard::mode::listinterfaces', + 'memory' => 'network::infoblox::snmp::mode::memory', + 'services' => 'network::infoblox::snmp::mode::services', + ); + + return $self; +} + +1; + +__END__ + +=head1 PLUGIN DESCRIPTION + +Check Infoblox equipments in SNMP. + +=cut diff --git a/centreon-plugins/network/netgear/mseries/snmp/mode/components/fan.pm b/centreon-plugins/network/netgear/mseries/snmp/mode/components/fan.pm new file mode 100644 index 000000000..04ab649b7 --- /dev/null +++ b/centreon-plugins/network/netgear/mseries/snmp/mode/components/fan.pm @@ -0,0 +1,86 @@ +# +# Copyright 2017 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::netgear::mseries::snmp::mode::components::fan; + +use strict; +use warnings; + +my %map_fan_status = ( + 1 => 'notpresent', 2 => 'operational', 3 => 'failed', 4 => 'powering', + 5 => 'nopower', 6 => 'notpowering', 7 => 'incompatible' +); + +my $mapping = { + boxServicesFanItemState => { oid => '.1.3.6.1.4.1.4526.10.43.1.6.1.3', map => \%map_fan_status }, + boxServicesFanSpeed => { oid => '.1.3.6.1.4.1.4526.10.43.1.6.1.4' }, +}; +my $oid_boxServicesFansEntry = '.1.3.6.1.4.1.4526.10.43.1.6.1'; + +sub load { + my ($self) = @_; + + push @{$self->{request}}, { oid => $oid_boxServicesFansEntry, begin => $mapping->{boxServicesFanItemState}->{oid}, end => $mapping->{boxServicesFanSpeed}->{oid} }; +} + +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')); + + my ($exit, $warn, $crit, $checked); + foreach my $oid ($self->{snmp}->oid_lex_sort(keys %{$self->{results}->{$oid_boxServicesFansEntry}})) { + next if ($oid !~ /^$mapping->{boxServicesFanItemState}->{oid}\.(.*)$/); + my $instance = $1; + my $result = $self->{snmp}->map_instance(mapping => $mapping, results => $self->{results}->{$oid_boxServicesFansEntry}, instance => $instance); + + next if ($self->check_filter(section => 'fan', instance => $instance)); + if ($result->{boxServicesFanItemState} =~ /notpresent/i) { + $self->absent_problem(section => 'fan', instance => $instance); + next; + } + + $self->{components}->{fan}->{total}++; + $self->{output}->output_add(long_msg => sprintf("fan '%s' status is '%s' [instance = %s, speed = %s]", + $instance, $result->{boxServicesFanItemState}, $instance, defined($result->{boxServicesFanSpeed}) ? $result->{boxServicesFanSpeed} : 'unknown')); + $exit = $self->get_severity(label => 'default', section => 'fan', value => $result->{boxServicesFanItemState}); + 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->{boxServicesFanItemState})); + } + + next if (!defined($result->{boxServicesFanSpeed}) || $result->{boxServicesFanSpeed} !~ /[0-9]+/); + + ($exit, $warn, $crit, $checked) = $self->get_severity_numeric(section => 'fan', instance => $instance, value => $result->{boxServicesFanSpeed}); + if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { + $self->{output}->output_add(severity => $exit, + short_msg => sprintf("Fan '%s' is '%s' rpm", $instance, $result->{boxServicesFanSpeed})); + } + $self->{output}->perfdata_add(label => 'fan_' . $instance, unit => 'rpm', + value => $result->{boxServicesFanSpeed}, + warning => $warn, + critical => $crit, min => 0 + ); + } +} + +1; diff --git a/centreon-plugins/network/netgear/mseries/snmp/mode/components/psu.pm b/centreon-plugins/network/netgear/mseries/snmp/mode/components/psu.pm new file mode 100644 index 000000000..e7e0ef28a --- /dev/null +++ b/centreon-plugins/network/netgear/mseries/snmp/mode/components/psu.pm @@ -0,0 +1,71 @@ +# +# Copyright 2017 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::netgear::mseries::snmp::mode::components::psu; + +use strict; +use warnings; + +my %map_psu_status = ( + 1 => 'notpresent', 2 => 'operational', 3 => 'failed', 4 => 'powering', + 5 => 'nopower', 6 => 'notpowering', 7 => 'incompatible' +); + +my $mapping = { + boxServicesPowSupplyItemState => { oid => '.1.3.6.1.4.1.4526.10.43.1.7.1.3', map => \%map_psu_status }, +}; + +sub load { + my ($self) = @_; + + push @{$self->{request}}, { oid => $mapping->{boxServicesPowSupplyItemState}->{oid} }; +} + +sub check { + my ($self) = @_; + + $self->{output}->output_add(long_msg => "Checking power supplies"); + $self->{components}->{psu} = {name => 'psu', total => 0, skip => 0}; + return if ($self->check_filter(section => 'psu')); + + my ($exit, $warn, $crit, $checked); + foreach my $oid ($self->{snmp}->oid_lex_sort(keys %{$self->{results}->{$mapping->{boxServicesPowSupplyItemState}->{oid}}})) { + next if ($oid !~ /^$mapping->{boxServicesPowSupplyItemState}->{oid}\.(.*)$/); + my $instance = $1; + my $result = $self->{snmp}->map_instance(mapping => $mapping, results => $self->{results}->{$mapping->{boxServicesPowSupplyItemState}->{oid}}, instance => $instance); + + next if ($self->check_filter(section => 'psu', instance => $instance)); + if ($result->{boxServicesPowSupplyItemState} =~ /notpresent/i) { + $self->absent_problem(section => 'psu', instance => $instance); + next; + } + + $self->{components}->{psu}->{total}++; + $self->{output}->output_add(long_msg => sprintf("power supply '%s' status is '%s' [instance = %s]", + $instance, $result->{boxServicesPowSupplyItemState}, $instance)); + $exit = $self->get_severity(label => 'default', section => 'psu', value => $result->{boxServicesPowSupplyItemState}); + 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->{boxServicesPowSupplyItemState})); + } + } +} + +1; diff --git a/centreon-plugins/network/netgear/mseries/snmp/mode/components/temperature.pm b/centreon-plugins/network/netgear/mseries/snmp/mode/components/temperature.pm new file mode 100644 index 000000000..36a1a6603 --- /dev/null +++ b/centreon-plugins/network/netgear/mseries/snmp/mode/components/temperature.pm @@ -0,0 +1,86 @@ +# +# Copyright 2017 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::netgear::mseries::snmp::mode::components::temperature; + +use strict; +use warnings; + +my %map_temp_status = ( + 0 => 'low', 1 => 'normal', 2 => 'warning', 3 => 'critical', + 4 => 'shutdown', 5 => 'notpresent', 6 => 'notoperational', +); + +my $mapping = { + boxServicesTempSensorState => { oid => '.1.3.6.1.4.1.4526.10.43.1.8.1.4', map => \%map_temp_status }, + boxServicesTempSensorTemperature => { oid => '.1.3.6.1.4.1.4526.10.43.1.8.1.5' }, +}; +my $oid_boxServicesTempSensorsEntry = '.1.3.6.1.4.1.4526.10.43.1.8.1'; + +sub load { + my ($self) = @_; + + push @{$self->{request}}, { oid => $oid_boxServicesTempSensorsEntry, begin => $mapping->{boxServicesTempSensorState}->{oid}, end => $mapping->{boxServicesTempSensorTemperature}->{oid} }; +} + +sub check { + my ($self) = @_; + + $self->{output}->output_add(long_msg => "Checking temperatures"); + $self->{components}->{temperature} = {name => 'temperatures', total => 0, skip => 0}; + return if ($self->check_filter(section => 'temperature')); + + my ($exit, $warn, $crit, $checked); + foreach my $oid ($self->{snmp}->oid_lex_sort(keys %{$self->{results}->{$oid_boxServicesTempSensorsEntry}})) { + next if ($oid !~ /^$mapping->{boxServicesTempSensorState}->{oid}\.(.*)$/); + my $instance = $1; + my $result = $self->{snmp}->map_instance(mapping => $mapping, results => $self->{results}->{$oid_boxServicesTempSensorsEntry}, instance => $instance); + + next if ($self->check_filter(section => 'temperature', instance => $instance)); + if ($result->{boxServicesTempSensorState} =~ /notpresent/i) { + $self->absent_problem(section => 'temperature', instance => $instance); + next; + } + + $self->{components}->{temperature}->{total}++; + $self->{output}->output_add(long_msg => sprintf("temperature '%s' status is '%s' [instance = %s, temperature = %s]", + $instance, $result->{boxServicesTempSensorState}, $instance, defined($result->{boxServicesTempSensorTemperature}) ? $result->{boxServicesTempSensorTemperature} : 'unknown')); + $exit = $self->get_severity(section => 'temperature', value => $result->{boxServicesTempSensorState}); + if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { + $self->{output}->output_add(severity => $exit, + short_msg => sprintf("Temperature '%s' status is '%s'", $instance, $result->{boxServicesTempSensorState})); + } + + next if (!defined($result->{boxServicesTempSensorTemperature}) || $result->{boxServicesTempSensorTemperature} !~ /[0-9]+/); + + ($exit, $warn, $crit, $checked) = $self->get_severity_numeric(section => 'temperature', instance => $instance, value => $result->{boxServicesTempSensorTemperature}); + if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { + $self->{output}->output_add(severity => $exit, + short_msg => sprintf("Temperature '%s' is '%s' rpm", $instance, $result->{boxServicesTempSensorTemperature})); + } + $self->{output}->perfdata_add(label => 'temp_' . $instance, unit => 'C', + value => $result->{boxServicesTempSensorTemperature}, + warning => $warn, + critical => $crit, + ); + } +} + +1; diff --git a/centreon-plugins/network/netgear/mseries/snmp/mode/cpu.pm b/centreon-plugins/network/netgear/mseries/snmp/mode/cpu.pm new file mode 100644 index 000000000..4ad787a62 --- /dev/null +++ b/centreon-plugins/network/netgear/mseries/snmp/mode/cpu.pm @@ -0,0 +1,123 @@ +# +# Copyright 2017 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::netgear::mseries::snmp::mode::cpu; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'global', type => 0, cb_prefix_output => 'prefix_cpu_output' } + ]; + + $self->{maps_counters}->{global} = [ + { label => '5s', set => { + key_values => [ { name => 'usage_5s' } ], + output_template => '%.2f %% (5sec)', output_error_template => "%s (5sec)", + perfdatas => [ + { label => 'cpu_5s', value => 'usage_5s_absolute', template => '%.2f', + unit => '%', min => 0, max => 100 }, + ], + } + }, + { label => '1m', set => { + key_values => [ { name => 'usage_1m' } ], + output_template => '%.2f %% (1m)', output_error_template => "%s (1min)", + perfdatas => [ + { label => 'cpu_1m', value => 'usage_1m_absolute', template => '%.2f', + unit => '%', min => 0, max => 100 }, + ], + } + }, + { label => '5m', set => { + key_values => [ { name => 'usage_5m' } ], + output_template => '%.2f %% (5min)', output_error_template => "%s (5min)", + perfdatas => [ + { label => 'cpu_5m', value => 'usage_5m_absolute', template => '%.2f', + unit => '%', min => 0, max => 100 }, + ], + } + }, + ]; +} + +sub prefix_cpu_output { + my ($self, %options) = @_; + + return "CPU "; +} + +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 => + { + }); + + return $self; +} + +sub manage_selection { + my ($self, %options) = @_; + + # STRING: " 5 Secs ( 43.2625%) 60 Secs ( 13.9157%) 300 Secs ( 8.9274%)" + my $oid_agentSwitchCpuProcessTotalUtilization = '.1.3.6.1.4.1.4526.10.1.1.4.9.0'; + my $snmp_result = $options{snmp}->get_leef(oids => [$oid_agentSwitchCpuProcessTotalUtilization], nothing_quit => 1); + + $snmp_result->{$oid_agentSwitchCpuProcessTotalUtilization} =~ /\s*5\s*Secs\s*\(\s*(.*?)%\s*\)\s*60\s*Secs\s*\(\s*(.*?)%\s*\)\s*300\s*Secs\s*\(\s*(.*?)%\s*\)/i; + $self->{global} = { usage_5s => $1, usage_1m => $2, usage_5m => $3 }; +} + +1; + +__END__ + +=head1 MODE + +Check CPU usage. + +=over 8 + +=item B<--filter-counters> + +Only display some counters (regexp can be used). +Example: --filter-counters='5m' + +=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/centreon-plugins/network/netgear/mseries/snmp/mode/hardware.pm b/centreon-plugins/network/netgear/mseries/snmp/mode/hardware.pm new file mode 100644 index 000000000..3f48cfb07 --- /dev/null +++ b/centreon-plugins/network/netgear/mseries/snmp/mode/hardware.pm @@ -0,0 +1,129 @@ +# +# Copyright 2017 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::netgear::mseries::snmp::mode::hardware; + +use base qw(centreon::plugins::templates::hardware); + +use strict; +use warnings; + +sub set_system { + my ($self, %options) = @_; + + $self->{regexp_threshold_overload_check_section_option} = '^(temperature|fan|psu)$'; + $self->{regexp_threshold_numeric_check_section_option} = '^(temperature|fan)$'; + + $self->{cb_hook2} = 'snmp_execute'; + + $self->{thresholds} = { + default => [ + ['notPresent', 'OK'], + ['operational', 'OK'], + ['failed', 'CRITICAL'], + ['notpowering', 'WARNING'], + ['powering', 'OK'], + ['nopower', 'OK'], + ['incompatible', 'WARNING'], + ], + temperature => [ + ['low', 'OK'], + ['normal', 'OK'], + ['warning', 'WARNING'], + ['critical', 'CRITICAL'], + ['notpresent', 'OK'], + ['shutdown', 'OK'], + ['notoperational', 'WARNING'], + ], + }; + + $self->{components_path} = 'network::netgear::mseries::snmp::mode::components'; + $self->{components_module} = ['fan', 'psu', 'temperature']; +} + +sub snmp_execute { + my ($self, %options) = @_; + + $self->{snmp} = $options{snmp}; + $self->{results} = $self->{snmp}->get_multiple_table(oids => $self->{request}); +} + +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 => + { + }); + + return $self; +} + +1; + +__END__ + +=head1 MODE + +Check hardware. + +=over 8 + +=item B<--component> + +Which component to check (Default: '.*'). +Can be: 'fan', 'psu', 'temperature'. + +=item B<--filter> + +Exclude some parts (comma seperated list) (Example: --filter=fan --filter=psu) +Can also exclude specific instance: --filter=fan,1.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,1 + +=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='psu,CRITICAL,^(?!(operational)$)' + +=item B<--warning> + +Set warning threshold for 'temperature', 'fan' (syntax: type,regexp,threshold) +Example: --warning='temperature,.*,40' + +=item B<--critical> + +Set critical threshold for 'temperature', 'fan' (syntax: type,regexp,threshold) +Example: --critical='temperature,.*,50' + +=back + +=cut diff --git a/centreon-plugins/network/netgear/mseries/snmp/mode/memory.pm b/centreon-plugins/network/netgear/mseries/snmp/mode/memory.pm new file mode 100644 index 000000000..d2e2e646e --- /dev/null +++ b/centreon-plugins/network/netgear/mseries/snmp/mode/memory.pm @@ -0,0 +1,138 @@ +# +# Copyright 2017 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::netgear::mseries::snmp::mode::memory; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; + +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 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}->{prct_used} = $options{new_datas}->{$self->{instance} . '_prct_used'}; + + $self->{result_values}->{used} = int($self->{result_values}->{prct_used} * $self->{result_values}->{total} / 100); + $self->{result_values}->{free} = $self->{result_values}->{total} - $self->{result_values}->{used}; + $self->{result_values}->{prct_free} = 100 - $self->{result_values}->{prct_used}; + + return 0; +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'memory', type => 0 } + ]; + + $self->{maps_counters}->{memory} = [ + { label => 'usage', set => { + key_values => [ { name => 'prct_used' }, { name => 'total' } ], + closure_custom_calc => $self->can('custom_usage_calc'), + closure_custom_output => $self->can('custom_usage_output'), + closure_custom_perfdata => $self->can('custom_usage_perfdata'), + closure_custom_threshold_check => $self->can('custom_usage_threshold'), + } + }, + ]; +} + +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 => + { + }); + + return $self; +} + +sub manage_selection { + my ($self, %options) = @_; + + my $oid_agentSwitchCpuProcessMemFree = '.1.3.6.1.4.1.4526.10.1.1.4.1.0'; # KB + my $oid_agentSwitchCpuProcessMemAvailable = '.1.3.6.1.4.1.4526.10.1.1.4.2.0'; # KB + my $snmp_result = $options{snmp}->get_leef(oids => [$oid_agentSwitchCpuProcessMemFree, $oid_agentSwitchCpuProcessMemAvailable], nothing_quit => 1); + + my $total = $snmp_result->{$oid_agentSwitchCpuProcessMemAvailable} * 1024; + $self->{memory} = { + prct_used => ($total - $snmp_result->{$oid_agentSwitchCpuProcessMemFree} * 1024) * 100 / $total, + total => $total, + }; +} + +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 diff --git a/centreon-plugins/network/netgear/mseries/snmp/plugin.pm b/centreon-plugins/network/netgear/mseries/snmp/plugin.pm new file mode 100644 index 000000000..454375a16 --- /dev/null +++ b/centreon-plugins/network/netgear/mseries/snmp/plugin.pm @@ -0,0 +1,52 @@ +# +# Copyright 2017 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::netgear::mseries::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::netgear::mseries::snmp::mode::cpu', + 'hardware' => 'network::netgear::mseries::snmp::mode::hardware', + 'interfaces' => 'snmp_standard::mode::interfaces', + 'list-interfaces' => 'snmp_standard::mode::listinterfaces', + 'memory' => 'network::netgear::mseries::snmp::mode::memory', + ); + + return $self; +} + +1; + +__END__ + +=head1 PLUGIN DESCRIPTION + +Check Netgear Fully Managed Switches (M4200, M4300, M6100,...) in SNMP. + +=cut diff --git a/centreon-plugins/network/paloalto/snmp/mode/memory.pm b/centreon-plugins/network/paloalto/snmp/mode/memory.pm new file mode 100644 index 000000000..4384a87f7 --- /dev/null +++ b/centreon-plugins/network/paloalto/snmp/mode/memory.pm @@ -0,0 +1,98 @@ +# +# Copyright 2017 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::paloalto::snmp::mode::memory; + +use base qw(snmp_standard::mode::storage); + +use strict; +use warnings; + +sub default_storage_type { + my ($self, %options) = @_; + + return '^(hrStorageRam|hrStorageFlashMemory)'; +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + return $self; +} + +1; + +__END__ + +=head1 MODE + +Check memory. + +=over 8 + +=item B<--warning-usage> + +Threshold warning. + +=item B<--critical-usage> + +Threshold critical. + +=item B<--units> + +Units of thresholds (Default: '%') ('%', 'B'). + +=item B<--free> + +Thresholds are on free space left. + +=item B<--storage> + +Set the storage (number expected) ex: 1, 2,... (empty means 'check all storage'). + +=item B<--name> + +Allows to use storage name with option --storage instead of storage oid index. + +=item B<--regexp> + +Allows to use regexp to filter storage (with option --name). + +=item B<--regexp-isensitive> + +Allows to use regexp non case-sensitive (with --regexp). + +=item B<--reload-cache-time> + +Time in minutes before reloading cache file (default: 180). + +=item B<--show-cache> + +Display cache storage datas. + +=item B<--filter-storage-type> + +Filter storage types with a regexp (Default: '^(hrStorageRam|hrStorageFlashMemory)$'). + +=back + +=cut diff --git a/centreon-plugins/network/paloalto/snmp/plugin.pm b/centreon-plugins/network/paloalto/snmp/plugin.pm index a65a3a281..42e4a13cb 100644 --- a/centreon-plugins/network/paloalto/snmp/plugin.pm +++ b/centreon-plugins/network/paloalto/snmp/plugin.pm @@ -31,14 +31,15 @@ sub new { $self->{version} = '0.5'; %{$self->{modes}} = ( - 'cluster-status' => 'network::paloalto::snmp::mode::clusterstatus', - 'cpu' => 'snmp_standard::mode::cpu', - 'interfaces' => 'snmp_standard::mode::interfaces', - 'list-interfaces' => 'snmp_standard::mode::listinterfaces', - 'hardware' => 'snmp_standard::mode::hardwaredevice', - 'panorama' => 'network::paloalto::snmp::mode::panorama', - 'sessions' => 'network::paloalto::snmp::mode::sessions', - ); + 'cluster-status' => 'network::paloalto::snmp::mode::clusterstatus', + 'cpu' => 'snmp_standard::mode::cpu', + 'hardware' => 'snmp_standard::mode::hardwaredevice', + 'interfaces' => 'snmp_standard::mode::interfaces', + 'list-interfaces' => 'snmp_standard::mode::listinterfaces', + 'memory' => 'network::paloalto::snmp::mode::memory', + 'panorama' => 'network::paloalto::snmp::mode::panorama', + 'sessions' => 'network::paloalto::snmp::mode::sessions', + ); return $self; } diff --git a/centreon-plugins/network/radware/alteon/snmp/mode/cpu.pm b/centreon-plugins/network/radware/alteon/snmp/mode/cpu.pm index 17952b101..2f74dcacd 100644 --- a/centreon-plugins/network/radware/alteon/snmp/mode/cpu.pm +++ b/centreon-plugins/network/radware/alteon/snmp/mode/cpu.pm @@ -29,46 +29,120 @@ sub set_counters { my ($self, %options) = @_; $self->{maps_counters_type} = [ - { name => 'global', type => 0, cb_prefix_output => 'prefix_cpu_output' } + { name => 'mp_cpu', type => 0, cb_prefix_output => 'prefix_mp_cpu_output', skipped_code => { -10 => 1 } }, + { name => 'sp_ga_avg', type => 0, skipped_code => { -10 => 1 } }, + { name => 'sp_ga', type => 1, cb_init => 'skip_sp_ga', cb_prefix_output => 'prefix_sp_ga_output', message_multiple => 'All SP GA CPU are ok' }, ]; - $self->{maps_counters}->{global} = [ - { label => '1s', set => { - key_values => [ { name => '1s' } ], + $self->{maps_counters}->{mp_cpu} = [ + { label => 'mp-1s', set => { + key_values => [ { name => 'mp_1s' } ], output_template => '%.2f%% (1sec)', perfdatas => [ - { label => 'cpu_1s', value => '1s_absolute', template => '%.2f', + { label => 'mp_cpu_1s', value => 'mp_1s_absolute', template => '%.2f', min => 0, max => 100, unit => '%' }, ], } }, - { label => '4s', set => { - key_values => [ { name => '4s' } ], + { label => 'mp-4s', set => { + key_values => [ { name => 'mp_4s' } ], output_template => '%.2f%% (4sec)', perfdatas => [ - { label => 'cpu_4s', value => '4s_absolute', template => '%.2f', + { label => 'mp_cpu_4s', value => 'mp_4s_absolute', template => '%.2f', min => 0, max => 100, unit => '%' }, ], } }, - { label => '64s', set => { - key_values => [ { name => '64s' } ], + { label => 'mp-64s', set => { + key_values => [ { name => 'mp_64s' } ], output_template => '%.2f%% (64sec)', perfdatas => [ - { label => 'cpu_64s', value => '64s_absolute', template => '%.2f', + { label => 'mp_cpu_64s', value => 'mp_64s_absolute', template => '%.2f', min => 0, max => 100, unit => '%' }, ], } }, ]; + + $self->{maps_counters}->{sp_ga_avg} = [ + { label => 'sp-ga-avg-1s', set => { + key_values => [ { name => 'sp_1s' } ], + output_template => 'SP GA Average CPU Usage: %.2f%% (1sec)', + perfdatas => [ + { label => 'avg_spga_cpu_1s', value => 'sp_1s_absolute', template => '%.2f', + min => 0, max => 100, unit => '%' }, + ], + } + }, + { label => 'sp-ga-avg-4s', set => { + key_values => [ { name => 'sp_4s' } ], + output_template => '%.2f%% (4sec)', + perfdatas => [ + { label => 'avg_spga_cpu_4s', value => 'sp_4s_absolute', template => '%.2f', + min => 0, max => 100, unit => '%' }, + ], + } + }, + { label => 'sp-ga-avg-64s', set => { + key_values => [ { name => 'sp_64s' } ], + output_template => '%.2f%% (64sec)', + perfdatas => [ + { label => 'avg_spga_cpu_64s', value => 'sp_64s_absolute', template => '%.2f', + min => 0, max => 100, unit => '%' }, + ], + } + }, + ]; + + $self->{maps_counters}->{sp_ga} = [ + { label => 'sp-ga-1s', set => { + key_values => [ { name => 'sp_1s' }, { name => 'display' } ], + output_template => '%.2f%% (1sec)', + perfdatas => [ + { label => 'spga_cpu_1s', value => 'sp_1s_absolute', template => '%.2f', + min => 0, max => 100, unit => '%', label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + { label => 'sp-ga-4s', set => { + key_values => [ { name => 'sp_4s' }, { name => 'display' } ], + output_template => '%.2f%% (4sec)', + perfdatas => [ + { label => 'spga_cpu_4s', value => 'sp_4s_absolute', template => '%.2f', + min => 0, max => 100, unit => '%', label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + { label => 'sp-ga-64s', set => { + key_values => [ { name => 'sp_64s' }, { name => 'display' } ], + output_template => '%.2f%% (64sec)', + perfdatas => [ + { label => 'spga_cpu_64s', value => 'sp_64s_absolute', template => '%.2f', + min => 0, max => 100, unit => '%', label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + ]; } -sub prefix_cpu_output { +sub prefix_mp_cpu_output { my ($self, %options) = @_; return "MP CPU Usage: "; } +sub prefix_sp_ga_output { + my ($self, %options) = @_; + + return "SP GA CPU '" . $options{instance_value}->{display} . "' Usage: "; +} + +sub skip_sp_ga { + my ($self, %options) = @_; + + scalar(keys %{$self->{sp_ga}}) <= 0 ? return(1) : return(0); +} + sub new { my ($class, %options) = @_; my $self = $class->SUPER::new(package => __PACKAGE__, %options); @@ -82,18 +156,56 @@ sub new { return $self; } +my $mapping = { + mpCpuStatsUtil1Second => { oid => '.1.3.6.1.4.1.1872.2.5.1.2.2.1' }, + mpCpuStatsUtil4Seconds => { oid => '.1.3.6.1.4.1.1872.2.5.1.2.2.2' }, + mpCpuStatsUtil64Seconds => { oid => '.1.3.6.1.4.1.1872.2.5.1.2.2.3' }, +}; +my $mapping2 = { + spGAStatsCpuUtil1Second => { oid => '.1.3.6.1.4.1.1872.2.5.1.2.13.1.1.3' }, + spGAStatsCpuUtil4Seconds => { oid => '.1.3.6.1.4.1.1872.2.5.1.2.13.1.1.4' }, + spGAStatsCpuUtil64Seconds => { oid => '.1.3.6.1.4.1.1872.2.5.1.2.13.1.1.5' }, +}; +my $oid_mpCpuStats = '.1.3.6.1.4.1.1872.2.5.1.2.2'; +my $oid_spGAStatsCpuUtilTableEntry = '.1.3.6.1.4.1.1872.2.5.1.2.13.1.1'; + sub manage_selection { my ($self, %options) = @_; + + my $snmp_result = $options{snmp}->get_multiple_table(oids => [ { oid => $oid_mpCpuStats }, { oid => $oid_spGAStatsCpuUtilTableEntry } ], + return_type => 1, nothing_quit => 1); + $self->{sp_ga} = {}; + my ($avg_sp_1s, $avg_sp_4s, $avg_sp_64s) = (0, 0, 0); + foreach my $oid (keys %{$snmp_result}) { + next if ($oid !~ /^$mapping2->{spGAStatsCpuUtil64Seconds}->{oid}\.(.*)$/); + my $instance = $1; + my $result = $options{snmp}->map_instance(mapping => $mapping2, results => $snmp_result, instance => $instance); - my $oid_mpCpuStatsUtil1Second = '.1.3.6.1.4.1.1872.2.5.1.2.2.1.0'; - my $oid_mpCpuStatsUtil4Seconds = '.1.3.6.1.4.1.1872.2.5.1.2.2.2.0'; - my $oid_mpCpuStatsUtil64Seconds = '.1.3.6.1.4.1.1872.2.5.1.2.2.3.0'; - my $snmp_result = $options{snmp}->get_leef(oids => [ - $oid_mpCpuStatsUtil1Second, $oid_mpCpuStatsUtil4Seconds, - $oid_mpCpuStatsUtil64Seconds], nothing_quit => 1); + $self->{sp_ga}->{$instance} = { + display => $instance, + sp_1s => $result->{spGAStatsCpuUtil1Second}, + sp_4s => $result->{spGAStatsCpuUtil4Seconds}, + sp_64s => $result->{spGAStatsCpuUtil64Seconds}, + }; + $avg_sp_1s += $result->{spGAStatsCpuUtil1Second}; + $avg_sp_4s += $result->{spGAStatsCpuUtil4Seconds}; + $avg_sp_64s += $result->{spGAStatsCpuUtil64Seconds}; + } - $self->{global} = { '1s' => $snmp_result->{$oid_mpCpuStatsUtil1Second}, '4s' => $snmp_result->{$oid_mpCpuStatsUtil4Seconds}, - '64s' => $snmp_result->{$oid_mpCpuStatsUtil64Seconds} }; + $self->{sp_ga_avg} = {}; + if (scalar(keys %{$self->{sp_ga}}) > 1) { + $self->{sp_ga_avg} = { + sp_1s => $avg_sp_1s / scalar(keys %{$self->{sp_ga}}), + sp_4s => $avg_sp_4s / scalar(keys %{$self->{sp_ga}}), + sp_64s => $avg_sp_64s / scalar(keys %{$self->{sp_ga}}), + }; + } + + $self->{mp_cpu} = { + mp_1s => $snmp_result->{$mapping->{mpCpuStatsUtil1Second}->{oid} . '.0'}, + mp_4s => $snmp_result->{$mapping->{mpCpuStatsUtil4Seconds}->{oid} . '.0'}, + mp_64s => $snmp_result->{$mapping->{mpCpuStatsUtil64Seconds}->{oid} . '.0'}, + }; } 1; @@ -114,14 +226,18 @@ Example: --filter-counters='^(64s)$' =item B<--warning-*> Threshold warning. -Can be: '1s', '4s', '64s'. +Can be: 'mp-1s', 'mp-4s', 'mp-64s', +'sp-ga-1s', 'sp-ga-4s', 'sp-ga-64s', +'sp-ga-avg-1s', 'sp-ga-avg-4s', 'sp-ga-avg-64s'. =item B<--critical-*> Threshold critical. -Can be: '1s', '4s', '64s'. +Can be: 'mp-1s', 'mp-4s', 'mp-64s', +'sp-ga-1s', 'sp-ga-4s', 'sp-ga-64s', +'sp-ga-avg-1s', 'sp-ga-avg-4s', 'sp-ga-avg-64s'. =back =cut - \ No newline at end of file + diff --git a/centreon-plugins/network/stonesoft/snmp/mode/connections.pm b/centreon-plugins/network/stonesoft/snmp/mode/connections.pm index 59d920169..8a31f4e59 100644 --- a/centreon-plugins/network/stonesoft/snmp/mode/connections.pm +++ b/centreon-plugins/network/stonesoft/snmp/mode/connections.pm @@ -160,7 +160,7 @@ sub manage_selection { my $oid_fwConnNumber = '.1.3.6.1.4.1.1369.5.2.1.4.0'; $self->{results} = $self->{snmp}->get_leef(oids => [$oid_fwConnNumber], nothing_quit => 1); - $self->{global} = { fwConnNumber => $self->{result}->{$oid_fwConnNumber} }; + $self->{global} = { fwConnNumber => $self->{results}->{$oid_fwConnNumber} }; } 1; diff --git a/centreon-plugins/network/hp/procurve/plugin.pm b/centreon-plugins/network/ubiquiti/edge/snmp/plugin.pm similarity index 76% rename from centreon-plugins/network/hp/procurve/plugin.pm rename to centreon-plugins/network/ubiquiti/edge/snmp/plugin.pm index ed633764a..c3cf26c72 100644 --- a/centreon-plugins/network/hp/procurve/plugin.pm +++ b/centreon-plugins/network/ubiquiti/edge/snmp/plugin.pm @@ -18,7 +18,7 @@ # limitations under the License. # -package network::hp::procurve::plugin; +package network::ubiquiti::edge::snmp::plugin; use strict; use warnings; @@ -31,11 +31,11 @@ sub new { $self->{version} = '1.0'; %{$self->{modes}} = ( - 'cpu' => 'network::hp::procurve::mode::cpu', - 'environment' => 'network::hp::procurve::mode::environment', + 'cpu' => 'centreon::common::broadcom::fastpath::snmp::mode::cpu', + 'hardware' => 'centreon::common::broadcom::fastpath::snmp::mode::hardware', 'interfaces' => 'snmp_standard::mode::interfaces', 'list-interfaces' => 'snmp_standard::mode::listinterfaces', - 'memory' => 'network::hp::procurve::mode::memory', + 'memory' => 'centreon::common::broadcom::fastpath::snmp::mode::memory', ); return $self; @@ -47,6 +47,6 @@ __END__ =head1 PLUGIN DESCRIPTION -Check Switch HP Procurve in SNMP. +Check Ubiquiti Edge Router in SNMP. =cut diff --git a/centreon-plugins/network/zyxel/snmp/mode/cpu.pm b/centreon-plugins/network/zyxel/snmp/mode/cpu.pm new file mode 100644 index 000000000..88dcbc887 --- /dev/null +++ b/centreon-plugins/network/zyxel/snmp/mode/cpu.pm @@ -0,0 +1,132 @@ +# +# Copyright 2017 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::zyxel::snmp::mode::cpu; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'global', type => 0, cb_prefix_output => 'prefix_cpu_output' } + ]; + + $self->{maps_counters}->{global} = [ + { label => '5s', set => { + key_values => [ { name => 'usage_5s' } ], + output_template => '%.2f %% (5sec)', output_error_template => "%s (5sec)", + perfdatas => [ + { label => 'cpu_5s', value => 'usage_5s_absolute', template => '%.2f', + unit => '%', min => 0, max => 100 }, + ], + } + }, + { label => '1m', set => { + key_values => [ { name => 'usage_1m' } ], + output_template => '%.2f %% (1m)', output_error_template => "%s (1min)", + perfdatas => [ + { label => 'cpu_1m', value => 'usage_1m_absolute', template => '%.2f', + unit => '%', min => 0, max => 100 }, + ], + } + }, + { label => '5m', set => { + key_values => [ { name => 'usage_5m' } ], + output_template => '%.2f %% (5min)', output_error_template => "%s (5min)", + perfdatas => [ + { label => 'cpu_5m', value => 'usage_5m_absolute', template => '%.2f', + unit => '%', min => 0, max => 100 }, + ], + } + }, + ]; +} + +sub prefix_cpu_output { + my ($self, %options) = @_; + + return "CPU "; +} + +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 => + { + }); + + return $self; +} + +sub manage_selection { + my ($self, %options) = @_; + + my $oid_sysCPU5SecUsage = '.1.3.6.1.4.1.890.1.6.22.1.3.0'; + my $oid_sysCPU1MinUsage = '.1.3.6.1.4.1.890.1.6.22.1.4.0'; + my $oid_sysCPU5MinUsage = '.1.3.6.1.4.1.890.1.6.22.1.5.0'; + my $oid_sysMgmtCPU5SecUsage = '.1.3.6.1.4.1.890.1.15.3.2.7.0'; + my $oid_sysMgmtCPU1MinUsage = '.1.3.6.1.4.1.890.1.15.3.2.8.0'; + my $oid_sysMgmtCPU5MinUsage = '.1.3.6.1.4.1.890.1.15.3.2.9.0'; + my $snmp_result = $options{snmp}->get_leef(oids => [$oid_sysCPU5SecUsage, + $oid_sysCPU1MinUsage, $oid_sysCPU5MinUsage, $oid_sysMgmtCPU5SecUsage, + $oid_sysMgmtCPU1MinUsage, $oid_sysMgmtCPU5MinUsage], nothing_quit => 1); + + $self->{global} = { + usage_5s => defined($snmp_result->{$oid_sysCPU5SecUsage}) ? $snmp_result->{$oid_sysCPU5SecUsage} : $snmp_result->{$oid_sysMgmtCPU5SecUsage}, + usage_1m => defined($snmp_result->{$oid_sysCPU1MinUsage}) ? $snmp_result->{$oid_sysCPU1MinUsage} : $snmp_result->{$oid_sysMgmtCPU1MinUsage}, + usage_5m => defined($snmp_result->{$oid_sysCPU5MinUsage}) ? $snmp_result->{$oid_sysCPU5MinUsage} : $snmp_result->{$oid_sysMgmtCPU5MinUsage}, + }; +} + +1; + +__END__ + +=head1 MODE + +Check CPU usage. + +=over 8 + +=item B<--filter-counters> + +Only display some counters (regexp can be used). +Example: --filter-counters='5m' + +=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/centreon-plugins/network/zyxel/snmp/mode/listvpn.pm b/centreon-plugins/network/zyxel/snmp/mode/listvpn.pm new file mode 100644 index 000000000..2b9323f09 --- /dev/null +++ b/centreon-plugins/network/zyxel/snmp/mode/listvpn.pm @@ -0,0 +1,132 @@ +# +# Copyright 2017 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::zyxel::snmp::mode::listvpn; + +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 => + { + "filter-name:s" => { name => 'filter_name' }, + }); + $self->{vpn} = {}; + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::init(%options); +} + +my %map_active_status = (0 => 'inactive', 1 => 'active'); +my %map_connect_status = (0 => 'disconnected', 1 => 'connected'); + +my $mapping = { + vpnStatusConnectionName => { oid => '.1.3.6.1.4.1.890.1.6.22.2.4.1.2' }, + vpnStatusActiveStatus => { oid => '.1.3.6.1.4.1.890.1.6.22.2.4.1.5', map => \%map_active_status }, + vpnStatusConnectStatus => { oid => '.1.3.6.1.4.1.890.1.6.22.2.4.1.6', map => \%map_connect_status }, +}; + +my $oid_vpnStatusEntry = '.1.3.6.1.4.1.890.1.6.22.2.4.1'; + +sub manage_selection { + my ($self, %options) = @_; + + my $snmp_result = $options{snmp}->get_table(oid => $oid_vpnStatusEntry, nothing_quit => 1); + foreach my $oid (keys %{$snmp_result}) { + next if ($oid !~ /^$mapping->{vpnStatusConnectionName}->{oid}\.(.*)$/); + my $instance = $1; + my $result = $options{snmp}->map_instance(mapping => $mapping, results => $snmp_result, instance => $instance); + + if (defined($self->{option_results}->{filter_name}) && $self->{option_results}->{filter_name} ne '' && + $result->{vpnStatusConnectionName} !~ /$self->{option_results}->{filter_name}/) { + $self->{output}->output_add(long_msg => "skipping '" . $result->{vpnStatusConnectionName} . "': no matching filter.", debug => 1); + next; + } + + $self->{vpn}->{$result->{vpnStatusConnectionName}} = { + name => $result->{vpnStatusConnectionName}, + active_status => $result->{vpnStatusActiveStatus}, + connect_status => $result->{vpnStatusConnectStatus}, + }; + } +} + +sub run { + my ($self, %options) = @_; + + $self->manage_selection(%options); + foreach my $instance (sort keys %{$self->{vpn}}) { + $self->{output}->output_add(long_msg => '[name = ' . $self->{vpn}->{$instance}->{name} . "]" . + " [active status = '" . $self->{vpn}->{$instance}->{active_status} . "']" . + " [connect status = '" . $self->{vpn}->{$instance}->{connect_status} . "']" + ); + } + + $self->{output}->output_add(severity => 'OK', + short_msg => 'List VPNs:'); + $self->{output}->display(nolabel => 1, force_ignore_perfdata => 1, force_long_output => 1); + $self->{output}->exit(); +} + +sub disco_format { + my ($self, %options) = @_; + + $self->{output}->add_disco_format(elements => ['name', 'active_status', 'connect_status']); +} + +sub disco_show { + my ($self, %options) = @_; + + $self->manage_selection(%options); + foreach my $instance (sort keys %{$self->{vpn}}) { + $self->{output}->add_disco_entry( + %{$self->{vpn}->{$instance}} + ); + } +} + +1; + +__END__ + +=head1 MODE + +List VPNs. + +=over 8 + +=item B<--filter-name> + +Filter by VPN name. + +=back + +=cut + diff --git a/centreon-plugins/network/zyxel/snmp/mode/memory.pm b/centreon-plugins/network/zyxel/snmp/mode/memory.pm new file mode 100644 index 000000000..5bfe7eb76 --- /dev/null +++ b/centreon-plugins/network/zyxel/snmp/mode/memory.pm @@ -0,0 +1,111 @@ +# +# Copyright 2017 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::zyxel::snmp::mode::memory; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'memory', type => 0 } + ]; + + $self->{maps_counters}->{memory} = [ + { label => 'mem-usage', set => { + key_values => [ { name => 'ram_used' } ], + output_template => 'Memory Used: %.2f%%', + perfdatas => [ + { label => 'memory_used', value => 'ram_used_absolute', template => '%.2f', + min => 0, max => 100, unit => '%' }, + ], + } + }, + { label => 'flash-usage', set => { + key_values => [ { name => 'flash_used' } ], + output_template => 'Flash Used: %.2f%%', + perfdatas => [ + { label => 'flash_used', value => 'flash_used_absolute', template => '%.2f', + min => 0, max => 100, unit => '%' }, + ], + } + }, + ]; +} + +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 => + { + }); + + return $self; +} + +sub manage_selection { + my ($self, %options) = @_; + + my $oid_sysRAMUsage = '.1.3.6.1.4.1.890.1.6.22.1.2.0'; + my $oid_sysFLASHUsage = '.1.3.6.1.4.1.890.1.6.22.1.7.0'; + my $oid_sysMgmtMemUsage = '.1.3.6.1.4.1.890.1.15.3.2.5.0'; + my $oid_sysMgmtFlashUsage = '.1.3.6.1.4.1.890.1.15.3.2.6.0'; + my $snmp_result = $options{snmp}->get_leef(oids => [ + $oid_sysRAMUsage, $oid_sysFLASHUsage, + $oid_sysMgmtMemUsage, $oid_sysMgmtFlashUsage, + ], nothing_quit => 1); + + $self->{memory} = { + ram_used => defined($snmp_result->{$oid_sysRAMUsage}) ? $snmp_result->{$oid_sysRAMUsage} : $snmp_result->{$oid_sysMgmtMemUsage}, + flash_used => defined($snmp_result->{$oid_sysFLASHUsage}) ? $snmp_result->{$oid_sysFLASHUsage} : $snmp_result->{$oid_sysMgmtFlashUsage}, + }; +} + +1; + +__END__ + +=head1 MODE + +Check memory usage. + +=over 8 + +=item B<--warning-*> + +Threshold warning. +Can be: 'mem-usage' (%), 'flash-usage' (%). + +=item B<--critical-*> + +Threshold critical. +Can be: 'mem-usage' (%), 'flash-usage' (%). + + +=back + +=cut diff --git a/centreon-plugins/network/zyxel/snmp/mode/sessions.pm b/centreon-plugins/network/zyxel/snmp/mode/sessions.pm new file mode 100644 index 000000000..a26c71883 --- /dev/null +++ b/centreon-plugins/network/zyxel/snmp/mode/sessions.pm @@ -0,0 +1,92 @@ +# +# Copyright 2017 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::zyxel::snmp::mode::sessions; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'global', type => 0 }, + ]; + + $self->{maps_counters}->{global} = [ + { label => 'usage', set => { + key_values => [ { name => 'sessions' } ], + output_template => 'Current active sessions : %s', + perfdatas => [ + { label => 'sessions', value => 'sessions_absolute', template => '%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 => + { + }); + + return $self; +} + +sub manage_selection { + my ($self, %options) = @_; + + my $oid_sysSessionNum = '.1.3.6.1.4.1.890.1.6.22.1.6.0'; + my $oid_sysActiveSessionNum = '.1.3.6.1.4.1.890.1.6.22.1.6.0'; + my $snmp_result = $options{snmp}->get_leef(oids => [$oid_sysSessionNum, $oid_sysActiveSessionNum], nothing_quit => 1); + + $self->{global} = { + sessions => defined($snmp_result->{$oid_sysSessionNum}) ? $snmp_result->{$oid_sysSessionNum} : $snmp_result->{$oid_sysActiveSessionNum}, + }; +} + +1; + +__END__ + +=head1 MODE + +Check sessions. + +=over 8 + +=item B<--warning-usage> + +Threshold warning. + +=item B<--critical-usage> + +Threshold critical. + +=back + +=cut diff --git a/centreon-plugins/network/zyxel/snmp/mode/vpnstatus.pm b/centreon-plugins/network/zyxel/snmp/mode/vpnstatus.pm new file mode 100644 index 000000000..4671aef59 --- /dev/null +++ b/centreon-plugins/network/zyxel/snmp/mode/vpnstatus.pm @@ -0,0 +1,249 @@ +# +# Copyright 2017 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::zyxel::snmp::mode::vpnstatus; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; +use Digest::MD5 qw(md5_hex); + +my $instance_mode; + +sub custom_status_threshold { + my ($self, %options) = @_; + my $status = 'ok'; + my $message; + + eval { + local $SIG{__WARN__} = sub { $message = $_[0]; }; + local $SIG{__DIE__} = sub { $message = $_[0]; }; + + if (defined($instance_mode->{option_results}->{critical_status}) && $instance_mode->{option_results}->{critical_status} ne '' && + eval "$instance_mode->{option_results}->{critical_status}") { + $status = 'critical'; + } elsif (defined($instance_mode->{option_results}->{warning_status}) && $instance_mode->{option_results}->{warning_status} ne '' && + eval "$instance_mode->{option_results}->{warning_status}") { + $status = 'warning'; + } + }; + if (defined($message)) { + $self->{output}->output_add(long_msg => 'filter status issue: ' . $message); + } + + return $status; +} + +sub custom_status_output { + my ($self, %options) = @_; + + my $msg = 'connection status : ' . $self->{result_values}->{connectstatus} . ' [activation status: ' . $self->{result_values}->{activestatus} . ']'; + return $msg; +} + +sub custom_status_calc { + my ($self, %options) = @_; + + $self->{result_values}->{activestatus} = $options{new_datas}->{$self->{instance} . '_activestatus'}; + $self->{result_values}->{connectstatus} = $options{new_datas}->{$self->{instance} . '_connectstatus'}; + $self->{result_values}->{display} = $options{new_datas}->{$self->{instance} . '_display'}; + return 0; +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'vpn', type => 1, cb_prefix_output => 'prefix_vpn_output', message_multiple => 'All VPN tunnels are OK' }, + ]; + + $self->{maps_counters}->{vpn} = [ + { label => 'status', threshold => 0, set => { + key_values => [ { name => 'activestatus' }, { name => 'connectstatus' }, { name => 'display' } ], + closure_custom_calc => $self->can('custom_status_calc'), + closure_custom_output => $self->can('custom_status_output'), + closure_custom_perfdata => sub { return 0; }, + closure_custom_threshold_check => $self->can('custom_status_threshold'), + } + }, + { label => 'traffic-in', set => { + key_values => [ { name => 'traffic_in', diff => 1 }, { name => 'display' } ], + per_second => 1, output_change_bytes => 2, + output_template => 'Traffic In: %s %s/s', + perfdatas => [ + { label => 'traffic_in', value => 'traffic_in_per_second', template => '%.2f', + min => 0, unit => 'b/s', label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + { label => 'traffic-out', set => { + key_values => [ { name => 'traffic_out', diff => 1 }, { name => 'display' } ], + per_second => 1, output_change_bytes => 2, + output_template => 'Traffic Out: %s %s/s', + perfdatas => [ + { label => 'traffic_out', value => 'traffic_out_per_second', template => '%.2f', + min => 0, unit => 'b/s', label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + } + ]; +} + +sub prefix_vpn_output { + my ($self, %options) = @_; + + return "VPN '" . $options{instance_value}->{display} . "' "; +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options, statefile => 1); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => + { + "filter-name:s" => { name => 'filter_name' }, + "warning-status:s" => { name => 'warning_status', default => '' }, + "critical-status:s" => { name => 'critical_status', default => '%{connectstatus} eq "disconnected"' }, + }); + return $self; +} + +sub change_macros { + my ($self, %options) = @_; + + foreach (('warning_status', 'critical_status')) { + if (defined($self->{option_results}->{$_})) { + $self->{option_results}->{$_} =~ s/%\{(.*?)\}/\$self->{result_values}->{$1}/g; + } + } +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::check_options(%options); + + $self->change_macros(); + $instance_mode = $self; +} + +my %map_active_status = (0 => 'inactive', 1 => 'active'); +my %map_connect_status = (0 => 'disconnected', 1 => 'connected'); + +my $mapping = { + vpnStatusConnectionName => { oid => '.1.3.6.1.4.1.890.1.6.22.2.4.1.2' }, + vpnStatusActiveStatus => { oid => '.1.3.6.1.4.1.890.1.6.22.2.4.1.5', map => \%map_active_status }, + vpnStatusConnectStatus => { oid => '.1.3.6.1.4.1.890.1.6.22.2.4.1.6', map => \%map_connect_status }, +}; + +my $mapping2 = { + vpnSaMonitorConnectionName => { oid => '.1.3.6.1.4.1.890.1.6.22.2.6.1.2' }, + vpnSaMonitorInBytes => { oid => '.1.3.6.1.4.1.890.1.6.22.2.6.1.7' }, + vpnSaMonitorOutBytes => { oid => '.1.3.6.1.4.1.890.1.6.22.2.6.1.9' }, +}; + +my $oid_vpnStatusEntry = '.1.3.6.1.4.1.890.1.6.22.2.4.1'; +my $oid_vpnSaMonitorEntry = '.1.3.6.1.4.1.890.1.6.22.2.6.1'; + +sub manage_selection { + my ($self, %options) = @_; + + $self->{cache_name} = "zyxel_" . $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')) . '_' . + (defined($self->{option_results}->{filter_name}) ? md5_hex($self->{option_results}->{filter_name}) : md5_hex('all')); + + $self->{vpn} = {}; + my $snmp_result = $options{snmp}->get_multiple_table(oids => [ + { oid => $oid_vpnStatusEntry }, + { oid => $oid_vpnSaMonitorEntry }, + ], nothing_quit => 1); + + foreach my $oid (sort keys %{$snmp_result->{$oid_vpnStatusEntry}}) { + next if ($oid !~ /^$mapping->{vpnStatusConnectionName}->{oid}\.(.*)$/); + my $instance = $1; + my $result = $options{snmp}->map_instance(mapping => $mapping, results => $snmp_result->{$oid_vpnStatusEntry}, instance => $instance); + if (defined($self->{option_results}->{filter_name}) && $self->{option_results}->{filter_name} ne '' && + $result->{vpnStatusConnectionName} !~ /$self->{option_results}->{filter_name}/) { + $self->{output}->output_add(long_msg => "skipping '" . $result->{vpnStatusConnectionName} . "': no matching filter.", debug => 1); + next; + } + + $self->{vpn}->{$result->{vpnStatusConnectionName}} = { + display => $result->{vpnStatusConnectionName}, + activestatus => $result->{vpnStatusActiveStatus}, + connectstatus => $result->{vpnStatusConnectStatus}, + }; + } + + foreach my $oid (sort keys %{$snmp_result->{$oid_vpnSaMonitorEntry}}) { + next if ($oid !~ /^$mapping2->{vpnSaMonitorConnectionName}->{oid}\.(.*)$/); + my $instance = $1; + my $result = $options{snmp}->map_instance(mapping => $mapping2, results => $snmp_result->{$oid_vpnSaMonitorEntry}, instance => $instance); + next if (!defined($self->{vpn}->{$result->{vpnSaMonitorConnectionName}})); + + $self->{vpn}->{$result->{vpnSaMonitorConnectionName}}->{traffic_in} = $result->{vpnSaMonitorInBytes} * 8; + $self->{vpn}->{$result->{vpnSaMonitorConnectionName}}->{traffic_out} = $result->{vpnSaMonitorOutBytes} * 8; + } + + if (scalar(keys %{$self->{vpn}}) <= 0) { + $self->{output}->add_option_msg(short_msg => "No vpn found."); + $self->{output}->option_exit(); + } +} + +1; + +__END__ + +=head1 MODE + +Check VPN state and traffic. + +=over 8 + +=item B<--filter-name> + +Filter vpn name with regexp. + +=item B<--warning-*> + +Threshold warning. +Can be: 'traffic-in', 'traffic-out'. + +=item B<--critical-*> + +Threshold critical. +Can be: 'traffic-in', 'traffic-out'. + +=item B<--warning-status> + +Set warning threshold for status. +Can used special variables like: %{activestatus}, %{connectstatus}, %{display} + +=item B<--critical-status> + +Set critical threshold for status (Default: '%{connectstatus} eq "disconnected"'). +Can used special variables like: %{activestatus}, %{connectstatus}, %{display} + +=back + +=cut diff --git a/centreon-plugins/network/zyxel/snmp/plugin.pm b/centreon-plugins/network/zyxel/snmp/plugin.pm new file mode 100644 index 000000000..1a58c741b --- /dev/null +++ b/centreon-plugins/network/zyxel/snmp/plugin.pm @@ -0,0 +1,54 @@ +# +# Copyright 2017 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::zyxel::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::zyxel::snmp::mode::cpu', + 'interfaces' => 'snmp_standard::mode::interfaces', + 'list-interfaces' => 'snmp_standard::mode::listinterfaces', + 'list-vpn' => 'network::zyxel::snmp::mode::listvpn', + 'memory' => 'network::zyxel::snmp::mode::memory', + 'sessions' => 'network::zyxel::snmp::mode::sessions', + 'vpn-status' => 'network::zyxel::snmp::mode::vpnstatus', + ); + + return $self; +} + +1; + +__END__ + +=head1 PLUGIN DESCRIPTION + +Check Zyxel equipments in SNMP. + +=cut diff --git a/centreon-plugins/os/windows/local/mode/cmdreturn.pm b/centreon-plugins/os/windows/local/mode/cmdreturn.pm new file mode 100644 index 000000000..e03be3dd7 --- /dev/null +++ b/centreon-plugins/os/windows/local/mode/cmdreturn.pm @@ -0,0 +1,173 @@ +# +# Copyright 2017 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 os::windows::local::mode::cmdreturn; + +use base qw(centreon::plugins::mode); + +use strict; +use warnings; +use centreon::plugins::misc; +use Time::HiRes qw(gettimeofday tv_interval); + +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-time:s" => { name => 'warning_time' }, + "critical-time:s" => { name => 'critical_time' }, + "timeout:s" => { name => 'timeout', default => 30 }, + "command:s" => { name => 'command' }, + "command-path:s" => { name => 'command_path' }, + "command-options:s" => { name => 'command_options' }, + "manage-returns:s" => { name => 'manage_returns', default => '' }, + }); + $self->{manage_returns} = {}; + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::init(%options); + + if (!defined($self->{option_results}->{command})) { + $self->{output}->add_option_msg(short_msg => "Need to specify command option."); + $self->{output}->option_exit(); + } + + foreach my $entry (split(/#/, $self->{option_results}->{manage_returns})) { + next if (!($entry =~ /(.*?),(.*?),(.*)/)); + next if (!$self->{output}->is_litteral_status(status => $2)); + if ($1 ne '') { + $self->{manage_returns}->{$1} = {return => $2, msg => $3}; + } else { + $self->{manage_returns}->{default} = {return => $2, msg => $3}; + } + } + if ($self->{option_results}->{manage_returns} eq '' || scalar(keys %{$self->{manage_returns}}) == 0) { + $self->{output}->add_option_msg(short_msg => "Need to specify manage-returns option correctly."); + $self->{output}->option_exit(); + } + + if (($self->{perfdata}->threshold_validate(label => 'warning-time', value => $self->{option_results}->{warning_time})) == 0) { + $self->{output}->add_option_msg(short_msg => "Wrong warning threshold '" . $self->{option_results}->{warning_time} . "'."); + $self->{output}->option_exit(); + } + if (($self->{perfdata}->threshold_validate(label => 'critical-time', value => $self->{option_results}->{critical_time})) == 0) { + $self->{output}->add_option_msg(short_msg => "Wrong critical threshold '" . $self->{option_results}->{critical_time} . "'."); + $self->{output}->option_exit(); + } +} + +sub run { + my ($self, %options) = @_; + + my $timing0 = [gettimeofday]; + my ($stdout, $exit_code) = centreon::plugins::misc::execute(output => $self->{output}, + options => $self->{option_results}, + command => $self->{option_results}->{command}, + command_path => $self->{option_results}->{command_path}, + command_options => $self->{option_results}->{command_options}, + no_quit => 1); + my $timeelapsed = tv_interval($timing0, [gettimeofday]); + + my $long_msg = $stdout; + $long_msg =~ s/\|/-/mg; + $self->{output}->output_add(long_msg => $long_msg); + + if (defined($self->{manage_returns}->{$exit_code})) { + $self->{output}->output_add(severity => $self->{manage_returns}->{$exit_code}->{return}, + short_msg => $self->{manage_returns}->{$exit_code}->{msg}); + } elsif (defined($self->{manage_returns}->{default})) { + $self->{output}->output_add(severity => $self->{manage_returns}->{default}->{return}, + short_msg => $self->{manage_returns}->{default}->{msg}); + } else { + $self->{output}->output_add(severity => 'UNKNWON', + short_msg => 'Exit code from command'); + } + + if (defined($exit_code)) { + $self->{output}->perfdata_add(label => "code", + value => $exit_code); + } + + my $exit = $self->{perfdata}->threshold_check(value => $timeelapsed, + threshold => [ { label => 'critical-time', exit_litteral => 'critical' }, { label => 'warning-time', exit_litteral => 'warning' } ]); + if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { + $self->{output}->output_add(severity => $exit, + short_msg => sprintf("Response time %.3fs", $timeelapsed)); + } + + $self->{output}->perfdata_add(label => 'time', unit => 's', + value => sprintf('%.3f', $timeelapsed), + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning_time'), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical_time'), + min => 0); + + $self->{output}->display(); + $self->{output}->exit(); +} + +1; + +__END__ + +=head1 MODE + +Check command returns. + +=over 8 + +=item B<--manage-returns> + +Set action according command exit code. +Example: 0,OK,File xxx exist#1,CRITICAL,File xxx not exist#,UNKNOWN,Command problem + +=item B<--timeout> + +Timeout in seconds for the command (Default: 30). + +=item B<--command> + +Command to test (Default: none). + +=item B<--command-path> + +Command path (Default: none). + +=item B<--command-options> + +Command options (Default: none). + +=item B<--warning-time> + +Threshold warning in seconds. + +=item B<--critical-time> + +Threshold critical in seconds. + +=back + +=cut diff --git a/centreon-plugins/os/windows/local/mode/sessions.pm b/centreon-plugins/os/windows/local/mode/sessions.pm index a9d87dd29..e9b0d573e 100644 --- a/centreon-plugins/os/windows/local/mode/sessions.pm +++ b/centreon-plugins/os/windows/local/mode/sessions.pm @@ -285,12 +285,14 @@ Filter session name (can be a regexp). =item B<--warning-*> Threshold warning. -Can be: 'inactive', 'active'. +Can be: 'sessions-created', 'sessions-disconnected', +'sessions-reconnected', 'sessions-active'. =item B<--critical-*> Threshold critical. -Can be: 'inactive', 'active', 'time' (in seconds since the session starts). +Can be: 'sessions-created', 'sessions-disconnected', +'sessions-reconnected', 'sessions-active'. =back diff --git a/centreon-plugins/os/windows/local/plugin.pm b/centreon-plugins/os/windows/local/plugin.pm index 71795803d..0d428c699 100644 --- a/centreon-plugins/os/windows/local/plugin.pm +++ b/centreon-plugins/os/windows/local/plugin.pm @@ -31,6 +31,7 @@ sub new { $self->{version} = '0.1'; %{$self->{modes}} = ( + 'cmd-return' => 'os::windows::local::mode::cmdreturn', 'pending-reboot' => 'os::windows::local::mode::pendingreboot', 'sessions' => 'os::windows::local::mode::sessions', 'time' => 'os::windows::local::mode::ntp', diff --git a/centreon-plugins/snmp_standard/mode/dynamiccommand.pm b/centreon-plugins/snmp_standard/mode/dynamiccommand.pm index be9b70b2a..9169dd2a6 100644 --- a/centreon-plugins/snmp_standard/mode/dynamiccommand.pm +++ b/centreon-plugins/snmp_standard/mode/dynamiccommand.pm @@ -86,10 +86,10 @@ sub create_command { my ($self, %options) = @_; my $oids2set = {}; - $oids2set->{$oid_nsExtendStatus . '.' . $options{instance}} = 4; - $oids2set->{$oid_nsExtendArgs . '.' . $options{instance}} = $self->{option_results}->{args}; - $oids2set->{$oid_nsExtendCommand . '.' . $options{instance}} = $self->{option_results}->{command}; - $oids2set->{$oid_nsExtendExecType . '.' . $options{instance}} = defined($self->{option_results}->{shell}) ? 2 : 1; + $oids2set->{$oid_nsExtendStatus . '.' . $options{instance}} = { value => 4, type => 'INTEGER' }; + $oids2set->{$oid_nsExtendArgs . '.' . $options{instance}} = { value => $self->{option_results}->{args}, type => 'OCTETSTR' }; + $oids2set->{$oid_nsExtendCommand . '.' . $options{instance}} = { value => $self->{option_results}->{command}, type => 'OCTETSTR' }; + $oids2set->{$oid_nsExtendExecType . '.' . $options{instance}} = { value => (defined($self->{option_results}->{shell}) ? 2 : 1), type => 'INTEGER' }; $self->{snmp}->set(oids => $oids2set); } @@ -106,15 +106,15 @@ sub update_command { my $oids2set = {}; if (!defined($options{result}->{$oid_nsExtendCommand . '.' . $options{instance}}) || $options{result}->{$oid_nsExtendCommand . '.' . $options{instance}} ne $self->{option_results}->{command}) { - $oids2set->{$oid_nsExtendCommand . '.' . $options{instance}} = $self->{option_results}->{command}; + $oids2set->{$oid_nsExtendCommand . '.' . $options{instance}} = { value => $self->{option_results}->{command}, type => 'OCTETSTR' }; } if (!defined($options{result}->{$oid_nsExtendArgs . '.' . $options{instance}}) || $options{result}->{$oid_nsExtendArgs . '.' . $options{instance}} ne $self->{option_results}->{args}) { - $oids2set->{$oid_nsExtendArgs . '.' . $options{instance}} = $self->{option_results}->{args}; + $oids2set->{$oid_nsExtendArgs . '.' . $options{instance}} = { value => $self->{option_results}->{args}, type => 'OCTETSTR' }; } if (!defined($options{result}->{$oid_nsExtendExecType . '.' . $options{instance}}) || $options{result}->{$oid_nsExtendExecType . '.' . $options{instance}} ne $shell) { - $oids2set->{$oid_nsExtendExecType . '.' . $options{instance}} = $shell; + $oids2set->{$oid_nsExtendExecType . '.' . $options{instance}} = { value => $shell, type => 'INTEGER' }; } if (scalar(keys %$oids2set) > 0) { diff --git a/centreon-plugins/snmp_standard/mode/entity.pm b/centreon-plugins/snmp_standard/mode/entity.pm index de889ac4f..8610e38f9 100644 --- a/centreon-plugins/snmp_standard/mode/entity.pm +++ b/centreon-plugins/snmp_standard/mode/entity.pm @@ -62,9 +62,10 @@ sub new { sub snmp_execute { my ($self, %options) = @_; - my $oid_entPhysicalName = '.1.3.6.1.2.1.47.1.1.1.1.7'; + my $oid_entPhysicalName = '.1.3.6.1.2.1.47.1.1.1.1.7'; + my $oid_entPhysicalDescr = '.1.3.6.1.2.1.47.1.1.1.1.2'; $self->{snmp} = $options{snmp}; - push @{$self->{request}}, { oid => $oid_entPhysicalName}; + push @{$self->{request}}, { oid => $oid_entPhysicalName }, { oid => $oid_entPhysicalDescr }; $self->{results} = $self->{snmp}->get_multiple_table(oids => $self->{request}); } @@ -186,6 +187,7 @@ sub check { return if ($self->check_filter(section => 'sensor')); my $oid_entPhysicalName = '.1.3.6.1.2.1.47.1.1.1.1.7'; + my $oid_entPhysicalDescr = '.1.3.6.1.2.1.47.1.1.1.1.2'; foreach my $oid ($self->{snmp}->oid_lex_sort(keys %{$self->{results}->{$oid_entPhysicalName}})) { next if ($oid !~ /^$oid_entPhysicalName\.(.*)$/); my $instance = $1; @@ -194,7 +196,8 @@ sub check { next if ($self->check_filter(section => 'sensor', instance => $result->{entPhySensorType} . '.' . $instance)); - my $name = $self->{results}->{$oid_entPhysicalName}->{$oid}; + my $name = $self->{results}->{$oid_entPhysicalName}->{$oid} ne '' ? + $self->{results}->{$oid_entPhysicalName}->{$oid} : $self->{results}->{$oid_entPhysicalDescr}->{$oid_entPhysicalDescr . '.' . $instance}; # It seems there is no scale if (!defined($self->{option_results}->{sensor_scale})) { $result->{entPhySensorValue} = defined($result->{entPhySensorValue}) ? diff --git a/centreon-plugins/snmp_standard/mode/printererror.pm b/centreon-plugins/snmp_standard/mode/printererror.pm index a0b4688f8..0cea63e51 100644 --- a/centreon-plugins/snmp_standard/mode/printererror.pm +++ b/centreon-plugins/snmp_standard/mode/printererror.pm @@ -73,20 +73,11 @@ sub run { my $result = $self->{snmp}->get_table(oid => $oid_hrPrinterDetectedErrorState, nothing_quit => 1); foreach (keys %$result) { - my ($value1, $value2) = unpack('C', $result->{$_}); + # 16 bits value + my $value = unpack('S', $result->{$_}); - foreach my $key (keys %errors_printer) { - my ($byte_check, $pos); - if ($key >= 8) { - next if (!defined($value2)); - $byte_check = $value2; - $pos = $key - 8; - } else { - $byte_check = $value1; - $pos = $key - } - - if (($byte_check & (1 << $pos)) && + foreach my $key (keys %errors_printer) { + if (($value & (1 << $key)) && (!$self->{output}->is_status(value => ${$errors_printer{$key}}[1], compare => 'ok', litteral => 1))) { $self->{output}->output_add(severity => ${$errors_printer{$key}}[1], short_msg => sprintf(${$errors_printer{$key}}[0])); diff --git a/centreon-plugins/snmp_standard/mode/storage.pm b/centreon-plugins/snmp_standard/mode/storage.pm index 1c696d937..6a99caa69 100644 --- a/centreon-plugins/snmp_standard/mode/storage.pm +++ b/centreon-plugins/snmp_standard/mode/storage.pm @@ -20,13 +20,15 @@ package snmp_standard::mode::storage; -use base qw(centreon::plugins::mode); +use base qw(centreon::plugins::templates::counter); use strict; use warnings; use centreon::plugins::statefile; use Digest::MD5 qw(md5_hex); +my $instance_mode; + my %oids_hrStorageTable = ( 'hrstoragedescr' => '.1.3.6.1.2.1.25.2.3.1.3', 'hrfsmountpoint' => '.1.3.6.1.2.1.25.3.8.1.2', @@ -69,6 +71,113 @@ my %storage_types_manage = ( '.1.3.6.1.2.1.25.3.9.23' => 'hrFSLinuxExt2', ); +sub custom_usage_perfdata { + my ($self, %options) = @_; + + my $label = 'used'; + my $value_perf = $self->{result_values}->{used}; + if (defined($instance_mode->{option_results}->{free})) { + $label = 'free'; + $value_perf = $self->{result_values}->{free}; + } + my $extra_label = ''; + $extra_label = '_' . $self->{result_values}->{display} if (!defined($options{extra_instance}) || $options{extra_instance} != 0); + my %total_options = (); + if ($instance_mode->{option_results}->{units} eq '%') { + $total_options{total} = $self->{result_values}->{total}; + $total_options{cast_int} = 1; + } + + $self->{output}->perfdata_add(label => $label . $extra_label, unit => 'B', + value => $value_perf, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{label}, %total_options), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{label}, %total_options), + min => 0, max => $self->{result_values}->{total}); +} + +sub custom_usage_threshold { + my ($self, %options) = @_; + + my ($exit, $threshold_value); + $threshold_value = $self->{result_values}->{used}; + $threshold_value = $self->{result_values}->{free} if (defined($instance_mode->{option_results}->{free})); + if ($instance_mode->{option_results}->{units} eq '%') { + $threshold_value = $self->{result_values}->{prct_used}; + $threshold_value = $self->{result_values}->{prct_free} if (defined($instance_mode->{option_results}->{free})); + } + $exit = $self->{perfdata}->threshold_check(value => $threshold_value, 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("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}->{display} = $options{new_datas}->{$self->{instance} . '_display'}; + $self->{result_values}->{total} = $options{new_datas}->{$self->{instance} . '_size'} * $options{new_datas}->{$self->{instance} . '_allocation_units'}; + my $reserved_value = 0; + if (defined($instance_mode->{option_results}->{space_reservation})) { + $reserved_value = $instance_mode->{option_results}->{space_reservation} * $self->{result_values}->{total} / 100; + } + + $self->{result_values}->{used} = $options{new_datas}->{$self->{instance} . '_used'} * $options{new_datas}->{$self->{instance} . '_allocation_units'}; + $self->{result_values}->{free} = $self->{result_values}->{total} - $self->{result_values}->{used} - $reserved_value; + $self->{result_values}->{prct_used} = $self->{result_values}->{used} * 100 / ($self->{result_values}->{total} - $reserved_value); + $self->{result_values}->{prct_free} = 100 - $self->{result_values}->{prct_used}; + + # limit to 100. Better output. + if ($self->{result_values}->{prct_used} > 100) { + $self->{result_values}->{free} = 0; + $self->{result_values}->{prct_used} = 100; + $self->{result_values}->{prct_free} = 0; + } + + return 0; +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'storage', type => 1, cb_prefix_output => 'prefix_storage_output', message_multiple => 'All storages are ok' }, + ]; + + $self->{maps_counters}->{storage} = [ + { label => 'usage', set => { + key_values => [ { name => 'display' }, { name => 'used' }, { name => 'size' }, { name => 'allocation_units' } ], + closure_custom_calc => $self->can('custom_usage_calc'), + closure_custom_output => $self->can('custom_usage_output'), + closure_custom_perfdata => $self->can('custom_usage_perfdata'), + closure_custom_threshold_check => $self->can('custom_usage_threshold'), + } + }, + ]; +} + +sub prefix_storage_output { + my ($self, %options) = @_; + + return "Storage '" . $options{instance_value}->{display} . "' "; +} + +sub default_storage_type { + my ($self, %options) = @_; + + return '^(hrStorageFixedDisk|hrStorageNetworkDisk|hrFSBerkeleyFFS)$'; +} + sub new { my ($class, %options) = @_; my $self = $class->SUPER::new(package => __PACKAGE__, %options); @@ -77,8 +186,6 @@ sub new { $self->{version} = '1.0'; $options{options}->add_options(arguments => { - "warning:s" => { name => 'warning' }, - "critical:s" => { name => 'critical' }, "units:s" => { name => 'units', default => '%' }, "free" => { name => 'free' }, "reload-cache-time:s" => { name => 'reload_cache_time', default => 180 }, @@ -92,7 +199,7 @@ sub new { "display-transform-dst:s" => { name => 'display_transform_dst' }, "show-cache" => { name => 'show_cache' }, "space-reservation:s" => { name => 'space_reservation' }, - "filter-storage-type:s" => { name => 'filter_storage_type', default => '^(hrStorageFixedDisk|hrStorageNetworkDisk|hrFSBerkeleyFFS)$' }, + "filter-storage-type:s" => { name => 'filter_storage_type', default => $self->default_storage_type() }, }); $self->{storage_id_selected} = []; @@ -103,43 +210,34 @@ sub new { sub check_options { my ($self, %options) = @_; - $self->SUPER::init(%options); + $self->SUPER::check_options(%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}->{space_reservation}) && ($self->{option_results}->{space_reservation} < 0 || $self->{option_results}->{space_reservation} > 100)) { - $self->{output}->add_option_msg(short_msg => "Space reservation argument must be between 0 and 100 percent."); - $self->{output}->option_exit(); + $self->{output}->add_option_msg(short_msg => "Space reservation argument must be between 0 and 100 percent."); + $self->{output}->option_exit(); } $self->{option_results}->{oid_filter} = lc($self->{option_results}->{oid_filter}); if ($self->{option_results}->{oid_filter} !~ /^(hrstoragedescr|hrfsmountpoint)$/) { - $self->{output}->add_option_msg(short_msg => "Unsupported --oid-filter option."); - $self->{output}->option_exit(); + $self->{output}->add_option_msg(short_msg => "Unsupported --oid-filter option."); + $self->{output}->option_exit(); } $self->{option_results}->{oid_display} = lc($self->{option_results}->{oid_display}); if ($self->{option_results}->{oid_display} !~ /^(hrstoragedescr|hrfsmountpoint)$/) { - $self->{output}->add_option_msg(short_msg => "Unsupported --oid-display option."); - $self->{output}->option_exit(); + $self->{output}->add_option_msg(short_msg => "Unsupported --oid-display option."); + $self->{output}->option_exit(); } - + $self->{statefile_cache}->check_options(%options); + $instance_mode = $self; } -sub run { +sub manage_selection { my ($self, %options) = @_; + $self->{snmp} = $options{snmp}; - $self->{hostname} = $self->{snmp}->get_hostname(); - $self->{snmp_port} = $self->{snmp}->get_port(); - - $self->manage_selection(); + $self->get_selection(); my $oid_hrStorageAllocationUnits = '.1.3.6.1.2.1.25.2.3.1.4'; my $oid_hrStorageSize = '.1.3.6.1.2.1.25.2.3.1.5'; @@ -149,109 +247,37 @@ sub run { $self->{snmp}->load(oids => [$oid_hrStorageAllocationUnits, $oid_hrStorageSize, $oid_hrStorageUsed], instances => $self->{storage_id_selected}, nothing_quit => 1); my $result = $self->{snmp}->get_leef(); - my $multiple = 0; - if (scalar(@{$self->{storage_id_selected}}) > 1) { - $multiple = 1; - } - if ($multiple == 1) { - $self->{output}->output_add(severity => 'OK', - short_msg => 'All storages are ok.'); - } - + $self->{storage} = {}; foreach (sort @{$self->{storage_id_selected}}) { my $name_storage = $self->get_display_value(id => $_); if (!defined($result->{$oid_hrStorageAllocationUnits . "." . $_})) { - if ($multiple == 0) { - $self->{output}->add_option_msg(severity => 'UNKNOWN', - short_msg => sprintf("Skipping storage '%s': not found (need to reload the cache)", - $name_storage)); - } else { - $self->{output}->add_option_msg(long_msg => sprintf("Skipping storage '%s': not found (need to reload the cache)", - $name_storage)); - } + $self->{output}->add_option_msg(long_msg => sprintf("skipping storage '%s': not found (need to reload the cache)", + $name_storage)); next; } # in bytes hrStorageAllocationUnits my $total_size = $result->{$oid_hrStorageSize . "." . $_} * $result->{$oid_hrStorageAllocationUnits . "." . $_}; if ($total_size <= 0) { - if ($multiple == 0) { - $self->{output}->add_option_msg(severity => 'UNKNOWN', - short_msg => sprintf("Skipping storage '%s': total size is <= 0 (%s)", - $name_storage, int($total_size))); - } else { - $self->{output}->add_option_msg(long_msg => sprintf("Skipping storage '%s': total size is <= 0 (%s)", - $name_storage, int($total_size))); - } + $self->{output}->add_option_msg(long_msg => sprintf("skipping storage '%s': total size is <= 0 (%s)", + $name_storage, int($total_size))); next; } - my $reserved_value = 0; - if (defined($self->{option_results}->{space_reservation})) { - $reserved_value = $self->{option_results}->{space_reservation} * $total_size / 100; - } - my $total_used = $result->{$oid_hrStorageUsed . "." . $_} * $result->{$oid_hrStorageAllocationUnits . "." . $_}; - my $total_free = $total_size - $total_used - $reserved_value; - my $prct_used = $total_used * 100 / ($total_size - $reserved_value); - my $prct_free = 100 - $prct_used; - - # limit to 100. Better output. - if ($prct_used > 100) { - $total_free = 0; - $prct_used = 100; - $prct_free = 0; - } - - my ($exit, $threshold_value); - - $threshold_value = $total_used; - $threshold_value = $total_free if (defined($self->{option_results}->{free})); - if ($self->{option_results}->{units} eq '%') { - $threshold_value = $prct_used; - $threshold_value = $prct_free if (defined($self->{option_results}->{free})); - } - $exit = $self->{perfdata}->threshold_check(value => $threshold_value, threshold => [ { label => 'critical', 'exit_litteral' => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]); - - my ($total_size_value, $total_size_unit) = $self->{perfdata}->change_bytes(value => $total_size); - my ($total_used_value, $total_used_unit) = $self->{perfdata}->change_bytes(value => $total_used); - my ($total_free_value, $total_free_unit) = $self->{perfdata}->change_bytes(value => $total_free); - - $self->{output}->output_add(long_msg => sprintf("Storage '%s' Total: %s Used: %s (%.2f%%) Free: %s (%.2f%%)", $name_storage, - $total_size_value . " " . $total_size_unit, - $total_used_value . " " . $total_used_unit, $prct_used, - $total_free_value . " " . $total_free_unit, $prct_free)); - if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1) || ($multiple == 0)) { - $self->{output}->output_add(severity => $exit, - short_msg => sprintf("Storage '%s' Total: %s Used: %s (%.2f%%) Free: %s (%.2f%%)", $name_storage, - $total_size_value . " " . $total_size_unit, - $total_used_value . " " . $total_used_unit, $prct_used, - $total_free_value . " " . $total_free_unit, $prct_free)); - } - - my $label = 'used'; - my $value_perf = $total_used; - if (defined($self->{option_results}->{free})) { - $label = 'free'; - $value_perf = $total_free; - } - my $extra_label = ''; - $extra_label = '_' . $name_storage if ($multiple == 1); - my %total_options = (); - if ($self->{option_results}->{units} eq '%') { - $total_options{total} = $total_size - $reserved_value; - $total_options{cast_int} = 1; - } - $self->{output}->perfdata_add(label => $label . $extra_label, unit => 'B', - value => $value_perf, - warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning', %total_options), - critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical', %total_options), - min => 0, max => int($total_size - $reserved_value)); + $self->{storage}->{$_} = { + display => $name_storage, + allocation_units => $result->{$oid_hrStorageAllocationUnits . "." . $_}, + size => $result->{$oid_hrStorageSize . "." . $_}, + used => $result->{$oid_hrStorageUsed . "." . $_}, + }; + } + + if (scalar(keys %{$self->{storage}}) <= 0) { + $self->{output}->add_option_msg(short_msg => "Issue with storage information (see details)"); + $self->{output}->option_exit(); } - - $self->{output}->display(); - $self->{output}->exit(); } sub reload_cache { @@ -311,11 +337,11 @@ sub filter_type { return 0; } -sub manage_selection { +sub get_selection { my ($self, %options) = @_; # init cache file - my $has_cache_file = $self->{statefile_cache}->read(statefile => 'cache_snmpstandard_' . $self->{hostname} . '_' . $self->{snmp_port} . '_' . $self->{mode}); + my $has_cache_file = $self->{statefile_cache}->read(statefile => 'cache_snmpstandard_' . $self->{snmp}->get_hostname() . '_' . $self->{snmp}->get_port() . '_' . $self->{mode}); if (defined($self->{option_results}->{show_cache})) { $self->{output}->add_option_msg(long_msg => $self->{statefile_cache}->get_string_content()); $self->{output}->option_exit(); @@ -382,11 +408,11 @@ __END__ =over 8 -=item B<--warning> +=item B<--warning-usage> Threshold warning. -=item B<--critical> +=item B<--critical-usage> Threshold critical. diff --git a/centreon-plugins/storage/dell/fluidfs/snmp/mode/volumeusage.pm b/centreon-plugins/storage/dell/fluidfs/snmp/mode/volumeusage.pm index e9d092b16..74fb6404f 100644 --- a/centreon-plugins/storage/dell/fluidfs/snmp/mode/volumeusage.pm +++ b/centreon-plugins/storage/dell/fluidfs/snmp/mode/volumeusage.pm @@ -211,7 +211,6 @@ Units of thresholds (Default: '%') ('%', 'B'). Thresholds are on free space left. - =back =cut diff --git a/centreon-plugins/storage/emc/xtremio/restapi/custom/xtremioapi.pm b/centreon-plugins/storage/emc/xtremio/restapi/custom/xtremioapi.pm index 5ddc0815c..af3ba4ac0 100644 --- a/centreon-plugins/storage/emc/xtremio/restapi/custom/xtremioapi.pm +++ b/centreon-plugins/storage/emc/xtremio/restapi/custom/xtremioapi.pm @@ -23,16 +23,13 @@ package storage::emc::xtremio::restapi::custom::xtremioapi; use strict; use warnings; use centreon::plugins::http; +use centreon::plugins::statefile; 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"; @@ -46,11 +43,12 @@ sub new { 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', }, + "hostname:s@" => { name => 'hostname', }, + "xtremio-username:s@" => { name => 'xtremio_username', }, + "xtremio-password:s@" => { name => 'xtremio_password', }, + "proxyurl:s@" => { name => 'proxyurl', }, + "timeout:s@" => { name => 'timeout', }, + "reload-cache-time:s" => { name => 'reload_cache_time' }, }); } $options{options}->add_help(package => __PACKAGE__, sections => 'REST API OPTIONS', once => 1); @@ -58,25 +56,21 @@ sub new { $self->{output} = $options{output}; $self->{mode} = $options{mode}; $self->{http} = centreon::plugins::http->new(output => $self->{output}); + $self->{statefile_cache_cluster} = centreon::plugins::statefile->new(%options); 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++) { @@ -92,14 +86,13 @@ sub set_defaults { 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; + $self->{reload_cache_time} = (defined($self->{option_results}->{reload_cache_time})) ? shift(@{$self->{option_results}->{reload_cache_time}}) : 180; if (!defined($self->{hostname})) { $self->{output}->add_option_msg(short_msg => "Need to specify hostname option."); @@ -113,6 +106,7 @@ sub check_options { if (!defined($self->{hostname}) || scalar(@{$self->{option_results}->{hostname}}) == 0) { + $self->{statefile_cache_cluster}->check_options(option_results => $self->{option_results}); return 0; } return 1; @@ -136,6 +130,26 @@ sub settings { $self->{http}->set_options(%{$self->{option_results}}); } +sub cache_clusters { + my ($self, %options) = @_; + + my $has_cache_file = $self->{statefile_cache_cluster}->read(statefile => 'cache_xtremio_clusters_' . $self->{hostname}); + my $timestamp_cache = $self->{statefile_cache_cluster}->get(name => 'last_timestamp'); + my $clusters = $self->{statefile_cache_cluster}->get(name => 'clusters'); + if ($has_cache_file == 0 || !defined($timestamp_cache) || ((time() - $timestamp_cache) > (($self->{reload_cache_time}) * 60))) { + $clusters = {}; + my $datas = { last_timestamp => time(), clusters => $clusters }; + my @items = $self->get_items(url => '/api/json/types/', + obj => 'clusters'); + foreach (@items) { + $clusters->{$_} = 1; + } + $self->{statefile_cache_cluster}->write(data => $datas); + } + + return $clusters; +} + sub get_items { my ($self, %options) = @_; @@ -157,28 +171,76 @@ sub get_items { my @items; foreach my $context (@{$decoded->{$options{obj}}}) { - push @items,$context->{name}; + push @items, $context->{name}; } return @items; } +sub get_details_data { + my ($self, %options) = @_; + + my $response = $self->{http}->request(url_path => $options{url}, + critical_status => '', warning_status => '', unknown_status => ''); + 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; +} + + +sub get_details_lookup_clusters { + my ($self, %options) = @_; + + #Message if object not found: + #{ + # "message": "obj_not_found", + # "error_code": 400 + #} + # + if (!defined($self->{cache_clusters})) { + $self->{cache_clusters} = $self->cache_clusters(); + } + foreach my $cluster_name (keys %{$self->{cache_clusters}}) { + my $url = $options{url} . $options{append} . 'cluster-name=' . $cluster_name; + my $decoded = $self->get_details_data(url => $url); + return $decoded if (!defined($decoded->{error_code})); + } + + # object is not found. + $self->{output}->add_option_msg(short_msg => "xtremio api issue: cannot found object details"); + $self->{output}->option_exit(); +} + sub get_details { my ($self, %options) = @_; $self->settings(); + my $append = '?'; if ((defined($options{obj}) && $options{obj} ne '') && (defined($options{name}) && $options{name} ne '')) { - $options{url} .= $options{obj} . '/?name=' . $options{name} ; - } + $options{url} .= $options{obj} . '/?name=' . $options{name}; + $append = '&'; + } - 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"); + #Message when cluster id needed: + #{ + # "message": "cluster_id_is_required", + # "error_code": 400 + #} + # + my $decoded = $self->get_details_data(%options); + if (defined($decoded->{error_code}) && + ($decoded->{error_code} == 400 && $decoded->{message} eq 'cluster_id_is_required')) { + $decoded = $self->get_details_lookup_clusters(%options, append => $append); + } elsif (defined($decoded->{error_code})) { + $self->{output}->add_option_msg(short_msg => "xtremio api issue: $decoded->{message}"); $self->{output}->option_exit(); } @@ -222,6 +284,11 @@ Proxy URL if any Set HTTP timeout +=item B<--reload-cache-time> + +Time in seconds before reloading cache file (default: 180). +The cache is used when XMS manages multiple clusters. + =back =head1 DESCRIPTION diff --git a/centreon-plugins/storage/kaminario/restapi/custom/api.pm b/centreon-plugins/storage/kaminario/restapi/custom/api.pm index 4ea8dd4a8..022bfdc2d 100644 --- a/centreon-plugins/storage/kaminario/restapi/custom/api.pm +++ b/centreon-plugins/storage/kaminario/restapi/custom/api.pm @@ -129,18 +129,9 @@ sub get_performance { my ($self, %options) = @_; $self->settings(); - #my $content = $self->{http}->request(url_path => '/api/v2' . $options{path} . '&__resolution=' . $self->{resolution}, - # critical_status => '', warning_status => ''); - my $content = do { - local $/ = undef; - if (!open my $fh, "<", '/tmp/4.json') { - $self->{output}->add_option_msg(short_msg => "Could not open file toto : $!"); - $self->{output}->option_exit(); - } - <$fh>; - }; - - #my $response = $self->{http}->get_response(); + my $content = $self->{http}->request(url_path => '/api/v2' . $options{path} . '&__resolution=' . $self->{resolution}, + critical_status => '', warning_status => ''); + my $response = $self->{http}->get_response(); my $decoded; eval { @@ -151,10 +142,10 @@ sub get_performance { $self->{output}->option_exit(); } - #if ($response->code() != 200) { - # $self->{output}->add_option_msg(short_msg => "Connection issue: " . $decoded->{message}); - # $self->{output}->option_exit(); - #} + if ($response->code() != 200) { + $self->{output}->add_option_msg(short_msg => "Connection issue: " . $decoded->{message}); + $self->{output}->option_exit(); + } return $decoded; } diff --git a/centreon-plugins/storage/purestorage/restapi/custom/api.pm b/centreon-plugins/storage/purestorage/restapi/custom/api.pm new file mode 100644 index 000000000..161538fbb --- /dev/null +++ b/centreon-plugins/storage/purestorage/restapi/custom/api.pm @@ -0,0 +1,282 @@ +# +# Copyright 2017 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::purestorage::restapi::custom::api; + +use strict; +use warnings; +use centreon::plugins::http; +use JSON; + +sub new { + my ($class, %options) = @_; + my $self = {}; + bless $self, $class; + + 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' }, + "username:s" => { name => 'username' }, + "password:s" => { name => 'password' }, + "proxyurl:s" => { name => 'proxyurl' }, + "timeout:s" => { name => 'timeout' }, + "api-path:s" => { name => 'api_path' }, + }); + } + $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; +} + +sub set_options { + my ($self, %options) = @_; + + $self->{option_results} = $options{option_results}; +} + +sub set_defaults { + my ($self, %options) = @_; + + 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) = @_; + + $self->{hostname} = (defined($self->{option_results}->{hostname})) ? $self->{option_results}->{hostname} : undef; + $self->{username} = (defined($self->{option_results}->{username})) ? $self->{option_results}->{username} : undef; + $self->{password} = (defined($self->{option_results}->{password})) ? $self->{option_results}->{password} : undef; + $self->{timeout} = (defined($self->{option_results}->{timeout})) ? $self->{option_results}->{timeout} : 10; + $self->{proxyurl} = (defined($self->{option_results}->{proxyurl})) ? $self->{option_results}->{proxyurl} : undef; + $self->{api_path} = (defined($self->{option_results}->{api_path})) ? $self->{option_results}->{api_path} : '/api/1.11'; + + if (!defined($self->{hostname})) { + $self->{output}->add_option_msg(short_msg => "Need to specify hostname option."); + $self->{output}->option_exit(); + } + if (!defined($self->{username})) { + $self->{output}->add_option_msg(short_msg => "Need to specify username option."); + $self->{output}->option_exit(); + } + if (!defined($self->{password})) { + $self->{output}->add_option_msg(short_msg => "Need to specify password option."); + $self->{output}->option_exit(); + } + + return 0; +} + +sub get_connection_infos { + my ($self, %options) = @_; + + return $self->{hostname} . '_' . $self->{http}->get_port(); +} + +sub build_options_for_httplib { + my ($self, %options) = @_; + + $self->{option_results}->{hostname} = $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}->add_header(key => 'Accept', value => 'application/json'); + $self->{http}->add_header(key => 'Content-Type', value => 'application/json'); + if (defined($self->{session_id})) { + $self->{http}->add_header(key => 'Cookie', value => 'session=' . $self->{session_id}); + } + $self->{http}->set_options(%{$self->{option_results}}); +} + +sub request_api { + my ($self, %options) = @_; + + my $content = $self->{http}->request(method => $options{method}, url_path => $options{url_path}, query_form_post => $options{query_form_post}, + critical_status => '', warning_status => '', unknown_status => ''); + my $response = $self->{http}->get_response(); + my $decoded; + eval { + $decoded = decode_json($content); + }; + if ($@) { + $self->{output}->output_add(long_msg => $content, debug => 1); + $self->{output}->add_option_msg(short_msg => "Cannot decode json response"); + $self->{output}->option_exit(); + } + if ($response->code() != 200) { + $self->{output}->add_option_msg(short_msg => "Connection issue: " . $decoded->{msg}); + $self->{output}->option_exit(); + } + + return $decoded; +} + +sub get_api_token { + my ($self, %options) = @_; + + my $json_request = { username => $self->{username}, password => $self->{password} }; + my $encoded; + eval { + $encoded = encode_json($json_request); + }; + if ($@) { + $self->{output}->add_option_msg(short_msg => "Cannot encode json request"); + $self->{output}->option_exit(); + } + + $self->settings(); + my $decoded = $self->request_api(method => 'POST', url_path => $self->{api_path} . '/auth/apitoken', query_form_post => $encoded); + if (!defined($decoded->{api_token})) { + $self->{output}->add_option_msg(short_msg => "Cannot get api token"); + $self->{output}->option_exit(); + } + + return $decoded->{api_token}; +} + +sub get_session { + my ($self, %options) = @_; + + my $json_request = { api_token => $options{api_token} }; + my $encoded; + eval { + $encoded = encode_json($json_request); + }; + if ($@) { + $self->{output}->add_option_msg(short_msg => "Cannot encode json request"); + $self->{output}->option_exit(); + } + + $self->settings(); + my $decoded = $self->request_api(method => 'POST', url_path => $self->{api_path} . '/auth/session', query_form_post => $encoded); + my $headers = $self->{http}->get_header(); + my $cookie = $headers->header('Set-Cookie'); + if (!defined($cookie)) { + $self->{output}->add_option_msg(short_msg => "Cannot get session"); + $self->{output}->option_exit(); + } + + $cookie =~ /session=(.*);/; + return $1; +} + +sub connect { + my ($self, %options) = @_; + + my $api_token = $self->get_api_token(); + $self->{session_id} = $self->get_session(api_token => $api_token); +} + +sub get_object { + my ($self, %options) = @_; + + if (!defined($self->{api_token})) { + $self->connect(); + } + + $self->settings(); + return $self->request_api(method => 'GET', url_path => $self->{api_path} . $options{path}); +} + +sub DESTROY { + my $self = shift; + + if (defined($self->{session_id})) { + $self->request_api(method => 'DELETE', url_path => $self->{api_path} . '/auth/session'); + } +} + +1; + +__END__ + +=head1 NAME + +Pure Storage REST API + +=head1 SYNOPSIS + +Pure Storage Rest API custom mode + +=head1 REST API OPTIONS + +=over 8 + +=item B<--hostname> + +Pure Storage hostname. + +=item B<--username> + +Pure Storage username. + +=item B<--password> + +Pure Storage password. + +=item B<--proxyurl> + +Proxy URL if any. + +=item B<--timeout> + +Set HTTP timeout in seconds (Default: '10'). + +=item B<--api-path> + +API base url path (Default: '/api/1.11'). + +=back + +=head1 DESCRIPTION + +B. + +=cut diff --git a/centreon-plugins/storage/purestorage/restapi/mode/alarms.pm b/centreon-plugins/storage/purestorage/restapi/mode/alarms.pm new file mode 100644 index 000000000..31d2ad3e1 --- /dev/null +++ b/centreon-plugins/storage/purestorage/restapi/mode/alarms.pm @@ -0,0 +1,218 @@ +# +# Copyright 2017 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::purestorage::restapi::mode::alarms; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; +use centreon::plugins::misc; +use centreon::plugins::statefile; + +my $instance_mode; + +sub custom_status_threshold { + my ($self, %options) = @_; + my $status = 'ok'; + my $message; + + eval { + local $SIG{__WARN__} = sub { $message = $_[0]; }; + local $SIG{__DIE__} = sub { $message = $_[0]; }; + + if (defined($instance_mode->{option_results}->{critical_status}) && $instance_mode->{option_results}->{critical_status} ne '' && + eval "$instance_mode->{option_results}->{critical_status}") { + $status = 'critical'; + } elsif (defined($instance_mode->{option_results}->{warning_status}) && $instance_mode->{option_results}->{warning_status} ne '' && + eval "$instance_mode->{option_results}->{warning_status}") { + $status = 'warning'; + } + }; + if (defined($message)) { + $self->{output}->output_add(long_msg => 'filter status issue: ' . $message); + } + + return $status; +} + +sub custom_status_output { + my ($self, %options) = @_; + + my $msg = sprintf("alarm [component: %s] [severity: %s] [category: %s] [event: %s] %s", $self->{result_values}->{component_name}, + $self->{result_values}->{severity}, $self->{result_values}->{category}, + $self->{result_values}->{event}, centreon::plugins::misc::change_seconds(value => $self->{result_values}->{opened})); + return $msg; +} + +sub custom_status_calc { + my ($self, %options) = @_; + + $self->{result_values}->{category} = $options{new_datas}->{$self->{instance} . '_category'}; + $self->{result_values}->{code} = $options{new_datas}->{$self->{instance} . '_code'}; + $self->{result_values}->{severity} = $options{new_datas}->{$self->{instance} . '_current_severity'}; + $self->{result_values}->{component_name} = $options{new_datas}->{$self->{instance} . '_component_name'}; + $self->{result_values}->{opened} = $options{new_datas}->{$self->{instance} . '_opened'}; + $self->{result_values}->{event} = $options{new_datas}->{$self->{instance} . '_event'}; + return 0; +} + + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'alarms', type => 2, message_multiple => '0 problem(s) detected', display_counter_problem => { label => 'alerts', min => 0 }, + group => [ { name => 'alarm', skipped_code => { -11 => 1 } } ] + } + ]; + + $self->{maps_counters}->{alarm} = [ + { label => 'status', threshold => 0, set => { + key_values => [ { name => 'category' }, { name => 'code' }, { name => 'current_severity' }, { name => 'opened' }, { name => 'event' }, { name => 'component_name' } ], + closure_custom_calc => $self->can('custom_status_calc'), + closure_custom_output => $self->can('custom_status_output'), + closure_custom_perfdata => sub { return 0; }, + closure_custom_threshold_check => $self->can('custom_status_threshold'), + } + }, + ]; +} + +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-category:s" => { name => 'filter_category' }, + "warning-status:s" => { name => 'warning_status', default => '%{severity} =~ /warning/i' }, + "critical-status:s" => { name => 'critical_status', default => '%{severity} =~ /critical/i' }, + "memory" => { name => 'memory' }, + }); + + centreon::plugins::misc::mymodule_load(output => $self->{output}, module => 'Date::Parse', + error_msg => "Cannot load module 'Date::Parse'."); + $self->{statefile_cache} = centreon::plugins::statefile->new(%options); + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::check_options(%options); + + $instance_mode = $self; + $self->change_macros(); + + if (defined($self->{option_results}->{memory})) { + $self->{statefile_cache}->check_options(%options); + } +} + +sub change_macros { + my ($self, %options) = @_; + + foreach (('warning_status', 'critical_status')) { + if (defined($self->{option_results}->{$_})) { + $self->{option_results}->{$_} =~ s/%\{(.*?)\}/\$self->{result_values}->{$1}/g; + } + } +} + +sub manage_selection { + my ($self, %options) = @_; + + $self->{alarms}->{global} = { alarm => {} }; + my $alarm_results = $options{custom}->get_object(path => '/message'); + + my $last_time; + if (defined($self->{option_results}->{memory})) { + $self->{statefile_cache}->read(statefile => 'cache_purestorage_' . $self->{mode} . '_' . $options{custom}->get_connection_infos()); + $last_time = $self->{statefile_cache}->get(name => 'last_time'); + } + + #[ + # {"category": "hardware", "code": 39, "actual": "2", "opened": "2017-11-27T11:32:51Z", "component_type": "hardware", "event": "Fibre Channel link failure", "current_severity": "warning", "details": "", "expected": null, "id": 10088813, "component_name": "ct1.fc3"}, + # ... + # + + my ($i, $current_time) = (1, time()); + foreach my $alarm (@{$alarm_results}) { + my $create_time = Date::Parse::str2time($alarm->{opened}); + if (!defined($create_time)) { + $self->{manager}->{output}->output_add(severity => 'UNKNOWN', + short_msg => "Can't Parse date '" . $alarm->{opened} . "'"); + next; + } + + next if (defined($self->{option_results}->{memory}) && defined($last_time) && $last_time > $create_time); + if (defined($self->{option_results}->{filter_category}) && $self->{option_results}->{filter_category} ne '' && + $alarm->{category} !~ /$self->{option_results}->{filter_category}/) { + $self->{output}->output_add(long_msg => "skipping '" . $alarm->{category} . "': no matching filter.", debug => 1); + next; + } + + my $diff_time = $current_time - $create_time; + + $self->{alarms}->{global}->{alarm}->{$i} = { + %$alarm, + opened => $diff_time, + }; + $i++; + } + + if (defined($self->{option_results}->{memory})) { + $self->{statefile_cache}->write(data => { last_time => $current_time }); + } +} + +1; + +__END__ + +=head1 MODE + +Check alarms. + +=over 8 + +=item B<--filter-category> + +Filter by category name (can be a regexp). + +=item B<--warning-status> + +Set warning threshold for status (Default: '%{severity} =~ /warning/i') +Can used special variables like: %{category}, %{code}, %{severity}, %{opened}, %{event}, %{component_name} + +=item B<--critical-status> + +Set critical threshold for status (Default: '%{severity} =~ /critical/i'). +Can used special variables like: %{category}, %{code}, %{severity}, %{opened}, %{event}, %{component_name} + +=item B<--memory> + +Only check new alarms. + +=back + +=cut diff --git a/centreon-plugins/storage/purestorage/restapi/mode/hardware.pm b/centreon-plugins/storage/purestorage/restapi/mode/hardware.pm new file mode 100644 index 000000000..6c2f4755d --- /dev/null +++ b/centreon-plugins/storage/purestorage/restapi/mode/hardware.pm @@ -0,0 +1,162 @@ +# +# Copyright 2017 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::purestorage::restapi::mode::hardware; + +use base qw(centreon::plugins::templates::hardware); + +use strict; +use warnings; + +sub set_system { + my ($self, %options) = @_; + + $self->{regexp_threshold_overload_check_section_option} = '^(entity)$'; + $self->{regexp_threshold_numeric_check_section_option} = '^(temperature)$'; + + $self->{cb_hook2} = 'restapi_execute'; + + $self->{thresholds} = { + entity => [ + ['ok', 'OK'], + ['critical', 'CRITICAL'], + ['degraded', 'WARNING'], + ['device_off', 'WARNING'], + ['identifying', 'OK'], + ['not_installed', 'OK'], + ['unknown', 'UNKNOWN'], + ], + }; + + $self->{components_path} = 'storage::purestorage::restapi::mode::components'; + $self->{components_module} = ['entity']; +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options, no_absent => 1, no_load_components => 1); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => + { + }); + + return $self; +} + +sub restapi_execute { + my ($self, %options) = @_; + + $self->{results} = $options{custom}->get_object(path => '/hardware'); +} + +1; + +=head1 MODE + +Check hardware. + +=over 8 + +=item B<--component> + +Which component to check (Default: '.*'). +Can be: 'entity'. + +=item B<--filter> + +Exclude some parts (comma seperated list) +Can also exclude specific instance: --filter=entity,CT1.FC0 + +=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='entity,OK,device_off' + +=item B<--warning> + +Set warning threshold for 'temperature' (syntax: type,regexp,threshold) +Example: --warning='temperature,.*,40' + +=item B<--critical> + +Set critical threshold for 'temperature' (syntax: type,regexp,threshold) +Example: --critical='temperature,.*,50' + +=back + +=cut + +package storage::purestorage::restapi::mode::components::entity; + +use strict; +use warnings; + +sub load { } + +sub check { + my ($self) = @_; + + $self->{output}->output_add(long_msg => "Checking entity"); + $self->{components}->{entity} = {name => 'entity', total => 0, skip => 0}; + return if ($self->check_filter(section => 'entity')); + + # [ + # {"status": "ok", "slot": null, "name": "CH0", "index": 0, "identify": "off", "voltage": null, "details": null, "speed": null, "temperature": null}, + # ... + # ] + + foreach my $entry (@{$self->{results}}) { + my $instance = $entry->{name}; + + next if ($self->check_filter(section => 'entity', instance => $instance)); + + $self->{components}->{entity}->{total}++; + $self->{output}->output_add(long_msg => sprintf("entity '%s' status is '%s' [instance = %s]", + $entry->{name}, $entry->{status}, $instance)); + my $exit = $self->get_severity(section => 'entity', value => $entry->{status}); + if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { + $self->{output}->output_add(severity => $exit, + short_msg => sprintf("entity '%s' status is '%s'", $entry->{name}, $entry->{status})); + } + + if (defined($entry->{temperature}) && $entry->{temperature} =~ /[0-9]/) { + my ($exit2, $warn, $crit, $checked) = $self->get_severity_numeric(section => 'temperature', instance => $instance, value => $entry->{temperature}); + if (!$self->{output}->is_status(value => $exit2, compare => 'ok', litteral => 1)) { + $self->{output}->output_add(severity => $exit2, + short_msg => sprintf("entity '%s' temperature is %s C", $entry->{name}, $entry->{temperature})); + } + $self->{output}->perfdata_add(label => 'temperature_' . $entry->{name}, unit => 'C', + value => $entry->{temperature}, + warning => $warn, + critical => $crit, min => 0 + ); + } + } +} + +1; diff --git a/centreon-plugins/storage/purestorage/restapi/mode/listvolumes.pm b/centreon-plugins/storage/purestorage/restapi/mode/listvolumes.pm new file mode 100644 index 000000000..19c0cde56 --- /dev/null +++ b/centreon-plugins/storage/purestorage/restapi/mode/listvolumes.pm @@ -0,0 +1,93 @@ +# +# Copyright 2017 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::purestorage::restapi::mode::listvolumes; + +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 => + { + }); + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::init(%options); +} + +sub manage_selection { + my ($self, %options) = @_; + + $self->{volumes} = $options{custom}->get_object(path => '/volume'); +} + +sub run { + my ($self, %options) = @_; + + $self->manage_selection(%options); + foreach (@{$self->{volumes}}) { + $self->{output}->output_add(long_msg => "[name = '" . $_->{name} . "']"); + } + + $self->{output}->output_add(severity => 'OK', + short_msg => 'List volumes:'); + $self->{output}->display(nolabel => 1, force_ignore_perfdata => 1, force_long_output => 1); + $self->{output}->exit(); +} + +sub disco_format { + my ($self, %options) = @_; + + $self->{output}->add_disco_format(elements => ['name']); +} + +sub disco_show { + my ($self, %options) = @_; + + $self->manage_selection(%options); + foreach (@{$self->{volumes}}) { + $self->{output}->add_disco_entry(name => $_->{name}); + } +} + +1; + +__END__ + +=head1 MODE + +List volumes. + +=over 8 + +=back + +=cut + diff --git a/centreon-plugins/storage/purestorage/restapi/mode/volumeusage.pm b/centreon-plugins/storage/purestorage/restapi/mode/volumeusage.pm new file mode 100644 index 000000000..e48b3d7e5 --- /dev/null +++ b/centreon-plugins/storage/purestorage/restapi/mode/volumeusage.pm @@ -0,0 +1,233 @@ +# +# Copyright 2017 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::purestorage::restapi::mode::volumeusage; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; + +my $instance_mode; + +sub custom_usage_perfdata { + my ($self, %options) = @_; + + my $label = 'used'; + my $value_perf = $self->{result_values}->{used}; + if (defined($instance_mode->{option_results}->{free})) { + $label = 'free'; + $value_perf = $self->{result_values}->{free}; + } + my $extra_label = ''; + $extra_label = '_' . $self->{result_values}->{display} if (!defined($options{extra_instance}) || $options{extra_instance} != 0); + my %total_options = (); + if ($instance_mode->{option_results}->{units} eq '%') { + $total_options{total} = $self->{result_values}->{total}; + $total_options{cast_int} = 1; + } + + $self->{output}->perfdata_add(label => $label . $extra_label, unit => 'B', + value => $value_perf, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{label}, %total_options), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{label}, %total_options), + min => 0, max => $self->{result_values}->{total}); +} + +sub custom_usage_threshold { + my ($self, %options) = @_; + + my ($exit, $threshold_value); + $threshold_value = $self->{result_values}->{used}; + $threshold_value = $self->{result_values}->{free} if (defined($instance_mode->{option_results}->{free})); + if ($instance_mode->{option_results}->{units} eq '%') { + $threshold_value = $self->{result_values}->{prct_used}; + $threshold_value = $self->{result_values}->{prct_free} if (defined($instance_mode->{option_results}->{free})); + } + $exit = $self->{perfdata}->threshold_check(value => $threshold_value, 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("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}->{display} = $options{new_datas}->{$self->{instance} . '_display'}; + $self->{result_values}->{total} = $options{new_datas}->{$self->{instance} . '_size'}; + $self->{result_values}->{used} = $options{new_datas}->{$self->{instance} . '_volumes'}; + $self->{result_values}->{free} = $self->{result_values}->{total} - $self->{result_values}->{used}; + $self->{result_values}->{prct_used} = $self->{result_values}->{used} * 100 / $self->{result_values}->{total}; + $self->{result_values}->{prct_free} = 100 - $self->{result_values}->{prct_used}; + + return 0; +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'volume', type => 1, cb_prefix_output => 'prefix_volume_output', message_multiple => 'All volumes are ok' }, + ]; + + $self->{maps_counters}->{volume} = [ + { label => 'usage', set => { + key_values => [ { name => 'display' }, { name => 'volumes' }, { name => 'size' } ], + closure_custom_calc => $self->can('custom_usage_calc'), + closure_custom_output => $self->can('custom_usage_output'), + closure_custom_perfdata => $self->can('custom_usage_perfdata'), + closure_custom_threshold_check => $self->can('custom_usage_threshold'), + } + }, + { label => 'data-reduction', set => { + key_values => [ { name => 'data_reduction' }, { name => 'display' } ], + output_template => 'Data Reduction : %.3f', + perfdatas => [ + { label => 'data_reduction', value => 'data_reduction_absolute', template => '%.3f', + min => 0, label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + { label => 'total-reduction', set => { + key_values => [ { name => 'total_reduction' }, { name => 'display' } ], + output_template => 'Total Reduction : %.3f', + perfdatas => [ + { label => 'total_reduction', value => 'total_reduction_absolute', template => '%.3f', + min => 0, label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + { label => 'snapshots', set => { + key_values => [ { name => 'snapshots' }, { name => 'display' } ], + output_template => 'Snapshots : %s %s', + output_change_bytes => 1, + perfdatas => [ + { label => 'snapshots', value => 'snapshots_absolute', template => '%s', + unit => 'B', min => 0, 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' }, + "units:s" => { name => 'units', default => '%' }, + "free" => { name => 'free' }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::check_options(%options); + + $instance_mode = $self; +} + +sub prefix_volume_output { + my ($self, %options) = @_; + + return "Volume '" . $options{instance_value}->{display} . "' "; +} + +sub manage_selection { + my ($self, %options) = @_; + + $self->{volume} = {}; + my $result = $options{custom}->get_object(path => '/volume?space=true'); + + #[ + # {"total": 328750479478, "name": "PURE-M50R2-ADM24-CLU04-Oracle-prod1", "system": null, "snapshots": 1454226866, "volumes": 327296252612, "data_reduction": 5.436245544153763, "size": 3298534883328, "shared_space": null, "thin_provisioning": 0.387090105873843, "total_reduction": 8.86956728264988} + # ... + #] + foreach my $entry (@{$result}) { + if (defined($self->{option_results}->{filter_name}) && $self->{option_results}->{filter_name} ne '' && + $entry->{name} !~ /$self->{option_results}->{filter_name}/) { + $self->{output}->output_add(long_msg => "skipping '" . $entry->{volume_name} . "': no matching filter.", debug => 1); + next; + } + + $self->{volume}->{$entry->{name}} = { + display => $entry->{name}, + %{$entry}, + }; + } +} + +1; + +__END__ + +=head1 MODE + +Check volume usage. + +=over 8 + +=item B<--filter-counters> + +Only display some counters (regexp can be used). +Example: --filter-counters='^iops$' + +=item B<--filter-name> + +Filter volume name (can be a regexp). + +=item B<--warning-*> + +Threshold warning. +Can be: 'usage', 'data-reduction', 'total-reduction'. + +=item B<--critical-*> + +Threshold critical. +Can be: 'usage', 'data-reduction', 'total-reduction'. + +=item B<--units> + +Units of thresholds (Default: '%') ('%', 'B'). + +=item B<--free> + +Thresholds are on free space left. + +=back + +=cut diff --git a/centreon-plugins/storage/purestorage/restapi/plugin.pm b/centreon-plugins/storage/purestorage/restapi/plugin.pm new file mode 100644 index 000000000..8a12a1b1b --- /dev/null +++ b/centreon-plugins/storage/purestorage/restapi/plugin.pm @@ -0,0 +1,52 @@ +# +# Copyright 2017 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::purestorage::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; + + $self->{version} = '0.1'; + %{$self->{modes}} = ( + 'alarms' => 'storage::purestorage::restapi::mode::alarms', + 'hardware' => 'storage::purestorage::restapi::mode::hardware', + 'list-volumes' => 'storage::purestorage::restapi::mode::listvolumes', + 'volume-usage' => 'storage::purestorage::restapi::mode::volumeusage', + ); + + $self->{custom_modes}{api} = 'storage::purestorage::restapi::custom::api'; + return $self; +} + +1; + +__END__ + +=head1 PLUGIN DESCRIPTION + +Check Pure Storage through HTTP/REST API. + +=cut diff --git a/centreon-plugins/storage/purestorage/snmp/mode/stats.pm b/centreon-plugins/storage/purestorage/snmp/mode/stats.pm new file mode 100644 index 000000000..2de919aa8 --- /dev/null +++ b/centreon-plugins/storage/purestorage/snmp/mode/stats.pm @@ -0,0 +1,160 @@ +# +# Copyright 2017 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::purestorage::snmp::mode::stats; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'global', type => 0, message_separator => ' - ' }, + ]; + + $self->{maps_counters}->{global} = [ + { label => 'read-bandwidth', set => { + key_values => [ { name => 'pureArrayReadBandwidth' }, ], + output_change_bytes => 2, + output_template => 'Read Bandwith : %s %s/s', + perfdatas => [ + { label => 'read_bandwidth', value => 'pureArrayReadBandwidth_absolute', template => '%.2f', + min => 0, unit => 'b/s' }, + ], + } + }, + { label => 'write-bandwidth', set => { + key_values => [ { name => 'pureArrayWriteBandwidth' }, ], + output_change_bytes => 2, + output_template => 'Write Bandwith : %s %s/s', + perfdatas => [ + { label => 'write_bandwidth', value => 'pureArrayWriteBandwidth_absolute', template => '%.2f', + min => 0, unit => 'b/s' }, + ], + } + }, + { label => 'read-iops', set => { + key_values => [ { name => 'pureArrayReadIOPS' } ], + output_template => 'Read IOPs : %s', + perfdatas => [ + { label => 'read_iops', value => 'pureArrayReadIOPS_absolute', template => '%s', + unit => 'iops', min => 0 }, + ], + } + }, + { label => 'write-iops', set => { + key_values => [ { name => 'pureArrayWriteIOPS' } ], + output_template => 'Write IOPs : %s', + perfdatas => [ + { label => 'write_iops', value => 'pureArrayWriteIOPS_absolute', template => '%s', + unit => 'iops', min => 0 }, + ], + } + }, + { label => 'read-latency', set => { + key_values => [ { name => 'pureArrayReadLatency' } ], + output_template => 'Read Latency : %s us/op', + perfdatas => [ + { label => 'read_latency', value => 'pureArrayReadLatency_absolute', template => '%s', + unit => 'us/op', min => 0 }, + ], + } + }, + { label => 'write-latency', set => { + key_values => [ { name => 'pureArrayWriteLatency' } ], + output_template => 'Write Latency : %s us/op', + perfdatas => [ + { label => 'write_latency', value => 'pureArrayWriteLatency_absolute', template => '%s', + unit => 'us/op', 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 => + { + }); + + return $self; +} + +my $mapping = { + pureArrayReadBandwidth => { oid => '.1.3.6.1.4.1.40482.4.1' }, + pureArrayWriteBandwidth => { oid => '.1.3.6.1.4.1.40482.4.2' }, + pureArrayReadIOPS => { oid => '.1.3.6.1.4.1.40482.4.3' }, + pureArrayWriteIOPS => { oid => '.1.3.6.1.4.1.40482.4.4' }, + pureArrayReadLatency => { oid => '.1.3.6.1.4.1.40482.4.5' }, + pureArrayWriteLatency => { oid => '.1.3.6.1.4.1.40482.4.6' }, +}; +my $oid_purePerformance = '.1.3.6.1.4.1.40482.4'; + +sub manage_selection { + my ($self, %options) = @_; + + my $snmp_result = $options{snmp}->get_table(oid => $oid_purePerformance, + nothing_quit => 1); + my $result = $options{snmp}->map_instance(mapping => $mapping, results => $snmp_result, instance => '0'); + + $result->{pureArrayReadBandwidth} *= 8; + $result->{pureArrayWriteBandwidth} *= 8; + + $self->{global} = { %$result }; +} + +1; + +__END__ + +=head1 MODE + +Check statistics performance. + +=over 8 + +=item B<--filter-counters> + +Only display some counters (regexp can be used). +Example: --filter-counters='bandwidth' + +=item B<--warning-*> + +Threshold warning. +Can be: 'read-bandwidth', 'write-bandwidth', 'read-iops', 'write-iops', +'read-latency', 'write-latency'. + +=item B<--critical-*> + +Threshold critical. +Can be: 'read-bandwidth', 'write-bandwidth', 'read-iops', 'write-iops', +'read-latency', 'write-latency'. + +=back + +=cut diff --git a/centreon-plugins/storage/purestorage/snmp/plugin.pm b/centreon-plugins/storage/purestorage/snmp/plugin.pm new file mode 100644 index 000000000..5bd3f6938 --- /dev/null +++ b/centreon-plugins/storage/purestorage/snmp/plugin.pm @@ -0,0 +1,48 @@ +# +# Copyright 2017 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::purestorage::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} = '0.1'; + %{$self->{modes}} = ( + 'stats' => 'storage::purestorage::snmp::mode::stats', + ); + + return $self; +} + +1; + +__END__ + +=head1 PLUGIN DESCRIPTION + +Check Pure Storage in SNMP. + +=cut