在容器的 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 日志中查找字符串的主要内容,如果未能解决你的问题,请参考以下文章