Compose: Recurso: capacidade de limpar o histórico de registro

Criado em 9 mar. 2015  ·  145Comentários  ·  Fonte: docker/compose

Um recurso que achei que seria útil, desde que originalmente usei o Fig, e agora o Compose seria a capacidade de limpar o histórico de log para contêineres gerenciados por Composed. Os contêineres de longa execução ou "tagarelas" podem gerar muito ruído de log que pode não ser desejado.

Eu esperaria que um comando como o seguinte resolvesse o problema:
$ docker-compose logs --clear [service]

arelogs kinenhancement

Comentários muito úteis

docker logs -c (clear) <container> seria ótimo.

+1

Todos 145 comentários

Não acho que esse seja um recurso compatível com o docker daemon. Olhando para os documentos da API, a única opção seria truncar os logs retornados para um número limitado de linhas por contêiner:

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

: +1: para este problema. Na verdade, eu uso o compose para desenvolver um site em Golang, Mongodb e nginx ... 5 dias depois de começar, tenho longos logs que se tornam preocupantes. Cada vez que eu reinicio os contêineres, acrescento muitas linhas ao log.
@dnephin Não entendo se você der uma solução (que eu não entendo :)) ou se propõe verificar se é possível com api. Desculpe pelo meu péssimo inglês.

Docker 1.6 irá adicionar suporte para drivers de registro, consulte https://github.com/docker/docker/pull/10568 (atualmente; JSON, syslog e "nenhum") trabalho está em andamento para rotação de registro básico; https://github.com/docker/docker/pull/11485

É bom ouvir isso, muito obrigado :)

Obrigado pelo histórico e atualização no Docker 1.6 - ansioso por isso!

docker logs -c (clear) <container> seria ótimo.

+1

+1 muito importante

Caramba, eu apenas sentei por vários minutos de toras para chegar ao fim. Eu realmente aprecio isso também para não ter que reconstruir contêineres constantemente.

+1

+1

+1

: +1:

+1

+2

+1

Apenas para registro, com Docker 1.8 e docker-compose 1.4 já existe um método para limitar o tamanho do log usando https://docs.docker.com/compose/yml/#log -driver e log-opt max-size:

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

@dmage Obrigado, exatamente o que eu preciso.

+1000

+1 iria adorar isso

+1

A solução

@Rodeoclash - Acho que um caso de uso para isso é a reutilização de um determinado conjunto de contêineres para uma nova execução, ou seja, um teste de CI. Os registros antigos são irrelevantes para a nova execução, portanto, clear antes do próximo comando esclareceria a confusão.

+1

+1, mesma necessidade que @rosskevin

