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, [