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鈥檒l occasionally send you account related emails.
Already on GitHub? Sign in to your account
[WIP, RFC] new logger: rawfifo (infra for plugin) #23198
Conversation
Signed-off-by: Akihiro Suda <suda.akihiro@lab.ntt.co.jp>
Years ago when we designed our logging pipeline we decided to not use named pipes because they fundamentally are blocking unless you have a reader on the other side of the pipe, meaning that you lose log messages if that needs to restart鈥攐r worse, you tie up the Docker daemon. This needs to be extremely carefully engineered to handle a crashed reader at the other end of the pipe. |
@sirupsen hmm iirc you should be able to make the named pipe non blocking and change the size of the named pipe, there are also some trick which allow we to write to the pipe without any reader yet, maybe that help with the concern ? Otherwise we probably can also look at the msg queue facility provided by the kernel as an alternative to this. |
We use That said, a named pipe can still be valuable to many people, but it should come with a strong disclaimer (unless there are ways to make it non-blocking and/or super safe to not block the daemon logging thread). |
Thank you all for the comment. Actually, even when there is no reader yet, the container can write some output to stdio until the buffer gets filled up. (please see also "Scenario 1" and "Scenario 2") In Linux, the buffer size is 4096 bytes by default, but you can configure the size using So I think this help with the concern as @dqminh mentioned. However, we still have to address the reader crash issue as @sirupsen mentioned. Approach 1: propagate SIGPIPE to the container program when the reader exitedPro: This keeps the original UNIX semantic, and do nothing particular to Docker. Con: The process exists on SIGPIPE by default. Even though the approach keeps the original UNIX semantic, this may surprise users. Approach 2: reopen the pipe in the daemon and wait for reader restart; propagate nothing to the container programPro: The container program keeps running on the reader crash. Con: Some log messages will be lost during reopening the pipe. If reader could not restart due to some reason, the output will be blocked after running out the buffer. This may surprise users. Approach 3: use other MQsSeveral pros and cons.. Approach 4: close this PR and find out other performance/stability isolation techniqueFor OOM issue, several approaches are suggested in #18057 For CPU usage issues #21181, #19209, I am not sure how we can address the issue. |
@sirupsen Can I hear your opinion 馃槂 ? |
I definitely applaud the effort here, but I'm not sure this is the right direction. |
@cpuguy83 So perhaps the |
Ok, we discussed this in the maintainers session, and think we should close this for now, looking for the right approach. Thanks for contributing though! |
oops closed the wrong PR |
darn, was the good one, sorry for the noise |
What I did
Added a new logger called
rawfifo
.This can be used for implementing logging plugins outside the daemon process.
Related: #18604
Related: #18001 (comment),
How I did it
RawLogger
.RawLogger
embedsLogger
.Copier
from a structure into an interface.Copier
:MessageCopier
andRawCopier
.MessageCopier
is identical to the formerCopier
.RawCopier
is different fromMessageCopier
in that it does not try to detect '\n' and just copies raw log streams to anio.Writer
, which is returned fromRawLogger.RawWriter()
.rawfifo
logging driver which implementsRawLogger
(andLogger
as well).How to verify it
Scenario 1: standard workload
Execute:
Make sure you can execute a command in the container interactively.
Make sure the output is copied to the log:
You may have an issue when you try to stop the container.
This issue will be fixed after discussing the core design.
Scenario 2: make sure infinite output does not lead to OOM
Execute:
Wait for 5 or more minutes.
Make sure there is no significant impact in CPU and RAM usage.
Make sure the output is copied to the log.
Note that some output were blocked during we were waiting for several minutes.
Scenario 3: make sure infinite output without \n does not lead to OOM (see also #20600, #18057)
Execute:
Wait for 5 or more minutes.
Make sure there is no significant impact in CPU and RAM usage.
Open the log, and Make sure there is still no significant impact in CPU and RAM usage.
Description for the changelog
new logger: rawfifo
A picture of a cute animal (not mandatory but encouraged)
https://upload.wikimedia.org/wikipedia/commons/4/40/Adelie_Penguins_on_iceberg.jpg
Signed-off-by: Akihiro Suda suda.akihiro@lab.ntt.co.jp
Motivation: split the logging routine from the daemon process
I know this PR is controversial and GELF is the standard way for connecting the Docker daemon to other logging software.
#18001 (comment)
But having complicated logging routines (including GELF) in the daemon itself can lead to some issues related to performance and stability.
So I suggest making in-daemon routines as small as possible with this
rawfifo
driver, and do substantial work outside the daemon process (a.k.a plugin).As we can limit resource usage for external logging processes via cgroup, we can prevent them from crasing the daemon.
If the external logging process does not read from the fifo, write to stdout is blocked, and the daemon does not need to be busy for buffering the write and waiting for '\n'.
Even if I cannot get positive comments for my implementation, I would like to hear comments about how we can split loggers from the damon in aspect of performance and stability 馃槃
Tags
RawLogger
does not support tags because it just copies the raw log stream from a container to a named pipe without appending meta data.So it is recommended to specify the
rawfifo-dir
which path contains the container name and other information instead.Timestamps
RawLogger
does not support timestamps.It is up to the external logging process to read logs as fast as possible and determine arbitrary timestamps.
TODO
rawfifo-dir