Docker 응용 프로그램을 stdout에 쓰십시오.


49

12 요인 권고 에 따라 타사 응용 프로그램을 배포하고 있는데 그 중 하나는 응용 프로그램 로그가 stdout / stderr에 인쇄되어야한다는 것을 지적합니다. 클러스터링 소프트웨어가 수집 할 수 있습니다.

그러나 응용 프로그램은 파일이나 syslog에만 쓸 수 있습니다. 대신이 로그를 어떻게 인쇄합니까?


그들은 이미 syslog에 가고 있습니다. 당신은 거기에서 그들을 데리러 수 있습니다!
Michael Hampton

@MichaelHampton은 괜찮아 보이지만 Docker는 stdout에 쓸 수있는 단일 프로세스를 실행 하며이 두 가지를 결합하는 것처럼 들립니까?
kolypto

1
데몬 프로세스가 syslog를 사용하고 인쇄하는 프론트 프로세스를 가질 수 있습니까?
qkrijger

@qkrijger, 좋은 지적입니다! 이제 누군가 경험이 있다면 ...?
kolypto

답변:


107

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

간단히 말해서 앱은 파일로 파일에 계속 쓸 수 있지만 결과적으로 줄은 stdout& stderr!


2
이. 입니다. 다만. 훌륭한. 그리고 다목적.
spacediver

11
이것에 문제가되는 것은 루트가 아닌 프로세스로 백그라운드로 포크하려고 할 때입니다. 에이 squid3문제가 있고에 대한 권한에 문제가 있습니다 /dev/stdout.
mikepurvis

4
항상 작동하는 것은 아닙니다. 예를 들어 응용 프로그램이 파일을 찾으려고하면이 방법은 일반적으로 작동하지 않습니다.
mixja

링크가 다운되었습니다 ...
Babken Vardanyan

4
모든 것이 승리를위한 파일입니다.
RubberDuck

16

또 다른 질문으로 부모가 종료 할 때 자식 프로세스를 종료 하면이를 정리하는 데 도움이되는 응답이 있습니다.

이런 식으로 파일에 기록하고 지속적으로 기록하도록 응용 프로그램을 구성 tail -f합니다. 운좋게도 tail받아 들일 수 있습니다 --pid PID: 지정된 프로세스가 종료되면 종료됩니다. $$현재 쉘의 PID를 넣 습니다.

마지막 단계로, 시작된 응용 프로그램은 exec'현재 응용 프로그램으로 완전히 교체됩니다.

러너 스크립트 run.sh는 다음과 같습니다.

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

참고 : tail -F파일 이름 을 사용하여 파일 이름을 나열하면 나중에 표시 되더라도 파일 이름을 읽습니다.

마지막으로 최소한의 Dockerfile은 다음과 같습니다.

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

참고 : 매우 이상한 tail -f동작 ( "원격 파일로 대체되었습니다.이 이름을 포기했다")을 해결하기 위해 다른 접근법을 시도했습니다. 모든 알려진 로그 파일이 시작시 생성 및 잘립니다 :이 방법으로 나는 존재합니다. , 그리고 나서야-꼬리를 붙입니다 :

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

특히 Apache 서버의 경우 Piped logs ( httpd.apache.org/docs/2.4/logs.html#piped )를 사용하고 있으며 작동하는 것처럼 보입니다.
php-coder

이 문제는 알파인과 비슷한 문제를 해결 tail하고 --pid 옵션없이 BusyBox에서 제대로 작동하는 것 같습니다 .
Ryan

해결 방법이 나를 위해 일했습니다. 매우 유용합니다. 감사합니다.
Tamas Kalman

7

도커 컨테이너의 백그라운드 프로세스, 예를 들어 exec를 / bin / bash에 연결하여 사용할 수있었습니다.

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

이것은 출력을 하나의 도커 픽업 인 pid 1의 stdout으로 보냅니다.


이것이 정답입니다. 로그는 PID1에 대해 stdout으로 전송되어야하며 애플리케이션이 다른 PID에서 실행중인 경우 docker logs또는 로 표시되지 않습니다 kubectl logs. PID1로 실행되지 않는 crontab을 통해 작업을 예약하는 컨테이너가 있습니다.
leeman24

6

nginx를 위해 당신이 한 수 nginx.conf를 가리키는 /dev/stderr/dev/stdout같이

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

그리고 당신의 Dockerfile입장은

/usr/sbin/nginx -g 'daemon off;'

마스터 프로세스가 다음과 같이 실행되고 있지 않으면 작동하지 않습니다.root
peedee
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.