Como redirecionar logs de contêiner do docker para um único arquivo?


110

Quero redirecionar todos os logs do meu contêiner do docker para um único arquivo de log para analisá-los. eu tentei

docker logs container > /tmp/stdout.log 2>/tmp/stderr.log

mas isso dá log em dois arquivos diferentes. Ja tentei

docker logs container > /tmp/stdout.log

mas não funcionou.

Respostas:


137

Não há necessidade de redirecionar os logs.

Por padrão, o Docker armazena logs em um arquivo de log. Para verificar o caminho do arquivo de log, execute o comando:

docker inspect --format='{{.LogPath}}' containername

/var/lib/docker/containers/f844a7b45ca5a9589ffaa1a5bd8dea0f4e79f0e2ff639c1d010d96afb4b53334/f844a7b45ca5a9589ffaa1a5bd8dea0f4e79f0e2ff639c1d010d96afb4b53334-json.log

Abra esse arquivo de log e analise.

se você redirecionar os logs, só obterá os logs antes do redirecionamento. você não poderá ver os logs ao vivo.

EDITAR:

Para ver os registros ao vivo, você pode executar o comando abaixo

tail -f `docker inspect --format='{{.LogPath}}' containername`

Nota:

Este arquivo de log /var/lib/docker/containers/f844a7b45ca5a9589ffaa1a5bd8dea0f4e79f0e2ff639c1d010d96afb4b53334/f844a7b45ca5a9589ffaa1a5bd8dea0f4e79f0e2ff639c1d010d96afb4b53334-json.logserá criado apenas se o docker gerar logs, se não houver logs, esse arquivo não estará lá. é semelhante como em algum momento se executarmos o comando docker logs containernamee ele não retornar nada. Nesse cenário, este arquivo não estará disponível.


tail -f `docker inspect --format='{{.LogPath}}' myapp`- é realmente JSON
Adam

irá falhar se o arquivo não estiver lá. significa que se o docker não gerar nenhum log, este arquivo não será criado. mas se o docker estiver gerando logs, este comando é bom para ver os logs ativos. obrigado Adam. adicionando-o à minha resposta para ajudar os outros.
pl_rock

"Docker, por padrão, armazena logs em um arquivo de log." - em que contexto? Todos os contêineres em execução em um host docker obtêm saída para um único arquivo? Um único contêiner?
Chris Stryczynski de

@ChrisStryczynski Docker cria um arquivo de registro por contêiner
Eddy Hernandez

126

Que tal esta opção:

docker logs containername >& logs/myFile.log

Ele não redirecionará os logs que foram solicitados na pergunta, mas os copiará uma vez para um arquivo específico.


Se eu não estiver errado, este comando basicamente copiará todos os logs de quando o contêiner foi iniciado para apresentar em myFile.logs. Certo.?
S Andrew

@SAndrew basicamente sim! mas novas versões do Docker podem mudar. melhor ver docker logs --helppara ter certeza
Eddy Hernandez

38

docker logs -f <yourContainer> &> your.log &

Explicação:

  • -f(ou seja --follow): grava todos os logs existentes e continua ( segue ) registrando tudo o que vem a seguir.
  • &> redireciona a saída padrão e o erro padrão.
  • Provavelmente você deseja executar esse método em segundo plano, portanto, o & .
  • Você pode separar a saída e stderr por: > output.log 2> error.log(em vez de usar &>).

9

Para capturar stdout e stderr de seu contêiner do docker em um único arquivo de log, execute o seguinte:

docker logs container > container.log 2>&1

8

Supondo que você tenha vários contêineres e queira agregar os logs em um único arquivo, você precisa usar algum agregador de log como fluentd. fluentd é compatível como driver de registro para contêineres docker.

Portanto, em docker-compose, você precisa definir o driver de registro

  service1:
    image: webapp:0.0.1
    logging:
      driver: "fluentd"
      options:
        tag: service1 

  service2:
        image: myapp:0.0.1
        logging:
          driver: "fluentd"
          options:
            tag: service2

