为什么当程序输出通过管道传输时,journalctl 不会显示日志?

为什么当程序输出通过管道传输时,journalctl 不会显示日志?

我正在尝试通过 systemd 服务运行我的 docker-compose 容器,并让 fail2ban 读取它们的日志。但是,docker-compose 添加了如下前缀:

container_name_1 | Actual log message

因此,我想做的是docker-compose up --no-color 2>&1 | sed 's/^[^ ]* *| //'删除该前缀,以便 fail2ban 能够正确匹配日志行。但是当我这样做时,我只Started mydockercontainers.service在 journalctl 日志中看到。删除到 sed 的管道可以解决所有问题。

我如何删除此前缀并将日志消息保留在日志中?

答案1

大多数程序(包括 sed)在输出不是交互式 tty 设备时,都会使用块缓冲,而不是行缓冲。(对于服务,stdout 是一个管道,使用 时您会看到类似的效果sed | cat。)

这意味着输出在缓冲区中累积时将被延迟 - 它将仅以 10-20 行左右的块写入(无论 4kB 缓冲区中有多少行)。使用sed -u--unbuffered选项可禁用缓冲。

如果程序没有这样的选项,请用 将其包装起来stdbuf -i0 -o0

相关内容