mod_log_config.c revision 25e17566bc9005778707317c8919c610513a4418
777374243e15c53e7b0a7345e190c1018920be18Jakub Hrozek/* ====================================================================
777374243e15c53e7b0a7345e190c1018920be18Jakub Hrozek * The Apache Software License, Version 1.1
777374243e15c53e7b0a7345e190c1018920be18Jakub Hrozek * Copyright (c) 2000-2001 The Apache Software Foundation. All rights
777374243e15c53e7b0a7345e190c1018920be18Jakub Hrozek * Redistribution and use in source and binary forms, with or without
777374243e15c53e7b0a7345e190c1018920be18Jakub Hrozek * modification, are permitted provided that the following conditions
777374243e15c53e7b0a7345e190c1018920be18Jakub Hrozek * 1. Redistributions of source code must retain the above copyright
777374243e15c53e7b0a7345e190c1018920be18Jakub Hrozek * notice, this list of conditions and the following disclaimer.
777374243e15c53e7b0a7345e190c1018920be18Jakub Hrozek * 2. Redistributions in binary form must reproduce the above copyright
777374243e15c53e7b0a7345e190c1018920be18Jakub Hrozek * notice, this list of conditions and the following disclaimer in
777374243e15c53e7b0a7345e190c1018920be18Jakub Hrozek * the documentation and/or other materials provided with the
777374243e15c53e7b0a7345e190c1018920be18Jakub Hrozek * distribution.
777374243e15c53e7b0a7345e190c1018920be18Jakub Hrozek * 3. The end-user documentation included with the redistribution,
777374243e15c53e7b0a7345e190c1018920be18Jakub Hrozek * if any, must include the following acknowledgment:
777374243e15c53e7b0a7345e190c1018920be18Jakub Hrozek * "This product includes software developed by the
777374243e15c53e7b0a7345e190c1018920be18Jakub Hrozek * Apache Software Foundation (http://www.apache.org/)."
777374243e15c53e7b0a7345e190c1018920be18Jakub Hrozek * Alternately, this acknowledgment may appear in the software itself,
777374243e15c53e7b0a7345e190c1018920be18Jakub Hrozek * if and wherever such third-party acknowledgments normally appear.
777374243e15c53e7b0a7345e190c1018920be18Jakub Hrozek * 4. The names "Apache" and "Apache Software Foundation" must
777374243e15c53e7b0a7345e190c1018920be18Jakub Hrozek * not be used to endorse or promote products derived from this
777374243e15c53e7b0a7345e190c1018920be18Jakub Hrozek * software without prior written permission. For written
777374243e15c53e7b0a7345e190c1018920be18Jakub Hrozek * permission, please contact apache@apache.org.
f424902e9e6c0fb6cae309bef0ce208b13733fb6Jakub Hrozek * 5. Products derived from this software may not be called "Apache",
f424902e9e6c0fb6cae309bef0ce208b13733fb6Jakub Hrozek * nor may "Apache" appear in their name, without prior written
f424902e9e6c0fb6cae309bef0ce208b13733fb6Jakub Hrozek * permission of the Apache Software Foundation.
f424902e9e6c0fb6cae309bef0ce208b13733fb6Jakub Hrozek * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
f424902e9e6c0fb6cae309bef0ce208b13733fb6Jakub Hrozek * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
f424902e9e6c0fb6cae309bef0ce208b13733fb6Jakub Hrozek * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
f424902e9e6c0fb6cae309bef0ce208b13733fb6Jakub Hrozek * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
f424902e9e6c0fb6cae309bef0ce208b13733fb6Jakub Hrozek * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
f424902e9e6c0fb6cae309bef0ce208b13733fb6Jakub Hrozek * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
f424902e9e6c0fb6cae309bef0ce208b13733fb6Jakub Hrozek * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
f424902e9e6c0fb6cae309bef0ce208b13733fb6Jakub Hrozek * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
f424902e9e6c0fb6cae309bef0ce208b13733fb6Jakub Hrozek * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
f424902e9e6c0fb6cae309bef0ce208b13733fb6Jakub Hrozek * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
f424902e9e6c0fb6cae309bef0ce208b13733fb6Jakub Hrozek * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
f424902e9e6c0fb6cae309bef0ce208b13733fb6Jakub Hrozek * SUCH DAMAGE.
f424902e9e6c0fb6cae309bef0ce208b13733fb6Jakub Hrozek * ====================================================================
f424902e9e6c0fb6cae309bef0ce208b13733fb6Jakub Hrozek * This software consists of voluntary contributions made by many
f424902e9e6c0fb6cae309bef0ce208b13733fb6Jakub Hrozek * individuals on behalf of the Apache Software Foundation. For more
f424902e9e6c0fb6cae309bef0ce208b13733fb6Jakub Hrozek * information on the Apache Software Foundation, please see
f424902e9e6c0fb6cae309bef0ce208b13733fb6Jakub Hrozek * Portions of this software are based upon public domain software
f424902e9e6c0fb6cae309bef0ce208b13733fb6Jakub Hrozek * originally written at the National Center for Supercomputing Applications,
f424902e9e6c0fb6cae309bef0ce208b13733fb6Jakub Hrozek * University of Illinois, Urbana-Champaign.
f424902e9e6c0fb6cae309bef0ce208b13733fb6Jakub Hrozek * Modified by djm@va.pubnix.com:
f424902e9e6c0fb6cae309bef0ce208b13733fb6Jakub Hrozek * If no TransferLog is given explicitly, decline to log.
f424902e9e6c0fb6cae309bef0ce208b13733fb6Jakub Hrozek * This is module implements the TransferLog directive (same as the
777374243e15c53e7b0a7345e190c1018920be18Jakub Hrozek * common log module), and additional directives, LogFormat and CustomLog.
777374243e15c53e7b0a7345e190c1018920be18Jakub Hrozek * TransferLog fn Logs transfers to fn in standard log format, unless
777374243e15c53e7b0a7345e190c1018920be18Jakub Hrozek * a custom format is set with LogFormat
777374243e15c53e7b0a7345e190c1018920be18Jakub Hrozek * LogFormat format Set a log format from TransferLog files
777374243e15c53e7b0a7345e190c1018920be18Jakub Hrozek * CustomLog fn format
777374243e15c53e7b0a7345e190c1018920be18Jakub Hrozek * Log to file fn with format given by the format
777374243e15c53e7b0a7345e190c1018920be18Jakub Hrozek * CookieLog fn For backwards compatability with old Cookie
777374243e15c53e7b0a7345e190c1018920be18Jakub Hrozek * logging module - now deprecated.
777374243e15c53e7b0a7345e190c1018920be18Jakub Hrozek * There can be any number of TransferLog and CustomLog
f424902e9e6c0fb6cae309bef0ce208b13733fb6Jakub Hrozek * commands. Each request will be logged to _ALL_ the
f424902e9e6c0fb6cae309bef0ce208b13733fb6Jakub Hrozek * named files, in the appropriate format.
777374243e15c53e7b0a7345e190c1018920be18Jakub Hrozek * If no TransferLog or CustomLog directive appears in a VirtualHost,
777374243e15c53e7b0a7345e190c1018920be18Jakub Hrozek * the request will be logged to the log file(s) defined outside
777374243e15c53e7b0a7345e190c1018920be18Jakub Hrozek * the virtual host section. If a TransferLog or CustomLog directive
777374243e15c53e7b0a7345e190c1018920be18Jakub Hrozek * appears in the VirtualHost section, the log files defined outside
777374243e15c53e7b0a7345e190c1018920be18Jakub Hrozek * the VirtualHost will _not_ be used. This makes this module compatable
777374243e15c53e7b0a7345e190c1018920be18Jakub Hrozek * with the CLF and config log modules, where the use of TransferLog
777374243e15c53e7b0a7345e190c1018920be18Jakub Hrozek * inside the VirtualHost section overrides its use outside.
777374243e15c53e7b0a7345e190c1018920be18Jakub Hrozek * <VirtualHost>
777374243e15c53e7b0a7345e190c1018920be18Jakub Hrozek * LogFormat "... custom format ..."
777374243e15c53e7b0a7345e190c1018920be18Jakub Hrozek * CustomLog log/virtual_useragents "%t %{user-agent}i"
777374243e15c53e7b0a7345e190c1018920be18Jakub Hrozek * </VirtualHost>
777374243e15c53e7b0a7345e190c1018920be18Jakub Hrozek * This will log using CLF to access_log any requests handled by the
777374243e15c53e7b0a7345e190c1018920be18Jakub Hrozek * main server, while any requests to the virtual host will be logged
777374243e15c53e7b0a7345e190c1018920be18Jakub Hrozek * with the "... custom format..." to virtual_only _AND_ using
777374243e15c53e7b0a7345e190c1018920be18Jakub Hrozek * the custom user-agent log to virtual_useragents.
777374243e15c53e7b0a7345e190c1018920be18Jakub Hrozek * Note that the NCSA referer and user-agent logs are easily added with
777374243e15c53e7b0a7345e190c1018920be18Jakub Hrozek * CustomLog:
777374243e15c53e7b0a7345e190c1018920be18Jakub Hrozek * CustomLog logs/referer "%{referer}i -> %U"
777374243e15c53e7b0a7345e190c1018920be18Jakub Hrozek * CustomLog logs/agent "%{user-agent}i"
777374243e15c53e7b0a7345e190c1018920be18Jakub Hrozek * RefererIgnore functionality can be obtained with conditional
777374243e15c53e7b0a7345e190c1018920be18Jakub Hrozek * logging (SetEnvIf and CustomLog ... env=!VAR).
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov * But using this method allows much easier modification of the
777374243e15c53e7b0a7345e190c1018920be18Jakub Hrozek * log format, e.g. to log hosts along with UA:
777374243e15c53e7b0a7345e190c1018920be18Jakub Hrozek * CustomLog logs/referer "%{referer}i %U %h"
777374243e15c53e7b0a7345e190c1018920be18Jakub Hrozek * The argument to LogFormat and CustomLog is a string, which can include
777374243e15c53e7b0a7345e190c1018920be18Jakub Hrozek * literal characters copied into the log files, and '%' directives as
777374243e15c53e7b0a7345e190c1018920be18Jakub Hrozek * %...B: bytes sent, excluding HTTP headers.
777374243e15c53e7b0a7345e190c1018920be18Jakub Hrozek * %...b: bytes sent, excluding HTTP headers in CLF format, i.e. a '-'
777374243e15c53e7b0a7345e190c1018920be18Jakub Hrozek * when no bytes where sent (rather than a '0'.
777374243e15c53e7b0a7345e190c1018920be18Jakub Hrozek * %...c: Status of the connection.
777374243e15c53e7b0a7345e190c1018920be18Jakub Hrozek * 'X' = connection aborted before the response completed.
777374243e15c53e7b0a7345e190c1018920be18Jakub Hrozek * '+' = connection may be kept alive after the response is sent.
777374243e15c53e7b0a7345e190c1018920be18Jakub Hrozek * '-' = connection will be closed after the response is sent.
777374243e15c53e7b0a7345e190c1018920be18Jakub Hrozek * %...{FOOBAR}C: The contents of the HTTP cookie FOOBAR
777374243e15c53e7b0a7345e190c1018920be18Jakub Hrozek * %...{FOOBAR}e: The contents of the environment variable FOOBAR
777374243e15c53e7b0a7345e190c1018920be18Jakub Hrozek * %...f: filename
777374243e15c53e7b0a7345e190c1018920be18Jakub Hrozek * %...h: remote host
777374243e15c53e7b0a7345e190c1018920be18Jakub Hrozek * %...a: remote IP-address
777374243e15c53e7b0a7345e190c1018920be18Jakub Hrozek * %...A: local IP-address
777374243e15c53e7b0a7345e190c1018920be18Jakub Hrozek * %...{Foobar}i: The contents of Foobar: header line(s) in the request
777374243e15c53e7b0a7345e190c1018920be18Jakub Hrozek * sent to the client.
777374243e15c53e7b0a7345e190c1018920be18Jakub Hrozek * %...l: remote logname (from identd, if supplied)
777374243e15c53e7b0a7345e190c1018920be18Jakub Hrozek * %...{Foobar}n: The contents of note "Foobar" from another module.
777374243e15c53e7b0a7345e190c1018920be18Jakub Hrozek * %...{Foobar}o: The contents of Foobar: header line(s) in the reply.
777374243e15c53e7b0a7345e190c1018920be18Jakub Hrozek * %...p: the port the request was served to
777374243e15c53e7b0a7345e190c1018920be18Jakub Hrozek * %...P: the process ID of the child that serviced the request.
777374243e15c53e7b0a7345e190c1018920be18Jakub Hrozek * %...r: first line of request
777374243e15c53e7b0a7345e190c1018920be18Jakub Hrozek * %...s: status. For requests that got internally redirected, this
777374243e15c53e7b0a7345e190c1018920be18Jakub Hrozek * is status of the *original* request --- %...>s for the last.
777374243e15c53e7b0a7345e190c1018920be18Jakub Hrozek * %...t: time, in common log format time format
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov * %...{format}t: The time, in the form given by format, which should
777374243e15c53e7b0a7345e190c1018920be18Jakub Hrozek * be in strftime(3) format.
777374243e15c53e7b0a7345e190c1018920be18Jakub Hrozek * %...T: the time taken to serve the request, in seconds.
777374243e15c53e7b0a7345e190c1018920be18Jakub Hrozek * %...D: the time taken to serve the request, in micro seconds.
777374243e15c53e7b0a7345e190c1018920be18Jakub Hrozek * %...u: remote user (from auth; may be bogus if return status (%s) is 401)
777374243e15c53e7b0a7345e190c1018920be18Jakub Hrozek * %...U: the URL path requested.
777374243e15c53e7b0a7345e190c1018920be18Jakub Hrozek * %...v: the configured name of the server (i.e. which virtual host?)
777374243e15c53e7b0a7345e190c1018920be18Jakub Hrozek * %...V: the server name according to the UseCanonicalName setting
777374243e15c53e7b0a7345e190c1018920be18Jakub Hrozek * %...m: the request method
777374243e15c53e7b0a7345e190c1018920be18Jakub Hrozek * %...H: the request protocol
777374243e15c53e7b0a7345e190c1018920be18Jakub Hrozek * %...q: the query string prepended by "?", or empty if no query string
777374243e15c53e7b0a7345e190c1018920be18Jakub Hrozek * The '...' can be nothing at all (e.g. "%h %u %r %s %b"), or it can
777374243e15c53e7b0a7345e190c1018920be18Jakub Hrozek * indicate conditions for inclusion of the item (which will cause it
777374243e15c53e7b0a7345e190c1018920be18Jakub Hrozek * to be replaced with '-' if the condition is not met). Note that
777374243e15c53e7b0a7345e190c1018920be18Jakub Hrozek * there is no escaping performed on the strings from %r, %...i and
777374243e15c53e7b0a7345e190c1018920be18Jakub Hrozek * %...o; some with long memories may remember that I thought this was
777374243e15c53e7b0a7345e190c1018920be18Jakub Hrozek * a bad idea, once upon a time, and I'm still not comfortable with
777374243e15c53e7b0a7345e190c1018920be18Jakub Hrozek * it, but it is difficult to see how to "do the right thing" with all
777374243e15c53e7b0a7345e190c1018920be18Jakub Hrozek * of '%..i', unless we URL-escape everything and break with CLF.
777374243e15c53e7b0a7345e190c1018920be18Jakub Hrozek * The forms of condition are a list of HTTP status codes, which may
777374243e15c53e7b0a7345e190c1018920be18Jakub Hrozek * or may not be preceded by '!'. Thus, '%400,501{User-agent}i' logs
777374243e15c53e7b0a7345e190c1018920be18Jakub Hrozek * User-agent: on 400 errors and 501 errors (Bad Request, Not
777374243e15c53e7b0a7345e190c1018920be18Jakub Hrozek * Implemented) only; '%!200,304,302{Referer}i' logs Referer: on all
777374243e15c53e7b0a7345e190c1018920be18Jakub Hrozek * requests which did *not* return some sort of normal status.
777374243e15c53e7b0a7345e190c1018920be18Jakub Hrozek * The default LogFormat reproduces CLF; see below.
777374243e15c53e7b0a7345e190c1018920be18Jakub Hrozek * The way this is supposed to work with virtual hosts is as follows:
777374243e15c53e7b0a7345e190c1018920be18Jakub Hrozek * a virtual host can have its own LogFormat, or its own TransferLog.
777374243e15c53e7b0a7345e190c1018920be18Jakub Hrozek * If it doesn't have its own LogFormat, it inherits from the main
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov * server. If it doesn't have its own TransferLog, it writes to the
777374243e15c53e7b0a7345e190c1018920be18Jakub Hrozek * same descriptor (meaning the same process for "| ...").
777374243e15c53e7b0a7345e190c1018920be18Jakub Hrozek * --- rst */
777374243e15c53e7b0a7345e190c1018920be18Jakub Hrozek#define DEFAULT_LOG_FORMAT "%h %l %u %t \"%r\" %>s %b"
777374243e15c53e7b0a7345e190c1018920be18Jakub Hrozekmodule AP_MODULE_DECLARE_DATA log_config_module;
777374243e15c53e7b0a7345e190c1018920be18Jakub Hrozekstatic int xfer_flags = (APR_WRITE | APR_APPEND | APR_CREATE);
777374243e15c53e7b0a7345e190c1018920be18Jakub Hrozekstatic apr_fileperms_t xfer_perms = APR_OS_DEFAULT;
777374243e15c53e7b0a7345e190c1018920be18Jakub Hrozek/* POSIX.1 defines PIPE_BUF as the maximum number of bytes that is
777374243e15c53e7b0a7345e190c1018920be18Jakub Hrozek * guaranteed to be atomic when writing a pipe. And PIPE_BUF >= 512
777374243e15c53e7b0a7345e190c1018920be18Jakub Hrozek * is guaranteed. So we'll just guess 512 in the event the system
777374243e15c53e7b0a7345e190c1018920be18Jakub Hrozek * doesn't have this. Now, for file writes there is actually no limit,
777374243e15c53e7b0a7345e190c1018920be18Jakub Hrozek * the entire write is atomic. Whether all systems implement this
777374243e15c53e7b0a7345e190c1018920be18Jakub Hrozek * correctly is another question entirely ... so we'll just use PIPE_BUF
777374243e15c53e7b0a7345e190c1018920be18Jakub Hrozek * because it's probably a good guess as to what is implemented correctly
777374243e15c53e7b0a7345e190c1018920be18Jakub Hrozek * everywhere.
777374243e15c53e7b0a7345e190c1018920be18Jakub Hrozek * multi_log_state is our per-(virtual)-server configuration. We store
777374243e15c53e7b0a7345e190c1018920be18Jakub Hrozek * an array of the logs we are going to use, each of type config_log_state.
777374243e15c53e7b0a7345e190c1018920be18Jakub Hrozek * If a default log format is given by LogFormat, store in default_format
777374243e15c53e7b0a7345e190c1018920be18Jakub Hrozek * (backward compat. with mod_log_config). We also store for each virtual
777374243e15c53e7b0a7345e190c1018920be18Jakub Hrozek * server a pointer to the logs specified for the main server, so that if this
f424902e9e6c0fb6cae309bef0ce208b13733fb6Jakub Hrozek * vhost has no logs defined, we can use the main server's logs instead.
f424902e9e6c0fb6cae309bef0ce208b13733fb6Jakub Hrozek * So, for the main server, config_logs contains a list of the log files
f424902e9e6c0fb6cae309bef0ce208b13733fb6Jakub Hrozek * and server_config_logs in empty. For a vhost, server_config_logs
f424902e9e6c0fb6cae309bef0ce208b13733fb6Jakub Hrozek * points to the same array as config_logs in the main server, and
f424902e9e6c0fb6cae309bef0ce208b13733fb6Jakub Hrozek * config_logs points to the array of logs defined inside this vhost,
f424902e9e6c0fb6cae309bef0ce208b13733fb6Jakub Hrozek * which might be empty.
f424902e9e6c0fb6cae309bef0ce208b13733fb6Jakub Hrozektypedef struct {
f424902e9e6c0fb6cae309bef0ce208b13733fb6Jakub Hrozek * config_log_state holds the status of a single log file. fname might
f424902e9e6c0fb6cae309bef0ce208b13733fb6Jakub Hrozek * be NULL, which means this module does no logging for this
f424902e9e6c0fb6cae309bef0ce208b13733fb6Jakub Hrozek * request. format might be NULL, in which case the default_format
f424902e9e6c0fb6cae309bef0ce208b13733fb6Jakub Hrozek * from the multi_log_state should be used, or if that is NULL as
f424902e9e6c0fb6cae309bef0ce208b13733fb6Jakub Hrozek * well, use the CLF. log_fd is NULL before the log file is opened and
f424902e9e6c0fb6cae309bef0ce208b13733fb6Jakub Hrozek * set to a valid fd after it is opened.
f424902e9e6c0fb6cae309bef0ce208b13733fb6Jakub Hrozektypedef struct {
f424902e9e6c0fb6cae309bef0ce208b13733fb6Jakub Hrozek * Format items...
f424902e9e6c0fb6cae309bef0ce208b13733fb6Jakub Hrozek * Note that many of these could have ap_sprintfs replaced with static buffers.
f424902e9e6c0fb6cae309bef0ce208b13733fb6Jakub Hrozektypedef struct {
f424902e9e6c0fb6cae309bef0ce208b13733fb6Jakub Hrozekstatic char *format_integer(apr_pool_t *p, int i)
f424902e9e6c0fb6cae309bef0ce208b13733fb6Jakub Hrozek if (i <= 0) {
f424902e9e6c0fb6cae309bef0ce208b13733fb6Jakub Hrozekstatic const char *constant_item(request_rec *dummy, char *stuff)
f424902e9e6c0fb6cae309bef0ce208b13733fb6Jakub Hrozekstatic const char *log_remote_host(request_rec *r, char *a)
f424902e9e6c0fb6cae309bef0ce208b13733fb6Jakub Hrozek return ap_get_remote_host(r->connection, r->per_dir_config,
f424902e9e6c0fb6cae309bef0ce208b13733fb6Jakub Hrozekstatic const char *log_remote_address(request_rec *r, char *a)
f424902e9e6c0fb6cae309bef0ce208b13733fb6Jakub Hrozekstatic const char *log_local_address(request_rec *r, char *a)
f424902e9e6c0fb6cae309bef0ce208b13733fb6Jakub Hrozekstatic const char *log_remote_logname(request_rec *r, char *a)
f424902e9e6c0fb6cae309bef0ce208b13733fb6Jakub Hrozekstatic const char *log_remote_user(request_rec *r, char *a)
f424902e9e6c0fb6cae309bef0ce208b13733fb6Jakub Hrozekstatic const char *log_request_line(request_rec *r, char *a)
f424902e9e6c0fb6cae309bef0ce208b13733fb6Jakub Hrozek /* NOTE: If the original request contained a password, we
f424902e9e6c0fb6cae309bef0ce208b13733fb6Jakub Hrozek * re-write the request line here to contain XXXXXX instead:
f424902e9e6c0fb6cae309bef0ce208b13733fb6Jakub Hrozek * (note the truncation before the protocol string for HTTP/0.9 requests)
f424902e9e6c0fb6cae309bef0ce208b13733fb6Jakub Hrozek * (note also that r->the_request contains the unmodified request)
f424902e9e6c0fb6cae309bef0ce208b13733fb6Jakub Hrozek return (r->parsed_uri.password) ? apr_pstrcat(r->pool, r->method, " ",
f424902e9e6c0fb6cae309bef0ce208b13733fb6Jakub Hrozek ap_unparse_uri_components(r->pool, &r->parsed_uri, 0),
f424902e9e6c0fb6cae309bef0ce208b13733fb6Jakub Hrozek r->assbackwards ? NULL : " ", r->protocol, NULL)
f424902e9e6c0fb6cae309bef0ce208b13733fb6Jakub Hrozekstatic const char *log_request_file(request_rec *r, char *a)
f424902e9e6c0fb6cae309bef0ce208b13733fb6Jakub Hrozekstatic const char *log_request_uri(request_rec *r, char *a)
f424902e9e6c0fb6cae309bef0ce208b13733fb6Jakub Hrozekstatic const char *log_request_method(request_rec *r, char *a)
f424902e9e6c0fb6cae309bef0ce208b13733fb6Jakub Hrozekstatic const char *log_request_protocol(request_rec *r, char *a)
f424902e9e6c0fb6cae309bef0ce208b13733fb6Jakub Hrozekstatic const char *log_request_query(request_rec *r, char *a)
f424902e9e6c0fb6cae309bef0ce208b13733fb6Jakub Hrozek return (r->args != NULL) ? apr_pstrcat(r->pool, "?", r->args, NULL)
f424902e9e6c0fb6cae309bef0ce208b13733fb6Jakub Hrozekstatic const char *log_status(request_rec *r, char *a)
f424902e9e6c0fb6cae309bef0ce208b13733fb6Jakub Hrozekstatic const char *clf_log_bytes_sent(request_rec *r, char *a)
777374243e15c53e7b0a7345e190c1018920be18Jakub Hrozek return apr_psprintf(r->pool, "%ld", r->bytes_sent);
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashovstatic const char *log_bytes_sent(request_rec *r, char *a)
777374243e15c53e7b0a7345e190c1018920be18Jakub Hrozek return apr_psprintf(r->pool, "%ld", r->bytes_sent);
777374243e15c53e7b0a7345e190c1018920be18Jakub Hrozekstatic const char *log_header_in(request_rec *r, char *a)
777374243e15c53e7b0a7345e190c1018920be18Jakub Hrozekstatic const char *log_header_out(request_rec *r, char *a)
777374243e15c53e7b0a7345e190c1018920be18Jakub Hrozek const char *cp = apr_table_get(r->headers_out, a);
777374243e15c53e7b0a7345e190c1018920be18Jakub Hrozek if (!strcasecmp(a, "Content-type") && r->content_type) {
777374243e15c53e7b0a7345e190c1018920be18Jakub Hrozek cp = ap_field_noparam(r->pool, r->content_type);
777374243e15c53e7b0a7345e190c1018920be18Jakub Hrozekstatic const char *log_note(request_rec *r, char *a)
f424902e9e6c0fb6cae309bef0ce208b13733fb6Jakub Hrozekstatic const char *log_env_var(request_rec *r, char *a)
f424902e9e6c0fb6cae309bef0ce208b13733fb6Jakub Hrozekstatic const char *log_cookie(request_rec *r, char *a)
f424902e9e6c0fb6cae309bef0ce208b13733fb6Jakub Hrozek if ((cookies = apr_table_get(r->headers_in, "Cookie"))) {
f424902e9e6c0fb6cae309bef0ce208b13733fb6Jakub Hrozek start_cookie += strlen(a) + 1; /* cookie_name + '=' */
f424902e9e6c0fb6cae309bef0ce208b13733fb6Jakub Hrozek /* kill everything in cookie after ';' */
777374243e15c53e7b0a7345e190c1018920be18Jakub Hrozekstatic const char *log_request_time(request_rec *r, char *a)
777374243e15c53e7b0a7345e190c1018920be18Jakub Hrozek hi. i think getting the time again at the end of the request
777374243e15c53e7b0a7345e190c1018920be18Jakub Hrozek just for logging is dumb. i know it's "required" for CLF.
777374243e15c53e7b0a7345e190c1018920be18Jakub Hrozek folks writing log parsing tools don't realise that out of order
777374243e15c53e7b0a7345e190c1018920be18Jakub Hrozek times have always been possible (consider what happens if one
777374243e15c53e7b0a7345e190c1018920be18Jakub Hrozek process calculates the time to log, but then there's a context
777374243e15c53e7b0a7345e190c1018920be18Jakub Hrozek switch before it writes and before that process is run again the
777374243e15c53e7b0a7345e190c1018920be18Jakub Hrozek log rotation occurs) and they should just fix their tools rather
777374243e15c53e7b0a7345e190c1018920be18Jakub Hrozek than force the server to pay extra cpu cycles. if you've got
char sign;
int timz;
if (timz < 0) {
/ APR_USEC_PER_SEC);
return ap_get_server_name(r);
const char **sa)
s = *sa;
s = *sa;
*sa = s;
return NULL;
const char *s = *sa;
while (apr_isdigit(*++s)) {
if (!handler) {
*sa = s;
return NULL;
char *res;
return NULL;
s = APR_EOL_STR;
const char *cp;
int in_list = 0;
#ifdef BUFFERED_LOGS
char *str, *s;
const char **strs;
int *strl;
char *envar;
return DECLINED;
return DECLINED;
return DECLINED;
orig = r;
while (r->next) {
r = r->next;
#ifdef BUFFERED_LOGS
apr_size_t w;
s += strl[i];
w = len;
s += strl[i];
s += strl[i];
return OK;
return OK;
return mls;
return add;
const char *name)
return err_string;
return err_string;
const char *fn)
{NULL}
!= APR_SUCCESS) {
#ifdef BUFFERED_LOGS
return cls;
const char *dummy;
const char *format;
if (format) {
if (format) {
if (format) {
return NULL;
#ifdef BUFFERED_LOGS
for (; s; s = s->next) {
if (log_list) {
return APR_SUCCESS;
open_multi_logs(s, p);
open_multi_logs(s, p);
#ifdef BUFFERED_LOGS
if (log_pfn_register) {