From: Rainer Jung Date: Wed, 29 Aug 2018 02:43:40 +0000 (+0000) Subject: mod_status: Cumulate CPU time of exited child X-Git-Tag: 2.4.35~46 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=076318d29e2c8b80661b708d85eafdb42a46297a;p=thirdparty%2Fapache%2Fhttpd.git mod_status: Cumulate CPU time of exited child processes in the "cu" and "cs" values. Add CPU time of the parent process to the "c" and "s" values. Backport of r1837595 from trunk. Submitted by: rjung Reviewed by: rjung, jim, ylavic git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.4.x@1839531 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/CHANGES b/CHANGES index 01ad3f49315..a3011d5717b 100644 --- a/CHANGES +++ b/CHANGES @@ -1,6 +1,11 @@ -*- coding: utf-8 -*- Changes with Apache 2.4.35 + *) mod_status: Cumulate CPU time of exited child processes in the + "cu" and "cs" values. Add CPU time of the parent process to the + "c" and "s" values. + [Rainer Jung] + *) mod_status: Complete the data shown for async MPMs in "auto" mode. Added number of processes, number of stopping processes and number of busy and idle workers. [Rainer Jung] diff --git a/STATUS b/STATUS index 15ddbe762ff..352b931b5b7 100644 --- a/STATUS +++ b/STATUS @@ -163,15 +163,6 @@ PATCHES ACCEPTED TO BACKPORT FROM TRUNK: (adjust CHANGES and include/ap_mmn.h) +1: rjung, jim, ylavic - *) mod_status: Cumulate CPU time of exited child - processes in the "cu" and "cs" values. - Add CPU time of the parent process to the - "c" and "s" values. - trunk: http://svn.apache.org/r1837595 - 2.4.x patch: svn merge -c 1837595 ^/httpd/httpd/trunk . - (adjust CHANGES and include/ap_mmn.h) - +1: rjung, jim, ylavic - PATCHES PROPOSED TO BACKPORT FROM TRUNK: [ New proposals should be added at the end of the list ] diff --git a/include/ap_mmn.h b/include/ap_mmn.h index 839228e29bf..c7d3b8f3fe6 100644 --- a/include/ap_mmn.h +++ b/include/ap_mmn.h @@ -515,6 +515,10 @@ * 20120211.77 (2.4.34-dev) Add ap_exists_directive() * 20120211.78 (2.4.34-dev) Add response_field_size to proxy_worker_shared * 20120211.79 (2.4.34-dev) Add AP_GETLINE_NOSPC_EOL flag to http_protocol.h + * 20120211.80 (2.4.35-dev) Add new ap_update_global_status() method and + * times field in the global_score structure in + * scoreboard.h. + * */ #define MODULE_MAGIC_COOKIE 0x41503234UL /* "AP24" */ @@ -522,7 +526,7 @@ #ifndef MODULE_MAGIC_NUMBER_MAJOR #define MODULE_MAGIC_NUMBER_MAJOR 20120211 #endif -#define MODULE_MAGIC_NUMBER_MINOR 79 /* 0...n */ +#define MODULE_MAGIC_NUMBER_MINOR 80 /* 0...n */ /** * Determine if the server's current MODULE_MAGIC_NUMBER is at least a diff --git a/include/scoreboard.h b/include/scoreboard.h index 57cf3df132c..52a582cc959 100644 --- a/include/scoreboard.h +++ b/include/scoreboard.h @@ -125,6 +125,9 @@ typedef struct { * should still be serving requests. */ apr_time_t restart_time; +#ifdef HAVE_TIMES + struct tms times; +#endif } global_score; /* stuff which the parent generally writes and the children rarely read */ @@ -190,6 +193,8 @@ AP_DECLARE(int) ap_update_child_status_descr(ap_sb_handle_t *sbh, int status, co AP_DECLARE(void) ap_time_process_request(ap_sb_handle_t *sbh, int status); +AP_DECLARE(int) ap_update_global_status(void); + AP_DECLARE(worker_score *) ap_get_scoreboard_worker(ap_sb_handle_t *sbh); /** Return a pointer to the worker_score for a given child, thread pair. diff --git a/modules/generators/mod_status.c b/modules/generators/mod_status.c index 4085924ada8..a2ba214e289 100644 --- a/modules/generators/mod_status.c +++ b/modules/generators/mod_status.c @@ -195,6 +195,7 @@ static int status_handler(request_rec *r) long req_time; int short_report; int no_table_report; + global_score *global_record; worker_score *ws_record; process_score *ps_record; char *stat_buffer; @@ -202,6 +203,7 @@ static int status_handler(request_rec *r) int *thread_idle_buffer = NULL; int *thread_busy_buffer = NULL; clock_t tu, ts, tcu, tcs; + clock_t gu, gs, gcu, gcs; ap_generation_t mpm_generation, worker_generation; #ifdef HAVE_TIMES float tick; @@ -235,6 +237,12 @@ static int status_handler(request_rec *r) short_report = 0; no_table_report = 0; + if (!ap_exists_scoreboard_image()) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01237) + "Server status unavailable in inetd mode"); + return HTTP_INTERNAL_SERVER_ERROR; + } + pid_buffer = apr_palloc(r->pool, server_limit * sizeof(pid_t)); stat_buffer = apr_palloc(r->pool, server_limit * thread_limit * sizeof(char)); if (is_async) { @@ -243,14 +251,17 @@ static int status_handler(request_rec *r) } nowtime = apr_time_now(); +#ifdef HAVE_TIMES + global_record = ap_get_scoreboard_global(); + gu = global_record->times.tms_utime; + gs = global_record->times.tms_stime; + gcu = global_record->times.tms_cutime; + gcs = global_record->times.tms_cstime; +#else + gu = gs = gcu = gcs = 0; +#endif tu = ts = tcu = tcs = 0; - if (!ap_exists_scoreboard_image()) { - ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01237) - "Server status unavailable in inetd mode"); - return HTTP_INTERNAL_SERVER_ERROR; - } - r->allowed = (AP_METHOD_BIT << M_GET); if (r->method_number != M_GET) return DECLINED; @@ -459,6 +470,7 @@ static int status_handler(request_rec *r) } if (ap_extended_status) { + clock_t cpu = gu + gs + gcu + gcs + tu + ts + tcu + tcs; if (short_report) { ap_rprintf(r, "Total Accesses: %lu\nTotal kBytes: %" APR_OFF_T_FMT "\n", @@ -467,11 +479,11 @@ static int status_handler(request_rec *r) #ifdef HAVE_TIMES /* Allow for OS/2 not having CPU stats */ ap_rprintf(r, "CPUUser: %g\nCPUSystem: %g\nCPUChildrenUser: %g\nCPUChildrenSystem: %g\n", - tu / tick, ts / tick, tcu / tick, tcs / tick); + (gu + tu) / tick, (gs + ts) / tick, (gcu + tcu) / tick, (gcs + tcs) / tick); - if (ts || tu || tcu || tcs) + if (cpu) ap_rprintf(r, "CPULoad: %g\n", - (tu + ts + tcu + tcs) / tick / up_time * 100.); + cpu / tick / up_time * 100.); #endif ap_rprintf(r, "Uptime: %ld\n", (long) (up_time)); @@ -494,23 +506,28 @@ static int status_handler(request_rec *r) #ifdef HAVE_TIMES /* Allow for OS/2 not having CPU stats */ ap_rprintf(r, "
CPU Usage: u%g s%g cu%g cs%g", - tu / tick, ts / tick, tcu / tick, tcs / tick); + (gu + tu) / tick, (gs + ts) / tick, (gcu + tcu) / tick, (gcs + tcs) / tick); - if (ts || tu || tcu || tcs) + if (cpu) ap_rprintf(r, " - %.3g%% CPU load
\n", - (tu + ts + tcu + tcs) / tick / up_time * 100.); + cpu / tick / up_time * 100.); + else + ap_rputs("\n", r); #endif + ap_rputs("
", r); if (up_time > 0) { - ap_rprintf(r, "
%.3g requests/sec - ", + ap_rprintf(r, "%.3g requests/sec - ", (float) count / (float) up_time); format_byte_out(r, (unsigned long)(KBYTE * (float) kbcount / (float) up_time)); - ap_rputs("/second - ", r); + ap_rputs("/second", r); } if (count > 0) { + if (up_time > 0) + ap_rputs(" - ", r); format_byte_out(r, (unsigned long)(KBYTE * (float) kbcount / (float) count)); ap_rputs("/request", r); diff --git a/server/mpm_common.c b/server/mpm_common.c index 3ea43e79226..04f36d9db86 100644 --- a/server/mpm_common.c +++ b/server/mpm_common.c @@ -187,6 +187,8 @@ AP_DECLARE(void) ap_wait_or_timeout(apr_exit_why_e *status, int *exitcode, } rv = apr_proc_wait_all_procs(ret, exitcode, status, APR_NOWAIT, p); + ap_update_global_status(); + if (APR_STATUS_IS_EINTR(rv)) { ret->pid = -1; return; @@ -510,6 +512,7 @@ void ap_core_child_status(server_rec *s, pid_t pid, ++cur->active; break; case MPM_CHILD_EXITED: + ap_update_global_status(); status_msg = "exited"; if (cur == APR_RING_SENTINEL(geninfo, mpm_gen_info_t, link)) { ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, APLOGNO(00546) diff --git a/server/scoreboard.c b/server/scoreboard.c index 4343eba4b04..720f06bb613 100644 --- a/server/scoreboard.c +++ b/server/scoreboard.c @@ -494,6 +494,12 @@ static int update_child_status_internal(int child_num, if (status == SERVER_DEAD) { ws->my_access_count = 0L; ws->my_bytes_served = 0L; +#ifdef HAVE_TIMES + ws->times.tms_utime = 0; + ws->times.tms_stime = 0; + ws->times.tms_cutime = 0; + ws->times.tms_cstime = 0; +#endif } ws->conn_count = 0; ws->conn_bytes = 0; @@ -624,6 +630,17 @@ AP_DECLARE(void) ap_time_process_request(ap_sb_handle_t *sbh, int status) } } +AP_DECLARE(int) ap_update_global_status() +{ +#ifdef HAVE_TIMES + if (ap_scoreboard_image == NULL) { + return APR_SUCCESS; + } + times(&ap_scoreboard_image->global->times); +#endif + return APR_SUCCESS; +} + AP_DECLARE(worker_score *) ap_get_scoreboard_worker_from_indexes(int x, int y) { if (((x < 0) || (x >= server_limit)) ||