coar 99/02/17 15:28:20
Modified: htdocs/manual/mod mod_log_config.html src CHANGES src/modules/standard mod_log_config.c Log: Add conditional logging based upon environment variable existence. Also add RefererIgnore functionality from mod_log_referer to mod_log_config; mod_log_referer and mod_log_agent are now deprecated. The list of envariables to check is set up as an array even though the current implementation (TAKE23) only handles one; just in case we ever want to do something strange like, 'env=foo,bar,!bag'. PR: 519, 548, 1351, 1811(?), 3449 Revision Changes Path 1.29 +133 -10 apache-1.3/htdocs/manual/mod/mod_log_config.html Index: mod_log_config.html =================================================================== RCS file: /home/cvs/apache-1.3/htdocs/manual/mod/mod_log_config.html,v retrieving revision 1.28 retrieving revision 1.29 diff -u -r1.28 -r1.29 --- mod_log_config.html 1998/09/17 12:33:07 1.28 +++ mod_log_config.html 1999/02/17 23:28:11 1.29 @@ -14,22 +14,23 @@ > <!--#include virtual="header.html" --> <H1 ALIGN="CENTER">Module mod_log_config</H1> - +<P> This module is contained in the <CODE>mod_log_config.c</CODE> file, and is compiled in by default in Apache 1.2. mod_log_config replaces mod_log_common in Apache 1.2. Prior to version 1.2, mod_log_config was an optional module. It provides for logging of the requests made to the server, using the Common Log Format or a user-specified format. +</P> <H2>Summary</H2> - +<P> Three directives are provided by this module: <CODE>TransferLog</CODE> to create a log file, <CODE>LogFormat</CODE> to set a custom format, and <CODE>CustomLog</CODE> to define a log file and format in one go. The <CODE>TransferLog</CODE> and <CODE>CustomLog</CODE> directives can be used multiple times in each server to cause each request to be logged to multiple files. -<P> +</P> <H3>Compatibility notes</H3> @@ -45,6 +46,22 @@ <CODE>CookieLog</CODE> is deprecated, and a <CODE>CustomLog</CODE> should be defined to log user-tracking information instead. +<LI>As of Apache 1.3.5, this module allows conditional logging +based upon the setting of environment variables. That is, +you can control whether a request should be logged or not +based upon whether an arbitrary environment variable is +defined or not. This is settable on a <EM>per</EM>-logfile +basis. + +<LI>Beginning with Apache 1.3.5, the mod_log_config module has +also subsumed the <CODE>RefererIgnore</CODE> directive from +<A HREF="mod_log_referer.html">mod_log_referer</A>. The use +of <CODE>RefererIgnore</CODE> is deprecated, and should be +replaced by combinations of +<A HREF="mod_setenvif.html"><CODE>SetEnvIf</CODE></A> directives +and environment variable controlled <CODE>CustomLog</CODE> +definitions. + </UL> <H2>Log File Formats</H2> @@ -195,7 +212,9 @@ <UL> <LI><A HREF="#cookielog">CookieLog</A> <LI><A HREF="#customlog">CustomLog</A> +<LI><A HREF="#customlog-conditional">CustomLog (conditional)</A> <LI><A HREF="#logformat">LogFormat</A> +<LI><A HREF="#refererignore">RefererIgnore</A> <LI><A HREF="#transferlog">TransferLog</A> </UL> <HR> @@ -223,8 +242,8 @@ The CookieLog directive sets the filename for logging of cookies. The filename is relative to the <A HREF="core.html#serverroot">ServerRoot</A>. This directive is included -only for compatibility with <A -HREF="mod_cookies.html">mod_cookies</A>, and is deprecated. +only for compatibility with +<A HREF="mod_cookies.html">mod_cookies</A>, and is deprecated. <P> <HR> @@ -242,7 +261,10 @@ HREF="directive-dict.html#Status" REL="Help" ><STRONG>Status:</STRONG></A> Base<BR> -<STRONG>Compatibility: </STRONG> Nickname only available in Apache 1.3 +<A + HREF="directive-dict.html#Compatibility" + REL="Help" +><STRONG>Compatibility:</STRONG></A> Nickname only available in Apache 1.3 or later <BR> <A @@ -274,7 +296,58 @@ ><SAMP>LogFormat</SAMP></A> directive. </P> + <HR> +<H2><A NAME="customlog-conditional">CustomLog (conditional)</A></H2> +<A + HREF="directive-dict.html#Syntax" + REL="Help" +><STRONG>Syntax:</STRONG></A> CustomLog <EM>file-pipe</EM> + <EM>format-or-nickname</EM> + env=[!]<EM>environment-variable</EM><BR> +<A + HREF="directive-dict.html#Context" + REL="Help" +><STRONG>Context:</STRONG></A> server config, virtual host<BR> +<A + HREF="directive-dict.html#Status" + REL="Help" +><STRONG>Status:</STRONG></A> Base<BR> +<A + HREF="directive-dict.html#Compatibility" + REL="Help" +><STRONG>Compatibility:</STRONG></A> Only available in Apache 1.3.5 + or later +<BR> +<A + HREF="directive-dict.html#Module" + REL="Help" +><STRONG>Module:</STRONG></A> mod_log_config +<P> + +The behaviour of this form of the <SAMP>CustomLog</SAMP> directive is almost +identical to the <A HREF="#customlog">standard <CODE>CustomLog</CODE></A> +directive. The difference is that the '<CODE>env=</CODE>' clause controls +whether a particular request will be logged in the specified file or +not. If the specified environment variable is set for the +request (or is not set, in the case of a '<CODE>env=!<EM>name</EM></SAMP>' +clause), then the request will be logged. +</P> +<P> +Environment variables can be set on a <EM>per</EM>-request basis +using the <A HREF="mod_setenvif.html">mod_setenvif</A> and/or +<A HREF="mod_rewrite.html">mod_rewrite</A> modules. For example, +if you don't want to record requests for all GIF images on +your server in a separate logfile but not your main log, you +can use: +</P> +<PRE> + SetEnvIf Request_URI \.gif$ gif-image + CustomLog gif-requests.log common env=gif-image + CustomLog nongif-requests.log common env=!gif-image +</PRE> + +<HR> <H2><A NAME="logformat">LogFormat</A></H2> <!--%plaintext <?INDEX {\tt LogFormat} directive> --> <A @@ -295,7 +368,10 @@ HREF="directive-dict.html#Status" REL="Help" ><STRONG>Status:</STRONG></A> Base<BR> -<STRONG>Compatibility: </STRONG> Nickname only available in Apache 1.3 +<A + HREF="directive-dict.html#Compatibility" + REL="Help" +><STRONG>Compatibility:</STRONG></A> Nickname only available in Apache 1.3 or later <BR> <A @@ -314,9 +390,7 @@ <P> If you include a nickname for the format on the directive line, you can use it in other <SAMP>LogFormat</SAMP> and -<A - HREF="#customlog" -><SAMP>CustomLog</SAMP></A> +<A HREF="#customlog"><SAMP>CustomLog</SAMP></A> directives rather than repeating the entire format string. </P> <P> @@ -327,6 +401,55 @@ </P> <HR> +<H2><A NAME="refererignore">RefererIgnore</A></H2> +<A + HREF="directive-dict.html#Syntax" + REL="Help" +><STRONG>Syntax:</STRONG></A> RefererIgnore <EM>string string ...</EM><BR> +<A + HREF="directive-dict.html#Context" + REL="Help" +><STRONG>Context:</STRONG></A> server config, virtual host<BR> +<A + HREF="directive-dict.html#Status" + REL="Help" +><STRONG>Status:</STRONG></A> Base<BR> +<A + HREF="directive-dict.html#Compatibility" + REL="Help" +><STRONG>Compatibility:</STRONG></A>> Only available in Apache 1.3.5 + or later +<BR> +<A + HREF="directive-dict.html#Module" + REL="Help" +><STRONG>Module:</STRONG></A> mod_log_config + +<P> +The RefererIgnore directive adds to the list of strings to ignore in +Referer headers. If any of the strings in the list is contained in +the Referer header, then no referrer information will be logged for the +request. Example: +</P> +<PRE> + RefererIgnore www.ncsa.uiuc.edu +</PRE> +<P> +will avoid logging references from www.ncsa.uiuc.edu. +</P> +<P> +<STRONG>Note:</STRONG> <EM>All</EM> transaction logfiles +(defined by <CODE>CustomLog</CODE> or <CODE>TransferLog</CODE>) in +the same server scope as the <CODE>RefererIgnore</CODE> (<EM>e.g.</EM>, +in the same <CODE><VirtualHost></CODE> container) +are affected by +this directive. If you want to control this behaviour on a +<EM>per</EM>-logfile basis, you should use the +<A HREF="#customlog-conditional">conditional <SAMP>CustomLog</SAMP></A> +capability. +</P> +<HR> + <H2><A NAME="transferlog">TransferLog</A></H2> <!--%plaintext <?INDEX {\tt TransferLog} directive> --> <A 1.1250 +4 -0 apache-1.3/src/CHANGES Index: CHANGES =================================================================== RCS file: /home/cvs/apache-1.3/src/CHANGES,v retrieving revision 1.1249 retrieving revision 1.1250 diff -u -r1.1249 -r1.1250 --- CHANGES 1999/02/16 14:29:48 1.1249 +++ CHANGES 1999/02/17 23:28:12 1.1250 @@ -1,5 +1,9 @@ Changes with Apache 1.3.5 + *) Added RefererIgnore and conditional logging based upon environment + variables to mod_log_config. mod_log_referer and mod_log_agent + are now deprecated.[Ken Coar] + *) Allow apache acting as a proxy server to relay the real reason of a failure to a client rather than the "internal server error" it does currently. The general exposure mechanism 1.73 +93 -10 apache-1.3/src/modules/standard/mod_log_config.c Index: mod_log_config.c =================================================================== RCS file: /home/cvs/apache-1.3/src/modules/standard/mod_log_config.c,v retrieving revision 1.72 retrieving revision 1.73 diff -u -r1.72 -r1.73 --- mod_log_config.c 1999/02/02 16:21:20 1.72 +++ mod_log_config.c 1999/02/17 23:28:17 1.73 @@ -219,6 +219,8 @@ array_header *config_logs; array_header *server_config_logs; table *formats; + int ignore_referers; + array_header *referer_list; } multi_log_state; /* @@ -235,6 +237,8 @@ char *format_string; array_header *format; int log_fd; + int conditions; + array_header *condition_list; #ifdef BUFFERED_LOGS int outcnt; char outbuf[LOG_BUFSIZE]; @@ -694,6 +698,27 @@ return DECLINED; } + /* + * See if we've got any conditional envariable-controlled logging decisions + * to make. + */ + if (cls->conditions != 0) { + char **candidates = (char **) cls->condition_list->elts; + for (i = 0; i < cls->condition_list->nelts; ++i) { + char *envname = candidates[i]; + if (*envname != '!') { + if (ap_table_get(r->subprocess_env, envname) == NULL) { + return DECLINED; + } + } + else { + if (ap_table_get(r->subprocess_env, &envname[1]) != NULL) { + return DECLINED; + } + } + } + } + format = cls->format ? cls->format : default_format; strs = ap_palloc(r->pool, sizeof(char *) * (format->nelts)); @@ -752,10 +777,27 @@ static int multi_log_transaction(request_rec *r) { multi_log_state *mls = ap_get_module_config(r->server->module_config, - &config_log_module); + &config_log_module); config_log_state *clsarray; int i; + /* + * See if there are any Referer: values we're supposed to ignore. + */ + if (mls->ignore_referers != 0) { + const char *referer = ap_table_get(r->headers_in, "Referer"); + if (referer != NULL) { + char **candidate = (char **) mls->referer_list->elts; + for (i = 0; i < mls->referer_list->nelts; ++i) { + if (strstr(referer, candidate[i]) != NULL) { + return DECLINED; + } + } + } + } + /* + * Continue and log this transaction.. + */ if (mls->config_logs->nelts) { clsarray = (config_log_state *) mls->config_logs->elts; for (i = 0; i < mls->config_logs->nelts; ++i) { @@ -783,14 +825,17 @@ static void *make_config_log_state(pool *p, server_rec *s) { - multi_log_state *mls = (multi_log_state *) ap_palloc(p, sizeof(multi_log_state)); + multi_log_state *mls; + mls = (multi_log_state *) ap_palloc(p, sizeof(multi_log_state)); mls->config_logs = ap_make_array(p, 1, sizeof(config_log_state)); mls->default_format_string = NULL; mls->default_format = NULL; mls->server_config_logs = NULL; mls->formats = ap_make_table(p, 4); ap_table_setn(mls->formats, "CLF", DEFAULT_LOG_FORMAT); + mls->ignore_referers = 0; + mls->referer_list = NULL; return mls; } @@ -812,6 +857,12 @@ add->default_format = base->default_format; } add->formats = ap_overlay_tables(p, base->formats, add->formats); + add->ignore_referers = (add->ignore_referers != 0) + ? add->ignore_referers + : base->ignore_referers; + if (base->ignore_referers != 0) { + ap_array_cat(add->referer_list, base->referer_list); + } return add; } @@ -824,7 +875,7 @@ { const char *err_string = NULL; multi_log_state *mls = ap_get_module_config(cmd->server->module_config, - &config_log_module); + &config_log_module); /* * If we were given two arguments, the second is a name to be given to the @@ -844,18 +895,47 @@ return err_string; } +static const char *add_referer_ignore(cmd_parms *cmd, void *mconfig, + char *word1) +{ + multi_log_state *mls = ap_get_module_config(cmd->server->module_config, + &config_log_module); + char **ignore_uri; + + mls->ignore_referers++; + if (mls->referer_list == NULL) { + mls->referer_list = ap_make_array(cmd->pool, 4, sizeof(char *)); + } + ignore_uri = (char **) ap_push_array(mls->referer_list); + *ignore_uri = ap_pstrdup(cmd->pool, word1); + return NULL; +} + static const char *add_custom_log(cmd_parms *cmd, void *dummy, char *fn, - char *fmt) + char *fmt, char *envclause) { const char *err_string = NULL; multi_log_state *mls = ap_get_module_config(cmd->server->module_config, - &config_log_module); + &config_log_module); config_log_state *cls; cls = (config_log_state *) ap_push_array(mls->config_logs); + cls->conditions = 0; + if (envclause != NULL) { + char **env_condition; + + if (strncasecmp(envclause, "env=", 4) != 0) { + return "error in condition clause"; + } + cls->condition_list = ap_make_array(cmd->pool, 4, sizeof(char *)); + env_condition = (char **) ap_push_array(cls->condition_list); + *env_condition = ap_pstrdup(cmd->pool, &envclause[4]); + cls->conditions++; + } + cls->fname = fn; cls->format_string = fmt; - if (!fmt) { + if (fmt != NULL) { cls->format = NULL; } else { @@ -868,24 +948,27 @@ static const char *set_transfer_log(cmd_parms *cmd, void *dummy, char *fn) { - return add_custom_log(cmd, dummy, fn, NULL); + return add_custom_log(cmd, dummy, fn, NULL, NULL); } static const char *set_cookie_log(cmd_parms *cmd, void *dummy, char *fn) { - return add_custom_log(cmd, dummy, fn, "%{Cookie}n \"%r\" %t"); + return add_custom_log(cmd, dummy, fn, "%{Cookie}n \"%r\" %t", NULL); } static const command_rec config_log_cmds[] = { - {"CustomLog", add_custom_log, NULL, RSRC_CONF, TAKE2, - "a file name and a custom log format string or format name"}, + {"CustomLog", add_custom_log, NULL, RSRC_CONF, TAKE23, + "a file name, a custom log format string or format name, " + "and an optional \"env=\" clause (see docs)"}, {"TransferLog", set_transfer_log, NULL, RSRC_CONF, TAKE1, "the filename of the access log"}, {"LogFormat", log_format, NULL, RSRC_CONF, TAKE12, "a log format string (see docs) and an optional format name"}, {"CookieLog", set_cookie_log, NULL, RSRC_CONF, TAKE1, "the filename of the cookie log"}, + {"RefererIgnore", add_referer_ignore, NULL, RSRC_CONF, ITERATE, + "referer URLs to ignore"}, {NULL} };