From 194829ce9f1c5f3d3f020fad1836b7ab81cdb209 Mon Sep 17 00:00:00 2001 From: Ian Holsman Date: Sat, 28 Sep 2002 04:18:35 +0000 Subject: [PATCH] New Module -- mod_logio. This adds the ability to log the bytes sent and received for each request Submitted by: Bojan Smojver Reviewed by: Justin & Ian git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@97000 13f79535-47bb-0310-9956-ffa450edef68 --- CHANGES | 3 + docs/conf/httpd-std.conf.in | 3 + docs/conf/httpd-win.conf | 3 + docs/manual/mod/mod_log_config.html.en | 12 +- docs/manual/mod/mod_log_config.xml | 8 + docs/manual/mod/mod_logio.xml | 57 +++++++ modules/loggers/config.m4 | 2 + modules/loggers/mod_logio.c | 226 +++++++++++++++++++++++++ 8 files changed, 313 insertions(+), 1 deletion(-) create mode 100644 docs/manual/mod/mod_logio.xml create mode 100644 modules/loggers/mod_logio.c diff --git a/CHANGES b/CHANGES index 5d0bb2db05..46fdff9d8d 100644 --- a/CHANGES +++ b/CHANGES @@ -1,5 +1,8 @@ Changes with Apache 2.0.43 + *) New Module: mod_logio. adds the ability to log bytes sent and + received. [Bojan Smojver ] + *) SuExec needs to use the same default directory as the rest of server, namely /usr/local/apache2. [SangBeom han ] diff --git a/docs/conf/httpd-std.conf.in b/docs/conf/httpd-std.conf.in index be7063cf70..a055fdced8 100644 --- a/docs/conf/httpd-std.conf.in +++ b/docs/conf/httpd-std.conf.in @@ -479,6 +479,9 @@ LogFormat "%h %l %u %t \"%r\" %>s %b" common LogFormat "%{Referer}i -> %U" referer LogFormat "%{User-agent}i" agent +# You need to enable mod_logio.c to use %I and %O +#LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" %I %O" combinedio + # # The location and format of the access logfile (Common Logfile Format). # If you do not define any access logfiles within a diff --git a/docs/conf/httpd-win.conf b/docs/conf/httpd-win.conf index 09aeab5a68..0f54df71e2 100644 --- a/docs/conf/httpd-win.conf +++ b/docs/conf/httpd-win.conf @@ -406,6 +406,9 @@ LogFormat "%h %l %u %t \"%r\" %>s %b" common LogFormat "%{Referer}i -> %U" referer LogFormat "%{User-agent}i" agent +# You need to enable mod_logio.c to use %I and %O +#LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" %I %O" combinedio + # # The location and format of the access logfile (Common Logfile Format). # If you do not define any access logfiles within a diff --git a/docs/manual/mod/mod_log_config.html.en b/docs/manual/mod/mod_log_config.html.en index a35990ddf5..e2184dd246 100644 --- a/docs/manual/mod/mod_log_config.html.en +++ b/docs/manual/mod/mod_log_config.html.en @@ -138,6 +138,16 @@ be in strftime(3) format. (potentially localized) this conflicted with the historical ssl %...{var}c syntax.) +%...I: +Bytes received, including request and headers, cannot be zero. You need to +enable mod_logio to use this. + +%...O: +Bytes sent, including headers, cannot be zero. You need to enable mod_logio to use +this. +

The "..." can be nothing at all (e.g., "%h %u @@ -352,4 +362,4 @@ hostStatus: TransferLog logs/access_log

- \ No newline at end of file + diff --git a/docs/manual/mod/mod_log_config.xml b/docs/manual/mod/mod_log_config.xml index 86fce8d575..b5412c0676 100644 --- a/docs/manual/mod/mod_log_config.xml +++ b/docs/manual/mod/mod_log_config.xml @@ -143,6 +143,14 @@ be in strftime(3) format. (potentially localized) this conflicted with the historical ssl %...{var}c syntax.) +%...I: +Bytes received, including request and headers, cannot be zero. You need to +enable mod_logio to use this. + +%...O: +Bytes sent, including headers, cannot be zero. You need to enable +mod_logio to use this. +

