enhance redis plugin

This commit is contained in:
qgarnier 2017-12-05 15:57:28 +01:00
parent 2ea4f6c74e
commit edf6b87d19
10 changed files with 273 additions and 426 deletions

View File

@ -54,20 +54,15 @@ sub new {
return $self;
}
# Method to manage multiples
sub set_options {
my ($self, %options) = @_;
# options{options_result}
$self->{option_results} = $options{option_results};
}
# Method to manage multiples
sub set_defaults {
my ($self, %options) = @_;
# options{default}
# Manage default value
foreach (keys %{$options{default}}) {
if ($_ eq $self->{mode}) {
for (my $i = 0; $i < scalar(@{$options{default}->{$_}}); $i++) {
@ -99,15 +94,19 @@ sub check_options {
return 0;
}
sub get_connection_info {
my ($self, %options) = @_;
return $self->{hostname} . ":" . $self->{port};
}
sub get_info {
my ($self, %options) = @_;
$self->{redis} = Redis->new(server => $self->{hostname}.":".$self->{port});
$self->{redis} = Redis->new(server => $self->{hostname} . ":" . $self->{port});
my $response = $self->{redis}->info;
my $items;
foreach my $attributes (keys %{$response}) {
$items->{$attributes} = $response->{$attributes};
}

View File

@ -85,13 +85,13 @@ sub new {
sub manage_selection {
my ($self, %options) = @_;
$self->{redis} = $options{custom};
$self->{results} = $self->{redis}->get_info();
$self->{global} = { 'connected_clients' => $self->{results}->{connected_clients},
'blocked_clients' => $self->{results}->{blocked_clients},
'client_longest_output_list' => $self->{results}->{client_longest_output_list},
'client_biggest_input_buf' => $self->{results}->{client_biggest_input_buf}};
my $results = $options{custom}->get_info();
$self->{global} = {
connected_clients => $results->{connected_clients},
blocked_clients => $results->{blocked_clients},
client_longest_output_list => $results->{client_longest_output_list},
client_biggest_input_buf => $results->{client_biggest_input_buf},
};
}
1;

View File

@ -1,128 +0,0 @@
#
# Copyright 2017 Centreon (http://www.centreon.com/)
#
# Centreon is a full-fledged industry-strength solution that meets
# the needs in IT infrastructure and application monitoring for
# service performance.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
package apps::redis::cli::mode::cluster;
use base qw(centreon::plugins::mode);
use strict;
use warnings;
my $thresholds = {
global => [
['disabled', 'CRITICAL'],
['enabled', 'OK'],
],
};
my %map_status = (
0 => 'disabled',
1 => 'enabled',
);
sub new {
my ($class, %options) = @_;
my $self = $class->SUPER::new(package => __PACKAGE__, %options);
bless $self, $class;
$self->{version} = '1.0';
$options{options}->add_options(arguments =>
{
"threshold-overload:s@" => { name => 'threshold_overload' },
});
return $self;
}
sub check_options {
my ($self, %options) = @_;
$self->SUPER::init(%options);
$self->{overload_th} = {};
foreach my $val (@{$self->{option_results}->{threshold_overload}}) {
if ($val !~ /^(.*?),(.*)$/) {
$self->{output}->add_option_msg(short_msg => "Wrong threshold-overload option '" . $val . "'.");
$self->{output}->option_exit();
}
my ($section, $status, $filter) = ('global', $1, $2);
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 get_severity {
my ($self, %options) = @_;
my $status = 'UNKNOWN'; # default
if (defined($self->{overload_th}->{$options{section}})) {
foreach (@{$self->{overload_th}->{$options{section}}}) {
if ($options{value} =~ /$_->{filter}/i) {
$status = $_->{status};
return $status;
}
}
}
foreach (@{$thresholds->{$options{section}}}) {
if ($options{value} =~ /$$_[0]/i) {
$status = $$_[1];
return $status;
}
}
return $status;
}
sub run {
my ($self, %options) = @_;
$self->{redis} = $options{custom};
$self->{results} = $self->{redis}->get_info();
my $exit = $self->get_severity(section => 'global', value => $map_status{$items->{cluster_enabled}});
$self->{output}->output_add(severity => $exit, short_msg => sprintf("Cluster is '%s'", $map_status{$items->{cluster_enabled}}));
$self->{output}->display();
$self->{output}->exit();
}
1;
__END__
=head1 MODE
Check cluster status
=over 8
=item B<--threshold-overload>
Set to overload default threshold values (syntax: status,regexp)
Example: --threshold-overload='CRITICAL,disabled'
=back
=cut

View File

@ -21,16 +21,16 @@
package apps::redis::cli::mode::commands;
use base qw(centreon::plugins::templates::counter);
use Digest::MD5 qw(md5_hex);
use strict;
use warnings;
use Digest::MD5 qw(md5_hex);
sub set_counters {
my ($self, %options) = @_;
$self->{maps_counters_type} = [
{ name => 'global', type => 0, cb_prefix_output => 'prefix_output' }
{ name => 'global', type => 0, cb_prefix_output => 'prefix_output' },
];
$self->{maps_counters}->{global} = [
@ -76,13 +76,14 @@ sub new {
sub manage_selection {
my ($self, %options) = @_;
$self->{cache_name} = "redis_" . $self->{mode} . '_' . $self->{option_results}->{hostname} . '_' . md5_hex('all');
$self->{cache_name} = "redis_" . $self->{mode} . '_' . $options{custom}->get_connection_info() . '_' .
(defined($self->{option_results}->{filter_counters}) ? md5_hex($self->{option_results}->{filter_counters}) : md5_hex('all'));
$self->{redis} = $options{custom};
$self->{results} = $self->{redis}->get_info();
$self->{global} = { 'total_commands_processed' => $self->{results}->{total_commands_processed},
'instantaneous_ops_per_sec' => $self->{results}->{instantaneous_ops_per_sec}};
my $results = $options{custom}->get_info();
$self->{global} = {
total_commands_processed => $results->{total_commands_processed},
instantaneous_ops_per_sec => $results->{instantaneous_ops_per_sec},
};
}
1;

View File

@ -21,17 +21,17 @@
package apps::redis::cli::mode::connections;
use base qw(centreon::plugins::templates::counter);
use Digest::MD5 qw(md5_hex);
use strict;
use warnings;
use Digest::MD5 qw(md5_hex);
sub set_counters {
my ($self, %options) = @_;
$self->{maps_counters_type} = [
{ name => 'connections', type => 0, cb_prefix_output => 'prefix_connections_output' },
{ name => 'traffic', type => 0, cb_prefix_output => 'prefix_traffic_output' }
{ name => 'traffic', type => 0, cb_prefix_output => 'prefix_traffic_output' },
];
$self->{maps_counters}->{connections} = [
@ -59,7 +59,7 @@ sub set_counters {
output_template => 'Traffic In: %s %s/s',
per_second => 1, output_change_bytes => 2,
perfdatas => [
{ label => 'traffic_in', value => 'total_net_input_bytes_per_second', template => '%s', min => 0, unit => 'b/s' },
{ label => 'traffic_in', value => 'total_net_input_bytes_per_second', template => '%d', min => 0, unit => 'b/s' },
],
},
},
@ -68,7 +68,7 @@ sub set_counters {
output_template => 'Traffic Out: %s %s/s',
per_second => 1, output_change_bytes => 2,
perfdatas => [
{ label => 'traffic_out', value => 'total_net_output_bytes_per_second', template => '%s', min => 0, unit => 'b/s' },
{ label => 'traffic_out', value => 'total_net_output_bytes_per_second', template => '%d', min => 0, unit => 'b/s' },
],
},
},
@ -104,16 +104,20 @@ sub new {
sub manage_selection {
my ($self, %options) = @_;
$self->{cache_name} = "redis_" . $self->{mode} . '_' . $self->{option_results}->{hostname} . '_' . md5_hex('all');
$self->{cache_name} = "redis_" . $self->{mode} . '_' . $options{custom}->get_connection_info() . '_' .
(defined($self->{option_results}->{filter_counters}) ? md5_hex($self->{option_results}->{filter_counters}) : md5_hex('all'));
$self->{redis} = $options{custom};
$self->{results} = $self->{redis}->get_info();
my $results = $options{custom}->get_info();
$self->{connections} = { 'total_connections_received' => $self->{results}->{total_connections_received},
'rejected_connections' => $self->{results}->{rejected_connections}};
$self->{connections} = {
total_connections_received => $results->{total_connections_received},
rejected_connections => $results->{rejected_connections},
};
$self->{traffic} = { 'total_net_input_bytes' => $self->{results}->{total_net_input_bytes},
'total_net_output_bytes' => $self->{results}->{total_net_output_bytes}};
$self->{traffic} = {
total_net_input_bytes => $results->{total_net_input_bytes} * 8,
total_net_output_bytes => $results->{total_net_output_bytes} * 8,
};
}
1;

View File

@ -91,13 +91,14 @@ sub new {
sub manage_selection {
my ($self, %options) = @_;
$self->{redis} = $options{custom};
$self->{results} = $self->{redis}->get_info();
my $results = $options{custom}->get_info();
$self->{global} = { 'used_cpu_sys' => $self->{results}->{used_cpu_sys},
'used_cpu_user' => $self->{results}->{used_cpu_user},
'used_cpu_sys_children' => $self->{results}->{used_cpu_sys_children},
'used_cpu_user_children' => $self->{results}->{used_cpu_user_children}};
$self->{global} = {
used_cpu_sys => $results->{used_cpu_sys},
used_cpu_user => $results->{used_cpu_user},
used_cpu_sys_children => $results->{used_cpu_sys_children},
used_cpu_user_children => $results->{used_cpu_user_children},
};
}
1;

View File

@ -25,6 +25,8 @@ use base qw(centreon::plugins::templates::counter);
use strict;
use warnings;
my $instance_mode;
sub custom_usage_perfdata {
my ($self, %options) = @_;
@ -35,8 +37,6 @@ sub custom_usage_perfdata {
min => 0, max => $self->{result_values}->{total});
}
my $instance_mode;
sub custom_usage_threshold {
my ($self, %options) = @_;
@ -80,13 +80,13 @@ sub set_counters {
$self->{maps_counters_type} = [
{ name => 'used', type => 0 },
{ name => 'rss', type => 0 },
{ name => 'peak', type => 0 },
{ name => 'overhead', type => 0 },
{ name => 'startup', type => 0 },
{ name => 'dataset', type => 0 },
{ name => 'lua', type => 0 },
{ name => 'stats', type => 0, cb_prefix_output => 'prefix_stats_output' }
{ name => 'rss', type => 0, skipped_code => { -10 => 1 } },
{ name => 'peak', type => 0, skipped_code => { -10 => 1 } },
{ name => 'overhead', type => 0, skipped_code => { -10 => 1 } },
{ name => 'startup', type => 0, skipped_code => { -10 => 1 } },
{ name => 'dataset', type => 0, skipped_code => { -10 => 1 } },
{ name => 'lua', type => 0, skipped_code => { -10 => 1 } },
{ name => 'stats', type => 0, cb_prefix_output => 'prefix_stats_output', skipped_code => { -10 => 1 } },
];
$self->{maps_counters}->{used} = [
@ -225,31 +225,32 @@ sub check_options {
}
my $metrics = {
'used_memory' => { label => 'used', display => 'Used' },
'used_memory_rss' => { label => 'rss', display => 'Rss' },
'used_memory_peak' => { label => 'peak', display => 'Peak' },
'used_memory_overhead' => { label => 'overhead', display => 'Overhead' },
'used_memory_startup' => { label => 'startup', display => 'Startup' },
'used_memory_dataset' => { label => 'dataset', display => 'Dataset' },
'used_memory_lua' => { label => 'lua', display => 'Lua' },
used_memory => { label => 'used', display => 'Used' },
used_memory_rss => { label => 'rss', display => 'Rss' },
used_memory_peak => { label => 'peak', display => 'Peak' },
used_memory_overhead => { label => 'overhead', display => 'Overhead' },
used_memory_startup => { label => 'startup', display => 'Startup' },
used_memory_dataset => { label => 'dataset', display => 'Dataset' },
used_memory_lua => { label => 'lua', display => 'Lua' },
};
sub manage_selection {
my ($self, %options) = @_;
$self->{redis} = $options{custom};
$self->{results} = $self->{redis}->get_info();
foreach my $type (keys $metrics) {
$self->{$metrics->{$type}->{label}} = { 'display' => $metrics->{$type}->{display},
'label' => $metrics->{$type}->{label},
'used' => $self->{results}->{$type},
'total' => $self->{results}->{total_system_memory} };
my $results = $options{custom}->get_info();
foreach my $type (keys %$metrics) {
next if (!defined($results->{$type}));
$self->{$metrics->{$type}->{label}} = { display => $metrics->{$type}->{display},
label => $metrics->{$type}->{label},
used => $results->{$type},
total => $results->{total_system_memory} };
}
$self->{stats} = { 'mem_fragmentation_ratio' => $self->{results}->{mem_fragmentation_ratio},
'active_defrag_running' => $self->{results}->{active_defrag_running},
'lazyfree_pending_objects' => $self->{results}->{lazyfree_pending_objects} };
$self->{stats} = {
mem_fragmentation_ratio => $results->{mem_fragmentation_ratio},
active_defrag_running => $results->{active_defrag_running},
lazyfree_pending_objects => $results->{lazyfree_pending_objects},
};
}
1;

View File

@ -25,30 +25,24 @@ use base qw(centreon::plugins::templates::counter);
use strict;
use warnings;
my $thresholds = {
status => [
['fail', 'CRITICAL'],
['ok', 'OK'],
],
progress => [
['stopped', 'WARNING'],
['in progress', 'OK'],
],
};
my %map_status = (
0 => 'stopped',
1 => 'in progress',
);
my $instance_mode;
sub set_counters {
my ($self, %options) = @_;
$self->{maps_counters_type} = [
{ name => 'global', type => 0 }
{ name => 'global', type => 0, skipped_code => { -10 => 1 } },
];
$self->{maps_counters}->{global} = [
{ label => 'status', threshold => 0, set => {
key_values => [ { name => 'status' }, { name => 'progress_status' } ],
closure_custom_calc => $self->can('custom_status_calc'),
closure_custom_output => $self->can('custom_status_output'),
closure_custom_perfdata => sub { return 0; },
closure_custom_threshold_check => $self->can('custom_status_threshold'),
}
},
{ label => 'changes', set => {
key_values => [ { name => 'rdb_changes_since_last_save' } ],
output_template => 'Number of changes since the last dump: %s',
@ -93,6 +87,45 @@ sub set_counters {
];
}
sub custom_status_threshold {
my ($self, %options) = @_;
my $status = 'ok';
my $message;
eval {
local $SIG{__WARN__} = sub { $message = $_[0]; };
local $SIG{__DIE__} = sub { $message = $_[0]; };
if (defined($instance_mode->{option_results}->{critical_status}) && $instance_mode->{option_results}->{critical_status} ne '' &&
eval "$instance_mode->{option_results}->{critical_status}") {
$status = 'critical';
} elsif (defined($instance_mode->{option_results}->{warning_status}) && $instance_mode->{option_results}->{warning_status} ne '' &&
eval "$instance_mode->{option_results}->{warning_status}") {
$status = 'warning';
}
};
if (defined($message)) {
$self->{output}->output_add(long_msg => 'filter status issue: ' . $message);
}
return $status;
}
sub custom_status_output {
my ($self, %options) = @_;
my $msg = sprintf("RDB save status is '%s' [progress status: %s]", $self->{result_values}->{status}, $self->{result_values}->{progress_status});
return $msg;
}
sub custom_status_calc {
my ($self, %options) = @_;
$self->{result_values}->{status} = $options{new_datas}->{$self->{instance} . '_status'};
$self->{result_values}->{progress_status} = $options{new_datas}->{$self->{instance} . '_progress_status'};
return 0;
}
sub new {
my ($class, %options) = @_;
my $self = $class->SUPER::new(package => __PACKAGE__, %options);
@ -102,7 +135,8 @@ sub new {
$options{options}->add_options(arguments =>
{
"threshold-overload:s@" => { name => 'threshold_overload' },
"warning-status:s" => { name => 'warning_status', default => '%{sync_status} =~ /in progress/i' },
"critical-status:s" => { name => 'critical_status', default => '%{link_status} =~ /down/i' },
});
return $self;
@ -110,70 +144,41 @@ sub new {
sub check_options {
my ($self, %options) = @_;
$self->SUPER::init(%options);
$self->{overload_th} = {};
foreach my $val (@{$self->{option_results}->{threshold_overload}}) {
if ($val !~ /^(.*?),(.*?),(.*)$/) {
$self->{output}->add_option_msg(short_msg => "Wrong threshold-overload option '" . $val . "'.");
$self->{output}->option_exit();
}
my ($section, $status, $filter) = ($1, $2, $3);
if ($self->{output}->is_litteral_status(status => $status) == 0) {
$self->{output}->add_option_msg(short_msg => "Wrong threshold-overload status '" . $val . "'.");
$self->{output}->option_exit();
}
$self->{overload_th}->{$section} = [] if (!defined($self->{overload_th}->{$section}));
push @{$self->{overload_th}->{$section}}, {filter => $filter, status => $status};
}
$self->SUPER::check_options(%options);
$instance_mode = $self;
$self->change_macros();
}
sub get_severity {
sub change_macros {
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 (('warning_status', 'critical_status')) {
if (defined($self->{option_results}->{$_})) {
$self->{option_results}->{$_} =~ s/%\{(.*?)\}/\$self->{result_values}->{$1}/g;
}
}
foreach (@{$thresholds->{$options{section}}}) {
if ($options{value} =~ /$$_[0]/i) {
$status = $$_[1];
return $status;
}
}
return $status;
}
my %map_status = (
0 => 'stopped',
1 => 'in progress',
);
sub manage_selection {
my ($self, %options) = @_;
$self->{redis} = $options{custom};
$self->{results} = $self->{redis}->get_info();
my @exits;
push @exits, $self->get_severity(section => 'status', value => $self->{results}->{rdb_last_bgsave_status});
push @exits, $self->get_severity(section => 'progess', value => $map_status{$self->{results}->{rdb_bgsave_in_progress}});
$self->{output}->output_add(short_msg => sprintf("RDB save is in '%s' status", $self->{results}->{rdb_last_bgsave_status}));
$self->{output}->output_add(short_msg => sprintf("RDB save is '%s'", $map_status{$self->{results}->{rdb_bgsave_in_progress}}));
$self->{global} = { 'rdb_changes_since_last_save' => $self->{results}->{rdb_changes_since_last_save},
'rdb_last_save_time' => centreon::plugins::misc::change_seconds(value => time() - $self->{results}->{rdb_last_save_time}),
'rdb_last_save_time_sec' => time() - $self->{results}->{rdb_last_save_time},
'rdb_last_cow_size' => $self->{results}->{rdb_last_cow_size},
'rdb_last_bgsave_time' => $self->{results}->{rdb_last_bgsave_time_sec},
'rdb_current_bgsave_time' => $self->{results}->{rdb_current_bgsave_time_sec}};
my $exit = $self->{output}->get_most_critical(status => \@exits);
$self->{output}->output_add(severity => $exit);
my $results = $options{custom}->get_info();
$self->{global} = {
status => $results->{rdb_last_bgsave_status},
progress_status => $map_status{$results->{rdb_bgsave_in_progress}},
rdb_changes_since_last_save => $results->{rdb_changes_since_last_save},
rdb_last_save_time => centreon::plugins::misc::change_seconds(value => time() - $results->{rdb_last_save_time}),
rdb_last_save_time_sec => time() - $results->{rdb_last_save_time},
rdb_last_cow_size => $results->{rdb_last_cow_size},
rdb_last_bgsave_time => $results->{rdb_last_bgsave_time_sec},
rdb_current_bgsave_time => $results->{rdb_current_bgsave_time_sec}
};
}
1;
@ -182,55 +187,31 @@ __END__
=head1 MODE
Check RDB persistence status
Check RDB persistence status.
=over 8
=item B<--threshold-overload>
=item B<--warning-status>
Set to overload default threshold values (syntax: section,status,regexp)
Example: --threshold-overload='status,CRITICAL,ok'
Section can be: 'status', 'progress'
Set warning threshold for status (Default: '%{progress_status} =~ /in progress/i').
Can used special variables like: %{progress_status}, %{status}
=item B<--warning-changes>
=item B<--critical-status>
Warning threshold for number of changes since the last dump
Set critical threshold for status (Default: '%{status} =~ /fail/i').
Can used special variables like: %{progress_status}, %{status}
=item B<--critical-changes>
=item B<--warning-*>
Critical threshold for number of changes since the last dump
Threshold warning.
Can be: 'changes', 'last-save', 'save-size',
'last-save-duration', 'current-save-duration'.
=item B<--warning-last-save>
=item B<--critical-*>
Warning threshold for time since last successful save (in second)
=item B<--critical-last-save>
Critical threshold for time since last successful save (in second)
=item B<--warning-save-size>
Warning threshold for size of last save (in bytes)
=item B<--critical-save-size>
Critical threshold for size of last save (in bytes)
=item B<--warning-last-save-duration>
Warning threshold for duration of last save (in second)
=item B<--critical-last-save-duration>
Critical threshold for duration of last save (in second)
=item B<--warning-current-save-duration>
Warning threshold for current of last save (in second)
=item B<--critical-current-save-duration>
Critical threshold for current of last save (in second)
Threshold critical.
Can be: 'changes', 'last-save', 'save-size',
'last-save-duration', 'current-save-duration'.
=back

View File

@ -25,32 +25,26 @@ use base qw(centreon::plugins::templates::counter);
use strict;
use warnings;
my $thresholds = {
link => [
['down', 'CRITICAL'],
['up', 'OK'],
],
sync => [
['stopped', 'OK'],
['in progress', 'WARNING'],
],
};
my %map_sync = (
0 => 'stopped',
1 => 'in progress',
);
my $instance_mode;
sub set_counters {
my ($self, %options) = @_;
$self->{maps_counters_type} = [
{ name => 'global', type => 0 },
{ name => 'master', type => 0 },
{ name => 'slave', type => 0 }
{ name => 'global', type => 0, skipped_code => { -10 => 1 } },
{ name => 'master', type => 0, skipped_code => { -10 => 1 } },
{ name => 'slave', type => 0, skipped_code => { -10 => 1 } },
];
$self->{maps_counters}->{global} = [
{ label => 'status', threshold => 0, set => {
key_values => [ { name => 'link_status' }, { name => 'sync_status' }, { name => 'role' }, { name => 'cluster_state' } ],
closure_custom_calc => $self->can('custom_status_calc'),
closure_custom_output => $self->can('custom_status_output'),
closure_custom_perfdata => sub { return 0; },
closure_custom_threshold_check => $self->can('custom_status_threshold'),
}
},
{ label => 'connected-slaves', set => {
key_values => [ { name => 'connected_slaves' } ],
output_template => 'Number of connected slaves: %s',
@ -108,6 +102,51 @@ sub set_counters {
];
}
sub custom_status_threshold {
my ($self, %options) = @_;
my $status = 'ok';
my $message;
eval {
local $SIG{__WARN__} = sub { $message = $_[0]; };
local $SIG{__DIE__} = sub { $message = $_[0]; };
if (defined($instance_mode->{option_results}->{critical_status}) && $instance_mode->{option_results}->{critical_status} ne '' &&
eval "$instance_mode->{option_results}->{critical_status}") {
$status = 'critical';
} elsif (defined($instance_mode->{option_results}->{warning_status}) && $instance_mode->{option_results}->{warning_status} ne '' &&
eval "$instance_mode->{option_results}->{warning_status}") {
$status = 'warning';
}
};
if (defined($message)) {
$self->{output}->output_add(long_msg => 'filter status issue: ' . $message);
}
return $status;
}
sub custom_status_output {
my ($self, %options) = @_;
my $msg = sprintf("Node role is '%s' [cluster: %s]", $self->{result_values}->{role}, $self->{result_values}->{cluster_state});
if ($self->{result_values}->{role} eq 'slave') {
$msg .= sprintf(" [link status: %s] [sync status: %s]",
$self->{result_values}->{link_status}, $self->{result_values}->{sync_status});
}
return $msg;
}
sub custom_status_calc {
my ($self, %options) = @_;
$self->{result_values}->{role} = $options{new_datas}->{$self->{instance} . '_role'};
$self->{result_values}->{sync_status} = $options{new_datas}->{$self->{instance} . '_sync_status'};
$self->{result_values}->{link_status} = $options{new_datas}->{$self->{instance} . '_link_status'};
$self->{result_values}->{cluster_state} = $options{new_datas}->{$self->{instance} . '_cluster_state'};
return 0;
}
sub new {
my ($class, %options) = @_;
my $self = $class->SUPER::new(package => __PACKAGE__, %options);
@ -117,7 +156,8 @@ sub new {
$options{options}->add_options(arguments =>
{
"threshold-overload:s@" => { name => 'threshold_overload' },
"warning-status:s" => { name => 'warning_status', default => '%{sync_status} =~ /in progress/i' },
"critical-status:s" => { name => 'critical_status', default => '%{link_status} =~ /down/i' },
});
return $self;
@ -125,79 +165,52 @@ sub new {
sub check_options {
my ($self, %options) = @_;
$self->SUPER::init(%options);
$self->{overload_th} = {};
foreach my $val (@{$self->{option_results}->{threshold_overload}}) {
if ($val !~ /^(.*?),(.*?),(.*)$/) {
$self->{output}->add_option_msg(short_msg => "Wrong threshold-overload option '" . $val . "'.");
$self->{output}->option_exit();
}
my ($section, $status, $filter) = ($1, $2, $3);
if ($self->{output}->is_litteral_status(status => $status) == 0) {
$self->{output}->add_option_msg(short_msg => "Wrong threshold-overload status '" . $val . "'.");
$self->{output}->option_exit();
}
$self->{overload_th}->{$section} = [] if (!defined($self->{overload_th}->{$section}));
push @{$self->{overload_th}->{$section}}, {filter => $filter, status => $status};
}
$self->SUPER::check_options(%options);
$instance_mode = $self;
$self->change_macros();
}
sub get_severity {
sub change_macros {
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 (('warning_status', 'critical_status')) {
if (defined($self->{option_results}->{$_})) {
$self->{option_results}->{$_} =~ s/%\{(.*?)\}/\$self->{result_values}->{$1}/g;
}
}
foreach (@{$thresholds->{$options{section}}}) {
if ($options{value} =~ /$$_[0]/i) {
$status = $$_[1];
return $status;
}
}
return $status;
}
my %map_sync = (
0 => 'stopped',
1 => 'in progress',
);
my %map_cluster_state = (
0 => 'disabled',
1 => 'enabled',
);
sub manage_selection {
my ($self, %options) = @_;
$self->{redis} = $options{custom};
$self->{results} = $self->{redis}->get_info();
my @exits;
my $results = $options{custom}->get_info();
$self->{output}->output_add(short_msg => sprintf("Node is '%s'", $self->{results}->{role}));
$self->{global} = {
connected_slaves => $results->{connected_slaves},
role => $results->{role},
cluster_state => defined($results->{cluster_enabled}) ? $map_cluster_state{$results->{cluster_enabled}} : '-',
link_status => defined($results->{master_link_status}) ? $results->{master_link_status} : '-',
sync_status => defined($results->{master_sync_in_progress}) ? $map_sync{$results->{master_sync_in_progress}} : '-',
};
$self->{global} = { 'connected_slaves' => $self->{results}->{connected_slaves} };
if ($self->{results}->{role} =~ /master/) {
$self->{master} = { 'master_repl_offset' => $self->{results}->{master_repl_offset} };
} elsif ($self->{results}->{role} =~ /slave/) {
$self->{output}->output_add(short_msg => sprintf("Link with master '%s:%s' is '%s', Sync is '%s'",
$self->{results}->{master_host},
$self->{results}->{master_port},
$self->{results}->{master_link_status},
$map_sync{$self->{results}->{master_sync_in_progress}}));
push @exits, $self->get_severity(section => 'link', value => $self->{results}->{master_link_status});
push @exits, $self->get_severity(section => 'sync', value => $map_sync{$self->{results}->{master_sync_in_progress}});
$self->{slave} = { 'master_last_io_seconds_ago' => $self->{results}->{master_last_io_seconds_ago},
'slave_repl_offset' => $self->{results}->{slave_repl_offset},
'slave_priority' => $self->{results}->{slave_priority},
'slave_read_only' => $self->{results}->{slave_read_only} };
}
my $exit = $self->{output}->get_most_critical(status => \@exits);
$self->{output}->output_add(severity => $exit);
$self->{master} = { master_repl_offset => $results->{master_repl_offset} };
$self->{slave} = {
master_last_io_seconds_ago => $results->{master_last_io_seconds_ago},
slave_repl_offset => $results->{slave_repl_offset},
slave_priority => $results->{slave_priority},
slave_read_only => $results->{slave_read_only},
};
}
1;
@ -206,55 +219,31 @@ __END__
=head1 MODE
Check replication status
Check replication status.
=over 8
=item B<--threshold-overload>
=item B<--warning-status>
Set to overload default threshold values (syntax: section,status,regexp)
Example: --threshold-overload='link,OK,down'
Section can be: 'link', 'sync'
Set warning threshold for status (Default: '%{sync_status} =~ /in progress/i').
Can used special variables like: %{sync_status}, %{link_status}, %{cluster_state}
=item B<--warning-connected-slaves>
=item B<--critical-status>
Warning threshold for number of connected slave
Set critical threshold for status (Default: '%{link_status} =~ /down/i').
Can used special variables like: %{sync_status}, %{link_status}, %{cluster_state}
=item B<--critical-connected-slaves>
=item B<--warning-*>
Critical threshold for number of connected slave
Threshold warning.
Can be: 'connected-slaves', 'master-repl-offset',
'master-last-io', 'slave-priority', 'slave-read-only'.
=item B<--warning-master-repl-offset>
=item B<--critical-*>
Warning threshold for master replication offset (in second)
=item B<--critical-master-repl-offset>
Critical threshold for master replication offset (in second)
=item B<--warning-master-last-io>
Warning threshold for last interaction with master (in second)
=item B<--critical-master-last-io>
Critical threshold for last interaction with master (in second)
=item B<--warning-slave-priority>
Warning threshold for slave priority
=item B<--critical-slave-priority>
Critical threshold for slave priority
=item B<--warning-slave-read-only>
Warning threshold for slave being in read-only
=item B<--critical-slave-read-only>
Critical threshold for slave being in read-only
Threshold critical.
Can be: 'connected-slaves', 'master-repl-offset',
'master-last-io', 'slave-priority', 'slave-read-only'.
=back

View File

@ -32,7 +32,6 @@ sub new {
$self->{version} = '1.0';
%{$self->{modes}} = (
'clients' => 'apps::redis::cli::mode::clients',
'cluster' => 'apps::redis::cli::mode::cluster',
'commands' => 'apps::redis::cli::mode::commands',
'connections' => 'apps::redis::cli::mode::connections',
'cpu' => 'apps::redis::cli::mode::cpu',