See initial patch attached.  (30 seconds between reports is just to
make testing faster.)
Index: server/mpm/worker/worker.c
===================================================================
--- server/mpm/worker/worker.c  (revision 906552)
+++ server/mpm/worker/worker.c  (working copy)
@@ -1550,15 +1550,11 @@
                 /* no threads are "inactive" - starting, stopping, etc. */
                 /* have we reached MaxClients, or just getting close? */
                 if (0 == idle_thread_count) {
-                    static int reported = 0;
-                    if (!reported) {
-                        /* only report this condition once */
-                        ap_log_error(APLOG_MARK, APLOG_ERR, 0,
-                                     ap_server_conf,
-                                     "server reached MaxClients setting, 
consider"
-                                     " raising the MaxClients setting");
-                        reported = 1;
-                    }
+                    static ap_log_interval_t interval = {0};
+                    ap_log_error_interval(APLOG_MARK, APLOG_ERR, 
apr_time_from_sec(30), 0,
+                                          &interval, 0, ap_server_conf,
+                                          "server reached MaxClients setting, 
consider"
+                                          " raising the MaxClients setting");
                 } else {
                     static int reported = 0;
                     if (!reported) {
Index: include/http_log.h
===================================================================
--- include/http_log.h  (revision 906552)
+++ include/http_log.h  (working copy)
@@ -169,6 +169,17 @@
                              const char *fmt, ...)
                            __attribute__((format(printf,6,7)));
 
+typedef struct ap_log_interval_t {
+    apr_time_t last_report;
+    apr_int32_t count;
+} ap_log_interval_t;
+
+AP_DECLARE(void) ap_log_error_interval(const char *file, int line, int level,
+                                       apr_time_t max_interval, apr_int32_t 
max_count,
+                                       ap_log_interval_t *state,
+                                       apr_status_t status, const server_rec 
*s,
+                                       const char *fmt, ...);
+
 /**
  * ap_log_perror() - log messages which are not related to a particular
  * request, connection, or virtual server.  This uses a printf-like
Index: server/log.c
===================================================================
--- server/log.c        (revision 906552)
+++ server/log.c        (working copy)
@@ -732,6 +732,41 @@
     va_end(args);
 }
 
+AP_DECLARE(void) ap_log_error_interval(const char *file, int line, int level,
+                                       apr_time_t max_interval, apr_int32_t 
max_count,
+                                       ap_log_interval_t *state,
+                                       apr_status_t status, const server_rec 
*s,
+                                       const char *fmt, ...)
+{
+    va_list args;
+    char fmt_buf[512];
+    apr_time_t now;
+    int report = 0;
+
+    ++state->count;
+
+    if (max_interval != 0) {
+        now = apr_time_now();
+        if ((now - state->last_report) >= max_interval) {
+            report = 1;
+        }
+    }
+    else if (state->count >= max_count) {
+        report = 1;
+    }
+
+    if (report) {
+        apr_snprintf(fmt_buf, sizeof fmt_buf, "%s (occurred %u times)",
+                     fmt, state->count);
+        va_start(args, fmt);
+        log_error_core(file, line, level, status, s, NULL, NULL, NULL, 
fmt_buf, args);
+        va_end(args);
+
+        state->count = 0;
+        state->last_report = apr_time_now();
+    }
+}
+    
 AP_DECLARE(void) ap_log_perror(const char *file, int line, int level,
                                apr_status_t status, apr_pool_t *p,
                                const char *fmt, ...)

Reply via email to