You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@httpd.apache.org by sf...@apache.org on 2010/09/28 13:53:18 UTC

svn commit: r1002125 - in /httpd/httpd/trunk: CHANGES docs/manual/mod/core.xml include/ap_mmn.h include/http_core.h include/http_log.h modules/metadata/mod_unique_id.c server/core.c server/log.c

Author: sf
Date: Tue Sep 28 11:53:17 2010
New Revision: 1002125

URL: http://svn.apache.org/viewvc?rev=1002125&view=rev
Log:
Add generate_log_id hook to allow to use the ID generated by mod_unique_id as
error log ID for requests.

Modified:
    httpd/httpd/trunk/CHANGES
    httpd/httpd/trunk/docs/manual/mod/core.xml
    httpd/httpd/trunk/include/ap_mmn.h
    httpd/httpd/trunk/include/http_core.h
    httpd/httpd/trunk/include/http_log.h
    httpd/httpd/trunk/modules/metadata/mod_unique_id.c
    httpd/httpd/trunk/server/core.c
    httpd/httpd/trunk/server/log.c

Modified: httpd/httpd/trunk/CHANGES
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/CHANGES?rev=1002125&r1=1002124&r2=1002125&view=diff
==============================================================================
--- httpd/httpd/trunk/CHANGES [utf-8] (original)
+++ httpd/httpd/trunk/CHANGES [utf-8] Tue Sep 28 11:53:17 2010
@@ -2,6 +2,9 @@
 
 Changes with Apache 2.3.9
 
+  *) core/mod_unique_id: Add generate_log_id hook to allow to use
+     the ID generated by mod_unique_id as error log ID for requests.
+
   *) mod_cache: Make sure that we never allow a 304 Not Modified response
      that we asked for to leak to the client should the 304 response be
      uncacheable. PR45341 [Graham Leggett]

Modified: httpd/httpd/trunk/docs/manual/mod/core.xml
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/docs/manual/mod/core.xml?rev=1002125&r1=1002124&r2=1002125&view=diff
==============================================================================
--- httpd/httpd/trunk/docs/manual/mod/core.xml (original)
+++ httpd/httpd/trunk/docs/manual/mod/core.xml Tue Sep 28 11:53:17 2010
@@ -1175,7 +1175,8 @@ in case of an error</description>
     same connection or request, which request happens on which connection.
     A <code>%L</code> format string is also available in
     <module>mod_log_config</module>, to allow to correlate access log entries
-    with error log lines.</p>
+    with error log lines. If <module>mod_unique_id</module> is loaded, its
+    unique id will be used as log ID for requests.</p>
 
     <example><title>Example (somewhat similar to default format)</title>
         ErrorLogFormat "[%{u}t] [%-m:%l] [pid %P] %7F: %E: [client\ %a]

Modified: httpd/httpd/trunk/include/ap_mmn.h
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/include/ap_mmn.h?rev=1002125&r1=1002124&r2=1002125&view=diff
==============================================================================
--- httpd/httpd/trunk/include/ap_mmn.h (original)
+++ httpd/httpd/trunk/include/ap_mmn.h Tue Sep 28 11:53:17 2010
@@ -270,6 +270,7 @@
  *                         cache_server_conf, cache_enable, cache_disable,
  *                         cache_request_rec and cache_provider_list private.
  * 20100923.1 (2.3.9-dev)  Add cache_status hook.
+ * 20100923.2 (2.3.9-dev)  Add generate_log_id hook.
  */
 
 #define MODULE_MAGIC_COOKIE 0x41503234UL /* "AP24" */
@@ -277,7 +278,7 @@
 #ifndef MODULE_MAGIC_NUMBER_MAJOR
 #define MODULE_MAGIC_NUMBER_MAJOR 20100923
 #endif
