httpd-cvs mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From s.@apache.org
Subject svn commit: r1418767 - in /httpd/httpd/trunk: CHANGES docs/manual/mod/core.xml include/ap_mmn.h include/http_core.h server/core.c server/request.c
Date Sat, 08 Dec 2012 22:16:33 GMT
Author: sf
Date: Sat Dec  8 22:16:31 2012
New Revision: 1418767

URL: http://svn.apache.org/viewvc?rev=1418767&view=rev
Log:
Add LogLevelOverride directive that allows to override the loglevel for
clients from certain IPs

Modified:
    httpd/httpd/trunk/CHANGES
    httpd/httpd/trunk/docs/manual/mod/core.xml
    httpd/httpd/trunk/include/ap_mmn.h
    httpd/httpd/trunk/include/http_core.h
    httpd/httpd/trunk/server/core.c
    httpd/httpd/trunk/server/request.c

Modified: httpd/httpd/trunk/CHANGES
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/CHANGES?rev=1418767&r1=1418766&r2=1418767&view=diff
==============================================================================
--- httpd/httpd/trunk/CHANGES [utf-8] (original)
+++ httpd/httpd/trunk/CHANGES [utf-8] Sat Dec  8 22:16:31 2012
@@ -1,6 +1,11 @@
                                                          -*- coding: utf-8 -*-
 Changes with Apache 2.5.0
 
+  *) core: Add LogLevelOverride directive that allows to override the
+     loglevel for clients from certain IPs. This also works for things
+     like the SSL handshake where <If> LogLevel ... </If> is evaluated
+     too late. [Stefan Fritsch]
+
   *) mod_status: Print out list of times since a Vhost was last used.
      [Jim Jagielski]
 

Modified: httpd/httpd/trunk/docs/manual/mod/core.xml
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/docs/manual/mod/core.xml?rev=1418767&r1=1418766&r2=1418767&view=diff
==============================================================================
--- httpd/httpd/trunk/docs/manual/mod/core.xml (original)
+++ httpd/httpd/trunk/docs/manual/mod/core.xml Sat Dec  8 22:16:31 2012
@@ -2893,11 +2893,65 @@ LogLevel info
 
     <note>
         Per directory loglevel configuration only affects messages that are
-	logged after the request has been parsed and that are associated with
-	the request. Log messages which are associated with the connection or
-	the server are not affected.
+        logged after the request has been parsed and that are associated with
+        the request. Log messages which are associated with the server or
+        the connection are not affected. The latter can be influenced by the
+        <directive module="core">LogLevelOverride</directive> directive,
+        though.
     </note>
 </usage>
+<seealso><directive module="core">ErrorLog</directive></seealso>
+<seealso><directive module="core">ErrorLogFormat</directive></seealso>
+<seealso><directive module="core">LogLevelOverride</directive></seealso>
+</directivesynopsis>
+
+<directivesynopsis>
+<name>LogLevelOverride</name>
+<description>Override the verbosity of the ErrorLog for certain clients</description>
+<syntax>LogLevel <var>ipaddress</var>[/<var>prefixlen</var>]
+    [<var>module</var>:]<var>level</var> [<var>module</var>:<var>level</var>]
...
+</syntax>
+<default>unset</default>
+<contextlist><context>server config</context><context>virtual host</context>
+</contextlist>
+<compatibility>Available in Apache HTTP Server 2.5.0 and later</compatibility>
+
+<usage>
+    <p><directive>LogLevelOverride</directive> adjusts the
+    <directive module="core">LogLevel</directive> for requests coming from
+    certain client IP addresses.
+    This allows to enable verbose logging only for certain test clients.
+    The IP address is checked at a very early state in the connection
+    processing.  Therefore, <directive>LogLevelOverride</directive> allows to
+    change the log level for things like the SSL handshake which happen before
+    a <directive module="core">LogLevel</directive> directive in an
+    <directive type="section" module="core">If</directive> container would
+    be evaluated.</p>
+
+    <p><directive>LogLevelOverride</directive> accepts either a single
+    IP-address or a CIDR IP-address/len subnet specification.
+    For the syntax of the loglevel specification, see the
+    <directive module="core">LogLevel</directive> directive.</p>
+
+    <p>For requests that match a <directive>LogLevelOverride</directive>
+    directive, per-directory specifications of
+    <directive module="core">LogLevel</directive> are ignored.</p>
+
+    <p>Examples:</p>
+
+    <highlight language="config">
+        LogLevelOverride 192.0.2.0/24 ssl:trace6
+        LogLevelOverride 192.0.2.7 ssl:trace8
+    </highlight>
+
+    <note>
+        <directive module="core">LogLevelOverride</directive> only affects
+        log messages that are associated with the request or the connection.
+        Log messages which are associated with the server not affected.
+    </note>
+
+</usage>
+<seealso><directive module="core">LogLevel</directive></seealso>
 </directivesynopsis>
 
 <directivesynopsis>

