Compose: 功能:能够清除日志历史记录

创建于 2015-03-09  ·  145评论  ·  资料来源: docker/compose

自从最初使用Fig以来,我一直认为该功能将非常有用,现在Compose将具有清除Composed管理容器的日志历史记录的功能。 长时间运行的容器或“混乱的”容器最终可能会带来很多原本就不需要的日志噪声。

我希望像下面这样的命令可以解决该问题:
$ docker-compose logs --clear [service]

arelogs kinenhancement

最有用的评论

docker logs -c (clear) <container>很好。

+1

所有145条评论

我认为这不是docker守护程序支持的功能。 查看api文档,唯一的选择是将返回的日志截断为每个容器有限的行数:

https://docs.docker.com/reference/api/docker_remote_api_v1.17/#get -container-logs

:+1:这个问题。 我实际上使用compose在Golang,Mongodb和nginx上开发了一个网站...开始5天后,我的日志很长,令人担忧。 每次我重新启动容器时,都会在日志中添加很多行。
@dnephin我不明白您是否提供解决方案(我不明白:)),或者您是否打算检查api是否可行。 对不起,我的英语不好。

Docker 1.6将增加对日志记录驱动程序的支持,请参阅https://github.com/docker/docker/pull/10568 (当前; JSON,syslog和“ none”)正在进行基本日志轮换的工作; https://github.com/docker/docker/pull/11485

很高兴听到这一消息,非常感谢:)

感谢您提供Docker 1.6的背景知识和更新-期待它!

docker logs -c (clear) <container>很好。

+1

+1非常重要

天哪,我只是坐在几分钟的原木上直到尽头。 我也很感激,因为不必不断重建容器。

+1

+1

+1

:+1:

+1

+2

+1

仅作记录,对于Docker 1.8和docker-compose 1.4,已经存在一种使用https://docs.docker.com/compose/yml/#log -driver和log-opt max-size限制日志大小的方法:

  log_driver: "json-file"
  log_opt:
    max-size: "100k"
    max-file: "20"

@dmage谢谢,正是我需要的。

+1000

+1会喜欢这个

+1

@dmage解决方案对我们很有用。 其他为此+1的人,给他的解决方案有什么问题?

@Rodeoclash-我认为一个用例是将给定容器集重用于新运行,即CI测试运行。 旧日志与新运行无关,因此在下一条命令前使用clear可以消除混乱。

+1

+1,与@rosskevin相同的需求

