From e04e5519b50ab8045a7a33bb7c32995e06bc4844 Mon Sep 17 00:00:00 2001 From: scresto Date: Fri, 4 Jul 2025 17:40:37 +0200 Subject: [PATCH] Plugin(apps::apache::serverstatus) - Modes (requests - slotstates) : Add nlabel and force new perfdata (#5657) Breaking change Refs:CTOR-382 --- src/apps/apache/serverstatus/mode/requests.pm | 196 ++++++++++-------- .../apache/serverstatus/mode/slotstates.pm | 121 +++++++++-- tests/apps/apache/serverstatus/requests.robot | 44 ++++ .../serverstatus/serverstatus.mockoon.json | 139 +++++++++++++ .../apps/apache/serverstatus/slotstates.robot | 39 ++++ 5 files changed, 440 insertions(+), 99 deletions(-) create mode 100644 tests/apps/apache/serverstatus/requests.robot create mode 100644 tests/apps/apache/serverstatus/serverstatus.mockoon.json create mode 100644 tests/apps/apache/serverstatus/slotstates.robot diff --git a/src/apps/apache/serverstatus/mode/requests.pm b/src/apps/apache/serverstatus/mode/requests.pm index abe4cb530..e88caa9d6 100644 --- a/src/apps/apache/serverstatus/mode/requests.pm +++ b/src/apps/apache/serverstatus/mode/requests.pm @@ -20,7 +20,7 @@ package apps::apache::serverstatus::mode::requests; -use base qw(centreon::plugins::mode); +use base qw(centreon::plugins::templates::counter); use strict; use warnings; @@ -30,7 +30,7 @@ use centreon::plugins::misc; 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 => { @@ -43,22 +43,23 @@ sub new { 'username:s' => { name => 'username' }, 'password:s' => { name => 'password' }, 'header:s@' => { name => 'header' }, - 'warning:s' => { name => 'warning' }, - 'critical:s' => { name => 'critical' }, - 'warning-bytes:s' => { name => 'warning_bytes' }, - 'critical-bytes:s' => { name => 'critical_bytes' }, - 'warning-access:s' => { name => 'warning_access' }, - 'critical-access:s' => { name => 'critical_access' }, + 'warning:s' => { name => 'warning', redirect => 'warning-apache-request-average-persecond' }, + 'critical:s' => { name => 'critical', redirect => 'critical-apache-request-average-persecond' }, + 'warning-bytes:s' => { name => 'warning_bytes', redirect => 'warning-apache-bytes-persecond' }, + 'critical-bytes:s' => { name => 'critical_bytes', redirect => 'critical-apache-bytes-persecond' }, + 'warning-access:s' => { name => 'warning_access', redirect => 'warning-apache-access-persecond' }, + 'critical-access:s' => { name => 'critical_access', redirect => 'critical-apache-access-persecond' }, 'timeout:s' => { name => 'timeout' }, }); $self->{http} = centreon::plugins::http->new(%options); - $self->{statefile_value} = centreon::plugins::statefile->new(%options); + return $self; } sub check_options { my ($self, %options) = @_; - $self->SUPER::init(%options); + + $self->SUPER::check_options(%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} . "'."); @@ -86,13 +87,97 @@ sub check_options { } $self->{http}->set_options(%{$self->{option_results}}); - $self->{statefile_value}->check_options(%options); } -sub run { +sub custom_bytes_persecond_calc { my ($self, %options) = @_; - my $webcontent = $self->{http}->request(); + unless (defined $options{old_datas}->{global_total_bytes}) { + $self->{error_msg} = "Buffer creation"; + return -1; + } + + my $delta_time = $options{delta_time} || 1; + + my $old_total_bytes = $options{old_datas}->{global_total_bytes} || 0; + $old_total_bytes = 0 if $old_total_bytes > $options{new_datas}->{global_total_bytes}; + + $self->{result_values}->{bPerSec} = ($options{new_datas}->{global_total_bytes} - $old_total_bytes) / $delta_time; + + return 0; +} + +sub custom_access_persecond_calc { + my ($self, %options) = @_; + + unless (defined $options{old_datas}->{global_total_access}) { + $self->{error_msg} = "Buffer creation"; + return -1; + } + my $delta_time = $options{delta_time} || 1; + + my $old_total_access = $options{old_datas}->{global_total_access} || 0; + $old_total_access = 0 if $old_total_access > $options{new_datas}->{global_total_access}; + + $self->{result_values}->{aPerSec} = ($options{new_datas}->{global_total_access} - $old_total_access) / $delta_time; + + return 0; +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'global', type => 0, cb_prefix_output => 'prefix_global_output', askipped_code => { -2 => 1 } } + ]; + + $self->{maps_counters}->{global} = [ + { label => 'bytesPerSec', nlabel => 'apache.bytes.persecond', + set => { + key_values => [ { name => 'bPerSec' }, { name => 'total_bytes' } ], + output_template => 'BytesPerSec: %.2f %s', + output_change_bytes => 1, + closure_custom_calc => $self->can('custom_bytes_persecond_calc'), + perfdatas => [ { template => '%.2f', min => 0, unit => 'B' } ] + } + }, + { label => 'accessPerSec', nlabel => 'apache.access.persecond', + set => { + key_values => [ { name => 'aPerSec' }, { name => 'total_access' } ], + closure_custom_calc => $self->can('custom_access_persecond_calc'), + output_template => 'AccessPerSec: %.2f', + perfdatas => [ { template => '%.2f', min => 0, } ] + } + }, + { label => 'avg_RequestPerSec', nlabel => 'apache.request.average.persecond', + set => { + key_values => [ { name => 'rPerSec' } ], + output_template => 'RequestPerSec: %.2f', + perfdatas => [ { template => '%.2f', min => 0, } ] + } + }, + { label => 'avg_bytesPerRequest', nlabel => 'apache.bytes.average.perrequest', + set => { + key_values => [ { name => 'bPerReq' } ], + output_change_bytes => 1, + output_template => 'BytesPerRequest: %.2f %s', + perfdatas => [ { template => '%.2f', min => 0, unit => 'B', } ] + } + }, + { label => 'avg_bytesPerSec', nlabel => 'apache.bytes.average.persecond', + display_ok => 0, + set => { + key_values => [ { name => 'avg_bPerSec' } ], + perfdatas => [ { min => 0, unit => 'B' } ] + } + }, + ]; +} + +sub manage_selection { + my ($self, %options) = @_; + + my ($webcontent) = $self->{http}->request(); #Total accesses: 7323 - Total Traffic: 243.7 MB - Total Duration: 7175675 #CPU Usage: u1489.98 s1118.39 cu0 cs0 - .568% CPU load @@ -105,7 +190,6 @@ sub run { if ($webcontent =~ /Total\s+Traffic:\s+(\S+)\s+(.|)B\s+/mi) { $total_bytes = centreon::plugins::misc::convert_bytes(value => $1, unit => $2 . 'B'); } - $rPerSec = $1 if ($webcontent =~ /^ReqPerSec:\s+([^\s]+)/mi); if ($webcontent =~ /^(\S+)\s+requests\/sec/mi) { $rPerSec = $1; @@ -127,79 +211,23 @@ sub run { $self->{output}->add_option_msg(short_msg => "Apache 'ExtendedStatus' option is off."); $self->{output}->option_exit(); } + $rPerSec = '0' . $rPerSec if ($rPerSec =~ /^\./); $avg_bPerSec = '0' . $avg_bPerSec if ($avg_bPerSec =~ /^\./); $bPerReq = '0' . $bPerReq if ($bPerReq =~ /^\./); - - $self->{statefile_value}->read(statefile => 'apache_' . $self->{option_results}->{hostname} . '_' . $self->{http}->get_port() . '_' . $self->{mode}); - my $old_timestamp = $self->{statefile_value}->get(name => 'last_timestamp'); - my $old_total_access = $self->{statefile_value}->get(name => 'total_access'); - my $old_total_bytes = $self->{statefile_value}->get(name => 'total_bytes'); - my $new_datas = {}; - $new_datas->{last_timestamp} = time(); - $new_datas->{total_bytes} = $total_bytes; - $new_datas->{total_access} = $total_access; - - $self->{statefile_value}->write(data => $new_datas); - if (!defined($old_timestamp) || !defined($old_total_access)) { - $self->{output}->output_add(severity => 'OK', - short_msg => "Buffer creation..."); - $self->{output}->display(); - $self->{output}->exit(); - } - $old_total_access = 0 if ($old_total_access > $new_datas->{total_access}); - $old_total_bytes = 0 if ($old_total_bytes > $new_datas->{total_bytes}); - my $delta_time = $new_datas->{last_timestamp} - $old_timestamp; - $delta_time = 1 if ($delta_time == 0); # One seconds ;) - - my $bPerSec = ($new_datas->{total_bytes} - $old_total_bytes) / $delta_time; - my $aPerSec = ($new_datas->{total_access} - $old_total_access) / $delta_time; - - my $exit1 = $self->{perfdata}->threshold_check(value => $rPerSec, threshold => [ { label => 'critical', 'exit_litteral' => 'critical' }, { label => 'warning', exit_litteral => 'warning' } ]); - my $exit2 = $self->{perfdata}->threshold_check(value => $bPerSec, threshold => [ { label => 'critical-bytes', 'exit_litteral' => 'critical' }, { label => 'warning-bytes', exit_litteral => 'warning' } ]); - my $exit3 = $self->{perfdata}->threshold_check(value => $aPerSec, threshold => [ { label => 'critical-access', 'exit_litteral' => 'critical' }, { label => 'warning-access', exit_litteral => 'warning' } ]); - - my $exit = $self->{output}->get_most_critical(status => [ $exit1, $exit2, $exit3 ]); - - my ($bPerSec_value, $bPerSec_unit) = $self->{perfdata}->change_bytes(value => $bPerSec); - my ($bPerReq_value, $bPerReq_unit) = $self->{perfdata}->change_bytes(value => $bPerReq); - - $self->{output}->output_add(severity => $exit, - short_msg => sprintf("BytesPerSec: %s AccessPerSec: %.2f RequestPerSec: %.2f BytesPerRequest: %s ", - $bPerSec_value . ' ' . $bPerSec_unit, - $aPerSec, - $rPerSec, - $bPerReq_value . ' ' . $bPerReq_unit - )); - $self->{output}->perfdata_add(label => "avg_RequestPerSec", - value => sprintf("%.2f", $rPerSec), - warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning'), - critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical'), - min => 0 - ); - $self->{output}->perfdata_add(label => "bytesPerSec", unit => 'B', - value => sprintf("%.2f", $bPerSec), - warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-bytes'), - critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-bytes'), - min => 0); - $self->{output}->perfdata_add(label => "avg_bytesPerRequest", unit => 'B', - value => $bPerReq, - min => 0 - ); - $self->{output}->perfdata_add(label => "avg_bytesPerSec", unit => 'B', - value => $avg_bPerSec, - min => 0 - ); - $self->{output}->perfdata_add(label => "accessPerSec", - value => sprintf("%.2f", $aPerSec), - warning => $self->{perfdata}->get_perfdata_for_output(label => 'warning-access'), - critical => $self->{perfdata}->get_perfdata_for_output(label => 'critical-access'), - min => 0); + $self->{global} = { + rPerSec => $rPerSec, + bPerReq => $bPerReq, + avg_bPerSec => $avg_bPerSec, + total_bytes => $total_bytes, + total_access => $total_access, + bPerSec => 0, # Will be calculated in custom_bytes_persecond_calc + aPerSec => 0, # Will be calculated in custom_access_persecond_calc - $self->{output}->display(); - $self->{output}->exit(); + }; + $self->{cache_name} = 'apache_' . $self->{option_results}->{hostname} . '_' . $self->{http}->get_port() . '_' . $self->{mode}; } 1; @@ -256,6 +284,12 @@ Threshold for HTTP timeout Set HTTP headers (multiple option) +=item B<--filter-counters> + +Only display some counters (regexp can be used). +Can be : C, C, C, C, C +Example : --filter-counters='^accessPerSec$' + =item B<--warning> Warning Threshold for Request per seconds diff --git a/src/apps/apache/serverstatus/mode/slotstates.pm b/src/apps/apache/serverstatus/mode/slotstates.pm index 2d5ea1641..09531eec8 100644 --- a/src/apps/apache/serverstatus/mode/slotstates.pm +++ b/src/apps/apache/serverstatus/mode/slotstates.pm @@ -176,9 +176,9 @@ sub set_counters { closure_custom_perfdata => $self->can('custom_value_perfdata'), } }, - { label => 'gracefuly-finished', nlabel => 'apache.slot.gracefulyfinished.count', set => { - key_values => [ { name => 'gracefuly_finished' }, { name => 'total' } ], - closure_custom_calc => $self->can('custom_value_calc'), closure_custom_calc_extra_options => { label_ref => 'gracefuly_finished' }, + { label => 'gracefully-finishing', nlabel => 'apache.slot.gracefullyfinishing.count', set => { + key_values => [ { name => 'gracefully_finishing' }, { name => 'total' } ], + closure_custom_calc => $self->can('custom_value_calc'), closure_custom_calc_extra_options => { label_ref => 'gracefully_finishing' }, closure_custom_output => $self->can('custom_value_output'), closure_custom_threshold_check => $self->can('custom_value_threshold'), closure_custom_perfdata => $self->can('custom_value_perfdata'), @@ -197,7 +197,7 @@ sub set_counters { 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 => { @@ -211,7 +211,12 @@ sub new { 'password:s' => { name => 'password' }, 'header:s@' => { name => 'header' }, 'timeout:s' => { name => 'timeout' }, - 'units:s' => { name => 'units', default => '%' } + 'units:s' => { name => 'units', default => '%' }, + # To keep compatibility with old thresholds + 'warning-gracefuly-finished:s' => { name => 'warning_gracefully_finishing', redirect => 'warning-apache-slot-gracefullyfinishing-count' }, + 'warning-apache-slot-gracefulyfinished-count:s' => { name => 'warning_gracefully_finishing', redirect => 'warning-apache-slot-gracefullyfinishing-count' }, + 'critical-gracefuly-finished:s' => { name => 'critical_gracefuly_finished', redirect => 'critical-apache-slot-gracefullyfinishing-count' }, + 'critical-apache-slot-gracefulyfinished-count:s' => { name => 'critical_apache_smpt_gracefulyfinished_count', redirect => 'critical-apache-slot-gracefullyfinishing-count' }, }); $self->{http} = centreon::plugins::http->new(%options); @@ -248,7 +253,7 @@ sub manage_selection { reading => ($ScoreBoard =~ tr/R//), sending => ($ScoreBoard =~ tr/W//), keepalive => ($ScoreBoard =~ tr/K//), dns_lookup => ($ScoreBoard =~ tr/D//), closing => ($ScoreBoard =~ tr/C//), logging => ($ScoreBoard =~ tr/L//), - gracefuly_finished => ($ScoreBoard =~ tr/G//), idle_cleanup_worker => ($ScoreBoard =~ tr/I//) + gracefully_finishing => ($ScoreBoard =~ tr/G//), idle_cleanup_worker => ($ScoreBoard =~ tr/I//) }; } @@ -258,7 +263,7 @@ __END__ =head1 MODE -Check Apache WebServer Slots informations +Check Apache WebServer Slots information =over 8 @@ -310,21 +315,101 @@ Set HTTP headers (multiple option) Threshold unit (default: '%'. Can be: '%' or 'absolute') -=item B<--warning-*> +=item B<--warning-busy> -Warning threshold. -Can be: 'busy', 'free', 'waiting', 'starting', 'reading', -'sending', 'keepalive', 'dns-lookup', 'closing', -'logging', 'gracefuly-finished', 'idle-cleanup-worker'. +Threshold. -=item B<--critical-*> +=item B<--critical-busy> -Critical threshold. -Can be: 'busy', 'free', 'waiting', 'starting', 'reading', -'sending', 'keepalive', 'dns-lookup', 'closing', -'logging', 'gracefuly-finished', 'idle-cleanup-worker'. +Threshold. -=over 8) +=item B<--warning-closing> + +Threshold. + +=item B<--critical-closing> + +Threshold. + +=item B<--warning-dns-lookup> + +Threshold. + +=item B<--critical-dns-lookup> + +Threshold. + +=item B<--warning-free> + +Threshold. + +=item B<--critical-free> + +Threshold. + +=item B<--warning-gracefully-finishing> + +Threshold. + +=item B<--critical-gracefully-finishing> + +Threshold. + +=item B<--warning-idle-cleanup-worker> + +Threshold. + +=item B<--critical-idle-cleanup-worker> + +Threshold. + +=item B<--warning-keepalive> + +Threshold. + +=item B<--critical-keepalive> + +Threshold. + +=item B<--warning-logging> + +Threshold. + +=item B<--critical-logging> + +Threshold. + +=item B<--warning-reading> + +Threshold. + +=item B<--critical-reading> + +Threshold. + +=item B<--warning-sending> + +Threshold. + +=item B<--critical-sending> + +Threshold. + +=item B<--warning-starting> + +Threshold. + +=item B<--critical-starting> + +Threshold. + +=item B<--warning-waiting> + +Threshold. + +=item B<--critical-waiting> + +Threshold. =back diff --git a/tests/apps/apache/serverstatus/requests.robot b/tests/apps/apache/serverstatus/requests.robot new file mode 100644 index 000000000..60ffa4e38 --- /dev/null +++ b/tests/apps/apache/serverstatus/requests.robot @@ -0,0 +1,44 @@ +# Note: With these tests a counter is incremented in the Mockoon mock data. +# To reset it, make sure to restart the Mockoon server before each robot execution. + +*** Settings *** +Documentation Check Apache WebServer Requests statistics + +Resource ${CURDIR}${/}..${/}..${/}..${/}resources/import.resource + +Suite Setup Start Mockoon ${MOCKOON_JSON} +Suite Teardown Stop Mockoon +Test Timeout 120s + + +*** Variables *** +${MOCKOON_JSON} ${CURDIR}${/}serverstatus.mockoon.json +${HOSTNAME} 127.0.0.1 +${APIPORT} 3000 +${CMD} ${CENTREON_PLUGINS} +... --plugin=apps::apache::serverstatus::plugin +... --mode=requests +... --hostname=${HOSTNAME} +... --port=${APIPORT} + +*** Test Cases *** +Requests ${tc} + [Tags] apps apache serverstatus + + ${command} Catenate + ... ${CMD} + ... ${extra_options} + + Ctn Run Command And Check Result As Strings ${command} ${expected_result} + + Examples: tc extra_options expected_result -- + ... 1 ${EMPTY} OK: bytesPerSec : Buffer creation, accessPerSec : Buffer creation, RequestPerSec: 300.00, BytesPerRequest: 2.11 MB | 'apache.request.average.persecond'=300.00;;;0; 'apache.bytes.average.perrequest'=2211284.85B;;;0; 'apache.bytes.average.persecond'=10B;;;0; + ... 2 --urlpath=/server-status-2 OK: BytesPerSec: 607.00 KB, AccessPerSec: 484.00, RequestPerSec: 300.00, BytesPerRequest: 1.25 KB | 'apache.bytes.persecond'=621568.00B;;;0; 'apache.access.persecond'=484.00;;;0; 'apache.request.average.persecond'=300.00;;;0; 'apache.bytes.average.perrequest'=1284.23B;;;0; 'apache.bytes.average.persecond'=100B;;;0; + ... 3 --warning-apache.bytes.persecond=:400 WARNING: BytesPerSec: 57.61 MB | 'apache.bytes.persecond'=60408832.00B;0:400;;0; 'apache.access.persecond'=474516.00;;;0; 'apache.request.average.persecond'=300.00;;;0; 'apache.bytes.average.perrequest'=2211284.85B;;;0; 'apache.bytes.average.persecond'=10B;;;0; + ... 4 --critical-apache-access-persecond=:10 --urlpath=/server-status-2 CRITICAL: AccessPerSec: 484.00 | 'apache.bytes.persecond'=621568.00B;;;0; 'apache.access.persecond'=484.00;;0:10;0; 'apache.request.average.persecond'=300.00;;;0; 'apache.bytes.average.perrequest'=1284.23B;;;0; 'apache.bytes.average.persecond'=100B;;;0; + ... 5 --critical-apache-request-average-persecond=400: CRITICAL: RequestPerSec: 300.00 | 'apache.bytes.persecond'=60408832.00B;;;0; 'apache.access.persecond'=474516.00;;;0; 'apache.request.average.persecond'=300.00;;400:;0; 'apache.bytes.average.perrequest'=2211284.85B;;;0; 'apache.bytes.average.persecond'=10B;;;0; + ... 6 --warning-apache-bytes-average-perrequest=:10 --urlpath=/server-status-2 WARNING: BytesPerRequest: 1.25 KB | 'apache.bytes.persecond'=621568.00B;;;0; 'apache.access.persecond'=484.00;;;0; 'apache.request.average.persecond'=300.00;;;0; 'apache.bytes.average.perrequest'=1284.23B;0:10;;0; 'apache.bytes.average.persecond'=100B;;;0; + ... 7 --warning-apache-bytes-average-persecond=400: WARNING: avg_bytesPerSec : 10 | 'apache.bytes.persecond'=60408832.00B;;;0; 'apache.access.persecond'=474516.00;;;0; 'apache.request.average.persecond'=300.00;;;0; 'apache.bytes.average.perrequest'=2211284.85B;;;0; 'apache.bytes.average.persecond'=10B;400:;;0; + ... 8 --warning=400: --urlpath=/server-status-2 WARNING: RequestPerSec: 300.00 | 'apache.bytes.persecond'=621568.00B;;;0; 'apache.access.persecond'=484.00;;;0; 'apache.request.average.persecond'=300.00;400:;;0; 'apache.bytes.average.perrequest'=1284.23B;;;0; 'apache.bytes.average.persecond'=100B;;;0; + ... 9 --critical-access=:10 CRITICAL: AccessPerSec: 474516.00 | 'apache.bytes.persecond'=60408832.00B;;;0; 'apache.access.persecond'=474516.00;;0:10;0; 'apache.request.average.persecond'=300.00;;;0; 'apache.bytes.average.perrequest'=2211284.85B;;;0; 'apache.bytes.average.persecond'=10B;;;0; + ... 10 --warning-bytes=:10 --urlpath=/server-status-2 WARNING: BytesPerSec: 607.00 KB | 'apache.bytes.persecond'=621568.00B;0:10;;0; 'apache.access.persecond'=484.00;;;0; 'apache.request.average.persecond'=300.00;;;0; 'apache.bytes.average.perrequest'=1284.23B;;;0; 'apache.bytes.average.persecond'=100B;;;0; diff --git a/tests/apps/apache/serverstatus/serverstatus.mockoon.json b/tests/apps/apache/serverstatus/serverstatus.mockoon.json new file mode 100644 index 000000000..b559bca12 --- /dev/null +++ b/tests/apps/apache/serverstatus/serverstatus.mockoon.json @@ -0,0 +1,139 @@ +{ + "uuid": "a213c65b-587e-41a7-bbd0-4fa7c0ce527b", + "lastMigration": 33, + "name": "Apache", + "endpointPrefix": "", + "latency": 0, + "port": 3006, + "hostname": "", + "folders": [], + "routes": [ + { + "uuid": "3467f012-2e63-4806-b036-56e6e5889f14", + "type": "http", + "documentation": "", + "method": "get", + "endpoint": "server-status/", + "responses": [ + { + "uuid": "68e70383-91e5-43c4-9ddf-d773a1228648", + "body": "172.17.0.1\nServerVersion: Apache/2.4.63 (Ubuntu)\nServerMPM: prefork\nServer Built: 2025-03-07T13:40:17\nCurrentTime: Wednesday, 02-Jul-2025 10:53:07 CEST\nRestartTime: Monday, 23-Jun-2025 08:45:20 CEST\nParentServerConfigGeneration: 6\nParentServerMPMGeneration: 5\nServerUptimeSeconds: 785267\nServerUptime: 9 days 2 hours 7 minutes 47 seconds\nLoad1: 0.69\nLoad5: 0.63\nLoad15: 0.80\nTotal Accesses: 475000\nTotal kBytes: 59600\nTotal Duration: 12300\nCPUUser: 3.18\nCPUSystem: 9.79\nCPUChildrenUser: .1\nCPUChildrenSystem: .14\nCPULoad: .00168223\nUptime: 785267\nReqPerSec: 300\nBytesPerSec: 10\nBytesPerReq: 2211284.85\nDurationPerReq: .258947\nBusyWorkers: 1\nGracefulWorkers: 0\nIdleWorkers: 5\nScoreboard: _____W................................................................................................................................................", + "latency": 0, + "statusCode": 200, + "label": "", + "headers": [ + { + "key": "Content-Type", + "value": "text/html" + } + ], + "bodyType": "INLINE", + "filePath": "", + "databucketID": "", + "sendFileAsBody": false, + "rules": [], + "rulesOperator": "OR", + "disableTemplating": false, + "fallbackTo404": false, + "default": false, + "crudKey": "id", + "callbacks": [] + } + ], + "responseMode": null, + "streamingMode": null, + "streamingInterval": 0 + }, + { + "uuid": "48731c52-6855-420a-be13-3a62af4faf7f", + "type": "http", + "documentation": "", + "method": "get", + "endpoint": "server-status-2/", + "responses": [ + { + "uuid": "07bb3b4e-4595-42ea-ba64-b491d7bb0d79", + "body": "172.17.0.1\nServerVersion: Apache/2.4.63 (Ubuntu)\nServerMPM: prefork\nServer Built: 2025-03-07T13:40:17\nCurrentTime: Wednesday, 02-Jul-2025 10:57:28 CEST\nRestartTime: Monday, 23-Jun-2025 08:45:20 CEST\nParentServerConfigGeneration: 6\nParentServerMPMGeneration: 5\nServerUptimeSeconds: 785528\nServerUptime: 9 days 2 hours 12 minutes 8 seconds\nLoad1: 0.40\nLoad5: 0.57\nLoad15: 0.75\nTotal Accesses: 484\nTotal kBytes: 607\nTotal Duration: 127\nCPUUser: 3.18\nCPUSystem: 9.8\nCPUChildrenUser: .1\nCPUChildrenSystem: .14\nCPULoad: .00168294\nUptime: 785528\nReqPerSec: 300\nBytesPerSec: 100\nBytesPerReq: 1284.23\nDurationPerReq: .262397\nBusyWorkers: 1\nGracefulWorkers: 0\nIdleWorkers: 5\nScoreboard: W_____................................................................................................................................................", + "latency": 0, + "statusCode": 200, + "label": "", + "headers": [ + { + "key": "Content-Type", + "value": "text/html" + } + ], + "bodyType": "INLINE", + "filePath": "", + "databucketID": "", + "sendFileAsBody": false, + "rules": [], + "rulesOperator": "OR", + "disableTemplating": false, + "fallbackTo404": false, + "default": false, + "crudKey": "id", + "callbacks": [] + } + ], + "responseMode": null, + "streamingMode": null, + "streamingInterval": 0 + } + ], + "rootChildren": [ + { + "type": "route", + "uuid": "3467f012-2e63-4806-b036-56e6e5889f14" + }, + { + "type": "route", + "uuid": "48731c52-6855-420a-be13-3a62af4faf7f" + } + ], + "proxyMode": false, + "proxyHost": "", + "proxyRemovePrefix": false, + "tlsOptions": { + "enabled": false, + "type": "CERT", + "pfxPath": "", + "certPath": "", + "keyPath": "", + "caPath": "", + "passphrase": "" + }, + "cors": true, + "headers": [ + { + "key": "Content-Type", + "value": "application/json" + }, + { + "key": "Access-Control-Allow-Origin", + "value": "*" + }, + { + "key": "Access-Control-Allow-Methods", + "value": "GET,POST,PUT,PATCH,DELETE,HEAD,OPTIONS" + }, + { + "key": "Access-Control-Allow-Headers", + "value": "Content-Type, Origin, Accept, Authorization, Content-Length, X-Requested-With" + } + ], + "proxyReqHeaders": [ + { + "key": "", + "value": "" + } + ], + "proxyResHeaders": [ + { + "key": "", + "value": "" + } + ], + "data": [], + "callbacks": [] +} \ No newline at end of file diff --git a/tests/apps/apache/serverstatus/slotstates.robot b/tests/apps/apache/serverstatus/slotstates.robot new file mode 100644 index 000000000..93e053899 --- /dev/null +++ b/tests/apps/apache/serverstatus/slotstates.robot @@ -0,0 +1,39 @@ +# Note: With these tests a counter is incremented in the Mockoon mock data. +# To reset it, make sure to restart the Mockoon server before each robot execution. + +*** Settings *** +Documentation Check Apache WebServer SloteStates statistics + +Resource ${CURDIR}${/}..${/}..${/}..${/}resources/import.resource + +Suite Setup Start Mockoon ${MOCKOON_JSON} +Suite Teardown Stop Mockoon +Test Timeout 120s + + +*** Variables *** +${MOCKOON_JSON} ${CURDIR}${/}serverstatus.mockoon.json +${HOSTNAME} 127.0.0.1 +${APIPORT} 3000 +${CMD} ${CENTREON_PLUGINS} +... --plugin=apps::apache::serverstatus::plugin +... --mode=slotstates +... --hostname=${HOSTNAME} +... --port=${APIPORT} + +*** Test Cases *** +SloteStates ${tc} + [Tags] apps apache serverstatus + + ${command} Catenate + ... ${CMD} + ... ${extra_options} + + Ctn Run Command And Check Result As Strings ${command} ${expected_result} + + Examples: tc extra_options expected_result -- + ... 1 ${EMPTY} OK: Slots busy: 1 (0.67 %), free: 149 (99.33 %), waiting: 5 (3.33 %), starting: 0 (0.00 %), reading: 0 (0.00 %), sending: 1 (0.67 %), keepalive: 0 (0.00 %), dns lookup: 0 (0.00 %), closing: 0 (0.00 %), logging: 0 (0.00 %), gracefully finishing: 0 (0.00 %), idle cleanup worker: 0 (0.00 %) | 'apache.slot.busy.count'=1;;;0;150 'apache.slot.free.count'=149;;;0;150 'apache.slot.waiting.count'=5;;;0;150 'apache.slot.starting.count'=0;;;0;150 'apache.slot.reading.count'=0;;;0;150 'apache.slot.sending.count'=1;;;0;150 'apache.slot.keepalive.count'=0;;;0;150 'apache.slot.dnslookup.count'=0;;;0;150 'apache.slot.closing.count'=0;;;0;150 'apache.slot.logging.count'=0;;;0;150 'apache.slot.gracefullyfinishing.count'=0;;;0;150 'apache.slot.idlecleanupworker.count'=0;;;0;150 + ... 2 --warning-gracefully-finishing=10: WARNING: Slots gracefully finishing: 0 (0.00 %) | 'apache.slot.busy.count'=1;;;0;150 'apache.slot.free.count'=149;;;0;150 'apache.slot.waiting.count'=5;;;0;150 'apache.slot.starting.count'=0;;;0;150 'apache.slot.reading.count'=0;;;0;150 'apache.slot.sending.count'=1;;;0;150 'apache.slot.keepalive.count'=0;;;0;150 'apache.slot.dnslookup.count'=0;;;0;150 'apache.slot.closing.count'=0;;;0;150 'apache.slot.logging.count'=0;;;0;150 'apache.slot.gracefullyfinishing.count'=0;15:;;0;150 'apache.slot.idlecleanupworker.count'=0;;;0;150 + ... 3 --critical-apache-slot-gracefullyfinishing-count=10: CRITICAL: Slots gracefully finishing: 0 (0.00 %) | 'apache.slot.busy.count'=1;;;0;150 'apache.slot.free.count'=149;;;0;150 'apache.slot.waiting.count'=5;;;0;150 'apache.slot.starting.count'=0;;;0;150 'apache.slot.reading.count'=0;;;0;150 'apache.slot.sending.count'=1;;;0;150 'apache.slot.keepalive.count'=0;;;0;150 'apache.slot.dnslookup.count'=0;;;0;150 'apache.slot.closing.count'=0;;;0;150 'apache.slot.logging.count'=0;;;0;150 'apache.slot.gracefullyfinishing.count'=0;;15:;0;150 'apache.slot.idlecleanupworker.count'=0;;;0;150 + ... 4 --warning-gracefuly-finished=10: WARNING: Slots gracefully finishing: 0 (0.00 %) | 'apache.slot.busy.count'=1;;;0;150 'apache.slot.free.count'=149;;;0;150 'apache.slot.waiting.count'=5;;;0;150 'apache.slot.starting.count'=0;;;0;150 'apache.slot.reading.count'=0;;;0;150 'apache.slot.sending.count'=1;;;0;150 'apache.slot.keepalive.count'=0;;;0;150 'apache.slot.dnslookup.count'=0;;;0;150 'apache.slot.closing.count'=0;;;0;150 'apache.slot.logging.count'=0;;;0;150 'apache.slot.gracefullyfinishing.count'=0;15:;;0;150 'apache.slot.idlecleanupworker.count'=0;;;0;150 + ... 5 --critical-apache-slot-gracefulyfinished-count=10: CRITICAL: Slots gracefully finishing: 0 (0.00 %) | 'apache.slot.busy.count'=1;;;0;150 'apache.slot.free.count'=149;;;0;150 'apache.slot.waiting.count'=5;;;0;150 'apache.slot.starting.count'=0;;;0;150 'apache.slot.reading.count'=0;;;0;150 'apache.slot.sending.count'=1;;;0;150 'apache.slot.keepalive.count'=0;;;0;150 'apache.slot.dnslookup.count'=0;;;0;150 'apache.slot.closing.count'=0;;;0;150 'apache.slot.logging.count'=0;;;0;150 'apache.slot.gracefullyfinishing.count'=0;;15:;0;150 'apache.slot.idlecleanupworker.count'=0;;;0;150