diff --git a/centreon-plugins/network/silverpeak/snmp/mode/alarms.pm b/centreon-plugins/network/silverpeak/snmp/mode/alarms.pm index 89048099f..6c85a0977 100644 --- a/centreon-plugins/network/silverpeak/snmp/mode/alarms.pm +++ b/centreon-plugins/network/silverpeak/snmp/mode/alarms.pm @@ -24,17 +24,22 @@ use base qw(centreon::plugins::templates::counter); use strict; use warnings; +use DateTime; use POSIX; use centreon::plugins::misc; use centreon::plugins::statefile; -use centreon::plugins::templates::catalog_functions qw(catalog_status_threshold); +use centreon::plugins::templates::catalog_functions qw(catalog_status_threshold_ng); sub custom_status_output { my ($self, %options) = @_; - my $msg = sprintf("alarm [severity: %s] [source: %s] [text: %s] %s", $self->{result_values}->{severity}, - $self->{result_values}->{source}, $self->{result_values}->{text}, $self->{result_values}->{generation_time}); - return $msg; + return sprintf( + "alarm [severity: %s] [source: %s] [text: %s] %s", + $self->{result_values}->{severity}, + $self->{result_values}->{source}, + $self->{result_values}->{text}, + scalar(localtime($self->{result_values}->{generation_time})) + ); } sub custom_status_calc { @@ -58,15 +63,20 @@ sub set_counters { ]; $self->{maps_counters}->{alarm} = [ - { label => 'status', threshold => 0, set => { + { + label => 'status', + type => 2, + warning_default => '%{severity} =~ /minor|warning/i', + critical_default => '%{severity} =~ /critical|major/i', + set => { key_values => [ { name => 'spsActiveAlarmSource' }, { name => 'spsActiveAlarmDescr' }, { name => 'since' }, { name => 'spsActiveAlarmSeverity' }, { name => 'spsActiveAlarmLogTime' } ], 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 => \&catalog_status_threshold, + closure_custom_threshold_check => \&catalog_status_threshold_ng } - }, + } ]; } @@ -75,16 +85,16 @@ sub new { my $self = $class->SUPER::new(package => __PACKAGE__, %options); bless $self, $class; - $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' }, - }); - - centreon::plugins::misc::mymodule_load(output => $self->{output}, module => 'Date::Parse', - error_msg => "Cannot load module 'Date::Parse'."); + $options{options}->add_options(arguments => { + 'filter-msg:s' => { name => 'filter_msg' }, + 'memory' => { name => 'memory' } + }); + + centreon::plugins::misc::mymodule_load( + output => $self->{output}, + module => 'Date::Parse', + error_msg => "Cannot load module 'Date::Parse'." + ); $self->{statefile_cache} = centreon::plugins::statefile->new(%options); return $self; } @@ -93,7 +103,6 @@ sub check_options { my ($self, %options) = @_; $self->SUPER::check_options(%options); - $self->change_macros(macros => ['warning_status', 'critical_status']); if (defined($self->{option_results}->{memory})) { $self->{statefile_cache}->check_options(%options); } @@ -106,7 +115,7 @@ my $mapping = { spsActiveAlarmSeverity => { oid => '.1.3.6.1.4.1.23867.3.1.1.2.1.1.3', map => \%map_severity }, spsActiveAlarmSource => { oid => '.1.3.6.1.4.1.23867.3.1.1.2.1.1.6' }, spsActiveAlarmDescr => { oid => '.1.3.6.1.4.1.23867.3.1.1.2.1.1.5' }, - spsActiveAlarmLogTime => { oid => '.1.3.6.1.4.1.23867.3.1.1.2.1.1.11' }, # timestamp + spsActiveAlarmLogTime => { oid => '.1.3.6.1.4.1.23867.3.1.1.2.1.1.11' } # timestamp }; sub manage_selection { @@ -131,27 +140,50 @@ sub manage_selection { next if ($oid !~ /^$mapping->{spsActiveAlarmSeverity}->{oid}\.(.*)$/); my $instance = $1; my $result = $options{snmp}->map_instance(mapping => $mapping, results => $snmp_result, instance => $instance); - - my $create_time = $result->{spsActiveAlarmLogTime}; - if (!defined($create_time)) { - $self->{output}->output_add(severity => 'UNKNOWN', - short_msg => "Can't get date '" . $result->{spsActiveAlarmLogTime} . "'"); + + if (!defined($result->{spsActiveAlarmLogTime})) { + $self->{output}->output_add( + severity => 'UNKNOWN', + short_msg => "Can't get date '" . $result->{spsActiveAlarmLogTime} . "'" + ); next; } - + + my $create_time = $result->{spsActiveAlarmLogTime}; + if ($create_time !~ /^\d+$/) { + my @date = unpack('n C6 a C2', $result->{spsActiveAlarmLogTime}); + my $tz; + if (defined($date[7])) { + $tz = 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 => $tz + ); + $create_time = $dt->epoch(); + } + 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->{spsActiveAlarmDescr} !~ /$self->{option_results}->{filter_msg}/) { $self->{output}->output_add(long_msg => "skipping '" . $result->{spsActiveAlarmDescr} . "': no matching filter.", debug => 1); next; } - + my $diff_time = $current_time - $create_time; - - $self->{alarms}->{global}->{alarm}->{$i} = { %$result, since => $diff_time }; + + $self->{alarms}->{global}->{alarm}->{$i} = $result; + $self->{alarms}->{global}->{alarm}->{$i}->{since} = $diff_time; + $self->{alarms}->{global}->{alarm}->{$i}->{spsActiveAlarmLogTime} = $create_time; $i++; } - + if (defined($self->{option_results}->{memory})) { $self->{statefile_cache}->write(data => { last_time => $current_time }); } diff --git a/centreon-plugins/network/silverpeak/snmp/mode/status.pm b/centreon-plugins/network/silverpeak/snmp/mode/status.pm index 1201d03d7..1f2e74cfa 100644 --- a/centreon-plugins/network/silverpeak/snmp/mode/status.pm +++ b/centreon-plugins/network/silverpeak/snmp/mode/status.pm @@ -24,35 +24,29 @@ use base qw(centreon::plugins::templates::counter); use strict; use warnings; -use centreon::plugins::templates::catalog_functions qw(catalog_status_threshold); +use centreon::plugins::templates::catalog_functions qw(catalog_status_threshold_ng); sub custom_status_output { my ($self, %options) = @_; - my $msg = "Operational state: '" . $self->{result_values}->{operStatus} . "' "; - return $msg; -} -sub custom_status_calc { - my ($self, %options) = @_; - $self->{result_values}->{operStatus} = $options{new_datas}->{$self->{instance} . '_operStatus'}; - return 0; + return "Operational state: '" . $self->{result_values}->{operStatus} . "' "; } sub set_counters { my ($self, %options) = @_; $self->{maps_counters_type} = [ - { name => 'operationnal_state', type => 0 }, + { name => 'global', type => 0 } ]; - $self->{maps_counters}->{operationnal_state} = [ - { label => 'status', threshold => 0, set => { + + $self->{maps_counters}->{global} = [ + { label => 'status', type => 2, critical_default => '%{operStatus} !~ /(Normal)/', set => { key_values => [ { name => 'operStatus' } ], - 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 => \&catalog_status_threshold, + closure_custom_threshold_check => \&catalog_status_threshold_ng } - }, + } ]; } @@ -61,33 +55,21 @@ sub new { my $self = $class->SUPER::new(package => __PACKAGE__, %options); bless $self, $class; - $options{options}->add_options(arguments => - { - "warning-status:s" => { name => 'warning_status', default => '' }, - "critical-status:s" => { name => 'critical_status', default => '%{operStatus} !~ /(Normal)/' }, - }); + $options{options}->add_options(arguments => {}); return $self; } -sub check_options { - my ($self, %options) = @_; - $self->SUPER::check_options(%options); - - $self->change_macros(macros => ['warning_status', 'critical_status']); -} - sub manage_selection { my ($self, %options) = @_; - $self->{operationnal_state} = {}; - my $oid_spsOperStatus = '.1.3.6.1.4.1.23867.3.1.1.1.3.0'; + my $result = $options{snmp}->get_leef( + oids => [ $oid_spsOperStatus ], + nothing_quit => 1 + ); - my $result = $options{snmp}->get_leef(oids => [ $oid_spsOperStatus ], - nothing_quit => 1); - - $self->{operationnal_state} = { operStatus => $result->{$oid_spsOperStatus}}; + $self->{global} = { operStatus => $result->{$oid_spsOperStatus}}; } 1; diff --git a/centreon-plugins/network/silverpeak/snmp/mode/uptime.pm b/centreon-plugins/network/silverpeak/snmp/mode/uptime.pm index b2ab23fc5..52aff8f68 100644 --- a/centreon-plugins/network/silverpeak/snmp/mode/uptime.pm +++ b/centreon-plugins/network/silverpeak/snmp/mode/uptime.pm @@ -20,7 +20,7 @@ package network::silverpeak::snmp::mode::uptime; -use base qw(centreon::plugins::mode); +use base qw(centreon::plugins::templates::counter); use strict; use warnings; @@ -29,102 +29,157 @@ use centreon::plugins::misc; use centreon::plugins::statefile; use Time::HiRes qw(time); +my $unitdiv = { s => 1, w => 604800, d => 86400, h => 3600, m => 60 }; +my $unitdiv_long = { s => 'seconds', w => 'weeks', d => 'days', h => 'hours', m => 'minutes' }; + +sub custom_uptime_output { + my ($self, %options) = @_; + + my $msg = sprintf( + 'System uptime is: %s', + centreon::plugins::misc::change_seconds(value => $self->{result_values}->{uptime}, start => 'd') + ); + if (defined($self->{instance_mode}->{option_results}->{add_sysdesc})) { + $msg .= sprintf(', %s', $self->{result_values}->{sysdesc}); + } + + return $msg; +} + +sub custom_uptime_perfdata { + my ($self, %options) = @_; + + $self->{output}->perfdata_add( + label => 'uptime', unit => $self->{instance_mode}->{option_results}->{unit}, + nlabel => 'system.uptime.' . $unitdiv_long->{ $self->{instance_mode}->{option_results}->{unit} }, + value => floor($self->{result_values}->{uptime} / $unitdiv->{ $self->{instance_mode}->{option_results}->{unit} }), + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{thlabel}), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{thlabel}), + min => 0 + ); +} + +sub custom_uptime_threshold { + my ($self, %options) = @_; + + return $self->{perfdata}->threshold_check( + value => floor($self->{result_values}->{uptime} / $unitdiv->{ $self->{instance_mode}->{option_results}->{unit} }), + threshold => [ + { label => 'critical-' . $self->{thlabel}, exit_litteral => 'critical' }, + { label => 'warning-'. $self->{thlabel}, exit_litteral => 'warning' }, + { label => 'unknown-'. $self->{thlabel}, exit_litteral => 'unknown' } + ] + ); +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'global', type => 0 } + ]; + + $self->{maps_counters}->{global} = [ + { label => 'uptime', set => { + key_values => [ { name => 'uptime' }, { name => 'sysdesc' } ], + closure_custom_output => $self->can('custom_uptime_output'), + closure_custom_perfdata => $self->can('custom_uptime_perfdata'), + closure_custom_threshold_check => $self->can('custom_uptime_threshold') + } + } + ]; +} + sub new { my ($class, %options) = @_; - my $self = $class->SUPER::new(package => __PACKAGE__, %options); + my $self = $class->SUPER::new(package => __PACKAGE__, %options, force_new_perfdata => 1); bless $self, $class; - - $options{options}->add_options(arguments => - { - "warning:s" => { name => 'warning' }, - "critical:s" => { name => 'critical' }, - "force-oid:s" => { name => 'force_oid' }, - "check-overflow" => { name => 'check_overflow' }, - }); - + + $options{options}->add_options(arguments => { + 'force-oid:s' => { name => 'force_oid' }, + 'check-overload' => { name => 'check_overload' }, + 'reboot-window:s' => { name => 'reboot_window', default => 5000 }, + 'unit:s' => { name => 'unit', default => 's' }, + 'add-sysdesc' => { name => 'add_sysdesc' } + }); + $self->{statefile_cache} = centreon::plugins::statefile->new(%options); 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} . "'."); - $self->{output}->option_exit(); + if ($self->{option_results}->{unit} eq '' || !defined($unitdiv->{$self->{option_results}->{unit}})) { + $self->{option_results}->{unit} = 's'; } - 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_cache}->check_options(%options); } -sub check_overflow { +sub check_overload { my ($self, %options) = @_; - return $options{timeticks} if (!defined($self->{option_results}->{check_overflow})); + 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}, overflow => 0 }; - $self->{statefile_cache}->read(statefile => "cache_" . $self->{snmp}->get_hostname() . '_' . $self->{snmp}->get_port() . '_' . $self->{mode}); + $self->{new_datas} = { last_time => $current_time, uptime => $options{timeticks} }; + $self->{statefile_cache}->read(statefile => 'cache_' . $options{snmp}->get_hostname() . '_' . $options{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 $overflow = $self->{statefile_cache}->get(name => 'overflow'); + $self->{new_datas}->{overload} = $self->{statefile_cache}->get(name => 'overload') || 0; - if (defined($old_uptime) && $old_uptime < $current_time) { + if (defined($old_uptime) && $options{timeticks} < $old_uptime) { 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)) { - $overflow++; + $overflow >= ($options{timeticks} - ($self->{option_results}->{reboot_window} / 2)) && + $overflow <= ($options{timeticks} + ($self->{option_results}->{reboot_window} / 2))) { + $self->{new_datas}->{overload}++; + } else { + $self->{new_datas}->{overload} = 0; } - - $options{timeticks} += ($overflow * 4294967296); } - $self->{new_datas}->{overflow} = $overflow if (defined($overflow)); - + $options{timeticks} += ($self->{new_datas}->{overload} * 4294967296); + $self->{statefile_cache}->write(data => $self->{new_datas}); return $options{timeticks}; } -sub run { +sub manage_selection { my ($self, %options) = @_; - $self->{snmp} = $options{snmp}; - + + my $oid_sysDescr = '.1.3.6.1.2.1.1.1.0'; + my @oids = (); + if (defined($self->{option_results}->{add_sysdesc})) { + @oids = ($oid_sysDescr); + } + + # To be used first for OS # spsSystemUptime from SILVERPEAK-MGMT-MIB 8.0 my $oid_hrSystemUptime = '.1.3.6.1.4.1.23867.3.1.1.1.5.0'; + # For network equipment or others + my $oid_sysUpTime = '.1.3.6.1.2.1.1.3.0'; my ($result, $value); - + if (defined($self->{option_results}->{force_oid})) { - $result = $self->{snmp}->get_leef(oids => [ $self->{option_results}->{force_oid} ], nothing_quit => 1); - $value = $result->{$self->{option_results}->{force_oid}}; + $result = $options{snmp}->get_leef(oids => [ @oids, $self->{option_results}->{force_oid} ], nothing_quit => 1); + $value = $result->{ $self->{option_results}->{force_oid} }; } else { - $result = $self->{snmp}->get_leef(oids => [ $oid_hrSystemUptime ], nothing_quit => 1); - $value = $result->{$oid_hrSystemUptime}; + $result = $options{snmp}->get_leef(oids => [ @oids, $oid_hrSystemUptime, $oid_sysUpTime ], nothing_quit => 1); + if (defined($result->{$oid_hrSystemUptime})) { + $value = $result->{$oid_hrSystemUptime}; + } else { + $value = $result->{$oid_sysUpTime}; + } } - - $value = $self->check_overflow(timeticks => $value); + + $value = $self->check_overload(timeticks => $value, snmp => $options{snmp}); $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 => $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 => $value, start => 'd'))); - - $self->{output}->display(); - $self->{output}->exit(); + $self->{global} = { uptime => $value, sysdesc => defined($result->{$oid_sysDescr}) ? $result->{$oid_sysDescr} : '-' }; } 1; @@ -137,23 +192,37 @@ Check system uptime. =over 8 -=item B<--warning> +=item B<--warning-uptime> -Threshold warning in seconds. +Threshold warning. -=item B<--critical> +=item B<--critical-uptime> -Threshold critical in seconds. +Threshold critical. + +=item B<--add-sysdesc> + +Display system description. =item B<--force-oid> Can choose your oid (numeric format only). -=item B<--check-overflow> +=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. +=item B<--reboot-window> + +To be used with check-overload option. Time in milliseconds (Default: 5000) +You increase the chance of not missing a reboot if you decrease that value. + +=item B<--unit> + +Select the unit for performance data and thresholds. May be 's' for seconds, 'm' for minutes, +'h' for hours, 'd' for days, 'w' for weeks. Default is seconds + =back =cut diff --git a/centreon-plugins/network/silverpeak/snmp/plugin.pm b/centreon-plugins/network/silverpeak/snmp/plugin.pm index d0e5a1704..7bb5c8e36 100644 --- a/centreon-plugins/network/silverpeak/snmp/plugin.pm +++ b/centreon-plugins/network/silverpeak/snmp/plugin.pm @@ -29,14 +29,13 @@ sub new { my $self = $class->SUPER::new(package => __PACKAGE__, %options); bless $self, $class; - $self->{version} = '1.0'; - %{$self->{modes}} = ( + $self->{modes} = { 'alarms' => 'network::silverpeak::snmp::mode::alarms', 'interfaces' => 'snmp_standard::mode::interfaces', 'list-interfaces' => 'snmp_standard::mode::listinterfaces', 'status' => 'network::silverpeak::snmp::mode::status', - 'uptime' => 'network::silverpeak::snmp::mode::uptime', - ); + 'uptime' => 'network::silverpeak::snmp::mode::uptime' + }; return $self; }