Add generate_log_id hook to allow to use the ID generated by mod_unique_id as

error log ID for requests.


git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1002125 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Stefan Fritsch
2010-09-28 11:53:17 +00:00
parent b18ae22f53
commit b65066c6ac
8 changed files with 119 additions and 41 deletions

View File

@ -2,6 +2,9 @@
Changes with Apache 2.3.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 *) 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 that we asked for to leak to the client should the 304 response be
uncacheable. PR45341 [Graham Leggett] uncacheable. PR45341 [Graham Leggett]

View File

@ -1175,7 +1175,8 @@ in case of an error</description>
same connection or request, which request happens on which connection. same connection or request, which request happens on which connection.
A <code>%L</code> format string is also available in A <code>%L</code> format string is also available in
<module>mod_log_config</module>, to allow to correlate access log entries <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> <example><title>Example (somewhat similar to default format)</title>
ErrorLogFormat "[%{u}t] [%-m:%l] [pid %P] %7F: %E: [client\ %a] ErrorLogFormat "[%{u}t] [%-m:%l] [pid %P] %7F: %E: [client\ %a]

View File

@ -270,6 +270,7 @@
* cache_server_conf, cache_enable, cache_disable, * cache_server_conf, cache_enable, cache_disable,
* cache_request_rec and cache_provider_list private. * cache_request_rec and cache_provider_list private.
* 20100923.1 (2.3.9-dev) Add cache_status hook. * 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" */ #define MODULE_MAGIC_COOKIE 0x41503234UL /* "AP24" */
@ -277,7 +278,7 @@
#ifndef MODULE_MAGIC_NUMBER_MAJOR #ifndef MODULE_MAGIC_NUMBER_MAJOR
#define MODULE_MAGIC_NUMBER_MAJOR 20100923 #define MODULE_MAGIC_NUMBER_MAJOR 20100923
#endif #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 * Determine if the server's current MODULE_MAGIC_NUMBER is at least a

View File

@ -729,7 +729,7 @@ typedef struct {
unsigned int min_loglevel; /* only log if level is higher than this */ unsigned int min_loglevel; /* only log if level is higher than this */
} ap_errorlog_format_item; } 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);
/* ---------------------------------------------------------------------- /* ----------------------------------------------------------------------
* *

View File

@ -618,6 +618,18 @@ AP_DECLARE_HOOK(void, error_log, (const char *file, int line,
const request_rec *r, apr_pool_t *pool, const request_rec *r, apr_pool_t *pool,
const char *errstr)) 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 #ifdef __cplusplus
} }
#endif #endif

View File

@ -281,7 +281,7 @@ static const char uuencoder[64] = {
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '@', '-', '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; char *str;
/* /*
@ -295,17 +295,8 @@ static int gen_unique_id(request_rec *r)
} paddedbuf; } paddedbuf;
unsigned char *x,*y; unsigned char *x,*y;
unsigned short counter; unsigned short counter;
const char *e;
int i,j,k; 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.in_addr = cur_unique_id.in_addr;
new_unique_id.pid = cur_unique_id.pid; new_unique_id.pid = cur_unique_id.pid;
new_unique_id.counter = cur_unique_id.counter; new_unique_id.counter = cur_unique_id.counter;
@ -344,14 +335,64 @@ static int gen_unique_id(request_rec *r)
} }
str[k++] = '\0'; str[k++] = '\0';
/* set the environment variable */
apr_table_setn(r->subprocess_env, "UNIQUE_ID", str);
/* and increment the identifier for the next call */ /* and increment the identifier for the next call */
counter = ntohs(new_unique_id.counter) + 1; counter = ntohs(new_unique_id.counter) + 1;
cur_unique_id.counter = htons(counter); 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; 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_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_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) = { AP_DECLARE_MODULE(unique_id) = {

View File

@ -3900,8 +3900,6 @@ static int core_pre_config(apr_pool_t *pconf, apr_pool_t *plog, apr_pool_t *ptem
{ {
ap_mutex_init(pconf); ap_mutex_init(pconf);
ap_register_builtin_errorlog_handlers(pconf);
return APR_SUCCESS; return APR_SUCCESS;
} }
@ -4114,6 +4112,7 @@ static int core_pre_connection(conn_rec *c, void *csd)
static void register_hooks(apr_pool_t *p) static void register_hooks(apr_pool_t *p)
{ {
errorlog_hash = apr_hash_make(p); errorlog_hash = apr_hash_make(p);
ap_register_log_hooks(p);
/* create_connection and pre_connection should always be hooked /* create_connection and pre_connection should always be hooked
* APR_HOOK_REALLY_LAST by core to give other modules the opportunity * APR_HOOK_REALLY_LAST by core to give other modules the opportunity

View File

@ -60,6 +60,7 @@ typedef struct {
APR_HOOK_STRUCT( APR_HOOK_STRUCT(
APR_HOOK_LINK(error_log) APR_HOOK_LINK(error_log)
APR_HOOK_LINK(generate_log_id)
) )
int AP_DECLARE_DATA ap_default_loglevel = DEFAULT_LOGLEVEL; int AP_DECLARE_DATA ap_default_loglevel = DEFAULT_LOGLEVEL;
@ -782,25 +783,8 @@ static int log_env_var(const ap_errorlog_info *info, const char *arg,
return 0; return 0;
} }
AP_DECLARE(void) ap_register_builtin_errorlog_handlers(apr_pool_t *p) static int core_generate_log_id(const conn_rec *c, const request_rec *r,
{ const char **idstring)
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)
{ {
apr_uint64_t id, tmp; apr_uint64_t id, tmp;
pid_t pid; pid_t pid;
@ -843,15 +827,46 @@ static void add_log_id(const conn_rec *c, const request_rec *r)
apr_base64_encode(encoded, (char *)&id, sizeof(id)); apr_base64_encode(encoded, (char *)&id, sizeof(id));
/* Skip the last char, it is always '=' */ /* 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 */ /* need to cast const away */
if (r) { if (r) {
((request_rec *)r)->log_id = encoded; id = &((request_rec *)r)->log_id;
} }
else { 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 request_rec *r, apr_pool_t *pool,
const char *errstr), (file, line, module_index, level, const char *errstr), (file, line, module_index, level,
status, s, r, pool, errstr)) 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)