monit-general
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Apache, rotatelogs & chroot environment


From: David Fletcher
Subject: Re: Apache, rotatelogs & chroot environment
Date: Sat, 4 Dec 2004 01:00:03 +0000

Hi,

Here is a patch for monit/protocols/http.c, based in the 4.4 release. With this 
patch
Monit will check the status of an Apache server using the mod_status page
available at

http://www.example.com/server-status/?auto

to see if logging is working successfully.

If there are more than 50% of active httpd processes logging (i.e. there is a 
problem with
logging) then the server is re-started. I was originally thinking about a 
chroot specific
problem, but this patch is completely general. Other status messages could also 
be
checked, as well as the ones about logging.

The /etc/monitrc entry looks like this:

   if failed host 127.0.0.1 port 80
       protocol HTTP request /server-status/?auto then restart

I have tested it, and it seems to work well. The original behaviour of http.c 
is retained
for any other page request given in the monitrc file. 

During testing I have found that if httpd processes become locked because they 
can't log,
a request for server-status generates a new child process, and gives a correct 
report on
the condition of the server. Only if there are very rapid incoming connections 
or a very
low maximum number of httpd processes will the server-status page become 
inaccessible. In
this case the server will be re-started because the connection to it will fail.

I hope this is useful to people running Monit and Apache to avoid server 
lock-up if
logging fails. If people don't want to include it in the Monit distribution, I 
can put in
on my website for people to download.

Best wishes,

David.

diff -Naur http.c http_apache.c
--- http.c      Sat Dec  4 00:21:34 2004
+++ http_apache.c       Sat Dec  4 00:32:40 2004
@@ -60,6 +60,7 @@
 static int check_request(Socket_T s);
 static char *get_host_header(Socket_T s, char * host);
 static int check_request_checksum(Socket_T s, char *checksum, int);
+static int check_apache_status(Socket_T s);
 
 
 /**
@@ -113,8 +114,12 @@
   if(request_checksum) {
     return check_request_checksum(s, request_checksum, request_hashtype);
   }
-
-  return check_request(s);
+  
+  if(strcmp(request, "/server-status/?auto")){
+    return check_request(s);
+  }else{
+    return check_apache_status(s);
+  }
   
 }
 
@@ -276,3 +281,75 @@
   return TRUE;
 
 }
+
+
+
+/**
+ * Check an Apache server to detect logging difficulties
+ * Do this using the server-status report, which will only be
+ * available if the server is still responding to some extent.
+ * Could be expanded to monitor other server-status messages.
+ * @param s A socket
+ * @return TRUE if the respons is valid otherwise FALSE
+ */
+static int check_apache_status(Socket_T s) {
+  
+  char line[STRLEN];
+  char search_string[STRLEN];
+  int scored = 0;
+  
+  if(! check_request(s))
+    return FALSE;
+  
+  while(NULL != socket_readln(s, line, STRLEN)) {
+    if(starts_with(line, "Scoreboard:")) {   
+      if(1 != sscanf(line, "%*s%*[: ]%s", search_string)) {
+       chomp(line, STRLEN);
+       log("HTTP error: parsing Apache status response '%s'\n", line);
+       return FALSE;
+      }else{
+        scored = 1;
+      }
+    }
+  }
+  
+  DEBUG("Scoreboard: %s\n", search_string);
+  
+  /*Check that some scoreboard line was found, if not return an error*/
+  if(!scored){
+    log("HTTP error: no scoreboard line returned by Apache server-status\n");
+    return FALSE;
+  }
+  
+  int no_L,active_servers;
+  double logging;
+  char *p;
+  
+  /*Percentage of Apache child processes that may be logging before a restart*/
+  double logging_limit = 50;
+  
+  no_L = 0;
+  active_servers = 0;
+  
+  /*Currently only logging processes, further types could be added*/
+  for(p = search_string ; *p ; p++){
+    active_servers++;
+    switch(*p){
+    case 'L':
+      no_L++;
+      break;
+    case '.':
+      active_servers--;
+      break;
+    }
+  }
+  
+  logging = 100 * no_L / active_servers;
+  
+  if(logging > logging_limit){
+    log("HTTP error: %3.0f percent of Apache processes are logging\n", 
logging);
+    return FALSE;
+  }  
+  return TRUE;
+}
+


-- 
-------------------------------------------------
Email: address@hidden
-------------------------------------------------




reply via email to

[Prev in Thread] Current Thread [Next in Thread]