You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by rj...@apache.org on 2015/01/06 04:12:30 UTC

svn commit: r1649728 - in /tomcat/jk/trunk/native: apache-1.3/mod_jk.c apache-2.0/mod_jk.c common/jk_logger.h

Author: rjung
Date: Tue Jan  6 03:12:30 2015
New Revision: 1649728

URL: http://svn.apache.org/r1649728
Log:
Further improve handling of piped loggers
during graceful or normal restart.

Some "Broken Pipe" errors in children mod_jk
logging remain when doing graceful restart
under load. This is because rotatelogs gets
restarted very early during graceful restart
and the pool cleanups in the children do
not run for some time, so remaining requests
log to the closed pipe.

Modified:
    tomcat/jk/trunk/native/apache-1.3/mod_jk.c
    tomcat/jk/trunk/native/apache-2.0/mod_jk.c
    tomcat/jk/trunk/native/common/jk_logger.h

Modified: tomcat/jk/trunk/native/apache-1.3/mod_jk.c
URL: http://svn.apache.org/viewvc/tomcat/jk/trunk/native/apache-1.3/mod_jk.c?rev=1649728&r1=1649727&r2=1649728&view=diff
==============================================================================
--- tomcat/jk/trunk/native/apache-1.3/mod_jk.c (original)
+++ tomcat/jk/trunk/native/apache-1.3/mod_jk.c Tue Jan  6 03:12:30 2015
@@ -137,7 +137,6 @@ typedef struct
      * Log stuff
      */
     char *log_file;
-    int log_fd;
     int log_level;
     jk_logger_t *log;
 
@@ -265,7 +264,6 @@ typedef struct dir_config_struct
 
 static server_rec *main_server = NULL;
 static jk_logger_t *main_log = NULL;
-static int main_log_is_piped = JK_FALSE;
 static table *jk_log_fds = NULL;
 static jk_worker_env_t worker_env;
 static char *jk_shm_file = NULL;
