gpt4 book ai didi

logging - 如何使用 docker 在微服务架构中发送日志?

转载 作者:IT老高 更新时间:2023-10-28 12:36:55 25 4
gpt4 key购买 nike

Heroku 在其 Twelve-Factor App manifest 中描述了日志作为简单的事件流:

Logs are the stream of aggregated, time-ordered events collected from the output streams of all running processes and backing services. Logs in their raw form are typically a text format with one event per line (though backtraces from exceptions may span multiple lines). Logs have no fixed beginning or end, but flow continuously as long as the app is operating.


此外,应用程序应该简单地将日志写入 stdout ,将任务留给“环境”。

A twelve-factor app never concerns itself with routing or storage of its output stream. It should not attempt to write to or manage logfiles. Instead, each running process writes its event stream, unbuffered, to stdout. During local development, the developer will view this stream in the foreground of their terminal to observe the app’s behavior.

In staging or production deploys, each process’ stream will be captured by the execution environment, collated together with all other streams from the app, and routed to one or more final destinations for viewing and long-term archival. These archival destinations are not visible to or configurable by the app, and instead are completely managed by the execution environment. Open-source log routers (such as Logplex and Fluent) are available for this purpose.


那么,就可靠性、效率和易用性而言,在 docker 环境中实现这一目标的最佳方法是什么?我认为以下问题浮现在脑海中:
  • 依赖 Docker 自己的日志工具 ( docker logs ) 是否安全?
  • 运行 docker undetached 并将其输出视为日志流是否安全?
  • 可以 stdout被直接重定向到一个文件(磁盘空间)?
  • 如果使用文件,它应该在 docker 镜像还是绑定(bind)卷( docker run --volume=[] )中?
  • 是否需要对数旋转?
  • 将标准输出直接重定向到 logshipper(以及哪个 logshipper)是否安全?
  • 命名管道(又名 FIFO)是一种选择吗?
  • (更多问题?)
  • 最佳答案

    Docker 1.6 introduced logging drivers的概念提供对日志输出的更多控制。 --log-driver标志配置在哪里 stdout & stderr从在容器中运行的进程应该被引导。另见 Configuring Logging drivers .

    有几个驱动程序可用。请注意,除了 json-file 之外的所有这些禁止使用 docker logs收集容器日志。

  • none - 禁用容器日志。
  • json-file - 行为与以前一样,json 格式的标准输出在 /var/lib/docker/containers/<containerid>/<containerid>-json.log 中可用
  • syslog - 将消息写入 syslog。也接受 --log-opt通过 TCP、UDP 或 Unix 域套接字将日志消息定向到指定的系统日志。同时禁用 docker logs
  • journald - 写入 systemd 日志。
  • *gelf - Graylog 扩展日志格式 (GELF)。将日志消息写入 GELF 端点,例如 Graylog 或 Logstash
  • *fluentd - 将容器日志发送到 fluentd .接受一些选项来自定义 fluentd 的地址并发送带有日志消息的标签。
  • **awslogs - 将日志消息写入 AWS CloudWatch Logs

  • * Docker 1.8 中的新功能

    ** Docker 1.9 中的新功能

    例如:
    docker run --log-driver=syslog --log-opt syslog-address=tcp://10.0.0.10:1514 ...

    这是 Docker 推荐的软件解决方案,用于将日志消息写入 stdout & stderr .但是,某些软件不会将日志消息写入 stdout/stderr .例如,它们改为写入日志文件或系统日志。在这些情况下,下面原始答案中的一些细节仍然适用。回顾一下:

    如果应用程序写入本地日志文件,则从主机挂载一个卷(或使用 data-only container 到容器并将日志消息写入该位置。

    如果应用程序写入 syslog,有几个选项:
  • 通过使用 /dev/log 将主机的系统日志套接字( -v /dev/log:/dev/log )挂载到容器,发送到主机的系统日志.
  • 如果应用程序在其配置中接受 syslog 端点,则将主机的 syslog 守护程序配置为通过 Docker 桥接网络上的 TCP 和/或 UDP 进行监听,并使用该端点。或者只是发送到远程系统日志主机。
  • 在容器中运行 syslog 守护进程,并使用 Docker 链接从其他正在运行的容器访问它。
  • 使用 logspout通过 UDP 自动将容器日志路由到远程系统日志

  • 不要忘记容器内的任何日志都应该像在主机操作系统上一样轮换。

    Docker 1.6 之前的原始答案

    Is it safe to rely on Docker's own log facility (docker logs)?


    docker logs每次都打印整个流,而不仅仅是新日志,所以不合适。 docker logs --follow会给 tail -f - 类似的功能,但是你有一个 docker CLI 命令一直在运行。因此虽然运行 docker logs 是安全的,不是最优的。

    Is it safe to run docker undetached and consider its output as the logging stream?



    您可以使用 systemd 而不是 daemonize 启动容器,从而捕获 systemd 日志中的所有标准输出,然后主机可以根据需要对其进行管理。

    Can stdout be redirected to a file directly (disk space)?



    你可以用 docker run ... > logfile 做到这一点当然,但是自动化和管理感觉很脆弱和更难。

    If using a file, should it be inside the docker image or a bound volume (docker run --volume=[])?



    如果你在容器内部写入,那么你需要在容器中运行 logrotate 或其他东西来管理日志文件。最好从主机挂载一个卷并使用主机的日志轮换守护进程控制它。

    Is logrotation required?



    当然,如果应用程序写入日志,您需要像在 native 操作系统环境中一样轮换它们。但是如果您在容器内写入则更难,因为日志文件位置不可预测。如果您在主机上进行轮换,日志文件将存在于以下位置,例如使用 devicemapper 作为存储驱动程序, /var/lib/docker/devicemapper/mnt/<containerid>/rootfs/... .需要一些丑陋的包装器才能让 logrotate 找到该路径下的日志。

    Is it safe to redirect stdout directly into a logshipper (and which logshipper)?



    最好使用 syslog 并让日志收集器处理 syslog。

    Is a named pipe (aka FIFO) an option?



    命名管道并不理想,因为如果管道的读取端死亡,写入者(容器)将得到一个损坏的管道。即使该事件由应用程序处理,它也会被阻止,直到再次有读者。加上它绕过 docker logs .

    另见此 post on fluentd with docker .

    请参阅 Jeff Lindsay 的工具 logspout从正在运行的容器中收集日志并根据需要路由它们。

    最后,请注意来自容器的 stdout 记录到主机上的文件 /var/lib/docker/containers/<containerid>/<containerid>-json.log .

    关于logging - 如何使用 docker 在微服务架构中发送日志?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24807557/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com