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

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

Grep 在 docker log 命令中不能正常工作:

docker logs nginx | grep "127."

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

118489 次浏览

跟进评论,并澄清其他任何人打这个问题。下面是我能看到的搜索 nginx 容器日志的最简单方法。

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

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

如果容器正在记录到 stderr,这种情况可能会发生,管道只对 stdout 有效,所以请尝试:

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

2及1”将告诉 shell 将 真是的重定向到 Stdout,并使用管道将输出给 grep。

作为 vim 的粉丝,我更喜欢使用 less/(或 ?向后搜索)搜索

docker logs nginx 2>&1 | less

更多关于 vim 搜索 给你的信息

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

docker ps --filter ancestor=nginx

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

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

首先,使用这个命令(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

此外,我发现突出显示在日志中搜索的一些术语非常有用。特别是在生产装置上,那里产生了大量的原木输出。在我的例子中,我想突出显示 COUNT(*)语句。但是对于一个简单的 grep,我不能看到整个 SQL 语句,因为它是一个多行语句。这是可能的 -E开关和一些正则表达式:

例如,以下代码片段搜索包含 COUNT(*)count(*)的所有查询:

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

一些解释:

  • 告诉 docker 使用 F跟踪日志,这样过滤器也可以应用于新的条目,比如使用 tail -f查看它时
  • Greps --line-buffered开关刷新每一行的输出,当使用 docker logs -f时需要实时 grep
  • -E是一个 你好xtended 正则表达式模式,需要应用我们的模式来返回不匹配的结果
  • --color突出显示了匹配的部分(似乎是我的 Ubuntu 16.04 LTS 的默认行为,但可能不是在其他发行版上,所以为了安全起见,我在这里包含了它)
  • *被转义以禁用其 特殊的球体功能,其中 ()被屏蔽以避免它们作为组的正则表达式含义,这是通过 -E开关启用的

如果容器记录到 stderr,您可以通过管道将它们传送到 爱德华多已经写了一个简单的 grep:

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

如果不需要活动 grep,则可以省略 -f开关。在这两种情况下,您都可以看到带有突出显示的搜索关键字的整个 log buth,如下所示:

enter image description here

docker logs <container_name> 2>&1 | grep <string>

当我调试问题时,我通常也使用 -f选项

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

它会向我们实时显示我们所期待的内容。

若要包括时间戳,请添加

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

你也可以使用 匿名烟斗:

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

你可以使用以下方法:

  1. 所有贝壳上都有:
    docker logs nginx 2>&1 | grep "127."
    
  2. 只适用于新版本的 bash:
    docker logs nginx | &> grep "127"
    

这是什么语法?

  • 标准输入(0)
  • 标准输出(1)
  • 标准错误(2)

>操作符实际上默认使用 1作为 文件描述符号,这就是为什么我们不需要 指定 1>以重定向标准输出: (date 1> now.txt = date > now.txt)

一起

我们可以一次重定向多个流 连接两个文件,将标准输出重定向到名为 Txt,并将标准错误重定向到一个名为 error.txt 的文件。

cat bees.txt ants.txt > insects.txt 2> error.txt
变得花枝招展

如果我们想重定向标准输出和 标准错误到同一个文件,我们可以做 ls docs > output.txt 2> output.txt

或者我们可以改用 2>&1,它是一种奇特的语法 “将标准错误重定向到相同的 标准输出位置。

ls docs > output.txt 2>&1
越来越花哨了

新版本的 bash 还支持更为花哨的语法 用于重定向标准输出和标准输出 同一个文件的错误: &>表示法

ls docs &> output.txt

这个顶级的解决方案对我来说不起作用—— Grep打印了这个输出,我无法正确地找到我正在搜索的内容(我正在使用一个自定义的 docker 容器来尝试,而不是使用 Nginx) :

docker logs collector 2>&1 | grep "ERROR"
grep: (standard input): binary file matches

我的解决方案是使用 Grep-a‘ pattern’

来自 Grep 的手册页:

- A-短信 将二进制文件视为文本进行处理; 这等效于—— inary-files = text 选项。

因此,这对我来说很有效:

docker logs collector | grep -a 'ERROR'