@@ -2778,7 +2776,6 @@ static void *create_jk_config(ap_pool *
     jk_server_conf_t *c =
         (jk_server_conf_t *) ap_pcalloc(p, sizeof(jk_server_conf_t));
 
-    c->log_fd = -1;
     c->mountcopy = JK_FALSE;
     c->was_initialized = JK_FALSE;
 
@@ -3012,7 +3009,6 @@ static void open_jk_log(server_rec *s, p
     const char *fname;
     int jklogfd;
     piped_log *pl;
-    int is_piped = JK_FALSE;
     jk_logger_t *jkl;
     jk_file_logger_t *flp;
     jk_server_conf_t *conf =
@@ -3054,7 +3050,6 @@ static void open_jk_log(server_rec *s, p
                 exit(1);
             }
             jklogfd = ap_piped_log_write_fd(pl);
-            is_piped = JK_TRUE;
         }
         else {
             fname = ap_server_root_relative(p, conf->log_file);
@@ -3077,19 +3072,21 @@ static void open_jk_log(server_rec *s, p
         }
         log_fd_set(p, conf->log_file, jklogfd);
     }
-    conf->log_fd = jklogfd;
     jkl = (jk_logger_t *)ap_palloc(p, sizeof(jk_logger_t));
     flp = (jk_file_logger_t *)ap_palloc(p, sizeof(jk_file_logger_t));
     if (jkl && flp) {
         jkl->log = jk_log_to_file;
         jkl->level = conf->log_level;
         jkl->logger_private = flp;
-        flp->log_fd = conf->log_fd;
+        flp->log_fd = jklogfd;
+        if (*conf->log_file == '|')
+            flp->is_piped = JK_TRUE;
+        else
+            flp->is_piped = JK_FALSE;
         conf->log = jkl;
         jk_set_time_fmt(conf->log, conf->stamp_format_string);
         if (main_log == NULL)
             main_log = conf->log;
-            main_log_is_piped = is_piped;
         return;
     }
 
@@ -3550,10 +3547,27 @@ static int jk_fixups(request_rec * r)
 
 static void child_exit_handler(server_rec * s, ap_pool * p)
 {
-    wc_shutdown(main_log);
+    /* If the main log is piped, we need to make sure
+     * it is no longer used. The external log process
+     * (e.g. rotatelogs) will be gone now and the pipe will
+     * block, once the buffer gets full. Setting
+     * log_fd to -1 makes logging switch to error log.
+     */
+    jk_server_conf_t *conf =
+        (jk_server_conf_t *) ap_get_module_config(s->module_config,
+                                                  &jk_module);
+    jk_logger_t *l = conf->log;
+    if (l && l->logger_private) {
+        jk_file_logger_t *p = l->logger_private;
+        if (p && p->is_piped == JK_TRUE) {
+            p->log_fd = -1;
+            p->is_piped = JK_FALSE;
+        }
+    }
+    wc_shutdown(l);
     /* srevilak - refactor cleanup body to jk_generic_cleanup() */
     jk_generic_cleanup(s);
-    jk_shm_close(main_log);
+    jk_shm_close(l);
 }
 
 static void child_init_handler(server_rec * s, ap_pool * p)
@@ -3578,8 +3592,26 @@ static void child_init_handler(server_re
 /** srevilak -- registered as a cleanup handler in jk_init */
 static void jk_server_cleanup(void *data)
 {
-    jk_generic_cleanup((server_rec *) data);
-    jk_shm_close(main_log);
+    /* If the main log is piped, we need to make sure
+     * it is no longer used. The external log process
+     * (e.g. rotatelogs) will be gone now and the pipe will
+     * block, once the buffer gets full. Setting
+     * log_fd to -1 makes logging switch to error log.
+     */
+    server_rec *s = (server_rec *) data;
+    jk_server_conf_t *conf =
+        (jk_server_conf_t *) ap_get_module_config(s->module_config,
+                                                  &jk_module);
+    jk_logger_t *l = conf->log;
+    if (l && l->logger_private) {
+        jk_file_logger_t *p = l->logger_private;
+        if (p && p->is_piped == JK_TRUE) {
+            p->log_fd = -1;
+            p->is_piped = JK_FALSE;
+        }
+    }
+    jk_generic_cleanup(s);
+    jk_shm_close(l);
 }
 
 
@@ -3589,17 +3621,6 @@ static void jk_server_cleanup(void *data
 static void jk_generic_cleanup(server_rec *s)
 {
 
-    /* If the main log is piped, we need to make sure
-     * it is no longer used. The external log process
-     * (e.g.  rotatelogs) will be gone now and the pipe will
-     * block, once the buffer gets full
-     */
-    if (main_log && main_log_is_piped && main_log->logger_private) {
-        jk_file_logger_t *p = main_log->logger_private;
-        if (p) {
-            p->log_fd = -1;
-        }
-    }
     if (jk_worker_properties) {
         jk_map_free(&jk_worker_properties);
         jk_worker_properties = NULL;

Modified: tomcat/jk/trunk/native/apache-2.0/mod_jk.c
URL: http://svn.apache.org/viewvc/tomcat/jk/trunk/native/apache-2.0/mod_jk.c?rev=1649728&r1=1649727&r2=1649728&view=diff
==============================================================================
--- tomcat/jk/trunk/native/apache-2.0/mod_jk.c (original)
+++ tomcat/jk/trunk/native/apache-2.0/mod_jk.c Tue Jan  6 03:12:30 2015
@@ -169,7 +169,6 @@ typedef struct
     char *log_file;
     int log_level;
     jk_logger_t *log;
-    apr_file_t *jklogfp;
 
     /*
      * Mount stuff
@@ -276,7 +275,6 @@ typedef struct apache_private_data apach
 
 static server_rec *main_server = NULL;
 static jk_logger_t *main_log = NULL;
-static int main_log_is_piped = JK_FALSE;
 static apr_hash_t *jk_log_fps = NULL;
 static jk_worker_env_t worker_env;
 static apr_global_mutex_t *jk_log_lock = NULL;
@@ -2645,16 +2643,19 @@ static apr_status_t jk_cleanup_proc(void
 {
     /* If the main log is piped, we need to make sure
      * it is no longer used. The external log process
-     * (e.g.  rotatelogs) will be gone now and the pipe will
-     * block, once the buffer gets full
+     * (e.g. rotatelogs) will be gone now and the pipe will
+     * block, once the buffer gets full. NULLing
+     * jklogfp makes logging switch to error log.
      */
-    if (main_log && main_log_is_piped && main_log->logger_private) {
-        jk_file_logger_t *p = main_log->logger_private;
-        if (p) {
+    jk_logger_t *l = (jk_logger_t *)data;
+    if (l && l->logger_private) {
+        jk_file_logger_t *p = l->logger_private;
+        if (p && p->is_piped == JK_TRUE) {
             p->jklogfp = NULL;
+            p->is_piped = JK_FALSE;
         }
     }
-    jk_shm_close(main_log);
+    jk_shm_close(l);
     return APR_SUCCESS;
 }
 
@@ -2662,13 +2663,27 @@ static apr_status_t jk_cleanup_proc(void
  */
 static apr_status_t jk_cleanup_child(void *data)
 {
+    /* If the main log is piped, we need to make sure
+     * it is no longer used. The external log process
+     * (e.g. rotatelogs) will be gone now and the pipe will
+     * block, once the buffer gets full. NULLing
+     * jklogfp makes logging switch to error log.
+     */
+    jk_logger_t *l = (jk_logger_t *)data;
+    if (l && l->logger_private) {
+        jk_file_logger_t *p = l->logger_private;
+        if (p && p->is_piped == JK_TRUE) {
+            p->jklogfp = NULL;
+            p->is_piped = JK_FALSE;
+        }
+    }
     /* Force the watchdog thread exit */
     if (jk_watchdog_interval > 0) {
         jk_watchdog_interval = 0;
         while (jk_watchdog_running)
             apr_sleep(apr_time_from_sec(1));
     }
-    wc_shutdown(main_log);
+    wc_shutdown(l);
     return jk_cleanup_proc(data);
 }
 
@@ -3272,7 +3287,6 @@ static int open_jklog(server_rec * s, ap
     apr_status_t rc;
     apr_file_t *jklogfp;
     piped_log *pl;
-    int is_piped = JK_FALSE;
     jk_logger_t *jkl;
     jk_file_logger_t *flp;
     int jklog_flags = (APR_WRITE | APR_APPEND | APR_CREATE);
@@ -3305,7 +3319,6 @@ static int open_jklog(server_rec * s, ap
                 return -1;
             }
             jklogfp = (void *)ap_piped_log_write_fd(pl);
-            is_piped = JK_TRUE;
         }
         else {
             fname = ap_server_root_relative(p, conf->log_file);
@@ -3325,19 +3338,21 @@ static int open_jklog(server_rec * s, ap
         apr_file_inherit_set(jklogfp);
         apr_hash_set(jk_log_fps, conf->log_file, APR_HASH_KEY_STRING, jklogfp);
     }
-    conf->jklogfp = jklogfp;
     jkl = (jk_logger_t *)apr_palloc(p, sizeof(jk_logger_t));
     flp = (jk_file_logger_t *) apr_palloc(p, sizeof(jk_file_logger_t));
     if (jkl && flp) {
         jkl->log = jk_log_to_file;
         jkl->level = conf->log_level;
         jkl->logger_private = flp;
-        flp->jklogfp = conf->jklogfp;
+        flp->jklogfp = jklogfp;
+        if (*conf->log_file == '|')
+            flp->is_piped = JK_TRUE;
+        else
+            flp->is_piped = JK_FALSE;
         conf->log = jkl;
         jk_set_time_fmt(conf->log, conf->stamp_format_string);
         if (main_log == NULL) {
             main_log = conf->log;
-            main_log_is_piped = is_piped;
 
             /* hgomez@20070425 */
             /* Shouldn't we clean both conf->log and main_log ?                   */

Modified: tomcat/jk/trunk/native/common/jk_logger.h
URL: http://svn.apache.org/viewvc/tomcat/jk/trunk/native/common/jk_logger.h?rev=1649728&r1=1649727&r2=1649728&view=diff
==============================================================================
--- tomcat/jk/trunk/native/common/jk_logger.h (original)
+++ tomcat/jk/trunk/native/common/jk_logger.h Tue Jan  6 03:12:30 2015
@@ -57,6 +57,7 @@ struct jk_file_logger_t
     void *jklogfp;
     /* For Apache 1.3 piped logging */
     int log_fd;
+    int is_piped;
 };
 
 /* Level like Java tracing, but available only



---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org