什么是在docker容器日志中查找特定字符串的最佳方法?比如说,我想要查看所有来自以"127."开头的ip的"nginx" docker镜像所做的请求。
在docker日志命令上使用grep无法按预期工作:
docker logs nginx | grep "127."
它会打印所有日志,但不会筛选结果!
docker logs nginx 2>&1 | grep "127."
docker logs
命令本身是将日志打印到 stderr 而不是 stdout。 - Code-Apprenticedocker logs nginx |& less
来减少输入字符数。 - Milad ABCdocker logs <container_name> 2>&1 | grep <string>
COUNT(*)
语句。但是,使用简单的grep无法看到整个多行SQL语句。这是可能的使用-E
开关和一些正则表达式:COUNT(*)
和count(*)
的所有查询:docker logs <containerName> -f | grep --line-buffered -i -E --color "select count\(\*\)|$"
一些解释:
docker logs -f
告诉 docker 跟随日志,因此过滤器也适用于新条目,例如使用 tail -f
查看时--line-buffered
开关在每行刷新输出,这是实时 grep 时需要的,当使用 docker logs -f
时-E
是一个扩展正则表达式模式,需要应用我们的模式,以允许我们返回不匹配的结果--color
高亮匹配的部分(在我的 Ubuntu 16.04 LTS 上似乎是默认行为,但可能在其他发行版上不是,因此我在这里包含它以确保安全)*
被转义以禁用其 特殊的 glob 功能,其中 (
和 )
被掩盖以避免它们作为组的正则表达式含义,该功能由 -E
开关启用docker logs <containerName> -f 2>&1 | grep --line-buffered -i -E --color "select count\(\*\)|$"
-f
开关。在两种情况下,您都可以看到整个日志,但是高亮显示搜索词,如下所示:
您还可以使用匿名管道:
docker logs nginx 2> >(grep '127.')
docker logs
直接写入屏幕,绕过了 STDOUT 或 STDERR。 - Anne van Leyden您可以使用以下内容:
docker logs nginx 2>&1 | grep "127."
docker logs nginx | &> grep "127"
0
)1
)2
)>
运算符实际上默认使用 1
作为文件描述符编号,这就是为什么我们不需要指定 1>
来重定向标准输出:(date 1> now.txt)= (date > now.txt)
。
我们可以同时重定向多个流!在这个例子中,我们连接了两个文件,将标准输出重定向到一个名为insects.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
对于那些遇到这个问题的人,以下是对评论进行跟进并澄清的最简单方法。这是我能想到的搜索nginx容器日志的最简单方法。
docker logs nginx > stdout.log 2>stderr.log
cat stdout.log | grep "127."
在我看来,这有点混乱,因为你需要创建和删除这些可能非常大的文件。希望我们能获得一些工具来使它更加方便。
docker logs
看起来不支持单独的 stdout 和 stderr。 - Martynas Jusevičius通常在调试问题时,我也会使用-f
选项。
docker logs -f nginx 2>&1 | grep "127."
它将实时显示我们期望的内容。
如果要包括时间戳,请添加“-t”。
docker logs -ft nginx 2>&1 | grep "127."
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
grep /var/lib/docker/... '127.'
而不是 nano
,对吗? - karlsebal
docker logs
命令是否将输出发送到标准输出?如果是,则grep
应该可以正常工作。如果不是,则需要将标准错误重定向到标准输出,然后再使用grep
进行过滤。 - Etan Reisner$ 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
- user2915097docker logs
很难使用 grep,因为它包含终端控制字符。我建议通过 nginx 日志文件进行 grep。 - hek2mgldocker logs
输出到标准输出和标准错误的更多信息,请参考:https://github.com/moby/moby/issues/41139 - cdalxndr