(plugin) network::silverpeak::snmp - better date management (#3644)

This commit is contained in:
qgarnier 2022-05-06 16:21:05 +02:00 committed by GitHub
parent 8feb4c5019
commit 8297b298dd
4 changed files with 209 additions and 127 deletions

View File

@ -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 });
}

View File

@ -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;

View File

@ -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

View File

@ -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;
}