Ok, para recapitular:

  • você pode fazer isso a partir de um arquivo de composição (consulte https://github.com/docker/compose/issues/1083#issuecomment-141936600)
  • # 265 abrange a capacidade de limitar a saída do comando logs
  • # 1756 cobre a caixa do recipiente reutilizada

Vou fechar isso, pois já é suporte ou rastreado em outras questões.

Eu não entendo muito bem por que isso foi fechado. Como você limpa o histórico de log?

Eu adiciono:

  log_opt:
    max-size: 50k

Para limitar o comprimento dos logs.

Eles realmente precisam adicionar isso, é essencial. Limitar os logs é bom e tudo, mas deve haver um comando simples para limpar os logs.

docker logs -c <container>

O que da?

Eu entendo como limitar o tamanho do log, mas como você _limpa_ o log?

Não acho que a limpeza de um log seja suportada pelo mecanismo docker, que é o que gerencia os logs.

Talvez com um driver de log personalizado você pudesse fazer isso, mas seria algo externo para compor.

1 por ser capaz de limpar as toras ...

+1

+1

+1

+1

1 para comando de log claro.

+1 para comando de log limpo

+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');

Invocação:

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

@sgarbesi obrigado!
+1

+1 para comando de log limpo

Fechado a favor de?

Para reiterar meu comentário de https://github.com/docker/compose/issues/1083#issuecomment -149357280:

Ok, para recapitular:

  • você pode fazer isso a partir de um arquivo de composição (consulte https://github.com/docker/compose/issues/1083#issuecomment-141936600)
  • # 265 abrange a capacidade de limitar a saída do comando logs
  • # 1756 cobre a caixa do recipiente reutilizada

Se o que você está procurando é algum comando como docker logs --clear , que não é compatível com o mecanismo do docker, então você precisa solicitá-lo no docker / docker. No entanto, acho que as opções acima já devem ser suficientes para a maioria dos casos. O que a maioria das pessoas deseja é apenas mostrar um subconjunto dos logs, não removê-los de fato.

Obrigado @dnephin e a todos por suas contribuições. Eu levantei esse problema há quase um ano e, a julgar pelos comentários feitos desde então, parece muito claro para mim que o gerenciamento de log é um problema para muitos usuários de escrita.

Foram mencionadas algumas soluções alternativas, eu mesmo uso principalmente max-size para manter os logs em um comprimento razoável. Isso ajuda muito, e sou grato por essas soluções alternativas, mas é importante ter em mente que se trata de uma _solução_, não uma solução.

Também está claro para mim agora que parte da responsabilidade de consertar isso está dentro do sistema de registro do Docker e que seria necessário fornecer um comando clear para o Compose utilizar - justo o suficiente.

Dito isso, no entanto, existem alguns recursos que foram incluídos nos lançamentos do Docker desde que este tíquete foi criado - a saber --since=<timestamp> e --tail=<num-lines> que poderiam ser suportados pelo Compose para chegar mais perto de dar um real solução para este problema.

Por exemplo, apoiar --since poderia tornar algo assim possível:

$ docker-compose logs --since=now my_container

ou

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

Suporte para --tail também seria útil, por exemplo

$ docker-compose logs --tail=100 my_container

e, claro, combinações dos mesmos. Também pode fazer sentido oferecer suporte a docker-compose.yml como parte do bloco logging , mas mesmo sem isso, apenas apoiando essas duas opções, suspeito que você poderia satisfazer a maioria das pessoas que + Este ingresso com +1.

Em resumo, obrigado novamente por todos os comentários e soluções alternativas e pelo Docker e o Compose - ambos são ótimos produtos - espero que você considere as ideias apresentadas neste tópico e continue a tornar esses produtos ainda melhores.

Veja # 2227 para um resumo

: +1: obrigado @dnephin ,

O que fiz foi deletar manualmente os <container-id>-json.log arquivos colocados dentro de /var/lib/docker/containers/<container-id>/ (use sudo ). Depois de executar docker-compose logs , o log estava vazio. Não é uma solução, mas com um arquivo .bash adequado você pode automatizar a limpeza antes de cada compilação.

Edit: Algo assim resolve (use por sua conta e risco !!):

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 Depois de executar o comando clean, o recurso de log funcionará normalmente?

+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

Invocação:


chmod +x docker-logs-clean.sh

sudo ./docker-logs-clean.sh

+1 para opção de linha de comando para limpar registros manualmente

@kassanmoor faz por mim.

+1

Obrigado por outras maneiras de limpar registros de contêineres

👍

+1 👍

+1!

+1

+1

+1

Esse seria um ótimo recurso, tenho alguns contêineres baseados em Java e, mesmo depois de um ou dois dias, para solucionar o problema, pode levar 30 segundos ou mais para fazer um docker logs -f <container> porque o Java adora aqueles multilinhas Histórico.

Outra coisa que pode ser mais fácil de implementar é outro sinalizador nos logs para iniciar um final sem ecoar todos os logs existentes docker logs -f -n <container> por exemplo (significando seguir apenas novos logs). Isso ecoaria apenas as mensagens de log recebidas após a execução do comando.

O oposto também funcionaria (e seria mais próximo da forma como o gnu tail funciona) é fazer um eco-f nas últimas 5-10 linhas e, em seguida, novas linhas por padrão e adicionar um sinalizador para ecoar tudo como faz agora (talvez docker logs -f -a <container> ou algo assim).

Por falar nisso, eu adoraria ter o recurso do gnu tail que permite a especificação de quantas linhas terminar como docker logs -100 <container> me dá as últimas100 linhas.

+1

+1

+1

+1

+1

+1

+1

+1

+1

+1

Existe um truque para o Docker para mac? Obrigado e +1 para uma opção de linha de comando para isso :)

+1

+1

+1

ATUALIZAÇÃO: 2016/10/08 - Remoção do requisito para "jq", pois "docker logs" suporta modelos Go! (https://docs.docker.com/engine/admin/formatting/)

Olá a todos,

Porque excluir arquivos que podem ser abertos geralmente é uma ideia RUIM - especialmente se você está tentando economizar espaço em disco! - Expandi os esforços iniciais de @lvitals & @wazoo (obrigado pelas ideias, pessoal) para produzir o script um pouco mais funcional abaixo.

Copie o código abaixo em um arquivo
vi ./docker-container-log-trim.sh
Torne o arquivo executável
chmod +x ./docker-container-log-trim.sh
Então execute com
sudo ./docker-container-log-trim.sh

Remova o comentário da linha com > quando você confiar no script ... é aí que a mágica acontece. :-)

Feedback bem-vindo.
Obrigado.

PS. Testado, mas não endurecido pela batalha. Use por sua conta e risco.

#!/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

Portanto, como foi expresso várias vezes que há um desejo por um comando claro explícito e como nunca houve um adicionado, há alguma chance de ele ser reaberto?

Depende de uma mudança no motor do docker, é claro, mas ainda é algo que eventualmente precisará ser tratado no docker-compose também - e definitivamente não é corrigido no que diz respeito a um comando explícito.

@DavidPesticcio Estou recebendo este erro ao executar seu script: line 53: $logfile: ambiguous redirect (após remover o comentário)

Olá @gingerlime , Parece que $ TEMP não está sendo preenchido ... talvez você não tenha o "mktemp" instalado ou ele não esteja no seu caminho? : - /

"Funciona bem para mim" - sim, eu sei, isso não ajuda muito para você, mas é verdade ... :-)

