在容器的 docker 日志中查找字符串

Posted

技术标签:

【中文标题】在容器的 docker 日志中查找字符串【英文标题】:Finding a string in docker logs of container 【发布时间】:2016-04-15 23:10:06 【问题描述】:

在 docker 容器的日志中查找特定字符串的最佳方法是什么?假设我想查看所有请求,这些请求是在来自以“127”开头的 ip 的“nginx”docker 映像中发出的。

grep 在 docker logs 命令上无法正常工作:

docker logs nginx | grep "127."

打印所有日志,但不过滤结果!

【问题讨论】:

问题是:在 docker 容器的日志中查找特定字符串的最佳方法是什么 docker logs 是否将输出发送到标准输出?因为如果确实如此,那么grep 应该可以正常工作。如果不是,那么它有点坏了,您需要在使用 grep 过滤之前将标准错误重定向到标准输出。 检查stderr et atdout,从github.com/docker/docker/issues/7440$ docker run -d --name foo busybox ls abcd $ docker logs foo > stdout.log 2>stderr.log $ cat stdout.log $ cat stderr.log ls: abcd: No such file or directory提取 @Robse 抱歉,在添加该示例之前,您的问题很难回答。看起来 docker logs 很难 grep,因为它包含终端控制字符。我会通过 nginx 日志文件 grep。 想知道您是否可以使用 --follow 执行此操作,以便 grep 在容器初始化时不断循环 【参考方案1】:

如果容器正在记录到 stderr,则可能会发生这种情况,管道仅适用于 stdout,因此请尝试:

docker logs nginx 2>&1 | grep "127."

"2>&1" 将告诉 shell 将 stderr 重定向到 stdout 并使用管道将输出提供给 grep。

【讨论】:

【参考方案2】:

作为 vim 粉丝,我更喜欢使用 less 并使用 / 进行搜索

docker logs nginx 2>&1 | less

【讨论】:

docker logs nginx |& less 少几个字符:)【参考方案3】:
docker logs <container_name> 2>&1 | grep <string>

【讨论】:

【参考方案4】:

您也可以使用anonymous pipe:

docker logs nginx 2> >(grep '127.')

【讨论】:

出于某种原因,这是唯一适合我的答案。其他的都不行,我摸不着头脑。似乎docker logs 直接写入屏幕,绕过 STDOUT 或 STDERR。【参考方案5】:

跟进 cmets 并为遇到此问题的其他人澄清这一点。这是搜索 nginx 容器日志的最简单方法。

docker logs nginx > stdout.log 2>stderr.log
cat stdout.log | grep "127."

IMO 有点混乱,因为您需要创建和删除这些可能非常大的文件。希望我们能得到一些工具,让它更方便一点。

【讨论】:

不太可能 - docker logs 似乎不会支持单独的 stdout 和 stderr github.com/moby/moby/issues/25683【参考方案6】:

此外,我发现突出显示我在日志中搜索的一些术语很有用。特别是在生成大量日志输出的生产性安装中。就我而言,我想强调 COUNT(*) 声明。但是使用简单的 grep 我看不到整个 SQL 语句,因为它是一个多行语句。这是可能的with -E switch and some regex:

例如,下面的 sn -p 搜索所有包含COUNT(*) 以及count(*) 的查询:

docker logs <containerName> -f | grep --line-buffered -i -E --color "select count\(\*\)|$"

一些解释:

docker logs -f 告诉 docker follow 日志,因此过滤器也适用于新条目,例如使用 tail -f 查看时 greps --line-buffered开关每行刷新输出,使用docker logs -f时需要实时grep -E 是一个e扩展的正则表达式模式,需要应用我们的模式以允许我们返回不匹配的结果 --color 突出显示匹配的部分(在我的 Ubuntu 16.04 LTS 上似乎是默认行为,但在其他发行版上可能没有,所以为了安全起见,我将其包含在此处) * 被转义以禁用其special glob functionality,其中() 被屏蔽以避免它们的正则表达式含义为组,由-E 开关启用

如果容器记录到标准错误,你可以通过管道as Edoardo already wrote for a simple grep:

docker logs <containerName> -f 2>&1 | grep --line-buffered -i -E --color "select count\(\*\)|$"

如果不需要实时 grep,可以省略 -f 开关。在这两种情况下,您都会看到带有突出显示的搜索词的整个日志,如下所示:

【讨论】:

【参考方案7】:

运行以下命令提取镜像 nginx 的容器名称 -

docker ps --filter ancestor=nginx

从上一个命令中复制容器 ID,然后通过以下命令为您的容器提取日志路径

grep "127." `docker inspect --format=.LogPath <ContainerName>`

【讨论】:

【参考方案8】:

当我调试问题时,我通常也将它与-f 选项一起使用

docker logs -f nginx 2>&1 | grep "127."

它会实时向我们展示我们的预期。

【讨论】:

【参考方案9】:

首先,使用这个命令(b1e3c456f07f 是容器id):

docker inspect --format='.LogPath' b1e3c456f07f

结果将是这样的:

/var/lib/docker/containers/b1e3c456f07f2cb3ae79381ada33a034041a10f65174f52bc1792110b36fb767/b1e3c456f07f2cb3ae79381ada33a034041a10f65174f52bc1792110b36fb767-json.log

其次,使用这个命令(你可以使用vim):

nano /var/lib/docker/containers/b1e3c456f07f2cb3ae79381ada33a034041a10f65174f52bc1792110b36fb767/b1e3c456f07f2cb3ae79381ada33a034041a10f65174f52bc1792110b36fb767-json.log

【讨论】:

不应该是grep /var/lib/docker/… '127.'而不是nano吗? 超频。您甚至可以使用 MS Word 或将其发送到您的打印机;)至少您应该建议如何搜索字符串,因为这是要解决的任务

以上是关于在容器的 docker 日志中查找字符串的主要内容,如果未能解决你的问题,请参考以下文章

Docker日志查看

Docker容器日志查看与清理

docker容器中解决中文乱码(详解)

docker常用操作

docker容器日志存储多久

Docker:容器管理(启动参数,查看容器和日志,进入和修改容器)