]> granicus.if.org Git - apache/commitdiff
Would be nice to have some sort of canonical definition
authorJim Jagielski <jim@apache.org>
Mon, 24 Sep 2012 16:56:58 +0000 (16:56 +0000)
committerJim Jagielski <jim@apache.org>
Mon, 24 Sep 2012 16:56:58 +0000 (16:56 +0000)
of server loading for Apache. So create a struct that
holds some useful data. The hope is that for those
platforms that lack getloadavg(), people will write
replacements.

git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1389481 13f79535-47bb-0310-9956-ffa450edef68

configure.in
include/httpd.h
modules/generators/mod_status.c
server/util.c

index 2cce0404b2d03550b57bb6649c4bba6ef396feb5..1b0cee14d323574da28ee877935aef93688f3991 100644 (file)
@@ -483,7 +483,8 @@ bindprocessor \
 prctl \
 timegm \
 getpgid \
-fopen64
+fopen64 \
+getloadavg
 )
 
 dnl confirm that a void pointer is large enough to store a long integer
index 9f3fea9bb64dd592e890bb52aef0d7f441e8d8cd..a012505520fb28086f898761b2679cb4bb5f037b 100644 (file)
@@ -1298,6 +1298,24 @@ struct server_rec {
     void *context;
 };
 
+/**
+ * @struct server_load_rec
+ * @brief  A structure to hold various server load params
+ */
+typedef struct ap_sload_t ap_sload_t;
+struct ap_sload_t {
+    /* 1 min loadavg, ala getloadavg() */
+    float loadavg1;
+    /* 5 min loadavg */
+    float loadavg5;
+    /* 15 min loadavg */
+    float loadavg15;
+    /* percentage of process/threads ready/idle (0->100)*/
+    int idle;
+    /* percentage of process/threads busy (0->100) */
+    int busy;
+};
+
 /**
  * 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
@@ -2187,6 +2205,11 @@ AP_DECLARE(void *) ap_realloc(void *ptr, size_t size)
                    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);
 
 #define AP_NORESTART APR_OS_START_USEERR + 1
 
index 50bcb27297bd7fec96233ce39a7a9502b7c7fc2d..bbd2d5d07a0bae08fcf53154ae51dcc5d83729bd 100644 (file)
@@ -393,6 +393,8 @@ static int status_handler(request_rec *r)
                                ap_scoreboard_image->global->restart_time);
 
     if (!short_report) {
+        ap_sload_t t;
+
         ap_rputs(DOCTYPE_HTML_3_2
                  "<html><head>\n"
                  "<title>Apache Status</title>\n"
@@ -419,6 +421,9 @@ static int status_handler(request_rec *r)
         ap_rputs("<dt>Server uptime: ", r);
         show_time(r, up_time);
         ap_rputs("</dt>\n", r);
+        ap_get_sload(&t);
+        ap_rprintf(r, "<dt>Server load: %.2f %.2f %.2f [%d:%d]</dt>\n",
+                   t.loadavg1, t.loadavg5, t.loadavg15, t.idle, t.busy);
     }
 
     if (ap_extended_status) {
index 24d3a22ed3558b09f4bc8da8518fadb7142c8323..d518eadef1ad8998f89eae45155ad7b354ba6c64 100644 (file)
@@ -63,6 +63,8 @@
 #include <grp.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
  * is generated automatically by gen_test_char.c.
@@ -2788,3 +2790,63 @@ AP_DECLARE(void *) ap_realloc(void *ptr, size_t size)
         ap_abort_on_oom();
     return p;
 }
+
+AP_DECLARE(void) ap_get_sload(ap_sload_t *ld)
+{
+    double la[3];
+    int i, j, num, server_limit, thread_limit;
+    int ready = 0;
+    int busy = 0;
+    int total;
+    ap_generation_t mpm_generation;
+
+    /* preload errored fields, we overwrite */
+    ld->loadavg1 = -1.0;
+    ld->loadavg5 = -1.0;
+    ld->loadavg15 = -1.0;
+    ld->idle = -1;
+    ld->busy = -1;
+
+#if HAVE_GETLOADAVG
+    num = getloadavg(la, 3);
+    if (num > 0) {
+        ld->loadavg1 = (float)la[0];
+    }
+    if (num > 1) {
+        ld->loadavg5 = (float)la[1];
+    }
+    if (num > 2) {
+        ld->loadavg15 = (float)la[2];
+    }
+#endif
+    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 (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++;
+            }
+        }
+    }
+    total = busy + ready;
+    if (total) {
+        ld->idle = ready * 100 / total;
+        ld->busy = busy * 100 / total;
+    }
+
+}