-#define MODULE_MAGIC_NUMBER_MINOR 1                     /* 0...n */
+#define MODULE_MAGIC_NUMBER_MINOR 2                     /* 0...n */
 
 /**
  * Determine if the server's current MODULE_MAGIC_NUMBER is at least a

Modified: httpd/httpd/trunk/include/http_core.h
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/include/http_core.h?rev=1002125&r1=1002124&r2=1002125&view=diff
==============================================================================
--- httpd/httpd/trunk/include/http_core.h (original)
+++ httpd/httpd/trunk/include/http_core.h Tue Sep 28 11:53:17 2010
@@ -729,7 +729,7 @@ typedef struct {
     unsigned int min_loglevel;              /* only log if level is higher than this */
 } ap_errorlog_format_item;
 
-AP_DECLARE(void) ap_register_builtin_errorlog_handlers(apr_pool_t *p);
+AP_DECLARE(void) ap_register_log_hooks(apr_pool_t *p);
 
 /* ----------------------------------------------------------------------
  *

Modified: httpd/httpd/trunk/include/http_log.h
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/include/http_log.h?rev=1002125&r1=1002124&r2=1002125&view=diff
==============================================================================
--- httpd/httpd/trunk/include/http_log.h (original)
+++ httpd/httpd/trunk/include/http_log.h Tue Sep 28 11:53:17 2010
@@ -618,6 +618,18 @@ AP_DECLARE_HOOK(void, error_log, (const 
                        const request_rec *r, apr_pool_t *pool,
                        const char *errstr))
 
+/**
+ * hook method to generate unique id for connection or request
+ * @ingroup hooks
+ * @param c the conn_rec of the connections
+ * @param r the request_req (may be NULL)
+ * @param id the place where to store the unique id
+ * @return OK or DECLINE
+ */
+AP_DECLARE_HOOK(int, generate_log_id,
+                (const conn_rec *c, const request_rec *r, const char **id))
+
+
 #ifdef __cplusplus
 }
 #endif

Modified: httpd/httpd/trunk/modules/metadata/mod_unique_id.c
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/metadata/mod_unique_id.c?rev=1002125&r1=1002124&r2=1002125&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/metadata/mod_unique_id.c (original)
+++ httpd/httpd/trunk/modules/metadata/mod_unique_id.c Tue Sep 28 11:53:17 2010
@@ -281,7 +281,7 @@ static const char uuencoder[64] = {
     '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '@', '-',
 };
 
-static int gen_unique_id(request_rec *r)
+static const char *gen_unique_id(const request_rec *r)
 {
     char *str;
     /*
@@ -295,17 +295,8 @@ static int gen_unique_id(request_rec *r)
     } paddedbuf;
     unsigned char *x,*y;
     unsigned short counter;
-    const char *e;
     int i,j,k;
 
-    /* copy the unique_id if this is an internal redirect (we're never
-     * actually called for sub requests, so we don't need to test for
-     * them) */
-    if (r->prev && (e = apr_table_get(r->subprocess_env, "REDIRECT_UNIQUE_ID"))) {
-        apr_table_setn(r->subprocess_env, "UNIQUE_ID", e);
-        return DECLINED;
-    }
-
     new_unique_id.in_addr = cur_unique_id.in_addr;
     new_unique_id.pid = cur_unique_id.pid;
     new_unique_id.counter = cur_unique_id.counter;
@@ -344,14 +335,64 @@ static int gen_unique_id(request_rec *r)
     }
     str[k++] = '\0';
 
-    /* set the environment variable */
-    apr_table_setn(r->subprocess_env, "UNIQUE_ID", str);
-
     /* and increment the identifier for the next call */
 
     counter = ntohs(new_unique_id.counter) + 1;
     cur_unique_id.counter = htons(counter);
 
