enh(centreon/sql): add execution-time mode (#4614)

This commit is contained in:
qgarnier 2023-11-02 17:54:02 +01:00 committed by GitHub
parent de039a6a5c
commit a33b359a40
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 214 additions and 50 deletions

View File

@ -28,15 +28,15 @@ use centreon::plugins::statefile;
sub new {
my ($class, %options) = @_;
my $self = $class->SUPER::new(package => __PACKAGE__, %options);
my $self = $class->SUPER::new(package => __PACKAGE__, %options, force_new_perfdata => 1);
bless $self, $class;
$options{options}->add_options(arguments =>
{
"warning:s" => { name => 'warning' },
"critical:s" => { name => 'critical' },
"centreon-storage-database:s" => { name => 'centreon_storage_database', default => 'centreon_storage' },
});
$options{options}->add_options(arguments => {
'warning:s' => { name => 'warning' },
'critical:s' => { name => 'critical' },
'centreon-storage-database:s' => { name => 'centreon_storage_database', default => 'centreon_storage' }
});
$self->{statefile_cache} = centreon::plugins::statefile->new(%options);
return $self;
@ -67,19 +67,26 @@ sub execute {
while ((my $row = $self->{sql}->fetchrow_hashref())) {
$self->{output}->output_add(long_msg => sprintf("%d sent notifications from %s", $row->{num}, $row->{name}));
$total_notifications += $row->{num};
$self->{output}->perfdata_add(label => 'notifications_' . $row->{name},
value => $row->{num},
min => 0);
$self->{output}->perfdata_add(
nlabel => 'notifications.sent.count',
instances => $row->{name},
value => $row->{num},
min => 0
);
}
my $exit_code = $self->{perfdata}->threshold_check(value => $total_notifications, threshold => [ { label => 'critical', exit_litteral => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]);
$self->{output}->output_add(severity => $exit_code,
short_msg => sprintf("%d total sent notifications", $total_notifications));
$self->{output}->perfdata_add(label => 'total',
value => $total_notifications,
warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning'),
critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical'),
min => 0);
$self->{output}->output_add(
severity => $exit_code,
short_msg => sprintf("%d total sent notifications", $total_notifications)
);
$self->{output}->perfdata_add(
nlabel => 'notifications.sent.count',
value => $total_notifications,
warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning'),
critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical'),
min => 0
);
}
sub run {
@ -93,8 +100,10 @@ sub run {
$self->{statefile_cache}->write(data => $new_datas);
if (!defined($old_timestamp)) {
$self->{output}->output_add(severity => 'OK',
short_msg => "Buffer creation...");
$self->{output}->output_add(
severity => 'OK',
short_msg => "Buffer creation..."
);
} else {
$self->execute(time => $old_timestamp);
}

View File

@ -28,13 +28,13 @@ use centreon::plugins::statefile;
sub new {
my ($class, %options) = @_;
my $self = $class->SUPER::new(package => __PACKAGE__, %options);
my $self = $class->SUPER::new(package => __PACKAGE__, %options, force_new_perfdata => 1);
bless $self, $class;
$options{options}->add_options(arguments => {
'warning:s' => { name => 'warning' },
'critical:s' => { name => 'critical' },
'centreon-storage-database:s' => { name => 'centreon_storage_database', default => 'centreon_storage' },
'centreon-storage-database:s' => { name => 'centreon_storage_database', default => 'centreon_storage' }
});
$self->{statefile_cache} = centreon::plugins::statefile->new(%options);
@ -68,10 +68,10 @@ sub execute {
while ((my $row = $self->{sql}->fetchrow_hashref())) {
if (!defined($total_problems_by_poller->{$row->{name}})) {
$total_problems_by_poller->{$row->{name}} = {
'0_1' => { label_perf => 'host_down', label => 'host down', num => 0 },
'1_1' => { label_perf => 'service_warning', label => 'service warning', num => 0 },
'1_2' => { label_perf => 'service_critical', label => 'service critical', num => 0 },
'1_3' => { label_perf => 'service_unknown', label => 'service unknown', num => 0 }
'0_1' => { label_perf => 'hosts.down.count', label => 'host down', num => 0 },
'1_1' => { label_perf => 'services.warning.count', label => 'service warning', num => 0 },
'1_2' => { label_perf => 'services.critical.count', label => 'service critical', num => 0 },
'1_3' => { label_perf => 'services.unknown.count', label => 'service unknown', num => 0 }
};
}
@ -98,8 +98,10 @@ sub execute {
$poller
)
);
$self->{output}->perfdata_add(
label => $total_problems_by_poller->{$poller}->{$id}->{label_perf} . "_" . $poller,
label => $total_problems_by_poller->{$poller}->{$id}->{label_perf},
instances => $poller,
value => $total_problems_by_poller->{$poller}->{$id}->{num},
min => 0
);
@ -107,21 +109,25 @@ sub execute {
}
my $exit_code = $self->{perfdata}->threshold_check(value => $total_problems->{total}, threshold => [ { label => 'critical', exit_litteral => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]);
$self->{output}->output_add(severity => $exit_code,
short_msg => sprintf("%d total problems", $total_problems->{total}));
$self->{output}->output_add(
severity => $exit_code,
short_msg => sprintf("%d total problems", $total_problems->{total})
);
$self->{output}->perfdata_add(
label => 'total',
nlabel => 'total.outage.count',
value => $total_problems->{total},
warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning'),
critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical'),
min => 0
);
$self->{output}->perfdata_add(
label => 'total_hosts',
nlabel => 'hosts.outage.count',
value => $total_problems->{hosts},
min => 0);
min => 0
);
$self->{output}->perfdata_add(
label => 'total_services',
nlabel => 'services.outage.count',
value => $total_problems->{services},
min => 0
);
@ -137,8 +143,10 @@ sub run {
$self->{statefile_cache}->write(data => $new_datas);
if (!defined($old_timestamp)) {
$self->{output}->output_add(severity => 'OK',
short_msg => "Buffer creation...");
$self->{output}->output_add(
severity => 'OK',
short_msg => "Buffer creation..."
);
} else {
$self->execute(time => $old_timestamp);
}

View File

@ -0,0 +1,140 @@
#
# Copyright 2023 Centreon (http://www.centreon.com/)
#
# Centreon is a full-fledged industry-strength solution that meets
# the needs in IT infrastructure and application monitoring for
# service performance.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
package apps::centreon::sql::mode::executiontime;
use base qw(centreon::plugins::templates::counter);
use strict;
use warnings;
sub custom_value_output {
my ($self, %options) = @_;
return sprintf(
"Service '%s' of host '%s' execution time is '%.2fs'",
$self->{result_values}->{description},
$self->{result_values}->{name},
$self->{result_values}->{execution_time}
);
}
sub set_counters {
my ($self, %options) = @_;
$self->{maps_counters_type} = [
{ name => 'global', type => 0 },
{ name => 'services', type => 1 }
];
$self->{maps_counters}->{global} = [
{ label => 'count', nlabel => 'services.execution.exceed.count', set => {
key_values => [ { name => 'count' } ],
output_template => 'Number of services exceeding execution time: %s',
perfdatas => [
{ template => '%s', min => 0 }
]
}
}
];
$self->{maps_counters}->{services} = [
{ label => 'list', set => {
key_values => [ { name => 'description' }, { name => 'name' } , { name => 'execution_time' } ],
closure_custom_output => $self->can('custom_value_output'),
closure_custom_perfdata => sub { return 0; }
}
}
];
}
sub new {
my ($class, %options) = @_;
my $self = $class->SUPER::new(package => __PACKAGE__, %options, force_new_perfdata => 1);
bless $self, $class;
$options{options}->add_options(arguments => {
'filter-poller:s' => { name => 'filter_poller' },
'centreon-storage-database:s' => { name => 'centreon_storage_database', default => 'centreon_storage' },
'execution-time:s' => { name => 'execution_time', default => '20' }
});
return $self;
}
sub manage_selection {
my ($self, %options) = @_;
$options{sql}->connect();
$options{sql}->query(
query => 'SELECT h.name, s.description, s.execution_time
FROM ' . $self->{option_results}->{centreon_storage_database} . '.services s, ' . $self->{option_results}->{centreon_storage_database} . '.hosts h
WHERE s.execution_time > ' . $self->{option_results}->{execution_time} . '
AND h.enabled = 1
AND (h.name NOT LIKE "\_Module\_%" OR h.name LIKE "\_Module\_Meta%")
AND s.enabled = 1
AND h.host_id = s.host_id'
);
$self->{global}->{count} = 0;
$self->{services} = {};
while ((my $row = $options{sql}->fetchrow_hashref())) {
if (defined($self->{option_results}->{filter_poller}) && $self->{option_results}->{filter_poller} ne '' &&
$row->{poller} !~ /$self->{option_results}->{filter_poller}/) {
$self->{output}->output_add(long_msg => "skipping '" . $row->{self} . "': no matching filter.", debug => 1);
next;
}
$self->{global}->{count}++;
$self->{services}->{ $row->{name} . "-" . $row->{description} } = $row;
}
}
1;
__END__
=head1 MODE
Check the number of services exceeding defined execution time.
=over 8
=item B<--execution-time>
Set the number of seconds which defines the
limit of execution time (default: '20').
=item B<--centreon-storage-database>
Centreon storage database name (default: 'centreon_storage').
=item B<--filter-poller>
Filter by poller name (regexp can be used).
=item B<--warning-count> B<--critical-count>
Thresholds on the number of services exceeding
defined execution time.
=back
=cut

View File

@ -31,13 +31,12 @@ sub new {
my $self = $class->SUPER::new(package => __PACKAGE__, %options);
bless $self, $class;
$options{options}->add_options(arguments =>
{
"tablename:s@" => { name => 'tablename' },
"timezone:s" => { name => 'timezone' },
"warning:s" => { name => 'warning' },
"critical:s" => { name => 'critical' },
});
$options{options}->add_options(arguments => {
"tablename:s@" => { name => 'tablename' },
"timezone:s" => { name => 'timezone' },
"warning:s" => { name => 'warning' },
"critical:s" => { name => 'critical' }
});
return $self;
}
@ -70,24 +69,30 @@ sub run {
$self->{sql}->connect();
$self->{output}->output_add(severity => 'OK',
short_msg => sprintf("All table partitions are up to date"));
$self->{output}->output_add(
severity => 'OK',
short_msg => sprintf("All table partitions are up to date")
);
foreach my $value (@{$self->{option_results}->{tablename}}) {
next if ($value eq '');
if ($value !~ /(\S+)\.(\S+)/) {
$self->{output}->output_add(severity => 'UNKNOWN',
short_msg => sprintf("Wrong table name '%s'", $value));
$self->{output}->output_add(
severity => 'UNKNOWN',
short_msg => sprintf("Wrong table name '%s'", $value)
);
next;
}
my ($database, $table) = ($1, $2);
$self->{sql}->query(query => "SELECT MAX(CONVERT(PARTITION_DESCRIPTION, SIGNED INTEGER)) as lastPart FROM INFORMATION_SCHEMA.PARTITIONS WHERE TABLE_NAME='" . $table . "' AND TABLE_SCHEMA='" . $database . "' GROUP BY TABLE_NAME;");
my ($last_time) = $self->{sql}->fetchrow_array();
if (!defined($last_time)) {
$self->{output}->output_add(severity => 'UNKNOWN',
short_msg => sprintf("Couldn't get partition infos for table '%s'", $value));
$self->{output}->output_add(
severity => 'UNKNOWN',
short_msg => sprintf("Couldn't get partition infos for table '%s'", $value)
);
next;
}
my $retention_forward_current = 0;
my ($day,$month,$year) = (localtime(time))[3,4,5];
my $current_time = mktime(0, 0, 0, $day, $month, $year);
@ -99,8 +104,10 @@ sub run {
$self->{output}->output_add(long_msg => sprintf("Table '%s' last partition date is %s (current retention forward in days: %s)", $value, scalar(localtime($last_time)), $retention_forward_current));
my $exit = $self->{perfdata}->threshold_check(value => $retention_forward_current, threshold => [ { label => 'critical', exit_litteral => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]);
if (!$self->{output}->is_status(value => $exit, compare => 'ok', litteral => 1)) {
$self->{output}->output_add(severity => $exit,
short_msg => sprintf("Partitions for table '%s' are not up to date (current retention forward in days: %s)", $value, $retention_forward_current));
$self->{output}->output_add(
severity => $exit,
short_msg => sprintf("Partitions for table '%s' are not up to date (current retention forward in days: %s)", $value, $retention_forward_current)
);
}
}