Hello,

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

Reply via email to