diff options
author | Jan Kaluža <jkaluza@apache.org> | 2015-04-17 12:14:15 +0200 |
---|---|---|
committer | Jan Kaluža <jkaluza@apache.org> | 2015-04-17 12:14:15 +0200 |
commit | 438584b1065f40849b4cfb71bdda0734dc9402d3 (patch) | |
tree | 224c89d66d418c2890ba0fa38ecdf44521344a6d | |
parent | * mod_dav_fs: set default value of DavLockDB using installation layout (diff) | |
download | apache2-438584b1065f40849b4cfb71bdda0734dc9402d3.tar.xz apache2-438584b1065f40849b4cfb71bdda0734dc9402d3.zip |
* mod_log_config: Allow using ErrorLog providers for CustomLog.
git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1674261 13f79535-47bb-0310-9956-ffa450edef68
-rw-r--r-- | docs/manual/mod/mod_log_config.xml | 16 | ||||
-rw-r--r-- | modules/loggers/mod_log_config.c | 99 |
2 files changed, 111 insertions, 4 deletions
diff --git a/docs/manual/mod/mod_log_config.xml b/docs/manual/mod/mod_log_config.xml index f40fb0b68c..7a6d4c2cb3 100644 --- a/docs/manual/mod/mod_log_config.xml +++ b/docs/manual/mod/mod_log_config.xml @@ -418,7 +418,7 @@ <directivesynopsis> <name>CustomLog</name> <description>Sets filename and format of log file</description> -<syntax>CustomLog <var>file</var>|<var>pipe</var> +<syntax>CustomLog <var>file</var>|<var>pipe</var>|<var>provider</var> <var>format</var>|<var>nickname</var> [env=[!]<var>environment-variable</var>| expr=<var>expression</var>]</syntax> @@ -457,6 +457,20 @@ expr=<var>expression</var>]</syntax> may allow the use of back slashes. In general it is a good idea to always use forward slashes throughout the configuration files.</p> </note></dd> + <dt><var>provider</var></dt> + <dd>Modules implementing ErrorLog providers can also be used as a target + for CustomLog messages. To use ErrorLog provider as a target, + "provider:argument" syntax must be used. You can for example use + <module>mod_journald</module> or <module>mod_syslog</module> + as a provider: + <highlight language="config"> +# CustomLog logging to journald +CustomLog "journald" "%h %l %u %t \"%r\" %>s %b" + +# CustomLog logging to syslog with "user" facility +CustomLog "syslog:user" "%h %l %u %t \"%r\" %>s %b" + </highlight> + </dd> </dl> <p>The second argument specifies what will be written to the diff --git a/modules/loggers/mod_log_config.c b/modules/loggers/mod_log_config.c index 75e131eeba..6bc7cd4181 100644 --- a/modules/loggers/mod_log_config.c +++ b/modules/loggers/mod_log_config.c @@ -161,6 +161,7 @@ #include "http_protocol.h" #include "util_time.h" #include "ap_mpm.h" +#include "ap_provider.h" #if APR_HAVE_UNISTD_H #include <unistd.h> @@ -289,6 +290,35 @@ typedef struct { apr_array_header_t *conditions; } log_format_item; +/* + * errorlog_provider_data holds pointer to provider and its handle + * generated by provider initialization. It is used when logging using + * ap_errorlog_provider. + */ +typedef struct { + struct ap_errorlog_provider *provider; + void *handle; +} errorlog_provider_data; + +/* + * Type of the log_writer created by ap_default_log_writer_init. + * It is used by ap_default_log_writer to determine the type of + * the log_writer. + */ +enum default_log_writer_type { + LOG_WRITER_FD, + LOG_WRITER_PROVIDER +}; + +/* + * Abstract struct to allow multiple types of log writers to be created + * by ap_default_log_writer_init function. + */ +typedef struct { + enum default_log_writer_type type; + void *log_writer; +} default_log_writer; + static char *pfmt(apr_pool_t *p, int i) { if (i <= 0) { @@ -1596,6 +1626,7 @@ static apr_status_t ap_default_log_writer( request_rec *r, apr_size_t len) { + default_log_writer *log_writer = handle; char *str; char *s; int i; @@ -1612,13 +1643,44 @@ static apr_status_t ap_default_log_writer( request_rec *r, s += strl[i]; } - rv = apr_file_write_full((apr_file_t*)handle, str, len, NULL); + if (log_writer->type == LOG_WRITER_FD) { + rv = apr_file_write_full((apr_file_t*)log_writer->log_writer, str, + len, NULL); + } + else { + errorlog_provider_data *data = log_writer->log_writer; + ap_errorlog_info info; + info.r = r; + info.s = r->server; + info.c = r->connection; + info.pool = r->pool; + info.file = NULL; + info.line = 0; + info.status = 0; + info.using_provider = 1; + info.startup = 0; + info.format = ""; + data->provider->writer(&info, data->handle, + str, len); + } return rv; } static void *ap_default_log_writer_init(apr_pool_t *p, server_rec *s, const char* name) { + default_log_writer *log_writer; + const char *provider_name = name; + ap_errorlog_provider *provider = NULL; + char *sep; + + /* We support *Log "errorlog_provider:arg" syntax now, so get the provider + * name from the name. */ + if ((sep = ap_strchr_c(name, ':')) != NULL) { + provider_name = apr_pstrmemdup(p, name, sep - name); + sep++; + } + if (*name == '|') { piped_log *pl; @@ -1626,7 +1688,34 @@ static void *ap_default_log_writer_init(apr_pool_t *p, server_rec *s, if (pl == NULL) { return NULL; } - return ap_piped_log_write_fd(pl); + + log_writer = apr_pcalloc(p, sizeof(default_log_writer)); + log_writer->type = LOG_WRITER_FD; + log_writer->log_writer = ap_piped_log_write_fd(pl); + if (!log_writer->log_writer) { + return NULL; + } + return log_writer; + } + else if ((provider = ap_lookup_provider(AP_ERRORLOG_PROVIDER_GROUP, + provider_name, AP_ERRORLOG_PROVIDER_VERSION)) != NULL) { + void *provider_handle; + errorlog_provider_data *provider_data; + + provider_handle = provider->init(p, s); + if (!provider_handle) { + /* provider must log something to the console */ + return NULL; + } + + provider_data = apr_pcalloc(p, sizeof(errorlog_provider_data)); + provider_data->provider = provider; + provider_data->handle = provider_handle; + + log_writer = apr_pcalloc(p, sizeof(default_log_writer)); + log_writer->type = LOG_WRITER_PROVIDER; + log_writer->log_writer = provider_data; + return log_writer; } else { const char *fname = ap_server_root_relative(p, name); @@ -1644,7 +1733,11 @@ static void *ap_default_log_writer_init(apr_pool_t *p, server_rec *s, "could not open transfer log file %s.", fname); return NULL; } - return fd; + + log_writer = apr_pcalloc(p, sizeof(default_log_writer)); + log_writer->type = LOG_WRITER_FD; + log_writer->log_writer = fd; + return log_writer; } } static void *ap_buffered_log_writer_init(apr_pool_t *p, server_rec *s, |