如何将Docker容器日志重定向到单个文件?


110

我想将我的docker容器的所有日志重定向到单个日志文件以进行分析。我试过了

docker logs container > /tmp/stdout.log 2>/tmp/stderr.log

但这使登录两个不同的文件。我已经试过了

docker logs container > /tmp/stdout.log

但它没有用。

Answers:


137

无需重定向日志。

Docker默认将日志存储到一个日志文件中。要检查日志文件路径,请运行命令:

docker inspect --format='{{.LogPath}}' containername

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

打开该日志文件并进行分析。

如果您重定向日志,则只能在重定向之前获取日志。您将无法看到实时日志。

编辑:

要查看实时日志,可以在以下命令中运行

tail -f `docker inspect --format='{{.LogPath}}' containername`

注意:

/var/lib/docker/containers/f844a7b45ca5a9589ffaa1a5bd8dea0f4e79f0e2ff639c1d010d96afb4b53334/f844a7b45ca5a9589ffaa1a5bd8dea0f4e79f0e2ff639c1d010d96afb4b53334-json.log仅当docker生成日志(如果没有日志)时,才会创建此日志文件,然后该文件将不存在。如果我们运行命令docker logs containername,它类似于某个时候,但什么也不返回。在这种情况下,该文件将不可用。


tail -f `docker inspect --format='{{.LogPath}}' myapp`-确实是JSON-
亚当

如果该文件不存在,它将失败。表示如果docker没有生成任何日志,则不会创建此文件。但是如果docker生成日志,那么使用此命令可以查看实时日志。谢谢亚当。将其添加到我的答案中以帮助他人。
pl_rock

“默认情况下,Docker将日志存储到一个日志文件中。” -在什么情况下?在Docker主机上运行的所有容器都将输出输出到单个文件?一个容器?
克里斯·斯特里钦斯基

@ChrisStryczynski Docker为每个容器创建一个日志文件
Eddy Hernandez

126

这个选项怎么样:

docker logs containername >& logs/myFile.log

它不会重定向问题中要求的日志,而是将它们复制一次到特定文件。


如果我没有记错的话,此命令基本上会将容器开始显示时的所有日志复制到myFile.logs。对。?
S安德鲁

@SAndrew基本上是!但是Docker的新版本可能会更改。更好地看到docker logs --help,以确保
埃迪·埃尔南德斯

38

docker logs -f <yourContainer> &> your.log &

说明:

  • -f(即--follow):写入所有现有日志,并继续(跟随)记录接下来出现的所有内容。
  • &> 重定向标准输出和标准错误。
  • 您可能想在后台运行该方法,因此&
  • 您可以通过以下方式将输出和stderr分开:(> output.log 2> error.log而不是使用&>)。

9

要将stdout和stderr从docker容器捕获到单个日志文件,请运行以下命令:

docker logs container > container.log 2>&1

8

假设您有多个容器,并且要将日志聚合到一个文件中,则需要使用一些日志聚合器,例如fluentd。支持fluentd作为Docker容器的日志记录驱动程序。

因此,在docker-compose中,您需要定义日志记录驱动程序

  service1:
    image: webapp:0.0.1
    logging:
      driver: "fluentd"
      options:
        tag: service1 

  service2:
        image: myapp:0.0.1
        logging:
          driver: "fluentd"
          options:
            tag: service2

第二步将是更新流利的conf,以满足服务1和服务2的日志

 <match service1>
   @type copy
   <store>
    @type file
    path /fluentd/log/service/service.*.log
    time_slice_format %Y%m%d
    time_slice_wait 10m
    time_format %Y%m%dT%H%M%S%z
  </store>
 </match> 
 <match service2>
    @type copy
   <store>
    @type file
    path /fluentd/log/service/service.*.log
    time_slice_format %Y%m%d
    time_slice_wait 10m
    time_format %Y%m%dT%H%M%S%
  </store>
 </match> 

在此配置中,我们要求将日志写入此路径的单个文件
/fluentd/log/service/service.*.log

第三步将是运行自定义的fluentd,它将开始将日志写入文件。

这是逐步说明链接

有点长,但是正确的方法,因为您可以更好地控制日志文件路径等,并且在Docker Swarm中也很好用。


1

由于Docker为我们合并了stdout和stderr,因此我们可以将日志输出像其他任何shell流一样对待。要将当前日志重定向到文件,请使用重定向运算符

$ docker logs test_container > output.log
docker logs -f test_container > output.log

无需将输出发送到stderr和stdout,而是将应用程序的输出重定向到文件,然后将文件映射到容器外部的永久存储。

$ docker logs test_container> /tmp/output.log

Docker不会在命令行上接受相对路径,因此,如果要使用其他目录,则需要使用完整路径。


1

如果您在Windows上工作并且使用PowerShell(像我一样),则可以使用以下行捕获stdoutstderr

 docker logs <containerId> | Out-File 'C:/dev/mylog.txt'

希望对您有所帮助!


1
根据容器名称将所有容器日志保存到文件...foreach ($element in $(docker ps -a --format "{{.Names}}")) {docker logs $element | Out-File "C:/dockerlogs/$element.log"}
xisket

1

我使用的最简单方法是在终端上执行以下命令:

docker logs elk > /home/Desktop/output.log

结构是:

docker logs <Container Name> > path/filename.log

1

首先检查您的集装箱编号

docker ps -a

您可以在“容器ID”列中看到第一行。可能看起来像这样的“ 3fd0bfce2806”,然后在shell中键入

docker inspect --format='{{.LogPath}}' 3fd0bfce2806

您会看到类似这样的内容

/var/lib/docker/containers/3fd0bfce2806b3f20c2f5aeea2b70e8a7cff791a9be80f43cdf045c83373b1f1/3fd0bfce2806b3f20c2f5aeea2b70e8a7cff791a9be80f43cdf045c83373b1f1-json.log

那么你可以看到它

cat /var/lib/docker/containers/3fd0bfce2806b3f20c2f5aeea2b70e8a7cff791a9be80f43cdf045c83373b1f1/3fd0bfce2806b3f20c2f5aeea2b70e8a7cff791a9be80f43cdf045c83373b1f1-json.log

它将采用JSON格式,您可以使用时间戳来跟踪错误


0

Bash脚本将所有容器日志复制到指定目录:

#!/usr/bin/env bash

TARGET_DIR=~/logs/docker_logs
mkdir -p "$TARGET_DIR"
for name in `sudo docker ps --format '{{.Names}}'`;
do
    path=$(sudo docker inspect --format='{{.LogPath}}' $name)
    sudo cp -rf "$path" "$TARGET_DIR"/$name.log
done
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.