如何正确清除Docker容器的日志?


Answers:


251

这个问题出发,您可以运行一种代码:

echo "" > $(docker inspect --format='{{.LogPath}}' <container_name_or_id>)

或有类似的truncate命令:

truncate -s 0 $(docker inspect --format='{{.LogPath}}' <container_name_or_id>)

我对这两个都不满意,因为它们直接修改Docker的文件。当docker将json格式的数据写入文件时,可能会发生外部日志删除,导致部分行并破坏了从docker logscli 读取任何日志的能力。

相反,您可以让Docker自动为您轮换日志。如果您使用默认的JSON日志记录驱动程序,则使用dockerd的其他标志来完成此操作:

dockerd ... --log-opt max-size=10m --log-opt max-file=3

您还可以将其设置为daemon.json文件的一部分,而不用修改启动脚本:

{
  "log-driver": "json-file",
  "log-opts": {"max-size": "10m", "max-file": "3"}
}

这些选项需要使用root访问权限进行配置。请确保systemctl reload docker在更改此文件以应用设置后运行。然后,此设置将是所有新创建的容器的默认设置。请注意,需要删除并重新创建现有容器以接收新的日志限制。


可以将类似的日志选项传递给单个容器以覆盖这些默认值,从而使您可以在单个容器上保存更多或更少的日志。从这docker run看起来像:

docker run --log-driver json-file --log-opt max-size=10m --log-opt max-file=3 ...

或在撰写文件中:

version: '3.7'
services:
  app:
    image: ...
    logging:
      options:
        max-size: "10m"
        max-file: "3"

为了节省更多空间,您可以从json日志驱动程序切换到“本地”日志驱动程序。它采用相同的max-size和max-file选项,但不是使用json而是使用更快和更小的二进制语法来存储在json中。这使您可以在相同大小的文件中存储更多日志。的daemon.json条目如下所示:

{
  "log-driver": "local",
  "log-opts": {"max-size": "10m", "max-file": "3"}
}

本地驱动程序的缺点是依赖直接访问json日志的外部日志解析器/转发器将不再起作用。因此,如果您使用诸如filebeat之类的工具发送给Elastic或Splunk的通用转发器,则应避免使用“本地”驱动程序。

我的“ 提示和技巧”演示中对此有更多介绍


6
我自己做了一个service docker restart 不起作用。在生效之前,还必须品牌创建新的容器。即,仅提起旧容器并没有应用新日志记录
Robbo_UK

我正在使用Docker 1.13.1,并且'docker inspect --format ='{{。LogPath}}'<容器ID>'返回一个空字符串(“”)...。但是我仍然从'码头工人日志<容器ID>'?!?那是哪里来的,我该如何清除呢?
JD艾伦,

@JDAllen 1.13.1早已不受支持。我没有一个旧的系统可以查看其检查输出。
BMitch19年

更好的是echo -n > ...。无论如何,我希望能够更好地控制我的日志。例如,在docker-compose重新启动后,我希望拥有一种机制来对保留的日志进行处理。
NarūnasK

2
@AlexisWilke,如果您能够停止docker,那么您很有可能会停止您的容器。如果可以做的话,那么建议使用日志记录选项重新创建容器。新容器没有旧日志,新日志将自动滚动,从而同时解决了短期和长期问题。
BMitch

226

用:

truncate -s 0 /var/lib/docker/containers/*/*-json.log

您可能需要sudo

sudo sh -c "truncate -s 0 /var/lib/docker/containers/*/*-json.log"

参考 杰夫·S。如何正确清除Docker容器的日志?

参考:在使用文件时对其进行截断(Linux)


4
截断:无法打开“ /var/lib/docker/containers/*/*-json.log”进行写入:没有这样的文件或目录
BTR Naidu

2
@BTRNaidu您必须以root / sudo身份运行它,containers否则将无法获得的内容。
spydon's

25
sudo sh -c "truncate -s 0 /var/lib/docker/containers/*/*-json.log"-为我工作
杰夫S.

7
忽略上面的两个专业人员。如果不确定,则可以使用“ ls /var/lib/docker/containers/*/*-json.log”检查被截断的内容。
duketwo

1
清空日志文件后,出现以下错误:error from daemon in stream: Error grabbing logs: invalid character '\x00' looking for beginning of value
arcol

42

在Windows和Mac(可能还有其他)的Docker上,可以使用tail选项。例如:

docker logs -f --tail 100

这样,仅显示最后100行,而您不必先滚动到1M行...

(因此,删除日志可能是不必要的)


12
这个想法是清理日志文件,而不是打印日志文件的最后n行
Youssouf Maiga,

41
sudo sh -c "truncate -s 0 /var/lib/docker/containers/*/*-json.log"

4
要获取日志的大小sudo sh -c "du -ch /var/lib/docker/containers/*/*-json.log",仅获取日志的总大小sudo sh -c "du -ch /var/lib/docker/containers/*/*-json.log | grep total"
Daniel F

dockerd / aufs不了解并且无法删除旋转的日志文件是否存在任何问题?
ThorSummoner

此命令对我有用,而此SO中的其他命令则无效。如果有关系,我将在CentOS 7上运行Docker版本18
Tundra Fizz,

27

您可以设置logrotate定期清除日志。

/etc/logrotate.d/docker-logs中的示例文件

