【问题标题】:Finding a string in docker logs of container在容器的 docker 日志中查找字符串
【发布时间】: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 在容器初始化时不断循环

标签: docker 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 有点混乱,因为您需要创建和删除这些可能非常大的文件。希望我们能得到一些工具,让它更方便一点。

      【讨论】:

      【解决方案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 或将其发送到您的打印机;)至少您应该建议如何搜索字符串,因为这是要解决的任务
            猜你喜欢
            • 1970-01-01
            • 2021-10-08
            • 2018-05-29
            • 1970-01-01
            • 1970-01-01
            • 2014-04-26
            • 1970-01-01
            • 2017-04-08
            相关资源
            最近更新 更多