From: Rainer Jung Date: Tue, 7 Aug 2018 13:04:05 +0000 (+0000) Subject: mod_status: Cumulate CPU time of exited child X-Git-Tag: 2.5.0-alpha2-ci-test-only~2402 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=ed521579496724570446484fa524a023518cdcb5;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. git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1837595 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/CHANGES b/CHANGES index 56a3bcc5927..2d61ebe9233 100644 --- a/CHANGES +++ b/CHANGES @@ -1,6 +1,11 @@ -*- coding: utf-8 -*- Changes with Apache 2.5.1 + *) 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: Add cumulated response duration time in milliseconds. [Rainer Jung] diff --git a/include/ap_mmn.h b/include/ap_mmn.h index e42f8ff8916..774053d51cd 100644 --- a/include/ap_mmn.h +++ b/include/ap_mmn.h @@ -591,6 +591,9 @@ * 20180720.3 (2.5.1-dev) Add client64 to worker_share * 20180720.4 (2.5.1-dev) Add new duration field to worker_score struct in * scoreboard.h + * 20180720.5 (2.5.1-dev) Add new ap_update_global_status() method and + * times field in the global_score structure in + * scoreboard.h. * */ @@ -599,7 +602,7 @@ #ifndef MODULE_MAGIC_NUMBER_MAJOR #define MODULE_MAGIC_NUMBER_MAJOR 20180720 #endif -#define MODULE_MAGIC_NUMBER_MINOR 4 /* 0...n */ +#define MODULE_MAGIC_NUMBER_MINOR 5 /* 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 1a4bd7cb3e5..97d8d39c4a0 100644 --- a/include/scoreboard.h +++ b/include/scoreboard.h @@ -127,6 +127,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 */ @@ -193,6 +196,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 90cc7b01319..5e588a21cff 100644 --- a/modules/generators/mod_status.c +++ b/modules/generators/mod_status.c @@ -197,6 +197,7 @@ static int status_handler(request_rec *r) apr_time_t duration_slot; int short_report; int no_table_report; + global_score *global_record; worker_score *ws_record; process_score *ps_record; char *stat_buffer; @@ -204,6 +205,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; @@ -238,6 +240,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) { @@ -246,14 +254,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; @@ -463,6 +474,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 "\nTotal Duration: %" @@ -472,11 +484,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)); @@ -502,15 +514,18 @@ 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 @@ -519,7 +534,8 @@ static int status_handler(request_rec *r) } if (count > 0) { - ap_rputs(" - ", r); + if (up_time > 0) + ap_rputs(" - ", r); format_byte_out(r, (unsigned long)(KBYTE * (float) kbcount / (float) count)); ap_rprintf(r, "/request - %g ms/request", diff --git a/server/mpm_common.c b/server/mpm_common.c index 43194e7ba0a..6a7a3a8b370 100644 --- a/server/mpm_common.c +++ b/server/mpm_common.c @@ -211,6 +211,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; @@ -534,6 +536,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 7cc9e116101..bacc4647896 100644 --- a/server/scoreboard.c +++ b/server/scoreboard.c @@ -506,6 +506,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; @@ -647,6 +653,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)) ||