Merge pull request #20 from centreon/master

merge from master
This commit is contained in:
Sims24 2016-07-12 20:02:28 +02:00 committed by GitHub
commit b2fbd6016a
40 changed files with 2932 additions and 891 deletions

View File

@ -157,6 +157,10 @@ Specify https if needed (Default: 'http')
Set path to get Jenkins information Set path to get Jenkins information
=item B <--credentials>
Required to use username/password authentication method
=item B<--username> =item B<--username>
Specify username for API authentification Specify username for API authentification

View File

@ -20,133 +20,14 @@
package centreon::common::emc::navisphere::mode::disk; package centreon::common::emc::navisphere::mode::disk;
sub get_absolute { use base qw(centreon::plugins::templates::counter);
my ($self, %options) = @_;
my $name = $options{instance} . '_' . $options{label};
my $value;
$self->{new_datas}->{$name} = $1;
$self->{old_datas}->{$name} = $self->{statefile_value}->get(name => $name);
return undef if (!defined($self->{old_datas}->{$name}));
# Reward... put to 0
if ($self->{old_datas}->{$name} > $self->{new_datas}->{$name}) {
$self->{old_datas}->{$name} = 0;
}
$value = ($self->{new_datas}->{$name} - $self->{old_datas}->{$name});
return ($value, $value);
}
sub get_bytes_per_seconds {
my ($self, %options) = @_;
my $name = $options{instance} . '_' . $options{label};
my $value;
$self->{new_datas}->{$name} = $1;
if (!defined($self->{old_datas}->{last_timestamp})) {
$self->{old_datas}->{last_timestamp} = $self->{statefile_value}->get(name => 'last_timestamp');
}
$self->{old_datas}->{$name} = $self->{statefile_value}->get(name => $name);
return undef if (!defined($self->{old_datas}->{last_timestamp}) || !defined($self->{old_datas}->{$name}));
# Reward... put to 0
if ($self->{old_datas}->{$name} > $self->{new_datas}->{$name}) {
$self->{old_datas}->{$name} = 0;
}
# At least one second
my $delta_time = $self->{new_datas}->{last_timestamp} - $self->{old_datas}->{last_timestamp};
if ($delta_time <= 0) {
$delta_time = 1;
}
$value = ($self->{new_datas}->{$name} - $self->{old_datas}->{$name}) / $delta_time;
my ($scale_value, $scale_unit) = $self->{perfdata}->change_bytes(value => $value);
return ($value, $scale_value . ' ' . $scale_unit);
}
sub get_utils {
my ($self, %options) = @_;
my $name = $options{instance} . '_' . $options{label};
my $value;
$self->{new_datas}->{$name . '_busy'} = $1;
$self->{new_datas}->{$name . '_idle'} = $2;
$self->{old_datas}->{$name . '_busy'} = $self->{statefile_value}->get(name => $name . '_busy');
$self->{old_datas}->{$name . '_idle'} = $self->{statefile_value}->get(name => $name . '_idle');
return undef if (!defined($self->{old_datas}->{$name . '_busy'}) || !defined($self->{old_datas}->{$name . '_idle'}));
# Reward... put to 0
if ($self->{old_datas}->{$name . '_busy'} > $self->{new_datas}->{$name . '_busy'}) {
$self->{old_datas}->{$name . '_busy'} = 0;
}
if ($self->{old_datas}->{$name . '_idle'} > $self->{new_datas}->{$name . '_idle'}) {
$self->{old_datas}->{$name . '_idle'} = 0;
}
my $total_ticks = ($self->{new_datas}->{$name . '_idle'} - $self->{old_datas}->{$name . '_idle'}) +
($self->{new_datas}->{$name . '_busy'} - $self->{old_datas}->{$name . '_busy'});
if ($total_ticks <= 0) {
return (0, 0);
}
$value = ($self->{new_datas}->{$name . '_busy'} - $self->{old_datas}->{$name . '_busy'}) * 100 / $total_ticks;
return ($value, $value);
}
use base qw(centreon::plugins::mode);
use strict; use strict;
use warnings; use warnings;
use centreon::plugins::statefile;
use centreon::plugins::misc; use centreon::plugins::misc;
use Digest::MD5 qw(md5_hex);
my $maps_counters = { my $instance_mode;
hard_read_errors => { thresholds => {
warning_hard_read_errors => { label => 'warning-hard-read-errors', exit_value => 'warning' },
critical_hard_read_errors => { label => 'critical-hard-read-errors', exit_value => 'critical' },
},
matching => 'Hard Read Errors:\s+(\d+)', closure => \&get_absolute,
output_msg => 'Hard Read Errors : %d', perfdata => '%s',
unit => '',
},
hard_write_errors => { thresholds => {
warning_hard_write_errors => { label => 'warning-hard-write-errors', exit_value => 'warning' },
critical_hard_write_errors => { label => 'critical-hard-write-errors', exit_value => 'critical' },
},
matching => 'Hard Write Errors:\s+(\d+)', closure => \&get_absolute,
output_msg => 'Hard Write Errors : %d', perfdata => '%s',
unit => '',
},
write_io => { thresholds => {
warning_write_io => { label => 'warning-write-io', exit_value => 'warning' },
critical_write_io => { label => 'critical-write-io', exit_value => 'critical' },
},
matching => 'Kbytes Written:\s+(\d+)', closure => \&get_bytes_per_seconds,
output_msg => 'Write I/O : %s', perfdata => '%d',
unit => 'B',
},
read_io => { thresholds => {
warning_read_io => { label => 'warning-read-io', exit_value => 'warning' },
critical_read_io => { label => 'critical-read-io', exit_value => 'critical' },
},
matching => 'Kbytes Read:\s+(\d+)', closure => \&get_bytes_per_seconds,
output_msg => 'Read I/O : %s', perfdata => '%d',
unit => 'B',
},
utils => { thresholds => {
warning_utils => { label => 'warning-utils', exit_value => 'warning' },
critical_utils => { label => 'critical-utils', exit_value => 'critical' },
},
matching => 'Busy Ticks:\s+(\d+).*Idle Ticks:\s+(\d+)', closure => \&get_utils,
output_msg => 'Utils : %.2f %%', perfdata => '%.2f',
unit => '%',
},
};
my @states = ( my @states = (
['^enabled$' , 'OK'], ['^enabled$' , 'OK'],
@ -168,92 +49,147 @@ my @states = (
['^.*$' , 'CRITICAL'], ['^.*$' , 'CRITICAL'],
); );
sub custom_threshold_check {
my ($self, %options) = @_;
foreach (@states) {
if ($self->{result_values}->{state} =~ /$_->[0]/i) {
return $_->[1];
}
}
return 'ok';
}
sub custom_state_output {
my ($self, %options) = @_;
my $msg = sprintf("state is '%s'", $self->{result_values}->{state});
return $msg;
}
sub custom_state_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_utils_calc {
my ($self, %options) = @_;
my $diff_busy = $options{new_datas}->{$self->{instance} . '_busy_ticks'} - $options{old_datas}->{$self->{instance} . '_busy_ticks'};
my $diff_idle = $options{new_datas}->{$self->{instance} . '_idle_ticks'} - $options{old_datas}->{$self->{instance} . '_idle_ticks'};
$self->{result_values}->{utils} = $diff_busy * 100 / ($diff_busy + $diff_idle);
$self->{result_values}->{display} = $options{new_datas}->{$self->{instance} . '_display'};
return 0;
}
sub set_counters {
my ($self, %options) = @_;
$self->{maps_counters_type} = [
{ name => 'disk', type => 1, cb_prefix_output => 'prefix_disk_output', message_multiple => 'All disks are OK', skipped_code => { -10 => 1 } },
];
$self->{maps_counters}->{disk} = [
{ label => 'state', threshold => 0, set => {
key_values => [ { name => 'state' }, { name => 'display' } ],
closure_custom_calc => $self->can('custom_state_calc'),
closure_custom_output => $self->can('custom_state_output'),
closure_custom_perfdata => sub { return 0; },
closure_custom_threshold_check => $self->can('custom_threshold_check'),
}
},
{ label => 'hard-read-errors', set => {
key_values => [ { name => 'hard_read_errors', diff => 1 }, { name => 'display' } ],
output_template => 'Hard Read Errors : %d',
perfdatas => [
{ label => 'hard_read_errors', value => 'hard_read_errors_absolute', template => '%d',
min => 0, label_extra_instance => 1, instance_use => 'display_absolute' },
],
}
},
{ label => 'hard-write-errors', set => {
key_values => [ { name => 'hard_write_errors', diff => 1 }, { name => 'display' } ],
output_template => 'Hard Write Errors : %d',
perfdatas => [
{ label => 'hard_write_errors', value => 'hard_write_errors_absolute', template => '%d',
min => 0, label_extra_instance => 1, instance_use => 'display_absolute' },
],
}
},
{ label => 'read-io', set => {
key_values => [ { name => 'read_io', diff => 1 }, { name => 'display' } ],
output_template => 'Read I/O : %s %s/s',
per_second => 1, output_change_bytes => 1,
perfdatas => [
{ label => 'read_io', value => 'read_io_absolute', template => '%s',
min => 0, unit => 'B/s', label_extra_instance => 1, instance_use => 'display_absolute' },
],
}
},
{ label => 'write-io', set => {
key_values => [ { name => 'write_io', diff => 1 }, { name => 'display' } ],
output_template => 'Write I/O : %s %s/s',
per_second => 1, output_change_bytes => 1,
perfdatas => [
{ label => 'write_io', value => 'write_io_absolute', template => '%s',
min => 0, unit => 'B/s', label_extra_instance => 1, instance_use => 'display_absolute' },
],
}
},
{ label => 'utils', set => {
key_values => [ { name => 'busy_ticks', diff => 1 }, { name => 'idle_ticks', diff => 1 }, { name => 'display' } ],
closure_custom_calc => $self->can('custom_utils_calc'),
output_template => 'Utils : %.2f %%', output_use => 'utils',
perfdatas => [
{ label => 'utils', value => 'utils', template => '%.2f',
min => 0, max => 100, unit => '%%', label_extra_instance => 1, instance_use => 'display' },
],
}
},
];
}
sub prefix_disk_output {
my ($self, %options) = @_;
return "Disk '" . $options{instance_value}->{display} . "' ";
}
sub new { sub new {
my ($class, %options) = @_; my ($class, %options) = @_;
my $self = $class->SUPER::new(package => __PACKAGE__, %options); my $self = $class->SUPER::new(package => __PACKAGE__, %options, statefile => 1);
bless $self, $class; bless $self, $class;
$self->{version} = '1.0'; $self->{version} = '1.0';
$options{options}->add_options(arguments => $options{options}->add_options(arguments =>
{ {
"threshold-overload:s@" => { name => 'threshold_overload' },
"filter-raidgroupid:s" => { name => 'filter_raidgroupid', }, "filter-raidgroupid:s" => { name => 'filter_raidgroupid', },
"filter-disk:s" => { name => 'filter_disk', }, "filter-disk:s" => { name => 'filter_disk', },
}); });
foreach (keys %{$maps_counters}) {
foreach my $name (keys %{$maps_counters->{$_}->{thresholds}}) {
$options{options}->add_options(arguments => {
$maps_counters->{$_}->{thresholds}->{$name}->{label} . ':s' => { name => $name },
});
}
}
$self->{statefile_value} = centreon::plugins::statefile->new(%options);
return $self; return $self;
} }
sub check_options { sub check_options {
my ($self, %options) = @_; my ($self, %options) = @_;
$self->SUPER::init(%options); $self->SUPER::check_options(%options);
foreach (keys %{$maps_counters}) {
foreach my $name (keys %{$maps_counters->{$_}->{thresholds}}) {
if (($self->{perfdata}->threshold_validate(label => $maps_counters->{$_}->{thresholds}->{$name}->{label}, value => $self->{option_results}->{$name})) == 0) {
$self->{output}->add_option_msg(short_msg => "Wrong " . $maps_counters->{$_}->{thresholds}->{$name}->{label} . " threshold '" . $self->{option_results}->{$name} . "'.");
$self->{output}->option_exit();
}
}
}
$self->{overload_th} = {}; $instance_mode = $self;
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 ($filter, $threshold) = ($1, $2);
if ($self->{output}->is_litteral_status(status => $threshold) == 0) {
$self->{output}->add_option_msg(short_msg => "Wrong threshold-overload status '" . $val . "'.");
$self->{output}->option_exit();
}
$self->{overload_th}->{$filter} = $threshold;
}
$self->{statefile_value}->check_options(%options);
} }
sub get_severity { sub manage_selection {
my ($self, %options) = @_; my ($self, %options) = @_;
my $status = 'unknown';
foreach my $entry (@states) { $self->{disk} = {};
if ($options{value} =~ /${$entry}[0]/i) { $self->{cache_name} = "cache_clariion_" . $options{custom}->{hostname} . '_' . $options{custom}->{mode} . '_' .
$status = ${$entry}[1]; (defined($self->{option_results}->{filter_disk}) ? md5_hex($self->{option_results}->{filter_disk}) : md5_hex('all'));
foreach my $filter (keys %{$self->{overload_th}}) {
if (${$entry}[0] =~ /$filter/i) { my $response = $options{custom}->execute_command(cmd => 'getdisk -state -bytrd -bytwrt -hw -hr -busyticks -idleticks -rg');
$status = $self->{overload_th}->{$filter};
last;
}
}
last;
}
}
return $status;
}
sub run {
my ($self, %options) = @_;
my $clariion = $options{custom};
my $response = $clariion->execute_command(cmd => 'getdisk -state -bytrd -bytwrt -hw -hr -busyticks -idleticks -rg');
my ($total_num_disks, $skip_num_disks) = (0, 0);
$self->{new_datas} = {};
$self->{statefile_value}->read(statefile => "cache_clariion_" . $clariion->{hostname} . '_' . $self->{mode});
$self->{new_datas}->{last_timestamp} = time();
#Bus 1 Enclosure 7 Disk 13 #Bus 1 Enclosure 7 Disk 13
#State: Enabled #State: Enabled
@ -274,77 +210,31 @@ sub run {
# First Filters # First Filters
if (defined($self->{option_results}->{filter_disk}) && $self->{option_results}->{filter_disk} ne '' && if (defined($self->{option_results}->{filter_disk}) && $self->{option_results}->{filter_disk} ne '' &&
$disk_instance !~ /$self->{option_results}->{filter_disk}/) { $disk_instance !~ /$self->{option_results}->{filter_disk}/) {
$skip_num_disks++; $self->{output}->output_add(long_msg => "skipping disk '" . $disk_instance . "': no matching filter disk", debug => 1);
$self->{output}->output_add(long_msg => "Skipping disk '" . $disk_instance . "': no matching filter disk");
next; next;
} }
if (defined($self->{option_results}->{filter_raidgroupid}) && $self->{option_results}->{filter_raidgroupid} ne '' && if (defined($self->{option_results}->{filter_raidgroupid}) && $self->{option_results}->{filter_raidgroupid} ne '' &&
$values =~ /^Raid Group ID:\s+(\S+)/mi && $1 !~ /$self->{option_results}->{filter_raidgroupid}/) { $values =~ /^Raid Group ID:\s+(\S+)/mi && $1 !~ /$self->{option_results}->{filter_raidgroupid}/) {
$skip_num_disks++; $self->{output}->output_add(long_msg => "skipping disk '" . $disk_instance . "': no matching filter raid group id", debug => 1);
$self->{output}->output_add(long_msg => "Skipping disk '" . $disk_instance . "': no matching filter raid group id");
next; next;
} }
$total_num_disks++; my $datas = {};
$values =~ /^State:\s+(.*?)(\n|$)/msi; while ($values =~ /^([^\n]*?):(.*?)\n/msgi) {
$datas->{centreon::plugins::misc::trim(lc($1))} = centreon::plugins::misc::trim($2);
my $state = centreon::plugins::misc::trim($1);
my $exit = $self->get_severity(value => $state);
if (!$self->{output}->is_status(litteral => 1, value => $exit, compare => 'ok')) {
$self->{output}->output_add(severity => $exit,
short_msg => sprintf("Disk '%s' state is %s",
$disk_instance, $state));
# Don't check values if in critical/warning
next;
} }
# Work on values. No check if in 'Hot Spare Ready' or 'Unbound' $self->{disk}->{$disk_instance} = {
next if ($state =~ /^(Hot Spare Ready|Unbound)$/i); display => $disk_instance,
state => $datas->{state},
my ($short_msg, $long_msg) = ('', ''); hard_read_errors => $datas->{'hard read errors'},
my @exits; hard_write_errors => $datas->{'hard write errors'},
foreach (keys %{$maps_counters}) { read_io => defined($datas->{'kbytes read'}) ? $datas->{'kbytes read'} * 1024 : undef,
next if ($values !~ /$maps_counters->{$_}->{matching}/msi); write_io => defined($datas->{'kbytes write'}) ? $datas->{'kbytes write'} * 1024 : undef,
my ($value_check, $value_output) = &{$maps_counters->{$_}->{closure}}($self, busy_ticks => $datas->{'busy ticks'},
instance => $disk_instance, label => $_); idle_ticks => $datas->{'idle ticks'},
next if (!defined($value_check)); };
my ($warning, $critical);
foreach my $name (keys %{$maps_counters->{$_}->{thresholds}}) {
my $exit2 = $self->{perfdata}->threshold_check(value => $value_check, threshold => [ { label => $maps_counters->{$_}->{thresholds}->{$name}->{label}, 'exit_litteral' => $maps_counters->{$_}->{thresholds}->{$name}->{exit_value} }]);
$long_msg .= ' ' . sprintf($maps_counters->{$_}->{output_msg}, $value_output);
if (!$self->{output}->is_status(litteral => 1, value => $exit2, compare => 'ok')) {
$short_msg .= ' ' . sprintf($maps_counters->{$_}->{output_msg}, $value_output);
}
push @exits, $exit2;
$warning = $self->{perfdata}->get_perfdata_for_output(label => $maps_counters->{$_}->{thresholds}->{$name}->{label}) if ($maps_counters->{$_}->{thresholds}->{$name}->{exit_value} eq 'warning');
$critical = $self->{perfdata}->get_perfdata_for_output(label => $maps_counters->{$_}->{thresholds}->{$name}->{label}) if ($maps_counters->{$_}->{thresholds}->{$name}->{exit_value} eq 'critical');
}
$self->{output}->perfdata_add(label => $_ . '_' . $disk_instance, unit => $maps_counters->{$_}->{unit},
value => sprintf($maps_counters->{$_}->{perfdata}, $value_check),
warning => $warning,
critical => $critical,
min => 0);
}
$self->{output}->output_add(long_msg => "Disk '$disk_instance':$long_msg");
$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 => "Disk '$disk_instance':$short_msg"
);
}
} }
$self->{output}->output_add(severity => 'OK',
short_msg => sprintf("All %s disks are ok.",
$total_num_disks . '/' . $skip_num_disks)
);
$self->{statefile_value}->write(data => $self->{new_datas});
$self->{output}->display();
$self->{output}->exit();
} }
1; 1;
@ -367,11 +257,6 @@ Can be: 'read-errors', 'write-errors', 'read-io', 'write-io', 'utils'.
Threshold critical. Threshold critical.
Can be: 'read-errors', 'write-errors', 'read-io', 'write-io', 'utils'. Can be: 'read-errors', 'write-errors', 'read-io', 'write-io', 'utils'.
=item B<--threshold-overload>
Set to overload default threshold value.
Example: --threshold-overload='(enabled)=critical'
=item B<--filter-disk> =item B<--filter-disk>
Filter Disk (regexp can be used). Filter Disk (regexp can be used).