Modified: httpd/httpd/trunk/include/ap_mmn.h
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/include/ap_mmn.h?rev=1418767&r1=1418766&r2=1418767&view=diff
==============================================================================
--- httpd/httpd/trunk/include/ap_mmn.h (original)
+++ httpd/httpd/trunk/include/ap_mmn.h Sat Dec  8 22:16:31 2012
@@ -406,6 +406,7 @@
  * 20120724.6 (2.5.0-dev)  Add sticky_separator to proxy_balancer_shared struct.
  * 20120724.7 (2.5.0-dev)  Add min_http_version/max_http_version to
  *                         core_server_config
+ * 20120724.8 (2.5.0-dev)  Add conn_log_level to core_server_config
  */
 
 #define MODULE_MAGIC_COOKIE 0x41503235UL /* "AP25" */
@@ -413,7 +414,7 @@
 #ifndef MODULE_MAGIC_NUMBER_MAJOR
 #define MODULE_MAGIC_NUMBER_MAJOR 20120724
 #endif
-#define MODULE_MAGIC_NUMBER_MINOR 7                   /* 0...n */
+#define MODULE_MAGIC_NUMBER_MINOR 8                   /* 0...n */
 
 /**
  * Determine if the server's current MODULE_MAGIC_NUMBER is at least a

Modified: httpd/httpd/trunk/include/http_core.h
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/include/http_core.h?rev=1418767&r1=1418766&r2=1418767&view=diff
==============================================================================
--- httpd/httpd/trunk/include/http_core.h (original)
+++ httpd/httpd/trunk/include/http_core.h Sat Dec  8 22:16:31 2012
@@ -668,6 +668,8 @@ typedef struct {
     apr_uint16_t min_http_version;
     apr_uint16_t max_http_version;
 
+    apr_array_header_t *conn_log_level;
+
 } core_server_config;
 
 /* for AddOutputFiltersByType in core.c */

Modified: httpd/httpd/trunk/server/core.c
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/server/core.c?rev=1418767&r1=1418766&r2=1418767&view=diff
==============================================================================
--- httpd/httpd/trunk/server/core.c (original)
+++ httpd/httpd/trunk/server/core.c Sat Dec  8 22:16:31 2012
@@ -128,6 +128,11 @@ AP_DECLARE_DATA int ap_main_state = AP_S
 AP_DECLARE_DATA int ap_run_mode = AP_SQ_RM_UNKNOWN;
 AP_DECLARE_DATA int ap_config_generation = 0;
 
