+ add a plugin for jmx jolokia agent

This commit is contained in:
garnier-quentin 2015-06-04 14:42:28 +02:00
parent 850d76609f
commit abe5c4dd8d
5 changed files with 810 additions and 2 deletions

View File

@ -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 <http://www.gnu.org/licenses>.
#
# 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 <qgarnier@merethis.com>
#
####################################################################################
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

View File

@ -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 <http://www.gnu.org/licenses>.
#
# 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 <qgarnier@merethis.com>
#
####################################################################################
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

View File

@ -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 <http://www.gnu.org/licenses>.
#
# 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 <qgarnier@merethis.com>
#
####################################################################################
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

View File

@ -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 <http://www.gnu.org/licenses>.
#
# 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 <qgarnier@merethis.com>
#
####################################################################################
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<custom>.
=cut

View File

@ -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',
);