Fazer um aplicativo do Docker gravar no stdout

41

Estou implantando um aplicativo de terceiros em conformidade com o 12 advisory de fator , e um dos pontos indica que os logs de aplicativo devem ser impresso em stdout / stderr: o software de cluster pode coletá-lo.

No entanto, o aplicativo só pode gravar em arquivos ou syslog. Como faço para imprimir esses registros?

    
por kolypto 28.05.2014 / 15:32

4 respostas

91

Uma receita incrível é fornecida no nginx Dockerfile :

# forward request and error logs to docker log collector
RUN ln -sf /dev/stdout /var/log/nginx/access.log \
    && ln -sf /dev/stderr /var/log/nginx/error.log

Simplesmente, o aplicativo pode continuar escrevendo como um arquivo, mas, como resultado, as linhas irão para stdout & stderr !

    
por 07.10.2014 / 23:57
14

Em outra pergunta, Matar o processo filho quando o pai sai , Recebi a resposta que ajudou a resolver isso.

Dessa forma, configuramos o aplicativo para que ele registre em um arquivo e continuamente tail -f it. Felizmente, tail pode aceitar --pid PID : sairá quando o processo especificado sair. Colocamos $$ lá: PID do shell atual.

Como etapa final, o aplicativo lançado é exec 'ed, o que significa que o shell atual foi completamente substituído por esse aplicativo.

O script do corredor, run.sh , ficará assim:

#! /usr/bin/env bash
set -eu

rm -rf /var/log/my-application.log
tail --pid $$ -F /var/log/my-application.log &

exec /path/to/my-application --logfile /var/log/my-application.log

OBSERVAÇÃO: usando tail -F , listamos nomes de arquivos, e eles serão lidos mesmo que apareçam depois!

Finalmente, o Dockerfile minimalista:

FROM ubuntu
ADD run.sh /root/run.sh
CMD ['/root/run.sh']

Nota: para trabalhar com algum comportamento tail -f extremamente estranho (que diz "foi substituído por um arquivo remoto. Desistindo deste nome") eu tentei outra abordagem: todos os arquivos de log conhecidos são criados & truncado no início: dessa forma eu garanto que eles existem, e só então - siga-os:

#! /usr/bin/env bash
set -eu

LOGS=/var/log/myapp/

( umask 0 && truncate -s0 $LOGS/http.{access,error}.log )
tail --pid $$ -n0 -F $LOGS/* &

exec /usr/sbin/apache2 -DFOREGROUND
    
por 28.05.2014 / 21:46
5

para nginx você pode ter nginx.conf apontando para /dev/stderr e /dev/stdout como este

user  nginx;
worker_processes  4;
error_log  /dev/stderr;
http {
    access_log  /dev/stdout  main;
...

e sua entrada Dockerfile deve ser

/usr/sbin/nginx -g 'daemon off;'
    
por 01.08.2016 / 19:40
0

Para um processo em segundo plano em um contêiner docker, por exemplo conectando com exec a / bin / bash eu pude usar.

echo "test log1" >> /proc/1/fd/1

Isso envia a saída para o stdout de pid 1, que é o único captador da janela de encaixe.

    
por 27.09.2018 / 08:16