Eu atualizei o script, então você não precisa mais de "jq" - talvez eu deva adicionar um salvamento se mktemp também estiver faltando ... Achei que fosse uma ferramenta padrão - mas talvez você não esteja executando o script dentro de uma instalação "padrão" - como de um contêiner mínimo, talvez? :-)

Espero que ajude!

Eu tenho mktemp e uso-o freqüentemente ... Não gastei muito tempo depurando-o. Acabamos com o script mais simples acima que apenas detona esses logs. Em nosso ambiente de desenvolvimento, eles não são importantes.

na minha configuração (ou seja, executando como nenhum usuário root), este script bash não está ajudando, caso eu tenha a premissão negada ao tentar abrir o arquivo de log.

é um pouco estranho, como um usuário, posso iniciar o docker, mas posso tocar em seus arquivos de log ...
mais uma razão para gastar algo com os comandos docker / docker-compose

Tive que modificar o script de @DavidPesticcio por causa dos erros mencionados antes ... aqui vai:

#!/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 alguma chance de que isso possa ser reaberto, uma vez que há uma demanda óbvia para ter um comando de limpeza único explícito para logs?

Truncar os registros de um determinado contêiner (deve ser root):

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

Você deseja truncamento, não exclusão. (Excluir o arquivo referenciado por um identificador de arquivo aberto não recupera espaço até que o processo, neste caso, o daemon Docker, seja encerrado completamente)

@oogali justo o suficiente. Ainda assim, seria bom ter um comando adequado para fazê-lo sob demanda.

+1

seria bom ter um comando adequado para isso

+1
seria bom ter um comando adequado para fazê-lo sob demanda.

