mod_logio.c revision 96513497f07d88471172e7b0ee3a61cd31a3baa2
1ff28eaee33d9d0cee46bd176b6d6f8805c95036Tom Gundersen/* Copyright 2002-2005 The Apache Software Foundation or its licensors, as
1ff28eaee33d9d0cee46bd176b6d6f8805c95036Tom Gundersen * applicable.
12b42c76672a66c2d4ea7212c14f8f1b5a62b78dTom Gundersen *
1ff28eaee33d9d0cee46bd176b6d6f8805c95036Tom Gundersen * Licensed under the Apache License, Version 2.0 (the "License");
1ff28eaee33d9d0cee46bd176b6d6f8805c95036Tom Gundersen * you may not use this file except in compliance with the License.
1ff28eaee33d9d0cee46bd176b6d6f8805c95036Tom Gundersen * You may obtain a copy of the License at
1ff28eaee33d9d0cee46bd176b6d6f8805c95036Tom Gundersen *
1ff28eaee33d9d0cee46bd176b6d6f8805c95036Tom Gundersen * http://www.apache.org/licenses/LICENSE-2.0
1ff28eaee33d9d0cee46bd176b6d6f8805c95036Tom Gundersen *
1ff28eaee33d9d0cee46bd176b6d6f8805c95036Tom Gundersen * Unless required by applicable law or agreed to in writing, software
1ff28eaee33d9d0cee46bd176b6d6f8805c95036Tom Gundersen * distributed under the License is distributed on an "AS IS" BASIS,
1ff28eaee33d9d0cee46bd176b6d6f8805c95036Tom Gundersen * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1ff28eaee33d9d0cee46bd176b6d6f8805c95036Tom Gundersen * See the License for the specific language governing permissions and
1ff28eaee33d9d0cee46bd176b6d6f8805c95036Tom Gundersen * limitations under the License.
1ff28eaee33d9d0cee46bd176b6d6f8805c95036Tom Gundersen */
1ff28eaee33d9d0cee46bd176b6d6f8805c95036Tom Gundersen
1ff28eaee33d9d0cee46bd176b6d6f8805c95036Tom Gundersen/*
1ff28eaee33d9d0cee46bd176b6d6f8805c95036Tom Gundersen * Written by Bojan Smojver <bojan rexursive.com>:
1ff28eaee33d9d0cee46bd176b6d6f8805c95036Tom Gundersen *
1ff28eaee33d9d0cee46bd176b6d6f8805c95036Tom Gundersen * The argument to LogFormat and CustomLog is a string, which can include
1ff28eaee33d9d0cee46bd176b6d6f8805c95036Tom Gundersen * literal characters copied into the log files, and '%' directives as
1ff28eaee33d9d0cee46bd176b6d6f8805c95036Tom Gundersen * follows:
1ff28eaee33d9d0cee46bd176b6d6f8805c95036Tom Gundersen *
1ff28eaee33d9d0cee46bd176b6d6f8805c95036Tom Gundersen * %...I: bytes received, including request and headers, cannot be zero
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek * %...O: bytes sent, including headers, cannot be zero
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek *
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek */
1ff28eaee33d9d0cee46bd176b6d6f8805c95036Tom Gundersen
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek#include "apr_strings.h"
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek#include "apr_lib.h"
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek#include "apr_hash.h"
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek#include "apr_optional.h"
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek#define APR_WANT_STRFUNC
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek#include "apr_want.h"
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
1ff28eaee33d9d0cee46bd176b6d6f8805c95036Tom Gundersen#include "ap_config.h"
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek#include "mod_log_config.h"
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek#include "httpd.h"
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek#include "http_core.h"
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek#include "http_config.h"
1ff28eaee33d9d0cee46bd176b6d6f8805c95036Tom Gundersen#include "http_connection.h"
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek#include "http_protocol.h"
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmekmodule AP_MODULE_DECLARE_DATA logio_module;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
1ff28eaee33d9d0cee46bd176b6d6f8805c95036Tom Gundersenstatic const char logio_filter_name[] = "LOG_INPUT_OUTPUT";
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek/*
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek * Logging of input and output config...
1ff28eaee33d9d0cee46bd176b6d6f8805c95036Tom Gundersen */
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmektypedef struct logio_config_t {
1ff28eaee33d9d0cee46bd176b6d6f8805c95036Tom Gundersen apr_off_t bytes_in;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek apr_off_t bytes_out;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek} logio_config_t;
1ff28eaee33d9d0cee46bd176b6d6f8805c95036Tom Gundersen
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek/*
12b42c76672a66c2d4ea7212c14f8f1b5a62b78dTom Gundersen * Optional function for the core to add to bytes_out
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek */
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmekstatic void ap_logio_add_bytes_out(conn_rec *c, apr_off_t bytes){
12b42c76672a66c2d4ea7212c14f8f1b5a62b78dTom Gundersen logio_config_t *cf = ap_get_module_config(c->conn_config, &logio_module);
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek cf->bytes_out += bytes;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek}
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek/*
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek * Format items...
12b42c76672a66c2d4ea7212c14f8f1b5a62b78dTom Gundersen */
57e27ec0ada6775d85a5201cd25e989d92d0a1afZbigniew Jędrzejewski-Szmek
57e27ec0ada6775d85a5201cd25e989d92d0a1afZbigniew Jędrzejewski-Szmekstatic const char *log_bytes_in(request_rec *r, char *a)
57e27ec0ada6775d85a5201cd25e989d92d0a1afZbigniew Jędrzejewski-Szmek{
57e27ec0ada6775d85a5201cd25e989d92d0a1afZbigniew Jędrzejewski-Szmek logio_config_t *cf = ap_get_module_config(r->connection->conn_config,
1ff28eaee33d9d0cee46bd176b6d6f8805c95036Tom Gundersen &logio_module);
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek return apr_off_t_toa(r->pool, cf->bytes_in);
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek}
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmekstatic const char *log_bytes_out(request_rec *r, char *a)
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek{
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek logio_config_t *cf = ap_get_module_config(r->connection->conn_config,
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek &logio_module);
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek return apr_off_t_toa(r->pool, cf->bytes_out);
102bd40e1ed71c7ab980a90435a1c23d4c786c63Lennart Poettering}
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek/*
1ff28eaee33d9d0cee46bd176b6d6f8805c95036Tom Gundersen * Reset counters after logging...
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek */
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmekstatic int logio_transaction(request_rec *r)
1ff28eaee33d9d0cee46bd176b6d6f8805c95036Tom Gundersen{
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek logio_config_t *cf = ap_get_module_config(r->connection->conn_config,
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek &logio_module);
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek cf->bytes_in = cf->bytes_out = 0;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek return OK;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek}
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek/*
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek * Logging of input filter...
5256e00e8b9015dd1a976d647fc71dc7efbd8cf8Tom Gundersen */
5256e00e8b9015dd1a976d647fc71dc7efbd8cf8Tom Gundersen
5256e00e8b9015dd1a976d647fc71dc7efbd8cf8Tom Gundersenstatic apr_status_t logio_in_filter(ap_filter_t *f,
5256e00e8b9015dd1a976d647fc71dc7efbd8cf8Tom Gundersen apr_bucket_brigade *bb,
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek ap_input_mode_t mode,
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek apr_read_type_e block,
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek apr_off_t readbytes) {
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek apr_off_t length;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek apr_status_t status;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek logio_config_t *cf = ap_get_module_config(f->c->conn_config, &logio_module);
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
5256e00e8b9015dd1a976d647fc71dc7efbd8cf8Tom Gundersen status = ap_get_brigade(f->next, bb, mode, block, readbytes);
5256e00e8b9015dd1a976d647fc71dc7efbd8cf8Tom Gundersen
5256e00e8b9015dd1a976d647fc71dc7efbd8cf8Tom Gundersen apr_brigade_length (bb, 0, &length);
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek if (length > 0)
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek cf->bytes_in += length;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek return status;
5256e00e8b9015dd1a976d647fc71dc7efbd8cf8Tom Gundersen}
5256e00e8b9015dd1a976d647fc71dc7efbd8cf8Tom Gundersen
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek/*
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek * The hooks...
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek */
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmekstatic int logio_pre_conn(conn_rec *c, void *csd) {
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek logio_config_t *cf = apr_pcalloc(c->pool, sizeof(*cf));
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek ap_set_module_config(c->conn_config, &logio_module, cf);
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
5256e00e8b9015dd1a976d647fc71dc7efbd8cf8Tom Gundersen ap_add_input_filter(logio_filter_name, NULL, NULL, c);
5256e00e8b9015dd1a976d647fc71dc7efbd8cf8Tom Gundersen
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek return OK;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek}
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmekstatic int logio_pre_config(apr_pool_t *p, apr_pool_t *plog, apr_pool_t *ptemp)
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek{
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek static APR_OPTIONAL_FN_TYPE(ap_register_log_handler) *log_pfn_register;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek log_pfn_register = APR_RETRIEVE_OPTIONAL_FN(ap_register_log_handler);
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek if (log_pfn_register) {
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek log_pfn_register(p, "I", log_bytes_in, 0);
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek log_pfn_register(p, "O", log_bytes_out, 0);
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek }
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek return OK;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek}
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmekstatic void register_hooks(apr_pool_t *p)
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek{
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek static const char *pre[] = { "mod_log_config.c", NULL };
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek ap_hook_pre_connection(logio_pre_conn, NULL, NULL, APR_HOOK_MIDDLE);
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek ap_hook_pre_config(logio_pre_config, NULL, NULL, APR_HOOK_REALLY_FIRST);
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek ap_hook_log_transaction(logio_transaction, pre, NULL, APR_HOOK_MIDDLE);
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek ap_register_input_filter(logio_filter_name, logio_in_filter, NULL,
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek AP_FTYPE_NETWORK - 1);
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek APR_REGISTER_OPTIONAL_FN(ap_logio_add_bytes_out);
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek}
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmekmodule AP_MODULE_DECLARE_DATA logio_module =
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek{
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek STANDARD20_MODULE_STUFF,
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek NULL, /* create per-dir config */
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek NULL, /* merge per-dir config */
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek NULL, /* server config */
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek NULL, /* merge server config */
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek NULL, /* command apr_table_t */
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek register_hooks /* register hooks */
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek};
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek