It works by taking the average of response times of threads who processed a request within the last RESPTIME_WINDOW_SECS seconds. I set this to 5 seconds.
I also added in the functionality to print the last response time (Req column), previously this was hardcoded to 0 since we didn't bother to fill out start_time and stop_time.
Thoughts? This is my first patch submission so please, be easy. :) Maybe we weren't filling out start_time/stop_time due to excessive CPU caused by getting the time?
Index: include/scoreboard.h
===================================================================
RCS file: /home/cvspublic/httpd-2.0/include/scoreboard.h,v
retrieving revision 1.48
diff -u -r1.48 scoreboard.h
--- include/scoreboard.h 1 Jan 2004 13:26:16 -0000 1.48
+++ include/scoreboard.h 17 Jan 2004 02:14:52 -0000
@@ -206,6 +206,7 @@
AP_DECLARE(int) ap_update_child_status(ap_sb_handle_t *sbh, int status, request_rec
*r);
AP_DECLARE(int) ap_update_child_status_from_indexes(int child_num, int thread_num,
int status, request_rec *r);
+AP_DECLARE(void) ap_update_timing(ap_sb_handle_t *sbh, int status);
void ap_time_process_request(int child_num, int thread_num, int status);
AP_DECLARE(worker_score *) ap_get_scoreboard_worker(int x, int y);
Index: modules/generators/mod_status.c
===================================================================
RCS file: /home/cvspublic/httpd-2.0/modules/generators/mod_status.c,v
retrieving revision 1.76
diff -u -r1.76 mod_status.c
--- modules/generators/mod_status.c 1 Jan 2004 13:26:19 -0000 1.76
+++ modules/generators/mod_status.c 17 Jan 2004 02:14:52 -0000
@@ -261,6 +261,8 @@
unsigned long lres, my_lres, conn_lres;
apr_off_t bytes, my_bytes, conn_bytes;
apr_off_t bcount, kbcount;
+ long avg_resp_time;
+ int total_active_servers;
long req_time;
#ifdef HAVE_TIMES
float tick;
@@ -272,8 +274,12 @@
process_score *ps_record;
char *stat_buffer;
pid_t *pid_buffer;
+ long *reqtime_buffer;
clock_t tu, ts, tcu, tcs;
+ avg_resp_time = 0;
+ total_active_servers = 0;
+
if (strcmp(r->handler, STATUS_MAGIC_TYPE) &&
strcmp(r->handler, "server-status")) {
return DECLINED;
@@ -297,6 +303,7 @@
pid_buffer = apr_palloc(r->pool, server_limit * sizeof(pid_t));
stat_buffer = apr_palloc(r->pool, server_limit * thread_limit * sizeof(char));
+ reqtime_buffer = apr_palloc(r->pool, server_limit * thread_limit * sizeof(long));
nowtime = apr_time_now();
tu = ts = tcu = tcs = 0;
@@ -416,6 +423,26 @@
bcount = bcount & 0x3ff;
}
}
+
+ if (ws_record->start_time == 0L)
+ req_time = 0L;
+ else
+ req_time = (long)
+ ((ws_record->stop_time -
+ ws_record->start_time) / 1000);
+ if (req_time < 0L)
+ req_time = 0L;
+
+ reqtime_buffer[indx] = req_time;
+
+ /*
+ * If it's within a certain time period, use this for
+ * current average. */
+ if ((nowtime - ws_record->stop_time)/1000000 <= RESPTIME_WINDOW_SECS)
+ {
+ total_active_servers++;
+ avg_resp_time += req_time;
+ }
}
}
#ifdef HAVE_TIMES
@@ -426,6 +453,8 @@
#endif
pid_buffer[i] = ps_record->pid;
}
+ if (total_active_servers)
+ avg_resp_time = avg_resp_time / total_active_servers;
/* up_time in seconds */
up_time = (apr_uint32_t) apr_time_sec(nowtime -
@@ -501,6 +530,8 @@
ap_rprintf(r, "<dt>%.3g requests/sec - ",
(float) count / (float) up_time);
+ ap_rprintf(r, "%ld ms/request response time - ", avg_resp_time);
+
if (up_time > 0) {
format_byte_out(r, (unsigned long)(KBYTE * (float) kbcount
/ (float) up_time));
@@ -601,6 +632,7 @@
for (i = 0; i < server_limit; ++i) {
for (j = 0; j < thread_limit; ++j) {
+ int indx = (i * thread_limit) + j;
ws_record = ap_get_scoreboard_worker(i, j);
if (ws_record->access_count == 0 &&
@@ -611,14 +643,7 @@
ps_record = ap_get_scoreboard_process(i);
- if (ws_record->start_time == 0L)
- req_time = 0L;
- else
- req_time = (long)
- ((ws_record->stop_time -
- ws_record->start_time) / 1000);
- if (req_time < 0L)
- req_time = 0L;
+ req_time = reqtime_buffer[indx];
lres = ws_record->access_count;
my_lres = ws_record->my_access_count;
Index: modules/generators/mod_status.h
===================================================================
RCS file: /home/cvspublic/httpd-2.0/modules/generators/mod_status.h,v
retrieving revision 1.3
diff -u -r1.3 mod_status.h
--- modules/generators/mod_status.h 1 Jan 2004 13:26:19 -0000 1.3
+++ modules/generators/mod_status.h 17 Jan 2004 02:14:52 -0000
@@ -89,4 +89,9 @@
* return OK or DECLINED. */
APR_DECLARE_EXTERNAL_HOOK(ap, STATUS, int, status_hook,
(request_rec *r, int flags))
+/*
+ * Windows in seconds for recording average web server response time
+ */
+#define RESPTIME_WINDOW_SECS 5
+
#endif
Index: modules/http/http_core.c
===================================================================
RCS file: /home/cvspublic/httpd-2.0/modules/http/http_core.c,v
retrieving revision 1.312
diff -u -r1.312 http_core.c
--- modules/http/http_core.c 1 Jan 2004 13:26:19 -0000 1.312
+++ modules/http/http_core.c 17 Jan 2004 02:14:52 -0000
@@ -293,8 +293,12 @@
ap_update_child_status(c->sbh, SERVER_BUSY_WRITE, r);
if (r->status == HTTP_OK)
+ {
+ ap_update_timing(c->sbh,START_PREQUEST);
ap_process_request(r);
-
+ ap_update_timing(c->sbh,STOP_PREQUEST);
+ }
+
if (ap_extended_status)
ap_increment_counts(c->sbh, r);
Index: server/scoreboard.c
===================================================================
RCS file: /home/cvspublic/httpd-2.0/server/scoreboard.c,v
retrieving revision 1.71
diff -u -r1.71 scoreboard.c
--- server/scoreboard.c 1 Jan 2004 13:26:23 -0000 1.71
+++ server/scoreboard.c 17 Jan 2004 02:14:52 -0000
@@ -466,6 +466,12 @@
status, r);
}
+AP_DECLARE(void) ap_update_timing(ap_sb_handle_t *sbh, int status)
+{
+ return ap_time_process_request(sbh->child_num, sbh->thread_num,
+ status);
+}
+
void ap_time_process_request(int child_num, int thread_num, int status)
{
worker_score *ws;
