This is what I came up so far, but I've hit a problem along the way. No
matter what I do (or should I say, whatever I tried to do so far :-),
the number of input bytes is zero (HTTP/1.1) or not even calculated
(HTTP/1.0). The number of output bytes is correct, at least in my tests.
Could anyone point out what kind of silliness am I doing in the input
filter? I kind of understand what output filters do, but I'm still a bit
vague on input filters...

Thanks,
Bojan

PS. The patch for mod_log_config.c and config.m4 is against 2.0.40, but
it does work for the current CVS head as well, with some offset.
/* ====================================================================
 * 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 [EMAIL PROTECTED]
 *
 * 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/>.
 *
 */

/*
 * mod_logio.c: Record input/output traffic in bytes, per request
 *
 * Written by Bojan Smojver ([EMAIL PROTECTED])
 *
 */

#include "httpd.h"
#include "http_config.h"
#include "http_log.h"
#include "apr_strings.h"
#include "apr_general.h"
#include "util_filter.h"
#include "apr_buckets.h"
#include "http_request.h"
#define APR_WANT_STRFUNC
#include "apr_want.h"

static const char logioFilterName[] = "LOGIO";
module AP_MODULE_DECLARE_DATA logio_module;

typedef struct logio_ctx_t {
    apr_off_t length;
} logio_ctx;

static apr_status_t logio_out_filter(ap_filter_t *f, apr_bucket_brigade *bb) {
    request_rec *r = f->r;

    if (!r->main) {
        apr_off_t length;
        logio_ctx *ctx = f->ctx;

        if (!ctx) {
            ctx = f->ctx = apr_pcalloc(r->pool, sizeof(*ctx));
            ctx->length = 0;
        }

        apr_brigade_length (bb, 0, &length);

        if (length > 0)
            ctx->length += length;

        apr_table_setn(r->notes, "mod_logio_output_bytes",
                       apr_ltoa(r->pool,ctx->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) {
    request_rec *r = f->r;
    apr_status_t status;

    status = ap_get_brigade(f->next, bb, mode, block, readbytes);

    if (!r->main) {
        apr_off_t length;
        logio_ctx *ctx = f->ctx;

        if (!ctx) {
            ctx = f->ctx = apr_pcalloc(r->pool, sizeof(*ctx));
            ctx->length = 0;
        }

        apr_brigade_length (bb, 0, &length);

        if (length > 0)
            ctx->length += length;

        apr_table_setn(r->notes, "mod_logio_input_bytes",
                       apr_ltoa(r->pool,ctx->length));
    }

    return status;
}

static void register_hooks(apr_pool_t *p) {
    ap_register_output_filter(logioFilterName, logio_out_filter, NULL,
                              AP_FTYPE_TRANSCODE);
    ap_register_input_filter(logioFilterName, logio_in_filter, NULL,
                              AP_FTYPE_TRANSCODE);
}

static const command_rec logio_filter_cmds[] = {
    { NULL }
};

module AP_MODULE_DECLARE_DATA logio_module = {
    STANDARD20_MODULE_STUFF,
    NULL,                         /* dir config creater */
    NULL,                         /* dir merger --- default is to override */
    NULL,                         /* server config */
    NULL,                         /* merge server config */
    logio_filter_cmds,            /* command table */
    register_hooks                /* register hooks */
};
--- httpd-2.0.40/modules/loggers/mod_log_config.c       Thu Jul 18 02:08:53 2002
+++ /usr/src/httpd/modules/loggers/mod_log_config.c     Fri Sep 13 08:48:02 2002
@@ -153,9 +153,11 @@
  *         '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.)
-*
+ *         (This directive was %...c in late versions of Apache 1.3, but
+ *         this conflicted with the historical ssl %...{var}c syntax.)
+ * %...I:  bytes received, including request and headers, cannot be zero
+ * %...O:  bytes sent, including headers, cannot be zero
+ *
  * 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
@@ -594,6 +596,20 @@
     return "-";
 }
 
+static const char *log_bytes_recv_all(request_rec *r, char *a)
+{
+    const char *length = apr_table_get(r->notes, "mod_logio_input_bytes");
+
+    return length ? length : "-";
+}
+
+static const char *log_bytes_sent_all(request_rec *r, char *a)
+{
+    const char *length = apr_table_get(r->notes, "mod_logio_output_bytes");
+
+    return length ? length : "-";
+}
+
 /*****************************************************************
  *
  * Parsing the log format string
@@ -1272,6 +1288,8 @@
         log_pfn_register(p, "T", log_request_duration, 1);
         log_pfn_register(p, "U", log_request_uri, 1);
         log_pfn_register(p, "s", log_status, 1);
+        log_pfn_register(p, "I", log_bytes_recv_all, 0);
+        log_pfn_register(p, "O", log_bytes_sent_all, 0);
     }
 
     return OK;
--- httpd-2.0.40/modules/filters/config.m4      Tue May  7 08:23:52 2002
+++ /usr/src/httpd/modules/filters/config.m4    Fri Sep 13 08:23:52 2002
@@ -6,6 +6,8 @@
 
 APACHE_MODULE(include, Server Side Includes, , , yes)
 
+APACHE_MODULE(logio, Log Input/Output, , , no)
+
 APR_ADDTO(LT_LDFLAGS,-export-dynamic)
 
 APACHE_MODULE(deflate, Deflate transfer encoding support, , , no, [

Reply via email to