⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mod_log_nw.c

📁 apache 安装教程 apache 安装教程
💻 C
📖 第 1 页 / 共 3 页
字号:
/* Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements.  See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License.  You may obtain a copy of the License at * *     http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. *//* * Modified by djm@va.pubnix.com: * If no TransferLog is given explicitly, decline to log. * * This is module implements the TransferLog directive (same as the * common log module), and additional directives, LogFormat and CustomLog. * * * Syntax: * *    TransferLog fn      Logs transfers to fn in standard log format, unless *                        a custom format is set with LogFormat *    LogFormat format    Set a log format from TransferLog files *    CustomLog fn format *                        Log to file fn with format given by the format *                        argument * *    CookieLog fn        For backwards compatability with old Cookie *                        logging module - now deprecated. * * There can be any number of TransferLog and CustomLog * commands. Each request will be logged to _ALL_ the * named files, in the appropriate format. * * If no TransferLog or CustomLog directive appears in a VirtualHost, * the request will be logged to the log file(s) defined outside * the virtual host section. If a TransferLog or CustomLog directive * appears in the VirtualHost section, the log files defined outside * the VirtualHost will _not_ be used. This makes this module compatable * with the CLF and config log modules, where the use of TransferLog * inside the VirtualHost section overrides its use outside. *  * Examples: * *    TransferLog    logs/access_log *    <VirtualHost> *    LogFormat      "... custom format ..." *    TransferLog    log/virtual_only *    CustomLog      log/virtual_useragents "%t %{user-agent}i" *    </VirtualHost> * * This will log using CLF to access_log any requests handled by the * main server, while any requests to the virtual host will be logged * with the "... custom format..." to virtual_only _AND_ using * the custom user-agent log to virtual_useragents. * * Note that the NCSA referer and user-agent logs are easily added with * CustomLog: *   CustomLog   logs/referer  "%{referer}i -> %U" *   CustomLog   logs/agent    "%{user-agent}i" * * 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: *   CustomLog   logs/referer "%{referer}i %U %h" * * The argument to LogFormat and CustomLog is a string, which can include * literal characters copied into the log files, and '%' directives as * follows: * * %...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'. * %...c:  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. * %...{FOOBAR}e:  The contents of the environment variable FOOBAR * %...f:  filename * %...h:  remote host * %...a:  remote IP-address * %...A:  local IP-address * %...{Foobar}i:  The contents of Foobar: header line(s) in the request *                 sent to the client. * %...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 port the request was served to * %...P:  the process ID of the child that serviced the request. * %...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. * %...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 * * 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 "| ..."). * * --- rst */#define DEFAULT_LOG_FORMAT "%h %l %u %t \"%r\" %>s %b"#include "httpd.h"#include "http_config.h"#include "http_core.h"          /* For REMOTE_NAME */#include "http_log.h"#include <limits.h>module MODULE_VAR_EXPORT config_log_module;static int xfer_flags = (O_WRONLY | O_APPEND | O_CREAT);#if defined(OS2) || defined(WIN32) || defined(NETWARE)/* OS/2 dosen't support users and groups */static mode_t xfer_mode = (S_IREAD | S_IWRITE);#elsestatic mode_t xfer_mode = (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);#endif/* 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 * everywhere. */#ifdef PIPE_BUF#define LOG_BUFSIZE     PIPE_BUF#else#define LOG_BUFSIZE     (512)#endif/* * 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 in 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, * which might be empty. */typedef struct {    char *default_format_string;    array_header *default_format;    array_header *config_logs;    array_header *server_config_logs;    table *formats;    int rotatedaily;    int rotateinterval;} multi_log_state;/* * 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 * well, use the CLF. log_fd is -1 before the log file is opened and * set to a valid fd after it is opened. */typedef struct {    char *fname;    char *format_string;    array_header *format;    int log_fd;    char *condition_var;#ifdef BUFFERED_LOGS    int outcnt;    char outbuf[LOG_BUFSIZE];#endif    time_t time_jump;} config_log_state;/* * Format items... * Note that many of these could have ap_sprintfs replaced with static buffers. */typedef const char *(*item_key_func) (request_rec *, char *);typedef struct {    item_key_func func;    char *arg;    int condition_sense;    int want_orig;    array_header *conditions;} log_format_item;static char *format_integer(pool *p, int i){    return ap_psprintf(p, "%d", i);}static char *pfmt(pool *p, int i){    if (i <= 0) {        return "-";    }    else {        return format_integer(p, i);    }}static const char *constant_item(request_rec *dummy, char *stuff){    return stuff;}static const char *log_remote_host(request_rec *r, char *a){    return ap_get_remote_host(r->connection, r->per_dir_config,                                    REMOTE_NAME);}static const char *log_remote_address(request_rec *r, char *a){    return r->connection->remote_ip;}static const char *log_local_address(request_rec *r, char *a){    return r->connection->local_ip;}static const char *log_remote_logname(request_rec *r, char *a){    return ap_get_remote_logname(r);}static const char *log_remote_user(request_rec *r, char *a){    char *rvalue = r->connection->user;    if (rvalue == NULL) {        rvalue = "-";    }    else if (strlen(rvalue) == 0) {        rvalue = "\"\"";    }    return rvalue;}static const char *log_request_line(request_rec *r, char *a){	    /* 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)	     */    return (r->parsed_uri.password) ? ap_pstrcat(r->pool, r->method, " ",					 ap_unparse_uri_components(r->pool, &r->parsed_uri, 0),					 r->assbackwards ? NULL : " ", r->protocol, NULL)					: r->the_request;}static const char *log_request_file(request_rec *r, char *a){    return r->filename;}static const char *log_request_uri(request_rec *r, char *a){    return r->uri;}static const char *log_request_method(request_rec *r, char *a){    return r->method;}static const char *log_request_protocol(request_rec *r, char *a){    return r->protocol;}static const char *log_request_query(request_rec *r, char *a){    return (r->args != NULL) ? ap_pstrcat(r->pool, "?", r->args, NULL)                             : "";}static const char *log_status(request_rec *r, char *a){    return pfmt(r->pool, r->status);}static const char *clf_log_bytes_sent(request_rec *r, char *a){    if (!r->sent_bodyct) {        return "-";    }    else {        long int bs;        ap_bgetopt(r->connection->client, BO_BYTECT, &bs);	return ap_psprintf(r->pool, "%ld", bs);    }}static const char *log_bytes_sent(request_rec *r, char *a){    if (!r->sent_bodyct) {        return "0";    }    else {        long int bs;        ap_bgetopt(r->connection->client, BO_BYTECT, &bs);	return ap_psprintf(r->pool, "%ld", bs);    }}static const char *log_header_in(request_rec *r, char *a){    return ap_table_get(r->headers_in, a);}static const char *log_header_out(request_rec *r, char *a){    const char *cp = ap_table_get(r->headers_out, a);    if (!strcasecmp(a, "Content-type") && r->content_type) {        cp = ap_field_noparam(r->pool, r->content_type);    }    if (cp) {        return cp;    }    return ap_table_get(r->err_headers_out, a);}static const char *log_note(request_rec *r, char *a){    return ap_table_get(r->notes, a);}static const char *log_env_var(request_rec *r, char *a){    return ap_table_get(r->subprocess_env, a);}static const char *log_request_time(request_rec *r, char *a){    int timz;    struct tm *t;    char tstr[MAX_STRING_LEN];    t = ap_get_gmtoff(&timz);    if (a && *a) {              /* Custom format */        strftime(tstr, MAX_STRING_LEN, a, t);    }    else {                      /* CLF format */        char sign = (timz < 0 ? '-' : '+');        if (timz < 0) {            timz = -timz;        }        ap_snprintf(tstr, sizeof(tstr), "[%02d/%s/%d:%02d:%02d:%02d %c%.2d%.2d]",                t->tm_mday, ap_month_snames[t->tm_mon], t->tm_year+1900,                 t->tm_hour, t->tm_min, t->tm_sec,                sign, timz / 60, timz % 60);    }    return ap_pstrdup(r->pool, tstr);}static const char *log_request_duration(request_rec *r, char *a){    return ap_psprintf(r->pool, "%ld", time(NULL) - r->request_time);}/* These next two routines use the canonical name:port so that log * parsers don't need to duplicate all the vhost parsing crud. */static const char *log_virtual_host(request_rec *r, char *a){    return r->server->server_hostname;}static const char *log_server_port(request_rec *r, char *a){    return ap_psprintf(r->pool, "%u",	r->server->port ? r->server->port : ap_default_port(r));

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -