core: make sure that $JOURNAL_STREAM prefers stderr over stdout information (#6824)
authorLennart Poettering <lennart@poettering.net>
Fri, 15 Sep 2017 06:26:38 +0000 (08:26 +0200)
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Fri, 15 Sep 2017 06:26:38 +0000 (08:26 +0200)
If two separate log streams are connected to stdout and stderr, let's
make sure $JOURNAL_STREAM points to the latter, as that's the preferred
log destination, and the environment variable has been created in order
to permit services to automatically upgrade from stderr based logging to
native journal logging.

Also, document this behaviour.

Fixes: #6800

man/systemd.exec.xml
src/core/execute.c

index 7821b69..53daff0 100644 (file)
@@ -2012,6 +2012,12 @@ CapabilityBoundingSet=~CAP_B CAP_C</programlisting>
         <varname>$JOURNAL_STREAM</varname> is set at all as services might invoke external processes replacing their
         standard output or standard error output, without unsetting the environment variable.</para>
 
+        <para>If both standard output and standard error of the executed processes are connected to the journal via a
+        stream socket, this environment variable will contain information about the standard error stream, as that's
+        usually the preferred destination for log data. (Note that typically the same stream is used for both standard
+        output and standard error, hence very likely the environment variable contains device and inode information
+        matching both stream file descriptors.)</para>
+
         <para>This environment variable is primarily useful to allow services to optionally upgrade their used log
         protocol to the native journal protocol (using
         <citerefentry><refentrytitle>sd_journal_print</refentrytitle><manvolnum>3</manvolnum></citerefentry> and other
index 9dcc02a..e2d84fe 100644 (file)
@@ -595,9 +595,13 @@ static int setup_output(
 
                         /* If we connected this fd to the journal via a stream, patch the device/inode into the passed
                          * parameters, but only then. This is useful so that we can set $JOURNAL_STREAM that permits
-                         * services to detect whether they are connected to the journal or not. */
+                         * services to detect whether they are connected to the journal or not.
+                         *
+                         * If both stdout and stderr are connected to a stream then let's make sure to store the data
+                         * about STDERR as that's usually the best way to do logging. */
 
-                        if (fstat(fileno, &st) >= 0) {
+                        if (fstat(fileno, &st) >= 0 &&
+                            (*journal_stream_ino == 0 || fileno == STDERR_FILENO)) {
                                 *journal_stream_dev = st.st_dev;
                                 *journal_stream_ino = st.st_ino;
                         }