好,回顾一下:

  • 您可以从撰写文件中执行此操作(请参阅https://github.com/docker/compose/issues/1083#issuecomment-141936600)
  • #265说明了能够限制logs命令的输出
  • #1756涵盖了重复使用的容器盒

由于此问题已经得到支持或已在其他问题中得到跟踪,因此将要结束。

我不太明白为什么要关闭它。 您如何清除日志历史记录?

我加:

  log_opt:
    max-size: 50k

限制日志的长度。

他们真的需要添加它,这是必不可少的。 限制日志是一件好事,除了应该有一个简单的命令来清除日志。

docker logs -c <container>

是什么赋予了?

我了解如何限制日志大小,但是如何清除日志?

我不认为docker引擎支持清除日志,这是管理日志的原因。

也许可以使用自定义日志驱动程序来执行此操作,但这在编写时是外部的。

+1可以刷新日志...

+1

+1

+1

+1

+1表示清除日志命令。

+1清除日志命令

+1

+1

+1

:+1:

+1

+1

docker-logs-clean.sh

#!/bin/bash

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

调用方式:

sudo ./docker-logs-clean.sh <container-name>;

@sgarbesi谢谢!
+1

+1清除日志命令

封闭赞成?

要从https://github.com/docker/compose/issues/1083#issuecomment -149357280重申我的评论:

好,回顾一下:

  • 您可以从撰写文件中执行此操作(请参阅https://github.com/docker/compose/issues/1083#issuecomment-141936600)
  • #265说明了能够限制logs命令的输出
  • #1756涵盖了重复使用的容器盒

如果您要查找的是docker logs --clear类的命令,docker引擎不支持,因此您需要在docker / docker上请求该命令。 但是,我认为上述选择对于大多数情况已经足够了。 大多数人想要的只是显示部分日志,而不是实际删除它们。

感谢@dnephin以及其他所有人的贡献。 我大约一年前就提出了这个问题,从那以后的评论来看,对我来说,很明显,日志管理是许多复合用户的痛苦点。

提到了一些解决方法,我本人主要使用max-size来将日志保持在合理的长度。 这很有帮助,我感谢这些解决方法,但请务必记住,这是_解决方法_,而不是解决方案。

现在我也很清楚,解决此问题的部分责任在于Docker日志记录系统中,并且它需要提供一个clear命令供Compose使用-足够公平。

然而,所有这些都说明,自创建该票证以来,有一些功能已成为Docker版本的组成部分,即--since=<timestamp>--tail=<num-lines>可以由Compose支持,从而更接近于提供真实的解决这个问题。

例如,支持--since可以使这种事情成为可能:

$ docker-compose logs --since=now my_container

要么

$ docker-compose logs --since=5m my_container

支持--tail也很有用,例如

$ docker-compose logs --tail=100 my_container

当然是它们的组合作为logging块的一部分在docker-compose.yml支持这些可能也很有意义,但是即使没有这种支持,我也只能通过支持这两个选项来满足大多数+这张票一张。

总而言之,再次感谢所有反馈和变通办法,以及Docker和Compose本身-它们都是很棒的产品-我希望您会考虑此主题中提出的想法并继续使这些产品变得更大。

有关详细信息,请参见#2227

:+1:感谢@dnephin ,期待它!

我所做的是手动删除/var/lib/docker/containers/<container-id>/内的<container-id>-json.log文件(使用sudo )。 一旦运行docker-compose logs ,日志将为空。 这不是解决方案,但是有了正确的.bash文件,您可以在每次构建之前自动进行清理。

编辑:这样的事情可以解决问题(使用风险自负!):

sudo find /var/lib/docker/containers/ -type f -name '*-json.log' -delete

+1

+1

+1

+1

+2

+2

+1

+20

+1

+1

+1

+1

@sgarbesi运行clean命令后,日志功能将正常运行吗?

+1

docker-logs-clean.sh

#!/bin/bash

for container_id in $(docker ps -a --filter="name=$name" -q);

    do file=$(docker inspect $container_id | grep -G '"LogPath": "*"' | sed -e 's/.*"LogPath": "//g' | sed -e 's/",//g');

    if [ -f $file ]
      then
          rm $file;
    fi

done

调用方式:


chmod +x docker-logs-clean.sh

sudo ./docker-logs-clean.sh

+1用于命令行选项,用于手动清除日志

@kassanmoor为我做。

+1

感谢您使用其他方法清除容器日志

👍

+1👍

+1!

+1

+1

+1

这将是一个很棒的功能,我有一些基于Java的容器,甚至在一两天后进行故障排除时,可能需要30秒或更长时间才能执行docker logs -f <container>因为Java喜欢这些多行代码日志。

可能更易于实现的另一件事是,在日志上添加另一个标志,以在不回显所有现有日志docker logs -f -n <container>情况下开始尾部(意味着仅跟踪新日志)。 这只会回显运行命令后收到的日志消息。

相反的方法也可以工作(并且更接近gnu tail的工作方式)正在执行-f响应最后5-10行,然后默认情况下添加新行,并添加一个标志来像现在一样回显所有内容(也许docker logs -f -a <container>或其他内容)。

关于这一点,我很想拥有gnu tail的功能,该功能允许指定要尾数的行,例如docker logs -100 <container>给了我last100行。

+1

+1

+1

+1

+1

+1

+1

+1

+1

+1

Docker for mac有技巧吗? 谢谢,并为此+1了一个命令行选项:)

+1

+1

+1

更新:2016/10/08-删除了对“ jq”的要求,因为“ Docker日志”支持Go模板! (https://docs.docker.com/engine/admin/formatting/)

大家好,

因为删除可能打开的文件通常是个坏主意-尤其是在您试图节省磁盘空间的情况下! -我扩展了@sgarbesi@lvitals@wazoo的初步工作(感谢有创意的人),以在下面产生功能更强大的脚本。

将以下代码复制到文件中
vi ./docker-container-log-trim.sh
使文件可执行
chmod +x ./docker-container-log-trim.sh
然后执行
sudo ./docker-container-log-trim.sh

当您信任脚本时,请用>取消注释行...这就是魔术发生的地方。 :-)

欢迎反馈。
谢谢。

PS。 经过测试,但未经过严格的测试。 使用风险自负。

#!/bin/bash

# NOTES:
#  Does NOT delete logfile (BAD IDEA) - simply trims file with redirect.
#  Handles single/all-running/all-existing containers - see end of script for usage.
#  Enjoy :-)


_get_container_logfile() {

  case $1 in

    running) _trim_container_logfile "$(docker ps -q)" $2
             ;;

        all) _trim_container_logfile "$(docker ps -aq)" $2
             ;;

          *) _trim_container_logfile "$(docker ps -a | awk -v ID=$1 '$1 ~ ID || $NF ~ ID {print $1}')" $2
             ;;

  esac

}


