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]
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]
* 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" */
#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
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);
/* ----------------------------------------------------------------------
*
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
'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;
/*
} 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;
}
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;
}
{
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) = {
{
ap_mutex_init(pconf);
- ap_register_builtin_errorlog_handlers(pconf);
-
return APR_SUCCESS;
}
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
APR_HOOK_STRUCT(
APR_HOOK_LINK(error_log)
+ APR_HOOK_LINK(generate_log_id)
)
int AP_DECLARE_DATA ap_default_loglevel = DEFAULT_LOGLEVEL;
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;
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);
}
/*
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)