mod_status.c revision 842ae4bd224140319ae7feec1872b93dfd491143
97a3ecc40b65d5f8e865bbe0b1c9325d8c016e34nd/* Licensed to the Apache Software Foundation (ASF) under one or more
97a3ecc40b65d5f8e865bbe0b1c9325d8c016e34nd * contributor license agreements. See the NOTICE file distributed with
97a3ecc40b65d5f8e865bbe0b1c9325d8c016e34nd * this work for additional information regarding copyright ownership.
97a3ecc40b65d5f8e865bbe0b1c9325d8c016e34nd * The ASF licenses this file to You under the Apache License, Version 2.0
97a3ecc40b65d5f8e865bbe0b1c9325d8c016e34nd * (the "License"); you may not use this file except in compliance with
97a3ecc40b65d5f8e865bbe0b1c9325d8c016e34nd * the License. You may obtain a copy of the License at
97a3ecc40b65d5f8e865bbe0b1c9325d8c016e34nd * Unless required by applicable law or agreed to in writing, software
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen * distributed under the License is distributed on an "AS IS" BASIS,
2e545ce2450a9953665f701bb05350f0d3f26275nd * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen * See the License for the specific language governing permissions and
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen * limitations under the License.
af33a4994ae2ff15bc67d19ff1a7feb906745bf8rbowen/* Status Module. Display lots of internal data about how Apache is
3f08db06526d6901aa08c110b5bc7dde6bc39905nd * performing and the state of all children processes.
97a3ecc40b65d5f8e865bbe0b1c9325d8c016e34nd * To enable this, add the following lines into any config file:
3f08db06526d6901aa08c110b5bc7dde6bc39905nd * <Location /server-status>
97a3ecc40b65d5f8e865bbe0b1c9325d8c016e34nd * SetHandler server-status
9472e4d3c410be3b3f1addbf3b1db1769f64e765nd * </Location>
97a3ecc40b65d5f8e865bbe0b1c9325d8c016e34nd * You may want to protect this location by password or domain so no one
7f5b59ccc63c0c0e3e678a168f09ee6a2f51f9d0nd * else can look at it. Then you can access the statistics with a URL like:
97a3ecc40b65d5f8e865bbe0b1c9325d8c016e34nd * /server-status - Returns page using tables
4b575a6b6704b516f22d65a3ad35696d7b9ba372rpluem * /server-status?notable - Returns page for browsers without table support
4b575a6b6704b516f22d65a3ad35696d7b9ba372rpluem * /server-status?refresh - Returns page with 1 second refresh
4b575a6b6704b516f22d65a3ad35696d7b9ba372rpluem * /server-status?refresh=6 - Returns page with refresh every 6 seconds
4b575a6b6704b516f22d65a3ad35696d7b9ba372rpluem * /server-status?auto - Returns page with data for automatic parsing
97a3ecc40b65d5f8e865bbe0b1c9325d8c016e34nd * Mark Cox, mark@ukweb.com, November 1995
97a3ecc40b65d5f8e865bbe0b1c9325d8c016e34nd * 12.11.95 Initial version for www.telescope.org
97a3ecc40b65d5f8e865bbe0b1c9325d8c016e34nd * 13.3.96 Updated to remove rprintf's [Mark]
97a3ecc40b65d5f8e865bbe0b1c9325d8c016e34nd * 18.3.96 Added CPU usage, process information, and tidied [Ben Laurie]
97a3ecc40b65d5f8e865bbe0b1c9325d8c016e34nd * 18.3.96 Make extra Scoreboard variables #definable
97a3ecc40b65d5f8e865bbe0b1c9325d8c016e34nd * 25.3.96 Make short report have full precision [Ben Laurie suggested]
97a3ecc40b65d5f8e865bbe0b1c9325d8c016e34nd * 25.3.96 Show uptime better [Mark/Ben Laurie]
97a3ecc40b65d5f8e865bbe0b1c9325d8c016e34nd * 29.3.96 Better HTML and explanation [Mark/Rob Hartill suggested]
97a3ecc40b65d5f8e865bbe0b1c9325d8c016e34nd * 09.4.96 Added message for non-STATUS compiled version
97a3ecc40b65d5f8e865bbe0b1c9325d8c016e34nd * 18.4.96 Added per child and per slot counters [Jim Jagielski]
97a3ecc40b65d5f8e865bbe0b1c9325d8c016e34nd * 01.5.96 Table format, cleanup, even more spiffy data [Chuck Murcko/Jim J.]
30471a4650391f57975f60bbb6e4a90be7b284bfhumbedooh * 18.5.96 Adapted to use new rprintf() routine, incidentally fixing a missing
97a3ecc40b65d5f8e865bbe0b1c9325d8c016e34nd * piece in short reports [Ben Laurie]
97a3ecc40b65d5f8e865bbe0b1c9325d8c016e34nd * 21.5.96 Additional Status codes (DNS and LOGGING only enabled if
97a3ecc40b65d5f8e865bbe0b1c9325d8c016e34nd * extended STATUS is enabled) [George Burgyan/Jim J.]
97a3ecc40b65d5f8e865bbe0b1c9325d8c016e34nd * 10.8.98 Allow for extended status info at runtime (no more STATUS)
97a3ecc40b65d5f8e865bbe0b1c9325d8c016e34nd * [Jim J.]
97a3ecc40b65d5f8e865bbe0b1c9325d8c016e34nd#endif /* NEXT */
97a3ecc40b65d5f8e865bbe0b1c9325d8c016e34nd/* Implement 'ap_run_status_hook'. */
97a3ecc40b65d5f8e865bbe0b1c9325d8c016e34ndAPR_IMPLEMENT_OPTIONAL_HOOK_RUN_ALL(ap, STATUS, int, status_hook,
97a3ecc40b65d5f8e865bbe0b1c9325d8c016e34nd/* ugh... need to know if we're running with a pthread implementation
97a3ecc40b65d5f8e865bbe0b1c9325d8c016e34nd * such as linuxthreads that treats individual threads as distinct
97a3ecc40b65d5f8e865bbe0b1c9325d8c016e34nd * processes; that affects how we add up CPU time in a process
97a3ecc40b65d5f8e865bbe0b1c9325d8c016e34nd * command-related code. This is here to prevent use of ExtendedStatus
97a3ecc40b65d5f8e865bbe0b1c9325d8c016e34nd * without status_module included.
97a3ecc40b65d5f8e865bbe0b1c9325d8c016e34ndstatic const char *set_extended_status(cmd_parms *cmd, void *dummy, int arg)
97a3ecc40b65d5f8e865bbe0b1c9325d8c016e34nd const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
97a3ecc40b65d5f8e865bbe0b1c9325d8c016e34nd AP_INIT_FLAG("ExtendedStatus", set_extended_status, NULL, RSRC_CONF,
97a3ecc40b65d5f8e865bbe0b1c9325d8c016e34nd "\"On\" to enable extended status information, \"Off\" to disable"),
97a3ecc40b65d5f8e865bbe0b1c9325d8c016e34nd/* Format the number of bytes nicely */
97a3ecc40b65d5f8e865bbe0b1c9325d8c016e34ndstatic void format_byte_out(request_rec *r, apr_off_t bytes)
97a3ecc40b65d5f8e865bbe0b1c9325d8c016e34ndstatic void format_kbyte_out(request_rec *r, apr_off_t kbytes)
97a3ecc40b65d5f8e865bbe0b1c9325d8c016e34ndstatic void show_time(request_rec *r, apr_interval_time_t tsecs)
97a3ecc40b65d5f8e865bbe0b1c9325d8c016e34nd ap_rprintf(r, " %d minute%s", mins, mins == 1 ? "" : "s");
97a3ecc40b65d5f8e865bbe0b1c9325d8c016e34nd ap_rprintf(r, " %d second%s", secs, secs == 1 ? "" : "s");
97a3ecc40b65d5f8e865bbe0b1c9325d8c016e34nd/* Main handler for x-httpd-status requests */
97a3ecc40b65d5f8e865bbe0b1c9325d8c016e34nd/* ID values for command table */
97a3ecc40b65d5f8e865bbe0b1c9325d8c016e34nd const char *form_data_str;
97a3ecc40b65d5f8e865bbe0b1c9325d8c016e34nd const char *hdr_out_str;
97a3ecc40b65d5f8e865bbe0b1c9325d8c016e34ndstatic const struct stat_opt status_options[] = /* see #defines above */
97a3ecc40b65d5f8e865bbe0b1c9325d8c016e34nd const char *loc;
97a3ecc40b65d5f8e865bbe0b1c9325d8c016e34nd int j, i, res;
97a3ecc40b65d5f8e865bbe0b1c9325d8c016e34nd unsigned long count;
97a3ecc40b65d5f8e865bbe0b1c9325d8c016e34nd pid_buffer = apr_palloc(r->pool, server_limit * sizeof(pid_t));
97a3ecc40b65d5f8e865bbe0b1c9325d8c016e34nd stat_buffer = apr_palloc(r->pool, server_limit * thread_limit * sizeof(char));
97a3ecc40b65d5f8e865bbe0b1c9325d8c016e34nd "Server status unavailable in inetd mode");
cc7e1025de9ac63bd4db6fe7f71c158b2cf09fe4humbedooh * Simple table-driven form data set parser that lets you alter the header
0d0ba3a410038e179b695446bb149cce6264e0abnd if (*(loc + strlen(status_options[i].form_data_str)) == '='
case STAT_OPT_NOTABLE:
case STAT_OPT_AUTO:
for (i = 0; i < server_limit; ++i) {
#ifdef HAVE_TIMES
for (j = 0; j < thread_limit; ++j) {
ready++;
busy++;
if (ap_extended_status) {
#ifdef HAVE_TIMES
if (times_per_thread) {
#ifdef HAVE_TIMES
if (!short_report) {
DEFAULT_TIME_FORMAT, 0),
(int)ap_my_generation);
if (ap_extended_status) {
if (short_report) {
#ifdef HAVE_TIMES
if (up_time > 0)
if (up_time > 0)
if (count > 0)
#ifdef HAVE_TIMES
if (up_time > 0)
if (up_time > 0) {
/ (float) up_time));
if (count > 0) {
/ (float) count));
if (!short_report)
if (!short_report)
for (i = 0; i < server_limit; ++i) {
for (j = 0; j < thread_limit; ++j) {
&& !short_report)
if (short_report)
if (!ap_extended_status) {
for (i = 0; i < server_limit; ++i) {
for (j = 0; j < thread_limit; ++j) {
if (no_table_report)
#ifdef HAVE_TIMES
for (i = 0; i < server_limit; ++i) {
for (j = 0; j < thread_limit; ++j) {
req_time = 0L;
req_time = (long)
if (req_time < 0L)
req_time = 0L;
if (no_table_report) {
ap_rprintf(r,
i, (int)worker_generation,
ap_rprintf(r,
i, (int) worker_generation,
case SERVER_READY:
case SERVER_STARTING:
case SERVER_BUSY_READ:
case SERVER_BUSY_WRITE:
case SERVER_BUSY_KEEPALIVE:
case SERVER_BUSY_LOG:
case SERVER_BUSY_DNS:
case SERVER_CLOSING:
case SERVER_DEAD:
case SERVER_GRACEFUL:
case SERVER_IDLE_KILL:
#ifdef HAVE_TIMES
#ifdef HAVE_TIMES
(long) req_time);
ap_rprintf(r,
ap_rprintf(r,
i, (int)worker_generation,
ap_rprintf(r,
i, (int)worker_generation,
(int)conn_lres,
case SERVER_READY:
case SERVER_STARTING:
case SERVER_BUSY_READ:
case SERVER_BUSY_WRITE:
case SERVER_BUSY_KEEPALIVE:
case SERVER_BUSY_LOG:
case SERVER_BUSY_DNS:
case SERVER_CLOSING:
case SERVER_DEAD:
case SERVER_GRACEFUL:
case SERVER_IDLE_KILL:
ap_rprintf(r,
#ifdef HAVE_TIMES
#ifdef HAVE_TIMES
(long)req_time);
ap_rprintf(r,
ap_rprintf(r,
if (!no_table_report) {
#ifdef HAVE_TIMES
if (!short_report) {
int flags =
if (!short_report) {
server_rec *s)
return OK;
#ifdef HAVE_TIMES
#ifdef HAVE_TIMES