summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJan Kaluža <jkaluza@apache.org>2015-04-17 12:14:15 +0200
committerJan Kaluža <jkaluza@apache.org>2015-04-17 12:14:15 +0200
commit438584b1065f40849b4cfb71bdda0734dc9402d3 (patch)
tree224c89d66d418c2890ba0fa38ecdf44521344a6d
parent* mod_dav_fs: set default value of DavLockDB using installation layout (diff)
downloadapache2-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.xml16
-rw-r--r--modules/loggers/mod_log_config.c99
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\" %&gt;s %b"
+
+# CustomLog logging to syslog with "user" facility
+CustomLog "syslog:user" "%h %l %u %t \"%r\" %&gt;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,