core: make sure that $JOURNAL_STREAM prefers stderr over stdout information (#6824)

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
This commit is contained in:
Lennart Poettering 2017-09-15 08:26:38 +02:00 committed by Zbigniew Jędrzejewski-Szmek
parent 2e914ef433
commit ab2116b140
2 changed files with 12 additions and 2 deletions

View 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

View 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;
}