_trim_container_logfile() {

  TEMP=$(mktemp)

  case $2 in
    *[!0-9]*) echo "[lines] must be a number - \"$2\" is not a number."
              exit 1
              ;;
        ''|*) MAX=${2:-1000}
              ;;
  esac


  if [ -z $1 ]
  then
    echo "Container name/id unknown!"
    exit 1
  else
    for container in $1
    do
      logfile="$logfile $(docker inspect --format '{{ .LogPath }}' $container)"
      echo "Keeping $MAX lines: $logfile"

      tail -n ${MAX} $logfile > $TEMP
      # Uncomment the next line when you trust the script!
      # cat $TEMP > $logfile
    done
  fi

  rm $TEMP
}


if [ -a "$(which docker)" ]
then
  case $1 in
    --trim) if [ -z $2 ]
            then
              echo "Container name/id missing!"
              exit 1
            else
              _get_container_logfile $2 $3
            fi
            ;;

    --trim-running) _get_container_logfile running $2
                    ;;

    --trim-all) _get_container_logfile all $2
                ;;

    *) echo "Usage:"
       echo "  --trim {container} [lines]   Keep [lines] of logfile for a single container"
       echo "  --trim-running     [lines]   Keep [lines] of logfile for all running containers"
       echo "  --trim-all         [lines]   Keep [lines] of logfile for all containers"
       echo "Default: lines=1000"
       exit 1
       ;;
  esac
else
  echo "Requires \"docker\""
  exit 1
fi

+1

+1

因此,由于多次表达了对明确明确命令的希望,并且由于从未添加任何命令,因此有机会重新打开它吗?

当然,这取决于Docker引擎的更改,但这仍然是最终需要在docker-compose中解决的问题-就显式命令而言,它绝对不是固定的。

@DavidPesticcio运行脚本时出现此错误: line 53: $logfile: ambiguous redirect (删除注释后)

@gingerlime ,您好,好像没有填充$ TEMP ...也许您没有安装“ mktemp”,或者它不在您的路径中? :-/

“对我来说很好”-是的,我知道,这对您没有太大帮助,但这是真的... :-)

我已经更新了脚本,因此您不再需要“ jq”了-如果mktemp也丢失了,也许我应该添加纾困...我以为这是一个标准工具-但也许您没有运行“标准”安装中的脚本-可能是从最小容器中获取脚本? :-)

希望有帮助!

我确实有mktemp ,并且经常使用它...并没有花太多时间调试它。 最后得到了上面的简单脚本,仅破坏了这些日志。 在我们的开发环境中,它们并不重要。

在我的设置中(即没有root用户身份运行),此bash脚本无济于事,因为我在尝试打开日志文件时被拒绝。

有点奇怪,作为用户我可以启动docker,但可以记录日志文件...
有更多理由花费在docker / docker-compose命令上的原因

由于之前提到的错误,我不得不修改@DavidPesticcio的脚本……它去了:

#!/bin/bash

# NOTES:
#  Does NOT delete logfile (BAD IDEA) - simply trims file with redirect.
#  Handles single/all-running/all-existing containers - see end of script for usage.
#  Enjoy :-)


_get_container_logfile() {

  case $1 in

    running) _trim_container_logfile "$(docker ps -q)" $2
             ;;

        all) _trim_container_logfile "$(docker ps -aq)" $2
             ;;

          *) _trim_container_logfile "$(docker ps -a | awk -v ID=$1 '$1 ~ ID || $NF ~ ID {print $1}')" $2
             ;;

  esac

}


_trim_container_logfile() {

  TEMP=$(mktemp)

  case $2 in
    *[!0-9]*) echo "[lines] must be a number - \"$2\" is not a number."
              exit 1
              ;;
        ''|*) MAX=${2:-1000}
              ;;
  esac


  if [ -z "$1" ]
  then
    echo "Container name/id unknown!"
    exit 1
  else
    for container in $1
    do
      logfile="$(docker inspect --format '{{.LogPath}}' $container)"
      if [ ! -f "$logfile" ]; then continue; fi
      echo "Keeping $MAX lines: $logfile"

      tail -n ${MAX} "$logfile" > "$TEMP"
      # Uncomment the next line when you trust the script!
      # cat "$TEMP" > "$logfile"
    done
  fi

  rm "$TEMP"
}


if [ -a "$(which docker)" ]
then
  case $1 in
    --trim) if [ -z $2 ]
            then
              echo "Container name/id missing!"
              exit 1
            else
              _get_container_logfile $2 $3
            fi
            ;;

    --trim-running) _get_container_logfile running $2
                    ;;

    --trim-all) _get_container_logfile all $2
                ;;

    *) echo "Usage:"
       echo "  --trim {container} [lines]   Keep [lines] of logfile for a single container"
       echo "  --trim-running     [lines]   Keep [lines] of logfile for all running containers"
       echo "  --trim-all         [lines]   Keep [lines] of logfile for all containers"
       echo "Default: lines=1000"
       exit 1
       ;;
  esac
