]> granicus.if.org Git - apache/commitdiff
- Introduce log levels trace1/.../trace8
authorStefan Fritsch <sf@apache.org>
Sun, 6 Jun 2010 16:54:51 +0000 (16:54 +0000)
committerStefan Fritsch <sf@apache.org>
Sun, 6 Jun 2010 16:54:51 +0000 (16:54 +0000)
- Add macro wrappers for ap_log_*error. On C99, this will save argument
  preparation and function call overhead when a message is not logged
  because of the configured loglevel.
- Introduce per-module loglevel configuration.

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

configure.in
include/ap_mmn.h
include/http_config.h
include/http_log.h
include/httpd.h
server/config.c
server/core.c
server/log.c
server/util_debug.c

index 4501857bb2e1124ced180121a00b51ffb740a21b..9ee5b5b58b0f0418300b1d805687740ef8a9da64 100644 (file)
@@ -170,6 +170,9 @@ dnl PCRE and for our config tests will be whatever PCRE determines.
 AC_PROG_CC
 AC_PROG_CPP
 
+dnl Try to get c99 support for variadic macros
+AC_PROG_CC_C99
+
 if test "x${cache_file}" = "x/dev/null"; then
   # Likewise, ensure that CC and CPP are passed through to the pcre
   # configure script iff caching is disabled (the autoconf 2.5x default).
index ac40e9def1854f84fe99a19d397344fb49d05c97..e708bc3c07472c4f331fda722f2b1d601a715852 100644 (file)
  * 20100223.1 (2.3.6-dev)  Added ap_process_fnmatch_configs().
  * 20100504.0 (2.3.6-dev)  Added name arg to ap_{proc,global}_mutex_create().
  * 20100604.0 (2.3.6-dev)  Remove unused core_dir_config::loglevel
+ * 20100606.0 (2.3.6-dev)  Make ap_log_*error macro wrappers around
+ *                         ap_log_*error_ to save argument preparation and
+ *                         function call overhead.
+ *                         Introduce per-module loglevels
+ *
  */
 
 #define MODULE_MAGIC_COOKIE 0x41503234UL /* "AP24" */
 
 #ifndef MODULE_MAGIC_NUMBER_MAJOR
-#define MODULE_MAGIC_NUMBER_MAJOR 20100604
+#define MODULE_MAGIC_NUMBER_MAJOR 20100606
 #endif
 #define MODULE_MAGIC_NUMBER_MINOR 0                     /* 0...n */
 
index 33a3e54a62c3f0234253203b89a260f43fc0595e..c5bbd482984182bf378607324bcb3626213844df 100644 (file)
@@ -28,6 +28,7 @@
 
 #include "apr_hooks.h"
 #include "util_cfgtree.h"
