Here's a patch against PHP_4 that provides a new function called apache_get_scoreboard(). The function returns an array containing current scoreboard.
The idea behind this is to provide a flexible way to dump Apache scoreboard. There are several applications that I can think of : a tool such as Apache::VMonitor (ie mod_status page on steroïds), dumping the scoreboard in XML format for a monitoring application (that would also generate graphs representing Apache activity), or text format for a command-line tool, etc.
There's a drawback though, which somewhat breaks the "rule" (if any) "write once run everywhere" because Apache scoreboard structure depends on the platform and on the version of Apache. I chose however for simplicity to do a strict mapping of the structure.
I've attached a supersimple test script.
This is my first PHP hack so comments are welcome,
Thank you,
Olivier
Index: sapi/apache/php_apache.c =================================================================== RCS file: /repository/php-src/sapi/apache/php_apache.c,v retrieving revision 1.69.2.3 diff -u -r1.69.2.3 php_apache.c --- sapi/apache/php_apache.c 3 Jan 2003 21:32:24 -0000 1.69.2.3 +++ sapi/apache/php_apache.c 8 Oct 2003 08:23:09 -0000 @@ -44,6 +44,7 @@ PHP_FUNCTION(apache_lookup_uri); PHP_FUNCTION(apache_child_terminate); PHP_FUNCTION(apache_setenv); +PHP_FUNCTION(apache_get_scoreboard); PHP_MINFO_FUNCTION(apache); @@ -55,6 +56,7 @@ PHP_FE(apache_child_terminate, NULL) PHP_FE(apache_setenv, NULL) PHP_FE(apache_response_headers, NULL) + PHP_FE(apache_get_scoreboard, NULL) PHP_FALIAS(getallheaders, apache_request_headers, NULL) {NULL, NULL, NULL} }; @@ -82,6 +84,17 @@ #else php_apache_globals_ctor(&php_apache_info TSRMLS_CC); #endif + REGISTER_LONG_CONSTANT("APACHE_SERVER_DEAD", SERVER_DEAD, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("APACHE_SERVER_STARTING", SERVER_STARTING, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("APACHE_SERVER_READY", SERVER_READY, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("APACHE_SERVER_BUSY_READ", SERVER_BUSY_READ, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("APACHE_SERVER_BUSY_WRITE", SERVER_BUSY_WRITE, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("APACHE_SERVER_BUSY_KEEPALIVE", SERVER_BUSY_KEEPALIVE, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("APACHE_SERVER_BUSY_LOG", SERVER_BUSY_LOG, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("APACHE_SERVER_BUSY_DNS", SERVER_BUSY_DNS, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("APACHE_SERVER_GRACEFUL", SERVER_GRACEFUL, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("APACHE_HARD_SERVER_LIMIT", HARD_SERVER_LIMIT, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("APACHE_EXTENDED_STATUS", ap_extended_status, CONST_CS | CONST_PERSISTENT); REGISTER_INI_ENTRIES(); return SUCCESS; } @@ -474,6 +487,142 @@ } /* }}} */ +/* {{{ proto array apache_get_scoreboard(void) + Fetch Apache scoreboard */ +PHP_FUNCTION(apache_get_scoreboard) +{ + zval *rv_global, *rv_parent, *parent_z, *rv_servers, *servers_z; + parent_score scoreboard_parent_rec; + short_score scoreboard_servers_rec; + int i; +#if MODULE_MAGIC_NUMBER >= 19981204 + server_rec *vhost; +#endif +#ifndef NO_TIMES + zval *times_z; +#endif +#if !defined(NO_GETTIMEOFDAY) + zval *start_time_z, *stop_time_z; +#endif + + if (array_init(return_value) == FAILURE) { + RETURN_FALSE; + } + + if (!ap_exists_scoreboard_image()) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "scoreboard is not available"); + RETURN_FALSE; + } + + ap_sync_scoreboard_image(); + + MAKE_STD_ZVAL(rv_global); + if (array_init(rv_global) == FAILURE) { + RETURN_FALSE; + } +#if MODULE_MAGIC_NUMBER >= 19981204 + add_assoc_long(rv_global, "running_generation", (long)ap_scoreboard_image->global.running_generation); +#else + add_assoc_long(rv_global, "exit_generation", (long)ap_scoreboard_image->global.exit_generation); +#endif + MAKE_STD_ZVAL(rv_parent); + if (array_init(rv_parent) == FAILURE) { + RETURN_FALSE; + } + MAKE_STD_ZVAL(rv_servers); + if (array_init(rv_servers) == FAILURE) { + RETURN_FALSE; + } + + for (i = 0; i < HARD_SERVER_LIMIT; ++i) { + + MAKE_STD_ZVAL(parent_z); + if (array_init(parent_z) == FAILURE) { + RETURN_FALSE; + } + scoreboard_parent_rec = ap_scoreboard_image->parent[i]; + add_assoc_long(parent_z, "pid", (long)scoreboard_parent_rec.pid); +#ifdef OPTIMIZE_TIMEOUTS + add_assoc_long(parent_z, "last_rtime", scoreboard_parent_rec.last_rtime); + add_assoc_long(parent_z, "last_vtime", (long)scoreboard_parent_rec.last_vtime); +#endif +#if MODULE_MAGIC_NUMBER >= 19981204 + add_assoc_long(parent_z, "generation", (long)scoreboard_parent_rec.generation); +#endif + add_next_index_zval(rv_parent, parent_z); + + MAKE_STD_ZVAL(servers_z); + if (array_init(servers_z) == FAILURE) { + RETURN_FALSE; + } + scoreboard_servers_rec = ap_scoreboard_image->servers[i]; +#ifdef OPTIMIZE_TIMEOUTS + add_assoc_long(servers_z, "cur_vtime", (long)scoreboard_servers_rec.cur_vtime); + add_assoc_long(servers_z, "timeout_len", (long)scoreboard_servers_rec.timeout_len); +#endif + add_assoc_long(servers_z, "status", (long)scoreboard_servers_rec.status); + add_assoc_long(servers_z, "access_count", (long)scoreboard_servers_rec.access_count); + add_assoc_long(servers_z, "bytes_served", (long)scoreboard_servers_rec.bytes_served); + add_assoc_long(servers_z, "my_access_count", (long)scoreboard_servers_rec.my_access_count); + add_assoc_long(servers_z, "my_bytes_served", (long)scoreboard_servers_rec.my_bytes_served); + add_assoc_long(servers_z, "conn_bytes", (long)scoreboard_servers_rec.conn_bytes); + add_assoc_long(servers_z, "conn_count", (long)scoreboard_servers_rec.conn_count); +#if defined(NO_GETTIMEOFDAY) + add_assoc_long(servers_z, "start_time", scoreboard_servers_rec.start_time); + add_assoc_long(servers_z, "stop_time", scoreboard_servers_rec.stop_time); +#else + MAKE_STD_ZVAL(start_time_z); + if (array_init(start_time_z) == FAILURE) { + RETURN_FALSE; + } + add_assoc_long(start_time_z, "tv_sec", scoreboard_servers_rec.start_time.tv_sec); + add_assoc_long(start_time_z, "tv_usec", scoreboard_servers_rec.start_time.tv_usec); + add_assoc_zval(servers_z, "start_time", start_time_z); + MAKE_STD_ZVAL(stop_time_z); + if (array_init(stop_time_z) == FAILURE) { + RETURN_FALSE; + } + add_assoc_long(stop_time_z, "tv_sec", scoreboard_servers_rec.stop_time.tv_sec); + add_assoc_long(stop_time_z, "tv_usec", scoreboard_servers_rec.stop_time.tv_usec); + add_assoc_zval(servers_z, "stop_time", stop_time_z); +#endif +#ifndef NO_TIMES + MAKE_STD_ZVAL(times_z); + if (array_init(times_z) == FAILURE) { + RETURN_FALSE; + } + add_assoc_long(times_z, "tms_utime", scoreboard_servers_rec.times.tms_utime); + add_assoc_long(times_z, "tms_stime", scoreboard_servers_rec.times.tms_stime); + add_assoc_long(times_z, "tms_cutime", scoreboard_servers_rec.times.tms_cutime); + add_assoc_long(times_z, "tms_cstime", scoreboard_servers_rec.times.tms_cstime); + add_assoc_zval(servers_z, "times", times_z); +#endif +#ifndef OPTIMIZE_TIMEOUTS + add_assoc_long(servers_z, "last_used", scoreboard_servers_rec.last_used); +#endif + add_assoc_string(servers_z, "client", scoreboard_servers_rec.client, 1); + add_assoc_string(servers_z, "request", scoreboard_servers_rec.request, 1); +#if MODULE_MAGIC_NUMBER >= 19981204 + /* + * see Apache's scoreboard.h for an explanation of this + */ + vhost = scoreboard_servers_rec.vhostrec; + if (scoreboard_parent_rec.generation != ap_my_generation) { + vhost = NULL; + } + add_assoc_string(servers_z, "vhost", vhost ? vhost->server_hostname : "", 1); +#else + add_assoc_string(servers_z, "vhost", scoreboard_servers_rec.vhost, 1); +#endif + add_next_index_zval(rv_servers, servers_z); + } + + add_assoc_zval(return_value, "global", rv_global); + add_assoc_zval(return_value, "parent", rv_parent); + add_assoc_zval(return_value, "servers", rv_servers); + +} +/* }}} */ #if 0 This function is most likely a bad idea. Just playing with it for now. Index: sapi/apache/php_apache_http.h =================================================================== RCS file: /repository/php-src/sapi/apache/php_apache_http.h,v retrieving revision 1.4 diff -u -r1.4 php_apache_http.h --- sapi/apache/php_apache_http.h 8 Oct 2002 00:13:56 -0000 1.4 +++ sapi/apache/php_apache_http.h 8 Oct 2003 08:23:09 -0000 @@ -13,7 +13,7 @@ #include "php_regex.h" #include "php_compat.h" -#if HAVE_OPENSSL_EXT +#ifdef HAVE_OPENSSL_EXT /* zlib typedefs free_func which causes problems if the SSL includes happen * after zlib.h is included */ # include <openssl/ssl.h> @@ -36,6 +36,8 @@ #include "http_request.h" #include "http_log.h" #include "util_script.h" +#include "scoreboard.h" +#include "http_conf_globals.h" #include "php_variables.h" #include "php_main.h"
-- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php