我想从 Docker 容器输出日志文件,但偶然发现了一些我不明白的东西。这两行不会失败,但只有第一行按我的意愿工作:
tail --follow "/var/log/my-log" &
tail --follow "/var/log/my-log" | sed -e 's/^/prefix:/' &
检查正在运行的容器内部,我看到进程正在运行,但我只看到容器输出中第一行的输出。
FROM debian:buster-slim
COPY boot.sh /
ENTRYPOINT [ "/boot.sh" ]
必须是可执行的 (chmod +x
)!
#!/bin/sh
echo "starting"
echo "start" > "/var/log/my-log"
tail --follow "/var/log/my-log" &
tail --follow "/var/log/my-log" | sed -e 's/^/prefix:/' &
echo "sleeping"
sleep inf
docker build --tag pipeline .
docker run --init --rm --name pipeline pipeline
运行图像。您还可以在此处查看容器的输出。docker exec -it pipeline bash
打开一个 shell,然后在那里运行,例如date >> /var/log/my-log
。您还可以在此处运行这两个 tail ...
命令,以查看它们应该如何工作。docker kill pipeline
。我希望在容器的输出中找到两个 tail ...
命令的输出,但它在日志文件的初始“开始”条目上已经失败。添加前缀的 tail 命令也会忽略日志文件的其他条目。
顺便说一句:我欢迎使用管道/FIFO 的解决方法,以避免开始写入持久日志文件。我仍然想了解为什么这会失败。 ;)
答案 0 :(得分:3)
根据我的测试,似乎 sed
导致了运行容器时没有出现此命令 tail --follow "/var/log/my-log" | sed -e 's/^/prefix:/' &
的输出的问题。这个问题可以通过将 -u
传递给 sed
来解决,这会禁用缓冲。
最终的工作boot.sh
如下:
#!/bin/sh
echo "starting"
echo "start" > "/var/log/my-log"
tail --follow "/var/log/my-log" &
tail --follow "/var/log/my-log" | sed -u -e 's/^/prefix:/' &
echo "sleeping"
sleep inf
运行容器后的输出将是:
starting
sleeping
start
prefix:start
将更多数据附加到日志文件也会按预期显示。
starting
sleeping
start
prefix:start
newlog
prefix:newlog