我正在部署一个容器化应用程序,该应用程序在启动时输出大量无用的消息(相同的消息大约一百万次,没有任何变化)。该消息无法通过应用程序的配置来抑制,并且应用程序的开发超出了我的控制范围。这会导致日志记录基础设施出现烦人且有问题的峰值。仅在查看日志时才能过滤日志记录基础设施中的消息,而不能在将日志从容器运行时转发到日志记录存储后端时进行过滤。
所以我的目的是在容器入口点内foo bar baz
使用应用程序外部抑制此消息(在以下示例中)。grep
到目前为止我尝试过的是:
#!/bin/bash
set -euxo pipefail
exec myapp --some parameter | grep --line-buffered -v "foo bar baz"
但这不会替换 PID 1 myapp --some parameter
,从而导致信号SIGTERM
无法转发到正确的进程:
$> docker exec -it ep-test ps aux
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 0.1 0.0 18384 3008 pts/0 Ss+ 16:54 0:00 /bin/bash /entrypoint
root 7 0.0 0.0 4540 836 pts/0 S+ 16:54 0:00 myapp --some parameter
root 8 0.0 0.0 11472 964 pts/0 S+ 16:54 0:00 grep --line-buffered -v "foo bar baz"
root 9 0.0 0.0 34412 2668 pts/1 Rs+ 16:54 0:00 ps aux
如果我将 减少到exec
,exec myapp --some parameter
则 PID 1 会被正确替换(但输出不会根据需要进行过滤):
$> docker exec -it ep-test ps aux
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 0.2 0.0 4540 768 pts/0 Ss+ 16:55 0:00 myapp --some parameter
root 7 0.0 0.0 34412 2796 pts/1 Rs+ 16:55 0:00 ps aux
为了彻底关闭应用程序,将SIGTERM
(和其他已知信号)转发到非常重要myapp
。据我所知,实现此目的的最简单方法是将 PID 1 替换为exec
.
myapp
所以我的问题是是否有一种简单的方法来过滤with的输出grep
,同时确保发送到容器的信号被发送/转发到myapp
?
答案1
您可以尝试对 grep 使用 bash 命名管道(fifo),这样它就不会使用普通管道。该语法>(cmd)
创建一个 fifo,将cmd
fifo 作为标准输入运行,并在命令行中替换为 fifo 的名称,例如/dev/fd/63
,因此您可以使用 将 app 命令的 stdout 定向到该 fifo >
。
exec myapp --some parameter > >(grep --line-buffered -v "foo bar baz")
注意 中的空格> >()
。