将在 docker 容器中创建的日志文件重定向到 stdout / stderr



我有以下Dockerfile:

FROM ubuntu:16.04
RUN apt-get update
VOLUME ["/LOGS"]
COPY ./testServer .
ENTRYPOINT ./testServer 8600

"testServer"具有正在写入的日志文件。它们位于目录"LOGS"中。每次启动"testServer"时,都会创建一个新日志。我想做的是将目录中的最新日志文件"尾部"到 stdout/stderr。

我尝试添加:

CMD ["/bin/sh", "-c", "tail $( ls -Art /LOGS | tail -n 1 ) > out_server.log 2>&1"]

到 Dockerfile(并随后重建映像),但它不起作用。

如何做到这一点?

蒂亚

相反,您可以使用 tail,您可以将日志文件符号链接到容器进程的 stdout。为此,您需要将可执行文件包装在单独的脚本中,以便它作为独立于容器主进程的进程启动。

要执行的脚本:

#!/bin/bash
# The application log will be redirected to the main docker container process's stdout, so # that it will show up in the container logs
touch /my/app/application.log
ln -sf /proc/1/fd/1 /my/app/application.log
# Execute my app
./testServer 8600

在 docker 文件中,只需复制并执行脚本

COPY start_server.sh /the/above/script/start_server.sh
CMD ["/bin/bash", "/the/above/script/start_server.sh"]

这里有两个问题。

  1. 您定义了ENTRYPOINT,并且正在尝试使用CMD运行命令。Docker 使用单个进程启动容器,当您定义这两个进程时,CMD将作为附加 cli 参数附加到ENTRYPOINT。容器作为 pid 1 运行的是:

    /bin/sh -c './testServer 8600 /bin/sh -c "tail $( ls -Art /LOGS | tail -n 1 ) > out_server.log 2>&1"'

    除非testServer运行额外的args,否则它们永远不会被使用。

  2. 如果您正在运行的命令确实有效,它将所有内容输出到容器内的/out_server.log,而不是 stdout,并且一旦到达输入末尾就会停止。如果这是您的 pid 1,容器也会在此时退出。

要解决此问题,您可以创建一个如下所示的 entrypoint.sh:

#!/bin/sh
./testServer 8600 &
sleep 2 # give testServer time to create the newest log
exec tail -f $( ls -Art /LOGS | tail -n 1 )

该入口点在后台启动testServer,然后与exec一起运行尾部。exec 替换 pid 1,以便通过信号。

将您的 Dockerfile 更新为:

FROM ubuntu:16.04
# This apt-get line shouldn't be needed unless something else 
# needs the possibly outdated package repo list
# RUN apt-get update
# Removing this volume, you can create it from a docker-compose.yml
# VOLUME ["/LOGS"]
COPY entrypoint.sh testServer /
RUN chmod 755 /entrypoint.sh /testServer
ENTRYPOINT [ "/entrypoint.sh" ]

有关我删除VOLUME行的原因的更多详细信息,请参阅此处的博客文章。

我发现以下内容很有用。

#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

由于上述行,写入access.logerror.log的内容将分别写入stdoutstderr

如果这是一个要求,我会重新配置 ubuntu 用于输出的系统日志。一个例子在这里

相关内容

  • 没有找到相关文章

最新更新