kolypto Asked: 2014-05-29 05:32:49 +0800 CST2014-05-29 05:32:49 +0800 CST 2014-05-29 05:32:49 +0800 CST 使 Docker 应用程序写入标准输出 772 我正在部署一个符合12 因素咨询的 3rd-party 应用程序,其中一点告诉应用程序日志应该打印到 stdout/stderr:然后集群软件可以收集它。 但是,应用程序只能写入文件或系统日志。我该如何打印这些日志? logging 6 个回答 Voted Best Answer kolypto 2014-10-08T13:57:13+08:002014-10-08T13:57:13+08:00 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! Pieter 2018-09-27T22:16:57+08:002018-09-27T22:16:57+08:00 对于 docker 容器中的后台进程,例如使用 exec 连接到 /bin/bash 我可以使用。 echo "test log1" >> /proc/1/fd/1 这会将输出发送到 pid 1 的标准输出,这是 docker 拾取和记录的一个。 kolypto 2014-05-29T11:46:15+08:002014-05-29T11:46:15+08:00 在另一个问题中,当父级退出时杀死子进程,我得到了有助于解决这个问题的响应。 这样,我们配置应用程序,使其记录到文件中,并持续记录tail -f。幸运的是,tail可以接受--pid PID:它会在指定进程退出时退出。我们放在$$那里:当前shell的PID。 作为最后一步,启动的应用程序是exec'ed,这意味着当前的 shell 被该应用程序完全替换。 运行脚本 ,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 Muayyad Alsadi 2016-08-02T09:40:46+08:002016-08-02T09:40:46+08:00 对于 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;' Ali Hussein 2021-12-19T13:45:02+08:002021-12-19T13:45:02+08:00 在我的情况下,对标准输出的符号链接不起作用,所以我运行以下命令 ln -sf /proc/self/fd/1 /var/log/main.log mainmachine 2022-01-22T12:55:00+08:002022-01-22T12:55:00+08:00 我刚刚不得不用 apache2 解决这个问题,并努力使用 CustomLog 尝试重定向/proc/1/fd/1但无法使其正常工作。在我的实现中,apache 没有运行 as pid 1,所以kolypto 的答案没有按原样运行。Pieter 的方法似乎很有说服力,所以我将两者合并,结果非常好: # Redirect apache log output to docker log collector RUN ln -sf /proc/1/fd/1 /var/log/apache2/access.log \ && ln -sf /proc/1/fd/2 /var/log/apache2/error.log 从技术上讲,这可以保持 apacheaccess.log并error.log就docker log 收集stdout器而言,但如果有一种方法可以将两者分开容器外stderr,那就太好了,就像一个开关只会显示一个或另一个...docker logs
nginx Dockerfile中给出了一个惊人的配方:
简单地说,应用程序可以继续将其作为文件写入,但结果行将转到
stdout
&stderr
!对于 docker 容器中的后台进程,例如使用 exec 连接到 /bin/bash 我可以使用。
这会将输出发送到 pid 1 的标准输出,这是 docker 拾取和记录的一个。
在另一个问题中,当父级退出时杀死子进程,我得到了有助于解决这个问题的响应。
这样,我们配置应用程序,使其记录到文件中,并持续记录
tail -f
。幸运的是,tail
可以接受--pid PID
:它会在指定进程退出时退出。我们放在$$
那里:当前shell的PID。作为最后一步,启动的应用程序是
exec
'ed,这意味着当前的 shell 被该应用程序完全替换。运行脚本 ,
run.sh
将如下所示:注意:通过使用
tail -F
我们列出的文件名,即使它们稍后出现,它也会读取它们!最后,简约的 Dockerfile:
注意:为了解决一些非常奇怪的
tail -f
行为(它说“已被远程文件替换。放弃此名称”)我尝试了另一种方法:所有已知的日志文件都在启动时创建并截断:这样我确保它们存在,然后才 - 尾随他们:对于 nginx,您可以
nginx.conf
指向/dev/stderr
并/dev/stdout
喜欢这样你的
Dockerfile
条目应该是在我的情况下,对标准输出的符号链接不起作用,所以我运行以下命令
我刚刚不得不用 apache2 解决这个问题,并努力使用 CustomLog 尝试重定向
/proc/1/fd/1
但无法使其正常工作。在我的实现中,apache 没有运行 aspid 1
,所以kolypto 的答案没有按原样运行。Pieter 的方法似乎很有说服力,所以我将两者合并,结果非常好:从技术上讲,这可以保持 apache
access.log
并error.log
就docker log 收集stdout
器而言,但如果有一种方法可以将两者分开容器外stderr
,那就太好了,就像一个开关只会显示一个或另一个...docker logs