如何使用tail命令将Docker输出传递给jq?

5
我将尝试将docker中的json日志导入到jq中进行处理。 如果我使用以下命令,则可以正常工作:
docker logs container_id 2>&1 | jq '.'

但是,如果我尝试追踪它,它会卡住(什么都不显示)。

docker logs -f container_id 2>&1 | jq '.'

单独使用尾部追踪命令是可行的:

docker logs -f container_id 2>&1

我在这里缺少什么?


2
也许与http://unix.stackexchange.com/questions/25372/turn-off-buffering-in-pipe有关。 - Benjamin W.
日志文件以JSON格式存储在容器主机的文件系统中。要确定JSON文件的位置,您可以运行:docker inspect [container] | grep LogPath - peak
也许需要进行流式传输?我不知道在Docker中输出的差异,但也许您可以使用jq的--stream选项,并使用streaming过滤器来处理数据。 - Jeff Mercado
BashFAQ #9 是相关的。 - Charles Duffy
...嗯,可能相关。假设您将jq替换为cat;您是否遇到了相同的问题?如果是这样,那么您的问题就是docker logs在未写入TTY时缓冲其stdout(这是默认的libc行为,因此适用于许多应用程序!)。 - Charles Duffy
显示剩余2条评论
2个回答

5

与其从标准输出中跟踪日志,您可能希望跟踪存储在容器目录中的日志文件。

Docker为每个容器存储日志,位于/var/lib/docker/containers/[container_ID]下,您可以使用docker inspect --format="{{.Id}}" container_name找到容器ID

然后像平常一样使用tail和jq命令。

tail -f  /var/lib/docker/containers/[container_ID]/[container_ID]-json.log | jq '.'

1
虽然这段代码可能回答了问题,但提供有关它如何以及/或为什么解决问题的附加上下文将改善答案的长期价值。 - Nic3500
@Nic3500 谢谢您的反馈,我已经改进了答案 :) - Mouath

-2

尽管默认的(json-file)日志驱动程序使用JSON作为文件格式,但docker logs命令不会输出JSON,而是纯文本,因此如果您使用jq,则必须使用-R选项来读取它。


2
你误解了我的问题。docker logs 输出我的标准输出。容器内的应用程序已经输出 JSON……这不是问题所在。正如我所说,如果我不使用 -f,它就可以正常工作。 - eran

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接