mod_log_config.c revision 115a63f51ccb350b6a0a5888ed218558cda546e0
2810N/A/* Licensed to the Apache Software Foundation (ASF) under one or more 2810N/A * contributor license agreements. See the NOTICE file distributed with 2810N/A * this work for additional information regarding copyright ownership. 2810N/A * The ASF licenses this file to You under the Apache License, Version 2.0 2810N/A * (the "License"); you may not use this file except in compliance with 2810N/A * the License. You may obtain a copy of the License at 2810N/A * Unless required by applicable law or agreed to in writing, software 2810N/A * distributed under the License is distributed on an "AS IS" BASIS, 2810N/A * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 2810N/A * See the License for the specific language governing permissions and 2810N/A * limitations under the License. 2810N/A * Modified by djm@va.pubnix.com: 2810N/A * If no TransferLog is given explicitly, decline to log. 2810N/A * This is module implements the TransferLog directive (same as the 2810N/A * common log module), and additional directives, LogFormat and CustomLog. 2810N/A * TransferLog fn Logs transfers to fn in standard log format, unless 2900N/A * a custom format is set with LogFormat 2900N/A * LogFormat format Set a log format from TransferLog files 2810N/A * Log to file fn with format given by the format 2810N/A * There can be any number of TransferLog and CustomLog 2810N/A * commands. Each request will be logged to _ALL_ the 2810N/A * named files, in the appropriate format. 2810N/A * If no TransferLog or CustomLog directive appears in a VirtualHost, 2810N/A * the request will be logged to the log file(s) defined outside 2810N/A * the virtual host section. If a TransferLog or CustomLog directive 2810N/A * appears in the VirtualHost section, the log files defined outside 2810N/A * the VirtualHost will _not_ be used. This makes this module compatable 2810N/A * with the CLF and config log modules, where the use of TransferLog 2810N/A * inside the VirtualHost section overrides its use outside. 2810N/A * LogFormat "... custom format ..." 2810N/A * This will log using CLF to access_log any requests handled by the 2810N/A * main server, while any requests to the virtual host will be logged 2810N/A * with the "... custom format..." to virtual_only _AND_ using 2810N/A * the custom user-agent log to virtual_useragents. 2810N/A * Note that the NCSA referer and user-agent logs are easily added with 2810N/A * RefererIgnore functionality can be obtained with conditional * logging (SetEnvIf and CustomLog ... env=!VAR). * But using this method allows much easier modification of the * log format, e.g. to log hosts along with UA: * The argument to LogFormat and CustomLog is a string, which can include * literal characters copied into the log files, and '%' directives as * %...B: bytes sent, excluding HTTP headers. * %...b: bytes sent, excluding HTTP headers in CLF format, i.e. a '-' * when no bytes where sent (rather than a '0'. * %...{FOOBAR}C: The contents of the HTTP cookie FOOBAR * %...{FOOBAR}e: The contents of the environment variable FOOBAR * %...a: remote IP-address * %...A: local IP-address * %...{Foobar}i: The contents of Foobar: header line(s) in the request * %...k: number of keepalive requests served over this connection * %...l: remote logname (from identd, if supplied) * %...{Foobar}n: The contents of note "Foobar" from another module. * %...{Foobar}o: The contents of Foobar: header line(s) in the reply. * %...p: the canonical port for the server * %...{format}p: the canonical port for the server, or the actual local * %...P: the process ID of the child that serviced the request. * %...{format}P: the process ID or thread ID of the child/thread that * %...r: first line of request * %...s: status. For requests that got internally redirected, this * is status of the *original* request --- %...>s for the last. * %...t: time, in common log format time format * %...{format}t: The time, in the form given by format, which should * be in strftime(3) format. * %...T: the time taken to serve the request, in seconds. * %...D: the time taken to serve the request, in micro seconds. * %...u: remote user (from auth; may be bogus if return status (%s) is 401) * %...U: the URL path requested. * %...v: the configured name of the server (i.e. which virtual host?) * %...V: the server name according to the UseCanonicalName setting * %...m: the request method * %...H: the request protocol * %...q: the query string prepended by "?", or empty if no query string * %...X: Status of the connection. * 'X' = connection aborted before the response completed. * '+' = connection may be kept alive after the response is sent. * '-' = connection will be closed after the response is sent. * (This directive was %...c in late versions of Apache 1.3, but * this conflicted with the historical ssl %...{var}c syntax.) * %...L: Log-Id of the Request (or '-' if none) * %...{c}L: Log-Id of the Connection (or '-' if none) * The '...' can be nothing at all (e.g. "%h %u %r %s %b"), or it can * indicate conditions for inclusion of the item (which will cause it * to be replaced with '-' if the condition is not met). Note that * there is no escaping performed on the strings from %r, %...i and * %...o; some with long memories may remember that I thought this was * a bad idea, once upon a time, and I'm still not comfortable with * it, but it is difficult to see how to "do the right thing" with all * of '%..i', unless we URL-escape everything and break with CLF. * The forms of condition are a list of HTTP status codes, which may * or may not be preceded by '!'. Thus, '%400,501{User-agent}i' logs * User-agent: on 400 errors and 501 errors (Bad Request, Not * Implemented) only; '%!200,304,302{Referer}i' logs Referer: on all * requests which did *not* return some sort of normal status. * The default LogFormat reproduces CLF; see below. * The way this is supposed to work with virtual hosts is as follows: * a virtual host can have its own LogFormat, or its own TransferLog. * If it doesn't have its own LogFormat, it inherits from the main * server. If it doesn't have its own TransferLog, it writes to the * same descriptor (meaning the same process for "| ..."). /* POSIX.1 defines PIPE_BUF as the maximum number of bytes that is * guaranteed to be atomic when writing a pipe. And PIPE_BUF >= 512 * is guaranteed. So we'll just guess 512 in the event the system * doesn't have this. Now, for file writes there is actually no limit, * the entire write is atomic. Whether all systems implement this * correctly is another question entirely ... so we'll just use PIPE_BUF * because it's probably a good guess as to what is implemented correctly * multi_log_state is our per-(virtual)-server configuration. We store * an array of the logs we are going to use, each of type config_log_state. * If a default log format is given by LogFormat, store in default_format * (backward compat. with mod_log_config). We also store for each virtual * server a pointer to the logs specified for the main server, so that if this * vhost has no logs defined, we can use the main server's logs instead. * So, for the main server, config_logs contains a list of the log files * and server_config_logs is empty. For a vhost, server_config_logs * points to the same array as config_logs in the main server, and * config_logs points to the array of logs defined inside this vhost, * config_log_state holds the status of a single log file. fname might * be NULL, which means this module does no logging for this * request. format might be NULL, in which case the default_format * from the multi_log_state should be used, or if that is NULL as * log_writer is NULL before the log file is opened and is * set to a opaque structure (usually a fd) after it is opened. * log_request_state holds request specific log data that is not * part of the request_rec. * Note that many of these could have ap_sprintfs replaced with static buffers. /* NOTE: If the original request contained a password, we * re-write the request line here to contain XXXXXX instead: * (note the truncation before the protocol string for HTTP/0.9 requests) * (note also that r->the_request contains the unmodified request) * This supports Netscape version 0 cookies while being tolerant to * some properties of RFC2109/2965 version 1 cookies: * - case-insensitive match of cookie names * - white space between the tokens * It does not support the following version 1 features: * - quoted strings as cookie values * - commas to separate cookies /* The custom time formatting uses a very large temp buffer * on the stack. To avoid using so much stack space in the * common case where we're not using a custom format, the code * for the custom format in a separate function. (That's why * log_request_time_custom is not inlined right here.) /* This code uses the same technique as ap_explode_recent_localtime(): * optimistic caching with logic to detect and correct race conditions. /* Invalid or old snapshot, so compute the proper time string * and store it in the cache "[%02d/%s/%d:%02d:%02d:%02d %c%.2d%.2d]",
/* These next two routines use the canonical name:port so that log * parsers don't need to duplicate all the vhost parsing crud. /* This respects the setting of UseCanonicalName so that * the dynamic mass virtual hosting trick works better. int tid = 0;
/* APR will format "0" anyway but an arg is needed */ /* APR can format a thread id in hex */ *a ==
'h' ?
"%pt" :
"%pT",
/* APR is missing the feature, so always use decimal */ /***************************************************************** * Parsing the log format string while (*s && *s !=
'%') {
* This might allocate a few chars extra if there's a backslash * escape in the format string. while (*s && *s !=
'%') {
* Allow the loop to deal with this *s in the normal * fashion so that it handles end of string etc. it->
arg =
"";
/* For safety's sake... */ return apr_pstrcat(p,
"Unrecognized LogFormat directive %",
return "Ran off end of LogFormat parsing args to some directive";
/***************************************************************** /* First, see if we need to process this thing at all... */ * See if we've got any conditional envariable-controlled logging decisions "Error evaluating log condition: %s",
err);
"log writer isn't correctly setup");
* Initialize per request state /***************************************************************** * Use the merger to simply add a pointer from the vhost log state * to the log of logs specified for the non-vhost configuration. Make sure * vhosts inherit any globally-defined format names. * Set the default logfile format, or define a nickname for a format string. * If we were given two arguments, the second is a name to be given to the * format. This syntax just defines the nickname - it doesn't actually * make the format the default. return "missing environment variable name";
return "missing condition";
return "error in condition clause";
"a file name, a custom log format string or format name, " "and an optional \"env=\" or \"expr=\" clause (see docs)"),
"the filename of the access log"),
"a log format string (see docs) and an optional format name"),
"Enable Buffered Logging (experimental)"),
return cls;
/* virtual config shared w/main server */ return cls;
/* Leave it NULL to decline. */ /* Failure already logged by open_config_log */ /* Failure already logged by open_config_log */ /* First init the buffered logs array, which is needed when opening the logs. */ /* Next, do "physical" server, which gets default log fd and format * for the virtual servers, if they don't override... /* Then, virtual servers */ /* Now register the last buffer flush with the cleanup engine */ "could not initialize buffered log mutex, " "transfer log may become corrupted");
"invalid transfer log path %s.",
name);
"could not open transfer log file %s.",
fname);
/* reset to default conditions */ /* Init log_hash before we register the optional function. It is * possible for the optional function, ap_register_log_handler, * to be called before any other mod_log_config hooks are called. * As a policy, we should init everything required by an optional function * before calling APR_REGISTER_OPTIONAL_FN. NULL,
/* create per-dir config */ NULL,
/* merge per-dir config */