+    return str;
+}
+
+/*
+ * There are two ways the generation of a unique id can be triggered:
+ *
+ * - from the post_read_request hook which calls set_unique_id()
+ * - from error logging via the generate_log_id hook which calls
+ *   generate_log_id(). This may happen before or after set_unique_id()
+ *   has been called, or not at all.
+ */
+
+static int generate_log_id(const conn_rec *c, const request_rec *r,
+                           const char **id)
+{
+    /* we do not care about connection ids */
+    if (r == NULL)
+        return DECLINED;
+
+    /* XXX: do we need special handling for internal redirects? */
+
+    /* if set_unique_id() has been called for this request, use it */
+    *id = apr_table_get(r->subprocess_env, "UNIQUE_ID");
+
+    if (!*id)
+        *id = gen_unique_id(r);
+    return OK;
+}
+
+static int set_unique_id(request_rec *r)
+{
+    const char *id = NULL;
+    /* copy the unique_id if this is an internal redirect (we're never
+     * actually called for sub requests, so we don't need to test for
+     * them) */
+    if (r->prev) {
+       id = apr_table_get(r->subprocess_env, "REDIRECT_UNIQUE_ID");
+    }
+
+    if (!id) {
+        /* if we have a log id, it was set by our generate_log_id() function
+         * and we should reuse the same id
+         */
+        id = r->log_id;
+    }
+
+    if (!id) {
+        id = gen_unique_id(r);
+    }
+
+    /* set the environment variable */
+    apr_table_setn(r->subprocess_env, "UNIQUE_ID", id);
+
     return DECLINED;
 }
 
