如何清理Docker容器日志?

93

我使用

Docker

容器日志输出读取我的日志。

docker logs -f <container_name>

通过调用console.log(),我在我的node.js应用程序中记录了大量数据到日志中。 我需要清理日志,因为它已经变得太长了,而docker logs命令会先运行现有日志的行,然后才能到达结尾。如何清理日志以使其再次变短? 我想看到像这样的一个命令:

docker logs clean <container_name>

但似乎它并不存在。


1
你可以尝试使用"--follow"或"--since"选项。如果你的日志需求很特别,也许应该考虑启用其中一个日志插件:https://docs.docker.com/engine/admin/logging/overview/ - Mark O'Connor
不要手动清理日志,这可能会导致故障。你可能只想激活日志轮换,并让Docker守护程序自动处理它,可以参考我的回答:https://stackoverflow.com/questions/67046393/is-it-possible-to-clear-a-docker-container-log-file-mid-run/75251471#75251471 - Stuck
官方文档中可以看到:“警告 json-file 日志驱动程序使用基于文件的存储。这些文件被设计为仅由Docker守护程序访问。使用外部工具与这些文件进行交互可能会干扰Docker的日志系统并导致意外行为,应该避免”。这意味着建议简单截断日志文件的答案必须被视为错误 - undefined
10个回答

186

首先,如果您只需要查看较少的输出,您可以让Docker仅显示最近的几行:

docker logs --since 30s -f <container_name_or_id>

或者你可以设置行数来限制:

docker logs --tail 20 -f <container_name_or_id>
要删除Docker for Linux安装中的日志,您可以针对单个容器运行以下命令:

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

请注意,这需要root权限,我不建议这样做。如果在docker写入日志到同一个文件的过程中将文件置为空,可能会破坏日志文件。相反,您应该配置Docker来轮换日志。


最后,您可以通过在/etc/docker/daemon.json文件中添加以下内容来 配置Docker 自动轮换日志:

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

这允许 Docker 为每个容器保留多达 3 个日志文件,每个文件限制为 10 兆字节(因此每个容器的日志限制在 20 到 30 兆字节之间)。您需要运行 systemctl reload docker 来应用这些更改。这些更改是任何新创建的容器的默认设置,不适用于已经创建的容器。您需要删除和重新创建任何现有容器才能应用这些设置。


17
在Ubuntu中,你可以使用命令du -chs /var/lib/docker/containers/*/*json.log来了解你的容器日志占用了多少空间。 - hisa_py
在Ubuntu服务器19.04中,您需要使用以下命令创建文件/etc/default/docker:sudo echo 'DOCKER_OPTS="--config-file=/etc/docker/daemon.json"' > /etc/default/docker,并编辑文件daemon.json。 - FChiri
查看官方文档以配置日志轮换:https://docs.docker.com/config/containers/logging/configure/#configure-the-default-logging-driver - Gaël J

60

2
简短而简洁,我喜欢,谢谢。 - RedShift
2
仅用于清理特定容器的日志: truncate -s 0 $(docker inspect --format='{{.LogPath}}' <container_name_or_id>) - char

20

如果您想删除所有日志文件,而不仅仅是特定容器的日志,则可以使用:

docker system prune

但是请注意,这不会清除正在运行容器的日志。


5
伟大的一点。这可能很明显,但始终要记住,这不会清除正在运行的容器的日志。 - Charles Roberto Canato
18
好的,这可能会起作用。但是这很危险!这也将删除未使用的卷。 - Konrad Klockgether
这是在开发过程中清理沙盒的绝佳选择 - 谢谢! - theRiley
5
这并不清除正在运行的容器的日志。 - Zach Bloomquist
1
@KonradKlockgether 这个命令如果不加上 --volume 标志,是无法删除卷的。 - Sebastian Oscar Lopez

18

这不是理想的解决方案,但在 Docker 建立一个命令来做到这一点之前,这是一个好的解决方法。

创建一个名为 docker-clean-logs.sh 的脚本文件,并使用以下内容:

#!/bin/bash

rm $(docker inspect $1 | grep -G '"LogPath": "*"' | sed -e 's/.*"LogPath": "//g' | sed -e 's/",//g');

授予它执行权限:

chmod +x ./docker-clean-logs.sh

停止您想要清理的Docker容器:

docker stop <container_name>

然后运行上述脚本:

./docker-clean-logs.sh <container_name>

最后再次运行您的容器:

docker start ...

感谢用户sgarbesi在此页面上的贡献:https://github.com/docker/compose/issues/1083


2
不知道它以前是否能够工作,但现在肯定已经不能工作了。 - Andrew Savinykh

6

运行:

 docker inspect {containerId}

复制LogPath值

truncate -s 0 {LogaPath}

4

4

Docker Swarm服务的解决方案:

   logging:
     options:
       max-size: "10m"
       max-file: "10"

2
为了在OSX上执行此操作,您需要进入Docker容器正在运行的虚拟机中。
您可以使用walkerlee/nsenter镜像来在虚拟机内部运行命令。
docker run --rm -it --privileged --pid=host walkerlee/nsenter -t 1 -m -u -i -n sh

将其与被接受答案的简化版本结合起来,你就得到了:
#!/bin/sh
docker run --rm -it --privileged --pid=host walkerlee/nsenter -t 1 -m -u -i -n \
    cp /dev/null $(docker inspect -f '{{.LogPath}}' $1)

保存它,执行 chmod +x 命令,然后运行它。据我所知,这不需要停止容器。此外,它会清空日志文件(而不是删除它),以避免在清理后立即执行 docker logs 命令时出现错误。

在我的MacOS(Big Sur)上运行良好,不像这里发布的所有其他解决方案。 - Stevey

0

在Windows 10上,这些解决方案都没有起作用,我一直收到“没有这样的文件或目录”错误。

以下方法有效

  • 获取容器ID(检查容器)
  • 在文件浏览器中打开docker-desktop-data(在WSL中)
  • 导航到version-pack-data\community\docker\containers\CONTAINER_ID
  • 停止容器
  • 打开CONTAINER_ID-json.log文件并将其修剪或只需创建一个同名的空文件

enter image description here

来源


-1
如果你的日志被旋转了,就像这样:

enter image description here

使用以下代码清除它们

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接