+ add a plugin for jmx jolokia agent
This commit is contained in:
parent
850d76609f
commit
abe5c4dd8d
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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',
|
||||
);
|
||||
|
||||
|
|
Loading…
Reference in New Issue