kol*_*pto 141
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
Run Code Online (Sandbox Code Playgroud)
简单地说,应用程序可以继续将其作为文件写入,但结果行将转到stdout& stderr!
Pie*_*ter 32
对于 docker 容器中的后台进程,例如使用 exec 连接到 /bin/bash 我能够使用。
echo "test log1" >> /proc/1/fd/1
Run Code Online (Sandbox Code Playgroud)
这会将输出发送到 pid 1 的 stdout,这是 docker 拾取的一个。
kol*_*pto 19
在另一个问题中,当父进程退出时杀死子进程,我得到了帮助解决这个问题的回复。
通过这种方式,我们配置了应用程序,使其记录到文件中,并持续记录到文件中tail -f。幸运的是,tail可以接受--pid PID:它会在指定进程退出时退出。我们把$$:当前shell的PID。
作为最后一步,启动的应用程序是exec'ed,这意味着当前的 shell 被该应用程序完全替换。
Runner 脚本 ,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
Run Code Online (Sandbox Code Playgroud)
注意:通过使用tail -F我们列出文件名,即使它们稍后出现,它也会读取它们!
最后,简约的 Dockerfile:
FROM ubuntu
ADD run.sh /root/run.sh
CMD ['/root/run.sh']
Run Code Online (Sandbox Code Playgroud)
注意:为了解决一些非常奇怪的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
Run Code Online (Sandbox Code Playgroud)
小智 7
对于 nginx,您可以nginx.conf指向/dev/stderr并/dev/stdout喜欢这个
user nginx;
worker_processes 4;
error_log /dev/stderr;
http {
access_log /dev/stdout main;
...
Run Code Online (Sandbox Code Playgroud)
你的Dockerfile条目应该是
/usr/sbin/nginx -g 'daemon off;'
Run Code Online (Sandbox Code Playgroud)