8b0621
diff --git a/modules/loggers/config.m4 b/modules/loggers/config.m4
8b0621
index 762e773e94..0848d2e377 100644
8b0621
--- a/modules/loggers/config.m4
8b0621
+++ b/modules/loggers/config.m4
8b0621
@@ -5,6 +5,8 @@ dnl APACHE_MODULE(name, helptext[, objects[, structname[, default[, config]]]])
8b0621
 APACHE_MODPATH_INIT(loggers)
8b0621
 	
8b0621
 APACHE_MODULE(log_config, logging configuration.  You won't be able to log requests to the server without this module., , , yes)
8b0621
+APR_ADDTO(MOD_LOG_CONFIG_LDADD, [$SYSTEMD_LIBS])
8b0621
+
8b0621
 APACHE_MODULE(log_debug, configurable debug logging, , , most)
8b0621
 APACHE_MODULE(log_forensic, forensic logging)
8b0621
 
8b0621
diff --git a/modules/loggers/mod_log_config.c b/modules/loggers/mod_log_config.c
8b0621
index 996c09cf49..50a056a2f8 100644
8b0621
--- a/modules/loggers/mod_log_config.c
8b0621
+++ b/modules/loggers/mod_log_config.c
8b0621
@@ -172,6 +172,10 @@
8b0621
 #include <limits.h>
8b0621
 #endif
8b0621
 
8b0621
+#ifdef HAVE_SYSTEMD
8b0621
+#include <systemd/sd-journal.h>
8b0621
+#endif
8b0621
+
8b0621
 #define DEFAULT_LOG_FORMAT "%h %l %u %t \"%r\" %>s %b"
8b0621
 
8b0621
 module AP_MODULE_DECLARE_DATA log_config_module;
8b0621
@@ -1638,6 +1642,25 @@ static apr_status_t ap_default_log_writer( request_rec *r,
8b0621
 
8b0621
     return rv;
8b0621
 }
8b0621
+
8b0621
+static apr_status_t wrap_journal_stream(apr_pool_t *p, apr_file_t **outfd,
8b0621
+                                        int priority)
8b0621
+{
8b0621
+#ifdef HAVE_SYSTEMD
8b0621
+    int fd;
8b0621
+
8b0621
+    fd = sd_journal_stream_fd("httpd", priority, 0);
8b0621
+    if (fd < 0) return fd;
8b0621
+
8b0621
+    /* This is an AF_UNIX socket fd so is more pipe-like than
8b0621
+     * file-like (the fd is neither seekable or readable), and use of
8b0621
+     * apr_os_pipe_put_ex() allows cleanup registration. */
8b0621
+    return apr_os_pipe_put_ex(outfd, &fd, 1, p);
8b0621
+#else
8b0621
+    return APR_ENOTIMPL;
8b0621
+#endif
8b0621
+}
8b0621
+
8b0621
 static void *ap_default_log_writer_init(apr_pool_t *p, server_rec *s,
8b0621
                                         const char* name)
8b0621
 {
8b0621
@@ -1650,6 +1673,32 @@ static void *ap_default_log_writer_init(apr_pool_t *p, server_rec *s,
8b0621
         }
8b0621
         return ap_piped_log_write_fd(pl);
8b0621
     }
8b0621
+    else if (strncasecmp(name, "journald:", 9) == 0) {
8b0621
+        int priority;
8b0621
+        const char *err = ap_parse_log_level(name + 9, &priority);
8b0621
+        apr_status_t rv;
8b0621
+        apr_file_t *fd;
8b0621
+
8b0621
+        if (err == NULL && priority > LOG_DEBUG) {
8b0621
+            err = "TRACE level debugging not supported with journald";
8b0621
+        }
8b0621
+
8b0621
+        if (err) {
8b0621
+            ap_log_error(APLOG_MARK, APLOG_ERR, APR_EBADPATH, s, 
8b0621
+                         "invalid journald log priority name %s: %s",
8b0621
+                         name, err);
8b0621
+            return NULL;
8b0621
+        }
8b0621
+
8b0621
+        rv = wrap_journal_stream(p, &fd, priority);
8b0621
+        if (rv) {
8b0621
+            ap_log_error(APLOG_MARK, APLOG_ERR, rv, s, 
8b0621
+                         "could not open journald log stream");
8b0621
+            return NULL;
8b0621
+        }
8b0621
+
8b0621
+        return fd;
8b0621
+    }
8b0621
     else {
8b0621
         const char *fname = ap_server_root_relative(p, name);
8b0621
         apr_file_t *fd;