View File

@ -0,0 +1,90 @@
#
# Copyright 2016 Centreon (http://www.centreon.com/)
#
# Centreon is a full-fledged industry-strength solution that meets
# the needs in IT infrastructure and application monitoring for
# service performance.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES 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::fastpath::mode::components::fan;
use strict;
use warnings;
my %map_fan_status = (
1 => 'notpresent',
2 => 'operational',
3 => 'failed',
4 => 'powering',
5 => 'nopower',
6 => 'notpowering',
7 => 'incompatible',
);
my $mapping = {
boxServicesFanItemState => { oid => '.1.3.6.1.4.1.674.10895.5000.2.6132.1.1.43.1.6.1.3', map => \%map_fan_status },
boxServicesFanSpeed => { oid => '.1.3.6.1.4.1.674.10895.5000.2.6132.1.1.43.1.6.1.4' },
};
my $oid_boxServicesFansEntry = '.1.3.6.1.4.1.674.10895.5000.2.6132.1.1.43.1.6.1';
sub load {
my ($self) = @_;
push @{$self->{request}}, { oid => $oid_boxServicesFansEntry, begin => $mapping->{boxServicesFanItemState}->{oid} };
}
sub check {
my ($self) = @_;
$self->{output}->output_add(long_msg => "Checking fans");
$self->{components}->{fan} = {name => 'fans', total => 0, skip => 0};
return if ($self->check_filter(section => 'fan'));
my ($exit, $warn, $crit, $checked);
foreach my $oid ($self->{snmp}->oid_lex_sort(keys %{$self->{results}->{$oid_boxServicesFansEntry}})) {
next if ($oid !~ /^$mapping->{boxServicesFanItemState}->{oid}\.(.*)$/);
my $instance = $1;
my $result = $self->{snmp}->map_instance(mapping => $mapping, results => $self->{results}->{$oid_boxServicesFansEntry}, instance => $instance);
next if ($self->check_filter(section => 'fan', instance => $instance));
if ($result->{boxServicesFanItemState} =~ /notPresent/i) {
$self->absent_problem(section => 'fan', instance => $instance);
next;
}
$self->{components}->{fan}->{total}++;
$self->{output}->output_add(long_msg => sprintf("fan '%s' status is '%s' [instance = %s, speed = %s]",
$instance, $result->{boxServicesFanItemState}, $instance, defined($result->{boxServicesFanSpeed}) ? $result->{boxServicesFanSpeed} : 'unknown'));
$exit = $self->get_severity(label => 'default', section => 'fan', value => $result->{boxServicesFanItemState});
if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) {
$self->{output}->output_add(severity => $exit,
short_msg => sprintf("Fan '%s' status is '%s'", $instance, $result->{boxServicesFanItemState}));
next;
}
($exit, $warn, $crit, $checked) = $self->get_severity_numeric(section => 'fan', instance => $instance, value => $result->{boxServicesFanSpeed});
if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) {
$self->{output}->output_add(severity => $exit,
short_msg => sprintf("Fan '%s' is '%s' rpm", $instance, $result->{boxServicesFanSpeed}));
}
$self->{output}->perfdata_add(label => 'fan_' . $instance, unit => 'rpm',
value => $result->{boxServicesFanSpeed},
warning => $warn,
critical => $crit, min => 0
);
}
}
1;

View File

@ -0,0 +1,78 @@
#
# Copyright 2016 Centreon (http://www.centreon.com/)
#
# Centreon is a full-fledged industry-strength solution that meets
# the needs in IT infrastructure and application monitoring for
# service performance.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES 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::fastpath::mode::components::psu;
use strict;
use warnings;
my %map_status = (
1 => 'notpresent',
2 => 'operational',
3 => 'failed',
4 => 'powering',
5 => 'nopower',
6 => 'notpowering',
7 => 'incompatible',
);
my $mapping = {
boxServicesPowSupplyItemState => { oid => '.1.3.6.1.4.1.674.10895.5000.2.6132.1.1.43.1.7.1.3', map => \%map_status },
};
my $oid_boxServicesPowSuppliesEntry = '.1.3.6.1.4.1.674.10895.5000.2.6132.1.1.43.1.7.1';
sub load {
my ($self) = @_;
push @{$self->{request}}, { oid => $oid_boxServicesPowSuppliesEntry, begin => $mapping->{boxServicesPowSupplyItemState}->{oid} };
}
sub check {
my ($self) = @_;
$self->{output}->output_add(long_msg => "Checking power supplies");
$self->{components}->{psu} = {name => 'psus', total => 0, skip => 0};
return if ($self->check_filter(section => 'psu'));
my ($exit, $warn, $crit, $checked);
foreach my $oid ($self->{snmp}->oid_lex_sort(keys %{$self->{results}->{$oid_boxServicesPowSuppliesEntry}})) {
next if ($oid !~ /^$mapping->{boxServicesPowSupplyItemState}->{oid}\.(.*)$/);
my $instance = $1;
my $result = $self->{snmp}->map_instance(mapping => $mapping, results => $self->{results}->{$oid_boxServicesPowSuppliesEntry}, instance => $instance);
next if ($self->check_filter(section => 'psu', instance => $instance));
if ($result->{boxServicesPowSupplyItemState} =~ /notPresent/i) {
$self->absent_problem(section => 'psu', instance => $instance);
next;
}
$self->{components}->{psu}->{total}++;
$self->{output}->output_add(long_msg => sprintf("power supply '%s' status is '%s' [instance = %s]",
$instance, $result->{boxServicesPowSupplyItemState}, $instance));
$exit = $self->get_severity(label => 'default', section => 'psu', value => $result->{boxServicesPowSupplyItemState});
if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) {
$self->{output}->output_add(severity => $exit,
short_msg => sprintf("Power supply '%s' status is '%s'", $instance, $result->{boxServicesPowSupplyItemState}));
next;
}
}
}
1;

View File

@ -0,0 +1,99 @@
#
# Copyright 2016 Centreon (http://www.centreon.com/)
#
# Centreon is a full-fledged industry-strength solution that meets
# the needs in IT infrastructure and application monitoring for
# service performance.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES 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::fastpath::mode::components::temperature;
use strict;
use warnings;
my %map_temp_status = (
0 => 'low',
1 => 'normal',
2 => 'warning',
3 => 'critical',
4 => 'shutdown',
5 => 'notpresent',
6 => 'notoperational',
);
my $mapping1 = {
boxServicesTempSensorState => { oid => '.1.3.6.1.4.1.674.10895.5000.2.6132.1.1.43.1.8.1.3', map => \%map_temp_status },
boxServicesTempSensorTemperature => { oid => '.1.3.6.1.4.1.674.10895.5000.2.6132.1.1.43.1.8.1.4' },
};
my $mapping2 = {
boxServicesTempSensorState => { oid => '.1.3.6.1.4.1.674.10895.5000.2.6132.1.1.43.1.8.1.4', map => \%map_temp_status },
boxServicesTempSensorTemperature => { oid => '.1.3.6.1.4.1.674.10895.5000.2.6132.1.1.43.1.8.1.5' },
};
my $oid_boxServicesTempSensorsEntry = '.1.3.6.1.4.1.674.10895.5000.2.6132.1.1.43.1.8.1';
sub load {
my ($self) = @_;
push @{$self->{request}}, { oid => $oid_boxServicesTempSensorsEntry };
}
sub check {
my ($self) = @_;
$self->{output}->output_add(long_msg => "Checking temperatures");
$self->{components}->{temperature} = {name => 'temperatures', total => 0, skip => 0};
return if ($self->check_filter(section => 'temperature'));
my ($result, $exit, $warn, $crit, $checked);
foreach my $oid ($self->{snmp}->oid_lex_sort(keys %{$self->{results}->{$oid_boxServicesTempSensorsEntry}})) {
next if ($oid !~ /^$mapping2->{boxServicesTempSensorState}->{oid}\.(.*)$/);
my $instance = $1;
if (defined($self->{results}->{$oid_boxServicesTempSensorsEntry}->{$mapping2->{boxServicesTempSensorTemperature}->{oid} . '.' . $instance})) {
$result = $self->{snmp}->map_instance(mapping => $mapping2, results => $self->{results}->{$oid_boxServicesTempSensorsEntry}, instance => $instance);
} else {
$result = $self->{snmp}->map_instance(mapping => $mapping1, results => $self->{results}->{$oid_boxServicesTempSensorsEntry}, instance => $instance);
}
next if ($self->check_filter(section => 'temperature', instance => $instance));
if ($result->{boxServicesTempSensorState} =~ /notPresent/i) {
$self->absent_problem(section => 'temperature', instance => $instance);
next;
}
$self->{components}->{temperature}->{total}++;
$self->{output}->output_add(long_msg => sprintf("temperature '%s' status is '%s' [instance = %s, temperature = %s]",
$instance, $result->{boxServicesTempSensorState}, $instance, defined($result->{boxServicesTempSensorTemperature}) ? $result->{boxServicesTempSensorTemperature} : 'unknown'));
$exit = $self->get_severity(section => 'temperature', value => $result->{boxServicesTempSensorState});
if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) {
$self->{output}->output_add(severity => $exit,
short_msg => sprintf("Temperature '%s' status is '%s'", $instance, $result->{boxServicesTempSensorState}));
next;
}
($exit, $warn, $crit, $checked) = $self->get_severity_numeric(section => 'temperature', instance => $instance, value => $result->{boxServicesTempSensorTemperature});
if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) {
$self->{output}->output_add(severity => $exit,
short_msg => sprintf("Temperature '%s' is '%s' C", $instance, $result->{boxServicesTempSensorTemperature}));
}
$self->{output}->perfdata_add(label => 'temp_' . $instance, unit => 'C',
value => $result->{boxServicesTempSensorTemperature},
warning => $warn,
critical => $crit, min => 0
);
}
}
1;

View File