/var/lib/docker/containers/*/*.log {
 rotate 7
 daily
 compress
 size=50M
 missingok
 delaycompress
 copytruncate
}

以及我该如何使用呢?它用作默认值docker run吗?文件/etc/logrotate.d/docker-logs不存在,我必须创建它吗?
Carlos.V

您必须调用logrotate实用程序(logrotate <config-file>),它将读取您的配置并运行清理。例如,您也可以将其设置为cron作业。
AlexPnt

这个问题是,它可能无法与docker正在正确同步。使用docker工具可能更明智。("log-opts"如BMitch所示)
亚历克西斯·威尔克

12

Docker4Mac,2018年解决方案:

LOGPATH=$(docker inspect --format='{{.LogPath}}' <container_name_or_id>)
docker run -it --rm --privileged --pid=host alpine:latest nsenter -t 1 -m -u -n -i -- truncate -s0 $LOGPATH

第一行获取日志文件路径,类似于接受的答案。

第二行使用nsenter此命令,您可以在xhyve作为Docker4Mac下所有Docker容器的主机的VM中运行命令。我们运行的命令很熟悉truncate -s0 $LOGPATH非Mac答案。

如果您使用docker-compose,则第一行变为:

local LOGPATH=$(docker inspect --format='{{.LogPath}}' $(docker-compose ps -q <service>))

并且<service>是从服务的名称docker-compose.yml的文件。

感谢https://github.com/justincormack/nsenter1nsenter技巧。


4
要截断所有容器的日志,可以使用shell通配符(如其他答案所示),所以这只是一个命令:docker run -it --rm --privileged --pid=host alpine:latest nsenter -t 1 -m -u -n -i -- sh -c 'truncate -s0 /var/lib/docker/containers/*/*-json.log'
bradenm

10

您不能直接通过Docker命令执行此操作。

您可以限制日志的大小,也可以使用脚本删除与容器相关的日志。您可以在此处找到脚本示例(从底部读取):功能:能够清除日志历史记录#1083

查阅docker-compose文件参考的日志记录部分,您可以在其中为某些日志记录驱动程序指定选项(例如日志轮换和日志大小限制)。


7

root用户身份,尝试运行以下命令:

>  /var/lib/docker/containers/*/*-json.log

要么

cat /dev/null > /var/lib/docker/containers/*/*-json.log

要么

echo "" > /var/lib/docker/containers/*/*-json.log

6

在我的Ubuntu服务器上,即使像sudo一样, Cannot open ‘/var/lib/docker/containers/*/*-json.log’ for writing: No such file or directory

但是结合码头工人检查并截断答案有效:

sudo truncate -s 0 `docker inspect --format='{{.LogPath}}' <container>`

2

我确实更喜欢这一点(来自上面的解决方案):

truncate -s 0 /var/lib/docker/containers/*/*-json.log

但是,我正在运行多个系统(例如,Ubuntu 18.x Bionic),其中该路径无法按预期工作。Docker是通过Snap安装的,因此容器的路径更像是:

truncate -s 0 /var/snap/docker/common/var-lib-docker/containers/*/*-json.log

1

您还可以在docker run命令行上提供log-opts参数,如下所示:

docker run --log-opt max-size=10m --log-opt max-file=5 my-app:latest

或像这样的docker-compose.yml

my-app:
image: my-app:latest
logging:
    driver: "json-file"
    options:
        max-file: "5"
        max-size: 10m

鸣谢:https : //medium.com/@Quigley_Ja/rotating-docker-logs-keeping-your-overlay-folder-small-40cfa2155412(James Quigley)


该参数值应该被引用(即"5""10m"分别),如图所示这里,为全球daemon.json文件,但它是一个码头工人,compose.yml相同。在这两种情况下,它只会影响新创建的容器。
Adrian W

@AdrianW:docker-compose.yml不需要引号。这些是完全不同的文件格式。是的,您是对的:“ docker run”命令和docker-compose参数仅会影响新创建的容器-与此处投票最多的答案相反,后者仅影响重启的dockerd守护程序,并且只能通过root用户访问。我的答案应该比重新启动整个dockerd流程显示出比编辑更简单和更新的路径。
达格·巴德森

不带引号,我得到:错误:应用程序无法创建服务应用程序容器:JSON:不能解组数为字符串类型的转到结构领域LogConfig.Config 如果我引用这样的:"5"它的工作原理。10m确实没有报价的工作。
艾德里安W

看起来Windows的Docker和Linux的Docker之间存在差异。对于后者,我必须将值括在引号中。不上前。更新了说明以适合两者。谢谢@AdrianW
Dag Baardsen

0

适用于Mac用户的Docker,以下是解决方案:

    1. 通过以下方式查找日志文件路径:

      $ docker inspect | grep log

    1. 通过SSH进入Docker机器(假设名称为default,如果不是,请运行docker-machine ls以找出答案):

      $ docker-machine ssh default

    1. 更改为root用户(参考):

      $ sudo -i

    1. 删除日志文件内容:

      $ echo "" > log_file_path_from_step1


2
docker-machine不适用于Mac的Docker。您可以改为运行“泊坞窗运行-ti -v在/ var / lib中/泊坞窗/容器:在/ var / CentOS的成立庆典”,然后“截断--size 0 /var/inception/08d29a7d469232cfef4456dc6eebcbf313bf01ba73e479520a036150c5ab84de/08d29a7d469232cfef4456dc6eebcbf313bf01ba73e479520a036150c5ab84de-json.log”
jamshid

您可以用来docker exec -it default sh在容器中输入sh shell。但是,许多容器并没有隐式地使sudo命令可用。
达格·巴德森
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.