概述

在这篇教程中,我们将解释如何在 Docker 中访问 Spring Boot 日志,从本地开发到可持续的多容器解决方案。

1. 基本控制台输出

首先,让我们从我们之前的文章构建我们的 Spring Boot Docker 图像:

$> mvn spring-boot:build-image

然后,在运行容器时,我们可以立即在控制台看到 STDOUT 日志:

$> docker run --name=demo-container docker.io/library/spring-boot-docker:0.0.1-SNAPSHOT
Setting Active Processor Count to 1
WARNING: Container memory limit unset. Configuring JVM for 1G container.

这个命令类似于 Linux shell 的 tail -f 命令。

现在,让我们通过在运行容器中添加一行到 application.properties 文件来配置我们的 Spring Boot 应用程序,以通过日志附加器获取日志:

logging.file.path=logs

然后,我们可以通过在运行的容器中运行 tail -f 命令获得相同的结果:

$> docker exec -it demo-container tail -f /workspace/logs/spring.log > $HOME/spring.log
Setting Active Processor Count to 1
WARNING: Container memory limit unset. Configuring JVM for 1G container.

对于单容器解决方案,这就是全部内容。接下来的章节将学习如何分析由组合容器产生的日志历史记录和日志输出。

2. Docker 卷用于日志文件

如果我们必须从主机文件系统访问日志文件,我们需要创建一个 Docker 卷

为此,我们可以使用命令运行应用程序容器:

$> mvn spring-boot:build-image -v /path-to-host:/workspace/logs

然后,我们可以在 /path-to-host 目录中看到 spring.log 文件。

从我们关于 Docker Compose 的之前的文章开始,我们可以从 Docker Compose 文件运行多个容器。

如果我们在使用 Docker Compose 文件,则应添加卷配置:

network-example-service-available-to-host-on-port-1337:
image: karthequian/helloworld:latest
container_name: network-example-service-available-to-host-on-port-1337
volumes:
- /path-to-host:/workspace/logs

然后,让我们运行文章 Compose 文件:

$> docker-compose up

日志文件位于 /path-to-host 目录。

现在,我们回顾了基本解决方案后,让我们探索更高级的 docker logs 命令。

在接下来的章节中,我们假设我们的 Spring Boot 应用程序已配置为将日志打印到 STDOUT

3. 多容器的 Docker 日志

一旦我们同时运行多个容器,我们就无法从多个容器读取混合日志。

在 Docker Compose 文档中,我们可以找到默认情况下容器由 json-file 日志驱动设置,该驱动支持 docker logs 命令。

让我们看看如何通过我们 Docker Compose 示例工作。

首先,让我们找到我们的容器 ID:

$> docker ps
CONTAINER ID        IMAGE                           COMMAND                  
877bb028a143        karthequian/helloworld:latest   "/runner.sh nginx"       

然后,我们可以使用 docker logs -f 命令显示我们的容器日志。尽管使用了 json-file 驱动,但输出仍然是纯文本——JSON 只在 Docker 内部使用:

$> docker logs -f 877bb028a143
172.27.0.1 - - [22/Oct/2020:11:19:52 +0000] "GET / HTTP/1.1" 200 4369 "
172.27.0.1 - - [22/Oct/2020:11:19:52 +0000] "GET / HTTP/1.1" 200 4369 "

\-f 选项行为类似于 Linux shell 命令 tail -f:它随着日志输出产生而回显输出。

注意 如果我们在 Swarm 模式下运行容器,我们应该使用 docker service psdocker service logs 命令

在文档中,我们可以看到 docker logs 命令支持有限的输出选项: json-filelocaljournald

4. Docker 日志聚合服务驱动

docker logs 命令特别适用于即时监控:它不提供复杂的过滤器或长期统计信息。

为此目的,**Docker 支持几个日志聚合服务驱动**。正如我们在之前的文章中研究过 Graylog,我们将为此平台配置适当的驱动器。

此配置可以全局应用于主机的 daemon.json 文件。在 Linux 主机上的 /etc/docker 或 Windows 服务器上的 C:\\ProgramData\\docker\\config 中找到。

请注意,如果不存在 daemon.json 文件,我们应该创建它:

{ 
    "log-driver": "gelf",
    "log-opts": {
        "gelf-address": "udp://1.2.3.4:12201"
    }
}

Graylog 驱动器称为 GELF — 我们只需指定 Graylog 实例的 IP 地址。

我们也可以在运行单个容器时覆盖此配置

$> docker run \
      --log-driver gelf –-log-opt gelf-address=udp://1.2.3.4:12201 \
      alpine echo hello world

5. 结论

在这篇文章中,我们回顾了在 Docker 中访问 Spring Boot 日志的不同方式。

将日志打印到 STDOUT 使得从单容器执行中观察日志变得非常容易。

然而,如果我们要利用 Docker 日志功能,将日志写入文件可能不是一个最佳选择,因为容器没有与完整服务器相同的限制。