+typedef struct {
+    apr_ipsubnet_t *subnet;
+    struct ap_logconf log;
+} conn_log_config;
+
 static void *create_core_dir_config(apr_pool_t *a, char *dir)
 {
     core_dir_config *conf;
@@ -524,6 +529,17 @@ static void *merge_core_server_configs(a
     if (virt->error_log_req)
         conf->error_log_req = virt->error_log_req;
 
+    if (virt->conn_log_level) {
+        if (!conf->conn_log_level) {
+            conf->conn_log_level = virt->conn_log_level;
+        }
+        else {
+            /* apr_array_append actually creates a new array */
+            conf->conn_log_level = apr_array_append(p, conf->conn_log_level,
+                                                    virt->conn_log_level);
+        }
+    }
+
     return conf;
 }
 
@@ -3032,30 +3048,14 @@ static const char *include_config (cmd_p
     return NULL;
 }
 
-static const char *set_loglevel(cmd_parms *cmd, void *config_, const char *arg_)
+static const char *update_loglevel(cmd_parms *cmd, struct ap_logconf *log,
+                                   const char *arg)
 {
-    char *level_str;
-    int level;
+    const char *level_str, *err;
     module *module;
-    char *arg = apr_pstrdup(cmd->temp_pool, arg_);
-    struct ap_logconf *log;
-    const char *err;
-
-    if (cmd->path) {
-        core_dir_config *dconf = config_;
-        if (!dconf->log) {
-            dconf->log = ap_new_log_config(cmd->pool, NULL);
-        }
-        log = dconf->log;
-    }
-    else {
-        log = &cmd->server->log;
-    }
-
-    if (arg == NULL)
-        return "LogLevel requires level keyword or module loglevel specifier";
+    int level;
 
-    level_str = ap_strrchr(arg, ':');
+    level_str = ap_strrchr_c(arg, ':');
 
     if (level_str == NULL) {
         err = ap_parse_log_level(arg, &log->level);
@@ -3063,11 +3063,12 @@ static const char *set_loglevel(cmd_parm
             return err;
         ap_reset_module_loglevels(log, APLOG_NO_MODULE);
         ap_log_error(APLOG_MARK, APLOG_TRACE3, 0, cmd->server,
-                     "Setting LogLevel for all modules to %s", arg);
+                     "Setting %s for all modules to %s", cmd->cmd->name, arg);
         return NULL;
     }
 
-    *level_str++ = '\0';
+    arg = apr_pstrmemdup(cmd->temp_pool, arg, level_str - arg);
+    level_str++;
     if (!*level_str) {
         return apr_psprintf(cmd->temp_pool, "Module specifier '%s' must be "
                             "followed by a log level keyword", arg);
@@ -3090,9 +3091,64 @@ static const char *set_loglevel(cmd_parm
 
     ap_set_module_loglevel(cmd->pool, log, module->module_index, level);
     ap_log_error(APLOG_MARK, APLOG_TRACE3, 0, cmd->server,
-                 "Setting LogLevel for module %s to %s", module->name,
-                 level_str);
+                 "Setting %s for module %s to %s", cmd->cmd->name,
+                 module->name, level_str);
+
+    return NULL;
+}
 
+static const char *set_loglevel(cmd_parms *cmd, void *config_, const char *arg)
+{
+    struct ap_logconf *log;
+
+    if (cmd->path) {
+        core_dir_config *dconf = config_;
+        if (!dconf->log) {
+            dconf->log = ap_new_log_config(cmd->pool, NULL);
+        }
+        log = dconf->log;
+    }
+    else {
+        log = &cmd->server->log;
+    }
+
+    if (arg == NULL)
+        return "LogLevel requires level keyword or module loglevel specifier";
+
+    return update_loglevel(cmd, log, arg);
+}
+
+static const char *set_loglevel_override(cmd_parms *cmd, void *d_, int argc,
+                                         char *const argv[])
+{
+    core_server_config *sconf;
+    conn_log_config *entry;
+    int ret, i;
+    const char *addr, *mask, *err;
+
+    if (argc < 2)
+        return "LogLevelOverride requires at least two arguments";
+
+    entry = apr_pcalloc(cmd->pool, sizeof(conn_log_config));
+    sconf = ap_get_core_module_config(cmd->server->module_config);
+    if (!sconf->conn_log_level)
+        sconf->conn_log_level = apr_array_make(cmd->pool, 4, sizeof(entry));
+    APR_ARRAY_PUSH(sconf->conn_log_level, conn_log_config *) = entry;
+
+    addr = argv[0];
+    mask = ap_strchr_c(addr, '/');
+    if (mask) {
+        addr = apr_pstrmemdup(cmd->temp_pool, addr, mask - addr);
+        mask++;
+    }
+    ret = apr_ipsubnet_create(&entry->subnet, addr, mask, cmd->pool);
+    if (ret != APR_SUCCESS)
+        return "parsing of subnet/netmask failed";
+
+    for (i = 1; i < argc; i++) {
+        if ((err = update_loglevel(cmd, &entry->log, argv[i])) != NULL)
+            return err;
+    }
     return NULL;
 }
 
@@ -4089,6 +4145,8 @@ AP_INIT_TAKE1("IncludeOptional", include
   "does not exist or the pattern does not match any files"),
 AP_INIT_ITERATE("LogLevel", set_loglevel, NULL, RSRC_CONF|ACCESS_CONF,
   "Level of verbosity in error logging"),
+AP_INIT_TAKE_ARGV("LogLevelOverride", set_loglevel_override, NULL, RSRC_CONF,
+  "Override LogLevel for clients with certain IPs"),
 AP_INIT_TAKE1("NameVirtualHost", ap_set_name_virtual_host, NULL, RSRC_CONF,
   "A numeric IP address:port, or the name of a host"),
 AP_INIT_TAKE12("ServerTokens", set_serv_tokens, NULL, RSRC_CONF,
@@ -4661,12 +4719,13 @@ static int core_create_proxy_req(request
     return core_create_req(pr);
 }
 
-static conn_rec *core_create_conn(apr_pool_t *ptrans, server_rec *server,
+static conn_rec *core_create_conn(apr_pool_t *ptrans, server_rec *s,
                                   apr_socket_t *csd, long id, void *sbh,
                                   apr_bucket_alloc_t *alloc)
 {
     apr_status_t rv;
     conn_rec *c = (conn_rec *) apr_pcalloc(ptrans, sizeof(conn_rec));
+    core_server_config *sconf = ap_get_core_module_config(s->module_config);
 
     c->sbh = sbh;
     (void)ap_update_child_status(c->sbh, SERVER_BUSY_READ, (request_rec *)NULL);
@@ -4680,7 +4739,7 @@ static conn_rec *core_create_conn(apr_po
     c->pool = ptrans;
     if ((rv = apr_socket_addr_get(&c->local_addr, APR_LOCAL, csd))
         != APR_SUCCESS) {
-        ap_log_error(APLOG_MARK, APLOG_INFO, rv, server, APLOGNO(00137)
+        ap_log_error(APLOG_MARK, APLOG_INFO, rv, s, APLOGNO(00137)
                      "apr_socket_addr_get(APR_LOCAL)");
         apr_socket_close(csd);
         return NULL;
@@ -4689,20 +4748,38 @@ static conn_rec *core_create_conn(apr_po
     apr_sockaddr_ip_get(&c->local_ip, c->local_addr);
     if ((rv = apr_socket_addr_get(&c->client_addr, APR_REMOTE, csd))
         != APR_SUCCESS) {
-        ap_log_error(APLOG_MARK, APLOG_INFO, rv, server, APLOGNO(00138)
+        ap_log_error(APLOG_MARK, APLOG_INFO, rv, s, APLOGNO(00138)
                      "apr_socket_addr_get(APR_REMOTE)");
         apr_socket_close(csd);
         return NULL;
     }
 
     apr_sockaddr_ip_get(&c->client_ip, c->client_addr);
-    c->base_server = server;
+    c->base_server = s;
 
     c->id = id;
     c->bucket_alloc = alloc;
 
     c->clogging_input_filters = 0;
 
+    if (sconf->conn_log_level) {
+        int i;
+        conn_log_config *conf;
+        const struct ap_logconf *log = NULL;
+        struct ap_logconf *merged;
+
+        for (i = 0; i < sconf->conn_log_level->nelts; i++) {
+            conf = APR_ARRAY_IDX(sconf->conn_log_level, i, conn_log_config *);
+            if (apr_ipsubnet_test(conf->subnet, c->client_addr))
+                log = &conf->log;
+        }
+        if (log) {
+            merged = ap_new_log_config(c->pool, log);
+            ap_merge_log_config(&s->log, merged);
+            c->log = merged;
+        }
+    }
+
     return c;
 }
 

Modified: httpd/httpd/trunk/server/request.c
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/server/request.c?rev=1418767&r1=1418766&r2=1418767&view=diff
==============================================================================
--- httpd/httpd/trunk/server/request.c (original)
+++ httpd/httpd/trunk/server/request.c Sat Dec  8 22:16:31 2012
@@ -165,9 +165,11 @@ AP_DECLARE(int) ap_process_request_inter
             return access_status;
         }
 
-        d = ap_get_core_module_config(r->per_dir_config);
-        if (d->log) {
-            r->log = d->log;
+        /* Don't set per-dir loglevel if LogLevelOverride is set */
+        if (!r->connection->log) {
+            d = ap_get_core_module_config(r->per_dir_config);
+            if (d->log)
+                r->log = d->log;
         }
 
         if ((access_status = ap_run_translate_name(r))) {
@@ -193,9 +195,11 @@ AP_DECLARE(int) ap_process_request_inter
         return access_status;
     }
 
-    d = ap_get_core_module_config(r->per_dir_config);
-    if (d->log) {
-        r->log = d->log;
+    /* Don't set per-dir loglevel if LogLevelOverride is set */
+    if (!r->connection->log) {
+        d = ap_get_core_module_config(r->per_dir_config);
+        if (d->log)
+            r->log = d->log;
     }
 
     if ((access_status = ap_run_post_perdir_config(r))) {



Mime
View raw message