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
