From 29a6edb2139d1eda4c1cfa8a9bcbd8167909c015 Mon Sep 17 00:00:00 2001 From: qgarnier Date: Fri, 27 Jan 2023 14:48:21 +0000 Subject: [PATCH] (plugin) oracle ucp jmx - new (#4186) --- .../oracle/ucp/jmx/mode/connectionpools.pm | 261 ++++++++++++++++++ .../ucp/jmx/mode/listconnectionpools.pm | 121 ++++++++ src/apps/oracle/ucp/jmx/plugin.pm | 49 ++++ 3 files changed, 431 insertions(+) create mode 100644 src/apps/oracle/ucp/jmx/mode/connectionpools.pm create mode 100644 src/apps/oracle/ucp/jmx/mode/listconnectionpools.pm create mode 100644 src/apps/oracle/ucp/jmx/plugin.pm diff --git a/src/apps/oracle/ucp/jmx/mode/connectionpools.pm b/src/apps/oracle/ucp/jmx/mode/connectionpools.pm new file mode 100644 index 000000000..8cc5cac7a --- /dev/null +++ b/src/apps/oracle/ucp/jmx/mode/connectionpools.pm @@ -0,0 +1,261 @@ +# +# 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::oracle::ucp::jmx::mode::connectionpools; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; + +sub custom_usage_perfdata { + my ($self, %options) = @_; + + $self->{output}->perfdata_add( + nlabel => $self->{nlabel}, + instances => $self->{result_values}->{poolName}, + 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} > 0 ? $self->{result_values}->{total} : undef + ); +} + +sub custom_usage_free_perfdata { + my ($self, %options) = @_; + + $self->{output}->perfdata_add( + nlabel => $self->{nlabel}, + instances => $self->{result_values}->{poolName}, + 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}->{poolName}, + value => sprintf('%.2f', $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 custom_usage_threshold { + my ($self, %options) = @_; + + return $self->{perfdata}->threshold_check( + value => $self->{result_values}->{used}, threshold => [ + { label => 'critical-' . $self->{thlabel}, exit_litteral => 'critical' }, + { label => 'warning-' . $self->{thlabel}, exit_litteral => 'warning' }, + ] + ); +} + +sub custom_usage_free_threshold { + my ($self, %options) = @_; + + return $self->{perfdata}->threshold_check( + value => $self->{result_values}->{free}, threshold => [ + { label => 'critical-' . $self->{thlabel}, exit_litteral => 'critical' }, + { label => 'warning-'. $self->{thlabel}, exit_litteral => 'warning' } + ] + ); +} + +sub custom_usage_prct_threshold { + my ($self, %options) = @_; + + return $self->{perfdata}->threshold_check( + value => $self->{result_values}->{prct_used}, threshold => [ + { label => 'critical-' . $self->{thlabel}, exit_litteral => 'critical' }, + { label => 'warning-'. $self->{thlabel}, exit_litteral => 'warning' } + ] + ); +} + +sub custom_usage_output { + my ($self, %options) = @_; + + my $msg; + if ($self->{result_values}->{total} <= 0) { + $msg = sprintf("used: %s (unlimited)", $self->{result_values}->{used}); + } else { + $msg = sprintf( + "total: %s used: %s (%.2f%%) free: %s (%.2f%%)", + $self->{result_values}->{total}, + $self->{result_values}->{used}, $self->{result_values}->{prct_used}, + $self->{result_values}->{free}, $self->{result_values}->{prct_free} + ); + } + + return $msg; +} + +sub custom_usage_calc { + my ($self, %options) = @_; + + $self->{result_values}->{poolName} = $options{new_datas}->{$self->{instance} . '_poolName'}; + $self->{result_values}->{total} = $options{new_datas}->{$self->{instance} . '_total'}; + $self->{result_values}->{used} = $options{new_datas}->{$self->{instance} . '_used'}; + + if ($self->{result_values}->{total} == 0) { + return -10 if ($options{extra_options}->{label} ne 'usage'); + return 0; + } + + $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}; + $self->{result_values}->{free} = $self->{result_values}->{total} - $self->{result_values}->{used}; + + return 0; +} + +sub prefix_pool_output { + my ($self, %options) = @_; + + return sprintf( + "Connection pool '%s' ", + $options{instance_value}->{poolName} + ); +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'pools', type => 1, cb_prefix_output => 'prefix_pool_output', message_multiple => 'All connection pools are ok', skipped_code => { -10 => 1 } } + ]; + + $self->{maps_counters}->{pools} = [ + { label => 'usage', nlabel => 'connection_pool.usage.count', set => { + key_values => [ + { name => 'poolName' }, { name => 'used' }, { name => 'total' } + ], + closure_custom_calc_extra_options => { label => 'usage' }, + closure_custom_calc => $self->can('custom_usage_calc'), + closure_custom_output => $self->can('custom_usage_output'), + closure_custom_threshold_check => $self->can('custom_usage_threshold'), + closure_custom_perfdata => $self->can('custom_usage_perfdata') + } + }, + { label => 'usage-free', nlabel => 'connection_pool.free.count', display_ok => 0, set => { + key_values => [ + { name => 'poolName' }, { name => 'used' }, { name => 'total' } + ], + closure_custom_calc_extra_options => { label => 'free' }, + closure_custom_calc => $self->can('custom_usage_calc'), + closure_custom_output => $self->can('custom_usage_output'), + closure_custom_threshold_check => $self->can('custom_usage_free_threshold'), + closure_custom_perfdata => $self->can('custom_usage_free_perfdata') + } + }, + { label => 'usage-prct', nlabel => 'connection_pool.usage.percentage', display_ok => 0, set => { + key_values => [ + { name => 'poolName' }, { name => 'used' }, { name => 'total' } + ], + closure_custom_calc_extra_options => { label => 'prct' }, + closure_custom_calc => $self->can('custom_usage_calc'), + closure_custom_output => $self->can('custom_usage_output'), + closure_custom_threshold_check => $self->can('custom_usage_prct_threshold'), + 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 => { + 'filter-index:s' => { name => 'filter_index' }, + 'filter-vserver:s' => { name => 'filter_vserver' }, + 'filter-volume:s' => { name => 'filter_volume' }, + 'filter-qtree:s' => { name => 'filter_qtree' } + }); + + return $self; +} + +sub manage_selection { + my ($self, %options) = @_; + + my $request = [ + { mbean => "oracle.ucp.admin.UniversalConnectionPoolMBean:name=UniversalConnectionPoolManager*,poolName=*", attributes => + [ { name => 'remainingPoolCapacityCount' }, { name => 'totalConnectionsCount' }, { name => 'maxPoolSize' } ] } + ]; + + my $result = $options{custom}->get_attributes(request => $request, nothing_quit => 1); + + $self->{pools} = {}; + foreach my $key (keys %$result) { + $key =~ /(?:[:,])poolName=(.*?)(?:,|$)/; + my $poolName = $1; + + next if (defined($self->{option_results}->{filter_pool_name}) && $self->{option_results}->{filter_pool_name} ne '' && + $poolName !~ /$self->{option_results}->{filter_pool_name}/); + + $self->{pools}->{$poolName} = { + poolName => $poolName, + used => $result->{$key}->{totalConnectionsCount}, + total => defined($result->{$key}->{maxPoolSize}) ? $result->{$key}->{maxPoolSize} : 0 + }; + } + + if (scalar(keys %{$self->{pools}}) <= 0) { + $self->{output}->add_option_msg(short_msg => 'No connection pools found'); + $self->{output}->option_exit(); + } +} + +1; + +__END__ + +=head1 MODE + +Check connection pools. + +=over 8 + +=item B<--filter-pool-name> + +Filter connection pools by name (can be a regexp). + +=item B<--warning-*> B<--critical-*> + +Thresholds. +Can be: 'usage', 'usage-free', 'usage-prct'. + +=back + +=cut diff --git a/src/apps/oracle/ucp/jmx/mode/listconnectionpools.pm b/src/apps/oracle/ucp/jmx/mode/listconnectionpools.pm new file mode 100644 index 000000000..0f68a81d8 --- /dev/null +++ b/src/apps/oracle/ucp/jmx/mode/listconnectionpools.pm @@ -0,0 +1,121 @@ +# +# 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::oracle::ucp::jmx::mode::listconnectionpools; + +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; + + $options{options}->add_options(arguments => {}); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::init(%options); +} + +sub manage_selection { + my ($self, %options) = @_; + + my $mbeans = $options{custom}->get_attributes( + request => [ + { + mbean => "oracle.ucp.admin.UniversalConnectionPoolMBean:name=UniversalConnectionPoolManager*,poolName=*", + attributes => [ { name => 'totalConnectionsCount' } ] + } + ] + ); + + my $results = {}; + foreach my $mbean (keys %$mbeans) { + $mbean =~ /(?:[:,])poolName=(.*?)(?:,|$)/; + my $poolName = $1; + + $mbean =~ /(?:[:,])name=(.*?)(?:,|$)/; + my $name = $1; + + $results->{$name} = { + name => $name, + poolName => $poolName + }; + } + + return $results; +} + +sub run { + my ($self, %options) = @_; + + my $results = $self->manage_selection(%options); + foreach my $instance (sort keys %$results) { + $self->{output}->output_add( + long_msg => + '[name = ' . $results->{$instance}->{name} . "]" . + " [poolName = '" . $results->{$instance}->{poolName} . "']" + ); + } + + $self->{output}->output_add( + severity => 'OK', + short_msg => 'List connection pools:' + ); + $self->{output}->display(nolabel => 1, force_ignore_perfdata => 1, force_long_output => 1); + $self->{output}->exit(); +} + +sub disco_format { + my ($self, %options) = @_; + + $self->{output}->add_disco_format(elements => ['name', 'poolName']); +} + +sub disco_show { + my ($self, %options) = @_; + + my $results = $self->manage_selection(%options); + foreach my $instance (sort keys %$results) { + $self->{output}->add_disco_entry( + %{$results->{$instance}} + ); + } +} + +1; + +__END__ + +=head1 MODE + +List connection pools. + +=over 8 + +=back + +=cut diff --git a/src/apps/oracle/ucp/jmx/plugin.pm b/src/apps/oracle/ucp/jmx/plugin.pm new file mode 100644 index 000000000..8d504671b --- /dev/null +++ b/src/apps/oracle/ucp/jmx/plugin.pm @@ -0,0 +1,49 @@ +# +# 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::oracle::ucp::jmx::plugin; + +use strict; +use warnings; +use base qw(centreon::plugins::script_custom); + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $self->{modes} = { + 'connection-pools' => 'apps::oracle::ucp::jmx::mode::connectionpools', + 'list-connection-pools' => 'apps::oracle::ucp::jmx::mode::listconnectionpools' + }; + + $self->{custom_modes}->{jolokia} = 'centreon::common::protocols::jmx::custom::jolokia'; + return $self; +} + +1; + +__END__ + +=head1 PLUGIN DESCRIPTION + +Check Oracle Universal Connection Pool in JMX. Need Jolokia agent. + +=cut