-
Notifications
You must be signed in to change notification settings - Fork 127
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
extra newlines in logged container output #242
Comments
very odd, I am unable to reproduce this behavior on fedora 33 and systemd 246 (with conmon 2.0.26 + podman 3.0.0/2.2.1) what is the host OS and systemd version? |
just now but i've seen the same behavior on ubuntu too. |
also
split output lines look like
|
To reproduce, try this: repo_242.cpp #include <iostream>
#include <thread>
using namespace std;
int main() {
cerr << "This should be";
std::this_thread::sleep_for(1s);
cerr << " on the same line" << endl;
return 0;
} Dockerfile FROM buildpack-deps
COPY repo_242.cpp /repo_242.cpp
RUN g++ /repo_242.cpp -o /repo_242
ENTRYPOINT [ "/repo_242" ] Run: podman build . -t debug
podman run --rm --log-driver journald debug
journalctl -e _COMM=conmon It will show something like:
|
Okay I've also reproduced. Looking at the code, the fix is not trivial, and I don't think I have the cycles to tackle it right now. Does anyone want to take a shot? the root of the issue is we call a read() to read the stdout/err from the container, and that read doesn't wait for alll the output before returning. We'd need to implement some sort of buffer for the journald log driver to save the data until there's a newline (or find a better read() function, I don't know of any) |
@giuseppe PTAL |
is it what we want though? With buffering we risk that a message that has no |
In the example above, perhaps conmon should print |
I think breaking a log line in the middle is unacceptable. This will break any existing log analysis tools, and make the log much harder for humans to interpret. We may need to flush the buffer when the program exits to avoid losing any message. Anyway, if the stdout is connected directly to journald, journald will do buffering, too (Can be verified by running the above test program with relevant lines from journald: |
True, but I think it would still be preferred over breaking up loglines. Any ideas on what docker does in this case? |
Are you sure the sleep is necessary to reproduce this? I found this ticket when researching split log lines in an openshift deployment, and mine are coming in the middle of atomic log calls like log("This is a long message"). |
No, it is not necessary. It just makes this easier to reproduce. |
Ensures that log lines less than or equal to 8k in size are logged as a single journald message by buffering partial messages from subsequent read calls until a newline is observed (or buffer is full). Fixes: containers#242 Signed-off-by: Cory Snyder <[email protected]>
Ensures that log lines less than or equal to 8k in size are logged as a single journald message by buffering partial messages from subsequent read calls until a newline is observed (or buffer is full). Fixes: containers#242 Signed-off-by: Cory Snyder <[email protected]>
Ensures that log lines less than or equal to 8k in size are logged as a single journald message by buffering partial messages from subsequent read calls until a newline is observed (or buffer is full). Fixes: containers#242 Signed-off-by: Cory Snyder <[email protected]>
Ensures that log lines less than or equal to 8k in size are logged as a single journald message by buffering partial messages from subsequent read calls until a newline is observed (or buffer is full). Fixes: containers#242 Signed-off-by: Cory Snyder <[email protected]>
Ensures that log lines less than or equal to 8k in size are logged as a single journald message by buffering partial messages from subsequent read calls until a newline is observed (or buffer is full). Fixes: #242 Signed-off-by: Cory Snyder <[email protected]>
Buggy container runtimes are known to do partial reads on container's stderr and emit torn logs [1]. This is due to write(2) allowing partial data transfer. One way to avoid this when stderr is a FIFO (which is the case for container runtimes) is to changed the file flags to set O_NONBLOCK which alters the behavior of write(2) when the write size is less than PIPE_BUF. This makes a write guaranteed to be atomic. The small complexity added is to poll on stderr in this case whenever a write(2) fails with EAGAIN. This does not block the log flush thread in any new way. It would always block when the stderr FIFO was full. [1] containers/conmon#242 Fixes: cef04bc Fixes: https://tracker.ceph.com/issues/57923 Related: https://bugzilla.redhat.com/show_bug.cgi?id=1996599 Related: https://bugzilla.redhat.com/show_bug.cgi?id=2108228 Signed-off-by: Patrick Donnelly <[email protected]>
Buggy container runtimes are known to do partial reads on container's stderr and emit torn logs [1]. This is due to write(2) allowing partial data transfer. One way to avoid this when stderr is a FIFO (which is the case for container runtimes) is to changed the file flags to set O_NONBLOCK which alters the behavior of write(2) when the write size is less than PIPE_BUF. This makes a write guaranteed to be atomic. The small complexity added is to poll on stderr in this case whenever a write(2) fails with EAGAIN. This does not block the log flush thread in any new way. It would always block when the stderr FIFO was full. [1] containers/conmon#242 Fixes: cef04bc Fixes: https://tracker.ceph.com/issues/57923 Related: https://bugzilla.redhat.com/show_bug.cgi?id=1996599 Related: https://bugzilla.redhat.com/show_bug.cgi?id=2108228 Signed-off-by: Patrick Donnelly <[email protected]>
Buggy container runtimes are known to do partial reads on container's stderr and emit torn logs [1]. This is due to write(2) allowing partial data transfer. One way to avoid this when stderr is a FIFO (which is the case for container runtimes) is to change the file flags to set O_NONBLOCK which alters the behavior of write(2) when the write size is less than PIPE_BUF. This makes a write guaranteed to be atomic. The small complexity added is to poll on stderr in this case whenever a write(2) fails with EAGAIN. This does not block the log flush thread in any new way. It would always block when the stderr FIFO was full. [1] containers/conmon#242 Fixes: cef04bc Fixes: https://tracker.ceph.com/issues/57923 Related: https://bugzilla.redhat.com/show_bug.cgi?id=1996599 Related: https://bugzilla.redhat.com/show_bug.cgi?id=2108228 Signed-off-by: Patrick Donnelly <[email protected]>
Buggy container runtimes are known to do partial reads on container's stderr and emit torn logs [1]. This is due to write(2) allowing partial data transfer. One way to avoid this when stderr is a FIFO (which is the case for container runtimes) is to change the file flags to set O_NONBLOCK which alters the behavior of write(2) when the write size is less than PIPE_BUF. This makes a write guaranteed to be atomic. The small complexity added is to poll on stderr in this case whenever a write(2) fails with EAGAIN. This does not block the log flush thread in any new way. It would always block when the stderr FIFO was full. [1] containers/conmon#242 Fixes: cef04bc Fixes: https://tracker.ceph.com/issues/57923 Related: https://bugzilla.redhat.com/show_bug.cgi?id=1996599 Related: https://bugzilla.redhat.com/show_bug.cgi?id=2108228 Signed-off-by: Patrick Donnelly <[email protected]>
Buggy container runtimes are known to do partial reads on container's stderr and emit torn logs [1]. This is due to write(2) allowing partial data transfer. One way to avoid this when stderr is a FIFO (which is the case for container runtimes) is to change the file flags to set O_NONBLOCK which alters the behavior of write(2) when the write size is less than PIPE_BUF. This makes a write guaranteed to be atomic. The small complexity added is to poll on stderr in this case whenever a write(2) fails with EAGAIN. This does not block the log flush thread in any new way. It would always block when the stderr FIFO was full. [1] containers/conmon#242 Fixes: cef04bc Fixes: https://tracker.ceph.com/issues/57923 Related: https://bugzilla.redhat.com/show_bug.cgi?id=1996599 Related: https://bugzilla.redhat.com/show_bug.cgi?id=2108228 Signed-off-by: Patrick Donnelly <[email protected]>
Buggy container runtimes are known to do partial reads on container's stderr and emit torn logs [1]. This is due to write(2) allowing partial data transfer. One way to avoid this when stderr is a FIFO (which is the case for container runtimes) is to change the file flags to set O_NONBLOCK which alters the behavior of write(2) when the write size is less than PIPE_BUF. This makes a write guaranteed to be atomic. The small complexity added is to poll on stderr in this case whenever a write(2) fails with EAGAIN. This does not block the log flush thread in any new way. It would always block when the stderr FIFO was full. [1] containers/conmon#242 Fixes: cef04bc Fixes: https://tracker.ceph.com/issues/57923 Related: https://bugzilla.redhat.com/show_bug.cgi?id=1996599 Related: https://bugzilla.redhat.com/show_bug.cgi?id=2108228 Signed-off-by: Patrick Donnelly <[email protected]> (cherry picked from commit 2551130) Conflicts: src/log/Log.cc: code moved
Buggy container runtimes are known to do partial reads on container's stderr and emit torn logs [1]. This is due to write(2) allowing partial data transfer. One way to avoid this when stderr is a FIFO (which is the case for container runtimes) is to change the file flags to set O_NONBLOCK which alters the behavior of write(2) when the write size is less than PIPE_BUF. This makes a write guaranteed to be atomic. The small complexity added is to poll on stderr in this case whenever a write(2) fails with EAGAIN. This does not block the log flush thread in any new way. It would always block when the stderr FIFO was full. [1] containers/conmon#242 Fixes: cef04bc Fixes: https://tracker.ceph.com/issues/57923 Related: https://bugzilla.redhat.com/show_bug.cgi?id=1996599 Related: https://bugzilla.redhat.com/show_bug.cgi?id=2108228 Signed-off-by: Patrick Donnelly <[email protected]> (cherry picked from commit 2551130) Conflicts: src/log/Log.cc src/log/Log.h
Buggy container runtimes are known to do partial reads on container's stderr and emit torn logs [1]. This is due to write(2) allowing partial data transfer. One way to avoid this when stderr is a FIFO (which is the case for container runtimes) is to change the file flags to set O_NONBLOCK which alters the behavior of write(2) when the write size is less than PIPE_BUF. This makes a write guaranteed to be atomic. The small complexity added is to poll on stderr in this case whenever a write(2) fails with EAGAIN. This does not block the log flush thread in any new way. It would always block when the stderr FIFO was full. [1] containers/conmon#242 Fixes: cef04bc Fixes: https://tracker.ceph.com/issues/57923 Related: https://bugzilla.redhat.com/show_bug.cgi?id=1996599 Related: https://bugzilla.redhat.com/show_bug.cgi?id=2108228 Signed-off-by: Patrick Donnelly <[email protected]> (cherry picked from commit 2551130) Conflicts: src/log/Log.cc: code moved
Buggy container runtimes are known to do partial reads on container's stderr and emit torn logs [1]. This is due to write(2) allowing partial data transfer. One way to avoid this when stderr is a FIFO (which is the case for container runtimes) is to change the file flags to set O_NONBLOCK which alters the behavior of write(2) when the write size is less than PIPE_BUF. This makes a write guaranteed to be atomic. The small complexity added is to poll on stderr in this case whenever a write(2) fails with EAGAIN. This does not block the log flush thread in any new way. It would always block when the stderr FIFO was full. [1] containers/conmon#242 Fixes: cef04bc Fixes: https://tracker.ceph.com/issues/57923 Related: https://bugzilla.redhat.com/show_bug.cgi?id=1996599 Related: https://bugzilla.redhat.com/show_bug.cgi?id=2108228 Signed-off-by: Patrick Donnelly <[email protected]> (cherry picked from commit 2551130) Conflicts: src/log/Log.cc: code moved
Buggy container runtimes are known to do partial reads on container's stderr and emit torn logs [1]. This is due to write(2) allowing partial data transfer. One way to avoid this when stderr is a FIFO (which is the case for container runtimes) is to change the file flags to set O_NONBLOCK which alters the behavior of write(2) when the write size is less than PIPE_BUF. This makes a write guaranteed to be atomic. The small complexity added is to poll on stderr in this case whenever a write(2) fails with EAGAIN. This does not block the log flush thread in any new way. It would always block when the stderr FIFO was full. [1] containers/conmon#242 Fixes: cef04bc Fixes: https://tracker.ceph.com/issues/57923 Related: https://bugzilla.redhat.com/show_bug.cgi?id=1996599 Related: https://bugzilla.redhat.com/show_bug.cgi?id=2108228 Signed-off-by: Patrick Donnelly <[email protected]> (cherry picked from commit 2551130) Conflicts: src/log/Log.cc: code moved
Buggy container runtimes are known to do partial reads on container's stderr and emit torn logs [1]. This is due to write(2) allowing partial data transfer. One way to avoid this when stderr is a FIFO (which is the case for container runtimes) is to change the file flags to set O_NONBLOCK which alters the behavior of write(2) when the write size is less than PIPE_BUF. This makes a write guaranteed to be atomic. The small complexity added is to poll on stderr in this case whenever a write(2) fails with EAGAIN. This does not block the log flush thread in any new way. It would always block when the stderr FIFO was full. [1] containers/conmon#242 Fixes: cef04bc Fixes: https://tracker.ceph.com/issues/57923 Related: https://bugzilla.redhat.com/show_bug.cgi?id=1996599 Related: https://bugzilla.redhat.com/show_bug.cgi?id=2108228 Signed-off-by: Patrick Donnelly <[email protected]> (cherry picked from commit 2551130) Conflicts: src/log/Log.cc src/log/Log.h
Buggy container runtimes are known to do partial reads on container's stderr and emit torn logs [1]. This is due to write(2) allowing partial data transfer. One way to avoid this when stderr is a FIFO (which is the case for container runtimes) is to change the file flags to set O_NONBLOCK which alters the behavior of write(2) when the write size is less than PIPE_BUF. This makes a write guaranteed to be atomic. The small complexity added is to poll on stderr in this case whenever a write(2) fails with EAGAIN. This does not block the log flush thread in any new way. It would always block when the stderr FIFO was full. [1] containers/conmon#242 Fixes: cef04bc Fixes: https://tracker.ceph.com/issues/57923 Related: https://bugzilla.redhat.com/show_bug.cgi?id=1996599 Related: https://bugzilla.redhat.com/show_bug.cgi?id=2108228 Signed-off-by: Patrick Donnelly <[email protected]> (cherry picked from commit 2551130) Conflicts: src/log/Log.cc src/log/Log.h
Buggy container runtimes are known to do partial reads on container's stderr and emit torn logs [1]. This is due to write(2) allowing partial data transfer. One way to avoid this when stderr is a FIFO (which is the case for container runtimes) is to change the file flags to set O_NONBLOCK which alters the behavior of write(2) when the write size is less than PIPE_BUF. This makes a write guaranteed to be atomic. The small complexity added is to poll on stderr in this case whenever a write(2) fails with EAGAIN. This does not block the log flush thread in any new way. It would always block when the stderr FIFO was full. [1] containers/conmon#242 Fixes: cef04bc Fixes: https://tracker.ceph.com/issues/57923 Related: https://bugzilla.redhat.com/show_bug.cgi?id=1996599 Related: https://bugzilla.redhat.com/show_bug.cgi?id=2108228 Signed-off-by: Patrick Donnelly <[email protected]> (cherry picked from commit 2551130) Conflicts: src/log/Log.cc: code moved (cherry picked from commit cfb6f46) Resolves: rhbz#2108228
container output, as seen in journald, has random newlines inserted.
Steps to reproduce the issue:
There is probably a simpler way to do this, but this is what I did:
systemctl start conmon-test
journalctl -u conmon-test
Describe the results you received:
Output has random newlines. For example:
and
The number of newlines seems to vary.. in my actual workload (not this test) I get a half dozen per line of output.
Describe the results you expected:
No inserted newlines.
Additional information you deem important (e.g. issue happens only occasionally):
Output of
conmon --version
:Output of
podman version
:Package info (e.g. output of
rpm -q podman
orapt list podman
):I've seen the same with podman 2.2.1 on centos too.
The text was updated successfully, but these errors were encountered: