]> granicus.if.org Git - apache/commitdiff
New Module -- mod_logio.
authorIan Holsman <ianh@apache.org>
Sat, 28 Sep 2002 04:18:35 +0000 (04:18 +0000)
committerIan Holsman <ianh@apache.org>
Sat, 28 Sep 2002 04:18:35 +0000 (04:18 +0000)
This adds the ability to log the bytes sent and
received for each request

Submitted by: Bojan Smojver <bojan@rexursive.com>
Reviewed by: Justin & Ian

git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@97000 13f79535-47bb-0310-9956-ffa450edef68

CHANGES
docs/conf/httpd-std.conf.in
docs/conf/httpd-win.conf
docs/manual/mod/mod_log_config.html.en
docs/manual/mod/mod_log_config.xml
docs/manual/mod/mod_logio.xml [new file with mode: 0644]
modules/loggers/config.m4
modules/loggers/mod_logio.c [new file with mode: 0644]

diff --git a/CHANGES b/CHANGES
index 5d0bb2db05ef95084ac08a822d5000d51cfe48c1..46fdff9d8d50623c6aa128674d4d8774a5bf9977 100644 (file)
--- 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 <bojan@rexursive.com>]
+
   *) SuExec needs to use the same default directory as the rest of
      server, namely /usr/local/apache2.  
      [SangBeom han <sbhan@os.korea.ac.kr>]
index be7063cf702b56b7b40568d878147985482c6aa8..a055fdced801d53d3ce1c5fea64c4fb67910deae 100644 (file)
@@ -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 <VirtualHost>
index 09aeab5a68c1a52ae9f06d7f0b3c9a79a8a5a227..0f54df71e219058892f74cefc897ece9393fd419 100644 (file)
@@ -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 <VirtualHost>
index a35990ddf55317e7f0c607b602ce3446f4798bd5..e2184dd2466daa8067249322c9eac4cd7c1cd587 100644 (file)
@@ -138,6 +138,16 @@ be in strftime(3) format. (potentially localized)</td></tr>
 this conflicted with the historical ssl %...{var}c syntax.)</div>
 </td></tr>
 
+<tr><td>%...I:</td>          
+<td>Bytes received, including request and headers, cannot be zero. You need to
+enable <code class="module"><a
+href="../mod/mod_logio.html">mod_logio</a></code> to use this.</td></tr>
+
+<tr><td>%...O:</td>          
+<td>Bytes sent, including headers, cannot be zero. You need to enable <code
+class="module"><a href="../mod/mod_logio.html">mod_logio</a></code> to use
+this.</td></tr>
+
 </table>
 
     <p>The "..." can be nothing at all (<em>e.g.</em>, <code>"%h %u
@@ -352,4 +362,4 @@ host</td></tr><tr><th><a href="directive-dict.html#Status">Status:
    TransferLog logs/access_log
 </code></p></div>
 
-</div></div><div id="footer"><p class="apache">Maintained by the <a href="http://httpd.apache.org/docs-project/">Apache HTTP Server Documentation Project</a></p><p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="../faq/">FAQ</a> | <a href="../glossary.html">Glossary</a> | <a href="../sitemap.html">Sitemap</a></p></div></body></html>
\ No newline at end of file
+</div></div><div id="footer"><p class="apache">Maintained by the <a href="http://httpd.apache.org/docs-project/">Apache HTTP Server Documentation Project</a></p><p class="menu"><a href="../mod/">Modules</a> | <a href="../mod/directives.html">Directives</a> | <a href="../faq/">FAQ</a> | <a href="../glossary.html">Glossary</a> | <a href="../sitemap.html">Sitemap</a></p></div></body></html>
index 86fce8d575bd8575e67245a2a1b7d7eba2df6abe..b5412c0676e48b2cc5158e6f4f030587b187ff47 100644 (file)
@@ -143,6 +143,14 @@ be in strftime(3) format. (potentially localized)</td></tr>
 this conflicted with the historical ssl %...{var}c syntax.)</note>
 </td></tr>
 
+<tr><td>%...I:</td>
+<td>Bytes received, including request and headers, cannot be zero. You need to
+enable <module>mod_logio</module> to use this.</td></tr>
+
+<tr><td>%...O:</td>
+<td>Bytes sent, including headers, cannot be zero. You need to enable
+<module>mod_logio</module> to use this.</td></tr>
+
 </table>
 
     <p>The "..." can be nothing at all (<em>e.g.</em>, <code>"%h %u
diff --git a/docs/manual/mod/mod_logio.xml b/docs/manual/mod/mod_logio.xml
new file mode 100644 (file)
index 0000000..7d1d817
--- /dev/null
@@ -0,0 +1,57 @@
+<?xml version="1.0"?>
+<!DOCTYPE modulesynopsis SYSTEM "../style/modulesynopsis.dtd">
+<?xml-stylesheet type="text/xsl" href="../style/manual.en.xsl"?>
+<modulesynopsis>
+
+<name>mod_logio</name>
+<description>Logging of input and output bytes per request</description>
+<status>Base</status>
+<sourcefile>mod_logio.c</sourcefile>
+<identifier>logio_module</identifier>
+
+<summary>
+
+    <p>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.</p>
+
+    <p>This module requires <module>mod_log_config</module>.</p>
+
+</summary>
+
+<seealso><a href="../logs.html">Apache Log Files</a></seealso>
+
+<section id="formats">
+<title>Custom Log Formats</title>
+
+    <p>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:</p>
+
+<table>
+
+<tr><td>%...I:</td>
+<td>Bytes received, including request and headers, cannot be zero.</td></tr>
+
+<tr><td>%...O:</td>
+<td>Bytes sent, including headers, cannot be zero.</td></tr>
+
+</table>
+
+    <p>Usually, the functionality is used like this:</p>
+
+    <dl>
+
+      <dt>Combined I/O log format:</dt>
+
+      <dd><code>"%h %l %u %t \"%r\" %&gt;s %b \"%{Referer}i\"
+      \"%{User-agent}i\" %I %O"</code></dd>
+
+    </dl>
+
+</section>
+
+</modulesynopsis>
index 8d4304abc4dfa8d19623127e58853b393704bfe5..4e383cd30634b6134e083ae14a2dd3921c8600e4 100644 (file)
@@ -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 (file)
index 0000000..64c364d
--- /dev/null
@@ -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
+ * <http://www.apache.org/>.
+ *
+ * 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 <bojan@rexursive.com>:
+ *
+ * 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 */
+};