diff --git a/centreon-plugins/apps/oracle/gg/local/custom/cli.pm b/centreon-plugins/apps/oracle/gg/local/custom/cli.pm new file mode 100644 index 000000000..306b9e909 --- /dev/null +++ b/centreon-plugins/apps/oracle/gg/local/custom/cli.pm @@ -0,0 +1,255 @@ +# +# Copyright 2020 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +package apps::oracle::gg::local::custom::cli; + +use strict; +use warnings; +use centreon::plugins::ssh; +use centreon::plugins::misc; + +sub new { + my ($class, %options) = @_; + my $self = {}; + bless $self, $class; + + 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 => { + 'hostname:s' => { name => 'hostname' }, + 'timeout:s' => { name => 'timeout' }, + 'command:s' => { name => 'command' }, + 'command-path:s' => { name => 'command_path' }, + 'command-options:s' => { name => 'command_options' }, + 'sudo:s' => { name => 'sudo' }, + 'ggs-home:s' => { name => 'ggs_home' }, + 'oracle-home:s' => { name => 'oracle_home' } + }); + } + + $options{options}->add_help(package => __PACKAGE__, sections => 'CLI OPTIONS', once => 1); + + $self->{output} = $options{output}; + $self->{ssh} = centreon::plugins::ssh->new(%options); + + return $self; +} + +sub set_options { + my ($self, %options) = @_; + + $self->{option_results} = $options{option_results}; +} + +sub set_defaults {} + +sub check_options { + my ($self, %options) = @_; + + if (defined($self->{option_results}->{timeout}) && $self->{option_results}->{timeout} =~ /(\d+)/) { + $self->{timeout} = $1; + } + if (defined($self->{option_results}->{hostname}) && $self->{option_results}->{hostname} ne '') { + $self->{ssh}->check_options(option_results => $self->{option_results}); + } + + return 0; +} + +sub get_identifier { + my ($self, %options) = @_; + + my $id = defined($self->{option_results}->{hostname}) ? $self->{option_results}->{hostname} : 'me'; + if (defined($self->{option_results}->{hostname}) && $self->{option_results}->{hostname} ne '') { + $id .= ':' . $self->{ssh}->get_port(); + } + return $id; +} + +sub set_local_environment { + my ($self, %options) = @_; + + if (!defined($ENV{GGS_HOME}) || $ENV{GGS_HOME} eq '') { + if (!defined($self->{option_results}->{ggs_home}) || $self->{option_results}->{ggs_home} eq '') { + $self->{output}->add_option_msg(short_msg => "Please set option --ggs-home."); + $self->{output}->option_exit(); + } + + $ENV{GGS_HOME} = $self->{option_results}->{ggs_home}; + } + + if (!defined($ENV{ORACLE_HOME}) || $ENV{ORACLE_HOME} eq '') { + if (!defined($self->{option_results}->{oracle_home_home}) || $self->{option_results}->{oracle_home} eq '') { + $self->{output}->add_option_msg(short_msg => "Please set option --oracle-home."); + $self->{output}->option_exit(); + } + + $ENV{ORACLE_HOME} = $self->{option_results}->{oracle_home}; + $ENV{LD_LIBRARY_PATH} = $ENV{GGS_HOME} . ':' . $ENV{ORACLE_HOME} . '/lib'; + } +} + +sub set_ssh_command { + my ($self, %options) = @_; + + my $env_vars = ''; + my $command = 'ggsci'; + if (!defined($self->{option_results}->{ggs_home})) { + $self->{output}->add_option_msg(short_msg => "Please set option --ggs-home."); + $self->{output}->option_exit(); + } + if ($self->{option_results}->{ggs_home} ne '') { + $command = '"' . $self->{option_results}->{ggs_home} . '/ggsci"'; + } + + if (!defined($self->{option_results}->{oracle_home})) { + $self->{output}->add_option_msg(short_msg => "Please set option --oracle-home."); + $self->{output}->option_exit(); + } + if ($self->{option_results}->{oracle_home} ne '') { + $env_vars = 'export ORACLE_HOME="' . $self->{option_results}->{oracle_home} . '"; '; + $env_vars .= 'export LD_LIBRARY_PATH="' . $self->{option_results}->{oracle_home} . '/lib"; '; + } + + return $env_vars . 'echo "' . $options{commands} . '" | ' . $command; +} + +sub execute_command { + my ($self, %options) = @_; + + my $timeout = $self->{timeout}; + if (!defined($timeout)) { + $timeout = defined($options{timeout}) ? $options{timeout} : 45; + } + + my $command_override = 0; + if (defined($self->{option_results}->{command}) && $self->{option_results}->{command} ne '') { + $command_override = 1; + } + my $command_options = defined($self->{option_results}->{command_options}) && $self->{option_results}->{command_options} ne '' ? $self->{option_results}->{command_options} : $options{command_options}; + + my $command = $self->{option_results}->{command}; + my ($stdout, $exit_code); + if (defined($self->{option_results}->{hostname}) && $self->{option_results}->{hostname} ne '') { + if ($command_override == 0) { + $command = $self->set_ssh_command(commands => $options{commands}); + } + + ($stdout, $exit_code) = $self->{ssh}->execute( + hostname => $self->{option_results}->{hostname}, + sudo => $self->{option_results}->{sudo}, + command => $command, + command_path => defined($self->{option_results}->{command_path}) && $self->{option_results}->{command_path} ne '' ? $self->{option_results}->{command_path} : $options{command_path}, + command_options => $command_options, + timeout => $timeout, + no_quit => $options{no_quit} + ); + } else { + if ($command_override == 0) { + $self->set_local_environment(); + $command = 'echo "' . $options{commands} . '" | "' . $ENV{GGS_HOME} . '/ggsci"'; + } + ($stdout, $exit_code) = centreon::plugins::misc::execute( + output => $self->{output}, + sudo => $self->{option_results}->{sudo}, + options => { timeout => $timeout }, + command => $command, + command_path => defined($self->{option_results}->{command_path}) && $self->{option_results}->{command_path} ne '' ? $self->{option_results}->{command_path} : $options{command_path}, + command_options => $command_options, + no_quit => $options{no_quit} + ); + } + + $self->{output}->output_add(long_msg => "command response: $stdout", debug => 1); + + return ($stdout, $exit_code); +} + +1; + +__END__ + +=head1 NAME + +ggsci cli + +=head1 SYNOPSIS + +ggsci cli + +=head1 CLI OPTIONS + +=over 8 + +=item B<--hostname> + +Hostname to query. + +=item B<--timeout> + +Timeout in seconds for the command (Default: 45). Default value can be override by the mode. + +=item B<--command> + +Command to get information. Used it you have output in a file. + +=item B<--command-path> + +Command path. + +=item B<--command-options> + +Command options. + +=item B<--sudo> + +sudo command. + +=item B<--ggs-home> + +Directory with ggsci command line. + +Mandatory in ssh (you can set it empty if you have an user with GGS_HOME set in PATH environment) + +Mandatory in local if GSS_HOME environment variable is not. + +=item B<--oracle-home> + +Oracle home directory. + +Mandatory in ssh (you can set it empty if you have an user with ORACLE_HOME set in environment) + +Mandatory in local if ORACLE_HOME environment variable is not set. + +=back + +=head1 DESCRIPTION + +B. + +=cut diff --git a/centreon-plugins/apps/oracle/gg/local/mode/processes.pm b/centreon-plugins/apps/oracle/gg/local/mode/processes.pm new file mode 100644 index 000000000..31a5889aa --- /dev/null +++ b/centreon-plugins/apps/oracle/gg/local/mode/processes.pm @@ -0,0 +1,209 @@ +# +# Copyright 2020 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +package apps::oracle::gg::local::mode::processes; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; +use centreon::plugins::templates::catalog_functions qw(catalog_status_threshold_ng); + +sub custom_status_output { + my ($self, %options) = @_; + + return sprintf('status: %s', + $self->{result_values}->{status} + ); +} + +sub prefix_process_output { + my ($self, %options) = @_; + + return sprintf( + "Process '%s' ", + $options{instance_value}->{name} + ); +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'processes', type => 1, cb_prefix_output => 'prefix_process_output', message_multiple => 'All processes are ok', skipped_code => { -10 => 1 } } + ]; + + $self->{maps_counters}->{processes} = [ + { label => 'status', type => 2, critical_default => '%{status} =~ /ABENDED/i', set => { + key_values => [ { name => 'status' }, { name => 'group' }, { name => 'type' }, { name => 'name' } ], + closure_custom_output => $self->can('custom_status_output'), + closure_custom_perfdata => sub { return 0; }, + closure_custom_threshold_check => \&catalog_status_threshold_ng + } + }, + { label => 'lag', nlabel => 'process.lag.seconds', set => { + key_values => [ { name => 'lag_secs' }, { name => 'lag_human' } ], + output_template => 'lag: %s', + output_use => 'lag_human', + perfdatas => [ + { template => '%s', min => 0, unit => 's', label_extra_instance => 1 } + ] + } + }, + { label => 'time-checkpoint', nlabel => 'process.time.checkpoint.seconds', set => { + key_values => [ { name => 'time_secs' }, { name => 'time_human' } ], + output_template => 'time since checkpoint: %s', + output_use => 'time_human', + perfdatas => [ + { template => '%s', min => 0, unit => 's', label_extra_instance => 1 } + ] + } + } + ]; +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options, force_new_perfdata => 1); + bless $self, $class; + + $options{options}->add_options(arguments => { + 'filter-name:s' => { name => 'filter_name' }, + 'filter-group:s' => { name => 'filter_group' }, + 'filter-type:s' => { name => 'filter_type' } + }); + + return $self; +} + +sub manage_selection { + my ($self, %options) = @_; + + my ($stdout) = $options{custom}->execute_command( + commands => 'INFO ALL' + ); + + $self->{processes} = {}; + while ($stdout =~ /^(MANAGER|EXTRACT|REPLICAT)\s+(\S+)(.*?)(?:\n|\Z)/msig) { + my ($type, $status, $data) = ($1, $2, $3); + + if (defined($self->{option_results}->{filter_type}) && $self->{option_results}->{filter_type} ne '' && + $type !~ /$self->{option_results}->{filter_type}/) { + $self->{output}->output_add(long_msg => "skipping process '" . $type . "': no matching filter.", debug => 1); + next; + } + + if ($type eq 'MANAGER') { + $self->{processes}->{$type} = { + status => $status, + name => $type, + type => $type, + group => '-' + }; + next; + } + + next if ($data !~ /\s*(\S+)\s*(?:(\d+:\d+:\d+)\s+(\d+:\d+:\d+))?/); + + my ($group, $lag, $time) = ($1, $2, $3); + my $name = $type . ':' . $group; + if (defined($self->{option_results}->{filter_group}) && $self->{option_results}->{filter_group} ne '' && + $group !~ /$self->{option_results}->{filter_group}/) { + $self->{output}->output_add(long_msg => "skipping process '" . $group . "': no matching filter.", debug => 1); + next; + } + if (defined($self->{option_results}->{filter_name}) && $self->{option_results}->{filter_name} ne '' && + $name !~ /$self->{option_results}->{filter_name}/) { + $self->{output}->output_add(long_msg => "skipping process '" . $group . "': no matching filter.", debug => 1); + next; + } + + $self->{processes}->{$name} = { + status => $status, + name => $name, + type => $type, + group => $group + }; + + next if ($status eq 'STOPPED'); + + if (defined($lag)) { + my ($hour, $min, $sec) = split(/:/, $lag); + my $lag_secs = ($hour * 3600) + ($min * 60) + $sec; + $self->{processes}->{$name}->{lag_secs} = $lag_secs; + $self->{processes}->{$name}->{lag_human} = centreon::plugins::misc::change_seconds(value => $self->{processes}->{$name}->{lag_secs}); + } + if (defined($time)) { + my ($hour, $min, $sec) = split(/:/, $time); + my $time_secs = ($hour * 3600) + ($min * 60) + $sec; + $self->{processes}->{$name}->{time_secs} = $time_secs; + $self->{processes}->{$name}->{time_human} = centreon::plugins::misc::change_seconds(value => $self->{processes}->{$name}->{time_secs}); + } + } + +} + +1; + +__END__ + +=head1 MODE + +Check processes. + +=over 8 + +=item B<--filter-name> + +Filter processes by name (can be a regexp). + +name is the following concatenation: type:group (eg.: EXTRACT:DB_test) + +=item B<--filter-group> + +Filter processes by group (can be a regexp). + +=item B<--filter-type> + +Filter processes by type (can be a regexp). + +=item B<--unknown-status> + +Set unknown threshold for status. +Can used special variables like: %{status}, %{name}, %{group}, %{type} + +=item B<--warning-status> + +Set warning threshold for status. +Can used special variables like: %{status}, %{name}, %{group}, %{type} + +=item B<--critical-status> + +Set critical threshold for status (Default: '%{status} =~ /ABENDED/i'). +Can used special variables like: %{status}, %{name}, %{group}, %{type} + +=item B<--warning-*> B<--critical-*> + +Thresholds. +Can be: 'lag' (s), 'time-checkpoint' (s). + +=back + +=cut diff --git a/centreon-plugins/apps/oracle/gg/local/plugin.pm b/centreon-plugins/apps/oracle/gg/local/plugin.pm new file mode 100644 index 000000000..9b348564b --- /dev/null +++ b/centreon-plugins/apps/oracle/gg/local/plugin.pm @@ -0,0 +1,49 @@ +# +# Copyright 2020 Centreon (http://www.centreon.com/) +# +# Centreon is a full-fledged industry-strength solution that meets +# the needs in IT infrastructure and application monitoring for +# service performance. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +package apps::oracle::gg::local::plugin; + +use strict; +use warnings; +use base qw(centreon::plugins::script_custom); + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + bless $self, $class; + + $self->{version} = '0.1'; + $self->{modes} = { + 'processes' => 'apps::oracle::gg::local::mode::processes' + }; + + $self->{custom_modes}->{cli} = 'apps::oracle::gg::local::custom::cli'; + return $self; +} + +1; + +__END__ + +=head1 PLUGIN DESCRIPTION + +Check Oracle GoldenGate with ggsci command line. + +=cut