Changes with Apache 2.4.4
+ *) core: Functions to provide server load values: ap_get_sload() and
+ ap_get_loadavg(). [Jim Jagielski, Jan Kaluza <jkaluza redhat.com>,
+ Jeff Trawick]
+
*) mod_ldap: Fix regression in handling "server unavailable" errors on
Windows. PR 54140. [Eric Covener]
PATCHES ACCEPTED TO BACKPORT FROM TRUNK:
[ start all new proposals below, under PATCHES PROPOSED. ]
- * core: Add in ap_get_sload() and ap_get_loadavg().
- http://svn.apache.org/viewvc?view=revision&revision=1389481
- http://svn.apache.org/viewvc?view=revision&revision=1389506
- http://svn.apache.org/viewvc?view=revision&revision=1389564
- http://svn.apache.org/viewvc?view=revision&revision=1390562
- http://svn.apache.org/viewvc?view=revision&revision=1390564
- http://svn.apache.org/viewvc?view=revision&revision=1393338
- http://svn.apache.org/viewvc?view=revision&revision=1397710
- http://svn.apache.org/viewvc?view=revision&revision=1397716
- 2.4.x patch: http://people.apache.org/~jim/patches/server-load-2.4.patch
- +1: jim, jorton, igalic
PATCHES PROPOSED TO BACKPORT FROM TRUNK:
sys/prctl.h \
sys/processor.h \
sys/sem.h \
-sys/sdt.h
+sys/sdt.h \
+sys/loadavg.h
)
AC_HEADER_SYS_WAIT
prctl \
timegm \
getpgid \
-fopen64
+fopen64 \
+getloadavg
)
dnl confirm that a void pointer is large enough to store a long integer
void *context;
};
+/**
+ * @struct ap_sload_t
+ * @brief A structure to hold server load params
+ */
+typedef struct ap_sload_t ap_sload_t;
+struct ap_sload_t {
+ /* percentage of process/threads ready/idle (0->100)*/
+ int idle;
+ /* percentage of process/threads busy (0->100) */
+ int busy;
+ /* total bytes served */
+ apr_off_t bytes_served;
+ /* total access count */
+ unsigned long access_count;
+};
+
+/**
+ * @struct ap_loadavg_t
+ * @brief A structure to hold various server loadavg
+ */
+typedef struct ap_loadavg_t ap_loadavg_t;
+struct ap_loadavg_t {
+ /* current loadavg, ala getloadavg() */
+ float loadavg;
+ /* 5 min loadavg */
+ float loadavg5;
+ /* 15 min loadavg */
+ float loadavg15;
+};
+
/**
* Get the context_document_root for a request. This is a generalization of
* the document root, which is too limited in the presence of mappers like
AP_FN_ATTR_WARN_UNUSED_RESULT
AP_FN_ATTR_ALLOC_SIZE(2);
+/**
+ * Get server load params
+ * @param ld struct to populate: -1 in fields means error
+ */
+AP_DECLARE(void) ap_get_sload(ap_sload_t *ld);
+
+/**
+ * Get server load averages (ala getloadavg)
+ * @param ld struct to populate: -1 in fields means error
+ */
+AP_DECLARE(void) ap_get_loadavg(ap_loadavg_t *ld);
+
#define AP_NORESTART APR_OS_START_USEERR + 1
ap_scoreboard_image->global->restart_time);
if (!short_report) {
+ ap_loadavg_t t;
+
ap_rputs(DOCTYPE_HTML_3_2
"<html><head>\n"
"<title>Apache Status</title>\n"
ap_rputs("<dt>Server uptime: ", r);
show_time(r, up_time);
ap_rputs("</dt>\n", r);
+ ap_get_loadavg(&t);
+ ap_rprintf(r, "<dt>Server load: %.2f %.2f %.2f</dt>\n",
+ t.loadavg, t.loadavg5, t.loadavg15);
}
if (ap_extended_status) {
#ifdef HAVE_GRP_H
#include <grp.h>
#endif
+#ifdef HAVE_SYS_LOADAVG_H
+#include <sys/loadavg.h>
+#endif
+
+#include "ap_mpm.h"
/* A bunch of functions in util.c scan strings looking for certain characters.
* To make that more efficient we encode a lookup table. The test_char_table
ap_abort_on_oom();
return p;
}
+
+AP_DECLARE(void) ap_get_sload(ap_sload_t *ld)
+{
+ int i, j, server_limit, thread_limit;
+ int ready = 0;
+ int busy = 0;
+ int total;
+ ap_generation_t mpm_generation;
+
+ /* preload errored fields, we overwrite */
+ ld->idle = -1;
+ ld->busy = -1;
+ ld->bytes_served = 0;
+ ld->access_count = 0;
+
+ ap_mpm_query(AP_MPMQ_GENERATION, &mpm_generation);
+ ap_mpm_query(AP_MPMQ_HARD_LIMIT_THREADS, &thread_limit);
+ ap_mpm_query(AP_MPMQ_HARD_LIMIT_DAEMONS, &server_limit);
+
+ for (i = 0; i < server_limit; i++) {
+ process_score *ps;
+ ps = ap_get_scoreboard_process(i);
+
+ for (j = 0; j < thread_limit; j++) {
+ int res;
+ worker_score *ws = NULL;
+ ws = &ap_scoreboard_image->servers[i][j];
+ res = ws->status;
+
+ if (!ps->quiescing && ps->pid) {
+ if (res == SERVER_READY && ps->generation == mpm_generation) {
+ ready++;
+ }
+ else if (res != SERVER_DEAD &&
+ res != SERVER_STARTING && res != SERVER_IDLE_KILL &&
+ ps->generation == mpm_generation) {
+ busy++;
+ }
+ }
+
+ if (ap_extended_status && !ps->quiescing && ps->pid) {
+ if (ws->access_count != 0
+ || (res != SERVER_READY && res != SERVER_DEAD)) {
+ ld->access_count += ws->access_count;
+ ld->bytes_served += ws->bytes_served;
+ }
+ }
+ }
+ }
+ total = busy + ready;
+ if (total) {
+ ld->idle = ready * 100 / total;
+ ld->busy = busy * 100 / total;
+ }
+}
+
+AP_DECLARE(void) ap_get_loadavg(ap_loadavg_t *ld)
+{
+ /* preload errored fields, we overwrite */
+ ld->loadavg = -1.0;
+ ld->loadavg5 = -1.0;
+ ld->loadavg15 = -1.0;
+
+#if HAVE_GETLOADAVG
+ {
+ double la[3];
+ int num;
+
+ num = getloadavg(la, 3);
+ if (num > 0) {
+ ld->loadavg = (float)la[0];
+ }
+ if (num > 1) {
+ ld->loadavg5 = (float)la[1];
+ }
+ if (num > 2) {
+ ld->loadavg15 = (float)la[2];
+ }
+ }
+#endif
+}