Isso é óbvio, definir uma data de início como filtro é mais trabalhoso do que apenas limpá-la para ver a saída de corrente. Por favor, adicione este recurso.

+1

+1

+1

+1

+1

Sugestão tangencialmente relacionada:

Ao fazer docker-compose logs -f , o padrão automaticamente é --tail=30 (ou qualquer outro número que seja razoável)

docker-compose logs -f não é suficiente porque com um grande número de logs exibindo leva muito tempo

+1

+1

+1

+1

+1

+1

+1

+1

+1

+1

Ou existe esta solução alternativa também

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

Por favor, pare de comentar +1. Isso torna este tópico realmente difícil de ler e extrair informações valiosas. Há um botão de polegar para cima na postagem do OP para isso.

Nada aqui funciona para mim com o Docker para mac. No entanto, hackeei algo que funciona com base na leitura deste tópico e nos fóruns do docker.

O problema com o D4M, é que no mac, você precisa realmente executar os comandos no xhyve vm. Então aqui está o que eu inventei. Adicione essas duas funções ao seu .bash_profile .

Importante : não se esqueça de iniciar um novo shell ou recarregar seu perfil antes de continuar.


Agora, docker-logs-clean parece com isto:

#!/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"

Observe que não estou rm ing o arquivo de log, mas apenas fazendo > , que truncará totalmente o arquivo.

FWIW no docker-compose versão 2, o recurso para limitar os tamanhos dos arquivos de registro:

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"

Ele não está muito bem documentado no site do docker e pode ser útil para outras pessoas.

+1

+1

+1

+1

+1

Fiz um script simples docker_clear_log.sh :
sudo truncate -s 0 $(docker inspect --format='{{.LogPath}}' $1)
Uso: ./docker_clear_log.sh [Name-or-ID]
Deve funcionar se você tiver direitos de sudo e configuração log_driver: "json-file" para o docker (padrão).

+1

Eu também tentei uma solução temporária e parece funcionar

O problema original nunca foi resolvido e o problema foi fechado de qualquer maneira. Interessante. @djessup , você gostou dessas maçãs?

ainda seria bom ter um registro docker-compose --clean

Por que este problema foi encerrado sem nem mesmo um comentário, quando o problema em si não foi resolvido?

@linvi

Quando cheguei a este tópico, o comentário final havia sido dobrado em outros comentários. Está bem aqui:

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

Acho que eles esperam cobrir esse caso de uso específico por meios indiretos. Mencione seu caso de uso específico e como ele não é coberto, e isso pode ajudar a reabrir o ticket. Na pior das hipóteses, alguém pode apontar uma maneira fácil de conseguir o que deseja: D

Alguma atualização?

quando há um log, devemos ser capazes de limpá-lo de uma forma simples.

seria muito bom, se você pudesse construir o comando nele. isso não parece difícil.
milhares de pessoas ficariam muito felizes por não ter que percorrer tudo.

Se você usar docker-compose, use lazydocker para visualizar os logs. Então, não há necessidade de excluir os logs. Você obtém registros ao vivo e começa com os registros mais recentes. Isso ajuda muito na depuração.

grafik

https://github.com/jesseduffield/lazydocker
Você pode instalá-lo com uma linha e é uma boa ferramenta de monitoramento. É uma pena que as pessoas não sejam tão razoáveis ​​em entender que uma função "excluir log" é uma coisa boa.

Mas a solução alternativa com o docker preguiçoso faz isso por mim. Obrigado jesseduffield por nos dar a possibilidade de ser preguiçosos com sua ferramenta de monitoramento :-)
Considere doar para o lazydocker se isso tornar a depuração / monitoramento mais fácil para você.
E para vocês desenvolvedores / mantenedores do docker: por que a interface do docker não é assim?
O Docker é muito bom, mas dê uma olhada no lazydocker; há espaço para melhorias.

+2147483647

+49324893

Esta página foi útil?
0 / 5 - 0 avaliações