else
  echo "Requires \"docker\""
  exit 1
fi

@dnephin是否有可能重新打开它,因为显然需要对日志有明确的一次性清除命令?

截断给定容器(必须是root)的日志:

cp /dev/null $(docker inspect -f '{{.LogPath}}' container_name)

您想要截断,而不是删除。 (删除打开的文件句柄引用的文件不会回收空间,直到该进程(在本例中为Docker守护程序)完全退出为止)

@oogali足够公平。 拥有适当的命令按需执行仍会很好。

+1

拥有适当的命令会很高兴

+1
拥有适当的命令按需执行该命令将很高兴。

这是一个明智的选择,设置开始日期是因为过滤器的工作量很大,然后只需清除它以查看当前输出即可。 请添加此功能。

+1

+1

+1

+1

+1

与切线相关的建议:

在执行docker-compose logs -f ,会自动默认为--tail=30 (或其他任何合理的数字)

docker-compose logs -f是不够的,因为显示大量日志会花费很长时间

+1

+1

+1

+1

+1

+1

+1

+1

+1

+1

或者也有这种解决方法

logpath=`docker inspect --format='{{.LogPath}}' reveelium_metricsextraction_1` && mv $logpath $logpath".bckup"

请停止评论+1。 这使得该线程确实很难读取和提取有价值的信息。 为此,OP帖子上有一个大拇指按钮。

对于Mac的Docker,这里没有任何内容适合我。 但是,基于阅读此线程和docker论坛,我一起整理了一些可行的方法。

D4M的问题在于,在Mac上,您需要在xhyve vm上实际运行命令。 这就是我的想法。 将这两个函数添加到.bash_profile

重要提示:在继续操作之前,请不要忘记启动新的Shell或重新加载配置文件。


现在, docker-logs-clean看起来像这样:

#!/bin/bash -e

if [[ -z $1 ]]; then
    echo "No container specified"
    exit 1
fi

logFile=$(docker inspect -f '{{.LogPath}}' $1 2> /dev/null)

echo -n "Cleaning ${logFile}... "
d4mexec << EOF
> $logFile
EOF
echo "done"

请注意,我不是在rm日志文件中,而是在执行> ,它将完全截断该文件。

docker-compose版本2中的FWIW限制日志文件大小的功能:

version: '2'
services:
  my-service:
    image: nginx:alpine
    restart: always
    logging:
      # limit logs retained on host to 25MB
      driver: "json-file"
      options:
        max-size: "500k"
        max-file: "50"

在Docker网站上没有很好的记录,这可能对其他人有用。

+1

+1

+1

+1

+1

我做了一个简单的脚本docker_clear_log.sh
sudo truncate -s 0 $(docker inspect --format='{{.LogPath}}' $1)
用法:./ docker_clear_log.sh [名称或ID]
如果您具有sudo权限并且为docker设置了log_driver: "json-file" (默认值),则该选项应该可以工作。

+1

我也尝试过临时解决方案,它似乎可以工作

最初的问题从未得到解决,而且该问题还是被关闭了。 有趣。 @djessup ,你喜欢那些苹果吗?

拥有一个docker-compose日志--clean还是很不错的

当问题本身没有解决时,为什么甚至没有评论就关闭了该问题?

@linvi

当我进入该主题时,结束语已被折叠成其他评论。 就在这里:

https://github.com/docker/compose/issues/1083#issuecomment -149357280

我认为他们希望通过间接方式涵盖此特定用例。 提及您特定的用例以及未涵盖的情况,这可能有助于重新打开故障单。 最坏的情况是,有人可能会指出一种简单的方法来获得您想要的东西:D

任何更新?

当有日志时,我们应该能够以一种简单的方式清除它。

如果您可以在其中构建命令,那将是非常好的。 这似乎并不难。
成千上万的人将很高兴不必滚动浏览所有内容。

如果使用docker -compose,请使用

grafik

https://github.com/jesseduffield/lazydocker
您可以用一条线安装它,它是一个很好的监视工具。 人们不太了解“删除日志”功能是一件好事,这很可惜。

但是懒惰的码头工人的解决方法为我做到了。 谢谢jesseduffield,让我们有机会对您的监视工具保持懒惰:-)
如果这样也可以简化对您的调试/监视,请考虑捐赠给lazydocker。
对您来说,Docker开发人员/维护人员:为什么Docker的界面不是这样?
Docker非常棒,但是请看一下lazydocker; 有改进的空间。

+2147483647

+49324893

此页面是否有帮助?
0 / 5 - 0 等级