@ -20,50 +20,50 @@
package centreon::common::fastpath::mode::environment; package centreon::common::fastpath::mode::environment;
use base qw(centreon::plugins::mode); use base qw(centreon::plugins::templates::hardware);
use strict; use strict;
use warnings; use warnings;
my $oid_boxServicesFansEntry = '.1.3.6.1.4.1.674.10895.5000.2.6132.1.1.43.1.6.1'; sub set_system {
my $oid_boxServicesFanItemState = '.1.3.6.1.4.1.674.10895.5000.2.6132.1.1.43.1.6.1.3'; my ($self, %options) = @_;
my $oid_boxServicesFanSpeed = '.1.3.6.1.4.1.674.10895.5000.2.6132.1.1.43.1.6.1.4';
my $oid_boxServicesPowSuppliesEntry = '.1.3.6.1.4.1.674.10895.5000.2.6132.1.1.43.1.7.1'; $self->{regexp_threshold_overload_check_section_option} = '^(fan|psu|temperature)$';
my $oid_boxServicesPowSupplyItemState = '.1.3.6.1.4.1.674.10895.5000.2.6132.1.1.43.1.7.1.3'; $self->{regexp_threshold_numeric_check_section_option} = '^(temperature|fan)$';
my $oid_boxServicesTempSensorsEntry = '.1.3.6.1.4.1.674.10895.5000.2.6132.1.1.43.1.8.1';
my $oid_boxServicesTempSensorTemperature1 = '.1.3.6.1.4.1.674.10895.5000.2.6132.1.1.43.1.8.1.4'; # oid for 6200 series $self->{cb_hook2} = 'snmp_execute';
my $oid_boxServicesTempSensorTemperature2 = '.1.3.6.1.4.1.674.10895.5000.2.6132.1.1.43.1.8.1.5';
$self->{thresholds} = {
default => [
['notpresent', 'OK'],
['operational', 'OK'],
['failed', 'CRITICAL'],
['powering', 'WARNING'],
['nopower', 'CRITICAL'],
['notpowering', 'CRITICAL'],
['incompatible', 'CRITICAL'],
],
temperature => [
['low', 'WARNING'],
['normal', 'OK'],
['warning', 'WARNING'],
['critical', 'CRITICAL'],
['shutdown', 'CRITICAL'],
['notpresent', 'OK'],
['notoperational', 'CRITICAL'],
],
};
$self->{components_path} = 'centreon::common::fastpath::mode::components';
$self->{components_module} = ['fan', 'psu', 'temperature'];
}
my $thresholds = { sub snmp_execute {
psu => [ my ($self, %options) = @_;
['notpresent', 'OK'],
['operational', 'OK'], $self->{snmp} = $options{snmp};
['failed', 'CRITICAL'], $self->{results} = $self->{snmp}->get_multiple_table(oids => $self->{request});
['powering', 'WARNING'], }
['nopower', 'CRITICAL'],
['notpowering', 'CRITICAL'],
['incompatible', 'CRITICAL'],
],
fan => [
['notpresent', 'OK'],
['operational', 'OK'],
['failed', 'CRITICAL'],
['powering', 'WARNING'],
['nopower', 'CRITICAL'],
['notpowering', 'CRITICAL'],
['incompatible', 'CRITICAL'],
],
};
my %map_states = (
1 => 'notpresent',
2 => 'operational',
3 => 'failed',
4 => 'powering',
5 => 'nopower',
6 => 'notpowering',
7 => 'incompatible',
);
sub new { sub new {
my ($class, %options) = @_; my ($class, %options) = @_;
@ -73,291 +73,35 @@ sub new {
$self->{version} = '1.0'; $self->{version} = '1.0';
$options{options}->add_options(arguments => $options{options}->add_options(arguments =>
{ {
"exclude:s" => { name => 'exclude' },
"component:s" => { name => 'component', default => 'all' },
"absent-problem:s" => { name => 'absent' },
"no-component:s" => { name => 'no_component' },
"threshold-overload:s@" => { name => 'threshold_overload' },
"warning-temperature:s" => { name => 'warning_temperature' },
"critical-temperature:s" => { name => 'critical_temperature' },
}); });
$self->{components} = {};
$self->{no_components} = undef;
return $self; return $self;
} }
sub check_options {
my ($self, %options) = @_;
$self->SUPER::init(%options);
if (($self->{perfdata}->threshold_validate(label => 'warning_temperature', value => $self->{option_results}->{warning_temperature})) == 0) {
$self->{output}->add_option_msg(short_msg => "Wrong warning temperature threshold '" . $self->{option_results}->{warning_temperature} . "'.");
$self->{output}->option_exit();
}
if (($self->{perfdata}->threshold_validate(label => 'critical_temperature', value => $self->{option_results}->{critical_temperature})) == 0) {
$self->{output}->add_option_msg(short_msg => "Wrong critical temperature threshold '" . $self->{option_results}->{critical_temperature} . "'.");
$self->{output}->option_exit();
}
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->{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) = @_;
# $options{snmp} = snmp object
$self->{snmp} = $options{snmp};
# There is a bug with get_leef and snmpv1.
$self->{results} = $self->{snmp}->get_multiple_table(oids => [
{ oid => $oid_boxServicesFansEntry },
{ oid => $oid_boxServicesPowSuppliesEntry },
{ oid => $oid_boxServicesTempSensorsEntry },
]);
if ($self->{option_results}->{component} eq 'all') {
$self->check_fan();
$self->check_psu();
$self->check_temperature();
} elsif ($self->{option_results}->{component} eq 'fan') {
$self->check_fan();
} elsif ($self->{option_results}->{component} eq 'psu') {
$self->check_psu();
} elsif ($self->{option_results}->{component} eq 'temperature') {
$self->check_temperature();
} else {
$self->{output}->add_option_msg(short_msg => "Wrong option. Cannot find component '" . $self->{option_results}->{component} . "'.");
$self->{output}->option_exit();
}
my $total_components = 0;
my $display_by_component = '';
my $display_by_component_append = '';
foreach my $comp (sort(keys %{$self->{components}})) {
# Skipping short msg when no components
next if ($self->{components}->{$comp}->{total} == 0 && $self->{components}->{$comp}->{skip} == 0);
$total_components += $self->{components}->{$comp}->{total} + $self->{components}->{$comp}->{skip};
my $count_by_components = $self->{components}->{$comp}->{total} + $self->{components}->{$comp}->{skip};
$display_by_component .= $display_by_component_append . $self->{components}->{$comp}->{total} . '/' . $count_by_components . ' ' . $self->{components}->{$comp}->{name};
$display_by_component_append = ', ';
}
$self->{output}->output_add(severity => 'OK',
short_msg => sprintf("All %s components are ok [%s].",
$total_components,
$display_by_component)
);
if (defined($self->{option_results}->{no_component}) && $total_components == 0) {
$self->{output}->output_add(severity => $self->{no_components},
short_msg => 'No components are checked.');
}
$self->{output}->display();
$self->{output}->exit();
}
sub check_exclude {
my ($self, %options) = @_;
if (defined($options{instance})) {
if (defined($self->{option_results}->{exclude}) && $self->{option_results}->{exclude} =~ /(^|\s|,)${options{section}}[^,]*#\Q$options{instance}\E#/) {
$self->{components}->{$options{section}}->{skip}++;
$self->{output}->output_add(long_msg => sprintf("Skipping $options{section} section $options{instance} instance."));
return 1;
}
} elsif (defined($self->{option_results}->{exclude}) && $self->{option_results}->{exclude} =~ /(^|\s|,)$options{section}(\s|,|$)/) {
$self->{output}->output_add(long_msg => sprintf("Skipping $options{section} section."));
return 1;
}
return 0;
}
sub absent_problem {
my ($self, %options) = @_;
if (defined($self->{option_results}->{absent}) &&
$self->{option_results}->{absent} =~ /(^|\s|,)($options{section}(\s*,|$)|${options{section}}[^,]*#\Q$options{instance}\E#)/) {
$self->{output}->output_add(severity => 'CRITICAL',
short_msg => sprintf("Component '%s' instance '%s' is not present",
$options{section}, $options{instance}));
}
$self->{output}->output_add(long_msg => sprintf("Skipping $options{section} section $options{instance} instance (not present)"));
$self->{components}->{$options{section}}->{skip}++;
return 1;
}
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 check_fan {
my ($self) = @_;
$self->{output}->output_add(long_msg => "Checking fans");
$self->{components}->{fan} = {name => 'fans', total => 0, skip => 0};
return if ($self->check_exclude(section => 'fan'));
foreach my $oid ($self->{snmp}->oid_lex_sort(keys %{$self->{results}->{$oid_boxServicesFansEntry}})) {
next if ($oid !~ /^$oid_boxServicesFanItemState\.(.*)/);
my $instance = $1;
my $fan_state = $self->{results}->{$oid_boxServicesFansEntry}->{$oid_boxServicesFanItemState . '.' . $instance};
my $fan_speed = $self->{results}->{$oid_boxServicesFansEntry}->{$oid_boxServicesFanSpeed . '.' . $instance};
next if ($self->check_exclude(section => 'fan', instance => $instance));
next if ($map_states{$fan_state} eq 'notPresent' &&
$self->absent_problem(section => 'fan', instance => $instance));
$self->{components}->{fan}->{total}++;
$self->{output}->output_add(long_msg => sprintf("Fan '%s' state is %s.",
$instance, $map_states{$fan_state}));
my $exit = $self->get_severity(section => 'fan', value => $map_states{$fan_state});
if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) {
$self->{output}->output_add(severity => $exit,
short_msg => sprintf("Fan '%s' state is %s.", $instance, $map_states{$fan_state}));
}
$self->{output}->perfdata_add(label => "Fan_$instance",
unit => 'rpm',
value => $fan_speed,
min => 0);
}
}
sub check_psu {
my ($self) = @_;
$self->{output}->output_add(long_msg => "Checking power supplies");
$self->{components}->{psu} = {name => 'psus', total => 0, skip => 0};
return if ($self->check_exclude(section => 'psu'));
foreach my $oid ($self->{snmp}->oid_lex_sort(keys %{$self->{results}->{$oid_boxServicesPowSuppliesEntry}})) {
next if ($oid !~ /^$oid_boxServicesPowSupplyItemState\.(.*)/);
my $instance = $1;
my $psu_state = $self->{results}->{$oid_boxServicesPowSuppliesEntry}->{$oid_boxServicesPowSupplyItemState . '.' . $instance};
next if ($self->check_exclude(section => 'psu', instance => $instance));
next if ($map_states{$psu_state} eq 'notPresent' &&
$self->absent_problem(section => 'psu', instance => $instance));
$self->{components}->{psu}->{total}++;
$self->{output}->output_add(long_msg => sprintf("Power supply '%s' state is %s.",
$instance, $map_states{$psu_state}));
my $exit = $self->get_severity(section => 'psu', value => $map_states{$psu_state});
if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) {
$self->{output}->output_add(severity => $exit,
short_msg => sprintf("Power supply '%s' state is %s.", $instance, $map_states{$psu_state}));
}
}
}
sub check_temperature {
my ($self) = @_;
$self->{output}->output_add(long_msg => "Checking temperature sensors");
$self->{components}->{temperature} = {name => 'temperature sensors', total => 0, skip => 0};
return if ($self->check_exclude(section => 'temperature'));
foreach my $oid ($self->{snmp}->oid_lex_sort(keys %{$self->{results}->{$oid_boxServicesTempSensorsEntry}})) {
my $instance;
if ($oid =~ /^$oid_boxServicesTempSensorTemperature1\.(.*)/) {
$instance = $1;
} elsif ($oid =~ /^$oid_boxServicesTempSensorTemperature2\.(.*)\.(.*)/) {
$instance = $1 . '.' . $2;
} else {
next;
}
my $temperature;
if (defined($self->{results}->{$oid_boxServicesTempSensorsEntry}->{$oid_boxServicesTempSensorTemperature1 . '.' . $instance})) {
$temperature = $self->{results}->{$oid_boxServicesTempSensorsEntry}->{$oid_boxServicesTempSensorTemperature1 . '.' . $instance};
} else {
$temperature = $self->{results}->{$oid_boxServicesTempSensorsEntry}->{$oid_boxServicesTempSensorTemperature2 . '.' . $instance};
}
next if ($self->check_exclude(section => 'temperature', instance => $instance));
$instance =~ s/(\d+)\.//;
$self->{components}->{temperature}->{total}++;
$self->{output}->output_add(long_msg => sprintf("Temperature sensor '%s' : %sc.",
$instance, $temperature));
my $exit = $self->{perfdata}->threshold_check(value => $temperature, threshold => [ { label => 'critical_temperature', 'exit_litteral' => 'critical' }, { label => 'warning_temperature', exit_litteral => 'warning' } ]);
if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) {
$self->{output}->output_add(severity => $exit,
short_msg => sprintf("Temperature sensor '%s' : %sc.", $instance, $temperature));
}
$self->{output}->perfdata_add(label => "Temperature_$instance",
unit => 'c',
value => $temperature);
}
}
1; 1;
__END__ __END__
=head1 MODE =head1 MODE
Check environment (FASTPATH-BOXSERVICES-MIB) (Fans, Power Supplies, Temperature). Check Hardware (Fans, Power Supplies, Temperature) (FASTPATH-BOXSERVICES-MIB).
=over 8 =over 8
=item B<--component> =item B<--component>
Which component to check (Default: 'all'). Which component to check (Default: '.*').
Can be: 'psu', 'fan', 'temperature'. Can be: 'fan', 'psu', 'temperature'.
=item B<--exclude> =item B<--filter>
Exclude some parts (comma seperated list) (Example: --exclude=psu) Exclude some parts (comma seperated list) (Example: --filter=fan --filter=psu)
Can also exclude specific instance: --exclude='fan#fan2_unit1#' Can also exclude specific instance: --filter=fan,1
=item B<--absent-problem> =item B<--absent-problem>
Return an error if an entity is not 'present' (default is skipping) (comma seperated list) Return an error if an entity is not 'present' (default is skipping) (comma seperated list)
Can be specific or global: --absent-problem=psu Can be specific or global: --absent-problem=psu,1
=item B<--no-component> =item B<--no-component>
@ -366,18 +110,20 @@ If total (with skipped) is 0. (Default: 'critical' returns).
=item B<--threshold-overload> =item B<--threshold-overload>
Set to overload default threshold values (syntax: section,status,regexp) Set to overload default threshold values (syntax: section,[instance,]status,regexp)
It used before default thresholds (order stays). It used before default thresholds (order stays).
Example: --threshold-overload='psu,CRITICAL,^(?!(normal)$)' Example: --threshold-overload='psu,CRITICAL,^(?!(operational)$)'
=item B<--warning-temperature> =item B<--warning>
Warning threshold for temperature in celsius. Set warning threshold for 'temperature', 'fan' (syntax: type,regexp,threshold)
Example: --warning='fan,1.1,5000'
=item B<--critical-temperature> =item B<--critical>
Critical threshold for temperature in celsius. Set critical threshold for 'temperature', 'fan' (syntax: type,regexp,threshold)
Example: --critical='fan,.*,2000'
=back =back
=cut =cut

View File

