From 65f64d271269d01bb7f3b680d775f376733103a7 Mon Sep 17 00:00:00 2001 From: garnier-quentin Date: Thu, 4 Nov 2021 10:38:37 +0100 Subject: [PATCH] wip --- centreon-plugins/database/db2/dbi.pm | 17 ++ .../database/db2/mode/connectedusers.pm | 91 ++++---- .../database/db2/mode/databaselogs.pm | 194 ++++++++++++++++++ .../database/db2/mode/databaseusage.pm | 182 ++++++++++++++++ centreon-plugins/database/db2/plugin.pm | 10 +- 5 files changed, 447 insertions(+), 47 deletions(-) create mode 100644 centreon-plugins/database/db2/mode/databaselogs.pm create mode 100644 centreon-plugins/database/db2/mode/databaseusage.pm diff --git a/centreon-plugins/database/db2/dbi.pm b/centreon-plugins/database/db2/dbi.pm index 434c07221..01233ba29 100644 --- a/centreon-plugins/database/db2/dbi.pm +++ b/centreon-plugins/database/db2/dbi.pm @@ -37,6 +37,23 @@ sub connect { $self->SUPER::connect(%options); } +sub get_dbh { + my ($self, %options) = @_; + + return $self->{instance}; +} + +sub get_database_name { + my ($self, %options) = @_; + + my $dbname = 'unknown'; + $dbname = $1 if ($self->{data_source} =~ /DATABASE=([^;]*?)/i); + $dbname = $1 if ($self->{data_source} =~ /DBI:DB2:(.*)/); + $dbname =~ s/^\s+//g; + $dbname =~ s/\s+$//g; + return $dbname; +} + 1; __END__ diff --git a/centreon-plugins/database/db2/mode/connectedusers.pm b/centreon-plugins/database/db2/mode/connectedusers.pm index 761bafc13..d7fe9b944 100644 --- a/centreon-plugins/database/db2/mode/connectedusers.pm +++ b/centreon-plugins/database/db2/mode/connectedusers.pm @@ -20,59 +20,63 @@ package database::db2::mode::connectedusers; -use base qw(centreon::plugins::mode); +use base qw(centreon::plugins::templates::counter); use strict; use warnings; +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'global', type => 0 } + ]; + + $self->{maps_counters}->{global} = [ + { label => 'connected', nlabel => 'users.connected.count', set => { + key_values => [ { name => 'connected' } ], + output_template => 'connected users: %d', + perfdatas => [ + { template => '%d', min => 0 } + ] + } + } + ]; +} + 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', }, + + $options{options}->add_options(arguments => { + 'filter-appl-name:s' => { name => 'filter_appl_name' } }); return $self; } -sub check_options { +sub manage_selection { 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(); + $options{sql}->connect(); + $options{sql}->query(query => q{ + SELECT + appl_name + FROM + sysibmadm.applications + }); + + $self->{global} = { connected => 0 }; + while (my $row = $options{sql}->fetchrow_arrayref()) { + if (defined($self->{option_results}->{filter_appl_name}) && $self->{option_results}->{filter_appl_name} ne '' && + $row->[0] !~ /$self->{option_results}->{filter_appl_name}/) { + $self->{output}->output_add(long_msg => "skipping '" . $row->[0] . "': no matching filter.", debug => 1); + next; + } + + $self->{global}->{connected}++; } - 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) = @_; - # $options{sql} = sqlmode object - $self->{sql} = $options{sql}; - - $self->{sql}->connect(); - $self->{sql}->query(query => q{SELECT COUNT(*) FROM v$session WHERE type = 'USER'}); - my $users = $self->{sql}->fetchrow_array(); - $self->{sql}->disconnect(); - - my $exit_code = $self->{perfdata}->threshold_check(value => $users, threshold => [ { label => 'critical', 'exit_litteral' => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]); - $self->{output}->output_add(severity => $exit_code, - short_msg => sprintf("%i Connected user(s).", $users)); - $self->{output}->perfdata_add(label => 'connected_users', - value => $users, - 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; @@ -81,17 +85,18 @@ __END__ =head1 MODE -Check Oracle connected users. +Check connected users. =over 8 -=item B<--warning> +=item B<--filter-appl-name> -Threshold warning. +Filter users by application name (Can be a regex). -=item B<--critical> +=item B<--warning-*> B<--critical-*> -Threshold critical. +Thresholds. +Can be: 'connected'. =back diff --git a/centreon-plugins/database/db2/mode/databaselogs.pm b/centreon-plugins/database/db2/mode/databaselogs.pm new file mode 100644 index 000000000..15e6fa55c --- /dev/null +++ b/centreon-plugins/database/db2/mode/databaselogs.pm @@ -0,0 +1,194 @@ +# +# Copyright 2021 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 database::db2::mode::databaseusage; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; + +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}); + return sprintf( + 'usage total: %s used: %s (%.2f%%) free: %s (%.2f%%)', + $self->{result_values}->{partition}, + $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} + ); +} + +sub custom_usage_perfdata { + my ($self, %options) = @_; + + $self->{output}->perfdata_add( + nlabel => $self->{nlabel}, + unit => 'B', + instances => [$self->{result_values}->{dbname}, $self->{result_values}->{partition}], + value => $self->{result_values}->{used}, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{thlabel}), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{thlabel}), + min => 0, + max => $self->{result_values}->{total} + ); +} + +sub custom_usage_free_perfdata { + my ($self, %options) = @_; + + $self->{output}->perfdata_add( + nlabel => $self->{nlabel}, + unit => 'B', + instances => [$self->{result_values}->{dbname}, $self->{result_values}->{partition}], + value => $self->{result_values}->{free}, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{thlabel}), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{thlabel}), + min => 0, + max => $self->{result_values}->{total} + ); +} + +sub custom_usage_prct_perfdata { + my ($self, %options) = @_; + + $self->{output}->perfdata_add( + nlabel => $self->{nlabel}, + unit => '%', + instances => [$self->{result_values}->{dbname}, $self->{result_values}->{partition}], + value => $self->{result_values}->{prct_used}, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{thlabel}), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{thlabel}), + min => 0, + max => 100 + ); +} + +sub prefix_log_output { + my ($self, %options) = @_; + + return sprintf( + "database '%s' log '%s' ", + $options{instance_value}->{dbname}, + $options{instance_value}->{partition} + ); +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'logs', type => 1, cb_prefix_output => 'prefix_log_output', message_multiple => 'All database logs are ok', } + ]; + + $self->{maps_counters}->{logs} = [ + { label => 'log-usage', nlabel => 'database.log.usage.bytes', set => { + key_values => [ + { name => 'used' }, { name => 'free' }, + { name => 'prct_used' }, { name => 'prct_free' }, + { name => 'total' }, { name => 'dbname' }, { name => 'partition' } + ], + closure_custom_output => $self->can('custom_usage_output'), + closure_custom_perfdata => $self->can('custom_usage_perfdata') + } + }, + { label => 'log-usage-free', nlabel => 'database.log.free.bytes', display_ok => 0, set => { + key_values => [ + { name => 'free' }, { name => 'used' }, + { name => 'prct_used' }, { name => 'prct_free' }, + { name => 'total' }, { name => 'dbname' }, { name => 'partition' } + ], + closure_custom_output => $self->can('custom_usage_output'), + closure_custom_perfdata => $self->can('custom_usage_free_perfdata') + } + }, + { label => 'log-usage-prct', nlabel => 'database.log.usage.percentage', display_ok => 0, set => { + key_values => [ + { name => 'prct_used' }, { name => 'used' }, + { name => 'free' }, { name => 'prct_free' }, + { name => 'total' }, { name => 'dbname' }, { name => 'partition' } + ], + closure_custom_output => $self->can('custom_usage_output'), + closure_custom_perfdata => $self->can('custom_usage_prct_perfdata') + } + } + ]; +} + +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 => {}); + + return $self; +} + +sub manage_selection { + my ($self, %options) = @_; + + $options{sql}->connect(); + $options{sql}->query(query => q{ + SELECT + dbpartitionnum, total_log_used_kb, total_log_available_kb + FROM + sysibmadm.log_utilization + }); + + my $dbname = $options{sql}->get_database_name(); + $self->{logs} = {}; + while (my $row = $options{sql}->fetchrow_arrayref()) { + my $used = $row->[1] * 1024; + my $total = $used + ($row->[2] * 1024); + $self->{logs}->{ $row->[0] } = { + dbname => $dbname, + partition => $row->[0], + total => $total, + used => $used, + free => $total - $used, + prct_used => $used * 100 / $total, + prct_free => 100 - ($used * 100 / $total) + }; + } +} + +1; + +__END__ + +=head1 MODE + +Check database logs utilization. + +=over 8 + +=item B<--warning-*> B<--critical-*> + +Thresholds. +Can be: 'usage', 'usage-free', 'usage-prct'. + +=back + +=cut diff --git a/centreon-plugins/database/db2/mode/databaseusage.pm b/centreon-plugins/database/db2/mode/databaseusage.pm new file mode 100644 index 000000000..488e7227b --- /dev/null +++ b/centreon-plugins/database/db2/mode/databaseusage.pm @@ -0,0 +1,182 @@ +# +# Copyright 2021 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 database::db2::mode::databaseusage; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; +use DBD::DB2::Constants; + +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}); + return sprintf( + 'space 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} + ); +} + +sub custom_usage_perfdata { + my ($self, %options) = @_; + + $self->{output}->perfdata_add( + nlabel => $self->{nlabel}, + unit => 'B', + instances => $self->{result_values}->{dbname}, + value => $self->{result_values}->{used}, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{thlabel}), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{thlabel}), + min => 0, + max => $self->{result_values}->{total} + ); +} + +sub custom_usage_free_perfdata { + my ($self, %options) = @_; + + $self->{output}->perfdata_add( + nlabel => $self->{nlabel}, + unit => 'B', + instances => $self->{result_values}->{dbname}, + value => $self->{result_values}->{free}, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{thlabel}), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{thlabel}), + min => 0, + max => $self->{result_values}->{total} + ); +} + +sub custom_usage_prct_perfdata { + my ($self, %options) = @_; + + $self->{output}->perfdata_add( + nlabel => $self->{nlabel}, + unit => '%', + instances => $self->{result_values}->{dbname}, + value => $self->{result_values}->{prct_used}, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{thlabel}), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{thlabel}), + min => 0, + max => 100 + ); +} + +sub prefix_output { + my ($self, %options) = @_; + + return sprintf( + "database '%s' ", + $options{instance_value}->{dbname} + ); +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'global', type => 0, cb_prefix_output => 'prefix_output' } + ]; + + $self->{maps_counters}->{global} = [ + { label => 'space-usage', nlabel => 'database.space.usage.bytes', set => { + key_values => [ { name => 'used' }, { name => 'free' }, { name => 'prct_used' }, { name => 'prct_free' }, { name => 'total' }, { name => 'dbname' } ], + closure_custom_output => $self->can('custom_usage_output'), + closure_custom_perfdata => $self->can('custom_usage_perfdata') + } + }, + { label => 'space-usage-free', nlabel => 'database.space.free.bytes', display_ok => 0, set => { + key_values => [ { name => 'free' }, { name => 'used' }, { name => 'prct_used' }, { name => 'prct_free' }, { name => 'total' }, { name => 'dbname' } ], + closure_custom_output => $self->can('custom_usage_output'), + closure_custom_perfdata => $self->can('custom_usage_free_perfdata') + } + }, + { label => 'space-usage-prct', nlabel => 'database.space.usage.percentage', display_ok => 0, set => { + key_values => [ { name => 'prct_used' }, { name => 'used' }, { name => 'free' }, { name => 'prct_free' }, { name => 'total' }, { name => 'dbname' } ], + closure_custom_output => $self->can('custom_usage_output'), + closure_custom_perfdata => $self->can('custom_usage_prct_perfdata') + } + } + ]; +} + +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 => {}); + + return $self; +} + +sub manage_selection { + my ($self, %options) = @_; + + $options{sql}->connect(); + my $dbh = $options{sql}->get_dbh(); + + my ($snapshot_timestamp, $db_size, $db_capacity) = (0, 0, 0); + my $sth = $dbh->prepare(q{ + CALL SYSPROC.GET_DBSIZE_INFO(?, ?, ?, 0) + }); + $sth->bind_param_inout(1, \$snapshot_timestamp, 30, { db2_param_type=>SQL_PARAM_OUTPUT() }); + $sth->bind_param_inout(2, \$db_size, 30, { db2_param_type=>SQL_PARAM_OUTPUT() }); + $sth->bind_param_inout(3, \$db_capacity, 30, { db2_param_type=>SQL_PARAM_OUTPUT() }); + $sth->execute(); + if (!defined($snapshot_timestamp) || $snapshot_timestamp == 0) { + $self->{output}->add_option_msg(short_msg => 'Cannot execute query: ' . $dbh->errstr()); + $self->{output}->option_exit(); + } + + $self->{global} = { + dbname => $options{sql}->get_database_name(), + total => $db_capacity, + used => $db_size, + free => $db_capacity - $db_size, + prct_used => $db_size * 100 / $db_capacity, + prct_free => 100 - ($db_size * 100 / $db_capacity) + }; +} + +1; + +__END__ + +=head1 MODE + +Check database space usage. + +=over 8 + +=item B<--warning-*> B<--critical-*> + +Thresholds. +Can be: 'space-usage', 'space-usage-free', 'space-usage-prct'. + +=back + +=cut diff --git a/centreon-plugins/database/db2/plugin.pm b/centreon-plugins/database/db2/plugin.pm index b114aa1ee..2b7c8bff8 100644 --- a/centreon-plugins/database/db2/plugin.pm +++ b/centreon-plugins/database/db2/plugin.pm @@ -32,12 +32,14 @@ sub new { $self->{version} = '0.1'; $self->{modes} = { - 'collection' => 'centreon::common::protocols::sql::mode::collection', - 'connection-time' => 'centreon::common::protocols::sql::mode::connectiontime', - 'connected-users' => 'database::db2::mode::connectedusers' + 'collection' => 'centreon::common::protocols::sql::mode::collection', + 'connection-time' => 'centreon::common::protocols::sql::mode::connectiontime', + 'connected-users' => 'database::db2::mode::connectedusers', + 'database-logs' => 'database::db2::mode::databaselogs', + 'database-usage' => 'database::db2::mode::databaseusage' }; - $self->{sql_modes}->{dbi} = 'database::db2::dbi'; + $self->{sql_modes}->{dbi} = 'database::db2::dbi'; return $self; }