@@ -359,7 +400,8 @@ static void register_hooks(apr_pool_t *p
 {
     ap_hook_post_config(unique_id_global_init, NULL, NULL, APR_HOOK_MIDDLE);
     ap_hook_child_init(unique_id_child_init, NULL, NULL, APR_HOOK_MIDDLE);
-    ap_hook_post_read_request(gen_unique_id, NULL, NULL, APR_HOOK_MIDDLE);
+    ap_hook_post_read_request(set_unique_id, NULL, NULL, APR_HOOK_MIDDLE);
+    ap_hook_generate_log_id(generate_log_id, NULL, NULL, APR_HOOK_MIDDLE);
 }
 
 AP_DECLARE_MODULE(unique_id) = {

Modified: httpd/httpd/trunk/server/core.c
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/server/core.c?rev=1002125&r1=1002124&r2=1002125&view=diff
==============================================================================
--- httpd/httpd/trunk/server/core.c (original)
+++ httpd/httpd/trunk/server/core.c Tue Sep 28 11:53:17 2010
@@ -3900,8 +3900,6 @@ static int core_pre_config(apr_pool_t *p
 {
     ap_mutex_init(pconf);
 
-    ap_register_builtin_errorlog_handlers(pconf);
-
     return APR_SUCCESS;
 }
 
@@ -4114,6 +4112,7 @@ static int core_pre_connection(conn_rec 
 static void register_hooks(apr_pool_t *p)
 {
     errorlog_hash = apr_hash_make(p);
+    ap_register_log_hooks(p);
 
     /* create_connection and pre_connection should always be hooked
      * APR_HOOK_REALLY_LAST by core to give other modules the opportunity

Modified: httpd/httpd/trunk/server/log.c
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/server/log.c?rev=1002125&r1=1002124&r2=1002125&view=diff
==============================================================================
--- httpd/httpd/trunk/server/log.c (original)
+++ httpd/httpd/trunk/server/log.c Tue Sep 28 11:53:17 2010
@@ -60,6 +60,7 @@ typedef struct {
 
 APR_HOOK_STRUCT(
     APR_HOOK_LINK(error_log)
+    APR_HOOK_LINK(generate_log_id)
 )
 
 int AP_DECLARE_DATA ap_default_loglevel = DEFAULT_LOGLEVEL;
@@ -782,25 +783,8 @@ static int log_env_var(const ap_errorlog
     return 0;
 }
 
-AP_DECLARE(void) ap_register_builtin_errorlog_handlers(apr_pool_t *p)
-{
-    ap_register_errorlog_handler(p, "a", log_remote_address, 0);
-    ap_register_errorlog_handler(p, "A", log_local_address, 0);
-    ap_register_errorlog_handler(p, "e", log_env_var, 0);
-    ap_register_errorlog_handler(p, "E", log_apr_status, 0);
-    ap_register_errorlog_handler(p, "F", log_file_line, 0);
-    ap_register_errorlog_handler(p, "i", log_header, 0);
-    ap_register_errorlog_handler(p, "k", log_keepalives, 0);
-    ap_register_errorlog_handler(p, "l", log_loglevel, 0);
-    ap_register_errorlog_handler(p, "L", log_log_id, 0);
-    ap_register_errorlog_handler(p, "m", log_module_name, 0);
-    ap_register_errorlog_handler(p, "n", log_note, 0);
-    ap_register_errorlog_handler(p, "P", log_pid, 0);
-    ap_register_errorlog_handler(p, "t", log_ctime, 0);
-    ap_register_errorlog_handler(p, "T", log_tid, 0);
-}
-
-static void add_log_id(const conn_rec *c, const request_rec *r)
+static int core_generate_log_id(const conn_rec *c, const request_rec *r,
+                                 const char **idstring)
 {
     apr_uint64_t id, tmp;
     pid_t pid;
@@ -843,15 +827,46 @@ static void add_log_id(const conn_rec *c
     apr_base64_encode(encoded, (char *)&id, sizeof(id));
 
     /* Skip the last char, it is always '=' */
-    encoded[len - 2] = '\0'; 
+    encoded[len - 2] = '\0';
+
+    *idstring = encoded;
+
+    return OK;
+}
 
+static void add_log_id(const conn_rec *c, const request_rec *r)
+{
+    const char **id;
     /* need to cast const away */
     if (r) {
-        ((request_rec *)r)->log_id = encoded;
+        id = &((request_rec *)r)->log_id;
     }
     else {
-        ((conn_rec *)c)->log_id = encoded;
+        id = &((conn_rec *)c)->log_id;
     }
+
+    ap_run_generate_log_id(c, r, id);
+}
+
+AP_DECLARE(void) ap_register_log_hooks(apr_pool_t *p)
+{
+    ap_hook_generate_log_id(core_generate_log_id, NULL, NULL,
+                            APR_HOOK_REALLY_LAST);
+
+    ap_register_errorlog_handler(p, "a", log_remote_address, 0);
+    ap_register_errorlog_handler(p, "A", log_local_address, 0);
+    ap_register_errorlog_handler(p, "e", log_env_var, 0);
+    ap_register_errorlog_handler(p, "E", log_apr_status, 0);
+    ap_register_errorlog_handler(p, "F", log_file_line, 0);
+    ap_register_errorlog_handler(p, "i", log_header, 0);
+    ap_register_errorlog_handler(p, "k", log_keepalives, 0);
+    ap_register_errorlog_handler(p, "l", log_loglevel, 0);
+    ap_register_errorlog_handler(p, "L", log_log_id, 0);
+    ap_register_errorlog_handler(p, "m", log_module_name, 0);
+    ap_register_errorlog_handler(p, "n", log_note, 0);
+    ap_register_errorlog_handler(p, "P", log_pid, 0);
+    ap_register_errorlog_handler(p, "t", log_ctime, 0);
+    ap_register_errorlog_handler(p, "T", log_tid, 0);
 }
 
 /*
@@ -1694,3 +1709,8 @@ AP_IMPLEMENT_HOOK_VOID(error_log,
                         const request_rec *r, apr_pool_t *pool,
                         const char *errstr), (file, line, module_index, level,
                         status, s, r, pool, errstr))
+
+AP_IMPLEMENT_HOOK_RUN_FIRST(int, generate_log_id,
+                            (const conn_rec *c, const request_rec *r,
+                             const char **id),
+                            (c, r, id), DECLINED)