+#include "ap_config.h"
 
 #ifdef __cplusplus
 extern "C" {
@@ -394,6 +395,17 @@ struct module_struct {
     void (*register_hooks) (apr_pool_t *p);
 };
 
+/*
+ * Macro to choose which module a file belongs to, for logging.
+ */
+#define APLOG_USE_MODULE(foo) \
+    extern module AP_MODULE_DECLARE_DATA foo##_module;                  \
+    static int * const aplog_module_index = &(foo##_module.module_index)
+
+#define AP_DECLARE_MODULE(foo) \
+    APLOG_USE_MODULE(foo);                         \
+    module AP_MODULE_DECLARE_DATA foo##_module
+
 /**
  * @defgroup ModuleInit Module structure initializers
  *
@@ -469,6 +481,44 @@ AP_DECLARE(void) ap_set_module_config(ap_conf_vector_t *cv, const module *m,
 #endif /* AP_DEBUG */
 
 
+/**
+ * Generic accessor for modules to get the module-specific loglevel
+ * @param s The server from which to get the loglevel.
+ * @param index The module_index of the module to get the loglevel for.
+ * @return The module-specific loglevel
+ */
+AP_DECLARE(int) ap_get_module_loglevel(const server_rec *s, int index);
+
+/**
+ * Accessor to set module-specific loglevel
+ * @param p A pool
+ * @param s The server for which to set the loglevel.
+ * @param index The module_index of the module to set the loglevel for.
+ * @param level The new log level
+ * @return The module-specific loglevel
+ */
+AP_DECLARE(void) ap_set_module_loglevel(apr_pool_t *p, server_rec *s,
+                                        int index, int level);
+
+#if !defined(AP_DEBUG)
+
+#define ap_get_module_loglevel(s,i)            \
+    (i < 0 || (s)->module_loglevels == NULL || (((s)->module_loglevels)[i]) < 0 ?   \
+     (s)->loglevel :                            \
+     ((s)->module_loglevels)[i])
+
+#endif /* AP_DEBUG */
+
+/**
+ * Reset all module-specific loglevels to server default
+ * @param p A pool
+ * @param s The server for which to set the loglevel.
+ * @param index The module_index of the module to set the loglevel for.
+ * @param level The new log level
+ * @return The module-specific loglevel
+ */
+AP_DECLARE(void) ap_reset_module_loglevels(server_rec *s);
+
 /**
  * Generic command handling function for strings
  * @param cmd The command parameters for this directive
index 80e8b9fa679ac68aef3e2f70d2899dad157036ba..183be0aa8eecf1e7e67d8b78017eae4dfb24cf74 100644 (file)
@@ -35,33 +35,51 @@ extern "C" {
 #ifdef HAVE_SYSLOG
 #include <syslog.h>
 
+#include "http_config.h"
+
 #ifndef LOG_PRIMASK
 #define LOG_PRIMASK 7
 #endif
 
-#define APLOG_EMERG     LOG_EMERG     /* system is unusable */
-#define APLOG_ALERT     LOG_ALERT     /* action must be taken immediately */
-#define APLOG_CRIT      LOG_CRIT      /* critical conditions */
-#define APLOG_ERR       LOG_ERR       /* error conditions */
-#define APLOG_WARNING   LOG_WARNING   /* warning conditions */
-#define APLOG_NOTICE    LOG_NOTICE    /* normal but significant condition */
-#define APLOG_INFO      LOG_INFO      /* informational */
-#define APLOG_DEBUG     LOG_DEBUG     /* debug-level messages */
-
-#define APLOG_LEVELMASK LOG_PRIMASK   /* mask off the level value */
+#define APLOG_EMERG     LOG_EMERG       /* system is unusable */
+#define APLOG_ALERT     LOG_ALERT       /* action must be taken immediately */
+#define APLOG_CRIT      LOG_CRIT        /* critical conditions */
+#define APLOG_ERR       LOG_ERR         /* error conditions */
+#define APLOG_WARNING   LOG_WARNING     /* warning conditions */
+#define APLOG_NOTICE    LOG_NOTICE      /* normal but significant condition */
+#define APLOG_INFO      LOG_INFO        /* informational */
+#define APLOG_DEBUG     LOG_DEBUG       /* debug-level messages */
+#define APLOG_TRACE1   (LOG_DEBUG + 1)  /* trace-level 1 messages */
+#define APLOG_TRACE2   (LOG_DEBUG + 2)  /* trace-level 2 messages */
+#define APLOG_TRACE3   (LOG_DEBUG + 3)  /* trace-level 3 messages */
+#define APLOG_TRACE4   (LOG_DEBUG + 4)  /* trace-level 4 messages */
+#define APLOG_TRACE5   (LOG_DEBUG + 5)  /* trace-level 5 messages */
+#define APLOG_TRACE6   (LOG_DEBUG + 6)  /* trace-level 6 messages */
+#define APLOG_TRACE7   (LOG_DEBUG + 7)  /* trace-level 7 messages */
+#define APLOG_TRACE8   (LOG_DEBUG + 8)  /* trace-level 8 messages */
+
+#define APLOG_LEVELMASK 15     /* mask off the level value */
 
 #else
 
-#define        APLOG_EMERG     0       /* system is unusable */
-#define        APLOG_ALERT     1       /* action must be taken immediately */
-#define        APLOG_CRIT      2       /* critical conditions */
-#define        APLOG_ERR       3       /* error conditions */
-#define        APLOG_WARNING   4       /* warning conditions */
-#define        APLOG_NOTICE    5       /* normal but significant condition */
-#define        APLOG_INFO      6       /* informational */
-#define        APLOG_DEBUG     7       /* debug-level messages */
-
-#define        APLOG_LEVELMASK 7       /* mask off the level value */
+#define APLOG_EMERG      0     /* system is unusable */
+#define APLOG_ALERT      1     /* action must be taken immediately */
+#define APLOG_CRIT       2     /* critical conditions */
+#define APLOG_ERR        3     /* error conditions */
+#define APLOG_WARNING    4     /* warning conditions */
+#define APLOG_NOTICE     5     /* normal but significant condition */
+#define APLOG_INFO       6     /* informational */
+#define APLOG_DEBUG      7     /* debug-level messages */
+#define APLOG_TRACE1     8     /* trace-level 1 messages */
+#define APLOG_TRACE2     9     /* trace-level 2 messages */
+#define APLOG_TRACE3    10     /* trace-level 3 messages */
+#define APLOG_TRACE4    11     /* trace-level 4 messages */
+#define APLOG_TRACE5    12     /* trace-level 5 messages */
+#define APLOG_TRACE6    13     /* trace-level 6 messages */
+#define APLOG_TRACE7    14     /* trace-level 7 messages */
+#define APLOG_TRACE8    15     /* trace-level 8 messages */
+
+#define APLOG_LEVELMASK 15     /* mask off the level value */
 
 #endif
 
@@ -91,9 +109,79 @@ extern "C" {
 #define DEFAULT_LOGLEVEL       APLOG_WARNING
 #endif
 
+#define APLOG_NO_MODULE         -1
+
+/*
+ * Objects with static storage duration are set to NULL if not
+ * initialized explicitly. This means if aplog_module_index
+ * is not initalized using the APLOG_USE_MODULE or the
+ * AP_DECLARE_MODULE macro, we can safely fall back to
+ * use APLOG_NO_MODULE.
+ */
+static int * const aplog_module_index;
+#define APLOG_MODULE_INDEX  \
+    (aplog_module_index ? *aplog_module_index : APLOG_NO_MODULE)
+
+/*
+ * APLOG_MAX_LOGLEVEL can be used to remove logging above some
+ * specified level at compile time.
+ */
+#ifndef APLOG_MAX_LOGLEVEL
+#define APLOG_MODULE_IS_LEVEL(s,module_index,level)              \
+          ( (((level)&APLOG_LEVELMASK) <= APLOG_NOTICE) ||       \
+            (s == NULL) ||                                       \
+            (ap_get_module_loglevel(s, module_index)             \
+             >= ((level)&APLOG_LEVELMASK) ) )
+#else
+#define APLOG_MODULE_IS_LEVEL(s,module_index,level)              \
+        ( (((level)&APLOG_LEVELMASK) <= APLOG_MAX_LOGLEVEL) &&   \
+          ( (((level)&APLOG_LEVELMASK) <= APLOG_NOTICE) ||       \
+            (s == NULL) ||                                       \
+            (ap_get_module_loglevel(s, module_index)             \
+             >= ((level)&APLOG_LEVELMASK) ) ) )
+#endif
+
+#define APLOG_IS_LEVEL(s,level)     \
+    APLOG_MODULE_IS_LEVEL(s,APLOG_MODULE_INDEX,level)
+
+#define APLOGinfo(s)                APLOG_IS_LEVEL(s,APLOG_INFO)
+#define APLOGdebug(s)               APLOG_IS_LEVEL(s,APLOG_DEBUG)
+#define APLOGtrace1(s)              APLOG_IS_LEVEL(s,APLOG_TRACE1)
+#define APLOGtrace2(s)              APLOG_IS_LEVEL(s,APLOG_TRACE2)
+#define APLOGtrace3(s)              APLOG_IS_LEVEL(s,APLOG_TRACE3)
+#define APLOGtrace4(s)              APLOG_IS_LEVEL(s,APLOG_TRACE4)
+#define APLOGtrace5(s)              APLOG_IS_LEVEL(s,APLOG_TRACE5)
+#define APLOGtrace6(s)              APLOG_IS_LEVEL(s,APLOG_TRACE6)
+#define APLOGtrace7(s)              APLOG_IS_LEVEL(s,APLOG_TRACE7)
+#define APLOGtrace8(s)              APLOG_IS_LEVEL(s,APLOG_TRACE8)
+
+#define APLOG_R_IS_LEVEL(r,level)   APLOG_IS_LEVEL(r->server,level)
+#define APLOGrinfo(r)               APLOG_R_IS_LEVEL(r,APLOG_INFO)
+#define APLOGrdebug(r)              APLOG_R_IS_LEVEL(r,APLOG_DEBUG)
+#define APLOGrtrace1(r)             APLOG_R_IS_LEVEL(r,APLOG_TRACE1)
+#define APLOGrtrace2(r)             APLOG_R_IS_LEVEL(r,APLOG_TRACE2)
+#define APLOGrtrace3(r)             APLOG_R_IS_LEVEL(r,APLOG_TRACE3)
+#define APLOGrtrace4(r)             APLOG_R_IS_LEVEL(r,APLOG_TRACE4)
+#define APLOGrtrace5(r)             APLOG_R_IS_LEVEL(r,APLOG_TRACE5)
+#define APLOGrtrace6(r)             APLOG_R_IS_LEVEL(r,APLOG_TRACE6)
+#define APLOGrtrace7(r)             APLOG_R_IS_LEVEL(r,APLOG_TRACE7)
+#define APLOGrtrace8(r)             APLOG_R_IS_LEVEL(r,APLOG_TRACE8)
+
+#define APLOG_C_IS_LEVEL(c,level)   APLOG_IS_LEVEL(c->base_server,level)
+#define APLOGcinfo(c)               APLOG_C_IS_LEVEL(c,APLOG_INFO)
+#define APLOGcdebug(c)              APLOG_C_IS_LEVEL(c,APLOG_DEBUG)
+#define APLOGctrace1(r)             APLOG_C_IS_LEVEL(c,APLOG_TRACE1)
+#define APLOGctrace2(r)             APLOG_C_IS_LEVEL(c,APLOG_TRACE2)
+#define APLOGctrace3(r)             APLOG_C_IS_LEVEL(c,APLOG_TRACE3)
+#define APLOGctrace4(r)             APLOG_C_IS_LEVEL(c,APLOG_TRACE4)
+#define APLOGctrace5(r)             APLOG_C_IS_LEVEL(c,APLOG_TRACE5)
+#define APLOGctrace6(r)             APLOG_C_IS_LEVEL(c,APLOG_TRACE6)
+#define APLOGctrace7(r)             APLOG_C_IS_LEVEL(c,APLOG_TRACE7)
+#define APLOGctrace8(r)             APLOG_C_IS_LEVEL(c,APLOG_TRACE8)
+
 extern int AP_DECLARE_DATA ap_default_loglevel;
 
-#define APLOG_MARK     __FILE__,__LINE__
+#define APLOG_MARK     __FILE__,__LINE__,APLOG_MODULE_INDEX
 
 /**
  * Set up for logging to stderr.
@@ -147,6 +235,7 @@ void ap_logs_child_init(apr_pool_t *p, server_rec *s);
  * to the error_log.
  * @param file The file in which this function is called
  * @param line The line number on which this function is called
+ * @param module_index The module_index of the module generating this message
  * @param level The level of this error message
  * @param status The status code from the previous command
  * @param s The server on which we are logging
@@ -164,10 +253,20 @@ void ap_logs_child_init(apr_pool_t *p, server_rec *s);
  * simple format string like "%s", followed by the string containing the 
  * untrusted data.
  */
-AP_DECLARE(void) ap_log_error(const char *file, int line, int level, 
-                             apr_status_t status, const server_rec *s, 
-                             const char *fmt, ...)
-                           __attribute__((format(printf,6,7)));
+#if __STDC_VERSION__ >= 199901L
+/* need additional step to expand APLOG_MARK first */
+#define ap_log_error(...) ap_log_error__(__VA_ARGS__)
+#define ap_log_error__(file, line, mi, level, status, s, ...)           \
+    do { server_rec *sr = s; if (APLOG_MODULE_IS_LEVEL(sr, mi, level))  \
+             ap_log_error_(file, line, mi, level, status, sr, __VA_ARGS__); \
+    } while(0)
+#else
+#define ap_log_error ap_log_error_
+#endif
+AP_DECLARE(void) ap_log_error_(const char *file, int line, int module_index,
+                               int level, apr_status_t status,
+                               const server_rec *s, const char *fmt, ...)
+                              __attribute__((format(printf,7,8)));
 
 /**
  * ap_log_perror() - log messages which are not related to a particular
@@ -175,6 +274,7 @@ AP_DECLARE(void) ap_log_error(const char *file, int line, int level,
  * format to log messages to the error_log.
  * @param file The file in which this function is called
  * @param line The line number on which this function is called
+ * @param module_index ignored dummy value for use by APLOG_MARK
  * @param level The level of this error message
  * @param status The status code from the previous command
  * @param p The pool which we are logging for
@@ -188,10 +288,20 @@ AP_DECLARE(void) ap_log_error(const char *file, int line, int level,
  * simple format string like "%s", followed by the string containing the 
  * untrusted data.
  */
-AP_DECLARE(void) ap_log_perror(const char *file, int line, int level, 
-                             apr_status_t status, apr_pool_t *p, 
-                             const char *fmt, ...)
-                           __attribute__((format(printf,6,7)));
+#if __STDC_VERSION__ >= 199901L && defined(APLOG_MAX_LOGLEVEL)
+/* need additional step to expand APLOG_MARK first */
+#define ap_log_perror(...) ap_log_perror__(__VA_ARGS__)
+#define ap_log_perror__(file, line, mi, level, status, p, ...)            \
+    do { if ((level) <= APLOG_MAX_LOGLEVEL )                              \
+             ap_do_log_perror(file, line, mi, level, status, p,           \
+                             __VA_ARGS__); } while(0)
+#else
+#define ap_log_perror ap_log_perror_
+#endif
+AP_DECLARE(void) ap_log_perror_(const char *file, int line, int module_index,
+                                int level, apr_status_t status, apr_pool_t *p,
+                                const char *fmt, ...)
+                               __attribute__((format(printf,7,8)));
 
 /**
  * ap_log_rerror() - log messages which are related to a particular
@@ -199,6 +309,7 @@ AP_DECLARE(void) ap_log_perror(const char *file, int line, int level,
  * error_log.
  * @param file The file in which this function is called
  * @param line The line number on which this function is called
+ * @param module_index The module_index of the module generating this message
  * @param level The level of this error message
  * @param status The status code from the previous command
  * @param r The request which we are logging for
@@ -212,10 +323,20 @@ AP_DECLARE(void) ap_log_perror(const char *file, int line, int level,
  * simple format string like "%s", followed by the string containing the 
  * untrusted data.
  */
-AP_DECLARE(void) ap_log_rerror(const char *file, int line, int level, 
-                               apr_status_t status, const request_rec *r, 
-                               const char *fmt, ...)
-                           __attribute__((format(printf,6,7)));
+#if __STDC_VERSION__ >= 199901L
+/* need additional step to expand APLOG_MARK first */
+#define ap_log_rerror(...) ap_log_rerror__(__VA_ARGS__)
+#define ap_log_rerror__(file, line, mi, level, status, r, ...)              \
+    do { if (APLOG_MODULE_IS_LEVEL(r->server, mi, level))                   \
+             ap_log_rerror_(file, line, mi, level, status, r, __VA_ARGS__); \
+    } while(0)
+#else
+#define ap_log_rerror ap_log_rerror_
+#endif
+AP_DECLARE(void) ap_log_rerror_(const char *file, int line, int module_index,
+                                int level, apr_status_t status,
+                                const request_rec *r, const char *fmt, ...)
+                           __attribute__((format(printf,7,8)));
 
 /**
  * ap_log_cerror() - log messages which are related to a particular
@@ -224,6 +345,7 @@ AP_DECLARE(void) ap_log_rerror(const char *file, int line, int level,
  * @param file The file in which this function is called
  * @param line The line number on which this function is called
  * @param level The level of this error message
+ * @param module_index The module_index of the module generating this message
  * @param status The status code from the previous command
  * @param c The connection which we are logging for
  * @param fmt The format string
@@ -238,10 +360,20 @@ AP_DECLARE(void) ap_log_rerror(const char *file, int line, int level,
  * simple format string like "%s", followed by the string containing the 
  * untrusted data.
  */
-AP_DECLARE(void) ap_log_cerror(const char *file, int line, int level, 
-                               apr_status_t status, const conn_rec *c, 
-                               const char *fmt, ...)
-                           __attribute__((format(printf,6,7)));
+#if __STDC_VERSION__ >= 199901L
+/* need additional step to expand APLOG_MARK first */
+#define ap_log_cerror(...) ap_log_cerror__(__VA_ARGS__)
+#define ap_log_cerror__(file, line, mi, level, status, c, ...)              \
+    do { if (APLOG_MODULE_IS_LEVEL(c->base_server, mi, level))              \
+             ap_log_cerror_(file, line, mi, level, status, c, __VA_ARGS__); \
+    } while(0)
+#else
+#define ap_log_cerror ap_log_cerror_
+#endif
+AP_DECLARE(void) ap_log_cerror_(const char *file, int line, int module_level,
+                                int level, apr_status_t status,
+                                const conn_rec *c, const char *fmt, ...)
+                           __attribute__((format(printf,7,8)));
 
 /**
  * Convert stderr to the error log
@@ -321,6 +453,7 @@ AP_DECLARE(apr_file_t *) ap_piped_log_write_fd(piped_log *pl);
  * @ingroup hooks
  * @param file The file in which this function is called
  * @param line The line number on which this function is called
+ * @param module_index The module_index of the module generating this message
  * @param level The level of this error message
  * @param status The status code from the previous command
  * @param s The server which we are logging for
@@ -328,7 +461,8 @@ AP_DECLARE(apr_file_t *) ap_piped_log_write_fd(piped_log *pl);
  * @param pool Memory pool to allocate from
  * @param errstr message to log 
  */
-AP_DECLARE_HOOK(void, error_log, (const char *file, int line, int level,
+AP_DECLARE_HOOK(void, error_log, (const char *file, int line,
+                       int module_index, int level,
                        apr_status_t status, const server_rec *s,
                        const request_rec *r, apr_pool_t *pool,
                        const char *errstr))
index 5c52148ee7b0be5684e32a0e9f96cd4577d170df..9d1ccda5a62c05417d832b21a87a702ac7d8c75c 100644 (file)
@@ -1186,6 +1186,8 @@ struct server_rec {
 
     /* Log files --- note that transfer log is now in the modules... */
 
+    /** The per-module log levels */
+    int *module_loglevels;
     /** The name of the error log */
     char *error_fname;
     /** A file descriptor that references the error log */
index 9d468f07fbf734f42915f4ba874dd1941f2c7d52..1cd97e9aef39eb8a40d1fa971bb555d76e4ca57d 100644 (file)
@@ -50,6 +50,8 @@
 #include "http_vhost.h"
 #include "util_cfgtree.h"
 
+APLOG_USE_MODULE(core);
+
 AP_DECLARE_DATA const char *ap_server_argv0 = NULL;
 AP_DECLARE_DATA const char *ap_server_root = NULL;
 AP_DECLARE_DATA server_rec *ap_server_conf = NULL;
@@ -1353,6 +1355,26 @@ AP_DECLARE_NONSTD(const char *) ap_set_deprecated(cmd_parms *cmd,
     return cmd->cmd->errmsg;
 }
 
+AP_DECLARE(void) ap_reset_module_loglevels(server_rec *s)
+{
+    if (s->module_loglevels) {
+        memset(s->module_loglevels, -1,
+               sizeof(int) * (total_modules + DYNAMIC_MODULE_LIMIT));
+    }
+}
+
+AP_DECLARE(void) ap_set_module_loglevel(apr_pool_t *pool, server_rec *s,
+                                        int index, int level)
+{
+    if (!s->module_loglevels) {
+        s->module_loglevels = apr_palloc(pool,
+                     sizeof(int) * (total_modules + DYNAMIC_MODULE_LIMIT));
+        ap_reset_module_loglevels(s);
+    }
+
+    s->module_loglevels[index] = level;
+}
+
 /*****************************************************************
  *
  * Reading whole config files...
@@ -1960,6 +1982,7 @@ AP_CORE_DECLARE(const char *) ap_init_virtual_host(apr_pool_t *p,
     s->keep_alive_max = -1;
     s->error_log = main_server->error_log;
     s->loglevel = main_server->loglevel;
+    s->module_loglevels = NULL;
     /* useful default, otherwise we get a port of 0 on redirects */
     s->port = main_server->port;
     s->next = NULL;
@@ -2008,6 +2031,18 @@ AP_DECLARE(void) ap_fixup_virtual_hosts(apr_pool_t *p, server_rec *main_server)
         if (virt->keep_alive_max == -1)
             virt->keep_alive_max = main_server->keep_alive_max;
 
+        if (virt->module_loglevels == NULL) {
+            virt->module_loglevels = main_server->module_loglevels;
+        }
+        else if (main_server->module_loglevels != NULL) {
+            int i;
+            for (i = 0; i < total_modules + DYNAMIC_MODULE_LIMIT; i++) {
+                if (virt->module_loglevels[i] < 0)
+                    virt->module_loglevels[i] =
+                        main_server->module_loglevels[i];
+            }
+        }
+
         /* XXX: this is really something that should be dealt with by a
          * post-config api phase
          */
@@ -2041,6 +2076,7 @@ static server_rec *init_server_config(process_rec *process, apr_pool_t *p)
     s->server_scheme = NULL;
     s->error_fname = DEFAULT_ERRORLOG;
     s->loglevel = DEFAULT_LOGLEVEL;
+    s->module_loglevels = NULL;
     s->limit_req_line = DEFAULT_LIMIT_REQUEST_LINE;
     s->limit_req_fieldsize = DEFAULT_LIMIT_REQUEST_FIELDSIZE;
     s->limit_req_fields = DEFAULT_LIMIT_REQUEST_FIELDS;
index 63e4b1cb62baa9b7b22df34585f029ccaad0d33f..9f29d562cf74420059b07e0a5b9820e72d9891b1 100644 (file)
@@ -2625,24 +2625,60 @@ static const char *include_config (cmd_parms *cmd, void *dummy,
     return NULL;
 }
 
-static const char *set_loglevel(cmd_parms *cmd, void *dummy, const char *arg)
+static const char *set_loglevel(cmd_parms *cmd, void *dummy, const char *arg_)
 {
-    char *str;
+    char *level_str;
+    int level;
+    module *module;
+    char *arg = apr_pstrdup(cmd->temp_pool, arg_);
 
     const char *err = ap_check_cmd_context(cmd, NOT_IN_DIR_LOC_FILE);
     if (err != NULL) {
         return err;
     }
 
-    if ((str = ap_getword_conf(cmd->pool, &arg))) {
-        err = ap_parse_log_level(str, &cmd->server->loglevel);
+    if (arg == NULL)
+        return "LogLevel requires level keyword or module loglevel specifier";
+
+    level_str = ap_strchr(arg, ':');
+
+    if (level_str == NULL) {
+        err = ap_parse_log_level(arg, &cmd->server->loglevel);
         if (err != NULL)
-            return apr_psprintf(cmd->pool, "LogLevel: %s", err);
+            return err;
+        ap_reset_module_loglevels(cmd->server);
+        ap_log_error(APLOG_MARK, APLOG_TRACE3, 0, cmd->server,
+                     "Setting LogLevel for all modules to %s", arg);
+        return NULL;
     }
-    else {
-        return "LogLevel requires level keyword";
+
+    *level_str++ = '\0';
+    if (!*level_str) {
+        return apr_psprintf(cmd->temp_pool, "Module specifier '%s' must be "
+                            "followed by a log level keyword", arg);
     }
 
+    err = ap_parse_log_level(level_str, &level);
+    if (err != NULL)
+        return apr_psprintf(cmd->temp_pool, "%s:%s: %s", arg, level_str, err);
+
+    if ((module = find_module(cmd->server, arg)) == NULL) {
+        char *name = apr_psprintf(cmd->temp_pool, "%s_module", arg);
+        ap_log_error(APLOG_MARK, APLOG_TRACE6, 0, cmd->server,
+                     "Cannot find module '%s', trying '%s'", arg, name);
+       module = find_module(cmd->server, name);
+    }
+
+    if (module == NULL) {
+        return apr_psprintf(cmd->temp_pool, "Cannot find module %s", arg);
+    }
+
+    ap_set_module_loglevel(cmd->pool, cmd->server, 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);
+
     return NULL;
 }
 
@@ -3319,7 +3355,7 @@ AP_INIT_TAKE1("IncludeOptional", include_config, (void*)1,
   (RSRC_CONF | ACCESS_CONF | EXEC_ON_READ),
   "Name or pattern of the config file(s) to be included; ignored if the file "
   "does not exist or the pattern does not match any files"),
-AP_INIT_TAKE1("LogLevel", set_loglevel, NULL, RSRC_CONF,
+AP_INIT_ITERATE("LogLevel", set_loglevel, NULL, RSRC_CONF,
   "Level of verbosity in error logging"),
 AP_INIT_TAKE1("NameVirtualHost", ap_set_name_virtual_host, NULL, RSRC_CONF,
   "A numeric IP address:port, or the name of a host"),
@@ -3990,7 +4026,7 @@ static void register_hooks(apr_pool_t *p)
                                   NULL, AP_FTYPE_RESOURCE - 10);
 }
 
-AP_DECLARE_DATA module core_module = {
+AP_DECLARE_MODULE(core) = {
     MPM20_MODULE_STUFF,
     AP_PLATFORM_REWRITE_ARGS_HOOK, /* hook to run before apache parses args */
     create_core_dir_config,       /* create per-directory config structure */
index 9d9e24f4d5ca21d414b6ca34802b5fdd430a9326..49ab7ad77ba10212c835415cf590344bee0b680e 100644 (file)
@@ -49,6 +49,8 @@
 #include "util_time.h"
 #include "ap_mpm.h"
 
+APLOG_USE_MODULE(core);
+
 typedef struct {
     const char *t_name;
     int t_val;
@@ -134,6 +136,14 @@ static const TRANS priorities[] = {
     {"notice",  APLOG_NOTICE},
     {"info",    APLOG_INFO},
     {"debug",   APLOG_DEBUG},
+    {"trace1",  APLOG_TRACE1},
+    {"trace2",  APLOG_TRACE2},
+    {"trace3",  APLOG_TRACE3},
+    {"trace4",  APLOG_TRACE4},
+    {"trace5",  APLOG_TRACE5},
+    {"trace6",  APLOG_TRACE6},
+    {"trace7",  APLOG_TRACE7},
+    {"trace8",  APLOG_TRACE8},
     {NULL,      -1},
 };
 
@@ -535,7 +545,8 @@ AP_DECLARE(void) ap_error_log2stderr(server_rec *s) {
     }
 }
 
-static void log_error_core(const char *file, int line, int level,
+static void log_error_core(const char *file, int line, int module_index,
+                           int level,
                            apr_status_t status, const server_rec *s,
                            const conn_rec *c,
                            const request_rec *r, apr_pool_t *pool,
@@ -572,10 +583,10 @@ static void log_error_core(const char *file, int line, int level,
     else if (s->error_log) {
         /*
          * If we are doing normal logging, don't log messages that are
-         * above the server log level unless it is a startup/shutdown notice
+         * above the module's log level unless it is a startup/shutdown notice
          */
         if ((level_and_mask != APLOG_NOTICE)
-            && (level_and_mask > s->loglevel)) {
+            && (level_and_mask > ap_get_module_loglevel(s, module_index))) {
             return;
         }
 
@@ -584,9 +595,9 @@ static void log_error_core(const char *file, int line, int level,
     else {
         /*
          * If we are doing syslog logging, don't log messages that are
-         * above the server log level (including a startup/shutdown notice)
+         * above the module's log level (including a startup/shutdown notice)
          */
-        if (level_and_mask > s->loglevel) {
+        if (level_and_mask > ap_get_module_loglevel(s, module_index)) {
             return;
         }
     }
@@ -606,7 +617,7 @@ static void log_error_core(const char *file, int line, int level,
                             "[%s] ", priorities[level_and_mask].t_name);
     }
 
-    if (file && level_and_mask == APLOG_DEBUG) {
+    if (file && level_and_mask >= APLOG_DEBUG) {
 #if defined(_OSD_POSIX) || defined(WIN32) || defined(__MVS__)
         char tmp[256];
         char *e = strrchr(file, '/');
@@ -719,44 +730,48 @@ static void log_error_core(const char *file, int line, int level,
     }
 #ifdef HAVE_SYSLOG
     else {
-        syslog(level_and_mask, "%s", errstr);
+        syslog(level_and_mask < LOG_PRIMASK ? level_and_mask : APLOG_DEBUG,
+               "%s", errstr);
     }
 #endif
 
-    ap_run_error_log(file, line, level, status, s, r, pool, errstr + errstrlen);
+    ap_run_error_log(file, line, module_index, level, status, s, r, pool,
+                     errstr + errstrlen);
 }
 
-AP_DECLARE(void) ap_log_error(const char *file, int line, int level,
-                              apr_status_t status, const server_rec *s,
-                              const char *fmt, ...)
+AP_DECLARE(void) ap_log_error_(const char *file, int line, int module_index,
+                               int level, apr_status_t status,
+                               const server_rec *s, const char *fmt, ...)
 {
     va_list args;
 
     va_start(args, fmt);
-    log_error_core(file, line, level, status, s, NULL, NULL, NULL, fmt, args);
+    log_error_core(file, line, module_index, level, status, s, NULL, NULL,
+                   NULL, fmt, args);
     va_end(args);
 }
 
-AP_DECLARE(void) ap_log_perror(const char *file, int line, int level,
-                               apr_status_t status, apr_pool_t *p,
-                               const char *fmt, ...)
+AP_DECLARE(void) ap_log_perror_(const char *file, int line, int module_index,
+                                int level, apr_status_t status, apr_pool_t *p,
+                                const char *fmt, ...)
 {
     va_list args;
 
     va_start(args, fmt);
-    log_error_core(file, line, level, status, NULL, NULL, NULL, p, fmt, args);
+    log_error_core(file, line, module_index, level, status, NULL, NULL, NULL,
+                   p, fmt, args);
     va_end(args);
 }
 
-AP_DECLARE(void) ap_log_rerror(const char *file, int line, int level,
-                               apr_status_t status, const request_rec *r,
-                               const char *fmt, ...)
+AP_DECLARE(void) ap_log_rerror_(const char *file, int line, int module_index,
+                                int level, apr_status_t status,
+                                const request_rec *r, const char *fmt, ...)
 {
     va_list args;
 
     va_start(args, fmt);
-    log_error_core(file, line, level, status, r->server, NULL, r, NULL, fmt,
-                   args);
+    log_error_core(file, line, module_index, level, status, r->server, NULL, r,
+                   NULL, fmt, args);
 
     /*
      * IF APLOG_TOCLIENT is set,
@@ -777,15 +792,15 @@ AP_DECLARE(void) ap_log_rerror(const char *file, int line, int level,
     va_end(args);
 }
 
-AP_DECLARE(void) ap_log_cerror(const char *file, int line, int level,
-                               apr_status_t status, const conn_rec *c,
-                               const char *fmt, ...)
+AP_DECLARE(void) ap_log_cerror_(const char *file, int line, int module_index,
+                                int level, apr_status_t status,
+                                const conn_rec *c, const char *fmt, ...)
 {
     va_list args;
 
     va_start(args, fmt);
-    log_error_core(file, line, level, status, c->base_server, c, NULL, NULL,
-                   fmt, args);
+    log_error_core(file, line, module_index, level, status, c->base_server, c,
+                   NULL, NULL, fmt, args);
     va_end(args);
 }
 
@@ -1162,7 +1177,7 @@ AP_DECLARE(void) ap_close_piped_log(piped_log *pl)
 AP_DECLARE(const char *) ap_parse_log_level(const char *str, int *val)
 {
     char *err = "Log level keyword must be one of emerg/alert/crit/error/warn/"
-                "notice/info/debug";
+                "notice/info/debug/trace1/.../trace8";
     int i = 0;
 
     if (str == NULL)
@@ -1179,8 +1194,8 @@ AP_DECLARE(const char *) ap_parse_log_level(const char *str, int *val)
 }
 
 AP_IMPLEMENT_HOOK_VOID(error_log,
-                       (const char *file, int line, int level,
+                       (const char *file, int line, int module_index, int level,
                         apr_status_t status, const server_rec *s,
                         const request_rec *r, apr_pool_t *pool,
-                        const char *errstr), (file, line, level,
+                        const char *errstr), (file, line, module_index, level,
                         status, s, r, pool, errstr))
index 0387c724b84cad82a9e645c3774ad01496e311b5..0230038b0e6384600a08739fd677ec11d87c07c1 100644 (file)
@@ -106,6 +106,22 @@ AP_DECLARE(void *) ap_get_module_config(const ap_conf_vector_t *cv,
     return ((void **)cv)[m->module_index];
 }
 
+#if defined(ap_get_module_loglevel)
+#undef ap_get_module_loglevel
+AP_DECLARE(int) ap_get_module_loglevel(const server_rec *s, int module_index);
+#endif
+
+AP_DECLARE(int) ap_get_module_loglevel(const server_rec *s, int module_index)
+{
+    if (module_index < 0 || s->module_loglevels == NULL ||
+        s->module_loglevels[module_index] < 0)
+    {
+        return s->loglevel;
+    }
+
+    return s->module_loglevels[module_index];
+}
+
 /**
  * Generic accessors for other modules to set at their own module-specific
  * data