我使用docker logs [container-name]来查看特定容器的日志。
docker logs [container-name]
有什么优雅的方法来清除这些日志吗?
首先是糟糕的答案。在这个问题中有一个你可以运行的一行程序:
echo "" > $(docker inspect --format='\{\{.LogPath}}' <container_name_or_id>)
代替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 logs cli读取任何日志的能力。有关这种情况的例子,请参见以下是对duketwo回答的评论:
docker logs
清空日志文件后,我得到这个错误:error from daemon in stream: Error grabbing logs: invalid character '\x00' looking for beginning of value
error from daemon in stream: Error grabbing logs: invalid character '\x00' looking for beginning of value
相反,您可以让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以应用设置。这个设置将是所有新创建的容器的默认设置。注意,需要删除并重新创建现有容器以接收新的日志限制。
systemctl reload docker
可以将类似的日志选项传递给各个容器以覆盖这些默认值,从而允许您在各个容器上保存更多或更少的日志。从docker run来看,如下所示:
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日志驱动切换到&;local&;日志的司机。它采用相同的max-size和max-file选项,但它使用更快更小的二进制语法,而不是存储在json中。这允许您在相同大小的文件中存储更多的日志。这个守护进程。Json条目看起来像这样:
{ "log-driver": "local", "log-opts": {"max-size": "10m", "max-file": "3"} }
本地驱动程序的缺点是依赖于直接访问json日志的外部日志解析器/转发器将不再工作。因此,如果你使用filebeat之类的工具向Elastic或Splunk的通用转发器发送信息,我会避免使用“;司机。
我在我的窍门和技巧演示中有更多关于这一点的内容。
你不能通过Docker命令直接做到这一点。
您可以限制日志的大小,或者使用脚本删除与容器相关的日志。你可以在这里找到脚本示例(从底部阅读):功能:能够清除日志历史#1083
查看docker-compose文件引用的日志部分,在那里你可以为一些日志驱动程序指定选项(比如日志旋转和日志大小限制)。
使用:
truncate -s 0 /var/lib/docker/containers/**/*-json.log
你可能需要sudo
sudo sh -c "truncate -s 0 /var/lib/docker/containers/**/*-json.log"
参考。杰夫S. Docker:如何正确清除Docker容器的日志?
参考:当文件's被使用时截断它(Linux)
通过设置日志清除功能,可以定期清除日志。
“/etc/logrotate.d/docker-logs”文件示例
/var/lib/docker/containers/*/*.log { rotate 7 daily compress size=50M missingok delaycompress copytruncate }
sudo sh -c "truncate -s 0 /var/lib/docker/containers/*/*-json.log"
Docker为Mac用户,这里是解决方案:
查找日志文件路径
$ docker inspect | grep log < / p >
$ docker inspect | grep log
SSH进入docker机器(假设名称为default,如果不是,运行docker-machine ls来查找):
default
docker-machine ls
$ docker-machine ssh default < / p >
$ docker-machine ssh default
$ sudo -i < / p >
$ sudo -i
删除日志文件内容:
$ echo "" > log_file_path_from_step1 < / p >
$ echo "" > log_file_path_from_step1
作为根用户,尝试运行以下命令:
> /var/lib/docker/containers/*/*-json.log
或
cat /dev/null > /var/lib/docker/containers/*/*-json.log
echo "" > /var/lib/docker/containers/*/*-json.log
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容器的主机。我们运行的命令是非mac答案中熟悉的truncate -s0 $LOGPATH。
nsenter
xhyve
truncate -s0 $LOGPATH
如果你使用docker-compose,第一行变成:
docker-compose
local LOGPATH=$(docker inspect --format='\{\{.LogPath}}' $(docker-compose ps -q <service>))
而<service>是你的docker-compose.yml文件中的服务名。
<service>
docker-compose.yml
感谢https://github.com/justincormack/nsenter1的nsenter技巧。
在Docker for Windows和Mac上,也可能在其他平台上,可以使用tail选项。例如:
docker logs -f --tail 100
这样,只显示最后100行,你不需要首先滚动1M行……
(因此,删除日志可能是不必要的)
在我的Ubuntu服务器上,即使是sudo,我也会得到Cannot open ‘/var/lib/docker/containers/*/*-json.log’ for writing: No such file or directory
Cannot open ‘/var/lib/docker/containers/*/*-json.log’ for writing: No such file or directory
但是结合docker检查和截断答案是有效的:
sudo truncate -s 0 `docker inspect --format='\{\{.LogPath}}' <container>`
我更喜欢这个(从上面的解决方案):
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
你也可以在docker run命令行上提供log-opts参数,如下所示:
docker run --log-opt max-size=10m --log-opt max-file=5 my-app:latest
或者是码头式的。Yml是这样的
my-app: image: my-app:latest logging: driver: "json-file" options: max-size: "10m" max-file: "5"
credit: https://medium.com/@Quigley_Ja/ roting-docker -logs- keeping-your-overlay-folader -small-40cfa2155412 (James Quigley)
不确定这是否对您有帮助,但删除容器总是有帮助的。
因此,如果你使用docker-compose进行设置,你可以简单地使用docker-compose down && docker-compose up -d而不是docker-compose restart。通过适当的设置(确保对持久数据使用卷挂载),您不会以这种方式丢失任何数据。
docker-compose down && docker-compose up -d
docker-compose restart
当然,这比任务要求的要多。但是在各种情况下,其他答案都不起作用(如果使用远程docker服务器或在Windows机器上工作,访问底层文件系统是私有的,而且很困难)
我需要一些可以作为一个命令运行的东西,而不是必须编写docker ps并复制每个容器ID并多次运行该命令。我已经改编了BMitch的回答,我想我会分享,以防其他人发现这个有用。
docker ps
混合xargs似乎实现了我在这里需要的:
xargs
docker ps --format='\{\{.ID}}' | \ xargs -I {} sh -c 'echo > $(docker inspect --format="\{\{.LogPath}}" {})'
这将获取由docker ps (会删除列表上所有容器的日志!)列出的每个容器ID,将其管道到xargs中,然后回显一个空白字符串来替换容器的日志路径。
下面是一个清除docker容器日志的跨平台解决方案:
docker run --rm -v /var/lib/docker:/var/lib/docker alpine sh -c "echo '' > $(docker inspect --format='\{\{.LogPath}}' CONTAINER_NAME)"
将此粘贴到您的终端,并将CONTAINER_NAME更改为所需的容器名称或id。
CONTAINER_NAME
要移除/清除docker容器日志,我们可以使用下面的命令
$(docker inspect container_id|grep " logpath;|cut -d "f4) 或 $(docker inspect container_name|grep "LogPath"|cut -d "f4) < / p >
这将删除所有容器的日志文件:
sudo find /var/lib/docker/containers/ -type f -name "*.log" -delete
Ubuntu Linux /:
如果您有多个容器,而您只想删除一个日志,而不想删除其他日志。
sudo su
docker ps -a
CONTAINER ID
E1X2A3M4P5L6
> /var/lib/docker/containers/E1X2A3M4P5L6*/E1X2A3M4P5L6*-json.log
正如你所看到的,在/containers里面是容器,logs有相同的名称,但在结尾有-json.log。你只需要知道前12个字符,因为*意味着“任何东西”。
/containers
-json.log
*
感谢回复@BMitch,我刚刚写了一个shell脚本来清理所有容器的日志:
#!/bin/bash ids=$(docker ps -a --format='\{\{.ID}}') for id in $ids do echo $(docker ps -a --format='\{\{.ID}} ### \{\{.Names}} ### \{\{.Image}}' | fgrep $id) truncate -s 0 $(docker inspect --format='\{\{.LogPath}}' $id) ls -llh $(docker inspect --format='\{\{.LogPath}}' $id) done
如果你需要在删除之前存储日志文件的备份,我已经为指定的容器创建了一个执行以下操作的脚本(你必须使用sudo运行它):
注:
#!/bin/bash set -ex ############################# Main Variables Definition: CONTAINER_NAME="your-container-name" SIZE_TO_TRUNCATE="10M" ############################# Other Variables Definition: CURRENT_DATE=$(date "+%d-%b-%Y-%H-%M-%S") RANDOM_VALUE=$(shuf -i 1-1000000 -n 1) LOG_FOLDER="/opt/${CONTAINER_NAME}/logs" CN=$(docker ps --no-trunc -f name=${CONTAINER_NAME} | awk '{print $1}' | tail -n +2) LOG_DOCKER_FILE="$(docker inspect --format='\{\{.LogPath}}' ${CN})" LOG_FILE_NAME="${CURRENT_DATE}-${RANDOM_VALUE}" ############################# Procedure: mkdir -p "${LOG_FOLDER}" cp ${LOG_DOCKER_FILE} "${LOG_FOLDER}/${LOG_FILE_NAME}.log" cd ${LOG_FOLDER} tar -cvzf "${LOG_FILE_NAME}.tar.gz" "${LOG_FILE_NAME}.log" rm -rf "${LOG_FILE_NAME}.log" truncate -s ${SIZE_TO_TRUNCATE} ${LOG_DOCKER_FILE}
您可以创建一个cronjob来每月运行前面的脚本。第一次运行:
sudo crontab -e
在键盘上输入一个进入编辑模式。然后添加如下一行:
0 0 1 * * /your-script-path/script.sh
按逃避键退出编辑模式。通过输入: wq并按回车键保存文件。确保script.sh文件具有执行权限。
docker system prune