From 5b06c3ef5dd8db7bedca26c7933cacf387d0565b Mon Sep 17 00:00:00 2001 From: Sims24 Date: Sat, 23 Jan 2016 14:40:16 +0100 Subject: [PATCH 1/6] + add tables-size mode to plugin.pm --- centreon-plugins/database/mysql/plugin.pm | 1 + 1 file changed, 1 insertion(+) diff --git a/centreon-plugins/database/mysql/plugin.pm b/centreon-plugins/database/mysql/plugin.pm index 5ae0b6c5c..916f9f133 100644 --- a/centreon-plugins/database/mysql/plugin.pm +++ b/centreon-plugins/database/mysql/plugin.pm @@ -47,6 +47,7 @@ sub new { 'sql' => 'centreon::common::protocols::sql::mode::sql', 'threads-connected' => 'database::mysql::mode::threadsconnected', 'uptime' => 'database::mysql::mode::uptime', + 'tables-size' => 'database::mysql::mode::tablessize', ); $self->{sql_modes}{mysqlcmd} = 'database::mysql::mysqlcmd'; From 9e19d2b7ce2d856bcd64033b23b0cdf8a815389c Mon Sep 17 00:00:00 2001 From: Sims24 Date: Sat, 23 Jan 2016 14:43:06 +0100 Subject: [PATCH 2/6] + add tablessize.pm mode enhancement: https://github.com/centreon/centreon-plugins/issues/293 --- .../database/mysql/mode/tablessize.pm | 137 ++++++++++++++++++ 1 file changed, 137 insertions(+) create mode 100644 centreon-plugins/database/mysql/mode/tablessize.pm diff --git a/centreon-plugins/database/mysql/mode/tablessize.pm b/centreon-plugins/database/mysql/mode/tablessize.pm new file mode 100644 index 000000000..71541766d --- /dev/null +++ b/centreon-plugins/database/mysql/mode/tablessize.pm @@ -0,0 +1,137 @@ +# +# 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 database::mysql::mode::tablessize; + +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', }, + "db-table:s" => { name => 'db_table', }, + }); + + 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}->{db_table}) || $self->{option_results}->{db_table} !~ /\./) { + $self->{output}->add_option_msg(short_msg => "Check --db-table option (mandatory) formatting"); + $self->{output}->option_exit(); + } + + ($self->{db}, $self->{table}) = split(/\./, $self->{option_results}->{db_table}) if (defined ($self->{option_results}->{db_table})); + +} + +sub run { + my ($self, %options) = @_; + # $options{sql} = sqlmode object + $self->{sql} = $options{sql}; + $self->{sql}->connect(); + + my $multiple = 0; + my $query = "SELECT table_name AS NAME, ROUND(data_length+index_length) + FROM information_schema.TABLES + WHERE table_schema = '" . $self->{db}. "' AND table_name LIKE '" . $self->{table} . "'"; + + $self->{sql}->query(query => $query); + my $result = $self->{sql}->fetchall_arrayref(); + + if (!($self->{sql}->is_version_minimum(version => '5'))) { + $self->{output}->add_option_msg(short_msg => "MySQL version '" . $self->{sql}->{version} . "' is not supported."); + $self->{output}->option_exit(); + } + + if (scalar (@$result) > 1) { + $self->{output}->output_add(severity => 'OK', + short_msg => "All tables are ok."); + $multiple = 1; + } + + foreach my $row (@$result) { + my $exit_code = $self->{perfdata}->threshold_check(value => $$row[1], threshold => [ { label => 'critical', exit_litteral => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]); + my ($value, $value_unit) = $self->{perfdata}->change_bytes(value => $$row[1]); + $self->{output}->output_add(long_msg => sprintf("Table '" . $$row[0] . "' size: %s%s", $value, $value_unit)); + if ($multiple == 0 || !$self->{output}->is_status(value => $exit_code, compare => 'ok', litteral => 1)) { + $self->{output}->output_add(severity => $exit_code, + short_msg => sprintf("Table '%s' size is '%i%s'", $$row[0], $value, $value_unit)); + } + $self->{output}->perfdata_add(label => $$row[0] . '_size', unit => 'B', + value => $$row[1], + 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 => 'UNKNOWN', + short_msg => sprintf("Didn't find table '%s' in '%s' database !", $self->{table}, $self->{db})) if (scalar(@$result) == 0); + + $self->{output}->display(); + $self->{output}->exit(); +} + +1; + +__END__ + +=head1 MODE + +Check MySQL tables size. + +=over 8 + +=item B<--warning> + +Threshold warning in bytes. + +=item B<--critical> + +Threshold critical in bytes. + +=item B<--db-table> + +Filter database and table to check [use '%' wildcard with caution!] +e.g unique : --db-table database.table_name +e.g multiple : --db-table database.table_% + +=back + +=cut From 183e34e375091937c903265ca1b4ff674e3cf4b6 Mon Sep 17 00:00:00 2001 From: Sims24 Date: Sat, 23 Jan 2016 20:05:10 +0100 Subject: [PATCH 3/6] + update tablessize.pm after PR comment see https://github.com/centreon/centreon-plugins/pull/299 --- .../database/mysql/mode/tablessize.pm | 55 +++++++++---------- 1 file changed, 25 insertions(+), 30 deletions(-) diff --git a/centreon-plugins/database/mysql/mode/tablessize.pm b/centreon-plugins/database/mysql/mode/tablessize.pm index 71541766d..3a93c93a1 100644 --- a/centreon-plugins/database/mysql/mode/tablessize.pm +++ b/centreon-plugins/database/mysql/mode/tablessize.pm @@ -35,7 +35,7 @@ sub new { { "warning:s" => { name => 'warning', }, "critical:s" => { name => 'critical', }, - "db-table:s" => { name => 'db_table', }, + "db-table:s@" => { name => 'db_table', }, }); return $self; @@ -53,13 +53,18 @@ sub check_options { $self->{output}->add_option_msg(short_msg => "Wrong critical threshold '" . $self->{option_results}->{critical} . "'."); $self->{output}->option_exit(); } - if (!defined($self->{option_results}->{db_table}) || $self->{option_results}->{db_table} !~ /\./) { - $self->{output}->add_option_msg(short_msg => "Check --db-table option (mandatory) formatting"); + if (!defined(@{$self->{option_results}->{db_table}})) { + $self->{output}->add_option_msg(short_msg => "Please define --db-table option"); $self->{output}->option_exit(); } - - ($self->{db}, $self->{table}) = split(/\./, $self->{option_results}->{db_table}) if (defined ($self->{option_results}->{db_table})); - + foreach (@{$self->{option_results}->{db_table}}) { + my ($db, $table) = split /\./; + if (!defined($db) || !defined($table)) { + $self->{output}->add_option_msg(short_msg => "Check --db-table option formatting : '" . $_ . "'"); + $self->{output}->option_exit(); + } + $self->{filter}->{$db.$table} = 1; + } } sub run { @@ -67,13 +72,9 @@ sub run { # $options{sql} = sqlmode object $self->{sql} = $options{sql}; $self->{sql}->connect(); - - my $multiple = 0; - my $query = "SELECT table_name AS NAME, ROUND(data_length+index_length) - FROM information_schema.TABLES - WHERE table_schema = '" . $self->{db}. "' AND table_name LIKE '" . $self->{table} . "'"; - - $self->{sql}->query(query => $query); + $self->{sql}->query(query => "SELECT table_schema AS DB, table_name AS NAME, ROUND(data_length + index_length) + FROM information_schema.TABLES"); + my $result = $self->{sql}->fetchall_arrayref(); if (!($self->{sql}->is_version_minimum(version => '5'))) { @@ -81,28 +82,24 @@ sub run { $self->{output}->option_exit(); } - if (scalar (@$result) > 1) { - $self->{output}->output_add(severity => 'OK', - short_msg => "All tables are ok."); - $multiple = 1; - } + $self->{output}->output_add(severity => 'OK', + short_msg => "All tables are ok."); foreach my $row (@$result) { - my $exit_code = $self->{perfdata}->threshold_check(value => $$row[1], threshold => [ { label => 'critical', exit_litteral => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]); - my ($value, $value_unit) = $self->{perfdata}->change_bytes(value => $$row[1]); - $self->{output}->output_add(long_msg => sprintf("Table '" . $$row[0] . "' size: %s%s", $value, $value_unit)); - if ($multiple == 0 || !$self->{output}->is_status(value => $exit_code, compare => 'ok', litteral => 1)) { + next if (!defined($self->{filter}->{$$row[0].$$row[1]}) || !defined($$row[2])); + my $exit_code = $self->{perfdata}->threshold_check(value => $$row[2], threshold => [ { label => 'critical', exit_litteral => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]); + my ($value, $value_unit) = $self->{perfdata}->change_bytes(value => $$row[2]); + $self->{output}->output_add(long_msg => sprintf("Database: '%s' Table: '%s' Size: '%s%s'", $$row[0], $$row[1], $value, $value_unit)); + if (!$self->{output}->is_status(value => $exit_code, compare => 'ok', litteral => 1)) { $self->{output}->output_add(severity => $exit_code, - short_msg => sprintf("Table '%s' size is '%i%s'", $$row[0], $value, $value_unit)); + short_msg => sprintf("Table '%s' size in db '%s' is '%i%s'", $$row[0], $$row[1], $value, $value_unit)); } - $self->{output}->perfdata_add(label => $$row[0] . '_size', unit => 'B', - value => $$row[1], + $self->{output}->perfdata_add(label => $$row[0] . '_' . $$row[1] . '_size', unit => 'B', + value => $$row[2], 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 => 'UNKNOWN', - short_msg => sprintf("Didn't find table '%s' in '%s' database !", $self->{table}, $self->{db})) if (scalar(@$result) == 0); $self->{output}->display(); $self->{output}->exit(); @@ -128,9 +125,7 @@ Threshold critical in bytes. =item B<--db-table> -Filter database and table to check [use '%' wildcard with caution!] -e.g unique : --db-table database.table_name -e.g multiple : --db-table database.table_% +Filter database and table to check (multiple: eg: --db-table centreon_storage.data_bin --db-table centreon_storage.logs) =back From 682b74dc27b76d235eb47c1ee255c01c86411f84 Mon Sep 17 00:00:00 2001 From: Sims24 Date: Sun, 24 Jan 2016 11:58:05 +0100 Subject: [PATCH 4/6] + init filter for greater clarity --- centreon-plugins/database/mysql/mode/tablessize.pm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/centreon-plugins/database/mysql/mode/tablessize.pm b/centreon-plugins/database/mysql/mode/tablessize.pm index 3a93c93a1..4fe8f75ab 100644 --- a/centreon-plugins/database/mysql/mode/tablessize.pm +++ b/centreon-plugins/database/mysql/mode/tablessize.pm @@ -37,7 +37,7 @@ sub new { "critical:s" => { name => 'critical', }, "db-table:s@" => { name => 'db_table', }, }); - + $self->{filter} = {}; return $self; } From 1a814f850f6374f41ebb9fd643b94f9d20730a65 Mon Sep 17 00:00:00 2001 From: Sims24 Date: Sun, 24 Jan 2016 21:13:10 +0100 Subject: [PATCH 5/6] + refactor tablessize.pm with new template --- .../database/mysql/mode/tablessize.pm | 123 ++++++++++-------- 1 file changed, 70 insertions(+), 53 deletions(-) diff --git a/centreon-plugins/database/mysql/mode/tablessize.pm b/centreon-plugins/database/mysql/mode/tablessize.pm index 4fe8f75ab..1bc21020b 100644 --- a/centreon-plugins/database/mysql/mode/tablessize.pm +++ b/centreon-plugins/database/mysql/mode/tablessize.pm @@ -20,11 +20,45 @@ package database::mysql::mode::tablessize; -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 }, + { name => 'table', type => 1, cb_prefix_output => 'prefix_table_output', message_multiple => 'All tables sizes are ok' }, + ]; + + $self->{maps_counters}->{global} = [ + { label => 'total', set => { + key_values => [ { name => 'total' } ], + output_template => 'Total Size : %s%s', + output_change_bytes => 1, + perfdatas => [ + { label => 'total', value => 'total_absolute', template => '%s', + unit => 'B', min => 0 }, + ], + } + }, + ]; + $self->{maps_counters}->{table} = [ + { label => 'table', set => { + key_values => [ { name => 'size' }, { name => 'display' } ], + output_template => 'size : %s%s', + output_change_bytes => 1, + perfdatas => [ + { label => 'table', value => 'size_absolute', template => '%s', + unit => 'B', min => 0, label_extra_instance => 1, instance_use => 'display_absolute' }, + ], + } + }, + ]; +} + sub new { my ($class, %options) = @_; my $self = $class->SUPER::new(package => __PACKAGE__, %options); @@ -33,48 +67,26 @@ sub new { $self->{version} = '1.0'; $options{options}->add_options(arguments => { - "warning:s" => { name => 'warning', }, - "critical:s" => { name => 'critical', }, - "db-table:s@" => { name => 'db_table', }, + "filter-db:s" => { name => 'filter_db' }, + "filter-table:s" => { name => 'filter_table' }, }); - $self->{filter} = {}; return $self; } -sub check_options { +sub prefix_table_output { 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}->{db_table}})) { - $self->{output}->add_option_msg(short_msg => "Please define --db-table option"); - $self->{output}->option_exit(); - } - foreach (@{$self->{option_results}->{db_table}}) { - my ($db, $table) = split /\./; - if (!defined($db) || !defined($table)) { - $self->{output}->add_option_msg(short_msg => "Check --db-table option formatting : '" . $_ . "'"); - $self->{output}->option_exit(); - } - $self->{filter}->{$db.$table} = 1; - } + return "Table '" . $options{instance_value}->{display} . "' "; } -sub run { +sub manage_selection { my ($self, %options) = @_; # $options{sql} = sqlmode object $self->{sql} = $options{sql}; $self->{sql}->connect(); + $self->{sql}->query(query => "SELECT table_schema AS DB, table_name AS NAME, ROUND(data_length + index_length) FROM information_schema.TABLES"); - my $result = $self->{sql}->fetchall_arrayref(); if (!($self->{sql}->is_version_minimum(version => '5'))) { @@ -82,27 +94,24 @@ sub run { $self->{output}->option_exit(); } - $self->{output}->output_add(severity => 'OK', - short_msg => "All tables are ok."); + $self->{global} = { total => 0 }; + $self->{table} = {}; foreach my $row (@$result) { - next if (!defined($self->{filter}->{$$row[0].$$row[1]}) || !defined($$row[2])); - my $exit_code = $self->{perfdata}->threshold_check(value => $$row[2], threshold => [ { label => 'critical', exit_litteral => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]); - my ($value, $value_unit) = $self->{perfdata}->change_bytes(value => $$row[2]); - $self->{output}->output_add(long_msg => sprintf("Database: '%s' Table: '%s' Size: '%s%s'", $$row[0], $$row[1], $value, $value_unit)); - if (!$self->{output}->is_status(value => $exit_code, compare => 'ok', litteral => 1)) { - $self->{output}->output_add(severity => $exit_code, - short_msg => sprintf("Table '%s' size in db '%s' is '%i%s'", $$row[0], $$row[1], $value, $value_unit)); + next if (!defined($$row[2])); + if (defined($self->{option_results}->{filter_table}) && $self->{option_results}->{filter_table} ne '' && + $$row[1] !~ /$self->{option_results}->{filter_table}/) { + $self->{output}->output_add(long_msg => "Skipping '" . $$row[0].'.'.$$row[1] . "': no matching filter.", debug => 1); + next; } - $self->{output}->perfdata_add(label => $$row[0] . '_' . $$row[1] . '_size', unit => 'B', - value => $$row[2], - warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning'), - critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical'), - min => 0); + if (defined($self->{option_results}->{filter_db}) && $self->{option_results}->{filter_db} ne '' && + $$row[0] !~ /$self->{option_results}->{filter_db}/) { + $self->{output}->output_add(long_msg => "Skipping '" . $$row[0].'.'.$$row[1] . "': no matching filter.", debug => 1); + next + } + $self->{table}->{$$row[0].'.'.$$row[1]} = { size => $$row[2], display => $$row[0].'.'.$$row[1] }; + $self->{global}->{total} += $$row[2] if defined($self->{table}->{$$row[0].'.'.$$row[1]}); } - - $self->{output}->display(); - $self->{output}->exit(); } 1; @@ -111,21 +120,29 @@ __END__ =head1 MODE -Check MySQL tables size. +Check AP status. =over 8 -=item B<--warning> +=item B<--filter-counters> -Threshold warning in bytes. +Only display some counters (regexp can be used). -=item B<--critical> +=item B<--filter-db> -Threshold critical in bytes. +Filter DB name (can be a regexp). -=item B<--db-table> +=item B<--filter-table> -Filter database and table to check (multiple: eg: --db-table centreon_storage.data_bin --db-table centreon_storage.logs) +Filter table name (can be a regexp). + +=item B<--warning-*> + +Set warning threshold for number of user. Can be : 'total', 'table' + +=item B<--critical-*> + +Set critical threshold for number of user. Can be : 'total', 'table' =back From 7bb2aabc07585418ad77bf01d9f6a0af7cb24f81 Mon Sep 17 00:00:00 2001 From: Sims24 Date: Sun, 24 Jan 2016 21:46:51 +0100 Subject: [PATCH 6/6] + fix help mode description --- centreon-plugins/database/mysql/mode/tablessize.pm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/centreon-plugins/database/mysql/mode/tablessize.pm b/centreon-plugins/database/mysql/mode/tablessize.pm index 1bc21020b..da2699bd9 100644 --- a/centreon-plugins/database/mysql/mode/tablessize.pm +++ b/centreon-plugins/database/mysql/mode/tablessize.pm @@ -120,7 +120,7 @@ __END__ =head1 MODE -Check AP status. +Check size of one (or more) table from one (or more) databases =over 8