A segunda etapa seria atualizar o fluentd conf para fornecer os logs para o serviço 1 e o serviço 2

 <match service1>
   @type copy
   <store>
    @type file
    path /fluentd/log/service/service.*.log
    time_slice_format %Y%m%d
    time_slice_wait 10m
    time_format %Y%m%dT%H%M%S%z
  </store>
 </match> 
 <match service2>
    @type copy
   <store>
    @type file
    path /fluentd/log/service/service.*.log
    time_slice_format %Y%m%d
    time_slice_wait 10m
    time_format %Y%m%dT%H%M%S%
  </store>
 </match> 

Nesta configuração, estamos pedindo que os logs sejam gravados em um único arquivo para este caminho
/fluentd/log/service/service.*.log

e a terceira etapa seria executar o fluentd personalizado, que começará a gravar os logs no arquivo.

Aqui está o link para instruções passo a passo

Um pouco longo, mas da maneira correta, já que você obtém mais controle sobre o caminho dos arquivos de log, etc., e funciona bem no Docker Swarm também.


1

Como o Docker mescla stdout e stderr para nós, podemos tratar a saída do log como qualquer outro fluxo de shell. Para redirecionar os registros atuais para um arquivo, use um operador de redirecionamento

$ docker logs test_container > output.log
docker logs -f test_container > output.log

Em vez de enviar a saída para stderr e stdout, redirecione a saída de seu aplicativo para um arquivo e mapeie o arquivo para armazenamento permanente fora do contêiner.

$ docker logs test_container> /tmp/output.log

O Docker não aceitará caminhos relativos na linha de comando, portanto, se quiser usar um diretório diferente, você precisará usar o caminho completo.


1

Se você trabalha no Windows e usa o PowerShell (como eu), pode usar a seguinte linha para capturar o stdoute stderr:

 docker logs <containerId> | Out-File 'C:/dev/mylog.txt'

Eu espero que isso ajude alguém!


1
Para salvar todos os logs do contêiner em um arquivo, com base no nome do contêiner ...foreach ($element in $(docker ps -a --format "{{.Names}}")) {docker logs $element | Out-File "C:/dockerlogs/$element.log"}
xisket

1

A maneira mais fácil de usar é este comando no terminal:

docker logs elk > /home/Desktop/output.log

estrutura é:

docker logs <Container Name> > path/filename.log

1

Primeiro verifique o ID do seu contêiner

docker ps -a

Você pode ver a primeira linha nas colunas CONTAINER ID. Provavelmente se parece com "3fd0bfce2806" e digite-o no shell

docker inspect --format='{{.LogPath}}' 3fd0bfce2806

Você verá algo assim

/var/lib/docker/containers/3fd0bfce2806b3f20c2f5aeea2b70e8a7cff791a9be80f43cdf045c83373b1f1/3fd0bfce2806b3f20c2f5aeea2b70e8a7cff791a9be80f43cdf045c83373b1f1-json.log

então você pode ver como

cat /var/lib/docker/containers/3fd0bfce2806b3f20c2f5aeea2b70e8a7cff791a9be80f43cdf045c83373b1f1/3fd0bfce2806b3f20c2f5aeea2b70e8a7cff791a9be80f43cdf045c83373b1f1-json.log

Seria no formato JSON, você pode usar o carimbo de data / hora para rastrear erros


0

Script Bash para copiar todos os registros do contêiner para um diretório especificado:

#!/usr/bin/env bash

TARGET_DIR=~/logs/docker_logs
mkdir -p "$TARGET_DIR"
for name in `sudo docker ps --format '{{.Names}}'`;
do
    path=$(sudo docker inspect --format='{{.LogPath}}' $name)
    sudo cp -rf "$path" "$TARGET_DIR"/$name.log
done
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.