From c966d9fb61123a46073f0e997dbadd73dcff5d34 Mon Sep 17 00:00:00 2001 From: garnier-quentin Date: Thu, 4 Jun 2015 14:42:28 +0200 Subject: [PATCH] + add a plugin for jmx jolokia agent --- .../apps/protocols/jmx/mode/listattributes.pm | 102 ++++++ .../apps/protocols/jmx/mode/numericvalue.pm | 323 ++++++++++++++++++ centreon-plugins/apps/protocols/jmx/plugin.pm | 66 ++++ .../common/protocols/jmx/custom/jolokia.pm | 317 +++++++++++++++++ centreon-plugins/snmp_standard/plugin.pm | 4 +- 5 files changed, 810 insertions(+), 2 deletions(-) create mode 100644 centreon-plugins/apps/protocols/jmx/mode/listattributes.pm create mode 100644 centreon-plugins/apps/protocols/jmx/mode/numericvalue.pm create mode 100644 centreon-plugins/apps/protocols/jmx/plugin.pm create mode 100644 centreon-plugins/centreon/common/protocols/jmx/custom/jolokia.pm diff --git a/centreon-plugins/apps/protocols/jmx/mode/listattributes.pm b/centreon-plugins/apps/protocols/jmx/mode/listattributes.pm new file mode 100644 index 000000000..8c4442375 --- /dev/null +++ b/centreon-plugins/apps/protocols/jmx/mode/listattributes.pm @@ -0,0 +1,102 @@ +################################################################################ +# Copyright 2005-2014 MERETHIS +# Centreon is developped by : Julien Mathis and Romain Le Merlus under +# GPL Licence 2.0. +# +# This program is free software; you can redistribute it and/or modify it under +# the terms of the GNU General Public License as published by the Free Software +# Foundation ; either version 2 of the License. +# +# This program is distributed in the hope that it will be useful, but WITHOUT ANY +# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. See the GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along with +# this program; if not, see . +# +# Linking this program statically or dynamically with other modules is making a +# combined work based on this program. Thus, the terms and conditions of the GNU +# General Public License cover the whole combination. +# +# As a special exception, the copyright holders of this program give MERETHIS +# permission to link this program with independent modules to produce an executable, +# regardless of the license terms of these independent modules, and to copy and +# distribute the resulting executable under terms of MERETHIS choice, provided that +# MERETHIS also meet, for each linked independent module, the terms and conditions +# of the license of that module. An independent module is a module which is not +# derived from this program. If you modify this program, you may extend this +# exception to your version of the program, but you are not obliged to do so. If you +# do not wish to do so, delete this exception statement from your version. +# +# For more information : contact@centreon.com +# Authors : Quentin Garnier +# +#################################################################################### + +package apps::protocols::jmx::mode::listattributes; + +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 => + { + "max-depth:s" => { name => 'max_depth', default => 6 }, + "max-objects:s" => { name => 'max_objects', default => 10000 }, + "max-collection-size:s" => { name => 'max_collection_size', default => 150 }, + "mbean-pattern:s" => { name => 'mbean_pattern', default => '*:*' }, + }); + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::init(%options); + +} + +sub run { + my ($self, %options) = @_; + $self->{connector} = $options{custom}; + + $self->{connector}->list_attributes(%{$self->{option_results}}); + $self->{output}->exit(); +} + +1; + +__END__ + +=head1 MODE + +List JMX attributes. + +=over 8 + +=item B<--max-depth> + +Maximum nesting level of the returned JSON structure for a certain MBean (Default: 6) + +=item B<--max-collection-size> + +Maximum size of a collection after which it gets truncated (default: 150) + +=item B<--max-objects> + +Maximum overall objects to fetch for a mbean (default: 10000) + +=item B<--mbean-pattern> + +Pattern matching (Default: '*:*'). +For details: http://docs.oracle.com/javase/1.5.0/docs/api/javax/management/ObjectName.html + +=back + +=cut diff --git a/centreon-plugins/apps/protocols/jmx/mode/numericvalue.pm b/centreon-plugins/apps/protocols/jmx/mode/numericvalue.pm new file mode 100644 index 000000000..bd8ec6808 --- /dev/null +++ b/centreon-plugins/apps/protocols/jmx/mode/numericvalue.pm @@ -0,0 +1,323 @@ +################################################################################ +# Copyright 2005-2013 MERETHIS +# Centreon is developped by : Julien Mathis and Romain Le Merlus under +# GPL Licence 2.0. +# +# This program is free software; you can redistribute it and/or modify it under +# the terms of the GNU General Public License as published by the Free Software +# Foundation ; either version 2 of the License. +# +# This program is distributed in the hope that it will be useful, but WITHOUT ANY +# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. See the GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along with +# this program; if not, see . +# +# Linking this program statically or dynamically with other modules is making a +# combined work based on this program. Thus, the terms and conditions of the GNU +# General Public License cover the whole combination. +# +# As a special exception, the copyright holders of this program give MERETHIS +# permission to link this program with independent modules to produce an executable, +# regardless of the license terms of these independent modules, and to copy and +# distribute the resulting executable under terms of MERETHIS choice, provided that +# MERETHIS also meet, for each linked independent module, the terms and conditions +# of the license of that module. An independent module is a module which is not +# derived from this program. If you modify this program, you may extend this +# exception to your version of the program, but you are not obliged to do so. If you +# do not wish to do so, delete this exception statement from your version. +# +# For more information : contact@centreon.com +# Authors : Quentin Garnier +# +#################################################################################### + +package apps::protocols::jmx::mode::numericvalue; + +use base qw(centreon::plugins::mode); + +use strict; +use warnings; +use centreon::plugins::statefile; +use Digest::MD5 qw(md5_hex); +use centreon::plugins::misc; + +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 => + { + "mbean-pattern:s" => { name => 'mbean_pattern' }, + "attribute:s@" => { name => 'attribute' }, + "lookup-path:s" => { name => 'lookup_path' }, + "lookup-jpath:s" => { name => 'lookup_jpath' }, + + "type:s@" => { name => 'type' }, + "counter-per-seconds:s@" => { name => 'counter_per_seconds' }, + "warning:s@" => { name => 'warning' }, + "critical:s@" => { name => 'critical' }, + "format:s@" => { name => 'format' }, + "format-scale:s@" => { name => 'format_scale' }, + "format-scale-unit:s@" => { name => 'format_scale_unit' }, + "perfdata-unit:s@" => { name => 'perfdata_unit' }, + "perfdata-name:s@" => { name => 'perfdata_name' }, + "perfdata-min:s@" => { name => 'perfdata_min' }, + "perfdata-max:s@" => { name => 'perfdata_max' }, + }); + $self->{statefile_cache} = centreon::plugins::statefile->new(%options); + $self->{jpath} = undef; + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::init(%options); + + if (!defined($self->{option_results}->{mbean_pattern}) || $self->{option_results}->{mbean_pattern} eq '') { + $self->{output}->add_option_msg(short_msg => "Need to specify mbean-pattern option."); + $self->{output}->option_exit(); + } + if (!defined($self->{option_results}->{attribute}) || scalar($self->{option_results}->{attribute}) == 0) { + $self->{option_results}->{attribute} = undef; + } + + if (defined($self->{option_results}->{type})) { + foreach (@{$self->{option_results}->{type}}) { + if ($_ =~ /^counter$/) { + $self->{statefile_cache}->check_options(%options); + last; + } + } + } + + if ((!defined($self->{option_results}->{lookup_jpath}) || $self->{option_results}->{lookup_jpath} eq '') && + (!defined($self->{option_results}->{lookup_path}) || $self->{option_results}->{lookup_path} eq '')) { + $self->{output}->add_option_msg(short_msg => "Need to specify --lookup-path or --lookup-jpath option."); + $self->{output}->option_exit(); + } + + if (defined($self->{option_results}->{lookup_jpath}) && $self->{option_results}->{lookup_jpath} ne '') { + centreon::plugins::misc::mymodule_load(output => $self->{output}, module => 'JSON::Path', + error_msg => "Cannot load module 'JSON::Path'."); + $self->{jpath} = JSON::Path->new($self->{option_results}->{lookup_jpath}); + } +} + +sub set_attributes { + my ($self, %options) = @_; + + $self->{attributes} = {}; + $self->{attributes}->{type} = (defined($self->{option_results}->{type})) ? shift(@{$self->{option_results}->{type}}) : 'gauge'; + $self->{attributes}->{counter_per_seconds} = (defined($self->{option_results}->{counter_per_seconds})) ? shift(@{$self->{option_results}->{counter_per_seconds}}) : undef; + $self->{attributes}->{warning} = (defined($self->{option_results}->{warning})) ? shift(@{$self->{option_results}->{warning}}) : undef; + $self->{attributes}->{critical} = (defined($self->{option_results}->{critical})) ? shift(@{$self->{option_results}->{critical}}) : undef; + $self->{attributes}->{format} = (defined($self->{option_results}->{format})) ? shift(@{$self->{option_results}->{format}}) : 'current value' . $options{number} . ' is %s'; + $self->{attributes}->{format_scale} = (defined($self->{option_results}->{format_scale})) ? shift(@{$self->{option_results}->{format_scale}}) : undef; + $self->{attributes}->{format_scale_unit} = (defined($self->{option_results}->{format_scale_unit})) ? shift(@{$self->{option_results}->{format_scale_unit}}) : 'other'; + $self->{attributes}->{perfdata_unit} = (defined($self->{option_results}->{perfdata_unit})) ? shift(@{$self->{option_results}->{perfdata_unit}}) : ''; + $self->{attributes}->{perfdata_name} = (defined($self->{option_results}->{perfdata_name})) ? shift(@{$self->{option_results}->{perfdata_name}}) : 'value' . $options{number}; + $self->{attributes}->{perfdata_min} = (defined($self->{option_results}->{perfdata_min})) ? shift(@{$self->{option_results}->{perfdata_min}}) : ''; + $self->{attributes}->{perfdata_max} = (defined($self->{option_results}->{perfdata_max})) ? shift(@{$self->{option_results}->{perfdata_max}}) : ''; + + if ($self->{attributes}->{type} !~ /^gauge|counter$/i) { + $self->{output}->add_option_msg(short_msg => "Wrong --type argument '" . $self->{attributes}->{type} . "' ('gauge' or 'counter')."); + $self->{output}->option_exit(); + } + if ($self->{attributes}->{format_scale_unit} !~ /^other|network$/i) { + $self->{output}->add_option_msg(short_msg => "Wrong --format-scale-unit argument '" . $self->{attributes}->{format_scale_unit} . "' ('other' or 'network')."); + $self->{output}->option_exit(); + } + + if (($self->{perfdata}->threshold_validate(label => 'warning-' . $options{number}, value => $self->{attributes}->{warning})) == 0) { + $self->{output}->add_option_msg(short_msg => "Wrong warning threshold '" . $self->{attributes}->{warning} . "'."); + $self->{output}->option_exit(); + } + if (($self->{perfdata}->threshold_validate(label => 'critical-' . $options{number}, value => $self->{attributes}->{critical})) == 0) { + $self->{output}->add_option_msg(short_msg => "Wrong critical threshold '" . $self->{attributes}->{critical} . "'."); + $self->{output}->option_exit(); + } +} + +sub check_value { + my ($self, %options) = @_; + + my $value = $options{value}; + if ($self->{attributes}->{type} =~ /^counter$/i) { + if (!defined($self->{datas})) { + $self->{datas} = {}; + $self->{statefile_cache}->read(statefile => "jmxstandard_" . $self->{mode} . '_' . md5_hex($self->{connector}->{url} . ' ' . $self->{option_results}->{mbean_pattern})); + } + + my $old_timestamp = $self->{statefile_cache}->get(name => 'timestamp'); + my $old_value = $self->{statefile_cache}->get(name => 'value' . $options{number}); + + $self->{datas}->{timestamp} = time(); + $self->{datas}->{'value' . $options{number}} = $value; + if (!defined($old_timestamp)) { + $self->{output}->output_add(severity => 'OK', + short_msg => "Value " . $options{number} . ": buffer creation..."); + return ; + } + + # Reboot or counter goes back + if ($old_value > $value) { + $old_value = 0; + } + $value = $value - $old_value; + if (defined($self->{attributes}->{counter_per_seconds})) { + my $delta_time = $self->{datas}->{timestamp} - $old_timestamp; + $delta_time = 1 if ($delta_time == 0); # at least 1 sec + $value = $value / $delta_time; + } + } + + my $exit = $self->{perfdata}->threshold_check(value => $value, + threshold => [ { label => 'critical-' . $options{number}, exit_litteral => 'critical' }, { label => 'warning-' . $options{number}, exit_litteral => 'warning' } ]); + if (defined($self->{attributes}->{format_scale})) { + my ($value_mod, $value_unit) = $self->{perfdata}->change_bytes(value => $value); + if ($self->{attributes}->{format_scale} =~ /^network$/i) { + ($value_mod, $value_unit) = $self->{perfdata}->change_bytes(value => $value, network => 1); + } + $self->{output}->output_add(severity => $exit, + short_msg => sprintf($self->{attributes}->{format}, $value_mod . $value_unit)); + } else { + $self->{output}->output_add(severity => $exit, + short_msg => sprintf($self->{attributes}->{format}, $value)); + } + + $self->{output}->perfdata_add(label => $self->{attributes}->{perfdata_name}, unit => $self->{attributes}->{perfdata_unit}, + value => $value, + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $options{number}), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $options{number}), + min => $self->{attributes}->{perfdata_min}, max => $self->{attributes}->{perfdata_max}); +} + +sub find_values { + my ($self, %options) = @_; + + $self->{values} = []; + if (defined($options{result})) { + if (!ref($options{result})) { + push @{$self->{values}}, $options{result} if ($options{result} =~ /^[0-9\.,]+$/); + } elsif (defined($self->{jpath})) { + my @values = (); + + eval { + @values = $self->{jpath}->values($options{result}); + }; + if ($@) { + $self->{output}->add_option_msg(short_msg => "Cannot lookup: $@"); + $self->{output}->option_exit(); + } + foreach my $value (@values) { + push @{$self->{values}}, $value if (!ref($value) && $value =~ /^[0-9\.,]+$/); + } + } + } + + if (scalar(@{$self->{values}}) == 0) { + $self->{output}->output_add(severity => 'UNKNOWN', + short_msg => 'Cannot find numeric values'); + $self->{output}->display(); + $self->{output}->exit(); + } +} + +sub run { + my ($self, %options) = @_; + # $options{snmp} = snmp object + $self->{connector} = $options{custom}; + + my $result = $self->{connector}->get_attributes(mbean_pattern => $self->{option_results}->{mbean_pattern}, attributes => $self->{option_results}->{attribute}, path => $self->{option_results}->{lookup_path}); + + $self->find_values(result => $result); + for (my $i = 1; $i <= scalar(@{$self->{values}}); $i++) { + $self->set_attributes(number => $i); + $self->check_value(value => $self->{values}->[$i - 1], number => $i); + } + + if (defined($self->{datas})) { + $self->{statefile_cache}->write(data => $self->{datas}); + } + + $self->{output}->display(); + $self->{output}->exit(); +} + +1; + +__END__ + +=head1 MODE + +Check an JMX numeric value. +Example: +perl centreon_plugins.pl --plugin=apps::protocols::jmx::plugin --custommode=jolokia --url=http://127.0.0.1/jolokia --mode=numeric-value --mbean-pattern='java.lang:type=Memory' --attribute='HeapMemoryUsage' --lookup-path='used' --format-scale --format-unit='B' --format='HeapMemory Usage used: %s' --perfdata-name='used' + +=over 8 + +=item B<--oid> + +OID value to check (numeric format only). + +=item B<--lookup-path> + +What to lookup (from internal Jmx4Perl). Use --lookup-jpath for complex matching. + +=item B<--lookup-jpath> + +What to lookup in JSON response (JSON XPath string) +See: http://goessner.net/articles/JsonPath/ + +=item B<--warning> + +Threshold warning. + +=item B<--critical> + +Threshold critical. + +=item B<--oid-type> + +Type of the OID (Default: 'gauge'). +Can be 'counter' also. 'counter' will use a retention file. + +=item B<--counter-per-seconds> + +Convert counter value on a value per seconds (only with type 'counter'. + +=item B<--format> + +Output format (Default: 'current valueX is %s') + +=item B<--format-scale> + +Scale bytes value. We'll display value in output. + +=item B<--format-scale-type> + +Could be 'network' (value divide by 1000) or 'other' (divide by 1024) (Default: 'other') + +=item B<--perfdata-unit> + +Perfdata unit in perfdata output (Default: '') + +=item B<--perfdata-name> + +Perfdata name in perfdata output (Default: 'valueX') + +=item B<--perfdata-min> + +Minimum value to add in perfdata output (Default: '') + +=item B<--perfdata-max> + +Maximum value to add in perfdata output (Default: '') + +=back + +=cut diff --git a/centreon-plugins/apps/protocols/jmx/plugin.pm b/centreon-plugins/apps/protocols/jmx/plugin.pm new file mode 100644 index 000000000..c1df435ed --- /dev/null +++ b/centreon-plugins/apps/protocols/jmx/plugin.pm @@ -0,0 +1,66 @@ +################################################################################ +# Copyright 2005-2014 MERETHIS +# Centreon is developped by : Julien Mathis and Romain Le Merlus under +# GPL Licence 2.0. +# +# This program is free software; you can redistribute it and/or modify it under +# the terms of the GNU General Public License as published by the Free Software +# Foundation ; either version 2 of the License. +# +# This program is distributed in the hope that it will be useful, but WITHOUT ANY +# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. See the GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along with +# this program; if not, see . +# +# Linking this program statically or dynamically with other modules is making a +# combined work based on this program. Thus, the terms and conditions of the GNU +# General Public License cover the whole combination. +# +# As a special exception, the copyright holders of this program give MERETHIS +# permission to link this program with independent modules to produce an executable, +# regardless of the license terms of these independent modules, and to copy and +# distribute the resulting executable under terms of MERETHIS choice, provided that +# MERETHIS also meet, for each linked independent module, the terms and conditions +# of the license of that module. An independent module is a module which is not +# derived from this program. If you modify this program, you may extend this +# exception to your version of the program, but you are not obliged to do so. If you +# do not wish to do so, delete this exception statement from your version. +# +# For more information : contact@centreon.com +# Authors : Quentin Garnier +# +#################################################################################### + +package apps::protocols::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; + # $options->{options} = options object + + $self->{version} = '0.1'; + %{$self->{modes}} = ( + 'list-attributes' => 'apps::protocols::jmx::mode::listattributes', + 'numeric-value' => 'apps::protocols::jmx::mode::numericvalue', + ); + + $self->{custom_modes}{jolokia} = 'centreon::common::protocols::jmx::custom::jolokia'; + return $self; +} + +1; + +__END__ + +=head1 PLUGIN DESCRIPTION + +Generic JMX plugin. Need Jolokia agent. + +=cut diff --git a/centreon-plugins/centreon/common/protocols/jmx/custom/jolokia.pm b/centreon-plugins/centreon/common/protocols/jmx/custom/jolokia.pm new file mode 100644 index 000000000..3673108a5 --- /dev/null +++ b/centreon-plugins/centreon/common/protocols/jmx/custom/jolokia.pm @@ -0,0 +1,317 @@ +################################################################################ +# Copyright 2005-2013 MERETHIS +# Centreon is developped by : Julien Mathis and Romain Le Merlus under +# GPL Licence 2.0. +# +# This program is free software; you can redistribute it and/or modify it under +# the terms of the GNU General Public License as published by the Free Software +# Foundation ; either version 2 of the License. +# +# This program is distributed in the hope that it will be useful, but WITHOUT ANY +# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. See the GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along with +# this program; if not, see . +# +# Linking this program statically or dynamically with other modules is making a +# combined work based on this program. Thus, the terms and conditions of the GNU +# General Public License cover the whole combination. +# +# As a special exception, the copyright holders of this program give MERETHIS +# permission to link this program with independent modules to produce an executable, +# regardless of the license terms of these independent modules, and to copy and +# distribute the resulting executable under terms of MERETHIS choice, provided that +# MERETHIS also meet, for each linked independent module, the terms and conditions +# of the license of that module. An independent module is a module which is not +# derived from this program. If you modify this program, you may extend this +# exception to your version of the program, but you are not obliged to do so. If you +# do not wish to do so, delete this exception statement from your version. +# +# For more information : contact@centreon.com +# Authors : Quentin Garnier +# +#################################################################################### + +package centreon::common::protocols::jmx::custom::jolokia; + +use strict; +use warnings; +use JMX::Jmx4Perl; +use JMX::Jmx4Perl::Alias; +use JMX::Jmx4Perl::Request; +use JMX::Jmx4Perl::Util; + +sub new { + my ($class, %options) = @_; + my $self = {}; + bless $self, $class; + # $options{options} = options object + # $options{output} = output object + # $options{exit_value} = integer + # $options{noptions} = integer + + if (!defined($options{output})) { + print "Class Custom: Need to specify 'output' argument.\n"; + exit 3; + } + if (!defined($options{options})) { + $options{output}->add_option_msg(short_msg => "Class Custom: Need to specify 'options' argument."); + $options{output}->option_exit(); + } + + if (!defined($options{noptions})) { + $options{options}->add_options(arguments => + { + "url:s@" => { name => 'url' }, + "timeout:s@" => { name => 'timeout' }, + "username:s@" => { name => 'username' }, + "password:s@" => { name => 'password' }, + "proxy-url:s@" => { name => 'proxy_url' }, + "proxy-username:s@" => { name => 'proxy_username' }, + "proxy-password:s@" => { name => 'proxy_password' }, + "target-url:s@" => { name => 'target_url' }, + "target-username:s@" => { name => 'target_username' }, + "target-password:s@" => { name => 'target_password' }, + }); + } + $options{options}->add_help(package => __PACKAGE__, sections => 'JOLOKIA OPTIONS', once => 1); + + $self->{output} = $options{output}; + $self->{mode} = $options{mode}; + + $self->{jmx4perl} = undef; + 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++) { + foreach my $opt (keys %{$options{default}->{$_}[$i]}) { + if (!defined($self->{option_results}->{$opt}[$i])) { + $self->{option_results}->{$opt}[$i] = $options{default}->{$_}[$i]->{$opt}; + } + } + } + } + } +} + +sub check_options { + my ($self, %options) = @_; + # return 1 = ok still url + # return 0 = no url left + + foreach (('url', 'timeout', 'username', 'password', 'proxy_url', 'proxy_username', + 'proxy_password', 'target_url', 'target_username', 'target_password')) { + $self->{$_} = (defined($self->{option_results}->{$_})) ? shift(@{$self->{option_results}->{$_}}) : undef; + } + + $self->{connect_params} = {}; + if (!defined($self->{url}) || $self->{url} eq '') { + $self->{output}->add_option_msg(short_msg => "Please set option --url."); + $self->{output}->option_exit(); + } + if (defined($self->{timeout}) && $self->{timeout} =~ /^\d+$/ && + $self->{timeout} > 0) { + $self->{timeout} = $self->{timeout}; + } else { + $self->{timeout} = 30; + } + + $self->{connect_params}->{url} = $self->{url}; + $self->{connect_params}->{timeout} = $self->{timeout}; + if (defined($self->{username}) && $self->{username} ne '') { + $self->{connect_params}->{user} = $self->{username}; + $self->{connect_params}->{password} = $self->{password}; + } + if (defined($self->{proxy_url}) && $self->{proxy_url} ne '') { + $self->{connect_params}->{username}->{proxy} = { http => undef, https => undef }; + if ($self->{proxy_url} =~ /^(.*?):/) { + $self->{connect_params}->{username}->{proxy}->{$1} = $self->{proxy_url}; + if (defined($self->{proxy_username}) && $self->{proxy_username} ne '') { + $self->{connect_params}->{proxy_user} = $self->{proxy_username}; + $self->{connect_params}->{proxy_password} = $self->{proxy_password}; + } + } + } + if (defined($self->{target_url}) && $self->{target_url} ne '') { + $self->{connect_params}->{username}->{target} = { url => $self->{target_url}, user => undef, password => undef }; + if (defined($self->{target_username}) && $self->{target_username} ne '') { + $self->{connect_params}->{username}->{target}->{user} = $self->{target_username}; + $self->{connect_params}->{username}->{target}->{password} = $self->{target_password}; + } + } + + if (!defined($self->{url}) || + scalar(@{$self->{option_results}->{url}}) == 0) { + return 0; + } + return 1; +} + +sub connect { + my ($self, %options) = @_; + + $self->{jmx4perl} = new JMX::Jmx4Perl($self->{connect_params}); +} + +sub get_attributes { + my ($self, %options) = @_; + my $dont_quit = defined($options{dont_quit}) && $options{dont_quit} == 1 ? 1 : 0; + + if (!defined($self->{jmx4perl})) { + $self->connect(); + } + + my $resp; + eval { + local $SIG{__DIE__} = 'IGNORE'; + my $attributes = $options{attributes}; + if (defined($attributes) && ref($attributes) eq 'ARRAY' && scalar(@{$attributes}) == 1) { + $attributes = $attributes->[0]; + } + $resp = $self->{jmx4perl}->get_attribute($options{mbean_pattern}, $attributes, $options{path}); + }; + if ($@ && $dont_quit == 0) { + $self->{output}->add_option_msg(short_msg => "protocol issue: " . $@); + $self->{output}->option_exit(); + } + + return $resp; +} + +sub list_attributes { + my ($self, %options) = @_; + my $max_depth = defined($options{max_depth}) ? $options{max_depth} : 5; + my $max_objects = defined($options{max_objects}) ? $options{max_objects} : 100; + my $max_collection_size = defined($options{max_collection_size}) ? $options{max_collection_size} : 50; + my $pattern = defined($options{mbean_pattern}) ? $options{mbean_pattern} : '*:*'; + my $color = 1; + + eval { + local $SIG{__DIE__} = 'IGNORE'; + require Term::ANSIColor; + }; + if ($@) { + $color = 0; + } + + if (!defined($self->{jmx4perl})) { + $self->connect(); + } + + my $mbeans = $self->{jmx4perl}->search($pattern); + print "List attributes:\n"; + for my $mbean (@$mbeans) { + my $request = JMX::Jmx4Perl::Request->new(READ, $mbean, undef, {maxDepth => $max_depth, + maxObjects => $max_objects, + maxCollectionSize => $max_collection_size, + ignoreErrors => 1}); + my $response = $self->{jmx4perl}->request($request); + if ($response->is_error) { + print "ERROR: " . $response->error_text . "\n"; + print JMX::Jmx4Perl::Util->dump_value($response, { format => 'DATA' }); + } else { + my $values = $response->value; + if (keys %$values) { + for my $a (keys %$values) { + print Term::ANSIColor::color('red on_yellow') if ($color == 1); + print "$mbean -- $a"; + print Term::ANSIColor::color('reset') if ($color == 1); + my $val = $values->{$a}; + if (JMX::Jmx4Perl::Util->is_object_to_dump($val)) { + my $v = JMX::Jmx4Perl::Util->dump_value($val, { format => 'DATA' }); + $v =~ s/^\s*//; + print " = " . $v; + } else { + if (my $scal = JMX::Jmx4Perl::Util->dump_scalar($val)) { + print " = " . $scal . "\n"; + } else { + print " = undef\n"; + } + } + } + } + } + } +} + +1; + +__END__ + +=head1 NAME + +JOlokia connector library + +=head1 SYNOPSIS + +my jolokia connector + +=head1 JOLOKIA OPTIONS + +=over 8 + +=item B<--url> + +Url where the jolokia agent is deployed (required). +Example: http://localhost:8080/jolokia + +=item B<--timeout> + +Timeout in seconds for HTTP requests (Defaults: 30 seconds) + +=item B<--username> + +Credentials to use for the HTTP request + +=item B<--password> + +Credentials to use for the HTTP request + +=item B<--proxy-url> + +Optional proxy to use. + +=item B<--proxy-username> + +Credentials to use for the proxy + +=item B<--proxy-password> + +Credentials to use for the proxy + +=item B<--target-url> + +Target to use (if you use jolokia agent as a proxy) + +=item B<--target-username> + +Credentials to use for the target + +=item B<--target-password> + +Credentials to use for the target + +=back + +=head1 DESCRIPTION + +B. + +=cut \ No newline at end of file diff --git a/centreon-plugins/snmp_standard/plugin.pm b/centreon-plugins/snmp_standard/plugin.pm index 267ac4655..313bf3393 100644 --- a/centreon-plugins/snmp_standard/plugin.pm +++ b/centreon-plugins/snmp_standard/plugin.pm @@ -47,8 +47,8 @@ sub new { $self->{version} = '0.1'; %{$self->{modes}} = ( - 'numeric-value' => 'snmp_standard::mode::numericvalue', - 'string-value' => 'snmp_standard::mode::stringvalue', + 'numeric-value' => 'snmp_standard::mode::numericvalue', + 'string-value' => 'snmp_standard::mode::stringvalue', 'dynamic-command' => 'snmp_standard::mode::dynamiccommand', );