From b879729770304f65c6b2ef4e3f53002c550d8a69 Mon Sep 17 00:00:00 2001 From: qgarnier Date: Tue, 16 Mar 2021 15:50:34 +0100 Subject: [PATCH] Enh nginx serverstatus (#2655) --- .../apps/nginx/serverstatus/custom/api.pm | 180 ++++++++++++ .../nginx/serverstatus/mode/connections.pm | 159 +++-------- .../apps/nginx/serverstatus/mode/requests.pm | 266 ++++++++---------- .../nginx/serverstatus/mode/responsetime.pm | 165 ----------- .../apps/nginx/serverstatus/plugin.pm | 12 +- 5 files changed, 345 insertions(+), 437 deletions(-) create mode 100644 centreon-plugins/apps/nginx/serverstatus/custom/api.pm delete mode 100644 centreon-plugins/apps/nginx/serverstatus/mode/responsetime.pm diff --git a/centreon-plugins/apps/nginx/serverstatus/custom/api.pm b/centreon-plugins/apps/nginx/serverstatus/custom/api.pm new file mode 100644 index 000000000..5c05180c7 --- /dev/null +++ b/centreon-plugins/apps/nginx/serverstatus/custom/api.pm @@ -0,0 +1,180 @@ +# +# Copyright 2021 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::nginx::serverstatus::custom::api; + +use base qw(centreon::plugins::mode); + +use strict; +use warnings; +use centreon::plugins::http; + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options); + 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' }, + 'port:s' => { name => 'port'}, + 'proto:s' => { name => 'proto' }, + 'endpoint:s' => { name => 'endpoint', default => '/nginx_status' }, + 'username:s' => { name => 'username' }, + 'password:s' => { name => 'password' }, + 'timeout:s' => { name => 'timeout', default => 30 }, + 'unknown-http-status:s' => { name => 'unknown_http_status' }, + 'warning-http-status:s' => { name => 'warning_http_status' }, + 'critical-http-status:s' => { name => 'critical_http_status' } + }); + } + + $options{options}->add_help(package => __PACKAGE__, sections => 'NGINX OPTIONS', once => 1); + + $self->{output} = $options{output}; + $self->{http} = centreon::plugins::http->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) = @_; + + $self->{hostname} = (defined($self->{option_results}->{hostname})) ? $self->{option_results}->{hostname} : ''; + $self->{port} = (defined($self->{option_results}->{port})) ? $self->{option_results}->{port} : 80; + $self->{proto} = (defined($self->{option_results}->{proto})) ? $self->{option_results}->{proto} : 'http'; + $self->{endpoint} = (defined($self->{option_results}->{endpoint}) && $self->{option_results}->{endpoint} ne '') ? $self->{option_results}->{endpoint} : '/nginx_status'; + $self->{timeout} = (defined($self->{option_results}->{timeout})) ? $self->{option_results}->{timeout} : 30; + $self->{username} = (defined($self->{option_results}->{username})) ? $self->{option_results}->{username} : ''; + $self->{password} = (defined($self->{option_results}->{password})) ? $self->{option_results}->{password} : ''; + $self->{unknown_http_status} = (defined($self->{option_results}->{unknown_http_status})) ? $self->{option_results}->{unknown_http_status} : '%{http_code} < 200 or %{http_code} >= 300'; + $self->{warning_http_status} = (defined($self->{option_results}->{warning_http_status})) ? $self->{option_results}->{warning_http_status} : ''; + $self->{critical_http_status} = (defined($self->{option_results}->{critical_http_status})) ? $self->{option_results}->{critical_http_status} : ''; + + if ($self->{hostname} eq '') { + $self->{output}->add_option_msg(short_msg => "Need to specify --hostname option."); + $self->{output}->option_exit(); + } + + return 0; +} + +sub build_options_for_httplib { + my ($self, %options) = @_; + + $self->{option_results}->{hostname} = $self->{hostname}; + $self->{option_results}->{port} = $self->{port}; + $self->{option_results}->{proto} = $self->{proto}; + $self->{option_results}->{timeout} = $self->{timeout}; + if ($self->{username} ne '') { + $self->{option_results}->{credentials} = 1; + $self->{option_results}->{basic} = 1; + $self->{option_results}->{username} = $self->{username}; + $self->{option_results}->{password} = $self->{password}; + } +} + +sub settings { + my ($self, %options) = @_; + + $self->build_options_for_httplib(); + $self->{http}->set_options(%{$self->{option_results}}); +} + +sub get_connection_info { + my ($self, %options) = @_; + + return $self->{hostname} . ":" . $self->{port}; +} + +sub get_status { + my ($self, %options) = @_; + + $self->settings(); + my ($content) = $self->{http}->request( + url_path => $self->{endpoint}, + unknown_status => $self->{unknown_http_status}, + warning_status => $self->{warning_http_status}, + critical_status => $self->{critical_http_status} + ); + + return $content; +} + +1; + +__END__ + +=head1 NAME + +Nginx server-status + +=head1 NGINX OPTIONS + +=over 8 + +=item B<--hostname> + +IP Addr/FQDN of the webserver host + +=item B<--port> + +Port used by the webserver (Default: 80) + +=item B<--proto> + +Specify https if needed + +=item B<--endpoint> + +Set path to get server-status page (Default: '/nginx_status') + +=item B<--username> + +Specify username for basic authentication. + +=item B<--password> + +Specify password for basic authentication + +=item B<--timeout> + +HTTP timeout + +=back + +=cut diff --git a/centreon-plugins/apps/nginx/serverstatus/mode/connections.pm b/centreon-plugins/apps/nginx/serverstatus/mode/connections.pm index 670ca424c..3ffd3a8a0 100644 --- a/centreon-plugins/apps/nginx/serverstatus/mode/connections.pm +++ b/centreon-plugins/apps/nginx/serverstatus/mode/connections.pm @@ -20,89 +20,65 @@ package apps::nginx::serverstatus::mode::connections; -use base qw(centreon::plugins::mode); +use base qw(centreon::plugins::templates::counter); use strict; use warnings; -use centreon::plugins::http; -my $maps = [ - { counter => 'active', output => 'Active connections %d', match => 'Active connections:\s*(\d+)' }, - { counter => 'reading', output => 'Reading connections %d', match => 'Reading:\s*(\d+)' }, - { counter => 'writing', output => 'Writing connections %d', match => 'Writing:\s*(\d+)' }, - { counter => 'waiting', output => 'Waiting connections %d', match => 'Waiting:\s*(\d+)' }, -]; +sub prefix_global_output { + my ($self, %options) = @_; + + return 'Connections '; +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'global', cb_prefix_output => 'prefix_global_output', type => 0 } + ]; + + $self->{maps_counters}->{global} = []; + foreach (('active', 'reading', 'writing', 'waiting')) { + push @{$self->{maps_counters}->{global}}, + { label => 'connections-' . $_, nlabel => 'server.connections.' . $_ . '.count', set => { + key_values => [ { name => $_ }, { name => 'total' } ], + output_template => $_ . ': %d', + perfdatas => [ + { template => '%d', min => 0, max => 'total' } + ] + } + }; + } +} sub new { my ($class, %options) = @_; - my $self = $class->SUPER::new(package => __PACKAGE__, %options); + my $self = $class->SUPER::new(package => __PACKAGE__, %options, force_new_perfdata => 1); bless $self, $class; $options{options}->add_options(arguments => { - "hostname:s" => { name => 'hostname' }, - "port:s" => { name => 'port', }, - "proto:s" => { name => 'proto' }, - "urlpath:s" => { name => 'url_path', default => "/nginx_status" }, - "credentials" => { name => 'credentials' }, - "basic" => { name => 'basic' }, - "username:s" => { name => 'username' }, - "password:s" => { name => 'password' }, - "timeout:s" => { name => 'timeout' }, }); - foreach (@{$maps}) { - $options{options}->add_options(arguments => { - 'warning-' . $_->{counter} . ':s' => { name => 'warning_' . $_->{counter} }, - 'critical-' . $_->{counter} . ':s' => { name => 'critical_' . $_->{counter} }, - }); - } - - $self->{http} = centreon::plugins::http->new(%options); + return $self; } -sub check_options { +sub manage_selection { my ($self, %options) = @_; - $self->SUPER::init(%options); - foreach (@{$maps}) { - if (($self->{perfdata}->threshold_validate(label => 'warning-' . $_->{counter}, value => $self->{option_results}->{'warning_' . $_->{counter}})) == 0) { - $self->{output}->add_option_msg(short_msg => "Wrong warning-" . $_->{counter} . " threshold '" . $self->{option_results}->{'warning_' . $_->{counter}} . "'."); - $self->{output}->option_exit(); - } - if (($self->{perfdata}->threshold_validate(label => 'critical-' . $_->{counter}, value => $self->{option_results}->{'critical_' . $_->{counter}})) == 0) { - $self->{output}->add_option_msg(short_msg => "Wrong critical-" . $_->{counter} . " threshold '" . $self->{option_results}->{'critical_' . $_->{counter}} . "'."); - $self->{output}->option_exit(); - } + my $content = $options{custom}->get_status(); + $self->{global} = {}; + $self->{global}->{active} = $1 if ($content =~ /Active connections:\s*(\d+)/msi); + $self->{global}->{reading} = $1 if ($content =~ /Reading:\s*(\d+)/msi); + $self->{global}->{writing} = $1 if ($content =~ /Writing:\s*(\d+)/msi); + $self->{global}->{waiting} = $1 if ($content =~ /Waiting:\s*(\d+)/msi); + if (!defined($self->{global}->{active})) { + $self->{output}->add_option_msg(short_msg => 'Cannot find connection informations.'); + $self->{output}->option_exit(); } - - $self->{http}->set_options(%{$self->{option_results}}); -} - -sub run { - my ($self, %options) = @_; - - my $webcontent = $self->{http}->request(); - foreach (@{$maps}) { - if ($webcontent !~ /$_->{match}/msi) { - $self->{output}->output_add(severity => 'UNKNOWN', - short_msg => "Cannot find " . $_->{counter} . " connections."); - next; - } - my $value = $1; - my $exit = $self->{perfdata}->threshold_check(value => $value, threshold => [ { label => 'critical-' . $_->{counter}, 'exit_litteral' => 'critical' }, { label => 'warning-' . $_->{counter}, 'exit_litteral' => 'warning' }]); - - $self->{output}->output_add(severity => $exit, - short_msg => sprintf($_->{output}, $value)); - - $self->{output}->perfdata_add(label => $_->{counter}, - value => $value, - warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $_->{counter}), - critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $_->{counter}), - min => 0); - } - - $self->{output}->display(); - $self->{output}->exit(); + my $total = 0; + $total += $self->{global}->{$_} foreach (keys %{$self->{global}}); + $self->{global}->{total} = $total; } 1; @@ -111,57 +87,14 @@ __END__ =head1 MODE -Check current connections: active, reading, writing, waiting. +Check current connections. =over 8 -=item B<--hostname> +=item B<--warning-*> B<--critical-*> -IP Addr/FQDN of the webserver host - -=item B<--port> - -Port used by Apache - -=item B<--proto> - -Protocol to use http or https, http is default - -=item B<--urlpath> - -Set path to get server-status page in auto mode (Default: '/nginx_status') - -=item B<--credentials> - -Specify this option if you access server-status page with authentication - -=item B<--username> - -Specify username for authentication (Mandatory if --credentials is specified) - -=item B<--password> - -Specify password for authentication (Mandatory if --credentials is specified) - -=item B<--basic> - -Specify this option if you access server-status page over basic authentication and don't want a '401 UNAUTHORIZED' error to be logged on your webserver. - -Specify this option if you access server-status page over hidden basic authentication or you'll get a '404 NOT FOUND' error. - -(Use with --credentials) - -=item B<--timeout> - -Threshold for HTTP timeout - -=item B<--warning-*> - -Warning Threshold. Can be: 'active', 'waiting', 'writing', 'reading'. - -=item B<--critical-*> - -Critical Threshold. Can be: 'active', 'waiting', 'writing', 'reading'. +Thresholds. +Can be: 'connections-active', 'connections-waiting', 'connections-writing', 'connections-reading'. =back diff --git a/centreon-plugins/apps/nginx/serverstatus/mode/requests.pm b/centreon-plugins/apps/nginx/serverstatus/mode/requests.pm index d38d24dff..2bcefd17b 100644 --- a/centreon-plugins/apps/nginx/serverstatus/mode/requests.pm +++ b/centreon-plugins/apps/nginx/serverstatus/mode/requests.pm @@ -20,137 +20,136 @@ package apps::nginx::serverstatus::mode::requests; -use base qw(centreon::plugins::mode); +use base qw(centreon::plugins::templates::counter); use strict; use warnings; -use centreon::plugins::http; -use centreon::plugins::statefile; +use POSIX; +use Digest::MD5 qw(md5_hex); -my $maps = [ - { counter => 'accepts', output => 'Connections accepted per seconds %.2f', match => 'server accepts handled requests.*?(\d+)' }, - { counter => 'handled', output => 'Connections handled per serconds %.2f', match => 'server accepts handled requests.*?\d+\s+(\d+)' }, - { counter => 'requests', output => 'Requests per seconds %.2f', match => 'server accepts handled requests.*?\d+\s+\d+\s+(\d+)' }, -]; +sub custom_requests_perfdata { + my ($self, %options) = @_; + + my $nlabel = $self->{nlabel}; + if (defined($self->{instance_mode}->{option_results}->{per_minute})) { + $nlabel =~ s/persecond/perminute/; + } + $self->{output}->perfdata_add( + nlabel => $nlabel, + value => sprintf('%.2f', $self->{result_values}->{value}), + warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $self->{thlabel}), + critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $self->{thlabel}), + min => 0 + ); +} + +sub custom_requests_calc { + my ($self, %options) = @_; + + my $diff_value = ($options{new_datas}->{ $self->{instance} . '_' . $options{extra_options}->{metric} } - $options{old_datas}->{ $self->{instance} . '_' . $options{extra_options}->{metric} }); + $self->{result_values}->{value} = $diff_value / $options{delta_time}; + if (defined($self->{instance_mode}->{option_results}->{per_minute})) { + $self->{result_values}->{value} = $diff_value / ceil($options{delta_time} / 60); + } + $self->{result_values}->{output_str} = sprintf( + $options{extra_options}->{output_str} . (defined($self->{instance_mode}->{option_results}->{per_minute}) ? '/min' : '/s'), + $self->{result_values}->{value} + ); + return 0; +} + +sub custom_dropped_calc { + my ($self, %options) = @_; + + $self->{result_values}->{dropped} = + ($options{new_datas}->{ $self->{instance} . '_accepts' } - $options{old_datas}->{ $self->{instance} . '_accepts' }) - + ($options{new_datas}->{ $self->{instance} . '_handled' } - $options{old_datas}->{ $self->{instance} . '_handled' }); + return 0; +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'global', type => 0, message_separator => ' - ' } + ]; + + $self->{maps_counters}->{global} = [ + { label => 'connections-accepted', nlabel => 'server.connections.accepted.persecond', set => { + key_values => [ { name => 'accepts', diff => 1 } ], + closure_custom_calc => $self->can('custom_requests_calc'), + closure_custom_calc_extra_options => { metric => 'accepts', output_str => 'connections accepted: %.2f' }, + output_template => '%s', + output_use => 'output_str', threshold_use => 'value', + closure_custom_perfdata => $self->can('custom_requests_perfdata') + } + }, + { label => 'connections-handled', nlabel => 'server.connections.handled.persecond', set => { + key_values => [ { name => 'handled', diff => 1 } ], + closure_custom_calc => $self->can('custom_requests_calc'), + closure_custom_calc_extra_options => { metric => 'handled', output_str => 'connections handled: %.2f' }, + output_template => '%s', + output_use => 'output_str', threshold_use => 'value', + closure_custom_perfdata => $self->can('custom_requests_perfdata') + } + }, + { label => 'connections-dropped', nlabel => 'server.connections.dropped.count', set => { + key_values => [ { name => 'accepts', diff => 1 }, { name => 'handled', diff => 1 } ], + closure_custom_calc => $self->can('custom_dropped_calc'), + output_template => 'connections dropped: %d', + output_use => 'dropped', threshold_use => 'dropped', + perfdatas => [ + { value => 'dropped', template => '%d', min => 0 } + ] + } + }, + { label => 'requests', nlabel => 'server.requests.persecond', set => { + key_values => [ { name => 'requests', diff => 1 } ], + closure_custom_calc => $self->can('custom_requests_calc'), + closure_custom_calc_extra_options => { metric => 'requests', output_str => 'requests: %.2f' }, + output_template => '%s', + output_use => 'output_str', threshold_use => 'value', + closure_custom_perfdata => $self->can('custom_requests_perfdata') + } + } + ]; +} sub new { my ($class, %options) = @_; - my $self = $class->SUPER::new(package => __PACKAGE__, %options); + my $self = $class->SUPER::new(package => __PACKAGE__, %options, statefile => 1, force_new_perfdata => 1); bless $self, $class; $options{options}->add_options(arguments => { - "hostname:s" => { name => 'hostname' }, - "port:s" => { name => 'port', }, - "proto:s" => { name => 'proto' }, - "urlpath:s" => { name => 'url_path', default => "/nginx_status" }, - "credentials" => { name => 'credentials' }, - "basic" => { name => 'basic' }, - "username:s" => { name => 'username' }, - "password:s" => { name => 'password' }, - "timeout:s" => { name => 'timeout' }, + 'per-minute' => { name => 'per_minute' } }); - foreach (@{$maps}) { - $options{options}->add_options(arguments => { - 'warning-' . $_->{counter} . ':s' => { name => 'warning_' . $_->{counter} }, - 'critical-' . $_->{counter} . ':s' => { name => 'critical_' . $_->{counter} }, - }); - } - $self->{statefile_value} = centreon::plugins::statefile->new(%options); - $self->{http} = centreon::plugins::http->new(%options); + return $self; } sub check_options { my ($self, %options) = @_; - $self->SUPER::init(%options); + $self->{maps_counters}->{global}->[0]->{nlabel} = 'toto'; + $self->SUPER::check_options(%options); - foreach (@{$maps}) { - if (($self->{perfdata}->threshold_validate(label => 'warning-' . $_->{counter}, value => $self->{option_results}->{'warning_' . $_->{counter}})) == 0) { - $self->{output}->add_option_msg(short_msg => "Wrong warning-" . $_->{counter} . " threshold '" . $self->{option_results}->{'warning_' . $_->{counter}} . "'."); - $self->{output}->option_exit(); - } - if (($self->{perfdata}->threshold_validate(label => 'critical-' . $_->{counter}, value => $self->{option_results}->{'critical_' . $_->{counter}})) == 0) { - $self->{output}->add_option_msg(short_msg => "Wrong critical-" . $_->{counter} . " threshold '" . $self->{option_results}->{'critical_' . $_->{counter}} . "'."); - $self->{output}->option_exit(); - } - } - - $self->{statefile_value}->check_options(%options); - $self->{http}->set_options(%{$self->{option_results}}); } -sub run { +sub manage_selection { my ($self, %options) = @_; - my $webcontent = $self->{http}->request(); - my ($buffer_creation, $exit) = (0, 0); - my $new_datas = {}; - my $old_datas = {}; - - $self->{statefile_value}->read(statefile => 'nginx_' . $self->{option_results}->{hostname} . '_' . $self->{http}->get_port() . '_' . $self->{mode}); - $old_datas->{timestamp} = $self->{statefile_value}->get(name => 'timestamp'); - $new_datas->{timestamp} = time(); - foreach (@{$maps}) { - if ($webcontent !~ /$_->{match}/msi) { - $self->{output}->output_add(severity => 'UNKNOWN', - short_msg => "Cannot find " . $_->{counter} . " information."); - next; - } - - $new_datas->{$_->{counter}} = $1; - my $tmp_value = $self->{statefile_value}->get(name => $_->{counter}); - if (!defined($tmp_value)) { - $buffer_creation = 1; - next; - } - if ($new_datas->{$_->{counter}} < $tmp_value) { - $buffer_creation = 1; - next; - } - - $exit = 1; - $old_datas->{$_->{counter}} = $tmp_value; + my $content = $options{custom}->get_status(); + if ($content !~ /server accepts handled requests.*?(\d+)\s+(\d+)\s+(\d+)/msi) { + $self->{output}->add_option_msg(short_msg => 'Cannot find request informations.'); + $self->{output}->option_exit(); } - - $self->{statefile_value}->write(data => $new_datas); - if ($buffer_creation == 1) { - $self->{output}->output_add(severity => 'OK', - short_msg => "Buffer creation..."); - if ($exit == 0) { - $self->{output}->display(); - $self->{output}->exit(); - } - } - - foreach (@{$maps}) { - # In buffer creation. - next if (!defined($old_datas->{$_->{counter}})); - if ($new_datas->{$_->{counter}} - $old_datas->{$_->{counter}} == 0) { - $self->{output}->output_add(severity => 'OK', - short_msg => "Counter '" . $_->{counter} . "' not moved. Have to wait."); - next; - } - - my $delta_time = $new_datas->{timestamp} - $old_datas->{timestamp}; - $delta_time = 1 if ($delta_time <= 0); - - my $value = ($new_datas->{$_->{counter}} - $old_datas->{$_->{counter}}) / $delta_time; - my $exit = $self->{perfdata}->threshold_check(value => $value, threshold => [ { label => 'critical-' . $_->{counter}, 'exit_litteral' => 'critical' }, { label => 'warning-' . $_->{counter}, 'exit_litteral' => 'warning' }]); - - $self->{output}->output_add(severity => $exit, - short_msg => sprintf($_->{output}, $value)); - - $self->{output}->perfdata_add(label => $_->{counter}, - value => sprintf('%.2f', $value), - warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-' . $_->{counter}), - critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-' . $_->{counter}), - min => 0); - - } - - $self->{output}->display(); - $self->{output}->exit(); + $self->{global} = { + accepts => $1, + handled => $2, + requests => $3 + }; + $self->{cache_name} = 'nginx_' . $self->{mode} . '_' . md5_hex($options{custom}->get_connection_info()) . '_' . + (defined($self->{option_results}->{filter_counters}) ? md5_hex($self->{option_results}->{filter_counters}) : md5_hex('all')); } 1; @@ -159,57 +158,18 @@ __END__ =head1 MODE -Check Nginx Request statistics: number of accepted connections per seconds, number of handled connections per seconds, number of requests per seconds. +Check Nginx request statistics. =over 8 -=item B<--hostname> +=item B<--per-minute> -IP Addr/FQDN of the webserver host +Per second metrics are computed per minute. -=item B<--port> +=item B<--warning-*> B<--critical-*> -Port used by Apache - -=item B<--proto> - -Specify https if needed - -=item B<--urlpath> - -Set path to get server-status page in auto mode (Default: '/nginx_status') - -=item B<--credentials> - -Specify this option if you access server-status page with authentication - -=item B<--username> - -Specify username for authentication (Mandatory if --credentials is specified) - -=item B<--password> - -Specify password for authentication (Mandatory if --credentials is specified) - -=item B<--basic> - -Specify this option if you access server-status page over basic authentication and don't want a '401 UNAUTHORIZED' error to be logged on your webserver. - -Specify this option if you access server-status page over hidden basic authentication or you'll get a '404 NOT FOUND' error. - -(Use with --credentials) - -=item B<--timeout> - -Threshold for HTTP timeout - -=item B<--warning-*> - -Warning Threshold. Can be: 'accepts', 'handled', 'requests'. - -=item B<--critical-*> - -Critical Threshold. Can be: 'accepts', 'handled', 'requests'. +Thresholds. +Can be: 'connections-accepted', 'connections-handled', 'requests'. =back diff --git a/centreon-plugins/apps/nginx/serverstatus/mode/responsetime.pm b/centreon-plugins/apps/nginx/serverstatus/mode/responsetime.pm deleted file mode 100644 index 1abcd1268..000000000 --- a/centreon-plugins/apps/nginx/serverstatus/mode/responsetime.pm +++ /dev/null @@ -1,165 +0,0 @@ -# -# Copyright 2021 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::nginx::serverstatus::mode::responsetime; - -use base qw(centreon::plugins::mode); - -use strict; -use warnings; -use Time::HiRes qw(gettimeofday tv_interval); -use centreon::plugins::http; - -sub new { - my ($class, %options) = @_; - my $self = $class->SUPER::new(package => __PACKAGE__, %options); - bless $self, $class; - - $options{options}->add_options(arguments => { - "hostname:s" => { name => 'hostname' }, - "port:s" => { name => 'port', }, - "proto:s" => { name => 'proto' }, - "urlpath:s" => { name => 'url_path', default => "/nginx_status" }, - "credentials" => { name => 'credentials' }, - "basic" => { name => 'basic' }, - "username:s" => { name => 'username' }, - "password:s" => { name => 'password' }, - "warning:s" => { name => 'warning' }, - "critical:s" => { name => 'critical' }, - "timeout:s" => { name => 'timeout' }, - "unknown-status:s" => { name => 'unknown_status', default => '' }, - "warning-status:s" => { name => 'warning_status' }, - "critical-status:s" => { name => 'critical_status', default => '%{http_code} < 200 or %{http_code} >= 300' }, - }); - $self->{http} = centreon::plugins::http->new(%options); - return $self; -} - -sub check_options { - my ($self, %options) = @_; - $self->SUPER::init(%options); - - if (($self->{perfdata}->threshold_validate(label => 'warning', value => $self->{option_results}->{warning})) == 0) { - $self->{output}->add_option_msg(short_msg => "Wrong warning threshold '" . $self->{option_results}->{warning} . "'."); - $self->{output}->option_exit(); - } - if (($self->{perfdata}->threshold_validate(label => 'critical', value => $self->{option_results}->{critical})) == 0) { - $self->{output}->add_option_msg(short_msg => "Wrong critical threshold '" . $self->{option_results}->{critical} . "'."); - $self->{output}->option_exit(); - } - - $self->{http}->set_options(%{$self->{option_results}}); -} - -sub run { - my ($self, %options) = @_; - - my $timing0 = [gettimeofday]; - - my $webcontent = $self->{http}->request(); - - my $timeelapsed = tv_interval ($timing0, [gettimeofday]); - - my $exit = $self->{perfdata}->threshold_check(value => $timeelapsed, - threshold => [ { label => 'critical', exit_litteral => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]); - $self->{output}->output_add(severity => $exit, - short_msg => sprintf("Response time %fs ", $timeelapsed)); - $self->{output}->perfdata_add(label => "time", - value => $timeelapsed, - warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning'), - critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical')); - - $self->{output}->display(); - $self->{output}->exit(); -} - -1; - -__END__ - -=head1 MODE - -Check Nginx WebServer statistics informations - -=over 8 - -=item B<--hostname> - -IP Addr/FQDN of the webserver host - -=item B<--port> - -Port used by Apache - -=item B<--proto> - -Specify https if needed - -=item B<--urlpath> - -Set path to get server-status page in auto mode (Default: '/nginx_status') - -=item B<--credentials> - -Specify this option if you access server-status page with authentication - -=item B<--username> - -Specify username for authentication (Mandatory if --credentials is specified) - -=item B<--password> - -Specify password for authentication (Mandatory if --credentials is specified) - -=item B<--basic> - -Specify this option if you access server-status page over basic authentication and don't want a '401 UNAUTHORIZED' error to be logged on your webserver. - -Specify this option if you access server-status page over hidden basic authentication or you'll get a '404 NOT FOUND' error. - -(Use with --credentials) - -=item B<--timeout> - -Threshold for HTTP timeout - -=item B<--unknown-status> - -Threshold warning for http response code - -=item B<--warning-status> - -Threshold warning for http response code - -=item B<--critical-status> - -Threshold critical for http response code (Default: '%{http_code} < 200 or %{http_code} >= 300') - -=item B<--warning> - -Threshold warning in seconds (nginx_status page response time) - -=item B<--critical> - -Threshold critical in seconds (nginx_status page response time) - -=back - -=cut diff --git a/centreon-plugins/apps/nginx/serverstatus/plugin.pm b/centreon-plugins/apps/nginx/serverstatus/plugin.pm index a7b9314b9..7fc6cf447 100644 --- a/centreon-plugins/apps/nginx/serverstatus/plugin.pm +++ b/centreon-plugins/apps/nginx/serverstatus/plugin.pm @@ -22,7 +22,7 @@ package apps::nginx::serverstatus::plugin; use strict; use warnings; -use base qw(centreon::plugins::script_simple); +use base qw(centreon::plugins::script_custom); sub new { my ($class, %options) = @_; @@ -30,12 +30,12 @@ sub new { bless $self, $class; $self->{version} = '0.1'; - %{$self->{modes}} = ( - 'connections' => 'apps::nginx::serverstatus::mode::connections', - 'responsetime' => 'apps::nginx::serverstatus::mode::responsetime', - 'requests' => 'apps::nginx::serverstatus::mode::requests', - ); + $self->{modes} = { + 'connections' => 'apps::nginx::serverstatus::mode::connections', + 'requests' => 'apps::nginx::serverstatus::mode::requests' + }; + $self->{custom_modes}->{api} = 'apps::nginx::serverstatus::custom::api'; return $self; }