The "..." can be nothing at all (e.g., "%h %u diff --git a/docs/manual/mod/mod_logio.xml b/docs/manual/mod/mod_logio.xml new file mode 100644 index 0000000000..7d1d817082 --- /dev/null +++ b/docs/manual/mod/mod_logio.xml @@ -0,0 +1,57 @@ + + + + + +mod_logio +Logging of input and output bytes per request +Base +mod_logio.c +logio_module + +

+ +

This module provides the logging of input and output number of + bytes received/sent per request. The numbers reflect the actual bytes + as received on the network, which then takes into account the + headers and bodies of requests and responses. The counting is done + before SSL/TLS on input and after SSL/TLS on output, so the numbers + will correctly reflect any changes made by encryption.

+ +

This module requires mod_log_config.

+ +
+ +Apache Log Files + +
+Custom Log Formats + +

This modules adds two new logging directives. The characteristics of the + request itself are logged by placing "%" directives in the format string, + which are replaced in the log file by the values as follows:

+ + + + + + + + + +
%...I:Bytes received, including request and headers, cannot be zero.
%...O:Bytes sent, including headers, cannot be zero.
+ +

Usually, the functionality is used like this:

+ +
+ +
Combined I/O log format:
+ +
"%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" + \"%{User-agent}i\" %I %O"
+ +
+ +
+ + diff --git a/modules/loggers/config.m4 b/modules/loggers/config.m4 index 8d4304abc4..4e383cd306 100644 --- a/modules/loggers/config.m4 +++ b/modules/loggers/config.m4 @@ -6,4 +6,6 @@ APACHE_MODPATH_INIT(loggers) APACHE_MODULE(log_config, logging configuration, , , yes) +APACHE_MODULE(logio, input and output logging, , , no) + APACHE_MODPATH_FINISH diff --git a/modules/loggers/mod_logio.c b/modules/loggers/mod_logio.c new file mode 100644 index 0000000000..64c364d4b6 --- /dev/null +++ b/modules/loggers/mod_logio.c @@ -0,0 +1,226 @@ +/* ==================================================================== + * The Apache Software License, Version 1.1 + * + * Copyright (c) 2000-2002 The Apache Software Foundation. All rights + * reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The end-user documentation included with the redistribution, + * if any, must include the following acknowledgment: + * "This product includes software developed by the + * Apache Software Foundation (http://www.apache.org/)." + * Alternately, this acknowledgment may appear in the software itself, + * if and wherever such third-party acknowledgments normally appear. + * + * 4. The names "Apache" and "Apache Software Foundation" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact apache@apache.org. + * + * 5. Products derived from this software may not be called "Apache", + * nor may "Apache" appear in their name, without prior written + * permission of the Apache Software Foundation. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + * Portions of this software are based upon public domain software + * originally written at the National Center for Supercomputing Applications, + * University of Illinois, Urbana-Champaign. + */ + +/* + * Written by Bojan Smojver : + * + * The argument to LogFormat and CustomLog is a string, which can include + * literal characters copied into the log files, and '%' directives as + * follows: + * + * %...I: bytes received, including request and headers, cannot be zero + * %...O: bytes sent, including headers, cannot be zero + * + */ + +#include "apr_strings.h" +#include "apr_lib.h" +#include "apr_hash.h" +#include "apr_optional.h" + +#define APR_WANT_STRFUNC +#include "apr_want.h" + +#include "ap_config.h" +#include "mod_log_config.h" +#include "httpd.h" +#include "http_config.h" +#include "http_protocol.h" + +module AP_MODULE_DECLARE_DATA logio_module; + +static const char logio_filter_name[] = "LOG_INPUT_OUTPUT"; + +/* + * Logging of input and output config... + */ + +typedef struct logio_config_t { + apr_off_t bytes_in; + apr_off_t bytes_out; +} logio_config_t; + +/* + * Format items... + */ + +static const char *log_bytes_in(request_rec *r, char *a) +{ + logio_config_t *cf = ap_get_module_config(r->connection->conn_config, + &logio_module); + + return apr_off_t_toa(r->pool, cf->bytes_in); +} + +static const char *log_bytes_out(request_rec *r, char *a) +{ + logio_config_t *cf = ap_get_module_config(r->connection->conn_config, + &logio_module); + + return apr_off_t_toa(r->pool, cf->bytes_out); +} + +/* + * Reset counters after logging... + */ + +static int logio_transaction(request_rec *r) +{ + logio_config_t *cf = ap_get_module_config(r->connection->conn_config, + &logio_module); + + cf->bytes_in = cf->bytes_out = 0; + + return OK; +} + +/* + * Logging of input and output filters... + */ + +static apr_status_t logio_out_filter(ap_filter_t *f, + apr_bucket_brigade *bb) { + apr_off_t length; + logio_config_t *cf = ap_get_module_config(f->c->conn_config, &logio_module); + + if (!cf) { /* Create config */ + cf = apr_pcalloc(f->c->pool, sizeof(*cf)); + ap_set_module_config(f->c->conn_config, &logio_module, cf); + } + + apr_brigade_length (bb, 0, &length); + + if (length > 0) + cf->bytes_out += length; + + return ap_pass_brigade(f->next, bb); +} + +static apr_status_t logio_in_filter(ap_filter_t *f, + apr_bucket_brigade *bb, + ap_input_mode_t mode, + apr_read_type_e block, + apr_off_t readbytes) { + apr_off_t length; + apr_status_t status; + logio_config_t *cf = ap_get_module_config(f->c->conn_config, &logio_module); + + status = ap_get_brigade(f->next, bb, mode, block, readbytes); + + if (!cf) { /* Create config */ + cf = apr_pcalloc(f->c->pool, sizeof(*cf)); + ap_set_module_config(f->c->conn_config, &logio_module, cf); + } + + apr_brigade_length (bb, 0, &length); + + if (length > 0) + cf->bytes_in += length; + + return status; +} + +/* + * The hooks... + */ + +static int logio_pre_conn(conn_rec *c) { + ap_add_input_filter(logio_filter_name, NULL, NULL, c); + ap_add_output_filter(logio_filter_name, NULL, NULL, c); + + return OK; +} + +static int logio_pre_config(apr_pool_t *p, apr_pool_t *plog, apr_pool_t *ptemp) +{ + static APR_OPTIONAL_FN_TYPE(ap_register_log_handler) *log_pfn_register; + + log_pfn_register = APR_RETRIEVE_OPTIONAL_FN(ap_register_log_handler); + + if (log_pfn_register) { + log_pfn_register(p, "I", log_bytes_in, 0); + log_pfn_register(p, "O", log_bytes_out, 0); + } + + return OK; +} + +static void register_hooks(apr_pool_t *p) +{ + static const char *pre[] = { "mod_log_config.c", NULL }; + + ap_hook_pre_connection(logio_pre_conn, NULL, NULL, APR_HOOK_MIDDLE); + ap_hook_pre_config(logio_pre_config, NULL, NULL, APR_HOOK_REALLY_FIRST); + ap_hook_log_transaction(logio_transaction, pre, NULL, APR_HOOK_MIDDLE); + + ap_register_input_filter(logio_filter_name, logio_in_filter, NULL, + AP_FTYPE_NETWORK - 1); + ap_register_output_filter(logio_filter_name, logio_out_filter, NULL, + AP_FTYPE_NETWORK - 1); +} + +module AP_MODULE_DECLARE_DATA logio_module = +{ + STANDARD20_MODULE_STUFF, + NULL, /* create per-dir config */ + NULL, /* merge per-dir config */ + NULL, /* server config */ + NULL, /* merge server config */ + NULL, /* command apr_table_t */ + register_hooks /* register hooks */ +}; -- 2.40.0