diff --git a/centreon-plugins/apps/activedirectory/local/mode/dcdiag.pm b/centreon-plugins/apps/activedirectory/local/mode/dcdiag.pm index 5cd950747..fabece521 100644 --- a/centreon-plugins/apps/activedirectory/local/mode/dcdiag.pm +++ b/centreon-plugins/apps/activedirectory/local/mode/dcdiag.pm @@ -37,17 +37,18 @@ sub new { $self->{version} = '1.0'; $options{options}->add_options(arguments => { - "config:s" => { name => 'config', }, - "language:s" => { name => 'language', default => 'en' }, - "dfsr" => { name => 'dfsr', }, - "noeventlog" => { name => 'noeventlog', }, - "timeout:s" => { name => 'timeout', default => 30 }, + "config:s" => { name => 'config' }, + "language:s" => { name => 'language', default => 'en' }, + "dfsr" => { name => 'dfsr' }, + "noeventlog" => { name => 'noeventlog' }, + "nomachineaccount" => { name => 'nomachineaccount' }, + "timeout:s" => { name => 'timeout', default => 30 }, }); $self->{os_is2003} = 0; $self->{os_is2008} = 0; $self->{os_is2012} = 0; - $self->{msg} = {global => undef, ok => undef, warning => undef, critical => undef}; + $self->{msg} = { global => undef, ok => undef, warning => undef, critical => undef }; return $self; } @@ -132,7 +133,8 @@ sub load_xml { sub dcdiag { my ($self, %options) = @_; - my $dcdiag_cmd = 'dcdiag /test:services /test:replications /test:advertising /test:fsmocheck /test:ridmanager /test:machineaccount'; + my $dcdiag_cmd = 'dcdiag /test:services /test:replications /test:advertising /test:fsmocheck /test:ridmanager'; + $dcdiag_cmd .= ' /test:machineaccount' if (!defined($self->{option_results}->{machineaccount})); $dcdiag_cmd .= ' /test:frssysvol' if ($self->{os_is2003} == 1); $dcdiag_cmd .= ' /test:sysvolcheck' if ($self->{os_is2008} == 1 || $self->{os_is2012} == 1); @@ -214,10 +216,14 @@ Specifies that SysVol replication uses DFS instead of FRS (Windows 2008 or later Don't run the dc tests kccevent, frsevent and dfsrevent +=item B<--nomachineaccount> + +Don't run the dc tests machineaccount + =item B<--timeout> Set timeout time for command execution (Default: 30 sec) =back -=cut \ No newline at end of file +=cut diff --git a/centreon-plugins/apps/activedirectory/local/mode/dfsrbacklog.pm b/centreon-plugins/apps/activedirectory/local/mode/dfsrbacklog.pm new file mode 100644 index 000000000..f345a3560 --- /dev/null +++ b/centreon-plugins/apps/activedirectory/local/mode/dfsrbacklog.pm @@ -0,0 +1,143 @@ +# +# 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::activedirectory::local::mode::dfsrbacklog; + +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 => 'backlog', set => { + key_values => [ { name => 'backlog' } ], + output_template => 'Backlog File Count : %s', + perfdatas => [ + { label => 'backlog', value => 'backlog_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 => + { + "sending-member:s" => { name => 'sending_member' }, + "replication-group:s" => { name => 'replication_group' }, + "replicated-folder:s" => { name => 'replicated_folder' }, + "timeout:s" => { name => 'timeout', default => 30 }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + + $self->SUPER::check_options(%options); + $self->{option_results}->{command} = 'dfsrdiag'; + $self->{option_results}->{command_options} = 'backlog '; + + if (!defined($self->{option_results}->{sending_member}) || $self->{option_results}->{sending_member} eq '') { + $self->{output}->add_option_msg(short_msg => "Need to specify sending-member option."); + $self->{output}->option_exit(); + } + $self->{option_results}->{command_options} .= '/SendingMember:' . $self->{option_results}->{sending_member} . ' '; + + if (!defined($self->{option_results}->{replication_group}) || $self->{option_results}->{replication_group} eq '') { + $self->{output}->add_option_msg(short_msg => "Need to specify replication-group option."); + $self->{output}->option_exit(); + } + $self->{option_results}->{command_options} .= '/RGName:' . $self->{option_results}->{replication_group} . ' '; + + if (!defined($self->{option_results}->{replicated_folder}) || $self->{option_results}->{replicated_folder} eq '') { + $self->{output}->add_option_msg(short_msg => "Need to specify replicated-folder option."); + $self->{output}->option_exit(); + } + $self->{option_results}->{command_options} .= '/RFName:' . $self->{option_results}->{replicated_folder} . ' '; +} + +sub manage_selection { + my ($self, %options) = @_; + + 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}); + + my $backlog = 0; + my $pattern = 'Backlog\s+File\s+Count\s*:\s+(\d+)'; + $backlog = $1 + if ($stdout =~ /$pattern/si); + + $self->{global} = { backlog => $backlog }; +} + +1; + +__END__ + +=head1 MODE + +Check dfsr backlog. + +=over 8 + +=item B<--sending-member> + +Name of the member that is sending the replication data. + +=item B<--replication-group> + +Name for the replication group. + +=item B<--replicated-folder> + +Name name for the replicated folder. + +=item B<--timeout> + +Timeout in seconds for the command (Default: 30). + +=item B<--warning-backlog> + +Threshold warning. + +=item B<--critical-backlog> + +Threshold critical. + +=back + +=cut diff --git a/centreon-plugins/apps/activedirectory/local/plugin.pm b/centreon-plugins/apps/activedirectory/local/plugin.pm index 231002867..c79e7c230 100644 --- a/centreon-plugins/apps/activedirectory/local/plugin.pm +++ b/centreon-plugins/apps/activedirectory/local/plugin.pm @@ -31,8 +31,9 @@ sub new { $self->{version} = '0.1'; %{$self->{modes}} = ( - 'dcdiag' => 'apps::activedirectory::local::mode::dcdiag', - 'netdom' => 'apps::activedirectory::local::mode::netdom', + 'dcdiag' => 'apps::activedirectory::local::mode::dcdiag', + 'dfsr-backlog' => 'apps::activedirectory::local::mode::dfsrbacklog', + 'netdom' => 'apps::activedirectory::local::mode::netdom', ); return $self; diff --git a/centreon-plugins/apps/backup/netbackup/local/mode/dedupstatus.pm b/centreon-plugins/apps/backup/netbackup/local/mode/dedupstatus.pm index e563d367e..c390efe4a 100644 --- a/centreon-plugins/apps/backup/netbackup/local/mode/dedupstatus.pm +++ b/centreon-plugins/apps/backup/netbackup/local/mode/dedupstatus.pm @@ -28,7 +28,7 @@ use centreon::plugins::misc; my $instance_mode; -sub custom_threshold_output { +sub custom_status_threshold { my ($self, %options) = @_; my $status = 'ok'; my $message; @@ -67,25 +67,35 @@ sub custom_status_calc { return 0; } +sub custom_usage_threshold { + my ($self, %options) = @_; + + if (!defined($instance_mode->{option_results}->{'critical-usage'}) || $instance_mode->{option_results}->{'critical-usage'} eq '') { + $self->{perfdata}->threshold_validate(label => 'critical-usage', value => $self->{result_values}->{watermark_absolute}); + } + return $self->{perfdata}->threshold_check(value => $self->{result_values}->{usage_absolute}, threshold => [ { label => 'critical-' . $self->{label}, exit_litteral => 'critical' }, { label => 'warning-'. $self->{label}, exit_litteral => 'warning' } ]); +} + sub set_counters { my ($self, %options) = @_; $self->{maps_counters_type} = [ - { name => 'pool', type => 1, cb_prefix_output => 'prefix_pool_output', message_multiple => 'All dedup status are ok' } + { name => 'volume', type => 1, cb_prefix_output => 'prefix_volume_output', message_multiple => 'All dedup status are ok' } ]; - $self->{maps_counters}->{pool} = [ + $self->{maps_counters}->{volume} = [ { label => 'status', threshold => 0, set => { key_values => [ { name => 'status' }, { 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_threshold_output'), + closure_custom_threshold_check => $self->can('custom_status_threshold'), } }, { label => 'usage', set => { - key_values => [ { name => 'usage' }, { name => 'display' } ], + key_values => [ { name => 'usage' }, { name => 'watermark' }, { name => 'display' } ], output_template => 'Use: %s %%', + closure_custom_threshold_check => $self->can('custom_usage_threshold'), perfdatas => [ { label => 'used', value => 'usage_absolute', template => '%s', unit => '%', min => 0, max => 100, label_extra_instance => 1, instance_use => 'display_absolute' }, @@ -103,16 +113,19 @@ sub new { $self->{version} = '1.0'; $options{options}->add_options(arguments => { - "hostname:s" => { name => 'hostname' }, - "remote" => { name => 'remote' }, - "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 }, - "sudo" => { name => 'sudo' }, - "command:s" => { name => 'command', default => 'nbdevquery' }, - "command-path:s" => { name => 'command_path' }, - "command-options:s" => { name => 'command_options', default => '-listdv -U -stype PureDisk' }, + "hostname:s" => { name => 'hostname' }, + "remote" => { name => 'remote' }, + "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 }, + "sudo" => { name => 'sudo' }, + "command:s" => { name => 'command', default => 'nbdevquery' }, + "command-path:s" => { name => 'command_path' }, + "command-options:s" => { name => 'command_options', default => '-listdp -U' }, + "command2:s" => { name => 'command2', default => 'nbdevquery' }, + "command2-path:s" => { name => 'command2_path' }, + "command2-options:s" => { name => 'command2_options', default => '-listdv -U -stype PureDisk' }, "filter-name:s" => { name => 'filter_name' }, "warning-status:s" => { name => 'warning_status', default => '' }, "critical-status:s" => { name => 'critical_status', default => '%{status} !~ /up/i' }, @@ -129,10 +142,10 @@ sub check_options { $self->change_macros(); } -sub prefix_pool_output { +sub prefix_volume_output { my ($self, %options) = @_; - return "Disk pool name '" . $options{instance_value}->{display} . "' "; + return "Disk volume '" . $options{instance_value}->{display} . "' "; } sub change_macros { @@ -153,8 +166,36 @@ sub manage_selection { sudo => $self->{option_results}->{sudo}, command => $self->{option_results}->{command}, command_path => $self->{option_results}->{command_path}, - command_options => $self->{option_results}->{command_options}); - $self->{pool} = {}; + command_options => $self->{option_results}->{command_options}); + + #Disk Pool Name : NBU-MASTER-DP + #Disk Pool Id : NBU-MASTER-DP + #Disk Type : PureDisk + #Status : UP + #Flag : Patchwork + #Raw Size (GB) : 19236.97 + #Usable Size (GB) : 19236.97 + #High Watermark : 99 + #Low Watermark : 60 + #Num Volumes : 1 + #Max IO Streams : -1 + my $watermark = {}; + while ($stdout =~ /^(Disk Pool Name.*?)(?=Disk Pool Name|\z)/msig) { + my $pool = $1; + + $pool =~ /^Disk Pool Name\s*:\s*(.*?)\n/msi; + my $display = centreon::plugins::misc::trim($1); + $pool =~ /^High Watermark\s*:\s*(.*?)\n/msi; + $watermark->{$display} = centreon::plugins::misc::trim($1); + } + + ($stdout) = centreon::plugins::misc::execute(output => $self->{output}, + options => $self->{option_results}, + sudo => $self->{option_results}->{sudo}, + command => $self->{option_results}->{command2}, + command_path => $self->{option_results}->{command2_path}, + command_options => $self->{option_results}->{command2_options}); + $self->{volume} = {}; #Disk Pool Name : NBU-MASTER-DP #Disk Type : PureDisk #Disk Volume Name : PureDiskVolume @@ -167,24 +208,26 @@ sub manage_selection { #Flag : AdminUp #Flag : InternalUp while ($stdout =~ /^(Disk Pool Name.*?)(?=Disk Pool Name|\z)/msig) { - my $pool = $1; + my $volume = $1; - my ($display, $usage, $status); - $display = centreon::plugins::misc::trim($1) if ($pool =~ /^Disk Pool Name\s*:\s*(.*?)\n/msi); - $status = $1 if ($pool =~ /^Status\s*:\s*(.*?)\n/msi); - $usage = $1 if ($pool =~ /^Use%\s*:\s*(.*?)\n/msi); + my ($pool_name, $volume_name, $usage, $status); + $pool_name = centreon::plugins::misc::trim($1) if ($volume =~ /^Disk Pool Name\s*:\s*(.*?)\n/msi); + $volume_name = centreon::plugins::misc::trim($1) if ($volume =~ /^Disk Volume Name\s*:\s*(.*?)\n/msi); + $status = $1 if ($volume =~ /^Status\s*:\s*(.*?)\n/msi); + $usage = $1 if ($volume =~ /^Use%\s*:\s*(.*?)\n/msi); + my $display = $pool_name . '.' . $volume_name; if (defined($self->{option_results}->{filter_name}) && $self->{option_results}->{filter_name} ne '' && $display !~ /$self->{option_results}->{filter_name}/) { $self->{output}->output_add(long_msg => "skipping '" . $display . "': no matching filter.", debug => 1); next; } - $self->{pool}->{$display} = { display => $display, usage => $usage, status => $status }; + $self->{volume}->{$display} = { display => $display, usage => $usage, status => $status, watermark => $watermark->{$pool_name} }; } - if (scalar(keys %{$self->{pool}}) <= 0) { - $self->{output}->add_option_msg(short_msg => "No pool found."); + if (scalar(keys %{$self->{volume}}) <= 0) { + $self->{output}->add_option_msg(short_msg => "No volume found."); $self->{output}->option_exit(); } } @@ -238,6 +281,19 @@ Command path (Default: none). =item B<--command-options> +Command options (Default: ' -listdp -U'). + +=item B<--command2> + +Command to get information (Default: 'nbdevquery'). +Can be changed if you have output in a file. + +=item B<--command2-path> + +Command path (Default: none). + +=item B<--command2-options> + Command options (Default: '-listdv -U -stype PureDisk'). =item B<--filter-name> diff --git a/centreon-plugins/apps/backup/netbackup/local/mode/jobstatus.pm b/centreon-plugins/apps/backup/netbackup/local/mode/jobstatus.pm index b2b57495a..901f345cc 100644 --- a/centreon-plugins/apps/backup/netbackup/local/mode/jobstatus.pm +++ b/centreon-plugins/apps/backup/netbackup/local/mode/jobstatus.pm @@ -165,6 +165,9 @@ sub custom_frozen_calc { $self->{result_values}->{type} = $options{new_datas}->{$self->{instance} . '_type'}; $self->{result_values}->{state} = $options{new_datas}->{$self->{instance} . '_state'}; $self->{result_values}->{kb} = $options{new_datas}->{$self->{instance} . '_kb'} - $options{old_datas}->{$self->{instance} . '_kb'}; + $self->{result_values}->{parentid} = $options{new_datas}->{$self->{instance} . '_parentid'}; + $self->{result_values}->{schedule} = $options{new_datas}->{$self->{instance} . '_schedule'}; + $self->{result_values}->{jobid} = $options{new_datas}->{$self->{instance} . '_jobid'}; return 0; } @@ -173,11 +176,23 @@ sub set_counters { my ($self, %options) = @_; $self->{maps_counters_type} = [ + { name => 'global', type => 0 }, { name => 'policy', type => 2, cb_prefix_output => 'prefix_policy_output', cb_long_output => 'policy_long_output', message_multiple => 'All policies are ok', group => [ { name => 'job', cb_prefix_output => 'prefix_job_output', skipped_code => { -11 => 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 => 'state' } ], @@ -196,7 +211,9 @@ sub set_counters { } }, { label => 'frozen', threshold => 0, set => { - key_values => [ { name => 'kb', diff => 1 }, { name => 'status' }, { name => 'display' }, { name => 'elapsed' }, { name => 'type' }, { name => 'state' } ], + key_values => [ { name => 'kb', diff => 1 }, { name => 'status' }, + { name => 'display' }, { name => 'elapsed' }, { name => 'type' }, { name => 'state' }, + { name => 'parentid' }, { name => 'schedule' }, { name => 'jobid' } ], closure_custom_calc => $self->can('custom_frozen_calc'), closure_custom_output => $self->can('custom_frozen_output'), closure_custom_perfdata => sub { return 0; }, @@ -225,7 +242,9 @@ sub new { "command-path:s" => { name => 'command_path' }, "command-options:s" => { name => 'command_options', default => '-report -most_columns' }, "filter-policy-name:s" => { name => 'filter_policy_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 => '%{status} == 0' }, "warning-status:s" => { name => 'warning_status', default => '%{status} == 1' }, "critical-status:s" => { name => 'critical_status', default => '%{status} > 1' }, @@ -297,7 +316,10 @@ sub manage_selection { my ($self, %options) = @_; $self->{cache_name} = "netbackup_" . $self->{mode} . '_' . (defined($self->{option_results}->{hostname}) ? $self->{option_results}->{hostname} : 'me') . '_' . - (defined($self->{option_results}->{filter_counters}) ? md5_hex($self->{option_results}->{filter_counters}) : md5_hex('all')); + (defined($self->{option_results}->{filter_counters}) ? md5_hex($self->{option_results}->{filter_counters}) : md5_hex('all')) . '_' . + (defined($self->{option_results}->{filter_policy_name}) ? md5_hex($self->{option_results}->{filter_policy_name}) : md5_hex('all')) . '_' . + (defined($self->{option_results}->{filter_start_time}) ? md5_hex($self->{option_results}->{filter_start_time}) : md5_hex('all')) . '_' . + (defined($self->{option_results}->{job_end_time}) ? md5_hex($self->{option_results}->{job_end_time}) : md5_hex('all')); my ($stdout) = centreon::plugins::misc::execute(output => $self->{output}, options => $self->{option_results}, @@ -305,12 +327,14 @@ sub manage_selection { command => $self->{option_results}->{command}, command_path => $self->{option_results}->{command_path}, command_options => $self->{option_results}->{command_options}); + + $self->{global} = { total => 0 }; $self->{policy} = {}; my $current_time = time(); foreach my $line (split /\n/, $stdout) { my @values = split /,/, $line; - my ($job_id, $job_type, $job_state, $job_status, $job_pname, $job_start_time, $job_end_time, $job_kb) = - ($values[0], $values[1], $values[2], $values[3], $values[4], $values[8], $values[10], $values[14]); + my ($job_id, $job_type, $job_state, $job_status, $job_pname, $job_schedule, $job_start_time, $job_end_time, $job_kb, $job_parentid) = + ($values[0], $values[1], $values[2], $values[3], $values[4], $values[5], $values[8], $values[10], $values[14], $values[33]); $job_pname = defined($job_pname) && $job_pname ne '' ? $job_pname : 'unknown'; $job_status = defined($job_status) && $job_status =~ /[0-9]/ ? $job_status : undef; @@ -319,22 +343,33 @@ sub manage_selection { $self->{output}->output_add(long_msg => "skipping job '" . $job_pname . "/" . $job_id . "': no matching filter.", debug => 1); next; } + if (defined($self->{option_results}->{filter_type}) && $self->{option_results}->{filter_type} ne '' && + $job_type{$job_type} !~ /$self->{option_results}->{filter_type}/) { + $self->{output}->output_add(long_msg => "skipping job '" . $job_pname . "/" . $job_id . "': no matching filter type.", debug => 1); + next; + } if (defined($self->{option_results}->{filter_end_time}) && $self->{option_results}->{filter_end_time} =~ /[0-9]+/ && defined($job_end_time) && $job_end_time =~ /[0-9]+/ && $job_end_time < $current_time - $self->{option_results}->{filter_end_time}) { - $self->{output}->output_add(long_msg => "skipping job '" . $job_pname . "/" . $job_id . "': too old.", debug => 1); + $self->{output}->output_add(long_msg => "skipping job '" . $job_pname . "/" . $job_id . "': end time too old.", debug => 1); + next; + } + if (defined($self->{option_results}->{filter_start_time}) && $self->{option_results}->{filter_start_time} =~ /[0-9]+/ && + defined($job_start_time) && $job_start_time =~ /[0-9]+/ && $job_start_time < $current_time - $self->{option_results}->{filter_start_time}) { + $self->{output}->output_add(long_msg => "skipping job '" . $job_pname . "/" . $job_id . "': start time too old.", debug => 1); next; } $self->{policy}->{$job_pname} = { job => {}, display => $job_pname } if (!defined($self->{policy}->{$job_pname})); my $elapsed_time = $current_time - $job_start_time; - $self->{policy}->{$job_pname}->{job}->{$job_id} = { display => $job_id, elapsed => $elapsed_time, - status => $job_status, state => $job_state{$job_state}, type => $job_type{$job_type}, - kb => defined($job_kb) && $job_kb =~ /[0-9]+/ ? $job_kb : undef }; - } - - if (scalar(keys %{$self->{policy}}) <= 0) { - $self->{output}->add_option_msg(short_msg => "No job found."); - $self->{output}->option_exit(); + $self->{policy}->{$job_pname}->{job}->{$job_id} = { + display => $job_id, elapsed => $elapsed_time, + status => $job_status, state => $job_state{$job_state}, type => $job_type{$job_type}, + kb => defined($job_kb) && $job_kb =~ /[0-9]+/ ? $job_kb : undef, + parentid => defined($job_parentid) ? $job_parentid : '', + jobid => $job_id, + schedule => defined($job_schedule) ? $job_schedule : '', + }; + $self->{global}->{total}++; } } @@ -393,6 +428,14 @@ Command options (Default: '-report -most_columns'). Filter job policy 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). @@ -425,12 +468,22 @@ Can used special variables like: %{display}, %{status}, %{elapsed}, %{type} =item B<--warning-frozen> Set warning threshold for frozen jobs (Default: none) -Can used special variables like: %{display}, %{status}, %{elapsed}, %{type}, %{kb} +Can used special variables like: +%{display}, %{status}, %{elapsed}, %{type}, %{kb}, %{parentid}, %{schedule}, %{jobid} =item B<--critical-frozen> Set critical threshold for frozen jobs (Default: '%{state} =~ /active|queue/ && %{kb} == 0'). -Can used special variables like: %{display}, %{status}, %{elapsed}, %{type}, %{kb} +Can used special variables like: +%{display}, %{status}, %{elapsed}, %{type}, %{kb}, %{parentid}, %{schedule}, %{jobid} + +=item B<--warning-total> + +Set warning threshold for total jobs. + +=item B<--critical-total> + +Set critical threshold for total jobs. =back diff --git a/centreon-plugins/apps/backup/tsm/local/custom/api.pm b/centreon-plugins/apps/backup/tsm/local/custom/api.pm new file mode 100644 index 000000000..56919a8ca --- /dev/null +++ b/centreon-plugins/apps/backup/tsm/local/custom/api.pm @@ -0,0 +1,222 @@ +# +# 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::tsm::local::custom::api; + +use strict; +use warnings; +use centreon::plugins::misc; + +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 => + { + "tsm-hostname:s" => { name => 'tsm_hostname' }, + "tsm-username:s" => { name => 'tsm_username' }, + "tsm-password:s" => { name => 'tsm_password' }, + "ssh-hostname:s" => { name => 'ssh_hostname' }, + "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 => 45 }, + "sudo" => { name => 'sudo' }, + "command:s" => { name => 'command', default => 'dsmadmc' }, + "command-path:s" => { name => 'command_path', default => '/opt/tivoli/tsm/client/ba/bin' }, + "command-options:s" => { name => 'command_options', default => '' }, + }); + } + $options{options}->add_help(package => __PACKAGE__, sections => 'TSM 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) = @_; + + if (!defined($self->{option_results}->{tsm_hostname}) || $self->{option_results}->{tsm_hostname} eq '') { + $self->{output}->add_option_msg(short_msg => "Need to set tsm-hostname option."); + $self->{output}->option_exit(); + } + if (!defined($self->{option_results}->{tsm_username}) || $self->{option_results}->{tsm_username} eq '') { + $self->{output}->add_option_msg(short_msg => "Need to set tsm-username option."); + $self->{output}->option_exit(); + } + if (!defined($self->{option_results}->{tsm_password})) { + $self->{output}->add_option_msg(short_msg => "Need to set tsm-password option."); + $self->{output}->option_exit(); + } + + return 0; +} + +sub tsm_build_options { + my ($self, %options) = @_; + + return if (defined($self->{option_results}->{command_options}) && $self->{option_results}->{command_options} ne ''); + + if (defined($self->{option_results}->{ssh_hostname}) && $self->{option_results}->{ssh_hostname} ne '') { + $self->{option_results}->{hostname} = $self->{option_results}->{ssh_hostname}; + $self->{option_results}->{remote} = 1; + } + + $self->{option_results}->{command_options} = + "-comma -dataonly=yes -SERVER=\"$self->{option_results}->{tsm_hostname}\" -ID=\"$self->{option_results}->{tsm_username}\" -PASSWORD=\"$self->{option_results}->{tsm_password}\" -TAB \"$options{query}\""; +} + +sub get_tsm_id { + my ($self, %options) = @_; + + return $self->{option_results}->{tsm_hostname} . '_' . $self->{option_results}->{tsm_username} . '_' . $self->{option_results}->{tsm_password}; +} + +sub execute_command { + my ($self, %options) = @_; + + $self->tsm_build_options(%options); + my ($response, $exit_code) = 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 => $self->{option_results}->{command_options}, + no_quit => 1 + ); + + # 11 is for: ANR2034E SELECT: No match found using this criteria. + if ($exit_code != 0 && $exit_code != 11) { + $self->{output}->output_add(long_msg => $response); + $self->{output}->add_option_msg(short_msg => "Execution command issue (details)."); + $self->{output}->option_exit(); + } + + $self->{output}->output_add(long_msg => $response, debug => 1); + return $response; +} + +1; + +__END__ + +=head1 NAME + +tsm cli + +=head1 SYNOPSIS + +my tsm cli + +=head1 TSM CLI OPTIONS + +=over 8 + +=item B<--tsm-hostname> + +TSM hostname to query (Required). + +=item B<--tsm-username> + +TSM username (Required). + +=item B<--tsm-password> + +TSM password (Required). + +=item B<--ssh-hostname> + +Specify SSH hostname. + +=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: 45). + +=item B<--sudo> + +Use 'sudo' to execute the command. + +=item B<--command> + +Specify command (default: 'dsmadmc'). + +=item B<--command-path> + +Specify path (default: '/opt/tivoli/tsm/client/ba/bin') + +=item B<--command-options> + +Command options. + +=back + +=head1 DESCRIPTION + +B. + +=cut diff --git a/centreon-plugins/apps/backup/tsm/local/mode/actlog.pm b/centreon-plugins/apps/backup/tsm/local/mode/actlog.pm new file mode 100644 index 000000000..c60f78528 --- /dev/null +++ b/centreon-plugins/apps/backup/tsm/local/mode/actlog.pm @@ -0,0 +1,215 @@ +# +# 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::tsm::local::mode::actlog; + +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 [severity: %s] [message: %s] %s", $self->{result_values}->{severity}, + $self->{result_values}->{message}, $self->{result_values}->{generation_time}); + return $msg; +} + +sub custom_status_calc { + my ($self, %options) = @_; + + $self->{result_values}->{message} = $options{new_datas}->{$self->{instance} . '_message'}; + $self->{result_values}->{severity} = $options{new_datas}->{$self->{instance} . '_severity'}; + $self->{result_values}->{since} = $options{new_datas}->{$self->{instance} . '_since'}; + $self->{result_values}->{generation_time} = $options{new_datas}->{$self->{instance} . '_generation_time'}; + 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 => 'message' }, { name => 'severity' }, { name => 'since' }, { name => 'generation_time' } ], + 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-time:s" => { name => 'filter_time', default => '1' }, + "warning-status:s" => { name => 'warning_status', default => '%{severity} =~ /warning/' }, + "critical-status:s" => { name => 'critical_status', default => '%{severity} =~ /error|severe/' }, + "memory" => { name => 'memory' }, + "timezone:s" => { name => 'timezone' }, + }); + + centreon::plugins::misc::mymodule_load(output => $self->{output}, module => 'DateTime', + error_msg => "Cannot load module 'DateTime'."); + $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); + } + + $self->{option_results}->{timezone} = 'GMT' if (!defined($self->{option_results}->{timezone}) || $self->{option_results}->{timezone} eq ''); +} + +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 $response = $options{custom}->execute_command( + query => "SELECT date_time, severity, message FROM actlog WHERE date_time>current_timestamp-" . $self->{option_results}->{filter_time} . " hours" + ); + $self->{alarms}->{global} = { alarm => {} }; + my $last_time; + if (defined($self->{option_results}->{memory})) { + $self->{statefile_cache}->read(statefile => 'cache_tsm_' . $self->{mode} . '_' . $options{custom}->get_tsm_id()); + $last_time = $self->{statefile_cache}->get(name => 'last_time'); + } + + my %map_severity = (E => 'error', W => 'warning', I => 'information', S => 'severe', K => 'kernel'); + my ($i, $current_time) = (1, time()); + #2017-09-19 12:08:14.000000,I,"ANR1283I File count is incorrect fo..." + while ($response =~ /^(.*?),(.*?),(.*)$/mg) { + my ($date, $severity, $message) = ($1, $2, $3); + $date =~ /^(\d+)-(\d+)-(\d+)\s+(\d+)[:\/](\d+)[:\/](\d+)/; + + my $dt = DateTime->new(year => $1, month => $2, day => $3, hour => $4, minute => $5, second => $6, + time_zone => $self->{option_results}->{timezone}); + + next if (defined($self->{option_results}->{memory}) && defined($last_time) && $last_time > $dt->epoch); + + my $diff_time = $current_time - $dt->epoch; + + $message =~ s/^"(.*)"$/$1/; + $self->{alarms}->{global}->{alarm}->{$i} = { + message => $message, + severity => $map_severity{$severity}, + since => $diff_time, generation_time => centreon::plugins::misc::change_seconds(value => $diff_time) + }; + $i++; + } + + if (defined($self->{option_results}->{memory})) { + $self->{statefile_cache}->write(data => { last_time => $current_time }); + } +} + +1; + +__END__ + +=head1 MODE + +Check activity logs. + +=over 8 + +=item B<--filter-time> + +Get activity log more recent than X hour(s) (default: '1'). + +=item B<--warning-status> + +Set warning threshold for status (Default: '%{severity} =~ /warning/') +Can used special variables like: %{message}, %{severity}, %{since} + +=item B<--critical-status> + +Set critical threshold for status (Default: '%{severity} =~ /error|severe/'). +Can used special variables like: %{message}, %{severity}, %{since} + +=item B<--timezone> + +Timezone of time options. Default is 'GMT'. + +=item B<--memory> + +Only check new alarms. + +=back + +=cut + diff --git a/centreon-plugins/apps/backup/tsm/local/mode/drives.pm b/centreon-plugins/apps/backup/tsm/local/mode/drives.pm new file mode 100644 index 000000000..a22415130 --- /dev/null +++ b/centreon-plugins/apps/backup/tsm/local/mode/drives.pm @@ -0,0 +1,165 @@ +# +# 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::tsm::local::mode::drives; + +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_global_output' }, + ]; + + $self->{maps_counters}->{global} = [ + { label => 'online', set => { + key_values => [ { name => 'online' } ], + output_template => 'online : %s', + perfdatas => [ + { label => 'online', value => 'online_absolute', template => '%s', min => 0 }, + ], + } + }, + { label => 'offline', set => { + key_values => [ { name => 'offline' } ], + output_template => 'offline : %s', + perfdatas => [ + { label => 'offline', value => 'offline_absolute', template => '%s', min => 0 }, + ], + } + }, + { label => 'unavailable', set => { + key_values => [ { name => 'unavailable' } ], + output_template => 'unavailable : %s', + perfdatas => [ + { label => 'unavailable', value => 'unavailable_absolute', template => '%s', min => 0 }, + ], + } + }, + { label => 'empty', set => { + key_values => [ { name => 'empty' } ], + output_template => 'empty : %s', + perfdatas => [ + { label => 'empty', value => 'empty_absolute', template => '%s', min => 0 }, + ], + } + }, + { label => 'loaded', set => { + key_values => [ { name => 'loaded' } ], + output_template => 'loaded : %s', + perfdatas => [ + { label => 'loaded', value => 'loaded_absolute', template => '%s', min => 0 }, + ], + } + }, + { label => 'unloaded', set => { + key_values => [ { name => 'unloaded' } ], + output_template => 'unloaded : %s', + perfdatas => [ + { label => 'unloaded', value => 'unloaded_absolute', template => '%s', min => 0 }, + ], + } + }, + { label => 'reserved', set => { + key_values => [ { name => 'reserved' } ], + output_template => 'reserved : %s', + perfdatas => [ + { label => 'reserved', value => 'reserved_absolute', template => '%s', min => 0 }, + ], + } + }, + { label => 'unknown', set => { + key_values => [ { name => 'unknown' } ], + output_template => 'unknown : %s', + perfdatas => [ + { label => 'unknown', value => 'unknown_absolute', template => '%s', min => 0 }, + ], + } + }, + ]; +} + +sub prefix_global_output { + my ($self, %options) = @_; + + return "Total Drives "; +} + +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 $response = $options{custom}->execute_command( + query => "SELECT library_name, drive_name, online, drive_state FROM drives" + ); + $self->{global} = { + online => 0, offline => 0, + unavailable => 0, empty => 0, loaded => 0, unloaded => 0, reserved => 0, unknown => 0, + }; + + my %mapping_online = (yes => 'online', no => 'offline'); + while ($response =~ /^(.*?),(.*?),(yes|no),(unavailable|empty|loaded|unloaded|reserved|unknown)$/mgi) { + my ($library, $drive, $online, $state) = ($1, $2, lc($3), lc($4)); + + $self->{global}->{$mapping_online{$online}}++; + $self->{global}->{$state}++; + } +} + +1; + +__END__ + +=head1 MODE + +Check drives. + +=over 8 + +=item B<--warning-*> + +Set warning threshold. Can be : 'online', 'offline', 'unavailable', +'empty', 'loaded', 'unloaded', 'reserved', 'unknown'. + +=item B<--critical-*> + +Set critical threshold. Can be : Can be : 'online', 'offline', 'unavailable', +'empty', 'loaded', 'unloaded', 'reserved', 'unknown'. + +=back + +=cut + diff --git a/centreon-plugins/apps/backup/tsm/local/mode/nodes.pm b/centreon-plugins/apps/backup/tsm/local/mode/nodes.pm new file mode 100644 index 000000000..5f944ad18 --- /dev/null +++ b/centreon-plugins/apps/backup/tsm/local/mode/nodes.pm @@ -0,0 +1,113 @@ +# +# 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::tsm::local::mode::nodes; + +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 => 'associated', set => { + key_values => [ { name => 'associated' } ], + output_template => 'Total Associated Nodes : %s', + perfdatas => [ + { label => 'associated', value => 'associated_absolute', template => '%s', min => 0 }, + ], + } + }, + { label => 'non-associated', set => { + key_values => [ { name => 'non_associated' } ], + output_template => 'Total Non Associated Nodes : %s', + perfdatas => [ + { label => 'non_associated', value => 'non_associated_absolute', template => '%s', min => 0 }, + ], + } + }, + { label => 'locked', set => { + key_values => [ { name => 'locked' } ], + output_template => 'Total Locked Nodes : %s', + perfdatas => [ + { label => 'locked', value => 'locked_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 $response = $options{custom}->execute_command( + query => "SELECT node_name, 'non_associated' FROM nodes WHERE node_name NOT IN (SELECT node_name FROM associations) UNION SELECT node_name, 'associated' FROM nodes WHERE node_name IN (SELECT node_name FROM associations) UNION SELECT node_name, 'locked' FROM nodes WHERE locked='YES'" + ); + $self->{global} = { associated => 0, non_associated => 0, locked => 0 }; + + while ($response =~ /^(.*?),(non_associated|associated|locked)$/mg) { + my ($node_name, $type) = ($1, $2); + + $self->{global}->{$type}++; + $self->{output}->output_add(long_msg => "node '$node_name' is $type"); + } +} + +1; + +__END__ + +=head1 MODE + +Check node status. + +=over 8 + +=item B<--warning-*> + +Set warning threshold. Can be : 'associated', 'non-associated', 'locked'. + +=item B<--critical-*> + +Set critical threshold. Can be : Can be : 'associated', 'non-associated', 'locked'. + +=back + +=cut + diff --git a/centreon-plugins/apps/backup/tsm/local/mode/sessions.pm b/centreon-plugins/apps/backup/tsm/local/mode/sessions.pm new file mode 100644 index 000000000..945e62c4c --- /dev/null +++ b/centreon-plugins/apps/backup/tsm/local/mode/sessions.pm @@ -0,0 +1,247 @@ +# +# 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::tsm::local::mode::sessions; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; +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]; }; + + 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("[client name: %s] [state: %s] [session type: %s] started since", + $self->{result_values}->{client_name}, $self->{result_values}->{state}, + $self->{result_values}->{session_type}, $self->{result_values}->{generation_time}); + return $msg; +} + +sub custom_status_calc { + my ($self, %options) = @_; + + $self->{result_values}->{session_id} = $options{new_datas}->{$self->{instance} . '_session_id'}; + $self->{result_values}->{client_name} = $options{new_datas}->{$self->{instance} . '_client_name'}; + $self->{result_values}->{session_type} = $options{new_datas}->{$self->{instance} . '_session_type'}; + $self->{result_values}->{state} = $options{new_datas}->{$self->{instance} . '_state'}; + $self->{result_values}->{since} = $options{new_datas}->{$self->{instance} . '_since'}; + $self->{result_values}->{generation_time} = $options{new_datas}->{$self->{instance} . '_generation_time'}; + return 0; +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'global', type => 0 }, + { name => 'sessions', type => 1, cb_prefix_output => 'prefix_sessions_output', message_multiple => 'All sessions are ok' }, + ]; + + $self->{maps_counters}->{global} = [ + { label => 'total', set => { + key_values => [ { name => 'total' } ], + output_template => 'Total Sessions : %s', + perfdatas => [ + { label => 'total', value => 'total_absolute', template => '%s', min => 0 }, + ], + } + }, + ]; + + $self->{maps_counters}->{sessions} = [ + { label => 'status', threshold => 0, set => { + key_values => [ { name => 'session_id' }, { name => 'client_name' }, { name => 'session_type' }, + { name => 'state' }, { name => 'since' }, { name => 'generation_time' } ], + 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 prefix_sessions_output { + my ($self, %options) = @_; + + return "Session '" . $options{instance_value}->{session_id} . "' "; +} + +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-clientname:s" => { name => 'filter_clientname' }, + "filter-sessiontype:s" => { name => 'filter_sessiontype' }, + "filter-state:s" => { name => 'filter_state' }, + "warning-status:s" => { name => 'warning_status', default => '' }, + "critical-status:s" => { name => 'critical_status', default => '' }, + "timezone:s" => { name => 'timezone' }, + }); + + centreon::plugins::misc::mymodule_load(output => $self->{output}, module => 'DateTime', + error_msg => "Cannot load module 'DateTime'."); + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::check_options(%options); + + $instance_mode = $self; + $self->change_macros(); + + $self->{option_results}->{timezone} = 'GMT' if (!defined($self->{option_results}->{timezone}) || $self->{option_results}->{timezone} eq ''); +} + +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 $response = $options{custom}->execute_command( + query => "SELECT session_id, client_name, start_time, state, session_type FROM sessions" + ); + $self->{sessions} = {}; + $self->{global} = { total => 0 }; + + while ($response =~ /^(.*?),(.*?),(.*?),(.*?),(.*?)$/mg) { + my ($session_id, $client_name, $start_time, $state, $session_type) = ($1, $2, $3, $4, $5); + $start_time =~ /^(\d+)-(\d+)-(\d+)\s+(\d+)[:\/](\d+)[:\/](\d+)/; + + my $dt = DateTime->new(year => $1, month => $2, day => $3, hour => $4, minute => $5, second => $6, + time_zone => $self->{option_results}->{timezone}); + + if (defined($self->{option_results}->{filter_clientname}) && $self->{option_results}->{filter_clientname} ne '' && + $client_name !~ /$self->{option_results}->{filter_clientname}/) { + $self->{output}->output_add(long_msg => "skipping '" . $client_name . "': no matching client name filter.", debug => 1); + next; + } + if (defined($self->{option_results}->{filter_sessiontype}) && $self->{option_results}->{filter_sessiontype} ne '' && + $session_type !~ /$self->{option_results}->{filter_sessiontype}/) { + $self->{output}->output_add(long_msg => "skipping '" . $session_type . "': no matching session type filter.", debug => 1); + next; + } + if (defined($self->{option_results}->{filter_state}) && $self->{option_results}->{filter_state} ne '' && + $state !~ /$self->{option_results}->{filter_state}/) { + $self->{output}->output_add(long_msg => "skipping '" . $session_type . "': no matching state filter.", debug => 1); + next; + } + + my $diff_time = time() - $dt->epoch; + $self->{global}->{total}++; + + $self->{sessions}->{$session_id} = { + session_id => $session_id, + client_name => $client_name, + state => $state, + session_type => $session_type, + since => $diff_time, generation_time => centreon::plugins::misc::change_seconds(value => $diff_time) + }; + } +} + +1; + +__END__ + +=head1 MODE + +Check sessions. + +=over 8 + +=item B<--filter-clientname> + +Filter by client name. + +=item B<--filter-state> + +Filter by state. + +=item B<--filter-sessiontype> + +Filter by session type. + +=item B<--warning-status> + +Set warning threshold for status (Default: '') +Can used special variables like: %{client_name}, %{state}, %{session_type}, %{since} + +=item B<--critical-status> + +Set critical threshold for status (Default: ''). +Can used special variables like: %{client_name}, %{state}, %{session_type}, %{since} + +=item B<--warning-*> + +Set warning threshold. Can be : 'total'. + +=item B<--critical-*> + +Set critical threshold. Can be : 'total'. + +=item B<--timezone> + +Timezone of time options. Default is 'GMT'. + +=back + +=cut + diff --git a/centreon-plugins/apps/backup/tsm/local/mode/volumes.pm b/centreon-plugins/apps/backup/tsm/local/mode/volumes.pm new file mode 100644 index 000000000..c01a90bfd --- /dev/null +++ b/centreon-plugins/apps/backup/tsm/local/mode/volumes.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 apps::backup::tsm::local::mode::volumes; + +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 }, + { name => 'volumes', type => 1, cb_prefix_output => 'prefix_volumes_output', message_multiple => 'All volumes are ok' }, + ]; + + $self->{maps_counters}->{global} = [ + { label => 'total', set => { + key_values => [ { name => 'total' } ], + output_template => 'Volumes Total : %s', + perfdatas => [ + { label => 'total', value => 'total_absolute', template => '%s', min => 0 }, + ], + } + }, + { label => 'online', set => { + key_values => [ { name => 'online' } ], + output_template => 'Online : %s', + perfdatas => [ + { label => 'online', value => 'online_absolute', template => '%s', min => 0 }, + ], + } + }, + { label => 'offline', set => { + key_values => [ { name => 'offline' } ], + output_template => 'Offline : %s', + perfdatas => [ + { label => 'offline', value => 'offline_absolute', template => '%s', min => 0 }, + ], + } + }, + { label => 'empty', set => { + key_values => [ { name => 'empty' } ], + output_template => 'Empty : %s', + perfdatas => [ + { label => 'empty', value => 'empty_absolute', template => '%s', min => 0 }, + ], + } + }, + { label => 'pending', set => { + key_values => [ { name => 'pending' } ], + output_template => 'Pending : %s', + perfdatas => [ + { label => 'pending', value => 'pending_absolute', template => '%s', min => 0 }, + ], + } + }, + { label => 'filling', set => { + key_values => [ { name => 'filling' } ], + output_template => 'Filling : %s', + perfdatas => [ + { label => 'filling', value => 'filling_absolute', template => '%s', min => 0 }, + ], + } + }, + { label => 'full', set => { + key_values => [ { name => 'full' } ], + output_template => 'Full : %s', + perfdatas => [ + { label => 'full', value => 'full_absolute', template => '%s', min => 0 }, + ], + } + }, + ]; + + $self->{maps_counters}->{volumes} = [ + { label => 'used', set => { + key_values => [ { name => 'prct_utilized' }, { name => 'display' } ], + output_template => 'Usage : %s %%', + perfdatas => [ + { label => 'used', value => 'prct_utilized_absolute', template => '%s', min => 0, max => 100, + unit => '%', label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + ]; +} + +sub prefix_volumes_output { + my ($self, %options) = @_; + + return "Volumes '" . $options{instance_value}->{display} . "' "; +} + +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-volume:s" => { name => 'filter_volume' }, + "filter-stgpool:s" => { name => 'filter_stgpool' }, + }); + + return $self; +} + +sub manage_selection { + my ($self, %options) = @_; + + my $response = $options{custom}->execute_command( + query => "SELECT volume_name, stgpool_name, status, pct_utilized FROM volumes" + ); + $self->{volumes} = {}; + $self->{global} = { total => 0, online => 0, offline => 0, empty => 0, pending => 0, filling => 0, full => 0 }; + + while ($response =~ /^(.*?),(.*?),(.*?),(.*?)$/mg) { + my ($volume_name, $stgpool, $status, $pct_utilized) = ($1, $2, $3, $4); + + if (defined($self->{option_results}->{filter_volume}) && $self->{option_results}->{filter_volume} ne '' && + $volume_name !~ /$self->{option_results}->{filter_volume}/) { + $self->{output}->output_add(long_msg => "skipping '" . $volume_name . "': no matching volume name filter.", debug => 1); + next; + } + if (defined($self->{option_results}->{filter_stgpool}) && $self->{option_results}->{filter_stgpool} ne '' && + $stgpool !~ /$self->{option_results}->{filter_stgpool}/) { + $self->{output}->output_add(long_msg => "skipping '" . $stgpool . "': no matching storage pool filter.", debug => 1); + next; + } + + $self->{global}->{total}++; + $self->{global}->{lc($status)}++; + + $self->{volumes}->{$volume_name} = { + display => $volume_name, + prct_utilized => $pct_utilized, + }; + } +} + +1; + +__END__ + +=head1 MODE + +Check volumes. + +=over 8 + +=item B<--filter-volume> + +Filter by volume name. + +=item B<--filter-stgpool> + +Filter by storage pool name. + +=item B<--warning-*> + +Set warning threshold. Can be : 'total', 'used', +'online',' offline', 'empty', 'pending', 'filling', full'. + +=item B<--critical-*> + +Set critical threshold. Can be : 'total', 'used', +'online', 'offline', empty', 'pending', 'filling', full'. + +=back + +=cut + diff --git a/centreon-plugins/apps/backup/tsm/local/plugin.pm b/centreon-plugins/apps/backup/tsm/local/plugin.pm new file mode 100644 index 000000000..5a4d001d5 --- /dev/null +++ b/centreon-plugins/apps/backup/tsm/local/plugin.pm @@ -0,0 +1,53 @@ +# +# 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::tsm::local::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}} = ( + 'actlog' => 'apps::backup::tsm::local::mode::actlog', + 'drives' => 'apps::backup::tsm::local::mode::drives', + 'nodes' => 'apps::backup::tsm::local::mode::nodes', + 'sessions' => 'apps::backup::tsm::local::mode::sessions', + 'volumes' => 'apps::backup::tsm::local::mode::volumes', + ); + + $self->{custom_modes}{api} = 'apps::backup::tsm::local::custom::api'; + return $self; +} + +1; + +__END__ + +=head1 PLUGIN DESCRIPTION + +Check IBM Tivoli Storage Manager (use dsmadmc). + +=cut diff --git a/centreon-plugins/apps/centreon/local/mode/brokerstats.pm b/centreon-plugins/apps/centreon/local/mode/brokerstats.pm new file mode 100644 index 000000000..10b1d9704 --- /dev/null +++ b/centreon-plugins/apps/centreon/local/mode/brokerstats.pm @@ -0,0 +1,289 @@ +# +# 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::centreon::local::mode::brokerstats; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; +use centreon::plugins::misc; +use JSON; + +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'; + } + }; + if (defined($message)) { + $self->{output}->output_add(long_msg => 'filter status issue: ' . $message); + } + + return $status; +} + +sub custom_status_output { + my ($self, %options) = @_; + my $msg; + + if ($self->{result_values}->{type} eq 'input') { + $msg = sprintf("state : %s", $self->{result_values}->{state}); + } else { + $msg = sprintf("state : %s [status : %s] [queue file enabled : %s]", + $self->{result_values}->{state}, $self->{result_values}->{status}, $self->{result_values}->{queue_file_enabled}); + } + return $msg; +} + +sub custom_status_calc { + my ($self, %options) = @_; + + $self->{result_values}->{queue_file_enabled} = $options{new_datas}->{$self->{instance} . '_queue_file_enabled'}; + $self->{result_values}->{state} = $options{new_datas}->{$self->{instance} . '_state'}; + $self->{result_values}->{status} = $options{new_datas}->{$self->{instance} . '_status'}; + $self->{result_values}->{type} = $options{new_datas}->{$self->{instance} . '_type'}; + $self->{result_values}->{display} = $options{new_datas}->{$self->{instance} . '_display'}; + return 0; +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'endpoint', type => 1, cb_prefix_output => 'prefix_endpoint_output', message_multiple => 'Broker statistics are ok', skipped_code => { -10 => 1 } } + ]; + + $self->{maps_counters}->{endpoint} = [ + { label => 'status', threshold => 0, set => { + key_values => [ { name => 'queue_file_enabled' }, { name => 'state' }, { name => 'status' }, { name => 'type' }, { 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_threshold_output'), + } + }, + { label => 'speed-events', set => { + key_values => [ { name => 'speed_events' }, { name => 'display' } ], + output_template => 'Speed Events: %s/s', + perfdatas => [ + { label => 'speed_events', value => 'speed_events_absolute', template => '%s', + unit => 'events/s', min => 0, label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + { label => 'queued-events', set => { + key_values => [ { name => 'queued_events' }, { name => 'display' } ], + output_template => 'Queued Events: %s', + perfdatas => [ + { label => 'queued_events', value => 'queued_events_absolute', template => '%s', + unit => 'events', min => 0, label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + { label => 'unacknowledged-events', set => { + key_values => [ { name => 'unacknowledged_events' }, { name => 'display' } ], + output_template => 'Unacknowledged Events: %s', + perfdatas => [ + { label => 'unacknowledged_events', value => 'unacknowledged_events_absolute', template => '%s', + unit => 'events', 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 => + { + "broker-stats-file:s@" => { name => 'broker_stats_file' }, + "hostname:s" => { name => 'hostname' }, + "remote" => { name => 'remote' }, + "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 }, + "sudo" => { name => 'sudo' }, + "filter-name:s" => { name => 'filter_name' }, + "warning-status:s" => { name => 'warning_status', default => '' }, + "critical-status:s" => { name => 'critical_status', default => '%{type} eq "output" and %{queue_file_enabled} =~ /yes/i' }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::check_options(%options); + + if (!defined($self->{option_results}->{broker_stats_file}) || scalar(@{$self->{option_results}->{broker_stats_file}}) == 0) { + $self->{output}->add_option_msg(short_msg => "Please set broker-stats-file option."); + $self->{output}->option_exit(); + } + $instance_mode = $self; + $self->change_macros(); +} + +sub prefix_endpoint_output { + my ($self, %options) = @_; + + return "Endpoint $options{instance_value}->{type} '" . $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->{endpoint} = {}; + foreach my $config (@{$self->{option_results}->{broker_stats_file}}) { + my ($stdout) = centreon::plugins::misc::execute(output => $self->{output}, + options => $self->{option_results}, + sudo => $self->{option_results}->{sudo}, + command => 'cat', + command_options => $config); + my $json; + eval { + $json = decode_json($stdout); + }; + if ($@) { + $self->{output}->add_option_msg(short_msg => "Cannot decode json response: $@"); + $self->{output}->option_exit(); + } + + foreach my $entry (keys %$json) { + next if ($entry !~ /^endpoint/); + + my $endpoint = $entry; + $endpoint =~ s/endpoint //; + my $state = $json->{$entry}->{state}; + my $type = 'output'; + $type = 'input' if (!defined($json->{$entry}->{status})); + + $self->{endpoint}->{$endpoint} = { + display => $endpoint, + state => $state, + type => $type, + status => defined($json->{$entry}->{status}) ? $json->{$entry}->{status} : '-', + speed_events => $json->{$entry}->{event_processing_speed}, + queued_events => $json->{$entry}->{queued_events}, + unacknowledged_events => $json->{$entry}->{bbdo_unacknowledged_events}, + queue_file_enabled => defined($json->{$entry}->{queue_file_enabled}) ? $json->{$entry}->{queue_file_enabled} : '-', + }; + } + } + + if (scalar(keys %{$self->{endpoint}}) <= 0) { + $self->{output}->add_option_msg(short_msg => "No endpoint found."); + $self->{output}->option_exit(); + } +} + +1; + +__END__ + +=head1 MODE + +Check Centreon Broker statistics files. + +=over 8 + +=item B<--remote> + +Execute command remotely in 'ssh'. + +=item B<--hostname> + +Hostname to query (need --remote). + +=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<--sudo> + +Use 'sudo' to execute the command. + +=item B<--broker-stats-file> + +Specify the centreon-broker json stats file (Required). Can be multiple. + +=item B<--warning-*> + +Threshold warning. +Can be: 'speed-events', 'queued-events', 'unacknowledged-events'. + +=item B<--critical-*> + +Threshold critical. +Can be: 'speed-events', 'queued-events', 'unacknowledged-events'. + +=item B<--warning-status> + +Set warning threshold for status. +Can used special variables like: %{queue_file_enabled}, %{state}, %{status}, %{type}, %{display} + +=item B<--critical-status> + +Set critical threshold for status (Default: '%{type} eq "output" and %{queue_file_enabled} =~ /yes/i'). +Can used special variables like: %{queue_file_enabled}, %{state}, %{status}, %{type}, %{display} + +=back + +=cut diff --git a/centreon-plugins/apps/centreon/local/mode/retentionbroker.pm b/centreon-plugins/apps/centreon/local/mode/retentionbroker.pm index 5f064ca3e..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,16 +123,16 @@ 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; $total_size += $size; my ($size_value, $size_unit) = $self->{perfdata}->change_bytes(value => $size); - $self->{output}->output_add(long_msg => sprintf("failover '%s': %d file(s) finded (%s)", + $self->{output}->output_add(long_msg => sprintf("failover '%s': %d file(s) found (%s)", $failover, $total, $size_value . ' ' . $size_unit)); } @@ -149,7 +149,7 @@ sub run { my ($status, $total, $size) = $self->check_directory(config => $config, path => $temporary); if ($status) { my ($size_value, $size_unit) = $self->{perfdata}->change_bytes(value => $size); - $self->{output}->output_add(long_msg => sprintf("temporary: %d file(s) finded (%s)", + $self->{output}->output_add(long_msg => sprintf("temporary: %d file(s) found (%s)", $total, $size_value . ' ' . $size_unit)); if ($total > 0) { $self->{output}->output_add(severity => 'CRITICAL', diff --git a/centreon-plugins/apps/centreon/local/plugin.pm b/centreon-plugins/apps/centreon/local/plugin.pm index 87fc4823f..65f53fa91 100644 --- a/centreon-plugins/apps/centreon/local/plugin.pm +++ b/centreon-plugins/apps/centreon/local/plugin.pm @@ -31,6 +31,7 @@ sub new { $self->{version} = '0.1'; %{$self->{modes}} = ( + 'broker-stats' => 'apps::centreon::local::mode::brokerstats', 'centreon-plugins-version' => 'apps::centreon::local::mode::centreonpluginsversion', 'downtime-trap' => 'apps::centreon::local::mode::downtimetrap', 'metaservice' => 'apps::centreon::local::mode::metaservice', diff --git a/centreon-plugins/apps/centreon/map/jmx/mode/gates.pm b/centreon-plugins/apps/centreon/map/jmx/mode/gates.pm index b70a32f56..9291f8491 100644 --- a/centreon-plugins/apps/centreon/map/jmx/mode/gates.pm +++ b/centreon-plugins/apps/centreon/map/jmx/mode/gates.pm @@ -58,22 +58,22 @@ sub run { $self->{connector} = $options{custom}; $self->{request} = [ - { mbean => "com.centreon.studio.map:name=BusinessGate,type=repo" } + { mbean => "com.centreon.studio.map:name=statistics,type=context" } ]; my $result = $self->{connector}->get_attributes(request => $self->{request}, nothing_quit => 1); - my $gates = $result->{"com.centreon.studio.map:name=BusinessGate,type=repo"}->{LoadedModelCount}; + my $gates = $result->{"com.centreon.studio.map:name=statistics,type=context"}->{OpenContextCount}; my $exit = $self->{perfdata}->threshold_check(value => $gates, threshold => [ { label => 'critical', exit_litteral => 'critical' }, { label => 'warning', exit_litteral => 'warning'} ]); $self->{output}->output_add(severity => $exit, short_msg => sprintf("Business gates opened : %d", - $result->{"com.centreon.studio.map:name=BusinessGate,type=repo"}->{LoadedModelCount})); + $result->{"com.centreon.studio.map:name=statistics,type=context"}->{OpenContextCount})); $self->{output}->perfdata_add(label => 'gates', - value => $result->{"com.centreon.studio.map:name=BusinessGate,type=repo"}->{LoadedModelCount}, + value => $result->{"com.centreon.studio.map:name=statistics,type=context"}->{OpenContextCount}, warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning'), critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical'), min => 0); diff --git a/centreon-plugins/apps/elasticsearch/mode/cluster.pm b/centreon-plugins/apps/elasticsearch/mode/cluster.pm deleted file mode 100644 index 79b398efe..000000000 --- a/centreon-plugins/apps/elasticsearch/mode/cluster.pm +++ /dev/null @@ -1,204 +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::elasticsearch::mode::cluster; - -use base qw(centreon::plugins::mode); - -use strict; -use warnings; -use centreon::plugins::http; -use JSON; - -my $thresholds = { - cluster => [ - ['green', 'OK'], - ['yellow', 'WARNING'], - ['red', 'CRITICAL'], - ], -}; - -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 => 9200 }, - "proto:s" => { name => 'proto' }, - "urlpath:s" => { name => 'url_path', default => '/_cluster/health' }, - "credentials" => { name => 'credentials' }, - "username:s" => { name => 'username' }, - "password:s" => { name => 'password' }, - "timeout:s" => { name => 'timeout' }, - "threshold-overload:s@" => { name => 'threshold_overload' }, - }); - - $self->{http} = centreon::plugins::http->new(output => $self->{output}); - return $self; -} - -sub check_options { - my ($self, %options) = @_; - $self->SUPER::init(%options); - - $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}; - } - - $self->{http}->set_options(%{$self->{option_results}}); -} - -sub get_severity { - my ($self, %options) = @_; - my $status = 'UNKNOWN'; # default - - if (defined($self->{overload_th}->{$options{section}})) { - foreach (@{$self->{overload_th}->{$options{section}}}) { - if ($options{value} =~ /$_->{filter}/i) { - $status = $_->{status}; - return $status; - } - } - } - foreach (@{$thresholds->{$options{section}}}) { - if ($options{value} =~ /$$_[0]/i) { - $status = $$_[1]; - return $status; - } - } - return $status; -} - - -sub run { - my ($self, %options) = @_; - - my $jsoncontent = $self->{http}->request(); - - my $json = JSON->new; - - my $webcontent; - - eval { - $webcontent = $json->decode($jsoncontent); - }; - - if ($@) { - $self->{output}->add_option_msg(short_msg => "Cannot decode json response"); - $self->{output}->option_exit(); - } - - my $exit = $self->get_severity(section => 'cluster', value => $webcontent->{status}); - - if ($webcontent->{status} eq 'green') { - $self->{output}->output_add(severity => $exit, - short_msg => sprintf("All shard are allocated for %s", $webcontent->{cluster_name})); - } elsif ($webcontent->{status} eq 'yellow') { - $self->{output}->output_add(severity => $exit, - short_msg => sprintf("Primary shards are allocated but replicas not for %s", $webcontent->{cluster_name})); - } elsif ($webcontent->{status} eq 'red') { - $self->{output}->output_add(severity => $exit, - short_msg => sprintf("Some or all primary shards aren't ready for %s", $webcontent->{cluster_name})); - } - - $self->{output}->perfdata_add(label => 'primary_shard', - value => sprintf("%d", $webcontent->{active_primary_shards}), - min => 0, - ); - $self->{output}->perfdata_add(label => 'shard', - value => sprintf("%d", $webcontent->{active_shards}), - min => 0, - ); - $self->{output}->perfdata_add(label => 'unassigned_shard', - value => sprintf("%d", $webcontent->{unassigned_shards}), - min => 0, - ); - - $self->{output}->display(); - $self->{output}->exit(); - -} - -1; - -__END__ - -=head1 MODE - -Check Elasticsearch cluster health - -=over 8 - -=item B<--hostname> - -IP Addr/FQDN of the Elasticsearch host - -=item B<--port> - -Port used by Elasticsearch API (Default: '9200') - -=item B<--proto> - -Specify https if needed (Default: 'http') - -=item B<--urlpath> - -Set path to get Elasticsearch information (Default: '/_cluster/health') - -=item B<--credentials> - -Specify this option if you access webpage over basic authentification - -=item B<--username> - -Specify username for API authentification - -=item B<--password> - -Specify password for API authentification - -=item B<--timeout> - -Threshold for HTTP timeout (Default: 5) - -=item B<--threshold-overload> - -Set to overload default threshold values (syntax: section,status,regexp) -It used before default thresholds (order stays). -Example: --threshold-overload='cluster,CRITICAL,^(?!(on)$)' - -=back - -=cut diff --git a/centreon-plugins/apps/elasticsearch/mode/indices.pm b/centreon-plugins/apps/elasticsearch/mode/indices.pm deleted file mode 100644 index cd05970f1..000000000 --- a/centreon-plugins/apps/elasticsearch/mode/indices.pm +++ /dev/null @@ -1,200 +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::elasticsearch::mode::indices; - -use base qw(centreon::plugins::mode); - -use strict; -use warnings; -use centreon::plugins::http; -use JSON; -use Data::Dumper; - -my $thresholds = { - indices => [ - ['green', 'OK'], - ['yellow', 'WARNING'], - ['red', 'CRITICAL'], - ], -}; - -my %map_states_indices = ( - OK => 'green', - WARNING => 'yellow', - CRITICAL => 'red', -); - -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' }, - "port:s" => { name => 'port', default => 9200 }, - "proto:s" => { name => 'proto' }, - "urlpath:s" => { name => 'url_path', default => '/_cluster/health' }, - "credentials" => { name => 'credentials' }, - "username:s" => { name => 'username' }, - "password:s" => { name => 'password' }, - "timeout:s" => { name => 'timeout' }, - "threshold-overload:s@" => { name => 'threshold_overload' }, - }); - - $self->{http} = centreon::plugins::http->new(output => $self->{output}); - return $self; -} - -sub check_options { - my ($self, %options) = @_; - $self->SUPER::init(%options); - - $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}; - } - - $self->{option_results}->{get_param} = [ 'level=indices' ]; - $self->{http}->set_options(%{$self->{option_results}}); -} - -sub get_severity { - my ($self, %options) = @_; - my $status = 'UNKNOWN'; # default - - if (defined($self->{overload_th}->{$options{section}})) { - foreach (@{$self->{overload_th}->{$options{section}}}) { - if ($options{value} =~ /$_->{filter}/i) { - $status = $_->{status}; - return $status; - } - } - } - foreach (@{$thresholds->{$options{section}}}) { - if ($options{value} =~ /$$_[0]/i) { - $status = $$_[1]; - return $status; - } - } - - return $status; -} - -sub run { - my ($self, %options) = @_; - - my $jsoncontent = $self->{http}->request(); - - my $json = JSON->new; - my $webcontent; - - eval { - $webcontent = $json->decode($jsoncontent); - }; - if ($@) { - $self->{output}->add_option_msg(short_msg => "Cannot decode json response"); - $self->{output}->option_exit(); - } - - $self->{output}->output_add(severity => 'OK', - short_msg => sprintf("All indices are in green state.")); - my $exit = 'OK'; - foreach my $indicename (sort (keys %{$webcontent->{indices}})) { - my $tmp_exit = $self->get_severity(section => 'indices', value => $webcontent->{indices}->{$indicename}->{status}); - $exit = $self->{output}->get_most_critical(status => [ $tmp_exit, $exit ]); - if (!$self->{output}->is_status(value => $tmp_exit, compare => 'OK', litteral => 1)) { - $self->{output}->output_add(long_msg => sprintf("Indice %s status is in %s state", - $indicename, $webcontent->{indices}->{$indicename}->{status})); - } - } - - if (!$self->{output}->is_status(value => $exit, compare => 'OK', litteral => 1)) { - $self->{output}->output_add(severity => $exit, - short_msg => sprintf("Some indices are in wrong state")); - } - - $self->{output}->display(); - $self->{output}->exit(); -} - -1; - -__END__ - -=head1 MODE - -Check Elasticsearch indices health - -=over 8 - -=item B<--hostname> - -IP Addr/FQDN of the Elasticsearch host - -=item B<--port> - -Port used by Elasticsearch API (Default: '9200') - -=item B<--proto> - -Specify https if needed (Default: 'http') - -=item B<--urlpath> - -Set path to get Elasticsearch information (Default: '/_cluster/health') - -=item B<--credentials> - -Specify this option if you access webpage over basic authentification - -=item B<--username> - -Specify username for API authentification - -=item B<--password> - -Specify password for API authentification - -=item B<--threshold-overload> - -Set to overload default threshold values (syntax: section,status,regexp) -It used before default thresholds (order stays). -Example: --threshold-overload='indices,CRITICAL,^(?!(on)$)' - -=item B<--timeout> - -Threshold for HTTP timeout (Default: 3) - -=back - -=cut diff --git a/centreon-plugins/apps/elasticsearch/mode/nodescount.pm b/centreon-plugins/apps/elasticsearch/mode/nodescount.pm deleted file mode 100644 index cab50ebc7..000000000 --- a/centreon-plugins/apps/elasticsearch/mode/nodescount.pm +++ /dev/null @@ -1,171 +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::elasticsearch::mode::nodescount; - -use base qw(centreon::plugins::mode); - -use strict; -use warnings; -use centreon::plugins::http; -use JSON; - -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 => 9200 }, - "proto:s" => { name => 'proto' }, - "urlpath:s" => { name => 'url_path', default => '/_cluster/stats' }, - "credentials" => { name => 'credentials' }, - "username:s" => { name => 'username' }, - "password:s" => { name => 'password' }, - "warning:s" => { name => 'warning' }, - "critical:s" => { name => 'critical' }, - "timeout:s" => { name => 'timeout' }, - }); - - $self->{http} = centreon::plugins::http->new(output => $self->{output}); - 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->{http}->set_options(%{$self->{option_results}}); -} - -sub run { - my ($self, %options) = @_; - - my $jsoncontent = $self->{http}->request(); - - my $json = JSON->new; - my $webcontent; - - eval { - $webcontent = $json->decode($jsoncontent); - }; - - if ($@) { - $self->{output}->add_option_msg(short_msg => "Cannot decode json response"); - $self->{output}->option_exit(); - } - - my $exit = $self->{perfdata}->threshold_check(value => $webcontent->{nodes}->{count}->{total}, threshold => [ { label => 'critical', 'exit_litteral' => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]); - - $self->{output}->output_add(severity => $exit, - short_msg => sprintf("Number of nodes for cluster %s : %d", - $webcontent->{cluster_name}, $webcontent->{nodes}->{count}->{total})); - $self->{output}->perfdata_add(label => "node", - value => $webcontent->{nodes}->{count}->{total}, - warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning'), - critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical'), - min => 0, - ); - $self->{output}->perfdata_add(label => "nodemasteronly", - value => $webcontent->{nodes}->{count}->{master_only}, - min => 0, - ); - $self->{output}->perfdata_add(label => "nodedataonly", - value => $webcontent->{nodes}->{count}->{data_only}, - min => 0, - ); - $self->{output}->perfdata_add(label => "nodemasterdata", - value => $webcontent->{nodes}->{count}->{master_data}, - min => 0, - ); - $self->{output}->perfdata_add(label => "nodeclient", - value => $webcontent->{nodes}->{count}->{client}, - min => 0, - ); - $self->{output}->display(); - $self->{output}->exit(); - -} - -1; - -__END__ - -=head1 MODE - -Check Elasticsearch number of nodes - -=over 8 - -=item B<--hostname> - -IP Addr/FQDN of the Elasticsearch host - -=item B<--port> - -Port used by Elasticsearch API (Default: '9200') - -=item B<--proto> - -Specify https if needed (Default: 'http') - -=item B<--urlpath> - -Set path to get Elasticsearch information (Default: '_cluster/stats') - -=item B<--credentials> - -Specify this option if you access webpage over basic authentification - -=item B<--username> - -Specify username for API authentification - -=item B<--password> - -Specify password for API authentification - -=item B<--warning> - -Threshold warning. - -=item B<--critical> - -Threshold critical. - -=item B<--timeout> - -Threshold for HTTP timeout (Default: 5) - -=back - -=cut diff --git a/centreon-plugins/apps/elasticsearch/restapi/custom/api.pm b/centreon-plugins/apps/elasticsearch/restapi/custom/api.pm new file mode 100644 index 000000000..d5d130d9b --- /dev/null +++ b/centreon-plugins/apps/elasticsearch/restapi/custom/api.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 apps::elasticsearch::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 => + { + "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' }, + }); + } + $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}}) : 9200; + $self->{proto} = (defined($self->{option_results}->{proto})) ? shift(@{$self->{option_results}->{proto}}) : 'http'; + $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; + + 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 get { + my ($self, %options) = @_; + + $self->settings(); + + my $response = $self->{http}->request(url_path => $options{path}, + critical_status => '', warning_status => ''); + 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(); + } + if (defined($content->{errmsg})) { + $self->{output}->add_option_msg(short_msg => "Cannot get data: " . $content->{errmsg}); + $self->{output}->option_exit(); + } + + return $content; +} + +1; + +__END__ + +=head1 NAME + +Elasticsearch REST API + +=head1 SYNOPSIS + +Elasticsearch Rest API custom mode + +=head1 REST API OPTIONS + +=over 8 + +=item B<--hostname> + +Elasticsearch hostname. + +=item B<--port> + +Port used (Default: 9200) + +=item B<--proto> + +Specify https if needed (Default: 'http') + +=item B<--username> + +Elasticsearch username. + +=item B<--password> + +Elasticsearch password. + +=item B<--proxyurl> + +Proxy URL if any + +=item B<--timeout> + +Set HTTP timeout + +=back + +=head1 DESCRIPTION + +B. + +=cut diff --git a/centreon-plugins/apps/elasticsearch/restapi/mode/cluster.pm b/centreon-plugins/apps/elasticsearch/restapi/mode/cluster.pm new file mode 100644 index 000000000..541cd924e --- /dev/null +++ b/centreon-plugins/apps/elasticsearch/restapi/mode/cluster.pm @@ -0,0 +1,203 @@ +# +# 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::elasticsearch::restapi::mode::cluster; + +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 = "Cluster '" . $self->{result_values}->{display} . "' Status : " . $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}->{display} = $options{new_datas}->{$self->{instance} . '_display'}; + 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 => 'status' }, { 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 => 'active-primary-shards', set => { + key_values => [ { name => 'active_primary_shards' } ], + output_template => 'Active Primary Shards : %s', + perfdatas => [ + { label => 'active_primary_shards', value => 'active_primary_shards_absolute', template => '%s', + min => 0 }, + ], + } + }, + { label => 'active-shards', set => { + key_values => [ { name => 'active_shards' } ], + output_template => 'Active Shards : %s', + perfdatas => [ + { label => 'active_shards', value => 'active_shards_absolute', template => '%s', + min => 0 }, + ], + } + }, + { label => 'unassigned-shards', set => { + key_values => [ { name => 'unassigned_shards' } ], + output_template => 'Unassigned Shards : %s', + perfdatas => [ + { label => 'unassigned_shards', value => 'unassigned_shards_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 => + { + "elastic-path:s" => { name => 'elastic_path', default => '/_cluster/health' }, + "warning-status:s" => { name => 'warning_status', default => '%{status} =~ /yellow/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 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 => $self->{option_results}->{elastic_path}); + $self->{global} = { + display => $result->{cluster_name}, + status => $result->{status}, + active_primary_shards => $result->{active_primary_shards}, + active_shards => $result->{active_shards}, + unassigned_shards => $result->{unassigned_shards}, + }; +} + +1; + +__END__ + +=head1 MODE + +Check Elasticsearch cluster. + +=over 8 + +=item B<--elastic-path> + +Set path to get Elasticsearch information (Default: '/_cluster/health') + +=item B<--filter-counters> + +Only display some counters (regexp can be used). +Example: --filter-counters='^status$' + +=item B<--warning-*> + +Threshold warning. +Can be: 'active-primary-shards', 'active-shards', 'unassigned-shards'. + +=item B<--critical-*> + +Threshold critical. +Can be: 'active-primary-shards', 'active-shards', 'unassigned-shards'. + +=item B<--warning-status> + +Set warning threshold for status (Default: '%{status} =~ /yellow/i') +Can used special variables like: %{status}. + +=item B<--critical-status> + +Set critical threshold for status (Default: '%{status} =~ /red/i'). +Can used special variables like: %{status}. + +=back + +=cut diff --git a/centreon-plugins/apps/elasticsearch/restapi/mode/indices.pm b/centreon-plugins/apps/elasticsearch/restapi/mode/indices.pm new file mode 100644 index 000000000..cdc6be4f6 --- /dev/null +++ b/centreon-plugins/apps/elasticsearch/restapi/mode/indices.pm @@ -0,0 +1,219 @@ +# +# 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::elasticsearch::restapi::mode::indices; + +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} . '_status'}; + $self->{result_values}->{display} = $options{new_datas}->{$self->{instance} . '_display'}; + return 0; +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'indices', type => 1, cb_prefix_output => 'prefix_indices_output', message_multiple => 'All indices are ok' }, + ]; + + $self->{maps_counters}->{indices} = [ + { label => 'status', threshold => 0, set => { + key_values => [ { name => 'status' }, { 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 => 'active-primary-shards', set => { + key_values => [ { name => 'active_primary_shards' }, { name => 'display' } ], + output_template => 'Active Primary Shards : %s', + perfdatas => [ + { label => 'active_primary_shards', value => 'active_primary_shards_absolute', template => '%s', + min => 0, label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + { label => 'active-shards', set => { + key_values => [ { name => 'active_shards' }, { name => 'display' } ], + output_template => 'Active Shards : %s', + perfdatas => [ + { label => 'active_shards', value => 'active_shards_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); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => + { + "elastic-path:s" => { name => 'elastic_path', default => '/_cluster/health?level=indices' }, + "filter-name:s" => { name => 'filter_name' }, + "warning-status:s" => { name => 'warning_status', default => '%{status} =~ /yellow/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_indices_output { + my ($self, %options) = @_; + + return "Indices '" . $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->{indices} = {}; + my $result = $options{custom}->get(path => $self->{option_results}->{elastic_path}); + + foreach my $indice (keys %{$result->{indices}}) { + if (defined($self->{option_results}->{filter_name}) && $self->{option_results}->{filter_name} ne '' && + $indice !~ /$self->{option_results}->{filter_name}/) { + $self->{output}->output_add(long_msg => "skipping '" . $indice . "': no matching filter.", debug => 1); + next; + } + + $self->{indices}->{$indice} = { + display => $indice, + status => $result->{indices}->{$indice}->{status}, + active_primary_shards => $result->{indices}->{$indice}->{active_primary_shards}, + active_shards => $result->{indices}->{$indice}->{active_shards}, + }; + } + + if (scalar(keys %{$self->{indices}}) <= 0) { + $self->{output}->add_option_msg(short_msg => "No indices found."); + $self->{output}->option_exit(); + } +} + +1; + +__END__ + +=head1 MODE + +Check Elasticsearch indices. + +=over 8 + +=item B<--elastic-path> + +Set path to get Elasticsearch information (Default: '/_cluster/health?level=indices') + +=item B<--filter-name> + +Filter name (can be a regexp). + +=item B<--filter-counters> + +Only display some counters (regexp can be used). +Example: --filter-counters='^status$' + +=item B<--warning-*> + +Threshold warning. +Can be: 'active-primary-shards', 'active-shards'. + +=item B<--critical-*> + +Threshold critical. +Can be: 'active-primary-shards', 'active-shards'. + +=item B<--warning-status> + +Set warning threshold for status (Default: '%{status} =~ /yellow/i') +Can used special variables like: %{display}, %{status}. + +=item B<--critical-status> + +Set critical threshold for status (Default: '%{status} =~ /red/i'). +Can used special variables like: %{display}, %{status}. + +=back + +=cut diff --git a/centreon-plugins/apps/elasticsearch/restapi/mode/nodes.pm b/centreon-plugins/apps/elasticsearch/restapi/mode/nodes.pm new file mode 100644 index 000000000..bc71a28c1 --- /dev/null +++ b/centreon-plugins/apps/elasticsearch/restapi/mode/nodes.pm @@ -0,0 +1,144 @@ +# +# 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::elasticsearch::restapi::mode::nodes; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'nodes', type => 0, cb_prefix_output => 'prefix_output' }, + ]; + + $self->{maps_counters}->{nodes} = [ + { label => 'total', set => { + key_values => [ { name => 'total' } ], + output_template => 'Total : %s', + perfdatas => [ + { label => 'total', value => 'total_absolute', template => '%s', + min => 0 }, + ], + } + }, + { label => 'masteronly', set => { + key_values => [ { name => 'master_only' } ], + output_template => 'Master Only : %s', + perfdatas => [ + { label => 'master_only', value => 'master_only_absolute', template => '%s', + min => 0 }, + ], + } + }, + { label => 'dataonly', set => { + key_values => [ { name => 'data_only' } ], + output_template => 'Data Only : %s', + perfdatas => [ + { label => 'data_only', value => 'data_only_absolute', template => '%s', + min => 0 }, + ], + } + }, + { label => 'masterdata', set => { + key_values => [ { name => 'master_data' } ], + output_template => 'Master Data : %s', + perfdatas => [ + { label => 'master_data', value => 'master_data_absolute', template => '%s', + min => 0 }, + ], + } + }, + { label => 'client', set => { + key_values => [ { name => 'client' } ], + output_template => 'Client : %s', + perfdatas => [ + { label => 'client', value => 'client_absolute', template => '%s', + min => 0 }, + ], + } + }, + ]; +} + +sub prefix_output { + my ($self, %options) = @_; + + return "Nodes "; +} + +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 => + { + "elastic-path:s" => { name => 'elastic_path', default => '/_cluster/stats' }, + }); + + return $self; +} + +sub manage_selection { + my ($self, %options) = @_; + + my $result = $options{custom}->get(path => $self->{option_results}->{elastic_path}); + $self->{nodes} = { + %{$result->{nodes}->{count}} + }; +} + +1; + +__END__ + +=head1 MODE + +Check Elasticsearch nodes. + +=over 8 + +=item B<--elastic-path> + +Set path to get Elasticsearch information (Default: '/_cluster/stats') + +=item B<--filter-counters> + +Only display some counters (regexp can be used). +Example: --filter-counters='^total$' + +=item B<--warning-*> + +Threshold warning. +Can be: 'total', 'masteronly', 'dataonly', 'masterdata', 'client'. + +=item B<--critical-*> + +Threshold critical. +Can be: 'total', 'masteronly', 'dataonly', 'masterdata', 'client'. + +=back + +=cut diff --git a/centreon-plugins/apps/elasticsearch/restapi/plugin.pm b/centreon-plugins/apps/elasticsearch/restapi/plugin.pm new file mode 100644 index 000000000..24598f393 --- /dev/null +++ b/centreon-plugins/apps/elasticsearch/restapi/plugin.pm @@ -0,0 +1,50 @@ +# +# 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::elasticsearch::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}} = ( + 'cluster' => 'apps::elasticsearch::restapi::mode::cluster', + 'indices' => 'apps::elasticsearch::restapi::mode::indices', + 'nodes' => 'apps::elasticsearch::restapi::mode::nodes', + ); + $self->{custom_modes}{api} = 'apps::elasticsearch::restapi::custom::api'; + return $self; +} + +1; + +__END__ + +=head1 PLUGIN DESCRIPTION + +Check elasticsearch through HTTP/REST API. + +=cut diff --git a/centreon-plugins/apps/hyperv/2012/local/mode/scvmmintegrationservice.pm b/centreon-plugins/apps/hyperv/2012/local/mode/scvmmintegrationservice.pm index 0dcb5342f..3c5267d4f 100644 --- a/centreon-plugins/apps/hyperv/2012/local/mode/scvmmintegrationservice.pm +++ b/centreon-plugins/apps/hyperv/2012/local/mode/scvmmintegrationservice.pm @@ -81,7 +81,7 @@ sub set_counters { { name => 'vm', type => 1, cb_prefix_output => 'prefix_vm_output', message_multiple => 'All integration services are ok' }, ]; $self->{maps_counters}->{vm} = [ - { label => 'snapshot', set => { + { label => 'status', , threshold => 0, set => { key_values => [ { name => 'vm' }, { name => 'status' }, { name => 'vmaddition' }, { name => 'operatingsystemshutdownenabled' }, { name => 'timesynchronizationenabled' }, { name => 'dataexchangeenabled' }, { name => 'heartbeatenabled' }, { name => 'backupenabled' } ], @@ -287,4 +287,4 @@ Can used special variables like: %{vm}, %{vmaddition}, %{status} =back -=cut \ No newline at end of file +=cut diff --git a/centreon-plugins/apps/inin/ig/snmp/mode/spanusage.pm b/centreon-plugins/apps/inin/ig/snmp/mode/spanusage.pm new file mode 100644 index 000000000..ede862960 --- /dev/null +++ b/centreon-plugins/apps/inin/ig/snmp/mode/spanusage.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 apps::inin::ig::snmp::mode::spanusage; + +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} . '_i3IgSpanInfoSpanState'}; + $self->{result_values}->{display} = $options{new_datas}->{$self->{instance} . '_display'}; + return 0; +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'span', type => 1, cb_prefix_output => 'prefix_span_output', message_multiple => 'All spans are ok' } + ]; + + $self->{maps_counters}->{span} = [ + { label => 'status', threshold => 0, set => { + key_values => [ { name => 'i3IgSpanInfoSpanState' }, { 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 => 'active-channels', set => { + key_values => [ { name => 'i3IgSpanInfoActiveChannels' }, { name => 'display' } ], + output_template => 'Current Active Channels : %s', + perfdatas => [ + { label => 'active_channels', value => 'i3IgSpanInfoActiveChannels_absolute', template => '%d', + 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' }, + "warning-status:s" => { name => 'warning_status', default => '' }, + "critical-status:s" => { name => 'critical_status', default => '%{status} !~ /closed|ready/i' }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::check_options(%options); + + $instance_mode = $self; + $self->change_macros(); +} + +sub prefix_span_output { + my ($self, %options) = @_; + + return "Span '" . $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 %map_state = (0 => 'closed', 1 => 'ready', 2 => 'alarm', 3 => 'error'); +my $mapping = { + i3IgSpanInfoSpanId => { oid => '.1.3.6.1.4.1.2793.4.2.3.1.3' }, + i3IgSpanInfoActiveChannels => { oid => '.1.3.6.1.4.1.2793.4.2.3.1.5' }, + i3IgSpanInfoSpanState => { oid => '.1.3.6.1.4.1.2793.4.2.3.1.6', map => \%map_state }, +}; + +my $oid_i3IgSpanInfoTableEntry = '.1.3.6.1.4.1.2793.4.2.3.1'; + +sub manage_selection { + my ($self, %options) = @_; + + $self->{span} = {}; + my $snmp_result = $options{snmp}->get_table(oid => $oid_i3IgSpanInfoTableEntry, + nothing_quit => 1); + + foreach my $oid (keys %{$snmp_result}) { + next if ($oid !~ /^$mapping->{i3IgSpanInfoSpanState}->{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->{i3IgSpanInfoSpanId} !~ /$self->{option_results}->{filter_name}/) { + $self->{output}->output_add(long_msg => "skipping '" . $result->{i3IgSpanInfoSpanId} . "': no matching filter.", debug => 1); + next; + } + + $self->{span}->{$instance} = { + display => $result->{i3IgSpanInfoSpanId}, + %$result + }; + } + + if (scalar(keys %{$self->{span}}) <= 0) { + $self->{output}->add_option_msg(short_msg => "No span found."); + $self->{output}->option_exit(); + } +} + +1; + +__END__ + +=head1 MODE + +Check span usage. + +=over 8 + +=item B<--filter-counters> + +Only display some counters (regexp can be used). +Example: --filter-counters='^status$' + +=item B<--filter-name> + +Filter span 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} !~ /closed|ready/i'). +Can used special variables like: %{status}, %{display} + +=item B<--warning-*> + +Threshold warning. +Can be: 'active-channels'. + +=item B<--critical-*> + +Threshold critical. +Can be: 'active-channels'. + +=back + +=cut diff --git a/centreon-plugins/apps/inin/ig/snmp/mode/stats.pm b/centreon-plugins/apps/inin/ig/snmp/mode/stats.pm new file mode 100644 index 000000000..5ef9add9f --- /dev/null +++ b/centreon-plugins/apps/inin/ig/snmp/mode/stats.pm @@ -0,0 +1,157 @@ +# +# 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::inin::ig::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 => ' - ' }, + { name => 'cg', type => 1, cb_prefix_output => 'prefix_cg_output', message_multiple => 'All channel groups are ok' } + ]; + + $self->{maps_counters}->{global} = [ + { label => 'sip-active-calls', set => { + key_values => [ { name => 'SipActiveCallsCount' } ], + output_template => 'SIP Current Active Calls : %s', + perfdatas => [ + { label => 'sip_active_calls', value => 'SipActiveCallsCount_absolute', template => '%d', + min => 0 }, + ], + } + }, + { label => 'tdm-active-calls', set => { + key_values => [ { name => 'TdmActiveCallsCount' } ], + output_template => 'TDM Current Active Calls : %s', + perfdatas => [ + { label => 'tdm_active_calls', value => 'TdmActiveCallsCount_absolute', template => '%d', + min => 0 }, + ], + } + }, + ]; + $self->{maps_counters}->{cg} = [ + { label => 'channel-group-active-calls', set => { + key_values => [ { name => 'i3IgChannelGroupActiveCallsCount' }, { name => 'display' } ], + output_template => 'Current Active Calls : %s', + perfdatas => [ + { label => 'channel_group_active_calls', value => 'i3IgChannelGroupActiveCallsCount_absolute', template => '%d', + 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' }, + }); + + return $self; +} + +sub prefix_cg_output { + my ($self, %options) = @_; + + return "Channel group '" . $options{instance_value}->{display} . "' "; +} + +my $mapping = { + i3IgChannelGroupName => { oid => '.1.3.6.1.4.1.2793.4.2.13.1.2' }, + i3IgChannelGroupActiveCallsCount => { oid => '.1.3.6.1.4.1.2793.4.2.13.1.3' }, +}; +my $oid_i3IgInfo = '.1.3.6.1.4.1.2793.4.2'; +my $oid_i3IgSipActiveCallsCount = '.1.3.6.1.4.1.2793.4.2.4'; +my $oid_i3IgTdmActiveCallsCount = '.1.3.6.1.4.1.2793.4.2.7'; + +sub manage_selection { + my ($self, %options) = @_; + + $self->{cg} = {}; + my $snmp_result = $options{snmp}->get_table(oid => $oid_i3IgInfo, start => $oid_i3IgSipActiveCallsCount, end => , + nothing_quit => 1); + + foreach my $oid (keys %{$snmp_result}) { + next if ($oid !~ /^$mapping->{i3IgChannelGroupActiveCallsCount}->{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->{i3IgChannelGroupName} !~ /$self->{option_results}->{filter_name}/) { + $self->{output}->output_add(long_msg => "skipping '" . $result->{i3IgSpanInfoSpanId} . "': no matching filter.", debug => 1); + next; + } + + $self->{cg}->{$instance} = { display => $result->{i3IgChannelGroupName}, %$result }; + } + + $self->{global} = { + SipActiveCallsCount => $snmp_result->{$oid_i3IgSipActiveCallsCount . '.0'}, + TdmActiveCallsCount => $snmp_result->{$oid_i3IgTdmActiveCallsCount . '.0'}, + }; +} + +1; + +__END__ + +=head1 MODE + +Check statistics. + +=over 8 + +=item B<--filter-counters> + +Only display some counters (regexp can be used). +Example: --filter-counters='^sip-active-calls$' + +=item B<--filter-name> + +Filter channel group name (can be a regexp). + +=item B<--warning-*> + +Threshold warning. +Can be: 'sip-active-calls', 'tdm-active-calls', +'channel-group-active-calls'. + +=item B<--critical-*> + +Threshold critical. +Can be: 'sip-active-calls', 'tdm-active-calls', +'channel-group-active-calls'. + +=back + +=cut diff --git a/centreon-plugins/apps/inin/ig/snmp/plugin.pm b/centreon-plugins/apps/inin/ig/snmp/plugin.pm new file mode 100644 index 000000000..6574486e3 --- /dev/null +++ b/centreon-plugins/apps/inin/ig/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::inin::ig::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}} = ( + 'span-usage' => 'apps::inin::ig::snmp::mode::spanusage', + 'stats' => 'apps::inin::ig::snmp::mode::stats', + ); + + return $self; +} + +1; + +__END__ + +=head1 PLUGIN DESCRIPTION + +Check Interactive Intelligence Interaction Gateway in SNMP. + +=cut diff --git a/centreon-plugins/apps/java/awa/jmx/mode/agent.pm b/centreon-plugins/apps/java/awa/jmx/mode/agent.pm new file mode 100644 index 000000000..0c83a08c4 --- /dev/null +++ b/centreon-plugins/apps/java/awa/jmx/mode/agent.pm @@ -0,0 +1,214 @@ +# +# 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::awa::jmx::mode::agent; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; +use centreon::plugins::misc; +use DateTime; + +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 = 'active : ' . $self->{result_values}->{active} . ' [IpAddress: ' . $self->{result_values}->{ipaddress} . ' ]' . + '[LastCheck: ' . centreon::plugins::misc::change_seconds(value => $self->{result_values}->{since}) . ']'; + return $msg; +} + +sub custom_status_calc { + my ($self, %options) = @_; + + $self->{result_values}->{since} = $options{new_datas}->{$self->{instance} . '_since'}; + $self->{result_values}->{ipaddress} = $options{new_datas}->{$self->{instance} . '_ipaddress'}; + $self->{result_values}->{active} = $options{new_datas}->{$self->{instance} . '_active'}; + $self->{result_values}->{display} = $options{new_datas}->{$self->{instance} . '_display'}; + return 0; +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'agent', type => 1, cb_prefix_output => 'prefix_agent_output', message_multiple => 'All agents are ok', skipped_code => { -10 => 1 } }, + ]; + + $self->{maps_counters}->{agent} = [ + { label => 'status', threshold => 0, set => { + key_values => [ { name => 'active' }, { name => 'ipaddress' }, { name => 'since' }, { 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'), + } + }, + ]; +} + +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 => '' }, + "critical-status:s" => { name => 'critical_status', default => '' }, + "timezone:s" => { name => 'timezone' }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::check_options(%options); + + $instance_mode = $self; + $self->change_macros(); + $self->{option_results}->{timezone} = 'GMT' if (!defined($self->{option_results}->{timezone}) || $self->{option_results}->{timezone} eq ''); +} + +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 prefix_agent_output { + my ($self, %options) = @_; + + return "Agent '" . $options{instance_value}->{display} . "' "; +} + +sub manage_selection { + my ($self, %options) = @_; + + $self->{app} = {}; + $self->{request} = [ + { mbean => 'Automic:name=*,side=Agents,type=*', + attributes => [ { name => 'LastCheck' }, { name => 'IpAddress' }, + { name => 'Active' }, { name => 'Name' } ] }, + ]; + my $result = $options{custom}->get_attributes(request => $self->{request}, nothing_quit => 1); + + foreach my $mbean (keys %{$result}) { + $mbean =~ /name=(.*?)(,|$)/i; + my $name = $1; + $mbean =~ /type=(.*?)(,|$)/i; + my $display = $1 . '.' . $name; + + if (defined($self->{option_results}->{filter_name}) && $self->{option_results}->{filter_name} ne '' && + $display !~ /$self->{option_results}->{filter_name}/) { + $self->{output}->output_add(long_msg => "skipping '" . $display . "': no matching filter.", debug => 1); + next; + } + + next if ($result->{$mbean}->{LastCheck} !~ /^\s*(\d+)-(\d+)-(\d+)\s+(\d+):(\d+):(\d+)/); + + my $dt = DateTime->new( + year => $1, + month => $2, + day => $3, + hour => $4, + minute => $5, + second => $6, + time_zone => $self->{option_results}->{timezone}, + ); + + $self->{agent}->{$display} = { + display => $display, + ipaddress => $result->{$mbean}->{IpAddress}, + active => $result->{$mbean}->{Active} ? 'yes' : 'no', + since => time() - $dt->epoch, + }; + } + + if (scalar(keys %{$self->{agent}}) <= 0) { + $self->{output}->add_option_msg(short_msg => "No agent found."); + $self->{output}->option_exit(); + } +} + +1; + +__END__ + +=head1 MODE + +Check agent status. + +=over 8 + +=item B<--filter-name> + +Filter agent name (can be a regexp). + +=item B<--warning-status> + +Set warning threshold for status (Default: ''). +Can used special variables like: %{since}, %{display}, %{ipaddress}, %{active} + +=item B<--critical-status> + +Set critical threshold for status (Default: ''). +Can used special variables like: %{since}, %{display}, %{ipaddress}, %{active} + +=item B<--timezone> + +Timezone options (the date from the equipment overload that option). Default is 'GMT'. + +=back + +=cut diff --git a/centreon-plugins/apps/java/awa/jmx/mode/listagents.pm b/centreon-plugins/apps/java/awa/jmx/mode/listagents.pm new file mode 100644 index 000000000..82447c84b --- /dev/null +++ b/centreon-plugins/apps/java/awa/jmx/mode/listagents.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::java::awa::jmx::mode::listagents; + +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' }, + "filter-type:s" => { name => 'filter_type' }, + }); + $self->{agents} = {}; + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::init(%options); +} + +sub manage_selection { + my ($self, %options) = @_; + + $self->{request} = [ + { mbean => 'Automic:name=*,side=Agents,type=*', + attributes => [ { name => 'IpAddress' }, { name => 'Active' }, { name => 'Name' } ] }, + ]; + my $result = $options{custom}->get_attributes(request => $self->{request}, nothing_quit => 1); + + foreach my $mbean (keys %{$result}) { + $mbean =~ /name=(.*?)(,|$)/i; + my $name = $1; + $mbean =~ /type=(.*?)(,|$)/i; + my $type = $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; + } + 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 '" . $name . "': no matching filter.", debug => 1); + next; + } + + $self->{agents}->{$name . '.' . $type} = { + name => $name, type => $type, + ipaddress => $result->{$mbean}->{IpAddress}, + active => $result->{$mbean}->{Active} ? 'yes' : 'no', + }; + } +} + +sub run { + my ($self, %options) = @_; + + $self->manage_selection(%options); + foreach my $instance (sort keys %{$self->{agents}}) { + $self->{output}->output_add(long_msg => '[name = ' . $self->{agents}->{$instance}->{name} . "]" . + " [type = '" . $self->{agents}->{$instance}->{type} . "']" . + " [ipaddress = '" . $self->{agents}->{$instance}->{ipaddress} . "']" . + " [active = '" . $self->{agents}->{$instance}->{active} . "']" + ); + } + + $self->{output}->output_add(severity => 'OK', + short_msg => 'List agents:'); + $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', 'ipaddress', 'active']); +} + +sub disco_show { + my ($self, %options) = @_; + + $self->manage_selection(%options); + foreach my $instance (sort keys %{$self->{agents}}) { + $self->{output}->add_disco_entry( + %{$self->{agents}->{$instance}} + ); + } +} + +1; + +__END__ + +=head1 MODE + +List agents. + +=over 8 + +=item B<--filter-name> + +Filter by agent name (can be a regexp). + +=item B<--filter-type> + +Filter by type (can be a regexp). + +=back + +=cut + diff --git a/centreon-plugins/apps/java/awa/jmx/mode/listqueues.pm b/centreon-plugins/apps/java/awa/jmx/mode/listqueues.pm new file mode 100644 index 000000000..efc9fd979 --- /dev/null +++ b/centreon-plugins/apps/java/awa/jmx/mode/listqueues.pm @@ -0,0 +1,136 @@ +# +# 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::awa::jmx::mode::listqueues; + +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' }, + "filter-type:s" => { name => 'filter_type' }, + }); + $self->{queues} = {}; + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::init(%options); +} + +sub manage_selection { + my ($self, %options) = @_; + + $self->{request} = [ + { mbean => 'Automic:name=*,side=Queues,type=*', + attributes => [ { name => 'Status' }, { name => 'Name' } ] }, + ]; + my $result = $options{custom}->get_attributes(request => $self->{request}, nothing_quit => 1); + + foreach my $mbean (keys %{$result}) { + $mbean =~ /name=(.*?)(,|$)/i; + my $name = $1; + $mbean =~ /type=(.*?)(,|$)/i; + my $type = $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; + } + 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 '" . $name . "': no matching filter.", debug => 1); + next; + } + + $self->{queues}->{$name . '.' . $type} = { + name => $name, type => $type, + status => $result->{$mbean}->{Status}, + }; + } +} + +sub run { + my ($self, %options) = @_; + + $self->manage_selection(%options); + foreach my $instance (sort keys %{$self->{queues}}) { + $self->{output}->output_add(long_msg => '[name = ' . $self->{queues}->{$instance}->{name} . "]" . + " [type = '" . $self->{queues}->{$instance}->{type} . "']" . + " [status = '" . $self->{queues}->{$instance}->{status} . "']" + ); + } + + $self->{output}->output_add(severity => 'OK', + short_msg => 'List queues:'); + $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', 'status']); +} + +sub disco_show { + my ($self, %options) = @_; + + $self->manage_selection(%options); + foreach my $instance (sort keys %{$self->{queues}}) { + $self->{output}->add_disco_entry( + %{$self->{queues}->{$instance}} + ); + } +} + +1; + +__END__ + +=head1 MODE + +List queues. + +=over 8 + +=item B<--filter-name> + +Filter by queue name (can be a regexp). + +=item B<--filter-type> + +Filter by type (can be a regexp). + +=back + +=cut + diff --git a/centreon-plugins/apps/java/awa/jmx/mode/listservers.pm b/centreon-plugins/apps/java/awa/jmx/mode/listservers.pm new file mode 100644 index 000000000..91bbecd59 --- /dev/null +++ b/centreon-plugins/apps/java/awa/jmx/mode/listservers.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::java::awa::jmx::mode::listservers; + +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' }, + "filter-type:s" => { name => 'filter_type' }, + }); + $self->{servers} = {}; + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::init(%options); +} + +sub manage_selection { + my ($self, %options) = @_; + + $self->{request} = [ + { mbean => 'Automic:name=*,side=Servers,type=*', + attributes => [ { name => 'NetArea' }, { name => 'IpAddress' }, + { name => 'Active' }, { name => 'Name' } ] }, + ]; + my $result = $options{custom}->get_attributes(request => $self->{request}, nothing_quit => 1); + + foreach my $mbean (keys %{$result}) { + $mbean =~ /name=(.*?)(,|$)/i; + my $name = $1; + $mbean =~ /type=(.*?)(,|$)/i; + my $type = $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; + } + 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 '" . $name . "': no matching filter.", debug => 1); + next; + } + + $self->{servers}->{$name . '.' . $type} = { + name => $name, type => $type, + ipaddress => $result->{$mbean}->{IpAddress}, + active => $result->{$mbean}->{Active} ? 'yes' : 'no', + netarea => $result->{$mbean}->{NetArea}, + }; + } +} + +sub run { + my ($self, %options) = @_; + + $self->manage_selection(%options); + foreach my $instance (sort keys %{$self->{servers}}) { + $self->{output}->output_add(long_msg => '[name = ' . $self->{servers}->{$instance}->{name} . "]" . + " [type = '" . $self->{servers}->{$instance}->{type} . "']" . + " [ipaddress = '" . $self->{servers}->{$instance}->{ipaddress} . "']" . + " [active = '" . $self->{servers}->{$instance}->{active} . "']" . + " [netarea = '" . $self->{servers}->{$instance}->{netarea} . "']" + ); + } + + $self->{output}->output_add(severity => 'OK', + short_msg => 'List servers:'); + $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', 'ipaddress', 'active', 'netarea']); +} + +sub disco_show { + my ($self, %options) = @_; + + $self->manage_selection(%options); + foreach my $instance (sort keys %{$self->{servers}}) { + $self->{output}->add_disco_entry( + %{$self->{servers}->{$instance}} + ); + } +} + +1; + +__END__ + +=head1 MODE + +List servers. + +=over 8 + +=item B<--filter-name> + +Filter by server name (can be a regexp). + +=item B<--filter-type> + +Filter by type (can be a regexp). + +=back + +=cut + diff --git a/centreon-plugins/apps/java/awa/jmx/mode/queue.pm b/centreon-plugins/apps/java/awa/jmx/mode/queue.pm new file mode 100644 index 000000000..ed2ea3b2c --- /dev/null +++ b/centreon-plugins/apps/java/awa/jmx/mode/queue.pm @@ -0,0 +1,188 @@ +# +# 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::awa::jmx::mode::queue; + +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} . '_status'}; + $self->{result_values}->{display} = $options{new_datas}->{$self->{instance} . '_display'}; + return 0; +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'queue', type => 1, cb_prefix_output => 'prefix_queue_output', message_multiple => 'All queues are ok', skipped_code => { -10 => 1 } }, + ]; + + $self->{maps_counters}->{queue} = [ + { label => 'status', threshold => 0, set => { + key_values => [ { name => 'status' }, { 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'), + } + }, + ]; +} + +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 => '' }, + "critical-status:s" => { name => 'critical_status', default => '%{status} !~ /GREEN/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 prefix_queue_output { + my ($self, %options) = @_; + + return "Queue '" . $options{instance_value}->{display} . "' "; +} + +sub manage_selection { + my ($self, %options) = @_; + + $self->{app} = {}; + $self->{request} = [ + { mbean => 'Automic:name=*,side=Queues,type=*', + attributes => [ { name => 'Status' }, { name => 'Name' } ] }, + ]; + my $result = $options{custom}->get_attributes(request => $self->{request}, nothing_quit => 1); + + foreach my $mbean (keys %{$result}) { + $mbean =~ /name=(.*?)(,|$)/i; + my $name = $1; + $mbean =~ /type=(.*?)(,|$)/i; + my $display = $1 . '.' . $name; + + if (defined($self->{option_results}->{filter_name}) && $self->{option_results}->{filter_name} ne '' && + $display !~ /$self->{option_results}->{filter_name}/) { + $self->{output}->output_add(long_msg => "skipping '" . $display . "': no matching filter.", debug => 1); + next; + } + + $self->{queue}->{$display} = { + display => $display, + status => $result->{$mbean}->{Status}, + }; + } + + if (scalar(keys %{$self->{queue}}) <= 0) { + $self->{output}->add_option_msg(short_msg => "No queue found."); + $self->{output}->option_exit(); + } +} + +1; + +__END__ + +=head1 MODE + +Check queue status. + +=over 8 + +=item B<--filter-name> + +Filter queue name (can be a regexp). + +=item B<--warning-status> + +Set warning threshold for status (Default: ''). +Can used special variables like: %{display}, %{status} + +=item B<--critical-status> + +Set critical threshold for status (Default: '%{status} !~ /GREEN/i'). +Can used special variables like: %{display}, %{status} + +=back + +=cut diff --git a/centreon-plugins/apps/java/awa/jmx/mode/server.pm b/centreon-plugins/apps/java/awa/jmx/mode/server.pm new file mode 100644 index 000000000..65f82c92d --- /dev/null +++ b/centreon-plugins/apps/java/awa/jmx/mode/server.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::java::awa::jmx::mode::server; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; +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]; }; + + 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 = 'active : ' . $self->{result_values}->{active} . ' [IpAddress: ' . $self->{result_values}->{ipaddress} . ' ]'; + return $msg; +} + +sub custom_status_calc { + my ($self, %options) = @_; + + $self->{result_values}->{ipaddress} = $options{new_datas}->{$self->{instance} . '_ipaddress'}; + $self->{result_values}->{active} = $options{new_datas}->{$self->{instance} . '_active'}; + $self->{result_values}->{display} = $options{new_datas}->{$self->{instance} . '_display'}; + return 0; +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'server', type => 1, cb_prefix_output => 'prefix_server_output', message_multiple => 'All servers are ok', skipped_code => { -10 => 1 } }, + ]; + + $self->{maps_counters}->{server} = [ + { label => 'status', threshold => 0, set => { + key_values => [ { name => 'active' }, { name => 'ipaddress' }, { 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'), + } + }, + ]; +} + +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 => '' }, + "critical-status:s" => { name => 'critical_status', default => '' }, + }); + + 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 prefix_server_output { + my ($self, %options) = @_; + + return "Server '" . $options{instance_value}->{display} . "' "; +} + +sub manage_selection { + my ($self, %options) = @_; + + $self->{app} = {}; + $self->{request} = [ + { mbean => 'Automic:name=*,side=Servers,type=*', + attributes => [ { name => 'NetArea' }, { name => 'IpAddress' }, + { name => 'Active' }, { name => 'Name' } ] }, + ]; + my $result = $options{custom}->get_attributes(request => $self->{request}, nothing_quit => 1); + + foreach my $mbean (keys %{$result}) { + $mbean =~ /name=(.*?)(,|$)/i; + my $name = $1; + $mbean =~ /type=(.*?)(,|$)/i; + my $display = $1 . '.' . $name; + + if (defined($self->{option_results}->{filter_name}) && $self->{option_results}->{filter_name} ne '' && + $display !~ /$self->{option_results}->{filter_name}/) { + $self->{output}->output_add(long_msg => "skipping '" . $display . "': no matching filter.", debug => 1); + next; + } + + $self->{server}->{$display} = { + display => $display, + ipaddress => $result->{$mbean}->{IpAddress}, + active => $result->{$mbean}->{Active} ? 'yes' : 'no', + }; + } + + if (scalar(keys %{$self->{server}}) <= 0) { + $self->{output}->add_option_msg(short_msg => "No server found."); + $self->{output}->option_exit(); + } +} + +1; + +__END__ + +=head1 MODE + +Check server status. + +=over 8 + +=item B<--filter-name> + +Filter server name (can be a regexp). + +=item B<--warning-status> + +Set warning threshold for status (Default: ''). +Can used special variables like: %{display}, %{ipaddress}, %{active} + +=item B<--critical-status> + +Set critical threshold for status (Default: ''). +Can used special variables like: %{display}, %{ipaddress}, %{active} + +=back + +=cut diff --git a/centreon-plugins/apps/java/awa/jmx/plugin.pm b/centreon-plugins/apps/java/awa/jmx/plugin.pm new file mode 100644 index 000000000..48e36c0a2 --- /dev/null +++ b/centreon-plugins/apps/java/awa/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::awa::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}} = ( + 'agent' => 'apps::java::awa::jmx::mode::agent', + 'list-agents' => 'apps::java::awa::jmx::mode::listagents', + 'list-queues' => 'apps::java::awa::jmx::mode::listqueues', + 'list-servers' => 'apps::java::awa::jmx::mode::listservers', + 'queue' => 'apps::java::awa::jmx::mode::queue', + 'server' => 'apps::java::awa::jmx::mode::server', + ); + + $self->{custom_modes}{jolokia} = 'centreon::common::protocols::jmx::custom::jolokia'; + return $self; +} + +1; + +__END__ + +=head1 PLUGIN DESCRIPTION + +Check Automic Workload Automation (Awa) in JMX. Need Jolokia agent. + +=cut diff --git a/centreon-plugins/apps/java/hibernate/jmx/mode/stats.pm b/centreon-plugins/apps/java/hibernate/jmx/mode/stats.pm new file mode 100644 index 000000000..fad0cd08f --- /dev/null +++ b/centreon-plugins/apps/java/hibernate/jmx/mode/stats.pm @@ -0,0 +1,189 @@ +# +# 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::hibernate::jmx::mode::stats; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; +use centreon::plugins::misc; +use Digest::MD5 qw(md5_hex); + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'app', type => 1, cb_prefix_output => 'prefix_app_output', message_multiple => 'All hibernate applications are ok', skipped_code => { -10 => 1 } }, + ]; + + $self->{maps_counters}->{app} = [ + { label => 'connect-count', set => { + key_values => [ { name => 'connect', diff => 1 }, { name => 'display' } ], + output_template => 'Connect Count : %s', + perfdatas => [ + { label => 'connect_count', value => 'connect_absolute', template => '%s', + min => 0, label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + { label => 'close-count', set => { + key_values => [ { name => 'close', diff => 1 }, { name => 'display' } ], + output_template => 'Close Count : %s', + perfdatas => [ + { label => 'close_count', value => 'close_absolute', template => '%s', + min => 0, label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + { label => 'query-count', set => { + key_values => [ { name => 'query', diff => 1 }, { name => 'display' } ], + output_template => 'Query Count : %s', + perfdatas => [ + { label => 'query_count', value => 'query_absolute', template => '%s', + min => 0, label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + { label => 'insert-count', set => { + key_values => [ { name => 'insert', diff => 1 }, { name => 'display' } ], + output_template => 'Insert Count : %s', + perfdatas => [ + { label => 'insert_count', value => 'insert_absolute', template => '%s', + min => 0, label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + { label => 'update-count', set => { + key_values => [ { name => 'update', diff => 1 }, { name => 'display' } ], + output_template => 'Update Count : %s', + perfdatas => [ + { label => 'update_count', value => 'update_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_app_output { + my ($self, %options) = @_; + + return "Application '" . $options{instance_value}->{display} . "' "; +} + +sub manage_selection { + my ($self, %options) = @_; + + $self->{app} = {}; + $self->{request} = [ + { mbean => 'Hibernate:Application=*,type=statistics', + attributes => [ { name => 'SessionCloseCount' }, { name => 'ConnectCount' }, + { name => 'EntityInsertCount' }, { name => 'CollectionUpdateCount' }, + { name => 'QueryExecutionCount' }, { name => 'StatisticsEnabled' } ] }, + { mbean => 'Hibernate:type=statistics', + attributes => [ { name => 'SessionCloseCount' }, { name => 'ConnectCount' }, + { name => 'EntityInsertCount' }, { name => 'CollectionUpdateCount' }, + { name => 'QueryExecutionCount' }, { name => 'StatisticsEnabled' } ] }, + ]; + my $result = $options{custom}->get_attributes(request => $self->{request}, nothing_quit => 1); + + foreach my $mbean (keys %{$result}) { + $mbean =~ /Application=(.*?),/; + my $app = defined($1) ? $1 : 'global'; + + if (defined($self->{option_results}->{filter_name}) && $self->{option_results}->{filter_name} ne '' && + $app !~ /$self->{option_results}->{filter_name}/) { + $self->{output}->output_add(long_msg => "skipping '" . $app . "': no matching filter.", debug => 1); + next; + } + if (!$result->{$mbean}->{StatisticsEnabled}) { + $self->{output}->output_add(long_msg => "skipping '" . $app . "': statistics is disabled.", debug => 1); + next; + } + + $self->{app}->{$app} = { + display => $app, + close => $result->{$mbean}->{SessionCloseCount}, + connect => $result->{$mbean}->{ConnectCount}, + insert => $result->{$mbean}->{EntityInsertCount}, + query => $result->{$mbean}->{QueryExecutionCount}, + update => $result->{$mbean}->{CollectionUpdateCount}, + }; + } + + if (scalar(keys %{$self->{app}}) <= 0) { + $self->{output}->add_option_msg(short_msg => "No application found (or staistics is disabled)."); + $self->{output}->option_exit(); + } + + $self->{cache_name} = "hibernate_" . $self->{mode} . '_' . md5_hex($options{custom}->{url}) . '_' . + (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 hibernate statistics. + +=over 8 + +=item B<--filter-counters> + +Only display some counters (regexp can be used). +Example: --filter-counters='^connect-count$' + +=item B<--filter-name> + +Filter application name (can be a regexp). + +=item B<--warning-*> + +Threshold warning. +Can be: 'connect-count', 'query-count', 'insert-count', +'update-count' 'close-count'. + +=item B<--critical-*> + +Threshold critical. +Can be: 'connect-count', 'query-count', 'insert-count', +'update-count' 'close-count'. + +=back + +=cut diff --git a/centreon-plugins/apps/java/hibernate/jmx/plugin.pm b/centreon-plugins/apps/java/hibernate/jmx/plugin.pm new file mode 100644 index 000000000..40b9d96b0 --- /dev/null +++ b/centreon-plugins/apps/java/hibernate/jmx/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::java::hibernate::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}} = ( + 'stats' => 'apps::java::hibernate::jmx::mode::stats', + ); + + $self->{custom_modes}{jolokia} = 'centreon::common::protocols::jmx::custom::jolokia'; + return $self; +} + +1; + +__END__ + +=head1 PLUGIN DESCRIPTION + +Check Hibernate 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 new file mode 100644 index 000000000..0f8a1fe05 --- /dev/null +++ b/centreon-plugins/apps/java/solr/jmx/mode/cacheusage.pm @@ -0,0 +1,172 @@ +# +# 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::solr::jmx::mode::cacheusage; + +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 => 'solrcache', type => 1, cb_prefix_output => 'prefix_cache_output', message_multiple => 'All caches are ok', skipped_code => { -10 => 1 } }, + ]; + + $self->{maps_counters}->{solrcache} = [ + { label => 'evictions-count', set => { + key_values => [ { name => 'cumulative_evictions', diff => 1 }, { name => 'display' } ], + output_template => 'Evictions Count : %s', + perfdatas => [ + { label => 'evictions_count', value => 'cumulative_evictions_absolute', template => '%s', + min => 0, label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + { label => 'lookups-count', set => { + key_values => [ { name => 'cumulative_lookups', diff => 1 }, { name => 'display' } ], + output_template => 'Lookups Count : %s', + perfdatas => [ + { label => 'lookups_count', value => 'cumulative_lookups_absolute', template => '%s', + min => 0, label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + { label => 'inserts-count', set => { + key_values => [ { name => 'cumulative_inserts', diff => 1 }, { name => 'display' } ], + output_template => 'Inserts Count : %s', + perfdatas => [ + { label => 'inserts_count', value => 'cumulative_inserts_absolute', template => '%s', + min => 0, label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + { label => 'hits-count', set => { + key_values => [ { name => 'cumulative_hits', diff => 1 }, { name => 'display' } ], + output_template => 'Hits Count : %s', + perfdatas => [ + { label => 'hits_count', value => 'cumulative_hits_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_cache_output { + my ($self, %options) = @_; + + return "Cache '" . $options{instance_value}->{display} . "' "; +} + +sub manage_selection { + my ($self, %options) = @_; + + $self->{solrcache} = {}; + $self->{request} = [ + { mbean => 'solr/*:id=*,type=documentCache', + attributes => [ { name => 'cumulative_evictions' }, { name => 'cumulative_lookups' }, + { name => 'cumulative_inserts' }, { name => 'cumulative_hits' } ] }, + { mbean => 'solr/*:id=*,type=filterCache', + attributes => [ { name => 'cumulative_evictions' }, { name => 'cumulative_lookups' }, + { name => 'cumulative_inserts' }, { name => 'cumulative_hits' } ] }, + { mbean => 'solr/*:id=*,type=queryResultCache', + attributes => [ { name => 'cumulative_evictions' }, { name => 'cumulative_lookups' }, + { name => 'cumulative_inserts' }, { name => 'cumulative_hits' } ] }, + ]; + my $result = $options{custom}->get_attributes(request => $self->{request}, nothing_quit => 1); + + foreach my $mbean (keys %{$result}) { + $mbean =~ /solr\/(.*?):.*?,type=(.*?)(?:,|$)/; + my $cache = $1 . '.' . $2; + + if (defined($self->{option_results}->{filter_name}) && $self->{option_results}->{filter_name} ne '' && + $cache !~ /$self->{option_results}->{filter_name}/) { + $self->{output}->output_add(long_msg => "skipping '" . $cache . "': no matching filter.", debug => 1); + next; + } + + $self->{solrcache}->{$cache} = { + display => $cache, + %{$result->{$mbean}}, + }; + } + + if (scalar(keys %{$self->{solrcache}}) <= 0) { + $self->{output}->add_option_msg(short_msg => "No cache found."); + $self->{output}->option_exit(); + } + + $self->{cache_name} = "solr_" . $self->{mode} . '_' . md5_hex($options{custom}->{url}) . '_' . + (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 cache usage. + +=over 8 + +=item B<--filter-counters> + +Only display some counters (regexp can be used). +Example: --filter-counters='^evictions-count$' + +=item B<--filter-name> + +Filter cache name (can be a regexp). + +=item B<--warning-*> + +Threshold warning. +Can be: 'evictions-count', 'lookups-count', 'inserts-count', +'hits-count'. + +=item B<--critical-*> + +Threshold critical. +Can be: 'evictions-count', 'lookups-count', 'inserts-count', +'hits-count'. + +=back + +=cut diff --git a/centreon-plugins/apps/java/solr/jmx/mode/requesthandlerusage.pm b/centreon-plugins/apps/java/solr/jmx/mode/requesthandlerusage.pm new file mode 100644 index 000000000..30f0cd6be --- /dev/null +++ b/centreon-plugins/apps/java/solr/jmx/mode/requesthandlerusage.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. +# + +package apps::java::solr::jmx::mode::requesthandlerusage; + +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 => 'rh', type => 1, cb_prefix_output => 'prefix_rh_output', message_multiple => 'All request handlers are ok', skipped_code => { -10 => 1 } }, + ]; + + $self->{maps_counters}->{rh} = [ + { label => '15min-rate-requests', set => { + key_values => [ { name => '15minRateRequestsPerSecond' }, { name => 'display' } ], + output_template => '15min Rate Requests : %.7f/s', + perfdatas => [ + { label => '15min_rate_requests', value => '15minRateRequestsPerSecond_absolute', template => '%.7f', + min => 0, unit => '/s', label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + { label => 'avg-requests', set => { + key_values => [ { name => 'avgRequestsPerSecond' }, { name => 'display' } ], + output_template => 'Average Requests : %.7f/s', + perfdatas => [ + { label => 'avg_requests', value => 'avgRequestsPerSecond_absolute', template => '%.7f', + min => 0, unit => '/s', label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + { label => 'avg-time', set => { + key_values => [ { name => 'avgTimePerRequest' }, { name => 'display' } ], + output_template => 'Average Time Per Request : %.3f ms', + perfdatas => [ + { label => 'avg_time', value => 'avgTimePerRequest_absolute', template => '%.3f', + min => 0, unit => 'ms', label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + { label => 'requests-count', set => { + key_values => [ { name => 'requests', diff => 1 }, { name => 'display' } ], + output_template => 'Requests Count : %s', + perfdatas => [ + { label => 'requests_count', value => 'requests_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', default => '(/select|/update)$' }, + }); + + return $self; +} + +sub prefix_rh_output { + my ($self, %options) = @_; + + return "Request Handler '" . $options{instance_value}->{display} . "' "; +} + +sub manage_selection { + my ($self, %options) = @_; + + $self->{rh} = {}; + $self->{request} = [ + { mbean => 'solr/*:id=org.apache.solr.handler.component.SearchHandler,type=*', + attributes => [ { name => '15minRateRequestsPerSecond' }, { name => 'avgTimePerRequest' }, + { name => 'avgRequestsPerSecond' }, { name => 'requests' } ] }, + { mbean => 'solr/*:id=org.apache.solr.handler.UpdateRequestHandler,type=*', + attributes => [ { name => '15minRateRequestsPerSecond' }, { name => 'avgTimePerRequest' }, + { name => 'avgRequestsPerSecond' }, { name => 'requests' } ] }, + ]; + my $result = $options{custom}->get_attributes(request => $self->{request}, nothing_quit => 1); + + foreach my $mbean (keys %{$result}) { + $mbean =~ /solr\/(.*?):id=.*?\.(.*?)Handler,type=(.*?)(?:,|$)/; + my $rhname = $1 . '.' . $2 . '.' . $3; + + if (defined($self->{option_results}->{filter_name}) && $self->{option_results}->{filter_name} ne '' && + $rhname !~ /$self->{option_results}->{filter_name}/) { + $self->{output}->output_add(long_msg => "skipping '" . $rhname . "': no matching filter.", debug => 1); + next; + } + + $self->{rh}->{$rhname} = { + display => $rhname, + %{$result->{$mbean}}, + }; + } + + if (scalar(keys %{$self->{rh}}) <= 0) { + $self->{output}->add_option_msg(short_msg => "No request handler found."); + $self->{output}->option_exit(); + } + + $self->{cache_name} = "solr_" . $self->{mode} . '_' . md5_hex($options{custom}->{url}) . '_' . + (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 request handler usage. + +=over 8 + +=item B<--filter-counters> + +Only display some counters (regexp can be used). +Example: --filter-counters='^requests-count$' + +=item B<--filter-name> + +Filter request handler name (can be a regexp). +Default: '(/select|/update)$'. + +=item B<--warning-*> + +Threshold warning. +Can be: 'requests-count', 'avg-requests', 'avg-time', +'15min-rate-requests'. + +=item B<--critical-*> + +Threshold critical. +Can be: 'requests-count', 'avg-requests', 'avg-time', +'15min-rate-requests'. + +=back + +=cut diff --git a/centreon-plugins/apps/java/solr/jmx/plugin.pm b/centreon-plugins/apps/java/solr/jmx/plugin.pm new file mode 100644 index 000000000..180a49960 --- /dev/null +++ b/centreon-plugins/apps/java/solr/jmx/plugin.pm @@ -0,0 +1,50 @@ +# +# 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::solr::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}} = ( + 'cache-usage' => 'apps::java::solr::jmx::mode::cacheusage', + 'request-handler-usage' => 'apps::java::solr::jmx::mode::requesthandlerusage', + ); + + $self->{custom_modes}{jolokia} = 'centreon::common::protocols::jmx::custom::jolokia'; + return $self; +} + +1; + +__END__ + +=head1 PLUGIN DESCRIPTION + +Check Solr in JMX. Need Jolokia agent. + +=cut diff --git a/centreon-plugins/apps/java/zookeeper/jmx/mode/stats.pm b/centreon-plugins/apps/java/zookeeper/jmx/mode/stats.pm new file mode 100644 index 000000000..812dd2ee2 --- /dev/null +++ b/centreon-plugins/apps/java/zookeeper/jmx/mode/stats.pm @@ -0,0 +1,177 @@ +# +# 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::zookeeper::jmx::mode::stats; + +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 => 'zk', type => 1, cb_prefix_output => 'prefix_zk_output', skipped_code => { -10 => 1 } }, + ]; + + $self->{maps_counters}->{zk} = [ + { label => 'avg-request-latency', set => { + key_values => [ { name => 'AvgRequestLatency' } ], + output_template => 'Avg Request Latency : %s ms', + perfdatas => [ + { label => 'avg_request_latency', value => 'AvgRequestLatency_absolute', template => '%s', + min => 0, unit => 'ms' }, + ], + } + }, + { label => 'max-request-latency', set => { + key_values => [ { name => 'MaxRequestLatency' } ], + output_template => 'Max Request Latency : %s ms', + perfdatas => [ + { label => 'max_request_latency', value => 'MaxRequestLatency_absolute', template => '%s', + min => 0, unit => 'ms' }, + ], + } + }, + { label => 'outstanding-requests', set => { + key_values => [ { name => 'OutstandingRequests' } ], + output_template => 'Outstanding Requests : %s', + perfdatas => [ + { label => 'outstanding_requests', value => 'OutstandingRequests_absolute', template => '%s', + min => 0 }, + ], + } + }, + { label => 'packets-received', set => { + key_values => [ { name => 'PacketsReceived', diff => 1 } ], + output_template => 'Packets Received : %s', + perfdatas => [ + { label => 'packets_received', value => 'PacketsReceived_absolute', template => '%s', + min => 0 }, + ], + } + }, + { label => 'packets-sent', set => { + key_values => [ { name => 'PacketsSent', diff => 1 } ], + output_template => 'Packets Sent : %s', + perfdatas => [ + { label => 'packets_sent', value => 'PacketsSent_absolute', template => '%s', + min => 0 }, + ], + } + }, + { label => 'num-connections', set => { + key_values => [ { name => 'NumAliveConnections' } ], + output_template => 'Num Alive Connections : %s', + perfdatas => [ + { label => 'num_connections', value => 'NumAliveConnections_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 prefix_zk_output { + my ($self, %options) = @_; + + return "Zookeeper '" . $options{instance_value}->{display} . "' "; +} + +sub manage_selection { + my ($self, %options) = @_; + + $self->{zk} = {}; + $self->{request} = [ + { mbean => 'org.apache.ZooKeeperService:name0=*,name1=*,name2=Leader', + attributes => [ { name => 'AvgRequestLatency' }, { name => 'MaxRequestLatency' }, + { name => 'OutstandingRequests' }, { name => 'PacketsReceived' }, + { name => 'PacketsSent' }, { name => 'NumAliveConnections' } ] }, + { mbean => 'org.apache.ZooKeeperService:name0=*,name1=*,name2=Follower', + attributes => [ { name => 'AvgRequestLatency' }, { name => 'MaxRequestLatency' }, + { name => 'OutstandingRequests' }, { name => 'PacketsReceived' }, + { name => 'PacketsSent' }, { name => 'NumAliveConnections' } ] }, + ]; + my $result = $options{custom}->get_attributes(request => $self->{request}, nothing_quit => 1); + + foreach my $mbean (keys %{$result}) { + next if ($mbean !~ /name2=(.*?)(?:,|$)/); + my $type = $1; + + $self->{zk}->{$type} = { + display => $type, + %{$result->{$mbean}}, + }; + } + + if (scalar(keys %{$self->{zk}}) <= 0) { + $self->{output}->add_option_msg(short_msg => "No zookeeper found."); + $self->{output}->option_exit(); + } + + $self->{cache_name} = "zookeeper_" . $self->{mode} . '_' . md5_hex($options{custom}->{url}) . '_' . + (defined($self->{option_results}->{filter_counters}) ? md5_hex($self->{option_results}->{filter_counters}) : md5_hex('all')); +} + +1; + +__END__ + +=head1 MODE + +Check hibernate statistics. + +=over 8 + +=item B<--filter-counters> + +Only display some counters (regexp can be used). +Example: --filter-counters='^avg-request-latency$' + +=item B<--warning-*> + +Threshold warning. +Can be: 'avg-request-latency', 'max-request-latency', 'outstanding-requests', +'packets-received' 'packets-sent', 'num-connections'. + +=item B<--critical-*> + +Threshold critical. +Can be: 'avg-request-latency', 'max-request-latency', 'outstanding-requests', +'packets-received' 'packets-sent', 'num-connections'. + +=back + +=cut diff --git a/centreon-plugins/apps/java/zookeeper/jmx/plugin.pm b/centreon-plugins/apps/java/zookeeper/jmx/plugin.pm new file mode 100644 index 000000000..e62cbd6a1 --- /dev/null +++ b/centreon-plugins/apps/java/zookeeper/jmx/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::java::zookeeper::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}} = ( + 'stats' => 'apps::java::zookeeper::jmx::mode::stats', + ); + + $self->{custom_modes}{jolokia} = 'centreon::common::protocols::jmx::custom::jolokia'; + return $self; +} + +1; + +__END__ + +=head1 PLUGIN DESCRIPTION + +Check Zookeeper in JMX. Need Jolokia agent. + +=cut diff --git a/centreon-plugins/apps/jmeter/mode/scenario.pm b/centreon-plugins/apps/jmeter/mode/scenario.pm index 9ead71843..43994eb8c 100644 --- a/centreon-plugins/apps/jmeter/mode/scenario.pm +++ b/centreon-plugins/apps/jmeter/mode/scenario.pm @@ -103,7 +103,7 @@ sub run { my $p = XML::Parser->new(NoLWP => 1); my $xp = XML::XPath->new(parser => $p, xml => $stdout); - my $listHttpSampleNode = $xp->findnodes('/testResults/httpSample'); + my $listHttpSampleNode = $xp->findnodes('/testResults/httpSample|/testResults/sample'); my $timing0 = 0; my $timing1 = 0; diff --git a/centreon-plugins/apps/pfsense/snmp/mode/blockedpackets.pm b/centreon-plugins/apps/pfsense/snmp/mode/blockedpackets.pm deleted file mode 100644 index 617452cd4..000000000 --- a/centreon-plugins/apps/pfsense/snmp/mode/blockedpackets.pm +++ /dev/null @@ -1,288 +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::pfsense::snmp::mode::blockedpackets; - -use base qw(centreon::plugins::mode); - -use strict; -use warnings; -use POSIX; -use centreon::plugins::statefile; -use Digest::MD5 qw(md5_hex); - -my $oid_pfsenseInterfaceName = '.1.3.6.1.4.1.12325.1.200.1.8.2.1.2'; - -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-in:s" => { name => 'warning_in', }, - "warning-out:s" => { name => 'warning_out', }, - "critical-in:s" => { name => 'critical_in', }, - "critical-out:s" => { name => 'critical_out', }, - "name" => { name => 'use_name' }, - "interface:s" => { name => 'interface' }, - "regexp" => { name => 'use_regexp' }, - "regexp-isensitive" => { name => 'use_regexpi' }, - }); - - $self->{interface_id_selected} = []; - $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-in', value => $self->{option_results}->{warning_in})) == 0) { - $self->{output}->add_option_msg(short_msg => "Wrong warning in threshold '" . $self->{option_results}->{warning_in} . "'."); - $self->{output}->option_exit(); - } - if (($self->{perfdata}->threshold_validate(label => 'warning-out', value => $self->{option_results}->{warning_out})) == 0) { - $self->{output}->add_option_msg(short_msg => "Wrong warning out threshold '" . $self->{option_results}->{warning_out} . "'."); - $self->{output}->option_exit(); - } - if (($self->{perfdata}->threshold_validate(label => 'critical-in', value => $self->{option_results}->{critical_in})) == 0) { - $self->{output}->add_option_msg(short_msg => "Wrong critical in threshold '" . $self->{option_results}->{critical_in} . "'."); - $self->{output}->option_exit(); - } - if (($self->{perfdata}->threshold_validate(label => 'critical-out', value => $self->{option_results}->{critical_out})) == 0) { - $self->{output}->add_option_msg(short_msg => "Wrong critical out threshold '" . $self->{option_results}->{critical_out} . "'."); - $self->{output}->option_exit(); - } - - $self->{statefile_value}->check_options(%options); -} - -sub run { - my ($self, %options) = @_; - $self->{snmp} = $options{snmp}; - $self->{hostname} = $self->{snmp}->get_hostname(); - $self->{snmp_port} = $self->{snmp}->get_port(); - - if ($self->{snmp}->is_snmpv1()) { - $self->{output}->add_option_msg(short_msg => "Can't check SNMP 64 bits counters with SNMPv1."); - $self->{output}->option_exit(); - } - - $self->manage_selection(); - - my $oid_pfsenseBlockedInPackets = '.1.3.6.1.4.1.12325.1.200.1.8.2.1.12'; - my $oid_pfsenseBlockedOutPackets = '.1.3.6.1.4.1.12325.1.200.1.8.2.1.14'; - my ($result, $valueIn, $valueOut); - - my $new_datas = {}; - $self->{statefile_value}->read(statefile => "pfsense_" . $self->{hostname} . '_' . $self->{snmp_port} . '_' . $self->{mode} . '_' . (defined($self->{option_results}->{interface}) ? md5_hex($self->{option_results}->{interface}) : md5_hex('all'))); - - $self->{snmp}->load(oids => [$oid_pfsenseBlockedInPackets, $oid_pfsenseBlockedOutPackets], - instances => $self->{interface_id_selected}); - $result = $self->{snmp}->get_leef(); - - $new_datas->{last_timestamp} = time(); - my $old_timestamp; - if (!defined($self->{option_results}->{interface}) || defined($self->{option_results}->{use_regexp})) { - $self->{output}->output_add(severity => 'OK', - short_msg => 'All interfaces are ok.'); - } - - foreach (sort @{$self->{interface_id_selected}}) { - my $display_value = $self->{names}->{$_}; - - ################# - # New values - ################# - $new_datas->{'in_blocked_' . $_} = $result->{$oid_pfsenseBlockedInPackets . "." . $_}; - $new_datas->{'out_blocked_' . $_} = $result->{$oid_pfsenseBlockedOutPackets . "." . $_}; - - ################ - # Old values - ################ - my @getting = ('in_blocked', 'out_blocked'); - my $old_datas = {}; - $old_timestamp = $self->{statefile_value}->get(name => 'last_timestamp'); - foreach my $key (@getting) { - $old_datas->{$key} = $self->{statefile_value}->get(name => $key . '_' . $_); - if (!defined($old_datas->{$key}) || $new_datas->{$key . '_' . $_} < $old_datas->{$key}) { - # We set 0. Has reboot. - $old_datas->{$key} = 0; - } - } - - if (!defined($old_timestamp)) { - next; - } - my $time_delta = $new_datas->{last_timestamp} - $old_timestamp; - if ($time_delta <= 0) { - # At least one second. two fast calls ;) - $time_delta = 1; - } - - ########### - - my $in_blocked_absolute = $new_datas->{'in_blocked_' . $_} - $old_datas->{in_blocked}; - my $out_blocked_absolute = $new_datas->{'out_blocked_' . $_} - $old_datas->{out_blocked}; - my $in_blocked_absolute_per_sec = $in_blocked_absolute / $time_delta; - my $out_blocked_absolute_per_sec = $out_blocked_absolute / $time_delta; - - ############### - # Manage Output - ############### - - my $exit1 = $self->{perfdata}->threshold_check(value => $in_blocked_absolute_per_sec, threshold => [ { label => 'critical-in', 'exit_litteral' => 'critical' }, { label => 'warning-in', exit_litteral => 'warning' } ]); - my $exit2 = $self->{perfdata}->threshold_check(value => $out_blocked_absolute_per_sec, threshold => [ { label => 'critical-out', 'exit_litteral' => 'critical' }, { label => 'warning-out', exit_litteral => 'warning' } ]); - - my $exit = $self->{output}->get_most_critical(status => [ $exit1, $exit2 ]); - $self->{output}->output_add(long_msg => sprintf("Interface '%s' Packets In Blocked : %.2f /s [%i packets], Out Blocked : %.2f /s [%i packets]", $display_value, - $in_blocked_absolute_per_sec, $in_blocked_absolute, - $out_blocked_absolute_per_sec, $out_blocked_absolute)); - - if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1) || (defined($self->{option_results}->{interface}) && !defined($self->{option_results}->{use_regexp}))) { - $self->{output}->output_add(severity => $exit, - short_msg => sprintf("Interface '%s' Packets In Blocked : %.2f /s [%i packets], Out Blocked : %.2f /s [%i packets]", $display_value, - $in_blocked_absolute_per_sec, $in_blocked_absolute, - $out_blocked_absolute_per_sec, $out_blocked_absolute)); - } - - my $extra_label = ''; - $extra_label = '_' . $display_value if (!defined($self->{option_results}->{interface}) || defined($self->{option_results}->{use_regexp})); - $self->{output}->perfdata_add(label => 'packets_blocked_in_per_sec' . $extra_label, - value => sprintf("%.2f", $in_blocked_absolute_per_sec), - warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-in'), - critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-in'), - min => 0); - $self->{output}->perfdata_add(label => 'packets_blocked_out_per_sec' . $extra_label, - value => sprintf("%.2f", $out_blocked_absolute_per_sec), - warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-out'), - critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-out'), - min => 0); - - } - - $self->{statefile_value}->write(data => $new_datas); - if (!defined($old_timestamp)) { - $self->{output}->output_add(severity => 'OK', - short_msg => "Buffer creation..."); - } - - $self->{output}->display(); - $self->{output}->exit(); -} - -sub manage_selection { - my ($self, %options) = @_; - - my $all_ids = []; - $self->{names} = {}; - my $result = $self->{snmp}->get_table(oid => $oid_pfsenseInterfaceName, nothing_quit => 1); - foreach my $key ($self->{snmp}->oid_lex_sort(keys %$result)) { - next if ($key !~ /\.([0-9]+)$/); - push @{$all_ids}, $1; - $self->{names}->{$1} = $self->{output}->to_utf8($result->{$key}); - } - - if (!defined($self->{option_results}->{use_name}) && defined($self->{option_results}->{interface})) { - # get by ID - push @{$self->{interface_id_selected}}, $self->{option_results}->{interface}; - if (!defined($self->{names}->{$self->{option_results}->{interface}})) { - $self->{output}->add_option_msg(short_msg => "No interface found for id '" . $self->{option_results}->{interface} . "'."); - $self->{output}->option_exit(); - } - } else { - foreach my $i (@{$all_ids}) { - my $filter_name = $self->{names}->{$i}; - next if (!defined($filter_name)); - if (!defined($self->{option_results}->{interface})) { - push @{$self->{interface_id_selected}}, $i; - next; - } - if (defined($self->{option_results}->{use_regexp}) && defined($self->{option_results}->{use_regexpi}) && $filter_name =~ /$self->{option_results}->{interface}/i) { - push @{$self->{interface_id_selected}}, $i; - } - if (defined($self->{option_results}->{use_regexp}) && !defined($self->{option_results}->{use_regexpi}) && $filter_name =~ /$self->{option_results}->{interface}/) { - push @{$self->{interface_id_selected}}, $i; - } - if (!defined($self->{option_results}->{use_regexp}) && !defined($self->{option_results}->{use_regexpi}) && $filter_name eq $self->{option_results}->{interface}) { - push @{$self->{interface_id_selected}}, $i; - } - } - - if (scalar(@{$self->{interface_id_selected}}) <= 0) { - if (defined($self->{option_results}->{interface})) { - $self->{output}->add_option_msg(short_msg => "No interface found for name '" . $self->{option_results}->{interface} . "' (maybe you should reload cache file)."); - } else { - $self->{output}->add_option_msg(short_msg => "No interface found (maybe you should reload cache file)."); - } - $self->{output}->option_exit(); - } - } -} - -1; - -__END__ - -=head1 MODE - -Check pfSense blocked packets. - -=over 8 - -=item B<--warning-in> - -Threshold warning for input blocked packets. - -=item B<--warning-out> - -Threshold warning for output blocked packets. - -=item B<--critical-in> - -Threshold critical for input blocked packets. - -=item B<--critical-out> - -Threshold critical for output blocked packets. - -=item B<--interface> - -Set the interface (number expected) ex: 1, 2,... (empty means 'check all interface'). - -=item B<--name> - -Allows to use interface name with option --interface instead of interface oid index. - -=item B<--regexp> - -Allows to use regexp to filter interfaces (with option --name). - -=item B<--regexp-isensitive> - -Allows to use regexp non case-sensitive (with --regexp). - -=back - -=cut diff --git a/centreon-plugins/apps/pfsense/snmp/mode/listpfinterfaces.pm b/centreon-plugins/apps/pfsense/snmp/mode/listpfinterfaces.pm new file mode 100644 index 000000000..3fb844c93 --- /dev/null +++ b/centreon-plugins/apps/pfsense/snmp/mode/listpfinterfaces.pm @@ -0,0 +1,112 @@ +# +# 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::pfsense::snmp::mode::listpfinterfaces; + +use base qw(centreon::plugins::mode); + +use strict; +use warnings; + +my $oid_pfInterfacesIfDescr = '.1.3.6.1.4.1.12325.1.200.1.8.2.1.2'; + +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' }, + }); + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::init(%options); +} + +sub manage_selection { + my ($self, %options) = @_; + + my $snmp_result = $self->{snmp}->get_table(oid => $oid_pfInterfacesIfDescr, nothing_quit => 1); + $self->{pfint} = {}; + foreach my $oid (keys %{$snmp_result}) { + if (defined($self->{option_results}->{filter_name}) && $self->{option_results}->{filter_name} ne '' && + $snmp_result->{$oid} !~ /$self->{option_results}->{filter_name}/) { + $self->{output}->output_add(long_msg => "skipping pfInteface '" . $snmp_result->{$oid} . "'.", debug => 1); + next; + } + + $self->{pfint}->{$snmp_result->{$oid}} = { name => $snmp_result->{$oid} }; + } +} + +sub run { + my ($self, %options) = @_; + $self->{snmp} = $options{snmp}; + + $self->manage_selection(); + foreach my $name (sort keys %{$self->{pfint}}) { + $self->{output}->output_add(long_msg => "'" . $name . "'"); + } + + $self->{output}->output_add(severity => 'OK', + short_msg => 'List pfIntefaces:'); + $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->{snmp} = $options{snmp}; + + $self->manage_selection(); + foreach my $name (sort keys %{$self->{pfint}}) { + $self->{output}->add_disco_entry(name => $name); + } +} + +1; + +__END__ + +=head1 MODE + +List pfInteface. + +=over 8 + +=item B<--filter-name> + +Filter by pfinterface name. + +=back + +=cut + diff --git a/centreon-plugins/apps/pfsense/snmp/mode/memorydroppedpackets.pm b/centreon-plugins/apps/pfsense/snmp/mode/memorydroppedpackets.pm deleted file mode 100644 index 6d15ee1ff..000000000 --- a/centreon-plugins/apps/pfsense/snmp/mode/memorydroppedpackets.pm +++ /dev/null @@ -1,130 +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::pfsense::snmp::mode::memorydroppedpackets; - -use base qw(centreon::plugins::mode); - -use strict; -use warnings; -use POSIX; -use centreon::plugins::statefile; - -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', }, - }); - $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}; - $self->{hostname} = $self->{snmp}->get_hostname(); - $self->{snmp_port} = $self->{snmp}->get_port(); - - my $oid_pfsenseMemDropPackets = '.1.3.6.1.4.1.12325.1.200.1.2.6.0'; - my ($result, $value); - - $result = $self->{snmp}->get_leef(oids => [ $oid_pfsenseMemDropPackets ], nothing_quit => 1); - $value = $result->{$oid_pfsenseMemDropPackets}; - - $self->{statefile_value}->read(statefile => 'pfsense_' . $self->{hostname} . '_' . $self->{snmp_port} . '_' . $self->{mode}); - my $old_timestamp = $self->{statefile_value}->get(name => 'last_timestamp'); - my $old_memDropPackets = $self->{statefile_value}->get(name => 'memDropPackets'); - - my $new_datas = {}; - $new_datas->{last_timestamp} = time(); - $new_datas->{memDropPackets} = $value; - - $self->{statefile_value}->write(data => $new_datas); - if (!defined($old_timestamp) || !defined($old_memDropPackets)) { - $self->{output}->output_add(severity => 'OK', - short_msg => "Buffer creation..."); - $self->{output}->display(); - $self->{output}->exit(); - } - $old_memDropPackets = 0 if ($old_memDropPackets > $new_datas->{memDropPackets}); - my $delta_time = $new_datas->{last_timestamp} - $old_timestamp; - $delta_time = 1 if ($delta_time == 0); - - my $memDropPacketsPerSec = ($new_datas->{memDropPackets} - $old_memDropPackets) / $delta_time; - - my $exit_code = $self->{perfdata}->threshold_check(value => $memDropPacketsPerSec, - threshold => [ { label => 'critical', 'exit_litteral' => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]); - $self->{output}->perfdata_add(label => 'dropped_packets_Per_Sec', - value => sprintf("%.2f", $memDropPacketsPerSec), - 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("Dropped packets due to memory limitations : %.2f /s", - $memDropPacketsPerSec)); - - $self->{output}->display(); - $self->{output}->exit(); -} - -1; - -__END__ - -=head1 MODE - -Check number of packets per second dropped due to memory limitations. - -=over 8 - -=item B<--warning> - -Threshold warning for dropped packets in packets per second. - -=item B<--critical> - -Threshold critical for dropped packets in packets per second. - -=back - -=cut diff --git a/centreon-plugins/apps/pfsense/snmp/mode/packetstats.pm b/centreon-plugins/apps/pfsense/snmp/mode/packetstats.pm new file mode 100644 index 000000000..9fa2b1415 --- /dev/null +++ b/centreon-plugins/apps/pfsense/snmp/mode/packetstats.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::pfsense::snmp::mode::packetstats; + +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, message_separator => ' - ' }, + ]; + + $self->{maps_counters}->{global} = [ + { label => 'match', set => { + key_values => [ { name => 'pfCounterMatch', diff => 1 } ], + per_second => 1, + output_template => 'Packets Matched Filter Rule : %.2f/s', + perfdatas => [ + { label => 'match', value => 'pfCounterMatch_per_second', template => '%.2f', unit => '/s', + min => 0 }, + ], + } + }, + { label => 'badoffset', set => { + key_values => [ { name => 'pfCounterBadOffset', diff => 1 } ], + per_second => 1, + output_template => 'Bad Offset Packets : %.2f/s', + perfdatas => [ + { label => 'bad_offset', value => 'pfCounterBadOffset_per_second', template => '%.2f', unit => '/s', + min => 0 }, + ], + } + }, + { label => 'fragment', set => { + key_values => [ { name => 'pfCounterFragment', diff => 1 } ], + per_second => 1, + output_template => 'Fragmented Packets : %.2f/s', + perfdatas => [ + { label => 'fragment', value => 'pfCounterFragment_per_second', template => '%.2f', unit => '/s', + min => 0 }, + ], + } + }, + { label => 'short', set => { + key_values => [ { name => 'pfCounterShort', diff => 1 } ], + per_second => 1, + output_template => 'Short Packets : %.2f/s', + perfdatas => [ + { label => 'short', value => 'pfCounterShort_per_second', template => '%.2f', unit => '/s', + min => 0 }, + ], + } + }, + { label => 'normalize', set => { + key_values => [ { name => 'pfCounterNormalize', diff => 1 } ], + per_second => 1, + output_template => 'Normalized Packets : %.2f/s', + perfdatas => [ + { label => 'normalize', value => 'pfCounterNormalize_per_second', template => '%.2f', unit => '/s', + min => 0 }, + ], + } + }, + { label => 'memdrop', set => { + key_values => [ { name => 'pfCounterMemDrop', diff => 1 } ], + per_second => 1, + output_template => 'Dropped Packets Due To Memory : %.2f/s', + perfdatas => [ + { label => 'memdrop', value => 'pfCounterMemDrop_per_second', template => '%.2f', unit => '/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) = @_; + + if ($options{snmp}->is_snmpv1()) { + $self->{output}->add_option_msg(short_msg => "Can't check SNMP 64 bits counters with SNMPv1."); + $self->{output}->option_exit(); + } + my %oids = ( + pfCounterMatch => '.1.3.6.1.4.1.12325.1.200.1.2.1.0', + pfCounterBadOffset => '.1.3.6.1.4.1.12325.1.200.1.2.2.0', + pfCounterFragment => '.1.3.6.1.4.1.12325.1.200.1.2.3.0', + pfCounterShort => '.1.3.6.1.4.1.12325.1.200.1.2.4.0', + pfCounterNormalize => '.1.3.6.1.4.1.12325.1.200.1.2.5.0', + pfCounterMemDrop => '.1.3.6.1.4.1.12325.1.200.1.2.6.0', + ); + my $snmp_result = $options{snmp}->get_leef(oids => [values %oids], nothing_quit => 1); + $self->{global} = {}; + foreach (keys %oids) { + $self->{global}->{$_} = $snmp_result->{$oids{$_}}; + } + + $self->{cache_name} = "pfsense_" . $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')); +} + +1; + +__END__ + +=head1 MODE + +Check global packet statistics. + +=over 8 + +=item B<--filter-counters> + +Only display some counters (regexp can be used). +Example: --filter-counters='^match$' + +=item B<--warning-*> + +Threshold warning. +Can be: 'match', 'badoffset', 'fragment', 'short', +'normalize', 'memdrop'. + +=item B<--critical-*> + +Threshold critical. +Can be: 'match', 'badoffset', 'fragment', 'short', +'normalize', 'memdrop'. + +=back + +=cut diff --git a/centreon-plugins/apps/pfsense/snmp/mode/pfinterfaces.pm b/centreon-plugins/apps/pfsense/snmp/mode/pfinterfaces.pm new file mode 100644 index 000000000..28212720f --- /dev/null +++ b/centreon-plugins/apps/pfsense/snmp/mode/pfinterfaces.pm @@ -0,0 +1,181 @@ +# +# 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::pfsense::snmp::mode::pfinterfaces; + +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 => 'pfint', type => 1, cb_prefix_output => 'prefix_pfint_output', message_multiple => 'All pfInterfaes are ok' } + ]; + + $self->{maps_counters}->{pfint} = [ + { label => 'traffic-in-pass', set => { + key_values => [ { name => 'pfInterfacesIf4BytesInPass', diff => 1 }, { name => 'display' } ], + per_second => 1, output_change_bytes => 2, + output_template => 'Traffic In Pass : %s %s/s', + perfdatas => [ + { label => 'traffic_in_pass', value => 'pfInterfacesIf4BytesInPass_per_second', template => '%.2f', + min => 0, unit => 'b/s', label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + { label => 'traffic-out-pass', set => { + key_values => [ { name => 'pfInterfacesIf4BytesOutPass', diff => 1 }, { name => 'display' } ], + per_second => 1, output_change_bytes => 2, + output_template => 'Traffic Out Pass : %s %s/s', + perfdatas => [ + { label => 'traffic_out_pass', value => 'pfInterfacesIf4BytesOutPass_per_second', template => '%.2f', + min => 0, unit => 'b/s', label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + { label => 'traffic-in-block', set => { + key_values => [ { name => 'pfInterfacesIf4BytesInBlock', diff => 1 }, { name => 'display' } ], + per_second => 1, output_change_bytes => 2, + output_template => 'Traffic In Block : %s %s/s', + perfdatas => [ + { label => 'traffic_in_block', value => 'pfInterfacesIf4BytesInBlock_per_second', template => '%.2f', + min => 0, unit => 'b/s', label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + { label => 'traffic-out-block', set => { + key_values => [ { name => 'pfInterfacesIf4BytesOutBlock', diff => 1 }, { name => 'display' } ], + per_second => 1, output_change_bytes => 2, + output_template => 'Traffic Out Block : %s %s/s', + perfdatas => [ + { label => 'traffic_out_block', value => 'pfInterfacesIf4BytesOutBlock_per_second', template => '%.2f', + min => 0, unit => 'b/s', label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + ]; +} + +sub prefix_pfint_output { + my ($self, %options) = @_; + + return "pfInterface '" . $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; +} + +my $oid_pfInterfacesIfDescr = '.1.3.6.1.4.1.12325.1.200.1.8.2.1.2'; +my $mapping = { + pfInterfacesIf4BytesInPass => { oid => '.1.3.6.1.4.1.12325.1.200.1.8.2.1.7' }, + pfInterfacesIf4BytesInBlock => { oid => '.1.3.6.1.4.1.12325.1.200.1.8.2.1.8' }, + pfInterfacesIf4BytesOutPass => { oid => '.1.3.6.1.4.1.12325.1.200.1.8.2.1.9' }, + pfInterfacesIf4BytesOutBlock => { oid => '.1.3.6.1.4.1.12325.1.200.1.8.2.1.10' }, +}; + +sub manage_selection { + my ($self, %options) = @_; + + if ($options{snmp}->is_snmpv1()) { + $self->{output}->add_option_msg(short_msg => "Can't check SNMP 64 bits counters with SNMPv1."); + $self->{output}->option_exit(); + } + my $snmp_result = $options{snmp}->get_table(oid => $oid_pfInterfacesIfDescr, nothing_quit => 1); + $self->{pfint} = {}; + foreach my $oid (keys %{$snmp_result}) { + $oid =~ /^$oid_pfInterfacesIfDescr\.(.*)$/; + my $instance = $1; + + my $name = $snmp_result->{$oid}; + 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 pfInterface '" . $name . "'.", debug => 1); + next; + } + + $self->{pfint}->{$instance} = { display => $name }; + } + + $options{snmp}->load(oids => [$mapping->{pfInterfacesIf4BytesInPass}->{oid}, $mapping->{pfInterfacesIf4BytesOutPass}->{oid}, + $mapping->{pfInterfacesIf4BytesInBlock}->{oid}, $mapping->{pfInterfacesIf4BytesOutBlock}->{oid}, + ], + instances => [keys %{$self->{pfint}}], instance_regexp => '^(.*)$'); + $snmp_result = $options{snmp}->get_leef(nothing_quit => 1); + + foreach my $instance (keys %{$self->{pfint}}) { + my $result = $options{snmp}->map_instance(mapping => $mapping, results => $snmp_result, instance => $instance); + + foreach (keys %$mapping) { + $self->{pfint}->{$instance}->{$_} = $result->{$_} * 8; + } + } + + if (scalar(keys %{$self->{pfint}}) <= 0) { + $self->{output}->add_option_msg(short_msg => "No pfInterface found."); + $self->{output}->option_exit(); + } + + $self->{cache_name} = "pfsense_" . $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 pfInterfaces. + +=over 8 + +=item B<--warning-*> + +Threshold warning. +Can be: 'traffic-in-pass', 'traffic-out-pass', 'traffic-in-block', 'traffic-out-block'. + +=item B<--critical-*> + +Threshold critical. +Can be: 'traffic-in-pass', 'traffic-out-pass', 'traffic-in-block', 'traffic-out-block'. + +=item B<--filter-name> + +Filter by interface name (can be a regexp). + +=back + +=cut diff --git a/centreon-plugins/apps/pfsense/snmp/mode/runtime.pm b/centreon-plugins/apps/pfsense/snmp/mode/runtime.pm index 85fbecf27..2a765f737 100644 --- a/centreon-plugins/apps/pfsense/snmp/mode/runtime.pm +++ b/centreon-plugins/apps/pfsense/snmp/mode/runtime.pm @@ -24,6 +24,7 @@ use base qw(centreon::plugins::mode); use strict; use warnings; +use centreon::plugins::misc; use POSIX; sub new { @@ -36,7 +37,6 @@ sub new { { "warning:s" => { name => 'warning', }, "critical:s" => { name => 'critical', }, - "seconds" => { name => 'seconds', }, }); return $self; @@ -78,7 +78,7 @@ sub run { min => 0); $self->{output}->output_add(severity => $exit_code, short_msg => sprintf("PfSense running since : %s", - defined($self->{option_results}->{seconds}) ? floor($valueRuntime / 100) . " seconds" : floor($valueRuntime / 86400 / 100) . " days" )); + centreon::plugins::misc::change_seconds(value => floor($valueRuntime / 100)))); } else { $self->{output}->perfdata_add(label => 'runtime', unit => 's', @@ -87,7 +87,7 @@ sub run { critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical'), min => 0); $self->{output}->output_add(severity => 'critical', - short_msg => sprintf("PfSense not running.")); + short_msg => 'PfSense not running'); } $self->{output}->display(); @@ -112,10 +112,6 @@ Threshold warning in seconds. Threshold critical in seconds. -=item B<--seconds> - -Display runtime in seconds. - =back =cut diff --git a/centreon-plugins/apps/pfsense/snmp/plugin.pm b/centreon-plugins/apps/pfsense/snmp/plugin.pm index 284cd7872..4781bc702 100644 --- a/centreon-plugins/apps/pfsense/snmp/plugin.pm +++ b/centreon-plugins/apps/pfsense/snmp/plugin.pm @@ -31,9 +31,10 @@ sub new { $self->{version} = '0.1'; %{$self->{modes}} = ( - 'runtime' => 'apps::pfsense::snmp::mode::runtime', - 'memory-dropped-packets' => 'apps::pfsense::snmp::mode::memorydroppedpackets', - 'blocked-packets' => 'apps::pfsense::snmp::mode::blockedpackets', + 'list-pfinterfaces' => 'apps::pfsense::snmp::mode::listpfinterfaces', + 'packet-stats' => 'apps::pfsense::snmp::mode::packetstats', + 'pfinterfaces' => 'apps::pfsense::snmp::mode::pfinterfaces', + 'runtime' => 'apps::pfsense::snmp::mode::runtime', ); return $self; diff --git a/centreon-plugins/apps/php/apc/web/mode/filecache.pm b/centreon-plugins/apps/php/apc/web/mode/filecache.pm index 9f02d5d16..28053726c 100644 --- a/centreon-plugins/apps/php/apc/web/mode/filecache.pm +++ b/centreon-plugins/apps/php/apc/web/mode/filecache.pm @@ -20,122 +20,105 @@ package apps::php::apc::web::mode::filecache; -use base qw(centreon::plugins::mode); +use base qw(centreon::plugins::templates::counter); use strict; use warnings; use centreon::plugins::http; -use centreon::plugins::statefile; -use centreon::plugins::values; +use Digest::MD5 qw(md5_hex); -my $maps_counters = { - 'request-rate' => { class => 'centreon::plugins::values', obj => undef, - set => { - key_values => [ - { name => 'rr' }, - ], - output_template => 'Request Rate (global): %.2f', - perfdatas => [ - { value => 'rr_absolute', label => 'request_rate',template => '%.2f', - unit => 'r/s', min => 0 }, - ], - } - }, - 'request-rate-now' => { class => 'centreon::plugins::values', obj => undef, - set => { - key_values => [ - { name => 'hits', diff => 1 }, { name => 'misses', diff => 1 }, - ], - closure_custom_calc => \&custom_rr_calc, per_second => 1, - output_template => 'Request Rate : %.2f', output_error_template => 'Request Rate : %s', - output_use => 'rr_now', threshold_use => 'rr_now', - perfdatas => [ - { value => 'rr_now', label => 'request_rate_now', template => '%.2f', - unit => 'r/s', min => 0 }, - ], - } - }, - 'hit-rate' => { class => 'centreon::plugins::values', obj => undef, - set => { - key_values => [ - { name => 'hr' }, - ], - output_template => 'Hit Rate (global): %.2f', - perfdatas => [ - { value => 'hr_absolute', label => 'hit_rate',template => '%.2f', - unit => 'r/s', min => 0 }, - ], - } - }, - 'hit-rate-now' => { class => 'centreon::plugins::values', obj => undef, - set => { - key_values => [ - { name => 'hits', diff => 1 }, - ], - closure_custom_calc => \&custom_hr_calc, per_second => 1, - output_template => 'Hit Rate : %.2f', output_error_template => 'Hit Rate : %s', - output_use => 'hr_now', threshold_use => 'hr_now', - perfdatas => [ - { value => 'hr_now', label => 'hit_rate_now', template => '%.2f', - unit => 'r/s', min => 0 }, - ], - } - }, - 'miss-rate' => { class => 'centreon::plugins::values', obj => undef, - set => { - key_values => [ - { name => 'mr' }, - ], - output_template => 'Miss Rate (global): %.2f', - perfdatas => [ - { value => 'mr_absolute', label => 'miss_rate',template => '%.2f', - unit => 'r/s', min => 0 }, - ], - } - }, - 'miss-rate-now' => { class => 'centreon::plugins::values', obj => undef, - set => { - key_values => [ - { name => 'misses', diff => 1 }, - ], - closure_custom_calc => \&custom_mr_calc, per_second => 1, - output_template => 'Miss Rate : %.2f', output_error_template => 'Miss Rate : %s', - output_use => 'mr_now', threshold_use => 'mr_now', - perfdatas => [ - { value => 'mr_now', label => 'miss_rate_now', template => '%.2f', - unit => 'r/s', min => 0 }, - ], - } - }, - 'hit-percent' => { class => 'centreon::plugins::values', obj => undef, - set => { - key_values => [ - { name => 'hits' }, { name => 'misses' }, - ], - closure_custom_calc => \&custom_hit_percent_calc, - output_template => 'Hit Ratio (global) : %.2f %%', output_error_template => 'Hit Ratio (global): %s', - output_use => 'hit_ratio', threshold_use => 'hit_ratio', - perfdatas => [ - { value => 'hit_ratio', label => 'hit_ratio', template => '%.2f', - unit => '%', min => 0, max => 100 }, - ], - } - }, - 'hit-percent-now' => { class => 'centreon::plugins::values', obj => undef, - set => { - key_values => [ - { name => 'hits', diff => 1 }, { name => 'misses', diff => 1 }, - ], - closure_custom_calc => \&custom_hit_percent_now_calc, - output_template => 'Hit Ratio : %.2f %%', output_error_template => 'Hit Ratio : %s', - output_use => 'hit_ratio_now', threshold_use => 'hit_ratio_now', - perfdatas => [ - { value => 'hit_ratio_now', label => 'hit_ratio_now', template => '%.2f', - unit => '%', min => 0, max => 100 }, - ], - } - }, -}; +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'fcache', type => 0, cb_prefix_output => 'prefix_output' } + ]; + + $self->{maps_counters}->{fcache} = [ + { label => 'request-rate', set => { + key_values => [ { name => 'rr' } ], + output_template => 'Request Rate (global): %.2f', + perfdatas => [ + { value => 'rr_absolute', label => 'request_rate',template => '%.2f', + unit => 'r/s', min => 0 }, + ], + } + }, + { label => 'request-rate-now', set => { + key_values => [ { name => 'hits', diff => 1 }, { name => 'misses', diff => 1 } ], + closure_custom_calc => $self->can('custom_rr_calc'), per_second => 1, + output_template => 'Request Rate : %.2f', output_error_template => 'Request Rate : %s', + output_use => 'rr_now', threshold_use => 'rr_now', + perfdatas => [ + { value => 'rr_now', label => 'request_rate_now', template => '%.2f', + unit => 'r/s', min => 0 }, + ], + } + }, + { label => 'hit-rate', set => { + key_values => [ { name => 'hr' } ], + output_template => 'Hit Rate (global): %.2f', + perfdatas => [ + { value => 'hr_absolute', label => 'hit_rate',template => '%.2f', + unit => 'r/s', min => 0 }, + ], + } + }, + { label => 'hit-rate-now', set => { + key_values => [ { name => 'hits', diff => 1 } ], + closure_custom_calc => $self->can('custom_hr_calc'), per_second => 1, + output_template => 'Hit Rate : %.2f', output_error_template => 'Hit Rate : %s', + output_use => 'hr_now', threshold_use => 'hr_now', + perfdatas => [ + { value => 'hr_now', label => 'hit_rate_now', template => '%.2f', + unit => 'r/s', min => 0 }, + ], + } + }, + { label => 'miss-rate', set => { + key_values => [ { name => 'mr' } ], + output_template => 'Miss Rate (global): %.2f', + perfdatas => [ + { value => 'mr_absolute', label => 'miss_rate',template => '%.2f', + unit => 'r/s', min => 0 }, + ], + } + }, + { label => 'miss-rate-now', set => { + key_values => [ { name => 'misses', diff => 1 } ], + closure_custom_calc => $self->can('custom_mr_calc'), per_second => 1, + output_template => 'Miss Rate : %.2f', output_error_template => 'Miss Rate : %s', + output_use => 'mr_now', threshold_use => 'mr_now', + perfdatas => [ + { value => 'mr_now', label => 'miss_rate_now', template => '%.2f', + unit => 'r/s', min => 0 }, + ], + } + }, + { label => 'hit-percent', set => { + key_values => [ { name => 'hits' }, { name => 'misses' } ], + closure_custom_calc => $self->can('custom_hit_percent_calc'), + output_template => 'Hit Ratio (global) : %.2f %%', output_error_template => 'Hit Ratio (global): %s', + output_use => 'hit_ratio', threshold_use => 'hit_ratio', + perfdatas => [ + { value => 'hit_ratio', label => 'hit_ratio', template => '%.2f', + unit => '%', min => 0, max => 100 }, + ], + } + }, + { label => 'hit-percent-now', set => { + key_values => [ { name => 'hits', diff => 1 }, { name => 'misses', diff => 1 } ], + closure_custom_calc => $self->can('custom_hit_percent_now_calc'), + output_template => 'Hit Ratio : %.2f %%', output_error_template => 'Hit Ratio : %s', + output_use => 'hit_ratio_now', threshold_use => 'hit_ratio_now', + perfdatas => [ + { value => 'hit_ratio_now', label => 'hit_ratio_now', template => '%.2f', + unit => '%', min => 0, max => 100 }, + ], + } + }, + ]; +} sub custom_rr_calc { my ($self, %options) = @_; @@ -205,9 +188,15 @@ sub custom_hit_percent_calc { return 0; } +sub prefix_output { + my ($self, %options) = @_; + + return "Apc File Cache Information "; +} + 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'; @@ -225,97 +214,32 @@ sub new { }); $self->{http} = centreon::plugins::http->new(output => $self->{output}); - $self->{statefile_value} = centreon::plugins::statefile->new(%options); - - foreach (keys %{$maps_counters}) { - $options{options}->add_options(arguments => { - 'warning-' . $_ . ':s' => { name => 'warning-' . $_ }, - 'critical-' . $_ . ':s' => { name => 'critical-' . $_ }, - }); - my $class = $maps_counters->{$_}->{class}; - $maps_counters->{$_}->{obj} = $class->new(statefile => $self->{statefile_value}, - output => $self->{output}, perfdata => $self->{perfdata}, - label => $_); - $maps_counters->{$_}->{obj}->set(%{$maps_counters->{$_}->{set}}); - } return $self; } sub check_options { my ($self, %options) = @_; - $self->SUPER::init(%options); - - foreach (keys %{$maps_counters}) { - $maps_counters->{$_}->{obj}->init(option_results => $self->{option_results}); - } + $self->SUPER::check_options(%options); $self->{http}->set_options(%{$self->{option_results}}); - $self->{statefile_value}->check_options(%options); -} - -sub run { - my ($self, %options) = @_; - $self->{webcontent} = $self->{http}->request(); - - $self->manage_selection(); - - $self->{new_datas} = {}; - $self->{statefile_value}->read(statefile => "apc_" . $self->{option_results}->{hostname} . '_' . $self->{http}->get_port() . '_' . $self->{mode}); - $self->{new_datas}->{last_timestamp} = time(); - - my ($short_msg, $short_msg_append, $long_msg, $long_msg_append) = ('', '', '', ''); - my @exits; - foreach (sort keys %{$maps_counters}) { - $maps_counters->{$_}->{obj}->set(instance => 'fcache'); - - my ($value_check) = $maps_counters->{$_}->{obj}->execute(values => $self->{fcache}, - new_datas => $self->{new_datas}); - - if ($value_check != 0) { - $long_msg .= $long_msg_append . $maps_counters->{$_}->{obj}->output_error(); - $long_msg_append = ', '; - next; - } - my $exit2 = $maps_counters->{$_}->{obj}->threshold_check(); - push @exits, $exit2; - - my $output = $maps_counters->{$_}->{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 = ', '; - } - - $maps_counters->{$_}->{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 => "Apc File Cache Information $short_msg" - ); - } else { - $self->{output}->output_add(short_msg => "Apc File Cache Information $long_msg"); - } - - $self->{statefile_value}->write(data => $self->{new_datas}); - $self->{output}->display(); - $self->{output}->exit(); } sub manage_selection { my ($self, %options) = @_; + my $webcontent = $self->{http}->request(); + $self->{fcache} = {}; - $self->{fcache}->{hits} = $self->{webcontent} =~ /File Cache Information.*?Hits.*?(\d+)/msi ? $1 : undef; - $self->{fcache}->{misses} = $self->{webcontent} =~ /File Cache Information.*?Misses.*?(\d+)/msi ? $1 : undef; - $self->{fcache}->{rr} = $self->{webcontent} =~ /File Cache Information.*?Request Rate.*?([0-9\.]+)/msi ? $1 : undef; - $self->{fcache}->{hr} = $self->{webcontent} =~ /File Cache Information.*?Hit Rate.*?([0-9\.]+)/msi ? $1 : undef; - $self->{fcache}->{mr} = $self->{webcontent} =~ /File Cache Information.*?Miss Rate.*?([0-9\.]+)/msi ? $1 : undef; - $self->{fcache}->{ir} = $self->{webcontent} =~ /File Cache Information.*?Insert Rate.*?([0-9\.]+)/msi ? $1 : undef; + $self->{fcache}->{hits} = $webcontent =~ /File Cache Information.*?Hits.*?(\d+)/msi ? $1 : undef; + $self->{fcache}->{misses} = $webcontent =~ /File Cache Information.*?Misses.*?(\d+)/msi ? $1 : undef; + $self->{fcache}->{rr} = $webcontent =~ /File Cache Information.*?Request Rate.*?([0-9\.]+)/msi ? $1 : undef; + $self->{fcache}->{hr} = $webcontent =~ /File Cache Information.*?Hit Rate.*?([0-9\.]+)/msi ? $1 : undef; + $self->{fcache}->{mr} = $webcontent =~ /File Cache Information.*?Miss Rate.*?([0-9\.]+)/msi ? $1 : undef; + $self->{fcache}->{ir} = $webcontent =~ /File Cache Information.*?Insert Rate.*?([0-9\.]+)/msi ? $1 : undef; + + $self->{cache_name} = "apc_" . $self->{mode} . '_' . $self->{option_results}->{hostname} . '_' . $self->{http}->get_port() . '_' . + (defined($self->{option_results}->{filter_counters}) ? md5_hex($self->{option_results}->{filter_counters}) : md5_hex('all')); } 1; @@ -368,7 +292,7 @@ Threshold for HTTP timeout (Default: 30) Threshold warning. Can be: 'request-rate', 'request-rate-now', -'hit-rate', 'hit-rate-now', 'miss-rate', 'miss-rate-now', 'insert-rate', +'hit-rate', 'hit-rate-now', 'miss-rate', 'miss-rate-now', 'hit-percent', 'hit-percent-now'. '*-now' are rate between two calls. @@ -376,7 +300,7 @@ Can be: 'request-rate', 'request-rate-now', Threshold critical. Can be: 'request-rate', 'request-rate-now', -'hit-rate', 'hit-rate-now', 'miss-rate', 'miss-rate-now', 'insert-rate', +'hit-rate', 'hit-rate-now', 'miss-rate', 'miss-rate-now', 'hit-percent', 'hit-percent-now'. '*-now' are rate between two calls. diff --git a/centreon-plugins/apps/php/apc/web/mode/memory.pm b/centreon-plugins/apps/php/apc/web/mode/memory.pm index da7baee2b..326763ac3 100644 --- a/centreon-plugins/apps/php/apc/web/mode/memory.pm +++ b/centreon-plugins/apps/php/apc/web/mode/memory.pm @@ -20,43 +20,45 @@ package apps::php::apc::web::mode::memory; -use base qw(centreon::plugins::mode); +use base qw(centreon::plugins::templates::counter); use strict; use warnings; use centreon::plugins::http; -use centreon::plugins::values; +use centreon::plugins::misc; -my $maps_counters = { - 'used' => { class => 'centreon::plugins::values', obj => undef, - set => { - key_values => [ - { name => 'free' }, { name => 'used' }, - ], - closure_custom_calc => \&custom_used_calc, - closure_custom_output => \&custom_used_output, - threshold_use => 'used_prct', - output_error_template => 'Memory Usage: %s', - perfdatas => [ - { value => 'used', label => 'used', template => '%d', - unit => 'B', min => 0, max => 'total', threshold_total => 'total' }, - ], - } - }, - 'fragmentation' => { class => 'centreon::plugins::values', obj => undef, - set => { - key_values => [ - { name => 'fragmentation' }, - ], - output_template => 'Memory Fragmentation: %.2f %%', output_error_template => 'Memory Fragmentation: %s', - output_use => 'fragmentation_absolute', threshold_use => 'fragmentation_absolute', - perfdatas => [ - { value => 'fragmentation_absolute', label => 'fragmentation', template => '%.2f', - unit => '%', min => 0, max => 100 }, - ], - } - }, -}; +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'mem', type => 0, cb_prefix_output => 'prefix_output' } + ]; + + $self->{maps_counters}->{mem} = [ + { label => 'used', set => { + key_values => [ { name => 'free' }, { name => 'free' } ], + closure_custom_calc => $self->can('custom_used_calc'), + closure_custom_output => $self->can('custom_used_output'), + threshold_use => 'used_prct', + output_error_template => 'Memory Usage: %s', + perfdatas => [ + { value => 'used', label => 'used', template => '%d', + unit => 'B', min => 0, max => 'total', threshold_total => 'total' }, + ], + } + }, + { label => 'fragmentation', set => { + key_values => [ { name => 'fragmentation' } ], + output_template => 'Memory Fragmentation: %.2f %%', output_error_template => 'Memory Fragmentation: %s', + output_use => 'fragmentation_absolute', threshold_use => 'fragmentation_absolute', + perfdatas => [ + { value => 'fragmentation_absolute', label => 'fragmentation', template => '%.2f', + unit => '%', min => 0, max => 100 }, + ], + } + }, + ]; +} sub custom_used_calc { my ($self, %options) = @_; @@ -82,6 +84,12 @@ sub custom_used_output { $free_value . " " . $free_unit, $self->{result_values}->{free_prct}); } +sub prefix_output { + my ($self, %options) = @_; + + return "Apc "; +} + sub new { my ($class, %options) = @_; my $self = $class->SUPER::new(package => __PACKAGE__, %options); @@ -103,106 +111,32 @@ sub new { $self->{http} = centreon::plugins::http->new(output => $self->{output}); - foreach (keys %{$maps_counters}) { - $options{options}->add_options(arguments => { - 'warning-' . $_ . ':s' => { name => 'warning-' . $_ }, - 'critical-' . $_ . ':s' => { name => 'critical-' . $_ }, - }); - my $class = $maps_counters->{$_}->{class}; - $maps_counters->{$_}->{obj} = $class->new(output => $self->{output}, perfdata => $self->{perfdata}, - label => $_); - $maps_counters->{$_}->{obj}->set(%{$maps_counters->{$_}->{set}}); - } - return $self; } sub check_options { my ($self, %options) = @_; - $self->SUPER::init(%options); - - foreach (keys %{$maps_counters}) { - $maps_counters->{$_}->{obj}->init(option_results => $self->{option_results}); - } + $self->SUPER::check_options(%options); $self->{http}->set_options(%{$self->{option_results}}); } -sub run { - my ($self, %options) = @_; - $self->{webcontent} = $self->{http}->request(); - - $self->manage_selection(); - - my ($short_msg, $short_msg_append, $long_msg, $long_msg_append) = ('', '', '', ''); - my @exits; - foreach (sort keys %{$maps_counters}) { - $maps_counters->{$_}->{obj}->set(instance => 'mem'); - - my ($value_check) = $maps_counters->{$_}->{obj}->execute(values => $self->{mem}); - - if ($value_check != 0) { - $long_msg .= $long_msg_append . $maps_counters->{$_}->{obj}->output_error(); - $long_msg_append = ', '; - next; - } - my $exit2 = $maps_counters->{$_}->{obj}->threshold_check(); - push @exits, $exit2; - - my $output = $maps_counters->{$_}->{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 = ', '; - } - - $maps_counters->{$_}->{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 => "Apc $short_msg" - ); - } else { - $self->{output}->output_add(short_msg => "Apc $long_msg"); - } - - $self->{output}->display(); - $self->{output}->exit(); -} - -sub in_bytes { - my ($self, %options) = @_; - my $value = $options{value}; - - if ($options{unit} =~ /^G/) { - $value *= 1024 * 1024 * 1024; - } elsif ($options{unit} =~ /^M/) { - $value *= 1024 * 1024; - } elsif ($options{unit} =~ /^K/) { - $value *= 1024; - } - - return $value; -} - sub manage_selection { my ($self, %options) = @_; + my $webcontent = $self->{http}->request(); + my ($free, $used); - if ($self->{webcontent} =~ /Memory Usage.*?Free:.*?([0-9\.]+)\s*(\S*)/msi) { - $free = $self->in_bytes(value => $1, unit => $2); + if ($webcontent =~ /Memory Usage.*?Free:.*?([0-9\.]+)\s*(\S*)/msi) { + $free = centreon::plugins::misc::convert_bytes(value => $1, unit => $2); } - if ($self->{webcontent} =~ /Memory Usage.*?Used:.*?([0-9\.]+)\s*(\S*)/msi) { - $used = $self->in_bytes(value => $1, unit => $2); + if ($webcontent =~ /Memory Usage.*?Used:.*?([0-9\.]+)\s*(\S*)/msi) { + $used = centreon::plugins::misc::convert_bytes(value => $1, unit => $2); } $self->{mem} = {}; $self->{mem}->{free} = $free; $self->{mem}->{used} = $used; - $self->{mem}->{fragmentation} = $self->{webcontent} =~ /Fragmentation:.*?([0-9\.]+)/msi ? $1 : undef; + $self->{mem}->{fragmentation} = $webcontent =~ /Fragmentation:.*?([0-9\.]+)/msi ? $1 : undef; } 1; diff --git a/centreon-plugins/apps/php/fpm/web/mode/usage.pm b/centreon-plugins/apps/php/fpm/web/mode/usage.pm index 60abce170..b263e0eed 100644 --- a/centreon-plugins/apps/php/fpm/web/mode/usage.pm +++ b/centreon-plugins/apps/php/fpm/web/mode/usage.pm @@ -20,33 +20,38 @@ package apps::php::fpm::web::mode::usage; -use base qw(centreon::plugins::mode); +use base qw(centreon::plugins::templates::counter); use strict; use warnings; use centreon::plugins::http; -use centreon::plugins::values; -use centreon::plugins::statefile; +use Digest::MD5 qw(md5_hex); -my $maps_counters = { - fpm => { - '000_active-processes' => { set => { +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'fpm', type => 0, cb_prefix_output => 'prefix_output' } + ]; + + $self->{maps_counters}->{fpm} = [ + { label => 'active-processes', set => { key_values => [ { name => 'active' }, { name => 'total' } ], - closure_custom_calc => \&custom_active_calc, - closure_custom_output => \&custom_active_output, + closure_custom_calc => $self->can('custom_active_calc'), + closure_custom_output => $self->can('custom_active_output'), threshold_use => 'active_prct', - closure_custom_perfdata => => \&custom_active_perfdata, + closure_custom_perfdata => => $self->can('custom_active_perfdata'), } }, - '001_idle-processes' => { set => { + { label => 'idle-processes', set => { key_values => [ { name => 'idle' }, { name => 'total' } ], - closure_custom_calc => \&custom_idle_calc, - closure_custom_output => \&custom_idle_output, + closure_custom_calc => $self->can('custom_idle_calc'), + closure_custom_output => $self->can('custom_idle_output'), threshold_use => 'idle_prct', - closure_custom_perfdata => => \&custom_idle_perfdata, + closure_custom_perfdata => => $self->can('custom_idle_perfdata'), } - }, - '002_listen-queue' => { set => { + }, + { label => 'listen-queue', set => { key_values => [ { name => 'listen_queue' }, { name => 'max_listen_queue' } ], output_template => 'Listen queue : %s', output_use => 'listen_queue_absolute', threshold_use => 'listen_queue_absolute', @@ -56,7 +61,7 @@ my $maps_counters = { ], } }, - '003_requests' => { set => { + { label => 'requests', set => { key_values => [ { name => 'request', diff => 1 } ], per_second => 1, output_template => 'Requests : %.2f/s', @@ -66,8 +71,8 @@ my $maps_counters = { ], } }, - }, -}; + ]; +} sub custom_active_calc { my ($self, %options) = @_; @@ -123,9 +128,15 @@ sub custom_idle_perfdata { min => 0, max => $self->{result_values}->{total}); } +sub prefix_output { + my ($self, %options) = @_; + + return "php-fpm "; +} + 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'; @@ -141,108 +152,34 @@ sub new { "proxyurl:s" => { name => 'proxyurl' }, "timeout:s" => { name => 'timeout', default => 5 }, }); - $self->{statefile_value} = centreon::plugins::statefile->new(%options); $self->{http} = centreon::plugins::http->new(output => $self->{output}); - foreach my $key (('fpm')) { - 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); + $self->SUPER::check_options(%options); - foreach my $key (('fpm')) { - foreach (keys %{$maps_counters->{$key}}) { - $maps_counters->{$key}->{$_}->{obj}->init(option_results => $self->{option_results}); - } - } - - $self->{statefile_value}->check_options(%options); $self->{http}->set_options(%{$self->{option_results}}); } -sub run { - my ($self, %options) = @_; - $self->{webcontent} = $self->{http}->request(); - - $self->manage_selection(); - - $self->{new_datas} = {}; - $self->{statefile_value}->read(statefile => "php_fpm_" . $self->{option_results}->{hostname} . '_' . $self->{http}->get_port() . '_' . $self->{mode}); - $self->{new_datas}->{last_timestamp} = time(); - - my ($short_msg, $short_msg_append, $long_msg, $long_msg_append) = ('', '', '', ''); - my @exits; - - foreach (sort keys %{$maps_counters->{fpm}}) { - my $obj = $maps_counters->{fpm}->{$_}->{obj}; - - $obj->set(instance => 'fpm'); - - my ($value_check) = $obj->execute(values => $self->{fpm}, - 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 => "php-fpm $short_msg" - ); - } else { - $self->{output}->output_add(short_msg => "php-fpm $long_msg"); - } - - $self->{statefile_value}->write(data => $self->{new_datas}); - $self->{output}->display(); - $self->{output}->exit(); -} - sub manage_selection { my ($self, %options) = @_; + my $webcontent = $self->{http}->request(); + $self->{fpm} = { request => undef, listen_queue => undef, max_listen_queue => undef, idle => undef, active => undef, total => undef }; - $self->{fpm}->{request} = $1 if ($self->{webcontent} =~ /accepted\s+conn:\s+(\d+)/msi); - $self->{fpm}->{listen_queue} = $1 if ($self->{webcontent} =~ /listen\s+queue:\s+(\d+)/msi); - $self->{fpm}->{max_listen_queue} = $1 if ($self->{webcontent} =~ /max\s+listen\s+queue:\s+(\d+)/msi); - $self->{fpm}->{idle} = $1 if ($self->{webcontent} =~ /idle\s+processes:\s+(\d+)/msi); - $self->{fpm}->{active} = $1 if ($self->{webcontent} =~ /active\s+processes:\s+(\d+)/msi); - $self->{fpm}->{total} = $1 if ($self->{webcontent} =~ /total\s+processes:\s+(\d+)/msi); + $self->{fpm}->{request} = $1 if ($webcontent =~ /accepted\s+conn:\s+(\d+)/msi); + $self->{fpm}->{listen_queue} = $1 if ($webcontent =~ /listen\s+queue:\s+(\d+)/msi); + $self->{fpm}->{max_listen_queue} = $1 if ($webcontent =~ /max\s+listen\s+queue:\s+(\d+)/msi); + $self->{fpm}->{idle} = $1 if ($webcontent =~ /idle\s+processes:\s+(\d+)/msi); + $self->{fpm}->{active} = $1 if ($webcontent =~ /active\s+processes:\s+(\d+)/msi); + $self->{fpm}->{total} = $1 if ($webcontent =~ /total\s+processes:\s+(\d+)/msi); + + $self->{cache_name} = "php_fpm_" . $self->{mode} . '_' . $self->{option_results}->{hostname} . '_' . $self->{http}->get_port() . '_' . + (defined($self->{option_results}->{filter_counters}) ? md5_hex($self->{option_results}->{filter_counters}) : md5_hex('all')); } 1; diff --git a/centreon-plugins/apps/protocols/radius/mode/login.pm b/centreon-plugins/apps/protocols/radius/mode/login.pm index a3e66358d..7662d55e5 100644 --- a/centreon-plugins/apps/protocols/radius/mode/login.pm +++ b/centreon-plugins/apps/protocols/radius/mode/login.pm @@ -20,13 +20,85 @@ package apps::protocols::radius::mode::login; -use base qw(centreon::plugins::mode); +use base qw(centreon::plugins::templates::counter); use strict; use warnings; use Time::HiRes qw(gettimeofday tv_interval); use Authen::Radius; +my $instance_mode; +my $radius_result_attributes = {}; + +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 = 'Radius Access Request Status: ' . $self->{result_values}->{status} . + ' [error msg: ' . $self->{result_values}->{error_msg} . ']'; + return $msg; +} + +sub custom_status_calc { + my ($self, %options) = @_; + + $self->{result_values}->{status} = $options{new_datas}->{$self->{instance} . '_status'}; + $self->{result_values}->{error_msg} = $options{new_datas}->{$self->{instance} . '_error_msg'}; + $self->{result_values}->{attributes} = $radius_result_attributes; + return 0; +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'radius', type => 0, message_separator => ' - ' }, + ]; + + $self->{maps_counters}->{radius} = [ + { label => 'status', threshold => 0, set => { + key_values => [ { name => 'status' }, { name => 'error_msg' } ], + 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 => 'time', set => { + key_values => [ { name => 'elapsed' } ], + output_template => 'Response time : %.3f second(s)', + perfdatas => [ + { label => 'time', value => 'elapsed_absolute', template => '%.3f', + min => 0, unit => 's' }, + ], + } + }, + ]; +} + sub new { my ($class, %options) = @_; my $self = $class->SUPER::new(package => __PACKAGE__, %options); @@ -36,81 +108,141 @@ sub new { $options{options}->add_options(arguments => { "hostname:s" => { name => 'hostname' }, + "port:s" => { name => 'port', default => 1812 }, "secret:s" => { name => 'secret' }, "username:s" => { name => 'username' }, "password:s" => { name => 'password' }, "warning:s" => { name => 'warning' }, "critical:s" => { name => 'critical' }, - "timeout:s" => { name => 'timeout', default => '30' }, + "timeout:s" => { name => 'timeout', default => 5 }, + "retry:s" => { name => 'retry', default => 0 }, + 'radius-attribute:s%' => { name => 'radius_attribute' }, + 'radius-dictionary:s' => { name => 'radius_dictionary' }, + "warning-status:s" => { name => 'warning_status', default => '' }, + "critical-status:s" => { name => 'critical_status', default => '%{status} ne "accepted"' }, }); + return $self; } 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} . "'."); + my @mandatory = ('hostname', 'secret'); + push @mandatory, 'username', 'password' if (!defined($self->{option_results}->{radius_attribute})); + foreach (@mandatory) { + if (!defined($self->{option_results}->{$_})) { + $self->{output}->add_option_msg(short_msg => "Please set the " . $_ . " option"); + $self->{output}->option_exit(); + } + } + + if (defined($self->{option_results}->{radius_attribute}) && + (!defined($self->{option_results}->{radius_dictionary}) || $self->{option_results}->{radius_dictionary} eq '')) { + $self->{output}->add_option_msg(short_msg => "Please set radius-dictionary option"); $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->{option_results}->{retry} = 0 if (!defined($self->{option_results}->{retry}) || $self->{option_results}->{retry} !~ /^\d+$/); + if (defined($self->{option_results}->{port}) && $self->{option_results}->{port} =~ /^\d+$/) { + $self->{option_results}->{hostname} .= ':' . $self->{option_results}->{port}; } + $instance_mode = $self; + $self->change_macros(); +} - if (!defined($self->{option_results}->{hostname})) { - $self->{output}->add_option_msg(short_msg => "Please set the hostname option"); - $self->{output}->option_exit(); - } +sub change_macros { + my ($self, %options) = @_; - if (!defined($self->{option_results}->{secret})) { - $self->{output}->add_option_msg(short_msg => "Please set the secret option"); - $self->{output}->option_exit(); - } - - 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(); + foreach (('warning_status', 'critical_status')) { + if (defined($self->{option_results}->{$_})) { + $self->{option_results}->{$_} =~ s/%\{(.*?)\}/\$self->{result_values}->{$1}/g; + } } } -sub run { +sub radius_simple_connection { my ($self, %options) = @_; - my $timing0 = [gettimeofday]; - - my $radius = Authen::Radius->new(Host => $self->{option_results}->{hostname}, - Secret => $self->{option_results}->{secret}, - TimeOut => $self->{option_results}->{timeout}, - ); + $self->{timing0} = [gettimeofday]; + my $retry = 0; + while ($retry <= $self->{option_results}->{retry}) { + if ($self->{radius_session}->check_pwd($self->{option_results}->{username}, $self->{option_results}->{password})) { + $self->{radius}->{status} = 'accepted'; + last; + } - - my $authentication = $radius->check_pwd($self->{option_results}->{username}, $self->{option_results}->{password}); - - if ($authentication != 1) { - $self->{output}->output_add(severity => 'CRITICAL', - short_msg => 'Authentication failed'); + if ($retry + 1 > $self->{option_results}->{retry}) { + $self->{radius}->{status} = 'rejected'; + $self->{radius}->{error_msg} = $self->{radius_session}->strerror(); + } + $retry++; } +} - my $timeelapsed = tv_interval ($timing0, [gettimeofday]); +sub radius_attr_connection { + my ($self, %options) = @_; - my $exit = $self->{perfdata}->threshold_check(value => $timeelapsed, - threshold => [ { label => 'critical', 'exit_litteral' => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]); - $self->{output}->output_add(severity => $exit, - short_msg => sprintf("Response time %.3f second(s)", $timeelapsed)); - $self->{output}->perfdata_add(label => "time", unit => 's', - value => sprintf('%.3f', $timeelapsed), - warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning'), - critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical')); + my $message; + eval { + local $SIG{__WARN__} = sub { $message = join(' - ', @_); }; + local $SIG{__DIE__} = sub { $message = join(' - ', @_); }; - $self->{output}->display(); - $self->{output}->exit(); + Authen::Radius->load_dictionary($self->{option_results}->{radius_dictionary}); + foreach (keys %{$self->{option_results}->{radius_attribute}}) { + $self->{radius_session}->add_attributes({ Name => $_, Value => $self->{option_results}->{radius_attribute}->{$_} }); + } + }; + if (defined($message)) { + $self->{output}->output_add(long_msg => $message, debug => 1); + $self->{output}->add_option_msg(short_msg => "Issue with dictionary and attributes"); + $self->{output}->option_exit(); + } + + $self->{timing0} = [gettimeofday]; + my $retry = 0; + while ($retry <= $self->{option_results}->{retry}) { + my $type; + + if ($self->{radius_session}->send_packet(ACCESS_REQUEST) && ($type = $self->{radius_session}->recv_packet()) == ACCESS_ACCEPT) { + $self->{radius}->{status} = 'accepted'; + last; + } + + if ($retry + 1 > $self->{option_results}->{retry}) { + $self->{radius}->{status} = 'unknown'; + $self->{radius}->{error_msg} = $self->{radius_session}->strerror(); + if (defined($type) && $type == ACCESS_REJECT) { + $self->{radius}->{status} = 'rejected'; + } + } + $retry++; + } +} + +sub manage_selection { + my ($self, %options) = @_; + + $self->{radius} = { status => 'unknown', error_msg => 'none' }; + $self->{radius_session} = Authen::Radius->new( + Host => $self->{option_results}->{hostname}, + Secret => $self->{option_results}->{secret}, + TimeOut => $self->{option_results}->{timeout}, + ); + + if (defined($self->{option_results}->{radius_attribute})) { + $self->radius_attr_connection(); + } else { + $self->radius_simple_connection(); + } + + $self->{radius}->{elapsed} = tv_interval($self->{timing0}, [gettimeofday]); + foreach my $attr ($self->{radius_session}->get_attributes()) { + $radius_result_attributes->{$attr->{Name}} = defined($attr->{Value}) ? $attr->{Value} : ''; + $self->{output}->output_add(long_msg => 'Attribute Name = ' . $attr->{Name} . + ', Value = ' . (defined($attr->{Value}) ? $attr->{Value} : ''), debug => 1); + } } 1; @@ -119,7 +251,10 @@ __END__ =head1 MODE -Check Connection (also login) to a Radius Server. +Check login to a Radius Server. + +Example with attributes: +centreon_plugins.pl --plugin=apps/protocols/radius/plugin.pm --mode=login --hostname=192.168.1.2 --secret=centreon --radius-attribute='User-Password=test' --radius-attribute='User-Name=user@test.com' --radius-dictionary=dictionary.txt =over 8 @@ -127,6 +262,10 @@ Check Connection (also login) to a Radius Server. IP Addr/FQDN of the radius host +=item B<--port> + +Radius port (Default: 1812) + =item B<--secret> Secret of the radius host @@ -141,13 +280,37 @@ Specify password for authentication =item B<--timeout> -Connection timeout in seconds (Default: 30) +Connection timeout in seconds (Default: 5) -=item B<--warning> +=item B<--timeout> + +Number of retry connection (Default: 0) + +=item B<--radius-attribute> + +If you need to add option, please following attributes. +Option username and password should be set with that option. +Example: --radius-attribute="User-Password=test" + +=item B<--radius-dictionary> + +Set radius-dictionary file (mandatory with --radius-attribute). + +=item B<--warning-status> + +Set warning threshold for status (Default: ''). +Can used special variables like: %{status}, %{error_msg}, %{attributes}. + +=item B<--critical-status> + +Set critical threshold for status (Default: '%{status} ne "accepted"'). +Can used special variables like: %{status}, %{error_msg}, %{attributes}. + +=item B<--warning-time> Threshold warning in seconds -=item B<--critical> +=item B<--critical-time> Threshold critical in seconds diff --git a/centreon-plugins/apps/protocols/ssh/mode/login.pm b/centreon-plugins/apps/protocols/ssh/mode/login.pm new file mode 100644 index 000000000..16d775619 --- /dev/null +++ b/centreon-plugins/apps/protocols/ssh/mode/login.pm @@ -0,0 +1,168 @@ +# +# 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::protocols::ssh::mode::login; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; +use Time::HiRes qw(gettimeofday tv_interval); + +my $instance_mode; + +sub custom_status_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'; + } + }; + 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("%s", $self->{result_values}->{message}); + return $msg; +} + +sub custom_status_calc { + my ($self, %options) = @_; + + $self->{result_values}->{message} = $options{new_datas}->{$self->{instance} . '_message'}; + $self->{result_values}->{status} = $options{new_datas}->{$self->{instance} . '_status'}; + return 0; +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'global', type => 0, message_separator => ' - ' }, + ]; + $self->{maps_counters}->{global} = [ + { label => 'status', threshold => 0, set => { + key_values => [ { name => 'status' }, { name => 'message' } ], + 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_output'), + } + }, + { label => 'time', set => { + key_values => [ { name => 'time_elapsed' } ], + output_template => 'Response time %.3fs', + perfdatas => [ + { label => 'time', value => 'time_elapsed_absolute', template => '%.3f', unit => 's', min => 0 }, + ], + } + }, + ]; +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => + { + "warning-status:s" => { name => 'warning_status', default => '' }, + "critical-status:s" => { name => 'critical_status', default => '%{message} !~ /authentification succeeded/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 $timing0 = [gettimeofday]; + my $result = $options{custom}->login(); + my $timeelapsed = tv_interval($timing0, [gettimeofday]); + $self->{global} = { %$result, time_elapsed => $timeelapsed }; +} + +1; + +__END__ + +=head1 MODE + +Check SSH connection. + +=over 8 + +=item B<--warning-status> + +Set warning threshold for status. +Can used special variables like: %{status}, %{message} + +=item B<--critical-status> + +Set critical threshold for status (Default: '%{message} !~ /authentification succeeded/i' +Can used special variables like: %{status}, %{message} + +=item B<--warning-time> + +Threshold warning in seconds. + +=item B<--critical-time> + +Threshold critical in seconds. + +=back + +=cut diff --git a/centreon-plugins/apps/protocols/ssh/plugin.pm b/centreon-plugins/apps/protocols/ssh/plugin.pm new file mode 100644 index 000000000..1e299d451 --- /dev/null +++ b/centreon-plugins/apps/protocols/ssh/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 apps::protocols::ssh::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}} = ( + 'login' => 'apps::protocols::ssh::mode::login', + ); + + $self->{custom_modes}{api} = 'centreon::common::protocols::ssh::custom::api'; + return $self; +} + +1; + +__END__ + +=head1 PLUGIN DESCRIPTION + +Check a SSH server. + +Need Libssh perl: +https://github.com/garnier-quentin/perl-libssh + +=cut diff --git a/centreon-plugins/apps/tomcat/jmx/mode/connectorusage.pm b/centreon-plugins/apps/tomcat/jmx/mode/connectorusage.pm new file mode 100644 index 000000000..cea015621 --- /dev/null +++ b/centreon-plugins/apps/tomcat/jmx/mode/connectorusage.pm @@ -0,0 +1,255 @@ +# +# 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::connectorusage; + +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 => 'tomcatconnector', type => 1, cb_prefix_output => 'prefix_connector_output', message_multiple => 'All connectors are ok' }, + ]; + + $self->{maps_counters}->{tomcatconnector} = [ + { label => 'threads-count', set => { + key_values => [ { name => 'currentThreadCount' }, { name => 'maxThreads' }, { 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 => 'threads-busy', set => { + key_values => [ { name => 'currentThreadsBusy' }, { name => 'maxThreads' }, { name => 'display' } ], + closure_custom_calc => $self->can('custom_usage_calc'), + closure_custom_calc_extra_options => { label_ref => 'currentThreadsBusy', message => 'Current Busy 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 => 'request-count', set => { + key_values => [ { name => 'requestCount', diff => 1 }, { name => 'display' } ], + output_template => 'Request Count : %s', + perfdatas => [ + { label => 'request_count', value => 'requestCount_absolute', template => '%s', + min => 0, label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + { label => 'traffic-in', set => { + key_values => [ { name => 'bytesReceived', diff => 1 }, { name => 'display' } ], + per_second => 1, output_change_bytes => 2, + output_template => 'Traffic In : %s %s/s', + perfdatas => [ + { label => 'traffic_in', value => 'bytesReceived_per_second', template => '%.2f', + min => 0, unit => 'b/s', label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + { label => 'traffic-out', set => { + key_values => [ { name => 'bytesSent', diff => 1 }, { name => 'display' } ], + per_second => 1, output_change_bytes => 2, + output_template => 'Traffic Out : %s %s/s', + perfdatas => [ + { label => 'traffic_out', value => 'bytesSent_per_second', template => '%.2f', + min => 0, unit => 'b/s', 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("%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} . '_maxThreads'}; + $self->{result_values}->{used} = $options{new_datas}->{$self->{instance} . '_' . $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_connector_output { + my ($self, %options) = @_; + + return "Connector '" . $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) = @_; + + # Tomcat: Catalina + # Jboss: jboss.web + $self->{request} = [ + { mbean => "*:name=*,type=ThreadPool", attributes => [ { name => 'currentThreadCount' }, { name => 'currentThreadsBusy' }, { name => 'maxThreads' } ] }, + { mbean => "*:name=*,type=GlobalRequestProcessor", attributes => [ { name => 'bytesReceived' }, { name => 'bytesSent' }, { name => 'requestCount' } ] } + ]; + + my $result = $options{custom}->get_attributes(request => $self->{request}, nothing_quit => 1); + + $self->{tomcatconnector} = {}; + foreach my $key (keys %$result) { + $key =~ /name=(.*?),type=(.*)/; + my ($connector, $type) = ($1, $2); + + if (defined($self->{option_results}->{filter_name}) && $self->{option_results}->{filter_name} ne '' && + $connector !~ /$self->{option_results}->{filter_name}/) { + $self->{output}->output_add(long_msg => "skipping '" . $connector . "': no matching filter.", debug => 1); + next; + } + + $result->{$key}->{bytesSent} *= 8 if (defined($result->{$key}->{bytesSent})); + $result->{$key}->{bytesReceived} *= 8 if (defined($result->{$key}->{bytesReceived})); + $self->{tomcatconnector}->{$connector} = { display => $connector } + if (!defined($self->{tomcatconnector}->{$connector})); + $self->{tomcatconnector}->{$connector} = { %{$self->{tomcatconnector}->{$connector}}, %{$result->{$key}} }; + } + + $self->{cache_name} = "tomcat_" . $self->{mode} . '_' . md5_hex($options{custom}->{url}) . '_' . + (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 connector usage. + +=over 8 + +=item B<--filter-counters> + +Only display some counters (regexp can be used). +Example: --filter-counters='threads-busy' + +=item B<--filter-name> + +Filter connector name (can be a regexp). + +=item B<--warning-*> + +Threshold warning. +Can be: 'threads-count', 'threads-busy', 'request-count', 'traffic-in', 'traffic-out'. + +=item B<--critical-*> + +Threshold critical. +Can be: 'threads-count', 'threads-busy', 'request-count', 'traffic-in', 'traffic-out'. + +=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 150596b90..25a5c57a6 100644 --- a/centreon-plugins/apps/tomcat/jmx/plugin.pm +++ b/centreon-plugins/apps/tomcat/jmx/plugin.pm @@ -32,6 +32,7 @@ sub new { $self->{version} = '0.1'; %{$self->{modes}} = ( 'class-count' => 'centreon::common::jvm::mode::classcount', + 'connector-usage' => 'apps::tomcat::jmx::mode::connectorusage', 'cpu-load' => 'centreon::common::jvm::mode::cpuload', 'fd-usage' => 'centreon::common::jvm::mode::fdusage', 'gc-usage' => 'centreon::common::jvm::mode::gcusage', diff --git a/centreon-plugins/apps/tomcat/web/mode/traffic.pm b/centreon-plugins/apps/tomcat/web/mode/traffic.pm index 08480457d..eecf4001d 100644 --- a/centreon-plugins/apps/tomcat/web/mode/traffic.pm +++ b/centreon-plugins/apps/tomcat/web/mode/traffic.pm @@ -20,18 +20,121 @@ package apps::tomcat::web::mode::traffic; -use base qw(centreon::plugins::mode); +use base qw(centreon::plugins::templates::counter); + use strict; use warnings; use centreon::plugins::http; -use centreon::plugins::statefile; use Digest::MD5 qw(md5_hex); use XML::XPath; use URI::Escape; +my $instance_mode; + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'connector', type => 1, cb_prefix_output => 'prefix_connector_output', message_multiple => 'All connector traffics are ok' }, + ]; + + $self->{maps_counters}->{connector} = [ + { label => 'in', set => { + key_values => [ { name => 'in', diff => 1 }, { name => 'display' } ], + per_second => 1, + closure_custom_calc => $self->can('custom_traffic_calc'), closure_custom_calc_extra_options => { label_ref => 'in' }, + closure_custom_output => $self->can('custom_traffic_output'), + closure_custom_perfdata => $self->can('custom_traffic_perfdata'), + closure_custom_threshold_check => $self->can('custom_traffic_threshold'), + } + }, + { label => 'out', set => { + key_values => [ { name => 'out', diff => 1 }, { name => 'display' } ], + per_second => 1, + closure_custom_calc => $self->can('custom_traffic_calc'), closure_custom_calc_extra_options => { label_ref => 'out' }, + closure_custom_output => $self->can('custom_traffic_output'), + closure_custom_perfdata => $self->can('custom_traffic_perfdata'), + closure_custom_threshold_check => $self->can('custom_traffic_threshold'), + } + }, + ]; +} + +sub custom_traffic_perfdata { + my ($self, %options) = @_; + + my $extra_label = ''; + if (!defined($options{extra_instance}) || $options{extra_instance} != 0) { + $extra_label .= '_' . $self->{result_values}->{display}; + } + + my ($warning, $critical); + if ($instance_mode->{option_results}->{units_traffic} eq '%' && defined($self->{result_values}->{speed})) { + $warning = $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{label}, total => $self->{result_values}->{speed}, cast_int => 1); + $critical = $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{label}, total => $self->{result_values}->{speed}, cast_int => 1); + } elsif ($instance_mode->{option_results}->{units_traffic} eq 'b/s') { + $warning = $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{label}); + $critical = $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{label}); + } + + $self->{output}->perfdata_add(label => 'traffic_' . $self->{result_values}->{label} . $extra_label, unit => 'b/s', + value => sprintf("%.2f", $self->{result_values}->{traffic}), + warning => $warning, + critical => $critical, + min => 0, max => $self->{result_values}->{speed}); +} + +sub custom_traffic_threshold { + my ($self, %options) = @_; + + my $exit = 'ok'; + if ($instance_mode->{option_results}->{units_traffic} eq '%' && defined($self->{result_values}->{speed})) { + $exit = $self->{perfdata}->threshold_check(value => $self->{result_values}->{traffic_prct}, threshold => [ { label => 'critical-' . $self->{label}, exit_litteral => 'critical' }, { label => 'warning-' . $self->{label}, exit_litteral => 'warning' } ]); + } elsif ($instance_mode->{option_results}->{units_traffic} eq 'b/s') { + $exit = $self->{perfdata}->threshold_check(value => $self->{result_values}->{traffic}, threshold => [ { label => 'critical-' . $self->{label}, exit_litteral => 'critical' }, { label => 'warning-' . $self->{label}, exit_litteral => 'warning' } ]); + } + return $exit; +} + +sub custom_traffic_output { + my ($self, %options) = @_; + + my ($traffic_value, $traffic_unit) = $self->{perfdata}->change_bytes(value => $self->{result_values}->{traffic}, network => 1); + my ($total_value, $total_unit); + if (defined($self->{result_values}->{speed}) && $self->{result_values}->{speed} =~ /[0-9]/) { + ($total_value, $total_unit) = $self->{perfdata}->change_bytes(value => $self->{result_values}->{speed}, network => 1); + } + + my $msg = sprintf("Traffic %s : %s/s (%s on %s)", + ucfirst($self->{result_values}->{label}), $traffic_value . $traffic_unit, + defined($self->{result_values}->{traffic_prct}) ? sprintf("%.2f%%", $self->{result_values}->{traffic_prct}) : '-', + defined($total_value) ? $total_value . $total_unit : '-'); + return $msg; +} + +sub custom_traffic_calc { + my ($self, %options) = @_; + + $self->{result_values}->{label} = $options{extra_options}->{label_ref}; + $self->{result_values}->{display} = $options{new_datas}->{$self->{instance} . '_display'}; + my $diff_traffic = $options{new_datas}->{$self->{instance} . '_' . $self->{result_values}->{label}} - $options{old_datas}->{$self->{instance} . '_' . $self->{result_values}->{label}}; + $self->{result_values}->{traffic} = $diff_traffic / $options{delta_time}; + if (defined($instance_mode->{option_results}->{'speed_' . $self->{result_values}->{label}}) && $instance_mode->{option_results}->{'speed_' . $self->{result_values}->{label}} =~ /[0-9]/) { + $self->{result_values}->{traffic_prct} = $self->{result_values}->{traffic} * 100 / ($instance_mode->{option_results}->{'speed_' . $self->{result_values}->{label}} * 1000 * 1000); + $self->{result_values}->{speed} = $instance_mode->{option_results}->{'speed_' . $self->{result_values}->{label}} * 1000 * 1000; + } + return 0; +} + +sub prefix_connector_output { + my ($self, %options) = @_; + + return "Connector '" . $options{instance_value}->{display} . "' "; +} + 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'; @@ -46,73 +149,37 @@ sub new { "proxyurl:s" => { name => 'proxyurl' }, "timeout:s" => { name => 'timeout' }, "urlpath:s" => { name => 'url_path', default => '/manager/status?XML=true' }, - "name:s" => { name => 'name' }, - "regexp" => { name => 'use_regexp' }, - "regexp-isensitive" => { name => 'use_regexpi' }, - "speed:s" => { name => 'speed' }, - "warning-in:s" => { name => 'warning_in' }, - "critical-in:s" => { name => 'critical_in' }, - "warning-out:s" => { name => 'warning_out' }, - "critical-out:s" => { name => 'critical_out' }, + "filter-name:s" => { name => 'filter_name' }, + "speed-in:s" => { name => 'speed_in' }, + "speed-out:s" => { name => 'speed_out' }, + "units-traffic:s" => { name => 'units_traffic', default => '%' }, }); - $self->{result} = {}; - $self->{hostname} = undef; - $self->{statefile_value} = centreon::plugins::statefile->new(%options); $self->{http} = centreon::plugins::http->new(output => $self->{output}); return $self; } sub check_options { my ($self, %options) = @_; - $self->SUPER::init(%options); - - if (($self->{perfdata}->threshold_validate(label => 'warning-in', value => $self->{option_results}->{warning_in})) == 0) { - $self->{output}->add_option_msg(short_msg => "Wrong warning 'in' threshold '" . $self->{option_results}->{warning_in} . "'."); - $self->{output}->option_exit(); - } - if (($self->{perfdata}->threshold_validate(label => 'critical-in', value => $self->{option_results}->{critical_in})) == 0) { - $self->{output}->add_option_msg(short_msg => "Wrong critical 'in' threshold '" . $self->{option_results}->{critical_in} . "'."); - $self->{output}->option_exit(); - } - if (($self->{perfdata}->threshold_validate(label => 'warning-out', value => $self->{option_results}->{warning_out})) == 0) { - $self->{output}->add_option_msg(short_msg => "Wrong warning 'out' threshold '" . $self->{option_results}->{warning_out} . "'."); - $self->{output}->option_exit(); - } - if (($self->{perfdata}->threshold_validate(label => 'critical-out', value => $self->{option_results}->{critical_out})) == 0) { - $self->{output}->add_option_msg(short_msg => "Wrong critical 'out' threshold '" . $self->{option_results}->{critical_out} . "'."); - $self->{output}->option_exit(); - } - if (defined($self->{option_results}->{speed}) && $self->{option_results}->{speed} ne '' && $self->{option_results}->{speed} !~ /^[0-9]+(\.[0-9]+){0,1}$/) { - $self->{output}->add_option_msg(short_msg => "Speed must be a positive number '" . $self->{option_results}->{speed} . "' (can be a float also)."); - $self->{output}->option_exit(); - } - if (defined($self->{option_results}->{units}) && $self->{option_results}->{units} eq '%' && - (!defined($self->{option_results}->{speed}) || $self->{option_results}->{speed} eq '')) { - $self->{output}->add_option_msg(short_msg => "To use percent, you need to set --speed option."); - $self->{output}->option_exit(); - } + $self->SUPER::check_options(%options); - $self->{statefile_value}->check_options(%options); $self->{hostname} = $self->{option_results}->{hostname}; if (!defined($self->{hostname})) { $self->{hostname} = 'me'; } $self->{http}->set_options(%{$self->{option_results}}); + $instance_mode = $self; } my %xpath_to_check = ( - in => '/status/connector/requestInfo/@bytesReceived', - out => '/status/connector/requestInfo/@bytesSent', + in => '/status/connector/requestInfo/@bytesReceived', + out => '/status/connector/requestInfo/@bytesSent', ); sub manage_selection { my ($self, %options) = @_; - my $webcontent = $self->{http}->request(); - my $port = $self->{option_results}->{port}; - #EXAMPLE 1: # # @@ -150,22 +217,29 @@ sub manage_selection { # # # + my $webcontent = $self->{http}->request(); #GET XML DATA - my $xpath = XML::XPath->new( xml => $webcontent ); + my $xpath = XML::XPath->new(xml => $webcontent); my %xpath_check_results; - foreach my $xpath_check ( keys %xpath_to_check ) { - my $singlepath = $xpath_to_check{$xpath_check}; - $singlepath =~ s{\$port}{$port}; + $self->{connector} = {}; + foreach my $label (keys %xpath_to_check) { + my $singlepath = $xpath_to_check{$label}; my $nodeset = $xpath->find($singlepath); - foreach my $node ($nodeset->get_nodelist) { + foreach my $node ($nodeset->get_nodelist()) { my $connector_name = $node->getParentNode()->getParentNode()->getAttribute("name"); $connector_name =~ s/^["'\s]+//; $connector_name =~ s/["'\s]+$//; $connector_name = uri_unescape($connector_name); + if (defined($self->{option_results}->{filter_name}) && $self->{option_results}->{filter_name} ne '' && + $connector_name !~ /$self->{option_results}->{filter_name}/) { + $self->{output}->output_add(long_msg => "skipping '" . $connector_name . "': no matching filter.", debug => 1); + next; + } + next if (defined($self->{option_results}->{name}) && defined($self->{option_results}->{use_regexp}) && defined($self->{option_results}->{use_regexpi}) && $connector_name !~ /$self->{option_results}->{name}/i); next if (defined($self->{option_results}->{name}) && defined($self->{option_results}->{use_regexp}) && !defined($self->{option_results}->{use_regexpi}) @@ -173,126 +247,23 @@ sub manage_selection { next if (defined($self->{option_results}->{name}) && !defined($self->{option_results}->{use_regexp}) && !defined($self->{option_results}->{use_regexpi}) && $connector_name ne $self->{option_results}->{name}); + $self->{connector}->{$connector_name} = { display => $connector_name } if (!defined($self->{connector}->{$connector_name})); my $value = $node->string_value(); - if ( $value =~ /^"?([0-9.]+)"?$/ ) { - $self->{result}->{$connector_name}{$xpath_check} = $1; - } else { - $self->{result}->{$connector_name}{$xpath_check} = "not_numeric"; - }; - }; - - if (scalar(keys %{$self->{result}}) <= 0) { - if (defined($self->{option_results}->{name})) { - $self->{output}->add_option_msg(short_msg => "No information found for name '" . $self->{option_results}->{name} . "'."); - } else { - $self->{output}->add_option_msg(short_msg => "No information found."); - } - $self->{output}->option_exit(); - }; - }; -}; - -sub run { - my ($self, %options) = @_; - - $self->manage_selection(); - - my $new_datas = {}; - $self->{statefile_value}->read(statefile => 'cache_apps_tomcat_web_' . $self->{option_results}->{hostname} . '_' . $self->{http}->get_port() . '_' . $self->{mode} . '_' . (defined($self->{option_results}->{name}) ? md5_hex($self->{option_results}->{name}) : md5_hex('all'))); - $new_datas->{last_timestamp} = time(); - my $old_timestamp = $self->{statefile_value}->get(name => 'last_timestamp'); - - if (!defined($self->{option_results}->{name}) || defined($self->{option_results}->{use_regexp})) { - $self->{output}->output_add(severity => 'OK', - short_msg => 'All traffic are ok.'); - } - - foreach my $name (sort(keys %{$self->{result}})) { - $new_datas->{'in_' . $name} = $self->{result}->{$name}->{in} * 8; - $new_datas->{'out_' . $name} = $self->{result}->{$name}->{out} * 8; - - my $old_in = $self->{statefile_value}->get(name => 'in_' . $name); - my $old_out = $self->{statefile_value}->get(name => 'out_' . $name); - if (!defined($old_timestamp) || !defined($old_in) || !defined($old_out)) { - next; - } - if ($new_datas->{'in_' . $name} < $old_in) { - # We set 0. Has reboot. - $old_in = 0; - } - if ($new_datas->{'out_' . $name} < $old_out) { - # We set 0. Has reboot. - $old_out = 0; - } - - my $time_delta = $new_datas->{last_timestamp} - $old_timestamp; - if ($time_delta <= 0) { - # At least one second. two fast calls ;) - $time_delta = 1; - } - my $in_absolute_per_sec = ($new_datas->{'in_' . $name} - $old_in) / $time_delta; - my $out_absolute_per_sec = ($new_datas->{'out_' . $name} - $old_out) / $time_delta; - - my ($exit, $interface_speed, $in_prct, $out_prct); - if (defined($self->{option_results}->{speed}) && $self->{option_results}->{speed} ne '') { - $interface_speed = $self->{option_results}->{speed} * 1000000; - $in_prct = $in_absolute_per_sec * 100 / ($self->{option_results}->{speed} * 1000000); - $out_prct = $out_absolute_per_sec * 100 / ($self->{option_results}->{speed} * 1000000); - if ($self->{option_results}->{units} eq '%') { - my $exit1 = $self->{perfdata}->threshold_check(value => $in_prct, threshold => [ { label => 'critical-in', 'exit_litteral' => 'critical' }, { label => 'warning-in', exit_litteral => 'warning' } ]); - my $exit2 = $self->{perfdata}->threshold_check(value => $out_prct, threshold => [ { label => 'critical-out', 'exit_litteral' => 'critical' }, { label => 'warning-out', exit_litteral => 'warning' } ]); - $exit = $self->{output}->get_most_critical(status => [ $exit1, $exit2 ]); + if ($value =~ /^"?([0-9.]+)"?$/) { + $self->{connector}->{$connector_name}->{$label} = $1 * 8; } - $in_prct = sprintf("%.2f", $in_prct); - $out_prct = sprintf("%.2f", $out_prct); - } else { - my $exit1 = $self->{perfdata}->threshold_check(value => $in_absolute_per_sec, threshold => [ { label => 'critical-in', 'exit_litteral' => 'critical' }, { label => 'warning-in', exit_litteral => 'warning' } ]); - my $exit2 = $self->{perfdata}->threshold_check(value => $out_absolute_per_sec, threshold => [ { label => 'critical-out', 'exit_litteral' => 'critical' }, { label => 'warning-out', exit_litteral => 'warning' } ]); - $exit = $self->{output}->get_most_critical(status => [ $exit1, $exit2 ]); - $in_prct = '-'; - $out_prct = '-'; } - - ########### - # Manage Output - ########### - - my ($in_value, $in_unit) = $self->{perfdata}->change_bytes(value => $in_absolute_per_sec, network => 1); - my ($out_value, $out_unit) = $self->{perfdata}->change_bytes(value => $out_absolute_per_sec, network => 1); - $self->{output}->output_add(long_msg => sprintf("Connector '%s' Traffic In : %s/s (%s %%), Out : %s/s (%s %%) ", $name, - $in_value . $in_unit, $in_prct, - $out_value . $out_unit, $out_prct)); - if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1) || (defined($self->{option_results}->{name}) && !defined($self->{option_results}->{use_regexp}))) { - $self->{output}->output_add(severity => $exit, - short_msg => sprintf("Connector '%s' Traffic In : %s/s (%s %%), Out : %s/s (%s %%) ", $name, - $in_value . $in_unit, $in_prct, - $out_value . $out_unit, $out_prct)); - } - - my $extra_label = ''; - $extra_label = '_' . $name if (!defined($self->{option_results}->{name}) || defined($self->{option_results}->{use_regexp})); - - $self->{output}->perfdata_add(label => 'traffic_in' . $extra_label, unit => 'b/s', - value => sprintf("%.2f", $in_absolute_per_sec), - warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-in', total => $interface_speed), - critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-in', total => $interface_speed), - min => 0, max => $interface_speed); - $self->{output}->perfdata_add(label => 'traffic_out' . $extra_label, unit => 'b/s', - value => sprintf("%.2f", $out_absolute_per_sec), - warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-out', total => $interface_speed), - critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-out', total => $interface_speed), - min => 0, max => $interface_speed); } - $self->{statefile_value}->write(data => $new_datas); - if (!defined($old_timestamp)) { - $self->{output}->output_add(severity => 'OK', - short_msg => "Buffer creation..."); + if (scalar(keys %{$self->{connector}}) <= 0) { + $self->{output}->add_option_msg(short_msg => "No information found."); + $self->{output}->option_exit(); } - - $self->{output}->display(); - $self->{output}->exit(); -}; + + $self->{cache_name} = "tomcat_web_" . $self->{mode} . '_' . $self->{option_results}->{hostname} . '_' . $self->{http}->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; @@ -340,37 +311,31 @@ Threshold for HTTP timeout Path to the Tomcat Manager XML (Default: '/manager/status?XML=true') -=item B<--name> +=item B<--filter-name> -Set the filter name (empty means 'check all contexts') +Filter by context name (can be a regexp). -=item B<--regexp> +=item B<--warning-*> -Allows to use regexp to filter (with option --name). +Threshold warning. +Can be: 'in', 'out'. -=item B<--regexp-isensitive> +=item B<--critical-*> -Allows to use regexp non case-sensitive (with --regexp). +Threshold critical. +Can be: 'in', 'out'. -=item B<--warning-in> +=item B<--units-traffic> -Threshold warning in percent for 'in' traffic. +Units of thresholds for the traffic (Default: '%') ('%', 'b/s'). -=item B<--critical-in> +=item B<--speed-in> -Threshold critical in percent for 'in' traffic. +Set interface speed for incoming traffic (in Mb). -=item B<--warning-out> +=item B<--speed-out> -Threshold warning in percent for 'out' traffic. - -=item B<--critical-out> - -Threshold critical in percent for 'out' traffic. - -=item B<--speed> - -Set Connector Interface speed (in Mb). +Set interface speed for outgoing traffic (in Mb). =back diff --git a/centreon-plugins/apps/toshiba/storemate/sql/mode/maintenanceplan.pm b/centreon-plugins/apps/toshiba/storemate/sql/mode/maintenanceplan.pm new file mode 100644 index 000000000..9046b7a60 --- /dev/null +++ b/centreon-plugins/apps/toshiba/storemate/sql/mode/maintenanceplan.pm @@ -0,0 +1,214 @@ +# +# 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::toshiba::storemate::sql::mode::maintenanceplan; + +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 [workstation: %s] [text: %s] %s", $self->{result_values}->{workstation_id}, + $self->{result_values}->{description}, $self->{result_values}->{generation_time}); + return $msg; +} + +sub custom_status_calc { + my ($self, %options) = @_; + + $self->{result_values}->{description} = $options{new_datas}->{$self->{instance} . '_description'}; + $self->{result_values}->{workstation_id} = $options{new_datas}->{$self->{instance} . '_workstation_id'}; + $self->{result_values}->{since} = $options{new_datas}->{$self->{instance} . '_since'}; + $self->{result_values}->{generation_time} = $options{new_datas}->{$self->{instance} . '_generation_time'}; + 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 => 'description' }, { name => 'workstation_id' }, { name => 'since' }, { name => 'generation_time' } ], + 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 => + { + "database:s" => { name => 'database', default => 'Framework' }, + "warning-status:s" => { name => 'warning_status', default => '' }, + "critical-status:s" => { name => 'critical_status', default => '1 == 1' }, + "memory" => { name => 'memory' }, + "timezone:s" => { name => 'timezone' }, + }); + + centreon::plugins::misc::mymodule_load(output => $self->{output}, module => 'DateTime', + error_msg => "Cannot load module 'DateTime'."); + $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); + } + + $self->{option_results}->{timezone} = 'GMT' if (!defined($self->{option_results}->{timezone}) || $self->{option_results}->{timezone} eq ''); +} + +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->{sql} = $options{sql}; + $self->{sql}->connect(); + $self->{sql}->query(query => "SELECT CONVERT(varchar, LOGDATE, 120) as LOGDATE, WORKSTATION_ID, USER_ID, DESCRIPTION, DESCRIPTION_PARAMETERS + FROM " . $self->{option_results}->{database} . ".dbo.log + WHERE (TYPE <> 1) AND (DESCRIPTION_PARAMETERS LIKE N'\%FO\%') AND (TASKNAME = 'FOCleanup')"); + $self->{alarms}->{global} = { alarm => {} }; + my $last_time; + if (defined($self->{option_results}->{memory})) { + $self->{statefile_cache}->read(statefile => 'cache_toshiba_storemate_' . $self->{mode} . '_' . $self->{sql}->get_unique_id4save()); + $last_time = $self->{statefile_cache}->get(name => 'last_time'); + } + + my ($i, $current_time) = (1, time()); + while (my $row = $self->{sql}->fetchrow_hashref()) { + # date form: 2017-09-22 01:01:08.133 + $row->{LOGDATE} =~ /^(\d+)-(\d+)-(\d+)\s+(\d+)[:\/](\d+)[:\/](\d+)/; + + my $dt = DateTime->new(year => $1, month => $2, day => $3, hour => $4, minute => $5, second => $6, + time_zone => $self->{option_results}->{timezone}); + + next if (defined($self->{option_results}->{memory}) && defined($last_time) && $last_time > $dt->epoch); + + my $diff_time = $current_time - $dt->epoch; + + $self->{alarms}->{global}->{alarm}->{$i} = { + description => $row->{DESCRIPTION}, + workstation_id => $row->{WORKSTATION_ID}, + since => $diff_time, generation_time => centreon::plugins::misc::change_seconds(value => $diff_time) + }; + $i++; + } + + if (defined($self->{option_results}->{memory})) { + $self->{statefile_cache}->write(data => { last_time => $current_time }); + } +} + +1; + +__END__ + +=head1 MODE + +Check the maintenance plan error logs. + +=over 8 + +=item B<--database> + +Database name (default: 'Framework'). + +=item B<--warning-status> + +Set warning threshold for status (Default: '') +Can used special variables like: %{description}, %{workstation_id}, %{since} + +=item B<--critical-status> + +Set critical threshold for status (Default: '1 == 1'. We match all errors). +Can used special variables like: %{description}, %{workstation_id}, %{since} + +=item B<--timezone> + +Timezone of time options. Default is 'GMT'. + +=item B<--memory> + +Only check new alarms. + +=back + +=cut + diff --git a/centreon-plugins/apps/toshiba/storemate/sql/mode/posstatus.pm b/centreon-plugins/apps/toshiba/storemate/sql/mode/posstatus.pm new file mode 100644 index 000000000..b6069e951 --- /dev/null +++ b/centreon-plugins/apps/toshiba/storemate/sql/mode/posstatus.pm @@ -0,0 +1,295 @@ +# +# 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::toshiba::storemate::sql::mode::posstatus; + +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_global_output' }, + { name => 'state', type => 0, cb_prefix_output => 'prefix_state_output' }, + { name => 'merchandise', type => 0, cb_prefix_output => 'prefix_merchandise_output' }, + { name => 'transaction', type => 0, cb_prefix_output => 'prefix_transaction_output' }, + ]; + + $self->{maps_counters}->{global} = [ + { label => 'total', set => { + key_values => [ { name => 'total' } ], + output_template => 'total : %s', + perfdatas => [ + { label => 'total', value => 'total_absolute', template => '%s', + min => 0 }, + ], + } + }, + { label => 'online', set => { + key_values => [ { name => 'online' } ], + output_template => 'online : %s', + perfdatas => [ + { label => 'online', value => 'online_absolute', template => '%s', + min => 0 }, + ], + } + }, + { label => 'offline', set => { + key_values => [ { name => 'offline' } ], + output_template => 'offline : %s', + perfdatas => [ + { label => 'offline', value => 'offline_absolute', template => '%s', + min => 0 }, + ], + } + }, + ]; + + $self->{maps_counters}->{state} = [ + { label => 'state-unknown', set => { + key_values => [ { name => 'unknown' } ], + output_template => 'unknown : %s', + perfdatas => [ + { label => 'state_unknown', value => 'unknown_absolute', template => '%s', + min => 0 }, + ], + } + }, + { label => 'state-signoff', set => { + key_values => [ { name => 'signoff' } ], + output_template => 'signed off : %s', + perfdatas => [ + { label => 'state_signoff', value => 'signoff_absolute', template => '%s', + min => 0 }, + ], + } + }, + { label => 'state-signon', set => { + key_values => [ { name => 'signon' } ], + output_template => 'signed on : %s', + perfdatas => [ + { label => 'state_signon', value => 'signon_absolute', template => '%s', + min => 0 }, + ], + } + }, + { label => 'state-closed', set => { + key_values => [ { name => 'closed' } ], + output_template => 'closed : %s', + perfdatas => [ + { label => 'state_closed', value => 'closed_absolute', template => '%s', + min => 0 }, + ], + } + }, + { label => 'state-paused', set => { + key_values => [ { name => 'paused' } ], + output_template => 'paused : %s', + perfdatas => [ + { label => 'state_paused', value => 'paused_absolute', template => '%s', + min => 0 }, + ], + } + }, + ]; + + $self->{maps_counters}->{merchandise} = [ + { label => 'merchandise-rep-unknown', set => { + key_values => [ { name => 'unknown' } ], + output_template => 'unknown : %s', + perfdatas => [ + { label => 'merchandise_rep_unknown', value => 'unknown_absolute', template => '%s', + min => 0 }, + ], + } + }, + { label => 'merchandise-rep-ok', set => { + key_values => [ { name => 'ok' } ], + output_template => 'ok : %s', + perfdatas => [ + { label => 'merchandise_rep_ok', value => 'ok_absolute', template => '%s', + min => 0 }, + ], + } + }, + { label => 'merchandise-rep-suspended', set => { + key_values => [ { name => 'suspended' } ], + output_template => 'suspended : %s', + perfdatas => [ + { label => 'merchandise_rep_suspended', value => 'suspended_absolute', template => '%s', + min => 0 }, + ], + } + }, + { label => 'merchandise-rep-error', set => { + key_values => [ { name => 'error' } ], + output_template => 'error : %s', + perfdatas => [ + { label => 'merchandise_rep_error', value => 'error_absolute', template => '%s', + min => 0 }, + ], + } + }, + ]; + + $self->{maps_counters}->{transaction} = [ + { label => 'transaction-rep-unknown', set => { + key_values => [ { name => 'unknown' } ], + output_template => 'unknown : %s', + perfdatas => [ + { label => 'transaction_rep_unknown', value => 'unknown_absolute', template => '%s', + min => 0 }, + ], + } + }, + { label => 'transaction-rep-ok', set => { + key_values => [ { name => 'ok' } ], + output_template => 'ok : %s', + perfdatas => [ + { label => 'transaction_rep_ok', value => 'ok_absolute', template => '%s', + min => 0 }, + ], + } + }, + { label => 'transaction-rep-suspended', set => { + key_values => [ { name => 'suspended' } ], + output_template => 'suspended : %s', + perfdatas => [ + { label => 'transaction_rep_suspended', value => 'suspended_absolute', template => '%s', + min => 0 }, + ], + } + }, + { label => 'transaction-rep-error', set => { + key_values => [ { name => 'error' } ], + output_template => 'error : %s', + perfdatas => [ + { label => 'transaction_rep_error', value => 'error_absolute', template => '%s', + min => 0 }, + ], + } + }, + ]; +} + +sub prefix_global_output { + my ($self, %options) = @_; + + return "Points of sale "; +} + +sub prefix_state_output { + my ($self, %options) = @_; + + return "State "; +} + +sub prefix_merchandise_output { + my ($self, %options) = @_; + + return "Merchandise replication "; +} + +sub prefix_transaction_output { + my ($self, %options) = @_; + + return "Transaction replication "; +} + +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 => + { + "database:s" => { name => 'database', default => 'Framework' }, + }); + + return $self; +} + +sub manage_selection { + my ($self, %options) = @_; + + $self->{sql} = $options{sql}; + $self->{sql}->connect(); + $self->{sql}->query(query => "SELECT WORKSTATION_ID, ONLINE, FO_STATE, MERCHANDISE_REPLICATION, TRANSACTION_REPLICATION + FROM " . $self->{option_results}->{database} . ".dbo.WORKSTATION_STATUS"); + + $self->{global} = { total => 0, online => 0, offline => 0 }; + $self->{state} = { unknown => 0, signoff => 0, signon => 0, closed => 0, paused => 0 }; + $self->{merchandise} = { unknown => 0, ok => 0, suspended => 0, error => 0 }; + $self->{transaction} = { unknown => 0, ok => 0, suspended => 0, error => 0 }; + + my %map_status = (0 => 'offline', 1 => 'online'); + my %map_state = (0 => 'unknown', 1 => 'signoff', 2 => 'signon', 3 => 'closed', 4 => 'paused'); + my %map_merch_rep_status = (0 => 'unknown', 1 => 'ok', 2 => 'suspended', 3 => 'error'); + my %map_trans_rep_status = (0 => 'unknown', 1 => 'ok', 2 => 'suspended', 3 => 'error'); + + while (my $row = $self->{sql}->fetchrow_hashref()) { + $self->{global}->{total}++; + $self->{global}->{$map_status{$row->{ONLINE}}}++ + if (defined($map_status{$row->{ONLINE}})); + $self->{state}->{$map_state{$row->{FO_STATE}}}++ + if (defined($map_state{$row->{FO_STATE}})); + $self->{merchandise}->{$map_merch_rep_status{$row->{MERCHANDISE_REPLICATION}}}++ + if (defined($map_merch_rep_status{$row->{MERCHANDISE_REPLICATION}})); + $self->{transaction}->{$map_trans_rep_status{$row->{TRANSACTION_REPLICATION}}}++ + if (defined($map_trans_rep_status{$row->{TRANSACTION_REPLICATION}})); + } +} + +1; + +__END__ + +=head1 MODE + +Check points of sale status + +=over 8 + +=item B<--database> + +Database name (default: 'Framework'). + +=item B<--warning-*> + +Threshold warning. +Can be: 'online, offline, state-unknown, state-signoff, state-signon, state-closed, state-paused, +merchandise-rep-unknown, merchandise-rep-ok, merchandise-rep-suspended, merchandise-rep-error, +transaction-rep-unknown, transaction-rep-ok, transaction-rep-suspended, transaction-rep-error'. + +=item B<--critical-*> + +Threshold critical. +Can be: 'online, offline, state-unknown, state-signoff, state-signon, state-closed, state-paused, +merchandise-rep-unknown, merchandise-rep-ok, merchandise-rep-suspended, merchandise-rep-error, +transaction-rep-unknown, transaction-rep-ok, transaction-rep-suspended, transaction-rep-error'. + +=back + +=cut + diff --git a/centreon-plugins/apps/vmware/wsman/mode/components/cim_card.pm b/centreon-plugins/apps/vmware/wsman/mode/components/cim_card.pm index 825253e93..93c93557c 100644 --- a/centreon-plugins/apps/vmware/wsman/mode/components/cim_card.pm +++ b/centreon-plugins/apps/vmware/wsman/mode/components/cim_card.pm @@ -23,14 +23,16 @@ package apps::vmware::wsman::mode::components::cim_card; use strict; use warnings; +sub load {} + sub check { my ($self) = @_; - my $result = $self->{wsman}->request(uri => 'http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_Card'); + my $result = $self->{wsman}->request(uri => 'http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_Card', dont_quit => 1); $self->{output}->output_add(long_msg => "Checking cim cards"); $self->{components}->{cim_card} = {name => 'cards', total => 0, skip => 0}; - return if ($self->check_filter(section => 'cim_card')); + return if ($self->check_filter(section => 'cim_card') || !defined($result)); foreach (@{$result}) { my $instance = defined($_->{Name}) && $_->{Name} ne '' ? $_->{Name} : $_->{ElementName}; @@ -57,4 +59,4 @@ sub check { } } -1; \ No newline at end of file +1; diff --git a/centreon-plugins/apps/vmware/wsman/mode/components/cim_computersystem.pm b/centreon-plugins/apps/vmware/wsman/mode/components/cim_computersystem.pm index 242f5099b..75abc89fd 100644 --- a/centreon-plugins/apps/vmware/wsman/mode/components/cim_computersystem.pm +++ b/centreon-plugins/apps/vmware/wsman/mode/components/cim_computersystem.pm @@ -23,14 +23,16 @@ package apps::vmware::wsman::mode::components::cim_computersystem; use strict; use warnings; +sub load {} + sub check { my ($self) = @_; - my $result = $self->{wsman}->request(uri => 'http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_ComputerSystem'); + my $result = $self->{wsman}->request(uri => 'http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_ComputerSystem', dont_quit => 1); $self->{output}->output_add(long_msg => "Checking cim computer systems"); $self->{components}->{cim_computersystem} = {name => 'computer systems', total => 0, skip => 0}; - return if ($self->check_filter(section => 'cim_computersystem')); + return if ($self->check_filter(section => 'cim_computersystem') || !defined($result)); foreach (@{$result}) { my $instance = defined($_->{Name}) && $_->{Name} ne '' ? $_->{Name} : $_->{ElementName}; @@ -57,4 +59,4 @@ sub check { } } -1; \ No newline at end of file +1; diff --git a/centreon-plugins/apps/vmware/wsman/mode/components/cim_memory.pm b/centreon-plugins/apps/vmware/wsman/mode/components/cim_memory.pm index 7a062bff7..072d33637 100644 --- a/centreon-plugins/apps/vmware/wsman/mode/components/cim_memory.pm +++ b/centreon-plugins/apps/vmware/wsman/mode/components/cim_memory.pm @@ -23,14 +23,16 @@ package apps::vmware::wsman::mode::components::cim_memory; use strict; use warnings; +sub load {} + sub check { my ($self) = @_; - my $result = $self->{wsman}->request(uri => 'http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_Memory'); + my $result = $self->{wsman}->request(uri => 'http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_Memory', dont_quit => 1); $self->{output}->output_add(long_msg => "Checking cim memories"); $self->{components}->{cim_memory} = {name => 'memories', total => 0, skip => 0}; - return if ($self->check_filter(section => 'cim_memory')); + return if ($self->check_filter(section => 'cim_memory') || !defined($result)); foreach (@{$result}) { my $instance = defined($_->{Name}) && $_->{Name} ne '' ? $_->{Name} : $_->{ElementName}; @@ -57,4 +59,4 @@ sub check { } } -1; \ No newline at end of file +1; diff --git a/centreon-plugins/apps/vmware/wsman/mode/components/cim_numericsensor.pm b/centreon-plugins/apps/vmware/wsman/mode/components/cim_numericsensor.pm index 3f1254c10..a81655b1f 100644 --- a/centreon-plugins/apps/vmware/wsman/mode/components/cim_numericsensor.pm +++ b/centreon-plugins/apps/vmware/wsman/mode/components/cim_numericsensor.pm @@ -24,14 +24,16 @@ use strict; use warnings; use apps::vmware::wsman::mode::components::resources qw($mapping_units $mapping_sensortype); +sub load {} + sub check { my ($self) = @_; - my $result = $self->{wsman}->request(uri => 'http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_NumericSensor'); + my $result = $self->{wsman}->request(uri => 'http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_NumericSensor', dont_quit => 1); $self->{output}->output_add(long_msg => "Checking cim numeric sensors"); $self->{components}->{cim_numericsensor} = {name => 'numeric sensors', total => 0, skip => 0}; - return if ($self->check_filter(section => 'cim_numericsensor')); + return if ($self->check_filter(section => 'cim_numericsensor') || !defined($result)); foreach (@{$result}) { my $sensor_type = defined($mapping_sensortype->{$_->{SensorType}}) ? $mapping_sensortype->{$_->{SensorType}} : 'unknown'; @@ -108,4 +110,4 @@ sub check { } } -1; \ No newline at end of file +1; diff --git a/centreon-plugins/apps/vmware/wsman/mode/components/cim_processor.pm b/centreon-plugins/apps/vmware/wsman/mode/components/cim_processor.pm index 5d5833f87..990774d16 100644 --- a/centreon-plugins/apps/vmware/wsman/mode/components/cim_processor.pm +++ b/centreon-plugins/apps/vmware/wsman/mode/components/cim_processor.pm @@ -23,14 +23,16 @@ package apps::vmware::wsman::mode::components::cim_processor; use strict; use warnings; +sub load {} + sub check { my ($self) = @_; - my $result = $self->{wsman}->request(uri => 'http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_Processor'); + my $result = $self->{wsman}->request(uri => 'http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_Processor', dont_quit => 1); $self->{output}->output_add(long_msg => "Checking cim processors"); $self->{components}->{cim_processor} = {name => 'processors', total => 0, skip => 0}; - return if ($self->check_filter(section => 'cim_processor')); + return if ($self->check_filter(section => 'cim_processor') || !defined($result)); foreach (@{$result}) { my $instance = defined($_->{Name}) && $_->{Name} ne '' ? $_->{Name} : $_->{ElementName}; @@ -59,4 +61,4 @@ sub check { } } -1; \ No newline at end of file +1; diff --git a/centreon-plugins/apps/vmware/wsman/mode/components/cim_recordlog.pm b/centreon-plugins/apps/vmware/wsman/mode/components/cim_recordlog.pm index 820be9634..7c57647d8 100644 --- a/centreon-plugins/apps/vmware/wsman/mode/components/cim_recordlog.pm +++ b/centreon-plugins/apps/vmware/wsman/mode/components/cim_recordlog.pm @@ -23,14 +23,16 @@ package apps::vmware::wsman::mode::components::cim_recordlog; use strict; use warnings; +sub load {} + sub check { my ($self) = @_; - my $result = $self->{wsman}->request(uri => 'http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_RecordLog'); + my $result = $self->{wsman}->request(uri => 'http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_RecordLog', dont_quit => 1); $self->{output}->output_add(long_msg => "Checking cim recordlog"); $self->{components}->{cim_recordlog} = {name => 'recordlog', total => 0, skip => 0}; - return if ($self->check_filter(section => 'cim_recordlog')); + return if ($self->check_filter(section => 'cim_recordlog') || !defined($result)); foreach (@{$result}) { my $instance = defined($_->{Name}) && $_->{Name} ne '' ? $_->{Name} : $_->{ElementName}; @@ -57,4 +59,4 @@ sub check { } } -1; \ No newline at end of file +1; diff --git a/centreon-plugins/apps/vmware/wsman/mode/components/omc_discretesensor.pm b/centreon-plugins/apps/vmware/wsman/mode/components/omc_discretesensor.pm index ff6d3fa26..cafc5ff37 100644 --- a/centreon-plugins/apps/vmware/wsman/mode/components/omc_discretesensor.pm +++ b/centreon-plugins/apps/vmware/wsman/mode/components/omc_discretesensor.pm @@ -24,14 +24,16 @@ use strict; use warnings; use apps::vmware::wsman::mode::components::resources qw($mapping_EnableState); +sub load {} + sub check { my ($self) = @_; - my $result = $self->{wsman}->request(uri => 'http://schema.omc-project.org/wbem/wscim/1/cim-schema/2/OMC_DiscreteSensor'); + my $result = $self->{wsman}->request(uri => 'http://schema.omc-project.org/wbem/wscim/1/cim-schema/2/OMC_DiscreteSensor', dont_quit => 1); $self->{output}->output_add(long_msg => "Checking OMC discrete sensors"); $self->{components}->{omc_discretesensor} = {name => 'omc discrete sensors', total => 0, skip => 0}; - return if ($self->check_filter(section => 'omc_discretesensor')); + return if ($self->check_filter(section => 'omc_discretesensor') || !defined($result)); foreach (@{$result}) { my $instance = $_->{Name}; @@ -62,4 +64,4 @@ sub check { } } -1; \ No newline at end of file +1; diff --git a/centreon-plugins/apps/vmware/wsman/mode/components/omc_fan.pm b/centreon-plugins/apps/vmware/wsman/mode/components/omc_fan.pm index f0e8c929a..53e30c7e2 100644 --- a/centreon-plugins/apps/vmware/wsman/mode/components/omc_fan.pm +++ b/centreon-plugins/apps/vmware/wsman/mode/components/omc_fan.pm @@ -23,14 +23,16 @@ package apps::vmware::wsman::mode::components::omc_fan; use strict; use warnings; +sub load {} + sub check { my ($self) = @_; - my $result = $self->{wsman}->request(uri => 'http://schema.omc-project.org/wbem/wscim/1/cim-schema/2/OMC_Fan'); + my $result = $self->{wsman}->request(uri => 'http://schema.omc-project.org/wbem/wscim/1/cim-schema/2/OMC_Fan', dont_quit => 1); $self->{output}->output_add(long_msg => "Checking OMC fans"); $self->{components}->{omc_fan} = {name => 'omc fans', total => 0, skip => 0}; - return if ($self->check_filter(section => 'omc_fan')); + return if ($self->check_filter(section => 'omc_fan') || !defined($result)); foreach (@{$result}) { my $instance = $_->{Name}; @@ -57,4 +59,4 @@ sub check { } } -1; \ No newline at end of file +1; diff --git a/centreon-plugins/apps/vmware/wsman/mode/components/omc_psu.pm b/centreon-plugins/apps/vmware/wsman/mode/components/omc_psu.pm index 1fcd1a4f3..74f95893c 100644 --- a/centreon-plugins/apps/vmware/wsman/mode/components/omc_psu.pm +++ b/centreon-plugins/apps/vmware/wsman/mode/components/omc_psu.pm @@ -23,14 +23,16 @@ package apps::vmware::wsman::mode::components::omc_psu; use strict; use warnings; +sub load {} + sub check { my ($self) = @_; - my $result = $self->{wsman}->request(uri => 'http://schema.omc-project.org/wbem/wscim/1/cim-schema/2/OMC_PowerSupply'); + my $result = $self->{wsman}->request(uri => 'http://schema.omc-project.org/wbem/wscim/1/cim-schema/2/OMC_PowerSupply', dont_quit => 1); $self->{output}->output_add(long_msg => "Checking OMC power supplies"); $self->{components}->{omc_psu} = {name => 'omc psus', total => 0, skip => 0}; - return if ($self->check_filter(section => 'omc_psu')); + return if ($self->check_filter(section => 'omc_psu') || !defined($result)); foreach (@{$result}) { my $instance = $_->{Name}; @@ -57,4 +59,4 @@ sub check { } } -1; \ No newline at end of file +1; diff --git a/centreon-plugins/apps/vmware/wsman/mode/components/vmware_battery.pm b/centreon-plugins/apps/vmware/wsman/mode/components/vmware_battery.pm index 56943bdf5..3981080e3 100644 --- a/centreon-plugins/apps/vmware/wsman/mode/components/vmware_battery.pm +++ b/centreon-plugins/apps/vmware/wsman/mode/components/vmware_battery.pm @@ -23,14 +23,16 @@ package apps::vmware::wsman::mode::components::vmware_battery; use strict; use warnings; +sub load {} + sub check { my ($self) = @_; - my $result = $self->{wsman}->request(uri => 'http://schemas.vmware.com/wbem/wscim/1/cim-schema/2/VMware_Battery'); + my $result = $self->{wsman}->request(uri => 'http://schemas.vmware.com/wbem/wscim/1/cim-schema/2/VMware_Battery', dont_quit => 1); $self->{output}->output_add(long_msg => "Checking vmware batteries"); $self->{components}->{vmware_battery} = {name => 'batteries', total => 0, skip => 0}; - return if ($self->check_filter(section => 'vmware_battery')); + return if ($self->check_filter(section => 'vmware_battery') || !defined($result)); foreach (@{$result}) { my $instance = defined($_->{Name}) && $_->{Name} ne '' ? $_->{Name} : $_->{ElementName}; @@ -57,4 +59,4 @@ sub check { } } -1; \ No newline at end of file +1; diff --git a/centreon-plugins/apps/vmware/wsman/mode/components/vmware_controller.pm b/centreon-plugins/apps/vmware/wsman/mode/components/vmware_controller.pm index 9757a2f1f..09cf24fe6 100644 --- a/centreon-plugins/apps/vmware/wsman/mode/components/vmware_controller.pm +++ b/centreon-plugins/apps/vmware/wsman/mode/components/vmware_controller.pm @@ -23,14 +23,16 @@ package apps::vmware::wsman::mode::components::vmware_controller; use strict; use warnings; +sub load {} + sub check { my ($self) = @_; - my $result = $self->{wsman}->request(uri => 'http://schemas.vmware.com/wbem/wscim/1/cim-schema/2/VMware_Controller'); + my $result = $self->{wsman}->request(uri => 'http://schemas.vmware.com/wbem/wscim/1/cim-schema/2/VMware_Controller', dont_quit => 1); $self->{output}->output_add(long_msg => "Checking vmware controller"); $self->{components}->{vmware_controller} = {name => 'controller', total => 0, skip => 0}; - return if ($self->check_filter(section => 'vmware_controller')); + return if ($self->check_filter(section => 'vmware_controller') || !defined($result)); foreach (@{$result}) { my $instance = defined($_->{Name}) && $_->{Name} ne '' ? $_->{Name} : $_->{ElementName}; @@ -57,4 +59,4 @@ sub check { } } -1; \ No newline at end of file +1; diff --git a/centreon-plugins/apps/vmware/wsman/mode/components/vmware_sassataport.pm b/centreon-plugins/apps/vmware/wsman/mode/components/vmware_sassataport.pm index edb188cfd..99d89d6bd 100644 --- a/centreon-plugins/apps/vmware/wsman/mode/components/vmware_sassataport.pm +++ b/centreon-plugins/apps/vmware/wsman/mode/components/vmware_sassataport.pm @@ -23,14 +23,16 @@ package apps::vmware::wsman::mode::components::vmware_sassataport; use strict; use warnings; +sub load {} + sub check { my ($self) = @_; - my $result = $self->{wsman}->request(uri => 'http://schemas.vmware.com/wbem/wscim/1/cim-schema/2/VMware_SASSATAPort'); + my $result = $self->{wsman}->request(uri => 'http://schemas.vmware.com/wbem/wscim/1/cim-schema/2/VMware_SASSATAPort', dont_quit => 1); $self->{output}->output_add(long_msg => "Checking vmware sas/sata ports"); $self->{components}->{vmware_sassataport} = {name => 'sas/sata ports', total => 0, skip => 0}; - return if ($self->check_filter(section => 'vmware_sassataport')); + return if ($self->check_filter(section => 'vmware_sassataport') || !defined($result)); foreach (@{$result}) { my $instance = defined($_->{Name}) && $_->{Name} ne '' ? $_->{Name} : $_->{ElementName}; @@ -57,4 +59,4 @@ sub check { } } -1; \ No newline at end of file +1; diff --git a/centreon-plugins/apps/vmware/wsman/mode/components/vmware_storageextent.pm b/centreon-plugins/apps/vmware/wsman/mode/components/vmware_storageextent.pm index d13d25b70..200e1304d 100644 --- a/centreon-plugins/apps/vmware/wsman/mode/components/vmware_storageextent.pm +++ b/centreon-plugins/apps/vmware/wsman/mode/components/vmware_storageextent.pm @@ -23,14 +23,16 @@ package apps::vmware::wsman::mode::components::vmware_storageextent; use strict; use warnings; +sub load {} + sub check { my ($self) = @_; - my $result = $self->{wsman}->request(uri => 'http://schemas.vmware.com/wbem/wscim/1/cim-schema/2/VMware_StorageExtent'); + my $result = $self->{wsman}->request(uri => 'http://schemas.vmware.com/wbem/wscim/1/cim-schema/2/VMware_StorageExtent', dont_quit => 1); $self->{output}->output_add(long_msg => "Checking vmware storage extent"); $self->{components}->{vmware_storageextent} = {name => 'storage extent', total => 0, skip => 0}; - return if ($self->check_filter(section => 'vmware_storageextent')); + return if ($self->check_filter(section => 'vmware_storageextent') || !defined($result)); foreach (@{$result}) { my $instance = defined($_->{Name}) && $_->{Name} ne '' ? $_->{Name} : $_->{ElementName}; @@ -57,4 +59,4 @@ sub check { } } -1; \ No newline at end of file +1; diff --git a/centreon-plugins/apps/vmware/wsman/mode/components/vmware_storagevolume.pm b/centreon-plugins/apps/vmware/wsman/mode/components/vmware_storagevolume.pm index 9efd36696..fc504f09f 100644 --- a/centreon-plugins/apps/vmware/wsman/mode/components/vmware_storagevolume.pm +++ b/centreon-plugins/apps/vmware/wsman/mode/components/vmware_storagevolume.pm @@ -23,14 +23,16 @@ package apps::vmware::wsman::mode::components::vmware_storagevolume; use strict; use warnings; +sub load {} + sub check { my ($self) = @_; - my $result = $self->{wsman}->request(uri => 'http://schemas.vmware.com/wbem/wscim/1/cim-schema/2/VMware_StorageVolume'); + my $result = $self->{wsman}->request(uri => 'http://schemas.vmware.com/wbem/wscim/1/cim-schema/2/VMware_StorageVolume', dont_quit => 1); $self->{output}->output_add(long_msg => "Checking vmware storage volumes"); $self->{components}->{vmware_storagevolume} = {name => 'storage volumes', total => 0, skip => 0}; - return if ($self->check_filter(section => 'vmware_storagevolume')); + return if ($self->check_filter(section => 'vmware_storagevolume') || !defined($result)); foreach (@{$result}) { my $instance = defined($_->{Name}) && $_->{Name} ne '' ? $_->{Name} : $_->{ElementName}; @@ -57,4 +59,4 @@ sub check { } } -1; \ No newline at end of file +1; diff --git a/centreon-plugins/apps/vmware/wsman/mode/hardware.pm b/centreon-plugins/apps/vmware/wsman/mode/hardware.pm index 7aed1e56d..2cab3ff84 100644 --- a/centreon-plugins/apps/vmware/wsman/mode/hardware.pm +++ b/centreon-plugins/apps/vmware/wsman/mode/hardware.pm @@ -20,41 +20,54 @@ package apps::vmware::wsman::mode::hardware; -use base qw(centreon::plugins::mode); +use base qw(centreon::plugins::templates::hardware); use strict; use warnings; use apps::vmware::wsman::mode::components::resources qw($mapping_HealthState $mapping_OperationalStatus); -my %type = ('cim_numericsensor' => 1); - -my $thresholds = { - default => [ - ['Unknown', 'OK'], - ['OK', 'OK'], - ['Degraded', 'WARNING'], - ['Minor failure', 'WARNING'], - ['Major failure', 'CRITICAL'], - ['Critical failure', 'CRITICAL'], - ['Non-recoverable error', 'CRITICAL'], - - ['Other', 'UNKNOWN'], - ['Stressed', 'WARNING'], - ['Predictive Failure', 'WARNING'], - ['Error', 'CRITICAL'], - ['Starting', 'OK'], - ['Stopping', 'WARNING'], - ['In Service', 'OK'], - ['No Contact', 'CRITICAL'], - ['Lost Communication', 'CRITICAL'], - ['Aborted', 'CRITICAL'], - ['Dormant', 'OK'], - ['Supporting Entity in Error', 'CRITICAL'], - ['Completed', 'OK'], - ['Power Mode', 'OK'], - ['Relocating', 'WARNING'], - ], -}; +sub set_system { + my ($self, %options) = @_; + + $self->{regexp_threshold_overload_check_section_option} = + '^(omc_discretesensor|omc_fan|omc_psu|vmware_storageextent|vmware_controller|vmware_storagevolume|vmware_battery|vmware_sassataport|cim_card|cim_computersystem|cim_numericsensor|cim_memory|cim_processor|cim_recordlog)$'; + $self->{regexp_threshold_numeric_check_section_option} = '^(cim_numericsensor)$'; + + $self->{cb_hook1} = 'get_type'; + + $self->{thresholds} = { + default => [ + ['Unknown', 'OK'], + ['OK', 'OK'], + ['Degraded', 'WARNING'], + ['Minor failure', 'WARNING'], + ['Major failure', 'CRITICAL'], + ['Critical failure', 'CRITICAL'], + ['Non-recoverable error', 'CRITICAL'], + + ['Other', 'UNKNOWN'], + ['Stressed', 'WARNING'], + ['Predictive Failure', 'WARNING'], + ['Error', 'CRITICAL'], + ['Starting', 'OK'], + ['Stopping', 'WARNING'], + ['In Service', 'OK'], + ['No Contact', 'CRITICAL'], + ['Lost Communication', 'CRITICAL'], + ['Aborted', 'CRITICAL'], + ['Dormant', 'OK'], + ['Supporting Entity in Error', 'CRITICAL'], + ['Completed', 'OK'], + ['Power Mode', 'OK'], + ['Relocating', 'WARNING'], + ], + }; + + $self->{components_path} = 'apps::vmware::wsman::mode::components'; + $self->{components_module} = ['omc_discretesensor', 'omc_fan', 'omc_psu', 'vmware_storageextent', 'vmware_controller', + 'vmware_storagevolume', 'vmware_battery', 'vmware_sassataport', 'cim_card', + 'cim_computersystem', 'cim_numericsensor', 'cim_memory', 'cim_processor', 'cim_recordlog']; +} sub new { my ($class, %options) = @_; @@ -63,106 +76,29 @@ sub new { $self->{version} = '1.0'; $options{options}->add_options(arguments => - { - "filter:s@" => { name => 'filter' }, - "component:s" => { name => 'component', default => '.*' }, - "no-component:s" => { name => 'no_component' }, - "threshold-overload:s@" => { name => 'threshold_overload' }, - "warning:s@" => { name => 'warning' }, - "critical:s@" => { name => 'critical' }, + { }); - - $self->{components} = {}; - $self->{no_components} = undef; return $self; } -sub check_options { - my ($self, %options) = @_; - $self->SUPER::init(%options); - - if (defined($self->{option_results}->{no_component})) { - if ($self->{option_results}->{no_component} ne '') { - $self->{no_components} = $self->{option_results}->{no_component}; - } else { - $self->{no_components} = 'critical'; - } - } - - $self->{filter} = []; - foreach my $val (@{$self->{option_results}->{filter}}) { - next if (!defined($val) || $val eq ''); - my @values = split (/,/, $val); - push @{$self->{filter}}, { filter => $values[0], instance => $values[1] }; - } - - $self->{overload_th} = {}; - foreach my $val (@{$self->{option_results}->{threshold_overload}}) { - next if (!defined($val) || $val eq ''); - my @values = split (/,/, $val); - if (scalar(@values) < 3) { - $self->{output}->add_option_msg(short_msg => "Wrong threshold-overload option '" . $val . "'."); - $self->{output}->option_exit(); - } - my ($section, $instance, $status, $filter); - if (scalar(@values) == 3) { - ($section, $status, $filter) = @values; - $instance = '.*'; - } else { - ($section, $instance, $status, $filter) = @values; - } - if ($self->{output}->is_litteral_status(status => $status) == 0) { - $self->{output}->add_option_msg(short_msg => "Wrong threshold-overload status '" . $val . "'."); - $self->{output}->option_exit(); - } - $self->{overload_th}->{$section} = [] if (!defined($self->{overload_th}->{$section})); - push @{$self->{overload_th}->{$section}}, {filter => $filter, status => $status, instance => $instance }; - } - - $self->{numeric_threshold} = {}; - foreach my $option (('warning', 'critical')) { - foreach my $val (@{$self->{option_results}->{$option}}) { - next if (!defined($val) || $val eq ''); - if ($val !~ /^(.*?),(.*?),(.*)$/) { - $self->{output}->add_option_msg(short_msg => "Wrong $option option '" . $val . "'."); - $self->{output}->option_exit(); - } - my ($section, $instance, $value) = ($1, $2, $3); - if (!defined($type{$section})) { - $self->{output}->add_option_msg(short_msg => "Wrong $option option '" . $val . "'."); - $self->{output}->option_exit(); - } - my $position = 0; - if (defined($self->{numeric_threshold}->{$section})) { - $position = scalar(@{$self->{numeric_threshold}->{$section}}); - } - if (($self->{perfdata}->threshold_validate(label => $option . '-' . $section . '-' . $position, value => $value)) == 0) { - $self->{output}->add_option_msg(short_msg => "Wrong $option threshold '" . $value . "'."); - $self->{output}->option_exit(); - } - $self->{numeric_threshold}->{$section} = [] if (!defined($self->{numeric_threshold}->{$section})); - push @{$self->{numeric_threshold}->{$section}}, { label => $option . '-' . $section . '-' . $position, threshold => $option, instance => $instance }; - } - } -} - - sub get_type { my ($self, %options) = @_; - my $result = $self->{wsman}->request(uri => 'http://schema.omc-project.org/wbem/wscim/1/cim-schema/2/OMC_SMASHFirmwareIdentity'); - $result = pop(@$result); + my $result = $options{wsman}->request(uri => 'http://schema.omc-project.org/wbem/wscim/1/cim-schema/2/OMC_SMASHFirmwareIdentity', dont_quit => 1); + $result = pop(@$result) if (defined($result)); $self->{manufacturer} = 'unknown'; if (defined($result->{Manufacturer}) && $result->{Manufacturer} ne '') { $self->{manufacturer} = $result->{Manufacturer}; } - $result = $self->{wsman}->request(uri => 'http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_Chassis'); + $result = $options{wsman}->request(uri => 'http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_Chassis'); $result = pop(@$result); my $model = defined($result->{Model}) && $result->{Model} ne '' ? $result->{Model} : 'unknown'; $self->{output}->output_add(long_msg => sprintf("Manufacturer : %s, Model : %s", $self->{manufacturer}, $model)); + + $self->{wsman} = $options{wsman}; } sub get_status { @@ -179,115 +115,6 @@ sub get_status { return $status; } -sub run { - my ($self, %options) = @_; - $self->{wsman} = $options{wsman}; - - $self->get_type(); - - my @components = ('omc_discretesensor', 'omc_fan', 'omc_psu', 'vmware_storageextent', 'vmware_controller', - 'vmware_storagevolume', 'vmware_battery', 'vmware_sassataport', 'cim_card', - 'cim_computersystem', 'cim_numericsensor', 'cim_memory', 'cim_processor', 'cim_recordlog'); - foreach (@components) { - if (/$self->{option_results}->{component}/) { - my $mod_name = "apps::vmware::wsman::mode::components::$_"; - centreon::plugins::misc::mymodule_load(output => $self->{output}, module => $mod_name, - error_msg => "Cannot load module '$mod_name'."); - my $func = $mod_name->can('check'); - $func->($self); - } - } - - my $total_components = 0; - my $display_by_component = ''; - my $display_by_component_append = ''; - foreach my $comp (sort(keys %{$self->{components}})) { - # Skipping short msg when no components - next if ($self->{components}->{$comp}->{total} == 0 && $self->{components}->{$comp}->{skip} == 0); - $total_components += $self->{components}->{$comp}->{total} + $self->{components}->{$comp}->{skip}; - my $count_by_components = $self->{components}->{$comp}->{total} + $self->{components}->{$comp}->{skip}; - $display_by_component .= $display_by_component_append . $self->{components}->{$comp}->{total} . '/' . $count_by_components . ' ' . $self->{components}->{$comp}->{name}; - $display_by_component_append = ', '; - } - - $self->{output}->output_add(severity => 'OK', - short_msg => sprintf("All %s sensors are ok [%s].", - $total_components, - $display_by_component) - ); - - if (defined($self->{option_results}->{no_component}) && $total_components == 0) { - $self->{output}->output_add(severity => $self->{no_components}, - short_msg => 'No sensors are checked.'); - } - - $self->{output}->display(); - $self->{output}->exit(); -} - -sub check_filter { - my ($self, %options) = @_; - - foreach (@{$self->{filter}}) { - if ($options{section} =~ /$_->{filter}/) { - if (!defined($options{instance}) && !defined($_->{instance})) { - $self->{output}->output_add(long_msg => sprintf("Skipping $options{section} section.")); - return 1; - } elsif (defined($options{instance}) && $options{instance} =~ /$_->{instance}/) { - $self->{output}->output_add(long_msg => sprintf("Skipping $options{section} section $options{instance} instance.")); - return 1; - } - } - } - - return 0; -} - -sub get_severity_numeric { - my ($self, %options) = @_; - my $status = 'OK'; # default - my $thresholds = { warning => undef, critical => undef }; - my $checked = 0; - - if (defined($self->{numeric_threshold}->{$options{section}})) { - my $exits = []; - foreach (@{$self->{numeric_threshold}->{$options{section}}}) { - if ($options{instance} =~ /$_->{instance}/) { - push @{$exits}, $self->{perfdata}->threshold_check(value => $options{value}, threshold => [ { label => $_->{label}, exit_litteral => $_->{threshold} } ]); - $thresholds->{$_->{threshold}} = $self->{perfdata}->get_perfdata_for_output(label => $_->{label}); - $checked = 1; - } - } - $status = $self->{output}->get_most_critical(status => $exits) if (scalar(@{$exits}) > 0); - } - - return ($status, $thresholds->{warning}, $thresholds->{critical}, $checked); -} - -sub get_severity { - my ($self, %options) = @_; - my $status = 'UNKNOWN'; # default - - if (defined($self->{overload_th}->{$options{section}})) { - foreach (@{$self->{overload_th}->{$options{section}}}) { - if ($options{value} =~ /$_->{filter}/i && - (!defined($options{instance}) || $options{instance} =~ /$_->{instance}/)) { - $status = $_->{status}; - return $status; - } - } - } - my $label = defined($options{label}) ? $options{label} : $options{section}; - foreach (@{$thresholds->{$label}}) { - if ($options{value} =~ /$$_[0]/i) { - $status = $$_[1]; - return $status; - } - } - - return $status; -} - 1; __END__ @@ -335,4 +162,4 @@ Example: --critical='cim_numericsensor,.*,40' =back -=cut \ No newline at end of file +=cut diff --git a/centreon-plugins/centreon/common/cisco/standard/snmp/mode/ipsla.pm b/centreon-plugins/centreon/common/cisco/standard/snmp/mode/ipsla.pm index acdf53d5f..462bc97ee 100644 --- a/centreon-plugins/centreon/common/cisco/standard/snmp/mode/ipsla.pm +++ b/centreon-plugins/centreon/common/cisco/standard/snmp/mode/ipsla.pm @@ -32,7 +32,7 @@ sub set_counters { $self->{maps_counters_type} = [ { name => 'tag', type => 1, cb_prefix_output => 'prefix_tag_output', message_multiple => 'All RTT controls are ok', - skipped_code => { -2 => 1 } } + skipped_code => { -2 => 1, -3 => 1, -10 => 1 } } ]; $self->{maps_counters}->{tag} = [ { label => 'status', threshold => 0, set => { @@ -955,4 +955,4 @@ Can be: 'CompletionTime', 'NumberOverThresholds', 'AverageDelaySD', 'AverageDela =back =cut - \ No newline at end of file + 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/memorydetailed.pm b/centreon-plugins/centreon/common/jvm/mode/memorydetailed.pm index 162a19524..c9817e8e4 100644 --- a/centreon-plugins/centreon/common/jvm/mode/memorydetailed.pm +++ b/centreon-plugins/centreon/common/jvm/mode/memorydetailed.pm @@ -20,7 +20,7 @@ package centreon::common::jvm::mode::memorydetailed; -use base qw(centreon::plugins::mode); +use base qw(centreon::plugins::templates::counter); use strict; use warnings; @@ -42,6 +42,133 @@ my %mapping_memory = ( 'Tenured Gen' => 'tenured', ); +my $instance_mode; + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'mem', type => 1, cb_prefix_output => 'prefix_mem_output', message_multiple => 'All memories within bounds', skipped_code => { -12 => 1 } }, + ]; + + $self->{maps_counters}->{mem} = [ + { label => 'eden', set => { + key_values => [ { name => 'used' }, { name => 'max' }, { name => 'display' } ], + closure_custom_calc => $self->can('custom_usage_calc'), + 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 => 'tenured', set => { + key_values => [ { name => 'used' }, { name => 'max' }, { name => 'display' } ], + closure_custom_calc => $self->can('custom_usage_calc'), + 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 => 'survivor', set => { + key_values => [ { name => 'used' }, { name => 'max' }, { name => 'display' } ], + closure_custom_calc => $self->can('custom_usage_calc'), + 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 => 'permanent', set => { + key_values => [ { name => 'used' }, { name => 'max' }, { name => 'display' } ], + closure_custom_calc => $self->can('custom_usage_calc'), + 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 => 'code', set => { + key_values => [ { name => 'used' }, { name => 'max' }, { name => 'display' } ], + closure_custom_calc => $self->can('custom_usage_calc'), + 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 $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; + } + + $self->{output}->perfdata_add(label => $self->{label}, unit => 'B', + 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; + my ($total_used_value, $total_used_unit) = $self->{perfdata}->change_bytes(value => $self->{result_values}->{used}); + if ($self->{result_values}->{max} > 0) { + my ($total_size_value, $total_size_unit) = $self->{perfdata}->change_bytes(value => $self->{result_values}->{max}); + my ($total_free_value, $total_free_unit) = $self->{perfdata}->change_bytes(value => $self->{result_values}->{max} - $self->{result_values}->{used}); + $msg = sprintf("Total: %s Used: %s (%.2f%%) Free: %s (%.2f%%)", + $total_size_value . " " . $total_size_unit, + $total_used_value . " " . $total_used_unit, $self->{result_values}->{prct_used}, + $total_free_value . " " . $total_free_unit, 100 - $self->{result_values}->{prct_used}); + } else { + $msg = sprintf("Used: %s", $total_used_value . " " . $total_used_unit); + } + return $msg; +} + +sub custom_usage_calc { + my ($self, %options) = @_; + + if ($mapping_memory{$options{new_datas}->{$self->{instance} . '_display'}} ne $self->{label}) { + return -12; + } + $self->{result_values}->{display} = $options{new_datas}->{$self->{instance} . '_display'}; + $self->{result_values}->{max} = $options{new_datas}->{$self->{instance} . '_max'}; + $self->{result_values}->{used} = $options{new_datas}->{$self->{instance} . '_used'}; + if ($self->{result_values}->{max} > 0) { + $self->{result_values}->{prct_used} = $self->{result_values}->{used} * 100 / $self->{result_values}->{max}; + } + + return 0; +} + +sub prefix_mem_output { + my ($self, %options) = @_; + + return "Memory '" . $options{instance_value}->{display} . "' "; +} + sub new { my ($class, %options) = @_; my $self = $class->SUPER::new(package => __PACKAGE__, %options); @@ -49,48 +176,29 @@ sub new { $self->{version} = '1.0'; $options{options}->add_options(arguments => - { - "warning-eden:s" => { name => 'warning_eden' }, - "critical-eden:s" => { name => 'critical_eden' }, - "warning-survivor:s" => { name => 'warning_survivor' }, - "critical-survivor:s" => { name => 'critical_survivor' }, - "warning-tenured:s" => { name => 'warning_tenured' }, - "critical-tenured:s" => { name => 'critical_tenured' }, - "warning-permanent:s" => { name => 'warning_permanent' }, - "critical-permanent:s" => { name => 'critical_permanent' }, - "warning-code:s" => { name => 'warning_code' }, - "critical-code:s" => { name => 'critical_code' } + { + "units:s" => { name => 'units', default => '%' }, }); return $self; } sub check_options { my ($self, %options) = @_; - $self->SUPER::init(%options); - - foreach my $label ('warning_eden', 'critical_eden', 'warning_survivor', 'critical_survivor', 'warning_tenured', 'critical_tenured', 'warning_permanent', 'critical_permanent', 'warning_code', 'critical_code') { - if (($self->{perfdata}->threshold_validate(label => $label, value => $self->{option_results}->{$label})) == 0) { - my ($label_opt) = $label; - $label_opt =~ tr/_/-/; - $self->{output}->add_option_msg(short_msg => "Wrong " . $label_opt . " threshold '" . $self->{option_results}->{$label} . "'."); - $self->{output}->option_exit(); - } - } + $self->SUPER::check_options(%options); + + $instance_mode = $self; } -sub run { +sub manage_selection { my ($self, %options) = @_; - $self->{connector} = $options{custom}; $self->{request} = [ { mbean => "java.lang:type=MemoryPool,name=*", attributes => [ { name => 'Usage' } ] } ]; - my $result = $self->{connector}->get_attributes(request => $self->{request}, nothing_quit => 1); - - $self->{output}->output_add(severity => 'OK', - short_msg => 'All memories within bounds'); + my $result = $options{custom}->get_attributes(request => $self->{request}, nothing_quit => 1); + $self->{mem} = {}; foreach my $key (keys %$result) { $key =~ /name=(.*?),type/; my $memtype = $1; @@ -100,29 +208,12 @@ sub run { next; } - my $prct = $result->{"java.lang:name=".$memtype.",type=MemoryPool"}->{Usage}->{used} / $result->{"java.lang:name=".$memtype.",type=MemoryPool"}->{Usage}->{max} * 100; - - $self->{output}->perfdata_add(label => $mapping_memory{$memtype}, unit => 'B', - value => $result->{"java.lang:name=" . $memtype . ",type=MemoryPool"}->{Usage}->{used}, - warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $mapping_memory{$memtype}, total => $result->{"java.lang:name=" . $memtype . ",type=MemoryPool"}->{Usage}->{used}, cast_int => 1), - warning => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $mapping_memory{$memtype}, total => $result->{"java.lang:name=" . $memtype . ",type=MemoryPool"}->{Usage}->{used}, cast_int => 1), - min => 0, max => $result->{"java.lang:name=".$memtype.",type=MemoryPool"}->{Usage}->{max}); - - my $exit = $self->{perfdata}->threshold_check(value => $prct, - threshold => [ { label => 'critical_' . $mapping_memory{$memtype}, exit_litteral => 'critical' }, - { label => 'warning_' . $mapping_memory{$memtype}, exit_litteral => 'warning' } ]); - - $self->{output}->output_add(long_msg => sprintf("%s usage %.2f%%", $memtype, $prct)); - if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { - $self->{output}->output_add(severity => $exit, - short_msg => sprintf("%s usage %.2f%% ", $memtype, $prct)); - } - + $self->{mem}->{$memtype} = { + display => $memtype, + used => $result->{"java.lang:name=" . $memtype . ",type=MemoryPool"}->{Usage}->{used}, + max => $result->{"java.lang:name=".$memtype.",type=MemoryPool"}->{Usage}->{max}, + }; } - - $self->{output}->display(); - $self->{output}->exit(); - } 1; @@ -184,6 +275,10 @@ Threshold warning of NonHeap 'Code Cache' memory usage Threshold critical of NonHeap 'Code Cache' memory usage +=item B<--units> + +Units of thresholds (Default: '%') ('%', 'B'). + =back =cut diff --git a/centreon-plugins/centreon/common/powershell/windows/pendingreboot.pm b/centreon-plugins/centreon/common/powershell/windows/pendingreboot.pm new file mode 100644 index 000000000..64e2c2488 --- /dev/null +++ b/centreon-plugins/centreon/common/powershell/windows/pendingreboot.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 centreon::common::powershell::windows::pendingreboot; + +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 +$ProgressPreference = "SilentlyContinue" + +Try { + $ErrorActionPreference = "Stop" + + $ComputerName = "$env:COMPUTERNAME" + $CompPendRen,$PendFileRename,$Pending,$SCCM = $false,$false,$false,$false + + ## Setting CBSRebootPend to null since not all versions of Windows has this value + $CBSRebootPend = $null + + ## Querying WMI for build version + $WMI_OS = Get-WmiObject -Class Win32_OperatingSystem -Property BuildNumber, CSName -ComputerName $ComputerName -ErrorAction Stop + + ## Making registry connection to the local/remote computer + $HKLM = [UInt32] "0x80000002" + $WMI_Reg = [WMIClass] "\\\\$ComputerName\\root\\default:StdRegProv" + + ## If Vista/2008 & Above query the CBS Reg Key + If ([Int32]$WMI_OS.BuildNumber -ge 6001) { + $RegSubKeysCBS = $WMI_Reg.EnumKey($HKLM,"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Component Based Servicing\\") + $CBSRebootPend = $RegSubKeysCBS.sNames -contains "RebootPending" + } + + ## Query WUAU from the registry + $RegWUAURebootReq = $WMI_Reg.EnumKey($HKLM,"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\WindowsUpdate\\Auto Update\\") + $WUAURebootReq = $RegWUAURebootReq.sNames -contains "RebootRequired" + + ## Query PendingFileRenameOperations from the registry + $RegSubKeySM = $WMI_Reg.GetMultiStringValue($HKLM,"SYSTEM\\CurrentControlSet\\Control\\Session Manager\\","PendingFileRenameOperations") + $RegValuePFRO = $RegSubKeySM.sValue + + ## Query ComputerName and ActiveComputerName from the registry + $ActCompNm = $WMI_Reg.GetStringValue($HKLM,"SYSTEM\\CurrentControlSet\\Control\\ComputerName\\ActiveComputerName\\","ComputerName") + $CompNm = $WMI_Reg.GetStringValue($HKLM,"SYSTEM\\CurrentControlSet\\Control\\ComputerName\\ComputerName\\","ComputerName") + If ($ActCompNm -ne $CompNm) { + $CompPendRen = $true + } + + ## If PendingFileRenameOperations has a value set $RegValuePFRO variable to $true + If ($RegValuePFRO) { + $PendFileRename = $true + } + + ## Determine SCCM 2012 Client Reboot Pending Status + ## To avoid nested "if" statements and unneeded WMI calls to determine if the CCM_ClientUtilities class exist, setting EA = 0 + $CCMClientSDK = $null + $CCMSplat = @{ + NameSpace="ROOT\\ccm\\ClientSDK" + Class="CCM_ClientUtilities" + Name="DetermineIfRebootPending" + ComputerName=$ComputerName + ErrorAction="Stop" + } + ## Try CCMClientSDK + Try { + $CCMClientSDK = Invoke-WmiMethod @CCMSplat + } Catch [System.UnauthorizedAccessException] { + $CcmStatus = Get-Service -Name CcmExec -ComputerName $ComputerName -ErrorAction SilentlyContinue + If ($CcmStatus.Status -ne "Running") { + Write-Warning "$ComputerName`: Error - CcmExec service is not running." + $CCMClientSDK = $null + } + } Catch { + $CCMClientSDK = $null + } + + If ($CCMClientSDK) { + If ($CCMClientSDK.ReturnValue -ne 0) { + Write-Warning "Error: DetermineIfRebootPending returned error code $($CCMClientSDK.ReturnValue)" + } + If ($CCMClientSDK.IsHardRebootPending -or $CCMClientSDK.RebootPending) { + $SCCM = $true + } + } Else { + $SCCM = $null + } + + Write-Host ("[CBServicing={0}]" -f $CBSRebootPend ) -NoNewline + Write-Host ("[WindowsUpdate={0}]" -f $WUAURebootReq ) -NoNewline + Write-Host ("[CCMClientSDK={0}]" -f $SCCM ) -NoNewline + Write-Host ("[PendComputerRename={0}]" -f $CompPendRen ) -NoNewline + Write-Host ("[PendFileRename={0}]" -f $PendFileRename ) -NoNewline + Write-Host ("[PendFileRenVal={0}]" -f $RegValuePFRO ) -NoNewline + Write-Host ("[RebootPending={0}]" -f ($CompPendRen -or $CBSRebootPend -or $WUAURebootReq -or $SCCM -or $PendFileRename) ) +} Catch { + Write-Host $Error[0].Exception + exit 1 +} + +exit 0 +'; + + return centreon::plugins::misc::powershell_encoded($ps); +} + +1; + +__END__ + +=head1 DESCRIPTION + +Method to get pending reboot informations. + +=cut + diff --git a/centreon-plugins/centreon/common/protocols/jmx/custom/jolokia.pm b/centreon-plugins/centreon/common/protocols/jmx/custom/jolokia.pm index d2dfaca51..fb1f83915 100644 --- a/centreon-plugins/centreon/common/protocols/jmx/custom/jolokia.pm +++ b/centreon-plugins/centreon/common/protocols/jmx/custom/jolokia.pm @@ -292,7 +292,8 @@ sub list_attributes { $v =~ s/^\s*//; print " = " . $v; } else { - if (my $scal = JMX::Jmx4Perl::Util->dump_scalar($val)) { + my $scal = JMX::Jmx4Perl::Util->dump_scalar($val); + if (defined($scal)) { print " = " . $scal . "\n"; } else { print " = undef\n"; @@ -367,4 +368,4 @@ Credentials to use for the target B. -=cut \ No newline at end of file +=cut diff --git a/centreon-plugins/centreon/common/protocols/ssh/custom/api.pm b/centreon-plugins/centreon/common/protocols/ssh/custom/api.pm new file mode 100644 index 000000000..6e323c3b9 --- /dev/null +++ b/centreon-plugins/centreon/common/protocols/ssh/custom/api.pm @@ -0,0 +1,201 @@ +# +# 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::ssh::custom::api; + +use strict; +use warnings; +use Libssh::Session qw(:all); + +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' }, + "timeout:s@" => { name => 'timeout' }, + "ssh-username:s@" => { name => 'ssh_username' }, + "ssh-password:s@" => { name => 'ssh_password' }, + "ssh-dir:s@" => { name => 'ssh_dir' }, + "ssh-identity:s@" => { name => 'ssh_identity' }, + "ssh-skip-serverkey-issue" => { name => 'ssh_skip_serverkey_issue' }, + }); + } + $options{options}->add_help(package => __PACKAGE__, sections => 'SSH OPTIONS', once => 1); + + $self->{output} = $options{output}; + $self->{mode} = $options{mode}; + + $self->{ssh} = 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}}) : undef; + $self->{port} = (defined($self->{option_results}->{port})) ? shift(@{$self->{option_results}->{port}}) : 22; + $self->{timeout} = (defined($self->{option_results}->{timeout})) ? shift(@{$self->{option_results}->{timeout}}) : 10; + $self->{ssh_username} = (defined($self->{option_results}->{ssh_username})) ? shift(@{$self->{option_results}->{ssh_username}}) : undef; + $self->{ssh_password} = (defined($self->{option_results}->{ssh_password})) ? shift(@{$self->{option_results}->{ssh_password}}) : undef; + $self->{ssh_dir} = (defined($self->{option_results}->{ssh_dir})) ? shift(@{$self->{option_results}->{ssh_dir}}) : undef; + $self->{ssh_identity} = (defined($self->{option_results}->{ssh_identity})) ? shift(@{$self->{option_results}->{ssh_identity}}) : undef; + $self->{ssh_skip_serverkey_issue} = defined($self->{option_results}->{ssh_skip_serverkey_issue}) ? 1 : 0; + + if (!defined($self->{hostname}) || $self->{hostname} eq '') { + $self->{output}->add_option_msg(short_msg => "Please set option --hostname."); + $self->{output}->option_exit(); + } + + if (!defined($self->{hostname}) || + scalar(@{$self->{option_results}->{hostname}}) == 0) { + return 0; + } + return 1; +} + +sub login { + my ($self, %options) = @_; + + my $result = { status => 0, message => 'authentification succeeded' }; + $self->{ssh} = Libssh::Session->new(); + + foreach (['hostname', 'host'], ['port', 'port'], ['timeout', 'timeout'], ['ssh_username', 'user'], + ['ssh_dir', 'sshdir'], ['ssh_identity', 'identity']) { + next if (!defined($self->{$_->[0]}) || $self->{$_->[0]} eq ''); + + if ($self->{ssh}->options($_->[1] => $self->{$_->[0]}) != SSH_OK) { + $result->{message} = $self->{ssh}->error(); + $result->{status} = 1; + return $result; + } + } + + if ($self->{ssh}->connect(SkipKeyProblem => $self->{ssh_skip_serverkey_issue}) != SSH_OK) { + $result->{message} = $self->{ssh}->error(); + $result->{status} = 1; + return $result; + } + + if ($self->{ssh}->auth_publickey_auto() != SSH_AUTH_SUCCESS) { + if (defined($self->{ssh_username}) && $self->{ssh_username} ne '' && + defined($self->{ssh_password}) && $self->{ssh_password} ne '' && + $self->{ssh}->auth_password(password => $self->{ssh_password}) == SSH_AUTH_SUCCESS) { + return $result; + } + + my $msg_error = $self->{ssh}->error(GetErrorSession => 1); + $result->{message} = sprintf("auth issue: %s", defined($msg_error) && $msg_error ne '' ? $msg_error : 'pubkey issue'); + $result->{status} = 1; + } + + return $result; +} + +1; + +__END__ + +=head1 NAME + +SSH connector library + +=head1 SYNOPSIS + +my ssh connector + +=head1 SSH OPTIONS + +=over 8 + +=item B<--hostname> + +SSH server hostname (required). + +=item B<--port> + +SSH port. + +=item B<--timeout> + +Timeout in seconds for connection (Defaults: 10 seconds) + +=item B<--ssh-username> + +SSH username. + +=item B<--ssh-password> + +SSH password. + +=item B<--ssh-dir> + +Set the ssh directory. + +=item B<--ssh-identity> + +Set the identity file name (default: id_dsa and id_rsa are checked). + +=item B<--ssh-skip-serverkey-issue> + +Connection will be OK even if there is a problem (server known changed or server found other) with the ssh server. + +=back + +=head1 DESCRIPTION + +B. + +=cut diff --git a/centreon-plugins/centreon/plugins/misc.pm b/centreon-plugins/centreon/plugins/misc.pm index 6c1fb6525..f13b2d987 100644 --- a/centreon-plugins/centreon/plugins/misc.pm +++ b/centreon-plugins/centreon/plugins/misc.pm @@ -393,7 +393,7 @@ sub convert_bytes { my (%options) = @_; my %expo = (k => 1, m => 2, g => 3, t => 4); my $value = $options{value}; - my $base = defined($options{network}) ? 1000 : 1020; + my $base = defined($options{network}) ? 1000 : 1024; if ($options{unit} =~ /([kmgt])b/i) { $value = $value * ($base ** $expo{lc($1)}); diff --git a/centreon-plugins/centreon/plugins/script.pm b/centreon-plugins/centreon/plugins/script.pm index dbcfd9359..f652738d0 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 = 20170613; +my $global_version = 20171013; my $alternative_fatpacker = 0; sub new { diff --git a/centreon-plugins/centreon/plugins/script_simple.pm b/centreon-plugins/centreon/plugins/script_simple.pm index c9332b65d..c5945e064 100644 --- a/centreon-plugins/centreon/plugins/script_simple.pm +++ b/centreon-plugins/centreon/plugins/script_simple.pm @@ -64,11 +64,11 @@ sub init { # $options{version} = string version # $options{help} = string help - if (defined($options{help}) && !defined($self->{mode_name})) { + if (defined($options{help}) && !defined($self->{mode_name}) && !defined($self->{dynmode_name})) { $self->{options}->display_help(); $self->{output}->option_exit(); } - if (defined($options{version}) && !defined($self->{mode_name})) { + if (defined($options{version}) && !defined($self->{mode_name}) && !defined($self->{dynmode_name})) { $self->version(); } if (defined($self->{list_mode})) { diff --git a/centreon-plugins/centreon/plugins/script_snmp.pm b/centreon-plugins/centreon/plugins/script_snmp.pm index 1cfd11be8..19debc914 100644 --- a/centreon-plugins/centreon/plugins/script_snmp.pm +++ b/centreon-plugins/centreon/plugins/script_snmp.pm @@ -66,11 +66,11 @@ sub init { # $options{version} = string version # $options{help} = string help - if (defined($options{help}) && !defined($self->{mode_name})) { + if (defined($options{help}) && !defined($self->{mode_name}) && !defined($self->{dynmode_name})) { $self->{options}->display_help(); $self->{output}->option_exit(); } - if (defined($options{version}) && !defined($self->{mode_name})) { + if (defined($options{version}) && !defined($self->{mode_name}) && !defined($self->{dynmode_name})) { $self->version(); } if (defined($self->{list_mode})) { diff --git a/centreon-plugins/centreon/plugins/script_wsman.pm b/centreon-plugins/centreon/plugins/script_wsman.pm index 22daecde4..630d020a3 100644 --- a/centreon-plugins/centreon/plugins/script_wsman.pm +++ b/centreon-plugins/centreon/plugins/script_wsman.pm @@ -66,11 +66,11 @@ sub init { # $options{version} = string version # $options{help} = string help - if (defined($options{help}) && !defined($self->{mode_name})) { + if (defined($options{help}) && !defined($self->{mode_name}) && !defined($self->{dynmode_name})) { $self->{options}->display_help(); $self->{output}->option_exit(); } - if (defined($options{version}) && !defined($self->{mode_name})) { + if (defined($options{version}) && !defined($self->{mode_name}) && !defined($self->{dynmode_name})) { $self->version(); } if (defined($self->{list_mode})) { 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/templates/counter.pm b/centreon-plugins/centreon/plugins/templates/counter.pm index fb6454bd5..798320b1c 100644 --- a/centreon-plugins/centreon/plugins/templates/counter.pm +++ b/centreon-plugins/centreon/plugins/templates/counter.pm @@ -263,7 +263,10 @@ sub run_instances { $suffix_output = '' if (!defined($suffix_output)); my $exit = $self->{output}->get_most_critical(status => [ @exits ]); - $self->{output}->output_add(long_msg => ($display_status_lo == 1 ? lc($exit) . ': ' : '') . "${prefix_output}${long_msg}${suffix_output}"); + # in mode grouped, we don't display 'ok' + my $debug = 0; + $debug = 1 if ($display_status_lo == 1 && $self->{output}->is_status(value => $exit, compare => 'OK', litteral => 1)); + $self->{output}->output_add(long_msg => ($display_status_lo == 1 ? lc($exit) . ': ' : '') . "${prefix_output}${long_msg}${suffix_output}", debug => $debug); if ($resume == 1) { $self->{most_critical_instance} = $self->{output}->get_most_critical(status => [ $self->{most_critical_instance}, $exit ]); next; @@ -403,4 +406,4 @@ Can be: 'xxx', 'xxx'. =back -=cut \ No newline at end of file +=cut diff --git a/centreon-plugins/centreon/plugins/values.pm b/centreon-plugins/centreon/plugins/values.pm index 3d849602b..957650c3c 100644 --- a/centreon-plugins/centreon/plugins/values.pm +++ b/centreon-plugins/centreon/plugins/values.pm @@ -139,8 +139,8 @@ sub output { if (defined($self->{closure_custom_output})) { return $self->{closure_custom_output}->($self); } - my $first = ${${$self->{key_values}}[0]}{name}; - my ($value, $unit) = ($self->{result_values}->{$first . '_absolute'}, $self->{output_absolute_unit}); + my $first = $self->{key_values}->[0]->{name}; + my ($value, $unit) = (defined($first) ? $self->{result_values}->{$first . '_absolute'} : '', $self->{output_absolute_unit}); if (!defined($self->{output_use})) { if ($self->{per_second} == 1) { diff --git a/centreon-plugins/changelog b/centreon-plugins/changelog index 9e934ce42..d3f82b033 100644 --- a/centreon-plugins/changelog +++ b/centreon-plugins/changelog @@ -1,6 +1,39 @@ -2017-07-XX Quentin Garnier +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 + * Plugin added: Automic Workload Automation JMX + * Plugin added: Fujitsu Server SNMP + * Plugin added: Foxbox Notification + * Break: Netasq renamed to Stormshield + +2017-08-11 Quentin Garnier + * Plugin added: Ruckus AP SNMP + * Plugin added: Adva FSP3000 SNMP + * Plugin added: Nokia Timos SNMP + * Plugin added: Huawei SNMP + * Plugin added: Hibernate JMX + * Plugin added: Raisecom SNMP + * Break: mode change for Pfsense SNMP + * Break: mode change for HP MSL SNMP + * Break: mode change for Juniper ISG SNMP + * Break: mode change for Digi Standard (sarian now) SNMP + +2017-07-13 Quentin Garnier * Plugin added: Supermicro SNMP * Plugin added: QuadStor VTL Local + * Plugin added: Docker Rest API + * Mode added: [linux] directlvm-usage + * Mode added: [oracle] rollback-segment-usage + * Mode added: [oracle] event-waits-usage 2017-06-13 Quentin Garnier * Plugin added: HP Eva CLI diff --git a/centreon-plugins/cloud/docker/restapi/custom/api.pm b/centreon-plugins/cloud/docker/restapi/custom/api.pm index 13d4ba939..a84867136 100644 --- a/centreon-plugins/cloud/docker/restapi/custom/api.pm +++ b/centreon-plugins/cloud/docker/restapi/custom/api.pm @@ -171,6 +171,18 @@ sub api_read_file { return $content; } +sub get_hostnames { + my ($self, %options) = @_; + + return $self->{hostname}; +} + +sub get_port { + my ($self, %options) = @_; + + return $self->{option_results}->{port}; +} + sub cache_containers { my ($self, %options) = @_; @@ -197,6 +209,46 @@ sub cache_containers { return $containers; } +sub internal_api_list_nodes { + my ($self, %options) = @_; + + my $response = $self->{http}->{$options{node_name}}->request( + url_path => '/nodes', + unknown_status => '', critical_status => '', warning_status => ''); + my $nodes; + eval { + $nodes = JSON::XS->new->utf8->decode($response); + }; + if ($@) { + $nodes = []; + $self->{output}->output_add(severity => 'UNKNOWN', + short_msg => "Node '$options{node_name}': cannot decode json list nodes response: $@"); + } else { + $nodes = [] if (ref($nodes) eq 'HASH'); # nodes is not in a swarm + } + + return $nodes; +} + +sub internal_api_info { + my ($self, %options) = @_; + + my $response = $self->{http}->{$options{node_name}}->request( + url_path => '/info', + unknown_status => '', critical_status => '', warning_status => ''); + my $nodes; + eval { + $nodes = JSON::XS->new->utf8->decode($response); + }; + if ($@) { + $nodes = []; + $self->{output}->output_add(severity => 'UNKNOWN', + short_msg => "Node '$options{node_name}': cannot decode json info response: $@"); + } + + return $nodes; +} + sub internal_api_list_containers { my ($self, %options) = @_; @@ -235,6 +287,44 @@ sub internal_api_get_container_stats { return $container_stats; } +sub api_list_containers { + my ($self, %options) = @_; + + my $containers = {}; + foreach my $node_name (keys %{$self->{http}}) { + my $list_containers = $self->internal_api_list_containers(node_name => $node_name); + foreach my $container (@$list_containers) { + $containers->{$container->{Id}} = { + State => $container->{State}, + NodeName => $node_name, + Name => join(':', @{$container->{Names}}), + }; + } + } + + return $containers; +} + +sub api_list_nodes { + my ($self, %options) = @_; + + my $nodes = {}; + foreach my $node_name (keys %{$self->{http}}) { + my $info_node = $self->internal_api_info(node_name => $node_name); + my $list_nodes = $self->internal_api_list_nodes(node_name => $node_name); + $nodes->{$node_name} = { nodes => [], + containers_running => $info_node->{ContainersRunning}, + containers_stopped => $info_node->{ContainersStopped}, + containers_paused => $info_node->{ContainersPaused}, + }; + foreach my $node (@$list_nodes) { + push @{$nodes->{$node_name}->{nodes}}, { Status => $node->{Status}->{State}, ManagerStatus => $node->{ManagerStatus}->{Reachability}, Addr => $node->{Status}->{Addr} }; + } + } + + return $nodes; +} + sub api_get_containers { my ($self, %options) = @_; @@ -243,8 +333,23 @@ sub api_get_containers { } my $content_total = $self->cache_containers(statefile => $options{statefile}); - if (defined($options{container_id}) && $options{container_id} ne '' && defined($content_total->{$options{container_id}})) { - $content_total->{$options{container_id}}->{Stats} = $self->internal_api_get_container_stats(node_name => $content_total->{$options{container_id}}->{NodeName}, container_id => $options{container_id}); + if (defined($options{container_id}) && $options{container_id} ne '') { + if (defined($content_total->{$options{container_id}})) { + $content_total->{$options{container_id}}->{Stats} = $self->internal_api_get_container_stats(node_name => $content_total->{$options{container_id}}->{NodeName}, container_id => $options{container_id}); + } + } elsif (defined($options{container_name}) && $options{container_name} ne '') { + my $container_id; + + foreach (keys %$content_total) { + if ($content_total->{$_}->{Name} eq $options{container_name}) { + $container_id = $_; + last; + } + } + + if (defined($container_id)) { + $content_total->{$container_id}->{Stats} = $self->internal_api_get_container_stats(node_name => $content_total->{$container_id}->{NodeName}, container_id => $container_id); + } } else { foreach my $container_id (keys %{$content_total}) { $content_total->{$container_id}->{Stats} = $self->internal_api_get_container_stats(node_name => $content_total->{$container_id}->{NodeName}, container_id => $container_id); diff --git a/centreon-plugins/cloud/docker/restapi/mode/containerusage.pm b/centreon-plugins/cloud/docker/restapi/mode/containerusage.pm index a9827566d..3ec13cb61 100644 --- a/centreon-plugins/cloud/docker/restapi/mode/containerusage.pm +++ b/centreon-plugins/cloud/docker/restapi/mode/containerusage.pm @@ -37,11 +37,11 @@ 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}") { + if (defined($instance_mode->{option_results}->{critical_container_status}) && $instance_mode->{option_results}->{critical_container_status} ne '' && + eval "$instance_mode->{option_results}->{critical_container_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}") { + } elsif (defined($instance_mode->{option_results}->{warning_container_status}) && $instance_mode->{option_results}->{warning_container_status} ne '' && + eval "$instance_mode->{option_results}->{warning_container_status}") { $status = 'warning'; } }; @@ -54,7 +54,7 @@ sub custom_status_threshold { sub custom_status_output { my ($self, %options) = @_; - my $msg = 'status : ' . $self->{result_values}->{status} . ' [error: ' . $self->{result_values}->{error} . ']'; + my $msg = 'state : ' . $self->{result_values}->{state}; return $msg; } @@ -62,55 +62,146 @@ sub custom_status_output { sub custom_status_calc { my ($self, %options) = @_; - $self->{result_values}->{status} = $options{new_datas}->{$self->{instance} . '_status'}; + $self->{result_values}->{state} = $options{new_datas}->{$self->{instance} . '_state'}; $self->{result_values}->{name} = $options{new_datas}->{$self->{instance} . '_name'}; - $self->{result_values}->{error} = $options{new_datas}->{$self->{instance} . '_error'}; return 0; } +sub custom_cpu_calc { + my ($self, %options) = @_; + + my $delta_cpu_total = $options{new_datas}->{$self->{instance} . '_cpu_total_usage'} - $options{old_datas}->{$self->{instance} . '_cpu_total_usage'}; + my $delta_cpu_system = $options{new_datas}->{$self->{instance} . '_cpu_system_usage'} - $options{old_datas}->{$self->{instance} . '_cpu_system_usage'}; + $self->{result_values}->{prct_cpu} = (($delta_cpu_total / $delta_cpu_system) * $options{new_datas}->{$self->{instance} . '_cpu_number'}) * 100; + $self->{result_values}->{display} = $options{new_datas}->{$self->{instance} . '_display'}; + + return 0; +} + +sub custom_memory_perfdata { + my ($self, %options) = @_; + + my $extra_label = ''; + if (!defined($options{extra_instance}) || $options{extra_instance} != 0) { + $extra_label .= '_' . $self->{result_values}->{display}; + } + $self->{output}->perfdata_add(label => 'memory_used' . $extra_label, unit => 'B', + value => $self->{result_values}->{used}, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{label}, total => $self->{result_values}->{total}, cast_int => 1), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{label}, total => $self->{result_values}->{total}, cast_int => 1), + min => 0, max => $self->{result_values}->{total}); +} + +sub custom_memory_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_memory_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_memory_calc { + my ($self, %options) = @_; + + $self->{result_values}->{display} = $options{new_datas}->{$self->{instance} . '_display'}; + $self->{result_values}->{total} = $options{new_datas}->{$self->{instance} . '_memory_total'}; + $self->{result_values}->{used} = $options{new_datas}->{$self->{instance} . '_memory_usage'}; + $self->{result_values}->{free} = $self->{result_values}->{total} - $self->{result_values}->{used}; + $self->{result_values}->{prct_free} = $self->{result_values}->{free} * 100 / $self->{result_values}->{total}; + $self->{result_values}->{prct_used} = $self->{result_values}->{used} * 100 / $self->{result_values}->{total}; + return 0; +} + sub set_counters { my ($self, %options) = @_; $self->{maps_counters_type} = [ { name => 'containers', type => 1, cb_prefix_output => 'prefix_containers_output', message_multiple => 'All containers are ok', skipped_code => { -11 => 1 } }, + { name => 'containers_traffic', type => 1, cb_prefix_output => 'prefix_containers_traffic_output', message_multiple => 'All container traffics are ok', skipped_code => { -11 => 1 } }, ]; - $self->{maps_counters}->{output_stream} = [ + $self->{maps_counters}->{containers} = [ { label => 'container-status', threshold => 0, set => { - key_values => [ { name => 'status' }, { name => 'name' }, { name => 'error' } ], + key_values => [ { name => 'state' }, { name => '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'), } }, + { label => 'cpu', set => { + key_values => [ { name => 'cpu_total_usage', diff => 1 }, { name => 'cpu_system_usage', diff => 1 }, { name => 'cpu_number' }, { name => 'display' } ], + output_template => 'CPU Usage : %.2f %%', + closure_custom_calc => $self->can('custom_cpu_calc'), + output_use => 'prct_cpu', threshold_use => 'prct_cpu', + perfdatas => [ + { label => 'cpu', value => 'prct_cpu', template => '%.2f', + unit => '%', min => 0, max => 100, label_extra_instance => 1, instance_use => 'display' }, + ], + } + }, + { label => 'memory', set => { + key_values => [ { name => 'memory_usage' }, { name => 'memory_total' }, { name => 'display' } ], + closure_custom_calc => $self->can('custom_memory_calc'), + closure_custom_output => $self->can('custom_memory_output'), + closure_custom_perfdata => $self->can('custom_memory_perfdata'), + closure_custom_threshold_check => $self->can('custom_memory_threshold'), + } + }, + { label => 'read-iops', set => { + key_values => [ { name => 'read_io', diff => 1 }, { name => 'display' } ], + per_second => 1, + output_template => 'Read IOPs : %.2f', output_error_template => "Read IOPs : %s", + perfdatas => [ + { label => 'read_iops', value => 'read_io_per_second', template => '%.2f', + unit => 'iops', min => 0, label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + { label => 'write-iops', set => { + key_values => [ { name => 'write_io', diff => 1 }, { name => 'display' } ], + per_second => 1, + output_template => 'Write IOPs : %.2f', output_error_template => "Write IOPs : %s", + perfdatas => [ + { label => 'write_iops', value => 'write_io_per_second', template => '%.2f', + unit => 'iops', min => 0, label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + ]; + + $self->{maps_counters}->{containers_traffic} = [ { label => 'traffic-in', set => { - key_values => [ { name => 'traffic_in', diff => 1 }, { name => 'name' } ], + 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 => 'name_absolute' }, + 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 => 'name' } ], + 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 => 'name_absolute' }, - ], - } - }, - { label => 'dropped-in', set => { - key_values => [ { name => 'dropped_in', diff => 1 }, { name => 'name' } ], - output_template => 'Packets Dropped In : %s', - perfdatas => [ - { label => 'dropped_in', value => 'dropped_in_absolute', template => '%.2f', - min => 0, label_extra_instance => 1, instance_use => 'name_absolute' }, + min => 0, unit => 'b/s', label_extra_instance => 1, instance_use => 'display_absolute' }, ], } }, @@ -126,9 +217,11 @@ sub new { $options{options}->add_options(arguments => { "container-id:s" => { name => 'container_id' }, + "container-name:s" => { name => 'container_name' }, "filter-name:s" => { name => 'filter_name' }, - "warning-container-status:s" => { name => 'warning_container_status' }, - "critical-container-status:s" => { name => 'critical_container_status', default => '%{status} !~ /Connecting|Connected/i || %{error} !~ /none/i' }, + "use-name" => { name => 'use_name' }, + "warning-container-status:s" => { name => 'warning_container_status', default => '' }, + "critical-container-status:s" => { name => 'critical_container_status', default => '' }, }); $self->{statefile_cache_containers} = centreon::plugins::statefile->new(%options); @@ -144,6 +237,12 @@ sub check_options { $self->{statefile_cache_containers}->check_options(%options); } +sub prefix_containers_traffic_output { + my ($self, %options) = @_; + + return "Container '" . $options{instance_value}->{display} . "' "; +} + sub prefix_containers_output { my ($self, %options) = @_; @@ -164,26 +263,43 @@ sub manage_selection { my ($self, %options) = @_; $self->{containers} = {}; - my $result = $options{custom}->api_get_containers(container_id => $self->{option_results}->{container_id}, statefile => $self->{statefile_cache_containers}); - use Data::Dumper; - print Data::Dumper::Dumper($result); - exit(1); + $self->{containers_traffic} = {}; + my $result = $options{custom}->api_get_containers(container_id => $self->{option_results}->{container_id}, + container_name => $self->{option_results}->{container_name}, statefile => $self->{statefile_cache_containers}); - foreach my $entry (@{$result->{outputs}}) { - my $name = $entry->{name} . '/' . $entry->{requested_stream_id}; + foreach my $container_id (keys %{$result}) { + next if (!defined($result->{$container_id}->{Stats})); + my $name = $result->{$container_id}->{Name}; 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->{output_stream}->{$entry->{id}} = { - display => $name, - status => $entry->{status}, - traffic_in => $entry->{stats}->{net_recv}->{bytes} * 8, - traffic_out => $entry->{stats}->{net_send}->{bytes} * 8, - dropped_in => $entry->{stats}->{net_recv}->{dropped}, + my $read_io = $result->{$container_id}->{Stats}->{blkio_stats}->{io_service_bytes_recursive}->[0]->{value}; + my $write_io = $result->{$container_id}->{Stats}->{blkio_stats}->{io_service_bytes_recursive}->[1]->{value}; + $self->{containers}->{$container_id} = { + display => defined($self->{option_results}->{use_name}) ? $name : $container_id, + name => $name, + state => $result->{$container_id}->{State}, + read_io => $read_io, + write_io => $write_io, + cpu_total_usage => $result->{$container_id}->{Stats}->{cpu_stats}->{cpu_usage}->{total_usage}, + cpu_system_usage => $result->{$container_id}->{Stats}->{cpu_stats}->{system_cpu_usage}, + cpu_number => scalar(@{$result->{$container_id}->{Stats}->{cpu_stats}->{cpu_usage}->{percpu_usage}}), + memory_usage => $result->{$container_id}->{Stats}->{memory_stats}->{usage}, + memory_total => $result->{$container_id}->{Stats}->{memory_stats}->{limit}, }; + + foreach my $interface (keys %{$result->{$container_id}->{Stats}->{networks}}) { + my $name = defined($self->{option_results}->{use_name}) ? $name : $container_id; + $name .= '.' . $interface; + $self->{containers_traffic}->{$name} = { + display => $name, + traffic_in => $result->{$container_id}->{Stats}->{networks}->{$interface}->{rx_bytes} * 8, + traffic_out => $result->{$container_id}->{Stats}->{networks}->{$interface}->{tx_bytes} * 8, + }; + } } if (scalar(keys %{$self->{containers}}) <= 0) { @@ -191,9 +307,12 @@ sub manage_selection { $self->{output}->option_exit(); } - $self->{cache_name} = "docker_" . $self->{mode} . '_' . $options{custom}->{hostname} . '_' . $options{custom}->{port} . '_' . + my $hostnames = $options{custom}->get_hostnames(); + $self->{cache_name} = "docker_" . $self->{mode} . '_' . join('_', @$hostnames) . '_' . $options{custom}->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')); + (defined($self->{option_results}->{filter_name}) ? md5_hex($self->{option_results}->{filter_name}) : md5_hex('all')) . '_' . + (defined($self->{option_results}->{container_id}) ? md5_hex($self->{option_results}->{container_id}) : md5_hex('all')) . '_' . + (defined($self->{option_results}->{container_name}) ? md5_hex($self->{option_results}->{container_name}) : md5_hex('all')); } 1; @@ -210,6 +329,14 @@ Check container usage. Exact container ID. +=item B<--container-name> + +Exact container name (if multiple names: names separated by ':'). + +=item B<--use-name> + +Use docker name for perfdata and display. + =item B<--filter-name> Filter by container name (can be a regexp). @@ -222,24 +349,24 @@ Example: --filter-counters='^container-status$' =item B<--warning-*> Threshold warning. -Can be: 'traffic-in', 'traffic-out', 'dropped-in'. +Can be: 'read-iops', 'write-iops', 'traffic-in', 'traffic-out', +'cpu' (%), 'memory' (%). =item B<--critical-*> Threshold critical. -Can be: 'traffic-in', 'traffic-out', 'dropped-in'. +Can be: 'read-iops', 'write-iops', 'traffic-in', 'traffic-out', +'cpu' (%), 'memory' (%). =item B<--warning-container-status> Set warning threshold for status (Default: -) -Can used special variables like: %{id}, %{name}, %{status}. +Can used special variables like: %{name}, %{state}. =item B<--critical-container-status> -Set critical threshold for status (Default: '%{status} !~ /Connecting|Connected/i'). -Can used special variables like: %{id}, %{name}, %{status}. - - +Set critical threshold for status (Default: -). +Can used special variables like: %{name}, %{state}. =back diff --git a/centreon-plugins/cloud/docker/restapi/mode/listcontainers.pm b/centreon-plugins/cloud/docker/restapi/mode/listcontainers.pm new file mode 100644 index 000000000..2419c0712 --- /dev/null +++ b/centreon-plugins/cloud/docker/restapi/mode/listcontainers.pm @@ -0,0 +1,100 @@ +# +# 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::docker::restapi::mode::listcontainers; + +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->{containers} = $options{custom}->api_list_containers(); +} + +sub run { + my ($self, %options) = @_; + + $self->manage_selection(%options); + foreach my $container_id (sort keys %{$self->{containers}}) { + $self->{output}->output_add(long_msg => '[id = ' . $container_id . "] [name = '" . $self->{containers}->{$container_id}->{Name} . "']" . + " [node = '" . $self->{containers}->{$container_id}->{NodeName} . "']" . + " [state = '" . $self->{containers}->{$container_id}->{State} . "']" + ); + } + + $self->{output}->output_add(severity => 'OK', + short_msg => 'List containers:'); + $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 => ['id', 'name', 'node', 'state']); +} + +sub disco_show { + my ($self, %options) = @_; + + $self->manage_selection(%options); + foreach my $container_id (sort keys %{$self->{containers}}) { + $self->{output}->add_disco_entry(name => $self->{containers}->{$container_id}->{Name}, + node => $self->{containers}->{$container_id}->{NodeName}, + state => $self->{containers}->{$container_id}->{State}, + id => $container_id, + ); + } +} + +1; + +__END__ + +=head1 MODE + +List containers. + +=over 8 + +=back + +=cut + diff --git a/centreon-plugins/cloud/docker/restapi/mode/nodestatus.pm b/centreon-plugins/cloud/docker/restapi/mode/nodestatus.pm new file mode 100644 index 000000000..a4835549a --- /dev/null +++ b/centreon-plugins/cloud/docker/restapi/mode/nodestatus.pm @@ -0,0 +1,221 @@ +# +# 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::docker::restapi::mode::nodestatus; + +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_node_status}) && $instance_mode->{option_results}->{critical_node_status} ne '' && + eval "$instance_mode->{option_results}->{critical_node_status}") { + $status = 'critical'; + } elsif (defined($instance_mode->{option_results}->{warning_node_status}) && $instance_mode->{option_results}->{warning_node_status} ne '' && + eval "$instance_mode->{option_results}->{warning_node_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} . ' [manager status: ' . $self->{result_values}->{manager_status} . ']'; + + return $msg; +} + +sub custom_status_calc { + my ($self, %options) = @_; + + $self->{result_values}->{status} = $options{new_datas}->{$self->{instance} . '_status'}; + $self->{result_values}->{manager_status} = $options{new_datas}->{$self->{instance} . '_manager_status'}; + $self->{result_values}->{display} = $options{new_datas}->{$self->{instance} . '_display'}; + + return 0; +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'node', type => 1, cb_prefix_output => 'prefix_node_output', message_multiple => 'All node informations are ok', skipped_code => { -11 => 1 } }, + { name => 'nodes', type => 1, cb_prefix_output => 'prefix_node_output', message_multiple => 'All node status are ok', skipped_code => { -11 => 1 } }, + ]; + + $self->{maps_counters}->{nodes} = [ + { label => 'node-status', threshold => 0, set => { + key_values => [ { name => 'status' }, { name => 'manager_status' }, { 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'), + } + }, + ]; + $self->{maps_counters}->{node} = [ + { label => 'containers-running', set => { + key_values => [ { name => 'containers_running' }, { name => 'display' } ], + output_template => 'Containers Running : %s', + perfdatas => [ + { label => 'containers_running', value => 'containers_running_absolute', template => '%s', + min => 0, label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + { label => 'containers-stopped', set => { + key_values => [ { name => 'containers_stopped' }, { name => 'display' } ], + output_template => 'Containers Stopped : %s', + perfdatas => [ + { label => 'containers_stopped', value => 'containers_stopped_absolute', template => '%s', + min => 0, label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + { label => 'containers-running', set => { + key_values => [ { name => 'containers_paused' }, { name => 'display' } ], + output_template => 'Containers Paused : %s', + perfdatas => [ + { label => 'containers_paused', value => 'containers_paused_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); + bless $self, $class; + + $self->{version} = '1.0'; + $options{options}->add_options(arguments => + { + "warning-node-status:s" => { name => 'warning_node_status', default => '' }, + "critical-node-status:s" => { name => 'critical_node_status', default => '%{status} !~ /ready/ || %{manager_status} !~ /reachable|-/' }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::check_options(%options); + + $instance_mode = $self; + $self->change_macros(); +} + +sub prefix_node_output { + my ($self, %options) = @_; + + return "Node '" . $options{instance_value}->{display} . "' "; +} + +sub change_macros { + my ($self, %options) = @_; + + foreach (('warning_node_status', 'critical_node_status')) { + if (defined($self->{option_results}->{$_})) { + $self->{option_results}->{$_} =~ s/%\{(.*?)\}/\$self->{result_values}->{$1}/g; + } + } +} + +sub manage_selection { + my ($self, %options) = @_; + + $self->{node} = {}; + $self->{nodes} = {}; + my $result = $options{custom}->api_list_nodes(); + + foreach my $node_name (keys %{$result}) { + $self->{node}->{$node_name} = { + display => $node_name, + containers_running => $result->{$node_name}->{containers_running}, + containers_stopped => $result->{$node_name}->{containers_stopped}, + containers_paused => $result->{$node_name}->{containers_paused}, + }; + foreach my $entry (@{$result->{$node_name}->{nodes}}) { + my $name = $node_name . '/' . $entry->{Addr}; + $self->{nodes}->{$name} = { + display => $name , + status => $entry->{Status}, + manager_status => defined($entry->{ManagerStatus}) ? $entry->{ManagerStatus} : '-', + }; + } + } + + if (scalar(keys %{$self->{node}}) <= 0) { + $self->{output}->add_option_msg(short_msg => "No node found."); + $self->{output}->option_exit(); + } +} + +1; + +__END__ + +=head1 MODE + +Check node status. + +=over 8 + +=item B<--warning-node-status> + +Set warning threshold for status (Default: -) +Can used special variables like: %{display}, %{status}, %{manager_status}. + +=item B<--critical-node-status> + +Set critical threshold for status (Default: '%{status} !~ /ready/ || %{manager_status} !~ /reachable|-/'). +Can used special variables like: %{display}, %{status}, %{manager_status}. + +=item B<--warning-*> + +Threshold warning. +Can be: 'containers-running', 'containers-paused', 'containers-stopped'. + +=item B<--critical-*> + +Threshold critical. +Can be: 'containers-running', 'containers-paused', 'containers-stopped'., + +=back + +=cut diff --git a/centreon-plugins/cloud/docker/restapi/plugin.pm b/centreon-plugins/cloud/docker/restapi/plugin.pm index 9356bacc4..a95750a0f 100644 --- a/centreon-plugins/cloud/docker/restapi/plugin.pm +++ b/centreon-plugins/cloud/docker/restapi/plugin.pm @@ -32,6 +32,7 @@ sub new { $self->{version} = '0.3'; %{$self->{modes}} = ( 'container-usage' => 'cloud::docker::restapi::mode::containerusage', + 'list-containers' => 'cloud::docker::restapi::mode::listcontainers', 'node-status' => 'cloud::docker::restapi::mode::nodestatus', ); diff --git a/centreon-plugins/contrib/README.md b/centreon-plugins/contrib/README.md new file mode 100644 index 000000000..a9271584d --- /dev/null +++ b/centreon-plugins/contrib/README.md @@ -0,0 +1,37 @@ +# HOWTO Centos + +Install dependencies: + + # yum install perl-devel 'perl(ExtUtils::Embed)' + +Compile the wrapper: + + # gcc -o cwrapper_perl cwrapper_perl.c `perl -MExtUtils::Embed -e ccopts -e ldopts` + +Create a fatpack: https://github.com/centreon/centreon-plugins/blob/master/docs/en/user/guide.rst#can-i-have-one-standalone-perl-file- + +Comment following lines in the end of fatpack file: + + use strict; + use warnings; + # Not perl embedded compliant at all + #use FindBin; + #use lib "$FindBin::Bin"; + # use lib '/usr/lib/nagios/plugins/'; + + use centreon::plugins::script; + + centreon::plugins::script->new()->run(); + +Set setuid right: + + # chown root:root cwrapper_perl + # chmod 4775 cwrapper_perl + +Test it: + + $ cwrapper_perl centreon_protocol_udp.pl --plugin --mode=connection --hostname=10.30.2.65 --port=161 + + + + diff --git a/centreon-plugins/contrib/cwrapper_perl.c b/centreon-plugins/contrib/cwrapper_perl.c new file mode 100644 index 000000000..fc658b302 --- /dev/null +++ b/centreon-plugins/contrib/cwrapper_perl.c @@ -0,0 +1,29 @@ +#include +#include + +static PerlInterpreter *my_perl; +static void xs_init (pTHX); + +EXTERN_C void boot_DynaLoader (pTHX_ CV* cv); +EXTERN_C void xs_init(pTHX) +{ + char *file = __FILE__; + /* DynaLoader is a special case */ + newXS("DynaLoader::boot_DynaLoader", boot_DynaLoader, file); +} + +int main (int argc, char **argv, char **env) +{ + int exitstatus = 0; + + PERL_SYS_INIT3(&argc, &argv, &env); + my_perl = perl_alloc(); + perl_construct(my_perl); + PL_exit_flags |= PERL_EXIT_DESTRUCT_END; + perl_parse(my_perl, xs_init, argc, argv, (char **)NULL); + exitstatus = perl_run(my_perl); + perl_destruct(my_perl); + perl_free(my_perl); + PERL_SYS_TERM(); + exit(exitstatus); +} diff --git a/centreon-plugins/database/firebird/mode/longqueries.pm b/centreon-plugins/database/firebird/mode/longqueries.pm index bc1690146..61586c361 100644 --- a/centreon-plugins/database/firebird/mode/longqueries.pm +++ b/centreon-plugins/database/firebird/mode/longqueries.pm @@ -127,9 +127,9 @@ Threshold warning (number of long queries). Threshold critical (number of long queries). -=item B<--critical> +=item B<--seconds> -Threshold critical (number of long queries). +Filter queries over X seconds (Default: 60). =item B<--filter-user> diff --git a/centreon-plugins/database/firebird/mode/memory.pm b/centreon-plugins/database/firebird/mode/memory.pm index b7dad55f5..4b4d7f509 100644 --- a/centreon-plugins/database/firebird/mode/memory.pm +++ b/centreon-plugins/database/firebird/mode/memory.pm @@ -20,56 +20,61 @@ package database::firebird::mode::memory; -use base qw(centreon::plugins::mode); +use base qw(centreon::plugins::templates::counter); use strict; use warnings; -use centreon::plugins::values; -my $maps_counters = { - global => { - '000_used' => { set => { +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'global', type => 0, cb_prefix_output => 'prefix_output' } + ]; + + $self->{maps_counters}->{global} = [ + { label => 'used', set => { key_values => [ { name => 'database_used' }, { name => 'database_allocated' } ], - closure_custom_calc => \&custom_unit_calc, closure_custom_calc_extra_options => { label_ref => 'database' }, - closure_custom_output => \&custom_used_output, + closure_custom_calc => $self->can('custom_unit_calc'), closure_custom_calc_extra_options => { label_ref => 'database' }, + closure_custom_output => $self->can('custom_used_output'), threshold_use => 'prct', - closure_custom_perfdata => \&custom_used_perfdata, + closure_custom_perfdata => $self->can('custom_used_perfdata'), } }, - '001_attachment' => { set => { + { label => 'attachment', set => { key_values => [ { name => 'attachment_used' }, { name => 'database_allocated' } ], - closure_custom_calc => \&custom_unit_calc, closure_custom_calc_extra_options => { label_ref => 'attachment' }, - closure_custom_output => \&custom_unit_output, + closure_custom_calc => $self->can('custom_unit_calc'), closure_custom_calc_extra_options => { label_ref => 'attachment' }, + closure_custom_output => $self->can('custom_unit_output'), threshold_use => 'prct', - closure_custom_perfdata => \&custom_unit_perfdata, + closure_custom_perfdata => $self->can('custom_unit_perfdata'), } }, - '002_transaction' => { set => { + { label => 'transaction', set => { key_values => [ { name => 'transaction_used' }, { name => 'database_allocated' } ], - closure_custom_calc => \&custom_unit_calc, closure_custom_calc_extra_options => { label_ref => 'transaction' }, - closure_custom_output => \&custom_unit_output, + closure_custom_calc => $self->can('custom_unit_calc'), closure_custom_calc_extra_options => { label_ref => 'transaction' }, + closure_custom_output => $self->can('custom_unit_output'), threshold_use => 'prct', - closure_custom_perfdata => \&custom_unit_perfdata, + closure_custom_perfdata => $self->can('custom_unit_perfdata'), } }, - '003_statement' => { set => { + { label => 'statement', set => { key_values => [ { name => 'statement_used' }, { name => 'database_allocated' } ], - closure_custom_calc => \&custom_unit_calc, closure_custom_calc_extra_options => { label_ref => 'statement' }, - closure_custom_output => \&custom_unit_output, + closure_custom_calc => $self->can('custom_unit_calc'), closure_custom_calc_extra_options => { label_ref => 'statement' }, + closure_custom_output => $self->can('custom_unit_output'), threshold_use => 'prct', - closure_custom_perfdata => \&custom_unit_perfdata, + closure_custom_perfdata => $self->can('custom_unit_perfdata'), } }, - '004_call' => { set => { + { label => 'call', set => { key_values => [ { name => 'call_used' }, { name => 'database_allocated' } ], - closure_custom_calc => \&custom_unit_calc, closure_custom_calc_extra_options => { label_ref => 'call' }, - closure_custom_output => \&custom_unit_output, + closure_custom_calc => $self->can('custom_unit_calc'), closure_custom_calc_extra_options => { label_ref => 'call' }, + closure_custom_output => $self->can('custom_unit_output'), threshold_use => 'prct', - closure_custom_perfdata => \&custom_unit_perfdata, + closure_custom_perfdata => $self->can('custom_unit_perfdata'), } }, - }, -}; + ]; +} sub custom_used_output { my ($self, %options) = @_; @@ -130,6 +135,12 @@ sub custom_unit_calc { return 0; } +sub prefix_output { + my ($self, %options) = @_; + + return "Memory "; +} + sub new { my ($class, %options) = @_; my $self = $class->SUPER::new(package => __PACKAGE__, %options); @@ -140,101 +151,25 @@ sub new { { }); - foreach my $key (('global')) { - foreach (keys %{$maps_counters->{$key}}) { - my ($id, $name) = split /_/; - if (!defined($maps_counters->{$key}->{$_}->{threshold}) || $maps_counters->{$key}->{$_}->{threshold} != 0) { - $options{options}->add_options(arguments => { - 'warning-' . $name . ':s' => { name => 'warning-' . $name }, - 'critical-' . $name . ':s' => { name => 'critical-' . $name }, - }); - } - $maps_counters->{$key}->{$_}->{obj} = centreon::plugins::values->new(output => $self->{output}, - perfdata => $self->{perfdata}, - label => $name); - $maps_counters->{$key}->{$_}->{obj}->set(%{$maps_counters->{$key}->{$_}->{set}}); - } - } - return $self; } -sub check_options { - my ($self, %options) = @_; - $self->SUPER::init(%options); - - foreach my $key (('global')) { - foreach (keys %{$maps_counters->{$key}}) { - $maps_counters->{$key}->{$_}->{obj}->init(option_results => $self->{option_results}); - } - } -} - -sub run { - my ($self, %options) = @_; - $self->{sql} = $options{sql}; - - $self->manage_selection(); - - my ($short_msg, $short_msg_append, $long_msg, $long_msg_append) = ('', '', '', ''); - my @exits; - - foreach (sort keys %{$maps_counters->{global}}) { - my $obj = $maps_counters->{global}->{$_}->{obj}; - - $obj->set(instance => 'firebird'); - - my ($value_check) = $obj->execute(values => $self->{firebird}); - - 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 => "Memory $short_msg" - ); - } else { - $self->{output}->output_add(short_msg => "Memory $long_msg"); - } - - $self->{output}->display(); - $self->{output}->exit(); -} - sub manage_selection { my ($self, %options) = @_; - $self->{sql}->connect(); - $self->{sql}->query(query => q{SELECT MON$STAT_GROUP as MYGROUP, MON$MEMORY_ALLOCATED AS MYTOTAL, MON$MEMORY_USED AS MYUSED FROM MON$MEMORY_USAGE}); + $options{sql}->connect(); + $options{sql}->query(query => q{SELECT MON$STAT_GROUP as MYGROUP, MON$MEMORY_ALLOCATED AS MYTOTAL, MON$MEMORY_USED AS MYUSED FROM MON$MEMORY_USAGE}); my %map_group = (0 => 'database', 1 => 'attachment', 2 => 'transaction', 3 => 'statement', 4 => 'call'); - $self->{firebird} = {}; - while ((my $row = $self->{sql}->fetchrow_hashref())) { + $self->{global} = {}; + while ((my $row = $options{sql}->fetchrow_hashref())) { if (!defined($self->{firebird}->{$map_group{$row->{MYGROUP}} . '_used'})) { - $self->{firebird}->{$map_group{$row->{MYGROUP}} . '_used'} = 0; - $self->{firebird}->{$map_group{$row->{MYGROUP}} . '_allocated'} = 0; + $self->{global}->{$map_group{$row->{MYGROUP}} . '_used'} = 0; + $self->{global}->{$map_group{$row->{MYGROUP}} . '_allocated'} = 0; } - $self->{firebird}->{$map_group{$row->{MYGROUP}} . '_used'} += $row->{MYUSED}; - $self->{firebird}->{$map_group{$row->{MYGROUP}} . '_allocated'} += $row->{MYTOTAL}; + $self->{global}->{$map_group{$row->{MYGROUP}} . '_used'} += $row->{MYUSED}; + $self->{global}->{$map_group{$row->{MYGROUP}} . '_allocated'} += $row->{MYTOTAL}; } } diff --git a/centreon-plugins/database/firebird/mode/pages.pm b/centreon-plugins/database/firebird/mode/pages.pm index eb7057a24..228d37c14 100644 --- a/centreon-plugins/database/firebird/mode/pages.pm +++ b/centreon-plugins/database/firebird/mode/pages.pm @@ -20,16 +20,21 @@ package database::firebird::mode::pages; -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 $maps_counters = { - global => { - '000_reads' => { set => { +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'global', type => 0, cb_prefix_output => 'prefix_output' } + ]; + + $self->{maps_counters}->{global} = [ + { label => 'reads', set => { key_values => [ { name => 'reads', diff => 1 } ], per_second => 1, output_template => 'Reads : %.2f', @@ -39,7 +44,7 @@ my $maps_counters = { ], } }, - '001_writes' => { set => { + { label => 'writes', set => { key_values => [ { name => 'writes', diff => 1 } ], per_second => 1, output_template => 'Writes : %.2f', @@ -49,7 +54,7 @@ my $maps_counters = { ], } }, - '002_fetches' => { set => { + { label => 'fetches', set => { key_values => [ { name => 'fetches', diff => 1 } ], per_second => 1, output_template => 'Fetches : %.2f', @@ -59,7 +64,7 @@ my $maps_counters = { ], } }, - '003_statement' => { set => { + { label => 'marks', set => { key_values => [ { name => 'marks', diff => 1 } ], per_second => 1, output_template => 'Marks : %.2f', @@ -69,120 +74,44 @@ my $maps_counters = { ], } }, - }, -}; + ]; +} + +sub prefix_output { + my ($self, %options) = @_; + + return "Page "; +} 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 (('global')) { - foreach (keys %{$maps_counters->{$key}}) { - my ($id, $name) = split /_/; - if (!defined($maps_counters->{$key}->{$_}->{threshold}) || $maps_counters->{$key}->{$_}->{threshold} != 0) { - $options{options}->add_options(arguments => { - 'warning-' . $name . ':s' => { name => 'warning-' . $name }, - 'critical-' . $name . ':s' => { name => 'critical-' . $name }, - }); - } - $maps_counters->{$key}->{$_}->{obj} = centreon::plugins::values->new(statefile => $self->{statefile_value}, - output => $self->{output}, perfdata => $self->{perfdata}, - label => $name); - $maps_counters->{$key}->{$_}->{obj}->set(%{$maps_counters->{$key}->{$_}->{set}}); - } - } - + return $self; } -sub check_options { - my ($self, %options) = @_; - $self->SUPER::init(%options); - - foreach my $key (('global')) { - foreach (keys %{$maps_counters->{$key}}) { - $maps_counters->{$key}->{$_}->{obj}->init(option_results => $self->{option_results}); - } - } - - $self->{statefile_value}->check_options(%options); -} - -sub run { - my ($self, %options) = @_; - $self->{sql} = $options{sql}; - - $self->manage_selection(); - - $self->{new_datas} = {}; - $self->{statefile_value}->read(statefile => 'firebird_' . $self->{mode} . '_' . $self->{sql}->get_unique_id4save()); - $self->{new_datas}->{last_timestamp} = time(); - - my ($short_msg, $short_msg_append, $long_msg, $long_msg_append) = ('', '', '', ''); - my @exits; - - foreach (sort keys %{$maps_counters->{global}}) { - my $obj = $maps_counters->{global}->{$_}->{obj}; - - $obj->set(instance => 'firebird'); - - my ($value_check) = $obj->execute(values => $self->{firebird}, - 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 => "Page $short_msg" - ); - } else { - $self->{output}->output_add(short_msg => "Page $long_msg"); - } - - $self->{statefile_value}->write(data => $self->{new_datas}); - $self->{output}->display(); - $self->{output}->exit(); -} - sub manage_selection { my ($self, %options) = @_; - $self->{sql}->connect(); - $self->{sql}->query(query => q{SELECT MON$PAGE_READS as PAGE_READS, MON$PAGE_WRITES as PAGE_WRITES, MON$PAGE_FETCHES as PAGE_FETCHES, MON$PAGE_MARKS as PAGE_MARKS FROM MON$IO_STATS mi WHERE mi.MON$STAT_GROUP = 0}); + $options{sql}->connect(); + $options{sql}->query(query => q{SELECT MON$PAGE_READS as PAGE_READS, MON$PAGE_WRITES as PAGE_WRITES, MON$PAGE_FETCHES as PAGE_FETCHES, MON$PAGE_MARKS as PAGE_MARKS FROM MON$IO_STATS mi WHERE mi.MON$STAT_GROUP = 0}); my $row = $self->{sql}->fetchrow_hashref(); if (!defined($row)) { $self->{output}->add_option_msg(short_msg => "Cannot get page informations"); $self->{output}->option_exit(); } - $self->{firebird} = { reads => $row->{PAGE_READS}, writes => $row->{PAGE_WRITES}, + $self->{global} = { reads => $row->{PAGE_READS}, writes => $row->{PAGE_WRITES}, fetches => $row->{PAGE_FETCHES}, marks => $row->{PAGE_MARKS} }; + + $self->{cache_name} = "firebird_" . $self->{mode} . '_' . $options{sql}->get_unique_id4save() . '_' . + (defined($self->{option_results}->{filter_counters}) ? md5_hex($self->{option_results}->{filter_counters}) : md5_hex('all')); } 1; diff --git a/centreon-plugins/database/firebird/mode/queries.pm b/centreon-plugins/database/firebird/mode/queries.pm index 59dc5e80c..546146221 100644 --- a/centreon-plugins/database/firebird/mode/queries.pm +++ b/centreon-plugins/database/firebird/mode/queries.pm @@ -20,16 +20,21 @@ package database::firebird::mode::queries; -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 $maps_counters = { - global => { - '000_total' => { set => { +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'global', type => 0, cb_prefix_output => 'prefix_output' } + ]; + + $self->{maps_counters}->{global} = [ + { label => 'total', set => { key_values => [ { name => 'total', diff => 1 } ], per_second => 1, output_template => 'Total : %d', @@ -39,7 +44,7 @@ my $maps_counters = { ], } }, - '001_seq-reads' => { set => { + { label => 'seq-reads', set => { key_values => [ { name => 'seq_reads', diff => 1 } ], per_second => 1, output_template => 'Seq Reads : %d', @@ -49,7 +54,7 @@ my $maps_counters = { ], } }, - '002_inserts' => { set => { + { label => 'inserts', set => { key_values => [ { name => 'inserts', diff => 1 } ], per_second => 1, output_template => 'Inserts : %d', @@ -59,7 +64,7 @@ my $maps_counters = { ], } }, - '003_updates' => { set => { + { label => 'updates', set => { key_values => [ { name => 'updates', diff => 1 } ], per_second => 1, output_template => 'Updates : %d', @@ -69,8 +74,8 @@ my $maps_counters = { ], } }, - '004_deletes' => { set => { - key_values => [ { name => 'deletes', diff => 1 } ], + { label => 'deletes', set => { + key_values => [ { name => 'deletes', diff => 1 } ], per_second => 1, output_template => 'Deletes : %d', perfdatas => [ @@ -79,7 +84,7 @@ my $maps_counters = { ], } }, - '005_backouts' => { set => { + { label => 'backouts', set => { key_values => [ { name => 'backouts', diff => 1 } ], per_second => 1, output_template => 'Backouts : %d', @@ -89,7 +94,7 @@ my $maps_counters = { ], } }, - '006_purges' => { set => { + { label => 'purges', set => { key_values => [ { name => 'purges', diff => 1 } ], per_second => 1, output_template => 'Purges : %d', @@ -99,7 +104,7 @@ my $maps_counters = { ], } }, - '007_expunges' => { set => { + { label => 'expunges', set => { key_values => [ { name => 'expunges', diff => 1 } ], per_second => 1, output_template => 'Expunges : %d', @@ -109,126 +114,50 @@ my $maps_counters = { ], } }, - }, -}; + ]; +} + +sub prefix_output { + my ($self, %options) = @_; + + return "Records "; +} 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 (('global')) { - foreach (keys %{$maps_counters->{$key}}) { - my ($id, $name) = split /_/; - if (!defined($maps_counters->{$key}->{$_}->{threshold}) || $maps_counters->{$key}->{$_}->{threshold} != 0) { - $options{options}->add_options(arguments => { - 'warning-' . $name . ':s' => { name => 'warning-' . $name }, - 'critical-' . $name . ':s' => { name => 'critical-' . $name }, - }); - } - $maps_counters->{$key}->{$_}->{obj} = centreon::plugins::values->new(statefile => $self->{statefile_value}, - output => $self->{output}, perfdata => $self->{perfdata}, - label => $name); - $maps_counters->{$key}->{$_}->{obj}->set(%{$maps_counters->{$key}->{$_}->{set}}); - } - } - + return $self; } -sub check_options { - my ($self, %options) = @_; - $self->SUPER::init(%options); - - foreach my $key (('global')) { - foreach (keys %{$maps_counters->{$key}}) { - $maps_counters->{$key}->{$_}->{obj}->init(option_results => $self->{option_results}); - } - } - - $self->{statefile_value}->check_options(%options); -} - -sub run { - my ($self, %options) = @_; - $self->{sql} = $options{sql}; - - $self->manage_selection(); - - $self->{new_datas} = {}; - $self->{statefile_value}->read(statefile => 'firebird_' . $self->{mode} . '_' . $self->{sql}->get_unique_id4save()); - $self->{new_datas}->{last_timestamp} = time(); - - my ($short_msg, $short_msg_append, $long_msg, $long_msg_append) = ('', '', '', ''); - my @exits; - - foreach (sort keys %{$maps_counters->{global}}) { - my $obj = $maps_counters->{global}->{$_}->{obj}; - - $obj->set(instance => 'firebird'); - - my ($value_check) = $obj->execute(values => $self->{firebird}, - 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 => "Records $short_msg" - ); - } else { - $self->{output}->output_add(short_msg => "Records $long_msg"); - } - - $self->{statefile_value}->write(data => $self->{new_datas}); - $self->{output}->display(); - $self->{output}->exit(); -} - sub manage_selection { my ($self, %options) = @_; - $self->{sql}->connect(); - $self->{sql}->query(query => q{SELECT MON$RECORD_SEQ_READS as MYREADS,MON$RECORD_INSERTS as MYINSERTS, + $options{sql}->connect(); + $options{sql}->query(query => q{SELECT MON$RECORD_SEQ_READS as MYREADS,MON$RECORD_INSERTS as MYINSERTS, MON$RECORD_UPDATES as MYUPDATES, MON$RECORD_DELETES as MYDELETES, MON$RECORD_BACKOUTS as MYBACKOUTS, MON$RECORD_PURGES as MYPURGES, MON$RECORD_EXPUNGES as MYEXPUNGES FROM MON$RECORD_STATS mr WHERE mr.MON$STAT_GROUP = '0'}); - my $row = $self->{sql}->fetchrow_hashref(); + my $row = $options{sql}->fetchrow_hashref(); if (!defined($row)) { $self->{output}->add_option_msg(short_msg => "Cannot get query informations"); $self->{output}->option_exit(); } - $self->{firebird} = { seq_reads => $row->{MYREADS}, inserts => $row->{MYINSERTS}, + $self->{global} = { seq_reads => $row->{MYREADS}, inserts => $row->{MYINSERTS}, updates => $row->{MYUPDATES}, deletes => $row->{MYDELETES}, backouts => $row->{MYBACKOUTS}, purges => $row->{MYPURGES}, expunges => $row->{MYEXPUNGES} }; - $self->{firebird}->{total} = $row->{MYREADS} + $row->{MYINSERTS} + $row->{MYUPDATES} + + $self->{global}->{total} = $row->{MYREADS} + $row->{MYINSERTS} + $row->{MYUPDATES} + $row->{MYDELETES} + $row->{MYBACKOUTS} + $row->{MYPURGES} + $row->{MYEXPUNGES}; + + $self->{cache_name} = "firebird_" . $self->{mode} . '_' . $options{sql}->get_unique_id4save() . '_' . + (defined($self->{option_results}->{filter_counters}) ? md5_hex($self->{option_results}->{filter_counters}) : md5_hex('all')); } 1; diff --git a/centreon-plugins/database/oracle/mode/eventwaitsusage.pm b/centreon-plugins/database/oracle/mode/eventwaitsusage.pm new file mode 100644 index 000000000..9de9db890 --- /dev/null +++ b/centreon-plugins/database/oracle/mode/eventwaitsusage.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 database::oracle::mode::eventwaitsusage; + +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 => 'event', type => 1, cb_prefix_output => 'prefix_event_output', message_multiple => 'All event waits are OK' }, + ]; + + $self->{maps_counters}->{event} = [ + { label => 'total-waits-sec', set => { + key_values => [ { name => 'total_waits', diff => 1 }, { name => 'display' } ], + per_second => 1, + output_template => 'Total Waits : %.2f/s', + perfdatas => [ + { label => 'total_waits', value => 'total_waits_per_second', template => '%.2f', + unit => '/s', min => 0, label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + { label => 'total-waits-time', set => { + key_values => [ { name => 'time_waited_micro', diff => 1 }, { name => 'display' } ], + per_second => 1, + closure_custom_calc => $self->can('custom_usage_calc'), + output_template => 'Total Waits Time : %.2f %%', output_use => 'prct_wait', threshold_use => 'prct_wait', + perfdatas => [ + { label => 'total_waits_time', value => 'prct_wait', template => '%.2f', min => 0, max => 100, unit => '%', + label_extra_instance => 1, instance_use => 'display' }, + ], + } + }, + ]; +} + +sub custom_usage_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; +} + +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_event_output { + my ($self, %options) = @_; + + return "Event '" . $options{instance_value}->{display} . "' "; +} + +sub manage_selection { + my ($self, %options) = @_; + $self->{sql} = $options{sql}; + $self->{sql}->connect(); + + my $query = q{ + 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, + 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(); + + $self->{event} = {}; + foreach my $row (@$result) { + my ($name, $total_waits, $time_waited_micro) = ($row->[1], $row->[2], $row->[5]); + + 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->{event}->{$name} = { + display => $name, + total_waits => $total_waits, + time_waited_micro => $time_waited_micro + }; + } + + 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() . '_' . + (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 Oracle event wait usage. + +=over 8 + +=item B<--warning-*> + +Threshold warning. +Can be: 'total-waits-sec', 'total-waits-time'. + +=item B<--critical-*> + +Threshold critical. +Can be: 'total-waits-sec', 'total-waits-time'. + +=item B<--filter-name> + +Filter by event name. Can be a regex. + +=back + +=cut diff --git a/centreon-plugins/database/oracle/mode/longqueries.pm b/centreon-plugins/database/oracle/mode/longqueries.pm new file mode 100644 index 000000000..2349e2863 --- /dev/null +++ b/centreon-plugins/database/oracle/mode/longqueries.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 database::oracle::mode::longqueries; + +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("query [status: %s] [sql: %s] %s", $self->{result_values}->{status}, + $self->{result_values}->{sql_text}, $self->{result_values}->{generation_time}); + return $msg; +} + +sub custom_status_calc { + my ($self, %options) = @_; + + $self->{result_values}->{status} = $options{new_datas}->{$self->{instance} . '_status'}; + $self->{result_values}->{sql_text} = $options{new_datas}->{$self->{instance} . '_sql_text'}; + $self->{result_values}->{username} = $options{new_datas}->{$self->{instance} . '_username'}; + $self->{result_values}->{since} = $options{new_datas}->{$self->{instance} . '_since'}; + $self->{result_values}->{generation_time} = $options{new_datas}->{$self->{instance} . '_generation_time'}; + 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 => 'status' }, { name => 'sql_text' }, { name => 'since' }, { name => 'username' }, { name => 'generation_time' } ], + 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 => + { + "warning-status:s" => { name => 'warning_status', default => '' }, + "critical-status:s" => { name => 'critical_status', default => '' }, + "memory" => { name => 'memory' }, + "timezone:s" => { name => 'timezone' }, + }); + + centreon::plugins::misc::mymodule_load(output => $self->{output}, module => 'DateTime', + error_msg => "Cannot load module 'DateTime'."); + $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); + } + + if (defined($self->{option_results}->{timezone}) && $self->{option_results}->{timezone} ne '') { + $ENV{TZ} = $self->{option_results}->{timezone}; + } +} + +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->{sql} = $options{sql}; + $self->{sql}->connect(); + + if (!$self->{sql}->is_version_minimum(version => '11')) { + $self->{output}->add_option_msg(short_msg => "Need oracle version >= 11"); + $self->{output}->option_exit(); + } + + $self->{alarms}->{global} = { alarm => {} }; + + my $query = q{ + SELECT status, ((sql_exec_start - date '1970-01-01')*24*60*60) as sql_exec_start, elapsed_time + FROM v$sql_monitor + }; + if ($self->{sql}->is_version_minimum(version => '12')) { + $query = q{ + SELECT status, ((sql_exec_start - date '1970-01-01')*24*60*60) as sql_exec_start, elapsed_time, username, sql_text + FROM v$sql_monitor + }; + } + $self->{sql}->query(query => $query); + + my $last_time; + if (defined($self->{option_results}->{memory})) { + $self->{statefile_cache}->read(statefile => "cache_oracle_" . $self->{mode} . $self->{sql}->get_unique_id4save()); + $last_time = $self->{statefile_cache}->get(name => 'last_time'); + } + + my ($i, $current_time) = (1, time()); + while ((my @row = $self->{sql}->fetchrow_array())) { + my @values = localtime($row[1]); + my $dt = DateTime->new( + year => $values[5] + 1900, + month => $values[4] + 1, + day => $values[3], + hour => $values[2], + minute => $values[1], + second => $values[0], + time_zone => 'UTC', + ); + + next if (defined($self->{option_results}->{memory}) && defined($last_time) && $last_time > $dt->epoch); + $row[4] =~ s/(\n|\|)/-/ms if (defined($row[4])); + + my $since = $row[2] / 1000000; + $self->{alarms}->{global}->{alarm}->{$i} = { + status => $row[0], + sql_text => defined($row[4]) ? $row[4] : '-', + username => defined($row[5]) ? $row[5] : '-', + since => $since, + generation_time => centreon::plugins::misc::change_seconds(value => $since) }; + $i++; + } + + if (defined($self->{option_results}->{memory})) { + $self->{statefile_cache}->write(data => { last_time => $current_time }); + } +} + +1; + +__END__ + +=head1 MODE + +Check long sql queries. + +=over 8 + +=item B<--warning-status> + +Set warning threshold for status (Default: '') +Can used special variables like: %{username}, %{sql_text}, %{since}, %{status} + +=item B<--critical-status> + +Set critical threshold for status (Default: ''). +Can used special variables like: %{username}, %{sql_text}, %{since}, %{status} + +=item B<--timezone> + +Timezone of oracle server (If not set, we use current server execution timezone). + +=item B<--memory> + +Only check new queries. + +=back + +=cut diff --git a/centreon-plugins/database/oracle/mode/rollbacksegmentusage.pm b/centreon-plugins/database/oracle/mode/rollbacksegmentusage.pm new file mode 100644 index 000000000..17163a2a0 --- /dev/null +++ b/centreon-plugins/database/oracle/mode/rollbacksegmentusage.pm @@ -0,0 +1,189 @@ +# +# 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::rollbacksegmentusage; + +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 => 'segment', type => 0, cb_prefix_output => 'prefix_output' }, + ]; + + $self->{maps_counters}->{segment} = [ + { label => 'extends', set => { + key_values => [ { name => 'extends', diff => 1 } ], + per_second => 1, + output_template => 'Extends : %.2f/s', + perfdatas => [ + { label => 'extends', value => 'extends_per_second', template => '%.2f', + unit => '/s', min => 0 }, + ], + } + }, + { label => 'wraps', set => { + key_values => [ { name => 'wraps', diff => 1 } ], + per_second => 1, + output_template => 'Wraps : %.2f/s', + perfdatas => [ + { label => 'wraps', value => 'wraps_per_second', template => '%.2f', + unit => '/s', min => 0 }, + ], + } + }, + { label => 'header-contention', set => { + key_values => [ { name => 'undoheader', diff => 1 }, { name => 'complete', diff => 1 } ], + closure_custom_calc => $self->can('custom_contention_calc'), closure_custom_calc_extra_options => { label_ref => 'header' }, + output_template => 'Header Contention : %.2f %%', output_use => 'header_prct', threshold_use => 'header_prct', + perfdatas => [ + { label => 'header_contention', value => 'header_prct', template => '%.2f', min => 0, max => 100, unit => '%' }, + ], + } + }, + { label => 'block-contention', set => { + key_values => [ { name => 'undoblock', diff => 1 }, { name => 'complete', diff => 1 } ], + closure_custom_calc => $self->can('custom_contention_calc'), closure_custom_calc_extra_options => { label_ref => 'block' }, + output_template => 'Block Contention : %.2f %%', output_use => 'block_prct', threshold_use => 'block_prct', + perfdatas => [ + { label => 'block_contention', value => 'block_prct', template => '%.2f', min => 0, max => 100, unit => '%' }, + ], + } + }, + { label => 'hit-ratio', set => { + key_values => [ { name => 'waits', diff => 1 }, { name => 'gets', diff => 1 } ], + closure_custom_calc => $self->can('custom_hitratio_calc'), + output_template => 'gets/waits Ratio : %.2f %%', output_use => 'hit_ratio', threshold_use => 'hit_ratio', + perfdatas => [ + { label => 'hit_ratio', value => 'hit_ratio', template => '%.2f', min => 0, max => 100, unit => '%' }, + ], + } + }, + ]; +} + +sub custom_hitratio_calc { + my ($self, %options) = @_; + + my $delta_waits = $options{new_datas}->{$self->{instance} . '_waits'} - $options{old_datas}->{$self->{instance} . '_waits'}; + my $delta_gets = $options{new_datas}->{$self->{instance} . '_gets'} - $options{old_datas}->{$self->{instance} . '_gets'}; + $self->{result_values}->{hit_ratio} = $delta_gets == 0 ? 100 : (100 - 100 * $delta_waits / $delta_gets); + + return 0; +} + +sub custom_contention_calc { + my ($self, %options) = @_; + + my $delta_waits = $options{new_datas}->{$self->{instance} . '_complete'} - $options{old_datas}->{$self->{instance} . '_complete'}; + my $delta_undo = $options{new_datas}->{$self->{instance} . '_undo' . $options{extra_options}->{label_ref}} - $options{old_datas}->{$self->{instance} . '_undo' . $options{extra_options}->{label_ref}}; + $self->{result_values}->{$options{extra_options}->{label_ref} . '_prct'} = $delta_waits == 0 ? 0 : (100 * $delta_undo / $delta_waits); + + 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 prefix_output { + my ($self, %options) = @_; + + return "Rollback Segment "; +} + +sub manage_selection { + my ($self, %options) = @_; + $self->{sql} = $options{sql}; + $self->{sql}->connect(); + + my $query = q{ + SELECT SUM(waits), SUM(gets), SUM(extends), SUM(wraps) FROM v$rollstat + }; + + $self->{sql}->query(query => $query); + my @result = $self->{sql}->fetchrow_array(); + $self->{segment} = { waits => $result[0], gets => $result[1], extends => $result[2], wraps => $result[3] }; + + $query = q{ + SELECT ( + SELECT SUM(count) + FROM v$waitstat + WHERE class = 'undo header' OR class = 'system undo header' + ) undoheader, + ( + SELECT SUM(count) + FROM v$waitstat + WHERE class = 'undo block' OR class = 'system undo block' + ) undoblock, + ( + SELECT SUM(count) + FROM v$waitstat + ) complete + FROM DUAL + }; + $self->{sql}->query(query => $query); + @result = $self->{sql}->fetchrow_array(); + $self->{segment}->{undoheader} = $result[0]; + $self->{segment}->{undoblock} = $result[1]; + $self->{segment}->{complete} = $result[2]; + + $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')); +} + +1; + +__END__ + +=head1 MODE + +Check Oracle rollback segment usage. + +=over 8 + +=item B<--warning-*> + +Threshold warning. +Can be: 'header-contention', 'block-contention', 'hit-ratio', +'extends', 'wraps'. + +=item B<--critical-*> + +Threshold critical. +Can be: 'header-contention', 'block-contention', 'hit-ratio', +'extends', 'wraps'. + +=back + +=cut diff --git a/centreon-plugins/database/oracle/plugin.pm b/centreon-plugins/database/oracle/plugin.pm index a9918646c..ad0cb4bae 100644 --- a/centreon-plugins/database/oracle/plugin.pm +++ b/centreon-plugins/database/oracle/plugin.pm @@ -38,10 +38,13 @@ sub new { 'corrupted-blocks' => 'database::oracle::mode::corruptedblocks', 'data-files-status' => 'database::oracle::mode::datafilesstatus', 'datacache-hitratio' => 'database::oracle::mode::datacachehitratio', + 'event-waits-usage' => 'database::oracle::mode::eventwaitsusage', + 'long-queries' => 'database::oracle::mode::longqueries', 'process-usage' => 'database::oracle::mode::processusage', 'rman-backup-problems' => 'database::oracle::mode::rmanbackupproblems', 'rman-backup-age' => 'database::oracle::mode::rmanbackupage', 'rman-online-backup-age' => 'database::oracle::mode::rmanonlinebackupage', + 'rollback-segment-usage' => 'database::oracle::mode::rollbacksegmentusage', 'tablespace-usage' => 'database::oracle::mode::tablespaceusage', 'session-usage' => 'database::oracle::mode::sessionusage', 'sql' => 'centreon::common::protocols::sql::mode::sql', 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 1a5febdc7..7f62447a4 100644 --- a/centreon-plugins/hardware/devices/video/appeartv/snmp/mode/alarms.pm +++ b/centreon-plugins/hardware/devices/video/appeartv/snmp/mode/alarms.pm @@ -102,6 +102,7 @@ sub new { $self->{version} = '1.0'; $options{options}->add_options(arguments => { + "filter-msg:s" => { name => 'filter_msg' }, "warning-status:s" => { name => 'warning_status', default => '%{severity} =~ /minor|warning/i' }, "critical-status:s" => { name => 'critical_status', default => '%{severity} =~ /critical|major/i' }, "memory" => { name => 'memory' }, @@ -175,6 +176,11 @@ sub manage_selection { } next if (defined($self->{option_results}->{memory}) && defined($last_time) && $last_time > $create_time); + if (defined($self->{option_results}->{filter_msg}) && $self->{option_results}->{filter_msg} ne '' && + $result->{msgText} !~ /$self->{option_results}->{filter_msg}/) { + $self->{output}->output_add(long_msg => "skipping '" . $result->{msgText} . "': no matching filter.", debug => 1); + next; + } my $diff_time = $current_time - $create_time; @@ -197,6 +203,10 @@ Check alarms. =over 8 +=item B<--filter-msg> + +Filter by message (can be a regexp). + =item B<--warning-status> Set warning threshold for status (Default: '%{severity} =~ /minor|warning/i') diff --git a/centreon-plugins/hardware/pdu/apc/snmp/mode/load.pm b/centreon-plugins/hardware/pdu/apc/snmp/mode/load.pm index 45b49c9de..e5cc499f9 100644 --- a/centreon-plugins/hardware/pdu/apc/snmp/mode/load.pm +++ b/centreon-plugins/hardware/pdu/apc/snmp/mode/load.pm @@ -149,7 +149,7 @@ sub run { $self->{output}->output_add(long_msg => sprintf("Phase '%s' on Bank '%s' status is '%s' [instance: %s, value: %s]", $result->{rPDULoadStatusPhaseNumber}, $result->{rPDULoadStatusBankNumber}, $result->{rPDULoadStatusLoadState}, - $instance, $result->{rPDULoadStatusLoad})); + $instance, defined($result->{rPDULoadStatusLoad}) ? $result->{rPDULoadStatusLoad} : '-')); my $exit = $self->get_severity(section => 'load', instance => $instance, value => $result->{rPDULoadStatusLoadState}); if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { $self->{output}->output_add(severity => $exit, @@ -273,4 +273,4 @@ Set critical threshold for temperatures (syntax: type,instance,threshold) Example: --critical='load,.*,40' =back -=cut \ No newline at end of file +=cut diff --git a/centreon-plugins/hardware/pdu/apc/snmp/mode/outlet.pm b/centreon-plugins/hardware/pdu/apc/snmp/mode/outlet.pm index 015356ace..7fb1ae8a1 100644 --- a/centreon-plugins/hardware/pdu/apc/snmp/mode/outlet.pm +++ b/centreon-plugins/hardware/pdu/apc/snmp/mode/outlet.pm @@ -154,7 +154,8 @@ sub run { $self->{output}->output_add(long_msg => sprintf("Outlet '%s' state is '%s' [instance: %s, bank : %s, phase : %s, load: %s]", $result->{rPDUOutletStatusOutletName}, $result->{rPDUOutletStatusOutletState}, - $instance, $result->{rPDUOutletStatusOutletBank}, $result->{rPDUOutletStatusOutletPhase}, $result->{rPDUOutletStatusLoad})); + $instance, $result->{rPDUOutletStatusOutletBank}, $result->{rPDUOutletStatusOutletPhase}, + defined($result->{rPDUOutletStatusLoad}) ? $result->{rPDUOutletStatusLoad} : '-')); my $exit = $self->get_severity(section => 'outlet', instance => $instance, value => $result->{rPDUOutletStatusOutletState}); if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { $self->{output}->output_add(severity => $exit, diff --git a/centreon-plugins/hardware/server/fujitsu/snmp/mode/components/cpu.pm b/centreon-plugins/hardware/server/fujitsu/snmp/mode/components/cpu.pm new file mode 100644 index 000000000..e24efde68 --- /dev/null +++ b/centreon-plugins/hardware/server/fujitsu/snmp/mode/components/cpu.pm @@ -0,0 +1,95 @@ +# +# 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::fujitsu::snmp::mode::components::cpu; + +use strict; +use warnings; + +my $map_sc_cpu_status = { + 1 => 'unknown', 2 => 'disabled', 3 => 'ok', 4 => 'not-present', 5 => 'error', + 6 => 'fail', 7 => 'missing-termination', 8 => 'prefailure-warning', +}; +my $map_sc2_cpu_status = { + 1 => 'unknown', 2 => 'not-present', 3 => 'ok', 4 => 'disabled', 5 => 'error', + 6 => 'failed', 7 => 'missing-termination', 8 => 'prefailure-warning', +}; + +my $mapping = { + sc => { + cpuStatus => { oid => '.1.3.6.1.4.1.231.2.10.2.2.5.4.1.1.6', map => $map_sc_cpu_status }, + }, + sc2 => { + sc2cpuDesignation => { oid => '.1.3.6.1.4.1.231.2.10.2.2.10.6.4.1.3' }, + sc2cpuStatus => { oid => '.1.3.6.1.4.1.231.2.10.2.2.10.6.4.1.4', map => $map_sc2_cpu_status }, + }, +}; +my $oid_sc2CPUs = '.1.3.6.1.4.1.231.2.10.2.2.10.6.4.1'; + +sub load { + my ($self) = @_; + + push @{$self->{request}}, { oid => $oid_sc2CPUs, end => $mapping->{sc2}->{sc2cpuStatus} }, { oid => $mapping->{sc}->{cpuStatus}->{oid} }; +} + +sub check_cpu { + my ($self, %options) = @_; + + my ($exit, $warn, $crit, $checked); + foreach my $oid ($self->{snmp}->oid_lex_sort(keys %{$self->{results}->{$options{entry}}})) { + next if ($oid !~ /^$options{mapping}->{$options{status}}->{oid}\.(.*)$/); + my $instance = $1; + my $result = $self->{snmp}->map_instance(mapping => $options{mapping}, results => $self->{results}->{$options{entry}}, instance => $instance); + $result->{instance} = $instance; + + next if ($self->check_filter(section => 'cpu', instance => $instance)); + next if ($result->{$options{status}} =~ /not-present|not-available/i && + $self->absent_problem(section => 'cpu', instance => $instance)); + $self->{components}->{cpu}->{total}++; + + $self->{output}->output_add(long_msg => sprintf("cpu '%s' status is '%s' [instance = %s]", + $result->{$options{name}}, $result->{$options{status}}, $instance, + )); + + $exit = $self->get_severity(section => 'cpu', value => $result->{$options{status}}); + if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { + $self->{output}->output_add(severity => $exit, + short_msg => sprintf("Cpu '%s' status is '%s'", $result->{$options{name}}, $result->{$options{status}})); + } + } +} + +sub check { + my ($self) = @_; + + $self->{output}->output_add(long_msg => "Checking cpu"); + $self->{components}->{cpu} = {name => 'cpu', total => 0, skip => 0}; + return if ($self->check_filter(section => 'cpu')); + + if (defined($self->{results}->{$oid_sc2CPUs}) && scalar(keys %{$self->{results}->{$oid_sc2CPUs}}) > 0) { + check_cpu($self, entry => $oid_sc2CPUs, mapping => $mapping->{sc2}, name => 'sc2cpuDesignation', + status => 'sc2cpuStatus'); + } else { + check_cpu($self, entry => $mapping->{sc}->{cpuStatus}, mapping => $mapping->{sc}, name => 'instance', + status => 'cpuStatus'); + } +} + +1; diff --git a/centreon-plugins/hardware/server/fujitsu/snmp/mode/components/fan.pm b/centreon-plugins/hardware/server/fujitsu/snmp/mode/components/fan.pm new file mode 100644 index 000000000..82bc184d3 --- /dev/null +++ b/centreon-plugins/hardware/server/fujitsu/snmp/mode/components/fan.pm @@ -0,0 +1,116 @@ +# +# 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::fujitsu::snmp::mode::components::fan; + +use strict; +use warnings; + +my $map_sc_fan_status = { + 1 => 'unknown', 2 => 'disabled', 3 => 'ok', 4 => 'fail', + 5 => 'prefailure-predicted', 6 => 'redundant-fan-failed', + 7 => 'not-manageable', 8 => 'not-present', +}; +my $map_sc2_fan_status = { + 1 => 'unknown', 2 => 'disabled', 3 => 'ok', 4 => 'failed', + 5 => 'prefailure-predicted', 6 => 'redundant-fan-failed', + 7 => 'not-manageable', 8 => 'not-present', +}; + +my $mapping = { + sc => { + fanStatus => { oid => '.1.3.6.1.4.1.231.2.10.2.2.5.2.2.1.3', map => $map_sc_fan_status }, + fanCurrentSpeed => { oid => '.1.3.6.1.4.1.231.2.10.2.2.5.2.2.1.8' }, + fanDesignation => { oid => '.1.3.6.1.4.1.231.2.10.2.2.5.2.2.1.16' }, + }, + sc2 => { + sc2fanDesignation => { oid => '.1.3.6.1.4.1.231.2.10.2.2.10.5.2.1.3' }, + sc2fanStatus => { oid => '.1.3.6.1.4.1.231.2.10.2.2.10.5.2.1.5', map => $map_sc2_fan_status }, + sc2fanCurrentSpeed => { oid => '.1.3.6.1.4.1.231.2.10.2.2.10.5.2.1.6' }, + }, +}; +my $oid_sc2Fans = '.1.3.6.1.4.1.231.2.10.2.2.10.5.2.1'; +my $oid_fans = '.1.3.6.1.4.1.231.2.10.2.2.5.2.2.1'; + +sub load { + my ($self) = @_; + + push @{$self->{request}}, { oid => $oid_sc2Fans, end => $mapping->{sc2}->{sc2fanCurrentSpeed} }, { oid => $oid_fans }; +} + +sub check_fan { + my ($self, %options) = @_; + + my ($exit, $warn, $crit, $checked); + foreach my $oid ($self->{snmp}->oid_lex_sort(keys %{$self->{results}->{$options{entry}}})) { + next if ($oid !~ /^$options{mapping}->{$options{status}}->{oid}\.(.*)$/); + my $instance = $1; + my $result = $self->{snmp}->map_instance(mapping => $options{mapping}, results => $self->{results}->{$options{entry}}, instance => $instance); + + next if ($self->check_filter(section => 'fan', instance => $instance)); + next if ($result->{$options{status}} =~ /not-present|not-available/i && + $self->absent_problem(section => 'fan', instance => $instance)); + + $self->{components}->{fan}->{total}++; + + $self->{output}->output_add(long_msg => sprintf("fan '%s' status is '%s' [instance = %s] [speed = %s]", + $result->{$options{name}}, $result->{$options{status}}, $instance, $result->{$options{speed}} + )); + + $exit = $self->get_severity(section => 'fan', value => $result->{$options{status}}); + 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'", $result->{$options{name}}, $result->{$options{status}})); + } + + next if (!defined($result->{$options{speed}}) || $result->{$options{speed}} == -1); + + ($exit, $warn, $crit, $checked) = $self->get_severity_numeric(section => 'fan', instance => $instance, value => $result->{$options{speed}}); + + if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { + $self->{output}->output_add(severity => $exit, + short_msg => sprintf("Fan '%s' speed is %s rpm", $result->{$options{name}}, $result->{$options{speed}})); + } + $self->{output}->perfdata_add(label => 'fan_' . $result->{$options{name}}, unit => 'rpm', + value => $result->{$options{speed}}, + warning => $warn, + critical => $crit, + min => 0 + ); + } +} + +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')); + + if (defined($self->{results}->{$oid_sc2Fans}) && scalar(keys %{$self->{results}->{$oid_sc2Fans}}) > 0) { + check_fan($self, entry => $oid_sc2Fans, mapping => $mapping->{sc2}, name => 'sc2fanDesignation', + speed => 'sc2fanCurrentSpeed', status => 'sc2fanStatus'); + } else { + check_fan($self, entry => $oid_fans, mapping => $mapping->{sc}, name => 'fanDesignation', + speed => 'fanCurrentSpeed', status => 'fanStatus'); + } +} + +1; diff --git a/centreon-plugins/hardware/server/fujitsu/snmp/mode/components/memory.pm b/centreon-plugins/hardware/server/fujitsu/snmp/mode/components/memory.pm new file mode 100644 index 000000000..bb9704a55 --- /dev/null +++ b/centreon-plugins/hardware/server/fujitsu/snmp/mode/components/memory.pm @@ -0,0 +1,96 @@ +# +# 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::fujitsu::snmp::mode::components::memory; + +use strict; +use warnings; + +my $map_sc_memory_status = { + 1 => 'unknown', 2 => 'error', 3 => 'ok', 4 => 'not-available', 5 => 'fail', + 6 => 'prefailure-warning', 7 => 'hot-spare', 8 => 'mirror', + 9 => 'disabled', 10 => 'raid', +}; +my $map_sc2_memory_status = { + 1 => 'unknown', 2 => 'not-present', 3 => 'ok', 4 => 'disabled', 5 => 'error', 6 => 'failed', + 7 => 'prefailure-predicted', 8 => 'hot-spare', 9 => 'mirror', 10 => 'raid', 11 => 'hidden', +}; + +my $mapping = { + sc => { + memModuleStatus => { oid => '.1.3.6.1.4.1.231.2.10.2.2.5.4.10.1.3', map => $map_sc_memory_status }, + }, + sc2 => { + sc2memModuleDesignation => { oid => '.1.3.6.1.4.1.231.2.10.2.2.10.6.5.1.3' }, + sc2memModuleStatus => { oid => '.1.3.6.1.4.1.231.2.10.2.2.10.6.5.1.4', map => $map_sc2_memory_status }, + }, +}; +my $oid_sc2MemoryModules = '.1.3.6.1.4.1.231.2.10.2.2.10.6.5.1'; + +sub load { + my ($self) = @_; + + push @{$self->{request}}, { oid => $oid_sc2MemoryModules, end => $mapping->{sc2}->{sc2memModuleStatus} }, { oid => $mapping->{sc}->{memModuleStatus}->{oid} }; +} + +sub check_memory { + my ($self, %options) = @_; + + my ($exit, $warn, $crit, $checked); + foreach my $oid ($self->{snmp}->oid_lex_sort(keys %{$self->{results}->{$options{entry}}})) { + next if ($oid !~ /^$options{mapping}->{$options{status}}->{oid}\.(.*)$/); + my $instance = $1; + my $result = $self->{snmp}->map_instance(mapping => $options{mapping}, results => $self->{results}->{$options{entry}}, instance => $instance); + $result->{instance} = $instance; + + next if ($self->check_filter(section => 'memory', instance => $instance)); + next if ($result->{$options{status}} =~ /not-present|not-available/i && + $self->absent_problem(section => 'memory', instance => $instance)); + $self->{components}->{memory}->{total}++; + + $self->{output}->output_add(long_msg => sprintf("memory '%s' status is '%s' [instance = %s]", + $result->{$options{name}}, $result->{$options{status}}, $instance, + )); + + $exit = $self->get_severity(section => 'memory', value => $result->{$options{status}}); + if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { + $self->{output}->output_add(severity => $exit, + short_msg => sprintf("Memory '%s' status is '%s'", $result->{$options{name}}, $result->{$options{status}})); + } + } +} + +sub check { + my ($self) = @_; + + $self->{output}->output_add(long_msg => "Checking memories"); + $self->{components}->{memory} = {name => 'memories', total => 0, skip => 0}; + return if ($self->check_filter(section => 'memory')); + + if (defined($self->{results}->{$oid_sc2MemoryModules}) && scalar(keys %{$self->{results}->{$oid_sc2MemoryModules}}) > 0) { + check_memory($self, entry => $oid_sc2MemoryModules, mapping => $mapping->{sc2}, name => 'sc2memModuleDesignation', + status => 'sc2memModuleStatus'); + } else { + check_memory($self, entry => $mapping->{sc}->{memModuleStatus}, mapping => $mapping->{sc}, name => 'instance', + status => 'memModuleStatus'); + } +} + +1; diff --git a/centreon-plugins/hardware/server/fujitsu/snmp/mode/components/psu.pm b/centreon-plugins/hardware/server/fujitsu/snmp/mode/components/psu.pm new file mode 100644 index 000000000..4aa3febdf --- /dev/null +++ b/centreon-plugins/hardware/server/fujitsu/snmp/mode/components/psu.pm @@ -0,0 +1,109 @@ +# +# 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::fujitsu::snmp::mode::components::psu; + +use strict; +use warnings; + +my $map_psu_status = { + 1 => 'unknown', 2 => 'not-present', 3 => 'ok', 4 => 'failed', 5 => 'ac-fail', 6 => 'dc-fail', + 7 => 'critical-temperature', 8 => 'not-manageable', 9 => 'fan-failure-predicted', 10 => 'fan-failure', + 11 => 'power-safe-mode', 12 => 'non-redundant-dc-fail', 13 => 'non-redundant-ac-fail', +}; + +my $mapping = { + sc => { + powerSupplyUnitStatus => { oid => '.1.3.6.1.4.1.231.2.10.2.2.5.11.2.1.3', map => $map_psu_status }, + powerSupplyUnitDesignation => { oid => '.1.3.6.1.4.1.231.2.10.2.2.5.11.2.1.4' }, + }, + sc2 => { + sc2PowerSupplyDesignation => { oid => '.1.3.6.1.4.1.231.2.10.2.2.10.6.2.1.3' }, + sc2PowerSupplyStatus => { oid => '.1.3.6.1.4.1.231.2.10.2.2.10.6.2.1.5', map => $map_psu_status }, + sc2psPowerSupplyLoad => { oid => '.1.3.6.1.4.1.231.2.10.2.2.10.6.2.1.6' }, + }, +}; +my $oid_sc2PowerSupply = '.1.3.6.1.4.1.231.2.10.2.2.10.6.2.1'; +my $oid_powerSupplyUnits = '.1.3.6.1.4.1.231.2.10.2.2.5.11.2.1'; + +sub load { + my ($self) = @_; + + push @{$self->{request}}, { oid => $oid_sc2PowerSupply }, { oid => $oid_powerSupplyUnits }; +} + +sub check_psu { + my ($self, %options) = @_; + + my ($exit, $warn, $crit, $checked); + foreach my $oid ($self->{snmp}->oid_lex_sort(keys %{$self->{results}->{$options{entry}}})) { + next if ($oid !~ /^$options{mapping}->{$options{status}}->{oid}\.(.*)$/); + my $instance = $1; + my $result = $self->{snmp}->map_instance(mapping => $options{mapping}, results => $self->{results}->{$options{entry}}, instance => $instance); + + next if ($self->check_filter(section => 'psu', instance => $instance)); + next if ($result->{$options{status}} =~ /not-present|not-available/i && + $self->absent_problem(section => 'psu', instance => $instance)); + $self->{components}->{psu}->{total}++; + + $self->{output}->output_add(long_msg => sprintf("power supply '%s' status is '%s' [instance = %s] [value = %s]", + $result->{$options{name}}, $result->{$options{status}}, $instance, $result->{$options{current}} + )); + + $exit = $self->get_severity(section => 'psu', value => $result->{$options{status}}); + 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'", $result->{$options{name}}, $result->{$options{status}})); + } + + next if (!defined($result->{$options{current}}) || $result->{$options{current}} == 0); + + ($exit, $warn, $crit, $checked) = $self->get_severity_numeric(section => 'power', instance => $instance, value => $result->{$options{current}}); + + if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { + $self->{output}->output_add(severity => $exit, + short_msg => sprintf("Power supply '%s' is %s W", $result->{$options{name}}, $result->{$options{current}})); + } + $self->{output}->perfdata_add(label => 'power_' . $result->{$options{name}}, unit => 'W', + value => $result->{$options{current}}, + warning => $warn, + critical => $crit, + min => 0 + ); + } +} + +sub check { + my ($self) = @_; + + $self->{output}->output_add(long_msg => "Checking poer supplies"); + $self->{components}->{psu} = {name => 'psus', total => 0, skip => 0}; + return if ($self->check_filter(section => 'psu')); + + if (defined($self->{results}->{$oid_sc2PowerSupply}) && scalar(keys %{$self->{results}->{$oid_sc2PowerSupply}}) > 0) { + check_psu($self, entry => $oid_sc2PowerSupply, mapping => $mapping->{sc2}, name => 'sc2PowerSupplyDesignation', + current => 'sc2psPowerSupplyLoad', status => 'sc2PowerSupplyStatus'); + } else { + check_psu($self, entry => $oid_powerSupplyUnits, mapping => $mapping->{sc}, name => 'powerSupplyUnitDesignation', + status => 'powerSupplyUnitStatus'); + } +} + +1; diff --git a/centreon-plugins/hardware/server/fujitsu/snmp/mode/components/temperature.pm b/centreon-plugins/hardware/server/fujitsu/snmp/mode/components/temperature.pm new file mode 100644 index 000000000..8541dc113 --- /dev/null +++ b/centreon-plugins/hardware/server/fujitsu/snmp/mode/components/temperature.pm @@ -0,0 +1,114 @@ +# +# 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::fujitsu::snmp::mode::components::temperature; + +use strict; +use warnings; + +my $map_sc_temp_status = { + 1 => 'unknown', 2 => 'sensor-disabled', 3 => 'ok', 4 => 'sensor-fail', + 5 => 'warning-temp-warm', 6 => 'warning-temp-cold', 7 => 'critical-temp-warm', + 8 => 'critical-temp-cold', 9 => 'damage-temp-warm', 10 => 'damage-temp-cold', 99 => 'not-available', +}; +my $map_sc2_temp_status = { + 1 => 'unknown', 2 => 'not-available', 3 => 'ok', 4 => 'sensor-failed', 5 => 'failed', + 6 => 'temperature-warning-toohot', 7 => 'temperature-critical-toohot', 8 => 'temperature-normal', + 9 => 'temperature-warning', +}; + +my $mapping = { + sc => { + tempSensorStatus => { oid => '.1.3.6.1.4.1.231.2.10.2.2.5.2.1.1.3', map => $map_sc_temp_status }, + tempCurrentValue => { oid => '.1.3.6.1.4.1.231.2.10.2.2.5.2.1.1.11' }, + tempSensorDesignation => { oid => '.1.3.6.1.4.1.231.2.10.2.2.5.2.1.1.13' }, + }, + sc2 => { + sc2tempSensorDesignation => { oid => '.1.3.6.1.4.1.231.2.10.2.2.10.5.1.1.3' }, + sc2tempSensorStatus => { oid => '.1.3.6.1.4.1.231.2.10.2.2.10.5.1.1.5', map => $map_sc2_temp_status }, + sc2tempCurrentTemperature => { oid => '.1.3.6.1.4.1.231.2.10.2.2.10.5.1.1.6' }, + }, +}; +my $oid_sc2TemperatureSensors = '.1.3.6.1.4.1.231.2.10.2.2.10.5.1.1'; +my $oid_temperatureSensors = '.1.3.6.1.4.1.231.2.10.2.2.5.2.1.1'; + +sub load { + my ($self) = @_; + + push @{$self->{request}}, { oid => $oid_sc2TemperatureSensors, end => $mapping->{sc2}->{sc2tempCurrentTemperature} }, { oid => $oid_temperatureSensors }; +} + +sub check_temperature { + my ($self, %options) = @_; + + my ($exit, $warn, $crit, $checked); + foreach my $oid ($self->{snmp}->oid_lex_sort(keys %{$self->{results}->{$options{entry}}})) { + next if ($oid !~ /^$options{mapping}->{$options{status}}->{oid}\.(.*)$/); + my $instance = $1; + 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)); + next if ($result->{$options{status}} =~ /not-present|not-available/i && + $self->absent_problem(section => 'temperature', instance => $instance)); + $self->{components}->{temperature}->{total}++; + + $self->{output}->output_add(long_msg => sprintf("temperature '%s' status is '%s' [instance = %s] [value = %s]", + $result->{$options{name}}, $result->{$options{status}}, $instance, $result->{$options{current}} + )); + + $exit = $self->get_severity(section => 'temperature', value => $result->{$options{status}}); + 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->{$options{name}}, $result->{$options{status}})); + } + + next if (!defined($result->{$options{current}}) || $result->{$options{current}} <= 0 || $result->{$options{current}} == 255); + + ($exit, $warn, $crit, $checked) = $self->get_severity_numeric(section => 'temperature', instance => $instance, value => $result->{$options{current}}); + + if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { + $self->{output}->output_add(severity => $exit, + short_msg => sprintf("Temperature '%s' is %s V", $result->{$options{name}}, $result->{$options{current}})); + } + $self->{output}->perfdata_add(label => 'temperature_' . $result->{$options{name}}, unit => 'C', + value => $result->{$options{current}}, + warning => $warn, + critical => $crit, + ); + } +} + +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')); + + if (defined($self->{results}->{$oid_sc2TemperatureSensors}) && scalar(keys %{$self->{results}->{$oid_sc2TemperatureSensors}}) > 0) { + check_temperature($self, entry => $oid_sc2TemperatureSensors, mapping => $mapping->{sc2}, name => 'sc2tempSensorDesignation', + current => 'sc2tempCurrentTemperature', status => 'sc2tempSensorStatus'); + } else { + check_temperature($self, entry => $oid_temperatureSensors, mapping => $mapping->{sc}, name => 'tempSensorDesignation', + current => 'tempCurrentValue', status => 'tempSensorStatus'); + } +} + +1; diff --git a/centreon-plugins/hardware/server/fujitsu/snmp/mode/components/voltage.pm b/centreon-plugins/hardware/server/fujitsu/snmp/mode/components/voltage.pm new file mode 100644 index 000000000..d7b563ac6 --- /dev/null +++ b/centreon-plugins/hardware/server/fujitsu/snmp/mode/components/voltage.pm @@ -0,0 +1,116 @@ +# +# 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::fujitsu::snmp::mode::components::voltage; + +use strict; +use warnings; + +my $map_sc_voltage_status = { + 1 => 'unknown', 2 => 'not-available', 3 => 'ok', + 4 => 'too-low', 5 => 'too-high', 6 => 'out-of-range', + 7 => 'battery-prefailure', +}; +my $map_sc2_voltage_status = { + 1 => 'unknown', 2 => 'not-available', 3 => 'ok', + 4 => 'too-low', 5 => 'too-high', 6 => 'out-of-range', + 7 => 'warning', +}; + +my $mapping = { + sc => { + sniScVoltageStatus => { oid => '.1.3.6.1.4.1.231.2.10.2.2.5.11.4.1.3', map => $map_sc_voltage_status }, + sniScVoltageDesignation => { oid => '.1.3.6.1.4.1.231.2.10.2.2.5.11.4.1.4' }, + sniScVoltageCurrentValue => { oid => '.1.3.6.1.4.1.231.2.10.2.2.5.11.4.1.7' }, + }, + sc2 => { + sc2VoltageDesignation => { oid => '.1.3.6.1.4.1.231.2.10.2.2.10.6.3.1.3' }, + sc2VoltageStatus => { oid => '.1.3.6.1.4.1.231.2.10.2.2.10.6.3.1.4', map => $map_sc2_voltage_status }, + sc2VoltageCurrentValue => { oid => '.1.3.6.1.4.1.231.2.10.2.2.10.6.3.1.5' }, + }, +}; +my $oid_sc2Voltages = '.1.3.6.1.4.1.231.2.10.2.2.10.6.3.1'; +my $oid_sniScVoltages = '.1.3.6.1.4.1.231.2.10.2.2.5.11.4.1'; + +sub load { + my ($self) = @_; + + push @{$self->{request}}, { oid => $oid_sc2Voltages, end => $mapping->{sc2}->{sc2VoltageCurrentValue} }, { oid => $oid_sniScVoltages }; +} + +sub check_voltage { + my ($self, %options) = @_; + + my ($exit, $warn, $crit, $checked); + foreach my $oid ($self->{snmp}->oid_lex_sort(keys %{$self->{results}->{$options{entry}}})) { + next if ($oid !~ /^$options{mapping}->{$options{status}}->{oid}\.(.*)$/); + my $instance = $1; + my $result = $self->{snmp}->map_instance(mapping => $options{mapping}, results => $self->{results}->{$options{entry}}, instance => $instance); + + next if ($self->check_filter(section => 'voltage', instance => $instance)); + next if ($result->{$options{status}} =~ /not-present|not-available/i && + $self->absent_problem(section => 'voltage', instance => $instance)); + $self->{components}->{voltage}->{total}++; + + $result->{$options{current}} = $result->{$options{current}} / 1000 if (defined($result->{$options{current}})); + + $self->{output}->output_add(long_msg => sprintf("voltage '%s' status is '%s' [instance = %s] [value = %s]", + $result->{$options{name}}, $result->{$options{status}}, $instance, $result->{$options{current}} + )); + + $exit = $self->get_severity(section => 'voltage', value => $result->{$options{status}}); + if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { + $self->{output}->output_add(severity => $exit, + short_msg => sprintf("Voltage '%s' status is '%s'", $result->{$options{name}}, $result->{$options{status}})); + } + + next if (!defined($result->{$options{current}})); + + ($exit, $warn, $crit, $checked) = $self->get_severity_numeric(section => 'voltage', instance => $instance, value => $result->{$options{current}}); + + if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { + $self->{output}->output_add(severity => $exit, + short_msg => sprintf("Voltage '%s' is %s V", $result->{$options{name}}, $result->{$options{current}})); + } + $self->{output}->perfdata_add(label => 'voltage_' . $result->{$options{name}}, unit => 'V', + value => $result->{$options{current}}, + warning => $warn, + critical => $crit, + ); + } +} + +sub check { + my ($self) = @_; + + $self->{output}->output_add(long_msg => "Checking voltages"); + $self->{components}->{voltage} = {name => 'voltages', total => 0, skip => 0}; + return if ($self->check_filter(section => 'voltage')); + + if (defined($self->{results}->{$oid_sc2Voltages}) && scalar(keys %{$self->{results}->{$oid_sc2Voltages}}) > 0) { + check_voltage($self, entry => $oid_sc2Voltages, mapping => $mapping->{sc2}, name => 'sc2VoltageDesignation', + current => 'sc2VoltageCurrentValue', status => 'sc2VoltageStatus'); + } else { + check_voltage($self, entry => $oid_sniScVoltages, mapping => $mapping->{sc}, name => 'sniScVoltageDesignation', + current => 'sniScVoltageCurrentValue', status => 'sniScVoltageStatus'); + } +} + +1; diff --git a/centreon-plugins/hardware/server/fujitsu/snmp/mode/hardware.pm b/centreon-plugins/hardware/server/fujitsu/snmp/mode/hardware.pm new file mode 100644 index 000000000..4b579ae9b --- /dev/null +++ b/centreon-plugins/hardware/server/fujitsu/snmp/mode/hardware.pm @@ -0,0 +1,189 @@ +# +# 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::fujitsu::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|voltage|cpu|memory)$'; + $self->{regexp_threshold_numeric_check_section_option} = '^(temperature|fan|voltage|power)$'; + + $self->{cb_hook2} = 'snmp_execute'; + + $self->{thresholds} = { + memory => [ + ['unknown', 'UNKNOWN'], + ['not-present|not-available', 'OK'], + ['ok', 'OK'], + ['disabled', 'OK'], + ['error', 'CRITICAL'], + ['prefailure-predicted|prefailure-warning', 'WARNING'], + ['fail', 'CRITICAL'], # can be failed + ['disabled', 'OK'], + ['hot-spare', 'OK'], + ['mirror', 'OK'], + ['raid', 'OK'], + ['hidden', 'OK'], + ], + cpu => [ + ['unknown', 'UNKNOWN'], + ['disabled', 'OK'], + ['ok', 'OK'], + ['not-present', 'OK'], + ['error', 'CRITICAL'], + ['prefailure-warning', 'WARNING'], + ['fail', 'CRITICAL'], # can be failed also + ['missing-termination', 'WARNING'], + ], + voltage => [ + ['unknown', 'UNKNOWN'], + ['not-available', 'OK'], + ['ok', 'OK'], + ['too-low', 'WARNING'], + ['too-high', 'WARNING'], + ['out-of-range', 'CRITICAL'], + ['battery-prefailure', 'CRITICAL'], + ['warning', 'WARNING'], + ], + fan => [ + ['unknown', 'UNKNOWN'], + ['disabled', 'OK'], + ['ok', 'OK'], + ['prefailure-predicted', 'WARNING'], + ['fail', 'CRITICAL'], + ['redundant-fan-failed', 'WARNING'], + ['not-manageable', 'OK'], + ['not-present', 'OK'], + ], + temperature => [ + ['unknown', 'UNKNOWN'], + ['sensor-disabled', 'OK'], + ['ok', 'OK'], + ['sensor-fail', 'CRITICAL'], # can be also sensor-failed + ['warning-temp-warm', 'WARNING'], + ['warning-temp-cold', 'WARNING'], + ['critical-temp-warm', 'CRITICAL'], + ['critical-temp-cold', 'CRITICAL'], + ['damage-temp-warm', 'WARNING'], + ['damage-temp-cold', 'CRITICAL'], + ['not-available', 'OK'], + ['temperature-warning', 'WARNING'], # can be also temperature-warning-toohot + ['temperature-critical-toohot', 'CRITICAL'], + ['temperature-normal', 'OK'], + ], + psu => [ + ['unknown', 'UNKNOWN'], + ['not-present', 'OK'], + ['ok', 'OK'], + ['ac-fail', 'CRITICAL'], + ['dc-fail', 'CRITICAL'], + ['failed', 'CRITICAL'], + ['critical-temperature', 'CRITICAL'], + ['not-manageable', 'OK'], + ['fan-failure-predicted', 'WARNING'], + ['fan-failure', 'CRITICAL'], + ['power-safe-mode', 'WARNING'], + ['non-redundant-dc-fail', 'WARNING'], + ['non-redundant-ac-fail', 'WARNING'], + + ['degraded', 'WARNING'], + ['critical', 'CRITICAL'], + ], + }; + + $self->{components_path} = 'hardware::server::fujitsu::snmp::mode::components'; + $self->{components_module} = ['fan', 'voltage', 'psu', 'memory', 'cpu', '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: 'temperature', 'fan', 'psu', 'voltage', 'cpu', 'memory'. + +=item B<--filter> + +Exclude some parts (comma seperated list) (Example: --filter=temperature) +Can also exclude specific instance: --filter=temperature,1 + +=item B<--absent-problem> + +Return an error if an entity is not 'present' (default is skipping) +Can be specific or global: --absent-problem="fan,1.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,^(?!(ok)$)' + +=item B<--warning> + +Set warning threshold (syntax: type,regexp,threshold) +Example: --warning='temperature,.*,30' + +=item B<--critical> + +Set critical threshold (syntax: type,regexp,threshold) +Example: --critical='temperature,.*,40' + +=back + +=cut diff --git a/centreon-plugins/hardware/server/fujitsu/snmp/plugin.pm b/centreon-plugins/hardware/server/fujitsu/snmp/plugin.pm new file mode 100644 index 000000000..88454599d --- /dev/null +++ b/centreon-plugins/hardware/server/fujitsu/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::server::fujitsu::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}} = ( + 'hardware' => 'hardware::server::fujitsu::snmp::mode::hardware', + ); + + return $self; +} + +1; + +__END__ + +=head1 PLUGIN DESCRIPTION + +Check Fujitsu server in SNMP. + +=cut diff --git a/centreon-plugins/hardware/server/hp/ilo/xmlapi/custom/api.pm b/centreon-plugins/hardware/server/hp/ilo/xmlapi/custom/api.pm index 88a5f611f..2b6dc98d6 100644 --- a/centreon-plugins/hardware/server/hp/ilo/xmlapi/custom/api.pm +++ b/centreon-plugins/hardware/server/hp/ilo/xmlapi/custom/api.pm @@ -229,6 +229,28 @@ sub change_shitty_xml { $options{response} =~ s///mg; + #Other shitty xml: + # + #  + # + #  + #  + #  + # + #  + #  + #  + # + #  + #  + #  + # + #  + #  + #  + # + $options{response} =~ s///msg; + return $options{response}; } @@ -250,7 +272,7 @@ sub get_ilo_response { $xml_result = XMLin($response, ForceArray => ['FAN', 'TEMP', 'MODULE', 'SUPPLY', 'PROCESSOR', 'NIC', 'SMART_STORAGE_BATTERY', 'CONTROLLER', 'DRIVE_ENCLOSURE', - 'LOGICAL_DRIVE', 'PHYSICAL_DRIVE', 'DRIVE_BAY']); + 'LOGICAL_DRIVE', 'PHYSICAL_DRIVE', 'DRIVE_BAY', 'BACKPLANE']); }; if ($@) { $self->{output}->add_option_msg(short_msg => "Cannot decode xml response: $@"); @@ -264,6 +286,7 @@ sub get_ilo_data { my ($self, %options) = @_; $self->{content} = ''; + if (!defined($self->{option_results}->{force_ilo3})) { $self->find_ilo_version(); } else { diff --git a/centreon-plugins/hardware/server/hp/ilo/xmlapi/mode/components/pdrive.pm b/centreon-plugins/hardware/server/hp/ilo/xmlapi/mode/components/pdrive.pm index 8b9e57492..25da27bf0 100644 --- a/centreon-plugins/hardware/server/hp/ilo/xmlapi/mode/components/pdrive.pm +++ b/centreon-plugins/hardware/server/hp/ilo/xmlapi/mode/components/pdrive.pm @@ -76,7 +76,7 @@ sub check_ilo4 { sub check_ilo2 { my ($self) = @_; - return if (!defined($self->{xml_result}->{GET_EMBEDDED_HEALTH_DATA}->{DRIVES}->{DRIVE_BAY})); + return if (!defined($self->{xml_result}->{GET_EMBEDDED_HEALTH_DATA}->{DRIVES}->{DRIVE_BAY})); # In ILO2: # # @@ -103,6 +103,52 @@ sub check_ilo2 { } } +sub check_ilo3 { + my ($self) = @_; + + return if (!defined($self->{xml_result}->{GET_EMBEDDED_HEALTH_DATA}->{DRIVES}->{BACKPLANE})); + # In ILO3: + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + foreach my $backplane (@{$self->{xml_result}->{GET_EMBEDDED_HEALTH_DATA}->{DRIVES}->{BACKPLANE}}) { + next if (!defined($backplane->{DRIVE_BAY})); + + foreach my $result (@{$backplane->{DRIVE_BAY}}) { + my $instance = $result->{NUM}; + + next if ($self->check_filter(section => 'pdrive', instance => $instance)); + next if ($result->{STATUS} =~ /not installed|n\/a|not present|not applicable/i && + $self->absent_problem(section => 'pdrive', instance => $instance)); + + $self->{components}->{pdrive}->{total}++; + + $self->{output}->output_add(long_msg => sprintf("physical drive '%s' status is '%s' [instance = %s]", + $result->{NUM}, $result->{STATUS}, $instance)); + + my $exit = $self->get_severity(label => 'default', section => 'pdrive', value => $result->{STATUS}); + if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { + $self->{output}->output_add(severity => $exit, + short_msg => sprintf("Physical drive '%s' status is '%s'", $result->{NUM}, $result->{STATUS})); + } + } + } +} + sub check { my ($self) = @_; @@ -111,7 +157,8 @@ sub check { return if ($self->check_filter(section => 'pdrive')); check_ilo4($self); + check_ilo3($self); check_ilo2($self); } -1; \ No newline at end of file +1; diff --git a/centreon-plugins/hardware/server/hp/proliant/snmp/mode/components/lnic.pm b/centreon-plugins/hardware/server/hp/proliant/snmp/mode/components/lnic.pm index abf51302c..211f08429 100644 --- a/centreon-plugins/hardware/server/hp/proliant/snmp/mode/components/lnic.pm +++ b/centreon-plugins/hardware/server/hp/proliant/snmp/mode/components/lnic.pm @@ -86,10 +86,10 @@ sub check { my $exit = $self->get_severity(section => 'lnic', value => $result3->{cpqNicIfLogMapCondition}); if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { $self->{output}->output_add(severity => $exit, - short_msg => sprintf("logical nic '%s' is %s (%s)", + short_msg => sprintf("logical nic '%s' is %s", $instance, $result3->{cpqNicIfLogMapCondition})); } } } -1; \ No newline at end of file +1; diff --git a/centreon-plugins/hardware/ups/apc/snmp/mode/batterystatus.pm b/centreon-plugins/hardware/ups/apc/snmp/mode/batterystatus.pm index f39ffc7ae..60bae6757 100644 --- a/centreon-plugins/hardware/ups/apc/snmp/mode/batterystatus.pm +++ b/centreon-plugins/hardware/ups/apc/snmp/mode/batterystatus.pm @@ -44,7 +44,7 @@ sub custom_threshold_output { $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 = 'warning'; + $status = 'unknown'; } }; if (defined($message)) { diff --git a/centreon-plugins/hardware/ups/apc/snmp/mode/outputlines.pm b/centreon-plugins/hardware/ups/apc/snmp/mode/outputlines.pm index a0fef8274..c9609438e 100644 --- a/centreon-plugins/hardware/ups/apc/snmp/mode/outputlines.pm +++ b/centreon-plugins/hardware/ups/apc/snmp/mode/outputlines.pm @@ -44,7 +44,7 @@ sub custom_threshold_output { $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 = 'warning'; + $status = 'unknown'; } }; if (defined($message)) { diff --git a/centreon-plugins/hardware/ups/powerware/snmp/mode/environment.pm b/centreon-plugins/hardware/ups/powerware/snmp/mode/environment.pm index 4bbc68853..c6e6aa5fb 100644 --- a/centreon-plugins/hardware/ups/powerware/snmp/mode/environment.pm +++ b/centreon-plugins/hardware/ups/powerware/snmp/mode/environment.pm @@ -20,44 +20,39 @@ package hardware::ups::powerware::snmp::mode::environment; -use base qw(centreon::plugins::mode); +use base qw(centreon::plugins::templates::counter); use strict; use warnings; -use centreon::plugins::values; -my $maps_counters = { - temperature => { class => 'centreon::plugins::values', obj => undef, - set => { - key_values => [ - { name => 'temperature', no_value => 0, }, - ], - output_template => 'Ambiant Temperature: %.2f C', output_error_template => 'Ambiant Temperature: %s', - perfdatas => [ - { value => 'temperature_absolute', label => 'temperature', template => '%.2f', - unit => 'C' }, - ], - } - }, - humidity => { class => 'centreon::plugins::values', obj => undef, - set => { - key_values => [ - { name => 'humidity', no_value => 0 }, - ], - output_template => 'Humidity: %.2f %%', output_error_template => 'Humidity: %s', - perfdatas => [ - { value => 'humidity_absolute', label => 'humidity', template => '%.2f', - unit => '%', min => 0, max => 100 }, - ], - } - }, -}; - -my $oid_xupsEnvironment = '.1.3.6.1.4.1.534.1.6'; -my $oid_xupsEnvAmbientTemp = '.1.3.6.1.4.1.534.1.6.1.0'; # in degree centigrade -my $oid_xupsEnvAmbientLowerLimit = '.1.3.6.1.4.1.534.1.6.2.0'; -my $oid_xupsEnvAmbientUpperLimit = '.1.3.6.1.4.1.534.1.6.3.0'; -my $oid_xupsEnvAmbientHumidity = '.1.3.6.1.4.1.534.1.6.4.0'; # in % +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'global', type => 0, skipped_code => { -10 => 1 } } + ]; + + $self->{maps_counters}->{global} = [ + { label => 'temperature', set => { + key_values => [ { name => 'temperature' } ], + output_template => 'Ambiant Temperature: %.2f C', + perfdatas => [ + { label => 'temperature', value => 'temperature_absolute', template => '%.2f', + min => 0, unit => 'C' }, + ], + } + }, + { label => 'humidity', set => { + key_values => [ { name => 'humidity' } ], + output_template => 'Humidity: %.2f %%', + perfdatas => [ + { label => 'humidity', value => 'humidity_absolute', template => '%.2f', + min => 0, max => 100, unit => '%' }, + ], + } + }, + ]; +} sub new { my ($class, %options) = @_; @@ -68,101 +63,49 @@ sub new { $options{options}->add_options(arguments => { }); - - $self->{instance_selected} = {}; - - foreach (keys %{$maps_counters}) { - $options{options}->add_options(arguments => { - 'warning-' . $_ . ':s' => { name => 'warning-' . $_ }, - 'critical-' . $_ . ':s' => { name => 'critical-' . $_ }, - }); - my $class = $maps_counters->{$_}->{class}; - $maps_counters->{$_}->{obj} = $class->new(output => $self->{output}, perfdata => $self->{perfdata}, - label => $_); - $maps_counters->{$_}->{obj}->set(%{$maps_counters->{$_}->{set}}); - } return $self; } -sub check_options { - my ($self, %options) = @_; - $self->SUPER::init(%options); - - foreach (keys %{$maps_counters}) { - $maps_counters->{$_}->{obj}->init(option_results => $self->{option_results}); - } -} - -sub manage_counters { - my ($self, %options) = @_; - - foreach (sort keys %{$options{maps_counters}}) { - $options{maps_counters}->{$_}->{obj}->set(instance => $options{instance}); - - my ($value_check) = $options{maps_counters}->{$_}->{obj}->execute(values => $self->{instance_selected}->{$options{instance}}); - - # We don't want to display no value - next if ($value_check == -10); - if ($value_check != 0) { - next; - } - my $exit = $options{maps_counters}->{$_}->{obj}->threshold_check(); - - my $output = $options{maps_counters}->{$_}->{obj}->output(); - - $self->{output}->output_add(severity => $exit, - short_msg => $output - ); - - $options{maps_counters}->{$_}->{obj}->perfdata(); - } -} - -sub run { - my ($self, %options) = @_; - $self->{snmp} = $options{snmp}; - - $self->manage_selection(); - - $self->manage_counters(instance => 'ambiant', maps_counters => $maps_counters); - - $self->{output}->display(); - $self->{output}->exit(); -} - sub manage_selection { my ($self, %options) = @_; - my $values_ok = 0; - $self->{instance_selected}->{ambiant} = {}; - - $self->{results} = $self->{snmp}->get_table(oid => $oid_xupsEnvironment, - nothing_quit => 1); - - if (defined($self->{results}->{$oid_xupsEnvAmbientTemp}) && $self->{results}->{$oid_xupsEnvAmbientTemp} ne '' && - $self->{results}->{$oid_xupsEnvAmbientTemp} != 0) { - $self->{instance_selected}->{ambiant}->{temperature} = $self->{results}->{$oid_xupsEnvAmbientTemp}; - $values_ok++; - } - if (defined($self->{results}->{$oid_xupsEnvAmbientHumidity}) && $self->{results}->{$oid_xupsEnvAmbientHumidity} ne '' && - $self->{results}->{$oid_xupsEnvAmbientHumidity} != 0) { - $self->{instance_selected}->{ambiant}->{humidity} = $self->{results}->{$oid_xupsEnvAmbientHumidity}; - $values_ok++; - } - + + my $oids = { + xupsEnvAmbientTemp => '.1.3.6.1.4.1.534.1.6.1.0', + xupsEnvAmbientLowerLimit => '.1.3.6.1.4.1.534.1.6.2.0', + xupsEnvAmbientUpperLimit => '.1.3.6.1.4.1.534.1.6.3.0', + xupsEnvAmbientHumidity => '.1.3.6.1.4.1.534.1.6.4.0', + xupsEnvRemoteTemp => '.1.3.6.1.4.1.534.1.6.5.0', + xupsEnvRemoteHumidity => '.1.3.6.1.4.1.534.1.6.6.0', + xupsEnvRemoteTempLowerLimit => '.1.3.6.1.4.1.534.1.6.9.0', + xupsEnvRemoteTempUpperLimit => '.1.3.6.1.4.1.534.1.6.10.0', + xupsEnvRemoteHumidityLowerLimit => '.1.3.6.1.4.1.534.1.6.11.0', + xupsEnvRemoteHumidityUpperLimit => '.1.3.6.1.4.1.534.1.6.11.0', + }; + my $snmp_result = $options{snmp}->get_leef(oids => [ + values %$oids + ], nothing_quit => 1); + + $self->{global} = {}; + $self->{global}->{temperature} = defined($snmp_result->{$oids->{xupsEnvAmbientTemp}}) && $snmp_result->{$oids->{xupsEnvAmbientTemp}} ne '' && $snmp_result->{$oids->{xupsEnvAmbientTemp}} != 0 ? + $snmp_result->{$oids->{xupsEnvAmbientTemp}} : + (defined($snmp_result->{$oids->{xupsEnvRemoteTemp}}) && $snmp_result->{$oids->{xupsEnvRemoteTemp}} ne '' && $snmp_result->{$oids->{xupsEnvRemoteTemp}} != 0 ? + $snmp_result->{$oids->{xupsEnvRemoteTemp}} : undef); + $self->{global}->{humidity} = defined($snmp_result->{$oids->{xupsEnvAmbientHumidity}}) && $snmp_result->{$oids->{xupsEnvAmbientHumidity}} ne '' && $snmp_result->{$oids->{xupsEnvAmbientHumidity}} != 0 ? + $snmp_result->{$oids->{xupsEnvAmbientHumidity}} : + (defined($snmp_result->{$oids->{xupsEnvRemoteHumidity}}) && $snmp_result->{$oids->{xupsEnvRemoteHumidity}} ne '' && $snmp_result->{$oids->{xupsEnvRemoteHumidity}} != 0 ? + $snmp_result->{$oids->{xupsEnvRemoteHumidity}} : undef); + if (!defined($self->{option_results}->{'critical-temperature'}) || $self->{option_results}->{'critical-temperature'} eq '') { my $crit_val = ''; - $crit_val = $self->{results}->{$oid_xupsEnvAmbientLowerLimit} . ':' if (defined($self->{results}->{$oid_xupsEnvAmbientLowerLimit}) && - $self->{results}->{$oid_xupsEnvAmbientLowerLimit} ne ''); - $crit_val .= $self->{results}->{$oid_xupsEnvAmbientUpperLimit} if (defined($self->{results}->{$oid_xupsEnvAmbientUpperLimit}) && - $self->{results}->{$oid_xupsEnvAmbientUpperLimit} ne '' && $self->{results}->{$oid_xupsEnvAmbientUpperLimit} ne 0); + $crit_val = $snmp_result->{$oids->{xupsEnvAmbientLowerLimit}} . ':' + if (defined($snmp_result->{$oids->{xupsEnvAmbientLowerLimit}}) && + $snmp_result->{$oids->{xupsEnvAmbientLowerLimit}} ne '' && $snmp_result->{$oids->{xupsEnvAmbientLowerLimit}} != 0); + $crit_val .= $snmp_result->{$oids->{xupsEnvAmbientUpperLimit}} + if (defined($snmp_result->{$oids->{xupsEnvAmbientUpperLimit}}) && + $snmp_result->{$oids->{xupsEnvAmbientUpperLimit}} ne '' && $snmp_result->{$oids->{xupsEnvAmbientUpperLimit}} != 0); $self->{perfdata}->threshold_validate(label => 'critical-temperature', value => $crit_val); } - - if ($values_ok == 0) { - $self->{output}->add_option_msg(short_msg => "Cannot get temperature and humidity values."); - $self->{output}->option_exit(); - } } 1; diff --git a/centreon-plugins/network/acmepacket/snmp/mode/systemusage.pm b/centreon-plugins/network/acmepacket/snmp/mode/systemusage.pm index 0b4ca3711..c1e82cd2d 100644 --- a/centreon-plugins/network/acmepacket/snmp/mode/systemusage.pm +++ b/centreon-plugins/network/acmepacket/snmp/mode/systemusage.pm @@ -25,6 +25,48 @@ 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('replication state : %s', $self->{result_values}->{replication_state}); + return $msg; +} + +sub custom_status_calc { + my ($self, %options) = @_; + + $self->{result_values}->{replication_state} = $options{new_datas}->{$self->{instance} . '_replication_state'}; + return 0; +} + sub set_counters { my ($self, %options) = @_; @@ -87,6 +129,14 @@ sub set_counters { ], } }, + { label => 'replication-status', threshold => 0, set => { + key_values => [ { name => 'replication_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'), + } + }, ]; } @@ -98,27 +148,55 @@ sub new { $self->{version} = '1.0'; $options{options}->add_options(arguments => { + "warning-replication-status:s" => { name => 'warning_replication_status', default => '' }, + "critical-replication-status:s" => { name => 'critical_replication_status', default => '%{replication_state} =~ /outOfService/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_replication_status', 'critical_replication_status')) { + if (defined($self->{option_results}->{$_})) { + $self->{option_results}->{$_} =~ s/%\{(.*?)\}/\$self->{result_values}->{$1}/g; + } + } +} + sub manage_selection { my ($self, %options) = @_; - + + my %mapping_redundancy = ( + 0 => 'unknown', 1 => 'initial', 2 => 'active', 3 => 'standby', + 4 => 'outOfService', 5 => 'unassigned', 6 => 'activePending', + 7 => 'standbyPending', 8 => 'outOfServicePending', 9 => 'recovery', + ); my $oid_apSysCPUUtil = '.1.3.6.1.4.1.9148.3.2.1.1.1.0'; my $oid_apSysMemoryUtil = '.1.3.6.1.4.1.9148.3.2.1.1.2.0'; my $oid_apSysHealthScore = '.1.3.6.1.4.1.9148.3.2.1.1.3.0'; + my $oid_apSysRedundancy = '.1.3.6.1.4.1.9148.3.2.1.1.4.0'; my $oid_apSysGlobalConSess = '.1.3.6.1.4.1.9148.3.2.1.1.5.0'; my $oid_apSysGlobalCPS = '.1.3.6.1.4.1.9148.3.2.1.1.6.0'; my $oid_apSysLicenseCapacity = '.1.3.6.1.4.1.9148.3.2.1.1.10.0'; my $result = $options{snmp}->get_leef(oids => [ - $oid_apSysCPUUtil, $oid_apSysMemoryUtil, $oid_apSysHealthScore, + $oid_apSysCPUUtil, $oid_apSysMemoryUtil, $oid_apSysHealthScore, $oid_apSysRedundancy, $oid_apSysLicenseCapacity, $oid_apSysGlobalConSess, $oid_apSysGlobalCPS ], nothing_quit => 1); - $self->{global} = { cpu_load => $result->{$oid_apSysCPUUtil}, + $self->{global} = { + cpu_load => $result->{$oid_apSysCPUUtil}, memory_used => $result->{$oid_apSysMemoryUtil}, + replication_state => $mapping_redundancy{$result->{$oid_apSysRedundancy}}, license_used => $result->{$oid_apSysLicenseCapacity}, health_score => $result->{$oid_apSysHealthScore}, current_sessions => $result->{$oid_apSysGlobalConSess}, @@ -141,6 +219,16 @@ Check system usage. Only display some counters (regexp can be used). Example: --filter-counters='^memory-usage$' +=item B<--warning-replication-status> + +Set warning threshold for status (Default: ''). +Can used special variables like: %{replication_state} + +=item B<--critical-replication-status> + +Set critical threshold for status (Default: '%{replication_state} =~ /outOfService/i'). +Can used special variables like: %{replication_state} + =item B<--warning-*> Threshold warning. diff --git a/centreon-plugins/network/adva/fsp3000/snmp/mode/alarms.pm b/centreon-plugins/network/adva/fsp3000/snmp/mode/alarms.pm new file mode 100644 index 000000000..71a01fec4 --- /dev/null +++ b/centreon-plugins/network/adva/fsp3000/snmp/mode/alarms.pm @@ -0,0 +1,357 @@ +# +# 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::adva::fsp3000::snmp::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 %s [severity: %s] [type: %s] %s", $self->{result_values}->{label}, $self->{result_values}->{severity}, + $self->{result_values}->{type}, $self->{result_values}->{generation_time}); + return $msg; +} + +sub custom_status_calc { + my ($self, %options) = @_; + + $self->{result_values}->{type} = $options{new_datas}->{$self->{instance} . '_type'}; + $self->{result_values}->{severity} = $options{new_datas}->{$self->{instance} . '_severity'}; + $self->{result_values}->{since} = $options{new_datas}->{$self->{instance} . '_since'}; + $self->{result_values}->{generation_time} = $options{new_datas}->{$self->{instance} . '_generation_time'}; + $self->{result_values}->{label} = $options{new_datas}->{$self->{instance} . '_label'}; + 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 => 'severity' }, { name => 'type' }, { name => 'label'}, { name => 'since' }, { name => 'generation_time' } ], + 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 => + { + "warning-status:s" => { name => 'warning_status', default => '%{severity} =~ /warning|minor/i' }, + "critical-status:s" => { name => 'critical_status', default => '%{severity} =~ /critical|major/i' }, + "memory" => { name => 'memory' }, + "timezone:s" => { name => 'timezone' }, + }); + + centreon::plugins::misc::mymodule_load(output => $self->{output}, module => 'DateTime', + error_msg => "Cannot load module 'DateTime'."); + $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); + } + + $self->{option_results}->{timezone} = 'GMT' if (!defined($self->{option_results}->{timezone}) || $self->{option_results}->{timezone} eq ''); +} + +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_type = ( + 0 => 'undefined', 5 => 'terminalLoopback', 6 => 'oosDisabled', 7 => 'oosManagement', 8 => 'oosMaintenance', 9 => 'oosAins', 10 => 'removed', + 11 => 'lossOfSignal', 12 => 'optInputPwrReceivedTooLow', 13 => 'optInputPwrReceivedTooHigh', 14 => 'laserTemperatureTooHigh', 15 => 'laserTemperatureTooLow', 16 => 'optOutputPowerTransTooLow', 17 => 'optOutputPowerTransTooHigh', + 18 => 'autoShutdownToHighTemp', 19 => 'autoShutdownToHighTxPwr', 20 => 'laserEndOfLife', 21 => 'serverSignalFailureVf', 22 => 'equalizationProgress', + 23 => 'uPortFailure', 24 => 'autoShutdownBlock', 25 => 'autoPowerShutdown', 26 => 'confOutPowerTransTooHigh', 27 => 'confOutPowerTransTooLow', + 28 => 'optSignalFailure', 29 => 'dsbdChannelPowerTooHigh', 30 => 'lossOfSignalCPort', 31 => 'lossOfSignalNPort', 32 => 'outputPowerFault', + 33 => 'eqlzAdjust', 34 => 'ampFailure', 35 => 'eqptProvMismatch', 36 => 'backreflectionTooHigh', 48 => 'fiberConnLos', 49 => 'fiberConnOptFault', + 50 => 'fiberConnInvalid', 51 => 'fiberConnMismatch', 52 => 'fiberConnCommError', 53 => 'fiberConnProtocolFailure', 54 => 'fiberConnDataFailure', + 55 => 'fiberAttenuationHigh', 57 => 'laserBiasCurrAbnormal', 58 => 'fiberConnInvalidTx', 59 => 'fiberConnMismatchTx', 60 => 'fiberAttenuationHighTx', + 61 => 'laserFailure', 62 => 'lossOfReceiverClockRecovery', 63 => 'fiberAttenuationCond', 64 => 'channelMismatch', 65 => 'alarmIndicationSignalLine', + 66 => 'alarmIndicationSignalLowerOrderPath', 67 => 'alarmIndicationSignalOdu', 68 => 'alarmIndicationSignalOpu', 69 => 'alarmIndicationSignalOtu', + 70 => 'alarmIndicationSignalHigherOrderPath', 71 => 'alarmIndicationSignalOduTcmA', 72 => 'alarmIndicationSignalOduTcmB', 73 => 'alarmIndicationSignalOduTcmC', 74 => 'virtualChannelAis', + 75 => 'amplifierAbnormal', 76 => 'automaticPowerReduction', 77 => 'automaticPowerReductionForEyeSafety', 80 => 'apsConfigMismatch', 81 => 'apsProtocolFailure', 82 => 'aseLow', + 83 => 'aseTableGenFailLow', 84 => 'aseTableGenFailHighBackreflection', 85 => 'aseTableGenFailOscMissing', 86 => 'aseTableGenFailPilot', 87 => 'aseTableGenFailSignalinput', + 88 => 'aseTableNotAvailable', 89 => 'aseTableGenProgress', 90 => 'encryptionPortAuthPasswdMissing', 92 => 'backwardDefectIndicationOdu', 93 => 'backwardDefectIndicationOtu', + 94 => 'backwardDefectIndicationOduTcmA', 95 => 'backwardDefectIndicationOduTcmB', 96 => 'backwardDefectIndicationOduTcmC', 97 => 'topologyDataCalculationInProgress', 99 => 'dispertionTunningCondition', 100 => 'lossOfCharSync', + 101 => 'lossOfCharSyncFromFarEnd', 103 => 'encryptionPortEncryptionSwitchOffEnabled', 104 => 'encryptionModuleCryPasswdMissing', 107 => 'encryptionModuleSelfTestStarted', 108 => 'encryptionPortEncryptionSwitchedOff', 109 => 'opuClientSignalFail', + 110 => 'databaseMismatch', 111 => 'databaseFailure', 112 => 'databaseNcuMismatch', 113 => 'dbReplicationIncompleted', 114 => 'databaseVersionMismatch', 115 => 'xfpDecisionThresSetFailed', 116 => 'duplexLinkFailure', 118 => 'singleFanFailure', + 119 => 'multipleFanFailure', 120 => 'lossOfSignalTransmitter', 122 => 'farEndIpAddressUnknown', 123 => 'farEndCommFailure', 125 => 'backupForcedToHalt', 127 => 'facilityForcedOn', 128 => 'fwdAseTableFailPilot', 129 => 'fwdAseTableOnPilot', + 131 => 'encryptionModuleFwpUpdateEnabled', 132 => 'fwpMismatchDownloadNotServiceAffecting', 133 => 'fwpMismatchDownloadServiceAffecting', 135 => 'gainTiltNotSettable', 136 => 'highBer', 137 => 'receiverOverloadProtection', 138 => 'hwInitializing', 139 => 'hwOprReachedHT', + 140 => 'hwDegrade', 141 => 'hwFailure', 142 => 'switchtoProtectionInhibited', 143 => 'switchtoWorkingInhibited', 148 => 'encryptionPortKeyInitExchgMissed', 149 => 'encryptionPortMaxKeyExchgFailuresReachedIs', 150 => 'encryptionPortMaxKeyExchgFailuresReachedOos', + 151 => 'encryptionPortKeyExchangedForced', 152 => 'laserOnDelay', 153 => 'lockedDefectOdu', 154 => 'lockedDefectOduTcmA', 155 => 'lockedDefectOduTcmB', 156 => 'lockedDefectOduTcmC', 157 => 'linkControlProtocolFailure', 158 => 'linkDown', 159 => 'autoShutdownSendingAisLine', + 160 => 'autoShutdownSendingAisOdu', 161 => 'autoShutdownSendingAisOpu', 162 => 'clientFailForwarding', 163 => 'autoShutdownAls', 164 => 'autoAmpShutdown', 165 => 'autoShutdownAmpAps', 166 => 'aseTableBuild', 167 => 'autoShutdownOpuClientSignalFail', 168 => 'autoShutdownSendingEPC', + 169 => 'autoShutdownSendingLckOdu', 170 => 'autoShutdownSendingOciOdu', 171 => 'autoShutdownLaserOffDueToErrFwd', 172 => 'autoShutdownTxRxLasersDueToHighTemp', 173 => 'localFault', 174 => 'localOscLevelAbnormal', 175 => 'lossOfGfpFrame', 176 => 'lossOfFrameMux', 177 => 'lossOfFrameOtu', + 178 => 'lossOfFrame', 179 => 'lossOfFrameLossOfMultiFrameOdu', 180 => 'lossOfLane', 181 => 'lossofMultiframeLowerOrderPath', 182 => 'lossOfMultiFrameOtu', 183 => 'lossofMultiframeHigherOrderPath', 184 => 'lossOfPointerLowerOrderPath', 185 => 'lossOfPointerHigherOrderPath', + 186 => 'losAttProgress', 187 => 'lossOsc', 188 => 'gfpLossOfClientSig', 189 => 'loopbackError', 190 => 'facilityLoopback', 191 => 'lossofTandemConnectionOduTcmA', 192 => 'lossofTandemConnectionOduTcmB', 193 => 'lossofTandemConnectionOduTcmC', 194 => 'mansw', 197 => 'equipmentNotAccepted', 198 => 'equipmentNotApproved', 199 => 'capabilityLevelMismatch', + 200 => 'equipmentMismatch', 201 => 'equipmentNotSupportedByPhysicalLayer', 202 => 'meaSwRevision', 203 => 'mismatch', 204 => 'midstageFault', 205 => 'multiplexStructureIdentifierMismatchOPU', 206 => 'backupNotResponding', 207 => 'openConnectionIndicationOdu', + 208 => 'openConnectionIndicationOduTcmA', 209 => 'openConnectionIndicationOduTcmB', 210 => 'openConnectionIndicationOduTcmC', 211 => 'oduTribMsiMismatch', 212 => 'transmitterDisabledOff', 213 => 'receiverDisabled', 214 => 'opmAbnormalCondition', 215 => 'faultOnOpm', 216 => 'thresOptPowerCtrlFailureHigh', + 217 => 'thresOptPowerCtrlFailureLow', 218 => 'txPowerLimited', 219 => 'oscOpticalPowerControlFailHigh', 220 => 'oscOpticalPowerControlFailLow', 221 => 'oTDRMeasuringinProgress', 222 => 'encryptionModuleCryPasswdError', 223 => 'peerLink', 224 => 'pilotReceiveLevelHigh', + 225 => 'lossOfPilotSignal', 226 => 'payloadMismatchGfp', 227 => 'payloadMismatchLowerOrderPath', 228 => 'payloadMismatchOPU', 229 => 'payloadMismatchHigherOrderPath', 230 => 'provPayloadMismatch', 231 => 'prbsLossOfSeqSynch', 232 => 'prbsRcvActivated', 233 => 'prbsTrmtActivated', 234 => 'protectionNotAvailable', 235 => 'powerSupplyUnitFailure', 236 => 'maxPowerConsProvModulesToHigh', + 237 => 'maxPowerConsEquipModulesToHigh', 238 => 'powerMissing', 239 => 'remoteDefectIndicationLine', 240 => 'remoteDefectIndicationLowerOrderPath', 241 => 'remoteDefectIndicationHigherOrderPath', 243 => 'dcnCommunicationFail', 244 => 'ntpForSchedEqlzRequired', 245 => 'signalDegradeOlm', 246 => 'signalDegradeLine', 247 => 'signalDegradationonLinkVector', + 248 => 'signalDegradeOdu', 249 => 'signalDegradeOtu', 250 => 'pcsSignalDegrade', 251 => 'signalDegradeScn', 252 => 'signalDegradeOduTcmA', 253 => 'signalDegradeOduTcmB', 254 => 'signalDegradeOduTcmC', 255 => 'encryptionModuleSelfTestFail', 256 => 'encryptionModuleSelfTestFailCritical', + 257 => 'signalFailureOnLink', 258 => 'signalFailureonLinkVector', 259 => 'signalFailureOPU', 260 => 'serverSignalFailTx', 261 => 'facilityDataRateNotSupported', 263 => 'lossofSequenceLowerOrderPath', 264 => 'lossofSequenceHigherOrderPath', 265 => 'serverSignalFail', 266 => 'serverSignalFailureGfp', + 267 => 'serverSignalFailureODU', 268 => 'serverSignalFailurePath', 269 => 'serverSignalFailureSectionRS', 272 => 'switchToDuplexInhibited', 274 => 'switchFailed', 276 => 'currentTooHigh', 277 => 'attOnReceiverFiberHigherThanMonitor', 278 => 'attOnReceiverFiberLowerThanMonitor', 279 => 'attOnTransmitterFiberHigherThanMonitor', + 280 => 'attOnTransmitterFiberLowerThanMonitor', 281 => 'thres15MinExceededOduBbe', 283 => 'thres15MinExceededOtuBbe', 285 => 'thres15MinExceededOduTcmABbe', 287 => 'thres15MinExceededOduTcmBBbe', 289 => 'thres15MinExceededOduTcmCBbe', 291 => 'thres15MinExceededFecBERCE', 293 => 'brPwrRxTooHigh', 294 => 'chromaticDispersionTooHigh', + 295 => 'chromaticDispersionTooLow', 296 => 'dispersionCompensationTooHigh', 297 => 'dispersionCompensationTooLow', 298 => 'thres15MinExceededFecCE', 300 => 'carrierFreqOffsetTooHigh', 301 => 'carrierFreqOffsetTooLow', 302 => 'thres15MinExceededSonetLineCV', 304 => 'thres15MinExceededPhysConvCV', + 306 => 'thres15MinExceededSonetSectCV', 308 => 'thres15MinExceededPhysConvDE', 310 => 'differentialGroupDelayTooHigh', 311 => 'thres15MinExceededFecES', 313 => 'thres15MinExceededSonetLineES', 315 => 'thres15MinExceededOduES', 317 => 'thres15MinExceededOtuES', + 319 => 'thres15MinExceededPhysConvES', 321 => 'thres15MinExceededSonetSectES', 323 => 'thres15MinExceededOduTcmAES', 325 => 'thres15MinExceededOduTcmBES', 327 => 'thres15MinExceededOduTcmCES', 329 => 'latencyTooHigh', 330 => 'latencyTooLow', 331 => 'laserBiasCurrentNormalizedtooHigh', 332 => 'localOscTemperatureTooHigh', 333 => 'localOscTemperatureTooLow', + 334 => 'pumpLaser1TempTooHigh', 335 => 'pumpLaser1TempTooLow', 336 => 'pumpLaser2TempTooHigh', 337 => 'pumpLaser2TempTooLow', 338 => 'pumpLaser3TempTooHigh', 339 => 'pumpLaser3TempTooLow', 340 => 'pumpLaser4TempTooHigh', 341 => 'pumpLaser4TempTooLow', 342 => 'oscPwrTooHigh', + 343 => 'oscPwrTooLow', 344 => 'ramanPumpPwrTooHigh', 345 => 'ramanPumpPwrTooLow', 346 => 'roundTripDelayTooHigh', 347 => 'roundTripDelayTooLow', 348 => 'thres15MinExceededSonetSectSEFS', 350 => 'thres15MinExceededFecSES', 352 => 'thres15MinExceededSonetLineSES', + 354 => 'thres15MinExceededOduSES', 356 => 'thres15MinExceededOtuSES', 358 => 'thres15MinExceededSonetSectSES', 360 => 'thres15MinExceededOduTcmASES', 362 => 'thres15MinExceededOduTcmBSES', 364 => 'thres15MinExceededOduTcmCSES', 366 => 'logicalLanesSkewTooHigh', + 367 => 'signalToNoiseRatioTooLow', 368 => 'subModuleTempTooHigh', 369 => 'temperatureTooHigh', 370 => 'temperatureTooLow', 371 => 'thres15MinExceededSonetLineUAS', 373 => 'thres15MinExceededOduUAS', 375 => 'thres15MinExceededOtuUAS', + 377 => 'thres15MinExceededOduTcmAUAS', 379 => 'thres15MinExceededOduTcmBUAS', 381 => 'thres15MinExceededOduTcmCUAS', 383 => 'thres15MinExceededFecUBE', 385 => 'encryptionModuleTamperDetected', 386 => 'thermoElectricCoolerEndOfLife', 387 => 'alarmInputTIF', 389 => 'traceIdentifierMismatchOdu', + 390 => 'traceIdentifierMismatchOtu', 391 => 'sectionTraceMismatch', 392 => 'traceIdentifierMismatchOduTcmA', 393 => 'traceIdentifierMismatchOduTcmB', 394 => 'traceIdentifierMismatchOduTcmC', 395 => 'turnupFailed', 396 => 'turnupCondition', 397 => 'unequippedLowerOrderPath', 398 => 'unequippedHigherOrderPath', 399 => 'voaControlFail', 400 => 'voltageOutOfRange', 401 => 'inputVoltageFailure', 402 => 'inputVoltageFailurePort1', + 403 => 'inputVoltageFailurePort2', 406 => 'wtrTimerRunning', 407 => 'lossOfLaneOtu', 408 => 'lossOfTestSeqSynchOpu', 409 => 'lossOfMfiOpu', 410 => 'oosDisabledLckOduTrmt', 411 => 'configurationMismatch', 412 => 'oduAutoShutdownRxAIS', 413 => 'oduAutoShutdownTxAIS', 414 => 'oosDisabledLckOduRx', 420 => 'thres15MinExceededBbePcs', + 422 => 'autoShutdownGAis', 423 => 'equipmentMismatchAllow', 424 => 'warmUp', 432 => 'networkPathRestricted', 434 => 'vfClientSignalFail', 435 => 'autoShutdownVfCSF', 439 => 'linkFailToPartner1', 440 => 'linkFailToPartner2', 441 => 'linkFailToPartner3', 442 => 'linkFailToPartner4', 443 => 'partnerUnavailable', + 445 => 'partner1Deleted', 446 => 'partner2Deleted', 447 => 'partner3Deleted', 448 => 'partner4Deleted', 450 => 'thres15MinExceededPhysConvSE', 452 => 'thres15MinExceededPhysConvCVDE', 456 => 'autoShutdownSendingOciOduTx', 457 => 'acpLinkLoss', 458 => 'acpChannelUnAvail', 459 => 'acpPartnerUnassigned', 460 => 'acpPartnerDeleted', 461 => 'thres15MinExceededCrcErrorsRcv', 463 => 'thres15MinExceededCrcFramesEgress', + 465 => 'autoServiceMismatch', 466 => 'batteryNoCharge', 469 => 'tagReceiveFail', 470 => 'tagReceiveFailMaxReached', 473 => 'internalEncryptionFail', 13006 => 'cfmRemoteDefectIndication', 13007 => 'cfmCcmMacStatus', 13008 => 'cfmCcmError', 13009 => 'cfmCcmLost', 13010 => 'cfmCcmXConn', 100005 => 'mepNotPresentL2', 100006 => 'priVidNotEqualExtVidL2', 100009 => 'sfCfmLevel0L2', 100010 => 'sfCfmLevel1L2', 100011 => 'sfCfmLevel2L2', + 100012 => 'sfCfmLevel3L2', 100013 => 'sfCfmLevel4L2 ', 100014 => 'sfCfmLevel5L2', 100015 => 'sfCfmLevel6L2', 100016 => 'sfCfmLevel7L2', 120004 => 'messageLossSpeq', 120005 => 'oscFiberMissingSpeq', 120006 => 'optLowSpeq', 120007 => 'ppcOutOfRangeSpeq', 120008 => 'gainTooHighSpeq', 120009 => 'gainTooLowSpeq', 120010 => 'gainAdoptFailedSpeq', 120011 => 'processLockedOutSpeq', 120012 => 'ppcLimitExceededSpeq', +); +my %map_severity = (1 => 'indeterminate', 2 => 'critical', 3 => 'major', 4 => 'minor', 5 => 'warning', 6 => 'cleared', 7 => 'notReported'); + +my $oids = { + alarmSysTable => { + oid => '.1.3.6.1.4.1.2544.1.11.7.4.1', label => 'sys', + mapping => { + severity => { oid => '.1.3.6.1.4.1.2544.1.11.7.4.1.1.2', map => \%map_severity }, + timestamp => { oid => '.1.3.6.1.4.1.2544.1.11.7.4.1.1.4' }, + } + }, + alarmEqptTable => { + oid => '.1.3.6.1.4.1.2544.1.11.7.4.5', label => 'eqpt', + mapping => { + severity => { oid => '.1.3.6.1.4.1.2544.1.11.7.4.5.1.2', map => \%map_severity }, + timestamp => { oid => '.1.3.6.1.4.1.2544.1.11.7.4.5.1.4' }, + } + }, + alarmFacilityTable => { + oid => '.1.3.6.1.4.1.2544.1.11.7.4.7', label => 'facility', + mapping => { + severity => { oid => '.1.3.6.1.4.1.2544.1.11.7.4.7.1.2', map => \%map_severity }, + timestamp => { oid => '.1.3.6.1.4.1.2544.1.11.7.4.7.1.4' }, + } + }, + alarmTerminPointTable => { + oid => '.1.3.6.1.4.1.2544.1.11.7.4.9', label => 'terminpoint', + mapping => { + severity => { oid => '.1.3.6.1.4.1.2544.1.11.7.4.9.1.2', map => \%map_severity }, + timestamp => { oid => '.1.3.6.1.4.1.2544.1.11.7.4.9.1.4' }, + } + }, + alarmExternalPortTable => { + oid => '.1.3.6.1.4.1.2544.1.11.7.4.11', label => 'externalport', + mapping => { + severity => { oid => '.1.3.6.1.4.1.2544.1.11.7.4.11.1.2', map => \%map_severity }, + timestamp => { oid => '.1.3.6.1.4.1.2544.1.11.7.4.11.1.4' }, + } + }, + alarmDcnTable => { + oid => '.1.3.6.1.4.1.2544.1.11.7.4.16', label => 'dcn', + mapping => { + severity => { oid => '.1.3.6.1.4.1.2544.1.11.7.4.16.1.2', map => \%map_severity }, + timestamp => { oid => '.1.3.6.1.4.1.2544.1.11.7.4.16.1.4' }, + } + }, + alarmEnvTable => { + oid => '.1.3.6.1.4.1.2544.1.11.7.4.20', label => 'env', + mapping => { + severity => { oid => '.1.3.6.1.4.1.2544.1.11.7.4.20.1.2', map => \%map_severity }, + timestamp => { oid => '.1.3.6.1.4.1.2544.1.11.7.4.20.1.4' }, + } + }, + alarmContainerTable => { + oid => '.1.3.6.1.4.1.2544.1.11.7.4.24', label => 'container', + mapping => { + severity => { oid => '.1.3.6.1.4.1.2544.1.11.7.4.24.1.2', map => \%map_severity }, + timestamp => { oid => '.1.3.6.1.4.1.2544.1.11.7.4.24.1.4' }, + } + }, + alarmOpticalMuxTable => { + oid => '.1.3.6.1.4.1.2544.1.11.7.4.28', label => 'opticalmux', + mapping => { + severity => { oid => '.1.3.6.1.4.1.2544.1.11.7.4.28.1.2', map => \%map_severity }, + timestamp => { oid => '.1.3.6.1.4.1.2544.1.11.7.4.28.1.4' }, + } + }, + alarmShelfConnTable => { + oid => '.1.3.6.1.4.1.2544.1.11.7.4.34', label => 'shelfconn', + mapping => { + severity => { oid => '.1.3.6.1.4.1.2544.1.11.7.4.32.1.2', map => \%map_severity }, + timestamp => { oid => '.1.3.6.1.4.1.2544.1.11.7.4.32.1.4' }, + } + }, + alarmNtpIPv4Table => { + oid => '.1.3.6.1.4.1.2544.1.11.7.4.36', label => 'ntpipv4', + mapping => { + severity => { oid => '.1.3.6.1.4.1.2544.1.11.7.4.36.1.2', map => \%map_severity }, + timestamp => { oid => '.1.3.6.1.4.1.2544.1.11.7.4.36.1.4' }, + } + }, +}; + +sub manage_selection { + my ($self, %options) = @_; + + $self->{alarms}->{global} = { alarm => {} }; + my $get_oids = []; + foreach (keys %$oids) { + push @$get_oids, { oid => $oids->{$_}->{oid} }; + } + my $snmp_result = $options{snmp}->get_multiple_table(oids => $get_oids); + + my $last_time; + if (defined($self->{option_results}->{memory})) { + $self->{statefile_cache}->read(statefile => "cache_adva_" . $options{snmp}->get_hostname() . '_' . $options{snmp}->get_port(). '_' . $self->{mode}); + $last_time = $self->{statefile_cache}->get(name => 'last_time'); + } + + my ($i, $current_time) = (1, time()); + + foreach (keys %$oids) { + my $branch_oid = $oids->{$_}->{oid}; + next if (!defined($snmp_result->{$branch_oid})); + + foreach my $oid (keys %{$snmp_result->{$branch_oid}}) { + next if ($oid !~ /^$oids->{$_}->{mapping}->{severity}->{oid}\.(.*)\.(.*?)$/); + my $instance = $1 . '.' . $2; + my $type = defined($map_type{$2}) ? $map_type{$2} : 'unknown'; + my $result = $options{snmp}->map_instance(mapping => $oids->{$_}->{mapping}, results => $snmp_result->{$branch_oid}, instance => $instance); + + my @date = unpack 'n C6 a C2', $result->{timestamp}; + my $timezone = $self->{option_results}->{timezone}; + if (defined($date[7])) { + $timezone = sprintf("%s%02d%02d", $date[7], $date[8], $date[9]); + } + + my $dt = DateTime->new(year => $date[0], month => $date[1], day => $date[2], hour => $date[3], minute => $date[4], second => $date[5], + time_zone => $timezone); + + next if (defined($self->{option_results}->{memory}) && defined($last_time) && $last_time > $dt->epoch); + + my $diff_time = $current_time - $dt->epoch; + + $self->{alarms}->{global}->{alarm}->{$i} = { severity => $result->{severity}, + type => $type, since => $diff_time, + generation_time => centreon::plugins::misc::change_seconds(value => $diff_time), + label => $oids->{$_}->{label} + }; + $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<--warning-status> + +Set warning threshold for status (Default: '%{severity} =~ /warning|minor/i') +Can used special variables like: %{severity}, %{type}, %{label}, %{since} + +=item B<--critical-status> + +Set critical threshold for status (Default: '%{severity} =~ /critical|major/i'). +Can used special variables like: %{severity}, %{type}, %{label}, %{since} + +=item B<--timezone> + +Timezone options (the date from the equipment overload that option). Default is 'GMT'. + +=item B<--memory> + +Only check new alarms. + +=back + +=cut diff --git a/centreon-plugins/network/adva/fsp3000/snmp/mode/interfaces.pm b/centreon-plugins/network/adva/fsp3000/snmp/mode/interfaces.pm new file mode 100644 index 000000000..28cf7e380 --- /dev/null +++ b/centreon-plugins/network/adva/fsp3000/snmp/mode/interfaces.pm @@ -0,0 +1,360 @@ +# +# 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::adva::fsp3000::snmp::mode::interfaces; + +use base qw(snmp_standard::mode::interfaces); + +use strict; +use warnings; + +my $instance_mode; + +sub set_oids_traffic { + my ($self, %options) = @_; + + $self->{currentEthRx15minBytes} = '.1.3.6.1.4.1.2544.1.11.2.6.2.52.1.5'; # in B + $self->{currentEthRx1dayBytes} = '.1.3.6.1.4.1.2544.1.11.2.6.2.53.1.5'; # in B + $self->{currentEthTx15minBytes} = '.1.3.6.1.4.1.2544.1.11.2.6.2.56.1.3'; # in B + $self->{currentEthTx1dayBytes} = '.1.3.6.1.4.1.2544.1.11.2.6.2.57.1.3'; # in B + $self->{currentEthRxHighSpeed15minBytes} = '.1.3.6.1.4.1.2544.1.11.2.6.2.88.1.4'; # in B + $self->{currentEthRxHighSpeed1dayBytes} = '.1.3.6.1.4.1.2544.1.11.2.6.2.89.1.4'; # in B +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters} = { int => {}, global => {} }; + $self->{maps_counters}->{int}->{'030_traffic-in'} = { filter => 'add_traffic', + set => { + key_values => [ { name => 'traffic_in_15min', diff => 1 }, { name => 'traffic_in_1day', diff => 1 }, { name => 'speed_in'}, { name => 'display' } ], + per_second => 1, + closure_custom_calc => $self->can('custom_traffic_calc'), closure_custom_calc_extra_options => { label_ref => 'in' }, + closure_custom_output => $self->can('custom_traffic_output'), output_error_template => 'Traffic In : %s', + closure_custom_perfdata => $self->can('custom_traffic_perfdata'), + closure_custom_threshold_check => $self->can('custom_traffic_threshold'), + } + }; + $self->{maps_counters}->{int}->{'031_traffic-out'} = { filter => 'add_traffic', + set => { + key_values => [ { name => 'traffic_out_15min', diff => 1 }, { name => 'traffic_out_1day', diff => 1 }, { name => 'speed_out'}, { name => 'display' } ], + per_second => 1, + closure_custom_calc => $self->can('custom_traffic_calc'), closure_custom_calc_extra_options => { label_ref => 'out' }, + closure_custom_output => $self->can('custom_traffic_output'), output_error_template => 'Traffic Out : %s', + closure_custom_perfdata => $self->can('custom_traffic_perfdata'), + closure_custom_threshold_check => $self->can('custom_traffic_threshold'), + } + }; + $self->{maps_counters}->{int}->{'090_laser-temp'} = { filter => 'add_optical', + set => { + key_values => [ { name => 'laser_temp' }, { name => 'display' } ], + output_template => 'Laser Temperature : %.2f C', output_error_template => 'Laser Temperature : %.2f', + perfdatas => [ + { label => 'laser_temp', value => 'laser_temp_absolute', template => '%.2f', + unit => 'C', label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }; + $self->{maps_counters}->{int}->{'091_input-power'} = { filter => 'add_optical', + set => { + key_values => [ { name => 'input_power' }, { name => 'display' } ], + output_template => 'Input Power : %s dBm', output_error_template => 'Input Power : %s', + perfdatas => [ + { label => 'input_power', value => 'input_power_absolute', template => '%s', + unit => 'dBm', label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }; + $self->{maps_counters}->{int}->{'091_output-power'} = { filter => 'add_optical', + set => { + key_values => [ { name => 'output_power' }, { name => 'display' } ], + output_template => 'Output Power : %s dBm', output_error_template => 'Output Power : %s', + perfdatas => [ + { label => 'output_power', value => 'output_power_absolute', template => '%s', + unit => 'dBm', label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }; + + $self->SUPER::set_counters(%options); +} + +sub custom_traffic_perfdata { + my ($self, %options) = @_; + + my $extra_label = ''; + if (!defined($options{extra_instance}) || $options{extra_instance} != 0) { + $extra_label .= '_' . $self->{result_values}->{display}; + } + + my ($warning, $critical); + if ($instance_mode->{option_results}->{units_traffic} eq '%' && defined($self->{result_values}->{speed})) { + $warning = $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{label}, total => $self->{result_values}->{speed}, cast_int => 1); + $critical = $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{label}, total => $self->{result_values}->{speed}, cast_int => 1); + } elsif ($instance_mode->{option_results}->{units_traffic} eq 'b/s') { + $warning = $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{label}); + $critical = $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{label}); + } + + $self->{output}->perfdata_add(label => 'traffic_' . $self->{result_values}->{label} . $extra_label, unit => 'b/s', + value => sprintf("%.2f", $self->{result_values}->{traffic_per_seconds}), + warning => $warning, + critical => $critical, + min => 0, max => $self->{result_values}->{speed}); +} + +sub custom_traffic_threshold { + my ($self, %options) = @_; + + my $exit = 'ok'; + if ($instance_mode->{option_results}->{units_traffic} eq '%' && defined($self->{result_values}->{speed})) { + $exit = $self->{perfdata}->threshold_check(value => $self->{result_values}->{traffic_prct}, threshold => [ { label => 'critical-' . $self->{label}, exit_litteral => 'critical' }, { label => 'warning-' . $self->{label}, exit_litteral => 'warning' } ]); + } elsif ($instance_mode->{option_results}->{units_traffic} eq 'b/s') { + $exit = $self->{perfdata}->threshold_check(value => $self->{result_values}->{traffic_per_seconds}, threshold => [ { label => 'critical-' . $self->{label}, exit_litteral => 'critical' }, { label => 'warning-' . $self->{label}, exit_litteral => 'warning' } ]); + } + return $exit; +} + +sub custom_traffic_output { + my ($self, %options) = @_; + + my $label = $self->{result_values}->{label}; + $label =~ s/_/ /g; + $label =~ s/(\w+)/\u$1/g; + my ($traffic_value, $traffic_unit) = $self->{perfdata}->change_bytes(value => $self->{result_values}->{traffic_per_seconds}, network => 1); + my $msg = sprintf("Traffic %s : %s/s (%s)", + $label, $traffic_value . $traffic_unit, + defined($self->{result_values}->{traffic_prct}) ? sprintf("%.2f%%", $self->{result_values}->{traffic_prct}) : '-'); + return $msg; +} + +sub custom_traffic_calc { + my ($self, %options) = @_; + + return -10 if (defined($instance_mode->{last_status}) && $instance_mode->{last_status} == 0); + + # we choose the performance value (1day is updated every 15 minutes. 15min is updated all the time but reset every 15min + my $counter = 'traffic_' . $options{extra_options}->{label_ref} . '_15min'; + if ($options{delta_time} >= 600) { + $counter = 'traffic_' . $options{extra_options}->{label_ref} . '_1day'; + } + + my $diff_traffic = ($options{new_datas}->{$self->{instance} . '_' . $counter} - $options{old_datas}->{$self->{instance} . '_' . $counter}); + + $self->{result_values}->{traffic_per_seconds} = $diff_traffic / $options{delta_time}; + if (defined($options{new_datas}->{$self->{instance} . '_speed_' . $options{extra_options}->{label_ref}}) && + $options{new_datas}->{$self->{instance} . '_speed_' . $options{extra_options}->{label_ref}} > 0) { + $self->{result_values}->{traffic_prct} = $self->{result_values}->{traffic_per_seconds} * 100 / $options{new_datas}->{$self->{instance} . '_speed_' . $options{extra_options}->{label_ref}}; + $self->{result_values}->{speed} = $options{new_datas}->{$self->{instance} . '_speed_' . $options{extra_options}->{label_ref}}; + } + + $self->{result_values}->{label} = $options{extra_options}->{label_ref}; + $self->{result_values}->{display} = $options{new_datas}->{$self->{instance} . '_display'}; + return 0; +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options, no_set_traffic => 1, no_errors => 1, no_cast => 1); + bless $self, $class; + + $options{options}->add_options(arguments => + { + "add-optical" => { name => 'add_optical' }, + } + ); + + $instance_mode = $self; + return $self; +} + +my $oid_opticalIfDiagLaserTemp = '.1.3.6.1.4.1.2544.1.11.2.4.3.5.1.2'; +my $oid_opticalIfDiagInputPower = '.1.3.6.1.4.1.2544.1.11.2.4.3.5.1.3'; +my $oid_opticalIfDiagOutputPower = '.1.3.6.1.4.1.2544.1.11.2.4.3.5.1.4'; + +sub custom_load { + my ($self, %options) = @_; + + return if (!defined($self->{option_results}->{add_optical})); + + $self->{snmp}->load(oids => [$oid_opticalIfDiagLaserTemp, $oid_opticalIfDiagInputPower, $oid_opticalIfDiagOutputPower], + instances => $self->{array_interface_selected}); +} + +sub custom_add_result { + my ($self, %options) = @_; + + return if (!defined($self->{option_results}->{add_optical})); + $self->{interface_selected}->{$options{instance}}->{laser_temp} = undef; + if (defined($self->{results}->{$oid_opticalIfDiagLaserTemp . '.' . $options{instance}}) && + $self->{results}->{$oid_opticalIfDiagLaserTemp . '.' . $options{instance}} != -2147483648) { + $self->{interface_selected}->{$options{instance}}->{laser_temp} = $self->{results}->{$oid_opticalIfDiagLaserTemp . '.' . $options{instance}} * 0.1; + } + + $self->{interface_selected}->{$options{instance}}->{input_power} = undef; + if (defined($self->{results}->{$oid_opticalIfDiagInputPower . '.' . $options{instance}}) && + $self->{results}->{$oid_opticalIfDiagInputPower . '.' . $options{instance}} != -65535) { + $self->{interface_selected}->{$options{instance}}->{input_power} = $self->{results}->{$oid_opticalIfDiagInputPower . '.' . $options{instance}} / 10; + } + + $self->{interface_selected}->{$options{instance}}->{output_power} = undef; + if (defined($self->{results}->{$oid_opticalIfDiagOutputPower . '.' . $options{instance}}) && + $self->{results}->{$oid_opticalIfDiagOutputPower . '.' . $options{instance}} != -65535) { + $self->{interface_selected}->{$options{instance}}->{output_power} = $self->{results}->{$oid_opticalIfDiagOutputPower . '.' . $options{instance}} / 10; + } +} + +sub load_traffic { + my ($self, %options) = @_; + + if ($self->{snmp}->is_snmpv1()) { + $self->{output}->add_option_msg(short_msg => "Can't check SNMP 64 bits counters with SNMPv1."); + $self->{output}->option_exit(); + } + + $self->set_oids_traffic(); + $self->{snmp}->load(oids => [$self->{currentEthRx15minBytes}, $self->{currentEthRx1dayBytes}, + $self->{currentEthTx15minBytes}, $self->{currentEthTx1dayBytes}, + $self->{currentEthRxHighSpeed15minBytes}, $self->{currentEthRxHighSpeed1dayBytes}], instances => $self->{array_interface_selected}); +} + +sub add_result_traffic { + my ($self, %options) = @_; + + $self->{interface_selected}->{$options{instance}}->{traffic_in_15min} = + defined($self->{results}->{$self->{currentEthRxHighSpeed15minBytes} . '.' . $options{instance}}) ? $self->{results}->{$self->{currentEthRxHighSpeed15minBytes} . '.' . $options{instance}} * 8 : + (defined($self->{results}->{$self->{currentEthRx15minBytes} . '.' . $options{instance}}) ? $self->{results}->{$self->{currentEthRx15minBytes} . '.' . $options{instance}} * 8 : undef); + $self->{interface_selected}->{$options{instance}}->{traffic_in_1day} = + defined($self->{results}->{$self->{currentEthRxHighSpeed1dayBytes} . '.' . $options{instance}}) ? $self->{results}->{$self->{currentEthRxHighSpeed1dayBytes} . '.' . $options{instance}} * 8 : + (defined($self->{results}->{$self->{currentEthRx1dayBytes} . '.' . $options{instance}}) ? $self->{results}->{$self->{currentEthRx1dayBytes} . '.' . $options{instance}} * 8 : undef); + $self->{interface_selected}->{$options{instance}}->{traffic_out_15min} = + defined($self->{results}->{$self->{currentEthTx15minBytes} . '.' . $options{instance}}) ? $self->{results}->{$self->{currentEthTx15minBytes} . '.' . $options{instance}} * 8 : undef; + $self->{interface_selected}->{$options{instance}}->{traffic_out_1day} = + defined($self->{results}->{$self->{currentEthTx1dayBytes} . '.' . $options{instance}}) ? $self->{results}->{$self->{currentEthTx1dayBytes} . '.' . $options{instance}} * 8 : undef; + + $self->{interface_selected}->{$options{instance}}->{speed_in} = 0; + $self->{interface_selected}->{$options{instance}}->{speed_out} = 0; + if ($self->{get_speed} == 0) { + if (defined($self->{option_results}->{speed}) && $self->{option_results}->{speed} ne '') { + $self->{interface_selected}->{$options{instance}}->{speed_in} = $self->{option_results}->{speed} * 1000000; + $self->{interface_selected}->{$options{instance}}->{speed_out} = $self->{option_results}->{speed} * 1000000; + } + $self->{interface_selected}->{$options{instance}}->{speed_in} = $self->{option_results}->{speed_in} * 1000000 if (defined($self->{option_results}->{speed_in}) && $self->{option_results}->{speed_in} ne ''); + $self->{interface_selected}->{$options{instance}}->{speed_out} = $self->{option_results}->{speed_out} * 1000000 if (defined($self->{option_results}->{speed_out}) && $self->{option_results}->{speed_out} ne ''); + } +} + +1; + +__END__ + +=head1 MODE + +Check interfaces. + +=over 8 + +=item B<--add-status> + +Check interface status. + +=item B<--add-traffic> + +Check interface traffic. + +=item B<--add-optical> + +Check interface optical. + +=item B<--warning-status> + +Set warning threshold for status. +Can used special variables like: %{admstatus}, %{opstatus}, %{display} + +=item B<--critical-status> + +Set critical threshold for status (Default: '%{admstatus} eq "up" and %{opstatus} ne "up"'). +Can used special variables like: %{admstatus}, %{opstatus}, %{display} + +=item B<--warning-*> + +Threshold warning. +Can be: 'laser-temp', 'input-power', 'output-power', 'traffic-in', 'traffic-out'. + +=item B<--critical-*> + +Threshold critical. +Can be: 'laser-temp', 'input-power', 'output-power', 'traffic-in', 'traffic-out'. + +=item B<--units-traffic> + +Units of thresholds for the traffic (Default: '%') ('%', 'b/s'). + +=item B<--interface> + +Set the interface (number expected) ex: 1,2,... (empty means 'check all interface'). + +=item B<--name> + +Allows to use interface name with option --interface instead of interface oid index (Can be a regexp) + +=item B<--speed> + +Set interface speed for incoming/outgoing traffic (in Mb). + +=item B<--speed-in> + +Set interface speed for incoming traffic (in Mb). + +=item B<--speed-out> + +Set interface speed for outgoing traffic (in Mb). + +=item B<--reload-cache-time> + +Time in minutes before reloading cache file (default: 180). + +=item B<--oid-filter> + +Choose OID used to filter interface (default: ifName) (values: ifDesc, ifAlias, ifName). + +=item B<--oid-display> + +Choose OID used to display interface (default: ifName) (values: ifDesc, ifAlias, ifName). + +=item B<--oid-extra-display> + +Add an OID to display. + +=item B<--display-transform-src> + +Regexp src to transform display value. + +=item B<--display-transform-dst> + +Regexp dst to transform display value. + +=item B<--show-cache> + +Display cache interface datas. + +=back + +=cut diff --git a/centreon-plugins/network/adva/fsp3000/snmp/mode/listinterfaces.pm b/centreon-plugins/network/adva/fsp3000/snmp/mode/listinterfaces.pm new file mode 100644 index 000000000..5bf52fcd9 --- /dev/null +++ b/centreon-plugins/network/adva/fsp3000/snmp/mode/listinterfaces.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 network::adva::fsp3000::snmp::mode::listinterfaces; + +use base qw(snmp_standard::mode::listinterfaces); + +use strict; +use warnings; + +my $mapping = { + advaInventoryAidString => { oid => '.1.3.6.1.4.1.2544.1.11.7.10.1.1.6' }, + advaInventoryUnitName => { oid => '.1.3.6.1.4.1.2544.1.11.7.10.1.1.7' }, +}; + +sub set_oids_label { + my ($self, %options) = @_; + + $self->{oids_label} = { + 'ifdesc' => '.1.3.6.1.2.1.2.2.1.2', + 'ifalias' => '.1.3.6.1.2.1.31.1.1.1.18', + }; +} + +sub default_oid_filter_name { + my ($self, %options) = @_; + + return 'ifdesc'; +} + +sub default_oid_display_name { + my ($self, %options) = @_; + + return 'ifdesc'; +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + return $self; +} + +sub manage_selection { + my ($self, %options) = @_; + + $self->SUPER::manage_selection(%options); + + my $oid_advaInventoryEntry = '.1.3.6.1.4.1.2544.1.11.7.10.1.1'; + my $snmp_result = $self->{snmp}->get_table( + oid => $oid_advaInventoryEntry, + begin => $mapping->{advaInventoryAidString}->{oid}, + end => $mapping->{advaInventoryUnitName}->{oid} + ); + + $self->{extra_oids}->{type} = { oid => $mapping->{advaInventoryUnitName}->{oid}, matching => '%{instance}$' }; + $self->{results}->{ $self->{extra_oids}->{type} } = {}; + foreach my $oid (keys %{$snmp_result}) { + next if ($oid !~ /^$mapping->{advaInventoryUnitName}->{oid}\.(.*)$/); + my $instance = $1; + my $result = $self->{snmp}->map_instance(mapping => $mapping, results => $snmp_result, instance => $instance); + + next if ($result->{advaInventoryUnitName} !~ /^(SFP|XFP)/i); + + # interface name example: CH-1-3-N1 + # inventory name example: PL-1-3-N1 + next if ($result->{advaInventoryAidString} !~ /(\d+-\d+-[^\-]+)$/); + my $lookup = $1; + + foreach (sort @{$self->{interface_id_selected}}) { + my $display_value = $self->get_display_value(id => $_); + + if ($display_value =~ /CH-$lookup$/) { + $self->{results}->{ $self->{extra_oids}->{type}->{oid} }->{ $self->{extra_oids}->{type}->{oid} . '.' . $_ } = $result->{advaInventoryUnitName}; + } + } + } +} + +sub disco_format { + my ($self, %options) = @_; + + $self->{extra_oids}->{type} = { oid => $mapping->{advaInventoryUnitName}->{oid}, matching => '%{instance}$' }; + $self->SUPER::disco_format(%options); +} + +1; + +__END__ + +=head1 MODE + +=over 8 + +=item B<--interface> + +Set the interface (number expected) ex: 1,2,... (empty means 'check all interface'). + +=item B<--name> + +Allows to use interface name with option --interface instead of interface oid index (Can be a regexp) + +=item B<--speed> + +Set interface speed (in Mb). + +=item B<--skip-speed0> + +Don't display interface with speed 0. + +=item B<--filter-status> + +Display interfaces matching the filter (example: 'up'). + +=item B<--use-adminstatus> + +Display interfaces with AdminStatus 'up'. + +=item B<--oid-filter> + +Choose OID used to filter interface (default: ifDesc) (values: ifDesc, ifAlias). + +=item B<--oid-display> + +Choose OID used to display interface (default: ifDesc) (values: ifDesc, ifAlias). + +=item B<--display-transform-src> + +Regexp src to transform display value. (security risk!!!) + +=item B<--display-transform-dst> + +Regexp dst to transform display value. (security risk!!!) + +=item B<--add-extra-oid> + +Display an OID. +Example: --add-extra-oid='alias,.1.3.6.1.2.1.31.1.1.1.18' +or --add-extra-oid='vlan,.1.3.6.1.2.1.31.19,%{instance}\..*' + +=back + +=cut diff --git a/centreon-plugins/network/adva/fsp3000/snmp/plugin.pm b/centreon-plugins/network/adva/fsp3000/snmp/plugin.pm new file mode 100644 index 000000000..b6c4d32fa --- /dev/null +++ b/centreon-plugins/network/adva/fsp3000/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::adva::fsp3000::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}} = ( + 'alarms' => 'network::adva::fsp3000::snmp::mode::alarms', + 'interfaces' => 'network::adva::fsp3000::snmp::mode::interfaces', + 'list-interfaces' => 'network::adva::fsp3000::snmp::mode::listinterfaces', + 'memory' => 'snmp_standard::mode::memory', + 'uptime' => 'snmp_standard::mode::uptime', + ); + + return $self; +} + +1; + +__END__ + +=head1 PLUGIN DESCRIPTION + +Check Adva fsp3000 equipments in SNMP. + +=cut diff --git a/centreon-plugins/network/alcatel/isam/snmp/mode/hubsapusage.pm b/centreon-plugins/network/alcatel/isam/snmp/mode/hubsapusage.pm new file mode 100644 index 000000000..a089b7a92 --- /dev/null +++ b/centreon-plugins/network/alcatel/isam/snmp/mode/hubsapusage.pm @@ -0,0 +1,516 @@ +# +# 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::alcatel::isam::snmp::mode::hubsapusage; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; +use Digest::MD5 qw(md5_hex); +use centreon::plugins::statefile; + +my $instance_mode; + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'global', type => 0 }, + { name => 'sap', type => 1, cb_prefix_output => 'prefix_sap_output', message_multiple => 'All SAP are ok', skipped_code => { -10 => 1 } }, + ]; + + $self->{maps_counters}->{sap} = [ + { label => 'status', threshold => 0, set => { + key_values => [ { name => 'status' }, { name => 'admin' }, { 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 => 'in-traffic', set => { + key_values => [ { name => 'in', diff => 1 }, { name => 'display' } ], + per_second => 1, + closure_custom_calc => $self->can('custom_sap_calc'), closure_custom_calc_extra_options => { label_ref => 'in' }, + closure_custom_output => $self->can('custom_sap_output'), + closure_custom_perfdata => $self->can('custom_sap_perfdata'), + closure_custom_threshold_check => $self->can('custom_qsap_threshold'), + } + }, + { label => 'out-traffic', set => { + key_values => [ { name => 'out', diff => 1 }, { name => 'display' } ], + per_second => 1, + closure_custom_calc => $self->can('custom_sap_calc'), closure_custom_calc_extra_options => { label_ref => 'out' }, + closure_custom_output => $self->can('custom_sap_output'), + closure_custom_perfdata => $self->can('custom_sap_perfdata'), + closure_custom_threshold_check => $self->can('custom_sap_threshold'), + } + }, + ]; + + $self->{maps_counters}->{global} = [ + { label => 'total-in-traffic', set => { + key_values => [], + manual_keys => 1, per_second => 1, output_change_bytes => 2, + closure_custom_calc => $self->can('custom_total_traffic_calc'), closure_custom_calc_extra_options => { label_ref => 'in' }, + closure_custom_output => $self->can('custom_total_traffic_output'), + closure_custom_perfdata => $self->can('custom_total_traffic_perfdata'), + closure_custom_threshold_check => $self->can('custom_total_traffic_threshold'), + } + }, + { label => 'total-out-traffic', set => { + key_values => [], + manual_keys => 1, per_second => 1, output_change_bytes => 2, + closure_custom_calc => $self->can('custom_total_traffic_calc'), closure_custom_calc_extra_options => { label_ref => 'out' }, + closure_custom_output => $self->can('custom_total_traffic_output'), + closure_custom_perfdata => $self->can('custom_total_traffic_perfdata'), + closure_custom_threshold_check => $self->can('custom_total_traffic_threshold'), + } + }, + ]; +} + +sub custom_total_traffic_perfdata { + my ($self, %options) = @_; + + my ($warning, $critical); + if ($instance_mode->{option_results}->{units_traffic} eq '%' && defined($self->{result_values}->{speed})) { + $warning = $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{label}, total => $self->{result_values}->{speed}, cast_int => 1); + $critical = $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{label}, total => $self->{result_values}->{speed}, cast_int => 1); + } elsif ($instance_mode->{option_results}->{units_traffic} eq 'b/s') { + $warning = $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{label}); + $critical = $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{label}); + } + + $self->{output}->perfdata_add(label => 'total_traffic_' . $self->{result_values}->{label}, unit => 'b/s', + value => sprintf("%.2f", $self->{result_values}->{total_traffic}), + warning => $warning, + critical => $critical, + min => 0, max => $self->{result_values}->{speed}); +} + +sub custom_total_traffic_threshold { + my ($self, %options) = @_; + + my $exit = 'ok'; + if ($instance_mode->{option_results}->{units_traffic} eq '%' && defined($self->{result_values}->{speed})) { + $exit = $self->{perfdata}->threshold_check(value => $self->{result_values}->{traffic_prct}, threshold => [ { label => 'critical-' . $self->{label}, exit_litteral => 'critical' }, { label => 'warning-' . $self->{label}, exit_litteral => 'warning' } ]); + } elsif ($instance_mode->{option_results}->{units_traffic} eq 'b/s') { + $exit = $self->{perfdata}->threshold_check(value => $self->{result_values}->{total_traffic}, threshold => [ { label => 'critical-' . $self->{label}, exit_litteral => 'critical' }, { label => 'warning-' . $self->{label}, exit_litteral => 'warning' } ]); + } + return $exit; +} + +sub custom_total_traffic_output { + my ($self, %options) = @_; + + my ($traffic_value, $traffic_unit) = $self->{perfdata}->change_bytes(value => $self->{result_values}->{total_traffic}, network => 1); + my ($total_value, $total_unit); + if (defined($self->{result_values}->{speed}) && $self->{result_values}->{speed} =~ /[0-9]/) { + ($total_value, $total_unit) = $self->{perfdata}->change_bytes(value => $self->{result_values}->{speed}, network => 1); + } + + my $msg = sprintf("Total Traffic %s : %s/s (%s on %s)", + ucfirst($self->{result_values}->{label}), $traffic_value . $traffic_unit, + defined($self->{result_values}->{traffic_prct}) ? sprintf("%.2f%%", $self->{result_values}->{traffic_prct}) : '-', + defined($total_value) ? $total_value . $total_unit : '-'); + return $msg; +} + +sub custom_total_traffic_calc { + my ($self, %options) = @_; + + my $total_traffic = 0; + foreach (keys %{$options{new_datas}}) { + if (/^global_traffic_$options{extra_options}->{label_ref}_/) { + my $new_total = $options{new_datas}->{$_}; + next if (!defined($options{old_datas}->{$_})); + my $old_total = $options{old_datas}->{$_}; + + my $diff_traffic = $new_total - $old_total; + if ($diff_traffic < 0) { + $total_traffic += $old_total; + } else { + $total_traffic += $diff_traffic; + } + } + } + + $self->{result_values}->{label} = $options{extra_options}->{label_ref}; + $self->{result_values}->{total_traffic} = $total_traffic / $options{delta_time}; + if (defined($instance_mode->{option_results}->{'speed_total_' . $self->{result_values}->{label}}) && $instance_mode->{option_results}->{'speed_total_' . $self->{result_values}->{label}} =~ /[0-9]/) { + $self->{result_values}->{traffic_prct} = $self->{result_values}->{total_traffic} * 100 / ($instance_mode->{option_results}->{'speed_total_' . $self->{result_values}->{label}} * 1000 * 1000); + $self->{result_values}->{speed} = $instance_mode->{option_results}->{'speed_total_' . $self->{result_values}->{label}} * 1000 * 1000; + } + 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]; }; + + 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'; + } + + $instance_mode->{last_status} = 0; + if ($self->{result_values}->{admin} eq 'up') { + $instance_mode->{last_status} = 1; + } + }; + 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} . ' (admin: ' . $self->{result_values}->{admin} . ')'; + + return $msg; +} + +sub custom_status_calc { + my ($self, %options) = @_; + + $self->{result_values}->{admin} = $options{new_datas}->{$self->{instance} . '_admin'}; + $self->{result_values}->{status} = $options{new_datas}->{$self->{instance} . '_status'}; + $self->{result_values}->{display} = $options{new_datas}->{$self->{instance} . '_display'}; + return 0; +} + +sub custom_sap_perfdata { + my ($self, %options) = @_; + + my $extra_label = ''; + if (!defined($options{extra_instance}) || $options{extra_instance} != 0) { + $extra_label .= '_' . $self->{result_values}->{display}; + } + + my ($warning, $critical); + if ($instance_mode->{option_results}->{units_traffic} eq '%' && defined($self->{result_values}->{speed})) { + $warning = $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{label}, total => $self->{result_values}->{speed}, cast_int => 1); + $critical = $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{label}, total => $self->{result_values}->{speed}, cast_int => 1); + } elsif ($instance_mode->{option_results}->{units_traffic} eq 'b/s') { + $warning = $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{label}); + $critical = $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{label}); + } + + $self->{output}->perfdata_add(label => 'traffic_' . $self->{result_values}->{label} . $extra_label, unit => 'b/s', + value => sprintf("%.2f", $self->{result_values}->{traffic}), + warning => $warning, + critical => $critical, + min => 0, max => $self->{result_values}->{speed}); +} + +sub custom_sap_threshold { + my ($self, %options) = @_; + + my $exit = 'ok'; + if ($instance_mode->{option_results}->{units_traffic} eq '%' && defined($self->{result_values}->{speed})) { + $exit = $self->{perfdata}->threshold_check(value => $self->{result_values}->{traffic_prct}, threshold => [ { label => 'critical-' . $self->{label}, exit_litteral => 'critical' }, { label => 'warning-' . $self->{label}, exit_litteral => 'warning' } ]); + } elsif ($instance_mode->{option_results}->{units_traffic} eq 'b/s') { + $exit = $self->{perfdata}->threshold_check(value => $self->{result_values}->{traffic}, threshold => [ { label => 'critical-' . $self->{label}, exit_litteral => 'critical' }, { label => 'warning-' . $self->{label}, exit_litteral => 'warning' } ]); + } + return $exit; +} + +sub custom_sap_output { + my ($self, %options) = @_; + + my ($traffic_value, $traffic_unit) = $self->{perfdata}->change_bytes(value => $self->{result_values}->{traffic}, network => 1); + my ($total_value, $total_unit); + if (defined($self->{result_values}->{speed}) && $self->{result_values}->{speed} =~ /[0-9]/) { + ($total_value, $total_unit) = $self->{perfdata}->change_bytes(value => $self->{result_values}->{speed}, network => 1); + } + + my $msg = sprintf("Traffic %s : %s/s (%s on %s)", + ucfirst($self->{result_values}->{label}), $traffic_value . $traffic_unit, + defined($self->{result_values}->{traffic_prct}) ? sprintf("%.2f%%", $self->{result_values}->{traffic_prct}) : '-', + defined($total_value) ? $total_value . $total_unit : '-'); + return $msg; +} + +sub custom_sap_calc { + my ($self, %options) = @_; + + return -10 if (defined($instance_mode->{last_status}) && $instance_mode->{last_status} == 0); + $self->{result_values}->{label} = $options{extra_options}->{label_ref}; + $self->{result_values}->{display} = $options{new_datas}->{$self->{instance} . '_display'}; + $self->{result_values}->{traffic} = ($options{new_datas}->{$self->{instance} . '_' . $self->{result_values}->{label}} - $options{old_datas}->{$self->{instance} . '_' . $self->{result_values}->{label}}) / $options{delta_time}; + if (defined($instance_mode->{option_results}->{'speed_' . $self->{result_values}->{label}}) && $instance_mode->{option_results}->{'speed_' . $self->{result_values}->{label}} =~ /[0-9]/) { + $self->{result_values}->{traffic_prct} = $self->{result_values}->{traffic} * 100 / ($instance_mode->{option_results}->{'speed_' . $self->{result_values}->{label}} * 1000 * 1000); + $self->{result_values}->{speed} = $instance_mode->{option_results}->{'speed_' . $self->{result_values}->{label}} * 1000 * 1000; + } + 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 => + { + "reload-cache-time:s" => { name => 'reload_cache_time', default => 300 }, + "display-name:s" => { name => 'display_name', default => '%{SvcDescription}.%{IfName}.%{SapEncapName}' }, + "filter-name:s" => { name => 'filter_name' }, + "speed-in:s" => { name => 'speed_in' }, + "speed-out:s" => { name => 'speed_out' }, + "speed-total-in:s" => { name => 'speed_total_in' }, + "speed-total-out:s" => { name => 'speed_total_out' }, + "units-traffic:s" => { name => 'units_traffic', default => '%' }, + "warning-status:s" => { name => 'warning_status', default => '' }, + "critical-status:s" => { name => 'critical_status', default => '%{admin} =~ /up/i and %{status} !~ /up/i' }, + }); + + $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(); + $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 prefix_sap_output { + my ($self, %options) = @_; + + return "SAP '" . $options{instance_value}->{display} . "' "; +} + +sub get_display_name { + my ($self, %options) = @_; + + my $display_name = $self->{option_results}->{display_name}; + $display_name =~ s/%\{(.*?)\}/$options{$1}/ge; + return $display_name; +} + +my %map_admin = (1 => 'up', 2 => 'down'); +my %map_oper = (1 => 'up', 2 => 'down', 3 => 'ingressQosMismatch', + 4 => 'egressQosMismatch', 5 => 'portMtuTooSmall', 6 => 'svcAdminDown', + 7 => 'iesIfAdminDown' +); + +my $mapping = { + sapAdminStatus => { oid => '.1.3.6.1.4.1.6527.3.1.2.4.3.2.1.6', map => \%map_admin }, + sapOperStatus => { oid => '.1.3.6.1.4.1.6527.3.1.2.4.3.2.1.7', map => \%map_oper }, + fadSapStatsIngressOctets => { oid => '.1.3.6.1.4.1.637.61.1.85.17.2.2.1.2' }, + fadSapStatsEgressOctets => { oid => '.1.3.6.1.4.1.637.61.1.85.17.2.2.1.4' }, +}; + +my $oid_sapDescription = '.1.3.6.1.4.1.6527.3.1.2.4.3.2.1.5'; +my $oid_svcDescription = '.1.3.6.1.4.1.6527.3.1.2.4.2.2.1.6'; +my $oid_ifName = '.1.3.6.1.2.1.31.1.1.1.1'; + +sub reload_cache { + my ($self, %options) = @_; + + my $datas = { last_timestamp => time() }; + my $snmp_result = $options{snmp}->get_multiple_table(oids => [ + { oid => $oid_sapDescription }, + { oid => $oid_svcDescription }, + { oid => $oid_ifName }, + ], + nothing_quit => 1); + $datas->{snmp_result} = $snmp_result; + + if (scalar(keys %{$datas->{snmp_result}->{$oid_sapDescription}}) <= 0) { + $self->{output}->add_option_msg(short_msg => "Can't construct cache..."); + $self->{output}->option_exit(); + } + + $self->{statefile_cache}->write(data => $datas); +} + +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(); + } + + my $has_cache_file = $self->{statefile_cache}->read(statefile => 'cache_alcatel_isam_' . $options{snmp}->get_hostname() . '_' . $options{snmp}->get_port() . '_' . $self->{mode}); + my $timestamp_cache = $self->{statefile_cache}->get(name => 'last_timestamp'); + if ($has_cache_file == 0 || !defined($timestamp_cache) || + ((time() - $timestamp_cache) > (($self->{option_results}->{reload_cache_time}) * 60))) { + $self->reload_cache(%options); + $self->{statefile_cache}->read(); + } + + my $snmp_result = $self->{statefile_cache}->get(name => 'snmp_result'); + + $self->{global} = {}; + $self->{sap} = {}; + foreach my $oid (keys %{$snmp_result->{$oid_sapDescription}}) { + next if ($oid !~ /^$oid_sapDescription\.(.*?)\.(.*?)\.(.*?)$/); + # $SvcId and $SapEncapValue is the same. We use service table + my ($SvcId, $SapPortId, $SapEncapValue) = ($1, $2, $3); + my $instance = $SvcId . '.' . $SapPortId . '.' . $SapEncapValue; + + my $SapDescription = $snmp_result->{$oid_sapDescription}->{$oid} ne '' ? + $snmp_result->{$oid_sapDescription}->{$oid} : 'unknown'; + my $SvcDescription = defined($snmp_result->{$oid_svcDescription}->{$oid_svcDescription . '.' . $SvcId}) && $snmp_result->{$oid_svcDescription}->{$oid_svcDescription . '.' . $SvcId} ne '' ? + $snmp_result->{$oid_svcDescription}->{$oid_svcDescription . '.' . $SvcId} : $SvcId; + my $IfName = defined($snmp_result->{$oid_ifName}->{$oid_ifName . '.' . $SapPortId}) && $snmp_result->{$oid_ifName}->{$oid_ifName . '.' . $SapPortId} ne '' ? + $snmp_result->{$oid_ifName}->{$oid_ifName . '.' . $SapPortId} : $SapPortId; + my $SapEncapName = defined($snmp_result->{$oid_svcDescription}->{$oid_svcDescription . '.' . $SapEncapValue}) && $snmp_result->{$oid_svcDescription}->{$oid_svcDescription . '.' . $SapEncapValue} ne '' ? + $snmp_result->{$oid_svcDescription}->{$oid_svcDescription . '.' . $SapEncapValue} : $SapEncapValue; + + my $name = $self->get_display_name( + SapDescription => $SapDescription, + SvcDescription => $SvcDescription, + SapEncapName => $SapEncapName, + IfName => $IfName, + SvcId => $SvcId, + SapPortId => $SapPortId, + SapEncapValue => $SapEncapValue); + 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->{sap}->{$instance} = { display => $name }; + } + + $options{snmp}->load(oids => [$mapping->{fadSapStatsIngressOctets}->{oid}, + $mapping->{fadSapStatsEgressOctets}->{oid}, + $mapping->{sapAdminStatus}->{oid}, $mapping->{sapOperStatus}->{oid}], + instances => [keys %{$self->{sap}}], instance_regexp => '(\d+\.\d+\.\d+)$'); + $snmp_result = $options{snmp}->get_leef(nothing_quit => 1); + foreach (keys %{$self->{sap}}) { + my $result = $options{snmp}->map_instance(mapping => $mapping, results => $snmp_result, instance => $_); + $self->{sap}->{$_}->{in} = $result->{fadSapStatsIngressOctets} * 8; + $self->{sap}->{$_}->{out} = $result->{fadSapStatsEgressOctets} * 8; + $self->{sap}->{$_}->{status} = $result->{sapOperStatus}; + $self->{sap}->{$_}->{admin} = $result->{sapAdminStatus}; + + $self->{global}->{'traffic_in_' . $_} = $result->{fadSapStatsIngressOctets} * 8; + $self->{global}->{'traffic_out_' . $_} = $result->{fadSapStatsEgressOctets} * 8; + } + + if (scalar(keys %{$self->{sap}}) <= 0) { + $self->{output}->add_option_msg(short_msg => "No SAP found."); + $self->{output}->option_exit(); + } + + $self->{cache_name} = "alcatel_isam_" . $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 SAP QoS usage. + +=over 8 + +=item B<--display-name> + +Display name (Default: '%{SvcDescription}.%{IfName}.%{SapEncapName}'). +Can also be: %{SapDescription}, %{SapPortId} + +=item B<--filter-name> + +Filter by SAP name (can be a regexp). + +=item B<--speed-in> + +Set interface speed for incoming traffic (in Mb). + +=item B<--speed-out> + +Set interface speed for outgoing traffic (in Mb). + +=item B<--speed-total-in> + +Set interface speed for total incoming traffic (in Mb). + +=item B<--speed-total-out> + +Set interface speed for total outgoing traffic (in Mb). + +=item B<--units-traffic> + +Units of thresholds for the traffic (Default: '%') ('%', 'b/s'). + +=item B<--warning-status> + +Set warning threshold for ib status. +Can used special variables like: %{admin}, %{status}, %{display} + +=item B<--critical-status> + +Set critical threshold for ib status (Default: '%{admin} =~ /up/i and %{status} !~ /up/i'). +Can used special variables like: %{admin}, %{status}, %{display} + +=item B<--warning-*> + +Threshold warning. +Can be: 'total-in-traffic', 'total-out-traffic', 'in-traffic', 'out-traffic'. + +=item B<--critical-*> + +Threshold critical. +Can be: 'total-in-traffic', 'total-out-traffic', 'in-traffic', 'out-traffic'. + +=item B<--reload-cache-time> + +Time in seconds before reloading cache file (default: 300). + +=back + +=cut diff --git a/centreon-plugins/network/alcatel/isam/snmp/mode/listhubsap.pm b/centreon-plugins/network/alcatel/isam/snmp/mode/listhubsap.pm new file mode 100644 index 000000000..07e9f8805 --- /dev/null +++ b/centreon-plugins/network/alcatel/isam/snmp/mode/listhubsap.pm @@ -0,0 +1,148 @@ +# +# 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::alcatel::isam::snmp::mode::listhubsap; + +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); +} + +my %map_admin = (1 => 'up', 2 => 'down'); +my %map_oper = (1 => 'up', 2 => 'down', 3 => 'ingressQosMismatch', + 4 => 'egressQosMismatch', 5 => 'portMtuTooSmall', 6 => 'svcAdminDown', + 7 => 'iesIfAdminDown' +); +my $mapping = { + sapAdminStatus => { oid => '.1.3.6.1.4.1.6527.3.1.2.4.3.2.1.6', map => \%map_admin }, + sapOperStatus => { oid => '.1.3.6.1.4.1.6527.3.1.2.4.3.2.1.7', map => \%map_oper }, +}; +my $oid_sapDescription = '.1.3.6.1.4.1.6527.3.1.2.4.3.2.1.5'; +my $oid_svcDescription = '.1.3.6.1.4.1.6527.3.1.2.4.2.2.1.6'; +my $oid_sapBaseInfoEntry = '.1.3.6.1.4.1.6527.3.1.2.4.3.2.1'; +my $oid_ifName = '.1.3.6.1.2.1.31.1.1.1.1'; + +sub manage_selection { + my ($self, %options) = @_; + + $self->{sap} = {}; + my $snmp_result = $self->{snmp}->get_multiple_table(oids => [ + { oid => $oid_sapDescription }, + { oid => $oid_svcDescription }, + { oid => $oid_ifName }, + { oid => $oid_sapBaseInfoEntry, start => $mapping->{sapAdminStatus}->{oid}, end => $mapping->{sapOperStatus}->{oid} }, + ], nothing_quit => 1); + foreach my $oid (keys %{$snmp_result->{$oid_sapDescription}}) { + next if ($oid !~ /^$oid_sapDescription\.(.*?)\.(.*?)\.(.*?)$/); + my ($SvcId, $SapPortId, $SapEncapValue) = ($1, $2, $3); + + my $result = $self->{snmp}->map_instance(mapping => $mapping, results => $snmp_result->{ $oid_sapBaseInfoEntry }, instance => $SvcId . '.' . $SapPortId . '.' . $SapEncapValue); + $self->{sap}->{$SvcId . '.' . $SapPortId . '.' . $SapEncapValue} = { + SvcId => $SvcId, + SapPortId => $SapPortId, + SapEncapValue => $SapEncapValue, + IfName => defined($snmp_result->{$oid_ifName}->{$oid_ifName . '.' . $SapPortId}) && $snmp_result->{$oid_ifName}->{$oid_ifName . '.' . $SapPortId} ne '' ? + $snmp_result->{$oid_ifName}->{$oid_ifName . '.' . $SapPortId} : $SapPortId, + SapDescription => $snmp_result->{$oid_sapDescription}->{$oid} ne '' ? $snmp_result->{$oid_sapDescription}->{$oid} : 'unknown', + SvcDescription => defined($snmp_result->{$oid_svcDescription}->{$oid_svcDescription . '.' . $SvcId}) && $snmp_result->{$oid_svcDescription}->{$oid_svcDescription . '.' . $SvcId} ne '' ? + $snmp_result->{$oid_svcDescription}->{$oid_svcDescription . '.' . $SvcId} : $SvcId, + SapEncapName => defined($snmp_result->{$oid_svcDescription}->{$oid_svcDescription . '.' . $SapEncapValue}) && $snmp_result->{$oid_svcDescription}->{$oid_svcDescription . '.' . $SapEncapValue} ne '' ? + $snmp_result->{$oid_svcDescription}->{$oid_svcDescription . '.' . $SapEncapValue} : $SapEncapValue, + SapAdminStatus => $result->{sapAdminStatus}, + SapOperStatus => $result->{sapOperStatus}, + }; + } +} + +sub run { + my ($self, %options) = @_; + + $self->{snmp} = $options{snmp}; + $self->manage_selection(); + foreach my $instance (sort keys %{$self->{sap}}) { + my $msg = ''; + $self->{output}->output_add(long_msg => + "[SvcId = " . $self->{sap}->{$instance}->{SvcId} . "]" . + "[SapPortId = " . $self->{sap}->{$instance}->{SapPortId} . "]" . + "[SapEncapValue = " . $self->{sap}->{$instance}->{SapEncapValue} . "]" . + "[SapDescription = " . $self->{sap}->{$instance}->{SapDescription} . "]" . + "[SvcDescription = " . $self->{sap}->{$instance}->{SvcDescription} . "]" . + "[SapEncapName = " . $self->{sap}->{$instance}->{SapEncapName} . "]" . + "[SapAdminStatus = " . $self->{sap}->{$instance}->{SapAdminStatus} . "]" . + "[SapOperStatus = " . $self->{sap}->{$instance}->{SapOperStatus} . "]" . + "[IfName = " . $self->{sap}->{$instance}->{IfName} + ); + } + + $self->{output}->output_add(severity => 'OK', + short_msg => 'List SAP:'); + $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 => ['SvcId', 'SapPortId', 'SapEncapValue', 'SapDescription', + 'SvcDescription', 'SapEncapName', 'SapAdminStatus', 'SapOperStatus', 'IfName']); +} + +sub disco_show { + my ($self, %options) = @_; + $self->{snmp} = $options{snmp}; + + $self->manage_selection(disco => 1); + foreach my $instance (sort keys %{$self->{sap}}) { + $self->{output}->add_disco_entry(%{$self->{sap}->{$instance}}); + } +} + +1; + +__END__ + +=head1 MODE + +List SAP. + +=over 8 + +=back + +=cut + diff --git a/centreon-plugins/network/alcatel/isam/snmp/mode/vlantraffic.pm b/centreon-plugins/network/alcatel/isam/snmp/mode/vlantraffic.pm deleted file mode 100644 index 522888b28..000000000 --- a/centreon-plugins/network/alcatel/isam/snmp/mode/vlantraffic.pm +++ /dev/null @@ -1,337 +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 network::alcatel::isam::snmp::mode::vlantraffic; - -use base qw(centreon::plugins::mode); - -use strict; -use warnings; -use centreon::plugins::values; -use centreon::plugins::statefile; -use Digest::MD5 qw(md5_hex); - -my $maps_counters = { - vlan => { - '001_in' => { - set => { - key_values => [ { name => 'in', diff => 1 }, { name => 'display' } ], - output_template => 'In : %s %s/s', output_change_bytes => 2, - perfdatas => [ - { label => 'in', value => 'in_absolute', template => '%d', - unit => 'b/s', min => 0, label_extra_instance => 1, instance_use => 'display_absolute' }, - ], - }, - }, - '001_out' => { - set => { - key_values => [ { name => 'out', diff => 1 }, { name => 'display' } ], - output_template => 'Out : %s %s/s', output_change_bytes => 2, - perfdatas => [ - { label => 'out', value => 'out_absolute', template => '%d', - unit => 'b/s', 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 => - { - "no-component:s" => { name => 'no_component' }, - "filter-interface:s" => { name => 'filter_interface' }, - "filter-vlan:s" => { name => 'filter_vlan' }, - "show-cache" => { name => 'show_cache' }, - "reload-cache-time:s" => { name => 'reload_cache_time', default => 180 }, - }); - $self->{statefile_value} = centreon::plugins::statefile->new(%options); - $self->{statefile_cache} = centreon::plugins::statefile->new(%options); - - foreach my $key (('vlan')) { - 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 (('vlan')) { - foreach (keys %{$maps_counters->{$key}}) { - $maps_counters->{$key}->{$_}->{obj}->init(option_results => $self->{option_results}); - } - } - - if (defined($self->{option_results}->{no_component})) { - if ($self->{option_results}->{no_component} ne '') { - $self->{no_components} = $self->{option_results}->{no_component}; - } else { - $self->{no_components} = 'critical'; - } - } - - $self->{statefile_cache}->check_options(%options); - $self->{statefile_value}->check_options(%options); -} - -sub run { - my ($self, %options) = @_; - $self->{snmp} = $options{snmp}; - $self->{hostname} = $self->{snmp}->get_hostname(); - $self->{snmp_port} = $self->{snmp}->get_port(); - - $self->manage_selection(); - - my $multiple = 1; - if (scalar(keys %{$self->{vlan}}) == 1) { - $multiple = 0; - } - - if ($multiple == 1) { - $self->{output}->output_add(severity => 'OK', - short_msg => 'All VLAN usages are ok'); - } - $self->{new_datas} = {}; - $self->{statefile_value}->read(statefile => "alcatel_isam_" . $self->{hostname} . '_' . $self->{snmp_port} . '_' . $self->{mode} . '_' . - (defined($self->{option_results}->{filter_vlan}) ? md5_hex($self->{option_results}->{filter_vlan}) : md5_hex('all')) . '_' . - (defined($self->{option_results}->{filter_interface}) ? md5_hex($self->{option_results}->{filter_interface}) : md5_hex('all'))); - $self->{new_datas}->{last_timestamp} = time(); - - foreach my $id (sort keys %{$self->{vlan}}) { - my ($short_msg, $short_msg_append, $long_msg, $long_msg_append) = ('', '', '', ''); - my @exits = (); - foreach (sort keys %{$maps_counters->{vlan}}) { - my $obj = $maps_counters->{vlan}->{$_}->{obj}; - $obj->set(instance => $id); - - my ($value_check) = $obj->execute(values => $self->{vlan}->{$id}, - 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(extra_instance => $multiple); - } - - $self->{output}->output_add(long_msg => "VLAN '$self->{vlan}->{$id}->{display}' Traffic $long_msg"); - my $exit = $self->{output}->get_most_critical(status => [ @exits ]); - if (!$self->{output}->is_status(litteral => 1, value => $exit, compare => 'ok')) { - $self->{output}->output_add(severity => $exit, - short_msg => "VLAN '$self->{vlan}->{$id}->{display}' Traffic $short_msg" - ); - } - - if ($multiple == 0) { - $self->{output}->output_add(short_msg => "VLAN '$self->{vlan}->{$id}->{display}' Traffic $long_msg"); - } - } - - $self->{statefile_value}->write(data => $self->{new_datas}); - $self->{output}->display(); - $self->{output}->exit(); -} - -my $oid_extendVlanStaticName = '.1.3.6.1.4.1.637.61.1.31.2.4.1.6'; -my $oid_extendPortVlanVlanIndex = '.1.3.6.1.4.1.637.61.1.31.2.12.1.1'; -my $oid_dot1dBasePortIfIndex = '.1.3.6.1.2.1.17.1.4.1.2'; -my $oid_ifDescr = '.1.3.6.1.2.1.2.2.1.2'; -my $oid_extendPortVlanCurrent1DayUpFwdByteCounter = '.1.3.6.1.4.1.637.61.1.31.9.3.1.5'; -my $oid_extendPortVlanCurrent1DayDnFwdByteCounter = '.1.3.6.1.4.1.637.61.1.31.9.3.1.7'; - -sub reload_cache { - my ($self) = @_; - my $datas = {}; - - my $result = $self->{snmp}->get_multiple_table(oids => [ - { oid => $oid_extendVlanStaticName }, - { oid => $oid_extendPortVlanVlanIndex }, - { oid => $oid_dot1dBasePortIfIndex }, - { oid => $oid_ifDescr }, - ], nothing_quit => 1); - $result->{last_timestamp} = time(); - - if (scalar(keys %{$result->{$oid_extendVlanStaticName}}) <= 0) { - $self->{output}->add_option_msg(short_msg => "Can't construct cache..."); - $self->{output}->option_exit(); - } - - $self->{statefile_cache}->write(data => $result); -} - -sub get_big_counter { - my ($self, %options) = @_; - - my $hex = unpack('H*', $options{value}); - $hex =~ /^(.){8}(.){8}$/; - return (hex($1) << 32) + hex($2); -} - -sub manage_selection { - my ($self, %options) = @_; - - # init cache file - my $has_cache_file = $self->{statefile_cache}->read(statefile => 'cache_alcatel_isam_' . $self->{hostname} . '_' . $self->{snmp_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(); - } - - my $timestamp_cache = $self->{statefile_cache}->get(name => 'last_timestamp'); - if ($has_cache_file == 0 || - !defined($timestamp_cache) || ((time() - $timestamp_cache) > (($self->{option_results}->{reload_cache_time}) * 60))) { - $self->reload_cache(); - $self->{statefile_cache}->read(); - } - - $self->{vlan} = {}; - my $value = $self->{statefile_cache}->get(name => $oid_extendVlanStaticName); - my $port_vlan_result = $self->{statefile_cache}->get(name => $oid_extendPortVlanVlanIndex); - my $dot1base_result = $self->{statefile_cache}->get(name => $oid_dot1dBasePortIfIndex); - my $ifdescr_result = $self->{statefile_cache}->get(name => $oid_ifDescr); - foreach ($self->{snmp}->oid_lex_sort(keys %{$value})) { - /^$oid_extendVlanStaticName\.(.*)$/; - my $vlan_index = $1; - my $vlan_name = $value->{$_}; - if (defined($self->{option_results}->{filter_vlan}) && $self->{option_results}->{filter_vlan} ne '' && - $vlan_name !~ /$self->{option_results}->{filter_vlan}/) { - $self->{output}->output_add(long_msg => "Skipping '" . $vlan_name . "': no matching filter.", debug => 1); - next; - } - # we look for the interface description - #extendPortVlanVlanIndex.(dot1dBasePort).(VlanIndex) - foreach ($self->{snmp}->oid_lex_sort(keys %{$port_vlan_result})) { - next if ($_ !~ /^$oid_extendPortVlanVlanIndex\.(\d+)\.$vlan_index$/); - my $dot1dBasePort = $1; - next if (!defined($dot1base_result->{$oid_dot1dBasePortIfIndex . '.' . $dot1dBasePort})); - my $ifIndex = $dot1base_result->{$oid_dot1dBasePortIfIndex . '.' . $dot1dBasePort}; - next if (!defined($ifdescr_result->{$oid_ifDescr . '.' . $ifIndex})); - - my $ifDescr = $ifdescr_result->{$oid_ifDescr . '.' . $ifIndex}; - if (defined($self->{option_results}->{filter_interface}) && $self->{option_results}->{filter_interface} ne '' && - $ifDescr !~ /$self->{option_results}->{filter_interface}/) { - $self->{output}->output_add(long_msg => "Skipping '" . $ifDescr . "': no matching filter.", debug => 1); - next; - } - - $self->{snmp}->load(oids => [$oid_extendPortVlanCurrent1DayUpFwdByteCounter, $oid_extendPortVlanCurrent1DayDnFwdByteCounter], - instances => [$dot1dBasePort . '.' . $vlan_index], instance_regexp => '(.*)'); - } - - $self->{vlan}->{$vlan_index} = { display => $vlan_name, in => 0, out => 0 }; - } - - $self->{results} = $self->{snmp}->get_leef(); - - foreach (keys %{$self->{results}}) { - next if ($_ !~ /^$oid_extendPortVlanCurrent1DayUpFwdByteCounter\.(\d+)\.(\d+)$/); - my $vlan_index = $2; - - my $in = defined($self->{results}->{$oid_extendPortVlanCurrent1DayDnFwdByteCounter . '.' . $1 . '.' . $vlan_index}) ? - $self->get_big_counter(value => $self->{results}->{$oid_extendPortVlanCurrent1DayDnFwdByteCounter . '.' . $1 . '.' . $vlan_index}) : 0; - my $out = defined($self->{results}->{$_}) ? - $self->get_big_counter(value => $self->{results}->{$_}) : 0; - - $self->{vlan}->{$vlan_index}->{in} += $in * 8; - $self->{vlan}->{$vlan_index}->{out} += $out * 8; - } - - if (scalar(keys %{$self->{vlan}}) <= 0) { - $self->{output}->output_add(severity => defined($self->{no_components}) ? $self->{no_components} : 'unknown', - short_msg => 'No components are checked.'); - } -} - -1; - -__END__ - -=head1 MODE - -Check traffic by VLAN. - -=over 8 - -=item B<--filter-vlan> - -Filter by vlan name (regexp can be used). - -=item B<--filter-interface> - -Filter by interface description (regexp can be used). - -=item B<--warning-*> - -Threshold warning. -Can be: 'cac-usage' (%), 'conference-usage' (%). - -=item B<--critical-*> - -Threshold critical. -Can be: 'cac-usage' (%), 'conference-usage' (%). - -=item B<--no-component> - -Set the threshold where no components (Default: 'unknown' returns). - -=item B<--reload-cache-time> - -Time in minutes before reloading cache file (default: 180). - -=item B<--show-cache> - -Display cache datas. - -=back - -=cut diff --git a/centreon-plugins/network/alcatel/isam/snmp/plugin.pm b/centreon-plugins/network/alcatel/isam/snmp/plugin.pm index c066bb53e..0709ec2e9 100644 --- a/centreon-plugins/network/alcatel/isam/snmp/plugin.pm +++ b/centreon-plugins/network/alcatel/isam/snmp/plugin.pm @@ -34,9 +34,10 @@ sub new { 'cpu' => 'network::alcatel::isam::snmp::mode::cpu', 'hardware' => 'network::alcatel::isam::snmp::mode::hardware', 'interfaces' => 'snmp_standard::mode::interfaces', + 'list-hub-sap' => 'network::alcatel::isam::snmp::mode::listhubsap', 'list-interfaces' => 'snmp_standard::mode::listinterfaces', 'memory' => 'network::alcatel::isam::snmp::mode::memory', - 'vlan-traffic' => 'network::alcatel::isam::snmp::mode::vlantraffic', + 'hub-sap-usage' => 'network::alcatel::isam::snmp::mode::hubsapusage', ); return $self; diff --git a/centreon-plugins/network/alcatel/pss/1830/snmp/mode/sapqosstats.pm b/centreon-plugins/network/alcatel/pss/1830/snmp/mode/sapqosstats.pm index 7b6ef96dd..963f497bd 100644 --- a/centreon-plugins/network/alcatel/pss/1830/snmp/mode/sapqosstats.pm +++ b/centreon-plugins/network/alcatel/pss/1830/snmp/mode/sapqosstats.pm @@ -25,6 +25,7 @@ use base qw(centreon::plugins::templates::counter); use strict; use warnings; use Digest::MD5 qw(md5_hex); +use centreon::plugins::statefile; my $instance_mode; @@ -37,38 +38,50 @@ sub set_counters { $self->{maps_counters}->{sap} = [ { label => 'status', threshold => 0, set => { - key_values => [ { name => 'status' }, { name => 'admin' }, { name => 'display' } ], + key_values => [ { name => 'tnSapOperStatus' }, { name => 'tnSapAdminStatus' }, { 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 => 'in-traffic', set => { - key_values => [ { name => 'in', diff => 1 }, { name => 'display' } ], - per_second => 1, - closure_custom_calc => $self->can('custom_qos_calc'), closure_custom_calc_extra_options => { label_ref => 'in' }, - closure_custom_output => $self->can('custom_qos_output'), - closure_custom_perfdata => $self->can('custom_qos_perfdata'), - closure_custom_threshold_check => $self->can('custom_qos_threshold'), - } - }, - { label => 'out-traffic', set => { - key_values => [ { name => 'out', diff => 1 }, { name => 'display' } ], - per_second => 1, - closure_custom_calc => $self->can('custom_qos_calc'), closure_custom_calc_extra_options => { label_ref => 'out' }, - closure_custom_output => $self->can('custom_qos_output'), - closure_custom_perfdata => $self->can('custom_qos_perfdata'), - closure_custom_threshold_check => $self->can('custom_qos_threshold'), - } - }, - { label => 'in-drop-packets', set => { - key_values => [ { name => 'in_dropped_packets', diff => 1 }, { name => 'display' } ], - closure_custom_calc => $self->can('custom_qos_drop_calc'), - output_template => 'In Dropped Packets : %s', + { label => 'traffic-in-below-cir', set => { + key_values => [ { name => 'tnSapBaseStatsIngressQchipForwardedInProfOctets', diff => 1 }, { name => 'display' } ], + per_second => 1, output_change_bytes => 2, + output_template => 'Traffic In Below CIR : %s %s/s', perfdatas => [ - { label => 'in_drop_packets', value => 'in_dropped_packets_absolute', template => '%s', - min => 0, label_extra_instance => 1, instance_use => 'display' }, + { label => 'traffic_in_below_cir', value => 'tnSapBaseStatsIngressQchipForwardedInProfOctets_per_second', template => '%.2f', + min => 0, unit => 'b/s', label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + { label => 'traffic-in-above-cir', set => { + key_values => [ { name => 'tnSapBaseStatsIngressQchipForwardedOutProfOctets', diff => 1 }, { name => 'display' } ], + per_second => 1, output_change_bytes => 2, + output_template => 'Traffic In Above CIR : %s %s/s', + perfdatas => [ + { label => 'traffic_in_above_cir', value => 'tnSapBaseStatsIngressQchipForwardedOutProfOctets_per_second', template => '%.2f', + min => 0, unit => 'b/s', label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + { label => 'traffic-out-below-cir', set => { + key_values => [ { name => 'tnSapBaseStatsEgressQchipForwardedInProfOctets', diff => 1 }, { name => 'display' } ], + per_second => 1, output_change_bytes => 2, + output_template => 'Traffic Out Below CIR : %s %s/s', + perfdatas => [ + { label => 'traffic_out_below_cir', value => 'tnSapBaseStatsEgressQchipForwardedInProfOctets_per_second', template => '%.2f', + min => 0, unit => 'b/s', label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + { label => 'traffic-out-above-cir', set => { + key_values => [ { name => 'tnSapBaseStatsEgressQchipForwardedOutProfOctets', diff => 1 }, { name => 'display' } ], + per_second => 1, output_change_bytes => 2, + output_template => 'Traffic Out Above CIR : %s %s/s', + perfdatas => [ + { label => 'traffic_out_above_cir', value => 'tnSapBaseStatsEgressQchipForwardedOutProfOctets_per_second', template => '%.2f', + min => 0, unit => 'b/s', label_extra_instance => 1, instance_use => 'display_absolute' }, ], } }, @@ -116,87 +129,12 @@ sub custom_status_output { sub custom_status_calc { my ($self, %options) = @_; - $self->{result_values}->{admin} = $options{new_datas}->{$self->{instance} . '_admin'}; - $self->{result_values}->{status} = $options{new_datas}->{$self->{instance} . '_status'}; + $self->{result_values}->{admin} = $options{new_datas}->{$self->{instance} . '_tnSapAdminStatus'}; + $self->{result_values}->{status} = $options{new_datas}->{$self->{instance} . '_tnSapOperStatus'}; $self->{result_values}->{display} = $options{new_datas}->{$self->{instance} . '_display'}; return 0; } -sub custom_qos_perfdata { - my ($self, %options) = @_; - - my $extra_label = ''; - if (!defined($options{extra_instance}) || $options{extra_instance} != 0) { - $extra_label .= '_' . $self->{result_values}->{display}; - } - - my ($warning, $critical); - if ($instance_mode->{option_results}->{units_traffic} eq '%' && defined($self->{result_values}->{speed})) { - $warning = $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{label}, total => $self->{result_values}->{speed}, cast_int => 1); - $critical = $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{label}, total => $self->{result_values}->{speed}, cast_int => 1); - } elsif ($instance_mode->{option_results}->{units_traffic} eq 'b/s') { - $warning = $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{label}); - $critical = $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{label}); - } - - $self->{output}->perfdata_add(label => 'traffic_' . $self->{result_values}->{label} . $extra_label, unit => 'b/s', - value => sprintf("%.2f", $self->{result_values}->{traffic}), - warning => $warning, - critical => $critical, - min => 0, max => $self->{result_values}->{speed}); -} - -sub custom_qos_threshold { - my ($self, %options) = @_; - - my $exit = 'ok'; - if ($instance_mode->{option_results}->{units_traffic} eq '%' && defined($self->{result_values}->{speed})) { - $exit = $self->{perfdata}->threshold_check(value => $self->{result_values}->{traffic_prct}, threshold => [ { label => 'critical-' . $self->{label}, exit_litteral => 'critical' }, { label => 'warning-' . $self->{label}, exit_litteral => 'warning' } ]); - } elsif ($instance_mode->{option_results}->{units_traffic} eq 'b/s') { - $exit = $self->{perfdata}->threshold_check(value => $self->{result_values}->{traffic}, threshold => [ { label => 'critical-' . $self->{label}, exit_litteral => 'critical' }, { label => 'warning-' . $self->{label}, exit_litteral => 'warning' } ]); - } - return $exit; -} - -sub custom_qos_output { - my ($self, %options) = @_; - - my ($traffic_value, $traffic_unit) = $self->{perfdata}->change_bytes(value => $self->{result_values}->{traffic}, network => 1); - my ($total_value, $total_unit); - if (defined($self->{result_values}->{speed}) && $self->{result_values}->{speed} =~ /[0-9]/) { - ($total_value, $total_unit) = $self->{perfdata}->change_bytes(value => $self->{result_values}->{speed}, network => 1); - } - - my $msg = sprintf("Traffic %s : %s/s (%s on %s)", - ucfirst($self->{result_values}->{label}), $traffic_value . $traffic_unit, - defined($self->{result_values}->{traffic_prct}) ? sprintf("%.2f%%", $self->{result_values}->{traffic_prct}) : '-', - defined($total_value) ? $total_value . $total_unit : '-'); - return $msg; -} - -sub custom_qos_calc { - my ($self, %options) = @_; - - return -10 if (defined($instance_mode->{last_status}) && $instance_mode->{last_status} == 0); - $self->{result_values}->{label} = $options{extra_options}->{label_ref}; - $self->{result_values}->{display} = $options{new_datas}->{$self->{instance} . '_display'}; - $self->{result_values}->{traffic} = ($options{new_datas}->{$self->{instance} . '_' . $self->{result_values}->{label}} - $options{old_datas}->{$self->{instance} . '_' . $self->{result_values}->{label}}) / $options{delta_time}; - if (defined($instance_mode->{option_results}->{'speed_' . $self->{result_values}->{label}}) && $instance_mode->{option_results}->{'speed_' . $self->{result_values}->{label}} =~ /[0-9]/) { - $self->{result_values}->{traffic_prct} = $self->{result_values}->{traffic} * 100 / ($instance_mode->{option_results}->{'speed_' . $self->{result_values}->{label}} * 1000 * 1000); - $self->{result_values}->{speed} = $instance_mode->{option_results}->{'speed_' . $self->{result_values}->{label}} * 1000 * 1000; - } - return 0; -} - -sub custom_qos_drop_calc { - my ($self, %options) = @_; - - return -10 if (defined($instance_mode->{last_status}) && $instance_mode->{last_status} == 0); - $self->{result_values}->{display} = $options{new_datas}->{$self->{instance} . '_display'}; - $self->{result_values}->{in_dropped_packets_absolute} = $options{new_datas}->{$self->{instance} . '_in_dropped_packets'} - $options{old_datas}->{$self->{instance} . '_in_dropped_packets'}; - return 0; -} - sub new { my ($class, %options) = @_; my $self = $class->SUPER::new(package => __PACKAGE__, %options, statefile => 1); @@ -204,16 +142,15 @@ sub new { $self->{version} = '1.0'; $options{options}->add_options(arguments => - { + { + "reload-cache-time:s" => { name => 'reload_cache_time', default => 300 }, "display-name:s" => { name => 'display_name', default => '%{SysSwitchId}.%{SvcId}.%{SapPortId}.%{SapEncapValue}' }, "filter-name:s" => { name => 'filter_name' }, - "speed-in:s" => { name => 'speed_in' }, - "speed-out:s" => { name => 'speed_out' }, - "units-traffic:s" => { name => 'units_traffic', default => '%' }, "warning-status:s" => { name => 'warning_status', default => '' }, "critical-status:s" => { name => 'critical_status', default => '%{admin} =~ /up/i and %{status} !~ /up/i' }, }); + $self->{statefile_cache} = centreon::plugins::statefile->new(%options); return $self; } @@ -223,6 +160,7 @@ sub check_options { $instance_mode = $self; $self->change_macros(); + $self->{statefile_cache}->check_options(%options); } sub change_macros { @@ -258,14 +196,34 @@ my %map_oper = (1 => 'up', 2 => 'down', 3 => 'ingressQosMismatch', my $mapping = { tnSapAdminStatus => { oid => '.1.3.6.1.4.1.7483.6.1.2.4.3.2.1.6', map => \%map_admin }, tnSapOperStatus => { oid => '.1.3.6.1.4.1.7483.6.1.2.4.3.2.1.7', map => \%map_oper }, - tnSapBaseStatsIngressForwardedOctets => { oid => '.1.3.6.1.4.1.7483.7.2.2.2.8.1.1.1.4' }, - tnSapBaseStatsEgressForwardedOctets => { oid => '.1.3.6.1.4.1.7483.7.2.2.2.8.1.1.1.6' }, - tnSapBaseStatsIngressDroppedPackets => { oid => '.1.3.6.1.4.1.7483.7.2.2.2.8.1.1.1.9' }, + tnSapBaseStatsIngressQchipForwardedInProfOctets => { oid => '.1.3.6.1.4.1.7483.6.1.2.4.3.6.1.12' }, + tnSapBaseStatsIngressQchipForwardedOutProfOctets => { oid => '.1.3.6.1.4.1.7483.6.1.2.4.3.6.1.14' }, + tnSapBaseStatsEgressQchipForwardedInProfOctets => { oid => '.1.3.6.1.4.1.7483.6.1.2.4.3.6.1.20' }, + tnSapBaseStatsEgressQchipForwardedOutProfOctets => { oid => '.1.3.6.1.4.1.7483.6.1.2.4.3.6.1.22' }, }; my $oid_tnSapDescription = '.1.3.6.1.4.1.7483.6.1.2.4.3.2.1.5'; my $oid_tnSvcName = '.1.3.6.1.4.1.7483.6.1.2.4.2.2.1.28'; +sub reload_cache { + my ($self, %options) = @_; + + my $datas = { last_timestamp => time() }; + my $snmp_result = $options{snmp}->get_multiple_table(oids => [ + { oid => $oid_tnSapDescription }, + { oid => $oid_tnSvcName }, + ], + nothing_quit => 1); + $datas->{snmp_result} = $snmp_result; + + if (scalar(keys %{$datas->{snmp_result}->{$oid_tnSapDescription}}) <= 0) { + $self->{output}->add_option_msg(short_msg => "Can't construct cache..."); + $self->{output}->option_exit(); + } + + $self->{statefile_cache}->write(data => $datas); +} + sub manage_selection { my ($self, %options) = @_; @@ -274,13 +232,15 @@ sub manage_selection { $self->{output}->option_exit(); } - # SNMP Get is slow for Dropped, Ingress, Egress. So we are doing in 2 times. - $self->{sap} = {}; - my $snmp_result = $options{snmp}->get_multiple_table(oids => [ - { oid => $oid_tnSapDescription }, - { oid => $oid_tnSvcName }, - ], - nothing_quit => 1); + my $has_cache_file = $self->{statefile_cache}->read(statefile => 'cache_alcatel_pss1830_' . $options{snmp}->get_hostname() . '_' . $options{snmp}->get_port() . '_' . $self->{mode}); + my $timestamp_cache = $self->{statefile_cache}->get(name => 'last_timestamp'); + if ($has_cache_file == 0 || !defined($timestamp_cache) || + ((time() - $timestamp_cache) > (($self->{option_results}->{reload_cache_time}) * 60))) { + $self->reload_cache(%options); + $self->{statefile_cache}->read(); + } + + my $snmp_result = $self->{statefile_cache}->get(name => 'snmp_result'); foreach my $oid (keys %{$snmp_result->{$oid_tnSapDescription}}) { next if ($oid !~ /^$oid_tnSapDescription\.(.*?)\.(.*?)\.(.*?)\.(.*?)$/); @@ -301,18 +261,23 @@ sub manage_selection { $self->{sap}->{$instance} = { display => $name }; } - $options{snmp}->load(oids => [$mapping->{tnSapBaseStatsIngressForwardedOctets}->{oid}, - $mapping->{tnSapBaseStatsEgressForwardedOctets}->{oid}, $mapping->{tnSapBaseStatsIngressDroppedPackets}->{oid}, + $options{snmp}->load(oids => [$mapping->{tnSapBaseStatsIngressQchipForwardedInProfOctets}->{oid}, + $mapping->{tnSapBaseStatsIngressQchipForwardedOutProfOctets}->{oid}, $mapping->{tnSapBaseStatsEgressQchipForwardedInProfOctets}->{oid}, + $mapping->{tnSapBaseStatsEgressQchipForwardedOutProfOctets}->{oid}, $mapping->{tnSapAdminStatus}->{oid}, $mapping->{tnSapOperStatus}->{oid}], instances => [keys %{$self->{sap}}], instance_regexp => '(\d+\.\d+\.\d+\.\d+)$'); $snmp_result = $options{snmp}->get_leef(nothing_quit => 1); foreach (keys %{$self->{sap}}) { my $result = $options{snmp}->map_instance(mapping => $mapping, results => $snmp_result, instance => $_); - $self->{sap}->{$_}->{in} = $result->{tnSapBaseStatsIngressForwardedOctets} * 8; - $self->{sap}->{$_}->{out} = $result->{tnSapBaseStatsEgressForwardedOctets} * 8; - $self->{sap}->{$_}->{in_dropped_packets} = $result->{tnSapBaseStatsIngressDroppedPackets}; - $self->{sap}->{$_}->{status} = $result->{tnSapAdminStatus}; - $self->{sap}->{$_}->{admin} = $result->{tnSapOperStatus}; + + foreach my $name (('tnSapBaseStatsIngressQchipForwardedInProfOctets', 'tnSapBaseStatsIngressQchipForwardedOutProfOctets', + 'tnSapBaseStatsEgressQchipForwardedInProfOctets', 'tnSapBaseStatsEgressQchipForwardedOutProfOctets')) { + $result->{$name} *= 8 if (defined($result->{$name})); + } + + foreach my $name (keys %$mapping) { + $self->{sap}->{$_}->{$name} = $result->{$name} if (defined($result->{$name})); + } } if (scalar(keys %{$self->{sap}}) <= 0) { @@ -344,18 +309,6 @@ Can also be: %{SapDescription}, %{SvcName} Filter by SAP name (can be a regexp). -=item B<--speed-in> - -Set interface speed for incoming traffic (in Mb). - -=item B<--speed-out> - -Set interface speed for outgoing traffic (in Mb). - -=item B<--units-traffic> - -Units of thresholds for the traffic (Default: '%') ('%', 'b/s'). - =item B<--warning-status> Set warning threshold for ib status. @@ -369,12 +322,16 @@ Can used special variables like: %{admin}, %{status}, %{display} =item B<--warning-*> Threshold warning. -Can be: 'in-traffic', 'out-traffic', 'in-drop-packets'. +Can be: 'traffic-in-above-cir', 'traffic-in-below-cir', 'traffic-out-above-cir', 'traffic-out-below-cir'. =item B<--critical-*> Threshold critical. -Can be: 'in-traffic', 'out-traffic', 'in-drop-packets'. +Can be: 'traffic-in-above-cir', 'traffic-in-below-cir', 'traffic-out-above-cir', 'traffic-out-below-cir'. + +=item B<--reload-cache-time> + +Time in seconds before reloading cache file (default: 300). =back diff --git a/centreon-plugins/network/audiocodes/snmp/mode/listtrunks.pm b/centreon-plugins/network/audiocodes/snmp/mode/listtrunks.pm new file mode 100644 index 000000000..8f3c81185 --- /dev/null +++ b/centreon-plugins/network/audiocodes/snmp/mode/listtrunks.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 network::audiocodes::snmp::mode::listtrunks; + +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 => + { + }); + $self->{trunks} = {}; + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::init(%options); +} + +my %map_deactivate = (0 => 'notAvailable', 1 => 'deActivated', 2 => 'activated'); +my %map_alarm = (0 => 'greyDisabled', 1 => 'greenActive', 2 => 'redLosLof', +3 => 'blueAis', 4 => 'yellowRai', 5 => 'orangeDChannel', 6 => 'purpleLowerLayerDown', 7 => 'darkOrangeNFASAlarm'); + +my $mapping = { + acTrunkStatusAlarm => { oid => '.1.3.6.1.4.1.5003.9.10.9.2.1.1.1.7', map => \%map_alarm }, + acTrunkDeactivate => { oid => '.1.3.6.1.4.1.5003.9.10.9.1.1.1.1.1.11', map => \%map_deactivate }, + acTrunkName => { oid => '.1.3.6.1.4.1.5003.9.10.9.1.1.1.1.1.13' }, +}; + +sub manage_selection { + my ($self, %options) = @_; + + my $snmp_result = $options{snmp}->get_multiple_table(oids => [ + { oid => $mapping->{acTrunkStatusAlarm}->{oid} }, + { oid => $mapping->{acTrunkDeactivate}->{oid} }, + { oid => $mapping->{acTrunkName}->{oid} }, + ], + return_type => 1, nothing_quit => 1); + + foreach my $oid (keys %{$snmp_result}) { + next if ($oid !~ /^$mapping->{acTrunkName}->{oid}\.(.*)$/); + my $instance = $1; + my $result = $options{snmp}->map_instance(mapping => $mapping, results => $snmp_result, instance => $instance); + + if (!defined($result->{acTrunkName}) || $result->{acTrunkName} eq '') { + $self->{output}->output_add(long_msg => "skipping instance '" . $instance . "': no name defined.", debug => 1); + next; + } + + $self->{trunks}->{$instance} = + { name => $result->{acTrunkName}, status => $result->{acTrunkStatusAlarm}, state => $result->{acTrunkDeactivate} }; + } +} + +sub run { + my ($self, %options) = @_; + + $self->manage_selection(%options); + foreach my $instance (sort keys %{$self->{trunks}}) { + $self->{output}->output_add(long_msg => '[name = ' . $self->{trunks}->{$instance}->{name} . + "] [status = '" . $self->{trunks}->{$instance}->{status} . "'] [state = '" . + $self->{trunks}->{$instance}->{state} . "']" + ); + } + + $self->{output}->output_add(severity => 'OK', + short_msg => 'List trunks:'); + $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', 'status', 'state']); +} + +sub disco_show { + my ($self, %options) = @_; + + $self->manage_selection(%options); + foreach my $instance (sort keys %{$self->{trunks}}) { + $self->{output}->add_disco_entry(name => $self->{trunks}->{$instance}->{name}, + status => $self->{trunks}->{$instance}->{status}, state => $self->{trunks}->{$instance}->{state}); + } +} + +1; + +__END__ + +=head1 MODE + +List trunks. + +=over 8 + +=back + +=cut + diff --git a/centreon-plugins/network/audiocodes/snmp/mode/trunkstatus.pm b/centreon-plugins/network/audiocodes/snmp/mode/trunkstatus.pm index 8d2d5cf1b..bd4b172f5 100644 --- a/centreon-plugins/network/audiocodes/snmp/mode/trunkstatus.pm +++ b/centreon-plugins/network/audiocodes/snmp/mode/trunkstatus.pm @@ -123,8 +123,9 @@ sub new { $self->{version} = '1.0'; $options{options}->add_options(arguments => { - "warning-status:s" => { name => 'warning_status', default => '' }, - "critical-status:s" => { name => 'critical_status', default => '%{state} =~ /activated/ and %{alarm} !~ /greenActive/i' }, + "filter-name:s" => { name => 'filter_name' }, + "warning-status:s" => { name => 'warning_status', default => '' }, + "critical-status:s" => { name => 'critical_status', default => '%{state} =~ /activated/ and %{alarm} !~ /greenActive/i' }, }); return $self; @@ -197,8 +198,15 @@ sub manage_selection { my $result = $options{snmp}->map_instance(mapping => $mapping->{status}, results => $datas->{status}, instance => $instance); my $result2 = $options{snmp}->map_instance(mapping => $mapping->{usage}, results => $datas->{usage}, instance => $instance . '.0'); + my $display = defined($result->{acTrunkName}) && $result->{acTrunkName} ne '' ? $result->{acTrunkName} : $instance; + if (defined($self->{option_results}->{filter_name}) && $self->{option_results}->{filter_name} ne '' && + $display !~ /$self->{option_results}->{filter_name}/) { + $self->{output}->output_add(long_msg => "skipping '" . $display . "': no matching filter.", debug => 1); + next; + } + $self->{trunk}->{$instance} = { - display => defined($result->{acTrunkName}) && $result->{acTrunkName} ne '' ? $result->{acTrunkName} : $instance, + display => $display, alarm => $result->{acTrunkStatusAlarm}, state => $result->{acTrunkDeactivate}, dchannel => $result->{acTrunkStatusDChannel}, @@ -211,7 +219,8 @@ sub manage_selection { } $self->{cache_name} = "audiocodes_" . $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_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; @@ -224,6 +233,10 @@ Check trunk status. =over 8 +=item B<--filter-name> + +Filter by name (can be a regexp). + =item B<--warning-status> Set warning threshold for status. diff --git a/centreon-plugins/network/audiocodes/snmp/plugin.pm b/centreon-plugins/network/audiocodes/snmp/plugin.pm index d77abafc2..f34fc0b63 100644 --- a/centreon-plugins/network/audiocodes/snmp/plugin.pm +++ b/centreon-plugins/network/audiocodes/snmp/plugin.pm @@ -35,6 +35,7 @@ sub new { 'hardware' => 'network::audiocodes::snmp::mode::hardware', 'interfaces' => 'snmp_standard::mode::interfaces', 'list-interfaces' => 'snmp_standard::mode::listinterfaces', + 'list-trunks' => 'network::audiocodes::snmp::mode::listtrunks', 'memory' => 'network::audiocodes::snmp::mode::memory', 'trunk-status' => 'network::audiocodes::snmp::mode::trunkstatus', ); diff --git a/centreon-plugins/network/checkpoint/snmp/mode/components/raiddisk.pm b/centreon-plugins/network/checkpoint/snmp/mode/components/raiddisk.pm index 5762c7b74..075d070ec 100644 --- a/centreon-plugins/network/checkpoint/snmp/mode/components/raiddisk.pm +++ b/centreon-plugins/network/checkpoint/snmp/mode/components/raiddisk.pm @@ -28,23 +28,31 @@ my %map_states_disk = ( 0 => 'online', 1 => 'missing', 2 => 'not_compatible', - 3 => 'failed', + 3 => 'disc_failed', 4 => 'initializing', 5 => 'offline_requested', 6 => 'failed_requested', + 7 => 'unconfigured_good_spun_up', + 8 => 'unconfigured_good_spun_down', + 9 => 'unconfigured_bad', + 10 => 'hotspare', + 11 => 'drive_offline', + 12 => 'rebuild', + 13 => 'failed', + 14 => 'copyback', 255 => 'other_offline', ); my $mapping = { raidDiskProductID => { oid => '.1.3.6.1.4.1.2620.1.6.7.7.2.1.6' }, - raidDiskSyncState => { oid => '.1.3.6.1.4.1.2620.1.6.7.7.2.1.11', map => \%map_states_disk }, + raidDiskState => { oid => '.1.3.6.1.4.1.2620.1.6.7.7.2.1.9', map => \%map_states_disk }, }; sub load { my ($self) = @_; push @{$self->{request}}, { oid => $mapping->{raidDiskProductID}->{oid} }, - { oid => $mapping->{raidDiskSyncState}->{oid} }; + { oid => $mapping->{raidDiskState}->{oid} }; } sub check { @@ -57,19 +65,20 @@ sub check { foreach my $oid ($self->{snmp}->oid_lex_sort(keys %{$self->{results}->{$mapping->{raidDiskProductID}->{oid}}})) { $oid =~ /^$mapping->{raidDiskProductID}->{oid}\.(.*)$/; my $instance = $1; - my $result = $self->{snmp}->map_instance(mapping => $mapping, results => $self->{results}->{$mapping->{raidDiskSyncState}->{oid}}, instance => $instance); + my $result = $self->{snmp}->map_instance(mapping => $mapping, results => + $self->{results}->{$mapping->{raidDiskState}->{oid}}, instance => $instance); next if ($self->check_filter(section => 'raiddisk', instance => $instance)); my $name = centreon::plugins::misc::trim($self->{results}->{$mapping->{raidDiskProductID}->{oid}}->{$oid}); $self->{components}->{raiddisk}->{total}++; $self->{output}->output_add(long_msg => sprintf("raid disk '%s' status is '%s'", - $name, $result->{raidDiskSyncState})); - my $exit = $self->get_severity(section => 'raiddisk', value => $result->{raidDiskSyncState}); + $name, $result->{raidDiskState})); + my $exit = $self->get_severity(section => 'raiddisk', value => $result->{raidDiskState}); if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { $self->{output}->output_add(severity => $exit, short_msg => sprintf("Raid disk '%s' status is '%s'", - $name, $result->{raidDiskSyncState})); + $name, $result->{raidDiskState})); } } } diff --git a/centreon-plugins/network/checkpoint/snmp/mode/hardware.pm b/centreon-plugins/network/checkpoint/snmp/mode/hardware.pm index 575a49779..f411012f4 100644 --- a/centreon-plugins/network/checkpoint/snmp/mode/hardware.pm +++ b/centreon-plugins/network/checkpoint/snmp/mode/hardware.pm @@ -51,16 +51,25 @@ sub set_system { psu => [ ['up', 'OK'], ['down', 'CRITICAL'], + ['dummy', 'OK'], ['.*', 'UNKNOWN'], ], raiddisk => [ ['online', 'OK'], ['missing', 'OK'], ['not_compatible', 'CRITICAL'], - ['failed', 'CRITICAL'], + ['disc_failed', 'CRITICAL'], ['initializing', 'OK'], ['offline_requested', 'OK'], ['failed_requested', 'OK'], + ['unconfigured_good_spun_up', 'WARNING'], + ['unconfigured_good_spun_down', 'WARNING'], + ['unconfigured_bad', 'CRITICAL'], + ['hotspare', 'OK'], + ['drive_offline', 'WARNING'], + ['rebuild', 'WARNING'], + ['failed', 'CRITICAL'], + ['copyback', 'WARNING'], ['other_offline', 'WARNING'], ['.*', 'UNKNOWN'], ], diff --git a/centreon-plugins/network/cisco/meraki/cloudcontroller/snmp/mode/deviceusage.pm b/centreon-plugins/network/cisco/meraki/cloudcontroller/snmp/mode/deviceusage.pm index 05730c43d..29e028b2b 100644 --- a/centreon-plugins/network/cisco/meraki/cloudcontroller/snmp/mode/deviceusage.pm +++ b/centreon-plugins/network/cisco/meraki/cloudcontroller/snmp/mode/deviceusage.pm @@ -24,6 +24,7 @@ use base qw(centreon::plugins::templates::counter); use strict; use warnings; +use Digest::MD5 qw(md5_hex); my $instance_mode; @@ -66,12 +67,79 @@ sub custom_status_calc { return 0; } +sub custom_traffic_perfdata { + my ($self, %options) = @_; + + my $extra_label = ''; + if (!defined($options{extra_instance}) || $options{extra_instance} != 0) { + $extra_label .= '_' . $self->{result_values}->{display}; + } + + my ($warning, $critical); + if ($instance_mode->{option_results}->{units_traffic} eq '%' && defined($self->{result_values}->{speed})) { + $warning = $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{label}, total => $self->{result_values}->{speed}, cast_int => 1); + $critical = $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{label}, total => $self->{result_values}->{speed}, cast_int => 1); + } elsif ($instance_mode->{option_results}->{units_traffic} eq 'b/s') { + $warning = $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{label}); + $critical = $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{label}); + } + + $self->{output}->perfdata_add(label => 'traffic_' . $self->{result_values}->{label} . $extra_label, unit => 'b/s', + value => sprintf("%.2f", $self->{result_values}->{traffic}), + warning => $warning, + critical => $critical, + min => 0, max => $self->{result_values}->{speed}); +} + +sub custom_traffic_threshold { + my ($self, %options) = @_; + + my $exit = 'ok'; + if ($instance_mode->{option_results}->{units_traffic} eq '%' && defined($self->{result_values}->{speed})) { + $exit = $self->{perfdata}->threshold_check(value => $self->{result_values}->{traffic_prct}, threshold => [ { label => 'critical-' . $self->{label}, exit_litteral => 'critical' }, { label => 'warning-' . $self->{label}, exit_litteral => 'warning' } ]); + } elsif ($instance_mode->{option_results}->{units_traffic} eq 'b/s') { + $exit = $self->{perfdata}->threshold_check(value => $self->{result_values}->{traffic}, threshold => [ { label => 'critical-' . $self->{label}, exit_litteral => 'critical' }, { label => 'warning-' . $self->{label}, exit_litteral => 'warning' } ]); + } + return $exit; +} + +sub custom_traffic_output { + my ($self, %options) = @_; + + my ($traffic_value, $traffic_unit) = $self->{perfdata}->change_bytes(value => $self->{result_values}->{traffic}, network => 1); + my ($total_value, $total_unit); + if (defined($self->{result_values}->{speed}) && $self->{result_values}->{speed} =~ /[0-9]/) { + ($total_value, $total_unit) = $self->{perfdata}->change_bytes(value => $self->{result_values}->{speed}, network => 1); + } + + my $msg = sprintf("Traffic %s : %s/s (%s on %s)", + ucfirst($self->{result_values}->{label}), $traffic_value . $traffic_unit, + defined($self->{result_values}->{traffic_prct}) ? sprintf("%.2f%%", $self->{result_values}->{traffic_prct}) : '-', + defined($total_value) ? $total_value . $total_unit : '-'); + return $msg; +} + +sub custom_traffic_calc { + my ($self, %options) = @_; + + $self->{result_values}->{label} = $options{extra_options}->{label_ref}; + $self->{result_values}->{display} = $options{new_datas}->{$self->{instance} . '_display'}; + my $diff_traffic = $options{new_datas}->{$self->{instance} . '_' . $self->{result_values}->{label}} - $options{old_datas}->{$self->{instance} . '_' . $self->{result_values}->{label}}; + $self->{result_values}->{traffic} = $diff_traffic / $options{delta_time}; + if (defined($instance_mode->{option_results}->{'speed_' . $self->{result_values}->{label}}) && $instance_mode->{option_results}->{'speed_' . $self->{result_values}->{label}} =~ /[0-9]/) { + $self->{result_values}->{traffic_prct} = $self->{result_values}->{traffic} * 100 / ($instance_mode->{option_results}->{'speed_' . $self->{result_values}->{label}} * 1000 * 1000); + $self->{result_values}->{speed} = $instance_mode->{option_results}->{'speed_' . $self->{result_values}->{label}} * 1000 * 1000; + } + return 0; +} + sub set_counters { my ($self, %options) = @_; $self->{maps_counters_type} = [ { name => 'global', type => 0 }, - { name => 'device', type => 1, cb_prefix_output => 'prefix_device_output', message_multiple => 'All devices are ok' } + { name => 'device', type => 1, cb_prefix_output => 'prefix_device_output', message_multiple => 'All devices are ok' }, + { name => 'interface', type => 1, cb_prefix_output => 'prefix_interface_output', message_multiple => 'All device interfaces are ok', skipped_code => { -10 => 1 } }, ]; $self->{maps_counters}->{global} = [ { label => 'total-devices', set => { @@ -103,19 +171,44 @@ sub set_counters { } }, ]; + + $self->{maps_counters}->{interface} = [ + { label => 'in', set => { + key_values => [ { name => 'in', diff => 1 }, { name => 'display' } ], + per_second => 1, + closure_custom_calc => $self->can('custom_traffic_calc'), closure_custom_calc_extra_options => { label_ref => 'in' }, + closure_custom_output => $self->can('custom_traffic_output'), + closure_custom_perfdata => $self->can('custom_traffic_perfdata'), + closure_custom_threshold_check => $self->can('custom_traffic_threshold'), + } + }, + { label => 'out', set => { + key_values => [ { name => 'out', diff => 1 }, { name => 'display' } ], + per_second => 1, + closure_custom_calc => $self->can('custom_traffic_calc'), closure_custom_calc_extra_options => { label_ref => 'out' }, + closure_custom_output => $self->can('custom_traffic_output'), + closure_custom_perfdata => $self->can('custom_traffic_perfdata'), + closure_custom_threshold_check => $self->can('custom_traffic_threshold'), + } + }, + ]; } 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 => { "filter-name:s" => { name => 'filter_name' }, + "filter-interface:s" => { name => 'filter_interface' }, "warning-status:s" => { name => 'warning_status', default => '' }, "critical-status:s" => { name => 'critical_status', default => '%{status} =~ /offline/' }, + "speed-in:s" => { name => 'speed_in' }, + "speed-out:s" => { name => 'speed_out' }, + "units-traffic:s" => { name => 'units_traffic', default => '%' }, }); return $self; @@ -135,6 +228,12 @@ sub prefix_device_output { return "Device '" . $options{instance_value}->{display} . "' "; } +sub prefix_interface_output { + my ($self, %options) = @_; + + return "Interface '" . $options{instance_value}->{display} . "' "; +} + sub change_macros { my ($self, %options) = @_; @@ -154,29 +253,80 @@ my $mapping = { devStatus => { oid => '.1.3.6.1.4.1.29671.1.1.4.1.3', map => \%map_status }, devClientCount => { oid => '.1.3.6.1.4.1.29671.1.1.4.1.5' }, }; -my $oid_devEntry = '.1.3.6.1.4.1.29671.1.1.4.1'; +my $mapping2 = { + devInterfaceName => { oid => '.1.3.6.1.4.1.29671.1.1.5.1.3' }, + devInterfaceSentBytes => { oid => '.1.3.6.1.4.1.29671.1.1.5.1.6' }, + devInterfaceRecvBytes => { oid => '.1.3.6.1.4.1.29671.1.1.5.1.7' }, +}; sub manage_selection { my ($self, %options) = @_; $self->{device} = {}; + $self->{interface} = {}; $self->{global} = { total => 0 }; - my $results = $options{snmp}->get_table(oid => $oid_devEntry, nothing_quit => 1); - foreach my $oid (keys %{$results}) { - next if ($oid !~ /^$mapping->{devName}->{oid}\.(.*)$/); + + my $snmp_result = $options{snmp}->get_multiple_table(oids => + [ { oid => $mapping->{devName}->{oid} }, + { oid => $mapping2->{devInterfaceName}->{oid} }, + ], nothing_quit => 1); + + foreach my $oid (keys %{$snmp_result->{ $mapping->{devName}->{oid} }}) { + $oid =~ /^$mapping->{devName}->{oid}\.(.*)$/; my $instance = $1; - my $result = $options{snmp}->map_instance(mapping => $mapping, results => $results, instance => $instance); + my $dev_name = $snmp_result->{$mapping->{devName}->{oid}}->{$oid}; if (defined($self->{option_results}->{filter_name}) && $self->{option_results}->{filter_name} ne '' && - $result->{devName} !~ /$self->{option_results}->{filter_name}/) { - $self->{output}->output_add(long_msg => "skipping '" . $result->{devName} . "': no matching filter.", debug => 1); + $dev_name !~ /$self->{option_results}->{filter_name}/) { + $self->{output}->output_add(long_msg => "skipping device '" . $dev_name . "': no matching filter.", debug => 1); next; } + foreach (keys %{$snmp_result->{ $mapping2->{devInterfaceName}->{oid} }}) { + next if (!/^$mapping2->{devInterfaceName}->{oid}\.$instance\.(.*)/); + + my $index = $1; + my $interface_name = $snmp_result->{ $mapping2->{devInterfaceName}->{oid} }->{$_}; + if (defined($self->{option_results}->{filter_interface}) && $self->{option_results}->{filter_interface} ne '' && + $interface_name !~ /$self->{option_results}->{filter_interface}/) { + $self->{output}->output_add(long_msg => "skipping interface '" . $dev_name . '.' . $interface_name . "': no matching filter.", debug => 1); + next; + } + + $self->{interface}->{$instance . '.' . $index} = { display => $dev_name . '.' . $interface_name }; + } + $self->{global}->{total}++; - $self->{device}->{$instance} = { display => $result->{devName}, - status => $result->{devStatus}, - clients => $result->{devClientCount}}; + $self->{device}->{$instance} = { display => $dev_name }; } + + if (scalar(keys %{$self->{interface}}) > 0) { + $options{snmp}->load(oids => [$mapping2->{devInterfaceSentBytes}->{oid}, $mapping2->{devInterfaceRecvBytes}->{oid}], + instances => [keys %{$self->{interface}}], instance_regexp => '^(.*)$'); + $snmp_result = $options{snmp}->get_leef(nothing_quit => 1); + foreach (keys %{$self->{interface}}) { + my $result = $options{snmp}->map_instance(mapping => $mapping2, results => $snmp_result, instance => $_); + + $self->{interface}->{$_}->{in} = $result->{devInterfaceRecvBytes} * 8; + $self->{interface}->{$_}->{out} = $result->{devInterfaceSentBytes} * 8; + } + } + + if (scalar(keys %{$self->{device}}) > 0) { + $options{snmp}->load(oids => [$mapping->{devStatus}->{oid}, $mapping->{devClientCount}->{oid}], + instances => [keys %{$self->{device}}], instance_regexp => '^(.*)$'); + $snmp_result = $options{snmp}->get_leef(nothing_quit => 1); + foreach (keys %{$self->{device}}) { + my $result = $options{snmp}->map_instance(mapping => $mapping, results => $snmp_result, instance => $_); + + $self->{device}->{$_}->{status} = $result->{devStatus}; + $self->{device}->{$_}->{clients} = $result->{devClientCount}; + } + } + + $self->{cache_name} = "cisco_meraki_" . $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')) . '_' . + (defined($self->{option_results}->{filter_interface}) ? md5_hex($self->{option_results}->{filter_interface}) : md5_hex('all')); } 1; @@ -198,6 +348,22 @@ Example: --filter-counters='^clients$' Filter device name (can be a regexp). +=item B<--filter-interface> + +Filter interface name (can be a regexp). + +=item B<--speed-in> + +Set interface speed for incoming traffic (in Mb). + +=item B<--speed-out> + +Set interface speed for outgoing traffic (in Mb). + +=item B<--units-traffic> + +Units of thresholds for the traffic (Default: '%') ('%', 'b/s'). + =item B<--warning-status> Set warning threshold for status. @@ -211,12 +377,12 @@ Can used special variables like: %{status}, %{display} =item B<--warning-*> Threshold warning. -Can be: 'total-devices', 'clients'. +Can be: 'total-devices', 'clients', 'in', 'out'. =item B<--critical-*> Threshold critical. -Can be: 'total-devices', 'clients'. +Can be: 'total-devices', 'clients', 'in', 'out'. =back diff --git a/centreon-plugins/network/citrix/netscaler/snmp/mode/vserverstatus.pm b/centreon-plugins/network/citrix/netscaler/snmp/mode/vserverstatus.pm index 95c88e03c..aa5a0584a 100644 --- a/centreon-plugins/network/citrix/netscaler/snmp/mode/vserverstatus.pm +++ b/centreon-plugins/network/citrix/netscaler/snmp/mode/vserverstatus.pm @@ -262,9 +262,9 @@ sub manage_selection { foreach (keys %{$self->{vservers}}) { my $result = $options{snmp}->map_instance(mapping => $mapping2, results => $snmp_result, instance => $_); - $self->{vservers}->{$_}->{in} = (defined($result->{vsvrTotalResponseBytes}) ? $result->{vsvrTotalResponseBytes} * 8 : + $self->{vservers}->{$_}->{out} = (defined($result->{vsvrTotalResponseBytes}) ? $result->{vsvrTotalResponseBytes} * 8 : (($result->{vsvrTotalResponseBytesHigh} << 32) + $result->{vsvrTotalResponseBytesLow})) * 8; - $self->{vservers}->{$_}->{out} = (defined($result->{vsvrTotalRequestBytes}) ? $result->{vsvrTotalRequestBytes} * 8 : + $self->{vservers}->{$_}->{in} = (defined($result->{vsvrTotalRequestBytes}) ? $result->{vsvrTotalRequestBytes} * 8 : (($result->{vsvrTotalRequestBytesHigh} << 32) + $result->{vsvrTotalRequestBytesLow})) * 8; $self->{vservers}->{$_}->{health} = $result->{vsvrHealth}; $self->{vservers}->{$_}->{clients} = $result->{vsvrTotalClients}; diff --git a/centreon-plugins/network/digi/standard/snmp/mode/cpu.pm b/centreon-plugins/network/digi/sarian/snmp/mode/cpu.pm similarity index 98% rename from centreon-plugins/network/digi/standard/snmp/mode/cpu.pm rename to centreon-plugins/network/digi/sarian/snmp/mode/cpu.pm index cde764c13..361539fc6 100644 --- a/centreon-plugins/network/digi/standard/snmp/mode/cpu.pm +++ b/centreon-plugins/network/digi/sarian/snmp/mode/cpu.pm @@ -18,7 +18,7 @@ # limitations under the License. # -package network::digi::standard::snmp::mode::cpu; +package network::digi::sarian::snmp::mode::cpu; use base qw(centreon::plugins::mode); diff --git a/centreon-plugins/network/digi/standard/snmp/mode/gprs.pm b/centreon-plugins/network/digi/sarian/snmp/mode/gprs.pm similarity index 99% rename from centreon-plugins/network/digi/standard/snmp/mode/gprs.pm rename to centreon-plugins/network/digi/sarian/snmp/mode/gprs.pm index 3fe9e6738..31491dfb1 100644 --- a/centreon-plugins/network/digi/standard/snmp/mode/gprs.pm +++ b/centreon-plugins/network/digi/sarian/snmp/mode/gprs.pm @@ -18,7 +18,7 @@ # limitations under the License. # -package network::digi::standard::snmp::mode::gprs; +package network::digi::sarian::snmp::mode::gprs; use base qw(centreon::plugins::templates::counter); @@ -230,7 +230,7 @@ __END__ =head1 MODE -Check AP status. +Check GPRS status. =over 8 diff --git a/centreon-plugins/network/digi/standard/snmp/mode/memory.pm b/centreon-plugins/network/digi/sarian/snmp/mode/memory.pm similarity index 98% rename from centreon-plugins/network/digi/standard/snmp/mode/memory.pm rename to centreon-plugins/network/digi/sarian/snmp/mode/memory.pm index 907127f52..8487452ee 100644 --- a/centreon-plugins/network/digi/standard/snmp/mode/memory.pm +++ b/centreon-plugins/network/digi/sarian/snmp/mode/memory.pm @@ -18,7 +18,7 @@ # limitations under the License. # -package network::digi::standard::snmp::mode::memory; +package network::digi::sarian::snmp::mode::memory; use base qw(centreon::plugins::mode); diff --git a/centreon-plugins/network/digi/standard/snmp/mode/temperature.pm b/centreon-plugins/network/digi/sarian/snmp/mode/temperature.pm similarity index 98% rename from centreon-plugins/network/digi/standard/snmp/mode/temperature.pm rename to centreon-plugins/network/digi/sarian/snmp/mode/temperature.pm index 597ac8dd3..7b348eaec 100644 --- a/centreon-plugins/network/digi/standard/snmp/mode/temperature.pm +++ b/centreon-plugins/network/digi/sarian/snmp/mode/temperature.pm @@ -18,7 +18,7 @@ # limitations under the License. # -package network::digi::standard::snmp::mode::temperature; +package network::digi::sarian::snmp::mode::temperature; use base qw(centreon::plugins::templates::counter); diff --git a/centreon-plugins/network/digi/standard/snmp/plugin.pm b/centreon-plugins/network/digi/sarian/snmp/plugin.pm similarity index 76% rename from centreon-plugins/network/digi/standard/snmp/plugin.pm rename to centreon-plugins/network/digi/sarian/snmp/plugin.pm index a0864d61f..3d1841625 100644 --- a/centreon-plugins/network/digi/standard/snmp/plugin.pm +++ b/centreon-plugins/network/digi/sarian/snmp/plugin.pm @@ -18,7 +18,7 @@ # limitations under the License. # -package network::digi::standard::snmp::plugin; +package network::digi::sarian::snmp::plugin; use strict; use warnings; @@ -33,10 +33,10 @@ sub new { %{$self->{modes}} = ( 'interfaces' => 'snmp_standard::mode::interfaces', 'list-interfaces' => 'snmp_standard::mode::listinterfaces', - 'cpu' => 'network::digi::standard::snmp::mode::cpu', - 'memory' => 'network::digi::standard::snmp::mode::memory', - 'temperature' => 'network::digi::standard::snmp::mode::temperature', - 'gprs' => 'network::digi::standard::snmp::mode::gprs', + 'cpu' => 'network::digi::sarian::snmp::mode::cpu', + 'memory' => 'network::digi::sarian::snmp::mode::memory', + 'temperature' => 'network::digi::sarian::snmp::mode::temperature', + 'gprs' => 'network::digi::sarian::snmp::mode::gprs', ); return $self; diff --git a/centreon-plugins/network/f5/bigip/snmp/mode/nodestatus.pm b/centreon-plugins/network/f5/bigip/snmp/mode/nodestatus.pm index 818a3b831..b37977d93 100644 --- a/centreon-plugins/network/f5/bigip/snmp/mode/nodestatus.pm +++ b/centreon-plugins/network/f5/bigip/snmp/mode/nodestatus.pm @@ -196,8 +196,8 @@ sub manage_selection { $oid =~ /^$branch_name\.(.*)$/; my $instance = $1; if (defined($self->{option_results}->{filter_name}) && $self->{option_results}->{filter_name} ne '' && - $snmp_result->{$oid} !~ /$self->{option_results}->{filter_name}/) { - $self->{output}->output_add(long_msg => "skipping node '" . $snmp_result->{$oid} . "'.", debug => 1); + $snmp_result->{$branch_name}->{$oid} !~ /$self->{option_results}->{filter_name}/) { + $self->{output}->output_add(long_msg => "skipping node '" . $snmp_result->{$branch_name}->{$oid} . "'.", debug => 1); next; } diff --git a/centreon-plugins/network/f5/bigip/snmp/mode/tmmusage.pm b/centreon-plugins/network/f5/bigip/snmp/mode/tmmusage.pm index 9f915b3e9..b130108de 100644 --- a/centreon-plugins/network/f5/bigip/snmp/mode/tmmusage.pm +++ b/centreon-plugins/network/f5/bigip/snmp/mode/tmmusage.pm @@ -241,13 +241,13 @@ Filter by TMM name (regexp can be used). =item B<--warning-*> Threshold warning. -Can be: 'cpu1m', 'cpu5m', 'memory-usage' (%), 'total-client-connections', 'current-client-connections', +Can be: 'cpu-1m', 'cpu-5m', 'memory-usage' (%), 'total-client-connections', 'current-client-connections', 'total-server-connections', 'current-server-connections'. =item B<--critical-*> Threshold critical. -Can be: 'cpu1m', 'cpu5m', 'memory-usage' (%), 'total-client-connections', 'current-client-connections', +Can be: 'cpu-1m', 'cpu-5m', 'memory-usage' (%), 'total-client-connections', 'current-client-connections', 'total-server-connections', 'current-server-connections'. =back diff --git a/centreon-plugins/network/huawei/snmp/mode/cpu.pm b/centreon-plugins/network/huawei/snmp/mode/cpu.pm new file mode 100644 index 000000000..b9d702598 --- /dev/null +++ b/centreon-plugins/network/huawei/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::huawei::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 => 'cpu', type => 1, cb_prefix_output => 'prefix_cpu_output', message_multiple => 'All CPU usages are ok' } + ]; + + $self->{maps_counters}->{cpu} = [ + { label => 'usage', set => { + key_values => [ { name => 'cpu' }, { name => 'num' }, ], + output_template => 'Usage : %.2f %%', + perfdatas => [ + { label => 'cpu', value => 'cpu_absolute', template => '%.2f', + min => 0, max => 100, unit => '%', label_extra_instance => 1, instance_use => 'num_absolute' }, + ], + } + }, + ]; +} + +sub prefix_cpu_output { + my ($self, %options) = @_; + + return "CPU '" . $options{instance_value}->{num} . "' "; +} + +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 $oid_hwEntityCpuUsage = '.1.3.6.1.4.1.2011.5.25.31.1.1.1.1.5'; +my $oid_hwAvgDuty5min = '.1.3.6.1.4.1.2011.6.3.4.1.4'; +my $oid_hwResOccupancy = '.1.3.6.1.4.1.2011.6.3.17.1.1.3'; +my $map_type = { 1 => 'memory', 2 => 'messageUnits', 3 => 'cpu' }; + +sub manage_selection { + my ($self, %options) = @_; + + my $results = $options{snmp}->get_multiple_table(oids => [ + { oid => $oid_hwEntityCpuUsage }, + { oid => $oid_hwAvgDuty5min }, + { oid => $oid_hwResOccupancy }, + ], nothing_quit => 1); + + $self->{cpu} = {}; + my $num = 1; + if (defined($results->{$oid_hwAvgDuty5min}) && scalar(keys %{$results->{$oid_hwAvgDuty5min}}) > 0) { + foreach (keys %{$results->{$oid_hwAvgDuty5min}}) { + $self->{cpu}->{$num} = { num => $num, cpu => $results->{$oid_hwAvgDuty5min}->{$_} }; + $num++; + } + } elsif (defined($results->{$oid_hwEntityCpuUsage}) && scalar(keys %{$results->{$oid_hwEntityCpuUsage}}) > 0) { + foreach (keys %{$results->{$oid_hwEntityCpuUsage}}) { + $self->{cpu}->{$num} = { num => $num, cpu => $results->{$oid_hwEntityCpuUsage}->{$_} }; + $num++; + } + } else { + foreach (keys %{$results->{$oid_hwResOccupancy}}) { + /\.([0-9]*?)$/; + next if (!defined($map_type->{$1}) || $map_type->{$1} ne 'cpu'); + $self->{cpu}->{$num} = { num => $num, cpu => $results->{$oid_hwResOccupancy}->{$_} }; + $num++; + } + } +} + +1; + +__END__ + +=head1 MODE + +Check CPU usages. + +=over 8 + +=item B<--warning-usage> + +Threshold warning. + +=item B<--critical-usage> + +Threshold critical. + +=back + +=cut diff --git a/centreon-plugins/network/huawei/snmp/mode/memory.pm b/centreon-plugins/network/huawei/snmp/mode/memory.pm new file mode 100644 index 000000000..80a6c324b --- /dev/null +++ b/centreon-plugins/network/huawei/snmp/mode/memory.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 network::huawei::snmp::mode::memory; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; + +sub custom_usage_perfdata { + my ($self, %options) = @_; + + my $extra_label = ''; + if (!defined($options{extra_instance}) || $options{extra_instance} != 0) { + $extra_label .= '_' . $self->{result_values}->{display}; + } + if ($self->{result_values}->{total} > 0) { + $self->{output}->perfdata_add(label => 'used' . $extra_label, unit => 'B', + value => $self->{result_values}->{used}, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{label}, total => $self->{result_values}->{total}, cast_int => 1), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{label}, total => $self->{result_values}->{total}, cast_int => 1), + min => 0, max => $self->{result_values}->{total}); + } else { + $self->{output}->perfdata_add(label => 'used' . $extra_label, unit => '%', + value => $self->{result_values}->{prct_used}, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{label}), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{label}), + min => 0, max => 100); + } +} + +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 $msg = 'Used: ' . $self->{result_values}->{prct_used} . '%'; + if ($self->{result_values}->{total} > 0) { + 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}); + + $msg = sprintf("Total: %s Used: %s (%.2f%%) Free: %s (%.2f%%)", + $total_size_value . " " . $total_size_unit, + $total_used_value . " " . $total_used_unit, $self->{result_values}->{prct_used}, + $total_free_value . " " . $total_free_unit, $self->{result_values}->{prct_free}); + } + return $msg; +} + +sub custom_usage_calc { + my ($self, %options) = @_; + + $self->{result_values}->{display} = $options{new_datas}->{$self->{instance} . '_display'}; + $self->{result_values}->{total} = $options{new_datas}->{$self->{instance} . '_total'}; + $self->{result_values}->{free} = $options{new_datas}->{$self->{instance} . '_free'}; + $self->{result_values}->{used} = $options{new_datas}->{$self->{instance} . '_total'} - $self->{result_values}->{free}; + + if ($self->{result_values}->{total} > 0) { + $self->{result_values}->{prct_free} = $self->{result_values}->{free} * 100 / $self->{result_values}->{total}; + $self->{result_values}->{prct_used} = $self->{result_values}->{used} * 100 / $self->{result_values}->{total}; + } else { + $self->{result_values}->{prct_used} = $options{new_datas}->{$self->{instance} . '_used_prct'}; + } + return 0; +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'memory', type => 1, cb_prefix_output => 'prefix_memory_output', message_multiple => 'All memory usages are ok' } + ]; + + $self->{maps_counters}->{memory} = [ + { label => 'usage', set => { + key_values => [ { name => 'display' }, { name => 'used_prct' }, { name => 'free' }, { 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 prefix_memory_output { + my ($self, %options) = @_; + + return "Memory '" . $options{instance_value}->{display} . "' "; +} + +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 $oid_hwEntityMemUsage = '.1.3.6.1.4.1.2011.5.25.31.1.1.1.1.7'; # prct +my $oid_hwMemoryDevEntry = '.1.3.6.1.4.1.2011.6.3.5.1.1'; +my $oid_hwResOccupancy = '.1.3.6.1.4.1.2011.6.3.17.1.1.3'; +my $map_type = { 1 => 'memory', 2 => 'messageUnits', 3 => 'cpu' }; + +my $mapping = { + hwMemoryDevSize => { oid => '.1.3.6.1.4.1.2011.6.3.5.1.1.2' }, # B + hwMemoryDevFree => { oid => '.1.3.6.1.4.1.2011.6.3.5.1.1.3' }, # B +}; + +sub manage_selection { + my ($self, %options) = @_; + + $self->{memory} = {}; + my $results = $options{snmp}->get_multiple_table(oids => [ + { oid => $oid_hwEntityMemUsage }, + { oid => $oid_hwMemoryDevEntry, end => $mapping->{hwMemoryDevFree}->{oid} }, + { oid => $oid_hwResOccupancy }, + ], nothing_quit => 1); + + my $num = 1; + if (defined($results->{$oid_hwMemoryDevEntry}) && scalar(keys %{$results->{$oid_hwMemoryDevEntry}}) > 0) { + foreach (keys %{$results->{$oid_hwMemoryDevEntry}}) { + next if (!/^$mapping->{hwMemoryDevFree}->{oid}\.(.*)$/); + my $result = $options{snmp}->map_instance(mapping => $mapping, results => $results->{$oid_hwMemoryDevEntry}, instance => $1); + $self->{memory}->{$num} = { display => $num, used_prct => -1, free => $result->{hwMemoryDevFree}, total => $result->{hwMemoryDevSize} }; + $num++; + } + } elsif (defined($results->{$oid_hwEntityMemUsage}) && scalar(keys %{$results->{$oid_hwEntityMemUsage}}) > 0) { + foreach (keys %{$results->{$oid_hwEntityMemUsage}}) { + $self->{memory}->{$num} = { display => $num, used_prct => $results->{$oid_hwEntityMemUsage}->{$_}, free => 0, total => 0 }; + $num++; + } + } else { + foreach (keys %{$results->{$oid_hwResOccupancy}}) { + /\.([0-9]*?)$/; + next if (!defined($map_type->{$1}) || $map_type->{$1} ne 'memory'); + $self->{memory}->{$num} = { display => $num, used_prct => $results->{$oid_hwResOccupancy}->{$_}, free => 0, total => 0 }; + $num++; + } + } +} + +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/huawei/snmp/plugin.pm b/centreon-plugins/network/huawei/snmp/plugin.pm new file mode 100644 index 000000000..3289100c7 --- /dev/null +++ b/centreon-plugins/network/huawei/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::huawei::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::huawei::snmp::mode::cpu', + 'interfaces' => 'snmp_standard::mode::interfaces', + 'list-interfaces' => 'snmp_standard::mode::listinterfaces', + 'memory' => 'network::huawei::snmp::mode::memory', + 'uptime' => 'snmp_standard::mode::uptime', + ); + + return $self; +} + +1; + +__END__ + +=head1 PLUGIN DESCRIPTION + +Check Huawei equipments in SNMP. + +=cut diff --git a/centreon-plugins/network/juniper/common/screenos/mode/components/fan.pm b/centreon-plugins/network/juniper/common/screenos/snmp/mode/components/fan.pm similarity index 97% rename from centreon-plugins/network/juniper/common/screenos/mode/components/fan.pm rename to centreon-plugins/network/juniper/common/screenos/snmp/mode/components/fan.pm index 8c0969899..37daf4c3a 100644 --- a/centreon-plugins/network/juniper/common/screenos/mode/components/fan.pm +++ b/centreon-plugins/network/juniper/common/screenos/snmp/mode/components/fan.pm @@ -18,7 +18,7 @@ # limitations under the License. # -package network::juniper::common::screenos::mode::components::fan; +package network::juniper::common::screenos::snmp::mode::components::fan; use strict; use warnings; diff --git a/centreon-plugins/network/juniper/common/screenos/mode/components/module.pm b/centreon-plugins/network/juniper/common/screenos/snmp/mode/components/module.pm similarity index 97% rename from centreon-plugins/network/juniper/common/screenos/mode/components/module.pm rename to centreon-plugins/network/juniper/common/screenos/snmp/mode/components/module.pm index 86f281808..41588f971 100644 --- a/centreon-plugins/network/juniper/common/screenos/mode/components/module.pm +++ b/centreon-plugins/network/juniper/common/screenos/snmp/mode/components/module.pm @@ -18,7 +18,7 @@ # limitations under the License. # -package network::juniper::common::screenos::mode::components::module; +package network::juniper::common::screenos::snmp::mode::components::module; use strict; use warnings; diff --git a/centreon-plugins/network/juniper/common/screenos/mode/components/psu.pm b/centreon-plugins/network/juniper/common/screenos/snmp/mode/components/psu.pm similarity index 97% rename from centreon-plugins/network/juniper/common/screenos/mode/components/psu.pm rename to centreon-plugins/network/juniper/common/screenos/snmp/mode/components/psu.pm index f6870d210..361769bf0 100644 --- a/centreon-plugins/network/juniper/common/screenos/mode/components/psu.pm +++ b/centreon-plugins/network/juniper/common/screenos/snmp/mode/components/psu.pm @@ -18,7 +18,7 @@ # limitations under the License. # -package network::juniper::common::screenos::mode::components::psu; +package network::juniper::common::screenos::snmp::mode::components::psu; use strict; use warnings; diff --git a/centreon-plugins/network/juniper/common/screenos/mode/components/temperature.pm b/centreon-plugins/network/juniper/common/screenos/snmp/mode/components/temperature.pm similarity index 97% rename from centreon-plugins/network/juniper/common/screenos/mode/components/temperature.pm rename to centreon-plugins/network/juniper/common/screenos/snmp/mode/components/temperature.pm index 030400404..1c5c7778e 100644 --- a/centreon-plugins/network/juniper/common/screenos/mode/components/temperature.pm +++ b/centreon-plugins/network/juniper/common/screenos/snmp/mode/components/temperature.pm @@ -18,7 +18,7 @@ # limitations under the License. # -package network::juniper::common::screenos::mode::components::temperature; +package network::juniper::common::screenos::snmp::mode::components::temperature; use strict; use warnings; @@ -66,4 +66,4 @@ sub check { } } -1; \ No newline at end of file +1; diff --git a/centreon-plugins/network/juniper/common/screenos/mode/cpu.pm b/centreon-plugins/network/juniper/common/screenos/snmp/mode/cpu.pm similarity index 99% rename from centreon-plugins/network/juniper/common/screenos/mode/cpu.pm rename to centreon-plugins/network/juniper/common/screenos/snmp/mode/cpu.pm index e78b94a78..ab7c0759d 100644 --- a/centreon-plugins/network/juniper/common/screenos/mode/cpu.pm +++ b/centreon-plugins/network/juniper/common/screenos/snmp/mode/cpu.pm @@ -18,7 +18,7 @@ # limitations under the License. # -package network::juniper::common::screenos::mode::cpu; +package network::juniper::common::screenos::snmp::mode::cpu; use base qw(centreon::plugins::mode); diff --git a/centreon-plugins/network/juniper/common/screenos/mode/hardware.pm b/centreon-plugins/network/juniper/common/screenos/snmp/mode/hardware.pm similarity index 96% rename from centreon-plugins/network/juniper/common/screenos/mode/hardware.pm rename to centreon-plugins/network/juniper/common/screenos/snmp/mode/hardware.pm index 59a574728..a8f573c21 100644 --- a/centreon-plugins/network/juniper/common/screenos/mode/hardware.pm +++ b/centreon-plugins/network/juniper/common/screenos/snmp/mode/hardware.pm @@ -18,7 +18,7 @@ # limitations under the License. # -package network::juniper::common::screenos::mode::hardware; +package network::juniper::common::screenos::snmp::mode::hardware; use base qw(centreon::plugins::templates::hardware); @@ -48,7 +48,7 @@ sub set_system { ], }; - $self->{components_path} = 'network::juniper::common::screenos::mode::components'; + $self->{components_path} = 'network::juniper::common::screenos::snmp::mode::components'; $self->{components_module} = ['psu', 'fan', 'temperature', 'module']; } diff --git a/centreon-plugins/network/juniper/common/screenos/mode/memory.pm b/centreon-plugins/network/juniper/common/screenos/snmp/mode/memory.pm similarity index 98% rename from centreon-plugins/network/juniper/common/screenos/mode/memory.pm rename to centreon-plugins/network/juniper/common/screenos/snmp/mode/memory.pm index fe9b0dc4a..b9290d578 100644 --- a/centreon-plugins/network/juniper/common/screenos/mode/memory.pm +++ b/centreon-plugins/network/juniper/common/screenos/snmp/mode/memory.pm @@ -18,7 +18,7 @@ # limitations under the License. # -package network::juniper::common::screenos::mode::memory; +package network::juniper::common::screenos::snmp::mode::memory; use base qw(centreon::plugins::mode); diff --git a/centreon-plugins/network/juniper/common/screenos/mode/sessions.pm b/centreon-plugins/network/juniper/common/screenos/snmp/mode/sessions.pm similarity index 98% rename from centreon-plugins/network/juniper/common/screenos/mode/sessions.pm rename to centreon-plugins/network/juniper/common/screenos/snmp/mode/sessions.pm index 1b96a2c8c..6c1b89496 100644 --- a/centreon-plugins/network/juniper/common/screenos/mode/sessions.pm +++ b/centreon-plugins/network/juniper/common/screenos/snmp/mode/sessions.pm @@ -18,7 +18,7 @@ # limitations under the License. # -package network::juniper::common::screenos::mode::sessions; +package network::juniper::common::screenos::snmp::mode::sessions; use base qw(centreon::plugins::templates::counter); diff --git a/centreon-plugins/network/juniper/isg/plugin.pm b/centreon-plugins/network/juniper/isg/snmp/plugin.pm similarity index 88% rename from centreon-plugins/network/juniper/isg/plugin.pm rename to centreon-plugins/network/juniper/isg/snmp/plugin.pm index 115112358..130f4e62a 100644 --- a/centreon-plugins/network/juniper/isg/plugin.pm +++ b/centreon-plugins/network/juniper/isg/snmp/plugin.pm @@ -18,7 +18,7 @@ # limitations under the License. # -package network::juniper::isg::plugin; +package network::juniper::isg::snmp::plugin; use strict; use warnings; @@ -31,10 +31,10 @@ sub new { $self->{version} = '1.0'; %{$self->{modes}} = ( - 'cpu' => 'network::juniper::common::screenos::mode::cpu', - 'memory' => 'network::juniper::common::screenos::mode::memory', - 'sessions' => 'network::juniper::common::screenos::mode::sessions', - 'hardware' => 'network::juniper::common::screenos::mode::hardware', + 'cpu' => 'network::juniper::common::screenos::snmp::mode::cpu', + 'memory' => 'network::juniper::common::screenos::snmp::mode::memory', + 'sessions' => 'network::juniper::common::screenos::snmp::mode::sessions', + 'hardware' => 'network::juniper::common::screenos::snmp::mode::hardware', 'interfaces' => 'snmp_standard::mode::interfaces', 'list-interfaces' => 'snmp_standard::mode::listinterfaces', ); diff --git a/centreon-plugins/network/juniper/ssg/plugin.pm b/centreon-plugins/network/juniper/ssg/snmp/plugin.pm similarity index 88% rename from centreon-plugins/network/juniper/ssg/plugin.pm rename to centreon-plugins/network/juniper/ssg/snmp/plugin.pm index 169270806..3dad3f014 100644 --- a/centreon-plugins/network/juniper/ssg/plugin.pm +++ b/centreon-plugins/network/juniper/ssg/snmp/plugin.pm @@ -18,7 +18,7 @@ # limitations under the License. # -package network::juniper::ssg::plugin; +package network::juniper::ssg::snmp::plugin; use strict; use warnings; @@ -31,10 +31,10 @@ sub new { $self->{version} = '1.0'; %{$self->{modes}} = ( - 'cpu' => 'network::juniper::common::screenos::mode::cpu', - 'memory' => 'network::juniper::common::screenos::mode::memory', - 'sessions' => 'network::juniper::common::screenos::mode::sessions', - 'hardware' => 'network::juniper::common::screenos::mode::hardware', + 'cpu' => 'network::juniper::common::screenos::snmp::mode::cpu', + 'memory' => 'network::juniper::common::screenos::snmp::mode::memory', + 'sessions' => 'network::juniper::common::screenos::snmp::mode::sessions', + 'hardware' => 'network::juniper::common::screenos::snmp::mode::hardware', 'interfaces' => 'snmp_standard::mode::interfaces', 'list-interfaces' => 'snmp_standard::mode::listinterfaces', ); diff --git a/centreon-plugins/network/nokia/timos/snmp/mode/bgpusage.pm b/centreon-plugins/network/nokia/timos/snmp/mode/bgpusage.pm new file mode 100644 index 000000000..abbefca8f --- /dev/null +++ b/centreon-plugins/network/nokia/timos/snmp/mode/bgpusage.pm @@ -0,0 +1,257 @@ +# +# 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::nokia::timos::snmp::mode::bgpusage; + +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 = '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 => 'bgp', type => 1, cb_prefix_output => 'prefix_bgp_output', message_multiple => 'All BGP are ok' }, + ]; + $self->{maps_counters}->{bgp} = [ + { label => '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 => 'active-prefixes', set => { + key_values => [ { name => 'active_prefixes' }, { name => 'display' } ], + output_template => 'Active Prefixes : %s', + perfdatas => [ + { label => 'active_prefixes', value => 'active_prefixes_absolute', template => '%s', + min => 0, label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + { label => 'sent-prefixes', set => { + key_values => [ { name => 'sent_prefixes', diff => 1 }, { name => 'display' } ], + output_template => 'Sent Prefixes : %s', + perfdatas => [ + { label => 'sent_prefixes', value => 'sent_prefixes_absolute', template => '%s', + min => 0, label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + { label => 'received-prefixes', set => { + key_values => [ { name => 'received_prefixes', diff => 1 }, { name => 'display' } ], + output_template => 'Received Prefixes : %s', + perfdatas => [ + { label => 'received_prefixes', value => 'received_prefixes_absolute', template => '%s', + min => 0, label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + ]; +} + +sub prefix_bgp_output { + my ($self, %options) = @_; + + return "BGP '" . $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 => '%{state} =~ /outOfService/' }, + }); + + 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 = (1 => 'unknown', 2 => 'inService', 3 => 'outOfService', + 4 => 'transition', 5 => 'disabled', +); + +my $oid_vRtrName = '.1.3.6.1.4.1.6527.3.1.2.3.1.1.4'; +my $mapping = { + tBgpPeerNgDescription => { oid => '.1.3.6.1.4.1.6527.3.1.2.14.4.7.1.7' }, + tBgpPeerNgOperStatus => { oid => '.1.3.6.1.4.1.6527.3.1.2.14.4.7.1.42', map => \%map_status }, + tBgpPeerNgPeerAS4Byte => { oid => '.1.3.6.1.4.1.6527.3.1.2.14.4.7.1.66' }, + tBgpPeerNgOperReceivedPrefixes => { oid => '.1.3.6.1.4.1.6527.3.1.2.14.4.8.1.5' }, + tBgpPeerNgOperSentPrefixes => { oid => '.1.3.6.1.4.1.6527.3.1.2.14.4.8.1.6' }, + tBgpPeerNgOperActivePrefixes => { oid => '.1.3.6.1.4.1.6527.3.1.2.14.4.8.1.7' }, +}; + +sub manage_selection { + my ($self, %options) = @_; + + my $snmp_result = $options{snmp}->get_multiple_table(oids => [ + { oid => $oid_vRtrName }, + { oid => $mapping->{tBgpPeerNgDescription}->{oid} }, + { oid => $mapping->{tBgpPeerNgPeerAS4Byte}->{oid} }, + ], return_type => 1, nothing_quit => 1); + $self->{bgp} = {}; + foreach my $oid (keys %$snmp_result) { + next if ($oid !~ /^$mapping->{tBgpPeerNgPeerAS4Byte}->{oid}\.(\d+)\.(\d+)\.(.*)$/); + my ($vrtr_id, $peer_type, $peer_addr) = ($1, $2, $3); + + my $vrtr_name = $snmp_result->{$oid_vRtrName . '.' . $vrtr_id}; + my $result = $options{snmp}->map_instance(mapping => $mapping, results => $snmp_result, instance => $vrtr_id . '.' . $peer_type . '.' . $peer_addr); + + my $name = $vrtr_name . ':' . $peer_addr . ':' . $result->{tBgpPeerNgPeerAS4Byte} . ':' . $result->{tBgpPeerNgDescription}; + 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 . "'.", debug => 1); + next; + } + + $self->{bgp}->{$vrtr_id . '.' . $peer_type . '.' . $peer_addr} = { + display => $name + }; + } + + $options{snmp}->load(oids => [$mapping->{tBgpPeerNgOperReceivedPrefixes}->{oid}, $mapping->{tBgpPeerNgOperSentPrefixes}->{oid}, + $mapping->{tBgpPeerNgOperActivePrefixes}->{oid}, $mapping->{tBgpPeerNgOperStatus}->{oid}], + instances => [keys %{$self->{bgp}}], instance_regexp => '^(.*)$'); + $snmp_result = $options{snmp}->get_leef(nothing_quit => 1); + foreach (keys %{$self->{bgp}}) { + my $result = $options{snmp}->map_instance(mapping => $mapping, results => $snmp_result, instance => $_); + + $self->{bgp}->{$_}->{sent_prefixes} = $result->{tBgpPeerNgOperSentPrefixes}; + $self->{bgp}->{$_}->{active_prefixes} = $result->{tBgpPeerNgOperActivePrefixes}; + $self->{bgp}->{$_}->{received_prefixes} = $result->{tBgpPeerNgOperReceivedPrefixes}; + $self->{bgp}->{$_}->{state} = $result->{tBgpPeerNgOperStatus}; + } + + if (scalar(keys %{$self->{bgp}}) <= 0) { + $self->{output}->add_option_msg(short_msg => "No bgp found."); + $self->{output}->option_exit(); + } + + $self->{cache_name} = "nokia_timos_" . $options{snmp}->get_hostname() . '_' . $options{snmp}->get_port() . '_' . $self->{mode} . '_' . + (defined($self->{option_results}->{filter_name}) ? md5_hex($self->{option_results}->{filter_name}) : md5_hex('all')) . '_' . + (defined($self->{option_results}->{filter_counters}) ? md5_hex($self->{option_results}->{filter_counters}) : md5_hex('all')); +} + +1; + +__END__ + +=head1 MODE + +Check BGP usage. + +=over 8 + +=item B<--warning-*> + +Threshold warning. +Can be: 'active-prefixes', 'sent-prefixes', 'received-prefixes'. + +=item B<--critical-*> + +Threshold critical. +Can be: 'active-prefixes', 'sent-prefixes', 'received-prefixes'. + +=item B<--warning-status> + +Set warning threshold for status. +Can used special variables like: %{display}, %{state} + +=item B<--critical-status> + +Set critical threshold for status (Default: '%{state} =~ /outOfService/') +Can used special variables like: %{display}, %{state} + +=item B<--filter-name> + +Filter by BGP name (can be a regexp). +Syntax: VrtrName:peeraddr:peerAS:description + +=back + +=cut diff --git a/centreon-plugins/network/nokia/timos/snmp/mode/cpu.pm b/centreon-plugins/network/nokia/timos/snmp/mode/cpu.pm new file mode 100644 index 000000000..cb642449b --- /dev/null +++ b/centreon-plugins/network/nokia/timos/snmp/mode/cpu.pm @@ -0,0 +1,96 @@ +# +# 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::nokia::timos::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 => 'usage', set => { + key_values => [ { name => 'cpu' } ], + output_template => 'Usage : %.2f %%', + perfdatas => [ + { label => 'cpu', value => 'cpu_absolute', template => '%.2f', + min => 0, max => 100, unit => '%' }, + ], + } + }, + ]; +} + +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_sgiCpuUsage = '.1.3.6.1.4.1.6527.3.1.2.1.1.1.0'; + my $snmp_result = $options{snmp}->get_leef(oids => [$oid_sgiCpuUsage], nothing_quit => 1); + + $self->{global} = { cpu => $snmp_result->{$oid_sgiCpuUsage} }; +} + +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/nokia/timos/snmp/mode/hardware.pm b/centreon-plugins/network/nokia/timos/snmp/mode/hardware.pm new file mode 100644 index 000000000..5721aec2b --- /dev/null +++ b/centreon-plugins/network/nokia/timos/snmp/mode/hardware.pm @@ -0,0 +1,212 @@ +# +# 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::nokia::timos::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} = '^(entity)$'; + $self->{regexp_threshold_numeric_check_section_option} = '^temperature$'; + + $self->{cb_hook2} = 'snmp_execute'; + + $self->{thresholds} = { + default => [ + ['unknown', 'UNKNOWN'], + ['inService', 'OK'], + ['outOfService', 'OK'], + ['diagnosing', 'OK'], + ['failed', 'CRITICAL'], + ['booting', 'OK'], + ['empty', 'OK'], + ['unprovisioned', 'OK'], + ['provisioned', 'OK'], + ['upgrade', 'OK'], + ['downgrade', 'OK'], + ['resetPending', 'OK'], + ['softReset', 'OK'], + ['preExtension', 'OK'], + ], + }; + + $self->{components_path} = 'network::nokia::timos::snmp::mode::components'; + $self->{components_module} = ['entity']; +} + +sub snmp_execute { + my ($self, %options) = @_; + + $self->{snmp} = $options{snmp}; + $self->{results} = $self->{snmp}->get_multiple_table(oids => $self->{request}, return_type => 1); +} + +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; +} + +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,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='entity,fan..*,CRITICAL,booting' + +=item B<--warning> + +Set warning threshold (syntax: type,regexp,threshold) +Example: --warning='temperature,.*,20' + +=item B<--critical> + +Set critical threshold (syntax: type,regexp,threshold) +Example: --critical='temperature,.*,30' + +=back + +=cut + +package network::nokia::timos::snmp::mode::components::entity; + +use strict; +use warnings; + +my %map_class = ( + 1 => 'other', 2 => 'unknown', 3 => 'physChassis', + 4 => 'container', 5 => 'powerSupply', 6 => 'fan', + 7 => 'sensor', 8 => 'ioModule', 9 => 'cpmModule', + 10 => 'fabricModule', 11 => 'mdaModule', + 12 => 'flashDiskModule', 13 => 'port', 14 => 'mcm', + 15 => 'ccm', 16 => 'oesCard', 17 => 'oesControlCard', + 18 => 'oesUserPanel', 19 => 'alarmInputModule', +); +my %map_truth = (1 => 'true', 2 => 'false'); +my %map_oper_state = ( + 1 => 'unknown', 2 => 'inService', 3 => 'outOfService', + 4 => 'diagnosing', 5 => 'failed', 6 => 'booting', + 7 => 'empty', 8 => 'provisioned', 9 => 'unprovisioned', + 10 => 'upgrade', 11 => 'downgrade', 12 => 'inServiceUpgrade', + 13 => 'inServiceDowngrade', 14 => 'resetPending', + 15 => 'softReset', 16 => 'preExtension', +); + +my $mapping = { + tmnxHwClass => { oid => '.1.3.6.1.4.1.6527.3.1.2.2.1.8.1.7', map => \%map_class }, + tmnxHwName => { oid => '.1.3.6.1.4.1.6527.3.1.2.2.1.8.1.8' }, + tmnxHwOperState => { oid => '.1.3.6.1.4.1.6527.3.1.2.2.1.8.1.16', map => \%map_oper_state }, + tmnxHwTempSensor => { oid => '.1.3.6.1.4.1.6527.3.1.2.2.1.8.1.17', map => \%map_truth }, + tmnxHwTemperature => { oid => '.1.3.6.1.4.1.6527.3.1.2.2.1.8.1.18' }, + tmnxHwTempThreshold => { oid => '.1.3.6.1.4.1.6527.3.1.2.2.1.8.1.19' }, +}; + +sub load { + my ($self) = @_; + + push @{$self->{request}}, { oid => $mapping->{tmnxHwClass}->{oid} }, { oid => $mapping->{tmnxHwName}->{oid} }, + { oid => $mapping->{tmnxHwTempSensor}->{oid} }, { oid => $mapping->{tmnxHwOperState}->{oid} }, + { oid => $mapping->{tmnxHwTemperature}->{oid} }, { oid => $mapping->{tmnxHwTempThreshold}->{oid} }; +} + +sub check { + my ($self) = @_; + + $self->{output}->output_add(long_msg => "Checking entities"); + $self->{components}->{entity} = {name => 'entity', total => 0, skip => 0}; + return if ($self->check_filter(section => 'entity')); + + my ($exit, $warn, $crit, $checked); + foreach my $oid ($self->{snmp}->oid_lex_sort(keys %{$self->{results}})) { + next if ($oid !~ /^$mapping->{tmnxHwName}->{oid}\.(.*)$/); + my $instance = $1; + my $result = $self->{snmp}->map_instance(mapping => $mapping, results => $self->{results}, instance => $instance); + + next if ($self->check_filter(section => 'entity', instance => $result->{tmnxHwClass} . '.' . $instance)); + + $self->{components}->{entity}->{total}++; + $self->{output}->output_add(long_msg => sprintf("%s '%s' status is '%s' [instance = %s, temperature = %s]", + $result->{tmnxHwClass}, $result->{tmnxHwName}, + $result->{tmnxHwOperState}, $result->{tmnxHwClass} . '.' . $instance, + $result->{tmnxHwTempSensor} eq 'true' ? $result->{tmnxHwTemperature} : '-')); + $exit = $self->get_severity(label => 'default', section => 'entity', instance => $result->{tmnxHwClass} . '.' . $instance, value => $result->{tmnxHwOperState}); + if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { + $self->{output}->output_add(severity => $exit, + short_msg => sprintf("%s '%s' status is '%s'", $result->{tmnxHwClass}, $result->{tmnxHwName}, $result->{tmnxHwOperState})); + } + + next if ($result->{tmnxHwTempSensor} eq 'false'); + ($exit, $warn, $crit, $checked) = $self->get_severity_numeric(section => 'temperature', instance => $result->{tmnxHwClass} . '.' . $instance,, value => $result->{tmnxHwTemperature}); + if ($checked == 0 && $result->{tmnxHwTempThreshold} != -1 ) { + $self->{perfdata}->threshold_validate(label => 'critical-temperature-instance-' . $result->{tmnxHwClass} . '.' . $instance, value => $result->{tmnxHwTempThreshold}); + + $exit = $self->{perfdata}->threshold_check(value => $result->{slHdwTempSensorCurrentTemp}, threshold => [ { label => 'critical-temperature-instance-' . $instance, exit_litteral => 'critical' }]); + $warn = undef; + $crit = $self->{perfdata}->get_perfdata_for_output(label => 'critical-temperature-instance-' . $result->{tmnxHwClass} . '.' . $instance); + } + + if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { + $self->{output}->output_add(severity => $exit, + short_msg => sprintf("%s '%s' temperature is '%s' C", $result->{tmnxHwClass}, + $result->{tmnxHwName}, $result->{tmnxHwTemperature})); + } + $self->{output}->perfdata_add(label => 'temperature_' . $result->{tmnxHwName}, unit => 'C', + value => $result->{tmnxHwTemperature}, + warning => $warn, + critical => $crit + ); + } +} + +1; diff --git a/centreon-plugins/network/nokia/timos/snmp/mode/isisusage.pm b/centreon-plugins/network/nokia/timos/snmp/mode/isisusage.pm new file mode 100644 index 000000000..595a34894 --- /dev/null +++ b/centreon-plugins/network/nokia/timos/snmp/mode/isisusage.pm @@ -0,0 +1,265 @@ +# +# 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::nokia::timos::snmp::mode::isisusage; + +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 = 'state : ' . $self->{result_values}->{oper_state} . ' (admin: ' . $self->{result_values}->{admin_state} . ')'; + return $msg; +} + +sub custom_status_calc { + my ($self, %options) = @_; + + $self->{result_values}->{oper_state} = $options{new_datas}->{$self->{instance} . '_oper_state'}; + $self->{result_values}->{admin_state} = $options{new_datas}->{$self->{instance} . '_admin_state'}; + $self->{result_values}->{display} = $options{new_datas}->{$self->{instance} . '_display'}; + return 0; +} + + +sub custom_total_sessions_calc { + my ($self, %options) = @_; + + my $total_sessions = 0; + foreach (keys %{$options{new_datas}}) { + if (/$self->{instance}_total_sessions_(\d+)/) { + my $new_total = $options{new_datas}->{$_}; + next if (!defined($options{old_datas}->{$_})); + my $old_total = $options{old_datas}->{$_}; + + $total_sessions += $new_total - $old_total; + $total_sessions += $old_total if ($total_sessions <= 0); + } + } + + $self->{result_values}->{display} = $options{new_datas}->{$self->{instance} . '_display'}; + $self->{result_values}->{total_sessions} = $total_sessions; + + return 0; +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'isis', type => 1, cb_prefix_output => 'prefix_isis_output', message_multiple => 'All IS-IS instances are ok' }, + { name => 'int', type => 1, cb_prefix_output => 'prefix_int_output', message_multiple => 'All interfaces are ok' }, + ]; + $self->{maps_counters}->{int} = [ + { label => 'status', threshold => 0, set => { + key_values => [ { name => 'oper_state' }, { name => 'admin_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'), + } + }, + ]; + + $self->{maps_counters}->{isis} = [ + { label => 'total-int-inservice', set => { + key_values => [ { name => 'inService' }, { name => 'display' } ], + output_template => 'Total Interfaces InServices : %s', + perfdatas => [ + { label => 'total_int_inservice', value => 'inService_absolute', template => '%s', + min => 0, label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + { label => 'total-int-outservice', set => { + key_values => [ { name => 'outOfService' }, { name => 'display' } ], + output_template => 'Total Interfaces OutOfServices : %s', + perfdatas => [ + { label => 'total_int_outservice', value => 'outOfService_absolute', template => '%s', + min => 0, label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + ]; +} + +sub prefix_isis_output { + my ($self, %options) = @_; + + return "IS-IS instance '" . $options{instance_value}->{display} . "' "; +} + +sub prefix_int_output { + my ($self, %options) = @_; + + return "Interface '" . $options{instance_value}->{display} . "' "; +} + +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 => '' }, + "critical-status:s" => { name => 'critical_status', default => '%{admin_state} eq "inService" and %{oper_state} !~ /inService|transition/' }, + }); + + 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_admin_status = (1 => 'noop', 2 => 'inService', 3 => 'outOfService'); +my %map_oper_status = (1 => 'unknown', 2 => 'inService', 3 => 'outOfService', 4 => 'transition'); + +my $oid_vRtrName = '.1.3.6.1.4.1.6527.3.1.2.3.1.1.4'; +my $oid_ifName = '.1.3.6.1.2.1.31.1.1.1.1'; +# index = vRtrID + isisInstance + ifIndex +my $mapping = { + tmnxIsisIfAdminState => { oid => '.1.3.6.1.4.1.6527.3.1.2.88.2.1.1.3', map => \%map_admin_status }, + tmnxIsisIfOperState => { oid => '.1.3.6.1.4.1.6527.3.1.2.88.2.1.1.4', map => \%map_oper_status }, +}; + +sub manage_selection { + my ($self, %options) = @_; + + my $snmp_result = $options{snmp}->get_multiple_table(oids => [ + { oid => $oid_vRtrName }, + { oid => $oid_ifName }, + { oid => $mapping->{tmnxIsisIfAdminState}->{oid} }, + { oid => $mapping->{tmnxIsisIfOperState}->{oid} }, + ], return_type => 1, nothing_quit => 1); + $self->{isis} = {}; + $self->{int} = {}; + foreach my $oid (keys %$snmp_result) { + next if ($oid !~ /^$mapping->{tmnxIsisIfOperState}->{oid}\.(\d+)\.(\d+)\.(\d+)$/); + my ($vrtr_id, $isis_id, $ifindex) = ($1, $2, $3); + + my $vrtr_name = $snmp_result->{$oid_vRtrName . '.' . $vrtr_id}; + my $result = $options{snmp}->map_instance(mapping => $mapping, results => $snmp_result, instance => $vrtr_id . '.' . $isis_id . '.' . $ifindex); + my $name = $vrtr_name . '.' . $isis_id; + 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 . "'.", debug => 1); + next; + } + + $self->{isis}->{$vrtr_id . '.' . $isis_id} = { display => $name, inService => 0, outOfService => 0 } if (!defined($self->{isis}->{$vrtr_id . '.' . $isis_id})); + $self->{isis}->{$vrtr_id . '.' . $isis_id}->{$result->{tmnxIsisIfOperState}}++; + + $self->{int}->{$vrtr_id . '.' . $isis_id . '.' . $ifindex} = { + display => $name . '.' . $snmp_result->{$oid_ifName . '.' . $ifindex}, + admin_state => $result->{tmnxIsisIfAdminState}, + oper_state => $result->{tmnxIsisIfOperState}, + }; + } + + if (scalar(keys %{$self->{isis}}) <= 0) { + $self->{output}->add_option_msg(short_msg => "No IS-IS intance found."); + $self->{output}->option_exit(); + } +} + +1; + +__END__ + +=head1 MODE + +Check IS-IS usage. + +=over 8 + +=item B<--warning-*> + +Threshold warning. +Can be: 'total-int-inservice', 'total-int-outservice'. + +=item B<--critical-*> + +Threshold critical. +Can be: 'total-int-inservice', 'total-int-outservice'. + +=item B<--warning-status> + +Set warning threshold for status. +Can used special variables like: %{display}, %{oper_state}, %{admin_state}. + +=item B<--critical-status> + +Set critical threshold for status (Default: '%{admin_state} eq "inService" and %{oper_state} !~ /inService|transition/'). +Can used special variables like: %{display}, %{oper_state}, %{admin_state}. + +=item B<--filter-name> + +Filter by instance name (can be a regexp). + +=back + +=cut diff --git a/centreon-plugins/network/nokia/timos/snmp/mode/l2tpusage.pm b/centreon-plugins/network/nokia/timos/snmp/mode/l2tpusage.pm new file mode 100644 index 000000000..24526d6ae --- /dev/null +++ b/centreon-plugins/network/nokia/timos/snmp/mode/l2tpusage.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 network::nokia::timos::snmp::mode::l2tpusage; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; +use Digest::MD5 qw(md5_hex); +use Socket; + +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 = '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 custom_total_sessions_calc { + my ($self, %options) = @_; + + my $total_sessions = 0; + foreach (keys %{$options{new_datas}}) { + if (/$self->{instance}_total_sessions_(\d+)/) { + my $new_total = $options{new_datas}->{$_}; + next if (!defined($options{old_datas}->{$_})); + my $old_total = $options{old_datas}->{$_}; + + my $diff_sessions = $new_total - $old_total; + if ($diff_sessions < 0) { + $total_sessions += $old_total; + } else { + $total_sessions += $diff_sessions; + } + } + } + + $self->{result_values}->{display} = $options{new_datas}->{$self->{instance} . '_display'}; + $self->{result_values}->{total_sessions} = $total_sessions; + + return 0; +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'tunnel', type => 1, cb_prefix_output => 'prefix_tunnel_output', message_multiple => 'All tunnels are ok' }, + { name => 'vrtr', type => 1, cb_prefix_output => 'prefix_vrtr_output', message_multiple => 'All tunnels by virtual router are ok' }, + { name => 'peer', type => 1, cb_prefix_output => 'prefix_peer_output', message_multiple => 'All tunnels by peer router are ok' }, + ]; + $self->{maps_counters}->{tunnel} = [ + { label => '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'), + } + }, + ]; + + $self->{maps_counters}->{vrtr} = [ + { label => 'vrtr-tunnel-total', set => { + key_values => [ { name => 'total_tunnel' }, { name => 'display' } ], + output_template => 'Total : %s', + perfdatas => [ + { label => 'vrtr_total_tunnel', value => 'total_tunnel_absolute', template => '%s', + min => 0, label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + { label => 'vrtr-tunnel-active-sessions', set => { + key_values => [ { name => 'active_sessions' }, { name => 'display' } ], + output_template => 'Active Sessions : %s', + perfdatas => [ + { label => 'vrtr_tunnel_active_sessions', value => 'active_sessions_absolute', template => '%s', + min => 0, label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + { label => 'vrtr-tunnel-total-sessions', set => { + key_values => [], + manual_keys => 1, + output_template => 'Total Sessions : %s', + threshold_use => 'total_sessions', output_use => 'total_sessions', + closure_custom_calc => $self->can('custom_total_sessions_calc'), + perfdatas => [ + { label => 'vrtr_tunnel_total_sessions', value => 'total_sessions', template => '%s', + min => 0, label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + ]; + + $self->{maps_counters}->{peer} = [ + { label => 'peer-tunnel-total', set => { + key_values => [ { name => 'total_tunnel' }, { name => 'display' } ], + output_template => 'Total : %s', + perfdatas => [ + { label => 'peer_total_tunnel', value => 'total_tunnel_absolute', template => '%s', + min => 0, label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + { label => 'peer-tunnel-active-sessions', set => { + key_values => [ { name => 'active_sessions' }, { name => 'display' } ], + output_template => 'Active Sessions : %s', + perfdatas => [ + { label => 'peer_tunnel_active_sessions', value => 'active_sessions_absolute', template => '%s', + min => 0, label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + { label => 'peer-tunnel-total-sessions', set => { + key_values => [], + manual_keys => 1, + output_template => 'Total Sessions : %s', + threshold_use => 'total_sessions', output_use => 'total_sessions', + closure_custom_calc => $self->can('custom_total_sessions_calc'), + perfdatas => [ + { label => 'peer_tunnel_total_sessions', value => 'total_sessions', template => '%s', + min => 0, label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + ]; +} + +sub prefix_tunnel_output { + my ($self, %options) = @_; + + return "Tunnel '" . $options{instance_value}->{display} . "' "; +} + +sub prefix_vrtr_output { + my ($self, %options) = @_; + + return "Virtual router '" . $options{instance_value}->{display} . "' Tunnel "; +} + +sub prefix_peer_output { + my ($self, %options) = @_; + + return "Peer '" . $options{instance_value}->{display} . "' Tunnel "; +} + +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-vrtr-name:s" => { name => 'filter_vrtr_name' }, + "filter-peer-addr:s" => { name => 'filter_peer_addr' }, + "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); + + $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 = (1 => 'unknown', 2 => 'idle', 3 => 'waitReply', 4 => 'waitConn', + 5 => 'establishedIdle', 6 => 'established', 7 => 'draining', 8 => 'drained', + 9 => 'closed', 10 => 'closedByPeer' +); + +my $oid_vRtrName = '.1.3.6.1.4.1.6527.3.1.2.3.1.1.4'; +# index vRtrID and TuStatusId +my $mapping = { + tmnxL2tpTuStatusState => { oid => '.1.3.6.1.4.1.6527.3.1.2.60.1.3.2.2.1.2', map => \%map_status }, + tmnxL2tpTuStatusPeerAddr => { oid => '.1.3.6.1.4.1.6527.3.1.2.60.1.3.2.2.1.6' }, + tmnxL2tpTuStatsTotalSessions => { oid => '.1.3.6.1.4.1.6527.3.1.2.60.1.3.2.3.1.2' }, + tmnxL2tpTuStatsActiveSessions => { oid => '.1.3.6.1.4.1.6527.3.1.2.60.1.3.2.3.1.4' }, +}; + +sub manage_selection { + my ($self, %options) = @_; + + my $snmp_result = $options{snmp}->get_multiple_table(oids => [ + { oid => $oid_vRtrName }, + { oid => $mapping->{tmnxL2tpTuStatusPeerAddr}->{oid} }, + { oid => $mapping->{tmnxL2tpTuStatusState}->{oid} }, + ], return_type => 1, nothing_quit => 1); + $self->{vrtr} = {}; + $self->{peer} = {}; + $self->{tunnel} = {}; + foreach my $oid (keys %$snmp_result) { + next if ($oid !~ /^$mapping->{tmnxL2tpTuStatusState}->{oid}\.(.*?)\.(.*)$/); + my ($vrtr_id, $l2tp_tu_id) = ($1, $2); + + my $vrtr_name = $snmp_result->{$oid_vRtrName . '.' . $vrtr_id}; + my $result = $options{snmp}->map_instance(mapping => $mapping, results => $snmp_result, instance => $vrtr_id . '.' . $l2tp_tu_id); + my $peer_addr = inet_ntoa($result->{tmnxL2tpTuStatusPeerAddr}); + if (defined($self->{option_results}->{filter_vrtr_name}) && $self->{option_results}->{filter_vrtr_name} ne '' && + $vrtr_name !~ /$self->{option_results}->{filter_vrtr_name}/) { + $self->{output}->output_add(long_msg => "skipping vrtr '" . $vrtr_name . "'.", debug => 1); + next; + } + if (defined($self->{option_results}->{filter_peer_addr}) && $self->{option_results}->{filter_peer_addr} ne '' && + $peer_addr !~ /$self->{option_results}->{filter_peer_addr}/) { + $self->{output}->output_add(long_msg => "skipping peer addr '" . $peer_addr . "'.", debug => 1); + next; + } + + $self->{tunnel}->{$vrtr_id . '.' . $l2tp_tu_id} = { display => $vrtr_name . '-' . $peer_addr, state => $result->{tmnxL2tpTuStatusState} }; + $self->{vrtr}->{$vrtr_name} = { display => $vrtr_name, total_tunnel => 0, active_sessions => 0 } if (!defined($self->{vrtr}->{$vrtr_name})); + $self->{vrtr}->{$vrtr_name}->{total_tunnel}++; + + $self->{peer}->{$peer_addr} = { display => $peer_addr, total_tunnel => 0, active_sessions => 0 } if (!defined($self->{peer}->{$peer_addr})); + $self->{peer}->{$peer_addr}->{total_tunnel}++; + } + + $options{snmp}->load(oids => [$mapping->{tmnxL2tpTuStatsActiveSessions}->{oid}, $mapping->{tmnxL2tpTuStatsTotalSessions}->{oid}], + instances => [keys %{$self->{tunnel}}], instance_regexp => '^(.*)$'); + my $snmp_result2 = $options{snmp}->get_leef(nothing_quit => 1); + + foreach (keys %{$self->{tunnel}}) { + /(\d+)\.\d+/; + my $vrtr_name = $snmp_result->{$oid_vRtrName . '.' . $1}; + my $result = $options{snmp}->map_instance(mapping => $mapping, results => { %$snmp_result, %$snmp_result2 }, instance => $_); + my $peer_addr = inet_ntoa($result->{tmnxL2tpTuStatusPeerAddr}); + + $self->{vrtr}->{$vrtr_name}->{active_sessions} += $result->{tmnxL2tpTuStatsActiveSessions}; + $self->{peer}->{$peer_addr}->{active_sessions} += $result->{tmnxL2tpTuStatsActiveSessions}; + $self->{vrtr}->{$vrtr_name}->{'total_sessions_' . $_} = $result->{tmnxL2tpTuStatsTotalSessions}; + $self->{peer}->{$peer_addr}->{'total_sessions_' . $_} = $result->{tmnxL2tpTuStatsTotalSessions}; + } + + if (scalar(keys %{$self->{tunnel}}) <= 0) { + $self->{output}->add_option_msg(short_msg => "No tunnel found."); + $self->{output}->option_exit(); + } + + $self->{cache_name} = "nokia_timos_" . $options{snmp}->get_hostname() . '_' . $options{snmp}->get_port() . '_' . $self->{mode} . '_' . + (defined($self->{option_results}->{filter_vrtr_name}) ? md5_hex($self->{option_results}->{filter_vrtr_name}) : md5_hex('all')) . '_' . + (defined($self->{option_results}->{filter_peer_addr}) ? md5_hex($self->{option_results}->{filter_peer_addr}) : md5_hex('all')) . '_' . + (defined($self->{option_results}->{filter_counters}) ? md5_hex($self->{option_results}->{filter_counters}) : md5_hex('all')); +} + +1; + +__END__ + +=head1 MODE + +Check L2TP usage. + +=over 8 + +=item B<--warning-*> + +Threshold warning. +Can be: 'vrtr-tunnel-total', 'vrtr-tunnel-active-sessions', 'vrtr-tunnel-total-sessions', +'peer-tunnel-total', 'peer-tunnel-active-sessions', 'peer-tunnel-total-sessions'. + +=item B<--critical-*> + +Threshold critical. +Can be: 'vrtr-tunnel-total', 'vrtr-tunnel-active-sessions', 'vrtr-tunnel-total-sessions', +'peer-tunnel-total', 'peer-tunnel-active-sessions', 'peer-tunnel-total-sessions'. + +=item B<--warning-status> + +Set warning threshold for status. +Can used special variables like: %{display}, %{state} + +=item B<--critical-status> + +Set critical threshold for status. +Can used special variables like: %{display}, %{state} + +=item B<--filter-vrtr-name> + +Filter by vrtr name (can be a regexp). + +=item B<--filter-peer-addr> + +Filter by peer addr (can be a regexp). + +=back + +=cut diff --git a/centreon-plugins/network/nokia/timos/snmp/mode/ldpusage.pm b/centreon-plugins/network/nokia/timos/snmp/mode/ldpusage.pm new file mode 100644 index 000000000..4947db849 --- /dev/null +++ b/centreon-plugins/network/nokia/timos/snmp/mode/ldpusage.pm @@ -0,0 +1,276 @@ +# +# 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::nokia::timos::snmp::mode::ldpusage; + +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 = 'IPv4 state : ' . $self->{result_values}->{ipv4_oper_state} . ' (admin: ' . $self->{result_values}->{admin_state} . ')'; + return $msg; +} + +sub custom_status_calc { + my ($self, %options) = @_; + + $self->{result_values}->{ipv4_oper_state} = $options{new_datas}->{$self->{instance} . '_ipv4_oper_state'}; + $self->{result_values}->{admin_state} = $options{new_datas}->{$self->{instance} . '_admin_state'}; + $self->{result_values}->{display} = $options{new_datas}->{$self->{instance} . '_display'}; + return 0; +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'ldp', type => 1, cb_prefix_output => 'prefix_ldp_output', message_multiple => 'All ldp instances are ok' } + ]; + + $self->{maps_counters}->{ldp} = [ + { label => 'status', threshold => 0, set => { + key_values => [ { name => 'ipv4_oper_state' }, { name => 'admin_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 => 'ipv4-active-sessions', set => { + key_values => [ { name => 'ipv4_active_sessions' }, { name => 'display' } ], + output_template => 'IPv4 Active Sessions : %s', + perfdatas => [ + { label => 'ipv4_active_sessions', value => 'ipv4_active_sessions_absolute', template => '%s', + min => 0, label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + { label => 'ipv4-active-link-adj', set => { + key_values => [ { name => 'ipv4_active_link_adj' }, { name => 'display' } ], + output_template => 'IPv4 Active Link Adjacencies : %s', + perfdatas => [ + { label => 'ipv4_active_link_adj', value => 'ipv4_active_link_adj_absolute', template => '%s', + min => 0, label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + { label => 'ipv4-active-target-adj', set => { + key_values => [ { name => 'ipv4_active_target_adj' }, { name => 'display' } ], + output_template => 'IPv4 Active Target Adjacencies : %s', + perfdatas => [ + { label => 'ipv4_active_target_adj', value => 'ipv4_active_target_adj_absolute', template => '%s', + min => 0, label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + { label => 'ipv4-oper-down-events', set => { + key_values => [ { name => 'ipv4_oper_down_events', diff => 1 }, { name => 'display' } ], + output_template => 'IPv4 Oper Down Events : %s', + perfdatas => [ + { label => 'ipv4_oper_down_events', value => 'ipv4_oper_down_events_absolute', template => '%s', + min => 0, label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + ]; +} + +sub prefix_ldp_output { + my ($self, %options) = @_; + + return "LDP instance '" . $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 => '%{admin_state} eq "inService" and %{ipv4_oper_state} !~ /inService|transition/' }, + }); + + 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_oper_state = (1 => 'unknown', 2 => 'inService', 3 => 'outOfService', 4 => 'transition'); +my %map_admin_state = (1 => 'noop', 2 => 'inService', 3 => 'outOfService'); + +# index vRtrID +my $mapping = { + vRtrName => { oid => '.1.3.6.1.4.1.6527.3.1.2.3.1.1.4' }, + vRtrLdpNgGenAdminState => { oid => '.1.3.6.1.4.1.6527.3.1.2.91.47.1.5', map => \%map_admin_state }, + vRtrLdpNgGenIPv4OperState => { oid => '.1.3.6.1.4.1.6527.3.1.2.91.47.1.6', map => \%map_oper_state }, +}; +# index vRtrID +my $mapping2 = { + vLdpNgStatsIPv4OperDownEvents => { oid => '.1.3.6.1.4.1.6527.3.1.2.91.42.1.1' }, + vLdpNgStatsIPv4ActiveSess => { oid => '.1.3.6.1.4.1.6527.3.1.2.91.42.1.3' }, + vLdpNgStatsIPv4ActiveLinkAdj => { oid => '.1.3.6.1.4.1.6527.3.1.2.91.42.1.5' }, + vLdpNgStatsIPv4ActiveTargAdj => { oid => '.1.3.6.1.4.1.6527.3.1.2.91.42.1.7' }, +}; + +sub manage_selection { + my ($self, %options) = @_; + + my $snmp_result = $options{snmp}->get_multiple_table(oids => [ + { oid => $mapping->{vRtrName}->{oid} }, + { oid => $mapping->{vRtrLdpNgGenAdminState}->{oid} }, + { oid => $mapping->{vRtrLdpNgGenIPv4OperState}->{oid} }, + ], return_type => 1, nothing_quit => 1); + $self->{ldp} = {}; + foreach my $oid (keys %{$snmp_result}) { + next if ($oid !~ /^$mapping->{vRtrLdpNgGenAdminState}->{oid}\.(.*)$/); + my $instance = $1; + my $result = $options{snmp}->map_instance(mapping => $mapping, results => $snmp_result, instance => $instance); + + if (!defined($result->{vRtrName}) || $result->{vRtrName} eq '') { + $self->{output}->output_add(long_msg => "skipping LDP '$instance': cannot get a name. please set it.", debug => 1); + next; + } + if (defined($self->{option_results}->{filter_name}) && $self->{option_results}->{filter_name} ne '' && + $result->{vRtrName} !~ /$self->{option_results}->{filter_name}/) { + $self->{output}->output_add(long_msg => "skipping LDP '" . $result->{vRtrName} . "'.", debug => 1); + next; + } + + $self->{ldp}->{$instance} = { display => $result->{vRtrName}, + admin_state => $result->{vRtrLdpNgGenAdminState}, + ipv4_oper_state => $result->{vRtrLdpNgGenIPv4OperState}, + }; + } + + $options{snmp}->load(oids => [$mapping2->{vLdpNgStatsIPv4OperDownEvents}->{oid}, $mapping2->{vLdpNgStatsIPv4ActiveSess}->{oid}, + $mapping2->{vLdpNgStatsIPv4ActiveLinkAdj}->{oid}, $mapping2->{vLdpNgStatsIPv4ActiveTargAdj}->{oid}, + ], + instances => [keys %{$self->{ldp}}], instance_regexp => '^(.*)$'); + $snmp_result = $options{snmp}->get_leef(nothing_quit => 1); + + foreach (keys %{$self->{ldp}}) { + my $result = $options{snmp}->map_instance(mapping => $mapping2, results => $snmp_result, instance => $_); + + $self->{ldp}->{$_}->{ipv4_oper_down_events} = $result->{vLdpNgStatsIPv4OperDownEvents}; + $self->{ldp}->{$_}->{ipv4_active_sessions} = $result->{vLdpNgStatsIPv4ActiveSess}; + $self->{ldp}->{$_}->{ipv4_active_link_adj} = $result->{vLdpNgStatsIPv4ActiveLinkAdj}; + $self->{ldp}->{$_}->{ipv4_active_target_adj} = $result->{vLdpNgStatsIPv4ActiveTargAdj}; + } + + if (scalar(keys %{$self->{ldp}}) <= 0) { + $self->{output}->add_option_msg(short_msg => "No LDP instance found."); + $self->{output}->option_exit(); + } + + $self->{cache_name} = "nokia_timos_" . $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 LDP usage. + +=over 8 + +=item B<--warning-*> + +Threshold warning. +Can be: 'ipv4-oper-down-events', 'ipv4-active-sessions', 'ipv4-active-link-adj', +'ipv4-active-target-adj'. + +=item B<--critical-*> + +Threshold critical. +Can be: 'ipv4-oper-down-events', 'ipv4-active-sessions', 'ipv4-active-link-adj', +'ipv4-active-target-adj'. + +=item B<--warning-status> + +Set warning threshold for status. +Can used special variables like: %{ipv4_oper_state}, %{admin_state}, %{display} + +=item B<--critical-status> + +Set critical threshold for status (Default: '%{admin_state} eq "inService" and %{ipv4_oper_state} !~ /inService|transition/'). +Can used special variables like: %{ipv4_oper_state}, %{admin_state}, %{display} + +=item B<--filter-name> + +Filter by LDP instance name (can be a regexp). + +=back + +=cut diff --git a/centreon-plugins/network/nokia/timos/snmp/mode/listbgp.pm b/centreon-plugins/network/nokia/timos/snmp/mode/listbgp.pm new file mode 100644 index 000000000..fc07a6960 --- /dev/null +++ b/centreon-plugins/network/nokia/timos/snmp/mode/listbgp.pm @@ -0,0 +1,136 @@ +# +# 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::nokia::timos::snmp::mode::listbgp; + +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); +} + +my %map_status = (1 => 'unknown', 2 => 'inService', 3 => 'outOfService', + 4 => 'transition', 5 => 'disabled', +); +my %map_type = (1 => 'noType', 2 => 'internal', 3 => 'external'); +my $oid_vRtrName = '.1.3.6.1.4.1.6527.3.1.2.3.1.1.4'; +my $mapping = { + tBgpPeerNgDescription => { oid => '.1.3.6.1.4.1.6527.3.1.2.14.4.7.1.7' }, + tBgpPeerNgPeerType => { oid => '.1.3.6.1.4.1.6527.3.1.2.14.4.7.1.27', map => \%map_type }, + tBgpPeerNgOperStatus => { oid => '.1.3.6.1.4.1.6527.3.1.2.14.4.7.1.42', map => \%map_status }, + tBgpPeerNgPeerAS4Byte => { oid => '.1.3.6.1.4.1.6527.3.1.2.14.4.7.1.66' }, +}; + +sub manage_selection { + my ($self, %options) = @_; + + my $snmp_result = $options{snmp}->get_multiple_table(oids => [ + { oid => $oid_vRtrName }, + { oid => $mapping->{tBgpPeerNgOperStatus}->{oid} }, + { oid => $mapping->{tBgpPeerNgPeerType}->{oid} }, + { oid => $mapping->{tBgpPeerNgDescription}->{oid} }, + { oid => $mapping->{tBgpPeerNgPeerAS4Byte}->{oid} }, + ], return_type => 1, nothing_quit => 1); + $self->{bgp} = {}; + foreach my $oid (keys %$snmp_result) { + next if ($oid !~ /^$mapping->{tBgpPeerNgPeerAS4Byte}->{oid}\.(\d+)\.(\d+)\.(.*)$/); + my ($vrtr_id, $peer_type, $peer_addr) = ($1, $2, $3); + + my $vrtr_name = $snmp_result->{$oid_vRtrName . '.' . $vrtr_id}; + my $result = $options{snmp}->map_instance(mapping => $mapping, results => $snmp_result, instance => $vrtr_id . '.' . $peer_type . '.' . $peer_addr); + + $self->{bgp}->{$vrtr_id . '.' . $peer_type . '.' . $peer_addr} = { + vrtr_name => $vrtr_name, peer_type => $result->{tBgpPeerNgPeerType}, + peer_addr => $peer_addr, peer_as => $result->{tBgpPeerNgPeerAS4Byte}, + status => $result->{tBgpPeerNgOperStatus}, description => $result->{tBgpPeerNgDescription} }; + } +} + +sub run { + my ($self, %options) = @_; + + $self->manage_selection(%options); + foreach my $instance (sort keys %{$self->{bgp}}) { + $self->{output}->output_add(long_msg => '[vrtr_name = ' . $self->{bgp}->{$instance}->{vrtr_name} . + "] [peer_addr = '" . $self->{bgp}->{$instance}->{peer_addr} . + "'] [peer_as = '" . $self->{bgp}->{$instance}->{peer_as} . + "'] [peer_type = '" . $self->{bgp}->{$instance}->{peer_type} . + "'] [description = '" . $self->{bgp}->{$instance}->{description} . + "'] [status = '" . $self->{bgp}->{$instance}->{status} . + '"]'); + } + + $self->{output}->output_add(severity => 'OK', + short_msg => 'List BGP:'); + $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 => ['vrtr_name', 'peer_addr', 'peer_as', 'peer_type', 'status', 'description']); +} + +sub disco_show { + my ($self, %options) = @_; + + $self->manage_selection(%options); + foreach my $instance (sort keys %{$self->{bgp}}) { + $self->{output}->add_disco_entry(vrtr_name => $self->{bgp}->{$instance}->{vrtr_name}, + peer_addr => $self->{bgp}->{$instance}->{peer_addr}, + peer_as => $self->{bgp}->{$instance}->{peer_as}, + peer_type => $self->{bgp}->{$instance}->{peer_type}, + status => $self->{bgp}->{$instance}->{status}, + description => $self->{bgp}->{$instance}->{description}, + ); + } +} + +1; + +__END__ + +=head1 MODE + +List BGP. + +=over 8 + +=back + +=cut + diff --git a/centreon-plugins/network/nokia/timos/snmp/mode/listisis.pm b/centreon-plugins/network/nokia/timos/snmp/mode/listisis.pm new file mode 100644 index 000000000..41f32c0f2 --- /dev/null +++ b/centreon-plugins/network/nokia/timos/snmp/mode/listisis.pm @@ -0,0 +1,119 @@ +# +# 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::nokia::timos::snmp::mode::listisis; + +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); +} + +my %map_status = (1 => 'unknown', 2 => 'inService', 3 => 'outOfService', 4 => 'transition'); +my $oid_vRtrName = '.1.3.6.1.4.1.6527.3.1.2.3.1.1.4'; +my $mapping = { + tmnxIsisOperState => { oid => '.1.3.6.1.4.1.6527.3.1.2.88.1.1.1.12', map => \%map_status }, +}; + +sub manage_selection { + my ($self, %options) = @_; + + my $snmp_result = $options{snmp}->get_multiple_table(oids => [ + { oid => $oid_vRtrName }, + { oid => $mapping->{tmnxIsisOperState}->{oid} }, + ], return_type => 1, nothing_quit => 1); + $self->{isis} = {}; + foreach my $oid (keys %$snmp_result) { + next if ($oid !~ /^$mapping->{tmnxIsisOperState}->{oid}\.(\d+)\.(\d+)$/); + my ($vrtr_id, $isis_id) = ($1, $2); + + my $vrtr_name = $snmp_result->{$oid_vRtrName . '.' . $vrtr_id}; + my $result = $options{snmp}->map_instance(mapping => $mapping, results => $snmp_result, instance => $vrtr_id . '.' . $isis_id); + + $self->{isis}->{$vrtr_id . '.' . $isis_id} = { + name => $vrtr_name . '.' . $isis_id, + status => $result->{tmnxIsisOperState} + }; + } +} + +sub run { + my ($self, %options) = @_; + + $self->manage_selection(%options); + foreach my $instance (sort keys %{$self->{isis}}) { + $self->{output}->output_add(long_msg => "[name = '" . $self->{isis}->{$instance}->{name} . + "'] [status = '" . $self->{isis}->{$instance}->{status} . + '"]'); + } + + $self->{output}->output_add(severity => 'OK', + short_msg => 'List IS-IS:'); + $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', 'status']); +} + +sub disco_show { + my ($self, %options) = @_; + + $self->manage_selection(%options); + foreach my $instance (sort keys %{$self->{isis}}) { + $self->{output}->add_disco_entry(name => $self->{isis}->{$instance}->{name}, + status => $self->{isis}->{$instance}->{status}, + ); + } +} + +1; + +__END__ + +=head1 MODE + +List IS-IS instances. + +=over 8 + +=back + +=cut + diff --git a/centreon-plugins/network/nokia/timos/snmp/mode/listldp.pm b/centreon-plugins/network/nokia/timos/snmp/mode/listldp.pm new file mode 100644 index 000000000..c0686433c --- /dev/null +++ b/centreon-plugins/network/nokia/timos/snmp/mode/listldp.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::nokia::timos::snmp::mode::listldp; + +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->{ldp} = {}; + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::init(%options); +} + +my %map_oper_state = (1 => 'unknown', 2 => 'inService', 3 => 'outOfService', 4 => 'transition'); +my %map_admin_state = (1 => 'noop', 2 => 'inService', 3 => 'outOfService'); +my $mapping = { + vRtrName => { oid => '.1.3.6.1.4.1.6527.3.1.2.3.1.1.4' }, + vRtrLdpNgGenAdminState => { oid => '.1.3.6.1.4.1.6527.3.1.2.91.47.1.5', map => \%map_admin_state }, + vRtrLdpNgGenIPv4OperState => { oid => '.1.3.6.1.4.1.6527.3.1.2.91.47.1.6', map => \%map_oper_state }, +}; + +sub manage_selection { + my ($self, %options) = @_; + + my $snmp_result = $options{snmp}->get_multiple_table(oids => [ + { oid => $mapping->{vRtrName}->{oid} }, + { oid => $mapping->{vRtrLdpNgGenAdminState}->{oid} }, + { oid => $mapping->{vRtrLdpNgGenIPv4OperState}->{oid} }, + ], + return_type => 1, nothing_quit => 1); + + foreach my $oid (keys %{$snmp_result}) { + next if ($oid !~ /^$mapping->{vRtrLdpNgGenAdminState}->{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->{vRtrName} !~ /$self->{option_results}->{filter_name}/) { + $self->{output}->output_add(long_msg => "skipping '" . $result->{vRtrName} . "': no matching filter.", debug => 1); + next; + } + + $self->{ldp}->{$instance} = { name => $result->{vRtrName}, + admin_state => $result->{vRtrLdpNgGenAdminState}, ipv4_oper_state => $result->{vRtrLdpNgGenIPv4OperState} }; + } +} + +sub run { + my ($self, %options) = @_; + + $self->manage_selection(%options); + foreach my $instance (sort keys %{$self->{ldp}}) { + $self->{output}->output_add(long_msg => '[name = ' . $self->{ldp}->{$instance}->{name} . + "] [admin = '" . $self->{ldp}->{$instance}->{admin_state} . + "'] [ipv4_oper = '" . $self->{ldp}->{$instance}->{ipv4_oper_state} . '"]'); + } + + $self->{output}->output_add(severity => 'OK', + short_msg => 'List LDPs:'); + $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', 'admin', 'ipv4_oper']); +} + +sub disco_show { + my ($self, %options) = @_; + + $self->manage_selection(%options); + foreach my $instance (sort keys %{$self->{ldp}}) { + $self->{output}->add_disco_entry(name => $self->{ldp}->{$instance}->{name}, + admin => $self->{ldp}->{$instance}->{admin_state}, + ipv4_oper => $self->{ldp}->{$instance}->{ipv4_oper_state}, + ); + } +} + +1; + +__END__ + +=head1 MODE + +List LDPs. + +=over 8 + +=item B<--filter-name> + +Filter by ldp instance (can be a regexp). + +=back + +=cut + diff --git a/centreon-plugins/network/nokia/timos/snmp/mode/listsap.pm b/centreon-plugins/network/nokia/timos/snmp/mode/listsap.pm new file mode 100644 index 000000000..dff5ee06a --- /dev/null +++ b/centreon-plugins/network/nokia/timos/snmp/mode/listsap.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::nokia::timos::snmp::mode::listsap; + +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' }, + }); + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::init(%options); +} + +my %map_admin_status = (1 => 'up', 2 => 'down'); +my %map_oper_status = (1 => 'up', 2 => 'down', 3 => 'ingressQosMismatch', + 4 => 'egressQosMismatch', 5 => 'portMtuTooSmall', 6 => 'svcAdminDown', + 7 => 'iesIfAdminDown', +); +my $mapping = { + sapDescription => { oid => '.1.3.6.1.4.1.6527.3.1.2.4.3.2.1.5' }, + sapAdminStatus => { oid => '.1.3.6.1.4.1.6527.3.1.2.4.3.2.1.6', map => \%map_admin_status }, + sapOperStatus => { oid => '.1.3.6.1.4.1.6527.3.1.2.4.3.2.1.7', map => \%map_oper_status }, +}; + +sub manage_selection { + my ($self, %options) = @_; + + my $snmp_result = $options{snmp}->get_multiple_table(oids => [ + { oid => $mapping->{sapDescription}->{oid} }, + { oid => $mapping->{sapAdminStatus}->{oid} }, + { oid => $mapping->{sapOperStatus}->{oid} }, + ], + return_type => 1, nothing_quit => 1); + $self->{sap} = {}; + foreach my $oid (keys %{$snmp_result}) { + next if ($oid !~ /^$mapping->{sapOperStatus}->{oid}\.(.*)$/); + my $instance = $1; + my $result = $options{snmp}->map_instance(mapping => $mapping, results => $snmp_result, instance => $instance); + + if (!defined($result->{sapDescription}) || $result->{sapDescription} eq '') { + $self->{output}->output_add(long_msg => "skipping sap '$instance': cannot get a description. please set it.", debug => 1); + next; + } + if (defined($self->{option_results}->{filter_name}) && $self->{option_results}->{filter_name} ne '' && + $result->{sapDescription} !~ /$self->{option_results}->{filter_name}/) { + $self->{output}->output_add(long_msg => "skipping '" . $result->{sapDescription} . "': no matching filter.", debug => 1); + next; + } + + $self->{sap}->{$instance} = { description => $result->{sapDescription}, + admin_state => $result->{sapAdminStatus}, oper_state => $result->{sapOperStatus} }; + } +} + +sub run { + my ($self, %options) = @_; + + $self->manage_selection(%options); + foreach my $instance (sort keys %{$self->{sap}}) { + $self->{output}->output_add(long_msg => '[description = ' . $self->{sap}->{$instance}->{description} . + "] [admin = '" . $self->{sap}->{$instance}->{admin_state} . + "'] [oper = '" . $self->{sap}->{$instance}->{oper_state} . '"]'); + } + + $self->{output}->output_add(severity => 'OK', + short_msg => 'List SAPs:'); + $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 => ['description', 'admin', 'oper']); +} + +sub disco_show { + my ($self, %options) = @_; + + $self->manage_selection(%options); + foreach my $instance (sort keys %{$self->{sap}}) { + $self->{output}->add_disco_entry(description => $self->{sap}->{$instance}->{description}, + admin => $self->{sap}->{$instance}->{admin_state}, + oper => $self->{sap}->{$instance}->{oper_state}, + ); + } +} + +1; + +__END__ + +=head1 MODE + +List Service Access Points. + +=over 8 + +=item B<--filter-name> + +Filter by sap description (can be a regexp). + +=back + +=cut + diff --git a/centreon-plugins/network/nokia/timos/snmp/mode/listvrtr.pm b/centreon-plugins/network/nokia/timos/snmp/mode/listvrtr.pm new file mode 100644 index 000000000..8250192f3 --- /dev/null +++ b/centreon-plugins/network/nokia/timos/snmp/mode/listvrtr.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::nokia::timos::snmp::mode::listvrtr; + +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' }, + }); + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::init(%options); +} + +my %map_type = (1 => 'baseRouter', 2 => 'vprn', 3 => 'vr'); +my $mapping = { + vRtrName => { oid => '.1.3.6.1.4.1.6527.3.1.2.3.1.1.4' }, + vRtrType => { oid => '.1.3.6.1.4.1.6527.3.1.2.3.1.1.28', map => \%map_type }, +}; + +sub manage_selection { + my ($self, %options) = @_; + + my $snmp_result = $options{snmp}->get_multiple_table(oids => [ + { oid => $mapping->{vRtrName}->{oid} }, + { oid => $mapping->{vRtrType}->{oid} }, + ], + return_type => 1, nothing_quit => 1); + $self->{vrtr} = {}; + foreach my $oid (keys %{$snmp_result}) { + next if ($oid !~ /^$mapping->{vRtrName}->{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->{vRtrName} !~ /$self->{option_results}->{filter_name}/) { + $self->{output}->output_add(long_msg => "skipping '" . $result->{vRtrName} . "': no matching filter.", debug => 1); + next; + } + + $self->{vrtr}->{$instance} = { + name => $result->{vRtrName}, + type => $result->{vRtrType} + }; + } +} + +sub run { + my ($self, %options) = @_; + + $self->manage_selection(%options); + foreach my $instance (sort keys %{$self->{vrtr}}) { + $self->{output}->output_add(long_msg => '[name = ' . $self->{vrtr}->{$instance}->{name} . + "] [type = '" . $self->{vrtr}->{$instance}->{type} . + "']"); + } + + $self->{output}->output_add(severity => 'OK', + short_msg => 'List virtual routers:'); + $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 my $instance (sort keys %{$self->{vrtr}}) { + $self->{output}->add_disco_entry(name => $self->{vrtr}->{$instance}->{name}, + type => $self->{vrtr}->{$instance}->{type}, + ); + } +} + +1; + +__END__ + +=head1 MODE + +List virtual routers. + +=over 8 + +=item B<--filter-name> + +Filter by virtual router name (can be a regexp). + +=back + +=cut + diff --git a/centreon-plugins/network/nokia/timos/snmp/mode/memory.pm b/centreon-plugins/network/nokia/timos/snmp/mode/memory.pm new file mode 100644 index 000000000..9b59ba400 --- /dev/null +++ b/centreon-plugins/network/nokia/timos/snmp/mode/memory.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 network::nokia::timos::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}->{free} = $options{new_datas}->{$self->{instance} . '_free'}; + $self->{result_values}->{used} = $options{new_datas}->{$self->{instance} . '_used'}; + $self->{result_values}->{total} = $self->{result_values}->{free} + $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}; + $self->{result_values}->{free} = $self->{result_values}->{total} - $self->{result_values}->{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 => 'used' }, { name => 'free' } ], + 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_sgiKbMemoryUsed = '.1.3.6.1.4.1.6527.3.1.2.1.1.9.0'; # in KB + my $oid_sgiKbMemoryAvailable = '.1.3.6.1.4.1.6527.3.1.2.1.1.10.0'; # in KB + my $oid_sgiMemoryUsed = '.1.3.6.1.4.1.6527.3.1.2.1.1.2.0'; # in B + my $oid_sgiMemoryAvailable = '.1.3.6.1.4.1.6527.3.1.2.1.1.3.0'; # in B + my $snmp_result = $options{snmp}->get_leef(oids => [$oid_sgiKbMemoryUsed, $oid_sgiKbMemoryAvailable, $oid_sgiMemoryUsed, $oid_sgiMemoryAvailable], + nothing_quit => 1); + + $self->{memory} = { + used => defined($snmp_result->{$oid_sgiKbMemoryUsed}) ? $snmp_result->{$oid_sgiKbMemoryUsed} * 1024 : $snmp_result->{$oid_sgiMemoryUsed}, + free => defined($snmp_result->{$oid_sgiKbMemoryAvailable}) ? $snmp_result->{$oid_sgiKbMemoryAvailable} * 1024 : $snmp_result->{$oid_sgiMemoryAvailable}, + }; + +} + +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/nokia/timos/snmp/mode/sapusage.pm b/centreon-plugins/network/nokia/timos/snmp/mode/sapusage.pm new file mode 100644 index 000000000..60cf7561e --- /dev/null +++ b/centreon-plugins/network/nokia/timos/snmp/mode/sapusage.pm @@ -0,0 +1,286 @@ +# +# 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::nokia::timos::snmp::mode::sapusage; + +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 = 'state : ' . $self->{result_values}->{oper_state} . ' (admin: ' . $self->{result_values}->{admin_state} . ')'; + return $msg; +} + +sub custom_status_calc { + my ($self, %options) = @_; + + $self->{result_values}->{oper_state} = $options{new_datas}->{$self->{instance} . '_sapOperStatus'}; + $self->{result_values}->{admin_state} = $options{new_datas}->{$self->{instance} . '_sapAdminStatus'}; + $self->{result_values}->{display} = $options{new_datas}->{$self->{instance} . '_display'}; + return 0; +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'sap', type => 1, cb_prefix_output => 'prefix_sap_output', message_multiple => 'All service access points are ok' } + ]; + + $self->{maps_counters}->{sap} = [ + { label => 'status', threshold => 0, set => { + key_values => [ { name => 'sapAdminStatus' }, { name => 'sapOperStatus' }, { 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-below-cir', set => { + key_values => [ { name => 'sapBaseStatsIngressQchipForwardedInProfOctets', diff => 1 }, { name => 'display' } ], + per_second => 1, output_change_bytes => 2, + output_template => 'Traffic In Below CIR : %s %s/s', + perfdatas => [ + { label => 'traffic_in_below_cir', value => 'sapBaseStatsIngressQchipForwardedInProfOctets_per_second', template => '%.2f', + min => 0, unit => 'b/s', label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + { label => 'traffic-in-above-cir', set => { + key_values => [ { name => 'sapBaseStatsIngressQchipForwardedOutProfOctets', diff => 1 }, { name => 'display' } ], + per_second => 1, output_change_bytes => 2, + output_template => 'Traffic In Above CIR : %s %s/s', + perfdatas => [ + { label => 'traffic_in_above_cir', value => 'sapBaseStatsIngressQchipForwardedOutProfOctets_per_second', template => '%.2f', + min => 0, unit => 'b/s', label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + { label => 'traffic-out-below-cir', set => { + key_values => [ { name => 'sapBaseStatsEgressQchipForwardedInProfOctets', diff => 1 }, { name => 'display' } ], + per_second => 1, output_change_bytes => 2, + output_template => 'Traffic Out Below CIR : %s %s/s', + perfdatas => [ + { label => 'traffic_out_below_cir', value => 'sapBaseStatsEgressQchipForwardedInProfOctets_per_second', template => '%.2f', + min => 0, unit => 'b/s', label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + { label => 'traffic-out-above-cir', set => { + key_values => [ { name => 'sapBaseStatsEgressQchipForwardedOutProfOctets', diff => 1 }, { name => 'display' } ], + per_second => 1, output_change_bytes => 2, + output_template => 'Traffic Out Above CIR : %s %s/s', + perfdatas => [ + { label => 'traffic_out_above_cir', value => 'sapBaseStatsEgressQchipForwardedOutProfOctets_per_second', template => '%.2f', + min => 0, unit => 'b/s', label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + ]; +} + +sub prefix_sap_output { + my ($self, %options) = @_; + + return "Service Access Point '" . $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 => '%{admin_state} eq "up" and %{oper_state} !~ /up/' }, + }); + + 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_admin_status = (1 => 'up', 2 => 'down'); +my %map_oper_status = (1 => 'up', 2 => 'down', 3 => 'ingressQosMismatch', + 4 => 'egressQosMismatch', 5 => 'portMtuTooSmall', 6 => 'svcAdminDown', + 7 => 'iesIfAdminDown', +); +my $mapping = { + sapDescription => { oid => '.1.3.6.1.4.1.6527.3.1.2.4.3.2.1.5' }, + sapAdminStatus => { oid => '.1.3.6.1.4.1.6527.3.1.2.4.3.2.1.6', map => \%map_admin_status }, + sapOperStatus => { oid => '.1.3.6.1.4.1.6527.3.1.2.4.3.2.1.7', map => \%map_oper_status }, + sapBaseStatsIngressQchipForwardedInProfOctets => { oid => '.1.3.6.1.4.1.6527.3.1.2.4.3.6.1.12' }, + sapBaseStatsIngressQchipForwardedOutProfOctets => { oid => '.1.3.6.1.4.1.6527.3.1.2.4.3.6.1.14' }, + sapBaseStatsEgressQchipForwardedInProfOctets => { oid => '.1.3.6.1.4.1.6527.3.1.2.4.3.6.1.20' }, + sapBaseStatsEgressQchipForwardedOutProfOctets => { oid => '.1.3.6.1.4.1.6527.3.1.2.4.3.6.1.22' }, +}; + +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(); + } + + my $snmp_result = $options{snmp}->get_multiple_table(oids => [ + { oid => $mapping->{sapDescription}->{oid} }, + ], return_type => 1, nothing_quit => 1); + my $done_description = {}; + $self->{sap} = {}; + foreach my $oid (keys %{$snmp_result}) { + $oid =~ /^$mapping->{sapDescription}->{oid}\.(.*)$/; + my $instance = $1; + if (!defined($snmp_result->{$oid}) || $snmp_result->{$oid} eq '') { + $self->{output}->output_add(long_msg => "skipping sap '$instance': cannot get a description. please set it.", debug => 1); + next; + } + if (defined($self->{option_results}->{filter_name}) && $self->{option_results}->{filter_name} ne '' && + $snmp_result->{$oid} !~ /$self->{option_results}->{filter_name}/) { + $self->{output}->output_add(long_msg => "skipping sap '" . $snmp_result->{$oid} . "'.", debug => 1); + next; + } + + if (defined($done_description->{$snmp_result->{$oid}})) { + $self->{output}->output_add(long_msg => "skipping sap '" . $snmp_result->{$oid} . "': duplicated description.", debug => 1); + next; + } else { + $done_description->{$snmp_result->{$oid}} = 1; + } + $self->{sap}->{$instance} = { display => $snmp_result->{$oid} }; + } + + $options{snmp}->load(oids => [$mapping->{sapAdminStatus}->{oid}, $mapping->{sapOperStatus}->{oid}, + $mapping->{sapBaseStatsIngressQchipForwardedInProfOctets}->{oid}, $mapping->{sapBaseStatsIngressQchipForwardedOutProfOctets}->{oid}, + $mapping->{sapBaseStatsEgressQchipForwardedInProfOctets}->{oid}, $mapping->{sapBaseStatsEgressQchipForwardedOutProfOctets}->{oid}, + ], + instances => [keys %{$self->{sap}}], instance_regexp => '^(.*)$'); + $snmp_result = $options{snmp}->get_leef(nothing_quit => 1); + + foreach (keys %{$self->{sap}}) { + my $result = $options{snmp}->map_instance(mapping => $mapping, results => $snmp_result, instance => $_); + + foreach my $name (('sapBaseStatsIngressQchipForwardedInProfOctets', 'sapBaseStatsIngressQchipForwardedOutProfOctets', + 'sapBaseStatsEgressQchipForwardedInProfOctets', 'sapBaseStatsEgressQchipForwardedOutProfOctets')) { + $result->{$name} *= 8 if (defined($result->{$name})); + } + + foreach my $name (keys %$mapping) { + $self->{sap}->{$_}->{$name} = $result->{$name} if (defined($result->{$name})); + } + } + + if (scalar(keys %{$self->{sap}}) <= 0) { + $self->{output}->add_option_msg(short_msg => "No service access point found."); + $self->{output}->option_exit(); + } + + $self->{cache_name} = "nokia_timos_" . $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 service access point usage. + +=over 8 + +=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: '%{admin_state} eq "up" and %{oper_state} !~ /up/'). +Can used special variables like: %{status}, %{display} + +=item B<--warning-*> + +Threshold warning. +Can be: 'traffic-in-above-cir', 'traffic-in-below-cir', 'traffic-out-above-cir', 'traffic-out-below-cir'. + +=item B<--critical-*> + +Threshold critical. +Can be: 'traffic-in-above-cir', 'traffic-in-below-cir', 'traffic-out-above-cir', 'traffic-out-below-cir'. + +=item B<--filter-name> + +Filter by virtual server name (can be a regexp). + +=back + +=cut diff --git a/centreon-plugins/network/nokia/timos/snmp/plugin.pm b/centreon-plugins/network/nokia/timos/snmp/plugin.pm new file mode 100644 index 000000000..2e13bdccc --- /dev/null +++ b/centreon-plugins/network/nokia/timos/snmp/plugin.pm @@ -0,0 +1,63 @@ +# +# 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::nokia::timos::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}} = ( + 'bgp-usage' => 'network::nokia::timos::snmp::mode::bgpusage', + 'cpu' => 'network::nokia::timos::snmp::mode::cpu', + 'hardware' => 'network::nokia::timos::snmp::mode::hardware', + 'l2tp-usage' => 'network::nokia::timos::snmp::mode::l2tpusage', + 'ldp-usage' => 'network::nokia::timos::snmp::mode::ldpusage', + 'interfaces' => 'snmp_standard::mode::interfaces', + 'isis-usage' => 'network::nokia::timos::snmp::mode::isisusage', + 'list-bgp' => 'network::nokia::timos::snmp::mode::listbgp', + 'list-interfaces' => 'snmp_standard::mode::listinterfaces', + 'list-isis' => 'network::nokia::timos::snmp::mode::listisis', + 'list-ldp' => 'network::nokia::timos::snmp::mode::listldp', + 'list-sap' => 'network::nokia::timos::snmp::mode::listsap', + 'list-vrtr' => 'network::nokia::timos::snmp::mode::listvrtr', + 'memory' => 'network::nokia::timos::snmp::mode::memory', + 'sap-usage' => 'network::nokia::timos::snmp::mode::sapusage', + 'uptime' => 'snmp_standard::mode::uptime', + ); + + return $self; +} + +1; + +__END__ + +=head1 PLUGIN DESCRIPTION + +Check Nokia TiMOS (SR OS) equipments (7750SR, 7210SAS) in SNMP. + +=cut diff --git a/centreon-plugins/network/radware/alteon/snmp/mode/vserverstatus.pm b/centreon-plugins/network/radware/alteon/snmp/mode/vserverstatus.pm index 2d58f7770..a26209f6f 100644 --- a/centreon-plugins/network/radware/alteon/snmp/mode/vserverstatus.pm +++ b/centreon-plugins/network/radware/alteon/snmp/mode/vserverstatus.pm @@ -80,7 +80,7 @@ sub set_counters { 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'), + closure_custom_threshold_check => $self->can('custom_status_threshold'), } }, { label => 'traffic', set => { diff --git a/centreon-plugins/network/raisecom/snmp/mode/components/fan.pm b/centreon-plugins/network/raisecom/snmp/mode/components/fan.pm new file mode 100644 index 000000000..f75b3ca9b --- /dev/null +++ b/centreon-plugins/network/raisecom/snmp/mode/components/fan.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 network::raisecom::snmp::mode::components::fan; + +use strict; +use warnings; + +my %map_fan_state = ( + 1 => 'normal', + 2 => 'abnormal', +); + +my $mapping = { + raisecomFanSpeedValue => { oid => '.1.3.6.1.4.1.8886.1.1.5.2.2.1.2' }, + raisecomFanWorkState => { oid => '.1.3.6.1.4.1.8886.1.1.5.2.2.1.3', map => \%map_fan_state }, +}; +my $oid_raisecomFanMonitorStateEntry = '.1.3.6.1.4.1.8886.1.1.5.2.2.1'; + +sub load { + my ($self) = @_; + + push @{$self->{request}}, { oid => $oid_raisecomFanMonitorStateEntry }; +} + +sub check { + my ($self) = @_; + + $self->{output}->output_add(long_msg => "Checking fans"); + $self->{components}->{fan} = {name => 'fan', total => 0, skip => 0}; + return if ($self->check_filter(section => 'fan')); + + foreach my $oid ($self->{snmp}->oid_lex_sort(keys %{$self->{results}->{$oid_raisecomFanMonitorStateEntry}})) { + next if ($oid !~ /^$mapping->{raisecomFanWorkState}->{oid}\.(.*)$/); + my $instance = $1; + my $result = $self->{snmp}->map_instance(mapping => $mapping, results => $self->{results}->{$oid_raisecomFanMonitorStateEntry}, instance => $instance); + + next if ($self->check_filter(section => 'fan', instance => $instance)); + + $self->{components}->{fan}->{total}++; + $self->{output}->output_add(long_msg => sprintf("Fan '%s' status is '%s' [instance = %s]", + $instance, $result->{raisecomFanWorkState}, $instance)); + my $exit = $self->get_severity(section => 'fan', value => $result->{raisecomFanWorkState}); + 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->{raisecomFanWorkState})); + } + + my ($exit2, $warn, $crit) = $self->get_severity_numeric(section => 'fan.speed', instance => $instance, value => $result->{raisecomFanSpeedValue}); + if (!$self->{output}->is_status(value => $exit2, compare => 'ok', litteral => 1)) { + $self->{output}->output_add(severity => $exit2, + short_msg => sprintf("Fan speed '%s' is %s rpm", $instance, $result->{raisecomFanSpeedValue})); + } + + $self->{output}->perfdata_add(label => 'fan_' . $instance, unit => 'rpm', + value => $result->{raisecomFanSpeedValue}, + warning => $warn, + critical => $crit, + min => 0); + } +} + +1; diff --git a/centreon-plugins/network/raisecom/snmp/mode/components/temperature.pm b/centreon-plugins/network/raisecom/snmp/mode/components/temperature.pm new file mode 100644 index 000000000..03b5844a3 --- /dev/null +++ b/centreon-plugins/network/raisecom/snmp/mode/components/temperature.pm @@ -0,0 +1,83 @@ +# +# 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::raisecom::snmp::mode::components::temperature; + +use strict; +use warnings; + +my $mapping = { + raisecomTemperatureValue => { oid => '.1.3.6.1.4.1.8886.1.1.4.2.1' }, + raisecomTemperatureThresholdLow => { oid => '.1.3.6.1.4.1.8886.1.1.4.2.5' }, + raisecomTemperatureThresholdHigh => { oid => '.1.3.6.1.4.1.8886.1.1.4.2.6' }, +}; +my $oid_raisecomTemperatureEntry = '.1.3.6.1.4.1.8886.1.1.4.2'; + +sub load { + my ($self) = @_; + + push @{$self->{request}}, { oid => $oid_raisecomTemperatureEntry }; +} + +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')); + + foreach my $oid ($self->{snmp}->oid_lex_sort(keys %{$self->{results}->{$oid_raisecomTemperatureEntry}})) { + next if ($oid !~ /^$mapping->{raisecomTemperatureValue}->{oid}\.(.*)$/); + my $instance = $1; + my $result = $self->{snmp}->map_instance(mapping => $mapping, results => $self->{results}->{$oid_raisecomTemperatureEntry}, instance => $instance); + + next if ($self->check_filter(section => 'temperature', instance => $instance)); + $self->{components}->{temperature}->{total}++; + + $self->{output}->output_add(long_msg => sprintf("temperature '%s' is %.2f C [instance: %s].", + $instance, $result->{raisecomTemperatureValue}, $instance + )); + + my ($exit, $warn, $crit, $checked) = $self->get_severity_numeric(section => 'temperature', instance => $instance, value => $result->{raisecomTemperatureValue}); + if ($checked == 0) { + my $warn_th = $result->{raisecomTemperatureThresholdLow} . ':'; + my $crit_th = ':' . $result->{raisecomTemperatureThresholdHigh}; + $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->{raisecomTemperatureValue}, 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 %.2f C", $instance, $result->{raisecomTemperatureValue})); + } + $self->{output}->perfdata_add(label => 'temp_' . $instance, unit => 'C', + value => $result->{raisecomTemperatureValue}, + warning => $warn, + critical => $crit, + ); + } +} + +1; diff --git a/centreon-plugins/network/raisecom/snmp/mode/components/voltage.pm b/centreon-plugins/network/raisecom/snmp/mode/components/voltage.pm new file mode 100644 index 000000000..af685576c --- /dev/null +++ b/centreon-plugins/network/raisecom/snmp/mode/components/voltage.pm @@ -0,0 +1,83 @@ +# +# 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::raisecom::snmp::mode::components::voltage; + +use strict; +use warnings; + +my $mapping = { + raisecomVoltValue => { oid => '.1.3.6.1.4.1.8886.1.1.4.3.1.1.3' }, + raisecomVoltThresholdLow => { oid => '.1.3.6.1.4.1.8886.1.1.4.3.1.1.7' }, + raisecomVoltThresholdHigh => { oid => '.1.3.6.1.4.1.8886.1.1.4.3.1.1.8' }, +}; +my $oid_raisecomVoltEntry = '.1.3.6.1.4.1.8886.1.1.4.3.1.1'; + +sub load { + my ($self) = @_; + + push @{$self->{request}}, { oid => $oid_raisecomVoltEntry }; +} + +sub check { + my ($self) = @_; + + $self->{output}->output_add(long_msg => "Checking voltages"); + $self->{components}->{voltage} = {name => 'voltages', total => 0, skip => 0}; + return if ($self->check_filter(section => 'voltage')); + + foreach my $oid ($self->{snmp}->oid_lex_sort(keys %{$self->{results}->{$oid_raisecomVoltEntry}})) { + next if ($oid !~ /^$mapping->{raisecomVoltValue}->{oid}\.(.*)$/); + my $instance = $1; + my $result = $self->{snmp}->map_instance(mapping => $mapping, results => $self->{results}->{$oid_raisecomVoltEntry}, instance => $instance); + + next if ($self->check_filter(section => 'voltage', instance => $instance)); + $self->{components}->{voltage}->{total}++; + + $self->{output}->output_add(long_msg => sprintf("voltage '%s' is %.2f mV [instance: %s].", + $instance, $result->{raisecomVoltValue}, $instance + )); + + my ($exit, $warn, $crit, $checked) = $self->get_severity_numeric(section => 'voltage', instance => $instance, value => $result->{raisecomVoltValue}); + if ($checked == 0) { + my $warn_th = $result->{raisecomVoltThresholdLow} . ':'; + my $crit_th = ':' . $result->{raisecomVoltThresholdHigh}; + $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->{raisecomVoltValue}, 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 %.2f mV", $instance, $result->{raisecomVoltValue})); + } + $self->{output}->perfdata_add(label => 'volt_' . $instance, unit => 'mV', + value => $result->{raisecomVoltValue}, + warning => $warn, + critical => $crit, + ); + } +} + +1; diff --git a/centreon-plugins/network/raisecom/snmp/mode/cpu.pm b/centreon-plugins/network/raisecom/snmp/mode/cpu.pm new file mode 100644 index 000000000..f95f06f03 --- /dev/null +++ b/centreon-plugins/network/raisecom/snmp/mode/cpu.pm @@ -0,0 +1,145 @@ +# +# 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::raisecom::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 => 'cpu', type => 0, cb_prefix_output => 'prefix_cpu_output' } + ]; + + $self->{maps_counters}->{cpu} = [ + { label => '5s', set => { + key_values => [ { name => 'fiveSec' } ], + output_template => '%.2f%% (5sec)', + perfdatas => [ + { label => 'cpu_5s', value => 'fiveSec_absolute', template => '%.2f', + min => 0, max => 100, unit => '%' }, + ], + } + }, + { label => '1m', set => { + key_values => [ { name => 'oneMin' } ], + output_template => '%.2f%% (1min)', + perfdatas => [ + { label => 'cpu_1m', value => 'oneMin_absolute', template => '%.2f', + min => 0, max => 100, unit => '%' }, + ], + } + }, + { label => '10m', set => { + key_values => [ { name => 'tenMin' } ], + output_template => '%.2f%% (10min)', + perfdatas => [ + { label => 'cpu_10m', value => 'tenMin_absolute', template => '%.2f', + min => 0, max => 100, unit => '%' }, + ], + } + }, + { label => '2h', set => { + key_values => [ { name => 'twoHour' } ], + output_template => '%.2f%% (2h)', + perfdatas => [ + { label => 'cpu_2h', value => 'twoHour_absolute', template => '%.2f', + min => 0, max => 100, unit => '%' }, + ], + } + }, + ]; +} + +sub prefix_cpu_output { + my ($self, %options) = @_; + + return "CPU Usage "; +} + +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_period = (1 => 'oneSec', 2 => 'fiveSec', 3 => 'oneMin', 4 => 'tenMin', 5 => 'twoHour'); + +my $mapping = { + raisecomCPUUtilizationPeriod => { oid => '.1.3.6.1.4.1.8886.1.1.1.5.1.1.1.2', map => \%mapping_period }, + raisecomCPUUtilization => { oid => '.1.3.6.1.4.1.8886.1.1.1.5.1.1.1.3' }, +}; + +my $oid_raisecomCPUUtilizationEntry = '.1.3.6.1.4.1.8886.1.1.1.5.1.1.1'; + +sub manage_selection { + my ($self, %options) = @_; + + $self->{cpu} = {}; + my $snmp_result = $options{snmp}->get_table(oid => $oid_raisecomCPUUtilizationEntry, + nothing_quit => 1); + foreach my $oid (keys %{$snmp_result}) { + next if ($oid !~ /^$mapping->{raisecomCPUUtilization}->{oid}\.(.*)$/); + my $instance = $1; + my $result = $options{snmp}->map_instance(mapping => $mapping, results => $snmp_result, instance => $instance); + + $self->{cpu}->{$result->{raisecomCPUUtilizationPeriod}} = $result->{raisecomCPUUtilization}; + } +} + +1; + +__END__ + +=head1 MODE + +Check CPU usage. + +=over 8 + +=item B<--filter-counters> + +Only display some counters (regexp can be used). +Example: --filter-counters='^(1s|1m)$' + +=item B<--warning-*> + +Threshold warning. +Can be: '1s', '5s', '1m', '10m', '2h'. + +=item B<--critical-*> + +Threshold critical. +Can be: '1s', '5s', '1m', '10m', '2h'. + +=back + +=cut diff --git a/centreon-plugins/network/raisecom/snmp/mode/hardware.pm b/centreon-plugins/network/raisecom/snmp/mode/hardware.pm new file mode 100644 index 000000000..45be0e383 --- /dev/null +++ b/centreon-plugins/network/raisecom/snmp/mode/hardware.pm @@ -0,0 +1,110 @@ +# +# 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::raisecom::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|voltage)$'; + $self->{regexp_threshold_numeric_check_section_option} = '^(temperature|fan.speed|voltage)$'; + + $self->{cb_hook2} = 'snmp_execute'; + + $self->{thresholds} = { + fan => [ + ['abnormal', 'CRITICAL'], + ['normal', 'OK'], + ], + }; + + $self->{components_path} = 'network::raisecom::snmp::mode::components'; + $self->{components_module} = ['fan', 'temperature', 'voltage']; +} + +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: 'temperature', 'fan', 'voltage'. + +=item B<--filter> + +Exclude some parts (comma seperated list) (Example: --filter=fan +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,WARNING,twoHour' + +=item B<--warning> + +Set warning threshold for temperatures, fan speed (syntax: type,instance,threshold) +Example: --warning='temperature,.*,30' + +=item B<--critical> + +Set critical threshold for temperatures, fan speed (syntax: type,instance,threshold) +Example: --critical='temperature,.*,40' + +=back + +=cut diff --git a/centreon-plugins/network/raisecom/snmp/mode/memory.pm b/centreon-plugins/network/raisecom/snmp/mode/memory.pm new file mode 100644 index 000000000..58e1cfa2e --- /dev/null +++ b/centreon-plugins/network/raisecom/snmp/mode/memory.pm @@ -0,0 +1,116 @@ +# +# 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::raisecom::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_raisecomAvailableMemory = '.1.3.6.1.4.1.8886.1.1.3.2.0'; + my $oid_raisecomTotalMemory = '.1.3.6.1.4.1.8886.1.1.3.1.0'; + + my $oids = [$oid_raisecomAvailableMemory, $oid_raisecomTotalMemory]; + + my $result = $self->{snmp}->get_leef(oids => $oids, + nothing_quit => 1); + + my $free_size = $result->{$oid_raisecomAvailableMemory}; + my $total_size = $result->{$oid_raisecomTotalMemory}; + my $used_size = $total_size - $free_size; + + my $prct_used = $used_size * 100 / $total_size; + my $prct_free = 100 - $prct_used; + 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 ($used_value, $used_unit) = $self->{perfdata}->change_bytes(value => $used_size); + my ($free_value, $free_unit) = $self->{perfdata}->change_bytes(value => $free_size); + + $self->{output}->output_add(severity => $exit, + short_msg => sprintf("Memory Total: %s, Used: %s (%.2f%%), Free: %s (%.2f%%)", + $total_value . " " . $total_unit, + $used_value . " " . $used_unit, $prct_used, + $free_value . " " . $free_unit, $prct_free)); + + $self->{output}->perfdata_add(label => "used", unit => 'B', + value => $used_size, + 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/raisecom/snmp/plugin.pm b/centreon-plugins/network/raisecom/snmp/plugin.pm new file mode 100644 index 000000000..bcfde70be --- /dev/null +++ b/centreon-plugins/network/raisecom/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::raisecom::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}} = ( + 'cpu' => 'network::raisecom::snmp::mode::cpu', + 'hardware' => 'network::raisecom::snmp::mode::hardware', + 'interfaces' => 'snmp_standard::mode::interfaces', + 'list-interfaces' => 'snmp_standard::mode::listinterfaces', + 'memory' => 'network::raisecom::snmp::mode::memory', + ); + + return $self; +} + +1; + +__END__ + +=head1 PLUGIN DESCRIPTION + +Check Raisecom devices through SNMP + +=cut diff --git a/centreon-plugins/network/riverbed/steelhead/snmp/mode/connections.pm b/centreon-plugins/network/riverbed/steelhead/snmp/mode/connections.pm index 3971a5b6f..7280f89af 100644 --- a/centreon-plugins/network/riverbed/steelhead/snmp/mode/connections.pm +++ b/centreon-plugins/network/riverbed/steelhead/snmp/mode/connections.pm @@ -20,11 +20,84 @@ package network::riverbed::steelhead::snmp::mode::connections; -use base qw(centreon::plugins::mode); +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_connection_output' } + ]; + + $self->{maps_counters}->{global} = [ + { label => 'total', set => { + key_values => [ { name => 'totalConnections' } ], + output_template => 'total %s', + perfdatas => [ + { label => 'total', value => 'totalConnections_absolute', template => '%s', min => 0 }, + ], + } + }, + { label => 'established', set => { + key_values => [ { name => 'establishedConnections' } ], + output_template => 'established %s', + perfdatas => [ + { label => 'established', value => 'establishedConnections_absolute', template => '%s', min => 0 }, + ], + } + }, + { label => 'active', set => { + key_values => [ { name => 'activeConnections' } ], + output_template => 'active %s', + perfdatas => [ + { label => 'active', value => 'activeConnections_absolute', template => '%s', min => 0 }, + ], + } + }, + { label => 'optimized', set => { + key_values => [ { name => 'optimizedConnections' } ], + output_template => 'optimized %s', + perfdatas => [ + { label => 'optimized', value => 'optimizedConnections_absolute', template => '%s', min => 0 }, + ], + } + }, + { label => 'passthrough', set => { + key_values => [ { name => 'passthroughConnections' } ], + output_template => 'passthrough %s', + perfdatas => [ + { label => 'passthrough', value => 'passthroughConnections_absolute', template => '%s', min => 0 }, + ], + } + }, + { label => 'half-opened', set => { + key_values => [ { name => 'halfOpenedConnections' } ], + output_template => 'half opened %s', + perfdatas => [ + { label => 'half_opened', value => 'halfOpenedConnections_absolute', template => '%s', min => 0 }, + ], + } + }, + { label => 'half-closed', set => { + key_values => [ { name => 'halfClosedConnections' } ], + output_template => 'half closed %s', + perfdatas => [ + { label => 'half_closed', value => 'halfClosedConnections_absolute', template => '%s', min => 0 }, + ], + } + }, + ]; +} + +sub prefix_connection_output { + my ($self, %options) = @_; + + return "Connections: "; +} + sub new { my ($class, %options) = @_; my $self = $class->SUPER::new(package => __PACKAGE__, %options); @@ -33,87 +106,31 @@ sub new { $self->{version} = '0.1'; $options{options}->add_options(arguments => { - "warning:s" => { name => 'warning' }, - "critical:s" => { name => 'critical' }, }); return $self; } -sub check_options { +sub manage_selection { 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(); + my $oids = { + optimizedConnections => '.1.3.6.1.4.1.17163.1.1.5.2.1.0', + passthroughConnections => '.1.3.6.1.4.1.17163.1.1.5.2.2.0', + halfOpenedConnections => '.1.3.6.1.4.1.17163.1.1.5.2.3.0', + halfClosedConnections => '.1.3.6.1.4.1.17163.1.1.5.2.4.0', + establishedConnections => '.1.3.6.1.4.1.17163.1.1.5.2.5.0', + activeConnections => '.1.3.6.1.4.1.17163.1.1.5.2.6.0', + totalConnections => '.1.3.6.1.4.1.17163.1.1.5.2.7.0', + }; + + my $snmp_result = $options{snmp}->get_leef(oids => [ + values %$oids + ], nothing_quit => 1); + + $self->{global} = {}; + foreach (keys %$oids) { + $self->{global}->{$_} = $snmp_result->{$oids->{$_}}; } - 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_optimizedConnections = '.1.3.6.1.4.1.17163.1.1.5.2.1.0'; - my $oid_passthroughConnections = '.1.3.6.1.4.1.17163.1.1.5.2.2.0'; - my $oid_halfOpenedConnections = '.1.3.6.1.4.1.17163.1.1.5.2.3.0'; - my $oid_halfClosedConnections = '.1.3.6.1.4.1.17163.1.1.5.2.4.0'; - my $oid_establishedConnections = '.1.3.6.1.4.1.17163.1.1.5.2.5.0'; - my $oid_activeConnections = '.1.3.6.1.4.1.17163.1.1.5.2.6.0'; - my $oid_totalConnections = '.1.3.6.1.4.1.17163.1.1.5.2.7.0'; - - my $result = $self->{snmp}->get_leef(oids => [$oid_optimizedConnections, $oid_passthroughConnections, $oid_halfOpenedConnections, $oid_halfClosedConnections, - $oid_establishedConnections, $oid_activeConnections, $oid_totalConnections, ], nothing_quit => 1); - my $optimized = $result->{$oid_optimizedConnections}; - my $passthrough = $result->{$oid_passthroughConnections}; - my $halfOpened = $result->{$oid_halfOpenedConnections}; - my $halfClosed = $result->{$oid_halfClosedConnections}; - my $established = $result->{$oid_establishedConnections}; - my $active = $result->{$oid_activeConnections}; - my $total = $result->{$oid_totalConnections}; - - my $exit = $self->{perfdata}->threshold_check(value => $total, threshold => [ { label => 'critical', exit_litteral => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]); - - $self->{output}->output_add(severity => $exit, - short_msg => sprintf("Connections: total %d, established %d, active %d, optimized %d, passthrough %d, half opened %d, half closed %d ", - $total, $established, $active, $optimized, $passthrough, $halfOpened, $halfClosed)); - - $self->{output}->perfdata_add(label => "total", - value => $total, - warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning'), - critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical'), - min => 0 - ); - $self->{output}->perfdata_add(label => "established", - value => $established, - min => 0 - ); - $self->{output}->perfdata_add(label => "active", - value => $active, - min => 0 - ); - $self->{output}->perfdata_add(label => "optimized", - value => $optimized, - min => 0 - ); - $self->{output}->perfdata_add(label => "passthrough", - value => $passthrough, - min => 0 - ); - $self->{output}->perfdata_add(label => "half opened", - value => $halfOpened, - min => 0 - ); - $self->{output}->perfdata_add(label => "half closed", - value => $halfClosed, - min => 0 - ); - - $self->{output}->display(); - $self->{output}->exit(); } 1; @@ -126,13 +143,22 @@ Current connections: total, established, active, optimized, passthrough, half op =over 8 -=item B<--warning> +=item B<--filter-counters> -Threshold warning for total connections. +Only display some counters (regexp can be used). +Example: --filter-counters='^(total)$' -=item B<--critical> +=item B<--warning-*> -Threshold critical for total connections. +Threshold warning. +Can be: 'total', 'established', 'active', 'optimized', +'passthrough', 'half-opened', 'half-closed'. + +=item B<--critical-*> + +Threshold critical. +Can be: 'total', 'established', 'active', 'optimized', +'passthrough', 'half-opened', 'half-closed'. =back diff --git a/centreon-plugins/network/ruckus/ap/snmp/mode/cpu.pm b/centreon-plugins/network/ruckus/ap/snmp/mode/cpu.pm new file mode 100644 index 000000000..e313a46ca --- /dev/null +++ b/centreon-plugins/network/ruckus/ap/snmp/mode/cpu.pm @@ -0,0 +1,97 @@ +# +# 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::ruckus::ap::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 => 'usage', set => { + key_values => [ { name => 'cpu' } ], + output_template => 'Usage : %.2f %%', + perfdatas => [ + { label => 'cpu', value => 'cpu_absolute', template => '%.2f', + min => 0, max => 100, unit => '%' }, + ], + } + }, + ]; +} + +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_ruckusSystemCPUUtil = '.1.3.6.1.4.1.25053.1.1.11.1.1.1.1.0'; + my $oid_ruckusUnleashedSystemStatsCPUUtil = '.1.3.6.1.4.1.25053.1.15.1.1.1.15.13.0'; + my $snmp_result = $options{snmp}->get_leef(oids => [$oid_ruckusSystemCPUUtil, $oid_ruckusUnleashedSystemStatsCPUUtil], nothing_quit => 1); + + $self->{global} = { cpu => defined($snmp_result->{$oid_ruckusSystemCPUUtil}) ? $snmp_result->{$oid_ruckusSystemCPUUtil} : $snmp_result->{$oid_ruckusUnleashedSystemStatsCPUUtil} }; +} + +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/ruckus/ap/snmp/mode/memory.pm b/centreon-plugins/network/ruckus/ap/snmp/mode/memory.pm new file mode 100644 index 000000000..dd76415cb --- /dev/null +++ b/centreon-plugins/network/ruckus/ap/snmp/mode/memory.pm @@ -0,0 +1,150 @@ +# +# 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::ruckus::ap::snmp::mode::memory; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; + +sub custom_usage_perfdata { + my ($self, %options) = @_; + + if ($self->{result_values}->{total} > 0) { + $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}); + } else { + $self->{output}->perfdata_add(label => 'used', unit => '%', + value => $self->{result_values}->{prct_used}, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{label}), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{label}), + min => 0, max => 100); + } +} + +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 $msg = 'Memory Used: ' . $self->{result_values}->{prct_used} . '%'; + if ($self->{result_values}->{total} > 0) { + 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}); + + $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'}; + + if ($self->{result_values}->{total} > 0) { + $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_ruckusSystemMemoryUtil = '.1.3.6.1.4.1.25053.1.1.11.1.1.1.2.0'; + my $oid_ruckusSystemMemSize = '.1.3.6.1.4.1.25053.1.1.11.1.1.1.10.0'; + my $oid_ruckusUnleashedSystemStatsMemoryUtil = '.1.3.6.1.4.1.25053.1.15.1.1.1.15.14.0'; + my $snmp_result = $options{snmp}->get_leef(oids => [$oid_ruckusSystemMemoryUtil, $oid_ruckusSystemMemSize, $oid_ruckusUnleashedSystemStatsMemoryUtil], nothing_quit => 1); + + $self->{memory} = { + prct_used => defined($snmp_result->{$oid_ruckusSystemMemoryUtil}) ? $snmp_result->{$oid_ruckusSystemMemoryUtil} : $snmp_result->{$oid_ruckusUnleashedSystemStatsMemoryUtil}, + total => defined($snmp_result->{$oid_ruckusSystemMemSize}) ? $snmp_result->{$oid_ruckusSystemMemSize} : 0, + }; +} + +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/ruckus/ap/snmp/mode/users.pm b/centreon-plugins/network/ruckus/ap/snmp/mode/users.pm new file mode 100644 index 000000000..aa7de5071 --- /dev/null +++ b/centreon-plugins/network/ruckus/ap/snmp/mode/users.pm @@ -0,0 +1,206 @@ +# +# 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::ruckus::ap::snmp::mode::users; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; + +sub custom_global_perfdata { + my ($self, %options) = @_; + + if ($self->{result_values}->{limit} > 0) { + $self->{output}->perfdata_add(label => 'total', unit => 'users', + value => $self->{result_values}->{total}, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{label}, total => $self->{result_values}->{limit}, cast_int => 1), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{label}, total => $self->{result_values}->{limit}, cast_int => 1), + min => 0, max => $self->{result_values}->{limit}); + } else { + $self->{output}->perfdata_add(label => 'total', unit => 'users', + value => $self->{result_values}->{total}, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{label}), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{label}), + min => 0); + } +} + +sub custom_global_threshold { + my ($self, %options) = @_; + + my $exit; + if ($self->{result_values}->{limit} > 0) { + $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' } ]); + } else { + $exit = $self->{perfdata}->threshold_check(value => $self->{result_values}->{total}, threshold => [ { label => 'critical-' . $self->{label}, exit_litteral => 'critical' }, { label => 'warning-' . $self->{label}, exit_litteral => 'warning' } ]); + } + return $exit; +} + +sub custom_global_output { + my ($self, %options) = @_; + + my $msg = 'Total Users : ' . $self->{result_values}->{total}; + if ($self->{result_values}->{limit} > 0) { + $msg .= " (" . sprintf("%.2f", $self->{result_values}->{prct_used}) . '% used on ' . $self->{result_values}->{limit} . ")"; + } + + return $msg; +} + +sub custom_global_calc { + my ($self, %options) = @_; + + $self->{result_values}->{total} = $options{new_datas}->{$self->{instance} . '_total'}; + $self->{result_values}->{limit} = $options{new_datas}->{$self->{instance} . '_limit'}; + if ($self->{result_values}->{limit} > 0) { + $self->{result_values}->{prct_used} = $self->{result_values}->{total} * 100 / $self->{result_values}->{limit}; + } + return 0; +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'global', type => 0 }, + { name => 'ssid', type => 1, cb_prefix_output => 'prefix_ssid_output', message_multiple => 'All users by SSID are ok', cb_init => 'skip_ssid', }, + ]; + $self->{maps_counters}->{global} = [ + { label => 'total', set => { + key_values => [ { name => 'total' }, { name => 'limit' } ], + closure_custom_calc => $self->can('custom_global_calc'), + closure_custom_output => $self->can('custom_global_output'), + closure_custom_perfdata => $self->can('custom_global_perfdata'), + closure_custom_threshold_check => $self->can('custom_global_threshold'), + } + }, + ]; + + $self->{maps_counters}->{ssid} = [ + { label => 'ssid', set => { + key_values => [ { name => 'total' }, { name => 'display' } ], + output_template => 'users : %s', + perfdatas => [ + { label => 'ssid', value => 'total_absolute', template => '%s', + unit => 'users', min => 0, label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + ]; +} + +sub prefix_ssid_output { + my ($self, %options) = @_; + + return "SSID '" . $options{instance_value}->{display} . "' "; +} + +sub skip_ssid { + my ($self, %options) = @_; + + scalar(keys %{$self->{ssid}}) > 1 ? return(0) : return(1); +} + +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-ssid:s" => { name => 'filter_ssid' }, + }); + + return $self; +} + +my $oid_ruckusUnleashedSystemMaxSta = '.1.3.6.1.4.1.25053.1.15.1.1.1.1.13.0'; +my $oid_ruckusUnleashedSystemStatsNumSta = '.1.3.6.1.4.1.25053.1.15.1.1.1.15.2.0'; +my $mapping = { + ruckusWLANStatsSSID => { oid => '.1.3.6.1.4.1.25053.1.1.6.1.1.1.4.1.1' }, + ruckusWLANStatsNumSta => { oid => '.1.3.6.1.4.1.25053.1.1.6.1.1.1.4.1.3' }, +}; + +sub manage_selection { + my ($self, %options) = @_; + + $self->{global} = { total => -1, limit => -1 }; + my $snmp_result = $options{snmp}->get_leef(oids => [$oid_ruckusUnleashedSystemMaxSta, $oid_ruckusUnleashedSystemStatsNumSta]); + $self->{global}->{limit} = $snmp_result->{$oid_ruckusUnleashedSystemMaxSta} if (defined($snmp_result->{$oid_ruckusUnleashedSystemMaxSta})); + $self->{global}->{total} = $snmp_result->{$oid_ruckusUnleashedSystemStatsNumSta} if (defined($snmp_result->{$oid_ruckusUnleashedSystemStatsNumSta})); + + return if ($self->{global}->{total} != -1); + + $snmp_result = $options{snmp}->get_multiple_table(oids => [ + { oid => $mapping->{ruckusWLANStatsSSID}->{oid} }, + { oid => $mapping->{ruckusWLANStatsNumSta}->{oid} } ], return_type => 1, nothing_quit => 1); + + $self->{ssid} = {}; + foreach my $oid (keys %{$snmp_result}) { + next if ($oid !~ /^$mapping->{ruckusWLANStatsNumSta}->{oid}\.(\d+)/); + $self->{global}->{total} = 0 if ($self->{global}->{total} == -1); + my $instance = $1; + my $result = $options{snmp}->map_instance(mapping => $mapping, results => $snmp_result, instance => $instance); + + $self->{ssid}->{$result->{ruckusWLANStatsSSID}} = { display => $result->{ruckusWLANStatsSSID}, total => $result->{ruckusWLANStatsNumSta} }; + $self->{global}->{total} += $result->{ruckusWLANStatsNumSta}; + } + + if ($self->{global}->{total} == -1) { + $self->{output}->add_option_msg(short_msg => "Cannot find informations"); + $self->{output}->option_exit(); + } +} + +1; + +__END__ + +=head1 MODE + +Check users connected. + +=over 8 + +=item B<--filter-counters> + +Only display some counters (regexp can be used). +Example: --filter-counters='^total$' + +=item B<--warning-*> + +Threshold warning. +Can be: 'total', 'ssid'. + +=item B<--critical-*> + +Threshold critical. +Can be: 'total', 'ssid'. + +=item B<--filter-ssid> + +Filter by SSID (can be a regexp). + +=back + +=cut diff --git a/centreon-plugins/network/ruckus/ap/snmp/plugin.pm b/centreon-plugins/network/ruckus/ap/snmp/plugin.pm new file mode 100644 index 000000000..ed63dca98 --- /dev/null +++ b/centreon-plugins/network/ruckus/ap/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::ruckus::ap::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::ruckus::ap::snmp::mode::cpu', + 'interfaces' => 'snmp_standard::mode::interfaces', + 'list-interfaces' => 'snmp_standard::mode::listinterfaces', + 'memory' => 'network::ruckus::ap::snmp::mode::memory', + 'users' => 'network::ruckus::ap::snmp::mode::users', + ); + + return $self; +} + +1; + +__END__ + +=head1 PLUGIN DESCRIPTION + +Check Ruckus AP (Unleashed and ZoneFlex) equipments in SNMP. + +=cut diff --git a/centreon-plugins/network/sophos/es/snmp/mode/message.pm b/centreon-plugins/network/sophos/es/snmp/mode/message.pm index 43225cb5e..79239f27e 100644 --- a/centreon-plugins/network/sophos/es/snmp/mode/message.pm +++ b/centreon-plugins/network/sophos/es/snmp/mode/message.pm @@ -179,7 +179,7 @@ Threshold warning. Threshold critical. -Can be: queue, total-in, total-out, msg-in, msg-out. +Can be: queue, total-msg-in, total-msg-out, msg-in, msg-out. =back 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/netasq/local/mode/qosusage.pm b/centreon-plugins/network/stormshield/local/mode/qosusage.pm similarity index 97% rename from centreon-plugins/network/netasq/local/mode/qosusage.pm rename to centreon-plugins/network/stormshield/local/mode/qosusage.pm index a8e80e8c9..fe8bc7bc2 100644 --- a/centreon-plugins/network/netasq/local/mode/qosusage.pm +++ b/centreon-plugins/network/stormshield/local/mode/qosusage.pm @@ -18,7 +18,7 @@ # limitations under the License. # -package network::netasq::local::mode::qosusage; +package network::stormshield::local::mode::qosusage; use base qw(centreon::plugins::templates::counter); @@ -235,7 +235,13 @@ sub manage_selection { $self->load_speed_config(); $self->{qos} = {}; - while ($content =~ /(\S+?)=([^,]+?),(\d+),(\d+),(\d+),(\d+)(?:\s|\Z)/msg) { + # Version 3, there is 7 fields (5 before) + my $pattern = '(\S+?)=([^,]+?),(\d+),(\d+),(\d+),(\d+)(?:\s|\Z)'; + if ($content !~ /$pattern/) { + $pattern = '(\S+?)=([^,]+?),(\d+),(\d+),(\d+),(\d+),\d+,\d+(?:\s|\Z)'; + } + + while ($content =~ /$pattern/msg) { my ($vlan, $name, $in, $in_max, $out, $out_max) = ($1, $2, $3, $4, $5, $6); if (defined($self->{option_results}->{filter_name}) && $self->{option_results}->{filter_name} ne '' && $name !~ /$self->{option_results}->{filter_name}/) { diff --git a/centreon-plugins/network/netasq/local/plugin.pm b/centreon-plugins/network/stormshield/local/plugin.pm similarity index 86% rename from centreon-plugins/network/netasq/local/plugin.pm rename to centreon-plugins/network/stormshield/local/plugin.pm index a2afd0714..f046ec1d2 100644 --- a/centreon-plugins/network/netasq/local/plugin.pm +++ b/centreon-plugins/network/stormshield/local/plugin.pm @@ -18,7 +18,7 @@ # limitations under the License. # -package network::netasq::local::plugin; +package network::stormshield::local::plugin; use strict; use warnings; @@ -31,7 +31,7 @@ sub new { $self->{version} = '0.1'; %{$self->{modes}} = ( - 'qos-usage' => 'network::netasq::local::mode::qosusage', + 'qos-usage' => 'network::stormshield::local::mode::qosusage', ); return $self; @@ -43,6 +43,6 @@ __END__ =head1 PLUGIN DESCRIPTION -Check Netasq equipment. +Check Stormshield equipment (also Netasq). =cut diff --git a/centreon-plugins/network/netasq/snmp/mode/connections.pm b/centreon-plugins/network/stormshield/snmp/mode/connections.pm similarity index 91% rename from centreon-plugins/network/netasq/snmp/mode/connections.pm rename to centreon-plugins/network/stormshield/snmp/mode/connections.pm index a5532e647..7d532bdd8 100644 --- a/centreon-plugins/network/netasq/snmp/mode/connections.pm +++ b/centreon-plugins/network/stormshield/snmp/mode/connections.pm @@ -18,7 +18,7 @@ # limitations under the License. # -package network::netasq::snmp::mode::connections; +package network::stormshield::snmp::mode::connections; use base qw(centreon::plugins::templates::counter); @@ -70,7 +70,7 @@ sub new { sub manage_selection { my ($self, %options) = @_; - $self->{cache_name} = "fw_netasq_" . $options{snmp}->get_hostname() . '_' . $options{snmp}->get_port() . '_' . $self->{mode} . '_' . md5_hex('all'); + $self->{cache_name} = "fw_stormshield_" . $options{snmp}->get_hostname() . '_' . $options{snmp}->get_port() . '_' . $self->{mode} . '_' . md5_hex('all'); my $oid_ntqASQStatsStatefulUdpConn = '.1.3.6.1.4.1.11256.1.12.1.33.0'; my $oid_ntqASQStatsStatefulTcpConn = '.1.3.6.1.4.1.11256.1.12.1.23.0'; @@ -89,7 +89,7 @@ __END__ =head1 MODE -Check connections setup rate on Netasq Firewall equipments. +Check connections setup rate on Stormshield Firewall equipments. =over 8 diff --git a/centreon-plugins/network/netasq/snmp/mode/hanodes.pm b/centreon-plugins/network/stormshield/snmp/mode/hanodes.pm similarity index 98% rename from centreon-plugins/network/netasq/snmp/mode/hanodes.pm rename to centreon-plugins/network/stormshield/snmp/mode/hanodes.pm index bf56b295e..f1053c770 100644 --- a/centreon-plugins/network/netasq/snmp/mode/hanodes.pm +++ b/centreon-plugins/network/stormshield/snmp/mode/hanodes.pm @@ -18,7 +18,7 @@ # limitations under the License. # -package network::netasq::snmp::mode::hanodes; +package network::stormshield::snmp::mode::hanodes; use base qw(centreon::plugins::templates::counter); @@ -227,7 +227,7 @@ __END__ =head1 MODE -Check Netasq dead nodes and state and health of nodes +Check Stormshield dead nodes and state and health of nodes =over 8 diff --git a/centreon-plugins/network/netasq/snmp/mode/vpnstatus.pm b/centreon-plugins/network/stormshield/snmp/mode/vpnstatus.pm similarity index 98% rename from centreon-plugins/network/netasq/snmp/mode/vpnstatus.pm rename to centreon-plugins/network/stormshield/snmp/mode/vpnstatus.pm index feae30c78..28642edbc 100644 --- a/centreon-plugins/network/netasq/snmp/mode/vpnstatus.pm +++ b/centreon-plugins/network/stormshield/snmp/mode/vpnstatus.pm @@ -18,7 +18,7 @@ # limitations under the License. # -package network::netasq::snmp::mode::vpnstatus; +package network::stormshield::snmp::mode::vpnstatus; use base qw(centreon::plugins::mode); @@ -163,7 +163,7 @@ sub run { $matching .= defined($self->{option_results}->{$_}) ? $self->{option_results}->{$_} : 'all'; } $self->{new_datas} = {}; - $self->{statefile_value}->read(statefile => "netasq_" . $self->{hostname} . '_' . $self->{snmp_port} . '_' . $self->{mode} . '_' . md5_hex($matching)); + $self->{statefile_value}->read(statefile => "stormshield_" . $self->{hostname} . '_' . $self->{snmp_port} . '_' . $self->{mode} . '_' . md5_hex($matching)); $self->{new_datas}->{last_timestamp} = time(); foreach my $id (sort keys %{$self->{vpn}}) { diff --git a/centreon-plugins/network/netasq/snmp/plugin.pm b/centreon-plugins/network/stormshield/snmp/plugin.pm similarity index 82% rename from centreon-plugins/network/netasq/snmp/plugin.pm rename to centreon-plugins/network/stormshield/snmp/plugin.pm index 4759a1b0b..4f1a755b2 100644 --- a/centreon-plugins/network/netasq/snmp/plugin.pm +++ b/centreon-plugins/network/stormshield/snmp/plugin.pm @@ -18,7 +18,7 @@ # limitations under the License. # -package network::netasq::snmp::plugin; +package network::stormshield::snmp::plugin; use strict; use warnings; @@ -33,15 +33,15 @@ sub new { %{$self->{modes}} = ( 'cpu' => 'snmp_standard::mode::cpu', 'cpu-detailed' => 'snmp_standard::mode::cpudetailed', - 'connections' => 'network::netasq::snmp::mode::connections', + 'connections' => 'network::stormshield::snmp::mode::connections', 'interfaces' => 'snmp_standard::mode::interfaces', 'list-interfaces' => 'snmp_standard::mode::listinterfaces', 'load' => 'snmp_standard::mode::loadaverage', - 'ha-nodes' => 'network::netasq::snmp::mode::hanodes', + 'ha-nodes' => 'network::stormshield::snmp::mode::hanodes', 'memory' => 'os::freebsd::snmp::mode::memory', 'storage' => 'snmp_standard::mode::storage', 'swap' => 'snmp_standard::mode::swap', - 'vpn-status' => 'network::netasq::snmp::mode::vpnstatus', + 'vpn-status' => 'network::stormshield::snmp::mode::vpnstatus', ); return $self; @@ -53,6 +53,6 @@ __END__ =head1 PLUGIN DESCRIPTION -Check Netasq equipment in SNMP. +Check Stormshield equipment (also Netasq) in SNMP. =cut diff --git a/centreon-plugins/notification/foxbox/mode/alert.pm b/centreon-plugins/notification/foxbox/mode/alert.pm new file mode 100644 index 000000000..bd3fc802b --- /dev/null +++ b/centreon-plugins/notification/foxbox/mode/alert.pm @@ -0,0 +1,145 @@ +# +# 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 notification::foxbox::mode::alert; + +use base qw(centreon::plugins::mode); + +use strict; +use warnings; +use centreon::plugins::http; + +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 => { + "foxbox-username:s" => { name => 'foxbox_username', default => 'centreon' }, + "foxbox-password:s" => { name => 'foxbox_password' }, + "from:s" => { name => 'from', default => 'centreon' }, + "proto:s" => { name => 'proto', default => 'http' }, + "urlpath:s" => { name => 'url_path', default => '/source/send_sms.php' }, + "phonenumber:s" => { name => 'phonenumber' }, + "hostname:s" => { name => 'hostname' }, + "texto:s" => { name => 'texto' }, + "timeout:s" => { name => 'timeout', default => 10 }, + } + ); + + $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}->{foxbox_password})) { + $self->{output} + ->add_option_msg(short_msg => "You need to set --foxbox-username and --foxbox-password options"); + $self->{output}->option_exit(); + } + if (!defined($self->{option_results}->{phonenumber})) { + $self->{output}->add_option_msg(short_msg => "Please set the --phonenumber option"); + $self->{output}->option_exit(); + } + + if (!defined($self->{option_results}->{texto})) { + $self->{output}->add_option_msg(short_msg => "Please set the --texto option"); + $self->{output}->option_exit(); + } + + $self->{http}->set_options(%{ $self->{option_results} }); +} + +sub run { + my ($self, %options) = @_; + + my $response = $self->{http}->request(method => 'POST', + post_param => [ + 'username=' . $self->{option_results}->{foxbox_username}, + 'pwd=' . $self->{option_results}->{foxbox_password}, + 'from=' . $self->{option_results}->{from}, + 'nphone=' . $self->{option_results}->{phonenumber}, + 'testo=' . $self->{option_results}->{texto}, + ] + ); + + $self->{output}->output_add( + severity => 'OK', + short_msg => 'message sent' + ); + + $self->{output}->display(); + $self->{output}->exit(); +} + +1; + +__END__ + +=head1 MODE + +Send SMS with Foxbox API. + +=over 8 + +=item B<--hostname> + +url of the Foxbox Server. + +=item B<--urlpath> + +The url path. (Default: /source/send_sms.php) + +=item B<--foxbox-username> + +Specify username for API authentification (Default: centreon). + +=item B<--foxbox-password> + +Specify password for API authentification (Required). + +=item B<--proto> + +Specify http or https protocol. (Default: http) + +=item B<--phonenumber> + +Specify phone number (Required). + +=item B<--texto> + +Specify the content of your SMS message (Required). + +=item B<--from> + +Specify the sender. It should NOT start with a number and have a max of 11 characters (Default: centreon). + +=item B<--timeout> + +Timeout in seconds for the command (Default: 10). + +=back + +=cut diff --git a/centreon-plugins/apps/elasticsearch/plugin.pm b/centreon-plugins/notification/foxbox/plugin.pm similarity index 76% rename from centreon-plugins/apps/elasticsearch/plugin.pm rename to centreon-plugins/notification/foxbox/plugin.pm index 3407ba309..a92307172 100644 --- a/centreon-plugins/apps/elasticsearch/plugin.pm +++ b/centreon-plugins/notification/foxbox/plugin.pm @@ -18,7 +18,7 @@ # limitations under the License. # -package apps::elasticsearch::plugin; +package notification::foxbox::plugin; use strict; use warnings; @@ -31,10 +31,9 @@ sub new { $self->{version} = '0.1'; %{$self->{modes}} = ( - 'cluster' => 'apps::elasticsearch::mode::cluster', - 'nodescount' => 'apps::elasticsearch::mode::nodescount', - 'indices' => 'apps::elasticsearch::mode::indices', - ); + 'alert' => 'notification::foxbox::mode::alert', + ); + return $self; } @@ -44,6 +43,6 @@ __END__ =head1 PLUGIN DESCRIPTION -Check elasticsearch status. +Send Foxbox notifications. =cut diff --git a/centreon-plugins/notification/highsms/plugin.pm b/centreon-plugins/notification/highsms/plugin.pm old mode 100755 new mode 100644 diff --git a/centreon-plugins/os/windows/local/conf/qwinsta.xml b/centreon-plugins/os/windows/local/conf/qwinsta.xml new file mode 100644 index 000000000..d3c842101 --- /dev/null +++ b/centreon-plugins/os/windows/local/conf/qwinsta.xml @@ -0,0 +1,19 @@ + + + + Total sessions created + Total sessions disconnected + Total sessions reconnected + Active + SESSIONNAME + STATE + + + Nombre total de sessions c.*?s + Nombre total de sessions d.*?connect.*?es + Nombre total de sessions reconnect.*?es + Actif + SESSION + ^.*?TAT + + diff --git a/centreon-plugins/os/windows/local/mode/pendingreboot.pm b/centreon-plugins/os/windows/local/mode/pendingreboot.pm new file mode 100644 index 000000000..1c84c2b59 --- /dev/null +++ b/centreon-plugins/os/windows/local/mode/pendingreboot.pm @@ -0,0 +1,203 @@ +# +# 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::pendingreboot; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; +use centreon::plugins::misc; +use centreon::common::powershell::windows::pendingreboot; + +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 = 'Reboot Pending : ' . $self->{result_values}->{RebootPending}; + return $msg; +} + +sub custom_status_calc { + my ($self, %options) = @_; + + $self->{result_values}->{CBServicing} = $options{new_datas}->{$self->{instance} . '_CBServicing'}; + $self->{result_values}->{RebootPending} = $options{new_datas}->{$self->{instance} . '_RebootPending'}; + $self->{result_values}->{WindowsUpdate} = $options{new_datas}->{$self->{instance} . '_WindowsUpdate'}; + $self->{result_values}->{CCMClientSDK} = $options{new_datas}->{$self->{instance} . '_CCMClientSDK'}; + return 0; +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'pendingreboot', type => 0 }, + ]; + $self->{maps_counters}->{pendingreboot} = [ + { label => 'status', , threshold => 0, set => { + key_values => [ { name => 'CBServicing' }, { name => 'RebootPending' }, { name => 'WindowsUpdate' }, + { name => 'CCMClientSDK' } ], + 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 => + { + "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' }, + "warning-status:s" => { name => 'warning_status', default => '%{RebootPending} =~ /true/i' }, + "critical-status:s" => { name => 'critical_status', default => '' }, + }); + 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 $ps = centreon::common::powershell::windows::pendingreboot::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(); + } + + #[CBServicing=False][WindowsUpdate=False][CCMClientSDK=][PendComputerRename=False][PendFileRename=False][PendFileRenVal=][RebootPending=False] + $self->{pendingreboot} = {}; + while ($stdout =~ /\[(.*?)=\s*(.*?)\s*\]/mg) { + $self->{pendingreboot}->{$1} = $2; + } +} + +1; + +__END__ + +=head1 MODE + +Check windows pending reboot. + +=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<--warning-status> + +Set warning threshold for status (Default: '%{RebootPending} =~ /true/i'). +Can used special variables like: %{RebootPending}, %{CBServicing}, %{WindowsUpdate}, %{CCMClientSDK}. + +=item B<--critical-status> + +Set critical threshold for status (Default: ''). +Can used special variables like: %{RebootPending}, %{CBServicing}, %{WindowsUpdate}, %{CCMClientSDK}. + +=back + +=cut diff --git a/centreon-plugins/os/windows/local/mode/rdpsessions.pm b/centreon-plugins/os/windows/local/mode/rdpsessions.pm deleted file mode 100644 index c85f2c31a..000000000 --- a/centreon-plugins/os/windows/local/mode/rdpsessions.pm +++ /dev/null @@ -1,206 +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 os::windows::local::mode::rdpsessions; - -use base qw(centreon::plugins::mode); - -use strict; -use warnings; -use Win32::OLE; -use DateTime; - -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-inactive:s" => { name => 'warning_inactive' }, - "critical-inactive:s" => { name => 'critical_inactive' }, - "warning-active:s" => { name => 'warning_active' }, - "critical-active:s" => { name => 'critical_active' }, - "warning-time:s" => { name => 'warning_time' }, - "critical-time:s" => { name => 'critical_time' }, - }); - $self->{os_is2003} = 0; - $self->{os_is2008} = 0; - $self->{os_is2012} = 0; - $self->{result_sessions} = {}; - $self->{result_detailed} = {}; - return $self; -} - -sub check_options { - my ($self, %options) = @_; - $self->SUPER::init(%options); - - foreach my $label (('warning_inactive', 'critical_inactive', 'warning_active', 'critical_active', 'warning_time', 'critical_time')) { - if (($self->{perfdata}->threshold_validate(label => $label, value => $self->{option_results}->{$label})) == 0) { - my ($label_opt) = $label; - $label_opt =~ tr/_/-/; - $self->{output}->add_option_msg(short_msg => "Wrong " . $label_opt . " threshold '" . $self->{option_results}->{$label} . "'."); - $self->{output}->option_exit(); - } - } -} - -sub check_version { - my ($self, %options) = @_; - - my ($ver_string, $ver_major, $ver_minor, $ver_build, $ver_id) = Win32::GetOSVersion(); - #"Operating system is " . "$ver_string - ($ver_id.$ver_major.$ver_minor.$ver_build)\n"; - - # 5.1, 5.2 => XP/2003 - # 6.0, 6.1 => Vista/7/2008 - # 6.2, 6.3 => 2012 - if ($ver_major == 5 && ($ver_minor == 1 || $ver_minor == 2)) { - $self->{os_is2003} = 1; - } elsif ($ver_major == 6 && ($ver_minor == 0 || $ver_minor == 1)) { - $self->{os_is2008} = 1; - } elsif ($ver_major == 6 && ($ver_minor == 2 || $ver_minor == 3)) { - $self->{os_is2012} = 1; - } else { - $self->{output}->output_add(severity => 'UNKNOWN', - short_msg => 'OS version ' . $ver_major . '.' . $ver_minor . ' not managed.'); - return 1; - } - return 0; -} - -sub get_sessions { - my ($self, %options) = @_; - - $self->{wmi} = Win32::OLE->GetObject('winmgmts:root\CIMV2'); - if (!defined($self->{wmi})) { - $self->{output}->add_option_msg(short_msg => "Cant create server object:" . Win32::OLE->LastError()); - $self->{output}->option_exit(); - } - my $query = 'SELECT ActiveSessions, InactiveSessions FROM Win32_PerfRawData_LocalSessionManager_TerminalServices'; - if ($self->{os_is2003} == 1) { - $query = 'SELECT ActiveSessions, InactiveSessions FROM Win32_PerfRawData_TermService_TerminalServices '; - } - my $resultset = $self->{wmi}->ExecQuery($query); - foreach my $obj (in $resultset) { - $self->{result_sessions}->{active_sessions} = $obj->{ActiveSessions}; - if ($self->{os_is2003} == 1) { - $self->{result_sessions}->{inactive_sessions} = $obj->{InactiveSessions} - 1; # Console session - } else { - $self->{result_sessions}->{inactive_sessions} = $obj->{InactiveSessions} - 2; # Service and Console sessions - } - } -} - -sub get_detailed_informations { - my ($self, %options) = @_; - - my $query = 'SELECT LogonId, StartTime FROM Win32_LogonSession WHERE LogonType = 10'; - my $resultset = $self->{wmi}->ExecQuery($query); - foreach my $obj (in $resultset) { - my $resultset2 = $self->{wmi}->ExecQuery('Associators of {Win32_LogonSession.LogonId=' . - $obj->{LogonId} . '} Where AssocClass=Win32_LoggedOnUser Role=Dependent'); - foreach my $obj2 (in $resultset2) { - $obj->{StartTime} =~ /^([0-9]{4})([0-9]{2})([0-9]{2})([0-9]{2})([0-9]{2})([0-9]{2})\.[0-9]+([+\-])(.*)/; - my ($year, $month, $day, $hour, $min, $sec, $tz, $tz_min) = ($1, $2, $3, $4, $5, $6, $7, $8); - my $tz_time = sprintf("%02d%02d", $tz_min / 60, $tz_min % 60); - my $dt = DateTime->new( - year => $year, - month => $month, - day => $day, - hour => $hour, - minute => $min, - second => $sec, - time_zone => $tz . $tz_time, - ); - - $self->{result_detailed}->{$obj2->{Domain} . '\\' . $obj2->{Name}} = $dt->epoch; - } - } -} - -sub manage { - my ($self, %options) = @_; - - my $exit = $self->{perfdata}->threshold_check(value => $self->{result_sessions}->{active_sessions}, threshold => [ { label => 'critical_active', exit_litteral => 'critical' }, { label => 'warning_active', exit_litteral => 'warning' } ]); - $self->{output}->output_add(severity => $exit, - short_msg => sprintf("%d active session(s)", $self->{result_sessions}->{active_sessions})); - $exit = $self->{perfdata}->threshold_check(value => $self->{result_sessions}->{inactive_sessions}, threshold => [ { label => 'critical_inactive', exit_litteral => 'critical' }, { label => 'warning_inactive', exit_litteral => 'warning' } ]); - $self->{output}->output_add(severity => $exit, - short_msg => sprintf("%d inactive session(s)", $self->{result_sessions}->{inactive_sessions})); - - foreach my $user (sort keys %{$self->{result_detailed}}) { - $exit = $self->{perfdata}->threshold_check(value => time() - $self->{result_detailed}->{$user}, threshold => [ { label => 'critical_time', exit_litteral => 'critical' }, { label => 'warning_time', exit_litteral => 'warning' } ]); - $self->{output}->output_add(long_msg => sprintf("User %s session opened since %s", $user, scalar(localtime($self->{result_detailed}->{$user})))); - if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { - $self->{output}->output_add(severity => $exit, - short_msg => sprintf("User %s session opened since %s", $user, scalar(localtime($self->{result_detailed}->{$user})))); - } - } - - $self->{output}->perfdata_add(label => 'active_sessions', - value => $self->{result_sessions}->{active_sessions}, - warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning_active'), - critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical_active'), - min => 0, max => $self->{result_sessions}->{active_sessions} + $self->{result_sessions}->{inactive_sessions}); - $self->{output}->perfdata_add(label => 'inactive_sessions', - value => $self->{result_sessions}->{inactive_sessions}, - warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning_inactive'), - critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical_inactive'), - min => 0, max => $self->{result_sessions}->{active_sessions} + $self->{result_sessions}->{inactive_sessions}); -} - -sub run { - my ($self, %options) = @_; - - if ($self->check_version() == 0) { - $self->get_sessions(); - $self->get_detailed_informations(); - $self->manage(); - } - - $self->{output}->display(); - $self->{output}->exit(); -} - -1; - -__END__ - -=head1 MODE - -Check rdp sessions. - -=over 8 - -=item B<--warning-*> - -Threshold warning. -Can be: 'inactive', 'active', 'time' (in seconds since the session starts). - -=item B<--critical-*> - -Threshold critical. -Can be: 'inactive', 'active', 'time' (in seconds since the session starts). - -=back - -=cut \ No newline at end of file diff --git a/centreon-plugins/os/windows/local/mode/sessions.pm b/centreon-plugins/os/windows/local/mode/sessions.pm new file mode 100644 index 000000000..a9d87dd29 --- /dev/null +++ b/centreon-plugins/os/windows/local/mode/sessions.pm @@ -0,0 +1,297 @@ +# +# 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::sessions; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; +use Digest::MD5 qw(md5_hex); +use XML::Simple; + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'global', type => 0, cb_prefix_output => 'prefix_global_output', }, + ]; + + $self->{maps_counters}->{global} = [ + { label => 'sessions-created', set => { + key_values => [ { name => 'sessions_created', diff => 1 } ], + output_template => 'Created : %s', + perfdatas => [ + { label => 'sessions_created', value => 'sessions_created_absolute', template => '%s', min => 0 }, + ], + } + }, + { label => 'sessions-disconnected', set => { + key_values => [ { name => 'sessions_disconnected', diff => 1 } ], + output_template => 'Disconnected : %s', + perfdatas => [ + { label => 'sessions_disconnected', value => 'sessions_disconnected_absolute', template => '%s', min => 0 }, + ], + } + }, + { label => 'sessions-reconnected', set => { + key_values => [ { name => 'sessions_reconnected', diff => 1 } ], + output_template => 'Reconnected : %s', + perfdatas => [ + { label => 'sessions_reconnected', value => 'sessions_reconnected_absolute', template => '%s', min => 0 }, + ], + } + }, + { label => 'sessions-active', set => { + key_values => [ { name => 'sessions_active' } ], + output_template => 'Active : %s', + perfdatas => [ + { label => 'sessions_active', value => 'sessions_active_absolute', template => '%s', min => 0 }, + ], + } + }, + ]; +} + +sub prefix_global_output { + my ($self, %options) = @_; + + return "Sessions "; +} + +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 => + { + "command:s" => { name => 'command', default => 'qwinsta' }, + "command-path:s" => { name => 'command_path' }, + "command-options:s" => { name => 'command_options', default => '/COUNTER' }, + "timeout:s" => { name => 'timeout', default => 30 }, + "filter-sessionname:s" => { name => 'filter_sessionname' }, + "config:s" => { name => 'config' }, + "language:s" => { name => 'language', default => 'en' }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + + $self->SUPER::check_options(%options); + if (defined($self->{option_results}->{config})) { + $self->{config_file} = $self->{option_results}->{config}; + } else { + $self->{output}->add_option_msg(short_msg => "Need to specify config file option."); + $self->{output}->option_exit();; + } +} + +sub read_config { + my ($self, %options) = @_; + + my $content_file = do { + local $/ = undef; + if (!open my $fh, "<", $self->{option_results}->{config}) { + $self->{output}->add_option_msg(short_msg => "Could not open file $self->{option_results}->{config} : $!"); + $self->{output}->option_exit(); + } + <$fh>; + }; + + my $content; + eval { + $content = XMLin($content_file, ForceArray => ['qwinsta'], KeyAttr => ['language']); + }; + if ($@) { + $self->{output}->add_option_msg(short_msg => "Cannot decode xml response: $@"); + $self->{output}->option_exit(); + } + + if (!defined($content->{qwinsta}->{$self->{option_results}->{language}})) { + $self->{output}->add_option_msg(short_msg => "Cannot find language '$self->{option_results}->{language}' in config file"); + $self->{output}->option_exit(); + } + + return $content->{qwinsta}->{$self->{option_results}->{language}}; +} + +sub read_qwinsta { + my ($self, %options) = @_; + + $self->{output}->output_add(long_msg => $options{stdout}, debug => 1); + if ($options{stdout} !~ /^(.*?)$options{config}->{created}/si) { + $self->{output}->add_option_msg(short_msg => "Cannot find information in command output"); + $self->{output}->option_exit(); + } + my $sessions = $1; + + my @lines = split /\n/, $sessions; + my $header = shift @lines; + + my @position_wrap = (); + while ($header =~ /(\s+(\S+))/g) { + push @position_wrap, { begin => $-[1], word_begin => $-[2], end => $+[1], label => $2 }; + } + my $session_data = []; + foreach my $line (@lines) { + my $data = {}; + for (my $pos = 0; $pos <= $#position_wrap; $pos++) { + my $area; + + if (length($line) < $position_wrap[$pos]->{begin}) { + $area = ''; + } else { + if ($pos + 1 <= $#position_wrap) { + $area = substr($line, $position_wrap[$pos]->{begin}, ($position_wrap[$pos]->{end} - $position_wrap[$pos]->{begin}) + ($position_wrap[$pos + 1]->{word_begin} - $position_wrap[$pos]->{end})); + } else { + $area = substr($line, $position_wrap[$pos]->{begin}); + } + } + + $data->{$position_wrap[$pos]->{label}} = '-'; + while ($area =~ /([^\s]+)/g) { + if (($-[1] >= $position_wrap[$pos]->{word_begin} - $position_wrap[$pos]->{begin} && $-[1] <= $position_wrap[$pos]->{end} - $position_wrap[$pos]->{begin}) + || + ($+[1] >= $position_wrap[$pos]->{word_begin} - $position_wrap[$pos]->{begin} && $+[1] <= $position_wrap[$pos]->{end} - $position_wrap[$pos]->{begin})) { + $data->{$position_wrap[$pos]->{label}} = $1; + last; + } + } + } + push @$session_data, $data; + } + + return $session_data; +} + +sub read_qwinsta_counters { + my ($self, %options) = @_; + + my $counters = {}; + $counters->{sessions_created} = $1 + if ($options{stdout} =~ /$options{config}->{created}.*?(\d+)/si); + $counters->{sessions_disconnected} = $1 + if ($options{stdout} =~ /$options{config}->{disconnected}.*?(\d+)/si); + $counters->{sessions_reconnected} = $1 + if ($options{stdout} =~ /$options{config}->{reconnected}.*?(\d+)/si); + + return $counters; +} + +sub manage_selection { + my ($self, %options) = @_; + + my $config = $self->read_config(); + 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}); + + my $datas = $self->read_qwinsta(stdout => $stdout, config => $config); + my $counters = $self->read_qwinsta_counters(stdout => $stdout, config => $config); + + my $active = 0; + foreach my $session (@$datas) { + if (defined($self->{option_results}->{filter_sessionname}) && $self->{option_results}->{filter_sessionname} ne '' && + $session->{$config->{header_sessionname}} !~ /$self->{option_results}->{filter_sessionname}/) { + $self->{output}->output_add(long_msg => "skipping '" . $session->{$config->{header_sessionname}} . "': no matching filter.", debug => 1); + next; + } + + my $matching = 0; + foreach my $label (keys %$session) { + $matching = 1 if ($label =~ /$config->{header_state}/ && + $session->{$label} =~ /$config->{activestate}/); + } + + if ($matching == 1) { + $active++; + my $output = ''; + $output .= " [$_ => $session->{$_}]" for (sort keys %$session); + $self->{output}->output_add(long_msg => $output); + } + } + + $self->{global} = { %$counters, sessions_active => $active }; + + $self->{cache_name} = "windows_" . $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')); +} + +1; + +__END__ + +=head1 MODE + +Check sessions. + +=over 8 + +=item B<--config> + +command can be localized by using a configuration file. +This parameter can be used to specify an alternative location for the configuration file + +=item B<--language> + +Set the language used in config file (default: 'en'). + +=item B<--command> + +Command to get information (Default: 'qwinsta'). +Can be changed if you have output in a file. + +=item B<--command-path> + +Command path (Default: none). + +=item B<--command-options> + +Command options (Default: '/COUNTER'). + +=item B<--timeout> + +Timeout in seconds for the command (Default: 30). + +=item B<--filter-sessionname> + +Filter session name (can be a regexp). + +=item B<--warning-*> + +Threshold warning. +Can be: 'inactive', 'active'. + +=item B<--critical-*> + +Threshold critical. +Can be: 'inactive', 'active', 'time' (in seconds since the session starts). + +=back + +=cut diff --git a/centreon-plugins/os/windows/local/plugin.pm b/centreon-plugins/os/windows/local/plugin.pm index c97f8111c..71795803d 100644 --- a/centreon-plugins/os/windows/local/plugin.pm +++ b/centreon-plugins/os/windows/local/plugin.pm @@ -31,8 +31,9 @@ sub new { $self->{version} = '0.1'; %{$self->{modes}} = ( - 'rdp-sessions' => 'os::windows::local::mode::rdpsessions', - 'time' => 'os::windows::local::mode::ntp', + 'pending-reboot' => 'os::windows::local::mode::pendingreboot', + 'sessions' => 'os::windows::local::mode::sessions', + 'time' => 'os::windows::local::mode::ntp', ); return $self; diff --git a/centreon-plugins/snmp_standard/mode/diskusage.pm b/centreon-plugins/snmp_standard/mode/diskusage.pm index ca11b4439..cdc9fa6a3 100644 --- a/centreon-plugins/snmp_standard/mode/diskusage.pm +++ b/centreon-plugins/snmp_standard/mode/diskusage.pm @@ -302,7 +302,7 @@ Allows to use regexp non case-sensitive (with --regexp). =item B<--reload-cache-time> -Time in seconds before reloading cache file (default: 180). +Time in minutes before reloading cache file (default: 180). =item B<--display-transform-src> 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/interfaces.pm b/centreon-plugins/snmp_standard/mode/interfaces.pm index 5793948d2..58b3cf3fa 100644 --- a/centreon-plugins/snmp_standard/mode/interfaces.pm +++ b/centreon-plugins/snmp_standard/mode/interfaces.pm @@ -1088,12 +1088,16 @@ sub load_cast { sub get_informations { my ($self, %options) = @_; + my $custom_load_method = $self->can('custom_load'); + my $custom_add_result_method = $self->can('custom_add_result'); + $self->get_selection(); $self->{array_interface_selected} = [keys %{$self->{interface_selected}}]; $self->load_status() if (defined($self->{option_results}->{add_status}) || defined($self->{option_results}->{add_global})); $self->load_errors() if (defined($self->{option_results}->{add_errors})); $self->load_traffic() if (defined($self->{option_results}->{add_traffic})); $self->load_cast() if ($self->{no_cast} == 0 && (defined($self->{option_results}->{add_cast}) || defined($self->{option_results}->{add_errors}))); + $self->$custom_load_method() if ($custom_load_method); $self->{results} = $self->{snmp}->get_leef(); @@ -1103,6 +1107,7 @@ sub get_informations { $self->add_result_traffic(instance => $_) if (defined($self->{option_results}->{add_traffic})); $self->add_result_cast(instance => $_) if ($self->{no_cast} == 0 && (defined($self->{option_results}->{add_cast}) || defined($self->{option_results}->{add_errors}))); $self->add_result_errors(instance => $_) if (defined($self->{option_results}->{add_errors})); + $self->$custom_add_result_method(instance => $_) if ($custom_add_result_method); } } diff --git a/centreon-plugins/snmp_standard/mode/numericvalue.pm b/centreon-plugins/snmp_standard/mode/numericvalue.pm index e75352489..6cf4770ca 100644 --- a/centreon-plugins/snmp_standard/mode/numericvalue.pm +++ b/centreon-plugins/snmp_standard/mode/numericvalue.pm @@ -41,6 +41,7 @@ sub new { "warning:s" => { name => 'warning' }, "critical:s" => { name => 'critical' }, "format:s" => { name => 'format' }, + "format-custom:s" => { name => 'format_custom' }, "format-scale" => { name => 'format_scale' }, "format-scale-type:s" => { name => 'format_scale_type' }, "perfdata-unit:s" => { name => 'perfdata_unit' }, @@ -83,7 +84,8 @@ sub add_data { $self->{output}->option_exit(); } - foreach (['oid_type', 'gauge'], ['counter_per_seconds'], ['format', 'current value is %s'], ['format_scale'], + foreach (['oid_type', 'gauge'], ['counter_per_seconds'], ['format', 'current value is %s'], + ['format_custom', ''], ['format_scale'], ['perfdata_unit', ''], ['perfdata_name', 'value'], ['perfdata_min', ''], ['perfdata_max', '']) { if (defined($options{data}->{$_->[0]})) { @@ -172,6 +174,10 @@ sub check_data { } } + if ($options{entry}->{format_custom} ne '') { + $value = eval "$value $options{entry}->{format_custom}"; + } + my $exit = $self->{perfdata}->threshold_check(value => $value, threshold => [ { label => 'critical-' . $options{num}, exit_litteral => 'critical' }, { label => 'warning-' . $options{num}, exit_litteral => 'warning' } ]); if (defined($options{entry}->{format_scale})) { @@ -255,6 +261,11 @@ Convert counter value on a value per seconds (only with type 'counter'). Output format (Default: 'current value is %s') +=item B<--format-custom> + +Apply a custom change on the value +(Example to multiply the value: --format-custom='* 8'). + =item B<--format-scale> Scale bytes value. We'll display value in output. diff --git a/centreon-plugins/snmp_standard/mode/storage.pm b/centreon-plugins/snmp_standard/mode/storage.pm index 3e98c9a5c..1c696d937 100644 --- a/centreon-plugins/snmp_standard/mode/storage.pm +++ b/centreon-plugins/snmp_standard/mode/storage.pm @@ -416,7 +416,7 @@ Allows to use regexp non case-sensitive (with --regexp). =item B<--reload-cache-time> -Time in seconds before reloading cache file (default: 180). +Time in minutes before reloading cache file (default: 180). =item B<--oid-filter> diff --git a/centreon-plugins/snmp_standard/mode/uptime.pm b/centreon-plugins/snmp_standard/mode/uptime.pm index 7f5a2778c..e4a26deaf 100644 --- a/centreon-plugins/snmp_standard/mode/uptime.pm +++ b/centreon-plugins/snmp_standard/mode/uptime.pm @@ -26,6 +26,8 @@ use strict; use warnings; use POSIX; use centreon::plugins::misc; +use centreon::plugins::statefile; +use Time::HiRes qw(time); sub new { my ($class, %options) = @_; @@ -35,11 +37,13 @@ sub new { $self->{version} = '1.0'; $options{options}->add_options(arguments => { - "warning:s" => { name => 'warning', }, - "critical:s" => { name => 'critical', }, - "force-oid:s" => { name => 'force_oid', }, + "warning:s" => { name => 'warning' }, + "critical:s" => { name => 'critical' }, + "force-oid:s" => { name => 'force_oid' }, + "check-overload" => { name => 'check_overload' }, }); - + + $self->{statefile_cache} = centreon::plugins::statefile->new(%options); return $self; } @@ -55,6 +59,38 @@ sub check_options { $self->{output}->add_option_msg(short_msg => "Wrong critical threshold '" . $self->{option_results}->{critical} . "'."); $self->{output}->option_exit(); } + + $self->{statefile_cache}->check_options(%options); +} + +sub check_overload { + my ($self, %options) = @_; + + return $options{timeticks} if (!defined($self->{option_results}->{check_overload})); + + my $current_time = floor(time() * 100); + $self->{new_datas} = { last_time => $current_time, uptime => $options{timeticks}, overload => 0 }; + $self->{statefile_cache}->read(statefile => "cache_" . $self->{snmp}->get_hostname() . '_' . $self->{snmp}->get_port() . '_' . $self->{mode}); + my $old_uptime = $self->{statefile_cache}->get(name => 'uptime'); + my $last_time = $self->{statefile_cache}->get(name => 'last_time'); + my $overload = $self->{statefile_cache}->get(name => 'overload'); + + if (defined($old_uptime) && $old_uptime < $current_time) { + my $diff_time = $current_time - $last_time; + my $overflow = ($old_uptime + $diff_time) % 4294967296; + my $division = ($old_uptime + $diff_time) / 4294967296; + if ($division >= 1 && + $overflow >= ($options{timeticks} - 5000) && + $overflow <= ($options{timeticks} + 5000)) { + $overload++; + } + + $options{timeticks} += ($overload * 4294967296); + } + $self->{new_datas}->{overload} = $overload if (defined($overload)); + + $self->{statefile_cache}->write(data => $self->{new_datas}); + return $options{timeticks}; } sub run { @@ -79,17 +115,20 @@ sub run { } } - my $exit_code = $self->{perfdata}->threshold_check(value => floor($value / 100), + $value = $self->check_overload(timeticks => $value); + $value = floor($value / 100); + + 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 => 'uptime', unit => 's', - value => floor($value / 100), + 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("System uptime is: %s", - centreon::plugins::misc::change_seconds(value => floor($value / 100), start => 'd'))); + centreon::plugins::misc::change_seconds(value => $value, start => 'd'))); $self->{output}->display(); $self->{output}->exit(); @@ -117,6 +156,11 @@ Threshold critical in seconds. Can choose your oid (numeric format only). +=item B<--check-overload> + +Uptime counter limit is 4294967296 and overflow. +With that option, we manage the counter going back. But there is a few chance we can miss a reboot. + =back =cut diff --git a/centreon-plugins/storage/dell/compellent/local/mode/volumeusage.pm b/centreon-plugins/storage/dell/compellent/local/mode/volumeusage.pm index 616898c3b..900a99c12 100644 --- a/centreon-plugins/storage/dell/compellent/local/mode/volumeusage.pm +++ b/centreon-plugins/storage/dell/compellent/local/mode/volumeusage.pm @@ -223,7 +223,8 @@ sub manage_selection { cem_port => $self->{option_results}->{cem_port}, sdk_path_dll => $self->{option_results}->{sdk_path_dll}, no_ps => $self->{option_results}->{no_ps}, - filter_sc => $self->{option_results}->{ps_sc_filter}); + filter_sc => $self->{option_results}->{ps_sc_filter}, + filter_vol => $self->{option_results}->{ps_sc_volume}); $self->{option_results}->{command_options} .= " " . $ps; my ($stdout) = centreon::plugins::misc::windows_execute(output => $self->{output}, @@ -349,4 +350,4 @@ Can be: 'sc-total', 'volume-usage', 'volume-overhead', 'volume-replay'. =back -=cut \ No newline at end of file +=cut diff --git a/centreon-plugins/storage/emc/isilon/snmp/mode/clusterusage.pm b/centreon-plugins/storage/emc/isilon/snmp/mode/clusterusage.pm index 30c6cf3c5..aeacaa9f2 100644 --- a/centreon-plugins/storage/emc/isilon/snmp/mode/clusterusage.pm +++ b/centreon-plugins/storage/emc/isilon/snmp/mode/clusterusage.pm @@ -147,7 +147,7 @@ sub set_counters { key_values => [ { name => 'health' } ], output_template => 'Node health: %.2f%%', perfdatas => [ - { label => 'health', value => 'health_absolute', template => '%2f', + { label => 'health', value => 'health_absolute', template => '%.2f', min => 0, max => 100, unit => '%' }, ], } diff --git a/centreon-plugins/storage/hp/msl/snmp/mode/hardware.pm b/centreon-plugins/storage/hp/msl/snmp/mode/hardware.pm new file mode 100644 index 000000000..cdae4bb3a --- /dev/null +++ b/centreon-plugins/storage/hp/msl/snmp/mode/hardware.pm @@ -0,0 +1,142 @@ +# +# 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::hp::msl::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} = '^(library)$'; + + $self->{cb_hook2} = 'snmp_execute'; + + $self->{thresholds} = { + library => [ + ['unknown', 'UNKNOWN'], + ['unused', 'UNKNOWN'], + ['ok', 'OK'], + ['warning', 'WARNING'], + ['critical', 'CRITICAL'], + ['nonrecoverable', 'CRITICAL'], + ], + }; + + $self->{components_path} = 'storage::hp::msl::snmp::mode::components'; + $self->{components_module} = ['library']; +} + +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 hardware. + +=over 8 + +=item B<--component> + +Which component to check (Default: '.*'). +Can be: 'library'. + +=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='library,CRITICAL,^(?!(ok)$)' + +=back + +=cut + +package storage::hp::msl::snmp::mode::components::library; + +use strict; +use warnings; + +my %map_health = (1 => 'unknown', 2 => 'unused', 3 => 'ok', + 4 => 'warning', 5 => 'critical', 6 => 'nonrecoverable', +); + +my $mapping_library = { + hpHttpMgDeviceHealth => { oid => '.1.3.6.1.4.1.11.2.36.1.1.5.1.1.3', map => \%map_health }, +}; + +sub load { + my ($self) = @_; + + push @{$self->{request}}, { oid => $mapping_library->{hpHttpMgDeviceHealth}->{oid} }; +} + +sub check { + my ($self) = @_; + + $self->{output}->output_add(long_msg => "Checking library"); + $self->{components}->{library} = {name => 'library', total => 0, skip => 0}; + return if ($self->check_filter(section => 'library')); + + foreach ($self->{snmp}->oid_lex_sort(keys %{$self->{results}->{ $mapping_library->{hpHttpMgDeviceHealth}->{oid} }})) { + /^$mapping_library->{hpHttpMgDeviceHealth}->{oid}\.(.*)$/; + my $instance = $1; + my $result = $self->{snmp}->map_instance(mapping => $mapping_library, results => $self->{results}->{ $mapping_library->{hpHttpMgDeviceHealth}->{oid} }, instance => $instance); + + next if ($self->check_filter(section => 'library', instance => $instance)); + + $self->{components}->{library}->{total}++; + $self->{output}->output_add(long_msg => sprintf("library '%s' status is '%s' [instance = %s]", + $instance, $result->{hpHttpMgDeviceHealth}, $instance)); + my $exit = $self->get_severity(section => 'library', value => $result->{hpHttpMgDeviceHealth}); + if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { + $self->{output}->output_add(severity => $exit, + short_msg => sprintf("Library '%s' status is '%s'", $instance, $result->{hpHttpMgDeviceHealth})); + } + } +} + +1; diff --git a/centreon-plugins/storage/hp/msl/snmp/mode/status.pm b/centreon-plugins/storage/hp/msl/snmp/mode/status.pm deleted file mode 100644 index 1197cf73c..000000000 --- a/centreon-plugins/storage/hp/msl/snmp/mode/status.pm +++ /dev/null @@ -1,146 +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 storage::hp::msl::snmp::mode::status; - -use base qw(centreon::plugins::mode); - -use strict; -use warnings; - -my $oid_hpHttpMgDeviceHealth = '.1.3.6.1.4.1.11.2.36.1.1.5.1.1.3.1'; - -my $thresholds = { - library => [ - ['unknown', 'UNKNOWN'], - ['unused', 'UNKNOWN'], - ['ok', 'OK'], - ['warning', 'WARNING'], - ['critical', 'CRITICAL'], - ['nonrecoverable', 'CRITICAL'], - ], -}; - -my %map_states_status = ( - 1 => 'unknown', - 2 => 'unused', - 3 => 'ok', - 4 => 'warning', - 5 => 'critical', - 6 => 'nonrecoverable', -); - -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 => - { - "threshold-overload:s@" => { name => 'threshold_overload' }, - }); - - return $self; -} - -sub check_options { - my ($self, %options) = @_; - $self->SUPER::init(%options); - - $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->{snmp} = $options{snmp}; - - my $result = $self->{snmp}->get_leef(oids => [$oid_hpHttpMgDeviceHealth], - nothing_quit => 1); - my $library_status = $result->{$oid_hpHttpMgDeviceHealth}; - - $self->{output}->output_add(severity => 'OK', - short_msg => sprintf("Library status is %s.", $map_states_status{$library_status})); - - my $exit = $self->get_severity(section => 'library', value => $map_states_status{$library_status}); - if (!$self->{output}->is_status(value => $exit, compare => 'OK', litteral => 1)) { - $self->{output}->output_add(severity => $exit, - short_msg => sprintf("Library status is %s.", $map_states_status{$library_status})); - } - - $self->{output}->display(); - $self->{output}->exit(); -} - -sub get_severity { - my ($self, %options) = @_; - my $status = 'UNKNOWN'; # default - - if (defined($self->{overload_th}->{$options{section}})) { - foreach (@{$self->{overload_th}->{$options{section}}}) { - if ($options{value} =~ /$_->{filter}/i) { - $status = $_->{status}; - return $status; - } - } - } - foreach (@{$thresholds->{$options{section}}}) { - if ($options{value} =~ /$$_[0]/i) { - $status = $$_[1]; - return $status; - } - } - - return $status; -} - -1; - -__END__ - -=head1 MODE - -Check Library status. - -=over 8 - -=item B<--threshold-overload> - -Set to overload default threshold values (syntax: section,status,regexp) -It used before default thresholds (order stays). -Example: --threshold-overload='library,CRITICAL,^(?!(ok)$)' - -=back - -=cut diff --git a/centreon-plugins/storage/hp/msl/snmp/plugin.pm b/centreon-plugins/storage/hp/msl/snmp/plugin.pm index 696973005..4c7cdc464 100644 --- a/centreon-plugins/storage/hp/msl/snmp/plugin.pm +++ b/centreon-plugins/storage/hp/msl/snmp/plugin.pm @@ -31,7 +31,7 @@ sub new { $self->{version} = '1.0'; %{$self->{modes}} = ( - 'status' => 'storage::hp::msl::snmp::mode::status', + 'hardware' => 'storage::hp::msl::snmp::mode::hardware', ); return $self; diff --git a/centreon-plugins/storage/hp/storeonce/restapi/custom/api.pm b/centreon-plugins/storage/hp/storeonce/restapi/custom/api.pm index f14f72989..6cb495765 100644 --- a/centreon-plugins/storage/hp/storeonce/restapi/custom/api.pm +++ b/centreon-plugins/storage/hp/storeonce/restapi/custom/api.pm @@ -59,20 +59,15 @@ sub new { } -# 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++) { @@ -88,8 +83,6 @@ 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->{username} = (defined($self->{option_results}->{username})) ? shift(@{$self->{option_results}->{username}}) : ''; @@ -130,18 +123,15 @@ sub settings { $self->{http}->set_options(%{$self->{option_results}}); } -#my $xml = XMLin($biggest_reponse, ForceArray => 1); - sub get { my ($self, %options) = @_; $self->settings(); - my $response = $self->{http}->request(url_path => '/storeonceservices' . $options{path}, critical_status => '', warning_status => ''); my $content; eval { - $content = XMLin($response, ForceArray => $options{ForceArray}); + $content = XMLin($response, ForceArray => $options{ForceArray}, KeyAttr => []); }; if ($@) { $self->{output}->add_option_msg(short_msg => "Cannot decode xml response: $@"); diff --git a/centreon-plugins/storage/hp/storeonce/restapi/mode/nasusage.pm b/centreon-plugins/storage/hp/storeonce/restapi/mode/nasusage.pm new file mode 100644 index 000000000..a41d7c4e6 --- /dev/null +++ b/centreon-plugins/storage/hp/storeonce/restapi/mode/nasusage.pm @@ -0,0 +1,251 @@ +# +# 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::hp::storeonce::restapi::mode::nasusage; + +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_nas_status_output { + my ($self, %options) = @_; + + my $msg = sprintf('status : %s [replication health: %s]', + $self->{result_values}->{health}, $self->{result_values}->{replication_health}); + return $msg; +} + +sub custom_nas_status_calc { + my ($self, %options) = @_; + + $self->{result_values}->{health} = $options{new_datas}->{$self->{instance} . '_health'}; + $self->{result_values}->{replication_health} = $options{new_datas}->{$self->{instance} . '_replication_health'}; + $self->{result_values}->{display} = $options{new_datas}->{$self->{instance} . '_display'}; + return 0; +} + +sub custom_share_status_output { + my ($self, %options) = @_; + + my $msg = sprintf('status : %s', $self->{result_values}->{health}); + return $msg; +} + +sub custom_share_status_calc { + my ($self, %options) = @_; + + $self->{result_values}->{health} = $options{new_datas}->{$self->{instance} . '_health'}; + $self->{result_values}->{display} = $options{new_datas}->{$self->{instance} . '_display'}; + return 0; +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'nas', type => 1, cb_prefix_output => 'prefix_nas_output', message_multiple => 'All nas are ok' }, + { name => 'share', type => 1, cb_prefix_output => 'prefix_share_output', message_multiple => 'All shares are ok' }, + ]; + + $self->{maps_counters}->{nas} = [ + { label => 'nas-status', threshold => 0, set => { + key_values => [ { name => 'replication_health' }, { name => 'health' }, { 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'), + } + }, + ]; + + $self->{maps_counters}->{share} = [ + { label => 'share-status', threshold => 0, set => { + key_values => [ { name => 'health' }, { name => 'display' } ], + closure_custom_calc => $self->can('custom_share_status_calc'), + closure_custom_output => $self->can('custom_share_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-nas-status:s" => { name => 'warning_nas_status', default => '%{health} =~ /warning/i' }, + "critical-nas-status:s" => { name => 'critical_nas_status', default => '%{health} =~ /critical/i' }, + "warning-share-status:s" => { name => 'warning_share_status', default => '%{health} =~ /warning/i' }, + "critical-share-status:s" => { name => 'critical_share_status', default => '%{health} =~ /critical/i' }, + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::check_options(%options); + + $instance_mode = $self; + $self->change_macros(); +} + +sub prefix_nas_output { + my ($self, %options) = @_; + + return "NAS '" . $options{instance_value}->{display} . "' "; +} + +sub prefix_share_output { + my ($self, %options) = @_; + + return "Share '" . $options{instance_value}->{display} . "' "; +} + +sub change_macros { + my ($self, %options) = @_; + + foreach (('warning_nas_status', 'critical_nas_status', 'warning_share_status', 'critical_share_status')) { + if (defined($self->{option_results}->{$_})) { + $self->{option_results}->{$_} =~ s/%\{(.*?)\}/\$self->{result_values}->{$1}/g; + } + } +} + +my %mapping_health_level = ( + 0 => 'unknown', + 1 => 'ok', + 2 => 'information', + 3 => 'warning', + 4 => 'critical', +); + +sub manage_selection { + my ($self, %options) = @_; + + $self->{nas} = {}; + $self->{share} = {}; + my $result = $options{custom}->get(path => '/cluster/servicesets/*all*/services/nas', ForceArray => ['service', 'item']); + if (defined($result->{services}->{service})) { + foreach my $entry (@{$result->{services}->{service}}) { + if (defined($self->{option_results}->{filter_name}) && $self->{option_results}->{filter_name} ne '' && + $entry->{properties}->{ssid} !~ /$self->{option_results}->{filter_name}/) { + $self->{output}->output_add(long_msg => "skipping '" . $entry->{properties}->{ssid} . "': no matching filter.", debug => 1); + next; + } + + $self->{nas}->{$entry->{properties}->{ssid}} = { + display => $entry->{properties}->{ssid}, + health => $mapping_health_level{$entry->{properties}->{nasHealthLevel}}, + replication_health => $mapping_health_level{$entry->{properties}->{repHealthLevel}}, + }; + + foreach my $item (@{$entry->{shares}->{item}}) { + $self->{share}->{$entry->{properties}->{ssid} . '.' . $item->{id}} = { + display => $entry->{properties}->{ssid} . '.' . $item->{id}, + health => $mapping_health_level{$item->{summaryHealthLevel}}, + }; + } + } + } + + if (scalar(keys %{$self->{nas}}) <= 0) { + $self->{output}->add_option_msg(short_msg => "No nas found."); + $self->{output}->option_exit(); + } +} + +1; + +__END__ + +=head1 MODE + +Check NAS status. + +=over 8 + +=item B<--filter-counters> + +Only display some counters (regexp can be used). +Example: --filter-counters='^nas-status$' + +=item B<--filter-name> + +Filter nas name (can be a regexp). + +=item B<--warning-nas-status> + +Set warning threshold for status (Default: '%{health} =~ /warning/i'). +Can used special variables like: %{health}, %{replication_health}, %{display} + +=item B<--critical-nas-status> + +Set critical threshold for status (Default: '%{health} =~ /critical/i'). +Can used special variables like: %{health}, %{replication_health}, %{display} + +=item B<--warning-share-status> + +Set warning threshold for status (Default: '%{health} =~ /warning/i'). +Can used special variables like: %{health}, %{replication_health}, %{display} + +=item B<--critical-share-status> + +Set critical threshold for status (Default: '%{health} =~ /critical/i'). +Can used special variables like: %{health}, %{replication_health}, %{display} + +=back + +=cut diff --git a/centreon-plugins/storage/hp/storeonce/restapi/mode/servicesetusage.pm b/centreon-plugins/storage/hp/storeonce/restapi/mode/servicesetusage.pm index 5faa7790f..5e84754e6 100644 --- a/centreon-plugins/storage/hp/storeonce/restapi/mode/servicesetusage.pm +++ b/centreon-plugins/storage/hp/storeonce/restapi/mode/servicesetusage.pm @@ -54,7 +54,8 @@ sub custom_status_threshold { sub custom_status_output { my ($self, %options) = @_; - my $msg = 'status : ' . $self->{result_values}->{health}; + my $msg = sprintf('status : %s [replication health: %s] [housekeeping health: %s]', + $self->{result_values}->{health}, $self->{result_values}->{replication_health}, $self->{result_values}->{housekeeping_health}); return $msg; } @@ -63,6 +64,7 @@ sub custom_status_calc { $self->{result_values}->{health} = $options{new_datas}->{$self->{instance} . '_health'}; $self->{result_values}->{housekeeping_health} = $options{new_datas}->{$self->{instance} . '_housekeeping_health'}; + $self->{result_values}->{replication_health} = $options{new_datas}->{$self->{instance} . '_replication_health'}; $self->{result_values}->{display} = $options{new_datas}->{$self->{instance} . '_display'}; return 0; } @@ -140,7 +142,7 @@ sub set_counters { $self->{maps_counters}->{scs} = [ { label => 'status', threshold => 0, set => { - key_values => [ { name => 'health' }, { name => 'housekeeping_health' }, { name => 'display' } ], + key_values => [ { name => 'health' }, { name => 'replication_health' }, { name => 'housekeeping_health' }, { name => 'display' } ], closure_custom_calc => $self->can('custom_status_calc'), closure_custom_output => $self->can('custom_status_output'), closure_custom_perfdata => sub { return 0; }, @@ -235,6 +237,7 @@ sub manage_selection { display => $entry->{properties}->{alias}, health => $mapping_health_level{$entry->{properties}->{healthLevel}}, housekeeping_health => $mapping_health_level{$entry->{properties}->{housekeepingHealthLevel}}, + replication_health => $mapping_health_level{$entry->{properties}->{repHealthLevel}}, total => $entry->{properties}->{capacityBytes}, used => $entry->{properties}->{capacityBytes} - $entry->{properties}->{freeBytes}, dedup => $entry->{properties}->{dedupeRatio} }; @@ -269,12 +272,12 @@ Filter service set name (can be a regexp). =item B<--warning-status> Set warning threshold for status (Default: '%{health} =~ /warning/). -Can used special variables like: %{health}, %{housekeeping_health}, %{display} +Can used special variables like: %{health}, %{replication_health}, %{housekeeping_health}, %{display} =item B<--critical-status> Set critical threshold for status (Default: '%{health} =~ /critical/'). -Can used special variables like: %{health}, %{housekeeping_health}, %{display} +Can used special variables like: %{health}, %{replication_health}, %{housekeeping_health}, %{display} =item B<--warning-*> diff --git a/centreon-plugins/storage/hp/storeonce/restapi/plugin.pm b/centreon-plugins/storage/hp/storeonce/restapi/plugin.pm index d3ae16bbc..7f457d8eb 100644 --- a/centreon-plugins/storage/hp/storeonce/restapi/plugin.pm +++ b/centreon-plugins/storage/hp/storeonce/restapi/plugin.pm @@ -33,6 +33,7 @@ sub new { %{$self->{modes}} = ( 'cluster-usage' => 'storage::hp::storeonce::restapi::mode::clusterusage', 'fcs-usage' => 'storage::hp::storeonce::restapi::mode::fcsusage', + 'nas-usage' => 'storage::hp::storeonce::restapi::mode::nasusage', 'serviceset-usage' => 'storage::hp::storeonce::restapi::mode::servicesetusage', ); diff --git a/centreon-plugins/storage/kaminario/restapi/custom/api.pm b/centreon-plugins/storage/kaminario/restapi/custom/api.pm new file mode 100644 index 000000000..4ea8dd4a8 --- /dev/null +++ b/centreon-plugins/storage/kaminario/restapi/custom/api.pm @@ -0,0 +1,208 @@ +# +# 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::kaminario::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', }, + "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}); + + 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->{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}}) : '5m'; + + 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} = 443; + $self->{option_results}->{proto} = 'https'; + $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}->add_header(key => 'Accept', value => 'application/json'); + $self->{http}->set_options(%{$self->{option_results}}); +} + +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 $decoded; + eval { + $decoded = decode_json($content); + }; + if ($@) { + $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->{message}); + # $self->{output}->option_exit(); + #} + + return $decoded; +} + +1; + +__END__ + +=head1 NAME + +KAMINARIO REST API + +=head1 SYNOPSIS + +Kaminario Rest API custom mode + +=head1 REST API OPTIONS + +=over 8 + +=item B<--hostname> + +Kaminario hostname. + +=item B<--username> + +Kaminario username. + +=item B<--password> + +Kaminario password. + +=item B<--proxyurl> + +Proxy URL if any. + +=item B<--timeout> + +Set HTTP timeout in seconds (Default: '10'). + +=item B<--resolution> + +Selected data performance resolution (Default: '5m'). + +=back + +=head1 DESCRIPTION + +B. + +=cut diff --git a/centreon-plugins/storage/kaminario/restapi/mode/systemusage.pm b/centreon-plugins/storage/kaminario/restapi/mode/systemusage.pm new file mode 100644 index 000000000..d865a334b --- /dev/null +++ b/centreon-plugins/storage/kaminario/restapi/mode/systemusage.pm @@ -0,0 +1,187 @@ +# +# 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::kaminario::restapi::mode::systemusage; + +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_global_output' }, + { name => 'bs', type => 1, cb_prefix_output => 'prefix_bs_output', message_multiple => 'All block sizes are ok' } + ]; + + $self->{maps_counters}->{global} = [ + { label => 'iops', set => { + key_values => [ { name => 'iops_avg' } ], + output_template => 'Average IOPs : %s', + perfdatas => [ + { label => 'iops', value => 'iops_avg_absolute', template => '%s', + min => 0, unit => 'iops' }, + ], + } + }, + { label => 'throughput', set => { + key_values => [ { name => 'throughput_avg' } ], + output_template => 'Average Throughput : %s %s', + output_change_bytes => 1, + perfdatas => [ + { label => 'throughput', value => 'throughput_avg_absolute', template => '%s', + min => 0, unit => 'B' }, + ], + } + }, + { label => 'latency-inner', set => { + key_values => [ { name => 'latency_inner' } ], + output_template => 'Latency Inner : %.6fms', + perfdatas => [ + { label => 'latency_inner', value => 'latency_inner_absolute', template => '%.6f', + min => 0, unit => 'ms' }, + ], + } + }, + { label => 'latency-outer', set => { + key_values => [ { name => 'latency_outer' } ], + output_template => 'Latency Outer : %.6fms', + perfdatas => [ + { label => 'latency_outer', value => 'latency_outer_absolute', template => '%.6f', + min => 0, unit => 'ms' }, + ], + } + }, + ]; + + $self->{maps_counters}->{bs} = [ + { label => 'bs-iops', set => { + key_values => [ { name => 'iops_avg' }, { name => 'display' } ], + output_template => 'Average IOPs : %s', + perfdatas => [ + { label => 'iops', value => 'iops_avg_absolute', template => '%s', + min => 0, unit => 'iops', label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + { label => 'bs-throughput', set => { + key_values => [ { name => 'throughput_avg' }, { name => 'display' } ], + output_template => 'Average Throughput : %s %s', + output_change_bytes => 1, + perfdatas => [ + { label => 'throughput', value => 'throughput_avg_absolute', template => '%s', + min => 0, unit => 'B', label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + { label => 'bs-latency-inner', set => { + key_values => [ { name => 'latency_inner' }, { name => 'display' } ], + output_template => 'Latency Inner : %.6fms', + perfdatas => [ + { label => 'latency_inner', value => 'latency_inner_absolute', template => '%.6f', + min => 0, unit => 'ms', label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + { label => 'bs-latency-outer', set => { + key_values => [ { name => 'latency_outer' }, { name => 'display' } ], + output_template => 'Latency Outer : %.6fms', + perfdatas => [ + { label => 'latency_outer', value => 'latency_outer_absolute', template => '%.6f', + min => 0, unit => 'ms', 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 => + { + }); + + return $self; +} + +sub prefix_global_output { + my ($self, %options) = @_; + + return "System "; +} + +sub prefix_bs_output { + my ($self, %options) = @_; + + return "Block size '" . $options{instance_value}->{display} . "' "; +} + +sub manage_selection { + my ($self, %options) = @_; + + $self->{bs} = {}; + my $result = $options{custom}->get_performance(path => '/stats/system?__datapoints=1&__bs_breakdown=true'); + foreach my $entry (@{$result->{hits}}) { + $self->{bs}->{$entry->{bs}} = { + display => $entry->{bs}, + %{$entry}, + }; + } + + $result = $options{custom}->get_performance(path => '/stats/system?__datapoints=1'); + $self->{global} = { %{$result->{hits}->[0]} }; +} + +1; + +__END__ + +=head1 MODE + +Check system usage. + +=over 8 + +=item B<--filter-counters> + +Only display some counters (regexp can be used). +Example: --filter-counters='^iops$' + +=item B<--warning-*> + +Threshold warning. +Can be: 'latency-inner', 'latency-outer', 'iops', 'throughput', +'bs-latency-inner', 'bs-latency-outer', 'bs-iops', 'bs-throughput', + +=item B<--critical-*> + +Threshold critical. +Can be: 'latency-inner', 'latency-outer', 'iops', 'throughput', +'bs-latency-inner', 'bs-latency-outer', 'bs-iops', 'bs-throughput', + +=back + +=cut diff --git a/centreon-plugins/storage/kaminario/restapi/mode/volumeusage.pm b/centreon-plugins/storage/kaminario/restapi/mode/volumeusage.pm new file mode 100644 index 000000000..0a3078e8f --- /dev/null +++ b/centreon-plugins/storage/kaminario/restapi/mode/volumeusage.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 storage::kaminario::restapi::mode::volumeusage; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; + +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 => 'iops', set => { + key_values => [ { name => 'iops_avg' }, { name => 'display' } ], + output_template => 'Average IOPs : %s', + perfdatas => [ + { label => 'iops', value => 'iops_avg_absolute', template => '%s', + min => 0, unit => 'iops', label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + { label => 'throughput', set => { + key_values => [ { name => 'throughput_avg' }, { name => 'display' } ], + output_template => 'Average Throughput : %s %s', + output_change_bytes => 1, + perfdatas => [ + { label => 'throughput', value => 'throughput_avg_absolute', template => '%s', + min => 0, unit => 'B', label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + { label => 'latency-inner', set => { + key_values => [ { name => 'latency_inner' }, { name => 'display' } ], + output_template => 'Latency Inner : %.6fms', + perfdatas => [ + { label => 'latency_inner', value => 'latency_inner_absolute', template => '%.6f', + min => 0, unit => 'ms', label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + { label => 'latency-outer', set => { + key_values => [ { name => 'latency_outer' }, { name => 'display' } ], + output_template => 'Latency Outer : %.6fms', + perfdatas => [ + { label => 'latency_outer', value => 'latency_outer_absolute', template => '%.6f', + min => 0, unit => 'ms', 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' }, + }); + + return $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_performance(path => '/stats/volumes?__datapoints=1'); + foreach my $entry (@{$result->{hits}}) { + if (defined($self->{option_results}->{filter_name}) && $self->{option_results}->{filter_name} ne '' && + $entry->{volume_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->{volume_name}} = { + display => $entry->{volume_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: 'latency-inner', 'latency-outer', 'iops', 'throughput' + +=item B<--critical-*> + +Threshold critical. +Can be: 'latency-inner', 'latency-outer', 'iops', 'throughput' + +=back + +=cut diff --git a/centreon-plugins/storage/kaminario/restapi/plugin.pm b/centreon-plugins/storage/kaminario/restapi/plugin.pm new file mode 100644 index 000000000..bd3316d46 --- /dev/null +++ b/centreon-plugins/storage/kaminario/restapi/plugin.pm @@ -0,0 +1,50 @@ +# +# 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::kaminario::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}} = ( + 'system-usage' => 'storage::kaminario::restapi::mode::systemusage', + 'volume-usage' => 'storage::kaminario::restapi::mode::volumeusage', + ); + + $self->{custom_modes}{api} = 'storage::kaminario::restapi::custom::api'; + return $self; +} + +1; + +__END__ + +=head1 PLUGIN DESCRIPTION + +Check Kaminario through HTTP/REST API. + +=cut