@ -30,7 +30,7 @@ use Pod::Find qw(pod_where);
my %handlers = (DIE => {}); my %handlers = (DIE => {});
my $global_version = 20160524; my $global_version = 20160627;
my $alternative_fatpacker = 0; my $alternative_fatpacker = 0;
sub new { sub new {

View File

@ -679,7 +679,7 @@ sub check_options {
if (!defined($options{option_results}->{snmp_security_name})) { if (!defined($options{option_results}->{snmp_security_name})) {
$self->{output}->add_option_msg(short_msg => "Missing paramater Security Name."); $self->{output}->add_option_msg(short_msg => "Missing parameter Security Name.");
$self->{output}->option_exit(); $self->{output}->option_exit();
} }

View File

@ -1,3 +1,15 @@
2016-06-27 Quentin Garnier <qgarnier@centreon.com>
* Update FAQ: build a standalone perl script
* Plugin added: to check Lenovo S Series (#412)
* Plugin added: to check Digi AnywhereUSB
* Mode added: [netasq] 'ha-nodes'
* Mode removed: [netasq] 'ha-status'
* Fix: [dell n4000]{environment} wrong temperature (#397)
* Fix: [netapp]{cache-age} not working (#422)
* Fix: [cisco wlc]{ap-users} wrong total
* Fix: [tomcat]{memory} problem with java 8
* Fix: [netapp]{filesys} no values (#415)
2016-05-24 Quentin Garnier <qgarnier@centreon.com> 2016-05-24 Quentin Garnier <qgarnier@centreon.com>
* Can use '/' instead '::' for plugin option (#380) * Can use '/' instead '::' for plugin option (#380)
* Mode added: [pacemaker] 'constraints' * Mode added: [pacemaker] 'constraints'

View File

@ -20,50 +20,129 @@
package database::mssql::mode::databasessize; package database::mssql::mode::databasessize;
use base qw(centreon::plugins::mode); use base qw(centreon::plugins::templates::counter);
use strict; use strict;
use warnings; use warnings;
my $instance_mode;
sub set_counters {
my ($self, %options) = @_;
$self->{maps_counters_type} = [
{ name => 'database', type => 1, cb_prefix_output => 'prefix_database_output', message_multiple => 'All databases are OK' },
];
$self->{maps_counters}->{database} = [
{ label => 'database', set => {
key_values => [ { name => 'prct_used' }, { name => 'used' }, { name => 'free' }, { name => 'total' }, { name => 'display' } ],
closure_custom_calc => \&custom_usage_calc,
closure_custom_output => \&custom_usage_output,
closure_custom_perfdata => \&custom_usage_perfdata,
closure_custom_threshold_check => \&custom_usage_threshold,
}
},
];
}
sub custom_usage_perfdata {
my ($self, %options) = @_;
my $label = 'db_' . $self->{result_values}->{display} . '_used';
my $value_perf = $self->{result_values}->{used};
if (defined($instance_mode->{option_results}->{free})) {
$label = 'db_' . $self->{result_values}->{display} . '_free';
$value_perf = $self->{result_values}->{free};
}
my $extra_label = '';
$extra_label = '_' . $self->{result_values}->{display} if (!defined($options{extra_instance}) || $options{extra_instance} != 0);
my %total_options = ();
if ($instance_mode->{option_results}->{units} eq '%') {
$total_options{total} = $self->{result_values}->{total};
$total_options{cast_int} = 1;
}
$self->{output}->perfdata_add(label => $label . $extra_label, unit => 'B',
value => $value_perf,
warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{label}, %total_options),
critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{label}, %total_options),
min => 0, max => $self->{result_values}->{total});
}
sub custom_usage_threshold {
my ($self, %options) = @_;
my ($exit, $threshold_value);
$threshold_value = $self->{result_values}->{used};
$threshold_value = $self->{result_values}->{free} if (defined($instance_mode->{option_results}->{free}));
if ($instance_mode->{option_results}->{units} eq '%') {
$threshold_value = $self->{result_values}->{prct_used};
$threshold_value = $self->{result_values}->{prct_free} if (defined($instance_mode->{option_results}->{free}));
}
$exit = $self->{perfdata}->threshold_check(value => $threshold_value, threshold => [ { label => 'critical-' . $self->{label}, exit_litteral => 'critical' }, { label => 'warning-'. $self->{label}, exit_litteral => 'warning' } ]);
return $exit;
}
sub custom_usage_output {
my ($self, %options) = @_;
my ($total_size_value, $total_size_unit) = $self->{perfdata}->change_bytes(value => $self->{result_values}->{total});
my ($total_used_value, $total_used_unit) = $self->{perfdata}->change_bytes(value => $self->{result_values}->{used});
my ($total_free_value, $total_free_unit) = $self->{perfdata}->change_bytes(value => $self->{result_values}->{free});
my $msg = sprintf("Total: %s Used: %s (%.2f%%) Free: %s (%.2f%%)",
$total_size_value . " " . $total_size_unit,
$total_used_value . " " . $total_used_unit, $self->{result_values}->{prct_used},
$total_free_value . " " . $total_free_unit, $self->{result_values}->{prct_free});
return $msg;
}
sub custom_usage_calc {
my ($self, %options) = @_;
$self->{result_values}->{display} = $options{new_datas}->{$self->{instance} . '_display'};
$self->{result_values}->{total} = $options{new_datas}->{$self->{instance} . '_total'};
$self->{result_values}->{used} = $options{new_datas}->{$self->{instance} . '_used'};
$self->{result_values}->{prct_used} = $options{new_datas}->{$self->{instance} . '_prct_used'};
$self->{result_values}->{free} = $options{new_datas}->{$self->{instance} . '_free'};
$self->{result_values}->{prct_free} = 100 - $self->{result_values}->{prct_used};
return 0;
}
sub new { sub new {
my ($class, %options) = @_; my ($class, %options) = @_;
my $self = $class->SUPER::new(package => __PACKAGE__, %options); my $self = $class->SUPER::new(package => __PACKAGE__, %options);
bless $self, $class; bless $self, $class;
$self->{version} = '1.0'; $self->{version} = '1.0';
$options{options}->add_options(arguments => $options{options}->add_options(arguments =>
{ {
"warning:s" => { name => 'warning', }, "filter-database:s" => { name => 'filter_database' },
"critical:s" => { name => 'critical', }, "units:s" => { name => 'units', default => '%' },
"filter:s" => { name => 'filter', }, "free" => { name => 'free' },
"free" => { name => 'free', },
}); });
return $self; return $self;
} }
sub prefix_database_output {
my ($self, %options) = @_;
return "Database '" . $options{instance_value}->{display} . "' ";
}
sub check_options { sub check_options {
my ($self, %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) { $instance_mode = $self;
$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 { sub manage_selection {
my ($self, %options) = @_; my ($self, %options) = @_;
# $options{sql} = sqlmode object # $options{sql} = sqlmode object
$self->{sql} = $options{sql}; $self->{sql} = $options{sql};
$self->{output}->output_add(severity => 'OK',
short_msg => "All databases are ok.");
$self->{sql}->connect(); $self->{sql}->connect();
$self->{sql}->query(query => q{DBCC SQLPERF(LOGSPACE)}); $self->{sql}->query(query => q{DBCC SQLPERF(LOGSPACE)});
@ -71,7 +150,7 @@ sub run {
my @databases_selected; my @databases_selected;
foreach my $row (@$result) { foreach my $row (@$result) {
next if (defined($self->{option_results}->{filter}) && $$row[0] !~ /$self->{option_results}->{filter}/); next if (defined($self->{option_results}->{filter_database}) && $$row[0] !~ /$self->{option_results}->{filter_database}/);
push @databases_selected, $$row[0]; push @databases_selected, $$row[0];
} }
@ -83,44 +162,17 @@ sub run {
my $size = convert_bytes($size_brut); my $size = convert_bytes($size_brut);
my $free_brut = $$row[2]; my $free_brut = $$row[2];
my $free = convert_bytes($free_brut); my $free = convert_bytes($free_brut);
my $use = $size - $free; my $used = $size - $free;
my $percent_use = ($use / $size) * 100; my $percent_used = ($used / $size) * 100;
my $percent_free = 100 - $percent_use;
my ($use_value, $use_unit) = $self->{perfdata}->change_bytes(value => $use); $self->{database}->{$database} = { used => $used,
$self->{output}->output_add(long_msg => sprintf("DB '%s' Size: %s Used: %.2f %s (%.2f%%) Free: %s (%.2f%%)", $database, $size_brut, $use_value, $use_unit, $percent_use, $free_brut, $percent_free)); free => $free,
if (defined($self->{option_results}->{free})) { total => $size,
my $exit_code = $self->{perfdata}->threshold_check(value => $percent_free, threshold => [ { label => 'critical', exit_litteral => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]); prct_used => $percent_used,
if (!$self->{output}->is_status(value => $exit_code, compare => 'ok', litteral => 1)) { display => lc $database };
$self->{output}->output_add(severity => $exit_code,
short_msg => sprintf("DB '%s' Size: %s Free: %s (%.2f%%)", $database, $size_brut, $free_brut, $percent_use));
}
$self->{output}->perfdata_add(label => sprintf("db_%s_free",$database),
unit => 'B',
value => int($free),
warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning', total => $size, cast_int => 1),
critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical', total => $size, cast_int => 1),
min => 0,
max => int($size));
} else {
my $exit_code = $self->{perfdata}->threshold_check(value => $percent_use, threshold => [ { label => 'critical', 'exit_litteral' => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]);
if (!$self->{output}->is_status(value => $exit_code, compare => 'ok', litteral => 1)) {
$self->{output}->output_add(severity => $exit_code,
short_msg => sprintf("DB '%s' Size: %s Used: %.2f %s (%.2f%%)", $database, $size_brut, $use_value, $use_unit, $percent_use));
}
$self->{output}->perfdata_add(label => sprintf("db_%s_used",$database),
unit => 'B',
value => int($use),
warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning', total => $size, cast_int => 1),
critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical', total => $size, cast_int => 1),
min => 0,
max => int($size));
}
} }
} }
$self->{output}->display();
$self->{output}->exit();
} }
sub convert_bytes { sub convert_bytes {
@ -144,25 +196,29 @@ __END__
=head1 MODE =head1 MODE
Check MSSQL databases size. Check MSSQL Database usage
=over 8 =over 8
=item B<--warning> =item B<--warning-database>
Threshold warning in percent used. Threshold warning.
=item B<--critical> =item B<--critical-database>
Threshold critical in percent used. Threshold critical.
=item B<--filter> =item B<--filter-database>
Filter database. Filter database by name. Can be a regex
=item B<--units>
Default is '%', can be 'B'
=item B<--free> =item B<--free>
Check free space instead of used space. Perfdata show free space
=back =back

View File

@ -112,9 +112,6 @@ sub run {
my $label = $_; my $label = $_;
$label =~ s/ /-/g; $label =~ s/ /-/g;
foreach my $row (@$result) { foreach my $row (@$result) {
next if (defined($already_checked->{$$row[0]}));
if (defined($self->{option_results}->{incremental_level})) { if (defined($self->{option_results}->{incremental_level})) {
# db incr with incremental level 0 = DB FULL # db incr with incremental level 0 = DB FULL
if (/db full/ && $$row[0] =~ /db incr/i && defined($$row[2]) && $$row[2] == 0) { # it's a full. we get if (/db full/ && $$row[0] =~ /db incr/i && defined($$row[2]) && $$row[2] == 0) { # it's a full. we get
@ -123,11 +120,14 @@ sub run {
next if (/db incr/ && $$row[0] =~ /db incr/i && defined($$row[2]) && $$row[2] == 0); # it's a full. we skip. next if (/db incr/ && $$row[0] =~ /db incr/i && defined($$row[2]) && $$row[2] == 0); # it's a full. we skip.
next if ($$row[0] !~ /$_/i); next if ($$row[0] !~ /$_/i);
} }
$already_checked->{$$row[0]} = 1;
} else { } else {
next if ($$row[0] !~ /$_/i); next if ($$row[0] !~ /$_/i);
} }
next if (defined($already_checked->{$$row[0]}));
$already_checked->{$$row[0]} = 1;
$count_backups++; $count_backups++;
$executed = 1; $executed = 1;

View File

@ -509,6 +509,8 @@ How can i check the plugin version ?
You can check the version of plugins and modes with option ``--version``: You can check the version of plugins and modes with option ``--version``:
:: ::
$ perl centreon_plugins.pl --version
Global Version: 20160524
$ perl centreon_plugins.pl --plugin=os::linux::snmp::plugin --version $ perl centreon_plugins.pl --plugin=os::linux::snmp::plugin --version
Plugin Version: 0.1 Plugin Version: 0.1
$ perl centreon_plugins.pl --plugin=os::linux::snmp::plugin --mode=storage --version $ perl centreon_plugins.pl --plugin=os::linux::snmp::plugin --mode=storage --version
@ -521,6 +523,58 @@ For example, we want to execute the mode only if the version >= 2.x:
$ perl centreon_plugins.pl --plugin=os::linux::snmp::plugin --mode=storage --hostname=127.0.0.1 --snmp-version=2c --snmp-community=public --verbose --mode-version='2.x' $ perl centreon_plugins.pl --plugin=os::linux::snmp::plugin --mode=storage --hostname=127.0.0.1 --snmp-version=2c --snmp-community=public --verbose --mode-version='2.x'
UNKNOWN: Not good version for plugin mode. Excepted at least: 2.x. Get: 1.0 UNKNOWN: Not good version for plugin mode. Excepted at least: 2.x. Get: 1.0
-------------------------------------
Can i have one standalone Perl file ?
-------------------------------------
We have done some tests and it will cost around 4% more of execution time. We are going to create a standalone Linux SNMP plugin.
Download the Perl module ``App::FatPacker`` on metacpan:
::
# tar zxvf App-FatPacker-0.010005.tar.gz
# cd App-FatPacker-0.010005
# perl Makefile.PL && make && make install
Create a directory to build it:
::
# mkdir -p build/plugin
# cd build
Clone ``centreon-plugins``:
::
# git clone https://github.com/centreon/centreon-plugins.git
``fatpack`` includes ``pm`` files under the directory ``lib``:
::
# mkdir plugin/lib && cd centreon-plugins
Copy the common files for all plugins:
::
# cp -R --parent centreon/plugins/{misc,mode,options,output,perfdata,script,statefile,values}.pm centreon/plugins/templates/ centreon/plugins/alternative/ ../plugin/lib/
# cp centreon_plugins.pl ../plugin
# sed -i 's/alternative_fatpacker = 0/alternative_fatpacker = 1/' ../plugin/lib/centreon/plugins/script.pm
Copy files for Linux SNMP plugin:
::
# cp -R --parent centreon/plugins/{script_snmp,snmp}.pm os/linux/snmp/ snmp_standard/mode/{cpu,cpudetailed,diskio,diskusage,inodes,interfaces,loadaverage,listdiskspath,listinterfaces,liststorages,memory,processcount,storage,swap,ntp,tcpcon,uptime}.pm ../plugin/lib/
Build the standalone Perl file:
::
# cd ../plugin
# fatpack file centreon_plugins.pl > centreon_linux_snmp.pl
The plugin works in the same way:
::
# perl centreon_linux_snmp.pl --plugin os::linux::snmp::plugin --mode=processcount --snmp-community public --snmp-version 2c --hostname=127.0.0.1 --process-name='' --process-status='' --process-args=''
*************** ***************
Troubleshooting Troubleshooting
*************** ***************

View File

@ -509,6 +509,8 @@ Comment puis-je vérifier la version du plugin ?
Vous pouvez vérifier la version des plugins et des modes avec l'option ``--version`` : Vous pouvez vérifier la version des plugins et des modes avec l'option ``--version`` :
:: ::
$ perl centreon_plugins.pl --version
Global Version: 20160524
$ perl centreon_plugins.pl --plugin=os::linux::snmp::plugin --version $ perl centreon_plugins.pl --plugin=os::linux::snmp::plugin --version
Plugin Version: 0.1 Plugin Version: 0.1
$ perl centreon_plugins.pl --plugin=os::linux::snmp::plugin --mode=storage --version $ perl centreon_plugins.pl --plugin=os::linux::snmp::plugin --mode=storage --version
@ -521,6 +523,59 @@ Par exemple, nous voulons exécuter le mode seulement si sa version >= 2.x :
$ perl centreon_plugins.pl --plugin=os::linux::snmp::plugin --mode=storage --hostname=127.0.0.1 --snmp-version=2c --snmp-community=public --verbose --mode-version='2.x' $ perl centreon_plugins.pl --plugin=os::linux::snmp::plugin --mode=storage --hostname=127.0.0.1 --snmp-version=2c --snmp-community=public --verbose --mode-version='2.x'
UNKNOWN: Not good version for plugin mode. Excepted at least: 2.x. Get: 1.0 UNKNOWN: Not good version for plugin mode. Excepted at least: 2.x. Get: 1.0
--------------------------------------------
Comment puis-je avoir un seul fichier Perl ?
--------------------------------------------
Nous avons réalisé des tests et le temps d'éxecution est augmenté d'environ 4%. Nous allons créer un fichier unique pour la sonde Linux SNMP.
Télécharger le module Perl ``App::FatPacker`` sur metacpan:
::
# tar zxvf App-FatPacker-0.010005.tar.gz
# cd App-FatPacker-0.010005
# perl Makefile.PL && make && make install
Créer un répertoire de construction:
::
# mkdir -p build/plugin
# cd build
Cloner ``centreon-plugins``:
::
# git clone https://github.com/centreon/centreon-plugins.git
``fatpack`` inclut les fichiers ``pm`` présent dans le répertoire ``lib``:
::
# mkdir plugin/lib && cd centreon-plugins
Copier les fichiers communs à l'ensemble des sondes:
::
# cp -R --parent centreon/plugins/{misc,mode,options,output,perfdata,script,statefile,values}.pm centreon/plugins/templates/ centreon/plugins/alternative/ ../plugin/lib/
# cp centreon_plugins.pl ../plugin
# sed -i 's/alternative_fatpacker = 0/alternative_fatpacker = 1/' ../plugin/lib/centreon/plugins/script.pm
Copier les fichiers pour la sonde Linux SNMP:
::
# cp -R --parent centreon/plugins/{script_snmp,snmp}.pm os/linux/snmp/ snmp_standard/mode/{cpu,cpudetailed,diskio,diskusage,inodes,interfaces,loadaverage,listdiskspath,listinterfaces,liststorages,memory,processcount,storage,swap,ntp,tcpcon,uptime}.pm ../plugin/lib/
Construire le fichier Perl unique:
::
# cd ../plugin
# fatpack file centreon_plugins.pl > centreon_linux_snmp.pl
La sonde fonctionne de la même façon:
::
# perl centreon_linux_snmp.pl --plugin os::linux::snmp::plugin --mode=processcount --snmp-community public --snmp-version 2c --hostname=127.0.0.1 --process-name='' --process-status='' --process-args=''
********* *********
Dépannage Dépannage
********* *********

View File

@ -20,137 +20,112 @@
package network::bluecoat::snmp::mode::clientrequests; package network::bluecoat::snmp::mode::clientrequests;
use base qw(centreon::plugins::mode); use base qw(centreon::plugins::templates::counter);
use strict; use strict;
use warnings; use warnings;
use centreon::plugins::statefile; use Digest::MD5 qw(md5_hex);
sub set_counters {
my ($self, %options) = @_;
$self->{maps_counters_type} = [
{ name => 'global', type => 0, cb_prefix_output => 'prefix_output' },
];
$self->{maps_counters}->{global} = [
{ label => 'hits', set => {
key_values => [ { name => 'client_http_requests', diff => 1 }, { name => 'client_http_hits', diff => 1 } ],
closure_custom_calc => $self->can('custom_data_calc'), closure_custom_calc_extra_options => { label_ref => 'hits' },
output_template => 'Hits = %.2f %%', output_use => 'hits_prct',
perfdatas => [
{ label => 'hits', value => 'hits_prct', template => '%.2f', min => 0, max => 100, unit => '%' },
],
}
},
{ label => 'partial-hits', set => {
key_values => [ { name => 'client_http_requests', diff => 1 }, { name => 'client_http_partial_hits', diff => 1 } ],
closure_custom_calc => $self->can('custom_data_calc'), closure_custom_calc_extra_options => { label_ref => 'partial_hits' },
output_template => 'Partial Hits = %.2f %%', output_use => 'partial_hits_prct',
perfdatas => [
{ label => 'partial_hits', value => 'partial_hits_prct', template => '%.2f', min => 0, max => 100, unit => '%' },
],
}
},
{ label => 'misses', set => {
key_values => [ { name => 'client_http_requests', diff => 1 }, { name => 'client_http_misses', diff => 1 } ],
closure_custom_calc => $self->can('custom_data_calc'), closure_custom_calc_extra_options => { label_ref => 'misses' },
output_template => 'Misses = %.2f %%', output_use => 'misses_prct',
perfdatas => [
{ label => 'misses', value => 'misses_prct', template => '%.2f', min => 0, max => 100, unit => '%' },
],
}
},
{ label => 'errors', set => {
key_values => [ { name => 'client_http_requests', diff => 1 }, { name => 'client_http_errors', diff => 1 } ],
closure_custom_calc => $self->can('custom_data_calc'), closure_custom_calc_extra_options => { label_ref => 'errors' },
output_template => 'Errors = %.2f %%', output_use => 'errors_prct',
perfdatas => [
{ label => 'errors', value => 'errors_prct', template => '%.2f', min => 0, max => 100, unit => '%' },
],
}
},
];
}
sub prefix_output {
my ($self, %options) = @_;
return "Client Requests: ";
}
sub custom_data_calc {
my ($self, %options) = @_;
my $label = $options{extra_options}->{label_ref};
my $delta_value = $options{new_datas}->{$self->{instance} . '_client_http_' . $label} - $options{old_datas}->{$self->{instance} . '_client_http_' . $label};
my $delta_total = $options{new_datas}->{$self->{instance} . '_client_http_requests'} - $options{old_datas}->{$self->{instance} . '_client_http_requests'};
$self->{result_values}->{$label . '_prct'} = 0;
if ($delta_total > 0) {
$self->{result_values}->{$label . '_prct'} = $delta_value * 100 / $delta_total;
}
return 0;
}
sub new { sub new {
my ($class, %options) = @_; my ($class, %options) = @_;
my $self = $class->SUPER::new(package => __PACKAGE__, %options); my $self = $class->SUPER::new(package => __PACKAGE__, %options, statefile => 1);
bless $self, $class; bless $self, $class;
$self->{version} = '1.0'; $self->{version} = '1.0';
$options{options}->add_options(arguments => $options{options}->add_options(arguments =>
{ {
"warning-errors:s" => { name => 'warning_errors' },
"critical-errors:s" => { name => 'critical_errors' },
"warning-misses:s" => { name => 'warning_misses' },
"critical-misses:s" => { name => 'critical_misses' },
}); });
$self->{statefile_value} = centreon::plugins::statefile->new(%options);
return $self; return $self;
} }
sub check_options { sub manage_selection {
my ($self, %options) = @_; my ($self, %options) = @_;
$self->SUPER::init(%options);
if (($self->{perfdata}->threshold_validate(label => 'warning_errors', value => $self->{option_results}->{warning_errors})) == 0) {
$self->{output}->add_option_msg(short_msg => "Wrong warning 'errors' threshold '" . $self->{option_results}->{warning_errors} . "'.");
$self->{output}->option_exit();
}
if (($self->{perfdata}->threshold_validate(label => 'critical_errors', value => $self->{option_results}->{critical_errors})) == 0) {
$self->{output}->add_option_msg(short_msg => "Wrong critical 'errors' threshold '" . $self->{option_results}->{critical_errors} . "'.");
$self->{output}->option_exit();
}
if (($self->{perfdata}->threshold_validate(label => 'warning_misses', value => $self->{option_results}->{warning_misses})) == 0) {
$self->{output}->add_option_msg(short_msg => "Wrong warning 'misses' threshold '" . $self->{option_results}->{warning_misses} . "'.");
$self->{output}->option_exit();
}
if (($self->{perfdata}->threshold_validate(label => 'critical_misses', value => $self->{option_results}->{critical_misses})) == 0) {
$self->{output}->add_option_msg(short_msg => "Wrong critical 'misses' threshold '" . $self->{option_results}->{critical_misses} . "'.");
$self->{output}->option_exit();
}
$self->{statefile_value}->check_options(%options);
}
sub run { if ($options{snmp}->is_snmpv1()) {
my ($self, %options) = @_;
# $options{snmp} = snmp object
$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 => "Need to use SNMP v2c or v3."); $self->{output}->add_option_msg(short_msg => "Need to use SNMP v2c or v3.");
$self->{output}->option_exit(); $self->{output}->option_exit();
} }
my $result = $options{snmp}->get_leef(oids => ['.1.3.6.1.4.1.3417.2.11.3.1.1.1.0',
'.1.3.6.1.4.1.3417.2.11.3.1.1.2.0',
'.1.3.6.1.4.1.3417.2.11.3.1.1.3.0',
'.1.3.6.1.4.1.3417.2.11.3.1.1.4.0',
'.1.3.6.1.4.1.3417.2.11.3.1.1.5.0'], nothing_quit => 1);
$self->{statefile_value}->read(statefile => 'bluecoat_' . $self->{hostname} . '_' . $self->{snmp_port} . '_' . $self->{mode}); $self->{cache_name} = "bluecoat_" . $options{snmp}->get_hostname() . '_' . $options{snmp}->get_port() . '_' . $self->{mode} . '_' .
my $result = $self->{snmp}->get_leef(oids => ['.1.3.6.1.4.1.3417.2.11.3.1.1.1.0', (defined($self->{option_results}->{filter_counters}) ? md5_hex($self->{option_results}->{filter_counters}) : md5_hex('all'));
'.1.3.6.1.4.1.3417.2.11.3.1.1.2.0',
'.1.3.6.1.4.1.3417.2.11.3.1.1.3.0',
'.1.3.6.1.4.1.3417.2.11.3.1.1.4.0',
'.1.3.6.1.4.1.3417.2.11.3.1.1.5.0'], nothing_quit => 1);
my $new_datas = {};
my $old_timestamp = $self->{statefile_value}->get(name => 'last_timestamp');
my $old_client_http_requests = $self->{statefile_value}->get(name => 'client_http_requests');
my $old_client_http_hits = $self->{statefile_value}->get(name => 'client_http_hits');
my $old_client_http_partial_hits = $self->{statefile_value}->get(name => 'client_http_partial_hits');
my $old_client_http_misses = $self->{statefile_value}->get(name => 'client_http_misses');
my $old_client_http_errors = $self->{statefile_value}->get(name => 'client_http_errors');
$new_datas->{last_timestamp} = time();
$new_datas->{client_http_requests} = $result->{'.1.3.6.1.4.1.3417.2.11.3.1.1.1.0'};
$new_datas->{client_http_hits} = $result->{'.1.3.6.1.4.1.3417.2.11.3.1.1.2.0'};
$new_datas->{client_http_partial_hits} = $result->{'.1.3.6.1.4.1.3417.2.11.3.1.1.3.0'};
$new_datas->{client_http_misses} = $result->{'.1.3.6.1.4.1.3417.2.11.3.1.1.4.0'};
$new_datas->{client_http_errors} = $result->{'.1.3.6.1.4.1.3417.2.11.3.1.1.5.0'};
$self->{statefile_value}->write(data => $new_datas); $self->{global} = { client_http_requests => $result->{'.1.3.6.1.4.1.3417.2.11.3.1.1.1.0'},
client_http_hits => $result->{'.1.3.6.1.4.1.3417.2.11.3.1.1.2.0'},
if (!defined($old_timestamp) || !defined($old_client_http_misses)) { client_http_partial_hits => $result->{'.1.3.6.1.4.1.3417.2.11.3.1.1.3.0'},
$self->{output}->output_add(severity => 'OK', client_http_misses => $result->{'.1.3.6.1.4.1.3417.2.11.3.1.1.4.0'},
short_msg => "Buffer creation..."); client_http_errors => $result->{'.1.3.6.1.4.1.3417.2.11.3.1.1.5.0'} };
$self->{output}->display();
$self->{output}->exit();
}
if ($new_datas->{client_http_requests} < $old_client_http_requests) {
# We set 0. Has reboot.
$old_client_http_requests = 0;
$old_client_http_hits = 0;
$old_client_http_partial_hits = 0;
$old_client_http_misses = 0;
$old_client_http_errors = 0;
}
my $delta_http_requests = $new_datas->{client_http_requests} - $old_client_http_requests;
my $prct_misses = sprintf("%.2f", ($new_datas->{client_http_misses} - $old_client_http_misses) * 100 / $delta_http_requests);
my $prct_hits = sprintf("%.2f", ($new_datas->{client_http_hits} - $old_client_http_hits) * 100 / $delta_http_requests);
my $prct_partial_hits = sprintf("%.2f", ($new_datas->{client_http_partial_hits} - $old_client_http_partial_hits) * 100 / $delta_http_requests);
my $prct_errors = sprintf("%.2f", ($new_datas->{client_http_errors} - $old_client_http_errors) * 100 / $delta_http_requests);
my $exit1 = $self->{perfdata}->threshold_check(value => $prct_errors, threshold => [ { label => 'critical_errors', 'exit_litteral' => 'critical' }, { label => 'warning_errors', exit_litteral => 'warning' } ]);
my $exit2 = $self->{perfdata}->threshold_check(value => $prct_misses, threshold => [ { label => 'critical_misses', 'exit_litteral' => 'critical' }, { label => 'warning_misses', exit_litteral => 'warning' } ]);
my $exit = $self->{output}->get_most_critical(status => [ $exit1, $exit2 ]);
$self->{output}->output_add(severity => $exit,
short_msg => "Client Requests: Hits = $prct_hits%, Partial Hits = $prct_partial_hits%, Misses = $prct_misses%, Errors = $prct_errors%");
$self->{output}->perfdata_add(label => 'hits', unit => '%',
value => $prct_hits,
min => 0);
$self->{output}->perfdata_add(label => 'partial_hits', unit => '%',
value => $prct_partial_hits,
min => 0);
$self->{output}->perfdata_add(label => 'misses', unit => '%',
value => $prct_misses,
warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning_misses'),
critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical_misses'),
min => 0);
$self->{output}->perfdata_add(label => 'errors', unit => '%',
value => $prct_errors,
warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning_errors'),
critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical_errors'),
min => 0);
$self->{output}->display();
$self->{output}->exit();
} }
1; 1;
@ -163,21 +138,20 @@ Check http client requests (in percent by type: hit, partial, misses, errors)
=over 8 =over 8
=item B<--warning-errors> =item B<--filter-counters>
Threshold warning of client http errors in percent. Only display some counters (regexp can be used).
Example: --filter-counters='errors'
=item B<--critical-errors> =item B<--warning-*>
Threshold critical of client http errors in percent. Threshold warning.
Can be: errors (%), hits (%), partial-hits (%), misses (%).
=item B<--warning-misses> =item B<--critical-*>
Threshold warning of client http misses in percent. Threshold critical.
Can be: errors (%), hits (%), partial-hits (%), misses (%).
=item B<--critical-misses>
Threshold critial of client http misses in percent.
=back =back

View File

@ -0,0 +1,99 @@
#
# Copyright 2016 Centreon (http://www.centreon.com/)
#
# Centreon is a full-fledged industry-strength solution that meets
# the needs in IT infrastructure and application monitoring for
# service performance.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
package network::digi::anywhereusb::snmp::mode::cpu;
use base qw(centreon::plugins::mode);
use strict;
use warnings;
sub new {
my ($class, %options) = @_;
my $self = $class->SUPER::new(package => __PACKAGE__, %options);
bless $self, $class;
$self->{version} = '1.0';
$options{options}->add_options(arguments =>
{
"warning:s" => { name => 'warning' },
"critical:s" => { name => 'critical' },
});
return $self;
}
sub check_options {
my ($self, %options) = @_;
$self->SUPER::init(%options);
if (($self->{perfdata}->threshold_validate(label => 'warning', value => $self->{option_results}->{warning})) == 0) {
$self->{output}->add_option_msg(short_msg => "Wrong warning threshold '" . $self->{option_results}->{warning} . "'.");
$self->{output}->option_exit();
}
if (($self->{perfdata}->threshold_validate(label => 'critical', value => $self->{option_results}->{critical})) == 0) {
$self->{output}->add_option_msg(short_msg => "Wrong critical threshold '" . $self->{option_results}->{critical} . "'.");
$self->{output}->option_exit();
}
}
sub run {
my ($self, %options) = @_;
$self->{snmp} = $options{snmp};
my $oid_diCpuUtilization = '.1.3.6.1.4.1.332.11.6.1.6.0';
my $result = $self->{snmp}->get_leef(oids => [$oid_diCpuUtilization], nothing_quit => 1);
my $exit = $self->{perfdata}->threshold_check(value => $result->{$oid_diCpuUtilization},
threshold => [ { label => 'critical', exit_litteral => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]);
$self->{output}->output_add(severity => $exit,
short_msg => sprintf("CPU Usage : %.2f", $result->{$oid_diCpuUtilization}));
$self->{output}->perfdata_add(label => "cpu",
value => $result->{$oid_diCpuUtilization},
warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning'),
critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical'),
min => 0);
$self->{output}->display();
$self->{output}->exit();
}
1;
__END__
=head1 MODE
Check current processor usage.
=over 8
=item B<--warning>
Threshold warning.
=item B<--critical>
Threshold critical.
=back
=cut

View File

@ -0,0 +1,132 @@
#
# Copyright 2016 Centreon (http://www.centreon.com/)
#
# Centreon is a full-fledged industry-strength solution that meets
# the needs in IT infrastructure and application monitoring for
# service performance.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
package network::digi::anywhereusb::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 Usage Total: %s Used: %s (%.2f%%) Free: %s (%.2f%%)",
$total_size_value . " " . $total_size_unit,
$total_used_value . " " . $total_used_unit, $self->{result_values}->{prct_used},
$total_free_value . " " . $total_free_unit, $self->{result_values}->{prct_free});
return $msg;
}
sub custom_usage_calc {
my ($self, %options) = @_;
$self->{result_values}->{total} = $options{new_datas}->{$self->{instance} . '_total'};
$self->{result_values}->{used} = $options{new_datas}->{$self->{instance} . '_total'} - $options{new_datas}->{$self->{instance} . '_free'};
$self->{result_values}->{free} = $options{new_datas}->{$self->{instance} . '_free'};
$self->{result_values}->{prct_free} = $self->{result_values}->{free} * 100 / $self->{result_values}->{total};
$self->{result_values}->{prct_used} = $self->{result_values}->{used} * 100 / $self->{result_values}->{total};
return 0;
}
sub set_counters {
my ($self, %options) = @_;
$self->{maps_counters_type} = [
{ name => 'memory', type => 0 }
];
$self->{maps_counters}->{memory} = [
{ label => 'usage', set => {
key_values => [ { 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 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_diTotalMemory = '.1.3.6.1.4.1.332.11.6.1.8.0';
my $oid_diFreeMemory = '.1.3.6.1.4.1.332.11.6.1.9.0';
my $result = $options{snmp}->get_leef(oids => [$oid_diTotalMemory, $oid_diFreeMemory],
nothing_quit => 1);
$self->{memory} = { free => $result->{$oid_diFreeMemory}, total => $result->{$oid_diTotalMemory} };
}
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

View File

@ -0,0 +1,51 @@
#
# Copyright 2016 Centreon (http://www.centreon.com/)
#
# Centreon is a full-fledged industry-strength solution that meets
# the needs in IT infrastructure and application monitoring for
# service performance.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
package network::digi::anywhereusb::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::digi::anywhereusb::snmp::mode::cpu',
'interfaces' => 'snmp_standard::mode::interfaces',
'list-interfaces' => 'snmp_standard::mode::listinterfaces',
'memory' => 'network::digi::anywhereusb::snmp::mode::memory',
);
return $self;
}
1;
__END__
=head1 PLUGIN DESCRIPTION
Check Digi AnywhereUSB equipments in SNMP.
=cut

View File

@ -65,44 +65,41 @@ sub check {
next; next;
} }
next if (!(defined($result2->{EntityExtTemperatureThreshold}) &&
$result2->{EntityExtTemperatureThreshold} > 0 && $result2->{EntityExtTemperatureThreshold} < 65535));
my $name = $self->get_long_name(instance => $instance); my $name = $self->get_long_name(instance => $instance);
$self->{components}->{sensor}->{total}++; $self->{components}->{sensor}->{total}++;
if (defined($result2->{EntityExtTemperatureThreshold}) && $self->{output}->output_add(long_msg => sprintf("Sensor '%s' status is '%s' [instance = %s]",
$result2->{EntityExtTemperatureThreshold} > 0 && $result2->{EntityExtTemperatureThreshold} < 65535) { $name, $result->{EntityExtErrorStatus}, $instance));
$self->{output}->output_add(long_msg => sprintf("Sensor '%s' status is '%s' [instance = %s]", $exit = $self->get_severity(section => 'sensor', value => $result->{EntityExtErrorStatus});
$name, $result->{EntityExtErrorStatus}, $instance)); if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) {
$exit = $self->get_severity(section => 'sensor', value => $result->{EntityExtErrorStatus}); $self->{output}->output_add(severity => $exit,
if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) { short_msg => sprintf("Sensor '%s' status is '%s'", $name, $result->{EntityExtErrorStatus}));
$self->{output}->output_add(severity => $exit,
short_msg => sprintf("Sensor '%s' status is '%s'", $name, $result->{EntityExtErrorStatus}));
}
($exit, $warn, $crit, $checked) = $self->get_severity_numeric(section => 'temperature', instance => $instance, value => $result2->{EntityExtTemperature});
if ($checked == 0) {
my $crit_th = '~:' . $result2->{EntityExtTemperatureThreshold};
$self->{perfdata}->threshold_validate(label => 'warning-temperature-instance-' . $instance, value => undef);
$self->{perfdata}->threshold_validate(label => 'critical-temperature-instance-' . $instance, value => $crit_th);
$exit = $self->{perfdata}->threshold_check(value => $result2->{EntityExtTemperature}, 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 sensor '%s' is %s degree centigrade", $name, $result2->{EntityExtTemperature}));
}
$self->{output}->perfdata_add(label => 'temp_' . $instance, unit => 'C',
value => $result2->{EntityExtTemperature},
warning => $warn,
critical => $crit,
);
} }
next if (defined($result2->{EntityExtTemperature}) && $result2->{EntityExtTemperature} <= 0);
($exit, $warn, $crit, $checked) = $self->get_severity_numeric(section => 'temperature', instance => $instance, value => $result2->{EntityExtTemperature});
if ($checked == 0 && defined($result2->{EntityExtTemperatureThreshold}) &&
$result2->{EntityExtTemperatureThreshold} > 0 && $result2->{EntityExtTemperatureThreshold} < 65535) {
my $crit_th = '~:' . $result2->{EntityExtTemperatureThreshold};
$self->{perfdata}->threshold_validate(label => 'warning-temperature-instance-' . $instance, value => undef);
$self->{perfdata}->threshold_validate(label => 'critical-temperature-instance-' . $instance, value => $crit_th);
$exit = $self->{perfdata}->threshold_check(value => $result2->{EntityExtTemperature}, 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 sensor '%s' is %s degree centigrade", $name, $result2->{EntityExtTemperature}));
}
$self->{output}->perfdata_add(label => 'temp_' . $instance, unit => 'C',
value => $result2->{EntityExtTemperature},
warning => $warn,
critical => $crit,
);
} }
} }

View File

@ -1,77 +0,0 @@
===============
Mode Lun
===============
Command to test. All: getlun -uid -state -rg -type -drivetype -capacity -prb -bind
LOGICAL UNIT NUMBER 3
UID: 60:06:01:60:F8:C0:1E:00:A2:DC:41:39:8C:0F:E1:11
State: Bound
RAIDGroup ID: 0
RAID Type: RAID5
Drive Type: SATAII
LUN Capacity(Megabytes): 1659491
LUN Capacity(Blocks): 3398637568
Prct Rebuilt: 100
Prct Bound: 100
LOGICAL UNIT NUMBER 1
UID: 60:06:01:60:F8:C0:1E:00:0E:A7:F5:5F:66:10:E1:11
State: Bound
RAIDGroup ID: 101
RAID Type: Hot Spare
Drive Type: SATAII
LUN Capacity(Megabytes): 704364
LUN Capacity(Blocks): 1442538624
Prct Rebuilt: N/A
Prct Bound: 100
For one lun: getlun 1 -uid -state -rg -type -drivetype -capacity -prb -bind
UID: 60:06:01:60:F8:C0:1E:00:0E:A7:F5:5F:66:10:E1:11
State: Bound
RAIDGroup ID: 101
RAID Type: Hot Spare
Drive Type: SATAII
LUN Capacity(Megabytes): 704364
LUN Capacity(Blocks): 1442538624
Prct Rebuilt: N/A
Prct Bound: 100
======================
Mode pour les raid group
======================
La commande globale: getrg -type -tcap -ucap -prcntdf -prcntex -state
RaidGroup ID: 40
RaidGroup Type: r5
Raw Capacity (Blocks): 5770154824
Logical Capacity (Blocks): 4327616118
Free Capacity (Blocks,non-contiguous): 246
Percent defragmented: 100
Percent expanded: 100
RaidGroup State: Explicit_Remove
Valid_luns
RaidGroup ID: 103
RaidGroup Type: hot_spare
Raw Capacity (Blocks): 1442538706
Logical Capacity (Blocks): 1442538706
Free Capacity (Blocks,non-contiguous): 82
Percent defragmented: 100
Percent expanded: 100
RaidGroup State: Valid_luns
Pour un seul: getrg 109 -type -tcap -ucap -prcntdf -prcntex -state
RaidGroup ID: 109
RaidGroup Type: hot_spare
Raw Capacity (Blocks): 1442538706
Logical Capacity (Blocks): 0
Free Capacity (Blocks,non-contiguous): 1442538706
Percent defragmented: 100
Percent expanded: 100
RaidGroup State: Valid_luns

View File

@ -153,10 +153,6 @@ sub send_email {
} }
if (defined($self->{option_results}->{email_smtp_username}) && defined($self->{option_results}->{email_smtp_password})) { if (defined($self->{option_results}->{email_smtp_username}) && defined($self->{option_results}->{email_smtp_password})) {
$smtp_options{-pass} = $self->{option_results}->{email_smtp_password}; $smtp_options{-pass} = $self->{option_results}->{email_smtp_password};
}
foreach my $option (@{$self->{option_results}->{email_smtp_options}}) {
next if ($option !~ /^(.+?)=(.+)$/);
$smtp_options{-$1} = $2;
} }
####### #######
@ -172,6 +168,17 @@ sub send_email {
my $subject = $1; my $subject = $1;
my $status = lc($self->{output}->get_litteral_status()); my $status = lc($self->{output}->get_litteral_status());
foreach my $option (@{$self->{option_results}->{email_smtp_options}}) {
next if ($option !~ /^(.+?)=(.+)$/);
my ($label, $value) = ($1, $2);
if ($label =~ /subject/i) {
$value =~ s/%\{status\}/$status/g;
$value =~ s/%\{short_msg\}/$subject/g;
$label = lc($label);
}
$smtp_options{-$label} = $value;
}
my $send_email = 0; my $send_email = 0;
$send_email = 1 if ($status ne 'ok'); $send_email = 1 if ($status ne 'ok');
####### #######
@ -216,9 +223,9 @@ sub send_email {
} }
my $result = $mail->send(-to => $smtp_to, my $result = $mail->send(-to => $smtp_to,
-from => $self->{option_results}->{email_smtp_from}, -from => $self->{option_results}->{email_smtp_from},
-subject => $subject, -subject => defined($smtp_options{-subject}) ? $smtp_options{-subject} : $subject,
-body => $stdout, -body => $stdout,
-attachments => $self->{option_results}->{file_health_env}); -attachments => $self->{option_results}->{file_health} . ',' . $self->{option_results}->{file_health_env});
$mail->bye(); $mail->bye();
if ($result == -1) { if ($result == -1) {
$self->{output}->add_option_msg(severity => 'UNKNOWN', short_msg => "problem to send the email"); $self->{output}->add_option_msg(severity => 'UNKNOWN', short_msg => "problem to send the email");

View File

@ -49,11 +49,48 @@ sub set_system {
$self->{components_module} = ['module', 'temperature', 'director', 'cabling', 'power', 'fabric', 'voltage', 'sparedisk']; $self->{components_module} = ['module', 'temperature', 'director', 'cabling', 'power', 'fabric', 'voltage', 'sparedisk'];
} }
sub find_files {
my ($self, %options) = @_;
if (!opendir(DIR, $self->{option_results}->{health_directory})) {
$self->{output}->add_option_msg(short_msg => "Cannot open directory: $!");
$self->{output}->option_exit();
}
my $save_value = 0;
while (my $file = readdir(DIR)) {
next if (! -d $self->{option_results}->{health_directory} . '/' . $file ||
$file !~ /$self->{option_results}->{health_directory_pattern}/);
if (hex($1) > $save_value) {
$self->{option_results}->{file_health} = $self->{option_results}->{health_directory} . '/' . $file . '/' . $self->{option_results}->{file_health_name};
$self->{option_results}->{file_health_env} = $self->{option_results}->{health_directory} . '/' . $file . '/' . $self->{option_results}->{file_health_env_name};
$save_value = hex($1);
}
}
closedir(DIR);
}
sub check_options { sub check_options {
my ($self, %options) = @_; my ($self, %options) = @_;
$self->SUPER::check_options(%options); $self->SUPER::check_options(%options);
$self->{statefile_cache}->check_options(%options); $self->{statefile_cache}->check_options(%options);
if (!defined($self->{option_results}->{file_health_name}) || !defined($self->{option_results}->{file_health_env_name})) {
$self->{output}->add_option_msg(short_msg => "Please set option --file-health-name and --file-health-env-name.");
$self->{output}->option_exit();
}
if (!defined($self->{option_results}->{health_directory}) || ! -d $self->{option_results}->{health_directory}) {
$self->{output}->add_option_msg(short_msg => "Please set right option for --health-directory.");
$self->{output}->option_exit();
}
if (!defined($self->{option_results}->{health_directory_pattern})) {
$self->{output}->add_option_msg(short_msg => "Please set option for --health-directory-pattern.");
$self->{output}->option_exit();
}
$self->find_files();
} }
sub new { sub new {
@ -64,8 +101,10 @@ sub new {
$self->{version} = '1.0'; $self->{version} = '1.0';
$options{options}->add_options(arguments => $options{options}->add_options(arguments =>
{ {
"file-health:s" => { name => 'file_health' }, "health-directory:s" => { name => 'health_directory' },
"file-health-env:s" => { name => 'file_health_env' }, "health-directory-pattern:s" => { name => 'health_directory_pattern' },
"file-health-name:s" => { name => 'file_health_name', default => 'HealthCheck.log' },
"file-health-env-name:s" => { name => 'file_health_env_name', default => 'sympl_env_health.log' },
# Email # Email
"email-warning:s" => { name => 'email_warning' }, "email-warning:s" => { name => 'email_warning' },
"email-critical:s" => { name => 'email_critical' }, "email-critical:s" => { name => 'email_critical' },
@ -84,11 +123,6 @@ sub new {
sub read_files { sub read_files {
my ($self, %options) = @_; my ($self, %options) = @_;
if (!defined($self->{option_results}->{file_health}) || !defined($self->{option_results}->{file_health_env})) {
$self->{output}->add_option_msg(short_msg => "Please set option --file-health and --file-health-env.");
$self->{output}->option_exit();
}
foreach (('file_health', 'file_health_env')) { foreach (('file_health', 'file_health_env')) {
$self->{'content_' . $_} = do { $self->{'content_' . $_} = do {
@ -145,10 +179,6 @@ sub send_email {
if (defined($self->{option_results}->{email_smtp_username}) && defined($self->{option_results}->{email_smtp_password})) { if (defined($self->{option_results}->{email_smtp_username}) && defined($self->{option_results}->{email_smtp_password})) {
$smtp_options{-pass} = $self->{option_results}->{email_smtp_password}; $smtp_options{-pass} = $self->{option_results}->{email_smtp_password};
} }
foreach my $option (@{$self->{option_results}->{email_smtp_options}}) {
next if ($option !~ /^(.+?)=(.+)$/);
$smtp_options{-$1} = $2;
}
####### #######
# Get current data # Get current data
@ -163,6 +193,17 @@ sub send_email {
my $subject = $1; my $subject = $1;
my $status = lc($self->{output}->get_litteral_status()); my $status = lc($self->{output}->get_litteral_status());
foreach my $option (@{$self->{option_results}->{email_smtp_options}}) {
next if ($option !~ /^(.+?)=(.+)$/);
my ($label, $value) = ($1, $2);
if ($label =~ /subject/i) {
$value =~ s/%\{status\}/$status/g;
$value =~ s/%\{short_msg\}/$subject/g;
$label = lc($label);
}
$smtp_options{-$label} = $value;
}
my $send_email = 0; my $send_email = 0;
$send_email = 1 if ($status ne 'ok'); $send_email = 1 if ($status ne 'ok');
####### #######
@ -176,7 +217,7 @@ sub send_email {
$send_email = 0 if ($status ne 'ok' && defined($prev_output) && $prev_output eq $subject); $send_email = 0 if ($status ne 'ok' && defined($prev_output) && $prev_output eq $subject);
# recovery email # recovery email
$send_email = 1 if ($status eq 'ok' && defined($prev_status) && $prev_status ne 'ok'); $send_email = 1 if ($status eq 'ok' && defined($prev_status) && $prev_status ne 'ok');
$self->{statefile_cache}->write(data => $self->{new_datas}); $self->{statefile_cache}->write(data => $self->{new_datas});
} }
my $smtp_to = ''; my $smtp_to = '';
@ -207,9 +248,9 @@ sub send_email {
} }
my $result = $mail->send(-to => $smtp_to, my $result = $mail->send(-to => $smtp_to,
-from => $self->{option_results}->{email_smtp_from}, -from => $self->{option_results}->{email_smtp_from},
-subject => $subject, -subject => defined($smtp_options{-subject}) ? $smtp_options{-subject} : $subject,
-body => $stdout, -body => $stdout,
-attachments => $self->{option_results}->{file_health_env}); -attachments => $self->{option_results}->{file_health} . "," . $self->{option_results}->{file_health_env});
$mail->bye(); $mail->bye();
if ($result == -1) { if ($result == -1) {
$self->{output}->add_option_msg(severity => 'UNKNOWN', short_msg => "problem to send the email"); $self->{output}->add_option_msg(severity => 'UNKNOWN', short_msg => "problem to send the email");
@ -259,13 +300,21 @@ Example: --warning='sparedisk,.*,5:'
Set critical threshold for disk (syntax: type,regexp,threshold) Set critical threshold for disk (syntax: type,regexp,threshold)
Example: --critical='sparedisk,.*,3:' Example: --critical='sparedisk,.*,3:'
=item B<--file-health> =item B<--health-directory>
The location of the global storage file status (Should be something like: C:/xxxx/HealthCheck.log). Location of health files.
=item B<--file-health-env> =item B<--health-directory-pattern>
The location of the environment storage file status (Should be something like: C:/xxxx/sumpl_env_health.log). Set pattern to match the most recent directory (getting the hexa value).
=item B<--file-health-name>
Name of the global storage file status (Default: HealthCheck.log).
=item B<--file-health-env-name>
Name of the environment storage file status (Default: sympl_env_health.log).
=back =back

View File

@ -0,0 +1,60 @@
#
# Copyright 2016 Centreon (http://www.centreon.com/)
#
# Centreon is a full-fledged industry-strength solution that meets
# the needs in IT infrastructure and application monitoring for
# service performance.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES 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::ibm::storwize::ssh::mode::components::array;
use strict;
use warnings;
sub load {
my ($self) = @_;
$self->{ssh_commands} .= 'echo "==========lsarray=========="; lsarray -delim : ; echo "===============";';
}
sub check {
my ($self) = @_;
$self->{output}->output_add(long_msg => "Checking arrays");
$self->{components}->{array} = {name => 'arrays', total => 0, skip => 0};
return if ($self->check_filter(section => 'array'));
return if ($self->{results} !~ /==========lsarray==.*?\n(.*?)==============/msi);
my $content = $1;
my $result = $self->get_hasharray(content => $content, delim => ':');
foreach (@$result) {
next if ($self->check_filter(section => 'array', instance => $_->{mdisk_id}));
$self->{components}->{array}->{total}++;
$self->{output}->output_add(long_msg => sprintf("array '%s' status is '%s' [instance: %s].",
$_->{mdisk_name}, $_->{status},
$_->{mdisk_id}
));
my $exit = $self->get_severity(label => 'default', section => 'array', value => $_->{status});
if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) {
$self->{output}->output_add(severity => $exit,
short_msg => sprintf("Array '%s' status is '%s'",
$_->{mdisk_name}, $_->{status}));
}
}
}
1;

View File

@ -0,0 +1,60 @@
#
# Copyright 2016 Centreon (http://www.centreon.com/)
#
# Centreon is a full-fledged industry-strength solution that meets
# the needs in IT infrastructure and application monitoring for
# service performance.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES 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::ibm::storwize::ssh::mode::components::drive;
use strict;
use warnings;
sub load {
my ($self) = @_;
$self->{ssh_commands} .= 'echo "==========lsdrive=========="; lsdrive -delim : ; echo "===============";';
}
sub check {
my ($self) = @_;
$self->{output}->output_add(long_msg => "Checking drives");
$self->{components}->{drive} = {name => 'drives', total => 0, skip => 0};
return if ($self->check_filter(section => 'drive'));
return if ($self->{results} !~ /==========lsdrive==.*?\n(.*?)==============/msi);
my $content = $1;
my $result = $self->get_hasharray(content => $content, delim => ':');
foreach (@$result) {
next if ($self->check_filter(section => 'drive', instance => $_->{id}));
$self->{components}->{drive}->{total}++;
$self->{output}->output_add(long_msg => sprintf("drive '%s' status is '%s' [instance: %s].",
$_->{id}, $_->{status},
$_->{id}
));
my $exit = $self->get_severity(label => 'default', section => 'drive', value => $_->{status});
if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) {
$self->{output}->output_add(severity => $exit,
short_msg => sprintf("Drive '%s' status is '%s'",
$_->{id}, $_->{status}));
}
}
}
1;

View File

@ -0,0 +1,60 @@
#
# Copyright 2016 Centreon (http://www.centreon.com/)
#
# Centreon is a full-fledged industry-strength solution that meets
# the needs in IT infrastructure and application monitoring for
# service performance.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES 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::ibm::storwize::ssh::mode::components::enclosure;
use strict;
use warnings;
sub load {
my ($self) = @_;
$self->{ssh_commands} .= 'echo "==========lsenclosure=========="; lsenclosure -delim : ; echo "===============";';
}
sub check {
my ($self) = @_;
$self->{output}->output_add(long_msg => "Checking enclosures");
$self->{components}->{enclosure} = {name => 'enclosures', total => 0, skip => 0};
return if ($self->check_filter(section => 'enclosure'));
return if ($self->{results} !~ /==========lsenclosure==.*?\n(.*?)==============/msi);
my $content = $1;
my $result = $self->get_hasharray(content => $content, delim => ':');
foreach (@$result) {
next if ($self->check_filter(section => 'enclosure', instance => $_->{id}));
$self->{components}->{enclosure}->{total}++;
$self->{output}->output_add(long_msg => sprintf("enclosure '%s' status is '%s' [instance: %s].",
$_->{id}, $_->{status},
$_->{id}
));
my $exit = $self->get_severity(label => 'default', section => 'enclosure', value => $_->{status});
if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) {
$self->{output}->output_add(severity => $exit,
short_msg => sprintf("Enclosure '%s' status is '%s'",
$_->{id}, $_->{status}));
}
}
}
1;

View File

@ -0,0 +1,61 @@
#
# Copyright 2016 Centreon (http://www.centreon.com/)
#
# Centreon is a full-fledged industry-strength solution that meets
# the needs in IT infrastructure and application monitoring for
# service performance.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES 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::ibm::storwize::ssh::mode::components::enclosurebattery;
use strict;
use warnings;
sub load {
my ($self) = @_;
$self->{ssh_commands} .= 'echo "==========lsenclosurebattery=========="; lsenclosurebattery -delim : ; echo "===============";';
}
sub check {
my ($self) = @_;
$self->{output}->output_add(long_msg => "Checking enclosure batteries");
$self->{components}->{enclosurebattery} = {name => 'enclosure batteries', total => 0, skip => 0};
return if ($self->check_filter(section => 'enclosurebattery'));
return if ($self->{results} !~ /==========lsenclosurebattery==.*?\n(.*?)==============/msi);
my $content = $1;
my $result = $self->get_hasharray(content => $content, delim => ':');
foreach (@$result) {
my $instance = $_->{enclosure_id} . '.' . $_->{battery_id};
next if ($self->check_filter(section => 'enclosurebattery', instance => $instance));
$self->{components}->{enclosurebattery}->{total}++;
$self->{output}->output_add(long_msg => sprintf("enclosure battery '%s' status is '%s' [instance: %s].",
$instance, $_->{status},
$instance
));
my $exit = $self->get_severity(label => 'default', section => 'enclosurebattery', value => $_->{status});
if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) {
$self->{output}->output_add(severity => $exit,
short_msg => sprintf("Enclosure battery '%s' status is '%s'",
$instance, $_->{status}));
}
}
}
1;

View File

@ -0,0 +1,61 @@
#
# Copyright 2016 Centreon (http://www.centreon.com/)
#
# Centreon is a full-fledged industry-strength solution that meets
# the needs in IT infrastructure and application monitoring for
# service performance.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES 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::ibm::storwize::ssh::mode::components::enclosurecanister;
use strict;
use warnings;
sub load {
my ($self) = @_;
$self->{ssh_commands} .= 'echo "==========lsenclosurecanister=========="; lsenclosurecanister -delim : ; echo "===============";';
}
sub check {
my ($self) = @_;
$self->{output}->output_add(long_msg => "Checking enclosure canisters");
$self->{components}->{enclosurecanister} = {name => 'enclosure canisters', total => 0, skip => 0};
return if ($self->check_filter(section => 'enclosurecanister'));
return if ($self->{results} !~ /==========lsenclosurecanister==.*?\n(.*?)==============/msi);
my $content = $1;
my $result = $self->get_hasharray(content => $content, delim => ':');
foreach (@$result) {
my $instance = $_->{enclosure_id} . '.' . $_->{canister_id};
next if ($self->check_filter(section => 'enclosurecanister', instance => $instance));
$self->{components}->{enclosurecanister}->{total}++;
$self->{output}->output_add(long_msg => sprintf("enclosure canister '%s' status is '%s' [instance: %s].",
$instance, $_->{status},
$instance
));
my $exit = $self->get_severity(label => 'default', section => 'enclosurecanister', value => $_->{status});
if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) {
$self->{output}->output_add(severity => $exit,
short_msg => sprintf("Enclosure canister '%s' status is '%s'",
$instance, $_->{status}));
}
}
}
1;

View File

@ -0,0 +1,61 @@
#
# Copyright 2016 Centreon (http://www.centreon.com/)
#
# Centreon is a full-fledged industry-strength solution that meets
# the needs in IT infrastructure and application monitoring for
# service performance.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES 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::ibm::storwize::ssh::mode::components::enclosurepsu;
use strict;
use warnings;
sub load {
my ($self) = @_;
$self->{ssh_commands} .= 'echo "==========lsenclosurepsu=========="; lsenclosurepsu -delim : ; echo "===============";';
}
sub check {
my ($self) = @_;
$self->{output}->output_add(long_msg => "Checking enclosure psus");
$self->{components}->{enclosurepsu} = {name => 'enclosure psus', total => 0, skip => 0};
return if ($self->check_filter(section => 'enclosurepsu'));
return if ($self->{results} !~ /==========lsenclosurepsu==.*?\n(.*?)==============/msi);
my $content = $1;
my $result = $self->get_hasharray(content => $content, delim => ':');
foreach (@$result) {
my $instance = $_->{enclosure_id} . '.' . $_->{PSU_id};
next if ($self->check_filter(section => 'enclosurepsu', instance => $instance));
$self->{components}->{enclosurepsu}->{total}++;
$self->{output}->output_add(long_msg => sprintf("enclosure power supply '%s' status is '%s' [instance: %s].",
$instance, $_->{status},
$instance
));
my $exit = $self->get_severity(label => 'default', section => 'enclosurepsu', value => $_->{status});
if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) {
$self->{output}->output_add(severity => $exit,
short_msg => sprintf("Enclosure power supply '%s' status is '%s'",
$instance, $_->{status}));
}
}
}
1;

View File

@ -0,0 +1,60 @@
#
# Copyright 2016 Centreon (http://www.centreon.com/)
#
# Centreon is a full-fledged industry-strength solution that meets
# the needs in IT infrastructure and application monitoring for
# service performance.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES 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::ibm::storwize::ssh::mode::components::host;
use strict;
use warnings;
sub load {
my ($self) = @_;
$self->{ssh_commands} .= 'echo "==========lshost=========="; lshost -delim : ; echo "===============";';
}
sub check {
my ($self) = @_;
$self->{output}->output_add(long_msg => "Checking hosts");
$self->{components}->{host} = {name => 'hosts', total => 0, skip => 0};
return if ($self->check_filter(section => 'host'));
return if ($self->{results} !~ /==========lshost==.*?\n(.*?)==============/msi);
my $content = $1;
my $result = $self->get_hasharray(content => $content, delim => ':');
foreach (@$result) {
next if ($self->check_filter(section => 'host', instance => $_->{id}));
$self->{components}->{host}->{total}++;
$self->{output}->output_add(long_msg => sprintf("host '%s' status is '%s' [instance: %s].",
$_->{name}, $_->{status},
$_->{id}
));
my $exit = $self->get_severity(label => 'default', section => 'host', value => $_->{status});
if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) {
$self->{output}->output_add(severity => $exit,
short_msg => sprintf("Host '%s' status is '%s'",
$_->{name}, $_->{status}));
}
}
}
1;

View File

@ -0,0 +1,60 @@
#
# Copyright 2016 Centreon (http://www.centreon.com/)
#
# Centreon is a full-fledged industry-strength solution that meets
# the needs in IT infrastructure and application monitoring for
# service performance.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES 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::ibm::storwize::ssh::mode::components::mdisk;
use strict;
use warnings;
sub load {
my ($self) = @_;
$self->{ssh_commands} .= 'echo "==========lsmdisk=========="; lsmdisk -delim : ; echo "===============";';
}
sub check {
my ($self) = @_;
$self->{output}->output_add(long_msg => "Checking mdisks");
$self->{components}->{mdisk} = {name => 'mdisks', total => 0, skip => 0};
return if ($self->check_filter(section => 'mdisk'));
return if ($self->{results} !~ /==========lsmdisk==.*?\n(.*?)==============/msi);
my $content = $1;
my $result = $self->get_hasharray(content => $content, delim => ':');
foreach (@$result) {
next if ($self->check_filter(section => 'mdisk', instance => $_->{id}));
$self->{components}->{mdisk}->{total}++;
$self->{output}->output_add(long_msg => sprintf("mdisk '%s' status is '%s' [instance: %s].",
$_->{name}, $_->{status},
$_->{id}
));
my $exit = $self->get_severity(section => 'mdisk', value => $_->{status});
if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) {
$self->{output}->output_add(severity => $exit,
short_msg => sprintf("MDisk '%s' status is '%s'",
$_->{name}, $_->{status}));
}
}
}
1;

View File

@ -0,0 +1,60 @@
#
# Copyright 2016 Centreon (http://www.centreon.com/)
#
# Centreon is a full-fledged industry-strength solution that meets
# the needs in IT infrastructure and application monitoring for
# service performance.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES 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::ibm::storwize::ssh::mode::components::node;
use strict;
use warnings;
sub load {
my ($self) = @_;
$self->{ssh_commands} .= 'echo "==========lsnode=========="; lsnode -delim : ; echo "===============";';
}
sub check {
my ($self) = @_;
$self->{output}->output_add(long_msg => "Checking nodes");
$self->{components}->{node} = {name => 'nodes', total => 0, skip => 0};
return if ($self->check_filter(section => 'node'));
return if ($self->{results} !~ /==========lsnode==.*?\n(.*?)==============/msi);
my $content = $1;
my $result = $self->get_hasharray(content => $content, delim => ':');
foreach (@$result) {
next if ($self->check_filter(section => 'node', instance => $_->{id}));
$self->{components}->{node}->{total}++;
$self->{output}->output_add(long_msg => sprintf("node '%s' status is '%s' [instance: %s].",
$_->{name}, $_->{status},
$_->{id}
));
my $exit = $self->get_severity(label => 'default', section => 'node', value => $_->{status});
if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) {
$self->{output}->output_add(severity => $exit,
short_msg => sprintf("Node '%s' status is '%s'",
$_->{name}, $_->{status}));
}
}
}
1;

View File

@ -0,0 +1,61 @@
#
# Copyright 2016 Centreon (http://www.centreon.com/)
#
# Centreon is a full-fledged industry-strength solution that meets
# the needs in IT infrastructure and application monitoring for
# service performance.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES 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::ibm::storwize::ssh::mode::components::portfc;
use strict;
use warnings;
sub load {
my ($self) = @_;
$self->{ssh_commands} .= 'echo "==========lsportfc=========="; lsportfc -delim : ; echo "===============";';
}
sub check {
my ($self) = @_;
$self->{output}->output_add(long_msg => "Checking portfc");
$self->{components}->{portfc} = {name => 'portfc', total => 0, skip => 0};
return if ($self->check_filter(section => 'portfc'));
return if ($self->{results} !~ /==========lsportfc==.*?\n(.*?)==============/msi);
my $content = $1;
my $result = $self->get_hasharray(content => $content, delim => ':');
foreach (@$result) {
next if ($self->check_filter(section => 'portfc', instance => $_->{id}));
$self->{components}->{portfc}->{total}++;
my $name = $_->{node_name} . "." . $_->{WWPN};
$self->{output}->output_add(long_msg => sprintf("portfc '%s' status is '%s' [instance: %s].",
$name, $_->{status},
$_->{id}
));
my $exit = $self->get_severity(section => 'portfc', value => $_->{status});
if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) {
$self->{output}->output_add(severity => $exit,
short_msg => sprintf("PortFC '%s' status is '%s'",
$name, $_->{status}));
}
}
}
1;

View File

@ -0,0 +1,61 @@
#
# Copyright 2016 Centreon (http://www.centreon.com/)
#
# Centreon is a full-fledged industry-strength solution that meets
# the needs in IT infrastructure and application monitoring for
# service performance.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES 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::ibm::storwize::ssh::mode::components::portsas;
use strict;
use warnings;
sub load {
my ($self) = @_;
$self->{ssh_commands} .= 'echo "==========lsportsas=========="; lsportsas -delim : ; echo "===============";';
}
sub check {
my ($self) = @_;
$self->{output}->output_add(long_msg => "Checking portsas");
$self->{components}->{portsas} = {name => 'portsas', total => 0, skip => 0};
return if ($self->check_filter(section => 'portsas'));
return if ($self->{results} !~ /==========lsportsas==.*?\n(.*?)==============/msi);
my $content = $1;
my $result = $self->get_hasharray(content => $content, delim => ':');
foreach (@$result) {
next if ($self->check_filter(section => 'portsas', instance => $_->{id}));
$self->{components}->{portsas}->{total}++;
my $name = $_->{node_name} . "." . $_->{WWPN};
$self->{output}->output_add(long_msg => sprintf("port sas '%s' status is '%s' [instance: %s].",
$name, $_->{status},
$_->{id}
));
my $exit = $self->get_severity(section => 'portsas', value => $_->{status});
if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) {
$self->{output}->output_add(severity => $exit,
short_msg => sprintf("Port sas '%s' status is '%s'",
$name, $_->{status}));
}
}
}
1;

View File

@ -0,0 +1,60 @@
#
# Copyright 2016 Centreon (http://www.centreon.com/)
#
# Centreon is a full-fledged industry-strength solution that meets
# the needs in IT infrastructure and application monitoring for
# service performance.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES 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::ibm::storwize::ssh::mode::components::quorum;
use strict;
use warnings;
sub load {
my ($self) = @_;
$self->{ssh_commands} .= 'echo "==========lsquorum=========="; lsquorum -delim : ; echo "===============";';
}
sub check {
my ($self) = @_;
$self->{output}->output_add(long_msg => "Checking quorums");
$self->{components}->{quorum} = {name => 'quorums', total => 0, skip => 0};
return if ($self->check_filter(section => 'quorum'));
return if ($self->{results} !~ /==========lsquorum==.*?\n(.*?)==============/msi);
my $content = $1;
my $result = $self->get_hasharray(content => $content, delim => ':');
foreach (@$result) {
next if ($self->check_filter(section => 'quorum', instance => $_->{quorum_index}));
$self->{components}->{quorum}->{total}++;
$self->{output}->output_add(long_msg => sprintf("quorum '%s' status is '%s' [instance: %s].",
$_->{controller_name}, $_->{status},
$_->{quorum_index}
));
my $exit = $self->get_severity(label => 'default', section => 'quorum', value => $_->{status});
if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) {
$self->{output}->output_add(severity => $exit,
short_msg => sprintf("Quorum '%s' status is '%s'",
$_->{controller_name}, $_->{status}));
}
}
}
1;

View File

@ -0,0 +1,63 @@
#
# Copyright 2016 Centreon (http://www.centreon.com/)
#
# Centreon is a full-fledged industry-strength solution that meets
# the needs in IT infrastructure and application monitoring for
# service performance.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES 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::ibm::storwize::ssh::mode::components::systemstats;
use strict;
use warnings;
sub load {
my ($self) = @_;
$self->{ssh_commands} .= 'echo "==========lssystemstats=========="; lssystemstats ; echo "===============";';
}
sub check {
my ($self) = @_;
$self->{output}->output_add(long_msg => "Checking systemstats");
$self->{components}->{systemstats} = {name => 'systemstats', total => 0, skip => 0};
return if ($self->check_filter(section => 'systemstats'));
return if ($self->{results} !~ /==========lssystemstats==.*?\n(.*?)==============/msi);
my $content = $1;
my $result = $self->get_hasharray(content => $content, delim => '\s+');
foreach (@$result) {
next if ($self->check_filter(section => 'systemstats', instance => $_->{stat_name}));
$self->{components}->{systemstats}->{total}++;
$self->{output}->output_add(long_msg => sprintf("system stat '%s' value is '%s' [instance: %s].",
$_->{stat_name}, $_->{stat_current},
$_->{stat_name}
));
my ($exit, $warn, $crit, $checked) = $self->get_severity_numeric(section => 'systemstats', instance => $_->{stat_name}, value => $_->{stat_current});
if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) {
$self->{output}->output_add(severity => $exit,
short_msg => sprintf("System stat '%s' value is '%s'", $_->{stat_name}, $_->{stat_current}));
}
$self->{output}->perfdata_add(label => "sstat_" . $_->{stat_name},
value => $_->{stat_current},
warning => $warn,
critical => $crit);
}
}
1;

View File

@ -0,0 +1,60 @@
#
# Copyright 2016 Centreon (http://www.centreon.com/)
#
# Centreon is a full-fledged industry-strength solution that meets
# the needs in IT infrastructure and application monitoring for
# service performance.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES 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::ibm::storwize::ssh::mode::components::vdisk;
use strict;
use warnings;
sub load {
my ($self) = @_;
$self->{ssh_commands} .= 'echo "==========lsvdisk=========="; lsvdisk -delim : ; echo "===============";';
}
sub check {
my ($self) = @_;
$self->{output}->output_add(long_msg => "Checking vdisks");
$self->{components}->{vdisk} = {name => 'vdisks', total => 0, skip => 0};
return if ($self->check_filter(section => 'vdisk'));
return if ($self->{results} !~ /==========lsvdisk==.*?\n(.*?)==============/msi);
my $content = $1;
my $result = $self->get_hasharray(content => $content, delim => ':');
foreach (@$result) {
next if ($self->check_filter(section => 'vdisk', instance => $_->{id}));
$self->{components}->{vdisk}->{total}++;
$self->{output}->output_add(long_msg => sprintf("vdisk '%s' status is '%s' [instance: %s].",
$_->{name}, $_->{status},
$_->{id}
));
my $exit = $self->get_severity(label => 'default', section => 'vdisk', value => $_->{status});
if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) {
$self->{output}->output_add(severity => $exit,
short_msg => sprintf("Vdisk '%s' status is '%s'",
$_->{name}, $_->{status}));
}
}
}
1;

View File

@ -0,0 +1,219 @@
#
# Copyright 2016 Centreon (http://www.centreon.com/)
#
# Centreon is a full-fledged industry-strength solution that meets
# the needs in IT infrastructure and application monitoring for
# service performance.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES 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::ibm::storwize::ssh::mode::eventlog;
use base qw(centreon::plugins::mode);
use strict;
use warnings;
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:s" => { name => 'warning', },
"critical:s" => { name => 'critical', },
"filter-event-id:s" => { name => 'filter_event_id' },
"filter-message:s" => { name => 'filter_message' },
"retention:s" => { name => 'retention' },
"hostname:s" => { name => '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 => 30 },
"sudo" => { name => 'sudo' },
"command:s" => { name => 'command' },
"command-path:s" => { name => 'command_path' },
"command-options:s" => { name => 'command_options' },
});
return $self;
}
sub check_options {
my ($self, %options) = @_;
$self->SUPER::init(%options);
if (($self->{perfdata}->threshold_validate(label => 'warning', value => $self->{option_results}->{warning})) == 0) {
$self->{output}->add_option_msg(short_msg => "Wrong warning threshold '" . $self->{option_results}->{warning} . "'.");
$self->{output}->option_exit();
}
if (($self->{perfdata}->threshold_validate(label => 'critical', value => $self->{option_results}->{critical})) == 0) {
$self->{output}->add_option_msg(short_msg => "Wrong critical threshold '" . $self->{option_results}->{critical} . "'.");
$self->{output}->option_exit();
}
if (defined($self->{option_results}->{hostname}) && $self->{option_results}->{hostname} ne '') {
$self->{option_results}->{remote} = 1;
}
my $last_timestamp = '';
if (defined($self->{option_results}->{retention}) && $self->{option_results}->{retention} =~ /^\d+$/) {
# by default UTC timezone used
my $dt = DateTime->from_epoch(epoch => time() - $self->{option_results}->{retention});
my $dt_format = sprintf("%d%02d%02d%02d%02d%02d", substr($dt->year(), 2), $dt->month(), $dt->day(), $dt->hour(), $dt->minute(), $dt->second());
$last_timestamp = 'last_timestamp>=' . $dt_format . ":";
}
$self->{ls_command} = "lseventlog -message no -alert yes -filtervalue '${last_timestamp}fixed=no' -delim :";
}
sub get_hasharray {
my ($self, %options) = @_;
my $result = [];
return $result if ($options{content} eq '');
my ($header, @lines) = split /\n/, $options{content};
my @header_names = split /$options{delim}/, $header;
for (my $i = 0; $i <= $#lines; $i++) {
my @content = split /$options{delim}/, $lines[$i];
my $data = {};
for (my $j = 0; $j <= $#header_names; $j++) {
$data->{$header_names[$j]} = $content[$j];
}
push @$result, $data;
}
return $result;
}
sub run {
my ($self, %options) = @_;
my $content = centreon::plugins::misc::execute(output => $self->{output},
options => $self->{option_results},
sudo => $self->{option_results}->{sudo},
command => defined($self->{option_results}->{command}) && $self->{option_results}->{command} ne '' ? $self->{option_results}->{command} : $self->{ls_command} . " ; exit ;",
command_path => $self->{option_results}->{command_path},
command_options => defined($self->{option_results}->{command_options}) && $self->{option_results}->{command_options} ne '' ? $self->{option_results}->{command_options} : undef);
my $result = $self->get_hasharray(content => $content, delim => ':');
my ($num_eventlog_checked, $num_errors) = (0, 0);
foreach (@$result) {
$num_eventlog_checked++;
if (defined($self->{option_results}->{filter_message}) && $self->{option_results}->{filter_message} ne '' &&
$_->{description} !~ /$self->{option_results}->{filter_message}/) {
$self->{output}->output_add(long_msg => "skipping '" . $_->{description} . "': no matching filter description.", debug => 1);
next;
}
if (defined($self->{option_results}->{filter_event_id}) && $self->{option_results}->{filter_event_id} ne '' &&
$_->{event_id} !~ /$self->{option_results}->{filter_event_id}/) {
$self->{output}->output_add(long_msg => "skipping '" . $_->{event_id} . "': no matching filter event id.", debug => 1);
next;
}
$self->{output}->output_add(long_msg => sprintf("%s : %s - %s",
scalar(localtime($_->{last_timestamp})),
$_->{event_id}, $_->{description}
)
);
$num_errors++;
}
$self->{output}->output_add(long_msg => sprintf("Number of message checked: %s", $num_eventlog_checked));
my $exit = $self->{perfdata}->threshold_check(value => $num_errors, threshold => [ { label => 'critical', exit_litteral => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]);
$self->{output}->output_add(severity => $exit,
short_msg => sprintf("%d problem detected (use verbose for more details)", $num_errors)
);
$self->{output}->perfdata_add(label => 'problems',
value => $num_errors,
warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning'),
critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical'),
min => 0);
$self->{output}->display();
$self->{output}->exit();
}
1;
__END__
=head1 MODE
Check eventlogs.
=over 8
=item B<--warning>
Threshold warning.
=item B<--critical>
Threshold critical.
=item B<--filter-event-id>
Filter on event id.
=item B<--filter-message>
Filter on event message.
=item B<--retention>
Get eventlog of X last seconds. For the last minutes: --retention=60
=item B<--hostname>
Hostname to query.
=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<--command>
Command to get information. Used it you have output in a file.
=item B<--command-path>
Command path.
=item B<--command-options>
Command options.
=back
=cut

View File

@ -0,0 +1,214 @@
#
# Copyright 2016 Centreon (http://www.centreon.com/)
#
# Centreon is a full-fledged industry-strength solution that meets
# the needs in IT infrastructure and application monitoring for
# service performance.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES 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::ibm::storwize::ssh::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} =
'^(array|drive|enclosure|enclosurebattery|enclosurecanister|enclosurepsu|host|portfc|portsas|vdisk|node|quorum|mdisk)$';
$self->{regexp_threshold_numeric_check_section_option} = '^(systemstats)$';
$self->{cb_hook2} = 'ssh_execute';
$self->{thresholds} = {
default => [
['online', 'OK'],
['offline', 'CRITICAL'],
['degraded', 'WARNING'],
['excluded', 'OK'], # lsarray
['mask', 'OK'], # lshost
],
portfc => [
['active', 'OK'],
['inactive_unconfigured', 'OK'],
['.*', 'CRITICAL'],
],
portsas => [
['online', 'OK'],
['offline_unconfigured', 'OK'],
['excluded', 'OK'],
['offline', 'CRITICAL'],
['degraded', 'WARNING'],
],
mdisk => [
['online', 'OK'],
['excluded', 'OK'],
['offline', 'CRITICAL'],
['degraded_paths', 'WARNING'],
['degraded_ports', 'WARNING'],
['degraded', 'WARNING'],
],
};
$self->{components_path} = 'storage::ibm::storwize::ssh::mode::components';
$self->{components_module} = ['array', 'drive', 'enclosure', 'enclosurebattery', 'enclosurecanister',
'enclosurepsu', 'host', 'portfc', 'portsas', 'vdisk', 'node', 'quorum', 'mdisk', 'systemstats'];
}
sub ssh_execute {
my ($self, %options) = @_;
$self->{results} = centreon::plugins::misc::execute(output => $self->{output},
options => $self->{option_results},
sudo => $self->{option_results}->{sudo},
command => defined($self->{option_results}->{command}) && $self->{option_results}->{command} ne '' ? $self->{option_results}->{command} : $self->{ssh_commands} . " exit ;",
command_path => $self->{option_results}->{command_path},
command_options => defined($self->{option_results}->{command_options}) && $self->{option_results}->{command_options} ne '' ? $self->{option_results}->{command_options} : undef);
}
sub check_options {
my ($self, %options) = @_;
$self->SUPER::check_options(%options);
if (defined($self->{option_results}->{hostname}) && $self->{option_results}->{hostname} ne '') {
$self->{option_results}->{remote} = 1;
}
}
sub new {
my ($class, %options) = @_;
my $self = $class->SUPER::new(package => __PACKAGE__, %options, no_absent => 1);
bless $self, $class;
$self->{version} = '1.0';
$options{options}->add_options(arguments =>
{
"hostname:s" => { name => '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 => 30 },
"sudo" => { name => 'sudo' },
"command:s" => { name => 'command' },
"command-path:s" => { name => 'command_path' },
"command-options:s" => { name => 'command_options' },
});
$self->{ssh_commands} = '';
return $self;
}
sub get_hasharray {
my ($self, %options) = @_;
my $result = [];
return $result if ($options{content} eq '');
my ($header, @lines) = split /\n/, $options{content};
my @header_names = split /$options{delim}/, $header;
for (my $i = 0; $i <= $#lines; $i++) {
my @content = split /$options{delim}/, $lines[$i];
my $data = {};
for (my $j = 0; $j <= $#header_names; $j++) {
$data->{$header_names[$j]} = $content[$j];
}
push @$result, $data;
}
return $result;
}
1;
__END__
=head1 MODE
Check components.
=over 8
=item B<--component>
Which component to check (Default: '.*').
Can be: 'array', 'drive'.
=item B<--filter>
Exclude some parts (comma seperated list) (Example: --filter=host --filter=enclosurecanister)
Can also exclude specific instance: --filter=host,10
=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='host,.*,OK,degraded'
=item B<--warning>
Set warning threshold for temperatures (syntax: type,regexp,threshold)
Example: --warning='systemstats,cpu_pc,30'
=item B<--critical>
Set critical threshold for temperatures (syntax: type,regexp,threshold)
Example: --critical='systemstats,cpu_pc,40'
=item B<--hostname>
Hostname to query.
=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<--command>
Command to get information. Used it you have output in a file.
=item B<--command-path>
Command path.
=item B<--command-options>
Command options.
=back
=cut

View File

@ -0,0 +1,349 @@
#
# Copyright 2016 Centreon (http://www.centreon.com/)
#
# Centreon is a full-fledged industry-strength solution that meets
# the needs in IT infrastructure and application monitoring for
# service performance.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES 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::ibm::storwize::ssh::mode::poolusage;
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 custom_usage_perfdata {
my ($self, %options) = @_;
my $label = 'used';
my $value_perf = $self->{result_values}->{used};
if (defined($instance_mode->{option_results}->{free})) {
$label = 'free';
$value_perf = $self->{result_values}->{free};
}
my $extra_label = '';
$extra_label = '_' . $self->{result_values}->{display} if (!defined($options{extra_instance}) || $options{extra_instance} != 0);
my %total_options = ();
if ($instance_mode->{option_results}->{units} eq '%') {
$total_options{total} = $self->{result_values}->{total};
$total_options{cast_int} = 1;
}
$self->{output}->perfdata_add(label => $label . $extra_label, unit => 'B',
value => $value_perf,
warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{label}, %total_options),
critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{label}, %total_options),
min => 0, max => $self->{result_values}->{total});
}
sub custom_usage_threshold {
my ($self, %options) = @_;
my ($exit, $threshold_value);
$threshold_value = $self->{result_values}->{used};
$threshold_value = $self->{result_values}->{free} if (defined($instance_mode->{option_results}->{free}));
if ($instance_mode->{option_results}->{units} eq '%') {
$threshold_value = $self->{result_values}->{prct_used};
$threshold_value = $self->{result_values}->{prct_free} if (defined($instance_mode->{option_results}->{free}));
}
$exit = $self->{perfdata}->threshold_check(value => $threshold_value, threshold => [ { label => 'critical-' . $self->{label}, exit_litteral => 'critical' }, { label => 'warning-'. $self->{label}, exit_litteral => 'warning' } ]);
return $exit;
}
sub custom_usage_output {
my ($self, %options) = @_;
my ($total_size_value, $total_size_unit) = $self->{perfdata}->change_bytes(value => $self->{result_values}->{total});
my ($total_used_value, $total_used_unit) = $self->{perfdata}->change_bytes(value => $self->{result_values}->{used});
my ($total_free_value, $total_free_unit) = $self->{perfdata}->change_bytes(value => $self->{result_values}->{free});
my $msg = sprintf("Usage Total: %s Used: %s (%.2f%%) Free: %s (%.2f%%)",
$total_size_value . " " . $total_size_unit,
$total_used_value . " " . $total_used_unit, $self->{result_values}->{prct_used},
$total_free_value . " " . $total_free_unit, $self->{result_values}->{prct_free});
return $msg;
}
sub custom_usage_calc {
my ($self, %options) = @_;
$self->{result_values}->{display} = $options{new_datas}->{$self->{instance} . '_display'};
$self->{result_values}->{total} = $options{new_datas}->{$self->{instance} . '_total'};
$self->{result_values}->{used} = $options{new_datas}->{$self->{instance} . '_used'};
$self->{result_values}->{free} = $self->{result_values}->{total} - $self->{result_values}->{used};
$self->{result_values}->{prct_used} = $self->{result_values}->{used} * 100 / $self->{result_values}->{total};
$self->{result_values}->{prct_free} = 100 - $self->{result_values}->{prct_used};
return 0;
}
sub set_counters {
my ($self, %options) = @_;
$self->{maps_counters_type} = [
{ name => 'pool', type => 1, cb_prefix_output => 'prefix_pool_output', message_multiple => 'All pools are ok' }
];
$self->{maps_counters}->{pool} = [
{ 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 => 'usage', set => {
key_values => [ { name => 'display' }, { name => 'used' }, { name => 'total' } ],
closure_custom_calc => $self->can('custom_usage_calc'),
closure_custom_output => $self->can('custom_usage_output'),
closure_custom_perfdata => $self->can('custom_usage_perfdata'),
closure_custom_threshold_check => $self->can('custom_usage_threshold'),
}
},
];
}
sub new {
my ($class, %options) = @_;
my $self = $class->SUPER::new(package => __PACKAGE__, %options);
bless $self, $class;
$self->{version} = '1.0';
$options{options}->add_options(arguments =>
{
"filter-name:s" => { name => 'filter_name' },
"warning-status:s" => { name => 'warning_status', default => '%{status} =~ /degraded/i' },
"critical-status:s" => { name => 'critical_status', default => '%{status} =~ /offline/i' },
"units:s" => { name => 'units', default => '%' },
"free" => { name => 'free' },
"hostname:s" => { name => '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 => 30 },
"sudo" => { name => 'sudo' },
"command:s" => { name => 'command' },
"command-path:s" => { name => 'command_path' },
"command-options:s" => { name => 'command_options' },
});
return $self;
}
sub check_options {
my ($self, %options) = @_;
$self->SUPER::check_options(%options);
if (defined($self->{option_results}->{hostname}) && $self->{option_results}->{hostname} ne '') {
$self->{option_results}->{remote} = 1;
}
$instance_mode = $self;
$self->change_macros();
}
sub prefix_pool_output {
my ($self, %options) = @_;
return "Pool '" . $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->{pool} = {};
my $content = centreon::plugins::misc::execute(output => $self->{output},
options => $self->{option_results},
sudo => $self->{option_results}->{sudo},
command => defined($self->{option_results}->{command}) && $self->{option_results}->{command} ne '' ? $self->{option_results}->{command} : "lsmdiskgrp -delim : -bytes ; exit ;",
command_path => $self->{option_results}->{command_path},
command_options => defined($self->{option_results}->{command_options}) && $self->{option_results}->{command_options} ne '' ? $self->{option_results}->{command_options} : undef);
my $result = $self->get_hasharray(content => $content, delim => ':');
foreach (@$result) {
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->{pool}->{$_->{id}} = { display => $_->{name},
status => $_->{status},
total => $_->{used_capacity} + $_->{free_capacity}, used => $_->{used_capacity}
};
}
if (scalar(keys %{$self->{pool}}) <= 0) {
$self->{output}->add_option_msg(short_msg => "No pool found.");
$self->{output}->option_exit();
}
}
sub get_hasharray {
my ($self, %options) = @_;
my $result = [];
return $result if ($options{content} eq '');
my ($header, @lines) = split /\n/, $options{content};
my @header_names = split /$options{delim}/, $header;
for (my $i = 0; $i <= $#lines; $i++) {
my @content = split /$options{delim}/, $lines[$i];
my $data = {};
for (my $j = 0; $j <= $#header_names; $j++) {
$data->{$header_names[$j]} = $content[$j];
}
push @$result, $data;
}
return $result;
}
1;
__END__
=head1 MODE
Check pool usages.
=over 8
=item B<--filter-counters>
Only display some counters (regexp can be used).
Example: --filter-counters='^status$'
=item B<--filter-name>
Filter pool name (can be a regexp).
=item B<--warning-status>
Set warning threshold for status (Default: '%{status} =~ /degraded/i').
Can used special variables like: %{status}, %{display}
=item B<--critical-status>
Set critical threshold for status (Default: '%{status} =~ /offline/i').
Can used special variables like: %{status}, %{display}
=item B<--warning-*>
Threshold warning.
Can be: 'usage'.
=item B<--critical-*>
Threshold critical.
Can be: 'usage'.
=item B<--units>
Units of thresholds (Default: '%') ('%', 'B').
=item B<--free>
Thresholds are on free space left.
=item B<--hostname>
Hostname to query.
=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<--command>
Command to get information. Used it you have output in a file.
=item B<--command-path>
Command path.
=item B<--command-options>
Command options.
=back
=cut

View File

@ -0,0 +1,50 @@
#
# Copyright 2016 Centreon (http://www.centreon.com/)
#
# Centreon is a full-fledged industry-strength solution that meets
# the needs in IT infrastructure and application monitoring for
# service performance.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES 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::ibm::storwize::ssh::plugin;
use strict;
use warnings;
use base qw(centreon::plugins::script_simple);
sub new {
my ($class, %options) = @_;
my $self = $class->SUPER::new(package => __PACKAGE__, %options);
bless $self, $class;
$self->{version} = '1.0';
%{$self->{modes}} = (
'components' => 'storage::ibm::storwize::ssh::mode::hardware',
'pool-usage' => 'storage::ibm::storwize::ssh::mode::poolusage',
'eventlog' => 'storage::ibm::storwize::ssh::mode::eventlog',
);
return $self;
}
1;
__END__
=head1 PLUGIN DESCRIPTION
Check IBM Storwize (v3700, v5000, v7000, SAN Volume Controller) in SSH.
=cut

View File

@ -0,0 +1,50 @@
#
# Copyright 2016 Centreon (http://www.centreon.com/)
#
# Centreon is a full-fledged industry-strength solution that meets
# the needs in IT infrastructure and application monitoring for
# service performance.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES 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::lenovo::sseries::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' => 'snmp_standard::mode::hardwarefibrealliance',
'interfaces' => 'snmp_standard::mode::interfaces',
'list-interfaces' => 'snmp_standard::mode::listinterfaces',
);
return $self;
}
1;
__END__
=head1 PLUGIN DESCRIPTION
Check Lenovo Storage S Series (S2200 and S3200) in SNMP.
=cut